pax_global_header00006660000000000000000000000064126301156270014515gustar00rootroot0000000000000052 comment=ca7d5dd5d31bb644a6c7b6fe47d5a6474a5995ce bareos-Release-14.2.6/000077500000000000000000000000001263011562700144405ustar00rootroot00000000000000bareos-Release-14.2.6/.gitignore000066400000000000000000000003321263011562700164260ustar00rootroot00000000000000# temporay files *~ # Compiled Object files *.slo *.lo *.o # Compiled Dynamic libraries *.so *.dylib # Compiled Static libraries *.lai *.la *.a # Autoconf generated files autoconf/config.log # debian debian/*.log bareos-Release-14.2.6/.travis.yml000066400000000000000000000065411263011562700165570ustar00rootroot00000000000000language: cpp compiler: - gcc - clang # This project also uses Coverity Scan https://scan.coverity.com/ # However, the Travis coverity scan addon (as of 19.02.2014) does not fit our needs, # because then all builds are done as covertiy scans and results send to the server. # Therefore we reused the old method # (setting environment variables, download and execute a script). env: global: # -- BEGIN Coverity Scan ENV # The build command with all of the arguments that you would apply to a manual `cov-build` # Usually this is the same as STANDARD_BUILD_COMMAND, exluding the automated test arguments - COVERITY_SCAN_BUILD_COMMAND="make" # Name of the project - COVERITY_SCAN_PROJECT_NAME="bareos/bareos" # Email address for notifications related to this build - COVERITY_SCAN_NOTIFICATION_EMAIL="coverity@bareos.org" # Regular expression selects on which branches to run analysis # Be aware of quotas. Do not run on every branch/commit - COVERITY_SCAN_BRANCH_PATTERN="master" # COVERITY_SCAN_TOKEN via "travis encrypt" using the repo's public key - secure: "EMFCxVpjP2SBZIGqRxwdxcxxdg373w+sXIm109N7ZGMouOFVCeHq4PMBV9m6EyQ6wyb02oa6Re0GfZM9Yvc1vLc+fWpIV7y8kmVLXZhyAhGhLnCKXfirahgJkEIJTqddU/aWroub4oPPkqqNcxNAWYgrwi8jpcBkO50FGxxI9rg=" - COVERITY_SCAN_BUILD_URL="https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" - COVERITY_SCAN_BUILD="curl -s $COVERITY_SCAN_BUILD_URL | bash" # -- END Coverity Scan ENV matrix: - DB=postgresql - DB=mysql - DB=sqlite3 - DB=postgresql COVERITY_SCAN=1 matrix: # covertiy scan should only run once and it might fail, # because the number of times its runs is limited per week. # We only check when compiled with gcc. exclude: - compiler: clang env: DB=postgresql COVERITY_SCAN=1 allow_failures: - env: DB=postgresql COVERITY_SCAN=1 before_install: # install build dependencies # use files instead of shell variables, because travis has some problems supporting variables - sudo apt-get -qq update - dpkg-checkbuilddeps 2> /tmp/dpkg-builddeps || true - sed "s/.*:.*:\s//" /tmp/dpkg-builddeps > /tmp/build_depends - yes "" | sudo xargs --arg-file /tmp/build_depends apt-get -q --assume-no install before_script: # changelog file is required (and normally generated by OBS) - cp -a platforms/packaging/bareos.changes debian/changelog # build Debian packages - if [ -z "${COVERITY_SCAN}" ]; then fakeroot debian/rules binary; else debian/rules override_dh_auto_configure; eval "$COVERITY_SCAN_BUILD"; fi # create Debian package repository - cd .. - if [ -z "${COVERITY_SCAN}" ]; then dpkg-scanpackages . /dev/null | gzip > Packages.gz; fi - if [ -z "${COVERITY_SCAN}" ]; then printf 'deb file:%s /\n' $PWD > /tmp/bareos.list; fi - if [ -z "${COVERITY_SCAN}" ]; then sudo cp /tmp/bareos.list /etc/apt/sources.list.d/bareos.list; fi - cd - # install Bareos packages - if [ -z "${COVERITY_SCAN}" ]; then sudo apt-get -qq update; fi - if [ -z "${COVERITY_SCAN}" ]; then sudo apt-get install -y --force-yes bareos bareos-database-$DB; fi script: # run test script - if [ -z "${COVERITY_SCAN}" ]; then sudo -E $PWD/test/all; fi addons: hosts: - bareos.example.com bareos-Release-14.2.6/AGPL-3.0.txt000066400000000000000000001033301263011562700162220ustar00rootroot00000000000000 GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 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 Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are 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. 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. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. 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 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 work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. 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 AGPL, see . bareos-Release-14.2.6/AUTHORS000066400000000000000000000040301263011562700155050ustar00rootroot00000000000000This file contains a list of the people who have contributed code, programs or documentation. Contributors: Adam Thorton Adrew J. Millar Adrian Close Aitor Matilla Alan Brown Aleksandar Milivojevic Alexander Bergolth Alexandre Baron Alexandre Simon Allan Black Andreas Helmcke Andreas Piesk Andre Noll Andrew Ford Arno Lehmann Attila Fülöp Bastian Friedrich Ben Walton Bernd Frick Bill Moran Bruno Friedmann Camilo Viecco Carlos A. Molina G Carsten Paeth Chris Lee Christer Fletcher Christian Masopust Christopher Hull Craig Miskell D. Scott Barninger Dan Langille Daniel Neuberger Daniele Eccher David Boyes David Duchscher Davide Franco Devin Reade Dirk Bartley Eamon Brosnan Edwin Groothuis Eric Bollengier Erich Prinz Evgeni Golov Felix Schwarz Francisco Reyes Frank Bergkemper Frank Kardel Frank Sweetser Frank Ueberschar Graham Keeling Grzegorz Grabowski Howard Thomson Jaime Ventura Jakub Hradil James Harper Jan Kesten Jan Görig Jo Simoens Joakim Tjernlund Joao Henrique Freitas Joerg Steffens John Goerzen John Kodis John Walker Jorj Bauer Jose Herrera Jose Luis Tallon Josip Almasi Juan Luis Frances Juergen Lock Karl Cunningham Kern Sibbald Kjetil Torgrim Homme Landon Fuller Laurent Papier Lorenz Schori Luca Berra Lucas B. Cohen Lucas Di Pentima Ludovic Strappazon Lukas Nykryn Maik Aussendorf Marc Cousin Marc Schiffbauer Marco van Wieringen Martin Schmid Martin Simmons Matthew Ife Max Meyer Meno Abels Michael -buk- Scherer Michael Renner Michael Stapelberg Michel Meyers Morgan Nic Bellamy Nicolas Boichat Oleg Livshyts Olivier Gagnon Olivier Lehmann Peter Buschmann Peter Eriksson Peter Much Phil Stracchino Philipp Storz Philippe Chauvat Preben Guldberg Radosław Korzeniewski Riccardo Ghetta Richard Mortimer Robert Nelson Rudolf Cejka Russel Howe Scott Bailey Sebastian Lederer Sergey Svishchev Simone Caronni Stefan Reddig Stephan Duehr Thomas Glatthor Thomas Lohman Thorsten Enge Tim Oberfoell Tomas Cameron Tullio Andreatta Ulrich Leodolter Victor Hugo dos Santos Vitaliy Kosharskiy Wolfgang Denk Yuri Timofeev Yves Orton Zilvinas Krapavickas bareos-Release-14.2.6/LICENSE000066400000000000000000001521321263011562700154510ustar00rootroot00000000000000BAREOS is a fork of the Bacula source code. Please find below (1) our license information, (2) the preexisting license information of Bacula (from 06/05/2013, i.e. the date the source was forked into BAREOS), and (3) the license text of the AGPLv3. Our license information (1) is applicable to all changes to the preexisting code of Bacula. 1. BAREOS LICENSE SPECIFICS The following license terms apply to the BAREOS code: Trademark: The name BAREOS is a registered trademark of Bareos GmbH & Co. KG Bareos is licensed under the AGPL version 3 (see 3. below). Some parts of the code are licensed under permissive licenses: a) For the native NDMP support we imported some BSD 2 clause code which has the following copyright: /* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ b) Furthermore we included code from src/lib/bmtio.h which has the following copyright: /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)mtio.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: stable/7/sys/sys/mtio.h 139825 2005-01-07 02:29:27Z imp $ */ c) Furthermore we included the LMDB code from the OpenLDAP project which has the following copyright: The OpenLDAP Public License Version 2.8, 17 August 2003 Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source form must retain copyright statements and notices, 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and 3. Redistributions must contain a verbatim copy of this document. The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED 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 OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE 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 names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. OpenLDAP is a registered trademark of the OpenLDAP Foundation. Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. The new source header doesn't include a reference to the AUTHORS file in each source file but we still maintain the AUTHORS file with all authors of the orignal project ("Bacula") and any new authors for code submitted to the BAREOS project.The AUTHORS file can be found in the main directory. d) Files: src/lib/sha1.h src/lib/sha1.c Copyright: Steve Reid License: public-domain replaced the SHA licensed implementation (Copyright: 2001 The Internet Society), mentioned later in this document. e) Bareos can be compiled with data compression and decompression using the fastlzlib library. (see git://github.com/exalead/fastlzlib.git) The following licenses (LICENSE, LICENSE-FASTLZ and LICENSE-LZ4) apply to the fastlzlib and its components: == LICENSE == zlib-like interface to fast block compression (LZ4 or FastLZ) libraries Copyright (C) 2013 Exalead SA. (http://www.exalead.com/) 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. Remarks/Bugs: LZ4 compression library by Yann Collet (yann.collet.73@gmail.com) FastLZ compression library by Ariya Hidayat (ariya@kde.org) Library encapsulation by Xavier Roche (fastlz@exalead.com) == LICENSE-FASTLZ == FastLZ - lightning-fast lossless compression library Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) 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. == LICENSE-LZ4 == LZ4 - Fast LZ compression algorithm Header File Copyright (C) 2011-2012, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ =========================================== 2. History: The original Bacula code was Copyright Kern Sibbald and John Walker. After November 2004, it became Copyright Kern Sibbald, and finally, the copyright was transferred to the Free Software Foundation Europe on 15 November 2006. The license was changed from GPLv2 to AGPLv3 on 24 July 2010. Trademark: The name Bacula is a registered trademark of Kern Sibbald. =================================== License: For the most part, Bacula is licensed under the AGPL version 3. This code is listed under Copyright Free Software Foundation Europe e.V. What follows is the addition(s) to the AGPL version 3 license, that applies to code that is copyrighted by the Free Software Foundation Europe e.V. Linking: As a special exception to the AGPLv3, the Bacula Project gives permission to link the code of its release of Bacula with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Affero General Public License in all respects for all of the code used other than "OpenSSL". As a special exception to the AGPLv3, the Bacula Project gives permission to link the code of its release of the Bacula Win32 File daemon with the Microsoft supplied Volume Shadow Copy (VSS) libraries and distribute the linked executables. You must obey the GNU General Public License in all respects for all of the code used other than for the Microsoft VSS code, where you must obey their license terms. The Bacula Project gives permission for plugins with AGPLv3 compatible licenses to be loaded and distributed with the Bacula executables as long as the combined work is distributed under the terms listed in the Bacula LICENSE file. A full list of AGPLv3 compatible licenses can be found at: http://www.fsf.org/licensing/licenses/. If you wish to load or distribute plugins with different licensing terms please contact the Bacula Project at: license@bacula.org =================================== What follows is information from the authors of the code: License: To the best of our knowledge, all code used in Bacula, which is copyrighted by a third party, has licenses that are compatible with the OpenSSL license, and so given the exception that we have made to the AGPLv3 above, Bacula can be freely linked and distributed with the OpenSSL libraries. Intellectual Property rights: Recipient understands that although each Contributor to Bacula grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. Copyrights: Each Contributor to Bacula represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. Code falling under the above conditions will be marked as follows: Bacula® - The Network Backup Solution Copyright (C) 2000-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation plus additions that are listed in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. Windows: Certain source code used to build the Windows version of the Bacula File daemon is copyrighted and or trademarked by Microsoft and may contain Microsoft intellectual property (examples: Microsoft VC++, the source to the VSS libraries, the Microsoft C runtime libraries). As such we cannot and do not distribute that software. We are permitted however to distribute Bacula with the necessary Microsoft libraries in binary form. You may obtain the parts that we cannot distribute as follows. The Microsoft compiler available for purchase, and Microsoft provides a free version of the compiler. The source code and libraries are available for download from Microsoft public Web servers. We have documented in the src/win32 directory the URLs from which we obtained the library source, and how we build the Windows File daemon and many users have succeeded in doing so themselves. Our intention is to respect as closely as possible Open Source practices while maintaining full respect for proprietary and copyrighted code. GPLv2 or later license: src/tools/bsmtp.c Copyright (C) 1997 Ralf S. Engelschall, All Rights Reserved. (note, bsmtp.c does not use OpenSSL, nor is it used with the code of any other part of Bacula) 3 clause BSD License notice for inclusion with the binary: src/lib/fnmatch.c * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. src/lib/fnmatch.h * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. Permissive licenses: src/lib/var.c/h ** OSSP var - Variable Expansion ** Copyright (c) 2001-2002 Ralf S. Engelschall ** Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) src/lib/bsnprintf.c * Copyright Patrick Powell 1995 src/bregex.c/h * Copyright (c) 1991 Tatu Ylonen, Espoo, Finland src/lib/sha1.c/h Copyright (C) The Internet Society (2001). All Rights Reserved. src/win32/compat/getopt.c "... licensed under IBM copyrights to use the IBM-provided source code in any way he or she deems fit ..." src/win32/compat/sys/mtio.h (LGPL) Copyright (C) 1996, 1997 Free Software Foundation, Inc. Bacula can be enabled with data encryption and/or communications encryption. If this is the case, you will be including OpenSSL code that that contains cryptographic software written by Eric Young (eay@cryptsoft.com) and also software written by Tim Hudson (tjh@cryptsoft.com). There are parts of Bacula that are licensed under the LGPL so that those files may be used in proprietary code to interface with Bacula. Finally there are parts of Bacula that are in the public domain. 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. 3. GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 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 Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are 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. 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. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. 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 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 work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. 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 AGPL, see . =========================================== bareos-Release-14.2.6/Makefile.in000077500000000000000000000164721263011562700165220ustar00rootroot00000000000000# # Master Makefile # @MCOMMON@ working_dir = @working_dir@ log_dir = @logdir@ dir_group = @dir_group@ dir_user = @dir_user@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ topdir = . thisdir = . first_rule: all dummy: # --client-only directories fd_subdirs = src scripts src/lib src/findlib @LMDB_DIR@ src/filed \ @READLINE_SRC@ @BAT_DIR@ @TRAY_MONITOR_DIR@ src/console @FD_PLUGIN_DIR@ # Non-client-only directores subdirs = src/cats @NDMP_DIR@ @DIRD_DIR@ @STORED_DIR@ @SD_BACKENDS_DIR@ @SD_PLUGIN_DIR@ @DIR_PLUGIN_DIR@ src/tools all_subdirs = ${fd_subdirs} ${@ALL_DIRS@} manpages platforms DIST = INSTALL README.configure configure Makefile Makefile.in ChangeLog DIST_CFG = autoconf/aclocal.m4 autoconf/configure.in \ autoconf/config.h.in autoconf/acconfig.h autoconf/Make.common.in \ autoconf/install-sh autoconf/mkinstalldirs MKDIR = $(srcdir)/autoconf/mkinstalldirs LIBTOOL_DEPS = @LIBTOOL_DEPS@ #------------------------------------------------------------------------- all: info Makefile @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done depend: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1); done bareos-fd: Makefile @for I in ${fd_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) DESTDIR=$(DESTDIR) all || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done #------------------------------------------------------------------------- autoconf/aclocal.m4: autoconf/configure.in autoconf/bareos/* autoconf/gettext/* autoconf/libtool/* # Note, the following is needed in the above if ever any new macro is added. # However, at the current time, the -I libtool causes the autoconf/aclocal.m4 # get messed up, so this is commented out # cd autoconf && aclocal -I bareos-macros -I gettext-macros -I libtool configure: autoconf/configure.in autoconf/aclocal.m4 autoconf/config.h.in cd $(srcdir); ${RMF} config.cache config.log config.out config.status src/config.h ${RMF} -r autoconf/autom4te.cache autom4te.cache touch config.status autoconf --prepend-include=$(srcdir)/autoconf \ autoconf/configure.in > configure chmod 755 configure ${RMF} -r autoconf/autom4te.cache autom4te.cache config.status: if test -x config.status; then config.status --recheck; \ else $(SHELL) configure; fi autoconf/config.h.in: autoconf/configure.in cd $(srcdir); ${RMF} config.cache config.log config.out config.status src/config.h autoheader --prepend-include=$(srcdir)/autoconf \ autoconf/configure.in > autoconf/config.h.in chmod 644 autoconf/config.h.in libtool: Makefile $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck installdirs: $(MKDIR) $(DESTDIR)$(sbindir) $(MKDIR) $(DESTDIR)$(sysconfdir) chmod 770 $(DESTDIR)$(sysconfdir) -if test "x$(dir_user)" != "x" ; then \ chown $(dir_user) $(DESTDIR)$(sysconfdir); \ fi -if test "x$(dir_group)" != "x" ; then \ chgrp $(dir_group) $(DESTDIR)$(sysconfdir); \ fi $(MKDIR) $(DESTDIR)$(scriptdir) $(MKDIR) $(DESTDIR)$(archivedir) -if test ! -d $(DESTDIR)$(working_dir) ; then \ $(MKDIR) $(DESTDIR)$(working_dir); \ chmod 770 $(DESTDIR)$(working_dir); \ fi $(MKDIR) $(DESTDIR)$(log_dir); chmod 775 $(DESTDIR)$(log_dir); -if test "x$(dir_user)" != "x" ; then \ chown $(dir_user) $(DESTDIR)$(working_dir); \ fi -if test "x$(dir_group)" != "x" ; then \ chgrp $(dir_group) $(DESTDIR)$(working_dir); \ fi install: installdirs @for I in $(all_subdirs); do (cd $$I && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1); done (cd platforms && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1) install-autostart: (cd platforms && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1) install-autostart-dir: (cd platforms && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1) install-autostart-fd: (cd platforms && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1) install-autostart-sd: (cd platforms && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1) Makefile: Makefile.in cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status Makefiles: $(SHELL) config.status (cd scripts; \ chmod 755 bareos btraceback mtx-changer bconsole devel_bareos; ) (cd src/cats; \ chmod 755 create_bareos_database update_bareos_tables make_bareos_tables; \ chmod 755 grant_bareos_privileges drop_bareos_tables drop_bareos_database; \ chmod 755 make_catalog_backup delete_catalog_backup) @for I in @DB_BACKENDS@ ; do \ (cd src/cats; \ chmod 755 create_$${I}_database update_$${I}_tables make_$${I}_tables; \ chmod 755 grant_$${I}_privileges drop_$${I}_tables drop_$${I}_database); \ done (cd src/qt-console; \ chmod 755 install_conf_file) info: @mkdir -p build/ scripts/git-info.sh build/ $(CP) -p config.out build/ clean: @for I in ${all_subdirs} ; \ do (cd $$I; echo "==>Entering directory `pwd`"; ${MAKE} $@ || exit 1); done @$(RMF) *~ 1 2 3 core core.* config.guess console.log console.sum @$(RMF) examples/1 examples/2 examples/devices/1 examples/devices/2 @$(RMF) -r autom4te.cache @$(RMF) -r build/ @find . -name ".#*" -exec $(RMF) {} \; # clean for distribution distclean: @for I in $(all_subdirs); do (cd $$I && $(MAKE) $@ || exit 1); done @for I in $(all_subdirs); do (cd $$I && $(RMF) startit stopit btraceback); done @(cd $(srcdir) && $(RMF) *~ config.cache config.h config.log config.status config.out) @(cd $(srcdir) && $(RMF) Makefile autoconf/Make.common) @$(RMF) bareos fd Makefile startmysql stopmysql startit stopit btraceback @$(RMF) bconsole gconsole @$(RMF) *~ 1 2 3 core core.* config.guess console.log console.sum @$(RMF) working/* kerns-* @$(RMF) -r txt diff src/python src/testprogs @$(RMF) libtool # remove files generated by configure find . -type f -a -name "*.in" -a ! -name "control.in" | sed -e 's/.in$$//' | xargs $(RMF) devclean: @for I in $(all_subdirs); do (cd $$I && $(MAKE) $@ || exit 1); done @for I in $(all_subdirs); do (cd $$I && $(RMF) startit stopit btraceback); done @(cd $(srcdir) && $(RMF) *~ config.cache config.h config.log config.status config.out) @(cd $(srcdir) && $(RMF) Makefile autoconf/Make.common) @$(RMF) bareos fd Makefile startmysql stopmysql startit stopit btraceback @$(RMF) bconsole gconsole @$(RMF) *~ 1 2 3 core core.* config.guess console.log console.sum @$(RMF) working/* distdirs: mkdir ../$(VERNAME); mkdir ../$(VERNAME)/autoconf; @for I in $(all_subdirs); do (cd $$I && $(MAKE) DESTDIR=$(DESTDIR) $@ || (echo "Failed to make distclean in $$I"; exit 0) ); done distcopy: $(CP) -p $(DIST) ../$(VERNAME); $(CP) -p $(DIST_CFG) ../$(VERNAME)/autoconf; @for I in $(all_subdirs); do (cd $$I && $(MAKE) DESTDIR=$(DESTDIR) $@ || exit 1); done distrib: configure autoconf/config.h.in distdirs distcopy test: tar.gz: ../$(VERNAME).tar.gz ../$(VERNAME).tar.gz: (cd ..; tar cvf - $(VERNAME) | gzip -f9 > $(VERNAME).tar.gz) tar.Z: ../$(VERNAME).tar.Z ../$(VERNAME).tar.Z: (cd ..; tar cvf - $(VERNAME) | compress > $(VERNAME).tar.Z) tar.bz2: ../$(VERNAME).tar.bz2 ../$(VERNAME).tar.bz2: (cd ..; tar cvf - $(VERNAME) | bzip2 -f9 > $(VERNAME).tar.bz2) uuencode: tar.gz uuencode ../$(VERNAME).tar.gz $(VERNAME).tar.gz > ../$(VERNAME).tgz.uu # ------------------------------------------------------------------------ bareos-Release-14.2.6/README.NDMP000066400000000000000000000315511263011562700160620ustar00rootroot00000000000000Embedding full NDMP support in BAREOS. No filed plugin but a proper implementation with support in the director to act as a NDMP DMA (Data Management Application) and for NDMP tape agent support in the storage daemon for saving data using the NDMP protocol. This code is based on the NDMJOB NDMP reference implementation of Traakan, Inc., Los Altos, CA which has a BSD style license (2 clause one). http://www.traakan.com/ndmjob/index.html We imported the latest actively supported version of this reference NDMP code from the Amanda project. Instead of basing it on glib what Amanda has done we reverted some changes back to the way the latest spinnaker sources of the NDMJOB code deliver things with per OS specific code. The robot and tape simulator are rewritten versions from NDMJOB with support for registering callbacks in the calling code. This way we can implement virtual tape and robot functionality in the storage daemon for handling NDMP backups. There is also some code added for registering authentication callbacks in the calling code. This way we can perform clear text and md5 based authentication against the internal config data we keep in BAREOS native resources. The core fileindex handling code is rewritten to use callback functions for doing the real work. This way we can hook in internal functions into the core file indexing process which happens after a backup and before a restore to fill the files which have been backuped or restored. Some missing initialization, commission and decommission is added although it is empty it is better to have a consistent coding path/style for everything. Added extra destroy method as for some agents a decommission means make it ready for a next run and we want something that does a tear down and cleanup of anything dynamically allocated during a NDMP run. We also added support for telling the initialization upfront what NDMP services it should support. (e.g. DATA MANAGEMENT APPLICATION (DMA), DATA AGENT, TAPE AGENT or ROBOT AGENT) so when we accept a connection in the storage daemon via ndmp_tape we only allow the client to use our NDMP TAPE AGENT and not the ROBOT, DMA and DATA AGENT. See ndm_session structure members ..._agent_enabled. We also rewrote some of the internal structures. Normally a NDMP session is described by a so called ndm_session struct which is a whopping 1442392 bytes (almost 1.4 Mb) in size. The coders decided they would allocate each array up front and as such the total structure is huge. This is not very handy when using it as a base for a shared library as we want to support all agents but possibly not at the same time (even most likely not at the same time.) So the new ndm_session struct has pointers to the individual members and storage is only allocated when things are needed we also only allocate buffers at the time we need them not upfront. For things like directory names or other pathnames we just strdup the actual string and free it on decommission of the data, this saves a lot when PATH_MAX = 1024 bytes and you stuff a directory path of lets say 30 bytes. The DMA and DATA AGENT also keep track of an list of environment variables and a name list structure. In the original code the environment variable list can have a maximum of 1024 entries and 10240 entries for the name list and that is allocated as one big array of either 1024 or 10240 entries. This is madness we rewrote the list code to use a normal linked list so we only need the space to store the actual number of nodes of each list. There is a enumerate function which returns a memory chunk with all entries concatenated which is used for the rpc calls. We keep track of this enumerate buffer in the list descriptor and when the list is torn down it is freed. (We cannot free it earlier as it is needed as buffer for the returning rpc call.) This lingering of a buffer should be no problem as it should be moderate in size now and not the whopping 1024 or 10240 entries anymore. The media table is also rewritten to a linked list and not a fixed list of 40 entries as it was in the old code. This has significant size advantages to give an idea: ndm_control_agent, original size 523000 bytes, new size 928 bytes ndm_data_agent, original size 553232 bytes, new size 304 bytes ndm_tape_agent, original size 263388 bytes, new size 228 bytes ndm_plumbing, original size 102592 bytes, new size 20 bytes As we initialize some things now later we needed to add some extra checks and things may core dump due to dereferencing a null pointer. We decided to take that as a risk and fix those problems which we encounter them. Adding extra checks all over the place checking if things are not initialized is also gross overkill and as NDMP is a nice state machine we probably can get away by putting checks in strategic places. The test routines are put into an extra define named NDMOS_OPTION_NO_TEST_AGENTS so one can disable them for a production shared library. Extra support for getaddrinfo() is added to the library which supercedes the old and by POSIX deprecated gethostbyname() interface. Also the implementation of poll() is completed and we now also check the return info from poll() and set the channel ready flag if we detect something on a channel. This way the poll() handler should be on par with the select() based poller. The ndmjob program code is also included and you can build the ndmjob binary using the new shared library. Currently it is mostly for testing the new code in the shared library. The ndmjob program code is rewritten to also use linked list whereever possible without the need to completely rewrite the code. The NDMJOB header files are made C++ aware so we can compile the shared lib a pure C-code (which it essentially also is) and use it from BAREOS. The config engine of the director and storage daemon have been made aware of the NDMP protocol. Currently there is support for creating NDMP protocol based Backup and Restore Jobs. The storage resource is extended with a protocol and authentication type field which can be used by the NDMP DMA coded in ndmp_dma.c. A Client also has those two fields. When a storage daemon used in the NDMP backup/restore is in real life an BAREOS storage daemon an extra field named paired storage is part of the storage resource and is used by the DMA to contact the storage daemon via the native protocol to be able to simulate a NDMP save or restore via the normal BAREOS infrastructure. Via the native protocol we reserve things like drives etc so the virtual NDMP tape client can save its data, the native link is also used for things like getting the next volume to load etc. The job start code for backup and restore is modified to check for the job protocol and dispatch to the native routines when it is a native backup or to the NDMP routines when it is any NDMP job. The NDMP tape agent lives in ndmp_tape.c in the storage daemon it creates an extra listening thread which handles NDMP connections. Its based on the BAREOS bnet_server_thread code but put somewhat on a diet as for NDMP we don't need all the bells and whistles from the bsock class so we implemented a light weight ndmp connection structure. This structure is passed as handle to the connection handler and could be seen as local hook data and can be extended along the way to keep some state information on the NDMP session related to internal BAREOS resources. A ndmp backup configuration looks somethings like this: Configuration in bareos-dir.conf: Replace with the hostname of the storage device you are backing up e.g. the DATA AGENT in NDMP terms. # # Use the DUMP protocol (e.g. UNIX DUMP comparable to tar/cpio) # Generates FileHandle Information which can be used for single file # restore. # JobDefs { Name = "DefaultNDMPJob" Type = Backup Protocol = NDMP Level = Incremental Client = -ndmp Backup Format = dump FileSet = "NDMP Fileset" Schedule = "WeeklyCycle" Storage = NDMPFile Messages = Standard Pool = NDMPFile Priority = 10 Write Bootstrap = "/var/opt/bareos/run/bareos/%c.bsr" } # # A special restore Job which has the protocol set right etc. # JobDefs { Name = "DefaultNDMPRestoreJob" Client = -ndmp Type = Restore Protocol = NDMP Backup Format = dump FileSet = "NDMP Fileset" Storage = NDMPFile Pool = Default Messages = Standard Where = / } # # A NDMP Backup Job using the JobDef above. # Job { Name = "BackupNDMPDump" JobDefs = "DefaultNDMPJob" } # # Use the NETAPP SMTAPE protocol e.g. same protocol is used as replication protocol # between two NETAPP storage boxes. Doesn't allow single file restore all or nothing # restore of whole NETAPP volume. # Job { Name = "BackupNDMPSMTape" JobDefs = "DefaultNDMPJob" Backup Format = smtape Client = -ndmp FileSet = "NDMP SMtape Fileset" } # # A NDMP restore Job using the JobDef above. # Job { Name = "NDMPRestoreDump" JobDefs = "DefaultNDMPRestoreJob" } # # A NDMP restore Job using the JobDef above but for restoring a SMTAPE type of NDMP backup. # Job { Name = "NDMPRestoreSMTape" JobDefs = "DefaultNDMPRestoreJob" Backup Format = smtape FileSet = "NDMP SMtape Restore Fileset" } Fileset { Name = "NDMP Fileset" Include { Options { meta = "USER=root" } File = /export/home/... } } # # A NDMP Backup using SMPTAPE of a NetAPP storage box. # Fileset { Name = "NDMP SMtape Fileset" Include { Options { meta = "SMTAPE_DELETE_SNAPSHOT=Y" } File = /vol/vol1 } } # # A NDMP Restore using SMPTAPE of a NetAPP storage box. # Fileset { Name = "NDMP SMtape Restore Fileset" Include { Options { meta = "SMTAPE_BREAK_MIRROR=Y" } File = /vol/vol1 } } # # A NDMP Client. # Client { Name = -ndmp Address = ... Port = 10000 Protocol = NDMPv4 # Need to specify protocol before password as protocol determines password encoding used. Auth Type = Clear # Clear == Clear Text, MD5 == Challenge protocol Username = "ndmp" # username of the NDMP user on the DATA AGENT e.g. storage box being backuped. Password = "test" # password of the NDMP user on the DATA AGENT e.g. storage box being backuped. } # # Your normal Bareos SD definition should be already in your config. # Storage { Name = File Address = ... # N.B. Use a fully qualified name here SDPort = 9103 Password = ... Device = FileStorage Media Type = File } # # Same storage daemon but via NDMP protocol. # We link via the PairedStorage config option the Bareos SD instance definition to a NDMP TAPE AGENT. # Storage { Name = NDMPFile Address = ... # N.B. Use a fully qualified name here Port = 10000 Protocol = NDMPv4 # Need to specify protocol before password as protocol determines password encoding used. Auth Type = Clear # Clear == Clear Text, MD5 == Challenge protocol Username = ndmp # username of the NDMP user on the TAPE AGENT e.g. the Bareos SD but accessed via the NDMP protocol. Password = test # password of the NDMP user on the TAPE AGENT e.g. the Bareos SD but accessed via the NDMP protocol. Device = FileStorage Media Type = File PairedStorage = File } # # Your normal File based backup pool normally already defined. # Pool { Name = File Pool Type = Backup Recycle = yes AutoPrune = yes Storage = File Volume Retention = 365 days # one year Maximum Volume Bytes = 50G # Limit Volume size to something reasonable Maximum Volumes = 100 # Limit number of Volumes in Pool } # # Seperate Pool for NDMP data so upgrading of Jobs works and selects the right storage. # Pool { Name = NDMPFile Pool Type = Backup Recycle = yes AutoPrune = yes Storage = NDMPFile Volume Retention = 365 days # one year Maximum Volume Bytes = 50G # Limit Volume size to something reasonable Maximum Volumes = 100 # Limit number of Volumes in Pool } Configuration in bareos-sd.conf: # # Normal SD config block, should enable the NDMP protocol here otherwise it won't listen # on port 10000. # Storage { Name = .... ... NDMP Enable = yes } # # This entry gives the DMA in the Director access to the bareos SD via the NDMP protocol. # This option is used via the NDMP protocol to open the right TAPE AGENT connection to your # Bareos SD via the NDMP protocol. The initialization of the SD is done via the native protocol # and is handled via the PairedStorage keyword. # Ndmp { Name = ...-ndmp-dma # Can be any name but normally you should use the name of the Director here. Username = ndmp # Same username as you specified in the NDMPFile storage definition. Password = test # Same password as you specified in the NDMPFile storage definition. AuthType = Clear # Clear == Clear Text, MD5 == Challenge protocol } bareos-Release-14.2.6/README.dbconfig000066400000000000000000000107041263011562700170740ustar00rootroot00000000000000On Debian based systems (Debian, Ubuntu, Univention Corporate Server), database configuration can be done with help of the dbconfig system. * Package: dbconfig-common * Homepage/Documentation: http://people.debian.org/~seanius/policy/dbconfig-common.html/ Install/update scenarios: * fresh install * preinstalled 2001 * preinstalled 2002 * 12: 2001 -> 2002, 13: 2001 -> 2002: update from 12 to 13 Behavior: * config file: /etc/dbconfig-common/bareos.conf * sql files stored at * /usr/share/dbconfig-common/data/bareos-database-common/upgrade/pgsql/2001 * /usr/share/dbconfig-common/data/bareos-database-common/upgrade/pgsql/2002 * /usr/share/dbconfig-common/data/bareos-database-common/upgrade/mysql/2001 * /usr/share/dbconfig-common/data/bareos-database-common/upgrade/mysql/2002 * /usr/share/dbconfig-common/data/bareos-database-common/install/pgsql * /usr/share/dbconfig-common/data/bareos-database-common/install/mysql Upgrade: * bareos-database-common.postinst * every file from /usr/share/dbconfig-common/data/bareos-database-common/upgrade/DATABASE/*, that is larger than parameter $2 (package version of replaced package) will be installed. * even if the filename "is larger" than current package version * dbconfig does not store the installed version. It uses only the old and the current package version. * in Bareos, different branches can each do a database version update, example: * 12.4.6: 2001 * 12.4.7: 2002 * 12.4.8: 2003 * 13.2.2: 2001 * 13.2.3: 2002 * 13.2.4: 2003 * using standard dbconfig this could result in following * updating from 12.4.6 to 13.2.3 would result in a database update from * 2001 (12.4.6) -> 2002 (12.4.7) -> 2003 (12.4.8) -> 2001 (13.2.2) ... => failure * Bareos modifies the dbconfig behavior by not working with package versions, but database versions: * bareos-database-common.config, bareos-database-common.postinst: * instead of passing parameter $2 (old package version), this gots translated to database version with the help of a map file (versions.map). * with the help of this, every database schema update is only be done once * how to handle package update from version without dbconfig to version with it? Bareos dbconfig will be introduced with some version >= 14.1.0. The latest database version for 12.4 and 13.2 will be 2002. Therefore we claim, that the first version using db_config will be 2003, even if it is only 2002. Using this, all existing database updates get applied. if dpkg --compare-versions "$param2_orig" lt "14.1.0"; then dbc_first_version="2003" ... fi Database Permissions by dbconfig: MySQL: GRANT USAGE ON *.* TO 'bareos'@'localhost' IDENTIFIED BY PASSWORD '*3E80BB05233BE488EE70C1D6494E2F2DB00FEBB4' GRANT ALL PRIVILEGES ON `bareos`.* TO 'bareos'@'localhost' PostgreSQL: bareos will be the database owner Testing: # bareos-database-dbconfig # ~/dbconf # fakeroot debian/rules binary # /var/lib/dpkg/info/*.postinst ... /var/log/dbconfig-common/dbc.log eval "`dbconfig-generate-include /etc/dbconfig-common/bareos-database-common.conf`" Behavior ======== noninteractive ============== export DEBIAN_FRONTEND=noninteractive echo "bareos-database-common bareos-database-common/mysql/admin-pass select linuxlinux" | debconf-set-selections postgresql ========== * install * /etc/dbconfig-common/bareos-database-common.conf created * db: setup * update from 12.4: * updates db_version from 2001 to 2002. * update from 13.2: * db_version is already 2002. It detects, nothing to do. * update dbconfig already configured * ? mysql ===== * install * /etc/dbconfig-common/bareos-database-common.conf created * db: setup * dbpass must be set to bareos-dir.conf * update from 12.4: * updates db_version from 2001 to 2002. * update from 13.2: * db_version is already 2002. It detects, nothing to do. * update dbconfig already configured * ? sqlite3 ======= * install * /etc/dbconfig-common/bareos-database-common.conf created * db: setup * creates link from /var/lib/bareos/bareos.db to bareos * update from 12.4: * updates db_version from 2001 to 2002. * update from 13.2: * db_version is already 2002. It detects, nothing to do. * creates link from /var/lib/bareos/bareos.db to bareos * update dbconfig already configured * ? bareos-Release-14.2.6/README.md000066400000000000000000000373171263011562700157320ustar00rootroot00000000000000[BAREOS](http://www.bareos.org/) is a fork of the Bacula project. If you want to contribute somethings to this repo please read our contribution policy at https://www.bareos.org/en/howto-contribute.html This source code has the following changes (highlevel) compared with Bacula 5.2.13 (original version forked.): Release 14.2.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=master)](https://travis-ci.org/bareos/bareos) * Configuration engine refactoring in preparation for configuration API. * Accurate mode refactoring * Data storage abstraction * In memory hashtable (same as previously) * LMDB (Lightning Memory DB same as used in OpenLDAP.) * Python FD plugin base class abstraction for Python plugin writers. * Added missing methods to Python FD class should now have all methods and structures that C plugin has. * Fixed most important high level coding problems found by Coverity scans. * Disable a client (analog to disable job but then for all jobs of a certain client.) * Disable a schedule (analog to disable job but then for all jobs triggered by that schedule.) * Cleanup of more global variables. * Make scripting more robust for getting the database engine used. * Debian packaging got major overhaul. * dbconfig used for database configuration on debian based distributions. * dh_installinit used for init scripts on debian based distributions. * The LICENSE text is more inline with what debian requires for the debian packaging. * Bug fixes to bugs found by Coverity scans. * Added prototype of CRL (Certificate Revocation List) reload logic for openssl. * Limit storage list to autochangers automatically when a command makes sense only on autochangers. * Exclude Dir containting extended to allow multiple settings. * Added elapsed time printing in restore jobs. * Some tools are installed into bindir instead of sbindir now. * Traymonitor now shows a red icon when there are connection or authentication problems with a server. * CentOS 7 and RHEL7 support added to build system. * Fixed several problems with copy and migration jobs to make them work better. * Do not cancel the copy/migration job on certain events. * When you configure your Copy and Migration Jobs now without a dummy client/fileset you get the following: * Jobs now show the actual client of the original job. * Jobs now show the actual level of the the original job. * Jobs now show the actual fileset of the original job. * The jobs data spooling setting is now only used when its not enabled already. * In the old situation the disabling of data spooling in the Job would disable a command line override to enable spooling. * The printing of Client and FileSet and Level is restored now they are set with sensible info. * Disabled checking client concurrency for Copy and Migration Jobs. * As the client is not contacted anyway we are now only limited by the storage concurrency. * Allow to read from file type devices multiple times * A read volume on a file type device can now be reserved by multiple jobs and when the jobs use the same volume they can execute at the same time when the right concurrency is met on the other resources. * Added a prototype of a CEPHFS storage backend. * Added support for dynamic loading of storage backends in the storage daemon. * File storage is always loaded. * Tape/GFAPI/RADOS/... can be loaded dynamically (simular to what we alread had for database backends.) * All shared code between the different storage programs (bareos-sd, btape, ...) is now in a new shared library. * VTAPE is removed from the code base (Use MHVTL). * Initial support for TAPEALERT is added. * Storage daemon statistics gathering. * Some preliminary work for allowing to have audit events. * Use a special backend dir to store both catalog and storage backends. * Support for NotToBackup Registry Key on windows. * On the packaging side we now store the bareos libs in a subdir. (e.g. /usr/lib/bareos, /usr/lib64/bareos) Release 14.1.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=master)](https://travis-ci.org/bareos/bareos) * Windows DIR. * Support for different blocksizes (e.g. per volume blocksize) for better performance. * Preliminary support for Cloud storage backends: * GFAPI (Gluster FileSystem) (tested simple backup and restore, needs more tests) * Object storage (S3/Swift etc.) using libdroplet (Needs patched bareos libdroplet) (Due to unusable VFS abstraction not working). * Rados (CEPH) (tested simple backup and restore, needs more tests) Release 13.4.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=master)](https://travis-ci.org/bareos/bareos) * First attempt at supporting IBM lin_tape driver. * Fix storage daemon plugin interface. * AIX compile fixes. * Catalog backend scripting reworked. * Python plugins (fd/sd/dir) * Windows SD. * Support for Univention packages. * Bpipe plugin upgraded to new plugin config parser. * Socket abstraction (TCP supported, prototype for SCTP and UDT sockets). * Windows enhancements * Volume Mountpoints support (VMP). * Use GetFileInformationByHandleEx to get real changetime. * Windows dedup support * Initial support for Windows EFS filesystems Release 13.3.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=master)](https://travis-ci.org/bareos/bareos) * NDMP enhancements (first code for doing filelevel restores, preliminary). * Plugin framework enhancements. * Auto inflation/deflation storage daemon plugin (needs more testing). * Interactive path selection refactoring. * Add config option for storing a diagnostic device. * Plugin framework enhancements. * Conditionally enable VSS. * Refactor windows version detection code. * Implement plugin options passing. * Upgrade all filed plugins to use fd_common.h * Windows config files admin-only access. * Use modern autoconf idioms. * Enhanced help for run and restore command. * Add command for doing a name resolution on client. * Implement a store_alist_dir function. * Fill the process environment with an BAREOS_CFGDIR. * Cleanup win api compat layer. * Sortable tables in bRestore. * Copy job definition requires unnecessary settings (relax config). * Added usage to the plugin information block. * Make new diskonly configs the default installed configs. * Private connection to database for some long running operations. * Plugin to do backup of Microsoft Sql Server (mssql) server. * Config engine redesign Phase 1. Release 13.2.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=bareos-13.2)](https://travis-ci.org/bareos/bareos) * Allow to cancel multiple jobids with cancel cmd from bconsole. Release 13.1.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=bareos-13.2)](https://travis-ci.org/bareos/bareos) * Allow cancel by JobId on storage daemon. (#13) * Security (filed) * Implementation of an allowed scriptdir keyword (#31) * Implementation of an allowed job command keyword (#32) * Cleanup of compression framework (#34) * Encryption cipher is hardcoded (#46) * Job migration/copy between different SDs (#7) * Use open_bpipe wrapper in bpipe plugin (#104) * Side effect of using open_bpipe is that you can only call a binary or a script like all other things in Bareos e.g. runscripts etc. If you want to use a direct cmdline you need to embed the cmdline in a sh -c 'cmdline ...' * Add firewall friendly reverse data channel initialization. * instead of FD connecting to SD for backup, restore and verify the client is defined as a passive client and the Director instructs the SD to connect to the FD. So no need for puching holes in your firewall for returning data traffic but initiate all connections from the inside to the outside. The default is still non passive mode but for external clients in an DMZ or on the Internet you can define the client as a passive client. Release 12.4.x ============== [![Build Status](https://travis-ci.org/bareos/bareos.png?branch=bareos-12.4)](https://travis-ci.org/bareos/bareos) * First attempt at adding a rerun command. * Pass the restore context as parameter to display_job_parameters * When showing the pool source show if it was set on the cmdline. * Link bacula using libumem on Solaris the better multithreaded allocator * Rewrite find_one_file using inline functions so its better readable. * Add support for backtrace dumps on Solaris * Add a bstrinlinecpy function which allows for overlapping copies. * Major overhaul of configure subsystem. * Rewrite the restore stream processing somewhat so its better readable. * Use bstr functions whereever possible. * Major overhaul of config tables and layout of code. * Backport catalog changes * Backport of dynamic loadable backends and sql pooling. * First attempt at adding a fileset size option. * Replace the mntent cache htable with a dlist. * Add safeguard to append_file function for empty filepatterns. * Modify block device restore * First attempt at adding fileset shadowing detection. * Reindent cmdline table. * Reindent config tables without space allignment. * Add sd and dir plugin dir to build targets. * Do not check for backend when --enable-client-only is given. * Backported quota support. * Import/Export of volumes from bconsole and BAT with full support in bareos-dir and bareos-sd * Cleanup of dird * Add an autochanger transfer option. * Add extra function to update database with new data. * Allow get_user_slot_list to search for specific argument. * Tweak layout of status slots * Tweak status slots no need to get a drive * Tweak update slots only ask for drive with scan option. * First try at implementing Import/Export GUI. * Add better support for multi drive autochangers. * Change drive selection dialog. * Allow export when a volume is loaded in a drive. * Repopulate the media view on enabling the pane. * Do not show import/export slots in contents overview. * Repopulate panes in BAT when they get focus again. * Allow a move slots operation from BAT. * Upgrade libtool to 2.4.2 * Bring autoconf stuff to 2.68 version. * See if adding ENGINE initialization to openssl makes it use hw crypto. * Fix help text and comments on list and llist cmd. * Output .help item= as machine parseable data. * Need a way to express we want a private database connection. * Implement an unformated list type NF_LIST * Use NF_LIST e.g. non formated list for the files and basefiles of a job. * Implement a special version of NF_LIST e.g. RAW_LIST * Use RAW_LIST e.g. no formated raw output list for the job log of a job * Add basic backup/restore only mode. * Replace all bnet_sig and bnet_close. * Sort the prototypes in the protos.h header. * Added sample postgresql stored procedures for lstat field. * Use bools instead of integers for db functions. * Change catalog code to use a single exit from function. * Do not use useless NULL arguments to db_sql_query * Uncripple storage daemon plugins. * Add support for newer AIX flags for acl retrieval. * Add mount/unmount storage daemon plugin event. * Implement baculaRegisterEvents proper. * Allow the stored plugin to override the volume status. * Use MAX_BLOCK_LENGTH instead of hardcoded 4096000 * Add clone job jobcode * Allow open_mail_pipe to use extended jobcodes. * Capture error in bpipe plugin. * Do not define types in prototype header. * Add additional storage plugin events. * Align all plugin headers. * Added support for loading plugins in btools. * Use a generic plugin info structure for all plugins (fd, sd, dir) instead of a per daemon one with the same content. * Only export load and unload symbols from plugins as "C" symbols for dynamic loading not everything. * Added support for poll POSIX interface next to the normal POSIX select support. Created basic wrappers so we can reuse some code. * Restored version browser in BAT, although it may be broken its replacement also has problems of his own. For now make both available and give the user something to choose something somewhat broken or something seriously broken. * Possibilty to schedule Jobs on last Sunday-Saturday of the month. * Deprecated old embeded python support in all daemons to be replaced with daemon plugins which interface with python. * Increase name lengths so director/stored/filed names of more than 30 characters can be used. * Allow users to test plugins from a plugtest binary when developing. * Deprecated wxwindows console. * Deprecated old tray-monitor use qt-tray-monitor instead. * Update config parser to allow default strings and make it more flexible. * Warn users when they are using deprecated keywords in their config. * Deprecated old runbeforejob/runafterjob protocol and switch to use new runjob protocol (introduced in 2006) for every runjob. * Deprecated DVD support. * Allow nextpool override from run cmdline. * Allow nextpool override from Job definition. * Add support for auto expanding drive selection on windows. * Add default piddir and workingdir settings to ease configuration. * Turn off client autopruning by default. * Extend scheduler to allow to perform modulo scheduling. * Implemented feature request 14 (Possibilty to schedule Jobs on last Friday of the month) * Implemented feature request 34 (Command that releases all drives in an autochanger) * SCSI crypto support using a storage daemon plugin * Native NDMP backup/restore with DataManagementAgent (DMA) in director and NDMP Tape Server support int the storage daemon. Currently all or nothing restore for NDMP. * Automatic sending of BSR (at least of the Catalog DB) vie email (#24) * Tray-monitor shows backup activity by blinking icon Long standing bugs fixed (bug numbers are from the bacula bug database): * Implement feature request #1698 * Proper fix #1764 ld: warning: symbol plugin_list has differing sizes * Add the essentials from bugreport #1846 * Fix bug #1739 level overides ignore user input. * Fix bug #1679 Job Overrides are Not listed In Manual Run Confirmation * Fix bug #1965 Can not unmount with a 2-drive-library in BAT * Fix bug #1955 bconsole inconsistent with response handling * Fix bug #1978/#1962 Job is flagged if post-run script returns non-zero * Fix bug #1966 bconsole does not show completions for some commands * Fix bug #1960 qformlayout.h requires qt 4.4 Build System ============ * Fully new building system used for compiling and packaging the software * Based on [Open Build System](https://build.opensuse.org/) * Packages are build for: * CentOS 5 * CentOS 6 * Debian 6.0 * Debian 7.0 * Fedora 18 * Fedora 19 * RedHat Enterprise Linux 5 (RHEL5) * RedHat Enterprise Linux 6 (RHEL6) * Suse Linux Enterprise 11 SP1 (SLE_11_SP1) * Suse Linux Enterprise 11 SP2 (SLE_11_SP2) * Suse Linux Enterprise 11 SP3 (SLE_11_SP3) * Univention 3.1 * Univention 3.2 * OpenSuse 11.4 * OpenSuse 12.1 * OpenSuse 12.2 * OpenSuse 12.3 * OpenSuse 13.1 * OpenSuse factory * Ubuntu 10.04 * Ubuntu 12.04 * Windows (32 and 64 Bit) * Fully automatic generation of new packages within one hour after new release of software or bugfix. * Fully automatic continuos integration tests of new packages with all supported Linux distributions * Windows * New clean MINGW based windows Makefile set based on integration into OBS * Use native libraries available in OBS for MINGW32 and MINGW64 (no more deppkgs) * No longer based on archaic build system but state of the art and maintained OBS crosscompiling * Automatic creation of NSI installer packages * Supports of silent installs * OBS uses source services to checkout current software directly from git * see http://en.opensuse.org/openSUSE:Build_Service_private_instance_software_live_cycle bareos-Release-14.2.6/README.scsicrypto000066400000000000000000000352551263011562700175330ustar00rootroot00000000000000LTO4 and LTO5 drives and other modern tape drives support hardware encryption. There are several ways of using encryption with these drives The following three types of key management are available for doing encryption. The transmission of the keys to the volumes is accomplished by: - A backup application that supports Application Managed Encryption (AME) - A tape library that supports Library Managed Encryption (LME) - Using a Key Management Appliance (KMA). We added support for Application Managed Encryption (AME) scheme where on labeling a crypto key is generated for a volume and when the volume is mounted the crypto key is loaded and when unloaded the key is cleared from the memory of the Tape Drive using the SCSI SPOUT command set. If you have implemented Library Managed Encryption (LME) or a Key Management Appliance (KMA) there is no need to have support from Bareos on loading and clearing the encryption keys as either the Library knows the per volume encryption keys itself or it will ask the KMA for the encryption key when it needs it. For big installations you might consider using a KMA but the Application Managed Encryption implemented in Bareos should also scale rather well and has low overhead as the keys are only loaded and cleared when needed. How does it all work: - the libbareos library has some new features: - crypto_wrap.c - Implements a RFC3394 based wrapping of crypto keys - crypto_cache.c - Implements a cache of wrapped crypto keys used when we cannot ask the director for the key e.g. on startup of the storage daemon. - passphrase.c - Implements generation of semi-random passphrases - scsi_lli.c - Implements a lowlevel interface to the tape drive for several ioctl interfaces available on some modern UNIX platforms. Current supported platforms are: - Linux (SG_IO ioctl interface) (tested) - Solaris (USCSI ioctl interface) (tested) - FreeBSD (libcam interface) - NetBSD (SCIOCCOMMAND ioctl interface) - OpenBSD (SCIOCCOMMAND ioctl interface) - scsi_crypto.c - Implements sending of SCSI Security Protocol IN (SPIN) and SCSI Security Protocol OUT (SPOUT) pages using the scsi_lli interface. - A new tool named bscrypto allows you to manipulate the tape drive. It is mostly used for Disaster Recovery (DR) purposes. The storage daemon and the btools (bls, bextract, bscan, btape, bextract) will use a so called storage daemon plugin to perform the setting and clearing of the encryption keys. To bootstrap the encryption support and for populating things like the crypto cache with encryption keys of volumes that you want to scan you need to use the bscrypto tool. The bscrypto tools has the following capabilities: - Generate a new passphrase - to be used as a so called Key Encryption Key (KEK) for wrapping a passphrase using RFC3394 key wrapping with aes-wrap - or - - for usage as a clear text encryption key loaded into the tape drive. - Base64 encode a key if requested - Generate a wrapped passphrase which performs the following steps: - generate a semi random clear text passphrase - wrap the passphrase using the Key Encryption Key using RFC3394 - base64 encode the wrapped key (as the wrapped key is binary, we always need to base64-encode it in order to be able to pass the data as part of the director to storage daemon protocol - show the content of a wrapped or unwrapped keyfile This can be used to reveal the content of the passphrase when a passphrase is stored in the database and you have the urge to change the Key Encryption Key. Normally I would urge people to not change their Key Encryption Key as this means that you have to redo all your stored encryption keys as they are stored in the database wrapped using the Key Encryption Key available in the config during the label phase of the volume - Clear the crypto cache on the machine running the bareos-sd which keeps a cache of used encryption keys which can be used when the bareos-sd is restarted without the need to connect to the bareos-dir to retrieve the encryption keys. - Set the encryption key of the drive - Clear the encryption key of the drive - Show the encryption status of the drive - Show the encryption status of the next block (e.g. volume) - Populate the crypto cache with data - A new storage daemon plugin is added named scsicrypto-sd which hooks into the "unload", "label read", "label write" and "label verified" events for loading and clearing the key. It checks the drive if it needs to clear it by either using a internal state if it loaded a key before or when enabled via a special option which first issues an encrytion status query. When there is a connection to the director and the volume information is not available it will ask the director for the data on the currently loaded volume. When no connection is available a cache is used which should contain the most recently mounted volumes. When an encryption key is available it is loaded into the drives memory. - The director is extended with additional code for handling hardware data encryption. On a label of a volume the extra keyword "encrypt" will force the director to generate a new semi random passphrase for the volume and this passphrase is stored in the database as part of the media information. A passphrase is always stored in the database base64 encoded and when a so called Key Encryption Key is set in the config of the director the passphrase is first wrapped using RFC3394 key wrapping and then base64 encoded. By using key wrapping the keys in the database are save against people sniffing the info as the data is still encrypted using the Key Encryption Key (which in essense is just an extra passphrase of the same length as the volume passphrases used) When the storage daemon needs to mount the volume it will ask the director for the volume information and that protocol is extended with the exchange of the base64 wrapped encryption key (passphrase). The storage daemon has an extra config option in which it records the Key Encryption Key of the particular director and as such can unwrap the key sended into the original passphrase. As can be seen from the above info we don't allow the user to enter a passphrase but generate a semi random passphrase using the openssl random functions (if available) and convert that into a readable ASCII stream of letters, numbers and most other characters other than the quotes and space etc. This will give much stronger passphrase than when requesting the info from a user, as we store things in the database the user never has to enter these passphrases. The volume label is written unencrypted to the volume so we can always recognize a Bareos volume. When the key is loaded onto the drive we set the decryption mode to mixed so we can read both unencrypted and encrypted data from the volume. When there is no key loaded or the wrong key is loaded the drive will give an IO error when trying to read the volume. For disaster recovery you can store the Key Encryption Key and the content of the wrapped encryption keys somewhere save and the bscrypto tool together with the scsicrypto-sd plugin can be used to get access to your volumes when you ever lose your complete environment. When you don't want to use the scsicrypto-sd plugin when doing DR and you are only reading one volume you can also set the crypto key using the bscrypto tool because we use the mixed decryption mode you can set the right encryption key before reading the volume label as in mixed mode you can read both encrypted and unencrypted data from a volume. When you need to read more then one volume you better use the scsicrypto-sd plugin with things like bscan/bextract as the plugin will then auto load the correct encryption key when it loads the volume just as what the storage daemon does when performing backups and restores. The volume label is unencrypted so a volume can also be recognized by a non encrypted installation but it won't be able to read the actual data from it. Using an encrypted volume label doesn't add much security (there is no security related info in the volume label anyhow) and it makes it harder to recognize either a labeled volume with encrypted data v.s. a unlabeled new volume (both would return an IO-error on read of the label.) The initial setup of SCSI crypto looks something like this: - Run configure with your normal configure options and add the --enable-scsi-crypto option. - Build the Bareos programs and package/install them in the normal way. - Generate a Key Encryption Key e.g. bscrypto -g - === Security Setup === Some security levels need to be increased for the storage daemon to be able to use the low level SCSI interface for setting and getting encryption status on a tape device. The following additional security is needed for the following operating systems: - Linux (SG_IO ioctl interface) The user running the storage daemon needs the following additional capabilities: CAP_SYS_RAWIO (See capabilities(7)) On older kernels it can be you need CAP_SYS_ADMIN try CAP_SYS_RAWIO first and if that doesn't work try CAP_SYS_ADMIN When you are running the storage daemon as an other user then root (which has the CAP_SYS_RAWIO capability) you need to add it to the current set of capabilities. When you are using systemd you could add this additional capability to the CapabilityBoundingSet parameter. For systemd add to the bareos-sd.service the following: Capabilities=cap_sys_rawio+ep You can also setup the extra capability on bscrypto and bareos-sd by running the following cmd: # setcap cap_sys_rawio=ep bscrypto # setcap cap_sys_rawio=ep bareos-sd Check the setting with # getcap -v bscrypto # getcap -v bareos-sd getcap and setcap are part of libcap-progs which may not be installed on your system. - Solaris (USCSI ioctl interface) The user running the storage daemon needs the following additional privileges: PRIV_SYS_DEVICES (See privileges(5)) When you are running the storage daemon as an other user then root (which has the PRIV_SYS_DEVICES privilege) you need to add it to the current set of privileges. This can be setup by setting this either as a project for the user or as a extra privileges in the SMF definition starting the storage daemon. The SMF setup is the cleanest. For SMF make sure you have something like this in the instance block. === Changes in bareos-sd.conf === - Put the Key Encryption Key into the bareos-sd.conf under the director entry in that config for the specific director you are creating the config for. e.g. Key Encryption Key = "" - Enable the loading of storage daemon plugins by setting the plugin dir in the bareos-sd.conf e.g. Plugin Directory = - Enable the SCSI encryption option in the device configuration section of the drive in the bareos-sd.conf. e.g. Drive Crypto Enabled = Yes - When you want the plugin to probe the drive for its encryption status if it needs to clear a pending key enable the Query Crypto Status option in the device configuration section of the drive in the bareos-sd.conf e.g. Query Crypto Status = Yes === Changes in bareos-dir.conf === - Put the Key Encryption Key into the bareos-dir.conf under the director config item named Key Encryption Key e.g. Key Encryption Key = "" - restart sd and dir - Label a volume with the encrypt option e.g. label slots=1-5 barcodes encrypt For Disaster Recovery (DR) you need the following information: - Actual bareos-sd.conf with config options enabled as described above, including things like a definition of a director with the Key Encryption Key used for creating the encryption keys of the volumes. - The actual keys used for encryption of the volumes. This data needs to be availabe as a so called crypto cache file which is used by the plugin when no connection to the director can be made to do a lookup (most likely on DR). Most of the times the needed information e.g. bootstrap info is available on recently written volumes and most of the time the encryption cache will contain the most recent data so a recent copy of the bareos-sd..cryptoc file in the workingdir is most of the time enough. You can also save the info from database in a save place and use bscrypto to populate this info (VolumeNameEncryptKey) into the crypto cache file used by bextract and bscan. You can use bscrypto with the following flags to create a new or update an existing crypto cache file e.g. : # bscrypto -p /var/lib/bareos/bareos-sd..cryptoc - A valid BSR file with the location of the last save of the database makes recovery much easier. Adding a post script to the database save job could collect the needed info and make sure its stored somewhere safe. - Recover the database in the normal way e.g. for postgresql: # bextract -D -c bareos-sd.conf -V \ /dev/nst0 /tmp -b bootstrap.bsr # /usr/lib64/bareos/create_bareos_database # /usr/lib64/bareos/grant_bareos_privileges # psql bareos < /tmp/var/lib/bareos/bareos.sql Or something similar (change paths to follow where you installed the software or where the package put it.) NOTE: As described at the beginning of this README there are different types of key management: - A backup application that supports Application Managed Encryption (AME) - A tape library that supports Library Managed Encryption (LME) - Using a Key Management Appliance (KMA). If the Library is setup for LME or KMA it probably won't allow our AME setup and the scsi-crypto plugin will fail to set/clear the encryption key. To be able to use AME you need to "Modify Encryption Method" and set it to something like "Application Managed". If you decide to use LME or KMA you don't have to bother with the whole setup of AME which may for big libraries be easier, although the overhead of using AME even for very big libraries should be minimal. bareos-Release-14.2.6/autoconf/000077500000000000000000000000001263011562700162565ustar00rootroot00000000000000bareos-Release-14.2.6/autoconf/Make.common.in000066400000000000000000000054451263011562700207620ustar00rootroot00000000000000# # This file is pulled in by all the Unix Bareos Makefiles # so it has all the "common" definitions # DATE="@DATE@" LSMDATE=@LSMDATE@ VERSION=@VERSION@ VERNAME=bareos-$(VERSION)# MAINT=Bareos Gatekeeper# MAINTEMAIL=# WEBMAINT=# WEBMAINTEMAIL=# WEBPAGE=http://bareos.org# FTPSITENAME=# FTPSITEDIR=# #------------------------------------------------------------------------- SHELL = /bin/sh # Installation target directories & other installation stuff prefix = @prefix@ exec_prefix = @exec_prefix@ binprefix = manprefix = datarootdir = @datarootdir@ docdir = @docdir@ bindir = @bindir@ sbindir = @sbindir@ libdir = @libdir@ logdir = @logdir@ includedir = @includedir@ sysconfdir = @sysconfdir@ backenddir = @backenddir@ plugindir = @plugindir@ scriptdir = @scriptdir@ archivedir = @archivedir@ mandir = @mandir@ manext = 8 NO_ECHO = @ # Tools & program stuff CC = @CC@ CPP = @CPP@ CXX = @CXX@ MV = @MV@ RM = @REMOVE@ RMF = $(RM) -f CP = @CP@ LN_S = @LN_S@ SYMLINK = $(LN_S) -f SED = @SED@ AWK = @AWK@ ECHOCMD = @ECHOCMD@ CMP = @CMP@ TBL = @TBL@ AR = @AR@ GMAKE = @GMAKE@ RANLIB = @RANLIB@ MKDIR = @BUILD_DIR@/autoconf/mkinstalldirs INSTALL = @INSTALL@ # add the -s to the following in PRODUCTION mode INSTALL_PROGRAM = $(INSTALL) -m @SBINPERM@ INSTALL_LIB = $(INSTALL) -m 755 INSTALL_DATA = $(INSTALL) -m 644 INSTALL_SCRIPT = $(INSTALL) -m @SBINPERM@ INSTALL_CONFIG = $(INSTALL) -m 640 # # Libtool specific settings # DEFAULT_OBJECT_TYPE = @DEFAULT_OBJECT_TYPE@ DEFAULT_ARCHIVE_TYPE = @DEFAULT_ARCHIVE_TYPE@ DEFAULT_SHARED_OBJECT_TYPE = @DEFAULT_SHARED_OBJECT_TYPE@ LIBTOOL = @BUILD_DIR@/libtool LIBTOOL_TAG = CXX LIBTOOL_COMPILE = @LIBTOOL@ --silent --tag=$(LIBTOOL_TAG) --mode=compile LIBTOOL_LINK = @LIBTOOL@ --silent --tag=$(LIBTOOL_TAG) --mode=link LIBTOOL_INSTALL = @LIBTOOL@ --silent --tag=$(LIBTOOL_TAG) --mode=install LIBTOOL_INSTALL_FINISH = @LIBTOOL@ --silent --tag=$(LIBTOOL_TAG) --finish --mode=install LIBTOOL_UNINSTALL = @LIBTOOL@ --silent --tag=$(LIBTOOL_TAG) --mode=uninstall LIBTOOL_CLEAN = @LIBTOOL@ --silent --tag=$(LIBTOOL_TAG) --mode=clean # Flags & libs CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ TTOOL_LDFLAGS = @TTOOL_LDFLAGS@ #DEFS = @DEFS@ @LOCAL_DEFS@ LIBS = @LIBS@ WRAPLIBS = @WRAPLIBS@ DINCLUDE = @DINCLUDE@ DLIB = @DLIB@ PYTHON_LIBS = @PYTHON_LIBS@ OPENSSL_INCLUDES = @OPENSSL_INC@ OPENSSL_LIBS = @OPENSSL_LIBS@ GNUTLS_INCLUDES = @GNUTLS_INC@ GNUTLS_LIBS = @GNUTLS_LIBS@ DLLIBS = @LIBADD_DLOPEN@ # Windows (cygwin) flags WCFLAGS = @WCFLAGS@ WLDFLAGS = @WLDFLAGS@ # X Include directory #XINC = @X_CFLAGS@ @XPM_CFLAGS@ # extra libraries needed by X on some systems, X library location #XLIB = @X_LIBS@ @XPM_LIBS@ -lX11 @X_EXTRA_LIBS@ # End of common section of the Makefile #------------------------------------------------------------------------- bareos-Release-14.2.6/autoconf/aclocal.m4000066400000000000000000000034641263011562700201250ustar00rootroot00000000000000# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_include([libtool/libtool.m4]) m4_include([libtool/ltoptions.m4]) m4_include([libtool/ltsugar.m4]) m4_include([libtool/ltversion.m4]) m4_include([libtool/lt~obsolete.m4]) m4_include([libtool/ltdl.m4]) m4_include([gettext/codeset.m4]) m4_include([gettext/gettext.m4]) m4_include([gettext/glibc2.m4]) m4_include([gettext/glibc21.m4]) m4_include([gettext/iconv.m4]) m4_include([gettext/intdiv0.m4]) m4_include([gettext/intmax.m4]) m4_include([gettext/inttypes-pri.m4]) m4_include([gettext/inttypes.m4]) m4_include([gettext/inttypes_h.m4]) m4_include([gettext/isc-posix.m4]) m4_include([gettext/lcmessage.m4]) m4_include([gettext/lib-ld.m4]) m4_include([gettext/lib-link.m4]) m4_include([gettext/lib-prefix.m4]) m4_include([gettext/longdouble.m4]) m4_include([gettext/longlong.m4]) m4_include([gettext/nls.m4]) m4_include([gettext/po.m4]) m4_include([gettext/printf-posix.m4]) m4_include([gettext/progtest.m4]) m4_include([gettext/signed.m4]) m4_include([gettext/size_max.m4]) m4_include([gettext/stdint_h.m4]) m4_include([gettext/uintmax_t.m4]) m4_include([gettext/ulonglong.m4]) m4_include([gettext/wchar_t.m4]) m4_include([gettext/wint_t.m4]) m4_include([gettext/xsize.m4]) m4_include([bareos/db.m4]) m4_include([bareos/largefiles.m4]) m4_include([bareos/os.m4]) bareos-Release-14.2.6/autoconf/bareos/000077500000000000000000000000001263011562700175315ustar00rootroot00000000000000bareos-Release-14.2.6/autoconf/bareos/compare-version.m4000066400000000000000000000073031263011562700231070ustar00rootroot00000000000000dnl # Copyright © 2008 Tim Toolan dnl # dnl # Copying and distribution of this file, with or without modification, dnl # are permitted in any medium without royalty provided the copyright notice dnl # and this notice are preserved. dnl ######################################################################### AC_DEFUN([AX_COMPARE_VERSION], [ AC_PROG_AWK # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. AS_VAR_PUSHDEF([A],[ax_compare_version_A]) A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` AS_VAR_PUSHDEF([B],[ax_compare_version_B]) B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary dnl # then the first line is used to determine if the condition is true. dnl # The sed right after the echo is to remove any indented white space. m4_case(m4_tolower($2), [lt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [gt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [le],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` ], [ge],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` ],[ dnl Split the operator from the subversion count if present. m4_bmatch(m4_substr($2,2), [0],[ # A count of zero means use the length of the shorter version. # Determine the number of characters in A and B. ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` # Set A to no more than B's length and B to no more than A's length. A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` ], [[0-9]+],[ # A count greater than zero means use only that many subversions A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` ], [.+],[ AC_WARNING( [illegal OP numeric parameter: $2]) ],[]) # Pad zeros at end of numbers to make same length. ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" B="$B`echo $A | sed 's/./0/g'`" A="$ax_compare_version_tmp_A" # Check for equality or inequality as necessary. m4_case(m4_tolower(m4_substr($2,0,2)), [eq],[ test "x$A" = "x$B" && ax_compare_version=true ], [ne],[ test "x$A" != "x$B" && ax_compare_version=true ],[ AC_WARNING([illegal OP parameter: $2]) ]) ]) AS_VAR_POPDEF([A])dnl AS_VAR_POPDEF([B])dnl dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. if test "$ax_compare_version" = "true" ; then m4_ifvaln([$4],[$4],[:])dnl m4_ifvaln([$5],[else $5])dnl fi ]) dnl AX_COMPARE_VERSION bareos-Release-14.2.6/autoconf/bareos/db.m4000066400000000000000000001124121263011562700203610ustar00rootroot00000000000000AC_DEFUN([BA_CHECK_DBI_DB], [ AC_MSG_CHECKING(for DBI support) AC_ARG_WITH(dbi, AC_HELP_STRING([--with-dbi@<:@=DIR@:>@], [Include DBI support. DIR is the DBD base install directory, default is to search through a number of common places for the DBI files.]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/local/include/dbi/dbi.h; then DBI_INCDIR=/usr/local/dbi/include if test -d /usr/local/lib64; then DBI_LIBDIR=/usr/local/lib64 else DBI_LIBDIR=/usr/local/lib fi DBI_BINDIR=/usr/local/bin elif test -f /usr/include/dbi/dbi.h; then DBI_INCDIR=/usr/include if test -d /usr/lib64; then DBI_LIBDIR=/usr/lib64 else DBI_LIBDIR=/usr/lib fi DBI_BINDIR=/usr/bin elif test -f $prefix/include/dbi/dbi.h; then DBI_INCDIR=$prefix/include if test -d $prefix/lib64; then DBI_LIBDIR=$prefix/lib64 else DBI_LIBDIR=$prefix/lib fi DBI_BINDIR=$prefix/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find dbi.h in standard locations) fi if test -d /usr/local/lib/dbd; then DRIVERDIR=/usr/local/lib/dbd if test -d /usr/local/lib64/dbd; then DRIVERDIR=/usr/local/lib64/dbd else DRIVERDIR=/usr/local/lib/dbd fi elif test -d /usr/lib/dbd; then DRIVERDIR=/usr/lib/dbd if test -d /usr/lib64/dbd; then DRIVERDIR=/usr/lib64/dbd else DRIVERDIR=/usr/lib/dbd fi elif test -d $prefix/lib/dbd; then if test -d $prefix/lib64/dbd; then DRIVERDIR=$prefix/lib64/dbd else DRIVERDIR=$prefix/lib/dbd fi elif test -d /usr/local/lib64/dbd; then DRIVERDIR=/usr/local/lib64/dbd elif test -d /usr/lib64/dbd; then DRIVERDIR=/usr/lib64/dbd elif test -d $prefix/lib64/dbd; then DRIVERDIR=$prefix/lib64/dbd else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find DBD drivers in standard locations) fi else if test -f $withval/dbi.h; then DBI_INCDIR=$withval DBI_LIBDIR=$withval DBI_BINDIR=$withval elif test -f $withval/include/dbi/dbi.h; then DBI_INCDIR=$withval/include if test -d $withval/lib64; then DBI_LIBDIR=$withval/lib64 else DBI_LIBDIR=$withval/lib fi DBI_BINDIR=$withval/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid DBI directory $withval - unable to find dbi.h under $withval) fi if test -d $withval/dbd; then DRIVERDIR=$withval/dbd elif test -d $withval/lib/; then if test -d $withval/lib64/dbd; then DRIVERDIR=$withval/lib64/dbd else DRIVERDIR=$withval/lib/dbd fi elif test -d $withval/lib64/dbd; then DRIVERDIR=$withval/lib64/dbd else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid DBD driver directory $withval - unable to find DBD drivers under $withval) fi fi if test x$DBI_LIBDIR != x; then DBI_INCLUDE=-I$DBI_INCDIR if test x$use_libtool != xno; then DBI_LIBS="-R $DBI_LIBDIR -L$DBI_LIBDIR -ldbi" else DBI_LIBS="-L$DBI_LIBDIR -ldbi" fi DBI_LIB=$DBI_LIBDIR/libdbi.a DBI_DBD_DRIVERDIR="-D DBI_DRIVER_DIR=\\\"$DRIVERDIR\\\"" DB_LIBS="${DB_LIBS} ${DBI_LIBS}" AC_DEFINE(HAVE_DBI, 1, [Set if you have the DBI driver]) AC_MSG_RESULT(yes) if test -z "${db_backends}"; then db_backends="DBI" else db_backends="${db_backends} DBI" fi if test -z "${DB_BACKENDS}" ; then DB_BACKENDS="dbi" else DB_BACKENDS="${DB_BACKENDS} dbi" fi uncomment_dbi=" " dnl ------------------------------------------- dnl Push the DB_PROG onto the stack of supported database backends for DBI dnl ------------------------------------------- DB_BACKENDS="${DB_BACKENDS} ${DB_PROG}" dnl ------------------------------------------- dnl Check if dbi supports batch mode dnl ------------------------------------------- if test "x$support_batch_insert" = "xyes"; then if test $DB_PROG = postgresql; then AC_CHECK_LIB(pq, PQisthreadsafe, AC_DEFINE(HAVE_PQISTHREADSAFE, 1, [Define to 1 if you have the `PQisthreadsafe' function.])) AC_CHECK_LIB(pq, PQputCopyData, AC_DEFINE(HAVE_PQ_COPY, 1, [Define to 1 if you have the `PQputCopyData' function.])) test "x$ac_cv_lib_pq_PQputCopyData" = "xyes" pkg=$? if test $pkg = 0; then AC_DEFINE(HAVE_POSTGRESQL_BATCH_FILE_INSERT, 1, [Define to 1 if PostgreSQL DB batch insert code enabled]) fi fi fi fi else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ]) AC_SUBST(DBI_LIBS) AC_SUBST(DBI_INCLUDE) AC_SUBST(DBI_BINDIR) AC_SUBST(DBI_DBD_DRIVERDIR) ]) AC_DEFUN([BA_CHECK_DBI_DRIVER], [ db_prog=no AC_MSG_CHECKING(for DBI drivers support) AC_ARG_WITH(dbi-driver, AC_HELP_STRING([--with-dbi-driver@<:@=DRIVER@:>@], [Suport for DBI driver. DRIVER is the one DBI driver like Mysql, Postgresql, others. Default is to not configure any driver.]), [ if test "$withval" != "no"; then case $withval in "mysql") db_prog="mysql" MYSQL_CONFIG=`which mysql_config 2>/dev/null` if test "x${MYSQL_CONFIG}" != x; then MYSQL_BINDIR="${MYSQL_CONFIG%/*}" ${MYSQL_CONFIG} --variable=pkglibdir > /dev/null 2>&1 if test $? = 0 ; then MYSQL_LIBDIR=`${MYSQL_CONFIG} --variable=pkglibdir` MYSQL_INCDIR=`${MYSQL_CONFIG} --variable=pkgincludedir` else MYSQL_LIBDIR=`${MYSQL_CONFIG} --libs | sed -e 's/.*-L//' -e 's/ .*//'` MYSQL_INCDIR=`${MYSQL_CONFIG} --include | sed -e 's/-I//'` fi fi # # See if the mysql_config gave something that is worth anything. # Some OS-es just lie about this when you ask for the library to use # they just give you back the directory its not in. # # Fallback to the old way of finding the right settings to use and hope for the best. # if test x${MYSQL_LIBDIR} = x -o \ ! \( -f ${MYSQL_LIBDIR}/libmysqlclient_r.so -o \ -f ${MYSQL_LIBDIR}/libmysqlclient_r.a \); then if test -f /usr/local/mysql/bin/mysql; then MYSQL_BINDIR=/usr/local/mysql/bin if test -f /usr/local/mysql/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/local/mysql/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/mysql/lib64/mysql else MYSQL_LIBDIR=/usr/local/mysql/lib/mysql fi elif test -f /usr/bin/mysql; then MYSQL_BINDIR=/usr/bin if test -f /usr/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64/mysql elif test -f /usr/lib/mysql/libmysqlclient_r.a \ -o -f /usr/lib/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib/mysql else MYSQL_LIBDIR=/usr/lib fi elif test -f /usr/local/bin/mysql; then MYSQL_BINDIR=/usr/local/bin if test -f /usr/local/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/local/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/lib64/mysql elif test -f /usr/local/lib/mysql/libmysqlclient_r.a \ -o -f /usr/local/lib/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/lib/mysql else MYSQL_LIBDIR=/usr/local/lib fi elif test -f $withval/bin/mysql; then MYSQL_BINDIR=$withval/bin if test -f $withval/lib64/mysql/libmysqlclient_r.a \ -o -f $withval/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64/mysql elif test -f $withval/lib64/libmysqlclient_r.a \ -o -f $withval/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64 elif test -f $withval/lib/libmysqlclient_r.a \ -o -f $withval/lib/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib/ else MYSQL_LIBDIR=$withval/lib/mysql fi else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find mysql in standard locations) fi fi if test -f $MYSQL_LIBDIR/libmysqlclient_r.so; then DB_PROG_LIB=$MYSQL_LIBDIR/libmysqlclient_r.so else DB_PROG_LIB=$MYSQL_LIBDIR/libmysqlclient_r.a fi ;; "postgresql") db_prog="postgresql" PG_CONFIG=`which pg_config 2>/dev/null` if test -n "$PG_CONFIG"; then POSTGRESQL_BINDIR=`"$PG_CONFIG" --bindir` POSTGRESQL_LIBDIR=`"$PG_CONFIG" --libdir` fi # # See if the pg_config gave something that is worth anything. # if test x${POSTGRESQL_LIBDIR} = x -o \ ! \( -f ${POSTGRESQL_LIBDIR}/libpq.so -o \ -f ${POSTGRESQL_LIBDIR}/libpq.a \); then if test -f /usr/local/bin/psql; then POSTGRESQL_BINDIR=/usr/local/bin if test -d /usr/local/lib64; then POSTGRESQL_LIBDIR=/usr/local/lib64 else POSTGRESQL_LIBDIR=/usr/local/lib fi elif test -f /usr/bin/psql; then POSTGRESQL_BINDIR=/usr/local/bin if test -d /usr/lib64/postgresql; then POSTGRESQL_LIBDIR=/usr/lib64/postgresql elif test -d /usr/lib/postgresql; then POSTGRESQL_LIBDIR=/usr/lib/postgresql elif test -d /usr/lib64; then POSTGRESQL_LIBDIR=/usr/lib64 else POSTGRESQL_LIBDIR=/usr/lib fi elif test -f $withval/bin/psql; then POSTGRESQL_BINDIR=$withval/bin if test -d $withval/lib64; then POSTGRESQL_LIBDIR=$withval/lib64 else POSTGRESQL_LIBDIR=$withval/lib fi else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find psql in standard locations) fi fi if test -f $POSTGRESQL_LIBDIR/libpq.so; then DB_PROG_LIB=$POSTGRESQL_LIBDIR/libpq.so else DB_PROG_LIB=$POSTGRESQL_LIBDIR/libpq.a fi ;; "sqlite3") db_prog="sqlite3" if test -f /usr/local/bin/sqlite3; then SQLITE_BINDIR=/usr/local/bin if test -d /usr/local/lib64; then SQLITE_LIBDIR=/usr/local/lib64 else SQLITE_LIBDIR=/usr/local/lib fi elif test -f /usr/bin/sqlite3; then SQLITE_BINDIR=/usr/bin if test -d /usr/lib64; then SQLITE_LIBDIR=/usr/lib64 else SQLITE_LIBDIR=/usr/lib fi elif test -f $withval/bin/sqlite3; then SQLITE_BINDIR=$withval/bin if test -d $withval/lib64; then SQLITE_LIBDIR=$withval/lib64 else SQLITE_LIBDIR=$withval/lib fi else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find sqlite in standard locations) fi if test -f $SQLITE_LIBDIR/libsqlite3.so; then DB_PROG_LIB=$SQLITE_LIBDIR/libsqlite3.so else DB_PROG_LIB=$SQLITE_LIBDIR/libsqlite3.a fi ;; *) AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to set DBI driver. $withval is not supported) ;; esac AC_MSG_RESULT(yes) DB_PROG=$db_prog else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ]) AC_SUBST(MYSQL_BINDIR) AC_SUBST(POSTGRESQL_BINDIR) AC_SUBST(SQLITE_BINDIR) AC_SUBST(DB_PROG) AC_SUBST(DB_PROG_LIB) ]) AC_DEFUN([BA_CHECK_MYSQL_DB], [ AC_MSG_CHECKING(for MySQL support) AC_ARG_WITH(mysql, AC_HELP_STRING([--with-mysql@<:@=DIR@:>@], [Include MySQL support. DIR is the MySQL base install directory, default is to search through a number of common places for the MySQL files.]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then MYSQL_CONFIG=`which mysql_config 2>/dev/null` if test "x${MYSQL_CONFIG}" != x; then MYSQL_BINDIR="${MYSQL_CONFIG%/*}" ${MYSQL_CONFIG} --variable=pkglibdir > /dev/null 2>&1 if test $? = 0 ; then MYSQL_LIBDIR=`${MYSQL_CONFIG} --variable=pkglibdir` MYSQL_INCDIR=`${MYSQL_CONFIG} --variable=pkgincludedir` else MYSQL_LIBDIR=`${MYSQL_CONFIG} --libs | sed -e 's/.*-L//' -e 's/ .*//'` MYSQL_INCDIR=`${MYSQL_CONFIG} --include | sed -e 's/-I//'` fi fi # # See if the mysql_config gave something that is worth anything. # Some OS-es just lie about this when you ask for the library to use # they just give you back the directory its not in. # # Fallback to the old way of finding the right settings to use and hope for the best. # if test x${MYSQL_LIBDIR} = x -o \ ! \( -f ${MYSQL_LIBDIR}/libmysqlclient_r.so -o \ -f ${MYSQL_LIBDIR}/libmysqlclient_r.a \); then if test -f /usr/local/mysql/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/mysql/include/mysql if test -f /usr/local/mysql/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/local/mysql/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/mysql/lib64/mysql else MYSQL_LIBDIR=/usr/local/mysql/lib/mysql fi MYSQL_BINDIR=/usr/local/mysql/bin elif test -f /usr/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/include/mysql if test -f /usr/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64/mysql elif test -f /usr/lib64/libmysqlclient_r.a \ -o -f /usr/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64 elif test -f /usr/lib/x86_64-linux-gnu/libmysqlclient_r.a \ -o -f /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib/x86_64-linux-gnu elif test -f /usr/lib/mysql/libmysqlclient_r.a \ -o -f /usr/lib/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib/mysql else MYSQL_LIBDIR=/usr/lib fi MYSQL_BINDIR=/usr/bin elif test -f /usr/include/mysql.h; then MYSQL_INCDIR=/usr/include if test -f /usr/lib64/libmysqlclient_r.a \ -o -f /usr/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64 else MYSQL_LIBDIR=/usr/lib fi MYSQL_BINDIR=/usr/bin elif test -f /usr/local/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/include/mysql if test -f /usr/local/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/local/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/lib64/mysql else MYSQL_LIBDIR=/usr/local/lib/mysql fi MYSQL_BINDIR=/usr/local/bin elif test -f /usr/local/include/mysql.h; then MYSQL_INCDIR=/usr/local/include if test -f /usr/local/lib64/libmysqlclient_r.a \ -o -f /usr/local/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/lib64 else MYSQL_LIBDIR=/usr/local/lib fi MYSQL_BINDIR=/usr/local/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find mysql.h in standard locations) fi fi else if test -f $withval/include/mysql/mysql.h; then MYSQL_INCDIR=$withval/include/mysql if test -f $withval/lib64/mysql/libmysqlclient_r.a \ -o -f $withval/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64/mysql elif test -f $withval/lib64/libmysqlclient_r.a \ -o -f $withval/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64 elif test -f $withval/lib/libmysqlclient_r.a \ -o -f $withval/lib/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib else MYSQL_LIBDIR=$withval/lib/mysql fi MYSQL_BINDIR=$withval/bin elif test -f $withval/include/mysql.h; then MYSQL_INCDIR=$withval/include if test -f $withval/lib64/libmysqlclient_r.a \ -o -f $withval/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64 else MYSQL_LIBDIR=$withval/lib fi MYSQL_BINDIR=$withval/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid MySQL directory $withval - unable to find mysql.h under $withval) fi fi if test x${MYSQL_LIBDIR} != x; then MYSQL_INCLUDE=-I$MYSQL_INCDIR if test -f $MYSQL_LIBDIR/libmysqlclient_r.a \ -o -f $MYSQL_LIBDIR/libmysqlclient_r.so; then if test x$use_libtool != xno; then MYSQL_LIBS="-R $MYSQL_LIBDIR -L$MYSQL_LIBDIR -lmysqlclient_r -lz" else MYSQL_LIBS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz" fi DB_LIBS="${DB_LIBS} ${MYSQL_LIBS}" fi MYSQL_LIB=$MYSQL_LIBDIR/libmysqlclient_r.a AC_DEFINE(HAVE_MYSQL, 1, [Set if you have an MySQL Database]) AC_MSG_RESULT(yes) if test -z "${db_backends}" ; then db_backends="MySQL" else db_backends="${db_backends} MySQL" fi if test -z "${DB_BACKENDS}" ; then DB_BACKENDS="mysql" else DB_BACKENDS="${DB_BACKENDS} mysql" fi dnl ------------------------------------------- dnl Check if mysql supports batch mode dnl ------------------------------------------- if test "x$support_batch_insert" = "xyes"; then dnl For mysql checking saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$MYSQL_LIBDIR" saved_LIBS="${LIBS}" LIBS="${saved_LIBS} -lz" AC_CHECK_LIB(mysqlclient_r, mysql_thread_safe, AC_DEFINE(HAVE_MYSQL_THREAD_SAFE, 1, [Define to 1 if you have the `mysql_thread_safe' function.])) if test "x$ac_cv_lib_mysqlclient_r_mysql_thread_safe" = "xyes"; then if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="MySQL" else batch_insert_db_backends="${batch_insert_db_backends} MySQL" fi fi dnl Revert after mysql checks LDFLAGS="${saved_LDFLAGS}" LIBS="${saved_LIBS}" fi else AC_MSG_RESULT(no) fi fi ],[ AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(for MySQL embedded support) AC_ARG_WITH(embedded-mysql, AC_HELP_STRING([--with-embedded-mysql@<:@=DIR@:>@], [Include MySQL support. DIR is the MySQL base install directory, default is to search through a number of common places for the MySQL files.]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/local/mysql/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/mysql/include/mysql if test -d /usr/local/mysql/lib64/mysql; then MYSQL_LIBDIR=/usr/local/mysql/lib64/mysql else MYSQL_LIBDIR=/usr/local/mysql/lib/mysql fi MYSQL_BINDIR=/usr/local/mysql/bin elif test -f /usr/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/include/mysql if test -d /usr/lib64/mysql; then MYSQL_LIBDIR=/usr/lib64/mysql else MYSQL_LIBDIR=/usr/lib/mysql fi MYSQL_BINDIR=/usr/bin elif test -f /usr/include/mysql.h; then MYSQL_INCDIR=/usr/include if test -d /usr/lib64; then MYSQL_LIBDIR=/usr/lib64 else MYSQL_LIBDIR=/usr/lib fi MYSQL_BINDIR=/usr/bin elif test -f /usr/local/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/include/mysql if test -d /usr/local/lib64/mysql; then MYSQL_LIBDIR=/usr/local/lib64/mysql else MYSQL_LIBDIR=/usr/local/lib/mysql fi MYSQL_BINDIR=/usr/local/bin elif test -f /usr/local/include/mysql.h; then MYSQL_INCDIR=/usr/local/include if test -d /usr/local/lib64; then MYSQL_LIBDIR=/usr/local/lib64 else MYSQL_LIBDIR=/usr/local/lib fi MYSQL_BINDIR=/usr/local/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find mysql.h in standard locations) fi else if test -f $withval/include/mysql/mysql.h; then MYSQL_INCDIR=$withval/include/mysql if test -d $withval/lib64/mysql; then MYSQL_LIBDIR=$withval/lib64/mysql else MYSQL_LIBDIR=$withval/lib/mysql fi MYSQL_BINDIR=$withval/bin elif test -f $withval/include/mysql.h; then MYSQL_INCDIR=$withval/include if test -d $withval/lib64; then MYSQL_LIBDIR=$withval/lib64 else MYSQL_LIBDIR=$withval/lib fi MYSQL_BINDIR=$withval/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid MySQL directory $withval - unable to find mysql.h under $withval) fi fi if test x$MYSQL_LIBDIR != x; then MYSQL_INCLUDE=-I$MYSQL_INCDIR if test x$use_libtool != xno; then MYSQL_LIBS="-R $MYSQL_LIBDIR -L$MYSQL_LIBDIR -lmysqld -lz -lm -lcrypt" else MYSQL_LIBS="-L$MYSQL_LIBDIR -lmysqld -lz -lm -lcrypt" fi MYSQL_LIB=$MYSQL_LIBDIR/libmysqld.a DB_LIBS="${DB_LIBS} ${MYSQL_LIBS}" AC_DEFINE(HAVE_MYSQL, 1, [Set if you have an MySQL Database]) AC_DEFINE(HAVE_EMBEDDED_MYSQL, 1, [Set if you have an Embedded MySQL Database]) AC_MSG_RESULT(yes) if test -z "${db_backends}"; then db_backends="MySQL" else db_backends="${db_backends} MySQL" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="mysql" else DB_BACKENDS="${DB_BACKENDS} mysql" fi dnl ------------------------------------------- dnl Check if mysql supports batch mode dnl ------------------------------------------- if test "x$support_batch_insert" = "xyes"; then dnl For mysql checking saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$MYSQL_LIBDIR" saved_LIBS="${LIBS}" LIBS="${saved_LIBS} -lz -lm -lcrypt" AC_CHECK_LIB(mysqlclient_r, mysql_thread_safe, AC_DEFINE(HAVE_MYSQL_THREAD_SAFE, 1, [Set if have mysql_thread_safe])) if test "x$ac_cv_lib_mysqlclient_r_mysql_thread_safe" = "xyes"; then if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="MySQL" else batch_insert_db_backends="${batch_insert_db_backends} MySQL" fi fi dnl Revert after mysql checks LDFLAGS="${saved_LDFLAGS}" LIBS="${saved_LIBS}" fi fi else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ]) AC_SUBST(MYSQL_LIBS) AC_SUBST(MYSQL_INCLUDE) AC_SUBST(MYSQL_BINDIR) ]) AC_DEFUN([BA_CHECK_INGRES_DB], [ AC_MSG_CHECKING(for Ingres support) AC_ARG_WITH(ingres, AC_HELP_STRING([--with-ingres@<:@=DIR@:>@], [Include Ingres support. DIR is the Ingres base install directory, default is to search through a number of common places for the Ingres files.]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f ${II_SYSTEM}/files/eqdefc.h; then INGRES_INCDIR=${II_SYSTEM}/files INGRES_LIBDIR=${II_SYSTEM}/lib INGRES_BINDIR=${II_SYSTEM}/bin elif test -f ${II_SYSTEM}/ingres/files/eqdefc.h; then INGRES_INCDIR=${II_SYSTEM}/ingres/files INGRES_LIBDIR=${II_SYSTEM}/ingres/lib INGRES_BINDIR=${II_SYSTEM}/ingres/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find eqdefc.h in standard locations) fi else if test -f $withval/files/eqdefc.h; then INGRES_INCDIR=$withval/files INGRES_LIBDIR=$withval/lib INGRES_BINDIR=$withval/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid Ingres directory $withval - unable to find Ingres headers under $withval) fi fi if test x$INGRES_LIBDIR != x; then INGRES_INCLUDE=-I$INGRES_INCDIR if test x$use_libtool != xno; then INGRES_LIBS="-R $INGRES_LIBDIR -L$INGRES_LIBDIR -lq.1 -lcompat.1 -lframe.1" else INGRES_LIBS="-L$INGRES_LIBDIR -lq.1 -lcompat.1 -lframe.1" fi DB_LIBS="${DB_LIBS} ${INGRES_LIBS}" AC_DEFINE(HAVE_INGRES, 1, [Set if have Ingres Database]) AC_MSG_RESULT(yes) if test -z "${db_backends}"; then db_backends="Ingres" else db_backends="${db_backends} Ingres" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="ingres" else DB_BACKENDS="${DB_BACKENDS} ingres" fi fi else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ]) AC_SUBST(INGRES_LIBS) AC_SUBST(INGRES_INCLUDE) AC_SUBST(INGRES_BINDIR) ]) AC_DEFUN([BA_CHECK_SQLITE3_DB], [ AC_MSG_CHECKING(for SQLite3 support) AC_ARG_WITH(sqlite3, AC_HELP_STRING([--with-sqlite3@<:@=DIR@:>@], [Include SQLite3 support. DIR is the SQLite3 base install directory, default is to search through a number of common places for the SQLite3 files.]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/local/include/sqlite3.h; then SQLITE_INCDIR=/usr/local/include if test -d /usr/local/lib64; then SQLITE_LIBDIR=/usr/local/lib64 else SQLITE_LIBDIR=/usr/local/lib fi SQLITE_BINDIR=/usr/local/bin elif test -f /usr/include/sqlite3.h; then SQLITE_INCDIR=/usr/include if test -d /usr/lib64; then SQLITE_LIBDIR=/usr/lib64 else SQLITE_LIBDIR=/usr/lib fi SQLITE_BINDIR=/usr/bin elif test -f $prefix/include/sqlite3.h; then SQLITE_INCDIR=$prefix/include if test -d $prefix/lib64; then SQLITE_LIBDIR=$prefix/lib64 else SQLITE_LIBDIR=$prefix/lib fi SQLITE_BINDIR=$prefix/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find sqlite3.h in standard locations) fi else if test -f $withval/sqlite3.h; then SQLITE_INCDIR=$withval SQLITE_LIBDIR=$withval SQLITE_BINDIR=$withval elif test -f $withval/include/sqlite3.h; then SQLITE_INCDIR=$withval/include if test -d $withval/lib64; then SQLITE_LIBDIR=$withval/lib64 else SQLITE_LIBDIR=$withval/lib fi SQLITE_BINDIR=$withval/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval) fi fi if test x$SQLITE_LIBDIR != x; then SQLITE_INCLUDE=-I$SQLITE_INCDIR if test x$use_libtool != xno; then SQLITE_LIBS="-R $SQLITE_LIBDIR -L$SQLITE_LIBDIR -lsqlite3" else SQLITE_LIBS="-L$SQLITE_LIBDIR -lsqlite3" fi SQLITE_LIB=$SQLITE_LIBDIR/libsqlite3.a DB_LIBS="${DB_LIBS} ${SQLITE_LIBS}" AC_DEFINE(HAVE_SQLITE3, 1, [Set if you have an SQLite3 Database]) AC_MSG_RESULT(yes) if test -z "${db_backends}"; then db_backends="SQLite3" else db_backends="${db_backends} SQLite3" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="sqlite3" else DB_BACKENDS="${DB_BACKENDS} sqlite3" fi dnl ------------------------------------------- dnl Check if sqlite supports batch mode dnl ------------------------------------------- if test "x$support_batch_insert" = "xyes"; then dnl For sqlite checking saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$SQLITE_LIBDIR" AC_CHECK_LIB(sqlite3, sqlite3_threadsafe, AC_DEFINE(HAVE_SQLITE3_THREADSAFE, 1, [Define to 1 if you have the `sqlite3_threadsafe' function.])) if test "x$ac_cv_lib_sqlite3_sqlite3_threadsafe" = "xyes"; then if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="SQLite3" else batch_insert_db_backends="${batch_insert_db_backends} SQLite3" fi fi dnl Revert after sqlite checks LDFLAGS="${saved_LDFLAGS}" fi fi else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ]) AC_SUBST(SQLITE_LIBS) AC_SUBST(SQLITE_INCLUDE) AC_SUBST(SQLITE_BINDIR) ]) AC_DEFUN([BA_CHECK_POSTGRESQL_DB], [ AC_MSG_CHECKING(for PostgreSQL support) AC_ARG_WITH(postgresql, AC_HELP_STRING([--with-postgresql@<:@=DIR@:>@], [Include PostgreSQL support. DIR is the PostgreSQL base install directory, @<:@default=/usr/local/pgsql@:>@]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then PG_CONFIG=`which pg_config 2>/dev/null` if test -n "$PG_CONFIG"; then POSTGRESQL_INCDIR=`"$PG_CONFIG" --includedir` POSTGRESQL_LIBDIR=`"$PG_CONFIG" --libdir` POSTGRESQL_BINDIR=`"$PG_CONFIG" --bindir` fi # # See if the pg_config gave something that is worth anything. # if test x${POSTGRESQL_LIBDIR} = x -o \ ! \( -f ${POSTGRESQL_LIBDIR}/libpq.so -o \ -f ${POSTGRESQL_LIBDIR}/libpq.a \); then if test -f /usr/local/include/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/local/include if test -d /usr/local/lib64; then POSTGRESQL_LIBDIR=/usr/local/lib64 else POSTGRESQL_LIBDIR=/usr/local/lib fi POSTGRESQL_BINDIR=/usr/local/bin elif test -f /usr/include/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/include if test -d /usr/lib64; then POSTGRESQL_LIBDIR=/usr/lib64 else POSTGRESQL_LIBDIR=/usr/lib fi POSTGRESQL_BINDIR=/usr/bin elif test -f /usr/include/pgsql/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/include/pgsql if test -d /usr/lib64/pgsql; then POSTGRESQL_LIBDIR=/usr/lib64/pgsql else POSTGRESQL_LIBDIR=/usr/lib/pgsql fi POSTGRESQL_BINDIR=/usr/bin elif test -f /usr/include/postgresql/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/include/postgresql if test -d /usr/lib64/postgresql; then POSTGRESQL_LIBDIR=/usr/lib64/postgresql else POSTGRESQL_LIBDIR=/usr/lib/postgresql fi POSTGRESQL_BINDIR=/usr/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find libpq-fe.h in standard locations) fi fi else if test -f $withval/include/libpq-fe.h; then POSTGRESQL_INCDIR=$withval/include POSTGRESQL_LIBDIR=$withval/lib POSTGRESQL_BINDIR=$withval/bin elif test -f $withval/include/postgresql/libpq-fe.h; then POSTGRESQL_INCDIR=$withval/include/postgresql if test -d $withval/lib64; then POSTGRESQL_LIBDIR=$withval/lib64 else POSTGRESQL_LIBDIR=$withval/lib fi POSTGRESQL_BINDIR=$withval/bin else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid PostgreSQL directory $withval - unable to find libpq-fe.h under $withval) fi fi if test x$POSTGRESQL_LIBDIR != x; then AC_DEFINE(HAVE_POSTGRESQL, 1, [Set if you have an PostgreSQL Database]) AC_MSG_RESULT(yes) POSTGRESQL_INCLUDE=-I$POSTGRESQL_INCDIR if test x$use_libtool != xno; then POSTGRESQL_LIBS="-R $POSTGRESQL_LIBDIR -L$POSTGRESQL_LIBDIR -lpq" else POSTGRESQL_LIBS="-L$POSTGRESQL_LIBDIR -lpq" fi AC_CHECK_FUNC(crypt, , AC_CHECK_LIB(crypt, crypt, [POSTGRESQL_LIBS="$POSTGRESQL_LIBS -lcrypt"])) POSTGRESQL_LIB=$POSTGRESQL_LIBDIR/libpq.a DB_LIBS="${DB_LIBS} ${POSTGRESQL_LIBS}" if test -z "${db_backends}"; then db_backends="PostgreSQL" else db_backends="${db_backends} PostgreSQL" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="postgresql" else DB_BACKENDS="${DB_BACKENDS} postgresql" fi dnl ------------------------------------------- dnl Check if postgresql supports batch mode dnl ------------------------------------------- if test "x$support_batch_insert" = "xyes"; then dnl For postgresql checking saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$POSTGRESQL_LIBDIR" saved_LIBS="${LIBS}" if test "x$ac_cv_lib_crypt_crypt" = "xyes" ; then LIBS="${saved_LIBS} -lcrypt" fi AC_CHECK_LIB(pq, PQisthreadsafe, AC_DEFINE(HAVE_PQISTHREADSAFE, 1, [Set if have PQisthreadsafe])) AC_CHECK_LIB(pq, PQputCopyData, AC_DEFINE(HAVE_PQ_COPY, 1, [Set if have PQputCopyData])) if test "x$ac_cv_lib_pq_PQputCopyData" = "xyes"; then if test $support_batch_insert = yes ; then AC_DEFINE(HAVE_POSTGRESQL_BATCH_FILE_INSERT, 1, [Set if PostgreSQL DB batch insert code enabled]) if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="PostgreSQL" else batch_insert_db_backends="${batch_insert_db_backends} PostgreSQL" fi fi fi if test x$ac_cv_lib_pq_PQisthreadsafe != xyes -a x$support_batch_insert = xyes; then echo "WARNING: Your PostgreSQL client library is too old to detect " echo "if it was compiled with --enable-thread-safety, consider to " echo "upgrade it in order to avoid problems with Batch insert mode" fi dnl Revert after postgresql checks LDFLAGS="${saved_LDFLAGS}" LIBS="${saved_LIBS}" fi fi else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ]) AC_SUBST(POSTGRESQL_LIBS) AC_SUBST(POSTGRESQL_INCLUDE) AC_SUBST(POSTGRESQL_BINDIR) ]) AC_DEFUN([AM_CONDITIONAL], [AC_SUBST($1_TRUE) AC_SUBST($1_FALSE) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi]) bareos-Release-14.2.6/autoconf/bareos/largefiles.m4000066400000000000000000000071711263011562700221160ustar00rootroot00000000000000dnl dnl ========= Large File Support ============== dnl By default, many hosts won't let programs access large files; dnl one must use special compiler options to get large-file access to work. dnl For more details about this brain damage please see: dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html dnl Written by Paul Eggert . dnl dnl Modified by Kern Sibbald to turn on the large file dnl flags on all machines. Otherwise functions such as dnl fseek are not large file capable. dnl dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_FLAGS(FLAGSNAME) AC_DEFUN([AC_SYS_LARGEFILE_FLAGS], [AC_CACHE_CHECK([for $1 value to request large file support], ac_cv_sys_largefile_$1, [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || { ac_cv_sys_largefile_$1=no ifelse($1, CFLAGS, [case "$host_os" in # IRIX 6.2 and later require cc -n32. changequote(, )dnl irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) changequote([, ])dnl if test "$GCC" != yes; then ac_cv_sys_largefile_CFLAGS=-n32 fi ac_save_CC="$CC" CC="$CC $ac_cv_sys_largefile_CFLAGS" AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no) CC="$ac_save_CC" esac]) }])]) dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_SPACE_APPEND(VAR, VAL) AC_DEFUN([AC_SYS_LARGEFILE_SPACE_APPEND], [case $2 in no) ;; ?*) case "[$]$1" in '') $1=$2 ;; *) $1=[$]$1' '$2 ;; esac ;; esac]) dnl Internal subroutine of AC_SYS_LARGEFILE. dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT) AC_DEFUN([AC_SYS_LARGEFILE_MACRO_VALUE], [AC_CACHE_CHECK([for $1], $2, [$2=no changequote(, )dnl $4 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D$1) $2=1 ;; -D$1=*) $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done changequote([, ])dnl ]) if test "[$]$2" != no; then AC_DEFINE_UNQUOTED([$1], [$]$2, [$3]) fi]) AC_DEFUN([AC_BRS_LARGEFILE], [AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE(largefile, [ --disable-largefile omit support for large files]) if test "$enable_largefile" != no; then AC_CHECK_TOOL(GETCONF, getconf) AC_SYS_LARGEFILE_FLAGS(CFLAGS) AC_SYS_LARGEFILE_FLAGS(LDFLAGS) AC_SYS_LARGEFILE_FLAGS(LIBS) for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in no) ;; -D_FILE_OFFSET_BITS=*) ;; -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; -D_LARGE_FILES | -D_LARGE_FILES=*) ;; -D?* | -I?*) AC_SYS_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;; *) AC_SYS_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;; esac done AC_SYS_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS") AC_SYS_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS") AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, ac_cv_sys_file_offset_bits, [Number of bits in a file offset, on hosts where this is settable.], [ac_cv_sys_file_offset_bits=64]) AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, ac_cv_sys_largefile_source, [Define to make fseeko etc. visible, on some hosts.], [ac_cv_sys_largefile_source=1]) AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, ac_cv_sys_large_files, [Define for large files, on AIX-style hosts.], [ac_cv_sys_large_files=1]) fi ]) dnl ========================================================== bareos-Release-14.2.6/autoconf/bareos/os.m4000066400000000000000000000234361263011562700204240ustar00rootroot00000000000000dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7) AC_DEFUN([SIGNAL_CHECK], [AC_REQUIRE([AC_TYPE_SIGNAL]) AC_MSG_CHECKING(for type of signal functions) AC_CACHE_VAL(bash_cv_signal_vintage, [ AC_TRY_LINK([#include ],[ sigset_t ss; struct sigaction sa; sigemptyset(&ss); sigsuspend(&ss); sigaction(SIGINT, &sa, (struct sigaction *) 0); sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); ], bash_cv_signal_vintage="posix", [ AC_TRY_LINK([#include ], [ int mask = sigmask(SIGINT); sigsetmask(mask); sigblock(mask); sigpause(mask); ], bash_cv_signal_vintage="4.2bsd", [ AC_TRY_LINK([ #include RETSIGTYPE foo() { }], [ int mask = sigmask(SIGINT); sigset(SIGINT, foo); sigrelse(SIGINT); sighold(SIGINT); sigpause(SIGINT); ], bash_cv_signal_vintage="svr3", bash_cv_signal_vintage="v7" )] )] ) ]) AC_MSG_RESULT($bash_cv_signal_vintage) if test "$bash_cv_signal_vintage" = "posix"; then AC_DEFINE(HAVE_POSIX_SIGNALS, 1, [Define to 1 if you have POSIX signals]) elif test "$bash_cv_signal_vintage" = "4.2bsd"; then AC_DEFINE(HAVE_BSD_SIGNALS, 1, [Define to 1 if you have 4.2BSD signals]) elif test "$bash_cv_signal_vintage" = "svr3"; then AC_DEFINE(HAVE_USG_SIGHOLD, 1, [Define to 1 if you have SVR3 signals]) fi ]) AC_DEFUN([BA_CONDITIONAL], [AC_SUBST($1_TRUE) AC_SUBST($1_FALSE) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi]) AC_DEFUN([BA_CHECK_OPSYS], [ AC_CYGWIN if test $HAVE_UNAME=yes -a x`uname -s` = xSunOS then BA_CONDITIONAL(HAVE_SUN_OS, $TRUEPRG) AC_DEFINE(HAVE_SUN_OS, 1, [Define to 1 if you are running Solaris]) else BA_CONDITIONAL(HAVE_SUN_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xGNU then BA_CONDITIONAL(HAVE_HURD_OS, $TRUEPRG) AC_DEFINE(HAVE_HURD_OS, 1, [Define to 1 if you are running GNU Hurd]) else BA_CONDITIONAL(HAVE_HURD_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xOSF1 then BA_CONDITIONAL(HAVE_OSF1_OS, $TRUEPRG) AC_DEFINE(HAVE_OSF1_OS, 1, [Define to 1 if you are running Tru64]) else BA_CONDITIONAL(HAVE_OSF1_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xAIX then BA_CONDITIONAL(HAVE_AIX_OS, $TRUEPRG) AC_DEFINE(HAVE_AIX_OS, 1, [Define to 1 if you are running AIX]) else BA_CONDITIONAL(HAVE_AIX_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xHP-UX then BA_CONDITIONAL(HAVE_HPUX_OS, $TRUEPRG) AC_DEFINE(HAVE_HPUX_OS, 1, [Define to 1 if you are running HPUX]) else BA_CONDITIONAL(HAVE_HPUX_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xLinux then BA_CONDITIONAL(HAVE_LINUX_OS, $TRUEPRG) AC_DEFINE(HAVE_LINUX_OS, 1, [Define to 1 if you are running Linux]) else BA_CONDITIONAL(HAVE_LINUX_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xFreeBSD then BA_CONDITIONAL(HAVE_FREEBSD_OS, $TRUEPRG) AC_DEFINE(HAVE_FREEBSD_OS, 1, [Define to 1 if you are running FreeBSD]) else BA_CONDITIONAL(HAVE_FREEBSD_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xNetBSD then BA_CONDITIONAL(HAVE_NETBSD_OS, $TRUEPRG) AC_DEFINE(HAVE_NETBSD_OS, 1, [Define to 1 if you are running NetBSD]) else BA_CONDITIONAL(HAVE_NETBSD_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xOpenBSD then BA_CONDITIONAL(HAVE_OPENBSD_OS, $TRUEPRG) AC_DEFINE(HAVE_OPENBSD_OS, 1, [Define to 1 if you are running OpenBSD]) else BA_CONDITIONAL(HAVE_OPENBSD_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xBSD/OS then BA_CONDITIONAL(HAVE_BSDI_OS, $TRUEPRG) AC_DEFINE(HAVE_BSDI_OS, 1, [Define to 1 if you are running BSDI]) else BA_CONDITIONAL(HAVE_BSDI_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xSGI then BA_CONDITIONAL(HAVE_SGI_OS, $TRUEPRG) AC_DEFINE(HAVE_SGI_OS, 1, [Define to 1 if you are running SGI OS]) else BA_CONDITIONAL(HAVE_SGI_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xIRIX -o x`uname -s` = xIRIX64 then BA_CONDITIONAL(HAVE_IRIX_OS, $TRUEPRG) AC_DEFINE(HAVE_IRIX_OS, 1, [Define to 1 if you are running IRIX]) else BA_CONDITIONAL(HAVE_IRIX_OS, $FALSEPRG) fi if test $HAVE_UNAME=yes -a x`uname -s` = xDarwin then AM_CONDITIONAL(HAVE_DARWIN_OS, $TRUEPRG) AC_DEFINE(HAVE_DARWIN_OS, 1, [Define to 1 if you are running OSX]) else AM_CONDITIONAL(HAVE_DARWIN_OS, $FALSEPRG) fi ]) AC_DEFUN([BA_CHECK_OPSYS_DISTNAME], [ AC_MSG_CHECKING(for Operating System Distribution) if test "x$DISTNAME" != "x" then echo "distname set to $DISTNAME" else which lsb_release > /dev/null 2>&1 if test $? = 0 then LSB_DISTRIBUTOR=`lsb_release -i -s` case ${LSB_DISTRIBUTOR} in "SUSE LINUX") DISTNAME=suse ;; "openSUSE project") DISTNAME=suse ;; CentOS) DISTNAME=redhat ;; Fedora) DISTNAME=redhat ;; RedHatEnterprise*) DISTNAME=redhat ;; Oracle*) DISTNAME=redhat ;; MandrivaLinux) DISTNAME=mandrake ;; Arch|archlinux) DISTNAME=archlinux ;; LinuxMint) DISTNAME=debian ;; Debian) DISTNAME=debian ;; Ubuntu) DISTNAME=ubuntu ;; Univention) DISTNAME=univention ;; *) DISTNAME="" ;; esac # # If we got a valid DISTNAME get the DISTVER from lsb_release too. # if test "x$DISTNAME" != "x" then DISTVER=`lsb_release -d -s | sed -e 's/"//g'` fi fi # # If lsb_release gave us the wanted info we skip this fallback block. # if test "x$DISTNAME" = "x" -o "x$DISTVER" = "x" then if test $HAVE_UNAME=yes -a x`uname -s` = xOSF1 then DISTNAME=alpha DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xAIX then DISTNAME=aix DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xHP-UX then DISTNAME=hpux DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xSunOS then DISTNAME=solaris DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xGNU then DISTNAME=hurd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xFreeBSD then DISTNAME=freebsd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xNetBSD then DISTNAME=netbsd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xOpenBSD then DISTNAME=openbsd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xIRIX then DISTNAME=irix DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xBSD/OS then DISTNAME=bsdi DISTVER=`uname -a | awk '{print $3}'` elif test -f /etc/SuSE-release then DISTNAME=suse DISTVER=`cat /etc/SuSE-release | \ grep VERSION | \ cut -f3 -d' '` elif test -d /etc/SuSEconfig then DISTNAME=suse DISTVER=5.x elif test -f /etc/mandrake-release then DISTNAME=mandrake DISTVER=`cat /etc/mandrake-release | \ grep release | \ cut -f5 -d' '` elif test -f /etc/fedora-release then DISTNAME=redhat DISTVER="`cat /etc/fedora-release | cut -d' ' -f1,3`" elif test -f /etc/whitebox-release then DISTNAME=redhat DISTVER=`cat /etc/whitebox-release | grep release` elif test -f /etc/redhat-release then DISTNAME=redhat DISTVER=`cat /etc/redhat-release | grep release` elif test -f /etc/gentoo-release then DISTNAME=gentoo DISTVER=`awk '/version / { print $5 }' < /etc/gentoo-release` elif test -f /etc/debian_version then if `test -f /etc/apt/sources.list && grep -q ubuntu /etc/apt/sources.list`; then DISTNAME=ubuntu else DISTNAME=debian fi DISTVER=`cat /etc/debian_version` elif test -f /etc/slackware-version then DISTNAME=slackware DISTVER=`cat /etc/slackware-version` elif test x$host_vendor = xapple then DISTNAME=osx DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xDarwin then DISTNAME=darwin DISTVER=`uname -r` elif test -f /etc/engarde-version then DISTNAME=engarde DISTVER=`uname -r` elif test -f /etc/arch-release then DISTNAME=archlinux elif test "$CYGWIN" = yes then DISTNAME=cygwin AC_DEFINE(HAVE_CYGWIN, 1, [Define to 1 if you use CYGWIN]) else DISTNAME=unknown DISTVER=unknown fi fi fi AC_MSG_RESULT(done) ]) AC_DEFUN([BA_CHECK_OBS_DISTNAME], [ AC_MSG_CHECKING(for OBS OS Distribution) if test "x$OBS_DISTRIBUTION" != "x" then echo "obsdistname set to $OBS_DISTRIBUTION" else if test -e /.build.log; then OBS_PROJECT=`grep 'Building bareos for project' /.build.log | cut -d' ' -f10 | sed "s#'##g"` OBS_DISTRIBUTION=`grep 'Building bareos for project' /.build.log | cut -d' ' -f12 | sed "s#'##g"` OBS_ARCH=`grep 'Building bareos for project' /.build.log | cut -d' ' -f14 | sed "s#'##g"` OBS_SRCMD5=`grep 'Building bareos for project' /.build.log | cut -d' ' -f16 | sed "s#'##g"` AC_DEFINE(IS_BUILD_ON_OBS, 1, [Define to 1 if things are build using the Open Build Service (OBS)]) fi fi AC_MSG_RESULT(done) ]) bareos-Release-14.2.6/autoconf/config.guess000077500000000000000000001301451263011562700206020ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 Free Software Foundation, Inc. timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}" in i?86) test -z "$VENDOR" && VENDOR=pc ;; *) test -z "$VENDOR" && VENDOR=unknown ;; esac test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-${VENDOR}-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-${VENDOR}-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-${VENDOR}-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-${VENDOR}-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-${VENDOR}-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-${VENDOR}-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-${VENDOR}-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-${VENDOR}-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-${VENDOR}-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-${VENDOR}-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-${VENDOR}-osf1mk else echo ${UNAME_MACHINE}-${VENDOR}-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-${VENDOR}-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-${VENDOR}-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-${VENDOR}-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-${VENDOR}-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-${VENDOR}-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-${VENDOR}-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-${VENDOR}-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-${VENDOR}-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-${VENDOR}-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-${VENDOR}-linux-gnueabi else echo ${UNAME_MACHINE}-${VENDOR}-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; padre:Linux:*:*) echo sparc-${VENDOR}-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-${VENDOR}-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-${VENDOR}-linux-gnu ;; PA8*) echo hppa2.0-${VENDOR}-linux-gnu ;; *) echo hppa-${VENDOR}-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-${VENDOR}-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-${VENDOR}-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-${VENDOR}-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-${VENDOR}-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-${VENODR}-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-${VENDOR}-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-${VENODR}-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-${VENDOR}-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-${VENDOR}-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-${VENDOR}-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-${VENDOR}-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-${VENDOR}-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-${VENDOR}-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-${VENDOR}-tops10 exit ;; *:TENEX:*:*) echo pdp10-${VENDOR}-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-${VENDOR}-tops20 exit ;; *:ITS:*:*) echo pdp10-${VENDOR}-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-${VENDOR}-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-${VENDOR}-esx exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: bareos-Release-14.2.6/autoconf/config.h.in000066400000000000000000001013501263011562700203010ustar00rootroot00000000000000/* autoconf/config.h.in. Generated from autoconf/configure.in by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define to 1 if the `closedir' function returns void instead of `int'. */ #undef CLOSEDIR_VOID /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* Define to 1 if you have AIX3 statfs to get filesystem type */ #undef FSTYPE_AIX_STATFS /* Define to 1 if you have Ultrix getmnt to get filesystem type */ #undef FSTYPE_GETMNT /* Define to 1 if you have 4.3BSD getmntent to get filesystem type */ #undef FSTYPE_MNTENT /* Define to 1 if you have 4.4BSD and OSF1 statfs to get filesystem type */ #undef FSTYPE_STATFS /* Define to 1 if you have SVR4 statvfs to get filesystem type */ #undef FSTYPE_STATVFS /* Define to 1 if you have SVR3.2 statfs to get filesystem type */ #undef FSTYPE_USG_STATFS /* Define to 1 if you want Normal acl support */ #undef HAVE_ACL /* Defines if your system have the ACL_TYPE_DEFAULT_DIR acl type */ #undef HAVE_ACL_TYPE_DEFAULT_DIR /* Defines if your system have the ACL_TYPE_EXTENDED acl type */ #undef HAVE_ACL_TYPE_EXTENDED /* Defines if your system have the ACL_TYPE_NFS4 acl type */ #undef HAVE_ACL_TYPE_NFS4 /* Set if addrtosymstr exists */ #undef HAVE_ADDRTOSYMSTR /* Define to 1 if you have the `add_proplist_entry' function. */ #undef HAVE_ADD_PROPLIST_ENTRY /* Define to 1 if your system has AFS support */ #undef HAVE_AFS /* Andrew FileSystem ACL support */ #undef HAVE_AFS_ACL /* Define to 1 if you have the header file. */ #undef HAVE_AFS_AFSINT_H /* Define to 1 if you have the header file. */ #undef HAVE_AFS_VENUS_H /* Define to 1 if you are running AIX */ #undef HAVE_AIX_OS /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_ARGZ_H /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_NAMESER_H /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_ASSERT_H /* Define to 1 if you have the header file. */ #undef HAVE_ATTR_H /* Define to 1 if you have the `backtrace' function. */ #undef HAVE_BACKTRACE /* Define to 1 if you have the `backtrace_symbols' function. */ #undef HAVE_BACKTRACE_SYMBOLS /* Define to 1 if bat Qt4 GUI support should be enabled */ #undef HAVE_BAT /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY /* Big Endian */ #undef HAVE_BIG_ENDIAN /* Define to 1 if you are running BSDI */ #undef HAVE_BSDI_OS /* Define to 1 if you have 4.2BSD signals */ #undef HAVE_BSD_SIGNALS /* Define to 1 if you have the header file. */ #undef HAVE_CAMLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_CAM_SCSI_SCSI_MESSAGE_H /* Define to 1 if you have cephfs lib */ #undef HAVE_CEPHFS /* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework. */ #undef HAVE_CFLOCALECOPYCURRENT /* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework. */ #undef HAVE_CFPREFERENCESCOPYAPPVALUE /* Define to 1 if you have the `chflags' function. */ #undef HAVE_CHFLAGS /* Define to 1 if you have the `closefrom' function. */ #undef HAVE_CLOSEFROM /* Define to 1 if you have compressBound */ #undef HAVE_COMPRESS_BOUND /* Define to 1 if Bareos conio support enabled */ #undef HAVE_CONIO /* Define to 1 if cplus_demangle exists in libdemangle */ #undef HAVE_CPLUS_DEMANGLE /* Define to 1 if encryption support should be enabled */ #undef HAVE_CRYPTO /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H /* Define to 1 if you have the header file. */ #undef HAVE_CXXABI_H /* Define to 1 if you use CYGWIN */ #undef HAVE_CYGWIN /* Define to 1 if you are running OSX */ #undef HAVE_DARWIN_OS /* Define if the GNU dcgettext() function is already present or preinstalled. */ #undef HAVE_DCGETTEXT /* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if you don't. */ #undef HAVE_DECL_CYGWIN_CONV_PATH /* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you don't. */ #undef HAVE_DECL_FEOF_UNLOCKED /* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if you don't. */ #undef HAVE_DECL_FGETS_UNLOCKED /* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you don't. */ #undef HAVE_DECL_GETC_UNLOCKED /* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. */ #undef HAVE_DECL_TZNAME /* Define to 1 if you have the declaration of `_snprintf', and to 0 if you don't. */ #undef HAVE_DECL__SNPRINTF /* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you don't. */ #undef HAVE_DECL__SNWPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_DEMANGLE_H /* Define to 1 if you have the header file. */ #undef HAVE_DEV_SCSIPI_SCSIPI_ALL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define if you have the GNU dld library. */ #undef HAVE_DLD /* Define to 1 if you have the `dlerror' function. */ #undef HAVE_DLERROR /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_DL_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define if you have the _dyld_func_lookup function. */ #undef HAVE_DYLD /* Define to 1 if dynamic loading of catalog backends is enabled */ #undef HAVE_DYNAMIC_CATS_BACKENDS /* Define to 1 if dynamic loading of storage backends is enabled */ #undef HAVE_DYNAMIC_SD_BACKENDS /* Set if you have an Embedded MySQL Database */ #undef HAVE_EMBEDDED_MYSQL /* Define to 1 if OpenSSL library has ENGINE_load_pk11 available */ #undef HAVE_ENGINE_LOAD_PK11 /* Define to 1 if you have the header file. */ #undef HAVE_EXECINFO_H /* Define to 1 if you have the `extattr_get_file' function. */ #undef HAVE_EXTATTR_GET_FILE /* Define to 1 if you have the `extattr_get_link' function. */ #undef HAVE_EXTATTR_GET_LINK /* Define to 1 if you have the `extattr_list_file' function. */ #undef HAVE_EXTATTR_LIST_FILE /* Define to 1 if you have the `extattr_list_link' function. */ #undef HAVE_EXTATTR_LIST_LINK /* Define to 1 if you have the `extattr_namespace_to_string' function. */ #undef HAVE_EXTATTR_NAMESPACE_TO_STRING /* Define to 1 if you have the `extattr_set_file' function. */ #undef HAVE_EXTATTR_SET_FILE /* Define to 1 if you have the `extattr_set_link' function. */ #undef HAVE_EXTATTR_SET_LINK /* Define to 1 if you have the `extattr_string_to_namespace' function. */ #undef HAVE_EXTATTR_STRING_TO_NAMESPACE /* Define to 1 if you want Extended acl support */ #undef HAVE_EXTENDED_ACL /* Define to 1 if you have fastlz lib */ #undef HAVE_FASTLZ /* Define to 1 if you have the header file. */ #undef HAVE_FASTLZLIB_H /* Define to 1 if you have the `fchdir' function. */ #undef HAVE_FCHDIR /* Define to 1 if you have the `fchmod' function. */ #undef HAVE_FCHMOD /* Define to 1 if you have the `fchown' function. */ #undef HAVE_FCHOWN /* Define to 1 if you have the `fchownat' function. */ #undef HAVE_FCHOWNAT /* Define to 1 if you have the fcntl F_CLOSEM flag */ #undef HAVE_FCNTL_F_CLOSEM /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if you are running FreeBSD */ #undef HAVE_FREEBSD_OS /* Define to 1 if you have the `fseeko' function. */ #undef HAVE_FSEEKO /* Define to 1 if you have the `fstatat' function. */ #undef HAVE_FSTATAT /* Define to 1 if you have the `futimens' function. */ #undef HAVE_FUTIMENS /* Define to 1 if you have the `futimes' function. */ #undef HAVE_FUTIMES /* Define to 1 if you have the `futimesat' function. */ #undef HAVE_FUTIMESAT /* Define to 1 if you have the `fwprintf' function. */ #undef HAVE_FWPRINTF /* Define to 1 if you have the `gai_strerror' function. */ #undef HAVE_GAI_STRERROR /* Define to 1 if you use gcc. */ #undef HAVE_GCC /* Define to 1 if you have the `getaddrinfo' function. */ #undef HAVE_GETADDRINFO /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD /* Define to 1 if you have the `getea' function. */ #undef HAVE_GETEA /* Define to 1 if you have the `getegid' function. */ #undef HAVE_GETEGID /* Define to 1 if you have the `geteuid' function. */ #undef HAVE_GETEUID /* Define to 1 if you have the `getgid' function. */ #undef HAVE_GETGID /* Define to 1 if you have the `gethostbyname2' function. */ #undef HAVE_GETHOSTBYNAME2 /* Define to 1 if you have the `gethostbyname_r' function. */ #undef HAVE_GETHOSTBYNAME_R /* Define to 1 if you have the `gethostid' function. */ #undef HAVE_GETHOSTID /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `getmntent' function. */ #undef HAVE_GETMNTENT /* Define to 1 if you have the `getmntinfo' function. */ #undef HAVE_GETMNTINFO /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the `getpid' function. */ #undef HAVE_GETPID /* Define to 1 if you have the `getproplist' function. */ #undef HAVE_GETPROPLIST /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `getuid' function. */ #undef HAVE_GETUID /* Define to 1 if you have the `getxattr' function. */ #undef HAVE_GETXATTR /* Define to 1 if you have the `get_proplist_entry' function. */ #undef HAVE_GET_PROPLIST_ENTRY /* Define to 1 if you have gfapi lib */ #undef HAVE_GFAPI /* Define to 1 if GNUTLS library is available */ #undef HAVE_GNUTLS /* Define to 1 if you have the `gnutls_cipher_init' function. */ #undef HAVE_GNUTLS_CIPHER_INIT /* Define to 1 if you have the header file. */ #undef HAVE_GNUTLS_GNUTLS_H /* Define to 1 if you have the `gnutls_transport_set_int' function. */ #undef HAVE_GNUTLS_TRANSPORT_SET_INT /* Define to 1 if you have the header file. */ #undef HAVE_GRP_H /* Define to 1 if you are running HPUX */ #undef HAVE_HPUX_OS /* Define to 1 if you are running GNU Hurd */ #undef HAVE_HURD_OS /* Define to 1 if you have the `iconv()' function. */ #undef HAVE_ICONV /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if you have the `inet_pton' function. */ #undef HAVE_INET_PTON /* Define to 1 if you have int64_t */ #undef HAVE_INT64_T /* Define to 1 if you have intmax_t */ #undef HAVE_INTMAX_T /* Define to 1 if the system has the type `intptr_t'. */ #undef HAVE_INTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if exists, doesn't clash with , and declares uintmax_t. */ #undef HAVE_INTTYPES_H_WITH_UINTMAX /* Define to 1 if you have intxx_t */ #undef HAVE_INTXX_T /* Define to 1 if ioctl request is unsigned long int */ #undef HAVE_IOCTL_ULINT_REQUEST /* Define to 1 if IPv6 support should be enabled */ #undef HAVE_IPV6 /* Define to 1 if you are running IRIX */ #undef HAVE_IRIX_OS /* Define if you have and nl_langinfo(CODESET). */ #undef HAVE_LANGINFO_CODESET /* Define to 1 if you have the `lchmod' function. */ #undef HAVE_LCHMOD /* Define to 1 if you have the `lchown' function. */ #undef HAVE_LCHOWN /* Define if your file defines LC_MESSAGES. */ #undef HAVE_LC_MESSAGES /* Define to 1 if you have the `lgetea' function. */ #undef HAVE_LGETEA /* Define to 1 if you have the `lgetxattr' function. */ #undef HAVE_LGETXATTR /* Define to 1 if you have libcap */ #undef HAVE_LIBCAP /* Define to 1 if you have the header file. */ #undef HAVE_LIBC_H /* Define if you have the libdl library or equivalent. */ #undef HAVE_LIBDL /* Define if libdlloader will be built on this platform */ #undef HAVE_LIBDLLOADER /* Define to 1 if you have the `sun' library (-lsun). */ #undef HAVE_LIBSUN /* Define to 1 if you have the `util' library (-lutil). */ #undef HAVE_LIBUTIL /* Define to 1 if you have the header file. */ #undef HAVE_LIBUTIL_H /* Set to enable libwrap support */ #undef HAVE_LIBWRAP /* Define to 1 if you have zlib */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you are running Linux */ #undef HAVE_LINUX_OS /* Define to 1 if you have the `listea' function. */ #undef HAVE_LISTEA /* Define to 1 if you have the `listxattr' function. */ #undef HAVE_LISTXATTR /* Little Endian */ #undef HAVE_LITTLE_ENDIAN /* Define to 1 if you have the `llistea' function. */ #undef HAVE_LLISTEA /* Define to 1 if you have the `llistxattr' function. */ #undef HAVE_LLISTXATTR /* Define to 1 if LMDB support should be enabled */ #undef HAVE_LMDB /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R /* Define if you have the 'long double' type. */ #undef HAVE_LONG_DOUBLE /* Define if you have the 'long long' type. */ #undef HAVE_LONG_LONG /* Low level SCSI Interface support */ #undef HAVE_LOWLEVEL_SCSI_INTERFACE /* Define to 1 if you have the `lsetea' function. */ #undef HAVE_LSETEA /* Define to 1 if you have the `lsetxattr' function. */ #undef HAVE_LSETXATTR /* Define to 1 if you have the `lstat' function. */ #undef HAVE_LSTAT /* Define to 1 if you have the `lutimes' function. */ #undef HAVE_LUTIMES /* Define to 1 if you have lzo lib */ #undef HAVE_LZO /* Define to 1 if you have the header file. */ #undef HAVE_LZO_LZO1X_H /* Define to 1 if you have the header file. */ #undef HAVE_LZO_LZOCONF_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `malloc_trim' function. */ #undef HAVE_MALLOC_TRIM /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mempcpy' function. */ #undef HAVE_MEMPCPY /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define to 1 if you have the header file. */ #undef HAVE_MTIO_H /* Define to 1 if you have the `munmap' function. */ #undef HAVE_MUNMAP /* Set if you have an MySQL Database */ #undef HAVE_MYSQL /* Set if have mysql_thread_safe */ #undef HAVE_MYSQL_THREAD_SAFE /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if NDMP support should be enabled */ #undef HAVE_NDMP /* Define to 1 if you are running NetBSD */ #undef HAVE_NETBSD_OS /* Define to 1 if you have the `nl_langinfo' function. */ #undef HAVE_NL_LANGINFO /* Define to 1 if you have the header file. */ #undef HAVE_NL_TYPES_H /* Define to 1 to when walkcontext does not work */ #undef HAVE_NON_WORKING_WALKCONTEXT /* Define to 1 if you have the `nvlist_next_nvpair' function. */ #undef HAVE_NVLIST_NEXT_NVPAIR /* Define to 1 if you have libdroplet lib */ #undef HAVE_OBJECTSTORE /* Define to 1 to use the old sockopt option */ #undef HAVE_OLD_SOCKOPT /* Define to 1 if you have the `openat' function. */ #undef HAVE_OPENAT /* Define to 1 if you are running OpenBSD */ #undef HAVE_OPENBSD_OS /* Define to 1 if OpenSSL library is available */ #undef HAVE_OPENSSL /* Define to 1 if the OpenSSL library is export-contrained to 128bit ciphers */ #undef HAVE_OPENSSL_EXPORT_LIBRARY /* Define to 1 if you are running Tru64 */ #undef HAVE_OSF1_OS /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the header file. */ #undef HAVE_POLL_H /* Define to 1 if you have the `posix_fadvise' function. */ #undef HAVE_POSIX_FADVISE /* Define if your printf() function supports format strings with positions. */ #undef HAVE_POSIX_PRINTF /* Define to 1 if you have POSIX signals */ #undef HAVE_POSIX_SIGNALS /* Set if you have an PostgreSQL Database */ #undef HAVE_POSTGRESQL /* Set if PostgreSQL DB batch insert code enabled */ #undef HAVE_POSTGRESQL_BATCH_FILE_INSERT /* Set if have PQisthreadsafe */ #undef HAVE_PQISTHREADSAFE /* Set if have PQputCopyData */ #undef HAVE_PQ_COPY /* Define to 1 if you have the `prctl' function. */ #undef HAVE_PRCTL /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if you have the header file. */ #undef HAVE_PWD_H /* Define to 1 if python support should be enabled */ #undef HAVE_PYTHON /* Define to 1 if you have rados lib */ #undef HAVE_RADOS /* Define to 1 if you have the `readdir_r' function. */ #undef HAVE_READDIR_R /* Define to 1 if readline support should be enabled */ #undef HAVE_READLINE /* Define to 1 if you have the header file. */ #undef HAVE_REGEX_H /* Define to 1 if sa_len field exists in struct sockaddr */ #undef HAVE_SA_LEN /* Define to 1 if you have the header file. */ #undef HAVE_SCSI_SCSI_H /* Define to 1 if you have the header file. */ #undef HAVE_SCSI_SG_H /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setea' function. */ #undef HAVE_SETEA /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the `setpgid' function. */ #undef HAVE_SETPGID /* Define to 1 if you have the `setpgrp' function. */ #undef HAVE_SETPGRP /* Define to 1 if you have the `setproplist' function. */ #undef HAVE_SETPROPLIST /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `setxattr' function. */ #undef HAVE_SETXATTR /* Define to 1 if you are running SGI OS */ #undef HAVE_SGI_OS /* Define to 1 if the SHA-2 family of digest algorithms is available */ #undef HAVE_SHA2 /* Define if you have the shl_load function. */ #undef HAVE_SHL_LOAD /* Define to 1 if you have the `signal' function. */ #undef HAVE_SIGNAL /* Define to 1 if you have the `sizeof_proplist_entry' function. */ #undef HAVE_SIZEOF_PROPLIST_ENTRY /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if socklen_t exists */ #undef HAVE_SOCKLEN_T /* Set if you have an SQLite3 Database */ #undef HAVE_SQLITE3 /* Define to 1 if you have the `sqlite3_threadsafe' function. */ #undef HAVE_SQLITE3_THREADSAFE /* Define to 1 if sql pooling is enabled */ #undef HAVE_SQL_POOLING /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define if exists, doesn't clash with , and declares uintmax_t. */ #undef HAVE_STDINT_H_WITH_UINTMAX /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `stpcpy' function. */ #undef HAVE_STPCPY /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncmp' function. */ #undef HAVE_STRNCMP /* Define to 1 if you have the `strncpy' function. */ #undef HAVE_STRNCPY /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if `st_blksize' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLKSIZE /* Define to 1 if `st_blocks' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLOCKS /* Define to 1 if `st_rdev' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_RDEV /* Define to 1 if `tm_zone' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_ZONE /* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ #undef HAVE_ST_BLKSIZE /* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ #undef HAVE_ST_BLOCKS /* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use `HAVE_STRUCT_STAT_ST_RDEV' instead. */ #undef HAVE_ST_RDEV /* Define to 1 if you are running Solaris */ #undef HAVE_SUN_OS /* Define to 1 if systemd support should be enabled */ #undef HAVE_SYSTEMD /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ACL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ATTR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BITYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BYTEORDER_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CAPABILITY_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EA_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EXTATTR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MTIO_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_NVPAIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PROPLIST_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SCSI_IMPL_USCSI_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATVFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TAPE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_XATTR_H /* Define to 1 if you have the `tcgetattr' function. */ #undef HAVE_TCGETATTR /* Define to 1 if you have the header file. */ #undef HAVE_TERMCAP_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the header file. */ #undef HAVE_TERM_H /* Define to 1 if TLS support should be enabled */ #undef HAVE_TLS /* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use `HAVE_STRUCT_TM_TM_ZONE' instead. */ #undef HAVE_TM_ZONE /* Define to 1 if tray-monitor Qt4 GUI support should be enabled */ #undef HAVE_TRAYMONITOR /* Define to 1 if you have the `tsearch' function. */ #undef HAVE_TSEARCH /* Define to 1 if compiler has typeof */ #undef HAVE_TYPEOF /* Define to 1 if you don't have `tm_zone' but do have the external array `tzname'. */ #undef HAVE_TZNAME /* Define to 1 if you have the header file. */ #undef HAVE_UCONTEXT_H /* Define if you have the 'uintmax_t' type in or . */ #undef HAVE_UINTMAX_T /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have uintxx_t */ #undef HAVE_UINTXX_T /* Define to 1 if you have the header file. */ #undef HAVE_UMEM_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unlinkat' function. */ #undef HAVE_UNLINKAT /* Define if you have the 'unsigned long long' type. */ #undef HAVE_UNSIGNED_LONG_LONG /* Define to 1 if you have the header file. */ #undef HAVE_USCSI_ALL_H /* Define to 1 if you have SVR3 signals */ #undef HAVE_USG_SIGHOLD /* Define to 1 if you have the `utimes' function. */ #undef HAVE_UTIMES /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H /* Define to 1 if you have u_int */ #undef HAVE_U_INT /* Define to 1 if you have u_int64_t */ #undef HAVE_U_INT64_T /* Define to 1 if you have u_intmax_t */ #undef HAVE_U_INTMAX_T /* Define to 1 if you have u_intxx_t */ #undef HAVE_U_INTXX_T /* Define to 1 if you have the header file. */ #undef HAVE_VARARGS_H /* Set if va_copy exists */ #undef HAVE_VA_COPY /* Define to 1 if you have the `vfprintf' function. */ #undef HAVE_VFPRINTF /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define if you have the 'wchar_t' type. */ #undef HAVE_WCHAR_T /* Define to 1 if you have the `wcslen' function. */ #undef HAVE_WCSLEN /* Define if you have the 'wint_t' type. */ #undef HAVE_WINT_T /* Extended Attributes support */ #undef HAVE_XATTR /* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_H /* Define to 1 if you have the `__argz_count' function. */ #undef HAVE___ARGZ_COUNT /* Define to 1 if you have the `__argz_next' function. */ #undef HAVE___ARGZ_NEXT /* Define to 1 if you have the `__argz_stringify' function. */ #undef HAVE___ARGZ_STRINGIFY /* Define to 1 if you have the `__fsetlocking' function. */ #undef HAVE___FSETLOCKING /* Define as const if the declaration of iconv() needs const. */ #undef ICONV_CONST /* Define if integer division by zero raises signal SIGFPE. */ #undef INTDIV0_RAISES_SIGFPE /* Where are shared libs stored */ #undef LIBDIR /* Where are locale files stored */ #undef LOCALEDIR /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if `major', `minor', and `makedev' are declared in . */ #undef MAJOR_IN_MKDEV /* Define to 1 if `major', `minor', and `makedev' are declared in . */ #undef MAJOR_IN_SYSMACROS /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define if exists and defines unusable PRI* macros. */ #undef PRI_MACROS_BROKEN /* Define if you need function prototypes */ #undef PROTOTYPES /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define to 1 if the `setpgrp' function takes no argument. */ #undef SETPGRP_VOID /* The size of `char', as computed by sizeof. */ #undef SIZEOF_CHAR /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `int *', as computed by sizeof. */ #undef SIZEOF_INT_P /* The size of `long int', as computed by sizeof. */ #undef SIZEOF_LONG_INT /* The size of `long long int', as computed by sizeof. */ #undef SIZEOF_LONG_LONG_INT /* The size of `short int', as computed by sizeof. */ #undef SIZEOF_SHORT_INT /* Define as the maximum value of type 'size_t', if the system doesn't define it. */ #undef SIZE_MAX /* Define to 1 if you want Smartalloc enabled */ #undef SMARTALLOC /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if the `S_IS*' macros in do not work properly. */ #undef STAT_MACROS_BROKEN /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Where are config files stored */ #undef SYSCONFDIR /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Define to 1 if DB batch insert code enabled */ #undef USE_BATCH_FILE_INSERT /* Define to 1 to use the thr_setconcurrency function */ #undef USE_THR_SETCONCURRENCY /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to 1 if the X Window System is missing or not being used. */ #undef X_DISPLAY_MISSING /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Needed on HP-UX/g++ systems to support long long ints (int64) */ #undef _INCLUDE_LONGLONG /* Define to make fseeko etc. visible, on some hosts. */ #undef _LARGEFILE_SOURCE /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Directory for backend files */ #undef _PATH_BAREOS_BACKENDDIR /* Directory for PID files */ #undef _PATH_BAREOS_PIDDIR /* Directory for daemon files */ #undef _PATH_BAREOS_WORKINGDIR /* Define to 1 if you want Lock Manager enabled */ #undef _USE_LOCKMGR /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `long' if does not define. */ #undef daddr_t /* Define to `unsigned long' if does not define. */ #undef dev_t /* Define to `int' if doesn't define. */ #undef gid_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `unsigned long' if does not define. */ #undef ino_t /* Define to the type of a signed integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef intptr_t /* Set to correct scanf value for long long int */ #undef lld /* Set to correct scanf value for long long unsigned int */ #undef llu /* Define to `int' if does not define. */ #undef major_t /* Define to `int' if does not define. */ #undef minor_t /* Define to `int' if does not define. */ #undef mode_t /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define as the type of the result of subtracting two pointers, if the system doesn't define it. */ #undef ptrdiff_t /* Define to empty if the C compiler doesn't support this keyword. */ #undef signed /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to `int' if doesn't define. */ #undef uid_t /* Define to unsigned long or unsigned long long if and don't define. */ #undef uintmax_t /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t bareos-Release-14.2.6/autoconf/config.rpath000077500000000000000000000440121263011562700205670ustar00rootroot00000000000000#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2010 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's _LT_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; darwin*) case $cc_basename in xlc*) wl='-Wl,' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; newsos6) ;; linux* | k*bsd*-gnu) case $cc_basename in ecc*) wl='-Wl,' ;; icc* | ifort*) wl='-Wl,' ;; lf95*) wl='-Wl,' ;; pgcc | pgf77 | pgf90) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; rdos*) ;; solaris*) wl='-Wl,' ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3*) wl='-Wl,' ;; sysv4*MP*) ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) wl='-Wl,' ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's _LT_LINKER_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we cannot use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; interix[3-9]*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; bsdi[45]*) ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if test "$GCC" = yes ; then : else case $cc_basename in xlc*) ;; *) ld_shlibs=no ;; esac fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd1*) ld_shlibs=no ;; freebsd2.2*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; freebsd2*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the # linker has special search rules. library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) library_names_spec='$libname.a' ;; aix[4-9]*) library_names_spec='$libname$shrext' ;; amigaos*) library_names_spec='$libname.a' ;; beos*) library_names_spec='$libname$shrext' ;; bsdi[45]*) library_names_spec='$libname$shrext' ;; cygwin* | mingw* | pw32* | cegcc*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib library_names_spec='$libname$shrext' ;; dgux*) library_names_spec='$libname$shrext' ;; freebsd1*) ;; freebsd* | dragonfly*) case "$host_os" in freebsd[123]*) library_names_spec='$libname$shrext$versuffix' ;; *) library_names_spec='$libname$shrext' ;; esac ;; gnu*) library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac library_names_spec='$libname$shrext' ;; interix[3-9]*) library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux* | k*bsd*-gnu) library_names_spec='$libname$shrext' ;; knetbsd*-gnu) library_names_spec='$libname$shrext' ;; netbsd*) library_names_spec='$libname$shrext' ;; newsos6) library_names_spec='$libname$shrext' ;; nto-qnx*) library_names_spec='$libname$shrext' ;; openbsd*) library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) library_names_spec='$libname$shrext' ;; rdos*) ;; solaris*) library_names_spec='$libname$shrext' ;; sunos4*) library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) library_names_spec='$libname$shrext' ;; sysv4*MP*) library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) library_names_spec='$libname$shrext' ;; uts4*) library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: bareos-Release-14.2.6/autoconf/configure.in000066400000000000000000003773651263011562700206140ustar00rootroot00000000000000 dnl Process this file with autoconf to produce a configure script. dnl dnl require a recent autoconf AC_PREREQ(2.61) AC_INIT([bareos], m4_esyscmd([sed -n -e 's/^.*VERSION.*"\(.*\)"$/\1/p' ../src/include/version.h src/include/version.h 2> /dev/null | tr -d '\n'])) AC_CONFIG_SRCDIR(src/include/version.h) BUILD_DIR=`pwd` cd .. TOP_DIR=`pwd` cd ${BUILD_DIR} AC_SUBST(BUILD_DIR) AC_SUBST(TOP_DIR) AC_CONFIG_AUX_DIR(${BUILD_DIR}/autoconf) AC_CONFIG_HEADERS(src/include/config.h:autoconf/config.h.in) dnl search for true and false programs. AC_PATH_PROGS(TRUEPRG, true, :) AC_PATH_PROGS(FALSEPRG, false, :) dnl bareos version post_host= if test "x$BAREOS" != x; then post_host=`echo -${BAREOS} | tr 'A-Z ' 'a-z-'` fi BAREOS=${BAREOS:-Bareos} VERSION=`sed -n -e 's/^.*VERSION.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` DATE=`sed -n -e 's/^.*[ \t]*BDATE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LSMDATE=`sed -n -e 's/^.*LSMDATE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` BDB_VERSION=`sed -n -e 's/^.*BDB_VERSION \(.*\)$/\1/p' ${srcdir}/src/cats/cats.h` AC_SUBST(VERSION)dnl AC_SUBST(DATE)dnl AC_SUBST(LSMDATE)dnl AC_SUBST(BAREOS)dnl AC_SUBST(post_host)dnl AC_SUBST(BDB_VERSION)dnl dnl src/lib dnl can be overwritten by specific values from version.h LIBBAREOS_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOS_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSCFG_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSCFG_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOS_LT_RELEASE=${LIBBAREOS_LT_RELEASE:-$VERSION} LIBBAREOSCFG_LT_RELEASE=${LIBBAREOSCFG_LT_RELEASE:-$VERSION} AC_SUBST(LIBBAREOS_LT_RELEASE)dnl AC_SUBST(LIBBAREOSCFG_LT_RELEASE)dnl dnl src/cats dnl can be overwritten by specific values from version.h LIBBAREOSSQL_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSSQL_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSCATS_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSCATS_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSSQL_LT_RELEASE=${LIBBAREOSSQL_LT_RELEASE:-$VERSION} LIBBAREOSCATS_LT_RELEASE=${LIBBAREOSCATS_LT_RELEASE:-$VERSION} AC_SUBST(LIBBAREOSSQL_LT_RELEASE)dnl AC_SUBST(LIBBAREOSCATS_LT_RELEASE)dnl dnl src/findlib dnl can be overwritten by specific values from version.h LIBBAREOSFIND_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSFIND_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSFIND_LT_RELEASE=${LIBBAREOSFIND_LT_RELEASE:-$VERSION} AC_SUBST(LIBBAREOSFIND_LT_RELEASE)dnl dnl src/ndmp dnl can be overwritten by specific values from version.h LIBBAREOSNDMP_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSNDMP_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSNDMP_LT_RELEASE=${LIBBAREOSNDMP_LT_RELEASE:-$VERSION} AC_SUBST(LIBBAREOSNDMP_LT_RELEASE)dnl dnl src/lmdb dnl can be overwritten by specific values from version.h LIBBAREOSLMDB_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSLMDB_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSLMDB_LT_RELEASE=${LIBBAREOSLMDB_LT_RELEASE:-$VERSION} AC_SUBST(LIBBAREOSLMDB_LT_RELEASE)dnl dnl src/stored/backends dnl can be overwritten by specific values from version.h LIBBAREOSSD_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSCATS_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSSD_LT_RELEASE=${LIBBAREOSLMDB_LT_RELEASE:-$VERSION} AC_SUBST(LIBBAREOSSD_LT_RELEASE)dnl echo "configuring for ${BAREOS} $VERSION ($DATE)" dnl ------------------------------------------------------- dnl Check for compiler. dnl ------------------------------------------------------ AC_PROG_CC AC_PROG_CXX AC_PROG_CC_C_O dnl Determine if C compiler support -c -o. AC_PROG_GCC_TRADITIONAL dnl Determine if ioctl() need -traditional. BASECC=`basename $CC` have_gcc=no if test "x$BASECC" = xgcc; then AC_DEFINE(HAVE_GCC, 1, [Define to 1 if you use gcc.]) have_gcc=yes fi AC_PATH_PROG(CXX, $CXX, $CXX) if test ! -e $CXX; then AC_MSG_ERROR(Unable to find C++ compiler) fi dnl ------------------------------------------------------- dnl Check for programs. dnl ------------------------------------------------------ AC_PROG_INSTALL AC_PATH_PROG(MV, mv, []) dnl Alert !!! dnl If we name the variable RM it will shadow the RM variable in the configure script and we overwrite the dnl value with the name of the rm command and not rm -f which is its normal content. This gives all kind dnl of strange output of the configure script (like things don't exist etc.). dnl So we name it REMOVE (more software has run into this problem) AC_PATH_PROG(REMOVE, rm, []) dnl Alert !!! dnl If we name the variable ECHO it will shadow the ECHO variable in the configure script dnl This gives all kind of strange output in the make depend on some platforms dnl So we name it ECHOCMD (more software has run into this problem) AC_PATH_PROG(ECHOCMD, echo, []) AC_PATH_PROG(CP, cp, []) AC_PATH_PROG(SED, sed, []) AC_PATH_PROG(CMP, cmp, []) AC_PATH_PROG(TBL, tbl, []) AC_PATH_PROG(AR, ar, []) AC_PATH_PROG(OPENSSL, openssl, []) AC_PATH_PROG(MTX, mtx, [], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin]) AC_PATH_PROG(DD, dd, []) AC_PATH_PROG(PYTHON, python, []) AC_PATH_PROG(PKGCONFIG, pkg-config, []) AC_PATH_PROG(QMAKE, qmake, []) AC_PATH_PROG(GMAKE, gmake, []) AC_PATH_PROG(PIDOF, pidof, []) AC_PATH_PROG(PGREP, pgrep, []) AC_PATH_PROG(GCORE, gcore, []) AC_PATH_PROG(GDB, gdb, []) AC_PATH_PROG(DBX, dbx, []) AC_PATH_PROG(MDB, mdb, []) AC_PROG_AWK # Some AWK programs fail, so test it and warn the user if echo xfoo | $AWK 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $2) || (("(" prog ")") == $2) || (("[" prog "]") == $2) || ((prog ":") == $2)) { print $1 ; exit 0 } }' xfoo>/dev/null; then :; else AC_MSG_ERROR([!!!!!!!!! WARNING !!!!!!!!!!!!!! The regex engine of $AWK is too broken to be used you might want to install GNU AWK. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!]) fi THE_AWK=$AWK AC_PATH_PROG(AWK, $THE_AWK, $THE_AWK) test -n "$ARFLAG" || ARFLAGS="cr" AC_SUBST(ARFLAGS) MAKE_SHELL=/bin/sh AC_SUBST(MAKE_SHELL) AC_SUBST(LOCAL_LIBS) AC_SUBST(LOCAL_CFLAGS) AC_SUBST(LOCAL_LDFLAGS) AC_SUBST(LOCAL_DEFS) dnl -------------------------------------------------- dnl Libtool config dnl -------------------------------------------------- use_libtool=yes AC_ARG_ENABLE(libtool, AC_HELP_STRING([--enable-libtool], [enable building using GNU libtool @<:@default=yes@:>@]), [ if test x$enableval = xno; then use_libtool=no fi ] ) LT_INIT([shared disable-static]) LT_LIB_DLLOAD LT_LANG([C++]) if test x$use_libtool != xno; then DEFAULT_OBJECT_TYPE=".lo" DEFAULT_ARCHIVE_TYPE=".la" DEFAULT_SHARED_OBJECT_TYPE=".la" LIBTOOL="\$(LIBTOOL)" LIBTOOL_INSTALL_TARGET="libtool-install" LIBTOOL_CLEAN_TARGET="libtool-clean" QMAKE_LIBTOOL="${BUILD_DIR}/libtool" FD_PLUGIN_DIR="src/plugins/filed" SD_PLUGIN_DIR="src/plugins/stored" DIR_PLUGIN_DIR="src/plugins/dird" have_plugins=yes else DEFAULT_OBJECT_TYPE=".o" DEFAULT_ARCHIVE_TYPE=".a" DEFAULT_SHARED_OBJECT_TYPE=".so" LIBTOOL="# \$(LIBTOOL)" LIBTOOL_INSTALL_TARGET="" LIBTOOL_CLEAN_TARGET="" QMAKE_LIBTOOL="# ${BUILD_DIR}/libtool" FD_PLUGIN_DIR="" SD_PLUGIN_DIR="" DIR_PLUGIN_DIR="" have_plugins=no fi AC_SUBST(DEFAULT_OBJECT_TYPE) AC_SUBST(DEFAULT_ARCHIVE_TYPE) AC_SUBST(DEFAULT_SHARED_OBJECT_TYPE) AC_SUBST(LIBTOOL) AC_SUBST(LIBTOOL_INSTALL_TARGET) AC_SUBST(LIBTOOL_CLEAN_TARGET) AC_SUBST(QMAKE_LIBTOOL) AC_SUBST(FD_PLUGIN_DIR) dnl -------------------------------------------------- dnl Include file handling dnl -------------------------------------------------- AC_ARG_ENABLE(includes, AC_HELP_STRING([--enable-includes], [enable installing of include files @<:@default=no@:>@]), [ if test x$enableval = xyes; then install_includes=yes fi ] ) dnl It only makes sense to install include files when you install libraries which only happens when dnl libtool is enabled if test x$use_libtool != xno -a x$install_includes = xyes; then INCLUDE_INSTALL_TARGET="install-includes" else INCLUDE_INSTALL_TARGET="" fi AC_SUBST(INCLUDE_INSTALL_TARGET) dnl -------------------------------------------------- dnl Bareos OP Sys determination (see aclocal.m4) dnl -------------------------------------------------- BA_CHECK_OPSYS dnl ----------------------------------------------------------- dnl Bareos OPSys Distribution determination (see aclocal.m4) dnl ---------------------------------------------------------- BA_CHECK_OPSYS_DISTNAME dnl ----------------------------------------------------------- dnl Bareos OPSys Distribution determination (see aclocal.m4) dnl ---------------------------------------------------------- BA_CHECK_OBS_DISTNAME AC_SUBST(OBS_PROJECT) AC_SUBST(OBS_DISTRIBUTION) AC_SUBST(OBS_ARCH) AC_SUBST(OBS_SRCMD5) dnl -------------------------------------------------- dnl Suppport for gettext (translations) dnl By default, $datarootdir is ${prefix}/share dnl -------------------------------------------------- AM_GNU_GETTEXT([external]) dnl ------------------------------------------------------------------ dnl If the user has not set --prefix, we set our default to nothing. dnl In this case, if the user has not set --sysconfdir, we set it dnl to the package default of /etc/bareos. If either --prefix or dnl --sysconfdir is set, we leave sysconfdir alone except to eval it. dnl If the user has not set --libdir, we set it to the package dnl default of /usr/lib. If either --prefix or --libdir is set, dnl we leave libdir alone except to eval it. If the user has not set dnl --includedir, we set it to the package default of /usr/include. dnl If either --prefix or --includedir is set, we leave includedir dnl alone except to eval it dnl ------------------------------------------------------------------ os_name=`uname -s 2>/dev/null` if test x${prefix} = xNONE ; then if test `eval echo ${sysconfdir}` = NONE/etc ; then sysconfdir=/etc/bareos fi if test `eval echo ${libdir}` = NONE/lib ; then case ${os_name} in Linux) os_processor=`uname -p 2>/dev/null` case ${os_processor} in x86_64) libdir=/usr/lib64 ;; *) libdir=/usr/lib ;; esac ;; *) libdir=/usr/lib ;; esac fi if test `eval echo ${includedir}` = NONE/include ; then includedir=/usr/include fi if test `eval echo ${datarootdir}` = NONE/share ; then datarootdir=/usr/share fi prefix= fi dnl ------------------------------------------------------------------------- dnl If the user has not set --exec-prefix, we default to ${prefix} dnl ------------------------------------------------------------------------- if test x${exec_prefix} = xNONE ; then exec_prefix=${prefix} fi sysconfdir=`eval echo ${sysconfdir}` datarootdir=`eval echo ${datarootdir}` docdir=`eval echo ${docdir}` htmldir=`eval echo ${htmldir}` libdir=`eval echo ${libdir}` includedir=`eval echo ${includedir}` localedir=`eval echo ${datarootdir}/locale` AC_DEFINE_UNQUOTED(LIBDIR, "$libdir", [Where are shared libs stored]) AC_DEFINE_UNQUOTED(SYSCONFDIR, "$sysconfdir", [Where are config files stored]) AC_DEFINE_UNQUOTED(LOCALEDIR, "$localedir", [Where are locale files stored]) dnl ------------------------------------------------------------------ dnl If the user has not set --bindir, we set our default as /bin dnl ------------------------------------------------------------------ if test x$bindir = x'${exec_prefix}/bin' ; then bindir=${exec_prefix}/bin fi bindir=`eval echo ${bindir}` dnl ------------------------------------------------------------------ dnl If the user has not set --sbindir, we set our default as /sbin dnl ------------------------------------------------------------------ if test x$sbindir = x'${exec_prefix}/sbin' ; then sbindir=${exec_prefix}/sbin fi sbindir=`eval echo ${sbindir}` dnl ------------------------------------------------------------------------- dnl If the user has not set --mandir, we default to /usr/share/man dnl ------------------------------------------------------------------------- if test x$mandir = x'${prefix}/man' ; then mandir=/usr/share/man fi dnl ------------------------------------------------------------------------- dnl If the user has not set --htmldir, we default to /usr/share/doc/bareos/html dnl ------------------------------------------------------------------------- if test x$htmldir = x${docdir} ; then htmldir=`eval echo ${docdir}/html` fi dnl ------------------------------------------------------------------------- dnl If the user has not set --docdir, we default to /usr/share/doc/ dnl ------------------------------------------------------------------------- if test x$docdir = x'/usr/share/doc/' ; then docdir=`eval echo ${docdir}bareos` fi AC_PATH_PROGS(MSGFMT, msgfmt, no) if test "$MSGFMT" = "no" then echo 'msgfmt program not found, disabling NLS !' USE_NLS=no USE_INCLUDED_LIBINTL=no #else AM_GNU_GETTEXT fi support_smartalloc=yes support_readline=yes support_conio=yes support_bat=no support_traymonitor=no support_static_tools=no support_static_fd=no support_static_sd=no support_static_dir=no support_static_cons=no support_python=no build_client_only=no build_dird=yes build_stored=yes db_backends="" batch_insert_db_backends="" support_lockmgr=no support_lmdb=no support_ndmp=no dnl -------------------------------------------------------------------------- dnl CHECKING COMMAND LINE OPTIONS dnl -------------------------------------------------------------------------- dnl ------------------------------------------- dnl bat (default off) dnl ------------------------------------------- AC_ARG_ENABLE(bat, AC_HELP_STRING([--enable-bat], [enable build of bat Qt4 GUI @<:@default=no@:>@]), [ if test x$enableval = xyes; then AC_DEFINE(HAVE_BAT, 1, [Define to 1 if bat Qt4 GUI support should be enabled]) support_bat=yes fi ] ) BAT_DIR= DEBIAN_CONTROL_BAT=/dev/null if test x$support_bat = xyes; then abc=`$PKGCONFIG --atleast-version=4.6 QtGui` pkg=$? if test $pkg = 0; then BAT_DIR=src/qt-console DEBIAN_CONTROL_BAT=./debian/control.bareos-bat else AC_MSG_ERROR(Unable to find suitable Qt4 installation needed by bat) fi fi AC_SUBST(BAT_DIR) AC_SUBST_FILE(DEBIAN_CONTROL_BAT) dnl ------------------------------------------- dnl tray-monitor (default off) dnl ------------------------------------------- AC_ARG_ENABLE(traymonitor, AC_HELP_STRING([--enable-traymonitor], [enable build of traymonitor @<:@default=no@:>@]), [ if test x$enableval = xyes; then AC_DEFINE(HAVE_TRAYMONITOR, 1, [Define to 1 if tray-monitor Qt4 GUI support should be enabled]) support_traymonitor=yes fi ] ) TRAY_MONITOR_DIR= DEBIAN_CONTROL_TRAYMONITOR=/dev/null if test x$support_traymonitor = xyes; then abc=`$PKGCONFIG --atleast-version=4.6 QtGui` pkg=$? if test $pkg = 0; then TRAY_MONITOR_DIR=src/qt-tray-monitor DEBIAN_CONTROL_TRAYMONITOR=./debian/control.bareos-traymonitor else AC_MSG_ERROR(Unable to find suitable Qt4 installation needed by tray-monitor) fi fi AC_SUBST(TRAY_MONITOR_DIR) AC_SUBST_FILE(DEBIAN_CONTROL_TRAYMONITOR) dnl ------------------------------------------- dnl smartalloc (default off) dnl ------------------------------------------- AC_ARG_ENABLE(smartalloc, AC_HELP_STRING([--enable-smartalloc], [enable smartalloc debugging support @<:@default=no@:>@]), [ if test x$enableval = xno; then support_smartalloc=no fi ] ) if test x$support_smartalloc = xyes; then AC_DEFINE(SMARTALLOC, 1, [Define to 1 if you want Smartalloc enabled]) fi dnl ------------------------------------------- dnl Lock Manager (default off) dnl ------------------------------------------- AC_ARG_ENABLE(lockmgr, AC_HELP_STRING([--enable-lockmgr], [enable lock manager support @<:@default=no@:>@]), [ if test x$enableval = xyes; then support_lockmgr=yes fi ] ) if test x$support_lockmgr = xyes; then AC_DEFINE(_USE_LOCKMGR, 1, [Define to 1 if you want Lock Manager enabled]) fi dnl ------------------------------------------- dnl static-tools (default off) dnl ------------------------------------------- AC_ARG_ENABLE(static-tools, AC_HELP_STRING([--enable-static-tools], [enable static tape tools @<:@default=no@:>@]), [ if test x$enableval = xyes; then if test x$use_libtool = xyes; then AC_MSG_ERROR([Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool]) fi support_static_tools=yes fi ] ) TTOOL_LDFLAGS= if test x$support_static_tools = xyes; then TTOOL_LDFLAGS="-static" fi AC_SUBST(TTOOL_LDFLAGS) dnl ------------------------------------------- dnl static-fd (default off) dnl ------------------------------------------- AC_ARG_ENABLE(static-fd, AC_HELP_STRING([--enable-static-fd], [enable static File daemon @<:@default=no@:>@]), [ if test x$enableval = xyes; then if test x$use_libtool = xyes; then AC_MSG_ERROR([Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool]) fi support_static_fd=yes fi ] ) STATIC_FD= if test x$support_static_fd = xyes; then STATIC_FD="static-bareos-fd" fi AC_SUBST(STATIC_FD) dnl ------------------------------------------- dnl static-sd (default off) dnl ------------------------------------------- AC_ARG_ENABLE(static-sd, AC_HELP_STRING([--enable-static-sd], [enable static Storage daemon @<:@default=no@:>@]), [ if test x$enableval = xyes; then if test x$use_libtool = xyes; then AC_MSG_ERROR([Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool]) fi support_static_sd=yes fi ] ) STATIC_SD= if test x$support_static_sd = xyes; then STATIC_SD="static-bareos-sd" fi AC_SUBST(STATIC_SD) dnl ------------------------------------------- dnl static-dir (default off) dnl ------------------------------------------- AC_ARG_ENABLE(static-dir, AC_HELP_STRING([--enable-static-dir], [enable static Director @<:@default=no@:>@]), [ if test x$enableval = xyes; then if test x$use_libtool = xyes; then AC_MSG_ERROR([Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool]) fi support_static_dir=yes fi ] ) STATIC_DIR= if test x$support_static_dir = xyes; then STATIC_DIR="static-bareos-dir" fi AC_SUBST(STATIC_DIR) dnl ------------------------------------------- dnl static-cons (default off) dnl ------------------------------------------- AC_ARG_ENABLE(static-cons, AC_HELP_STRING([--enable-static-cons], [enable static Console @<:@default=no@:>@]), [ if test x$enableval = xyes; then if test x$use_libtool = xyes; then AC_MSG_ERROR([Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool]) fi support_static_cons=yes fi ] ) STATIC_CONS= if test x$support_static_cons = xyes; then STATIC_CONS="static-bconsole" fi AC_SUBST(STATIC_CONS) dnl ------------------------------------------- dnl client_only (default off) dnl ------------------------------------------- AC_ARG_ENABLE(client-only, AC_HELP_STRING([--enable-client-only], [build client (File daemon) only @<:@default=no@:>@]), [ if test x$enableval = xyes; then build_client_only=yes db_backends="None" DB_BACKENDS="none" fi ] ) if test x$build_client_only = xno; then ALL_DIRS="subdirs" else ALL_DIRS="" fi AC_SUBST(ALL_DIRS) dnl ------------------------------------------- dnl director (default on) dnl ------------------------------------------- AC_ARG_ENABLE(build-dird, AC_HELP_STRING([--enable-build-dird], [enable building of dird (Director) @<:@default=yes@:>@]), [ if test x$enableval = xno; then build_dird=no fi ] ) if test x$build_dird = xyes; then DIRD_DIR="src/dird" else DIRD_DIR="" DIR_PLUGIN_DIR="" fi AC_SUBST(DIRD_DIR) AC_SUBST(DIR_PLUGIN_DIR) dnl ------------------------------------------- dnl stored (default on) dnl ------------------------------------------- AC_ARG_ENABLE(build-stored, AC_HELP_STRING([--enable-build-stored], [enable building of stored (Storage daemon) @<:@default=yes@:>@]), [ if test x$enableval = xno; then build_stored=no fi ] ) if test x$build_stored = xyes; then STORED_DIR="src/stored" else STORED_DIR="" SD_PLUGIN_DIR="" fi AC_SUBST(STORED_DIR) AC_SUBST(SD_PLUGIN_DIR) dnl -------------------------------------------------- dnl dynamic loading of storage backends dnl -------------------------------------------------- use_dynamic_storage_backends=no AC_ARG_ENABLE(dynamic-storage_backends, AC_HELP_STRING([--enable-dynamic-storage-backends], [enable dynamic loading of storage backends @<:@default=no@:>@]), [ if test x$enableval = xyes; then use_dynamic_storage_backends=yes AC_DEFINE(HAVE_DYNAMIC_SD_BACKENDS, 1, [Define to 1 if dynamic loading of storage backends is enabled]) fi ] ) if test "x$use_libtool" != "xyes" -a "x$use_dynamic_storage_backends" = "xyes"; then echo "" echo "You specified --enable-dynamic-storage-plugins but disabled libtool with --disable-libtool" echo "We only support dynamic loading using libtool so either disable dynamic loading or enable libtool" echo "" echo "Aborting the configuration ..." echo " " echo " " exit 1 fi if test x$use_dynamic_storage_backends = xyes; then NEEDED_DEVICE_API_SRCS="" NEEDED_BACKEND_LIBS="" SD_BACKENDS_DIR="src/stored/backends" else NEEDED_DEVICE_API_SRCS="\$(AVAILABLE_DEVICE_API_SRCS)" NEEDED_BACKEND_LIBS="\$(AVAILABLE_BACKEND_LIBS)" SD_BACKENDS_DIR="" fi AC_SUBST(NEEDED_DEVICE_API_SRCS) AC_SUBST(NEEDED_BACKEND_LIBS) AC_SUBST(SD_BACKENDS_DIR) dnl --------------------------------------------------- dnl Check for conio (Bareos readline substitute)( dnl --------------------------------------------------- dnl this allows you to turn it completely off AC_ARG_ENABLE(conio, AC_HELP_STRING([--disable-conio], [disable conio support @<:@default=no@:>@]), [ if test x$enableval = xno; then support_conio=no fi ] ) dnl --------------------------------------------------- dnl Check for IPv6 support dnl --------------------------------------------------- dnl this allows you to turn it completely off support_ipv6=yes AC_ARG_ENABLE(ipv6, AC_HELP_STRING([--enable-ipv6], [enable ipv6 support @<:@default=yes@:>@]), [ if test x$enableval = xno; then support_ipv6=no fi ] ) if test x$support_ipv6 = xyes; then AC_TRY_LINK([ #include #include #include ], [struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0;], [support_ipv6=yes], [support_ipv6=no]) fi if test x$support_ipv6 = xyes; then AC_DEFINE(HAVE_IPV6, 1, [Define to 1 if IPv6 support should be enabled]) fi TERM_LIB="" AC_CHECK_HEADER(curses.h, [ AC_CHECK_LIB(tinfo, tgetent, [ TERM_LIB="-ltinfo" ], [ AC_CHECK_LIB(ncurses, tgetent, [ TERM_LIB="-lncurses" ], [ AC_CHECK_LIB(termcap, tgetent, [ TERM_LIB="-ltermcap" ]) ]) ]) ], [ AC_CHECK_HEADERS(curses.h) AC_CHECK_HEADER(term.h, [ AC_CHECK_LIB(curses, tgetent, [ TERM_LIB="-lcurses" ] ) ]) ]) got_conio="no" if test x$support_conio = xyes; then if test x$TERM_LIB != x; then CONS_LIBS=$TERM_LIB CONS_SRC="conio.c" got_conio="yes" support_readline=no AC_DEFINE(HAVE_CONIO, 1, [Define to 1 if Bareos conio support enabled]) else echo " "; echo "Required libraries not found. CONIO turned off ..."; echo " " fi fi dnl --------------------------------------------------- dnl Check for readline support/directory (default off) dnl --------------------------------------------------- dnl this allows you to turn it completely off AC_ARG_ENABLE(readline, AC_HELP_STRING([--disable-readline], [disable readline support @<:@default=yes@:>@]), [ if test x$enableval = xno; then support_readline=no fi ] ) if test x$TERM_LIB = x ; then support_readline=no fi got_readline="no" READLINE_SRC= if test x$support_readline = xyes; then AC_ARG_WITH(readline, AC_HELP_STRING([--with-readline@<:@=DIR@:>@], [specify readline library directory]), [ case "$with_readline" in no) : ;; yes|*) if test -f ${with_readline}/readline.h; then CONS_INC="-I${with_readline}" CONS_LDFLAGS="-L$with_readline" elif test -f ${with_readline}/include/readline/readline.h; then CONS_INC="-I${with_readline}/include/readline" CONS_LDFLAGS="-L${with_readline}/lib" with_readline="${with_readline}/include/readline" else CONS_INC="-I/usr/include/readline" with_readline="/usr/include/readline" fi AC_CHECK_HEADER(${with_readline}/readline.h, [ AC_DEFINE(HAVE_READLINE, 1, [Define to 1 if readline support should be enabled]) CONS_LIBS="-lreadline -lhistory $TERM_LIB" got_readline="yes" ], [ echo " " echo "readline.h not found. readline turned off ..." echo " " ] ) ;; esac ],[ dnl check for standard readline library AC_CHECK_HEADER(/usr/include/readline/readline.h, [ AC_DEFINE(HAVE_READLINE, 1, [Define to 1 if readline support should be enabled]) got_readline="yes" CONS_INC="-I/usr/include/readline" CONS_LIBS="-lreadline $TERM_LIB" ], [ dnl Did not find standard library, so try Bareos's default AC_CHECK_HEADER(${TOP_DIR}/depkgs/readline/readline.h, [ AC_DEFINE(HAVE_READLINE, 1, [Define to 1 if readline support should be enabled]) got_readline="yes" CONS_INC="-I${TOP_DIR}/depkgs/readline" CONS_LIBS="-lreadline -lhistory $TERM_LIB" CONS_LDFLAGS="-L${TOP_DIR}/depkgs/readline" PRTREADLINE_SRC="${TOP_DIR}/depkgs/readline" ], [ echo " " echo "readline.h not found. readline turned off ..." echo " " ] ) ] ) ] ) fi AC_SUBST(CONS_INC) AC_SUBST(CONS_SRC) AC_SUBST(CONS_LIBS) AC_SUBST(CONS_LDFLAGS) AC_SUBST(READLINE_SRC) dnl End of readline/conio stuff dnl ------------------------------------------- dnl dynamic-debian-package-list (default off) dnl ------------------------------------------- AC_ARG_ENABLE(dynamic-debian-package-list, AC_HELP_STRING([--enable-dynamic-debian-package-list], [generate debian/control depending on configured options @<:@default=no@:>@]), [ if test x$enableval = xyes; then generate_debian_control=yes fi ] ) DEBIAN_CONTROL= if test x$generate_debian_control = xyes; then DEBIAN_CONTROL="debian/control" fi AC_SUBST(DEBIAN_CONTROL) dnl ----------------------------------------------------------------------- dnl Minimal stuff for readline Makefile configuration MAKE_SHELL=/bin/sh AC_SUBST(MAKE_SHELL) AC_HEADER_STAT AC_HEADER_DIRENT AC_CHECK_HEADER(poll.h, [AC_DEFINE(HAVE_POLL_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_HEADER(sys/poll.h, [AC_DEFINE(HAVE_SYS_POLL_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_FUNCS(strcasecmp select poll setenv putenv tcgetattr) AC_CHECK_FUNCS(lstat lchown lchmod utimes lutimes futimes futimens fchmod fchown) AC_CHECK_FUNCS(nanosleep nl_langinfo) AC_CHECK_HEADERS(varargs.h) dnl ----------------------------------------------------------------------- dnl Check for Python support dnl AC_MSG_CHECKING(for Python support) AC_ARG_WITH(python, AC_HELP_STRING([--with-python@<:@=DIR@:>@], [Include Python support. DIR is the Python base install directory, default is to search through a number of common places for the Python files.]), [ PYTHON_INC= PYTHON_LIBS= if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -e /usr/bin/python-config ; then PYTHON_INC=`/usr/bin/python-config --includes` PYTHON_LIBS=`/usr/bin/python-config --libs` else for python_root in /usr /usr/local /usr/sfw; do for ver in python2.2 python2.3 python2.4 python2.5 python2.6 python2.7 python3; do if test -f $python_root/include/${ver}/Python.h; then PYTHON_INC=-I$python_root/include/${ver} if test -d $python_root/lib64/${ver}/config; then PYTHON_LIBS="-L$python_root/lib64/${ver}/config -l${ver}" else PYTHON_LIBS="-L$python_root/lib/${ver}/config -l${ver}" fi break fi done done if test x$PYTHON_INC = x; then if test -f $prefix/include/Python.h; then PYTHON_INC=-I$prefix/include if test -d $prefix/lib64/config; then PYTHON_LIBS="-L$prefix/lib64/config -lpython" else PYTHON_LIBS="-L$prefix/lib/config -lpython" fi else AC_MSG_RESULT(no) AC_MSG_ERROR(Unable to find Python.h in standard locations) fi fi fi else if test -e $withval/bin/python-config ; then PYTHON_INC=`$withval/bin/python-config --includes` PYTHON_LIBS=`$withval/bin/python-config --libs` elif test -f $withval/Python.h; then PYTHON_INC=-I$withval PYTHON_LIBS="-L$withval/config -lpython" elif test -f $withval/include/Python.h; then PYTHON_INC=-I$withval/include if test -d $withval/lib64/config; then PYTHON_LIBS="-L$withval/lib64/config -lpython" else PYTHON_LIBS="-L$withval/lib/config -lpython" fi elif test -f $withval/include/python/Python.h; then PYTHON_INC=-I$withval/include/python if test -d $withval/lib64/python/config; then PYTHON_LIBS="-L$withval/lib64/python/config -lpython" else PYTHON_LIBS="-L$withval/lib/python/config -lpython" fi else AC_MSG_RESULT(no) AC_MSG_ERROR(Invalid Python directory $withval - unable to find Python.h under $withval) fi fi AC_DEFINE(HAVE_PYTHON, 1, [Define to 1 if python support should be enabled]) AC_MSG_RESULT(yes) support_python=yes AC_MSG_NOTICE(checking for more Python libs) saved_LIBS="$LIBS"; LIBS= AC_SEARCH_LIBS(shm_open, [rt]) AC_CHECK_LIB(util, openpty) PYTHON_LIBS="$PYTHON_LIBS $LIBS" LIBS="$saved_LIBS" else AC_MSG_RESULT(no) fi ],[ AC_MSG_RESULT(no) ] ) AC_SUBST(PYTHON_LIBS) AC_SUBST(PYTHON_INC) dnl dnl Find where sockets are (especially for Solaris) dnl Do this before the TCP Wrappers test since tcp wrappers dnl uses the socket library and some linkers are stupid. dnl AC_CHECK_FUNC(socket, AC_MSG_RESULT(using socket from libc), [ AC_CHECK_LIB(socket, socket, [ LIBS="-lsocket $LIBS" SOCKLIBS="-lsocket $LIBS" ], [ AC_CHECK_LIB(xnet, socket, [ LIBS="-lxnet $LIBS" SOCKLIBS="-lxnet $LIBS" ], [ AC_CHECK_LIB(inet, socket, [ LIBS="-linet $LIBS" SOCKLIBS="-linet $LIBS" ] ) ] ) ] ) ] ) dnl ----------------------------------------------------------- dnl Check whether user wants TCP wrappers support (default off) dnl ----------------------------------------------------------- TCPW_MSG="no" WRAPLIBS="" AC_ARG_WITH(tcp-wrappers, AC_HELP_STRING([--with-tcp-wrappers@<:@=DIR@:>@], [enable tcpwrappers support]), [ if test "x$withval" != "xno" ; then saved_LIBS="$LIBS" LIBS="$saved_LIBS -lwrap" AC_SEARCH_LIBS(nanosleep, [rt]) AC_MSG_CHECKING(for libwrap) AC_TRY_LINK( [ #include #include int deny_severity = 0; int allow_severity = 0; struct request_info *req; ], [ hosts_access(req); ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_LIBWRAP, 1, [Define to 1 if libwrap support should be enabled]) TCPW_MSG="yes" LIBS="$saved_LIBS" WRAPLIBS="-lwrap" ], [ LIBS="$saved_LIBS -lwrap -lnsl" WRAPLIBS="$saved_LIBS -lwrap -lnsl" AC_TRY_LINK( [ #include #include int deny_severity = 0; int allow_severity = 0; struct request_info *req; ], [ hosts_access(req); ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_LIBWRAP, 1, [Set to enable libwrap support]) TCPW_MSG="yes" LIBS="$saved_LIBS" WRAPLIBS="-lwrap" ], [ AC_MSG_ERROR([*** libwrap missing]) ] ) ] ) fi ] ) dnl ----------------------------------------------------------- dnl Check if crypto support is wanted dnl ----------------------------------------------------------- support_crypto=auto AC_ARG_ENABLE(crypto, AC_HELP_STRING([--disable-crypto], [disable crypto support @<:@default=auto@:>@]), [ if test x$enableval = xyes; then support_crypto=yes elif test x$enableval = xno; then support_crypto=no fi ] ) dnl ----------------------------------------------------------- dnl Check if TLS support is wanted dnl ----------------------------------------------------------- support_tls=auto AC_ARG_ENABLE(tls, AC_HELP_STRING([--disable-tls], [disable TLS support @<:@default=auto@:>@]), [ if test x$enableval = xyes; then support_tls=yes elif test x$enableval = xno; then support_tls=no fi ] ) dnl ----------------------------------------------------------- dnl Default settings unless proven otherwise. dnl ----------------------------------------------------------- have_crypto=no have_tls=no dnl ----------------------------------------------------------- dnl Check whether OpenSSL is available dnl ----------------------------------------------------------- AC_MSG_CHECKING([for OpenSSL]) dnl The following uses quadrigraphs: dnl '@<:@' = '[' dnl '@:>@' = ']' AC_ARG_WITH(openssl, AC_HELP_STRING([--with-openssl@<:@=DIR@:>@], [Include OpenSSL support. DIR is the OpenSSL base]), [ with_openssl_directory=${withval} ] ) dnl See if crypto or tls support is wanted if test "x$support_crypto" != "xno" -o "x$support_tls" != "xno"; then if test "x$with_openssl_directory" != "xno"; then OPENSSL_LIBS="-lssl -lcrypto" OPENSSL_INC="" if test "x$with_openssl_directory" != "xyes" && test x"${with_openssl_directory}" != "x"; then # # Make sure the $with_openssl_directory also makes sense # if test -d "$with_openssl_directory/lib" -a -d "$with_openssl_directory/include"; then OPENSSL_LIBS="-L$with_openssl_directory/lib $OPENSSL_LIBS" OPENSSL_INC="-I$with_openssl_directory/include $OPENSSL_INC" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CFLAGS}" LIBS="${saved_LIBS} ${OPENSSL_LIBS}" CFLAGS="${saved_CFLAGS} ${OPENSSL_INC}" CPPFLAGS="${saved_CPPFLAGS} ${OPENSSL_INC}" AC_TRY_LINK( [ #include ], [ ENGINE_load_pk11(); ], [ AC_DEFINE(HAVE_ENGINE_LOAD_PK11, 1, [Define to 1 if OpenSSL library has ENGINE_load_pk11 available]) ] ) AC_TRY_LINK( [ #include ], [ CRYPTO_set_id_callback(NULL); ], [ have_openssl="yes" ], [ have_openssl="no" ] ) AC_TRY_LINK( [ #include ], [ EVP_sha512(); ], [ ac_cv_openssl_sha2="yes" ], [ ac_cv_openssl_sha2="no" ] ) dnl Solaris disables greater than 128+ bit encryption in their OpenSSL dnl implementation, presumably for export reasons. If 192bit AES dnl is available, we assume that we're running with a 'non-export' dnl openssl library. AC_TRY_LINK( [ #include ], [ EVP_aes_192_cbc(); ], [ ac_cv_openssl_export="no" ], [ ac_cv_openssl_export="yes" ] ) AC_MSG_RESULT([$have_crypto]) if test "$have_openssl" = "yes"; then AC_DEFINE(HAVE_OPENSSL, 1, [Define to 1 if OpenSSL library is available]) fi if test "$support_crypto" != "no" -a "$have_openssl" = "yes"; then have_crypto="yes" AC_DEFINE(HAVE_CRYPTO, 1, [Define to 1 if encryption support should be enabled]) fi if test "$support_tls" != "no" -a "$have_openssl" = "yes"; then have_tls="yes" AC_DEFINE(HAVE_TLS, 1, [Define to 1 if TLS support should be enabled]) fi if test "$ac_cv_openssl_sha2" = "yes"; then AC_DEFINE(HAVE_SHA2, 1, [Define to 1 if the SHA-2 family of digest algorithms is available]) fi if test "$ac_cv_openssl_export" = "yes"; then AC_DEFINE(HAVE_OPENSSL_EXPORT_LIBRARY, 1, [Define to 1 if the OpenSSL library is export-contrained to 128bit ciphers]) fi LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" else have_openssl="no" AC_MSG_RESULT(no) fi fi if test "$have_openssl" = "no"; then OPENSSL_LIBS="" OPENSSL_INC="" fi if test x$use_libtool != xno; then OPENSSL_LIBS_NONSHARED="" else OPENSSL_LIBS_NONSHARED="${OPENSSL_LIBS}" fi AC_SUBST(OPENSSL_LIBS) AC_SUBST(OPENSSL_INC) AC_SUBST(OPENSSL_LIBS_NONSHARED) dnl ----------------------------------------------------------- dnl Check whether GNUTLS is available dnl ----------------------------------------------------------- with_gnutls_directory=no AC_ARG_WITH(gnutls, AC_HELP_STRING([--with-gnutls@<:@=DIR@:>@], [Include GNUTLS support. DIR is the GNUTLS base]), [ with_gnutls_directory=${withval} ] ) dnl See if crypto or tls support is wanted if test "x$support_crypto" != "xno" -o "x$support_tls" != "xno"; then dnl When openssl was alread found and enabled use that. if test "x$have_openssl" != "xyes" -a "x$with_gnutls_directory" != "xno"; then GNUTLS_LIBS="-lgnutls" GNUTLS_INC="" if test "x$with_gnutls_directory" != "xyes" && test x"${with_gnutls_directory}" != "x"; then # # Make sure the $with_gnutls_directory also makes sense # if test -d "$with_gnutls_directory/lib" -a -d "$with_gnutls_directory/include"; then GNUTLS_LIBS="-L$with_gnutls_directory/lib $GNUTLS_LIBS" GNUTLS_INC="-I$with_gnutls_directory/include $GNUTLS_INC" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CFLAGS}" LIBS="${saved_LIBS} ${GNUTLS_LIBS}" CFLAGS="${saved_CFLAGS} ${GNUTLS_INC}" CPPFLAGS="${saved_CPPFLAGS} ${GNUTLS_INC}" AC_CHECK_HEADERS(gnutls/gnutls.h) if test $ac_cv_header_gnutls_gnutls_h = yes ; then AC_CHECK_LIB(gnutls, gnutls_init, [ have_gnutls="yes" ], [ have_gnutls="no" ] ) fi if test "$have_gnutls" = "yes"; then # do an additional check to see if required functions are available, # otherwise disable gnutls AC_CHECK_FUNCS(gnutls_cipher_init, [ have_gnutls="yes" ], [ have_gnutls="no" ] ) fi if test "$have_gnutls" = "yes"; then AC_DEFINE(HAVE_GNUTLS, 1, [Define to 1 if GNUTLS library is available]) # gnutls_transport_set_ptr may cause problems on some platforms, # therefore the replacement gnutls_transport_set_int is used # when available (since GnuTLS >= 3.1.9) AC_CHECK_FUNCS(gnutls_transport_set_int) fi if test "$support_tls" != "no" -a "$have_gnutls" = "yes"; then have_tls="yes" AC_DEFINE(HAVE_TLS, 1, [Define to 1 if TLS support should be enabled]) fi LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" else have_gnutls="no" fi fi if test "$have_gnutls" = "no"; then GNUTLS_LIBS="" GNUTLS_INC="" fi if test x$use_libtool != xno; then GNUTLS_LIBS_NONSHARED="" else GNUTLS_LIBS_NONSHARED="${GNUTLS_LIBS}" fi AC_SUBST(GNUTLS_LIBS) AC_SUBST(GNUTLS_INC) AC_SUBST(GNUTLS_LIBS_NONSHARED) dnl ----------------------------------------------------------- dnl dlopen is needed for plugins dnl ----------------------------------------------------------- AC_SEARCH_LIBS(dlopen, [dl]) dnl ------------------------------------------ dnl Where to place working dir dnl ------------------------------------------ working_dir=`eval echo ${prefix}/var/bareos/working` AC_ARG_WITH(working-dir, AC_HELP_STRING([--with-working-dir=PATH], [specify path of Bareos working directory]), [ if test "x$withval" != "xno" ; then working_dir=$withval fi ] ) AC_DEFINE_UNQUOTED(_PATH_BAREOS_WORKINGDIR, "$working_dir", [Directory for daemon files]) AC_SUBST(working_dir) dnl ------------------------------------------------------------------ dnl If the user has not set archivedir, we set our default as /tmp dnl ------------------------------------------------------------------ archivedir=/tmp AC_ARG_WITH(archivedir, AC_HELP_STRING([--with-archivedir=PATH], [specify path of SD archive directory]), [ if test "x$withval" != "xno" ; then archivedir=$withval fi ] ) AC_SUBST(archivedir) dnl ------------------------------------------------------------------ dnl Allow the user to specify the daemon resource name default hostname dnl ------------------------------------------------------------------ basename=`hostname` AC_ARG_WITH(basename, AC_HELP_STRING([--with-basename=RESNAME], [specify base resource name for daemons]), [ if test "x$withval" != "xno" ; then basename=$withval fi ] ) AC_SUBST(basename) dnl ------------------------------------------------------------------ dnl Allow the user to override the hostname (default = machine hostname) dnl ------------------------------------------------------------------ hostname=`uname -n | cut -d '.' -f 1` if test x${hostname} = x ; then hostname="localhost" fi dnl Make sure hostname is resolved ping -c 1 $hostname 2>/dev/null 1>/dev/null if test ! $? = 0; then hostname="localhost" fi AC_ARG_WITH(hostname, AC_HELP_STRING([--with-hostname=RESNAME], [specify host name for daemons]), [ if test "x$withval" != "xno" ; then hostname=$withval fi ] ) AC_SUBST(hostname) dnl ------------------------------------------ dnl Where to place scriptdir (script files) dnl ------------------------------------------ scriptdir=`eval echo ${sysconfdir}` AC_ARG_WITH(scriptdir, AC_HELP_STRING([--with-scriptdir=PATH], [specify path of Bareos scripts directory]), [ if test "x$withval" != "xno" ; then scriptdir=$withval fi ] ) AC_SUBST(scriptdir) # ------------------------------------------ # Where to place backenddir (backend library files) # ------------------------------------------ backenddir=`eval echo ${libdir}` AC_ARG_WITH(backenddir, AC_HELP_STRING([--with-backenddir=PATH], [specify path of Bareos backends directory]), [ if test "x$withval" != "xno" ; then backenddir=$withval fi ] ) AC_DEFINE_UNQUOTED(_PATH_BAREOS_BACKENDDIR, "$backenddir", [Directory for backend files]) AC_SUBST(backenddir) dnl ------------------------------------------ dnl Where to place bsrdir (bsr files) dnl ------------------------------------------ bsrdir=`eval echo ${prefix}/var/bareos/working` AC_ARG_WITH(bsrdir, AC_HELP_STRING([--with-bsrdir=PATH], [specify path of Bareos bsrs directory]), [ if test "x$withval" != "xno" ; then bsrdir=$withval fi ] ) AC_SUBST(bsrdir) dnl ------------------------------------------ dnl Where to place logdir (bsr files) dnl ------------------------------------------ logdir=`eval echo ${prefix}/var/bareos/logs` AC_ARG_WITH(logdir, AC_HELP_STRING([--with-logdir=PATH], [specify path of Bareos logs directory]), [ if test "x$withval" != "xno" ; then logdir=$withval fi ] ) AC_SUBST(logdir) # ------------------------------------------ # Where to place plugindir (plugin files) # ------------------------------------------ plugindir=`eval echo ${libdir}` AC_ARG_WITH(plugindir, AC_HELP_STRING([--with-plugindir=PATH], [specify path of Bareos plugins directory]), [ if test "x$withval" != "xno" ; then plugindir=$withval fi ] ) AC_SUBST(plugindir) # ------------------------------------------ # Where to place configtemplatedir (configuration template files) # ------------------------------------------ configtemplatedir=`eval echo ${libdir}` AC_ARG_WITH(configtemplatedir, AC_HELP_STRING([--with-configtemplatedir=PATH], [specify path of Bareos configuration templates directory (Debian only)]), [ if test "x$withval" != "xno" ; then configtemplatedir=$withval fi ] ) AC_SUBST(configtemplatedir) dnl ------------------------------------------ dnl Where to send dump email dnl ------------------------------------------ dump_email=root@localhost AC_ARG_WITH(dump-email, AC_HELP_STRING([--with-dump-email=EMAIL], [dump email address]), [ if test "x$withval" != "xno" ; then dump_email=$withval fi ] ) AC_SUBST(dump_email) dnl ------------------------------------------ dnl Where to send job email dnl ------------------------------------------ job_email=root@localhost AC_ARG_WITH(job-email, AC_HELP_STRING([--with-job-email=EMAIL], [job output email address]), [ if test "x$withval" != "xno" ; then job_email=$withval fi ] ) AC_SUBST(job_email) dnl ------------------------------------------ dnl Where to find smtp host dnl ------------------------------------------ smtp_host=localhost AC_ARG_WITH(smtp_host, AC_HELP_STRING([--with-smtp-host=HOST], [SMTP mail host address]), [ if test "x$withval" != "xno" ; then smtp_host=$withval fi ] ) AC_SUBST(smtp_host) dnl ------------------------------------ dnl Where to place pid files dnl ------------------------------------ piddir=/var/run AC_ARG_WITH(pid-dir, AC_HELP_STRING([--with-pid-dir=PATH], [specify location of Bareos pid files]), [ if test "x$withval" != "xno" ; then piddir=$withval fi ] ) AC_DEFINE_UNQUOTED(_PATH_BAREOS_PIDDIR, "$piddir", [Directory for PID files]) AC_SUBST(piddir) dnl ------------------------------------ dnl Where to place subsys "lock file" dnl ------------------------------------ subsysdir=/var/run/subsys if test -d /var/run/subsys; then subsysdir=/var/run/subsys elif test -d /var/lock/subsys; then subsysdir=/var/lock/subsys else subsysdir=/var/run/subsys fi AC_ARG_WITH(subsys-dir, AC_HELP_STRING([--with-subsys-dir=PATH], [specify location of Bareos subsys file]), [ if test "x$withval" != "xno" ; then subsysdir=$withval fi ] ) AC_SUBST(subsysdir) dnl ------------------------------------ dnl Where to start assigning ports dnl ------------------------------------ baseport=9101 AC_ARG_WITH(baseport, AC_HELP_STRING([--with-baseport=PORT], [specify base port address for daemons]), [ if test "x$withval" != "xno" ; then baseport=$withval fi ] ) AC_SUBST(baseport) dir_port=`expr $baseport` fd_port=`expr $baseport + 1` sd_port=`expr $fd_port + 1` AC_SUBST(dir_port) AC_SUBST(fd_port) AC_SUBST(sd_port) dnl ------------------------------------------ dnl Generate passwords dnl ------------------------------------------ dir_password= AC_ARG_WITH(dir-password, AC_HELP_STRING([--with-dir-password=PASSWORD], [specify Director's password]), [ if test "x$withval" != "xno" ; then dir_password=$withval fi ] ) if test "x$dir_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 33` else key=`openssl rand -base64 33` fi dir_password=$key fi fd_password= AC_ARG_WITH(fd-password, AC_HELP_STRING([--with-fd-password=PASSWORD], [specify Client's password]), [ if test "x$withval" != "xno" ; then fd_password=$withval fi ] ) if test "x$fd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 37` else key=`openssl rand -base64 33` fi fd_password=$key fi sd_password= AC_ARG_WITH(sd-password, AC_HELP_STRING([--with-sd-password=PASSWORD], [specify Storage daemon's password]), [ if test "x$withval" != "xno" ; then sd_password=$withval fi ] ) if test "x$sd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 41` else key=`openssl rand -base64 33` fi sd_password=$key fi mon_dir_password= AC_ARG_WITH(mon-dir-password, AC_HELP_STRING([--with-mon-dir-password=PASSWORD], [specify Director's password used by the monitor]), [ if test "x$withval" != "xno" ; then mon_dir_password=$withval fi ] ) if test "x$mon_dir_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 33` else key=`openssl rand -base64 33` fi mon_dir_password=$key fi mon_fd_password= AC_ARG_WITH(mon-fd-password, AC_HELP_STRING([--with-mon-fd-password=PASSWORD], [specify Client's password used by the monitor]), [ if test "x$withval" != "xno" ; then mon_fd_password=$withval fi ] ) if test "x$mon_fd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 37` else key=`openssl rand -base64 33` fi mon_fd_password=$key fi mon_sd_password= AC_ARG_WITH(mon-sd-password, AC_HELP_STRING([--with-mon-sd-password=PASSWORD], [specify Storage daemon's password used by the monitor]), [ if test "x$withval" != "xno" ; then mon_sd_password=$withval fi ] ) if test "x$mon_sd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 41` else key=`openssl rand -base64 33` fi mon_sd_password=$key fi AC_SUBST(dir_password) AC_SUBST(fd_password) AC_SUBST(sd_password) AC_SUBST(mon_dir_password) AC_SUBST(mon_fd_password) AC_SUBST(mon_sd_password) dnl dnl Pickup any database name dnl db_name=bareos AC_ARG_WITH(db_name, AC_HELP_STRING([--with-db-name=DBNAME], [specify database name @<:@default=bareos@:>@]), [ if test "x$withval" != "x" ; then db_name=$withval fi ] ) AC_SUBST(db_name) db_user=bareos AC_ARG_WITH(db_user, AC_HELP_STRING([--with-db-user=UNAME], [specify database user @<:@default=bareos@:>@]), [ if test "x$withval" != "x" ; then db_user=$withval fi ] ) AC_SUBST(db_user) db_password= AC_ARG_WITH(db_password, AC_HELP_STRING([--with-db-password=PWD], [specify database password @<:@default=*none*@:>@]), [ if test "x$withval" != "x" ; then db_password=$withval fi ] ) AC_SUBST(db_password) dnl dnl Pickup a database port dnl db_port=" " AC_ARG_WITH(db_port, AC_HELP_STRING([--with-db-port=DBPORT], [specify a database port @<:@default=null@:>@]), [ if test "x$withval" != "x" ; then db_port=$withval fi ] ) AC_SUBST(db_port) # # Handle users and groups for each daemon # dir_user= AC_ARG_WITH(dir_user, AC_HELP_STRING([--with-dir-user=USER], [specify user for Director daemon]), [ if test "x$withval" != "x" ; then dir_user=$withval fi ] ) dir_group= AC_ARG_WITH(dir_group, AC_HELP_STRING([--with-dir-group=GROUP], [specify group for Director daemon]), [ if test "x$withval" != "x" ; then dir_group=$withval fi ] ) sd_user= AC_ARG_WITH(sd_user, AC_HELP_STRING([--with-sd-user=USER], [specify user for Storage daemon]), [ if test "x$withval" != "x" ; then sd_user=$withval fi ] ) sd_group= AC_ARG_WITH(sd_group, AC_HELP_STRING([--with-sd-group=GROUP], [specify group for Storage daemon]), [ if test "x$withval" != "x" ; then sd_group=$withval fi ] ) fd_user= AC_ARG_WITH(fd_user, AC_HELP_STRING([--with-fd-user=USER], [specify user for File daemon]), [ if test "x$withval" != "x" ; then fd_user=$withval fi ] ) fd_group= AC_ARG_WITH(fd_group, AC_HELP_STRING([--with-fd-group=GROUP], [specify group for File daemon]), [ if test "x$withval" != "x" ; then fd_group=$withval fi ] ) AC_SUBST(dir_user) AC_SUBST(dir_group) AC_SUBST(sd_user) AC_SUBST(sd_group) AC_SUBST(fd_user) AC_SUBST(fd_group) dnl dnl allow setting default executable permissions dnl SBINPERM=0750 AC_ARG_WITH(sbin-perm, AC_HELP_STRING([--with-sbin-perm=MODE], [specify permissions for sbin binaries @<:@default=0750@:>@]), [ if test "x$withval" != "x" ; then SBINPERM=$withval fi ] ) AC_SUBST(SBINPERM) dnl ------------------------------------------- dnl logrotate: has "su" option? dnl ------------------------------------------- AC_PATH_PROG(LOGROTATE, logrotate, [], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin]) logrotate_su="" if test "x$LOGROTATE" != "x" -a "x$dir_user" != "x" -a "x$dir_group" != "x"; then echo -e "/tmp/dummy.log {\n su root root\n}" > logrotate-test-su.conf if $LOGROTATE -d logrotate-test-su.conf 2>&1 | grep "unknown option 'su'" >/dev/null; then logrotate_su="" else logrotate_su="su ${dir_user} ${dir_group}" fi rm logrotate-test-su.conf fi AC_SUBST(logrotate_su) dnl ------------------------------------------- dnl NDMP (default off) dnl ------------------------------------------- AC_ARG_ENABLE(ndmp, AC_HELP_STRING([--enable-ndmp], [enable build of NDMP support @<:@default=no@:>@]), [ if test x$enableval = xyes; then AC_DEFINE(HAVE_NDMP, 1, [Define to 1 if NDMP support should be enabled]) support_ndmp=yes fi ] ) if test x$support_ndmp = xyes; then NDMP_DIR="src/ndmp" NDMP_LIBS="-L../ndmp -lbareosndmp" NDMP_DEPS="../ndmp/libbareosndmp\$(DEFAULT_ARCHIVE_TYPE)" else NDMP_DIR="" NDMP_LIBS="" NDMP_DEPS="" fi AC_SUBST(NDMP_DIR) AC_SUBST(NDMP_LIBS) AC_SUBST(NDMP_DEPS) dnl ------------------------------------------- dnl LMDB (default off) dnl ------------------------------------------- AC_ARG_ENABLE(lmdb, AC_HELP_STRING([--enable-lmdb], [enable build of LMDB support @<:@default=no@:>@]), [ if test x$enableval = xyes; then AC_DEFINE(HAVE_LMDB, 1, [Define to 1 if LMDB support should be enabled]) support_lmdb=yes fi ] ) if test x$support_lmdb = xyes; then LMDB_DIR="src/lmdb" LMDB_LIBS="-L../lmdb -lbareoslmdb" LMDB_DEPS="../lmdb/libbareoslmdb\$(DEFAULT_ARCHIVE_TYPE)" else LMDB_DIR="" LMDB_LIBS="" LMDB_DEPS="" fi AC_SUBST(LMDB_DIR) AC_SUBST(LMDB_LIBS) AC_SUBST(LMDB_DEPS) dnl ------------------------------------------- dnl enable batch attribute DB insert (default on) dnl ------------------------------------------- support_batch_insert=yes AC_ARG_ENABLE(batch-insert, AC_HELP_STRING([--enable-batch-insert], [enable the DB batch insert code @<:@default=yes@:>@]), [ if test x$enableval = xno; then support_batch_insert=no fi ] ) if test x$support_batch_insert = xyes; then AC_DEFINE(USE_BATCH_FILE_INSERT, 1, [Define to 1 if DB batch insert code enabled]) fi dnl -------------------------------------------------- dnl dynamic loading of catalog backends dnl -------------------------------------------------- use_dynamic_cats_backends=no AC_ARG_ENABLE(dynamic-cats-backends, AC_HELP_STRING([--enable-dynamic-cats-backends], [enable dynamic loading of catalog backends @<:@default=no@:>@]), [ if test x$enableval = xyes; then use_dynamic_cats_backends=yes AC_DEFINE(HAVE_DYNAMIC_CATS_BACKENDS, 1, [Define to 1 if dynamic loading of catalog backends is enabled]) fi ] ) if test "x$use_libtool" != "xyes" -a "x$use_dynamic_cats_backends" = "xyes"; then echo "" echo "You specified --enable-dynamic-cats-plugins but disabled libtool with --disable-libtool" echo "We only support dynamic loading using libtool so either disable dynamic loading or enable libtool" echo "" echo "Aborting the configuration ..." echo " " echo " " exit 1 fi dnl -------------------------------------------------- dnl sql pooling support dnl -------------------------------------------------- use_sql_pooling=no AC_ARG_ENABLE(sql-pooling, AC_HELP_STRING([--enable-sql-pooling], [enable sql pooling support @<:@default=no@:>@]), [ if test x$enableval = xyes; then use_sql_pooling=yes AC_DEFINE(HAVE_SQL_POOLING, 1, [Define to 1 if sql pooling is enabled]) fi ] ) dnl ------------------------------------------------ dnl Bareos check for various SQL database engines dnl ------------------------------------------------ dnl dnl Set uncomment_dbi by default to '#' if DBI is enabled this will get reset dnl uncomment_dbi="#" BA_CHECK_POSTGRESQL_DB BA_CHECK_MYSQL_DB BA_CHECK_SQLITE3_DB #BA_CHECK_INGRES_DB #BA_CHECK_DBI_DB #BA_CHECK_DBI_DRIVER dnl ------------------------------------------- dnl If no batch insert backend are enable set dnl variable to None dnl ------------------------------------------- if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="None" fi dnl ------------------------------------------- dnl Check to see if we are only building a client then we can skip dnl all of these checks as no backend is build anyhow. dnl ------------------------------------------- if test x$build_client_only != xyes; then dnl ------------------------------------------- dnl Make sure at least one database backend is found dnl ------------------------------------------- if test "x${db_backends}" = "x" ; then echo " " echo " " echo "You have not specified either --enable-client-only or one of the" echo "supported databases: MySQL, PostgreSQL, or SQLite3." echo "This is not permitted. Please reconfigure." echo " " echo "Aborting the configuration ..." echo " " echo " " exit 1 fi dnl ------------------------------------------- dnl See how many catalog backends are configured. dnl ------------------------------------------- case `echo $DB_BACKENDS | wc -w | sed -e 's/^ *//'` in 1) DEFAULT_DB_TYPE="${DB_BACKENDS}" if test x$use_libtool = xno; then SHARED_CATALOG_TARGETS="" else SHARED_CATALOG_TARGETS="libbareoscats-${DEFAULT_DB_TYPE}.la" fi ;; *) dnl ------------------------------------------------ dnl Set the default backend to the first backend found dnl ------------------------------------------------ DEFAULT_DB_TYPE=`echo ${DB_BACKENDS} | cut -d' ' -f1` dnl ------------------------------------------------ dnl For multiple backend we need libtool support. dnl ------------------------------------------------ if test x$use_libtool = xno; then echo " " echo " " echo "You have specified two or more of the" echo "supported databases: MySQL, PostgreSQL, or SQLite3." echo "This is not permitted when not using libtool Please reconfigure." echo " " echo "Aborting the configuration ..." echo " " echo " " exit 1 fi SHARED_CATALOG_TARGETS="" for db_type in ${DB_BACKENDS} do if test -z "${SHARED_CATALOG_TARGETS}"; then SHARED_CATALOG_TARGETS="libbareoscats-${db_type}.la" else SHARED_CATALOG_TARGETS="${SHARED_CATALOG_TARGETS} libbareoscats-${db_type}.la" fi done ;; esac fi dnl ------------------------------------------- dnl When we are using dynamic catalog backends dnl disable the install of a default catalog backend dnl ------------------------------------------- if test x$use_dynamic_cats_backends = xyes; then LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET="" else LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET="libtool-install-default-backend" fi dnl ------------------------------------------- dnl Unset DB_LIBS when using libtool as we link the dnl shared library using the right database lib no need to dnl set DB_LIBS which is only used for non shared versions dnl of the backends. dnl ------------------------------------------- if test x$use_libtool = xyes; then DB_LIBS="" fi AC_SUBST(uncomment_dbi) AC_SUBST(DB_BACKENDS) AC_SUBST(DB_LIBS) AC_SUBST(DEFAULT_DB_TYPE) AC_SUBST(LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET) AC_SUBST(SHARED_CATALOG_TARGETS) AC_DEFINE(PROTOTYPES, 1, [Define if you need function prototypes]) dnl -------------------------------------------------------------------------- dnl Supply default CFLAGS, if not specified by `CFLAGS=flags ./configure' dnl if test -z "$CFLAGS" -o "$CFLAGS" = "-g -O2"; then if test -z "$CCOPTS"; then CCOPTS='-g -O2 -Wall' fi CFLAGS="$CCOPTS" fi dnl A few others AC_EXEEXT dnl See if we can use 64 bit file addresses largefile_support="no" AC_BRS_LARGEFILE AC_PATH_XTRA dnl -------------------------------------------------------------------------- dnl CHECKING FOR HEADER FILES dnl -------------------------------------------------------------------------- AC_CHECK_HEADERS( \ assert.h \ dl.h \ dlfcn.h \ fcntl.h \ grp.h \ pwd.h \ libc.h \ limits.h \ stdarg.h \ stdlib.h \ stdint.h \ inttypes.h \ string.h \ strings.h \ termios.h \ termcap.h \ term.h \ unistd.h \ sys/bitypes.h \ sys/byteorder.h \ sys/ioctl.h \ sys/select.h \ sys/socket.h \ sys/sockio.h \ sys/stat.h \ sys/time.h \ sys/types.h \ arpa/nameser.h \ mtio.h \ sys/dl.h \ sys/mtio.h \ sys/tape.h \ regex.h \ ) AC_HEADER_STDC AC_HEADER_MAJOR AC_HEADER_DIRENT AC_HEADER_STAT AC_HEADER_SYS_WAIT AC_HEADER_TIME AC_STRUCT_ST_BLKSIZE AC_STRUCT_ST_BLOCKS AC_STRUCT_TIMEZONE dnl -------------------------------------------------------------------------- dnl Check for utime.h structure dnl -------------------------------------------------------------------------- AC_CACHE_CHECK(for utime.h, ba_cv_header_utime_h, [ AC_TRY_COMPILE( [ #include #include ], [ struct utimbuf foo ], [ ba_cv_header_utime_h=yes ], [ ba_cv_header_utime_h=no ] ) ] ) test $ba_cv_header_utime_h = yes && AC_DEFINE(HAVE_UTIME_H, 1, [Define to 1 if you have the header file.]) dnl -------------------------------------------------------------------------- dnl Check for socklen_t dnl -------------------------------------------------------------------------- AC_CACHE_CHECK(for socklen_t, ba_cv_header_socklen_t, [ AC_TRY_COMPILE( [ #include #include ], [ socklen_t x ], [ ba_cv_header_socklen_t=yes ], [ ba_cv_header_socklen_t=no ] ) ] ) test $ba_cv_header_socklen_t = yes && AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define to 1 if socklen_t exists]) dnl -------------------------------------------------------------------------- dnl Check for ioctl request type dnl -------------------------------------------------------------------------- AC_LANG(C++) AC_CACHE_CHECK(for ioctl_req_t, ba_cv_header_ioctl_req_t, [ AC_TRY_COMPILE( [ #include #include #include ], [ int (*d_ioctl)(int fd, unsigned long int request, ...); d_ioctl = ::ioctl; ], [ ba_cv_header_ioctl_req_t=yes ], [ ba_cv_header_ioctl_req_t=no ] ) ] ) test $ba_cv_header_ioctl_req_t = yes && AC_DEFINE(HAVE_IOCTL_ULINT_REQUEST, 1, [Define to 1 if ioctl request is unsigned long int]) dnl Note: it is more correct to use AC_LANG(C++) but some of the older dnl *BSD systems still use old style C prototypes, which are wrong with dnl compiled with a C++ compiler. AC_LANG(C) dnl -------------------------------------------------------------------------- dnl Check for typeof() dnl -------------------------------------------------------------------------- AC_LANG_PUSH(C++) AC_CACHE_CHECK(for typeof, ba_cv_have_typeof, [ AC_TRY_RUN( [ main(){char *a = 0; a = (typeof a)a;} ], [ ba_cv_have_typeof=yes ], [ ba_cv_have_typeof=no ], [ ba_cv_have_typeof=no ] ) ] ) test $ba_cv_have_typeof = yes && AC_DEFINE([HAVE_TYPEOF], 1, [Define to 1 if compiler has typeof]) AC_LANG_POP(C++) AC_C_CONST AC_C_BIGENDIAN([AC_DEFINE(HAVE_BIG_ENDIAN, 1, [Big Endian])], [AC_DEFINE(HAVE_LITTLE_ENDIAN, 1, [Little Endian])]) dnl -------------------------------------------------------------------------- dnl CHECKING FOR FILESYSTEM TYPE dnl -------------------------------------------------------------------------- AC_MSG_CHECKING(how to get filesystem type) fstype=no # The order of these tests is important. AC_TRY_CPP( [ #include #include ], AC_DEFINE(FSTYPE_STATVFS, 1, [Define to 1 if you have SVR4 statvfs to get filesystem type]) fstype=SVR4 ) if test $fstype = no; then AC_TRY_CPP( [ #include #include ], AC_DEFINE(FSTYPE_USG_STATFS, 1, [Define to 1 if you have SVR3.2 statfs to get filesystem type]) fstype=SVR3 ) fi if test $fstype = no; then AC_TRY_CPP( [ #include #include ], AC_DEFINE(FSTYPE_AIX_STATFS, 1, [Define to 1 if you have AIX3 statfs to get filesystem type]) fstype=AIX ) fi if test $fstype = no; then AC_TRY_CPP( [ #include ], AC_DEFINE(FSTYPE_MNTENT, 1, [Define to 1 if you have 4.3BSD getmntent to get filesystem type]) fstype=4.3BSD ) fi if test $fstype = no; then AC_EGREP_HEADER(f_type;, sys/mount.h, AC_DEFINE(FSTYPE_STATFS, 1, [Define to 1 if you have 4.4BSD and OSF1 statfs to get filesystem type]) fstype=4.4BSD/OSF1) fi if test $fstype = no; then AC_TRY_CPP( [ #include #include ], AC_DEFINE(FSTYPE_GETMNT, 1, [Define to 1 if you have Ultrix getmnt to get filesystem type]) fstype=Ultrix ) fi AC_MSG_RESULT($fstype) AC_CHECK_HEADER(sys/statvfs.h, [AC_DEFINE(HAVE_SYS_STATVFS_H, 1, [Define to 1 if you have the header file.])] , ) dnl -------------------------------------------------------------------------- dnl CHECKING FOR TYPEDEFS, STRUCTURES, AND COMPILER CHARACTERISTICS. dnl -------------------------------------------------------------------------- AC_TYPE_SIGNAL SIGNAL_CHECK AC_TYPE_MODE_T AC_TYPE_UID_T AC_TYPE_SIZE_T AC_TYPE_PID_T AC_TYPE_OFF_T AC_TYPE_INTPTR_T AC_TYPE_UINTPTR_T AC_CHECK_TYPE(ino_t, unsigned long) AC_CHECK_TYPE(dev_t, unsigned long) AC_CHECK_TYPE(daddr_t, long) AC_CHECK_TYPE(major_t, int) AC_CHECK_TYPE(minor_t, int) AC_CHECK_TYPE(ssize_t, int) AC_STRUCT_ST_BLOCKS AC_STRUCT_ST_RDEV AC_STRUCT_TM AC_C_CONST AC_CHECK_SIZEOF(char, 1) AC_CHECK_SIZEOF(short int, 2) AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(long int, 4) AC_CHECK_SIZEOF(long long int, 8) AC_CHECK_SIZEOF(int *, 4) dnl Check for sys/types.h types AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [ AC_TRY_COMPILE( [ #include ], [ u_int a; a = 1; ], [ ac_cv_have_u_int="yes" ], [ ac_cv_have_u_int="no" ] ) ] ) if test "x$ac_cv_have_u_int" = "xyes" ; then AC_DEFINE(HAVE_U_INT, 1, [Define to 1 if you have u_int]) have_u_int=1 fi AC_CACHE_CHECK([for intmax_t type], ac_cv_have_intmax_t, [ AC_TRY_COMPILE( [ #include ], [ intmax_t a; a = 1; ], [ ac_cv_have_intmax_t="yes" ], [ AC_TRY_COMPILE( [ #include ], [ intmax_t a; a = 1; ], [ ac_cv_have_intmax_t="yes" ], [ ac_cv_have_intmax_t="no" ] ) ] ) ] ) if test "x$ac_cv_have_intmax_t" = "xyes" ; then AC_DEFINE(HAVE_INTMAX_T, 1, [Define to 1 if you have intmax_t]) have_intmax_t=1 fi AC_CACHE_CHECK([for u_intmax_t type], ac_cv_have_u_intmax_t, [ AC_TRY_COMPILE( [ #include ], [ u_intmax_t a; a = 1; ], [ ac_cv_have_u_intmax_t="yes" ], [ AC_TRY_COMPILE( [ #include ], [ u_intmax_t a; a = 1; ], [ ac_cv_have_u_intmax_t="yes" ], [ ac_cv_have_u_intmax_t="no" ] ) ] ) ] ) if test "x$ac_cv_have_u_intmax_t" = "xyes" ; then AC_DEFINE(HAVE_U_INTMAX_T, 1, [Define to 1 if you have u_intmax_t]) have_u_intmax_t=1 fi AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ AC_TRY_COMPILE( [ #include ], [ int8_t a; int16_t b; int32_t c; a = b = c = 1; ], [ ac_cv_have_intxx_t="yes" ], [ ac_cv_have_intxx_t="no" ] ) ] ) if test "x$ac_cv_have_intxx_t" = "xyes" ; then AC_DEFINE(HAVE_INTXX_T, 1, [Define to 1 if you have intxx_t]) have_intxx_t=1 fi AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ AC_TRY_COMPILE( [ #include ], [ int64_t a; a = 1; ], [ ac_cv_have_int64_t="yes" ], [ ac_cv_have_int64_t="no" ] ) ] ) if test "x$ac_cv_have_int64_t" = "xyes" ; then AC_DEFINE(HAVE_INT64_T, 1, [Define to 1 if you have int64_t]) have_int64_t=1 fi AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ AC_TRY_COMPILE( [ #include ], [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; ], [ ac_cv_have_u_intxx_t="yes" ], [ ac_cv_have_u_intxx_t="no" ] ) ] ) if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then AC_DEFINE(HAVE_U_INTXX_T, 1, [Define to 1 if you have u_intxx_t]) have_u_intxx_t=1 fi AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [ AC_TRY_COMPILE( [ #include ], [ u_int64_t a; a = 1; ], [ ac_cv_have_u_int64_t="yes" ], [ ac_cv_have_u_int64_t="no" ] ) ] ) if test "x$ac_cv_have_u_int64_t" = "xyes" ; then AC_DEFINE(HAVE_U_INT64_T, 1, [Define to 1 if you have u_int64_t]) have_u_int64_t=1 fi if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h]) AC_TRY_COMPILE( [ #include ], [ int8_t a; int16_t b; int32_t c; u_int8_t e; u_int16_t f; u_int32_t g; a = b = c = e = f = g = 1; ], [ AC_DEFINE(HAVE_U_INTXX_T, 1, [Define to 1 if you have u_intxx_t]) AC_DEFINE(HAVE_INTXX_T, 1, [Define to 1 if you have intxx_t]) AC_DEFINE(HAVE_SYS_BITYPES_H, 1, [Define to 1 if you have the header file.]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) ] ) fi if test -z "$have_u_intxx_t" ; then AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [ AC_TRY_COMPILE( [ #include ], [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], [ ac_cv_have_uintxx_t="yes" ], [ ac_cv_have_uintxx_t="no" ] ) ] ) if test "x$ac_cv_have_uintxx_t" = "xyes" ; then AC_DEFINE(HAVE_UINTXX_T, 1, [Define to 1 if you have uintxx_t]) fi fi if (test -z "$have_u_int64_t" || test -z "$have_int64_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then AC_MSG_CHECKING([for int64_t and u_int64_t types in sys/bitypes.h]) AC_TRY_COMPILE( [ #include ], [ int64_t a; u_int64_t b; a = b = 1; ], [ AC_DEFINE(HAVE_U_INT64_T, 1, [Define to 1 if you have u_int64_t]) AC_DEFINE(HAVE_INT64_T, 1, [Define to 1 if you have int64_t]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) ] ) fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then AC_MSG_CHECKING([for uintXX_t types in sys/bitypes.h]) AC_TRY_COMPILE( [ #include ], [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], [ AC_DEFINE(HAVE_UINTXX_T, 1, [Define to 1 if you have uintxx_t]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) ] ) fi dnl -------------------------------------------------------------------------- dnl CHECKING FOR REQUIRED LIBRARY FUNCTIONS dnl -------------------------------------------------------------------------- AC_CHECK_FUNCS( \ fork \ getcwd \ gethostname \ getpid \ gettimeofday \ setpgid \ setpgrp \ setsid \ signal \ strerror \ strncmp \ strncpy \ vfprintf \ ,, [echo 'configure: cannot find needed function.'; exit 1] ) AC_CHECK_DECL( F_CLOSEM, AC_DEFINE(HAVE_FCNTL_F_CLOSEM, 1, [Define to 1 if you have the fcntl F_CLOSEM flag]), , [#include ] ) AC_CHECK_FUNC(bcopy, [AC_DEFINE(HAVE_BCOPY, 1, [Define to 1 if you have the `bcopy' function.])]) AC_CHECK_FUNC(closefrom, [AC_DEFINE(HAVE_CLOSEFROM, 1, [Define to 1 if you have the `closefrom' function.])]) AC_CHECK_FUNC(getpagesize, [AC_DEFINE(HAVE_GETPAGESIZE, 1, [Define to 1 if you have the `getpagesize' function.])]) AC_CHECK_FUNC(malloc_trim, [AC_DEFINE(HAVE_MALLOC_TRIM, 1, [Define to 1 if you have the `malloc_trim' function.])]) dnl -------------------------------------------------------------------------- dnl On Solaris check for availability of libumem a very suitable memory dnl allocator for multithreaded programs (e.g. Bareos) dnl -------------------------------------------------------------------------- if test x${HAVE_SUN_OS_TRUE} = x; then AC_CHECK_HEADER(umem.h, [AC_DEFINE(HAVE_UMEM_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_LIB(umem, malloc, [ LIBS="-lumem $LIBS" ] ) fi dnl -------------------------------------------------------------------------- dnl Checking for backtrace dump support dnl -------------------------------------------------------------------------- AC_CHECK_FUNC(backtrace_symbols, [AC_DEFINE(HAVE_BACKTRACE_SYMBOLS, 1, [Define to 1 if you have the `backtrace_symbols' function.])] , ) AC_CHECK_FUNC(backtrace, [AC_DEFINE(HAVE_BACKTRACE, 1, [Define to 1 if you have the `backtrace' function.])] , ) AC_CHECK_HEADER(execinfo.h, [AC_DEFINE(HAVE_EXECINFO_H, 1, [Define to 1 if you have the header file.])] , ) dnl -------------------------------------------------------------------------- dnl Check explicit using C++ the cxxabi.h header which doesn't get detected dnl otherwise. dnl -------------------------------------------------------------------------- AC_LANG_PUSH(C++) AC_CHECK_HEADER(cxxabi.h, [AC_DEFINE(HAVE_CXXABI_H, 1, [Define to 1 if you have the header file.])] , ) AC_LANG_POP(C++) dnl -------------------------------------------------------------------------- dnl Specific tests for Solaris dnl -------------------------------------------------------------------------- if test x${HAVE_SUN_OS_TRUE} = x; then AC_CHECK_FUNC(addrtosymstr, [AC_DEFINE(HAVE_ADDRTOSYMSTR, 1, [Set if addrtosymstr exists])] , ) AC_CHECK_HEADER(ucontext.h, [AC_DEFINE(HAVE_UCONTEXT_H, 1, [Define to 1 if you have the header file.])] , ) if test X"$GCC" != "Xyes" ; then AC_CHECK_HEADER(demangle.h, [AC_DEFINE(HAVE_DEMANGLE_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_LIB(demangle, cplus_demangle, [ AC_DEFINE(HAVE_CPLUS_DEMANGLE, 1, [Define to 1 if cplus_demangle exists in libdemangle]) LIBS="-ldemangle $LIBS" ] ) fi fi AC_CHECK_FUNC(fchdir, [AC_DEFINE(HAVE_FCHDIR, 1, [Define to 1 if you have the `fchdir' function.])]) AC_CHECK_FUNC(strtoll, [AC_DEFINE(HAVE_STRTOLL, 1, [Define to 1 if you have the `strtoll' function.])]) AC_CHECK_FUNC(posix_fadvise, [AC_DEFINE(HAVE_POSIX_FADVISE, 1, [Define to 1 if you have the `posix_fadvise' function.])]) AC_CHECK_FUNC(fdatasync, [AC_DEFINE(HAVE_FDATASYNC, 1, [Define to 1 if you have the `fdatasync' function.])]) AC_CHECK_FUNC(chflags, [AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the `chflags' function.])]) AC_CHECK_FUNCS(snprintf vsnprintf gethostid fseeko) AC_CACHE_CHECK(for va_copy, ba_cv_va_copy, [ AC_TRY_LINK( [ #include void use_va_copy(va_list args){va_list args2; va_copy(args2,args); va_end(args2);} void call_use_va_copy(int junk,...){va_list args; va_start(args,junk); use_va_copy(args); va_end(args);} ], [ call_use_va_copy(1,2,3) ], [ ba_cv_va_copy=yes ], [ ba_cv_va_copy=no ] ) ] ) test $ba_cv_va_copy = yes && AC_DEFINE(HAVE_VA_COPY, 1, [Set if va_copy exists]) dnl -------------------------------------------------------------------------- dnl CHECKING FOR THREAD SAFE FUNCTIONS dnl -------------------------------------------------------------------------- AC_CHECK_FUNCS(localtime_r readdir_r strerror_r) dnl -------------------------------------------------------------------------- dnl If resolver functions are not in libc check for -lnsl or -lresolv. dnl -------------------------------------------------------------------------- AC_CHECK_FUNC(gethostbyname_r, [ AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, [Define to 1 if you have the `gethostbyname_r' function.]) AC_MSG_RESULT(using gethostbyname_r from resolver in libc) ], [ AC_CHECK_LIB(nsl, gethostbyname_r, [ AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, [Define to 1 if you have the `gethostbyname_r' function.]) LIBS="-lnsl $LIBS" SOCKLIBS="-lnsl $LIBS" ], [ AC_CHECK_LIB(resolv, gethostbyname_r, [ AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, [Define to 1 if you have the `gethostbyname_r' function.]) LIBS="-lresolv $LIBS" SOCKLIBS="-lresolv $LIBS" ] ) ] ) ] ) AC_CHECK_FUNC(inet_pton, [AC_DEFINE(HAVE_INET_PTON, 1, [Define to 1 if you have the `inet_pton' function.])]) AC_CHECK_FUNC(inet_ntop, [AC_DEFINE(HAVE_INET_NTOP, 1, [Define to 1 if you have the `inet_ntop' function.])]) AC_CHECK_FUNC(gethostbyname2, [AC_DEFINE(HAVE_GETHOSTBYNAME2, 1, [Define to 1 if you have the `gethostbyname2' function.])]) dnl ---------------------------- dnl check sa_len of sockaddr dnl ---------------------------- AC_CACHE_CHECK(for struct sockaddr has a sa_len field, ac_cv_struct_sockaddr_sa_len, [ AC_TRY_COMPILE( [ #include ], [ struct sockaddr s; s.sa_len; ], [ ac_cv_struct_sockaddr_sa_len=yes ], [ac_cv_struct_sockaddr_sa_len=no ] ) ] ) if test $ac_cv_struct_sockaddr_sa_len = yes; then AC_DEFINE(HAVE_SA_LEN, 1, [Define to 1 if sa_len field exists in struct sockaddr]) fi dnl dnl check for working getaddrinfo() dnl dnl Note that if the system doesn't have gai_strerror(), we dnl can't use getaddrinfo() because we can't get strings dnl describing the error codes. dnl AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo, [ AC_TRY_RUN( [ #include #include #include #include void main(void) { struct addrinfo hints, *ai; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo("127.0.0.1", NULL, &hints, &ai); if (error) { exit(1); } if (ai->ai_addr->sa_family != AF_INET) { exit(1); } exit(0); } ],[ ac_cv_working_getaddrinfo="yes" ],[ ac_cv_working_getaddrinfo="no" ],[ ac_cv_working_getaddrinfo="yes" ] ) ] ) AC_CHECK_FUNC(gai_strerror, [AC_DEFINE(HAVE_GAI_STRERROR, 1, [Define to 1 if you have the `gai_strerror' function.])]) if test "$ac_cv_working_getaddrinfo" = "yes"; then if test "$ac_cv_func_gai_strerror" != "yes"; then ac_cv_working_getaddrinfo="no" else AC_DEFINE(HAVE_GETADDRINFO, 1, [Define to 1 if you have the `getaddrinfo' function.]) fi fi AC_FUNC_STRFTIME AC_FUNC_VPRINTF AC_FUNC_ALLOCA AC_FUNC_GETMNTENT AC_CHECK_FUNC(getmntinfo, [AC_DEFINE(HAVE_GETMNTINFO, 1, [Define to 1 if you have the `getmntinfo' function.])]) AC_FUNC_CLOSEDIR_VOID AC_FUNC_SETPGRP dnl check for BSD setpgrp. # AC_FUNC_FNMATCH dnl use local version AC_CHECK_LIB(intl, gettext, [LIBS="$LIBS -lintl"]) AC_CHECK_LIB(sun, getpwnam) dnl dnl Check for zlib dnl ZLIB_LIBS="-lz" ZLIB_INC="" have_zlib=no AC_ARG_WITH(zlib, AC_HELP_STRING([--with-zlib@<:@=DIR@:>@], [Directory holding zlib includes/libs]), with_zlib_directory=${withval} ) if test "x${with_zlib_directory}" != "xyes" && test x"${with_zlib_directory}" != "x"; then # # Make sure the $with_zlib_directory also makes sense # if test -d "${with_zlib_directory}/lib" -a -d "${with_zlib_directory}/include"; then ZLIB_LIBS="-L${with_zlib_directory}/lib ${ZLIB_LIBS}" ZLIB_INC="-I${with_zlib_directory}/include ${ZLIB_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${ZLIB_LIBS}" CFLAGS="${saved_CFLAGS} ${ZLIB_INC}" CPPFLAGS="${saved_CPPFLAGS} ${ZLIB_INC}" AC_CHECK_HEADERS(zlib.h) AC_MSG_CHECKING(for compressBound in zlib library) AC_TRY_LINK( [ #include ], [ compressBound(0); ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_COMPRESS_BOUND, 1, [Define to 1 if you have compressBound]) ], [ AC_MSG_RESULT(no) ] ) AC_MSG_CHECKING(for deflate in zlib library) AC_TRY_LINK( [ #include ], [ deflate(Z_NULL, 0); ], [ AC_MSG_RESULT(yes) have_zlib="yes" ], [ AC_MSG_RESULT(no) have_zlib="no" ] ) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_zlib}" = "xyes"; then AC_DEFINE(HAVE_LIBZ, 1, [Define to 1 if you have zlib]) else ZLIB_LIBS="" ZLIB_INC="" fi if test x$use_libtool != xno; then ZLIB_LIBS_NONSHARED="" else ZLIB_LIBS_NONSHARED="${ZLIB_LIBS}" fi AC_SUBST(ZLIB_INC) AC_SUBST(ZLIB_LIBS) AC_SUBST(ZLIB_LIBS_NONSHARED) dnl dnl Check for lzo dnl LZO_LIBS="-llzo2" LZO_INC="" have_lzo=no AC_ARG_WITH(lzo, AC_HELP_STRING([--with-lzo@<:@=DIR@:>@], [Directory holding lzo includes/libs]), with_lzo_directory=${withval} ) if test "x${with_lzo_directory}" != "xyes" && test x"${with_lzo_directory}" != "x"; then # # Make sure the $with_lzo_directory also makes sense # if test -d "${with_lzo_directory}/lib" -a -d "${with_lzo_directory}/include"; then LZO_LIBS="-L${with_lzo_directory}/lib ${LZO_LIBS}" LZO_INC="-I${with_lzo_directory}/include ${LZO_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${LZO_LIBS}" CFLAGS="${saved_CFLAGS} ${LZO_INC}" CPPFLAGS="${saved_CPPFLAGS} ${LZO_INC}" AC_CHECK_HEADERS(lzo/lzoconf.h) AC_CHECK_HEADERS(lzo/lzo1x.h) AC_MSG_CHECKING(for lzo1x_1_compress in lzo library) AC_TRY_LINK( [ #include #include ], [ lzo1x_1_compress(NULL, 0, NULL, NULL, NULL); ], [ AC_MSG_RESULT(yes) have_lzo="yes" ], [ AC_MSG_RESULT(no) have_lzo="no" ] ) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_lzo}" = "xyes"; then AC_DEFINE(HAVE_LZO, 1, [Define to 1 if you have lzo lib]) else LZO_LIBS="" LZO_INC="" fi if test x$use_libtool != xno; then LZO_LIBS_NONSHARED="" else LZO_LIBS_NONSHARED="${LZO_LIBS}" fi AC_SUBST(LZO_INC) AC_SUBST(LZO_LIBS) AC_SUBST(LZO_LIBS_NONSHARED) dnl dnl Check for fastlz dnl FASTLZ_LIBS="-lfastlz" FASTLZ_INC="" have_fastlz=no AC_ARG_WITH(fastlz, AC_HELP_STRING([--with-fastlz@<:@=DIR@:>@], [Directory holding fastlz includes/libs]), with_fastlz_directory=${withval} ) if test "x${with_fastlz_directory}" != "xyes" && test x"${with_fastlz_directory}" != "x"; then # # Make sure the $with_fastlz_directory also makes sense # if test -d "${with_fastlz_directory}/lib" -a -d "${with_fastlz_directory}/include"; then FASTLZ_LIBS="-L${with_fastlz_directory}/lib ${FASTLZ_LIBS}" FASTLZ_INC="-I${with_fastlz_directory}/include ${FASTLZ_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${FASTLZ_LIBS}" CFLAGS="${saved_CFLAGS} ${FASTLZ_INC}" CPPFLAGS="${saved_CPPFLAGS} ${FASTLZ_INC}" AC_CHECK_HEADERS(fastlzlib.h) AC_MSG_CHECKING(for fastlzlibCompress in fastlz library) AC_TRY_LINK( [ #include ], [ fastlzlibCompress(Z_NULL, 0); ], [ AC_MSG_RESULT(yes) have_fastlz="yes" ], [ AC_MSG_RESULT(no) have_fastlz="no" ] ) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_fastlz}" = "xyes"; then AC_DEFINE(HAVE_FASTLZ, 1, [Define to 1 if you have fastlz lib]) else FASTLZ_LIBS="" FASTLZ_INC="" fi if test x$use_libtool != xno; then FASTLZ_LIBS_NONSHARED="" else FASTLZ_LIBS_NONSHARED="${FASTLZ_LIBS}" fi AC_SUBST(FASTLZ_INC) AC_SUBST(FASTLZ_LIBS) AC_SUBST(FASTLZ_LIBS_NONSHARED) dnl dnl Check if we have AFS on this system dnl AFS_CFLAGS="" AFS_LIBS="" support_afs=auto AC_ARG_ENABLE(afs, AC_HELP_STRING([--disable-afs], [disable afs support @<:@default=auto@:>@]), [ if test x$enableval = xyes; then support_afs=yes elif test x$enableval = xno; then support_afs=no fi ] ) have_afs=no if test x$support_afs = xyes -o x$support_afs = xauto; then AC_ARG_WITH(afsdir, AC_HELP_STRING([--with-afsdir@<:@=DIR@:>@], [Directory holding AFS includes/libs]), with_afsdir=$withval ) dnl dnl Search in standard places, or --with-afsdir not specified dnl if test x$with_afsdir = x; then for root in /usr /usr/local; do if test -d ${root}/include/afs/ ; then with_afsdir=${root} break fi if test -d ${root}/include/openafs/afs/ ; then with_afsdir=${root} break fi done fi if test -d ${with_afsdir}/include/afs/ ; then AFS_CFLAGS="-I${with_afsdir}/include" else if test -d ${with_afsdir}/include/openafs/afs/ ; then AFS_CFLAGS="-I${with_afsdir}/include/openafs" fi fi saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" CFLAGS="${AFS_CFLAGS} ${saved_CFLAGS}" CPPFLAGS="${AFS_CFLAGS} ${saved_CPPFLAGS}" AC_CHECK_HEADERS(afs/afsint.h) AC_TRY_CPP( [ #include #include ], AC_DEFINE(HAVE_AFS_VENUS_H,1,[Define to 1 if you have the header file.]) ) CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" dnl dnl See if we can find a libsys with the pioctl symbol in there dnl AC_MSG_CHECKING(for pioctl in AFS libsys) for dir in ${with_afsdir}/lib \ ${with_afsdir}/lib/afs \ ${with_afsdir}/lib/openafs \ ${with_afsdir}/lib64 \ ${with_afsdir}/lib64/afs \ ${with_afsdir}/lib64/openafs do for arch_type in .a .so do A=`test -f ${dir}/libsys${arch_type} && nm ${dir}/libsys${arch_type} 2>/dev/null | grep pioctl` pkg=$? if test $pkg = 0; then have_afs=yes AFS_LIBS="-L${dir} -lsys -lrx -llwp" break fi done done if test $have_afs = yes; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi if test x$support_afs = xyes -a $have_afs != yes; then AC_MSG_ERROR([afs support explicitly enabled but no supported afs implementation found, please either load the afs libraries or rerun configure without --enable-afs]) else if test $have_afs = yes; then AC_DEFINE(HAVE_AFS,1,[Define to 1 if your system has AFS support]) AC_DEFINE(HAVE_AFS_ACL,1,[Andrew FileSystem ACL support]) fi fi fi if test x$use_libtool != xno; then AFS_LIBS_NONSHARED="" else AFS_LIBS_NONSHARED="${AFS_LIBS}" fi AC_SUBST(AFS_CFLAGS) AC_SUBST(AFS_LIBS) AC_SUBST(AFS_LIBS_NONSHARED) dnl dnl Check for ACL support and libraries dnl ACL_LIBS="" support_acl=auto AC_ARG_ENABLE(acl, AC_HELP_STRING([--disable-acl], [disable acl support @<:@default=auto@:>@]), [ if test x$enableval = xyes; then support_acl=yes elif test x$enableval = xno; then support_acl=no fi ] ) have_acl=no have_extended_acl=no if test x$support_acl = xyes -o x$support_acl = xauto; then AC_CHECK_HEADER(sys/acl.h, [ AC_DEFINE(HAVE_SYS_ACL_H, 1, [Define to 1 if you have the header file.])] , ) dnl dnl First check for acl_get_file in libc dnl AC_CHECK_FUNC(acl_get_file, [ have_acl=yes ] ) dnl dnl Check for acl_get_file in libacl (Linux) dnl if test $have_acl = no; then AC_CHECK_LIB(acl, acl_get_file, [ have_acl=yes if test $have_afs = yes; then dnl dnl Because of possible naming conflict with AFS libacl make sure we use the one in /usr/lib64 or /usr/lib !!! dnl if test -d /usr/lib64/; then ACL_LIBS="-L/usr/lib64 -lacl $ACL_LIBS" else ACL_LIBS="-L/usr/lib -lacl $ACL_LIBS" fi else ACL_LIBS="-lacl $ACL_LIBS" fi ] ) fi dnl dnl Check for acl_get_file in libpacl (OSF1) dnl and if ACL_TYPE_DEFAULT_DIR is defined. dnl if test $have_acl = no -a \ x${HAVE_OSF1_OS_TRUE} = x; then AC_CHECK_LIB(pacl, acl_get_file, [ have_acl=yes ACL_LIBS="-lpacl $ACL_LIBS" ] ) AC_MSG_CHECKING(for ACL_TYPE_DEFAULT_DIR in acl.h include file) grep ACL_TYPE_DEFAULT_DIR /usr/include/sys/acl.h > /dev/null 2>&1 if test $? = 0; then AC_DEFINE(HAVE_ACL_TYPE_DEFAULT_DIR,1,[Defines if your system have the ACL_TYPE_DEFAULT_DIR acl type]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi dnl dnl On OSX check for availability of ACL_TYPE_EXTENDED dnl if test $have_acl = yes -a \ x${HAVE_DARWIN_OS_TRUE} = x; then AC_MSG_CHECKING(for ACL_TYPE_EXTENDED in acl.h include file) grep ACL_TYPE_EXTENDED /usr/include/sys/acl.h > /dev/null 2>&1 if test $? = 0; then AC_DEFINE(HAVE_ACL_TYPE_EXTENDED,1,[Defines if your system have the ACL_TYPE_EXTENDED acl type]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi dnl dnl On FreeBSD check for availability of ACL_TYPE_NFS4 dnl if test $have_acl = yes -a \ x${HAVE_FREEBSD_OS_TRUE} = x; then AC_MSG_CHECKING(for ACL_TYPE_NFS4 in acl.h include file) grep ACL_TYPE_NFS4 /usr/include/sys/acl.h > /dev/null 2>&1 if test $? = 0; then AC_DEFINE(HAVE_ACL_TYPE_NFS4,1,[Defines if your system have the ACL_TYPE_NFS4 acl type]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi dnl dnl Check for acltotext and acl_totext (Solaris) dnl if test $have_acl = no -a \ x${HAVE_SUN_OS_TRUE} = x; then AC_CHECK_LIB(sec, acltotext, [ have_acl=yes ACL_LIBS="-lsec $ACL_LIBS" AC_CHECK_LIB(sec, acl_totext, [ have_extended_acl=yes ] ) ] ) fi dnl dnl Check for acl_get and aclx_get (AIX) dnl if test $have_acl = no -a \ x${HAVE_AIX_OS_TRUE} = x; then AC_CHECK_FUNC(acl_get, [ have_acl=yes AC_CHECK_FUNC(aclx_get, [ have_extended_acl=yes ] ) ] ) fi if test x$support_acl = xyes -a $have_acl != yes; then AC_MSG_ERROR([acl support explicitly enabled but no supported acl implementation found, please either load the acl libraries or rerun configure without --enable-acl]) else if test $have_acl = yes; then AC_DEFINE([HAVE_ACL], 1, [Define to 1 if you want Normal acl support]) fi if test $have_extended_acl = yes; then AC_DEFINE([HAVE_EXTENDED_ACL], 1, [Define to 1 if you want Extended acl support]) fi fi fi if test x$use_libtool != xno; then ACL_LIBS_NONSHARED="" else ACL_LIBS_NONSHARED="${ACL_LIBS}" fi AC_SUBST(ACL_LIBS) AC_SUBST(ACL_LIBS_NONSHARED) dnl dnl Check for XATTR support dnl XATTR_LIBS="" support_xattr=auto AC_ARG_ENABLE(xattr, AC_HELP_STRING([--disable-xattr], [disable xattr support @<:@default=auto@:>@]), [ if test x$enableval = xyes; then support_xattr=yes elif test x$enableval = xno; then support_xattr=no fi ] ) have_xattr=no if test x$support_xattr = xyes -o x$support_xattr = xauto; then dnl dnl First check for *BSD support dnl When running on a BSD variant dnl if test x${HAVE_FREEBSD_OS_TRUE} = x -o \ x${HAVE_NETBSD_OS_TRUE} = x -o \ x${HAVE_OPENBSD_OS_TRUE} = x; then AC_CHECK_HEADER(sys/extattr.h, [AC_DEFINE(HAVE_SYS_EXTATTR_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_HEADER(libutil.h, [AC_DEFINE(HAVE_LIBUTIL_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_FUNCS(extattr_get_link extattr_set_link extattr_list_link, [ have_xattr=yes AC_DEFINE([HAVE_EXTATTR_GET_LINK], 1, [Define to 1 if you have the `extattr_get_link' function.]) AC_DEFINE([HAVE_EXTATTR_SET_LINK], 1, [Define to 1 if you have the `extattr_set_link' function.]) AC_DEFINE([HAVE_EXTATTR_LIST_LINK], 1, [Define to 1 if you have the `extattr_list_link' function.]) ] ) if test $have_xattr = no; then AC_CHECK_FUNCS(extattr_get_file extattr_set_file extattr_list_file, [ have_xattr=yes AC_DEFINE([HAVE_EXTATTR_GET_FILE], 1, [Define to 1 if you have the `extattr_get_file' function.]) AC_DEFINE([HAVE_EXTATTR_SET_FILE], 1, [Define to 1 if you have the `extattr_set_file' function.]) AC_DEFINE([HAVE_EXTATTR_LIST_FILE], 1, [Define to 1 if you have the `extattr_list_file' function.]) ] ) fi if test $have_xattr = yes; then have_extattr_string_in_libc=no AC_CHECK_FUNCS(extattr_namespace_to_string extattr_string_to_namespace, [ have_extattr_string_in_libc=yes AC_DEFINE([HAVE_EXTATTR_NAMESPACE_TO_STRING], 1, [Define to 1 if you have the `extattr_namespace_to_string' function.]) AC_DEFINE([HAVE_EXTATTR_STRING_TO_NAMESPACE], 1, [Define to 1 if you have the `extattr_string_to_namespace' function.]) ] ) dnl dnl If extattr_namespace_to_string and extattr_string_to_namespace are not in libc see if they are in libutil dnl if test $have_extattr_string_in_libc = no; then AC_CHECK_LIB(util, extattr_namespace_to_string extattr_string_to_namespace, [ AC_DEFINE([HAVE_EXTATTR_NAMESPACE_TO_STRING], 1, [Define to 1 if you have the `extattr_namespace_to_string' function.]) AC_DEFINE([HAVE_EXTATTR_STRING_TO_NAMESPACE], 1, [Define to 1 if you have the `extattr_string_to_namespace' function.]) XATTR_LIBS="-lutil $XATTR_LIBS" ] ) fi fi fi dnl dnl If we failed to find *BSD support try the AIX implementation of extented attributes (EA) dnl When running on AIX dnl if test $have_xattr = no -a \ x${HAVE_AIX_OS_TRUE} = x; then AC_CHECK_HEADER(sys/ea.h, [AC_DEFINE(HAVE_SYS_EA_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_FUNCS(llistea lgetea lsetea, [ have_xattr=yes AC_DEFINE([HAVE_LLISTEA], 1, [Define to 1 if you have the `llistea' function.]) AC_DEFINE([HAVE_LGETEA], 1, [Define to 1 if you have the `lgetea' function.]) AC_DEFINE([HAVE_LSETEA], 1, [Define to 1 if you have the `lsetea' function.]) ] ) if test $have_xattr = no; then AC_CHECK_FUNCS(listea getea setea, [ have_xattr=yes AC_DEFINE([HAVE_LISTEA], 1, [Define to 1 if you have the `listea' function.]) AC_DEFINE([HAVE_GETEA], 1, [Define to 1 if you have the `getea' function.]) AC_DEFINE([HAVE_SETEA], 1, [Define to 1 if you have the `setea' function.]) ] ) fi fi dnl dnl If we failed to find AIX support try the TRU64 implementation of extented attributes dnl when running on a TRU64 OS. dnl if test $have_xattr = no -a \ x${HAVE_OSF1_OS_TRUE} = x; then AC_CHECK_HEADER(sys/proplist.h, [AC_DEFINE(HAVE_SYS_PROPLIST_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_FUNCS(getproplist get_proplist_entry sizeof_proplist_entry add_proplist_entry setproplist, [ have_xattr=yes AC_DEFINE([HAVE_GETPROPLIST], 1, [Define to 1 if you have the `getproplist' function.]) AC_DEFINE([HAVE_GET_PROPLIST_ENTRY], 1, [Define to 1 if you have the `get_proplist_entry' function.]) AC_DEFINE([HAVE_SIZEOF_PROPLIST_ENTRY], 1, [Define to 1 if you have the `sizeof_proplist_entry' function.]) AC_DEFINE([HAVE_ADD_PROPLIST_ENTRY], 1, [Define to 1 if you have the `add_proplist_entry' function.]) AC_DEFINE([HAVE_SETPROPLIST], 1, [Define to 1 if you have the `setproplist' function.]) ] ) fi dnl dnl If we failed to find TRU64 support try the SOLARIS implementation of extented and extensible attributes dnl when running on a Solaris. dnl if test $have_xattr = no -a \ x${HAVE_SUN_OS_TRUE} = x; then AC_CHECK_HEADER(sys/attr.h, [AC_DEFINE(HAVE_SYS_ATTR_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_HEADER(sys/nvpair.h, [AC_DEFINE(HAVE_SYS_NVPAIR_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_HEADER(attr.h, [AC_DEFINE(HAVE_ATTR_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_FUNCS(openat fstatat unlinkat fchownat futimesat, [ have_xattr=yes AC_DEFINE([HAVE_OPENAT], 1, [Define to 1 if you have the `openat' function.]) AC_DEFINE([HAVE_FSTATAT], 1, [Define to 1 if you have the `fstatat' function.]) AC_DEFINE([HAVE_UNLINKAT], 1, [Define to 1 if you have the `unlinkat' function.]) AC_DEFINE([HAVE_FCHOWNAT], 1, [Define to 1 if you have the `fchownat' function.]) AC_DEFINE([HAVE_FUTIMESAT], 1, [Define to 1 if you have the `futimesat' function.]) ] ) if test $have_xattr = yes; then AC_CHECK_LIB(nvpair, nvlist_next_nvpair, [ AC_DEFINE([HAVE_NVLIST_NEXT_NVPAIR], 1, [Define to 1 if you have the `nvlist_next_nvpair' function.]) XATTR_LIBS="-lnvpair $XATTR_LIBS" ] ) fi fi dnl dnl If we failed to find Solaris support try the generic xattr support code dnl if test $have_xattr = no; then AC_CHECK_HEADER(sys/xattr.h, [AC_DEFINE(HAVE_SYS_XATTR_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_FUNCS(llistxattr lgetxattr lsetxattr, [ have_xattr=yes AC_DEFINE([HAVE_LLISTXATTR], 1, [Define to 1 if you have the `llistxattr' function.]) AC_DEFINE([HAVE_LGETXATTR], 1, [Define to 1 if you have the `lgetxattr' function.]) AC_DEFINE([HAVE_LSETXATTR], 1, [Define to 1 if you have the `lsetxattr' function.]) ] ) if test $have_xattr = no; then AC_CHECK_FUNCS(listxattr getxattr setxattr, [ have_xattr=yes AC_DEFINE([HAVE_LISTXATTR], 1, [Define to 1 if you have the `listxattr' function.]) AC_DEFINE([HAVE_GETXATTR], 1, [Define to 1 if you have the `getxattr' function.]) AC_DEFINE([HAVE_SETXATTR], 1, [Define to 1 if you have the `setxattr' function.]) ] ) fi fi if test x$support_xattr = xyes -a $have_xattr != yes; then AC_MSG_ERROR([xattr support explicitly enabled but no supported xattr implementation found, please either load the xattr libraries or rerun configure without --enable-xattr]) else if test $have_xattr = yes; then AC_DEFINE([HAVE_XATTR], 1, [Extended Attributes support]) fi fi fi if test x$use_libtool != xno; then XATTR_LIBS_NONSHARED="" else XATTR_LIBS_NONSHARED="${XATTR_LIBS}" fi AC_SUBST(XATTR_LIBS) AC_SUBST(XATTR_LIBS_NONSHARED) dnl dnl Check for SCSI Crypto support dnl support_scsi_crypto=no AC_ARG_ENABLE(scsi-crypto, AC_HELP_STRING([--enable-scsi-crypto], [enable low level SCSI crypto support @<:@default=no@:>@]), [ if test x$enableval = xyes; then support_scsi_crypto=yes fi ] ) CAM_LIBS="" have_scsi_crypto=no if test x$support_scsi_crypto = xyes; then if test x${HAVE_LINUX_OS_TRUE} = x; then AC_CHECK_HEADER(scsi/sg.h, [AC_DEFINE(HAVE_SCSI_SG_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_HEADER(scsi/scsi.h, [AC_DEFINE(HAVE_SCSI_SCSI_H, 1, [Define to 1 if you have the header file.])] , ) if test x$ac_cv_header_scsi_sg_h = xyes -a \ x$ac_cv_header_scsi_scsi_h = xyes; then have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_SUN_OS_TRUE} = x; then AC_CHECK_HEADER(sys/scsi/impl/uscsi.h, [AC_DEFINE(HAVE_SYS_SCSI_IMPL_USCSI_H, 1, [Define to 1 if you have the header file.])] , ) if test x$ac_cv_header_sys_scsi_impl_uscsi_h = xyes; then have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_FREEBSD_OS_TRUE} = x; then AC_CHECK_HEADER(camlib.h, [AC_DEFINE(HAVE_CAMLIB_H, 1, [Define to 1 if you have the header file.])] , ) AC_CHECK_HEADER(cam/scsi/scsi_message.h, [AC_DEFINE(HAVE_CAM_SCSI_SCSI_MESSAGE_H, 1, [Define to 1 if you have the header file.])] , ) if test x$ac_cv_header_camlib_h = xyes -a \ x$ac_cv_header_cam_scsi_scsi_message_h = xyes; then CAM_LIBS="-lcam" have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_NETBSD_OS_TRUE} = x; then AC_CHECK_HEADER(dev/scsipi/scsipi_all.h, [AC_DEFINE(HAVE_DEV_SCSIPI_SCSIPI_ALL_H, 1, [Define to 1 if you have the header file.])] , ) if test x$ac_cv_header_dev_scsipo_scsipo_all_h = xyes; then have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_OPENBSD_OS_TRUE} = x; then AC_CHECK_HEADER(scsi/uscsi_all.h, [AC_DEFINE(HAVE_USCSI_ALL_H, 1, [Define to 1 if you have the header file.])] , ) if test x$ac_cv_header_scsi_uscsi_all_h = xyes; then have_scsi_crypto=yes fi fi if test x$support_scsi_crypto = xyes -a $have_scsi_crypto != yes; then AC_MSG_ERROR([scsi crypto support explicitly enabled but no supported scsi crypto implementation found, please rerun configure without --enable-scsi-crypto]) else AC_DEFINE([HAVE_LOWLEVEL_SCSI_INTERFACE], 1, [Low level SCSI Interface support]) fi fi AC_SUBST(CAM_LIBS) dnl dnl Check for GlusterFS via gfapi. dnl GLUSTER_LIBS="-lgfapi" GLUSTER_INC="" have_glusterfs=no AC_ARG_WITH(glusterfs, AC_HELP_STRING([--with-glusterfs@<:@=DIR@:>@], [Directory holding GLUSTERFS includes/libs]), with_glusterfs_directory=$withval ) if test "x${with_glusterfs_directory}" != "xyes" && test x"${with_glusterfs_directory}" != "x"; then # # Make sure the $with_glusterfs_directory also makes sense # if test -d "${with_glusterfs_directory}/lib" -a -d "${with_glusterfs_directory}/include"; then GLUSTER_LIBS="-L${with_glusterfs_directory}/lib ${GLUSTER_LIBS}" GLUSTER_INC="-I${with_glusterfs_directory}/include ${GLUSTER_INC}" fi else GLUSTER_INC="-I/usr/include/glusterfs" fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${GLUSTER_LIBS}" CFLAGS="${saved_CFLAGS} ${GLUSTER_INC}" CPPFLAGS="${saved_CPPFLAGS} ${GLUSTER_INC}" AC_CHECK_HEADER(api/glfs.h) AC_MSG_CHECKING(for glfs_init in gfapi library) AC_TRY_LINK( [ #include ], [ glfs_new("volumename"); ], [ AC_MSG_RESULT(yes) have_glusterfs="yes" ], [ AC_MSG_RESULT(no) have_glusterfs="no" ] ) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_glusterfs}" = "xyes"; then AC_DEFINE(HAVE_GFAPI, 1, [Define to 1 if you have gfapi lib]) else GLUSTER_LIBS="" GLUSTER_INC="" fi AC_SUBST(GLUSTER_INC) AC_SUBST(GLUSTER_LIBS) dnl dnl Check for Object storage via libdroplet. dnl DROPLET_LIBS="-ldroplet" DROPLET_INC="" have_droplet=no AC_ARG_WITH(droplet, AC_HELP_STRING([--with-droplet@<:@=DIR@:>@], [Directory holding DROPLET includes/libs]), with_droplet_directory=$withval ) if test "x${with_droplet_directory}" != "xyes" && test x"${with_droplet_directory}" != "x"; then # # Make sure the $with_droplet_directory also makes sense # if test -d "${with_droplet_directory}/lib" -a -d "${with_droplet_directory}/include"; then DROPLET_LIBS="-L${with_droplet_directory}/lib ${DROPLET_LIBS}" DROPLET_INC="-I${with_droplet_directory}/include ${DROPLET_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${DROPLET_LIBS}" CFLAGS="${saved_CFLAGS} ${DROPLET_INC}" CPPFLAGS="${saved_CPPFLAGS} ${DROPLET_INC}" AC_CHECK_HEADER(droplet.h) AC_MSG_CHECKING(for dpl_ctx_new in libdroplet library) AC_TRY_LINK( [ #include ], [ dpl_ctx_new(NULL, NULL); ], [ AC_MSG_RESULT(yes) have_droplet="yes" ], [ AC_MSG_RESULT(no) have_droplet="no" ] ) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_droplet}" = "xyes"; then AC_DEFINE(HAVE_OBJECTSTORE, 1, [Define to 1 if you have libdroplet lib]) else DROPLET_LIBS="" DROPLET_INC="" fi AC_SUBST(DROPLET_INC) AC_SUBST(DROPLET_LIBS) dnl dnl Check for CEPH via librados. dnl RADOS_LIBS="-lrados" RADOS_INC="" have_ceph_rados=no AC_ARG_WITH(rados, AC_HELP_STRING([--with-rados@<:@=DIR@:>@], [Directory holding RADOS includes/libs]), with_rados_directory=$withval ) if test "x${with_rados_directory}" != "xyes" && test x"${with_rados_directory}" != "x"; then # # Make sure the $with_rados_directory also makes sense # if test -d "${with_rados_directory}/lib" -a -d "${with_rados_directory}/include"; then RADOS_LIBS="-L${with_rados_directory}/lib ${RADOS_LIBS}" RADOS_INC="-I${with_rados_directory}/include ${RADOS_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${RADOS_LIBS}" CFLAGS="${saved_CFLAGS} ${RADOS_INC}" CPPFLAGS="${saved_CPPFLAGS} ${RADOS_INC}" AC_CHECK_HEADER(rados/librados.h) AC_MSG_CHECKING(for rados_create in rados library) AC_TRY_LINK( [ #include ], [ rados_t cluster; rados_create(&cluster, NULL); ], [ AC_MSG_RESULT(yes) have_ceph_rados="yes" ], [ AC_MSG_RESULT(no) have_ceph_rados="no" ] ) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_ceph_rados}" = "xyes"; then AC_DEFINE(HAVE_RADOS, 1, [Define to 1 if you have rados lib]) else RADOS_LIBS="" RADOS_INC="" fi AC_SUBST(RADOS_INC) AC_SUBST(RADOS_LIBS) dnl dnl Check for CEPH via libcephfs. dnl CEPHFS_LIBS="-lcephfs" CEPHFS_INC="" have_cephfs=no AC_ARG_WITH(cephfs, AC_HELP_STRING([--with-cephfs@<:@=DIR@:>@], [Directory holding CEPHFS includes/libs]), with_cephfs_directory=$withval ) if test "x${with_cephfs_directory}" != "xyes" && test x"${with_cephfs_directory}" != "x"; then # # Make sure the $with_cephfs_directory also makes sense # if test -d "${with_cephfs_directory}/lib" -a -d "${with_cephfs_directory}/include"; then CEPHFS_LIBS="-L${with_cephfs_directory}/lib ${CEPHFS_LIBS}" CEPHFS_INC="-I${with_cephfs_directory}/include ${CEPHFS_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${CEPHFS_LIBS}" CFLAGS="${saved_CFLAGS} ${CEPHFS_INC}" CPPFLAGS="${saved_CPPFLAGS} ${CEPHFS_INC}" AC_LANG_PUSH(C++) AC_CHECK_HEADER(cephfs/libcephfs.h) AC_MSG_CHECKING(for ceph_create in cephfs library) AC_TRY_LINK( [ #include #include ], [ struct ceph_mount_info *cmount; ceph_create(&cmount, NULL); ], [ AC_MSG_RESULT(yes) have_cephfs="yes" ], [ AC_MSG_RESULT(no) have_cephfs="no" ] ) AC_LANG_POP(C++) LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_cephfs}" = "xyes"; then AC_DEFINE(HAVE_CEPHFS, 1, [Define to 1 if you have cephfs lib]) else CEPHFS_LIBS="" CEPHFS_INC="" fi AC_SUBST(CEPHFS_INC) AC_SUBST(CEPHFS_LIBS) dnl dnl Check for pthread libraries dnl PTHREAD_LIB="" AC_CHECK_LIB(pthread, pthread_create, PTHREAD_LIB="-lpthread", [ AC_CHECK_LIB(pthreads, pthread_create, PTHREAD_LIB="-lpthreads", [ AC_CHECK_LIB(c_r, pthread_create, PTHREAD_LIB="-lc_r", [ AC_CHECK_FUNC(pthread_create) ] ) ] ) ] ) dnl dnl Check for headers, functions and libraries required to support dnl keeping readall capabilities dnl AC_CHECK_HEADERS(sys/prctl.h sys/capability.h) AC_CHECK_FUNCS(prctl setreuid) AC_CHECK_LIB([cap], [cap_set_proc], [CAP_LIBS="-lcap"], [CAP_LIBS=]) if test x$CAP_LIBS = x-lcap; then AC_DEFINE(HAVE_LIBCAP, 1, [Define to 1 if you have libcap]) fi AC_SUBST(CAP_LIBS) CFLAGS=${CFLAGS--O} if test x$have_gcc = xyes ; then CPPFLAGS="$CPPFLAGS -fno-strict-aliasing -fno-exceptions" CFLAGS="$CFLAGS -fno-strict-aliasing -fno-exceptions" CXXFLAGS="$CFLAGS -fno-strict-aliasing -fno-exceptions -fno-rtti" fi LDFLAGS=${LDFLAGS--O} CPPFLAGS="$CPPFLAGS" CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" AC_SUBST(DEBUG) AC_SUBST(DINCLUDE) AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(CXXFLAGS) AC_SUBST(LDFLAGS) AC_SUBST(X_CFLAGS) AC_SUBST(DEFS) AC_SUBST(LIBS) AC_SUBST(DLIB) AC_SUBST(X_LIBS) AC_SUBST(X_EXTRA_LIBS) AC_SUBST(WCFLAGS) AC_SUBST(WLDFLAGS) AC_SUBST(WRAPLIBS) AC_SUBST(SOCKLIBS) lld="lld" llu="llu" WCFLAGS= WLDFLAGS= dnl dnl Finally we set appropriate distribution specific dnl variables and defaults dnl dnl PFILES are platform specific files PFILES="platforms/Makefile" PSCMD="ps -e" MACOSX= COMPRESS_MANPAGES=yes case "$DISTNAME" in aix) TAPEDRIVE="/dev/rmt0.1" PSCMD="ps -e -o pid,comm" PFILES="${PFILES} \ platforms/aix/Makefile" largefile_support="yes" ;; alpha) PTHREAD_LIB="-lpthread -lexc" if test "${CC}" = "gcc" ; then lld="lld" llu="llu" else lld="ld" llu="lu" fi TAPEDRIVE="/dev/nrmt0" ;; bsdi) TAPEDRIVE="/dev/nrmt0" PTHREAD_LIB="-pthread" CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" PSCMD="ps -ax -o pid,command" lld="qd" llu="qu" PFILES="${PFILES} \ platforms/bsdi/Makefile \ platforms/bsdi/bareos-fd \ platforms/bsdi/bareos-sd \ platforms/bsdi/bareos-dir" largefile_support="yes" ;; darwin) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" MACOSX=macosx PFILES="${PFILES} \ platforms/darwin/Makefile" ;; osx) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" MACOSX=macosx PFILES="${PFILES} \ platforms/osx/Makefile" ;; debian|ubuntu|univention) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" DEBIAN_CONTROL_UNIVENTION_BAREOS=/dev/null DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA=/dev/null PFILES="${PFILES} ${DEBIAN_CONTROL} \ debian/bareos-bat.install \ debian/bareos-bat.postinst \ debian/bareos-bconsole.install \ debian/bareos-bconsole.postinst \ debian/bareos-common.install \ debian/bareos-common.postinst \ debian/bareos-common.preinst \ debian/bareos-database-common.config \ debian/bareos-database-common.install \ debian/bareos-database-common.postinst \ debian/bareos-database-mysql.install \ debian/bareos-database-postgresql.install \ debian/bareos-database-sqlite3.install \ debian/bareos-database-tools.install \ debian/bareos-devel.install \ debian/bareos-director-python-plugin.install \ debian/bareos-director.bareos-dir.init \ debian/bareos-director.install \ debian/bareos-director.postinst \ debian/bareos-director.preinst \ debian/bareos-filedaemon-python-plugin.install \ debian/bareos-filedaemon.bareos-fd.init \ debian/bareos-filedaemon.install \ debian/bareos-filedaemon.postinst \ debian/bareos-filedaemon.preinst \ debian/bareos-storage-fifo.postinst \ debian/bareos-storage-fifo.install \ debian/bareos-storage-python-plugin.install \ debian/bareos-storage-tape.postinst \ debian/bareos-storage-tape.install \ debian/bareos-storage.bareos-sd.init \ debian/bareos-storage.install \ debian/bareos-storage.postinst \ debian/bareos-storage.preinst \ debian/bareos-tools.install \ debian/bareos-traymonitor.install \ debian/bareos-traymonitor.postinst \ platforms/debian/Makefile \ platforms/debian/set_dbconfig_vars.sh" case "$DISTNAME" in ubuntu) PFILES="${PFILES} \ platforms/ubuntu/Makefile" ;; univention) DEBIAN_CONTROL_UNIVENTION_BAREOS=./debian/control.univention-bareos DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA=./debian/control.univention-bareos-schema PFILES="${PFILES} \ debian/univention-bareos-schema.install \ debian/univention-bareos-schema.postinst \ debian/univention-bareos.install \ debian/univention-bareos.postinst \ platforms/univention/Makefile" ;; esac AC_SUBST_FILE(DEBIAN_CONTROL_UNIVENTION_BAREOS) AC_SUBST_FILE(DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA) ;; freebsd) VER=`echo $DISTVER | cut -c 1` if test x$VER = x4 ; then PTHREAD_LIB="${PTHREAD_LIBS:--pthread}" CFLAGS="${CFLAGS} ${PTHREAD_CFLAGS:--pthread}" CXXFLAGS="${CXXFLAGS} ${PTHREAD_CFLAGS:--pthread}" fi lld="qd" llu="qu" TAPEDRIVE="/dev/nrsa0" PSCMD="ps -ax -o pid,command" PFILES="${PFILES} \ platforms/freebsd/Makefile \ platforms/freebsd/bareos-fd \ platforms/freebsd/bareos-sd \ platforms/freebsd/bareos-dir" largefile_support="yes" ;; hurd) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/hurd/Makefile \ platforms/hurd/bareos-fd \ platforms/hurd/bareos-sd \ platforms/hurd/bareos-dir" ;; hpux) PSCMD="UNIX95=1; ps -e -o pid,comm" CFLAGS="${CFLAGS} -D_XOPEN_SOURCE_EXTENDED=1" CXXFLAGS="${CXXFLAGS} -D_XOPEN_SOURCE_EXTENDED=1" TAPEDRIVE="/dev/rmt/0hnb" PTHREAD_LIB="-lpthread" AC_DEFINE(_INCLUDE_LONGLONG, 1, [Needed on HP-UX/g++ systems to support long long ints (int64)]) ;; irix) TAPEDRIVE="/dev/rmt/0cbn" PSCMD="ps -e -o pid,comm" PFILES="${PFILES} \ platforms/irix/Makefile \ platforms/irix/bareos-fd \ platforms/irix/bareos-sd \ platforms/irix/bareos-dir" ;; netbsd) lld="qd" llu="qu" TAPEDRIVE="/dev/nrst0" PSCMD="ps -ax -o pid,command" PTHREAD_LIB="-pthread" CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" ;; openbsd) lld="qd" llu="qu" TAPEDRIVE="/dev/nrst0" PSCMD="ps -ax -o pid,command" PTHREAD_LIB="-pthread" CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" PFILES="${PFILES} \ platforms/openbsd/Makefile \ platforms/openbsd/bareos-fd \ platforms/openbsd/bareos-sd \ platforms/openbsd/bareos-dir" ;; redhat) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/redhat/Makefile \ platforms/redhat/bareos-fd \ platforms/redhat/bareos-sd \ platforms/redhat/bareos-dir " ;; mandrake) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/mandrake/Makefile \ platforms/mandrake/bareos-fd \ platforms/mandrake/bareos-sd \ platforms/mandrake/bareos-dir \ " ;; gentoo) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/gentoo/Makefile \ platforms/gentoo/bareos-init \ platforms/gentoo/bareos-fd \ platforms/gentoo/bareos-sd \ platforms/gentoo/bareos-dir" ;; slackware) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/slackware/Makefile \ platforms/slackware/rc.bareos-fd \ platforms/slackware/rc.bareos-sd \ platforms/slackware/rc.bareos-dir\ platforms/slackware/functions.bareos" ;; solaris) TAPEDRIVE="/dev/rmt/0cbn" PSCMD="ps -e -o pid,comm" PFILES="${PFILES} \ platforms/solaris/Makefile \ platforms/solaris/bareos-fd \ platforms/solaris/bareos-sd \ platforms/solaris/bareos-dir" COMPRESS_MANPAGES= case ${DISTVER} in 5.5|5.6) AC_DEFINE(HAVE_OLD_SOCKOPT, 1, [Define to 1 to use the old sockopt option]) AC_DEFINE(USE_THR_SETCONCURRENCY, 1, [Define to 1 to use the thr_setconcurrency function]) AC_DEFINE(HAVE_NON_WORKING_WALKCONTEXT, 1, [Define to 1 to when walkcontext does not work]) ;; 5.7|5.8) AC_DEFINE(USE_THR_SETCONCURRENCY, 1, [Define to 1 to use the thr_setconcurrency function]) AC_DEFINE(HAVE_NON_WORKING_WALKCONTEXT, 1, [Define to 1 to when walkcontext does not work]) ;; 5.9) AC_DEFINE(HAVE_NON_WORKING_WALKCONTEXT, 1, [Define to 1 to when walkcontext does not work]) ;; *) ;; esac LIBS="$LIBS -lresolv -lrt" ;; suse) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/suse/Makefile \ platforms/suse/bareos-fd \ platforms/suse/bareos-sd \ platforms/suse/bareos-dir \ platforms/suse/bareos" ;; unknown) TAPEDRIVE="/dev/nst0" ;; *) echo " === Something went wrong. Unknown DISTNAME $DISTNAME ===" ;; esac dnl ------------------------------------------- dnl systemd (default off) dnl ------------------------------------------- AC_MSG_CHECKING(for systemd support) AC_ARG_WITH(systemd, AC_HELP_STRING([--with-systemd@<:@=UNITDIR@:>@], [Include systemd support. UNITDIR is where systemd system .service files are located, default is to ask systemctl.]), [ if test "$withval" != "no"; then if test "$withval" = "yes"; then SYSTEMD_UNITDIR="`systemctl show | grep UnitPath | cut -d " " -f2`" else SYSTEMD_UNITDIR="${withval}" fi PFILES="${PFILES} \ platforms/systemd/Makefile \ platforms/systemd/bareos.conf \ platforms/systemd/bareos-dir.service \ platforms/systemd/bareos-fd.service \ platforms/systemd/bareos-sd.service" AC_DEFINE(HAVE_SYSTEMD, 1, [Define to 1 if systemd support should be enabled]) AC_MSG_RESULT(yes) support_systemd="yes" else AC_MSG_RESULT(no) support_systemd="no" fi ],[ support_systemd="no" AC_MSG_RESULT(no) ] ) AC_SUBST(SYSTEMD_UNITDIR) AC_SUBST(hostname) LIBS="$PTHREAD_LIB $LIBS" AC_DEFINE_UNQUOTED(lld, "$lld", [Set to correct scanf value for long long int]) AC_DEFINE_UNQUOTED(llu, "$llu", [Set to correct scanf value for long long unsigned int]) AC_SUBST(TAPEDRIVE) AC_SUBST(PSCMD) AC_SUBST(MACOSX) AC_SUBST(DISTNAME) AC_SUBST(DISTVER) AC_SUBST(COMPRESS_MANPAGES) dnl common parts of the Makefile MCOMMON=./autoconf/Make.common AC_SUBST_FILE(MCOMMON) dnl build a list of plugins we need to build. BUILD_FD_PLUGINS="" BUILD_SD_PLUGINS="" BUILD_DIR_PLUGINS="" DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN=/dev/null DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN=/dev/null DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN=/dev/null if test X"$support_python" = "Xyes" ; then BUILD_FD_PLUGINS="${BUILD_FD_PLUGINS} python-fd.la" BUILD_SD_PLUGINS="${BUILD_SD_PLUGINS} python-sd.la" BUILD_DIR_PLUGINS="${BUILD_DIR_PLUGINS} python-dir.la" DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN=./debian/control.bareos-filedaemon-python-plugin DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN=./debian/control.bareos-storage-python-plugin DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN=./debian/control.bareos-director-python-plugin fi if test X"$have_scsi_crypto" = "Xyes" ; then BUILD_SD_PLUGINS="${BUILD_SD_PLUGINS} scsicrypto-sd.la scsitapealert-sd.la" fi if test X"$have_zlib" = "Xyes" -o \ X"$have_lzo" = "Xyes" -o \ X"$have_fastlz" = "Xyes" ; then BUILD_SD_PLUGINS="${BUILD_SD_PLUGINS} autoxflate-sd.la" fi AC_SUBST(BUILD_FD_PLUGINS) AC_SUBST(BUILD_SD_PLUGINS) AC_SUBST(BUILD_DIR_PLUGINS) AC_SUBST_FILE(DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN) AC_SUBST_FILE(DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN) AC_SUBST_FILE(DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN) dnl build a list of storage backend we need to build. if test x$use_libtool != xno; then BUILD_SD_BACKENDS="libbareossd-fifo.la libbareossd-gentape.la libbareossd-tape.la" if test X"$have_glusterfs" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-gfapi.la" fi if test X"$have_droplet" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-object.la" fi if test X"$have_ceph_rados" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-rados.la" fi if test X"$have_cephfs" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-cephfs.la" fi else BUILD_SD_BACKENDS="" fi AC_SUBST(BUILD_SD_BACKENDS) dnl install storage backend config files INSTALL_SD_CONFS="device-fifo.conf device-tape-with-autoloader.conf" if test X"$have_glusterfs" = "Xyes" ; then INSTALL_SD_CONFS="${INSTALL_SD_CONFS} device-gluster.conf" fi if test X"$have_ceph_rados" = "Xyes" ; then INSTALL_SD_CONFS="${INSTALL_SD_CONFS} device-ceph-rados.conf" fi AC_SUBST(INSTALL_SD_CONFS) dnl Insanity check if test "x${subsysdir}" = "x${sbindir}" ; then echo " " echo " " echo "You have set both --sbindir and --with-subsys-dir" echo " equal to: ${subsysdir} " echo "This is not permitted. Please reconfigure." echo " " echo "Aborting configuration ..." echo " " echo " " exit 1 fi AC_CONFIG_FILES([ autoconf/Make.common \ Makefile \ manpages/Makefile \ scripts/bareos-config \ scripts/bareos-config-lib.sh \ scripts/bareos-explorer \ scripts/btraceback \ scripts/bconsole \ scripts/bareos \ scripts/bareos-ctl-dir \ scripts/bareos-ctl-fd \ scripts/bareos-ctl-sd \ scripts/devel_bareos \ scripts/Makefile \ scripts/logrotate \ scripts/mtx-changer \ scripts/disk-changer \ scripts/logwatch/Makefile \ scripts/logwatch/logfile.bareos.conf \ scripts/bat.console_apps \ src/Makefile \ src/include/host.h \ src/console/Makefile \ src/console/bconsole.conf \ src/qt-tray-monitor/bareos-tray-monitor.desktop \ src/qt-tray-monitor/tray-monitor.conf \ src/qt-tray-monitor/tray-monitor.pro \ src/qt-console/bat.conf \ src/qt-console/bat.desktop \ src/qt-console/bat.pro \ src/qt-console/install_conf_file \ src/dird/Makefile \ src/dird/bareos-dir.conf \ src/lib/Makefile \ src/stored/Makefile \ src/stored/bareos-sd.conf \ src/stored/backends/Makefile \ src/filed/Makefile \ src/filed/bareos-fd.conf \ src/cats/Makefile \ src/cats/make_catalog_backup.pl \ src/cats/make_catalog_backup \ src/cats/delete_catalog_backup \ src/cats/create_bareos_database \ src/cats/update_bareos_tables \ src/cats/grant_bareos_privileges \ src/cats/make_bareos_tables \ src/cats/drop_bareos_tables \ src/cats/drop_bareos_database \ src/cats/install-default-backend \ src/cats/ddl/versions.map \ src/findlib/Makefile \ src/lmdb/Makefile \ src/ndmp/Makefile \ src/tests/Makefile \ src/tools/Makefile \ src/plugins/filed/Makefile \ src/plugins/stored/Makefile \ src/plugins/dird/Makefile \ po/Makefile.in \ src/defaultconfigs/diskonly/bareos-sd.conf \ src/defaultconfigs/diskonly/bareos-dir.conf \ $PFILES ]) AC_OUTPUT if test "${support_bat}" = "yes" ; then if test "x$QMAKE" = "xnone"; then AC_MSG_ERROR([Could not find qmake $PATH. Check your Qt installation]) fi cd src/qt-console echo "Creating bat Makefile" # hack: required to get "make install" to work touch bat chmod 755 bat rm -f Makefile $QMAKE ${MAKE:-make} clean cd ${BUILD_DIR} fi if test "${support_traymonitor}" = "yes" ; then if test "x$QMAKE" = "xnone"; then AC_MSG_ERROR([Could not find qmake $PATH. Check your Qt installation]) fi cd src/qt-tray-monitor echo "Creating tray-monitor Makefile" # hack: required to get "make install" to work touch bareos-tray-monitor chmod 755 bareos-tray-monitor rm -f Makefile $QMAKE ${MAKE:-make} clean cd ${BUILD_DIR} fi dnl dnl if CC is gcc, we can rebuild the dependencies (since the depend rule dnl requires gcc). If it's not, don't rebuild dependencies dnl if test X"$GCC" = "Xyes" ; then echo "Doing make of dependencies" ${MAKE:-make} depend fi cd src/qt-console chmod 755 install_conf_file cd ${BUILD_DIR} cd scripts chmod 755 bareos btraceback mtx-changer chmod 755 bconsole mtx-changer devel_bareos logrotate cd .. c=src/cats chmod 755 $c/create_bareos_database $c/update_bareos_tables $c/make_bareos_tables chmod 755 $c/grant_bareos_privileges $c/drop_bareos_tables $c/drop_bareos_database chmod 755 $c/make_catalog_backup $c/delete_catalog_backup $c/make_catalog_backup.pl chmod 755 $c/install-default-backend if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then largefile_support="yes" fi dnl Only try to find out the version number of the compiler when we know its some kind of GCC compiler if test X"$GCC" = "Xyes" ; then dnl dnl A whole lot of hand springs to get the compiler version. dnl This is because gcc changed the output in version 3.0 dnl CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 3 -d ' '` if test "x${CCVERSION}" = "x" ; then CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 1 -d ' '` fi CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 3 -d ' '` if test x"${CXXVERSION}" = x ; then CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 1 -d ' '` fi fi # clean up any old junk echo " " echo "Cleaning up" echo " " ${MAKE:-make} clean echo " Configuration on `date`: Host: ${host}${post_host} -- ${DISTNAME} ${DISTVER} Bareos version: ${BAREOS} ${VERSION} (${DATE}) Distribution: ${DISTNAME} Source code location: ${srcdir} Modify package list: ${DEBIAN_CONTROL} Install binaries: ${bindir} Install system binaries: ${sbindir} Install libraries: ${libdir} Install config files: ${sysconfdir} Scripts directory: ${scriptdir} Archive directory: ${archivedir} Working directory: ${working_dir} PID directory: ${piddir} Subsys directory: ${subsysdir} Man directory: ${mandir} Data directory: ${datarootdir} Backend directory: ${backenddir} Plugin directory: ${plugindir} C Compiler: ${CC} ${CCVERSION} C++ Compiler: ${CXX} ${CXXVERSION} Compiler flags: ${WCFLAGS} ${CFLAGS} Linker flags: ${WLDFLAGS} ${LDFLAGS} Libraries: ${LIBS} Statically Linked Tools: ${support_static_tools} Statically Linked FD: ${support_static_fd} Statically Linked SD: ${support_static_sd} Statically Linked DIR: ${support_static_dir} Statically Linked CONS: ${support_static_cons} Database backends: ${db_backends} Database port: ${db_port} Database name: ${db_name} Database user: ${db_user} Database version: ${BDB_VERSION} Job Output Email: ${job_email} Traceback Email: ${dump_email} SMTP Host Address: ${smtp_host} Director Port: ${dir_port} File daemon Port: ${fd_port} Storage daemon Port: ${sd_port} Director User: ${dir_user} Director Group: ${dir_group} Storage Daemon User: ${sd_user} Storage DaemonGroup: ${sd_group} File Daemon User: ${fd_user} File Daemon Group: ${fd_group} Large file support: $largefile_support Bareos conio support: ${got_conio} ${CONS_LIBS} readline support: ${got_readline} ${PRTREADLINE_SRC} TCP Wrappers support: ${TCPW_MSG} ${WRAPLIBS} TLS support: ${have_tls} Encryption support: ${have_crypto} OpenSSL support: ${have_openssl} GNUTLS support: ${have_gnutls} ZLIB support: ${have_zlib} LZO support: ${have_lzo} FASTLZ support: ${have_fastlz} LMDB support: ${support_lmdb} NDMP support: ${support_ndmp} enable-smartalloc: ${support_smartalloc} enable-lockmgr: ${support_lockmgr} bat support: ${support_bat} tray-monitor support: ${support_traymonitor} client-only: ${build_client_only} build-dird: ${build_dird} build-stored: ${build_stored} Plugin support: ${have_plugins} AFS support: ${have_afs} ACL support: ${have_acl} XATTR support: ${have_xattr} SCSI Crypto support: ${have_scsi_crypto} GLUSTERFS support: ${have_glusterfs} DROPLET support: ${have_droplet} CEPH RADOS support: ${have_ceph_rados} CEPHFS support: ${have_cephfs} Python support: ${support_python} ${PYTHON_LIBS} systemd support: ${support_systemd} ${SYSTEMD_UNITDIR} Batch insert enabled: ${batch_insert_db_backends} " > config.out # create a small shell script useful for support with # configure options and config.out info cat > scripts/bareos_config << EOF #!/bin/sh cat << __EOC__ $ $0 $ac_configure_args EOF cat config.out >> scripts/bareos_config echo __EOC__ >> scripts/bareos_config chmod 755 scripts/bareos_config cat config.out bareos-Release-14.2.6/autoconf/gettext/000077500000000000000000000000001263011562700177425ustar00rootroot00000000000000bareos-Release-14.2.6/autoconf/gettext/codeset.m4000066400000000000000000000013511263011562700216320ustar00rootroot00000000000000# codeset.m4 serial AM1 (gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([AM_LANGINFO_CODESET], [ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, [AC_TRY_LINK([#include ], [char* cs = nl_langinfo(CODESET);], am_cv_langinfo_codeset=yes, am_cv_langinfo_codeset=no) ]) if test $am_cv_langinfo_codeset = yes; then AC_DEFINE(HAVE_LANGINFO_CODESET, 1, [Define if you have and nl_langinfo(CODESET).]) fi ]) bareos-Release-14.2.6/autoconf/gettext/gettext.m4000066400000000000000000000517101263011562700216740ustar00rootroot00000000000000# gettext.m4 serial 37 (gettext-0.14.4) dnl Copyright (C) 1995-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The dnl default (if it is not specified or empty) is 'no-libtool'. dnl INTLSYMBOL should be 'external' for packages with no intl directory, dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library dnl $(top_builddir)/intl/libintl.a will be created. dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is dnl 'need-formatstring-macros', then GNU gettext implementations that don't dnl support the ISO C 99 formatstring macros will be ignored. dnl INTLDIR is used to find the intl libraries. If empty, dnl the value `$(top_builddir)/intl/' is used. dnl dnl The result of the configuration is one of three cases: dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled dnl and used. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 2) GNU gettext has been found in the system's C library. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 3) No internationalization, always use English msgid. dnl Catalog format: none dnl Catalog extension: none dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. dnl The use of .gmo is historical (it was needed to avoid overwriting the dnl GNU format catalogs when building on a platform with an X/Open gettext), dnl but we keep it in order not to force irrelevant filename changes on the dnl maintainers. dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ])])])])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define([gt_included_intl], ifelse([$1], [external], [no], [yes])) define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) AC_REQUIRE([AM_PO_SUBDIRS])dnl ifelse(gt_included_intl, yes, [ AC_REQUIRE([AM_INTL_SUBDIR])dnl ]) dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Sometimes libintl requires libiconv, so first search for libiconv. dnl Ideally we would do this search only after the dnl if test "$USE_NLS" = "yes"; then dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT dnl the configure script would need to contain the same shell code dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not dnl documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation. gt_INTL_MACOSX dnl Set USE_NLS. AM_NLS ifelse(gt_included_intl, yes, [ BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no ]) LIBINTL= LTLIBINTL= POSUB= dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no ifelse(gt_included_intl, yes, [ AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH(included-gettext, AC_HELP_STRING([--with-included-gettext], [use the GNU gettext library included here]), nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ]) dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If GNU gettext is available we use this. Else we have dnl to fall back to GNU NLS library. dnl Add a version number to the cache macros. define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, [AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings;], [bindtextdomain ("", ""); return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], gt_cv_func_gnugettext_libc=yes, gt_cv_func_gnugettext_libc=no)]) if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl Sometimes libintl requires libiconv, so first search for libiconv. ifelse(gt_included_intl, yes, , [ AM_ICONV_LINK ]) dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) dnl because that would add "-liconv" to LIBINTL and LTLIBINTL dnl even if libiconv doesn't exist. AC_LIB_LINKFLAGS_BODY([intl]) AC_CACHE_CHECK([for GNU gettext in libintl], gt_cv_func_gnugettext_libintl, [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *);], [bindtextdomain ("", ""); return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias ("")], gt_cv_func_gnugettext_libintl=yes, gt_cv_func_gnugettext_libintl=no) dnl Now see whether libintl exists and depends on libiconv. if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *);], [bindtextdomain ("", ""); return * gettext ("")]ifelse([$2], [need-ngettext], [ + * ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias ("")], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext_libintl=yes ]) fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) fi dnl If an already present or preinstalled GNU gettext() is found, dnl use it. But if this macro is used in GNU gettext, and GNU dnl gettext is already preinstalled in libintl, we update this dnl libintl. (Cf. the install rule in intl/Makefile.in.) if test "$gt_cv_func_gnugettext_libc" = "yes" \ || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else dnl Reset the values set by searching for libintl. LIBINTL= LTLIBINTL= INCINTL= fi ifelse(gt_included_intl, yes, [ if test "$gt_use_preinstalled_gnugettext" != "yes"; then dnl GNU gettext is not found in the C library. dnl Fall back on included GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi CATOBJEXT= if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo fi ]) if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Some extra flags are needed during linking. LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if translation of program messages to the user's native language is requested.]) else USE_NLS=no fi fi AC_MSG_CHECKING([whether to use NLS]) AC_MSG_RESULT([$USE_NLS]) if test "$USE_NLS" = "yes"; then AC_MSG_CHECKING([where the gettext function comes from]) if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext_libintl" = "yes"; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi AC_MSG_RESULT([$gt_source]) fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext_libintl" = "yes"; then AC_MSG_CHECKING([how to link with libintl]) AC_MSG_RESULT([$LIBINTL]) AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) fi dnl For backward compatibility. Some packages may be using this. AC_DEFINE(HAVE_GETTEXT, 1, [Define if the GNU gettext() function is already present or preinstalled.]) AC_DEFINE(HAVE_DCGETTEXT, 1, [Define if the GNU dcgettext() function is already present or preinstalled.]) fi dnl We need to process the po/ directory. POSUB=po fi ifelse(gt_included_intl, yes, [ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL dnl to 'yes' because some of the testsuite requires it. if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then BUILD_INCLUDED_LIBINTL=yes fi dnl Make all variables we use known to autoconf. AC_SUBST(BUILD_INCLUDED_LIBINTL) AC_SUBST(USE_INCLUDED_LIBINTL) AC_SUBST(CATOBJEXT) dnl For backward compatibility. Some configure.ins may be using this. nls_cv_header_intl= nls_cv_header_libgt= dnl For backward compatibility. Some Makefiles may be using this. DATADIRNAME=share AC_SUBST(DATADIRNAME) dnl For backward compatibility. Some Makefiles may be using this. INSTOBJEXT=.mo AC_SUBST(INSTOBJEXT) dnl For backward compatibility. Some Makefiles may be using this. GENCAT=gencat AC_SUBST(GENCAT) dnl For backward compatibility. Some Makefiles may be using this. INTLOBJS= if test "$USE_INCLUDED_LIBINTL" = yes; then INTLOBJS="\$(GETTOBJS)" fi AC_SUBST(INTLOBJS) dnl Enable libtool support if the surrounding package wishes it. INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) ]) dnl For backward compatibility. Some Makefiles may be using this. INTLLIBS="$LIBINTL" AC_SUBST(INTLLIBS) dnl Make all documented variables known to autoconf. AC_SUBST(LIBINTL) AC_SUBST(LTLIBINTL) AC_SUBST(POSUB) ]) dnl Checks for all prerequisites of the intl subdirectory, dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. AC_DEFUN([AM_INTL_SUBDIR], [ AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([gt_GLIBC2])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_ISC_POSIX])dnl AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_C_CONST])dnl AC_REQUIRE([bh_C_SIGNED])dnl AC_REQUIRE([AC_C_INLINE])dnl AC_REQUIRE([AC_TYPE_OFF_T])dnl AC_REQUIRE([AC_TYPE_SIZE_T])dnl AC_REQUIRE([gl_AC_TYPE_LONG_LONG])dnl AC_REQUIRE([gt_TYPE_LONGDOUBLE])dnl AC_REQUIRE([gt_TYPE_WCHAR_T])dnl AC_REQUIRE([gt_TYPE_WINT_T])dnl AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) AC_REQUIRE([gl_AC_HEADER_STDINT_H]) AC_REQUIRE([gt_TYPE_INTMAX_T]) AC_REQUIRE([gt_PRINTF_POSIX]) AC_REQUIRE([AC_FUNC_ALLOCA])dnl AC_REQUIRE([AC_FUNC_MMAP])dnl AC_REQUIRE([gl_GLIBC21])dnl AC_REQUIRE([gt_INTDIV0])dnl AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl AC_REQUIRE([gt_INTTYPES_PRI])dnl AC_REQUIRE([gl_XSIZE])dnl AC_REQUIRE([gt_INTL_MACOSX])dnl AC_CHECK_TYPE([ptrdiff_t], , [AC_DEFINE([ptrdiff_t], [long], [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) ]) AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ stdlib.h string.h unistd.h sys/param.h]) AC_CHECK_FUNCS([asprintf fwprintf getcwd getegid geteuid getgid getuid \ mempcpy munmap putenv setenv setlocale snprintf stpcpy strcasecmp strdup \ strtoul tsearch wcslen __argz_count __argz_stringify __argz_next \ __fsetlocking]) dnl Use the _snprintf function only if it is declared (because on NetBSD it dnl is defined as a weak alias of snprintf; we prefer to use the latter). gt_CHECK_DECL(_snprintf, [#include ]) gt_CHECK_DECL(_snwprintf, [#include ]) dnl Use the *_unlocked functions only if they are declared. dnl (because some of them were defined without being declared in Solaris dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built dnl on Solaris 2.5.1 to run on Solaris 2.6). dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. gt_CHECK_DECL(feof_unlocked, [#include ]) gt_CHECK_DECL(fgets_unlocked, [#include ]) gt_CHECK_DECL(getc_unlocked, [#include ]) case $gt_cv_func_printf_posix in *yes) HAVE_POSIX_PRINTF=1 ;; *) HAVE_POSIX_PRINTF=0 ;; esac AC_SUBST([HAVE_POSIX_PRINTF]) if test "$ac_cv_func_asprintf" = yes; then HAVE_ASPRINTF=1 else HAVE_ASPRINTF=0 fi AC_SUBST([HAVE_ASPRINTF]) if test "$ac_cv_func_snprintf" = yes; then HAVE_SNPRINTF=1 else HAVE_SNPRINTF=0 fi AC_SUBST([HAVE_SNPRINTF]) if test "$ac_cv_func_wprintf" = yes; then HAVE_WPRINTF=1 else HAVE_WPRINTF=0 fi AC_SUBST([HAVE_WPRINTF]) AM_ICONV AM_LANGINFO_CODESET if test $ac_cv_header_locale_h = yes; then gt_LC_MESSAGES fi if test -n "$INTL_MACOSX_LIBS"; then CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" fi dnl intl/plural.c is generated from intl/plural.y. It requires bison, dnl because plural.y uses bison specific features. It requires at least dnl bison-1.26 because earlier versions generate a plural.c that doesn't dnl compile. dnl bison is only needed for the maintainer (who touches plural.y). But in dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put dnl the rule in general Makefile. Now, some people carelessly touch the dnl files or have a broken "make" program, hence the plural.c rule will dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not dnl present or too old. AC_CHECK_PROGS([INTLBISON], [bison]) if test -z "$INTLBISON"; then ac_verc_fail=yes else dnl Found it, now check the version. AC_MSG_CHECKING([version of bison]) changequote(<<,>>)dnl ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) changequote([,])dnl ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; esac AC_MSG_RESULT([$ac_prog_version]) fi if test $ac_verc_fail = yes; then INTLBISON=: fi ]) dnl Checks for special options needed on MacOS X. dnl Defines INTL_MACOSX_LIBS. AC_DEFUN([gt_INTL_MACOSX], [ dnl Check for API introduced in MacOS X 10.2. AC_CACHE_CHECK([for CFPreferencesCopyAppValue], gt_cv_func_CFPreferencesCopyAppValue, [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" AC_TRY_LINK([#include ], [CFPreferencesCopyAppValue(NULL, NULL)], [gt_cv_func_CFPreferencesCopyAppValue=yes], [gt_cv_func_CFPreferencesCopyAppValue=no]) CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1, [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) fi dnl Check for API introduced in MacOS X 10.3. AC_CACHE_CHECK([for CFLocaleCopyCurrent], gt_cv_func_CFLocaleCopyCurrent, [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" AC_TRY_LINK([#include ], [CFLocaleCopyCurrent();], [gt_cv_func_CFLocaleCopyCurrent=yes], [gt_cv_func_CFLocaleCopyCurrent=no]) CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) if test $gt_cv_func_CFLocaleCopyCurrent = yes; then AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1, [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi AC_SUBST([INTL_MACOSX_LIBS]) ]) dnl gt_CHECK_DECL(FUNC, INCLUDES) dnl Check whether a function is declared. AC_DEFUN([gt_CHECK_DECL], [ AC_CACHE_CHECK([whether $1 is declared], ac_cv_have_decl_$1, [AC_TRY_COMPILE([$2], [ #ifndef $1 char *p = (char *) $1; #endif ], ac_cv_have_decl_$1=yes, ac_cv_have_decl_$1=no)]) if test $ac_cv_have_decl_$1 = yes; then gt_value=1 else gt_value=0 fi AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value], [Define to 1 if you have the declaration of `$1', and to 0 if you don't.]) ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) bareos-Release-14.2.6/autoconf/gettext/glibc2.m4000066400000000000000000000013541263011562700213510ustar00rootroot00000000000000# glibc2.m4 serial 1 dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # Test for the GNU C Library, version 2.0 or newer. # From Bruno Haible. AC_DEFUN([gt_GLIBC2], [ AC_CACHE_CHECK(whether we are using the GNU C Library 2 or newer, ac_cv_gnu_library_2, [AC_EGREP_CPP([Lucky GNU user], [ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ >= 2) Lucky GNU user #endif #endif ], ac_cv_gnu_library_2=yes, ac_cv_gnu_library_2=no) ] ) AC_SUBST(GLIBC2) GLIBC2="$ac_cv_gnu_library_2" ] ) bareos-Release-14.2.6/autoconf/gettext/glibc21.m4000066400000000000000000000014451263011562700214330ustar00rootroot00000000000000# glibc21.m4 serial 3 dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # Test for the GNU C Library, version 2.1 or newer. # From Bruno Haible. AC_DEFUN([gl_GLIBC21], [ AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, ac_cv_gnu_library_2_1, [AC_EGREP_CPP([Lucky GNU user], [ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) Lucky GNU user #endif #endif ], ac_cv_gnu_library_2_1=yes, ac_cv_gnu_library_2_1=no) ] ) AC_SUBST(GLIBC21) GLIBC21="$ac_cv_gnu_library_2_1" ] ) bareos-Release-14.2.6/autoconf/gettext/iconv.m4000066400000000000000000000064351263011562700213320ustar00rootroot00000000000000# iconv.m4 serial AM4 (gettext-0.11.3) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_func_iconv=yes) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_DEFINE(HAVE_ICONV, 1, [Define to 1 if you have the `iconv()' function.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST(LIBICONV) AC_SUBST(LTLIBICONV) ]) AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL(am_cv_proto_iconv, [ AC_TRY_COMPILE([ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([$]{ac_t:- }[$]am_cv_proto_iconv) AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, [Define as const if the declaration of iconv() needs const.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/intdiv0.m4000066400000000000000000000033401263011562700215610ustar00rootroot00000000000000# intdiv0.m4 serial 1 (gettext-0.11.3) dnl Copyright (C) 2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([gt_INTDIV0], [ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], gt_cv_int_divbyzero_sigfpe, [ AC_TRY_RUN([ #include #include static void #ifdef __cplusplus sigfpe_handler (int sig) #else sigfpe_handler (sig) int sig; #endif { /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ exit (sig != SIGFPE); } int x = 1; int y = 0; int z; int nan; int main () { signal (SIGFPE, sigfpe_handler); /* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ #if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) signal (SIGTRAP, sigfpe_handler); #endif /* Linux/SPARC yields signal SIGILL. */ #if defined (__sparc__) && defined (__linux__) signal (SIGILL, sigfpe_handler); #endif z = x / y; nan = y / y; exit (1); } ], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, [ # Guess based on the CPU. case "$host_cpu" in alpha* | i[34567]86 | m68k | s390*) gt_cv_int_divbyzero_sigfpe="guessing yes";; *) gt_cv_int_divbyzero_sigfpe="guessing no";; esac ]) ]) case "$gt_cv_int_divbyzero_sigfpe" in *yes) value=1;; *) value=0;; esac AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, [Define if integer division by zero raises signal SIGFPE.]) ]) bareos-Release-14.2.6/autoconf/gettext/intmax.m4000066400000000000000000000017461263011562700215140ustar00rootroot00000000000000# intmax.m4 serial 2 (gettext-0.14.2) dnl Copyright (C) 2002-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl Test whether the system has the 'intmax_t' type, but don't attempt to dnl find a replacement if it is lacking. AC_DEFUN([gt_TYPE_INTMAX_T], [ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) AC_REQUIRE([gl_AC_HEADER_STDINT_H]) AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, [AC_TRY_COMPILE([ #include #include #if HAVE_STDINT_H_WITH_UINTMAX #include #endif #if HAVE_INTTYPES_H_WITH_UINTMAX #include #endif ], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) if test $gt_cv_c_intmax_t = yes; then AC_DEFINE(HAVE_INTMAX_T, 1, [Define if you have the 'intmax_t' type in or .]) fi ]) bareos-Release-14.2.6/autoconf/gettext/inttypes-pri.m4000066400000000000000000000020021263011562700226450ustar00rootroot00000000000000# inttypes-pri.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. # Define PRI_MACROS_BROKEN if exists and defines the PRI* # macros to non-string values. This is the case on AIX 4.3.3. AC_DEFUN([gt_INTTYPES_PRI], [ AC_REQUIRE([gt_HEADER_INTTYPES_H]) if test $gt_cv_header_inttypes_h = yes; then AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], gt_cv_inttypes_pri_broken, [ AC_TRY_COMPILE([#include #ifdef PRId32 char *p = PRId32; #endif ], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) ]) fi if test "$gt_cv_inttypes_pri_broken" = yes; then AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, [Define if exists and defines unusable PRI* macros.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/inttypes.m4000066400000000000000000000014721263011562700220670ustar00rootroot00000000000000# inttypes.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert. # Define HAVE_INTTYPES_H if exists and doesn't clash with # . AC_DEFUN([gt_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, [ AC_TRY_COMPILE( [#include #include ], [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) ]) if test $gt_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, [Define if exists and doesn't clash with .]) fi ]) bareos-Release-14.2.6/autoconf/gettext/inttypes_h.m4000066400000000000000000000016231263011562700223740ustar00rootroot00000000000000# inttypes_h.m4 serial 6 dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert. # Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([gl_AC_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], gl_cv_header_inttypes_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], gl_cv_header_inttypes_h=yes, gl_cv_header_inttypes_h=no)]) if test $gl_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) bareos-Release-14.2.6/autoconf/gettext/isc-posix.m4000066400000000000000000000017061263011562700221260ustar00rootroot00000000000000# isc-posix.m4 serial 2 (gettext-0.11.2) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # This file is not needed with autoconf-2.53 and newer. Remove it in 2005. # This test replaces the one in autoconf. # Currently this macro should have the same name as the autoconf macro # because gettext's gettext.m4 (distributed in the automake package) # still uses it. Otherwise, the use in gettext.m4 makes autoheader # give these diagnostics: # configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX # configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX undefine([AC_ISC_POSIX]) AC_DEFUN([AC_ISC_POSIX], [ dnl This test replaces the obsolescent AC_ISC_POSIX kludge. AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) ] ) bareos-Release-14.2.6/autoconf/gettext/lcmessage.m4000066400000000000000000000024041263011562700221470ustar00rootroot00000000000000# lcmessage.m4 serial 4 (gettext-0.14.2) dnl Copyright (C) 1995-2002, 2004-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995. # Check whether LC_MESSAGES is available in . AC_DEFUN([gt_LC_MESSAGES], [ AC_CACHE_CHECK([for LC_MESSAGES], gt_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], gt_cv_val_LC_MESSAGES=yes, gt_cv_val_LC_MESSAGES=no)]) if test $gt_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your file defines LC_MESSAGES.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/lib-ld.m4000066400000000000000000000065311263011562700213540ustar00rootroot00000000000000# lib-ld.m4 serial 3 (gettext-0.13) dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Subroutines of libtool.m4, dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision dnl with libtool.m4. dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, [# I'd rather use --version here, but apparently some GNU ld's only accept -v. case `$LD -v 2>&1 conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by GCC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]* | [A-Za-z]:[\\/]*)] [re_direlt='/[^/][^/]*/\.\./'] # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(acl_cv_path_LD, [if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi]) LD="$acl_cv_path_LD" if test -n "$LD"; then AC_MSG_RESULT($LD) else AC_MSG_RESULT(no) fi test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) AC_LIB_PROG_LD_GNU ]) bareos-Release-14.2.6/autoconf/gettext/lib-link.m4000066400000000000000000000554261263011562700217210ustar00rootroot00000000000000# lib-link.m4 serial 6 (gettext-0.14.3) dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_PREREQ(2.50) dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and dnl augments the CPPFLAGS variable. AC_DEFUN([AC_LIB_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ac_cv_lib[]Name[]_libs="$LIB[]NAME" ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ]) LIB[]NAME="$ac_cv_lib[]Name[]_libs" LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" INC[]NAME="$ac_cv_lib[]Name[]_cppflags" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the dnl results of this search when this library appears as a dependency. HAVE_LIB[]NAME=yes undefine([Name]) undefine([NAME]) ]) dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) dnl searches for libname and the libraries corresponding to explicit and dnl implicit dependencies, together with the specified include files and dnl the ability to compile and link the specified testcode. If found, it dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME dnl accordingly. AC_LIB_LINKFLAGS_BODY([$1], [$2]) dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, dnl because if the user has installed lib[]Name and not disabled its use dnl via --without-lib[]Name-prefix, he wants to use it. ac_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ac_save_LIBS="$LIBS" LIBS="$LIBS $LIB[]NAME" AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) LIBS="$ac_save_LIBS" ]) if test "$ac_cv_lib[]Name" = yes; then HAVE_LIB[]NAME=yes AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) AC_MSG_CHECKING([how to link with lib[]$1]) AC_MSG_RESULT([$LIB[]NAME]) else HAVE_LIB[]NAME=no dnl If $LIB[]NAME didn't lead to a usable library, we don't need dnl $INC[]NAME either. CPPFLAGS="$ac_save_CPPFLAGS" LIB[]NAME= LTLIB[]NAME= fi AC_SUBST([HAVE_LIB]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) undefine([Name]) undefine([NAME]) ]) dnl Determine the platform dependent parameters needed to use rpath: dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, dnl hardcode_direct, hardcode_minus_L. AC_DEFUN([AC_LIB_RPATH], [ dnl Tell automake >= 1.10 to complain if config.rpath is missing. m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE(rpath, [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib$1-prefix], [ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib --without-lib$1-prefix don't search for lib$1 in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) bareos-Release-14.2.6/autoconf/gettext/lib-prefix.m4000066400000000000000000000123101263011562700222420ustar00rootroot00000000000000# lib-prefix.m4 serial 4 (gettext-0.14.2) dnl Copyright (C) 2001-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't dnl require excessive bracketing. ifdef([AC_HELP_STRING], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], [AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) bareos-Release-14.2.6/autoconf/gettext/longdouble.m4000066400000000000000000000020531263011562700223360ustar00rootroot00000000000000# longdouble.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl Test whether the compiler supports the 'long double' type. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_LONGDOUBLE], [ AC_CACHE_CHECK([for long double], gt_cv_c_long_double, [if test "$GCC" = yes; then gt_cv_c_long_double=yes else AC_TRY_COMPILE([ /* The Stardent Vistra knows sizeof(long double), but does not support it. */ long double foo = 0.0; /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ int array [2*(sizeof(long double) >= sizeof(double)) - 1]; ], , gt_cv_c_long_double=yes, gt_cv_c_long_double=no) fi]) if test $gt_cv_c_long_double = yes; then AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/longlong.m4000066400000000000000000000014161263011562700220250ustar00rootroot00000000000000# longlong.m4 serial 5 dnl Copyright (C) 1999-2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert. # Define HAVE_LONG_LONG if 'long long' works. AC_DEFUN([gl_AC_TYPE_LONG_LONG], [ AC_CACHE_CHECK([for long long], ac_cv_type_long_long, [AC_TRY_LINK([long long ll = 1LL; int i = 63;], [long long llmax = (long long) -1; return ll << i | ll >> i | llmax / ll | llmax % ll;], ac_cv_type_long_long=yes, ac_cv_type_long_long=no)]) if test $ac_cv_type_long_long = yes; then AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have the 'long long' type.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/nls.m4000066400000000000000000000035301263011562700210010ustar00rootroot00000000000000# nls.m4 serial 2 (gettext-0.14.3) dnl Copyright (C) 1995-2003, 2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_PREREQ(2.50) AC_DEFUN([AM_NLS], [ AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) ]) AC_DEFUN([AM_MKINSTALLDIRS], [ dnl Tell automake >= 1.10 to complain if mkinstalldirs is missing. m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([mkinstalldirs])]) dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but $(top_srcdir). dnl Try to locate it. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then case "$ac_aux_dir" in /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; esac fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) ]) bareos-Release-14.2.6/autoconf/gettext/po.m4000066400000000000000000000436431263011562700206340ustar00rootroot00000000000000# po.m4 serial 7 (gettext-0.14.3) dnl Copyright (C) 1995-2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_PREREQ(2.50) dnl Checks for all prerequisites of the po subdirectory. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AM_NLS])dnl dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.12 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU msgfmt. if test "$GMSGFMT" != ":"; then dnl If it is no GNU msgfmt we define it as : so that the dnl Makefiles still can work. if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` AC_MSG_RESULT( [found $GMSGFMT program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi fi dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po fi AC_OUTPUT_COMMANDS([ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) dnl Postprocesses a Makefile in a directory containing PO files. AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], [ # When this code is run, in config.status, two variables have already been # set: # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, # - LINGUAS is the value of the environment variable LINGUAS at configure # time. changequote(,)dnl # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Find a way to echo strings without interpreting backslash. if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then gt_echo='echo' else if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then gt_echo='printf %s\n' else echo_func () { cat < "$ac_file.tmp" if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` cat >> "$ac_file.tmp" < /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` cat >> "$ac_file.tmp" <> "$ac_file.tmp" < #include /* The string "%2$d %1$d", with dollar characters protected from the shell's dollar expansion (possibly an autoconf bug). */ static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; static char buf[100]; int main () { sprintf (buf, format, 33, 55); return (strcmp (buf, "55 33") != 0); }], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no, [ AC_EGREP_CPP(notposix, [ #if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ notposix #endif ], gt_cv_func_printf_posix="guessing no", gt_cv_func_printf_posix="guessing yes") ]) ]) case $gt_cv_func_printf_posix in *yes) AC_DEFINE(HAVE_POSIX_PRINTF, 1, [Define if your printf() function supports format strings with positions.]) ;; esac ]) bareos-Release-14.2.6/autoconf/gettext/progtest.m4000066400000000000000000000055501263011562700220600ustar00rootroot00000000000000# progtest.m4 serial 4 (gettext-0.14.2) dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. AC_PREREQ(2.50) # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [ # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in [[\\/]]* | ?:[[\\/]]*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in ifelse([$5], , $PATH, [$5]); do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) bareos-Release-14.2.6/autoconf/gettext/signed.m4000066400000000000000000000011541263011562700214560ustar00rootroot00000000000000# signed.m4 serial 1 (gettext-0.10.40) dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([bh_C_SIGNED], [ AC_CACHE_CHECK([for signed], bh_cv_c_signed, [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)]) if test $bh_cv_c_signed = no; then AC_DEFINE(signed, , [Define to empty if the C compiler doesn't support this keyword.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/size_max.m4000066400000000000000000000036451263011562700220330ustar00rootroot00000000000000# size_max.m4 serial 2 dnl Copyright (C) 2003 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([gl_SIZE_MAX], [ AC_CHECK_HEADERS(stdint.h) dnl First test whether the system already has SIZE_MAX. AC_MSG_CHECKING([for SIZE_MAX]) result= AC_EGREP_CPP([Found it], [ #include #if HAVE_STDINT_H #include #endif #ifdef SIZE_MAX Found it #endif ], result=yes) if test -z "$result"; then dnl Define it ourselves. Here we assume that the type 'size_t' is not wider dnl than the type 'unsigned long'. dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr', dnl which is guaranteed to work from LONG_MIN to LONG_MAX. _AC_COMPUTE_INT([~(size_t)0 / 10], res_hi, [#include ], result=?) _AC_COMPUTE_INT([~(size_t)0 % 10], res_lo, [#include ], result=?) _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint, [#include ], result=?) if test "$fits_in_uint" = 1; then dnl Even though SIZE_MAX fits in an unsigned int, it must be of type dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. AC_TRY_COMPILE([#include extern size_t foo; extern unsigned long foo; ], [], fits_in_uint=0) fi if test -z "$result"; then if test "$fits_in_uint" = 1; then result="$res_hi$res_lo"U else result="$res_hi$res_lo"UL fi else dnl Shouldn't happen, but who knows... result='~(size_t)0' fi fi AC_MSG_RESULT([$result]) if test "$result" != yes; then AC_DEFINE_UNQUOTED([SIZE_MAX], [$result], [Define as the maximum value of type 'size_t', if the system doesn't define it.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/stdint_h.m4000066400000000000000000000015731263011562700220260ustar00rootroot00000000000000# stdint_h.m4 serial 5 dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert. # Define HAVE_STDINT_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([gl_AC_HEADER_STDINT_H], [ AC_CACHE_CHECK([for stdint.h], gl_cv_header_stdint_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], gl_cv_header_stdint_h=yes, gl_cv_header_stdint_h=no)]) if test $gl_cv_header_stdint_h = yes; then AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) bareos-Release-14.2.6/autoconf/gettext/uintmax_t.m4000066400000000000000000000020761263011562700222210ustar00rootroot00000000000000# uintmax_t.m4 serial 9 dnl Copyright (C) 1997-2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert. AC_PREREQ(2.13) # Define uintmax_t to 'unsigned long' or 'unsigned long long' # if it is not already defined in or . AC_DEFUN([gl_AC_TYPE_UINTMAX_T], [ AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) AC_REQUIRE([gl_AC_HEADER_STDINT_H]) if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then AC_REQUIRE([gl_AC_TYPE_UNSIGNED_LONG_LONG]) test $ac_cv_type_unsigned_long_long = yes \ && ac_type='unsigned long long' \ || ac_type='unsigned long' AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, [Define to unsigned long or unsigned long long if and don't define.]) else AC_DEFINE(HAVE_UINTMAX_T, 1, [Define if you have the 'uintmax_t' type in or .]) fi ]) bareos-Release-14.2.6/autoconf/gettext/ulonglong.m4000066400000000000000000000016151263011562700222130ustar00rootroot00000000000000# ulonglong.m4 serial 4 dnl Copyright (C) 1999-2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert. # Define HAVE_UNSIGNED_LONG_LONG if 'unsigned long long' works. AC_DEFUN([gl_AC_TYPE_UNSIGNED_LONG_LONG], [ AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, [AC_TRY_LINK([unsigned long long ull = 1ULL; int i = 63;], [unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ac_cv_type_unsigned_long_long=yes, ac_cv_type_unsigned_long_long=no)]) if test $ac_cv_type_unsigned_long_long = yes; then AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, [Define if you have the 'unsigned long long' type.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/wchar_t.m4000066400000000000000000000013261263011562700216350ustar00rootroot00000000000000# wchar_t.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl Test whether has the 'wchar_t' type. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_WCHAR_T], [ AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t, [AC_TRY_COMPILE([#include wchar_t foo = (wchar_t)'\0';], , gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)]) if test $gt_cv_c_wchar_t = yes; then AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/wint_t.m4000066400000000000000000000013041263011562700215060ustar00rootroot00000000000000# wint_t.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2003 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl Test whether has the 'wint_t' type. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_WINT_T], [ AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t, [AC_TRY_COMPILE([#include wint_t foo = (wchar_t)'\0';], , gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)]) if test $gt_cv_c_wint_t = yes; then AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.]) fi ]) bareos-Release-14.2.6/autoconf/gettext/xsize.m4000066400000000000000000000006451263011562700213530ustar00rootroot00000000000000# xsize.m4 serial 3 dnl Copyright (C) 2003-2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_XSIZE], [ dnl Prerequisites of lib/xsize.h. AC_REQUIRE([gl_SIZE_MAX]) AC_REQUIRE([AC_C_INLINE]) AC_CHECK_HEADERS(stdint.h) ]) bareos-Release-14.2.6/autoconf/install-sh000077500000000000000000000327251263011562700202730ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2010-02-06.18; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # 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 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: bareos-Release-14.2.6/autoconf/install.sh000077500000000000000000000110541263011562700202640ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 bareos-Release-14.2.6/autoconf/libtool/000077500000000000000000000000001263011562700177225ustar00rootroot00000000000000bareos-Release-14.2.6/autoconf/libtool/libtool.m4000066400000000000000000010572151263011562700216430ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS bareos-Release-14.2.6/autoconf/libtool/ltdl.m4000066400000000000000000000646631263011562700211420ustar00rootroot00000000000000# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- # # Copyright (C) 1999-2006, 2007, 2008, 2011 Free Software Foundation, Inc. # Written by Thomas Tanner, 1999 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 18 LTDL_INIT # LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE]) # ------------------------------------------ # DIRECTORY contains the libltdl sources. It is okay to call this # function multiple times, as long as the same DIRECTORY is always given. AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) _$0($*) ])# LT_CONFIG_LTDL_DIR # We break this out into a separate macro, so that we can call it safely # internally without being caught accidentally by the sed scan in libtoolize. m4_defun([_LT_CONFIG_LTDL_DIR], [dnl remove trailing slashes m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$])) m4_case(_LTDL_DIR, [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply `.' m4_if(_ARG_DIR, [.], [], [m4_define([_LTDL_DIR], _ARG_DIR) _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])], [m4_if(_ARG_DIR, _LTDL_DIR, [], [m4_fatal([multiple libltdl directories: `]_LTDL_DIR[', `]_ARG_DIR['])])]) m4_popdef([_ARG_DIR]) ])# _LT_CONFIG_LTDL_DIR # Initialise: m4_define([_LTDL_DIR], []) # _LT_BUILD_PREFIX # ---------------- # If Autoconf is new enough, expand to `${top_build_prefix}', otherwise # to `${top_builddir}/'. m4_define([_LT_BUILD_PREFIX], [m4_ifdef([AC_AUTOCONF_VERSION], [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]), [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX], [${top_build_prefix}], [${top_builddir}/])], [${top_build_prefix}])], [${top_builddir}/])[]dnl ]) # LTDL_CONVENIENCE # ---------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with # '${top_build_prefix}' if available, otherwise with '${top_builddir}/', # and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single # quotes!). If your package is not flat and you're not using automake, # define top_build_prefix, top_builddir, and top_srcdir appropriately # in your Makefiles. AC_DEFUN([LTDL_CONVENIENCE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_CONVENIENCE # AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], []) # _LTDL_CONVENIENCE # ----------------- # Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]). m4_defun([_LTDL_CONVENIENCE], [case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; esac LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" AC_SUBST([INCLTDL]) ])# _LTDL_CONVENIENCE # LTDL_INSTALLABLE # ---------------- # sets LIBLTDL to the link flags for the libltdl installable library # and LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-install to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl # is not found, LIBLTDL will be prefixed with '${top_build_prefix}' if # available, otherwise with '${top_builddir}/', and LTDLINCL will be # prefixed with '${top_srcdir}/' (note the single quotes!). If your # package is not flat and you're not using automake, define top_build_prefix, # top_builddir, and top_srcdir appropriately in your Makefiles. # In the future, this macro may have to be called after LT_INIT. AC_DEFUN([LTDL_INSTALLABLE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_INSTALLABLE # AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], []) # _LTDL_INSTALLABLE # ----------------- # Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]). m4_defun([_LTDL_INSTALLABLE], [if test -f $prefix/lib/libltdl.la; then lt_save_LDFLAGS="$LDFLAGS" LDFLAGS="-L$prefix/lib $LDFLAGS" AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes]) LDFLAGS="$lt_save_LDFLAGS" if test x"${lt_lib_ltdl-no}" = xyes; then if test x"$enable_ltdl_install" != xyes; then # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install AC_MSG_WARN([not overwriting libltdl at $prefix, force with `--enable-ltdl-install']) enable_ltdl_install=no fi elif test x"$enable_ltdl_install" = xno; then AC_MSG_WARN([libltdl not installed, but installation disabled]) fi fi # If configure.ac declared an installable ltdl, and the user didn't override # with --disable-ltdl-install, we will install the shipped libltdl. case $enable_ltdl_install in no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL="-lltdl" LTDLDEPS= LTDLINCL= ;; *) enable_ltdl_install=yes ac_configure_args="$ac_configure_args --enable-ltdl-install" LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" ;; esac AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" AC_SUBST([INCLTDL]) ])# LTDL_INSTALLABLE # _LTDL_MODE_DISPATCH # ------------------- m4_define([_LTDL_MODE_DISPATCH], [dnl If _LTDL_DIR is `.', then we are configuring libltdl itself: m4_if(_LTDL_DIR, [], [], dnl if _LTDL_MODE was not set already, the default value is `subproject': [m4_case(m4_default(_LTDL_MODE, [subproject]), [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR) _LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"])], [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"; lt_libobj_prefix="$lt_ltdl_dir/"])], [recursive], [], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl dnl Be careful not to expand twice: m4_define([$0], []) ])# _LTDL_MODE_DISPATCH # _LT_LIBOBJ(MODULE_NAME) # ----------------------- # Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead # of into LIBOBJS. AC_DEFUN([_LT_LIBOBJ], [ m4_pattern_allow([^_LT_LIBOBJS$]) _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" ])# _LT_LIBOBJS # LTDL_INIT([OPTIONS]) # -------------------- # Clients of libltdl can use this macro to allow the installer to # choose between a shipped copy of the ltdl sources or a preinstalled # version of the library. If the shipped ltdl sources are not in a # subdirectory named libltdl, the directory name must be given by # LT_CONFIG_LTDL_DIR. AC_DEFUN([LTDL_INIT], [dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) dnl We need to keep our own list of libobjs separate from our parent project, dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while dnl we look for our own LIBOBJs. m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) m4_pushdef([AC_LIBSOURCES]) dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: m4_if(_LTDL_MODE, [], [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) AC_ARG_WITH([included_ltdl], [AS_HELP_STRING([--with-included-ltdl], [use the GNU ltdl sources included here])]) if test "x$with_included_ltdl" != xyes; then # We are not being forced to use the included libltdl sources, so # decide whether there is a useful installed version we can use. AC_CHECK_HEADER([ltdl.h], [AC_CHECK_DECL([lt_dlinterface_register], [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], [with_included_ltdl=no], [with_included_ltdl=yes])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT #include ])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT] ) fi dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE dnl was called yet, then for old times' sake, we assume libltdl is in an dnl eponymous directory: AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) AC_ARG_WITH([ltdl_include], [AS_HELP_STRING([--with-ltdl-include=DIR], [use the ltdl headers installed in DIR])]) if test -n "$with_ltdl_include"; then if test -f "$with_ltdl_include/ltdl.h"; then : else AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include']) fi else with_ltdl_include=no fi AC_ARG_WITH([ltdl_lib], [AS_HELP_STRING([--with-ltdl-lib=DIR], [use the libltdl.la installed in DIR])]) if test -n "$with_ltdl_lib"; then if test -f "$with_ltdl_lib/libltdl.la"; then : else AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib']) fi else with_ltdl_lib=no fi case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in ,yes,no,no,) m4_case(m4_default(_LTDL_TYPE, [convenience]), [convenience], [_LTDL_CONVENIENCE], [installable], [_LTDL_INSTALLABLE], [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) ;; ,no,no,no,) # If the included ltdl is not to be used, then use the # preinstalled libltdl we found. AC_DEFINE([HAVE_LTDL], [1], [Define this if a modern libltdl is already installed]) LIBLTDL=-lltdl LTDLDEPS= LTDLINCL= ;; ,no*,no,*) AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together]) ;; *) with_included_ltdl=no LIBLTDL="-L$with_ltdl_lib -lltdl" LTDLDEPS= LTDLINCL="-I$with_ltdl_include" ;; esac INCLTDL="$LTDLINCL" # Report our decision... AC_MSG_CHECKING([where to find libltdl headers]) AC_MSG_RESULT([$LTDLINCL]) AC_MSG_CHECKING([where to find libltdl library]) AC_MSG_RESULT([$LIBLTDL]) _LTDL_SETUP dnl restore autoconf definition. m4_popdef([AC_LIBOBJ]) m4_popdef([AC_LIBSOURCES]) AC_CONFIG_COMMANDS_PRE([ _ltdl_libobjs= _ltdl_ltlibobjs= if test -n "$_LT_LIBOBJS"; then # Remove the extension. _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" done fi AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) ]) # Only expand once: m4_define([LTDL_INIT]) ])# LTDL_INIT # Old names: AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIB_LTDL], []) dnl AC_DEFUN([AC_WITH_LTDL], []) dnl AC_DEFUN([LT_WITH_LTDL], []) # _LTDL_SETUP # ----------- # Perform all the checks necessary for compilation of the ltdl objects # -- including compiler checks and header checks. This is a public # interface mainly for the benefit of libltdl's own configure.ac, most # other users should call LTDL_INIT instead. AC_DEFUN([_LTDL_SETUP], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_SYS_MODULE_EXT])dnl AC_REQUIRE([LT_SYS_MODULE_PATH])dnl AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl AC_REQUIRE([LT_LIB_DLLOAD])dnl AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl AC_REQUIRE([gl_FUNC_ARGZ])dnl m4_require([_LT_CHECK_OBJDIR])dnl m4_require([_LT_HEADER_DLFCN])dnl m4_require([_LT_CHECK_DLPREOPEN])dnl m4_require([_LT_DECL_SED])dnl dnl Don't require this, or it will be expanded earlier than the code dnl that sets the variables it relies on: _LT_ENABLE_INSTALL dnl _LTDL_MODE specific code must be called at least once: _LTDL_MODE_DISPATCH # In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS # the user used. This is so that ltdl.h can pick up the parent projects # config.h file, The first file in AC_CONFIG_HEADERS must contain the # definitions required by ltdl.c. # FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). AC_CONFIG_COMMANDS_PRE([dnl m4_pattern_allow([^LT_CONFIG_H$])dnl m4_ifset([AH_HEADER], [LT_CONFIG_H=AH_HEADER], [m4_ifset([AC_LIST_HEADERS], [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[ ]]*,,;s,[[ :]].*$,,'`], [])])]) AC_SUBST([LT_CONFIG_H]) AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) m4_pattern_allow([LT_LIBEXT])dnl AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) name= eval "lt_libprefix=\"$libname_spec\"" m4_pattern_allow([LT_LIBPREFIX])dnl AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix]) name=ltdl eval "LTDLOPEN=\"$libname_spec\"" AC_SUBST([LTDLOPEN]) ])# _LTDL_SETUP # _LT_ENABLE_INSTALL # ------------------ m4_define([_LT_ENABLE_INSTALL], [AC_ARG_ENABLE([ltdl-install], [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])]) case ,${enable_ltdl_install},${enable_ltdl_convenience} in *yes*) ;; *) enable_ltdl_convenience=yes ;; esac m4_ifdef([AM_CONDITIONAL], [AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)]) ])# _LT_ENABLE_INSTALL # LT_SYS_DLOPEN_DEPLIBS # --------------------- AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether deplibs are loaded by dlopen], [lt_cv_sys_dlopen_deplibs], [# PORTME does your system automatically load deplibs for dlopen? # or its logical equivalent (e.g. shl_load for HP-UX < 11) # For now, we just catch OSes we know something about -- in the # future, we'll try test this programmatically. lt_cv_sys_dlopen_deplibs=unknown case $host_os in aix3*|aix4.1.*|aix4.2.*) # Unknown whether this is true for these versions of AIX, but # we want this `case' here to explicitly catch those versions. lt_cv_sys_dlopen_deplibs=unknown ;; aix[[4-9]]*) lt_cv_sys_dlopen_deplibs=yes ;; amigaos*) case $host_cpu in powerpc) lt_cv_sys_dlopen_deplibs=no ;; esac ;; darwin*) # Assuming the user has installed a libdl from somewhere, this is true # If you are looking for one http://www.opendarwin.org/projects/dlcompat lt_cv_sys_dlopen_deplibs=yes ;; freebsd* | dragonfly*) lt_cv_sys_dlopen_deplibs=yes ;; gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) # GNU and its variants, using gnu ld.so (Glibc) lt_cv_sys_dlopen_deplibs=yes ;; hpux10*|hpux11*) lt_cv_sys_dlopen_deplibs=yes ;; interix*) lt_cv_sys_dlopen_deplibs=yes ;; irix[[12345]]*|irix6.[[01]]*) # Catch all versions of IRIX before 6.2, and indicate that we don't # know how it worked for any of those versions. lt_cv_sys_dlopen_deplibs=unknown ;; irix*) # The case above catches anything before 6.2, and it's known that # at 6.2 and later dlopen does load deplibs. lt_cv_sys_dlopen_deplibs=yes ;; netbsd*) lt_cv_sys_dlopen_deplibs=yes ;; openbsd*) lt_cv_sys_dlopen_deplibs=yes ;; osf[[1234]]*) # dlopen did load deplibs (at least at 4.x), but until the 5.x series, # it did *not* use an RPATH in a shared library to find objects the # library depends on, so we explicitly say `no'. lt_cv_sys_dlopen_deplibs=no ;; osf5.0|osf5.0a|osf5.1) # dlopen *does* load deplibs and with the right loader patch applied # it even uses RPATH in a shared library to search for shared objects # that the library depends on, but there's no easy way to know if that # patch is installed. Since this is the case, all we can really # say is unknown -- it depends on the patch being installed. If # it is, this changes to `yes'. Without it, it would be `no'. lt_cv_sys_dlopen_deplibs=unknown ;; osf*) # the two cases above should catch all versions of osf <= 5.1. Read # the comments above for what we know about them. # At > 5.1, deplibs are loaded *and* any RPATH in a shared library # is used to find them so we can finally say `yes'. lt_cv_sys_dlopen_deplibs=yes ;; qnx*) lt_cv_sys_dlopen_deplibs=yes ;; solaris*) lt_cv_sys_dlopen_deplibs=yes ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) libltdl_cv_sys_dlopen_deplibs=yes ;; esac ]) if test "$lt_cv_sys_dlopen_deplibs" != yes; then AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], [Define if the OS needs help to load dependent libraries for dlopen().]) fi ])# LT_SYS_DLOPEN_DEPLIBS # Old name: AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], []) # LT_SYS_MODULE_EXT # ----------------- AC_DEFUN([LT_SYS_MODULE_EXT], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([which extension is used for runtime loadable modules], [libltdl_cv_shlibext], [ module=yes eval libltdl_cv_shlibext=$shrext_cmds module=no eval libltdl_cv_shrext=$shrext_cmds ]) if test -n "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_MODULE_EXT])dnl AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], [Define to the extension used for runtime loadable modules, say, ".so".]) fi if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_SHARED_EXT])dnl AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"], [Define to the shared library suffix, say, ".dylib".]) fi ])# LT_SYS_MODULE_EXT # Old name: AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBEXT], []) # LT_SYS_MODULE_PATH # ------------------ AC_DEFUN([LT_SYS_MODULE_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([which variable specifies run-time module search path], [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"]) if test -n "$lt_cv_module_path_var"; then m4_pattern_allow([LT_MODULE_PATH_VAR])dnl AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], [Define to the name of the environment variable that determines the run-time module search path.]) fi ])# LT_SYS_MODULE_PATH # Old name: AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBPATH], []) # LT_SYS_DLSEARCH_PATH # -------------------- AC_DEFUN([LT_SYS_DLSEARCH_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([for the default library search path], [lt_cv_sys_dlsearch_path], [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"]) if test -n "$lt_cv_sys_dlsearch_path"; then sys_dlsearch_path= for dir in $lt_cv_sys_dlsearch_path; do if test -z "$sys_dlsearch_path"; then sys_dlsearch_path="$dir" else sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" fi done m4_pattern_allow([LT_DLSEARCH_PATH])dnl AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], [Define to the system default library search path.]) fi ])# LT_SYS_DLSEARCH_PATH # Old name: AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], []) # _LT_CHECK_DLPREOPEN # ------------------- m4_defun([_LT_CHECK_DLPREOPEN], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], [libltdl_cv_preloaded_symbols], [if test -n "$lt_cv_sys_global_symbol_pipe"; then libltdl_cv_preloaded_symbols=yes else libltdl_cv_preloaded_symbols=no fi ]) if test x"$libltdl_cv_preloaded_symbols" = xyes; then AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], [Define if libtool can extract symbol lists from object files.]) fi ])# _LT_CHECK_DLPREOPEN # LT_LIB_DLLOAD # ------------- AC_DEFUN([LT_LIB_DLLOAD], [m4_pattern_allow([^LT_DLLOADERS$]) LT_DLLOADERS= AC_SUBST([LT_DLLOADERS]) AC_LANG_PUSH([C]) LIBADD_DLOPEN= AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) if test "$ac_cv_search_dlopen" != "none required" ; then LIBADD_DLOPEN="-ldl" fi libltdl_cv_lib_dl_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H # include #endif ]], [[dlopen(0, 0);]])], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_CHECK_LIB([svld], [dlopen], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" AC_CHECK_FUNCS([dlerror]) LIBS="$lt_save_LIBS" fi AC_SUBST([LIBADD_DLOPEN]) LIBADD_SHL_LOAD= AC_CHECK_FUNC([shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], [AC_CHECK_LIB([dld], [shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD="-ldld"])]) AC_SUBST([LIBADD_SHL_LOAD]) case $host_os in darwin[[1567]].*) # We only want this for pre-Mac OS X 10.4. AC_CHECK_FUNC([_dyld_func_lookup], [AC_DEFINE([HAVE_DYLD], [1], [Define if you have the _dyld_func_lookup function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | os2* | pw32*) AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include ]]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac AC_CHECK_LIB([dld], [dld_link], [AC_DEFINE([HAVE_DLD], [1], [Define if you have the GNU dld library.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) AC_SUBST([LIBADD_DLD_LINK]) m4_pattern_allow([^LT_DLPREOPEN$]) LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done AC_DEFINE([HAVE_LIBDLLOADER], [1], [Define if libdlloader will be built on this platform]) fi AC_SUBST([LT_DLPREOPEN]) dnl This isn't used anymore, but set it for backwards compatibility LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" AC_SUBST([LIBADD_DL]) AC_LANG_POP ])# LT_LIB_DLLOAD # Old name: AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLLIB], []) # LT_SYS_SYMBOL_USCORE # -------------------- # does the compiler prefix global symbols with an underscore? AC_DEFUN([LT_SYS_SYMBOL_USCORE], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([for _ prefix in compiled symbols], [lt_cv_sys_symbol_underscore], [lt_cv_sys_symbol_underscore=no cat > conftest.$ac_ext <<_LT_EOF void nm_test_func(){} int main(){nm_test_func;return 0;} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. ac_nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then # See whether the symbols have a leading underscore. if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then lt_cv_sys_symbol_underscore=yes else if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then : else echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD fi fi else echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.c >&AS_MESSAGE_LOG_FD fi rm -rf conftest* ]) sys_symbol_underscore=$lt_cv_sys_symbol_underscore AC_SUBST([sys_symbol_underscore]) ])# LT_SYS_SYMBOL_USCORE # Old name: AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], []) # LT_FUNC_DLSYM_USCORE # -------------------- AC_DEFUN([LT_FUNC_DLSYM_USCORE], [AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl if test x"$lt_cv_sys_symbol_underscore" = xyes; then if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then AC_CACHE_CHECK([whether we have to add an underscore for dlsym], [libltdl_cv_need_uscore], [libltdl_cv_need_uscore=unknown save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" _LT_TRY_DLOPEN_SELF( [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], [], [libltdl_cv_need_uscore=cross]) LIBS="$save_LIBS" ]) fi fi if test x"$libltdl_cv_need_uscore" = xyes; then AC_DEFINE([NEED_USCORE], [1], [Define if dlsym() requires a leading underscore in symbol names.]) fi ])# LT_FUNC_DLSYM_USCORE # Old name: AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) bareos-Release-14.2.6/autoconf/libtool/ltoptions.m4000066400000000000000000000300711263011562700222200ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) bareos-Release-14.2.6/autoconf/libtool/ltsugar.m4000066400000000000000000000104241263011562700216460ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) bareos-Release-14.2.6/autoconf/libtool/ltversion.m4000066400000000000000000000012621263011562700222120ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) bareos-Release-14.2.6/autoconf/libtool/lt~obsolete.m4000066400000000000000000000137551263011562700225510ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) bareos-Release-14.2.6/autoconf/ltmain.sh000066400000000000000000010517721263011562700201130ustar00rootroot00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.2 TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -soname SONAME override the standard shared object name -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; soname) soname_spec="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -soname) prev=soname continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 bareos-Release-14.2.6/autoconf/mkinstalldirs000077500000000000000000000065351263011562700210750ustar00rootroot00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2004-02-15.20 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit 0 ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: bareos-Release-14.2.6/autoconf/python.conf.py000066400000000000000000000005411263011562700210750ustar00rootroot00000000000000import sys import os from distutils import sysconfig print 'PYTHON_INC="-I%s"' % \ ( sysconfig.get_config_var('INCLUDEPY'), ) libdir=sysconfig.get_config_var('LIBPL') filename = sysconfig.get_config_var('LDLIBRARY'); lib = os.path.splitext(filename)[0]; if lib[0:3] == 'lib': lib = lib[3:] print 'PYTHON_LIBS="-L%s -l%s"' % ( libdir, lib ) bareos-Release-14.2.6/autoconf/randpass000077500000000000000000000012541263011562700200210ustar00rootroot00000000000000#! /bin/sh # # Generate a random password, written to standard output # By John Walker # LANG=C if test "x$1" = "x" ; then PWL=48 # Password length in characters else PWL=$1 fi tmp=`mktemp randpass.XXXXXXXXXX` if test x$tmp = x; then tmp=/tmp/p.tmp.$$ if test -f $tmp; then echo "Temp file security problem on: $tmp" exit 1 fi fi cp autoconf/randpass.bc $tmp ps | sum | tr -d ':[:alpha:] ' | sed 's/^/k=/' >>$tmp date | tr -d ':[:alpha:] ' | sed 's/^/k=k*/' >>$tmp ls -l /tmp | sum | tr -d ':[:alpha:] ' | sed 's/^/k=k*/' >>$tmp echo "j=s(k); for (i = 0; i < $PWL; i++) r()" >>$tmp echo "quit" >>$tmp bc $tmp | awk -f autoconf/randpass.awk rm $tmp bareos-Release-14.2.6/autoconf/randpass.awk000066400000000000000000000006151263011562700205770ustar00rootroot00000000000000 # Dumb little AWK program to convert random decimal # values generated by rand.bc into passwords from the # character set defined below as "charset". BEGIN { charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" for (i = 0; i < length(charset); i++) { set[i] = substr(charset, i, 1) } } { printf "%s", set[$1 % length(charset)] } END { printf "\n" } bareos-Release-14.2.6/autoconf/randpass.bc000066400000000000000000000023231263011562700203770ustar00rootroot00000000000000 /* "bc" implementation of the "Minimal Standard" multiplicative congruential generator of Park and Miller. [Park, S.K. and K.W. Miller, Communications of the ACM 31, 1192-1201 (1988).] The generation algorithm is: I[j+1] = (I[j] 16807) & 0x7FFFFFFF Note that the intermediate value of the multiplication by 16807 (7^5) exceeds that representable in 32 bits; this has deterred use of this generator in most portable languages. Fortunately, bc computes with arbitrary precision so this poses no problem. Designed and implemented in September 2002 by John Walker, http://www.fourmilab.ch/. */ /* Initialise state to default value of 1. */ t = 1 /* Generate and return the next random byte, updating the state t. */ define r() { t = (t * 16807) % (2^31) return ((t / 2048) % (2^8)) } /* Set the seed to the x argument. The state t is set from the seed, after an initial shuffle. If you don't want 0 printed when setting the seed, assign s(x) to a junk variable. */ define s(x) { auto i, j if (x == 0) { "Seed must be nonzero"; return } t = x % (2^32) /* Perform initial shuffle of state. */ for (i = 0; i < 11; i++) j = r() } bareos-Release-14.2.6/configure000077500000000000000000036466521263011562700163750ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for bareos 14.2.6. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bareos' PACKAGE_TARNAME='bareos' PACKAGE_VERSION='14.2.6' PACKAGE_STRING='bareos 14.2.6' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/include/version.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_list= ac_subst_vars='LTLIBOBJS INSTALL_SD_CONFS BUILD_SD_BACKENDS BUILD_DIR_PLUGINS BUILD_SD_PLUGINS BUILD_FD_PLUGINS COMPRESS_MANPAGES DISTVER DISTNAME MACOSX PSCMD TAPEDRIVE SYSTEMD_UNITDIR SOCKLIBS WRAPLIBS WLDFLAGS WCFLAGS DLIB DINCLUDE DEBUG CAP_LIBS CEPHFS_LIBS CEPHFS_INC RADOS_LIBS RADOS_INC DROPLET_LIBS DROPLET_INC GLUSTER_LIBS GLUSTER_INC CAM_LIBS XATTR_LIBS_NONSHARED XATTR_LIBS ACL_LIBS_NONSHARED ACL_LIBS AFS_LIBS_NONSHARED AFS_LIBS AFS_CFLAGS FASTLZ_LIBS_NONSHARED FASTLZ_LIBS FASTLZ_INC LZO_LIBS_NONSHARED LZO_LIBS LZO_INC ZLIB_LIBS_NONSHARED ZLIB_LIBS ZLIB_INC LIBOBJS X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF GETCONF SHARED_CATALOG_TARGETS LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET DEFAULT_DB_TYPE DB_LIBS DB_BACKENDS uncomment_dbi SQLITE_BINDIR SQLITE_INCLUDE SQLITE_LIBS MYSQL_BINDIR MYSQL_INCLUDE MYSQL_LIBS POSTGRESQL_BINDIR POSTGRESQL_INCLUDE POSTGRESQL_LIBS LMDB_DEPS LMDB_LIBS LMDB_DIR NDMP_DEPS NDMP_LIBS NDMP_DIR logrotate_su LOGROTATE SBINPERM fd_group fd_user sd_group sd_user dir_group dir_user db_port db_password db_user db_name mon_sd_password mon_fd_password mon_dir_password sd_password fd_password dir_password sd_port fd_port dir_port baseport subsysdir piddir smtp_host job_email dump_email configtemplatedir plugindir logdir bsrdir backenddir scriptdir hostname basename archivedir working_dir GNUTLS_LIBS_NONSHARED GNUTLS_INC GNUTLS_LIBS OPENSSL_LIBS_NONSHARED OPENSSL_INC OPENSSL_LIBS PYTHON_INC PYTHON_LIBS DEBIAN_CONTROL READLINE_SRC CONS_LDFLAGS CONS_LIBS CONS_SRC CONS_INC SD_BACKENDS_DIR NEEDED_BACKEND_LIBS NEEDED_DEVICE_API_SRCS SD_PLUGIN_DIR STORED_DIR DIR_PLUGIN_DIR DIRD_DIR ALL_DIRS STATIC_CONS STATIC_DIR STATIC_SD STATIC_FD TTOOL_LDFLAGS TRAY_MONITOR_DIR BAT_DIR INTL_LIBTOOL_SUFFIX_PREFIX INTLOBJS GENCAT INSTOBJEXT DATADIRNAME CATOBJEXT USE_INCLUDED_LIBINTL BUILD_INCLUDED_LIBINTL INTLBISON HAVE_WPRINTF HAVE_SNPRINTF HAVE_ASPRINTF HAVE_POSIX_PRINTF GLIBC21 ALLOCA GLIBC2 POSUB LTLIBINTL LIBINTL INTLLIBS LTLIBICONV LIBICONV INTL_MACOSX_LIBS MSGMERGE XGETTEXT GMSGFMT MSGFMT USE_NLS MKINSTALLDIRS SET_MAKE OBS_SRCMD5 OBS_ARCH OBS_DISTRIBUTION OBS_PROJECT HAVE_DARWIN_OS_FALSE HAVE_DARWIN_OS_TRUE HAVE_IRIX_OS_FALSE HAVE_IRIX_OS_TRUE HAVE_SGI_OS_FALSE HAVE_SGI_OS_TRUE HAVE_BSDI_OS_FALSE HAVE_BSDI_OS_TRUE HAVE_OPENBSD_OS_FALSE HAVE_OPENBSD_OS_TRUE HAVE_NETBSD_OS_FALSE HAVE_NETBSD_OS_TRUE HAVE_FREEBSD_OS_FALSE HAVE_FREEBSD_OS_TRUE HAVE_LINUX_OS_FALSE HAVE_LINUX_OS_TRUE HAVE_HPUX_OS_FALSE HAVE_HPUX_OS_TRUE HAVE_AIX_OS_FALSE HAVE_AIX_OS_TRUE HAVE_OSF1_OS_FALSE HAVE_OSF1_OS_TRUE HAVE_HURD_OS_FALSE HAVE_HURD_OS_TRUE HAVE_SUN_OS_FALSE HAVE_SUN_OS_TRUE INCLUDE_INSTALL_TARGET FD_PLUGIN_DIR QMAKE_LIBTOOL LIBTOOL_CLEAN_TARGET LIBTOOL_INSTALL_TARGET DEFAULT_SHARED_OBJECT_TYPE DEFAULT_ARCHIVE_TYPE DEFAULT_OBJECT_TYPE LIBADD_DL LT_DLPREOPEN LIBADD_DLD_LINK LIBADD_SHL_LOAD LIBADD_DLOPEN LT_DLLOADERS CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB STRIP ac_ct_AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL LOCAL_DEFS LOCAL_LDFLAGS LOCAL_CFLAGS LOCAL_LIBS MAKE_SHELL ARFLAGS AWK MDB DBX GDB GCORE PGREP PIDOF GMAKE QMAKE PKGCONFIG PYTHON DD MTX OPENSSL AR TBL CMP SED CP ECHOCMD REMOVE MV INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM EGREP GREP CPP ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC LIBBAREOSSD_LT_RELEASE LIBBAREOSLMDB_LT_RELEASE LIBBAREOSNDMP_LT_RELEASE LIBBAREOSFIND_LT_RELEASE LIBBAREOSCATS_LT_RELEASE LIBBAREOSSQL_LT_RELEASE LIBBAREOSCFG_LT_RELEASE LIBBAREOS_LT_RELEASE BDB_VERSION post_host BAREOS LSMDATE DATE VERSION FALSEPRG TRUEPRG TOP_DIR BUILD_DIR target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='DEBIAN_CONTROL_BAT DEBIAN_CONTROL_TRAYMONITOR DEBIAN_CONTROL_UNIVENTION_BAREOS DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA MCOMMON DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN' ac_user_opts=' enable_option_checking enable_libtool enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_includes enable_nls enable_rpath with_libiconv_prefix with_libintl_prefix with_included_gettext enable_bat enable_traymonitor enable_smartalloc enable_lockmgr enable_static_tools enable_static_fd enable_static_sd enable_static_dir enable_static_cons enable_client_only enable_build_dird enable_build_stored enable_dynamic_storage_backends enable_conio enable_ipv6 enable_readline with_readline enable_dynamic_debian_package_list with_python with_tcp_wrappers enable_crypto enable_tls with_openssl with_gnutls with_working_dir with_archivedir with_basename with_hostname with_scriptdir with_backenddir with_bsrdir with_logdir with_plugindir with_configtemplatedir with_dump_email with_job_email with_smtp_host with_pid_dir with_subsys_dir with_baseport with_dir_password with_fd_password with_sd_password with_mon_dir_password with_mon_fd_password with_mon_sd_password with_db_name with_db_user with_db_password with_db_port with_dir_user with_dir_group with_sd_user with_sd_group with_fd_user with_fd_group with_sbin_perm enable_ndmp enable_lmdb enable_batch_insert enable_dynamic_cats_backends enable_sql_pooling with_postgresql with_mysql with_embedded_mysql with_sqlite3 enable_largefile with_x with_zlib with_lzo with_fastlz enable_afs with_afsdir enable_acl enable_xattr enable_scsi_crypto with_glusterfs with_droplet with_rados with_cephfs with_systemd ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP CXXCPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures bareos 14.2.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/bareos] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of bareos 14.2.6:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-libtool enable building using GNU libtool [default=yes] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=no] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-includes enable installing of include files [default=no] --disable-nls do not use Native Language Support --disable-rpath do not hardcode runtime library paths --enable-bat enable build of bat Qt4 GUI [default=no] --enable-traymonitor enable build of traymonitor [default=no] --enable-smartalloc enable smartalloc debugging support [default=no] --enable-lockmgr enable lock manager support [default=no] --enable-static-tools enable static tape tools [default=no] --enable-static-fd enable static File daemon [default=no] --enable-static-sd enable static Storage daemon [default=no] --enable-static-dir enable static Director [default=no] --enable-static-cons enable static Console [default=no] --enable-client-only build client (File daemon) only [default=no] --enable-build-dird enable building of dird (Director) [default=yes] --enable-build-stored enable building of stored (Storage daemon) [default=yes] --enable-dynamic-storage-backends enable dynamic loading of storage backends [default=no] --disable-conio disable conio support [default=no] --enable-ipv6 enable ipv6 support [default=yes] --disable-readline disable readline support [default=yes] --enable-dynamic-debian-package-list generate debian/control depending on configured options [default=no] --disable-crypto disable crypto support [default=auto] --disable-tls disable TLS support [default=auto] --enable-ndmp enable build of NDMP support [default=no] --enable-lmdb enable build of LMDB support [default=no] --enable-batch-insert enable the DB batch insert code [default=yes] --enable-dynamic-cats-backends enable dynamic loading of catalog backends [default=no] --enable-sql-pooling enable sql pooling support [default=no] --disable-largefile omit support for large files --disable-afs disable afs support [default=auto] --disable-acl disable acl support [default=auto] --disable-xattr disable xattr support [default=auto] --enable-scsi-crypto enable low level SCSI crypto support [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-gnu-ld assume the C compiler uses GNU ld default=no --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib --without-libintl-prefix don't search for libintl in includedir and libdir --with-included-gettext use the GNU gettext library included here --with-readline[=DIR] specify readline library directory --with-python[=DIR] Include Python support. DIR is the Python base install directory, default is to search through a number of common places for the Python files. --with-tcp-wrappers[=DIR] enable tcpwrappers support --with-openssl[=DIR] Include OpenSSL support. DIR is the OpenSSL base --with-gnutls[=DIR] Include GNUTLS support. DIR is the GNUTLS base --with-working-dir=PATH specify path of Bareos working directory --with-archivedir=PATH specify path of SD archive directory --with-basename=RESNAME specify base resource name for daemons --with-hostname=RESNAME specify host name for daemons --with-scriptdir=PATH specify path of Bareos scripts directory --with-backenddir=PATH specify path of Bareos backends directory --with-bsrdir=PATH specify path of Bareos bsrs directory --with-logdir=PATH specify path of Bareos logs directory --with-plugindir=PATH specify path of Bareos plugins directory --with-configtemplatedir=PATH specify path of Bareos configuration templates directory (Debian only) --with-dump-email=EMAIL dump email address --with-job-email=EMAIL job output email address --with-smtp-host=HOST SMTP mail host address --with-pid-dir=PATH specify location of Bareos pid files --with-subsys-dir=PATH specify location of Bareos subsys file --with-baseport=PORT specify base port address for daemons --with-dir-password=PASSWORD specify Director's password --with-fd-password=PASSWORD specify Client's password --with-sd-password=PASSWORD specify Storage daemon's password --with-mon-dir-password=PASSWORD specify Director's password used by the monitor --with-mon-fd-password=PASSWORD specify Client's password used by the monitor --with-mon-sd-password=PASSWORD specify Storage daemon's password used by the monitor --with-db-name=DBNAME specify database name [default=bareos] --with-db-user=UNAME specify database user [default=bareos] --with-db-password=PWD specify database password [default=*none*] --with-db-port=DBPORT specify a database port [default=null] --with-dir-user=USER specify user for Director daemon --with-dir-group=GROUP specify group for Director daemon --with-sd-user=USER specify user for Storage daemon --with-sd-group=GROUP specify group for Storage daemon --with-fd-user=USER specify user for File daemon --with-fd-group=GROUP specify group for File daemon --with-sbin-perm=MODE specify permissions for sbin binaries [default=0750] --with-postgresql[=DIR] Include PostgreSQL support. DIR is the PostgreSQL base install directory, [default=/usr/local/pgsql] --with-mysql[=DIR] Include MySQL support. DIR is the MySQL base install directory, default is to search through a number of common places for the MySQL files. --with-embedded-mysql[=DIR] Include MySQL support. DIR is the MySQL base install directory, default is to search through a number of common places for the MySQL files. --with-sqlite3[=DIR] Include SQLite3 support. DIR is the SQLite3 base install directory, default is to search through a number of common places for the SQLite3 files. --with-x use the X Window System --with-zlib[=DIR] Directory holding zlib includes/libs --with-lzo[=DIR] Directory holding lzo includes/libs --with-fastlz[=DIR] Directory holding fastlz includes/libs --with-afsdir[=DIR] Directory holding AFS includes/libs --with-glusterfs[=DIR] Directory holding GLUSTERFS includes/libs --with-droplet[=DIR] Directory holding DROPLET includes/libs --with-rados[=DIR] Directory holding RADOS includes/libs --with-cephfs[=DIR] Directory holding CEPHFS includes/libs --with-systemd[=UNITDIR] Include systemd support. UNITDIR is where systemd system .service files are located, default is to ask systemctl. Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP C++ preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF bareos configure 14.2.6 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by bareos $as_me 14.2.6, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_list " stdlib.h" as_fn_append ac_header_list " unistd.h" as_fn_append ac_header_list " sys/param.h" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu BUILD_DIR=`pwd` cd .. TOP_DIR=`pwd` cd ${BUILD_DIR} ac_aux_dir= for ac_dir in ${BUILD_DIR}/autoconf "$srcdir"/${BUILD_DIR}/autoconf; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in ${BUILD_DIR}/autoconf \"$srcdir\"/${BUILD_DIR}/autoconf" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_headers="$ac_config_headers src/include/config.h:autoconf/config.h.in" for ac_prog in true do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TRUEPRG+:} false; then : $as_echo_n "(cached) " >&6 else case $TRUEPRG in [\\/]* | ?:[\\/]*) ac_cv_path_TRUEPRG="$TRUEPRG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TRUEPRG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi TRUEPRG=$ac_cv_path_TRUEPRG if test -n "$TRUEPRG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TRUEPRG" >&5 $as_echo "$TRUEPRG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$TRUEPRG" && break done test -n "$TRUEPRG" || TRUEPRG=":" for ac_prog in false do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_FALSEPRG+:} false; then : $as_echo_n "(cached) " >&6 else case $FALSEPRG in [\\/]* | ?:[\\/]*) ac_cv_path_FALSEPRG="$FALSEPRG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_FALSEPRG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi FALSEPRG=$ac_cv_path_FALSEPRG if test -n "$FALSEPRG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FALSEPRG" >&5 $as_echo "$FALSEPRG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$FALSEPRG" && break done test -n "$FALSEPRG" || FALSEPRG=":" post_host= if test "x$BAREOS" != x; then post_host=`echo -${BAREOS} | tr 'A-Z ' 'a-z-'` fi BAREOS=${BAREOS:-Bareos} VERSION=`sed -n -e 's/^.*VERSION.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` DATE=`sed -n -e 's/^.* \t*BDATE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LSMDATE=`sed -n -e 's/^.*LSMDATE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` BDB_VERSION=`sed -n -e 's/^.*BDB_VERSION \(.*\)$/\1/p' ${srcdir}/src/cats/cats.h` LIBBAREOS_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOS_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSCFG_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSCFG_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOS_LT_RELEASE=${LIBBAREOS_LT_RELEASE:-$VERSION} LIBBAREOSCFG_LT_RELEASE=${LIBBAREOSCFG_LT_RELEASE:-$VERSION} LIBBAREOSSQL_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSSQL_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSCATS_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSCATS_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSSQL_LT_RELEASE=${LIBBAREOSSQL_LT_RELEASE:-$VERSION} LIBBAREOSCATS_LT_RELEASE=${LIBBAREOSCATS_LT_RELEASE:-$VERSION} LIBBAREOSFIND_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSFIND_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSFIND_LT_RELEASE=${LIBBAREOSFIND_LT_RELEASE:-$VERSION} LIBBAREOSNDMP_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSNDMP_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSNDMP_LT_RELEASE=${LIBBAREOSNDMP_LT_RELEASE:-$VERSION} LIBBAREOSLMDB_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSLMDB_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSLMDB_LT_RELEASE=${LIBBAREOSLMDB_LT_RELEASE:-$VERSION} LIBBAREOSSD_LT_RELEASE=`sed -n -e 's/^#.*LIBBAREOSCATS_LT_RELEASE.*"\(.*\)"$/\1/p' ${srcdir}/src/include/version.h` LIBBAREOSSD_LT_RELEASE=${LIBBAREOSLMDB_LT_RELEASE:-$VERSION} echo "configuring for ${BAREOS} $VERSION ($DATE)" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x$CC" != xcc; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if ${ac_cv_prog_gcc_traditional+:} false; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi BASECC=`basename $CC` have_gcc=no if test "x$BASECC" = xgcc; then $as_echo "#define HAVE_GCC 1" >>confdefs.h have_gcc=yes fi # Extract the first word of "$CXX", so it can be a program name with args. set dummy $CXX; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $CXX in [\\/]* | ?:[\\/]*) ac_cv_path_CXX="$CXX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CXX" && ac_cv_path_CXX="$CXX" ;; esac fi CXX=$ac_cv_path_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test ! -e $CXX; then as_fn_error $? "Unable to find C++ compiler" "$LINENO" 5 fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "mv", so it can be a program name with args. set dummy mv; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MV+:} false; then : $as_echo_n "(cached) " >&6 else case $MV in [\\/]* | ?:[\\/]*) ac_cv_path_MV="$MV" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MV=$ac_cv_path_MV if test -n "$MV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MV" >&5 $as_echo "$MV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "rm", so it can be a program name with args. set dummy rm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_REMOVE+:} false; then : $as_echo_n "(cached) " >&6 else case $REMOVE in [\\/]* | ?:[\\/]*) ac_cv_path_REMOVE="$REMOVE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_REMOVE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi REMOVE=$ac_cv_path_REMOVE if test -n "$REMOVE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $REMOVE" >&5 $as_echo "$REMOVE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "echo", so it can be a program name with args. set dummy echo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ECHOCMD+:} false; then : $as_echo_n "(cached) " >&6 else case $ECHOCMD in [\\/]* | ?:[\\/]*) ac_cv_path_ECHOCMD="$ECHOCMD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ECHOCMD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ECHOCMD=$ac_cv_path_ECHOCMD if test -n "$ECHOCMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ECHOCMD" >&5 $as_echo "$ECHOCMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "cp", so it can be a program name with args. set dummy cp; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CP+:} false; then : $as_echo_n "(cached) " >&6 else case $CP in [\\/]* | ?:[\\/]*) ac_cv_path_CP="$CP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CP=$ac_cv_path_CP if test -n "$CP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 $as_echo "$CP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 $as_echo "$SED" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "cmp", so it can be a program name with args. set dummy cmp; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CMP+:} false; then : $as_echo_n "(cached) " >&6 else case $CMP in [\\/]* | ?:[\\/]*) ac_cv_path_CMP="$CMP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CMP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CMP=$ac_cv_path_CMP if test -n "$CMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CMP" >&5 $as_echo "$CMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "tbl", so it can be a program name with args. set dummy tbl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TBL+:} false; then : $as_echo_n "(cached) " >&6 else case $TBL in [\\/]* | ?:[\\/]*) ac_cv_path_TBL="$TBL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TBL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi TBL=$ac_cv_path_TBL if test -n "$TBL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TBL" >&5 $as_echo "$TBL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AR+:} false; then : $as_echo_n "(cached) " >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "openssl", so it can be a program name with args. set dummy openssl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_OPENSSL+:} false; then : $as_echo_n "(cached) " >&6 else case $OPENSSL in [\\/]* | ?:[\\/]*) ac_cv_path_OPENSSL="$OPENSSL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_OPENSSL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi OPENSSL=$ac_cv_path_OPENSSL if test -n "$OPENSSL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL" >&5 $as_echo "$OPENSSL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "mtx", so it can be a program name with args. set dummy mtx; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MTX+:} false; then : $as_echo_n "(cached) " >&6 else case $MTX in [\\/]* | ?:[\\/]*) ac_cv_path_MTX="$MTX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MTX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MTX=$ac_cv_path_MTX if test -n "$MTX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MTX" >&5 $as_echo "$MTX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "dd", so it can be a program name with args. set dummy dd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DD+:} false; then : $as_echo_n "(cached) " >&6 else case $DD in [\\/]* | ?:[\\/]*) ac_cv_path_DD="$DD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DD=$ac_cv_path_DD if test -n "$DD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DD" >&5 $as_echo "$DD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "python", so it can be a program name with args. set dummy python; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKGCONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKGCONFIG=$ac_cv_path_PKGCONFIG if test -n "$PKGCONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 $as_echo "$PKGCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "qmake", so it can be a program name with args. set dummy qmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_QMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $QMAKE in [\\/]* | ?:[\\/]*) ac_cv_path_QMAKE="$QMAKE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_QMAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi QMAKE=$ac_cv_path_QMAKE if test -n "$QMAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $QMAKE" >&5 $as_echo "$QMAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gmake", so it can be a program name with args. set dummy gmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $GMAKE in [\\/]* | ?:[\\/]*) ac_cv_path_GMAKE="$GMAKE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GMAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GMAKE=$ac_cv_path_GMAKE if test -n "$GMAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMAKE" >&5 $as_echo "$GMAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "pidof", so it can be a program name with args. set dummy pidof; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PIDOF+:} false; then : $as_echo_n "(cached) " >&6 else case $PIDOF in [\\/]* | ?:[\\/]*) ac_cv_path_PIDOF="$PIDOF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PIDOF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PIDOF=$ac_cv_path_PIDOF if test -n "$PIDOF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PIDOF" >&5 $as_echo "$PIDOF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "pgrep", so it can be a program name with args. set dummy pgrep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PGREP+:} false; then : $as_echo_n "(cached) " >&6 else case $PGREP in [\\/]* | ?:[\\/]*) ac_cv_path_PGREP="$PGREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PGREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PGREP=$ac_cv_path_PGREP if test -n "$PGREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PGREP" >&5 $as_echo "$PGREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gcore", so it can be a program name with args. set dummy gcore; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GCORE+:} false; then : $as_echo_n "(cached) " >&6 else case $GCORE in [\\/]* | ?:[\\/]*) ac_cv_path_GCORE="$GCORE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GCORE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GCORE=$ac_cv_path_GCORE if test -n "$GCORE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCORE" >&5 $as_echo "$GCORE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gdb", so it can be a program name with args. set dummy gdb; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GDB+:} false; then : $as_echo_n "(cached) " >&6 else case $GDB in [\\/]* | ?:[\\/]*) ac_cv_path_GDB="$GDB" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GDB="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GDB=$ac_cv_path_GDB if test -n "$GDB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GDB" >&5 $as_echo "$GDB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "dbx", so it can be a program name with args. set dummy dbx; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DBX+:} false; then : $as_echo_n "(cached) " >&6 else case $DBX in [\\/]* | ?:[\\/]*) ac_cv_path_DBX="$DBX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DBX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DBX=$ac_cv_path_DBX if test -n "$DBX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DBX" >&5 $as_echo "$DBX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "mdb", so it can be a program name with args. set dummy mdb; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MDB+:} false; then : $as_echo_n "(cached) " >&6 else case $MDB in [\\/]* | ?:[\\/]*) ac_cv_path_MDB="$MDB" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MDB="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MDB=$ac_cv_path_MDB if test -n "$MDB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MDB" >&5 $as_echo "$MDB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done # Some AWK programs fail, so test it and warn the user if echo xfoo | $AWK 'BEGIN { prog=ARGV1; ARGC=1 } { if ((prog == $2) || (("(" prog ")") == $2) || (("" prog "") == $2) || ((prog ":") == $2)) { print $1 ; exit 0 } }' xfoo>/dev/null; then :; else as_fn_error $? "!!!!!!!!! WARNING !!!!!!!!!!!!!! The regex engine of $AWK is too broken to be used you might want to install GNU AWK. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" "$LINENO" 5 fi THE_AWK=$AWK # Extract the first word of "$THE_AWK", so it can be a program name with args. set dummy $THE_AWK; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AWK+:} false; then : $as_echo_n "(cached) " >&6 else case $AWK in [\\/]* | ?:[\\/]*) ac_cv_path_AWK="$AWK" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AWK="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_AWK" && ac_cv_path_AWK="$THE_AWK" ;; esac fi AWK=$ac_cv_path_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ARFLAG" || ARFLAGS="cr" MAKE_SHELL=/bin/sh use_libtool=yes # Check whether --enable-libtool was given. if test "${enable_libtool+set}" = set; then : enableval=$enable_libtool; if test x$enableval = xno; then use_libtool=no fi fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf # Set options # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=no fi enable_dlopen=no enable_win32_dll=no # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec_CXX='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" if test "$lt_cv_apple_cc_single_mod" != "yes"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi else ld_shlibs_CXX=no fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: LT_DLLOADERS= ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBADD_DLOPEN= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" $as_echo "#define HAVE_LIBDL 1" >>confdefs.h if test "$ac_cv_search_dlopen" != "none required" ; then LIBADD_DLOPEN="-ldl" fi libltdl_cv_lib_dl_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_DLFCN_H # include #endif int main () { dlopen(0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_LIBDL 1" >>confdefs.h libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : $as_echo "#define HAVE_LIBDL 1" >>confdefs.h LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" for ac_func in dlerror do : ac_fn_c_check_func "$LINENO" "dlerror" "ac_cv_func_dlerror" if test "x$ac_cv_func_dlerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLERROR 1 _ACEOF fi done LIBS="$lt_save_LIBS" fi LIBADD_SHL_LOAD= ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : $as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : $as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD="-ldld" fi fi case $host_os in darwin[1567].*) # We only want this for pre-Mac OS X 10.4. ac_fn_c_check_func "$LINENO" "_dyld_func_lookup" "ac_cv_func__dyld_func_lookup" if test "x$ac_cv_func__dyld_func_lookup" = xyes; then : $as_echo "#define HAVE_DYLD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la" fi ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | os2* | pw32*) ac_fn_c_check_decl "$LINENO" "cygwin_conv_path" "ac_cv_have_decl_cygwin_conv_path" "#include " if test "x$ac_cv_have_decl_cygwin_conv_path" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CYGWIN_CONV_PATH $ac_have_decl _ACEOF LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : $as_echo "#define HAVE_DLD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la" fi LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done $as_echo "#define HAVE_LIBDLLOADER 1" >>confdefs.h fi LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$use_libtool != xno; then DEFAULT_OBJECT_TYPE=".lo" DEFAULT_ARCHIVE_TYPE=".la" DEFAULT_SHARED_OBJECT_TYPE=".la" LIBTOOL="\$(LIBTOOL)" LIBTOOL_INSTALL_TARGET="libtool-install" LIBTOOL_CLEAN_TARGET="libtool-clean" QMAKE_LIBTOOL="${BUILD_DIR}/libtool" FD_PLUGIN_DIR="src/plugins/filed" SD_PLUGIN_DIR="src/plugins/stored" DIR_PLUGIN_DIR="src/plugins/dird" have_plugins=yes else DEFAULT_OBJECT_TYPE=".o" DEFAULT_ARCHIVE_TYPE=".a" DEFAULT_SHARED_OBJECT_TYPE=".so" LIBTOOL="# \$(LIBTOOL)" LIBTOOL_INSTALL_TARGET="" LIBTOOL_CLEAN_TARGET="" QMAKE_LIBTOOL="# ${BUILD_DIR}/libtool" FD_PLUGIN_DIR="" SD_PLUGIN_DIR="" DIR_PLUGIN_DIR="" have_plugins=no fi # Check whether --enable-includes was given. if test "${enable_includes+set}" = set; then : enableval=$enable_includes; if test x$enableval = xyes; then install_includes=yes fi fi if test x$use_libtool != xno -a x$install_includes = xyes; then INCLUDE_INSTALL_TARGET="install-includes" else INCLUDE_INSTALL_TARGET="" fi case $host_os in *cygwin* ) CYGWIN=yes;; * ) CYGWIN=no;; esac if test $HAVE_UNAME=yes -a x`uname -s` = xSunOS then if $TRUEPRG; then HAVE_SUN_OS_TRUE= HAVE_SUN_OS_FALSE='#' else HAVE_SUN_OS_TRUE='#' HAVE_SUN_OS_FALSE= fi $as_echo "#define HAVE_SUN_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_SUN_OS_TRUE= HAVE_SUN_OS_FALSE='#' else HAVE_SUN_OS_TRUE='#' HAVE_SUN_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xGNU then if $TRUEPRG; then HAVE_HURD_OS_TRUE= HAVE_HURD_OS_FALSE='#' else HAVE_HURD_OS_TRUE='#' HAVE_HURD_OS_FALSE= fi $as_echo "#define HAVE_HURD_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_HURD_OS_TRUE= HAVE_HURD_OS_FALSE='#' else HAVE_HURD_OS_TRUE='#' HAVE_HURD_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xOSF1 then if $TRUEPRG; then HAVE_OSF1_OS_TRUE= HAVE_OSF1_OS_FALSE='#' else HAVE_OSF1_OS_TRUE='#' HAVE_OSF1_OS_FALSE= fi $as_echo "#define HAVE_OSF1_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_OSF1_OS_TRUE= HAVE_OSF1_OS_FALSE='#' else HAVE_OSF1_OS_TRUE='#' HAVE_OSF1_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xAIX then if $TRUEPRG; then HAVE_AIX_OS_TRUE= HAVE_AIX_OS_FALSE='#' else HAVE_AIX_OS_TRUE='#' HAVE_AIX_OS_FALSE= fi $as_echo "#define HAVE_AIX_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_AIX_OS_TRUE= HAVE_AIX_OS_FALSE='#' else HAVE_AIX_OS_TRUE='#' HAVE_AIX_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xHP-UX then if $TRUEPRG; then HAVE_HPUX_OS_TRUE= HAVE_HPUX_OS_FALSE='#' else HAVE_HPUX_OS_TRUE='#' HAVE_HPUX_OS_FALSE= fi $as_echo "#define HAVE_HPUX_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_HPUX_OS_TRUE= HAVE_HPUX_OS_FALSE='#' else HAVE_HPUX_OS_TRUE='#' HAVE_HPUX_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xLinux then if $TRUEPRG; then HAVE_LINUX_OS_TRUE= HAVE_LINUX_OS_FALSE='#' else HAVE_LINUX_OS_TRUE='#' HAVE_LINUX_OS_FALSE= fi $as_echo "#define HAVE_LINUX_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_LINUX_OS_TRUE= HAVE_LINUX_OS_FALSE='#' else HAVE_LINUX_OS_TRUE='#' HAVE_LINUX_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xFreeBSD then if $TRUEPRG; then HAVE_FREEBSD_OS_TRUE= HAVE_FREEBSD_OS_FALSE='#' else HAVE_FREEBSD_OS_TRUE='#' HAVE_FREEBSD_OS_FALSE= fi $as_echo "#define HAVE_FREEBSD_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_FREEBSD_OS_TRUE= HAVE_FREEBSD_OS_FALSE='#' else HAVE_FREEBSD_OS_TRUE='#' HAVE_FREEBSD_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xNetBSD then if $TRUEPRG; then HAVE_NETBSD_OS_TRUE= HAVE_NETBSD_OS_FALSE='#' else HAVE_NETBSD_OS_TRUE='#' HAVE_NETBSD_OS_FALSE= fi $as_echo "#define HAVE_NETBSD_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_NETBSD_OS_TRUE= HAVE_NETBSD_OS_FALSE='#' else HAVE_NETBSD_OS_TRUE='#' HAVE_NETBSD_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xOpenBSD then if $TRUEPRG; then HAVE_OPENBSD_OS_TRUE= HAVE_OPENBSD_OS_FALSE='#' else HAVE_OPENBSD_OS_TRUE='#' HAVE_OPENBSD_OS_FALSE= fi $as_echo "#define HAVE_OPENBSD_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_OPENBSD_OS_TRUE= HAVE_OPENBSD_OS_FALSE='#' else HAVE_OPENBSD_OS_TRUE='#' HAVE_OPENBSD_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xBSD/OS then if $TRUEPRG; then HAVE_BSDI_OS_TRUE= HAVE_BSDI_OS_FALSE='#' else HAVE_BSDI_OS_TRUE='#' HAVE_BSDI_OS_FALSE= fi $as_echo "#define HAVE_BSDI_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_BSDI_OS_TRUE= HAVE_BSDI_OS_FALSE='#' else HAVE_BSDI_OS_TRUE='#' HAVE_BSDI_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xSGI then if $TRUEPRG; then HAVE_SGI_OS_TRUE= HAVE_SGI_OS_FALSE='#' else HAVE_SGI_OS_TRUE='#' HAVE_SGI_OS_FALSE= fi $as_echo "#define HAVE_SGI_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_SGI_OS_TRUE= HAVE_SGI_OS_FALSE='#' else HAVE_SGI_OS_TRUE='#' HAVE_SGI_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xIRIX -o x`uname -s` = xIRIX64 then if $TRUEPRG; then HAVE_IRIX_OS_TRUE= HAVE_IRIX_OS_FALSE='#' else HAVE_IRIX_OS_TRUE='#' HAVE_IRIX_OS_FALSE= fi $as_echo "#define HAVE_IRIX_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_IRIX_OS_TRUE= HAVE_IRIX_OS_FALSE='#' else HAVE_IRIX_OS_TRUE='#' HAVE_IRIX_OS_FALSE= fi fi if test $HAVE_UNAME=yes -a x`uname -s` = xDarwin then if $TRUEPRG; then HAVE_DARWIN_OS_TRUE= HAVE_DARWIN_OS_FALSE='#' else HAVE_DARWIN_OS_TRUE='#' HAVE_DARWIN_OS_FALSE= fi $as_echo "#define HAVE_DARWIN_OS 1" >>confdefs.h else if $FALSEPRG; then HAVE_DARWIN_OS_TRUE= HAVE_DARWIN_OS_FALSE='#' else HAVE_DARWIN_OS_TRUE='#' HAVE_DARWIN_OS_FALSE= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Operating System Distribution" >&5 $as_echo_n "checking for Operating System Distribution... " >&6; } if test "x$DISTNAME" != "x" then echo "distname set to $DISTNAME" else which lsb_release > /dev/null 2>&1 if test $? = 0 then LSB_DISTRIBUTOR=`lsb_release -i -s` case ${LSB_DISTRIBUTOR} in "SUSE LINUX") DISTNAME=suse ;; "openSUSE project") DISTNAME=suse ;; CentOS) DISTNAME=redhat ;; Fedora) DISTNAME=redhat ;; RedHatEnterprise*) DISTNAME=redhat ;; Oracle*) DISTNAME=redhat ;; MandrivaLinux) DISTNAME=mandrake ;; Arch|archlinux) DISTNAME=archlinux ;; LinuxMint) DISTNAME=debian ;; Debian) DISTNAME=debian ;; Ubuntu) DISTNAME=ubuntu ;; Univention) DISTNAME=univention ;; *) DISTNAME="" ;; esac # # If we got a valid DISTNAME get the DISTVER from lsb_release too. # if test "x$DISTNAME" != "x" then DISTVER=`lsb_release -d -s | sed -e 's/"//g'` fi fi # # If lsb_release gave us the wanted info we skip this fallback block. # if test "x$DISTNAME" = "x" -o "x$DISTVER" = "x" then if test $HAVE_UNAME=yes -a x`uname -s` = xOSF1 then DISTNAME=alpha DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xAIX then DISTNAME=aix DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xHP-UX then DISTNAME=hpux DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xSunOS then DISTNAME=solaris DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xGNU then DISTNAME=hurd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xFreeBSD then DISTNAME=freebsd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xNetBSD then DISTNAME=netbsd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xOpenBSD then DISTNAME=openbsd DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xIRIX then DISTNAME=irix DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xBSD/OS then DISTNAME=bsdi DISTVER=`uname -a | awk '{print }'` elif test -f /etc/SuSE-release then DISTNAME=suse DISTVER=`cat /etc/SuSE-release | \ grep VERSION | \ cut -f3 -d' '` elif test -d /etc/SuSEconfig then DISTNAME=suse DISTVER=5.x elif test -f /etc/mandrake-release then DISTNAME=mandrake DISTVER=`cat /etc/mandrake-release | \ grep release | \ cut -f5 -d' '` elif test -f /etc/fedora-release then DISTNAME=redhat DISTVER="`cat /etc/fedora-release | cut -d' ' -f1,3`" elif test -f /etc/whitebox-release then DISTNAME=redhat DISTVER=`cat /etc/whitebox-release | grep release` elif test -f /etc/redhat-release then DISTNAME=redhat DISTVER=`cat /etc/redhat-release | grep release` elif test -f /etc/gentoo-release then DISTNAME=gentoo DISTVER=`awk '/version / { print }' < /etc/gentoo-release` elif test -f /etc/debian_version then if `test -f /etc/apt/sources.list && grep -q ubuntu /etc/apt/sources.list`; then DISTNAME=ubuntu else DISTNAME=debian fi DISTVER=`cat /etc/debian_version` elif test -f /etc/slackware-version then DISTNAME=slackware DISTVER=`cat /etc/slackware-version` elif test x$host_vendor = xapple then DISTNAME=osx DISTVER=`uname -r` elif test $HAVE_UNAME=yes -a x`uname -s` = xDarwin then DISTNAME=darwin DISTVER=`uname -r` elif test -f /etc/engarde-version then DISTNAME=engarde DISTVER=`uname -r` elif test -f /etc/arch-release then DISTNAME=archlinux elif test "$CYGWIN" = yes then DISTNAME=cygwin $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h else DISTNAME=unknown DISTVER=unknown fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OBS OS Distribution" >&5 $as_echo_n "checking for OBS OS Distribution... " >&6; } if test "x$OBS_DISTRIBUTION" != "x" then echo "obsdistname set to $OBS_DISTRIBUTION" else if test -e /.build.log; then OBS_PROJECT=`grep 'Building bareos for project' /.build.log | cut -d' ' -f10 | sed "s#'##g"` OBS_DISTRIBUTION=`grep 'Building bareos for project' /.build.log | cut -d' ' -f12 | sed "s#'##g"` OBS_ARCH=`grep 'Building bareos for project' /.build.log | cut -d' ' -f14 | sed "s#'##g"` OBS_SRCMD5=`grep 'Building bareos for project' /.build.log | cut -d' ' -f16 | sed "s#'##g"` $as_echo "#define IS_BUILD_ON_OBS 1" >>confdefs.h fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi MKINSTALLDIRS= if test -n "$ac_aux_dir"; then case "$ac_aux_dir" in /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; esac fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGFMT" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test "$MSGFMT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GMSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 $as_echo "$GMSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XGETTEXT+:} false; then : $as_echo_n "(cached) " >&6 else case "$XGETTEXT" in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test "$XGETTEXT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 $as_echo "$XGETTEXT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f messages.po # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGMERGE+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGMERGE" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ;; esac fi MSGMERGE="$ac_cv_path_MSGMERGE" if test "$MSGMERGE" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 $as_echo "$MSGMERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GMSGFMT" != ":"; then if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5 $as_echo "found $GMSGFMT program is not GNU msgfmt; ignore it" >&6; } GMSGFMT=":" fi fi if test "$XGETTEXT" != ":"; then if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5 $as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; } XGETTEXT=":" fi rm -f messages.po fi ac_config_commands="$ac_config_commands default-1" if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 $as_echo_n "checking for ld used by GCC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | [A-Za-z]:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${acl_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi fi LD="$acl_cv_path_LD" if test -n "$LD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${acl_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU ld's only accept -v. case `$LD -v 2>&1 &5 $as_echo "$acl_cv_prog_gnu_ld" >&6; } with_gnu_ld=$acl_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 $as_echo_n "checking for shared library run path origin... " >&6; } if ${acl_cv_rpath+:} false; then : $as_echo_n "(cached) " >&6 else CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 $as_echo "$acl_cv_rpath" >&6; } wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; : else enable_rpath=yes fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libiconv-prefix was given. if test "${with_libiconv_prefix+set}" = set; then : withval=$with_libiconv_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBICONV= LTLIBICONV= INCICONV= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='iconv ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" else LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" ;; esac done fi else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 $as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFPreferencesCopyAppValue(NULL, NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFPreferencesCopyAppValue=yes else gt_cv_func_CFPreferencesCopyAppValue=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 $as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then $as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 $as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFLocaleCopyCurrent(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFLocaleCopyCurrent=yes else gt_cv_func_CFLocaleCopyCurrent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 $as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } if test $gt_cv_func_CFLocaleCopyCurrent = yes; then $as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } LIBINTL= LTLIBINTL= POSUB= if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 $as_echo_n "checking for GNU gettext in libc... " >&6; } if ${gt_cv_func_gnugettext1_libc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libc=yes else gt_cv_func_gnugettext1_libc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libc" >&5 $as_echo "$gt_cv_func_gnugettext1_libc" >&6; } if test "$gt_cv_func_gnugettext1_libc" != "yes"; then am_save_CPPFLAGS="$CPPFLAGS" for element in $INCICONV; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 $as_echo_n "checking for iconv... " >&6; } if ${am_cv_func_iconv+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 $as_echo "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then $as_echo "#define HAVE_ICONV 1" >>confdefs.h fi if test "$am_cv_lib_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 $as_echo_n "checking how to link with libiconv... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 $as_echo "$LIBICONV" >&6; } else CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libintl-prefix was given. if test "${with_libintl_prefix+set}" = set; then : withval=$with_libintl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBINTL= LTLIBINTL= INCINTL= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='intl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" else LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" ;; esac done fi else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 $as_echo_n "checking for GNU gettext in libintl... " >&6; } if ${gt_cv_func_gnugettext1_libintl+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libintl=yes else gt_cv_func_gnugettext1_libintl=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext1_libintl=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libintl" >&5 $as_echo "$gt_cv_func_gnugettext1_libintl" >&6; } fi if test "$gt_cv_func_gnugettext1_libc" = "yes" \ || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else LIBINTL= LTLIBINTL= INCINTL= fi if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then $as_echo "#define ENABLE_NLS 1" >>confdefs.h else USE_NLS=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 $as_echo_n "checking whether to use NLS... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } if test "$USE_NLS" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 $as_echo_n "checking where the gettext function comes from... " >&6; } if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 $as_echo "$gt_source" >&6; } fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 $as_echo_n "checking how to link with libintl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 $as_echo "$LIBINTL" >&6; } for element in $INCINTL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done fi $as_echo "#define HAVE_GETTEXT 1" >>confdefs.h $as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h fi POSUB=po fi INTLLIBS="$LIBINTL" os_name=`uname -s 2>/dev/null` if test x${prefix} = xNONE ; then if test `eval echo ${sysconfdir}` = NONE/etc ; then sysconfdir=/etc/bareos fi if test `eval echo ${libdir}` = NONE/lib ; then case ${os_name} in Linux) os_processor=`uname -p 2>/dev/null` case ${os_processor} in x86_64) libdir=/usr/lib64 ;; *) libdir=/usr/lib ;; esac ;; *) libdir=/usr/lib ;; esac fi if test `eval echo ${includedir}` = NONE/include ; then includedir=/usr/include fi if test `eval echo ${datarootdir}` = NONE/share ; then datarootdir=/usr/share fi prefix= fi if test x${exec_prefix} = xNONE ; then exec_prefix=${prefix} fi sysconfdir=`eval echo ${sysconfdir}` datarootdir=`eval echo ${datarootdir}` docdir=`eval echo ${docdir}` htmldir=`eval echo ${htmldir}` libdir=`eval echo ${libdir}` includedir=`eval echo ${includedir}` localedir=`eval echo ${datarootdir}/locale` cat >>confdefs.h <<_ACEOF #define LIBDIR "$libdir" _ACEOF cat >>confdefs.h <<_ACEOF #define SYSCONFDIR "$sysconfdir" _ACEOF cat >>confdefs.h <<_ACEOF #define LOCALEDIR "$localedir" _ACEOF if test x$bindir = x'${exec_prefix}/bin' ; then bindir=${exec_prefix}/bin fi bindir=`eval echo ${bindir}` if test x$sbindir = x'${exec_prefix}/sbin' ; then sbindir=${exec_prefix}/sbin fi sbindir=`eval echo ${sbindir}` if test x$mandir = x'${prefix}/man' ; then mandir=/usr/share/man fi if test x$htmldir = x${docdir} ; then htmldir=`eval echo ${docdir}/html` fi if test x$docdir = x'/usr/share/doc/' ; then docdir=`eval echo ${docdir}bareos` fi for ac_prog in msgfmt do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $MSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MSGFMT=$ac_cv_path_MSGFMT if test -n "$MSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$MSGFMT" && break done test -n "$MSGFMT" || MSGFMT="no" if test "$MSGFMT" = "no" then echo 'msgfmt program not found, disabling NLS !' USE_NLS=no USE_INCLUDED_LIBINTL=no #else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library 2 or newer" >&5 $as_echo_n "checking whether we are using the GNU C Library 2 or newer... " >&6; } if ${ac_cv_gnu_library_2+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ >= 2) Lucky GNU user #endif #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Lucky GNU user" >/dev/null 2>&1; then : ac_cv_gnu_library_2=yes else ac_cv_gnu_library_2=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2" >&5 $as_echo "$ac_cv_gnu_library_2" >&6; } GLIBC2="$ac_cv_gnu_library_2" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror in -lcposix" >&5 $as_echo_n "checking for strerror in -lcposix... " >&6; } if ${ac_cv_lib_cposix_strerror+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char strerror (); int main () { return strerror (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cposix_strerror=yes else ac_cv_lib_cposix_strerror=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cposix_strerror" >&5 $as_echo "$ac_cv_lib_cposix_strerror" >&6; } if test "x$ac_cv_lib_cposix_strerror" = xyes; then : LIBS="$LIBS -lcposix" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for signed" >&5 $as_echo_n "checking for signed... " >&6; } if ${bh_cv_c_signed+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { signed char x; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : bh_cv_c_signed=yes else bh_cv_c_signed=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bh_cv_c_signed" >&5 $as_echo "$bh_cv_c_signed" >&6; } if test $bh_cv_c_signed = no; then $as_echo "#define signed /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long" >&5 $as_echo_n "checking for long long... " >&6; } if ${ac_cv_type_long_long+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ long long ll = 1LL; int i = 63; int main () { long long llmax = (long long) -1; return ll << i | ll >> i | llmax / ll | llmax % ll; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_type_long_long=yes else ac_cv_type_long_long=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long" >&5 $as_echo "$ac_cv_type_long_long" >&6; } if test $ac_cv_type_long_long = yes; then $as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 $as_echo_n "checking for long double... " >&6; } if ${gt_cv_c_long_double+:} false; then : $as_echo_n "(cached) " >&6 else if test "$GCC" = yes; then gt_cv_c_long_double=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* The Stardent Vistra knows sizeof(long double), but does not support it. */ long double foo = 0.0; /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ int array [2*(sizeof(long double) >= sizeof(double)) - 1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_long_double=yes else gt_cv_c_long_double=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_long_double" >&5 $as_echo "$gt_cv_c_long_double" >&6; } if test $gt_cv_c_long_double = yes; then $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wchar_t" >&5 $as_echo_n "checking for wchar_t... " >&6; } if ${gt_cv_c_wchar_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include wchar_t foo = (wchar_t)'\0'; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_wchar_t=yes else gt_cv_c_wchar_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wchar_t" >&5 $as_echo "$gt_cv_c_wchar_t" >&6; } if test $gt_cv_c_wchar_t = yes; then $as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wint_t" >&5 $as_echo_n "checking for wint_t... " >&6; } if ${gt_cv_c_wint_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include wint_t foo = (wchar_t)'\0'; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_wint_t=yes else gt_cv_c_wint_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wint_t" >&5 $as_echo "$gt_cv_c_wint_t" >&6; } if test $gt_cv_c_wint_t = yes; then $as_echo "#define HAVE_WINT_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inttypes.h" >&5 $as_echo_n "checking for inttypes.h... " >&6; } if ${gl_cv_header_inttypes_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uintmax_t i = (uintmax_t) -1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_header_inttypes_h=yes else gl_cv_header_inttypes_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_inttypes_h" >&5 $as_echo "$gl_cv_header_inttypes_h" >&6; } if test $gl_cv_header_inttypes_h = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H_WITH_UINTMAX 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint.h" >&5 $as_echo_n "checking for stdint.h... " >&6; } if ${gl_cv_header_stdint_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { uintmax_t i = (uintmax_t) -1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_header_stdint_h=yes else gl_cv_header_stdint_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_stdint_h" >&5 $as_echo "$gl_cv_header_stdint_h" >&6; } if test $gl_cv_header_stdint_h = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H_WITH_UINTMAX 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intmax_t" >&5 $as_echo_n "checking for intmax_t... " >&6; } if ${gt_cv_c_intmax_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if HAVE_STDINT_H_WITH_UINTMAX #include #endif #if HAVE_INTTYPES_H_WITH_UINTMAX #include #endif int main () { intmax_t x = -1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_c_intmax_t=yes else gt_cv_c_intmax_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_intmax_t" >&5 $as_echo "$gt_cv_c_intmax_t" >&6; } if test $gt_cv_c_intmax_t = yes; then $as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether printf() supports POSIX/XSI format strings" >&5 $as_echo_n "checking whether printf() supports POSIX/XSI format strings... " >&6; } if ${gt_cv_func_printf_posix+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ notposix #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "notposix" >/dev/null 2>&1; then : gt_cv_func_printf_posix="guessing no" else gt_cv_func_printf_posix="guessing yes" fi rm -f conftest* else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include /* The string "%2$d %1$d", with dollar characters protected from the shell's dollar expansion (possibly an autoconf bug). */ static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; static char buf[100]; int main () { sprintf (buf, format, 33, 55); return (strcmp (buf, "55 33") != 0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gt_cv_func_printf_posix=yes else gt_cv_func_printf_posix=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_printf_posix" >&5 $as_echo "$gt_cv_func_printf_posix" >&6; } case $gt_cv_func_printf_posix in *yes) $as_echo "#define HAVE_POSIX_PRINTF 1" >>confdefs.h ;; esac # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getpagesize do : ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 $as_echo_n "checking for working mmap... " >&6; } if ${ac_cv_func_mmap_fixed_mapped+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_mmap_fixed_mapped=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default /* malloc might have been renamed as rpl_malloc. */ #undef malloc /* Thanks to Mike Haertel and Jim Avera for this test. Here is a matrix of mmap possibilities: mmap private not fixed mmap private fixed at somewhere currently unmapped mmap private fixed at somewhere already mapped mmap shared not fixed mmap shared fixed at somewhere currently unmapped mmap shared fixed at somewhere already mapped For private mappings, we should verify that changes cannot be read() back from the file, nor mmap's back from the file at a different address. (There have been systems where private was not correctly implemented like the infamous i386 svr4.0, and systems where the VM page cache was not coherent with the file system buffer cache like early versions of FreeBSD and possibly contemporary NetBSD.) For shared mappings, we should conversely verify that changes get propagated back to all the places they're supposed to be. Grep wants private fixed already mapped. The main things grep needs to know about mmap are: * does it exist and is it safe to write into the mmap'd area * how to use it (BSD variants) */ #include #include #if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ int main () { char *data, *data2, *data3; const char *cdata2; int i, pagesize; int fd, fd2; pagesize = getpagesize (); /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) return 1; for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) return 2; if (write (fd, data, pagesize) != pagesize) return 3; close (fd); /* Next, check that the tail of a page is zero-filled. File must have non-zero length, otherwise we risk SIGBUS for entire page. */ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd2 < 0) return 4; cdata2 = ""; if (write (fd2, cdata2, 1) != 1) return 5; data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); if (data2 == MAP_FAILED) return 6; for (i = 0; i < pagesize; ++i) if (*(data2 + i)) return 7; close (fd2); if (munmap (data2, pagesize)) return 8; /* Next, try to mmap the file at a fixed address which already has something else allocated at it. If we can, also make sure that we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) return 9; if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) return 10; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) return 11; /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) return 12; if (read (fd, data3, pagesize) != pagesize) return 13; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) return 14; close (fd); return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_mmap_fixed_mapped=yes else ac_cv_func_mmap_fixed_mapped=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 $as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } if test $ac_cv_func_mmap_fixed_mapped = yes; then $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library 2.1 or newer" >&5 $as_echo_n "checking whether we are using the GNU C Library 2.1 or newer... " >&6; } if ${ac_cv_gnu_library_2_1+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) Lucky GNU user #endif #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Lucky GNU user" >/dev/null 2>&1; then : ac_cv_gnu_library_2_1=yes else ac_cv_gnu_library_2_1=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2_1" >&5 $as_echo "$ac_cv_gnu_library_2_1" >&6; } GLIBC21="$ac_cv_gnu_library_2_1" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether integer division by zero raises SIGFPE" >&5 $as_echo_n "checking whether integer division by zero raises SIGFPE... " >&6; } if ${gt_cv_int_divbyzero_sigfpe+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : # Guess based on the CPU. case "$host_cpu" in alpha* | i3456786 | m68k | s390*) gt_cv_int_divbyzero_sigfpe="guessing yes";; *) gt_cv_int_divbyzero_sigfpe="guessing no";; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include static void #ifdef __cplusplus sigfpe_handler (int sig) #else sigfpe_handler (sig) int sig; #endif { /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ exit (sig != SIGFPE); } int x = 1; int y = 0; int z; int nan; int main () { signal (SIGFPE, sigfpe_handler); /* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ #if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) signal (SIGTRAP, sigfpe_handler); #endif /* Linux/SPARC yields signal SIGILL. */ #if defined (__sparc__) && defined (__linux__) signal (SIGILL, sigfpe_handler); #endif z = x / y; nan = y / y; exit (1); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : gt_cv_int_divbyzero_sigfpe=yes else gt_cv_int_divbyzero_sigfpe=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_int_divbyzero_sigfpe" >&5 $as_echo "$gt_cv_int_divbyzero_sigfpe" >&6; } case "$gt_cv_int_divbyzero_sigfpe" in *yes) value=1;; *) value=0;; esac cat >>confdefs.h <<_ACEOF #define INTDIV0_RAISES_SIGFPE $value _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long" >&5 $as_echo_n "checking for unsigned long long... " >&6; } if ${ac_cv_type_unsigned_long_long+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ unsigned long long ull = 1ULL; int i = 63; int main () { unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_type_unsigned_long_long=yes else ac_cv_type_unsigned_long_long=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long" >&5 $as_echo "$ac_cv_type_unsigned_long_long" >&6; } if test $ac_cv_type_unsigned_long_long = yes; then $as_echo "#define HAVE_UNSIGNED_LONG_LONG 1" >>confdefs.h fi if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then test $ac_cv_type_unsigned_long_long = yes \ && ac_type='unsigned long long' \ || ac_type='unsigned long' cat >>confdefs.h <<_ACEOF #define uintmax_t $ac_type _ACEOF else $as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inttypes.h" >&5 $as_echo_n "checking for inttypes.h... " >&6; } if ${gt_cv_header_inttypes_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_header_inttypes_h=yes else gt_cv_header_inttypes_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_header_inttypes_h" >&5 $as_echo "$gt_cv_header_inttypes_h" >&6; } if test $gt_cv_header_inttypes_h = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H 1 _ACEOF fi if test $gt_cv_header_inttypes_h = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the inttypes.h PRIxNN macros are broken" >&5 $as_echo_n "checking whether the inttypes.h PRIxNN macros are broken... " >&6; } if ${gt_cv_inttypes_pri_broken+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef PRId32 char *p = PRId32; #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gt_cv_inttypes_pri_broken=no else gt_cv_inttypes_pri_broken=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_inttypes_pri_broken" >&5 $as_echo "$gt_cv_inttypes_pri_broken" >&6; } fi if test "$gt_cv_inttypes_pri_broken" = yes; then cat >>confdefs.h <<_ACEOF #define PRI_MACROS_BROKEN 1 _ACEOF fi for ac_header in stdint.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" if test "x$ac_cv_header_stdint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SIZE_MAX" >&5 $as_echo_n "checking for SIZE_MAX... " >&6; } result= cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if HAVE_STDINT_H #include #endif #ifdef SIZE_MAX Found it #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Found it" >/dev/null 2>&1; then : result=yes fi rm -f conftest* if test -z "$result"; then if ac_fn_c_compute_int "$LINENO" "~(size_t)0 / 10" "res_hi" "#include "; then : else result=? fi if ac_fn_c_compute_int "$LINENO" "~(size_t)0 % 10" "res_lo" "#include "; then : else result=? fi if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) <= sizeof (unsigned int)" "fits_in_uint" "#include "; then : else result=? fi if test "$fits_in_uint" = 1; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern size_t foo; extern unsigned long foo; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : fits_in_uint=0 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test -z "$result"; then if test "$fits_in_uint" = 1; then result="$res_hi$res_lo"U else result="$res_hi$res_lo"UL fi else result='~(size_t)0' fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 $as_echo "$result" >&6; } if test "$result" != yes; then cat >>confdefs.h <<_ACEOF #define SIZE_MAX $result _ACEOF fi for ac_header in stdint.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" if test "x$ac_cv_header_stdint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDINT_H 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : else $as_echo "#define ptrdiff_t long" >>confdefs.h fi for ac_header in argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ stdlib.h string.h unistd.h sys/param.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in asprintf fwprintf getcwd getegid geteuid getgid getuid \ mempcpy munmap putenv setenv setlocale snprintf stpcpy strcasecmp strdup \ strtoul tsearch wcslen __argz_count __argz_stringify __argz_next \ __fsetlocking do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _snprintf is declared" >&5 $as_echo_n "checking whether _snprintf is declared... " >&6; } if ${ac_cv_have_decl__snprintf+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _snprintf char *p = (char *) _snprintf; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_decl__snprintf=yes else ac_cv_have_decl__snprintf=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl__snprintf" >&5 $as_echo "$ac_cv_have_decl__snprintf" >&6; } if test $ac_cv_have_decl__snprintf = yes; then gt_value=1 else gt_value=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL__SNPRINTF $gt_value _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _snwprintf is declared" >&5 $as_echo_n "checking whether _snwprintf is declared... " >&6; } if ${ac_cv_have_decl__snwprintf+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _snwprintf char *p = (char *) _snwprintf; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_decl__snwprintf=yes else ac_cv_have_decl__snwprintf=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl__snwprintf" >&5 $as_echo "$ac_cv_have_decl__snwprintf" >&6; } if test $ac_cv_have_decl__snwprintf = yes; then gt_value=1 else gt_value=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL__SNWPRINTF $gt_value _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether feof_unlocked is declared" >&5 $as_echo_n "checking whether feof_unlocked is declared... " >&6; } if ${ac_cv_have_decl_feof_unlocked+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef feof_unlocked char *p = (char *) feof_unlocked; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_decl_feof_unlocked=yes else ac_cv_have_decl_feof_unlocked=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl_feof_unlocked" >&5 $as_echo "$ac_cv_have_decl_feof_unlocked" >&6; } if test $ac_cv_have_decl_feof_unlocked = yes; then gt_value=1 else gt_value=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FEOF_UNLOCKED $gt_value _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fgets_unlocked is declared" >&5 $as_echo_n "checking whether fgets_unlocked is declared... " >&6; } if ${ac_cv_have_decl_fgets_unlocked+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef fgets_unlocked char *p = (char *) fgets_unlocked; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_decl_fgets_unlocked=yes else ac_cv_have_decl_fgets_unlocked=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl_fgets_unlocked" >&5 $as_echo "$ac_cv_have_decl_fgets_unlocked" >&6; } if test $ac_cv_have_decl_fgets_unlocked = yes; then gt_value=1 else gt_value=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FGETS_UNLOCKED $gt_value _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getc_unlocked is declared" >&5 $as_echo_n "checking whether getc_unlocked is declared... " >&6; } if ${ac_cv_have_decl_getc_unlocked+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef getc_unlocked char *p = (char *) getc_unlocked; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_decl_getc_unlocked=yes else ac_cv_have_decl_getc_unlocked=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl_getc_unlocked" >&5 $as_echo "$ac_cv_have_decl_getc_unlocked" >&6; } if test $ac_cv_have_decl_getc_unlocked = yes; then gt_value=1 else gt_value=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETC_UNLOCKED $gt_value _ACEOF case $gt_cv_func_printf_posix in *yes) HAVE_POSIX_PRINTF=1 ;; *) HAVE_POSIX_PRINTF=0 ;; esac if test "$ac_cv_func_asprintf" = yes; then HAVE_ASPRINTF=1 else HAVE_ASPRINTF=0 fi if test "$ac_cv_func_snprintf" = yes; then HAVE_SNPRINTF=1 else HAVE_SNPRINTF=0 fi if test "$ac_cv_func_wprintf" = yes; then HAVE_WPRINTF=1 else HAVE_WPRINTF=0 fi am_save_CPPFLAGS="$CPPFLAGS" for element in $INCICONV; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 $as_echo_n "checking for iconv... " >&6; } if ${am_cv_func_iconv+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 $as_echo "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then $as_echo "#define HAVE_ICONV 1" >>confdefs.h fi if test "$am_cv_lib_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 $as_echo_n "checking how to link with libiconv... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 $as_echo "$LIBICONV" >&6; } else CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi if test "$am_cv_func_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 $as_echo_n "checking for iconv declaration... " >&6; } if ${am_cv_proto_iconv+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_cv_proto_iconv_arg1="" else am_cv_proto_iconv_arg1="const" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" fi am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:- }$am_cv_proto_iconv" >&5 $as_echo "${ac_t:- }$am_cv_proto_iconv" >&6; } cat >>confdefs.h <<_ACEOF #define ICONV_CONST $am_cv_proto_iconv_arg1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 $as_echo_n "checking for nl_langinfo and CODESET... " >&6; } if ${am_cv_langinfo_codeset+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char* cs = nl_langinfo(CODESET); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_langinfo_codeset=yes else am_cv_langinfo_codeset=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 $as_echo "$am_cv_langinfo_codeset" >&6; } if test $am_cv_langinfo_codeset = yes; then $as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h fi if test $ac_cv_header_locale_h = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5 $as_echo_n "checking for LC_MESSAGES... " >&6; } if ${gt_cv_val_LC_MESSAGES+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return LC_MESSAGES ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_val_LC_MESSAGES=yes else gt_cv_val_LC_MESSAGES=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_val_LC_MESSAGES" >&5 $as_echo "$gt_cv_val_LC_MESSAGES" >&6; } if test $gt_cv_val_LC_MESSAGES = yes; then $as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h fi fi if test -n "$INTL_MACOSX_LIBS"; then CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" fi for ac_prog in bison do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_INTLBISON+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$INTLBISON"; then ac_cv_prog_INTLBISON="$INTLBISON" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_INTLBISON="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi INTLBISON=$ac_cv_prog_INTLBISON if test -n "$INTLBISON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLBISON" >&5 $as_echo "$INTLBISON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$INTLBISON" && break done if test -z "$INTLBISON"; then ac_verc_fail=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of bison" >&5 $as_echo_n "checking version of bison... " >&6; } ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 $as_echo "$ac_prog_version" >&6; } fi if test $ac_verc_fail = yes; then INTLBISON=: fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 $as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFPreferencesCopyAppValue(NULL, NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFPreferencesCopyAppValue=yes else gt_cv_func_CFPreferencesCopyAppValue=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 $as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then $as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 $as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFLocaleCopyCurrent(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFLocaleCopyCurrent=yes else gt_cv_func_CFLocaleCopyCurrent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 $as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } if test $gt_cv_func_CFLocaleCopyCurrent = yes; then $as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no LIBINTL= LTLIBINTL= POSUB= if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether included gettext is requested" >&5 $as_echo_n "checking whether included gettext is requested... " >&6; } # Check whether --with-included-gettext was given. if test "${with_included_gettext+set}" = set; then : withval=$with_included_gettext; nls_cv_force_use_gnu_gettext=$withval else nls_cv_force_use_gnu_gettext=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nls_cv_force_use_gnu_gettext" >&5 $as_echo "$nls_cv_force_use_gnu_gettext" >&6; } nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 $as_echo_n "checking for GNU gettext in libc... " >&6; } if ${gt_cv_func_gnugettext1_libc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libc=yes else gt_cv_func_gnugettext1_libc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libc" >&5 $as_echo "$gt_cv_func_gnugettext1_libc" >&6; } if test "$gt_cv_func_gnugettext1_libc" != "yes"; then use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libintl-prefix was given. if test "${with_libintl_prefix+set}" = set; then : withval=$with_libintl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBINTL= LTLIBINTL= INCINTL= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='intl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" else LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" ;; esac done fi else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 $as_echo_n "checking for GNU gettext in libintl... " >&6; } if ${gt_cv_func_gnugettext1_libintl+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libintl=yes else gt_cv_func_gnugettext1_libintl=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext1_libintl=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libintl" >&5 $as_echo "$gt_cv_func_gnugettext1_libintl" >&6; } fi if test "$gt_cv_func_gnugettext1_libc" = "yes" \ || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else LIBINTL= LTLIBINTL= INCINTL= fi if test "$gt_use_preinstalled_gnugettext" != "yes"; then nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="\${top_builddir}/intl/libintl.a $LIBICONV" LTLIBINTL="\${top_builddir}/intl/libintl.a $LTLIBICONV" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi CATOBJEXT= if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then CATOBJEXT=.gmo fi if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then $as_echo "#define ENABLE_NLS 1" >>confdefs.h else USE_NLS=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 $as_echo_n "checking whether to use NLS... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } if test "$USE_NLS" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 $as_echo_n "checking where the gettext function comes from... " >&6; } if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 $as_echo "$gt_source" >&6; } fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 $as_echo_n "checking how to link with libintl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 $as_echo "$LIBINTL" >&6; } for element in $INCINTL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done fi $as_echo "#define HAVE_GETTEXT 1" >>confdefs.h $as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h fi POSUB=po fi if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then BUILD_INCLUDED_LIBINTL=yes fi nls_cv_header_intl= nls_cv_header_libgt= DATADIRNAME=share INSTOBJEXT=.mo GENCAT=gencat INTLOBJS= if test "$USE_INCLUDED_LIBINTL" = yes; then INTLOBJS="\$(GETTOBJS)" fi INTL_LIBTOOL_SUFFIX_PREFIX= INTLLIBS="$LIBINTL" fi support_smartalloc=yes support_readline=yes support_conio=yes support_bat=no support_traymonitor=no support_static_tools=no support_static_fd=no support_static_sd=no support_static_dir=no support_static_cons=no support_python=no build_client_only=no build_dird=yes build_stored=yes db_backends="" batch_insert_db_backends="" support_lockmgr=no support_lmdb=no support_ndmp=no # Check whether --enable-bat was given. if test "${enable_bat+set}" = set; then : enableval=$enable_bat; if test x$enableval = xyes; then $as_echo "#define HAVE_BAT 1" >>confdefs.h support_bat=yes fi fi BAT_DIR= DEBIAN_CONTROL_BAT=/dev/null if test x$support_bat = xyes; then abc=`$PKGCONFIG --atleast-version=4.6 QtGui` pkg=$? if test $pkg = 0; then BAT_DIR=src/qt-console DEBIAN_CONTROL_BAT=./debian/control.bareos-bat else as_fn_error $? "Unable to find suitable Qt4 installation needed by bat" "$LINENO" 5 fi fi # Check whether --enable-traymonitor was given. if test "${enable_traymonitor+set}" = set; then : enableval=$enable_traymonitor; if test x$enableval = xyes; then $as_echo "#define HAVE_TRAYMONITOR 1" >>confdefs.h support_traymonitor=yes fi fi TRAY_MONITOR_DIR= DEBIAN_CONTROL_TRAYMONITOR=/dev/null if test x$support_traymonitor = xyes; then abc=`$PKGCONFIG --atleast-version=4.6 QtGui` pkg=$? if test $pkg = 0; then TRAY_MONITOR_DIR=src/qt-tray-monitor DEBIAN_CONTROL_TRAYMONITOR=./debian/control.bareos-traymonitor else as_fn_error $? "Unable to find suitable Qt4 installation needed by tray-monitor" "$LINENO" 5 fi fi # Check whether --enable-smartalloc was given. if test "${enable_smartalloc+set}" = set; then : enableval=$enable_smartalloc; if test x$enableval = xno; then support_smartalloc=no fi fi if test x$support_smartalloc = xyes; then $as_echo "#define SMARTALLOC 1" >>confdefs.h fi # Check whether --enable-lockmgr was given. if test "${enable_lockmgr+set}" = set; then : enableval=$enable_lockmgr; if test x$enableval = xyes; then support_lockmgr=yes fi fi if test x$support_lockmgr = xyes; then $as_echo "#define _USE_LOCKMGR 1" >>confdefs.h fi # Check whether --enable-static-tools was given. if test "${enable_static_tools+set}" = set; then : enableval=$enable_static_tools; if test x$enableval = xyes; then if test x$use_libtool = xyes; then as_fn_error $? "Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool" "$LINENO" 5 fi support_static_tools=yes fi fi TTOOL_LDFLAGS= if test x$support_static_tools = xyes; then TTOOL_LDFLAGS="-static" fi # Check whether --enable-static-fd was given. if test "${enable_static_fd+set}" = set; then : enableval=$enable_static_fd; if test x$enableval = xyes; then if test x$use_libtool = xyes; then as_fn_error $? "Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool" "$LINENO" 5 fi support_static_fd=yes fi fi STATIC_FD= if test x$support_static_fd = xyes; then STATIC_FD="static-bareos-fd" fi # Check whether --enable-static-sd was given. if test "${enable_static_sd+set}" = set; then : enableval=$enable_static_sd; if test x$enableval = xyes; then if test x$use_libtool = xyes; then as_fn_error $? "Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool" "$LINENO" 5 fi support_static_sd=yes fi fi STATIC_SD= if test x$support_static_sd = xyes; then STATIC_SD="static-bareos-sd" fi # Check whether --enable-static-dir was given. if test "${enable_static_dir+set}" = set; then : enableval=$enable_static_dir; if test x$enableval = xyes; then if test x$use_libtool = xyes; then as_fn_error $? "Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool" "$LINENO" 5 fi support_static_dir=yes fi fi STATIC_DIR= if test x$support_static_dir = xyes; then STATIC_DIR="static-bareos-dir" fi # Check whether --enable-static-cons was given. if test "${enable_static_cons+set}" = set; then : enableval=$enable_static_cons; if test x$enableval = xyes; then if test x$use_libtool = xyes; then as_fn_error $? "Libtool is enabled, not compatible with static tools, please rerun configure with --disable-libtool" "$LINENO" 5 fi support_static_cons=yes fi fi STATIC_CONS= if test x$support_static_cons = xyes; then STATIC_CONS="static-bconsole" fi # Check whether --enable-client-only was given. if test "${enable_client_only+set}" = set; then : enableval=$enable_client_only; if test x$enableval = xyes; then build_client_only=yes db_backends="None" DB_BACKENDS="none" fi fi if test x$build_client_only = xno; then ALL_DIRS="subdirs" else ALL_DIRS="" fi # Check whether --enable-build-dird was given. if test "${enable_build_dird+set}" = set; then : enableval=$enable_build_dird; if test x$enableval = xno; then build_dird=no fi fi if test x$build_dird = xyes; then DIRD_DIR="src/dird" else DIRD_DIR="" DIR_PLUGIN_DIR="" fi # Check whether --enable-build-stored was given. if test "${enable_build_stored+set}" = set; then : enableval=$enable_build_stored; if test x$enableval = xno; then build_stored=no fi fi if test x$build_stored = xyes; then STORED_DIR="src/stored" else STORED_DIR="" SD_PLUGIN_DIR="" fi use_dynamic_storage_backends=no # Check whether --enable-dynamic-storage_backends was given. if test "${enable_dynamic_storage_backends+set}" = set; then : enableval=$enable_dynamic_storage_backends; if test x$enableval = xyes; then use_dynamic_storage_backends=yes $as_echo "#define HAVE_DYNAMIC_SD_BACKENDS 1" >>confdefs.h fi fi if test "x$use_libtool" != "xyes" -a "x$use_dynamic_storage_backends" = "xyes"; then echo "" echo "You specified --enable-dynamic-storage-plugins but disabled libtool with --disable-libtool" echo "We only support dynamic loading using libtool so either disable dynamic loading or enable libtool" echo "" echo "Aborting the configuration ..." echo " " echo " " exit 1 fi if test x$use_dynamic_storage_backends = xyes; then NEEDED_DEVICE_API_SRCS="" NEEDED_BACKEND_LIBS="" SD_BACKENDS_DIR="src/stored/backends" else NEEDED_DEVICE_API_SRCS="\$(AVAILABLE_DEVICE_API_SRCS)" NEEDED_BACKEND_LIBS="\$(AVAILABLE_BACKEND_LIBS)" SD_BACKENDS_DIR="" fi # Check whether --enable-conio was given. if test "${enable_conio+set}" = set; then : enableval=$enable_conio; if test x$enableval = xno; then support_conio=no fi fi support_ipv6=yes # Check whether --enable-ipv6 was given. if test "${enable_ipv6+set}" = set; then : enableval=$enable_ipv6; if test x$enableval = xno; then support_ipv6=no fi fi if test x$support_ipv6 = xyes; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : support_ipv6=yes else support_ipv6=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test x$support_ipv6 = xyes; then $as_echo "#define HAVE_IPV6 1" >>confdefs.h fi TERM_LIB="" ac_fn_c_check_header_mongrel "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" if test "x$ac_cv_header_curses_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5 $as_echo_n "checking for tgetent in -ltinfo... " >&6; } if ${ac_cv_lib_tinfo_tgetent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltinfo $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tinfo_tgetent=yes else ac_cv_lib_tinfo_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5 $as_echo "$ac_cv_lib_tinfo_tgetent" >&6; } if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then : TERM_LIB="-ltinfo" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 $as_echo_n "checking for tgetent in -lncurses... " >&6; } if ${ac_cv_lib_ncurses_tgetent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lncurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ncurses_tgetent=yes else ac_cv_lib_ncurses_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 $as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : TERM_LIB="-lncurses" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 $as_echo_n "checking for tgetent in -ltermcap... " >&6; } if ${ac_cv_lib_termcap_tgetent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltermcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_termcap_tgetent=yes else ac_cv_lib_termcap_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 $as_echo "$ac_cv_lib_termcap_tgetent" >&6; } if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : TERM_LIB="-ltermcap" fi fi fi else for ac_header in curses.h do : ac_fn_c_check_header_mongrel "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" if test "x$ac_cv_header_curses_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CURSES_H 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "term.h" "ac_cv_header_term_h" "$ac_includes_default" if test "x$ac_cv_header_term_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lcurses" >&5 $as_echo_n "checking for tgetent in -lcurses... " >&6; } if ${ac_cv_lib_curses_tgetent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tgetent (); int main () { return tgetent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_curses_tgetent=yes else ac_cv_lib_curses_tgetent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_tgetent" >&5 $as_echo "$ac_cv_lib_curses_tgetent" >&6; } if test "x$ac_cv_lib_curses_tgetent" = xyes; then : TERM_LIB="-lcurses" fi fi fi got_conio="no" if test x$support_conio = xyes; then if test x$TERM_LIB != x; then CONS_LIBS=$TERM_LIB CONS_SRC="conio.c" got_conio="yes" support_readline=no $as_echo "#define HAVE_CONIO 1" >>confdefs.h else echo " "; echo "Required libraries not found. CONIO turned off ..."; echo " " fi fi # Check whether --enable-readline was given. if test "${enable_readline+set}" = set; then : enableval=$enable_readline; if test x$enableval = xno; then support_readline=no fi fi if test x$TERM_LIB = x ; then support_readline=no fi got_readline="no" READLINE_SRC= if test x$support_readline = xyes; then # Check whether --with-readline was given. if test "${with_readline+set}" = set; then : withval=$with_readline; case "$with_readline" in no) : ;; yes|*) if test -f ${with_readline}/readline.h; then CONS_INC="-I${with_readline}" CONS_LDFLAGS="-L$with_readline" elif test -f ${with_readline}/include/readline/readline.h; then CONS_INC="-I${with_readline}/include/readline" CONS_LDFLAGS="-L${with_readline}/lib" with_readline="${with_readline}/include/readline" else CONS_INC="-I/usr/include/readline" with_readline="/usr/include/readline" fi as_ac_Header=`$as_echo "ac_cv_header_${with_readline}/readline.h" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "${with_readline}/readline.h" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : $as_echo "#define HAVE_READLINE 1" >>confdefs.h CONS_LIBS="-lreadline -lhistory $TERM_LIB" got_readline="yes" else echo " " echo "readline.h not found. readline turned off ..." echo " " fi ;; esac else ac_fn_c_check_header_mongrel "$LINENO" "/usr/include/readline/readline.h" "ac_cv_header__usr_include_readline_readline_h" "$ac_includes_default" if test "x$ac_cv_header__usr_include_readline_readline_h" = xyes; then : $as_echo "#define HAVE_READLINE 1" >>confdefs.h got_readline="yes" CONS_INC="-I/usr/include/readline" CONS_LIBS="-lreadline $TERM_LIB" else as_ac_Header=`$as_echo "ac_cv_header_${TOP_DIR}/depkgs/readline/readline.h" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "${TOP_DIR}/depkgs/readline/readline.h" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : $as_echo "#define HAVE_READLINE 1" >>confdefs.h got_readline="yes" CONS_INC="-I${TOP_DIR}/depkgs/readline" CONS_LIBS="-lreadline -lhistory $TERM_LIB" CONS_LDFLAGS="-L${TOP_DIR}/depkgs/readline" PRTREADLINE_SRC="${TOP_DIR}/depkgs/readline" else echo " " echo "readline.h not found. readline turned off ..." echo " " fi fi fi fi # Check whether --enable-dynamic-debian-package-list was given. if test "${enable_dynamic_debian_package_list+set}" = set; then : enableval=$enable_dynamic_debian_package_list; if test x$enableval = xyes; then generate_debian_control=yes fi fi DEBIAN_CONTROL= if test x$generate_debian_control = xyes; then DEBIAN_CONTROL="debian/control" fi MAKE_SHELL=/bin/sh { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5 $as_echo_n "checking whether stat file-mode macros are broken... " >&6; } if ${ac_cv_header_stat_broken+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if defined S_ISBLK && defined S_IFDIR extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; #endif #if defined S_ISBLK && defined S_IFCHR extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; #endif #if defined S_ISLNK && defined S_IFREG extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; #endif #if defined S_ISSOCK && defined S_IFREG extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stat_broken=no else ac_cv_header_stat_broken=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5 $as_echo "$ac_cv_header_stat_broken" >&6; } if test $ac_cv_header_stat_broken = yes; then $as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi ac_fn_c_check_header_mongrel "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" if test "x$ac_cv_header_poll_h" = xyes; then : $as_echo "#define HAVE_POLL_H 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default" if test "x$ac_cv_header_sys_poll_h" = xyes; then : $as_echo "#define HAVE_SYS_POLL_H 1" >>confdefs.h fi for ac_func in strcasecmp select poll setenv putenv tcgetattr do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in lstat lchown lchmod utimes lutimes futimes futimens fchmod fchown do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in nanosleep nl_langinfo do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in varargs.h do : ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" if test "x$ac_cv_header_varargs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VARARGS_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python support" >&5 $as_echo_n "checking for Python support... " >&6; } # Check whether --with-python was given. if test "${with_python+set}" = set; then : withval=$with_python; PYTHON_INC= PYTHON_LIBS= if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -e /usr/bin/python-config ; then PYTHON_INC=`/usr/bin/python-config --includes` PYTHON_LIBS=`/usr/bin/python-config --libs` else for python_root in /usr /usr/local /usr/sfw; do for ver in python2.2 python2.3 python2.4 python2.5 python2.6 python2.7 python3; do if test -f $python_root/include/${ver}/Python.h; then PYTHON_INC=-I$python_root/include/${ver} if test -d $python_root/lib64/${ver}/config; then PYTHON_LIBS="-L$python_root/lib64/${ver}/config -l${ver}" else PYTHON_LIBS="-L$python_root/lib/${ver}/config -l${ver}" fi break fi done done if test x$PYTHON_INC = x; then if test -f $prefix/include/Python.h; then PYTHON_INC=-I$prefix/include if test -d $prefix/lib64/config; then PYTHON_LIBS="-L$prefix/lib64/config -lpython" else PYTHON_LIBS="-L$prefix/lib/config -lpython" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find Python.h in standard locations" "$LINENO" 5 fi fi fi else if test -e $withval/bin/python-config ; then PYTHON_INC=`$withval/bin/python-config --includes` PYTHON_LIBS=`$withval/bin/python-config --libs` elif test -f $withval/Python.h; then PYTHON_INC=-I$withval PYTHON_LIBS="-L$withval/config -lpython" elif test -f $withval/include/Python.h; then PYTHON_INC=-I$withval/include if test -d $withval/lib64/config; then PYTHON_LIBS="-L$withval/lib64/config -lpython" else PYTHON_LIBS="-L$withval/lib/config -lpython" fi elif test -f $withval/include/python/Python.h; then PYTHON_INC=-I$withval/include/python if test -d $withval/lib64/python/config; then PYTHON_LIBS="-L$withval/lib64/python/config -lpython" else PYTHON_LIBS="-L$withval/lib/python/config -lpython" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Invalid Python directory $withval - unable to find Python.h under $withval" "$LINENO" 5 fi fi $as_echo "#define HAVE_PYTHON 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } support_python=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for more Python libs" >&5 $as_echo "$as_me: checking for more Python libs" >&6;} saved_LIBS="$LIBS"; LIBS= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 $as_echo_n "checking for library containing shm_open... " >&6; } if ${ac_cv_search_shm_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shm_open (); int main () { return shm_open (); ; return 0; } _ACEOF for ac_lib in '' rt; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_shm_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_shm_open+:} false; then : break fi done if ${ac_cv_search_shm_open+:} false; then : else ac_cv_search_shm_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5 $as_echo "$ac_cv_search_shm_open" >&6; } ac_res=$ac_cv_search_shm_open if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 $as_echo_n "checking for openpty in -lutil... " >&6; } if ${ac_cv_lib_util_openpty+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char openpty (); int main () { return openpty (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_util_openpty=yes else ac_cv_lib_util_openpty=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 $as_echo "$ac_cv_lib_util_openpty" >&6; } if test "x$ac_cv_lib_util_openpty" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBUTIL 1 _ACEOF LIBS="-lutil $LIBS" fi PYTHON_LIBS="$PYTHON_LIBS $LIBS" LIBS="$saved_LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: using socket from libc" >&5 $as_echo "using socket from libc" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if ${ac_cv_lib_socket_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_socket=yes else ac_cv_lib_socket_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = xyes; then : LIBS="-lsocket $LIBS" SOCKLIBS="-lsocket $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lxnet" >&5 $as_echo_n "checking for socket in -lxnet... " >&6; } if ${ac_cv_lib_xnet_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_xnet_socket=yes else ac_cv_lib_xnet_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_socket" >&5 $as_echo "$ac_cv_lib_xnet_socket" >&6; } if test "x$ac_cv_lib_xnet_socket" = xyes; then : LIBS="-lxnet $LIBS" SOCKLIBS="-lxnet $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -linet" >&5 $as_echo_n "checking for socket in -linet... " >&6; } if ${ac_cv_lib_inet_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_inet_socket=yes else ac_cv_lib_inet_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_socket" >&5 $as_echo "$ac_cv_lib_inet_socket" >&6; } if test "x$ac_cv_lib_inet_socket" = xyes; then : LIBS="-linet $LIBS" SOCKLIBS="-linet $LIBS" fi fi fi fi TCPW_MSG="no" WRAPLIBS="" # Check whether --with-tcp-wrappers was given. if test "${with_tcp_wrappers+set}" = set; then : withval=$with_tcp_wrappers; if test "x$withval" != "xno" ; then saved_LIBS="$LIBS" LIBS="$saved_LIBS -lwrap" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing nanosleep" >&5 $as_echo_n "checking for library containing nanosleep... " >&6; } if ${ac_cv_search_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF for ac_lib in '' rt; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_nanosleep=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_nanosleep+:} false; then : break fi done if ${ac_cv_search_nanosleep+:} false; then : else ac_cv_search_nanosleep=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_nanosleep" >&5 $as_echo "$ac_cv_search_nanosleep" >&6; } ac_res=$ac_cv_search_nanosleep if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libwrap" >&5 $as_echo_n "checking for libwrap... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int deny_severity = 0; int allow_severity = 0; struct request_info *req; int main () { hosts_access(req); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_LIBWRAP 1" >>confdefs.h TCPW_MSG="yes" LIBS="$saved_LIBS" WRAPLIBS="-lwrap" else LIBS="$saved_LIBS -lwrap -lnsl" WRAPLIBS="$saved_LIBS -lwrap -lnsl" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int deny_severity = 0; int allow_severity = 0; struct request_info *req; int main () { hosts_access(req); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_LIBWRAP 1" >>confdefs.h TCPW_MSG="yes" LIBS="$saved_LIBS" WRAPLIBS="-lwrap" else as_fn_error $? "*** libwrap missing" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi fi support_crypto=auto # Check whether --enable-crypto was given. if test "${enable_crypto+set}" = set; then : enableval=$enable_crypto; if test x$enableval = xyes; then support_crypto=yes elif test x$enableval = xno; then support_crypto=no fi fi support_tls=auto # Check whether --enable-tls was given. if test "${enable_tls+set}" = set; then : enableval=$enable_tls; if test x$enableval = xyes; then support_tls=yes elif test x$enableval = xno; then support_tls=no fi fi have_crypto=no have_tls=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL" >&5 $as_echo_n "checking for OpenSSL... " >&6; } # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then : withval=$with_openssl; with_openssl_directory=${withval} fi if test "x$support_crypto" != "xno" -o "x$support_tls" != "xno"; then if test "x$with_openssl_directory" != "xno"; then OPENSSL_LIBS="-lssl -lcrypto" OPENSSL_INC="" if test "x$with_openssl_directory" != "xyes" && test x"${with_openssl_directory}" != "x"; then # # Make sure the $with_openssl_directory also makes sense # if test -d "$with_openssl_directory/lib" -a -d "$with_openssl_directory/include"; then OPENSSL_LIBS="-L$with_openssl_directory/lib $OPENSSL_LIBS" OPENSSL_INC="-I$with_openssl_directory/include $OPENSSL_INC" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CFLAGS}" LIBS="${saved_LIBS} ${OPENSSL_LIBS}" CFLAGS="${saved_CFLAGS} ${OPENSSL_INC}" CPPFLAGS="${saved_CPPFLAGS} ${OPENSSL_INC}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { ENGINE_load_pk11(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ENGINE_LOAD_PK11 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CRYPTO_set_id_callback(NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_openssl="yes" else have_openssl="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { EVP_sha512(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_openssl_sha2="yes" else ac_cv_openssl_sha2="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { EVP_aes_192_cbc(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_openssl_export="no" else ac_cv_openssl_export="yes" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_crypto" >&5 $as_echo "$have_crypto" >&6; } if test "$have_openssl" = "yes"; then $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h fi if test "$support_crypto" != "no" -a "$have_openssl" = "yes"; then have_crypto="yes" $as_echo "#define HAVE_CRYPTO 1" >>confdefs.h fi if test "$support_tls" != "no" -a "$have_openssl" = "yes"; then have_tls="yes" $as_echo "#define HAVE_TLS 1" >>confdefs.h fi if test "$ac_cv_openssl_sha2" = "yes"; then $as_echo "#define HAVE_SHA2 1" >>confdefs.h fi if test "$ac_cv_openssl_export" = "yes"; then $as_echo "#define HAVE_OPENSSL_EXPORT_LIBRARY 1" >>confdefs.h fi LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" else have_openssl="no" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "$have_openssl" = "no"; then OPENSSL_LIBS="" OPENSSL_INC="" fi if test x$use_libtool != xno; then OPENSSL_LIBS_NONSHARED="" else OPENSSL_LIBS_NONSHARED="${OPENSSL_LIBS}" fi with_gnutls_directory=no # Check whether --with-gnutls was given. if test "${with_gnutls+set}" = set; then : withval=$with_gnutls; with_gnutls_directory=${withval} fi if test "x$support_crypto" != "xno" -o "x$support_tls" != "xno"; then if test "x$have_openssl" != "xyes" -a "x$with_gnutls_directory" != "xno"; then GNUTLS_LIBS="-lgnutls" GNUTLS_INC="" if test "x$with_gnutls_directory" != "xyes" && test x"${with_gnutls_directory}" != "x"; then # # Make sure the $with_gnutls_directory also makes sense # if test -d "$with_gnutls_directory/lib" -a -d "$with_gnutls_directory/include"; then GNUTLS_LIBS="-L$with_gnutls_directory/lib $GNUTLS_LIBS" GNUTLS_INC="-I$with_gnutls_directory/include $GNUTLS_INC" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CFLAGS}" LIBS="${saved_LIBS} ${GNUTLS_LIBS}" CFLAGS="${saved_CFLAGS} ${GNUTLS_INC}" CPPFLAGS="${saved_CPPFLAGS} ${GNUTLS_INC}" for ac_header in gnutls/gnutls.h do : ac_fn_c_check_header_mongrel "$LINENO" "gnutls/gnutls.h" "ac_cv_header_gnutls_gnutls_h" "$ac_includes_default" if test "x$ac_cv_header_gnutls_gnutls_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GNUTLS_GNUTLS_H 1 _ACEOF fi done if test $ac_cv_header_gnutls_gnutls_h = yes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gnutls_init in -lgnutls" >&5 $as_echo_n "checking for gnutls_init in -lgnutls... " >&6; } if ${ac_cv_lib_gnutls_gnutls_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgnutls $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gnutls_init (); int main () { return gnutls_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gnutls_gnutls_init=yes else ac_cv_lib_gnutls_gnutls_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gnutls_gnutls_init" >&5 $as_echo "$ac_cv_lib_gnutls_gnutls_init" >&6; } if test "x$ac_cv_lib_gnutls_gnutls_init" = xyes; then : have_gnutls="yes" else have_gnutls="no" fi fi if test "$have_gnutls" = "yes"; then # do an additional check to see if required functions are available, # otherwise disable gnutls for ac_func in gnutls_cipher_init do : ac_fn_c_check_func "$LINENO" "gnutls_cipher_init" "ac_cv_func_gnutls_cipher_init" if test "x$ac_cv_func_gnutls_cipher_init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GNUTLS_CIPHER_INIT 1 _ACEOF have_gnutls="yes" else have_gnutls="no" fi done fi if test "$have_gnutls" = "yes"; then $as_echo "#define HAVE_GNUTLS 1" >>confdefs.h # gnutls_transport_set_ptr may cause problems on some platforms, # therefore the replacement gnutls_transport_set_int is used # when available (since GnuTLS >= 3.1.9) for ac_func in gnutls_transport_set_int do : ac_fn_c_check_func "$LINENO" "gnutls_transport_set_int" "ac_cv_func_gnutls_transport_set_int" if test "x$ac_cv_func_gnutls_transport_set_int" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GNUTLS_TRANSPORT_SET_INT 1 _ACEOF fi done fi if test "$support_tls" != "no" -a "$have_gnutls" = "yes"; then have_tls="yes" $as_echo "#define HAVE_TLS 1" >>confdefs.h fi LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" else have_gnutls="no" fi fi if test "$have_gnutls" = "no"; then GNUTLS_LIBS="" GNUTLS_INC="" fi if test x$use_libtool != xno; then GNUTLS_LIBS_NONSHARED="" else GNUTLS_LIBS_NONSHARED="${GNUTLS_LIBS}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi working_dir=`eval echo ${prefix}/var/bareos/working` # Check whether --with-working-dir was given. if test "${with_working_dir+set}" = set; then : withval=$with_working_dir; if test "x$withval" != "xno" ; then working_dir=$withval fi fi cat >>confdefs.h <<_ACEOF #define _PATH_BAREOS_WORKINGDIR "$working_dir" _ACEOF archivedir=/tmp # Check whether --with-archivedir was given. if test "${with_archivedir+set}" = set; then : withval=$with_archivedir; if test "x$withval" != "xno" ; then archivedir=$withval fi fi basename=`hostname` # Check whether --with-basename was given. if test "${with_basename+set}" = set; then : withval=$with_basename; if test "x$withval" != "xno" ; then basename=$withval fi fi hostname=`uname -n | cut -d '.' -f 1` if test x${hostname} = x ; then hostname="localhost" fi ping -c 1 $hostname 2>/dev/null 1>/dev/null if test ! $? = 0; then hostname="localhost" fi # Check whether --with-hostname was given. if test "${with_hostname+set}" = set; then : withval=$with_hostname; if test "x$withval" != "xno" ; then hostname=$withval fi fi scriptdir=`eval echo ${sysconfdir}` # Check whether --with-scriptdir was given. if test "${with_scriptdir+set}" = set; then : withval=$with_scriptdir; if test "x$withval" != "xno" ; then scriptdir=$withval fi fi # ------------------------------------------ # Where to place backenddir (backend library files) # ------------------------------------------ backenddir=`eval echo ${libdir}` # Check whether --with-backenddir was given. if test "${with_backenddir+set}" = set; then : withval=$with_backenddir; if test "x$withval" != "xno" ; then backenddir=$withval fi fi cat >>confdefs.h <<_ACEOF #define _PATH_BAREOS_BACKENDDIR "$backenddir" _ACEOF bsrdir=`eval echo ${prefix}/var/bareos/working` # Check whether --with-bsrdir was given. if test "${with_bsrdir+set}" = set; then : withval=$with_bsrdir; if test "x$withval" != "xno" ; then bsrdir=$withval fi fi logdir=`eval echo ${prefix}/var/bareos/logs` # Check whether --with-logdir was given. if test "${with_logdir+set}" = set; then : withval=$with_logdir; if test "x$withval" != "xno" ; then logdir=$withval fi fi # ------------------------------------------ # Where to place plugindir (plugin files) # ------------------------------------------ plugindir=`eval echo ${libdir}` # Check whether --with-plugindir was given. if test "${with_plugindir+set}" = set; then : withval=$with_plugindir; if test "x$withval" != "xno" ; then plugindir=$withval fi fi # ------------------------------------------ # Where to place configtemplatedir (configuration template files) # ------------------------------------------ configtemplatedir=`eval echo ${libdir}` # Check whether --with-configtemplatedir was given. if test "${with_configtemplatedir+set}" = set; then : withval=$with_configtemplatedir; if test "x$withval" != "xno" ; then configtemplatedir=$withval fi fi dump_email=root@localhost # Check whether --with-dump-email was given. if test "${with_dump_email+set}" = set; then : withval=$with_dump_email; if test "x$withval" != "xno" ; then dump_email=$withval fi fi job_email=root@localhost # Check whether --with-job-email was given. if test "${with_job_email+set}" = set; then : withval=$with_job_email; if test "x$withval" != "xno" ; then job_email=$withval fi fi smtp_host=localhost # Check whether --with-smtp_host was given. if test "${with_smtp_host+set}" = set; then : withval=$with_smtp_host; if test "x$withval" != "xno" ; then smtp_host=$withval fi fi piddir=/var/run # Check whether --with-pid-dir was given. if test "${with_pid_dir+set}" = set; then : withval=$with_pid_dir; if test "x$withval" != "xno" ; then piddir=$withval fi fi cat >>confdefs.h <<_ACEOF #define _PATH_BAREOS_PIDDIR "$piddir" _ACEOF subsysdir=/var/run/subsys if test -d /var/run/subsys; then subsysdir=/var/run/subsys elif test -d /var/lock/subsys; then subsysdir=/var/lock/subsys else subsysdir=/var/run/subsys fi # Check whether --with-subsys-dir was given. if test "${with_subsys_dir+set}" = set; then : withval=$with_subsys_dir; if test "x$withval" != "xno" ; then subsysdir=$withval fi fi baseport=9101 # Check whether --with-baseport was given. if test "${with_baseport+set}" = set; then : withval=$with_baseport; if test "x$withval" != "xno" ; then baseport=$withval fi fi dir_port=`expr $baseport` fd_port=`expr $baseport + 1` sd_port=`expr $fd_port + 1` dir_password= # Check whether --with-dir-password was given. if test "${with_dir_password+set}" = set; then : withval=$with_dir_password; if test "x$withval" != "xno" ; then dir_password=$withval fi fi if test "x$dir_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 33` else key=`openssl rand -base64 33` fi dir_password=$key fi fd_password= # Check whether --with-fd-password was given. if test "${with_fd_password+set}" = set; then : withval=$with_fd_password; if test "x$withval" != "xno" ; then fd_password=$withval fi fi if test "x$fd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 37` else key=`openssl rand -base64 33` fi fd_password=$key fi sd_password= # Check whether --with-sd-password was given. if test "${with_sd_password+set}" = set; then : withval=$with_sd_password; if test "x$withval" != "xno" ; then sd_password=$withval fi fi if test "x$sd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 41` else key=`openssl rand -base64 33` fi sd_password=$key fi mon_dir_password= # Check whether --with-mon-dir-password was given. if test "${with_mon_dir_password+set}" = set; then : withval=$with_mon_dir_password; if test "x$withval" != "xno" ; then mon_dir_password=$withval fi fi if test "x$mon_dir_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 33` else key=`openssl rand -base64 33` fi mon_dir_password=$key fi mon_fd_password= # Check whether --with-mon-fd-password was given. if test "${with_mon_fd_password+set}" = set; then : withval=$with_mon_fd_password; if test "x$withval" != "xno" ; then mon_fd_password=$withval fi fi if test "x$mon_fd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 37` else key=`openssl rand -base64 33` fi mon_fd_password=$key fi mon_sd_password= # Check whether --with-mon-sd-password was given. if test "${with_mon_sd_password+set}" = set; then : withval=$with_mon_sd_password; if test "x$withval" != "xno" ; then mon_sd_password=$withval fi fi if test "x$mon_sd_password" = "x" ; then if test "x$OPENSSL" = "xnone" ; then key=`autoconf/randpass 41` else key=`openssl rand -base64 33` fi mon_sd_password=$key fi db_name=bareos # Check whether --with-db_name was given. if test "${with_db_name+set}" = set; then : withval=$with_db_name; if test "x$withval" != "x" ; then db_name=$withval fi fi db_user=bareos # Check whether --with-db_user was given. if test "${with_db_user+set}" = set; then : withval=$with_db_user; if test "x$withval" != "x" ; then db_user=$withval fi fi db_password= # Check whether --with-db_password was given. if test "${with_db_password+set}" = set; then : withval=$with_db_password; if test "x$withval" != "x" ; then db_password=$withval fi fi db_port=" " # Check whether --with-db_port was given. if test "${with_db_port+set}" = set; then : withval=$with_db_port; if test "x$withval" != "x" ; then db_port=$withval fi fi # # Handle users and groups for each daemon # dir_user= # Check whether --with-dir_user was given. if test "${with_dir_user+set}" = set; then : withval=$with_dir_user; if test "x$withval" != "x" ; then dir_user=$withval fi fi dir_group= # Check whether --with-dir_group was given. if test "${with_dir_group+set}" = set; then : withval=$with_dir_group; if test "x$withval" != "x" ; then dir_group=$withval fi fi sd_user= # Check whether --with-sd_user was given. if test "${with_sd_user+set}" = set; then : withval=$with_sd_user; if test "x$withval" != "x" ; then sd_user=$withval fi fi sd_group= # Check whether --with-sd_group was given. if test "${with_sd_group+set}" = set; then : withval=$with_sd_group; if test "x$withval" != "x" ; then sd_group=$withval fi fi fd_user= # Check whether --with-fd_user was given. if test "${with_fd_user+set}" = set; then : withval=$with_fd_user; if test "x$withval" != "x" ; then fd_user=$withval fi fi fd_group= # Check whether --with-fd_group was given. if test "${with_fd_group+set}" = set; then : withval=$with_fd_group; if test "x$withval" != "x" ; then fd_group=$withval fi fi SBINPERM=0750 # Check whether --with-sbin-perm was given. if test "${with_sbin_perm+set}" = set; then : withval=$with_sbin_perm; if test "x$withval" != "x" ; then SBINPERM=$withval fi fi # Extract the first word of "logrotate", so it can be a program name with args. set dummy logrotate; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LOGROTATE+:} false; then : $as_echo_n "(cached) " >&6 else case $LOGROTATE in [\\/]* | ?:[\\/]*) ac_cv_path_LOGROTATE="$LOGROTATE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LOGROTATE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LOGROTATE=$ac_cv_path_LOGROTATE if test -n "$LOGROTATE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOGROTATE" >&5 $as_echo "$LOGROTATE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi logrotate_su="" if test "x$LOGROTATE" != "x" -a "x$dir_user" != "x" -a "x$dir_group" != "x"; then echo -e "/tmp/dummy.log {\n su root root\n}" > logrotate-test-su.conf if $LOGROTATE -d logrotate-test-su.conf 2>&1 | grep "unknown option 'su'" >/dev/null; then logrotate_su="" else logrotate_su="su ${dir_user} ${dir_group}" fi rm logrotate-test-su.conf fi # Check whether --enable-ndmp was given. if test "${enable_ndmp+set}" = set; then : enableval=$enable_ndmp; if test x$enableval = xyes; then $as_echo "#define HAVE_NDMP 1" >>confdefs.h support_ndmp=yes fi fi if test x$support_ndmp = xyes; then NDMP_DIR="src/ndmp" NDMP_LIBS="-L../ndmp -lbareosndmp" NDMP_DEPS="../ndmp/libbareosndmp\$(DEFAULT_ARCHIVE_TYPE)" else NDMP_DIR="" NDMP_LIBS="" NDMP_DEPS="" fi # Check whether --enable-lmdb was given. if test "${enable_lmdb+set}" = set; then : enableval=$enable_lmdb; if test x$enableval = xyes; then $as_echo "#define HAVE_LMDB 1" >>confdefs.h support_lmdb=yes fi fi if test x$support_lmdb = xyes; then LMDB_DIR="src/lmdb" LMDB_LIBS="-L../lmdb -lbareoslmdb" LMDB_DEPS="../lmdb/libbareoslmdb\$(DEFAULT_ARCHIVE_TYPE)" else LMDB_DIR="" LMDB_LIBS="" LMDB_DEPS="" fi support_batch_insert=yes # Check whether --enable-batch-insert was given. if test "${enable_batch_insert+set}" = set; then : enableval=$enable_batch_insert; if test x$enableval = xno; then support_batch_insert=no fi fi if test x$support_batch_insert = xyes; then $as_echo "#define USE_BATCH_FILE_INSERT 1" >>confdefs.h fi use_dynamic_cats_backends=no # Check whether --enable-dynamic-cats-backends was given. if test "${enable_dynamic_cats_backends+set}" = set; then : enableval=$enable_dynamic_cats_backends; if test x$enableval = xyes; then use_dynamic_cats_backends=yes $as_echo "#define HAVE_DYNAMIC_CATS_BACKENDS 1" >>confdefs.h fi fi if test "x$use_libtool" != "xyes" -a "x$use_dynamic_cats_backends" = "xyes"; then echo "" echo "You specified --enable-dynamic-cats-plugins but disabled libtool with --disable-libtool" echo "We only support dynamic loading using libtool so either disable dynamic loading or enable libtool" echo "" echo "Aborting the configuration ..." echo " " echo " " exit 1 fi use_sql_pooling=no # Check whether --enable-sql-pooling was given. if test "${enable_sql_pooling+set}" = set; then : enableval=$enable_sql_pooling; if test x$enableval = xyes; then use_sql_pooling=yes $as_echo "#define HAVE_SQL_POOLING 1" >>confdefs.h fi fi uncomment_dbi="#" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PostgreSQL support" >&5 $as_echo_n "checking for PostgreSQL support... " >&6; } # Check whether --with-postgresql was given. if test "${with_postgresql+set}" = set; then : withval=$with_postgresql; if test "$withval" != "no"; then if test "$withval" = "yes"; then PG_CONFIG=`which pg_config 2>/dev/null` if test -n "$PG_CONFIG"; then POSTGRESQL_INCDIR=`"$PG_CONFIG" --includedir` POSTGRESQL_LIBDIR=`"$PG_CONFIG" --libdir` POSTGRESQL_BINDIR=`"$PG_CONFIG" --bindir` fi # # See if the pg_config gave something that is worth anything. # if test x${POSTGRESQL_LIBDIR} = x -o \ ! \( -f ${POSTGRESQL_LIBDIR}/libpq.so -o \ -f ${POSTGRESQL_LIBDIR}/libpq.a \); then if test -f /usr/local/include/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/local/include if test -d /usr/local/lib64; then POSTGRESQL_LIBDIR=/usr/local/lib64 else POSTGRESQL_LIBDIR=/usr/local/lib fi POSTGRESQL_BINDIR=/usr/local/bin elif test -f /usr/include/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/include if test -d /usr/lib64; then POSTGRESQL_LIBDIR=/usr/lib64 else POSTGRESQL_LIBDIR=/usr/lib fi POSTGRESQL_BINDIR=/usr/bin elif test -f /usr/include/pgsql/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/include/pgsql if test -d /usr/lib64/pgsql; then POSTGRESQL_LIBDIR=/usr/lib64/pgsql else POSTGRESQL_LIBDIR=/usr/lib/pgsql fi POSTGRESQL_BINDIR=/usr/bin elif test -f /usr/include/postgresql/libpq-fe.h; then POSTGRESQL_INCDIR=/usr/include/postgresql if test -d /usr/lib64/postgresql; then POSTGRESQL_LIBDIR=/usr/lib64/postgresql else POSTGRESQL_LIBDIR=/usr/lib/postgresql fi POSTGRESQL_BINDIR=/usr/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find libpq-fe.h in standard locations" "$LINENO" 5 fi fi else if test -f $withval/include/libpq-fe.h; then POSTGRESQL_INCDIR=$withval/include POSTGRESQL_LIBDIR=$withval/lib POSTGRESQL_BINDIR=$withval/bin elif test -f $withval/include/postgresql/libpq-fe.h; then POSTGRESQL_INCDIR=$withval/include/postgresql if test -d $withval/lib64; then POSTGRESQL_LIBDIR=$withval/lib64 else POSTGRESQL_LIBDIR=$withval/lib fi POSTGRESQL_BINDIR=$withval/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Invalid PostgreSQL directory $withval - unable to find libpq-fe.h under $withval" "$LINENO" 5 fi fi if test x$POSTGRESQL_LIBDIR != x; then $as_echo "#define HAVE_POSTGRESQL 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } POSTGRESQL_INCLUDE=-I$POSTGRESQL_INCDIR if test x$use_libtool != xno; then POSTGRESQL_LIBS="-R $POSTGRESQL_LIBDIR -L$POSTGRESQL_LIBDIR -lpq" else POSTGRESQL_LIBS="-L$POSTGRESQL_LIBDIR -lpq" fi ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt" if test "x$ac_cv_func_crypt" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_crypt=yes else ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 $as_echo "$ac_cv_lib_crypt_crypt" >&6; } if test "x$ac_cv_lib_crypt_crypt" = xyes; then : POSTGRESQL_LIBS="$POSTGRESQL_LIBS -lcrypt" fi fi POSTGRESQL_LIB=$POSTGRESQL_LIBDIR/libpq.a DB_LIBS="${DB_LIBS} ${POSTGRESQL_LIBS}" if test -z "${db_backends}"; then db_backends="PostgreSQL" else db_backends="${db_backends} PostgreSQL" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="postgresql" else DB_BACKENDS="${DB_BACKENDS} postgresql" fi if test "x$support_batch_insert" = "xyes"; then saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$POSTGRESQL_LIBDIR" saved_LIBS="${LIBS}" if test "x$ac_cv_lib_crypt_crypt" = "xyes" ; then LIBS="${saved_LIBS} -lcrypt" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQisthreadsafe in -lpq" >&5 $as_echo_n "checking for PQisthreadsafe in -lpq... " >&6; } if ${ac_cv_lib_pq_PQisthreadsafe+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char PQisthreadsafe (); int main () { return PQisthreadsafe (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pq_PQisthreadsafe=yes else ac_cv_lib_pq_PQisthreadsafe=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQisthreadsafe" >&5 $as_echo "$ac_cv_lib_pq_PQisthreadsafe" >&6; } if test "x$ac_cv_lib_pq_PQisthreadsafe" = xyes; then : $as_echo "#define HAVE_PQISTHREADSAFE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQputCopyData in -lpq" >&5 $as_echo_n "checking for PQputCopyData in -lpq... " >&6; } if ${ac_cv_lib_pq_PQputCopyData+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char PQputCopyData (); int main () { return PQputCopyData (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pq_PQputCopyData=yes else ac_cv_lib_pq_PQputCopyData=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQputCopyData" >&5 $as_echo "$ac_cv_lib_pq_PQputCopyData" >&6; } if test "x$ac_cv_lib_pq_PQputCopyData" = xyes; then : $as_echo "#define HAVE_PQ_COPY 1" >>confdefs.h fi if test "x$ac_cv_lib_pq_PQputCopyData" = "xyes"; then if test $support_batch_insert = yes ; then $as_echo "#define HAVE_POSTGRESQL_BATCH_FILE_INSERT 1" >>confdefs.h if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="PostgreSQL" else batch_insert_db_backends="${batch_insert_db_backends} PostgreSQL" fi fi fi if test x$ac_cv_lib_pq_PQisthreadsafe != xyes -a x$support_batch_insert = xyes; then echo "WARNING: Your PostgreSQL client library is too old to detect " echo "if it was compiled with --enable-thread-safety, consider to " echo "upgrade it in order to avoid problems with Batch insert mode" fi LDFLAGS="${saved_LDFLAGS}" LIBS="${saved_LIBS}" fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MySQL support" >&5 $as_echo_n "checking for MySQL support... " >&6; } # Check whether --with-mysql was given. if test "${with_mysql+set}" = set; then : withval=$with_mysql; if test "$withval" != "no"; then if test "$withval" = "yes"; then MYSQL_CONFIG=`which mysql_config 2>/dev/null` if test "x${MYSQL_CONFIG}" != x; then MYSQL_BINDIR="${MYSQL_CONFIG%/*}" ${MYSQL_CONFIG} --variable=pkglibdir > /dev/null 2>&1 if test $? = 0 ; then MYSQL_LIBDIR=`${MYSQL_CONFIG} --variable=pkglibdir` MYSQL_INCDIR=`${MYSQL_CONFIG} --variable=pkgincludedir` else MYSQL_LIBDIR=`${MYSQL_CONFIG} --libs | sed -e 's/.*-L//' -e 's/ .*//'` MYSQL_INCDIR=`${MYSQL_CONFIG} --include | sed -e 's/-I//'` fi fi # # See if the mysql_config gave something that is worth anything. # Some OS-es just lie about this when you ask for the library to use # they just give you back the directory its not in. # # Fallback to the old way of finding the right settings to use and hope for the best. # if test x${MYSQL_LIBDIR} = x -o \ ! \( -f ${MYSQL_LIBDIR}/libmysqlclient_r.so -o \ -f ${MYSQL_LIBDIR}/libmysqlclient_r.a \); then if test -f /usr/local/mysql/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/mysql/include/mysql if test -f /usr/local/mysql/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/local/mysql/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/mysql/lib64/mysql else MYSQL_LIBDIR=/usr/local/mysql/lib/mysql fi MYSQL_BINDIR=/usr/local/mysql/bin elif test -f /usr/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/include/mysql if test -f /usr/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64/mysql elif test -f /usr/lib64/libmysqlclient_r.a \ -o -f /usr/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64 elif test -f /usr/lib/x86_64-linux-gnu/libmysqlclient_r.a \ -o -f /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib/x86_64-linux-gnu elif test -f /usr/lib/mysql/libmysqlclient_r.a \ -o -f /usr/lib/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib/mysql else MYSQL_LIBDIR=/usr/lib fi MYSQL_BINDIR=/usr/bin elif test -f /usr/include/mysql.h; then MYSQL_INCDIR=/usr/include if test -f /usr/lib64/libmysqlclient_r.a \ -o -f /usr/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/lib64 else MYSQL_LIBDIR=/usr/lib fi MYSQL_BINDIR=/usr/bin elif test -f /usr/local/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/include/mysql if test -f /usr/local/lib64/mysql/libmysqlclient_r.a \ -o -f /usr/local/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/lib64/mysql else MYSQL_LIBDIR=/usr/local/lib/mysql fi MYSQL_BINDIR=/usr/local/bin elif test -f /usr/local/include/mysql.h; then MYSQL_INCDIR=/usr/local/include if test -f /usr/local/lib64/libmysqlclient_r.a \ -o -f /usr/local/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=/usr/local/lib64 else MYSQL_LIBDIR=/usr/local/lib fi MYSQL_BINDIR=/usr/local/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find mysql.h in standard locations" "$LINENO" 5 fi fi else if test -f $withval/include/mysql/mysql.h; then MYSQL_INCDIR=$withval/include/mysql if test -f $withval/lib64/mysql/libmysqlclient_r.a \ -o -f $withval/lib64/mysql/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64/mysql elif test -f $withval/lib64/libmysqlclient_r.a \ -o -f $withval/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64 elif test -f $withval/lib/libmysqlclient_r.a \ -o -f $withval/lib/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib else MYSQL_LIBDIR=$withval/lib/mysql fi MYSQL_BINDIR=$withval/bin elif test -f $withval/include/mysql.h; then MYSQL_INCDIR=$withval/include if test -f $withval/lib64/libmysqlclient_r.a \ -o -f $withval/lib64/libmysqlclient_r.so; then MYSQL_LIBDIR=$withval/lib64 else MYSQL_LIBDIR=$withval/lib fi MYSQL_BINDIR=$withval/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Invalid MySQL directory $withval - unable to find mysql.h under $withval" "$LINENO" 5 fi fi if test x${MYSQL_LIBDIR} != x; then MYSQL_INCLUDE=-I$MYSQL_INCDIR if test -f $MYSQL_LIBDIR/libmysqlclient_r.a \ -o -f $MYSQL_LIBDIR/libmysqlclient_r.so; then if test x$use_libtool != xno; then MYSQL_LIBS="-R $MYSQL_LIBDIR -L$MYSQL_LIBDIR -lmysqlclient_r -lz" else MYSQL_LIBS="-L$MYSQL_LIBDIR -lmysqlclient_r -lz" fi DB_LIBS="${DB_LIBS} ${MYSQL_LIBS}" fi MYSQL_LIB=$MYSQL_LIBDIR/libmysqlclient_r.a $as_echo "#define HAVE_MYSQL 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } if test -z "${db_backends}" ; then db_backends="MySQL" else db_backends="${db_backends} MySQL" fi if test -z "${DB_BACKENDS}" ; then DB_BACKENDS="mysql" else DB_BACKENDS="${DB_BACKENDS} mysql" fi if test "x$support_batch_insert" = "xyes"; then saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$MYSQL_LIBDIR" saved_LIBS="${LIBS}" LIBS="${saved_LIBS} -lz" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_thread_safe in -lmysqlclient_r" >&5 $as_echo_n "checking for mysql_thread_safe in -lmysqlclient_r... " >&6; } if ${ac_cv_lib_mysqlclient_r_mysql_thread_safe+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient_r $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mysql_thread_safe (); int main () { return mysql_thread_safe (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_mysqlclient_r_mysql_thread_safe=yes else ac_cv_lib_mysqlclient_r_mysql_thread_safe=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_r_mysql_thread_safe" >&5 $as_echo "$ac_cv_lib_mysqlclient_r_mysql_thread_safe" >&6; } if test "x$ac_cv_lib_mysqlclient_r_mysql_thread_safe" = xyes; then : $as_echo "#define HAVE_MYSQL_THREAD_SAFE 1" >>confdefs.h fi if test "x$ac_cv_lib_mysqlclient_r_mysql_thread_safe" = "xyes"; then if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="MySQL" else batch_insert_db_backends="${batch_insert_db_backends} MySQL" fi fi LDFLAGS="${saved_LDFLAGS}" LIBS="${saved_LIBS}" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MySQL embedded support" >&5 $as_echo_n "checking for MySQL embedded support... " >&6; } # Check whether --with-embedded-mysql was given. if test "${with_embedded_mysql+set}" = set; then : withval=$with_embedded_mysql; if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/local/mysql/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/mysql/include/mysql if test -d /usr/local/mysql/lib64/mysql; then MYSQL_LIBDIR=/usr/local/mysql/lib64/mysql else MYSQL_LIBDIR=/usr/local/mysql/lib/mysql fi MYSQL_BINDIR=/usr/local/mysql/bin elif test -f /usr/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/include/mysql if test -d /usr/lib64/mysql; then MYSQL_LIBDIR=/usr/lib64/mysql else MYSQL_LIBDIR=/usr/lib/mysql fi MYSQL_BINDIR=/usr/bin elif test -f /usr/include/mysql.h; then MYSQL_INCDIR=/usr/include if test -d /usr/lib64; then MYSQL_LIBDIR=/usr/lib64 else MYSQL_LIBDIR=/usr/lib fi MYSQL_BINDIR=/usr/bin elif test -f /usr/local/include/mysql/mysql.h; then MYSQL_INCDIR=/usr/local/include/mysql if test -d /usr/local/lib64/mysql; then MYSQL_LIBDIR=/usr/local/lib64/mysql else MYSQL_LIBDIR=/usr/local/lib/mysql fi MYSQL_BINDIR=/usr/local/bin elif test -f /usr/local/include/mysql.h; then MYSQL_INCDIR=/usr/local/include if test -d /usr/local/lib64; then MYSQL_LIBDIR=/usr/local/lib64 else MYSQL_LIBDIR=/usr/local/lib fi MYSQL_BINDIR=/usr/local/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find mysql.h in standard locations" "$LINENO" 5 fi else if test -f $withval/include/mysql/mysql.h; then MYSQL_INCDIR=$withval/include/mysql if test -d $withval/lib64/mysql; then MYSQL_LIBDIR=$withval/lib64/mysql else MYSQL_LIBDIR=$withval/lib/mysql fi MYSQL_BINDIR=$withval/bin elif test -f $withval/include/mysql.h; then MYSQL_INCDIR=$withval/include if test -d $withval/lib64; then MYSQL_LIBDIR=$withval/lib64 else MYSQL_LIBDIR=$withval/lib fi MYSQL_BINDIR=$withval/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Invalid MySQL directory $withval - unable to find mysql.h under $withval" "$LINENO" 5 fi fi if test x$MYSQL_LIBDIR != x; then MYSQL_INCLUDE=-I$MYSQL_INCDIR if test x$use_libtool != xno; then MYSQL_LIBS="-R $MYSQL_LIBDIR -L$MYSQL_LIBDIR -lmysqld -lz -lm -lcrypt" else MYSQL_LIBS="-L$MYSQL_LIBDIR -lmysqld -lz -lm -lcrypt" fi MYSQL_LIB=$MYSQL_LIBDIR/libmysqld.a DB_LIBS="${DB_LIBS} ${MYSQL_LIBS}" $as_echo "#define HAVE_MYSQL 1" >>confdefs.h $as_echo "#define HAVE_EMBEDDED_MYSQL 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } if test -z "${db_backends}"; then db_backends="MySQL" else db_backends="${db_backends} MySQL" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="mysql" else DB_BACKENDS="${DB_BACKENDS} mysql" fi if test "x$support_batch_insert" = "xyes"; then saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$MYSQL_LIBDIR" saved_LIBS="${LIBS}" LIBS="${saved_LIBS} -lz -lm -lcrypt" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_thread_safe in -lmysqlclient_r" >&5 $as_echo_n "checking for mysql_thread_safe in -lmysqlclient_r... " >&6; } if ${ac_cv_lib_mysqlclient_r_mysql_thread_safe+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient_r $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mysql_thread_safe (); int main () { return mysql_thread_safe (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_mysqlclient_r_mysql_thread_safe=yes else ac_cv_lib_mysqlclient_r_mysql_thread_safe=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_r_mysql_thread_safe" >&5 $as_echo "$ac_cv_lib_mysqlclient_r_mysql_thread_safe" >&6; } if test "x$ac_cv_lib_mysqlclient_r_mysql_thread_safe" = xyes; then : $as_echo "#define HAVE_MYSQL_THREAD_SAFE 1" >>confdefs.h fi if test "x$ac_cv_lib_mysqlclient_r_mysql_thread_safe" = "xyes"; then if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="MySQL" else batch_insert_db_backends="${batch_insert_db_backends} MySQL" fi fi LDFLAGS="${saved_LDFLAGS}" LIBS="${saved_LIBS}" fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SQLite3 support" >&5 $as_echo_n "checking for SQLite3 support... " >&6; } # Check whether --with-sqlite3 was given. if test "${with_sqlite3+set}" = set; then : withval=$with_sqlite3; if test "$withval" != "no"; then if test "$withval" = "yes"; then if test -f /usr/local/include/sqlite3.h; then SQLITE_INCDIR=/usr/local/include if test -d /usr/local/lib64; then SQLITE_LIBDIR=/usr/local/lib64 else SQLITE_LIBDIR=/usr/local/lib fi SQLITE_BINDIR=/usr/local/bin elif test -f /usr/include/sqlite3.h; then SQLITE_INCDIR=/usr/include if test -d /usr/lib64; then SQLITE_LIBDIR=/usr/lib64 else SQLITE_LIBDIR=/usr/lib fi SQLITE_BINDIR=/usr/bin elif test -f $prefix/include/sqlite3.h; then SQLITE_INCDIR=$prefix/include if test -d $prefix/lib64; then SQLITE_LIBDIR=$prefix/lib64 else SQLITE_LIBDIR=$prefix/lib fi SQLITE_BINDIR=$prefix/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Unable to find sqlite3.h in standard locations" "$LINENO" 5 fi else if test -f $withval/sqlite3.h; then SQLITE_INCDIR=$withval SQLITE_LIBDIR=$withval SQLITE_BINDIR=$withval elif test -f $withval/include/sqlite3.h; then SQLITE_INCDIR=$withval/include if test -d $withval/lib64; then SQLITE_LIBDIR=$withval/lib64 else SQLITE_LIBDIR=$withval/lib fi SQLITE_BINDIR=$withval/bin else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Invalid SQLite3 directory $withval - unable to find sqlite3.h under $withval" "$LINENO" 5 fi fi if test x$SQLITE_LIBDIR != x; then SQLITE_INCLUDE=-I$SQLITE_INCDIR if test x$use_libtool != xno; then SQLITE_LIBS="-R $SQLITE_LIBDIR -L$SQLITE_LIBDIR -lsqlite3" else SQLITE_LIBS="-L$SQLITE_LIBDIR -lsqlite3" fi SQLITE_LIB=$SQLITE_LIBDIR/libsqlite3.a DB_LIBS="${DB_LIBS} ${SQLITE_LIBS}" $as_echo "#define HAVE_SQLITE3 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } if test -z "${db_backends}"; then db_backends="SQLite3" else db_backends="${db_backends} SQLite3" fi if test -z "${DB_BACKENDS}"; then DB_BACKENDS="sqlite3" else DB_BACKENDS="${DB_BACKENDS} sqlite3" fi if test "x$support_batch_insert" = "xyes"; then saved_LDFLAGS="${LDFLAGS}" LDFLAGS="${saved_LDFLAGS} -L$SQLITE_LIBDIR" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_threadsafe in -lsqlite3" >&5 $as_echo_n "checking for sqlite3_threadsafe in -lsqlite3... " >&6; } if ${ac_cv_lib_sqlite3_sqlite3_threadsafe+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqlite3_threadsafe (); int main () { return sqlite3_threadsafe (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sqlite3_sqlite3_threadsafe=yes else ac_cv_lib_sqlite3_sqlite3_threadsafe=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_threadsafe" >&5 $as_echo "$ac_cv_lib_sqlite3_sqlite3_threadsafe" >&6; } if test "x$ac_cv_lib_sqlite3_sqlite3_threadsafe" = xyes; then : $as_echo "#define HAVE_SQLITE3_THREADSAFE 1" >>confdefs.h fi if test "x$ac_cv_lib_sqlite3_sqlite3_threadsafe" = "xyes"; then if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="SQLite3" else batch_insert_db_backends="${batch_insert_db_backends} SQLite3" fi fi LDFLAGS="${saved_LDFLAGS}" fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi #BA_CHECK_INGRES_DB #BA_CHECK_DBI_DB #BA_CHECK_DBI_DRIVER if test -z "${batch_insert_db_backends}"; then batch_insert_db_backends="None" fi if test x$build_client_only != xyes; then if test "x${db_backends}" = "x" ; then echo " " echo " " echo "You have not specified either --enable-client-only or one of the" echo "supported databases: MySQL, PostgreSQL, or SQLite3." echo "This is not permitted. Please reconfigure." echo " " echo "Aborting the configuration ..." echo " " echo " " exit 1 fi case `echo $DB_BACKENDS | wc -w | sed -e 's/^ *//'` in 1) DEFAULT_DB_TYPE="${DB_BACKENDS}" if test x$use_libtool = xno; then SHARED_CATALOG_TARGETS="" else SHARED_CATALOG_TARGETS="libbareoscats-${DEFAULT_DB_TYPE}.la" fi ;; *) DEFAULT_DB_TYPE=`echo ${DB_BACKENDS} | cut -d' ' -f1` if test x$use_libtool = xno; then echo " " echo " " echo "You have specified two or more of the" echo "supported databases: MySQL, PostgreSQL, or SQLite3." echo "This is not permitted when not using libtool Please reconfigure." echo " " echo "Aborting the configuration ..." echo " " echo " " exit 1 fi SHARED_CATALOG_TARGETS="" for db_type in ${DB_BACKENDS} do if test -z "${SHARED_CATALOG_TARGETS}"; then SHARED_CATALOG_TARGETS="libbareoscats-${db_type}.la" else SHARED_CATALOG_TARGETS="${SHARED_CATALOG_TARGETS} libbareoscats-${db_type}.la" fi done ;; esac fi if test x$use_dynamic_cats_backends = xyes; then LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET="" else LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET="libtool-install-default-backend" fi if test x$use_libtool = xyes; then DB_LIBS="" fi $as_echo "#define PROTOTYPES 1" >>confdefs.h if test -z "$CFLAGS" -o "$CFLAGS" = "-g -O2"; then if test -z "$CCOPTS"; then CCOPTS='-g -O2 -Wall' fi CFLAGS="$CCOPTS" fi largefile_support="no" # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}getconf", so it can be a program name with args. set dummy ${ac_tool_prefix}getconf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_GETCONF+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$GETCONF"; then ac_cv_prog_GETCONF="$GETCONF" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_GETCONF="${ac_tool_prefix}getconf" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi GETCONF=$ac_cv_prog_GETCONF if test -n "$GETCONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GETCONF" >&5 $as_echo "$GETCONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_GETCONF"; then ac_ct_GETCONF=$GETCONF # Extract the first word of "getconf", so it can be a program name with args. set dummy getconf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_GETCONF+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_GETCONF"; then ac_cv_prog_ac_ct_GETCONF="$ac_ct_GETCONF" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_GETCONF="getconf" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_GETCONF=$ac_cv_prog_ac_ct_GETCONF if test -n "$ac_ct_GETCONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GETCONF" >&5 $as_echo "$ac_ct_GETCONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_GETCONF" = x; then GETCONF="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac GETCONF=$ac_ct_GETCONF fi else GETCONF="$ac_cv_prog_GETCONF" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLAGS value to request large file support" >&5 $as_echo_n "checking for CFLAGS value to request large file support... " >&6; } if ${ac_cv_sys_largefile_CFLAGS+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CFLAGS=`($GETCONF LFS_CFLAGS) 2>/dev/null` || { ac_cv_sys_largefile_CFLAGS=no case "$host_os" in # IRIX 6.2 and later require cc -n32. irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) if test "$GCC" != yes; then ac_cv_sys_largefile_CFLAGS=-n32 fi ac_save_CC="$CC" CC="$CC $ac_cv_sys_largefile_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else ac_cv_sys_largefile_CFLAGS=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CC="$ac_save_CC" esac } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CFLAGS" >&5 $as_echo "$ac_cv_sys_largefile_CFLAGS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LDFLAGS value to request large file support" >&5 $as_echo_n "checking for LDFLAGS value to request large file support... " >&6; } if ${ac_cv_sys_largefile_LDFLAGS+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_LDFLAGS=`($GETCONF LFS_LDFLAGS) 2>/dev/null` || { ac_cv_sys_largefile_LDFLAGS=no } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_LDFLAGS" >&5 $as_echo "$ac_cv_sys_largefile_LDFLAGS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBS value to request large file support" >&5 $as_echo_n "checking for LIBS value to request large file support... " >&6; } if ${ac_cv_sys_largefile_LIBS+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_LIBS=`($GETCONF LFS_LIBS) 2>/dev/null` || { ac_cv_sys_largefile_LIBS=no } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_LIBS" >&5 $as_echo "$ac_cv_sys_largefile_LIBS" >&6; } for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in no) ;; -D_FILE_OFFSET_BITS=*) ;; -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; -D_LARGE_FILES | -D_LARGE_FILES=*) ;; -D?* | -I?*) case "$ac_flag" in no) ;; ?*) case "$CPPFLAGS" in '') CPPFLAGS="$ac_flag" ;; *) CPPFLAGS=$CPPFLAGS' '"$ac_flag" ;; esac ;; esac ;; *) case "$ac_flag" in no) ;; ?*) case "$CFLAGS" in '') CFLAGS="$ac_flag" ;; *) CFLAGS=$CFLAGS' '"$ac_flag" ;; esac ;; esac ;; esac done case "$ac_cv_sys_largefile_LDFLAGS" in no) ;; ?*) case "$LDFLAGS" in '') LDFLAGS="$ac_cv_sys_largefile_LDFLAGS" ;; *) LDFLAGS=$LDFLAGS' '"$ac_cv_sys_largefile_LDFLAGS" ;; esac ;; esac case "$ac_cv_sys_largefile_LIBS" in no) ;; ?*) case "$LIBS" in '') LIBS="$ac_cv_sys_largefile_LIBS" ;; *) LIBS=$LIBS' '"$ac_cv_sys_largefile_LIBS" ;; esac ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_file_offset_bits=no ac_cv_sys_file_offset_bits=64 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D_FILE_OFFSET_BITS) ac_cv_sys_file_offset_bits=1 ;; -D_FILE_OFFSET_BITS=*) ac_cv_sys_file_offset_bits=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } if test "$ac_cv_sys_file_offset_bits" != no; then cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_source=no ac_cv_sys_largefile_source=1 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D_LARGEFILE_SOURCE) ac_cv_sys_largefile_source=1 ;; -D_LARGEFILE_SOURCE=*) ac_cv_sys_largefile_source=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } if test "$ac_cv_sys_largefile_source" != no; then cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES" >&5 $as_echo_n "checking for _LARGE_FILES... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_large_files=no ac_cv_sys_large_files=1 for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do case "$ac_flag" in -D_LARGE_FILES) ac_cv_sys_large_files=1 ;; -D_LARGE_FILES=*) ac_cv_sys_large_files=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; esac done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } if test "$ac_cv_sys_large_files" != no; then cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. $as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 $as_echo_n "checking whether -R must be followed by a space... " >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" ac_xsave_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" else LIBS="$ac_xsave_LIBS -R $x_libraries" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 $as_echo "neither works" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_c_werror_flag=$ac_xsave_c_werror_flag LIBS=$ac_xsave_LIBS fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn Johnson says this is needed for Ultrix, if the X # libraries were built with DECnet support. And Karl Berry says # the Alpha needs dnet_stub (dnet does not exist). ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_dnet_ntoa=yes else ac_cv_lib_dnet_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_stub_dnet_ntoa=yes else ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to T.E. Dickey. # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_gethostbyname=yes else ac_cv_lib_bsd_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says Simon Leinen: it contains gethostby* # variants that don't use the name server (or something). -lsocket # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); int main () { return connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_connect=yes else ac_cv_lib_socket_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char remove (); int main () { return remove (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_posix_remove=yes else ac_cv_lib_posix_remove=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shmat (); int main () { return shmat (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ipc_shmat=yes else ac_cv_lib_ipc_shmat=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS=$LDFLAGS test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ICE_IceConnectionNumber=yes else ac_cv_lib_ICE_IceConnectionNumber=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi LDFLAGS=$ac_save_LDFLAGS fi for ac_header in \ assert.h \ dl.h \ dlfcn.h \ fcntl.h \ grp.h \ pwd.h \ libc.h \ limits.h \ stdarg.h \ stdlib.h \ stdint.h \ inttypes.h \ string.h \ strings.h \ termios.h \ termcap.h \ term.h \ unistd.h \ sys/bitypes.h \ sys/byteorder.h \ sys/ioctl.h \ sys/select.h \ sys/socket.h \ sys/sockio.h \ sys/stat.h \ sys/time.h \ sys/types.h \ arpa/nameser.h \ mtio.h \ sys/dl.h \ sys/mtio.h \ sys/tape.h \ regex.h \ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/types.h defines makedev" >&5 $as_echo_n "checking whether sys/types.h defines makedev... " >&6; } if ${ac_cv_header_sys_types_h_makedev+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return makedev(0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_header_sys_types_h_makedev=yes else ac_cv_header_sys_types_h_makedev=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_types_h_makedev" >&5 $as_echo "$ac_cv_header_sys_types_h_makedev" >&6; } if test $ac_cv_header_sys_types_h_makedev = no; then ac_fn_c_check_header_mongrel "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mkdev_h" = xyes; then : $as_echo "#define MAJOR_IN_MKDEV 1" >>confdefs.h fi if test $ac_cv_header_sys_mkdev_h = no; then ac_fn_c_check_header_mongrel "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sysmacros_h" = xyes; then : $as_echo "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h fi fi fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5 $as_echo_n "checking whether stat file-mode macros are broken... " >&6; } if ${ac_cv_header_stat_broken+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if defined S_ISBLK && defined S_IFDIR extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; #endif #if defined S_ISBLK && defined S_IFCHR extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; #endif #if defined S_ISLNK && defined S_IFREG extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; #endif #if defined S_ISSOCK && defined S_IFREG extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stat_broken=no else ac_cv_header_stat_broken=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5 $as_echo "$ac_cv_header_stat_broken" >&6; } if test $ac_cv_header_stat_broken = yes; then $as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if ${ac_cv_header_sys_wait_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 _ACEOF $as_echo "#define HAVE_ST_BLKSIZE 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLOCKS 1 _ACEOF $as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h else case " $LIBOBJS " in *" fileblocks.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fileblocks.$ac_objext" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } if ${ac_cv_struct_tm+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_tm=time.h else ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 $as_echo "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include #include <$ac_cv_struct_tm> " if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_TM_TM_ZONE 1 _ACEOF fi if test "$ac_cv_member_struct_tm_tm_zone" = yes; then $as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h else ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include " if test "x$ac_cv_have_decl_tzname" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_TZNAME $ac_have_decl _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5 $as_echo_n "checking for tzname... " >&6; } if ${ac_cv_var_tzname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if !HAVE_DECL_TZNAME extern char *tzname[]; #endif int main () { return tzname[0][0]; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_var_tzname=yes else ac_cv_var_tzname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5 $as_echo "$ac_cv_var_tzname" >&6; } if test $ac_cv_var_tzname = yes; then $as_echo "#define HAVE_TZNAME 1" >>confdefs.h fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for utime.h" >&5 $as_echo_n "checking for utime.h... " >&6; } if ${ba_cv_header_utime_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct utimbuf foo ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ba_cv_header_utime_h=yes else ba_cv_header_utime_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ba_cv_header_utime_h" >&5 $as_echo "$ba_cv_header_utime_h" >&6; } test $ba_cv_header_utime_h = yes && $as_echo "#define HAVE_UTIME_H 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 $as_echo_n "checking for socklen_t... " >&6; } if ${ba_cv_header_socklen_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { socklen_t x ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ba_cv_header_socklen_t=yes else ba_cv_header_socklen_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ba_cv_header_socklen_t" >&5 $as_echo "$ba_cv_header_socklen_t" >&6; } test $ba_cv_header_socklen_t = yes && $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ioctl_req_t" >&5 $as_echo_n "checking for ioctl_req_t... " >&6; } if ${ba_cv_header_ioctl_req_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { int (*d_ioctl)(int fd, unsigned long int request, ...); d_ioctl = ::ioctl; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ba_cv_header_ioctl_req_t=yes else ba_cv_header_ioctl_req_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ba_cv_header_ioctl_req_t" >&5 $as_echo "$ba_cv_header_ioctl_req_t" >&6; } test $ba_cv_header_ioctl_req_t = yes && $as_echo "#define HAVE_IOCTL_ULINT_REQUEST 1" >>confdefs.h ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for typeof" >&5 $as_echo_n "checking for typeof... " >&6; } if ${ba_cv_have_typeof+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ba_cv_have_typeof=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ main(){char *a = 0; a = (typeof a)a;} _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ba_cv_have_typeof=yes else ba_cv_have_typeof=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ba_cv_have_typeof" >&5 $as_echo "$ba_cv_have_typeof" >&6; } test $ba_cv_have_typeof = yes && $as_echo "#define HAVE_TYPEOF 1" >>confdefs.h ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define HAVE_BIG_ENDIAN 1" >>confdefs.h ;; #( no) $as_echo "#define HAVE_LITTLE_ENDIAN 1" >>confdefs.h ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get filesystem type" >&5 $as_echo_n "checking how to get filesystem type... " >&6; } fstype=no # The order of these tests is important. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : $as_echo "#define FSTYPE_STATVFS 1" >>confdefs.h fstype=SVR4 fi rm -f conftest.err conftest.i conftest.$ac_ext if test $fstype = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : $as_echo "#define FSTYPE_USG_STATFS 1" >>confdefs.h fstype=SVR3 fi rm -f conftest.err conftest.i conftest.$ac_ext fi if test $fstype = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : $as_echo "#define FSTYPE_AIX_STATFS 1" >>confdefs.h fstype=AIX fi rm -f conftest.err conftest.i conftest.$ac_ext fi if test $fstype = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : $as_echo "#define FSTYPE_MNTENT 1" >>confdefs.h fstype=4.3BSD fi rm -f conftest.err conftest.i conftest.$ac_ext fi if test $fstype = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "f_type;" >/dev/null 2>&1; then : $as_echo "#define FSTYPE_STATFS 1" >>confdefs.h fstype=4.4BSD/OSF1 fi rm -f conftest* fi if test $fstype = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : $as_echo "#define FSTYPE_GETMNT 1" >>confdefs.h fstype=Ultrix fi rm -f conftest.err conftest.i conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $fstype" >&5 $as_echo "$fstype" >&6; } ac_fn_c_check_header_mongrel "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_statvfs_h" = xyes; then : $as_echo "#define HAVE_SYS_STATVFS_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type of signal functions" >&5 $as_echo_n "checking for type of signal functions... " >&6; } if ${bash_cv_signal_vintage+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { sigset_t ss; struct sigaction sa; sigemptyset(&ss); sigsuspend(&ss); sigaction(SIGINT, &sa, (struct sigaction *) 0); sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : bash_cv_signal_vintage="posix" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int mask = sigmask(SIGINT); sigsetmask(mask); sigblock(mask); sigpause(mask); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : bash_cv_signal_vintage="4.2bsd" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include RETSIGTYPE foo() { } int main () { int mask = sigmask(SIGINT); sigset(SIGINT, foo); sigrelse(SIGINT); sighold(SIGINT); sigpause(SIGINT); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : bash_cv_signal_vintage="svr3" else bash_cv_signal_vintage="v7" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bash_cv_signal_vintage" >&5 $as_echo "$bash_cv_signal_vintage" >&6; } if test "$bash_cv_signal_vintage" = "posix"; then $as_echo "#define HAVE_POSIX_SIGNALS 1" >>confdefs.h elif test "$bash_cv_signal_vintage" = "4.2bsd"; then $as_echo "#define HAVE_BSD_SIGNALS 1" >>confdefs.h elif test "$bash_cv_signal_vintage" = "svr3"; then $as_echo "#define HAVE_USG_SIGHOLD 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" if test "x$ac_cv_type_mode_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 $as_echo_n "checking for uid_t in sys/types.h... " >&6; } if ${ac_cv_type_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then : ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 $as_echo "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then $as_echo "#define uid_t int" >>confdefs.h $as_echo "#define gid_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" if test "x$ac_cv_type_intptr_t" = xyes; then : $as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h else for ac_type in 'int' 'long int' 'long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define intptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : $as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h else for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define uintptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ac_fn_c_check_type "$LINENO" "ino_t" "ac_cv_type_ino_t" "$ac_includes_default" if test "x$ac_cv_type_ino_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define ino_t unsigned long _ACEOF fi ac_fn_c_check_type "$LINENO" "dev_t" "ac_cv_type_dev_t" "$ac_includes_default" if test "x$ac_cv_type_dev_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define dev_t unsigned long _ACEOF fi ac_fn_c_check_type "$LINENO" "daddr_t" "ac_cv_type_daddr_t" "$ac_includes_default" if test "x$ac_cv_type_daddr_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define daddr_t long _ACEOF fi ac_fn_c_check_type "$LINENO" "major_t" "ac_cv_type_major_t" "$ac_includes_default" if test "x$ac_cv_type_major_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define major_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "minor_t" "ac_cv_type_minor_t" "$ac_includes_default" if test "x$ac_cv_type_minor_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define minor_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define ssize_t int _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLOCKS 1 _ACEOF $as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h else case " $LIBOBJS " in *" fileblocks.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fileblocks.$ac_objext" ;; esac fi ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_rdev" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_RDEV 1 _ACEOF $as_echo "#define HAVE_ST_RDEV 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } if ${ac_cv_struct_tm+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_tm=time.h else ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 $as_echo "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 $as_echo_n "checking size of char... " >&6; } if ${ac_cv_sizeof_char+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : else if test "$ac_cv_type_char" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (char) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_char=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 $as_echo "$ac_cv_sizeof_char" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short int" >&5 $as_echo_n "checking size of short int... " >&6; } if ${ac_cv_sizeof_short_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short int))" "ac_cv_sizeof_short_int" "$ac_includes_default"; then : else if test "$ac_cv_type_short_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short_int" >&5 $as_echo "$ac_cv_sizeof_short_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT_INT $ac_cv_sizeof_short_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long int" >&5 $as_echo_n "checking size of long int... " >&6; } if ${ac_cv_sizeof_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long int))" "ac_cv_sizeof_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_int" >&5 $as_echo "$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long int" >&5 $as_echo_n "checking size of long long int... " >&6; } if ${ac_cv_sizeof_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long int))" "ac_cv_sizeof_long_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long_int" >&5 $as_echo "$ac_cv_sizeof_long_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG_INT $ac_cv_sizeof_long_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } if ${ac_cv_sizeof_int_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : else if test "$ac_cv_type_int_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int_p" >&5 $as_echo "$ac_cv_sizeof_int_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT_P $ac_cv_sizeof_int_p _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_int type" >&5 $as_echo_n "checking for u_int type... " >&6; } if ${ac_cv_have_u_int+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_int a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_int="yes" else ac_cv_have_u_int="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_int" >&5 $as_echo "$ac_cv_have_u_int" >&6; } if test "x$ac_cv_have_u_int" = "xyes" ; then $as_echo "#define HAVE_U_INT 1" >>confdefs.h have_u_int=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intmax_t type" >&5 $as_echo_n "checking for intmax_t type... " >&6; } if ${ac_cv_have_intmax_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { intmax_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_intmax_t="yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { intmax_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_intmax_t="yes" else ac_cv_have_intmax_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_intmax_t" >&5 $as_echo "$ac_cv_have_intmax_t" >&6; } if test "x$ac_cv_have_intmax_t" = "xyes" ; then $as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h have_intmax_t=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_intmax_t type" >&5 $as_echo_n "checking for u_intmax_t type... " >&6; } if ${ac_cv_have_u_intmax_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_intmax_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_intmax_t="yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_intmax_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_intmax_t="yes" else ac_cv_have_u_intmax_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_intmax_t" >&5 $as_echo "$ac_cv_have_u_intmax_t" >&6; } if test "x$ac_cv_have_u_intmax_t" = "xyes" ; then $as_echo "#define HAVE_U_INTMAX_T 1" >>confdefs.h have_u_intmax_t=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intXX_t types" >&5 $as_echo_n "checking for intXX_t types... " >&6; } if ${ac_cv_have_intxx_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_intxx_t="yes" else ac_cv_have_intxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_intxx_t" >&5 $as_echo "$ac_cv_have_intxx_t" >&6; } if test "x$ac_cv_have_intxx_t" = "xyes" ; then $as_echo "#define HAVE_INTXX_T 1" >>confdefs.h have_intxx_t=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int64_t type" >&5 $as_echo_n "checking for int64_t type... " >&6; } if ${ac_cv_have_int64_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int64_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_int64_t="yes" else ac_cv_have_int64_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_int64_t" >&5 $as_echo "$ac_cv_have_int64_t" >&6; } if test "x$ac_cv_have_int64_t" = "xyes" ; then $as_echo "#define HAVE_INT64_T 1" >>confdefs.h have_int64_t=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_intXX_t types" >&5 $as_echo_n "checking for u_intXX_t types... " >&6; } if ${ac_cv_have_u_intxx_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_intxx_t="yes" else ac_cv_have_u_intxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_intxx_t" >&5 $as_echo "$ac_cv_have_u_intxx_t" >&6; } if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then $as_echo "#define HAVE_U_INTXX_T 1" >>confdefs.h have_u_intxx_t=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_int64_t types" >&5 $as_echo_n "checking for u_int64_t types... " >&6; } if ${ac_cv_have_u_int64_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_int64_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_int64_t="yes" else ac_cv_have_u_int64_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_int64_t" >&5 $as_echo "$ac_cv_have_u_int64_t" >&6; } if test "x$ac_cv_have_u_int64_t" = "xyes" ; then $as_echo "#define HAVE_U_INT64_T 1" >>confdefs.h have_u_int64_t=1 fi if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 $as_echo_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; u_int8_t e; u_int16_t f; u_int32_t g; a = b = c = e = f = g = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_U_INTXX_T 1" >>confdefs.h $as_echo "#define HAVE_INTXX_T 1" >>confdefs.h $as_echo "#define HAVE_SYS_BITYPES_H 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test -z "$have_u_intxx_t" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types" >&5 $as_echo_n "checking for uintXX_t types... " >&6; } if ${ac_cv_have_uintxx_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_uintxx_t="yes" else ac_cv_have_uintxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_uintxx_t" >&5 $as_echo "$ac_cv_have_uintxx_t" >&6; } if test "x$ac_cv_have_uintxx_t" = "xyes" ; then $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h fi fi if (test -z "$have_u_int64_t" || test -z "$have_int64_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int64_t and u_int64_t types in sys/bitypes.h" >&5 $as_echo_n "checking for int64_t and u_int64_t types in sys/bitypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int64_t a; u_int64_t b; a = b = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_U_INT64_T 1" >>confdefs.h $as_echo "#define HAVE_INT64_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types in sys/bitypes.h" >&5 $as_echo_n "checking for uintXX_t types in sys/bitypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi for ac_func in \ fork \ getcwd \ gethostname \ getpid \ gettimeofday \ setpgid \ setpgrp \ setsid \ signal \ strerror \ strncmp \ strncpy \ vfprintf \ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else echo 'configure: cannot find needed function.'; exit 1 fi done ac_fn_c_check_decl "$LINENO" "F_CLOSEM" "ac_cv_have_decl_F_CLOSEM" "#include " if test "x$ac_cv_have_decl_F_CLOSEM" = xyes; then : $as_echo "#define HAVE_FCNTL_F_CLOSEM 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "bcopy" "ac_cv_func_bcopy" if test "x$ac_cv_func_bcopy" = xyes; then : $as_echo "#define HAVE_BCOPY 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "closefrom" "ac_cv_func_closefrom" if test "x$ac_cv_func_closefrom" = xyes; then : $as_echo "#define HAVE_CLOSEFROM 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = xyes; then : $as_echo "#define HAVE_GETPAGESIZE 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "malloc_trim" "ac_cv_func_malloc_trim" if test "x$ac_cv_func_malloc_trim" = xyes; then : $as_echo "#define HAVE_MALLOC_TRIM 1" >>confdefs.h fi if test x${HAVE_SUN_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "umem.h" "ac_cv_header_umem_h" "$ac_includes_default" if test "x$ac_cv_header_umem_h" = xyes; then : $as_echo "#define HAVE_UMEM_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -lumem" >&5 $as_echo_n "checking for malloc in -lumem... " >&6; } if ${ac_cv_lib_umem_malloc+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lumem $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char malloc (); int main () { return malloc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_umem_malloc=yes else ac_cv_lib_umem_malloc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_umem_malloc" >&5 $as_echo "$ac_cv_lib_umem_malloc" >&6; } if test "x$ac_cv_lib_umem_malloc" = xyes; then : LIBS="-lumem $LIBS" fi fi ac_fn_c_check_func "$LINENO" "backtrace_symbols" "ac_cv_func_backtrace_symbols" if test "x$ac_cv_func_backtrace_symbols" = xyes; then : $as_echo "#define HAVE_BACKTRACE_SYMBOLS 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "backtrace" "ac_cv_func_backtrace" if test "x$ac_cv_func_backtrace" = xyes; then : $as_echo "#define HAVE_BACKTRACE 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default" if test "x$ac_cv_header_execinfo_h" = xyes; then : $as_echo "#define HAVE_EXECINFO_H 1" >>confdefs.h fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_fn_cxx_check_header_mongrel "$LINENO" "cxxabi.h" "ac_cv_header_cxxabi_h" "$ac_includes_default" if test "x$ac_cv_header_cxxabi_h" = xyes; then : $as_echo "#define HAVE_CXXABI_H 1" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x${HAVE_SUN_OS_TRUE} = x; then ac_fn_c_check_func "$LINENO" "addrtosymstr" "ac_cv_func_addrtosymstr" if test "x$ac_cv_func_addrtosymstr" = xyes; then : $as_echo "#define HAVE_ADDRTOSYMSTR 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "ucontext.h" "ac_cv_header_ucontext_h" "$ac_includes_default" if test "x$ac_cv_header_ucontext_h" = xyes; then : $as_echo "#define HAVE_UCONTEXT_H 1" >>confdefs.h fi if test X"$GCC" != "Xyes" ; then ac_fn_c_check_header_mongrel "$LINENO" "demangle.h" "ac_cv_header_demangle_h" "$ac_includes_default" if test "x$ac_cv_header_demangle_h" = xyes; then : $as_echo "#define HAVE_DEMANGLE_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cplus_demangle in -ldemangle" >&5 $as_echo_n "checking for cplus_demangle in -ldemangle... " >&6; } if ${ac_cv_lib_demangle_cplus_demangle+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldemangle $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cplus_demangle (); int main () { return cplus_demangle (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_demangle_cplus_demangle=yes else ac_cv_lib_demangle_cplus_demangle=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_demangle_cplus_demangle" >&5 $as_echo "$ac_cv_lib_demangle_cplus_demangle" >&6; } if test "x$ac_cv_lib_demangle_cplus_demangle" = xyes; then : $as_echo "#define HAVE_CPLUS_DEMANGLE 1" >>confdefs.h LIBS="-ldemangle $LIBS" fi fi fi ac_fn_c_check_func "$LINENO" "fchdir" "ac_cv_func_fchdir" if test "x$ac_cv_func_fchdir" = xyes; then : $as_echo "#define HAVE_FCHDIR 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll" if test "x$ac_cv_func_strtoll" = xyes; then : $as_echo "#define HAVE_STRTOLL 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "posix_fadvise" "ac_cv_func_posix_fadvise" if test "x$ac_cv_func_posix_fadvise" = xyes; then : $as_echo "#define HAVE_POSIX_FADVISE 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "fdatasync" "ac_cv_func_fdatasync" if test "x$ac_cv_func_fdatasync" = xyes; then : $as_echo "#define HAVE_FDATASYNC 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags" if test "x$ac_cv_func_chflags" = xyes; then : $as_echo "#define HAVE_CHFLAGS 1" >>confdefs.h fi for ac_func in snprintf vsnprintf gethostid fseeko do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for va_copy" >&5 $as_echo_n "checking for va_copy... " >&6; } if ${ba_cv_va_copy+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include void use_va_copy(va_list args){va_list args2; va_copy(args2,args); va_end(args2);} void call_use_va_copy(int junk,...){va_list args; va_start(args,junk); use_va_copy(args); va_end(args);} int main () { call_use_va_copy(1,2,3) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ba_cv_va_copy=yes else ba_cv_va_copy=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ba_cv_va_copy" >&5 $as_echo "$ba_cv_va_copy" >&6; } test $ba_cv_va_copy = yes && $as_echo "#define HAVE_VA_COPY 1" >>confdefs.h for ac_func in localtime_r readdir_r strerror_r do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" if test "x$ac_cv_func_gethostbyname_r" = xyes; then : $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: using gethostbyname_r from resolver in libc" >&5 $as_echo "using gethostbyname_r from resolver in libc" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r in -lnsl" >&5 $as_echo_n "checking for gethostbyname_r in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname_r+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname_r (); int main () { return gethostbyname_r (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname_r=yes else ac_cv_lib_nsl_gethostbyname_r=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname_r" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname_r" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname_r" = xyes; then : $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h LIBS="-lnsl $LIBS" SOCKLIBS="-lnsl $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r in -lresolv" >&5 $as_echo_n "checking for gethostbyname_r in -lresolv... " >&6; } if ${ac_cv_lib_resolv_gethostbyname_r+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname_r (); int main () { return gethostbyname_r (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_gethostbyname_r=yes else ac_cv_lib_resolv_gethostbyname_r=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_gethostbyname_r" >&5 $as_echo "$ac_cv_lib_resolv_gethostbyname_r" >&6; } if test "x$ac_cv_lib_resolv_gethostbyname_r" = xyes; then : $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h LIBS="-lresolv $LIBS" SOCKLIBS="-lresolv $LIBS" fi fi fi ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton" if test "x$ac_cv_func_inet_pton" = xyes; then : $as_echo "#define HAVE_INET_PTON 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop" if test "x$ac_cv_func_inet_ntop" = xyes; then : $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "gethostbyname2" "ac_cv_func_gethostbyname2" if test "x$ac_cv_func_gethostbyname2" = xyes; then : $as_echo "#define HAVE_GETHOSTBYNAME2 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr has a sa_len field" >&5 $as_echo_n "checking for struct sockaddr has a sa_len field... " >&6; } if ${ac_cv_struct_sockaddr_sa_len+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct sockaddr s; s.sa_len; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_sockaddr_sa_len=yes else ac_cv_struct_sockaddr_sa_len=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_sa_len" >&5 $as_echo "$ac_cv_struct_sockaddr_sa_len" >&6; } if test $ac_cv_struct_sockaddr_sa_len = yes; then $as_echo "#define HAVE_SA_LEN 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working getaddrinfo" >&5 $as_echo_n "checking for working getaddrinfo... " >&6; } if ${ac_cv_working_getaddrinfo+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_working_getaddrinfo="yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include void main(void) { struct addrinfo hints, *ai; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo("127.0.0.1", NULL, &hints, &ai); if (error) { exit(1); } if (ai->ai_addr->sa_family != AF_INET) { exit(1); } exit(0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_working_getaddrinfo="yes" else ac_cv_working_getaddrinfo="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_getaddrinfo" >&5 $as_echo "$ac_cv_working_getaddrinfo" >&6; } ac_fn_c_check_func "$LINENO" "gai_strerror" "ac_cv_func_gai_strerror" if test "x$ac_cv_func_gai_strerror" = xyes; then : $as_echo "#define HAVE_GAI_STRERROR 1" >>confdefs.h fi if test "$ac_cv_working_getaddrinfo" = "yes"; then if test "$ac_cv_func_gai_strerror" != "yes"; then ac_cv_working_getaddrinfo="no" else $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h fi fi for ac_func in strftime do : ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" if test "x$ac_cv_func_strftime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRFTIME 1 _ACEOF else # strftime is in -lintl on SCO UNIX. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5 $as_echo_n "checking for strftime in -lintl... " >&6; } if ${ac_cv_lib_intl_strftime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char strftime (); int main () { return strftime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_intl_strftime=yes else ac_cv_lib_intl_strftime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5 $as_echo "$ac_cv_lib_intl_strftime" >&6; } if test "x$ac_cv_lib_intl_strftime" = xyes; then : $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h LIBS="-lintl $LIBS" fi fi done for ac_func in vprintf do : ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" if test "x$ac_cv_func_vprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VPRINTF 1 _ACEOF ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes; then : $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h fi fi done # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi # getmntent is in the standard C library on UNICOS, in -lsun on Irix 4, # -lseq on Dynix/PTX, -lgen on Unixware. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getmntent" >&5 $as_echo_n "checking for library containing getmntent... " >&6; } if ${ac_cv_search_getmntent+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getmntent (); int main () { return getmntent (); ; return 0; } _ACEOF for ac_lib in '' sun seq gen; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_getmntent=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_getmntent+:} false; then : break fi done if ${ac_cv_search_getmntent+:} false; then : else ac_cv_search_getmntent=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getmntent" >&5 $as_echo "$ac_cv_search_getmntent" >&6; } ac_res=$ac_cv_search_getmntent if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ac_cv_func_getmntent=yes $as_echo "#define HAVE_GETMNTENT 1" >>confdefs.h else ac_cv_func_getmntent=no fi ac_fn_c_check_func "$LINENO" "getmntinfo" "ac_cv_func_getmntinfo" if test "x$ac_cv_func_getmntinfo" = xyes; then : $as_echo "#define HAVE_GETMNTINFO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5 $as_echo_n "checking whether closedir returns void... " >&6; } if ${ac_cv_func_closedir_void+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_closedir_void=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include <$ac_header_dirent> #ifndef __cplusplus int closedir (); #endif int main () { return closedir (opendir (".")) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_closedir_void=no else ac_cv_func_closedir_void=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_closedir_void" >&5 $as_echo "$ac_cv_func_closedir_void" >&6; } if test $ac_cv_func_closedir_void = yes; then $as_echo "#define CLOSEDIR_VOID 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 $as_echo_n "checking whether setpgrp takes no argument... " >&6; } if ${ac_cv_func_setpgrp_void+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : as_fn_error $? "cannot check setpgrp when cross compiling" "$LINENO" 5 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* If this system has a BSD-style setpgrp which takes arguments, setpgrp(1, 1) will fail with ESRCH and return -1, in that case exit successfully. */ return setpgrp (1,1) != -1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_setpgrp_void=no else ac_cv_func_setpgrp_void=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 $as_echo "$ac_cv_func_setpgrp_void" >&6; } if test $ac_cv_func_setpgrp_void = yes; then $as_echo "#define SETPGRP_VOID 1" >>confdefs.h fi # AC_FUNC_FNMATCH dnl use local version { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in -lintl" >&5 $as_echo_n "checking for gettext in -lintl... " >&6; } if ${ac_cv_lib_intl_gettext+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gettext (); int main () { return gettext (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_intl_gettext=yes else ac_cv_lib_intl_gettext=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_gettext" >&5 $as_echo "$ac_cv_lib_intl_gettext" >&6; } if test "x$ac_cv_lib_intl_gettext" = xyes; then : LIBS="$LIBS -lintl" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam in -lsun" >&5 $as_echo_n "checking for getpwnam in -lsun... " >&6; } if ${ac_cv_lib_sun_getpwnam+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsun $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getpwnam (); int main () { return getpwnam (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sun_getpwnam=yes else ac_cv_lib_sun_getpwnam=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sun_getpwnam" >&5 $as_echo "$ac_cv_lib_sun_getpwnam" >&6; } if test "x$ac_cv_lib_sun_getpwnam" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSUN 1 _ACEOF LIBS="-lsun $LIBS" fi ZLIB_LIBS="-lz" ZLIB_INC="" have_zlib=no # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; with_zlib_directory=${withval} fi if test "x${with_zlib_directory}" != "xyes" && test x"${with_zlib_directory}" != "x"; then # # Make sure the $with_zlib_directory also makes sense # if test -d "${with_zlib_directory}/lib" -a -d "${with_zlib_directory}/include"; then ZLIB_LIBS="-L${with_zlib_directory}/lib ${ZLIB_LIBS}" ZLIB_INC="-I${with_zlib_directory}/include ${ZLIB_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${ZLIB_LIBS}" CFLAGS="${saved_CFLAGS} ${ZLIB_INC}" CPPFLAGS="${saved_CPPFLAGS} ${ZLIB_INC}" for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compressBound in zlib library" >&5 $as_echo_n "checking for compressBound in zlib library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { compressBound(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_COMPRESS_BOUND 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in zlib library" >&5 $as_echo_n "checking for deflate in zlib library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { deflate(Z_NULL, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_zlib="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_zlib="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_zlib}" = "xyes"; then $as_echo "#define HAVE_LIBZ 1" >>confdefs.h else ZLIB_LIBS="" ZLIB_INC="" fi if test x$use_libtool != xno; then ZLIB_LIBS_NONSHARED="" else ZLIB_LIBS_NONSHARED="${ZLIB_LIBS}" fi LZO_LIBS="-llzo2" LZO_INC="" have_lzo=no # Check whether --with-lzo was given. if test "${with_lzo+set}" = set; then : withval=$with_lzo; with_lzo_directory=${withval} fi if test "x${with_lzo_directory}" != "xyes" && test x"${with_lzo_directory}" != "x"; then # # Make sure the $with_lzo_directory also makes sense # if test -d "${with_lzo_directory}/lib" -a -d "${with_lzo_directory}/include"; then LZO_LIBS="-L${with_lzo_directory}/lib ${LZO_LIBS}" LZO_INC="-I${with_lzo_directory}/include ${LZO_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${LZO_LIBS}" CFLAGS="${saved_CFLAGS} ${LZO_INC}" CPPFLAGS="${saved_CPPFLAGS} ${LZO_INC}" for ac_header in lzo/lzoconf.h do : ac_fn_c_check_header_mongrel "$LINENO" "lzo/lzoconf.h" "ac_cv_header_lzo_lzoconf_h" "$ac_includes_default" if test "x$ac_cv_header_lzo_lzoconf_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LZO_LZOCONF_H 1 _ACEOF fi done for ac_header in lzo/lzo1x.h do : ac_fn_c_check_header_mongrel "$LINENO" "lzo/lzo1x.h" "ac_cv_header_lzo_lzo1x_h" "$ac_includes_default" if test "x$ac_cv_header_lzo_lzo1x_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LZO_LZO1X_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_compress in lzo library" >&5 $as_echo_n "checking for lzo1x_1_compress in lzo library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { lzo1x_1_compress(NULL, 0, NULL, NULL, NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_lzo="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_lzo="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_lzo}" = "xyes"; then $as_echo "#define HAVE_LZO 1" >>confdefs.h else LZO_LIBS="" LZO_INC="" fi if test x$use_libtool != xno; then LZO_LIBS_NONSHARED="" else LZO_LIBS_NONSHARED="${LZO_LIBS}" fi FASTLZ_LIBS="-lfastlz" FASTLZ_INC="" have_fastlz=no # Check whether --with-fastlz was given. if test "${with_fastlz+set}" = set; then : withval=$with_fastlz; with_fastlz_directory=${withval} fi if test "x${with_fastlz_directory}" != "xyes" && test x"${with_fastlz_directory}" != "x"; then # # Make sure the $with_fastlz_directory also makes sense # if test -d "${with_fastlz_directory}/lib" -a -d "${with_fastlz_directory}/include"; then FASTLZ_LIBS="-L${with_fastlz_directory}/lib ${FASTLZ_LIBS}" FASTLZ_INC="-I${with_fastlz_directory}/include ${FASTLZ_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${FASTLZ_LIBS}" CFLAGS="${saved_CFLAGS} ${FASTLZ_INC}" CPPFLAGS="${saved_CPPFLAGS} ${FASTLZ_INC}" for ac_header in fastlzlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "fastlzlib.h" "ac_cv_header_fastlzlib_h" "$ac_includes_default" if test "x$ac_cv_header_fastlzlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FASTLZLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fastlzlibCompress in fastlz library" >&5 $as_echo_n "checking for fastlzlibCompress in fastlz library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { fastlzlibCompress(Z_NULL, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_fastlz="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_fastlz="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_fastlz}" = "xyes"; then $as_echo "#define HAVE_FASTLZ 1" >>confdefs.h else FASTLZ_LIBS="" FASTLZ_INC="" fi if test x$use_libtool != xno; then FASTLZ_LIBS_NONSHARED="" else FASTLZ_LIBS_NONSHARED="${FASTLZ_LIBS}" fi AFS_CFLAGS="" AFS_LIBS="" support_afs=auto # Check whether --enable-afs was given. if test "${enable_afs+set}" = set; then : enableval=$enable_afs; if test x$enableval = xyes; then support_afs=yes elif test x$enableval = xno; then support_afs=no fi fi have_afs=no if test x$support_afs = xyes -o x$support_afs = xauto; then # Check whether --with-afsdir was given. if test "${with_afsdir+set}" = set; then : withval=$with_afsdir; with_afsdir=$withval fi if test x$with_afsdir = x; then for root in /usr /usr/local; do if test -d ${root}/include/afs/ ; then with_afsdir=${root} break fi if test -d ${root}/include/openafs/afs/ ; then with_afsdir=${root} break fi done fi if test -d ${with_afsdir}/include/afs/ ; then AFS_CFLAGS="-I${with_afsdir}/include" else if test -d ${with_afsdir}/include/openafs/afs/ ; then AFS_CFLAGS="-I${with_afsdir}/include/openafs" fi fi saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" CFLAGS="${AFS_CFLAGS} ${saved_CFLAGS}" CPPFLAGS="${AFS_CFLAGS} ${saved_CPPFLAGS}" for ac_header in afs/afsint.h do : ac_fn_c_check_header_mongrel "$LINENO" "afs/afsint.h" "ac_cv_header_afs_afsint_h" "$ac_includes_default" if test "x$ac_cv_header_afs_afsint_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_AFS_AFSINT_H 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : $as_echo "#define HAVE_AFS_VENUS_H 1" >>confdefs.h fi rm -f conftest.err conftest.i conftest.$ac_ext CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pioctl in AFS libsys" >&5 $as_echo_n "checking for pioctl in AFS libsys... " >&6; } for dir in ${with_afsdir}/lib \ ${with_afsdir}/lib/afs \ ${with_afsdir}/lib/openafs \ ${with_afsdir}/lib64 \ ${with_afsdir}/lib64/afs \ ${with_afsdir}/lib64/openafs do for arch_type in .a .so do A=`test -f ${dir}/libsys${arch_type} && nm ${dir}/libsys${arch_type} 2>/dev/null | grep pioctl` pkg=$? if test $pkg = 0; then have_afs=yes AFS_LIBS="-L${dir} -lsys -lrx -llwp" break fi done done if test $have_afs = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$support_afs = xyes -a $have_afs != yes; then as_fn_error $? "afs support explicitly enabled but no supported afs implementation found, please either load the afs libraries or rerun configure without --enable-afs" "$LINENO" 5 else if test $have_afs = yes; then $as_echo "#define HAVE_AFS 1" >>confdefs.h $as_echo "#define HAVE_AFS_ACL 1" >>confdefs.h fi fi fi if test x$use_libtool != xno; then AFS_LIBS_NONSHARED="" else AFS_LIBS_NONSHARED="${AFS_LIBS}" fi ACL_LIBS="" support_acl=auto # Check whether --enable-acl was given. if test "${enable_acl+set}" = set; then : enableval=$enable_acl; if test x$enableval = xyes; then support_acl=yes elif test x$enableval = xno; then support_acl=no fi fi have_acl=no have_extended_acl=no if test x$support_acl = xyes -o x$support_acl = xauto; then ac_fn_c_check_header_mongrel "$LINENO" "sys/acl.h" "ac_cv_header_sys_acl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_acl_h" = xyes; then : $as_echo "#define HAVE_SYS_ACL_H 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "acl_get_file" "ac_cv_func_acl_get_file" if test "x$ac_cv_func_acl_get_file" = xyes; then : have_acl=yes fi if test $have_acl = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5 $as_echo_n "checking for acl_get_file in -lacl... " >&6; } if ${ac_cv_lib_acl_acl_get_file+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lacl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acl_get_file (); int main () { return acl_get_file (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_acl_acl_get_file=yes else ac_cv_lib_acl_acl_get_file=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5 $as_echo "$ac_cv_lib_acl_acl_get_file" >&6; } if test "x$ac_cv_lib_acl_acl_get_file" = xyes; then : have_acl=yes if test $have_afs = yes; then if test -d /usr/lib64/; then ACL_LIBS="-L/usr/lib64 -lacl $ACL_LIBS" else ACL_LIBS="-L/usr/lib -lacl $ACL_LIBS" fi else ACL_LIBS="-lacl $ACL_LIBS" fi fi fi if test $have_acl = no -a \ x${HAVE_OSF1_OS_TRUE} = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lpacl" >&5 $as_echo_n "checking for acl_get_file in -lpacl... " >&6; } if ${ac_cv_lib_pacl_acl_get_file+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpacl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acl_get_file (); int main () { return acl_get_file (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pacl_acl_get_file=yes else ac_cv_lib_pacl_acl_get_file=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pacl_acl_get_file" >&5 $as_echo "$ac_cv_lib_pacl_acl_get_file" >&6; } if test "x$ac_cv_lib_pacl_acl_get_file" = xyes; then : have_acl=yes ACL_LIBS="-lpacl $ACL_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ACL_TYPE_DEFAULT_DIR in acl.h include file" >&5 $as_echo_n "checking for ACL_TYPE_DEFAULT_DIR in acl.h include file... " >&6; } grep ACL_TYPE_DEFAULT_DIR /usr/include/sys/acl.h > /dev/null 2>&1 if test $? = 0; then $as_echo "#define HAVE_ACL_TYPE_DEFAULT_DIR 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test $have_acl = yes -a \ x${HAVE_DARWIN_OS_TRUE} = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ACL_TYPE_EXTENDED in acl.h include file" >&5 $as_echo_n "checking for ACL_TYPE_EXTENDED in acl.h include file... " >&6; } grep ACL_TYPE_EXTENDED /usr/include/sys/acl.h > /dev/null 2>&1 if test $? = 0; then $as_echo "#define HAVE_ACL_TYPE_EXTENDED 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test $have_acl = yes -a \ x${HAVE_FREEBSD_OS_TRUE} = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ACL_TYPE_NFS4 in acl.h include file" >&5 $as_echo_n "checking for ACL_TYPE_NFS4 in acl.h include file... " >&6; } grep ACL_TYPE_NFS4 /usr/include/sys/acl.h > /dev/null 2>&1 if test $? = 0; then $as_echo "#define HAVE_ACL_TYPE_NFS4 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test $have_acl = no -a \ x${HAVE_SUN_OS_TRUE} = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acltotext in -lsec" >&5 $as_echo_n "checking for acltotext in -lsec... " >&6; } if ${ac_cv_lib_sec_acltotext+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsec $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acltotext (); int main () { return acltotext (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sec_acltotext=yes else ac_cv_lib_sec_acltotext=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_acltotext" >&5 $as_echo "$ac_cv_lib_sec_acltotext" >&6; } if test "x$ac_cv_lib_sec_acltotext" = xyes; then : have_acl=yes ACL_LIBS="-lsec $ACL_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_totext in -lsec" >&5 $as_echo_n "checking for acl_totext in -lsec... " >&6; } if ${ac_cv_lib_sec_acl_totext+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsec $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acl_totext (); int main () { return acl_totext (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sec_acl_totext=yes else ac_cv_lib_sec_acl_totext=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_acl_totext" >&5 $as_echo "$ac_cv_lib_sec_acl_totext" >&6; } if test "x$ac_cv_lib_sec_acl_totext" = xyes; then : have_extended_acl=yes fi fi fi if test $have_acl = no -a \ x${HAVE_AIX_OS_TRUE} = x; then ac_fn_c_check_func "$LINENO" "acl_get" "ac_cv_func_acl_get" if test "x$ac_cv_func_acl_get" = xyes; then : have_acl=yes ac_fn_c_check_func "$LINENO" "aclx_get" "ac_cv_func_aclx_get" if test "x$ac_cv_func_aclx_get" = xyes; then : have_extended_acl=yes fi fi fi if test x$support_acl = xyes -a $have_acl != yes; then as_fn_error $? "acl support explicitly enabled but no supported acl implementation found, please either load the acl libraries or rerun configure without --enable-acl" "$LINENO" 5 else if test $have_acl = yes; then $as_echo "#define HAVE_ACL 1" >>confdefs.h fi if test $have_extended_acl = yes; then $as_echo "#define HAVE_EXTENDED_ACL 1" >>confdefs.h fi fi fi if test x$use_libtool != xno; then ACL_LIBS_NONSHARED="" else ACL_LIBS_NONSHARED="${ACL_LIBS}" fi XATTR_LIBS="" support_xattr=auto # Check whether --enable-xattr was given. if test "${enable_xattr+set}" = set; then : enableval=$enable_xattr; if test x$enableval = xyes; then support_xattr=yes elif test x$enableval = xno; then support_xattr=no fi fi have_xattr=no if test x$support_xattr = xyes -o x$support_xattr = xauto; then if test x${HAVE_FREEBSD_OS_TRUE} = x -o \ x${HAVE_NETBSD_OS_TRUE} = x -o \ x${HAVE_OPENBSD_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "sys/extattr.h" "ac_cv_header_sys_extattr_h" "$ac_includes_default" if test "x$ac_cv_header_sys_extattr_h" = xyes; then : $as_echo "#define HAVE_SYS_EXTATTR_H 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "libutil.h" "ac_cv_header_libutil_h" "$ac_includes_default" if test "x$ac_cv_header_libutil_h" = xyes; then : $as_echo "#define HAVE_LIBUTIL_H 1" >>confdefs.h fi for ac_func in extattr_get_link extattr_set_link extattr_list_link do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_EXTATTR_GET_LINK 1" >>confdefs.h $as_echo "#define HAVE_EXTATTR_SET_LINK 1" >>confdefs.h $as_echo "#define HAVE_EXTATTR_LIST_LINK 1" >>confdefs.h fi done if test $have_xattr = no; then for ac_func in extattr_get_file extattr_set_file extattr_list_file do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_EXTATTR_GET_FILE 1" >>confdefs.h $as_echo "#define HAVE_EXTATTR_SET_FILE 1" >>confdefs.h $as_echo "#define HAVE_EXTATTR_LIST_FILE 1" >>confdefs.h fi done fi if test $have_xattr = yes; then have_extattr_string_in_libc=no for ac_func in extattr_namespace_to_string extattr_string_to_namespace do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_extattr_string_in_libc=yes $as_echo "#define HAVE_EXTATTR_NAMESPACE_TO_STRING 1" >>confdefs.h $as_echo "#define HAVE_EXTATTR_STRING_TO_NAMESPACE 1" >>confdefs.h fi done if test $have_extattr_string_in_libc = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extattr_namespace_to_string extattr_string_to_namespace in -lutil" >&5 $as_echo_n "checking for extattr_namespace_to_string extattr_string_to_namespace in -lutil... " >&6; } if ${ac_cv_lib_util_extattr_namespace_to_string_extattr_string_to_namespace+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char extattr_namespace_to_string extattr_string_to_namespace (); int main () { return extattr_namespace_to_string extattr_string_to_namespace (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_util_extattr_namespace_to_string_extattr_string_to_namespace=yes else ac_cv_lib_util_extattr_namespace_to_string_extattr_string_to_namespace=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_extattr_namespace_to_string_extattr_string_to_namespace" >&5 $as_echo "$ac_cv_lib_util_extattr_namespace_to_string_extattr_string_to_namespace" >&6; } if test "x$ac_cv_lib_util_extattr_namespace_to_string_extattr_string_to_namespace" = xyes; then : $as_echo "#define HAVE_EXTATTR_NAMESPACE_TO_STRING 1" >>confdefs.h $as_echo "#define HAVE_EXTATTR_STRING_TO_NAMESPACE 1" >>confdefs.h XATTR_LIBS="-lutil $XATTR_LIBS" fi fi fi fi if test $have_xattr = no -a \ x${HAVE_AIX_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "sys/ea.h" "ac_cv_header_sys_ea_h" "$ac_includes_default" if test "x$ac_cv_header_sys_ea_h" = xyes; then : $as_echo "#define HAVE_SYS_EA_H 1" >>confdefs.h fi for ac_func in llistea lgetea lsetea do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_LLISTEA 1" >>confdefs.h $as_echo "#define HAVE_LGETEA 1" >>confdefs.h $as_echo "#define HAVE_LSETEA 1" >>confdefs.h fi done if test $have_xattr = no; then for ac_func in listea getea setea do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_LISTEA 1" >>confdefs.h $as_echo "#define HAVE_GETEA 1" >>confdefs.h $as_echo "#define HAVE_SETEA 1" >>confdefs.h fi done fi fi if test $have_xattr = no -a \ x${HAVE_OSF1_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "sys/proplist.h" "ac_cv_header_sys_proplist_h" "$ac_includes_default" if test "x$ac_cv_header_sys_proplist_h" = xyes; then : $as_echo "#define HAVE_SYS_PROPLIST_H 1" >>confdefs.h fi for ac_func in getproplist get_proplist_entry sizeof_proplist_entry add_proplist_entry setproplist do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_GETPROPLIST 1" >>confdefs.h $as_echo "#define HAVE_GET_PROPLIST_ENTRY 1" >>confdefs.h $as_echo "#define HAVE_SIZEOF_PROPLIST_ENTRY 1" >>confdefs.h $as_echo "#define HAVE_ADD_PROPLIST_ENTRY 1" >>confdefs.h $as_echo "#define HAVE_SETPROPLIST 1" >>confdefs.h fi done fi if test $have_xattr = no -a \ x${HAVE_SUN_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "sys/attr.h" "ac_cv_header_sys_attr_h" "$ac_includes_default" if test "x$ac_cv_header_sys_attr_h" = xyes; then : $as_echo "#define HAVE_SYS_ATTR_H 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "sys/nvpair.h" "ac_cv_header_sys_nvpair_h" "$ac_includes_default" if test "x$ac_cv_header_sys_nvpair_h" = xyes; then : $as_echo "#define HAVE_SYS_NVPAIR_H 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "attr.h" "ac_cv_header_attr_h" "$ac_includes_default" if test "x$ac_cv_header_attr_h" = xyes; then : $as_echo "#define HAVE_ATTR_H 1" >>confdefs.h fi for ac_func in openat fstatat unlinkat fchownat futimesat do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_OPENAT 1" >>confdefs.h $as_echo "#define HAVE_FSTATAT 1" >>confdefs.h $as_echo "#define HAVE_UNLINKAT 1" >>confdefs.h $as_echo "#define HAVE_FCHOWNAT 1" >>confdefs.h $as_echo "#define HAVE_FUTIMESAT 1" >>confdefs.h fi done if test $have_xattr = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nvlist_next_nvpair in -lnvpair" >&5 $as_echo_n "checking for nvlist_next_nvpair in -lnvpair... " >&6; } if ${ac_cv_lib_nvpair_nvlist_next_nvpair+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnvpair $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nvlist_next_nvpair (); int main () { return nvlist_next_nvpair (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nvpair_nvlist_next_nvpair=yes else ac_cv_lib_nvpair_nvlist_next_nvpair=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nvpair_nvlist_next_nvpair" >&5 $as_echo "$ac_cv_lib_nvpair_nvlist_next_nvpair" >&6; } if test "x$ac_cv_lib_nvpair_nvlist_next_nvpair" = xyes; then : $as_echo "#define HAVE_NVLIST_NEXT_NVPAIR 1" >>confdefs.h XATTR_LIBS="-lnvpair $XATTR_LIBS" fi fi fi if test $have_xattr = no; then ac_fn_c_check_header_mongrel "$LINENO" "sys/xattr.h" "ac_cv_header_sys_xattr_h" "$ac_includes_default" if test "x$ac_cv_header_sys_xattr_h" = xyes; then : $as_echo "#define HAVE_SYS_XATTR_H 1" >>confdefs.h fi for ac_func in llistxattr lgetxattr lsetxattr do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_LLISTXATTR 1" >>confdefs.h $as_echo "#define HAVE_LGETXATTR 1" >>confdefs.h $as_echo "#define HAVE_LSETXATTR 1" >>confdefs.h fi done if test $have_xattr = no; then for ac_func in listxattr getxattr setxattr do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_xattr=yes $as_echo "#define HAVE_LISTXATTR 1" >>confdefs.h $as_echo "#define HAVE_GETXATTR 1" >>confdefs.h $as_echo "#define HAVE_SETXATTR 1" >>confdefs.h fi done fi fi if test x$support_xattr = xyes -a $have_xattr != yes; then as_fn_error $? "xattr support explicitly enabled but no supported xattr implementation found, please either load the xattr libraries or rerun configure without --enable-xattr" "$LINENO" 5 else if test $have_xattr = yes; then $as_echo "#define HAVE_XATTR 1" >>confdefs.h fi fi fi if test x$use_libtool != xno; then XATTR_LIBS_NONSHARED="" else XATTR_LIBS_NONSHARED="${XATTR_LIBS}" fi support_scsi_crypto=no # Check whether --enable-scsi-crypto was given. if test "${enable_scsi_crypto+set}" = set; then : enableval=$enable_scsi_crypto; if test x$enableval = xyes; then support_scsi_crypto=yes fi fi CAM_LIBS="" have_scsi_crypto=no if test x$support_scsi_crypto = xyes; then if test x${HAVE_LINUX_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "scsi/sg.h" "ac_cv_header_scsi_sg_h" "$ac_includes_default" if test "x$ac_cv_header_scsi_sg_h" = xyes; then : $as_echo "#define HAVE_SCSI_SG_H 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "scsi/scsi.h" "ac_cv_header_scsi_scsi_h" "$ac_includes_default" if test "x$ac_cv_header_scsi_scsi_h" = xyes; then : $as_echo "#define HAVE_SCSI_SCSI_H 1" >>confdefs.h fi if test x$ac_cv_header_scsi_sg_h = xyes -a \ x$ac_cv_header_scsi_scsi_h = xyes; then have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_SUN_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "sys/scsi/impl/uscsi.h" "ac_cv_header_sys_scsi_impl_uscsi_h" "$ac_includes_default" if test "x$ac_cv_header_sys_scsi_impl_uscsi_h" = xyes; then : $as_echo "#define HAVE_SYS_SCSI_IMPL_USCSI_H 1" >>confdefs.h fi if test x$ac_cv_header_sys_scsi_impl_uscsi_h = xyes; then have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_FREEBSD_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "camlib.h" "ac_cv_header_camlib_h" "$ac_includes_default" if test "x$ac_cv_header_camlib_h" = xyes; then : $as_echo "#define HAVE_CAMLIB_H 1" >>confdefs.h fi ac_fn_c_check_header_mongrel "$LINENO" "cam/scsi/scsi_message.h" "ac_cv_header_cam_scsi_scsi_message_h" "$ac_includes_default" if test "x$ac_cv_header_cam_scsi_scsi_message_h" = xyes; then : $as_echo "#define HAVE_CAM_SCSI_SCSI_MESSAGE_H 1" >>confdefs.h fi if test x$ac_cv_header_camlib_h = xyes -a \ x$ac_cv_header_cam_scsi_scsi_message_h = xyes; then CAM_LIBS="-lcam" have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_NETBSD_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "dev/scsipi/scsipi_all.h" "ac_cv_header_dev_scsipi_scsipi_all_h" "$ac_includes_default" if test "x$ac_cv_header_dev_scsipi_scsipi_all_h" = xyes; then : $as_echo "#define HAVE_DEV_SCSIPI_SCSIPI_ALL_H 1" >>confdefs.h fi if test x$ac_cv_header_dev_scsipo_scsipo_all_h = xyes; then have_scsi_crypto=yes fi fi if test $have_scsi_crypto = no -a \ x${HAVE_OPENBSD_OS_TRUE} = x; then ac_fn_c_check_header_mongrel "$LINENO" "scsi/uscsi_all.h" "ac_cv_header_scsi_uscsi_all_h" "$ac_includes_default" if test "x$ac_cv_header_scsi_uscsi_all_h" = xyes; then : $as_echo "#define HAVE_USCSI_ALL_H 1" >>confdefs.h fi if test x$ac_cv_header_scsi_uscsi_all_h = xyes; then have_scsi_crypto=yes fi fi if test x$support_scsi_crypto = xyes -a $have_scsi_crypto != yes; then as_fn_error $? "scsi crypto support explicitly enabled but no supported scsi crypto implementation found, please rerun configure without --enable-scsi-crypto" "$LINENO" 5 else $as_echo "#define HAVE_LOWLEVEL_SCSI_INTERFACE 1" >>confdefs.h fi fi GLUSTER_LIBS="-lgfapi" GLUSTER_INC="" have_glusterfs=no # Check whether --with-glusterfs was given. if test "${with_glusterfs+set}" = set; then : withval=$with_glusterfs; with_glusterfs_directory=$withval fi if test "x${with_glusterfs_directory}" != "xyes" && test x"${with_glusterfs_directory}" != "x"; then # # Make sure the $with_glusterfs_directory also makes sense # if test -d "${with_glusterfs_directory}/lib" -a -d "${with_glusterfs_directory}/include"; then GLUSTER_LIBS="-L${with_glusterfs_directory}/lib ${GLUSTER_LIBS}" GLUSTER_INC="-I${with_glusterfs_directory}/include ${GLUSTER_INC}" fi else GLUSTER_INC="-I/usr/include/glusterfs" fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${GLUSTER_LIBS}" CFLAGS="${saved_CFLAGS} ${GLUSTER_INC}" CPPFLAGS="${saved_CPPFLAGS} ${GLUSTER_INC}" ac_fn_c_check_header_mongrel "$LINENO" "api/glfs.h" "ac_cv_header_api_glfs_h" "$ac_includes_default" if test "x$ac_cv_header_api_glfs_h" = xyes; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glfs_init in gfapi library" >&5 $as_echo_n "checking for glfs_init in gfapi library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { glfs_new("volumename"); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_glusterfs="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_glusterfs="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_glusterfs}" = "xyes"; then $as_echo "#define HAVE_GFAPI 1" >>confdefs.h else GLUSTER_LIBS="" GLUSTER_INC="" fi DROPLET_LIBS="-ldroplet" DROPLET_INC="" have_droplet=no # Check whether --with-droplet was given. if test "${with_droplet+set}" = set; then : withval=$with_droplet; with_droplet_directory=$withval fi if test "x${with_droplet_directory}" != "xyes" && test x"${with_droplet_directory}" != "x"; then # # Make sure the $with_droplet_directory also makes sense # if test -d "${with_droplet_directory}/lib" -a -d "${with_droplet_directory}/include"; then DROPLET_LIBS="-L${with_droplet_directory}/lib ${DROPLET_LIBS}" DROPLET_INC="-I${with_droplet_directory}/include ${DROPLET_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${DROPLET_LIBS}" CFLAGS="${saved_CFLAGS} ${DROPLET_INC}" CPPFLAGS="${saved_CPPFLAGS} ${DROPLET_INC}" ac_fn_c_check_header_mongrel "$LINENO" "droplet.h" "ac_cv_header_droplet_h" "$ac_includes_default" if test "x$ac_cv_header_droplet_h" = xyes; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dpl_ctx_new in libdroplet library" >&5 $as_echo_n "checking for dpl_ctx_new in libdroplet library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { dpl_ctx_new(NULL, NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_droplet="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_droplet="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_droplet}" = "xyes"; then $as_echo "#define HAVE_OBJECTSTORE 1" >>confdefs.h else DROPLET_LIBS="" DROPLET_INC="" fi RADOS_LIBS="-lrados" RADOS_INC="" have_ceph_rados=no # Check whether --with-rados was given. if test "${with_rados+set}" = set; then : withval=$with_rados; with_rados_directory=$withval fi if test "x${with_rados_directory}" != "xyes" && test x"${with_rados_directory}" != "x"; then # # Make sure the $with_rados_directory also makes sense # if test -d "${with_rados_directory}/lib" -a -d "${with_rados_directory}/include"; then RADOS_LIBS="-L${with_rados_directory}/lib ${RADOS_LIBS}" RADOS_INC="-I${with_rados_directory}/include ${RADOS_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${RADOS_LIBS}" CFLAGS="${saved_CFLAGS} ${RADOS_INC}" CPPFLAGS="${saved_CPPFLAGS} ${RADOS_INC}" ac_fn_c_check_header_mongrel "$LINENO" "rados/librados.h" "ac_cv_header_rados_librados_h" "$ac_includes_default" if test "x$ac_cv_header_rados_librados_h" = xyes; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rados_create in rados library" >&5 $as_echo_n "checking for rados_create in rados library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { rados_t cluster; rados_create(&cluster, NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_ceph_rados="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_ceph_rados="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_ceph_rados}" = "xyes"; then $as_echo "#define HAVE_RADOS 1" >>confdefs.h else RADOS_LIBS="" RADOS_INC="" fi CEPHFS_LIBS="-lcephfs" CEPHFS_INC="" have_cephfs=no # Check whether --with-cephfs was given. if test "${with_cephfs+set}" = set; then : withval=$with_cephfs; with_cephfs_directory=$withval fi if test "x${with_cephfs_directory}" != "xyes" && test x"${with_cephfs_directory}" != "x"; then # # Make sure the $with_cephfs_directory also makes sense # if test -d "${with_cephfs_directory}/lib" -a -d "${with_cephfs_directory}/include"; then CEPHFS_LIBS="-L${with_cephfs_directory}/lib ${CEPHFS_LIBS}" CEPHFS_INC="-I${with_cephfs_directory}/include ${CEPHFS_INC}" fi fi saved_LIBS="${LIBS}" saved_CFLAGS="${CFLAGS}" saved_CPPFLAGS="${CPPFLAGS}" LIBS="${saved_LIBS} ${CEPHFS_LIBS}" CFLAGS="${saved_CFLAGS} ${CEPHFS_INC}" CPPFLAGS="${saved_CPPFLAGS} ${CEPHFS_INC}" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_fn_cxx_check_header_mongrel "$LINENO" "cephfs/libcephfs.h" "ac_cv_header_cephfs_libcephfs_h" "$ac_includes_default" if test "x$ac_cv_header_cephfs_libcephfs_h" = xyes; then : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceph_create in cephfs library" >&5 $as_echo_n "checking for ceph_create in cephfs library... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct ceph_mount_info *cmount; ceph_create(&cmount, NULL); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_cephfs="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_cephfs="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBS="${saved_LIBS}" CFLAGS="${saved_CFLAGS}" CPPFLAGS="${saved_CPPFLAGS}" if test "x${have_cephfs}" = "xyes"; then $as_echo "#define HAVE_CEPHFS 1" >>confdefs.h else CEPHFS_LIBS="" CEPHFS_INC="" fi PTHREAD_LIB="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : PTHREAD_LIB="-lpthread" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5 $as_echo_n "checking for pthread_create in -lpthreads... " >&6; } if ${ac_cv_lib_pthreads_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthreads_pthread_create=yes else ac_cv_lib_pthreads_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5 $as_echo "$ac_cv_lib_pthreads_pthread_create" >&6; } if test "x$ac_cv_lib_pthreads_pthread_create" = xyes; then : PTHREAD_LIB="-lpthreads" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 $as_echo_n "checking for pthread_create in -lc_r... " >&6; } if ${ac_cv_lib_c_r_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_r_pthread_create=yes else ac_cv_lib_c_r_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_create" >&5 $as_echo "$ac_cv_lib_c_r_pthread_create" >&6; } if test "x$ac_cv_lib_c_r_pthread_create" = xyes; then : PTHREAD_LIB="-lc_r" else ac_fn_c_check_func "$LINENO" "pthread_create" "ac_cv_func_pthread_create" if test "x$ac_cv_func_pthread_create" = xyes; then : fi fi fi fi for ac_header in sys/prctl.h sys/capability.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in prctl setreuid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_set_proc in -lcap" >&5 $as_echo_n "checking for cap_set_proc in -lcap... " >&6; } if ${ac_cv_lib_cap_cap_set_proc+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cap_set_proc (); int main () { return cap_set_proc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cap_cap_set_proc=yes else ac_cv_lib_cap_cap_set_proc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_set_proc" >&5 $as_echo "$ac_cv_lib_cap_cap_set_proc" >&6; } if test "x$ac_cv_lib_cap_cap_set_proc" = xyes; then : CAP_LIBS="-lcap" else CAP_LIBS= fi if test x$CAP_LIBS = x-lcap; then $as_echo "#define HAVE_LIBCAP 1" >>confdefs.h fi CFLAGS=${CFLAGS--O} if test x$have_gcc = xyes ; then CPPFLAGS="$CPPFLAGS -fno-strict-aliasing -fno-exceptions" CFLAGS="$CFLAGS -fno-strict-aliasing -fno-exceptions" CXXFLAGS="$CFLAGS -fno-strict-aliasing -fno-exceptions -fno-rtti" fi LDFLAGS=${LDFLAGS--O} CPPFLAGS="$CPPFLAGS" CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" lld="lld" llu="llu" WCFLAGS= WLDFLAGS= PFILES="platforms/Makefile" PSCMD="ps -e" MACOSX= COMPRESS_MANPAGES=yes case "$DISTNAME" in aix) TAPEDRIVE="/dev/rmt0.1" PSCMD="ps -e -o pid,comm" PFILES="${PFILES} \ platforms/aix/Makefile" largefile_support="yes" ;; alpha) PTHREAD_LIB="-lpthread -lexc" if test "${CC}" = "gcc" ; then lld="lld" llu="llu" else lld="ld" llu="lu" fi TAPEDRIVE="/dev/nrmt0" ;; bsdi) TAPEDRIVE="/dev/nrmt0" PTHREAD_LIB="-pthread" CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" PSCMD="ps -ax -o pid,command" lld="qd" llu="qu" PFILES="${PFILES} \ platforms/bsdi/Makefile \ platforms/bsdi/bareos-fd \ platforms/bsdi/bareos-sd \ platforms/bsdi/bareos-dir" largefile_support="yes" ;; darwin) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" MACOSX=macosx PFILES="${PFILES} \ platforms/darwin/Makefile" ;; osx) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" MACOSX=macosx PFILES="${PFILES} \ platforms/osx/Makefile" ;; debian|ubuntu|univention) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" DEBIAN_CONTROL_UNIVENTION_BAREOS=/dev/null DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA=/dev/null PFILES="${PFILES} ${DEBIAN_CONTROL} \ debian/bareos-bat.install \ debian/bareos-bat.postinst \ debian/bareos-bconsole.install \ debian/bareos-bconsole.postinst \ debian/bareos-common.install \ debian/bareos-common.postinst \ debian/bareos-common.preinst \ debian/bareos-database-common.config \ debian/bareos-database-common.install \ debian/bareos-database-common.postinst \ debian/bareos-database-mysql.install \ debian/bareos-database-postgresql.install \ debian/bareos-database-sqlite3.install \ debian/bareos-database-tools.install \ debian/bareos-devel.install \ debian/bareos-director-python-plugin.install \ debian/bareos-director.bareos-dir.init \ debian/bareos-director.install \ debian/bareos-director.postinst \ debian/bareos-director.preinst \ debian/bareos-filedaemon-python-plugin.install \ debian/bareos-filedaemon.bareos-fd.init \ debian/bareos-filedaemon.install \ debian/bareos-filedaemon.postinst \ debian/bareos-filedaemon.preinst \ debian/bareos-storage-fifo.postinst \ debian/bareos-storage-fifo.install \ debian/bareos-storage-python-plugin.install \ debian/bareos-storage-tape.postinst \ debian/bareos-storage-tape.install \ debian/bareos-storage.bareos-sd.init \ debian/bareos-storage.install \ debian/bareos-storage.postinst \ debian/bareos-storage.preinst \ debian/bareos-tools.install \ debian/bareos-traymonitor.install \ debian/bareos-traymonitor.postinst \ platforms/debian/Makefile \ platforms/debian/set_dbconfig_vars.sh" case "$DISTNAME" in ubuntu) PFILES="${PFILES} \ platforms/ubuntu/Makefile" ;; univention) DEBIAN_CONTROL_UNIVENTION_BAREOS=./debian/control.univention-bareos DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA=./debian/control.univention-bareos-schema PFILES="${PFILES} \ debian/univention-bareos-schema.install \ debian/univention-bareos-schema.postinst \ debian/univention-bareos.install \ debian/univention-bareos.postinst \ platforms/univention/Makefile" ;; esac ;; freebsd) VER=`echo $DISTVER | cut -c 1` if test x$VER = x4 ; then PTHREAD_LIB="${PTHREAD_LIBS:--pthread}" CFLAGS="${CFLAGS} ${PTHREAD_CFLAGS:--pthread}" CXXFLAGS="${CXXFLAGS} ${PTHREAD_CFLAGS:--pthread}" fi lld="qd" llu="qu" TAPEDRIVE="/dev/nrsa0" PSCMD="ps -ax -o pid,command" PFILES="${PFILES} \ platforms/freebsd/Makefile \ platforms/freebsd/bareos-fd \ platforms/freebsd/bareos-sd \ platforms/freebsd/bareos-dir" largefile_support="yes" ;; hurd) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/hurd/Makefile \ platforms/hurd/bareos-fd \ platforms/hurd/bareos-sd \ platforms/hurd/bareos-dir" ;; hpux) PSCMD="UNIX95=1; ps -e -o pid,comm" CFLAGS="${CFLAGS} -D_XOPEN_SOURCE_EXTENDED=1" CXXFLAGS="${CXXFLAGS} -D_XOPEN_SOURCE_EXTENDED=1" TAPEDRIVE="/dev/rmt/0hnb" PTHREAD_LIB="-lpthread" $as_echo "#define _INCLUDE_LONGLONG 1" >>confdefs.h ;; irix) TAPEDRIVE="/dev/rmt/0cbn" PSCMD="ps -e -o pid,comm" PFILES="${PFILES} \ platforms/irix/Makefile \ platforms/irix/bareos-fd \ platforms/irix/bareos-sd \ platforms/irix/bareos-dir" ;; netbsd) lld="qd" llu="qu" TAPEDRIVE="/dev/nrst0" PSCMD="ps -ax -o pid,command" PTHREAD_LIB="-pthread" CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" ;; openbsd) lld="qd" llu="qu" TAPEDRIVE="/dev/nrst0" PSCMD="ps -ax -o pid,command" PTHREAD_LIB="-pthread" CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" PFILES="${PFILES} \ platforms/openbsd/Makefile \ platforms/openbsd/bareos-fd \ platforms/openbsd/bareos-sd \ platforms/openbsd/bareos-dir" ;; redhat) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/redhat/Makefile \ platforms/redhat/bareos-fd \ platforms/redhat/bareos-sd \ platforms/redhat/bareos-dir " ;; mandrake) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/mandrake/Makefile \ platforms/mandrake/bareos-fd \ platforms/mandrake/bareos-sd \ platforms/mandrake/bareos-dir \ " ;; gentoo) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/gentoo/Makefile \ platforms/gentoo/bareos-init \ platforms/gentoo/bareos-fd \ platforms/gentoo/bareos-sd \ platforms/gentoo/bareos-dir" ;; slackware) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/slackware/Makefile \ platforms/slackware/rc.bareos-fd \ platforms/slackware/rc.bareos-sd \ platforms/slackware/rc.bareos-dir\ platforms/slackware/functions.bareos" ;; solaris) TAPEDRIVE="/dev/rmt/0cbn" PSCMD="ps -e -o pid,comm" PFILES="${PFILES} \ platforms/solaris/Makefile \ platforms/solaris/bareos-fd \ platforms/solaris/bareos-sd \ platforms/solaris/bareos-dir" COMPRESS_MANPAGES= case ${DISTVER} in 5.5|5.6) $as_echo "#define HAVE_OLD_SOCKOPT 1" >>confdefs.h $as_echo "#define USE_THR_SETCONCURRENCY 1" >>confdefs.h $as_echo "#define HAVE_NON_WORKING_WALKCONTEXT 1" >>confdefs.h ;; 5.7|5.8) $as_echo "#define USE_THR_SETCONCURRENCY 1" >>confdefs.h $as_echo "#define HAVE_NON_WORKING_WALKCONTEXT 1" >>confdefs.h ;; 5.9) $as_echo "#define HAVE_NON_WORKING_WALKCONTEXT 1" >>confdefs.h ;; *) ;; esac LIBS="$LIBS -lresolv -lrt" ;; suse) TAPEDRIVE="/dev/nst0" PSCMD="ps -e -o pid,command" PFILES="${PFILES} \ platforms/suse/Makefile \ platforms/suse/bareos-fd \ platforms/suse/bareos-sd \ platforms/suse/bareos-dir \ platforms/suse/bareos" ;; unknown) TAPEDRIVE="/dev/nst0" ;; *) echo " === Something went wrong. Unknown DISTNAME $DISTNAME ===" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd support" >&5 $as_echo_n "checking for systemd support... " >&6; } # Check whether --with-systemd was given. if test "${with_systemd+set}" = set; then : withval=$with_systemd; if test "$withval" != "no"; then if test "$withval" = "yes"; then SYSTEMD_UNITDIR="`systemctl show | grep UnitPath | cut -d " " -f2`" else SYSTEMD_UNITDIR="${withval}" fi PFILES="${PFILES} \ platforms/systemd/Makefile \ platforms/systemd/bareos.conf \ platforms/systemd/bareos-dir.service \ platforms/systemd/bareos-fd.service \ platforms/systemd/bareos-sd.service" $as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } support_systemd="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } support_systemd="no" fi else support_systemd="no" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi LIBS="$PTHREAD_LIB $LIBS" cat >>confdefs.h <<_ACEOF #define lld "$lld" _ACEOF cat >>confdefs.h <<_ACEOF #define llu "$llu" _ACEOF MCOMMON=./autoconf/Make.common BUILD_FD_PLUGINS="" BUILD_SD_PLUGINS="" BUILD_DIR_PLUGINS="" DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN=/dev/null DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN=/dev/null DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN=/dev/null if test X"$support_python" = "Xyes" ; then BUILD_FD_PLUGINS="${BUILD_FD_PLUGINS} python-fd.la" BUILD_SD_PLUGINS="${BUILD_SD_PLUGINS} python-sd.la" BUILD_DIR_PLUGINS="${BUILD_DIR_PLUGINS} python-dir.la" DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN=./debian/control.bareos-filedaemon-python-plugin DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN=./debian/control.bareos-storage-python-plugin DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN=./debian/control.bareos-director-python-plugin fi if test X"$have_scsi_crypto" = "Xyes" ; then BUILD_SD_PLUGINS="${BUILD_SD_PLUGINS} scsicrypto-sd.la scsitapealert-sd.la" fi if test X"$have_zlib" = "Xyes" -o \ X"$have_lzo" = "Xyes" -o \ X"$have_fastlz" = "Xyes" ; then BUILD_SD_PLUGINS="${BUILD_SD_PLUGINS} autoxflate-sd.la" fi if test x$use_libtool != xno; then BUILD_SD_BACKENDS="libbareossd-fifo.la libbareossd-gentape.la libbareossd-tape.la" if test X"$have_glusterfs" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-gfapi.la" fi if test X"$have_droplet" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-object.la" fi if test X"$have_ceph_rados" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-rados.la" fi if test X"$have_cephfs" = "Xyes" ; then BUILD_SD_BACKENDS="${BUILD_SD_BACKENDS} libbareossd-cephfs.la" fi else BUILD_SD_BACKENDS="" fi INSTALL_SD_CONFS="device-fifo.conf device-tape-with-autoloader.conf" if test X"$have_glusterfs" = "Xyes" ; then INSTALL_SD_CONFS="${INSTALL_SD_CONFS} device-gluster.conf" fi if test X"$have_ceph_rados" = "Xyes" ; then INSTALL_SD_CONFS="${INSTALL_SD_CONFS} device-ceph-rados.conf" fi if test "x${subsysdir}" = "x${sbindir}" ; then echo " " echo " " echo "You have set both --sbindir and --with-subsys-dir" echo " equal to: ${subsysdir} " echo "This is not permitted. Please reconfigure." echo " " echo "Aborting configuration ..." echo " " echo " " exit 1 fi ac_config_files="$ac_config_files autoconf/Make.common Makefile manpages/Makefile scripts/bareos-config scripts/bareos-config-lib.sh scripts/bareos-explorer scripts/btraceback scripts/bconsole scripts/bareos scripts/bareos-ctl-dir scripts/bareos-ctl-fd scripts/bareos-ctl-sd scripts/devel_bareos scripts/Makefile scripts/logrotate scripts/mtx-changer scripts/disk-changer scripts/logwatch/Makefile scripts/logwatch/logfile.bareos.conf scripts/bat.console_apps src/Makefile src/include/host.h src/console/Makefile src/console/bconsole.conf src/qt-tray-monitor/bareos-tray-monitor.desktop src/qt-tray-monitor/tray-monitor.conf src/qt-tray-monitor/tray-monitor.pro src/qt-console/bat.conf src/qt-console/bat.desktop src/qt-console/bat.pro src/qt-console/install_conf_file src/dird/Makefile src/dird/bareos-dir.conf src/lib/Makefile src/stored/Makefile src/stored/bareos-sd.conf src/stored/backends/Makefile src/filed/Makefile src/filed/bareos-fd.conf src/cats/Makefile src/cats/make_catalog_backup.pl src/cats/make_catalog_backup src/cats/delete_catalog_backup src/cats/create_bareos_database src/cats/update_bareos_tables src/cats/grant_bareos_privileges src/cats/make_bareos_tables src/cats/drop_bareos_tables src/cats/drop_bareos_database src/cats/install-default-backend src/cats/ddl/versions.map src/findlib/Makefile src/lmdb/Makefile src/ndmp/Makefile src/tests/Makefile src/tools/Makefile src/plugins/filed/Makefile src/plugins/stored/Makefile src/plugins/dird/Makefile po/Makefile.in src/defaultconfigs/diskonly/bareos-sd.conf src/defaultconfigs/diskonly/bareos-dir.conf $PFILES" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by bareos $as_me 14.2.6, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ bareos config.status 14.2.6 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' # Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/config.h:autoconf/config.h.in" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; "autoconf/Make.common") CONFIG_FILES="$CONFIG_FILES autoconf/Make.common" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "manpages/Makefile") CONFIG_FILES="$CONFIG_FILES manpages/Makefile" ;; "scripts/bareos-config") CONFIG_FILES="$CONFIG_FILES scripts/bareos-config" ;; "scripts/bareos-config-lib.sh") CONFIG_FILES="$CONFIG_FILES scripts/bareos-config-lib.sh" ;; "scripts/bareos-explorer") CONFIG_FILES="$CONFIG_FILES scripts/bareos-explorer" ;; "scripts/btraceback") CONFIG_FILES="$CONFIG_FILES scripts/btraceback" ;; "scripts/bconsole") CONFIG_FILES="$CONFIG_FILES scripts/bconsole" ;; "scripts/bareos") CONFIG_FILES="$CONFIG_FILES scripts/bareos" ;; "scripts/bareos-ctl-dir") CONFIG_FILES="$CONFIG_FILES scripts/bareos-ctl-dir" ;; "scripts/bareos-ctl-fd") CONFIG_FILES="$CONFIG_FILES scripts/bareos-ctl-fd" ;; "scripts/bareos-ctl-sd") CONFIG_FILES="$CONFIG_FILES scripts/bareos-ctl-sd" ;; "scripts/devel_bareos") CONFIG_FILES="$CONFIG_FILES scripts/devel_bareos" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "scripts/logrotate") CONFIG_FILES="$CONFIG_FILES scripts/logrotate" ;; "scripts/mtx-changer") CONFIG_FILES="$CONFIG_FILES scripts/mtx-changer" ;; "scripts/disk-changer") CONFIG_FILES="$CONFIG_FILES scripts/disk-changer" ;; "scripts/logwatch/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/logwatch/Makefile" ;; "scripts/logwatch/logfile.bareos.conf") CONFIG_FILES="$CONFIG_FILES scripts/logwatch/logfile.bareos.conf" ;; "scripts/bat.console_apps") CONFIG_FILES="$CONFIG_FILES scripts/bat.console_apps" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/include/host.h") CONFIG_FILES="$CONFIG_FILES src/include/host.h" ;; "src/console/Makefile") CONFIG_FILES="$CONFIG_FILES src/console/Makefile" ;; "src/console/bconsole.conf") CONFIG_FILES="$CONFIG_FILES src/console/bconsole.conf" ;; "src/qt-tray-monitor/bareos-tray-monitor.desktop") CONFIG_FILES="$CONFIG_FILES src/qt-tray-monitor/bareos-tray-monitor.desktop" ;; "src/qt-tray-monitor/tray-monitor.conf") CONFIG_FILES="$CONFIG_FILES src/qt-tray-monitor/tray-monitor.conf" ;; "src/qt-tray-monitor/tray-monitor.pro") CONFIG_FILES="$CONFIG_FILES src/qt-tray-monitor/tray-monitor.pro" ;; "src/qt-console/bat.conf") CONFIG_FILES="$CONFIG_FILES src/qt-console/bat.conf" ;; "src/qt-console/bat.desktop") CONFIG_FILES="$CONFIG_FILES src/qt-console/bat.desktop" ;; "src/qt-console/bat.pro") CONFIG_FILES="$CONFIG_FILES src/qt-console/bat.pro" ;; "src/qt-console/install_conf_file") CONFIG_FILES="$CONFIG_FILES src/qt-console/install_conf_file" ;; "src/dird/Makefile") CONFIG_FILES="$CONFIG_FILES src/dird/Makefile" ;; "src/dird/bareos-dir.conf") CONFIG_FILES="$CONFIG_FILES src/dird/bareos-dir.conf" ;; "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; "src/stored/Makefile") CONFIG_FILES="$CONFIG_FILES src/stored/Makefile" ;; "src/stored/bareos-sd.conf") CONFIG_FILES="$CONFIG_FILES src/stored/bareos-sd.conf" ;; "src/stored/backends/Makefile") CONFIG_FILES="$CONFIG_FILES src/stored/backends/Makefile" ;; "src/filed/Makefile") CONFIG_FILES="$CONFIG_FILES src/filed/Makefile" ;; "src/filed/bareos-fd.conf") CONFIG_FILES="$CONFIG_FILES src/filed/bareos-fd.conf" ;; "src/cats/Makefile") CONFIG_FILES="$CONFIG_FILES src/cats/Makefile" ;; "src/cats/make_catalog_backup.pl") CONFIG_FILES="$CONFIG_FILES src/cats/make_catalog_backup.pl" ;; "src/cats/make_catalog_backup") CONFIG_FILES="$CONFIG_FILES src/cats/make_catalog_backup" ;; "src/cats/delete_catalog_backup") CONFIG_FILES="$CONFIG_FILES src/cats/delete_catalog_backup" ;; "src/cats/create_bareos_database") CONFIG_FILES="$CONFIG_FILES src/cats/create_bareos_database" ;; "src/cats/update_bareos_tables") CONFIG_FILES="$CONFIG_FILES src/cats/update_bareos_tables" ;; "src/cats/grant_bareos_privileges") CONFIG_FILES="$CONFIG_FILES src/cats/grant_bareos_privileges" ;; "src/cats/make_bareos_tables") CONFIG_FILES="$CONFIG_FILES src/cats/make_bareos_tables" ;; "src/cats/drop_bareos_tables") CONFIG_FILES="$CONFIG_FILES src/cats/drop_bareos_tables" ;; "src/cats/drop_bareos_database") CONFIG_FILES="$CONFIG_FILES src/cats/drop_bareos_database" ;; "src/cats/install-default-backend") CONFIG_FILES="$CONFIG_FILES src/cats/install-default-backend" ;; "src/cats/ddl/versions.map") CONFIG_FILES="$CONFIG_FILES src/cats/ddl/versions.map" ;; "src/findlib/Makefile") CONFIG_FILES="$CONFIG_FILES src/findlib/Makefile" ;; "src/lmdb/Makefile") CONFIG_FILES="$CONFIG_FILES src/lmdb/Makefile" ;; "src/ndmp/Makefile") CONFIG_FILES="$CONFIG_FILES src/ndmp/Makefile" ;; "src/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/tests/Makefile" ;; "src/tools/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/Makefile" ;; "src/plugins/filed/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/filed/Makefile" ;; "src/plugins/stored/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/stored/Makefile" ;; "src/plugins/dird/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/dird/Makefile" ;; "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; "src/defaultconfigs/diskonly/bareos-sd.conf") CONFIG_FILES="$CONFIG_FILES src/defaultconfigs/diskonly/bareos-sd.conf" ;; "src/defaultconfigs/diskonly/bareos-dir.conf") CONFIG_FILES="$CONFIG_FILES src/defaultconfigs/diskonly/bareos-dir.conf" ;; "$PFILES") CONFIG_FILES="$CONFIG_FILES $PFILES" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then if $AWK 'BEGIN { getline <"/dev/null" }' /dev/null; then ac_cs_awk_getline=: ac_cs_awk_pipe_init= ac_cs_awk_read_file=' while ((getline aline < (F[key])) > 0) print(aline) close(F[key])' ac_cs_awk_pipe_fini= else ac_cs_awk_getline=false ac_cs_awk_pipe_init="print \"cat <<'|#_!!_#|' &&\"" ac_cs_awk_read_file=' print "|#_!!_#|" print "cat " F[key] " &&" '$ac_cs_awk_pipe_init # The final `:' finishes the AND list. ac_cs_awk_pipe_fini='END { print "|#_!!_#|"; print ":" }' fi ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF # Create commands to substitute file output variables. { echo "cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1" && echo 'cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&' && echo "$ac_subst_files" | sed 's/.*/F["&"]="$&"/' && echo "_ACAWK" && echo "_ACEOF" } >conf$$files.sh && . ./conf$$files.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 rm -f conf$$files.sh { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" \$ac_cs_awk_pipe_init } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } if (nfields == 3 && !substed) { key = field[2] if (F[key] != "" && line ~ /^[ ]*@.*@[ ]*$/) { \$ac_cs_awk_read_file next } } print line } \$ac_cs_awk_pipe_fini _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | if $ac_cs_awk_getline; then $AWK -f "$ac_tmp/subs.awk" else $AWK -f "$ac_tmp/subs.awk" | $SHELL fi \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; "default-1":C) for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi if test "${support_bat}" = "yes" ; then if test "x$QMAKE" = "xnone"; then as_fn_error $? "Could not find qmake $PATH. Check your Qt installation" "$LINENO" 5 fi cd src/qt-console echo "Creating bat Makefile" # hack: required to get "make install" to work touch bat chmod 755 bat rm -f Makefile $QMAKE ${MAKE:-make} clean cd ${BUILD_DIR} fi if test "${support_traymonitor}" = "yes" ; then if test "x$QMAKE" = "xnone"; then as_fn_error $? "Could not find qmake $PATH. Check your Qt installation" "$LINENO" 5 fi cd src/qt-tray-monitor echo "Creating tray-monitor Makefile" # hack: required to get "make install" to work touch bareos-tray-monitor chmod 755 bareos-tray-monitor rm -f Makefile $QMAKE ${MAKE:-make} clean cd ${BUILD_DIR} fi if test X"$GCC" = "Xyes" ; then echo "Doing make of dependencies" ${MAKE:-make} depend fi cd src/qt-console chmod 755 install_conf_file cd ${BUILD_DIR} cd scripts chmod 755 bareos btraceback mtx-changer chmod 755 bconsole mtx-changer devel_bareos logrotate cd .. c=src/cats chmod 755 $c/create_bareos_database $c/update_bareos_tables $c/make_bareos_tables chmod 755 $c/grant_bareos_privileges $c/drop_bareos_tables $c/drop_bareos_database chmod 755 $c/make_catalog_backup $c/delete_catalog_backup $c/make_catalog_backup.pl chmod 755 $c/install-default-backend if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then largefile_support="yes" fi if test X"$GCC" = "Xyes" ; then CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 3 -d ' '` if test "x${CCVERSION}" = "x" ; then CCVERSION=`${CC} --version | tr '\n' ' ' | cut -f 1 -d ' '` fi CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 3 -d ' '` if test x"${CXXVERSION}" = x ; then CXXVERSION=`${CXX} --version | tr '\n' ' ' | cut -f 1 -d ' '` fi fi # clean up any old junk echo " " echo "Cleaning up" echo " " ${MAKE:-make} clean echo " Configuration on `date`: Host: ${host}${post_host} -- ${DISTNAME} ${DISTVER} Bareos version: ${BAREOS} ${VERSION} (${DATE}) Distribution: ${DISTNAME} Source code location: ${srcdir} Modify package list: ${DEBIAN_CONTROL} Install binaries: ${bindir} Install system binaries: ${sbindir} Install libraries: ${libdir} Install config files: ${sysconfdir} Scripts directory: ${scriptdir} Archive directory: ${archivedir} Working directory: ${working_dir} PID directory: ${piddir} Subsys directory: ${subsysdir} Man directory: ${mandir} Data directory: ${datarootdir} Backend directory: ${backenddir} Plugin directory: ${plugindir} C Compiler: ${CC} ${CCVERSION} C++ Compiler: ${CXX} ${CXXVERSION} Compiler flags: ${WCFLAGS} ${CFLAGS} Linker flags: ${WLDFLAGS} ${LDFLAGS} Libraries: ${LIBS} Statically Linked Tools: ${support_static_tools} Statically Linked FD: ${support_static_fd} Statically Linked SD: ${support_static_sd} Statically Linked DIR: ${support_static_dir} Statically Linked CONS: ${support_static_cons} Database backends: ${db_backends} Database port: ${db_port} Database name: ${db_name} Database user: ${db_user} Database version: ${BDB_VERSION} Job Output Email: ${job_email} Traceback Email: ${dump_email} SMTP Host Address: ${smtp_host} Director Port: ${dir_port} File daemon Port: ${fd_port} Storage daemon Port: ${sd_port} Director User: ${dir_user} Director Group: ${dir_group} Storage Daemon User: ${sd_user} Storage DaemonGroup: ${sd_group} File Daemon User: ${fd_user} File Daemon Group: ${fd_group} Large file support: $largefile_support Bareos conio support: ${got_conio} ${CONS_LIBS} readline support: ${got_readline} ${PRTREADLINE_SRC} TCP Wrappers support: ${TCPW_MSG} ${WRAPLIBS} TLS support: ${have_tls} Encryption support: ${have_crypto} OpenSSL support: ${have_openssl} GNUTLS support: ${have_gnutls} ZLIB support: ${have_zlib} LZO support: ${have_lzo} FASTLZ support: ${have_fastlz} LMDB support: ${support_lmdb} NDMP support: ${support_ndmp} enable-smartalloc: ${support_smartalloc} enable-lockmgr: ${support_lockmgr} bat support: ${support_bat} tray-monitor support: ${support_traymonitor} client-only: ${build_client_only} build-dird: ${build_dird} build-stored: ${build_stored} Plugin support: ${have_plugins} AFS support: ${have_afs} ACL support: ${have_acl} XATTR support: ${have_xattr} SCSI Crypto support: ${have_scsi_crypto} GLUSTERFS support: ${have_glusterfs} DROPLET support: ${have_droplet} CEPH RADOS support: ${have_ceph_rados} CEPHFS support: ${have_cephfs} Python support: ${support_python} ${PYTHON_LIBS} systemd support: ${support_systemd} ${SYSTEMD_UNITDIR} Batch insert enabled: ${batch_insert_db_backends} " > config.out # create a small shell script useful for support with # configure options and config.out info cat > scripts/bareos_config << EOF #!/bin/sh cat << __EOC__ $ $0 $ac_configure_args EOF cat config.out >> scripts/bareos_config echo __EOC__ >> scripts/bareos_config chmod 755 scripts/bareos_config cat config.out bareos-Release-14.2.6/debian/000077500000000000000000000000001263011562700156625ustar00rootroot00000000000000bareos-Release-14.2.6/debian/Makefile000066400000000000000000000006511263011562700173240ustar00rootroot00000000000000# # Makefile for preparations of Debian builds # all: copyright copyright: copyright.header copyright.footer @cat copyright.header > copyright @sed -r -e 's/^$$/./' -e 's/^[ ]*(.*)$$/ \1/' ../LICENSE >> copyright @cat copyright.footer >> copyright clean: @rm -f *~ *.log @rm -f -r tmp/* distclean: clean @find . -type f -a -name "*.in" -a ! -name "control.in" | sed -e 's/.in$$//' | xargs rm -f devclean: clean bareos-Release-14.2.6/debian/bareos-bat.install.in000066400000000000000000000003201263011562700216710ustar00rootroot00000000000000@sysconfdir@/bat.conf @configtemplatedir@ /usr/bin/bat /usr/share/pixmaps/bat.png /usr/share/pixmaps/bat.svg /usr/share/applications/bat.desktop /usr/share/man/man1/bat.1.gz /usr/share/doc/bareos/html/ bareos-Release-14.2.6/debian/bareos-bat.postinst.in000066400000000000000000000027361263011562700221230ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos DEFCONFIGDIR="@configtemplatedir@" CONFIG="bat.conf" TARGET="/etc/bareos/${CONFIG}" permissions() { chown root:${daemon_group} $TARGET chmod 640 $TARGET } case "$1" in configure) if [ ! -f "$TARGET" ]; then cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET} /usr/lib/bareos/scripts/bareos-config initialize_local_hostname /usr/lib/bareos/scripts/bareos-config initialize_passwords else cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET}.dist fi permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-bat.postrm000066400000000000000000000003551263011562700211520ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/bat.conf /etc/bareos/bat.conf.dist ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-bconsole.install.in000066400000000000000000000002201263011562700227260ustar00rootroot00000000000000@scriptdir@/bconsole @sysconfdir@/bconsole.conf @configtemplatedir@ /usr/bin/bconsole /usr/sbin/bconsole /usr/share/man/man1/bconsole.1.gz bareos-Release-14.2.6/debian/bareos-bconsole.postinst.in000066400000000000000000000027431263011562700231570ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos DEFCONFIGDIR="@configtemplatedir@" CONFIG="bconsole.conf" TARGET="/etc/bareos/${CONFIG}" permissions() { chown root:${daemon_group} $TARGET chmod 640 $TARGET } case "$1" in configure) if [ ! -f "$TARGET" ]; then cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET} /usr/lib/bareos/scripts/bareos-config initialize_local_hostname /usr/lib/bareos/scripts/bareos-config initialize_passwords else cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET}.dist fi permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-bconsole.postrm000066400000000000000000000003671263011562700222130ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/bconsole.conf /etc/bareos/bconsole.conf.dist ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-common.dirs000066400000000000000000000000541263011562700213050ustar00rootroot00000000000000/etc/bareos /var/lib/bareos /var/log/bareos bareos-Release-14.2.6/debian/bareos-common.docs000066400000000000000000000000541263011562700212740ustar00rootroot00000000000000AGPL-3.0.txt AUTHORS LICENSE README.* build/bareos-Release-14.2.6/debian/bareos-common.install.in000066400000000000000000000006711263011562700224240ustar00rootroot00000000000000@libdir@/libbareos-[0-9]*.so @libdir@/libbareoscfg-[0-9]*.so @libdir@/libbareosfind-[0-9]*.so @libdir@/libbareoslmdb-[0-9]*.so @libdir@/libbareosndmp-[0-9]*.so @libdir@/libbareossd-[0-9]*.so @scriptdir@/bareos-config @scriptdir@/bareos-config-lib.sh @scriptdir@/bareos-explorer @scriptdir@/btraceback.gdb /usr/bin/bsmtp /usr/sbin/bsmtp /usr/sbin/btraceback /usr/share/man/man1/bsmtp.1.gz /usr/share/man/man8/btraceback.8.gz /var/lib/bareos/ bareos-Release-14.2.6/debian/bareos-common.postinst.in000066400000000000000000000022041263011562700226330ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos permissions() { chown ${daemon_user}:${daemon_group} /var/lib/bareos/ chown ${daemon_user}:${daemon_group} /var/log/bareos/ } case "$1" in configure) permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-common.postrm000066400000000000000000000003221263011562700216660ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/.rndpwd ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-common.preinst.in000066400000000000000000000027261263011562700224450ustar00rootroot00000000000000#!/bin/sh # preinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos WORKING_DIR="@working_dir@" create_group() { [ -z "$1" ] && return # creating group if he isn't already there. # use addgroup instead of groupadd, # because "addgroup" uses the next available number, # while "groupadd" uses uses GID_MIN -1 (999) getent group $1 > /dev/null || addgroup -q --system $1 } create_user() { [ -z "$1" ] && return # creating user if he isn't already there. # use adduser instead of useradd, # because "adduser" uses the next available number, # while "useradd" uses uses UID_MIN -1 (999) getent passwd $1 > /dev/null || adduser -q --system --ingroup $daemon_group --home "$WORKING_DIR" --no-create-home --gecos "$1" $1 } case "$1" in install|upgrade) create_group $daemon_group create_user $daemon_user ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-database-common.config.in000066400000000000000000000107411263011562700237640ustar00rootroot00000000000000#!/bin/sh set -e . /usr/share/debconf/confmodule #set -x #echo "bareos-database-common.config: $@" >&2 if [ -r @scriptdir@/bareos-config-lib.sh ]; then . @scriptdir@/bareos-config-lib.sh if [ -f /usr/share/dbconfig-common/dpkg/config ]; then . /usr/share/dbconfig-common/dpkg/config dbc_debug=1 # prevent errors by using || true dbc_dbname=`get_database_name bareos` || true dbc_dbuser=`get_database_user bareos` || true # only required for sqlite3 dbc_basepath=`get_working_dir` # convert Bareos databases types into dbconfig_dbtypes dbc_dbtypes="" DB_INSTALLED=`get_databases_installed` if echo "$DB_INSTALLED" | grep -q postgresql; then dbc_dbtypes="${dbc_dbtypes}pgsql, "; fi if echo "$DB_INSTALLED" | grep -q mysql ; then dbc_dbtypes="${dbc_dbtypes}mysql, "; fi if echo "$DB_INSTALLED" | grep -q sqlite3 ; then dbc_dbtypes="${dbc_dbtypes}sqlite3, "; fi # remove trailing , dbc_dbtypes=`echo ${dbc_dbtypes} | sed 's/, *$//'` # action param1="$1" shift || true # $2: when action is "configure": most-recently-configured-version param2="$1" param2_orig=$param2 shift || true # When upgrading from an older version (param2), # do not pass the version number of the old package. # Instead we pass the database version number of the old package. if [ "$param2" ]; then case "$param1" in configure|reconfigure) param2=`get_database_version_by_release "$param2"` # dbconfig is available since Bareos version >= 14.1.0. # TODO: currently the database version for the first version using dbconfig # is identical with the last version without dbconfig. # Therefore we fake dbc_first_version and set it to 2003. # As soon as there is a database version 2003, # this will be true anyway. if dpkg --compare-versions "$param2_orig" lt "14.1.0"; then bareos_migrate_to_dbconfig="yes" dbc_first_version="2003" dbc_load_include="sh:/usr/lib/bareos/scripts/set_dbconfig_vars.sh" # empty passwords require special treatment, see below bareos_database_password=`get_database_password` || true # if password is given, set authmethod to password, # otherwise postgresql configuration will stay at default "ident" method. if [ "${bareos_database_password}" ]; then dbc_authmethod_user="password" fi fi ;; *) ;; esac fi dbc_go bareos-database-common $param1 $param2 $@ if [ "$bareos_migrate_to_dbconfig" = "yes" ]; then # TODO: check if settings app-pass to "" is really required. # Or is it only required for "DEBIAN_FRONTEND=noninteractive" ? case "`get_database_driver`" in postgresql) if [ -z "${bareos_database_password}" ]; then #db_set bareos-database-common/pgsql/authmethod-user "ident" # workaround: if an empty database password is defined, explicitly set it db_set bareos-database-common/pgsql/app-pass "" fi ;; mysql) if [ -z "${bareos_database_password}" ]; then # workaround: if an empty mysql password is defined, explicitly set it db_set bareos-database-common/mysql/app-pass "" fi ;; sqlite3) # dbconfig expects sqlite files as "dbname.db" # while Bareos expects them as "dbname". # A link is created, so that both names matches. if [ -e "${dbc_basepath}/${dbc_dbname}.db" ]; then if ! [ -e "${dbc_basepath}/${dbc_dbname}" ]; then ln -s "${dbc_basepath}/${dbc_dbname}.db" "${dbc_basepath}/${dbc_dbname}" fi fi ;; esac fi fi fi bareos-Release-14.2.6/debian/bareos-database-common.install.in000066400000000000000000000005011263011562700241560ustar00rootroot00000000000000@libdir@/libbareoscats-[0-9]*.so @libdir@/libbareossql-*.so @scriptdir@/create_bareos_database @scriptdir@/drop_bareos_database @scriptdir@/drop_bareos_tables @scriptdir@/grant_bareos_privileges @scriptdir@/make_bareos_tables @scriptdir@/set_dbconfig_vars.sh @scriptdir@/update_bareos_tables @scriptdir@/ddl/versions.map bareos-Release-14.2.6/debian/bareos-database-common.postinst.in000066400000000000000000000035041263011562700244010ustar00rootroot00000000000000#!/bin/sh set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package #set -x #echo "bareos-database-common.postinst: $@" >&2 . /usr/share/debconf/confmodule if [ -r @scriptdir@/bareos-config-lib.sh ]; then . @scriptdir@/bareos-config-lib.sh if [ -f /usr/share/dbconfig-common/dpkg/postinst ]; then . /usr/share/dbconfig-common/dpkg/postinst # action param1="$1" shift || true # when action is "configure": most-recently-configured-version param2="$1" shift || true if [ "$param2" ]; then case "$param1" in configure|reconfigure) param2=`get_database_version_by_release "$param2"` ;; *) ;; esac fi # dbc_pgsql_createdb_encoding: required for postgresql dbc_pgsql_createdb_encoding="SQL_ASCII" # dbc_dbfile_owner: only required for sqlite3 dbc_dbfile_owner=`get_user_dir`:`get_group_dir` # substitution is only done on installs, not on updates! #dbc_sql_substitutions="yes" # run dbconfig dbc_go bareos-database-common $param1 $param2 $@ # apply the dbconfig settings, ignore errors @scriptdir@/bareos-config apply_dbconfig_settings || true fi fi #DEBHELPER# bareos-Release-14.2.6/debian/bareos-database-common.postrm000066400000000000000000000004311263011562700234310ustar00rootroot00000000000000#!/bin/sh set -e if [ -f /usr/share/debconf/confmodule ]; then . /usr/share/debconf/confmodule if [ -f /usr/share/dbconfig-common/dpkg/postrm ]; then . /usr/share/dbconfig-common/dpkg/postrm dbc_go bareos-database-common $@ fi fi #DEBHELPER# bareos-Release-14.2.6/debian/bareos-database-common.prerm000066400000000000000000000004171263011562700232360ustar00rootroot00000000000000#!/bin/sh set -e if [ -f /usr/share/debconf/confmodule ]; then . /usr/share/debconf/confmodule if [ -f /usr/share/dbconfig-common/dpkg/prerm ]; then . /usr/share/dbconfig-common/dpkg/prerm dbc_go bareos-database-common $@ fi fi #DEBHELPER# bareos-Release-14.2.6/debian/bareos-database-mysql.install.in000066400000000000000000000003161263011562700240370ustar00rootroot00000000000000@backenddir@/libbareoscats-mysql*.so @scriptdir@/ddl/*/mysql*.sql /usr/share/dbconfig-common/data/bareos-database-common/install/mysql /usr/share/dbconfig-common/data/bareos-database-common/upgrade/mysql/* bareos-Release-14.2.6/debian/bareos-database-postgresql.install.in000066400000000000000000000004471263011562700251020ustar00rootroot00000000000000@backenddir@/libbareoscats-postgresql*.so @scriptdir@/ddl/*/postgresql*.sql /usr/share/dbconfig-common/data/bareos-database-common/install/pgsql /usr/share/dbconfig-common/data/bareos-database-common/upgrade-dbadmin/pgsql/* /usr/share/dbconfig-common/data/bareos-database-common/upgrade/pgsql/* bareos-Release-14.2.6/debian/bareos-database-sqlite3.install.in000066400000000000000000000003261263011562700242570ustar00rootroot00000000000000@backenddir@/libbareoscats-sqlite3*.so @scriptdir@/ddl/*/sqlite3*.sql /usr/share/dbconfig-common/data/bareos-database-common/install/sqlite3 /usr/share/dbconfig-common/data/bareos-database-common/upgrade/sqlite3/* bareos-Release-14.2.6/debian/bareos-database-tools.install.in000066400000000000000000000001601263011562700240270ustar00rootroot00000000000000/usr/sbin/bareos-dbcheck /usr/sbin/bscan /usr/share/man/man8/bareos-dbcheck.8.gz /usr/share/man/man8/bscan.8.gz bareos-Release-14.2.6/debian/bareos-devel.install.in000066400000000000000000000000241263011562700222230ustar00rootroot00000000000000/usr/include/bareos bareos-Release-14.2.6/debian/bareos-director-python-plugin.install.in000066400000000000000000000003111263011562700255510ustar00rootroot00000000000000@plugindir@/python-dir.so @plugindir@/bareos-dir.py* @plugindir@/bareos_dir_consts.py* @plugindir@/BareosDirWrapper.py* @plugindir@/BareosDirPluginBaseclass.py* @plugindir@/bareos-dir-class-plugin.py* bareos-Release-14.2.6/debian/bareos-director.bareos-dir.init.in000077500000000000000000000142321263011562700242730ustar00rootroot00000000000000#! /bin/sh ### BEGIN INIT INFO # Provides: bareos-dir # Required-Start: $network $remote_fs $time $syslog # Should-Start: postgresql mysql bareos-sd bareos-fd # Required-Stop: $network $remote_fs $time $syslog # Should-Stop: postgresql mysq bareos-sd bareos-fd # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Bareos Director # Description: Bareos is a network backup and restore program. # The Bareos Director controls the Bareos Storage- and File-Daemons. ### END INIT INFO DESC="Bareos Director" NAME=bareos-dir NETWORK_PORT=@dir_port@ DAEMON_USER=@dir_user@ DAEMON_GROUP=@dir_group@ DAEMON=/usr/sbin/$NAME if [ "x${DAEMON_USER}" != "x" ]; then DAEMON_USERGROUP="--chuid ${DAEMON_USER}" if [ "x${DAEMON_GROUP}" != "x" ]; then DAEMON_USERGROUP="${DAEMON_USERGROUP}:${DAEMON_GROUP}" fi fi DAEMON_ARGS= PIDFILE=@piddir@/${NAME}.${NETWORK_PORT}.pid SCRIPTNAME=/etc/init.d/$NAME PATH=/sbin:/usr/sbin:/bin:/usr/bin # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # workaround, if status_of_proc is not defined (Ubuntu 8.04) if ! type status_of_proc >/dev/null; then status_of_proc () { local pidfile daemon name status OPTIND pidfile= OPTIND=1 while getopts p: opt ; do case "$opt" in p) pidfile="$OPTARG";; esac done shift $(($OPTIND - 1)) if [ -n "$pidfile" ]; then pidfile="-p $pidfile" fi daemon="$1" name="$2" status="0" pidofproc $pidfile $daemon >/dev/null || status="$?" if [ "$status" = 0 ]; then log_success_msg "$name is running" return 0 elif [ "$status" = 4 ]; then log_failure_msg "could not access PID file for $name" return $status else log_failure_msg "$name is not running" return $status fi } fi # # Function that checks if the configuration is OK and # the Database can be connected # checkcfg() { echo "Checking Configuration and Database connection ... " su -s /bin/sh $DAEMON_USER -c "@sbindir@/bareos-dir -f -t -c @sysconfdir@/bareos-dir.conf" if [ $? -eq 0 ]; then return 0 else return 1 fi } # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started checkcfg || return 2 start-stop-daemon --start --quiet --pidfile $PIDFILE $DAEMON_USERGROUP --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE $DAEMON_USERGROUP --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. TIMEOUT=5 while [ $TIMEOUT -gt 0 ] && ! do_check; do sleep 1 TIMEOUT=$((TIMEOUT-1)) done do_check return $? } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE $DAEMON_USERGROUP --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 $DAEMON_USERGROUP --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that checks if daemon is running # do_check() { STATUS=2 # Ubuntu 8.04 does not support "lsof -s "TCP:LISTEN", therefore "grep '(LISTEN)'" is used pidofproc -p $PIDFILE $DAEMON >/dev/null && lsof -i "TCP:${NETWORK_PORT}" | grep --quiet '(LISTEN)' && STATUS=0 return $STATUS } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; reload|force-reload) # # If do_reload() is not implemented then leave this commented out # and leave 'force-reload' as an alias for 'restart'. # log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2 exit 3 ;; esac : bareos-Release-14.2.6/debian/bareos-director.dirs000066400000000000000000000000511263011562700216250ustar00rootroot00000000000000/etc/bareos/bareos-dir.d /usr/lib/bareos bareos-Release-14.2.6/debian/bareos-director.install.in000066400000000000000000000004441263011562700227450ustar00rootroot00000000000000/etc/logrotate.d/bareos-dir @scriptdir@/delete_catalog_backup @scriptdir@/make_catalog_backup @scriptdir@/make_catalog_backup.pl @scriptdir@/query.sql @sysconfdir@/bareos-dir.conf @configtemplatedir@ /usr/sbin/bareos-dir /usr/share/man/man8/bareos-dir.8.gz /usr/share/man/man8/bareos.8.gz bareos-Release-14.2.6/debian/bareos-director.postinst.in000066400000000000000000000033131263011562700231600ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos DEFCONFIGDIR="@configtemplatedir@" CONFIG="bareos-dir.conf" TARGET="/etc/bareos/${CONFIG}" permissions() { chown ${daemon_user}:${daemon_group} /etc/bareos/bareos-dir.d chown ${daemon_user}:${daemon_group} $TARGET chmod 640 $TARGET } case "$1" in configure) if [ ! -f "$TARGET" ]; then cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET} /usr/lib/bareos/scripts/bareos-config initialize_local_hostname /usr/lib/bareos/scripts/bareos-config initialize_passwords /usr/lib/bareos/scripts/bareos-config initialize_database_driver /usr/lib/bareos/scripts/bareos-config apply_dbconfig_settings else cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET}.dist fi permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-director.postrm000066400000000000000000000003731263011562700222170ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/bareos-dir.conf /etc/bareos/bareos-dir.conf.dist ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-director.preinst.in000066400000000000000000000027431263011562700227670ustar00rootroot00000000000000#!/bin/sh # preinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_group=@dir_group@ daemon_user=@dir_user@ WORKING_DIR="@working_dir@" create_group() { [ -z "$1" ] && return # creating group if he isn't already there. # use addgroup instead of groupadd, # because "addgroup" uses the next available number, # while "groupadd" uses uses GID_MIN -1 (999) getent group $1 > /dev/null || addgroup -q --system $1 } create_user() { [ -z "$1" ] && return # creating user if he isn't already there. # use adduser instead of useradd, # because "adduser" uses the next available number, # while "useradd" uses uses UID_MIN -1 (999) getent passwd $1 > /dev/null || adduser -q --system --ingroup $daemon_group --home "$WORKING_DIR" --no-create-home --gecos "$1" $1 } case "$1" in install|upgrade) create_group ${daemon_group} create_user ${daemon_user} ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-director.prerm000066400000000000000000000023441263011562700220200ustar00rootroot00000000000000#!/bin/sh # prerm script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in remove|deconfigure) # stop only on deinstall. Restart on upgrade must be done manually if [ -x "/etc/init.d/bareos-dir" ]; then if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then invoke-rc.d bareos-dir stop || exit $? else /etc/init.d/bareos-dir stop || exit $? fi fi ;; failed-upgrade|upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-filedaemon-python-plugin.install.in000066400000000000000000000004231263011562700260450ustar00rootroot00000000000000@plugindir@/python-fd.so @plugindir@/bareos-fd.py* @plugindir@/bareos-fd-local-fileset.py* @plugindir@/bareos-fd-mock-test.py* @plugindir@/BareosFdPluginBaseclass.py* @plugindir@/BareosFdPluginLocalFileset.py* @plugindir@/BareosFdWrapper.py* @plugindir@/bareos_fd_consts.py* bareos-Release-14.2.6/debian/bareos-filedaemon.bareos-fd.init.in000077500000000000000000000135431263011562700244020ustar00rootroot00000000000000#! /bin/sh ### BEGIN INIT INFO # Provides: bareos-fd # Required-Start: $network $remote_fs $time $syslog # Required-Stop: $network $remote_fs $time $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Bareos File Daemon # Description: Bareos is a network backup and restore program. # The Bareos File Daemon backup the local system # on behalf of the Bareos Director and # sends the data to the Bareos Storage Daemon. # It also receives data from restores. ### END INIT INFO DESC="Bareos File Daemon" NAME=bareos-fd NETWORK_PORT=@fd_port@ DAEMON_USER=@fd_user@ DAEMON_GROUP=@fd_group@ DAEMON=/usr/sbin/$NAME if [ "x${DAEMON_USER}" != "x" ]; then DAEMON_USERGROUP="--chuid ${DAEMON_USER}" if [ "x${DAEMON_GROUP}" != "x" ]; then DAEMON_USERGROUP="${DAEMON_USERGROUP}:${DAEMON_GROUP}" fi fi DAEMON_ARGS= PIDFILE=@piddir@/${NAME}.${NETWORK_PORT}.pid SCRIPTNAME=/etc/init.d/$NAME PATH=/sbin:/usr/sbin:/bin:/usr/bin # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # workaround, if status_of_proc is not defined (Ubuntu 8.04) if ! type status_of_proc >/dev/null; then status_of_proc () { local pidfile daemon name status OPTIND pidfile= OPTIND=1 while getopts p: opt ; do case "$opt" in p) pidfile="$OPTARG";; esac done shift $(($OPTIND - 1)) if [ -n "$pidfile" ]; then pidfile="-p $pidfile" fi daemon="$1" name="$2" status="0" pidofproc $pidfile $daemon >/dev/null || status="$?" if [ "$status" = 0 ]; then log_success_msg "$name is running" return 0 elif [ "$status" = 4 ]; then log_failure_msg "could not access PID file for $name" return $status else log_failure_msg "$name is not running" return $status fi } fi # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile $PIDFILE $DAEMON_USERGROUP --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE $DAEMON_USERGROUP --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. TIMEOUT=5 while [ $TIMEOUT -gt 0 ] && ! do_check; do sleep 1 TIMEOUT=$((TIMEOUT-1)) done do_check return $? } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE $DAEMON_USERGROUP --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 $DAEMON_USERGROUP --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that checks if daemon is running # do_check() { STATUS=2 # Ubuntu 8.04 does not support "lsof -s "TCP:LISTEN", therefore "grep '(LISTEN)'" is used pidofproc -p $PIDFILE $DAEMON >/dev/null && lsof -i "TCP:${NETWORK_PORT}" | grep --quiet '(LISTEN)' && STATUS=0 return $STATUS } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; reload|force-reload) # # If do_reload() is not implemented then leave this commented out # and leave 'force-reload' as an alias for 'restart'. # log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2 exit 3 ;; esac : bareos-Release-14.2.6/debian/bareos-filedaemon.install.in000066400000000000000000000002031263011562700232260ustar00rootroot00000000000000@sysconfdir@/bareos-fd.conf @configtemplatedir@ /usr/sbin/bareos-fd @plugindir@/bpipe-fd.so /usr/share/man/man8/bareos-fd.8.gz bareos-Release-14.2.6/debian/bareos-filedaemon.postinst.in000066400000000000000000000031561263011562700234550ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos #director_daemon_user=$daemon_user #storage_daemon_user=$daemon_user file_daemon_user=root #storage_daemon_group=$daemon_group DEFCONFIGDIR="@configtemplatedir@" CONFIG="bareos-fd.conf" TARGET="/etc/bareos/${CONFIG}" permissions() { chown ${file_daemon_user}:${daemon_group} $TARGET chmod 640 $TARGET } case "$1" in configure) if [ ! -f "$TARGET" ]; then cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET} /usr/lib/bareos/scripts/bareos-config initialize_local_hostname /usr/lib/bareos/scripts/bareos-config initialize_passwords else cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET}.dist fi permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-filedaemon.postrm000066400000000000000000000003711263011562700225050ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/bareos-fd.conf /etc/bareos/bareos-fd.conf.dist ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-filedaemon.preinst.in000066400000000000000000000027431263011562700232570ustar00rootroot00000000000000#!/bin/sh # preinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_group=@dir_group@ daemon_user=@dir_user@ WORKING_DIR="@working_dir@" create_group() { [ -z "$1" ] && return # creating group if he isn't already there. # use addgroup instead of groupadd, # because "addgroup" uses the next available number, # while "groupadd" uses uses GID_MIN -1 (999) getent group $1 > /dev/null || addgroup -q --system $1 } create_user() { [ -z "$1" ] && return # creating user if he isn't already there. # use adduser instead of useradd, # because "adduser" uses the next available number, # while "useradd" uses uses UID_MIN -1 (999) getent passwd $1 > /dev/null || adduser -q --system --ingroup $daemon_group --home "$WORKING_DIR" --no-create-home --gecos "$1" $1 } case "$1" in install|upgrade) create_group ${daemon_group} create_user ${daemon_user} ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-filedaemon.prerm000066400000000000000000000015651263011562700223140ustar00rootroot00000000000000#!/bin/sh # prerm script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in remove|deconfigure) ;; failed-upgrade|upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-storage-fifo.install.in000066400000000000000000000001131263011562700235100ustar00rootroot00000000000000/etc/bareos/bareos-sd.d/device-fifo.conf @backenddir@/libbareossd-fifo*.so bareos-Release-14.2.6/debian/bareos-storage-fifo.postinst.in000066400000000000000000000021261263011562700237330ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos permissions() { chown root:${daemon_group} /etc/bareos/bareos-sd.d/device-fifo.conf } case "$1" in configure) permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-storage-python-plugin.install.in000066400000000000000000000001241263011562700254040ustar00rootroot00000000000000@plugindir@/python-sd.so @plugindir@/bareos-sd.py* @plugindir@/bareos_sd_consts.py* bareos-Release-14.2.6/debian/bareos-storage-tape.install.in000066400000000000000000000004041263011562700235210ustar00rootroot00000000000000/etc/bareos/mtx-changer.conf /etc/bareos/bareos-sd.d/device-tape-with-autoloader.conf @backenddir@/libbareossd-gentape*.so @backenddir@/libbareossd-tape*.so @plugindir@/scsitapealert-sd.so @scriptdir@/mtx-changer /usr/share/man/man8/btape.8.gz /usr/sbin/btape bareos-Release-14.2.6/debian/bareos-storage-tape.postinst.in000066400000000000000000000021461263011562700237430ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos permissions() { chown root:${daemon_group} /etc/bareos/bareos-sd.d/device-tape-with-autoloader.conf } case "$1" in configure) permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-storage.bareos-sd.init.in000077500000000000000000000133131263011562700237530ustar00rootroot00000000000000#! /bin/sh ### BEGIN INIT INFO # Provides: bareos-sd # Required-Start: $network $remote_fs $time $syslog # Required-Stop: $network $remote_fs $time $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Bareos Storage Daemon # Description: Bareos is a network backup and restore program. # The Bareos Storage Daemon read and writes data to the storage devices. ### END INIT INFO DESC="Bareos Storage Daemon" NAME=bareos-sd NETWORK_PORT=@sd_port@ DAEMON_USER=@sd_user@ DAEMON_GROUP=@sd_group@ DAEMON=/usr/sbin/$NAME if [ "x${DAEMON_USER}" != "x" ]; then DAEMON_USERGROUP="--chuid ${DAEMON_USER}" if [ "x${DAEMON_GROUP}" != "x" ]; then DAEMON_USERGROUP="${DAEMON_USERGROUP}:${DAEMON_GROUP}" fi fi DAEMON_ARGS= PIDFILE=@piddir@/${NAME}.${NETWORK_PORT}.pid SCRIPTNAME=/etc/init.d/$NAME PATH=/sbin:/usr/sbin:/bin:/usr/bin # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # workaround, if status_of_proc is not defined (Ubuntu 8.04) if ! type status_of_proc >/dev/null; then status_of_proc () { local pidfile daemon name status OPTIND pidfile= OPTIND=1 while getopts p: opt ; do case "$opt" in p) pidfile="$OPTARG";; esac done shift $(($OPTIND - 1)) if [ -n "$pidfile" ]; then pidfile="-p $pidfile" fi daemon="$1" name="$2" status="0" pidofproc $pidfile $daemon >/dev/null || status="$?" if [ "$status" = 0 ]; then log_success_msg "$name is running" return 0 elif [ "$status" = 4 ]; then log_failure_msg "could not access PID file for $name" return $status else log_failure_msg "$name is not running" return $status fi } fi # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile $PIDFILE $DAEMON_USERGROUP --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE $DAEMON_USERGROUP --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. TIMEOUT=5 while [ $TIMEOUT -gt 0 ] && ! do_check; do sleep 1 TIMEOUT=$((TIMEOUT-1)) done do_check return $? } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE $DAEMON_USERGROUP --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 $DAEMON_USERGROUP --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that checks if daemon is running # do_check() { STATUS=2 # Ubuntu 8.04 does not support "lsof -s "TCP:LISTEN", therefore "grep '(LISTEN)'" is used pidofproc -p $PIDFILE $DAEMON >/dev/null && lsof -i "TCP:${NETWORK_PORT}" | grep --quiet '(LISTEN)' && STATUS=0 return $STATUS } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; reload|force-reload) # # If do_reload() is not implemented then leave this commented out # and leave 'force-reload' as an alias for 'restart'. # log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2 exit 3 ;; esac : bareos-Release-14.2.6/debian/bareos-storage.dirs000066400000000000000000000000601263011562700214560ustar00rootroot00000000000000/etc/bareos/bareos-sd.d /var/lib/bareos/storage bareos-Release-14.2.6/debian/bareos-storage.install.in000066400000000000000000000003261263011562700225750ustar00rootroot00000000000000/usr/sbin/bscrypto @plugindir@/scsicrypto-sd.so @scriptdir@/disk-changer @sysconfdir@/bareos-sd.conf @configtemplatedir@ /usr/sbin/bareos-sd /usr/share/man/man8/bscrypto.8.gz /usr/share/man/man8/bareos-sd.8.gz bareos-Release-14.2.6/debian/bareos-storage.postinst.in000066400000000000000000000034731263011562700230200ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos #director_daemon_user=$daemon_user storage_daemon_user=$daemon_user #file_daemon_user=root storage_daemon_group=$daemon_group DEFCONFIGDIR="@configtemplatedir@" CONFIG="bareos-sd.conf" TARGET="/etc/bareos/${CONFIG}" permissions() { chown ${storage_daemon_user}:${daemon_group} $TARGET chown ${storage_daemon_user}:${daemon_group} /etc/bareos/bareos-sd.d chown ${storage_daemon_user}:${daemon_group} /var/lib/bareos/storage/ chmod 640 $TARGET } case "$1" in configure) if [ ! -f "$TARGET" ]; then cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET} /usr/lib/bareos/scripts/bareos-config initialize_local_hostname /usr/lib/bareos/scripts/bareos-config initialize_passwords else cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET}.dist fi permissions /usr/lib/bareos/scripts/bareos-config setup_sd_user ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-storage.postrm000066400000000000000000000003711263011562700220460ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/bareos-sd.conf /etc/bareos/bareos-sd.conf.dist ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-storage.preinst.in000066400000000000000000000027431263011562700226200ustar00rootroot00000000000000#!/bin/sh # preinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_group=@dir_group@ daemon_user=@dir_user@ WORKING_DIR="@working_dir@" create_group() { [ -z "$1" ] && return # creating group if he isn't already there. # use addgroup instead of groupadd, # because "addgroup" uses the next available number, # while "groupadd" uses uses GID_MIN -1 (999) getent group $1 > /dev/null || addgroup -q --system $1 } create_user() { [ -z "$1" ] && return # creating user if he isn't already there. # use adduser instead of useradd, # because "adduser" uses the next available number, # while "useradd" uses uses UID_MIN -1 (999) getent passwd $1 > /dev/null || adduser -q --system --ingroup $daemon_group --home "$WORKING_DIR" --no-create-home --gecos "$1" $1 } case "$1" in install|upgrade) create_group ${daemon_group} create_user ${daemon_user} ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-storage.prerm000066400000000000000000000023411263011562700216460ustar00rootroot00000000000000#!/bin/sh # prerm script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in remove|deconfigure) # stop only on deinstall. Restart on upgrade must be done manually if [ -x "/etc/init.d/bareos-sd" ]; then if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then invoke-rc.d bareos-sd stop || exit $? else /etc/init.d/bareos-sd stop || exit $? fi fi ;; failed-upgrade|upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-tools.install.in000066400000000000000000000005051263011562700222700ustar00rootroot00000000000000/usr/bin/bregex /usr/bin/bwild /usr/sbin/bcopy /usr/sbin/bextract /usr/sbin/bls /usr/sbin/bregex /usr/sbin/bwild /usr/sbin/bpluginfo /usr/share/man/man1/bwild.1.gz /usr/share/man/man1/bregex.1.gz /usr/share/man/man8/bcopy.8.gz /usr/share/man/man8/bextract.8.gz /usr/share/man/man8/bls.8.gz /usr/share/man/man8/bpluginfo.8.gz bareos-Release-14.2.6/debian/bareos-traymonitor.install.in000066400000000000000000000004141263011562700235160ustar00rootroot00000000000000/etc/xdg/autostart/bareos-tray-monitor.desktop @sysconfdir@/tray-monitor.conf @configtemplatedir@ /usr/bin/bareos-tray-monitor /usr/share/man/man1/bareos-tray-monitor.1.gz /usr/share/applications/bareos-tray-monitor.desktop /usr/share/pixmaps/bareos-tray-monitor.xpm bareos-Release-14.2.6/debian/bareos-traymonitor.postinst.in000066400000000000000000000027471263011562700237460ustar00rootroot00000000000000#!/bin/sh # postinst script for bareos # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-remove' # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package daemon_user=bareos daemon_group=bareos DEFCONFIGDIR="@configtemplatedir@" CONFIG="tray-monitor.conf" TARGET="/etc/bareos/${CONFIG}" permissions() { chown root:${daemon_group} $TARGET chmod 640 $TARGET } case "$1" in configure) if [ ! -f "$TARGET" ]; then cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET} /usr/lib/bareos/scripts/bareos-config initialize_local_hostname /usr/lib/bareos/scripts/bareos-config initialize_passwords else cat ${DEFCONFIGDIR}/${CONFIG} > ${TARGET}.dist fi permissions ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/bareos-traymonitor.postrm000066400000000000000000000003771263011562700227770ustar00rootroot00000000000000#! /bin/sh set -e case "$1" in purge) rm -f /etc/bareos/tray-monitor.conf /etc/bareos/tray-monitor.conf.dist ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/compat000066400000000000000000000000021263011562700170600ustar00rootroot000000000000007 bareos-Release-14.2.6/debian/control000066400000000000000000000365621263011562700173010ustar00rootroot00000000000000# # when using # configure --enable-dynamic-debian-package-list # the file debian/control will be generated (overwritten) # from configure by the template debian/control.in. # While this makes building more flexible, # it does not comply with Debian Packaging Policy. # Therefore when building packages for Debian.org, # the statical debian/control will be used. # Source: bareos Section: admin Priority: optional Maintainer: Joerg Steffens Build-Depends: acl-dev, autotools-dev, bc, chrpath, debhelper (>= 7.0.50~), dpkg-dev (>= 1.13.19), libacl1-dev, libcap-dev, liblzo2-dev, libqt4-dev, libreadline-dev, libssl-dev, libwrap0-dev, libx11-dev, libsqlite3-dev, libmysqlclient-dev, libpq-dev, lsb-release, mtx, ncurses-dev, pkg-config, po-debconf (>= 0.8.2), python-dev, zlib1g-dev # libfastlz-dev: # installed in OBS via dsc file, # not part of Debian/Ubuntu. # Debian (not Ubuntu): # libsqlite0-dev, # libjconv-dev, # univention: # ucslint, univention-config-dev Build-Conflicts: python2.2-dev, python2.3, python2.4, qt3-dev-tools Standards-Version: 3.9.6 Vcs-Git: git://github.com/bareos/bareos.git -b bareos-14.2 Vcs-Browser: https://github.com/bareos/bareos/tree/bareos-14.2 Homepage: http://www.bareos.org/ Package: bareos Architecture: any Depends: bareos-director (= ${binary:Version}), bareos-storage (= ${binary:Version}), bareos-client (= ${binary:Version}), ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - metapackage Bareos is a set of programs to manage backup, recovery and verification of computer data across a network of computers of different kinds. . It is efficient and relatively easy to use, while offering many advanced storage management features that make it easy to find and recover lost or damaged files. Due to its modular design, Bareos is scalable from small single computer systems to networks of hundreds of machines. . This metapackage installs the entire suite of Bareos applications: job scheduling, storage control, node connector, and administrative console. Package: bareos-bconsole Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-console Replaces: bacula-console Description: Backup Archiving Recovery Open Sourced - text console Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The management console allows the administrator or user to communicate with the Bareos Director. . This package provides the text-interface version of the console. Package: bareos-client Architecture: any Depends: bareos-bconsole (>= ${binary:Version}), bareos-filedaemon (>= ${binary:Version}), ${misc:Depends} Recommends: bareos-traymonitor Description: Backup Archiving Recovery Open Sourced - client metapackage Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The package is a metapackage for client installations (file daemon and console). Package: bareos-common Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: openssl, ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-director-common, bacula-common Description: Backup Archiving Recovery Open Sourced - common files Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides files that are useful for other Bareos packages. Package: bareos-database-common Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), bareos-database-postgresql (= ${binary:Version}) | bareos-database-mysql (= ${binary:Version}) | bareos-database-sqlite3 (= ${binary:Version}), dbconfig-common, lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - common catalog files Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides generic abstraction libs and files to connect the Bareos Director daemon to a database. Package: bareos-database-postgresql Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: lsb-base (>= 3.2-13), postgresql-client, ${shlibs:Depends}, ${misc:Depends} Suggests: postgresql Description: Backup Archiving Recovery Open Sourced - PostgreSQL backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the functionality to connect the Bareos Director daemon to a PostgreSQL database. Package: bareos-database-mysql Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Suggests: mysql-server Description: Backup Archiving Recovery Open Sourced - MySQL backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the functionality to connect the Bareos Director daemon to a MySQL database. Package: bareos-database-sqlite3 Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: sqlite3, lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - SQLite backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the functionality to connect the Bareos Director daemon to a SQLite database. Package: bareos-database-tools Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), bareos-database-common (= ${binary:Version}), lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-sd-mysql, bacula-sd-pgsql, bacula-sd-sqlite3 Description: Backup Archiving Recovery Open Sourced - database tools Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides tools that requires access to the Bareos database. Package: bareos-dbg Architecture: any Section: debug Priority: extra Depends: bareos-storage (= ${binary:Version}) | bareos-bconsole (= ${binary:Version}) | bareos-common (= ${binary:Version}) | bareos-database-common (= ${binary:Version}) | bareos-database-mysql (= ${binary:Version}) | bareos-database-postgresql (= ${binary:Version}) | bareos-database-sqlite3 (= ${binary:Version}) | bareos-database-tools (= ${binary:Version}) | bareos-director (= ${binary:Version}) | bareos-filedaemon (= ${binary:Version}) | bareos-storage (= ${binary:Version}) | bareos-storage-tape (= ${binary:Version}) | bareos-storage-fifo (= ${binary:Version}) | bareos-tools (= ${binary:Version}), ${misc:Depends} Conflicts: bacula-sd-dbg, bacula-sd-mysql-dbg, bacula-sd-pgsql-dbg, bacula-sd-sqlite3-dbg Description: Backup Archiving Recovery Open Sourced - debugging symbols Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides debugging symbols for Bareos. Package: bareos-devel Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - development files Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides additonal files for develop against Bareos. Package: bareos-director Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), bareos-database-common (= ${binary:Version}), bareos-database-tools, lsb-base (>= 3.2-13), lsof, bsd-mailx | mailx, ${shlibs:Depends}, ${misc:Depends} Recommends: logrotate Conflicts: bacula-director Replaces: bacula-director Description: Backup Archiving Recovery Open Sourced - director daemon Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The Bareos Director service supervises all the backup, restore, verify and archive operations. It can run as a daemon or as a foreground service which administrators can use to schedule backups and recover files. . This package contains the Bareos Director daemon. Package: bareos-filedaemon Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), lsb-base (>= 3.2-13), lsof, ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-fd Replaces: bacula-fd Description: Backup Archiving Recovery Open Sourced - file daemon Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The file daemon has to be installed on the machine to be backed up. It is responsible for providing the file attributes and data when requested by the Director, and also for the file system-dependent part of restoration. . This package contains the Bareos File daemon. Package: bareos-storage Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), lsb-base (>= 3.2-13), lsof, ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-sd Replaces: bacula-sd Description: Backup Archiving Recovery Open Sourced - storage daemon Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The storage daemon performs the storage and recovery of the file attributes and data to the physical media; in other words, it is responsible for reading and writing the backups. . It runs on the machine which has access to the backup device(s) - usually a tape drive, but alternatively other storage media, such as files. Package: bareos-storage-fifo Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), bareos-storage (= ${binary:Version}), lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - storage daemon FIFO backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package contains the Storage backend for FIFO files. This package is only required, when a resource "Archive Device = fifo" should be used by the Bareos Storage Daemon. Package: bareos-storage-tape Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), bareos-storage (= ${binary:Version}), lsb-base (>= 3.2-13), mtx, ${shlibs:Depends}, ${misc:Depends} Recommends: mt-st Suggests: scsitools, sg3-utils Description: Backup Archiving Recovery Open Sourced - storage daemon tape support Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The storage daemon performs the storage and recovery of the file attributes and data to the physical media; in other words, it is responsible for reading and writing the backups. . It runs on the machine which has access to the backup device(s) - usually a tape drive, but alternatively other storage media, such as files. . This adds the tape specific support files for the storage daemon. Package: bareos-tools Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-sd, bacula-sd-mysql, bacula-sd-pgsql, bacula-sd-sqlite3 Description: Backup Archiving Recovery Open Sourced - common tools Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides some additional tools, mostly to work directly with Bareos storage volumes. Package: bareos-bat Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Suggests: kde|gnome-desktop-environment Conflicts: bacula-console-qt Replaces: bacula-console-qt Description: Backup Archiving Recovery Open Sourced - Bareos Admin Tool (BAT) Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . It is efficient and relatively easy to use, while offering many advanced storage management features that make it easy to find and recover lost or damaged files. Due to its modular design, Bareos is scalable from small single computer systems to networks of hundreds of machines. . Bareos Admin Tool (BAT), a graphical interface for Bareos. Package: bareos-director-python-plugin Architecture: any Section: python Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - director-python-plugin Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the Python plugin for the director. Package: bareos-filedaemon-python-plugin Architecture: any Section: python Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - filedaemon-python-plugin Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the Python plugin for the filedaemon. Package: bareos-storage-python-plugin Architecture: any Section: python Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - storage-python-plugin Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the Python plugin for the storage daemon. Package: bareos-traymonitor Architecture: any Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Suggests: kde|gnome-desktop-environment Conflicts: bacula-traymonitor Replaces: bacula-traymonitor Description: Backup Archiving Recovery Open Sourced - tray monitor Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides a tray monitor for the Bareos backup system. It is FreeDesktop-compatible, which means it will work under both KDE and GNOME. . The monitor constantly displays Bareos's status. bareos-Release-14.2.6/debian/control.bareos-bat000066400000000000000000000015331263011562700213050ustar00rootroot00000000000000Package: bareos-bat Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Suggests: kde|gnome-desktop-environment Conflicts: bacula-console-qt Replaces: bacula-console-qt Description: Backup Archiving Recovery Open Sourced - Bareos Admin Tool (BAT) Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . It is efficient and relatively easy to use, while offering many advanced storage management features that make it easy to find and recover lost or damaged files. Due to its modular design, Bareos is scalable from small single computer systems to networks of hundreds of machines. . Bareos Admin Tool (BAT), a graphical interface for Bareos. bareos-Release-14.2.6/debian/control.bareos-director-python-plugin000066400000000000000000000007621263011562700251700ustar00rootroot00000000000000Package: bareos-director-python-plugin Architecture: any Section: python Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - director-python-plugin Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the Python plugin for the director. bareos-Release-14.2.6/debian/control.bareos-filedaemon-python-plugin000066400000000000000000000007701263011562700254570ustar00rootroot00000000000000Package: bareos-filedaemon-python-plugin Architecture: any Section: python Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - filedaemon-python-plugin Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the Python plugin for the filedaemon. bareos-Release-14.2.6/debian/control.bareos-storage-python-plugin000066400000000000000000000007661263011562700250250ustar00rootroot00000000000000Package: bareos-storage-python-plugin Architecture: any Section: python Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - storage-python-plugin Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the Python plugin for the storage daemon. bareos-Release-14.2.6/debian/control.bareos-traymonitor000066400000000000000000000012311263011562700231210ustar00rootroot00000000000000Package: bareos-traymonitor Architecture: any Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Suggests: kde|gnome-desktop-environment Conflicts: bacula-traymonitor Replaces: bacula-traymonitor Description: Backup Archiving Recovery Open Sourced - tray monitor Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides a tray monitor for the Bareos backup system. It is FreeDesktop-compatible, which means it will work under both KDE and GNOME. . The monitor constantly displays Bareos's status. bareos-Release-14.2.6/debian/control.in000066400000000000000000000311251263011562700176740ustar00rootroot00000000000000# # when using # configure --enable-dynamic-debian-package-list # the file debian/control will be generated (overwritten) # from configure by the template debian/control.in. # While this makes building more flexible, # it does not comply with Debian Packaging Policy. # Therefore when building packages for Debian.org, # the statical debian/control will be used. # Source: bareos Section: admin Priority: optional Maintainer: Joerg Steffens Build-Depends: acl-dev, autotools-dev, bc, chrpath, debhelper (>= 7.0.50~), dpkg-dev (>= 1.13.19), libacl1-dev, libcap-dev, libfastlz-dev, liblzo2-dev, libqt4-dev, libreadline-dev, libssl-dev, libwrap0-dev, libx11-dev, libsqlite3-dev, libmysqlclient-dev, libpq-dev, lsb-release, mtx, ncurses-dev, pkg-config, po-debconf (>= 0.8.2), python-dev, zlib1g-dev # Debian (not Ubuntu): # libsqlite0-dev, # libjconv-dev, # univention: # ucslint, univention-config-dev Build-Conflicts: python2.2-dev, python2.3, python2.4, qt3-dev-tools Standards-Version: 3.9.6 Vcs-Git: git://github.com/bareos/bareos.git -b bareos-14.2 Vcs-Browser: https://github.com/bareos/bareos/tree/bareos-14.2 Homepage: http://www.bareos.org/ Package: bareos Architecture: any Depends: bareos-director (= ${binary:Version}), bareos-storage (= ${binary:Version}), bareos-client (= ${binary:Version}), ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - metapackage Bareos is a set of programs to manage backup, recovery and verification of computer data across a network of computers of different kinds. . It is efficient and relatively easy to use, while offering many advanced storage management features that make it easy to find and recover lost or damaged files. Due to its modular design, Bareos is scalable from small single computer systems to networks of hundreds of machines. . This metapackage installs the entire suite of Bareos applications: job scheduling, storage control, node connector, and administrative console. Package: bareos-bconsole Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-console Replaces: bacula-console Description: Backup Archiving Recovery Open Sourced - text console Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The management console allows the administrator or user to communicate with the Bareos Director. . This package provides the text-interface version of the console. Package: bareos-client Architecture: any Depends: bareos-bconsole (>= ${binary:Version}), bareos-filedaemon (>= ${binary:Version}), ${misc:Depends} Recommends: bareos-traymonitor Description: Backup Archiving Recovery Open Sourced - client metapackage Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The package is a metapackage for client installations (file daemon and console). Package: bareos-common Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: openssl, ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-director-common, bacula-common Description: Backup Archiving Recovery Open Sourced - common files Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides files that are useful for other Bareos packages. Package: bareos-database-common Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), bareos-database-postgresql (= ${binary:Version}) | bareos-database-mysql (= ${binary:Version}) | bareos-database-sqlite3 (= ${binary:Version}), dbconfig-common, lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - common catalog files Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides generic abstraction libs and files to connect the Bareos Director daemon to a database. Package: bareos-database-postgresql Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: lsb-base (>= 3.2-13), postgresql-client, ${shlibs:Depends}, ${misc:Depends} Suggests: postgresql Description: Backup Archiving Recovery Open Sourced - PostgreSQL backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the functionality to connect the Bareos Director daemon to a PostgreSQL database. Package: bareos-database-mysql Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Suggests: mysql-server Description: Backup Archiving Recovery Open Sourced - MySQL backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the functionality to connect the Bareos Director daemon to a MySQL database. Package: bareos-database-sqlite3 Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: sqlite3, lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - SQLite backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides the functionality to connect the Bareos Director daemon to a SQLite database. Package: bareos-database-tools Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), bareos-database-common (= ${binary:Version}), lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-sd-mysql, bacula-sd-pgsql, bacula-sd-sqlite3 Description: Backup Archiving Recovery Open Sourced - database tools Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides tools that requires access to the Bareos database. Package: bareos-dbg Architecture: any Section: debug Priority: extra Depends: bareos-storage (= ${binary:Version}) | bareos-bconsole (= ${binary:Version}) | bareos-common (= ${binary:Version}) | bareos-database-common (= ${binary:Version}) | bareos-database-mysql (= ${binary:Version}) | bareos-database-postgresql (= ${binary:Version}) | bareos-database-sqlite3 (= ${binary:Version}) | bareos-database-tools (= ${binary:Version}) | bareos-director (= ${binary:Version}) | bareos-filedaemon (= ${binary:Version}) | bareos-storage (= ${binary:Version}) | bareos-storage-tape (= ${binary:Version}) | bareos-storage-fifo (= ${binary:Version}) | bareos-tools (= ${binary:Version}), ${misc:Depends} Conflicts: bacula-sd-dbg, bacula-sd-mysql-dbg, bacula-sd-pgsql-dbg, bacula-sd-sqlite3-dbg Description: Backup Archiving Recovery Open Sourced - debugging symbols Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides debugging symbols for Bareos. Package: bareos-devel Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - development files Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides additonal files for develop against Bareos. Package: bareos-director Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), bareos-database-common (= ${binary:Version}), bareos-database-tools, lsb-base (>= 3.2-13), lsof, bsd-mailx | mailx, ${shlibs:Depends}, ${misc:Depends} Recommends: logrotate Conflicts: bacula-director Replaces: bacula-director Description: Backup Archiving Recovery Open Sourced - director daemon Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The Bareos Director service supervises all the backup, restore, verify and archive operations. It can run as a daemon or as a foreground service which administrators can use to schedule backups and recover files. . This package contains the Bareos Director daemon. Package: bareos-filedaemon Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), lsb-base (>= 3.2-13), lsof, ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-fd Replaces: bacula-fd Description: Backup Archiving Recovery Open Sourced - file daemon Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The file daemon has to be installed on the machine to be backed up. It is responsible for providing the file attributes and data when requested by the Director, and also for the file system-dependent part of restoration. . This package contains the Bareos File daemon. Package: bareos-storage Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), lsb-base (>= 3.2-13), lsof, ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-sd Replaces: bacula-sd Description: Backup Archiving Recovery Open Sourced - storage daemon Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The storage daemon performs the storage and recovery of the file attributes and data to the physical media; in other words, it is responsible for reading and writing the backups. . It runs on the machine which has access to the backup device(s) - usually a tape drive, but alternatively other storage media, such as files. Package: bareos-storage-fifo Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), bareos-storage (= ${binary:Version}), lsb-base (>= 3.2-13), ${shlibs:Depends}, ${misc:Depends} Description: Backup Archiving Recovery Open Sourced - storage daemon FIFO backend Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package contains the Storage backend for FIFO files. This package is only required, when a resource "Archive Device = fifo" should be used by the Bareos Storage Daemon. Package: bareos-storage-tape Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0, adduser Depends: bareos-common (= ${binary:Version}), bareos-storage (= ${binary:Version}), lsb-base (>= 3.2-13), mtx, ${shlibs:Depends}, ${misc:Depends} Recommends: mt-st Suggests: scsitools, sg3-utils Description: Backup Archiving Recovery Open Sourced - storage daemon tape support Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . The storage daemon performs the storage and recovery of the file attributes and data to the physical media; in other words, it is responsible for reading and writing the backups. . It runs on the machine which has access to the backup device(s) - usually a tape drive, but alternatively other storage media, such as files. . This adds the tape specific support files for the storage daemon. Package: bareos-tools Architecture: any Pre-Depends: debconf (>= 1.4.30) | debconf-2.0 Depends: bareos-common (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Conflicts: bacula-sd, bacula-sd-mysql, bacula-sd-pgsql, bacula-sd-sqlite3 Description: Backup Archiving Recovery Open Sourced - common tools Bareos is a set of programs to manage backup, recovery and verification of data across a network of computers of different kinds. . This package provides some additional tools, mostly to work directly with Bareos storage volumes. @DEBIAN_CONTROL_BAT@ @DEBIAN_CONTROL_DIRECTOR_PYTHON_PLUGIN@ @DEBIAN_CONTROL_FILEDAEMON_PYTHON_PLUGIN@ @DEBIAN_CONTROL_STORAGE_PYTHON_PLUGIN@ @DEBIAN_CONTROL_TRAYMONITOR@ @DEBIAN_CONTROL_UNIVENTION_BAREOS@ @DEBIAN_CONTROL_UNIVENTION_BAREOS_SCHEMA@ bareos-Release-14.2.6/debian/control.univention-bareos000066400000000000000000000010251263011562700227310ustar00rootroot00000000000000Package: univention-bareos Architecture: all Depends: univention-postgresql, postgresql-8.4, bareos (>= 12.4.4), bareos-database-common, bareos-database-postgresql, dbconfig-common, bareos-database-tools, univention-join (>> 5.0.20-1.436), shell-univention-lib (>> 2.0.17-1.125), univention-config Description: meta package for univention-bareos-integration This package integrates the bareos backup solution into UCS. The package provides automatic configuration of the bareos director, local file daemon and storage daemon. bareos-Release-14.2.6/debian/control.univention-bareos-schema000066400000000000000000000005441263011562700241740ustar00rootroot00000000000000Package: univention-bareos-schema Architecture: all Depends: shell-univention-lib (>> 2.0.17-1.125) Breaks: univention-ldap-server (<< 9.0.20-1.580.201303211526) Description: LDAP schema extension for Bareos This package provides the LDAP schema extension which enables the backup configuration for client systems from the Univention Management Console bareos-Release-14.2.6/debian/copyright000066400000000000000000002111721263011562700176210ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Bareos Upstream-Contact: Source: https://github.com/bareos/bareos Comment: BAREOS is a fork of the Bacula source code. The original Bacula code was Copyright Kern Sibbald and John Walker. After November 2004, it became Copyright Kern Sibbald, and finally, the copyright was transferred to the Free Software Foundation Europe on 15 November 2006. The license was changed from GPLv2 to AGPLv3 on 24 July 2010. The name Bacula is a registered trademark of Kern Sibbald. The name BAREOS is a registered trademark of Bareos GmbH & Co. KG Files: * Copyright: 2000-2012 Free Software Foundation Europe e.V. 2011-2012 Planets Communications B.V. 2013-2014 Bareos GmbH & Co. KG License: AGPL-3.0 with Bacula and other exceptions This section is the reformated version of `/usr/share/doc/bareos-common/LICENSE'. . BAREOS is a fork of the Bacula source code. Please find below (1) our license information, (2) the preexisting license information of Bacula (from 06/05/2013, i.e. the date the source was forked into BAREOS), and (3) the license text of the AGPLv3. Our license information (1) is applicable to all changes to the preexisting code of Bacula. . 1. . BAREOS LICENSE SPECIFICS . The following license terms apply to the BAREOS code: . Trademark: . The name BAREOS is a registered trademark of Bareos GmbH & Co. KG . Bareos is licensed under the AGPL version 3 (see 3. below). Some parts of the code are licensed under permissive licenses: . a) For the native NDMP support we imported some BSD 2 clause code which has the following copyright: . /* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ . b) Furthermore we included code from src/lib/bmtio.h which has the following copyright: . /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)mtio.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: stable/7/sys/sys/mtio.h 139825 2005-01-07 02:29:27Z imp $ */ . c) Furthermore we included the LMDB code from the OpenLDAP project which has the following copyright: . The OpenLDAP Public License Version 2.8, 17 August 2003 . Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions in source form must retain copyright statements and notices, . 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and . 3. Redistributions must contain a verbatim copy of this document. . The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. . THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED 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 OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE 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 names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. . OpenLDAP is a registered trademark of the OpenLDAP Foundation. . Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. . The new source header doesn't include a reference to the AUTHORS file in each source file but we still maintain the AUTHORS file with all authors of the orignal project ("Bacula") and any new authors for code submitted to the BAREOS project.The AUTHORS file can be found in the main directory. . d) Files: src/lib/sha1.h src/lib/sha1.c Copyright: Steve Reid License: public-domain replaced the SHA licensed implementation (Copyright: 2001 The Internet Society), mentioned later in this document. . e) Bareos can be compiled with data compression and decompression using the fastlzlib library. (see git://github.com/exalead/fastlzlib.git) The following licenses (LICENSE, LICENSE-FASTLZ and LICENSE-LZ4) apply to the fastlzlib and its components: . == LICENSE == . zlib-like interface to fast block compression (LZ4 or FastLZ) libraries Copyright (C) 2013 Exalead SA. (http://www.exalead.com/) . 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. . Remarks/Bugs: LZ4 compression library by Yann Collet (yann.collet.73@gmail.com) FastLZ compression library by Ariya Hidayat (ariya@kde.org) Library encapsulation by Xavier Roche (fastlz@exalead.com) . . == LICENSE-FASTLZ == . FastLZ - lightning-fast lossless compression library . Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) . 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. . . == LICENSE-LZ4 == . LZ4 - Fast LZ compression algorithm Header File Copyright (C) 2011-2012, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) . Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. . You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ . =========================================== . 2. . History: The original Bacula code was Copyright Kern Sibbald and John Walker. After November 2004, it became Copyright Kern Sibbald, and finally, the copyright was transferred to the Free Software Foundation Europe on 15 November 2006. The license was changed from GPLv2 to AGPLv3 on 24 July 2010. . Trademark: The name Bacula is a registered trademark of Kern Sibbald. . =================================== . License: For the most part, Bacula is licensed under the AGPL version 3. This code is listed under Copyright Free Software Foundation Europe e.V. What follows is the addition(s) to the AGPL version 3 license, that applies to code that is copyrighted by the Free Software Foundation Europe e.V. . Linking: As a special exception to the AGPLv3, the Bacula Project gives permission to link the code of its release of Bacula with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Affero General Public License in all respects for all of the code used other than "OpenSSL". . As a special exception to the AGPLv3, the Bacula Project gives permission to link the code of its release of the Bacula Win32 File daemon with the Microsoft supplied Volume Shadow Copy (VSS) libraries and distribute the linked executables. You must obey the GNU General Public License in all respects for all of the code used other than for the Microsoft VSS code, where you must obey their license terms. . The Bacula Project gives permission for plugins with AGPLv3 compatible licenses to be loaded and distributed with the Bacula executables as long as the combined work is distributed under the terms listed in the Bacula LICENSE file. A full list of AGPLv3 compatible licenses can be found at: http://www.fsf.org/licensing/licenses/. If you wish to load or distribute plugins with different licensing terms please contact the Bacula Project at: license@bacula.org . =================================== . . What follows is information from the authors of the code: . License: To the best of our knowledge, all code used in Bacula, which is copyrighted by a third party, has licenses that are compatible with the OpenSSL license, and so given the exception that we have made to the AGPLv3 above, Bacula can be freely linked and distributed with the OpenSSL libraries. . Intellectual Property rights: Recipient understands that although each Contributor to Bacula grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. . Copyrights: Each Contributor to Bacula represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. . Code falling under the above conditions will be marked as follows: . Bacula® - The Network Backup Solution . Copyright (C) 2000-2010 Free Software Foundation Europe e.V. . The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation plus additions that are listed in the file LICENSE. . 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. . Bacula® is a registered trademark of Kern Sibbald. . The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. . . Windows: Certain source code used to build the Windows version of the Bacula File daemon is copyrighted and or trademarked by Microsoft and may contain Microsoft intellectual property (examples: Microsoft VC++, the source to the VSS libraries, the Microsoft C runtime libraries). As such we cannot and do not distribute that software. We are permitted however to distribute Bacula with the necessary Microsoft libraries in binary form. . You may obtain the parts that we cannot distribute as follows. The Microsoft compiler available for purchase, and Microsoft provides a free version of the compiler. The source code and libraries are available for download from Microsoft public Web servers. We have documented in the src/win32 directory the URLs from which we obtained the library source, and how we build the Windows File daemon and many users have succeeded in doing so themselves. Our intention is to respect as closely as possible Open Source practices while maintaining full respect for proprietary and copyrighted code. . GPLv2 or later license: src/tools/bsmtp.c Copyright (C) 1997 Ralf S. Engelschall, All Rights Reserved. (note, bsmtp.c does not use OpenSSL, nor is it used with the code of any other part of Bacula) . 3 clause BSD License notice for inclusion with the binary: src/lib/fnmatch.c * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. src/lib/fnmatch.h * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. . Permissive licenses: src/lib/var.c/h ** OSSP var - Variable Expansion ** Copyright (c) 2001-2002 Ralf S. Engelschall ** Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) . src/lib/bsnprintf.c * Copyright Patrick Powell 1995 . src/bregex.c/h * Copyright (c) 1991 Tatu Ylonen, Espoo, Finland . src/lib/sha1.c/h Copyright (C) The Internet Society (2001). All Rights Reserved. . src/win32/compat/getopt.c "... licensed under IBM copyrights to use the IBM-provided source code in any way he or she deems fit ..." . src/win32/compat/sys/mtio.h (LGPL) Copyright (C) 1996, 1997 Free Software Foundation, Inc. . . Bacula can be enabled with data encryption and/or communications encryption. If this is the case, you will be including OpenSSL code that that contains cryptographic software written by Eric Young (eay@cryptsoft.com) and also software written by Tim Hudson (tjh@cryptsoft.com). . There are parts of Bacula that are licensed under the LGPL so that those files may be used in proprietary code to interface with Bacula. . Finally there are parts of Bacula that are in the public domain. . 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. . . . 3. . GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 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 Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. . The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are 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. . 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. . Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. . A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. . The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. . An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. . 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. . Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. . 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 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 work with which it is combined will remain governed by version 3 of the GNU General Public License. . 14. Revised Versions of this License. . The Free Software Foundation may publish revised and/or new versions of the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details. . You should have received a copy of the GNU Affero General Public License along with this program. If not, see . . Also add information on how to contact you by electronic and paper mail. . If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. . 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 AGPL, see . . =========================================== Files: src/lib/bmtio.h Copyright: 1982,1986,1993 The Regents of the University of California License: permissive /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)mtio.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: stable/7/sys/sys/mtio.h 139825 2005-01-07 02:29:27Z imp $ */ Files: src/lmdb/* Copyright: 2011-2014 Howard Chu, Symas Corp. License: OpenLDAP Files: src/ndmp/md5.h src/ndmp/md5c.c Copyright: 1991,1992, RSA Data Security, Inc. License: permissive Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. . License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. . License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. . RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. . These notices must be retained in any copies of any part of this documentation and/or software. Files: src/ndmp/* Copyright: 1998-2002 Traakan, Inc., Los Altos, CA License: BSD-2-clause /* * Copyright (c) 1998,1999,2000,2001,2002 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ Files: src/lib/bregex.h src/lib/bregex.c Copyright: 1991 Tatu Ylonen, Espoo, Finland 2006-2010 Free Software Foundation Europe e.V. License: permissive and AGPL-3.0 Files: src/lib/bsnprintf.c Copyright: 1995 Patrick Powell 2005-2012 Free Software Foundation Europe e.V. License: permissive and AGPL-3.0 Files: src/tools/bsmtp.c Copyright: 1997 Ralf S. Engelschall 2001-2012 Free Software Foundation Europe e.V. License: GPL-2 Files: src/lib/fnmatch.h src/lib/fnmatch.c Copyright: 1989,1992,1993,1994 The Regents of the University of California License: BSD-3-clause Files: src/lib/md5.h src/lib/md5.c Copyright: 2001 Alexander Peslyak License: public-domain This software was written by Alexander Peslyak in 2001. No copyright is claimed, and the software is hereby placed in the public domain. In case this attempt to disclaim copyright and place the software in the public domain is deemed null and void, then the software is Copyright (c) 2001 Alexander Peslyak and it is hereby released to the general public under the following terms: . Redistribution and use in source and binary forms, with or without modification, are permitted. . There's ABSOLUTELY NO WARRANTY, express or implied. . (This is a heavily cut-down "BSD license".) Files: src/lib/sha1.h src/lib/sha1.c Copyright: Steve Reid License: public-domain This work was put by the author in the public domain. Files: src/lib/var.h src/lib/var.c Copyright: 2001-2002 Ralf S. Engelschall 2001-2002 The OSSP Project (http://www.ossp.org/) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) 2003-2009 Free Software Foundation Europe e.V. License: permissive and AGPL-3.0 Files: src/win32/compat/include/sys/mtio.h Copyright: 1996, 1997 Free Software Foundation, Inc. License: LGPL-2.1+ Files: src/win32/plugins/filed/mssqlvdi-fd.c Copyright: 2010 Zilvinas Krapavickas 2013-2013 Bareos GmbH & Co. KG License: AGPL-3.0 License: AGPL-3.0 The full text of the GNU AFFERO GENERAL PUBLIC LICENSE version 3 can be found in the file `/usr/share/bareos-common/AGPL-3.0.txt'. License: BSD-3-clause * 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. License: LGPL-2.1+ On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/LGPL-2.1'. License: GPL-2 On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. License: OpenLDAP The OpenLDAP Public License Version 2.8, 17 August 2003 . Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions in source form must retain copyright statements and notices, . 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and . 3. Redistributions must contain a verbatim copy of this document. . The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. . THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED 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 OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE 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 names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. . OpenLDAP is a registered trademark of the OpenLDAP Foundation. . Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. License: permissive Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. bareos-Release-14.2.6/debian/copyright.footer000066400000000000000000000262721263011562700211230ustar00rootroot00000000000000 Files: src/lib/bmtio.h Copyright: 1982,1986,1993 The Regents of the University of California License: permissive /*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)mtio.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: stable/7/sys/sys/mtio.h 139825 2005-01-07 02:29:27Z imp $ */ Files: src/lmdb/* Copyright: 2011-2014 Howard Chu, Symas Corp. License: OpenLDAP Files: src/ndmp/md5.h src/ndmp/md5c.c Copyright: 1991,1992, RSA Data Security, Inc. License: permissive Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. . License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. . License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. . RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. . These notices must be retained in any copies of any part of this documentation and/or software. Files: src/ndmp/* Copyright: 1998-2002 Traakan, Inc., Los Altos, CA License: BSD-2-clause /* * Copyright (c) 1998,1999,2000,2001,2002 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ Files: src/lib/bregex.h src/lib/bregex.c Copyright: 1991 Tatu Ylonen, Espoo, Finland 2006-2010 Free Software Foundation Europe e.V. License: permissive and AGPL-3.0 Files: src/lib/bsnprintf.c Copyright: 1995 Patrick Powell 2005-2012 Free Software Foundation Europe e.V. License: permissive and AGPL-3.0 Files: src/tools/bsmtp.c Copyright: 1997 Ralf S. Engelschall 2001-2012 Free Software Foundation Europe e.V. License: GPL-2 Files: src/lib/fnmatch.h src/lib/fnmatch.c Copyright: 1989,1992,1993,1994 The Regents of the University of California License: BSD-3-clause Files: src/lib/md5.h src/lib/md5.c Copyright: 2001 Alexander Peslyak License: public-domain This software was written by Alexander Peslyak in 2001. No copyright is claimed, and the software is hereby placed in the public domain. In case this attempt to disclaim copyright and place the software in the public domain is deemed null and void, then the software is Copyright (c) 2001 Alexander Peslyak and it is hereby released to the general public under the following terms: . Redistribution and use in source and binary forms, with or without modification, are permitted. . There's ABSOLUTELY NO WARRANTY, express or implied. . (This is a heavily cut-down "BSD license".) Files: src/lib/sha1.h src/lib/sha1.c Copyright: Steve Reid License: public-domain This work was put by the author in the public domain. Files: src/lib/var.h src/lib/var.c Copyright: 2001-2002 Ralf S. Engelschall 2001-2002 The OSSP Project (http://www.ossp.org/) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) 2003-2009 Free Software Foundation Europe e.V. License: permissive and AGPL-3.0 Files: src/win32/compat/include/sys/mtio.h Copyright: 1996, 1997 Free Software Foundation, Inc. License: LGPL-2.1+ Files: src/win32/plugins/filed/mssqlvdi-fd.c Copyright: 2010 Zilvinas Krapavickas 2013-2013 Bareos GmbH & Co. KG License: AGPL-3.0 License: AGPL-3.0 The full text of the GNU AFFERO GENERAL PUBLIC LICENSE version 3 can be found in the file `/usr/share/bareos-common/AGPL-3.0.txt'. License: BSD-3-clause * 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. License: LGPL-2.1+ On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/LGPL-2.1'. License: GPL-2 On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. License: OpenLDAP The OpenLDAP Public License Version 2.8, 17 August 2003 . Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions in source form must retain copyright statements and notices, . 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and . 3. Redistributions must contain a verbatim copy of this document. . The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. . THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED 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 OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE 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 names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. . OpenLDAP is a registered trademark of the OpenLDAP Foundation. . Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. License: permissive Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. bareos-Release-14.2.6/debian/copyright.header000066400000000000000000000017011263011562700210430ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Bareos Upstream-Contact: Source: https://github.com/bareos/bareos Comment: BAREOS is a fork of the Bacula source code. The original Bacula code was Copyright Kern Sibbald and John Walker. After November 2004, it became Copyright Kern Sibbald, and finally, the copyright was transferred to the Free Software Foundation Europe on 15 November 2006. The license was changed from GPLv2 to AGPLv3 on 24 July 2010. The name Bacula is a registered trademark of Kern Sibbald. The name BAREOS is a registered trademark of Bareos GmbH & Co. KG Files: * Copyright: 2000-2012 Free Software Foundation Europe e.V. 2011-2012 Planets Communications B.V. 2013-2014 Bareos GmbH & Co. KG License: AGPL-3.0 with Bacula and other exceptions This section is the reformated version of `/usr/share/doc/bareos-common/LICENSE'. . bareos-Release-14.2.6/debian/rules000077500000000000000000000100221263011562700167350ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # # Sample debian/rules that uses debhelper. # # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # # Modified to make a template file for a multi-binary package with separated # build-arch and build-indep targets by Bill Allombert 2001 # Uncomment this to turn on verbose mode. DH_VERBOSE = 1 # This has to be exported to make some magic below work. DH_OPTIONS = -v DAEMON_USER = bareos DAEMON_GROUP = bareos DIRECTOR_DAEMON_USER = $(DAEMON_USER) STORAGE_DAEMON_USER = $(DAEMON_USER) FILE_DAEMON_USER = root STORAGE_DAEMON_GROUP = $(DAEMON_GROUP) define CONFIGURE_COMMON --with-sbin-perm=755 \ --libdir=/usr/lib/bareos \ --sysconfdir=/etc/bareos \ --with-archivedir=/var/lib/bareos/storage \ --with-backenddir=/usr/lib/bareos/backends \ --with-configtemplatedir=/usr/lib/bareos/defaultconfigs \ --with-scriptdir=/usr/lib/bareos/scripts \ --with-plugindir=/usr/lib/bareos/plugins \ --with-working-dir=/var/lib/bareos \ --with-pid-dir=/var/lib/bareos \ --with-bsrdir=/var/lib/bareos \ --with-logdir=/var/log/bareos \ --with-subsys-dir=/var/lock \ --enable-smartalloc \ --disable-conio \ --enable-readline \ --enable-batch-insert \ --enable-dynamic-debian-package-list \ --enable-dynamic-cats-backends \ --enable-dynamic-storage-backends \ --enable-acl \ --enable-xattr \ --enable-scsi-crypto \ --enable-lmdb \ --enable-ndmp \ --enable-ipv6 \ --with-postgresql \ --with-mysql \ --with-sqlite3 \ --with-tcp-wrappers \ --with-openssl \ --with-dir-user=$(DIRECTOR_DAEMON_USER) \ --with-dir-group=$(DAEMON_GROUP) \ --with-sd-user=$(STORAGE_DAEMON_USER) \ --with-sd-group=$(STORAGE_DAEMON_GROUP) \ --with-fd-user=$(FILE_DAEMON_USER) \ --with-fd-group=$(DAEMON_GROUP) \ --with-dir-password="XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX" \ --with-fd-password="XXX_REPLACE_WITH_CLIENT_PASSWORD_XXX" \ --with-sd-password="XXX_REPLACE_WITH_STORAGE_PASSWORD_XXX" \ --with-mon-dir-password="XXX_REPLACE_WITH_DIRECTOR_MONITOR_PASSWORD_XXX" \ --with-mon-fd-password="XXX_REPLACE_WITH_CLIENT_MONITOR_PASSWORD_XXX" \ --with-mon-sd-password="XXX_REPLACE_WITH_STORAGE_MONITOR_PASSWORD_XXX" \ --with-basename="XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX" \ --with-hostname="XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX" \ --enable-includes \ --disable-rpath endef # --docdir="\$(_docdir)/bareos" \ # --htmldir="\$(_docdir)/bareos/html" \ CONFIGURE_CLIENT_ONLY = $(CONFIGURE_COMMON) --enable-client-only CONFIGURE_FULL = $(CONFIGURE_COMMON) --with-python --enable-bat --enable-traymonitor override_dh_auto_configure: if [ "`lsb_release --short --id`" = "Ubuntu" ] && [ "`lsb_release --short --release`" = "8.04" ]; then \ echo "configure common configuration"; \ dh_auto_configure -- $(CONFIGURE_COMMON); \ else \ echo "configure full configuration"; \ dh_auto_configure -- $(CONFIGURE_FULL); \ fi override_dh_fixperms: # all files in /etc/bareos dh_fixperms \ --exclude etc/bareos/ \ --exclude var/lib/bareos/ \ --exclude var/log/bareos/ override_dh_strip: dh_strip --dbg-package=bareos-dbg override_dh_install: chrpath -d $(CURDIR)/debian/tmp/usr/lib/bareos/backends/libbareoscats-mysql* \ $(CURDIR)/debian/tmp/usr/lib/bareos/backends/libbareoscats-postgresql* \ $(CURDIR)/debian/tmp/usr/lib/bareos/backends/libbareoscats-sqlite3* dh_install override_dh_installinit: dh_installinit --package=bareos-director --name=bareos-dir --no-start dh_installinit --package=bareos-storage --name=bareos-sd --no-start dh_installinit --package=bareos-filedaemon --name=bareos-fd override_dh_makeshlibs: dh_makeshlibs -n %: PARALLEL="--parallel"; \ if [ "`lsb_release --short --id`" = "Ubuntu" ] && [ "`lsb_release --short --release`" = "8.04" ]; then PARALLEL=""; fi; \ dh $@ $$PARALLEL gen-debian-copyright: (cd debian; make copyright) bareos-Release-14.2.6/debian/univention-bareos-schema.install.in000066400000000000000000000000751263011562700245660ustar00rootroot00000000000000/usr/share/univention-bareos-schema/univention-bareos.schema bareos-Release-14.2.6/debian/univention-bareos-schema.postinst.in000066400000000000000000000004471263011562700250060ustar00rootroot00000000000000#!/bin/sh . /usr/share/univention-lib/all.sh if [ "$1" = "configure" ]; then ucs_registerLDAPSchema /usr/share/univention-bareos-schema/univention-bareos.schema fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/univention-bareos.config000066400000000000000000000007251263011562700225240ustar00rootroot00000000000000#!/bin/sh # config maintainer script for univention-bareos dbc_dbuser=bareos dbc_dbname=bareos dbc_authmethod_user=ident # source debconf stuff . /usr/share/debconf/confmodule # source dbconfig-common shell library, and call the hook function if [ -f /usr/share/dbconfig-common/dpkg/config.pgsql ]; then . /usr/share/dbconfig-common/dpkg/config.pgsql DEBIAN_FRONTEND=noninteractive;export DEBIAN_FRONTEND dbc_go univention-bareos $@ fi # ... rest of your code ... bareos-Release-14.2.6/debian/univention-bareos.dirs000066400000000000000000000000441263011562700222120ustar00rootroot00000000000000etc/bareos/autogenerated/fd-secrets bareos-Release-14.2.6/debian/univention-bareos.install.in000066400000000000000000000010161263011562700233240ustar00rootroot00000000000000/etc/bareos/autogenerated/clients/generic.template /etc/bareos/autogenerated/clients/windows.template /etc/bareos/autogenerated/fd-configs/generic.template /etc/bareos/autogenerated/fd-configs/windows.template /etc/cron.d/univention-bareos /usr/lib/univention-directory-listener/system/univention-bareos.py /usr/lib/univention-install/62univention-bareos.inst /usr/lib/univention-uninstall/63univention-bareos.uinst /usr/share/dbconfig-common/data/univention-bareos/install/pgsql /usr/share/univention-bareos/restart_director bareos-Release-14.2.6/debian/univention-bareos.postinst.in000066400000000000000000000045101263011562700235430ustar00rootroot00000000000000#!/bin/sh # source debconf stuff . /usr/share/debconf/confmodule . /usr/share/dbconfig-common/dpkg/postinst.pgsql dbc_pgsql_createdb_encoding="SQL_ASCII" dbc_go univention-bareos $@ . /usr/share/univention-lib/all.sh exec 3>/dev/null # ... rest of your code ... if [ "$1" = "configure" ]; then # on upgrade, set backup_myself to yes if it was not set filestorage=$(ucr get bareos/filestorage) backup_myself=$(ucr get bareos/backup_myself) if [ -n "$filestorage" -a -z "$backup_myself" ]; then ucr set bareos/backup_myself=yes fi # defaults ucr set \ bareos/pgsql/user?bareos \ bareos/pgsql/database?bareos \ bareos/filestorage?/var/lib/bareos/storage \ bareos/max_incr_volumes?1 \ bareos/max_diff_volumes?1 \ bareos/max_full_volumes?1 \ bareos/backup_myself?no ucr commit /etc/bareos/bareos-dir.conf /etc/bareos/bareos-sd.conf \ /etc/bareos/bareos-fd.conf /etc/bareos/bconsole.conf \ /etc/postgresql/8.4/main/pg_hba.conf touch /etc/bareos/autogenerated/clients.include chmod go-rwx /etc/bareos/autogenerated/fd-secrets chmod go-rwx /etc/bareos/autogenerated/fd-configs # activate our listener plugin invoke-rc.d univention-directory-listener restart # reload is sufficient for postgres to reload the pg_hba.conf file invoke-rc.d postgresql reload # restart bareos invoke-rc.d bareos-dir restart invoke-rc.d bareos-sd restart invoke-rc.d bareos-fd restart # firewall exceptions ucr set \ security/packetfilter/package/univention-bareos/tcp/9101/all="ACCEPT" \ security/packetfilter/package/univention-bareos/tcp/9101/all/en="bareos-dir" \ security/packetfilter/package/univention-bareos/tcp/9102/all="ACCEPT" \ security/packetfilter/package/univention-bareos/tcp/9102/all/en="bareos-fd" \ security/packetfilter/package/univention-bareos/tcp/9103/all="ACCEPT" \ security/packetfilter/package/univention-bareos/tcp/9103/all/en="bareos-sd" [ -x "/etc/init.d/univention-firewall" ] && invoke-rc.d univention-firewall restart call_joinscript 62univention-bareos.inst fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/univention-bareos.postrm000066400000000000000000000013121263011562700225740ustar00rootroot00000000000000#!/bin/sh set -e #set -x if [ -f /usr/share/debconf/confmodule ]; then . /usr/share/debconf/confmodule fi if [ -f /usr/share/dbconfig-common/dpkg/postrm.pgsql ]; then . /usr/share/dbconfig-common/dpkg/postrm.pgsql fi dbc_go univention-bareos $@ invoke-rc.d bareos-dir stop || true invoke-rc.d univention-directory-listener restart . /usr/share/univention-lib/all.sh . /usr/share/univention-join/joinscripthelper.lib if [ "$1" = "remove" ]; then call_unjoinscript 63univention-bareos-uninstall.uinst joinscript_remove_script_from_status_file univention-bareos fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/univention-bareos.preinst000066400000000000000000000004711263011562700227410ustar00rootroot00000000000000#!/bin/sh if [ "$1" = "install" ]; then test -e /usr/lib/univention-install/63univention-bareos-uninstall.uinst && rm /usr/lib/univention-install/63univention-bareos-uninstall.uinst fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/univention-bareos.prerm000066400000000000000000000007401263011562700224010ustar00rootroot00000000000000#!/bin/sh #set -x set -e . /usr/share/debconf/confmodule . /usr/share/dbconfig-common/dpkg/prerm.pgsql dbc_go univention-bareos $@ if [ "$1" = remove ]; then invoke-rc.d bareos-dir stop || true file="/usr/lib/univention-uninstall/63univention-bareos.uinst" if [ -r "$file" ]; then cp "$file" /usr/lib/univention-install/ fi fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 bareos-Release-14.2.6/debian/univention-bareos.univention-config-registry000066400000000000000000000014671263011562700265720ustar00rootroot00000000000000Type: multifile Multifile: etc/postgresql/8.4/main/pg_hba.conf Type: subfile Multifile: etc/postgresql/8.4/main/pg_hba.conf Subfile: etc/postgresql/8.4/main/pg_hba.conf.d/25-univention-bareos Variables: bareos/pgsql/.* Type: file File: etc/bareos/bareos-dir.conf Variables: bareos/pgsql/database Variables: bareos/pgsql/user Variables: bareos/filestorage Variables: hostname Variables: domainname Type: file File: etc/bareos/bareos-sd.conf Variables: bareos/filestorage Variables: hostname Variables: domainname Variables: bareos/backup_myself Variables: bareos/max_incr_volumes Variables: bareos/max_diff_volumes Variables: bareos/max_full_volumes Type: file File: etc/bareos/bareos-fd.conf Variables: hostname Variables: domainname Type: file File: etc/bareos/bconsole.conf Variables: hostname Variables: domainname bareos-Release-14.2.6/debian/univention-bareos.univention-config-registry-variables000066400000000000000000000024551263011562700305360ustar00rootroot00000000000000[bareos/filestorage] Description[de]=Speicherort für Backup-Volumes (bareos) Description[en]=Directory for backup volumes (bareos) Type=str Categories=backup [bareos/backup_myself] Description[de]=Eigensicherung aktivieren (yes/no) Description[en]=Enable backup job for the server itself (yes/no) Type=bool Categories=backup [bareos/max_incr_volumes] Description[de]=Maximale Anzahl der Volumes (10GB) im Pool für Incremental-Backups Description[en]=Maximum number of volumes (10GB) for the incremental backup pool Type=int Categories=backup [bareos/max_diff_volumes] Description[de]=Maximale Anzahl der Volumes (10GB) im Pool für Differential-Backups Description[en]=Maximum number of volumes (10GB) for the differential backup pool Type=int Categories=backup [bareos/max_full_volumes] Description[de]=Maximale Anzahl der Volumes (10GB) im Pool für Full-Backups Description[en]=Maximum number of volumes (10GB) for the full backup pool Type=int Categories=backup [bareos/pgsql/database] Description[de]=Datenbankname für die Bareos-Datenbank (bareos). Description[en]=Name of the bareos postgres database (bareos). Type=str Categories=backup [bareos/pgsql/user] Description[de]=Benutzername für die Bareos-Datenbank (bareos). Description[en]=Name of the bareos postgres user (bareos). Type=str Categories=backup bareos-Release-14.2.6/debian/univention-bareos.univention-service000066400000000000000000000013151263011562700251070ustar00rootroot00000000000000[bareos-director] description[de]=Dienst zum Steuern von Backups description[en]=Service for coordinating backups icon=service/bareos-dir programs=/usr/sbin/bareos-dir -c /etc/bareos/bareos-dir.conf start_type=bareos/dir/autostart [bareos-sd] description[de]=Dienst für den Zugriff auf Sicherungsmedien description[en]=Service for accessing backup media icon=service/bareos-sd programs=/usr/sbin/bareos-sd -c /etc/bareos/bareos-sd.conf start_type=bareos/sd/autostart [bareos-fd] description[de]=Dienst für den Zugriff auf zu sichernde Systeme description[en]=Service for accessing systems for backup icon=service/bareos-fd programs=/usr/sbin/bareos-fd -c /etc/bareos/bareos-fd.conf start_type=bareos/fd/autostart bareos-Release-14.2.6/debian/watch000066400000000000000000000002161263011562700167120ustar00rootroot00000000000000version=3 opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/bareos-$1\.tar\.gz/ \ https://github.com/bareos/bareos/releases .*/v?(\d\S*)\.tar\.gz bareos-Release-14.2.6/git_changelog000077500000000000000000000000341263011562700171550ustar00rootroot00000000000000#!/bin/sh git log --stat -M bareos-Release-14.2.6/manpages/000077500000000000000000000000001263011562700162335ustar00rootroot00000000000000bareos-Release-14.2.6/manpages/Makefile.in000066400000000000000000000014571263011562700203070ustar00rootroot00000000000000# # @MCOMMON@ .PHONY: dummy MAN1 = bareos-tray-monitor.1 bat.1 bconsole.1 bsmtp.1 bwild.1 bregex.1 MAN8 = bareos.8 bareos-dir.8 bareos-fd.8 bareos-sd.8 \ bcopy.8 bareos-dbcheck.8 bextract.8 bls.8 bscan.8 btape.8 \ btraceback.8 bpluginfo.8 \ bscrypto.8 all: nothing: depend: install: $(MKDIR) $(DESTDIR)/$(mandir)/man1 for I in ${MAN1}; \ do ($(RMF) $$I.gz; gzip -c $$I >$$I.gz; \ $(INSTALL_DATA) $$I.gz $(DESTDIR)$(mandir)/man1/$$I.gz; \ rm -f $$I.gz); \ done $(MKDIR) $(DESTDIR)/$(mandir)/man8 for I in ${MAN8}; \ do ($(RMF) $$I.gz; gzip -c $$I >$$I.gz; \ $(INSTALL_DATA) $$I.gz $(DESTDIR)$(mandir)/man8/$$I.gz; \ rm -f $$I.gz); \ done clean: @$(RMF) *~ 1 2 3 *.bak @find . -name .#* -exec $(RMF) {} \; depend: distclean: clean $(RMF) Makefile bareos-Release-14.2.6/manpages/bareos-dbcheck.8000066400000000000000000000175431263011562700211720ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BAREOS-DBCHECK 8 "26 September 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bareos-dbcheck \- Bareos's Catalog Database Check/Clean program .SH SYNOPSIS .B dbcheck .RI [ options ] .I working-directory .I bareos-database .I user .I password .RI [ dbhost ] .RI [ dbport ] .br .SH DESCRIPTION This manual page documents briefly the .B bareos-dbcheck command. .PP bareos-dbcheck will not repair your database if it is broken. Please see your vendor's instructions for fixing broken database. bareos-dbcheck is a simple program that will search for logical inconsistencies in the Bareos tables in your database, and optionally fix them. It is a database maintenance routine, in the sense that it can detect and remove unused rows, but it is not a database repair routine. To repair a database, see the tools furnished by the database vendor. Normally dbcheck should never need to be run, but if Bareos has crashed or you have a lot of Clients, Pools, or Jobs that you have removed, it could be useful. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-b If specified, dbcheck will run in batch mode, and it will proceed to examine and fix (if \-f is set) all programmed inconsistency checks. By default, dbcheck will enter interactive mode (see below). .TP .BI \-B print catalog configuration and exit. .TP .BI \-c\ config If the \-c option is given with the Director's conf file, there is no need to enter any of the command line arguments, in particular the working directory as dbcheck will read them from the file. .TP .BI \-C\ catalog catalog name in the director conf file. .TP .BI \-d\ nnn set debug level to \fInnn\fP. .TP .BI \-dt print timestamp in debug output. .TP .BI \-D\ drivername Specify the database driver name (default NULL) . .TP .BI \-f If specified, dbcheck will repair (fix) the inconsistencies it finds. Otherwise, it will report only. .TP .BI \-v Set verbose mode. .SH INTERACTIVE MODE In interactive mode dbcheck will prompt with the following: .PP Hello, this is the database check/correct program. Please select the function you want to perform. 1) Toggle modify database flag 2) Toggle verbose flag 3) Repair bad Filename records 4) Repair bad Path records 5) Eliminate duplicate Filename records 6) Eliminate duplicate Path records 7) Eliminate orphaned Jobmedia records 8) Eliminate orphaned File records 9) Eliminate orphaned Path records 10) Eliminate orphaned Filename records 11) Eliminate orphaned FileSet records 12) Eliminate orphaned Client records 13) Eliminate orphaned Job records 14) Eliminate all Admin records 15) Eliminate all Restore records 16) All (3-15) 17) Quit Select function number: By entering 1 or 2, you can toggle the modify database flag (\-f option) and the verbose flag (\-v). It can be helpful and reassuring to turn off the modify database flag, then select one or more of the consistency checks (items 3 through 9) to see what will be done, then toggle the modify flag on and re-run the check. The inconsistencies examined are the following: .BR Duplicate filename records. This can happen if you accidentally run two copies of Bareos at the same time, and they are both adding filenames simultaneously. It is a rare occurrence, but will create an inconsistent database. If this is the case, you will receive error messages during Jobs warning of duplicate database records. If you are not getting these error messages, there is no reason to run this check. .BR Repair bad Filename records. This checks and corrects filenames that have a trailing slash. They should not. .BR Repair bad Path records. This checks and corrects path names that do not have a trailing slash. They should. .BR Duplicate path records. This can happen if you accidentally run two copies of Bareos at the same time, and they are both adding filenames simultaneously. It is a rare occurrence, but will create an inconsistent database. See the item above for why this occurs and how you know it is happening. .BR Orphaned JobMedia records. This happens when a Job record is deleted (perhaps by a user issued SQL statement), but the corresponding JobMedia record (one for each Volume used in the Job) was not deleted. Normally, this should not happen, and even if it does, these records generally do not take much space in your database. However, by running this check, you can eliminate any such orphans. .BR Orphaned File records. This happens when a Job record is deleted (perhaps by a user issued SQL statement), but the corresponding File record (one for each Volume used in the Job) was not deleted. Note, searching for these records can be very time consuming (i.e. it may take hours) for a large database. Normally this should not happen as Bareos takes care to prevent it. Just the same, this check can remove any orphaned File records. It is recommended that you run this once a year since orphaned File records can take a large amount of space in your database. You might want to ensure that you have indexes on JobId, FilenameId, and PathId for the File table in your catalog before running this command. .BR Orphaned Path records. This condition happens any time a directory is deleted from your system and all associated Job records have been purged. During standard purging (or pruning) of Job records, Bareos does not check for orphaned Path records. As a consequence, over a period of time, old unused Path records will tend to accumulate and use space in your database. This check will eliminate them. It is recommended that you run this check at least once a year. .BR Orphaned Filename records. This condition happens any time a file is deleted from your system and all associated Job records have been purged. This can happen quite frequently as there are quite a large number of files that are created and then deleted. In addition, if you do a system update or delete an entire directory, there can be a very large number of Filename records that remain in the catalog but are no longer used. During standard purging (or pruning) of Job records, Bareos does not check for orphaned Filename records. As a consequence, over a period of time, old unused Filename records will accumulate and use space in your database. This check will eliminate them. It is strongly recommended that you run this check at least once a year, and for large database (more than 200 Megabytes), it is probably better to run this once every 6 months. .BR Orphaned Client records. These records can remain in the database long after you have removed a client. .BR Orphaned Job records. If no client is defined for a job or you do not run a job for a long time, you can accumulate old job records. This option allow you to remove jobs that are not attached to any client (and thus useless). .BR All Admin records. This command will remove all Admin records, regardless of their age. .BR All Restore records. This command will remove all Restore records, regardless of their age. By the way, I personally run dbcheck only where I have messed up my database due to a bug in developing Bareos code, so normally you should never need to run dbcheck inspite of the recommendations given above, which are given so that users don't waste their time running dbcheck too often. .SH SEE ALSO .BR bls (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bareos-dir.8000066400000000000000000000042201263011562700203510ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BAREOS\-DIR 8 "6 December 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME .B bareos\-dir \- Bareos Director .SH SYNOPSIS .B bareos\-dir .RI [ options ] .br .SH DESCRIPTION This manual page documents briefly the .B bareos\-dir command. .br Bareos's Director Daemon acts as the controller of the network backup system: it is responsible for scheduling and coordinating backups across the network. .SH OPTIONS .TP .BI \-c\ file Specify the configuration file to use. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .BI \-f Run in foreground (for debugging). .TP .BI \-g\ group Set the group/gid to run as. .TP .BI \-m Print kaboom output (for debugging) .TP .BI \-r\ job Run . .TP .BI \-s No signals (for debugging). .TP .B \-t Test the configuration file and report errors. .TP .BI \-u\ user Set the username/uid to run as. .TP .BI \-v Set verbose mode. .TP .BI \-? Show version and usage of program. .SH TCP-WRAPPERS CONFIGURATION Tcpwrappers looks for the service name of the bareos daemons in .I hosts.allow , and the service names of these daemons is configured to be different from the binary. The service names are configured to be .B %hostname%-%component% rather than .B bareos-dir (As defined in the bareos-dir.conf.in file) So the hosts.allow entry has to match .B %hostname%-%component% (servername-dir for example) instead of bareos-%component% .B WARNING: This means that if the hosts.allow file has the entry: .B bareos-dir: ALL you will not be able to run bconsole to connect to the local director! The entry would have to read: .B server-dir: ALL and this will allow the console to connect to the director. (The process running is bareos-dir.) .SH SEE ALSO .BR bareos-fd (8), .BR bareos-sd (8). .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bareos-fd.8000066400000000000000000000031421263011562700201660ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BAREOS\-SD 8 "6 December 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME .B bareos\-fd \- Bareos's File Daemon .SH SYNOPSIS .B bareos\-fd .RI [ options ] .br .SH DESCRIPTION This manual page documents briefly the .B bareos command. .br Bareos's File Daemon acts as the interface between the Bareos network backup system and the filesystems to be backed up: it is responsible for reading/writing/verifying the files to be backup'd/verified/restored. Network transfer can optionally be compressed. .SH OPTIONS .TP .BI \-b Enable backup only mode .TP .BI \-c\ file Specify the configuration file to use. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .BI \-f Run in foreground (for debugging). .TP .BI \-g\ group Set the group/gid to run as. .TP .BI \-k Keep readall permission when dropping privileges. .TP .BI \-m Print kaboom output (for debugging) .TP .BI \-r Enable restore only mode .TP .BI \-s No signals (for debugging). .TP .B \-t Test the configuration file and report errors. .TP .BI \-u\ user Set the username/uid to run as. .TP .BI \-v Set verbose mode. .TP .B \-? Show version and usage of program. .SH SEE ALSO .BR bareos\-dir (8), .BR bareos\-sd (8). .br .SH AUTHOR This manual page was written by Jose Luis Tallon . bareos-Release-14.2.6/manpages/bareos-sd.8000066400000000000000000000026611263011562700202100ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BAREOS\-SD 8 "6 December 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME .B bareos\-sd \- Bareos's Storage Daemon .SH SYNOPSIS .B bareos\-sd .RI [ options ] .br .SH DESCRIPTION This manual page documents briefly the .B bareos\-sd command. .br Bareos's Storage Daemon acts as the interface between the Bareos network backup system and a tape drive/autochanger or filesystem where the backups will be stored. .SH OPTIONS .TP .BI \-c\ file Specify the configuration file to use. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .BI \-f Run in foreground (for debugging). .TP .BI \-g\ group Set the group/gid to run as. .TP .BI \-p Proceed in spite of I/O errors .TP .BI \-m Print kaboom output (for debugging) .TP .BI \-s No signals (for debugging). .TP .B \-t Test the configuration file and report errors. .TP .BI \-u\ user Set the username/uid to run as. .TP .BI \-v Set verbose mode. .TP .B \-? Show version and usage of program. .SH SEE ALSO .BR bareos\-dir (8), .BR bareos\-fd (8). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bareos-tray-monitor.1000066400000000000000000000020771263011562700222400ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BACULA-TRAY-MONITOR 1 "May 10, 2006" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bareos-tray-monitor \- Bareos's 'System Tray' monitor .SH SYNOPSIS .B bareos-tray-monitor .RI [options] .br .SH DESCRIPTION This manual page documents briefly the .B bareos-tray-monitor command, a simple monitor for the 'system tray' in KDE/GNOME .PP .SH OPTIONS bareos-tray-monitor [\-c config_file] [\-d debug_level] [\-t] .TP .B \-c Specify configuration file. .TP .B \-d Set debug level to \fInn\fP. .TP .B \-t Test config mode: read configuration and exit. .TP .B \-? Show version and usage of program. .SH SEE ALSO .BR bareos-dir (8), .BR bls (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bareos.8000066400000000000000000000113721263011562700176030ustar00rootroot00000000000000.\" manual page [] for Bareos .\" SH section heading .\" SS subsection heading .\" LP paragraph .\" IP indented paragraph .\" TP hanging label .TH BAREOS 8 "Backup Archiving REcovery Open Sourced" .SH NAME Bareos \- Backup Archiving REcovery Open Sourced .SH SYNOPSIS .B bareos-dir \- Director .br .B bareos-fd \- File daemon or Client .br .B bareos-sd \- Storage daemon .br .B bconsole \- Console to control Bareos .br .B wx-console \- GUI Console .br .SH DESCRIPTION .LP Bareos is a set of computer programs that permits you (or the system administrator) to manage backup, recovery, and verification of computer data across a network of computers of different kinds. In technical terms, it is a network Client/Server based backup program. Bareos is relatively easy to use and efficient, while offering many advanced storage management features that make it easy to find and recover lost or damaged files. Due to its modular design, Bareos is scalable from small single computer systems to systems consisting of hundreds of computers located over a large network. .LP Bareos Director service consists of the program that supervises all the backup, restore, verify and archive operations. The system administrator uses the Bareos Director to schedule backups and to recover files. For more details see the Director Services Daemon Design Document in the Bareos Developer's Guild. The Director runs as a daemon or a service (i.e. in the background). .LP Bareos Console services is the program that allows the administrator or user to communicate with the Bareos Director (see above). Currently, the Bareos Console is available in two versions. The first and simplest is to run the Console program in a shell window (i.e. TTY interface). Most system administrators will find this completely adequate. The second version is a Qt 4.2 GUI interface named bat that has more features than the bconsole program. .LP Bareos File services (or Client program) is the software program that is installed on the machine to be backed up. It is specific to the operating system on which it runs and is responsible for providing the file attributes and data when requested by the Director. The File services are also responsible for the file system dependent part of restoring the file attributes and data during a recovery operation. For more details see the File Services Daemon Design Document in the Bareos Developer's Guide. This program runs as a daemon on the machine to be backed up, and in some of the documentation, the File daemon is referred to as the Client (for example in Bareos's configuration file). In addition to Unix/Linux File daemons, there is a Windows File daemon (normally distributed in binary format). The Windows File daemon runs on all currently known Windows versions (2K, 2003, XP, and Vista). .LP Bareos Storage services consist of the software programs that perform the storage and recovery of the file attributes and data to the physical backup media or volumes. In other words, the Storage daemon is responsible for reading and writing your tapes (or other storage media, e.g. files). For more details see the Storage Services Daemon Design Document in the Bareos Developer's Guide. The Storage services runs as a daemon on the machine that has the backup device (usually a tape drive). .LP Catalog services are comprised of the software programs responsible for maintaining the file indexes and volume databases for all files backed up. The Catalog services permit the System Administrator or user to quickly locate and restore any desired file. The Catalog services sets Bareos apart from simple backup programs like tar and bru, because the catalog maintains a record of all Volumes used, all Jobs run, and all Files saved, permitting efficient restoration and Volume management. Bareos currently supports three different databases, MySQL, PostgreSQL, and SQLite3, one of which must be chosen when building Bareos. .SH OPTIONS See the HTML/PDF documentation at: .br .br for details of the command line options. .SH CONFIGURATION Each daemon has its own configuration file which must be tailored for each particular installation. Please see the HTML/PDF documentation for the details. .SH SEE ALSO The HTML manual installed on your system (typically found in .br /usr/share/doc/bareos-) or the online manual at: .br .SH BUGS See .SH AUTHOR Kern Sibbald .SS Current maintainer Kern Sibbald .SS Contributors An enormous list of past and former persons who have devoted their time and energy to this project -- thanks. See the AUTHORS file in the main Bareos source directory. .SH COPYRIGHT Bareos is distributed under a modified AGPL version 3.0, as described in the file LICENSE included with the source distribution. bareos-Release-14.2.6/manpages/bat.1000066400000000000000000000022161263011562700170640ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BAT 1 "26 September 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bat \- Bareos Administration Tool Console .SH SYNOPSIS .B bat .RI [options] .br .SH DESCRIPTION This manual page documents briefly the .B bat command, the Qt4 version of the Bareos Administration Tool console. This is a GUI full featured program similar the bconsole program, but it is graphical oriented and more features. .PP .SH OPTIONS bat [\-s] [\-c config_file] [\-d debug_level] [\-t] .TP .B \-c Specify configuration file. Default is bat.conf. .TP .B \-d Set debug level to \fInn\fP. .TP .B \-s No signals. Used in debugging only. .TP .B \-t Test config mode: read configuration and exit. .TP .B \-? Show version and usage of program. .SH SEE ALSO .BR bareos-dir (8), .BR bls (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Kern Sibbald. bareos-Release-14.2.6/manpages/bconsole.1000066400000000000000000000022501263011562700201200ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH CONSOLE 1 "4 December 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bconsole \- Bareos's management Console .SH SYNOPSIS .B bconsole .RI [options] .br .SH DESCRIPTION This manual page documents briefly the .B bconsole command. .PP .SH OPTIONS .TP .BI \-D\ dir Select a Director. .TP .BI \-l List defined Directors. .TP .BI \-c\ config Specify configuration file. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .B \-n No conio (for scripting). .TP .B \-s No signals (for debugging). .TP .B \-u\ nn Set command execution timeout to \fInn\fP seconds .TP .B \-t Test the configuration file and report errors. .TP .B \-? Show version and usage of program. .SH SEE ALSO .BR bareos\-dir (8), .BR bls (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bcopy.8000066400000000000000000000026511263011562700174440ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BCOPY 8 "26 November 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bcopy \- Bareos's 'Copy from tape' .SH SYNOPSIS .B bcopy .RI [ options ] .I input-archive .I output-archive .br .SH DESCRIPTION This manual page documents briefly the .B bcopy command. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-b\ bootstrap Specify a bootstrap file. .TP .BI \-c\ config Specify configuration file. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .BI \-i\ input Specify input Volume names (separated by '|') .TP .BI \-o\ output Specify output Volume names (separated by '|') .TP .BI \-p Proceed in spite of I/O errors. .TP .BI \-w\ directory Specify working directory (default \fI/tmp\fP). .TP .B \-v Set verbose mode. .SH SEE ALSO .BR bls (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bextract.8000066400000000000000000000025731263011562700201470ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BEXTRACT 8 "26 November 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bextract \- Bareos's 'Extract from tape' .SH SYNOPSIS .B bextract .RI [ options ] .I bareos-archive-device-name .I output-directory .br .SH DESCRIPTION This manual page documents briefly the .B bextract command. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-b\ bootstrap Specify a bootstrap file. .TP .BI \-c\ config Specify configuration file. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .BI \-e\ file Specify exclude list. .TP .BI \-i\ file Specify include list. .TP .BI \-p Proceed in spite of I/O errors. .TP .B \-v Set verbose mode. .TP .BI \-V\ volume-name Specify volume names. .SH SEE ALSO .BR bls (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bls.8000066400000000000000000000034701263011562700171100ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BLS 8 "26 November 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bls \- Bareos's 'Tape LS' .SH SYNOPSIS .B bls .RI [ options ] .I .br .SH DESCRIPTION This manual page documents briefly the .B bls command. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-b\ bootstrap Specify a bootstrap file. .TP .BI \-c\ config Specify configuration file. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output .TP .BI \-e\ Specify exclude list file. .TP .BI \-i\ Specify include list file. .TP .BI \-j List jobs. .TP .BI \-k List blocks. .TP .I (no \-j or \-k option) List saved files .TP .BI -L Dump label. .TP .BI \-p Proceed in spite of errors. .TP .BI \-V\ volumes Specify volume names (separated by '|'). .TP .B \-v Set verbose mode. .SH SEE ALSO .BR bscan (8), .BR bextract (8). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/bpluginfo.8000066400000000000000000000061241263011562700203140ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH bpluginfo "8" "July 2012" "bpluginfo" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bpluginfo \- Bareos Plugin information utility .SH SYNOPSIS .B bplufinfo .RI [ options ] .I plugin_filename.so .br .SH DESCRIPTION .LP The main purpose of .B bpluginfo is to display different information about Bareos plugin. You can use it to check a plugin name, author, license and short description. You can use .B \-f option to display API implemented by the plugin. Some plugins may require additional '-a' option for validating a Bareos Daemons API. In most cases it is not required. .PP .SH OPTIONS A summary of options is included below. .TP .B \-h Show usage of the program. .TP .BI \-v Verbose information printing all available data from the plugin, including plugin header and implemented API. .TP .BI \-i Display short information from plugin header only. This is a default option. Option incompatible with .B \-f option. .TP .BI \-f Display information about implemented API functions. .TP .BI \-a\ You can supply the plugin initialization function with a particular Bareos API number. Without this option a default API number is '1'. Option require a numeric argument. .SH RETURN CODE .BR bpluginfo returns 0 on success, and non-zero on error. .TP You can check return code to find what was a cause of the error. * 0 - success * 1 - cannot load a plugin * 2 - cannot find a loadPlugin function * 3 - cannot find an unloadPlugin function * 10 - not enough memory .SH EXAMPLE USAGE This is an example of bplufinfo usage with verbose option (-v) and default plugin. .LP .sp .RS .nf \fB$ bpluginfo -v /usr/lib/bareos/plugins/python-fd.so Plugin type: Bareos File Daemon plugin Plugin magic: *FDPluginData* Plugin version: 2 Plugin release date: October 2013 Plugin author: Marco van Wieringen Plugin licence: Bareos AGPLv3 Plugin description: Python File Daemon Plugin Plugin API version: 8 Plugin usage: python:module_path=:module_name= Plugin functions: newPlugin() freePlugin() getPluginValue() setPluginValue() handlePluginEvent() startBackupFile() endBackupFile() startRestoreFile() endRestoreFile() pluginIO() createFile() setFileAttributes() checkFile() .fi .RE .SH AUTHOR Written by Radoslaw Korzeniewski (c) Inteos Sp. z o.o. .SH BUGS Does not handle all required Bareos functions callbacks which can lead to utility crash. .\".SH TODO" .PP .PP .SH "REPORTING BUGS" Report bugs to . .SH COPYRIGHT Copyright \(co 2012 Free Software Foundation Europe e.V. .br This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .SH "SEE ALSO" .BR bareos-dir, .BR bareos-sd, .BR bareos-fd, .BR "Bareos Plugins API" bareos-Release-14.2.6/manpages/bregex.1000066400000000000000000000036621263011562700176000ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BREGEX 1 "30 October 2011" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bregex \- Bareos's 'regex' engine .SH SYNOPSIS .B bregex .RI [ options ] .I -f .br .SH DESCRIPTION This manual page documents briefly the .B bregex command. .br This program can be useful for testing regex expressions to be applied against a list of filenames. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output .TP .BI \-f\ The data-file is a filename that contains lines of data to be matched (or not) against one or more patterns. When the program is run, it will prompt you for a regular expression pattern, then apply it one line at a time against the data in the file. Each line that matches will be printed preceded by its line number. You will then be prompted again for another pattern. .TP .BI \-n Print lines that do not match .TP .BI \-l Suppress lines numbers. .SH SEE ALSO .BR regex(7) .br .SH AUTHOR This manual page was written by Bruno Friedmann .nh . bareos-Release-14.2.6/manpages/bscan.8000066400000000000000000000054751263011562700174250ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BSCAN 8 "26 November 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bscan \- Bareos's 'Scan tape' .SH SYNOPSIS .B bscan .RI [ options ] .I bareos-archive .br .SH DESCRIPTION .LP The purpose of bscan is to read (scan) a Bareos Volume and to recreate or update the database contents with the information found on the Volume. This is done in a non-destructive way. This permits restoring database entries that have been lost by pruning, purging, deleting, or a database corruption problem. .LP Normally, it should not be necessary to run the bscan command because the database is self maintaining. Logical inconsistencies in the Bareos database can be found by bareos-dbcheck. In addition, if you have maintained bootstrap files during backups, you should be able to recover all your data from the bootstrap file without needed an up to date catalog. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-B\ drivername Specify the database driver name (default NULL) . .TP .BI \-b\ bootstrap Specify a bootstrap file. .TP .BI \-c\ configfile Specify storage daemon configuration file. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .BI \-D\ director Specify a director name specified in the storage daemon configuration file for the Key Encryption Key selection. .TP .BI \-a\ directory Specify the database backend directory .TP .B \-m Update media info in database. .TP .BI \-n\ name Specify the database name (default: \fIbareos\fP) .TP .BI \-u\ username Specify database username (default: \fIbareos\fP) .TP .BI \-P\ password Specify database password (default: \fInone\fP) .TP .BI \-h\ host Specify database host (default: \fINULL\fP) .TP .BI \-t\ port Specify database port (default: 0) .TP .B \-p Proceed in spite of I/O errors. .TP .B \-r List records. .TP .B \-s Synchronize or store in database. .TP .B \-S Show scan progress periodically. .TP .B \-v Verbose output mode. .TP .BI \-V\ volume Specify volume names (separated by '|') .TP .BI \-w\ directory Specify working directory (default from configuration file) .SH SEE ALSO .BR bls (8), .BR bextract (8), .BR bareos-dbcheck (8). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh , for the Debian GNU/Linux system (but may be used by others). bareos-Release-14.2.6/manpages/bscrypto.8000066400000000000000000000055701263011562700202000ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BSCRYPTO 8 "23 February 2013" "Marco van Wieringen" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bscrypto \- Bareos's 'SCSI Crypto' .SH SYNOPSIS .B bscrypto .RI [ options ] .I device_name .br .SH DESCRIPTION .LP The purpose of bscrypto is to be a standalone tool for manipulating the SCSI Crypto framework using the SCSI SPIN/SPOUT security pages. This tool allows you to perform standalone crypto operations that are normally performed by the .B scsicrypto-sd.so plugin in the storage daemon. .LP You also need bscrypto tool to to the initial setup of things like .B Key Encryption Keys in the .B bareos-sd.conf and .B bareos-dir.conf .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .B \-b Perform base64 encoding of keydata. Any binary data is base64 encoded and as such converted to normal ASCII. .TP .B \-c Clear encryption key. Clear the encryption key currently loaded on the drive by issueing a SCSI SPOUT clear key page. .TP .B \-D Dump the content of given cachefile .TP .B \-d Set debug level to .TP .B \-e Show drive encryption status. Request the current drive encryption status by issueing a SCSI SPIN cmd requesting the SPIN_DATA_ENCR_STATUS_PAGE. .TP .B \-g Generate new encryption passphrase in keyfile. A passphrase is generated from random data and is ASCII only. .TP .B \-k Show content of keyfile. If the data is wrapped using a so called .B Key Encryption Key you also need the .B \-b flag to base64 decode the data that is wrapped using the algoritm described in RFC3394 which gives binary output. .TP .B \-p Populate given cachefile with crypto keys .TP .B \-r Reset expiry time for entries of given cachefile .TP .B \-s Set encryption key loaded from keyfile. Load the new key from the keyfile and load it into the drives crypto buffer using a SCSI SPOUT command. .TP .B \-v Show volume encryption status. Request the current volume encryption status by issueing a SCSI SPIN cmd requesting the SPIN_NEXT_BLOCK_ENCR_STATUS_PAGE. .TP .B \-w Wrap/Unwrap the key using RFC3394 aes-(un)wrap using the key in keyfile as a .B Key Encryption Key After wrapping the data using this option the output is binary so you may want to use the .B \-b flag to base64 encode this data. .SH SEE ALSO .BR bareos-sd (8), .br .SH AUTHOR This manual page was written by Marco van Wieringen .nh bareos-Release-14.2.6/manpages/bsmtp.1000066400000000000000000000076161263011562700174540ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BSMTP 1 "3 July 2012" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME bsmtp \- Bareos's SMTP client (mail submission program) .SH SYNOPSIS .B bsmtp .RI [ options ] .I <...> .SH DESCRIPTION .B bsmtp is a simple mail user agent designed to permit more flexibility than the standard mail programs typically found on Unix systems, and to ease portability. It can even run on Windows machines. It is used by the Director daemon to send notifications and requests to the operator. .SH OPTIONS .TP .B \-4 Forces bsmtp to use IPv4 addresses only. .TP .B \-6 Forces bsmtp to use IPv6 addresses only. .TP .B \-8 Encode the mail in UTF-8. .TP .B \-a Use any ip protocol for address resolution. .TP .B \-c Set the \fBCc:\fR header. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output. .TP .B \-f Set the \fBFrom:\fR header. If not specified, .B bsmtp will try to use your username. .TP .BI \-h\ mailhost:port Use mailhost:port as the SMTP server. (default port: 25) .TP .B \-s Set the \fBSubject:\fR header. .TP .B \-r Set the \fBReply-To:\fR: header. .TP .B \-l Set the maximum number of lines to be sent. (default: unlimited) .TP .B \-? Show version and usage of program. .SH USAGE \fIrecipients\fR is a space separated list of email addresses. The body of the email message is read from standard input. Message is ended by sending the EOF character (Ctrl-D on many systems) on the start of a new line, much like many 'mail' commands. The actual, automated behavior of \fBbsmtp\fR will depend on the mail-related configuration of the Director in the \fIMessages\fR resource of \fIbareos-dir.conf\fR. Interactive use of \fBbsmtp\fR is pertinent to manually test and ensure these configuration bits are valid. This is highly recommended. .SH CONFIGURATION These commands should each appear on a single line in the configuration file. Messages { Name = Standard mailcommand = "/home/bareos/bin/bsmtp \-h mail.domain.com \-f \\"\\(Bareos\\) \\<%r\\>\\" \-s \\"Bareos: %t %e of %c %l\\" %r" operatorcommand = "/home/bareos/bin/bsmtp \-h mail.domain.com \-f \\"\\(Bareos\\) \\<%r\\>\\" \-s \\"Bareos: Intervention needed for %j\\" %r" mail = sysadmin@site.domain.com = all, !skipped operator = sysop@site.domain.com = mount console = all, !skipped, !saved } \fIhome/bareos/bin\fR is replaced with the path to the Bareos binary directory, and mail.domain.com is replaced with the fully qualified name of an SMTP server, which usually listen on port 25. .SH ENVIRONMENT If the \fB-h\fR option is not specified, \fBbsmtp\fR will use environment variable \fBSMTPSERVER\fR, or 'localhost' if not set. .SH NOTES Since \fBbsmtp\fR always uses a TCP connection rather than writing to a spool file, you may find that your \fBFrom:\fR address is being rejected because it does not contain a valid domain, or because your message has gotten caught in spam filtering rules. Generally, you should specify a fully qualified domain name in the from field, and depending on whether your SMTP gateway is Exim or Sendmail, you may need to modify the syntax of the from part of the message. If \fBbsmtp\fR cannot connect to the specified mail host, it will retry to connect to \fBlocalhost\fR. .SH BUGS If you are getting incorrect dates (e.g. 1970) and you are running with a non-English locale, you might try setting the \fBLANG="en_US"\fR environment variable. .SH AUTHOR This manual page was written by Jose Luis Tallon .nh , revised and edited by Lucas B. Cohen .nh . .SH SEE ALSO .BR "bareos-dir" "(8) " bareos-Release-14.2.6/manpages/btape.8000066400000000000000000000044151263011562700174230ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BTAPE 8 "26 November 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME btape \- Bareos's Tape interface test program .SH SYNOPSIS .B btape .RI [ options ] .I device-name .br .SH DESCRIPTION This manual page documents briefly the .B btape command. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show summary of options and commands. .TP .BI \-b\ bootstrap Specify a bootstrap file. .TP .BI \-c\ config Specify configuration file. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-p Proceed inspite of I/O errors. .TP .B \-s No signals (for debugging). .TP .B \-v Set verbose mode. .sp 3 .SH COMMANDS .TP .B autochanger test autochanger .TP .B bsf backspace file .TP .B bsr backspace record .TP .B cap list device capabilities .TP .B clear clear tape errors .TP .B eod go to end of Bareos data for append .TP .B eom go to the physical end of medium .TP .B fill fill tape, write onto second volume .TP .B unfill read filled tape .TP .B fsf forward space a file .TP .B fsr forward space a record .TP .B help print this reference .TP .B label write a Bareos label to the tape .TP .B load load a tape .TP .B quit quit btape .TP .B rawfill use write() to fill tape .TP .B readlabel read and print the Bareos tape label .TP .B rectest test record handling functions .TP .B rewind rewind the tape .TP .B scan read() tape block by block to EOT and report .TP .B scanblocks Bareos read block by block to EOT and report .TP .B status print tape status .TP .B test General test Bareos tape functions .TP .B weof write an EOF on the tape .TP .B wr write a single Bareos block .TP .B rr read a single record .TP .B rb read a single bareos block .TP .B qfill quick fill command .br .SH SEE ALSO .BR bscan (1), .BR bextract (1). .br .SH AUTHOR This manual page was written by Jose Luis Tallon .nh . bareos-Release-14.2.6/manpages/btraceback.8000066400000000000000000000043431263011562700204110ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BTRACEBACK 8 "6 December 2009" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .SH NAME btraceback \- wrapper script around gdb and bsmtp .SH SYNOPSIS .B btraceback .I /path/to/binary .I pid .SH DESCRIPTION \fBbtraceback\fR is a wrapper shell script around the \fBgdb\fR debugger (or \fBdbx\fR on Solaris systems) and \fBbsmtp\fR, provided for debugging purposes. .SH USAGE \fBbtraceback\fR is called by the exception handlers of the Bareos daemons during a crash. It can also be called interactively to view the current state of the threads belonging to a process, but this is not recommended unless you are trying to debug a problem (see below). .SH NOTES In order to work properly, debugging symbols must be available to the debugger on the system, and gdb, or dbx (on Solaris systems) must be available in the \fB$PATH\fR. If the Director or Storage daemon runs under a non-root uid, you will probably need to be modify the \fBbtraceback\fR script to elevate privileges for the call to \fBgdb\fR/\fBdbx\fR, to ensure it has the proper permissions to debug when called by the daemon. Although Bareos's use of \fBbtraceback\fR within its exception handlers is always safe, manual or interactive use of \fBbtraceback\fR is subject to the same risks than live debugging of any program, which means it could cause Bareos to crash under rare and abnormal circumstances. Consequently we do not recommend manual use of \fBbtraceback\fR in production environments unless it is required for debugging a problem. .SH ENVIRONMENT \fBbtracback\fR relies on \fB$PATH\fR to find the debugger. .SH FILES .TP .I /usr/lib/bareos/btraceback .RS The script itself. .RE .TP .I /usr/sbin/btraceback .RS symbolic link to \fI/usr/lib/bareos/btraceback\fR .RE .TP .I /etc/bareos/scripts/btraceback.gdb .RS the GDB command batch used to output a stack trace .RE .SH AUTHOR This manual page was written by Lucas B. Cohen .nh .SH SEE ALSO .BR "bsmtp" "(1) " bareos-Release-14.2.6/manpages/bwild.1000066400000000000000000000042301263011562700174150ustar00rootroot00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BWILD 1 "30 October 2011" "Kern Sibbald" "Backup Archiving REcovery Open Sourced" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bwild \- Bareos's 'wildcard' engine .SH SYNOPSIS .B bwild .RI [ options ] .I -f .br .SH DESCRIPTION This manual page documents briefly the .B bwild command. .br This is a simple program that will allow you to test wild-card expressions against a file of data. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invoke bold face and italics, .\" respectively. .SH OPTIONS A summary of options is included below. .TP .B \-? Show version and usage of program. .TP .BI \-d\ nn Set debug level to \fInn\fP. .TP .BI \-dt Print timestamp in debug output .TP .BI \-f\ The data-file is a filename that contains lines of data to be matched (or not) against one or more patterns. When the program is run, it will prompt you for a wild-card pattern, then apply it one line at a time against the data in the file. Each line that matches will be printed preceded by its line number. You will then be prompted again for another pattern. .br Enter an empty line for a pattern to terminate the program. You can print only lines that do not match by using the \-n option, and you can suppress printing of line numbers with the \-l option. .TP .BI \-n Print lines that do not match .TP .BI \-l Suppress lines numbers. .TP .BI \-i use case insensitive match. .SH SEE ALSO .BR fnmatch(3) .br .SH AUTHOR This manual page was written by Bruno Friedmann .nh . bareos-Release-14.2.6/platforms/000077500000000000000000000000001263011562700164475ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/Makefile.in000066400000000000000000000037641263011562700205260ustar00rootroot00000000000000# # This is the makefile template for the platform directory # which contains general platform installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ SUBDIRS = hurd freebsd redhat suse solaris unknown openbsd osx irix gentoo \ debian darwin aix bsdi mandrake slackware alpha ubuntu univention systemd DISTNAME=@DISTNAME@ DISTVER=@DISTVER@ all: @for subdir in ${SUBDIRS}; do \ if [ -f $${subdir}/Makefile ]; then \ (cd $${subdir}; $(MAKE) DESTDIR=$(DESTDIR);) \ fi; \ done install: @if test x$(DISTNAME) != x -a -f $(DISTNAME)/Makefile ; then \ (cd $(DISTNAME); \ $(MAKE) DESTDIR=$(DESTDIR) "DISTNAME=$(DISTNAME)" "DISTVER=$(DISTVER)" $@) \ fi install-autostart: @if test x$(DISTNAME) != x -a -f $(DISTNAME)/Makefile ; then \ (cd $(DISTNAME); \ $(MAKE) DESTDIR=$(DESTDIR) "DISTNAME=$(DISTNAME)" "DISTVER=$(DISTVER)" $@) \ fi install-autostart-dir: @if test x$(DISTNAME) != x -a -f $(DISTNAME)/Makefile ; then \ (cd $(DISTNAME); \ $(MAKE) DESTDIR=$(DESTDIR) "DISTNAME=$(DISTNAME)" "DISTVER=$(DISTVER)" $@) \ fi install-autostart-fd: @if test x$(DISTNAME) != x -a -f $(DISTNAME)/Makefile ; then \ (cd $(DISTNAME); \ $(MAKE) DESTDIR=$(DESTDIR) "DISTNAME=$(DISTNAME)" "DISTVER=$(DISTVER)" $@) \ fi install-autostart-sd: @if test x$(DISTNAME) != x -a -f $(DISTNAME)/Makefile ; then \ (cd $(DISTNAME); \ $(MAKE) DESTDIR=$(DESTDIR) "DISTNAME=$(DISTNAME)" "DISTVER=$(DISTVER)" $@) \ fi depend: clean: @for subdir in ${SUBDIRS}; do \ if [ -f $${subdir}/Makefile ]; then \ (cd $${subdir}; $(MAKE) clean) \ fi; \ done @$(RMF) 1 2 3 distclean: @for subdir in ${SUBDIRS}; do \ if [ -f $${subdir}/Makefile ]; then \ (cd $${subdir}; $(MAKE) distclean) \ fi; \ done @$(RMF) Makefile devclean: @for subdir in ${SUBDIRS}; do \ if [ -f $${subdir}/Makefile ]; then \ (cd $${subdir}; $(MAKE) devclean) \ fi; \ done @$(RMF) Makefile bareos-Release-14.2.6/platforms/README000066400000000000000000000003601263011562700173260ustar00rootroot00000000000000 This directory, /platforms, contains the platform specific installation files. Files that are common to all platforms are in this directory, and files that are specific to a particular platform are contained in subdirectories. bareos-Release-14.2.6/platforms/aix/000077500000000000000000000000001263011562700172305ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/aix/Makefile.in000066400000000000000000000033761263011562700213060ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the AXI specific installation. # # 1 March 2003 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @$(RMF) /etc/rc0.d/K20bareos-fd @$(RMF) /etc/rc1.d/S99bareos-fd @$(RMF) /etc/rc2.d/S99bareos-fd @$(MKDIR) /etc/init.d @$(INSTALL_PROGRAM) bareos-fd /etc/init.d/bareos-fd # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-fd /etc/rc0.d/K20bareos-fd @ln -f -s /etc/init.d/bareos-fd /etc/rc1.d/S99bareos-fd @ln -f -s /etc/init.d/bareos-fd /etc/rc2.d/S99bareos-fd install-autostart-sd: @$(RMF) /etc/rc0.d/K20bareos-sd @$(RMF) /etc/rc1.d/S99bareos-sd @$(RMF) /etc/rc2.d/S99bareos-sd @$(MKDIR) /etc/init.d @$(INSTALL_PROGRAM) bareos-sd /etc/rc.d/init.d/bareos-sd # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-sd /etc/rc0.d/K20bareos-sd @ln -f -s /etc/init.d/bareos-sd /etc/rc1.d/S99bareos-sd @ln -f -s /etc/init.d/bareos-sd /etc/rc2.d/S99bareos-sd install-autostart-dir: @$(RMF) /etc/rc0.d/K20bareos-dir @$(RMF) /etc/rc1.d/S99bareos-dir @$(RMF) /etc/rc2.d/S99bareos-dir @$(MKDIR) /etc/init.d @$(INSTALL_PROGRAM) bareos-dir /etc/rc.d/init.d/bareos-dir # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-dir /etc/rc0.d/K20bareos-dir @ln -f -s /etc/init.d/bareos-dir /etc/rc1.d/S99bareos-dir @ln -f -s /etc/init.d/bareos-dir /etc/rc2.d/S99bareos-dir clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec bareos-Release-14.2.6/platforms/alpha/000077500000000000000000000000001263011562700175345ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/alpha/Makefile.in000066400000000000000000000013351263011562700216030ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Tru64 specific installation. # # 28 May 2004 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-fd: @$(RMF) /sbin/rc0.d/K20bareos-fd @$(RMF) /sbin/rc3.d/S99bareos-fd @$(MKDIR) /sbin/init.d @$(INSTALL_PROGRAM) bareos-fd /sbin/init.d/bareos-fd # set symlinks for script at startup and shutdown @ln -f -s /sbin/init.d/bareos-fd /sbin/rc0.d/K20bareos-fd @ln -f -s /sbin/init.d/bareos-fd /sbin/rc3.d/S99bareos-fd clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-fd @$(RMF) Makefile devclean: clean @$(RMF) bareos-fd @$(RMF) Makefile bareos-Release-14.2.6/platforms/alpha/bareos-fd.in000066400000000000000000000016261263011562700217330ustar00rootroot00000000000000#!/bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos File daemon: " /sbin/bareos-fd $2 -c /etc/bareos/bareos-fd.conf RETVAL=$? echo ## [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; stop) echo "Stopping the Bareos File daemon: " # killproc @sbindir@/bareos-fd ID=`ps -ef | grep -F bareos-fd | grep -Fv grep | awk '{print $2}'` [ -n "$ID" ] && kill $ID RETVAL=$? echo ## [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/bsdi/000077500000000000000000000000001263011562700173705ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/bsdi/Makefile.in000066400000000000000000000047361263011562700214470ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Solaris specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ VPATH = @srcdir@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-fd /etc/rc.bareos-fd @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-fd /etc/rc.local; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.local already patched"; \ else \ $(RMF) /etc/rc.local.$$today; \ cp -p /etc/rc.local /etc/rc.local.$$today; \ ( echo "Start the Bareos File daemon. Do not remove the 'TAG_BAREOS_FD' text"; \ echo "if [ -x /etc/rc.bareos-fd ]; then # TAG_BAREOS_FD"; \ echo " /etc/rc.bareos-fd start # TAG_BAREOS_FD"; \ echo "fi # TAG_BAREOS_FD"; \ ) >> /etc/rc.local; \ echo ""; \ fi install-autostart-sd: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-sd /etc/rc.bareos-sd @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-sd /etc/rc.local; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.local already patched"; \ else \ $(RMF) /etc/rc.local.$$today; \ cp -p /etc/rc.local /etc/rc.local.$$today; \ ( echo "Start the Bareos Storage daemon. Do not remove the 'TAG_BAREOS_SD' text"; \ echo "if [ -x /etc/rc.bareos-fd ]; then # TAG_BAREOS_SD"; \ echo " /etc/rc.bareos-fd start # TAG_BAREOS_SD"; \ echo "fi # TAG_BAREOS_SD"; \ ) >> /etc/rc.local; \ echo ""; \ fi install-autostart-dir: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-dir /etc/rc.bareos-dir @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-dir /etc/rc.local; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.local already patched"; \ else \ $(RMF) /etc/rc.local.$$today; \ cp -p /etc/rc.local /etc/rc.local.$$today; \ ( echo "Start the Bareos Director. Do not remove the 'TAG_BAREOS_DIR' text"; \ echo "if [ -x /etc/rc.bareos-dir ]; then # TAG_BAREOS_DIR"; \ echo " /etc/rc.bareos-dir start # TAG_BAREOS_DIR"; \ echo "fi # TAG_BAREOS_DIR"; \ ) >> /etc/rc.local; \ echo ""; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec bareos-Release-14.2.6/platforms/bsdi/bareos-dir.in000066400000000000000000000015101263011562700217440ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # RETVAL=0 case "$1" in start) echo "Starting the Bareos Director: " @sbindir@/bareos-dir $2 -c @sysconfdir@/bareos-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-dir ;; stop) echo "Stopping the Director daemon: " # killproc @sbindir@/bareos-dir RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/bsdi/bareos-fd.in000066400000000000000000000014701263011562700215640ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos File daemon: " @sbindir@/bareos-fd $2 -c @sysconfdir@/bareos-fd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; stop) echo "Stopping the Bareos File daemon: " # killproc @sbindir@/bareos-fd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/bsdi/bareos-sd.in000066400000000000000000000015061263011562700216010ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos Storage daemon: " @sbindir@/bareos-sd $2 -c @sysconfdir@/bareos-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-sd ;; stop) echo "Stopping the Bareos Storage daemon: " # killproc @sbindir@/bareos-sd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/darwin/000077500000000000000000000000001263011562700177335ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/darwin/Makefile.in000066400000000000000000000007161263011562700220040ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Darwin specific installation. # # 22 Februrary 2003 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: install-autostart-sd: install-autostart-dir: clean: distclean: clean @$(RMF) Makefile devclean: clean @$(RMF) Makefile bareos-Release-14.2.6/platforms/debian/000077500000000000000000000000001263011562700176715ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/debian/Makefile.in000066400000000000000000000102021263011562700217310ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Debian/Ubuntu/Kubuntu specific installation. # # 21 March 2008 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ all: (cd ../../debian; $(MAKE) $@;) install: install_logrotate install-dbconfig install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install_logrotate: @$(MKDIR) $(DESTDIR)/etc/logrotate.d @$(INSTALL_DATA) ../../scripts/logrotate $(DESTDIR)/etc/logrotate.d/bareos-dir install-autostart-fd: @echo "Installing bareos-fd boot script ..." @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) ../../debian/bareos-filedaemon.bareos-fd.init $(DESTDIR)/etc/init.d/bareos-fd @echo "Installing bareos-fd symlinks ..." @if test x$(DESTDIR) = x ; then \ /usr/sbin/update-rc.d bareos-fd defaults; \ fi install-autostart-sd: @echo "Installing bareos-sd boot script ..." @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) ../../debian/bareos-storage.bareos-sd.init $(DESTDIR)/etc/init.d/bareos-sd @echo "Installing bareos-sd symlinks ..." @if test "x$(DESTDIR)" = "x" ; then \ /usr/sbin/update-rc.d bareos-sd defaults; \ fi install-autostart-dir: @echo "Installing bareos-dir boot script ..." @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) ../../debian/bareos-director.bareos-dir.init $(DESTDIR)/etc/init.d/bareos-dir @echo "Installing bareos-dir symlinks ..." @if test "x$(DESTDIR)" = "x" ; then \ /usr/sbin/update-rc.d bareos-dir defaults; \ fi install-dbconfig: @echo "Installing dbconfig files ..." @$(INSTALL_PROGRAM) set_dbconfig_vars.sh $(DESTDIR)/${scriptdir}/ @$(MKDIR) $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/install/ # # mysql # @$(SYMLINK) $(scriptdir)/ddl/creates/mysql.sql $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/install/mysql @$(MKDIR) $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade/mysql/ for i in $(DESTDIR)/$(scriptdir)/ddl/updates/mysql.*.sql; do \ if [ -r $$i ]; then \ BASENAME=`basename $$i`; \ VERSION=`echo $$BASENAME | sed -r 's/mysql\.[0-9]*_([0-9]*)\.sql/\1/'`; \ $(SYMLINK) $(scriptdir)/ddl/updates/$$BASENAME $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade/mysql/$$VERSION; \ fi; \ done # # postgresql # @$(SYMLINK) $(scriptdir)/ddl/creates/postgresql.sql $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/install/pgsql @$(MKDIR) $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade/pgsql/ @$(MKDIR) $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade-dbadmin/pgsql/ # if the initial install has not used dbconfig, # the bareos database user might not have the required permissions # to drop tables. Therefore droping tables will be done as database admin user. # Tables are created by the bareos database user, # because otherwise it do not receive the required permissions. for i in $(DESTDIR)/$(scriptdir)/ddl/updates/postgresql.*.sql; do \ if [ -r $$i ]; then \ BASENAME=`basename $$i`; \ VERSION=`echo $$BASENAME | sed -r 's/postgresql\.[0-9]*_([0-9]*)\.sql/\1/'`; \ grep -E -i "^DROP|^--|^$$" $$i > $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade-dbadmin/pgsql/$$VERSION; \ sed 's/^DROP/-- upgrade-dbadmin: DROP/' $$i > $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade/pgsql/$$VERSION; \ fi; \ done # # sqlite # @$(SYMLINK) $(scriptdir)/ddl/creates/sqlite3.sql $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/install/sqlite3 @$(MKDIR) $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade/sqlite3/ for i in $(DESTDIR)/$(scriptdir)/ddl/updates/sqlite3.*.sql; do \ if [ -r $$i ]; then \ BASENAME=`basename $$i`; \ VERSION=`echo $$BASENAME | sed -r 's/sqlite3\.[0-9]*_([0-9]*)\.sql/\1/'`; \ $(SYMLINK) $(scriptdir)/ddl/updates/$$BASENAME $(DESTDIR)/usr/share/dbconfig-common/data/bareos-database-common/upgrade/sqlite3/$$VERSION; \ fi; \ done clean: @$(RMF) 1 2 3 (cd ../../debian; $(MAKE) $@;) distclean: clean @$(RMF) Makefile devclean: clean @$(RMF) Makefile bareos-Release-14.2.6/platforms/debian/set_dbconfig_vars.sh.in000077500000000000000000000013341263011562700243170ustar00rootroot00000000000000#!/bin/sh # This script is intended to be sourced by # bareos-database-common postinstall script # on Debian based distributions. # It helps to configure dbconfig # when migrating to dbconfig. LIB=/usr/lib/bareos/scripts/bareos-config-lib.sh if ! [ -r "$LIB" ]; then echo "failed to read library $LIB" >&2 else . $LIB #dbc_dbserver= #dbc_dbport= dbname=`get_database_name` dbuser=`get_database_user` dbpass=`get_database_password` case "`get_database_driver`" in postgresql) dbtype="pgsql" ;; mysql) dbtype="mysql" ;; sqlite3) dbtype="sqlite3" basepath="`get_working_dir`" ;; esac fi bareos-Release-14.2.6/platforms/freebsd/000077500000000000000000000000001263011562700200615ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/freebsd/Makefile.in000066400000000000000000000047371263011562700221410ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Solaris specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ VPATH = @srcdir@ SED = /usr/bin/sed nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-fd /etc/rc.bareos-fd @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-fd /etc/rc.conf; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.conf already patched"; \ else \ $(RMF) /etc/rc.conf.$$today; \ cp -p /etc/rc.conf /etc/rc.conf.$$today; \ ( echo "Start the Bareos File daemon. Do not remove the 'TAG_BAREOS_FD' text"; \ echo "if [ -x /etc/rc.bareos-fd ]; then # TAG_BAREOS_FD"; \ echo " /etc/rc.bareos-fd start # TAG_BAREOS_FD"; \ echo "fi # TAG_BAREOS_FD"; \ ) >> /etc/rc.conf; \ echo ""; \ fi install-autostart-sd: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-sd /etc/rc.bareos-sd @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-sd /etc/rc.conf; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.conf already patched"; \ else \ $(RMF) /etc/rc.conf.$$today; \ cp -p /etc/rc.conf /etc/rc.conf.$$today; \ ( echo "Start the Bareos Storage daemon. Do not remove the 'TAG_BAREOS_SD' text"; \ echo "if [ -x /etc/rc.bareos-sd ]; then # TAG_BAREOS_SD"; \ echo " /etc/rc.bareos-sd start # TAG_BAREOS_SD"; \ echo "fi # TAG_BAREOS_SD"; \ ) >> /etc/rc.conf; \ echo ""; \ fi install-autostart-dir: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-dir /etc/rc.bareos-dir @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-dir /etc/rc.conf; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.conf already patched"; \ else \ $(RMF) /etc/rc.conf.$$today; \ cp -p /etc/rc.conf /etc/rc.conf.$$today; \ ( echo "Start the Bareos Director. Do not remove the 'TAG_BAREOS_DIR' text"; \ echo "if [ -x /etc/rc.bareos-dir ]; then # TAG_BAREOS_DIR"; \ echo " /etc/rc.bareos-dir start # TAG_BAREOS_DIR"; \ echo "fi # TAG_BAREOS_DIR"; \ ) >> /etc/rc.conf; \ echo ""; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec bareos-Release-14.2.6/platforms/freebsd/bareos-dir.in000066400000000000000000000015101263011562700224350ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # RETVAL=0 case "$1" in start) echo "Starting the Bareos Director: " @sbindir@/bareos-dir $2 -c @sysconfdir@/bareos-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-dir ;; stop) echo "Stopping the Director daemon: " # killproc @sbindir@/bareos-dir RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/freebsd/bareos-fd.in000066400000000000000000000014701263011562700222550ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos File daemon: " @sbindir@/bareos-fd $2 -c @sysconfdir@/bareos-fd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; stop) echo "Stopping the Bareos File daemon: " # killproc @sbindir@/bareos-fd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/freebsd/bareos-sd.in000066400000000000000000000015061263011562700222720ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos Storage daemon: " @sbindir@/bareos-sd $2 -c @sysconfdir@/bareos-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-sd ;; stop) echo "Stopping the Bareos Storage daemon: " # killproc @sbindir@/bareos-sd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/freebsd/chio-changer000066400000000000000000000126711263011562700223420ustar00rootroot00000000000000#!/bin/sh # # BAREOS interface to tape libraries and autoloaders for FreeBSD # (by Rudolf Cejka , v1.2, 2012/11/14) # # If you set in your Device resource # Changer Command = "path-to-this-script/chio-changer %c %o %S %a %d" # you will have the following input to this script: # chio-changer "changer-device" "command" "slot" "tape-device" "drive-index" # $1 $2 $3 $4 $5 # for example (on a FreeBSD system): # chio-changer /dev/ch0 load 1 /dev/nsa0 0 # # If you change the script, take care to return either the chio exit # code or a 0. If the script exits with a non-zero exit code, BAREOS # will assume the request failed. # PROGNAME=`basename $0` # Uncomment the following line, if you want to log debug output. #DEBUG=/var/run/bareos/${PROGNAME}.log # Uncomment the following line, if you need to eject a tape before moving # it from the drive. #OFFLINE=yes # Uncomment one or more of the following lines, if you need to wait for # some time (in seconds) after unloading, loading or transferring a tape. #OFFLINE_SLEEP=10 #LOAD_SLEEP=10 #MOVE_SLEEP=10 # Uncomment the following line, if you do not have a changer with volume # reader. #FAKE_BARCODES=/usr/local/etc/bareos-barcodes usage() { cat < [slot] [tape-device] [drive-index] Commands (): unload Unload a tape into the slot from where it was loaded load Load a tape from the slot (1-based) transfer Transfer a tape from the slot to the slot (1-based) list List full storage slots listall List all storage slots and drives with source information loaded Give slot from where the tape was loaded (0 = empty drive) slots Give number of available slots Example: ${PROGNAME} /dev/ch0 load 1 Load a tape from the slot 1 EOF exit 1 } # Default settings CHANGER=/dev/ch0 TAPE=/dev/nsa0 DRIVE=0 CHIO=/bin/chio MT=/usr/bin/mt if [ -n "${DEBUG}" ]; then MSG=$0 for PAR; do MSG="${MSG} \"${PAR}\""; done echo `date +"%Y/%m/%d %H:%M:%S"` ${MSG} >> ${DEBUG} fi if [ -n "$1" ]; then CHANGER=$1; fi COMMAND=$2 SLOT=$3 SLOTDST=$4 if [ -n "$4" ]; then TAPE=$4 fi if [ -n "$5" ]; then DRIVE=$5 fi case ${COMMAND} in unload) if [ "${OFFLINE}" = yes ]; then ${MT} -f ${TAPE} offline if [ $? = 0 -a -n "${OFFLINE_SLEEP}" ]; then sleep ${OFFLINE_SLEEP} fi fi if [ -z "${SLOT}" ]; then ${CHIO} -f ${CHANGER} return drive ${DRIVE} else ${CHIO} -f ${CHANGER} move drive ${DRIVE} slot $((${SLOT} - 1)) fi if [ $? -ne 0 ]; then # In case of an error, try to unload the cartridge to the first free slot FREE=`${CHIO} -f ${CHANGER} status slot | \ sed -ne '/FULL/d;s/^slot *\([0-9]*\):.*/\1/p' | \ awk 'BEGIN { n = 0 } { n = $1 + 1; exit } END { print n }'` if [ ${FREE} -gt 0 ]; then ${CHIO} -f ${CHANGER} move drive ${DRIVE} slot $((${FREE} - 1)) else exit 1 fi fi ;; load) if [ -z "${SLOT}" ]; then usage fi ${CHIO} -f ${CHANGER} move slot $((${SLOT} - 1)) drive ${DRIVE} if [ $? -ne 0 ]; then exit 1 fi if [ -n "${LOAD_SLEEP}" ]; then sleep ${LOAD_SLEEP} fi ;; transfer) if [ -z "${SLOT}" -o -z "${SLOTDST}" ]; then usage fi ${CHIO} -f ${CHANGER} move slot $((${SLOT} - 1)) slot $((${SLOTDST} - 1)) if [ $? -ne 0 ]; then exit 1 fi if [ -n "${MOVE_SLEEP}" ]; then sleep ${MOVE_SLEEP} fi ;; list) if [ -z "${FAKE_BARCODES}" ]; then ${CHIO} -f ${CHANGER} status -v slot | \ sed -ne 's/^slot *\([0-9]*\):.*FULL.*voltag.*<\([^:]*\):.*/\1:\2/p' | \ awk -F: '{ print $1 + 1 ":" $2 }' else if [ -f "${FAKE_BARCODES}" ]; then grep -v -e "^#" -e "^$" < ${FAKE_BARCODES} else echo "${PROGNAME}: Barcode file ${FAKE_BARCODES} is missing" exit 1 fi fi ;; listall) if [ -z "${FAKE_BARCODES}" ]; then ${CHIO} -f ${CHANGER} status -vS | \ sed -ne ' s/^slot *\([0-9]*\):.*ENAB.*FULL.*voltag.*<\([^:]*\):.*/I:\1:F:\2/p;t s/^slot *\([0-9]*\):.*FULL.*voltag.*<\([^:]*\):.*/S:\1:F:\2/p;t s/^drive *\([0-9]*\):.*FULL.*voltag.*<\([^:]*\):.*source.*<[^0-9]*\([0-9]*\)>.*/D:\1:F:\3:\2/p;t s/^slot *\([0-9]*\):.*ENAB.*voltag.*<\([^:]*\):.*/I:\1:E/p;t s/^slot *\([0-9]*\):.*voltag.*<\([^:]*\):.*/S:\1:E/p;t s/^drive *\([0-9]*\):.*voltag.*<\([^:]*\):.*/D:\1:E/p' | \ awk -F: '{ for (n = 1; n <= NF; n++) printf "%s%s", (n == ($1 == "D" ? 4 : 2)) ? ($n == "" ? 0 : $n + 1) : $n, (n == NF) ? "\n" : ":" }' else if [ -f "${FAKE_BARCODES}" ]; then grep -v -e "^#" -e "^$" < ${FAKE_BARCODES} | \ awk -F: '{ print "S:" $1 (match($2, "^ *$") ? ":E" : ":F:" $2) }' else echo "${PROGNAME}: Barcode file ${FAKE_BARCODES} is missing" exit 1 fi fi ;; loaded) # If a tape is loaded, but the source slot is unknown (for example, # after library reboot), try to report the first free slot FREE=`${CHIO} -f ${CHANGER} status slot | \ sed -ne '/FULL/d;s/^slot *\([0-9]*\):.*/\1/p' | \ awk 'BEGIN { n = 0 } { n = $1 + 1; exit } END { print n }'` ${CHIO} -f ${CHANGER} status -S drive | \ sed -ne 's/^drive *'${DRIVE}':.*FULL.*source.*<[^0-9]*\([0-9]*\)>.*/\1/p' \ | awk 'BEGIN { n = 0 } { n = ($1 == "") ? '${FREE}' : $1 + 1 } \ END { print n }' ;; slots) ${CHIO} -f ${CHANGER} status | grep -c "^slot " ;; *) usage ;; esac bareos-Release-14.2.6/platforms/freebsd/tapetest.c000066400000000000000000000323761263011562700220710ustar00rootroot00000000000000/* * * Program to test loss of data at EOM on * FreeBSD systems. * * Kern Sibbald, August 2003 * * If you build this program with: * * c++ -g -O2 -Wall -c tapetest.c * c++ -g -O2 -Wall tapetest.o -o tapetest * * Procedure for testing tape * ./tapetest /dev/your-tape-device * rewind * rawfill * rewind * scan * quit * * The output will be: * * ======== * Rewound /dev/nsa0 * *Begin writing blocks of 64512 bytes. * ++++++++++++++++++++ ... * Write failed. Last block written=17294. status=0 ERR=Unknown error: 0 * weof_dev * Wrote EOF to /dev/nsa0 * *Rewound /dev/nsa0 * *Starting scan at file 0 * 17294 blocks of 64512 bytes in file 0 * End of File mark. * End of File mark. * End of tape * Total files=1, blocks=17294, bytes = 1115670528 * ======== * * which is correct. Notice that the return status is * 0, while in the example below, which fails, the return * status is -1. * * If you build this program with: * * c++ -g -O2 -Wall -pthread -c tapetest.c * c++ -g -O2 -Wall -pthread tapetest.o -o tapetest * Note, we simply added -pthread compared to the * previous example. * * Procedure for testing tape * ./tapetest /dev/your-tape-device * rewind * rawfill * rewind * scan * quit * * The output will be: * * ======== * Rewound /dev/nsa0 * *Begin writing blocks of 64512 bytes. * +++++++++++++++++++++++++++++ ... * Write failed. Last block written=17926. status=-1 ERR=No space left on device * weof_dev * Wrote EOF to /dev/nsa0 * *Rewound /dev/nsa0 * *Starting scan at file 0 * 17913 blocks of 64512 bytes in file 0 * End of File mark. * End of File mark. * End of tape * Total files=1, blocks=17913, bytes = 1155603456 * ======== * * which is incroorect because it wrote 17,926 blocks but read * back only 17,913 blocks, AND because the return status on * the last block written was -1 when it should have been * 0 (ie. status=0 above). * * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define FALSE 0 #define TRUE 1 #define dev_state(dev, state) ((dev)->state & (state)) /* Device state bits */ #define ST_OPENED (1<<0) /* set when device opened */ #define ST_TAPE (1<<1) /* is a tape device */ #define ST_FILE (1<<2) /* is a file device */ #define ST_FIFO (1<<3) /* is a fifo device */ #define ST_PROG (1<<4) /* is a program device */ #define ST_LABEL (1<<5) /* label found */ #define ST_MALLOC (1<<6) /* dev packet malloc'ed in init_dev() */ #define ST_APPEND (1<<7) /* ready for Bareos append */ #define ST_READ (1<<8) /* ready for Bareos read */ #define ST_EOT (1<<9) /* at end of tape */ #define ST_WEOT (1<<10) /* Got EOT on write */ #define ST_EOF (1<<11) /* Read EOF i.e. zero bytes */ #define ST_NEXTVOL (1<<12) /* Start writing on next volume */ #define ST_SHORT (1<<13) /* Short block read */ #define BLOCK_SIZE (512 * 126) /* Exported variables */ int quit = 0; char buf[100000]; int verbose = 0; int debug_level = 0; int fd = 0; struct DEVICE { int fd; int dev_errno; int file; int block_num; int state; char *buf; int buf_len; char *dev_name; int file_addr; }; DEVICE *dev; #define uint32_t unsigned long #define uint64_t unsigned long long /* Forward referenced subroutines */ static void do_tape_cmds(); static void helpcmd(); static void scancmd(); static void rewindcmd(); static void rawfill_cmd(); /* Static variables */ static char cmd[1000]; static void usage(); int get_cmd(char *prompt); /********************************************************************* * * Main Bareos Pool Creation Program * */ int main(int argc, char *argv[]) { int ch; while ((ch = getopt(argc, argv, "d:v?")) != -1) { switch (ch) { case 'd': /* set debug level */ debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } break; case 'v': verbose++; break; case '?': default: helpcmd(); exit(0); } } argc -= optind; argv += optind; /* See if we can open a device */ if (argc == 0) { printf("No archive name specified.\n"); usage(); exit(1); } else if (argc != 1) { printf("Improper number of arguments specified.\n"); usage(); exit(1); } fd = open(argv[0], O_RDWR); if (fd < 0) { printf("Error opening %s ERR=%s\n", argv[0], strerror(errno)); exit(1); } dev = (DEVICE *)malloc(sizeof(DEVICE)); memset(dev, 0, sizeof(DEVICE)); dev->fd = fd; dev->dev_name = strdup(argv[0]); dev->buf_len = BLOCK_SIZE; dev->buf = (char *)malloc(BLOCK_SIZE); do_tape_cmds(); return 0; } int rewind_dev(DEVICE *dev) { struct mtop mt_com; if (dev->fd < 0) { dev->dev_errno = EBADF; printf("Bad call to rewind_dev. Device %s not open\n", dev->dev_name); return 0; } dev->state &= ~(ST_APPEND|ST_READ|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */ dev->block_num = dev->file = 0; mt_com.mt_op = MTREW; mt_com.mt_count = 1; if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { dev->dev_errno = errno; printf("Rewind error on %s. ERR=%s.\n", dev->dev_name, strerror(dev->dev_errno)); return 0; } return 1; } /* * Write an end of file on the device * Returns: 0 on success * non-zero on failure */ int weof_dev(DEVICE *dev, int num) { struct mtop mt_com; int status; if (dev->fd < 0) { dev->dev_errno = EBADF; printf("Bad call to fsf_dev. Archive not open\n"); return -1; } dev->state &= ~(ST_EOT | ST_EOF); /* remove EOF/EOT flags */ dev->block_num = 0; printf("weof_dev\n"); mt_com.mt_op = MTWEOF; mt_com.mt_count = num; status = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com); if (status == 0) { dev->file++; dev->file_addr = 0; } else { dev->dev_errno = errno; printf("ioctl MTWEOF error on %s. ERR=%s.\n", dev->dev_name, strerror(dev->dev_errno)); } return status; } void quitcmd() { quit = 1; } /* * Rewind the tape. */ static void rewindcmd() { if (!rewind_dev(dev)) { printf("Bad status from rewind. ERR=%s\n", strerror(dev->dev_errno)); } else { printf("Rewound %s\n", dev->dev_name); } } /* * Write and end of file on the tape */ static void weofcmd() { int status; if ((status = weof_dev(dev, 1)) < 0) { printf("Bad status from weof %d. ERR=%s\n", status, strerror(dev->dev_errno)); return; } else { printf("Wrote EOF to %s\n", dev->dev_name); } } /* * Read a record from the tape */ static void rrcmd() { char *buf; int status, len; if (!get_cmd("Enter length to read: ")) { return; } len = atoi(cmd); if (len < 0 || len > 1000000) { printf("Bad length entered, using default of 1024 bytes.\n"); len = 1024; } buf = (char *)malloc(len); status = read(fd, buf, len); if (status > 0 && status <= len) { errno = 0; } printf("Read of %d bytes gives status=%d. ERR=%s\n", len, status, strerror(errno)); free(buf); } /* * Write a record to the tape */ static void wrcmd() { int status; int rfd; rfd = open("/dev/urandom", O_RDONLY); if (rfd) { read(rfd, dev->buf, dev->buf_len); } else { printf("Cannot open /dev/urandom.\n"); return; } printf("Write one block of %u bytes.\n", dev->buf_len); status = write(dev->fd, dev->buf, dev->buf_len); if (status != (int)dev->buf_len) { if (status == -1) { printf("Bad status from write. ERR=%s\n", strerror(errno)); } else { printf("Expected to write %d bytes but wrote only %d.\n", dev->buf_len, status); } } } /* * Scan tape by reading block by block. Report what is * on the tape. Note, this command does raw reads, and as such * will not work with fixed block size devices. */ static void scancmd() { int status; int blocks, tot_blocks, tot_files; int block_size; uint64_t bytes; blocks = block_size = tot_blocks = 0; bytes = 0; if (dev->state & ST_EOT) { printf("End of tape\n"); return; } tot_files = dev->file; printf("Starting scan at file %u\n", dev->file); for (;;) { if ((status = read(dev->fd, buf, sizeof(buf))) < 0) { dev->dev_errno = errno; printf("Bad status from read %d. ERR=%s\n", status, strerror(dev->dev_errno)); if (blocks > 0) printf("%d block%s of %d bytes in file %d\n", blocks, blocks>1?"s":"", block_size, dev->file); return; } if (status != block_size) { if (blocks > 0) { printf("%d block%s of %d bytes in file %d\n", blocks, blocks>1?"s":"", block_size, dev->file); blocks = 0; } block_size = status; } if (status == 0) { /* EOF */ printf("End of File mark.\n"); /* Two reads of zero means end of tape */ if (dev->state & ST_EOF) dev->state |= ST_EOT; else { dev->state |= ST_EOF; dev->file++; } if (dev->state & ST_EOT) { printf("End of tape\n"); break; } } else { /* Got data */ dev->state &= ~ST_EOF; blocks++; tot_blocks++; bytes += status; } } tot_files = dev->file - tot_files; printf("Total files=%d, blocks=%d, bytes = %d\n", tot_files, tot_blocks, (int)bytes); } static void rawfill_cmd() { int status; int rfd; uint32_t block_num = 0; uint32_t *p; int my_errno; rfd = open("/dev/urandom", O_RDONLY); if (rfd) { read(rfd, dev->buf, dev->buf_len); } else { printf("Cannot open /dev/urandom.\n"); return; } p = (uint32_t *)dev->buf; printf("Begin writing blocks of %u bytes.\n", dev->buf_len); for ( ;; ) { *p = block_num; status = write(dev->fd, dev->buf, dev->buf_len); if (status == (int)dev->buf_len) { if ((block_num++ % 100) == 0) { printf("+"); fflush(stdout); } continue; } break; } my_errno = errno; printf("\n"); weofcmd(); printf("Write failed. Last block written=%d. status=%d ERR=%s\n", (int)block_num, status, strerror(my_errno)); } /* Strip any trailing junk from the command */ void strip_trailing_junk(char *cmd) { char *p; p = cmd + strlen(cmd) - 1; /* strip trailing junk from command */ while ((p >= cmd) && (*p == '\n' || *p == '\r' || *p == ' ')) *p-- = 0; } /* folded search for string - case insensitive */ int fstrsch(char *a, char *b) /* folded case search */ { register char *s1,*s2; register char c1=0, c2=0; s1=a; s2=b; while (*s1) { /* do it the fast way */ if ((*s1++ | 0x20) != (*s2++ | 0x20)) return 0; /* failed */ } while (*a) { /* do it over the correct slow way */ if (isupper(c1 = *a)) { c1 = tolower((int)c1); } if (isupper(c2 = *b)) { c2 = tolower((int)c2); } if (c1 != c2) { return 0; } a++; b++; } return 1; } struct cmdstruct { char *key; void (*func)(); char *help; }; static struct cmdstruct commands[] = { {"help", helpcmd, "print this command"}, {"quit", quitcmd, "quit tapetest"}, {"rawfill", rawfill_cmd, "use write() to fill tape"}, {"rewind", rewindcmd, "rewind the tape"}, {"rr", rrcmd, "raw read the tape"}, {"wr", wrcmd, "raw write one block to the tape"}, {"scan", scancmd, "read() tape block by block to EOT and report"}, {"weof", weofcmd, "write an EOF on the tape"}, }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) static void do_tape_cmds() { unsigned int i; int found; while (get_cmd("*")) { found = 0; for (i=0; i 0) cmd[--i] = 0; continue; } cmd[i++] = ch; cmd[i] = 0; } quit = 1; return 0; } bareos-Release-14.2.6/platforms/gentoo/000077500000000000000000000000001263011562700177425ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/gentoo/1.36.1-cdrecord-configure.patch000066400000000000000000000010041263011562700252460ustar00rootroot00000000000000--- configure.old 2005-02-06 07:44:05.221997769 -0500 +++ configure 2005-02-06 07:45:18.300994158 -0500 @@ -7478,15 +7478,6 @@ # get scsibus,target,lun # ------------------------------------------- CDSTL="3,0,0" -if test ! x$CDRECORD = x ; then - CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD-RW | ${AWK} '{print $1}'` - if test x${CDSTL} = x ; then - CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD+RW | ${AWK} '{print $1}'` - fi - if test x${CDSTL} = x ; then - CDSTL="3,0,0" - fi -fi bareos-Release-14.2.6/platforms/gentoo/1.36.2-cdrecord-configure.patch000066400000000000000000000011421263011562700252520ustar00rootroot00000000000000diff -uNr bareos-1.36.2/configure bareos-1.36.2-fixed/configure --- bareos-1.36.2/configure 2005-02-25 04:46:49.000000000 -0500 +++ bareos-1.36.2-fixed/configure 2005-03-06 10:11:23.905848861 -0500 @@ -7301,15 +7301,6 @@ # get scsibus,target,lun # ------------------------------------------- CDSTL="3,0,0" -if test ! x$CDRECORD = x ; then - CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD-RW | ${AWK} '{print $1}'` - if test x${CDSTL} = x ; then - CDSTL=`${CDRECORD} -scanbus 2>/dev/null | grep CD+RW | ${AWK} '{print $1}'` - fi - if test x${CDSTL} = x ; then - CDSTL="3,0,0" - fi -fi bareos-Release-14.2.6/platforms/gentoo/Makefile.in000066400000000000000000000016121263011562700220070ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Gentoo specific installation. # # 22 January 2003 -- Kern Sibbald # and corrected for Gentoo by # Patrick Naubert 25 Jan 2003 # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-fd $(DESTDIR)/etc/init.d/bareos-fd install-autostart-sd: @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-sd $(DESTDIR)/etc/init.d/bareos-sd install-autostart-dir: @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-dir $(DESTDIR)/etc/init.d/bareos-dir clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-Release-14.2.6/platforms/gentoo/bareos-dir.in000066400000000000000000000012261263011562700223220ustar00rootroot00000000000000#!/sbin/runscript # # bareos This shell script takes care of starting and stopping # the bareos Director daemon for the Gentoo release # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # start() { ebegin "Starting the Bareos Director" start-stop-daemon --start --quiet --exec @sbindir@/bareos-dir -- $2 -c @sysconfdir@/bareos-dir.conf eend $? } stop() { ebegin "Stopping the Director daemon" start-stop-daemon --stop --quiet --exec @sbindir@/bareos-dir eend $? } restart() { stop sleep 5 start } bareos-Release-14.2.6/platforms/gentoo/bareos-fd.in000066400000000000000000000012261263011562700221350ustar00rootroot00000000000000#!/sbin/runscript # # bareos This shell script takes care of starting and stopping # the bareos File daemon for the Gentoo release. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # start() { ebegin "Starting the Bareos File daemon" start-stop-daemon --start --quiet --exec @sbindir@/bareos-fd -- $2 -c @sysconfdir@/bareos-fd.conf eend $? } stop() { ebegin "Stopping the Bareos File daemon" start-stop-daemon --stop --quiet --exec @sbindir@/bareos-fd eend $? } restart() { stop sleep 5 start } bareos-Release-14.2.6/platforms/gentoo/bareos-init.in000066400000000000000000000050241263011562700225070ustar00rootroot00000000000000#!/sbin/runscript # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # Modified for user/group information # 24 Oct 2004 D. Scott Barninger # # added cdrom rescue for 1.36.1 # init script now comes from source package not ${FILES} dir # 26 Nov 2004 D. Scott Barninger # # fix symlink creation in rescue package in post script # remove mask on x86 keyword # fix post script so it doesn't talk about server config for client-only build # bug #181 - unable to reproduce on 2.4 kernel system so add FEATURES="-sandbox" # 04 Dec 2004 D. Scott Barninger # # more on bug #181 - another user has reported a sandbox violation trying to # write to /dev/sg0 - still can't reproduce this behavior # add an 'addpredict /dev/sg0' # 08 Dec 2004 D. Scott Barninger # # resolve bug #181 - problem is caused by configure calling cdrecord to scan # the scsi bus. patch configure to remove this. add logrotate script. # 06 Feb 2005 D. Scott Barninger # # fix documentation bug # 07 Feb 2005 D. Scott Barninger # # new USE keywords bareos-clientonly bareos-split # add new logwatch scripts # 06 Mar 2005 D. Scott Barninger # # 1.36.3 doc changes # 17 Apr 2005 D. Scott Barninger DESCRIPTION="featureful client/server network backup suite" HOMEPAGE="http://www.bareos.org/" SRC_URI="mirror://sourceforge/bareos/${P}.tar.gz" LICENSE="GPL-2" SLOT="0" KEYWORDS="x86 ~ppc ~sparc ~amd64" IUSE="readline tcpd gnome mysql sqlite X static postgres wxwindows bareos-clientonly bareos-split" inherit eutils # there is a local sqlite use flag. use it -OR- mysql, not both. # mysql is the recommended choice ... # may need sys-libs/libtermcap-compat but try without first DEPEND=">=sys-libs/zlib-1.1.4 readline? ( >=sys-libs/readline-4.1 ) tcpd? ( >=sys-apps/tcp-wrappers-7.6 ) gnome? ( gnome-base/libgnome ) gnome? ( app-admin/gnomesu ) !bareos-clientonly? ( sqlite? ( =dev-db/sqlite-2* ) mysql? ( >=dev-db/mysql-3.23 ) postgres? ( >=dev-db/postgresql-7.4.0 ) sys-apps/mtx ) X? ( virtual/x11 ) wxwindows? ( >=x11-libs/wxGTK-2.4.2 ) virtual/mta dev-libs/gmp app-text/tetex dev-tex/latex2html" RDEPEND="${DEPEND} !bareos-clientonly? ( sys-apps/mtx app-arch/mt-st )" src_compile() { # this resolves bug #181 epatch ${FILESDIR}/1.36.2-cdrecord-configure.patch local myconf="" myconf=" `use_enable readline` `use_enable gnome` `use_enable tcpd tcp-wrappers` `use_enable X x`" # define this to skip building the other daemons ... if use bareos-clientonly then myconf="${myconf} --enable-client-only" fi # select database support if ! use bareos-clientonly then # mysql is the recomended choice ... if use mysql then myconf="${myconf} --with-mysql=/usr" elif use postgres then myconf="${myconf} --with-postgresql=/usr" elif use sqlite then myconf="${myconf} --with-sqlite=/usr" elif use sqlite && use mysql then myconf="${myconf/--with-sqlite/}" fi fi if use wxwindows then myconf="${myconf} --enable-wx-console" fi if use readline then myconf="${myconf} --enable-readline" fi if use gnome then myconf="${myconf} --enable-traymonitor" fi ./configure \ --enable-smartalloc \ --prefix=/usr \ --mandir=/usr/share/man \ --with-pid-dir=/var/run \ --sysconfdir=/etc/bareos \ --infodir=/usr/share/info \ --with-subsys-dir=/var/lock/subsys \ --with-working-dir=/var/bareos \ --with-scriptdir=/etc/bareos \ --with-dir-user=root \ --with-dir-group=bareos \ --with-sd-user=root \ --with-sd-group=bareos \ --with-fd-user=root \ --with-fd-group=bareos \ --host=${CHOST} ${myconf} || die "bad ./configure" emake || die "compile problem" # for the rescue package regardless of use static cd ${S}/src/filed make static-bareos-fd cd ${S} # make the docs cd ${S}/doc/latex make cd ${S} if use static then cd ${S}/src/console make static-console cd ${S}/src/dird make static-bareos-dir if use gnome then cd ${S}/src/gnome-console make static-gnome-console fi if use wxwindows then cd ${S}/src/wx-console make static-wx-console fi cd ${S}/src/stored make static-bareos-sd fi } src_install() { make DESTDIR=${D} install || die if use static then cd ${S}/src/filed cp static-bareos-fd ${D}/usr/sbin/bareos-fd cd ${S}/src/console cp static-console ${D}/usr/sbin/console cd ${S}/src/dird cp static-bareos-dir ${D}/usr/sbin/bareos-dir if use gnome then cd ${S}/src/gnome-console cp static-gnome-console ${D}/usr/sbin/gnome-console fi if use wxwindows then cd ${S}/src/wx-console cp static-wx-console ${D}/usr/sbin/wx-console fi cd ${S}/src/stored cp static-bareos-sd ${D}/usr/sbin/bareos-sd fi # the menu stuff if use gnome then mkdir -p ${D}/usr/share/pixmaps mkdir -p ${D}/usr/share/applications cp ${S}/scripts/bareos.png ${D}/usr/share/pixmaps/bareos.png cp ${S}/scripts/bareos.desktop.gnome2.xsu ${D}/usr/share/applications/bareos.desktop cp ${S}/src/tray-monitor/generic.xpm ${D}/usr/share/pixmaps/bareos-tray-monitor.xpm cp ${S}/scripts/bareos-tray-monitor.desktop \ ${D}/usr/share/applications/bareos-tray-monitor.desktop chmod 755 ${D}/usr/sbin/bareos-tray-monitor chmod 644 ${D}/etc/bareos/tray-monitor.conf fi if ! use bareos-clientonly then # the database update scripts mkdir -p ${D}/etc/bareos/updatedb cp ${S}/updatedb/* ${D}/etc/bareos/updatedb/ chmod 754 ${D}/etc/bareos/updatedb/* # the logrotate configuration mkdir -p ${D}/etc/logrotate.d cp ${S}/scripts/logrotate ${D}/etc/logrotate.d/bareos chmod 644 ${D}/etc/logrotate.d/bareos # the logwatch scripts mkdir -p ${D}/etc/log.d/conf/logfiles mkdir -p ${D}/etc/log.d/conf/services mkdir -p ${D}/etc/log.d/scripts/services cp ${S}/scripts/logwatch/bareos ${D}/etc/log.d/scripts/services/bareos cp ${S}/scripts/logwatch/logfile.bareos.conf ${D}/etc/log.d/conf/logfiles/bareos.conf cp ${S}/scripts/logwatch/services.bareos.conf ${D}/etc/log.d/conf/services/bareos.conf chmod 755 ${D}/etc/log.d/scripts/services/bareos chmod 644 ${D}/etc/log.d/conf/logfiles/bareos.conf chmod 644 ${D}/etc/log.d/conf/services/bareos.conf fi # the cdrom rescue package mkdir -p ${D}/etc/bareos/rescue/cdrom cp -R ${S}/rescue/linux/cdrom/* ${D}/etc/bareos/rescue/cdrom/ mkdir ${D}/etc/bareos/rescue/cdrom/bin cp ${S}/src/filed/static-bareos-fd ${D}/etc/bareos/rescue/cdrom/bin/bareos-fd chmod 754 ${D}/etc/bareos/rescue/cdrom/bin/bareos-fd # documentation for a in ${S}/{ChangeLog,README,ReleaseNotes,kernstodo,LICENSE,doc/latex/bareos.pdf} do dodoc $a done dohtml -r ${S}/doc/latex/bareos # clean up permissions left broken by install chmod o-r ${D}/etc/bareos/query.sql # remove the working dir so we can add it postinst with group rmdir ${D}/var/bareos # init scripts exeinto /etc/init.d if use bareos-clientonly then newexe ${S}/platforms/gentoo/bareos-fd bareos-fd else if use bareos-split then newexe ${S}/platforms/gentoo/bareos-fd bareos-fd newexe ${S}/platforms/gentoo/bareos-sd bareos-sd newexe ${S}/platforms/gentoo/bareos-dir bareos-dir else newexe ${S}/platforms/gentoo/bareos-init bareos fi fi } pkg_postinst() { # create the daemon group HAVE_BAREOS=`cat /etc/group | grep bareos 2>/dev/null` if [ -z $HAVE_BAREOS ]; then enewgroup bareos einfo einfo "The group bareos has been created. Any users you add to" einfo "this group have access to files created by the daemons." fi # the working directory install -m0750 -o root -g bareos -d ${ROOT}/var/bareos # link installed bareos-fd.conf into rescue directory #ln -s /etc/bareos/bareos-fd.conf /etc/bareos/rescue/cdrom/bareos-fd.conf # no longer necessary after 1.36.2 einfo einfo "The CDRom rescue disk package has been installed into the" einfo "/etc/bareos/rescue/cdrom/ directory. Please examine the manual" einfo "for information on creating a rescue CD. CDR device detection" einfo "during build has been disabled to prevent sandbox violations." einfo "You need to examine /etc/bareos/rescue/cdrom/Makefile and adjust" einfo "the device information for your CD recorder." einfo if ! use bareos-clientonly; then einfo einfo "Please note either/or nature of database USE flags for" einfo "Bareos. If mysql is set, it will be used, else postgres" einfo "else finally SQLite. If you wish to have multiple DBs on" einfo "one system, you may wish to unset auxillary DBs for this" einfo "build." einfo if use mysql then # test for an existing database # note: this ASSUMES no password has been set for bareos database DB_VER=`mysql 2>/dev/null bareos -e 'select * from Version;'|tail -n 1` if [ -z "$DB_VER" ]; then einfo "This appears to be a new install and you plan to use mysql" einfo "for your catalog database. You should now create it by doing" einfo "these commands:" einfo " sh /etc/bareos/grant_mysql_privileges" einfo " sh /etc/bareos/create_mysql_database" einfo " sh /etc/bareos/make_mysql_tables" elif [ "$DB_VER" -lt "8" ]; then elinfo "This release requires an upgrade to your bareos database" einfo "as the database format has changed. Please read the" einfo "manual chapter for how to upgrade your database!!!" einfo einfo "Backup your database with the command:" einfo " mysqldump -f --opt bareos | bzip2 > /var/bareos/bareos_backup.sql.bz" einfo einfo "Then update your database using the scripts found in" einfo "/etc/bareos/updatedb/ from your current version $DB_VER to" einfo "version 8. Note that scripts must be run in order from your" einfo "version to the current version." fi fi if use postgres then # test for an existing database # note: this ASSUMES no password has been set for bareos database DB_VER=`echo 'select * from Version;' | psql bareos 2>/dev/null | tail -3 | head -1` if [ -z "$DB_VER" ]; then einfo "This appears to be a new install and you plan to use postgresql" einfo "for your catalog database. You should now create it by doing" einfo "these commands:" einfo " sh /etc/bareos/create_postgresql_database" einfo " sh /etc/bareos/make_postgresql_tables" einfo " sh /etc/bareos/grant_postgresql_privileges" elif [ "$DB_VER" -lt "8" ]; then elinfo "This release requires an upgrade to your bareos database" einfo "as the database format has changed. Please read the" einfo "manual chapter for how to upgrade your database!!!" einfo einfo "Backup your database with the command:" einfo " pg_dump bareos | bzip2 > /var/bareos/bareos_backup.sql.bz2" einfo einfo "Then update your database using the scripts found in" einfo "/etc/bareos/updatedb/ from your current version $DB_VER to" einfo "version 8. Note that scripts must be run in order from your" einfo "version to the current version." fi fi if use sqlite then # test for an existing database # note: this ASSUMES no password has been set for bareos database DB_VER=`echo "select * from Version;" | sqlite 2>/dev/null /var/bareos/bareos.db | tail -n 1` if [ -z "$DB_VER" ]; then einfo "This appears to be a new install and you plan to use sqlite" einfo "for your catalog database. You should now create it by doing" einfo "these commands:" einfo " sh /etc/bareos/grant_sqlite_privileges" einfo " sh /etc/bareos/create_sqlite_database" einfo " sh /etc/bareos/make_sqlite_tables" elif [ "$DB_VER" -lt "8" ]; then elinfo "This release requires an upgrade to your bareos database" einfo "as the database format has changed. Please read the" einfo "manual chapter for how to upgrade your database!!!" einfo einfo "Backup your database with the command:" einfo " echo .dump | sqlite /var/bareos/bareos.db | bzip2 > \\" einfo " /var/bareos/bareos_backup.sql.bz2" einfo einfo "Then update your database using the scripts found in" einfo "/etc/bareos/updatedb/ from your current version $DB_VER to" einfo "version 8. Note that scripts must be run in order from your" einfo "version to the current version." fi fi fi einfo einfo "Review your configuration files in /etc/bareos and" einfo "start the daemons:" if use bareos-clientonly; then einfo " /etc/init.d/bareos-fd start" else if use bareos-split; then einfo " /etc/init.d/bareos-sd start" einfo " /etc/init.d/bareos-dir start" einfo " /etc/init.d/bareos-fd start" einfo " or /etc/bareos/bareos will start all three." else einfo " /etc/init.d/bareos start" fi fi einfo einfo "You may also wish to:" if use bareos-clientonly; then einfo " rc-update add bareos-fd default" else if use bareos-split; then einfo " rc-update add bareos-sd default" einfo " rc-update add bareos-dir default" einfo " rc-update add bareos-fd default" else einfo " rc-update add bareos default" fi fi einfo } bareos-Release-14.2.6/platforms/hurd/000077500000000000000000000000001263011562700174115ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/hurd/Makefile.in000066400000000000000000000031041263011562700214540ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Debian GNU Hurd specific installation. # # 21 March 2008 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install_logrotate: @$(MKDIR) $(DESTDIR)/etc/logrotate.d @$(INSTALL_DATA) ../../scripts/logrotate $(DESTDIR)/etc/logrotate.d/bareos-dir install-autostart-fd: @echo "Installing bareos-fd boot script ..." @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-fd $(DESTDIR)/etc/init.d/bareos-fd @echo "Installing bareos-fd symlinks ..." @if test x$(DESTDIR) = x ; then \ /usr/sbin/update-rc.d bareos-fd start 91 2 3 4 5 . stop 9 0 1 6 .; \ fi install-autostart-sd: @echo "Installing bareos-sd boot script ..." @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-sd $(DESTDIR)/etc/init.d/bareos-sd @echo "Installing bareos-sd symlinks ..." @if test "x$(DESTDIR)" = "x" ; then \ /usr/sbin/update-rc.d bareos-sd start 91 2 3 4 5 . stop 9 0 1 6 .; \ fi install-autostart-dir: @echo "Installing bareos-dir boot script ..." @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-dir $(DESTDIR)/etc/init.d/bareos-dir @echo "Installing bareos-dir symlinks ..." @if test "x$(DESTDIR)" = "x" ; then \ /usr/sbin/update-rc.d bareos-dir start 90 2 3 4 5 . stop 9 0 1 6 .; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) Makefile @$(RMF) bareos-sd bareos-fd bareos-dir devclean: clean @$(RMF) Makefile @$(RMF) bareos-sd bareos-fd bareos-dir bareos-Release-14.2.6/platforms/hurd/bareos-dir.in000066400000000000000000000032641263011562700217750ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon on Debian GNU Hurd systems. # # Kern E. Sibbald - 21 March 2008 # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # ### BEGIN INIT INFO # Provides: bareos-dir # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start @BAREOS@ Director daemon at boot time # Description: Enable @BAREOS@ Director. ### END INIT INFO # NAME="bareos-dir" DESC="@BAREOS@ Director" DAEMON=@sbindir@/${NAME} BUSER=@dir_user@ BGROUP=@dir_group@ BOPTIONS="-c @sysconfdir@/${NAME}.conf" BPORT=@dir_port@ PATH=/sbin:/bin:/usr/sbin:/usr/bin test -f $DAEMON || exit 0 if [ -n "`getent services ${NAME}`" ]; then BPORT=`getent services ${NAME} | awk '{ gsub("/tcp","",$2); print $2; }'` fi if [ -f /etc/default/$NAME ]; then . /etc/default/$NAME fi PIDFILE=@piddir@/${NAME}.${BPORT}.pid if [ "x${BUSER}" != "x" ]; then USERGRP="--chuid ${BUSER}" if [ "x${BGROUP}" != "x" ]; then USERGRP="${USERGRP}:${BGROUP}" fi fi case "$1" in start) echo -n "Starting ${DESC}: " start-stop-daemon --start --quiet --pidfile ${PIDFILE} ${USERGRP} --exec ${DAEMON} -- ${BOPTIONS} RETVAL=$? echo "${NAME}" ;; stop) echo -n "Stopping ${DESC}: " start-stop-daemon --oknodo --stop --quiet ${USERGRP} --exec ${DAEMON} -- ${BOPTIONS} RETVAL=$? echo "${NAME}" ;; restart|force-reload) $0 stop sleep 5 $0 start ;; *) echo "Usage: /etc/init.d/${NAME} {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit $RETVAL bareos-Release-14.2.6/platforms/hurd/bareos-fd.in000066400000000000000000000032551263011562700216100ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon on Debian GNU Hurd systems. # # Kern E. Sibbald - 21 March 2008 # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # ### BEGIN INIT INFO # Provides: bareos-fd # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start @BAREOS@ Client daemon at boot time # Description: Enable @BAREOS@ Client. ### END INIT INFO NAME="bareos-fd" DESC="@BAREOS@ File Daemon" DAEMON=@sbindir@/${NAME} BUSER=@fd_user@ BGROUP=@fd_group@ BOPTIONS="-c @sysconfdir@/${NAME}.conf" BPORT=@fd_port@ PATH=/sbin:/bin:/usr/sbin:/usr/bin test -f $DAEMON || exit 0 if [ -n "`getent services ${NAME}`" ]; then BPORT=`getent services ${NAME} | awk '{ gsub("/tcp","",$2); print $2; }'` fi if [ -f /etc/default/$NAME ]; then . /etc/default/$NAME fi PIDFILE=@piddir@/${NAME}.${BPORT}.pid if [ "x${BUSER}" != "x" ]; then USERGRP="--chuid ${BUSER}" if [ "x${BGROUP}" != "x" ]; then USERGRP="${USERGRP}:${BGROUP}" fi fi case "$1" in start) echo -n "Starting ${DESC}: " start-stop-daemon --start --quiet --pidfile ${PIDFILE} ${USERGRP} --exec ${DAEMON} -- ${BOPTIONS} RETVAL=$? echo "${NAME}" ;; stop) echo -n "Stopping ${DESC}: " start-stop-daemon --oknodo --stop --quiet ${USERGRP} --exec ${DAEMON} -- ${BOPTIONS} RETVAL=$? echo "${NAME}" ;; restart|force-reload) $0 stop sleep 5 $0 start ;; *) echo "Usage: /etc/init.d/${NAME} {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit $RETVAL bareos-Release-14.2.6/platforms/hurd/bareos-sd.in000066400000000000000000000032721263011562700216240ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon on Debian GNU Hurd systems. # # Kern E. Sibbald - 21 March 2008 # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # ### BEGIN INIT INFO # Provides: bareos-sd # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start @BAREOS@ Storage daemon at boot time # Description: Enable @BAREOS@ Storage daemon. ### END INIT INFO NAME="bareos-sd" DESC="@BAREOS@ Storage Daemon" DAEMON=@sbindir@/${NAME} BUSER=@sd_user@ BGROUP=@sd_group@ BOPTIONS="-c @sysconfdir@/${NAME}.conf" BPORT=@sd_port@ PATH=/sbin:/bin:/usr/sbin:/usr/bin test -f $DAEMON || exit 0 if [ -n "`getent services ${NAME}`" ]; then BPORT=`getent services ${NAME} | awk '{ gsub("/tcp","",$2); print $2; }'` fi if [ -f /etc/default/$NAME ]; then . /etc/default/$NAME fi PIDFILE=@piddir@/${NAME}.${BPORT}.pid if [ "x${BUSER}" != "x" ]; then USERGRP="--chuid ${BUSER}" if [ "x${BGROUP}" != "x" ]; then USERGRP="${USERGRP}:${BGROUP}" fi fi case "$1" in start) echo -n "Starting ${DESC}: " start-stop-daemon --start --quiet --pidfile ${PIDFILE} ${USERGRP} --exec ${DAEMON} -- ${BOPTIONS} RETVAL=$? echo "${NAME}" ;; stop) echo -n "Stopping ${DESC}: " start-stop-daemon --oknodo --stop --quiet ${USERGRP} --exec ${DAEMON} -- ${BOPTIONS} RETVAL=$? echo "${NAME}" ;; restart|force-reload) $0 stop sleep 5 $0 start ;; *) echo "Usage: /etc/init.d/${NAME} {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit $RETVAL bareos-Release-14.2.6/platforms/irix/000077500000000000000000000000001263011562700174225ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/irix/Makefile.in000066400000000000000000000034051263011562700214710ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Solaris specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @$(RMF) /etc/rc0.d/K20bareos-fd @$(RMF) /etc/rc1.d/S99bareos-fd @$(RMF) /etc/rc2.d/S99bareos-fd @$(MKDIR) /etc/init.d @$(INSTALL_PROGRAM) bareos-fd /etc/init.d/bareos-fd # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-fd /etc/rc0.d/K20bareos-fd @ln -f -s /etc/init.d/bareos-fd /etc/rc1.d/S99bareos-fd @ln -f -s /etc/init.d/bareos-fd /etc/rc2.d/S99bareos-fd install-autostart-sd: @$(RMF) /etc/rc0.d/K20bareos-sd @$(RMF) /etc/rc1.d/S99bareos-sd @$(RMF) /etc/rc2.d/S99bareos-sd @$(MKDIR) /etc/init.d @$(INSTALL_PROGRAM) bareos-sd /etc/rc.d/init.d/bareos-sd # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-sd /etc/rc0.d/K20bareos-sd @ln -f -s /etc/init.d/bareos-sd /etc/rc1.d/S99bareos-sd @ln -f -s /etc/init.d/bareos-sd /etc/rc2.d/S99bareos-sd install-autostart-dir: @$(RMF) /etc/rc0.d/K20bareos-dir @$(RMF) /etc/rc1.d/S99bareos-dir @$(RMF) /etc/rc2.d/S99bareos-dir @$(MKDIR) /etc/init.d @$(INSTALL_PROGRAM) bareos-dir /etc/rc.d/init.d/bareos-dir # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-dir /etc/rc0.d/K20bareos-dir @ln -f -s /etc/init.d/bareos-dir /etc/rc1.d/S99bareos-dir @ln -f -s /etc/init.d/bareos-dir /etc/rc2.d/S99bareos-dir clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec bareos-Release-14.2.6/platforms/irix/bareos-dir.in000066400000000000000000000015101263011562700217760ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # RETVAL=0 case "$1" in start) echo "Starting the Bareos Director: " @sbindir@/bareos-dir $2 -c @sysconfdir@/bareos-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-dir ;; stop) echo "Stopping the Director daemon: " # killproc @sbindir@/bareos-dir RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/irix/bareos-fd.in000066400000000000000000000016631263011562700216220ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in 'start') echo "Starting the Bareos File daemon: " if test -x @sbindir@/bareos-fd && test -f @sysconfidir@/bareos-fd.conf; then exec @sbindir@/bareos-fd $2 -c @sysconfdir@/bareos-fd.conf fi RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; 'stop') echo "Stopping the Bareos File daemon: " /sbin/killall -k 10 -TERM @sbindir@/bareos-fd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; 'restart') $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/irix/bareos-sd.in000066400000000000000000000015061263011562700216330ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos Storage daemon: " @sbindir@/bareos-sd $2 -c @sysconfdir@/bareos-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-sd ;; stop) echo "Stopping the Bareos Storage daemon: " # killproc @sbindir@/bareos-sd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/mandrake/000077500000000000000000000000001263011562700202315ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/mandrake/Makefile.in000066400000000000000000000032251263011562700223000ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Mandrake specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bareos-fd; then \ /sbin/chkconfig --del bareos-fd; \ fi @$(MKDIR) $(DESTDIR)/etc/rc.d/init.d @$(INSTALL_PROGRAM) bareos-fd $(DESTDIR)/etc/rc.d/init.d/bareos-fd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-fd; \ fi install-autostart-sd: @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bareos-sd; then \ /sbin/chkconfig --del bareos-sd; \ fi @$(MKDIR) $(DESTDIR)/etc/rc.d/init.d @$(INSTALL_PROGRAM) bareos-sd $(DESTDIR)/etc/rc.d/init.d/bareos-sd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-sd; \ fi install-autostart-dir: @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bareos-dir; then \ /sbin/chkconfig --del bareos-dir; \ fi @$(MKDIR) $(DESTDIR)/etc/rc.d/init.d @$(INSTALL_PROGRAM) bareos-dir $(DESTDIR)/etc/rc.d/init.d/bareos-dir # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-dir; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) Makefile bareos-*.spec bareos.*.spec bareos.spec @$(RMF) bareos-sd bareos-fd bareos-dir devclean: clean @$(RMF) Makefile bareos-*.spec bareos.*.spec bareos.spec @$(RMF) bareos-sd bareos-fd bareos-dir bareos-Release-14.2.6/platforms/mandrake/bareos-dir.in000066400000000000000000000017151263011562700226140ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/init.d/functions RETVAL=0 case "$1" in start) echo -n "Starting the Bareos Director: " daemon @sbindir@/bareos-dir $2 -c @sysconfdir@/bareos-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-dir ;; stop) echo -n "Stopping the Director daemon: " killproc @sbindir@/bareos-dir RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-dir ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/mandrake/bareos-fd.in000066400000000000000000000017011263011562700224220ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/init.d/functions case "$1" in start) echo -n "Starting the Bareos File daemon: " daemon @sbindir@/bareos-fd $2 -c @sysconfdir@/bareos-fd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; stop) echo -n "Stopping the Bareos File daemon: " killproc @sbindir@/bareos-fd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-fd ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/mandrake/bareos-sd.in000066400000000000000000000017121263011562700224410ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/init.d/functions case "$1" in start) echo -n "Starting the Bareos Storage daemon: " daemon @sbindir@/bareos-sd $2 -c @sysconfdir@/bareos-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-sd ;; stop) echo -n "Stopping the Bareos Storage daemon: " killproc @sbindir@/bareos-sd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-sd ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/openbsd/000077500000000000000000000000001263011562700201015ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/openbsd/Makefile.in000066400000000000000000000047611263011562700221560ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Solaris specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ VPATH = @srcdir@ SED = /usr/bin/sed nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-fd /etc/rc.bareos-fd @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-fd /etc/rc.local; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.local already patched"; \ else \ $(RMF) /etc/rc.local.$$today; \ cp -p /etc/rc.local /etc/rc.local.$$today; \ ( echo "Start the Bareos File daemon. Do not remove the 'TAG_BAREOS_FD' text"; \ echo "if [ -x /etc/rc.bareos-fd ]; then # TAG_BAREOS_FD"; \ echo " /etc/rc.bareos-fd start # TAG_BAREOS_FD"; \ echo "fi # TAG_BAREOS_FD"; \ ) >> /etc/rc.local; \ echo ""; \ fi install-autostart-sd: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-sd /etc/rc.bareos-sd @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-sd /etc/rc.local; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.local already patched"; \ else \ $(RMF) /etc/rc.local.$$today; \ cp -p /etc/rc.local /etc/rc.local.$$today; \ ( echo "Start the Bareos Storage daemon. Do not remove the 'TAG_BAREOS_SD' text"; \ echo "if [ -x /etc/rc.bareos-fd ]; then # TAG_BAREOS_SD"; \ echo " /etc/rc.bareos-fd start # TAG_BAREOS_SD"; \ echo "fi # TAG_BAREOS_SD"; \ ) >> /etc/rc.local; \ echo ""; \ fi install-autostart-dir: @echo "FreeBSD platform installation" $(INSTALL_PROGRAM) bareos-dir /etc/rc.bareos-dir @-today="`date +%Y%m%d%H%M`"; \ grep -q /etc/rc.bareos-dir /etc/rc.local; \ if [ $$? -eq 0 ]; then \ echo "/etc/rc.local already patched"; \ else \ $(RMF) /etc/rc.local.$$today; \ cp -p /etc/rc.local /etc/rc.local.$$today; \ ( echo "Start the Bareos Director. Do not remove the 'TAG_BAREOS_DIR' text"; \ echo "if [ -x /etc/rc.bareos-dir ]; then # TAG_BAREOS_DIR"; \ echo " /etc/rc.bareos-dir start # TAG_BAREOS_DIR"; \ echo "fi # TAG_BAREOS_DIR"; \ ) >> /etc/rc.local; \ echo ""; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec bareos-Release-14.2.6/platforms/openbsd/bareos-dir.in000066400000000000000000000015101263011562700224550ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # RETVAL=0 case "$1" in start) echo "Starting the Bareos Director: " @sbindir@/bareos-dir $2 -c @sysconfdir@/bareos-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-dir ;; stop) echo "Stopping the Director daemon: " # killproc @sbindir@/bareos-dir RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/openbsd/bareos-fd.in000066400000000000000000000014701263011562700222750ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos File daemon: " @sbindir@/bareos-fd $2 -c @sysconfdir@/bareos-fd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; stop) echo "Stopping the Bareos File daemon: " # killproc @sbindir@/bareos-fd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/openbsd/bareos-sd.in000066400000000000000000000015061263011562700223120ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # case "$1" in start) echo "Starting the Bareos Storage daemon: " @sbindir@/bareos-sd $2 -c @sysconfdir@/bareos-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-sd ;; stop) echo "Stopping the Bareos Storage daemon: " # killproc @sbindir@/bareos-sd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/openbsd/chio-changer000066400000000000000000000065071263011562700223630ustar00rootroot00000000000000#!/bin/sh # # Bareos interface to chio(1) autoloader for OpenBSD # # Adapted from NetBSD pkgsrc by Antoine Jacoutot for OpenBSD. # Tested on an LTO-4 device with 1 drive and 8 slots. # The user BAREOS is running as needs rw access to the ch(4) and st(4) # devices. # # If you set in your Device resource: # Changer Command = "/path/to/chio-changer-openbsd %c %o %S %a %d" # you will have the following input to this script: # chio-changer-openbsd "changer-device" "command" "slot" "archive-device" "drive-index" # $1 $2 $3 $4 $5 # # So BAREOS will always call with all the following arguments, even though # in come cases, not all are used. # # N.B. If you change the script, take care to return either # the chio exit code or a 0. If the script exits with a non-zero # exit code, BAREOS will assume the request failed. # time (in seconds) for the unit to settle after (un)loading a tape SLEEP=1 CHIO=/bin/chio usage() { echo "usage: ${0##*/} ctl-device command [slot archive-device drive-index]" } # check parameters count check_parm_count() { pCount=$1 pCountNeed=$2 if test ${pCount} -lt ${pCountNeed}; then usage echo "!!! insufficient number of arguments given" exit 1 if test ${pCount} -lt 2; then usage echo "!!! mimimum usage is the first two arguments" exit 1 else usage echo "!!! command expected ${pCountNeed} arguments" exit 1 fi usage exit 1 fi } # check arguments count for specific actions case $2 in list|listall) check_parm_count $# 2 ;; slots) check_parm_count $# 2 ;; transfer) check_parm_count $# 4 ;; *) check_parm_count $# 5 ;; esac # get arguments ctl=$1 cmd="$2" slot=$3 device=$4 drive=$5 case ${cmd} in unload) ${CHIO} -f ${ctl} move drive ${drive} slot $((${slot} - 1)) rtn=$? [ ${rtn} -eq 0 ] && sleep ${SLEEP} exit ${rtn} ;; load) ${CHIO} -f ${ctl} move slot $((${slot} - 1)) drive ${drive} rtn=$? [ ${rtn} -eq 0 ] && sleep ${SLEEP} exit ${rtn} ;; list) ${CHIO} -f ${ctl} status -v slot | \ sed -ne 's/^slot *\([0-9]*:\).*FULL.*voltag.*<\(.*\):.*/\1\2/p' | \ awk -F: '{ print $1 + 1 ":" $2 }' exit $? ;; listall) # XXX only one drive is queried _list=$(${0} ${1} list) _loaded_s=$(${0} ${1} loaded ${slot} ${device} ${drive}) _loaded_t=$(${CHIO} -f ${ctl} status -v | grep "drive ${drive}" | awk '{ print $NF }' | sed -e 's,<,,' -e 's,:.*,,') [ -n "${_list}" -a -n "${_loaded_s}" -a -n "${_loaded_t}" ] || exit 1 (for i in ${_list}; do echo "S:${i}" | sed 's/\(.*\):/\1:F:/' done echo S:${_loaded_s}:E if [ "${_loaded_s}" -ne 0 ]; then echo D:${drive}:F:${_loaded_s}:${_loaded_t} else echo D:${drive}:E fi) | sort ;; loaded) # XXX output the first empty slot if the drive is loaded _slot=$(${CHIO} -f ${ctl} status -v | egrep '^slot.* voltag: <:[0-9]>$' | awk '{ print $2 }' | awk -F: '{ print $1 + 1 }') rtn=$? _loaded=$(${CHIO} -f ${ctl} status -v | egrep "^drive ${drive}: voltag: <.*:[0-9]>") [ -z "${_slot}" -o -z "${_loaded}" ] && _slot=0 echo ${_slot} | awk '{ print $1 }' exit ${rtn} ;; slots) ${CHIO} -f ${ctl} params | awk "/slots/{print \$2}" exit $? ;; transfer) slotdest=${device} ${CHIO} -f ${ctl} move slot $((${slot} - 1)) slot ${slotdest} exit $? ;; esac bareos-Release-14.2.6/platforms/opsi/000077500000000000000000000000001263011562700174215ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/opsi/CLIENT_DATA/000077500000000000000000000000001263011562700211705ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/opsi/CLIENT_DATA/delsub3264.ins000066400000000000000000000053161263011562700235050ustar00rootroot00000000000000; Copyright (c) uib gmbh (www.uib.de) ; This sourcecode is owned by uib gmbh ; and published under the Terms of the General Public License. ; credits: http://www.opsi.org/en/credits/ Set $UninstallProgram32$ = $InstallDir32$ + "\uninst.exe" Set $UninstallProgram64$ = $InstallDir64$ + "\uninst.exe" if (($INST_SystemType$ = "x86 System") and ($INST_architecture$ = "system specific")) or ($INST_architecture$ = "both") or ($INST_architecture$ = "32 only") Message "Uninstalling " + $ProductId$ + " 32 Bit..." if FileExists($UninstallProgram32$) comment "Uninstall program found, starting uninstall" Winbatch_uninstall_32 /WaitForProcessEnding "Au_.exe" /TimeOutSeconds "60" sub_check_exitcode endif ;comment "Delete files" ;Files_uninstall_32 /32Bit ;comment "Cleanup registry" ;Registry_uninstall /32Bit endif if ($INST_SystemType$ = "64 Bit System") and (($INST_architecture$ = "system specific") or ($INST_architecture$ = "both") or ($INST_architecture$ = "64 only")) Message "Uninstalling " + $ProductId$ + " 64 Bit..." if FileExists($UninstallProgram64$) comment "Uninstall program found, starting uninstall" Winbatch_uninstall_64 /WaitForProcessEnding "Au_.exe" /TimeOutSeconds "60" sub_check_exitcode endif ;comment "Delete files" ;Files_uninstall_64 /64Bit ;comment "Cleanup registry" ;Registry_uninstall /64Bit endif ;comment "Delete program shortcuts" ;LinkFolder_uninstall [Winbatch_uninstall_32] "$UninstallProgram32$" /S $keep_config$ [Winbatch_uninstall_64] "$UninstallProgram64$" /S $keep_config$ [Sub_check_exitcode] comment "Test for installation success via exit code" set $ExitCode$ = getLastExitCode ; informations to exit codes see ; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx ; http://msdn.microsoft.com/en-us/library/aa368542.aspx if ($ExitCode$ = "0") comment "Looks good: setup program gives exitcode zero" else comment "Setup program gives a exitcode unequal zero: " + $ExitCode$ if ($ExitCode$ = "1605") comment "ERROR_UNKNOWN_PRODUCT 1605 This action is only valid for products that are currently installed." comment "Uninstall of a not installed product failed - no problem" else if ($ExitCode$ = "1641") comment "looks good: setup program gives exitcode 1641" comment "ERROR_SUCCESS_REBOOT_INITIATED 1641 The installer has initiated a restart. This message is indicative of a success." else if ($ExitCode$ = "3010") comment "looks good: setup program gives exitcode 3010" comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010 A restart is required to complete the install. This message is indicative of a success." else logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$ isFatalError endif endif endif endif bareos-Release-14.2.6/platforms/opsi/CLIENT_DATA/logo.png000066400000000000000000000131541263011562700226420ustar00rootroot00000000000000PNG  IHDR9w pHYs.#.#x?v OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F IDATxMLN]Tn5X5AP$uU J!ksڽaR 8pkN'TB U{p-B LJHiUQۃg!3=)<ׄ@K@()!PRB()!x1Q^!'(>5'i*EGBI %%ob 1E.G2鞤wGS'I BI BI %%BI %%BI 7ʜKIŀ^Kl BI BI BI %%BI %%BI %%JJ%%JJ%%DOXQW8G>334O)j{'d,d,riy{TG9O-dU'JD))q/ٛ wP0Ľ2Cj“RJDk)iž4RRqzw0D2PRn(JJ0;~wsLj{Y,T"hQRz-aq}w% Q c>3d;H%1ޣHX\-G>]Q4O.TǔtrGI}w]HTFRnI?PRr0BI BI %%BI %%BI %%JJ%%JJ%%JJ]=JJzOj.{n^MI h"j{g=7/>}PR !Goi|˜\zб]qKK}=:yd,j˟);JJ܋/?iˢ=?纭<-oz$y%Bo8\tq?#OQy J5`SA% 𖡵Q1T"Xjs,wTXT19VA`HuXeoM/5{cFk{c$HWRͿJQ}ݕ|fcn2z{'_U.?Q&RVg΅C6=֜7^Ⱥ`ȏ2CX14Uli%izKr:y^ QL |W=]E35AMTtC=::)W3cwHa༜&{W$٭tC=R^&娚5Q #7Lrذ= Kfr)v\B=z^=IkR?lU2A>=hZXDe98P߮J%>0DaS+!,>KhuK:P_l+X@*vdZCwnͧȥM==i'^|U9aSS~T `a?Z>^ۓPGB֬Y jjOV7:|ԴX)y!MIz!k^5iWdJѰyJDK:ݒڐjS蚌E0;~ŋ6&HVݒڐUy"K]Ѭ^ ({-J\EkY++KoHzY֜U[3ön~7bڌk!KiFAqhue)KL8 Y/{v{S YSh ى`϶V1,)6ZQ)HUmI/dMjFUak{GaȖp7;2hCUYz{!酬ZKXLY=Jjuڞ`bZ̃]_ WOyXwF>7ALO7r*,j!)`KzY<,ta]_t)-jRO Y+aK]rYCII ;+GYq]JF|ߜSRs=J:шrTqb:%e:,^-ˠ6%G׼F1)}9 6dSNI]'l+Zr3%PrXMZ!KIENDB`bareos-Release-14.2.6/platforms/opsi/CLIENT_DATA/readme.txt000066400000000000000000000031161263011562700231670ustar00rootroot00000000000000TODO * (Programme not "Program Files") * properties? bconsole.conf: Director { Name = @director_name@ DIRport = 9101 address = @director_address@ Password = "@director_password@" } bacula-fd.conf: @director_name@ Director { Name = opsiwinxpjs1-mon Password = "2T7xTQg7uCi+RCUpQBUVYCSe+imYWbBfxOBa5QmDxDiD" Monitor = yes } bat.conf: Director { Name = @director_name@ DIRport = 9101 address = @director_address@ Password = "@director_password@" } tray-monitor.conf: Monitor { Name = opsiwinxpjs1-mon Password = "@mon_password@" # password for the Directors RefreshInterval = 30 seconds } Client { Name = opsiwinxpjs1-fd Address = localhost FDPort = 9102 Password = "2T7xTQg7uCi+RCUpQBUVYCSe+imYWbBfxOBa5QmDxDiD" } #Storage { # Name = @basename@-sd # Address = @hostname@ # SDPort = @sd_port@ # Password = "@mon_sd_password@" # password for StorageDaemon #} # #Director { # Name = @basename@-dir # DIRport = @dir_port@ # address = @hostname@ #} # * (fd service l??uft? start automatisch) * firewall * gui feedback? installer: http://www.bacula.org/git/cgit.cgi/bacula/tree/bacula/src/win32/full_win32_installer/winbacula.nsi @philipp: - \\ in pfaden bei windows configuration erforderlich? - benennung der properties? bareos-Release-14.2.6/platforms/opsi/CLIENT_DATA/setup3264.ins000066400000000000000000000167071263011562700233750ustar00rootroot00000000000000; Copyright (c) uib gmbh (www.uib.de) ; This sourcecode is owned by uib ; and published under the Terms of the General Public License. ; credits: http://www.opsi.org/en/credits/ [Actions] requiredWinstVersion >= "4.10.8.6" DefVar $MsiId32$ DefVar $UninstallProgram32$ DefVar $MsiId64$ DefVar $UninstallProgram64$ DefVar $LogDir$ DefVar $ProductId$ DefVar $ProductName$ DefVar $ProductExe32$ DefVar $ProductExe64$ DefVar $MinimumSpace$ DefVar $InstallDir$ DefVar $InstallDir32$ DefVar $InstallDir64$ DefVar $ExitCode$ DefVar $INST_SystemType$ DefVar $INST_architecture$ DefVar $filedaemon_full_name$ DefVar $filedaemon_full_password$ DefVar $filedaemon_monitor_name$ DefVar $filedaemon_monitor_password$ DefVar $filedaemon_client_address$ DefVar $director_name$ DefVar $director_address$ DefVar $director_password$ DefVar $keep_config$ DefVar $auto_config$ Set $INST_SystemType$ = GetSystemType Set $INST_architecture$ = GetProductProperty("install_architecture","system specific") Set $LogDir$ = "%SystemDrive%\tmp" ; ---------------------------------------------------------------- ; - Please edit the following values - ; ---------------------------------------------------------------- ;$ProductId$ should be the name of the product in opsi ; therefore please: only lower letters, no umlauts, ; no white space use '-' as a seperator Set $ProductId$ = "winbareos" Set $ProductExe32$ = "data\winbareos-12.4.4-32-bit-r512.1.exe" Set $ProductExe64$ = "data\winbareos-12.4.4-64-bit-r512.1.exe" Set $MinimumSpace$ = "30 MB" ; the path were we find the product after the installation Set $InstallDir$ = "%ProgramFilesDir%\Bareos" Set $InstallDir32$ = "%ProgramFiles32Dir%\Bareos" Set $InstallDir64$ = "%ProgramFiles64Dir%\Bareos" ; ---------------------------------------------------------------- if not(HasMinimumSpace ("%SystemDrive%", $MinimumSpace$)) LogError "Not enough space on %SystemDrive%, " + $MinimumSpace$ + " on drive %SystemDrive% needed for " + $ProductId$ isFatalError ; Stop process and set installation status to failed endif Set $auto_config$ = lower( GetProductProperty("auto_config", "true")) if $auto_config$ = "true" set $ProductName$ = $ProductId$ + " (auto config)" else set $keep_config$ = "/SILENTKEEPCONFIG" set $ProductName$ = $ProductId$ endif comment "Show product picture" ShowBitmap "%ScriptPath%\logo.png" $ProductName$ if FileExists("%ScriptPath%\delsub3264.ins") comment "Start uninstall sub section" Sub "%ScriptPath%\delsub3264.ins" endif comment "installing" Set $filedaemon_full_password$ = GetProductProperty( "filedaemon_full_password", "filedaemon_full_password" ) Set $filedaemon_monitor_password$ = GetProductProperty( "filedaemon_monitor_password", "filedaemon_monitor_password" ) Set $director_name$ = GetProductProperty( "director_name", "director_name" ) Set $director_address$ = GetProductProperty( "director_address", "director_address" ) Set $director_password$ = GetProductProperty( "director_password", "director_password" ) Set $filedaemon_full_name$ = GetProductProperty( "filedaemon_full_name", "" ) if $filedaemon_full_name$ = "" set $filedaemon_full_name$ = "%HostID%-fd" opsiservicecall_set_product_property_filedaemon_full_name endif Set $filedaemon_monitor_name$ = GetProductProperty( "filedaemon_monitor_name", "filedaemon_monitor_name" ) if $filedaemon_monitor_name$ = "" set $filedaemon_monitor_name$ = "%HostID%-mon" opsiservicecall_set_product_property_filedaemon_monitor_name endif Set $filedaemon_client_address$ = GetProductProperty( "filedaemon_client_address", "") if $filedaemon_client_address$ = "" set $filedaemon_client_address$ = "%HostID%" opsiservicecall_set_product_property_filedaemon_client_address endif if (($INST_SystemType$ = "x86 System") and ($INST_architecture$ = "system specific")) or ($INST_architecture$ = "both") or ($INST_architecture$ = "32 only") Message "Installing " + $ProductId$ + " 32 Bit..." comment "Start setup program" Winbatch_install_32 Sub_check_exitcode ;comment "Copy files" ;Files_install_32 /32Bit ;comment "Patch Registry" ;Registry_install /32Bit ;comment "Create shortcuts" ;LinkFolder_install endif if ($INST_SystemType$ = "64 Bit System") and (($INST_architecture$ = "system specific") or ($INST_architecture$ = "both") or ($INST_architecture$ = "64 only")) Message "Installing " + $ProductId$ + " 64 Bit..." comment "Start setup program" Winbatch_install_64 Sub_check_exitcode ;comment "Copy files" ;Files_install_64 /64Bit ;comment "Patch Registry" ;Registry_install /64Bit ;comment "Create shortcuts" ;LinkFolder_install endif ; ; end ; ; winbatch installer: ; /S silent installl ; /D destination path ; use this, otherwise it installs to "program files" for all languages. ; don't use " around argument, otherwise argument is ignored [Winbatch_install_32] "%ScriptPath%\$ProductExe32$" /S $keep_config$ /CLIENTNAME="$filedaemon_full_name$" /CLIENTPASSWORD="$filedaemon_full_password$" /DIRECTORNAME="$director_name$ /CLIENTADDRESS=$filedaemon_client_address$" /CLIENTMONITORPASSWORD="$filedaemon_monitor_password$" /DIRECTORADDRESS="$director_address$" /DIRECTORPASSWORD="$director_password$" /D=$InstallDir32$ [Winbatch_install_64] "%ScriptPath%\$ProductExe64$" /S $keep_config$ /CLIENTNAME="$filedaemon_full_name$" /CLIENTPASSWORD="$filedaemon_full_password$" /DIRECTORNAME="$director_name$" /CLIENTADDRESS="$filedaemon_client_address$" /CLIENTMONITORPASSWORD="$filedaemon_monitor_password$" /DIRECTORADDRESS="$director_address$" /DIRECTORPASSWORD="$director_password$" /D=$InstallDir64$ [opsiservicecall_set_product_property_filedaemon_full_name] "method": "setProductProperty", "params": [ '$ProductId$', 'filedaemon_full_name', '$filedaemon_full_name$', '%HostID%' ] [opsiservicecall_set_product_property_filedaemon_monitor_name] "method": "setProductProperty", "params": [ '$ProductId$', 'filedaemon_monitor_name', '$filedaemon_monitor_name$', '%HostID%' ] [opsiservicecall_set_product_property_filedaemon_client_address] "method": "setProductProperty", "params": [ '$ProductId$', 'filedaemon_client_address', '$filedaemon_client_address$', '%HostID%' ] [Sub_check_exitcode] comment "Test for installation success via exit code" set $ExitCode$ = getLastExitCode ; informations to exit codes see ; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx ; http://msdn.microsoft.com/en-us/library/aa368542.aspx if ($ExitCode$ = "0") comment "Looks good: setup program gives exitcode zero" else comment "Setup program gives a exitcode unequal zero: " + $ExitCode$ if ($ExitCode$ = "1605") comment "ERROR_UNKNOWN_PRODUCT 1605 This action is only valid for products that are currently installed." comment "Uninstall of a not installed product failed - no problem" else if ($ExitCode$ = "1641") comment "looks good: setup program gives exitcode 1641" comment "ERROR_SUCCESS_REBOOT_INITIATED 1641 The installer has initiated a restart. This message is indicative of a success." else if ($ExitCode$ = "3010") comment "looks good: setup program gives exitcode 3010" comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010 A restart is required to complete the install. This message is indicative of a success." else logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$ isFatalError endif endif endif endif bareos-Release-14.2.6/platforms/opsi/CLIENT_DATA/uninstall3264.ins000066400000000000000000000032741263011562700242410ustar00rootroot00000000000000; Copyright (c) uib gmbh (www.uib.de) ; This sourcecode is owned by uib gmbh ; and published under the Terms of the General Public License. ; credits: http://www.opsi.org/en/credits/ [Actions] requiredWinstVersion >= "4.10.8.6" DefVar $MsiId32$ DefVar $UninstallProgram32$ DefVar $MsiId64$ DefVar $UninstallProgram64$ DefVar $LogDir$ DefVar $ExitCode$ DefVar $ProductId$ DefVar $ProductName$ DefVar $InstallDir32$ DefVar $InstallDir64$ DefVar $LicenseRequired$ DefVar $LicensePool$ DefVar $auto_config$ DefVar $keep_config$ DefVar $INST_SystemType$ DefVar $INST_architecture$ Set $INST_SystemType$ = GetSystemType set $INST_architecture$ = GetProductProperty("install_architecture","system specific") Set $LogDir$ = "%SystemDrive%\tmp" ; ---------------------------------------------------------------- ; - Please edit the following values - ; ---------------------------------------------------------------- Set $ProductId$ = "bareos" Set $InstallDir32$ = "%ProgramFiles32Dir%\Bareos" Set $InstallDir64$ = "%ProgramFiles64Dir%\Bareos" ;Set $LicenseRequired$ = "false" ;Set $LicensePool$ = "p_" + $ProductId$ ; ---------------------------------------------------------------- Set $auto_config$ = lower( GetProductProperty("auto_config", "true")) if $auto_config$ = "true" set $ProductName$ = $ProductId$ + " (auto config)" else set $keep_config$ = "/SILENTKEEPCONFIG" set $ProductName$ = $ProductId$ endif comment "Show product picture" ShowBitmap "%ScriptPath%\logo.png" $ProductId$ Message "Uninstalling " + $ProductId$ + " ..." if FileExists("%ScriptPath%\delsub3264.ins") comment "Start uninstall sub section" Sub "%ScriptPath%\delsub3264.ins" endif bareos-Release-14.2.6/platforms/opsi/OPSI/000077500000000000000000000000001263011562700201735ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/opsi/OPSI/control000066400000000000000000000061651263011562700216060ustar00rootroot00000000000000[Package] version: $PackageVersion depends: incremental: False [Product] type: localboot id: winbareos name: Bareos file daemon description: backup software advice: version: $ProductVersion priority: 0 licenseRequired: False productClasses: setupScript: setup3264.ins uninstallScript: uninstall3264.ins updateScript: alwaysScript: onceScript: customScript: userLoginScript: [ProductProperty] type: unicode name: auto_config multivalue: False editable: False description: if true, Bareos configuration gets generated from Opsi properties values: ["false", "true"] default: ["true"] [ProductProperty] type: unicode name: filedaemon_full_name multivalue: False editable: True description: filedaemon bareos name. Leave empty for HostID-fd default: [""] [ProductProperty] type: unicode name: filedaemon_full_password multivalue: False editable: True description: password used by director to connect to this filedaemon default: ["filedaemon_full_password"] [ProductProperty] type: unicode name: filedaemon_client_address multivalue: False editable: True description: address of the filedaemon. Leave empty for HostID-fd default: [""] [ProductProperty] type: unicode name: filedaemon_monitor_name multivalue: False editable: True description: filedaemon bareos name. Leave empty for HostID-mon default: [""] [ProductProperty] type: unicode name: filedaemon_monitor_password multivalue: False editable: True description: password used by monitoring (eg. tray-monitor) to connect to this filedaemon default: ["filedaemon_monitor_password"] [ProductProperty] type: unicode name: director_name multivalue: False editable: True description: access to Bareos director for bconsole and bat default: ["director_name"] [ProductProperty] type: unicode name: director_address multivalue: False editable: True description: access to Bareos director for bconsole and bat default: ["director_address"] [ProductProperty] type: unicode name: director_password multivalue: False editable: True description: access to Bareos director for bconsole and bat default: ["director_password"] [ProductProperty] type: unicode name: install_architecture multivalue: False editable: False description: which architecture (32/64 bit) has to be installed values: ["32 only", "64 only", "both", "system specific"] default: ["system specific"] [Changelog] 20130627, Daniel Neuberger * added ProductProperty Update_KeepConfig 20130215, Joerg Steffens * adapted to be build with http://build.opensuse.org 20130129, , Daniel Neuberger * inital Bareos * added properties filedaemon_client_address * added Variables in setup * added silent installation in Setup 20120710, 5.2.10-3, Joerg Steffens * write properties filedaemon_full_name and filedaemon_monitor_name back to opsi server * added properties fileset and jobdefs 20120704, 5.2.10-2, Joerg Steffens * uninstall * properties * generate bareos-fd.conf 20120702, 5.2.10-1, Joerg Steffens * initial opsi-template (4.0.1-5) stable; urgency=low * added /nocancel at Inno example * added login.ins for 'user profile management' * moved changelog to control file -- detlef oertel Mon, 02 Jan 2012 16:01:53 +0200 bareos-Release-14.2.6/platforms/opsi/OPSI/postinst000066400000000000000000000005641263011562700220060ustar00rootroot00000000000000#! /bin/sh # # postinst script for softprod # This script executes after unpacking files from that archive and registering the product at the server. # # The following environment variables can be used to obtain information about the current installation: # PRODUCT_ID: id of the current product # CLIENT_DATA_DIR: directory which contains the installed client data # bareos-Release-14.2.6/platforms/opsi/OPSI/preinst000066400000000000000000000005271263011562700216060ustar00rootroot00000000000000#! /bin/sh # # preinst script for softprod # This script executes before that package will be unpacked from its archive file. # # The following environment variables can be used to obtain information about the current installation: # PRODUCT_ID: id of the current product # CLIENT_DATA_DIR: directory where client data will be installed # bareos-Release-14.2.6/platforms/opsi/winbareos-opsi.changes000066400000000000000000000002101263011562700237050ustar00rootroot00000000000000------------------------------------------------------------------- Fri Feb 15 13:52:58 UTC 2013 - joerg.steffens@dass-it.de - initial bareos-Release-14.2.6/platforms/opsi/winbareos-opsi.spec000066400000000000000000000047731263011562700232510ustar00rootroot00000000000000 #!BuildIgnore: post-build-checks Name: winbareos-opsi Version: 0 Release: 0 Summary: Bareos Windows Packages for OPSI License: AGPL-3.0 Group: Productivity/Archiving/Backup URL: http://www.bareos.org Requires: opsi-depotserver BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch BuildRequires: sed BuildRequires: opsi-utils BuildRequires: winbareos-nsi = %{version} Source0: bareos-%{version}.tar.gz %description Bareos - Backup Archiving Recovery Open Sourced. Bareos is a set of computer programs that permit you (or the system administrator) to manage backup, recovery, and verification of computer data across a network of computers of different kinds. In technical terms, it is a network client/server based backup program. Bareos is relatively easy to use and efficient, while offering many advanced storage management features that make it easy to find and recover lost or damaged files. Bareos source code has been released under the AGPL version 3 license. This package contains the Bareos Windows client packages for OPSI (http://www.opsi.org), the Windows system management solution. Using OPSI, the package can be distributed to Windows systems. %define opsidest /var/lib/opsi/repository %prep %setup -n bareos-%{version} %build cd platforms # OPSI ProductVersion is at most 32 characters long VERSION32C=$(sed -r -e 's/(.{1,32}).*/\1/' -e 's/\.*$//' <<< %{version}) # set version and release for OPSI sed -i -e "s/^version: \$PackageVersion/version: %{release}/i" \ -e "s/^version: \$ProductVersion/version: $VERSION32C/i" opsi/OPSI/control WINBAREOS32=`ls -1 /winbareos*-postvista-32-bit-*.exe` WINBAREOS64=`ls -1 /winbareos*-postvista-64-bit-*.exe` if [ -r "$WINBAREOS32" ] && [ -r "$WINBAREOS64" ]; then mkdir -p opsi/CLIENT_DATA/data cp -a $WINBAREOS32 $WINBAREOS64 opsi/CLIENT_DATA/data WINBAREOS32b='data\\'`basename $WINBAREOS32` WINBAREOS64b='data\\'`basename $WINBAREOS64` sed -i -e's/^Set $ProductExe32$ .*/Set $ProductExe32$ = "'$WINBAREOS32b'"/' \ -e's/^Set $ProductExe64$ .*/Set $ProductExe64$ = "'$WINBAREOS64b'"/' opsi/CLIENT_DATA/setup3264.ins opsi-makeproductfile -m -z opsi fi test -r winbareos*.opsi %install mkdir -p $RPM_BUILD_ROOT%{opsidest} cp -a platforms/winbareos*.opsi* $RPM_BUILD_ROOT%{opsidest} %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %{opsidest}/winbareos*.opsi* %changelog bareos-Release-14.2.6/platforms/osx/000077500000000000000000000000001263011562700172605ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/osx/Makefile.in000066400000000000000000000107021263011562700213250ustar00rootroot00000000000000# # This is the makefile template for the platform directory # which contains general platform installation. # # 17 August 2009 -- Lorenz Schori # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # GITVERSION=$(shell git log --pretty=format:"%at" -1) # bareos version and download site BAREOS_VERSION:=@VERSION@.git.$(GITVERSION) BAREOS_DL_URL:=http://github.com/bareos/bareos/archive/Release/${BAREOS_VERSION}.tar.gz # Build universal binary ARCHFLAGS:= MACOSX_SDK_SYSROOT:= MACOSX_VERSION_FLAGS:= # Tools PB:=pkgbuild MAKE:=/usr/bin/make CURL:=/usr/bin/curl TAR:=/usr/bin/tar ########### you should not have to edit anything beyond this line ########### # Build paths DL_DIR:=dl BUILD_DIR:=build PRODUCTS_DIR:=products WORKING_DIR:=${BUILD_DIR}/${BAREOS_VERSION} BAREOS_TAR:=${DL_DIR}/bareos-${BAREOS_VERSION}.tar.gz BAREOS_SOURCE:=${WORKING_DIR}/bareos-${BAREOS_VERSION} BAREOS_DESTDIR:=${WORKING_DIR}/destdir BAREOS_PREFIX:=/usr/local BAREOS_FD_CONF:=${BAREOS_PREFIX}/etc/bareos-fd.conf BAREOS_WORKING_DIR:=/var/run/bareos/working #BAREOS_PMDOC:=${WORKING_DIR}/installer.pmdoc # Detect whether we sit inside the bareos source tree. In this case we won't # download the tar from sourceforge but instead work with what its there # already CURSUB:=$(CURDIR:%/platforms/osx=%) ifneq ($(CURDIR),$(CURSUB)) BAREOS_TAR:= BAREOS_SOURCE:=../../ # BAREOS_VERSION:=$(shell sed -n 's,^VERSION=,,p' $(CURSUB)/autoconf/Make.common) endif PACKAGE_TITLE:=bareos-filedaemon-${BAREOS_VERSION} PACKAGE_ID:=org.bareos.bareos-fd.pkg PACKAGE_DIR:=${PRODUCTS_DIR}/${PACKAGE_TITLE} PACKAGE_BUNDLE:=${PACKAGE_DIR}/${PACKAGE_TITLE}.pkg PACKAGE_DMG:=${PRODUCTS_DIR}/${PACKAGE_TITLE}.dmg PACKAGE_RESOURCES:=ReadMe.html postflight preupgrade PACKAGE_XRESOURCES:=postflight preupgrade # Flags for the toolchain CONFIGFLAGS:=--enable-client-only --prefix=${BAREOS_PREFIX} \ --with-dir-password=@DIR_PW@ --with-fd-password=@FD_PW@ \ --with-sd-password=@SD_PW@ --with-mon-dir-password=@MON_DIR_PW@ \ --with-mon-fd-password=@MON_FD_PW@ --with-mon-sd-password=@MON_SD_PW@ \ --with-basename=@BASENAME@ --with-hostname=@HOSTNAME@ \ --with-working-dir=${BAREOS_WORKING_DIR} CPPFLAGS:= CFLAGS:=-O -g CXXFLAGS:=${CFLAGS} LDFLAGS:= CC:=gcc CPP:=cpp CXX:=g++ CXXPP:=cpp # Placeholders for *.in files INFILE_SUBST=\ -e "s,@PREFIX@,${BAREOS_PREFIX},g" \ -e "s,@BAREOS_VERSION@,${BAREOS_VERSION},g" \ -e "s,@FD_CONF@,${BAREOS_FD_CONF},g" \ -e "s,@BAREOS_DESTDIR@,${BAREOS_DESTDIR},g" \ -e "s,@PACKAGE_ID@,${PACKAGE_ID},g" nothing: all: dmg dmg: pkg hdiutil create -srcfolder "${PACKAGE_DIR}" "${PACKAGE_DMG}" pkg: ${BAREOS_DESTDIR} ${WORKING_DIR}/resources mkdir -p "${PACKAGE_DIR}" mkdir -p "${CURDIR}/${BAREOS_DESTDIR}${BAREOS_WORKING_DIR}" ${PB} --identifier "${PACKAGE_ID}" --root "${CURDIR}/${BAREOS_DESTDIR}" "bareos-${BAREOS_VERSION}.pkg" cp "bareos-${BAREOS_VERSION}.pkg" "${PACKAGE_DIR}" cp ${WORKING_DIR}/resources/ReadMe.html "${PACKAGE_DIR}/ReadMe.html" # sed ${INFILE_SUBST} \ # files/uninstall.command.in > "${PACKAGE_DIR}/uninstall.command"; # chmod 0775 "${PACKAGE_DIR}/uninstall.command" ${WORKING_DIR}/resources: ${BAREOS_DESTDIR} mkdir -p "${WORKING_DIR}/resources" for res in ${PACKAGE_RESOURCES}; do \ sed ${INFILE_SUBST} \ resources/$$res.in > "${WORKING_DIR}/resources/$$res"; \ done for xres in ${PACKAGE_XRESOURCES}; do \ chmod +x "${WORKING_DIR}/resources/$$xres"; \ done cp "${BAREOS_SOURCE}/LICENSE" "${WORKING_DIR}/resources/License.txt" install: ${BAREOS_DESTDIR}: ${BAREOS_SOURCE} (cd ${BAREOS_SOURCE} && ./configure ${CONFIGFLAGS} CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" CC="${CC}" CPP="${CPP}" CXX="${CXX}" CXXPP="${CXXPP}") ${MAKE} -C ${BAREOS_SOURCE} ${MAKE} -C ${BAREOS_SOURCE} install DESTDIR="${CURDIR}/${BAREOS_DESTDIR}" rm -rf "${BAREOS_DESTDIR}/tmp" for conffile in ${BAREOS_DESTDIR}${BAREOS_PREFIX}/etc/*.conf; do \ mv $$conffile $$conffile.example; \ done mkdir -p "${BAREOS_DESTDIR}/Library/LaunchDaemons" sed ${INFILE_SUBST} ${CURDIR}/files/org.bareos.bareos-fd.plist.in \ > "${BAREOS_DESTDIR}/Library/LaunchDaemons/org.bareos.bareos-fd.plist" ${BAREOS_SOURCE}: ${BAREOS_TAR} mkdir -p "${WORKING_DIR}" ${TAR} -xzf "${BAREOS_TAR}" -C "${WORKING_DIR}" ${BAREOS_TAR}: mkdir -p "${DL_DIR}" ${CURL} -L -o "${BAREOS_TAR}" "${BAREOS_DL_URL}" .PHONY: distclean clean install distclean: clean rm -rf "${DL_DIR}" "${PRODUCTS_DIR}" clean: rm -rf "${BUILD_DIR}" "${PACKAGE_DIR}" "${PACKAGE_DMG}" bareos-Release-14.2.6/platforms/osx/README000066400000000000000000000047121263011562700201440ustar00rootroot00000000000000Bareos file daemon package builder for Mac OS X =============================================== This package build script lets you download, compile and package the bareos file daemon easily with a single command line. Beside the bareos file daemon the resulting installer package contains a short ReadMe file with instructions on how to install and use the software. Also a basic launchd property list is included along with preugrade and postflight installer scripts to stop and restart the daemon while upgrading. To ensure the security of the users the passwords in the configuration files are generated during a first time installation and file permissions are checked and corrected on upgrades. Requirements: * Mac OS X 10.5 or later (building/packaging), 10.4 or later (deployment) * Mac OS X developer tools installed Example (compile and create package from within bareos source tree): $ ./configure --enable-client-only $ make -C platforms/osx By moving the contents of platforms/osx to some other directory (e.g. ~/bareos-standalone-bulder), it is possible to create installer packages from older bareos versions and for specific platforms. Examples (standalone mode): 1. Create an installer package from the newest supported bareos source containing the bareos file daemon as a PPC/Intel universal binary. $ make dmg 2. Create an installer package from a specified version of the bareos source containing the bareos file daemon as a PPC/Intel universal binary. $ make dmg BAREOS_VERSION=3.0.0 3. Create an installer package from the newest supported bareos source containing the bareos file daemon for PPC architecture only. $ make dmg ARCHFLAGS="-arch ppc" PACKAGE_TITLE="Bareos File Daemon PPC x.y.z" 4. Create an installer package from a specified version of the bareos source containing the bareos file daemon for the current architecture. $ make dmg BAREOS_VERSION=2.4.4 ARCHFLAGS="" You find the built disk images in the products folder. Misc commands: 1. Cleanup the build directory $ make clean 2. Additionally remove the downloads and products: $ make distclean Additional notes on the build-script: * The following *FLAGS are used tu build universal binary with 10.4 SDK: CPPFLAGS=-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 CFLAGS=-O -g -arch i386 -arch ppc CXXFLAGS=${CFLAGS} LDFLAGS=-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch i386 -arch ppc bareos-Release-14.2.6/platforms/osx/files/000077500000000000000000000000001263011562700203625ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/osx/files/installer.pmdoc.in/000077500000000000000000000000001263011562700240655ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/osx/files/installer.pmdoc.in/01destdir.xml000066400000000000000000000014401263011562700264050ustar00rootroot00000000000000 @PACKAGE_ID@ @BAREOS_VERSION@ destdir / version identifier parent resources/postflight resources/preupgrade 01destdir-contents.xml /\.DS_Store$ bareos-Release-14.2.6/platforms/osx/files/installer.pmdoc.in/index.xml000066400000000000000000000016561263011562700257260ustar00rootroot00000000000000 Bareos File Daemon @BAREOS_VERSION@ org.bareos resources/License.txt resources/ReadMe.html 01destdir.xml properties.title properties.anywhereDomain properties.systemDomain bareos-Release-14.2.6/platforms/osx/files/org.bareos.bareos-fd.plist.in000066400000000000000000000010411263011562700257420ustar00rootroot00000000000000 Label org.bareos.bareos-fd ProgramArguments @PREFIX@/sbin/bareos-fd -f -c @FD_CONF@ RunAtLoad bareos-Release-14.2.6/platforms/osx/files/uninstall.command.in000066400000000000000000000015661263011562700243500ustar00rootroot00000000000000#!/bin/sh echo "Bareos file daemon @BAREOS_VERSION@ uninstaller" # Remove startup item echo "* Bareos startup item... " if [ -f /Library/LaunchDaemons/org.bareos.bareos-fd.plist ]; then sudo launchctl unload /Library/LaunchDaemons/org.bareos.bareos-fd.plist sudo rm /Library/LaunchDaemons/org.bareos.bareos-fd.plist echo " + removed successfully" else echo " - not found, nothing to remove" fi echo "* Bareos file daemon... " if [ -d "/usr/local/bareos-@BAREOS_VERSION@" ]; then sudo rm -r "/usr/local/bareos-@BAREOS_VERSION@" echo " + removed successfully" else echo " - not found, nothing to remove" fi echo "* Installer receipt... " if [ -d "/Library/Receipts/Bareos File Daemon @BAREOS_VERSION@.pkg" ]; then sudo rm -r "/Library/Receipts/Bareos File Daemon @BAREOS_VERSION@.pkg" echo " + removed successfully" else echo " - not found, nothing to remove" fi bareos-Release-14.2.6/platforms/osx/installer-gencontents.py000066400000000000000000000032231263011562700241540ustar00rootroot00000000000000import os import stat import sys from xml.dom.minidom import Document def createFtags(doc, path, isrootpath=True): """ create f-tags for packagemaker's contents.xml files recursively replacing owner with "root" and group with "wheel" in each entry """ statinfo = os.lstat(path) isdir = stat.S_ISDIR(statinfo[0]) ftag = doc.createElement("f") ftag.setAttribute("n",os.path.split(path)[1]) ftag.setAttribute("p","%d" % statinfo[0]) ftag.setAttribute("o","root") ftag.setAttribute("g","wheel") # we additionally have to create owner and group # within each f-tag ftag.appendChild(doc.createElement("mod").appendChild(doc.createTextNode("owner"))) ftag.appendChild(doc.createElement("mod").appendChild(doc.createTextNode("group"))) if isrootpath: # needs to be the full path ftag.setAttribute("pt",os.path.abspath(path)) # no idea what those attributes mean: ftag.setAttribute("m","false") ftag.setAttribute("t","file") if isdir: for item in os.listdir(path): ftag.appendChild(createFtags(doc, os.path.join(path,item), False)) return ftag def generateContentsDocument(path): """ create new minidom document and generate contents by recursively traver- sing the given path. """ doc = Document() root = doc.createElement("pkg-contents") root.setAttribute("spec","1.12") root.appendChild(createFtags(doc, path)) doc.appendChild(root) return doc if __name__ == "__main__": # construct document doc = generateContentsDocument(sys.argv[1]) print doc.toprettyxml(indent=" "), bareos-Release-14.2.6/platforms/osx/resources/000077500000000000000000000000001263011562700212725ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/osx/resources/ReadMe.html.in000066400000000000000000000041271263011562700237260ustar00rootroot00000000000000 Bareos File Daemon @BAREOS_VERSION@

Bareos File Daemon @BAREOS_VERSION@

Bareos is on Open Source, enterprise ready, network based backup program. This installer package contains the bareos file daemon for Mac OS X 10.4 or later built as an universal binary for PPC and Intel processors.

Requirements

The bareos file daemon is only the client component of the backup system. For proper operation the file daemon needs to have access to a bareos director and storage daemon, typically installed on a server machine in the local network.

Installation

Open the Bareos File Daemon @BAREOS_VERSION@ installer package and follow the directions given to you.

Configuration

After the installation is complete you have to adapt the configuration file to your needs. The file is located in:

/usr/local/etc/bareos-fd.conf

Note: The configuration file contains passwords and therefore must not be accessible for any users except root. Use the following command line to edit the file as root-user:

sudo /Applications/TextEdit.app/Contents/MacOS/TextEdit /usr/local/etc/bareos-fd.conf

Operating the File Daemon

Use launchctl to enable and disable the bareos file daemon.

sudo launchctl load -w /Library/LaunchDaemons/org.bareos.bareos-fd.plist

sudo launchctl unload -w /Library/LaunchDaemons/org.bareos.bareos-fd.plist

Resources

Refer to the bareos website for more information.

http://bareos.org bareos-Release-14.2.6/platforms/osx/resources/postflight.in000066400000000000000000000020321263011562700240020ustar00rootroot00000000000000#!/bin/sh function genpw() { openssl rand -base64 33 } # copy example config files and fix permissions if [ ! -f $3@FD_CONF@ ]; then DIR_PW=$(genpw) FD_PW=$(genpw) SD_PW=$(genpw) MON_DIR_PW=$(genpw) MON_FD_PW=$(genpw) MON_SD_PW=$(genpw) HOSTNAME=$(hostname -s) mkdir -p "$(dirname $3@FD_CONF@)" sed \ -e "s,@DIR_PW@,$DIR_PW,g" \ -e "s,@FD_PW@,$FD_PW,g" \ -e "s,@SD_PW@,$SD_PW,g" \ -e "s,@MON_DIR_PW@,$MON_DIR_PW,g" \ -e "s,@MON_FD_PW@,$MON_FD_PW,g" \ -e "s,@MON_SD_PW@,$MON_SD_PW,g" \ -e "s,@BASENAME@,$HOSTNAME,g" \ -e "s,@HOSTNAME@,$HOSTNAME,g" \ "$3@PREFIX@/etc/bareos-fd.conf.example" > "$3@FD_CONF@" fi chmod 0600 "$3@FD_CONF@" # install startup item mkdir -p -m 0755 "$3/Library/LaunchDaemons" chmod 0644 "$3@PREFIX@/Library/LaunchDaemons/org.bareos.bareos-fd.plist" ln -fs "$3@PREFIX@/Library/LaunchDaemons/org.bareos.bareos-fd.plist" "$3/Library/LaunchDaemons/org.bareos.bareos-fd.plist" # Load startup item /bin/launchctl load "$3/Library/LaunchDaemons/org.bareos.bareos-fd.plist" bareos-Release-14.2.6/platforms/osx/resources/preupgrade.in000066400000000000000000000003171263011562700237610ustar00rootroot00000000000000#!/bin/sh # unload bareos file daemon before upgrading if [ -f "$3/Library/LaunchDaemons/org.bareos.bareos-fd.plist" ]; then /bin/launchctl unload "$3/Library/LaunchDaemons/org.bareos.bareos-fd.plist" fi bareos-Release-14.2.6/platforms/packaging/000077500000000000000000000000001263011562700203735ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/packaging/bareos-Univention_3.1.dsc000066400000000000000000000021211263011562700250520ustar00rootroot00000000000000Format: 1.0 Source: bareos Binary: bareos, bareos-bat, bareos-bconsole, bareos-client, bareos-common, bareos-database-common, bareos-database-postgresql, bareos-database-mysql, bareos-database-sqlite3, bareos-database-tools, bareos-devel, bareos-director, bareos-director-python-plugin, bareos-filedaemon, bareos-filedaemon-python-plugin, bareos-storage, bareos-storage-python-plugin, bareos-tools, bareos-traymonitor, univention-bareos, univention-bareos-schema Architecture: any Version: 14.2.6 Maintainer: Joerg Steffens Homepage: http://www.bareos.org/ Standards-Version: 3.9.4 Build-Depends: acl-dev, autotools-dev, bc, chrpath, debhelper (>= 7.0.50~), dpkg-dev (>= 1.13.19), libacl1-dev, libcap-dev, libfastlz-dev, liblzo2-dev, libqt4-dev, libreadline-dev, libssl-dev, libwrap0-dev, libx11-dev, libsqlite3-dev, libmysqlclient-dev, libpq-dev (>= 8.4), lsb-release, mtx, ncurses-dev, pkg-config, po-debconf (>= 0.8.2), python-dev, ucslint, univention-config-dev, zlib1g-dev Build-Conflicts: python2.2-dev, python2.3, python2.4, qt3-dev-tools DEBTRANSFORM-RELEASE: 1 Files: bareos-Release-14.2.6/platforms/packaging/bareos-Univention_3.2.dsc000066400000000000000000000021211263011562700250530ustar00rootroot00000000000000Format: 1.0 Source: bareos Binary: bareos, bareos-bat, bareos-bconsole, bareos-client, bareos-common, bareos-database-common, bareos-database-postgresql, bareos-database-mysql, bareos-database-sqlite3, bareos-database-tools, bareos-devel, bareos-director, bareos-director-python-plugin, bareos-filedaemon, bareos-filedaemon-python-plugin, bareos-storage, bareos-storage-python-plugin, bareos-tools, bareos-traymonitor, univention-bareos, univention-bareos-schema Architecture: any Version: 14.2.6 Maintainer: Joerg Steffens Homepage: http://www.bareos.org/ Standards-Version: 3.9.4 Build-Depends: acl-dev, autotools-dev, bc, chrpath, debhelper (>= 7.0.50~), dpkg-dev (>= 1.13.19), libacl1-dev, libcap-dev, libfastlz-dev, liblzo2-dev, libqt4-dev, libreadline-dev, libssl-dev, libwrap0-dev, libx11-dev, libsqlite3-dev, libmysqlclient-dev, libpq-dev (>= 8.4), lsb-release, mtx, ncurses-dev, pkg-config, po-debconf (>= 0.8.2), python-dev, ucslint, univention-config-dev, zlib1g-dev Build-Conflicts: python2.2-dev, python2.3, python2.4, qt3-dev-tools DEBTRANSFORM-RELEASE: 1 Files: bareos-Release-14.2.6/platforms/packaging/bareos-rpmlintrc000066400000000000000000000045631263011562700236110ustar00rootroot00000000000000#addFilter("E: shlib-policy-name-error") # We as packager don't take the risk to reload a perhaps running daemon # Bareos administrator should know that and only the director could be reloaded # safely if no jobs are running addFilter("W: init-script-without-%restart_on_update-postun /etc/init.d/bareos-dir") addFilter("W: init-script-without-%restart_on_update-postun /etc/init.d/bareos-sd") addFilter("W: init-script-without-%restart_on_update-postun /etc/init.d/bareos-fd") addFilter("W: no-reload-entry /etc/init.d/bareos-dir") addFilter("W: no-reload-entry /etc/init.d/bareos-fd") addFilter("W: no-reload-entry /etc/init.d/bareos-sd") # Filtered due to absolute false positive # http://lists.opensuse.org/opensuse-factory/2011-05/msg00315.html addFilter("W: file-contains-date-and-time") # Filtered there's no manual for init.d scripts # linked as /usr/sbin/rc addFilter("W: no-manual-page-for-binary rcbareos-dir") addFilter("W: no-manual-page-for-binary rcbareos-fd") addFilter("W: no-manual-page-for-binary rcbareos-sd") # Neither for console addFilter("W: no-manual-page-for-binary bareos-tray-monitor-gtk") addFilter("W: no-manual-page-for-binary bareos-tray-monitor-qt") # no man page for simple bash script unfrequently used addFilter("W: no-manual-page-for-binary btraceback") # BF asked upstream for fix - let the warning to remember # bareos-dir.x86_64: I: binary-or-shlib-calls-gethostbyname /usr/sbin/bsmtp # The binary calls gethostbyname(). Please port the code to use getaddrinfo(). # addFilter("I: binary-or-shlib-calls-gethostbyname /usr/sbin/bsmtp") # We use %%config on a non config file # see spec for explanation addFilter("W: non-etc-or-var-file-marked-as-conffile /usr/lib64/bareos/query.sql") # Filtered non-standard-gid # We will ask for that addFilter("W: non-standard-gid") addFilter("W: non-standard-uid") # shlibs-policy : asked in -buildservice 2011-11-24 # Filter added cause we don't share our .so and they can't be a different # version. # We (packagers & bareos specialists) decide to split those into separates # packages to simplify the requires and link with the 3 databases. addFilter("W: shlib-policy-missing-suffix") # These are fake warning, our package contain at least one lib # don't need versioning # can't be placed in runtime -dir package addFilter("W: shlib-policy-missing-lib ") addFilter("W: shlib-unversioned-lib") addFilter("E: shlib-policy-name-error") bareos-Release-14.2.6/platforms/packaging/bareos.changes000066400000000000000000000061431263011562700232040ustar00rootroot00000000000000bareos (14.2.6-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Mon, 16 Nov 2015 20:27:24 +0100 bareos (14.2.5-1) unstable; urgency=low * Switch version number -- Joerg Steffens Mon, 27 May 2015 10:30:00 +0100 bareos (14.2.4-1) unstable; urgency=low * Switch version number -- Joerg Steffens Mon, 23 Mar 2015 10:30:00 +0100 bareos (14.2.3-1) unstable; urgency=low * Switch version number -- Joerg Steffens Mon, 26 Jan 2015 10:30:00 +0100 bareos (14.2.2-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Fri, 12 Dec 2014 12:12:12 +0100 bareos (14.2.1-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Fri, 12 Sep 2014 16:31:41 +0200 bareos (14.2.0-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Fri, 11 Apr 2014 12:00:00 +0200 bareos (14.1.0-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Mon, 03 Feb 2014 14:19:25 +0100 bareos (13.4.0-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Sun, 29 Sep 2013 10:48:34 +0200 bareos (13.3.0-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Sun, 30 Jun 2013 13:32:59 +0200 bareos (13.2.0-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Tue, 09 Apr 2013 21:08:34 +0200 bareos (13.1.0-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Wed, 13 Feb 2013 17:47:59 +0100 bareos (12.4.1-1) unstable; urgency=low * Switch version number -- Marco van Wieringen Wed, 06 Feb 2013 15:09:10 +0100 bareos (12.4.0-7) unstable; urgency=low * enable ndmp and scsi-crypto * remove deprecated gtk tray monitor -- Marco van Wieringen Sun, 30 Dec 2012 16:51:18 +0100 bareos (12.4.0-6) unstable; urgency=low * permissions * build fixes -- Joerg Steffens Wed, 12 Dec 2012 19:23:19 +0100 bareos (12.4.0-5) unstable; urgency=low * add bareos group and users * add init scripts * add logrotate for bareos-dir -- Joerg Steffens Tue, 11 Dec 2012 18:21:17 +0100 bareos (12.4.0-4) unstable; urgency=low * bugfixes: package contents -- Joerg Steffens Fri, 07 Dec 2012 16:49:19 +0100 bareos (12.4.0-3) unstable; urgency=low * cleanup -- Joerg Steffens Tue, 04 Dec 2012 17:08:55 +0100 bareos (12.4.0-2) unstable; urgency=low * bugfixes -- Joerg Steffens Tue, 04 Dec 2012 16:47:34 +0100 bareos (12.4.0-1) unstable; urgency=low * Initial release -- Joerg Steffens Tue, 04 Dec 2012 16:43:57 +0100 bareos-Release-14.2.6/platforms/packaging/bareos.dsc000066400000000000000000000020701263011562700223400ustar00rootroot00000000000000Format: 1.0 Source: bareos Binary: bareos, bareos-bat, bareos-bconsole, bareos-client, bareos-common, bareos-database-common, bareos-database-postgresql, bareos-database-mysql, bareos-database-sqlite3, bareos-database-tools, bareos-devel, bareos-director, bareos-director-python-plugin, bareos-filedaemon, bareos-filedaemon-python-plugin, bareos-storage, bareos-storage-fifo, bareos-storage-tape, bareos-storage-python-plugin, bareos-tools, bareos-traymonitor Architecture: any Version: 14.2.6 Maintainer: Joerg Steffens Homepage: http://www.bareos.org/ Standards-Version: 3.9.4 Build-Depends: acl-dev, autotools-dev, bc, chrpath, debhelper (>= 7.0.50~), dpkg-dev (>= 1.13.19), git-core, libacl1-dev, libcap-dev, libfastlz-dev, liblzo2-dev, libqt4-dev, libreadline-dev, libssl-dev, libwrap0-dev, libx11-dev, libsqlite3-dev, libmysqlclient-dev, libpq-dev, lsb-release, mtx, ncurses-dev, openssl, pkg-config, po-debconf (>= 0.8.2), python-dev, zlib1g-dev Build-Conflicts: python2.2-dev, python2.3, python2.4, qt3-dev-tools DEBTRANSFORM-RELEASE: 1 Files: bareos-Release-14.2.6/platforms/packaging/bareos.spec000066400000000000000000001032141263011562700225230ustar00rootroot00000000000000# # spec file for package bareos # Copyright (c) 2011-2012 Bruno Friedmann (Ioda-Net) and Philipp Storz (dass IT) # 2013-2015 Bareos GmbH & Co KG # # Redesign of the bareos specfile: goals (20110922) # # * only support platforms that are available in OBS # * activate all options available (if reasonable) # * single-dir-install is not supported # * Single packages for: # * console package # * dir package # * sd package ( bls + btape + bcopy + bextract ) # * fd package ( ) # * tray monitor # * bareos-database-{sqlite,postgresql,mysql} (libs) (make_database/tables/grant rights) # * sql common abstract sql libraries (without db) # * libs common libraries (without db) # * tools without link to db libs (bwild, bregex) # * tools with link to db libs (dbcheck, bscan) # * bat # # Notice: the libbareoscats* package to be able to pass the shlib name policy are # explicitly named # # Please submit bugfixes or comments via http://bugs.opensuse.org/ Name: bareos Version: 14.2.6 Release: 0 Group: Productivity/Archiving/Backup License: AGPL-3.0 BuildRoot: %{_tmppath}/%{name}-root URL: http://www.bareos.org/ Vendor: The Bareos Team #Packager: {_packager} %define _libversion 14.2.6 %define library_dir %{_libdir}/bareos %define backend_dir %{_libdir}/bareos/backends %define plugin_dir %{_libdir}/bareos/plugins %define script_dir /usr/lib/bareos/scripts %define working_dir /var/lib/bareos %define pid_dir /var/lib/bareos %define bsr_dir /var/lib/bareos # TODO: use /run ? %define _subsysdir /var/lock # # Generic daemon user and group # %define daemon_user bareos %define daemon_group bareos %define director_daemon_user %{daemon_user} %define storage_daemon_user %{daemon_user} %define file_daemon_user root %define storage_daemon_group %{daemon_group} # default settings %define client_only 0 %define build_bat 1 %define build_qt_monitor 1 %define build_sqlite3 1 %define glusterfs 0 %define have_git 1 %define ceph 0 %define install_suse_fw 0 %define systemd 0 %define python_plugins 1 # # SUSE (openSUSE, SLES) specific settigs # %if 0%{?sles_version} == 10 %define build_bat 0 %define build_qt_monitor 0 %define build_sqlite3 0 %define have_git 0 %define python_plugins 0 %endif %if 0%{?suse_version} > 1010 %define install_suse_fw 1 %define _fwdefdir %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services %endif %if 0%{?suse_version} > 1140 %define systemd_support 1 %endif # # RedHat (CentOS, Fedora, RHEL) specific settings # %if 0%{?rhel_version} > 0 && 0%{?rhel_version} < 500 %define RHEL4 1 %define client_only 1 %define build_bat 0 %define build_qt_monitor 0 %define build_sqlite3 0 %define have_git 0 %define python_plugins 0 %endif # centos/rhel 5 : segfault when building qt monitor %if 0%{?centos_version} == 505 || 0%{?rhel_version} == 505 %define build_bat 0 %define build_qt_monitor 0 %define have_git 0 %define python_plugins 0 %endif %if 0%{?rhel_version} >= 700 || 0%{?centos_version} >= 700 || 0%{?fedora_version} >= 19 %define systemd_support 1 %if 0%{?fedora_version} != 19 %define glusterfs 1 %endif %endif %if 0%{?rhel_version} >= 700 %define ceph 1 %endif %if 0%{?systemd_support} BuildRequires: systemd %{?systemd_requires} %endif %if 0%{?glusterfs} BuildRequires: glusterfs-devel glusterfs-api-devel %endif %if 0%{?ceph} BuildRequires: ceph-devel %endif %if 0%{?have_git} BuildRequires: git-core %endif Source0: %{name}-%{version}.tar.gz #BuildRequires: elfutils BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: make BuildRequires: glibc BuildRequires: glibc-devel BuildRequires: ncurses-devel BuildRequires: perl BuildRequires: readline-devel BuildRequires: libstdc++-devel BuildRequires: zlib-devel BuildRequires: openssl-devel BuildRequires: libacl-devel BuildRequires: pkgconfig BuildRequires: lzo-devel BuildRequires: libfastlz-devel %if 0%{?build_sqlite3} %if 0%{?suse_version} BuildRequires: sqlite3-devel %else BuildRequires: sqlite-devel %endif %endif BuildRequires: mysql-devel BuildRequires: postgresql-devel BuildRequires: openssl BuildRequires: libcap-devel BuildRequires: mtx %if 0%{?build_bat} || 0%{?build_qt_monitor} BuildRequires: libqt4-devel %endif %if 0%{?python_plugins} BuildRequires: python-devel >= 2.6 %endif %if 0%{?suse_version} # suse_version: # 1315: SLE_12 # 1110: SLE_11 # 1010: SLE_10 BuildRequires: distribution-release BuildRequires: pwdutils BuildRequires: tcpd-devel BuildRequires: termcap BuildRequires: update-desktop-files %if 0%{?suse_version} > 1010 # link identical files BuildRequires: fdupes BuildRequires: lsb-release %endif %else # non suse BuildRequires: libtermcap-devel BuildRequires: passwd BuildRequires: tcp_wrappers # Some magic to be able to determine what platform we are running on. %if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora_version} BuildRequires: redhat-lsb # older versions require additional release packages %if 0%{?rhel_version} && 0%{?rhel_version} <= 600 BuildRequires: redhat-release %endif %if 0%{?centos_version} && 0%{?centos_version} <= 600 BuildRequires: redhat-release %endif %if 0%{?fedora_version} BuildRequires: fedora-release %endif %if 0%{?rhel_version} >= 600 || 0%{?centos_version} >= 600 || 0%{?fedora_version} >= 14 BuildRequires: tcp_wrappers-devel %endif %else # non suse, non redhat: eg. mandriva. BuildRequires: lsb-release %endif %endif Summary: Backup Archiving REcovery Open Sourced - metapackage Requires: %{name}-director = %{version} Requires: %{name}-storage = %{version} Requires: %{name}-client = %{version} %if 0%{?RHEL4} %define dscr Bareos - Backup Archiving Recovery Open Sourced. %else %define dscr Bareos - Backup Archiving Recovery Open Sourced. \ Bareos is a set of computer programs that permit you (or the system \ administrator) to manage backup, recovery, and verification of computer \ data across a network of computers of different kinds. In technical terms, \ it is a network client/server based backup program. Bareos is relatively \ easy to use and efficient, while offering many advanced storage management \ features that make it easy to find and recover lost or damaged files. \ Bareos source code has been released under the AGPL version 3 license. %endif %description %{dscr} # Notice : Don't try to change the order of package declaration # You will have side effect with PreReq %package bconsole Summary: Bareos administration console (CLI) Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} %package client Summary: Bareos client Meta-All-In-One package Group: Productivity/Archiving/Backup Requires: %{name}-bconsole = %{version} Requires: %{name}-filedaemon = %{version} %if 0%{?suse_version} Recommends: %{name}-traymonitor = %{version} %endif %package director Summary: Bareos Director daemon Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-database-common = %{version} Requires: %{name}-database-tools %if 0%{?suse_version} Requires(pre): pwdutils # Don't use this option on anything other then SUSE derived distributions # as Fedora & others don't know this tag Recommends: logrotate %else Requires(pre): shadow-utils %endif Provides: %{name}-dir %package storage Summary: Bareos Storage daemon Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Provides: %{name}-sd %if 0%{?suse_version} Requires(pre): pwdutils %else Requires(pre): shadow-utils %endif %if 0%{?glusterfs} %package storage-glusterfs Summary: GlusterFS support for the Bareos Storage daemon Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-storage = %{version} Requires: glusterfs %endif %if 0%{?ceph} %package storage-ceph Summary: CEPH support for the Bareos Storage daemon Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-storage = %{version} %endif %package storage-tape Summary: Tape support for the Bareos Storage daemon Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-storage = %{version} Requires: mtx %if !0%{?suse_version} Requires: mt-st %endif %package storage-fifo Summary: FIFO support for the Bareos Storage backend Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-storage = %{version} %package filedaemon Summary: Bareos File daemon (backup and restore client) Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Provides: %{name}-fd %if 0%{?suse_version} Requires(pre): pwdutils %else Requires(pre): shadow-utils %endif %package common Summary: Common files, required by multiple Bareos packages Group: Productivity/Archiving/Backup Requires: openssl %if 0%{?suse_version} Requires(pre): pwdutils %else Requires(pre): shadow-utils %endif Provides: %{name}-libs %package database-common Summary: Generic abstraction libs and files to connect to a database Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-database-backend = %{version} Requires: openssl Provides: %{name}-sql %package database-postgresql Summary: Libs & tools for postgresql catalog Group: Productivity/Archiving/Backup Requires: %{name}-database-common = %{version} Provides: %{name}-catalog-postgresql Provides: %{name}-database-backend %package database-mysql Summary: Libs & tools for mysql catalog Group: Productivity/Archiving/Backup Requires: %{name}-database-common = %{version} Provides: %{name}-catalog-mysql Provides: %{name}-database-backend %if 0%{?build_sqlite3} %package database-sqlite3 Summary: Libs & tools for sqlite3 catalog Group: Productivity/Archiving/Backup %if 0%{?suse_version} Requires: sqlite3 %endif Requires: %{name}-database-common = %{version} Provides: %{name}-catalog-sqlite3 Provides: %{name}-database-backend %endif %package database-tools Summary: Bareos CLI tools with database dependencies (bareos-dbcheck, bscan) Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} Requires: %{name}-database-common = %{version} Provides: %{name}-dbtools %package tools Summary: Bareos CLI tools (bcopy, bextract, bls, bregex, bwild) Group: Productivity/Archiving/Backup Requires: %{name}-common = %{version} %if 0%{build_qt_monitor} %package traymonitor Summary: Bareos Tray Monitor (QT) Group: Productivity/Archiving/Backup # Added to by pass the 09 checker rules (conflict with bareos-tray-monitor.conf) # This is mostly wrong cause the two binaries can use it! Conflicts: %{name}-tray-monitor-gtk Provides: %{name}-tray-monitor-qt %endif %if 0%{?build_bat} %package bat Summary: Bareos Admin Tool (GUI) Group: Productivity/Archiving/Backup %endif %package devel Summary: Devel headers Group: Development/Languages/C and C++ Requires: %{name}-common = %{version} Requires: zlib-devel Requires: libacl-devel Requires: postgresql-devel Requires: libcap-devel %if 0%{?build_sqlite3} %if 0%{?suse_version} Requires: sqlite3-devel %else Requires: sqlite-devel %endif %endif %if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora_version} Requires: openssl-devel %else Requires: libopenssl-devel %endif %if 0%{?rhel_version} >= 600 || 0%{?centos_version} >= 600 || 0%{?fedora_version} Requires: tcp_wrappers-devel %else %if 0%{?rhel_version} || 0%{?centos_version} Requires: tcp_wrappers %else Requires: tcpd-devel %endif %endif %if 0%{?rhel_version} >= 700 || 0%{?centos_version} >= 700 || 0%{?fedora_version} >= 19 Requires: mariadb-devel %else %if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora_version} Requires: mysql-devel %else Requires: libmysqlclient-devel %endif %endif %if 0%{?python_plugins} %package director-python-plugin Summary: Python plugin for Bareos Director daemon Group: Productivity/Archiving/Backup Requires: bareos-director = %{version} %package filedaemon-python-plugin Summary: Python plugin for Bareos File daemon Group: Productivity/Archiving/Backup Requires: bareos-filedaemon = %{version} %package storage-python-plugin Summary: Python plugin for Bareos Storage daemon Group: Productivity/Archiving/Backup Requires: bareos-storage = %{version} %description director-python-plugin %{dscr} This package contains the python plugin for the director daemon %description filedaemon-python-plugin %{dscr} This package contains the python plugin for the file daemon %description storage-python-plugin %{dscr} This package contains the python plugin for the storage daemon %endif %description client %{dscr} This package is a meta package requiring the packages containing the fd and the console. This is for client only installation. %description bconsole %{dscr} This package contains the bconsole (the CLI interface program) %description director %{dscr} This package contains the Director Service (Bareos main service daemon) %description storage %{dscr} This package contains the Storage Daemon (Bareos service to read and write data from/to media) %description storage-tape %{dscr} This package contains the Storage Daemon tape support (Bareos service to read and write data from/to tape media) %if 0%{?glusterfs} %description storage-glusterfs %{dscr} This package contains the Storage backend for GlusterFS. %endif %if 0%{?ceph} %description storage-ceph %{dscr} This package contains the Storage backend for CEPH. %endif %description storage-fifo %{dscr} This package contains the Storage backend for FIFO files. This package is only required, when a resource "Archive Device = fifo" should be used by the Bareos Storage Daemon. %description filedaemon %{dscr} This package contains the File Daemon (Bareos client daemon to read/write data from the backed up computer) %description common %{dscr} This package contains the shared libraries that are used by multiple daemons and tools. %description database-common %{dscr} This package contains the shared libraries that abstract the catalog interface %description database-postgresql %{dscr} This package contains the shared library to access postgresql as catalog db. %description database-mysql %{dscr} This package contains the shared library to use mysql as catalog db. %if 0%{?build_sqlite3} %description database-sqlite3 %{dscr} This package contains the shared library to use sqlite as catalog db. %endif %description database-tools %{dscr} This package contains Bareos database tools. %description tools %{dscr} This package contains Bareos tools. %if 0%{?build_qt_monitor} %description traymonitor %{dscr} This package contains the tray monitor (QT based). %endif %if 0%{?build_bat} %description bat %{dscr} This package contains the Bareos Admin Tool (BAT). BAT is a graphical interface for Bareos. %endif %description devel %{dscr} This package contains bareos development files. %prep %setup %build %if !0%{?suse_version} export PATH=$PATH:/usr/lib64/qt4/bin:/usr/lib/qt4/bin %endif export MTX=/usr/sbin/mtx # Notice keep the upstream order of ./configure --help %configure \ --prefix=%{_prefix} \ --libdir=%{library_dir} \ --sbindir=%{_sbindir} \ --with-sbin-perm=755 \ --sysconfdir=%{_sysconfdir}/bareos \ --mandir=%{_mandir} \ --docdir=%{_docdir}/%{name} \ --htmldir=%{_docdir}/%{name}/html \ --with-archivedir=/var/lib/bareos/storage \ --with-backenddir=%{backend_dir} \ --with-scriptdir=%{script_dir} \ --with-working-dir=%{working_dir} \ --with-plugindir=%{plugin_dir} \ --with-pid-dir=%{pid_dir} \ --with-bsrdir=%{bsr_dir} \ --with-logdir=/var/log/bareos \ --with-subsys-dir=%{_subsysdir} \ %if 0%{?python_plugins} --with-python \ %endif --enable-smartalloc \ --disable-conio \ --enable-readline \ --enable-batch-insert \ --enable-dynamic-cats-backends \ --enable-dynamic-storage-backends \ --enable-scsi-crypto \ --enable-lmdb \ --enable-ndmp \ --enable-ipv6 \ --enable-acl \ --enable-xattr \ %if 0%{?build_bat} --enable-bat \ %endif %if 0%{?build_qt_monitor} --enable-traymonitor \ %endif %if 0%{?client_only} --enable-client-only \ %endif --with-postgresql \ --with-mysql \ %if 0%{?build_sqlite3} --with-sqlite3 \ %endif --with-tcp-wrappers \ --with-dir-user=%{director_daemon_user} \ --with-dir-group=%{daemon_group} \ --with-sd-user=%{storage_daemon_user} \ --with-sd-group=%{storage_daemon_group} \ --with-fd-user=%{file_daemon_user} \ --with-fd-group=%{daemon_group} \ --with-dir-password="XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX" \ --with-fd-password="XXX_REPLACE_WITH_CLIENT_PASSWORD_XXX" \ --with-sd-password="XXX_REPLACE_WITH_STORAGE_PASSWORD_XXX" \ --with-mon-dir-password="XXX_REPLACE_WITH_DIRECTOR_MONITOR_PASSWORD_XXX" \ --with-mon-fd-password="XXX_REPLACE_WITH_CLIENT_MONITOR_PASSWORD_XXX" \ --with-mon-sd-password="XXX_REPLACE_WITH_STORAGE_MONITOR_PASSWORD_XXX" \ --with-openssl \ --with-basename="XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX" \ --with-hostname="XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX" \ %if 0%{?systemd_support} --with-systemd \ %endif --enable-includes #Add flags %__make CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" %{?_smp_mflags}; %install %if 0%{?suse_version} %makeinstall DESTDIR=%{buildroot} install %else make DESTDIR=%{buildroot} install %endif make DESTDIR=%{buildroot} install-autostart install -d -m 755 %{buildroot}/usr/share/applications install -d -m 755 %{buildroot}/usr/share/pixmaps install -d -m 755 %{buildroot}%{backend_dir} install -d -m 755 %{buildroot}%{working_dir} install -d -m 755 %{buildroot}%{plugin_dir} #Cleaning for F in \ %if 0%{?client_only} %{_mandir}/man1/bregex.1.gz \ %{_mandir}/man1/bsmtp.1.gz \ %{_mandir}/man1/bwild.1.gz \ %{_mandir}/man8/bareos-dbcheck.8.gz \ %{_mandir}/man8/bareos-dir.8.gz \ %{_mandir}/man8/bareos-sd.8.gz \ %{_mandir}/man8/bareos.8.gz \ %{_mandir}/man8/bcopy.8.gz \ %{_mandir}/man8/bextract.8.gz \ %{_mandir}/man8/bls.8.gz \ %{_mandir}/man8/bpluginfo.8.gz \ %{_mandir}/man8/bscan.8.gz \ %{_mandir}/man8/bscrypto.8.gz \ %{_mandir}/man8/btape.8.gz \ %{_sysconfdir}/logrotate.d/bareos-dir \ %{_sysconfdir}/rc.d/init.d/bareos-dir \ %{_sysconfdir}/rc.d/init.d/bareos-sd \ %{script_dir}/disk-changer \ %{script_dir}/mtx-changer \ %{_sysconfdir}/bareos/mtx-changer.conf \ %endif %if 0%{?install_suse_fw} == 0 %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/bareos-dir \ %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/bareos-sd \ %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/bareos-fd \ %endif %{script_dir}/bareos \ %{script_dir}/bareos_config \ %{script_dir}/btraceback.dbx \ %{script_dir}/btraceback.mdb \ %{script_dir}/bareos-ctl-funcs \ %{script_dir}/bareos-ctl-dir \ %{script_dir}/bareos-ctl-fd \ %{script_dir}/bareos-ctl-sd \ %{_docdir}/%{name}/INSTALL \ %{_sbindir}/%{name} do rm -f "%{buildroot}/$F" done # remove links to libraries # for i in #{buildroot}/#{_libdir}/libbareos*; do printf "$i: "; readelf -a $i | grep SONAME; done find %{buildroot}/%{library_dir} -type l -name "libbareos*.so" -maxdepth 1 -exec rm {} \; ls -la %{buildroot}/%{library_dir} %if ! 0%{?python_plugins} rm -f %{buildroot}/%{plugin_dir}/python-*.so rm -f %{buildroot}/%{plugin_dir}/*.py* %endif %if 0%{?build_bat} %if 0%{?suse_version} > 1010 %suse_update_desktop_file -i bat System Utility Archiving %endif %endif # install tray monitor # #if 0#{?build_qt_monitor} # #if 0#{?suse_version} > 1010 # disables, because suse_update_desktop_file complains # that there are two desktop file (applications and autostart) # ##suse_update_desktop_file bareos-tray-monitor System Backup # #endif # #endif # remove man page if bat is not built %if !0%{?build_bat} rm %{buildroot}%{_mandir}/man1/bat.1.gz %endif # remove man page if qt tray monitor is not built %if !0%{?build_qt_monitor} rm %{buildroot}%{_mandir}/man1/bareos-tray-monitor.1.gz %endif # install systemd service files %if 0%{?systemd_support} install -d -m 755 %{buildroot}%{_unitdir} install -m 644 platforms/systemd/bareos-dir.service %{buildroot}%{_unitdir} install -m 644 platforms/systemd/bareos-fd.service %{buildroot}%{_unitdir} install -m 644 platforms/systemd/bareos-sd.service %{buildroot}%{_unitdir} %endif # Create the Readme files for the meta packages [ -d %{buildroot}%{_docdir}/%{name}/ ] || install -d -m 755 %{buildroot}%{_docdir}/%{name} echo "This meta package emulates the former bareos-client package" > %{buildroot}%{_docdir}/%{name}/README.bareos-client echo "This is a meta package to install a full bareos system" > %{buildroot}%{_docdir}/%{name}/README.bareos %files %defattr(-, root, root) %{_docdir}/%{name}/README.bareos %files client %defattr(-, root, root) %dir %{_docdir}/%{name} %{_docdir}/%{name}/README.bareos-client %files bconsole # console package %defattr(-, root, root) %attr(0640, root, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bconsole.conf %{script_dir}/bconsole %{_bindir}/bconsole %{_sbindir}/bconsole %{_mandir}/man1/bconsole.1.gz %if !0%{?client_only} %files director # dir package (bareos-dir) %defattr(-, root, root) %if 0%{?suse_version} %{_sysconfdir}/init.d/bareos-dir %{_sbindir}/rcbareos-dir %if 0%{?install_suse_fw} # use noreplace if user has adjusted its list of IP %attr(0644, root, root) %config(noreplace) %{_fwdefdir}/bareos-dir %endif %else %{_sysconfdir}/rc.d/init.d/bareos-dir %endif %attr(0640, %{director_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-dir.conf %config(noreplace) %{_sysconfdir}/logrotate.d/%{name}-dir # we do not have any dir plugin but the python plugin #%%{plugin_dir}/*-dir.so %{script_dir}/delete_catalog_backup %{script_dir}/make_catalog_backup %{script_dir}/make_catalog_backup.pl %{_sbindir}/bareos-dir %dir %{_docdir}/%{name} %{_mandir}/man8/bareos-dir.8.gz %{_mandir}/man8/bareos.8.gz %if 0%{?systemd_support} %{_unitdir}/bareos-dir.service %endif # query.sql is not a config file, # but can be personalized by end user. # a rpmlint rule is add to filter the warning %config(noreplace) %{script_dir}/query.sql %files storage # sd package (bareos-sd, bls, btape, bcopy, bextract) %defattr(-, root, root) %attr(0640, %{storage_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-sd.conf %attr(-, %{storage_daemon_user}, %{daemon_group}) %dir %{_sysconfdir}/bareos/bareos-sd.d %if 0%{?suse_version} %{_sysconfdir}/init.d/bareos-sd %{_sbindir}/rcbareos-sd %if 0%{?install_suse_fw} # use noreplace if user has adjusted its list of IP %attr(0644, root, root) %config(noreplace) %{_fwdefdir}/bareos-sd %endif %else %{_sysconfdir}/rc.d/init.d/bareos-sd %endif %{_sbindir}/bareos-sd %{_sbindir}/bscrypto %{script_dir}/disk-changer %{plugin_dir}/autoxflate-sd.so %{plugin_dir}/scsicrypto-sd.so %{_mandir}/man8/bscrypto.8.gz %{_mandir}/man8/bareos-sd.8.gz %if 0%{?systemd_support} %{_unitdir}/bareos-sd.service %endif %attr(0775, %{storage_daemon_user}, %{daemon_group}) %dir /var/lib/bareos/storage %files storage-tape # tape specific files %defattr(-, root, root) %{backend_dir}/libbareossd-gentape*.so %{backend_dir}/libbareossd-tape*.so %{script_dir}/mtx-changer %config(noreplace) %{_sysconfdir}/bareos/mtx-changer.conf %{_mandir}/man8/btape.8.gz %{_sbindir}/btape %attr(0640, %{storage_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-sd.d/device-tape-with-autoloader.conf %{plugin_dir}/scsitapealert-sd.so %files storage-fifo %defattr(-, root, root) %{backend_dir}/libbareossd-fifo*.so %attr(0640, %{storage_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-sd.d/device-fifo.conf %if 0%{?glusterfs} %files storage-glusterfs %defattr(-, root, root) %{backend_dir}/libbareossd-gfapi*.so %attr(0640, %{storage_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-sd.d/device-gluster.conf %endif %if 0%{?ceph} %files storage-ceph %defattr(-, root, root) %{backend_dir}/libbareossd-rados*.so %{backend_dir}/libbareossd-cephfs*.so %attr(0640, %{storage_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-sd.d/device-ceph-rados.conf %endif %endif # not client_only %files filedaemon # fd package (bareos-fd, plugins) %defattr(-, root, root) %attr(0640, %{file_daemon_user}, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bareos-fd.conf %if 0%{?suse_version} %{_sysconfdir}/init.d/bareos-fd %{_sbindir}/rcbareos-fd %if 0%{?install_suse_fw} # use noreplace if user has adjusted its list of IP %attr(0644, root, root) %config(noreplace) %{_fwdefdir}/bareos-fd %endif %else %{_sysconfdir}/rc.d/init.d/bareos-fd %endif %{_sbindir}/bareos-fd %{plugin_dir}/bpipe-fd.so %{_mandir}/man8/bareos-fd.8.gz # tray monitor %if 0%{?systemd_support} %{_unitdir}/bareos-fd.service %endif %files common # common shared libraries (without db) %defattr(-, root, root) %attr(-, root, %{daemon_group}) %dir %{_sysconfdir}/bareos %if !0%{?client_only} %attr(-, %{daemon_user}, %{daemon_group}) %dir %{_sysconfdir}/bareos/bareos-dir.d %endif %dir %{backend_dir} %{library_dir}/libbareos-%{_libversion}.so %{library_dir}/libbareoscfg-%{_libversion}.so %{library_dir}/libbareosfind-%{_libversion}.so %{library_dir}/libbareoslmdb-%{_libversion}.so %if !0%{?client_only} %{library_dir}/libbareosndmp-%{_libversion}.so %{library_dir}/libbareossd-%{_libversion}.so %endif # generic stuff needed from multiple bareos packages %dir /usr/lib/bareos/ %dir %{script_dir} %{script_dir}/bareos-config %{script_dir}/bareos-config-lib.sh %{script_dir}/bareos-explorer %{script_dir}/btraceback.gdb %if "%{_libdir}" != "/usr/lib/" %dir %{_libdir}/bareos/ %endif %dir %{plugin_dir} %if !0%{?client_only} %{_bindir}/bsmtp %{_sbindir}/bsmtp %endif %{_sbindir}/btraceback %if !0%{?client_only} %{_mandir}/man1/bsmtp.1.gz %endif %{_mandir}/man8/btraceback.8.gz %attr(0770, %{daemon_user}, %{daemon_group}) %dir %{working_dir} %attr(0775, %{daemon_user}, %{daemon_group}) %dir /var/log/bareos %doc AGPL-3.0.txt AUTHORS LICENSE README.* %doc build/ %if !0%{?client_only} %files database-common # catalog independent files %defattr(-, root, root) %{library_dir}/libbareossql-%{_libversion}.so %{library_dir}/libbareoscats-%{_libversion}.so %dir %{script_dir}/ddl %dir %{script_dir}/ddl/creates %dir %{script_dir}/ddl/drops %dir %{script_dir}/ddl/grants %dir %{script_dir}/ddl/updates %{script_dir}/create_bareos_database %{script_dir}/drop_bareos_database %{script_dir}/drop_bareos_tables %{script_dir}/grant_bareos_privileges %{script_dir}/make_bareos_tables %{script_dir}/update_bareos_tables %{script_dir}/ddl/versions.map %files database-postgresql # postgresql catalog files %defattr(-, root, root) %{script_dir}/ddl/*/postgresql*.sql %{backend_dir}/libbareoscats-postgresql.so %{backend_dir}/libbareoscats-postgresql-%{_libversion}.so %files database-mysql # mysql catalog files %defattr(-, root, root) %{script_dir}/ddl/*/mysql*.sql %{backend_dir}/libbareoscats-mysql.so %{backend_dir}/libbareoscats-mysql-%{_libversion}.so %if 0%{?build_sqlite3} %files database-sqlite3 # sqlite3 catalog files %defattr(-, root, root) %{script_dir}/ddl/*/sqlite3*.sql %{backend_dir}/libbareoscats-sqlite3.so %{backend_dir}/libbareoscats-sqlite3-%{_libversion}.so %endif %files database-tools # dbtools with link to db libs (dbcheck, bscan) %defattr(-, root, root) %{_sbindir}/bareos-dbcheck %{_sbindir}/bscan %{_mandir}/man8/bareos-dbcheck.8.gz %{_mandir}/man8/bscan.8.gz %files tools # tools without link to db libs (bwild, bregex) %defattr(-, root, root) %{_bindir}/bregex %{_bindir}/bwild %{_sbindir}/bcopy %{_sbindir}/bextract %{_sbindir}/bls %{_sbindir}/bregex %{_sbindir}/bwild %{_sbindir}/bpluginfo %{_mandir}/man1/bwild.1.gz %{_mandir}/man1/bregex.1.gz %{_mandir}/man8/bcopy.8.gz %{_mandir}/man8/bextract.8.gz %{_mandir}/man8/bls.8.gz %{_mandir}/man8/bpluginfo.8.gz %if 0%{?build_qt_monitor} %files traymonitor %defattr(-,root, root) %attr(-, root, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/tray-monitor.conf %config %{_sysconfdir}/xdg/autostart/bareos-tray-monitor.desktop %{_bindir}/bareos-tray-monitor %{_mandir}/man1/bareos-tray-monitor.1.gz /usr/share/applications/bareos-tray-monitor.desktop /usr/share/pixmaps/bareos-tray-monitor.xpm %endif %if 0%{?build_bat} %files bat %defattr(-, root, root) %attr(-, root, %{daemon_group}) %{_bindir}/bat %attr(640, root, %{daemon_group}) %config(noreplace) %{_sysconfdir}/bareos/bat.conf %{_prefix}/share/pixmaps/bat.png %{_prefix}/share/pixmaps/bat.svg %{_prefix}/share/applications/bat.desktop %{_mandir}/man1/bat.1.gz %dir %{_docdir}/%{name} %dir %{_docdir}/%{name}/html/ %doc %{_docdir}/%{name}/html/bat/ %endif %endif # client_only %files devel %defattr(-, root, root) /usr/include/bareos %{library_dir}/*.la %if 0%{?python_plugins} %files filedaemon-python-plugin %defattr(-, root, root) %{plugin_dir}/python-fd.so %{plugin_dir}/bareos-fd.py* %{plugin_dir}/bareos-fd-local-fileset.py* %{plugin_dir}/bareos-fd-mock-test.py* %{plugin_dir}/BareosFdPluginBaseclass.py* %{plugin_dir}/BareosFdPluginLocalFileset.py* %{plugin_dir}/BareosFdWrapper.py* %{plugin_dir}/bareos_fd_consts.py* %files director-python-plugin %defattr(-, root, root) %{plugin_dir}/python-dir.so %{plugin_dir}/bareos-dir.py* %{plugin_dir}/bareos_dir_consts.py* %{plugin_dir}/BareosDirPluginBaseclass.py* %{plugin_dir}/bareos-dir-class-plugin.py* %{plugin_dir}/BareosDirWrapper.py* %files storage-python-plugin %defattr(-, root, root) %{plugin_dir}/python-sd.so %{plugin_dir}/bareos-sd.py* %{plugin_dir}/bareos_sd_consts.py* %endif # python_plugins # # Define some macros for updating the system settings. # %if 0%{?RHEL4} %define add_service_start() ( /sbin/chkconfig --add %1; %nil) %define stop_on_removal() ( /sbin/service %1 stop >/dev/null 2>&1 || /sbin/chkconfig --del %1 || true; %nil) %define restart_on_update() (/sbin/service %1 condrestart >/dev/null 2>&1 || true; %nil) %define insserv_cleanup() (/bin/true; %nil) %define create_group() (getent group %1 > /dev/null || groupadd -r %1; %nil); %define create_user() ( getent passwd %1 > /dev/null || useradd -r -c "%1" -d %{working_dir} -g %{daemon_group} -s /bin/false %1; %nil); %else # non RHEL4 %if 0%{?suse_version} %if 0%{!?add_service_start:1} %define add_service_start() \ SERVICE=%1 \ #service_add $1 \ %fillup_and_insserv $SERVICE \ %nil %endif %else # non suse, systemd %define insserv_cleanup() \ /bin/true \ %nil %if 0%{?systemd_support} # non suse, systemd %define add_service_start() \ /bin/systemctl daemon-reload >/dev/null 2>&1 || true \ /bin/systemctl enable %1.service >/dev/null 2>&1 || true \ %nil %define stop_on_removal() \ test -n "$FIRST_ARG" || FIRST_ARG=$1 \ if test "$FIRST_ARG" = "0" ; then \ /bin/systemctl stop %1.service > /dev/null 2>&1 || true \ fi \ %nil %define restart_on_update() \ test -n "$FIRST_ARG" || FIRST_ARG=$1 \ if test "$FIRST_ARG" -ge 1 ; then \ /bin/systemctl try-restart %1.service >/dev/null 2>&1 || true \ fi \ %nil %else # non suse, init.d %define add_service_start() \ /sbin/chkconfig --add %1 \ %nil %define stop_on_removal() \ test -n "$FIRST_ARG" || FIRST_ARG=$1 \ if test "$FIRST_ARG" = "0" ; then \ /sbin/service %1 stop >/dev/null 2>&1 || \ /sbin/chkconfig --del %1 || true \ fi \ %nil %define restart_on_update() \ test -n "$FIRST_ARG" || FIRST_ARG=$1 \ if test "$FIRST_ARG" -ge 1 ; then \ /sbin/service %1 condrestart >/dev/null 2>&1 || true \ fi \ %nil %endif %endif %define create_group() \ getent group %1 > /dev/null || groupadd -r %1 \ %nil # shell: use /bin/false, because nologin has different paths on different distributions %define create_user() \ getent passwd %1 > /dev/null || useradd -r --comment "%1" --home %{working_dir} -g %{daemon_group} --shell /bin/false %1 \ %nil %endif %post director %{script_dir}/bareos-config initialize_local_hostname %{script_dir}/bareos-config initialize_passwords %{script_dir}/bareos-config initialize_database_driver %add_service_start bareos-dir %post storage # pre script has already generated the storage daemon user, # but here we add the user to additional groups %{script_dir}/bareos-config setup_sd_user %{script_dir}/bareos-config initialize_local_hostname %{script_dir}/bareos-config initialize_passwords %add_service_start bareos-sd %post filedaemon %{script_dir}/bareos-config initialize_local_hostname %{script_dir}/bareos-config initialize_passwords %add_service_start bareos-fd %post bconsole %{script_dir}/bareos-config initialize_local_hostname %{script_dir}/bareos-config initialize_passwords %post common /sbin/ldconfig %postun common /sbin/ldconfig %post database-common /sbin/ldconfig %postun database-common /sbin/ldconfig %post database-postgresql /sbin/ldconfig %postun database-postgresql /sbin/ldconfig %post database-mysql /sbin/ldconfig %postun database-mysql /sbin/ldconfig %if 0%{?build_sqlite3} %post database-sqlite3 /sbin/ldconfig %postun database-sqlite3 /sbin/ldconfig %endif %if 0%{?build_qt_monitor} %post traymonitor %{script_dir}/bareos-config initialize_local_hostname %{script_dir}/bareos-config initialize_passwords %endif %if 0%{?build_bat} %post bat %{script_dir}/bareos-config initialize_local_hostname %{script_dir}/bareos-config initialize_passwords %endif %pre director %create_group %{daemon_group} %create_user %{director_daemon_user} exit 0 %pre storage %create_group %{daemon_group} %create_user %{storage_daemon_user} exit 0 %pre filedaemon %create_group %{daemon_group} %create_user %{storage_daemon_user} exit 0 %pre common %create_group %{daemon_group} %create_user %{daemon_user} exit 0 %preun director %stop_on_removal bareos-dir %preun storage %stop_on_removal bareos-sd %preun filedaemon %stop_on_removal bareos-fd %postun director # to prevent aborting jobs, no restart on update %insserv_cleanup %postun storage # to prevent aborting jobs, no restart on update %insserv_cleanup %postun filedaemon %restart_on_update bareos-fd %insserv_cleanup %changelog bareos-Release-14.2.6/platforms/packaging/debian.debtransform000066400000000000000000000001241263011562700242220ustar00rootroot00000000000000# this file is only required to activate debtransform from Open Build Service (OBS) bareos-Release-14.2.6/platforms/redhat/000077500000000000000000000000001263011562700177165ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/redhat/Makefile.in000066400000000000000000000033361263011562700217700ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the RedHat specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install_logrotate install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install_logrotate: @$(MKDIR) $(DESTDIR)/etc/logrotate.d @$(INSTALL_DATA) ../../scripts/logrotate $(DESTDIR)/etc/logrotate.d/bareos-dir install-autostart-fd: @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bareos-fd; then \ /sbin/chkconfig --del bareos-fd; \ fi @$(MKDIR) $(DESTDIR)/etc/rc.d/init.d @$(INSTALL_PROGRAM) bareos-fd $(DESTDIR)/etc/rc.d/init.d/bareos-fd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-fd; \ fi install-autostart-sd: @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bareos-sd; then \ /sbin/chkconfig --del bareos-sd; \ fi @$(MKDIR) $(DESTDIR)/etc/rc.d/init.d @$(INSTALL_PROGRAM) bareos-sd $(DESTDIR)/etc/rc.d/init.d/bareos-sd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-sd; \ fi install-autostart-dir: @if test x$(DESTDIR) = x -a -f /etc/rc.d/init.d/bareos-dir; then \ /sbin/chkconfig --del bareos-dir; \ fi @$(MKDIR) $(DESTDIR)/etc/rc.d/init.d @$(INSTALL_PROGRAM) bareos-dir $(DESTDIR)/etc/rc.d/init.d/bareos-dir # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-dir; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) Makefile @$(RMF) bareos-sd bareos-fd bareos-dir devclean: clean @$(RMF) Makefile @$(RMF) bareos-sd bareos-fd bareos-dir bareos-Release-14.2.6/platforms/redhat/bareos-dir.in000066400000000000000000000040361263011562700223000ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 92 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/init.d/functions DIR_USER=@dir_user@ DIR_GROUP=@dir_group@ DIR_OPTIONS='' OS=`uname -s` # if /lib/tls exists, force Bareos to use the glibc pthreads instead if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then export LD_ASSUME_KERNEL=2.4.19 fi # pull in any user defined DIR_DIR_OPTIONS, DIR_USER, or DIR_GROUP [ -f /etc/sysconfig/bareos ] && . /etc/sysconfig/bareos # # Disable Glibc malloc checks, it doesn't help and it keeps from getting # good dumps MALLOC_CHECK_=0 export MALLOC_CHECK_ function checkcfg () { echo "Checking Configuration and Database connection ... " su -s /bin/sh ${DIR_USER} -c "@sbindir@/bareos-dir -f -t -c @sysconfdir@/bareos-dir.conf" if [ $? -eq 0 ]; then return 0 else return 1 fi } RETVAL=0 case "$1" in start) checkcfg if [ $? -eq 0 ]; then if [ "${DIR_GROUP}" != '' ]; then DIR_OPTIONS="${DIR_OPTIONS} -g ${DIR_GROUP}" fi echo -n "Starting Bareos Director services: " daemon --user ${DIR_USER} @sbindir@/bareos-dir $2 ${DIR_OPTIONS} -c @sysconfdir@/bareos-dir.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-dira else echo "Configuration check failed, please check log file for errors" fi ;; stop) echo -n "Stopping Bareos Director services: " killproc @sbindir@/bareos-dir RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-dir RETVAL=$? ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit $RETVAL bareos-Release-14.2.6/platforms/redhat/bareos-fd.in000066400000000000000000000031151263011562700221100ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 91 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/init.d/functions FD_USER=@fd_user@ FD_GROUP=@fd_group@ FD_OPTIONS='' OS=`uname -s` # if /lib/tls exists, force Bareos to use the glibc pthreads instead if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then export LD_ASSUME_KERNEL=2.4.19 fi # pull in any user defined FD_OPTIONS, FD_USER, FD_GROUP [ -f /etc/sysconfig/bareos ] && . /etc/sysconfig/bareos # # Disable Glibc malloc checks, it doesn't help and it keeps from getting # good dumps MALLOC_CHECK_=0 export MALLOC_CHECK_ RETVAL=0 case "$1" in start) if [ "${FD_GROUP}" != '' ]; then FD_OPTIONS="${FD_OPTIONS} -g ${FD_GROUP}" fi echo -n "Starting Bareos File services: " daemon --user ${FD_USER} @sbindir@/bareos-fd $2 ${FD_OPTIONS} -c @sysconfdir@/bareos-fd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-fd ;; stop) echo -n "Stopping Bareos File services: " killproc @sbindir@/bareos-fd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-fd RETVAL=$? ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit $RETVAL bareos-Release-14.2.6/platforms/redhat/bareos-sd.in000066400000000000000000000031321263011562700221240ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/init.d/functions SD_USER=@sd_user@ SD_GROUP=@sd_group@ SD_OPTIONS='' OS=`uname -s` # if /lib/tls exists, force Bareos to use the glibc pthreads instead if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then export LD_ASSUME_KERNEL=2.4.19 fi # pull in any user defined SD_OPTIONS, SD_USER, or SD_GROUP [ -f /etc/sysconfig/bareos ] && . /etc/sysconfig/bareos # # Disable Glibc malloc checks, it doesn't help and it keeps from getting # good dumps MALLOC_CHECK_=0 export MALLOC_CHECK_ RETVAL=0 case "$1" in start) if [ "${SD_GROUP}" != '' ]; then SD_OPTIONS="${SD_OPTIONS} -g ${SD_GROUP}" fi echo -n "Starting Bareos Storage services: " daemon --user ${SD_USER} @sbindir@/bareos-sd $2 ${SD_OPTIONS} -c @sysconfdir@/bareos-sd.conf RETVAL=$? echo [ $RETVAL -eq 0 ] && touch @subsysdir@/bareos-sd ;; stop) echo -n "Stopping Bareos Storage services: " killproc @sbindir@/bareos-sd RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-sd RETVAL=$? ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit $RETVAL bareos-Release-14.2.6/platforms/slackware/000077500000000000000000000000001263011562700204235ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/slackware/Makefile.in000066400000000000000000000024241263011562700224720ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Slackware specific installation. # # 22 January 2003 -- Kern Sibbald # and corrected for Gentoo by # Patrick Naubert 25 Jan 2003 # and reworked for Slackware by # Matt Howard 09 Mar 2004 # further reworked for Slackware without Perl dependency by # Phil Stracchino 13 Mar 2004 # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: install-autostart-rc @$(MKDIR) $(DESTDIR)/etc/rc.d @$(INSTALL_PROGRAM) rc.bareos-fd $(DESTDIR)/etc/rc.d/rc.bareos-fd install-autostart-sd: install-autostart-rc @$(MKDIR) $(DESTDIR)/etc/rc.d @$(INSTALL_PROGRAM) rc.bareos-sd $(DESTDIR)/etc/rc.d/rc.bareos-sd install-autostart-dir: install-autostart-rc @$(MKDIR) $(DESTDIR)/etc/rc.d @$(INSTALL_PROGRAM) rc.bareos-dir $(DESTDIR)/etc/rc.d/rc.bareos-dir install-autostart-rc: @$(MKDIR) $(DESTDIR)/etc/rc.d @$(INSTALL_PROGRAM) functions.bareos $(DESTDIR)/etc/rc.d sh ./local-install.sh install $(DESTDIR) clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) rc.bareos-sd rc.bareos-fd rc.bareos-dir @$(RMF) Makefile devclean: clean @$(RMF) rc.bareos-sd rc.bareos-fd rc.bareos-dir @$(RMF) Makefile bareos-Release-14.2.6/platforms/slackware/functions.bareos.in000066400000000000000000000074721263011562700242470ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos daemons. # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # description: Backup Archiving REcovery Open Sourced. # PSCMD="@PSCMD@" # All these are not *really* needed but it makes it # easier to "steal" this code for the development # environment where they are different. # BACFDBIN=@sbindir@ BACFDCFG=@sysconfdir@ BACSDBIN=@sbindir@ BACSDCFG=@sysconfdir@ BACDIRBIN=@sbindir@ BACDIRCFG=@sysconfdir@ PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ DIR_PORT=@dir_port@ FD_PORT=@fd_port@ SD_PORT=@sd_port@ DIR_USER=@dir_user@ DIR_GROUP=@dir_group@ FD_USER=@fd_user@ FD_GROUP=@fd_group@ SD_USER=@sd_user@ SD_GROUP=@sd_group@ # A function to stop a program. killproc() { RC=0 # Test syntax. if [ $# = 0 ]; then echo "Usage: killproc {program} [signal]" return 1 fi notset=0 # check for third arg to be kill level if [ "$3" != "" ] ; then killlevel=$3 else notset=1 killlevel="-9" fi # Get base program name base=`basename $1` # Find pid. pid=`pidofproc $base $2` # Kill it. if [ "$pid" != "" ] ; then if [ "$notset" = "1" ] ; then if ps -p $pid>/dev/null 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid 2>/dev/null sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 3 if ps -p $pid >/dev/null 2>&1 ; then kill -KILL $pid 2>/dev/null fi fi fi fi ps -p $pid >/dev/null 2>&1 RC=$? [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" # RC=$((! $RC)) # use specified level only else if ps -p $pid >/dev/null 2>&1; then kill $killlevel $pid 2>/dev/null RC=$? [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" fi fi else failure "$base shutdown" fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f ${PIDDIR}/$base.$2.pid fi return $RC } # A function to find the pid of a program. pidofproc() { pid="" # Test syntax. if [ $# = 0 ] ; then echo "Usage: pidofproc {program}" return 1 fi # Get base program name base=`basename $1` # First try PID file if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Next try "pidof" if [ -x /sbin/pidof ] ; then pid=`/sbin/pidof $1` fi if [ "$pid" != "" ] ; then echo $pid return 0 fi # Finally try to extract it from ps ${PSCMD} | grep $1 | awk '{ print $1 }' | tr '\n' ' ' return 0 } status() { # Test syntax. if [ $# = 0 ] ; then echo "Usage: status {program}" return 1 fi # Get base program name base=`basename $1` # First try "pidof" if [ -x /sbin/pidof ] ; then pid=`/sbin/pidof $1` fi if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 else pid=`${PSCMD} | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $2) || (("(" prog ")") == $2) || (("[" prog "]") == $2) || ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 fi fi # Next try the PID files if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo "$base not running, but pid file exists" return 1 fi fi # See if the subsys lock exists if [ -f ${SUBSYSDIR}/$base ] ; then echo "$base not running, but subsys locked" return 2 fi echo "$base is stopped" return 3 } success() { return 0 } failure() { rc=$? return $rc } bareos-Release-14.2.6/platforms/slackware/local-install.sh000077500000000000000000000055311263011562700235240ustar00rootroot00000000000000#!/bin/sh # local-install.sh # for Bareos on Slackware platform # Phil Stracchino 13 Mar 2004 # # Installs and removes Bareos install section into /etc/rc.d/rc.local # provided /etc/rc.d/rc.local is writeable. Creates a backup copy of # /etc/rc.d/rc.local in /etc/rc.d/rc.local.bak if /etc/rc.d is writeable. # # Usage: local-install.sh install|remove [destdir] # # uncomment for debugging: #set -x if [ -n "$2" ] ; then TARG=$DESTDIR/etc/rc.d/rc.local else TARG=/etc/rc.d/rc.local fi if [ ! -f $TARG ] ; then echo $TARG does not appear to exist. Bailing out. exit -1 fi if [ "$1" = "install" ] ; then echo Installing Bareos autostart into $TARG: COUNT=`grep -c "Bareos section @@@@" $TARG` if [ ! "$COUNT" == "0" ] ; then echo -e "\tBareos autostart section appears to be already installed.\n\tIf you have changed the configuration, make uninstall-autostart\n\tthen make install-autostart again.\n" else if [ -w $TARG ] ; then if [ -w `dirname $TARG` ] ; then cp -p $TARG $TARG.bak echo -e "\tBackup copy of $TARG saved in $TARG.bak." else echo -e "\tWARNING: Unable to create backup copy of $TARG.\n\tAttempting to continue anyway."; fi cat >> $TARG << EOF # @@@@ Start Bareos section @@@@ # The line above is needed to automatically remove bareos. if [ -x /etc/rc.d/rc.bareos-sd ]; then /etc/rc.d/rc.bareos-sd start fi if [ -x /etc/rc.d/rc.bareos-fd ]; then /etc/rc.d/rc.bareos-fd start fi if [ -x /etc/rc.d/rc.bareos-dir ]; then /etc/rc.d/rc.bareos-dir start fi # @@@@ End Bareos section @@@@ EOF echo -e "\tBareos autostart section has been installed in $TARG.\n"; else echo -e "\tERROR! Cannot write to $TARG.\n\tBailing out.\n" exit -1 fi fi elif [ "$1" = "remove" ] ; then echo Removing Bareos autostart from $TARG: COUNT=`grep -c "Bareos section @@@@" $TARG` if [ ! "$COUNT" == "2" ] ; then echo -e "\tCould not find Bareos autostart section in $TARG. Bailing out.\n" exit -1 else if [ -w $TARG ] ; then if [ -w `dirname $TARG` ] ; then cp -p $TARG $TARG.bak echo -e "\tBackup copy of $TARG saved in $TARG.bak." else echo -e "\tWARNING: Unable to create backup copy of $TARG.\n\tAttempting to continue anyway."; fi FIRST=`grep -n "@@@@ Start Bareos section @@@@" $TARG | cut -d: -f1` LAST=`grep -n "@@@@ End Bareos section @@@@" $TARG | cut -d: -f1` FIRST=`expr $FIRST - 1` LAST=`expr $LAST + 1` head -$FIRST $TARG > ./installtmp tail +$LAST $TARG >> ./installtmp cat ./installtmp > $TARG rm ./installtmp echo -e "\tBareos autostart section has been removed from $TARG.\n"; fi fi else echo -e "\tUSAGE: $0 install|remove [destdir]" fi exit 0 bareos-Release-14.2.6/platforms/slackware/rc.bareos-dir.in000066400000000000000000000021361263011562700234070ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 92 99 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/functions.bareos case "$1" in start) [ -x ${BACDIRBIN}/bareos-dir ] && { sleep 2 echo -n "Starting the Director daemon: " OPTIONS='' if [ "${DIR_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${DIR_USER}" fi if [ "${DIR_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${DIR_GROUP}" fi ${BACDIRBIN}/bareos-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/bareos-dir.conf echo Done. } ;; stop) [ -x ${BACDIRBIN}/bareos-dir ] && { echo -n "Stopping the Director daemon: " killproc ${BACDIRBIN}/bareos-dir ${DIR_PORT} echo Done. } ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACDIRBIN}/bareos-dir ] && status ${BACDIRBIN}/bareos-dir ${DIR_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/slackware/rc.bareos-fd.in000066400000000000000000000020771263011562700232260ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 91 99 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/functions.bareos case "$1" in start) [ -x ${BACFDBIN}/bareos-fd ] && { sleep 2 echo -n "Starting the File daemon: " OPTIONS='' if [ "${FD_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${FD_USER}" fi if [ "${FD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${FD_GROUP}" fi ${BACFDBIN}/bareos-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/bareos-fd.conf echo Done. } ;; stop) [ -x ${BACFDBIN}/bareos-fd ] && { echo -n "Stopping the File daemon: " killproc ${BACFDBIN}/bareos-fd ${FD_PORT} echo Done. } ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACFDBIN}/bareos-fd ] && status ${BACFDBIN}/bareos-fd ${FD_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/slackware/rc.bareos-sd.in000066400000000000000000000021101263011562700232270ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 99 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # # Source function library . /etc/rc.d/functions.bareos case "$1" in start) [ -x ${BACSDBIN}/bareos-sd ] && { sleep 2 echo -n "Starting the Storage daemon: " OPTIONS='' if [ "${SD_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${SD_USER}" fi if [ "${SD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi ${BACSDBIN}/bareos-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/bareos-sd.conf echo Done. } ;; stop) [ -x ${BACSDBIN}/bareos-sd ] && { echo -n "Stopping the Storage daemon: " killproc ${BACSDBIN}/bareos-sd ${SD_PORT} echo Done. } ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACSDBIN}/bareos-sd ] && status ${BACSDBIN}/bareos-sd ${SD_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/solaris/000077500000000000000000000000001263011562700201235ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/solaris/Makefile.in000066400000000000000000000025321263011562700221720ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Solaris specific installation. # # 15 November 2001 -- Kern Sibbald # # 03 November 2003 corrections to the paths made by # Kenneth ragnor at virtualsd dot net # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ ALL_INSTALL_TARGETS = install-autostart-fd install-autostart-sd install-autostart-dir nothing: install: install-autostart: @case `uname -r` in \ 5.8|5.9) \ for target in $(ALL_INSTALL_TARGETS); do \ $(MAKE) DESTDIR=$(DESTDIR) $$target; \ done \ ;; \ esac install-autostart-%: @$(RMF) $(DESTDIR)/etc/rc0.d/K20bareos-$* @$(RMF) $(DESTDIR)/etc/rc1.d/S99bareos-$* @$(RMF) $(DESTDIR)/etc/rc2.d/S99bareos-$* @$(MKDIR) $(DESTDIR)/etc/init.d @$(MKDIR) $(DESTDIR)/etc/rc0.d @$(MKDIR) $(DESTDIR)/etc/rc1.d @$(MKDIR) $(DESTDIR)/etc/rc2.d @$(INSTALL_PROGRAM) bareos-$* $(DESTDIR)/etc/init.d/bareos-$* # set symlinks for script at startup and shutdown @ln -f -s /etc/init.d/bareos-$* $(DESTDIR)/etc/rc0.d/K20bareos-$* @ln -f -s /etc/init.d/bareos-$* $(DESTDIR)/etc/rc1.d/S99bareos-$* @ln -f -s /etc/init.d/bareos-$* $(DESTDIR)/etc/rc2.d/S99bareos-$* clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec devclean: clean @$(RMF) bareos-sd bareos-fd bareos-dir @$(RMF) Makefile bareos-*.spec bareos-Release-14.2.6/platforms/solaris/bareos-dir.in000066400000000000000000000025431263011562700225060ustar00rootroot00000000000000#!/bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # DIR_USER=@dir_user@ DIR_GROUP=@dir_group@ DIR_OPTIONS='' case "$1" in start) if [ ! -z "${DIR_USER}" ]; then [ -z "${DIR_OPTIONS}" ] && DIR_OPTIONS="-u ${DIR_USER}" || \ DIR_OPTIONS="${DIR_OPTIONS} -u ${DIR_USER}" fi if [ ! -z "${DIR_GROUP}" ]; then [ -z "${DIR_OPTIONS}" ] && DIR_OPTIONS="-g ${DIR_GROUP}" || \ DIR_OPTIONS="${DIR_OPTIONS} -g ${DIR_GROUP}" fi echo "Starting the Bareos Director: " @sbindir@/bareos-dir $2 ${DIR_OPTIONS} -c @sysconfdir@/bareos-dir.conf ;; stop) echo "Stopping the Director daemon: " if [ -x /usr/bin/zonename ]; then case `/usr/bin/zonename` in global) pkill -z global -x bareos-dir ;; *) pkill -x bareos-dir ;; esac else pkill -x bareos-dir fi ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/solaris/bareos-fd.in000066400000000000000000000025331263011562700223200ustar00rootroot00000000000000#!/bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # FD_USER=@fd_user@ FD_GROUP=@fd_group@ FD_OPTIONS='' case "$1" in start) if [ ! -z "${DIR_USER}" ]; then [ -z "${DIR_OPTIONS}" ] && DIR_OPTIONS="-u ${DIR_USER}" || \ DIR_OPTIONS="${DIR_OPTIONS} -u ${DIR_USER}" fi if [ ! -z "${DIR_GROUP}" ]; then [ -z "${DIR_OPTIONS}" ] && DIR_OPTIONS="-g ${DIR_GROUP}" || \ DIR_OPTIONS="${DIR_OPTIONS} -g ${DIR_GROUP}" fi echo "Starting the Bareos File daemon: " @sbindir@/bareos-fd $2 ${FD_OPTIONS} -c @sysconfdir@/bareos-fd.conf ;; stop) echo "Stopping the Bareos File daemon: " if [ -x /usr/bin/zonename ]; then case `/usr/bin/zonename` in global) pkill -z global -x bareos-fd ;; *) pkill -x bareos-fd ;; esac else pkill -x bareos-fd fi ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/solaris/bareos-sd.in000066400000000000000000000025441263011562700223370ustar00rootroot00000000000000#!/bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # SD_USER=@sd_user@ SD_GROUP=@sd_group@ SD_OPTIONS='' case "$1" in start) if [ ! -z "${DIR_USER}" ]; then [ -z "${DIR_OPTIONS}" ] && DIR_OPTIONS="-u ${DIR_USER}" || \ DIR_OPTIONS="${DIR_OPTIONS} -u ${DIR_USER}" fi if [ ! -z "${DIR_GROUP}" ]; then [ -z "${DIR_OPTIONS}" ] && DIR_OPTIONS="-g ${DIR_GROUP}" || \ DIR_OPTIONS="${DIR_OPTIONS} -g ${DIR_GROUP}" fi echo "Starting the Bareos Storage daemon: " @sbindir@/bareos-sd $2 ${SD_OPTIONS} -c @sysconfdir@/bareos-sd.conf ;; stop) echo "Stopping the Bareos Storage daemon: " if [ -x /usr/bin/zonename ]; then case `/usr/bin/zonename` in global) pkill -z global -x bareos-sd ;; *) pkill -x bareos-sd ;; esac else pkill -x bareos-sd fi ;; restart) $0 stop sleep 5 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/suse/000077500000000000000000000000001263011562700174265ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/suse/Makefile.in000066400000000000000000000047261263011562700215040ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the SUSE specific installation. # # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ FIREWALL_DIR = /etc/sysconfig/SuSEfirewall2.d/services/ nothing: install: install-firewall install_logrotate install_logrotate: @$(MKDIR) $(DESTDIR)/etc/logrotate.d @$(INSTALL_DATA) ../../scripts/logrotate $(DESTDIR)/etc/logrotate.d/bareos-dir install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-firewall: install-firewall-fd install-firewall-sd install-firewall-dir install-firewall-fd: @$(MKDIR) $(DESTDIR)/$(FIREWALL_DIR) @$(INSTALL_DATA) bareos-fd.fw $(DESTDIR)/$(FIREWALL_DIR)/bareos-fd install-firewall-sd: @$(MKDIR) $(DESTDIR)/$(FIREWALL_DIR) @$(INSTALL_DATA) bareos-sd.fw $(DESTDIR)/$(FIREWALL_DIR)/bareos-sd install-firewall-dir: @$(MKDIR) $(DESTDIR)/$(FIREWALL_DIR) @$(INSTALL_DATA) bareos-dir.fw $(DESTDIR)/$(FIREWALL_DIR)/bareos-dir install-autostart-fd: @if test x$(DESTDIR) = x -a -f /etc/init.d/bareos-fd; then \ /sbin/chkconfig --del bareos-fd; \ fi @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-fd $(DESTDIR)/etc/init.d/bareos-fd @$(SYMLINK) ../../etc/init.d/bareos-fd $(DESTDIR)$(sbindir)/rcbareos-fd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-fd; \ fi install-autostart-sd: @if test x$(DESTDIR) = x -a -f /etc/init.d/bareos-sd; then \ /sbin/chkconfig --del bareos-sd; \ fi @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-sd $(DESTDIR)/etc/init.d/bareos-sd @$(SYMLINK) ../../etc/init.d/bareos-sd $(DESTDIR)$(sbindir)/rcbareos-sd # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-sd; \ fi install-autostart-dir: @if test x$(DESTDIR) = x -a -f /etc/init.d/bareos-dir; then \ /sbin/chkconfig --del bareos-dir; \ fi @$(MKDIR) $(DESTDIR)/etc/init.d @$(INSTALL_PROGRAM) bareos-dir $(DESTDIR)/etc/init.d/bareos-dir @$(SYMLINK) ../../etc/init.d/bareos-dir $(DESTDIR)$(sbindir)/rcbareos-dir # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /sbin/chkconfig --add bareos-dir; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) Makefile bareos-*.spec bareos.*.spec bareos.spec @$(RMF) bareos-sd bareos-fd bareos-dir devclean: clean @$(RMF) Makefile bareos-*.spec bareos.*.spec bareos.spec @$(RMF) bareos-sd bareos-fd bareos-dir bareos-Release-14.2.6/platforms/suse/bareos-dir-suse-sqlite.patch000066400000000000000000000011131263011562700247460ustar00rootroot00000000000000--- ../../../bareos-2.1.10/platforms/suse/bareos-dir.in 2007-03-30 17:46:04.000000000 -0400 +++ bareos-dir.in 2007-05-19 12:42:30.000000000 -0400 @@ -13,8 +13,8 @@ # ### BEGIN INIT INFO # Provides: bareos-dir -# Required-Start: $local_fs $network @DEFAULT_DB_TYPE@ -# Required-Stop: $local_fs $network @DEFAULT_DB_TYPE@ +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: bareos director bareos-Release-14.2.6/platforms/suse/bareos-dir.fw000066400000000000000000000010251263011562700220110ustar00rootroot00000000000000## Name: Bareos Director ## Description: Open ports for Bareos director daemon # Once you know which IPs can be used you can restrict more grainfull # the access to this daemon # In that case all clients and console should be able to talk with dir # space separated list of allowed TCP ports TCP="9101" # space separated list of allowed UDP ports UDP="" # space separated list of allowed RPC services RPC="" # space separated list of allowed IP protocols IP="" # space separated list of allowed UDP broadcast ports BROADCAST="" bareos-Release-14.2.6/platforms/suse/bareos-dir.in000066400000000000000000000046171263011562700220150ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Director daemon # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # Copyright (C) 2011 Free Software Foundation Europe e.V. # Modified to work on SuSE 1/31/2004 D. Scott Barninger # Added rc.status functions 3/13/2004 D. Scott Barninger # Added LSB init info 10/14/2004 D. Scott Barninger # Added $remote_fs, add bareos specific daemon user & group Bruno Friedmann # Added config check Philipp Storz ### BEGIN INIT INFO # Provides: bareos-dir # Required-Start: $local_fs $remote_fs $network $time $syslog # Should-Start: postgresql mysql bareos-sd bareos-fd # Required-Stop: $local_fs $remote_fs $network # Should-Stop: postgresql mysql bareos-sd bareos-fd # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: bareos director # Description: Bareos network backup system director daemon ### END INIT INFO # source process status functions # this gives us funtion rc_status -v to tell us if we succeed or fail . /etc/rc.status function checkcfg () { echo "Checking Configuration and Database connection ... " su -s /bin/sh @dir_user@ -c "@sbindir@/bareos-dir -f -t -c @sysconfdir@/bareos-dir.conf" if [ $? -eq 0 ]; then return 0 else return 1 fi } RETVAL=0 case "$1" in start) checkcfg if [ $? -eq 0 ]; then echo -n "Starting the Bareos Director: " /sbin/startproc -u @dir_user@ -g @dir_group@ @sbindir@/bareos-dir $2 -c @sysconfdir@/bareos-dir.conf rc_status -v && touch @subsysdir@/bareos-dir else echo "Configuration check failed, please check log file for errors" rc_failed fi ;; stop) echo -n "Stopping the Director daemon: " /sbin/killproc @sbindir@/bareos-dir rc_status -v && rm -f @subsysdir@/bareos-dir ;; restart) $0 stop sleep 5 $0 start ;; status) echo -n "Checking for Bareos director " /sbin/checkproc @sbindir@/bareos-dir rc_status -v ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac rc_exit bareos-Release-14.2.6/platforms/suse/bareos-fd.fw000066400000000000000000000010231263011562700216220ustar00rootroot00000000000000## Name: Bareos File Daemon ## Description: Open ports for Bareos file daemon # Once you know which IPs can be used you can restrict more grainfull # the access to this daemon # In that case all dir, sd and console should be able to talk with fd # space separated list of allowed TCP ports TCP="9102" # space separated list of allowed UDP ports UDP="" # space separated list of allowed RPC services RPC="" # space separated list of allowed IP protocols IP="" # space separated list of allowed UDP broadcast ports BROADCAST="" bareos-Release-14.2.6/platforms/suse/bareos-fd.in000066400000000000000000000034631263011562700216260ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos File daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # Copyright (C) 2011 Free Software Foundation Europe e.V. # Modified to work on SuSE 1/31/2004 D. Scott Barninger # Added rc.status functions 3/13/2004 D. Scott Barninger # Added LSB init info 10/14/2004 D. Scott Barninger # Added $remote_fs, add bareos specific daemon user & group Bruno Friedmann # ### BEGIN INIT INFO # Provides: bareos-fd # Required-Start: $local_fs $remote_fs $network $time $syslog # Required-Stop: $local_fs $remote_fs $network $time $syslog # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: bareos file daemon # Description: Bareos network backup system file daemon ### END INIT INFO # source process status functions # this gives us funtion rc_status -v to tell us if we succeed or fail . /etc/rc.status case "$1" in start) echo -n "Starting the Bareos File daemon: " /sbin/startproc -u @fd_user@ -g @fd_group@ @sbindir@/bareos-fd $2 -c @sysconfdir@/bareos-fd.conf rc_status -v && touch @subsysdir@/bareos-fd ;; stop) echo -n "Stopping the Bareos File daemon: " /sbin/killproc @sbindir@/bareos-fd rc_status -v && rm -f @subsysdir@/bareos-fd ;; restart) $0 stop sleep 5 $0 start ;; status) echo -n "Checking for Bareos file daemon " /sbin/checkproc @sbindir@/bareos-fd rc_status -v ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac rc_exit bareos-Release-14.2.6/platforms/suse/bareos-sd.fw000066400000000000000000000010311263011562700216360ustar00rootroot00000000000000## Name: Bareos Storage Daemon ## Description: Open ports for Bareos storage daemon # Once you know which IPs can be used you can restrict more grainfull # the access to this daemon # In that case all dir, fd and console should be able to talk with sd # space separated list of allowed TCP ports TCP="9103" # space separated list of allowed UDP ports UDP="" # space separated list of allowed RPC services RPC="" # space separated list of allowed IP protocols IP="" # space separated list of allowed UDP broadcast ports BROADCAST="" bareos-Release-14.2.6/platforms/suse/bareos-sd.in000066400000000000000000000035101263011562700216340ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos Storage daemon. # # chkconfig: 2345 90 9 # description: Backup Archiving REcovery Open Sourced. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # Copyright (C) 2011 Free Software Foundation Europe e.V. # Modified to work on SuSE 1/31/2004 D. Scott Barninger # Added rc.status functions 3/13/2004 D. Scott Barninger # Added LSB init info 10/14/2004 D. Scott Barninger # Added $remote_fs, add bareos specific daemon user & group Bruno Friedmann # ### BEGIN INIT INFO # Provides: bareos-sd # Required-Start: $local_fs $remote_fs $network $time $syslog # Required-Stop: $local_fs $remote_fs $network $time $syslog # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: bareos storage daemon # Description: Bareos network backup system storage daemon ### END INIT INFO # source process status functions # this gives us funtion rc_status -v to tell us if we succeed or fail . /etc/rc.status case "$1" in start) echo -n "Starting the Bareos Storage daemon: " /sbin/startproc -u @sd_user@ -g @sd_group@ @sbindir@/bareos-sd $2 -c @sysconfdir@/bareos-sd.conf rc_status -v && touch @subsysdir@/bareos-sd ;; stop) echo -n "Stopping the Bareos Storage daemon: " /sbin/killproc @sbindir@/bareos-sd rc_status -v && rm -f @subsysdir@/bareos-sd ;; restart) $0 stop sleep 5 $0 start ;; status) echo -n "Checking for Bareos storage daemon " /sbin/checkproc @sbindir@/bareos-sd rc_status -v ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac rc_exit bareos-Release-14.2.6/platforms/suse/bareos.in000066400000000000000000000111421263011562700212300ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos daemons. # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # Submitted by Volker Sauer 21Feb04 # Tweaked a bit by Kern to convert it to a .in file # # description: Backup Archiving REcovery Open Sourced. # ### BEGIN INIT INFO # Provides: bareos # Required-Start: network mysql # Required-Stop: # Default-Start: 3 5 # Default-Stop: # Description: run bareos daemon(s) ### END INIT INFO PSCMD="@PSCMD@" PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ # A function to stop a program. killproc() { RC=0 # Test syntax. if [ $# = 0 ]; then echo "Usage: killproc {program} [signal]" return 1 fi notset=0 # check for third arg to be kill level if [ "$3" != "" ] ; then killlevel=$3 else notset=1 killlevel="-9" fi # Get base program name base=`basename $1` # Find pid. pid=`pidofproc $base $2` # Kill it. if [ "$pid" != "" ] ; then if [ "$notset" = "1" ] ; then if ps -p $pid>/dev/null 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid 2>/dev/null sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 3 if ps -p $pid >/dev/null 2>&1 ; then kill -KILL $pid 2>/dev/null fi fi fi fi ps -p $pid >/dev/null 2>&1 RC=$? [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" # RC=$((! $RC)) # use specified level only else if ps -p $pid >/dev/null 2>&1; then kill $killlevel $pid 2>/dev/null RC=$? [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" fi fi else failure "$base shutdown" fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f ${PIDDIR}/$base.$2.pid fi return $RC } # A function to find the pid of a program. pidofproc() { pid="" # Test syntax. if [ $# = 0 ] ; then echo "Usage: pidofproc {program}" return 1 fi # Get base program name base=`basename $1` # First try PID file if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Next try "pidof" if [ -x /sbin/pidof ] ; then pid=`/sbin/pidof $1` fi if [ "$pid" != "" ] ; then echo $pid return 0 fi # Finally try to extract it from ps ${PSCMD} | grep $1 | awk '{ print $1 }' | tr '\n' ' ' return 0 } status() { # Test syntax. if [ $# = 0 ] ; then echo "Usage: status {program}" return 1 fi # Get base program name base=`basename $1` # First try "pidof" if [ -x /sbin/pidof ] ; then pid=`/sbin/pidof $1` fi if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 else pid=`${PSCMD} | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $2) || (("(" prog ")") == $2) || (("[" prog "]") == $2) || ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 fi fi # Next try the PID files if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo "$base not running, but pid file exists" return 1 fi fi # See if the subsys lock exists if [ -f ${SUBSYSDIR}/$base ] ; then echo "$base not running, but subsys locked" return 2 fi echo "$base is stopped" return 3 } success() { return 0 } failure() { rc=$? return $rc } case "$1" in start) echo "Starting the Storage daemon" @sbindir@/bareos-sd $2 -v -c @sysconfdir@//bareos-sd.conf echo "Starting the File daemon" @sbindir@/bareos-fd $2 -v -c @sysconfdir@//bareos-fd.conf sleep 2 echo "Starting the Director daemon" @sbindir@/bareos-dir $2 -v -c @sysconfdir@//bareos-dir.conf ;; stop) echo "Stopping the File daemon" killproc @sbindir@/bareos-fd 9102 echo "Stopping the Storage daemon" killproc @sbindir@/bareos-sd 9103 echo "Stopping the Director daemon" killproc @sbindir@/bareos-dir 9101 echo ;; restart) $0 stop sleep 5 $0 start ;; status) status @sbindir@/bareos-sd 9103 status @sbindir@/bareos-fd 9102 status @sbindir@/bareos-dir 9101 ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/platforms/systemd/000077500000000000000000000000001263011562700201375ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/systemd/Makefile.in000066400000000000000000000045261263011562700222130ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the systemd specific installation. # # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ # should be /lib/systemd/system and get be get with # systemctl show | grep UnitPath | cut -d " " -f2 SYSTEMD_UNITDIR = @SYSTEMD_UNITDIR@ SYSTEMD_TMPFILES = /etc/tmpfiles.d nothing: install: install-dir install-conf install-dir: @$(MKDIR) $(DESTDIR)/$(SYSTEMD_UNITDIR) @$(MKDIR) $(DESTDIR)/$(SYSTEMD_TMPFILES) install-conf: @$(INSTALL_DATA) bareos.conf $(DESTDIR)/$(SYSTEMD_TMPFILES)/bareos.conf install-autostart: install-autostart-fd install-autostart-sd install-autostart-dir install-autostart-fd: @if test x$(DESTDIR) = x -a -f $(SYSTEMD_UNITDIR)/bareos-fd.service; then \ /bin/systemctl stop bareos-fd.service; \ /bin/systemctl disable bareos-fd.service; \ fi @$(INSTALL_DATA) bareos-fd.service $(DESTDIR)/$(SYSTEMD_UNITDIR)/bareos-fd.service # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /bin/systemctl enable bareos-fd.service; \ /bin/systemctl start bareos-fd.service; \ fi install-autostart-sd: @if test x$(DESTDIR) = x -a -f $(SYSTEMD_UNITDIR)/bareos-sd.service; then \ /bin/systemctl stop bareos-sd.service; \ /bin/systemctl disable bareos-sd.service; \ fi @$(INSTALL_DATA) bareos-sd.service $(DESTDIR)/$(SYSTEMD_UNITDIR)/bareos-sd.service # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /bin/systemctl enable bareos-sd.service; \ /bin/systemctl start bareos-sd.service; \ fi install-autostart-dir: @if test x$(DESTDIR) = x -a -f $(SYSTEMD_UNITDIR)/bareos-dir.service; then \ /bin/systemctl stop bareos-dir.service; \ /bin/systemctl disable bareos-dir.service; \ fi @$(INSTALL_DATA) bareos-dir.service $(DESTDIR)/$(SYSTEMD_UNITDIR)/bareos-dir.service # set symlinks for script at startup and shutdown @if test x$(DESTDIR) = x ; then \ /bin/systemctl enable bareos-dir.service; \ /bin/systemctl start bareos-dir.service; \ fi clean: @$(RMF) 1 2 3 distclean: clean @$(RMF) Makefile bareos-*.spec bareos.*.spec bareos.spec @$(RMF) bareos.conf bareos-sd.service bareos-fd.service bareos-dir.service devclean: clean @$(RMF) Makefile bareos-*.spec bareos.*.spec bareos.spec @$(RMF) bareos.conf bareos-sd.service bareos-fd.service bareos-dir.service bareos-Release-14.2.6/platforms/systemd/bareos-dir.service.in000066400000000000000000000027361263011562700241650ustar00rootroot00000000000000# This file is part of package Bareos Director Daemon # # Copyright (c) 2011 Free Software Foundation Europe e.V. # Bareos Community # Author: Bruno Friedmann # Description: # Used to start the bareos director daemon service (bareos-dir) # will be installed as /lib/systemd/system/bareos-dir.service # enable : systemctl enable bareos-dir.service # start : systemctl start bareos-dir.service # # Bareos Director Daemon service # [Unit] Description=Bareos Director Daemon service Documentation=man:bareos-dir(8) Requires=nss-lookup.target network.target remote-fs.target time-sync.target After=nss-lookup.target network.target remote-fs.target time-sync.target postgresql.service mysql.service # Dependency about the database # We let administrators decide if they need it (if local db instance) # Wants=@DEFAULT_DB_TYPE@.service # Check if working dir exist and is a directory ConditionPathIsDirectory=@working_dir@ # Before= # Conflicts= [Service] Type=forking User=@dir_user@ Group=@dir_group@ WorkingDirectory=@working_dir@ PIDFile=@piddir@/bareos-dir.@dir_port@.pid # EnvironmentFile=-/etc/sysconfig/bareos-dir # StandardOutput=syslog ExecStartPre=@sbindir@/bareos-dir -c @sysconfdir@/bareos-dir.conf -t -f ExecStart=@sbindir@/bareos-dir -c @sysconfdir@/bareos-dir.conf SuccessExitStatus=0 1 15 # This daemon should be able to reload the conf file #ExecReload=/sbin/killproc -p @piddir@/bareos-dir.pid -HUP @sbindir@/bareos-dir #Restart=on-failure [Install] WantedBy=multi-user.target bareos-Release-14.2.6/platforms/systemd/bareos-fd.service.in000066400000000000000000000017451263011562700237770ustar00rootroot00000000000000# This file is part of package Bareos File Daemon # # Copyright (c) 2011 Free Software Foundation Europe e.V. # Bareos Community # Author: Bruno Friedmann # Description: # Used to start the bareos file daemon service (bareos-fd) # will be installed as /lib/systemd/system/bareos-fd.service # enable : systemctl enable bareos-fd.service # start : systemctl start bareos-fd.service # # Bareos File Daemon service # [Unit] Description=Bareos File Daemon service Documentation=man:bareos-fd(8) Requires=nss-lookup.target network.target remote-fs.target time-sync.target After=nss-lookup.target network.target remote-fs.target time-sync.target # Wants= # Before= # Conflicts= [Service] Type=forking User=@fd_user@ Group=@fd_group@ WorkingDirectory=@working_dir@ PIDFile=@piddir@/bareos-fd.@fd_port@.pid StandardOutput=syslog ExecStart=@sbindir@/bareos-fd -c @sysconfdir@/bareos-fd.conf SuccessExitStatus=0 15 Restart=on-failure # IOSchedulingClass=idle [Install] WantedBy=multi-user.target bareos-Release-14.2.6/platforms/systemd/bareos-sd.service.in000066400000000000000000000020121263011562700240000ustar00rootroot00000000000000# This file is part of package Bareos Storage Daemon # # Copyright (c) 2011 Free Software Foundation Europe e.V. # for Bareos Community # Author: Bruno Friedmann # Description: # Used to start the bareos storage daemon service (bareos-sd) # will be installed as /lib/systemd/system/bareos-sd.service # enable : systemctl enable bareos-sd.service # start : systemctl start bareos-sd.service # # Bareos Storage Daemon service # [Unit] Description=Bareos Storage Daemon service Documentation=man:bareos-sd(8) Requires=nss-lookup.target network.target remote-fs.target time-sync.target After=nss-lookup.target network.target remote-fs.target time-sync.target # Wants= # Before= # Conflicts= [Service] Type=forking User=@sd_user@ Group=@sd_group@ WorkingDirectory=@working_dir@ PIDFile=@piddir@/bareos-sd.@sd_port@.pid # EnvironmentFile=-/etc/sysconfig/bareos-sd StandardOutput=syslog ExecStart=@sbindir@/bareos-sd -c @sysconfdir@/bareos-sd.conf SuccessExitStatus=0 15 Restart=on-failure [Install] WantedBy=multi-user.target bareos-Release-14.2.6/platforms/systemd/bareos.conf.in000066400000000000000000000001001263011562700226550ustar00rootroot00000000000000# See tmpfiles.d(5) for details d @piddir@ 2775 bareos bareos - bareos-Release-14.2.6/platforms/ubuntu/000077500000000000000000000000001263011562700177715ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/ubuntu/Makefile.in000066400000000000000000000007251263011562700220420ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Debian/Ubuntu/Kubuntu specific installation. # # 21 March 2008 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ all: (cd ../debian; $(MAKE) $@;) clean: (cd ../debian; $(MAKE) $@;) @$(RMF) 1 2 3 distclean: clean (cd ../debian; $(MAKE) $@;) @$(RMF) Makefile devclean: clean (cd ../debian; $(MAKE) $@;) @$(RMF) Makefile %: (cd ../debian; $(MAKE) $@;) bareos-Release-14.2.6/platforms/univention/000077500000000000000000000000001263011562700206455ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/62univention-bareos.inst000077500000000000000000000026601263011562700253720ustar00rootroot00000000000000#!/bin/sh VERSION=1 . /usr/share/univention-lib/base.sh . /usr/share/univention-lib/ldap.sh . /usr/share/univention-join/joinscripthelper.lib joinscript_init eval "$(univention-config-registry shell)" ucs_addServiceToLocalhost "Bareos Backup" "$@" # keep "cn=custom attributes,cn=univention,$ldap_base" clean univention-directory-manager container/cn create "$@" --ignore_exists \ --position "cn=custom attributes,cn=univention,$ldap_base" \ --set name="bareos" || die # extend to more modules? domaincontroller_master? univention-directory-manager settings/extended_attribute create "$@" \ --ignore_exists \ --position="cn=bareos,cn=custom attributes,cn=univention,$ldap_base" \ --set name=bareos-enabled \ --set module=computers/linux \ --set module=computers/ubuntu \ --set module=computers/windows \ --set module=computers/ipmanagedclient \ --set tabName="Bareos Backup" \ --set tabPosition=2 \ --set ldapMapping="bareosEnableJob" \ --set objectClass="bareosClientHost" \ --set longDescription="schedule backup for this host (the bareos client needs to be installed)" \ --set shortDescription="enable backup job" \ --set translationShortDescription='"de_DE" "Backup-Job aktivieren"' \ --set translationLongDescription='"de_DE" "Backup für diesen Rechner durchführen (Bareos-Client muss installiert sein)"' \ --set CLIName=bareos \ --set mayChange=1 \ --set syntax='OkOrNot' || die joinscript_save_current_version exit 0 bareos-Release-14.2.6/platforms/univention/63univention-bareos.uinst000077500000000000000000000010401263011562700255470ustar00rootroot00000000000000#!/bin/sh VERSION=1 . /usr/share/univention-lib/base.sh . /usr/share/univention-lib/ldap.sh . /usr/share/univention-join/joinscripthelper.lib joinscript_init SERVICE="Bareos Backup" eval "$(univention-config-registry shell)" ucs_removeServiceFromLocalhost "${SERVICE}" "$@" if ucs_isServiceUnused "${SERVICE}" "$@"; then # simply remove them all univention-directory-manager container/cn remove "$@" --dn "cn=bareos,cn=custom attributes,cn=univention,$ldap_base" fi joinscript_remove_script_from_status_file univention-bareos exit 0 bareos-Release-14.2.6/platforms/univention/AppCenter/000077500000000000000000000000001263011562700225265ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/AppCenter/LICENSE_AGREEMENT000066400000000000000000000015061263011562700251240ustar00rootroot00000000000000 Bareos - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/ bareos-Release-14.2.6/platforms/univention/AppCenter/univention-bareos.ini000066400000000000000000000046521263011562700267050ustar00rootroot00000000000000[Application] ID=bareos Name=Bareos Backup Version=12.4.4ucs3-1 EmailRequired=True NotifyVendor=True Description=scalable open source network backup solution LongDescription=Bareos (Backup Archiving Recovery Open Sourced) is a reliable, network-based open source software for backup, archiving and recovery of data for all well-established operating systems. In the year 2010 emerged from the Bacula Project, Bareos was and is actively developed as a fork and enriched with lots of new features. Thus Bareos today offers among other features LTO hardware encryption, bandwitdth limitation and new practical console commands. The source code of Bareos is available on Github under the AGPL v3 license. Additionally Bareos offers binary package repositories for the most important Linux distributions as well as for Windows. ATTENTION: After installation, you need to review at least the UCR variables bareos/filestorage, bareos/backup_myself and bareos/max_*_volumes for proper operation. Screenshot= Categories=Administration Vendor=Bareos GmbH und Co. KG Website=http://www.bareos.org/en/HOWTO/articles/bareos-univention-documentation.html WebsiteVendor=http://www.bareos.com Contact=info@bareos.com NotificationEmail=info@bareos.com LicenseFile=LICENSE_AGREEMENT ConflictedApps= ConflictedSystemPackages=univention-bacula,bacula-director-common,bacula-fd,bacula-sd DefaultPackages=univention-bareos DefaultPackagesMaster=univention-bareos-schema [de] Description=Leistungsfähige Open-Source-Backup-Lösung LongDescription=Bareos (Backup Archiving Recovery Open Sourced) ist eine zuverlässige, netzwerkübergreifende Open Source Software zur Sicherung, Archivierung und Wiederherstellung von Daten aller gängigen Betriebssysteme. Im Jahr 2010 hervorgegangen aus dem Projekt Bacula wurde und wird Bareos als Fork aktiv weiterentwickelt und mit vielen neuen Features angereichert. So bietet Bareos heute unter anderem eine LTO Hardware-Verschlüsselung, eine Bandbreitenbegrenzung und neue praktische Konsolen-Kommandos. Der Quellcode von Bareos ist auf Github verfügbar und steht unter der Lizenz AGPL v3. Zudem stellt Bareos fertige Pakete über Repositories für die wichtigsten Linux Distributionen sowie für Windows bereit. ACHTUNG: Nach der Installation sollten die UCR-Variablen bareos/filestorage, bareos/backup_myself und bareos/max_*_volumes geprüft werden, um einen korrekten Betrieb zu gewährleisten. bareos-Release-14.2.6/platforms/univention/Makefile.in000066400000000000000000000046561263011562700227250ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the Univention specific installation. # Univention is based on Debian, # therefore it also calls the Debian Makefile # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ all: (cd ../debian; $(MAKE) $@;) install: (cd ../debian; $(MAKE) $@;) @echo "generating Univention Config Registry (UCR) files ..." (cd ../..; ln -s platforms/univention/conffiles conffiles; univention-install-config-registry) @$(MKDIR) $(DESTDIR)/etc/bareos/autogenerated/fd-configs/ @$(INSTALL_CONFIG) fd-windows.template $(DESTDIR)/etc/bareos/autogenerated/fd-configs/windows.template @$(INSTALL_CONFIG) fd-generic.template $(DESTDIR)/etc/bareos/autogenerated/fd-configs/generic.template @$(MKDIR) $(DESTDIR)/etc/bareos/autogenerated/fd-secrets/ @$(MKDIR) $(DESTDIR)/etc/bareos/autogenerated/clients/ @$(INSTALL_CONFIG) job-windows.template $(DESTDIR)/etc/bareos/autogenerated/clients/windows.template @$(INSTALL_CONFIG) job-generic.template $(DESTDIR)/etc/bareos/autogenerated/clients/generic.template @$(MKDIR) $(DESTDIR)/etc/cron.d/ @$(INSTALL_CONFIG) univention-bareos.cron $(DESTDIR)/etc/cron.d/univention-bareos @$(MKDIR) $(DESTDIR)/usr/lib/univention-directory-listener/system @$(INSTALL_PROGRAM) univention-bareos.py $(DESTDIR)/usr/lib/univention-directory-listener/system @$(MKDIR) $(DESTDIR)/usr/lib/univention-install/ @$(INSTALL_PROGRAM) 62univention-bareos.inst $(DESTDIR)/usr/lib/univention-install/ @$(MKDIR) $(DESTDIR)/usr/lib/univention-uninstall/ @$(INSTALL_PROGRAM) 63univention-bareos.uinst $(DESTDIR)/usr/lib/univention-uninstall/ # dbconfig-common @$(MKDIR) $(DESTDIR)/usr/share/dbconfig-common/data/univention-bareos/install/ @$(INSTALL_CONFIG) postgres_create.sql $(DESTDIR)/usr/share/dbconfig-common/data/univention-bareos/install/pgsql @$(MKDIR) $(DESTDIR)/usr/share/univention-bareos/ @$(INSTALL_PROGRAM) restart_director $(DESTDIR)/usr/share/univention-bareos/ @$(MKDIR) $(DESTDIR)/usr/share/univention-bareos-schema/ @$(INSTALL_CONFIG) univention-bareos.schema $(DESTDIR)/usr/share/univention-bareos-schema/univention-bareos.schema clean: (cd ../debian; $(MAKE) $@;) @$(RMF) 1 2 3 distclean: clean (cd ../debian; $(MAKE) $@;) @$(RMF) Makefile devclean: clean (cd ../debian; $(MAKE) $@;) @$(RMF) Makefile %: (cd ../debian; $(MAKE) $@;) bareos-Release-14.2.6/platforms/univention/conffiles/000077500000000000000000000000001263011562700226155ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/000077500000000000000000000000001263011562700233705ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/bareos/000077500000000000000000000000001263011562700246435ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/bareos/bareos-dir.conf000066400000000000000000000246101263011562700275440ustar00rootroot00000000000000@%@UCRWARNING=# @%@ # # Default Bareos Director Configuration file for disk-only backup # (C) Bareos GmbH & Co.KG # # You have to configure the following for your environment: # # (#1) Email Address for bareos disaster recovery. # Specify a mailaddress outside of your backupserver. # There will be one mail per day. # # (#2) Email Address for bareos reports. (Mail Command) # This mail address will recieve a report about each backup job. # It will be sent after the backupjob is complete. # Has to be configured twice ("Standard" and "Daemon" Message Ressources) # # (#3) Email Address for bareos operator. (Operator Command) # This mail address will recieve a mail immediately when the # bareos system needs an operator intervention. # May be the same address as in (#2) # # # This disk-only setup stores all data into /var/lib/bareos/storage # # In the following description of the backup scheme, a reference number # shows where this property is set in the configuration file. # # The preconfigured backup scheme is as follows: # # Full Backups are done on first Saturday at 01:00 (#4) # Full Backups are written into the "Full" Pool (#5) # Full Backups are kept for 365 Days (#6) # # Differential Backups are done on 2nd to 5th Saturday at 01:00 (#7) # Differential Backups are written into the "Differential" Pool (#8) # Differential Backups are kept for 90 Days (#9) # # Incremental Backups are done monday to friday at 01:00 (#10) # Incremental Backups are written into the "Incremental" Pool (#11) # Incremental Backups are kept for 30 Days (#12) # # # # For Bareos release 13.2.0 (09 April 2013) -- debian 6.0.6 # # Director { # define myself Name = @%@hostname@%@.@%@domainname@%@-dir QueryFile = "/usr/lib/bareos/scripts/query.sql" Maximum Concurrent Jobs = 10 @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'DIRECTOR_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ Messages = Daemon # remove comment in next line to load plugins from specified directory # Plugin Directory = /usr/lib/bareos/plugins } JobDefs { Name = "DefaultJob" Type = Backup Level = Incremental Client = @%@hostname@%@.@%@domainname@%@-fd FileSet = "Linux All" Schedule = "WeeklyCycle" Storage = File Messages = Standard Pool = Incremental Priority = 10 Write Bootstrap = "/var/lib/bareos/%c.bsr" Full Backup Pool = Full # write Full Backups into "Full" Pool (#5) Differential Backup Pool = Differential # write Diff Backups into "Differential" Pool (#8) Incremental Backup Pool = Incremental # write Incr Backups into "Incremental" Pool (#11) } # # Define the main nightly save backup job # By default, this job will back up to disk in /var/lib/bareos/storage Job { Name = "Backup-@%@hostname@%@.@%@domainname@%@" JobDefs = "DefaultJob" FileSet = "UCS PDC" Enabled = "@%@bareos/backup_myself@%@" } # # Backup the catalog database (after the nightly save) # Job { Name = "BackupCatalog" JobDefs = "DefaultJob" Level = Full FileSet="Catalog" Schedule = "WeeklyCycleAfterBackup" # This creates an ASCII copy of the catalog # Arguments to make_catalog_backup.pl are: # make_catalog_backup.pl RunBeforeJob = "/usr/lib/bareos/scripts/make_catalog_backup.pl MyCatalog" # This deletes the copy of the catalog RunAfterJob = "/usr/lib/bareos/scripts/delete_catalog_backup" # This sends the bootstrap via mail for disaster recovery. # Should be sent to another system, please change recipient accordingly Write Bootstrap = "|/usr/sbin/bsmtp -h localhost -f \"\(Bareos\) \" -s \"Bootstrap for Job %j\" root@localhost" # (#1) Priority = 11 # run after main backup } # # Standard Restore template, to be changed by Console program # Only one such job is needed for all Jobs/Clients/Storage ... # Job { Name = "RestoreFiles" Type = Restore Client=@%@hostname@%@.@%@domainname@%@-fd FileSet = "Linux All" Storage = File Pool = Incremental Messages = Standard Where = /tmp/bareos-restores } FileSet { Name = "Windows All Drives" Enable VSS = yes Include { Options { Signature = MD5 Drive Type = fixed IgnoreCase = yes WildFile = "[A-Z]:/pagefile.sys" WildDir = "[A-Z]:/RECYCLER" WildDir = "[A-Z]:/$RECYCLE.BIN" WildDir = "[A-Z]:/System Volume Information" Exclude = yes } File = / } } FileSet { Name = "Linux All" Include { Options { Signature = MD5 # calculate md5 checksum per file One FS = No # change into other filessytems FS Type = ext2 # filesystems of given types will be backed up FS Type = ext3 # others will be ignored FS Type = ext4 FS Type = xfs FS Type = reiserfs FS Type = jfs } File = / } # Things that usually have to be excluded # You have to exclude /var/lib/bareos/storage # on your bareos server Exclude { File = /var/lib/bareos File = /var/lib/bareos/storage File = /proc File = /tmp File = /.journal File = /.fsck } } FileSet { Name = "UCS PDC" Include { Options { Signature = MD5 # calculate md5 checksum per file One FS = No # change into other filessytems FS Type = ext2 # filesystems of given types will be backed up FS Type = ext3 # others will be ignored FS Type = ext4 FS Type = xfs } File = / } # Things that usually have to be excluded # You have to exclude /var/lib/bareos/storage # on your bareos server Exclude { File = /var/lib/bareos File = /var/lib/bareos/storage File = /proc File = /tmp File = /.journal File = /.fsck } } Schedule { Name = "WeeklyCycle" Run = Full 1st sat at 01:00 # (#4) Run = Differential 2nd-5th sat at 01:00 # (#7) Run = Incremental mon-fri at 01:00 # (#10) } # This schedule does the catalog. It starts after the WeeklyCycle Schedule { Name = "WeeklyCycleAfterBackup" Run = Full mon-fri at 01:10 } # This is the backup of the catalog FileSet { Name = "Catalog" Include { Options { signature = MD5 } File = "/var/lib/bareos/bareos.sql" # database dump File = "/etc/bareos" # configuration } } # Client (File Services) to backup Client { Name = @%@hostname@%@.@%@domainname@%@-fd Address = @%@hostname@%@.@%@domainname@%@ @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'CLIENT_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ File Retention = 30 days # 30 days Job Retention = 6 months # six months AutoPrune = no # Prune expired Jobs/Files } # # Definition of file storage device # Storage { Name = File @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'STORAGE_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ # Do not use "localhost" here Address = @%@hostname@%@.@%@domainname@%@ # N.B. Use a fully qualified name here Device = FileStorage Media Type = File } # # Generic catalog service # Catalog { Name = MyCatalog # Uncomment the following lines if you want the dbi driver # dbdriver = "dbi:postgresql"; dbaddress = 127.0.0.1; dbport = dbdriver = "postgresql" dbname = "@%@bareos/pgsql/database@%@" dbuser = "@%@bareos/pgsql/user@%@" dbpassword = "" } # # Reasonable message delivery -- send most everything to email address and to the console # Messages { Name = Standard mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bareos\) \<%r\>\" -s \"Bareos: %t %e of %c %l\" %r" operatorcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bareos\) \<%r\>\" -s \"Bareos: Intervention needed for %j\" %r" mail = root@localhost = all, !skipped # (#2) operator = root@localhost = mount # (#3) console = all, !skipped, !saved append = "/var/log/bareos/bareos.log" = all, !skipped catalog = all } # # Message delivery for daemon messages (no job). # Messages { Name = Daemon mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bareos\) \<%r\>\" -s \"Bareos daemon message\" %r" mail = root@localhost = all, !skipped # (#2) console = all, !skipped, !saved append = "/var/log/bareos/bareos.log" = all, !skipped } # # Full Pool definition # Pool { Name = Full Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 365 days # How long should the Full Backups be kept? (#6) Maximum Volume Bytes = 10G # Limit Volume size to something reasonable Maximum Volumes = @%@bareos/max_full_volumes@%@ # Limit number of Volumes in Pool Label Format = "Full-" # Volumes will be labeled "Full-" } # # Differential Pool definition # Pool { Name = Differential Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 90 days # How long should the Differential Backups be kept? (#9) Maximum Volume Bytes = 10G # Limit Volume size to something reasonable Maximum Volumes = @%@bareos/max_diff_volumes@%@ # Limit number of Volumes in Pool Label Format = "Differential-" # Volumes will be labeled "Differential-" } # # Incremental Pool definition # Pool { Name = Incremental Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 30 days # How long should the Incremental Backups be kept? (#12) Maximum Volume Bytes = 10G # Limit Volume size to something reasonable Maximum Volumes = @%@bareos/max_incr_volumes@%@ # Limit number of Volumes in Pool Label Format = "Incremental-" # Volumes will be labeled "Incremental-" } # # Scratch pool definition # Pool { Name = Scratch Pool Type = Backup } # # Restricted console used by tray-monitor to get the status of the director # Console { Name = @%@hostname@%@.@%@domainname@%@-mon Password = "monitor" CommandACL = status, .status JobACL = *all* } @/etc/bareos/autogenerated/clients.include bareos-Release-14.2.6/platforms/univention/conffiles/etc/bareos/bareos-fd.conf000066400000000000000000000024541263011562700273610ustar00rootroot00000000000000@%@UCRWARNING=# @%@ # # Default Bareos File Daemon Configuration file # # For Bareos release 12.4.2 (03 March 2013) -- debian 6.0.6 # # There is not much to change here except perhaps the # File daemon Name to # # # List Directors who are permitted to contact this File daemon # Director { Name = @%@hostname@%@.@%@domainname@%@-dir @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'CLIENT_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ } # # Restricted Director, used by tray-monitor to get the # status of the file daemon # Director { Name = @%@hostname@%@.@%@domainname@%@-mon @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'CLIENT_MONITOR_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ Monitor = yes } # # "Global" File daemon configuration specifications # FileDaemon { # this is me Name = @%@hostname@%@.@%@domainname@%@-fd Maximum Concurrent Jobs = 20 # remove comment in next line to load plugins from specified directory # Plugin Directory = /usr/lib/bareos/plugins } # Send all messages except skipped files back to Director Messages { Name = Standard director = @%@hostname@%@.@%@domainname@%@-dir = all, !skipped, !restored } bareos-Release-14.2.6/platforms/univention/conffiles/etc/bareos/bareos-sd.conf000066400000000000000000000035671263011562700274040ustar00rootroot00000000000000@%@UCRWARNING=# @%@ # # Default Bareos Storage Daemon Configuration file # # For Bareos release 13.2.0 (09 April 2013) -- debian 6.0.6 # # You may need to change the name of your tape drive # on the "Archive Device" directive in the Device # resource. If you change the Name and/or the # "Media Type" in the Device resource, please ensure # that dird.conf has corresponding changes. # Storage { # definition of myself Name = @%@hostname@%@.@%@domainname@%@-sd Maximum Concurrent Jobs = 20 # remove comment in next line to load plugins from specified directory # Plugin Directory = /usr/lib/bareos/plugins } # # List Directors who are permitted to contact Storage daemon # Director { Name = @%@hostname@%@.@%@domainname@%@-dir @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'STORAGE_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ } # # Restricted Director, used by tray-monitor to get the # status of the storage daemon # Director { Name = @%@hostname@%@.@%@domainname@%@-mon @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'STORAGE_MONITOR_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ Monitor = yes } # # Devices supported by this Storage daemon # To connect, the Director's bareos-dir.conf must have the same Name and MediaType. # Device { Name = FileStorage Media Type = File Archive Device = @%@bareos/filestorage@%@ LabelMedia = yes; # lets Bareos label unlabeled media Random Access = Yes; AutomaticMount = yes; # when device opened, read it RemovableMedia = no; AlwaysOpen = no; } # # Send all messages to the Director, # mount messages also are sent to the email address # Messages { Name = Standard director = @%@hostname@%@.@%@domainname@%@-dir = all } bareos-Release-14.2.6/platforms/univention/conffiles/etc/bareos/bconsole.conf000066400000000000000000000005601263011562700273170ustar00rootroot00000000000000@%@UCRWARNING=# @%@ # # Bareos User Agent (or Console) Configuration File # Director { Name = @%@hostname@%@.@%@domainname@%@-dir DIRport = 9101 address = @%@hostname@%@.@%@domainname@%@ @!@ with open('/etc/bareos/.rndpwd','r') as f: for l in f.readlines(): if 'DIRECTOR_PASSWORD' in l: print " Password = \"%s\"" % (l.split('=')[1].strip()) @!@ } bareos-Release-14.2.6/platforms/univention/conffiles/etc/postgresql/000077500000000000000000000000001263011562700255735ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/postgresql/8.4/000077500000000000000000000000001263011562700261045ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/postgresql/8.4/main/000077500000000000000000000000001263011562700270305ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/postgresql/8.4/main/pg_hba.conf.d/000077500000000000000000000000001263011562700314165ustar00rootroot0000000000000025-univention-bareos000066400000000000000000000001001263011562700351440ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/univention/conffiles/etc/postgresql/8.4/main/pg_hba.conf.dlocal @%@bareos/pgsql/database@%@ @%@bareos/pgsql/user@%@ ident bareos-Release-14.2.6/platforms/univention/fd-generic.template000066400000000000000000000005261263011562700244100ustar00rootroot00000000000000# # This file needs to be copied to the backup client # as /etc/bareos/bareos-fd.conf # Director { Name = ${server_name}-dir Password = "$password" } FileDaemon { Name = ${client_name}-fd Maximum Concurrent Jobs = 20 } Messages { Name = Standard director = ${server_name}-dir = all, !skipped, !restored } bareos-Release-14.2.6/platforms/univention/fd-windows.template000066400000000000000000000011071263011562700244620ustar00rootroot00000000000000# # This file needs to be copied onto the client # (usually into the directory C:\ProgramData\Bareos) # with bareos-fd.conf as the file name. # # You can also let the windows installer generate this file # by calling setup.exe with the following parameters: # # # setup.exe /DIRECTORNAME=${server_name} /CLIENTNAME=${client_name} /CLIENTPASSWORD="${password}" # Director { Name = ${server_name}-dir Password = "$password" } FileDaemon { Name = ${client_name}-fd } Messages { Name = Standard director = ${server_name}-dir = all, !skipped, !restored } bareos-Release-14.2.6/platforms/univention/job-generic.template000066400000000000000000000006561263011562700245750ustar00rootroot00000000000000Client { Name = "${client_name}-fd" Address = "$client_name" Password = "${password}" File Retention = 30 days # 30 days Job Retention = 6 months # six months AutoPrune = no # Prune expired Jobs/Files } Job { Name = "Backup-${client_name}" Client = "${client_name}-fd" JobDefs = "DefaultJob" FileSet = "Linux All" Schedule = "WeeklyCycle" Enabled = "$enable" } bareos-Release-14.2.6/platforms/univention/job-windows.template000066400000000000000000000006671263011562700246550ustar00rootroot00000000000000Client { Name = "${client_name}-fd" Address = "$client_name" Password = "${password}" File Retention = 30 days # 30 days Job Retention = 6 months # six months AutoPrune = no # Prune expired Jobs/Files } Job { Name = "Backup-${client_name}" Client = "${client_name}-fd" JobDefs = "DefaultJob" FileSet = "Windows All Drives" Schedule = "WeeklyCycle" Enabled = "$enable" } bareos-Release-14.2.6/platforms/univention/postgres_create.sql000077500000000000000000000366711263011562700245770ustar00rootroot00000000000000CREATE TABLE Filename ( FilenameId SERIAL NOT NULL, Name TEXT NOT NULL, PRIMARY KEY (FilenameId) ); ALTER TABLE Filename ALTER COLUMN Name SET STATISTICS 1000; CREATE UNIQUE INDEX filename_name_idx ON Filename (Name); CREATE TABLE Path ( PathId SERIAL NOT NULL, Path TEXT NOT NULL, PRIMARY KEY (PathId) ); ALTER TABLE Path ALTER COLUMN Path SET STATISTICS 1000; CREATE UNIQUE INDEX path_name_idx ON Path (Path); -- We strongly recommend to avoid the temptation to add new indexes. -- In general, these will cause very significant performance -- problems in other areas. A better approch is to carefully check -- that all your memory configuation parameters are -- suitable for the size of your installation. If you backup -- millions of files, you need to adapt the database memory -- configuration parameters concerning sorting, joining and global -- memory. By DEFAULT, sort and join parameters are very small -- (sometimes 8Kb), and having sufficient memory specified by those -- parameters is extremely important to run fast. -- In File table -- FileIndex can be 0 for FT_DELETED files -- FileNameId can link to Filename.Name='' for directories CREATE TABLE File ( FileId BIGSERIAL NOT NULL, FileIndex INTEGER NOT NULL DEFAULT 0, JobId INTEGER NOT NULL, PathId INTEGER NOT NULL, FilenameId INTEGER NOT NULL, DeltaSeq SMALLINT NOT NULL DEFAULT 0, MarkId INTEGER NOT NULL DEFAULT 0, LStat TEXT NOT NULL, Md5 TEXT NOT NULL, PRIMARY KEY (FileId) ); CREATE INDEX file_jpfid_idx ON File (JobId, PathId, FilenameId); CREATE INDEX file_jobid_idx ON File (JobId); -- -- Add this if you have a good number of job -- that run at the same time -- ALTER SEQUENCE file_fileid_seq CACHE 1000; -- -- Possibly add one or more of the following indexes -- if your Verifies are too slow, but they can slow down -- backups. -- -- CREATE INDEX file_pathid_idx ON file(pathid); -- CREATE INDEX file_filenameid_idx ON file(filenameid); CREATE TABLE RestoreObject ( RestoreObjectId SERIAL NOT NULL, ObjectName TEXT NOT NULL, RestoreObject BYTEA NOT NULL, PluginName TEXT NOT NULL, ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER DEFAULT 0, JobId INTEGER, ObjectCompression INTEGER DEFAULT 0, PRIMARY KEY(RestoreObjectId) ); CREATE INDEX restore_jobid_idx ON RestoreObject(JobId); CREATE TABLE Job ( JobId SERIAL NOT NULL, Job TEXT NOT NULL, Name TEXT NOT NULL, Type CHAR(1) NOT NULL, Level CHAR(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus CHAR(1) NOT NULL, SchedTime TIMESTAMP WITHOUT TIME ZONE, StartTime TIMESTAMP WITHOUT TIME ZONE, EndTime TIMESTAMP WITHOUT TIME ZONE, RealEndTime TIMESTAMP WITHOUT TIME ZONE, JobTDate BIGINT DEFAULT 0, VolSessionId INTEGER DEFAULT 0, volSessionTime INTEGER DEFAULT 0, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0, ReadBytes BIGINT DEFAULT 0, JobErrors INTEGER DEFAULT 0, JobMissingFiles INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, FilesetId INTEGER DEFAULT 0, PriorJobid INTEGER DEFAULT 0, PurgedFiles SMALLINT DEFAULT 0, HasBase SMALLINT DEFAULT 0, HasCache SMALLINT DEFAULT 0, Reviewed SMALLINT DEFAULT 0, Comment TEXT, PRIMARY KEY (JobId) ); CREATE INDEX job_name_idx ON job (Name); -- Create a table like Job for long term statistics CREATE TABLE JobHisto (LIKE Job); CREATE INDEX jobhisto_idx ON JobHisto (StartTime); CREATE TABLE Location ( LocationId SERIAL NOT NULL, Location TEXT NOT NULL, Cost INTEGER DEFAULT 0, Enabled SMALLINT, PRIMARY KEY (LocationId) ); CREATE TABLE Fileset ( FileSetId SERIAL NOT NULL, Fileset TEXT NOT NULL, Md5 TEXT NOT NULL, CreateTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (filesetid) ); CREATE INDEX fileset_name_idx ON fileset (fileset); CREATE TABLE JobMedia ( JobMediaId SERIAL NOT NULL, JobId INTEGER NOT NULL, MediaId INTEGER NOT NULL, FirstIndex INTEGER DEFAULT 0, LastIndex INTEGER DEFAULT 0, StartFile INTEGER DEFAULT 0, EndFile INTEGER DEFAULT 0, StartBlock BIGINT DEFAULT 0, EndBlock BIGINT DEFAULT 0, VolIndex INTEGER DEFAULT 0, PRIMARY KEY (jobmediaid) ); CREATE INDEX job_media_job_id_media_id_idx ON jobmedia (JobId, MediaId); CREATE TABLE Media ( MediaId SERIAL NOT NULL, VolumeName TEXT NOT NULL, Slot INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, MediaType TEXT NOT NULL, MediaTypeId INTEGER DEFAULT 0, LabelType INTEGER DEFAULT 0, FirstWritten TIMESTAMP WITHOUT TIME ZONE, LastWritten TIMESTAMP WITHOUT TIME ZONE, LabelDate TIMESTAMP WITHOUT TIME ZONE, VolJobs INTEGER DEFAULT 0, VolFiles INTEGER DEFAULT 0, VolBlocks INTEGER DEFAULT 0, VolMounts INTEGER DEFAULT 0, VolBytes BIGINT DEFAULT 0, VolErrors INTEGER DEFAULT 0, VolWrites INTEGER DEFAULT 0, VolCapacityBytes BIGINT DEFAULT 0, VolStatus TEXT NOT NULL CHECK (VolStatus IN ('Full', 'Archive', 'Append', 'Recycle', 'Purged', 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning', 'Scratch')), Enabled SMALLINT DEFAULT 1, Recycle SMALLINT DEFAULT 0, ActionOnPurge SMALLINT DEFAULT 0, VolRetention BIGINT DEFAULT 0, VolUseDuration BIGINT DEFAULT 0, MaxVolJobs INTEGER DEFAULT 0, MaxVolFiles INTEGER DEFAULT 0, MaxVolBytes BIGINT DEFAULT 0, InChanger SMALLINT DEFAULT 0, StorageId INTEGER DEFAULT 0, DeviceId INTEGER DEFAULT 0, MediaAddressing SMALLINT DEFAULT 0, VolReadTime BIGINT DEFAULT 0, VolWriteTime BIGINT DEFAULT 0, EndFile INTEGER DEFAULT 0, EndBlock BIGINT DEFAULT 0, LocationId INTEGER DEFAULT 0, RecycleCount INTEGER DEFAULT 0, InitialWrite TIMESTAMP WITHOUT TIME ZONE, ScratchPoolId INTEGER DEFAULT 0, RecyclePoolId INTEGER DEFAULT 0, EncryptionKey TEXT, Comment TEXT, PRIMARY KEY (MediaId) ); CREATE UNIQUE INDEX media_volumename_id ON Media (VolumeName); CREATE INDEX media_poolid_idx ON Media (PoolId); CREATE INDEX media_storageid_idx ON Media (StorageId); CREATE TABLE MediaType ( MediaTypeId SERIAL, MediaType TEXT NOT NULL, ReadOnly INTEGER DEFAULT 0, PRIMARY KEY(MediaTypeId) ); CREATE TABLE Storage ( StorageId SERIAL, Name TEXT NOT NULL, AutoChanger INTEGER DEFAULT 0, PRIMARY KEY(StorageId) ); CREATE TABLE Device ( DeviceId SERIAL, Name TEXT NOT NULL, MediaTypeId INTEGER NOT NULL, StorageId INTEGER NOT NULL, DevMounts INTEGER NOT NULL DEFAULT 0, DevReadBytes BIGINT NOT NULL DEFAULT 0, DevWriteBytes BIGINT NOT NULL DEFAULT 0, DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, DevReadTime BIGINT NOT NULL DEFAULT 0, DevWriteTime BIGINT NOT NULL DEFAULT 0, DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, DevWriteTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, CleaningDate TIMESTAMP WITHOUT TIME ZONE, CleaningPeriod BIGINT NOT NULL DEFAULT 0, PRIMARY KEY(DeviceId) ); CREATE TABLE Pool ( PoolId SERIAL NOT NULL, Name TEXT NOT NULL, NumVols INTEGER DEFAULT 0, MaxVols INTEGER DEFAULT 0, UseOnce SMALLINT DEFAULT 0, UseCatalog SMALLINT DEFAULT 0, AcceptAnyVolume SMALLINT DEFAULT 0, VolRetention BIGINT DEFAULT 0, VolUseDuration BIGINT DEFAULT 0, MaxVolJobs INTEGER DEFAULT 0, MaxVolFiles INTEGER DEFAULT 0, MaxVolBytes BIGINT DEFAULT 0, AutoPrune SMALLINT DEFAULT 0, Recycle SMALLINT DEFAULT 0, ActionOnPurge SMALLINT DEFAULT 0, PoolType TEXT CHECK (PoolType IN ('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch')), LabelType INTEGER DEFAULT 0, LabelFormat TEXT NOT NULL, Enabled SMALLINT DEFAULT 1, ScratchPoolId INTEGER DEFAULT 0, RecyclePoolId INTEGER DEFAULT 0, NextPoolId INTEGER DEFAULT 0, MigrationHighBytes BIGINT DEFAULT 0, MigrationLowBytes BIGINT DEFAULT 0, MigrationTime BIGINT DEFAULT 0, PRIMARY KEY (PoolId) ); CREATE INDEX pool_name_idx ON Pool (Name); CREATE TABLE Client ( ClientId SERIAL NOT NULL, Name TEXT NOT NULL, UName TEXT NOT NULL, AutoPrune SMALLINT DEFAULT 0, FileRetention BIGINT DEFAULT 0, JobRetention BIGINT DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE UNIQUE INDEX client_name_idx ON Client (Name); CREATE TABLE Log ( LogId SERIAL NOT NULL, JobId INTEGER NOT NULL, Time TIMESTAMP WITHOUT TIME ZONE, LogText TEXT NOT NULL, PRIMARY KEY (LogId) ); CREATE INDEX log_name_idx ON Log (JobId); CREATE TABLE LocationLog ( LocLogId SERIAL NOT NULL, Date TIMESTAMP WITHOUT TIME ZONE, Comment TEXT NOT NULL, MediaId INTEGER DEFAULT 0, LocationId INTEGER DEFAULT 0, NewVolStatus TEXT NOT NULL CHECK (NewVolStatus IN ('Full', 'Archive', 'Append', 'Recycle', 'Purged', 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning', 'Scratch')), newenabled SMALLINT, PRIMARY KEY(LocLogId) ); CREATE TABLE counters ( Counter TEXT NOT NULL, MinValue INTEGER DEFAULT 0, MaxValue INTEGER DEFAULT 0, CurrentValue INTEGER DEFAULT 0, wrapcounter TEXT NOT NULL, PRIMARY KEY (Counter) ); CREATE TABLE basefiles ( BaseId SERIAL NOT NULL, JobId INTEGER NOT NULL, FileId BIGINT NOT NULL, FileIndex INTEGER, BaseJobId INTEGER, PRIMARY KEY (BaseId) ); CREATE INDEX basefiles_jobid_idx ON BaseFiles (JobId); CREATE TABLE unsavedfiles ( UnsavedId INTEGER NOT NULL, JobId INTEGER NOT NULL, PathId INTEGER NOT NULL, FilenameId INTEGER NOT NULL, PRIMARY KEY (UnsavedId) ); CREATE TABLE CDImages ( MediaId INTEGER NOT NULL, LastBurn TIMESTAMP WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (MediaId) ); CREATE TABLE PathHierarchy ( PathId INTEGER NOT NULL, PPathId INTEGER NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId INTEGER NOT NULL, JobId INTEGER NOT NULL, Size BIGINT DEFAULT 0, Files INTEGER DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE TABLE version ( VersionId INTEGER NOT NULL ); CREATE TABLE Status ( JobStatus CHAR(1) NOT NULL, JobStatusLong TEXT, Severity INTEGER, PRIMARY KEY (JobStatus) ); CREATE TABLE Quota ( ClientId INTEGER NOT NULL, GraceTime BIGINT DEFAULT 0, QuotaLimit BIGINT DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER NOT NULL, FilesetId INTEGER DEFAULT 0, FileSystem TEXT NOT NULL, PathId INTEGER NOT NULL, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem) ); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('C', 'Created, not yet running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('R', 'Running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('B', 'Blocked',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('T', 'Completed successfully', 10); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('E', 'Terminated with errors', 25); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('e', 'Non-fatal error',20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('f', 'Fatal error',100); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('D', 'Verify found differences',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('A', 'Canceled by user',90); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('F', 'Waiting for Client',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('S', 'Waiting for Storage daemon',15); INSERT INTO Status (JobStatus,JobStatusLong) VALUES ('m', 'Waiting for new media'); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('M', 'Waiting for media mount',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('s', 'Waiting for storage resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('j', 'Waiting for job resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('c', 'Waiting for client resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('d', 'Waiting on maximum jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('t', 'Waiting on start time',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('p', 'Waiting on higher priority jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('a', 'SD despooling attributes',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('i', 'Doing batch insert file records',15); INSERT INTO Version (VersionId) VALUES (2001); bareos-Release-14.2.6/platforms/univention/restart_director000077500000000000000000000002331263011562700241500ustar00rootroot00000000000000#!/bin/sh cd /etc/bareos/autogenerated test clients.include -nt .timestamp -o ! -f .timestamp && service bareos-dir restart >/dev/null && touch .timestamp bareos-Release-14.2.6/platforms/univention/univention-bareos.cron000066400000000000000000000002011263011562700251700ustar00rootroot00000000000000# restart the bareos director before running the daily backup jobs 30 0 * * * root /usr/share/univention-bareos/restart_director bareos-Release-14.2.6/platforms/univention/univention-bareos.py000066400000000000000000000125401263011562700246700ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Univention SSL """Bareos Client Configuration Listener Module.""" # __package__ = '' # workaround for PEP 366 from listener import configRegistry, setuid, unsetuid import grp import os import stat import univention.debug as ud import subprocess import string import random name = 'bareos' description = 'Generate Bareos Configuration for Clients' filter = '(objectClass=bareosClientHost)' attributes = [] PATH_PREFIX='/etc/bareos/autogenerated' FD_CONFIG_PATH=PATH_PREFIX+'/fd-configs' SECRETS_PATH=PATH_PREFIX+'/fd-secrets' JOBS_PATH=PATH_PREFIX+'/clients' INCLUDES_PATH=PATH_PREFIX+'/clients.include' JOB_DISABLED='Not' bareos_gid=grp.getgrnam('bareos').gr_gid def getFqdn(entry): if not entry.has_key('cn'): return None name = entry['cn'][0] if entry.has_key('associatedDomain'): name = name + '.' + entry['associatedDomain'][0] return name def initialize(): """Initialize the module once on first start or after clean.""" ud.debug(ud.LISTENER, ud.INFO, 'BAREOS: Initialize') def handler(dn, new, old): """Handle changes to 'dn'.""" setuid(0) try: # if configRegistry['server/role'] != 'domaincontroller_master': # return # ud.debug(ud.LISTENER, ud.INFO, 'BAREOS: handler '+dn+' '+str(bareos_gid)) if new and not old: # changeType: add name=getFqdn(new) processClient(name,new) elif old and not new: # changeType: delete try: name = getFqdn(old) processClient(name,old,delete=True) except: pass else: # changeType: modify name=getFqdn(new) processClient(name,new) finally: unsetuid() def clean(): """Handle request to clean-up the module.""" return def postrun(): """Transition from prepared-state to not-prepared.""" return def processClient(client_name,entry,delete=False): if client_name==None: return client_type='generic' if 'univentionWindows' in entry['objectClass']: client_type='windows' if delete==True: removeClient(client_name,client_type) return if entry.has_key('bareosEnableJob'): if entry['bareosEnableJob'][0]==JOB_DISABLED: removeClient(client_name,client_type) return addClient(client_name,client_type) def addClient(client_name,client_type): createFDConfig(client_name,client_type) createClientJob(client_name,client_type) addClientInclude(client_name) def removeClient(client_name,client_type): if client_name==None: return # removeClientInclude(client_name) # removeClientJob(client_name) disableClientJob(client_name,client_type) addClientInclude(client_name) def getClientSecret(client_name): path=SECRETS_PATH+'/'+client_name password=None try: f=open(path,'r') password=f.read().strip() except: password=createClientSecret(client_name) return password def getServerName(): server_name=configRegistry['hostname'] domain=configRegistry['domainname'] if domain: server_name=server_name+'.'+configRegistry['domainname'] return server_name def createFDConfig(client_name,client_type): path=FD_CONFIG_PATH+'/'+client_name+'.conf' password=getClientSecret(client_name) server_name=getServerName() templatefile=FD_CONFIG_PATH+'/'+client_type+'.template' os.umask(077) with open(templatefile,'r') as f: content=f.read() t=string.Template(content) with open(path,"w") as f: f.write(t.substitute(password=password,client_name=client_name,server_name=server_name)) os.chown(path,-1,0) def createClientSecret(client_name): path=SECRETS_PATH+'/'+client_name char_set = string.ascii_uppercase + string.digits + string.ascii_lowercase password=''.join(random.sample(char_set*40,40)) os.umask(077) with open(path,'w') as f: f.write(password) os.chown(path,-1,0) return password def removeClientJob(client_name): path=JOBS_PATH+'/'+client_name+'.include' os.remove(path) def createClientJob(client_name,client_type,enable='Yes'): password=getClientSecret(client_name) server_name=getServerName() path=JOBS_PATH+'/'+client_name+'.include' templatefile=JOBS_PATH+'/'+client_type+'.template' os.umask(077) with open(templatefile,'r') as f: content=f.read() t=string.Template(content) with open(path,"w") as f: f.write(t.substitute(enable=enable, \ password=password,client_name=client_name,server_name=server_name)) os.chown(path,-1,bareos_gid) os.chmod(path,stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) def disableClientJob(client_name,client_type): createClientJob(client_name,client_type,'No') def getClientIncludePath(client_name): return '@'+JOBS_PATH+'/'+client_name+'.include' def addClientInclude(client_name): # is the client already in the include list? if isClientIncluded(client_name): # update the timestamp on the file # to let the cron script know the configuration # has changed os.utime(INCLUDES_PATH,None) return # if not, add it at the end of the file with open(INCLUDES_PATH,'a') as f: f.write(getClientIncludePath(client_name)) f.write('\n') def isClientIncluded(client_name): want=getClientIncludePath(client_name) with open(INCLUDES_PATH,'r') as f: for l in f.readlines(): if want in l: return True return False def removeClientInclude(client_name): if not isClientIncluded(client_name): return want=getClientIncludePath(client_name) lines=[] with open(INCLUDES_PATH,'r+') as f: lines=f.readlines() f.seek(0) f.truncate(0) for l in lines: if want in l: continue f.write(l) bareos-Release-14.2.6/platforms/univention/univention-bareos.schema000066400000000000000000000024541263011562700255030ustar00rootroot00000000000000objectidentifier DASS 1.3.6.1.4.1.22346 objectidentifier DASS.BAREOS DASS:6 objectidentifier DASS.BAREOS.OC DASS.BAREOS:4 objectidentifier DASS.BAREOS.Attr DASS.BAREOS:6 # # schema file for Univentionr-Bareos attributes # attributeType ( DASS.BAREOS.Attr:2.1 NAME 'bareosCommon' DESC 'common bareos attributes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) attributeType ( DASS.BAREOS.Attr:2.2 NAME 'bareosSchedule' DESC 'backup schedule' SUP bareosCommon ) attributeType ( DASS.BAREOS.Attr:2.3 NAME 'bareosFileSet' DESC 'fileset to use for this bareos client' SUP bareosCommon ) attributeType ( DASS.BAREOS.Attr:2.4 NAME 'bareosOptions' DESC 'options for the backup job' SUP bareosCommon ) attributeType ( DASS.BAREOS.Attr:2.5 NAME 'bareosProfile' DESC 'job defaults' SUP bareosCommon ) attributeType ( DASS.BAREOS.Attr:2.6 NAME 'bareosEnableJob' DESC 'enable job for this client' SUP bareosCommon ) # # schema file for Univention-Bareos objectclasses # objectClass ( DASS.BAREOS.OC:2.1 NAME 'bareosClientHost' DESC 'a system that should be backed up by the bareos server' SUP top MAY ( bareosSchedule $ bareosFileSet $ bareosOptions $ bareosProfile $ bareosEnableJob ) AUXILIARY ) bareos-Release-14.2.6/platforms/unknown/000077500000000000000000000000001263011562700201465ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/unknown/Makefile.in000066400000000000000000000010421263011562700222100ustar00rootroot00000000000000# # This file is used as the template to create the # Makefile for the unknown specific installation. # # 15 November 2001 -- Kern Sibbald # # for Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ # @MCOMMON@ nothing: install: all: install-autostart: install-autostart-FD install-autostart-SD install-autostart-DIR install-autostart-FD: install-autostart-SD: install-autostart-DIR: clean: distclean: @$(RMF) bareos-SD bareos-FD bareos-DIR Makefile bareos-*.spec devclean: @$(RMF) bareos-SD bareos-FD bareos-DIR Makefile bareos-*.spec bareos-Release-14.2.6/platforms/win32/000077500000000000000000000000001263011562700174115ustar00rootroot00000000000000bareos-Release-14.2.6/platforms/win32/bareos.ico000066400000000000000000003633661263011562700214010ustar00rootroot00000000000000 (d ".".u0uu߾uu߾uuPuuPuuuuuuuuuuuupu uPuuuuuuuuuuuuuuuuu߾uu0u0uuuuuuuuuuuuuuuuuuuuuuu߾uuPu uu߾uuuuuuuuuuuuuuuuuuuuuuuuuuuuuPuupuϾuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu߾uu0uPuuuuuuuuuuuuuuuu~֩`ԯԯڱpƆ uuuuuuuuuuuuuuuuu߾uu u uu߾uuuuuuuuuuuuuuƆ ڱpÏҠPuuuuuuuuuuuuuuuuuϾu`uu`uuuuuuuuuuuuuuuƆ ڱpԯ֩`~uuuuuuuuuuuuuuuuu@u uuuuuuuuuuuuuuu~֩`ԯ֩`~uuuuuuuuuuuuuuu߾uu u@uuuuuuuuuuuuuuu֩`ԯԯ֩`~uuuuuuuuuuuuuuuu@uu`u߾uuuuuuuuuuuuuʏ0˟ݿԯ֩`~uuuuuuuuuuuuuu߾upuu uuuuuuuuuuuuuuƆ ڱpԯ֩`~uuΘ@Ï˟ҠPuuuuuuuuuuuuuuuu u0uuuuuuuuuuuuuuҠPԯ˟ҠPuuuuuuuuuƆ ڱpԯÏƆ uuuuuuuuuuuuuuu@u@uuuuuuuuuuuuuƆ ߺԯҠPuuuuuuuuuuuuuuu~֩`ԯݿ֩`~uuuuuuuuuuuuuϾu`u`uuuuuuuuuuuuuΘ@ԯݿ֩`~uuuuuuuuuuuuuuuuuuuu~֩`ԯ˟ʏ0uuuuuuuuuuuuu߾u`u`u߾uuuuuuuuuuu~֩`ڱpƆ uuuuuuuuuuuuuuuuuuuuuuuuuu~֩`ԯݿ֩`uuuuuuuuuuuuu߾upuu`u߾uuuuuuuuuuuƆ Ï˟ʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ ڱpߺ~uuuuuuuuuuuuuu`u߾uuuuuuuuuuuʏ0˟֩`~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0Ï˟Ɔ uuuuuuuuuuuu߾u`u@uuuuuuuuuuuuΘ@ݿ˟ʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ݿݿΘ@uuuuuuuuuuuu߾u`u0uuuuuuuuuuuu֩`֩`~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ Ïݿ֩`uuuuuuuuuuuuu@u uuuuuuuuuuuu֩`ԯΘ@uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ݿ֩`uuuuuuuuuuuuu uuuuuuuuuuuu֩`˟Ɔ uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0˟֩`uuuuuuuuuuuuuuPu߾uuuuuuuuuuΘ@ߺ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ ߺΘ@uuuuuuuuuuu߾uPu uuuuuuuuuuuΘ@ݿ֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~ڱpݿΘ@uuuuuuuuuuuu uuuuuuuuuuuƆ ԯ֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`˟Ɔ uuuuuuuuuuupu0uϾuuuuuuuuu~ÏݿҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ߺ~uuuuuuuuuuu uuuuuuuuuuuڱpҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ҠPuuuuuuuuuuuPu0uϾuuuuuuuuuΘ@֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ݿƆ uuuuuuuuuuuu`uuuuuuuuu~Ï֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~ߺڱpuuuuuuuuuuϾu0uuuuuuuuuuuҠPߺ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~˟ݿƆ uuuuuuuuuu`u0uϾuuuuuuuu~ԯ˟Ɔ uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0ݿڱpuuuuuuuuuuu`uuuuuuuuuΘ@Θ@uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ԯ~uuuuuuuuuuuuuuuuuuuuÏڱpuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~Ïʏ0uuuuuuuuuϾuuuuuuuuuuƆ ԯƆ uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuΘ@֩`uuuuuuuuuϾuuuuuuuuuuuҠPҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~Ï˟uuuuuuuuuϾu0uuϾuuuuuuuuڱpԯ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuҠPԯ~uuuuuuuu߾uuuϾuuuuuuuu˟֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ ~uuuuuuuuϾuuuϾuuuuuuu~ʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuÏ~uuuuuuuuϾuuϾuuuuuuu~˟~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`~uuuuuuuuuuuuuuuu~֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0~uuuuuuuuuuuuuuuu~ʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0~uuuuuuuu@u@uuuuuuu~ʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~˟uuuuuuuu߾uuuuuuuuuuԯ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~ڱpuuuuuuuuuuuuuuuuÏ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ ʏ0uuuuuuuu@uPuuuuuuuҠP~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0~uuuuuuuu߾uuuuuu~~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuҠPÏuuuuuuuu@upuuuuuuuԯʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺʏ0uuuuuuuu߾uuuuuuҠP֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿuuuuuuuu0u`uuuuuuu˟uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ Θ@uuuuuuuuuuuuuu֩`~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺԯuuuuuuuu uuuuuuuҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~Ɔ uuuuuuu@u`uuuuuuҠPݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺڱpuuuuuuuuuuuuuu˟Θ@uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~uuuuuuuuϾuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuԯ~uuuuuu߾uuuuuuΘ@ߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`ҠPuuuuuuuuuuuuڱpʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ ߺuuuuuuuuuuuuÏuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟uuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿݿݿݿݿݿݿݿݿݿݿݿÏߺߺߺߺ֩`Θ@Θ@uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿڱp~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuԯ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu~uuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuҠPuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟uuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~֩`ݿ~uuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuڱpΘ@uuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuԯڱpuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0ߺuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟uuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟ݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ ߺuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺߺuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0ҠPuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu~ߺʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺ˟uuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuԯuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu~uuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟uuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuƆ uuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuÏ~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuÏʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿÏڱpʏ0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuu˟Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@Θ@~uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuߺuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿ֩`uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺߺݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuݿݿuuuuuuuuuuuuÏݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿݿÏuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu???????bareos-Release-14.2.6/platforms/win32/bareosdir.ico000066400000000000000000000314461263011562700220670ustar00rootroot00000000000000hF .0V=@((   ׽׾׾׾׾׾׽ݸ͘VΙX͗T̖S͖S̖SџaѳڴÂ3ܶ0ww w!NJ@ҵڳą7ֽ޻ڲٰ}Ɖ>NJ@Ѵڳą7պڲէoÝݹƉ?Ѵڳą8ίNjA|(ӤjྕNJ?ѴڳÃ4ͭίɧѴԥkƉ>ѳ޺Ɖ=Ã3Ƈ;ƈ<Ą6{'͘VƝݷ˓N~,z%Ã3Н^˫Բմүܷ֩ss‘ֶ᷀Ȟүˡ㹂仄ڼ㸀ĕմŗЪzÔ|ǚˡެkˢǚxyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@  ww w!x!x"y#y#y$z$z%z&{&{'~|(|)})~+~,-.́€/̓ ΄"΅$φ&χ(1Á1Â2Â3Ã3Ã4ă5Ɖ=Ɖ>Љ*Љ+Њ-Ћ/ь1э2э3ӑ:Ӓ:Ӓ;ӓ<ɏHʑK˔O̕QΙXΚYΚZԕ@՗D֙G֚IМ^؞QО`ОaڢXڢYڤ[ۥ]ۥ^ҡeӤjӤkԦmԧoܨbܩdݪfݪgݫhޫiޮm߮n߯oըq֩r֪u׭yخzخ{د|ٯ|ٯ}ٰ~ٱ~ڱ~svy{}~ڱڳ۳۴۴۵۵ܷܷܵܶܶݹݹ޺޺߾߾㹁㺃仅佈徊忍ྕÓƗ›ǘɜʝȝɞʟŠšɣɧ̬ͮʠ̣̤ͥΦϨϩϰϱӮӯүвҵ԰ӰֳԲ׶׶մֵԹպջֻּظٹعٿٽٻڼNMPQNMNKzw P`*I䒇<%~Њ-Ҏ4Ӓ;ȍDʐFʒL̖SΘWϛ[ՖBךJ؝N؟Rџb٠Uڤ[ѡeԤkޭlէp֪t׭x߯pخ{޲sܴ{޹uyڳݷ߼޹߼὆侊࿖ƖșŗȝƢȦ˪̤ϩѬӴּؼڽTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSTTTTTTTTTTTTTTSTTSTTTTTTTTT5555555555555555555555555555555557555555555557(KLKLLKILLKLKLLKKLKKKLLKLLLKLLKILLLKLLLKLLKLK(4TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT.4TTQ82228CQTTTS=22222224MTTM4=STTTTTTTTTTTTTT14TTPFTTS  ?TTGOTTTTTTTTTTTTTT24TTR'G>FTTPKKG9KKQTTP GTTTTTTTTTTTTTT44TTT+!TTP%PTTTTT9TTTTTS=TTTTTTTTTTTTTT.4TTT9RTTM=TTTTT1*TTTTTT*1TTTTTTTTTTTTTT14TTTCMTTT1STTTT=STTTTT9STTTTTTTTTTTTT.4TTTLFTTTBMTTTTG PTTTTTC ITTTTTTTTTTTTT.4TTTR=TTTKGTTTTOHTTTTTM!RTTTTTTTTTTTT.4TTTT!+TTTPCTTSQM?TTTTTP%HPMQTTTTTTTT14TTTT2STTH FTT@1TTTTTQ 8TTTTTTTT24TTTT@PTP*MTTH!!!!=TTTTTS2(L>7TTTTTTTT.4TTTTI !!2TTTTTTTSSTTTTTTSJAIQRSSTTTTTTTT.4TTTTQ 9RTTTTTTL!'OTTTQA," :LTTTTTTTTT.4TTTTTMIIKMRTTTTTTTTL BTQ< 0;0::&,ESTTTTTT.4TTTTTTTTTTTTTTTTTTTS@>I< #::,:0&ITTTTT24TTTTTTTTTTTTTTTTTTTTTH" :0 "?[[[[[[[[[[[[[[[[[[Z")[[[[Y  N[[[[NW[[[[[[P$Z[[[[[[[J 0[[[[[[[[[[[[[[[[[[Z")Z[[[[.F[[[[Z$ G[[[[[[XX[[[[[[[R Y[[[[[[[[[[[[[[[[[Z")Z[[[[=6[[[[[:6[[[[[[Z$O[[[[[[[X M[[[[[[[[[[[[[[[[[Z"'Z[[[[G ([[[[[I (Z[[[[[[6G[[[[[[[Z)*Z[[[[[[[[[[[[[[[[Z"'Z[[[[RX[[[[O Y[[[[[[D:[[[[[[[[6 =Z[[[[[[[[[[[[[[[Z"'[[[[[XR[[[[SX[[[YXXG *[[[[[[[[= 1OXVRX[[[[[[[[[[Z")[[[[[Z( G[[[[M X[[[6X[[[[[[[?  F[[[[[[[[[[Z")Z[[[[[7=[[[[1(Z[[[7 T[[[[[[[A F>6[[[[[[[[[[Z")Z[[[[[F*YYS9 ?[[[[WMMMMMNZ[[[[[[[WMNX[SD==AP[[[[[[[[[[Z"'Z[[[[[N #$X[[[[[[[[[[[[[[[[[[[[[QEESZ[[[[[[[[[[[[[[Z"'Z[[[[[V1V[[[[[[[[[N11F[[[[[[XH++EV[[[[[[[[[[[[Z"'[[[[[[ZF:::=?IRZ[[[[[[[[[[F$Z[[[Q;&@LK@&3PZ[[[[[[[[[Z")[[[[[[[[[[[[[[[[[[[[[[[[[[P #X[Q44KE33HK8-LZ[[[[[[[Z")Z[[[[[[[[[[[[[[[[[[[[[[[[[ZPORT5;L@& ;KB!/Q[[[[[[Z")Z[[[[[[[[[[[[[[[[[[[[[[[[[[[ZG;K;3KB@X[[[[Z"'Z[[[[[[[[[[[[[[[[[[[[[[[[[[U3/K@5L5+S[[[Z"'Z[[[[[[[[[[[[[[[[[[[[[[[[[S!BH&EHQ[[Z"'[[[[[[[[[[[[[[[[[[[[[[[[[VK; 5KS[Z"'Z[[[[[[[[[[[[[[[[[[[[[[[Y+H42K+ZZ"497777474977774974977747+B8;@-7NGGFGFGGGGGFGFGGGGFFGGGGD!HKEK[[[[[[[[[[[[[[[[[[[[[[[[Y55    B+-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2 ;KHHHKHHHHKHHEB4;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2Q[[[[[[[[[[[[[[[L;/-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[[ZZZZZZZZZZZ[[[B;//[[[[[[[[[[[[[[[[[[[[[[[[[[X;/P[Z;%%%%%&%%%&EZ[Q;/-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[Z&Y[W;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[Z&X[W;/-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2P[Z&W[W;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[Z&W[X;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2P[Z&W[X;2-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[Z&Y[X;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2P[[@&++&&&&&&+H[[Q;2/Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[[ZZZZZ[[ZZ[Z[[[@@2/Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2P[[[[[[[[[[[[[[[L;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[[PEEEHEHEKEHB2;/-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[Z+   ;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2P[Z&;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2 P[Z&;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2P[[&;2-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;2KXW&;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2  ;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2;/-[[[[[[[[[[[[[[[[[[[[[[[[[[X;2;/-Z[[[[[[[[[[[[[[[[[[[[[[[[[X;K5555555555555555555;55555555L/-[[[[[[[[[[[[[[[[[[[[[[[[[[X!555555555555555555555555555555-[[[[[[[[[[[[[[[[[[[[[[[[[[X   2[[[[[[[[[[[[[[[[[[[[[[[[[[[PKKKKKKKKKKKKKKKKKKKKKLKKKKKKKKKKS[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[bareos-Release-14.2.6/platforms/win32/bareosfd.ico000066400000000000000000000314461263011562700217020ustar00rootroot00000000000000hF .0V=@((   ׽׾׾׾׾׾׽ݸ͘VΙX͗T̖S͖S̖SџaѳڴÂ3ܶ0ww w!NJ@ҵڳą7ֽ޻ڲٰ}Ɖ>NJ@Ѵڳą7պڲէoÝݹƉ?Ѵڳą8ίNjA|(ӤjྕNJ?ѴڳÃ4ͭίɧѴԥkƉ>ѳ޺Ɖ=Ã3Ƈ;ƈ<Ą6{'͘VƝ߼˔O~,z%Ã3Н^˫ȝʟʠÔʥܷըqٻ㹂{ɞ忋ǛެkͤΨΨ仆㹂Ա佈Ӱ忋ֶͦǛ㺃Ъxyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@  ww w!x!x"y#y#y$z$z%z&{&{'~|(|)})~+~,-.͂€/̓!΄"΅$Ά%Ά&ψ(1Á1Â2Â3Ã3Ã4ă5Ɖ=Ɖ>Ћ.ь1э2ю4Ҏ5Ґ7Ӓ<ԓ=Ԕ>Ԕ?ɏHʑK˔O̕QΙXΚYΚZԕ@ՕAՖC՗D՗E֘F֙IךJלNםOМ^؞P؞QО`Оa٠UڣYҡeӤjӤkԦmԧoݫhޮmըq֩r֪u׭yخzخ{د|ٯ|ٯ}ٰ~ٱ~ڱ~uڱڳ۳۴۴۵۵ܷܷܵܶܶݹݹ޺޺߾߾伇ྕ࿖ÓƗ›ǘɜʝŗƘǚǛȝŠšɣɧ̬ͮˡˢΧϰϱӮӯҭҮвҵ԰ӰӱֳԲ׶׶մԹպջֻּ׸ظٹظعڽ۾ܿxy{{n* BB(qzt(qGB+///>M~FBN<[8t&{<*԰,/;8=;-/FƂ```oѾ`bI26Z\kc`D1U\o\O  4ccԕwUH   1\kuZU  # ISoLvO 4koL؉%4klL k34klL  _34klL k24klL؏%4klL渷J 4klL%  4klL 4klL Rb  4klQEke`ZZU\ZZ\WU\\\UeZ`eeeggeeeeeeee`(.`   vw y$y|})́€/΄#ψ)Â2ņ8Ɖ>Љ+э3ԓ=ȍDʐFʒL̖SΘWϛ[ՖC֘FכL؝O؟Rџb٠Uۤ\ѡeԤkܨcݫi֪t׭x߯pخ{ܴvܴ{޹u}ڳݷ߼޹߼὆⾈࿖ŕșŖƙƢȦ˪ͥѬҳּغڽSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS6666666666666666666666666666666666666666666668'JLLLJJJKKLKLKJKLLJJLLKLLJJLLJLJJLJLJLLJLLKLL'5SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS/5SSPILSSSSSSSSSSJIIIKOSSSSSSSSSSSSSSSSSSSSSSS/5SSB OSSSSSSSSR  +LSSSSSSSSSSSSSSSSSSSSS35SSH ISSSSSSSSS%2"HSSSSSSSSSSSSSSSSSSSS/5SSO?SSSSSSSSS9QSKOSSSSSSSSSSSSSSSSSSS55SSS5SSSSSSSSSCOSSL9SSSSSSSSSSSSSSSSSSS/5SSS+HHGHHLSSSKHSSS6PSSSSSSSSSSSSSSSSSS35SSS>  QSSP>SSSH HSSSSSSSSSSSSSSSSSS25SSSF "++++6QSSS2SSSO?SSSSSSSSSSSSSSSSSS25SSSLCSSSSSSSSS3SSSR9SSSSSSSSSSSSSSSSSS25SSSR:SSSSSSSSS?OSSR6SSSSSSSSSSSSSSSSSS35SSSS%*SSSSSSSSSH KSSF ?SSSSSSSSSSSSSSSSSS/5SSSS9CFFFFHRSSO6B6NSSRM@IQSSSSSSSSSSS/5SSSSBHSSRDSQD-  7LSSSSSSSSS/3SSSSO:6639959LSSSC565:BPO< 1;1;;&-ERSSSSSS/5SSSSSSSSSSSSSSSSSSSSSSQ=#;7 -=1&ISSSSS/5SSSSSSSSSSSSSSSSSSSSSG #<1 #=07QSSS/5SSSSSSSSSSSSSSSSSSSS<77 &= #NSS35SSSSSSSSSSSSSSSSSSR7=#;& OS3)POOOPOPPOPOPOOOOOP@= ; .O(/55555555555555515/4 =(/SRRRRRRSRRRRRSRRRRI;     1 DRSSSSSSSSSSSSSSSSSSJ7 @GGEEEEEEDD=-#DSSSSSSSSSSSSSSSSSSSJ7OSSSSSSSSSSSI-#DSSSSSSSSSSSSSSSSSSSJ7OS@--.--.-=RS&-#DSSSSSSSSSSSSSSSSSSSJ7MS$ JS1-#DSSSSSSSSSSSSSSSSSSSJ7MS$ IS1-#DSSSSSSSSSSSSSSSSSSSJ;MS- IS4-#DSSSSSSSSSSSSSSSSSSSJ1MS$ IS4-#DSSSSSSSSSSSSSSSSSSSJ;MS.    OS.-#DSSSSSSSSSSSSSSSSSSSJ7MSONJNNLNNPSQ-#DSSSSSSSSSSSSSSSSSSSJ ;MSSSSRSSRSRM1-#DSSSSSSSSSSSSSSSSSSSJ1MS;  -#DSSSSSSSSSSSSSSSSSSSJ;MS$&#DSSSSSSSSSSSSSSSSSSSJ;MS&-#DSSSSSSSSSSSSSSSSSSSJ7MS&-#DSSSSSSSSSSSSSSSSSSSJ7 #-#DSSSSSSSSSSSSSSSSSSSJ7-#DSSSSSSSSSSSSSSSSSSSJ=7#DSSSSSSSSSSSSSSSSSSSJ17771771177177111117717DSSSSSSSSSSSSSSSSSSSNISSSSSSSSSSSSSSSSSSSSPPPPPPPPQPPPPPPPPPPPPPPPPRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS(=  vw z$w y{~{'~+́΅$ψ)Ã3ņ9ƈ=Љ+Ҏ4Ӓ;NJ@ȎEɏHʒL̖SΘWΚZՖC֘F՜LО^؞Qџb֧^٠Uۥ]ҡeԥlתcܧb٪dެj֪sخsخz߰qٰ~tzڲܶݹ߽⻅ΉྖÓÝȚǚȝƣ̡˪ͥϪϰѬԴֽظڽXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::D:>>>>>>>><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>:&XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$WXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXW&WXXXUUWXXXXXXXXXXXXXWUVUWUWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXW&WXXP!/WXXXXXXXXXXXX;!/GUXXXXXXXXXXXXXXXXXXXXXXXXXXXXW&WXXPTXXXXXXXXXXXX8 %OXXXXXXXXXXXXXXXXXXXXXXXXXXXW$WXXV LXXXXXXXXXXXXG <;-LXXXXXXXXXXXXXXXXXXXXXXXXXXW$WXXX- CXXXXXXXXXXXXOUXXP% TXXXXXXXXXXXXXXXXXXXXXXXXXW$XXXX84XXXXXXXXXXXXUOXXXU!8XXXXXXXXXXXXXXXXXXXXXXXXXW&XXXXD %XXXXXXXXXXXXW% FXXXXJ SXXXXXXXXXXXXXXXXXXXXXXXXW&WXXXOFJJGJJGLXXXXX58XXXXW%CXXXXXXXXXXXXXXXXXXXXXXXXW&WXXXU SXXXXC)XXXXX< -XXXXXXXXXXXXXXXXXXXXXXXXW$WXXXW% LXXXXL VXXXXL UXXXXXXXXXXXXXXXXXXXXXXXW$WXXXX4.OOLOOOOWXXXXTQXXXXSSXXXXXXXXXXXXXXXXXXXXXXXW$XXXXXA-XXXXXXXXXXXXW  JXXXXUOXXXXXXXXXXXXXXXXXXXXXXXW&WXXXXL  UXXXXXXXXXXXX.@XXXXU MXXXXXXXXXXXXXXXXXXXXXXXW&WXXXXTQXXXXXXXXXXXX</XXXXL PXXXXXXXXXXXXXXXXXXXXXXXW&WXXXXW  KXXXXXXXXXXXXG !XXXT' VXXXXXXXXXXXXXXXXXXXXXXXW$WXXXXX+.FFFFDFDOXXXXPAC8 >XXXXWP?DNWXXXXXXXXXXXXXXW$WXXXXX; !WXXXU 1VXXRE((BRXXXXXXXXXXXXW$XXXXXXJ%UXXXX4.HWXP9#?HH=#1MWXXXXXXXXXW&XXXXXXXTTSSTSQTTSTXXXXXUTSTTUUXXP22HE11DH6*IWXXXXXXXW&WXXXXXXXXXXXXXXXXXXXXXXXXXXXXXT69H="  9H?*NXXXXXXW&WXXXXXXXXXXXXXXXXXXXXXXXXXXXWD9I6 1H?=UXXXXW$WXXXXXXXXXXXXXXXXXXXXXXXXXXU0,I93I3(PXXXW$WXXXXXXXXXXXXXXXXXXXXXXXXXP"?E"DDMXXW$XXXXXXXXXXXXXXXXXXXXXXXXXRE9 3HNXW$WXXXXXXXXXXXXXXXXXXXXXXXU(H11H(VW255772775277555755577277+ ?69= *5KDDCDCDCDDCCDDDCDDDCCDDC?HHDHXXXXXXXXXXXXXXXXXXXXXXXXV33    ?(*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 9EEEEEEEEEHEEB?29**XXXXXXXXXXXXXXXXXXXXXXXXXXU90 NXXXXXXXXXXXXXXXI90*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXXWWWWWWWWWWWXXX?9,*WXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW9""#""#"""#BWXN9,*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#UXR9,*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#UXU9,*WXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#RXU9**XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#UXU90*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#UXU9**XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#VXU90*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXX=#((#(##(#*EXXN90*WXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXXWWWWWWWXWWWXXX==0*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXXXXXXXXXXXXXXXI9,*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXWMBEBEBBBBBE?09,*WXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW(  9**XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW#90*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXX(90*XXXXXXXXXXXXXXXXXXXXXXXXXXU90 MXW( 9,*WXXXXXXXXXXXXXXXXXXXXXXXXXU90 HUU#9**XXXXXXXXXXXXXXXXXXXXXXXXXXU90 90*XXXXXXXXXXXXXXXXXXXXXXXXXXU909,*XXXXXXXXXXXXXXXXXXXXXXXXXXU909**WXXXXXXXXXXXXXXXXXXXXXXXXXU9H3333333333333333333933333333M,*XXXXXXXXXXXXXXXXXXXXXXXXXXU333333333333333336333333333332*XXXXXXXXXXXXXXXXXXXXXXXXXXV   0XXXXXXXXXXXXXXXXXXXXXXXXXXWMHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHPXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXbareos-Release-14.2.6/platforms/win32/bareossd.ico000066400000000000000000000314461263011562700217170ustar00rootroot00000000000000hF .0V=@((   ׽׾׾׾׾׾׽ݸ͘VΙX͗T̖S͖S̖SџaѳڴÂ3ܶ0ww w!NJ@ҵڳą7ֽ޻ڲٰ}Ɖ>NJ@Ѵڳą7պڲէoÝݹƉ?Ѵڳą8ίNjA|(ӤjྕNJ?ѴڳÃ4ͭίɧѴԥkƉ>ѳ޺Ɖ=Ã3Ƈ;ƈ<Ą6{'͘VƝ޻˓O~,z%Ã3Н^˫㺃㺃⹂ɤܷըqŗ̣ɟǚʟ佈~彉ͦͥˢޭk߰qҮwΧẸ̇Ǜxyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@  ww w!x!x"y#y#y$z$z%z&{&{'|(|)})~+~,-.́€/̓ ̈́"΄"΄#΅#΅$1Á1Â2Â3Ã3Ã4ă5Ɖ=Ɖ>Љ+Љ,Ћ/ь0э2Ҏ4Ҏ5ҏ6Ґ7ӑ:Ԕ>ɏHʑK˔O̕QΙXΚYΚZԔ@ԕ@ԕAՕAՖB՗D՘E֘G؝NМ^؞P؟RО`Оa١Vۥ^ۦ_ҡeӤjӤkԦmԧoܧbݫhݫiޭlޭmޮm߮nըq֩r֪u׭yخzخ{د|ٯ|ٯ}ٰ~ٱ~ڱ~svxyڱڳ۳۴۴۵۵ܷܷܵܶܶݹݹ޺޺߾߾㹂㺃伇徊忋ྕ࿖Ɨĕ›ğǘɜʝŖŗǚǛŠɣɧ̬̤ͮͥΧΨϰϱӮӯҮвҵ԰ӱֳԱԳճ׶׶ֵԹպջֻּظٹٺٺپ۽غڼ۽۾ξc':/BO'/:dwE>`*,O%ΐ/':Px'*F%P<a:`a.%PM?/Bܽx*PGzB-,Ԍhii}zyϐiiI16_hqhiC! 1Yi}fT! 4imܨYH  1gt_] !!!" IYuL õT 4tuLᔍ$4tuL t34tuL h34tuL t36tuLᙘ$6tuLL 4tuL$ 4tuL 4tuL Wi 4tuVCtnh__\\\\\\\\__\o\hoooooonnnppnoi(.`   vw y$w y{~})́€/̈́!χ(ψ)Â2ņ8Ɖ>Њ-э3ԓ=ȍDʐFʒL̖SΘWϛ[ՕA֘F֚I؟Rџb٠UڢYѡeԤkܧaܨdޭl֪t׭xخ{޲sܴ{޹v}ڳݷ߼޹߼὇⾉࿖ƖșǚȜƢȦ˪̣ϩѭԴֻؾ۾VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUVVVUUVVVVVUVVVVUUVVVVUVVVVVUVUVVVVVUUVVVUV7979777977777777777977777977777979777779777779)NMLNNMNNNNMNMNNNLNNNNMNNNNMNNMNNNMLNNMNNNMNM)6VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV66VVVVVUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV06VVS@$$:QVVVVJ,,,,7HUVVVVVVVVVVVVVVVVVVVVVV36VU+ EVVVC $NVVVVVVVVVVVVVVVVVVVVV36VI3OSK$OVVM?J?QVVVVVVVVVVVVVVVVVVVV66VHRVVVR?VVSAVVM,UVVVVVVVVVVVVVVVVVVV06VUROVVVVU3VVU#3VVVCKVVVVVVVVVVVVVVVVVVV36VVVVVVUM4 7VVV3#UVVS7VVVVVVVVVVVVVVVVVVV36VVVVO7OVVV?SVVV,#VVVVVVVVVVVVVVVVVVV36VVVJ";RVVVVJ MVVV?SVVVVVVVVVVVVVVVVVV36VVV,?OUVVVVVVQCVVVASVVVVVVVVVVVVVVVVVV36VVU++VVVUIKTVVU7VVV7SVVVVVVVVVVVVVVVVVV06VVV:RVVMHVVV+$UUI$VVVUNDKTVVVVVVVVVVV36VVVQ;?MVVV;$GVSF' ! !8OUVVVVVVVV06VVVVK#;UVVVH$JP=!!2=8<<'.GUVVVVVV36VVVVVUMECHQVVVVVUOOOQSS>!%<8 .=2'KVVVVV36VVVVVVVVVVVVVVVVVVVVVJ%!=2%>18TVVV06VVVVVVVVVVVVVVVVVVVU=5<'>!%QVV36VVVVVVVVVVVVVVVVVVU8=%<'!RV3*RSSSRRSRRSSRRSRRSRB><%.R)06666666666666666605!=)0UUUUUUUUUUUUUUUUUUL=    2!FUVVVVVVVVVVVVVVVVVVL 8CGGGGGGGGFF<.%FVVVVVVVVVVVVVVVVVVVL 8RVVVVVVVVVVVK.%FVVVVVVVVVVVVVVVVVVVL 8PVB...../.>UV'.%FVVVVVVVVVVVVVVVVVVVL 8RV&LV2.%FVVVVVVVVVVVVVVVVVVVL 8PV& KV2.%FVVVVVVVVVVVVVVVVVVVL 2PV& KV2'%FVVVVVVVVVVVVVVVVVVVL 8PV& KV8.%FVVVVVVVVVVVVVVVVVVVL <PV/SV1.%FVVVVVVVVVVVVVVVVVVVL 8PVSQLQQNQQTVT.%FVVVVVVVVVVVVVVVVVVVL!8 PVVVUVUVUVUP2.%FVVVVVVVVVVVVVVVVVVVL 8PV< !!!!!! .%FVVVVVVVVVVVVVVVVVVVL 8PV%.%FVVVVVVVVVVVVVVVVVVVL <PV'.%FVVVVVVVVVVVVVVVVVVVL 8PV'.%FVVVVVVVVVVVVVVVVVVVL 8 !%.%FVVVVVVVVVVVVVVVVVVVL 8.%FVVVVVVVVVVVVVVVVVVVL >8%FVVVVVVVVVVVVVVVVVVVL28282888288288222228228FVVVVVVVVVVVVVVVVVVVQKVVVVVVVVVVVVVVVVVVVVSSSSSSSSSSSSSSSSSSSSTSSSSUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV(=  vw z$y|{'~+́΅#χ(ψ*Ã3ņ9ƈ=Њ,э3Ӓ<NJ@ȎEɏHʒL̖SΘWΚZՖB֘G՜KО^؞Qџb֧^١Vۤ\ҡeԥlתcܧb٪dޮm֪sܮqخz߰qٰ~tzڲܶݹ߽㻄⿋࿖ÓÝȚŗƙɝƣ̡˪ˢΨϰѬӳּظ۾YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYD:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::E:?????????????????????????????????????????????????????????:&YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY$XYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYX$XYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYX$YYYYYQGDDDLUYYYYYYYWPPPPPPVYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYX$XYYS. 5RYYYYYH .LYYYYYYYYYYYYYYYYYYYYYYYYYYYYYX&YYW' NYYYYM  7WYYYYYYYYYYYYYYYYYYYYYYYYYYYX&XYK 7QVUH!!VYYYU DLE- 4XYYYYYYYYYYYYYYYYYYYYYYYYYYX&XYA%XYYYYSHYYYX!HYYXE DYYYYYYYYYYYYYYYYYYYYYYYYYYX&YYM/ BYYYYYY;4YYYY/=YYYYBUYYYYYYYYYYYYYYYYYYYYYYYYYX&XYYYWYYYYYYY=-YYYY?.YYYYW!BYYYYYYYYYYYYYYYYYYYYYYYYYX&XYYYYYYYYYVG.YYYYK  XYYYYD&XYYYYYYYYYYYYYYYYYYYYYYYYX$XYYYYYYVH5  HYYYYRTYYYYQTYYYYYYYYYYYYYYYYYYYYYYYYX$XYYYYV= DYYYYYW LYYYYV  LYYYYYYYYYYYYYYYYYYYYYYYYX$YYYYX.'DTYYYYYYY)DYYYYY'EYYYYYYYYYYYYYYYYYYYYYYYYX&XYYYM &GUYYYYYYYYYY85YYYYY.?YYYYYYYYYYYYYYYYYYYYYYYYX&YYYYFVYYYYYXYYYYYYG%XYYYY'?YYYYYYYYYYYYYYYYYYYYYYYYX&XYYYL !XYYYYL'5LYYYYPVYYYUFYYYYYYYYYYYYYYYYYYYYYYYYX$XYYYV HYYYY4.YYYYVPYYQ-QYYYYXQ@EOXYYYYYYYYYYYYYYX$XYYYY=;LL8=YYYYX%'4'8YYYVC((CSYYYYYYYYYYYYX$YYYYYV4  TYYYYY42WYO9#>JI>#2NXYYYYYYYYYX&YYYYYYXG'.PYYYYYYK'%'&'-=MYQ22IF11EI6*JXYYYYYYYX&XYYYYYYYYVRRRVYYYYYYYYYXXXXXYYU39J@"  9I@,NYYYYYYX&XYYYYYYYYYYYYYYYYYYYYYYYYYYYXE9J91I@>VYYYYX$XYYYYYYYYYYYYYYYYYYYYYYYYYYV0*J>3I3(QYYYX$XYYYYYYYYYYYYYYYYYYYYYYYYYQ"@I" EENYYX$YYYYYYYYYYYYYYYYYYYYYYYYYTF9 3IQYX$XYYYYYYYYYYYYYYYYYYYYYYYW(I10I(XX275555255525555752755525( @69> *5LEEDEEEDEEEEEDEEEEDDEEEEB"F IEIYYYYYYYYYYYYYYYYYYYYYYYYW33   @(*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 9IFFIFFIFFFFCC@29,*YYYYYYYYYYYYYYYYYYYYYYYYYYV9, OYYYYYYYYYYYYYYYJ9,*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYYXXXXXXXXXWXYYY@90*XYYYYYYYYYYYYYYYYYYYYYYYYYV90 OYX9""#"#"""##CYYO9**YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#WYU90*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#UYU9**XYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#UYV9**YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#UYV90*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#VYV9**YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#WYV90*XYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYY>####(##(#*FYYO90*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYYYXYXXXXYXXXYYY>>0*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYYYYYYYYYYYYYYYJ90*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYYNCCCFCFCICF@09**YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX(  9**XYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#90*YYYYYYYYYYYYYYYYYYYYYYYYYYV9, NYX# 9,*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 NYX#90*XYYYYYYYYYYYYYYYYYYYYYYYYYV90 IWU#9,*YYYYYYYYYYYYYYYYYYYYYYYYYYV90 9,*YYYYYYYYYYYYYYYYYYYYYYYYYYV909,*YYYYYYYYYYYYYYYYYYYYYYYYYYV909,*YYYYYYYYYYYYYYYYYYYYYYYYYYV9I3333333333333333333933333333J,*YYYYYYYYYYYYYYYYYYYYYYYYYYV333333333333333333333333333333*XYYYYYYYYYYYYYYYYYYYYYYYYYV   0YYYYYYYYYYYYYYYYYYYYYYYYYYYNIIIIIIIIIJIIIIIIIIIIIIIJIIIIIIIJQYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYbareos-Release-14.2.6/platforms/win32/bareostools.ico000066400000000000000000000314461263011562700224510ustar00rootroot00000000000000hF .0V=@((   ޹ҡeԥlԥlԥlԥlԥlԥlԥlԥkԥkԥlԥlҡe߽Ýٯ}˒LʑJʑJʑK˒M˒M˒L˓O˒L˒M˒Lٰ}ǣÞҢgx"ϛZݸ͗Tw!x!ą8Ü̕Qw x!ӣhǤÝԤkȍDݸʑK}*ͭǣ€0y#ӣiǤÝ׬wؾܷҡe{'޻ơ{'ӣiǤœڲҢfvŇ:М]ӣiǣÝӤkد{Ңfӷ޹֪tǣÞӣh{'ɎFƉ=Ğڳy#Ɖ>̕RӤjǣÝӣiy#y#w ˔OΙWx"y$x"ӣiǤÝӣiy$y$ȍE̕Qy$y$ӣiǤÝӤky#€/պО`Ň:x"ӤkƢвخ{ņ9y$حy˒Lw ΘW࿗}*ă5خ{ϰ࿖خ{ȌB{'ą7z$z%z%ȌC~+Ň:׬w޻Ǥ۴Ңfņ8z%x"y$Ã3Н_ڲ۴Ԧm͘VӤjڲ߽࿖ڱ߼xyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@  ww w!x!x"x#y#y#y$z$z%z&{&{'{'|(|)}*~,,-.€.€/01Á1Â3Ã4ă4Ą5Ą6Ņ8ņ8ņ9ņ:Ň:Ň;Ƈ;ƈ;NJ?NJ@NjAȌCȍDȍEɏHʐIʐJʑJʑKʑL˒L˒M˓N̔P̔Q̕Q̕R̖R̖S͖S͗T͗U͘VΘWΙWΙXΚYϚZϛ[ϛ\Ϝ\М]Н^Н_О`џaџbѠcҡeҡfҢfҢgӣhӤkӥkԥkԥlԥmԦnէpըqթr֩q֩s֪s֪t׫v׬w׬xحyخzٯ|ٰ~ڱڲڲڳ۵ܷܵܶݷݸݸݹ޺޻޻߻߼߽߽ྕ࿖›œÝşŠơơƢǣǤȥȦɧʧʨʩ˫̬ͭͮΰϱвѴҴҵҶӶӷӸԸԺպջּֽ׾ؿܿJGկqDM{}Q>dөc7glhqDMܲe7vD4vDM΃7l{. #e7eܼ[D4 #n[@ܻH_Y  7v/Mb4 7 )d#q>܀>/M ~#JvDbDq}WD7)#_wH)D>'eܿMg}#G>'bܿ}'D>'Y~'D>'Tр'H>#'ܬ'D>#l#I>'DD#VQ)#D>#YϵՀMܼDDܙ,D>'MӃ7ܴ܏+J>D܉4ӏ#D>DQDܵ#'D>,ܵTn}܉'J>'Gܔܧ)'D>#JMvyܵm#'G>#lՌ/ܻ)'D>'VĔ7܊'G>'/@v'D>#G>bQQQQQQQQQQQQQQQQQQQQQQbD4yw7,4(.`   ww z${'~,€/Ã4ņ9NJ?NjAȍEɏH˒L̕RΚZН^џaҡeԥl֩s׭xخzٱ۴ܷݹ߼ྕƢȦ˩ϰѴջ00000000000000000000+" )0000000000000000000000000000000000000/%  "-00000000000000000000000000000000- (( (/000000000000000000000000000*  $+($*($.00000000000000000000000*  )) &+$#/0000000000000000000- !+%  *('00000000000000000$ !+$ *(-0000000000000-*$ +$'00000000000)')#, !000000000( ," +"  0000000( +($ "00000-*  ($ )0000- /#0- */00* )/0/ 000-* )00"(0000-00000-("00" /00000+/000000-  # 00$/000000) .0000000"$ 00$.000000$ -0000000"$00$-000000'+0000000!$ 00$-0000000000000!$00$+00000000000 $ 00$*000000000 $ 00$.0000000 $00$0000000-$ 00$/00000000( $ 00$.0000000000$  $00$  -00000/+00000""-$ 00$ '0/*$ ,000000 #00000!00-$ 00$ $000000000000"0000/0000#$ 00$ $00000000000/ 0000.)-/000)$00$#00000000000/000000000)$ 00$*00000000000$/000000' $00$$0000-000000$(000000 $ 00$ 000)/0000+ )00000/$00$00)$0000/)0)/00000"$ 00$/*-00000 )00000000# $00$#-00000/000000*$$ 00$,00000/00000$ $ 00$+00000000000$00$#).000000$ $ 00$ !0$ $ 00$ $00$$ 00$$ 00$$$$ 00 )))))))))))))))))))))))))))))))))))))) 00   00 0(=  w z${'}*€/Â3ņ9Ɖ>NjAɎFɏHʒL͗T͘VϚZН^ўaҡeէn֪s׭xخ{ٰ۴ܶ޺߼ྕœƣɦͭίϱҵֽؿ3333333333333333333333333332)(23333333333333333333333333333333333333333333333333333," )233333333333333333333333333333333333333333333332&   ,3333333333333333333333333333333333333333330" #020%  (23333333333333333333333333333333333333,+30%#,30# #1333333333333333333333333333333333, %22& #02,"0333333333333333333333333333330  )20! '21##233333333333333333333333332" ,2+ #02((33333333333333333333333) ,2)02&/33333333333333333331 )2* 02#&33333333333333333+#2,!20233333333333333% /2 )3% 0333333333333" !2*2,03333333333" &2" ,1133333333% )1 *03333333+ )0++0%333332#22,23/0) 13333)2133) 0333/3%3333**03333%.33333/&- 333120333333!+333333302133/ 0 033333332 )3333333330 1 133, #,"3333333332 %33333333330,# 133, #+ $3333333330"3333333333/,# 033, #+ #333333333/3333333333/+# 133, $+"333333333*"2333333333.+# 133, #+3333333333333333333,,# 033, #+33333333333333333,+# 133, #,233333333333333,+# 133, #+2333333333333,,# 033, #+23333333333++# 133, #+ +3333333330+# 133, #+"3333333333,+$ 033, #,333333333333( +# 133, #+23333333333333$+# 033, #+2333333333333333  +# 133, #+  033333333/-3333333+3) +# 133, #+#332,%/33333333+*3333332 )333( +# 133, #+"3333333333333333+ )3333330%33333"+# 033, #+3333333333333333+ (333333,#233333,# 133, #+3333333333333333+ &333333223333333"+# 033, #+3333333333333333+ %3333333333333"+# 133, #+ 0333333333333333+ #3333333333++# 033, %++333333333333333%"333333333#+# 133, #+$333333/33333333, 233333333,# 133, #+33333#"33333331 333333331+# 033, #+3333% "3333333,3#%33333333"+# 133, #+033& 3333333+33333333333) +# 133, #+ +3) 03333333& +33333333333(,# 133, #+") /33333333%3333333320++# 133, #, ,33333333+"3333333*+# 033, #+,33333333+#3333332+# 133, #+ +33333333, %333333),# 133, #+ '0233333/ &33331+# 033, #+ $+2/ (332+# 133, #+  (0,# 133, #+ +# 033, #,+# 133, #++# 033, #+,# 133, #10# 133, "322222223223222222223222322222222223222222223223222" 133,   133,  033, 13bareos-Release-14.2.6/platforms/win32/bconsole.ico000066400000000000000000000314461263011562700217210ustar00rootroot00000000000000hF .0V=@((   ȜǛȝɝɝɞǚˢӒ<֙IҎ4Њ.Ћ.ь0١Vˡχ(’Ӓ<̓!́{ךJˡψ)ҭЫȜͥӒ;֙HЉ+Ȝӑ:㹁ܧa֘Gʱ˹˸˸˹˸˻ӲЉ*ͦ律wЫ؞Q֙Gãxӎ2ՖCۤ\ڤ[כK΃ ֜N)0$zCӏ5~zх!ɑF~\,789CCD iO-FŏFq?=-  ~~%  556>>>---jjj---        xyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@    ""##$   ! (,4 9$ >)?( &&&(((,,,F- U8Y;\<~PBBBEEEGGGIIINNNPPPSSSUUUWWWXXX\\\sdLeeekkkvvvwwwzzzd3h5i5p<pNx yyzzzz{|||}}~~~|̀͂΅$Ά%χ'χ(ψ)ψ*Ј*Њ-ы/э3Ҏ3Ҏ5Ґ7Ӑ7Ґ8ӑ:Ӓ;֖A֘G֙H֙I֚I֚JךJ՜O؞Rȝeɞfɟg١WۢVۤ[ۤ\ܣX͢iʦwɨ}Ңaܧaܩdݩeݪfݫh߮nԩp֫q֬tٯw߯p߰pݰtݰu߱tޱvߴzosqsttuxz~ǪƯɪɫɬɬɭ˰ȱɰɱ˱˱˲˲˲ʴɵ˴ȵɵʷ˷˹ȹɹʺȻȼ徊忋忌ºý‘ǚȝʠϳҺһӼӱԱԲغڼ۾ۿ9////////////////////////////9&+1 '*4$%22- 0ӏ.Ԏ  +-4)5oh5(7{^N^}|8 g]B:@:BWo!"zkF:BBBBB@Hky#JrlBB:@:@=::@:seU:kõuL:[xpqS:u:YS:]MNM]:Y}ʸS:S:::L?[׋S:SHHHS?[x׋S::Y׋S?P:Yx׋S:VFIIHB??Y}׋S:P??FB?B?Y}׋P:V`F??:???:X֍m``_``d`````uuj(.`     %',0:#=-###+++555<<<B'E)H+R2h? kC gHqG}K}PCCCMMM^^^dddhhhwwwxxxQXt+y3|2w y}{a|́΅$ψ*ć4=ԓ=ōDĐKɒIɖR͚Vʛ]כK؝O؞QסY١UڣZʢnʤtʧzɨ}רjܧaܩfެjҬv߰qt|Ŭƭɫɭưɲɵָ־ʷɹɼɿ伆律ûĔĕǚɜͤϨЩӰعٻvttttttttttttttttttttttttttttttttttttttttttttv   pM{{{{K KR    cOrOR sQ QQrQQ LQ K $CeC% p4fkJ>Jjf7" 4hh>.)&).>gi7! #`j=-&))))''-9hg% 3lI.&)))))))))'-Fl5 3l9)))))))))))))))9l1+NNNNNNNNNNNNNNNNNNNNN,0h=&)))))'))'))))))&>g(Wcbrbcccqqcccqbqc_qbqr\Fd}m=kT,,,,SQ,,,+Bv6Jc>Ih_Mh`L`dFLhMNi_Lc}MdiMMl}=nT,,,,S{4,,,Bx6Jf`}}}m}}}}}}}}}}}}m~hIf~m}}~m=nT+,,,Sr442244224C;,,+Bx5J}m}}}~}}}}}}}}}}}}}}}l}}}}}}m=nT+,,,Sp,,,,,,,,,:<+,+Bx6Ibbbbbbbbbbbbbbbbbbbbbbbbbbbbb8oT,,,,Tp,,,,,,,,,5<+,,Ax6BnT,,,,Sp,,,,,,,,,5<,,+Bx5HkT,,,,Sp,,,,,,,,,5<+,+Bx5HkT,,,,Tp,,,+,,,,+;<,,+Bv:HnT+,,,TxSRRSRSRQTs:,,+Bv6HkT+,,,Tq,,,,Bx6HkT+,,,Tv;,,,,Ax6HkT+,,,TjkkjkkjkkUH6,,,,+Bx6HnT,,,,Tp,,,,,,,,,,,,,,,,+Ax6HkT+,,+Tq,,,,,,,,-,,,,,,,+Bx6HkT,,,+Tp,,,,,,,,,,,,,,,,+Bx6HnT+,,,Tp,,,,,,,,,,,,,,,,,Bx6HkT+,,,@jkC,,,,,,,,,,,,,,,,+Bx6HkT+,,,,,,,,,,,,,,,,,,,,,,,+Bx6HnT+,,++,,,,++,+,,,+,,,,,,,+@x6HnvUUUUUUUUjUUUUUjUUUUUUUUUUr6GDoooooooooookooooooookooookoT-S;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bareos-Release-14.2.6/platforms/win32/bsmtp.ico000066400000000000000000000314461263011562700212420ustar00rootroot00000000000000hF .0V=@((   rՕAzҎ5մɟψ*z|z̈́$Õ{ϖL̑H̒H͒H͒I̒HϕK߲v٠S}̑H͗UΙXz%{'}*̒I~ٟSѬҐ8y~ˏDԥlήڱٰ~Ɗ?ˏE~yӒ;ճ͂y{~ˏEӥl޻˒M۵׭xʎC~{y΅#ޭlЊ-z~ˏEӤkÝџb߼֪sʎC~zь0߮n׷ӱ΄#|͒InjCԧnէpӣhņ9̒I|Ά%ֵֵ׷ˡ́̇-̒K0x!.˒K̉1͂ͥմ׷ÔʀԞYནӝYˁ"̀Ƙմ׷ެjכK֙H߯oճ׷ѭɝȜӯճ׷ĕع׷ĖճwŗŖuלNŗΧͥͥͥͥͥͥͥͥͥΨĕכLxyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@  vw y#y{~{'}*́̃#χ)Ã4Ɖ>Ɇ1ˈ2Њ-Ҏ4Ӓ<ˎCΓGʑK̖SΚYՖC֘FכK؝OИRҞ\؞QОa١VڣZԡbԦlܧaܨdޭl֩s߰qvy߻伆律ྕÓŖƘɟǣȦˢϩѬӴֻٻ    %=A@@@@@@@@@@@@@@A@@@@@A@A> $BIIIIIIIIIIIIIIIIIIIIII@ $E*8HIIIIIIIIIIIIIIIIIIH6-D #HI9)EIIIIIIIIIIIIIIIID(;IH #HIIB%=IIIIIIIIIIIIII;%DIIH $HIIIG2/GIIIIIIIIIIG,6HIIIH #HIIIII?$AIIIIIIII? @IIIIIG #HIIIIIID7HIIIIH6EIIIIIIH $HIIIIII-(EIIC%1IIIIIIH #HIIIII1!BB!3IIIIIH #HIIII6!&"& 8IIIIH $HIII9 & "" ;IIIH #HII;!& =IIH#$HI?"@IH I@&999994 BH $A5E5555D: !B 5:+? !5<+@ 5@"&"&<< =4GBBBB?"!@IE%4<  (FIIIG0 4< 2GIIIIII;  !9IIIIIIIIIA&!&@IIIIIIIIIIIF) %EIIIIIIIIIIIIIH6 /GIIIIIIIIIIIIIIII<8IIIIIIIIIIIIIIIIIIIC#?IIIIIIIIIIIIIIIIIIIIIF,$DIIIIIIIIIIIIIIIIIIIIIIII8,GIIIIIIIIIIIIIIIIIIIIIIIIII?9HIIIIIIIIIIIII(.`   ww y$y{{$~+́ƀ%Á.΄#Ȅ,ψ)Â3ņ9Ɖ?ȇ6̉3ˌ;Њ-Ҏ4Ӓ;NjBɎEɏH˒M̖SΚYՖB֘FךJѝ\؟Rџb١WڣZԥkܧaܩdޭk֪t׬x߯pحy߰rٰuz۴ܷ޺߼㺄律ྖ’ŗƙɞή̤ϬѬԴԹظ۾,%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$%%%%%%%%%%%%%%0),,,,,..,,,,),,,,,..,,,,),,,,0,,),,,,,),0) 8RVVUVUVVVVVVVVVVVUVVVVVVVUVVVVVVVVVVVVVQ1   "KVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVG  G?=TVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVS8CF KVK% 'MVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVK$ 'LVG KVVS8AUVVVVVVVVVVVVVVVVVVVVVVVVVVU==TVVJ KVVVUG 0OVVVVVVVVVVVVVVVVVVVVVVVVM( $JVVVVG KVVVVVR1 FUVVVVVVVVVVVVVVVVVVVVUC 8SVVVVVG KVVVVVVUF7RVVVVVVVVVVVVVVVVVVQ0 GUVVVVVVJ KVVVVVVVVN) JUVVVVVVVVVVVVVVUF 0RVVVVVVVVJ KVVVVVVVVVUA:SVVVVVVVVVVVVS8CUVVVVVVVVVG KVVVVVVVVVVVK%KVVVVVVVVVVJ"NVVVVVVVVVVVJ KVVVVVVVVVVVD?UVVVVVVS=GVVVVVVVVVVVJ KVVVVVVVVVVF )NVVVVL%JVVVVVVVVVVJ KVVVVVVVVVJDVV@KVVVVVVVVVJ KVVVVVVVVI 9E@<&LVVVVVVVVJ KVVVVVVVL &<3 *93 NVVVVVVVJ KVVVVVVM<- #<- $QVVVVVVJ KVVVVVO  35+6%RVVVVVJ KVVVVR% 3+6(SVVVVJ KVVVR'&/&/,SVVVJ KVVS)56 1TVVJ KVT0 63PPPPPPPPP@6 7UVJ KU1 56VRKLLLLLSV<5  8UK J8 55V<*UI5  =G %  65V6UL5  (  56V6UK5   65V6UI4   66VH343434EVH5  %N(  66VVVVVVVVVP&5  2SVT:  66VH333334/5 ?UVVVVD 86V65 JVVVVVVVL% 66V65 'NVVVVVVVVVS7  5+K-5  7SVVVVVVVVVVVUC55 CUVVVVVVVVVVVVVVK"<<  JVVVVVVVVVVVVVVVVVR0 +544444444444444445/(OVVVVVVVVVVVVVVVVVVVU? :UVVVVVVVVVVVVVVVVVVVVVVF CUVVVVVVVVVVVVVVVVVVVVVVVVO)"KVVVVVVVVVVVVVVVVVVVVVVVVVVVT;)QVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVF:UVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVM%DUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVS8 "KVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUC0RVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVK%=UVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVSNVVVVVVVVVVVVVVVVVVVVVV(=  vw!y$zyy{}%~,́À,΅%χ(ψ)ă4ņ9Lj;Ό5Њ-э3Ґ7Ӓ<NjAɏFʑL͖S͘VΚY՗D֘FכK؝O֞UН^؞QОa٠Uڤ[Ңgԥmۧaܩdޭk֪u׭y߯pٯ}߰qٱuyڳݹ޼仄徉ྕқŗƙɝƤȦ̫̤άϰѬԴֽعڼ=33333333333333333333333333333333333333333333333333333333333?   3MNNNNNNNNNNNNLNNNNNNNNNNNLNNNNNNNNNNNLNNNNNNNNNNNNNNNNJ+  7W[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[T3  #M[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZG 3F;X[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[W8 I+7[R+&O[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[M% 3V[37[[Y?CZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[X;FZ[[27[[[[N& 2S[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[P*+R[[[Z27[[[[[X:GZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZC>X[[[[[27[[[[[[ZJ 3W[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[T2 &O[[[[[[Z27[[[[[[[[V3 #M[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZG 8W[[[[[[[[27[[[[[[[[[ZF;X[[[[[[[[[[[[[[[[[[[[[[[[[W7 JZ[[[[[[[[[27[[[[[[[[[[[S+*O[[[[[[[[[[[[[[[[[[[[[[[M% 3T[[[[[[[[[[[27[[[[[[[[[[[[Y?CY[[[[[[[[[[[[[[[[[[[X;FZ[[[[[[[[[[[Z37[[[[[[[[[[[[[[O& .S[[[[[[[[[[[[[[[[[P& *R[[[[[[[[[[[[[[37[[[[[[[[[[[[[[[X8 IZ[[[[[[[[[[[[[ZC >Y[[[[[[[[[[[[[[Z37[[[[[[[[[[[[[[[[C  3W[[[[[[[[[[[S2  G[[[[[[[[[[[[[[[[37[[[[[[[[[[[[[[ZF MZ[[[[[[[ZGM[[[[[[[[[[[[[[[37[[[[[[[[[[[[[[J;X[[[[[W8 N[[[[[[[[[[[[[Z37[[[[[[[[[[[[[M)O[[[L!P[[[[[[[[[[[[[27[[[[[[[[[[[[N -WYU4 S[[[[[[[[[[[[37[[[[[[[[[[[P,BB/(@E6%T[[[[[[[[[[[37[[[[[[[[[[S 4E<4E@&W[[[[[[[[[[37[[[[[[[[[T% ,E<,E<*X[[[[[[[[[37[[[[[[[[W)<@4E(2X[[[[[[[[37[[[[[[[X+E4B43Y[[[[[[[37[[[[[[X2G' B, 8Y[[[[[[37[[[[[Y7 A,G ;Z[[[[[37[[[[Z8 $@ 51 >Z[[[[37[[[Z; 44$,,,,,,,,,,($(6 CZ[[[37[[Z? 14 K[[Z[[Z[[[ZZZP"'6G[[[37[ZC 14 K[[XXXXXYXXY[[L'6I[[37[G11 K[Q'$K[X'6M[37J14 K[L4[Z''6N3#14 K[P/[Z''6%14 K[P/[Z''614 K[L/[Z''6/4 K[P6[Z$'6 +/4K[WB@AA@@@@EU[U'6 8W7 /4K[[[[[[[[[[[[[@ '6CZ[ZC/4K[ZQPPQPQPPPL5'6J[[[[[N 44K[P'6)R[[[[[[[V0 44K[L'6 7W[[[[[[[[[Y=14K[L '6CZ[[[[[[[[[[[ZJ14 K[L  '6JZ[[[[[[[[[[[[[[S*14,5- '6*S[[[[[[[[[[[[[[[[[X8 44'6 3X[[[[[[[[[[[[[[[[[[[ZF44  (6CZ[[[[[[[[[[[[[[[[[[[[[[O%-KA@@@@@@AABAAB@@@@@@@@@AH6M[[[[[[[[[[[[[[[[[[[[[[[[[W3 )S[[[[[[[[[[[[[[[[[[[[[[[[[[[Z? 7X[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[MCZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[S+ M[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[X;*S[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZI 8X[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[P&DZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[X7 M[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[YD +T[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[N# 8X[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[V2 FZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Y> N[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZJ*3T[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZZ[[[[[[[[[[[[[[[[[[[[[[[[[[[[[bareos-Release-14.2.6/platforms/win32/clientdialog.ini000066400000000000000000000026401263011562700225520ustar00rootroot00000000000000;Ini file generated by the HM NIS Edit IO designer. [Settings] NumFields=16 [Field 1] Type=Groupbox Text=Configuration of the Bareos Client Left=0 Right=300 Top=0 Bottom=140 [Field 2] Type=Text Left=100 Right=295 Top=11 Bottom=24 Text=ClientName [Field 3] Type=Text Text=DirectorHostName Left=100 Right=290 Top=43 Bottom=56 [Field 4] Type=Text Text=DirectorClientPassword Left=100 Right=290 Top=57 Bottom=70 [Field 14] Type=Text Text=client monitor password Left=101 Right=291 Top=104 Bottom=116 [Field 6] Type=Groupbox Text=Parameters for Monitor connecting to this client Left=4 Right=295 Top=92 Bottom=125 [Field 7] Type=Groupbox Text=Parameters for Director connecting to this client Left=4 Right=295 Top=28 Bottom=91 [Field 8] Type=Label Left=17 Right=20 Top=60 Bottom=62 [Field 9] Type=Label Text=Director Name Left=10 Right=72 Top=45 Bottom=53 [Field 10] Type=Label Text=Network Address Left=10 Right=98 Top=73 Bottom=81 [Field 11] Type=Label Text=Password Left=10 Right=90 Top=59 Bottom=67 [Field 12] Type=Label Text=Client Monitor Password Left=10 Right=90 Top=108 Bottom=116 [Field 13] Type=Label Text=Client Name Left=10 Right=86 Top=12 Bottom=20 [Field 5] Type=Text Left=100 Right=290 Top=71 Bottom=84 [Field 15] Type=Label Text=Bacula compatibility Left=10 Right=90 Top=128 Bottom=136 [Field 16] Type=Checkbox Text=compatible (new bareos features cannot be used) Left=100 Right=290 Top=128 Bottom=136 State=1 bareos-Release-14.2.6/platforms/win32/databasedialog.ini000066400000000000000000000022471263011562700230430ustar00rootroot00000000000000; Ini file generated by the HM NIS Edit IO designer. [Settings] NumFields=14 [Field 1] Type=Groupbox Text=Bareos Director Database Connection Left=0 Right=299 Top=71 Bottom=114 [Field 2] Type=Groupbox Text=Administrative DB Account to setup Bareos Database Left=0 Right=299 Top=0 Bottom=70 [Field 3] Type=Text State=DB Admin Username Left=98 Right=295 Top=9 Bottom=22 [Field 4] Type=Text State=DB Admin Password Left=98 Right=295 Top=25 Bottom=38 [Field 5] Type=Text State=DB User Left=41 Right=152 Top=82 Bottom=95 [Field 6] Type=Text State=DB Password Left=41 Right=152 Top=96 Bottom=109 [Field 7] Type=Text State=DB Name Left=180 Right=294 Top=80 Bottom=93 [Field 8] Type=Text Flags=ONLY_NUMBERS State=DB Port Left=180 Right=294 Top=96 Bottom=109 [Field 9] Type=Label Text=Password Left=6 Right=40 Top=98 Bottom=106 [Field 10] Type=Label Text=Port Left=158 Right=171 Top=98 Bottom=106 [Field 11] Type=Label Text=User Left=6 Right=38 Top=84 Bottom=92 [Field 12] Type=Label Text=Name Left=158 Right=176 Top=83 Bottom=91 [Field 13] Type=Label Text=DB Admin Username Left=9 Right=74 Top=11 Bottom=19 [Field 14] Type=Label Text=DB Admin Password Left=9 Right=73 Top=25 Bottom=33 bareos-Release-14.2.6/platforms/win32/directordialog.ini000066400000000000000000000010321263011562700231010ustar00rootroot00000000000000; Ini file generated by the HM NIS Edit IO designer. [Settings] NumFields=5 [Field 1] Type=Groupbox Text=Configuration to access the Bareos Director ( for bconsole and BAT ) Left=0 Right=299 Top=0 Bottom=51 [Field 2] Type=Text State=Director Network Address Left=98 Right=295 Top=12 Bottom=25 [Field 3] Type=Text State=Director Password Left=98 Right=295 Top=28 Bottom=41 [Field 4] Type=Label Text=Director Password Left=9 Right=98 Top=30 Bottom=38 [Field 5] Type=Label Text=Director Network Address Left=9 Right=98 Top=14 Bottom=22 bareos-Release-14.2.6/platforms/win32/fillup.sed000066400000000000000000000024401263011562700214010ustar00rootroot00000000000000s#@basename@#XXX_REPLACE_WITH_BASENAME_XXX#g s#@hostname@#XXX_REPLACE_WITH_HOSTNAME_XXX#g s#@mon_dir_password@#XXX_REPLACE_WITH_DIRECTOR_MONITOR_PASSWORD_XXX#g s#@mon_fd_password@#XXX_REPLACE_WITH_CLIENT_MONITOR_PASSWORD_XXX#g s#@mon_sd_password@#XXX_REPLACE_WITH_SD_MONITOR_PASSWORD_XXX#g s#@fd_password@#XXX_REPLACE_WITH_CLIENT_PASSWORD_XXX#g s#@dir_password@#XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX#g s#@sd_password@#XXX_REPLACE_WITH_STORAGE_PASSWORD_XXX#g s#@dir_port@#9101#g s#@fd_port@#9102#g s#@sd_port@#9103#g s#@plugindir@#"C:/Program Files/Bareos/Plugins"#g s#@archivedir@#C:/bareos-storage#g s#@scriptdir@#C:/Program Files/Bareos#g s#@working_dir@#C:/ProgramData/Bareos/working#g s#@logdir@#C:/ProgramData/Bareos/logs#g s#@sbindir@#C:/Program Files/Bareos#g s#@bindir@#C:/Program Files/Bareos#g s#@sysconfdir@#C:/ProgramData/Bareos#g s/@uncomment_dbi/#/g s#@db_name@#bareos#g s#@db_user@#bareos#g s#/tmp/bareos-restores#"C:/temp/bareos-restores"#g s#@db_password@#XXX_REPLACE_WITH_DB_PASSWORD_XXX#g s#@smtp_host@#XXX_REPLACE_WITH_SMTP_HOST_XXX#g s#@job_email@#XXX_REPLACE_WITH_JOB_EMAIL_XXX#g s#@DEFAULT_DB_TYPE@#XXX_REPLACE_WITH_DEFAULT_DB_TYPE_XXX#g s#@db_port@#XXX_REPLACE_WITH_DB_PORT_XXX#g # ddl sql files s#@DB_PASS@#XXX_REPLACE_WITH_DB_PASSWORD_XXX#g s#@DB_USER@#XXX_REPLACE_WITH_DB_USER_XXX#g bareos-Release-14.2.6/platforms/win32/mingw-debugsrc-devel.spec000066400000000000000000000033551263011562700243050ustar00rootroot00000000000000# # spec file for package mingw-debugsrc-devel # # Copyright (c) 2014-2015 Bareos GmbH & Co. KG # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.bareos.org # #!BuildIgnore: post-build-checks Name: mingw-debugsrc-devel Version: 14.2.6 Release: 0 Summary: bareos License: LGPLv2+ Group: Development/Libraries URL: http://bareos.org Source0: bareos-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch Provides: %name = %version %description %package postvista Summary: postvista %package postvista-debug Summary: postvista-debug %package prevista Summary: prevista %package prevista-debug Summary: prevista-debug %description postvista %description postvista-debug %description prevista %description prevista-debug %prep %setup -q -n bareos-%{version} %build %install cp -av ../bareos-* $RPM_BUILD_ROOT/ %post %postun %files %defattr(-,root,root) /bareos-* %files postvista %defattr(-,root,root) /bareos-* %files postvista-debug %defattr(-,root,root) /bareos-* %files prevista %defattr(-,root,root) /bareos-* %files prevista-debug %defattr(-,root,root) /bareos-* %changelog bareos-Release-14.2.6/platforms/win32/storagedialog.ini000066400000000000000000000023611263011562700227400ustar00rootroot00000000000000;Ini file generated by the HM NIS Edit IO designer. [Settings] NumFields=14 [Field 1] Type=Groupbox Text=Configuration of the Bareos Storage Daemon Left=0 Right=300 Top=0 Bottom=132 [Field 2] Type=Text Left=100 Right=295 Top=11 Bottom=24 Text=StorageName [Field 3] Type=Text Text=DirectorHostName Left=100 Right=290 Top=43 Bottom=56 [Field 4] Type=Text Text=DirectorStoragePassword Left=100 Right=290 Top=57 Bottom=70 [Field 14] Type=Text Text=Storage monitor password Left=101 Right=291 Top=104 Bottom=116 [Field 6] Type=Groupbox Text=Parameters for Monitor connecting to this Storage Daemon Left=4 Right=295 Top=92 Bottom=125 [Field 7] Type=Groupbox Text=Parameters for Director connecting to this Storage Daemon Left=4 Right=295 Top=28 Bottom=91 [Field 8] Type=Label Left=17 Right=20 Top=60 Bottom=62 [Field 9] Type=Label Text=Director Name Left=10 Right=72 Top=45 Bottom=53 [Field 10] Type=Label Text=Network Address Left=10 Right=98 Top=73 Bottom=81 [Field 11] Type=Label Text=Password Left=10 Right=90 Top=59 Bottom=67 [Field 12] Type=Label Text=Storage Monitor Password Left=10 Right=95 Top=108 Bottom=116 [Field 13] Type=Label Text=Storage Daemon Name Left=10 Right=86 Top=12 Bottom=20 [Field 5] Type=Text Left=100 Right=290 Top=71 Bottom=84 bareos-Release-14.2.6/platforms/win32/tray-monitor-conf-fd-sd.patch000066400000000000000000000012671263011562700250220ustar00rootroot00000000000000diff -ruN bareos-13.4.0.git.1383814247.orig/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in bareos-13.4.0.git.1383814247/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in --- bareos-13.4.0.git.1383814247.orig/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in 2013-11-07 12:57:00.625086539 +0100 +++ bareos-13.4.0.git.1383814247/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in 2013-11-07 13:06:42.082575296 +0100 @@ -22,8 +22,8 @@ Password = "@mon_sd_password@" # password for StorageDaemon } -Director { - Name = @basename@-dir - DIRport = @dir_port@ - address = @hostname@ -} +#Director { +# Name = @basename@-dir +# DIRport = @dir_port@ +# address = @hostname@ +#} bareos-Release-14.2.6/platforms/win32/tray-monitor-conf.patch000066400000000000000000000016711263011562700240260ustar00rootroot00000000000000diff -ruN bareos-12.11.orig/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in bareos-12.11/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in --- bareos-12.11.orig/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in 2012-11-12 11:28:21.000000000 +0100 +++ bareos-12.11/src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in 2012-11-17 00:59:17.000000000 +0100 @@ -15,15 +15,15 @@ Password = "@mon_fd_password@" # password for FileDaemon } -Storage { - Name = @basename@-sd - Address = @hostname@ - SDPort = @sd_port@ - Password = "@mon_sd_password@" # password for StorageDaemon -} - -Director { - Name = @basename@-dir - DIRport = @dir_port@ - address = @hostname@ -} +#Storage { +# Name = @basename@-sd +# Address = @hostname@ +# SDPort = @sd_port@ +# Password = "@mon_sd_password@" # password for StorageDaemon +#} +# +#Director { +# Name = @basename@-dir +# DIRport = @dir_port@ +# address = @hostname@ +#} bareos-Release-14.2.6/platforms/win32/traymon.ico000066400000000000000000000314461263011562700216060ustar00rootroot00000000000000hF .0V=@((   ޹ҡeԥlԥlԥlԥlԥkӤjӤjԥkԥlԥlԥlҡe߽Ýٯ}˒L˒M˒MʑK͗UѠcϜ\˒MʑK˒M˒Lٰ}ǣÞӢhx!x"|'ըpѴ׽ּ࿖Ɖ>w!x!ӣhǤÝӣiy${'ݹ׽ҢfNJ?ʑJ߼ջȌBx"ӣiǤÝӣix!Ϝ\պ֫t֪tvvw!ܶŠ{&ӣiǤÝӣiy#š׫vӣiؿٯ}ٱԦmȍCԸNjAӢhǤÝӣi|(ί͖SӤj׾ٯ}ٰ}պӤjʨΘVҢgǤÝӣi{&˪ϛ[ӥk߽w!w ޺د|̬̔PҢgǤÝӣix!۴߽ҢfơƢֻ۴ӶÃ4ӣhǤÝӣix!ɏGخz̖R̔P̕QН_Ҷخzx"ӣiǤÝӤj~+œǣٰ~޺׾ݹ~+y#ӤkƢг׬wΙW׬vݸ͗U{'x"Ą5خ{ϰϰ֩rw x"x"x"x"x"ƈ;׬w޻ؿҢgņ9z%x"y$Ą5О`ڲ۴Ԧm͘VӤjڲ߽࿖ڱ߼xyz{|}~ijklmnopqrstuvwZ[\]^_`abcdefghKLMNOPQRSTUVWXY<=>?@ABCDEFGHIJ-./0123456789:; !"#$%&'()*+, (@  vww w w!x!x"y#y#y$z$z%z&{&{'{'|(|)})}*}+~+~,-.€.€/€00Â3Ã4ă4Ą5ą7Ņ8ņ8ņ9ņ:Ň:Ň;Ƈ;ƈ;ň<Ɖ=Ɖ>NJ?NJ@Nj@NjAȌBȌDȍDɎFɎGɏGɏHɐHʐJʑJʑK˒L˒M˒N˓N˔O̔P̔Q̕Q̕R̖R̖S͖S͗T͗U͘VΘWΙXΚYϚZϛ[ϛ\Ϝ]Н^Н_О_џaџbѠdҡdҡeҡfҢfҢgӤjӤkӥkԥkԥlԦmԧoէoըpըq֩r֩s֪s֪t׫v׬w׬xحyخzخ{ٯ|ٰ}ٰ~ڱڲڳ۴۴۵۵ܷܵݷݸݸݹݺ޺޺޺޻޻߻߼߽ྕ࿗š›œÝĞğŠơƢơƢǢǣǤȥȦʨ˪˫̬ͬͭίϰϱбвҵҶӷӸԸԺպջּֽ׾֚RPǸ}HVZHmlHqvq~NVoBNNjAɎFɏHʒL͗TΘWΚZН^ўaҡeէnէp֩s׭xخ{ٰ~۳ܷ޺߽ྕœŢȦ̫ίϱҵּؿ55555552+555555555555555554,+35555555555555555555555555555555551255555555555555.$ +455555555555555555555555555555.!4!455555555554)   !.55555555555555555555555555,$553'555555552$ $242'  *45555555555555555555555+&5555,.55555.  .42'$142' %35555555555555555555((555555$455. '44* $14. $35555555555555555&*55555554$1  +42! *44&%45555555555555%-555555555-  .4- #24**555555555555!45555555555$.4+ 14(255555555552 555555555554, 24%(55555555552!5555555555.#42 45555555551$5555555555(+5' 2555555555-'5555555555 4.2555555555+)5555555552.3355555555' +555555555+,34555555- -555555555,2(555554$%.5555555521+ 35555+4 255555555-   5'5555,,255555555"$+2232.+! (. 55534355555554%255555555555. 43551 2 4555555$$45555555555555552  3 255. %.55553-55555.' !'255555*.% 355. %-55335553'  *5555..% 355. %-$44555*-5552-% 355. %-3554!  %555.-% 355. %-.554"555* .% 255. %-'555$555-% 355. &-555% +552-% 355. %-*550'5555555555555552455!-% 255. %-455'55555555555555554$552 .% 355. %-$551 '55,!!!!!!!!!!%255'355-% 355. %- .55#'5555-)55'.% 355. %-455'55550 55. -% 355. %-552 '55451 453-% 255. %- 55,'55450  255-% 355. %.$55('55451  .55.% 355. %-%55''5555. ,55-% 355. %-%55'&5555.,55-% 355. %-#55*'55+"155' .55.% 255. %-55-'55555555555555555 254-% 355. %,554'5555555555555552552-% 355. %-355'55+ 55--% 255. '-+55''55 -55"-% 355. %-553'55554.% 355. %-355%'55*55--% 255. %-%554'55555-% 355. %.255- %44255, -% 355. %-555(    -554-% 355. %- *555( +555!-% 355. %--555+.555' -% 255. %--5552 $3555* -% 355. '-+55551$  %25555& .% 355. %- %4555552,(()-2555552-% 355. %.+555555555555554'-% 255. %- '25555555551$.% 355. %- %(*'$ -% 355. '--% 355. %--% 255. %--% 355. %33% 355. $544444444444544444444445444444444444444444444445444$ 255.   355.  355. 25bareos-Release-14.2.6/platforms/win32/winbareos-nsi.spec000066400000000000000000000151041263011562700230460ustar00rootroot00000000000000%define __strip %{_mingw64_strip} %define __objdump %{_mingw64_objdump} %define _use_internal_dependency_generator 0 %define __find_requires %{_mingw64_findrequires} %define __find_provides %{_mingw64_findprovides} %define __os_install_post %{_mingw64_debug_install_post} \ %{_mingw64_install_post} # If versionstring contains debug, enable debug during build %define WIN_DEBUG %(echo %version | grep debug >/dev/null 2>&1 && echo "yes" || echo "no") #!BuildIgnore: post-build-checks Name: winbareos-nsi Version: 14.2.6 Release: 0 Summary: bareos License: LGPLv2+ Group: Development/Libraries URL: http://bareos.org BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch %define addonsdir /bareos-addons/ BuildRequires: bareos-addons %define SIGNCERT ia.p12 %define SIGNPWFILE signpassword BuildRequires: mingw32-filesystem BuildRequires: mingw64-filesystem BuildRequires: mingw64-cross-nsis BuildRequires: mingw32-openssl BuildRequires: mingw64-openssl BuildRequires: mingw32-libopenssl BuildRequires: mingw64-libopenssl BuildRequires: mingw32-sed BuildRequires: mingw64-sed BuildRequires: sed BuildRequires: vim, procps, bc BuildRequires: mingw32-winbareos-prevista = %{version} BuildRequires: mingw64-winbareos-prevista = %{version} BuildRequires: mingw32-winbareos-postvista = %{version} BuildRequires: mingw64-winbareos-postvista = %{version} BuildRequires: mingw32-winbareos-prevista-debug = %{version} BuildRequires: mingw64-winbareos-prevista-debug = %{version} BuildRequires: mingw32-winbareos-postvista-debug = %{version} BuildRequires: mingw64-winbareos-postvista-debug = %{version} BuildRequires: mingw-debugsrc-devel = %{version} BuildRequires: mingw32-libgcc BuildRequires: mingw64-libgcc BuildRequires: mingw32-readline BuildRequires: mingw64-readline BuildRequires: mingw32-libstdc++ BuildRequires: mingw64-libstdc++ BuildRequires: mingw32-pthreads BuildRequires: mingw64-pthreads BuildRequires: mingw32-libqt4 BuildRequires: mingw64-libqt4 BuildRequires: mingw32-lzo BuildRequires: mingw64-lzo BuildRequires: mingw32-libfastlz BuildRequires: mingw64-libfastlz BuildRequires: osslsigncode BuildRequires: obs-name-resolution-settings Source1: winbareos.nsi Source2: clientdialog.ini Source3: directordialog.ini Source4: storagedialog.ini Source6: bareos.ico Source9: databasedialog.ini %define NSISDLLS KillProcWMI.dll AccessControl.dll LogEx.dll %description bareos %package devel Summary: bareos Group: Development/Libraries %description devel bareos #{_mingw32_debug_package} %prep # unpack addons for i in `ls %addonsdir`; do tar xvf %addonsdir/$i done %build for flavor in postvista postvista-debug prevista prevista-debug; do mkdir -p $RPM_BUILD_ROOT/$flavor/nsisplugins for dll in %NSISDLLS; do cp $dll $RPM_BUILD_ROOT/$flavor/nsisplugins done for BITS in 32 64; do mkdir -p $RPM_BUILD_ROOT/$flavor/release${BITS} # copy the sql ddls over cp -av /etc/$flavor/mingw${BITS}-winbareos/ddl $RPM_BUILD_ROOT/$flavor/release${BITS} # copy the sources over if we create debug package WIN_DEBUG=$(echo $flavor | grep debug >/dev/null && echo yes || echo no) if [ "$WIN_DEBUG" == "yes" ]; then cp -av /bareos* $RPM_BUILD_ROOT/$flavor/release${BITS} fi done for file in \ bareos-fd.exe \ bareos-sd.exe \ bareos-dir.exe \ bareos-dbcheck.exe \ bconsole.exe \ bsmtp.exe \ btape.exe \ bls.exe \ bextract.exe \ bareos-tray-monitor.exe \ bat.exe \ bpipe-fd.dll \ mssqlvdi-fd.dll \ autoxflate-sd.dll \ libbareos.dll \ libbareosfind.dll \ libbareoslmdb.dll \ libbareoscats-postgresql.dll libbareoscats-sqlite3.dll libbareoscats.dll\ libbareossd.dll ; do cp %{_mingw32_bindir}/$flavor/$file $RPM_BUILD_ROOT/$flavor/release32 cp %{_mingw64_bindir}/$flavor/$file $RPM_BUILD_ROOT/$flavor/release64 osslsigncode verify -in $RPM_BUILD_ROOT/$flavor/release32/$file osslsigncode verify -in $RPM_BUILD_ROOT/$flavor/release64/$file done for file in \ libcrypto-*.dll \ libgcc_s_*-1.dll \ libhistory6.dll \ libreadline6.dll \ libssl-*.dll \ libstdc++-6.dll \ libtermcap-0.dll \ pthreadGCE2.dll \ zlib1.dll \ QtCore4.dll \ QtGui4.dll \ liblzo2-2.dll \ libfastlz.dll \ libpng*.dll \ openssl.exe \ sed.exe; do cp %{_mingw32_bindir}/$file $RPM_BUILD_ROOT/$flavor/release32 cp %{_mingw64_bindir}/$file $RPM_BUILD_ROOT/$flavor/release64 done for BITS in 32 64; do for cfg in /etc/$flavor/mingw${BITS}-winbareos/*.conf; do cp $cfg $RPM_BUILD_ROOT/$flavor/release${BITS} done cp %SOURCE1 %SOURCE2 %SOURCE3 %SOURCE4 %SOURCE6 %SOURCE9 \ %_sourcedir/LICENSE $RPM_BUILD_ROOT/$flavor/release${BITS} makensis -DVERSION=%version -DPRODUCT_VERSION=%version-%release -DBIT_WIDTH=${BITS} \ -DWIN_DEBUG=${WIN_DEBUG} $RPM_BUILD_ROOT/$flavor/release${BITS}/winbareos.nsi done done %install for flavor in postvista postvista-debug prevista prevista-debug; do mkdir -p $RPM_BUILD_ROOT%{_mingw32_bindir} mkdir -p $RPM_BUILD_ROOT%{_mingw64_bindir} FLAVOR=`echo "%name" | sed 's/winbareos-nsi-//g'` DESCRIPTION="Bareos installer version %version" URL="http://www.bareos.com" for BITS in 32 64; do cp $RPM_BUILD_ROOT/$flavor/release${BITS}/Bareos*.exe \ $RPM_BUILD_ROOT/winbareos-%version-$flavor-${BITS}-bit-r%release-unsigned.exe osslsigncode sign \ -pkcs12 %SIGNCERT \ -readpass %SIGNPWFILE \ -n "${DESCRIPTION}" \ -i http://www.bareos.com/ \ -t http://timestamp.comodoca.com/authenticode \ -in $RPM_BUILD_ROOT/winbareos-%version-$flavor-${BITS}-bit-r%release-unsigned.exe \ -out $RPM_BUILD_ROOT/winbareos-%version-$flavor-${BITS}-bit-r%release.exe osslsigncode verify -in $RPM_BUILD_ROOT/winbareos-%version-$flavor-${BITS}-bit-r%release.exe rm $RPM_BUILD_ROOT/winbareos-%version-$flavor-${BITS}-bit-r%release-unsigned.exe rm -R $RPM_BUILD_ROOT/$flavor/release${BITS} done rm -R $RPM_BUILD_ROOT/$flavor/nsisplugins done %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) /winbareos-*.exe #{_mingw32_bindir} #{_mingw64_bindir} %changelog bareos-Release-14.2.6/platforms/win32/winbareos.nsi000066400000000000000000001764071263011562700221340ustar00rootroot00000000000000; ; BAREOS?? - Backup Archiving REcovery Open Sourced ; ; Copyright (C) 2012-2014 Bareos GmbH & Co. KG ; ; This program is Free Software; you can redistribute it and/or ; modify it under the terms of version three of the GNU Affero General Public ; License as published by the Free Software Foundation and included ; in the file LICENSE. ; ; 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 ; Affero General Public License for more details. ; ; You should have received a copy of the GNU Affero General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ; 02110-1301, USA. RequestExecutionLevel admin !addplugindir ../nsisplugins #SilentInstall silentlog BrandingText "Bareos Installer" ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Bareos" #!define PRODUCT_VERSION "1.0" !define PRODUCT_PUBLISHER "Bareos GmbH & Co.KG" !define PRODUCT_WEB_SITE "http://www.bareos.com" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\bareos-fd.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" SetCompressor lzma # variable definitions Var LocalHostAddress Var HostName # Config Parameters Dialog # Needed for Configuring client config file Var ClientName #XXX_REPLACE_WITH_HOSTNAME_XXX Var ClientPassword #XXX_REPLACE_WITH_FD_PASSWORD_XXX Var ClientMonitorPassword #XXX_REPLACE_WITH_FD_MONITOR_PASSWORD_XXX Var ClientAddress #XXX_REPLACE_WITH_FD_MONITOR_PASSWORD_XXX Var ClientCompatible # is client compatible? # Needed for configuring the storage config file Var StorageName # name of the storage in the director config (Device) Var StorageDaemonName # name of the storage daemon Var StoragePassword Var StorageMonitorPassword Var StorageAddress # Needed for bconsole and bat: Var DirectorAddress #XXX_REPLACE_WITH_HOSTNAME_XXX Var DirectorPassword #XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX Var DirectorName Var DirectorMonPassword # Needed for PostgreSQL Database Var PostgresPath Var PostgresBinPath var PostgresPsqlExeFullPath Var DbDriver Var DbPassword Var DbPort Var DbUser Var DbName Var DbEncoding Var DbAdminPassword Var DbAdminUser # do we need to install Director/Storage (Cmdline setting) Var InstallDirector Var InstallStorage # Generated configuration snippet for bareos director config (client ressource) Var ConfigSnippet Var OsIsNT Var dialog Var hwnd # Keep the configuration files also when running silently? Var SilentKeepConfig # Are we doing an upgrade or fresh install? # If we are doing an upgrade we automatically # keep the existing config files silently and skip # the param dialogs and the config snippet dialog Var Upgrading # variable if we do write logs or not # Var WriteLogs !include "LogicLib.nsh" !include "FileFunc.nsh" !include "Sections.nsh" !include "StrFunc.nsh" !include "WinMessages.nsh" !include "nsDialogs.nsh" !include "x64.nsh" !include "WinVer.nsh" !include "WordFunc.nsh" # call functions once to have them included ${StrCase} ${StrTrimNewLines} ${StrRep} ; MUI 1.67 compatible ------ !include "MUI.nsh" ; MUI Settings !define MUI_ABORTWARNING !define MUI_ICON "bareos.ico" !define MUI_UNICON "bareos.ico" #!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" #!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" !define MUI_COMPONENTSPAGE_SMALLDESC !insertmacro GetParameters !insertmacro GetOptions ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License !insertmacro MUI_PAGE_LICENSE "LICENSE" ; Directory page !insertmacro MUI_PAGE_DIRECTORY ; Components page !insertmacro MUI_PAGE_COMPONENTS ; Custom für Abfragen benötigter Parameter für den Client Page custom getClientParameters ; Custom für Abfragen benötigter Parameter für den Zugriff auf director Page custom getDirectorParameters Page custom getDatabaseParameters getDatabaseParametersLeave ; Custom für Abfragen benötigter Parameter für den Storage Page custom getStorageParameters ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page ; Custom page shows director config snippet Page custom displayDirconfSnippet Function LaunchLink ExecShell "open" "http://www.bareos.com" FunctionEnd !define MUI_FINISHPAGE_RUN #!define MUI_FINISHPAGE_RUN_NOTCHECKED !define MUI_FINISHPAGE_RUN_TEXT "Open www.bareos.com" !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink" !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English" ; Reserve files !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ; MUI end ------ # check for the connection of the admin user with DbAdminUser/DbAdminPass # if not successfull, abort # this will quit the silent installer # and jump back to the db param dialog in interactive installer !macro CheckDbAdminConnection !define UniqueID ${__LINE__} # create a unique Id to be able to use labels in the macro. # See http://nsis.sourceforge.net/Tutorial:_Using_labels_in_macro%27s # search for value of HKEY_LOCAL_MACHINE\SOFTWARE\PostgreSQL Global Development Group\PostgreSQL, Key "Location" ReadRegStr $PostgresPath HKLM "SOFTWARE\PostgreSQL Global Development Group\PostgreSQL" "Location" StrCmp $WriteLogs "yes" 0 +2 LogEx::Init false $INSTDIR\sql.log # now check if we can login with DbAdminUser and DbAdminPassword StrCpy $R0 "$PostgresPath" StrCpy $R1 "\bin" StrCpy $PostgresBinPath "$R0$R1" # create postgresbinpath StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "PostgresPath=$PostgresPath" StrCpy $PostgresPsqlExeFullPath "$\"$PostgresBinPath\psql.exe$\"" # set postgres username and password in environment System::Call 'kernel32::SetEnvironmentVariable(t "PGUSER", t "$DbAdminUser")i.r0' System::Call 'kernel32::SetEnvironmentVariable(t "PGPASSWORD", t "$DbAdminPassword")i.r0' DetailPrint "Now trying to log into the postgres server with the DbAdmin User and Password" DetailPrint "Running $PostgresPsqlExeFullPath -c \copyright" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "Running $PostgresPsqlExeFullPath -c \copyright" nsExec::Exec /TIMEOUT=10000 "$PostgresPsqlExeFullPath -c \copyright" Pop $0 # return value/error/timeout DetailPrint "Return Value is $0" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "Return Value is $0" ${select} $0 ${case} "1" DetailPrint "psql.exe was killed" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "psql.exe was killed" ${case} "2" DetailPrint "connection failed, username or password wrong?" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "connection failed, username or password wrong?" ${case} "timeout" DetailPrint "connection timed out, probably password is wrong?" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "connection timed out, probably password is wrong?" ${case} "error" DetailPrint "could not execute $PostgresPsqlExeFullPath" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "could not execute $PostgresPsqlExeFullPath" ${case} "0" DetailPrint "success" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "success" goto afterabort_${UniqueID} ${caseelse} DetailPrint "Unknown problem executing $PostgresPsqlExeFullPath" StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "Unknown problem executing $PostgresPsqlExeFullPath" ${endselect} MessageBox MB_OK|MB_ICONSTOP "Connection to db server with DbAdmin credentials failed.$\r$\nplease check username/password and service" /SD IDOK StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "Connection to db server with DbAdmin credentials failed.$\r$\nplease check username/password and service" StrCmp $WriteLogs "yes" 0 +2 LogEx::Close FileOpen $R1 $TEMP\abortreason.txt w FileWrite $R1 "database connection failed" FileClose $R1 abort afterabort_${UniqueID}: !undef UniqueID !macroend # # move existing conf files to .old # and install new ones in original place # also, install a shortcut to edit # the conf file # !macro InstallConfFile fname # This is important to have $APPDATA variable # point to ProgramData folder # instead of current user's Roaming folder SetShellVarContext all ${If} ${FileExists} "$APPDATA\${PRODUCT_NAME}\${fname}" StrCmp $SilentKeepConfig "yes" keep # in silent install keep configs silently if desired StrCmp $Upgrading "yes" keep # during upgrade also keep configs silently MessageBox MB_YESNO|MB_ICONQUESTION \ "Existing config file found: $APPDATA\${PRODUCT_NAME}\${fname}$\r$\nKeep existing config file?" \ /SD IDNO IDYES keep IDNO move move: Rename "$APPDATA\${PRODUCT_NAME}\${fname}" "$APPDATA\${PRODUCT_NAME}\${fname}.old" Rename "$PLUGINSDIR\${fname}" "$APPDATA\${PRODUCT_NAME}\${fname}" MessageBox MB_OK|MB_ICONINFORMATION \ "Existing config file saved as $APPDATA\${PRODUCT_NAME}\${fname}.old" \ /SD IDOK GOTO skipmsgbox keep: Rename "$PLUGINSDIR\${fname}" "$APPDATA\${PRODUCT_NAME}\${fname}.new" StrCmp $Upgrading "yes" skipmsgbox # during upgrade keep existing file without messagebox MessageBox MB_OK|MB_ICONINFORMATION \ "New config file stored $APPDATA\${PRODUCT_NAME}\${fname}.new" \ /SD IDOK skipmsgbox: ${Else} Rename "$PLUGINSDIR\${fname}" "$APPDATA\${PRODUCT_NAME}\${fname}" ${EndIf} CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Edit ${fname}.lnk" "write.exe" '"$APPDATA\${PRODUCT_NAME}\${fname}"' # for traymonitor.conf, set access and ownership to users ${If} ${fname} == "tray-monitor.conf" # Disable file access inheritance AccessControl::DisableFileInheritance "$APPDATA\${PRODUCT_NAME}\${fname}" Pop $R0 ${If} $R0 == error Pop $R0 DetailPrint `AccessControl error: $R0` ${EndIf} # Set file owner to administrator AccessControl::SetFileOwner "$APPDATA\${PRODUCT_NAME}\${fname}" "(S-1-5-32-545)" # user Pop $R0 ${If} $R0 == error Pop $R0 DetailPrint `AccessControl error: $R0` ${EndIf} # Set fullaccess only for administrators (S-1-5-32-544) AccessControl::ClearOnFile "$APPDATA\${PRODUCT_NAME}\${fname}" "(S-1-5-32-545)" "FullAccess" Pop $R0 ${If} $R0 == error Pop $R0 DetailPrint `AccessControl error: $R0` ${EndIf} ${Else} # All other config files admin owner and only access # Disable file access inheritance AccessControl::DisableFileInheritance "$APPDATA\${PRODUCT_NAME}\${fname}" Pop $R0 ${If} $R0 == error Pop $R0 DetailPrint `AccessControl error: $R0` ${EndIf} # Set file owner to administrator AccessControl::SetFileOwner "$APPDATA\${PRODUCT_NAME}\${fname}" "(S-1-5-32-544)" # administratoren Pop $R0 ${If} $R0 == error Pop $R0 DetailPrint `AccessControl error: $R0` ${EndIf} # Set fullaccess only for administrators (S-1-5-32-544) AccessControl::ClearOnFile "$APPDATA\${PRODUCT_NAME}\${fname}" "(S-1-5-32-544)" "FullAccess" Pop $R0 ${If} $R0 == error Pop $R0 DetailPrint `AccessControl error: $R0` ${EndIf} ${EndIf} !macroend Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "${PRODUCT_NAME}-${PRODUCT_VERSION}.exe" InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show ShowUnInstDetails show InstType "Standard" InstType "Full" InstType "Minimal" Section -StopDaemon # nsExec::ExecToLog "net stop bareos-fd" # looks like this does not work on win7 sp1 # if the service doesnt exist, it fails and the installation # cannot start # so we use the shotgun: KillProcWMI::KillProc "bareos-fd.exe" KillProcWMI::KillProc "bareos-sd.exe" KillProcWMI::KillProc "bareos-dir.exe" KillProcWMI::KillProc "bareos-tray-monitor.exe" KillProcWMI::KillProc "bconsole.exe" KillProcWMI::KillProc "bat.exe" SectionEnd Section -SetPasswords SetShellVarContext all # Write sed file to replace the preconfigured variables by the configured values # # File Daemon and Tray Monitor configs # FileOpen $R1 $PLUGINSDIR\config.sed w #FileOpen $R1 config.sed w FileWrite $R1 "s#@VERSION@#${PRODUCT_VERSION}#g$\r$\n" FileWrite $R1 "s#@DATE@#${__DATE__}#g$\r$\n" FileWrite $R1 "s#@DISTNAME@#Windows#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX#$DirectorPassword#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DIRECTOR_MONITOR_PASSWORD_XXX#$DirectorMonPassword#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_CLIENT_PASSWORD_XXX#$ClientPassword#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_CLIENT_MONITOR_PASSWORD_XXX#$ClientMonitorPassword#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_HOSTNAME_XXX#$HostName#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_BASENAME_XXX-fd#$ClientName#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_BASENAME_XXX-dir#$DirectorName#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_BASENAME_XXX-mon#$HostName-mon#g$\r$\n" # # If we do not want to be compatible we uncomment the setting for compatible # ${If} $ClientCompatible != ${BST_CHECKED} FileWrite $R1 "s@# compatible@compatible@g$\r$\n" ${EndIf} FileWrite $R1 "s#XXX_REPLACE_WITH_SD_MONITOR_PASSWORD_XXX#$StorageMonitorPassword#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_STORAGE_PASSWORD_XXX#$StoragePassword#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_BASENAME_XXX-sd#$StorageDaemonName#g$\r$\n" # Director DB Connection Setup FileWrite $R1 "s#XXX_REPLACE_WITH_DATABASE_DRIVER_XXX#$DbDriver#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DB_PORT_XXX#$DbPort#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DB_USER_XXX#$DbUser#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DB_PASSWORD_XXX#$DbPassword#g$\r$\n" # backupcatalog backup scripts ${StrRep} '$0' "$APPDATA" '\' '/' # replace \ with / in APPDATA FileWrite $R1 "s#C:/Program Files/Bareos/make_catalog_backup.pl MyCatalog#$0/${PRODUCT_NAME}/scripts/make_catalog_backup.bat#g$\r$\n" FileWrite $R1 "s#C:/Program Files/Bareos/delete_catalog_backup#$0/${PRODUCT_NAME}/scripts/delete_catalog_backup.bat#g$\r$\n" FileClose $R1 nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\bareos-dir.conf"' nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\bareos-fd.conf"' nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\bareos-sd.conf"' nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\tray-monitor.fd.conf"' nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\tray-monitor.fd-sd.conf"' nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\tray-monitor.fd-sd-dir.conf"' #Delete config.sed FileOpen $R1 $PLUGINSDIR\postgres.sed w FileWrite $R1 "s#XXX_REPLACE_WITH_DB_USER_XXX#$DbUser#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DB_PASSWORD_XXX#with password '$DbPassword'#g$\r$\n" FileClose $R1 # # config files for bconsole and bat to access remote director # FileOpen $R1 $PLUGINSDIR\bconsole.sed w FileWrite $R1 "s#XXX_REPLACE_WITH_BASENAME_XXX-dir#$DirectorName#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_HOSTNAME_XXX#$DirectorAddress#g$\r$\n" FileWrite $R1 "s#XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX#$DirectorPassword#g$\r$\n" FileClose $R1 nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\bconsole.sed" -i-template "$PLUGINSDIR\bconsole.conf"' nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\bconsole.sed" -i-template "$PLUGINSDIR\bat.conf"' #Delete bconsole.sed # # write client config snippet for director # # # FileOpen $R1 import_this_file_into_your_director_config.txt w # # FileWrite $R1 'Client {$\n' # FileWrite $R1 ' Name = $ClientName$\n' # FileWrite $R1 ' Address = $ClientAddress$\n' # FileWrite $R1 ' Password = "$ClientPassword"$\n' # FileWrite $R1 ' Catalog = "MyCatalog"$\n' # FileWrite $R1 '}$\n' # # FileClose $R1 SectionEnd #; Check if database server is installed only in silent mode # otherwise this is done in the database dialog # Section -DataBaseCheck IfSilent 0 DataBaseCheckEnd # if we are silent, we do the db credentials check, otherwise the db dialog will do it StrCmp $InstallDirector "no" DataBaseCheckEnd # skip DbConnection if not instaling director !insertmacro CheckDbAdminConnection DataBaseCheckEnd: SectionEnd !If ${WIN_DEBUG} == yes # install sourcecode if WIN_DEBUG is yes Section Sourcecode SEC_SOURCE SectionIn 1 2 3 SetShellVarContext all SetOutPath "C:\" SetOverwrite ifnewer File /r "bareos-${VERSION}" SectionEnd !Endif SubSection "File Daemon (Client)" SUBSEC_FD Section "File Daemon and base libs" SEC_FD SectionIn 1 2 3 SetShellVarContext all # TODO: only do this if the file exists # nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /kill' # sleep 3000 # nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /remove' SetOutPath "$INSTDIR" SetOverwrite ifnewer CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" CreateDirectory "$APPDATA\${PRODUCT_NAME}" File "bareos-fd.exe" File "libbareos.dll" File "libbareosfind.dll" File "libbareoslmdb.dll" File "libcrypto-*.dll" File "libgcc_s_*-1.dll" File "libssl-*.dll" File "libstdc++-6.dll" File "pthreadGCE2.dll" File "zlib1.dll" File "liblzo2-2.dll" File "libfastlz.dll" # for password generation File "openssl.exe" File "sed.exe" !insertmacro InstallConfFile bareos-fd.conf SectionEnd Section /o "File Daemon Plugins " SEC_FDPLUGINS SectionIn 1 2 3 SetShellVarContext all SetOutPath "$INSTDIR\Plugins" SetOverwrite ifnewer File "bpipe-fd.dll" File "mssqlvdi-fd.dll" SectionEnd Section "Open Firewall for File Daemon" SEC_FIREWALL_FD SectionIn 1 2 3 SetShellVarContext current ${If} ${AtLeastWin7} # # See http://technet.microsoft.com/de-de/library/dd734783%28v=ws.10%29.aspx # DetailPrint "Opening Firewall, OS is Win7+" DetailPrint "netsh advfirewall firewall add rule name=$\"Bareos backup client (bareos-fd) access$\" dir=in action=allow program=$\"$PROGRAMFILES64\${PRODUCT_NAME}\bareos-fd.exe$\" enable=yes protocol=TCP localport=9102 description=$\"Bareos backup client rule$\"" # profile=[private,domain]" nsExec::Exec "netsh advfirewall firewall add rule name=$\"Bareos backup client (bareos-fd) access$\" dir=in action=allow program=$\"$PROGRAMFILES64\${PRODUCT_NAME}\bareos-fd.exe$\" enable=yes protocol=TCP localport=9102 description=$\"Bareos backup client rule$\"" # profile=[private,domain]" ${Else} DetailPrint "Opening Firewall, OS is < Win7" DetailPrint "netsh firewall add portopening protocol=TCP port=9102 name=$\"Bareos backup client (bareos-fd) access$\"" nsExec::Exec "netsh firewall add portopening protocol=TCP port=9102 name=$\"Bareos backup client (bareos-fd) access$\"" ${EndIf} SectionEnd SubSectionEnd #FileDaemon Subsection SubSection "Storage Daemon" SUBSEC_SD Section /o "Storage Daemon" SEC_SD SectionIn 2 SetShellVarContext all SetOutPath "$INSTDIR" SetOverwrite ifnewer File "libbareossd.dll" File "bareos-sd.exe" File "btape.exe" File "bls.exe" File "bextract.exe" CreateDirectory "C:\bareos-storage" !insertmacro InstallConfFile bareos-sd.conf SectionEnd Section /o "Storage Daemon Plugins " SEC_SDPLUGINS SectionIn 2 SetShellVarContext all SetOutPath "$INSTDIR\Plugins" SetOverwrite ifnewer File "autoxflate-sd.dll" SectionEnd Section "Open Firewall for Storage Daemon" SEC_FIREWALL_SD SectionIn 2 SetShellVarContext current ${If} ${AtLeastWin7} DetailPrint "Opening Firewall, OS is Win7+" DetailPrint "netsh advfirewall firewall add rule name=$\"Bareos storage daemon (bareos-sd) access$\" dir=in action=allow program=$\"$PROGRAMFILES64\${PRODUCT_NAME}\bareos-sd.exe$\" enable=yes protocol=TCP localport=9103 description=$\"Bareos storage daemon rule$\"" # profile=[private,domain]" nsExec::Exec "netsh advfirewall firewall add rule name=$\"Bareos storage daemon (bareos-sd) access$\" dir=in action=allow program=$\"$PROGRAMFILES64\${PRODUCT_NAME}\bareos-sd.exe$\" enable=yes protocol=TCP localport=9103 description=$\"Bareos storage daemon rule$\"" # profile=[private,domain]" ${Else} DetailPrint "Opening Firewall, OS is < Win7" DetailPrint "netsh firewall add portopening protocol=TCP port=9103 name=$\"Bareos storage daemon (bareos-sd) access$\"" nsExec::Exec "netsh firewall add portopening protocol=TCP port=9103 name=$\"Bareos storage daemon (bareos-sd) access$\"" ${EndIf} SectionEnd SubSectionEnd # Storage Daemon Subsection SubSection "Director" SUBSEC_DIR Section /o "Director" SEC_DIR SectionIn 2 SetShellVarContext all CreateDirectory "$APPDATA\${PRODUCT_NAME}\logs" CreateDirectory "$APPDATA\${PRODUCT_NAME}\working" CreateDirectory "$APPDATA\${PRODUCT_NAME}\scripts" SetOutPath "$INSTDIR" SetOverwrite ifnewer File "bareos-dir.exe" File "bareos-dbcheck.exe" File "bsmtp.exe" File "libbareoscats.dll" File "libbareoscats-postgresql.dll" # install sql ddl files # SetOutPath "$APPDATA\${PRODUCT_NAME}\scripts" # CopyFiles /SILENT "$PLUGINSDIR\ddl\*" "$APPDATA\${PRODUCT_NAME}\scripts" # File "libbareoscats-sqlite3.dll" !insertmacro InstallConfFile bareos-dir.conf # edit sql ddl files nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\postgres.sed" -i-template "$PLUGINSDIR\postgresql-grant.sql"' #nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\postgres.sed" -i-template "$PLUGINSDIR\postgresql-create.sql"' #nsExec::ExecToLog '$PLUGINSDIR\sed.exe -f "$PLUGINSDIR\config.sed" -i-template "$PLUGINSDIR\postgresql-drop.sql"' # install edited sql ddl files Rename "$PLUGINSDIR\postgresql-create.sql" "$APPDATA\${PRODUCT_NAME}\scripts\postgresql-create.sql" Rename "$PLUGINSDIR\postgresql-grant.sql" "$APPDATA\${PRODUCT_NAME}\scripts\postgresql-grant.sql" Rename "$PLUGINSDIR\postgresql-drop.sql" "$APPDATA\${PRODUCT_NAME}\scripts\postgresql-drop.sql" # create db-create script FileOpen $R1 $PLUGINSDIR\postgresql-createdb.sql w FileWrite $R1 "CREATE DATABASE $DbName $DbEncoding TEMPLATE template0; $\r$\n" FileWrite $R1 "ALTER DATABASE $DbName SET datestyle TO 'ISO, YMD'; $\r$\n" FileClose $R1 # install db-create script Rename "$PLUGINSDIR\postgresql-createdb.sql" "$APPDATA\${PRODUCT_NAME}\scripts\postgresql-createdb.sql" # copy postgresql libs to our path StrCpy $R0 "$PostgresPath" StrCpy $R1 "\bin" StrCpy $PostgresBinPath "$R0$R1" DetailPrint "Copying dlls from $PostgresBinPath ..." DetailPrint "libpq.dll" CopyFiles /SILENT "$PostgresBinPath\libpq.dll" "$INSTDIR" DetailPrint "libintl*.dll" CopyFiles /SILENT "$PostgresBinPath\libintl*.dll" "$INSTDIR" DetailPrint "ssleay32.dll" CopyFiles /SILENT "$PostgresBinPath\ssleay32.dll" "$INSTDIR" DetailPrint "libeay32.dll" CopyFiles /SILENT "$PostgresBinPath\libeay32.dll" "$INSTDIR" # Since PostgreSQL 9.4 unfortunately setting the PATH Variable is not enough # to execute psql.exe It always complains about: # > could not find a "psql.exe" to execute # > psql.exe: could not find own program executable # so we use the full path in the batch scripts # # write database create batch file # FileOpen $R1 "$APPDATA\${PRODUCT_NAME}\scripts\postgres_db_setup.bat" w FileWrite $R1 'REM call this batch file to create the bareos database in postgresql $\r$\n' FileWrite $R1 'REM $\r$\n' FileWrite $R1 'REM $\r$\n' FileWrite $R1 'REM create postgresql database $\r$\n' FileWrite $R1 "SET PATH=%PATH%;$\"$PostgresBinPath$\"$\r$\n" FileWrite $R1 "cd $APPDATA\${PRODUCT_NAME}\scripts\$\r$\n" FileWrite $R1 "echo creating bareos database$\r$\n" FileWrite $R1 "$PostgresPsqlExeFullPath -f postgresql-createdb.sql$\r$\n" FileWrite $R1 "echo creating bareos database tables$\r$\n" FileWrite $R1 "$PostgresPsqlExeFullPath -f postgresql-create.sql $DbName$\r$\n" FileWrite $R1 "echo granting bareos database rights$\r$\n" FileWrite $R1 "$PostgresPsqlExeFullPath -f postgresql-grant.sql $DbName$\r$\n" FileClose $R1 # # write database dump file # FileOpen $R1 "$APPDATA\${PRODUCT_NAME}\scripts\make_catalog_backup.bat" w FileWrite $R1 '@echo off$\r$\n' FileWrite $R1 'REM call this batch file to create a db dump$\r$\n' FileWrite $R1 'REM create postgresql database dump$\r$\n' FileWrite $R1 'SET PGUSER=bareos$\r$\n' FileWrite $R1 'SET PGPASSWORD=bareos$\r$\n' FileWrite $R1 'SET PGDATABASE=bareos$\r$\n' FileWrite $R1 "SET PATH=%PATH%;$\"$PostgresBinPath$\"$\r$\n" FileWrite $R1 'echo dumping bareos database$\r$\n' FileWrite $R1 "$\"$PostgresBinPath\pg_dump.exe$\" -f $\"$APPDATA\${PRODUCT_NAME}\working\bareos.sql$\" -c$\r$\n" FileClose $R1 # # write delete sql dump file # FileOpen $R1 "$APPDATA\${PRODUCT_NAME}\scripts\delete_catalog_backup.bat" w FileWrite $R1 '@echo off $\r$\n' FileWrite $R1 'REM this script deletes the db dump $\r$\n' FileWrite $R1 'del $APPDATA\${PRODUCT_NAME}\working\bareos.sql $\r$\n' FileClose $R1 SectionEnd Section /o "Director Plugins " SEC_DIRPLUGINS SectionIn 2 SetShellVarContext all SetOutPath "$INSTDIR\Plugins" SetOverwrite ifnewer # File "autoxflate-sd.dll" SectionEnd Section "Open Firewall for Director" SEC_FIREWALL_DIR SectionIn 2 SetShellVarContext current ${If} ${AtLeastWin7} DetailPrint "Opening Firewall, OS is Win7+" DetailPrint "netsh advfirewall firewall add rule name=$\"Bareos director (bareos-dir) access$\" dir=in action=allow program=$\"$PROGRAMFILES64\${PRODUCT_NAME}\bareos-dir.exe$\" enable=yes protocol=TCP localport=9101 description=$\"Bareos director rule$\"" # profile=[private,domain]" nsExec::Exec "netsh advfirewall firewall add rule name=$\"Bareos director (bareos-dir) access$\" dir=in action=allow program=$\"$PROGRAMFILES64\${PRODUCT_NAME}\bareos-dir.exe$\" enable=yes protocol=TCP localport=9101 description=$\"Bareos director rule$\"" # profile=[private,domain]" ${Else} DetailPrint "Opening Firewall, OS is < Win7" DetailPrint "netsh firewall add portopening protocol=TCP port=9101 name=$\"Bareos director (bareos-dir) access$\"" nsExec::Exec "netsh firewall add portopening protocol=TCP port=9101 name=$\"Bareos director (bareos-dir) access$\"" ${EndIf} SectionEnd SubSectionEnd # Director Subsection SubSection "Consoles" SUBSEC_CONSOLES Section /o "Text Console (bconsole)" SEC_BCONSOLE SectionIn 2 SetShellVarContext all SetOutPath "$INSTDIR" SetOverwrite ifnewer CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\bconsole.lnk" "$INSTDIR\bconsole.exe" '-c "$APPDATA\${PRODUCT_NAME}\bconsole.conf"' File "bconsole.exe" File "libhistory6.dll" File "libreadline6.dll" File "libtermcap-0.dll" !insertmacro InstallConfFile "bconsole.conf" SectionEnd Section /o "Tray-Monitor" SEC_TRAYMON SectionIn 1 2 SetShellVarContext all SetOutPath "$INSTDIR" SetOverwrite ifnewer CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\bareos-tray-monitor.lnk" "$INSTDIR\bareos-tray-monitor.exe" '-c "$APPDATA\${PRODUCT_NAME}\tray-monitor.conf"' # autostart CreateShortCut "$SMSTARTUP\bareos-tray-monitor.lnk" "$INSTDIR\bareos-tray-monitor.exe" '-c "$APPDATA\${PRODUCT_NAME}\tray-monitor.conf"' File "bareos-tray-monitor.exe" File "libpng*.dll" File "QtCore4.dll" File "QtGui4.dll" rename "$PLUGINSDIR\tray-monitor.fd.conf" "$PLUGINSDIR\tray-monitor.conf" ${If} ${SectionIsSelected} ${SEC_SD} delete "$PLUGINSDIR\tray-monitor.conf" rename "$PLUGINSDIR\tray-monitor.fd-sd.conf" "$PLUGINSDIR\tray-monitor.conf" ${EndIf} ${If} ${SectionIsSelected} ${SEC_DIR} delete "$PLUGINSDIR\tray-monitor.conf" rename "$PLUGINSDIR\tray-monitor.fd-sd-dir.conf" "$PLUGINSDIR\tray-monitor.conf" ${EndIf} !insertmacro InstallConfFile "tray-monitor.conf" SectionEnd Section /o "Qt Console (BAT)" SEC_BAT SectionIn 2 SetShellVarContext all SetOutPath "$INSTDIR" SetOverwrite ifnewer CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\BAT.lnk" "$INSTDIR\bat.exe" '-c "$APPDATA\${PRODUCT_NAME}\bat.conf"' CreateShortCut "$DESKTOP\BAT.lnk" "$INSTDIR\bat.exe" '-c "$APPDATA\${PRODUCT_NAME}\bat.conf"' File "bat.exe" File "libpng*.dll" File "QtCore4.dll" File "QtGui4.dll" !insertmacro InstallConfFile "bat.conf" SectionEnd SubSectionEnd # Consoles Subsection ; Section descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN ; FD !insertmacro MUI_DESCRIPTION_TEXT ${SEC_FD} "Installs the Bareos File Daemon and required Files" !insertmacro MUI_DESCRIPTION_TEXT ${SUBSEC_FD} "Programs belonging to the Bareos File Daemon (client)" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_FDPLUGINS} "Installs the Bareos File Daemon Plugins" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_FIREWALL_FD} "Opens the needed ports for the File Daemon in the windows firewall" ; SD !insertmacro MUI_DESCRIPTION_TEXT ${SEC_SD} "Installs the Bareos Storage Daemon" !insertmacro MUI_DESCRIPTION_TEXT ${SUBSEC_SD} "Programs belonging to the Bareos Storage Daemon" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_SDPLUGINS} "Installs the Bareos Storage Daemon Plugins" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_FIREWALL_SD} "Opens the needed ports for the Storage Daemon in the windows firewall" ; DIR !insertmacro MUI_DESCRIPTION_TEXT ${SEC_DIR} "Installs the Bareos Director Daemon" !insertmacro MUI_DESCRIPTION_TEXT ${SUBSEC_DIR} "Programs belonging to the Bareos Director" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_DIRPLUGINS} "Installs the Bareos Director Plugins" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_FIREWALL_DIR} "Opens the needed ports for the Director Daemon in the windows firewall" ; Consoles !insertmacro MUI_DESCRIPTION_TEXT ${SUBSEC_CONSOLES} "Programs to access and monitor the Bareos system (Consoles and Tray Monitor)" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_BCONSOLE} "Installs the CLI client console (bconsole)" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_TRAYMON} "Installs the Tray Icon to monitor the Bareos File Daemon" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_BAT} "Installs the Qt Console (BAT)" ; Sourcecode !If ${WIN_DEBUG} == yes !insertmacro MUI_DESCRIPTION_TEXT ${SEC_SOURCE} "Sourcecode for debugging will be installed into C:\bareos-${VERSION}" !Endif !insertmacro MUI_FUNCTION_DESCRIPTION_END Section -AdditionalIcons SetShellVarContext all WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninst.exe" SectionEnd Section -Post SetShellVarContext all WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bareos-fd.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bareos-fd.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" # install service nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /kill' sleep 3000 nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /remove' nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /install -c "$APPDATA\${PRODUCT_NAME}\bareos-fd.conf"' ${If} ${SectionIsSelected} ${SEC_SD} nsExec::ExecToLog '"$INSTDIR\bareos-sd.exe" /kill' sleep 3000 nsExec::ExecToLog '"$INSTDIR\bareos-sd.exe" /remove' nsExec::ExecToLog '"$INSTDIR\bareos-sd.exe" /install -c "$APPDATA\${PRODUCT_NAME}\bareos-sd.conf"' ${EndIf} ${If} ${SectionIsSelected} ${SEC_DIR} nsExec::ExecToLog '"$INSTDIR\bareos-dir.exe" /kill' sleep 3000 nsExec::ExecToLog '"$INSTDIR\bareos-dir.exe" /remove' nsExec::ExecToLog '"$INSTDIR\bareos-dir.exe" /install -c "$APPDATA\${PRODUCT_NAME}\bareos-dir.conf"' ${EndIf} SectionEnd Section -StartDaemon nsExec::ExecToLog "net start bareos-fd" ${If} ${SectionIsSelected} ${SEC_SD} nsExec::ExecToLog "net start bareos-sd" ${EndIf} ${If} ${SectionIsSelected} ${SEC_DIR} # MessageBox MB_OK|MB_ICONINFORMATION "To setup the bareos database, please run the script$\r$\n\ # $APPDATA\${PRODUCT_NAME}\scripts\postgres_db_setup.bat$\r$\n \ # with administrator rights now." /SD IDOK LogText "### Executing $APPDATA\${PRODUCT_NAME}\scripts\postgres_db_setup.bat" StrCmp $WriteLogs "yes" 0 +2 LogEx::Init false $INSTDIR\sql.log StrCmp $WriteLogs "yes" 0 +2 LogEx::Write "Now executing $APPDATA\${PRODUCT_NAME}\scripts\postgres_db_setup.bat" nsExec::ExecToLog "$APPDATA\${PRODUCT_NAME}\scripts\postgres_db_setup.bat > $PLUGINSDIR\db_setup_output.log" StrCmp $WriteLogs "yes" 0 +2 LogEx::AddFile " >" "$PLUGINSDIR\db_setup_output.log" #nsExec::ExecToStack "$APPDATA\${PRODUCT_NAME}\scripts\postgres_db_setup.bat" # Pop $0 # return value/error/timeout # Pop $1 # printed text, up to ${NSIS_MAX_STRLEN} # DetailPrint $1 # LogText $1 LogText "### Executing net start bareos-dir" nsExec::ExecToLog "net start bareos-dir" StrCmp $WriteLogs "yes" 0 +2 LogEx::Close ${EndIf} ${If} ${SectionIsSelected} ${SEC_TRAYMON} MessageBox MB_OK|MB_ICONINFORMATION "The tray monitor will be started automatically on next login. $\r$\n Alternatively it can be started from the start menu entry now." /SD IDOK ${EndIf} SectionEnd # helper functions to find out computer name Function GetComputerName Push $R0 Push $R1 Push $R2 System::Call "kernel32::GetComputerNameA(t .R0, *i ${NSIS_MAX_STRLEN} R1) i.R2" ${StrCase} $R0 $R0 "L" Pop $R2 Pop $R1 Exch $R0 FunctionEnd !define ComputerNameDnsFullyQualified 3 Function GetHostName Push $R0 Push $R1 Push $R2 ${If} $OsIsNT = 1 System::Call "kernel32::GetComputerNameExA(i ${ComputerNameDnsFullyQualified}, t .R0, *i ${NSIS_MAX_STRLEN} R1) i.R2 ?e" ${If} $R2 = 0 Pop $R2 DetailPrint "GetComputerNameExA failed - LastError = $R2" Call GetComputerName Pop $R0 ${Else} Pop $R2 ${EndIf} ${Else} Call GetComputerName Pop $R0 ${EndIf} Pop $R2 Pop $R1 Exch $R0 FunctionEnd Function .onInit # Parameters: # Needed for Client and Tray-Mon: # # Client Name # # Director Name # Client Password # Client Network Address # # Client Monitor Password # # Needed for Bconsole/Bat: # # Director Network Address # Director Password # var /GLOBAL cmdLineParams # Installer Options ${GetParameters} $cmdLineParams ClearErrors # /? param (help) ClearErrors ${GetOptions} $cmdLineParams '/?' $R0 IfErrors +3 0 MessageBox MB_OK|MB_ICONINFORMATION "[/CLIENTNAME=Name of the client ressource] $\r$\n\ [/CLIENTPASSWORD=Password to access the client] $\r$\n\ [/DIRECTORNAME=Name of Director to access the client and of the Director accessed by bconsole/BAT] $\r$\n\ [/CLIENTADDRESS=Network Address of the client] $\r$\n\ [/CLIENTMONITORPASSWORD=Password for monitor access] $\r$\n\ [/CLIENTCOMPATIBLE=(0/1) client compatible setting (0=no,1=yes)]$\r$\n\ $\r$\n\ [/DIRECTORADDRESS=Network Address of the Director (for bconsole or BAT)] $\r$\n\ [/DIRECTORPASSWORD=Password to access Director]$\r$\n\ $\r$\n\ [/STORAGENAME=Name of the storage ressource] $\r$\n\ [/STORAGEPASSWORD=Password to access the storage] $\r$\n\ [/STORAGEADDRESS=Network Address of the storage] $\r$\n\ [/STORAGEMONITORPASSWORD=Password for monitor access] $\r$\n\ $\r$\n\ [/INSTALLDIRECTOR Installs Director and Components, needs postgresql installed locally! ] $\r$\n\ [/DBADMINUSER=Database Admin User] $\r$\n\ [/DBADMINPASSWORD=Database Admin Password] $\r$\n\ [/INSTALLSTORAGE Installs Storage Daemon and Components] $\r$\n\ $\r$\n\ [/S silent install without user interaction]$\r$\n\ (deletes config files on uinstall, moves existing config files away and uses newly new ones) $\r$\n\ [/SILENTKEEPCONFIG keep configuration files on silent uninstall and use exinsting config files during silent install]$\r$\n\ [/D=C:\specify\installation\directory (! HAS TO BE THE LAST OPTION !)$\r$\n\ [/? (this help dialog)] $\r$\n\ [/WRITELOGS lets the installer create log files in INSTDIR" # [/DIRECTORNAME=Name of the Director to be accessed from bconsole/BAT]" Abort # Check if this is Windows NT. StrCpy $OsIsNT 0 ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion ${If} $R0 != "" StrCpy $OsIsNT 1 ${EndIf} # Check if we are installing on 64Bit, then do some settings ${If} ${RunningX64} # 64Bit OS ${If} ${BIT_WIDTH} == '32' MessageBox MB_OK|MB_ICONSTOP "You are running a 32 Bit installer on a 64 Bit OS.$\r$\nPlease use the 64 Bit installer." Abort ${EndIf} # if instdir was not altered, change installdir to $PROGRAMFILES64\${PRODUCT_NAME}, else use what was explicitly set StrCmp $INSTDIR "$PROGRAMFILES\${PRODUCT_NAME}" 0 dontset64bitinstdir StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}" dontset64bitinstdir: SetRegView 64 ${EnableX64FSRedirection} ${Else} # 32Bit OS ${If} ${BIT_WIDTH} == '64' MessageBox MB_OK|MB_ICONSTOP "You are running a 64 Bit installer on a 32 Bit OS.$\r$\nPlease use the 32 Bit installer." Abort ${EndIf} ${EndIf} # # UPGRADE: if already installed allow to uninstall installed version # inspired by http://nsis.sourceforge.net/Auto-uninstall_old_before_installing_new # strcpy $Upgrading "no" ReadRegStr $2 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" ReadRegStr $0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" ReadRegStr $R0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" # # If there is no version installed there is not much to upgrade so jump to done. # StrCmp $R0 "" done # # As versions before 12.4.5 cannot keep the config files during silent install, we do not support upgrading here # ${VersionCompare} "12.4.5" "$0" $1 ${select} $1 ${case} 1 MessageBox MB_OK|MB_ICONSTOP "Upgrade from version $0 is not supported.$\r$\nPlease uninstall and then install again." Abort ${endselect} strcpy $Upgrading "yes" ${StrRep} $INSTDIR $R0 "uninst.exe" "" # find current INSTDIR by cutting uninst.exe out of uninstall string MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "${PRODUCT_NAME} version $0 is already installed in $\r$\n \ '$INSTDIR' on your system.$\r$\n$\n \ `OK` executes the uninstaller before installing the new version$\r$\n \ `Cancel` cancels this upgrade. $\r$\n $\r$\n \ It is recommended that you make a copy of your configuration files before upgrading.$\r$\n \ " \ /SD IDCANCEL IDOK uninst Abort ;Run the uninstaller uninst: ClearErrors ExecWait '$R0 /S /SILENTKEEPCONFIG _?=$INSTDIR' ;Silent Uninstall, Keep Configuration files, Do not copy the uninstaller to a temp file IfErrors no_remove_uninstaller done # Exec $INSTDIR\uninst.exe no_remove_uninstaller: MessageBox MB_OK|MB_ICONEXCLAMATION "Error during uninstall of ${PRODUCT_NAME} version $0. Aborting" FileOpen $R1 $TEMP\abortreason.txt w FileWrite $R1 "Error during uninstall of ${PRODUCT_NAME} version $0. Aborting" FileClose $R1 abort done: ${GetOptions} $cmdLineParams "/CLIENTNAME=" $ClientName ClearErrors ${GetOptions} $cmdLineParams "/CLIENTPASSWORD=" $ClientPassword ClearErrors # ${GetOptions} $cmdLineParams "/CLIENTDIRECTORNAME=" $DirectorName # ClearErrors ${GetOptions} $cmdLineParams "/CLIENTADDRESS=" $ClientAddress ClearErrors ${GetOptions} $cmdLineParams "/CLIENTMONITORPASSWORD=" $ClientMonitorPassword ClearErrors ${GetOptions} $cmdLineParams "/CLIENTCOMPATIBLE=" $ClientCompatible ClearErrors ${GetOptions} $cmdLineParams "/DIRECTORADDRESS=" $DirectorAddress ClearErrors ${GetOptions} $cmdLineParams "/DIRECTORPASSWORD=" $DirectorPassword ClearErrors ${GetOptions} $cmdLineParams "/DIRECTORNAME=" $DirectorName ClearErrors ${GetOptions} $cmdLineParams "/STORAGENAME=" $StorageName ClearErrors ${GetOptions} $cmdLineParams "/STORAGEDAEMONNAME=" $StorageDaemonName ClearErrors ${GetOptions} $cmdLineParams "/STORAGEPASSWORD=" $StoragePassword ClearErrors ${GetOptions} $cmdLineParams "/STORAGEADDRESS=" $StorageAddress ClearErrors ${GetOptions} $cmdLineParams "/STORAGEMONITORPASSWORD=" $StorageMonitorPassword ClearErrors ${GetOptions} $cmdLineParams "/DBADMINPASSWORD=" $DbAdminPassword ClearErrors ${GetOptions} $cmdLineParams "/DBADMINUSER=" $DbAdminUser ClearErrors StrCpy $WriteLogs "yes" ${GetOptions} $cmdLineParams "/WRITELOGS" $R0 IfErrors 0 +2 # error is set if NOT found StrCpy $WriteLogs "no" ClearErrors StrCpy $InstallDirector "yes" ${GetOptions} $cmdLineParams "/INSTALLDIRECTOR" $R0 IfErrors 0 +2 # error is set if NOT found StrCpy $InstallDirector "no" ClearErrors StrCpy $InstallStorage "yes" ${GetOptions} $cmdLineParams "/INSTALLSTORAGE" $R0 IfErrors 0 +2 # error is set if NOT found StrCpy $InstallStorage "no" ClearErrors StrCpy $SilentKeepConfig "yes" ${GetOptions} $cmdLineParams "/SILENTKEEPCONFIG" $R0 IfErrors 0 +2 # error is set if NOT found StrCpy $SilentKeepConfig "no" ClearErrors InitPluginsDir File "/oname=$PLUGINSDIR\storagedialog.ini" "storagedialog.ini" File "/oname=$PLUGINSDIR\clientdialog.ini" "clientdialog.ini" File "/oname=$PLUGINSDIR\directordialog.ini" "directordialog.ini" File "/oname=$PLUGINSDIR\databasedialog.ini" "databasedialog.ini" File "/oname=$PLUGINSDIR\openssl.exe" "openssl.exe" File "/oname=$PLUGINSDIR\sed.exe" "sed.exe" # one of the two files have to be available depending onwhat openssl Version we sue File /nonfatal "/oname=$PLUGINSDIR\libcrypto-8.dll" "libcrypto-8.dll" File /nonfatal "/oname=$PLUGINSDIR\libcrypto-10.dll" "libcrypto-10.dll" # Either one of this two files will be available depending on 32/64 bits. File /nonfatal "/oname=$PLUGINSDIR\libgcc_s_sjlj-1.dll" "libgcc_s_sjlj-1.dll" File /nonfatal "/oname=$PLUGINSDIR\libgcc_s_seh-1.dll" "libgcc_s_seh-1.dll" File /nonfatal "/oname=$PLUGINSDIR\libssl-8.dll" "libssl-8.dll" File /nonfatal "/oname=$PLUGINSDIR\libssl-10.dll" "libssl-10.dll" File "/oname=$PLUGINSDIR\libstdc++-6.dll" "libstdc++-6.dll" File "/oname=$PLUGINSDIR\zlib1.dll" "zlib1.dll" File "/oname=$PLUGINSDIR\bareos-fd.conf" "bareos-fd.conf" File "/oname=$PLUGINSDIR\bareos-sd.conf" "bareos-sd.conf" File "/oname=$PLUGINSDIR\bareos-dir.conf" "bareos-dir.conf" File "/oname=$PLUGINSDIR\bconsole.conf" "bconsole.conf" File "/oname=$PLUGINSDIR\bat.conf" "bat.conf" File "/oname=$PLUGINSDIR\tray-monitor.fd.conf" "tray-monitor.fd.conf" File "/oname=$PLUGINSDIR\tray-monitor.fd-sd.conf" "tray-monitor.fd-sd.conf" File "/oname=$PLUGINSDIR\tray-monitor.fd-sd-dir.conf" "tray-monitor.fd-sd-dir.conf" File "/oname=$PLUGINSDIR\postgresql-create.sql" ".\ddl\creates\postgresql.sql" File "/oname=$PLUGINSDIR\postgresql-drop.sql" ".\ddl\drops\postgresql.sql" File "/oname=$PLUGINSDIR\postgresql-grant.sql" ".\ddl\grants\postgresql.sql" # File "/oname=$PLUGINSDIR\postgresql.sql" ".\ddl\updates\postgresql.sql" # make first section mandatory SectionSetFlags ${SEC_FD} 17 # SF_SELECTED & SF_RO SectionSetFlags ${SEC_TRAYMON} ${SF_SELECTED} # traymon SectionSetFlags ${SEC_FDPLUGINS} ${SF_SELECTED} # fd plugins SectionSetFlags ${SEC_FIREWALL_SD} ${SF_UNSELECTED} # unselect sd firewall (is selected by default, why?) SectionSetFlags ${SEC_FIREWALL_DIR} ${SF_UNSELECTED} # unselect dir firewall (is selected by default, why?) StrCmp $InstallDirector "no" dontInstDir SectionSetFlags ${SEC_DIR} ${SF_SELECTED} # director SectionSetFlags ${SEC_FIREWALL_DIR} ${SF_SELECTED} # director firewall SectionSetFlags ${SEC_DIRPLUGINS} ${SF_SELECTED} # director plugins # also install bconsole if director is selected SectionSetFlags ${SEC_BCONSOLE} ${SF_SELECTED} # bconsole dontInstDir: StrCmp $InstallStorage "no" dontInstSD SectionSetFlags ${SEC_SD} ${SF_SELECTED} # storage daemon SectionSetFlags ${SEC_FIREWALL_SD} ${SF_SELECTED} # sd firewall SectionSetFlags ${SEC_SDPLUGINS} ${SF_SELECTED} # sd plugins dontInstSD: # find out the computer name Call GetComputerName Pop $HostName Call GetHostName Pop $LocalHostAddress SetPluginUnload alwaysoff # check if password is set by cmdline. If so, skip creation strcmp $ClientPassword "" genclientpassword skipclientpassword genclientpassword: nsExec::Exec '"$PLUGINSDIR\openssl.exe" rand -base64 -out $PLUGINSDIR\pw.txt 33' pop $R0 ${If} $R0 = 0 FileOpen $R1 "$PLUGINSDIR\pw.txt" r IfErrors +4 FileRead $R1 $R0 ${StrTrimNewLines} $ClientPassword $R0 FileClose $R1 ${EndIf} skipclientpassword: strcmp $ClientMonitorPassword "" genclientmonpassword skipclientmonpassword genclientmonpassword: nsExec::Exec '"$PLUGINSDIR\openssl.exe" rand -base64 -out $PLUGINSDIR\pw.txt 33' pop $R0 ${If} $R0 = 0 FileOpen $R1 "$PLUGINSDIR\pw.txt" r IfErrors +4 FileRead $R1 $R0 ${StrTrimNewLines} $ClientMonitorPassword $R0 FileClose $R1 ${EndIf} skipclientmonpassword: # check if password is set by cmdline. If so, skip creation strcmp $StoragePassword "" genstoragepassword skipstoragepassword genstoragepassword: nsExec::Exec '"$PLUGINSDIR\openssl.exe" rand -base64 -out $PLUGINSDIR\pw.txt 33' pop $R0 ${If} $R0 = 0 FileOpen $R1 "$PLUGINSDIR\pw.txt" r IfErrors +4 FileRead $R1 $R0 ${StrTrimNewLines} $StoragePassword $R0 FileClose $R1 ${EndIf} skipstoragepassword: strcmp $StorageMonitorPassword "" genstoragemonpassword skipstoragemonpassword genstoragemonpassword: nsExec::Exec '"$PLUGINSDIR\openssl.exe" rand -base64 -out $PLUGINSDIR\pw.txt 33' pop $R0 ${If} $R0 = 0 FileOpen $R1 "$PLUGINSDIR\pw.txt" r IfErrors +4 FileRead $R1 $R0 ${StrTrimNewLines} $StorageMonitorPassword $R0 FileClose $R1 ${EndIf} skipstoragemonpassword: strcmp $DirectorPassword "" gendirectorpassword skipdirectorpassword gendirectorpassword: nsExec::Exec '"$PLUGINSDIR\openssl.exe" rand -base64 -out $PLUGINSDIR\pw.txt 33' pop $R0 ${If} $R0 = 0 FileOpen $R1 "$PLUGINSDIR\pw.txt" r IfErrors +4 FileRead $R1 $R0 ${StrTrimNewLines} $DirectorPassword $R0 FileClose $R1 ${EndIf} skipdirectorpassword: strcmp $DirectorMonPassword "" gendirectormonpassword skipdirectormonpassword gendirectormonpassword: nsExec::Exec '"$PLUGINSDIR\openssl.exe" rand -base64 -out $PLUGINSDIR\pw.txt 33' pop $R0 ${If} $R0 = 0 FileOpen $R1 "$PLUGINSDIR\pw.txt" r IfErrors +4 FileRead $R1 $R0 ${StrTrimNewLines} $DirectorMonPassword $R0 FileClose $R1 ${EndIf} skipdirectormonpassword: # if the variables are not empty (because of cmdline params), # dont set them with our own logic but leave them as they are strcmp $ClientName "" +1 +2 StrCpy $ClientName "$HostName-fd" strcmp $ClientAddress "" +1 +2 StrCpy $ClientAddress "$HostName" strcmp $DirectorName "" +1 +2 StrCpy $DirectorName "$HostName-dir" strcmp $DirectorAddress "" +1 +2 StrCpy $DirectorAddress "$HostName" strcmp $DirectorPassword "" +1 +2 StrCpy $DirectorPassword "$DirectorPassword" strcmp $StorageDaemonName "" +1 +2 StrCpy $StorageDaemonName "$HostName-sd" strcmp $StorageName "" +1 +2 StrCpy $StorageName "File" strcmp $StorageAddress "" +1 +2 StrCpy $StorageAddress "$HostName" strcmp $DbDriver "" +1 +2 StrCpy $DbDriver "postgresql" strcmp $DbPassword "" +1 +2 StrCpy $DbPassword "bareos" strcmp $DbPort "" +1 +2 StrCpy $DbPort "5432" strcmp $DbUser "" +1 +2 StrCpy $DbUser "bareos" strcmp $DbEncoding "" +1 +2 StrCpy $DbEncoding "ENCODING 'SQL_ASCII' LC_COLLATE 'C' LC_CTYPE 'C'" strcmp $DbName "" +1 +2 StrCpy $DbName "bareos" strcmp $DbAdminUser "" +1 +2 StrCpy $DbAdminUser "postgres" strcmp $DbAdminPassword "" +1 +2 StrCpy $DbAdminPassword "" !If ${WIN_DEBUG} == yes StrCpy $WriteLogs "yes" !EndIf StrCmp $WriteLogs "yes" 0 +3 LogSet on # enable nsis-own logging to $INSTDIR\install.log, needs INSTDIR defined LogText "Logging started, INSTDIR is $INSTDIR" FunctionEnd # # Client Configuration Dialog # Function getClientParameters push $R0 # skip if we are upgrading strcmp $Upgrading "yes" skip # prefill the dialog fields with our passwords and other # information WriteINIStr "$PLUGINSDIR\clientdialog.ini" "Field 2" "state" $ClientName WriteINIStr "$PLUGINSDIR\clientdialog.ini" "Field 3" "state" $DirectorName WriteINIStr "$PLUGINSDIR\clientdialog.ini" "Field 4" "state" $ClientPassword WriteINIStr "$PLUGINSDIR\clientdialog.ini" "Field 14" "state" $ClientMonitorPassword WriteINIStr "$PLUGINSDIR\clientdialog.ini" "Field 5" "state" $ClientAddress # WriteINIStr "$PLUGINSDIR\clientdialog.ini" "Field 7" "state" "Director console password" ${If} ${SectionIsSelected} ${SEC_FD} InstallOptions::dialog $PLUGINSDIR\clientdialog.ini Pop $R0 ReadINIStr $ClientName "$PLUGINSDIR\clientdialog.ini" "Field 2" "state" ReadINIStr $DirectorName "$PLUGINSDIR\clientdialog.ini" "Field 3" "state" ReadINIStr $ClientPassword "$PLUGINSDIR\clientdialog.ini" "Field 4" "state" ReadINIStr $ClientMonitorPassword "$PLUGINSDIR\clientdialog.ini" "Field 14" "state" ReadINIStr $ClientAddress "$PLUGINSDIR\clientdialog.ini" "Field 5" "state" ReadINIStr $ClientCompatible "$PLUGINSDIR\clientdialog.ini" "Field 16" "state" ${EndIf} # MessageBox MB_OK "Compatible:$\r$\n$Compatible" skip: Pop $R0 FunctionEnd # # Storage Configuration Dialog # Function getStorageParameters push $R0 # skip if we are upgrading strcmp $Upgrading "yes" skip # prefill the dialog fields with our passwords and other # information WriteINIStr "$PLUGINSDIR\storagedialog.ini" "Field 2" "state" $StorageDaemonName WriteINIStr "$PLUGINSDIR\storagedialog.ini" "Field 3" "state" $DirectorName WriteINIStr "$PLUGINSDIR\storagedialog.ini" "Field 4" "state" $StoragePassword WriteINIStr "$PLUGINSDIR\storagedialog.ini" "Field 14" "state" $StorageMonitorPassword WriteINIStr "$PLUGINSDIR\storagedialog.ini" "Field 5" "state" $StorageAddress # WriteINIStr "$PLUGINSDIR\storagedialog.ini" "Field 7" "state" "Director console password" ${If} ${SectionIsSelected} ${SEC_SD} InstallOptions::dialog $PLUGINSDIR\storagedialog.ini Pop $R0 ReadINIStr $StorageDaemonName "$PLUGINSDIR\storagedialog.ini" "Field 2" "state" ReadINIStr $DirectorName "$PLUGINSDIR\storagedialog.ini" "Field 3" "state" ReadINIStr $StoragePassword "$PLUGINSDIR\storagedialog.ini" "Field 4" "state" ReadINIStr $StorageMonitorPassword "$PLUGINSDIR\storagedialog.ini" "Field 14" "state" ReadINIStr $StorageAddress "$PLUGINSDIR\storagedialog.ini" "Field 5" "state" ${EndIf} # MessageBox MB_OK "$StorageName$\r$\n$StoragePassword$\r$\n$StorageMonitorPassword " skip: Pop $R0 FunctionEnd # # Director Configuration Dialog (for bconsole and bat configuration) # Function getDirectorParameters Push $R0 strcmp $Upgrading "yes" skip # prefill the dialog fields WriteINIStr "$PLUGINSDIR\directordialog.ini" "Field 2" "state" $DirectorAddress WriteINIStr "$PLUGINSDIR\directordialog.ini" "Field 3" "state" $DirectorPassword #TODO: also do this if BAT is selected alone ${If} ${SectionIsSelected} ${SEC_BCONSOLE} InstallOptions::dialog $PLUGINSDIR\directordialog.ini Pop $R0 ReadINIStr $DirectorAddress "$PLUGINSDIR\directordialog.ini" "Field 2" "state" ReadINIStr $DirectorPassword "$PLUGINSDIR\directordialog.ini" "Field 3" "state" ${EndIf} skip: Pop $R0 FunctionEnd # # Database Configuration Dialog (for bconsole and bat configuration) # Function getDatabaseParameters Push $R0 strcmp $Upgrading "yes" skip strcmp $InstallDirector "no" skip # prefill the dialog fields WriteINIStr "$PLUGINSDIR\databasedialog.ini" "Field 3" "state" $DbAdminUser WriteINIStr "$PLUGINSDIR\databasedialog.ini" "Field 4" "state" $DbAdminPassword WriteINIStr "$PLUGINSDIR\databasedialog.ini" "Field 5" "state" $DbUser WriteINIStr "$PLUGINSDIR\databasedialog.ini" "Field 6" "state" $DbPassword WriteINIStr "$PLUGINSDIR\databasedialog.ini" "Field 7" "state" $DbName WriteINIStr "$PLUGINSDIR\databasedialog.ini" "Field 8" "state" $DbPort InstallOptions::dialog $PLUGINSDIR\databasedialog.ini Pop $R0 skip: Pop $R0 FunctionEnd Function getDatabaseParametersLeave # read values just configured ReadINIStr $DbAdminUser "$PLUGINSDIR\databasedialog.ini" "Field 3" "state" ReadINIStr $DbAdminPassword "$PLUGINSDIR\databasedialog.ini" "Field 4" "state" ReadINIStr $DbUser "$PLUGINSDIR\databasedialog.ini" "Field 5" "state" ReadINIStr $DbPassword "$PLUGINSDIR\databasedialog.ini" "Field 6" "state" ReadINIStr $DbName "$PLUGINSDIR\databasedialog.ini" "Field 7" "state" ReadINIStr $DbPort "$PLUGINSDIR\databasedialog.ini" "Field 8" "state" dbcheckend: StrCmp $InstallDirector "no" SkipDbCheck # skip DbConnection if not instaling director !insertmacro CheckDbAdminConnection MessageBox MB_OK|MB_ICONINFORMATION "Connection to db server with DbAdmin credentials was successful." SkipDbCheck: FunctionEnd # # Display auto-created snippet to be added to director config # Function displayDirconfSnippet strcmp $Upgrading "yes" skip # skip config snippets if we have local director ${If} ${SectionIsSelected} ${SEC_DIR} goto skip ${EndIf} # # write client config snippet for director # # Multiline text edits cannot be created before but have to be created at runtime. # see http://nsis.sourceforge.net/NsDialogs_FAQ#How_to_create_a_multi-line_edit_.28text.29_control ${If} ${SectionIsSelected} ${SEC_SD} # if sd is selected, also generate sd snippet StrCpy $ConfigSnippet "Client {$\r$\n \ Name = $ClientName$\r$\n \ Address = $ClientAddress$\r$\n \ Password = $\"$ClientPassword$\"$\r$\n \ # uncomment the following if using bacula $\r$\n \ # Catalog = $\"MyCatalog$\"$\r$\n\ }$\r$\n $\r$\n\ Storage {$\r$\n \ Name = $StorageName$\r$\n \ Address = $StorageAddress$\r$\n \ Password = $\"$StoragePassword$\"$\r$\n \ Device = FileStorage$\r$\n \ Media Type = File$\r$\n\ }$\r$\n \ " ${Else} StrCpy $ConfigSnippet "Client {$\r$\n \ Name = $ClientName$\r$\n \ Address = $ClientAddress$\r$\n \ Password = $\"$ClientPassword$\"$\r$\n \ # uncomment the following if using bacula $\r$\n \ # Catalog = $\"MyCatalog$\"$\r$\n \ }$\r$\n" ${EndIf} nsDialogs::Create 1018 Pop $dialog ${NSD_CreateGroupBox} 0 0 100% 100% "Add this configuration snippet to your Bareos Director Configuration" Pop $hwnd nsDialogs::CreateControl EDIT \ "${__NSD_Text_STYLE}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN}" \ "${__NSD_Text_EXSTYLE}" \ 10 15 95% 90% \ $ConfigSnippet Pop $hwnd nsDialogs::Show skip: FunctionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully uninstalled." /SD IDYES FunctionEnd Function un.onInit MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Do you want to uninstall $(^Name) and all its components?" /SD IDYES IDYES +2 Abort FunctionEnd Section Uninstall # UnInstaller Options ${GetParameters} $cmdLineParams ClearErrors # check cmdline parameters StrCpy $SilentKeepConfig "yes" ${GetOptions} $cmdLineParams "/SILENTKEEPCONFIG" $R0 IfErrors 0 +2 # error is set if NOT found StrCpy $SilentKeepConfig "no" ClearErrors # on 64Bit Systems, change the INSTDIR and Registry view to remove the right entries ${If} ${RunningX64} # 64Bit OS SetRegView 64 ${EnableX64FSRedirection} ${EndIf} SetShellVarContext all # uninstall service nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /kill' sleep 3000 nsExec::ExecToLog '"$INSTDIR\bareos-fd.exe" /remove' nsExec::ExecToLog '"$INSTDIR\bareos-sd.exe" /kill' sleep 3000 nsExec::ExecToLog '"$INSTDIR\bareos-sd.exe" /remove' nsExec::ExecToLog '"$INSTDIR\bareos-dir.exe" /kill' sleep 3000 nsExec::ExecToLog '"$INSTDIR\bareos-dir.exe" /remove' # kill tray monitor KillProcWMI::KillProc "bareos-tray-monitor.exe" # kill bconsole and bat if running KillProcWMI::KillProc "bconsole.exe" KillProcWMI::KillProc "bat.exe" # be sure and also kill the other daemons KillProcWMI::KillProc "bareos-fd.exe" KillProcWMI::KillProc "bareos-sd.exe" KillProcWMI::KillProc "bareos-dir.exe" StrCmp $SilentKeepConfig "yes" ConfDeleteSkip # keep if silent and $SilentKeepConfig is yes MessageBox MB_YESNO|MB_ICONQUESTION \ "Do you want to keep the existing configuration files?" /SD IDNO IDYES ConfDeleteSkip Delete "$APPDATA\${PRODUCT_NAME}\bareos-fd.conf" Delete "$APPDATA\${PRODUCT_NAME}\bareos-sd.conf" Delete "$APPDATA\${PRODUCT_NAME}\bareos-dir.conf" Delete "$APPDATA\${PRODUCT_NAME}\tray-monitor.conf" Delete "$APPDATA\${PRODUCT_NAME}\bconsole.conf" Delete "$APPDATA\${PRODUCT_NAME}\bat.conf" ConfDeleteSkip: Delete "$APPDATA\${PRODUCT_NAME}\bareos-fd.conf.old" Delete "$APPDATA\${PRODUCT_NAME}\bareos-sd.conf.old" Delete "$APPDATA\${PRODUCT_NAME}\bareos-dir.conf.old" Delete "$APPDATA\${PRODUCT_NAME}\tray-monitor.conf.old" Delete "$APPDATA\${PRODUCT_NAME}\bconsole.conf.old" Delete "$APPDATA\${PRODUCT_NAME}\bat.conf.old" Delete "$INSTDIR\${PRODUCT_NAME}.url" Delete "$INSTDIR\uninst.exe" Delete "$INSTDIR\bareos-tray-monitor.exe" Delete "$INSTDIR\bat.exe" Delete "$INSTDIR\bareos-fd.exe" Delete "$INSTDIR\bareos-sd.exe" Delete "$INSTDIR\bareos-dir.exe" Delete "$INSTDIR\bareos-dbcheck.exe" Delete "$INSTDIR\btape.exe" Delete "$INSTDIR\bls.exe" Delete "$INSTDIR\bextract.exe" Delete "$INSTDIR\bconsole.exe" Delete "$INSTDIR\Plugins\bpipe-fd.dll" Delete "$INSTDIR\Plugins\mssqlvdi-fd.dll" Delete "$INSTDIR\Plugins\autoxflate-sd.dll" Delete "$INSTDIR\libbareos.dll" Delete "$INSTDIR\libbareossd.dll" Delete "$INSTDIR\libbareosfind.dll" Delete "$INSTDIR\libbareoslmdb.dll" Delete "$INSTDIR\libbareoscats.dll" Delete "$INSTDIR\libbareoscats-postgresql.dll" Delete "$INSTDIR\libcrypto-*.dll" Delete "$INSTDIR\libgcc_s_*-1.dll" Delete "$INSTDIR\libhistory6.dll" Delete "$INSTDIR\libreadline6.dll" Delete "$INSTDIR\libssl-*.dll" Delete "$INSTDIR\libstdc++-6.dll" Delete "$INSTDIR\libtermcap-0.dll" Delete "$INSTDIR\pthreadGCE2.dll" Delete "$INSTDIR\zlib1.dll" Delete "$INSTDIR\QtCore4.dll" Delete "$INSTDIR\QtGui4.dll" Delete "$INSTDIR\liblzo2-2.dll" Delete "$INSTDIR\libfastlz.dll" Delete "$INSTDIR\libpng*.dll" Delete "$INSTDIR\openssl.exe" Delete "$INSTDIR\sed.exe" Delete "$INSTDIR\bsmtp.exe" Delete "$INSTDIR\*template" # copied stuff from postgresql install Delete "$INSTDIR\libpq.dll" Delete "$INSTDIR\libintl*.dll" Delete "$INSTDIR\ssleay32.dll" Delete "$INSTDIR\libeay32.dll" # batch scripts and sql files Delete "$APPDATA\${PRODUCT_NAME}\scripts\*.bat" Delete "$APPDATA\${PRODUCT_NAME}\scripts\*.sql" # log Delete "$APPDATA\${PRODUCT_NAME}\logs\*.log" RMDir "$APPDATA\${PRODUCT_NAME}\logs" RMDir "$APPDATA\${PRODUCT_NAME}\working" RMDir "$APPDATA\${PRODUCT_NAME}\scripts" RMDir "$APPDATA\${PRODUCT_NAME}" Delete "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" Delete "$DESKTOP\${PRODUCT_NAME}.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" # shortcuts Delete "$SMPROGRAMS\${PRODUCT_NAME}\Edit*.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\bconsole.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\BAT.lnk" Delete "$DESKTOP\BAT.lnk" # traymon Delete "$SMPROGRAMS\${PRODUCT_NAME}\bareos-tray-monitor.lnk" # traymon autostart Delete "$SMSTARTUP\bareos-tray-monitor.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" Delete "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" RMDir "$SMPROGRAMS\${PRODUCT_NAME}" RMDir "$INSTDIR\Plugins" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" SetAutoClose true # close Firewall ${If} ${AtLeastWin7} DetailPrint "Closing Firewall, OS is Win7+" DetailPrint "netsh advfirewall firewall delete rule name=$\"Bareos backup client (bareos-fd) access$\"" nsExec::Exec "netsh advfirewall firewall delete rule name=$\"Bareos backup client (bareos-fd) access$\"" DetailPrint "netsh advfirewall firewall delete rule name=$\"Bareos storage daemon (bareos-sd) access$\"" nsExec::Exec "netsh advfirewall firewall delete rule name=$\"Bareos storage daemon (bareos-sd) access$\"" DetailPrint "netsh advfirewall firewall delete rule name=$\"Bareos director (bareos-dir) access$\"" nsExec::Exec "netsh advfirewall firewall delete rule name=$\"Bareos director (bareos-dir) access$\"" ${Else} DetailPrint "Closing Firewall, OS is < Win7" DetailPrint "netsh firewall delete portopening protocol=TCP port=9102 name=$\"Bareos backup client (bareos-fd) access$\"" nsExec::Exec "netsh firewall delete portopening protocol=TCP port=9102 name=$\"Bareos backup client (bareos-fd) access$\"" DetailPrint "netsh firewall delete portopening protocol=TCP port=9103 name=$\"Bareos storage dameon (bareos-sd) access$\"" nsExec::Exec "netsh firewall delete portopening protocol=TCP port=9103 name=$\"Bareos storage daemon (bareos-sd) access$\"" DetailPrint "netsh firewall delete portopening protocol=TCP port=9101 name=$\"Bareos director (bareos-dir) access$\"" nsExec::Exec "netsh firewall delete portopening protocol=TCP port=9101 name=$\"Bareos director (bareos-dir) access$\"" ${EndIf} # remove sourcecode RMDir /r "C:\bareos-${VERSION}" # install log Delete "$INSTDIR\install.txt" SectionEnd Function .onSelChange Push $R0 Push $R1 # Check if BAT was just selected then select SEC_BCONSOLE SectionGetFlags ${SEC_BAT} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 ${SF_SELECTED} 0 +2 SectionSetFlags ${SEC_BCONSOLE} $R0 # if director is selected, we set InstallDirector to yes else no StrCpy $InstallDirector "no" SectionGetFlags ${SEC_DIR} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 ${SF_SELECTED} 0 +2 StrCpy $InstallDirector "yes" Pop $R1 Pop $R0 FunctionEnd bareos-Release-14.2.6/platforms/win32/winbareos32.spec000066400000000000000000000175521263011562700224350ustar00rootroot00000000000000# If name contains debug, enable debug during build %define WIN_DEBUG %(echo %name | grep debug >/dev/null 2>&1 && echo "yes" || echo "no") # If name contains prevista, build for windows < vista %define WIN_VISTACOMPAT %(echo %name | grep prevista >/dev/null 2>&1 && echo "no" || echo "yes") # Determine Windows Version (32/64) from name (mingw32-.../ming64-...) %define WIN_VERSION %(echo %name | grep 64 >/dev/null 2>&1 && echo "64" || echo "32") # Set what to build %define BUILD_QTGUI yes %define __strip %{_mingw32_strip} %define __objdump %{_mingw32_objdump} %define _use_internal_dependency_generator 0 #define __find_requires %{_mingw32_findrequires} %define __find_provides %{_mingw32_findprovides} #define __os_install_post #{_mingw32_debug_install_post} \ # #{_mingw32_install_post} %define flavors "prevista postvista prevista-debug postvista-debug" Name: mingw32-winbareos Version: 14.2.6 Release: 0 Summary: bareos License: LGPLv2+ Group: Development/Libraries URL: http://bareos.org Source0: bareos-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch #!BuildIgnore: post-build-checks %define addonsdir /bareos-addons/ BuildRequires: bareos-addons %define SIGNCERT ia.p12 %define SIGNPWFILE signpassword Source1: fillup.sed Patch1: tray-monitor-conf.patch Patch2: tray-monitor-conf-fd-sd.patch BuildRequires: mingw32-filesystem BuildRequires: mingw32-cross-gcc BuildRequires: mingw32-cross-gcc-c++ BuildRequires: mingw32-cross-binutils BuildRequires: mingw32-cross-pkg-config BuildRequires: mingw32-libqt4-devel BuildRequires: mingw32-libqt4 BuildRequires: mingw32-pthreads-devel BuildRequires: mingw32-pthreads BuildRequires: mingw32-libopenssl-devel BuildRequires: mingw32-libopenssl BuildRequires: mingw32-openssl BuildRequires: mingw32-libdb-devel BuildRequires: mingw32-libgcc BuildRequires: mingw32-libtool #BuildRequires: mingw32-sed BuildRequires: mingw32-libgcrypt20 BuildRequires: mingw32-cross-nsis BuildRequires: mingw32-gcc BuildRequires: mingw32-gcc-c++ BuildRequires: mingw32-pthreads-devel BuildRequires: mingw32-zlib-devel BuildRequires: mingw32-zlib BuildRequires: mingw32-libpng16-16 BuildRequires: mingw32-libstdc++ BuildRequires: mingw32-readline BuildRequires: mingw32-readline-devel BuildRequires: mingw32-lzo BuildRequires: mingw32-lzo-devel BuildRequires: mingw32-libfastlz BuildRequires: mingw32-libfastlz-devel BuildRequires: mingw32-libsqlite3-0 BuildRequires: mingw32-libsqlite-devel BuildRequires: sed BuildRequires: vim, procps, bc BuildRequires: osslsigncode BuildRequires: obs-name-resolution-settings %description bareos %package devel Summary: bareos Group: Development/Libraries %description devel bareos %package prevista Summary: bareos %description prevista bareos %package prevista-debug Summary: bareos %description prevista-debug bareos %package postvista Summary: bareos %description postvista bareos %package postvista-debug Summary: bareos %description postvista-debug bareos #{_mingw32_debug_package} %prep #setup %setup -q -n bareos-%{version} cp src/qt-tray-monitor/tray-monitor.conf.in src/qt-tray-monitor/tray-monitor.conf.in.orig cp src/qt-tray-monitor/tray-monitor.conf.in src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in %patch1 -p1 mv src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in src/qt-tray-monitor/tray-monitor.fd.conf.in cp src/qt-tray-monitor/tray-monitor.conf.in.orig src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in %patch2 -p1 mv src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in src/qt-tray-monitor/tray-monitor.fd-sd.conf.in cp src/qt-tray-monitor/tray-monitor.conf.in.orig src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in # unpack addons for i in `ls %addonsdir`; do tar xvf %addonsdir/$i done CONTENT=`ls` for flavor in `echo "%flavors"`; do mkdir $flavor for content in $CONTENT; do echo copying $content to $flavor cp -a $content $flavor done done %build #cd src/win32/ #make WIN_DEBUG=%{WIN_DEBUG} BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=%{WIN_VISTACOMPAT} %{?jobs:-j%jobs} cd postvista/src/win32/ make WIN_DEBUG=no BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=yes %{?jobs:-j%jobs} cd - cd postvista-debug/src/win32/ make WIN_DEBUG=yes BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=yes %{?jobs:-j%jobs} cd - cd prevista/src/win32/ make WIN_DEBUG=no BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=no %{?jobs:-j%jobs} cd - cd prevista-debug/src/win32/ make WIN_DEBUG=yes BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=no %{?jobs:-j%jobs} cd - %install for flavor in `echo "%flavors"`; do mkdir -p $RPM_BUILD_ROOT%{_mingw32_bindir}/$flavor mkdir -p $RPM_BUILD_ROOT/etc/$flavor/%name pushd $flavor/src/win32 cp qt-tray-monitor/bareos-tray-monitor.exe \ qt-console/bat.exe \ console/bconsole.exe \ filed/bareos-fd.exe \ stored/bareos-sd.exe \ stored/btape.exe \ stored/bls.exe \ stored/bextract.exe \ dird/bareos-dir.exe \ dird/bareos-dbcheck.exe \ tools/bsmtp.exe \ stored/libbareossd*.dll \ cats/libbareoscats*.dll \ lib/libbareos.dll \ findlib/libbareosfind.dll \ lmdb/libbareoslmdb.dll \ plugins/filed/bpipe-fd.dll \ plugins/filed/mssqlvdi-fd.dll \ plugins/stored/autoxflate-sd.dll \ $RPM_BUILD_ROOT%{_mingw32_bindir}/$flavor for cfg in ../qt-tray-monitor/tray-monitor.fd.conf.in \ ../qt-tray-monitor/tray-monitor.fd-sd.conf.in \ ../qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in \ ../qt-console/bat.conf.in \ ../dird/bareos-dir.conf.in \ ../filed/bareos-fd.conf.in \ ../stored/bareos-sd.conf.in \ ../console/bconsole.conf.in \ ; do cp $cfg $RPM_BUILD_ROOT/etc/$flavor/%name/$(basename $cfg .in) done for cfg in $RPM_BUILD_ROOT/etc/$flavor/%name/*.conf; do sed -f %SOURCE1 $cfg -i ; done popd mkdir -p $RPM_BUILD_ROOT/etc/$flavor/%name/ddl for i in creates drops grants updates; do mkdir $RPM_BUILD_ROOT/etc/$flavor/%name/ddl/$i/ cp -av src/cats/ddl/$i/postgres* $RPM_BUILD_ROOT/etc/$flavor/%name/ddl/$i/ done for sql in $RPM_BUILD_ROOT/etc/$flavor//%name/ddl/*/*.sql; do sed -f %SOURCE1 $sql -i ; done # sign binary files pushd $RPM_BUILD_ROOT%{_mingw32_bindir}/$flavor for BINFILE in *; do mv $BINFILE $BINFILE.unsigned osslsigncode sign \ -pkcs12 ${OLDPWD}/%SIGNCERT \ -readpass ${OLDPWD}/%SIGNPWFILE \ -n "${DESCRIPTION}" \ -i http://www.bareos.com/ \ -t http://timestamp.comodoca.com/authenticode \ -in $BINFILE.unsigned \ -out $BINFILE rm *.unsigned done popd done %clean rm -rf $RPM_BUILD_ROOT %files %files prevista %defattr(-,root,root) /etc/prevista/%name/*.conf /etc/prevista/%name/ddl/ %dir %{_mingw32_bindir}/prevista %{_mingw32_bindir}/prevista/*.dll %{_mingw32_bindir}/prevista/*.exe %files postvista %defattr(-,root,root) /etc/postvista/%name/*.conf /etc/postvista/%name/ddl/ %dir %{_mingw32_bindir}/postvista %{_mingw32_bindir}/postvista/*.dll %{_mingw32_bindir}/postvista/*.exe %files prevista-debug %defattr(-,root,root) /etc/prevista-debug/%name/*.conf /etc/prevista-debug/%name/ddl/ %dir %{_mingw32_bindir}/prevista-debug %{_mingw32_bindir}/prevista-debug/*.dll %{_mingw32_bindir}/prevista-debug/*.exe %files postvista-debug %defattr(-,root,root) /etc/postvista-debug/%name/*.conf /etc/postvista-debug/%name/ddl/ %dir %{_mingw32_bindir}/postvista-debug %{_mingw32_bindir}/postvista-debug/*.dll %{_mingw32_bindir}/postvista-debug/*.exe %changelog bareos-Release-14.2.6/platforms/win32/winbareos64.spec000066400000000000000000000175471263011562700224460ustar00rootroot00000000000000# If name contains debug, enable debug during build %define WIN_DEBUG %(echo %name | grep debug >/dev/null 2>&1 && echo "yes" || echo "no") # If name contains prevista, build for windows < vista %define WIN_VISTACOMPAT %(echo %name | grep prevista >/dev/null 2>&1 && echo "no" || echo "yes") # Determine Windows Version (32/64) from name (mingw32-.../ming64-...) %define WIN_VERSION %(echo %name | grep 64 >/dev/null 2>&1 && echo "64" || echo "32") # Set what to build %define BUILD_QTGUI yes %define __strip %{_mingw64_strip} %define __objdump %{_mingw64_objdump} %define _use_internal_dependency_generator 0 #define __find_requires %{_mingw64_findrequires} %define __find_provides %{_mingw64_findprovides} #define __os_install_post #{_mingw64_debug_install_post} \ # #{_mingw64_install_post} %define flavors "prevista postvista prevista-debug postvista-debug" Name: mingw64-winbareos Version: 14.2.6 Release: 0 Summary: bareos License: LGPLv2+ Group: Development/Libraries URL: http://bareos.org Source0: bareos-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch #!BuildIgnore: post-build-checks %define addonsdir /bareos-addons/ BuildRequires: bareos-addons %define SIGNCERT ia.p12 %define SIGNPWFILE signpassword Source1: fillup.sed Patch1: tray-monitor-conf.patch Patch2: tray-monitor-conf-fd-sd.patch BuildRequires: mingw64-filesystem BuildRequires: mingw64-cross-gcc BuildRequires: mingw64-cross-gcc-c++ BuildRequires: mingw64-cross-binutils BuildRequires: mingw64-cross-pkg-config BuildRequires: mingw64-libqt4-devel BuildRequires: mingw64-libqt4 BuildRequires: mingw64-pthreads-devel BuildRequires: mingw64-pthreads BuildRequires: mingw64-libopenssl-devel BuildRequires: mingw64-libopenssl BuildRequires: mingw64-openssl BuildRequires: mingw64-libdb-devel BuildRequires: mingw64-libgcc BuildRequires: mingw64-libtool #BuildRequires: mingw64-sed BuildRequires: mingw64-libgcrypt20 BuildRequires: mingw64-cross-nsis BuildRequires: mingw64-gcc BuildRequires: mingw64-gcc-c++ BuildRequires: mingw64-pthreads-devel BuildRequires: mingw64-zlib-devel BuildRequires: mingw64-zlib BuildRequires: mingw64-libpng16-16 BuildRequires: mingw64-libstdc++ BuildRequires: mingw64-readline BuildRequires: mingw64-readline-devel BuildRequires: mingw64-lzo BuildRequires: mingw64-lzo-devel BuildRequires: mingw64-libfastlz BuildRequires: mingw64-libfastlz-devel BuildRequires: mingw64-libsqlite3-0 BuildRequires: mingw64-libsqlite-devel BuildRequires: sed BuildRequires: vim, procps, bc BuildRequires: osslsigncode BuildRequires: obs-name-resolution-settings %description bareos %package devel Summary: bareos Group: Development/Libraries %description devel bareos %package prevista Summary: bareos %description prevista bareos %package prevista-debug Summary: bareos %description prevista-debug bareos %package postvista Summary: bareos %description postvista bareos %package postvista-debug Summary: bareos %description postvista-debug bareos #{_mingw64_debug_package} %prep #setup %setup -q -n bareos-%{version} cp src/qt-tray-monitor/tray-monitor.conf.in src/qt-tray-monitor/tray-monitor.conf.in.orig cp src/qt-tray-monitor/tray-monitor.conf.in src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in %patch1 -p1 mv src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in src/qt-tray-monitor/tray-monitor.fd.conf.in cp src/qt-tray-monitor/tray-monitor.conf.in.orig src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in %patch2 -p1 mv src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in src/qt-tray-monitor/tray-monitor.fd-sd.conf.in cp src/qt-tray-monitor/tray-monitor.conf.in.orig src/qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in # unpack addons for i in `ls %addonsdir`; do tar xvf %addonsdir/$i done CONTENT=`ls` for flavor in `echo "%flavors"`; do mkdir $flavor for content in $CONTENT; do echo copying $content to $flavor cp -a $content $flavor done done %build #cd src/win32/ #make WIN_DEBUG=%{WIN_DEBUG} BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=%{WIN_VISTACOMPAT} %{?jobs:-j%jobs} cd postvista/src/win32/ make WIN_DEBUG=no BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=yes %{?jobs:-j%jobs} cd - cd postvista-debug/src/win32/ make WIN_DEBUG=yes BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=yes %{?jobs:-j%jobs} cd - cd prevista/src/win32/ make WIN_DEBUG=no BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=no %{?jobs:-j%jobs} cd - cd prevista-debug/src/win32/ make WIN_DEBUG=yes BUILD_QTGUI=%{BUILD_QTGUI} WIN_VERSION=%{WIN_VERSION} WIN_VISTACOMPAT=no %{?jobs:-j%jobs} cd - %install for flavor in `echo "%flavors"`; do mkdir -p $RPM_BUILD_ROOT%{_mingw64_bindir}/$flavor mkdir -p $RPM_BUILD_ROOT/etc/$flavor/%name pushd $flavor/src/win32 cp qt-tray-monitor/bareos-tray-monitor.exe \ qt-console/bat.exe \ console/bconsole.exe \ filed/bareos-fd.exe \ stored/bareos-sd.exe \ stored/btape.exe \ stored/bls.exe \ stored/bextract.exe \ dird/bareos-dir.exe \ dird/bareos-dbcheck.exe \ tools/bsmtp.exe \ stored/libbareossd*.dll \ cats/libbareoscats*.dll \ lib/libbareos.dll \ findlib/libbareosfind.dll \ lmdb/libbareoslmdb.dll \ plugins/filed/bpipe-fd.dll \ plugins/filed/mssqlvdi-fd.dll \ plugins/stored/autoxflate-sd.dll \ $RPM_BUILD_ROOT%{_mingw64_bindir}/$flavor for cfg in ../qt-tray-monitor/tray-monitor.fd.conf.in \ ../qt-tray-monitor/tray-monitor.fd-sd.conf.in \ ../qt-tray-monitor/tray-monitor.fd-sd-dir.conf.in \ ../qt-console/bat.conf.in \ ../dird/bareos-dir.conf.in \ ../filed/bareos-fd.conf.in \ ../stored/bareos-sd.conf.in \ ../console/bconsole.conf.in \ ; do cp $cfg $RPM_BUILD_ROOT/etc/$flavor/%name/$(basename $cfg .in) done for cfg in $RPM_BUILD_ROOT/etc/$flavor/%name/*.conf; do sed -f %SOURCE1 $cfg -i ; done popd mkdir -p $RPM_BUILD_ROOT/etc/$flavor/%name/ddl for i in creates drops grants updates; do mkdir $RPM_BUILD_ROOT/etc/$flavor/%name/ddl/$i/ cp -av src/cats/ddl/$i/postgres* $RPM_BUILD_ROOT/etc/$flavor/%name/ddl/$i/ done for sql in $RPM_BUILD_ROOT/etc/$flavor//%name/ddl/*/*.sql; do sed -f %SOURCE1 $sql -i ; done # sign binary files pushd $RPM_BUILD_ROOT%{_mingw64_bindir}/$flavor for BINFILE in *; do mv $BINFILE $BINFILE.unsigned osslsigncode sign \ -pkcs12 ${OLDPWD}/%SIGNCERT \ -readpass ${OLDPWD}/%SIGNPWFILE \ -n "${DESCRIPTION}" \ -i http://www.bareos.com/ \ -t http://timestamp.comodoca.com/authenticode \ -in $BINFILE.unsigned \ -out $BINFILE rm *.unsigned done popd done %clean rm -rf $RPM_BUILD_ROOT %files %files prevista %defattr(-,root,root) /etc/prevista/%name/*.conf /etc/prevista/%name/ddl/ %dir %{_mingw64_bindir}/prevista %{_mingw64_bindir}/prevista/*.dll %{_mingw64_bindir}/prevista/*.exe %files postvista %defattr(-,root,root) /etc/postvista/%name/*.conf /etc/postvista/%name/ddl/ %dir %{_mingw64_bindir}/postvista %{_mingw64_bindir}/postvista/*.dll %{_mingw64_bindir}/postvista/*.exe %files prevista-debug %defattr(-,root,root) /etc/prevista-debug/%name/*.conf /etc/prevista-debug/%name/ddl/ %dir %{_mingw64_bindir}/prevista-debug %{_mingw64_bindir}/prevista-debug/*.dll %{_mingw64_bindir}/prevista-debug/*.exe %files postvista-debug %defattr(-,root,root) /etc/postvista-debug/%name/*.conf /etc/postvista-debug/%name/ddl/ %dir %{_mingw64_bindir}/postvista-debug %{_mingw64_bindir}/postvista-debug/*.dll %{_mingw64_bindir}/postvista-debug/*.exe %changelog bareos-Release-14.2.6/po/000077500000000000000000000000001263011562700150565ustar00rootroot00000000000000bareos-Release-14.2.6/po/ChangeLog000066400000000000000000000000001263011562700166160ustar00rootroot00000000000000bareos-Release-14.2.6/po/LINGUAS000066400000000000000000000000301263011562700160740ustar00rootroot00000000000000de es fr nl sv uk it pl bareos-Release-14.2.6/po/Makefile.in.in000066400000000000000000000321341263011562700175330ustar00rootroot00000000000000# Makefile for PO directory in any package using GNU gettext. # Copyright (C) 1995-1997, 2000-2005 by Ulrich Drepper # # This file can be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU General Public # License but which still want to provide support for the GNU gettext # functionality. # Please note that the actual code of GNU gettext is covered by the GNU # General Public License and is *not* in the public domain. # # Origin: gettext-0.14.4 PACKAGE = bareos VERSION = @VERSION@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ SHELL = /bin/sh @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ datarootdir = @datarootdir@ localedir = $(datadir)/locale gettextsrcdir = $(datadir)/gettext/po INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = @MKINSTALLDIRS@ mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) GMSGFMT = @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = @XGETTEXT@ MSGMERGE = msgmerge MSGMERGE_UPDATE = @MSGMERGE@ --update MSGINIT = msginit MSGCONV = msgconv MSGFILTER = msgfilter POFILES = @POFILES@ GMOFILES = @GMOFILES@ UPDATEPOFILES = @UPDATEPOFILES@ DUMMYPOFILES = @DUMMYPOFILES@ DISTFILES.common = Makefile.in.in remove-potcdate.sin \ $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ $(POFILES) $(GMOFILES) \ $(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) POTFILES = \ CATALOGS = @CATALOGS@ # Makevars gets inserted here. (Don't remove this line!) .SUFFIXES: .SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update .po.mo: @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ .po.gmo: @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo .sin.sed: sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all: all-@USE_NLS@ all-yes: stamp-po all-no: # $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no # internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because # we don't want to bother translators with empty POT files). We assume that # LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. # In this case, stamp-po is a nop (i.e. a phony target). # stamp-po is a timestamp denoting the last time at which the CATALOGS have # been loosely updated. Its purpose is that when a developer or translator # checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, # "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent # invocations of "make" will do nothing. This timestamp would not be necessary # if updating the $(CATALOGS) would always touch them; however, the rule for # $(POFILES) has been designed to not touch files that don't need to be # changed. stamp-po: $(srcdir)/$(DOMAIN).pot test ! -f $(srcdir)/$(DOMAIN).pot || \ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) @test ! -f $(srcdir)/$(DOMAIN).pot || { \ echo "touch stamp-po" && \ echo timestamp > stamp-poT && \ mv stamp-poT stamp-po; \ } # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. # This target rebuilds $(DOMAIN).pot; it is an expensive operation. # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ else \ msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ fi; \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --msgid-bugs-address="$$msgid_bugs_address" test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ else \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ else \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ } # This rule has no dependencies: we don't need to update $(DOMAIN).pot at # every "make" invocation, only create it when it is missing. # Only "make $(DOMAIN).pot-update" or "make dist" will force an update. $(srcdir)/$(DOMAIN).pot: $(MAKE) $(DOMAIN).pot-update # This target rebuilds a PO file if $(DOMAIN).pot has changed. # Note that a PO file is not touched if it doesn't need to be changed. $(POFILES): $(srcdir)/$(DOMAIN).pot @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ if test -f "$(srcdir)/$${lang}.po"; then \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \ else \ $(MAKE) $${lang}.po-create; \ fi install: install-exec install-data install-exec: install-data: install-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ for file in $(DISTFILES.common) Makevars.template; do \ $(INSTALL_DATA) $(srcdir)/$$file \ $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ for file in Makevars; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi install-data-no: all install-data-yes: all $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ fi; \ done; \ done install-strip: install installdirs: installdirs-exec installdirs-data installdirs-exec: installdirs-data: installdirs-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ else \ : ; \ fi installdirs-data-no: installdirs-data-yes: $(mkinstalldirs) $(DESTDIR)$(datadir) @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ fi; \ done; \ done # Define this as empty until I found a useful application. installcheck: uninstall: uninstall-exec uninstall-data uninstall-exec: uninstall-data: uninstall-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ for file in $(DISTFILES.common) Makevars.template; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi uninstall-data-no: uninstall-data-yes: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ done; \ done check: all info dvi ps pdf html tags TAGS ctags CTAGS ID: mostlyclean: rm -f remove-potcdate.sed rm -f stamp-poT rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po rm -fr *.o clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES *.mo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f stamp-po $(GMOFILES) distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(MAKE) update-po @$(MAKE) dist2 # This is a separate target because 'update-po' must be executed before. dist2: stamp-po $(DISTFILES) dists="$(DISTFILES)"; \ if test "$(PACKAGE)" = "gettext-tools"; then \ dists="$$dists Makevars.template"; \ fi; \ if test -f $(srcdir)/$(DOMAIN).pot; then \ dists="$$dists $(DOMAIN).pot stamp-po"; \ fi; \ if test -f $(srcdir)/ChangeLog; then \ dists="$$dists ChangeLog"; \ fi; \ for i in 0 1 2 3 4 5 6 7 8 9; do \ if test -f $(srcdir)/ChangeLog.$$i; then \ dists="$$dists ChangeLog.$$i"; \ fi; \ done; \ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ for file in $$dists; do \ if test -f $$file; then \ cp -p $$file $(distdir) || exit 1; \ else \ cp -p $(srcdir)/$$file $(distdir) || exit 1; \ fi; \ done update-po: Makefile $(MAKE) $(DOMAIN).pot-update test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) $(MAKE) update-gmo # General rule for creating PO files. .nop.po-create: @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ exit 1 # General rule for updating PO files. .nop.po-update: @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ cd $(srcdir); \ if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi $(DUMMYPOFILES): update-gmo: Makefile $(GMOFILES) @: Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ $(SHELL) ./config.status force: depend: gen-potfiles: echo "# List of source files containing translatable strings." > POTFILES.in echo "# To generate this file, type 'make gen-potfiles'" >> POTFILES.in cd .. && find . -name "*.c" >> po/POTFILES.in cd .. && find . -name "*.h" >> po/POTFILES.in cd .. && find . -name "*.cpp" >> po/POTFILES.in # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: bareos-Release-14.2.6/po/Makevars000066400000000000000000000034031263011562700165520ustar00rootroot00000000000000# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = bareos # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Bareos GmbH & Co. KG # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = info@bareos.org # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = bareos-Release-14.2.6/po/POTFILES.in000066400000000000000000000413171263011562700166410ustar00rootroot00000000000000# List of source files containing translatable strings. # To generate this file, type 'make gen-potfiles' ./platforms/freebsd/tapetest.c ./src/cats/sql.c ./src/cats/dbi.c ./src/cats/sql_glue.c ./src/cats/myingres.c ./src/cats/sql_create.c ./src/cats/mysql.c ./src/cats/sql_delete.c ./src/cats/cats.c ./src/cats/sql_cmds.c ./src/cats/sql_find.c ./src/cats/sql_list.c ./src/cats/sql_pooling.c ./src/cats/sqlite.c ./src/cats/ingres.c ./src/cats/sql_update.c ./src/cats/sql_get.c ./src/cats/postgresql.c ./src/cats/cats_backends.c ./src/cats/bvfs.c ./src/console/conio.c ./src/console/console_conf.c ./src/console/console.c ./src/dird/ndmp_dma_backup.c ./src/dird/bsr.c ./src/dird/admin.c ./src/dird/dird.c ./src/dird/autoprune.c ./src/dird/dbcheck.c ./src/dird/quota.c ./src/dird/ndmp_fhdb_lmdb.c ./src/dird/ua_run.c ./src/dird/ua_status.c ./src/dird/msgchan.c ./src/dird/ndmp_dma_storage.c ./src/dird/ua_acl.c ./src/dird/dir_plugins.c ./src/dird/ua_impexp.c ./src/dird/authenticate.c ./src/dird/ua_output.c ./src/dird/migrate.c ./src/dird/recycle.c ./src/dird/backup.c ./src/dird/ua_query.c ./src/dird/ndmp_dma_restore.c ./src/dird/job.c ./src/dird/ua_configure.c ./src/dird/testfind.c ./src/dird/expand.c ./src/dird/ndmp_fhdb_mem.c ./src/dird/ua_dotcmds.c ./src/dird/ua_input.c ./src/dird/ua_cmds.c ./src/dird/verify.c ./src/dird/stats.c ./src/dird/run_conf.c ./src/dird/ua_server.c ./src/dird/scheduler.c ./src/dird/ua_label.c ./src/dird/ua_select.c ./src/dird/catreq.c ./src/dird/ua_purge.c ./src/dird/ua_audit.c ./src/dird/inc_conf.c ./src/dird/fd_cmds.c ./src/dird/restore.c ./src/dird/dird_conf.c ./src/dird/newvol.c ./src/dird/ua_update.c ./src/dird/getmsg.c ./src/dird/sd_cmds.c ./src/dird/next_vol.c ./src/dird/mountreq.c ./src/dird/ua_tree.c ./src/dird/vbackup.c ./src/dird/jobq.c ./src/dird/ua_restore.c ./src/dird/ndmp_fhdb_helpers.c ./src/dird/ndmp_dma_generic.c ./src/dird/ua_prune.c ./src/win32/compat/print.c ./src/win32/compat/compat.c ./src/win32/compat/winapi.c ./src/win32/generic/main.c ./src/win32/generic/service.c ./src/win32/stored/backends/win32_file_device.c ./src/win32/stored/backends/win32_tape_device.c ./src/win32/plugins/filed/mssqlvdi-fd.c ./src/win32/filed/vss_generic.c ./src/win32/filed/vss_W2K3.c ./src/win32/filed/vss_XP.c ./src/win32/filed/vss_Vista.c ./src/win32/filed/vss.c ./src/win32/findlib/win32.c ./src/tests/bbatch.c ./src/tests/gigaslam.c ./src/tests/bvfs_test.c ./src/tests/grow.c ./src/tests/ing_test.c ./src/tests/cats_test.c ./src/tests/testls.c ./src/tests/bregtest.c ./src/ndmp/ndml_stzf.c ./src/ndmp/ndma_cops_query.c ./src/ndmp/ndmjr_none.c ./src/ndmp/ndmp2_enum_strs.c ./src/ndmp/ndma_ctst_tape.c ./src/ndmp/ndma_comm_dispatch.c ./src/ndmp/ndml_conn.c ./src/ndmp/ndml_agent.c ./src/ndmp/ndml_fhdb.c ./src/ndmp/ndmjob_job.c ./src/ndmp/ndmjob_main_util.c ./src/ndmp/ndma_tape.c ./src/ndmp/ndmp0_enum_strs.c ./src/ndmp/ndml_log.c ./src/ndmp/ndmprotocol.c ./src/ndmp/ndmp4_pp.c ./src/ndmp/ndmp9_enum_strs.c ./src/ndmp/smc_api.c ./src/ndmp/ndmjob_simulator.c ./src/ndmp/ndmos_solaris.c ./src/ndmp/ndmp0_pp.c ./src/ndmp/ndml_fhh.c ./src/ndmp/ndma_comm_subr.c ./src/ndmp/ndmjob_args.c ./src/ndmp/md5c.c ./src/ndmp/ndmp9_xmt.c ./src/ndmp/ndma_ctrl_media.c ./src/ndmp/ndma_ctrl_conn.c ./src/ndmp/ndmjob_fhdb.c ./src/ndmp/ndmp3_translate.c ./src/ndmp/smc_parse.c ./src/ndmp/ndmp4_enum_strs.c ./src/ndmp/ndml_md5.c ./src/ndmp/ndmp4_xmt.c ./src/ndmp/ndmos_freebsd.c ./src/ndmp/ndma_ctrl_robot.c ./src/ndmp/ndma_cops_backreco.c ./src/ndmp/ndml_nmb.c ./src/ndmp/ndma_control.c ./src/ndmp/ndma_cops_labels.c ./src/ndmp/ndmos_linux.c ./src/ndmp/ndml_scsi.c ./src/ndmp/ndma_robot_simulator.c ./src/ndmp/ndma_robot.c ./src/ndmp/ndma_data_fh.c ./src/ndmp/ndml_config.c ./src/ndmp/ndml_bstf.c ./src/ndmp/ndmp2_pp.c ./src/ndmp/smc_pp.c ./src/ndmp/ndmp3_xmt.c ./src/ndmp/ndmjob_rules.c ./src/ndmp/ndma_comm_job.c ./src/ndmp/ndml_chan.c ./src/ndmp/ndma_ctrl_calls.c ./src/ndmp/ndma_tape_simulator.c ./src/ndmp/ndma_data_pfe.c ./src/ndmp/ndma_comm_session.c ./src/ndmp/ndml_util.c ./src/ndmp/ndma_cops_robot.c ./src/ndmp/ndmp_translate.c ./src/ndmp/ndmp2_translate.c ./src/ndmp/ndma_noti_calls.c ./src/ndmp/ndmp2_xmt.c ./src/ndmp/ndma_listmgmt.c ./src/ndmp/ndma_ctst_data.c ./src/ndmp/ndmp4_translate.c ./src/ndmp/wraplib.c ./src/ndmp/ndma_ctst_mover.c ./src/ndmp/ndmp3_enum_strs.c ./src/ndmp/ndmos_common.c ./src/ndmp/ndml_cstr.c ./src/ndmp/ndma_data.c ./src/ndmp/ndml_media.c ./src/ndmp/ndmjob_main.c ./src/ndmp/ndmp3_pp.c ./src/ndmp/ndmos.c ./src/ndmp/ndmp0_xmt.c ./src/ndmp/ndma_image_stream.c ./src/ndmp/ndma_ctst_subr.c ./src/stored/dir_cmd.c ./src/stored/ndmp_tape.c ./src/stored/fd_cmds.c ./src/stored/read.c ./src/stored/sd_plugins.c ./src/stored/stored_conf.c ./src/stored/dev.c ./src/stored/device.c ./src/stored/bscan.c ./src/stored/sd_stats.c ./src/stored/scan.c ./src/stored/append.c ./src/stored/btape.c ./src/stored/spool.c ./src/stored/reserve.c ./src/stored/mac.c ./src/stored/bls.c ./src/stored/backends/rados_device.c ./src/stored/backends/unix_file_device.c ./src/stored/backends/gfapi_device.c ./src/stored/backends/cephfs_device.c ./src/stored/backends/generic_tape_device.c ./src/stored/backends/unix_tape_device.c ./src/stored/backends/object_store_device.c ./src/stored/backends/unix_fifo_device.c ./src/stored/status.c ./src/stored/sd_cmds.c ./src/stored/authenticate.c ./src/stored/ebcdic.c ./src/stored/crc32.c ./src/stored/mount.c ./src/stored/label.c ./src/stored/block.c ./src/stored/askdir.c ./src/stored/bextract.c ./src/stored/bsr.c ./src/stored/lock.c ./src/stored/autochanger.c ./src/stored/wait.c ./src/stored/butil.c ./src/stored/read_record.c ./src/stored/acquire.c ./src/stored/ansi_label.c ./src/stored/sd_backends.c ./src/stored/job.c ./src/stored/vol_mgr.c ./src/stored/bcopy.c ./src/stored/stored.c ./src/stored/record.c ./src/findlib/xattr.c ./src/findlib/find.c ./src/findlib/hardlink.c ./src/findlib/drivetype.c ./src/findlib/bfile.c ./src/findlib/attribs.c ./src/findlib/savecwd.c ./src/findlib/enable_priv.c ./src/findlib/create_file.c ./src/findlib/mkpath.c ./src/findlib/find_one.c ./src/findlib/acl.c ./src/findlib/fstype.c ./src/findlib/shadowing.c ./src/findlib/match.c ./src/plugins/stored/python-sd.c ./src/plugins/stored/autoxflate-sd.c ./src/plugins/stored/scsitapealert-sd.c ./src/plugins/stored/example-plugin-sd.c ./src/plugins/stored/scsicrypto-sd.c ./src/plugins/dird/example-plugin-dir.c ./src/plugins/dird/python-dir.c ./src/plugins/filed/bpipe-fd.c ./src/plugins/filed/python-fd.c ./src/plugins/filed/test-deltaseq-fd.c ./src/plugins/filed/test-plugin-fd.c ./src/plugins/filed/example-plugin-fd.c ./src/lmdb/midl.c ./src/lmdb/mdb.c ./src/tools/bscrypto.c ./src/tools/bwild.c ./src/tools/smtp-orig.c ./src/tools/drivetype.c ./src/tools/bsmtp.c ./src/tools/bregex.c ./src/tools/bpluginfo.c ./src/tools/timelimit.c ./src/tools/fstype.c ./src/lib/htable.c ./src/lib/crypto_nss.c ./src/lib/message.c ./src/lib/runscript.c ./src/lib/lex.c ./src/lib/jcr.c ./src/lib/priv.c ./src/lib/scan.c ./src/lib/alist.c ./src/lib/tree.c ./src/lib/btime.c ./src/lib/mntent_cache.c ./src/lib/var.c ./src/lib/scsi_crypto.c ./src/lib/bnet.c ./src/lib/fnmatch.c ./src/lib/tls_none.c ./src/lib/crypto_cache.c ./src/lib/bregex.c ./src/lib/hmac.c ./src/lib/watchdog.c ./src/lib/guid_to_name.c ./src/lib/plugins.c ./src/lib/bsock_udt.c ./src/lib/bsys.c ./src/lib/bnet_server_tcp.c ./src/lib/binflate.c ./src/lib/crypto_wrap.c ./src/lib/berrno.c ./src/lib/cbuf.c ./src/lib/crypto.c ./src/lib/attr.c ./src/lib/sellist.c ./src/lib/md5.c ./src/lib/tls_nss.c ./src/lib/crypto_gnutls.c ./src/lib/ini.c ./src/lib/dlist.c ./src/lib/edit.c ./src/lib/address_conf.c ./src/lib/tls_gnutls.c ./src/lib/res.c ./src/lib/rwlock.c ./src/lib/bsock.c ./src/lib/bsock_tcp.c ./src/lib/crypto_none.c ./src/lib/devlock.c ./src/lib/attribs.c ./src/lib/parse_bsr.c ./src/lib/workq.c ./src/lib/daemon.c ./src/lib/bsock_sctp.c ./src/lib/cram-md5.c ./src/lib/bsnprintf.c ./src/lib/btimers.c ./src/lib/rblist.c ./src/lib/parse_conf.c ./src/lib/mem_pool.c ./src/lib/compression.c ./src/lib/queue.c ./src/lib/passphrase.c ./src/lib/base64.c ./src/lib/tls_openssl.c ./src/lib/util.c ./src/lib/poll.c ./src/lib/signal.c ./src/lib/breg.c ./src/lib/bget_msg.c ./src/lib/smartall.c ./src/lib/scsi_tapealert.c ./src/lib/serial.c ./src/lib/scsi_lli.c ./src/lib/bpipe.c ./src/lib/sha1.c ./src/lib/lockmgr.c ./src/lib/crypto_openssl.c ./src/filed/restore.c ./src/filed/sd_cmds.c ./src/filed/verify.c ./src/filed/fd_plugins.c ./src/filed/heartbeat.c ./src/filed/verify_vol.c ./src/filed/crypto.c ./src/filed/dir_cmd.c ./src/filed/estimate.c ./src/filed/filed_conf.c ./src/filed/filed.c ./src/filed/compression.c ./src/filed/accurate_htable.c ./src/filed/accurate_lmdb.c ./src/filed/status.c ./src/filed/authenticate.c ./src/filed/accurate.c ./src/filed/fileset.c ./src/filed/backup.c ./src/cats/bdb_priv.h ./src/cats/cats_backends.h ./src/cats/bvfs.h ./src/cats/bdb_postgresql.h ./src/cats/myingres.h ./src/cats/bdb_sqlite.h ./src/cats/sql_glue.h ./src/cats/protos.h ./src/cats/bdb_dbi.h ./src/cats/bdb_ingres.h ./src/cats/bdb_mysql.h ./src/cats/sql_cmds.h ./src/cats/cats.h ./src/console/console_conf.h ./src/console/func.h ./src/console/conio.h ./src/dird/inc_conf.h ./src/dird/ndmp_dma_priv.h ./src/dird/jobq.h ./src/dird/dird_conf.h ./src/dird/protos.h ./src/dird/ua.h ./src/dird/dir_plugins.h ./src/dird/dird.h ./src/dird/bsr.h ./src/win32/compat/include/netinet/tcp.h ./src/win32/compat/include/netinet/in.h ./src/win32/compat/include/dirent.h ./src/win32/compat/include/pwd.h ./src/win32/compat/include/compat.h ./src/win32/compat/include/ms_atl.h ./src/win32/compat/include/getopt.h ./src/win32/compat/include/mingwconfig.h ./src/win32/compat/include/mswinver.h ./src/win32/compat/include/sys/stat.h ./src/win32/compat/include/sys/file.h ./src/win32/compat/include/sys/wait.h ./src/win32/compat/include/sys/ioctl.h ./src/win32/compat/include/sys/socket.h ./src/win32/compat/include/sys/mtio.h ./src/win32/compat/include/sys/time.h ./src/win32/compat/include/syslog.h ./src/win32/compat/include/winhost.h ./src/win32/compat/include/netdb.h ./src/win32/compat/include/stdint.h ./src/win32/compat/include/arpa/inet.h ./src/win32/compat/include/dlfcn.h ./src/win32/compat/include/winsock.h ./src/win32/compat/include/alloca.h ./src/win32/compat/include/grp.h ./src/win32/compat/include/strings.h ./src/win32/compat/include/unistd.h ./src/win32/include/vss.h ./src/win32/include/winapi.h ./src/win32/generic/res.h ./src/win32/generic/protos.h ./src/win32/generic/win32.h ./src/win32/dird/who.h ./src/win32/stored/who.h ./src/win32/stored/backends/win32_tape_device.h ./src/win32/stored/backends/win32_file_device.h ./src/win32/filed/who.h ./src/ndmp/smc.h ./src/ndmp/ndmp_translate.h ./src/ndmp/ndmp2_translate.h ./src/ndmp/ndmos_linux.h ./src/ndmp/ndmos.h ./src/ndmp/ndmlib.h ./src/ndmp/ndmjob.h ./src/ndmp/scsiconst.h ./src/ndmp/ndmp4_translate.h ./src/ndmp/ndmagents.h ./src/ndmp/md5.h ./src/ndmp/wraplib.h ./src/ndmp/ndmp3_enum_strs.h ./src/ndmp/smc_priv.h ./src/ndmp/ndmp0_enum_strs.h ./src/ndmp/ndmjr_none.h ./src/ndmp/ndmp2_enum_strs.h ./src/ndmp/ndmp_ammend.h ./src/ndmp/ndmp_msg_buf.h ./src/ndmp/ndmos_freebsd.h ./src/ndmp/ndmp3_translate.h ./src/ndmp/smc_raw.h ./src/ndmp/ndmp4_enum_strs.h ./src/ndmp/ndmos_solaris.h ./src/ndmp/ndmprotocol.h ./src/ndmp/ndmp9_enum_strs.h ./src/include/host.h ./src/include/hostconfig.h ./src/include/jcr.h ./src/include/bc_types.h ./src/include/version.h ./src/include/fileopts.h ./src/include/bareos.h ./src/include/baconfig.h ./src/include/ch.h ./src/include/config.h ./src/include/streams.h ./src/include/filetypes.h ./src/stored/lock.h ./src/stored/block.h ./src/stored/vol_mgr.h ./src/stored/stored.h ./src/stored/record.h ./src/stored/sd_backends.h ./src/stored/backends/object_store_device.h ./src/stored/backends/unix_tape_device.h ./src/stored/backends/generic_tape_device.h ./src/stored/backends/unix_fifo_device.h ./src/stored/backends/rados_device.h ./src/stored/backends/unix_file_device.h ./src/stored/backends/gfapi_device.h ./src/stored/backends/cephfs_device.h ./src/stored/protos.h ./src/stored/sd_plugins.h ./src/stored/stored_conf.h ./src/stored/dev.h ./src/stored/reserve.h ./src/findlib/protos.h ./src/findlib/savecwd.h ./src/findlib/acl.h ./src/findlib/xattr.h ./src/findlib/find.h ./src/findlib/bfile.h ./src/plugins/stored/python-sd.h ./src/plugins/dird/python-dir.h ./src/plugins/filed/fd_common.h ./src/plugins/filed/python-fd.h ./src/lmdb/lmdb.h ./src/lmdb/midl.h ./src/qt-tray-monitor/monitortab.h ./src/qt-tray-monitor/tray_conf.h ./src/qt-tray-monitor/traymenu.h ./src/qt-tray-monitor/monitoritem.h ./src/qt-tray-monitor/monitoritemthread.h ./src/qt-tray-monitor/systemtrayicon.h ./src/qt-tray-monitor/authenticate.h ./src/qt-tray-monitor/tray-monitor.h ./src/qt-tray-monitor/mainwindow.h ./src/tools/assert_macro.h ./src/qt-console/relabel/relabel.h ./src/qt-console/bat_conf.h ./src/qt-console/restore/restore.h ./src/qt-console/restore/restoretree.h ./src/qt-console/mediaedit/mediaedit.h ./src/qt-console/fileset/fileset.h ./src/qt-console/console/console.h ./src/qt-console/storage/content.h ./src/qt-console/storage/storage.h ./src/qt-console/status/clientstat.h ./src/qt-console/status/storstat.h ./src/qt-console/status/dirstat.h ./src/qt-console/job/job.h ./src/qt-console/joblog/joblog.h ./src/qt-console/mediainfo/mediainfo.h ./src/qt-console/clients/clients.h ./src/qt-console/pages.h ./src/qt-console/mount/mount.h ./src/qt-console/label/label.h ./src/qt-console/joblist/joblist.h ./src/qt-console/jobs/jobs.h ./src/qt-console/bcomm/dircomm.h ./src/qt-console/select/select.h ./src/qt-console/select/textinput.h ./src/qt-console/help/help.h ./src/qt-console/testprogs/putz/putz.h ./src/qt-console/testprogs/examp/mainwindow.h ./src/qt-console/mainwin.h ./src/qt-console/bat.h ./src/qt-console/medialist/medialist.h ./src/qt-console/medialist/mediaview.h ./src/qt-console/run/run.h ./src/qt-console/qstd.h ./src/qt-console/util/fmtwidgetitem.h ./src/qt-console/util/comboutil.h ./src/lib/bsock_sctp.h ./src/lib/waitq.h ./src/lib/btimers.h ./src/lib/rblist.h ./src/lib/parse_conf.h ./src/lib/generic_res.h ./src/lib/mem_pool.h ./src/lib/queue.h ./src/lib/base64.h ./src/lib/workq.h ./src/lib/bits.h ./src/lib/rwlock.h ./src/lib/bsock.h ./src/lib/mutex_list.h ./src/lib/bsock_tcp.h ./src/lib/devlock.h ./src/lib/md5.h ./src/lib/ini.h ./src/lib/dlist.h ./src/lib/address_conf.h ./src/lib/protos.h ./src/lib/scsi_tapealert.h ./src/lib/serial.h ./src/lib/scsi_lli.h ./src/lib/bpipe.h ./src/lib/sha1.h ./src/lib/lockmgr.h ./src/lib/status.h ./src/lib/tcpd.h ./src/lib/smartall.h ./src/lib/breg.h ./src/lib/tree.h ./src/lib/btime.h ./src/lib/mntent_cache.h ./src/lib/var.h ./src/lib/tls.h ./src/lib/alist.h ./src/lib/runscript.h ./src/lib/lex.h ./src/lib/htable.h ./src/lib/bsr.h ./src/lib/bmtio.h ./src/lib/message.h ./src/lib/berrno.h ./src/lib/cbuf.h ./src/lib/crypto.h ./src/lib/attr.h ./src/lib/sellist.h ./src/lib/bsock_udt.h ./src/lib/msg_res.h ./src/lib/crypto_cache.h ./src/lib/bregex.h ./src/lib/watchdog.h ./src/lib/guid_to_name.h ./src/lib/plugins.h ./src/lib/lib.h ./src/lib/scsi_crypto.h ./src/lib/fnmatch.h ./src/filed/protos.h ./src/filed/filed_conf.h ./src/filed/filed.h ./src/filed/accurate.h ./src/filed/backup.h ./src/filed/fd_plugins.h ./src/filed/restore.h ./src/qt-tray-monitor/mainwindow.cpp ./src/qt-tray-monitor/traymenu.cpp ./src/qt-tray-monitor/tray_conf.cpp ./src/qt-tray-monitor/monitoritem.cpp ./src/qt-tray-monitor/systemtrayicon.cpp ./src/qt-tray-monitor/authenticate.cpp ./src/qt-tray-monitor/monitoritemthread.cpp ./src/qt-tray-monitor/tray-monitor.cpp ./src/qt-console/relabel/relabel.cpp ./src/qt-console/restore/restoretree.cpp ./src/qt-console/restore/restore.cpp ./src/qt-console/restore/brestore.cpp ./src/qt-console/restore/prerestore.cpp ./src/qt-console/mediaedit/mediaedit.cpp ./src/qt-console/fileset/fileset.cpp ./src/qt-console/console/console.cpp ./src/qt-console/storage/storage.cpp ./src/qt-console/storage/content.cpp ./src/qt-console/main.cpp ./src/qt-console/status/clientstat.cpp ./src/qt-console/status/dirstat.cpp ./src/qt-console/status/storstat.cpp ./src/qt-console/job/job.cpp ./src/qt-console/joblog/joblog.cpp ./src/qt-console/mediainfo/mediainfo.cpp ./src/qt-console/clients/clients.cpp ./src/qt-console/mount/mount.cpp ./src/qt-console/qstd.cpp ./src/qt-console/pages.cpp ./src/qt-console/bat_conf.cpp ./src/qt-console/label/label.cpp ./src/qt-console/joblist/joblist.cpp ./src/qt-console/jobs/jobs.cpp ./src/qt-console/bcomm/dircomm.cpp ./src/qt-console/select/textinput.cpp ./src/qt-console/select/select.cpp ./src/qt-console/help/help.cpp ./src/qt-console/testprogs/putz/main.cpp ./src/qt-console/testprogs/putz/putz.cpp ./src/qt-console/testprogs/examp/mainwindow.cpp ./src/qt-console/testprogs/examp/main.cpp ./src/qt-console/mainwin.cpp ./src/qt-console/medialist/medialist.cpp ./src/qt-console/medialist/mediaview.cpp ./src/qt-console/run/run.cpp ./src/qt-console/run/estimate.cpp ./src/qt-console/run/prune.cpp ./src/qt-console/run/runcmd.cpp ./src/qt-console/util/comboutil.cpp ./src/qt-console/util/fmtwidgetitem.cpp bareos-Release-14.2.6/po/README000066400000000000000000000022631263011562700157410ustar00rootroot00000000000000 Notes about Bareos translations. -------------------------------- --- To edit .po files, I recommend poedit, downloadable at http://www.poedit.org/ . --- To refresh bareos.pot and *.po, when some strings have been added, modified or removed from the sources files, run: # make update-po --- To refresh Bareos source files list (POTFILES.in), when a source file is added or removed from the repository, run: # make gen-potfiles && make update-po Note, the gen-potfiles pulls in all files found under the top directory. --- To add a new translation language (e.g. German), add a new line to LINGUAS containing the language code (e.g. de), then run: # msginit -l (e.g. "# msginit -l de_DE") Open the newly created file in an editor (e.g. de.po), and look for this line: "Project-Id-Version: ...\n" If it still look like this: "Project-Id-Version: PACKAGE VERSION\n" Correct it to: "Project-Id-Version: Bareos 12.4\n" You may also want to correct the language team to: "Language-Team: German \n" --- For more information, see the gettext manual: http://www.gnu.org/software/gettext/manual/ --- Nicolas Boichat , August 2005 bareos-Release-14.2.6/po/Rules-quot000066400000000000000000000033761263011562700170720ustar00rootroot00000000000000# Special Makefile rules for English message catalogs with quotation marks. DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot .SUFFIXES: .insert-header .po-update-en en@quot.po-create: $(MAKE) en@quot.po-update en@boldquot.po-create: $(MAKE) en@boldquot.po-update en@quot.po-update: en@quot.po-update-en en@boldquot.po-update: en@boldquot.po-update-en .insert-header.po-update-en: @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ ll=`echo $$lang | sed -e 's/@.*//'`; \ LC_ALL=C; export LC_ALL; \ cd $(srcdir); \ if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "creation of $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi en@quot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header en@boldquot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header mostlyclean: mostlyclean-quot mostlyclean-quot: rm -f *.insert-header bareos-Release-14.2.6/po/bareos.pot000066400000000000000000014150761263011562700170730ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Bareos GmbH & Co. KG # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "" #: src/cats/sql.c:789 msgid "Could not init database batch connection\n" msgstr "" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:260 #, c-format msgid "More than one Device!: %d\n" msgstr "" #: src/cats/sql_create.c:265 #, c-format msgid "error fetching Device row: %s\n" msgstr "" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1316 #, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1367 #, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1399 #, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1442 #, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1499 #, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1543 #, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 msgid "Could not init database connection" msgstr "" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "" #: src/cats/ingres.c:82 msgid "Failed to allocate space for query filter.\n" msgstr "" #: src/cats/ingres.c:103 msgid "Failed to allocate space for query filters.\n" msgstr "" #: src/cats/ingres.c:257 #, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" #: src/cats/ingres.c:1031 msgid "A user name for Ingres must be supplied.\n" msgstr "" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 msgid "Quota record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 msgid "Catalog Backends Dir not configured.\n" msgstr "" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:236 #, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "" #: src/console/console_conf.c:143 #, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" #: src/console/console.c:170 msgid "input from file" msgstr "" #: src/console/console.c:171 msgid "output to file" msgstr "" #: src/console/console.c:172 msgid "quit" msgstr "" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "" #: src/console/console.c:174 msgid "sleep specified time" msgstr "" #: src/console/console.c:175 msgid "print current time" msgstr "" #: src/console/console.c:176 msgid "print Console's version" msgstr "" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "" #: src/console/console.c:179 msgid "exit = quit" msgstr "" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "" #: src/console/console.c:181 msgid "help listing" msgstr "" #: src/console/console.c:183 msgid "set command separator" msgstr "" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr "" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "" #: src/console/console.c:996 #, c-format msgid "Can't find %s in Director list\n" msgstr "" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "" #: src/console/console.c:1600 #, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "" #: src/console/console.c:1612 #, c-format msgid "Autochanger error: ERR=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, c-format msgid "Could not get storage resource '%s'.\n" msgstr "" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 msgid "TLS required but not configured in BAREOS.\n" msgstr "" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "" #: src/dird/dird.c:1110 #, c-format msgid "Could not create storage record for %s\n" msgstr "" #: src/dird/dird.c:1119 #, c-format msgid "Could not update storage record for %s\n" msgstr "" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, c-format msgid "Error getting Quota value: ERR=%s" msgstr "" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:88 #, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:102 #, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:170 #, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:312 msgid "rerun these jobids? (yes/no): " msgstr "" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 msgid "Level" msgstr "" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "" #: src/dird/ua_run.c:555 msgid "Restore Client" msgstr "" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "" #: src/dird/ua_run.c:559 msgid "Backup Format" msgstr "" #: src/dird/ua_run.c:560 msgid "When" msgstr "" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "" #: src/dird/ua_run.c:571 msgid "NextPool" msgstr "" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "" #: src/dird/ua_run.c:582 msgid "Where" msgstr "" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 msgid "Please enter Backup Format: " msgstr "" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "" #: src/dird/ua_run.c:730 msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 msgid "Please enter Plugin Options string: " msgstr "" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 msgid "Storage from Run NextPool override" msgstr "" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, c-format msgid "Level \"%s\" not valid.\n" msgstr "" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 msgid "Please enter the path prefix to strip: " msgstr "" #: src/dird/ua_run.c:1035 msgid "Please enter the path prefix to add (/ for none): " msgstr "" #: src/dird/ua_run.c:1046 msgid "Please enter the file suffix to add: " msgstr "" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "" #: src/dird/ua_run.c:1438 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1498 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "" #: src/dird/ua_run.c:1546 #, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "" #: src/dird/ua_run.c:1602 msgid "Run Migration job\n" msgstr "" #: src/dird/ua_run.c:1604 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1870 msgid "NextPool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1886 msgid "Restore Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1894 msgid "Plugin Options specified twice.\n" msgstr "" #: src/dird/ua_run.c:1899 msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "" #: src/dird/ua_run.c:1906 msgid "Spool flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "" #: src/dird/ua_run.c:1922 msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1929 msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "" #: src/dird/ua_run.c:1934 msgid "Accurate flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1941 msgid "Invalid accurate flag.\n" msgstr "" #: src/dird/ua_run.c:1946 msgid "Backup Format specified twice.\n" msgstr "" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "" #: src/dird/ua_status.c:390 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 msgid "No clients defined.\n" msgstr "" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 msgid "Schedule" msgstr "" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "" #: src/dird/ua_status.c:1034 msgid "has terminated with warnings" msgstr "" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, c-format msgid "is waiting on Storage \"%s\"" msgstr "" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, c-format msgid "is waiting for its start time at %s" msgstr "" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 msgid "is waiting for Client to connect to Storage daemon" msgstr "" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "" #: src/dird/ua_status.c:1177 #, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 msgid "No Volumes found, or no barcodes.\n" msgstr "" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr "" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, c-format msgid "Unknown command: %s\n" msgstr "" #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "" #: src/dird/ua_dotcmds.c:1116 #, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1130 #, c-format msgid "List Media failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1156 #, c-format msgid "List Location failed: ERR=%s\n" msgstr "" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "" #: src/dird/ua_input.c:218 msgid "Comment too long.\n" msgstr "" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "" #: src/dird/ua_cmds.c:112 msgid "Configure director" msgstr "" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 msgid "Disable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 msgid "Print current memory usage" msgstr "" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "" #: src/dird/ua_cmds.c:164 msgid "Move slots in an autochanger" msgstr "" #: src/dird/ua_cmds.c:166 msgid "Prune records from catalog" msgstr "" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "" #: src/dird/ua_cmds.c:175 msgid "Restore files" msgstr "" #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 msgid "Rerun a job" msgstr "" #: src/dird/ua_cmds.c:192 msgid "Resolve a hostname" msgstr "" #: src/dird/ua_cmds.c:194 msgid "Run a job" msgstr "" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 msgid "Show resource records" msgstr "" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 msgid "Print current time" msgstr "" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 msgid "Use specific catalog" msgstr "" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 msgid "Print Director version" msgstr "" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, c-format msgid "JobId %s not a number\n" msgstr "" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "" #: src/dird/ua_cmds.c:793 msgid "Failed to set bandwidth limit on Client.\n" msgstr "" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:843 msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, c-format msgid "Client \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1495 msgid "Storage name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1520 #, c-format msgid "%s Failed to resolve %s\n" msgstr "" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, c-format msgid "%s resolves %s to %s\n" msgstr "" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "" #: src/dird/ua_cmds.c:1667 msgid "Accurate value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "" #: src/dird/ua_cmds.c:1696 #, c-format msgid "Wrong job specified of type %s.\n" msgstr "" #: src/dird/ua_cmds.c:1709 msgid "No client specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1714 msgid "No fileset specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, c-format msgid "Illegal JobId %s ignored\n" msgstr "" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "" #: src/dird/ua_cmds.c:1979 #, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr "" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:581 #, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:661 #, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "" #: src/dird/ua_select.c:307 #, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "" #: src/dird/ua_select.c:378 msgid "Select Client resource" msgstr "" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "" #: src/dird/ua_select.c:421 msgid "The defined Schedule resources are:\n" msgstr "" #: src/dird/ua_select.c:432 msgid "Select Schedule resource" msgstr "" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "" #: src/dird/ua_select.c:1093 msgid "Select Drive:\n" msgstr "" #: src/dird/ua_select.c:1098 msgid "Drive" msgstr "" #: src/dird/ua_select.c:1098 msgid "Select drive" msgstr "" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, c-format msgid "Selected Job %d for cancelling\n" msgstr "" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "" #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "" #: src/dird/ua_select.c:1443 #, c-format msgid "Choose Job to %s" msgstr "" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "" #: src/dird/catreq.c:203 #, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "" #: src/dird/catreq.c:344 msgid "1992 Create JobMedia error\n" msgstr "" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, c-format msgid "Attribute create error: ERR=%s" msgstr "" #: src/dird/catreq.c:556 #, c-format msgid "Restore object create error. %s" msgstr "" #: src/dird/catreq.c:564 #, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" #: src/dird/catreq.c:613 #, c-format msgid "attribute create error. %s" msgstr "" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, c-format msgid "read attr spool error. ERR=%s\n" msgstr "" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 msgid "Can't update volume size in the catalog\n" msgstr "" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:819 #, c-format msgid "No Volumes found to perform %s action.\n" msgstr "" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 msgid "for Job" msgstr "" #: src/dird/ua_audit.c:71 msgid "for Client" msgstr "" #: src/dird/ua_audit.c:74 msgid "for Storage" msgstr "" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 msgid "for Schedule" msgstr "" #: src/dird/ua_audit.c:83 msgid "for Pool" msgstr "" #: src/dird/ua_audit.c:86 msgid "for Command" msgstr "" #: src/dird/ua_audit.c:89 msgid "for Fileset" msgstr "" #: src/dird/ua_audit.c:92 msgid "for Catalog" msgstr "" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 msgid "for Plugin Options" msgstr "" #: src/dird/ua_audit.c:114 #, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 msgid "base job" msgstr "" #: src/dird/inc_conf.c:225 #, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "" #: src/dird/inc_conf.c:233 #, c-format msgid "Expected a parseable size, got: %s:" msgstr "" #: src/dird/inc_conf.c:251 #, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:405 #, c-format msgid "Expected a fstype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:428 #, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:450 #, c-format msgid "Expected a meta string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr "" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 msgid "Plugin options failed.\n" msgstr "" #: src/dird/fd_cmds.c:828 msgid "RestoreObject failed.\n" msgstr "" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, c-format msgid "Error opening datafile %s\n" msgstr "" #: src/tests/bbatch.c:339 msgid "Error while inserting file\n" msgstr "" #: src/tests/bvfs_test.c:51 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/cats_test.c:375 #, c-format msgid "Could not open, database \"%s\".\n" msgstr "" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:241 #, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:562 #, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, c-format msgid "%s: Failed to resolve %s\n" msgstr "" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1015 #, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:1025 #, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "" #: src/stored/dir_cmd.c:1030 #, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1038 #, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "" #: src/stored/dir_cmd.c:1042 #, c-format msgid "3905 Unknown wait state %d\n" msgstr "" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1086 #, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1101 #, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1105 #, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "" #: src/stored/dir_cmd.c:1209 #, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "" #: src/stored/dir_cmd.c:1216 #, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "" #: src/stored/dir_cmd.c:1222 #, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "" #: src/stored/dir_cmd.c:1226 #, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1230 #, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1238 #, c-format msgid "3022 Device \"%s\" released.\n" msgstr "" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:1360 #, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "" #: src/stored/dir_cmd.c:1384 #, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1486 #, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" #: src/stored/dir_cmd.c:1489 #, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "" #: src/stored/dir_cmd.c:1492 #, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "" #: src/stored/dir_cmd.c:1496 #, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "" #: src/stored/dir_cmd.c:1500 #, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "" #: src/stored/dir_cmd.c:1505 #, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "" #: src/stored/dir_cmd.c:1507 #, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, c-format msgid "Bad passiveclientcmd command: %s" msgstr "" #: src/stored/dir_cmd.c:1673 msgid "File Daemon" msgstr "" #: src/stored/dir_cmd.c:1679 #, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1690 msgid "Failed to authenticate File daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1724 #, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, c-format msgid "Encountered an unknown stream type %d\n" msgstr "" #: src/stored/ndmp_tape.c:590 #, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:749 msgid "Creating virtual file attributes failed.\n" msgstr "" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, c-format msgid "Read session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 msgid "Cannot initialize new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 msgid "Cannot initialize new NDMA connection\n" msgstr "" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "" #: src/stored/ndmp_tape.c:1414 #, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, c-format msgid "Error in poll: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1557 #, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, c-format msgid "FD command not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:272 msgid "Append data error.\n" msgstr "" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:432 #, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "" #: src/stored/stored_conf.c:874 #, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, c-format msgid "%s has an unknown device type %d\n" msgstr "" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:353 #, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:360 #, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "" #: src/stored/append.c:161 #, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:169 #, c-format msgid "Malformed data header from %s: %s\n" msgstr "" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 msgid "" "\n" "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:985 msgid "" "\n" "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 msgid "Flush block failed.\n" msgstr "" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 msgid "Job canceled.\n" msgstr "" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "" #: src/stored/spool.c:701 #, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:716 #, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/reserve.c:84 #, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "" #: src/stored/reserve.c:258 msgid "3939 Could not get dcr\n" msgstr "" #: src/stored/reserve.c:366 #, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "" #: src/stored/mac.c:454 msgid "Read device not properly initialized.\n" msgstr "" #: src/stored/mac.c:479 msgid "Cannot set buffer size SD->SD.\n" msgstr "" #: src/stored/mac.c:496 #, c-format msgid "Bad response to start replicate: %s\n" msgstr "" #: src/stored/mac.c:501 msgid "Bad response from stored to start replicate command\n" msgstr "" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, c-format msgid "Unable to parse device %s.\n" msgstr "" #: src/stored/backends/rados_device.c:62 #, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:69 #, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:77 #, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:89 #, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:271 #, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:278 #, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, c-format msgid "Request for unknown devicetype: %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:317 #, c-format msgid "Unable to parse device URI %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:329 #, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/cephfs_device.c:58 #, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:65 #, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:72 #, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:101 #, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/cephfs_device.c:111 #, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, c-format msgid "Failed to create a new context using config %s\n" msgstr "" #: src/stored/backends/object_store_device.c:190 #, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:274 #, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:298 #, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:406 #, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:416 #, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 msgid "waiting for" msgstr "" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 msgid "waiting for sysop intervention" msgstr "" #: src/stored/status.c:275 msgid "unknown state" msgstr "" #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "" #: src/stored/status.c:332 #, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "" #: src/stored/status.c:336 #, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "" #: src/stored/status.c:369 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "" #: src/stored/status.c:523 #, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 msgid "Attached Jobs: " msgstr "" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, c-format msgid " File=%u block=%u\n" msgstr "" #: src/stored/status.c:610 #, c-format msgid " Min block=%u Max block=%u\n" msgstr "" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr "" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, c-format msgid "3900 No arg in status command: %s\n" msgstr "" #: src/stored/status.c:984 #, c-format msgid "3900 No arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1033 #, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:131 msgid "Unable to authenticate Storage daemon\n" msgstr "" #: src/stored/sd_cmds.c:182 #, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "" #: src/stored/sd_cmds.c:185 msgid "Command error with SD, hanging up.\n" msgstr "" #: src/stored/sd_cmds.c:197 #, c-format msgid "SD command not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:338 msgid "Replicate data error.\n" msgstr "" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:133 #, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:257 #, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, c-format msgid "Could not reserve volume %s on %s\n" msgstr "" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 msgid "Error updating Catalog\n" msgstr "" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "" #: src/stored/mount.c:741 #, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" #: src/stored/block.c:644 #, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 msgid "Error sending Volume info to Director.\n" msgstr "" #: src/stored/block.c:949 msgid "Job failed or canceled.\n" msgstr "" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "" #: src/stored/lock.c:489 msgid "unknown blocked code" msgstr "" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:310 #, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:324 #, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "" #: src/stored/autochanger.c:699 msgid "3306 Issuing autochanger transfer command.\n" msgstr "" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "" #: src/stored/bcopy.c:60 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 msgid "Quota Exceeded. Job Terminated.\n" msgstr "" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:650 #, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:981 #, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1965 #, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2292 #, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:2321 #, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" #: src/findlib/find.c:180 #, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "" #: src/findlib/bfile.c:92 msgid "File data" msgstr "" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "" #: src/findlib/bfile.c:98 msgid "Compressed data" msgstr "" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "" #: src/findlib/bfile.c:106 msgid "Compressed sparse data" msgstr "" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:118 msgid "Win32 compressed data" msgstr "" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "" #: src/findlib/bfile.c:142 msgid "Encrypted compressed data" msgstr "" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:146 msgid "Encrypted Win32 Compressed data" msgstr "" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:168 msgid "TRU64 Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:170 msgid "TRU64 Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:172 msgid "Solaris Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:174 msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:176 msgid "AFS Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:178 msgid "AIX Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:180 msgid "AIX Specific NFSv4 ACL attribs" msgstr "" #: src/findlib/bfile.c:182 msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:184 msgid "GNU Hurd Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:186 msgid "GNU Hurd Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:188 msgid "GNU Hurd Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:190 msgid "IRIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:192 msgid "TRU64 Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:194 msgid "AIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "" #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "" #: src/findlib/find_one.c:268 #, c-format msgid "%s: mtime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:275 #, c-format msgid "%s: ctime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, c-format msgid "%s: size changed during backup.\n" msgstr "" #: src/findlib/find_one.c:729 #, c-format msgid "%s: File name too long [%d]\n" msgstr "" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:293 #, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:495 #, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:929 #, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:967 #, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1000 #, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1683 #, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2196 #, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2225 #, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, c-format msgid "Unparseable size option: %s\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, c-format msgid "Unexpected autodeflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:368 #, c-format msgid "Unexpected autoinflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 msgid "Plugin File argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:916 msgid "Plugin Reader argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:922 msgid "Plugin Writer argument not specified.\n" msgstr "" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, c-format msgid "Enter Key Encryption Key: " msgstr "" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, c-format msgid "Cannot open keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:401 #, c-format msgid "Enter Encryption Key: " msgstr "" #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:177 #, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, c-format msgid "Failed to connect to mailhost %s\n" msgstr "" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 msgid "BAREOS Message" msgstr "" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:1054 #, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "" #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "" #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "" #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "" #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "" #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "" #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr "" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr "" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr "" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr "" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr "" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "" #: src/lib/lex.c:140 #, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:144 #, c-format msgid "Config warning: %s\n" msgstr "" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 msgid "string" msgstr "" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 msgid "include" msgstr "" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "" #: src/lib/jcr.c:248 msgid "Copying" msgstr "" #: src/lib/jcr.c:250 msgid "Migration" msgstr "" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "" #: src/lib/jcr.c:265 msgid "backup" msgstr "" #: src/lib/jcr.c:267 msgid "verified" msgstr "" #: src/lib/jcr.c:269 msgid "restored" msgstr "" #: src/lib/jcr.c:269 msgid "restore" msgstr "" #: src/lib/jcr.c:271 msgid "archived" msgstr "" #: src/lib/jcr.c:271 msgid "archive" msgstr "" #: src/lib/jcr.c:273 msgid "copied" msgstr "" #: src/lib/jcr.c:273 msgid "copy" msgstr "" #: src/lib/jcr.c:275 msgid "migrated" msgstr "" #: src/lib/jcr.c:275 msgid "migrate" msgstr "" #: src/lib/jcr.c:277 msgid "scanned" msgstr "" #: src/lib/jcr.c:277 msgid "scan" msgstr "" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "" #: src/lib/jcr.c:394 #, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:108 #, c-format msgid "prctl failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:112 #, c-format msgid "setreuid failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 msgid "unknown error" msgstr "" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 msgid "Encryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:251 msgid "Encryption Mode: External\n" msgstr "" #: src/lib/scsi_crypto.c:256 msgid "Encryption Mode: Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 msgid "Volume encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:460 msgid "Compression Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 msgid "Encryption Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 msgid "Drive encryption status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "" #: src/lib/bnet.c:326 msgid "No problem." msgstr "" #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "" #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "" #: src/lib/crypto_cache.c:160 #, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 msgid "Volumename" msgstr "" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 msgid "EncryptionKey" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Added" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:274 #, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 msgid "No error" msgstr "" #: src/lib/crypto.c:176 msgid "Signer not found" msgstr "" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 msgid "Selection item too large.\n" msgstr "" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "" #: src/lib/ini.c:262 src/lib/ini.c:274 #, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:312 src/lib/ini.c:324 #, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:560 src/lib/ini.c:672 #, c-format msgid "Cannot open config file %s: %s\n" msgstr "" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, c-format msgid "Error loading CA certificates from %s\n" msgstr "" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "" #: src/lib/tls_gnutls.c:201 #, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "" #: src/lib/tls_gnutls.c:216 #, c-format msgid "Failed to load DH file %s\n" msgstr "" #: src/lib/tls_gnutls.c:224 msgid "Failed to generate new DH parameters\n" msgstr "" #: src/lib/tls_gnutls.c:289 #, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "" #: src/lib/res.c:830 #, c-format msgid "expected a speed number, got: %s" msgstr "" #: src/lib/res.c:835 msgid "unknown unit type encountered" msgstr "" #: src/lib/res.c:853 #, c-format msgid "expected a %s, got: %s" msgstr "" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "" #: src/lib/bsock.c:139 msgid "attr spool I/O error.\n" msgstr "" #: src/lib/bsock.c:276 #, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" #: src/lib/bsock.c:311 #, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:321 #, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "" #: src/lib/bsock.c:330 #, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "" #: src/lib/bsock.c:341 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:186 #, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:269 #, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:292 #, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:632 msgid "Could not malloc BSOCK data buffer\n" msgstr "" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "" #: src/lib/devlock.c:322 msgid "writeunlock called too many times.\n" msgstr "" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:542 #, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "" #: src/lib/parse_conf.c:149 msgid "Config filename too long.\n" msgstr "" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "" #: src/lib/compression.c:88 msgid "GZIP compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:91 msgid "LZO2 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:94 msgid "LZFZ compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:97 msgid "LZ4 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:100 msgid "LZ4HC compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 msgid "Failed to initialize ZLIB compression\n" msgstr "" #: src/lib/compression.c:215 msgid "Failed to initialize LZO compression\n" msgstr "" #: src/lib/compression.c:270 msgid "Failed to initialize FASTLZ compression\n" msgstr "" #: src/lib/compression.c:300 msgid "LZO init failed\n" msgstr "" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "" #: src/lib/compression.c:371 #, c-format msgid "Compression LZO error: %d\n" msgstr "" #: src/lib/compression.c:402 #, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "" #: src/lib/compression.c:413 #, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "" #: src/lib/compression.c:592 #, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 msgid "Compressed data stream found, but compression not configured!\n" msgstr "" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 msgid "Error loading revocation list file" msgstr "" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 msgid "Running" msgstr "" #: src/lib/util.c:214 msgid "Blocked" msgstr "" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "" #: src/lib/util.c:238 msgid "Verify differences" msgstr "" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "" #: src/lib/util.c:302 msgid "Completed successfully" msgstr "" #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "" #: src/lib/util.c:311 msgid "Fatal error" msgstr "" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "" #: src/lib/util.c:320 msgid "Verify found differences" msgstr "" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "" #: src/lib/util.c:369 msgid "Differences" msgstr "" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "" #: src/lib/util.c:391 msgid "Migrated Job" msgstr "" #: src/lib/util.c:394 msgid "Verify" msgstr "" #: src/lib/util.c:397 msgid "Restore" msgstr "" #: src/lib/util.c:400 msgid "Console" msgstr "" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "" #: src/lib/util.c:412 msgid "Job Copy" msgstr "" #: src/lib/util.c:415 msgid "Copy" msgstr "" #: src/lib/util.c:418 msgid "Migrate" msgstr "" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "" #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "" #: src/lib/util.c:479 msgid "Verify Data" msgstr "" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 msgid "Append" msgstr "" #: src/lib/util.c:500 msgid "Disabled" msgstr "" #: src/lib/util.c:502 msgid "Used" msgstr "" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 msgid "Recycle" msgstr "" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 msgid "Invalid volume status" msgstr "" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "" #: src/lib/signal.c:152 src/lib/signal.c:154 #, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "" #: src/lib/signal.c:323 msgid "Hangup" msgstr "" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "" #: src/lib/signal.c:325 msgid "Quit" msgstr "" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "" #: src/lib/signal.c:335 msgid "BUS error" msgstr "" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "" #: src/lib/signal.c:343 msgid "Termination" msgstr "" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "" #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:92 #, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:314 #, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:323 #, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "" #: src/lib/scsi_lli.c:348 #, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "" #: src/lib/scsi_lli.c:464 #, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "" #: src/lib/crypto_openssl.c:749 msgid "No signers found for crypto verify.\n" msgstr "" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1615 #, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, c-format msgid "Could not set Finder Info on %s\n" msgstr "" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, c-format msgid "Cannot open resource fork for %s.\n" msgstr "" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "" #: src/filed/dir_cmd.c:933 #, c-format msgid "Bad RunAfter command: %s\n" msgstr "" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1015 #, c-format msgid "Bad Plugin Options command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1066 #, c-format msgid "Bad RestoreObject command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1166 msgid "2909 Bad RestoreObject command.\n" msgstr "" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "" #: src/filed/dir_cmd.c:1696 #, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1708 #, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "" #: src/filed/filed.c:61 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, c-format msgid "Unable to create MDB environment: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:81 #, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:90 #, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:97 #, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:103 #, c-format msgid "Unable to start a write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:109 #, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, c-format msgid "Unable insert new data: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, c-format msgid "Unable close write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, c-format msgid "Unable to create write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:249 #, c-format msgid "Unable to create read transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, c-format msgid "Unable to renew read transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, c-format msgid "Unable create cursor: %s\n" msgstr "" #: src/filed/status.c:87 #, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, c-format msgid " %s%s %s Job started: %s\n" msgstr "" #: src/filed/status.c:201 #, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr "" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "" #: src/filed/authenticate.c:301 #, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, c-format msgid "Cannot verify checksum for %s\n" msgstr "" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr "" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:79 #, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:139 msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "" #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "" bareos-Release-14.2.6/po/boldquot.sed000066400000000000000000000003311263011562700174010ustar00rootroot00000000000000s/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g s/“/“/g s/”/”/g s/‘/‘/g s/’/’/g bareos-Release-14.2.6/po/de.po000066400000000000000000016370201263011562700160170ustar00rootroot00000000000000# translation of de.po to # German translations for Bareos package # German messages for Bareos. # Copyright (C) 2005-2006 Free Software Foundation Europe e.V. # This file is distributed under the same license as the Bareos package. # # , 2005. # Philipp Storz , 2007. msgid "" msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2007-06-25 20:38+0200\n" "Last-Translator: Philipp Storz \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: KBabel 1.11.4\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" "Abfrage %s gescheitert:\n" "%s\n" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" "einfgen %s gescheitert:\n" "%s\n" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "Problem beim Einfgen: affected_rows=%s\n" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" "Aktualisierung %s gescheitert:\n" "%s\n" #: src/cats/sql.c:285 #, fuzzy, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "Aktualisierungsproblem: affected_rows=%s\n" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" "lschen von %s fehlgeschlagen:\n" "%s\n" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "Fehler beim holen von Zeile: %s\n" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "Pfadlnge ist null. Datei=%s\n" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "Keine Ergebnisse zu \"list\" Kommando.\n" #: src/cats/sql.c:789 #, fuzzy msgid "Could not init database batch connection\n" msgstr "Konnte Datenbank \"%s\" nicht ffen.\n" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, fuzzy, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "Kann Verbindung zu PostgreSQL Server nicht aufbauen.\n" "Datenbank=%s Benutzer=%s\n" "Der Datenbankserver luft mglicherweise nicht oder das Passwort ist nicht " "korrekt.\n" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "Attribute create error. %s" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "Abfrage gescheitert: %s: ERR=%s\n" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, fuzzy, c-format msgid "error starting batch mode: %s" msgstr "Fehler beim holen von Zeile: %s\n" #: src/cats/dbi.c:1443 #, fuzzy, c-format msgid "error inserting batch mode: %s" msgstr "Fehler beim holen von Zeile: %s\n" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 #, fuzzy msgid "Driver type not specified in Catalog resource.\n" msgstr "Schlsselwort %s ist in dieser Ressource nicht erlaubt." #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "" #: src/cats/dbi.c:1490 #, fuzzy msgid "A user name for DBI must be supplied.\n" msgstr "Ein Benutzername fr MySQL muss angegeben werden.\n" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "Erzeugung von DB Job Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "Erzeugung von JobMedia Eintrag %s fehlgeschlagen: ERR=%s\n" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "Aktualisierung von Media Eintrag %s fehlgeschlagen: ERR=%s\n" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "pool Eintrag %s bereits vorhanden\n" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "Erzeugung von db Pool Eintrag %s fehlgeschlagen: ERR=%s\n" #: src/cats/sql_create.c:260 #, fuzzy, c-format msgid "More than one Device!: %d\n" msgstr "Mehr als ein Client!: %d\n" #: src/cats/sql_create.c:265 #, fuzzy, c-format msgid "error fetching Device row: %s\n" msgstr "Fehler beim holen von Zeile: %s\n" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "Erzeugung von db Device Eintrag %s fehlgeschlagen: ERR=%s\n" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "Mehr als ein Storage Eintrag!: %d\n" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "Fehler beim holen der Storage Zeile: %s\n" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "Erzeugung des DB Storage Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "Medientyp Eintrag %s bereits vorhanden\n" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "Erzeuge db Medientyp Eintrag %s fehlgeschlagen: ERR=%s\n" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "Volume \"%s\" bereits vorhanden.\n" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "Erzeugung DB Media Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "Mehr als ein Client!: %d\n" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "Fehler beim holen der Client Zeile: %s\n" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "Erzeugung des DB Client Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "Mehr als ein Pfad!: %s fr Pfad: %s\n" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "Erzeugung des db Path Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "Erzeugung des DB Counters Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "Mehr als ein FileSet!: %d\n" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "Fehler beim holen der FileSet Zeile: ERR=%s\n" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "Erzeugung des DB FileSet Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "Erzeugung des db File Eintrags %s fehlgeschlagen. ERR=%s" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "Mehr als ein Dateiname! %s fr Datei: %s\n" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "Fehler beim Holen der Zeile fr Datei=%s: ERR=%s\n" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "Erzeugung des db Filename Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "Versuche \"non-attributes\" in catalog einzufgen. Stream=%d\n" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, fuzzy, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "Erzeugung des db File Eintrags %s fehlgeschlagen. ERR=%s" #: src/cats/sql_create.c:1316 #, fuzzy, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "Erzeugung von DB Job Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1367 #, fuzzy, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "Erzeugung DB Media Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1399 #, fuzzy, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "Erzeugung von DB Job Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1442 #, fuzzy, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "Erzeugung von DB Job Eintrag %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1499 #, fuzzy, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "Erzeugung des DB FileSet Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/sql_create.c:1543 #, fuzzy, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "Erzeugung des DB Client Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/cats/mysql.c:197 #, fuzzy, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" "Kann Verbindung zu MySQL Server nicht aufbauen. \n" "Datenbank=%s Benutzer=%s\n" "Der Datenbankserver luft mglicherweise nicht oder das Passwort ist nicht " "korrekt.\n" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "Ein Benutzername fr MySQL muss angegeben werden.\n" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "Kein pool Eintrag %s vorhanden\n" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "Erwartete einen \"pool\" Eintrag, erhielt %d\n" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "Fehler beim Holen der Zeile %s\n" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" "Fehler bei Abfrage von Startzeit: ERR=%s\n" "CMD=%s\n" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "Keinen vorherigen \"Full backup\" Job Eintrag gefunden.\n" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "Unbekannter level=%d\n" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" "Kein \"Job\" Eintrag gefunden: ERR=%s\n" "CMD=%s\n" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "Unbekannter Job level=%d\n" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "Kein Job gefunden fr: %s.\n" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "Keinen Job gefunden fr: %s\n" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "" "Anforderung von \"Volume item\" %d grer als Max %d oder weniger als 1\n" #: src/cats/sql_find.c:396 #, fuzzy, c-format msgid "No Volume record found for item %d.\n" msgstr "Kein Volume Eintrag gefunden fr item %d.\n" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "Abfrage fehlgeschlagen: %s\n" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, fuzzy, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "Konnte Datenbank \"%s\" nicht ffen.\n" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 #, fuzzy msgid "Could not init database connection" msgstr "Konnte Datenbank \"%s\" nicht ffen.\n" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "Datenbank %s existiert nicht, bitte erzeugen.\n" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "unbekannt" #: src/cats/ingres.c:82 msgid "Failed to allocate space for query filter.\n" msgstr "" #: src/cats/ingres.c:103 msgid "Failed to allocate space for query filters.\n" msgstr "" #: src/cats/ingres.c:257 #, fuzzy, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" "Kann Verbindung zu MySQL Server nicht aufbauen. \n" "Datenbank=%s Benutzer=%s\n" "Der Datenbankserver luft mglicherweise nicht oder das Passwort ist nicht " "korrekt.\n" #: src/cats/ingres.c:1031 #, fuzzy msgid "A user name for Ingres must be supplied.\n" msgstr "Ein Benutzername fr MySQL muss angegeben werden.\n" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "Fehler beim holen der Zeile: %s\n" #: src/cats/sql_get.c:150 #, fuzzy, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "get_file_record erwartet 1 erhalten rows=%d\n" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "File Eintrag fr PathId=%s FilenameId=%s nicht gefunden.\n" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "File Eintrag nicht im Catalog gefunden.\n" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "Mehr als einen Dateinamen gefunden! : %s fr Datei: %s\n" #: src/cats/sql_get.c:200 #, fuzzy, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "Get DB Filename record %s hat fehlerhaften Eintrag gefunden: %d\n" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "Filename record: %s nicht gefunden.\n" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "Filename record: %s nicht in Catalog gefunden.\n" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "Get DB path record %s fehlerhaften Eintrag gefunden: %s\n" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "Path record: %s nicht gefunden.\n" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "Path record: %s nicht in Catalog gefunden.\n" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "Kein Job fr JobId %s gefunden\n" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "Keine volumes fr JobId=%d gefunden\n" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "Fehler beim Holen von Zeile %d: ERR=%s\n" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "Kein Volume fr JobId %d in Catalog gefunden.\n" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "Pool id select fehlgeschlagen: ERR=%s\n" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "Client id select fehlgeschlagen: ERR=%s\n" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "Mehr als ein Pool!: %s\n" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "Pool Eintrag in Catalog nicht gefunden.\n" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "Mehr als ein Client!: %s\n" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "Client Eintrag nicht in Catalog gefunden\n" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "Mehr als ein Counter!: %d\n" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "Fehler beim Holen der Counter Zeile: %s\n" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "Counter Eintrag: %s in Catalog nicht gefunden.\n" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "Fehler erhalten %s FileSets aber nur einen erwartet!\n" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "FileSet Eintrag \"%s\" nicht gefunden\n" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "FileSet Eintrag in Catalog nicht gefunden.\n" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "Media id select fehlgeschlagen: ERR=%s\n" #: src/cats/sql_get.c:984 #, fuzzy, c-format msgid "query dbids failed: ERR=%s\n" msgstr "Abfrage gescheitert: %s: ERR=%s\n" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "Mehr als ein Volume!: %s\n" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "Media Eintrag MediaId=%s nicht gefunden.\n" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "Media Eintrag fr Volume \"%s\" nicht gefunden.\n" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "Media Eintrag fr MediaId=%u in Catalog nicht gefunden.\n" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "Media Eintrag fr Vol=%s in Catalog nicht gefunden.\n" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, fuzzy, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "Pool id select fehlgeschlagen: ERR=%s\n" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 #, fuzzy msgid "Quota record not found in Catalog.\n" msgstr "Pool Eintrag in Catalog nicht gefunden.\n" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 #, fuzzy msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "Pool Eintrag in Catalog nicht gefunden.\n" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, fuzzy, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "Kann Verbindung zu PostgreSQL Server nicht aufbauen.\n" "Datenbank=%s Benutzer=%s\n" "Der Datenbankserver luft mglicherweise nicht oder das Passwort ist nicht " "korrekt.\n" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "Fehler beim Holen des aktuellen Wertes: %s\n" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, fuzzy, c-format msgid "error ending batch mode: %s" msgstr "Fehler beim holen von Zeile: %s\n" #: src/cats/postgresql.c:1110 #, fuzzy, c-format msgid "error copying in batch mode: %s" msgstr "Fehler beim holen von Zeile: %s\n" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "Ein Benutzername fr PostgreSQL muss angegeben werden.\n" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 msgid "Catalog Backends Dir not configured.\n" msgstr "" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, fuzzy, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:236 #, fuzzy, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "" #: src/console/console_conf.c:143 #, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "%s item wird in %s resource bentigt, wurde aber nicht gefunden.\n" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" "Der Versuch der Definition einer zweiten %s resource mit dem Namen \"%s\" " "ist nicht erlaubt.\n" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" #: src/console/console.c:170 msgid "input from file" msgstr "" #: src/console/console.c:171 msgid "output to file" msgstr "" #: src/console/console.c:172 msgid "quit" msgstr "" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "" #: src/console/console.c:174 msgid "sleep specified time" msgstr "" #: src/console/console.c:175 msgid "print current time" msgstr "" #: src/console/console.c:176 msgid "print Console's version" msgstr "" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "" #: src/console/console.c:179 msgid "exit = quit" msgstr "" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "" #: src/console/console.c:181 msgid "help listing" msgstr "" #: src/console/console.c:183 msgid "set command separator" msgstr "" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr "" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "" #: src/console/console.c:996 #, fuzzy, c-format msgid "Can't find %s in Director list\n" msgstr "Kann Director resource %s nicht finden\n" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "Initialisierung der Verschlsselungsbibliothek fehlgeschlagen.\n" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "TLS bentigt aber nicht konfiguriert in Bareos.\n" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "" #: src/console/console.c:1600 #, fuzzy, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "Kann Ausdruck\"%s\"nicht auflsen: ERR=%s\n" #: src/console/console.c:1612 #, fuzzy, c-format msgid "Autochanger error: ERR=%s\n" msgstr "Attribute create error. %s" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "Pool Ressource" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "Keine Storage Spezifikation in Job oder Pool gefunden.\n" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, fuzzy, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "Start Sicherung JobId %s, Job=%s\n" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, fuzzy, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "Fehler beim Holen des job Eintrags fr den job Bericht: %s" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, fuzzy, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "Fehler beim holen des Datensatzes fr Volume \"%s\": ERR=%s" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "Sicherung OK" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "Sicherung OK -- mit Warnungen" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "*** Sicherungsfehler ***" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "Sicherung Abgebrochen" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "Unangebrachter Beendigungskode: %c\n" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "Konnte Job Eintrag nicht holen. ERR=%s\n" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "Konnte Job Volume Parameter nicht holen. ERR=%s\n" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/dird/bsr.c:287 #, fuzzy msgid "No files found to read. No bootstrap file written.\n" msgstr "" "Keine Dateien fr Wiederherstellung/Migration gefunden. Keine Bootstrap " "Datei geschrieben.\n" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "Fehler beim schreiben der bsr Datei.\n" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "Bootstrap Eintrge geschrieben nach %s\n" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" "Der Job wird folgendes bentigen:\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "Keine Volumes zum Wiederherstellen gefunden.\n" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "Kann bootstrap Datei nicht ffnen: %s: ERR=%s\n" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, fuzzy, c-format msgid "Could not get storage resource '%s'.\n" msgstr "Kann Storage resource %s nicht finden\n" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "Starte Admin JobId %d, Job=%s\n" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "Admin OK" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "*** Admin Fehler ***" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "Admin abgebrochen" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "zu viele offene reload Anforderungen, Anforderung ignoriert.\n" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "Keine reload table Eintrge brig. Gebe auf.\n" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "Vorherige Konfiguration zurckgesetzt.\n" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" "Keine Director resource definiert in %s\n" "Ohne dies weiss ich nicht wer ich bin :-(\n" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "Keine Messages resource definiert in %s\n" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "Nur eine Director resource erlaubt in %s\n" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 #, fuzzy msgid "TLS required but not configured in BAREOS.\n" msgstr "TLS bentigt aber nicht konfiguriert in Bareos.\n" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "\"TLS Certificate\" Datei nicht fr Director definiert \"%s\" in %s.\n" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "\"TLS Key\" Datei nicht fr Director definiert \"%s\" in %s.\n" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Weder \"TLS CA Certificate\" noch \"TLS CA Certificate Dir\" sind fr " "Director \"%s\" in %s definert. Mindestens ein CA certificate store wird " "bentigt wenn \"TLS Verify Peer\" eingesetzt wird.\n" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "Konnte TLS context fr Director nicht initialisieren \"%s\" in %s.\n" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "Keine Job records definiert in %s\n" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "\"TLS Certificate\" Datei nicht definiert fr Console \"%s\" in %s.\n" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "\"TLS Key\" Datei nicht definiert fr Console \"%s\" in %s.\n" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Weder \"TLS CA Certificate\" noch \"TLS CA Certificate Dir\" sind definiert " "frConsole \"%s\" in %s. Mindestens ein CA certificate store wird bentigt " "beiEinsatz von \"TLS Verify Peer\".\n" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" "Konnte TLS context fr File daemon \"%s\" in %s nicht initialisieren.\n" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" "Weder \"TLS CA Certificate\" noch \"TLS CA Certificate Dir\" sind definiert " "fr File daemon \"%s\" in %s.\n" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" "Weder \"TLS CA Certificate\" noch \"TLS CA Certificate Dir\" sind definiert " "frStorage \"%s\" in %s.\n" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "Konnte TLS context fr Storage \"%s\" in %s nicht initialisieren.\n" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, fuzzy, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "Konnte Catalog \"%s\", database \"%s\" nicht ffnen.\n" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "Konnte Catalog \"%s\", database \"%s\" nicht ffnen.\n" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "" #: src/dird/dird.c:1110 #, fuzzy, c-format msgid "Could not create storage record for %s\n" msgstr "Kann Storage resource %s nicht finden\n" #: src/dird/dird.c:1119 #, fuzzy, c-format msgid "Could not update storage record for %s\n" msgstr "Kann Storage resource %s nicht finden\n" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Konnte regex pattern \"%s\" nicht kompilieren ERR=%s\n" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" "Ende automatische Suberung.\n" "\n" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, fuzzy, c-format msgid "Error getting Quota value: ERR=%s" msgstr "Fehler beim Holen von Zeile %d: ERR=%s\n" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, fuzzy, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "Fehler beim Holen der Zeile fr Datei=%s: ERR=%s\n" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, fuzzy, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "Fehler beim Holen der Zeile fr Datei=%s: ERR=%s\n" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, fuzzy, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "Fehler beim Holen des job Eintrags fr den job Bericht: %s" #: src/dird/ua_run.c:88 #, fuzzy, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "Fehler beim holen des Datensatzes fr Volume \"%s\": ERR=%s" #: src/dird/ua_run.c:102 #, fuzzy, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "Fehler beim Holen des job Eintrags fr den job Bericht: %s" #: src/dird/ua_run.c:170 #, fuzzy, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "Fehler beim holen des Datensatzes fr Volume \"%s\": ERR=%s" #: src/dird/ua_run.c:312 msgid "rerun these jobids? (yes/no): " msgstr "" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 msgid "Level" msgstr "" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "Job" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "" #: src/dird/ua_run.c:555 #, fuzzy msgid "Restore Client" msgstr "Wiederherstellung luft..." #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "" #: src/dird/ua_run.c:559 #, fuzzy msgid "Backup Format" msgstr "Sicherung OK" #: src/dird/ua_run.c:560 msgid "When" msgstr "" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "" #: src/dird/ua_run.c:571 #, fuzzy msgid "NextPool" msgstr " opcmd=%s\n" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "" #: src/dird/ua_run.c:582 msgid "Where" msgstr "" #: src/dird/ua_run.c:583 #, fuzzy msgid "File Relocation" msgstr "File daemon" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 msgid "Please enter Backup Format: " msgstr "" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "" #: src/dird/ua_run.c:730 msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 msgid "Please enter Plugin Options string: " msgstr "" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 #, fuzzy msgid "Storage from Run NextPool override" msgstr "Storage aus der \"NextPool\" Ressource des Pools." #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, fuzzy, c-format msgid "Level \"%s\" not valid.\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 msgid "Please enter the path prefix to strip: " msgstr "" #: src/dird/ua_run.c:1035 msgid "Please enter the path prefix to add (/ for none): " msgstr "" #: src/dird/ua_run.c:1046 msgid "Please enter the file suffix to add: " msgstr "" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "" #: src/dird/ua_run.c:1084 #, fuzzy, c-format msgid "%s -> %s\n" msgstr " --> Run=%s\n" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, fuzzy, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "Konnte job record fr JobId %s zum migrieren nicht holen. ERR=%s" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "" #: src/dird/ua_run.c:1438 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1498 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, fuzzy, c-format msgid "Where: %s\n" msgstr " opcmd=%s\n" #: src/dird/ua_run.c:1546 #, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "" #: src/dird/ua_run.c:1602 #, fuzzy msgid "Run Migration job\n" msgstr "Konnte Migrationsjob nicht starten.\n" #: src/dird/ua_run.c:1604 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1870 #, fuzzy msgid "NextPool specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1886 #, fuzzy msgid "Restore Client specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1894 #, fuzzy msgid "Plugin Options specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1899 msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "" #: src/dird/ua_run.c:1906 #, fuzzy msgid "Spool flag specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1913 #, fuzzy msgid "Invalid spooldata flag.\n" msgstr "Ungltige JobId gefunden.\n" #: src/dird/ua_run.c:1922 #, fuzzy msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1929 #, fuzzy msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "Ungltige JobId gefunden.\n" #: src/dird/ua_run.c:1934 #, fuzzy msgid "Accurate flag specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1941 #, fuzzy msgid "Invalid accurate flag.\n" msgstr "Ungltige JobId gefunden.\n" #: src/dird/ua_run.c:1946 #, fuzzy msgid "Backup Format specified twice.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, fuzzy, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "" #: src/dird/ua_status.c:390 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 #, fuzzy msgid "No clients defined.\n" msgstr "Keine %s resource definiert\n" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 #, fuzzy msgid "Schedule" msgstr "Schedule: name=%s\n" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "" #: src/dird/ua_status.c:1034 #, fuzzy msgid "has terminated with warnings" msgstr "%s OK -- mit Warnungen" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, fuzzy, c-format msgid "is waiting on Storage \"%s\"" msgstr "Storage daemon" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, fuzzy, c-format msgid "is waiting for its start time at %s" msgstr "Job %s wartet %d Sekunden auf die geplante Startzeit.\n" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, fuzzy, c-format msgid "is in unknown state %c" msgstr "unbekannt" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 #, fuzzy msgid "is waiting for Client to connect to Storage daemon" msgstr "Verbindung zu Storage daemon fehlgeschlagen.\n" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "" #: src/dird/ua_status.c:1177 #, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 #, fuzzy msgid "OK -- with warnings" msgstr "%s OK -- mit Warnungen" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 #, fuzzy msgid "No Volumes found, or no barcodes.\n" msgstr "Keine Volumes zum Wiederherstellen gefunden.\n" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, fuzzy, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "Konnte counter %s: nicht aktualisieren: ERR=%s\n" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "Kann var context nicht erzeugen: ERR=%s\n" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "kann Variable callback nicht setzen: ERR=%s\n" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "kann Variable operate nicht setzen: ERR=%s\n" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "Cannot unescape string: ERR=%s\n" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "Kann Ausdruck\"%s\"nicht auflsen: ERR=%s\n" #: src/dird/expand.c:527 #, fuzzy, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "kann Variable context nicht zerstren: ERR=%s\n" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr "" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, fuzzy, c-format msgid "Unknown command: %s\n" msgstr "unbekannt" #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 #, fuzzy msgid "query keyword not found.\n" msgstr "Path record: %s nicht gefunden.\n" #: src/dird/ua_dotcmds.c:1116 #, fuzzy, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "Media id select fehlgeschlagen: ERR=%s\n" #: src/dird/ua_dotcmds.c:1130 #, fuzzy, c-format msgid "List Media failed: ERR=%s\n" msgstr "Media id select fehlgeschlagen: ERR=%s\n" #: src/dird/ua_dotcmds.c:1156 #, fuzzy, c-format msgid "List Location failed: ERR=%s\n" msgstr "Client id select fehlgeschlagen: ERR=%s\n" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, fuzzy, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "Illegales Zeichen in \"Volume name\" \"%s\"\n" #: src/dird/ua_input.c:218 #, fuzzy msgid "Comment too long.\n" msgstr "Job nicht gefunden: %s\n" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "" #: src/dird/ua_cmds.c:112 #, fuzzy msgid "Configure director" msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #: src/dird/ua_cmds.c:114 #, fuzzy msgid "Create DB Pool from resource" msgstr "Pool Ressource" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 #, fuzzy msgid "Disable a job/client/schedule" msgstr "ist nicht aktiviert" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 msgid "Print current memory usage" msgstr "" #: src/dird/ua_cmds.c:161 #, fuzzy msgid "Mount storage" msgstr "Run storage override" #: src/dird/ua_cmds.c:164 #, fuzzy msgid "Move slots in an autochanger" msgstr "unbekannt" #: src/dird/ua_cmds.c:166 #, fuzzy msgid "Prune records from catalog" msgstr "File Eintrag nicht im Catalog gefunden.\n" #: src/dird/ua_cmds.c:168 #, fuzzy msgid "Purge records from catalog" msgstr "File Eintrag nicht im Catalog gefunden.\n" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "" #: src/dird/ua_cmds.c:175 #, fuzzy msgid "Restore files" msgstr "Wiederherstellung luft..." #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 #, fuzzy msgid "Rerun a job" msgstr "Konnte Migrationsjob nicht starten.\n" #: src/dird/ua_cmds.c:192 msgid "Resolve a hostname" msgstr "" #: src/dird/ua_cmds.c:194 #, fuzzy msgid "Run a job" msgstr "Konnte Migrationsjob nicht starten.\n" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 #, fuzzy msgid "Show resource records" msgstr "Job Ressource" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 msgid "Print current time" msgstr "" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 msgid "Use specific catalog" msgstr "" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 msgid "Print Director version" msgstr "" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, c-format msgid "JobId %s not a number\n" msgstr "" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "" #: src/dird/ua_cmds.c:793 msgid "Failed to set bandwidth limit on Client.\n" msgstr "" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "Verbindung zu Storage daemon fehlgeschlagen.\n" #: src/dird/ua_cmds.c:843 #, fuzzy msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "Verbindung zu Storage daemon fehlgeschlagen.\n" #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, fuzzy, c-format msgid "Client \"%s\" %sabled\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, fuzzy, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "Storage daemon" #: src/dird/ua_cmds.c:1495 #, fuzzy msgid "Storage name missing.\n" msgstr "FileSet: name=%s\n" #: src/dird/ua_cmds.c:1520 #, fuzzy, c-format msgid "%s Failed to resolve %s\n" msgstr "Verbindung zu File daemon fehlgeschlagen.\n" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, fuzzy, c-format msgid "%s resolves %s to %s\n" msgstr "%s -- keine Dateien zur Migration." #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, fuzzy, c-format msgid "Fileset \"%s\" not found.\n" msgstr "FileSet Eintrag \"%s\" nicht gefunden\n" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1637 #, fuzzy msgid "Fileset name missing.\n" msgstr "FileSet: name=%s\n" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "" #: src/dird/ua_cmds.c:1667 #, fuzzy msgid "Accurate value missing.\n" msgstr "FileSet: name=%s\n" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "" #: src/dird/ua_cmds.c:1696 #, c-format msgid "Wrong job specified of type %s.\n" msgstr "" #: src/dird/ua_cmds.c:1709 #, fuzzy msgid "No client specified or selected.\n" msgstr "Kein storage angegeben.\n" #: src/dird/ua_cmds.c:1714 #, fuzzy msgid "No fileset specified or selected.\n" msgstr "Keine Volumes zum Wiederherstellen gefunden.\n" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, fuzzy, c-format msgid "Illegal JobId %s ignored\n" msgstr "Clone JobId %d gestartet.\n" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "" #: src/dird/ua_cmds.c:1979 #, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, fuzzy, c-format msgid " %-13s %s\n" msgstr " --> Run=%s\n" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s (%s): %s\n" " JobId: %d\n" " Job: %s\n" " Client: %s\n" " Start time: %s\n" " End time: %s\n" " Dateien erwartet: %s\n" " Dateien. wiederhergestellt: %s\n" " Bytes wiederhergestellt: %s\n" " Geschwindigkeit: %.1f KB/s\n" " FD Fehler: %d\n" " FD Beendigungsstatus: %s\n" " SD Beendigungsstatus: %s\n" " Beendigungsstatus: %s\n" "\n" #: src/dird/verify.c:581 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s (%s): %s\n" " JobId: %d\n" " Job: %s\n" " Client: %s\n" " Start time: %s\n" " End time: %s\n" " Dateien erwartet: %s\n" " Dateien. wiederhergestellt: %s\n" " Bytes wiederhergestellt: %s\n" " Geschwindigkeit: %.1f KB/s\n" " FD Fehler: %d\n" " FD Beendigungsstatus: %s\n" " SD Beendigungsstatus: %s\n" " Beendigungsstatus: %s\n" "\n" #: src/dird/verify.c:661 #, fuzzy, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "" #: src/dird/ua_select.c:307 #, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "" #: src/dird/ua_select.c:378 #, fuzzy msgid "Select Client resource" msgstr "Pool Ressource" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "" #: src/dird/ua_select.c:421 #, fuzzy msgid "The defined Schedule resources are:\n" msgstr "Kann Schedule resource %s nicht finden\n" #: src/dird/ua_select.c:432 #, fuzzy msgid "Select Schedule resource" msgstr "Kann Schedule resource %s nicht finden\n" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "" #: src/dird/ua_select.c:1093 msgid "Select Drive:\n" msgstr "" #: src/dird/ua_select.c:1098 msgid "Drive" msgstr "" #: src/dird/ua_select.c:1098 msgid "Select drive" msgstr "" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, c-format msgid "Selected Job %d for cancelling\n" msgstr "" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "" #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "" #: src/dird/ua_select.c:1443 #, c-format msgid "Choose Job to %s" msgstr "" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "1990 Ungltige Catalog Anfrage: %s" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "Ungltige Catalog Anfrage; DB nicht offen: %s" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "1901 Keine Medien.\n" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "nicht in Pool" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "nicht korrekter Medientyp" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "ist nicht aktiviert" #: src/dird/catreq.c:203 #, fuzzy, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "1998 Volume \"%s\" status ist %s, %s.\n" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "1997 Volume \"%s\" Nicht in Catalog.\n" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "Konnte Media record fr Volume %s nicht holen: ERR=%s\n" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "1991 Catalog Anfrage fr vol=%s fehlgeschlagen: %s" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" "Volume Files bei %u werden auf %u fr Volumen \"%s\" gesetzt. Dies ist nicht " "Korrekt.\n" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "1992 Update Media Fehler. VolFiles=%u, CatFiles=%u\n" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "Catalog Fehler beim Aktualisieren des Media Eintrags. %s" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "1993 Update Media Fehler\n" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "Catalog Fehler beim Erzeugen des JobMedia Eintrags. %s" #: src/dird/catreq.c:344 #, fuzzy msgid "1992 Create JobMedia error\n" msgstr "1991 Update JobMedia Fehler\n" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "Ungltige Catalog Anfrage: %s" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, fuzzy, c-format msgid "Attribute create error: ERR=%s" msgstr "Attribute create error. %s" #: src/dird/catreq.c:556 #, fuzzy, c-format msgid "Restore object create error. %s" msgstr "Attribute create error. %s" #: src/dird/catreq.c:564 #, fuzzy, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "Erhielt %s aber nicht die gleiche Datei wie Attribute\n" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" "Catalog Fehler beim Aktualisieren des file digest. Nicht untersttzter " "digest stream typ: %d" #: src/dird/catreq.c:613 #, fuzzy, c-format msgid "attribute create error. %s" msgstr "Attribute create error. %s" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "Catalog Fehler beim Aktualisieren des file digest. %s" #: src/dird/catreq.c:643 #, fuzzy, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "1991 Ungltige Catalog Aktualisierung: %s" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "Ungltige Catalog Aktualisierung; DB nicht geffnet: %s" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, fuzzy, c-format msgid "read attr spool error. ERR=%s\n" msgstr "Regex bersetzungsfehler. ERR=%s\n" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, fuzzy, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "Mehr als ein Client!: %s\n" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 #, fuzzy msgid "Can't update volume size in the catalog\n" msgstr "Neues Volume \"%s\" in catalog erzeugt.\n" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, fuzzy, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "Kann Konsole \"%s\" an %s:%s:%d nicht authentisieren.\n" #: src/dird/ua_purge.c:819 #, fuzzy, c-format msgid "No Volumes found to perform %s action.\n" msgstr "Keine Volumes zum Wiederherstellen gefunden.\n" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 #, fuzzy msgid "for Job" msgstr "Job" #: src/dird/ua_audit.c:71 #, fuzzy msgid "for Client" msgstr "Wiederherstellung luft..." #: src/dird/ua_audit.c:74 #, fuzzy msgid "for Storage" msgstr "Storage daemon" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 #, fuzzy msgid "for Schedule" msgstr "Schedule: name=%s\n" #: src/dird/ua_audit.c:83 #, fuzzy msgid "for Pool" msgstr "nicht in Pool" #: src/dird/ua_audit.c:86 msgid "for Command" msgstr "" #: src/dird/ua_audit.c:89 #, fuzzy msgid "for Fileset" msgstr "FileSet: name=%s\n" #: src/dird/ua_audit.c:92 msgid "for Catalog" msgstr "" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 #, fuzzy msgid "for Plugin Options" msgstr "Kein storage angegeben.\n" #: src/dird/ua_audit.c:114 #, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 msgid "base job" msgstr "" #: src/dird/inc_conf.c:225 #, fuzzy, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "fstype Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:233 #, fuzzy, c-format msgid "Expected a parseable size, got: %s:" msgstr "regulren Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:251 #, fuzzy, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "FileSet option Schlsselwort erwartet, erhalten:%s:" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "Regex bersetzungsfehler. ERR=%s\n" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "regulren Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "wild-card Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:405 #, fuzzy, c-format msgid "Expected a fstype string, got: %s\n" msgstr "fstype Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:428 #, fuzzy, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "drivetype Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:450 #, fuzzy, c-format msgid "Expected a meta string, got: %s\n" msgstr "regulren Ausdruck erwartet, erhalten: %s\n" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "FileSet Schlsselwort erwartet,erhalten: %s" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "Geschweifte Klammer auf erwartet, erhalten: %s" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "Schlsselwort erwartet, erhalten:%s\n" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "Erwartete ein \"ist gleich\", erhalten: %s" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "Schlsselwort %s ist in dieser Ressource nicht erlaubt." #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, fuzzy, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" "Backslash gefunden. Benutze forward slashes oder setze den String in " "Anfhrungszeichen.: %s\n" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "Dateiname erwartet, erhalten: %s" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "veraltete Include/Exclude Anweisung nicht untersttzt\n" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "File daemon \"%s\" hat Job Kommando abgewiesen: %s\n" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "Fehler beim Aktualisieren des Client Eintrags. ERR=%s\n" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "FD hat fehlerhafte Antwort auf JobId Kommando zurckgegeben: %s\n" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "Nicht implementierter backup level %d %c\n" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "Kann Programm: %s nicht starten. ERR=%s\n" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr ">filed: Schreibfehler auf socket\n" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "Fehler beim Start des Programms: %s. ERR=%s\n" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "Kann inkludierte Datei nicht ffnen: %s. ERR=%s\n" #: src/dird/fd_cmds.c:660 #, fuzzy, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 #, fuzzy msgid "Plugin options failed.\n" msgstr "Kein storage angegeben.\n" #: src/dird/fd_cmds.c:828 #, fuzzy msgid "RestoreObject failed.\n" msgstr "Wiederherstellung luft..." #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, fuzzy, c-format msgid "Error opening datafile %s\n" msgstr "Fehler beim holen von Zeile: %s\n" #: src/tests/bbatch.c:339 #, fuzzy msgid "Error while inserting file\n" msgstr "Fehler beim schreiben der bsr Datei.\n" #: src/tests/bvfs_test.c:51 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/cats_test.c:375 #, fuzzy, c-format msgid "Could not open, database \"%s\".\n" msgstr "Konnte Datenbank \"%s\" nicht ffen.\n" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, fuzzy, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "konnte job cond Variable nicht initialisieren: ERR=%s\n" #: src/stored/dir_cmd.c:241 #, fuzzy, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "konnte job cond Variable nicht initialisieren: ERR=%s\n" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, fuzzy, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:562 #, fuzzy, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "JobId %s, Job %s zum Abbruch markiert.\n" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, fuzzy, c-format msgid "%s: Failed to resolve %s\n" msgstr "Verbindung zu File daemon fehlgeschlagen.\n" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, fuzzy, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 #, fuzzy msgid "Specified slot ignored. " msgstr "SQL fehlgeschlagen ERR=%s\n" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, fuzzy, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1015 #, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:1025 #, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "" #: src/stored/dir_cmd.c:1030 #, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1038 #, fuzzy, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1042 #, fuzzy, c-format msgid "3905 Unknown wait state %d\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, fuzzy, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/stored/dir_cmd.c:1086 #, fuzzy, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1101 #, fuzzy, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/stored/dir_cmd.c:1105 #, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "" #: src/stored/dir_cmd.c:1209 #, fuzzy, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "Device Eintrag %s bereits vorhanden\n" #: src/stored/dir_cmd.c:1216 #, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "" #: src/stored/dir_cmd.c:1222 #, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "" #: src/stored/dir_cmd.c:1226 #, fuzzy, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1230 #, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1238 #, c-format msgid "3022 Device \"%s\" released.\n" msgstr "" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:1360 #, fuzzy, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1384 #, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1486 #, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" #: src/stored/dir_cmd.c:1489 #, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "" #: src/stored/dir_cmd.c:1492 #, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "" #: src/stored/dir_cmd.c:1496 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1500 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1505 #, fuzzy, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "unbekannt" #: src/stored/dir_cmd.c:1507 #, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, fuzzy, c-format msgid "Bad passiveclientcmd command: %s" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/stored/dir_cmd.c:1673 #, fuzzy msgid "File Daemon" msgstr "File daemon" #: src/stored/dir_cmd.c:1679 #, fuzzy, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "Verbindung zu File daemon fehlgeschlagen.\n" #: src/stored/dir_cmd.c:1690 #, fuzzy msgid "Failed to authenticate File daemon.\n" msgstr "Verbindung zu File daemon fehlgeschlagen.\n" #: src/stored/dir_cmd.c:1724 #, fuzzy, c-format msgid "Bad pluginoptionscmd command: %s" msgstr " --> Run=%s\n" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, fuzzy, c-format msgid "Encountered an unknown stream type %d\n" msgstr "unbekannt" #: src/stored/ndmp_tape.c:590 #, fuzzy, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "Job nicht gefunden: %s\n" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:749 #, fuzzy msgid "Creating virtual file attributes failed.\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, fuzzy, c-format msgid "Read session label failed. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, fuzzy, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "Fehler beim Aktualisieren der DB Media Datei. ERR=%s\n" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 msgid "Cannot initialize new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 #, fuzzy msgid "Cannot initialize new NDMA connection\n" msgstr "Konnte Datenbank \"%s\" nicht ffen.\n" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "" #: src/stored/ndmp_tape.c:1414 #, fuzzy, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "Konnte job queue nicht initialiseren: ERR=%s\n" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, fuzzy, c-format msgid "Error in poll: %s\n" msgstr "Fehler beim holen der Zeile: %s\n" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, fuzzy, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "Konnte job queue nicht hinzufgen: ERR=%s\n" #: src/stored/ndmp_tape.c:1557 #, fuzzy, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "Konnte job queue nicht hinzufgen: ERR=%s\n" #: src/stored/fd_cmds.c:114 #, fuzzy, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "Job nicht gefunden: %s\n" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, fuzzy, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "Netzwerkfehler mit FD bei %s: ERR=%s\n" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, fuzzy, c-format msgid "FD command not found: %s\n" msgstr "Job nicht gefunden: %s\n" #: src/stored/fd_cmds.c:272 #, fuzzy msgid "Append data error.\n" msgstr "unbekannt" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, fuzzy, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "FileSet Schlsselwort erwartet,erhalten: %s" #: src/stored/stored_conf.c:432 #, fuzzy, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "FileSet Schlsselwort erwartet,erhalten: %s" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, fuzzy, c-format msgid "Warning: unknown resource type %d\n" msgstr "unbekannt" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "" #: src/stored/stored_conf.c:874 #, fuzzy, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, fuzzy, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "unbekannt\n" #: src/stored/dev.c:225 #, fuzzy, c-format msgid "%s has an unknown device type %d\n" msgstr "unbekannt" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, fuzzy, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/dev.c:353 #, fuzzy, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/dev.c:360 #, fuzzy, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, fuzzy, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, fuzzy, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" "Keine Director resource definiert in %s\n" "Ohne dies weiss ich nicht wer ich bin :-(\n" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, fuzzy, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "Konnte Client Eintrag nicht anlegen. ERR=%s\n" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, fuzzy, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "Netzwerkfehler mit FD bei %s: ERR=%s\n" #: src/stored/append.c:161 #, fuzzy, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "Fehler beim Lesen der catalog DB Steuerdatei. ERR=%s\n" #: src/stored/append.c:169 #, fuzzy, c-format msgid "Malformed data header from %s: %s\n" msgstr "Nicht wohlgeformte Nachricht: %s\n" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, fuzzy, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "Netzwerkfehler mit FD bei %s: ERR=%s\n" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 #, fuzzy msgid "" "\n" "Error writing record to block.\n" msgstr "Fehler beim schreiben der bsr Datei.\n" #: src/stored/btape.c:985 #, fuzzy msgid "" "\n" "Error writing block to device.\n" msgstr "Fehler beim schreiben der bsr Datei.\n" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 #, fuzzy msgid "Flush block failed.\n" msgstr "Job Einrichtung Fehlgeschlagen.\n" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 #, fuzzy msgid "Job canceled.\n" msgstr "%s Abgebrochen" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 #, fuzzy msgid "Network error on BlastAttributes.\n" msgstr "SD.\n" msgstr "" #: src/stored/mac.c:496 #, fuzzy, c-format msgid "Bad response to start replicate: %s\n" msgstr "Schlechte Antwort auf %s Kommando: erwartet %s, erhalten %s\n" #: src/stored/mac.c:501 #, fuzzy msgid "Bad response from stored to start replicate command\n" msgstr "Fehlerhafte Antwort von File daemon auf Hello Kommando: ERR=%s\n" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, fuzzy, c-format msgid "Unable to parse device %s.\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/rados_device.c:62 #, fuzzy, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/rados_device.c:69 #, fuzzy, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "Konnte Job Eintrag nicht holen. ERR=%s\n" #: src/stored/backends/rados_device.c:77 #, fuzzy, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "Konnte Job Eintrag nicht holen. ERR=%s\n" #: src/stored/backends/rados_device.c:89 #, fuzzy, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/rados_device.c:271 #, fuzzy, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/rados_device.c:278 #, fuzzy, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, fuzzy, c-format msgid "Request for unknown devicetype: %d\n" msgstr "unbekannt" #: src/stored/backends/gfapi_device.c:317 #, fuzzy, c-format msgid "Unable to parse device URI %s.\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/gfapi_device.c:329 #, fuzzy, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, fuzzy, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/cephfs_device.c:58 #, fuzzy, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/cephfs_device.c:65 #, fuzzy, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "Konnte Job Eintrag nicht holen. ERR=%s\n" #: src/stored/backends/cephfs_device.c:72 #, fuzzy, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/backends/cephfs_device.c:101 #, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/cephfs_device.c:111 #, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, fuzzy, c-format msgid "unknown func code %d" msgstr "unbekannt" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, fuzzy, c-format msgid "Failed to create a new context using config %s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/backends/object_store_device.c:190 #, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, fuzzy, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/backends/object_store_device.c:274 #, fuzzy, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/backends/object_store_device.c:298 #, fuzzy, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/backends/object_store_device.c:406 #, fuzzy, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:416 #, fuzzy, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 msgid "waiting for" msgstr "" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 #, fuzzy msgid "waiting for sysop intervention" msgstr "File daemon" #: src/stored/status.c:275 #, fuzzy msgid "unknown state" msgstr "unbekannt" #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "" #: src/stored/status.c:332 #, fuzzy, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "unbekannt" #: src/stored/status.c:336 #, fuzzy, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "unbekannt" #: src/stored/status.c:369 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "" #: src/stored/status.c:523 #, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 #, fuzzy msgid "Attached Jobs: " msgstr "ist nicht aktiviert" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, c-format msgid " File=%u block=%u\n" msgstr "" #: src/stored/status.c:610 #, c-format msgid " Min block=%u Max block=%u\n" msgstr "" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, fuzzy, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr " MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, fuzzy, c-format msgid "3900 No arg in status command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/stored/status.c:984 #, fuzzy, c-format msgid "3900 No arg in .status command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/stored/status.c:1033 #, fuzzy, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "unbekannt" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, fuzzy, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "Job nicht gefunden: %s\n" #: src/stored/sd_cmds.c:131 #, fuzzy msgid "Unable to authenticate Storage daemon\n" msgstr "Verbindung zu Storage daemon fehlgeschlagen.\n" #: src/stored/sd_cmds.c:182 #, fuzzy, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "Netzwerkfehler mit FD bei %s: ERR=%s\n" #: src/stored/sd_cmds.c:185 #, fuzzy msgid "Command error with SD, hanging up.\n" msgstr "Netzwerkfehler mit FD bei %s: ERR=%s\n" #: src/stored/sd_cmds.c:197 #, fuzzy, c-format msgid "SD command not found: %s\n" msgstr "Job nicht gefunden: %s\n" #: src/stored/sd_cmds.c:338 #, fuzzy msgid "Replicate data error.\n" msgstr "unbekannt" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, fuzzy, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "unbekannt" #: src/stored/authenticate.c:133 #, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, fuzzy, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "TLS Aushandlung fehlgeschlagen mit SD an \"%s:%d\"\n" #: src/stored/authenticate.c:257 #, fuzzy, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "unbekannt" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, fuzzy, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "TLS Aushandlung fehlgeschlagen mit SD an \"%s:%d\"\n" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, fuzzy, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "Erzeugung von db Device Eintrag %s fehlgeschlagen: ERR=%s\n" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, fuzzy, c-format msgid "Could not reserve volume %s on %s\n" msgstr "Konnte FileSet \"%s\" Eintrag nicht erzeugen. ERR=%s\n" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 #, fuzzy msgid "Error updating Catalog\n" msgstr "Fehler beim holen von Zeile: %s\n" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "" #: src/stored/mount.c:741 #, fuzzy, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "TLS bentigt aber nicht konfiguriert in Bareos.\n" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, fuzzy, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" #: src/stored/block.c:644 #, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 #, fuzzy msgid "Error sending Volume info to Director.\n" msgstr "Keine Volumes zum Wiederherstellen gefunden.\n" #: src/stored/block.c:949 #, fuzzy msgid "Job failed or canceled.\n" msgstr "JobId %s, Job %s zum Abbruch markiert.\n" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_datei] [-d debug_level]\n" " -c benutze als Konfigurationsdatei\n" " -dnn setze debug level auf nn\n" " -f starte in Vordergrund (fr debugging)\n" " -g groupid\n" " -s no signals (fr debugging)\n" " -t Konfigurationsdatei testen und beenden\n" " -u userid\n" " -v Ausfhrliche Benutzermeldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, fuzzy, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/stored/lock.c:489 #, fuzzy msgid "unknown blocked code" msgstr "unbekannt" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:310 #, fuzzy, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/stored/autochanger.c:324 #, fuzzy, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, fuzzy, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "Attribute create error. %s" #: src/stored/autochanger.c:699 msgid "3306 Issuing autochanger transfer command.\n" msgstr "" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, fuzzy, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "JobId %s, Job %s zum Abbruch markiert.\n" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, fuzzy, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "Weder storage noch Pool in Job \"%s\" definiert.\n" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, fuzzy, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, fuzzy, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, fuzzy, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/stored/bcopy.c:60 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_datei] [-d debug_level]\n" " -c benutze als Konfigurationsdatei\n" " -dnn setze debug level auf nn\n" " -f starte in Vordergrund (fr debugging)\n" " -g groupid\n" " -s no signals (fr debugging)\n" " -t Konfigurationsdatei testen und beenden\n" " -u userid\n" " -v Ausfhrliche Benutzermeldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, fuzzy, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "konnte job cond Variable nicht initialisieren: ERR=%s\n" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "" #: src/stored/record.c:65 #, fuzzy, c-format msgid "unknown: %d" msgstr "unbekannt" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 #, fuzzy msgid "Quota Exceeded. Job Terminated.\n" msgstr "\"Max run time\" berschritten, Job abgebrochen.\n" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, fuzzy, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, fuzzy, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:650 #, fuzzy, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, fuzzy, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/xattr.c:981 #, fuzzy, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, fuzzy, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, fuzzy, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, fuzzy, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/xattr.c:1453 #, fuzzy, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, fuzzy, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/xattr.c:1669 #, fuzzy, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, fuzzy, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/xattr.c:1931 #, fuzzy, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr " %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, fuzzy, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "Kann bootstrap Datei nicht ffnen: %s: ERR=%s\n" #: src/findlib/find_one.c:268 #, c-format msgid "%s: mtime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:275 #, c-format msgid "%s: ctime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, c-format msgid "%s: size changed during backup.\n" msgstr "" #: src/findlib/find_one.c:729 #, c-format msgid "%s: File name too long [%d]\n" msgstr "" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, fuzzy, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:293 #, fuzzy, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, fuzzy, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, fuzzy, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:495 #, fuzzy, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:875 #, fuzzy, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:929 #, fuzzy, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:967 #, fuzzy, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:1000 #, fuzzy, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, fuzzy, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, fuzzy, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1683 #, fuzzy, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1818 #, fuzzy, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, fuzzy, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, fuzzy, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, fuzzy, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "Socket Fehler auf %s Kommando: ERR=%s\n" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2196 #, fuzzy, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/acl.c:2225 #, fuzzy, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, fuzzy, c-format msgid "Unparseable size option: %s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, fuzzy, c-format msgid "Unexpected autodeflate setting on %s" msgstr "drivetype Ausdruck erwartet, erhalten: %s\n" #: src/plugins/stored/autoxflate-sd.c:368 #, fuzzy, c-format msgid "Unexpected autoinflate setting on %s" msgstr "fstype Ausdruck erwartet, erhalten: %s\n" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 #, fuzzy msgid "Plugin File argument not specified.\n" msgstr "Path record: %s nicht gefunden.\n" #: src/plugins/filed/bpipe-fd.c:916 #, fuzzy msgid "Plugin Reader argument not specified.\n" msgstr "Path record: %s nicht gefunden.\n" #: src/plugins/filed/bpipe-fd.c:922 #, fuzzy msgid "Plugin Writer argument not specified.\n" msgstr "Path record: %s nicht gefunden.\n" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, c-format msgid "Enter Key Encryption Key: " msgstr "" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, fuzzy, c-format msgid "Cannot open keyfile %s\n" msgstr "Kann inkludierte Datei nicht ffnen: %s. ERR=%s\n" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, fuzzy, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr " set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, fuzzy, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, fuzzy, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "unbekannt" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, fuzzy, c-format msgid "Failed to connect to mailhost %s\n" msgstr "Verbindung zu File daemon fehlgeschlagen.\n" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 msgid "BAREOS Message" msgstr "" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:1054 #, fuzzy, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "Catalog Fehler beim Aktualisieren von volume \"%s\". ERR=%s" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "" #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "" #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "" #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "" #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "" #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "" #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr " --> RunScript\n" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr " --> Command=%s\n" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr " --> Target=%s\n" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr " --> RunOnSuccess=%u\n" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr " --> RunOnFailure=%u\n" #: src/lib/runscript.c:340 #, fuzzy, c-format msgid " --> FailJobOnError=%u\n" msgstr " --> AbortJobOnError=%u\n" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr " --> RunWhen=%u\n" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "" #: src/lib/lex.c:140 #, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:144 #, c-format msgid "Config warning: %s\n" msgstr "" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 msgid "string" msgstr "" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 msgid "include" msgstr "" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "" #: src/lib/jcr.c:244 #, fuzzy msgid "Restoring" msgstr "Wiederherstellung luft..." #: src/lib/jcr.c:246 msgid "Archiving" msgstr "" #: src/lib/jcr.c:248 msgid "Copying" msgstr "" #: src/lib/jcr.c:250 msgid "Migration" msgstr "" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "" #: src/lib/jcr.c:254 #, fuzzy msgid "Unknown operation" msgstr "unbekannt" #: src/lib/jcr.c:265 #, fuzzy msgid "backup" msgstr "Sicherung OK" #: src/lib/jcr.c:267 msgid "verified" msgstr "" #: src/lib/jcr.c:269 #, fuzzy msgid "restored" msgstr "Job Ressource" #: src/lib/jcr.c:269 #, fuzzy msgid "restore" msgstr "Job Ressource" #: src/lib/jcr.c:271 msgid "archived" msgstr "" #: src/lib/jcr.c:271 msgid "archive" msgstr "" #: src/lib/jcr.c:273 msgid "copied" msgstr "" #: src/lib/jcr.c:273 msgid "copy" msgstr "" #: src/lib/jcr.c:275 msgid "migrated" msgstr "" #: src/lib/jcr.c:275 msgid "migrate" msgstr "" #: src/lib/jcr.c:277 msgid "scanned" msgstr "" #: src/lib/jcr.c:277 msgid "scan" msgstr "" #: src/lib/jcr.c:279 #, fuzzy msgid "unknown action" msgstr "unbekannt" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, fuzzy, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "pthread_create: ERR=%s\n" #: src/lib/jcr.c:365 #, fuzzy, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/lib/jcr.c:394 #, fuzzy, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "Konnte job queue nicht initialiseren: ERR=%s\n" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "" #: src/lib/jcr.c:686 #, fuzzy, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "Media id select fehlgeschlagen: ERR=%s\n" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:108 #, fuzzy, c-format msgid "prctl failed: ERR=%s\n" msgstr "pthread_create: ERR=%s\n" #: src/lib/priv.c:112 #, fuzzy, c-format msgid "setreuid failed: ERR=%s\n" msgstr "Abfrage gescheitert: %s: ERR=%s\n" #: src/lib/priv.c:116 #, fuzzy, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "pthread_create: ERR=%s\n" #: src/lib/priv.c:120 #, fuzzy, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "Media id select fehlgeschlagen: ERR=%s\n" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 #, fuzzy msgid "unknown command character in variable" msgstr "unbekannt" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 #, fuzzy msgid "unknown flag in search and replace operation" msgstr "unbekannt" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 #, fuzzy msgid "offsets in cut operation delimited by unknown character" msgstr "unbekannt" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 #, fuzzy msgid "unknown quoted pair in search and replace operation" msgstr "unbekannt" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 #, fuzzy msgid "unknown error" msgstr "unbekannt" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 msgid "Encryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:251 msgid "Encryption Mode: External\n" msgstr "" #: src/lib/scsi_crypto.c:256 msgid "Encryption Mode: Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 msgid "Volume encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:460 msgid "Compression Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 msgid "Encryption Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 #, fuzzy msgid "Drive encryption status: Unknown\n" msgstr "unbekannt" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "" #: src/lib/bnet.c:326 msgid "No problem." msgstr "" #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "" #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "" #: src/lib/crypto_cache.c:160 #, fuzzy, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "Kann bootstrap Datei nicht ffnen: %s: ERR=%s\n" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 #, fuzzy msgid "Volumename" msgstr "FileSet: name=%s\n" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 msgid "EncryptionKey" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Added" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, fuzzy, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "Client id select fehlgeschlagen: ERR=%s\n" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:274 #, fuzzy, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, fuzzy, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Konnte regex pattern \"%s\" nicht kompilieren ERR=%s\n" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 #, fuzzy msgid "No error" msgstr "unbekannt" #: src/lib/crypto.c:176 #, fuzzy msgid "Signer not found" msgstr "FileSet MD5 Prfsumme nicht gefunden.\n" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 #, fuzzy msgid "Unknown error" msgstr "unbekannt" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 msgid "Selection item too large.\n" msgstr "" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, fuzzy, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/lib/ini.c:262 src/lib/ini.c:274 #, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:312 src/lib/ini.c:324 #, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:560 src/lib/ini.c:672 #, fuzzy, c-format msgid "Cannot open config file %s: %s\n" msgstr "Kann inkludierte Datei nicht ffnen: %s. ERR=%s\n" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, fuzzy, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, c-format msgid "Error loading CA certificates from %s\n" msgstr "" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "" #: src/lib/tls_gnutls.c:201 #, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "" #: src/lib/tls_gnutls.c:216 #, fuzzy, c-format msgid "Failed to load DH file %s\n" msgstr "qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, fuzzy, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/lib/scsi_lli.c:92 #, fuzzy, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, fuzzy, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, fuzzy, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/scsi_lli.c:314 #, fuzzy, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/scsi_lli.c:323 #, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "" #: src/lib/scsi_lli.c:348 #, fuzzy, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/lib/scsi_lli.c:464 #, fuzzy, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "Kann Catalog DB Steuerdatei nicht ffnen %s: ERR=%s\n" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, fuzzy, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/lib/lockmgr.c:103 #, fuzzy, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "pthread_cond_wait: ERR=%s\n" #: src/lib/lockmgr.c:613 #, fuzzy, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "pthread_create: ERR=%s\n" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "" #: src/lib/crypto_openssl.c:749 #, fuzzy msgid "No signers found for crypto verify.\n" msgstr "Keine %ss zum Migrieren gefunden.\n" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1615 #, fuzzy, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "Konnte Job Eintrag nicht holen. ERR=%s\n" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, fuzzy, c-format msgid "Could not set Finder Info on %s\n" msgstr "Konnte Datenbank \"%s\" nicht ffen.\n" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 #, fuzzy msgid "Could not create digest.\n" msgstr "Konnte Client Eintrag nicht anlegen. ERR=%s\n" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, fuzzy, c-format msgid "Cannot open resource fork for %s.\n" msgstr "Kann Ausdruck\"%s\"nicht auflsen: ERR=%s\n" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 #, fuzzy msgid "Plugin save packet not found.\n" msgstr "Path record: %s nicht gefunden.\n" #: src/filed/fd_plugins.c:1076 #, fuzzy, c-format msgid "Plugin=%s not found.\n" msgstr "Pool Ressource \"%s\" nicht gefunden.\n" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, fuzzy, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/filed/crypto.c:214 #, fuzzy, c-format msgid "Digest one file failed for file: %s\n" msgstr "Mehr als ein Dateiname! %s fr Datei: %s\n" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, fuzzy, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/filed/dir_cmd.c:933 #, fuzzy, c-format msgid "Bad RunAfter command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1015 #, fuzzy, c-format msgid "Bad Plugin Options command: %s\n" msgstr " --> Run=%s\n" #: src/filed/dir_cmd.c:1066 #, fuzzy, c-format msgid "Bad RestoreObject command: %s\n" msgstr "Storage daemon hat \"Job command\": %s abgelehnt\n" #: src/filed/dir_cmd.c:1166 msgid "2909 Bad RestoreObject command.\n" msgstr "" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, fuzzy, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "Erzeugung des db Path Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/filed/dir_cmd.c:1696 #, fuzzy, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "Erzeugung des db Path Eintrags %s fehlgeschlagen. ERR=%s\n" #: src/filed/dir_cmd.c:1708 #, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, fuzzy, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, fuzzy, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "Restore replacement Option erwartet, erhalten: %s" #: src/filed/filed.c:61 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_datei] [-d debug_level]\n" " -c benutze als Konfigurationsdatei\n" " -dnn setze debug level auf nn\n" " -f starte in Vordergrund (fr debugging)\n" " -g groupid\n" " -s no signals (fr debugging)\n" " -t Konfigurationsdatei testen und beenden\n" " -u userid\n" " -v Ausfhrliche Benutzermeldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, fuzzy, c-format msgid "Unable to create MDB environment: %s\n" msgstr "Kann Konsole \"%s\" an %s:%s:%d nicht authentisieren.\n" #: src/filed/accurate_lmdb.c:81 #, fuzzy, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/filed/accurate_lmdb.c:90 #, fuzzy, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "Konnte Job Volume Parameter nicht holen. ERR=%s\n" #: src/filed/accurate_lmdb.c:97 #, fuzzy, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/filed/accurate_lmdb.c:103 #, fuzzy, c-format msgid "Unable to start a write transaction: %s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/filed/accurate_lmdb.c:109 #, fuzzy, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "Kann Datenbank=%s.nicht ffen. ERR=%s\n" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, c-format msgid "Unable insert new data: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, fuzzy, c-format msgid "Unable close write transaction: %s\n" msgstr "Kann DB lock nicht initialisieren. ERR=%s\n" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, fuzzy, c-format msgid "Unable to create write transaction: %s\n" msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #: src/filed/accurate_lmdb.c:249 #, fuzzy, c-format msgid "Unable to create read transaction: %s\n" msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, fuzzy, c-format msgid "Unable to renew read transaction: %s\n" msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, fuzzy, c-format msgid "Unable create cursor: %s\n" msgstr "Attribute create error. %s" #: src/filed/status.c:87 #, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, fuzzy, c-format msgid " %s%s %s Job started: %s\n" msgstr "Clone JobId %d gestartet.\n" #: src/filed/status.c:201 #, fuzzy, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr " MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #: src/filed/status.c:209 #, fuzzy, c-format msgid " Files Examined=%s\n" msgstr "FileSet: name=%s\n" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, fuzzy, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "unbekannt" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "" #: src/filed/authenticate.c:301 #, fuzzy, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "unbekannt" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, fuzzy, c-format msgid "Cannot verify checksum for %s\n" msgstr "Kann Schedule resource %s nicht finden\n" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, fuzzy, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "Fehler beim Start des Programms: %s. ERR=%s\n" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, fuzzy, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "Kann Ausdruck\"%s\"nicht auflsen: ERR=%s\n" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, fuzzy, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "Konnte counter %s: nicht aktualisieren: ERR=%s\n" #: src/filed/backup.c:595 #, fuzzy, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "Konnte regex pattern \"%s\" nicht kompilieren ERR=%s\n" #: src/filed/backup.c:602 #, fuzzy, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "Kann bootstrap Datei nicht ffnen: %s: ERR=%s\n" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, fuzzy, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "Konnte regex pattern \"%s\" nicht kompilieren ERR=%s\n" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr "" #: src/filed/backup.c:776 #, fuzzy, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "Kann Ausdruck\"%s\"nicht auflsen: ERR=%s\n" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "" #: src/filed/backup.c:1219 #, fuzzy, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "zu viele items in Job resource\n" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:79 #, fuzzy, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" "Kann mit File daemon on \"%s:%d\" nicht authentisieren. Mgliche Ursachen:\n" "Passworte oder Namen nicht gleich oder\n" "Maximum Concurrent Jobs berschritten auf dem FD oder\n" "FD Netzwerk durcheinander (Daemon neustarten).\n" "Weitere Informationen unter http://doc.bareos.org/master/html/bareos-manual-" "main-reference.html#AuthorizationErrors.\n" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:139 #, fuzzy msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "Director und Storage daemon Passworte or Namen nicht gleich.\n" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "" #: src/qt-console/main.cpp:181 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c setze Konfigurationsdatei auf Datei\n" " -dnn setze debug level auf nn\n" " -f starte im Vordergrund (fr debugging Zwecke)\n" " -g groupid\n" " -r starte jetzt\n" " -s no signals\n" " -t test - Konfiguration Lesen und beenden\n" " -u userid\n" " -v ausfhrliche Benutzer Meldungen\n" " -? diese Meldung ausgeben.\n" "\n" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "" #, fuzzy #~ msgid "@exec error: ERR=%s\n" #~ msgstr "Regex bersetzungsfehler. ERR=%s\n" #, fuzzy #~ msgid "Unable to load any shared library for .\n" #~ msgstr "Konnte bootstrap Datei %s nicht erzeugen. ERR=%s\n" #, fuzzy #~ msgid "Run FullPool override\n" #~ msgstr "von \"Run FullPool\" berschrieben" #, fuzzy #~ msgid "Run IncPool override\n" #~ msgstr "von \"Run pool\" berschrieben" #, fuzzy #~ msgid "Job IncPool override\n" #~ msgstr "von \"Run pool\" berschrieben" #, fuzzy #~ msgid "Run DiffPool override\n" #~ msgstr "von \"Run pool\" berschrieben" #, fuzzy #~ msgid "Job DiffPool override\n" #~ msgstr "von \"Run pool\" berschrieben" #, fuzzy #~ msgid "Expected a Console Authentication Type keyword, got: %s" #~ msgstr " Migration Job Type Schlsselwort erwartet, erhalten: %s" #~ msgid "Device record %s already exists\n" #~ msgstr "Device Eintrag %s bereits vorhanden\n" #, fuzzy #~ msgid "Plugin Options not yet implemented.\n" #~ msgstr "Kein storage angegeben.\n" #~ msgid "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n" #~ msgstr "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n" #~ msgid " query_file=%s\n" #~ msgstr " query_file=%s\n" #~ msgid " --> " #~ msgstr " --> " #~ msgid "Console: name=%s SSL=%d\n" #~ msgstr "Console: name=%s SSL=%d\n" #~ msgid "Counter: name=%s min=%d max=%d cur=%d wrapcntr=%s\n" #~ msgstr "Counter: name=%s min=%d max=%d cur=%d wrapcntr=%s\n" #~ msgid "Counter: name=%s min=%d max=%d\n" #~ msgstr "Counter: name=%s min=%d max=%d\n" #, fuzzy #~ msgid "" #~ "Client: name=%s protocol=%d authtype=%d address=%s FDport=%d MaxJobs=%u\n" #~ msgstr "Client: name=%s address=%s FDport=%d MaxJobs=%u\n" #, fuzzy #~ msgid "" #~ " JobRetention=%s FileRetention=%s AutoPrune=%d SoftQuota=%s " #~ "SoftQuotaGrace=%s HardQuota=%s StrictQuotas=%d\n" #~ msgstr " JobRetention=%s FileRetention=%s AutoPrune=%d\n" #~ msgid "" #~ "Device: name=%s ok=%d num_writers=%d max_writers=%d\n" #~ " reserved=%d open=%d append=%d read=%d labeled=%d offline=%d " #~ "autochgr=%d\n" #~ " poolid=%s volname=%s MediaType=%s\n" #~ msgstr "" #~ "Device: name=%s ok=%d num_writers=%d max_writers=%d\n" #~ " reserved=%d open=%d append=%d read=%d labeled=%d offline=%d " #~ "autochgr=%d\n" #~ " poolid=%s volname=%s MediaType=%s\n" #, fuzzy #~ msgid "" #~ "Storage: name=%s protocol=%d authtype=%d address=%s SDport=%d MaxJobs=%u\n" #~ " DeviceName=%s MediaType=%s PairedStorage=%s StorageId=%s\n" #~ msgstr "" #~ "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n" #~ " DeviceName=%s MediaType=%s StorageId=%s\n" #, fuzzy #~ msgid "" #~ "Catalog: name=%s address=%s DBport=%d db_name=%s\n" #~ " db_driver=%s db_user=%s MutliDBConn=%d\n" #~ msgstr "" #~ "Catalog: name=%s address=%s DBport=%d db_name=%s\n" #~ " db_user=%s MutliDBConn=%d\n" #, fuzzy #~ msgid "%s: name=%s JobType=%d protocol=%d level=%s Priority=%d Enabled=%d\n" #~ msgstr "%s: name=%s JobType=%d level=%s Priority=%d Enabled=%d\n" #~ msgid "JobDefs" #~ msgstr "JobDefs" #, fuzzy #~ msgid " MaxJobs=%u Resched=%d Times=%d Interval=%s Spool=%d\n" #~ msgstr "" #~ " MaxJobs=%u Resched=%d Times=%d Interval=%s Spool=%d " #~ "WritePartAfterJob=%d\n" #, fuzzy #~ msgid " SpoolSize=%s\n" #~ msgstr " opcmd=%s\n" #, fuzzy #~ msgid " Accurate=%d\n" #~ msgstr " SelectionType=%d\n" #~ msgid " SelectionType=%d\n" #~ msgstr " SelectionType=%d\n" #~ msgid " --> Where=%s\n" #~ msgstr " --> Where=%s\n" #, fuzzy #~ msgid " --> RegexWhere=%s\n" #~ msgstr " --> Where=%s\n" #~ msgid " --> Bootstrap=%s\n" #~ msgstr " --> Bootstrap=%s\n" #~ msgid " --> WriteBootstrap=%s\n" #~ msgstr " --> WriteBootstrap=%s\n" #, fuzzy #~ msgid " --> MaxRunTime=%u\n" #~ msgstr " --> RunWhen=%u\n" #, fuzzy #~ msgid " --> MaxWaitTime=%u\n" #~ msgstr " --> RunWhen=%u\n" #, fuzzy #~ msgid " --> MaxStartDelay=%u\n" #~ msgstr " --> Target=%s\n" #, fuzzy #~ msgid " --> MaxRunSchedTime=%u\n" #~ msgstr " --> RunWhen=%u\n" #, fuzzy #~ msgid " --> Base %s\n" #~ msgstr " --> Target=%s\n" #~ msgid " --> Run=%s\n" #~ msgstr " --> Run=%s\n" #~ msgid " --> SelectionPattern=%s\n" #~ msgstr " --> SelectionPattern=%s\n" #~ msgid "FileSet: name=%s\n" #~ msgstr "FileSet: name=%s\n" #~ msgid " --> Run Level=%s\n" #~ msgstr " --> Run Level=%s\n" #~ msgid " hour=" #~ msgstr " hour=" #~ msgid " mday=" #~ msgstr " mday=" #~ msgid " month=" #~ msgstr " month=" #~ msgid " wday=" #~ msgstr " wday=" #~ msgid " wom=" #~ msgstr " wom=" #~ msgid " woy=" #~ msgstr " woy=" #~ msgid " mins=%d\n" #~ msgstr " mins=%d\n" #~ msgid " --> " #~ msgstr " --> " #~ msgid "Pool: name=%s PoolType=%s\n" #~ msgstr "Pool: name=%s PoolType=%s\n" #~ msgid " use_cat=%d use_once=%d cat_files=%d\n" #~ msgstr " use_cat=%d use_once=%d cat_files=%d\n" #~ msgid " max_vols=%d auto_prune=%d VolRetention=%s\n" #~ msgstr " max_vols=%d auto_prune=%d VolRetention=%s\n" #~ msgid " VolUse=%s recycle=%d LabelFormat=%s\n" #~ msgstr " VolUse=%s recycle=%d LabelFormat=%s\n" #~ msgid " CleaningPrefix=%s LabelType=%d\n" #~ msgstr " CleaningPrefix=%s LabelType=%d\n" #, fuzzy #~ msgid " RecyleOldest=%d PurgeOldest=%d ActionOnPurge=%d\n" #~ msgstr " RecyleOldest=%d PurgeOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n" #, fuzzy #~ msgid " MaxVolJobs=%d MaxVolFiles=%d MaxVolBytes=%s\n" #~ msgstr " max_vols=%d auto_prune=%d VolRetention=%s\n" #~ msgid " MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #~ msgstr " MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #, fuzzy #~ msgid " JobRetention=%s FileRetention=%s\n" #~ msgstr " JobRetention=%s FileRetention=%s AutoPrune=%d\n" #, fuzzy #~ msgid " NextPool=%s\n" #~ msgstr " opcmd=%s\n" #, fuzzy #~ msgid " RecyclePool=%s\n" #~ msgstr " opcmd=%s\n" #, fuzzy #~ msgid " ScratchPool=%s\n" #~ msgstr " opcmd=%s\n" #, fuzzy #~ msgid " Catalog=%s\n" #~ msgstr " mailcmd=%s\n" #~ msgid "Messages: name=%s\n" #~ msgstr "Messages: name=%s\n" #~ msgid " mailcmd=%s\n" #~ msgstr " mailcmd=%s\n" #~ msgid " opcmd=%s\n" #~ msgstr " opcmd=%s\n" #, fuzzy #~ msgid "TLS negotiation failed with FD at \"%s:%d\"\n" #~ msgstr "TLS Aushandlung fehlgeschlagen mit FD an \"%s:%d\".\n" #, fuzzy #~ msgid "LZO uncompression error. ERR=%d\n" #~ msgstr "Regex bersetzungsfehler. ERR=%s\n" #, fuzzy #~ msgid " Drive %d status unknown.\n" #~ msgstr "unbekannt" #, fuzzy #~ msgid "" #~ "No Client, Storage or Director resource defined in %s\n" #~ "Without that I don't how to get status from the File, Storage or Director " #~ "Daemon :-(\n" #~ msgstr "" #~ "Keine Director resource definiert in %s\n" #~ "Ohne dies weiss ich nicht wer ich bin :-(\n" #~ msgid "Bareos " #~ msgstr "Bareos " #, fuzzy #~ msgid "Expected one of: %s, got: %s" #~ msgstr "Erwartet: %s, erhalten: %s" #, fuzzy #~ msgid "" #~ "%s %s %s (%s):\n" #~ " Build OS: %s %s %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Backup Level: %s%s\n" #~ " Client: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pool: \"%s\" (From %s)\n" #~ " Catalog: \"%s\" (From %s)\n" #~ " Storage: \"%s\" (From %s)\n" #~ " Scheduled time: %s\n" #~ " Start time: %s\n" #~ " End time: %s\n" #~ " Elapsed time: %s\n" #~ " Priority: %d\n" #~ " FD Files Written: %s\n" #~ " SD Files Written: %s\n" #~ " FD Bytes Written: %s (%sB)\n" #~ " SD Bytes Written: %s (%sB)\n" #~ " Rate: %.1f KB/s\n" #~ " Software Compression: %s\n" #~ "%s VSS: %s\n" #~ " Encryption: %s\n" #~ " Accurate: %s\n" #~ " Volume name(s): %s\n" #~ " Volume Session Id: %d\n" #~ " Volume Session Time: %d\n" #~ " Last Volume Bytes: %s (%sB)\n" #~ " Non-fatal FD errors: %d\n" #~ " SD Errors: %d\n" #~ " FD termination status: %s\n" #~ " SD termination status: %s\n" #~ " Termination: %s\n" #~ "\n" #~ msgstr "" #~ "%s %s (%s): %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Backup Level: %s%s\n" #~ " Client: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pool: \"%s\" (From %s)\n" #~ " Storage: \"%s\" (From %s)\n" #~ " Geplante Zeit: %s\n" #~ " Startzeit: %s\n" #~ " Endzeit: %s\n" #~ " Verstrichene Zeit: %s\n" #~ " Prioritt: %d\n" #~ " FD Dateien geschrieben: %s\n" #~ " SD Dateien geschrieben: %s\n" #~ " FD Bytes geschrieben: %s (%sB)\n" #~ " SD Bytes geschrieben: %s (%sB)\n" #~ " Geschwindigkeit: %.1f KB/s\n" #~ " Software Kompression: %s\n" #~ " VSS: %s\n" #~ " Verschlsselung: %s\n" #~ " Volume Name(n): %s\n" #~ " Volume Session Id: %d\n" #~ " Volume Session Zeit: %d\n" #~ " Letztes Volumen Bytes: %s (%sB)\n" #~ " Nicht-fatale FD Fehler %d\n" #~ " SD Fehler: %d\n" #~ " FD Beendigungsstatus: %s\n" #~ " SD Beendigungsstatus: %s\n" #~ " Beendigungsstatus: %s\n" #~ "\n" #, fuzzy #~ msgid "" #~ "Written by Nicolas Boichat (2004)\n" #~ "\n" #~ "Version: %s (%s) %s %s %s\n" #~ "\n" #~ "Usage: tray-monitor [-c config_file] [-d debug_level]\n" #~ " -c set configuration file to file\n" #~ " -d set debug level to \n" #~ " -dt print timestamp in debug output\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ "\n" #~ "Version: %s (%s)\n" #~ "\n" #~ "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" #~ " -c setze Konfigurationsdatei auf Datei\n" #~ " -dnn setze debug level auf nn\n" #~ " -f starte im Vordergrund (fr debugging Zwecke)\n" #~ " -g groupid\n" #~ " -r starte jetzt\n" #~ " -s no signals\n" #~ " -t test - Konfiguration Lesen und beenden\n" #~ " -u userid\n" #~ " -v ausfhrliche Benutzer Meldungen\n" #~ " -? diese Meldung ausgeben.\n" #~ "\n" #, fuzzy #~ msgid "# Bareos bwx-console Configuration File\n" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Close without saving" #~ msgstr "%s OK -- mit Warnungen" #, fuzzy #~ msgid "Error while saving" #~ msgstr "Fehler beim schreiben der bsr Datei.\n" #, fuzzy #~ msgid "Enter restore mode" #~ msgstr "Job Ressource" #, fuzzy #~ msgid "Cancel restore" #~ msgstr "Job Ressource" #, fuzzy #~ msgid "RestoreFiles" #~ msgstr "Wiederherstellung luft..." #, fuzzy #~ msgid "Error while starting restore: " #~ msgstr "Fehler beim schreiben der bsr Datei.\n" #, fuzzy #~ msgid "Restore failed : no file selected.\n" #~ msgstr "Mehr als ein Dateiname! %s fr Datei: %s\n" #, fuzzy #~ msgid "Restore failed : no file selected." #~ msgstr "Mehr als ein Dateiname! %s fr Datei: %s\n" #, fuzzy #~ msgid "Restoring, please wait..." #~ msgstr "Wiederherstellung luft..." #, fuzzy #~ msgid "Job failed." #~ msgstr "%s Abgebrochen" #, fuzzy #~ msgid "Restore job reported a non-fatal error." #~ msgstr "Attribute create error. %s" #, fuzzy #~ msgid "Restore job reported a fatal error." #~ msgstr "Attribute create error. %s" #, fuzzy #~ msgid "Restore job is waiting on File daemon." #~ msgstr "File daemon" #, fuzzy #~ msgid "Restore job is waiting for storage resource." #~ msgstr "Storage daemon" #, fuzzy #~ msgid "Run Restore job" #~ msgstr "Konnte Migrationsjob nicht starten.\n" #, fuzzy #~ msgid "Restore cancelled.\n" #~ msgstr "%s Abgebrochen" #, fuzzy #~ msgid "Restore cancelled." #~ msgstr "%s Abgebrochen" #, fuzzy #~ msgid "No results to list." #~ msgstr "Keine Ergebnisse zu \"list\" Kommando.\n" #, fuzzy #~ msgid "No backup found for this client." #~ msgstr "Kein Job gefunden fr: %s.\n" #, fuzzy #~ msgid "Query failed" #~ msgstr "Abfrage fehlgeschlagen: %s\n" #, fuzzy #~ msgid "Bootstrap:" #~ msgstr " --> Bootstrap=%s\n" #~ msgid "Restoring..." #~ msgstr "Wiederherstellung luft..." #, fuzzy #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Director \"%s\" in config file.\n" #~ "At least one CA certificate store is required.\n" #~ msgstr "" #~ "Weder \"TLS CA Certificate\" noch \"TLS CA Certificate Dir\" sind fr " #~ "Director \"%s\" in %s definert. Mindestens ein CA certificate store wird " #~ "bentigt wenn \"TLS Verify Peer\" eingesetzt wird.\n" #, fuzzy #~ msgid "" #~ "No Director resource defined in config file.\n" #~ "Without that I don't how to speak to the Director :-(\n" #~ msgstr "" #~ "Keine Director resource definiert in %s\n" #~ "Ohne dies weiss ich nicht wer ich bin :-(\n" #, fuzzy #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Console \"%s\" in config file.\n" #~ msgstr "" #~ "Weder \"TLS CA Certificate\" noch \"TLS CA Certificate Dir\" sind " #~ "definiert frStorage \"%s\" in %s.\n" #, fuzzy #~ msgid "Error while initializing windows sockets...\n" #~ msgstr "Fehler beim schreiben der bsr Datei.\n" #, fuzzy #~ msgid "Error while initializing library." #~ msgstr "Fehler beim schreiben der bsr Datei.\n" #, fuzzy #~ msgid "Cryptographic library initialization failed.\n" #~ msgstr "Initialisierung der Verschlsselungsbibliothek fehlgeschlagen.\n" #, fuzzy #~ msgid "Please correct configuration file.\n" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Error : Library not initialized\n" #~ msgstr "Initialisierung der Verschlsselungsbibliothek fehlgeschlagen.\n" #, fuzzy #~ msgid "Error : No configuration file loaded\n" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Connecting...\n" #~ msgstr "Wiederherstellung luft..." #, fuzzy #~ msgid "Error : No director defined in config file.\n" #~ msgstr "Keine Job records definiert in %s\n" #, fuzzy #~ msgid "Failed to connect to the director\n" #~ msgstr "Verbindung zu File daemon fehlgeschlagen.\n" #, fuzzy #~ msgid "Unknown command." #~ msgstr "unbekannt" #, fuzzy #~ msgid "Bareos bwx-console" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Change of configuration file" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Change your default configuration file" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Edit your configuration file" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Please choose a configuration file to use" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Using this configuration file: %s\n" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Please choose your default configuration file" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "Use this configuration file as default?" #~ msgstr "Bitte die Konfigurationsdatei korrigieren: %s\n" #, fuzzy #~ msgid "" #~ "Connection from unknown Director %s at %s rejected.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "unbekannthttp://www.bareos.org/rel-manual/faq.html" #, fuzzy #~ msgid "" #~ "Incorrect authorization key from File daemon at %s rejected.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "unbekannthttp://www.bareos.org/rel-manual/faq.html" #, fuzzy #~ msgid "A dbi driver for DBI must be supplied.\n" #~ msgstr "Ein Benutzername fr MySQL muss angegeben werden.\n" #, fuzzy #~ msgid "Max sched run time exceeded. Job canceled.\n" #~ msgstr "\"Max run time\" berschritten, Job abgebrochen.\n" #~ msgid "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" #~ msgstr "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" #~ msgid "WARNING!!!! The Internal Database is NOT OPERATIONAL!\n" #~ msgstr "WARNUNG!!!! Die Interne Datenbank ist NICHT BETRIEBSBEREIT!\n" #~ msgid "You should use SQLite, PostgreSQL, or MySQL\n" #~ msgstr "Sie sollten SQLite, PostgreSQL, oder MySQL benutzen\n" #~ msgid "" #~ "Error, catalog DB control file wrong version. Wanted %d, got %d\n" #~ "Please reinitialize the working directory.\n" #~ msgstr "" #~ "Fehler, catalog DB steuerdatei hat die falsche Version: erwartet: %d, " #~ "erhalten %d\n" #~ "Bitte das Arbeitsverzeichnis neu initialisieren.\n" #, fuzzy #~ msgid "Could not connect to storage daemon" #~ msgstr "Verbindung zu Storage daemon fehlgeschlagen.\n" #, fuzzy #~ msgid "No Client record defined for job %s\n" #~ msgstr "Keine Job records definiert in %s\n" #, fuzzy #~ msgid "No FileSet record defined for job %s\n" #~ msgstr "Keine Job records definiert in %s\n" #, fuzzy #~ msgid "No Storage resource defined for job %s\n" #~ msgstr "Keine Messages resource definiert in %s\n" #, fuzzy #~ msgid "No Pool resource defined for job %s\n" #~ msgstr "Keine %s resource definiert\n" #, fuzzy #~ msgid "No Catalog resource defined for client %s\n" #~ msgstr "Keine Messages resource definiert in %s\n" #, fuzzy #~ msgid "%d files (%s)" #~ msgstr "%s -- keine Dateien zur Migration." #, fuzzy #~ msgid "An error occurred while extracting files." #~ msgstr "Fehler beim schreiben der bsr Datei.\n" #, fuzzy #~ msgid "" #~ "\n" #~ "Version: %s (%s) %s %s %s\n" #~ "\n" #~ "Usage: bgnome-console [-s] [-c config_file] [-d debug_level] " #~ "[config_file]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -s no signals\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ "\n" #~ "Version: %s (%s)\n" #~ "\n" #~ "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" #~ " -c setze Konfigurationsdatei auf Datei\n" #~ " -dnn setze debug level auf nn\n" #~ " -f starte im Vordergrund (fr debugging Zwecke)\n" #~ " -g groupid\n" #~ " -r starte jetzt\n" #~ " -s no signals\n" #~ " -t test - Konfiguration Lesen und beenden\n" #~ " -u userid\n" #~ " -v ausfhrliche Benutzer Meldungen\n" #~ " -? diese Meldung ausgeben.\n" #~ "\n" #~ msgid "pthread_mutex_lock: ERR=%s\n" #~ msgstr "pthread_mutex_lock: ERR=%s\n" #~ msgid "pthread_mutex_unlock: ERR=%s\n" #~ msgstr "pthread_mutex_unlock: ERR=%s\n" #~ msgid "Start Migration JobId %s, Job=%s\n" #~ msgstr "Starte Migration JobId %s, Job=%s\n" #~ msgid "No Volumes found to migrate.\n" #~ msgstr "Keine Volumes zum Migrieren gefunden.\n" #~ msgid "No JobIds found to migrate.\n" #~ msgstr "Keine JobIds zum migrieren gefunden.\n" #~ msgid "Migration JobId %d started.\n" #~ msgstr "Migration JobId %d gestartet.\n" #~ msgid "Error updating DB Job file. ERR=%s\n" #~ msgstr "Fehler beim aktualisieren der DB Job Datei . ERR=%s\n" #, fuzzy #~ msgid "" #~ "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s" #~ "\" .\n" #~ msgstr "" #~ "Wollte Volume \"%s\"erzeugen, aber , but it already exists. Trying " #~ "again.\n" #, fuzzy #~ msgid "Unable to get Volume record: ERR=%s" #~ msgstr "Konnte Job Eintrag nicht holen. ERR=%s\n" #~ msgid "Invalid MediaId found.\n" #~ msgstr "Ungltige MediaId gefunden.\n" bareos-Release-14.2.6/po/en@boldquot.header000066400000000000000000000024711263011562700205100ustar00rootroot00000000000000# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # # This catalog furthermore displays the text between the quotation marks in # bold face, assuming the VT100/XTerm escape sequences. # bareos-Release-14.2.6/po/en@quot.header000066400000000000000000000022631263011562700176460ustar00rootroot00000000000000# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # bareos-Release-14.2.6/po/es.po000066400000000000000000023230561263011562700160400ustar00rootroot00000000000000# Spanish translations for branch package # Traducciones al español para el paquete branch. # Copyright (C) 2006 Free Software Foundation Europe e.V. # This file is distributed under the same license as the branch package. # # , 2006, 2009. msgid "" msgstr "" "Project-Id-Version: Bareos 3.0.2\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2009-12-01 16:04-0300\n" "Last-Translator: Victor Hugo dos Santos \n" "Language-Team: Bareos Spanish Team \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Spanish\n" "X-Poedit-SourceCharset: utf-8\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" "consulta %s fallida:\n" "%s\n" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" "Inserción %s fallida:\n" "%s\n" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "Problemas con la inserción: filas afectadas=%s\n" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" "Actualizar %s fallida:\n" "%s\n" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "Actualización fallida: celdas afectadas =%s por %s\n" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" "Borrado %s fallido:\n" "%s\n" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "error al obtener la fila:%s\n" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "La longitud de la ruta es nula. Archivo=%s\n" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "No hay resultados para listar.\n" #: src/cats/sql.c:789 #, fuzzy msgid "Could not init database batch connection\n" msgstr "No se pudo iniciar base de datos de Bareos\n" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "Tipo de base de datos desconocido: %s\n" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "No se puede inicializar el bloqueo de la BD. ERR=%s\n" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" "Incapaz de localizar los controladores de la interfaz DBD para DBI en: \n" "db_driverdir=%s. Es probable que no se encuentra ningún controlador\n" #: src/cats/dbi.c:289 #, fuzzy, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "No se pudo conectar a la interfaz DBI.\n" "Tipo=%s Base de Datos=%s Usuario=%s\n" "Probablemente no este ejecutando o su contraseña es incorrecta.\n" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "error al crear Atributo.%s" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "Consulta fallida: %s: ERR=%s\n" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "Error iniciando modo batch: %s" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "Error insertando en modo batch: %s" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "Tipo de controlador no especificado en los recursos de Catálogo.\n" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "Tipo de controlador no válido, debe ser \"dbi:\"\n" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "Un nombre de usuario para DBI debe ser suministrado.\n" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "Creación de registro de Job %s en BD fallido. ERR=%s\n" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "Creación de registro de JobMedia %s fallido. ERR=%s\n" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "Actualización del registro de Media %s fallido: ERR=%s\n" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "registro del pool %s ya existe\n" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "Creación del registro BD Pool %s fallido: ERR=%s\n" #: src/cats/sql_create.c:260 #, fuzzy, c-format msgid "More than one Device!: %d\n" msgstr "Mas de un cliente!: %d\n" #: src/cats/sql_create.c:265 #, fuzzy, c-format msgid "error fetching Device row: %s\n" msgstr "error al obtener la fila:%s\n" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "Creación del registro de BD Device %s fallido: ERR=%s\n" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "Mas de un registro de almacenamiento!: %d\n" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "error obteniendo fila del Almacenamiento:%s\n" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "Creación del registro BD Almacenamiento %s fallido. ERR=%s\n" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "registro de tipo de media %s ya existe\n" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "Fallo al crear la db_mediatype_record %s: ERR=%s\n" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "Volumen \"%s\" ya existe.\n" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "Creación del registro BD Almacenamiento %s fallido. ERR=%s\n" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "Mas de un cliente!: %d\n" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "error al obtener la fila Cliente:%s\n" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "Creación del registro BD Cliente %s fallido. ERR=%s\n" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "Mas de un Path!: %s para path: %s\n" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "Creación del registro Path db %s fallido. ERR=%s\n" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "Creación del registro BD Contadores %s fallido. ERR=%s\n" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "Más de un FileSet!: %d\n" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "error al obtener la fila FileSet: ERR=%s\n" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "Creación del registro BD FileSet %s fallido. ERR=%s\n" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "Creación del registro File db %s fallido. ERR=%s" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "Mas de un nombre de Archivo! %s para el archivo: %s\n" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "Error al obtener fila para el archivo=%s: ERR=%s\n" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "Creación del registro Filename db %s fallido. ERR=%s\n" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "Intento de poner non-atributos en el catálogo. Stream=%d\n" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "ERR=JobIds están vacíos\n" #: src/cats/sql_create.c:1270 #, fuzzy, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "Creación del registro File db %s fallido. ERR=%s" #: src/cats/sql_create.c:1316 #, fuzzy, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "Creación de registro de Job %s en BD fallido. ERR=%s\n" #: src/cats/sql_create.c:1367 #, fuzzy, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "Creación del registro BD Almacenamiento %s fallido. ERR=%s\n" #: src/cats/sql_create.c:1399 #, fuzzy, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "Creación de registro de Job %s en BD fallido. ERR=%s\n" #: src/cats/sql_create.c:1442 #, fuzzy, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "Creación de registro de Job %s en BD fallido. ERR=%s\n" #: src/cats/sql_create.c:1499 #, fuzzy, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "Creación del registro BD FileSet %s fallido. ERR=%s\n" #: src/cats/sql_create.c:1543 #, fuzzy, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "Creación del registro BD Cliente %s fallido. ERR=%s\n" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" "No se puede conectar al servidor MySQL.\n" "Base de Datos=%s Usuario=%s\n" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "Un nombre de usuario para MySQL debe de ser suministrado.\n" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "Registro de pool %s inexistente\n" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "Esperando un registro pool, tiene %d\n" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "Error obteniendo fila %s\n" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" "Error de consulta al solicitar tiempo inicial: ERR=%s\n" "CMD=%s\n" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "No encontrado registro anterior de Job de respaldo completo.\n" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "Nivel desconocido=%d\n" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" "No se encuentra el registro de trabajo: ERR=%s\n" " CMD=%s\n" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "Nivel del Job desconocido=%d\n" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "No se encontró ningún Job para: %s.\n" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "Job no encontrado para:%s\n" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "Solicitud de ítem Volumen %d mayor que el máximo %d o menor que 1\n" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "Registro de ítem Volumen no encontrado %d.\n" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "Consulta fallida: %s\n" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "Estos JobIds tienen copias de la siguiente manera:\n" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "El catálogo contiene copias de la siguiente manera:\n" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "No se pudo abrir la base de datos \"%s\": ERR=%s\n" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 #, fuzzy msgid "Could not init database connection" msgstr "No se pudo iniciar base de datos de Bareos\n" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "No existe base de datos %s, por favor crearla.\n" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "No se puede abrir la base de datos=%s. ERR=%s\n" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "desconocido" #: src/cats/ingres.c:82 #, fuzzy msgid "Failed to allocate space for query filter.\n" msgstr "No se pudo asignar memoria para la firma de cifrado.\n" #: src/cats/ingres.c:103 #, fuzzy msgid "Failed to allocate space for query filters.\n" msgstr "No se pudo asignar memoria para la firma de cifrado.\n" #: src/cats/ingres.c:257 #, fuzzy, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" "No se puede conectar al servidor MySQL.\n" "Base de Datos=%s Usuario=%s\n" #: src/cats/ingres.c:1031 #, fuzzy msgid "A user name for Ingres must be supplied.\n" msgstr "Un nombre de usuario para DBI debe ser suministrado.\n" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "Error obteniendo fila: %s\n" #: src/cats/sql_get.c:150 #, fuzzy, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "get_file_record falta 1 obtuvo filas=%d\n" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "Registro File para PathID=%s FilenameID=%s no encontrado.\n" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "Registro File no se encuentra en Catalogo.\n" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "Más de un Filename!: %s en archivo: %s\n" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "Obtener registro BD Filename %s encuentro registro malo: %d\n" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "Registro Filename: %s no encontrado.\n" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "Registro Filename: %s no encontrado en Catalogo.\n" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "Obtener registro ruta %s de BD encontró malo registro: %s\n" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "Registro Path: %s no encontrado.\n" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "Registro Path: %s no encontrado en el Catalogo.\n" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "No se encontró un job para el JobId %s\n" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "Volúmenes no encontrados para JobId=%d\n" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "Error obteniendo fila %d: ERR=%s\n" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "Volúmenes para JobId=%d no encontrado en el Catalogo.\n" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "Fallo al selecciona id del Pool: ERR=%s\n" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "Fallo al seleccionar ID del Cliente: ERR=%s\n" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "Mas de un Poll!: %s\n" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "Registro del Pool no encontrado en Catalogo.\n" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "Mas de un Cliente!: %s\n" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "Registro de cliente no encontrado en catalogo.\n" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "Mas de un Contador!: %d\n" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "error al obtener fila Contador: %s\n" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "registro Contador: %s no encontrado en Catalogo.\n" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "Error al obtener %s FileSets pero se esperaba sólo uno!\n" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "Registro FileSet \"%s\" no encontrado.\n" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "Registro FileSet no encontrado en Catalogo.\n" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "Fallo al seleccionar ID del Medio: ERR=%s\n" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "Consulta fallida a dbids: ERR=%s\n" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "Mas de un Volumen!: %s\n" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "Registro Media MediaID=%s no encontrado.\n" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "Registro Media para Volumen \"%s\" no encontrado.\n" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "Registro Media para MediaId=%u no encontrado en el Catalogo.\n" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "Registro Media para Volumen=%s no encontrado en el Catalogo.\n" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, fuzzy, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "Fallo al selecciona id del Pool: ERR=%s\n" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 #, fuzzy msgid "Quota record not found in Catalog.\n" msgstr "Registro del Pool no encontrado en Catalogo.\n" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 #, fuzzy msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "Registro del Pool no encontrado en Catalogo.\n" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" "Error de codificación de la base de datos \"%s\". Busco SQL_ASCII, obtuvo %" "s\n" #: src/cats/postgresql.c:236 #, fuzzy, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "No se puede conectar al servidor PostgreSQL.\n" "Base de datos=%s Usuario=%s\n" ", probablemente no funciona o tu contraseña es incorrecta.\n" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "PQescapeStringConn devuelto no-cero.\n" #: src/cats/postgresql.c:387 #, fuzzy msgid "PQescapeByteaConn returned NULL.\n" msgstr "PQescapeStringConn devuelto no-cero.\n" #: src/cats/postgresql.c:418 #, fuzzy msgid "PQunescapeByteaConn returned NULL.\n" msgstr "PQescapeStringConn devuelto no-cero.\n" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "error al obtener el valor: %s\n" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "Error finalizando modo batch: %s" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "Error copiando en modo batch: %s" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "Un nombre de usuario para PostgreSQL debe de ser suministrado.\n" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 #, fuzzy msgid "Catalog Backends Dir not configured.\n" msgstr "TLS activado, pero no configurado.\n" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, fuzzy, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "No se puede abrir archivo %s: ERR=%s\n" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, fuzzy, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "Fallo buscando por loadPlugin en plugin %s: ERR=%s\n" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, fuzzy, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "Fallo buscando por loadPlugin en plugin %s: ERR=%s\n" #: src/cats/cats_backends.c:236 #, fuzzy, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "No se puede abrir archivo %s: ERR=%s\n" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "Ningún registro para %d %s\n" #: src/console/console_conf.c:143 #, fuzzy, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "Console: nombre=%s rcfile=%s histfile=%s\n" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "Director: nombre=%s dirección=%s DIRport=%d\n" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "Tipo de recurso desconocido %d\n" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "Ítem %s es necesario en recurso %s, pero no se encuentra.\n" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" "Segundo intento de definir recurso %s llamado \"%s\" no está permitido.\n" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" "\n" "Versión: " #: src/console/console.c:170 msgid "input from file" msgstr "entrada desde archivo" #: src/console/console.c:171 msgid "output to file" msgstr "salida a archivo" #: src/console/console.c:172 msgid "quit" msgstr "salir" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "salida a archivo y pantalla" #: src/console/console.c:174 msgid "sleep specified time" msgstr "tiempo de espera especificado" #: src/console/console.c:175 msgid "print current time" msgstr "imprimir hora actual" #: src/console/console.c:176 msgid "print Console's version" msgstr "imprimir la versión de la Consola" #: src/console/console.c:177 msgid "echo command string" msgstr "cadena de comando echo" #: src/console/console.c:178 msgid "execute an external command" msgstr "ejecutar un comando externo" #: src/console/console.c:179 msgid "exit = quit" msgstr "exit = salir" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "zed_keys = usar las teclas zed en lugar de teclas bash" #: src/console/console.c:181 msgid "help listing" msgstr "listado de ayuda" #: src/console/console.c:183 msgid "set command separator" msgstr "configurar separador de comandos" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr ": es un comando invalido\n" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "Ilegal carácter de separación.\n" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "Problema lógico de comando\n" #: src/console/console.c:996 #, fuzzy, c-format msgid "Can't find %s in Director list\n" msgstr "No se puede encontrar el recurso Director %s\n" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "Directors disponibles:\n" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "%2d: %s en %s:%d\n" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "Seleccione Director introduciendo un numero:" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "%s no es un número. Debe introducir un número entre 1 y %d\n" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "Debe de introducir un numero entre 1 y %d\n" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "Inicialización de la librería de criptografía ha fallado.\n" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "Por favor, corrija el archivo de configuración: %s\n" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "Conectando al Director %s:%d\n" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "Fallo al inicializar el contexto TLS para la consola \"%s\".\n" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "Fallo al inicializar el contexto TLS para el Director \"%s\".\n" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "Introduzca un período para cancelar un comando.\n" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "Se requiere TLS pero no está configurado en Bareos.\n" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" "Ni \"Certificado TLS CA\" o \"Directorio de Certificado TLS CA\" están " "definidos para Director \"%s\" en %s. Por lo menos un almacén de " "Certificados CA es necesario.\n" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" "Recurso Director no definido en %s\n" "Sin eso no sé cómo hablar con el Director :-(\n" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" "Ni \"Certificado TLS CA\" o \"Directorio de Certificado TLS CA\" están " "definidos para Console \"%s\" en %s.\n" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "Demasiados argumentos en comando de entrada.\n" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "" "Primer argumento para comandos de entrada debe ser un nombre de archivo.\n" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "No se puede abrir el archivo %s para entrada. ERR=%s\n" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "Demasiados argumentos en la salida del comando output/tee.\n" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "No se puede abrir el archivo %s para salida. ERR=%s\n" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "Demasiados argumentos. Incluya comando entre comillas dobles.\n" #: src/console/console.c:1600 #, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "No puede popen(\"%s\", \"r\"): ERR=%s\n" #: src/console/console.c:1612 #, c-format msgid "Autochanger error: ERR=%s\n" msgstr "Auto-cambiador error: ERR=%s\n" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "Recurso pool" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "No se encuentran en la especificación del Storage en Job or Pool.\n" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, fuzzy, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "Iniciar Respaldo JobId %s, Job=%s\n" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "Error al obtener el registro del Job para reporte de trabajo: ERR=%s" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "Error al obtener registro de Clientes para reporte de Job: ERR=%s" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "Respaldo OK" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "Respaldo OK -- con advertencias" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "***Error en Respaldo ***" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "Respaldo Cancelado" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "Inadecuado código de terminación: %c\n" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "No se pudo obtener registro de Job. ERR=%s\n" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "No se pudo obtener Parámetros de Volumen de Job. ERR=%s\n" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "No se puede crear el archivo bootstrap %s. ERR=%s\n" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" "Ninguno archivo encontrado para leer. Ninguno archivo bootstrap escrito.\n" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "Error escribiendo archivo bsr.\n" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "Registros Bootstrap escritos para %s\n" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" "El job irá requerir los siguientes\n" " Storage(s) Dispositivo(s) SD Volumen(es)\n" "===========================================================================\n" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "Volúmenes no encontrados para restaurar.\n" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" "\n" "Volúmenes marcados con \"*\" están en línea.\n" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "No se puede abrir el archivo de arranque %s: ERR=%s\n" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, c-format msgid "Could not get storage resource '%s'.\n" msgstr "No se pudo obtener recurso de almacenamiento '%s'.\n" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "Inicio Admin JobId %d, Job=%s\n" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "Administración Ok" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "***Administración Error***" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "Administración Cancelada" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: dird [-f -s] [-c archivo_configuración] [-d nivel_depuración] " "[archivo_configuración]\n" " -c establecer archivo de configuración para archivo \n" " -d establecer el nivel de depuración para \n" " -dt imprimir timestamp en salida de depuración\n" " -f ejecutar en primer plano (para depuración)\n" " -g groupid\n" " -m imprimir salida kaboom para depuración)\n" " -r ejecutar ahora\n" " -s sin señales\n" " -t prueba - leer la configuración y salir\n" " -u userid\n" " -v mensajes de usuario detallados\n" " -? imprimir este mensaje.\n" "\n" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "Demasiadas solicitudes de recarga abiertas. Solicitud ignorada.\n" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "Fuera de entradas de las tablas recargadas. Abandonando.\n" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "Restablecimiento de la configuración anterior.\n" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" "Recurso Director no definido en %s\n" "Sin eso no sé quién soy :-(\n" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "Recursos de Mensajes no definidos en %s\n" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "Sólo un recurso Director permitido en %s\n" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 #, fuzzy msgid "TLS required but not configured in BAREOS.\n" msgstr "Se requiere TLS pero no está configurado en Bareos.\n" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "\"Certificado TLS\" archivo no definido para director \"%s\" en %s.\n" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "\"Clave TLS\" archivo no definido para director \"%s\" en %s.\n" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Ninguno \"TLS CA Certificate\" o \"TLS CA Certificate Dir\" esta definido " "para Director \"%s\" en %s. Al menos un almacén de certificado CA es " "requerido cuando se utiliza \"TLS Verify Peer\".\n" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "Fallo al inicializar contexto TLS para Director \"%s\" en %s.\n" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "Registros de Job no definidos en %s\n" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" "Archivo de \"Certificado TLS\" no definido para Console \"%s\" en %s.\n" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "Archivo de \"Llave TLS\" no definido para Console \"%s\" en %s.\n" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Ninguno \"TLS CA Certificate\" o \"TLS CA Certificate Dir\" esta definido " "para Console \"%s\" en %s. Al menos un almacén de certificado CA es " "requerido cuando se utiliza \"TLS Verify Peer\".\n" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "Fallo al inicializar contexto TLS para demonio File \"%s\" en %s.\n" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" "Ninguno \"TLS CA Certificate\" o \"TLS CA Certificate Dir\" esta definido " "para demonio File \"%s\" en %s.\n" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" "Ninguno \"TLS CA Certificate\" o \"TLS CA Certificate Dir\" esta definido " "para Storage \"%s\" en %s.\n" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "Fallo al inicializar contexto TLS para Storage \"%s\" en %s.\n" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, fuzzy, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "No se pudo abrir Catálogo \"%s\", base de datos \"%s\".\n" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "No se pudo abrir Catálogo \"%s\", base de datos \"%s\".\n" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "%s" #: src/dird/dird.c:1110 #, fuzzy, c-format msgid "Could not create storage record for %s\n" msgstr "No es posible crear el registro Pool. ERR=%s\n" #: src/dird/dird.c:1119 #, fuzzy, c-format msgid "Could not update storage record for %s\n" msgstr "No se pudo actualizar el registro de trabajo. ERR=%s\n" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "No se ha podido compilar patrón regex \"%s\" ERR=%s\n" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" "Fin auto podar(prune).\n" "\n" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" "Advertencia, saltando los parámetros adicionales para el directorio de " "trabajo/dbname/usuario/contraseña/maquina.\n" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" "Error, no puede encontrar el nombre del Catálogo [%s] en el archivo [%s] de " "configuración dado\n" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" "Error, no hay una sección de Catálogo en el archivo de configuración dado [% " "s]\n" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "Error, recurso Director no definido.\n" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "Número incorrecto de argumentos.\n" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "Directorio de trabajo no suministrado.\n" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "Puerto de la BD debe ser un valor numérico.\n" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "Puerto de la BD debe ser un valor entero.\n" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" "Hola, este es el programa de comprobación/corrección de la base de datos.\n" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "Modificación de base de datos esta activada." #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "Modificación base de datos esta desactivada." #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "Detallado esta activado.\n" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "Detallado está apagado.\n" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "Por favor seleccione la función que desea realizar.\n" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" "\n" " 1) Activar bandera modificar base de datos\n" " 2) Activar bandera detallado\n" " 3) Reparar malos registros de Nombre de Archivo\n" " 4) Reparar malos registros de Rutas\n" " 5) Eliminar registros de Nombre de Archivo duplicados\n" " 6) Eliminar registros de Rutas duplicados\n" " 7) Eliminar registros de Jobmedia huérfanos\n" " 8) Eliminar registros de Archivo huérfanos\n" " 9) Eliminar registros de Rutas huérfanos\n" " 10) Eliminar registros de nombre de archivo huérfanos\n" " 11) Eliminar registros de FileSet huérfanos\n" " 12) Eliminar registros de Cliente huérfanos\n" " 13) Eliminar registros de Job huérfanos\n" " 14) Eliminar todos los registros de Administración\n" " 15) Eliminar todos los registros de Restauración\n" " 16) Todos (3-15)\n" " 17) Salir\n" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" "\n" " 1) Activar bandera modificar base de datos\n" " 2) Activar bandera detallado\n" " 3) Verificar malos registros de Nombre de Archivo\n" " 4) Verificar malos registros de Rutas\n" " 5) Verificar registros de Nombre de Archivo duplicados\n" " 6) Verificar registros de Rutas duplicados\n" " 7) Verificar registros de Jobmedia huérfanos\n" " 8) Verificar registros de Archivo huérfanos\n" " 9) Verificar registros de Rutas huérfanos\n" " 10) Verificar registros de nombre de archivo huérfanos\n" " 11) Verificar registros de FileSet huérfanos\n" " 12) Verificar registros de Cliente huérfanos\n" " 13) Verificar registros de Job huérfanos\n" " 14) Verificar todos los registros de Administración\n" " 15) Verificar todos los registros de Restauración\n" " 16) Todos (3-15)\n" " 17) Salir\n" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "Seleccione número de función:" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "Base de datos será modificada.\n" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "Base de datos NO será modificada.\n" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "JobId=%s Nombre=\"%s\" HoraInicio=%s\n" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "Huérfanos JobMediaId=%s JobId=%s Volumen=\"%s\"\n" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "Huérfanos FileId=%s JobId=%s Volumen=\"%s\"\n" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "Huérfanos FileSetId=%s FileSet=\"%s\" MD5=%s\n" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "Huérfanos ClientId=%s Nombre=\"%s\"\n" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "Eliminando: %s\n" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "Comprobando entradas Nombre de Archivo(Filename) duplicadas.\n" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "Encontrados %d registros Nombre de Archivo(Filename) duplicados.\n" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "Imprimir la lista? (sí/no):" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "Encontrados %d para: %s\n" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "Comprobando entradas Path duplicadas.\n" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "Encontrados %d registros de Rutas duplicados.\n" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "Imprimirlos? (sí/no):" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "Comprobando entradas JobMedia huérfanas.\n" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "Encontrados %d registros JobMedia huérfanos.\n" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "Eliminando %d registros JobMedia huérfanos.\n" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "Comprobando entradas Files huérfanas. Esto puede tomar algún tiempo.\n" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "Encontrados %d registros File huérfanos.\n" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "Eliminando %d registros File huérfanos.\n" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "Crear índice temporal? (sí/no):" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" "Comprobando de entradas huérfanas de Ruta. Esto puede tomar algún tiempo!\n" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "Se han encontrado %d registros huérfanos de Ruta.\n" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "Eliminando %d registros huérfanos de Ruta.\n" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" "Comprobando de entradas de Nombre de Archivo huérfanos. Esto puede tomar " "algún tiempo!\n" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "Se han encontrado %d registros de Nombre de Archivos huérfanos.\n" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "Eliminando %d registros de Nombre de Archivos huérfanos.\n" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" "Comprobando de entradas FileSet huérfanos. Esto puede tomar algún tiempo!\n" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "Se han encontrado %d registros FileSet huérfanos.\n" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "Eliminando %d registros FileSet huérfanos.\n" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" "Comprobando entradas de Clientes huérfanos. Esto puede tomar algún tiempo!\n" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "Se han encontrado %d registros de Clientes huérfanos.\n" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "Eliminando %d registros de Clientes huérfanos.\n" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" "Comprobando entradas de Job huérfanos. Esto puede tomar algún tiempo!\n" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "Se han encontrado %d registros de Job huérfanos.\n" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "Eliminando %d registros de Job huérfanos.\n" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "Eliminando registros JobMedia de registros de Job huérfanos.\n" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "Eliminando registros Log de registros de Job huérfanos.\n" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "Comprobando entradas para Job Administrativo.\n" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "Se han encontrado %d registros de Job Administrativo.\n" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "Eliminando %d registros de Job Administrativo.\n" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "Comprobando entradas para Job de Restauración.\n" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "Se han encontrado %d registros de Job de Restauración.\n" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "Eliminando %d registros de Job de Restauración.\n" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "Comprobando Nombres de Archivo con una barra diagonal\n" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "Se han encontrado %d malos registros de Nombre de Archivo.\n" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "Reparando %d malos registros de Nombre de Archivo.\n" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "Comprobando Rutas sin una barra diagonal\n" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "Se han encontrado %d malos registros de Rutas.\n" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "si" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" "Listo. Índice sobre la columna %s ya existe y dbcheck funcionará más " "rápido.\n" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" "Nota. Índice sobre la columna %s no encontrado, esto puede en gran medida " "ralentizar dbcheck.\n" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "Crear índice temporal... Esto puede tomar algún tiempo!\n" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "Índice temporal creado.\n" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "Eliminar índice temporal.\n" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "Índice temporal %s eliminado.\n" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, fuzzy, c-format msgid "Error getting Quota value: ERR=%s" msgstr "Error al configurar InChanger: ERR =% s" #: src/dird/quota.c:187 #, fuzzy msgid "Quota does NOT include Failed Jobs\n" msgstr "No se pudo abrir el archivo incluir: %s\n" #: src/dird/quota.c:207 #, fuzzy, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "Error al configurar InChanger: ERR =% s" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, fuzzy, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "Error al configurar InChanger: ERR =% s" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, fuzzy, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "Configurando tamaño del bufer del bloque para %u bytes.\n" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, fuzzy, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "Error al obtener el registro del Job para reporte de trabajo: ERR=%s" #: src/dird/ua_run.c:88 #, fuzzy, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "Error al obtener registro de Clientes para reporte de Job: ERR=%s" #: src/dird/ua_run.c:102 #, fuzzy, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "Error al obtener el registro del Job para reporte de trabajo: ERR=%s" #: src/dird/ua_run.c:170 #, fuzzy, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "Error al obtener registro de Clientes para reporte de Job: ERR=%s" #: src/dird/ua_run.c:312 #, fuzzy msgid "rerun these jobids? (yes/no): " msgstr "Imprimir la lista? (sí/no):" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "OK para ejecutar? (si/mod/no): " #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "no" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "Job fallido.\n" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "Cola de Job. JobId=%s\n" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "Job no ejecutando.\n" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "mod" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "Parámetros para modificar:\n" #: src/dird/ua_run.c:550 msgid "Level" msgstr "Level" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "Storage" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "Job" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "FileSet" #: src/dird/ua_run.c:555 msgid "Restore Client" msgstr "Restaurar Client" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "Client" #: src/dird/ua_run.c:559 #, fuzzy msgid "Backup Format" msgstr "Respaldo OK" #: src/dird/ua_run.c:560 msgid "When" msgstr "Cuando " #: src/dird/ua_run.c:561 msgid "Priority" msgstr "Prioridad" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "Pool" #: src/dird/ua_run.c:571 #, fuzzy msgid "NextPool" msgstr "Pool" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "Opciones de Plug-in" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "Verificar Job" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "Bootstrap" #: src/dird/ua_run.c:582 msgid "Where" msgstr "Donde" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "Reubicar Archivo" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "Reemplazar" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "JobId" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "Seleccione los parámetros para modificar" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "Selección de usuario" #: src/dird/ua_run.c:639 #, fuzzy msgid "Please enter Backup Format: " msgstr "Por favor, introduzca un JobId para restaurar:" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" "Por favor, introduzca hora de inicio deseada YYYY-MM-DD HH:MM:SS (Enter para " "ahora)" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "Hora inválida, usando hora actual.\n" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "Introduzca nueva prioridad:" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "Prioridad debe ser un entero positivo.\n" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "Por favor, introduzca nombre de archivo Bootstrap:" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "Advertencia no puede abrir %s: ERR=%s\n" #: src/dird/ua_run.c:730 #, fuzzy msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" "Por favor, introduzca el prefijo de ruta para restaurar (/ para ninguno):" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 #, fuzzy msgid "Please enter Plugin Options string: " msgstr "Por favor, cadena de Opciones de Plugin:" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "Reemplazar:\n" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "Seleccione la opción sustituir" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" "Usted debe configurar el archivo bootstrap a NULL para poder especificar un " "jobId.\n" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "línea de comandos" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 #, fuzzy msgid "user input" msgstr "Entrada del usuario" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "Opción replace no valida: %s\n" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 #, fuzzy msgid "Storage from Run NextPool override" msgstr "Storage desde recurso Pool's NextPool " #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, c-format msgid "Level \"%s\" not valid.\n" msgstr "Nivel \"%s\" no es válido.\n" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "strip_prefix=%s add_prefix=%s add_suffix=%s\n" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "Este sustituirá a su actual valor Donde\n" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "Eliminar prefijo" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "Añadir prefijo" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "Añadir sufijo de archivo" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "Introduzca una expresión regular" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "Prueba de la manipulación de nombre de archivo" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "Usar esto ?" #: src/dird/ua_run.c:1028 #, fuzzy msgid "Please enter the path prefix to strip: " msgstr "Por favor, introduzca la ruta de prefijo para eliminar:" #: src/dird/ua_run.c:1035 #, fuzzy msgid "Please enter the path prefix to add (/ for none): " msgstr "" "Por favor, introduzca el prefijo de la ruta para añadir (/ para ninguno):" #: src/dird/ua_run.c:1046 #, fuzzy msgid "Please enter the file suffix to add: " msgstr "Por favor, introduzca el sufijo de archivo para añadir:" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "Por favor, introduzca una expresión regular válida (!from!to!):" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "regexdonde=%s\n" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "strip_prefix=%s add_prefix=%s add_suffix=%s resultado=%s\n" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "No se pudo utilizar su regexp\n" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "Por favor, introduzca el nombre de archivo de prueba:" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "%s -> %s\n" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "No puede utilizar su expresión regular.\n" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "Niveles:\n" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "Completo" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "Incremental" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "Diferencial" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "Desde" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "VirtualFull" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "Seleccionar Nivel" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "Iniciar Catálogo" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "Verificar Catálogo" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "Verificar volumen de catalogo" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "Verificar disco de catalogo" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "Verificar volumen de datos (aún no implementado)" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "Nivel no adecuado para este trabajo. No se puede cambiar.\n" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "*Ninguno*" #: src/dird/ua_run.c:1236 #, fuzzy, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" "Ejecutar %s job\n" "JobName: %s\n" "FileSet: %s\n" "Cliente: %s\n" "Storage: %s\n" "Cuando: %s\n" "Prioridad: %d\n" #: src/dird/ua_run.c:1288 #, fuzzy, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" "Ejecutar %s job\n" "Nombre del Job: %s\n" "Nivel: %s\n" "Cliente: %s\n" "FileSet: %s\n" "Pool: %s (Desde %s)\n" "Storage: %s (Desde %s)\n" "Cuando: %s\n" "Prioridad: %d\n" "%s%s%s" #: src/dird/ua_run.c:1328 #, fuzzy, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "No se ha podido obtener el registro Job para Job anterior. ERR=%s" #: src/dird/ua_run.c:1367 #, fuzzy, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" "Ejecutar %s job\n" "JobName: %s\n" "Level: %s\n" "Cliente: %s\n" "FileSet: %s\n" "Pool: %s (Desde %s)\n" "Storage: %s (Desde %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "Cuando: %s\n" "Prioridad: %d\n" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "Por favor, introduzca un JobId para restaurar:" #: src/dird/ua_run.c:1438 #, fuzzy, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "Ejecutar Job de Restauración\n" "Nombre del Job: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Reemplazar: %s\n" "FileSet: %s\n" "Cliente de Respaldo: %s\n" "Cliente de Restauración: %s\n" "Storage: %s\n" "Cuando: %s\n" "Catalogo: %s\n" "Prioridad: %d\n" "Opciones de Plugin: %s\n" #: src/dird/ua_run.c:1498 #, fuzzy, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "Ejecutar Job de Restauración\n" "Nombre del Job: %s\n" "Bootstrap: %s\n" "Donde: %s\n" "Reemplazar: %s\n" "FileSet: %s\n" "Respaldo Cliente: %s\n" "Restaurar Cliente: %s\n" "Storage: %s\n" "Cuando: %s\n" "Catalogo: %s\n" "Prioridad: %d\n" "Opciones de Plugin: %s\n" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" "Ejecutar Job Restaurar\n" "JobName: %s\n" "Bootstrap: %s\n" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "RegexWhere: %s\n" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "Donde: %s\n" #: src/dird/ua_run.c:1546 #, fuzzy, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "Remplazar: %s\n" "Cliente: %s\n" "Storage: %s\n" "JobId: %s\n" "Cuando: %s\n" "Catalogo: %s\n" "Prioridad: %d\n" "Opciones de Plugin: %s\n" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, fuzzy, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" "Ejecutar Job de Restauración\n" "Nombre del Job: %s\n" "Bootstrap: %s\n" "Donde: %s\n" "Reemplazar: %s\n" "FileSet: %s\n" "Respaldo Cliente: %s\n" "Restaurar Cliente: %s\n" "Storage: %s\n" "Cuando: %s\n" "Catalogo: %s\n" "Prioridad: %d\n" "Opciones de Plugin: %s\n" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "Ejecutar Job de Copia\n" #: src/dird/ua_run.c:1602 msgid "Run Migration job\n" msgstr "Ejecutar Job de Migración\n" #: src/dird/ua_run.c:1604 #, fuzzy, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" "Ejecutar %s job\n" "JobName: %s\n" "Level: %s\n" "Cliente: %s\n" "FileSet: %s\n" "Pool: %s (Desde %s)\n" "Storage: %s (Desde %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "Cuando: %s\n" "Prioridad: %d\n" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "Tipo de Job desconocido=%d\n" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "Falta valor para la palabra clave %s\n" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "Nombre del Job especificado dos veces.\n" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "JobId especificada dos veces.\n" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "Cliente especificado dos veces.\n" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "FileSet especificado dos veces.\n" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "Level especificado dos veces.\n" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "Storage especificado dos veces.\n" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "RegexDónde o Dónde especificado dos veces.\n" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "Sin autorización para especificación \"regexwhere\".\n" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "Dónde o RegexDónde especificado dos veces.\n" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "Sin autorización para especificación \"where\".\n" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "Bootstrap especificado dos veces.\n" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "Replace especificado dos veces.\n" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "Cuando especificado dos veces.\n" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "Prioridad especificada dos veces.\n" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "Prioridad debe ser positivo y distinto a cero, configurando en 10.\n" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "Job Verificar especificado dos veces.\n" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "Job Migración especificado dos veces.\n" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "Pool especificado dos veces.\n" #: src/dird/ua_run.c:1870 #, fuzzy msgid "NextPool specified twice.\n" msgstr "Pool especificado dos veces.\n" #: src/dird/ua_run.c:1886 msgid "Restore Client specified twice.\n" msgstr "Restaurar Cliente especificado dos veces.\n" #: src/dird/ua_run.c:1894 msgid "Plugin Options specified twice.\n" msgstr "Opciones de Plugin especificado dos veces.\n" #: src/dird/ua_run.c:1899 #, fuzzy msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "Sin autorización para especificación \"PluginOptions\".\n" #: src/dird/ua_run.c:1906 msgid "Spool flag specified twice.\n" msgstr "Bandera de cola especificada dos veces.\n" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "Invalida bandera spooldata.\n" #: src/dird/ua_run.c:1922 #, fuzzy msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "Bandera de cola especificada dos veces.\n" #: src/dird/ua_run.c:1929 #, fuzzy msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "Invalida bandera spooldata.\n" #: src/dird/ua_run.c:1934 #, fuzzy msgid "Accurate flag specified twice.\n" msgstr "Bandera de cola especificada dos veces.\n" #: src/dird/ua_run.c:1941 #, fuzzy msgid "Invalid accurate flag.\n" msgstr "Invalida bandera spooldata.\n" #: src/dird/ua_run.c:1946 #, fuzzy msgid "Backup Format specified twice.\n" msgstr "Bootstrap especificado dos veces.\n" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "Palabra clave inválida: %s\n" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "Catalogo \"%s\" no encontrado\n" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "Sin autorización. Catalogo \"%s\".\n" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "Job \"%s\" no encontrado\n" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "Un nombre de job debe de ser especificado.\n" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "Sin autorización. Job \"%s\".\n" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "Pool \"%s\" no encontrado.\n" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "Sin autorización. Pool \"%s\".\n" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "Storage \"%s\" no encontrado\n" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "Almacenamiento no especificado.\n" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "Sin autorización. Storage \"%s\".\n" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "Cliente \"%s\" no encontrado.\n" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "Sin autorización. Cliente \"%s\".\n" #: src/dird/ua_run.c:2112 #, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "Restaurar Cliente \"%s\" no encontrado.\n" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "FileSet \"%s\" no encontrado.\n" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "Sin autorización. FileSet \"%s\".\n" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "Job Verificar \"%s\" no encontrado.\n" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "Job Migración \"%s\" no encontrado.\n" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "Estado disponible para:\n" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "Seleccione el tipo de demonio para estado" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "%s Versión: %s (%s) %s %s %s\n" #: src/dird/ua_status.c:390 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "Demonio iniciado %s, %d Job ejecutando desde el inicio.\n" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 #, fuzzy msgid "No clients defined.\n" msgstr "Recurso %s no definido\n" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 #, fuzzy msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "Ignorando valor invalido para días. Máximo es 50.\n" #: src/dird/ua_status.c:774 msgid "Date" msgstr "Fecha" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 #, fuzzy msgid "Schedule" msgstr "" "\n" "Scheduled Jobs:\n" #: src/dird/ua_status.c:774 #, fuzzy msgid "Overrides" msgstr "anular ejecutar" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" "\n" "Scheduled Jobs:\n" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "Nivel Tipo Pri Scheduled Nombre Volumen\n" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "===================================================================================\n" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "%-14s %-8s %3d %-18s %-18s %s\n" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "Ignorando valores inválidos para el día. Máximo es de 500.\n" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "No hay Jobs Programados.\n" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" "\n" "Jobs Ejecutando:\n" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "Consola conectada en %s\n" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" "Ningún Jobs ejecutando.\n" "====\n" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "JobId Nivel Nombre Estado\n" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "======================================================================\n" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "esta esperando ejecución" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "esta ejecutando" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "esta bloqueado" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "ha terminado" #: src/dird/ua_status.c:1034 msgid "has terminated with warnings" msgstr "ha terminado con advertencias" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "ha errado" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "tiene errores" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "tiene un error fatal" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "ha verificar diferencias" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "ha sido cancelado" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "esta esperando por Client" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "esta esperando por Cliente %s" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, fuzzy, c-format msgid "is waiting on Storage \"%s\"" msgstr "esta esperando por Storage %s" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "esta esperando por Storage" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "esta esperando por máximo Storage jobs" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "esta esperando por máximo Cliente jobs" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "esta esperando por máximo Jobs jobs" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "esta esperando por máximo total jobs" #: src/dird/ua_status.c:1090 #, fuzzy, c-format msgid "is waiting for its start time at %s" msgstr "esta esperando por su hora de inicio" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "esta esperando por su hora de inicio" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "está esperando por jobs de una mayor prioridad para terminar" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "SD perpetrando Datos" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "SD desencolando Datos" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "SD desencolando Atributos" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "Insertando Atributos Dir" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "esta en estado desconocido %c" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "esta esperando por petición de montaje" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "está esperando un Volumen appendable" #: src/dird/ua_status.c:1144 msgid "is waiting for Client to connect to Storage daemon" msgstr "está esperando por cliente para conectarse al demonio Storage" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "está aguardando por el Cliente %s para conectarse al Storage %s" #: src/dird/ua_status.c:1177 #, fuzzy, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "%6d\t%-6s\t%-20s\t%s\n" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "%6d %-6s %-20s %s\n" #: src/dird/ua_status.c:1185 #, fuzzy, c-format msgid " %-30s\n" msgstr "Job : %s\n" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "Jobs No Terminados.\n" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" "\n" "Jobs No Terminados:\n" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "JobId Nivel Archivos Bytes Estado Finalizado Nombre \n" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "====================================================================\n" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "Creado" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "Error" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "Diferencias" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "Cancelar" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "OK" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "OK - con advertencias" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "Otros" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "%6d %-6s %8s %10s %-7s %-8s %s\n" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "\n" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 msgid "No Volumes found, or no barcodes.\n" msgstr "Volúmenes no encontrados, o no códigos de barras.\n" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "No hay ranuras en cambiador para analizar.\n" #: src/dird/ua_status.c:1524 #, fuzzy msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "Ranura | Nombre Volumen | Estado | Tipo de Media | Pool |\n" #: src/dird/ua_status.c:1525 #, fuzzy msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" "------+------------------+-----------+----------------------" "+--------------------|\n" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "Ranura %d mayor que el máximo %d ignorado.\n" #: src/dird/msgchan.c:159 #, fuzzy, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "Storage daemon rechazo Job comando: %s\n" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "Storage daemon rechazo Job comando: %s\n" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" "\n" "Utilice: testfind [-d nivel_ depuración] [-] [patrón1 ...]\n" " -a imprime atributos extendidos (depuración de Win32)\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -c especifica archivo de conteniendo recursos FileSet\n" " -f especifica cual FileSet para usar\n" " -? imprime esta mensaje.\n" "\n" "Los patrones son archivos de inclusión - normalmente directorios.\n" "Nivel de depuración >= 1 imprime cada archivo encontrado.\n" "Nivel de depuración >= 10 imprime ruta/archivo para catalogo.\n" "Los errores siempre se imprimen.\n" "Archivos/rutas truncados es numero con longitud > 255.\n" "Truncamiento es sólo en catálogo..\n" "\n" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" "\n" "Total de Archivos : %d\n" "Longitud máxima de archivo: %d\n" "Longitud máxima de ruta: %d\n" "Archivos truncados: %d\n" "Rutas truncadas: %d\n" "Enlaces duros : %d\n" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "Reg: %s\n" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "\t[no descenderá: recursividad desactivado]" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "\t[no descenderá: no permitido cambio de sistema de archivo]" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "\t[no descenderá: sistema de archivo no permitido]" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "\t[no descenderá: tipo de unidad no permitido]" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "Err: No es posible acceder %s: %s\n" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "Err: no podía seguir ff->link %s: %s\n" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "Err: no se pudo stat %s: %s\n" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "Saltar: Archivo no guardado. Sin cambios. %s\n" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "Err: Intento de copia de seguridad. No guardado. %s\n" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "Err: no se pudo abrir el directorio %s: %s\n" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "Err: Archivo desconocido ff->tipo %d: %s\n" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "===== Nombre de Archivo truncado para 255 caracteres: %s\n" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "========== Nombre de Ruta truncado para 255 caracteres: %s\n" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "========== La longitud de la ruta es nula. Archivo=%s\n" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "Ruta: %s\n" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "Archivo: %s\n" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "Opción incluir/excluir desconocida: %c\n" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "Conteo no actualizo contador %s: ERR=%s\n" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "No se puede crear contexto var: ERR=%s\n" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "No se puede establecer llamada var: ERR=%s\n" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "No se puede establecer variable operar: ERR=%s\n" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "No se puede unescapar cadena: ERR=%s\n" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "No se puede ampliar la expresión \"%s\": ERR=%s\n" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "No se puede destruir variable contexto: ERR=%s\n" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "No se puede usar comando %s en un runscript" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr ": es un comando inválido.\n" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "No se puede obtener el registro Job para JobId=%s: ERR=%s\n" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "No se pudo abrir socket SD.\n" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "Conectado al demonio Storage\n" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "Conectando al Cliente %s en %s:%d\n" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "Fallo al conectar con el cliente.\n" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, fuzzy, c-format msgid "Unknown command: %s\n" msgstr "Comando desconocido." #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "Demonios disponible son: \n" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "Director" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "Seleccione tipo de demonio para matar" #: src/dird/ua_dotcmds.c:804 #, fuzzy msgid "The Director will generate a deadlock.\n" msgstr "El Director tendrá una violación de segmento.\n" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "El Director tendrá una violación de segmento.\n" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "El acceso a determinado Cliente o FileSet no permitido.\n" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "Consulta fallida: %s. ERR=%s\n" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "consulta de palabra clave no encontrada.\n" #: src/dird/ua_dotcmds.c:1116 #, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "Fallo al listar MediaType: ERR=%s\n" #: src/dird/ua_dotcmds.c:1130 #, c-format msgid "List Media failed: ERR=%s\n" msgstr "Fallo al listar Media: ERR=%s\n" #: src/dird/ua_dotcmds.c:1156 #, c-format msgid "List Location failed: ERR=%s\n" msgstr "Fallo al listar Ubicación: ERR=%s\n" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "Introduzca ranura" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "Esperaba un número entero positivo, obtuvo: %s\n" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "Respuesta no válida. Usted tiene que contestar sí o no.\n" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "Inválido valor Habilitado, debe ser sí, no, archivado, 0, 1 o 2\n" #: src/dird/ua_input.c:211 #, fuzzy, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "Carácter ilegal \"%c\" en el nombre.\n" #: src/dird/ua_input.c:218 #, fuzzy msgid "Comment too long.\n" msgstr "Nombre demasiado largo.\n" #: src/dird/ua_input.c:224 #, fuzzy msgid "Comment must be at least one character long.\n" msgstr "Nombre de volumen debe ser de al menos un carácter de largo.\n" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "Añadir medios a un pool" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "Autodisplay mensajes de la consola" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "Auto-montar después de etiquetar" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "Cancelar un Job" #: src/dird/ua_cmds.c:112 #, fuzzy msgid "Configure director" msgstr "Editor de archivos de configuración" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "Crear Pool BD desde recurso" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "Eliminar volumen, pool o job" #: src/dird/ua_cmds.c:118 #, fuzzy msgid "Disable a job/client/schedule" msgstr "Deshabilitar un job" #: src/dird/ua_cmds.c:120 #, fuzzy msgid "Enable a job/client/schedule" msgstr "Habilitar un job" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "Realiza estimación FileSet, listando lista completa" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "Terminar la sesión bconsole" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "Modo gui no-interactivo" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "Imprimir ayuda en comandos específicos" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "Etiquetar una cinta" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "Listar objetos del catálogo" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "Completo o lista larga como la lista de comando" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "Mostrar mensajes pendientes" #: src/dird/ua_cmds.c:159 msgid "Print current memory usage" msgstr "Imprimir uso de la memoria actual" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "Montar Storage" #: src/dird/ua_cmds.c:164 #, fuzzy msgid "Move slots in an autochanger" msgstr "prueba Autochanger" #: src/dird/ua_cmds.c:166 #, fuzzy msgid "Prune records from catalog" msgstr "Purgar registros del catálogo" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "Purgar registros del catálogo" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "Consulta de catálogo " #: src/dird/ua_cmds.c:175 msgid "Restore files" msgstr "Restaurar Archivos" #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "Reetiquetar una cinta" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "Liberar Storage" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "Recargar archivo de configuración" #: src/dird/ua_cmds.c:190 #, fuzzy msgid "Rerun a job" msgstr "Ejecutar un Job" #: src/dird/ua_cmds.c:192 #, fuzzy msgid "Resolve a hostname" msgstr "no se puede resolver el hostname(%s) %s" #: src/dird/ua_cmds.c:194 msgid "Run a job" msgstr "Ejecutar un Job" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "Informe de estado" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "Establecer el nivel de depuración" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "Establecer nueva dirección del cliente - si esta autorizado" #: src/dird/ua_cmds.c:214 msgid "Show resource records" msgstr "Mostrar los registros de recursos" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "usar SQL para consultar el catálogo" #: src/dird/ua_cmds.c:221 msgid "Print current time" msgstr "Imprimir hora actual" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "Activar/desactivar archivo de traza" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "Desmonte almacenamiento" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "Umount - para los viejos tiempos tipos de Unix, véase unmount" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "Actualizar volumen, pool o stats" #: src/dird/ua_cmds.c:240 #, fuzzy msgid "Use specific catalog" msgstr "Usar catálogo xxx" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "es la variable de expansión" #: src/dird/ua_cmds.c:244 msgid "Print Director version" msgstr "Imprimir la versión del Director" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "Esperar hasta que no se estén ejecutando jobs" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "%s: es un comando invalido.\n" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" "Usted probablemente no quiere usar este comando, ya que el\n" "crea registros en la base de datos sin etiquetar los volúmenes.\n" "Usted probablemente desea utilizar el comando \"label\".\n" "\n" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "Pool ya tiene volúmenes máximo=%d\n" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "Introduzca nuevo máximo (cero para un número ilimitado):" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" "Introduzca el número de volúmenes para crear. 0=>nombre fijo. Máximo=%d:" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "El número debe estar comprendido entre 0 y %d\n" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "Introduzca nombre de Volumen:" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "Introduzca nombre de Volumen base:" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "Nombre de Volumen demasiado largo.\n" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "Nombre de volumen debe ser de al menos un carácter de largo.\n" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "Introduzca el número inicial:" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "Número de inicio debe ser mayor que cero.\n" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "Introduzca ranura (0 para ninguno):" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "InChanger? si/no: " #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "%d Volúmenes creados en el pool %s\n" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "Encender o apagar?" #: src/dird/ua_cmds.c:523 #, fuzzy, c-format msgid "JobId %s not a number\n" msgstr "Job %s no encontrado\n" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" "No se puede establecer %s RecyclePool para %s, %s no está¡ en la base de " "datos.\n" "Intente actualizarlo con 'update pool=%s'\n" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" "No se puede establecer %s ScratchPool para %s, %s no está en la base de " "datos.\n" "Intente actualizarlo con 'update pool=%s'\n" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" "Error: Pool %s ya existe.\n" "Use update para cambiarlo.\n" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "Pool %s creado.\n" #: src/dird/ua_cmds.c:793 #, fuzzy msgid "Failed to set bandwidth limit on Client.\n" msgstr "Fallo al conectar con el cliente.\n" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "Conectando al demonio Storage %s en %s:%d\n" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "Error al conectar con demonio Storage.\n" #: src/dird/ua_cmds.c:843 #, fuzzy msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "Fallo al conectar con el cliente.\n" #: src/dird/ua_cmds.c:881 #, fuzzy msgid "Enter new bandwidth limit kb/s: " msgstr "Introduzca nuevo Máximo de Trabajos" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "Comando no autorizado desde esta consola.\n" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "Cliente \"%s\" dirección configurada para %s\n" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "Job \"%s\" no encontrado.\n" #: src/dird/ua_cmds.c:1044 #, fuzzy, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "Job \"%s\" %sabled\n" #: src/dird/ua_cmds.c:1052 #, fuzzy, c-format msgid "Client \"%s\" %sabled\n" msgstr "Job \"%s\" %sabled\n" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "Job \"%s\" %sabled\n" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "Introduzca el nuevo nivel de depuración:" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "All" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "Seleccione el tipo de Demonio para establecer el nivel de depuración" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "No autorización para Cliente \"%s\"\n" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "Falta el nombre del cliente.\n" #: src/dird/ua_cmds.c:1488 #, fuzzy, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "Sin autorización. Storage \"%s\".\n" #: src/dird/ua_cmds.c:1495 #, fuzzy msgid "Storage name missing.\n" msgstr "Falta el nombre del Job.\n" #: src/dird/ua_cmds.c:1520 #, fuzzy, c-format msgid "%s Failed to resolve %s\n" msgstr "3914 No se ha podido etiquetar el volumen (no hay medios): ERR=%s\n" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, fuzzy, c-format msgid "%s resolves %s to %s\n" msgstr "%s recurso %s no encontrado.\n" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "No autorización para Job \"%s\"\n" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "Falta el nombre del Job.\n" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "FileSet \"%s\" no encontrado.\n" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "No autorización para FileSet \"%s\"\n" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "Falta Nombre del Fileset.\n" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "Valor del nivel ausente.\n" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "Valor no válido para exacto. Debe ser sí o no.\n" #: src/dird/ua_cmds.c:1667 #, fuzzy msgid "Accurate value missing.\n" msgstr "Valor del nivel ausente.\n" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "Job no especificado.\n" #: src/dird/ua_cmds.c:1696 #, fuzzy, c-format msgid "Wrong job specified of type %s.\n" msgstr "Job no especificado.\n" #: src/dird/ua_cmds.c:1709 #, fuzzy msgid "No client specified or selected.\n" msgstr "Cliente especificado dos veces.\n" #: src/dird/ua_cmds.c:1714 #, fuzzy msgid "No fileset specified or selected.\n" msgstr "No hay archivos seleccionados para ser restaurado.\n" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "Error al enviar lista incluir.\n" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "Error al enviar lista excluir.\n" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" "En general, esto no es una buena idea para eliminar un\n" "Pool o un Volumen ya que pueden contener datos.\n" "\n" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "Seleccione el ítem del catalogo para eliminar" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "Nada hecho.\n" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, fuzzy, c-format msgid "Illegal JobId %s ignored\n" msgstr "Clonar JobId %d iniciado.\n" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "Introduzca jobId para eliminar:" #: src/dird/ua_cmds.c:1979 #, fuzzy, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "¿Esta usted seguro de que desea eliminar el Pool \"%s\"? (si/no):" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, fuzzy, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "Job %s y los registros asociados eliminados del catálogo.\n" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" "\n" "Este comando eliminara los volúmenes %s\n" "y todos los Jobs guardados en este volumen desde el Catalogo\n" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "¿Estas usted seguro de que desea eliminar el Volumen \"%s\"? (si/no):" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "¿Esta usted seguro de que desea eliminar el Pool \"%s\"? (si/no):" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "Utilizando Catalogo nombre=%s BD=%s\n" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "ERR: No se puede abrir db\n" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "Tiempo agotado en esperar mount \n" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "ERR: Job no se ha encontrado\n" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" "Comando Descripción\n" " ======== ==============\n" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" "%-13s %s\n" "\n" "Argumentos:\n" "\t%s\n" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr " %-13s %s\n" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" "\n" "No se puede encontrar comando %s. \n" "\n" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" "\n" "Cuando en un prompt, entrando un período cancela el comando.\n" "\n" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "%s Versión: %s (%s) %s %s %s %s\n" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "No autorización para Catalogo \"%s\"\n" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "No pudo encontrar un Catalogo de recursos\n" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "No se pudo abrir la base de datos de catálogo \"%s\".\n" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "Usando Catalogo \"%s\"\n" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "Nivel Verify no implementado %d(%c)\n" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" "No se puede encontrar JobId de Job InitCatalog anterior.\n" "Por favor, ejecutar Verificar con Nivel=InitCatalog antes de\n" " ejecutar el Job actual.\n" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "No se puede encontrar JobId del trabajo anterior por este cliente.\n" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "Último Job %d no termino normalmente. JobStatus=%c\n" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "Verificar contra JobId=%d Job=%s\n" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "Inicio Verificar JobId=%s Nivel=%s Job=%s\n" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "Función obsoleta ... use bootstrap.\n" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "Nivel Verify no implementado %d\n" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "Verificar OK" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "*** Verificar Error ***" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "Verificar advertencias" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "Verificar Cancelada" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "Verificar Diferencias" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "Inadecuado código de terminación: %d %c\n" #: src/dird/verify.c:545 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s %s (%s): %s\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verificar Nivel: %s\n" " Cliente: %s\n" " Verificar JobId: %d\n" " Verificar Job: %s\n" " Hora de inicio: %s\n" " Hora de finalización: %s\n" " Archivos Esperado: %s\n" " Archivos Examinados: %s\n" " No-fatal FD errores: %d\n" " Estado de terminación del FD: %s\n" " Estado de terminación del SD: %s\n" " Terminación: %s\n" "\n" #: src/dird/verify.c:581 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s %s (%s): %s\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verificar Nivel: %s\n" " Cliente: %s\n" " Verificar JobId: %d\n" " Verificar Job: %s\n" " Hora de Inicio: %s\n" " Hora de Finalización: %s\n" " Archivos Examinados: %s\n" " No-fatal FD errores: %d\n" " FD estado de finalización: %s\n" " Terminación: %s\n" "\n" #: src/dird/verify.c:661 #, fuzzy, c-format msgid "" "dird\" command before continuing.\n" msgstr "" "Usted debe especificar un comando \"use \" antes de " "continuar.\n" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "Los recursos Catalogo definidos son:\n" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "Catalogo" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "Seleccione recurso Catalogo" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "Los recursos Job definidos son:\n" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "Seleccione recurso Job" #: src/dird/ua_select.c:307 #, fuzzy, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "Error: recurso Pool \"%s\" no existe.\n" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "Los recursos Restore definidos son:\n" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "Seleccione recurso Restore" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "Los recursos Clientes definidos son:\n" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "Seleccione recurso Cliente (File Daemon)" #: src/dird/ua_select.c:378 #, fuzzy msgid "Select Client resource" msgstr "Seleccionar recurso FileSet" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "Error: Recurso Cliente %s no existe.\n" #: src/dird/ua_select.c:421 #, fuzzy msgid "The defined Schedule resources are:\n" msgstr "Los recursos Clientes definidos son:\n" #: src/dird/ua_select.c:432 #, fuzzy msgid "Select Schedule resource" msgstr "Seleccione recurso Pool" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "No se pudo encontrar el Cliente %s: ERR=%s" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "No se pudo encontrar Cliente \"%s\": ERR=%s" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "Error al obtener el ID del cliente. ERR=%s\n" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" "Clientes no definidos. Usted debe ejecutar un Job antes de usar este " "comando.\n" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "Clientes definidos:\n" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "Seleccione el Cliente" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "No se pudo encontrar Pool \"%s\": ERR=%s" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "Pools no definidos. Utilice el comando \"create\" para crear uno.\n" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "Pools definidos:\n" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "Seleccione el Pool" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "No tienen acceso al Pool \"%s\"\n" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "Introduzca MediaId o nombre del Volumen:" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "Los recursos Pool definidos son:\n" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "Seleccione recurso Pool" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "Error: recurso Pool \"%s\" no existe.\n" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "Introduzca el JobId para seleccionar:" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "No pudo encontrar Job \"%s\": ERR=%s" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "Seleccionado automáticamente %s: %s\n" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" "Su petición ha múltiples opciones para \"%s\". La selección no es posible en " "modo batch.\n" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "Lista de selección para \"%s\" está vacía!\n" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "Seleccionado automáticamente: %s\n" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "Selección abortada, no hay nada hecho.\n" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "Por favor, introduzca un número entre 1 y %d\n" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "Nombre de Storage especificado dos veces.\n" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "Esperando comando jobid=nn, obtuvo: %s.\n" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "JobId %s no está en ejecución.\n" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "Esperando job=xxx, obtuvo: %s.\n" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "Job \"%s\" no está en ejecución.\n" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "Esperando ujobid=xxx, obtuvo: %s.\n" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "Recurso Storage \"%s\": No encontrado\n" #: src/dird/ua_select.c:1093 #, fuzzy msgid "Select Drive:\n" msgstr "Seleccione un ítem:" #: src/dird/ua_select.c:1098 #, fuzzy msgid "Drive" msgstr "Archivo" #: src/dird/ua_select.c:1098 #, fuzzy msgid "Select drive" msgstr "Seleccionar Nivel" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "Introduzca ranura Autochanger:" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "Tipos de Media definidos en el archivo de configuración:\n" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "Tipo de Media" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "Seleccione el Tipo de Media" #: src/dird/ua_select.c:1262 #, fuzzy, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" "JobId %s no está en ejecución. Utilice el nombre del Job para cancelar jobs " "inactivo.\n" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" "Advertencia Job %s no está¡ en ejecución. Continuar de todos modos ...\n" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "No hay Jobs en ejecución.\n" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "Ninguno de sus trabajos se está ejecutando.\n" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, fuzzy, c-format msgid "Selected Job %d for cancelling\n" msgstr "Seleccione recurso Job" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "Jobs no seleccionados.\n" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "Confirmar cancelar(si/no): " #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "Seleccione Job:\n" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "JobId=%s Job=%s" #: src/dird/ua_select.c:1443 #, fuzzy, c-format msgid "Choose Job to %s" msgstr "Elija Job para cancelar" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" "Cancelar: %s\n" "\n" "%s" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "Confirmar cancelar?" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "Números negativos no permitidos.\n" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "Rango final no es entero.\n" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "Rango inicial no es entero.\n" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "Rango final no más grande que inicial.\n" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "Valor de entrada no es un entero.\n" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "Los valores deben ser ser mayor que cero.\n" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "Ranura demasiado grande.\n" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "1990 Solicitud de Catalogo no válido: %s" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "Solicitud de Catalogo no válido; BD no abierta: %s" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "1901 Ninguna Media.\n" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "no está¡ en Pool" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "Tipo de Medio incorrecto" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "no está¡ Habilitado" #: src/dird/catreq.c:203 #, fuzzy, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "1998 Volumen \"%s\" en estado %s, %s.\n" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "1197 Volumen \"%s\" no está¡ en catálogo.\n" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "No es posible obtener registro Media para el Volumen %s: ERR=%s\n" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "1991 Solicitud de Catalogo para vol=%s fallida:%s" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" "Archivos de Volumen en %u se establece en %u para Volumen \"%s\". Esto es " "incorrecto.\n" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "1992 Error de actualización de Media. VolFiles=%u, CatFiles=%u\n" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "Error de catalogo actualizando registro Media. %s" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "1993 Error de actualización de Media\n" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "Error de Catalogo al crear registro JobMedia. %s" #: src/dird/catreq.c:344 msgid "1992 Create JobMedia error\n" msgstr "1992 Error al crear JobMedia\n" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "Invalida petición de Catalogo: %s" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, fuzzy, c-format msgid "Attribute create error: ERR=%s" msgstr "error al crear Atributo.%s" #: src/dird/catreq.c:556 #, fuzzy, c-format msgid "Restore object create error. %s" msgstr "error al crear Atributo.%s" #: src/dird/catreq.c:564 #, fuzzy, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "Obtuvo %s, pero no igual que los atributos de File\n" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" "Error al actualizar el resumen de archivo de catálogo. Incompatible resumen " "de tipo de flujo: %d" #: src/dird/catreq.c:613 #, fuzzy, c-format msgid "attribute create error. %s" msgstr "error al crear Atributo.%s" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "Error de catalogo actualizando archivo de resumen. %s" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "1994 Invalido Catálogo de Actualizaciones: %s" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "Actualización de Catalogo Inválida; La Base de Datos no se abre: %s" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, fuzzy, c-format msgid "read attr spool error. ERR=%s\n" msgstr "Error fread attr spool. ERR=%s\n" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" "\n" "Este comando puede ser PELIGROSO!!!\n" "\n" "El purgas (elimina) todos los archivos de un Job,\n" "JobId, Cliente o Volumen; o el purgas (elimina)\n" "Todos los Jobs de un Cliente o Volumen sin tener en cuenta\n" "los periodos de retención. Normalmente debería utilizar el\n" "comando PRUNE, que respecta los plazos de retención.\n" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "Elija el ítem para purgar" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "Iniciando purga de archivos para Cliente \"%s\"\n" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" "No encuentra los archivos del cliente %s para purgar %s del catálogo.\n" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "Archivos para Jobs %d para cliente \"%s\" purgado del catalogo %s.\n" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "Iniciando purga de jobs para Cliente \"%s\"\n" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "Jobs %d para cliente \"%s\" purgado del catalogo %s.\n" #: src/dird/ua_purge.c:439 #, fuzzy, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "No autorización para Cliente \"%s\"\n" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" "\n" "Volumen \"%s\" tiene VolStatus \"%s\" y no puede ser purgado.\n" "El VolStatus debe ser: Añadir, Lleno, Usado, o Error para ser purgado.\n" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "%d Archivo%s en Volumen \"%s\" purgado desde el catalogo.\n" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" "No hay más Jobs relacionados con Volumen \"%s\". Marcando el para purgar.\n" #: src/dird/ua_purge.c:705 #, fuzzy msgid "Can't update volume size in the catalog\n" msgstr "Se creó un Volumen nuevo \"%s\" en el catálogo.\n" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, fuzzy, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "No se puede truncar el dispositivo %s. ERR=%s\n" #: src/dird/ua_purge.c:819 #, fuzzy, c-format msgid "No Volumes found to perform %s action.\n" msgstr "No encontraron volúmenes para etiquetar, o sin códigos de barras.\n" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" "No se puede mover el Volumen reciclado en full Pool \"%s\" MaxVols=%d\n" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" "Todos los registros del Volumen \"%s\" podados; marcando el \"Purgados\"\n" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "No se puede purgar Volumen con VolStatus=%s\n" #: src/dird/ua_audit.c:68 #, fuzzy msgid "for Job" msgstr "Job" #: src/dird/ua_audit.c:71 #, fuzzy msgid "for Client" msgstr "Client" #: src/dird/ua_audit.c:74 #, fuzzy msgid "for Storage" msgstr "Storage" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 #, fuzzy msgid "for Schedule" msgstr "" "\n" "Scheduled Jobs:\n" #: src/dird/ua_audit.c:83 #, fuzzy msgid "for Pool" msgstr "Pool" #: src/dird/ua_audit.c:86 #, fuzzy msgid "for Command" msgstr "Malo Comando Job: %s" #: src/dird/ua_audit.c:89 #, fuzzy msgid "for Fileset" msgstr "Fileset" #: src/dird/ua_audit.c:92 #, fuzzy msgid "for Catalog" msgstr "Catalogo" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 #, fuzzy msgid "for Plugin Options" msgstr "Opciones de Plug-in" #: src/dird/ua_audit.c:114 #, fuzzy, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "Console: nombre=%s\n" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, fuzzy, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "Console: nombre=%s\n" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "verificar" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 #, fuzzy msgid "base job" msgstr "Job insertado" #: src/dird/inc_conf.c:225 #, fuzzy, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "Esperaba una franja de ruta entero positivo, obtuvo: %s:" #: src/dird/inc_conf.c:233 #, fuzzy, c-format msgid "Expected a parseable size, got: %s:" msgstr "Esperaba una igual, obtuvo: %s" #: src/dird/inc_conf.c:251 #, fuzzy, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "Esperaba una palabra clave Tipo FileSet, obtuvo: %s" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "Error al compilar Regex. ERR=%s\n" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "Se esperaba una expresión regular, se obtuvo: %s\n" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "Esperada una cadena comodín, obtuvo: %s\n" #: src/dird/inc_conf.c:405 #, fuzzy, c-format msgid "Expected a fstype string, got: %s\n" msgstr "Se esperaba una cadena fstype, se obtuvo: %s\n" #: src/dird/inc_conf.c:428 #, fuzzy, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "Se esperaba una cadena drivetype, se obtuvo: %s\n" #: src/dird/inc_conf.c:450 #, fuzzy, c-format msgid "Expected a meta string, got: %s\n" msgstr "Esperaba una cadena, obtuvo: %s" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "Esperaba una palabra clave FileSet, obtuvo: %s" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "Sección Options no permitida en Exclude\n" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "Esperando abrir paréntesis. Obtuvo %s" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "Esperando palabra clave, obtuvo: %s\n" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "esperaba una igual, obtuvo: %s" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "Palabra clave %s no esta permitido en este recurso" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" "Barra invertida encontrada. Utilice barras inclinadas o cite la cadena.: %s\n" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "Se esperaba un nombre de archivo, se obtuvo: %s" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "Directiva Plugin no permitida en Exclude\n" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "Directiva ExcludeDirContaining no permitida en Excluir(Exclude).\n" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "Antiguo estilo Incluir/Excluir no soportado\n" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "Cliente:" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "Demonio File \"%s\" rechazó comando Job: %s\n" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "Error al actualizar el registro Cliente:ERR=%s\n" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "FD dio mala respuesta al comando jobId: %s\n" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "Nivel %d %c de respaldo no implementado\n" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "No se puede ejecutar el programa: %s. ERR=%s\n" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr ">filed: error de escritura en socket\n" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "Error ejecutando el programa: %s. ERR=%s\n" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "No se puede abrir el archivo incluido: %s. ERR=%s\n" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "Cliente \"%s\" RunScript fallido.\n" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 #, fuzzy msgid "Plugin options failed.\n" msgstr "Opciones de Plugin especificado dos veces.\n" #: src/dird/fd_cmds.c:828 #, fuzzy msgid "RestoreObject failed.\n" msgstr "Restaurar Archivos" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "Ejemplo : bbatch -w /ruta/para/directorio/trabajo -h localhost -f dat1 -f " "dat -f datx\n" " inicializará 3 hilos y cargará dat1, dat y datx en su catalogo\n" "Vea bbatch.c para generar archivos de datos\n" "\n" "Utilice: bbatch [opciones] -w directorio/trabajo -f archivo_de_datos\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -n especifica el nombre de la base de datos (por defecto bareos)\n" " -u especifica el nombre de usuario de la base de datos (por " "defecto bareos)\n" " -P especifica la contraseña de la base de datos (por defecto " "none)\n" " -h especifica servidor de la base de datos (por defecto NULL)\n" " -w especifica el directorio de trabajo\n" " -v detallado\n" " -f especifica archivo de datos\n" " -? imprime esta mensaje\n" "\n" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "Incorrecto numero de argumentos: \n" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "No se pudo iniciar base de datos de Bareos\n" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "Usando Base de Datos: %s, Usuario: %s\n" #: src/tests/bbatch.c:329 #, c-format msgid "Error opening datafile %s\n" msgstr "Error abriendo archivo de datos %s\n" #: src/tests/bbatch.c:339 msgid "Error while inserting file\n" msgstr "Error insertando el archivo\n" #: src/tests/bvfs_test.c:51 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -n especifica el nombre de la base de datos (por defecto bareos)\n" " -u especifica el nombre de usuario de la base de datos (por " "defecto bareos)\n" " -P especifica la contraseña de la base de datos (por defecto " "none)\n" " -h especifica servidor de la base de datos (por defecto NULL)\n" " -w especifica el directorio de trabajo\n" " -j especifica jobids\n" " -p especifica la ruta\n" " -f especifica el archivo\n" " -l tupla máxima a buscar\n" " -T Truncar tabla de caché antes de empezar\n" " -v detallado\n" " -? imprime esta mensaje\n" "\n" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -n especifica el nombre de la base de datos (por defecto bareos)\n" " -u especifica el nombre de usuario de la base de datos (por " "defecto bareos)\n" " -P especifica la contraseña de la base de datos (por defecto " "none)\n" " -h especifica servidor de la base de datos (por defecto NULL)\n" " -w especifica el directorio de trabajo\n" " -j especifica jobids\n" " -p especifica la ruta\n" " -f especifica el archivo\n" " -l tupla máxima a buscar\n" " -T Truncar tabla de caché antes de empezar\n" " -v detallado\n" " -? imprime esta mensaje\n" "\n" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -n especifica el nombre de la base de datos (por defecto bareos)\n" " -u especifica el nombre de usuario de la base de datos (por " "defecto bareos)\n" " -P especifica la contraseña de la base de datos (por defecto " "none)\n" " -h especifica servidor de la base de datos (por defecto NULL)\n" " -w especifica el directorio de trabajo\n" " -j especifica jobids\n" " -p especifica la ruta\n" " -f especifica el archivo\n" " -l tupla máxima a buscar\n" " -T Truncar tabla de caché antes de empezar\n" " -v detallado\n" " -? imprime esta mensaje\n" "\n" #: src/tests/cats_test.c:375 #, fuzzy, c-format msgid "Could not open, database \"%s\".\n" msgstr "No se puede abrir la base de datos \"%s\".\n" #: src/tests/testls.c:50 #, fuzzy, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" "\n" "Utilice: testls [-d nivel_ depuración] [-] [patrón1 ...]\n" " -a imprime atributos extendidos (depuración de Win32)\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -e especifica archivo de exclusión de patrones\n" " -i especifica archivo de inclusión de patrones\n" " - leer patrón(es) desde stdin\n" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "No se pudo abrir el archivo incluir: %s\n" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "No se pudo abrir el archivo excluir: %s\n" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "Recursión deshabilitada. No entró al directorio. %s\n" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" "Saltar: Cambio de sistema de archivos prohibido. No entró al directorio. %s\n" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "No se pudo abrir el archivo de datos: %s\n" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, fuzzy, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "No se puede iniciar job cond varibale: ERR=%s\n" #: src/stored/dir_cmd.c:241 #, fuzzy, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "No se puede iniciar job cond varibale: ERR=%s\n" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "No se puede autentificar el Director\n" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "Fallo solicitud de conexión desde %s.\n" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "Inválida conexión desde %s. Len=%d\n" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, fuzzy, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "2991 Comando setdebug malo: %s\n" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "2901 Job %s no encontrado.\n" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "3903 Error escaneando comando cancel.\n" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "3904 Job %s no encontrado.\n" #: src/stored/dir_cmd.c:562 #, fuzzy, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "JobId %s, Job %s marcado para ser cancelado.\n" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, fuzzy, c-format msgid "%s: Failed to resolve %s\n" msgstr "3914 No se ha podido etiquetar el volumen (no hay medios): ERR=%s\n" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "3999 Dispositivo \"%s\" no encontrado o no pudo ser abierto.\n" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "3903 Error escaneando comando cancel: %s\n" #: src/stored/dir_cmd.c:743 #, fuzzy, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "3910 No se puede abrir el dispositivo %s: ERR=%s\n" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" "3920 No se puede etiquetar el volumen porque ya está etiquetado: \"%s\"\n" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "3921 Volumen incorrecto montado.\n" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "3922 No se puede renombrar un volumen ANSI/IBM etiquetado.\n" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "3912 Fallo al etiquetar el Volumen: ERR=%s\n" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "3914 No se ha podido etiquetar el volumen (no hay medios): ERR=%s\n" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" "3913 No se puede etiquetar el volumen. Estado desconocido %d de " "read_volume_label()\n" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "3001 Volumen Montado: %s\n" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, fuzzy, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" "3902 No se puede montar el volumen en Storage Device %s debido a que:\n" "%s" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" "\n" "Dispositivo \"%s\" solicitado por el DIR no se pudo abrir o no existe.\n" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" "\n" "Dispositivo \"%s\" en el cambiador \"%s\" solicitado por el DIR no se pudo " "abrir o no existe.\n" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "Ranura especificado ignorado." #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, fuzzy, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "3901 No se puede abrir el dispositivo %s: ERR=%s\n" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, fuzzy, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "3001 Dispositivo %s esta montado con volumen \"%s\"\n" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, fuzzy, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" "3905 Dispositivo %s abierto, pero ninguno volumen Bareos está montado.\n" "Si esto no es una cinta en blanco, trate de desmontar y volver a montar el " "volumen.\n" #: src/stored/dir_cmd.c:989 #, fuzzy, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "3001% s dispositivo está haciendo adquirir.\n" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, fuzzy, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "3903 Dispositivo %s ha sido etiquetada.\n" #: src/stored/dir_cmd.c:1015 #, fuzzy, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "3001 Dispositivo %s ya está montado con el volumen \"%s\"\n" #: src/stored/dir_cmd.c:1025 #, fuzzy, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "3002 Dispositivo %s está montado.\n" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "3907 %s" #: src/stored/dir_cmd.c:1030 #, fuzzy, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "3906 Dispositivo de Archivo %s está siempre montado.\n" #: src/stored/dir_cmd.c:1038 #, fuzzy, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "3903 Dispositivo %s ha sido etiquetada.\n" #: src/stored/dir_cmd.c:1042 #, fuzzy, c-format msgid "3905 Unknown wait state %d\n" msgstr "Estado del Analizador %d desconocido\n" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "3909 Error escaneando comando mount: %s\n" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, fuzzy, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "3002 Dispositivo %s desmontado.\n" #: src/stored/dir_cmd.c:1086 #, fuzzy, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "3901 Dispositivos %s ya está desmontado.\n" #: src/stored/dir_cmd.c:1101 #, fuzzy, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "3001 Dispositivo %s desmontado.\n" #: src/stored/dir_cmd.c:1105 #, fuzzy, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "3902 Dispositivo %s está ocupado en adquirir.\n" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "3907 Error escaneando comando unmount: %s\n" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "3916 Error de escaneando comando action_on_purge\n" #: src/stored/dir_cmd.c:1209 #, fuzzy, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "3921 Dispositivo %s ya liberado.\n" #: src/stored/dir_cmd.c:1216 #, fuzzy, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "3922 Dispositivo %s aguardando por sysop.\n" #: src/stored/dir_cmd.c:1222 #, fuzzy, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "3922 Dispositivo %s aguardando por montar.\n" #: src/stored/dir_cmd.c:1226 #, fuzzy, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "3923 Dispositivo %s está ocupado en adquirir.\n" #: src/stored/dir_cmd.c:1230 #, fuzzy, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "3914 Dispositivo %s ha sido etiquetada.\n" #: src/stored/dir_cmd.c:1238 #, fuzzy, c-format msgid "3022 Device \"%s\" released.\n" msgstr "3022 Dispositivo %s liberado.\n" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "3927 Error escaneando comando de liberación: %s\n" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "No se pudo crear el archivo de arranque %s: ERR=%s\n" #: src/stored/dir_cmd.c:1360 #, fuzzy, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "3995 Dispositivo %s no es un auto-cargador.\n" #: src/stored/dir_cmd.c:1384 #, fuzzy, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "3908 Error comando scanning auto-cambiador drives/list/ranuras: %s\n" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "3909 Error comando scanning readlabel: %s\n" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "3001 Volumen=%s Ranura=%d\n" #: src/stored/dir_cmd.c:1483 #, fuzzy, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "3931 Dispositivo %s está BLOQUEADO. Usuario sin montar.\n" #: src/stored/dir_cmd.c:1486 #, fuzzy, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" "3932 Dispositivo %s está BLOQUEADO. Usuario sin montar en espera por medios/" "montar.\n" #: src/stored/dir_cmd.c:1489 #, fuzzy, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "3933 Dispositivo %s está BLOQUEADO esperando por media.\n" #: src/stored/dir_cmd.c:1492 #, fuzzy, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "3934 Dispositivo %s se está inicializado.\n" #: src/stored/dir_cmd.c:1496 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "3935 Dispositivo %s está BLOQUEADO etiquetando un Volumen.\n" #: src/stored/dir_cmd.c:1500 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "3935 Dispositivo %s está BLOQUEADO por razón desconocida.\n" #: src/stored/dir_cmd.c:1505 #, fuzzy, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "3936 Dispositivo %s está ocupado leyendo.\n" #: src/stored/dir_cmd.c:1507 #, fuzzy, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "3937 Dispositivo %s está ocupado con %d escritura(s).\n" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "Error al conectar con el demonio de Storage: %s:%d\n" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "Fallo al autenticar demonio Storage.\n" #: src/stored/dir_cmd.c:1655 #, fuzzy, c-format msgid "Bad passiveclientcmd command: %s" msgstr "Malo comando sesión: %s" #: src/stored/dir_cmd.c:1673 #, fuzzy msgid "File Daemon" msgstr "demonio File" #: src/stored/dir_cmd.c:1679 #, fuzzy, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "Error al conectar con demonio File.\n" #: src/stored/dir_cmd.c:1690 #, fuzzy msgid "Failed to authenticate File daemon.\n" msgstr "No se puede autenticar demonio File\n" #: src/stored/dir_cmd.c:1724 #, fuzzy, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "Malo comando RunScript: %s\n" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, fuzzy, c-format msgid "Encountered an unknown stream type %d\n" msgstr "Advertencia: Tipo de recurso %d desconocido\n" #: src/stored/ndmp_tape.c:590 #, fuzzy, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "Fallo al conectar a FD: Nombre del Job no encontrado: %s\n" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "DCR es NULL!!!\n" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "DEVICE es NULL!!!\n" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "Fallo al escribir la etiqueta de sesión. ERR=%s\n" #: src/stored/ndmp_tape.c:749 #, fuzzy msgid "Creating virtual file attributes failed.\n" msgstr "Fallo crear archivo bootstrap.\n" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "Nombres de Volumen no encontrados para restaurar.\n" #: src/stored/ndmp_tape.c:811 #, fuzzy, c-format msgid "Read session label failed. ERR=%s\n" msgstr "Fallo al escribir la etiqueta de sesión. ERR=%s\n" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 #, fuzzy msgid "JCR is NULL!!!\n" msgstr "DCR es NULL!!!\n" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, fuzzy, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" "Tiempo transcurrido de escritura del Job = %02d:%02d:%02d, Tasa de " "transferencia = %s Bytes/segundo\n" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "Error escribiendo etiqueta de fin de sesión. ERR=%s\n" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "Error Fatal añadiendo en el dispositivo %s: ERR=%s\n" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 #, fuzzy msgid "Cannot initialize new NDMA session\n" msgstr "No se puede iniciar %s\n" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 #, fuzzy msgid "Cannot initialize new NDMA connection\n" msgstr "No se pudo iniciar base de datos de Bareos\n" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "No se puede abrir el socket de flujo. ERR=%s. Actual %s Todos %s\n" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "No se puede establecer SO_REUSEADDR en el socket: %s\n" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "No se puede enlazar a puerto %d: ERR=%s: Reintentando ...\n" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "No se puede enlazar a puerto %d: ERR=%s.\n" #: src/stored/ndmp_tape.c:1414 #, fuzzy, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "No se pudo iniciar cola cliente: ERR=%s\n" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "Error al seleccionar: %s\n" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, fuzzy, c-format msgid "Error in poll: %s\n" msgstr "Error al seleccionar: %s\n" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "Conexión desde %s:%d rechazada por hosts.access\n" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "No se puede establecer SO_KEEPALIVE en el socket: %s\n" #: src/stored/ndmp_tape.c:1534 #, fuzzy, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "No se pudo agregar job a la cola de cliente: ERR=%s\n" #: src/stored/ndmp_tape.c:1557 #, fuzzy, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "No es posible destruir la cola de cliente: ERR=%s\n" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "Fallo al conectar a FD: Nombre del Job no encontrado: %s\n" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "Hey!!!! JobId %u Job %s ya autenticada.\n" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "No se puede autenticar demonio File\n" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "Error de comando con FD, colgando. %s\n" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "Error de comando con FD, colgando.\n" #: src/stored/fd_cmds.c:246 #, c-format msgid "FD command not found: %s\n" msgstr "Comando FD no encontrado:% s \n" #: src/stored/fd_cmds.c:272 msgid "Append data error.\n" msgstr "Error al añadir datos.\n" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "Intento de anexar en sesión no abierta.\n" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "Intento de cerrar sesión no abierta.\n" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "Intento de abrir sesión ya abierta.\n" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "Intento de leer sesión no abierta.\n" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "Intento de abrir leer sesión no abierta.\n" #: src/stored/read.c:135 #, fuzzy, c-format msgid ">filed: Error Hdr=%s" msgstr ">filed: Error Hdr=%s\n" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "Error enviando para demonio File. ERR=%s\n" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "Error enviando para FD. ERR=%s\n" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "Esperaba una palabra clave Tipo Device, obtuvo: %s" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" "Valor máximo de tamaño bloque configurado %u es mayor de lo máximo " "permitido: %u" #: src/stored/stored_conf.c:409 #, fuzzy, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "Esperaba una palabra clave FileSet, obtuvo: %s" #: src/stored/stored_conf.c:432 #, fuzzy, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "esperaba una etiqueta Tape Label , obtuvo: %s" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "Advertencia: Recurso \"%s\" (%d) no definido.\n" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "dump_resource tipo=%d\n" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "Advertencia: Tipo de recurso %d desconocido\n" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "ítem \"%s\" es necesario en recurso \"%s\", pero no se encuentra.\n" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "Demasiados elementos en recursos \"%s\"\n" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "No puede encontrar recurso Auto-cambiador %s\n" #: src/stored/stored_conf.c:874 #, fuzzy, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" "Intento para definir secundo recurso \"%s\" denominado \"%s\" no está " "permitido.\n" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "Recurso Storage no definido en %s. No se puede continuar.\n" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "No se puede stat dispositivo %s: ERR=%s\n" #: src/stored/dev.c:160 #, fuzzy, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" "%s es un tipo de dispositivo desconocido. Debe ser cinta o directorio\n" " o tener RequiresMount=yes para DVD. st_mode=%x\n" #: src/stored/dev.c:225 #, fuzzy, c-format msgid "%s has an unknown device type %d\n" msgstr "Advertencia: Tipo de recurso %d desconocido\n" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "No se puede stat punto de montaje %s: ERR=%s\n" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" "Comandos mount y unmount deben ser definidos para un dispositivo que " "requiere montaje.\n" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "Mínimo tamaño de bloque > máximo en el dispositivo %s\n" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" "Tamaño de bloque %u en el dispositivo %s es demasiado grande, usando %u " "omisión\n" #: src/stored/dev.c:312 src/stored/dev.c:449 #, fuzzy, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" "Tamaño máximo de bloque %u no es múltiplo de tamaño de bloque en dispositivo " "%s.\n" #: src/stored/dev.c:316 src/stored/dev.c:454 #, fuzzy, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" "Máximo Tamaño de Volumen < 8 * Máximo Tamaño de Bloque en dispositivo %s\n" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "No se puede iniciar variable cond: ERR=%s\n" #: src/stored/dev.c:346 #, fuzzy, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/dev.c:353 #, fuzzy, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/dev.c:360 #, fuzzy, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "Modo ilegal dado para abrir dev.\n" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" "No se pudo abrir dispositivo de archivo %s. No hay nombre volumen " "determinado.\n" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "No se pudo abrir: %s, ERR=%s\n" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "Iseek error en %s. ERR=%s.\n" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "Mala llamada para eod. Dispositivo %s no abierto\n" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "Mala llamada de dispositivo. Dispositivo no abierto\n" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "Seek error: ERR=%s\n" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "Mala llamada a reposición. El dispositivo no abre\n" #: src/stored/dev.c:904 #, fuzzy, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "Fin de medio en Volumen \"%s\" Bytes=%s Bloques=%s en %s.\n" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "Nuevo volumen \"%s\" montado en el dispositivo %s en %s.\n" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "Fallo de etiqueta de volumen write_block_to_device. ERR=%s" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "Fallo de desbordamiento de bloque write_block_to_device. ERR=%s" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" "Error catastrófico. No se puede escribir bloque de desbordamiento al " "dispositivo %s. ERR=%s" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "Fallo al abrir dev: %s\n" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "No se puede abrir archivo %s: ERR=%s\n" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "Espaciando hacia adelante Volumen \"%s\" para archivo:bloque %u:%u.\n" #: src/stored/bscan.c:104 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: bscan [opciones] \n" " -b especifica un archivo bootstrap\n" " -c especifica un archivo de configuración\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -m Actualiza información de los medios en la base de datos\n" " -D especifica el nombre del driver de base de datos " "(por defecto NULL)\n" " -n especifica el nombre de la base de datos (por defecto bareos)\n" " -u especifica el nombre de usuario de la base de datos (por " "defecto bareos)\n" " -P especifica la contraseña de la base de datos (por defecto " "none)\n" " -h especifica servidor de la base de datos (por defecto NULL)\n" " -t especifica el puerto de la base de datos (por defecto 0)\n" " -p proceder a pesar de los errores\n" " -r lista de registros\n" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, fuzzy, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "Recurso Director no definido en %s. No se puede continuar.\n" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "Directorio de Trabajo no definido en %s. No se puede continuar.\n" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "Directorio de Trabajo: %s no encontrado. No se puede continuar.\n" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" "Directorio de Trabajo: %s no es un directorio. No se puede continuar.\n" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "Tamaño Primero Volumen = %s\n" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "Crear JobMedia para Job %s\n" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "No es posible crear registro JobMedia para Volumen=%s Job=%s\n" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "Hecho: %d%%\n" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "Registro: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "El volumen esta prelabeled. Esta cinta no puede ser escaneada. \n" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "Registro Pool para %s encontrado en BD.\n" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "VOL_LABEL: Registro Pool no encontrado para Pool: %s\n" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "VOL_LABEL: PoolType desajustado. BD=%s Vol=%s\n" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "Tipo de Pool \"%s\" esta OK.\n" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "Registro Media para %s encontrado en BD.\n" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "VOL_LABEL: Registro Media no encontrado para Volumen: %s\n" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "VOL_LABEL: MediaType desajustada. BD=%s Vol=%s\n" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "Tipo de Media \"%s\" esta OK.\n" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "VOL_LABEL: OK para Volumen: %s\n" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" "%d \"errores\" ignorados antes del primero registro de Inicio de Sesión.\n" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "SOS_LABEL: Encontrado registro Job para JobId: %d\n" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "SOS_LABEL: Registro Job no encontrado para JobId: %d\n" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "SOS_LABEL: VolSessId desajustado para JobId=%u. BD=%d Vol=%d\n" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "SOS_LABEL: VolSessTime desajustado para JobId=%u. BD=%d Vol=%d\n" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "SOS_LABEL: PoolId diferente para JobId=%u. BD=%d Vol=%d\n" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "No se pudo encontrar SessId=%d SessTime=%d para registro EOS.\n" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "No se pudo actualizar el registro de trabajo. ERR=%s\n" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "Final de todos los volúmenes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "No se pudo encontrar registro trabajo para SessId=%d SessTime=%d.\n" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "No se puede continuar.\n" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "%s registros de archivo. En el archivo:blk=%s:%s bytes=%s\n" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "Obtuvo registro MD5: %s\n" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "Obtuvo registro SHA1: %s\n" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "Obtuvo registro SHA256: %s\n" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "Obtuvo registro SHA512: %s\n" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "Obtuvo registro resume firmado: %s\n" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "Obtuvo Stream Nombres de Programas: %s\n" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "Obtuvo Registro Stream Datos de Programas: %s\n" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "Tipo de flujo desconocido!!! stream=%d len=%i\n" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "No se pudo crear el registro de Archivos de Atributos. ERR=%s\n" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "Registro Archivo creado: %s\n" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "No es posible crear registro media. ERR=%s\n" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "No es posible actualizar registro media. ERR=%s\n" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "Creado Registro Media para Volumen: %s\n" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "Actualizado el registro Media al final del Volumen: %s\n" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "No es posible crear el registro Pool. ERR=%s\n" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "Creado el registro Pool para Pool: %s\n" #: src/stored/bscan.c:1101 #, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "No se ha podido obtener el registro del cliente. ERR=%s\n" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "Creado registro Cliente para Cliente: %s\n" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "Fileset \"%s\" ya existe.\n" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "No es posible crear registro FileSet \"%s\". ERR=%s\n" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "Creado registro FileSet \"%s\"\n" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "No es posible crear registro JobId. ERR=%s\n" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "No se pudo actualizar el registro job de inicio. ERR=%s\n" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "Creado nuevo registro JobId=%u para JobId=%u original\n" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "No se puede actualizar registro JobId=%u. ERR=%s\n" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" "Actualizado el registro de terminación de Job para JobId=%u Nivel=%s " "TermStat=%c\n" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "Código de Terminación del Job: %d" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Nivel de Respaldo: %s\n" "Cliente: %s\n" "Hora de Inicio: %s\n" "Hora de Finalización: %s\n" "Archivos Escritos: %s\n" "Bytes Escritos: %s\n" "Id Volumen Sesión: %d\n" "Tiempo de la Sesión del Volumen: %d\n" "Últimos Bytes del Volumen: %s\n" "Terminación: %s\n" "\n" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "No es posible crear registro JobMedia. ERR=%s\n" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "Creado registro JobMedia JobID %d, MediaID %d\n" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "No se pudo encontrar SessId=%d SessTime=%d para registro MD5/SHA1.\n" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "No se pudo agregar MD5/SHA1 al registro File. ERR=%s\n" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "Actualizado registro MD5/SHA1\n" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "No se puede establecer el tamaño del búfer de red.\n" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "Nombre de volumen VACÍO. Esto no debería suceder!\n" #: src/stored/append.c:123 #, fuzzy, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "Error de red al enviar para SD. ERR=%s\n" #: src/stored/append.c:161 #, fuzzy, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "Error al leer datos de cabecera de FD. ERR=%s\n" #: src/stored/append.c:169 #, fuzzy, c-format msgid "Malformed data header from %s: %s\n" msgstr "Datos de cabecera mal formados desde FD: %s\n" #: src/stored/append.c:190 #, fuzzy, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "Archivo de índice de FD no es positivo o secuencial\n" #: src/stored/append.c:243 #, fuzzy, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "Error al leer la red desde FD. ERR=%s\n" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "Set ok=FALSE después de write_block_to_device.\n" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "Error al actualizar los atributos de archivo. ERR=%s\n" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" "Tamaño de bloque de cinta (%d) no es múltiplo del tamaño de sistema (% d)\n" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "Tamaño de bloque de cinta (%d) no es una potencia de 2\n" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" "\n" "\n" "!!!! Advertencia, deshabilitado direccionamiento de discos largos. boffset_t=" "%d debe ser de 8 o más !!!!!\n" "\n" "\n" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "32 bit printf/scanf problema. i=%d x32=%u y32=%u\n" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "64 bit printf/scanf problema. i=%d x64=%" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "Granularidad del bloque de cinta es %d bytes.\n" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "Nombre de archivo no especificado.\n" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "Número incorrecto de argumentos especificados.\n" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "btape sólo funciona con almacenamiento en cinta.\n" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "Volumen total bytes=%sB. Tasa total de Escritura = %sB/s\n" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "Volumen bytes=%sB. Tasa de Escritura = %sB/s\n" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "abrir dispositivo %s: OK\n" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "Ingrese nombre de Volumen:" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "Fallo al abrir dispositivo. ERR=%s\n" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "Escribe la etiqueta de Volumen para el volumen \"%s\".\n" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "Volumen no tiene etiqueta.\n" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "Etiqueta de volumen leída correctamente.\n" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "error de E/S en el dispositivo: ERR=%s" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "Nombre de Volumen error\n" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "Error creando etiqueta. ERR=%s" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "Volumen versión error.\n" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "Malo tipo de etiqueta de volumen.\n" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "Error desconocido.\n" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "Malo estado de carga. ERR=%s\n" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "Cargado %s\n" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "Malo estado de rebobinado. ERR=%s\n" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "Rebobinado %s\n" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "Malo estado de weof. ERR=%s\n" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "Escribir 1 EOF para %s\n" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "Escribir %d EOFs para %s\n" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "Movido para el final de la media.\n" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "Mal estado desde BSF. ERR=%s\n" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "Backspaced %d archivo%s.\n" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "Malo estado de BSR. ERR=%s\n" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "Backspaced %d registro%s.\n" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "Capacidades del dispositivo configuradas:\n" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "Estado del Dispositivo:\n" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "Parámetros del Dispositivo:\n" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "Estados:\n" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" "Prueba de escritura de registros cada vez mayores.\n" "Esta es una prueba de tortura para los registros.\n" "Voy a escribir\n" "registros cada vez mayores. Se detendrá cuando el tamaño de registro además " "de la cabecera excede el tamaño de bloque (por defecto sobre 64K)\n" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "Desea continuar? (y/n)" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "Comando Abortado.\n" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "Bloque %d i=%d\n" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "Saltar prueba de lectura hacia atrás, porque BSR esta desactivado.\n" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" "\n" "=== Prueba de escritura, copia de seguridad y re-lectura ===\n" "\n" "Yo voy a escribir 3 registros y un EOF\n" "a continuación respaldar sobre el EOF y re-leer el ultimo registro.\n" " Bareos hace esto después de escribir el último bloque en la\n" "cinta para comprobar que el bloque ha sido escrito correctamente.\n" "\n" "Esta es una característica *esencial* ...\n" "\n" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "Error al escribir registro al bloque.\n" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "Error al escribir bloque al dispositivo.\n" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "Escribió primer registro de %d bytes.\n" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "Escribió segundo registro de %d bytes.\n" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "Escribió tercer registro de %d bytes.\n" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "Fallo en retroceso de archivo! ERR=%s\n" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "Retroceso sobre EOF OK.\n" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "Fallo en retroceso de registro! ERR=%s\n" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "Retroceso de registro OK.\n" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "Lectura de bloque fallida! ERR=%s\n" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "Datos erróneos en el registro. Prueba fallida!\n" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" "\n" "Re-lectura de bloque correcta. Prueba Satisfactoria!\n" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" "=== Fin prueba de escritura, copia de seguridad, y re-lectura ===\n" "\n" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" "Esto no es terriblemente grave, desde que sólo utilices Bareos\n" "esta función para verificar el último bloque por escrito en la\n" "cinta. Bareos saltará la verificación del último bloque\n" "si usted agrega:\n" "\n" "Backward Space Record = NO\n" "\n" " en la definición de los recursos de Dispositivos de su demonio Storage.\n" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "Inicia escribiendo %i archivos de %sB con raw bloques de %u bytes.\n" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, fuzzy, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "Error al escritura en el bloque %u. stat=%d ERR=%s\n" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "Inicia escribiendo %i archivos de %sB con bloques de %u bytes.\n" #: src/stored/btape.c:981 msgid "" "\n" "Error writing record to block.\n" msgstr "" "\n" "Error escribiendo registro al bloque.\n" #: src/stored/btape.c:985 msgid "" "\n" "Error writing block to device.\n" msgstr "" "\n" "Error escribiendo bloque al dispositivo.\n" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" "El tamaño_archivo es demasiado grande, detenga esta prueba con Ctrl-c.\n" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "Prueba con cero de datos, debe dar el máximo rendimiento.\n" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "Prueba con datos aleatorios, deben dar el rendimiento mínimo.\n" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "Prueba con cero de datos y estructura del bloque de Bareos.\n" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" "\n" "=== Probar Escritura, Rebobinado y Re-lectura === \n" "\n" "Voy a escribir %d registros y un EOF\n" "a continuación escribiré %d registros y un EOF, a continuación, rebobinar,\n" "y re-leer los datos para verificar que son correctos.\n" "\n" "Este es una característica *esencial*...\n" "\n" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "Escribió %d bloques de %d bytes.\n" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "Rebobinar OK.\n" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "Obtuvo EOF en la cinta.\n" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "Fallo al leer bloque %d! ERR=%s\n" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "Fallo al leer registro. Bloque %d! ERR =%s\n" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" "Datos incorrectos en el registro. Esperaba %d, obtuvo %d en byte %d. Prueba " "Fallida!\n" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "%d bloques releídos correctamente.\n" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" "=== Prueba Satisfactoria. Fin prueba de Escritura, Rebobinado y Re-lectura " "===\n" "\n" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "Prueba de posición del bloque\n" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "Reposición para archivo:bloque %d:%d\n" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "Error de reposición.\n" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" "Fallo al leer bloque %d! archivo=%d blk=%d. ERR=%s\n" "\n" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" "Esto puede ser porque el tamaño del bloque de la\n" "unidad de cinta no está establecido en la variable\n" "de bloqueo como utilizado normalmente por Bareos.\n" "Consulte el capítulo Probando Cintas en el manual y\n" "busque por usando mt con defblksize y setoptions.\n" "Si el tamaño del bloque de la unidad de cinta es correcto,\n" "entonces quizá el controlador SCSI es *realmente* estúpido\n" "y no informa correctamente el archivo:bloque después de un FSF.\n" "En este caso, intente configurar:\n" " Fast Forward Space File = no\n" "en su recurso de Dispositivos.\n" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "Fallo al leer registro! ERR=%s\n" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "Bloque %d re-leído correctamente.\n" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" "\n" "\n" "=== Prueba de Añadir Archivos===\n" "\n" "Esta prueba es esencial para Bareos.\n" "\n" "Voy a escribir un registro en el archivo 0,\n" " dos registros en el archivo 1,\n" " y tres registros en el archivo de 2\n" "\n" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "Moviendo ahora a final de medio.\n" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "Deberíamos estar en el archivo 3. Estoy en el archivo %d. %s\n" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "Esto es correcto!" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "Esto NO es correcto!" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" "\n" "Ahora la parte importante, voy a tratar de anexar a la cinta.\n" "\n" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" "Añadiendo hecho, no debería haber ningún error de E/S\n" "\n" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "Hacer Bareos exploración de los bloques:\n" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "Fin del escaneo de la cinta.\n" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "Deberíamos estar en el archivo 4. Estoy en el archivo %d. %s\n" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" "\n" "Auto-cambiador habilitado, pero ningún nombre o comando de dispositivo " "especificado.\n" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" "\n" "Ah, veo que tienen un auto-cargador configurado.\n" "Para probar el auto-cargador debe tener una cinta en blanco\n" " que yo pueda escribir en la Ranura 1.\n" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" "\n" "¿Desea continuar con la prueba del auto-cambiador? (y/n):" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" "\n" "\n" "=== Prueba Auto-cambiador ===\n" "\n" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "3301 Emitiendo comando auto-cambiador \"cargado\".\n" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "3991 Malo comando cargador: %s\n" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "3991 resultado=\"%s\": ERR=%s\n" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "Ranura %d cargada. Voy a descargarla.\n" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "Nada cargado en la unidad. OK.\n" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "3302 Emitiendo comando auto-cambiador \"descargar %d %d\".\n" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "estado descargar=%s %d\n" #: src/stored/btape.c:1540 msgid "Bad" msgstr "Malo" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "3992 Malo comando cargador: %s\n" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "3992 resultado=\"%s\": ERR=%s\n" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "3303 Emitiendo comando auto-cambiador \"cargar %d %d\".\n" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "3303 Estado auto-cambiador \"carga %d %d\" está OK.\n" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "3993 Malo comando cargador: %s\n" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "3993 resultado=\"%s\": ERR=%s\n" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" "\n" "Fallo la prueba, probablemente porque es necesario poner\n" "un mayor tiempo de espera en su mtx-script en la clausula load).\n" "Añadiendo 30 segundos de espera y volviendo a intentarlo...\n" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "Escribió EOF para %s\n" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" "\n" "La prueba funcionó esta vez. Por favor, añada:\n" "\n" " sleep %d\n" "\n" "en su script mtx-cambiador dentro de de la clausula load).\n" "\n" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" "\n" "La prueba del auto-cargador funcionó!!\n" "\n" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "Usted debe corregir este error o la Auto-cambiador no funcionará.\n" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" "\n" "\n" "=== Probar espaciar archivos hacia adelante ===\n" "\n" "Esta prueba es esencial para Bareos.\n" "\n" "Voy a escribir cinco archivo, a continuación probar espaciado hacia " "adelante\n" "\n" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "Ahora espaciando 1 archivo hacia adelante.\n" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "Malo estado desde FSR. ERR=%s\n" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "Debemos estar en el archivo 1. Estoy en el archivo %d. %s\n" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "Ahora espaciando 2 archivo hacia adelante.\n" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "Ahora espaciando 4 archivo hacia adelante.\n" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" "La prueba funcionó esta vez. Por favor, añadir:\n" "\n" " Fast Forward Space File = no\n" "\n" "a su recurso Device para esta unidad.\n" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "Ahora espaciando un archivo mas hacia adelante.\n" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "Debemos estar en el archivo 5. Estoy en el archivo %d. %s\n" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" "\n" "=== Finalizo prueba de Espaciar archivos hacia adelante ===\n" "\n" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" "\n" "Fallida la prueba de espaciar archivos hacia adelante.\n" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" "usted tiene habilitado Espaciar Archivos Hacia Adelante Rápido.\n" "Voy deshabilitarlo y luego volver a intentar la prueba.\n" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" "Usted debe corregir este error o Bareos no funcionará.\n" "Algunos Sistemas, por ejemplo OpenBSD, requiere que usted establezca\n" "Use MTIOCGET = no\n" "en su recurso de dispositivo. Utilizar con precaución.\n" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" "\n" "Prueba de Añadir fallida. Intentando de nuevo.\n" "Configurando \"Hardware End of Medium = no\n" " y \"Fast Forward Space File = no\n" "y volviendo a intentar la prueba de añadir.\n" "\n" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" "\n" "\n" "Parece que la prueba funcionó esta vez, por favor, añadir:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "a su recurso de Device en el archivo configuración del Storage.\n" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" "\n" "\n" "Parece que *NO* se ha corregido el problema.\n" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" "\n" "\n" "Parece que ha fallado el añadir.Intentando de nuevo.\n" "Configurando \"BSF en EOM = yes\" y reintentando probar añadir.\n" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" "\n" "\n" "Parece que la prueba funcionó esta vez, por favor agregue:\n" "\n" "Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "en su recurso Device en el archivo de configuración del Storage.\n" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" "\n" "Fallo prueba Anexar.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "No se puede corregir el problema. Usted DEBE corregir este\n" "problema antes de que Bareos pueda utilizar su unidad de cinta " "correctamente \n" "\n" "Tal vez ejecutando Bareos en modo de bloque fijo va a funcionar.\n" "Hacerlo estableciendo:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "en la definición de dispositivo del demonio Storage.\n" "nnn debe coincidir con el tamaño de bloque controlador de su cinta, que\n" "puede determinarse mediante lectura de información del fabricante de la " "cinta, y la información en su driver del núcleo.\n" "Tamaños de bloque fijo, sin embargo, normalmente no son una solución ideal.\n" "\n" "Algunos sistemas, por ejemplo OpenBSD, exigen que se establezcan\n" "Use MTIOCGET= no\n" "en su recurso de dispositivo. Utilice con precaución.\n" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" "\n" "La anterior Bareos análisis debe tener una salida idéntica a lo que sigue.\n" "Por favor, verifique bien ...\n" "Ejemplo de la salida correcta === n1 bloque de 64448 bytes en el archivo " "1\n" "Fin de la marca de archivo.\n" "2 bloques de 64.448 bytes en el archivo 2\n" "Fin de la marca de archivo.\n" "3 bloques de 64448 bytes en el archivo 3\n" "Fin de la marca de archivo.\n" "1 bloque de 64448 bytes en el archivo 4\n" "Fin de la marca de archivo.\n" "Total de archivos = 4, bloques = 7, bytes = 451.136\n" "===Fin ejemplo de la salida correcta===\n" "\n" "Si la anterior salida de escaneo no es idéntica a la \n" "salida de ejemplo, usted DEBE corregir el problema\n" "o Bareos no será capaz de escribir varios Jobs en\n" "la cinta.\n" "\n" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "Malo estado desde FSF. ERR=%s\n" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "Espaciado 1 archivo hacia adelante.\n" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "Espaciados %d archivos hacia adelante.\n" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "Espaciado 1 registro hacia adelante.\n" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "Espaciados %d registros hacia adelante.\n" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "Escribió un registro de %d bytes.\n" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "Escribió bloques al dispositivo.\n" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "Introduzca la longitud para leer:" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "Mala longitud introducida, utilizando 1024 bytes por defecto.\n" #: src/stored/btape.c:1961 #, fuzzy, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "Lectura de %d bytes obtuvo stat=%d. ERR=%s\n" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "Fin de la cinta\n" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "Iniciando escaneo en el archivo %u\n" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "error de lectura en %s. ERR=%s.\n" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "Malo estado desde lectura %d. ERR=%s\n" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "1 bloque de %d bytes en el archivo %d\n" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "%d bloques de %d bytes en archivo %d\n" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "Fin de la marca de archivo.\n" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "Total de archivos=%d, bloques=%d, bytes = %s\n" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "Leer bloque corto.\n" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "Error leyendo el bloque. ERR=%s\n" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" "Bloque=%u archivo,blk=%u,%u blen=%u Primero rec FI=%s SessId=%u SessTim=%u " "Strm=%s rlen=%d\n" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "Estado del dispositivo: %u. ERR=%s\n" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" "\n" "Este comando simula Bareos escrito en una cinta.\n" "Se requiere de una o dos cintas en blanco, que se pueda etiquetar y " "escribir.\n" "\n" "Si usted tiene un auto-cargador configurado, se usará\n" "las cintas que se encuentran en las ranuras 1 y 2, de lo contrario,\n" "se le pedirá que inserte las cintas cuando sea necesario.\n" "\n" "Se imprimirá un estado a aproximadamente cada 322 MB, y escribirá un EOF " "cada %s.Si ha seleccionado\n" "la opción de prueba simple, después de escribir la primera cinta\n" "se rebobinará y volverá a leer el último bloque escrito.\n" "\n" "Si ha seleccionado\n" "la prueba de la cinta múltiple, cuando la primera cinta se llena, se le " "preguntará por la segunda, y después de escribir unos pocos\n" "bloques más, se detendrá. Entonces comenzará a releer las\n" "dos cintas.\n" "\n" "Esto puede tomar mucho tiempo - horas! ...\n" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" "¿Desea ejecutar la prueba simplificada (s) con una cinta\n" "o la prueba completa con múltiples (m) cintas?: (s/m)" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "Prueba simple (una sola cinta) seleccionada.\n" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "Múltiples cintas de prueba seleccionados.\n" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "Escribe la etiqueta de Inicio de Sesión.\n" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "%s Empezar a escribir registros Bareos en cinta ...\n" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "%s Empezar a escribir registros Bareos en la primera cinta ...\n" #: src/stored/btape.c:2305 msgid "Flush block failed.\n" msgstr "Fallo Flush bloque.\n" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "Escribió bloque=%u, archivo,blk=%u,%u VolBytes=%s tasa=%sB/s\n" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "%s Flush bloque, escribir EOF\n" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "Escribió 1000 bloques en segunda cinta. Hecho.\n" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "No OK\n" #: src/stored/btape.c:2367 msgid "Job canceled.\n" msgstr "Job cancelado.\n" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "Establecer ok=false después de write_block_to_device.\n" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "Escribió etiqueta de Fin de Sesión.\n" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "Escribió archivo de estado last_block_num1=%d last_block_num2=%d\n" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "No se puede crear archivo de estado: %s ERR=%s\n" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" "\n" "\n" "%s Hecho llenado de cinta en %d:%d. Ahora empezando a releer la cinta ...\n" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" "\n" "\n" "%s Hecho llenado de cintas en %d:%d. Ahora empezando a releer la primera " "cinta ...\n" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "do_unfill fallido.\n" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "%s: Error durante la prueba.\n" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" "\n" "El estado del archivo de nivel de ha cambiado. Usted debe rehacer\n" "el comando llenar.\n" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" "\n" "No se pudo encontrar el archivo de estado: %s ERR=%s\n" "Usted debe rehacer el comando llenar.\n" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "Monte primera cinta. Cuando esté listo, presione ENTER:" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "Rebobinado.\n" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "Leyendo los primeros 10.000 registros desde %u:%u.\n" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "Reposición desde %u:%u para %u:%u\n" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "Error de reposición. ERR=%s\n" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "Leyendo bloque %u.\n" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "Error leyendo bloque: ERR=%s.\n" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" "\n" "El último bloque de la cinta concuerdan. Prueba Satisfactoria.\n" "\n" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" "\n" "El último bloque de la primera cinta concuerdan.\n" "\n" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "Monte la segunda cinta. Cuando esté listo, presione ENTER:" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "Reposición desde %u:%u para 0:1\n" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "Leyendo bloque %d.\n" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" "\n" "El primer bloque de la segunda cinta concuerdan.\n" "\n" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" "\n" "El último bloque de la segunda cinta concuerdan. Prueba Satisfactoria.\n" "\n" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "Leer 10000 registros ahora desde %d:%d\n" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "Ultimo bloque escrito" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "Bloque que leer" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" "\n" "\n" "Los bloques difieren en %u byte\n" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" "\n" "\n" "!!!! El último bloque escrito y el bloque\n" "que se vuelve a leer difieren. La prueba FALLO !!!!\n" "Esto debe ser corregido antes de utilizar Bareos\n" "para escribir volúmenes multi-cinta !!!!\n" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "Último bloque en: %u:%u this_dev_block_num=%d\n" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "Bloque no está escrito: FileIndex=%u blk_block=%u Tamaño=%u\n" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "Bloque no escrito" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" "Fin de la cinta %d:%d. Volumen Bytes=%s. Velocidad de Escritura = %sB/s\n" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "No se puede corregir error de dispositivo. %s\n" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "Prueba de escritura de bloques de 64512 bytes a cinta.\n" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "¿Cuántos bloques usted quiere escribir? (1000):" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "Empezando a escribir %d bloques Bareos en la cinta ...\n" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "Empezando a escribir bloques raw de %u bytes.\n" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "prueba Autochanger" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "archivo de retroceso" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "registro de retroceso" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "lista de las capacidades del dispositivo" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "Errores Cinta de Limpieza" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "ir al final de los datos de Bareos para añadir" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "ir al final del medio físico" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "llenar cinta, escribir en segundo volumen" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "leer cinta llena" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "espaciar un archivo hacia adelante" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "espaciar un registro hacia adelante" #: src/stored/btape.c:2927 msgid "print this command" msgstr "imprimir este comando" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "escribir una etiqueta Bareos en la cinta" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "cargar una cinta" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "salir btape" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "usar write() para llenar la cinta" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "leer e imprimir la etiqueta Bareos de la cinta" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "prueba de manejo de registro de funciones" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "rebobinar la cinta" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "leer() cinta bloque por bloque para EOT y reportar" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "Bareos leer bloque por bloque para EOT y reportar" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] " "informe de velocidad de la unidad" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "imprimir estado de la cinta" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "Prueba general de las funciones de cinta Bareos" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "escribir un EOF en la cinta" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "escribir un único bloque de Bareos" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "leer un solo registro" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "leer un único bloque de Bareos" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "comando de llenado rápido" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "\"%s\" es un comando inválido\n" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "Comandos interactivos:\n" #: src/stored/btape.c:2985 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: btape \n" " -b especifica un archivo bootstrap\n" " -c especifica un archivo File de configuración\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -p proceder a pesar de los errores de E/S\n" " -s desactivar señales\n" " -v detallado\n" " -? imprime esta mensaje.\n" "\n" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" "Monte el segundo volumen en el dispositivo %s y pulse ENTER cuando esté " "listo:" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" "Monte Volumen \"%s\" en el dispositivo %s y presione ENTER cuando esté " "preparado:" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" "Monte un volumen en blanco en el dispositivo %s y pulse ENTER cuando esté " "listo:" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "Fin del Volumen \"%s\" %d registros.\n" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "Leer bloque=%u, VolBytes=%s velocidad=%sB/s\n" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "No se puede abrir Dev=%s, Vol=%s\n" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "Estadísticas de cola:\n" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" "Encolando datos: %u jobs activos, %s bytes; %u total de jobs, %s máximo " "bytes/job.\n" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" "Encolando Atributos: %u jobs activos, %s bytes; %u jobs total, %s bytes " "máximos.\n" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "Datos en cola ...\n" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "Mal retorno de despool WroteVol=%d\n" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "Fallo al abrir archivo %s de datos de cola: ERR=%s\n" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "Desencolando cero bytes. El disco probablemente esta LLENO!\n" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" "Perpetrando datos encolados al volumen \"%s\". Desencolando %s bytes ...\n" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "Escribiendo datos encolados al volumen. Desencolando %s bytes ...\n" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "No es posible crear el registro JobMedia para Volumen=\"%s\" Job=%s\n" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" "Tiempo transcurrido desencolando = %02d:%02d:%02d, Tasa de transferencia = %" "s Bytes/segundo\n" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "Fallo ftruncate archivo de cola: ERR=%s\n" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "Error de lectura de la cola. ERR=%s\n" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "Error de lectura de la cola. Esperaba %u bytes, obtuvo %d\n" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" "Error de lectura de cabecera de la cola. Esperaba %u bytes, obtuvo %d\n" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "Bloque de la cola demasiado grande. Máximo %u bytes, obtuvo %u\n" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "Error de lectura de datos de la cola. Esperaba %u bytes, obtuvo %d\n" #: src/stored/spool.c:476 #, fuzzy, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "Tamaño de cola especificada por el usuario alcanzado.\n" #: src/stored/spool.c:481 #, fuzzy, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "Tamaño de cola especificada por el usuario alcanzado.\n" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "Malo retorno desde despool en write_block.\n" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "Encolando datos de nuevo ...\n" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "Error escribiendo encabezado para archivo de cola. ERR=%s\n" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" "Error al escribir encabezado al archivo de cola. Probablemente disco lleno. " "Intentando recuperación. Esperaba escribir=%d tiene=%d\n" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "Error fatal desencolando." #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "Fallido reintento después de error encolando encabezado.\n" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "Error escribiendo datos en archivo de cola. ERR=%s\n" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "Fallido reintento después de error encolando dato.\n" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "Error de red en BlastAttributes.\n" #: src/stored/spool.c:701 #, fuzzy, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "Fallo fseek en los atributos de archivo: ERR=%s\n" #: src/stored/spool.c:716 #, fuzzy, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "Fallo fseek en los atributos de archivo: ERR=%s\n" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "Fallo fseek en los atributos de archivo: ERR=%s\n" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "Enviando attrs encolados al Director. Desencolando %s bytes ...\n" #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "Fallo fopen en archivo %s de atributo de cola: ERR=%s\n" #: src/stored/reserve.c:84 #, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "No se puede inicializar bloqueo de reserva. ERR=%s\n" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "Hey! num_writers=%d!!!!\n" #: src/stored/reserve.c:258 msgid "3939 Could not get dcr\n" msgstr "3939 No se pudo obtener DCR\n" #: src/stored/reserve.c:366 #, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "Reservación del Dispositivo fallida para JobId=%d: %s\n" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "Comando fallido: %s\n" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "3926 No se pudo obtener dcr para el dispositivo: %s\n" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" "3601 JobId=%u dispositivo %s está BLOQUEADO debido al desmontar por el " "usuario.\n" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "3602 JobId=%u dispositivo %s está ocupado (ya leyendo/escribiendo).\n" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "3603 JobId=%u dispositivo %s está ocupado leyendo.\n" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" "3604 JobId=%u dispositivo %s está BLOQUEADO debido al desmonte de usuario.\n" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" "3608 JobId=%u requiere Pool=\"%s\", pero hay Pool=\"%s\" nreserve=%d en la " "unidad %s.\n" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "3609 JobId=%u Máximo trabajos simultáneos superado en la unidad %s.\n" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "3610 JobId=%u máximo volumen jobs excedido en la unidad %s.\n" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" "3605 JobId=%u requiere la unidad disponible, pero el dispositivo %s está " "ocupado.\n" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" "3606 JobId=%u prefiere unidades montadas, pero la unidad %s no tiene " "Volumen.\n" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" "3607 JobId=%u quiere Vol=\"%s\" la unidad tiene Vol=\"%s\" en la unidad %s.\n" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "Error lógico!! JobId=%u No debería llegar hasta aquí.\n" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" "3910 JobId=%u Error de lógica!!! la unidad %s no debería llegar aquí.\n" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "Error lógico!!! No debe llegar aquí.\n" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "Error de comunicación con SD. Mala respuesta a %s. ERR=%s\n" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "Mala respuesta al comando %s. Esperaba %s, obtuvo %s\n" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "Error de red al enviar para SD. ERR=%s\n" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "Nombres de Volúmenes no encontrados para %s.\n" #: src/stored/mac.c:454 #, fuzzy msgid "Read device not properly initialized.\n" msgstr "" "Dispositivos de lectura y escritura no se han iniciado correctamente.\n" #: src/stored/mac.c:479 #, fuzzy msgid "Cannot set buffer size SD->SD.\n" msgstr "No puede establecer el tamaño del búfer FD-> SD.\n" #: src/stored/mac.c:496 #, fuzzy, c-format msgid "Bad response to start replicate: %s\n" msgstr "Mala respuesta para SD leer abrir: %s\n" #: src/stored/mac.c:501 #, fuzzy msgid "Bad response from stored to start replicate command\n" msgstr "Mala respuesta desde almacén para comando abrir\n" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" "Dispositivos de lectura y escritura no se han iniciado correctamente.\n" #: src/stored/bls.c:64 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: bls [opciones] \n" " -b especifica un archivo bootstrap\n" " -c especifica un archivo Storage de configuración\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -e lista de exclusión\n" " -i lista de inclusión\n" " -j lista de trabajos\n" " -k lista de bloques\n" " (no j o k opción) lista de archivos guardados\n" " -L dump label\n" " -p proceder a pesar de los errores\n" " -v detallado\n" " -V especifica nombres de Volumen (separados por |)\n" " -? imprime esta mensaje\n" "\n" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "No se pudo abrir archivo excluir: %s, ERR=%s\n" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "No se pudo abrir archivo incluir: %s, ERR=%s\n" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "Nombre de archivo no especificado\n" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" "\n" "Advertencia, este Volumen es una continuación del Volumen %s\n" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "Obtuvo EOM en archivo %u en el dispositivo %s, Volumen \"%s\"\n" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "Volumen Montado \"%s\".\n" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "Fin de archivo %u en el dispositivo %s, Volumen \"%s\"\n" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" "Archivo:blk=%u:%u blk_num=%u blen=%u Primer registro FI=%s SessId=%u SessTim=" "%u Strm=%s rlen=%d\n" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "Bloque: %d tamaño=%d\n" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "Nueva Etiqueta de Volumen" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "Etiqueta de Volumen" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "Inicio Job Sesión" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "Fin Job Sesión" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "Fin de Medio" #: src/stored/bls.c:465 #, fuzzy msgid "End of Physical Medium" msgstr "Fin de Medio" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 #, fuzzy msgid "End of object" msgstr "Fin de la Cinta" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "Desconocido" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "%s Registro: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" #: src/stored/backends/rados_device.c:49 #, fuzzy, c-format msgid "Unable to parse device %s.\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/stored/backends/rados_device.c:62 #, fuzzy, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "No se puede crear hilo. ERR=%s\n" #: src/stored/backends/rados_device.c:69 #, fuzzy, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "No se puede leer symlin %s en \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:77 #, fuzzy, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "No se puede conectar a %s en %s:%d. ERR=%s\n" #: src/stored/backends/rados_device.c:89 #, fuzzy, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "No se puede crear el archivo bootstrap %s. ERR=%s\n" #: src/stored/backends/rados_device.c:271 #, fuzzy, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "No se pudo stat dispositivo %s. ERR=%s\n" #: src/stored/backends/rados_device.c:278 #, fuzzy, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "No se puede abrir el archivo \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, fuzzy, c-format msgid "Request for unknown devicetype: %d\n" msgstr "Advertencia: Tipo de recurso %d desconocido\n" #: src/stored/backends/gfapi_device.c:317 #, fuzzy, c-format msgid "Unable to parse device URI %s.\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/stored/backends/gfapi_device.c:329 #, fuzzy, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "No se pudo convertir %d al namespace en el archivo \"%s\"\n" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, fuzzy, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "Fallo al inicializar el contexto TLS para la consola \"%s\".\n" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, fuzzy, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "%s existe pero no es un directorio.\n" #: src/stored/backends/cephfs_device.c:58 #, fuzzy, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "No se puede crear hilo. ERR=%s\n" #: src/stored/backends/cephfs_device.c:65 #, fuzzy, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "No se puede leer symlin %s en \"%s\": ERR=%s\n" #: src/stored/backends/cephfs_device.c:72 #, fuzzy, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/backends/cephfs_device.c:101 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "%s existe pero no es un directorio.\n" #: src/stored/backends/cephfs_device.c:111 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "%s existe pero no es un directorio.\n" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "ioctl MTEOM error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "ioctl MTIOCGET error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "ioctl MTOFFL error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "Mala llamada a weof_dev. El dispositivo no abre\n" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "Intento de WEOF en Volumen no-appendable\n" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "ioctl MTWEOF error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "Mala llamada a fsf. Dispositivo no abierto\n" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "Dispositivo %s en el final de la cinta.\n" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "ioctl MTFSF error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:498 #, fuzzy, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "error de lectura en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "Mala llamada a bsf. Dispositivo no abierto\n" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "ioctl MTBSF error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "Mala llamada a FSR. El dispositivo no abre\n" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "ioctl MTFSR no permitido en %s.\n" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "ioctl MTFSR %d error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "Mala llamada a bsr_dev. El dispositivo no abre\n" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "ioctl MTBSR no permitido en %s.\n" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "ioctl MTBSR error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "Mala llamada a load_dev. Dispositivo no abierto\n" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "ioctl MTLOAD error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "código de función %d desconocido" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "I/O función \"%s\" no es compatible con este dispositivo. \n" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "No se puede establecer eotmodel en el dispositivo %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "Ninguna cinta cargada o unidad offline en %s.\n" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "Rebobinar error en %s. ERR=%s.\n" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "Estado del Bareos:" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "archivo=%d bloque=%d\n" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "Estado del Dispositivo:" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, fuzzy, c-format msgid "Failed to create a new context using config %s\n" msgstr "No se puede convertir acl de texto en el archivo \"%s\"\n" #: src/stored/backends/object_store_device.c:190 #, fuzzy, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "3914 No se ha podido etiquetar el volumen (no hay medios): ERR=%s\n" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, fuzzy, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "No se pudo abrir %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:274 #, fuzzy, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "No se pudo abrir %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:298 #, fuzzy, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "No se pudo abrir %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:406 #, fuzzy, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "No se pudo abrir el directorio de Plugin %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:416 #, fuzzy, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "No se pudo abrir %s: ERR=%s\n" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "Estado de Volumen Usados:\n" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" "\n" "Estado del dispositivo:\n" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "Auto-cambiador \"%s\" con los dispositivos:\n" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 #, fuzzy msgid "waiting for" msgstr "Esperando por montaje" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 #, fuzzy msgid "waiting for sysop intervention" msgstr "esta esperando por su hora de inicio" #: src/stored/status.c:275 #, fuzzy msgid "unknown state" msgstr "Estado desconocido." #: src/stored/status.c:279 #, fuzzy, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Dispositivo %s está montado con:\n" " Volumen: %s\n" " Pool: %s\n" " Tipo de Media: %s\n" #: src/stored/status.c:289 #, fuzzy, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "Dispositivo %s abierto, pero volumen actual montado no es Bareos.\n" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "Total de Bytes=%s Bloques=%s Bytes/bloques=%s\n" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "Total de Bytes Leídos=%s Bloques Leídos=%s Bytes/bloque=%s\n" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "Situado en el archivo=%s Bloque=%s\n" #: src/stored/status.c:332 #, fuzzy, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "Dispositivo %s no está abierto.\n" #: src/stored/status.c:336 #, fuzzy, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "Dispositivo \"%s\" no está abierto o no existe.\n" #: src/stored/status.c:369 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "Demonio iniciado %s, %d Job ejecutando desde el inicio.\n" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" "Ninguna estructura del DISPOSITIVO.\n" "\n" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "Dispositivo está BLOQUEADO. Usuario desmontado.\n" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" " Dispositivo está BLOQUEADO. Usuario desmontado durante espera por media/" "mount.\n" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Dispositivo está BLOQUEADO esperando por montaje de volumen \"%s\",\n" " Pool: %s\n" " Tipo de Media: %s\n" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Dispositivo está BLOQUEADO esperando para crear un volumen para:\n" " Pool: %s\n" " Tipo de Media: %s\n" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "Dispositivo está bloqueado esperando por medios.\n" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "Dispositivo se está inicializando.\n" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "El dispositivo está bloqueado etiquetando un volumen.\n" #: src/stored/status.c:523 #, fuzzy, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "Ranura %d esta cargado en la unidad %d.\n" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "Unidad %d no está cargada.\n" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "Estado del dispositivo:\n" #: src/stored/status.c:581 #, fuzzy, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" "num_writers=%d reservado=%d bloque=%d\n" "\n" #: src/stored/status.c:585 #, fuzzy msgid "Attached Jobs: " msgstr "" "\n" "Scheduled Jobs:\n" #: src/stored/status.c:604 #, fuzzy, c-format msgid " Archive name: %s Device name: %s\n" msgstr "Nombre del archivo: %s Nombre del dispositivo: %s\n" #: src/stored/status.c:607 #, fuzzy, c-format msgid " File=%u block=%u\n" msgstr "Archivo=%u bloque=%u\n" #: src/stored/status.c:610 #, fuzzy, c-format msgid " Min block=%u Max block=%u\n" msgstr "Bloque Min=%u Bloque Max=%u\n" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "%s Job %s esperando por conexión de cliente.\n" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" "Leyendo: %s %s trabajo %s JobId=%d Volumen=\"%s\"\n" " pool=\"%s\" dispositivo=%s\n" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" "Escribiendo: %s %s trabajo %s JobId=%d Volumen=\"%s\"\n" " pool=\"%s\" dispositivo=%s\n" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "encolando=%d desencolando=%d despool_wait=%d\n" #: src/stored/status.c:689 #, fuzzy, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr "Archivos=%s Bytes=%s Bytes/sec=%s\n" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "FDSocket cerrado\n" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" "\n" "Jobs esperando para reservar una unidad:\n" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "===================================================================\n" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "Base" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "Catálogo de inicio" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "Volumen para Catalogo" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "Disco para Catalogo" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "Datos" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "Nivel del Job desconocido" #: src/stored/status.c:955 #, fuzzy, c-format msgid "3900 No arg in status command: %s\n" msgstr "Comando .status malo: %s\n" #: src/stored/status.c:984 #, fuzzy, c-format msgid "3900 No arg in .status command: %s\n" msgstr "Comando .status malo: %s\n" #: src/stored/status.c:1033 #, fuzzy, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "Comando .status malo: %s\n" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "Bareos Storage: Libre" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "Bareos Storage: Ejecutando" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "Bareos Storage: Último Job Cancelado" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "Bareos Storage: Último Job Fallido" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "Bareos Storage: Último Job con Advertencias" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, fuzzy, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "Fallo al conectar a FD: Nombre del Job no encontrado: %s\n" #: src/stored/sd_cmds.c:131 #, fuzzy msgid "Unable to authenticate Storage daemon\n" msgstr "Fallo al autenticar demonio Storage.\n" #: src/stored/sd_cmds.c:182 #, fuzzy, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "Error de comando con FD, colgando. %s\n" #: src/stored/sd_cmds.c:185 #, fuzzy msgid "Command error with SD, hanging up.\n" msgstr "Error de comando con FD, colgando.\n" #: src/stored/sd_cmds.c:197 #, fuzzy, c-format msgid "SD command not found: %s\n" msgstr "Comando FD no encontrado:% s \n" #: src/stored/sd_cmds.c:338 #, fuzzy msgid "Replicate data error.\n" msgstr "Error al añadir datos.\n" #: src/stored/sd_cmds.c:343 #, fuzzy msgid "Attempt to replicate on non-open session.\n" msgstr "Intento de leer sesión no abierta.\n" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "Solo autentico Directores, no %d\n" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "Malo comando Hello desde Director en %s. Len=%d\n" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "Malo comando Hello desde Director en %s: %s\n" #: src/stored/authenticate.c:90 #, fuzzy, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "Conexión desde Director %s desconocido en %s rechazada.\n" #: src/stored/authenticate.c:133 #, fuzzy, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "Contraseña incorrecta dada por el Director en %s.\n" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" "Problema de autorización: El servidor remoto no anunció suporte TLS " "requerido.\n" #: src/stored/authenticate.c:162 #, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "Fallida la negociación TLS con DIR en \"%s:%d\"\n" #: src/stored/authenticate.c:257 #, fuzzy, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "Conexión desde Director %s desconocido en %s rechazada.\n" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, fuzzy, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "Negociación TLS fallida con SD en \"%s:%d\"\n" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "No se puede autenticar Director en %s.\n" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "Demasiados errores tratando de montar el dispositivo %s.\n" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "Job %d cancelado.\n" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "Fallo al abrir dispositivo %s Volumen \"%s\": ERR=%s\n" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "Volumen \"%s\" previamente escrito, moviendo a finales de los datos.\n" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" "No se puede posicionar al final los datos en el dispositivo %s: ERR=%s\n" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "Volumen \"%s\" no en dispositivo %s.\n" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" "Director quería Volumen \"%s\".\n" " Volumen actual \"%s\" no es aceptable porque:\n" " %s" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, c-format msgid "Could not reserve volume %s on %s\n" msgstr "No es posible reservar volumen %s en %s\n" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "Listo para anexar al final del volumen \"%s\" en el archivo=%d\n" #: src/stored/mount.c:624 #, fuzzy, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" "Bareos no puede escribir en el Volumen de cinta \"%s\" porque:\n" "El número de archivos de desfasa! Volumen=%u Catalogo=%u\n" #: src/stored/mount.c:631 src/stored/mount.c:660 #, fuzzy msgid "Error updating Catalog\n" msgstr "Error abriendo archivo de datos %s\n" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" "Bareos no puede escribir en el Volumen de cinta \"%s\" porque:\n" "El número de archivos de desfasa! Volumen=%u Catalogo=%u\n" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "Listo para anexar al final del volumen \"%s\" tamaño=%s\n" #: src/stored/mount.c:652 #, fuzzy, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" "Bareos no puedo escribir en el volumen DVD \"%s\" porque: Los tamaños no " "coinciden! Volumen=%s Catálogo=%s\n" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" "Bareos no puede escribir en el Volumen de cinta \"%s\" porque:Los tamaños no " "coinciden! Volumen=%s Catalogo=%s\n" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "Etiquetada nuevo Volumen \"%s\" en el dispositivo %s.\n" #: src/stored/mount.c:741 #, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "Dispositivo %s no configurado para volúmenes autolabel.\n" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "Marcado volumen \"%s\" en Error en el Catálogo.\n" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" "Volumen auto-cambiador \"%s\" no se encuentra en la ranura %d\n" "Estableciendo InChanger a cero en el catálogo.\n" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "Hey !!!!! No WroteVol cero !!!!!\n" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" "Posición de la cinta no válida en el volumen \"%s\" en el dispositivo %s. " "Esperaba %d, obtuvo %d\n" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "No se puede rebobinar dispositivo %s: ERR=%s\n" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" "Volumen incorrecto montado en el dispositivo %s: Esperaba %s tiene %s\n" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "Demasiados intentos: %s" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" "Volumen requerido \"%s\" en %s no es un volumen etiquetado Bareos, debido a " "que: ERR=%s" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "No se pudo leer la etiqueta de volumen desde bloque.\n" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "No se pudo unserialize etiqueta del Volumen: ERR=%s\n" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "Malo Id de cabecera de Volumen: %s\n" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" "Volumen en %s tiene la versión incorrecta de Bareos. Busco %d tiene %d\n" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "Volumen en %s tiene una malo tipo de etiqueta Bareos: %x\n" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" "No se puede escribir la etiqueta de volumen para bloquear el dispositivo %s\n" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "Error de rebobinado en el dispositivo %s: ERR=%s\n" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "Error al truncar en el dispositivo %s :ERR=%s\n" #: src/stored/label.c:538 #, fuzzy, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "" "No se ha podido re-abrir el DVD después de truncar el dispositivo %s: ERR=%" "s\n" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "No es posible escribir el dispositivo %s: ERR=%s\n" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" "Volumen \"%s\" reciclado en el dispositivo %s, todos los datos anteriores " "perdidos.\n" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" "Escribió etiqueta de volumen \"%s\" pre-etiquetada en el dispositivo %s\n" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "Mala etiqueta de Volumen de sesión = %d\n" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "Esperando Etiqueta de Volumen, obtuvo FI=%s Stream=%s len=%d\n" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "Desconocido %d" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" "\n" "Volumen Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "Fecha de etiqueta escrito: %s\n" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "Fecha de etiqueta escrito: %04d-%02d-%02d at %02d:%02d\n" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" "\n" "%s Registro:\n" "JobId : %d\n" "VerNum : %d\n" "Nombre Pool : %s\n" "Tipo del Pool : %s\n" "Nombre del Job : %s\n" "Nombre del Cliente : %s\n" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" "Job (nombre único) : %s\n" "FileSet : %s\n" "Tipo de Job : %c\n" "JobLevel : %c\n" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "Fecha escrito: %s\n" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "Fecha escrito: %04d-%02d-%02d at %02d:%02d\n" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "Volumen fresco" #: src/stored/label.c:1113 msgid "Volume" msgstr "Volumen" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "Fin de la Media" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "Fin de la Cinta" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" "%s Registro: Archivo:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "Fin de la cinta física.\n" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "Registro %s: Archivo:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "Job=%s Fecha=%s Nivel=%c Tipo=%c\n" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "Fecha=%s Nivel=%c Tipo=%c Archivos=%s Bytes=%s Errores=%d Estado=%c\n" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" "Volcado de bloque %s %x: tamaño=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "%d errores de lectura de bloques no impresos.\n" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" "Error de volumen de datos en %u:%u! Se busca ID: \"%s\",se obtiene \"%s\". " "Buffer descartado.\n" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" "Error de datos de volumen en %u:%u! Longitud de bloque %u es demente " "(demasiado grande), probablemente debido a un archivo malo.\n" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" "Error de datos de Volumen en %u:%u!\n" "Bloque checksum desajustado en bloque=%u len=%d: calc=%x blk=%x\n" #: src/stored/block.c:457 #, fuzzy, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "No se pudo escribir bloque. Dispositivo en EOM.\n" #: src/stored/block.c:463 #, fuzzy, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "Intento de escritura en volumen de sólo lectura.\n" #: src/stored/block.c:469 #, fuzzy, c-format msgid "Attempt to write on closed device=%s\n" msgstr "Intento de escritura en volumen de sólo lectura.\n" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" "Capacidad máxima %s de volumen definido por el usuario superado en el " "dispositivo %s.\n" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "No se pudo escribir EOF. ERR=%s\n" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "Escribir cabecera de bloque cero.\n" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "Error de escritura en %u:%u en el dispositivo %s. ERR=%s.\n" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" "Fin de Volumen \"%s\" en %u:%u en el dispositivo %s. Escribió %u bytes " "obtuvo %d.\n" #: src/stored/block.c:644 #, fuzzy, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" "Error de lectura en fd=%d desde archivo:blk %u:%u en el dispositivo %s. ERR=%" "s.\n" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "Fallo en retroceso de archivo desde EOT. ERR=%s\n" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "Fallo en retroceso de registro desde EOT. ERR=%s\n" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "Fallo en re-lectura del último bloque en EOT. ERR=%s" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" "Re-lectura del último bloque: número de bloque difieren en más de uno.\n" "Probable mala configuración de la cinta y pérdida de datos. Leer bloque=%u " "Espera bloque=%u.\n" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" "Re-lectura del último bloque OK, pero número de bloque difieren. Leer bloque=" "%u Espera bloque=%u.\n" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "Éxito en re-lectura del último bloque.\n" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" "Error al escribir EOF final a la cinta. Este volumen puede no ser legible.\n" "%s" #: src/stored/block.c:836 #, fuzzy msgid "Error sending Volume info to Director.\n" msgstr "Error al obtener Volumen información: %s" #: src/stored/block.c:949 #, fuzzy msgid "Job failed or canceled.\n" msgstr "Job %d cancelado.\n" #: src/stored/block.c:955 #, fuzzy msgid "Attempt to read past end of tape or file.\n" msgstr "Intento de leer sesión no abierta.\n" #: src/stored/block.c:964 #, fuzzy, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" "Error de lectura en fd=%d desde archivo:blk %u:%u en el dispositivo %s. ERR=%" "s.\n" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "Problema de tamaño de búfer del bloque en el dispositivo %s\n" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" "Error de lectura en fd=%d desde archivo:blk %u:%u en el dispositivo %s. ERR=%" "s.\n" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "Leer cero bytes en %u:%u en el dispositivo %s.\n" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" "Error datos de volumen en %u:%u! Bloque muy corto de %d bytes en " "dispositivo %s descartado.\n" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" "Longitud del bloque %u es mayor que el buffer %u. Intentando recuperación.\n" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "Configurando tamaño del bufer del bloque para %u bytes.\n" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" "Error datos de volumen en %u:%u! Bloque corto de %d bytes en dispositivo %s " "descartado.\n" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "Error de red en bnet_recv en req_vol_info.\n" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "Error al obtener Volumen información: %s" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "no recibió información de volumen vol=%s: ERR=%s" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "Error al crear registro JobMedia: ERR=%s\n" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "Error al crear registro JobMedia: %s\n" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" "Job %s cancelado a la espera de montar el dispositivo Storage \"%s\".\n" #: src/stored/askdir.c:532 #, fuzzy, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Job %s en espera. No se puede encontrar ningún volumen grabable.\n" "Por favor utilice el comando \"label\" para crear un nuevo Volumen para:\n" "Storage: %s\n" "Pool: %s\n" "Tipo de Media: %s\n" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" "Tiempo máximo de espera excedido para montar dispositivo Storage %s para el " "Job %s\n" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "pthread error en mount_next_volume.\n" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "No puede solicitar otro volumen: nombre de volumen no entregado.\n" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "Job %s cancelado a la espera de montar el dispositivo Storage %s.\n" #: src/stored/askdir.c:617 #, fuzzy, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Por favor, montar Volumen \"%s\" o etiquete uno nuevo para :\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" #: src/stored/askdir.c:623 #, fuzzy, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Por favor, montar el volumen \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "pthread error en mount_volume\n" #: src/stored/bextract.c:71 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: bextract " "\n" " -b especifica un archivo bootstrap\n" " -c especifica un archivo Storage de configuración\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -e lista de exclusión\n" " -i lista de inclusión\n" " -p proceder a pesar de los errores de E/S\n" " -v detallado\n" " -V especifica nombres de Volúmenes (separados por |)\n" " -? imprime esta mensaje\n" "\n" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" "Nombre del Programa %d y/o registros de Datos de Flujo del Programa " "ignorado.\n" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "%d registros de flujo de datos Win32 or Win32 datos gzip. Ignorados.\n" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "Flujo desconocido=%d ignorado. Esto no debería suceder!\n" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "No se puede stat %s. El debe existir. ERR=%s\n" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "%s debe ser un directorio.\n" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "%u archivos restaurados.\n" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "Error de escritura en %s: %s\n" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "Error lógico, archivo de salida debería estar abierto, pero no esta.\n" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "flujo %s no suportado en este Cliente.\n" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "%s se ha eliminado.\n" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "Buscar error en %s: %s\n" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "Tratar de %s error en %s: ERR=%s\n" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "Obtener Nombre de Programa o Secuencia de Datos. Ignorado.\n" #: src/stored/lock.c:390 #, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "pthread_cond_wait fallido. ERR=%s\n" #: src/stored/lock.c:489 msgid "unknown blocked code" msgstr "Código desconocido bloqueado" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" "Ningún Nombre Changer obtenido para el dispositivo %s. No se puede " "continuar.\n" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" "Ningún Comando Changer obtenido para el dispositivo %s. No se puede " "continuar.\n" #: src/stored/autochanger.c:133 #, fuzzy, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" "Invalida ranura=%d definida en el catálogo para volumen \"%s\" en %s. Carga " "manual puede ser requerida.\n" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" "Ninguno \"Dispositivo Changer\" para %s. Carga manual de volumen puede ser " "requerido.\n" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" "Ninguno \"Comando Changer\" para %s. Carga manual de volumen puede ser " "requerido.\n" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" "3304 Emitiendo comando auto-cambiador \"cargar ranura %d, unidad %d\".\n" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "3305 Auto-cambiador \"carga ranura %d, unidad %d\", estado es OK.\n" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" "2992 Malo Auto-cambiador \"carga ranura %d, unidad %d\": ERR=%s.\n" "Resultados=%s\n" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "3301 Emitiendo comando auto-cambiador \"¿cargado? unidad %d\".\n" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" "3302 Auto-cambiador \"¿cargado? unidad %d\", el resultado es Ranura %d.\n" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" "3302 Auto-cambiador \"¿cargado? unidad %d\", resultado: nada cargado.\n" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" "3991 Malo comando auto-cambiador comando \"cargar? unidad %d\": ERR=%s\n" "Resultados=%s\n" #: src/stored/autochanger.c:310 #, fuzzy, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "Error bloqueando Mutex. ERR=%s\n" #: src/stored/autochanger.c:324 #, fuzzy, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "Error desbloqueando Mutex. ERR=%s\n" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" "3307 Emitiendo comando auto-cambiador \"descargar ranura %d, unidad %d\"\n" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" "3995 Malo comando auto-cambiador \"descargar ranura %d, unidad %d\": ERR=%s\n" "Resultados=%s\n" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "Volumen \"%s\" buscado en %s está en uso por el dispositivo %s\n" #: src/stored/autochanger.c:535 #, fuzzy, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" "3995 Malo comando auto-cambiador \"descargar ranura %d, unidad %d\": ERR=%" "s.\n" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "3993 Dispositivo %s no es un dispositivo auto-cargador.\n" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "3306 Emitiendo comando \"%s\" al auto-cambiador.\n" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "3996 Fallo al abrir bpipe.\n" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, fuzzy, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "Auto-cambiador error: ERR=%s\n" #: src/stored/autochanger.c:699 #, fuzzy msgid "3306 Issuing autochanger transfer command.\n" msgstr "3306 Emitiendo comando \"%s\" al auto-cambiador.\n" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "error timedwait pthread. ERR=%s\n" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "JobId=%s, Job %s esperando para reservar un dispositivo.\n" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "Nohdr," #: src/stored/butil.c:57 msgid "partial," msgstr "parcial," #: src/stored/butil.c:60 msgid "empty," msgstr "vacío," #: src/stored/butil.c:63 msgid "Nomatch," msgstr "Nomatch," #: src/stored/butil.c:66 msgid "cont," msgstr "cont," #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" "Nombre de Volumen o nombres es demasiado largo. Por favor, use un archivo ." "BSR.\n" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" "No se puede encontrar el dispositivo \"%s\" en el archivo de configuración %" "s.\n" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "No se pudo iniciar dispositivo %s\n" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "No se pudo abrir %s\n" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" "No se pudo encontrar dispositivo \"%s\" en el archivo de configuración %s.\n" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "Utilizando el dispositivo: \"%s\" para lectura.\n" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "Utilizando el dispositivo: \"%s\" para escritura.\n" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "Fin Inesperado de los Datos\n" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "Fin Inesperado de la Cinta\n" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "Fin Inesperado del Archivo\n" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "Puerta de la cinta está abierta\n" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "Inesperado Cinta esta off-line\n" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "Inicio de Sesión" #: src/stored/read_record.c:63 msgid "End Session" msgstr "Fin de Sesión" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "Código desconocido %d\n" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "Fin del Volumen en archivo %u en dispositivo %s, Volumen \"%s\"\n" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "Fin de todos los volúmenes.\n" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "fsr hizo en un intento para saltar malo registro.\n" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "Adquirir leer: num_writers=%d no es cero. Empleo %d cancelado.\n" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "No se especifica el volumen de lectura. Job %s cancelado.\n" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "Error logico: no hay prójimo volumen para leer. Numvol=%d Curvol=%d\n" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" "Cambiando dispositivo de lectura. Media Type=\"%s\" tiene=\"%s\"\n" " dispositivo=%s\n" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "Cambio Media Type. Nuevo dispositivo de lectura %s elegido.\n" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "No encuentra dispositivo adecuado para leer Volumen \"%s\"\n" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "Job %s cancelado.\n" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "Fallo al leer dispositivo %s abierto, Volumen \"%s\": ERR=%s\n" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" "Demasiados errores tratando de montar el dispositivo %s para la lectura.\n" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "Listo para leer desde volumen \"%s\" en el dispositivo %s.\n" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "Esperando anexar, pero el dispositivo %s está ocupado leyendo.\n" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "Dispositivo %s puede no está listo para anexar.\n" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "Alerta: %s" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "3997 Malo comando alerta: %s: ERR=%s.\n" #: src/stored/acquire.c:654 #, fuzzy, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "Error de lectura en el dispositivo %s en la etiqueta ANSI. ERR=%s\n" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "Insano! Fin de la cinta mientras leía la etiqueta ANSI.\n" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "Ninguna etiqueta VOL1 al leer etiqueta ANSI/IBM.\n" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "Buscando volumen ANSI \"%s\" obtuvo \"%s\"\n" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "Ninguna etiqueta HDR1 al leer etiqueta ANSI.\n" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "Volumen \"%s\" ANSI/IBM, no pertenece a Bareos.\n" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "Ninguna etiqueta HDR2 al leer etiqueta ANSI/IBM.\n" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "Registro de etiqueta ANSI/IBM desconocido o malo.\n" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "Demasiados registros mientras leía etiqueta ANSI/IBM.\n" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "Nombre de etiqueta de Volumen ANSI \"%s\" más de 6 caracteres.\n" #: src/stored/ansi_label.c:349 #, fuzzy, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "No ha podido escribir etiqueta ANSI VOL1. ERR=%s\n" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "No ha podido escribir etiqueta ANSI HDR1. ERR=%s\n" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "No se puede escribir la etiqueta ANSI HDR1.\n" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "Error al escribir EOF a la cinta. ERR=%s" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "write_ansi_ibm_label llamado para tipo non-ANSI/IBM\n" #: src/stored/sd_backends.c:172 #, fuzzy, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "No se puede abrir archivo %s: ERR=%s\n" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "En free_jcr(), pero todavía conectado al dispositivo!!!!\n" #: src/stored/vol_mgr.c:98 #, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "No se puede inicializar la lista de bloqueo de volumen. ERR=%s\n" #: src/stored/bcopy.c:60 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: bcopy [-d nivel_ depuración] \n" " -b bootstrap especifica un archivo bootstrap\n" " -c especifica un archivo Storage de configuración\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -i especifica nombres de Volúmenes de entrada (separados por |)\n" " -o especifica nombres de Volúmenes de salida (separados por |)\n" " -p proceder a pesar de los errores\n" "\n" " -v detallado\n" " -w especifica directorio de trabajo (por defecto /tmp)\n" " -? imprime esta mensaje\n" "\n" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "Fallo al escribir ultimo bloque.\n" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "%u Jobs copiado. %u registros copiados.\n" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "Volumen esta pre-etiquetado. Este volumen no puede ser copiado.\n" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "Etiqueta Volumen no copiada.\n" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "Copia omitida. Registro no coincide con filtro de BSR.\n" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "Etiqueta EOM no copiada.\n" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "Etiqueta EOT no copiada.\n" #: src/stored/stored.c:76 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versión: %s (%s)\n" "\n" "Utilice: stored [opciones] [-c archivo_configuración] " "[archivo_configuración]\n" " -c usar como archivo de configuración\n" " -d establecer el nivel de depuración para \n" " -dt imprimir timestamp en salida de depuración\n" " -f ejecutar en primer plano (para depuración)\n" " -g establecer groupid para grupo\n" " -m imprimir salida kaboom para depuración)\n" " -p continuar a pesar de errores de E/S\n" " -s sin señales (para depuración)\n" " -t prueba - leer la configuración y salir\n" " -u establecer userid para \n" " -v mensajes de usuario detallados\n" " -? imprimir este mensaje.\n" "\n" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "Tiempo de Sesión de Volumen es CERO!\n" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "No se puede crear hilo. ERR=%s\n" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "Sólo un recurso Storage permitido en %s\n" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "Recurso Director no definido en %s. No se puede continuar.\n" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "Recurso Device no definido en %s. No se puede continuar.\n" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "Recurso Mensajes no definido en %s. No se puede continuar.\n" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "Archivo \"TLS Certificate\" no definido para Storage \"%s\" en %s.\n" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "Archivo \"TLS Key\" no definido para Storage \"%s\" en %s.\n" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Ni \"Certificado TLS CA \" o \"Directorio del Certificado TLS CA\" están " "definidos para el Storage \"%s\" en %s. Por lo menos un almacén de " "Certificados CA es necesario cuando se utiliza \"Verificar TLS Peer\".\n" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, fuzzy, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "No se puede iniciar job cond varibale: ERR=%s\n" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "No se puede iniciar %s\n" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "No se pudo abrir el dispositivo %s\n" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "No se pudo montar el dispositivo %s\n" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "desconocido: %d" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "Buffer dañado\n" #: src/stored/record.c:479 #, fuzzy msgid "Quota Exceeded. Job Terminated.\n" msgstr "Máximo tiempo de ejecución excedido. Job cancelado.\n" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" "Chequeo de Sanidad fracasado. maxlen=%d datalen=%d. Bloque descartado.\n" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "Flujo xattr ilegal, no hay XATTR_MAGIC en el archivo \"%s\"\n" #: src/findlib/xattr.c:261 #, fuzzy, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" "Ilegal flujo xattr, fallo al analizar flujo xattr en el archivo \"%s\"\n" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, fuzzy, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "error de llistxattr en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, fuzzy, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "error de getacl en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "Flujo Xattr en el archivo \"%s\" excede el máximo tamaño de %d bytes\n" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "No se pudo serializar los atributos extendidos en el archivo \"%s\"\n" #: src/findlib/xattr.c:650 #, fuzzy, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "setacl error en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, fuzzy, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "error de extattr_list_link en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:981 #, fuzzy, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "Flujo xattr ilegal, no hay XATTR_MAGIC en el archivo \"%s\"\n" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, fuzzy, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "error de acl_set en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "error de llistxattr en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "error de lgetxattr en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "error de lsetxattr en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "error de extattr_list_link en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "No se pudo convertir %d al namespace en el archivo \"%s\"\n" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "error de extattr_get_link en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" "No se ha podido separar %s en el namespace y parte del nombre en el archivo " "\"%s\"\n" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "No se pudo convertir %s al namespace en el archivo \"%s\"\n" #: src/findlib/xattr.c:1965 #, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "error de extattr_set_link en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, fuzzy, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "error de getacl en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2292 #, fuzzy, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "No es posible leer el contenido de xattr %s en el archivo \"%s\"\n" #: src/findlib/xattr.c:2321 #, fuzzy, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "strtoacl error en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede obtener acl en xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "" "No se puede obtener acl texto en xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede obtener estado en xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "No se puede abrir xattr %s en \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "No se puede leer symlin %s en \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "No es posible leer el contenido de xattr %s en el archivo \"%s\"\n" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "No se puede chdir a xattr espacio de archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "No se puede abrir el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "No se puede abrir espacio xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "No se puede chdir a xattr espacio en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "No se puede listar el xattr espacio en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "No se puede convertir acl de texto en el archivo \"%s\"\n" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede restablecer acl de xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "No se puede abrir xattr espacio en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede abrir xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "No se puede chdir a xattr espacio de %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede mkfifo xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede mknode xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "No se puede mkdir xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "No se puede link xattr %s para %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" "No se puede restaurar los datos de xattr %s en el archivo \"%s\": No todos " "los datos disponibles en flujo xattr\n" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "" "No se puede restaurar los datos de xattr %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "No se puede symlink xattr %s para %s en el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "" "No es posible restablecer el propietario de xattr %s en el archivo \"%s\": " "ERR=%s\n" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "" "No es posible restablecer filetimes de xattr %s en el archivo \"%s\": ERR=%" "s\n" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" "Ilegal flujo xattr, fallo al analizar flujo xattr en el archivo \"%s\"\n" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "Fallo al restablecer atributos extensible en el archivo \"%s\"\n" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "Fallo al restablecer atributos extendidos en el archivo \"%s\"\n" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, fuzzy, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "No se puede abrir el archivo \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" "No se puede restaurar los atributos extendidos de %s - incompatible flujo " "xattr encontrado - %d\n" #: src/findlib/find.c:180 #, fuzzy, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "Plugin=%s no encontrado.\n" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "Atributos Unix" #: src/findlib/bfile.c:92 msgid "File data" msgstr "Archivo de datos" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "Sumario MD5" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "GZIP datos" #: src/findlib/bfile.c:98 #, fuzzy msgid "Compressed data" msgstr "Datos dispersos" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "Atributos extendidos" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "Datos dispersos" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "Datos GZIP dispersos" #: src/findlib/bfile.c:106 #, fuzzy msgid "Compressed sparse data" msgstr "Datos GZIP dispersos" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "Programa de nombres" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "Datos de programa" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "Sumario SHA1" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "Win32 datos" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "Win32 GZIP datos" #: src/findlib/bfile.c:118 #, fuzzy msgid "Win32 compressed data" msgstr "Win32 datos" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "Datos rama MacOS" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "HFS+ attribs" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "ACL estándar de Unix attribs" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "ACL por defecto de Unix attribs" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "Sumario SHA256" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "Sumario SAH512" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "Sumario Firmado" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "Cifrado de Archivo de datos" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "Cifrado de datos Win32" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "Cifrado de datos de sesiones " #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "Cifrado de datos GZIP" #: src/findlib/bfile.c:142 #, fuzzy msgid "Encrypted compressed data" msgstr "Cifrado de datos de sesiones " #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "Cifrado de datos Win32 GZIP" #: src/findlib/bfile.c:146 #, fuzzy msgid "Encrypted Win32 Compressed data" msgstr "Cifrado de datos Win32" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "Datos encriptados rama MacOS" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "Atributos ACL específicos de AIX" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "Atributos ACL específicos de Darwin" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "Atributos ACL por defecto específicos de FreeBSD" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "Atributos ACL de acceso específicos de FreeBSD" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "Atributos ACL específicos de HPUX" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "Atributos ACL por defecto específicos de Irix" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "Atributos ACL de acceso específicos de Irix" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "Atributos ACL por defecto específicos de Linux" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "Atributos ACL de acceso específicos de Linux" #: src/findlib/bfile.c:168 #, fuzzy msgid "TRU64 Specific Default ACL attribs" msgstr "Atributos ACL por defecto específicos de Irix" #: src/findlib/bfile.c:170 #, fuzzy msgid "TRU64 Specific Access ACL attribs" msgstr "Atributos ACL de acceso específicos de Irix" #: src/findlib/bfile.c:172 #, fuzzy msgid "Solaris Specific POSIX ACL attribs" msgstr "Atributos ACL específicos de Solaris" #: src/findlib/bfile.c:174 #, fuzzy msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "Atributos ACL específicos de Solaris" #: src/findlib/bfile.c:176 #, fuzzy msgid "AFS Specific ACL attribs" msgstr "Atributos ACL específicos de AIX" #: src/findlib/bfile.c:178 #, fuzzy msgid "AIX Specific POSIX ACL attribs" msgstr "Atributos ACL específicos de AIX" #: src/findlib/bfile.c:180 #, fuzzy msgid "AIX Specific NFSv4 ACL attribs" msgstr "Atributos ACL específicos de AIX" #: src/findlib/bfile.c:182 #, fuzzy msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "Atributos ACL de acceso específicos de FreeBSD" #: src/findlib/bfile.c:184 #, fuzzy msgid "GNU Hurd Specific Default ACL attribs" msgstr "Atributos ACL por defecto específicos de Irix" #: src/findlib/bfile.c:186 #, fuzzy msgid "GNU Hurd Specific Access ACL attribs" msgstr "Atributos ACL de acceso específicos de Irix" #: src/findlib/bfile.c:188 #, fuzzy msgid "GNU Hurd Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Linux" #: src/findlib/bfile.c:190 #, fuzzy msgid "IRIX Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Linux" #: src/findlib/bfile.c:192 #, fuzzy msgid "TRU64 Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Linux" #: src/findlib/bfile.c:194 #, fuzzy msgid "AIX Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Linux" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "Atributos Extendidos específicos de OpenBSD" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" "Atributos extensible específicos de Solaris o atributos de Sistema de " "Extensión" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Solaris" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Darwin" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "Atributos Extendidos Específicos de FreeBSD" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "Atributos Extendidos Específicos de Linux" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "Atributos Extendidos Específicos de NetBSD" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "No se pudo establecer propietario del archivo %s: ERR=%s\n" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "No se pudo establecer modos del archivo %s: ERR=%s\n" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "No se pudo establecer tiempos del archivo %s: ERR=%s\n" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" "Tamaño del archivo %s restaurado no es correcto. Original %s, restaurado %" "s.\n" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "No es posible establecer banderas en archivo %s: ERR=%s\n" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "Error en %s archivo %s: ERR=%s\n" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "Error en %s: ERR=%s\n" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "No se puede abrir el directorio actual: ERR=%s\n" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "No se puede obtener el directorio actual: ERR=%s\n" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "No se puede restablecer el directorio actual: ERR=%s\n" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "Establecer AdjustTokenPrivileges " #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "Archivo omitido. No más reciente: %s\n" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "Archivo omitido. No más viejo: %s\n" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "Archivo omitido. Ya existe: %s\n" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "El archivo %s ya existe y no puede ser reemplazado. ERR=%s.\n" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "bpkt ya abierto fid=%d\n" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "No se pudo crear %s: ERR=%s\n" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "No puede crear fifo %s: ERR=%s\n" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "No puede crear nodo %s: ERR=%s\n" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "" "No se pudo restaurar el archivo de banderas para el archivo% s: ERR=%s\n" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "No se pudo crear enlace duro %s -> %s: ERR=%s\n" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "" "No se pudo restablecer el archivo de banderas para el archivo %s: ERR=%s\n" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "No se pudo crear enlace simbólico %s -> %s: ERR=%s\n" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "Archivo %s original se han eliminado: tipo=%d\n" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "Archivo original %s no guardado: tipo=%d\n" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "Tipo de archivo desconocido %d; no restaurado: %s\n" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "Nombre de archivo con longitud cero: %s\n" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "No se puede crear directorio %s: ERR=%s\n" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "%s existe pero no es un directorio.\n" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "No se puede cambiar el propietario y/o grupo de %s: ERR=%s\n" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "No puede cambiar los permisos de %s: ERR=%s\n" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "%c: no es una unidad válida.\n" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "Demasiados subdirectorios. Algunos permisos no se restablece.\n" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "Indicador NODUMP establecido - no procesará %s\n" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "No puede stat archivo %s: ERR=%s\n" #: src/findlib/find_one.c:268 #, fuzzy, c-format msgid "%s: mtime changed during backup.\n" msgstr "%s mtime cambiado durante la copia de seguridad.\n" #: src/findlib/find_one.c:275 #, fuzzy, c-format msgid "%s: ctime changed during backup.\n" msgstr "%s ctime cambiado durante la copia de seguridad.\n" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, fuzzy, c-format msgid "%s: size changed during backup.\n" msgstr "%s tamaño cambiado durante la copia de seguridad.\n" #: src/findlib/find_one.c:729 #, fuzzy, c-format msgid "%s: File name too long [%d]\n" msgstr "Nombre de Volumen demasiado largo.\n" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "Directorio de nivel superior \"%s\" tiene fstype \"%s\" no listado\n" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" "Directorio de nivel superior \"%s\" tiene un tipo de unidad \"%s\" no " "listado\n" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, fuzzy, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "error de acl_get en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:293 #, fuzzy, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "" "codificación errónea del tipo de ACL en el flujo de ACL en el archivo \"%s" "\" \n" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, fuzzy, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "No se puede convertir acl de texto en el archivo \"%s\"\n" #: src/findlib/acl.c:403 #, fuzzy, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl\n" #: src/findlib/acl.c:411 #, fuzzy, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl\n" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, fuzzy, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "error de acl_set en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:495 #, fuzzy, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "error de acl_get en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "acl_to_text error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "error de acl_get_file en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:929 #, fuzzy, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "acl_delete_def_file error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "acl_delete_def_file error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "acl_from_text error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:967 #, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "error de acl_valid en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1000 #, fuzzy, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "acl_set_file error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "acl_set_file error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "error de pathconf en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1283 #, fuzzy, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl\n" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "error de getacl en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "altostr error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "strtoacl error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1683 #, fuzzy, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl\n" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "setacl error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "error de acl_get en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl\n" #: src/findlib/acl.c:1922 #, fuzzy, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl aclent\n" #: src/findlib/acl.c:1933 #, fuzzy, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" "Tratando de restaurar acl en el archivo \"%s\" en sistema de ficheros sin " "soporte a acl ace\n" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "error de acl_fromtext en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" "codificación errónea del tipo de ACL en el flujo de ACL en el archivo \"%s" "\" \n" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "error de acl_set en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "acltotext error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "aclfromtext error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "acl(SETACL) error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:2196 #, fuzzy, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "acl(SETACL) error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:2225 #, fuzzy, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "acl(SETACL) error en el archivo \"%s\": ERR=%s\n" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" "No puede restaurar ACL de %s - incompatible flujo acl encontrado - %d\n" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, fuzzy, c-format msgid "Unparseable size option: %s\n" msgstr "Opción replace no valida: %s\n" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, fuzzy, c-format msgid "Unexpected autodeflate setting on %s" msgstr "Se esperaba una cadena drivetype, se obtuvo: %s\n" #: src/plugins/stored/autoxflate-sd.c:368 #, fuzzy, c-format msgid "Unexpected autoinflate setting on %s" msgstr "Se esperaba una cadena fstype, se obtuvo: %s\n" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "Error de compresión DeflateParams: %d\n" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, fuzzy, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "Error de compresión DeflateReset: %d\n" #: src/plugins/stored/autoxflate-sd.c:575 #, fuzzy, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "Error Fatal añadiendo en el dispositivo %s: ERR=%s\n" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, fuzzy, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" "Error de lectura en fd=%d desde archivo:blk %u:%u en el dispositivo %s. ERR=%" "s.\n" #: src/plugins/filed/bpipe-fd.c:910 #, fuzzy msgid "Plugin File argument not specified.\n" msgstr "Plugin guardar paquetes no encontrado.\n" #: src/plugins/filed/bpipe-fd.c:916 #, fuzzy msgid "Plugin Reader argument not specified.\n" msgstr "Plugin guardar paquetes no encontrado.\n" #: src/plugins/filed/bpipe-fd.c:922 #, fuzzy msgid "Plugin Writer argument not specified.\n" msgstr "Plugin guardar paquetes no encontrado.\n" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, fuzzy, c-format msgid "Enter Key Encryption Key: " msgstr "Introduzca el nuevo periodo de retención:" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, fuzzy, c-format msgid "Cannot open keyfile %s\n" msgstr "No se pudo abrir %s\n" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, fuzzy, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "Fallo al restablecer atributos extendidos en el archivo \"%s\"\n" #: src/tools/bscrypto.c:401 #, fuzzy, c-format msgid "Enter Encryption Key: " msgstr "Introduzca el nuevo periodo de retención:" #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, fuzzy, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" "\n" "Utilice: drivetype [-v] ruta ...\n" "\n" " Imprime el tipo de unidad dado a archivo/directorio esta activada.\n" " Las siguientes opciones están soportados:\n" "\n" " -v imprime ambos tipos de rutas y archivo de sistemas.\n" " -? imprime esta mensaje.\n" "\n" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "%s: desconocido\n" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "Fatal malformación de respuesta desde %s: %s\n" #: src/tools/bsmtp.c:144 #, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "fgets fatal error: ERR=%s\n" #: src/tools/bsmtp.c:177 #, fuzzy, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" "\n" "Utilice: %s [-f desde] [-h servidor de correo] [-s asunto] [-c con copia] " "[destinatario ...]\n" " -8 conjunto charset a UTF-8\n" " -c establece el campo Cc:\n" " -d establece el nivel de depuración para \n" " -dt imprime un timestamp en salida de depuración\n" " -f establece el campo Desde:\n" " -h use servidor de correo:puerto como servidor SMTP\n" " -s establece el campo Asunto:\n" " -r establece el campo Responder-Para:\n" " -l establece el número máximo de líneas a enviar (por defecto: sin límite)\n" " -? imprimir este mensaje.\n" "\n" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "Fatal error: destinatario no determinado.\n" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "gethostname fatal error: ERR=%s\n" #: src/tools/bsmtp.c:403 #, fuzzy, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "Fallo fatal gethostbyname para mi mismo \"%s\": ERR=%s\n" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "Fallo fatal gethostbyname para mi mismo \"%s\": ERR=%s\n" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "Error servidor de correo \"%s\" desconocido: ERR=%s\n" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "Reintentando la conexión usando \"localhost\".\n" #: src/tools/bsmtp.c:501 #, fuzzy, c-format msgid "Failed to connect to mailhost %s\n" msgstr "Fallo al conectar con el cliente.\n" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" "Fatal error: Desconocida familia de direcciones para servidor smtp: %d\n" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "Fatal error de socket: ERR=%s\n" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "Fatal error de conexión para %s: ERR=%s\n" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "Fatal error _open_osfhandle: ERR=%s\n" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "Fatal error fdopen: ERR=%s\n" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "Fatal error dup: ERR=%s\n" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" "\n" "Utilice: fstype [-v] ruta ...\n" "\n" " Imprime el tipo de sistema de archivo de un determinado archivo/" "directorio.\n" "Las siguientes opciones son compatibles:\n" "\n" " -v imprimir tanto tipo de rutas y sistema de archivos.\n" " -? imprimir este mensaje.\n" "\n" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "Incompatible resume tipo=%d especificado\n" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "No puede abrir el archivo de mensajes de la consola %s: ERR=%s\n" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "No se pudo obtener con mutex: ERR=%s\n" #: src/lib/message.c:491 #, fuzzy msgid "BAREOS Message" msgstr "Bareos Message" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "Fallo al abrir tubería de correo %s: ERR=%s\n" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "Fallo al abrir tubería de correo .\n" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "Error al cerrar: ERR=%s\n" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "Programa de Correo: %s" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" "Programa de correo terminado en error.\n" "CMD=%s\n" "ERR=%s\n" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "fopen %s ha fallado: ERR=%s\n" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, fuzzy, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" "Operador de programa de correo terminado en error.\n" "CMD=%s\n" "ERR=%s\n" #: src/lib/message.c:1054 #, fuzzy, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "fopen %s ha fallado: ERR=%s\n" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "%s: ABORTADO debido a un ERROR en %s:%d\n" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "%s: ERROR DE TERMINACIÓN en %s:%d\n" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "%s: Error Fatal porque: " #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "%s: Error Fatal en %s:%d porque:\n" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "%s: ERROR: " #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "%s: ERROR en %s:%d " #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "%s: Advertencia: " #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "%s: Violación de seguridad: " #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "%s: ABORTADO debido a un ERROR\n" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "%s: ERROR DE TERMINACIÓN\n" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "%s JobId %u: Error Fatal: " #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "%s JobId %u: Error: " #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "%s JobId %u: Advertencia: " #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "%s JobId %u: Violación de seguridad: " #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "%s: ejecutar %s \"%s\"\n" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "Runscript: No pudo ejecutar %s. ERR=%s\n" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "Runscript: %s devolvió estado=%d distinto de cero. ERR=%s\n" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "--> EjecutarScript\n" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr "--> Comando=%s\n" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr "--> Objetivo=%s\n" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr "--> RunOnSuccess=%u\n" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr "--> RunOnFailure=%u\n" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "--> FailJobOnError=%u\n" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr "--> EjecutarCuando=%u\n" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "Probablemente comienza el problema en la línea %d\n" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" "Error de configuración: %s\n" " : línea %d, columna %d en el archivo %s\n" "%s\n" "%s" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "Error de configuración: %s\n" #: src/lib/lex.c:140 #, fuzzy, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" "Error de configuración: %s\n" " : línea %d, columna %d en el archivo %s\n" "%s\n" "%s" #: src/lib/lex.c:144 #, fuzzy, c-format msgid "Config warning: %s\n" msgstr "Error de configuración: %s\n" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "Cierre de archivo NULL\n" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" "get_char: llamado después de EOF. Usted puede tener una comilla doble " "abierta sin el cierre de comillas dobles.\n" #: src/lib/lex.c:359 msgid "none" msgstr "ninguno" #: src/lib/lex.c:360 msgid "comment" msgstr "comentario" #: src/lib/lex.c:361 msgid "number" msgstr "numero" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "ip_addr" #: src/lib/lex.c:363 msgid "identifier" msgstr "identificar" #: src/lib/lex.c:364 msgid "string" msgstr "cadena" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "quoted_string" #: src/lib/lex.c:366 msgid "include" msgstr "incluir" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "include_quoted_string" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "Marca de Orden de UTF-8 Byte" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "Marca de Orden de UTF-16le Byte" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "esperaba un numero entero positivo, obtuvo: %s" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" "Este archivo de configuración parece estar en un formato no compatible con " "Unicode (UTF-16be). Por favor, vuelva a guardar como UTF-8\n" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "No se puede abrir el archivo de configuración incluido %s: %s\n" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "esperaba un numero entero o un rango, obtuvo %s: %s" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "esperaba un numero entero, obtuvo %s: %s" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "esperaba un nombre, obtuvo %s: %s" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "nombre %s longitud %d demasiado largo, el máximo es %d\n" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "esperaba una cadena, obtuvo %s: %s" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "Backup" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "Verificando" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "Restaurando" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "Archivando" #: src/lib/jcr.c:248 msgid "Copying" msgstr "Copiando" #: src/lib/jcr.c:250 msgid "Migration" msgstr "Migración" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "Escaneando" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "Operación desconocida" #: src/lib/jcr.c:265 msgid "backup" msgstr "backup" #: src/lib/jcr.c:267 msgid "verified" msgstr "verificado" #: src/lib/jcr.c:269 msgid "restored" msgstr "restaurado" #: src/lib/jcr.c:269 msgid "restore" msgstr "restaurar" #: src/lib/jcr.c:271 msgid "archived" msgstr "archivado" #: src/lib/jcr.c:271 msgid "archive" msgstr "archivo" #: src/lib/jcr.c:273 msgid "copied" msgstr "copiado" #: src/lib/jcr.c:273 msgid "copy" msgstr "copia" #: src/lib/jcr.c:275 msgid "migrated" msgstr "migrado" #: src/lib/jcr.c:275 msgid "migrate" msgstr "migrar" #: src/lib/jcr.c:277 msgid "scanned" msgstr "escaneado" #: src/lib/jcr.c:277 msgid "scan" msgstr "escanear" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "acción desconocida" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "fallo crear clave pthread: ERR=%s\n" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "fallo pthread_once. ERR=%s\n" #: src/lib/jcr.c:394 #, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "No se pudo iniciar msg_queue mutex. ERR=%s\n" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "NULL jcr.\n" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "JCR use_count=%d JobId=%d\n" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "fallo pthread_setspecific: ERR=%s\n" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" "Watchdog envío kill después de %d segundos para hilo estancado leyendo " "demonio Storage.\n" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" "Watchdog envío kill después de %d segundos para hilo estancado leyendo " "demonio File.\n" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" "Watchdog envío kill después de %d segundos para hilo estancado leyendo " "demonio Director.\n" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "No se pudo encontrar userid=%s: ERR=%s\n" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "No se pudo encontrar contraseña de entrada. ERR=%s\n" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "No se pudo encontrar grupo=%s: ERR=%s\n" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "Podría no initgroups para grupo=%s, userid=%s: ERR=%s\n" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "Podría no initgroups para userid=%s: ERR=%s\n" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "No se pudo establecer grupo=%s: ERR=%s\n" #: src/lib/priv.c:108 #, c-format msgid "prctl failed: ERR=%s\n" msgstr "prctl fallido: ERR=%s\n" #: src/lib/priv.c:112 #, c-format msgid "setreuid failed: ERR=%s\n" msgstr "setreuid fallido: ERR=%s\n" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "cap_from_text fallido: ERR=%s\n" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "cap_set_proc fallido: ERR=%s\n" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "seguir readall caps no implementado en este SO o faltan bibliotecas.\n" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "No se pudo establecer userid especificado: %s\n" #: src/lib/var.c:2673 msgid "everything ok" msgstr "todo bien" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "carácter nombrado incompleto" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "valor hexadecimal incompleto" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "valor hexadecimal inválido" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "valor octal demasiado grande" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "valor octal inválido" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "valor octal incompleto" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "valor hexadecimal agrupado incompleto" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "incorrecta especificación de clase de caracteres" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "configuración de expansión inválido" #: src/lib/var.c:2683 msgid "out of memory" msgstr "sin memoria" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "especificación de la variable incompleta" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "variable no definida" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "de entrada no es ni texto ni variable" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "carácter de comando desconocido en la variable" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "mal-formada operación de búsqueda y reemplazo" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "bandera desconocida en operación de búsqueda y reemplazo" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "regex no válida en operación de búsqueda y reemplazo" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "faltan parámetros en el comando" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "palabra de búsqueda vacía en operación de búsqueda y reemplazo" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "inicio offset ausente en operación de corte" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "offset en operación de corte delimitado por carácter desconocido" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "rango fuera de límites en operaciones de corte" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "desplazamiento fuera de límites en operaciones de corte" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "error lógico en la operación de corte" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "malformación en operación de transposición" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "clase de origen y de destino desajustada en operación de transposición" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "clase de caracteres vacía en operación de transposición" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "clase de caracteres incorrectos en la operación adaptación" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "malformación en operación de relleno" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "parámetro de anchura ausente en la operación de relleno" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "cadena de llenado ausente en la operación de relleno" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "par de citado desconocido en operación de búsqueda y reemplazo" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "referencia de sub-coincidente fuera de rango" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "argumento invalido" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "par de la cita incompleta" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "función de búsqueda no soporta conjuntos de variables" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "índice de la variable de matriz contiene un carácter inválido" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "índice de la variable de matriz está incompleta" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "expresión de corchetes en el índice variable de matriz no cerrado" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "Error de división por cero en especificación del índice" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "no terminado la construcción de bucle" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "carácter no válido en el bucle de límites" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "lista de argumentos de operación mal formada " #: src/lib/var.c:2717 msgid "undefined operation" msgstr "operación no definida" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "Error de formato" #: src/lib/var.c:2727 msgid "unknown error" msgstr "error desconocido" #: src/lib/scsi_crypto.c:238 #, fuzzy msgid "Drive encryption status:\n" msgstr "Estado del Dispositivo:\n" #: src/lib/scsi_crypto.c:246 #, fuzzy msgid "Encryption Mode: Disabled\n" msgstr "Error de cifrado\n" #: src/lib/scsi_crypto.c:251 #, fuzzy msgid "Encryption Mode: External\n" msgstr "Error de cifrado\n" #: src/lib/scsi_crypto.c:256 #, fuzzy msgid "Encryption Mode: Encrypt\n" msgstr "Error de cifrado\n" #: src/lib/scsi_crypto.c:269 #, fuzzy msgid "Decryption Mode: Disabled\n" msgstr "Error de descifrado\n" #: src/lib/scsi_crypto.c:274 #, fuzzy msgid "Decryption Mode: Raw\n" msgstr "Error de descifrado\n" #: src/lib/scsi_crypto.c:279 #, fuzzy msgid "Decryption Mode: Decrypt\n" msgstr "Error de descifrado\n" #: src/lib/scsi_crypto.c:284 #, fuzzy msgid "Decryption Mode: Mixed\n" msgstr "Error de descifrado\n" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 #, fuzzy msgid "Volume encryption status:\n" msgstr "Estado de Volumen Usados:\n" #: src/lib/scsi_crypto.c:460 #, fuzzy msgid "Compression Status: Unknown\n" msgstr "Estado del job: Desconocido (%c)" #: src/lib/scsi_crypto.c:465 #, fuzzy msgid "Compression Status: Unavailable\n" msgstr "Estado disponible para:\n" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 #, fuzzy msgid "Encryption Status: Unknown\n" msgstr "Estado del job: Desconocido (%c)" #: src/lib/scsi_crypto.c:495 #, fuzzy msgid "Encryption Status: Unavailable\n" msgstr "Estado disponible para:\n" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 #, fuzzy msgid "Drive encryption status: Unknown\n" msgstr "Unidad %d estado desconocido.\n" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "Ha fallado la conexión de inicialización TLS.\n" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "Negociación TLS fallida.\n" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" "Comprobación de certificados TLS fallido. Certificado equivalente no " "corresponde con el commonName requerido\n" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" "Fallo en verificación en certificado TLS de la maquina. Nombre de la maquina " "\"%s\" no coincide con el certificado presentado\n" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "TLS activado, pero no configurado.\n" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "TLS permitido, pero no configurado.\n" #: src/lib/bnet.c:326 msgid "No problem." msgstr "No hay problema." #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "Respuesta autoritativa para el host no encontrado." #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "Non-autoritativa para la maquina no encontrada, o ServerFail." #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "Errores no recuperables, FORMERR, RECHAZADO o NOTIMP." #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "Nombre válido, ningún registro de datos del tipo solicitado." #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "Error desconocido." #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "Sig desconocido %d" #: src/lib/crypto_cache.c:160 #, fuzzy, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "No es posible crear el archivo de estado. %s ERR=%s\n" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 #, fuzzy msgid "Volumename" msgstr "Volumen" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 #, fuzzy msgid "EncryptionKey" msgstr "Introduzca el nuevo periodo de retención:" #: src/lib/crypto_cache.c:354 #, fuzzy msgid "Added" msgstr "Agregar" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "No se puede inicializar bloqueo de vigilancia. ERR=%s\n" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "BUG! register_watchdog llamado antes de start_watchdog\n" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "BUG! Watchdog %p tiene llamada NULL\n" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "BUG! Watchdog %p tiene intervalo cero \n" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "ERROR! unregister_watchdog_unlocked llamado antes start_watchdog\n" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "rwl_writelock failure. ERR=%s\n" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "rwl_writeunlock failure. ERR=%s\n" #: src/lib/plugins.c:144 #, fuzzy, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "fopen %s ha fallado: ERR=%s\n" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "Fallo buscando por loadPlugin en plugin %s: ERR=%s\n" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "Fallo buscando por unloadPlugin en plugin %s: ERR=%s\n" #: src/lib/plugins.c:274 #, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "No se pudo abrir el directorio de Plugin %s: ERR=%s\n" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "No se pudo encontrar ningún plugin en %s\n" #: src/lib/bsys.c:64 #, fuzzy, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "No se ha podido compilar patrón regex \"%s\" ERR=%s\n" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "Fuera de memoria: ERR=%s\n" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "Desbordamiento de búfer.\n" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "Malo errno" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "Memset para %d bytes en %s:%d\n" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "No se puede abrir el archivo pid. %s ERR=%s\n" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" "%s ya está en ejecución. pid=%d\n" "Compruebe el archivo %s\n" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "No se pudo abrir el archivo pid. %s ERR=%s\n" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "No es posible crear el archivo de estado. %s ERR=%s\n" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "Error de escritura HDR final: ERR=%s\n" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "No es posible destruir la cola de cliente: ERR=%s\n" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "No se pudo iniciar cola cliente: ERR=%s\n" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "No se pudo agregar job a la cola de cliente: ERR=%s\n" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "Hijo salió normalmente." #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "Error desconocido durante el programa execvp" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "Hijo salió con el código %d" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "Niño muerto con la señal %d: %s" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "Invalido errorno. Imposible mensaje de error." #: src/lib/crypto.c:174 msgid "No error" msgstr "Ningún error" #: src/lib/crypto.c:176 msgid "Signer not found" msgstr "Firmante no encontrado" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "Recipiente no encontrado" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "Algoritmo de resumen no soportado" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "Algoritmo de cifrado no soportado" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "La firma no es válida" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "Error de Descifrado" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "Error interno" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "Error desconocido" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "Error escaneando atributos: %s\n" #: src/lib/sellist.c:62 #, fuzzy msgid "Negative numbers not permitted.\n" msgstr "Números negativos no permitidos.\n" #: src/lib/sellist.c:99 #, fuzzy msgid "Selection items must be be greater than zero.\n" msgstr "Los valores deben ser ser mayor que cero.\n" #: src/lib/sellist.c:103 #, fuzzy msgid "Selection item too large.\n" msgstr "Ranura demasiado grande.\n" #: src/lib/sellist.c:160 #, fuzzy msgid "No input string given.\n" msgstr "Especificación de archivo no dado.\n" #: src/lib/crypto_gnutls.c:243 #, fuzzy, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "No se puede iniciar mutex: ERR=%s\n" #: src/lib/ini.c:262 src/lib/ini.c:274 #, fuzzy, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Error de configuración: %s\n" " : línea %d, columna %d en el archivo %s\n" "%s\n" "%s" #: src/lib/ini.c:312 src/lib/ini.c:324 #, fuzzy, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Error de configuración: %s\n" " : línea %d, columna %d en el archivo %s\n" "%s\n" "%s" #: src/lib/ini.c:560 src/lib/ini.c:672 #, fuzzy, c-format msgid "Cannot open config file %s: %s\n" msgstr "No se pudo abrir archivo de configuración \"%s\": %s\n" #: src/lib/edit.c:490 #, fuzzy msgid "Empty name not allowed.\n" msgstr "Bloque de direcciones vacío no está permitido" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "Carácter ilegal \"%c\" en el nombre.\n" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "Nombre demasiado largo.\n" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "Solo ipv4 y ipv6 estan soportado (%d)\n" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "Solo ipv4 esta soportado (%d)\n" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "Se trató de asignar una dirección IPv6 a IPv4(%d)\n" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "Se trató de asignar una dirección IPv4 a IPv6(%d)\n" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" "el viejo estilo de las direcciones no se pueden mezclar con el nuevo estilo" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "no se puede resolver el servicio(%s)" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "no se puede resolver el hostname(%s) %s" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "No se puede agregar dirección por defecto (%s)\n" #: src/lib/tls_gnutls.c:124 #, fuzzy, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "" "No se ha podido re-abrir el DVD después de truncar el dispositivo %s: ERR=%" "s\n" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, fuzzy, c-format msgid "Error loading CA certificates from %s\n" msgstr "Error cargando archivos de certificados" #: src/lib/tls_gnutls.c:162 #, fuzzy msgid "Certificate file must be specified as a verification store\n" msgstr "" "Un certificado de archivo o un directorio debe especificarse como un " "almacenes de verificación\n" #: src/lib/tls_gnutls.c:179 #, fuzzy, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "Error al cargar los almacenes de verificación del certificado" #: src/lib/tls_gnutls.c:201 #, fuzzy, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "Error cargando archivos de certificados" #: src/lib/tls_gnutls.c:216 #, fuzzy, c-format msgid "Failed to load DH file %s\n" msgstr "No se ha podido asignar un nuevo objeto keypair.\n" #: src/lib/tls_gnutls.c:224 #, fuzzy msgid "Failed to generate new DH parameters\n" msgstr "No se pudo establecer parámetros TLS de Diffie-Hellman" #: src/lib/tls_gnutls.c:289 #, fuzzy, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "cap_set_proc fallido: ERR=%s\n" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, fuzzy, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "No se pudo abrir %s: ERR=%s\n" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "Fallo rwl_writelock en %s:%d: ERR=%s\n" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "Fallo \trwl_writeunlock en %s:%d: ERR=%s\n" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "***DESCONOCIDO***" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "esperaba un =, obtuvo: %s" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "Código de ítem desconocido: %d\n" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "tipo de mensaje: %s no encontrado" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "Intento de redefinir el nombre \"%s\" para \"%s\"." #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "Intento de redefinir recurso \"%s\" referenciado en la línea %d: %s\n" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "Demasiadas directivas %s. Máximo es %d. linea %d: %s\n" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "" "No pudo encontrar recurso de configuración \"%s\" referenciado en linea %d : " "%s\n" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" "Falta la configuración de Recurso \"%s\" referenciado en linea %d : %s\n" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "esperaba un numero de tamaño, obtuvo: %s" #: src/lib/res.c:830 #, fuzzy, c-format msgid "expected a speed number, got: %s" msgstr "esperaba un numero de tamaño, obtuvo: %s" #: src/lib/res.c:835 #, fuzzy msgid "unknown unit type encountered" msgstr "" "codificación errónea del tipo de ACL en el flujo de ACL en el archivo \"%s" "\" \n" #: src/lib/res.c:853 #, fuzzy, c-format msgid "expected a %s, got: %s" msgstr "esperaba un tamaño, obtuvo: %s" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "esperaba una etiqueta Tape Label , obtuvo: %s" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "Esperaba un inicio de bloque {, obtuvo: %s" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "Bloque de direcciones vacío no está permitido" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "Esperaba una cadena, obtuvo: %s" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "Espera una cadena [ip|ipv4|ipv6], obtuvo: %s" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "Espera una cadena [ip|ipv4], obtuvo: %s" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "Esperaba una igual =, obtuvo: %s" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "Esperaba un identificador [addr|port], obtuvo: %s" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "Sólo un puerto por bloque de direcciones" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "Sólo una dirección por bloque de direcciones" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "Esperaba un numero o una cadena , obtuvo: %s" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "Esperaba un numero IP o un hostname, obtuvo: %s" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "Estado de la máquina desajustado" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "Esperaba un fin de bloque }, obtuvo: %s" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" "No se puede agregar el nombre de maquina(%s) y puerto(%s) a addrlist(%s)" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "no puede agregar el puerto (%s) a (%s)" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "Esperaba un numero de puerto o cadena, obtuvo: %s" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "rwl_writeunlock llamado muchas veces.\n" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "rwl_writeunlock por no-propietario.\n" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "Hilo %d encontró elementos sin cambios %d veces\n" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "%02d: intervalo %d, escritos %d, leídos %d\n" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "datos %02d: valor %d, %d escritos\n" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "Total: %d hilos escritos, %d datos escritos\n" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "Intente escribir bloqueo" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "Intente leer bloqueo" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "Crear hilo" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "Unir hilo" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" "%02d: intervalo %d, actualizados %d, r_collisions %d, w_collisions %d\n" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "datos %02d: valor %d, %d actualizados\n" #: src/lib/bsock.c:97 #, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "No se pudo iniciar bsock mutex. ERR=%s\n" #: src/lib/bsock.c:139 #, fuzzy msgid "attr spool I/O error.\n" msgstr "Error fread attr spool I/O.\n" #: src/lib/bsock.c:276 #, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "Problema de autorización de Director en \"%s:%d\"\n" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" "Problema de autorización: El servidor remoto en \"%s:%d\" no anuncio soporte " "TLS requiere.\n" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" "Problema de autorización con el Director en \"%s:%d\": El servidor remoto " "requiere TLS.\n" #: src/lib/bsock.c:311 #, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "Fallo negociación TLS no con el Director en \"%s:%d\"\n" #: src/lib/bsock.c:321 #, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "" "Mala respuesta al comando Hello: ERR=%s\n" "El director en \"%s:%d\" probablemente no esta corriendo.\n" #: src/lib/bsock.c:330 #, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "Director en \"%s:%d\" rechazó comando Hello\n" #: src/lib/bsock.c:341 #, fuzzy, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" "Problema de autorización con el Director en \"%s:%d\"\n" "Lo mas probable es que las contraseñas no están de acuerdo.\n" "Si está usando TLS, puede haber habido un error de validación de " "certificados durante la negociación TLS.\n" "Por favor, consulte http://doc.bareos.org/master/html/bareos-manual-main-" "reference.html#AuthorizationErrors para ayuda.\n" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" "No se pudo conectar a %s en %s:%d. ERR=%s\n" "Reintentando ...\n" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "No se puede conectar a %s en %s:%d. ERR=%s\n" #: src/lib/bsock_tcp.c:186 #, fuzzy, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "fallo gethostbyname() para la maquina \"%s\": ERR=%s\n" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "Error al abrir socket. proto=%d puerto=%d. ERR=%s\n" #: src/lib/bsock_tcp.c:269 #, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "Error al enlazar dirección de origen. proto=%d. ERR=%s\n" #: src/lib/bsock_tcp.c:292 #, fuzzy, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "No se puede establecer SO_KEEPIDLE en el socket: %s\n" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "Error de escritura enviando %d bytes para %s:%s:%d: ERR=%s\n" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "Escribió %d bytes para %s:%s:%d, pero solo %d aceptado.\n" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "Esperaba leer %d obtuvo %d desde %s:%s:%d\n" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "Tamaño de paquete muy grande de \"%s:%s:%d. Conexión de terminación.\n" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "Error de lectura desde %s:%s:%d: ERR=%s\n" #: src/lib/bsock_tcp.c:632 msgid "Could not malloc BSOCK data buffer\n" msgstr "No se pudo malloc datos BSOCK buffer.\n" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "error de sockopt: %s\n" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "Alerta, búfer de red=%d bytes no tamaño máximo.\n" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "error F_GETFL fcntl. ERR=%s\n" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "error F_SETFL fcntl. ERR=%s\n" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "Error de escritura en cola de atributo. ERR=%s\n" #: src/lib/devlock.c:322 #, fuzzy msgid "writeunlock called too many times.\n" msgstr "rwl_writeunlock llamado muchas veces.\n" #: src/lib/devlock.c:327 #, fuzzy msgid "writeunlock by non-owner.\n" msgstr "rwl_writeunlock por no-propietario.\n" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Error archivo Bootstrap: %s\n" " : Linea %d, columna %d del archivo %s\n" "%s\n" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, fuzzy, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Error archivo Bootstrap: %s\n" " : Linea %d, columna %d del archivo %s\n" "%s\n" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "No se puede abrir el archivo bootstrap %s: %s\n" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "MediaType %s en BSR en el lugar inadecuado.\n" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "Dispositivo %s en BSR en el lugar inadecuado.\n" #: src/lib/parse_bsr.c:542 #, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "error de compilación REGEX '%s'. ERR=%s\n" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "JobType aún no se han implementado\n" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "JobLevel aún no se han implementado\n" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "Ranura %d en BSR en el lugar inadecuado.\n" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "VolFile : %u-%u\n" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "VolBlock : %u-%u\n" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "VolAddr : %llu-%llu\n" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "FileIndex : %u\n" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "FileIndex : %u-%u\n" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "JobId : %u\n" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "JobId : %u-%u\n" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "SessId : %u\n" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "SessId : %u-%u\n" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "VolumeName : %s\n" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "MediaType : %s\n" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "Dispositivo : %s\n" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "Ranura : %d\n" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "Cliente : %s\n" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "Job : %s\n" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "SessTime : %u\n" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "BSR is NULL\n" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "Siguiente : 0x%x\n" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "Root bsr : 0x%x\n" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "contado : %u\n" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "encontrado : %u\n" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "realizado : %s\n" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "posicionamiento : %d\n" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "fast_reject : %d\n" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "No se puede fork para convertirse en demonio: ERR =%s\n" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "1999 Fallo de Autorización.\n" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "stop_btimer llamado con NULL btimer_id\n" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "No se puede inicializar recurso de bloqueo. ERR=%s\n" #: src/lib/parse_conf.c:149 msgid "Config filename too long.\n" msgstr "Nombre de archivo de configuración muy largo.\n" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "No se pudo abrir archivo de configuración \"%s\": %s\n" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" "Actualmente no podemos manejar archivos de origen UTF-16 . Por favor, " "convierta el archivo de configuración a UTF-8\n" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "esperaba un nombre de identificación de Recurso, obtuvo: %s" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "esperaba un nombre de recurso, obtuvo: %s" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "no en la definición de recurso: %s" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" "Palabra clave \"%s\" no permitida en este recurso.\n" "Tal vez a la izquierda de la llave de los recursos anteriores." #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "Nombre no especificado para el recurso" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "símbolo %d no soporte %s en la definición de los recursos" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "Estado del Analizador %d desconocido\n" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "Fin de archivo de configuración alcanzado con recursos sin cerrar." #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "MemPool índice %d mayor que máximo %d\n" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "Fuera de memoria solicitando %d bytes\n" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "obuf es NULL\n" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "Ninguno" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "Zlib error" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "Zlib error de stream" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "Zlib error de datos" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "Zlib error de memoria" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "Zlib error de buffer" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "Zlib error de version" #: src/lib/compression.c:88 #, fuzzy msgid "GZIP compression not supported on this platform\n" msgstr "flujo %s no suportado en este Cliente.\n" #: src/lib/compression.c:91 #, fuzzy msgid "LZO2 compression not supported on this platform\n" msgstr "flujo %s no suportado en este Cliente.\n" #: src/lib/compression.c:94 #, fuzzy msgid "LZFZ compression not supported on this platform\n" msgstr "flujo %s no suportado en este Cliente.\n" #: src/lib/compression.c:97 #, fuzzy msgid "LZ4 compression not supported on this platform\n" msgstr "flujo %s no suportado en este Cliente.\n" #: src/lib/compression.c:100 #, fuzzy msgid "LZ4HC compression not supported on this platform\n" msgstr "flujo %s no suportado en este Cliente.\n" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 #, fuzzy msgid "Failed to initialize ZLIB compression\n" msgstr "Fallo al inicializar el contexto de cifrado.\n" #: src/lib/compression.c:215 #, fuzzy msgid "Failed to initialize LZO compression\n" msgstr "Fallo al inicializar el contexto de cifrado.\n" #: src/lib/compression.c:270 #, fuzzy msgid "Failed to initialize FASTLZ compression\n" msgstr "Fallo al inicializar el contexto de cifrado.\n" #: src/lib/compression.c:300 #, fuzzy msgid "LZO init failed\n" msgstr "Negociación TLS fallida\n" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "Error de compresión Deflate: %d\n" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "Error de compresión DeflateReset: %d\n" #: src/lib/compression.c:371 #, fuzzy, c-format msgid "Compression LZO error: %d\n" msgstr "Error de compresión Deflate: %d\n" #: src/lib/compression.c:402 #, fuzzy, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "Error de compresión Deflate: %d\n" #: src/lib/compression.c:413 #, fuzzy, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "Error de compresión DeflateReset: %d\n" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "Error de descompresión en el archivo %s. ERR=%s\n" #: src/lib/compression.c:592 #, fuzzy, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "Error de descompresión en el archivo %s. ERR=%s\n" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 #, fuzzy msgid "Compressed data stream found, but compression not configured!\n" msgstr "Flujo de datos GZIP encontrado, pero GZIP no está configurado!\n" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" "Error con el certificado en profundidad: %d, emisor=%s, asunto=%s, ERR=%d:%" "s\n" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "Error inicializando contexto SSL" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "Error al cargar los almacenes de verificación del certificado" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" "Un certificado de archivo o un directorio debe especificarse como un " "almacenes de verificación\n" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 #, fuzzy msgid "Error loading revocation list file" msgstr "Error cargando archivos de certificados" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "Error cargando archivos de certificados" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "Error cargando llaves privadas" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "No se puede abrir el archivo de parámetros de DH" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" "No es posible cargar los parámetros de DH desde el archivo especificado" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "No se pudo establecer parámetros TLS de Diffie-Hellman" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" "Error configurando lista de cipher, no hay ciphers válidos disponibles\n" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "Par ha fallado al presentar un certificado TLS\n" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "Par %s ha fallado al presentar un certificado TLS\n" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "Error al crear archivo descriptor basado en BIO" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "Error creando nuevo objeto SSL" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "Fallo al conectar" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "Error de apagado TLS." #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "Error de lectura/escritura TLS." #: src/lib/util.c:211 msgid "Running" msgstr "Ejecutando" #: src/lib/util.c:214 msgid "Blocked" msgstr "Bloqueado" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "Error Fatal" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "No Fatal Error" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "Cancelado" #: src/lib/util.c:238 msgid "Verify differences" msgstr "Verificar diferencias" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "Esperando al FD" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "Espere al SD" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "Espere por un nuevo Volumen" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "Esperando por montaje" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "Esperando al recurso Storage" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "Esperando al recurso Job" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "Esperando al recurso Cliente" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "Esperando el máximo Jobs" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "Esperando a Hora de Inicio" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "Esperando por prioridad" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "Estado de terminación de Job desconocido=%d" #: src/lib/util.c:302 msgid "Completed successfully" msgstr "Se ha completado con éxito" #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "Completado con advertencias" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "Terminado con errores" #: src/lib/util.c:311 msgid "Fatal error" msgstr "Error fatal" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "Creado, aún no se ejecuta" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "Cancelada por el usuario" #: src/lib/util.c:320 msgid "Verify found differences" msgstr "Verificar diferencias encontradas" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "Esperando por demonio File" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "Esperando por demonio Storage" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "Esperando por trabajos de mayor prioridad" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "Insertando registros de archivo en lote" #: src/lib/util.c:369 msgid "Differences" msgstr "Diferencias" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "Código del término desconocido" #: src/lib/util.c:391 msgid "Migrated Job" msgstr "Jod de Migración" #: src/lib/util.c:394 msgid "Verify" msgstr "Verificar" #: src/lib/util.c:397 msgid "Restore" msgstr "Restaurar" #: src/lib/util.c:400 msgid "Console" msgstr "Consola" #: src/lib/util.c:403 msgid "System or Console" msgstr "Sistema o Consola" #: src/lib/util.c:406 msgid "Admin" msgstr "Admin" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "Archivo" #: src/lib/util.c:412 msgid "Job Copy" msgstr "Job de Copia" #: src/lib/util.c:415 msgid "Copy" msgstr "Copiar" #: src/lib/util.c:418 msgid "Migrate" msgstr "Migrar" #: src/lib/util.c:421 msgid "Scan" msgstr "Escanear" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "Tipo Desconocido" #: src/lib/util.c:435 msgid "Truncate" msgstr "Truncar" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "Verificar Catálogo Inicial" #: src/lib/util.c:479 msgid "Verify Data" msgstr "Verificar Datos" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "Virtual completa" #: src/lib/util.c:498 msgid "Append" msgstr "Añadir" #: src/lib/util.c:500 msgid "Disabled" msgstr "Inhabilitado" #: src/lib/util.c:502 msgid "Used" msgstr "Usado" #: src/lib/util.c:503 msgid "Cleaning" msgstr "Limpieza" #: src/lib/util.c:504 msgid "Purged" msgstr "Purga" #: src/lib/util.c:505 msgid "Recycle" msgstr "Reciclar" #: src/lib/util.c:506 msgid "Read-Only" msgstr "Sólo-Lectura" #: src/lib/util.c:518 msgid "Invalid volume status" msgstr "Invalido estado de volumen" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "Directorio de trabajo no definido. No se puede continuar.\n" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "Directorio de Trabajo: \"%s\" no encontrado. No se puede continuar.\n" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" "Directorio de Trabajo: \"%s\" no es un directorio. No se puede continuar.\n" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "Número de la señal no válida" #: src/lib/signal.c:152 src/lib/signal.c:154 #, fuzzy, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "Bareos interrumpido por señal %d: %s\n" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "Kaboom! %s, %s obtuvo la señal %d - %s. Intentando rastreo.\n" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "Kaboom! exepath=%s\n" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "Fork error: ERR=%s\n" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "Llamando: %s %s %s %s\n" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "execv: %s ha fallado: ERR=%s\n" #: src/lib/signal.c:247 #, fuzzy, c-format msgid "It looks like the traceback worked...\n" msgstr "Parece que el rastreo trabaja ...\n" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "BA_NSIG demasiado pequeño (%d) debe ser (%d)\n" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "SEÑAL DESCONOCIDA" #: src/lib/signal.c:323 msgid "Hangup" msgstr "Colgar" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "Interrumpir" #: src/lib/signal.c:325 msgid "Quit" msgstr "Salir" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "Instrucción ilegal" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "Trace/Trampa de Punto de Interrupción" #: src/lib/signal.c:328 msgid "Abort" msgstr "Anular" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "Instrucción EMT (Emulación de Trampa)" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "trampa IOT" #: src/lib/signal.c:335 msgid "BUS error" msgstr "BUS error" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "Excepción de punto flotante" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "Matar, imbloqueable" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "Señal 1 definida por el usuario" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "Violación de segmento" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "Señal definida por el usuario 2" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "Tuberí­a rota" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "Alarma" #: src/lib/signal.c:343 msgid "Termination" msgstr "Terminación" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "Error de pila" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "El estado de hijo ha cambiado" #: src/lib/signal.c:348 msgid "Continue" msgstr "Continue" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "Detener, imbloqueable" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "Teclado detenido" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "Leer en segundo plan desde tty" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "Escribir en segundo plan al tty" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "Condición de urgencia en el socket" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "Limite de CPU superado" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "Superado el límite de tamaño de archivo" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "Despertador virtual" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "Perfiles de alarma" #: src/lib/signal.c:358 msgid "Window size change" msgstr "Cambiar el tamaño de la ventana" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "I/O posible ahora" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "Fallo reiniciar energía" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "LWP no ejecutable" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "La señal especial SIGLWP utilizado por la biblioteca del hilo" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "Checkpoint de Congelación" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "Checkpoint de Thaw" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "Cancelación de Hilo" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "Recurso Perdido (por ejemplo, registro de bloqueo perdido)" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "Estado OK\n" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "bget_msg: señal desconocida %d\n" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "Fuera de memoria\n" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "Demasiada memoria utilizada." #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "Intento para liberar NULL llamado desde %s:%d\n" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "doble libre desde %s:%d\n" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "qp->qnext->qprev != qp llamado desde %s:%d\n" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "qp->qprev->qnext != qp llamado desde %s:%d\n" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "sm_realloc tamaño: %d\n" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" "\n" "Buffers huérfanos existen. Volcado terminado tras el\n" "descubrimiento de malos vínculos en la cadena de buffers huérfanos.\n" " Dirección del buffer con enlaces malos: %p\n" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "Búfer dañado encontrado. Llamado desde %s:%d\n" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" "\n" "Búfers dañado encontrado en %s:%d\n" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "descubrimiento de un malo vínculo anterior.\n" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "descubrimiento del siguiente malo enlace malo.\n" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "descubrimiento de datos de rebosamiento.\n" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "Puntero NULL.\n" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "Dirección de buffer : %p\n" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "Búfer dañados: %6u bytes asignados en la línea %d de %s %s\n" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, fuzzy, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "No se pudo abrir %s: ERR=%s\n" #: src/lib/scsi_lli.c:92 #, fuzzy, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "No se puede escribir última en %s: ERR=%s\n" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, fuzzy, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "No se puede establecer eotmodel en el dispositivo %s: ERR=%s\n" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, fuzzy, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/lib/scsi_lli.c:314 #, fuzzy, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/lib/scsi_lli.c:323 #, fuzzy, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "No se ha podido asignar un nuevo objeto keypair.\n" #: src/lib/scsi_lli.c:348 #, fuzzy, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "No se puede abrir el dispositivo %s: ERR=%s\n" #: src/lib/scsi_lli.c:464 #, fuzzy, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "No se puede establecer eotmodel en el dispositivo %s: ERR=%s\n" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 #, fuzzy msgid "Program killed by BAREOS (timeout)\n" msgstr "Programa finalizado(killed) por Bareos (timeout) \n" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "Error bloqueando Mutex. ERR=%s\n" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "Error desbloqueando Mutex. ERR=%s\n" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "pthread_create fallido: ERR=%s\n" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "No se puede abrir el archivo de certificado" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "No es posible leer el archivo de certificado" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "No se puede extraer la clave pública del certificado" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" "Certificado suministrado no incluye la extensión subjectKeyIdentifier " "necesaria." #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "Tipo de clave prevista no soportada: %d\n" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "No se puede abrir archivo de clave privada" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "No se puede leer la clave privada del archivo" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "Tipo Digest no soportado: %d\n" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "Fallo al inicializar resume OpenSSL" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "Fallo al actualizar resume OpenSSL" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "Fallo al finalizar resume OpenSSL" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "fallo digest_new OpenSSL" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "Fallo OpenSSL al obtener firma digest " #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "Fallo OpenSSL Verificación final digest " #: src/lib/crypto_openssl.c:749 msgid "No signers found for crypto verify.\n" msgstr "Firmantes no encontrados para verificar el cifrado.\n" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "Fallo en creación de firma" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "Fallo en decodificación de firma" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "Tipo de cifrado especificados no soportado\n" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "decodificación CryptoData fallida" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "Error al descifrar la clave de sesión" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "ContentEncryptionAlgorithm no soportado: %d\n" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "Fallo al inicializar contexto cipher OpenSSl" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "Cifrado de sesión suministro una clave simétrica inválida" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "Cifrado de sesión suministro una IV inválida" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "Fallido inicialización de contexto OpenSSL de cifrado de clave/IV " #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "No se puede inicializar hilo OpenSSL: ERR=%s\n" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "Fallo al seed OpenSSL PRNG\n" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "Fallo al guardar OpenSSL PRNG\n" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "No se puede destruir mutex: ERR=%s\n" #: src/lib/crypto_openssl.c:1615 #, fuzzy, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "No se puede destruir mutex: ERR=%s\n" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" "Tamaño de datos o flujo de %s no es correcto. Original %s, restaurado %s\n" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "Longitud no válida de Buscador de Información (obtuvo %d, no 32)\n" #: src/filed/restore.c:132 #, c-format msgid "Could not set Finder Info on %s\n" msgstr "No se pudo establecer Finder Info en %s\n" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "Error analizando registro de cabecera: %s\n" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "Error de registro de datos. ERR=%s\n" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "Tamaño actual de los datos %d no igual a cabecera %d\n" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "Inesperado flujo de datos de sesión criptográfica.\n" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" "Ninguna claves privadas de descifrado se ha definido para descifrar los " "datos cifrados de las copia de seguridad.\n" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "No es posible crear sumario.\n" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" "Falta la clave privada requerida para descifrar los datos del respaldo " "cifrado.\n" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "Fallo al descifrar la clave de sesión.\n" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" "Se produjo un error al descodificar flujo de datos de sesión encriptados: %" "s\n" #: src/filed/restore.c:861 #, c-format msgid "Cannot open resource fork for %s.\n" msgstr "No se puede abrir recursos fork para %s.\n" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "Inesperado signatura de datos de sesión criptográfica.\n" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "No se ha podido descifrar la firma del mensaje para %s\n" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "Detectado %ld errores de acl mientras que hace restaurar\n" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "Detectado %ld errores de xattr al hacer restauración\n" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" "%d incompatible flujos de datos y %d incompatible atributos de flujos " "ignorados.\n" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "%d incompatible flujo de recurso fork ignorado.\n" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "%d incompatible flujo Finder Info ignorado.\n" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "%d incompatible flujo de acl ignorado.\n" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "%d incompatible flujo de cifrado ignorado.\n" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "ignorado %d no soportado flujo xattr.\n" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "Error de escritura en Bloque de Descomposición Win32 en %s: %s\n" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "Error lógico: el archivo de salida debe estar abierto\n" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "Error lógica: archivo de salida no debe estar abierto\n" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "No se pudo leer búfer de red malloc %d\n" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "No es posible acceder %s: ERR=%s\n" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr " No es posible seguir el enlace %s: ERR=%s\n" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "No se pudo stat %s: ERR=%s\n" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "Archivo sin modificar omitido: %s\n" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "Archivo Archive omitido: %s\n" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "Recursión apagado. Directorio omitido: %s\n" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "Prohibido el cambio de sistema de archivos. Directorio omitido: %s\n" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "No se pudo abrir el directorio %s: ERR=%s\n" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "Tipo de archivo desconocido %d: %s\n" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "Error de red en enviar al Director: ERR=%s\n" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "Inicialización de %s Digest ha fallado\n" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "No se puede abrir %s: ERR=%s.\n" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "No se puede abrir recursos fork para %s: ERR=%s.\n" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "Error leyendo archivo %s: ERR=%s\n" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, fuzzy, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "Comando plugin \"%s\" regresó malo paquete startBackupFile.\n" #: src/filed/fd_plugins.c:633 #, fuzzy, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "Comando plugin \"%s\" regresó malo paquete startBackupFile.\n" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, fuzzy, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "Comando plugin \"%s\" regresó malo paquete startBackupFile.\n" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "Plugin guardar paquetes no encontrado.\n" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "Plugin=%s no encontrado.\n" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "Fallo llamada plugin createFile. Stat=%d archivo=%s\n" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "Fallo llamada plugin createFile. Retorno CF_ERROR archivo=%s\n" #: src/filed/fd_plugins.c:2378 #, fuzzy msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "Comando plugin \"%s\" regresó malo paquete startBackupFile.\n" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "Comando Storage no publicado antes de Verificar.\n" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "Error escaneando registro de cabecera: %s\n" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "A ocurrido un error al cifrar el stream.\n" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "Falta la firma criptográfica para %s\n" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "Validación de la firma fallida para el archivo %s: ERR=%s\n" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "Digest de un archivo fallido para el archivo: %s\n" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "Validación de la firma fallida para %s: %s\n" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "Error de descifrado. buf_len=%d decrypt_len=%d en el archivo %s\n" #: src/filed/crypto.c:401 #, fuzzy msgid "Encrypting sparse or offset data not supported.\n" msgstr "Cifrado de datos dispersos no soportado.\n" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "Fallo al inicializar el contexto de cifrado.\n" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "Falta cifrado de flujo de datos de sesión para %s\n" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "Fallo al inicializar el contexto de descifrado para %s\n" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "Error de cifrado\n" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "Error de descifrado\n" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "2001 Job %s marcado para ser cancelado.\n" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "2902 Error escaneando comando cancelar.\n" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "2991 Comando setdebug malo: %s\n" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "2992 Malo comando estimación.\n" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "Malo comando estimate: %s" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "Malo Comando Job: %s" #: src/filed/dir_cmd.c:870 #, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "Malo comando RunBeforeJob: %s\n" #: src/filed/dir_cmd.c:933 #, c-format msgid "Bad RunAfter command: %s\n" msgstr "Malo comando RunAfter: %s\n" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "Malo comando RunScript: %s\n" #: src/filed/dir_cmd.c:1015 #, fuzzy, c-format msgid "Bad Plugin Options command: %s\n" msgstr "Malo comando RunScript: %s\n" #: src/filed/dir_cmd.c:1066 #, fuzzy, c-format msgid "Bad RestoreObject command: %s\n" msgstr "Malo comando storage: %s" #: src/filed/dir_cmd.c:1166 #, fuzzy msgid "2909 Bad RestoreObject command.\n" msgstr "2905 Malo comando RunBeforeJob.\n" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" "Relojes de DIR y FD difieren por %lld segundos, FD compensando " "automáticamente.\n" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "Nivel de copia de seguridad desconocido: %s\n" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "Malo comando nivel: %s\n" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "Malo comando sesión: %s" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "Malo comando storage: %s" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "No puede contactar demonio Storage\n" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "Mala respuesta para añadir abierto: %s\n" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "Mala respuesta desde almacén para comando abrir\n" #: src/filed/dir_cmd.c:1691 #, fuzzy, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "Generar instantáneas(snapshots) VSS. Driver=\"%s\", Drive(s)=\"%s\"\n" #: src/filed/dir_cmd.c:1696 #, fuzzy, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "Fallo al generar VSS snapshots.\n" #: src/filed/dir_cmd.c:1708 #, fuzzy, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "Fallo al generar VSS snapshots.\n" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "VSS Writer (PrepareForBackup): %s\n" #: src/filed/dir_cmd.c:1723 #, fuzzy msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" "No encuentra las letras de unidad para la generación de instantáneas" "(snapshots) VSS.\n" #: src/filed/dir_cmd.c:1728 #, fuzzy, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" "VSS no se inicializo correctamente. Suporte VSS está desactivado. ERR=%s\n" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "Añadir Cierre con SD fallido.\n" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "Mal estado %d regresado desde demonio Storage.\n" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "2994 Malo comando verificar: %s\n" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "2994 Malo nivel de verificar: %s\n" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "Comando replace malo. CMD=%s\n" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "Mala regexp where. where=%s\n" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" "VSS no se inicializo correctamente. Suporte VSS está desactivado. ERR=%s\n" #: src/filed/dir_cmd.c:2085 #, fuzzy, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "VSS Writer (BackupComplete): %s\n" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "Secuencia de llamada impropia.\n" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "Mala respuesta para SD leer abrir: %s\n" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "Mala respuesta desde storage para comando leer abir\n" #: src/filed/filed_conf.c:520 #, fuzzy, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "Esperaba una opción de reemplazo de Restauración, obtuvo: %s" #: src/filed/filed.c:61 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version: %s (%s)\n" "\n" "Utilice: bareos-fd [-f -s] [-c archivo_de_configuración] [-d " "nivel_depuración]\n" " -c establecer archivo de configuración para archivo \n" " -d establecer el nivel de depuración para \n" " -dt imprimir timestamp en salida de depuración\n" " -f ejecutar en primer plano (para depuración)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m imprimir salida kaboom para depuración)\n" " -s sin señales(para depuración)\n" " -t prueba - leer la configuración y salir\n" " -u userid\n" " -v mensajes de usuario detallados\n" " -? imprimir este mensaje.\n" "\n" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "la opción -k no tiene sentido sin la opción -u.\n" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" "Ninguno recurso File Daemon definido en %s\n" "Sin eso yo no sé quién soy :-(\n" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "Sólo un recurso de cliente permitido en %s\n" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" "Ninguno \"Certificado TLS de CA\" o \"Directorio de Certificado TLS de CA\" " "están definidos para el demonio File en %s.\n" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "Cifrado o Firma PKI habilitado, pero no compilado en Bareos.\n" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" "\"Par de Claves PKI\" debe estar definido para el demonio File \"%s\" en %s, " "si uno o otro \"Firma PKI\" o \"Cifrar PKI\" están habilitados.\n" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "No se ha podido asignar un nuevo objeto keypair.\n" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "Fallo al cargar certificado publico para File Daemon \"%s\" en %s.\n" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "Fallo al cargar llave privada para File Daemon \"%s\" en %s.\n" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" "Fallo al cargar llave privada desde el archivo %s para File Daemon \"%s\" en " "%s.\n" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" "Fallo al cargar certificado del firmante desde el archivo %s para File " "Daemon \"%s\" en %s.\n" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" "Fallo al cargar certificado de llave maestro desde el archivo %s para File " "Daemon \"%s\" en %s.\n" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "Recurso Director no definido en %s\n" #: src/filed/accurate_lmdb.c:64 #, fuzzy, c-format msgid "Unable to create MDB environment: %s\n" msgstr "No se puede truncar el dispositivo %s. ERR=%s\n" #: src/filed/accurate_lmdb.c:81 #, fuzzy, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "No se pudo establecer modos del archivo %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:90 #, fuzzy, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "No se pudo establecer modos del archivo %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:97 #, fuzzy, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "No se puede abrir la base de datos=%s. ERR=%s\n" #: src/filed/accurate_lmdb.c:103 #, fuzzy, c-format msgid "Unable to start a write transaction: %s\n" msgstr "No se puede escribir en %s\n" #: src/filed/accurate_lmdb.c:109 #, fuzzy, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "No se puede abrir la base de datos=%s. ERR=%s\n" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, fuzzy, c-format msgid "Unable insert new data: %s\n" msgstr "No se puede escribir en %s\n" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, fuzzy, c-format msgid "Unable close write transaction: %s\n" msgstr "No se puede escribir en %s\n" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, fuzzy, c-format msgid "Unable to create write transaction: %s\n" msgstr "No se puede escribir en %s\n" #: src/filed/accurate_lmdb.c:249 #, fuzzy, c-format msgid "Unable to create read transaction: %s\n" msgstr "No se puede crear hilo. ERR=%s\n" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, fuzzy, c-format msgid "Unable to renew read transaction: %s\n" msgstr "No se puede escribir en %s\n" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, fuzzy, c-format msgid "Unable create cursor: %s\n" msgstr "No se puede escribir en %s\n" #: src/filed/status.c:87 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "Demonio iniciado %s, %d Job ejecutando desde el inicio.\n" #: src/filed/status.c:149 #, fuzzy, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d\n" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "Director conectado en: %s\n" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "JobId %d Job %s se está ejecutando.\n" #: src/filed/status.c:188 #, fuzzy, c-format msgid " %s%s %s Job started: %s\n" msgstr " %s%s Job iniciado: %s\n" #: src/filed/status.c:201 #, fuzzy, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr "Archivos=%s Bytes=%s Bytes/sec=%s Errores=%d\n" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "Archivos examinados=%s\n" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "Procesando archivo: %s\n" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "SDSocket cerrado.\n" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "====\n" #: src/filed/status.c:300 #, fuzzy msgid " SDSocket=closed\n" msgstr "SDSocket cerrado.\n" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "Comando .status malo: %s\n" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "2900 Malo comando .status, falta argumento.\n" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "2900 Malo comando .status, malo argumento.\n" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "Bareos Cliente: Inactivo" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "Bareos Cliente: Funcionando" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "Bareos Cliente: Ultimo Job Cancelado" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "Bareos Cliente: Ultimo Job Fallido" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "Bareos Cliente: Ultimo Job con Advertencias" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "Yo sólo autentifico directores, no %d\n" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "Conexión desde Director %s desconocido en %s rechazada.\n" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "Contraseña incorrecta dada por el Director en %s.\n" #: src/filed/authenticate.c:301 #, fuzzy, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "Conexión desde Director %s desconocido en %s rechazada.\n" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, fuzzy, c-format msgid "Cannot verify checksum for %s\n" msgstr "No se puede encontrar el recurso Schedule %s\n" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "2991 Malo comando accurate\n" #: src/filed/fileset.c:86 #, fuzzy, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "Directorio de Plugin no definido. No se puede usar plug-in: \"%\"\n" #: src/filed/fileset.c:128 #, fuzzy, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "Error al ejecutar el programa: %s. stat=%d: ERR=%s\n" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "No se puede abrir archivo de entrada FileSet: %s. ERR=%s\n" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "Error de compilación REGEX %s. ERR=%s\n" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "Comando FilseSet invalido: %s\n" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "No puede establecer el tamaño del búfer FD-> SD.\n" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "Detectado %ld errores de acl al hacer copia de seguridad\n" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "Detectado %ld errores de xattr al hacer copia de seguridad\n" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "No se puede abrir recurso fork para \"%s\": ERR=%s.\n" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "Fallo la inicialización de la firma digest %s\n" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "No se pudo asignar memoria para la firma de cifrado.\n" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "Se produjo un error al firmar el stream.\n" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "Se produjo un error concluir la firma del stream.\n" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "Recursión desactivado. No descenderá de %s dentro de %s\n" #: src/filed/backup.c:553 #, fuzzy, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" "%s es un sistema de ficheros diferentes. No descenderá de %s dentro de %s\n" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "Sistema de Archivos no permitido. No descenderá de %s en %s\n" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "Tipo de unidad no permitido. No descenderá en %s\n" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "Archivo de Socket omitido: %s\n" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "No se pudo acceder a \"%s\": ERR=%s\n" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "No se pudo seguir el enlace \"%s\": ERR=%s\n" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "No se pudo stat \"%s\": ERR=%s\n" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "Archivo no guardado: %s\n" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "No se puede abrir directorio \"%s\": ERR=%s.\n" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr " Tipo de archivo %d desconocido; no ha sido guardado: %s\n" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "No se puede abrir \"%s\": ERR=%s.\n" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "Error de lectura en el archivo %s. ERR=%s\n" #: src/filed/backup.c:1219 #, fuzzy, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "Demasiados errores.\n" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "Error de relleno de cifrado\n" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "Invalidas banderas de archivo, tipo de flujo de datos no soportado.\n" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "VSS Writer (BackupComplete): %s\n" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "Fallo ASSERT: %s\n" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "Monitor: nombre=%s FDtimeout=%s SDtimeout=%s\n" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "Director: nombre=%s dirección=%s FDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "Cliente: nombre=%s dirección=%s FDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "Storage: nombre=%s dirección=%s SDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "ConsoleFont: nombre=%s font face=%s\n" #: src/qt-tray-monitor/authenticate.cpp:79 #, fuzzy, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" "Director problema de autorización.\n" "Lo mas probable es que las contraseñas no están de acuerdo.\n" "Por favor, consulte http://doc.bareos.org/master/html/bareos-manual-main-" "reference.html#AuthorizationErrors para ayuda.\n" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "mala respuesta al comando Hello: ERR=%s\n" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "Director rechazo comando Hello\n" #: src/qt-tray-monitor/authenticate.cpp:139 #, fuzzy msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "Nombres o contraseñas en el Director o Storage no son las mismas.\n" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "Escrito por Nicolas Boichat (2004)\n" "\n" "Versión: %s (%s) %s %s %s\n" "\n" "Utilice: tray-monitor [-c archivo_configuración] [-d nivel_depuración]\n" " -c establece archivo de configuración para archivo\n" " -d establece nivel de depuración para \n" " -dt imprime timestamp en salida de depuración\n" " -t prueba - leer configuración y salir\n" " -? imprimir este mensaje.\n" "\n" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "Conectado" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "Procesando comando ..." #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versión: %s (%s) %s %s %s\n" "\n" "Utilice: bat [-s] [-c archivo_de_configuración] [-d nivel_depuración " "[archivo_de_configuración]\n" " -c establecer archivo de configuración para el archivo\n" " -dnn establecer el nivel de depuración a nn\n" " -s no hay señales\n" " -t prueba - leer la configuración y salir\n" " -? imprimir este mensaje.\n" "\n" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "Console: nombre=%s\n" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "Ya conectado\"%s\".\n" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "Conectando con Director %s:%d" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" "Conectando con Director %s:%d\n" "\n" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "Inicializando ..." #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "Comando completado ..." #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "En prompt principal esperando por una entrada..." #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "En prompt esperando por una entrada..." #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "Comando fallido." #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "Director desconectado." #~ msgid "sm_realloc %d at %p from %s:%d\n" #~ msgstr "sm_realloc %d en %p desde %s:%d\n" #, fuzzy #~ msgid "@exec error: ERR=%s\n" #~ msgstr "Seek error: ERR=%s\n" #~ msgid "3911 JobId=%u failed reserve drive %s.\n" #~ msgstr "3911 JobId=%u fallo al reservar unidad %s.\n" #, fuzzy #~ msgid "Unable to load any shared library for .\n" #~ msgstr "No se puede abrir archivo %s: ERR=%s\n" #, fuzzy #~ msgid "Run FullPool override\n" #~ msgstr "Anular Ejecutar FullPool " #, fuzzy #~ msgid "Job FullPool override\n" #~ msgstr "Anular Job FullPool" #, fuzzy #~ msgid "Run IncPool override\n" #~ msgstr "Anular Ejecutar IncPoll" #, fuzzy #~ msgid "Job IncPool override\n" #~ msgstr "Anular Job IncPoll" #, fuzzy #~ msgid "Run DiffPool override\n" #~ msgstr "Anular Ejecutar DiffPool" #, fuzzy #~ msgid "Job DiffPool override\n" #~ msgstr "Anular Job DiffPool" #~ msgid "SHA1Update() returned an error: %d\n" #~ msgstr "SHA1Update() retorno un error: %d\n" #, fuzzy #~ msgid "Expected a Console Authentication Type keyword, got: %s" #~ msgstr "Espera una palabra clave Tipo Job de Migración, obtuvo: %s" #~ msgid "Device record %s already exists\n" #~ msgstr "Registro de Dispositivo %s ya existe\n" #~ msgid "Device %s cannot BSF because it is not a tape.\n" #~ msgstr "Dispositivo %s no puede BSF, porque no es una cinta.\n" #~ msgid "TLS negotiation failed\n" #~ msgstr "Negociación TLS fallida\n" #, fuzzy #~ msgid "" #~ "Director authorization problem.\n" #~ "Most likely the passwords do not agree.\n" #~ "If you are using TLS, there may have been a certificate validation error " #~ "during the TLS handshake.\n" #~ "Please see " #~ msgstr "" #~ "Problema de Autorización de Director.\n" #~ "El más probable es que las contraseñas no están de acuerdo.\n" #~ "Si usted esta utilizando TLS, puede haber habido un error de validación " #~ "de certificado durante el apretón de manos TLS.\n" #~ "Por favor, consulte http://doc.bareos.org/master/html/bareos-manual-main-" #~ "reference.html#AuthorizationErrors para ayuda.\n" #, fuzzy #~ msgid "" #~ "Provides file backup and restore services. BAREOS -- Backup Archiving " #~ "REcovery Open Sourced" #~ msgstr "" #~ "Proporciona servicios de copia de seguridad y restauración. Bareos - la " #~ "solución de copia de seguridad de red." #~ msgid "Prune expired records from catalog" #~ msgstr "Prunar registros expirados del catálogo" #~ msgid "Loaded plugin: %s\n" #~ msgstr "Cargado el plugin: %s\n" #~ msgid "Plugin Options not yet implemented.\n" #~ msgstr "Opciones de Plugin todavía no se ha implementado.\n" #~ msgid "Using Device \"%s\"\n" #~ msgstr "Usando Dispositivo \"%s\"\n" #~ msgid "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n" #~ msgstr "Director: nombre=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n" #~ msgid " query_file=%s\n" #~ msgstr "query_file=%s\n" #~ msgid " --> " #~ msgstr "--> " #~ msgid "Console: name=%s SSL=%d\n" #~ msgstr "Console: nombre=%s SSL=%d\n" #~ msgid "Counter: name=%s min=%d max=%d cur=%d wrapcntr=%s\n" #~ msgstr "Counter: nombre=%s mínimo=%d máximo=%d cur=%d wrapcntr=%s\n" #~ msgid "Counter: name=%s min=%d max=%d\n" #~ msgstr "Counter: nombre=%s mínimo=%d máximo=%d\n" #, fuzzy #~ msgid "" #~ "Client: name=%s protocol=%d authtype=%d address=%s FDport=%d MaxJobs=%u\n" #~ msgstr "Cliente: nombre=%s dirección=%s FDport=%d MaxJobs=%u\n" #, fuzzy #~ msgid "" #~ " JobRetention=%s FileRetention=%s AutoPrune=%d SoftQuota=%s " #~ "SoftQuotaGrace=%s HardQuota=%s StrictQuotas=%d\n" #~ msgstr "JobRetention=%s FileRetention=%s AutoPrune=%d\n" #~ msgid "" #~ "Device: name=%s ok=%d num_writers=%d max_writers=%d\n" #~ " reserved=%d open=%d append=%d read=%d labeled=%d offline=%d " #~ "autochgr=%d\n" #~ " poolid=%s volname=%s MediaType=%s\n" #~ msgstr "" #~ "Device: nombre=%s ok=%d num_writers=%d max_writers=%d\n" #~ " reservado=%d abierto=%d append=%d leer=%d etiquetado=%d offline=%d " #~ "autochgr=%d\n" #~ " poolid=%s volname=%s MediaType=%s\n" #, fuzzy #~ msgid "" #~ "Storage: name=%s protocol=%d authtype=%d address=%s SDport=%d MaxJobs=%u\n" #~ " DeviceName=%s MediaType=%s PairedStorage=%s StorageId=%s\n" #~ msgstr "" #~ "Storage: nombre=%s dirección=%s SDport=%d MaxJobs=%u\n" #~ " DeviceName=%s MediaType=%s StorageId=%s\n" #~ msgid "" #~ "Catalog: name=%s address=%s DBport=%d db_name=%s\n" #~ " db_driver=%s db_user=%s MutliDBConn=%d\n" #~ msgstr "" #~ "Catálogo: nombre=%s dirección=%s DBport=%d db_nombre=%s\n" #~ " db_driver=%s db_user=%s MutliDBConn=%d\n" #, fuzzy #~ msgid "%s: name=%s JobType=%d protocol=%d level=%s Priority=%d Enabled=%d\n" #~ msgstr "%s: nombre=%s JobType=%d nivel=%s Prioridad=%d Activo=%d\n" #~ msgid "JobDefs" #~ msgstr "JobDefs" #, fuzzy #~ msgid " MaxJobs=%u Resched=%d Times=%d Interval=%s Spool=%d\n" #~ msgstr "" #~ "MaxJobs=%u Resched=%d Times=%d Intervalo=%s Spool=%d WritePartAfterJob=%" #~ "d\n" #~ msgid " SpoolSize=%s\n" #~ msgstr "SpoolSize=%s\n" #~ msgid " Accurate=%d\n" #~ msgstr "Preciso=%d\n" #~ msgid " SelectionType=%d\n" #~ msgstr "SelectionType=%d\n" #~ msgid " --> Where=%s\n" #~ msgstr "--> Donde=%s\n" #~ msgid " --> RegexWhere=%s\n" #~ msgstr "--> RegexDonde=%s\n" #~ msgid " --> Bootstrap=%s\n" #~ msgstr "--> Bootstrap=%s\n" #~ msgid " --> WriteBootstrap=%s\n" #~ msgstr "--> WriteBootstrap=%s\n" #~ msgid " --> PluginOptions=%s\n" #~ msgstr "--> PluginOptions=%s\n" #~ msgid " --> MaxRunTime=%u\n" #~ msgstr "--> MaxRunTime=%u\n" #~ msgid " --> MaxWaitTime=%u\n" #~ msgstr "--> MaxWaitTime=%u\n" #~ msgid " --> MaxStartDelay=%u\n" #~ msgstr "--> MaxStartDelay=%u\n" #, fuzzy #~ msgid " --> MaxRunSchedTime=%u\n" #~ msgstr "--> MaxRunTime=%u\n" #, fuzzy #~ msgid " --> Base %s\n" #~ msgstr "--> Objetivo=%s\n" #~ msgid " --> Run=%s\n" #~ msgstr "--> Ejecutar=%s\n" #~ msgid " --> SelectionPattern=%s\n" #~ msgstr "--> SeleccionPatron=%s\n" #~ msgid "FileSet: name=%s\n" #~ msgstr "FileSet: nombre=%s\n" #~ msgid "Schedule: name=%s\n" #~ msgstr "Schedule: nombre=%s\n" #~ msgid " --> Run Level=%s\n" #~ msgstr "--> Ejecutar Nivel=%s\n" #~ msgid " hour=" #~ msgstr "hora=" #~ msgid " mday=" #~ msgstr "mdia=" #~ msgid " month=" #~ msgstr "mes=" #~ msgid " wday=" #~ msgstr "wdia=" #~ msgid " wom=" #~ msgstr "wom=" #~ msgid " woy=" #~ msgstr "woy=" #~ msgid " mins=%d\n" #~ msgstr "mins=%d\n" #~ msgid " --> " #~ msgstr "--> " #~ msgid "Pool: name=%s PoolType=%s\n" #~ msgstr "Pool: nombre=%s PoolType=%s\n" #~ msgid " use_cat=%d use_once=%d cat_files=%d\n" #~ msgstr "use_cat=%d use_once=%d cat_files=%d\n" #~ msgid " max_vols=%d auto_prune=%d VolRetention=%s\n" #~ msgstr "max_vols=%d auto_prune=%d VolRetention=%s\n" #~ msgid " VolUse=%s recycle=%d LabelFormat=%s\n" #~ msgstr "VolUse=%s recycle=%d LabelFormat=%s\n" #~ msgid " CleaningPrefix=%s LabelType=%d\n" #~ msgstr "CleaningPrefix=%s LabelType=%d\n" #~ msgid " RecyleOldest=%d PurgeOldest=%d ActionOnPurge=%d\n" #~ msgstr "RecyleOldest=%d PurgeOldest=%d ActionOnPurge=%d\n" #~ msgid " MaxVolJobs=%d MaxVolFiles=%d MaxVolBytes=%s\n" #~ msgstr "MaxVolJobs=%d MaxVolFiles=%d MaxVolBytes=%s\n" #~ msgid " MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #~ msgstr "MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #, fuzzy #~ msgid " JobRetention=%s FileRetention=%s\n" #~ msgstr "JobRetention=%s FileRetention=%s AutoPrune=%d\n" #~ msgid " NextPool=%s\n" #~ msgstr "NextPool=%s\n" #~ msgid " RecyclePool=%s\n" #~ msgstr "RecyclePool=%s\n" #~ msgid " ScratchPool=%s\n" #~ msgstr "ScratchPool=%s\n" #~ msgid " Catalog=%s\n" #~ msgstr "Catálogo=%s\n" #~ msgid "Messages: name=%s\n" #~ msgstr "Mensajes: nombre=%s\n" #~ msgid " mailcmd=%s\n" #~ msgstr "mailcmd=%s\n" #~ msgid " opcmd=%s\n" #~ msgstr "opcmd=%s\n" #~ msgid "2905 Bad RunScript command.\n" #~ msgstr "2905 Malo comando RunScript.\n" #~ msgid "ACL support not configured for your machine.\n" #~ msgstr "Soporte ACL no configurado para su máquina. \n" #~ msgid "XATTR support not configured for your machine.\n" #~ msgstr "Soporte XATTR no está configurado para su máquina.\n" #~ msgid "Config token too long, file: %s, line %d, begins at line %d\n" #~ msgstr "" #~ "Configuración de señal demasiado largo, archivo: %s, línea %d, se inicia " #~ "en la línea %d\n" #~ msgid "Could not create client BSOCK.\n" #~ msgstr "No es posible crear cliente BSOCK. \n" #~ msgid "TLS negotiation failed with FD at \"%s:%d\"\n" #~ msgstr "Fallida la negociación TLS con FD en \"%s:%d\"\n" #~ msgid "Uncompression error. ERR=%d\n" #~ msgstr "Error de descompresión. ERR=%d\n" #, fuzzy #~ msgid "LZO uncompression error. ERR=%d\n" #~ msgstr "Error de descompresión. ERR=%d\n" #~ msgid "3991 Bad setdebug command: %s\n" #~ msgstr "3991 Malo comando setdebug: %s\n" #~ msgid "Network send error to FD. ERR=%s\n" #~ msgstr "Error de red al enviar a FD. ERR=%s\n" #~ msgid "" #~ "====\n" #~ "\n" #~ msgstr "" #~ "====\n" #~ "\n" #~ msgid " Drive %d status unknown.\n" #~ msgstr "Unidad %d estado desconocido.\n" #~ msgid "3900 Bad .status command, missing argument.\n" #~ msgstr "3900 Malo comando .status, falta argumentos.\n" #~ msgid "3900 Bad .status command, wrong argument.\n" #~ msgstr "3900 Malo comando .status, argumentos incorrectos.\n" #~ msgid "" #~ "No Client, Storage or Director resource defined in %s\n" #~ "Without that I don't how to get status from the File, Storage or Director " #~ "Daemon :-(\n" #~ msgstr "" #~ "Ningún recurso Cliente, Storage o Director definido en %s\n" #~ "Sin esto, Yo no se como obtener el estado de los demonios File, Storage o " #~ "Director :-(\n" #~ msgid "" #~ "Invalid refresh interval defined in %s\n" #~ "This value must be greater or equal to 1 second and less or equal to 10 " #~ "minutes (read value: %d).\n" #~ msgstr "" #~ "Invalido intervalo de actualización definido en %s\n" #~ "Este valor debe ser mayor o igual a 1 segundo y menor o igual a 10 " #~ "minutos (leer el valor:% d).\n" #~ msgid "Director daemon" #~ msgstr "Servicio Director" #~ msgid "Connecting to Client %s:%d" #~ msgstr "Conectando con Cliente %s:%d" #~ msgid "Connecting to Storage %s:%d" #~ msgstr "Conectando con Storage %s:%d" #~ msgid "Error, currentitem is not a Client, a Storage or a Director..\n" #~ msgstr "Error, currentitem no es un cliente, un Storage o un Director..\n" #~ msgid "Cannot connect to daemon." #~ msgstr "No se puede conectar al demonio" #~ msgid "Authentication error : %s" #~ msgstr "Error de autenticación : %s" #~ msgid "Opened connection with Director daemon." #~ msgstr "Conexión abierta con demonio Director." #~ msgid "Opened connection with File daemon." #~ msgstr "Conexión abierta con demonio File." #~ msgid "Opened connection with Storage daemon." #~ msgstr "Conexión abierta con demonio Storage." #~ msgid "Error : BNET_HARDEOF or BNET_ERROR" #~ msgstr "Error: BNET_HARDEOF o BNET_ERROR" #~ msgid "Error : Connection closed." #~ msgstr "Error : Conexión cerrada." #~ msgid "Enter autochanger drive[0]: " #~ msgstr "Introduzca unidad Autochanger [0]:" #~ msgid "Bareos " #~ msgstr "Bareos" #~ msgid "Python control commands" #~ msgstr "Comandos de control de Python" #~ msgid "Python interpreter restarted.\n" #~ msgstr "Interprete Python reiniciado.\n" #~ msgid "Expected one of: %s, got: %s" #~ msgstr "Esperaba uno de: %s, obtuvo: %s" #, fuzzy #~ msgid "" #~ "%s %s %s (%s):\n" #~ " Build OS: %s %s %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Backup Level: %s%s\n" #~ " Client: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pool: \"%s\" (From %s)\n" #~ " Catalog: \"%s\" (From %s)\n" #~ " Storage: \"%s\" (From %s)\n" #~ " Scheduled time: %s\n" #~ " Start time: %s\n" #~ " End time: %s\n" #~ " Elapsed time: %s\n" #~ " Priority: %d\n" #~ " FD Files Written: %s\n" #~ " SD Files Written: %s\n" #~ " FD Bytes Written: %s (%sB)\n" #~ " SD Bytes Written: %s (%sB)\n" #~ " Rate: %.1f KB/s\n" #~ " Software Compression: %s\n" #~ "%s VSS: %s\n" #~ " Encryption: %s\n" #~ " Accurate: %s\n" #~ " Volume name(s): %s\n" #~ " Volume Session Id: %d\n" #~ " Volume Session Time: %d\n" #~ " Last Volume Bytes: %s (%sB)\n" #~ " Non-fatal FD errors: %d\n" #~ " SD Errors: %d\n" #~ " FD termination status: %s\n" #~ " SD termination status: %s\n" #~ " Termination: %s\n" #~ "\n" #~ msgstr "" #~ "%s %s %s (%s): %s\n" #~ " Build OS: %s %s %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Nivel de Respaldo: %s%s\n" #~ " Cliente: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pool: \"%s\" (Desde %s)\n" #~ " Catalogo: \"%s\" (Desde %s)\n" #~ " Storage: \"%s\" (Desde %s)\n" #~ " Hora programada: %s\n" #~ " Hora de inicio: %s\n" #~ " Hora de finalización: %s\n" #~ " Tiempo transcurrido: %s\n" #~ " Prioridad: %d\n" #~ " FD Archivos Escritos: %s\n" #~ " SD Archivos Escritos: %s\n" #~ " FD Bytes Escritos: %s (%sB)\n" #~ " SD Bytes Escritos: %s (%sB)\n" #~ " Tasa: %.1f KB/s\n" #~ " Software Compresión: %s\n" #~ " VSS: %s\n" #~ " Cifrado: %s\n" #~ " Accurate: %s\n" #~ " Nombre del Volumen(es): %s\n" #~ " Id de Sesión del Volumen: %d\n" #~ " Tiempo de Sesión del Volumen: %d\n" #~ " Ultimo Volumen Bytes: %s (%sB)\n" #~ " No-fatal FD errores: %d\n" #~ " SD Errores: %d\n" #~ " Estado de terminación FD: %s\n" #~ " Estado de terminación SD: %s\n" #~ " Terminación: %s\n" #~ "\n" #~ msgid "Job pointer not found." #~ msgstr "No se encuentra el puntero del Job." #~ msgid "Pool record not found." #~ msgstr "Registro Pool no encontrado" #~ msgid "Attribute %s not found." #~ msgstr "Atributo %s no encontrado." #~ msgid "Read-only attribute" #~ msgstr "Atributo Solo-Lectura" #~ msgid "Priority must be 1-100" #~ msgstr "Prioridad debe ser 1-100" #~ msgid "Job Level can be set only during JobInit" #~ msgstr "Nivel de Job sólo se puede ajustar durante JobInit" #~ msgid "Bad JobLevel string" #~ msgstr "Mala cadena JobLevel" #~ msgid "" #~ "Written by Nicolas Boichat (2004)\n" #~ "\n" #~ "Version: %s (%s) %s %s %s\n" #~ "\n" #~ "Usage: tray-monitor [-c config_file] [-d debug_level]\n" #~ " -c set configuration file to file\n" #~ " -d set debug level to \n" #~ " -dt print timestamp in debug output\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ "Escrito por Nicolas Boichat (2004)\n" #~ "\n" #~ "Versión: %s (%s) %s %s %s\n" #~ "\n" #~ "Utilice: tray-monitor [-c archivo_configuración] [-d nivel_depuración]\n" #~ " -c establece archivo de configuración para archivo\n" #~ " -d establece nivel de depuración para \n" #~ " -dt imprime timestamp en salida de depuración\n" #~ " -t prueba - leer configuración y salir\n" #~ " -? imprimir este mensaje.\n" #~ "\n" #~ msgid "Bareos daemon status monitor" #~ msgstr "Monitor de Estado del demonio Bareos" #~ msgid "Open status window..." #~ msgstr "Abrir la ventana de estado..." #~ msgid "Exit" #~ msgstr "Salir" #~ msgid "Bareos tray monitor" #~ msgstr "Bareos tray monitor" #~ msgid " (DIR)" #~ msgstr "(DIR)" #~ msgid " (FD)" #~ msgstr "(FD)" #~ msgid " (SD)" #~ msgstr "(SD)" #~ msgid "Refresh interval in seconds: " #~ msgstr "Intervalo de actualización en segundos:" #~ msgid "Refresh now" #~ msgstr "Actualizar Ahora" #~ msgid "About" #~ msgstr "Sobre" #~ msgid "Close" #~ msgstr "Cerrar" #~ msgid "Disconnecting from Director %s:%d\n" #~ msgstr "Desconectando del Director %s:%d\n" #~ msgid "Disconnecting from Client %s:%d\n" #~ msgstr "Desconectando del Cliente %s:%d\n" #~ msgid "Disconnecting from Storage %s:%d\n" #~ msgstr "Desconectando del Almacenamiento %s:%d\n" #~ msgid "Bareos Tray Monitor" #~ msgstr "Bareos Tray Monitor" #~ msgid "Written by Nicolas Boichat\n" #~ msgstr "Escrito por Nicolás Boichat\n" #~ msgid "Version" #~ msgstr "Version" #~ msgid "" #~ "Current job: %s\n" #~ "Last job: %s" #~ msgstr "" #~ "Job actual: %s\n" #~ "Ultimo job: %s" #~ msgid " (%d errors)" #~ msgstr "(%d errores)" #~ msgid " (%d error)" #~ msgstr "(%d error)" #~ msgid "No current job." #~ msgstr "Ningún trabajo actual." #~ msgid "No last job." #~ msgstr "Ningún ultimo trabajo." #~ msgid "Job status: Created" #~ msgstr "Estado del trabajo: Creado" #~ msgid "Job status: Running" #~ msgstr "Estado del trabajo: Ejecutando" #~ msgid "Job status: Blocked" #~ msgstr "Estado del trabajo: Bloqueado" #~ msgid "Job status: Terminated" #~ msgstr "Estado del trabajo: Terminado" #~ msgid "Job status: Terminated in error" #~ msgstr "Estado del trabajo: Terminado con error" #~ msgid "Job status: Error" #~ msgstr "Estado del trabajo: Error" #~ msgid "Job status: Fatal error" #~ msgstr "Estado del trabajo: Fatal error" #~ msgid "Job status: Verify differences" #~ msgstr "Estado del Job: Verificar las diferencias" #~ msgid "Job status: Canceled" #~ msgstr "Estado del Job: Cancelado" #~ msgid "Job status: Waiting on File daemon" #~ msgstr "Estado del Job: Esperando en demonio File" #~ msgid "Job status: Waiting on the Storage daemon" #~ msgstr "Estado del Job: Esperando en demonio Storage" #~ msgid "Job status: Waiting for new media" #~ msgstr "Estado del Job: Esperando por nuevo medio" #~ msgid "Job status: Waiting for Mount" #~ msgstr "Estado del Job: Esperando por montar" #~ msgid "Job status: Waiting for storage resource" #~ msgstr "Estado del Job: Esperando por recurso storage" #~ msgid "Job status: Waiting for job resource" #~ msgstr "Estado del Job: Esperando por recurso job" #~ msgid "Job status: Waiting for Client resource" #~ msgstr "Estado del Job: Esperando por recurso Cliente" #~ msgid "Job status: Waiting for maximum jobs" #~ msgstr "Estado del Job: Esperando por jobs máximos " #~ msgid "Job status: Waiting for start time" #~ msgstr "Estado del Job: Esperando por hora de inicio " #~ msgid "Job status: Waiting for higher priority jobs to finish" #~ msgstr "Estado del Job: Esperando por jobs de prioridad mayor por finalizar" #~ msgid "Unknown job status %c." #~ msgstr "Estado del job desconocido %c." #~ msgid "Bad scan : '%s' %d\n" #~ msgstr "Mala análisis: '%s' %d\n" #~ msgid "Connecting to Client %s:%d\n" #~ msgstr "Conectando con Cliente %s:%d\n" #~ msgid "Connecting to Storage %s:%d\n" #~ msgstr "Conectando con Storage %s:%d\n" #~ msgid "Cannot connect to daemon.\n" #~ msgstr "No se puede conectar al demonio.\n" #~ msgid "Opened connection with Director daemon.\n" #~ msgstr "Conexión abierta con demonio Director.\n" #~ msgid "Opened connection with File daemon.\n" #~ msgstr "Conexión abierta con demonio File.\n" #~ msgid "Opened connection with Storage daemon.\n" #~ msgstr "Conexión abierta con demonio Storage.\n" #, fuzzy #~ msgid "<< Error: BNET_SUB_PROMPT signal received. >>\n" #~ msgstr "<< Error: BNET_PROMPT señal recibida. >>\n" #~ msgid "<< Heartbeat signal received, answered. >>\n" #~ msgstr "<< Heartbeat señal recibida, respondió. >>\n" #~ msgid "<< Unexpected signal received : %s >>\n" #~ msgstr "<< Inesperada señal recibida: %s >>\n" #~ msgid "\n" #~ msgstr "\n" #~ msgid "\n" #~ msgstr "\n" #~ msgid "part" #~ msgstr "parte" #~ msgid "file" #~ msgstr "archivo" #~ msgid "End of %s %u on device %s, Volume \"%s\"\n" #~ msgstr "Fin de %s %u en dispositivo %s, Volumen \"%s\"\n" #~ msgid "No FreeSpace command defined.\n" #~ msgstr "Comando FreeSpace no definido.\n" #~ msgid "Cannot run free space command. Results=%s ERR=%s\n" #~ msgstr "" #~ "No se puede ejecutar comando de espacio libre. Resultados=%s ERR=%s\n" #~ msgid "Error writing part %d to the DVD: ERR=%s\n" #~ msgstr "Error escribiendo parte %d en el DVD: ERR=%s\n" #~ msgid "Error while writing current part to the DVD: %s" #~ msgstr "Error al escribir parte actual al DVD: %s" #~ msgid "Part %d (%lld bytes) written to DVD.\n" #~ msgstr "Parte %d (%lld bytes) escrito al DVD.\n" #~ msgid "Remaining free space %s on %s\n" #~ msgstr "Espacio libre restante %s en %s\n" #~ msgid "Next Volume part already exists on DVD. Cannot continue: %s\n" #~ msgstr "" #~ "Siguiente parte del volumen ya existe en DVD. No se puede continuar: %s\n" #~ msgid "" #~ "Error writing. Current part less than total number of parts (%d/%d, " #~ "device=%s)\n" #~ msgstr "" #~ "Error al escribir. Parte actual menor que número total de partes (%d/%d, " #~ "dispositivo=%s)\n" #~ msgid "Ready to append to end of Volume \"%s\" part=%d size=%s\n" #~ msgstr "Listo para anexar al final del Volumen \"%s\" parte=%d tamaño=%s\n" #~ msgid "" #~ "Bareos cannot write on DVD Volume \"%s\" because: The sizes do not match! " #~ "Volume=%s Catalog=%s\n" #~ msgstr "" #~ "Bareos no puedo escribir en el volumen DVD \"%s\" porque: Los tamaños no " #~ "coinciden! Volumen=%s Catálogo=%s\n" #~ msgid "Cannot delete attribute %s" #~ msgstr "No se puedo eliminar atributo %s" #~ msgid "Cannot find attribute %s" #~ msgstr "No se puedo encontrar atributo %s" #~ msgid "Error in ParseTuple\n" #~ msgstr "Error en ParseTuple\n" #~ msgid "Parse tuple error in job_write\n" #~ msgstr "Error de análisis de tupla en job_write\n" #~ msgid "Error in Python method %s\n" #~ msgstr "Error en el método Python %s\n" #~ msgid "btape does not work with DVD storage.\n" #~ msgstr "btape no funciona con el almacenamiento de DVD.\n" #~ msgid "" #~ "Error writing final part to DVD. This Volume may not be readable.\n" #~ "%s" #~ msgstr "" #~ "Error al escribir la parte final a DVD. Este volumen puede no ser " #~ "legible.\n" #~ "%s" #~ msgid "" #~ "Error while writing, current part number is less than the total number of " #~ "parts (%d/%d, device=%s)\n" #~ msgstr "" #~ "Error al escribir, número de parte actual es menor que el número total de " #~ "partes (%d/%d, dispositivo=%s)\n" #~ msgid "Unable to open device next part %s: ERR=%s\n" #~ msgstr "No se puede abrir próxima parte %s del dispositivo: ERR=%s\n" #~ msgid "" #~ "End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, " #~ "free_space_errno=%d, errmsg=%s).\n" #~ msgstr "" #~ "Fin de Volumen \"%s\" en %u:%u en el dispositivo %s (part_size=%s, " #~ "free_space=%s, free_space_errno=%d, errmsg=%s).\n" #~ msgid "" #~ "End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, " #~ "free_space_errno=%d).\n" #~ msgstr "" #~ "Fin de Volumen \"%s\" en %u:%u en el dispositivo %s (part_size=%s, " #~ "free_space=%s, free_space_errno=%d).\n" #~ msgid "Unable to open device part=%d %s: ERR=%s\n" #~ msgstr "No se puede abrir el dispositivo parte =%d %s: ERR=%s\n" #~ msgid "Could not initialize Python\n" #~ msgstr "No se pudo inicializar Python\n" #~ msgid "Could not Run Python string %s\n" #~ msgstr "No se pudo ejecutar Python cadena %s\n" #~ msgid "Could not initialize Python Job type.\n" #~ msgstr "No se pudo inicializar Job tipo Python.\n" #~ msgid "Could not import Python script %s/%s. Python disabled.\n" #~ msgstr "No se puede importar script Python %s/%s. Python deshabilitado.\n" #~ msgid "Could not create Python Job Object.\n" #~ msgstr "No es posible crear objeto Job Python.\n" #~ msgid "Python function \"%s\" not found.\n" #~ msgstr "Python función \"%s\" no encontrada.\n" #~ msgid "Unknown Python daemon event %s\n" #~ msgstr "Demonio Python evento %s desconocido\n" #~ msgid "Unable to initialize the Python lock. ERR=%s\n" #~ msgstr "No se puede inicializar el bloqueo de Python. ERR=%s\n" #~ msgid "Bad response to Hello command: ERR=" #~ msgstr "mala respuesta al comando Hello: ERR =" #~ msgid "Open File Manager paused\n" #~ msgstr "Administrador Open File pausado\n" #~ msgid "FAILED to pause Open File Manager\n" #~ msgstr "Fallo al pausar Administrador Open File\n" #~ msgid "Running as '%s'. Privmask=%#08x\n" #~ msgstr "Ejecutando como '%s'. Privmask=%#08x\n" #~ msgid "Failed to retrieve current UserName\n" #~ msgstr "Fallo al recuperar UserName actual\n" #~ msgid "2905 Bad RunBeforeJob command.\n" #~ msgstr "2905 Malo comando RunBeforeJob.\n" #~ msgid "2905 Bad RunBeforeNow command.\n" #~ msgstr "2905 Malo comando RunBeforeNow.\n" #~ msgid "2905 Bad RunAfterJob command.\n" #~ msgstr "2905 Malo comando RunAfterJob.\n" #~ msgid "# Bareos bwx-console Configuration File\n" #~ msgstr "# Bareos bwx-console Archivo de Configuración\n" #~ msgid "Save and close" #~ msgstr "Guardar y cerrar" #~ msgid "Close without saving" #~ msgstr "Cerrar sin guardar" #~ msgid "Error while saving" #~ msgstr "Error al guardar" #~ msgid "Enter restore mode" #~ msgstr "Introduzca el modo de restauración" #~ msgid "Cancel restore" #~ msgstr "Cancelar restauración" #~ msgid "Remove" #~ msgstr "Eliminar" #~ msgid "Refresh" #~ msgstr "Actualizar" #~ msgid "M" #~ msgstr "M" #~ msgid "Filename" #~ msgstr "Nombre de Archivo" #~ msgid "Size" #~ msgstr "Tamaño" #~ msgid "Perm." #~ msgstr "Permiso" #~ msgid "User" #~ msgstr "Usuario" #~ msgid "Group" #~ msgstr "Grupo" #~ msgid "Job Name" #~ msgstr "Nombre del Job" #~ msgid "Before" #~ msgstr "Antes de" #~ msgid "Please configure parameters concerning files to restore :" #~ msgstr "" #~ "Por favor, configure los parámetros relativos a los archivos a restaurar:" #~ msgid "always" #~ msgstr "siempre" #~ msgid "if newer" #~ msgstr "si los nuevos" #~ msgid "if older" #~ msgstr "si los viejos" #~ msgid "never" #~ msgstr "nunca" #~ msgid "Please configure parameters concerning files restoration :" #~ msgstr "" #~ "Por favor, configure los parámetros relativos a los archivos de " #~ "restauración" #~ msgid "Getting parameters list." #~ msgstr "Obteniendo los parámetros de la lista." #~ msgid "Error : no clients returned by the director." #~ msgstr "Error: el director no devolvió ningún cliente" #~ msgid "Error : no filesets returned by the director." #~ msgstr "Error: el director no devolvió ningún fileset" #~ msgid "Error : no storage returned by the director." #~ msgstr "Error: el director no devolvió ningún storage" #~ msgid "Error : no jobs returned by the director." #~ msgstr "Error: no hay Jobs devuelto por el director." #~ msgid "RestoreFiles" #~ msgstr "RestoreFiles" #~ msgid "Please configure your restore parameters." #~ msgstr "Por favor, configure los parámetros de restauración." #~ msgid "Please select a client." #~ msgstr "Por favor seleccione un cliente." #~ msgid "Please select a restore date." #~ msgstr "Por favor seleccione una fecha de restauración." #~ msgid "Building restore tree..." #~ msgstr "Construyendo árbol de restauración..." #~ msgid "Error while starting restore: " #~ msgstr "Error al iniciar restauración:" #~ msgid "" #~ "Right click on a file or on a directory, or double-click on its mark to " #~ "add it to the restore list." #~ msgstr "" #~ "Haga clic derecho sobre un archivo o un directorio, o haga doble clic en " #~ "su marca para añadirlo a la lista de restauración." #~ msgid "Unexpected question has been received.\n" #~ msgstr "Pregunta inesperada ha sido recibida.\n" #~ msgid "bwx-console: unexpected restore question." #~ msgstr "bwx-console: inesperada consulta de restauración." #~ msgid " files selected to be restored." #~ msgstr "archivos seleccionados para ser restaurado." #~ msgid " file selected to be restored." #~ msgstr "archivo seleccionado para ser restaurado." #~ msgid "Please configure your restore (%ld files selected to be restored)..." #~ msgstr "" #~ "Por favor, configure su restauración (%ld archivos seleccionados para ser " #~ "restaurado)..." #~ msgid "Restore failed : no file selected.\n" #~ msgstr "Restauración fallida: ningún archivo seleccionado.\n" #~ msgid "Restore failed : no file selected." #~ msgstr "Restauración fallida: ningún archivo seleccionado." #~ msgid "Restoring, please wait..." #~ msgstr "Restaurando, por favor espere..." #~ msgid "Job queued. JobId=" #~ msgstr "Cola de Job. JobId=" #~ msgid "Restore queued, jobid=" #~ msgstr "Cola de Restauración, JobID =" #~ msgid "Job failed." #~ msgstr "Job fallido." #~ msgid "Restore failed, please look at messages.\n" #~ msgstr "Fallo en restauración, por favor, mirar los mensajes.\n" #~ msgid "Restore failed, please look at messages in console." #~ msgstr "Fallo en restauración, por favor, mirar los mensajes en la consola." #~ msgid "Failed to retrieve jobid.\n" #~ msgstr "No se ha podido recuperar jobId.\n" #~ msgid "" #~ "Restore is scheduled to run. bwx-console will not wait for its " #~ "completion.\n" #~ msgstr "" #~ "Restaurar está programado para ejecutarse. bwx-consola no esperara a su " #~ "conclusión.\n" #~ msgid "" #~ "Restore is scheduled to run. bwx-console will not wait for its completion." #~ msgstr "" #~ "Restaurar está programado para ejecutarse. bwx-consola no esperara a su " #~ "conclusión." #~ msgid "Restore job created, but not yet running." #~ msgstr "Job de restauración creado, pero aún no se ejecuta." #~ msgid "Restore job running, please wait (%ld of %ld files restored)..." #~ msgstr "" #~ "Job de restauración en ejecución, por favor espere (%ld de %ld archivos " #~ "restaurados) ..." #~ msgid "Restore job terminated successfully." #~ msgstr "Trabajo de restauración terminado correctamente." #~ msgid "Restore job terminated successfully.\n" #~ msgstr "Trabajo de restauración terminado correctamente.\n" #~ msgid "Restore job terminated in error, see messages in console." #~ msgstr "" #~ "Trabajo de restauración terminado con error, ver los mensajes en la " #~ "consola." #~ msgid "Restore job terminated in error, see messages.\n" #~ msgstr "Trabajo de restauración terminado con error, ver los mensajes.\n" #~ msgid "Restore job reported a non-fatal error." #~ msgstr "Trabajo de restauración no reporto error fatal." #~ msgid "Restore job reported a fatal error." #~ msgstr "Trabajo de restauración reporto un error fatal." #~ msgid "Restore job cancelled by user." #~ msgstr "Trabajo de restauración cancelado por el usuario." #~ msgid "Restore job cancelled by user.\n" #~ msgstr "Trabajo de restauración cancelado por el usuario.\n" #~ msgid "Restore job is waiting on File daemon." #~ msgstr "Trabajo de restauración esta esperando demonio File." #~ msgid "Restore job is waiting for new media." #~ msgstr "Trabajo de restauración esta esperando por un nuevo medio." #~ msgid "Restore job is waiting for storage resource." #~ msgstr "" #~ "Trabajo de restauración esta esperando por recurso de almacenamiento." #~ msgid "Restore job is waiting for job resource." #~ msgstr "Job de restauración está esperando por recurso job." #~ msgid "Restore job is waiting for Client resource." #~ msgstr "Trabajo de restauración esta esperando por recurso de Cliente." #~ msgid "Restore job is waiting for maximum jobs." #~ msgstr "Trabajo de restauración esta esperando por trabajo máximo." #~ msgid "Restore job is waiting for start time." #~ msgstr "Trabajo de restauración esta esperando por hora de inicio." #~ msgid "Restore job is waiting for higher priority jobs to finish." #~ msgstr "" #~ "Job de restauración está esperando por jobs de mayor prioridad para " #~ "finalizar." #~ msgid "" #~ "The restore job has not been started within one minute, bwx-console will " #~ "not wait for its completion anymore.\n" #~ msgstr "" #~ "El Job de restauración no se ha iniciado en el plazo de un minuto, bwx-" #~ "console no va a esperar para su realización más.\n" #~ msgid "" #~ "The restore job has not been started within one minute, bwx-console will " #~ "not wait for its completion anymore." #~ msgstr "" #~ "El Job de restauración no se ha iniciado en el plazo de un minuto, bwx-" #~ "console no va a esperar para su realización más." #~ msgid "Restore done successfully.\n" #~ msgstr "Restauración finalizada con suceso.\n" #~ msgid "Restore done successfully." #~ msgstr "Restauración finalizada con suceso." #~ msgid "Applying restore configuration changes..." #~ msgstr "Aplicando cambios de configuración de restauración..." #~ msgid "Failed to find the selected client." #~ msgstr "Fallo al encontrar el cliente seleccionado." #~ msgid "Failed to find the selected fileset." #~ msgstr "Fallo al encontrar el fileset seleccionado." #~ msgid "Failed to find the selected storage." #~ msgstr "Fallo al encontrar el almacenamiento seleccionado." #~ msgid "Run Restore job" #~ msgstr "Ejecutando Job de restauración" #~ msgid "Restore configuration changes were applied." #~ msgstr "Restaurar los cambios de configuración aplicados." #~ msgid "Restore cancelled.\n" #~ msgstr "Restauración cancelada.\n" #~ msgid "Restore cancelled." #~ msgstr "Restauración cancelada." #~ msgid "No results to list." #~ msgstr "No hay resultados para listar." #~ msgid "No backup found for this client." #~ msgstr "Respaldos no encontrados para este cliente." #~ msgid "ERROR" #~ msgstr "ERROR" #~ msgid "Query failed" #~ msgstr "Consulta fallida" #~ msgid "Cannot get previous backups list, see console." #~ msgstr "" #~ "No se puede obtener lista de copias de seguridad anteriores, ver la " #~ "consola." #~ msgid "JobName:" #~ msgstr "JobName:" #~ msgid "Bootstrap:" #~ msgstr "Bootstrap:" #~ msgid "Where:" #~ msgstr "Donde:" #~ msgid "Replace:" #~ msgstr "Reemplazar:" #~ msgid "ifnewer" #~ msgstr "ifnewer" #~ msgid "ifolder" #~ msgstr "ifolder" #~ msgid "FileSet:" #~ msgstr "FileSet:" #~ msgid "Client:" #~ msgstr "Cliente:" #~ msgid "Storage:" #~ msgstr "Storage:" #~ msgid "When:" #~ msgstr "Cuando:" #~ msgid "Priority:" #~ msgstr "Prioridad:" #~ msgid "Restoring..." #~ msgstr "Restaurando..." #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Director \"%s\" in config file.\n" #~ "At least one CA certificate store is required.\n" #~ msgstr "" #~ "Ni \"Certificado TLS CA \" o \"Directorio del Certificado TLS CA\" están " #~ "definidos para el Director \"%s\" en el archivo de configuración.\n" #~ "Por lo menos un almacén de certificados CA es necesario.\n" #~ msgid "" #~ "No Director resource defined in config file.\n" #~ "Without that I don't how to speak to the Director :-(\n" #~ msgstr "" #~ "Recurso Director no definido en el archivo de configuración.\n" #~ "Sin eso, yo no sé cómo hablar con el Director :-(\n" #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Console \"%s\" in config file.\n" #~ msgstr "" #~ "Ni \"Certificado TLS CA \" o \"Directorio del Certificado TLS CA\" están " #~ "definidos para la Consola \"%s\" en el archivo de configuración.\n" #~ msgid "Error while initializing windows sockets...\n" #~ msgstr "Error durante la inicialización de Windows Sockets ...\n" #~ msgid "Error while cleaning up windows sockets...\n" #~ msgstr "Error durante la limpieza de Windows Sockets ...\n" #~ msgid "Error while initializing library." #~ msgstr "Error al inicializar la librería." #~ msgid "Cryptographic library initialization failed.\n" #~ msgstr "Fallo en inicialización de la librería criptográfica.\n" #~ msgid "Please correct configuration file.\n" #~ msgstr "Por favor, corrija el archivo de configuración.\n" #~ msgid "Error : Library not initialized\n" #~ msgstr "Error: Librería no inicializada\n" #~ msgid "Error : No configuration file loaded\n" #~ msgstr "Error: No hay archivo de configuración cargado\n" #~ msgid "Connecting...\n" #~ msgstr "Conectando...\n" #~ msgid "Error : No director defined in config file.\n" #~ msgstr "Error: Director no definido en el archivo de configuración.\n" #~ msgid "Multiple directors found in your config file.\n" #~ msgstr "Varios directores encontrados en su archivo de configuración.\n" #~ msgid "Please choose a director (1-%d): " #~ msgstr "Por favor, elija un director (1-%d): " #~ msgid "Passphrase for Console \"%s\" TLS private key: " #~ msgstr "Frase de contraseña para Console \"%s\" TLS clave privada:" #~ msgid "Passphrase for Director \"%s\" TLS private key: " #~ msgstr "Frase de contraseña para Director \"%s\" TLS clave privada:" #~ msgid "Failed to connect to the director\n" #~ msgstr "Error al conectar con el director\n" #~ msgid "Connected\n" #~ msgstr "Conectado\n" #~ msgid "<< Unexpected signal received : " #~ msgstr "<\n" #~ "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n" #~ msgstr "" #~ "Bienvenido a Bareos bwx-console.\n" #~ "Escrito por Nicolas Boichat \n" #~ "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n" #~ msgid "About Bareos bwx-console" #~ msgstr "Acerca de Bareos bwx-console" #~ msgid "Please choose your default configuration file" #~ msgstr "Por favor, seleccione su archivo de configuración por defecto" #~ msgid "Use this configuration file as default?" #~ msgstr "Utilizar este archivo de configuración por defecto?" #~ msgid "Configuration file" #~ msgstr "Archivo de configuración" #~ msgid "Console thread terminated." #~ msgstr "Hilo de Consola terminado." #~ msgid "Connection to the director lost. Quit program?" #~ msgstr "Conexión perdida con el director. Salir del programa?" #~ msgid "Connection lost" #~ msgstr "Conexión perdida" #~ msgid "Connected to the director." #~ msgstr "Conectado al director." #~ msgid "Reconnect" #~ msgstr "Reconectar" #~ msgid "Reconnect to the director" #~ msgstr "Reconectar al director" #~ msgid "Disconnected of the director." #~ msgstr "Desconectado al director." #~ msgid "bwx-console: unexpected director's question." #~ msgstr "bwx-console: inesperada consulta del director." #~ msgid "Device switch. New device %s chosen.\n" #~ msgstr "Cambiar Dispositivo. Seleccione nuevo dispositivo %s.\n" #~ msgid "" #~ "Media Type not the same for all devices in changer %s. Cannot continue.\n" #~ msgstr "" #~ "Tipo de Media no es el mismo para todos los dispositivos en el cambiador %" #~ "s. No se puede continuar.\n" #~ msgid "Network buffer size %d not multiple of tape block size.\n" #~ msgstr "" #~ "Tamaño del buffer de red %d no múltiplo del tamaño de bloque de cinta.\n" #, fuzzy #~ msgid "Attempt to set StorageId to zero.\n" #~ msgstr "Intento de abrir sesión ya abierta.\n" #~ msgid "open_next_part can't unlink existing part %s, ERR=%s\n" #~ msgstr "open_next_part no se puede desvincular parte %s existente, ERR=%s\n" #~ msgid "Plugin load %s failed: ERR=%s\n" #~ msgstr "Fallo carga de Plugin %s: ERR=%s\n" #, fuzzy #~ msgid "VSS Writer (PreRestore): %s\n" #~ msgstr "VSS Writer (PrepareForBackup): %s\n" #~ msgid "" #~ "Authorization key rejected by Storage daemon.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Clave de autorización rechazada por demonio Storage.\n" #~ "Por favor, consulte http://www.bareos.org/en/rel-manual/" #~ "Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000 para ayuda.\n" #~ msgid "" #~ "Director and Storage daemon passwords or names not the same.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Contraseñas o nombres de los demonios Director y Storage no son los " #~ "mismos.\n" #~ " Por favor vea http://www.bareos.org/en/rel-manual/" #~ "Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000 para ayuda.\n" #~ msgid "" #~ "Director and File daemon passwords or names not the same.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Contraseñas o nombres de los demonios Director y File no son los mismos.\n" #~ " Por favor vea http://www.bareos.org/en/rel-manual/" #~ "Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000 para ayuda.\n" #~ msgid "Buffer overrun called from %s:%d\n" #~ msgstr "Desbordamiento de Buffer llamado desde %s:%d\n" #~ msgid "" #~ "Connection from unknown Director %s at %s rejected.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Conexión desde Director desconocido %s en %s rechazada.\n" #~ " Por favor vea http://www.bareos.org/en/rel-manual/" #~ "Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000 for help.\n" #~ msgid "" #~ "Incorrect password given by Director.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Contraseña incorrecta dada por el Director.\n" #~ " Por favor vea http://www.bareos.org/en/rel-manual/" #~ "Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000 for help.\n" #~ msgid "" #~ "Incorrect authorization key from File daemon at %s rejected.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Clave de autorización incorrecta desde el demonio File en %s rechazada.\n" #~ "Por favor, consulte http://www.bareos.org/en/rel-manual/" #~ "Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000 para ayuda.\n" #~ msgid "Record header file index %ld not equal record index %ld\n" #~ msgstr "" #~ "Archivo de registro de encabezado de índice %ld no es igual índice de " #~ "registro %ld\n" #~ msgid "" #~ "Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled " #~ "on this drive.\n" #~ msgstr "" #~ "Fallo al generar instantáneas(snapshots) VSS de la unidad \"%c:\\\". " #~ "Suporte VSS está deshabilitado en esta unidad.\n" #~ msgid "Malformed plugin command. Name not terminated by colon: %s\n" #~ msgstr "Comando plugin incorrecto. Nombre no terminado por dos puntos: %s\n" #~ msgid "Daemon started %s, %d Job%s run since started.\n" #~ msgstr "Demonio iniciado %s, %d Job%s ejecutados desde el inicio.\n" #~ msgid "A dbi driver for DBI must be supplied.\n" #~ msgstr "Un driver dbi para DBI debe ser suministrado.\n" #~ msgid "%s buffer: %s %6u bytes buf=%p allocated at %s:%d\n" #~ msgstr "%s buffer: %s %6u bytes buf=%p alocado en %s:%d\n" #~ msgid "Daemon started %s, 1 Job run since started.\n" #~ msgstr "Demonio iniciado %s, 1 Job ejecutando desde el inicio.\n" #~ msgid "Max sched run time exceeded. Job canceled.\n" #~ msgstr "" #~ "tiempo de ejecución máximo programado se ha superado. Job cancelado\n" #~ msgid "OSF1 Specific Default ACL attribs" #~ msgstr "Atributos ACL por defecto específicos de OSF1" #~ msgid "OSF1 Specific Access ACL attribs" #~ msgstr "Atributos ACL de acceso específicos de OSF1" #~ msgid "3000 Job %s marked to be canceled.\n" #~ msgstr "3000 Job %s marcados para ser cancelados.\n" #~ msgid "3905 Bizarre wait state %d\n" #~ msgstr "3905 Extraño estado de espera %d\n" #~ msgid "" #~ "Write part command must be defined for a device which requires mount.\n" #~ msgstr "" #~ "Comandos wirte part debe ser definido para un dispositivo que requiere " #~ "montaje.\n" #~ msgid "Could not open DVD device %s. No Volume name given.\n" #~ msgstr "" #~ "No se pudo abrir dispositivo de DVD %s. No hay nombre volumen " #~ "determinado.\n" #~ msgid "" #~ "The DVD in device %s contains data, please blank it before writing.\n" #~ msgstr "" #~ "El DVD en el dispositivo %s contiene datos, por favor, borre el antes de " #~ "la escritura.\n" #~ msgid "Unable to stat DVD part 1 file %s: ERR=%s\n" #~ msgstr "No se puede stat DVD parte 1, archivo %s: ERR=%s\n" #~ msgid "DVD part 1 is not a regular file %s.\n" #~ msgstr "La Parte 1 del DVD no es un archivo regular %s.\n" #~ msgid "There is no valid DVD in device %s.\n" #~ msgstr "No hay ningún DVD válido en el dispositivo %s.\n" #~ msgid "Could not mount DVD device %s.\n" #~ msgstr "No se pudo montar el dispositivo de DVD %s.\n" #~ msgid "Could not fstat: %s, ERR=%s\n" #~ msgstr "No se pudo fstat: %s, ERR=%s\n" #~ msgid "Bad call to rewind. Device %s not open\n" #~ msgstr "Mala llamada para rebobinar. Dispositivo %s no abierto\n" #~ msgid "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" #~ msgstr "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" #~ msgid "WARNING!!!! The Internal Database is NOT OPERATIONAL!\n" #~ msgstr "ATENCIÓN!!! La BD Interna NO ESTA OPERACIONAL!\n" #~ msgid "You should use SQLite, PostgreSQL, or MySQL\n" #~ msgstr "Usted debe usar SQLite, PostgreSQL o MySQL\n" #~ msgid "Unable to open Catalog DB control file %s: ERR=%s\n" #~ msgstr "No es posible abrir el archivo de control Catalogo BD %s: ERR=%s\n" #~ msgid "Error reading catalog DB control file. ERR=%s\n" #~ msgstr "Error leyendo el archivo de BD de control de catalogo. ERR=%s\n" #~ msgid "" #~ "Error, catalog DB control file wrong version. Wanted %d, got %d\n" #~ "Please reinitialize the working directory.\n" #~ msgstr "" #~ "Error, tiene una versión incorrecta del archivo de control de catalogo " #~ "BD. Se requiere %d y tiene %d\n" #~ "Por favor reinicialice el directorio de trabajo.\n" #~ msgid "Could not connect to storage daemon" #~ msgstr "No puedo conectar al demonio de storage" #~ msgid "3917 Volume recycled\n" #~ msgstr "3917 Volumen reciclado\n" #~ msgid "3918 Recycle failed\n" #~ msgstr "3918 Reciclaje fallida\n" #~ msgid "" #~ "PostgreSQL configuration problem. PostgreSQL library is not thread safe. " #~ "Cannot continue.\n" #~ msgstr "" #~ "Problema de configuración de PostgreSQL. Biblioteca de PostgreSQL no es " #~ "hilo seguro. No se puede continuar.\n" #~ msgid "%s:%i Failed ASSERT: %s\n" #~ msgstr "%s:%i Fallo ASSERT: %s\n" #~ msgid "Job %s marked to be canceled.\n" #~ msgstr "Job %s marcados para ser cancelados.\n" bareos-Release-14.2.6/po/fr.po000066400000000000000000020510311263011562700160270ustar00rootroot00000000000000# French translations for Bareos package # Traduction anglaise du package Bareos. # Copyright (C) 2005-2006 Free Software Foundation Europe e.V. # Nicolas Boichat , 2005. # msgid "" msgstr "" "Project-Id-Version: Bareos 1.38\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2009-10-18 14:04+0000\n" "Last-Translator: Eric Bollengier \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "Liste vide.\n" #: src/cats/sql.c:789 #, fuzzy msgid "Could not init database batch connection\n" msgstr "Impossible d'initialiser le Python\n" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, fuzzy, c-format msgid "Unknown database type: %s\n" msgstr "Mot clef inconnu : %s\n" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "Impossible d'initialiser le verrou sur la base. ERR=%s\n" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, fuzzy, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "Impossible de se connecter au serveur PostgreSQL.\n" "Base=%s Utilisateur=%s\n" "Le serveur n'est pas démarré ou bien votre password est invalide.\n" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, fuzzy, c-format msgid "error starting batch mode: %s" msgstr "erreur en terminant le mode batch: %s\n" #: src/cats/dbi.c:1443 #, fuzzy, c-format msgid "error inserting batch mode: %s" msgstr "erreur en terminant le mode batch: %s\n" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 #, fuzzy msgid "Driver type not specified in Catalog resource.\n" msgstr "Impossible de trouver un Catalogue\n" #: src/cats/dbi.c:1486 #, fuzzy msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "Saisie invalide. Veuillez répondre oui ou non.\n" #: src/cats/dbi.c:1490 #, fuzzy msgid "A user name for DBI must be supplied.\n" msgstr "Un nom d'utilisateur MySQL doit être fourni.\n" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "Le pool %s existe déjà en base\n" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:260 #, c-format msgid "More than one Device!: %d\n" msgstr "" #: src/cats/sql_create.c:265 #, fuzzy, c-format msgid "error fetching Device row: %s\n" msgstr "erreur en terminant le mode batch: %s\n" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "Le volume \"%s\" existe déjà en base.\n" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, fuzzy, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_create.c:1316 #, fuzzy, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_create.c:1367 #, fuzzy, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_create.c:1399 #, fuzzy, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_create.c:1442 #, fuzzy, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_create.c:1499 #, fuzzy, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_create.c:1543 #, fuzzy, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" "Impossible de se connecter au serveur MySQL.\n" "Base=%s Utilisateur=%s\n" "Le serveur n'est pas démarré ou bien votre password est invalide.\n" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "Un nom d'utilisateur MySQL doit être fourni.\n" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "Pas de précédent backup Full en base.\n" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "Niveau de job inconnu %d\n" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "Pas de job trouvé pour : %s.\n" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "Pas de job trouvé pour %s\n" #: src/cats/sql_find.c:382 #, fuzzy, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "Le slot %d est ignoré car il est supérieur au maximum %d.\n" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "Pas de volume trouvé en base pour l'objet %d.\n" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "Erreur sur la requête : %s\n" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, fuzzy, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir la base de données \"%s\".\n" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 #, fuzzy msgid "Could not init database connection" msgstr "Impossible d'initialiser le Python\n" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "inconnu" #: src/cats/ingres.c:82 #, fuzzy msgid "Failed to allocate space for query filter.\n" msgstr "Impossible de se connecter au Director\n" #: src/cats/ingres.c:103 #, fuzzy msgid "Failed to allocate space for query filters.\n" msgstr "Impossible de se connecter au Director\n" #: src/cats/ingres.c:257 #, fuzzy, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" "Impossible de se connecter au serveur MySQL.\n" "Base=%s Utilisateur=%s\n" "Le serveur n'est pas démarré ou bien votre password est invalide.\n" #: src/cats/ingres.c:1031 #, fuzzy msgid "A user name for Ingres must be supplied.\n" msgstr "Un nom d'utilisateur MySQL doit être fourni.\n" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, fuzzy, c-format msgid "query dbids failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, fuzzy, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 #, fuzzy msgid "Quota record not found in Catalog.\n" msgstr "%s ressource %s introuvable.\n" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, fuzzy, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "Impossible de se connecter au serveur PostgreSQL.\n" "Base=%s Utilisateur=%s\n" "Le serveur n'est pas démarré ou bien votre password est invalide.\n" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, fuzzy, c-format msgid "error ending batch mode: %s" msgstr "erreur en terminant le mode batch: %s\n" #: src/cats/postgresql.c:1110 #, fuzzy, c-format msgid "error copying in batch mode: %s" msgstr "erreur en terminant le mode batch: %s\n" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "Un nom d'utilisateur PostgreSQL doit être fourni.\n" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 #, fuzzy msgid "Catalog Backends Dir not configured.\n" msgstr "TLS activé mais non configuré.\n" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, fuzzy, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, fuzzy, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, fuzzy, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/cats/cats_backends.c:236 #, fuzzy, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "" #: src/console/console_conf.c:143 #, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" "\n" "Version : " #: src/console/console.c:170 msgid "input from file" msgstr "" #: src/console/console.c:171 msgid "output to file" msgstr "" #: src/console/console.c:172 msgid "quit" msgstr "quit" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "" #: src/console/console.c:174 msgid "sleep specified time" msgstr "" #: src/console/console.c:175 msgid "print current time" msgstr "affiche la date courante" #: src/console/console.c:176 msgid "print Console's version" msgstr "" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "" #: src/console/console.c:179 msgid "exit = quit" msgstr "exit = quit" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "" #: src/console/console.c:181 msgid "help listing" msgstr "" #: src/console/console.c:183 msgid "set command separator" msgstr "" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr "%s : est une commande invalide.\n" #: src/console/console.c:712 #, fuzzy msgid "Illegal separator character.\n" msgstr "Caractère illégal « %c » dans le nom.\n" #: src/console/console.c:744 #, fuzzy msgid "Command logic problem\n" msgstr "Commande annulée.\n" #: src/console/console.c:996 #, fuzzy, c-format msgid "Can't find %s in Director list\n" msgstr "Impossible de trouver la ressource Director \"%s\"\n" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, fuzzy, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "Vous devez saisir un nombre entre 1 et %d\n" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "Vous devez saisir un nombre entre 1 et %d\n" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "Merci de corriger le fichier de configuration : %s\n" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "Connexion au Director %s:%d\n" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "Impossible d'initialiser le contexte TLS pour le Director \"%s\".\n" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "Tapez un point (.) pour annuler une commande.\n" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" "Pas de director défini pour %s\n" "Sans cette définition, il n'est pas possible de se connecter à celui-ci.\n" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "Trop d'arguments sur la commande.\n" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "Le premier argument de la commande doit être un fichier.\n" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s pour lecture. ERR=%s\n" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s pour la sortie. ERR=%s\n" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "" "Trop d'arguments sur la commande. Essayez d'utiliser des « \" » autour des " "commandes\n" #: src/console/console.c:1600 #, fuzzy, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/console/console.c:1612 #, c-format msgid "Autochanger error: ERR=%s\n" msgstr "Erreur sur l'autochangeur : ERR=%s\n" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "Ressource Pool" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "Pas de Storage défini dans le Job ou le Pool.\n" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, fuzzy, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "Démarrage du backup JobId %s, Job=%s\n" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, fuzzy, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "Impossible de récupérer le Job du JobId=%s : ERR=%s\n" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, fuzzy, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "Impossible de mettre à jour les informations du Volume : ERR=%s" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "Backup OK" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "Backup OK -- avec des erreurs" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "*** Backup en erreur ***" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "Backup annulé" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/dird/bsr.c:287 #, fuzzy msgid "No files found to read. No bootstrap file written.\n" msgstr "" "Aucun fichier trouvé pour la restauration/migration. Pas de fichier " "Bootstrap écrit.\n" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "Erreur pendant l'écriture du fichier bsr.\n" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "Fichier bootstrap écrit sur %s\n" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" "Ce job va utiliser les éléments suivants :\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "Aucun volume trouvé pour la restauration.\n" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier bootstrap %s : ERR=%s\n" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, fuzzy, c-format msgid "Could not get storage resource '%s'.\n" msgstr "Impossible de trouver la ressource Storage \"%s\"\n" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "Admin OK" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "*** Admin en Erreur ***" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "Admin Annulé" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -d positionne le niveau de debug à nn\n" " -dt affiche un timestamp devant chaque ligne de debug\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "Retour à la dernière configuration.\n" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 #, fuzzy msgid "TLS required but not configured in BAREOS.\n" msgstr "TLS activé mais non configuré.\n" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, fuzzy, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "" "Impossible d'ouvrir le catalogue \"%s\", sur la base de données \"%s\".\n" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "" "Impossible d'ouvrir le catalogue \"%s\", sur la base de données \"%s\".\n" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "%s" #: src/dird/dird.c:1110 #, fuzzy, c-format msgid "Could not create storage record for %s\n" msgstr "Impossible de trouver la ressource Storage \"%s\"\n" #: src/dird/dird.c:1119 #, fuzzy, c-format msgid "Could not update storage record for %s\n" msgstr "Impossible de trouver la ressource Storage \"%s\"\n" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, fuzzy, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" "Fin de la purge automatique.\n" "\n" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 #, fuzzy msgid "Create temporary index? (yes/no): " msgstr "Continuez ? (oui/non) : " #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "oui" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, fuzzy, c-format msgid "Error getting Quota value: ERR=%s" msgstr "Impossible de positionner le flag InChanger : ERR=%s" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, fuzzy, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "Impossible de positionner le flag InChanger : ERR=%s" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, fuzzy, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "Impossible de positionner le flag InChanger : ERR=%s" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, fuzzy, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "Impossible de récupérer le Job du JobId=%s : ERR=%s\n" #: src/dird/ua_run.c:88 #, fuzzy, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "Impossible de mettre à jour les informations du Volume : ERR=%s" #: src/dird/ua_run.c:102 #, fuzzy, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "Impossible de récupérer le Job du JobId=%s : ERR=%s\n" #: src/dird/ua_run.c:170 #, fuzzy, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "Impossible de mettre à jour les informations du Volume : ERR=%s" #: src/dird/ua_run.c:312 #, fuzzy msgid "rerun these jobids? (yes/no): " msgstr "Le nouveau nombre de fichier du Volume est : %u\n" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "OK pour le lancement ? (oui/mod/non) : " #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "non" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "Job échoué.\n" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "Job mis en queue. JobId=%s\n" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "Job non lancé.\n" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "mod" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "Paramètre à modifier :\n" #: src/dird/ua_run.c:550 msgid "Level" msgstr "Type" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "Stockage" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "Job" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "FileSet" #: src/dird/ua_run.c:555 #, fuzzy msgid "Restore Client" msgstr "Restauration annulée" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "Client" #: src/dird/ua_run.c:559 #, fuzzy msgid "Backup Format" msgstr "Backup OK" #: src/dird/ua_run.c:560 msgid "When" msgstr "Quand" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "Priorité" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "Pool" #: src/dird/ua_run.c:571 #, fuzzy msgid "NextPool" msgstr "Pool" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "Job de vérification" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "Bootstrap" #: src/dird/ua_run.c:582 msgid "Where" msgstr "Destination" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "Écrasement" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "JobId" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "Sélectionnez le paramètre à modifier" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 #, fuzzy msgid "Please enter Backup Format: " msgstr "Saisissez le JobId pour la restauration : " #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" "Saisissez la date de lancement (YYYY-MM-DD HH:MM:SS) (ou maintenant) : " #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "Saisissez la nouvelle priorité : " #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "La priorité doit être un entier positif.\n" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "Saisissez le nom du fichier Bootstrap : " # Impossible d'ouvrir %s : ERR=%s #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/dird/ua_run.c:730 #, fuzzy msgid "Please enter the full path prefix for restore (/ for none): " msgstr "Saisissez le chemin (prefix) pour la restauration (/ pour aucun) : " #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 #, fuzzy msgid "Please enter Plugin Options string: " msgstr "Saisissez le début du chemin (prefix) à enlever : " #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "Écrasement :\n" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "Saisissez l'option d'écrasement" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" "Vous ne devez pas spécifié de fichier bootstrap pour pouvoir utiliser un " "JobId.\n" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "Option d'écrasement (Replace) invalide : %s\n" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 #, fuzzy msgid "Storage from Run NextPool override" msgstr "Sélectionnez le Pool" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, fuzzy, c-format msgid "Level \"%s\" not valid.\n" msgstr "Le type %s est invalide.\n" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 #, fuzzy msgid "Please enter the path prefix to strip: " msgstr "Saisissez le début du chemin (prefix) à enlever : " #: src/dird/ua_run.c:1035 #, fuzzy msgid "Please enter the path prefix to add (/ for none): " msgstr "Saisissez le chemin (prefix) à ajouter (/ pour aucun) : " #: src/dird/ua_run.c:1046 #, fuzzy msgid "Please enter the file suffix to add: " msgstr "Saisissez une extention à ajouter aux fichiers : " #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "Saisissez une regexp valide (!rechercher!remplacer!) : " #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "Impossible d'utiliser votre regexp\n" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "Saisissez un nom de fichier à tester : " #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "%s -> %s\n" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "Impossible d'utiliser votre regexp.\n" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "Types :\n" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "Full" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "Incrémental" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "Différentiel" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "Depuis" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "Saisissez le type" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "Initialisez le catalogue" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "Vérification des données sur le volume (pas encore implémenté)" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "" #: src/dird/ua_run.c:1236 #, fuzzy, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" "Lancement du job %s\n" "JobName : %s\n" "FileSet : %s\n" "Client : %s\n" "Storage : %s\n" "Quand : %s\n" "Priorité : %d\n" #: src/dird/ua_run.c:1288 #, fuzzy, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" "Lancement du job %s\n" "JobName : %s\n" "Niveau : %s\n" "Client : %s\n" "FileSet : %s\n" "Pool : %s (Depuis %s)\n" "Storage : %s (Depuis %s)\n" "Quand : %s\n" "Priorité : %d\n" #: src/dird/ua_run.c:1328 #, fuzzy, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "Impossible de récupérer le Job du JobId=%s : ERR=%s\n" #: src/dird/ua_run.c:1367 #, fuzzy, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" "Lancement du job %s\n" "JobName : %s\n" "Niveau : %s\n" "Client : %s\n" "FileSet : %s\n" "Pool : %s (Depuis %s)\n" "Storage : %s (Depuis %s)\n" "Verify Job : %s\n" "Verify List: %s\n" "Quand : %s\n" "Priorité : %d\n" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "Saisissez le JobId pour la restauration : " #: src/dird/ua_run.c:1438 #, fuzzy, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "Lancement de la restauration\n" "JobName : %s\n" "Bootstrap : %s\n" "RegexWhere : %s\n" "Écrasement : %s\n" "FileSet : %s\n" "Backup Client : %s\n" "Restore Client : %s\n" "Storage : %s\n" "Quand : %s\n" "Catalogue : %s\n" "Priorité : %d\n" #: src/dird/ua_run.c:1498 #, fuzzy, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "Lancement de la restauration\n" "JobName : %s\n" "Bootstrap : %s\n" "Déplacement : %s\n" "Écrasement : %s\n" "FileSet : %s\n" "Backup Client : %s\n" "Restore Client : %s\n" "Storage : %s\n" "Quand : %s\n" "Catalogue : %s\n" "Priorité : %d\n" "Options Plugins: %s\n" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" "Lancement de la restauration\n" "JobName : %s\n" "Bootstrap : %s\n" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "Where : %s\n" #: src/dird/ua_run.c:1546 #, fuzzy, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "Écrasement : %s\n" "Client : %s\n" "Storage : %s\n" "JobId : %s\n" "Quand : %s\n" "Catalogue : %s\n" "Priorité : %d\n" "Options Plugins : %s\n" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, fuzzy, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" "Lancement de la restauration\n" "JobName : %s\n" "Bootstrap : %s\n" "Destination : %s\n" "Écrasement : %s\n" "Client : %s\n" "Storage : %s\n" "JobId : %s\n" "Quand : %s\n" "Catalogue : %s\n" "Priorité : %d\n" #: src/dird/ua_run.c:1600 #, fuzzy msgid "Run Copy job\n" msgstr "Sélectionnez le Job de restauration" #: src/dird/ua_run.c:1602 #, fuzzy msgid "Run Migration job\n" msgstr "Sélectionnez le Job de restauration" #: src/dird/ua_run.c:1604 #, fuzzy, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" "Lancement de la restauration\n" "JobName : %s\n" "Bootstrap : %s\n" "Destination : %s\n" "Écrasement : %s\n" "Client : %s\n" "Storage : %s\n" "JobId : %s\n" "Quand : %s\n" "Catalogue : %s\n" "Priorité : %d\n" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "Job du Type=%d inconnu\n" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "Le job est déjà spécifié.\n" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "Le JobId est déjà spécifié.\n" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "Le client est déjà spécifié.\n" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "Le FileSet est déjà spécifié.\n" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "Le type (Level) est déjà spécifié.\n" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "Le Storage est déjà spécifié.\n" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "RegexWhere ou Where est déjà spécifiée.\n" #: src/dird/ua_run.c:1768 #, fuzzy msgid "No authorization for \"regexwhere\" specification.\n" msgstr "La destination (Where) est déjà spécifiée.\n" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "RegexWhere ou Where est déjà spécifiée.\n" #: src/dird/ua_run.c:1780 #, fuzzy msgid "No authoriztion for \"where\" specification.\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "Le bootstrap est déjà spécifié.\n" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "L'option d'écrasement (Replace) est déjà spécifié.\n" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "La planification (When) est déjà spécifiée.\n" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "La priorité (Priority) est déjà spécifiée.\n" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" "La priorité doit être supérieure à zéro. Utilisation d'une priorité de 10.\n" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "Le pool est déjà spécifié.\n" #: src/dird/ua_run.c:1870 #, fuzzy msgid "NextPool specified twice.\n" msgstr "Le pool est déjà spécifié.\n" #: src/dird/ua_run.c:1886 #, fuzzy msgid "Restore Client specified twice.\n" msgstr "Le client est déjà spécifié.\n" #: src/dird/ua_run.c:1894 #, fuzzy msgid "Plugin Options specified twice.\n" msgstr "Le client est déjà spécifié.\n" #: src/dird/ua_run.c:1899 #, fuzzy msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/dird/ua_run.c:1906 #, fuzzy msgid "Spool flag specified twice.\n" msgstr "Le pool est déjà spécifié.\n" #: src/dird/ua_run.c:1913 #, fuzzy msgid "Invalid spooldata flag.\n" msgstr "Période invalide.\n" #: src/dird/ua_run.c:1922 #, fuzzy msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "Le pool est déjà spécifié.\n" #: src/dird/ua_run.c:1929 #, fuzzy msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "Période invalide.\n" #: src/dird/ua_run.c:1934 #, fuzzy msgid "Accurate flag specified twice.\n" msgstr "Le pool est déjà spécifié.\n" #: src/dird/ua_run.c:1941 #, fuzzy msgid "Invalid accurate flag.\n" msgstr "Période invalide.\n" #: src/dird/ua_run.c:1946 #, fuzzy msgid "Backup Format specified twice.\n" msgstr "Le bootstrap est déjà spécifié.\n" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "Argument invalide : %s\n" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "Le catalogue \"%s\" est introuvable\n" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "Le job \"%s\" est introuvable\n" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "Un nom de Job doit être spécifié.\n" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "Le pool \"%s\" est introuvable.\n" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "Le Storage \"%s\" est introuvable.\n" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "Pas de storage sélectionné.\n" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, fuzzy, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "Le FileSet \"%s\" est introuvable.\n" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "Statut disponible pour :\n" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "Saisissez le composant à afficher" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "%s Version : %s (%s) %s %s %s\n" #: src/dird/ua_status.c:390 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "Démon démarré depuis %s, %d jobs lancés depuis cette date.\n" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, fuzzy, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr " Heap: bytes=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 #, fuzzy msgid "No clients defined.\n" msgstr "Pas de fichier dé-sélectionné.\n" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 #, fuzzy msgid "Schedule" msgstr "" "\n" "Jobs planifiés :\n" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" "\n" "Jobs planifiés :\n" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" "Type Action Pri Planification Nom Volume\n" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, fuzzy, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "%-14s %-8s %3d %-18s %-18s %s\n" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "%-14s %-8s %3d %-18s %-18s %s\n" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "Pas de job programmé.\n" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" "\n" "Job en cours :\n" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "Console connecté à %s\n" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" "Pas de job en cours.\n" "====\n" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr " JobId Type Nom Statut\n" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "======================================================================\n" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "est en attente d'exécution" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "est en cours" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "est bloqué" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "est terminé" #: src/dird/ua_status.c:1034 #, fuzzy msgid "has terminated with warnings" msgstr "Job terminés :\n" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "est en erreur" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "est en erreur (fatale)" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "a été annulé" #: src/dird/ua_status.c:1054 #, fuzzy msgid "is waiting on Client" msgstr "est en attente du client %s" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "est en attente du client %s" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, fuzzy, c-format msgid "is waiting on Storage \"%s\"" msgstr "est en attente du Storage %s" #: src/dird/ua_status.c:1068 #, fuzzy msgid "is waiting on Storage" msgstr "est en attente du Storage %s" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, fuzzy, c-format msgid "is waiting for its start time at %s" msgstr "attend son heure de démarrage" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "attend son heure de démarrage" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "attend qu'un job plus prioritaire se termine" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 #, fuzzy msgid "SD despooling Data" msgstr "Spooling des données...\n" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 #, fuzzy msgid "SD despooling Attributes" msgstr "Spooling des données...\n" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "est dans un état inconnu %c" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "est en attente d'un montage" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "est en attente d'un volume libre" #: src/dird/ua_status.c:1144 #, fuzzy msgid "is waiting for Client to connect to Storage daemon" msgstr "attend que le client %s se connecte au Storage %s" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "attend que le client %s se connecte au Storage %s" #: src/dird/ua_status.c:1177 #, fuzzy, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "%6d %-6s %-20s %s\n" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "%6d %-6s %-20s %s\n" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "Pas de job terminé.\n" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" "\n" "Job terminés :\n" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr " JobId Type Fichiers Octets Statut Terminé Nom\n" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "=====================================================================\n" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "Crée" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "Erreur" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "Annulé" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "OK" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "OK -- avec des avertissements" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "Autre" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, fuzzy, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "%6d %-6s %8s %10s %-7s %-8s %s\n" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "%6d %-6s %8s %10s %-7s %-8s %s\n" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "\n" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 #, fuzzy msgid "No Volumes found, or no barcodes.\n" msgstr "Pas de volume à labéliser ou pas de codebar.\n" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "Pas de slot dans le magasin à scanner.\n" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "Le slot %d est ignoré car il est supérieur au maximum %d.\n" #: src/dird/msgchan.c:159 #, fuzzy, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "Le storage a rejeté la commande Hello\n" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "Fichier : %s\n" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr ": est une commande invalide.\n" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "Impossible de récupérer le Job du JobId=%s : ERR=%s\n" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "Impossible d'ouvrir la socket avec le SD.\n" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "Connecté au Storage Daemon\n" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "Connexion au client %s (%s:%d)\n" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "Impossible de se connecter au Client.\n" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, fuzzy, c-format msgid "Unknown command: %s\n" msgstr "Erreur inconnue." #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "Les démons disponibles sont :\n" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "Director" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "Sélectionnez le composant a tuer" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 #, fuzzy msgid "query keyword not found.\n" msgstr "%s ressource %s introuvable.\n" #: src/dird/ua_dotcmds.c:1116 #, fuzzy, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/dird/ua_dotcmds.c:1130 #, fuzzy, c-format msgid "List Media failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/dird/ua_dotcmds.c:1156 #, fuzzy, c-format msgid "List Location failed: ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "Saisissez le slot" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "Attendait un entier positif, pas : %s\n" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "Réponse invalide. Vous devez répondre oui ou non.\n" #: src/dird/ua_input.c:183 #, fuzzy msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "Saisie invalide. Veuillez répondre oui ou non.\n" #: src/dird/ua_input.c:211 #, fuzzy, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "Caractère illégal « %c » dans le nom.\n" #: src/dird/ua_input.c:218 #, fuzzy msgid "Comment too long.\n" msgstr "Nom trop long.\n" #: src/dird/ua_input.c:224 #, fuzzy msgid "Comment must be at least one character long.\n" msgstr "Le nom du volume doit comporter au moins un caractère\n" #: src/dird/ua_cmds.c:104 #, fuzzy msgid "Add media to a pool" msgstr "ajouter un média dans un pool" #: src/dird/ua_cmds.c:106 #, fuzzy msgid "Autodisplay console messages" msgstr "autodisplay [on|off] -- messages de la console" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 #, fuzzy msgid "Cancel a job" msgstr "Annulé" #: src/dird/ua_cmds.c:112 #, fuzzy msgid "Configure director" msgstr "La création de la signature a échouée" #: src/dird/ua_cmds.c:114 #, fuzzy msgid "Create DB Pool from resource" msgstr "Pool à partir de sa définition" #: src/dird/ua_cmds.c:116 #, fuzzy msgid "Delete volume, pool or job" msgstr "met à jour un volume, un pool ou bien des slots" #: src/dird/ua_cmds.c:118 #, fuzzy msgid "Disable a job/client/schedule" msgstr "est bloqué" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 #, fuzzy msgid "Performs FileSet estimate, listing gives full listing" msgstr "" "estimate -- estime un FileSet (listing donne la liste des fichiers)" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 #, fuzzy msgid "Non-interactive gui mode" msgstr "gui [on|off] -- mode non interactif (pour interface graphique)" #: src/dird/ua_cmds.c:130 #, fuzzy msgid "Print help on specific command" msgstr "affiche cette commande" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 #, fuzzy msgid "Label a tape" msgstr "labéliser une bande" #: src/dird/ua_cmds.c:141 #, fuzzy msgid "List objects from catalog" msgstr "purge les enregistrements du catalogue" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 #, fuzzy msgid "Display pending messages" msgstr "Message de Bareos" #: src/dird/ua_cmds.c:159 #, fuzzy msgid "Print current memory usage" msgstr "affiche la consommation mémoire courante" #: src/dird/ua_cmds.c:161 #, fuzzy msgid "Mount storage" msgstr "unmount -- démonte un lecteur" #: src/dird/ua_cmds.c:164 #, fuzzy msgid "Move slots in an autochanger" msgstr "Slots d'un autochangeur" #: src/dird/ua_cmds.c:166 #, fuzzy msgid "Prune records from catalog" msgstr "purge les enregistrements du catalogue" #: src/dird/ua_cmds.c:168 #, fuzzy msgid "Purge records from catalog" msgstr "purge les enregistrements du catalogue" #: src/dird/ua_cmds.c:173 #, fuzzy msgid "Query catalog" msgstr "interroger le catalogue" #: src/dird/ua_cmds.c:175 #, fuzzy msgid "Restore files" msgstr "restauration de fichier" #: src/dird/ua_cmds.c:183 #, fuzzy msgid "Relabel a tape" msgstr "re-labélise une bande" #: src/dird/ua_cmds.c:186 #, fuzzy msgid "Release storage" msgstr "Restaurer" #: src/dird/ua_cmds.c:188 #, fuzzy msgid "Reload conf file" msgstr "recharge la configuration" #: src/dird/ua_cmds.c:190 #, fuzzy msgid "Rerun a job" msgstr "Job en cours :\n" #: src/dird/ua_cmds.c:192 #, fuzzy msgid "Resolve a hostname" msgstr "impossible de résoudre le hostname (%s) %s" #: src/dird/ua_cmds.c:194 #, fuzzy msgid "Run a job" msgstr "Job en cours :\n" #: src/dird/ua_cmds.c:202 #, fuzzy msgid "Report status" msgstr "Statut :\n" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 #, fuzzy msgid "Sets debug level" msgstr "positionne le niveau de debug" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 #, fuzzy msgid "Show resource records" msgstr "Pool à partir de sa définition" #: src/dird/ua_cmds.c:219 #, fuzzy msgid "Use SQL to query catalog" msgstr "passer des commandes SQL pour interroger le catalogue" #: src/dird/ua_cmds.c:221 #, fuzzy msgid "Print current time" msgstr "affiche la date courante" #: src/dird/ua_cmds.c:223 #, fuzzy msgid "Turn on/off trace to file" msgstr "active/désactive le fichier de trace" #: src/dird/ua_cmds.c:225 #, fuzzy msgid "Unmount storage" msgstr "unmount -- démonte un lecteur" #: src/dird/ua_cmds.c:228 #, fuzzy msgid "Umount - for old-time Unix guys, see unmount" msgstr "umount -- démonte un lecteur" #: src/dird/ua_cmds.c:231 #, fuzzy msgid "Update volume, pool or stats" msgstr "met à jour un volume, un pool ou bien des slots" #: src/dird/ua_cmds.c:240 #, fuzzy msgid "Use specific catalog" msgstr "interroger le catalogue" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 #, fuzzy msgid "Print Director version" msgstr "affiche la version du Director" #: src/dird/ua_cmds.c:246 #, fuzzy msgid "Wait until no jobs are running" msgstr "Aucun de vos jobs ne sont en cours.\n" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "%s : est une commande invalide.\n" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "Le pool a déjà atteint le nombre maximum de volume=%d\n" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "Entrez le nouveau maximum (zéro pour illimité) : " #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "Entrez le nombre de Volume à créer. 0=>nom fixé. Max=%d : " #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "Le nombre doit être entre 0 et %d\n" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "Entrez le nom du Volume : " #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "Entrez le nom de base du volume : " #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "Nom de Volume trop long.\n" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "Le nom du volume doit comporter au moins un caractère\n" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "Entrez le nombre de départ : " #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "Le nombre de départ doit être supérieur à zéro.\n" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "Saisissez le slot (0 pour aucun) : " #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "InChanger ? oui/non : " #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "%d Volumes créés dans le pool %s\n" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "Activer ou désactiver ? (on/off) " #: src/dird/ua_cmds.c:523 #, fuzzy, c-format msgid "JobId %s not a number\n" msgstr "Job %s non trouvé\n" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" "Erreur : Pool %s est déjà défini.\n" "Utilisez update pour le changer\n" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "Pool %s créé.\n" #: src/dird/ua_cmds.c:793 #, fuzzy msgid "Failed to set bandwidth limit on Client.\n" msgstr "Impossible de se connecter au Client.\n" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "Connexion au Storage Daemon %s (%s:%d)\n" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "Impossible de se connecter au Storage daemon.\n" #: src/dird/ua_cmds.c:843 #, fuzzy msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "Impossible de se connecter au Client.\n" #: src/dird/ua_cmds.c:881 #, fuzzy msgid "Enter new bandwidth limit kb/s: " msgstr "Saisissez la valeur du nombre maximum de Job : " #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "Commande interdite depuis cette console.\n" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "Client \"%s\" adresse positionné à %s\n" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "Job \"%s\" non trouvé.\n" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, fuzzy, c-format msgid "Client \"%s\" %sabled\n" msgstr "le client \"%s\" est introuvable.\n" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "Saisissez le nouveau niveau de debug : " #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "Sélectionnez le composant a mettre à jour" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, fuzzy, c-format msgid "No authorization for Client \"%s\"\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, fuzzy, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/dird/ua_cmds.c:1495 #, fuzzy msgid "Storage name missing.\n" msgstr "La valeur actuelle est : %s\n" #: src/dird/ua_cmds.c:1520 #, fuzzy, c-format msgid "%s Failed to resolve %s\n" msgstr "3912 Impossible de labéliser le Volume : ERR=%s\n" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, fuzzy, c-format msgid "%s resolves %s to %s\n" msgstr "%s ressource %s introuvable.\n" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, fuzzy, c-format msgid "Fileset \"%s\" not found.\n" msgstr "Le FileSet \"%s\" est introuvable.\n" #: src/dird/ua_cmds.c:1632 #, fuzzy, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 #, fuzzy msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "Saisie invalide. Veuillez répondre oui ou non.\n" #: src/dird/ua_cmds.c:1667 #, fuzzy msgid "Accurate value missing.\n" msgstr "La valeur actuelle est : %s\n" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "Pas de job sélectionné.\n" #: src/dird/ua_cmds.c:1696 #, fuzzy, c-format msgid "Wrong job specified of type %s.\n" msgstr "Pas de job sélectionné.\n" #: src/dird/ua_cmds.c:1709 #, fuzzy msgid "No client specified or selected.\n" msgstr "Le client est déjà spécifié.\n" #: src/dird/ua_cmds.c:1714 #, fuzzy msgid "No fileset specified or selected.\n" msgstr "Aucun fichier sélectionné pour la restauration.\n" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "Erreur pendant l'envoi de la liste d'inclusion.\n" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "Erreur pendant l'envoi de la liste d'exclusion.\n" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" "Généralement supprimer un pool ou bien un volume\n" "n'est pas une bonne idée car ils peuvent contenir des données.\n" "\n" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "Choisissez l'objet du catalogue à supprimer" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "Rien de fait.\n" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, c-format msgid "Illegal JobId %s ignored\n" msgstr "" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "Saisissez le JobId à supprimer : " #: src/dird/ua_cmds.c:1979 #, fuzzy, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "Êtes vous certain de vouloir supprimer ce Pool ? (oui/non) : " #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, fuzzy, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" "Le Job %s et les enregistrements associés ont été supprimés du catalogue.\n" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" "\n" "Cette commande va supprimer le Volume %s\n" "et tous les Jobs sauvegardés sur celui-ci du Catalogue\n" #: src/dird/ua_cmds.c:2031 #, fuzzy, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "Êtes vous certain de vouloir supprimer ce Volume ? (oui/non) : " #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, fuzzy, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "Êtes vous certain de vouloir supprimer ce Pool ? (oui/non) : " #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "Utilisation du Catalogue name=%s DB=%s\n" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "ERR: Job %s non trouvé\n" #: src/dird/ua_cmds.c:2391 #, fuzzy msgid "" " Command Description\n" " ======= ===========\n" msgstr "" " Commande Description\n" " ======== ===========\n" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, fuzzy, c-format msgid " %-13s %s\n" msgstr " %-10s %s\n" #: src/dird/ua_cmds.c:2404 #, fuzzy, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr ": est une commande invalide.\n" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" "\n" "Sur une question, tapez un point (.) pour annuler la commande en cours.\n" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "Impossible de trouver un Catalogue\n" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "Impossible d'ouvrir le catalogue \"%s\".\n" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "Utilisation du Catalogue \"%s\"\n" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" "Impossible de trouvé JobId d'un précédent Job « InitCatalog.\n" "Il faut lancer un Job Verify avec l'option Level=InitCatalog avant\n" "de lancer le Job courant.\n" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "Impossible de trouver JobId d'un précédent Job pour ce client.\n" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "Le dernier job %d ne s'est pas terminé correctement. JobStatus=%c\n" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "Vérification OK" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "*** Erreur de Vérification ***" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "Vérification annulée" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s %s (%s): %s\n" " Build OS: %s %s %s\n" " JobId : %d\n" " Job : %s\n" " FileSet: %s\n" " Client : %s\n" " Début : %s\n" " Fin : %s\n" " Fichiers attendus : %s\n" " Fichiers restaurés : %s\n" " Octets restaurés : %s\n" " Débit : %.1f Ko/s\n" " Erreurs du FD : %d\n" " Statut de fin du FD : %s\n" " Statut de fin du SD : %s\n" " Etat : %s\n" #: src/dird/verify.c:581 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s (%s) : %s\n" " Build: %s %s %s\\n\"\n" " JobId : %d\n" " Job : %s\n" " FileSet : %s\n" " Client : %s\n" " Début : %s\n" " Fin : %s\n" " Fichiers attendus : %s\n" " Fichiers restaurés : %s\n" " Octets restaurés : %s\n" " Débit : %.1f Ko/s\n" " Erreurs du FD : %d\n" " Statut de fin du FD : %s\n" " Statut de fin du SD : %s\n" " Etat : %s\n" #: src/dird/verify.c:661 #, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "Les Catalogues définis sont :\n" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "Catalogue" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "Sélectionnez le Catalogue" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "Les Job définis sont :\n" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "Sélectionnez le Job" #: src/dird/ua_select.c:307 #, fuzzy, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "Erreur : le Pool \"%s\" n'existe pas.\n" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "Les Job de restauration sont :\n" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "Sélectionnez le Job de restauration" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "Les clients définis sont :\n" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "Sélectionnez le client (File daemon)" #: src/dird/ua_select.c:378 #, fuzzy msgid "Select Client resource" msgstr "Sélectionnez le FileSet" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "Erreur : le client %s n'est pas définie.\n" #: src/dird/ua_select.c:421 #, fuzzy msgid "The defined Schedule resources are:\n" msgstr "Les clients définis sont :\n" #: src/dird/ua_select.c:432 #, fuzzy msgid "Select Schedule resource" msgstr "Sélectionnez le Pool" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "Impossible de trouver le client %s : ERR=%s" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "Impossible de trouver le client \"%s\" : ERR=%s" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "Erreur pendant l'obtention de l'identifiant du Client. ERR=%s\n" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" "Pas de client défini. Vous devez lancer une sauvegarde avant d'utiliser " "cette commande.\n" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "Clients définis :\n" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "Sélectionnez le client" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "Impossible de trouver le Pool \"%s\" : ERR=%s" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" "Pas de Pool défini. Utilisez la commande « create » pour en créer un.\n" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "Pools définis :\n" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "Sélectionnez le Pool" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "Pas d'accès au Pool \"%s\"\n" #: src/dird/ua_select.c:678 #, fuzzy msgid "Enter *MediaId or Volume name: " msgstr "Saisissez le MediaId ou le nom du Volume : " #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "Les Pools définis sont :\n" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "Sélectionnez le Pool" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "Erreur : le Pool \"%s\" n'existe pas.\n" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "Entrez le JobId à sélectionner : " #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "Impossible de trouver le Job \"%s\" : ERR=%s" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "Sélection automatique %s : %s\n" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "La sélection pour \"%s\" est vide !\n" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "Sélection automatique : %s\n" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "Sélection annulée, rien de fait.\n" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "Merci de saisir un nombre entre 1 et %d\n" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "Attendait l'option jobid=nn, pas : %s\n" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "JobId %s n'est pas en cours.\n" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "Attendait l'option job=xxx, pas : %s\n" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "Job \"%s\" n'est pas en cours.\n" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "Attendait l'option ujobid=xxx, pas : %s\n" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "Storage resource \"%s\" : non trouvé\n" #: src/dird/ua_select.c:1093 #, fuzzy msgid "Select Drive:\n" msgstr "Choix : " #: src/dird/ua_select.c:1098 #, fuzzy msgid "Drive" msgstr "Archiver" #: src/dird/ua_select.c:1098 #, fuzzy msgid "Select drive" msgstr "Saisissez le type" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "Saisissez le slot de l'autochanger [0] : " #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "Choisissez le type de Media" #: src/dird/ua_select.c:1262 #, fuzzy, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" "JobId %s n'est pas en cours. Utilisez le nom du Job pour annuler un job " "inactif.\n" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "Attention le Job %s n'est pas en cours. Continuons quand même...\n" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "Pas de job en cours.\n" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "Aucun de vos jobs ne sont en cours.\n" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, fuzzy, c-format msgid "Selected Job %d for cancelling\n" msgstr "Sélectionnez le Job" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "Pas de job sélectionné.\n" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "Confirmez l'annulation (oui/non) : " #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "Sélectionnez le Job :\n" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "JobId=%s Job=%s" #: src/dird/ua_select.c:1443 #, fuzzy, c-format msgid "Choose Job to %s" msgstr "Sélectionnez le Job à annuler" #: src/dird/ua_select.c:1452 #, fuzzy, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" "Annule : %s\n" "\n" "%s" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "Confirmez l'annulation : " #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "Les nombres négatifs ne sont pas autorisés\n" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "La valeur saisie n'est pas un nombre.\n" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "Les valeurs doivent être supérieurs à zéro.\n" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "Slot trop grand.\n" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "1990 Requête sur le Catalogue Invalide : %s" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "Requête sur le Catalogue invalide ; la base n'est pas ouverte : %s" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "1901 Pas de Media.\n" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "non présent dans le Pool" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "n'est pas activé (Enabled)" #: src/dird/catreq.c:203 #, fuzzy, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "1998 Le statut du Volume \"%s\" est %s, %s.\n" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "1997 le Volume \"%s\" n'est pas dans le catalogue.\n" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "" "Impossible de récupérer les informations du Media pour le Volume %s : ERR=%" "s\n" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "1993 Erreur sur la mise à jour du Media\n" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "" #: src/dird/catreq.c:344 #, fuzzy msgid "1992 Create JobMedia error\n" msgstr "1991 Erreur sur la mise à jour du JobMedia\n" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, fuzzy, c-format msgid "Attribute create error: ERR=%s" msgstr "Erreur sur l'autochangeur : ERR=%s\n" #: src/dird/catreq.c:556 #, fuzzy, c-format msgid "Restore object create error. %s" msgstr "Restauration annulée" #: src/dird/catreq.c:564 #, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" #: src/dird/catreq.c:613 #, c-format msgid "attribute create error. %s" msgstr "" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "" #: src/dird/catreq.c:643 #, fuzzy, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "1990 Requête sur le Catalogue Invalide : %s" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, fuzzy, c-format msgid "read attr spool error. ERR=%s\n" msgstr "Erreur pendant l'écriture des attributs dans le spool. ERR=%s\n" #: src/dird/ua_purge.c:95 #, fuzzy msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" "\n" "Cette commande peut être DANGEUREUSE !\n" "\n" "Elle supprime tous les enregistrements des fichiers d'un job, \n" "d'un client ou d'un volume ; ou bien elle supprime tous les jobs\n" "d'un client ou d'un volume sans s'occuper des périodes de rétention.\n" "\n" "Normalement vous devez utiliser la commande PRUNE qui respecte les périodes\n" "de rétention.\n" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "Choisissez l'élément à purger" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "Début de la purge des fichiers du client \"%s\"\n" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "Pas de fichier à purger pour le client \"%s\" dans le catalogue %s.\n" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "Fichiers de %d jobs du client \"%s\" purgé du catalogue %s.\n" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "Début de purge des jobs du client \"%s\"\n" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "%d jobs du client \"%s\" purgé du catalogue %s.\n" #: src/dird/ua_purge.c:439 #, fuzzy, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" "\n" "Le volume \"%s\" est en état \"%s\" et il ne peut pas être purgé.\n" "Son statut doit être : Append, Full, Used ou Error pour être purgé.\n" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "%d fichier%s du volume \"%s\" purgé du catalogue.\n" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" "Il n'y a plus de job associé avec le volume \"%s\". Il est marqué purgé.\n" #: src/dird/ua_purge.c:705 #, fuzzy msgid "Can't update volume size in the catalog\n" msgstr "Le Volume \"%s\" a été créé dans le catalogue.\n" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, fuzzy, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/dird/ua_purge.c:819 #, fuzzy, c-format msgid "No Volumes found to perform %s action.\n" msgstr "Pas de volume à labéliser ou pas de codebar.\n" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" "Impossible de déplacer le volume recyclé, le Pool \"%s\" est plein. MaxVols=%" "d\n" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" "Il n'y a pas de job associé avec le volume \"%s\". Il est marqué comme " "Purged.\n" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "Impossible de purger un volume dans l'état (VolStatus) %s\n" #: src/dird/ua_audit.c:68 #, fuzzy msgid "for Job" msgstr "Job" #: src/dird/ua_audit.c:71 #, fuzzy msgid "for Client" msgstr "Client" #: src/dird/ua_audit.c:74 #, fuzzy msgid "for Storage" msgstr "Stockage" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 #, fuzzy msgid "for Schedule" msgstr "" "\n" "Jobs planifiés :\n" #: src/dird/ua_audit.c:83 #, fuzzy msgid "for Pool" msgstr "Pool" #: src/dird/ua_audit.c:86 #, fuzzy msgid "for Command" msgstr "Erreur sur la commande : %s\n" #: src/dird/ua_audit.c:89 #, fuzzy msgid "for Fileset" msgstr "FileSet" #: src/dird/ua_audit.c:92 #, fuzzy msgid "for Catalog" msgstr "Catalogue" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 #, fuzzy msgid "for Plugin Options" msgstr " --> RunOnSuccess=%u\n" #: src/dird/ua_audit.c:114 #, fuzzy, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "Console connecté à %s\n" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, fuzzy, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "Console connecté à %s\n" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "Vérifier" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 #, fuzzy msgid "base job" msgstr "Annulé" #: src/dird/inc_conf.c:225 #, fuzzy, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "Attendait un entier positif, pas : %s\n" #: src/dird/inc_conf.c:233 #, fuzzy, c-format msgid "Expected a parseable size, got: %s:" msgstr "Attendait un égale, pas : %s" #: src/dird/inc_conf.c:251 #, fuzzy, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "Attendait une option de FileSet, eu : %s:" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:405 #, fuzzy, c-format msgid "Expected a fstype string, got: %s\n" msgstr "Attendait un type de lecteur, pas : %s\n" #: src/dird/inc_conf.c:428 #, fuzzy, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "Attendait un type de lecteur, pas : %s\n" #: src/dird/inc_conf.c:450 #, fuzzy, c-format msgid "Expected a meta string, got: %s\n" msgstr "Attendait une chaîne, pas : %s" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "Attendait le mot clef FileSet, eu : %s" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "Attendait {, eu : %s" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "Attendait un mot clef, eu : %s\n" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "attendait un égale, eu : %s" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "Attendait un nom de fichier, eu : %s" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 #, fuzzy msgid "Client: " msgstr "Client" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "Impossible de lancer la commande : %s. ERR=%s\n" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr "" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "Erreur dans l'exécution de la commande : %s. ERR=%s\n" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "Impossible d'ouvrir le fichier inclus : %s. ERR=%s\n" #: src/dird/fd_cmds.c:660 #, fuzzy, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 #, fuzzy msgid "Plugin options failed.\n" msgstr "Le client est déjà spécifié.\n" #: src/dird/fd_cmds.c:828 #, fuzzy msgid "RestoreObject failed.\n" msgstr "restauration de fichier" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, fuzzy, c-format msgid "Error opening datafile %s\n" msgstr "Impossible d'ouvrir le fichier de données %s.\n" #: src/tests/bbatch.c:339 #, fuzzy msgid "Error while inserting file\n" msgstr "Entrez le nombre de départ : " #: src/tests/bvfs_test.c:51 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/tests/ing_test.c:49 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/tests/cats_test.c:375 #, fuzzy, c-format msgid "Could not open, database \"%s\".\n" msgstr "Impossible d'ouvrir la base de données \"%s\".\n" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "Impossible d'ouvrir le fichier de données %s.\n" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, fuzzy, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/dir_cmd.c:241 #, fuzzy, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, fuzzy, c-format msgid "Connection request from %s failed.\n" msgstr "Demande de connexion échouée.\n" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, fuzzy, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "Connexion invalide. Len=%d\n" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, fuzzy, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "2991 Erreur dans la commande setdebug : %s\n" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "2901 Le job %s est introuvable.\n" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "3904 Job %s non trouvé.\n" #: src/stored/dir_cmd.c:562 #, fuzzy, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "JobId %s, Job %s marqué pour être annulé.\n" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, fuzzy, c-format msgid "%s: Failed to resolve %s\n" msgstr "3912 Impossible de labéliser le Volume : ERR=%s\n" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, fuzzy, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" "3920 Impossible de labéliser le Volume car il possède déjà le label : \"%s" "\"\n" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "3921 Mauvais volume monté.\n" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "3922 Impossible de re-labéliser un Volume ANSI/IBM.\n" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "3912 Impossible de labéliser le Volume : ERR=%s\n" #: src/stored/dir_cmd.c:787 #, fuzzy, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "3912 Impossible de labéliser le Volume : ERR=%s\n" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "3001 Volume monté : %s\n" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, fuzzy, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" "3902 Impossible de monté le volume dans le storage device %s car :\n" "%s" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 #, fuzzy msgid "Specified slot ignored. " msgstr "fopen %s en erreur : ERR=%s\n" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, fuzzy, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, fuzzy, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "3001 Device %s est monté avec le volume \"%s\"\n" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, fuzzy, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" "3905 Le device %s est ouvert mais il n'y a pas de volume Bareos monté.\n" "Si ce n'est pas une cartouche vierge, essayer de la démonter puis de la " "remonter.\n" #: src/stored/dir_cmd.c:989 #, fuzzy, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "3902 Le Device %s est occupé en acquisition.\n" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, fuzzy, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "3934 Device %s est en cours d'initialisation.\n" #: src/stored/dir_cmd.c:1015 #, fuzzy, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "3001 Device %s est déjà monté avec le volume \"%s\"\n" #: src/stored/dir_cmd.c:1025 #, fuzzy, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "3002 Le device %s est monté.\n" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "3907 %s" #: src/stored/dir_cmd.c:1030 #, fuzzy, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "3906 Le device fichier %s est toujours monté.\n" #: src/stored/dir_cmd.c:1038 #, fuzzy, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "3934 Device %s est en cours d'initialisation.\n" #: src/stored/dir_cmd.c:1042 #, fuzzy, c-format msgid "3905 Unknown wait state %d\n" msgstr "est dans un état inconnu %c" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "3909 Erreur pendant la lecture de la commande de montage : %s\n" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, fuzzy, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "3002 Le device %s est démonté.\n" #: src/stored/dir_cmd.c:1086 #, fuzzy, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "3901 Le device %s est déjà démonté.\n" #: src/stored/dir_cmd.c:1101 #, fuzzy, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "3001 Le device %s est démonté.\n" #: src/stored/dir_cmd.c:1105 #, fuzzy, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "3902 Le Device %s est occupé en acquisition.\n" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 #, fuzzy msgid "3916 Error scanning action_on_purge command\n" msgstr "2902 Erreur dans le décodage de la commande d'annulation.\n" #: src/stored/dir_cmd.c:1209 #, fuzzy, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "3921 Le Device %s est déjà libéré.\n" #: src/stored/dir_cmd.c:1216 #, fuzzy, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "3922 Device %s est en attente d'une intervention sysop.\n" #: src/stored/dir_cmd.c:1222 #, fuzzy, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "3922 Le Device %s est en atttente d'un montage.\n" #: src/stored/dir_cmd.c:1226 #, fuzzy, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "3902 Le Device %s est occupé en acquisition.\n" #: src/stored/dir_cmd.c:1230 #, fuzzy, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "3934 Device %s est en cours d'initialisation.\n" #: src/stored/dir_cmd.c:1238 #, fuzzy, c-format msgid "3022 Device \"%s\" released.\n" msgstr "3022 Le device %s est libéré.\n" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/stored/dir_cmd.c:1360 #, fuzzy, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "3995 Le Device %s n'est pas un autochangeur.\n" #: src/stored/dir_cmd.c:1384 #, fuzzy, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "3909 Erreur pendant la lecture de la commande de montage : %s\n" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "3001 Volume=%s Slot=%d\n" #: src/stored/dir_cmd.c:1483 #, fuzzy, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "3931 Device %s est BLOQUÉ, démonté par l'utilisateur.\n" #: src/stored/dir_cmd.c:1486 #, fuzzy, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" "3932 Device %s est BLOQUÉ, démonté par l'utilisateur alors que bareos était " "en attente d'un média.\n" #: src/stored/dir_cmd.c:1489 #, fuzzy, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "3933 Device %s est bloqué en attente d'un media.\n" #: src/stored/dir_cmd.c:1492 #, fuzzy, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "3934 Device %s est en cours d'initialisation.\n" #: src/stored/dir_cmd.c:1496 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "3935 Device %s est bloqué par une labélisation de volume.\n" #: src/stored/dir_cmd.c:1500 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "3935 Device %s est bloqué pour une raison inconnue.\n" #: src/stored/dir_cmd.c:1505 #, fuzzy, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "3936 Device %s est occupé en lecture.\n" #: src/stored/dir_cmd.c:1507 #, fuzzy, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "3937 Device %s est occupé avec %d flux en écriture.\n" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, fuzzy, c-format msgid "Bad passiveclientcmd command: %s" msgstr "Erreur sur la commande : %s\n" #: src/stored/dir_cmd.c:1673 #, fuzzy msgid "File Daemon" msgstr "FileSet" #: src/stored/dir_cmd.c:1679 #, fuzzy, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "Impossible de se connecter au client.\n" #: src/stored/dir_cmd.c:1690 #, fuzzy msgid "Failed to authenticate File daemon.\n" msgstr "Impossible de se connecter au client.\n" #: src/stored/dir_cmd.c:1724 #, fuzzy, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "Erreur dans la commande RunScript : %s\n" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, fuzzy, c-format msgid "Encountered an unknown stream type %d\n" msgstr "est dans un état inconnu %c" #: src/stored/ndmp_tape.c:590 #, fuzzy, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "Job non trouvé : %s\n" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "Impossible d'écrire le label de session. ERR=%s\n" #: src/stored/ndmp_tape.c:749 #, fuzzy msgid "Creating virtual file attributes failed.\n" msgstr "Impossible de restaurer sans un fichier bootstrap.\n" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, fuzzy, c-format msgid "Read session label failed. ERR=%s\n" msgstr "Impossible d'écrire le label de session. ERR=%s\n" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, fuzzy, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "Temps d'écriture du job = %02d:%02d:%02d, Taux de transfert = %s o/s\n" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, fuzzy, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "" "Erreur pendant l'écriture des données vers le fichier de spool. ERR=%s\n" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 #, fuzzy msgid "Cannot initialize new NDMA session\n" msgstr "Impossible d'initialiser %s\n" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 #, fuzzy msgid "Cannot initialize new NDMA connection\n" msgstr "Impossible d'initialiser le Python\n" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "Impossible de positionner l'option SO_REUSEADDR sur la socket : %s\n" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "Impossible de s'attacher au port %d : ERR=%s : Réessaie...\n" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "Impossible de s'attacher au port %d : ERR=%s.\n" #: src/stored/ndmp_tape.c:1414 #, fuzzy, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "Impossible d'initialiser la queue cliente : ERR=%s\n" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "Erreur sur le select : %s\n" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, fuzzy, c-format msgid "Error in poll: %s\n" msgstr "Erreur sur le select : %s\n" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "Connexion depuis %s:%d refusée par hosts.access\n" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "Impossible de positionner SO_KEEPALIVE sur la socket : %s\n" #: src/stored/ndmp_tape.c:1534 #, fuzzy, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "Impossible d'ajouter le job à la queue cliente : ERR=%s\n" #: src/stored/ndmp_tape.c:1557 #, fuzzy, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "Impossible de détruire la queue cliente : ERR=%s\n" #: src/stored/fd_cmds.c:114 #, fuzzy, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "Job non trouvé : %s\n" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, fuzzy, c-format msgid "FD command not found: %s\n" msgstr "Job non trouvé : %s\n" #: src/stored/fd_cmds.c:272 #, fuzzy msgid "Append data error.\n" msgstr "Erreur non fatale" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, fuzzy, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "Attendait le mot clef FileSet, eu : %s" #: src/stored/stored_conf.c:432 #, fuzzy, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "Attendait un Label de lecteur, a pas : %s" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "Trop d'éléments dans la ressource \"%s\"\n" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "Impossible de trouver la ressource AutoChanger %s\n" #: src/stored/stored_conf.c:874 #, fuzzy, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, c-format msgid "%s has an unknown device type %d\n" msgstr "" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" "La taille de bloc %u sur le Device %s est trop grande, utilisation de la " "valeur par défaut %u\n" #: src/stored/dev.c:312 src/stored/dev.c:449 #, fuzzy, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" "La taille du buffer réseau %d n'est pas un multiple de la taille de bloc du " "lecteur.\n" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, fuzzy, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/dev.c:353 #, fuzzy, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/dev.c:360 #, fuzzy, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "erreur de déplacement (lseek) sur %s : ERR=%s\n" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, fuzzy, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "Le Device %s n'est pas ouvert.\n" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, fuzzy, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "Fin de média sur le Volume \"%s\" Octets=%s Blocs=%s à %s.\n" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "Nouveau volume \"%s\" monté sur le device %s à %s.\n" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "Postionnement en avant du Volume \"%s\" sur le fichier:bloc %u:%u.\n" #: src/stored/bscan.c:104 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, fuzzy, c-format msgid "First Volume Size = %s\n" msgstr "Le nombre courant de fichier sur le Volume est : %u\n" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, fuzzy, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "Impossible d'initialiser la queue cliente : ERR=%s\n" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, fuzzy, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "erreur de déplacement (lseek) sur %s : ERR=%s\n" #: src/stored/append.c:161 #, fuzzy, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "" "Erreur pendant l'écriture des données vers le fichier de spool. ERR=%s\n" #: src/stored/append.c:169 #, fuzzy, c-format msgid "Malformed data header from %s: %s\n" msgstr "Message mal formé : %s\n" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, fuzzy, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "Erreur dans l'exécution de la commande : %s. ERR=%s\n" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "Saisissez un nom de Volume : " #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "Le Volume n'a pas de label.\n" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "Statut :\n" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "Voulez vous continuer ? (y/n) : " #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "Commande annulée.\n" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, fuzzy, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "Impossible d'écrire au bloc %u.\n" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 #, fuzzy msgid "" "\n" "Error writing record to block.\n" msgstr "Erreur pendant l'écriture du fichier bsr.\n" #: src/stored/btape.c:985 #, fuzzy msgid "" "\n" "Error writing block to device.\n" msgstr "Erreur pendant l'écriture du fichier bsr.\n" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, fuzzy, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "Ecriture de 1000 blocs de %d octets.\n" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, fuzzy, c-format msgid "%d blocks re-read correctly.\n" msgstr "1000 blocs relus correctement.\n" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, fuzzy, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" "\n" "Cette commande simule l'écriture d'une bande par Bareos.\n" "Ce test requiert une ou deux bandes vierges qui vont être\n" "labélisées et écrites.\n" "\n" "Si vous avez configuré un autochangeur, il utilisera les bandes\n" "des slots 1 et 2, sinon, le programme vous demandera d'insérer\n" "les bandes quand cela sera nécessaire.\n" "\n" "L'état d'avancement sera affiché tous les 322 Mo, et un EOF sera \n" "écrit tous les 3,2 Go. Si vous avez choisi le test simple, après avoir\n" "rempli la bande, elle sera rembobinée et le dernier bloc écrit sera\n" "relu.\n" "\n" "Si vous avez choisi le test multi-bande, quand la première bande sera\n" "remplie vous devrez insérer la nouvelle et après l'écriture de quelques\n" "blocs les deux bandes seront relues.\n" "\n" "Ce test peut durer longtemps (voir des heures).\n" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" "Voulez vous lancer le test simplifié (s) utilisant une seule bande\n" "ou bien le test multi-bande complet (m) : (s/m) " #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "Sélection du test simplifié (utilisant une seule bande).\n" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "Sélection du test multiple.\n" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "Écriture du label de début de session.\n" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 #, fuzzy msgid "Flush block failed.\n" msgstr "Flush de %s blocs, écriture de EOF\n" #: src/stored/btape.c:2319 #, fuzzy, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "Écriture blk_block=%u, dev_blk_num=%u VolBytes=%s rate=%.1f KB/s\n" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "Flush de %s blocs, écriture de EOF\n" #: src/stored/btape.c:2338 #, fuzzy msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "Ecriture de 1000 blocs de %d octets.\n" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 #, fuzzy msgid "Job canceled.\n" msgstr "Le job %s est annulé.\n" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "Écriture du label de fin de session.\n" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "Écriture du fichier d'état last_block_num1=%d last_block_num2=%d\n" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "Impossible de créer le fichier d'état : %s ERR=%s\n" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 #, fuzzy msgid "do_unfill failed.\n" msgstr "Job échoué.\n" #: src/stored/btape.c:2435 #, fuzzy, c-format msgid "%s: Error during test.\n" msgstr "Erreur pendant l'envoi de la liste d'inclusion.\n" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" "\n" "Impossible de trouver le fichier d'état : %s ERR=%s\n" "Vous devez relancer la commande « fill ».\n" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "Chargez la première bande et appuyez sur « Entrée » : " #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "Rembobinage.\n" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "Lecture des 10000 premiers enregistrements depuis %u:%u.\n" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "Re-positionnement de %u:%u à %u:%u\n" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "Erreur pendant le re-positionnement. ERR=%s\n" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "Lecture du bloc %u.\n" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "Chargez une deuxième bande et appuyez sur « Entrée » : " #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "Re-positionnement de %u:%u à 0:1\n" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "Lecture du bloc %d.\n" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "10000 enregistrements lus maintenant à %d:%d\n" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "Dernier bloc écrit" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "Bloc non écrit" #: src/stored/btape.c:2772 #, fuzzy, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "Fin de média sur le Volume \"%s\" Octets=%s Blocs=%s à %s.\n" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "affiche cette commande" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "rembobine la bande" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "Bareos lit bloc par bloc jusqu'à la fin de la bande (EOT) et résume" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "test général des fonctions Bareos sur un lecteur de bande" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "écrit un EOF sur la bande" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "écrit un seul bloc bareos" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "lit un seul enregistrement" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "lit un seul bloc bareos" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "\"%s\" est une commande invalide.\n" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" ") %s %s %s\n" "\n" "Usage : bconsole [-s] [-c config_file] [-d niveau_debug]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - lecture de la configuration et sortie\n" "\n" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, fuzzy, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "Le volume \"%s\" existe déjà en base.\n" #: src/stored/btape.c:3132 #, fuzzy, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "Écriture blk_block=%u, dev_blk_num=%u VolBytes=%s rate=%.1f KB/s\n" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 #, fuzzy msgid "Spooling statistics:\n" msgstr "Spooling des données...\n" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "Spooling des données...\n" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "Erreur pendant l'ouverture fichier de spool %s. ERR=%s\n" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" "Transfert des données spoolées sur le Volume \"%s\". Transfert de %s " "octets...\n" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" "Écriture des données spoolées sur le Volume. Transfert de %s octets...\n" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "Impossible de créer un JobMedia en base pour le Volume=%s Job=%s\n" #: src/stored/spool.c:335 #, fuzzy, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" "Temps du transfert des données spoolées = %02d:%02d:%02d, Taux de transfert " "= %s o/s\n" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, fuzzy, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "Taille du spool spécifiée par l'utlisateur atteinte.\n" #: src/stored/spool.c:481 #, fuzzy, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "Taille du spool spécifiée par l'utlisateur atteinte.\n" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "Reprise du spool des données...\n" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" "Erreur pendant l'écriture des données vers le fichier de spool. ERR=%s\n" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "" # Impossible d'ouvrir le fichier de spool des attributs : ERR=%s #: src/stored/spool.c:701 #, fuzzy, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier de spool des attributs %s : ERR=%s\n" # Impossible d'ouvrir le fichier de spool des attributs : ERR=%s #: src/stored/spool.c:716 #, fuzzy, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier de spool des attributs %s : ERR=%s\n" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" "Transfert des attributs spoolés au Director. Transfert de %s octets...\n" # Impossible d'ouvrir le fichier de spool des attributs : ERR=%s #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier de spool des attributs %s : ERR=%s\n" #: src/stored/reserve.c:84 #, fuzzy, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "Impossible d'initialiser le verrou sur la base. ERR=%s\n" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "" #: src/stored/reserve.c:258 #, fuzzy msgid "3939 Could not get dcr\n" msgstr "Impossible de créer la structure BSOCK cliente.\n" #: src/stored/reserve.c:366 #, fuzzy, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "Erreur sur la commande : %s\n" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" "3601 JobId=%u device %s est BLOQUÉ car il a été demonté par l'utilisateur.\n" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "3602 JobId=%u device %s est occupé (à lire ou écrire).\n" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "3603 JobId=%u device %s est occupé en lecture.\n" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" "3604 JobId=%u device %s est bloqué car il a été démonté par l'utilisateur " "(unmount).\n" #: src/stored/reserve.c:909 #, fuzzy, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" "3608 JobId=%u voulait le Pool=\"%s\", mais c'est le Pool=\"%s\" qui est dans " "le drive %s.\n" #: src/stored/reserve.c:932 #, fuzzy, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" "3607 JobId=%u voulait Vol=\"%s\", c'est le Vol=\"%s\" qui est dans le drive %" "s.\n" #: src/stored/reserve.c:944 #, fuzzy, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "" "3607 JobId=%u voulait Vol=\"%s\", c'est le Vol=\"%s\" qui est dans le drive %" "s.\n" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" "3605 JobId=%u voulait libérer le lecteur, mais le device %s est occupé.\n" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "3606 JobId=%u voulait un lecteur monté, mais le lecteur %s est vide.\n" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" "3607 JobId=%u voulait Vol=\"%s\", c'est le Vol=\"%s\" qui est dans le drive %" "s.\n" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "" #: src/stored/mac.c:454 #, fuzzy msgid "Read device not properly initialized.\n" msgstr " Le Device est en cours d'initialisation.\n" #: src/stored/mac.c:479 msgid "Cannot set buffer size SD->SD.\n" msgstr "" #: src/stored/mac.c:496 #, fuzzy, c-format msgid "Bad response to start replicate: %s\n" msgstr "Mauvaise réponse à la commande Hello : ERR=%s\n" #: src/stored/mac.c:501 #, fuzzy msgid "Bad response from stored to start replicate command\n" msgstr "" "Mauvaise réponse du File Daemon « %s:%d » à la commande Hello : ERR=%s\n" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "Bloc : %d taille=%d\n" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, fuzzy, c-format msgid "Unable to parse device %s.\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/backends/rados_device.c:62 #, fuzzy, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/backends/rados_device.c:69 #, fuzzy, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/stored/backends/rados_device.c:77 #, fuzzy, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/stored/backends/rados_device.c:89 #, fuzzy, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/stored/backends/rados_device.c:271 #, fuzzy, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/backends/rados_device.c:278 #, fuzzy, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, c-format msgid "Request for unknown devicetype: %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:317 #, fuzzy, c-format msgid "Unable to parse device URI %s.\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/backends/gfapi_device.c:329 #, fuzzy, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, fuzzy, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, fuzzy, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "%s doit être un répertoire.\n" #: src/stored/backends/cephfs_device.c:58 #, fuzzy, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/backends/cephfs_device.c:65 #, fuzzy, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/stored/backends/cephfs_device.c:72 #, fuzzy, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/backends/cephfs_device.c:101 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "%s doit être un répertoire.\n" #: src/stored/backends/cephfs_device.c:111 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "%s doit être un répertoire.\n" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, fuzzy, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "erreur de déplacement (lseek) sur %s : ERR=%s\n" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, fuzzy, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr " fichier=%d bloc=%d\n" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, fuzzy, c-format msgid "Failed to create a new context using config %s\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/stored/backends/object_store_device.c:190 #, fuzzy, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "3912 Impossible de labéliser le Volume : ERR=%s\n" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, fuzzy, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/stored/backends/object_store_device.c:274 #, fuzzy, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/stored/backends/object_store_device.c:298 #, fuzzy, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/stored/backends/object_store_device.c:406 #, fuzzy, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/stored/backends/object_store_device.c:416 #, fuzzy, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "Volume en cours d'utilisation :\n" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" "\n" "Statut du Device :\n" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "Autochangeur \"%s\" avec les Devices :\n" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 #, fuzzy msgid "waiting for" msgstr "En attente d'un montage" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 #, fuzzy msgid "waiting for sysop intervention" msgstr "attend son heure de démarrage" #: src/stored/status.c:275 #, fuzzy msgid "unknown state" msgstr "Erreur inconnue." #: src/stored/status.c:279 #, fuzzy, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Le Device %s est monté avec :\n" " Volume : %s\n" " Pool : %s\n" " Type du Media : %s\n" #: src/stored/status.c:289 #, fuzzy, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "Le Device %s est ouvert, mais il n'y a pas de Volume Bareos monté.\n" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr " Total Octets=%s Blocs=%s Octets/Bloc=%s\n" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr " Total des Octets lu=%s Blocs lu=%s Octets/Bloc=%s\n" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr " Positionné sur Fichier=%s Bloc=%s\n" #: src/stored/status.c:332 #, fuzzy, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "Le Device %s n'est pas ouvert.\n" #: src/stored/status.c:336 #, fuzzy, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "Le Device \"%s\" n'est pas ouvert ou il n'existe pas.\n" #: src/stored/status.c:369 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "Démon démarré depuis %s, %d jobs lancés depuis cette date.\n" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr " Le Device est BLOQUÉ. Démonté par l'utilisateur.\n" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" " Le Device est BLOQUÉ. Démonté par l'utilisateur à cause d'un chargement " "de média.\n" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" " Le Device est BLOQUÉ en attente du montage du volume \"%s\",\n" " Pool : %s\n" " Media type : %s\n" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" " Le Device est BLOQUÉ en attente de création d'un volume :\n" " Pool : %s\n" " Media type : %s\n" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr " Le Device est BLOQUÉ en attente d'un média.\n" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr " Le Device est en cours d'initialisation.\n" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr " Le Device est occupé à labéliser un Volume.\n" #: src/stored/status.c:523 #, fuzzy, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr " Le slot %d est chargé dans le lecteur %d.\n" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr " Le lecteur %d n'est pas chargé.\n" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 #, fuzzy msgid "Attached Jobs: " msgstr "" "\n" "Jobs planifiés :\n" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, fuzzy, c-format msgid " File=%u block=%u\n" msgstr "Fichier=%u bloc=%u\n" #: src/stored/status.c:610 #, fuzzy, c-format msgid " Min block=%u Max block=%u\n" msgstr "Min bloc=%u Max bloc=%u\n" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "%s Job %s est en attente de la connexion du Client.\n" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" "Lecture : %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" #: src/stored/status.c:662 #, fuzzy, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" "Ecriture : %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr " spooling=%d despooling=%d despool_wait=%d\n" #: src/stored/status.c:689 #, fuzzy, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr " Fichiers=%s Octets=%s Octets/sec=%s\n" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" "\n" "Jobs en attente de réservation de lecteur :\n" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "===================================================================\n" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "Base" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, fuzzy, c-format msgid "3900 No arg in status command: %s\n" msgstr "3909 Erreur pendant la lecture de la commande de montage : %s\n" #: src/stored/status.c:984 #, fuzzy, c-format msgid "3900 No arg in .status command: %s\n" msgstr "3909 Erreur pendant la lecture de la commande de montage : %s\n" #: src/stored/status.c:1033 #, fuzzy, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "Erreur inconnue." #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "Bareos Storage : En attente" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "Bareos Storage : En cours" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "Bareos Storage : Dernier Job annulé" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "Bareos Storage : Dernier Job en erreur" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "Bareos Storage : Le dernier Job avait des erreurs" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, fuzzy, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "Job non trouvé : %s\n" #: src/stored/sd_cmds.c:131 #, fuzzy msgid "Unable to authenticate Storage daemon\n" msgstr "Impossible de se connecter au Storage daemon.\n" #: src/stored/sd_cmds.c:182 #, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "" #: src/stored/sd_cmds.c:185 msgid "Command error with SD, hanging up.\n" msgstr "" #: src/stored/sd_cmds.c:197 #, fuzzy, c-format msgid "SD command not found: %s\n" msgstr "Job non trouvé : %s\n" #: src/stored/sd_cmds.c:338 #, fuzzy msgid "Replicate data error.\n" msgstr "Erreur non fatale" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, fuzzy, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "" "Connexion d'un Director inconnu %s à %s rejeté.\n" "\n" #: src/stored/authenticate.c:133 #, fuzzy, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "Password incorrect donné par le Director à %s.\n" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, fuzzy, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "Négociation TLS échouée avec le SD « %s:%d ».\n" #: src/stored/authenticate.c:257 #, fuzzy, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "" "Connexion d'un Director inconnu %s à %s rejeté.\n" "\n" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, fuzzy, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "Négociation TLS échouée avec le SD « %s:%d ».\n" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "Le job %d est annulé.\n" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, fuzzy, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "Impossible de supprimer le volume \"%s\". ERR=%s" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "Le volume \"%s\" contient des données, re-positionnement à la fin.\n" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "Le volume \"%s\" n'est pas dans le device %s.\n" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" "Le director voulait utiliser le volume \"%s\".\n" " Le volume courant \"%s\" n'est pas utilisable car :\n" " %s" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, fuzzy, c-format msgid "Could not reserve volume %s on %s\n" msgstr "Impossible de trouver le prochain volume pour le Job %s.\n" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "Prêt à ajouter des données à la fin du volume \"%s\" file=%d.\n" #: src/stored/mount.c:624 #, fuzzy, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" "Impossible d'écrire sur le volume \"%s\" \n" "car le nombre de fichiers ne correspond pas. Volume=%u Catalogue=%u\n" #: src/stored/mount.c:631 src/stored/mount.c:660 #, fuzzy msgid "Error updating Catalog\n" msgstr "Impossible d'ouvrir le fichier de données %s.\n" #: src/stored/mount.c:636 #, fuzzy, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" "Impossible d'écrire sur le volume \"%s\" \n" "car le nombre de fichiers ne correspond pas. Volume=%u Catalogue=%u\n" #: src/stored/mount.c:648 #, fuzzy, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" "Prêt à ajouter des données à la fin du volume \"%s\" part=%d size=%s\n" "\n" #: src/stored/mount.c:652 #, fuzzy, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" "Impossible d'écrire sur le volume \"%s\" car :\n" "Les tailles ne correspondent pas. Volume=%s Catalogue=%s\n" #: src/stored/mount.c:665 #, fuzzy, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" "Impossible d'écrire sur le volume \"%s\" car :\n" "Les tailles ne correspondent pas. Volume=%s Catalogue=%s\n" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "Le nouveau volume \"%s\" a été labélisé sur le device %s.\n" #: src/stored/mount.c:741 #, fuzzy, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "" "Attention, le device %s n'est pas configuré pour labéliser automatiquement " "les volumes.\n" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "Le volume \"%s\" est marqué en Erreur dans le catalogue.\n" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, fuzzy, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" "Fin du volume \"%s\" à %u:%u sur le device %s. Ecriture de %u octets, eu %" "d.\n" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "Impossible de lire le label du Volume depuis le média.\n" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "Le volume sur %s possède un mauvais label Bareos : %x\n" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "Impossible d'écrire le label du Volume sur le Device %s\n" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, fuzzy, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" "Recyclage du volume \"%s\" sur le lecteur %s, les précédentes données sont " "perdues.\n" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" "Écriture du label sur le Volume pré-labélisé \"%s\" sur le lecteur %s\n" #: src/stored/label.c:812 #, fuzzy, c-format msgid "Bad Volume session label = %d\n" msgstr "Le Volume n'a pas de label.\n" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, fuzzy, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "Impossible d'écrire un bloc. Le Device est au bout EOM.\n" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "Erreur d'écriture à %u:%u sur le device %s. ERR=%s\n" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" "Fin du volume \"%s\" à %u:%u sur le device %s. Ecriture de %u octets, eu %" "d.\n" #: src/stored/block.c:644 #, fuzzy, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "Erreur d'écriture à %u:%u sur le device %s. ERR=%s\n" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "Erreur sur la re-lecture du dernier bloc en EOT. ERR=%s" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "La re-lecture du dernier bloc écrit a réussi.\n" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 #, fuzzy msgid "Error sending Volume info to Director.\n" msgstr "Erreur pendant la récupération des informations sur un Volume : %s" #: src/stored/block.c:949 #, fuzzy msgid "Job failed or canceled.\n" msgstr "Le job %d est annulé.\n" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "Erreur pendant la récupération des informations sur un Volume : %s" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" "Le job %s a été annulé alors qu'il attendait un montage sur le Storage " "Device \"%s\".\n" #: src/stored/askdir.c:532 #, fuzzy, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Le Job %s est en attente. Bareos n'a pas pu trouver de media disponible.\n" "Merci de créer un nouveau volume via la commande « label » pour :\n" " Storage : %s\n" " Type du Media : %s\n" " Pool : %s\n" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" "Le Job %s a été annulé pendant qu'il attendait le montage sur le Storage " "Device %s.\n" #: src/stored/askdir.c:617 #, fuzzy, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Le Job %s est en attente. Bareos n'a pas pu trouver de media disponible.\n" "Merci de créer un nouveau volume via la commande « label » pour :\n" " Storage : %s\n" " Type du Media : %s\n" " Pool : %s\n" #: src/stored/askdir.c:623 #, fuzzy, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" "Le Job %s est en attente. Bareos n'a pas pu trouver de media disponible.\n" "Merci de créer un nouveau volume via la commande « label » pour :\n" " Storage : %s\n" " Type du Media : %s\n" " Pool : %s\n" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "Copyright (C) 2000-2005 Kern Sibbald.\n" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "%s doit être un répertoire.\n" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "%u fichiers restaurés.\n" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, fuzzy, c-format msgid "%s was deleted.\n" msgstr "Pas de job sélectionné.\n" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, fuzzy, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/stored/lock.c:489 #, fuzzy msgid "unknown blocked code" msgstr "source inconnue" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, fuzzy, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "Demande de labélisation du volume \"%s\" Slot %d...\n" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" "3304 Envoi de la commande « load slot %d, drive %d » à l'autochangeur.\n" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "3305 Autochangeur « load slot %d, drive %d », le résultat est OK.\n" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" "3992 Erreur sur l'autochangeur « load slot %d, drive %d » : ERR=%s.\n" "Resultat=%s\n" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "3301 Envoi de la commande « loaded? drive %d » à l'autochangeur.\n" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "3302 Autochangeur « loaded drive %d », le resultat est Slot %d.\n" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "3302 Autochangeur « loaded drive %d », résultat : lecteur vide.\n" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" "3991 Erreur sur l'autochangeur « loaded drive %d » : ERR=%s.\n" "Resultat=%s\n" #: src/stored/autochanger.c:310 #, fuzzy, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/stored/autochanger.c:324 #, fuzzy, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "rwl_writeunlock en échec sur %s:%d :. ERR=%s\n" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" "3307 Envoi de la commande « unload slot %d, drive %d » à l'autochangeur.\n" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" "3995 Erreur sur l'autochangeur « unload slot %d, drive %d » : ERR=%s.\n" "Resultat=%s\n" #: src/stored/autochanger.c:467 #, fuzzy, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "Le volume \"%s\" est utilisé par le device %s\n" #: src/stored/autochanger.c:535 #, fuzzy, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" "3995 Erreur sur l'autochangeur « unload slot %d, drive %d » : ERR=%s.\n" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "3993 Le Device %s n'est pas un autochangeur.\n" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "3306 Envoi de la commande \"%s\" à l'autochangeur.\n" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, fuzzy, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "Erreur sur l'autochangeur : ERR=%s\n" #: src/stored/autochanger.c:699 #, fuzzy msgid "3306 Issuing autochanger transfer command.\n" msgstr "3306 Envoi de la commande \"%s\" à l'autochangeur.\n" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, fuzzy, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "Le job %s est en attente de réservation d'un device.\n" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "Fin de Volume au fichier %u sur le Device %s, Volume \"%s\"\n" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "Fin de tous les Volumes.\n" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "Pas de volume spécifié pour la lecture. Abandon du job %s.\n" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" "Changement du Device de lecture. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, fuzzy, c-format msgid "Job %s canceled.\n" msgstr "Le job %s est annulé.\n" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "Prêt à lire les données du volume \"%s\" depuis le device %s.\n" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "Alert: %s" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, fuzzy, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, fuzzy, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "Impossible de créer le fichier d'état : %s ERR=%s\n" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, fuzzy, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, fuzzy, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "Impossible d'initialiser le verrou sur la base. ERR=%s\n" #: src/stored/bcopy.c:60 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version : %s (%s)\n" "\n" "Usage : stored [options] [-c config_file] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -dnn positionne le niveau de debug à nn\n" " -dt affiche un timestamp devant chaque ligne de debug\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -p continue même en cas d'erreurs E/S\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, fuzzy, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "Impossible d'initialiser %s\n" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "Impossible d'ouvrir le device %s\n" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "Impossible de monter le device %s\n" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 #, fuzzy msgid "Quota Exceeded. Job Terminated.\n" msgstr "Temps d'exécution maximum atteind. Abandon du job.\n" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, fuzzy, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, fuzzy, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, fuzzy, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/findlib/xattr.c:650 #, fuzzy, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, fuzzy, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:981 #, fuzzy, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, fuzzy, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, fuzzy, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, fuzzy, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:1453 #, fuzzy, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, fuzzy, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:1669 #, fuzzy, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, fuzzy, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:1931 #, fuzzy, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/findlib/xattr.c:1944 #, fuzzy, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/findlib/xattr.c:1965 #, fuzzy, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, fuzzy, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:2292 #, fuzzy, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/findlib/xattr.c:2321 #, fuzzy, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, fuzzy, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:2717 #, fuzzy, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:2799 #, fuzzy, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:2932 #, fuzzy, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/findlib/xattr.c:2955 #, fuzzy, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/findlib/xattr.c:3030 #, fuzzy, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/findlib/xattr.c:3070 #, fuzzy, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, fuzzy, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, fuzzy, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, fuzzy, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3195 #, fuzzy, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3288 #, fuzzy, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, fuzzy, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3395 #, fuzzy, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, fuzzy, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3459 #, fuzzy, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3499 #, fuzzy, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3517 #, fuzzy, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3535 #, fuzzy, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:3555 #, fuzzy, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" #: src/findlib/xattr.c:3621 #, fuzzy, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3644 #, fuzzy, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/xattr.c:3680 #, fuzzy, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/xattr.c:3708 #, fuzzy, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3801 #, fuzzy, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, fuzzy, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" #: src/findlib/find.c:180 #, fuzzy, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "Plugin=%s non trouvé.\n" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "" #: src/findlib/bfile.c:92 msgid "File data" msgstr "" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "" #: src/findlib/bfile.c:98 msgid "Compressed data" msgstr "" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "" #: src/findlib/bfile.c:106 msgid "Compressed sparse data" msgstr "" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:118 msgid "Win32 compressed data" msgstr "" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "" #: src/findlib/bfile.c:142 msgid "Encrypted compressed data" msgstr "" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:146 msgid "Encrypted Win32 Compressed data" msgstr "" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:168 msgid "TRU64 Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:170 msgid "TRU64 Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:172 msgid "Solaris Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:174 msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:176 msgid "AFS Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:178 msgid "AIX Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:180 msgid "AIX Specific NFSv4 ACL attribs" msgstr "" #: src/findlib/bfile.c:182 msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:184 msgid "GNU Hurd Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:186 msgid "GNU Hurd Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:188 msgid "GNU Hurd Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:190 msgid "IRIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:192 msgid "TRU64 Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:194 msgid "AIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:52 #, fuzzy, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier inclus : %s. ERR=%s\n" #: src/findlib/savecwd.c:63 #, fuzzy, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "change le répertoire courant" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, fuzzy, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "change le répertoire courant" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "" #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, fuzzy, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:352 #, fuzzy, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, fuzzy, c-format msgid "%s exists but is not a directory.\n" msgstr "%s doit être un répertoire.\n" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:261 #, fuzzy, c-format msgid "%c: is not a valid drive.\n" msgstr "%s : est une commande invalide.\n" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, fuzzy, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/find_one.c:268 #, c-format msgid "%s: mtime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:275 #, c-format msgid "%s: ctime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, c-format msgid "%s: size changed during backup.\n" msgstr "" #: src/findlib/find_one.c:729 #, fuzzy, c-format msgid "%s: File name too long [%d]\n" msgstr "Nom de Volume trop long.\n" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, fuzzy, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:293 #, fuzzy, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, fuzzy, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "Impossible de lire le certificat à partir du fichier" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, fuzzy, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:495 #, fuzzy, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:845 #, fuzzy, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:875 #, fuzzy, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:929 #, fuzzy, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" "Impossible de récupérer les informations du Media pour le Volume %s : ERR=%" "s\n" #: src/findlib/acl.c:935 #, fuzzy, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" "Impossible de récupérer les informations du Media pour le Volume %s : ERR=%" "s\n" #: src/findlib/acl.c:946 #, fuzzy, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:967 #, fuzzy, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1000 #, fuzzy, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1009 #, fuzzy, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, fuzzy, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, fuzzy, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1621 #, fuzzy, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, fuzzy, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1683 #, fuzzy, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1691 #, fuzzy, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1818 #, fuzzy, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, fuzzy, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, fuzzy, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, fuzzy, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:2084 #, fuzzy, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:2108 #, fuzzy, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:2128 #, fuzzy, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:2196 #, fuzzy, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:2225 #, fuzzy, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, fuzzy, c-format msgid "Unparseable size option: %s\n" msgstr "Option d'écrasement (Replace) invalide : %s\n" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, fuzzy, c-format msgid "Unexpected autodeflate setting on %s" msgstr "Attendait un type de lecteur, pas : %s\n" #: src/plugins/stored/autoxflate-sd.c:368 #, fuzzy, c-format msgid "Unexpected autoinflate setting on %s" msgstr "Attendait un type de lecteur, pas : %s\n" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, fuzzy, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "Erreur de décompression. ERR=%d\n" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 #, fuzzy msgid "Plugin File argument not specified.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/plugins/filed/bpipe-fd.c:916 #, fuzzy msgid "Plugin Reader argument not specified.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/plugins/filed/bpipe-fd.c:922 #, fuzzy msgid "Plugin Writer argument not specified.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, fuzzy, c-format msgid "Enter Key Encryption Key: " msgstr "Saisissez une nouvelle période de rétention : " #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, fuzzy, c-format msgid "Cannot open keyfile %s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, fuzzy, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/tools/bscrypto.c:401 #, fuzzy, c-format msgid "Enter Encryption Key: " msgstr "Saisissez une nouvelle période de rétention : " #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, fuzzy, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "erreur de fermeture : ERR=%s\n" #: src/tools/bsmtp.c:177 #, fuzzy, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version : %s (%s)\n" "\n" "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c utilise fich comme fichier de configuration\n" " -d positionne le niveau de debug à nn\n" " -dt affiche un timestamp devant chaque ligne de debug\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -r lance maintenant\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, fuzzy, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, fuzzy, c-format msgid "Failed to connect to mailhost %s\n" msgstr "Impossible de se connecter au Client.\n" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, fuzzy, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "erreur de fermeture : ERR=%s\n" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, fuzzy, c-format msgid "Unsupported digest type=%d specified\n" msgstr "Le cipher spécifié est non supporté\n" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 #, fuzzy msgid "BAREOS Message" msgstr "Message de Bareos" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "erreur de fermeture : ERR=%s\n" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" "La commande mail s'est terminée en erreur.\n" "CMD=%s\n" "ERR=%s\n" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, fuzzy, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" "La commande mail s'est terminée en erreur.\n" "CMD=%s\n" "ERR=%s\n" #: src/lib/message.c:1054 #, fuzzy, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "%s : Erreur Fatale car : " #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "%s : Erreur Fatale à %s:%d car :\n" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "%s : ERREUR : " #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "%s : ERREUR dans %s:%d " #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "%s : Attention : " #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, fuzzy, c-format msgid "%s JobId %u: Fatal error: " msgstr "%s : %s Erreur fatale : " #: src/lib/message.c:1601 #, fuzzy, c-format msgid "%s JobId %u: Error: " msgstr "%s : %s Erreur : " #: src/lib/message.c:1607 #, fuzzy, c-format msgid "%s JobId %u: Warning: " msgstr "%s : Attention : " #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "%s: exécution %s de la commande \"%s\"\n" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "Runscript : impossible d'exécuter %s. ERR=%s\n" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" "Runscript : %s s'est terminé avec un statut différent de 0 statut=%d. ERR=%" "s\n" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr " --> RunScript\n" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr " --> Command=%s\n" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr " --> Target=%s\n" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr " --> RunOnSuccess=%u\n" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr " --> RunOnFailure=%u\n" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr " --> RunWhen=%u\n" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "Le problème commence sûrement au début de la ligne %d.\n" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" "Erreur de config : %s\n" " : ligne %d, col %d du fichier %s\n" "%s\n" "%s" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "Erreur de config : %s\n" #: src/lib/lex.c:140 #, fuzzy, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" "Erreur de config : %s\n" " : ligne %d, col %d du fichier %s\n" "%s\n" "%s" #: src/lib/lex.c:144 #, fuzzy, c-format msgid "Config warning: %s\n" msgstr "Erreur de config : %s\n" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "none" #: src/lib/lex.c:360 msgid "comment" msgstr "comment" #: src/lib/lex.c:361 msgid "number" msgstr "number" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "ip_addr" # identifiant #: src/lib/lex.c:363 msgid "identifier" msgstr "identifier" #: src/lib/lex.c:364 msgid "string" msgstr "string" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "quoted_string" #: src/lib/lex.c:366 #, fuzzy msgid "include" msgstr "Depuis" #: src/lib/lex.c:367 #, fuzzy msgid "include_quoted_string" msgstr "quoted_string" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "attendait un nombre entier positif, pas : %s" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "Impossible d'ouvrir le fichier de configuration inclus %s : %s\n" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "attendait un entier ou bien un intervalle, pas %s : %s" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "attendait un nombre entier, pas %s : %s" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "attendait un nom, pas %s : %s" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "la longueur du nom %s (%d) est trop grande, le max est %d\n" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "attendait une chaîne, pas %s : %s" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "Backup" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "Vérification" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "Restauration" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "Archivage" #: src/lib/jcr.c:248 msgid "Copying" msgstr "Copier" #: src/lib/jcr.c:250 msgid "Migration" msgstr "Migrer" #: src/lib/jcr.c:252 #, fuzzy msgid "Scanning" msgstr "En cours" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "Opération inconnue" #: src/lib/jcr.c:265 msgid "backup" msgstr "backup" #: src/lib/jcr.c:267 msgid "verified" msgstr "vérifié" #: src/lib/jcr.c:269 msgid "restored" msgstr "Restauré" #: src/lib/jcr.c:269 msgid "restore" msgstr "restaurer" #: src/lib/jcr.c:271 msgid "archived" msgstr "archivé" #: src/lib/jcr.c:271 msgid "archive" msgstr "archiver" #: src/lib/jcr.c:273 msgid "copied" msgstr "copié" #: src/lib/jcr.c:273 msgid "copy" msgstr "copier" #: src/lib/jcr.c:275 msgid "migrated" msgstr "migrer" #: src/lib/jcr.c:275 msgid "migrate" msgstr "migré" #: src/lib/jcr.c:277 msgid "scanned" msgstr "scanné" #: src/lib/jcr.c:277 msgid "scan" msgstr "scanner" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "action inconnue" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "erreur sur pthread_key_create. ERR=%s\n" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "erreur sur pthread_once. ERR=%s\n" #: src/lib/jcr.c:394 #, fuzzy, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "Impossible d'initialiser la queue cliente : ERR=%s\n" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "NULL jcr.\n" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "JCR use_count=%d JobId=%d\n" #: src/lib/jcr.c:686 #, fuzzy, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" "Le watchdog a envoyé un signal après %d secs au thread bloqué en écoute du " "SD.\n" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" "Le watchdog a envoyé un signal après %d secs au thread bloqué en écoute du " "FD.\n" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" "Le watchdog a envoyé un signal après %d secs au thread bloqué en écoute du " "Director.\n" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "Impossible de trouver le userid %s : ERR=%s\n" #: src/lib/priv.c:67 #, fuzzy, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "Impossible de trouver le client %s : ERR=%s\n" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "Impossible de trouver le groupe=%s : ERR=%s\n" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" "Impossible d'utiliser initgroups pour le groupe=%s, userid=%s: ERR=%s\n" "\n" #: src/lib/priv.c:91 #, fuzzy, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/lib/priv.c:98 #, fuzzy, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/lib/priv.c:108 #, fuzzy, c-format msgid "prctl failed: ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/lib/priv.c:112 #, fuzzy, c-format msgid "setreuid failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/lib/priv.c:116 #, fuzzy, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/lib/priv.c:120 #, fuzzy, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "tout est ok" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "valeur hexadécimale incomplète" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "valeur hexadécimale invalide" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "valeur octal trop grande" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "valeur octal invalide" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "valeur octal incomplète" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "plus de mémoire" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "variable non définie" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "l'entrée n'est ni du texte ni une variable" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "argument invalide" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "opération indéfinie" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 msgid "unknown error" msgstr "erreur inconnue" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 msgid "Encryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:251 msgid "Encryption Mode: External\n" msgstr "" #: src/lib/scsi_crypto.c:256 msgid "Encryption Mode: Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 #, fuzzy msgid "Volume encryption status:\n" msgstr "Volume en cours d'utilisation :\n" #: src/lib/scsi_crypto.c:460 msgid "Compression Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:465 #, fuzzy msgid "Compression Status: Unavailable\n" msgstr "Statut disponible pour :\n" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 msgid "Encryption Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:495 #, fuzzy msgid "Encryption Status: Unavailable\n" msgstr "Statut disponible pour :\n" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 #, fuzzy msgid "Drive encryption status: Unknown\n" msgstr " Le statut du lecteur %d est inconnu.\n" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "Initialisation de la connexion TLS échouée.\n" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "Négociation TLS échouée.\n" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "TLS activé mais non configuré.\n" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "TLS actif mais non configuré.\n" #: src/lib/bnet.c:326 msgid "No problem." msgstr "Pas de problème." #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "Erreur inconnue." #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "sig inconnu %d" #: src/lib/crypto_cache.c:160 #, fuzzy, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "Impossible de créer le fichier d'état. %s ERR=%s\n" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 #, fuzzy msgid "Volumename" msgstr "Saisissez un nom de Volume : " #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 #, fuzzy msgid "EncryptionKey" msgstr "Saisissez une nouvelle période de rétention : " #: src/lib/crypto_cache.c:354 msgid "Added" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, fuzzy, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" #: src/lib/plugins.c:159 #, fuzzy, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "fopen %s en erreur : ERR=%s\n" # Impossible d'ouvrir le fichier de spool des attributs : ERR=%s #: src/lib/plugins.c:171 #, fuzzy, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "Impossible d'ouvrir le fichier de spool des attributs %s : ERR=%s\n" #: src/lib/plugins.c:274 #, fuzzy, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, fuzzy, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "Plus de mémoire : ERR=%s\n" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "Buffer overflow.\n" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "Mauvais errno" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "Impossible d'ouvrir le fichier contenant le pid. %s ERR=%s\n" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "Impossible d'ouvrir le fichier pid. %s ERR=%s\n" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "Impossible de créer le fichier d'état. %s ERR=%s\n" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "Impossible de détruire la queue cliente : ERR=%s\n" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "Impossible d'initialiser la queue cliente : ERR=%s\n" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "Impossible d'ajouter le job à la queue cliente : ERR=%s\n" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "Le processus fils est mort par le signal %d : %s" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 msgid "No error" msgstr "Pas d'erreur" #: src/lib/crypto.c:176 #, fuzzy msgid "Signer not found" msgstr "Le Storage \"%s\" est introuvable.\n" #: src/lib/crypto.c:178 #, fuzzy msgid "Recipient not found" msgstr "Ressource %s introuvable\n" #: src/lib/crypto.c:180 #, fuzzy msgid "Unsupported digest algorithm" msgstr "Le digest spécifié n'est pas supporté : %d\n" #: src/lib/crypto.c:182 #, fuzzy msgid "Unsupported encryption algorithm" msgstr "contentEncryptionAlgorithm non supporté : %d\n" #: src/lib/crypto.c:184 #, fuzzy msgid "Signature is invalid" msgstr "La création de la signature a échouée" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "Erreur interne" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "Erreur inconnue." #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "Erreur pendant la lecture des attributs : %s\n" #: src/lib/sellist.c:62 #, fuzzy msgid "Negative numbers not permitted.\n" msgstr "Les nombres négatifs ne sont pas autorisés\n" #: src/lib/sellist.c:99 #, fuzzy msgid "Selection items must be be greater than zero.\n" msgstr "Les valeurs doivent être supérieurs à zéro.\n" #: src/lib/sellist.c:103 #, fuzzy msgid "Selection item too large.\n" msgstr "Slot trop grand.\n" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, fuzzy, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "Impossible d'initialiser le muxtex : ERR=%s\n" #: src/lib/ini.c:262 src/lib/ini.c:274 #, fuzzy, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Erreur de config : %s\n" " : ligne %d, col %d du fichier %s\n" "%s\n" "%s" #: src/lib/ini.c:312 src/lib/ini.c:324 #, fuzzy, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Erreur de config : %s\n" " : ligne %d, col %d du fichier %s\n" "%s\n" "%s" #: src/lib/ini.c:560 src/lib/ini.c:672 #, fuzzy, c-format msgid "Cannot open config file %s: %s\n" msgstr "Impossible d'ouvrir le fichier de configuration \"%s\" : %s\n" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "Caractère illégal « %c » dans le nom.\n" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "Nom trop long.\n" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "Seulement l'ipv4 et l'ipv6 sont supportés (%d)\n" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "Seulement l'ipv4 est supporté (%d)\n" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "impossible de trouver une correspondance pour le service (%s)" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "impossible de résoudre le hostname (%s) %s" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "Impossible d'ajouter l'adresse par défaut (%s)\n" #: src/lib/tls_gnutls.c:124 #, fuzzy, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "" "Impossible de se positionner à la fin du média sur le device %s : ERR=%s\n" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, fuzzy, c-format msgid "Error loading CA certificates from %s\n" msgstr "Erreur dans le chargement du certificat" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, fuzzy, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "Erreur dans le chargement du certificat" #: src/lib/tls_gnutls.c:201 #, fuzzy, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "Erreur dans le chargement du certificat" #: src/lib/tls_gnutls.c:216 #, fuzzy, c-format msgid "Failed to load DH file %s\n" msgstr "Impossible de se connecter au Director\n" #: src/lib/tls_gnutls.c:224 #, fuzzy msgid "Failed to generate new DH parameters\n" msgstr "Impossible de positionner les paramètres TLS Diffie-Hellman" #: src/lib/tls_gnutls.c:289 #, fuzzy, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, fuzzy, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "rwl_writelock en échec sur %s:%d : ERR=%s\n" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "rwl_writeunlock en échec sur %s:%d :. ERR=%s\n" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "attendait un =, eu : %s" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "Impossible de trouver la ressource \"%s\" utilisée ligne %d : %s\n" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "Impossible de trouver la ressource \"%s\" utilisée ligne %d : %s\n" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "attendait une taille, eu : %s" #: src/lib/res.c:830 #, fuzzy, c-format msgid "expected a speed number, got: %s" msgstr "attendait une taille, eu : %s" #: src/lib/res.c:835 #, fuzzy msgid "unknown unit type encountered" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/lib/res.c:853 #, fuzzy, c-format msgid "expected a %s, got: %s" msgstr "attendait un =, eu : %s" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "Attendait un Label de lecteur, a pas : %s" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "Attendait un début de bloc {, pas : %s" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "Attendait une chaîne, pas : %s" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "Attentait la chaîne [ip|ipv4|ipv6], pas : %s" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "Attendait la chaîne [ip|ipv4], pas : %s" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "Attendait un égal =, pas : %s" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "Attendait un identifiant [addr|port], pas : %s" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "Seulement un port par bloc d'adresse" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "Seulement une adresse par bloc d'adresse" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "Attendait un nombre ou une chaîne, pas : %s" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "Attendait une adresse IP ou un nom de machine, pas : %s" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "Attendait une fin de bloc }, pas : %s" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" "Impossible d'ajouter le hostname (%s) et le port (%s) à la liste d'adresse (%" "s)" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "impossible d'ajouter le port (%s) à (%s)" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "Attendait un numéro de port ou une chaîne, pas : %s" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, fuzzy, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "Impossible d'initialiser la queue cliente : ERR=%s\n" #: src/lib/bsock.c:139 #, fuzzy msgid "attr spool I/O error.\n" msgstr "Erreur pendant l'écriture des attributs dans le spool. ERR=%s\n" #: src/lib/bsock.c:276 #, fuzzy, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" #: src/lib/bsock.c:311 #, fuzzy, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "Négociation TLS échouée avec le SD « %s:%d ».\n" #: src/lib/bsock.c:321 #, fuzzy, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "Mauvaise réponse à la commande Hello : ERR=%s\n" #: src/lib/bsock.c:330 #, fuzzy, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "Le File Daemon « %s:%d » a rejeté la commande Hello\n" #: src/lib/bsock.c:341 #, fuzzy, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" "Problème d'authentification avec le director.\n" "Le plus souvent, les mots de pass ne correspondent pas.\n" "Si vous utilisez TLS, il peut y avoir une erreur de validation du " "certificat\n" "pendant l'initialisation de la connexion TLS.\n" "Vous trouverez de l'aide sur\n" "http://doc.bareos.org/master/html/bareos-manual-main-reference." "html#AuthorizationErrors.\n" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" "Réessaie...\n" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/lib/bsock_tcp.c:186 #, fuzzy, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "Impossible de supprimer le volume \"%s\". ERR=%s" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "Ouverture de la socket en erreur. proto=%d port=%d. ERR=%s\n" #: src/lib/bsock_tcp.c:269 #, fuzzy, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "Ouverture de la socket en erreur. proto=%d port=%d. ERR=%s\n" #: src/lib/bsock_tcp.c:292 #, fuzzy, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "Impossible de positionner SO_KEEPALIVE sur la socket : %s\n" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, fuzzy, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "Erreur de lecture de %s:%s:%d : ERR=%s\n" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "Attendait %d en lecture, eu %d de %s:%s:%d\n" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "Erreur de lecture de %s:%s:%d : ERR=%s\n" #: src/lib/bsock_tcp.c:632 #, fuzzy msgid "Could not malloc BSOCK data buffer\n" msgstr "Impossible d'ouvrir la base de données \"%s\".\n" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "erreur sockopt : %s\n" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, fuzzy, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "erreur de fermeture : ERR=%s\n" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, fuzzy, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "erreur de fermeture : ERR=%s\n" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "Erreur pendant l'écriture des attributs dans le spool. ERR=%s\n" #: src/lib/devlock.c:322 msgid "writeunlock called too many times.\n" msgstr "" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, fuzzy, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Erreur de config : %s\n" " : ligne %d, col %d du fichier %s\n" "%s\n" "%s" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:542 #, fuzzy, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "erreur de fermeture : ERR=%s\n" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "" #: src/lib/daemon.c:56 #, fuzzy, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "Impossible de forker pour passer en mode démon : %s\n" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "" #: src/lib/parse_conf.c:149 #, fuzzy msgid "Config filename too long.\n" msgstr "Nom de Volume trop long.\n" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "Impossible d'ouvrir le fichier de configuration \"%s\" : %s\n" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "Attendait un identifiant de Ressource, a pas : %s" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "attendait un nom de ressource, eu : %s" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "mot clés inattendu %d %s dans la définition de la ressource" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "Plus de mémoire à l'allocation de %d octets\n" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "" #: src/lib/compression.c:88 msgid "GZIP compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:91 msgid "LZO2 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:94 msgid "LZFZ compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:97 msgid "LZ4 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:100 msgid "LZ4HC compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 #, fuzzy msgid "Failed to initialize ZLIB compression\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/lib/compression.c:215 #, fuzzy msgid "Failed to initialize LZO compression\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/lib/compression.c:270 #, fuzzy msgid "Failed to initialize FASTLZ compression\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/lib/compression.c:300 #, fuzzy msgid "LZO init failed\n" msgstr "Impossible de Rembobiner.\n" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "" #: src/lib/compression.c:371 #, fuzzy, c-format msgid "Compression LZO error: %d\n" msgstr "Erreur de décompression. ERR=%d\n" #: src/lib/compression.c:402 #, fuzzy, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "Erreur de décompression. ERR=%d\n" #: src/lib/compression.c:413 #, fuzzy, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "Erreur de décompression. ERR=%d\n" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "" #: src/lib/compression.c:592 #, fuzzy, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "Erreur de décompression. ERR=%d\n" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 msgid "Compressed data stream found, but compression not configured!\n" msgstr "" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "Erreur pendant l'initialisation du contexte SSL" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 #, fuzzy msgid "Error loading revocation list file" msgstr "Erreur dans le chargement du certificat" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "Erreur dans le chargement du certificat" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "Erreur dans le chargement de la clef privée" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "Impossible d'ouvrir le fichier de paramètre DH" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "Impossible de charger les paramètres DH à partir du fichier spécifié" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "Impossible de positionner les paramètres TLS Diffie-Hellman" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "Erreur pendant la création d'un nouvel objet SSL" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "Erreur de connexion" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 msgid "Running" msgstr "En cours" #: src/lib/util.c:214 msgid "Blocked" msgstr "Bloqué" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "Erreur Fatale" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "Erreur non fatale" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "Annulé" #: src/lib/util.c:238 msgid "Verify differences" msgstr "Vérification des différences" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "En attente du FD" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "En attente du SD" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "En attente d'un nouveau Volume" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "En attente d'un montage" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "En attente du Storage" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "" #: src/lib/util.c:302 #, fuzzy msgid "Completed successfully" msgstr "Restauration effectuée." #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "Terminé avec des avertissements" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "Terminé avec des erreurs" #: src/lib/util.c:311 msgid "Fatal error" msgstr "Erreur fatale" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "Créé, mais non démarré" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "Annulé par l'utilisateur" #: src/lib/util.c:320 #, fuzzy msgid "Verify found differences" msgstr "Vérification des différences" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "En attente du client" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "En attente du Storage" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "Attend qu'un job plus prioritaire se termine" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "Mise à jour du catalogue" #: src/lib/util.c:369 msgid "Differences" msgstr "" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "" #: src/lib/util.c:391 #, fuzzy msgid "Migrated Job" msgstr "Migrer" #: src/lib/util.c:394 msgid "Verify" msgstr "Vérifier" #: src/lib/util.c:397 msgid "Restore" msgstr "Restaurer" #: src/lib/util.c:400 msgid "Console" msgstr "" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "Admin" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "Archiver" #: src/lib/util.c:412 #, fuzzy msgid "Job Copy" msgstr "Copier" #: src/lib/util.c:415 msgid "Copy" msgstr "Copier" #: src/lib/util.c:418 msgid "Migrate" msgstr "Migrer" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "" #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "" #: src/lib/util.c:479 msgid "Verify Data" msgstr "" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 msgid "Append" msgstr "" #: src/lib/util.c:500 #, fuzzy msgid "Disabled" msgstr "est bloqué" #: src/lib/util.c:502 msgid "Used" msgstr "" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 #, fuzzy msgid "Recycle" msgstr "RecyclePool" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 #, fuzzy msgid "Invalid volume status" msgstr "Nom de Volume invalide : %s\n" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "" #: src/lib/signal.c:152 src/lib/signal.c:154 #, fuzzy, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "Bareos a reçu le signal %d : %s\n" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" "Kaboom ! %s, %s a reçu le signal %d - %s. Tentative de dump des traces.\n" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "Kaboom ! exepath=%s\n" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "Fork en erreur : ERR=%s\n" #: src/lib/signal.c:219 #, fuzzy, c-format msgid "Calling: %s %s %s %s\n" msgstr "Exécution : %s %s %s\n" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "execv : %s en échec : ERR=%s\n" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "BA_NSIG trop petit (%d) devrait être (%d)\n" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "SIGNAL INCONNU" #: src/lib/signal.c:323 msgid "Hangup" msgstr "Hangup" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "" #: src/lib/signal.c:325 msgid "Quit" msgstr "Quit" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "Abort" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "IOT trap" #: src/lib/signal.c:335 msgid "BUS error" msgstr "BUS error" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "Erreur de segmentation" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "Tube brisé" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "Alarm clock" #: src/lib/signal.c:343 msgid "Termination" msgstr "" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "Continue" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "Statut OK\n" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "Plus de mémoire\n" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "" #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr " pointeur NULL.\n" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr " Adresse du buffer : %p\n" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, fuzzy, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "Impossible d'ouvrir %s : ERR=%s\n" #: src/lib/scsi_lli.c:92 #, fuzzy, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, fuzzy, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, fuzzy, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/lib/scsi_lli.c:314 #, fuzzy, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/lib/scsi_lli.c:323 #, fuzzy, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "Impossible de se connecter au Director\n" #: src/lib/scsi_lli.c:348 #, fuzzy, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/lib/scsi_lli.c:464 #, fuzzy, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, fuzzy, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/lib/lockmgr.c:103 #, fuzzy, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "rwl_writeunlock en échec sur %s:%d :. ERR=%s\n" #: src/lib/lockmgr.c:613 #, fuzzy, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "Erreur sur l'ouverture du périphérique. ERR=%s\n" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "Impossible d'ouvrir de fichier de certificat" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "Impossible de lire le certificat à partir du fichier" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "Impossible d'extraire la clef publique à partir du certificat" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" "Le certificat fournis n'inclus pas l'extension subjectKeyIdentifier requise" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "Type de clef fourni non supporté : %d\n" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "Impossible d'ouvrir le fichier de clef privée" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "Impossible de lire la clef privée à partir du fichier" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "Le digest spécifié n'est pas supporté : %d\n" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "Initialisation du digest OpenSSL à échoué" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 #, fuzzy msgid "OpenSSL digest Verify final failed" msgstr "Initialisation du contexte clef/IV du cipher OpenSSL à échoué" #: src/lib/crypto_openssl.c:749 #, fuzzy msgid "No signers found for crypto verify.\n" msgstr "Aucun volume trouvé pour la restauration.\n" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "La création de la signature a échouée" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "Le décodage de la signature a échoué" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "Le cipher spécifié est non supporté\n" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "Le décodage du CryptoData a échoué" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "Impossible de décrypter la clef de session" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "contentEncryptionAlgorithm non supporté : %d\n" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "Initialisation du contexte clef/IV du cipher OpenSSL à échoué" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "Impossible d'initialiser le thread OpenSSL : ERR=%s\n" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "Impossible de sauvegarder le PRNG OpenSSL\n" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "Impossible de détruire le mutex : ERR=%s\n" #: src/lib/crypto_openssl.c:1615 #, fuzzy, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "Impossible de détruire le mutex : ERR=%s\n" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, fuzzy, c-format msgid "Could not set Finder Info on %s\n" msgstr "Impossible d'ouvrir le device %s\n" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 #, fuzzy msgid "Could not create digest.\n" msgstr "Impossible de créer la structure BSOCK cliente.\n" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "Impossible de décrypter la clef de session.\n" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, fuzzy, c-format msgid "Cannot open resource fork for %s.\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, fuzzy, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "Saisir la liste des fichiers à restaurer" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, fuzzy, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "contentEncryptionAlgorithm non supporté : %d\n" #: src/filed/restore.c:1112 #, fuzzy, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "contentEncryptionAlgorithm non supporté : %d\n" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 #, fuzzy msgid "Plugin save packet not found.\n" msgstr "le client \"%s\" est introuvable.\n" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "Plugin=%s non trouvé.\n" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, fuzzy, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/filed/crypto.c:214 #, fuzzy, c-format msgid "Digest one file failed for file: %s\n" msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 #, fuzzy msgid "Failed to initialize encryption context.\n" msgstr "Impossible d'initialiser le contexte TLS pour la Console \"%s\".\n" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "2001 Le job %s va être annulé.\n" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "2902 Erreur dans le décodage de la commande d'annulation.\n" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "2991 Erreur dans la commande setdebug : %s\n" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, fuzzy, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "Erreur dans la commande RunScript : %s\n" #: src/filed/dir_cmd.c:933 #, fuzzy, c-format msgid "Bad RunAfter command: %s\n" msgstr "Erreur dans la commande RunScript : %s\n" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "Erreur dans la commande RunScript : %s\n" #: src/filed/dir_cmd.c:1015 #, fuzzy, c-format msgid "Bad Plugin Options command: %s\n" msgstr "Erreur dans la commande RunScript : %s\n" #: src/filed/dir_cmd.c:1066 #, fuzzy, c-format msgid "Bad RestoreObject command: %s\n" msgstr "Erreur dans la commande RunScript : %s\n" #: src/filed/dir_cmd.c:1166 #, fuzzy msgid "2909 Bad RestoreObject command.\n" msgstr "2905 Erreur sur la commande RunScript.\n" #: src/filed/dir_cmd.c:1381 #, fuzzy, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" "L'horloge du client et du director ont %d secondes d'écart, le client s'est " "ajusté automatiquement.\n" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "Impossible de se connecter au démon Storage\n" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, fuzzy, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "Création des snapshot VSS. Driver=\"%s\", Lecteur(s)=\"%s\"\n" #: src/filed/dir_cmd.c:1696 #, fuzzy, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "Erreur durant la création des snapshots VSS.\n" #: src/filed/dir_cmd.c:1708 #, fuzzy, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "Erreur durant la création des snapshots VSS.\n" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, fuzzy, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "Impossible d'initialiser le verrou sur la base. ERR=%s\n" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, fuzzy, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "Attendait un niveau de remplacement, eu : %s" #: src/filed/filed.c:61 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Version : %s (%s)\n" "\n" "Usage : bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c utilise fich comme fichier de configuration\n" " -d positionne le niveau de debug à nn\n" " -dt affiche un timestamp sur chaque ligne de debug\n" " -f reste en avant-plan (pour debugger)\n" " -g groupid\n" " -s pas de signaux\n" " -t test - lit seulement le fichier de configuration\n" " -u userid\n" " -v affiche les messages utilisateurs\n" " -? affiche ce message.\n" "\n" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 #, fuzzy msgid "Failed to allocate a new keypair object.\n" msgstr "Impossible de se connecter au Director\n" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, fuzzy, c-format msgid "Unable to create MDB environment: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:81 #, fuzzy, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "Impossible de détruire le mutex : ERR=%s\n" #: src/filed/accurate_lmdb.c:90 #, fuzzy, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/filed/accurate_lmdb.c:97 #, fuzzy, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #: src/filed/accurate_lmdb.c:103 #, fuzzy, c-format msgid "Unable to start a write transaction: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:109 #, fuzzy, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, fuzzy, c-format msgid "Unable insert new data: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, fuzzy, c-format msgid "Unable close write transaction: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, fuzzy, c-format msgid "Unable to create write transaction: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:249 #, fuzzy, c-format msgid "Unable to create read transaction: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, fuzzy, c-format msgid "Unable to renew read transaction: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, fuzzy, c-format msgid "Unable create cursor: %s\n" msgstr "Impossible d'écrire le marqueur EOF. ERR=%s\n" #: src/filed/status.c:87 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "Démon démarré depuis %s, %d jobs lancés depuis cette date.\n" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "Connexion du director le %s\n" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, fuzzy, c-format msgid " %s%s %s Job started: %s\n" msgstr "Le job %d est annulé.\n" #: src/filed/status.c:201 #, fuzzy, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr " Fichiers=%s Octets=%s Octets/sec=%s Erreurs=%d\n" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "====\n" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "" "Connexion d'un Director inconnu %s à %s rejeté.\n" "\n" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "Password incorrect donné par le Director à %s.\n" #: src/filed/authenticate.c:301 #, fuzzy, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" "Connexion d'un Director inconnu %s à %s rejeté.\n" "\n" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, fuzzy, c-format msgid "Cannot verify checksum for %s\n" msgstr "Impossible de trouver la ressource Schedule \"%s\"\n" #: src/filed/accurate.c:312 #, fuzzy msgid "2991 Bad accurate command\n" msgstr "2991 Erreur dans la commande setdebug : %s\n" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, fuzzy, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "Erreur dans l'exécution de la commande : %s. stat=%d: ERR=%s\n" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, fuzzy, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "Impossible d'ouvrir le fichier %s : ERR=%s\n" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 #, fuzzy msgid "Failed to allocate memory for crypto signature.\n" msgstr "Impossible de se connecter au Director\n" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr " Impossible d'acceder à \"%s\" : ERR=%s\n" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr " Impossible de suivre le lien \"%s\" : ERR=%s\n" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr " Impossible d'acceder à \"%s\" : ERR=%s\\n\n" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr " Impossible d'ouvrir le répertoire \"%s\" : ERR=%s\n" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr " Type de fichier inconnu %d ; non sauvé : %s\n" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr " Impossible d'ouvrir \"%s\" : ERR=%s.\n" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:191 #, fuzzy, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "Client \"%s\" adresse positionné à %s\n" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:79 #, fuzzy, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" "Problème d'authentification avec le director.\n" "Le plus souvent, les mots de pass ne correspondent pas.\n" "Vous trouverez de l'aide sur\n" "http://doc.bareos.org/master/html/bareos-manual-main-reference." "html#AuthorizationErrors.\n" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "Mauvaise réponse à la commande Hello : ERR=%s\n" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "Le director a rejeté la commande Hello\n" #: src/qt-tray-monitor/authenticate.cpp:139 #, fuzzy msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" "Le mot de passe ou le nom du Director et du Client ne sont pas identiques.\n" #: src/qt-tray-monitor/authenticate.cpp:147 #, fuzzy, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" ") %s %s %s\n" "\n" "Usage : bconsole [-s] [-c config_file] [-d niveau_debug]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - lecture de la configuration et sortie\n" "\n" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 #, fuzzy msgid "Connected" msgstr "Connexion...\n" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "" #: src/qt-console/main.cpp:181 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" ") %s %s %s\n" "\n" "Usage : bconsole [-s] [-c config_file] [-d niveau_debug]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - lecture de la configuration et sortie\n" "\n" #: src/qt-console/bat_conf.cpp:152 #, fuzzy, c-format msgid "Console: name=%s\n" msgstr "Console connecté à %s\n" #: src/qt-console/bcomm/dircomm.cpp:84 #, fuzzy, c-format msgid "Already connected\"%s\".\n" msgstr "Console connecté à %s\n" #: src/qt-console/bcomm/dircomm.cpp:95 #, fuzzy, c-format msgid "Connecting to Director %s:%d" msgstr "Connexion au Director %s:%d\n" #: src/qt-console/bcomm/dircomm.cpp:97 #, fuzzy, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "Connexion au Director %s:%d\n" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:349 #, fuzzy msgid "Command completed ..." msgstr "Commande annulée.\n" #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:391 #, fuzzy msgid "Command failed." msgstr "Commande annulée.\n" #: src/qt-console/bcomm/dircomm.cpp:464 #, fuzzy msgid "Director disconnected." msgstr "Connexion du director le %s\n" #, fuzzy #~ msgid "sm_realloc %d at %p from %s:%d\n" #~ msgstr "Attendait %d en lecture, eu %d de %s:%s:%d\n" #, fuzzy #~ msgid "" #~ "Could not reserve volume \"%s\" for append, because it is read by an " #~ "other Job.\n" #~ msgstr "" #~ "Impossible de recycler le volume \"%s\" sur le device %s car il est " #~ "utilisé par un autre job.\n" #, fuzzy #~ msgid "@exec error: ERR=%s\n" #~ msgstr "erreur de fermeture : ERR=%s\n" #, fuzzy #~ msgid "Unable to load any shared library for .\n" #~ msgstr "Impossible de se connecter à %s sur %s:%d. ERR=%s\n" #, fuzzy #~ msgid "Run IncPool override\n" #~ msgstr "Sélectionnez le Pool" #, fuzzy #~ msgid "Run DiffPool override\n" #~ msgstr "Sélectionnez le Pool" #, fuzzy #~ msgid "Expected a Console Authentication Type keyword, got: %s" #~ msgstr "Attendait un type de Job de Migration, eu : %s" #~ msgid "Device record %s already exists\n" #~ msgstr "Le device %s existe déjà en base\n" #, fuzzy #~ msgid "" #~ "Director authorization problem.\n" #~ "Most likely the passwords do not agree.\n" #~ "If you are using TLS, there may have been a certificate validation error " #~ "during the TLS handshake.\n" #~ "Please see " #~ msgstr "" #~ "Problème d'authentification avec le director.\n" #~ "Le plus souvent, les mots de pass ne correspondent pas.\n" #~ "Si vous utilisez TLS, il peut y avoir une erreur de validation du " #~ "certificat\n" #~ "pendant l'initialisation de la connexion TLS.\n" #~ "Vous trouverez de l'aide sur\n" #~ "http://doc.bareos.org/master/html/bareos-manual-main-reference." #~ "html#AuthorizationErrors.\n" #, fuzzy #~ msgid "Prune expired records from catalog" #~ msgstr "purge les entrées expirées du catalogue" #, fuzzy #~ msgid "Plugin Options not yet implemented.\n" #~ msgstr "Le client est déjà spécifié.\n" #, fuzzy #~ msgid "" #~ "Client: name=%s protocol=%d authtype=%d address=%s FDport=%d MaxJobs=%u\n" #~ msgstr "Client \"%s\" adresse positionné à %s\n" #~ msgid "JobDefs" #~ msgstr "JobDefs" #~ msgid " --> RegexWhere=%s\n" #~ msgstr " --> RegexWhere=%s\n" #~ msgid " --> MaxRunTime=%u\n" #~ msgstr " --> MaxRunTime=%u\n" #~ msgid " --> MaxWaitTime=%u\n" #~ msgstr " --> MaxWaitTime=%u\n" #~ msgid " --> MaxStartDelay=%u\n" #~ msgstr " --> MaxStartDelay=%u\n" #, fuzzy #~ msgid " --> MaxRunSchedTime=%u\n" #~ msgstr " --> MaxRunTime=%u\n" #, fuzzy #~ msgid " --> Base %s\n" #~ msgstr " --> Target=%s\n" #, fuzzy #~ msgid " ScratchPool=%s\n" #~ msgstr "Utilisation du Catalogue \"%s\"\n" #, fuzzy #~ msgid " Catalog=%s\n" #~ msgstr "Utilisation du Catalogue \"%s\"\n" #~ msgid "2905 Bad RunScript command.\n" #~ msgstr "2905 Erreur sur la commande RunScript.\n" #~ msgid "Config token too long, file: %s, line %d, begins at line %d\n" #~ msgstr "Config token trop long, fichier : %s, ligne %d, débutant ligne %d\n" #~ msgid "Could not create client BSOCK.\n" #~ msgstr "Impossible de créer la structure BSOCK cliente.\n" #, fuzzy #~ msgid "TLS negotiation failed with FD at \"%s:%d\"\n" #~ msgstr "Négociation TLS échouée avec le FD « %s:%d ».\n" #~ msgid "Uncompression error. ERR=%d\n" #~ msgstr "Erreur de décompression. ERR=%d\n" #, fuzzy #~ msgid "LZO uncompression error. ERR=%d\n" #~ msgstr "Erreur de décompression. ERR=%d\n" #~ msgid "" #~ "====\n" #~ "\n" #~ msgstr "" #~ "====\n" #~ "\n" #~ msgid " Drive %d status unknown.\n" #~ msgstr " Le statut du lecteur %d est inconnu.\n" #, fuzzy #~ msgid "" #~ "No Client, Storage or Director resource defined in %s\n" #~ "Without that I don't how to get status from the File, Storage or Director " #~ "Daemon :-(\n" #~ msgstr "" #~ "Pas de director défini pour %s\n" #~ "Sans cette définition, il n'est pas possible de se connecter à celui-ci.\n" #, fuzzy #~ msgid "Director daemon" #~ msgstr "Director" #, fuzzy #~ msgid "Connecting to Client %s:%d" #~ msgstr "Connexion au client %s (%s:%d)\n" #, fuzzy #~ msgid "Connecting to Storage %s:%d" #~ msgstr "Connexion au Director %s:%d\n" #, fuzzy #~ msgid "Cannot connect to daemon." #~ msgstr "Impossible de se connecter au démon Storage\n" #, fuzzy #~ msgid "Authentication error : %s" #~ msgstr "Erreur sur l'autochangeur : ERR=%s\n" #, fuzzy #~ msgid "Opened connection with Director daemon." #~ msgstr "Impossible de se connecter au Storage daemon.\n" #, fuzzy #~ msgid "Opened connection with File daemon." #~ msgstr "Impossible de se connecter au client.\n" #, fuzzy #~ msgid "Opened connection with Storage daemon." #~ msgstr "Impossible de se connecter au Storage daemon.\n" #, fuzzy #~ msgid "Error : Connection closed." #~ msgstr "Connexion...\n" #~ msgid "Enter autochanger drive[0]: " #~ msgstr "Saisissez le numéro du lecteur de l'autochanger [0] : " #~ msgid "Bareos " #~ msgstr "Bareos " #, fuzzy #~ msgid "Expected one of: %s, got: %s" #~ msgstr "Attendait %s, a pas : %s" #, fuzzy #~ msgid "" #~ "%s %s %s (%s):\n" #~ " Build OS: %s %s %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Backup Level: %s%s\n" #~ " Client: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pool: \"%s\" (From %s)\n" #~ " Catalog: \"%s\" (From %s)\n" #~ " Storage: \"%s\" (From %s)\n" #~ " Scheduled time: %s\n" #~ " Start time: %s\n" #~ " End time: %s\n" #~ " Elapsed time: %s\n" #~ " Priority: %d\n" #~ " FD Files Written: %s\n" #~ " SD Files Written: %s\n" #~ " FD Bytes Written: %s (%sB)\n" #~ " SD Bytes Written: %s (%sB)\n" #~ " Rate: %.1f KB/s\n" #~ " Software Compression: %s\n" #~ "%s VSS: %s\n" #~ " Encryption: %s\n" #~ " Accurate: %s\n" #~ " Volume name(s): %s\n" #~ " Volume Session Id: %d\n" #~ " Volume Session Time: %d\n" #~ " Last Volume Bytes: %s (%sB)\n" #~ " Non-fatal FD errors: %d\n" #~ " SD Errors: %d\n" #~ " FD termination status: %s\n" #~ " SD termination status: %s\n" #~ " Termination: %s\n" #~ "\n" #~ msgstr "" #~ "%s %s %s (%s): %s\n" #~ " Build OS : %s %s %s\n" #~ " JobId : %d\n" #~ " Job : %s\n" #~ " Niveau de backup : %s%s\n" #~ " Client : \"%s\" %s\n" #~ " FileSet : \"%s\" %s\n" #~ " Pool : \"%s\" (Depuis %s)\n" #~ " Catalog: \"%s\" (Depuis %s)\n" #~ " Storage : \"%s\" (Depuis %s)\n" #~ " Date prévue : %s\n" #~ " Date de début : %s\n" #~ " Date de fin : %s\n" #~ " Temps écoulé : %s\n" #~ " Priorité : %d\n" #~ " Fichiers écrits FD : %s\n" #~ " Fichiers écrits SD : %s\n" #~ " Octets écrits FD : %s (%so)\n" #~ " Octets écrits SD : %s (%so)\n" #~ " Débit : %.1f Ko/s\n" #~ " Compression logicielle : %s\n" #~ " VSS : %s\n" #~ " Cryptage : %s\n" #~ " Accurate : %s\n" #~ " Nom des Volumes : %s\n" #~ " Volume Session Id : %d\n" #~ " Volume Session date : %d\n" #~ " Taille du volume : %s (%so)\n" #~ " Erreurs FD non fatales : %d\n" #~ " Erreurs du SD : %d\n" #~ " Statut de fin du FD : %s\n" #~ " Statut de fin du SD : %s\n" #~ " Statut de fin : %s\n" #~ "\n" #~ msgid "Attribute %s not found." #~ msgstr "Attribut %s non trouvé." #~ msgid "Priority must be 1-100" #~ msgstr "La priorité doit être comprise entre 1 et 100" #, fuzzy #~ msgid "" #~ "Written by Nicolas Boichat (2004)\n" #~ "\n" #~ "Version: %s (%s) %s %s %s\n" #~ "\n" #~ "Usage: tray-monitor [-c config_file] [-d debug_level]\n" #~ " -c set configuration file to file\n" #~ " -d set debug level to \n" #~ " -dt print timestamp in debug output\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ ") %s %s %s\n" #~ "\n" #~ "Usage : bconsole [-s] [-c config_file] [-d niveau_debug]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -s no signals\n" #~ " -t test - lecture de la configuration et sortie\n" #~ "\n" #, fuzzy #~ msgid "Bareos daemon status monitor" #~ msgstr "Bareos Storage : En cours" #, fuzzy #~ msgid "Bareos tray monitor" #~ msgstr "Bareos Storage : En cours" #, fuzzy #~ msgid "About" #~ msgstr "Abort" #, fuzzy #~ msgid "Disconnecting from Director %s:%d\n" #~ msgstr "Connexion au Director %s:%d\n" #, fuzzy #~ msgid "Disconnecting from Client %s:%d\n" #~ msgstr "Connexion au client %s (%s:%d)\n" #, fuzzy #~ msgid "Disconnecting from Storage %s:%d\n" #~ msgstr "Connexion au Director %s:%d\n" #~ msgid "Version" #~ msgstr "Version" #, fuzzy #~ msgid "" #~ "Current job: %s\n" #~ "Last job: %s" #~ msgstr "Le statut actuel du volume (Volume status) est : %s\n" #, fuzzy #~ msgid " (%d errors)" #~ msgstr "est en erreur" #, fuzzy #~ msgid " (%d error)" #~ msgstr "BUS error" #, fuzzy #~ msgid "No current job." #~ msgstr "Pas de RecyclePool courant\n" #, fuzzy #~ msgid "Job status: Running" #~ msgstr "Pas de job en cours.\n" #, fuzzy #~ msgid "Job status: Terminated" #~ msgstr "est terminé" #, fuzzy #~ msgid "Job status: Fatal error" #~ msgstr "%s : %s Erreur fatale : " #, fuzzy #~ msgid "Job status: Verify differences" #~ msgstr "Vérification des différences" #, fuzzy #~ msgid "Job status: Canceled" #~ msgstr "Le job %s est annulé.\n" #, fuzzy #~ msgid "Job status: Waiting on File daemon" #~ msgstr "%s Job %s est en attente de la connexion du Client.\n" #, fuzzy #~ msgid "Job status: Waiting on the Storage daemon" #~ msgstr "est en attente du Storage %s" #, fuzzy #~ msgid "Job status: Waiting for new media" #~ msgstr " Le Device est BLOQUÉ en attente d'un média.\n" #, fuzzy #~ msgid "Job status: Waiting for Mount" #~ msgstr "En attente d'un montage" #, fuzzy #~ msgid "Job status: Waiting for storage resource" #~ msgstr "En attente du Storage" #, fuzzy #~ msgid "Job status: Waiting for job resource" #~ msgstr "En attente du Storage" #, fuzzy #~ msgid "Job status: Waiting for Client resource" #~ msgstr "%s Job %s est en attente de la connexion du Client.\n" #, fuzzy #~ msgid "Job status: Waiting for start time" #~ msgstr "attend son heure de démarrage" #, fuzzy #~ msgid "Job status: Waiting for higher priority jobs to finish" #~ msgstr "attend qu'un job plus prioritaire se termine" #, fuzzy #~ msgid "Unknown job status %c." #~ msgstr "est dans un état inconnu %c" #, fuzzy #~ msgid "Connecting to Client %s:%d\n" #~ msgstr "Connexion au client %s (%s:%d)\n" #, fuzzy #~ msgid "Connecting to Storage %s:%d\n" #~ msgstr "Connexion au Director %s:%d\n" #, fuzzy #~ msgid "Cannot connect to daemon.\n" #~ msgstr "Impossible de se connecter au démon Storage\n" #, fuzzy #~ msgid "Opened connection with Director daemon.\n" #~ msgstr "Impossible de se connecter au Storage daemon.\n" #, fuzzy #~ msgid "Opened connection with File daemon.\n" #~ msgstr "Impossible de se connecter au client.\n" #, fuzzy #~ msgid "Opened connection with Storage daemon.\n" #~ msgstr "Impossible de se connecter au Storage daemon.\n" #, fuzzy #~ msgid "\n" #~ msgstr "%s : ERREUR : " #~ msgid "End of %s %u on device %s, Volume \"%s\"\n" #~ msgstr "Fin de %s %u sur le device %s, Volume \"%s\"\n" #, fuzzy #~ msgid "Cannot run free space command. Results=%s ERR=%s\n" #~ msgstr "Impossible de lancer la commande : %s. ERR=%s\n" #, fuzzy #~ msgid "Error writing part %d to the DVD: ERR=%s\n" #~ msgstr "Erreur dans l'exécution de la commande : %s. ERR=%s\n" #~ msgid "Ready to append to end of Volume \"%s\" part=%d size=%s\n" #~ msgstr "" #~ "Prêt à ajouter des données à la fin du volume \"%s\" part=%d size=%s\n" #~ "\n" #, fuzzy #~ msgid "" #~ "Bareos cannot write on DVD Volume \"%s\" because: The sizes do not match! " #~ "Volume=%s Catalog=%s\n" #~ msgstr "" #~ "Impossible d'écrire sur le volume \"%s\" car :\n" #~ "Les tailles ne correspondent pas. Volume=%s Catalogue=%s\n" #, fuzzy #~ msgid "Unable to open device part=%d %s: ERR=%s\n" #~ msgstr "3910 Impossible d'ouvrir le device %s : ERR=%s\n" #~ msgid "Could not initialize Python\n" #~ msgstr "Impossible d'initialiser le Python\n" #~ msgid "Could not Run Python string %s\n" #~ msgstr "Impossible de lancer la commande Python %s\n" #, fuzzy #~ msgid "Unable to initialize the Python lock. ERR=%s\n" #~ msgstr "Impossible d'initialiser le verrou sur la base. ERR=%s\n" #, fuzzy #~ msgid "Bad response to Hello command: ERR=" #~ msgstr "Mauvaise réponse à la commande Hello : ERR=%s\n" #, fuzzy #~ msgid "# Bareos bwx-console Configuration File\n" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Close without saving" #~ msgstr "Terminé avec des avertissements" #, fuzzy #~ msgid "Error while saving" #~ msgstr "Entrez le nombre de départ : " #, fuzzy #~ msgid "Enter restore mode" #~ msgstr "Saisissez le nom d'un répertoire : " #, fuzzy #~ msgid "Cancel restore" #~ msgstr "Annulé" #, fuzzy #~ msgid "Remove" #~ msgstr "Restaurer" #, fuzzy #~ msgid "Refresh" #~ msgstr "Restaurer" #, fuzzy #~ msgid "Size" #~ msgstr "Depuis" #, fuzzy #~ msgid "Job Name" #~ msgstr "Job échoué.\n" #, fuzzy #~ msgid "Before" #~ msgstr "Restaurer" #, fuzzy #~ msgid "Please configure parameters concerning files to restore :" #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid "if newer" #~ msgstr "Type" #, fuzzy #~ msgid "if older" #~ msgstr "FileSet" #, fuzzy #~ msgid "never" #~ msgstr "Type" #, fuzzy #~ msgid "Please configure parameters concerning files restoration :" #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid "Error : no clients returned by the director." #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Error : no filesets returned by the director." #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Error : no storage returned by the director." #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Error : no jobs returned by the director." #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "RestoreFiles" #~ msgstr "restauration de fichier" #, fuzzy #~ msgid "Please configure your restore parameters." #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid "Please select a client." #~ msgstr "Impossible de se connecter au Client.\n" #, fuzzy #~ msgid "Please select a restore date." #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid "Building restore tree..." #~ msgstr "" #~ "\n" #~ "Analyse des répertoires pour le JobId %s..." #, fuzzy #~ msgid "Error while starting restore: " #~ msgstr "Entrez le nombre de départ : " #, fuzzy #~ msgid " files selected to be restored." #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid " file selected to be restored." #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid "Please configure your restore (%ld files selected to be restored)..." #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #, fuzzy #~ msgid "Restore failed : no file selected.\n" #~ msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #, fuzzy #~ msgid "Restore failed : no file selected." #~ msgstr "Impossible de se connecter au Client.\n" #, fuzzy #~ msgid "Restoring, please wait..." #~ msgstr "string" #, fuzzy #~ msgid "Job queued. JobId=" #~ msgstr "Job mis en queue. JobId=%s\n" #, fuzzy #~ msgid "Restore queued, jobid=" #~ msgstr "Job démarré. JobId=%s\n" #, fuzzy #~ msgid "Job failed." #~ msgstr "Job échoué.\n" #, fuzzy #~ msgid "Restore failed, please look at messages.\n" #~ msgstr "Impossible de créer le fichier bootstrap %s : ERR=%s\n" #, fuzzy #~ msgid "Failed to retrieve jobid.\n" #~ msgstr "Impossible de se connecter au Client.\n" #, fuzzy #~ msgid "Restore job created, but not yet running." #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "Restore job running, please wait (%ld of %ld files restored)..." #~ msgstr "%s Job %s est en attente de la connexion du Client.\n" #, fuzzy #~ msgid "Restore job terminated successfully." #~ msgstr "Restauration non effectuée.\n" #, fuzzy #~ msgid "Restore job terminated successfully.\n" #~ msgstr "Restauration non effectuée.\n" #, fuzzy #~ msgid "Restore job terminated in error, see messages in console." #~ msgstr " Le Device est BLOQUÉ en attente d'un média.\n" #, fuzzy #~ msgid "Restore job terminated in error, see messages.\n" #~ msgstr " Le Device est BLOQUÉ en attente d'un média.\n" #, fuzzy #~ msgid "Restore job reported a non-fatal error." #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "Restore job reported a fatal error." #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "Restore job cancelled by user." #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "Restore job cancelled by user.\n" #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "Restore job is waiting on File daemon." #~ msgstr "%s Job %s est en attente de la connexion du Client.\n" #, fuzzy #~ msgid "Restore job is waiting for new media." #~ msgstr " Le Device est BLOQUÉ en attente d'un média.\n" #, fuzzy #~ msgid "Restore job is waiting for storage resource." #~ msgstr "En attente du Storage" #, fuzzy #~ msgid "Restore job is waiting for job resource." #~ msgstr "En attente du Storage" #, fuzzy #~ msgid "Restore job is waiting for Client resource." #~ msgstr "%s Job %s est en attente de la connexion du Client.\n" #, fuzzy #~ msgid "Restore job is waiting for maximum jobs." #~ msgstr "En attente du Storage" #, fuzzy #~ msgid "Restore job is waiting for start time." #~ msgstr "attend son heure de démarrage" #, fuzzy #~ msgid "Restore job is waiting for higher priority jobs to finish." #~ msgstr "attend qu'un job plus prioritaire se termine" #, fuzzy #~ msgid "Restore done successfully.\n" #~ msgstr "Restauration non effectuée.\n" #, fuzzy #~ msgid "Restore done successfully." #~ msgstr "Restauration non effectuée.\n" #, fuzzy #~ msgid "Applying restore configuration changes..." #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Failed to find the selected client." #~ msgstr "Impossible de se connecter au Client.\n" #, fuzzy #~ msgid "Failed to find the selected fileset." #~ msgstr "Impossible de se connecter au Client.\n" #, fuzzy #~ msgid "Failed to find the selected storage." #~ msgstr "Impossible de se connecter au Storage daemon.\n" #, fuzzy #~ msgid "Run Restore job" #~ msgstr "Sélectionnez le Job de restauration" #, fuzzy #~ msgid "Restore cancelled.\n" #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "Restore cancelled." #~ msgstr "Restauration annulée" #, fuzzy #~ msgid "No results to list." #~ msgstr "Liste vide.\n" #, fuzzy #~ msgid "No backup found for this client." #~ msgstr "Pas de job trouvé pour : %s.\n" #, fuzzy #~ msgid "ERROR" #~ msgstr "%s : ERREUR : " #, fuzzy #~ msgid "Query failed" #~ msgstr "Erreur sur la requête : %s\n" #, fuzzy #~ msgid "JobName:" #~ msgstr "Job échoué.\n" #, fuzzy #~ msgid "Bootstrap:" #~ msgstr "Bootstrap" #, fuzzy #~ msgid "Where:" #~ msgstr "Destination" #, fuzzy #~ msgid "Replace:" #~ msgstr "Écrasement :\n" #, fuzzy #~ msgid "ifnewer" #~ msgstr "Type" #, fuzzy #~ msgid "ifolder" #~ msgstr "FileSet" #, fuzzy #~ msgid "FileSet:" #~ msgstr "FileSet" #, fuzzy #~ msgid "Client:" #~ msgstr "Client" #, fuzzy #~ msgid "Storage:" #~ msgstr "Stockage" #, fuzzy #~ msgid "When:" #~ msgstr "Quand" #, fuzzy #~ msgid "Priority:" #~ msgstr "Priorité" #, fuzzy #~ msgid "Restoring..." #~ msgstr "string" #, fuzzy #~ msgid "" #~ "No Director resource defined in config file.\n" #~ "Without that I don't how to speak to the Director :-(\n" #~ msgstr "" #~ "Pas de director défini pour %s\n" #~ "Sans cette définition, il n'est pas possible de se connecter à celui-ci.\n" #, fuzzy #~ msgid "Error while initializing windows sockets...\n" #~ msgstr "Erreur pendant l'initialisation du contexte SSL" #, fuzzy #~ msgid "Error while cleaning up windows sockets...\n" #~ msgstr "Erreur pendant l'initialisation du contexte SSL" #, fuzzy #~ msgid "Error while initializing library." #~ msgstr "Erreur pendant l'initialisation du contexte SSL" #, fuzzy #~ msgid "Cryptographic library initialization failed.\n" #~ msgstr "Initialisation de la connexion TLS échouée.\n" #, fuzzy #~ msgid "Please correct configuration file.\n" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Error : Library not initialized\n" #~ msgstr "Impossible d'initialiser %s\n" #, fuzzy #~ msgid "Error : No configuration file loaded\n" #~ msgstr "La création de la signature a échouée" #~ msgid "Connecting...\n" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "Please choose a director (1-%d): " #~ msgstr "Aucun fichier sélectionné pour la restauration.\n" #~ msgid "Failed to connect to the director\n" #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Connected\n" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "Connection terminated\n" #~ msgstr "Sélection terminée.\n" #~ msgid "Type your command below:" #~ msgstr "Saisissez votre commande ci-dessous : " #, fuzzy #~ msgid "Unknown command." #~ msgstr "Erreur inconnue." #, fuzzy #~ msgid "Possible completions: " #~ msgstr "Les valeurs possibles sont :\n" #, fuzzy #~ msgid "Bareos bwx-console" #~ msgstr "Message de Bareos" #, fuzzy #~ msgid "Connect" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "Connect to the director" #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Disconnect" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "Disconnect of the director" #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Change of configuration file" #~ msgstr "La création de la signature a échouée" #, fuzzy #~ msgid "Change your default configuration file" #~ msgstr "Impossible de lire le certificat à partir du fichier" #, fuzzy #~ msgid "Edit your configuration file" #~ msgstr "La création de la signature a échouée" #, fuzzy #~ msgid "&File" #~ msgstr "FileSet" #, fuzzy #~ msgid "First run" #~ msgstr "est en cours" #, fuzzy #~ msgid "Unable to read configuration file" #~ msgstr "Impossible de lire le certificat à partir du fichier" #, fuzzy #~ msgid "Please choose a configuration file to use" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "" #~ "This configuration file has been successfully read, use it as default?" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Configuration file read successfully" #~ msgstr "La création de la signature a échouée" #, fuzzy #~ msgid "Using this configuration file: %s\n" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Connecting to the director..." #~ msgstr "Connexion au Director %s:%d\n" #, fuzzy #~ msgid "About Bareos bwx-console" #~ msgstr "Message de Bareos" #, fuzzy #~ msgid "Please choose your default configuration file" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Use this configuration file as default?" #~ msgstr "Merci de corriger le fichier de configuration : %s\n" #, fuzzy #~ msgid "Configuration file" #~ msgstr "La création de la signature a échouée" #, fuzzy #~ msgid "Console thread terminated." #~ msgstr "est terminé" #, fuzzy #~ msgid "Connection to the director lost. Quit program?" #~ msgstr "Connexion au Director %s:%d\n" #, fuzzy #~ msgid "Connection lost" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "Connected to the director." #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Reconnect" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "Reconnect to the director" #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Disconnected of the director." #~ msgstr "Impossible de se connecter au Director\n" #~ msgid "Network buffer size %d not multiple of tape block size.\n" #~ msgstr "" #~ "La taille du buffer réseau %d n'est pas un multiple de la taille de bloc " #~ "du lecteur.\n" #, fuzzy #~ msgid "Plugin load %s failed: ERR=%s\n" #~ msgstr "fopen %s en erreur : ERR=%s\n" #, fuzzy #~ msgid "VSS Writer (PreRestore): %s\n" #~ msgstr "Démarrage du Job de restauration %s\n" #, fuzzy #~ msgid "" #~ "Director and Storage daemon passwords or names not the same.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Problème d'authentification entre le storage et le director.\n" #~ "Le plus souvent, les mots de pass ne correspondent pas.\n" #~ "Vous trouverez de l'aide sur\n" #~ "http://www.bareos.org/rel-manual/faq.html#AuthorizationErrors\n" #, fuzzy #~ msgid "" #~ "Director and File daemon passwords or names not the same.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Problème d'authentification entre le client et le director.\n" #~ "Le plus souvent, les mots de pass ne correspondent pas.\n" #~ "Vous trouverez de l'aide sur\n" #~ "http://www.bareos.org/rel-manual/faq.html#AuthorizationErrors\n" #, fuzzy #~ msgid "" #~ "Incorrect authorization key from File daemon at %s rejected.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Problème d'authentification avec le director.\n" #~ "Le plus souvent, les mots de pass ne correspondent pas.\n" #~ "Vous trouverez de l'aide sur\n" #~ "http://www.bareos.org/rel-manual/faq.html#AuthorizationErrors\n" #~ msgid "" #~ "Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled " #~ "on this drive.\n" #~ msgstr "" #~ "Erreur lors de la création du snapshot VSS du lecteur « %c:\\\\ ». Le VSS " #~ "est désactivé sur ce lecteur.\n" #~ msgid "Daemon started %s, %d Job%s run since started.\n" #~ msgstr "Démon démarré le %s, %d job%s lancés depuis.\n" #, fuzzy #~ msgid "A dbi driver for DBI must be supplied.\n" #~ msgstr "Un nom d'utilisateur MySQL doit être fourni.\n" #~ msgid "Daemon started %s, 1 Job run since started.\n" #~ msgstr "Démon démarré depuis %s, 1 job lancé depuis cette date.\n" #~ msgid "Max sched run time exceeded. Job canceled.\n" #~ msgstr "" #~ "Temps d'exécution maximum depuis la planification atteind. Abandon du " #~ "job.\n" #~ msgid "3000 Job %s marked to be canceled.\n" #~ msgstr "3000 Job %s marqué pour être annulé.\n" #, fuzzy #~ msgid "Could not open DVD device %s. No Volume name given.\n" #~ msgstr "Le volume \"%s\" n'est pas dans le device %s.\n" #, fuzzy #~ msgid "There is no valid DVD in device %s.\n" #~ msgstr "Le volume \"%s\" n'est pas dans le device %s.\n" #, fuzzy #~ msgid "Could not mount DVD device %s.\n" #~ msgstr "Le volume \"%s\" n'est pas dans le device %s.\n" #~ msgid "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" #~ msgstr "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" #~ msgid "WARNING!!!! The Internal Database is NOT OPERATIONAL!\n" #~ msgstr "ATTENTION !!!! La base interne n'est pas OPÉRATIONNELLE !\n" #~ msgid "You should use SQLite, PostgreSQL, or MySQL\n" #~ msgstr "Vous devez utiliser SQLite, PostgreSQL, ou MySQL\n" #, fuzzy #~ msgid "Unable to open Catalog DB control file %s: ERR=%s\n" #~ msgstr "Impossible de créer le fichier bootstrap %s. ERR=%s\n" #, fuzzy #~ msgid "Could not connect to storage daemon" #~ msgstr "Impossible de se connecter au Storage daemon.\n" #, fuzzy #~ msgid "Job %s marked to be canceled.\n" #~ msgstr "Le job va être marqué annulé.\n" #, fuzzy #~ msgid "" #~ "cancel [jobid= job= ujobid=] -- \n" #~ " cancel a job" #~ msgstr "cancel [ | ] -- annulation d'un job" #, fuzzy #~ msgid "delete [volume= pool= job jobid=]" #~ msgstr "delete [pool= | media volume=]" #~ msgid "disable -- disable a job" #~ msgstr "disable -- désactive un job" #~ msgid "enable -- enable a job" #~ msgstr "enable -- active un job" #, fuzzy #~ msgid "" #~ "list [pools | jobs | jobtotals | media | \n" #~ " files | copies ]; from catalog" #~ msgstr "" #~ "list [pools | jobs | jobtotals | media | files " #~ "] -- depuis le catalogue" #~ msgid "messages" #~ msgstr "messages" #, fuzzy #~ msgid "use -- catalog xxx" #~ msgstr "utilise le catalogue xxx" #, fuzzy #~ msgid "No Client record defined for job %s\n" #~ msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #, fuzzy #~ msgid "No FileSet record defined for job %s\n" #~ msgstr "Pas de volume trouvé en base pour l'objet %d.\n" #, fuzzy #~ msgid "No Storage resource defined for job %s\n" #~ msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #, fuzzy #~ msgid "No Pool resource defined for job %s\n" #~ msgstr "La ressource Pool \"%s\" est introuvable !\n" #, fuzzy #~ msgid "No Catalog resource defined for client %s\n" #~ msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #, fuzzy #~ msgid "1 file (%s)" #~ msgstr "Nouveau Fichier : %s\n" #, fuzzy #~ msgid "%d files (%s)" #~ msgstr "Nouveau Fichier : %s\n" #, fuzzy #~ msgid "1 file selected (%s)" #~ msgstr "" #~ "\n" #~ "1 fichier sélectionne pour la restauration.\n" #~ "\n" #, fuzzy #~ msgid "%d files selected (%s)" #~ msgstr "" #~ "\n" #~ "1 fichier sélectionne pour la restauration.\n" #~ "\n" #, fuzzy #~ msgid "An error occurred while extracting files." #~ msgstr "Entrez le nombre de départ : " #, fuzzy #~ msgid "Command not found." #~ msgstr "Commande annulée.\n" #, fuzzy #~ msgid "Command exited abnormally." #~ msgstr "Commande annulée.\n" #, fuzzy #~ msgid "Do you want to create a new archive with these files?" #~ msgstr "" #~ "\n" #~ "Voulez vous restaurer tous les fichiers ? (oui|non) : " #, fuzzy #~ msgid "Create _Archive" #~ msgstr "Crée" #, fuzzy #~ msgid "Name" #~ msgstr "Job échoué.\n" #, fuzzy #~ msgid "Current Location:" #~ msgstr "Le slot courant est : %d\n" #, fuzzy #~ msgid "View selected file" #~ msgstr "" #~ "\n" #~ "%u fichiers sélectionnés pour la restauration.\n" #, fuzzy #~ msgid "Create _Folder" #~ msgstr "Crée" #, fuzzy #~ msgid "Couldn't find pixmap file: %s" #~ msgstr "Impossible d'ouvrir le fichier de données %s.\n" #, fuzzy #~ msgid "Bareos Console" #~ msgstr "Message de Bareos" #, fuzzy #~ msgid "Connect to Director" #~ msgstr "Impossible de se connecter au Director\n" #, fuzzy #~ msgid "Run" #~ msgstr "En cours" #, fuzzy #~ msgid "Label" #~ msgstr "Type" #, fuzzy #~ msgid "Enter Commands Here" #~ msgstr "Exécuter une requête SQL : " #, fuzzy #~ msgid " Status: " #~ msgstr "Statut :\n" #, fuzzy #~ msgid " " #~ msgstr " (" #, fuzzy #~ msgid "Bareos Console\n" #~ msgstr "Message de Bareos" #, fuzzy #~ msgid "Copyright (c) 2000 - 2004, Kern Sibbald and John Walker" #~ msgstr "" #~ "Copyright (C) 2000-2005 Kern Sibbald\n" #~ "\n" #~ "Version : " #, fuzzy #~ msgid "Select Director" #~ msgstr "Director" #, fuzzy #~ msgid "Job:" #~ msgstr "Job" #, fuzzy #~ msgid " " #~ msgstr " (" #, fuzzy #~ msgid "Level:" #~ msgstr "Type" #, fuzzy #~ msgid "Pool:" #~ msgstr "Pool" #, fuzzy #~ msgid "Messages:" #~ msgstr "messages" #, fuzzy #~ msgid "Where: " #~ msgstr "Destination" #, fuzzy #~ msgid "Restore File Selection" #~ msgstr "restauration de fichier" #, fuzzy #~ msgid "Current dir:" #~ msgstr "Le slot courant est : %d\n" #, fuzzy #~ msgid "Files Selected: " #~ msgstr "" #~ "\n" #~ "%u fichiers sélectionnés pour la restauration.\n" #, fuzzy #~ msgid "Label a Volume" #~ msgstr "labéliser une bande" #, fuzzy #~ msgid "Restore Files Dialog" #~ msgstr "restauration de fichier" #, fuzzy #~ msgid "Restore Files" #~ msgstr "restauration de fichier" #, fuzzy #~ msgid "Before:" #~ msgstr "Restaurer" #, fuzzy #~ msgid "Select Files" #~ msgstr "Saisissez le type" #, fuzzy #~ msgid "" #~ "\n" #~ "Version: %s (%s) %s %s %s\n" #~ "\n" #~ "Usage: bgnome-console [-s] [-c config_file] [-d debug_level] " #~ "[config_file]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -s no signals\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ ") %s %s %s\n" #~ "\n" #~ "Usage : bconsole [-s] [-c config_file] [-d niveau_debug]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -s no signals\n" #~ " -t test - lecture de la configuration et sortie\n" #~ "\n" #, fuzzy #~ msgid "Pthread cond init error = %s\n" #~ msgstr "Erreur pendant l'écriture des attributs dans le spool. ERR=%s\n" #, fuzzy #~ msgid " Not Connected" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid " Connecting to Director %s:%d" #~ msgstr "Connexion au Director %s:%d\n" #, fuzzy #~ msgid " Connected" #~ msgstr "Connexion...\n" #, fuzzy #~ msgid "File" #~ msgstr "FileSet" #, fuzzy #~ msgid "Director authorization problem.\n" #~ msgstr "Pas d'enregistrement trouvé en base pour : %s\n" #, fuzzy #~ msgid "" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Problème d'authentification entre le client et le director.\n" #~ "Le plus souvent, les mots de pass ne correspondent pas.\n" #~ "Vous trouverez de l'aide sur\n" #~ "http://www.bareos.org/rel-manual/faq.html#AuthorizationErrors\n" #, fuzzy #~ msgid "%s: Bad response to Hello command: ERR=%s\n" #~ msgstr "Mauvaise réponse à la commande Hello : ERR=%s\n" #, fuzzy #~ msgid "Can't restore ACLs of %s\n" #~ msgstr "Démarrage du Job de restauration %s\n" #~ msgid "Reposition from (file:block) %u:%u to %u:%u\n" #~ msgstr "Repositionnement de (fichier:bloc) %u:%u à %u:%u\n" #~ msgid "Cannot select %s in batch mode.\n" #~ msgstr "Impossible de choisir %s en mode batch.\n" #~ msgid "run " #~ msgstr "run -- lance un job" #~ msgid "status [storage | client]=" #~ msgstr "" #~ "status [storage | client]= -- affiche le statut d'un composant" #, fuzzy #~ msgid "Cannot find previous JobIds.\n" #~ msgstr "Impossible de trouver la ressource Job \"%s\"\n" #~ msgid "Enter new RecyclePool name: " #~ msgstr "Saisissez le nouveau RecyclePool : " #~ msgid "Start Migration JobId %s, Job=%s\n" #~ msgstr "Début de la Migration JobId %s, Job=%s\n" #~ msgid "No Volumes found to migrate.\n" #~ msgstr "Aucun volume trouvé pour la migration.\n" #, fuzzy #~ msgid "No JobIds found to migrate.\n" #~ msgstr "Aucun volume trouvé pour la restauration.\n" #~ msgid "" #~ "\n" #~ "%d Jobs, %s files inserted into the tree and marked for extraction.\n" #~ msgstr "" #~ "\n" #~ "%d Jobs, %s fichiers analysés et sélectionnés pour la restauration.\n" #~ msgid "" #~ "\n" #~ "%d Jobs, %s files inserted into the tree.\n" #~ msgstr "" #~ "\n" #~ "%d Jobs, %s fichiers analysés.\n" #~ msgid " (" #~ msgstr " (" #, fuzzy #~ msgid "Error updating DB Job file. ERR=%s\n" #~ msgstr "" #~ "Erreur pendant l'écriture des données vers le fichier de spool. ERR=%s\n" #, fuzzy #~ msgid "Error updating DB Media file. ERR=%s\n" #~ msgstr "Impossible de mettre à jour les informations du Volume : ERR=%s" #~ msgid "===Write error===\n" #~ msgstr "===Erreur d'écriture===\n" #~ msgid "Ready to append to end of Volume \"%s\" at file address=%u.\n" #~ msgstr "" #~ "Prêt à ajouter des données à la fin du volume \"%s\" file adress=%u.\n" #~ msgid "3901 open device failed: ERR=%s\n" #~ msgstr "3901 l'ouverture du device a échoué : ERR=%s\n" #, fuzzy #~ msgid "" #~ "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s" #~ "\" .\n" #~ msgstr "" #~ "Voulait le Volume \"%s\", mais le Device %s est occupé à écrire sur \"%s" #~ "\".\n" #, fuzzy #~ msgid "" #~ ") %s %s %s\n" #~ "\n" #~ "Usage: bconsole [-s] [-c config_file] [-d debug_level]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -n no conio\n" #~ " -s no signals\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ ") %s %s %s\n" #~ "\n" #~ "Usage : bconsole [-s] [-c config_file] [-d niveau_debug]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -s no signals\n" #~ " -t test - lecture de la configuration et sortie\n" #~ "\n" #~ msgid "%s: %s Warning: " #~ msgstr "%s : %s Attention : " #~ msgid "Cannot bind port %d: ERR=%s: retrying ...\n" #~ msgstr "Impossible de s'attacher au port %d : ERR=%s : Réessaie...\n" #~ msgid "Server socket" #~ msgstr "Socket serveur" #~ msgid "client" #~ msgstr "client" #, fuzzy #~ msgid " could not be installed" #~ msgstr "Bareos Storage : Dernier Job en erreur" #, fuzzy #~ msgid " has been removed" #~ msgstr "a été annulé" #, fuzzy #~ msgid " could not be removed" #~ msgstr "Impossible d'ouvrir le device %s\n" #~ msgid "get_char: called after EOF\n" #~ msgstr "get_char : appelé après EOF\n" #, fuzzy #~ msgid "Bareos Usage" #~ msgstr "Message de Bareos" #, fuzzy #~ msgid "Unable to get Volume record: ERR=%s" #~ msgstr "Impossible de mettre à jour les informations du Volume : ERR=%s" #~ msgid "Unable to update Volume record: ERR=%s" #~ msgstr "Impossible de mettre à jour les informations du Volume : ERR=%s" #~ msgid "Do you want to continue? (yes|no): " #~ msgstr "Voulez vous continuer ? (oui/non) : " #, fuzzy #~ msgid "Invalid MediaId found.\n" #~ msgstr "Période invalide.\n" #~ msgid "Device %s is mounted with Volume=\"%s\" Pool=\"%s\"\n" #~ msgstr "Le Device %s est monté avec le Volume=\"%s\" Pool=\"%s\"\n" #, fuzzy #~ msgid "Forbidden \"where\" specified.\n" #~ msgstr "La destination (Where) est déjà spécifiée.\n" #~ msgid "Please mount Volume \"%s\" on Storage Device %s for Job %s\n" #~ msgstr "" #~ "Merci de monter le Volume \"%s\" sur le Storage Device \"%s\" pour le Job " #~ "%s\n" #~ msgid "Job %s not found.\n" #~ msgstr "Job %s non trouvé.\n" #~ msgid "%s Version: %s (%s)\n" #~ msgstr "%s Version : %s (%s)\n" #~ msgid "There are no Jobs associated with Volume \"%s\". Prune not needed.\n" #~ msgstr "" #~ "Il n'y a pas de job associé avec le volume \"%s\". Pas besoin de purger " #~ "le catalogue (prune).\n" #~ msgid "" #~ "There are no Jobs associated with Volume \"%s\". Marking it purged.\n" #~ msgstr "" #~ "Il n'y a pas de job associé avec le volume \"%s\". Il doit être marqué\n" #~ "comme purgé.\n" #~ msgid "Pruned %d %s on Volume \"%s\" from catalog.\n" #~ msgstr "Purge du catalogue (prune) de %d %s sur le volume \"%s\".\n" #~ msgid "%d Files for client \"%s\" purged from %s catalog.\n" #~ msgstr "%d fichiers du client \"%s\" purgé du catalogue %s.\n" #~ msgid "No Jobs found for client %s to purge from %s catalog.\n" #~ msgstr "Pas de job à purger pour le client \"%s\" dans le catalogue %s.\n" #~ msgid "" #~ "Run Restore job\n" #~ "JobName: %s\n" #~ "Bootstrap: %s\n" #~ "Where: %s\n" #~ "Replace: %s\n" #~ "FileSet: %s\n" #~ "Client: %s\n" #~ "Storage: %s\n" #~ "When: %s\n" #~ "Catalog: %s\n" #~ "Priority: %d\n" #~ msgstr "" #~ "Lancement de la restauration\n" #~ "JobName : %s\n" #~ "Bootstrap : %s\n" #~ "Destination : %s\n" #~ "Écrasement : %s\n" #~ "FileSet : %s\n" #~ "Client : %s\n" #~ "Storage : %s\n" #~ "Quand : %s\n" #~ "Catalogue : %s\n" #~ "Priorité : %d\n" #~ msgid "Item 1 selected automatically.\n" #~ msgstr "Sélection automatique de l'objet 1.\n" #~ msgid "OpenSSL error occured" #~ msgstr "Une erreur OpenSSL s'est produite" #~ msgid "Device %s is busy reading.\n" #~ msgstr "Le device %s est occupé en lecture.\n" #, fuzzy #~ msgid "Job started. JobId=" #~ msgstr "Job démarré. JobId=%s\n" #, fuzzy #~ msgid "NextPool in Pool resource" #~ msgstr "Sélectionnez le Pool" #~ msgid "%s: is an illegal command.\n" #~ msgstr "%s : est une commande invalide.\n" #, fuzzy #~ msgid "\"%s\" is an illegal command\n" #~ msgstr "%s est une commande invalide\n" #, fuzzy #~ msgid "" #~ ")\n" #~ "\n" #~ "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" #~ " -c set configuration file to file\n" #~ " -dnn set debug level to nn\n" #~ " -f run in foreground (for debugging)\n" #~ " -r run now\n" #~ " -s no signals\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ "Copyright (C) 2000-2005 Kern Sibbald.\n" #~ "\n" #~ "Version : %s (%s)\n" #~ "\n" #~ "Usage : dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" #~ " -c utilise fich comme fichier de configuration\n" #~ " -dnn positionne le niveau de debug à nn\n" #~ " -f reste en avant-plan (pour debugger)\n" #~ " -g groupid\n" #~ " -r lance maintenant\n" #~ " -s pas de signaux\n" #~ " -t test - lit seulement le fichier de configuration\n" #~ " -u userid\n" #~ " -v affiche les messages utilisateurs\n" #~ " -? affiche ce message.\n" #~ "\n" #, fuzzy #~ msgid "" #~ "Copyright (C) 2004-2006 Kern Sibbald\n" #~ "Written by Nicolas Boichat\n" #~ msgstr "" #~ "Copyright (C) 2000-2005 Kern Sibbald\n" #~ "\n" #~ "Version : " #~ msgid "Using default Catalog name=%s DB=%s\n" #~ msgstr "Utilisation du Catalogue par défaut name=%s DB=%s\n" #, fuzzy #~ msgid "3912 Failed to truncate previous DVD volume.\n" #~ msgstr "3912 Impossible de labéliser le Volume : ERR=%s\n" #~ msgid "Write EOF failed.\n" #~ msgstr "Impossible d'écrire le EOF.\n" #~ msgid "Success" #~ msgstr "Succès" #~ msgid "No match" #~ msgstr "Aucune correspondance" #~ msgid "Invalid regular expression" #~ msgstr "Expression régulière invalide" #~ msgid "Invalid back reference" #~ msgstr "Référence arrière invalide" #~ msgid "Regular expression too big" #~ msgstr "Expression régulière trop grande" #~ msgid "Could not get %d bytes of shared memory: %s\n" #~ msgstr "Impossible de récupérer %d octets de mémoire partagée : %s\n" #~ msgid "catalog" #~ msgstr "catalog" #~ msgid "fd" #~ msgstr "fd" #~ msgid "========================================================================\n" #~ msgstr "========================================================================\n" #~ msgid "readlabel %s Slot=%d drive=%d\n" #~ msgstr "readlabel %s Slot=%d drive=%d\n" #~ msgid "autochanger list %s \n" #~ msgstr "autochanger list %s \n" #~ msgid "autochanger slots %s\n" #~ msgstr "autochanger slots %s\n" #~ msgid "autochanger drives %s\n" #~ msgstr "autochanger drives %s\n" #~ msgid "No MediaType found for your JobIds.\n" #~ msgstr "Pas de MediaType trouvé pour vos JobIds\n" #~ msgid "off" #~ msgstr "off" #~ msgid "jobid" #~ msgstr "jobid" #~ msgid "job" #~ msgstr "job" #~ msgid "restart" #~ msgstr "restart" #~ msgid "" #~ "\n" #~ "%s Version: %s (%s) %s %s %s\n" #~ msgstr "" #~ "\n" #~ "%s Version : %s (%s) %s %s %s\n" bareos-Release-14.2.6/po/insert-header.sin000066400000000000000000000012401263011562700203200ustar00rootroot00000000000000# Sed script that inserts the file called HEADER before the header entry. # # At each occurrence of a line starting with "msgid ", we execute the following # commands. At the first occurrence, insert the file. At the following # occurrences, do nothing. The distinction between the first and the following # occurrences is achieved by looking at the hold space. /^msgid /{ x # Test if the hold space is empty. s/m/m/ ta # Yes it was empty. First occurrence. Read the file. r HEADER # Output the file's contents by reading the next line. But don't lose the # current line while doing this. g N bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } bareos-Release-14.2.6/po/it.po000066400000000000000000014152261263011562700160450ustar00rootroot00000000000000# Italian translations for Bareos package # Traduzioni italiane per il pacchetto Bareos.. # Copyright (C) 2005-2006 Free Software Foundation Europe e.V. # , 2005. # msgid "" msgstr "" "Project-Id-Version: Bareos 1.38\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2005-08-08 17:50+0200\n" "Last-Translator: \n" "Language-Team: Italian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "" #: src/cats/sql.c:789 msgid "Could not init database batch connection\n" msgstr "" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:260 #, c-format msgid "More than one Device!: %d\n" msgstr "" #: src/cats/sql_create.c:265 #, c-format msgid "error fetching Device row: %s\n" msgstr "" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1316 #, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1367 #, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1399 #, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1442 #, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1499 #, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1543 #, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 msgid "Could not init database connection" msgstr "" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "" #: src/cats/ingres.c:82 msgid "Failed to allocate space for query filter.\n" msgstr "" #: src/cats/ingres.c:103 msgid "Failed to allocate space for query filters.\n" msgstr "" #: src/cats/ingres.c:257 #, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" #: src/cats/ingres.c:1031 msgid "A user name for Ingres must be supplied.\n" msgstr "" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 msgid "Quota record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 msgid "Catalog Backends Dir not configured.\n" msgstr "" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:236 #, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "" #: src/console/console_conf.c:143 #, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" #: src/console/console.c:170 msgid "input from file" msgstr "" #: src/console/console.c:171 msgid "output to file" msgstr "" #: src/console/console.c:172 msgid "quit" msgstr "" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "" #: src/console/console.c:174 msgid "sleep specified time" msgstr "" #: src/console/console.c:175 msgid "print current time" msgstr "" #: src/console/console.c:176 msgid "print Console's version" msgstr "" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "" #: src/console/console.c:179 msgid "exit = quit" msgstr "" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "" #: src/console/console.c:181 msgid "help listing" msgstr "" #: src/console/console.c:183 msgid "set command separator" msgstr "" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr "" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "" #: src/console/console.c:996 #, c-format msgid "Can't find %s in Director list\n" msgstr "" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "" #: src/console/console.c:1600 #, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "" #: src/console/console.c:1612 #, c-format msgid "Autochanger error: ERR=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, c-format msgid "Could not get storage resource '%s'.\n" msgstr "" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 msgid "TLS required but not configured in BAREOS.\n" msgstr "" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "" #: src/dird/dird.c:1110 #, c-format msgid "Could not create storage record for %s\n" msgstr "" #: src/dird/dird.c:1119 #, c-format msgid "Could not update storage record for %s\n" msgstr "" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, c-format msgid "Error getting Quota value: ERR=%s" msgstr "" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:88 #, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:102 #, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:170 #, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:312 msgid "rerun these jobids? (yes/no): " msgstr "" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 msgid "Level" msgstr "" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "" #: src/dird/ua_run.c:555 msgid "Restore Client" msgstr "" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "" #: src/dird/ua_run.c:559 msgid "Backup Format" msgstr "" #: src/dird/ua_run.c:560 msgid "When" msgstr "" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "" #: src/dird/ua_run.c:571 msgid "NextPool" msgstr "" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "" #: src/dird/ua_run.c:582 msgid "Where" msgstr "" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 msgid "Please enter Backup Format: " msgstr "" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "" #: src/dird/ua_run.c:730 msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 msgid "Please enter Plugin Options string: " msgstr "" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 msgid "Storage from Run NextPool override" msgstr "" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, c-format msgid "Level \"%s\" not valid.\n" msgstr "" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 msgid "Please enter the path prefix to strip: " msgstr "" #: src/dird/ua_run.c:1035 msgid "Please enter the path prefix to add (/ for none): " msgstr "" #: src/dird/ua_run.c:1046 msgid "Please enter the file suffix to add: " msgstr "" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "" #: src/dird/ua_run.c:1438 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1498 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "" #: src/dird/ua_run.c:1546 #, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "" #: src/dird/ua_run.c:1602 msgid "Run Migration job\n" msgstr "" #: src/dird/ua_run.c:1604 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1870 msgid "NextPool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1886 msgid "Restore Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1894 msgid "Plugin Options specified twice.\n" msgstr "" #: src/dird/ua_run.c:1899 msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "" #: src/dird/ua_run.c:1906 msgid "Spool flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "" #: src/dird/ua_run.c:1922 msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1929 msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "" #: src/dird/ua_run.c:1934 msgid "Accurate flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1941 msgid "Invalid accurate flag.\n" msgstr "" #: src/dird/ua_run.c:1946 msgid "Backup Format specified twice.\n" msgstr "" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "" #: src/dird/ua_status.c:390 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 msgid "No clients defined.\n" msgstr "" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 msgid "Schedule" msgstr "" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "" #: src/dird/ua_status.c:1034 msgid "has terminated with warnings" msgstr "" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, c-format msgid "is waiting on Storage \"%s\"" msgstr "" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, c-format msgid "is waiting for its start time at %s" msgstr "" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 msgid "is waiting for Client to connect to Storage daemon" msgstr "" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "" #: src/dird/ua_status.c:1177 #, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 msgid "No Volumes found, or no barcodes.\n" msgstr "" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr "" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, c-format msgid "Unknown command: %s\n" msgstr "" #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "" #: src/dird/ua_dotcmds.c:1116 #, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1130 #, c-format msgid "List Media failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1156 #, c-format msgid "List Location failed: ERR=%s\n" msgstr "" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "" #: src/dird/ua_input.c:218 msgid "Comment too long.\n" msgstr "" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "" #: src/dird/ua_cmds.c:112 msgid "Configure director" msgstr "" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 msgid "Disable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 msgid "Print current memory usage" msgstr "" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "" #: src/dird/ua_cmds.c:164 msgid "Move slots in an autochanger" msgstr "" #: src/dird/ua_cmds.c:166 msgid "Prune records from catalog" msgstr "" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "" #: src/dird/ua_cmds.c:175 msgid "Restore files" msgstr "" #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 msgid "Rerun a job" msgstr "" #: src/dird/ua_cmds.c:192 msgid "Resolve a hostname" msgstr "" #: src/dird/ua_cmds.c:194 msgid "Run a job" msgstr "" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 msgid "Show resource records" msgstr "" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 msgid "Print current time" msgstr "" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 msgid "Use specific catalog" msgstr "" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 msgid "Print Director version" msgstr "" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, c-format msgid "JobId %s not a number\n" msgstr "" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "" #: src/dird/ua_cmds.c:793 msgid "Failed to set bandwidth limit on Client.\n" msgstr "" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:843 msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, c-format msgid "Client \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1495 msgid "Storage name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1520 #, c-format msgid "%s Failed to resolve %s\n" msgstr "" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, c-format msgid "%s resolves %s to %s\n" msgstr "" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "" #: src/dird/ua_cmds.c:1667 msgid "Accurate value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "" #: src/dird/ua_cmds.c:1696 #, c-format msgid "Wrong job specified of type %s.\n" msgstr "" #: src/dird/ua_cmds.c:1709 msgid "No client specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1714 msgid "No fileset specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, c-format msgid "Illegal JobId %s ignored\n" msgstr "" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "" #: src/dird/ua_cmds.c:1979 #, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr "" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:581 #, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:661 #, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "" #: src/dird/ua_select.c:307 #, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "" #: src/dird/ua_select.c:378 msgid "Select Client resource" msgstr "" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "" #: src/dird/ua_select.c:421 msgid "The defined Schedule resources are:\n" msgstr "" #: src/dird/ua_select.c:432 msgid "Select Schedule resource" msgstr "" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "" #: src/dird/ua_select.c:1093 msgid "Select Drive:\n" msgstr "" #: src/dird/ua_select.c:1098 msgid "Drive" msgstr "" #: src/dird/ua_select.c:1098 msgid "Select drive" msgstr "" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, c-format msgid "Selected Job %d for cancelling\n" msgstr "" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "" #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "" #: src/dird/ua_select.c:1443 #, c-format msgid "Choose Job to %s" msgstr "" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "" #: src/dird/catreq.c:203 #, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "" #: src/dird/catreq.c:344 msgid "1992 Create JobMedia error\n" msgstr "" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, c-format msgid "Attribute create error: ERR=%s" msgstr "" #: src/dird/catreq.c:556 #, c-format msgid "Restore object create error. %s" msgstr "" #: src/dird/catreq.c:564 #, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" #: src/dird/catreq.c:613 #, c-format msgid "attribute create error. %s" msgstr "" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, c-format msgid "read attr spool error. ERR=%s\n" msgstr "" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 msgid "Can't update volume size in the catalog\n" msgstr "" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:819 #, c-format msgid "No Volumes found to perform %s action.\n" msgstr "" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 msgid "for Job" msgstr "" #: src/dird/ua_audit.c:71 msgid "for Client" msgstr "" #: src/dird/ua_audit.c:74 msgid "for Storage" msgstr "" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 msgid "for Schedule" msgstr "" #: src/dird/ua_audit.c:83 msgid "for Pool" msgstr "" #: src/dird/ua_audit.c:86 msgid "for Command" msgstr "" #: src/dird/ua_audit.c:89 msgid "for Fileset" msgstr "" #: src/dird/ua_audit.c:92 msgid "for Catalog" msgstr "" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 msgid "for Plugin Options" msgstr "" #: src/dird/ua_audit.c:114 #, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 msgid "base job" msgstr "" #: src/dird/inc_conf.c:225 #, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "" #: src/dird/inc_conf.c:233 #, c-format msgid "Expected a parseable size, got: %s:" msgstr "" #: src/dird/inc_conf.c:251 #, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:405 #, c-format msgid "Expected a fstype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:428 #, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:450 #, c-format msgid "Expected a meta string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr "" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 msgid "Plugin options failed.\n" msgstr "" #: src/dird/fd_cmds.c:828 msgid "RestoreObject failed.\n" msgstr "" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, c-format msgid "Error opening datafile %s\n" msgstr "" #: src/tests/bbatch.c:339 msgid "Error while inserting file\n" msgstr "" #: src/tests/bvfs_test.c:51 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/cats_test.c:375 #, c-format msgid "Could not open, database \"%s\".\n" msgstr "" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:241 #, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:562 #, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, c-format msgid "%s: Failed to resolve %s\n" msgstr "" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1015 #, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:1025 #, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "" #: src/stored/dir_cmd.c:1030 #, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1038 #, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "" #: src/stored/dir_cmd.c:1042 #, c-format msgid "3905 Unknown wait state %d\n" msgstr "" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1086 #, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1101 #, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1105 #, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "" #: src/stored/dir_cmd.c:1209 #, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "" #: src/stored/dir_cmd.c:1216 #, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "" #: src/stored/dir_cmd.c:1222 #, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "" #: src/stored/dir_cmd.c:1226 #, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1230 #, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1238 #, c-format msgid "3022 Device \"%s\" released.\n" msgstr "" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:1360 #, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "" #: src/stored/dir_cmd.c:1384 #, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1486 #, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" #: src/stored/dir_cmd.c:1489 #, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "" #: src/stored/dir_cmd.c:1492 #, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "" #: src/stored/dir_cmd.c:1496 #, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "" #: src/stored/dir_cmd.c:1500 #, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "" #: src/stored/dir_cmd.c:1505 #, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "" #: src/stored/dir_cmd.c:1507 #, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, c-format msgid "Bad passiveclientcmd command: %s" msgstr "" #: src/stored/dir_cmd.c:1673 msgid "File Daemon" msgstr "" #: src/stored/dir_cmd.c:1679 #, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1690 msgid "Failed to authenticate File daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1724 #, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, c-format msgid "Encountered an unknown stream type %d\n" msgstr "" #: src/stored/ndmp_tape.c:590 #, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:749 msgid "Creating virtual file attributes failed.\n" msgstr "" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, c-format msgid "Read session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 msgid "Cannot initialize new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 msgid "Cannot initialize new NDMA connection\n" msgstr "" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "" #: src/stored/ndmp_tape.c:1414 #, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, c-format msgid "Error in poll: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1557 #, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, c-format msgid "FD command not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:272 msgid "Append data error.\n" msgstr "" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:432 #, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "" #: src/stored/stored_conf.c:874 #, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, c-format msgid "%s has an unknown device type %d\n" msgstr "" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:353 #, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:360 #, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "" #: src/stored/append.c:161 #, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:169 #, c-format msgid "Malformed data header from %s: %s\n" msgstr "" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 msgid "" "\n" "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:985 msgid "" "\n" "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 msgid "Flush block failed.\n" msgstr "" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 msgid "Job canceled.\n" msgstr "" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "" #: src/stored/spool.c:701 #, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:716 #, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/reserve.c:84 #, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "" #: src/stored/reserve.c:258 msgid "3939 Could not get dcr\n" msgstr "" #: src/stored/reserve.c:366 #, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "" #: src/stored/mac.c:454 msgid "Read device not properly initialized.\n" msgstr "" #: src/stored/mac.c:479 msgid "Cannot set buffer size SD->SD.\n" msgstr "" #: src/stored/mac.c:496 #, c-format msgid "Bad response to start replicate: %s\n" msgstr "" #: src/stored/mac.c:501 msgid "Bad response from stored to start replicate command\n" msgstr "" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, c-format msgid "Unable to parse device %s.\n" msgstr "" #: src/stored/backends/rados_device.c:62 #, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:69 #, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:77 #, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:89 #, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:271 #, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:278 #, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, c-format msgid "Request for unknown devicetype: %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:317 #, c-format msgid "Unable to parse device URI %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:329 #, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/cephfs_device.c:58 #, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:65 #, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:72 #, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:101 #, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/cephfs_device.c:111 #, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, c-format msgid "Failed to create a new context using config %s\n" msgstr "" #: src/stored/backends/object_store_device.c:190 #, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:274 #, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:298 #, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:406 #, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:416 #, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 msgid "waiting for" msgstr "" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 msgid "waiting for sysop intervention" msgstr "" #: src/stored/status.c:275 msgid "unknown state" msgstr "" #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "" #: src/stored/status.c:332 #, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "" #: src/stored/status.c:336 #, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "" #: src/stored/status.c:369 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "" #: src/stored/status.c:523 #, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 msgid "Attached Jobs: " msgstr "" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, c-format msgid " File=%u block=%u\n" msgstr "" #: src/stored/status.c:610 #, c-format msgid " Min block=%u Max block=%u\n" msgstr "" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr "" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, c-format msgid "3900 No arg in status command: %s\n" msgstr "" #: src/stored/status.c:984 #, c-format msgid "3900 No arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1033 #, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:131 msgid "Unable to authenticate Storage daemon\n" msgstr "" #: src/stored/sd_cmds.c:182 #, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "" #: src/stored/sd_cmds.c:185 msgid "Command error with SD, hanging up.\n" msgstr "" #: src/stored/sd_cmds.c:197 #, c-format msgid "SD command not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:338 msgid "Replicate data error.\n" msgstr "" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:133 #, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:257 #, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, c-format msgid "Could not reserve volume %s on %s\n" msgstr "" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 msgid "Error updating Catalog\n" msgstr "" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "" #: src/stored/mount.c:741 #, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" #: src/stored/block.c:644 #, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 msgid "Error sending Volume info to Director.\n" msgstr "" #: src/stored/block.c:949 msgid "Job failed or canceled.\n" msgstr "" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "" #: src/stored/lock.c:489 msgid "unknown blocked code" msgstr "" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:310 #, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:324 #, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "" #: src/stored/autochanger.c:699 msgid "3306 Issuing autochanger transfer command.\n" msgstr "" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "" #: src/stored/bcopy.c:60 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 msgid "Quota Exceeded. Job Terminated.\n" msgstr "" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:650 #, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:981 #, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1965 #, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2292 #, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:2321 #, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" #: src/findlib/find.c:180 #, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "" #: src/findlib/bfile.c:92 msgid "File data" msgstr "" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "" #: src/findlib/bfile.c:98 msgid "Compressed data" msgstr "" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "" #: src/findlib/bfile.c:106 msgid "Compressed sparse data" msgstr "" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:118 msgid "Win32 compressed data" msgstr "" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "" #: src/findlib/bfile.c:142 msgid "Encrypted compressed data" msgstr "" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:146 msgid "Encrypted Win32 Compressed data" msgstr "" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:168 msgid "TRU64 Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:170 msgid "TRU64 Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:172 msgid "Solaris Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:174 msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:176 msgid "AFS Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:178 msgid "AIX Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:180 msgid "AIX Specific NFSv4 ACL attribs" msgstr "" #: src/findlib/bfile.c:182 msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:184 msgid "GNU Hurd Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:186 msgid "GNU Hurd Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:188 msgid "GNU Hurd Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:190 msgid "IRIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:192 msgid "TRU64 Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:194 msgid "AIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "" #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "" #: src/findlib/find_one.c:268 #, c-format msgid "%s: mtime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:275 #, c-format msgid "%s: ctime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, c-format msgid "%s: size changed during backup.\n" msgstr "" #: src/findlib/find_one.c:729 #, c-format msgid "%s: File name too long [%d]\n" msgstr "" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:293 #, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:495 #, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:929 #, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:967 #, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1000 #, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1683 #, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2196 #, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2225 #, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, c-format msgid "Unparseable size option: %s\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, c-format msgid "Unexpected autodeflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:368 #, c-format msgid "Unexpected autoinflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 msgid "Plugin File argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:916 msgid "Plugin Reader argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:922 msgid "Plugin Writer argument not specified.\n" msgstr "" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, c-format msgid "Enter Key Encryption Key: " msgstr "" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, c-format msgid "Cannot open keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:401 #, c-format msgid "Enter Encryption Key: " msgstr "" #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:177 #, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, c-format msgid "Failed to connect to mailhost %s\n" msgstr "" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 msgid "BAREOS Message" msgstr "" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:1054 #, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "" #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "" #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "" #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "" #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "" #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "" #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr "" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr "" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr "" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr "" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr "" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "" #: src/lib/lex.c:140 #, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:144 #, c-format msgid "Config warning: %s\n" msgstr "" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 msgid "string" msgstr "" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 msgid "include" msgstr "" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "" #: src/lib/jcr.c:248 msgid "Copying" msgstr "" #: src/lib/jcr.c:250 msgid "Migration" msgstr "" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "" #: src/lib/jcr.c:265 msgid "backup" msgstr "" #: src/lib/jcr.c:267 msgid "verified" msgstr "" #: src/lib/jcr.c:269 msgid "restored" msgstr "" #: src/lib/jcr.c:269 msgid "restore" msgstr "" #: src/lib/jcr.c:271 msgid "archived" msgstr "" #: src/lib/jcr.c:271 msgid "archive" msgstr "" #: src/lib/jcr.c:273 msgid "copied" msgstr "" #: src/lib/jcr.c:273 msgid "copy" msgstr "" #: src/lib/jcr.c:275 msgid "migrated" msgstr "" #: src/lib/jcr.c:275 msgid "migrate" msgstr "" #: src/lib/jcr.c:277 msgid "scanned" msgstr "" #: src/lib/jcr.c:277 msgid "scan" msgstr "" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "" #: src/lib/jcr.c:394 #, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:108 #, c-format msgid "prctl failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:112 #, c-format msgid "setreuid failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 msgid "unknown error" msgstr "" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 msgid "Encryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:251 msgid "Encryption Mode: External\n" msgstr "" #: src/lib/scsi_crypto.c:256 msgid "Encryption Mode: Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 msgid "Volume encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:460 msgid "Compression Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 msgid "Encryption Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 msgid "Drive encryption status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "" #: src/lib/bnet.c:326 msgid "No problem." msgstr "" #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "" #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "" #: src/lib/crypto_cache.c:160 #, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 msgid "Volumename" msgstr "" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 msgid "EncryptionKey" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Added" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:274 #, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 msgid "No error" msgstr "" #: src/lib/crypto.c:176 msgid "Signer not found" msgstr "" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 msgid "Selection item too large.\n" msgstr "" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "" #: src/lib/ini.c:262 src/lib/ini.c:274 #, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:312 src/lib/ini.c:324 #, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:560 src/lib/ini.c:672 #, c-format msgid "Cannot open config file %s: %s\n" msgstr "" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, c-format msgid "Error loading CA certificates from %s\n" msgstr "" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "" #: src/lib/tls_gnutls.c:201 #, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "" #: src/lib/tls_gnutls.c:216 #, c-format msgid "Failed to load DH file %s\n" msgstr "" #: src/lib/tls_gnutls.c:224 msgid "Failed to generate new DH parameters\n" msgstr "" #: src/lib/tls_gnutls.c:289 #, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "" #: src/lib/res.c:830 #, c-format msgid "expected a speed number, got: %s" msgstr "" #: src/lib/res.c:835 msgid "unknown unit type encountered" msgstr "" #: src/lib/res.c:853 #, c-format msgid "expected a %s, got: %s" msgstr "" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "" #: src/lib/bsock.c:139 msgid "attr spool I/O error.\n" msgstr "" #: src/lib/bsock.c:276 #, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" #: src/lib/bsock.c:311 #, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:321 #, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "" #: src/lib/bsock.c:330 #, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "" #: src/lib/bsock.c:341 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:186 #, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:269 #, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:292 #, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:632 msgid "Could not malloc BSOCK data buffer\n" msgstr "" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "" #: src/lib/devlock.c:322 msgid "writeunlock called too many times.\n" msgstr "" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:542 #, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "" #: src/lib/parse_conf.c:149 msgid "Config filename too long.\n" msgstr "" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "" #: src/lib/compression.c:88 msgid "GZIP compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:91 msgid "LZO2 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:94 msgid "LZFZ compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:97 msgid "LZ4 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:100 msgid "LZ4HC compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 msgid "Failed to initialize ZLIB compression\n" msgstr "" #: src/lib/compression.c:215 msgid "Failed to initialize LZO compression\n" msgstr "" #: src/lib/compression.c:270 msgid "Failed to initialize FASTLZ compression\n" msgstr "" #: src/lib/compression.c:300 msgid "LZO init failed\n" msgstr "" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "" #: src/lib/compression.c:371 #, c-format msgid "Compression LZO error: %d\n" msgstr "" #: src/lib/compression.c:402 #, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "" #: src/lib/compression.c:413 #, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "" #: src/lib/compression.c:592 #, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 msgid "Compressed data stream found, but compression not configured!\n" msgstr "" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 msgid "Error loading revocation list file" msgstr "" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 msgid "Running" msgstr "" #: src/lib/util.c:214 msgid "Blocked" msgstr "" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "" #: src/lib/util.c:238 msgid "Verify differences" msgstr "" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "" #: src/lib/util.c:302 msgid "Completed successfully" msgstr "" #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "" #: src/lib/util.c:311 msgid "Fatal error" msgstr "" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "" #: src/lib/util.c:320 msgid "Verify found differences" msgstr "" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "" #: src/lib/util.c:369 msgid "Differences" msgstr "" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "" #: src/lib/util.c:391 msgid "Migrated Job" msgstr "" #: src/lib/util.c:394 msgid "Verify" msgstr "" #: src/lib/util.c:397 msgid "Restore" msgstr "" #: src/lib/util.c:400 msgid "Console" msgstr "" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "" #: src/lib/util.c:412 msgid "Job Copy" msgstr "" #: src/lib/util.c:415 msgid "Copy" msgstr "" #: src/lib/util.c:418 msgid "Migrate" msgstr "" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "" #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "" #: src/lib/util.c:479 msgid "Verify Data" msgstr "" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 msgid "Append" msgstr "" #: src/lib/util.c:500 msgid "Disabled" msgstr "" #: src/lib/util.c:502 msgid "Used" msgstr "" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 msgid "Recycle" msgstr "" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 msgid "Invalid volume status" msgstr "" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "" #: src/lib/signal.c:152 src/lib/signal.c:154 #, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "" #: src/lib/signal.c:323 msgid "Hangup" msgstr "" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "" #: src/lib/signal.c:325 msgid "Quit" msgstr "" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "" #: src/lib/signal.c:335 msgid "BUS error" msgstr "" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "" #: src/lib/signal.c:343 msgid "Termination" msgstr "" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "" #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:92 #, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:314 #, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:323 #, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "" #: src/lib/scsi_lli.c:348 #, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "" #: src/lib/scsi_lli.c:464 #, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "" #: src/lib/crypto_openssl.c:749 msgid "No signers found for crypto verify.\n" msgstr "" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1615 #, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, c-format msgid "Could not set Finder Info on %s\n" msgstr "" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, c-format msgid "Cannot open resource fork for %s.\n" msgstr "" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "" #: src/filed/dir_cmd.c:933 #, c-format msgid "Bad RunAfter command: %s\n" msgstr "" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1015 #, c-format msgid "Bad Plugin Options command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1066 #, c-format msgid "Bad RestoreObject command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1166 msgid "2909 Bad RestoreObject command.\n" msgstr "" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "" #: src/filed/dir_cmd.c:1696 #, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1708 #, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "" #: src/filed/filed.c:61 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, c-format msgid "Unable to create MDB environment: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:81 #, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:90 #, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:97 #, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:103 #, c-format msgid "Unable to start a write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:109 #, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, c-format msgid "Unable insert new data: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, c-format msgid "Unable close write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, c-format msgid "Unable to create write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:249 #, c-format msgid "Unable to create read transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, c-format msgid "Unable to renew read transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, c-format msgid "Unable create cursor: %s\n" msgstr "" #: src/filed/status.c:87 #, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, c-format msgid " %s%s %s Job started: %s\n" msgstr "" #: src/filed/status.c:201 #, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr "" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "" #: src/filed/authenticate.c:301 #, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, c-format msgid "Cannot verify checksum for %s\n" msgstr "" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr "" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:79 #, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:139 msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "" #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "" bareos-Release-14.2.6/po/nl.po000066400000000000000000014673571263011562700160560ustar00rootroot00000000000000# Dutch translation of Bareos # Copyright (C) 2012 Kern Sibbald # This file is distributed under the same license as the PACKAGE package. # W. van den Akker , 2012 # msgid "" msgstr "" "Project-Id-Version: Bareos 5.2.7\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2012-05-05 11:52+0100\n" "Last-Translator: W. van den Akker \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "" #: src/cats/sql.c:789 #, fuzzy msgid "Could not init database batch connection\n" msgstr "Data parser kon niet geregistreerd worden!" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:260 #, c-format msgid "More than one Device!: %d\n" msgstr "" #: src/cats/sql_create.c:265 #, c-format msgid "error fetching Device row: %s\n" msgstr "" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1316 #, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1367 #, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1399 #, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1442 #, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1499 #, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1543 #, fuzzy, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 #, fuzzy msgid "Could not init database connection" msgstr "Data parser kon niet geregistreerd worden!" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "" #: src/cats/ingres.c:82 msgid "Failed to allocate space for query filter.\n" msgstr "" #: src/cats/ingres.c:103 msgid "Failed to allocate space for query filters.\n" msgstr "" #: src/cats/ingres.c:257 #, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" #: src/cats/ingres.c:1031 msgid "A user name for Ingres must be supplied.\n" msgstr "" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 msgid "Quota record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 msgid "Catalog Backends Dir not configured.\n" msgstr "" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, fuzzy, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:236 #, fuzzy, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "" #: src/console/console_conf.c:143 #, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" #: src/console/console.c:170 msgid "input from file" msgstr "" #: src/console/console.c:171 msgid "output to file" msgstr "" #: src/console/console.c:172 msgid "quit" msgstr "" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "" #: src/console/console.c:174 msgid "sleep specified time" msgstr "" #: src/console/console.c:175 msgid "print current time" msgstr "" #: src/console/console.c:176 msgid "print Console's version" msgstr "" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "" #: src/console/console.c:179 msgid "exit = quit" msgstr "" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "" #: src/console/console.c:181 msgid "help listing" msgstr "" #: src/console/console.c:183 msgid "set command separator" msgstr "" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr "" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "" #: src/console/console.c:996 #, c-format msgid "Can't find %s in Director list\n" msgstr "" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "" #: src/console/console.c:1600 #, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "" #: src/console/console.c:1612 #, fuzzy, c-format msgid "Autochanger error: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "Backup OK -- met waarschuwingen" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "*** Backup Fout ***" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "Backup geannuleerd" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "Fout bij schrijven van bsr bestand.\n" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "Geen Volumes gevonden om terug te zetten.\n" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" "\n" "Volumes gemarkeerd met \"*\" staan online.\n" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, c-format msgid "Could not get storage resource '%s'.\n" msgstr "" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "*** Admin Fout ***" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "Admin geannuleerd" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: tray-monitor [-c configuratiebestand] [-d debug_level]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -dt weergeven tijd in debug output\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 msgid "TLS required but not configured in BAREOS.\n" msgstr "" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "" #: src/dird/dird.c:1110 #, c-format msgid "Could not create storage record for %s\n" msgstr "" #: src/dird/dird.c:1119 #, c-format msgid "Could not update storage record for %s\n" msgstr "" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, c-format msgid "Error getting Quota value: ERR=%s" msgstr "" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:88 #, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:102 #, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:170 #, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:312 msgid "rerun these jobids? (yes/no): " msgstr "" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 msgid "Level" msgstr "" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "Opslag" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "Job" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "" #: src/dird/ua_run.c:555 msgid "Restore Client" msgstr "" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "Client" #: src/dird/ua_run.c:559 msgid "Backup Format" msgstr "" #: src/dird/ua_run.c:560 msgid "When" msgstr "" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "Pool" #: src/dird/ua_run.c:571 #, fuzzy msgid "NextPool" msgstr "Pool" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "" #: src/dird/ua_run.c:582 msgid "Where" msgstr "" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 msgid "Please enter Backup Format: " msgstr "" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "" #: src/dird/ua_run.c:730 msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 msgid "Please enter Plugin Options string: " msgstr "" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 msgid "Storage from Run NextPool override" msgstr "" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, c-format msgid "Level \"%s\" not valid.\n" msgstr "" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 msgid "Please enter the path prefix to strip: " msgstr "" #: src/dird/ua_run.c:1035 msgid "Please enter the path prefix to add (/ for none): " msgstr "" #: src/dird/ua_run.c:1046 msgid "Please enter the file suffix to add: " msgstr "" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "*Geen*" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "" #: src/dird/ua_run.c:1438 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1498 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "" #: src/dird/ua_run.c:1546 #, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "" #: src/dird/ua_run.c:1602 msgid "Run Migration job\n" msgstr "" #: src/dird/ua_run.c:1604 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1870 msgid "NextPool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1886 msgid "Restore Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1894 msgid "Plugin Options specified twice.\n" msgstr "" #: src/dird/ua_run.c:1899 msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "" #: src/dird/ua_run.c:1906 msgid "Spool flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "" #: src/dird/ua_run.c:1922 msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1929 msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "" #: src/dird/ua_run.c:1934 msgid "Accurate flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1941 msgid "Invalid accurate flag.\n" msgstr "" #: src/dird/ua_run.c:1946 msgid "Backup Format specified twice.\n" msgstr "" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "" #: src/dird/ua_status.c:390 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 msgid "No clients defined.\n" msgstr "" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "Datum" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 msgid "Schedule" msgstr "" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "" #: src/dird/ua_status.c:1034 msgid "has terminated with warnings" msgstr "" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, c-format msgid "is waiting on Storage \"%s\"" msgstr "" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, fuzzy, c-format msgid "is waiting for its start time at %s" msgstr "Job %s wacht %d seconde voor de start tijd.\n" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 msgid "is waiting for Client to connect to Storage daemon" msgstr "" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "" #: src/dird/ua_status.c:1177 #, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 msgid "No Volumes found, or no barcodes.\n" msgstr "" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "Bestand: %s\n" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr "" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, c-format msgid "Unknown command: %s\n" msgstr "" #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "" #: src/dird/ua_dotcmds.c:1116 #, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1130 #, c-format msgid "List Media failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1156 #, c-format msgid "List Location failed: ERR=%s\n" msgstr "" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "" #: src/dird/ua_input.c:218 msgid "Comment too long.\n" msgstr "" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "" #: src/dird/ua_cmds.c:112 #, fuzzy msgid "Configure director" msgstr "Configuratiebestand" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 msgid "Disable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 msgid "Print current memory usage" msgstr "" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "" #: src/dird/ua_cmds.c:164 msgid "Move slots in an autochanger" msgstr "" #: src/dird/ua_cmds.c:166 msgid "Prune records from catalog" msgstr "" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "" #: src/dird/ua_cmds.c:175 msgid "Restore files" msgstr "" #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 #, fuzzy msgid "Rerun a job" msgstr "Uitvoeren herstel opdracht" #: src/dird/ua_cmds.c:192 msgid "Resolve a hostname" msgstr "" #: src/dird/ua_cmds.c:194 msgid "Run a job" msgstr "" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 msgid "Show resource records" msgstr "" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 msgid "Print current time" msgstr "" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 msgid "Use specific catalog" msgstr "" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 msgid "Print Director version" msgstr "" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, fuzzy, c-format msgid "JobId %s not a number\n" msgstr "JobID %s is niet in uitvoering.\n" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "" #: src/dird/ua_cmds.c:793 #, fuzzy msgid "Failed to set bandwidth limit on Client.\n" msgstr "Kan de geselecteerde client niet vinden." #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:843 #, fuzzy msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "Kan de geselecteerde client niet vinden." #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "Job \"%s\" niet gevonden.\n" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, c-format msgid "Client \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1495 msgid "Storage name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1520 #, fuzzy, c-format msgid "%s Failed to resolve %s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, c-format msgid "%s resolves %s to %s\n" msgstr "" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "" #: src/dird/ua_cmds.c:1667 msgid "Accurate value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "" #: src/dird/ua_cmds.c:1696 #, c-format msgid "Wrong job specified of type %s.\n" msgstr "" #: src/dird/ua_cmds.c:1709 msgid "No client specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1714 #, fuzzy msgid "No fileset specified or selected.\n" msgstr "Geen Volumes gevonden om terug te zetten.\n" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, c-format msgid "Illegal JobId %s ignored\n" msgstr "" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "" #: src/dird/ua_cmds.c:1979 #, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr "" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "Kan Catalog medium niet vinden\n" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "Controle OK" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "*** Fout bij controleren ***" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:581 #, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:661 #, c-format msgid "" "dird\" command before continuing.\n" msgstr "" "U diente een \"use \" te specificeren alvorens te kunnen " "doorgaan.\n" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "De gedefinieerde Catalog media zijn:\n" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "Selecteer Catalog media" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "De gedefinieerde job resources zijn:\n" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "Selecteer Job media:" #: src/dird/ua_select.c:307 #, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "Selecteer Job om terug te zetten" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "De gedefinieerde Clients zijn:\n" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "Selecteer een Client (File daemon)" #: src/dird/ua_select.c:378 #, fuzzy msgid "Select Client resource" msgstr "Selecteer FileSet bron" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "Fout: Client %s bestaat niet.\n" #: src/dird/ua_select.c:421 #, fuzzy msgid "The defined Schedule resources are:\n" msgstr "De gedefinieerde Clients zijn:\n" #: src/dird/ua_select.c:432 #, fuzzy msgid "Select Schedule resource" msgstr "Selecteer Pool" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "Kan Client niet vinden %s: ERR=%s" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "Kan Client niet vinden \"%s\": ERR=%s" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "Gedefinieerde Clients:\n" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "Selecteer Client" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "Gedefinieerde Pools:\n" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "Selecteer Pool" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "Geen toegang tot Pool \"%s\"\n" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "Voer *MediaId of Volume naam in:" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "Selecteer Pool" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "Voer de gekozen Job in:" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "Kan Job niet vinden \"%s\": ERR=%s" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "Voer een nummer in tussen 1 en %d\n" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "JobID %s is niet in uitvoering.\n" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "Job \"%s\" is niet in uitvoering.\n" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "" #: src/dird/ua_select.c:1093 #, fuzzy msgid "Select Drive:\n" msgstr "Selecteer Job:\n" #: src/dird/ua_select.c:1098 msgid "Drive" msgstr "" #: src/dird/ua_select.c:1098 #, fuzzy msgid "Select drive" msgstr "Selecteer Client" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "Voer autochanger slot in:" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "Type media" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "Selecteer media type" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "Geen Jobs in uitvoering.\n" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "Geen van uw opdrachten zijn in uitvoering.\n" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, fuzzy, c-format msgid "Selected Job %d for cancelling\n" msgstr "Selecteer Job media:" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 #, fuzzy msgid "Confirm cancel (yes/no): " msgstr "Bevestig annulering (yes/no)" #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "Selecteer Job:\n" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "" #: src/dird/ua_select.c:1443 #, c-format msgid "Choose Job to %s" msgstr "" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" "Anuleer: %s\n" "\n" "%s" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "Bevestig annulering?" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "" #: src/dird/catreq.c:203 #, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "" #: src/dird/catreq.c:344 msgid "1992 Create JobMedia error\n" msgstr "" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, c-format msgid "Attribute create error: ERR=%s" msgstr "" #: src/dird/catreq.c:556 #, c-format msgid "Restore object create error. %s" msgstr "" #: src/dird/catreq.c:564 #, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" #: src/dird/catreq.c:613 #, c-format msgid "attribute create error. %s" msgstr "" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, fuzzy, c-format msgid "read attr spool error. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, fuzzy, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "Kan Client niet vinden \"%s\": ERR=%s" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 msgid "Can't update volume size in the catalog\n" msgstr "" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:819 #, c-format msgid "No Volumes found to perform %s action.\n" msgstr "" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 #, fuzzy msgid "for Job" msgstr "Job" #: src/dird/ua_audit.c:71 #, fuzzy msgid "for Client" msgstr "Client" #: src/dird/ua_audit.c:74 #, fuzzy msgid "for Storage" msgstr "Opslag" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 msgid "for Schedule" msgstr "" #: src/dird/ua_audit.c:83 #, fuzzy msgid "for Pool" msgstr "Pool" #: src/dird/ua_audit.c:86 msgid "for Command" msgstr "" #: src/dird/ua_audit.c:89 #, fuzzy msgid "for Fileset" msgstr "Bestandsnaam" #: src/dird/ua_audit.c:92 msgid "for Catalog" msgstr "" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 msgid "for Plugin Options" msgstr "" #: src/dird/ua_audit.c:114 #, fuzzy, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "Console: naam=%s\n" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, fuzzy, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "Console: naam=%s\n" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 msgid "base job" msgstr "" #: src/dird/inc_conf.c:225 #, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "" #: src/dird/inc_conf.c:233 #, fuzzy, c-format msgid "Expected a parseable size, got: %s:" msgstr "Kan de service niet installeren" #: src/dird/inc_conf.c:251 #, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:405 #, c-format msgid "Expected a fstype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:428 #, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:450 #, c-format msgid "Expected a meta string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr "" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 msgid "Plugin options failed.\n" msgstr "" #: src/dird/fd_cmds.c:828 msgid "RestoreObject failed.\n" msgstr "" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, c-format msgid "Error opening datafile %s\n" msgstr "" #: src/tests/bbatch.c:339 msgid "Error while inserting file\n" msgstr "" #: src/tests/bvfs_test.c:51 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/cats_test.c:375 #, c-format msgid "Could not open, database \"%s\".\n" msgstr "" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, fuzzy, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/dir_cmd.c:241 #, fuzzy, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:562 #, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, fuzzy, c-format msgid "%s: Failed to resolve %s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1015 #, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:1025 #, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "" #: src/stored/dir_cmd.c:1030 #, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1038 #, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "" #: src/stored/dir_cmd.c:1042 #, c-format msgid "3905 Unknown wait state %d\n" msgstr "" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1086 #, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1101 #, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1105 #, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "" #: src/stored/dir_cmd.c:1209 #, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "" #: src/stored/dir_cmd.c:1216 #, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "" #: src/stored/dir_cmd.c:1222 #, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "" #: src/stored/dir_cmd.c:1226 #, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1230 #, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1238 #, c-format msgid "3022 Device \"%s\" released.\n" msgstr "" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:1360 #, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "" #: src/stored/dir_cmd.c:1384 #, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1486 #, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" #: src/stored/dir_cmd.c:1489 #, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "" #: src/stored/dir_cmd.c:1492 #, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "" #: src/stored/dir_cmd.c:1496 #, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "" #: src/stored/dir_cmd.c:1500 #, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "" #: src/stored/dir_cmd.c:1505 #, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "" #: src/stored/dir_cmd.c:1507 #, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, c-format msgid "Bad passiveclientcmd command: %s" msgstr "" #: src/stored/dir_cmd.c:1673 #, fuzzy msgid "File Daemon" msgstr "Bestandsnaam" #: src/stored/dir_cmd.c:1679 #, fuzzy, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "Verbinden met de director mislukt\n" #: src/stored/dir_cmd.c:1690 #, fuzzy msgid "Failed to authenticate File daemon.\n" msgstr "Kan de geselecteerde fileset niet vinden." #: src/stored/dir_cmd.c:1724 #, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, c-format msgid "Encountered an unknown stream type %d\n" msgstr "" #: src/stored/ndmp_tape.c:590 #, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:749 msgid "Creating virtual file attributes failed.\n" msgstr "" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, fuzzy, c-format msgid "Read session label failed. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 msgid "Cannot initialize new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 #, fuzzy msgid "Cannot initialize new NDMA connection\n" msgstr "Data parser kon niet geregistreerd worden!" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "" #: src/stored/ndmp_tape.c:1414 #, fuzzy, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "Kan Client niet vinden %s: ERR=%s" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, c-format msgid "Error in poll: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, fuzzy, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "Kan Client niet vinden %s: ERR=%s" #: src/stored/ndmp_tape.c:1557 #, fuzzy, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "Kan Client niet vinden %s: ERR=%s" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, c-format msgid "FD command not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:272 msgid "Append data error.\n" msgstr "" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:432 #, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "" #: src/stored/stored_conf.c:874 #, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, c-format msgid "%s has an unknown device type %d\n" msgstr "" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, fuzzy, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/dev.c:353 #, fuzzy, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/dev.c:360 #, fuzzy, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, fuzzy, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: tray-monitor [-c configuratiebestand] [-d debug_level]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -dt weergeven tijd in debug output\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, fuzzy, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/append.c:161 #, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:169 #, c-format msgid "Malformed data header from %s: %s\n" msgstr "" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, fuzzy, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 msgid "" "\n" "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:985 msgid "" "\n" "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 msgid "Flush block failed.\n" msgstr "" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 msgid "Job canceled.\n" msgstr "" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: tray-monitor [-c configuratiebestand] [-d debug_level]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -dt weergeven tijd in debug output\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "" #: src/stored/spool.c:701 #, fuzzy, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/spool.c:716 #, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/reserve.c:84 #, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "" #: src/stored/reserve.c:258 msgid "3939 Could not get dcr\n" msgstr "" #: src/stored/reserve.c:366 #, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "" #: src/stored/mac.c:454 msgid "Read device not properly initialized.\n" msgstr "" #: src/stored/mac.c:479 msgid "Cannot set buffer size SD->SD.\n" msgstr "" #: src/stored/mac.c:496 #, c-format msgid "Bad response to start replicate: %s\n" msgstr "" #: src/stored/mac.c:501 msgid "Bad response from stored to start replicate command\n" msgstr "" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: tray-monitor [-c configuratiebestand] [-d debug_level]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -dt weergeven tijd in debug output\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, fuzzy, c-format msgid "Unable to parse device %s.\n" msgstr "Kan de service niet installeren" #: src/stored/backends/rados_device.c:62 #, fuzzy, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/rados_device.c:69 #, fuzzy, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/backends/rados_device.c:77 #, fuzzy, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/rados_device.c:89 #, fuzzy, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/backends/rados_device.c:271 #, fuzzy, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/rados_device.c:278 #, fuzzy, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, c-format msgid "Request for unknown devicetype: %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:317 #, fuzzy, c-format msgid "Unable to parse device URI %s.\n" msgstr "Verbinden met de director mislukt\n" #: src/stored/backends/gfapi_device.c:329 #, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/cephfs_device.c:58 #, fuzzy, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/cephfs_device.c:65 #, fuzzy, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/backends/cephfs_device.c:72 #, fuzzy, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/backends/cephfs_device.c:101 #, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/cephfs_device.c:111 #, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, fuzzy, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, fuzzy, c-format msgid "Failed to create a new context using config %s\n" msgstr "Kan de service niet installeren" #: src/stored/backends/object_store_device.c:190 #, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, fuzzy, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/object_store_device.c:274 #, fuzzy, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/object_store_device.c:298 #, fuzzy, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/object_store_device.c:406 #, fuzzy, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/backends/object_store_device.c:416 #, fuzzy, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 msgid "waiting for" msgstr "" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 msgid "waiting for sysop intervention" msgstr "" #: src/stored/status.c:275 msgid "unknown state" msgstr "" #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "" #: src/stored/status.c:332 #, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "" #: src/stored/status.c:336 #, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "" #: src/stored/status.c:369 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "" #: src/stored/status.c:523 #, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 msgid "Attached Jobs: " msgstr "" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, c-format msgid " File=%u block=%u\n" msgstr "" #: src/stored/status.c:610 #, c-format msgid " Min block=%u Max block=%u\n" msgstr "" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr "" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, c-format msgid "3900 No arg in status command: %s\n" msgstr "" #: src/stored/status.c:984 #, c-format msgid "3900 No arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1033 #, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:131 msgid "Unable to authenticate Storage daemon\n" msgstr "" #: src/stored/sd_cmds.c:182 #, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "" #: src/stored/sd_cmds.c:185 msgid "Command error with SD, hanging up.\n" msgstr "" #: src/stored/sd_cmds.c:197 #, c-format msgid "SD command not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:338 #, fuzzy msgid "Replicate data error.\n" msgstr "Zlib data fout" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:133 #, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:257 #, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, c-format msgid "Could not reserve volume %s on %s\n" msgstr "" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 msgid "Error updating Catalog\n" msgstr "" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "" #: src/stored/mount.c:741 #, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, fuzzy, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" #: src/stored/block.c:644 #, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 #, fuzzy msgid "Error sending Volume info to Director.\n" msgstr "Geen Volumes gevonden om terug te zetten.\n" #: src/stored/block.c:949 #, fuzzy msgid "Job failed or canceled.\n" msgstr "Terugzetten geannuleerd.\n" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "" #: src/stored/lock.c:489 msgid "unknown blocked code" msgstr "" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:310 #, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:324 #, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "" #: src/stored/autochanger.c:699 msgid "3306 Issuing autochanger transfer command.\n" msgstr "" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, fuzzy, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, fuzzy, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "" #: src/stored/bcopy.c:60 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, fuzzy, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 msgid "Quota Exceeded. Job Terminated.\n" msgstr "" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:650 #, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:981 #, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1965 #, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2292 #, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:2321 #, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" #: src/findlib/find.c:180 #, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "" #: src/findlib/bfile.c:92 msgid "File data" msgstr "" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "" #: src/findlib/bfile.c:98 msgid "Compressed data" msgstr "" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "" #: src/findlib/bfile.c:106 msgid "Compressed sparse data" msgstr "" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:118 msgid "Win32 compressed data" msgstr "" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "" #: src/findlib/bfile.c:142 msgid "Encrypted compressed data" msgstr "" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:146 msgid "Encrypted Win32 Compressed data" msgstr "" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:168 msgid "TRU64 Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:170 msgid "TRU64 Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:172 msgid "Solaris Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:174 msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:176 msgid "AFS Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:178 msgid "AIX Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:180 msgid "AIX Specific NFSv4 ACL attribs" msgstr "" #: src/findlib/bfile.c:182 msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:184 msgid "GNU Hurd Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:186 msgid "GNU Hurd Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:188 msgid "GNU Hurd Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:190 msgid "IRIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:192 msgid "TRU64 Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:194 msgid "AIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "" #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "" #: src/findlib/find_one.c:268 #, c-format msgid "%s: mtime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:275 #, c-format msgid "%s: ctime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, c-format msgid "%s: size changed during backup.\n" msgstr "" #: src/findlib/find_one.c:729 #, c-format msgid "%s: File name too long [%d]\n" msgstr "" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:293 #, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:495 #, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:929 #, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:967 #, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1000 #, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1683 #, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2196 #, fuzzy, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/findlib/acl.c:2225 #, fuzzy, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, fuzzy, c-format msgid "Unparseable size option: %s\n" msgstr "Kan de service niet installeren" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, c-format msgid "Unexpected autodeflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:368 #, c-format msgid "Unexpected autoinflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, fuzzy, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "Compressie LZO fout: %d\n" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 msgid "Plugin File argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:916 msgid "Plugin Reader argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:922 msgid "Plugin Writer argument not specified.\n" msgstr "" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, fuzzy, c-format msgid "Enter Key Encryption Key: " msgstr "Geef nieuwe retention periode:" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, c-format msgid "Cannot open keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, fuzzy, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "Kan de service niet installeren" #: src/tools/bscrypto.c:401 #, fuzzy, c-format msgid "Enter Encryption Key: " msgstr "Geef nieuwe retention periode:" #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:177 #, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, fuzzy, c-format msgid "Failed to connect to mailhost %s\n" msgstr "Verbinden met de director mislukt\n" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 msgid "BAREOS Message" msgstr "" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:1054 #, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "" #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "" #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "" #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "" #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "" #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "" #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr "" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr "" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr "" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr "" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr "" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "" #: src/lib/lex.c:140 #, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:144 #, c-format msgid "Config warning: %s\n" msgstr "" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 msgid "string" msgstr "" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 msgid "include" msgstr "" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "" #: src/lib/jcr.c:248 msgid "Copying" msgstr "" #: src/lib/jcr.c:250 msgid "Migration" msgstr "" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "" #: src/lib/jcr.c:265 msgid "backup" msgstr "" #: src/lib/jcr.c:267 msgid "verified" msgstr "" #: src/lib/jcr.c:269 msgid "restored" msgstr "" #: src/lib/jcr.c:269 msgid "restore" msgstr "" #: src/lib/jcr.c:271 msgid "archived" msgstr "" #: src/lib/jcr.c:271 msgid "archive" msgstr "" #: src/lib/jcr.c:273 msgid "copied" msgstr "" #: src/lib/jcr.c:273 msgid "copy" msgstr "" #: src/lib/jcr.c:275 msgid "migrated" msgstr "" #: src/lib/jcr.c:275 msgid "migrate" msgstr "" #: src/lib/jcr.c:277 msgid "scanned" msgstr "" #: src/lib/jcr.c:277 msgid "scan" msgstr "" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "" #: src/lib/jcr.c:394 #, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:108 #, c-format msgid "prctl failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:112 #, c-format msgid "setreuid failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 msgid "unknown error" msgstr "" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 #, fuzzy msgid "Encryption Mode: Disabled\n" msgstr "Fout in versleuteling \n" #: src/lib/scsi_crypto.c:251 #, fuzzy msgid "Encryption Mode: External\n" msgstr "Fout in versleuteling \n" #: src/lib/scsi_crypto.c:256 #, fuzzy msgid "Encryption Mode: Encrypt\n" msgstr "Fout in versleuteling \n" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 msgid "Volume encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:460 msgid "Compression Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 msgid "Encryption Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 msgid "Drive encryption status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "" #: src/lib/bnet.c:326 msgid "No problem." msgstr "" #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "" #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "" #: src/lib/crypto_cache.c:160 #, fuzzy, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 #, fuzzy msgid "Volumename" msgstr "Bestandsnaam" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 #, fuzzy msgid "EncryptionKey" msgstr "Geef nieuwe retention periode:" #: src/lib/crypto_cache.c:354 #, fuzzy msgid "Added" msgstr "Toevoegen" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:274 #, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 msgid "No error" msgstr "" #: src/lib/crypto.c:176 msgid "Signer not found" msgstr "" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 #, fuzzy msgid "Selection item too large.\n" msgstr "Selecteer Pool" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, fuzzy, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/lib/ini.c:262 src/lib/ini.c:274 #, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:312 src/lib/ini.c:324 #, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:560 src/lib/ini.c:672 #, c-format msgid "Cannot open config file %s: %s\n" msgstr "" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, fuzzy, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, c-format msgid "Error loading CA certificates from %s\n" msgstr "" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "" #: src/lib/tls_gnutls.c:201 #, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "" #: src/lib/tls_gnutls.c:216 #, fuzzy, c-format msgid "Failed to load DH file %s\n" msgstr "Kan de service niet installeren" #: src/lib/tls_gnutls.c:224 #, fuzzy msgid "Failed to generate new DH parameters\n" msgstr "Data parser kon niet geregistreerd worden!" #: src/lib/tls_gnutls.c:289 #, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, fuzzy, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "" #: src/lib/res.c:830 #, c-format msgid "expected a speed number, got: %s" msgstr "" #: src/lib/res.c:835 msgid "unknown unit type encountered" msgstr "" #: src/lib/res.c:853 #, c-format msgid "expected a %s, got: %s" msgstr "" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "" #: src/lib/bsock.c:139 msgid "attr spool I/O error.\n" msgstr "" #: src/lib/bsock.c:276 #, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" #: src/lib/bsock.c:311 #, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:321 #, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "" #: src/lib/bsock.c:330 #, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "" #: src/lib/bsock.c:341 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:186 #, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:269 #, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:292 #, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:632 msgid "Could not malloc BSOCK data buffer\n" msgstr "" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "" #: src/lib/devlock.c:322 msgid "writeunlock called too many times.\n" msgstr "" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:542 #, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "" #: src/lib/parse_conf.c:149 msgid "Config filename too long.\n" msgstr "" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "Zlib foutnr." #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "Zlib datastroom fout" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "Zlib data fout" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "Zlib geheugen fout" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "Zlib buffer fout" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "Zlib versie fout" #: src/lib/compression.c:88 msgid "GZIP compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:91 msgid "LZO2 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:94 msgid "LZFZ compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:97 msgid "LZ4 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:100 msgid "LZ4HC compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 msgid "Failed to initialize ZLIB compression\n" msgstr "" #: src/lib/compression.c:215 msgid "Failed to initialize LZO compression\n" msgstr "" #: src/lib/compression.c:270 msgid "Failed to initialize FASTLZ compression\n" msgstr "" #: src/lib/compression.c:300 msgid "LZO init failed\n" msgstr "Initialiseren LZO mislukt\n" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "" #: src/lib/compression.c:371 #, c-format msgid "Compression LZO error: %d\n" msgstr "Compressie LZO fout: %d\n" #: src/lib/compression.c:402 #, fuzzy, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "Compressie LZO fout: %d\n" #: src/lib/compression.c:413 #, fuzzy, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "Compressie LZO fout: %d\n" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "" #: src/lib/compression.c:592 #, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 msgid "Compressed data stream found, but compression not configured!\n" msgstr "" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 msgid "Error loading revocation list file" msgstr "" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 msgid "Running" msgstr "" #: src/lib/util.c:214 msgid "Blocked" msgstr "" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "" #: src/lib/util.c:238 msgid "Verify differences" msgstr "" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "" #: src/lib/util.c:302 msgid "Completed successfully" msgstr "" #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "" #: src/lib/util.c:311 msgid "Fatal error" msgstr "" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "" #: src/lib/util.c:320 msgid "Verify found differences" msgstr "" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "" #: src/lib/util.c:369 msgid "Differences" msgstr "" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "" #: src/lib/util.c:391 msgid "Migrated Job" msgstr "" #: src/lib/util.c:394 msgid "Verify" msgstr "" #: src/lib/util.c:397 msgid "Restore" msgstr "" #: src/lib/util.c:400 msgid "Console" msgstr "" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "" #: src/lib/util.c:412 msgid "Job Copy" msgstr "" #: src/lib/util.c:415 msgid "Copy" msgstr "" #: src/lib/util.c:418 msgid "Migrate" msgstr "" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "" #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "" #: src/lib/util.c:479 msgid "Verify Data" msgstr "" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 msgid "Append" msgstr "" #: src/lib/util.c:500 msgid "Disabled" msgstr "" #: src/lib/util.c:502 msgid "Used" msgstr "" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 msgid "Recycle" msgstr "" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 msgid "Invalid volume status" msgstr "" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "" #: src/lib/signal.c:152 src/lib/signal.c:154 #, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "" #: src/lib/signal.c:323 msgid "Hangup" msgstr "" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "" #: src/lib/signal.c:325 msgid "Quit" msgstr "" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "" #: src/lib/signal.c:335 msgid "BUS error" msgstr "" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "" #: src/lib/signal.c:343 msgid "Termination" msgstr "" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "" #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, fuzzy, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/lib/scsi_lli.c:92 #, fuzzy, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, fuzzy, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, fuzzy, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "Kan Client niet vinden %s: ERR=%s" #: src/lib/scsi_lli.c:314 #, fuzzy, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/lib/scsi_lli.c:323 #, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "" #: src/lib/scsi_lli.c:348 #, fuzzy, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "Verbinden met de director mislukt\n" #: src/lib/scsi_lli.c:464 #, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "" #: src/lib/crypto_openssl.c:749 msgid "No signers found for crypto verify.\n" msgstr "" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1615 #, fuzzy, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, c-format msgid "Could not set Finder Info on %s\n" msgstr "" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, c-format msgid "Cannot open resource fork for %s.\n" msgstr "" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "Fout in versleuteling \n" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "" #: src/filed/dir_cmd.c:933 #, c-format msgid "Bad RunAfter command: %s\n" msgstr "" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1015 #, c-format msgid "Bad Plugin Options command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1066 #, c-format msgid "Bad RestoreObject command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1166 msgid "2909 Bad RestoreObject command.\n" msgstr "" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "" #: src/filed/dir_cmd.c:1696 #, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1708 #, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "" #: src/filed/filed.c:61 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: tray-monitor [-c configuratiebestand] [-d debug_level]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -dt weergeven tijd in debug output\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, c-format msgid "Unable to create MDB environment: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:81 #, fuzzy, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/filed/accurate_lmdb.c:90 #, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:97 #, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:103 #, c-format msgid "Unable to start a write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:109 #, fuzzy, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, fuzzy, c-format msgid "Unable insert new data: %s\n" msgstr "Bestand niet in catalog: %s\n" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, fuzzy, c-format msgid "Unable close write transaction: %s\n" msgstr "Kan de service niet installeren" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, fuzzy, c-format msgid "Unable to create write transaction: %s\n" msgstr "Kan configuratiebestand niet lezen" #: src/filed/accurate_lmdb.c:249 #, fuzzy, c-format msgid "Unable to create read transaction: %s\n" msgstr "Kan configuratiebestand niet lezen" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, fuzzy, c-format msgid "Unable to renew read transaction: %s\n" msgstr "Kan configuratiebestand niet lezen" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, c-format msgid "Unable create cursor: %s\n" msgstr "" #: src/filed/status.c:87 #, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, c-format msgid " %s%s %s Job started: %s\n" msgstr "" #: src/filed/status.c:201 #, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr "" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "" #: src/filed/authenticate.c:301 #, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, c-format msgid "Cannot verify checksum for %s\n" msgstr "" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr "" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "Lees fout op bestand %s. FOUT=%s\n" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "Te veel fouten. OpdrachtFouten=%d.\n" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:79 #, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:139 msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: tray-monitor [-c configuratiebestand] [-d debug_level]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -dt weergeven tijd in debug output\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "Verbonden" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "Opdracht aan het uitvoeren ..." #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Versie: %s (%s) %s %s %s\n" "\n" "Specificatie: bat [-s] [-c configuratiebestand] [-d debug_level] " "[configuratiebestand]\n" " -c gebruik configuratiebestand\n" " -d instellen debug level op \n" " -s geen signaleringen\n" " -t test - lees configuratie en stop\n" " -? geef deze melding.\n" "\n" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "Console: naam=%s\n" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "Al verbonden\"%s\".\n" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" "Verbinden met Director %s:%d\n" "\n" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "Initialiseren ..." #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "Opdracht gereed ..." #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "Wacht op invoer op opdrachtregel in hoofdscherm ..." #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "Wacht op invoer op opdrachtregel ..." #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "Opdracht mislukt." #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "Director niet verbonden." #, fuzzy #~ msgid "Unable to load any shared library for .\n" #~ msgstr "Kan job cond variabele niet initialiseren: ERR=%s\n" #~ msgid "Enter autochanger drive[0]: " #~ msgstr "Voer autochanger drive[0] in: " #~ msgid "" #~ "Copyright (C) 2005 Christian Masopust\n" #~ "Written by Christian Masopust (2005)\n" #~ "\n" #~ "Version: " #~ msgstr "" #~ "Copyright (C) 2005 Christian Masopust\n" #~ "Gemaakt door Christian Masopust (2005)\n" #~ "\n" #~ "Versie: " #, fuzzy #~ msgid "# Bareos bwx-console Configuration File\n" #~ msgstr "Corrigeer configuratie bestand aub.\n" #~ msgid "Save and close" #~ msgstr "Opslaan en afsluiten" #, fuzzy #~ msgid "Enter restore mode" #~ msgstr "Terugzetten afbreken" #~ msgid "Cancel restore" #~ msgstr "Terugzetten afbreken" #~ msgid "Remove" #~ msgstr "Verwijderen" #~ msgid "Refresh" #~ msgstr "Verversen" #~ msgid "M" #~ msgstr "M" #~ msgid "Size" #~ msgstr "Omvang" #~ msgid "Perm." #~ msgstr "Perm." #~ msgid "User" #~ msgstr "Gebruiker" #~ msgid "Group" #~ msgstr "Groep" #~ msgid "Job Name" #~ msgstr "Naam opdracht:" #~ msgid "Please configure parameters concerning files to restore :" #~ msgstr "Configureer parameters voor het terugzetten van bestanden aub :" #~ msgid "always" #~ msgstr "altijd" #~ msgid "if newer" #~ msgstr "indien nieuwer" #~ msgid "if older" #~ msgstr "indien ouder" #~ msgid "never" #~ msgstr "nooit" #, fuzzy #~ msgid "Please configure parameters concerning files restoration :" #~ msgstr "Configureer parameters voor het terugzetten van bestanden aub :" #, fuzzy #~ msgid "Error : no clients returned by the director." #~ msgstr "Verbonden met de director." #, fuzzy #~ msgid "Error : no storage returned by the director." #~ msgstr "Verbonden met de director." #, fuzzy #~ msgid "Error : no jobs returned by the director." #~ msgstr "Verbonden met de director." #, fuzzy #~ msgid "RestoreFiles" #~ msgstr "Terugzetten geannuleerd." #, fuzzy #~ msgid "Please select a client." #~ msgstr "Kan de geselecteerde client niet vinden." #, fuzzy #~ msgid "Please select a restore date." #~ msgstr "Kiest u een director (1-%d): " #, fuzzy #~ msgid "Unexpected question has been received.\n" #~ msgstr "<< Onverwacht signaal ontvangen : " #, fuzzy #~ msgid "bwx-console: unexpected restore question." #~ msgstr "bwx-console: onverwachte director's opdracht" #, fuzzy #~ msgid " file selected to be restored." #~ msgstr "Selecteer Job media:" #, fuzzy #~ msgid "Please configure your restore (%ld files selected to be restored)..." #~ msgstr "Configureer parameters voor het terugzetten van bestanden aub :" #, fuzzy #~ msgid "Restore failed : no file selected.\n" #~ msgstr "Kan de geselecteerde client niet vinden." #, fuzzy #~ msgid "Restore failed : no file selected." #~ msgstr "Kan de geselecteerde client niet vinden." #, fuzzy #~ msgid "Restoring, please wait..." #~ msgstr "Terugzetten..." #~ msgid "Job failed." #~ msgstr "Job mislukt." #, fuzzy #~ msgid "Restore job terminated successfully." #~ msgstr "Terugzetten succesvol." #, fuzzy #~ msgid "Restore job terminated successfully.\n" #~ msgstr "Terugzetten succesvol.\n" #, fuzzy #~ msgid "Restore job cancelled by user." #~ msgstr "Terugzetten geannuleerd." #, fuzzy #~ msgid "Restore job cancelled by user.\n" #~ msgstr "Terugzetten geannuleerd." #~ msgid "Restore done successfully.\n" #~ msgstr "Terugzetten succesvol.\n" #~ msgid "Restore done successfully." #~ msgstr "Terugzetten succesvol." #, fuzzy #~ msgid "Applying restore configuration changes..." #~ msgstr "Corrigeer configuratie bestand aub.\n" #~ msgid "Failed to find the selected client." #~ msgstr "Kan de geselecteerde client niet vinden." #~ msgid "Run Restore job" #~ msgstr "Uitvoeren herstel opdracht" #, fuzzy #~ msgid "Restore cancelled.\n" #~ msgstr "Terugzetten geannuleerd." #~ msgid "Restore cancelled." #~ msgstr "Terugzetten geannuleerd." #~ msgid "No results to list." #~ msgstr "Geen resultaten gevonden om te tonen." #~ msgid "No backup found for this client." #~ msgstr "Geen backup gevonden voor deze client." #~ msgid "ERROR" #~ msgstr "FOUT" #, fuzzy #~ msgid "Query failed" #~ msgstr "Job mislukt." #~ msgid "Cannot get previous backups list, see console." #~ msgstr "Kan vorige backuplijst niet ophalen, zie console." #~ msgid "JobName:" #~ msgstr "JobNaam:" #, fuzzy #~ msgid "ifnewer" #~ msgstr "indien nieuwer" #, fuzzy #~ msgid "ifolder" #~ msgstr "indien ouder" #, fuzzy #~ msgid "FileSet:" #~ msgstr "Bestandsnaam" #, fuzzy #~ msgid "Client:" #~ msgstr "Client" #, fuzzy #~ msgid "Storage:" #~ msgstr "Opslag" #~ msgid "Restoring..." #~ msgstr "Terugzetten..." #~ msgid "Please correct configuration file.\n" #~ msgstr "Corrigeer configuratie bestand aub.\n" #, fuzzy #~ msgid "Error : No configuration file loaded\n" #~ msgstr "Wijzigen configuratiebestand" #~ msgid "Connecting...\n" #~ msgstr "Verbinding maken ...\n" #~ msgid "Error : No director defined in config file.\n" #~ msgstr "Fout : Geen director gevonden in uw configuratie.\n" #~ msgid "Multiple directors found in your config file.\n" #~ msgstr "Meerdere directors gevonden in uw configuratiebestand.\n" #~ msgid "Please choose a director (1-%d): " #~ msgstr "Kiest u een director (1-%d): " #, fuzzy #~ msgid "Failed to connect to the director\n" #~ msgstr "Verbinding naar director opnieuw opzetten" #~ msgid "Connected\n" #~ msgstr "Verbonden\n" #~ msgid "<< Unexpected signal received : " #~ msgstr "<< Onverwacht signaal ontvangen : " #~ msgid "Connection terminated\n" #~ msgstr "Verbinding verbroken\n" #~ msgid "Apply" #~ msgstr "Toepassen" #~ msgid "Type your command below:" #~ msgstr "Voer uw opdracht hieronder in:" #~ msgid "Unknown command." #~ msgstr "Onbekende opdracht." #, fuzzy #~ msgid "Bareos bwx-console" #~ msgstr "Over Bareos bwx-console" #~ msgid "Welcome to bareos bwx-console %s (%s)!\n" #~ msgstr "Welkom bij het bareos bwx-console %s (%s)!\n" #~ msgid "&About...\tF1" #~ msgstr "&Over...\tF1" #~ msgid "Show about dialog" #~ msgstr "Toon het Over scherm" #~ msgid "Connect" #~ msgstr "Verbonden" #~ msgid "Connect to the director" #~ msgstr "Verbinden met director" #~ msgid "Disconnect" #~ msgstr "Verbroken" #~ msgid "Disconnect of the director" #~ msgstr "Verbroken van de director" #~ msgid "Change of configuration file" #~ msgstr "Wijziging van configuratiebestand" #~ msgid "Change your default configuration file" #~ msgstr "Wijzig standaard configuratiebestand" #~ msgid "Edit your configuration file" #~ msgstr "Wijzigen configuratiebestand" #~ msgid "E&xit\tAlt-X" #~ msgstr "&Verlaat\tAlt-X" #~ msgid "Quit this program" #~ msgstr "Verlaat dit programma" #~ msgid "&File" #~ msgstr "&Bestand" #~ msgid "&Help" #~ msgstr "&Help" #~ msgid "" #~ "Warning : Unicode is disabled because you are using wxWidgets for GTK+ " #~ "1.2.\n" #~ msgstr "" #~ "Waarschuwing : Unicode is niet actief omdat u wxWidgets for GTK+ 1.2 " #~ "gebruikt.\n" #~ msgid "Send" #~ msgstr "Versturen" #~ msgid "Error while parsing command line arguments, using defaults.\n" #~ msgstr "" #~ "Fout bij verwerken van opdrachtregel variabelen, maak nu gebruik van " #~ "standaard instelling.\n" #~ msgid "Usage: bwx-console [-c configfile] [-w tmp]\n" #~ msgstr "Specificatie: bwx-console [-c configuratiebestand] [-w tmp]\n" #~ msgid "" #~ "It seems that it is the first time you run bwx-console.\n" #~ "This file (%s) has been choosen as default configuration file.\n" #~ "Do you want to edit it? (if you click No you will have to select another " #~ "file)" #~ msgstr "" #~ "Waarschijnlijk gebruikt u bwx-console voor de eerste keer.\n" #~ "Dit bestand (%s) is ingesteld als uw standaard configuratiebestand.\n" #~ "Wilt u dit wijzigen? (Als u Nee selecteert dan moet u een ander bestand " #~ "selecteren)" #~ msgid "First run" #~ msgstr "Eerste run" #~ msgid "" #~ "Unable to read %s\n" #~ "Error: %s\n" #~ "Do you want to choose another one? (Press no to edit this file)" #~ msgstr "" #~ "Kan %s\n" #~ " niet lezenFout: %s\n" #~ "Wilt u een andere kiezen? (Toets nee om het bestand te wijzigen)" #~ msgid "Please choose a configuration file to use" #~ msgstr "Kies een configuratiebestand om te gebruiken" #~ msgid "" #~ "This configuration file has been successfully read, use it as default?" #~ msgstr "Configuratiebestand met succes gelezen. Als standaard gebruiken?" #~ msgid "Configuration file read successfully" #~ msgstr "Configuratiebestand met succes gelezen" #~ msgid "Using this configuration file: %s\n" #~ msgstr "Dit configuratiebestand wordt gebruikt: %s\n" #~ msgid "Connecting to the director..." #~ msgstr "Verbinden met director ..." #~ msgid "Quitting.\n" #~ msgstr "Bezig met afsluiten.\n" #~ msgid "" #~ "Welcome to Bareos bwx-console.\n" #~ "Written by Nicolas Boichat \n" #~ "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n" #~ msgstr "" #~ "Welkom bij Bareos bwx-console.\n" #~ "Geschreven door Nicolas Boichat \n" #~ "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n" #~ msgid "About Bareos bwx-console" #~ msgstr "Over Bareos bwx-console" #~ msgid "Please choose your default configuration file" #~ msgstr "Kies aub uw standaard configuratiebestand" #~ msgid "Use this configuration file as default?" #~ msgstr "Dit configuratiebestand als standaard gebruiken?" #~ msgid "Configuration file" #~ msgstr "Configuratiebestand" #~ msgid "Console thread terminated." #~ msgstr "Console taak beeindigd." #~ msgid "Connection to the director lost. Quit program?" #~ msgstr "Verbinding met de director verbroken. Programma stoppen?" #~ msgid "Connection lost" #~ msgstr "Verbinding verloren" #~ msgid "Connected to the director." #~ msgstr "Verbonden met de director." #~ msgid "Reconnect" #~ msgstr "Opnieuw verbinden" #~ msgid "Reconnect to the director" #~ msgstr "Verbinding naar director opnieuw opzetten" #~ msgid "Disconnected of the director." #~ msgstr "Verbinding verbroken met director" #~ msgid "bwx-console: unexpected director's question." #~ msgstr "bwx-console: onverwachte director's opdracht" #, fuzzy #~ msgid "Error writing component file.\n" #~ msgstr "Fout bij schrijven van bsr bestand.\n" #, fuzzy #~ msgid "ComponentInfo failed.\n" #~ msgstr "Opdracht mislukt." #, fuzzy #~ msgid "Enter the JobId list to select: " #~ msgstr "Voer de gekozen Job in:" #, fuzzy #~ msgid "canceled" #~ msgstr "Backup geannuleerd" bareos-Release-14.2.6/po/pl.po000066400000000000000000021326361263011562700160460ustar00rootroot00000000000000# bareos translations # Copyright (C) 2010 Inteos Sp. z o.o. # Translated by Inteos Translation Team: pl@inteos.pl # This file is distributed under the same license as the bareos package. # msgid "" msgstr "" "Project-Id-Version: pl\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2010-02-21 09:58+0100\n" "Last-Translator: Grzegorz Grabowski \n" "Language-Team: Inteos PL \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" "nieudane zapytanie %s:\n" "%s\n" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" "nieudane wstawienie %s:\n" "%s\n" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "Problem ze wstawieniem: problematycznych_wierszy=%s\n" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" "nieudana aktualizacja: %s\n" "%s\n" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "Nieudana aktualizacja: problematycznych_wierszy=%s dla %s\n" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" "nieudane skasowanie %s:\n" "%s\n" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "błąd pobierania wiersza: %s\n" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "Długość ścieżki wynosi zero. Plik=%s\n" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "Brak rezultatów do wylistowania.\n" #: src/cats/sql.c:789 #, fuzzy msgid "Could not init database batch connection\n" msgstr "Nie można zainicjować wsadowego połączenia do bazy danych" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "Nieznany rodzaj bazy danych: %s\n" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "Nie można zainicjalizowa blokady BD. ERR=%s\n" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "Nie można połączyć się do interfejsu DBI. Typ=%s Baza danych=%s Użytkownik=%" "s\n" "Możliwe przyczyny: Nie działa SQL serwer; hasło jest niepoprawne; " "przekroczono max_connections.\n" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "Błąd stworzenia atrybutu. %s" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "Nieudane zapytanie: %s: ERR=%s\n" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "błąd uruchomienia trybu wsadowego: %s" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "Nie wskazano rodzaju sterownika w zasobach Katalogu.\n" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "Niepoprawny rodzaj sterownika, powinien być \"dbi:\"\n" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "Nazwa użytkownika dla DBI powinna być dostarczona.\n" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Zadania %s. ERR=%s\n" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "rekord puli %s ju istnieje\n" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Puli %s: ERR=%s\n" #: src/cats/sql_create.c:260 #, fuzzy, c-format msgid "More than one Device!: %d\n" msgstr "Więcej niż jeden Klient!: %d\n" #: src/cats/sql_create.c:265 #, fuzzy, c-format msgid "error fetching Device row: %s\n" msgstr "błąd pobierania wiersza: %s\n" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu bd Urządzenia %s: ERR=%s\n" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "Więcej niż jeden rekord Storage!: %d\n" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "błąd pobierania wiersza Storage: %s\n" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Storage %s. ERR=%s\n" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "rekord mediatype %s już istnieje\n" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu mediatype %s: ERR=%s\n" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "Wolumen \"%s\" już istnieje.\n" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Media %s: ERR=%s\n" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "Więcej niż jeden Klient!: %d\n" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "błąd pobierania wiersza Klienta: %s\n" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Klienta %s. ERR=%s\n" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "Więcej niż jedna Ścieżka: %s dla ścieżki: %s\n" #: src/cats/sql_create.c:662 #, fuzzy, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Ścieżki. ERR=%s\n" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Liczników %s. ERR=%s\n" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "Więcej niż jeden FileSet!: %d\n" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "błąd pobierania wiersza FileSet: ERR=%s\n" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD FileSet %s. ERR=%s\n" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "Nieudane stworzenie rekordu bd Pliku %s. ERR=%s" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "Więcej niż jedna Nazwa pliku! %s dla pliku: %s\n" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "Błąd pobierania wiersza dla pliku=%s: ERR=%s\n" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu Filename %s. ERR=%s\n" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "Próba umieszczenia nie-atrybutów w katalogu. Strumień=%d\n" #: src/cats/sql_create.c:1118 #, fuzzy msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "Nie można Skopiować/Zmigrować zadania używając BaseJob" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "ERR=JobIds są puste\n" #: src/cats/sql_create.c:1270 #, fuzzy, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "Nieudane stworzenie rekordu bd Pliku %s. ERR=%s" #: src/cats/sql_create.c:1316 #, fuzzy, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Zadania %s. ERR=%s\n" #: src/cats/sql_create.c:1367 #, fuzzy, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Media %s: ERR=%s\n" #: src/cats/sql_create.c:1399 #, fuzzy, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Zadania %s. ERR=%s\n" #: src/cats/sql_create.c:1442 #, fuzzy, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Zadania %s. ERR=%s\n" #: src/cats/sql_create.c:1499 #, fuzzy, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD FileSet %s. ERR=%s\n" #: src/cats/sql_create.c:1543 #, fuzzy, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "Nieudane stworzenie rekordu BD Klienta %s. ERR=%s\n" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" "Nie można połączyć się do serwera MySQL.\n" "Baza danych=%s Użytkownik=%s\n" "Nieudane MySQL connect, moliwe e nie dziaa serwer lub twoja autoryzacja jest " "niepoprawna.\n" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "Nazwa użytkownika dla MySQL powinna by dostarczona.\n" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "Rekord puli %s nie istnieje\n" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "Oczekiwano jeden rekord puli, otrzymano %d\n" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "Błąd pobierania wiersza %s\n" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "Nie znaleziono wcześniejszego rekordu Zadania Pełnego Backup'u.\n" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "Nieznany poziom=%d\n" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" "Nie znaleziono rekordu Zadania: ERR=%s\n" "CMD=%s\n" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "Nieznany poziom Zadania=%d\n" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "Nie znaleziono Zadania dla: %s.\n" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "Nie znaleziono Zadania dla: %s\n" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "Rządanie dla elementu Wolumenu %d większe od %d lub mniejsze niż 1\n" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "Nie znaleziono rekordu Wolumenu dla elementu %d.\n" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "Nieudane zapytanie: %s\n" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "Te JobIds posiadają następujące kopie:\n" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "Katalog posiada następujące kopie:\n" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "Nie można otworzyć bazy danych \"%s\": ERR=%s\n" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 #, fuzzy msgid "Could not init database connection" msgstr "Nie można zainicjować wsadowego połączenia do bazy danych" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "Baza danych %s nie istnieje, proszę utworzyć ją.\n" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "Nie mogę otworzyć Bazy danych=%s. ERR=%s\n" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "nieznany" #: src/cats/ingres.c:82 #, fuzzy msgid "Failed to allocate space for query filter.\n" msgstr "Nieudana alokacja pamici dla podpisu kryptograficznego.\n" #: src/cats/ingres.c:103 #, fuzzy msgid "Failed to allocate space for query filters.\n" msgstr "Nieudana alokacja pamici dla podpisu kryptograficznego.\n" #: src/cats/ingres.c:257 #, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" "Nie można połączyć się do serwera Ingres.\n" "Baza danych=%s Użytkownik=%s\n" "Najprawdopodobniej nie działa lub twoje hasło jest niepoprawne.\n" #: src/cats/ingres.c:1031 msgid "A user name for Ingres must be supplied.\n" msgstr "Nazwa użytkownika dla Ingres powinna być dostarczona.\n" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "Błąd pobierania rekordu: %s\n" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "Brak rekordu Pliku w Katalogu.\n" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "Więcej niż jedna nazwa pliku!: %s dla pliku %s\n" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "Rekord nazwy pliku: %s nie znaleziony.\n" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "Rekord nazwy pliku: %s nie znaleziony w Katalogu.\n" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "Rekord ścierzki: %s nie znaleziony.\n" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "Rekord ścierzki: %s nie znaleziony w Katalogu.\n" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "Brak Zadań dla JobIds dla %s\n" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "Nie znaleziono wolumenów dla JobId=%d\n" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "Nie znaleziono Wolumenu dla JobId %d w Katalogu.\n" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "Brak rekordu Puli w Katalogu.\n" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "Więcej niż jeden Klient!: %s\n" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "Nie znaleziono rekordu Klienta w Katalogu.\n" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "Więcej niż jeden Licznik!: %d\n" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "błąd pobierania wiersza Licznika: %s\n" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "Rekord licznika: %s nie znaleziono w Katalogu.\n" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "Rekord Fileset \"%s\" nie znaleziony.\n" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "Rekord Fileset nie znaleziony w Katalogu.\n" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "nieudane zapytanie dbids: ERR=%s\n" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "Więcej niż jeden Wolumen!: %s\n" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "Brak rekordu Medium MediaId=%s\n" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "Brak rekordu Medium dla Wolumenu \"%s\"\n" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "Brak rekordu Medium dla MediaId=%u w Katalogu.\n" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "Brak rekordu Medium dla Vol=%s w Katalogu.\n" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, fuzzy, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "nieudane fopen %s: ERR=%s\n" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 #, fuzzy msgid "Quota record not found in Catalog.\n" msgstr "Brak rekordu Puli w Katalogu.\n" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 #, fuzzy msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "Brak rekordu Puli w Katalogu.\n" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" "Nie można połączyć się do serwera PostgreSQL. Baza danych=%s Użytkownik=%s\n" "Moliwe przyczyny: nie działa serwer SQL; niepoprawne hasło; przekroczono " "max_connections.\n" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "błąd pobierania curval: %s\n" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "błąd zakończenia trybu wsadowego: %s" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "błąd kopiowania w trybie wsadowym: %s" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "Nazwa użytkownika dla MySQL powinna by dostarczona.\n" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 #, fuzzy msgid "Catalog Backends Dir not configured.\n" msgstr "Włączone TLS lecz nie zostao skonfigurowane.\n" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, fuzzy, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, fuzzy, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, fuzzy, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/cats/cats_backends.c:236 #, fuzzy, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/console/console_conf.c:143 #, fuzzy, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "Konsola: nazwa=%s plikrc=%s plikhist=%s\n" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "Director: nazwa=%s adres=%s DIRport=%d\n" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "Element %s jest wymagany w zasobie %s, lecz nie został znaleziony.\n" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" "Próba definicji kolejnego zasobu %s nazwanego \"%s\" nie jest dozwolona.\n" #: src/console/console.c:116 #, fuzzy, c-format msgid "" "\n" "Version: " msgstr "Wersja" #: src/console/console.c:170 msgid "input from file" msgstr "wkład z pliku" #: src/console/console.c:171 msgid "output to file" msgstr "dane wyjściowe dla pliku" #: src/console/console.c:172 msgid "quit" msgstr "wyjdź" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "dane wyjściowe dla pliku lub terminala" #: src/console/console.c:174 msgid "sleep specified time" msgstr "określony czas uśpienia" #: src/console/console.c:175 msgid "print current time" msgstr "wyświetl aktualny czas" #: src/console/console.c:176 msgid "print Console's version" msgstr "wyświetl wersję konsoli" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "wykonaj polecenie zewnętrzne" #: src/console/console.c:179 msgid "exit = quit" msgstr "wyjdź" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "zed_keys = użyj kluczy zed zamiast kluczy bash" #: src/console/console.c:181 msgid "help listing" msgstr "listing pomocy" #: src/console/console.c:183 msgid "set command separator" msgstr "ustaw separator poleceń" #: src/console/console.c:217 #, fuzzy msgid ": is an invalid command\n" msgstr "Za komenda level: %s\n" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "Nieprawidłowy znak seperatora.\n" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "Problem logiki polecenia\n" #: src/console/console.c:996 #, fuzzy, c-format msgid "Can't find %s in Director list\n" msgstr "Nie można znale zasobu Director %s\n" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "%2d: %s w %s:%d\n" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "%s nie jest liczbą. Musisz wybrać liczbę między 1 a %d\n" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "Musisz wybrać liczbę między 1 a %d\n" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "Nieudana inicjalizacja biblioteki kryptograficznej.\n" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "Podłączenie do Dyrektora %s:%d\n" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, fuzzy, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "Nieudana inicjalizacja kontekstu TLS dla Dyrektora \"%s\" w %s.\n" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, fuzzy, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "Nieudana inicjalizacja kontekstu TLS dla Dyrektora \"%s\" w %s.\n" #: src/console/console.c:1335 #, fuzzy msgid "Enter a period to cancel a command.\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, fuzzy, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie s " "zdefiniowane dla Dyrektora \"%s\" w %s. Co najmniej jedno skadowanie " "certyfikatu CA jest wymagane kiedy jest używane \"TLS Verify Peer\".\n" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, fuzzy, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" "Brak definicji zasobu demona Plików w %s\n" "Bez tego nie wiem kim jestem :-(\n" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, fuzzy, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie zostay " "zdefiniowane dla demona Plików w %s.\n" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "Zbyt wiele argumentów komendy wejściowej.\n" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "Pierwszym argumentem komendy wejściowej musi być nazwa pliku.\n" #: src/console/console.c:1524 #, fuzzy, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "Nie można otworzyć pliku wejciowego FileSet: %s. ERR=%s\n" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, fuzzy, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "Nie można otworzyć pliku wejciowego FileSet: %s. ERR=%s\n" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "Zbyt wiele argumentów. Otocz polecenie podwójnym cudzysłowem.\n" #: src/console/console.c:1600 #, fuzzy, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr " Nie można otworzyć \"%s\": ERR=%s.\n" #: src/console/console.c:1612 #, fuzzy, c-format msgid "Autochanger error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 #, fuzzy msgid "Pool resource" msgstr "Zasób Klienta" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 #, fuzzy msgid "No Storage specification found in Job or Pool.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, fuzzy, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "Uruchom Wirtualny Backup JobId %s, Job=%s\n" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, fuzzy, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, fuzzy, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "Błąd aktualizacji rekordu Klienta. ERR=%s\n" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 #, fuzzy msgid "Backup OK -- with warnings" msgstr "%s OK -- z ostrzeżeniami" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 #, fuzzy msgid "*** Backup Error ***" msgstr "*** Błąd Weryfikacji ***" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 #, fuzzy msgid "Backup Canceled" msgstr "%s Anulowano" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, fuzzy, c-format msgid "Inappropriate term code: %c\n" msgstr "Nieprawidłowy kod: %d %c\n" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, fuzzy, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "Nie mogę otrzyma rekordu Zadania dla JobId=%s: ERR=%s\n" #: src/dird/bsr.c:220 #, fuzzy, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "Nie można zainicjować zmiennej warunkowej zadania: ERR=%s\n" #: src/dird/bsr.c:269 #, fuzzy, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" #: src/dird/bsr.c:291 #, fuzzy msgid "Error writing bsr file.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" #: src/dird/bsr.c:376 #, fuzzy msgid "No Volumes found to restore.\n" msgstr "Błąd wersji Zlib" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "Nie można otworzyć pliku bootstrap %s: ERR=%s\n" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, c-format msgid "Could not get storage resource '%s'.\n" msgstr "Nie można otrzyma zasobu storage '%s'.\n" #: src/dird/admin.c:54 #, fuzzy, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "Start %s JobId %s, Job=%s\n" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "" #: src/dird/admin.c:89 #, fuzzy msgid "*** Admin Error ***" msgstr "*** Błąd Weryfikacji ***" #: src/dird/admin.c:93 #, fuzzy msgid "Admin Canceled" msgstr "%s Anulowano" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -r uruchom teraz zadanie \n" " -s brak sygnaw\n" " -t test - odczytaj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "Zbyt wiele żądań przeładowania. Żądanie zignorowane.\n" # fuzzy: src/dird/dird.c:536 #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "Przekroczono zakres wpisów tabeli przeładowania. Poddaję się.\n" #: src/dird/dird.c:582 #, fuzzy msgid "Resetting previous configuration.\n" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" "Brak definicji zasobu Dyrektora w %s\n" "Bez tego nie wiem kim jestem :-(\n" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "Dozwolony tylko jeden zasób Dyrektora w %s\n" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 #, fuzzy msgid "TLS required but not configured in BAREOS.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "Nie zdefiniowany plik \"TLS Certificate\" dla Dyrektora \"%s\" w %s.\n" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "Nie zdefiniowany plik \"TLS Key\" dla Dyrektora \"%s\" w %s.\n" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie s " "zdefiniowane dla Dyrektora \"%s\" w %s. Co najmniej jedno skadowanie " "certyfikatu CA jest wymagane kiedy jest używane \"TLS Verify Peer\".\n" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "Nieudana inicjalizacja kontekstu TLS dla Dyrektora \"%s\" w %s.\n" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "Brak definicji rekordw Zadania w %s\n" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "Nie zdefiniowany plik \"TLS Certificate\" dla Konsoli \"%s\" w %s.\n" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "Nie zdefiniowany plik \"TLS Key\" dla Konsoli \"%s\" w %s.\n" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie są " "zdefiniowane dla Konsoli \"%s\" w %s. Co najmniej jedno składowanie " "certyfikatu CA jest wymagane kiedy jest używane \"TLS Verify Peer\".\n" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "Nieudana inicjalizacja kontekstu TLS dla demona Plików \"%s\" in %s.\n" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie zostay " "zdefiniowane dla demona Plików \"%s\" w %s.\n" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie zostay " "zdefiniowane dla demona Przechowywania \"%s\" w %s.\n" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "Nieudana inicjalizacja kontekstu TLS dla Storage \"%s\" w %s.\n" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, fuzzy, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "Nie można otworzyć Katalogu \"%s\", baza danych \"%s\".\n" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "Nie można otworzyć Katalogu \"%s\", baza danych \"%s\".\n" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "%s" #: src/dird/dird.c:1110 #, c-format msgid "Could not create storage record for %s\n" msgstr "Nie można stworzyć rekordu storage dla %s\n" #: src/dird/dird.c:1119 #, c-format msgid "Could not update storage record for %s\n" msgstr "Nie można uaktualni rekordu storage dla %s\n" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Nie można skompilowa wzorca regex \"%s\" ERR=%s\n" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "Zakończ automatyczne obcięcie (ang. auto prune).\n" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" "ERR: W podanym pliku konfiguracyjnym [%s] nie można odnaleźć Katalogu o " "nazwie [%s]\n" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "ERR: w podanym pliku konfiguracyjnym [%s] brakuje sekcji Katalogu\n" #: src/dird/dbcheck.c:221 #, fuzzy msgid "Error no Director resource defined.\n" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "Niepoprawna ilość argumentów.\n" #: src/dird/dbcheck.c:255 #, fuzzy msgid "Working directory not supplied.\n" msgstr "Szyfrowanie rzadkich danych nie jest wspierane.\n" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "Port bazy danych musi mieć wartość numeryczną.\n" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "Port bazy danych musi mieć wartość całkowitą.\n" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "Witam, to jest program sprawdzający poprawność bazy danych.\n" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "Modyfikacja bazy danych w trakcie." #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "Modyfikacja bazy danych wyłączona." #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, fuzzy, c-format msgid " Verbose is on.\n" msgstr "Wersja" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, fuzzy, c-format msgid " Verbose is off.\n" msgstr "Wersja" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "Proszę wybrać funkcję którą chcesz wykonać.\n" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "Wybierz numer funkcji: " #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "Baza danych zostanie zmodyfikowana.\n" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "Baza danych NIE zostanie zmodyfikowana.\n" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "JobId=%s Nazwa=\"%s\" StartTime=%s\n" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "Usuwanie: %s\n" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "Sprawdzanie istnienia duplikatów nazw plików.\n" #: src/dird/dbcheck.c:705 #, fuzzy, c-format msgid "Found %d duplicate Filename records.\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "Znaleziono %d for: %s\n" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "Sprawdzanie istnienia duplikatów nazw ścieżek.\n" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "Znaleziono %d wystąpień duplikatów ścieżek.\n" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, fuzzy, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/dbcheck.c:850 #, fuzzy, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, fuzzy, c-format msgid "Found %d orphaned File records.\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/dbcheck.c:895 #, fuzzy, c-format msgid "Deleting %d orphaned File records.\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "Czy utworzyć tymczasowy index? (yes/no)" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, fuzzy, c-format msgid "Found %d orphaned Filename records.\n" msgstr "Nie można pobra lub stworzyć rekordu FileSet.\n" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, fuzzy, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/dbcheck.c:1062 #, fuzzy, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, fuzzy, c-format msgid "Found %d orphaned Client records.\n" msgstr "Nie można stworzyć rekordu Klienta. ERR=%s\n" #: src/dird/dbcheck.c:1104 #, fuzzy, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "Nie można stworzyć rekordu Klienta. ERR=%s\n" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, fuzzy, c-format msgid "Found %d orphaned Job records.\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "Weryfikacja wystąpień wpisów Zadań Admin'a\n" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "Znaleziono %d wpisów zadań Admin'a\n" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "Usuwanie %d wpisów zadań Admina.\n" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "Weryfikacja wystąpień wpisów Zadań Przywrócenia.\n" #: src/dird/dbcheck.c:1201 #, fuzzy, c-format msgid "Found %d Restore Job records.\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "Usuwanie %d wpisów zadań Przywrócenia.\n" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "Wyszukiwanie nazw plików z ukośnikiem zamykającym\n" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "Znaleziono %d wystąpień błędnych nazw plików.\n" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "Naprawa %d wystąpień błędnych nazw plików.\n" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "Wyszukiwanie ścieżek bez ukośnika zamykającego\n" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "Znaleziono %d wystąpień błędnych ścieżek.\n" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "Utwórz indeks tymczasowy... To może chwilę potrwać!\n" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "Indeks tymczasowy utworzony.\n" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "Usuń indeks tymczasowy.\n" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "Indeks tymczasowy %s usuniety.\n" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, fuzzy, c-format msgid "Error getting Quota value: ERR=%s" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/dird/quota.c:187 #, fuzzy msgid "Quota does NOT include Failed Jobs\n" msgstr "Nie można ustawi pola Finder Info na %s\n" #: src/dird/quota.c:207 #, fuzzy, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, fuzzy, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, fuzzy, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "Ustawiam rozmiar bloku bufora na %u bajtów.\n" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, fuzzy, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/ua_run.c:88 #, fuzzy, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "Błąd aktualizacji rekordu Klienta. ERR=%s\n" #: src/dird/ua_run.c:102 #, fuzzy, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/ua_run.c:170 #, fuzzy, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "Błąd aktualizacji rekordu Klienta. ERR=%s\n" #: src/dird/ua_run.c:312 #, fuzzy msgid "rerun these jobids? (yes/no): " msgstr "Czy utworzyć tymczasowy index? (yes/no)" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 #, fuzzy msgid "Job failed.\n" msgstr "Status zadania: Anulowane" #: src/dird/ua_run.c:528 #, fuzzy, c-format msgid "Job queued. JobId=%s\n" msgstr "Zadanie zakolejkowane. JobId=" #: src/dird/ua_run.c:535 #, fuzzy msgid "Job not run.\n" msgstr "Nie znaleziono zadania %s.\n" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 #, fuzzy msgid "Level" msgstr "nigdy" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 #, fuzzy msgid "Storage" msgstr "Demon Skadowania" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 #, fuzzy msgid "FileSet" msgstr "Demon Plików" #: src/dird/ua_run.c:555 #, fuzzy msgid "Restore Client" msgstr "Odtwarzanie Anulowane" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 #, fuzzy msgid "Client" msgstr "Klient:" #: src/dird/ua_run.c:559 #, fuzzy msgid "Backup Format" msgstr "Backup" #: src/dird/ua_run.c:560 #, fuzzy msgid "When" msgstr "Kiedy:" #: src/dird/ua_run.c:561 #, fuzzy msgid "Priority" msgstr "Priorytet:" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "" #: src/dird/ua_run.c:571 msgid "NextPool" msgstr "" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 #, fuzzy msgid "Verify Job" msgstr "Weryfikacja OK" #: src/dird/ua_run.c:581 #, fuzzy msgid "Bootstrap" msgstr "Bootstrap:" #: src/dird/ua_run.c:582 #, fuzzy msgid "Where" msgstr "Gdzie:" #: src/dird/ua_run.c:583 #, fuzzy msgid "File Relocation" msgstr "Demon Plików" #: src/dird/ua_run.c:584 #, fuzzy msgid "Replace" msgstr "Zamiana:" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 #, fuzzy msgid "Select parameter to modify" msgstr "Wybierz rodzaj demona do zabicia" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 #, fuzzy msgid "Please enter Backup Format: " msgstr "Proszę wskaż datę odtwarzania." #: src/dird/ua_run.c:650 #, fuzzy msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "Wprowadź datę w formacie YYYY-MM-DD HH:MM:SS :" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 #, fuzzy msgid "Enter new Priority: " msgstr "Priorytet:" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 #, fuzzy msgid "Please enter the Bootstrap file name: " msgstr "Nieudane stworzenie pliku bootstrap.\n" #: src/dird/ua_run.c:700 #, fuzzy, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr " Nie można otworzyć %s: ERR=%s.\n" #: src/dird/ua_run.c:730 #, fuzzy msgid "Please enter the full path prefix for restore (/ for none): " msgstr "Proszę wskaż datę odtwarzania." #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 #, fuzzy msgid "Please enter Plugin Options string: " msgstr "Wprowadź nazwę pliku (bez ścieżki):" #: src/dird/ua_run.c:774 #, fuzzy msgid "Replace:\n" msgstr "Zamiana:" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 #, fuzzy msgid "command line" msgstr "Nieudana komenda." #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, fuzzy, c-format msgid "Invalid replace option: %s\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 msgid "Storage from Run NextPool override" msgstr "" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, fuzzy, c-format msgid "Level \"%s\" not valid.\n" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 #, fuzzy msgid "Please enter the path prefix to strip: " msgstr "Wprowadź nazwę pliku (bez ścieżki):" #: src/dird/ua_run.c:1035 #, fuzzy msgid "Please enter the path prefix to add (/ for none): " msgstr "Proszę wskaż datę odtwarzania." #: src/dird/ua_run.c:1046 #, fuzzy msgid "Please enter the file suffix to add: " msgstr "Wprowadź nazwę pliku (bez ścieżki):" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, fuzzy, c-format msgid "regexwhere=%s\n" msgstr "Ze polecenie regexp where. where=%s\n" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 #, fuzzy msgid "Please enter filename to test: " msgstr "Wprowadź nazwę pliku (bez ścieżki):" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "Peny" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "Przyrostowy" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "Rnicowy" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "Od" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 #, fuzzy msgid "Select level" msgstr "Wybierz pozycję: " #: src/dird/ua_run.c:1179 #, fuzzy msgid "Initialize Catalog" msgstr "Inicjalizacja Katalogu" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "Weryfikacja Katalogu" #: src/dird/ua_run.c:1181 src/lib/util.c:473 #, fuzzy msgid "Verify Volume to Catalog" msgstr "Wolumen do Katalogu" #: src/dird/ua_run.c:1182 src/lib/util.c:476 #, fuzzy msgid "Verify Disk to Catalog" msgstr "Dysk do Katalogu" #: src/dird/ua_run.c:1183 #, fuzzy msgid "Verify Volume Data (not yet implemented)" msgstr "JobType jeszcze nie zaimplementowany\n" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 #, fuzzy msgid "*None*" msgstr "*brak*" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, fuzzy, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 #, fuzzy msgid "Please enter a JobId for restore: " msgstr "Proszę wskaż datę odtwarzania." #: src/dird/ua_run.c:1438 #, fuzzy, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/dird/ua_run.c:1498 #, fuzzy, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, fuzzy, c-format msgid "RegexWhere: %s\n" msgstr "Reg: %s\n" #: src/dird/ua_run.c:1542 #, fuzzy, c-format msgid "Where: %s\n" msgstr "Data zapisana : %s\n" #: src/dird/ua_run.c:1546 #, fuzzy, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, fuzzy, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/dird/ua_run.c:1600 #, fuzzy msgid "Run Copy job\n" msgstr "Uruchom job" #: src/dird/ua_run.c:1602 #, fuzzy msgid "Run Migration job\n" msgstr "Nie można rurchomi zadania migracji.\n" #: src/dird/ua_run.c:1604 #, fuzzy, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/dird/ua_run.c:1629 #, fuzzy, c-format msgid "Unknown Job Type=%d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/dird/ua_run.c:1706 #, fuzzy, c-format msgid "Value missing for keyword %s\n" msgstr "Nieznane sowo kluczowe: %s\n" #: src/dird/ua_run.c:1713 #, fuzzy msgid "Job name specified twice.\n" msgstr "Nie podano nazwy archiwum.\n" #: src/dird/ua_run.c:1721 #, fuzzy msgid "JobId specified twice.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 #, fuzzy msgid "Client specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1738 #, fuzzy msgid "FileSet specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1746 #, fuzzy msgid "Level specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1755 #, fuzzy msgid "Storage specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1763 #, fuzzy msgid "RegexWhere or Where specified twice.\n" msgstr "Specyfikacja \"RegexWhere\" nie została autoryzowana.\n" #: src/dird/ua_run.c:1768 #, fuzzy msgid "No authorization for \"regexwhere\" specification.\n" msgstr "Brak autoryzacji dla FileSet'u \"%s\"\n" #: src/dird/ua_run.c:1775 #, fuzzy msgid "Where or RegexWhere specified twice.\n" msgstr "Specyfikacja \"RegexWhere\" nie została autoryzowana.\n" #: src/dird/ua_run.c:1780 #, fuzzy msgid "No authoriztion for \"where\" specification.\n" msgstr "Brak autoryzacji dla FileSet'u \"%s\"\n" #: src/dird/ua_run.c:1787 #, fuzzy msgid "Bootstrap specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1795 #, fuzzy msgid "Replace specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1803 #, fuzzy msgid "When specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1811 #, fuzzy msgid "Priority specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 #, fuzzy msgid "Verify Job specified twice.\n" msgstr "Nie skazano zadania.\n" #: src/dird/ua_run.c:1854 #, fuzzy msgid "Migration Job specified twice.\n" msgstr "Nie skazano zadania.\n" #: src/dird/ua_run.c:1862 #, fuzzy msgid "Pool specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1870 #, fuzzy msgid "NextPool specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1886 #, fuzzy msgid "Restore Client specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1894 #, fuzzy msgid "Plugin Options specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1899 #, fuzzy msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "Brak autoryzacji dla Klienta \"%s\"\n" #: src/dird/ua_run.c:1906 #, fuzzy msgid "Spool flag specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "" #: src/dird/ua_run.c:1922 #, fuzzy msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1929 msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "" #: src/dird/ua_run.c:1934 #, fuzzy msgid "Accurate flag specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1941 #, fuzzy msgid "Invalid accurate flag.\n" msgstr "Nieprawidłowy JobId na liście.\n" #: src/dird/ua_run.c:1946 #, fuzzy msgid "Backup Format specified twice.\n" msgstr "określony czas uśpienia" #: src/dird/ua_run.c:1971 #, fuzzy, c-format msgid "Invalid keyword: %s\n" msgstr "Nieznane sowo kluczowe: %s\n" #: src/dird/ua_run.c:1986 #, fuzzy, c-format msgid "Catalog \"%s\" not found\n" msgstr "Wtyczka: \"%s\" nie znaleziona.\n" #: src/dird/ua_run.c:1990 #, fuzzy, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "Brak autoryzacji dla Katalogu \"%s\"\n" #: src/dird/ua_run.c:2001 #, fuzzy, c-format msgid "Job \"%s\" not found\n" msgstr "Nie znaleziono zadania %s.\n" #: src/dird/ua_run.c:2008 #, fuzzy msgid "A job name must be specified.\n" msgstr "Nie skazano zadania.\n" #: src/dird/ua_run.c:2014 #, fuzzy, c-format msgid "No authorization. Job \"%s\".\n" msgstr "Brak autoryzacji dla Zadania \"%s\"\n" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, fuzzy, c-format msgid "Pool \"%s\" not found.\n" msgstr "Wtyczka: \"%s\" nie znaleziona.\n" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, fuzzy, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "Brak autoryzacji dla Zadania \"%s\"\n" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, fuzzy, c-format msgid "Storage \"%s\" not found.\n" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 #, fuzzy msgid "No storage specified.\n" msgstr "Nie skazano zadania.\n" #: src/dird/ua_run.c:2083 #, fuzzy, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "Brak autoryzacji dla Katalogu \"%s\"\n" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, fuzzy, c-format msgid "Client \"%s\" not found.\n" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, fuzzy, c-format msgid "No authorization. Client \"%s\".\n" msgstr "Brak autoryzacji dla Klienta \"%s\"\n" #: src/dird/ua_run.c:2112 #, fuzzy, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/dird/ua_run.c:2130 #, fuzzy, c-format msgid "FileSet \"%s\" not found.\n" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/dird/ua_run.c:2138 #, fuzzy, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "Brak autoryzacji dla FileSet'u \"%s\"\n" #: src/dird/ua_run.c:2145 #, fuzzy, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "Nie znaleziono zadania %s.\n" #: src/dird/ua_run.c:2155 #, fuzzy, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "Wtyczka: \"%s\" nie znaleziona.\n" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 #, fuzzy msgid "Select daemon type for status" msgstr "Wybierz rodzaj demona do zabicia" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, fuzzy, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "%s Wersja: %s (%s) %s %s %s %s\n" #: src/dird/ua_status.c:390 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "Demon wystartowany %s, %d Zada %s uruchomionych od wystartowania.\n" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr " Sterta: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 #, fuzzy msgid "No clients defined.\n" msgstr "Nie zdefiniowano zasobu %s\n" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "Data" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 #, fuzzy msgid "Schedule" msgstr "" "\n" "Zakoczonych Zada:\n" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 #, fuzzy msgid "" "\n" "Scheduled Jobs:\n" msgstr "" "\n" "Zakoczonych Zada:\n" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 #, fuzzy msgid "===================================================================================\n" msgstr "======================================================================\n" #: src/dird/ua_status.c:864 #, fuzzy, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" #: src/dird/ua_status.c:868 #, fuzzy, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "%6d %-6s %8s %10s %-7s %-8s %s\n" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" "\n" "Uruchomione Zadania:\n" #: src/dird/ua_status.c:996 #, fuzzy, c-format msgid "Console connected at %s\n" msgstr "Dyrektor podłączony o: %s\n" #: src/dird/ua_status.c:1006 #, fuzzy msgid "" "No Jobs running.\n" "====\n" msgstr "adne Zadanie nie uruchomione.\n" #: src/dird/ua_status.c:1012 #, fuzzy msgid " JobId Level Name Status\n" msgstr " JobId Poziom Pliki Bajty Status Zakoczone Nazwa \n" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "======================================================================\n" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 #, fuzzy msgid "is running" msgstr "adne Zadanie nie uruchomione.\n" #: src/dird/ua_status.c:1028 #, fuzzy msgid "is blocked" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/dird/ua_status.c:1031 #, fuzzy msgid "has terminated" msgstr "Status zadania: Zakoczone" #: src/dird/ua_status.c:1034 #, fuzzy msgid "has terminated with warnings" msgstr "Przywracanie OK -- z ostrzeżeniami" #: src/dird/ua_status.c:1037 #, fuzzy msgid "has erred" msgstr "były" #: src/dird/ua_status.c:1040 #, fuzzy msgid "has errors" msgstr " (%d bdw)" #: src/dird/ua_status.c:1043 #, fuzzy msgid "has a fatal error" msgstr "Status zadania: Błąd krytyczny" #: src/dird/ua_status.c:1046 #, fuzzy msgid "has verify differences" msgstr "Rnice przy weryfikacji" #: src/dird/ua_status.c:1049 #, fuzzy msgid "has been canceled" msgstr "Status zadania: Anulowane" #: src/dird/ua_status.c:1054 #, fuzzy msgid "is waiting on Client" msgstr "Status zadania: Oczekiwanie na zasoby Klienta" #: src/dird/ua_status.c:1056 #, fuzzy, c-format msgid "is waiting on Client %s" msgstr "Rozłączanie od Klienta %s:%d\n" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, fuzzy, c-format msgid "is waiting on Storage \"%s\"" msgstr "Rozłączanie od Storage %s:%d\n" #: src/dird/ua_status.c:1068 #, fuzzy msgid "is waiting on Storage" msgstr "Status zadania: Oczekiwanie na demon Przechowywania" #: src/dird/ua_status.c:1074 #, fuzzy msgid "is waiting on max Storage jobs" msgstr "Status zadania: Oczekiwanie na demon Przechowywania" #: src/dird/ua_status.c:1077 #, fuzzy msgid "is waiting on max Client jobs" msgstr "Status zadania: Oczekiwanie ze wzgldu na maksymaln ilo zada" #: src/dird/ua_status.c:1080 #, fuzzy msgid "is waiting on max Job jobs" msgstr "Status zadania: Oczekiwanie ze wzgldu na maksymaln ilo zada" #: src/dird/ua_status.c:1083 #, fuzzy msgid "is waiting on max total jobs" msgstr "Status zadania: Oczekiwanie ze wzgldu na maksymaln ilo zada" #: src/dird/ua_status.c:1090 #, fuzzy, c-format msgid "is waiting for its start time at %s" msgstr "Status zadania: Oczekiwanie na czas startu" #: src/dird/ua_status.c:1092 #, fuzzy msgid "is waiting for its start time" msgstr "Status zadania: Oczekiwanie na czas startu" #: src/dird/ua_status.c:1098 #, fuzzy msgid "is waiting for higher priority jobs to finish" msgstr "Status zadania: Oczekiwanie na zakoczenie zada o wyszym priorytecie" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 #, fuzzy msgid "SD despooling Attributes" msgstr "Spooling statystyk:\n" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 #, fuzzy msgid "Dir inserting Attributes" msgstr "Atrybuty Unix" #: src/dird/ua_status.c:1115 #, fuzzy, c-format msgid "is in unknown state %c" msgstr "Nieznany status zadania %c." #: src/dird/ua_status.c:1129 #, fuzzy msgid "is waiting for a mount request" msgstr "Status zadania: Oczekiwanie na zasoby Klienta" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 #, fuzzy msgid "is waiting for Client to connect to Storage daemon" msgstr "Nieudane podłączenie do demona Skadowania: %s:%d\n" #: src/dird/ua_status.c:1146 #, fuzzy, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "Status zadania: Oczekiwanie na zasoby Klienta" #: src/dird/ua_status.c:1177 #, fuzzy, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" #: src/dird/ua_status.c:1181 #, fuzzy, c-format msgid "%6d %-6s %-20s %s\n" msgstr "%6d %-6s %8s %10s %-7s %-8s %s\n" #: src/dird/ua_status.c:1185 #, fuzzy, c-format msgid " %-30s\n" msgstr "Job : %s\n" #: src/dird/ua_status.c:1205 #, fuzzy msgid "No Terminated Jobs.\n" msgstr "" "\n" "Zakoczonych Zada:\n" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" "\n" "Zakoczonych Zada:\n" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr " JobId Poziom Pliki Bajty Status Zakoczone Nazwa \n" #: src/dird/ua_status.c:1213 #, fuzzy msgid "====================================================================\n" msgstr "======================================================================\n" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "Utworzone" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "Bd" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "Rnice" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "Anulowane" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "OK" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 #, fuzzy msgid "OK -- with warnings" msgstr "%s OK -- z ostrzeżeniami" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "Inne" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "%6d %-6s %8s %10s %-7s %-8s %s\n" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 #, fuzzy msgid "No Volumes found, or no barcodes.\n" msgstr "Błąd wersji Zlib" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, fuzzy, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "Demon Przechowywania odrzuci komend Hello\n" #: src/dird/msgchan.c:229 #, fuzzy, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "Demon Przechowywania odrzuci komend Hello\n" #: src/dird/msgchan.c:237 #, fuzzy, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" "\n" "Użycie: testfind [-d debug_level] [-] [pattern1 ...]\n" " -a wyświetl rozszerzone atrybuty (Win32 debug)\n" " -d «nn» set debug level to «nn»\n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level »= 1 prints each file found.\n" "Debug level »= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len » 255.\n" "Truncation is only in the catalog.\n" "\n" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "Reg: %s\n" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, fuzzy, c-format msgid "Err: Could not access %s: %s\n" msgstr " Brak dostpu %s: ERR=%s\n" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, fuzzy, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr " Nie można poda za linkiem %s: ERR=%s\n" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, fuzzy, c-format msgid "Err: Could not stat %s: %s\n" msgstr " Nie można wykona stat %s: ERR=%s\n" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "Pominiecie: Plik nie zapisany. Brak zmiany. %s\n" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "Err: Próba backup'u archiwum. Nie zapisano. %s\n" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, fuzzy, c-format msgid "Err: Could not open directory %s: %s\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, fuzzy, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr " Nieznany rodziaj pliku %d: %s\n" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "===== Nazwa pliku skrócona do 255 znaków: %s\n" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "========== Nazwa ścieżki skrócona do 255 znaków: %s\n" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "========== Zerowa długość ścieżki. Plik=%s\n" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "Ścieżka: %s\n" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, fuzzy, c-format msgid "File: %s\n" msgstr "Za komenda level: %s\n" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "Nieznana opcja include/exclude: %c\n" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "Nie można zaktualizowa licznika %s: ERR=%s\n" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "Nie można stworzyć kontekstu zmiennej: ERR=%s\n" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "Nie można ustawi wywoania zmiennej: ERR=%s\n" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "Nie można ustawi operatora zmiennej: ERR=%s\n" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "Nie można wyplta acucha: ERR=%s\n" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "Nie można rozwin wyraenia \"%s\": ERR=%s.\n" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "Nie można zniszczy kontekstu zmiennej: ERR=%s\n" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr ": jest nieprawidłowym poleceniem.\n" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "Nie mogę otrzyma rekordu Zadania dla JobId=%s: ERR=%s\n" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 #, fuzzy msgid "Could not open SD socket.\n" msgstr "Nie można stworzyć skrt.\n" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 #, fuzzy msgid "Connected to storage daemon\n" msgstr "Nie można skontaktowa się z demonem Skadowania\n" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, fuzzy, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "Podłączenie do Klienta %s:%d\n" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 #, fuzzy msgid "Failed to connect to Client.\n" msgstr "Nieudane podłączenie do demona Plików.\n" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, fuzzy, c-format msgid "Unknown command: %s\n" msgstr "Nieznana komenda." #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 #, fuzzy msgid "Director" msgstr "Demon Dyrektora" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "Wybierz rodzaj demona do zabicia" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "Director wygeneruje deadlock.\n" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "Brak pozwolenia na dostęp do wybranego Klienta lub FileSet'u.\n" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "Nieudane zapytanie: %s. ERR=%s\n" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "nie znaleziono sowa kluczowego zapytania.\n" #: src/dird/ua_dotcmds.c:1116 #, fuzzy, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/dird/ua_dotcmds.c:1130 #, fuzzy, c-format msgid "List Media failed: ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/dird/ua_dotcmds.c:1156 #, fuzzy, c-format msgid "List Location failed: ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "Wprowadź slot" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "Oczekiwano dodatniej wartości całkowitej, wprowadzono: %s\n" # fuzzy : src/dird/ua_input.c:162 #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "Nieprawidłowa odpowiedź. Musisz odpowiedzieć 'yes' lub 'no'.\n" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "Nieprawidłowy znak \"%c\" w komentarzu.\n" #: src/dird/ua_input.c:218 msgid "Comment too long.\n" msgstr "Komentarz za długi.\n" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "Komentarz musi mieć przynajmniej jeden znak.\n" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 #, fuzzy msgid "Cancel a job" msgstr "Anulowane" #: src/dird/ua_cmds.c:112 #, fuzzy msgid "Configure director" msgstr "Edytor pliku konfiguracyjnego" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 msgid "Disable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 #, fuzzy msgid "Terminate Bconsole session" msgstr "wyświetl wersję konsoli" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 #, fuzzy msgid "Print help on specific command" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 #, fuzzy msgid "Label a tape" msgstr "załaduj taśmę" #: src/dird/ua_cmds.c:141 #, fuzzy msgid "List objects from catalog" msgstr "Dysk do Katalogu" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 #, fuzzy msgid "Print current memory usage" msgstr "wyświetl aktualny czas" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "" #: src/dird/ua_cmds.c:164 #, fuzzy msgid "Move slots in an autochanger" msgstr "przetestuj bibliotekę taśmową" #: src/dird/ua_cmds.c:166 #, fuzzy msgid "Prune records from catalog" msgstr "Dysk do Katalogu" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "" #: src/dird/ua_cmds.c:173 #, fuzzy msgid "Query catalog" msgstr "Weryfikacja Katalogu" #: src/dird/ua_cmds.c:175 #, fuzzy msgid "Restore files" msgstr "Odtwarzanie Anulowane" #: src/dird/ua_cmds.c:183 #, fuzzy msgid "Relabel a tape" msgstr "załaduj taśmę" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 #, fuzzy msgid "Rerun a job" msgstr "Uruchom job" #: src/dird/ua_cmds.c:192 #, fuzzy msgid "Resolve a hostname" msgstr "załaduj taśmę" #: src/dird/ua_cmds.c:194 #, fuzzy msgid "Run a job" msgstr "Uruchom job" #: src/dird/ua_cmds.c:202 #, fuzzy msgid "Report status" msgstr "wyświetl status taśmy" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 #, fuzzy msgid "Sets debug level" msgstr "Wybierz rodzaj demona aby ustawić poziom debugingu" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 #, fuzzy msgid "Show resource records" msgstr "Nieznany rodzaj zasobu %d\n" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 #, fuzzy msgid "Print current time" msgstr "wyświetl aktualny czas" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 #, fuzzy msgid "Use specific catalog" msgstr "określony czas uśpienia" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 #, fuzzy msgid "Print Director version" msgstr "Demon Dyrektora" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, fuzzy, c-format msgid "%s: is an invalid command.\n" msgstr ": jest nieprawidłowym poleceniem.\n" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, fuzzy, c-format msgid "The number must be between 0 and %d\n" msgstr "Musisz wybrać liczbę między 1 a %d\n" #: src/dird/ua_cmds.c:409 #, fuzzy msgid "Enter Volume name: " msgstr "Wprowadź nazwę wolumenu: " #: src/dird/ua_cmds.c:413 #, fuzzy msgid "Enter base volume name: " msgstr "Wprowadź nazwę wolumenu: " #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 #, fuzzy msgid "Volume name too long.\n" msgstr "Komentarz za długi.\n" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "Wolumen musi mieć przynajmniej jeden znak.\n" #: src/dird/ua_cmds.c:437 #, fuzzy msgid "Enter the starting number: " msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 #, fuzzy msgid "Enter slot (0 for none): " msgstr "Anulowane" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, fuzzy, c-format msgid "%d Volumes created in pool %s\n" msgstr "Nie znaleziono zasobu Zadania dla \"%s\".\n" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, fuzzy, c-format msgid "JobId %s not a number\n" msgstr "Nie znaleziono zadania %s.\n" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, fuzzy, c-format msgid "Pool %s created.\n" msgstr "Status zadania: Anulowane" #: src/dird/ua_cmds.c:793 #, fuzzy msgid "Failed to set bandwidth limit on Client.\n" msgstr "Nieudane podłączenie do demona Plików.\n" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, fuzzy, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "Podłączenie do Storage %s:%d\n" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 #, fuzzy msgid "Failed to connect to Storage daemon.\n" msgstr "Nieudane podłączenie do demona Skadowania: %s:%d\n" #: src/dird/ua_cmds.c:843 #, fuzzy msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "Nieudane podłączenie do demona Skadowania: %s:%d\n" #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, fuzzy, c-format msgid "Client \"%s\" address set to %s\n" msgstr "Klient: nazwa=%s adres=%s FDport=%d\n" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, fuzzy, c-format msgid "Job \"%s\" not found.\n" msgstr "Nie znaleziono zadania %s.\n" #: src/dird/ua_cmds.c:1044 #, fuzzy, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "Status zadania: Anulowane" #: src/dird/ua_cmds.c:1052 #, fuzzy, c-format msgid "Client \"%s\" %sabled\n" msgstr "Status zadania: Anulowane" #: src/dird/ua_cmds.c:1060 #, fuzzy, c-format msgid "Job \"%s\" %sabled\n" msgstr "Status zadania: Anulowane" #: src/dird/ua_cmds.c:1305 #, fuzzy msgid "Enter new debug level: " msgstr "Wprowadź JobId do usunięcia: " #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "Wybierz rodzaj demona aby ustawić poziom debugingu" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "Brak autoryzacji dla Klienta \"%s\"\n" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "Brak nazwy Klienta.\n" #: src/dird/ua_cmds.c:1488 #, fuzzy, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "Brak autoryzacji dla Katalogu \"%s\"\n" #: src/dird/ua_cmds.c:1495 #, fuzzy msgid "Storage name missing.\n" msgstr "Brak nazwy Zadania.\n" #: src/dird/ua_cmds.c:1520 #, fuzzy, c-format msgid "%s Failed to resolve %s\n" msgstr "Nieudane pobranie jobid.\n" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, fuzzy, c-format msgid "%s resolves %s to %s\n" msgstr "Zasób Puli \"%s\" nie znaleziony.\n" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "Brak autoryzacji dla Zadania \"%s\"\n" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "Brak nazwy Zadania.\n" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "Brak autoryzacji dla FileSet'u \"%s\"\n" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "Brakująca nazwa fileset.\n" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "Brak wartości Poziomu.\n" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "Błędna wartość dla dokładności. Musisz wprowadzić 'yes' lub 'no'.\n" #: src/dird/ua_cmds.c:1667 #, fuzzy msgid "Accurate value missing.\n" msgstr "Brak wartości Poziomu.\n" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "Nie skazano zadania.\n" #: src/dird/ua_cmds.c:1696 #, fuzzy, c-format msgid "Wrong job specified of type %s.\n" msgstr "Nie skazano zadania.\n" #: src/dird/ua_cmds.c:1709 #, fuzzy msgid "No client specified or selected.\n" msgstr "określony czas uśpienia" #: src/dird/ua_cmds.c:1714 #, fuzzy msgid "No fileset specified or selected.\n" msgstr "Nieznany typ pliku %d; nie odtworzono: %s\n" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "Błąd wysyania listy wcze.\n" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "Błąd wysyania listy wycze\n" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" "Z zasady, nie jest dobrym pomysłem usunięcie \n" "Puli lub Wolumenu ponieważ mogą one zawierać dane.\n" "\n" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "Wybierz pozycję katalogu do usunięcia" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, fuzzy, c-format msgid "Illegal JobId %s ignored\n" msgstr "%s JobId %d wystartowane.\n" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "Wprowadź JobId do usunięcia: " #: src/dird/ua_cmds.c:1979 #, fuzzy, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "Czy jesteś pewien że chcesz usunąć Pulę \"%s\"? (yes/no): " #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, fuzzy, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "Zadanie %s oraz powiązane rekordy usunięte z katalogu.\n" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" "\n" "Ta komenda usunie wolumen %s\n" "oraz wszystkie Zadnia zapisane na tym wolumenie z Katalogu\n" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "Czy jesteś pewien że chcesz usunąć Wolumen \"%s\"? (yes/no): " #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "Czy jesteś pewien że chcesz usunąć Pulę \"%s\"? (yes/no): " #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "Używam Katalogu o nazwie=%s DB=%s\n" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "ERR: Nie można otworzyć BD\n" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "Przekroczono czas oczekiwania na zamontowanie\n" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "ERR: Zadanie nie znalezione\n" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" " Komenda Opis\n" " ======= ===========\n" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" " %-13s %s\n" "\n" "Argumenty:\n" "\t%s\n" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr "" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" "\n" "Niemożliwe odnalezienie komendy %s .\n" "\n" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "%s Wersja: %s (%s) %s %s %s %s\n" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "Brak autoryzacji dla Katalogu \"%s\"\n" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 #, fuzzy msgid "Could not find a Catalog resource\n" msgstr "Nie można znale zasobu Client %s\n" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "Nie można otworzyć bazy danych katalogu \"%s\".\n" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "Używam Katalogu \"%s\"\n" #: src/dird/verify.c:84 src/dird/verify.c:396 #, fuzzy, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "Niezaimplementowany poziom weryfikacji %d\n" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" "Niemożliwe znalezienie JobId wcześniejszego Zadania dla tego klienta.\n" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "Ostatnie Zadanie %d nie zakończyło się poprawnie. JobStatus=%c\n" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "Weryfikacja w stosunku do JobId=%d Job=%s\n" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "Uruchomienie Weryfikacji JobId=%s Level=%s Job=%s\n" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "Niezaimplementowany poziom weryfikacji %d\n" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "Weryfikacja OK" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "*** Błąd Weryfikacji ***" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "Ostrzerzenia przy Weryfikacji" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "Weryfikacja Anulowana" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "Rnice przy weryfikacji" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "Nieprawidłowy kod: %d %c\n" #: src/dird/verify.c:545 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s %s (%s): %s\n" " System operacyjny: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Poziom weryfikacji: %s\n" " Klient: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Czas rozpoczęcia: %s\n" " Czas zakończenia: %s\n" " Pliki oczekiwane: %s\n" " Pliki sprawdzone: %s\n" " Niekrytyczne błędy FD: %d\n" " Status FD termination: %s\n" " Status SD termination status: %s\n" " Termination: %s\n" "\n" #: src/dird/verify.c:581 #, fuzzy, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" "%s %s %s (%s): %s\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Klient: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Czas rozpoczęcia: %s\n" " Czas zakończenia: %s\n" " Pliki sprawdzone: %s\n" " Niekrytyczne błędy FD: %d\n" " Status FD termination: %s\n" " Termination: %s\n" "\n" # fuzzy, c-format #: src/dird/verify.c:661 #, fuzzy, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "" #: src/dird/ua_select.c:237 #, fuzzy msgid "Catalog" msgstr "Inicjalizacja Katalogu" #: src/dird/ua_select.c:237 #, fuzzy msgid "Select Catalog resource" msgstr "Zasób Klienta" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 #, fuzzy msgid "The defined Job resources are:\n" msgstr "Zbyt duo elementw w zasobie Zadania\n" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 #, fuzzy msgid "Select Job resource" msgstr "Zasób Klienta" #: src/dird/ua_select.c:307 #, fuzzy, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "Zasób Puli \"%s\" nie znaleziony.\n" #: src/dird/ua_select.c:320 #, fuzzy msgid "The defined Restore Job resources are:\n" msgstr "Usuwanie %d wpisów zadań Przywrócenia.\n" #: src/dird/ua_select.c:328 #, fuzzy msgid "Select Restore Job" msgstr "Uruchom Zadanie Przywracania %s\n" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 #, fuzzy msgid "The defined Client resources are:\n" msgstr "Nie można znale zasobu Client %s\n" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "" #: src/dird/ua_select.c:378 #, fuzzy msgid "Select Client resource" msgstr "Zasób Klienta" #: src/dird/ua_select.c:405 #, fuzzy, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "Zasób Puli \"%s\" nie znaleziony.\n" #: src/dird/ua_select.c:421 #, fuzzy msgid "The defined Schedule resources are:\n" msgstr "Nie można znale zasobu Client %s\n" #: src/dird/ua_select.c:432 #, fuzzy msgid "Select Schedule resource" msgstr "Wybierz zasób Puli" #: src/dird/ua_select.c:457 #, fuzzy, c-format msgid "Could not find Client %s: ERR=%s" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, fuzzy, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr " Nie można poda za dowiązaniem \"%s\": ERR=%s\n" #: src/dird/ua_select.c:496 #, fuzzy, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "Błąd aktualizacji rekordu Klienta. ERR=%s\n" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "" #: src/dird/ua_select.c:514 #, fuzzy msgid "Select the Client" msgstr "Wybierz pozycję: " #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, fuzzy, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr " Nie można poda za dowiązaniem \"%s\": ERR=%s\n" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "Zdefiniowane Pule:\n" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "Wybierz Pulę" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "Brak dostępu do Puli \"%s\"\n" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "Wprowadź *MediaId lub nazwę Wolumenu: " #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "Wybierz zasób Puli" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, fuzzy, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "Zasób Puli \"%s\" nie znaleziony.\n" #: src/dird/ua_select.c:754 #, fuzzy msgid "Enter the JobId to select: " msgstr "Wprowadź JobId do usunięcia: " #: src/dird/ua_select.c:792 #, fuzzy, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "Nie można zainicjować kolejki zada: ERR=%s\n" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 #, fuzzy msgid "Selection aborted, nothing done.\n" msgstr "Przywracanie niewykonane.\n" #: src/dird/ua_select.c:924 #, fuzzy, c-format msgid "Please enter a number between 1 and %d\n" msgstr "Musisz wybrać liczbę między 1 a %d\n" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, fuzzy, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "Oczekiwano ciągu znaków wild-card, otrzymano: %s\n" #: src/dird/ua_select.c:1009 #, fuzzy, c-format msgid "JobId %s is not running.\n" msgstr "JobId %d Zadanie %s jest uruchomione.\n" #: src/dird/ua_select.c:1019 #, fuzzy, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, fuzzy, c-format msgid "Job \"%s\" is not running.\n" msgstr "JobId %d Zadanie %s jest uruchomione.\n" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, fuzzy, c-format msgid "Storage resource \"%s\": not found\n" msgstr "Zasób Puli \"%s\" nie znaleziony.\n" #: src/dird/ua_select.c:1093 #, fuzzy msgid "Select Drive:\n" msgstr "Wybierz pozycję: " #: src/dird/ua_select.c:1098 #, fuzzy msgid "Drive" msgstr "archiwizacja" #: src/dird/ua_select.c:1098 #, fuzzy msgid "Select drive" msgstr "Wybierz pozycję: " #: src/dird/ua_select.c:1125 #, fuzzy msgid "Enter autochanger slot: " msgstr "przetestuj bibliotekę taśmową" #: src/dird/ua_select.c:1153 #, fuzzy msgid "Media Types defined in conf file:\n" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/dird/ua_select.c:1159 #, fuzzy msgid "Media Type" msgstr " MediaType : %s\n" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "adne Zadanie nie uruchomione.\n" #: src/dird/ua_select.c:1325 #, fuzzy msgid "None of your jobs are running.\n" msgstr "adne Zadanie nie uruchomione.\n" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, fuzzy, c-format msgid "Selected Job %d for cancelling\n" msgstr "Zasób Klienta" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 #, fuzzy msgid "No Jobs selected.\n" msgstr "Status zadania: Anulowane" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "" #: src/dird/ua_select.c:1429 #, fuzzy msgid "Select Job:\n" msgstr "Wybierz pozycję: " #: src/dird/ua_select.c:1438 #, fuzzy, c-format msgid "JobId=%s Job=%s" msgstr "%s korzysta z JobId=%s Job=%s\n" #: src/dird/ua_select.c:1443 #, fuzzy, c-format msgid "Choose Job to %s" msgstr "Wybierz pozycję katalogu do usunięcia" #: src/dird/ua_select.c:1452 #, fuzzy, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "Anulowane" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 #, fuzzy msgid "Slot too large.\n" msgstr "Komentarz za długi.\n" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "" #: src/dird/catreq.c:203 #, fuzzy, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "Nie można stworzyć skrt.\n" #: src/dird/catreq.c:208 #, fuzzy, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "W katalogu utworzono nowy Wolumen \"%s\"\n" #: src/dird/catreq.c:228 #, fuzzy, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "Nie mogę otrzyma rekordu Zadania dla JobId=%s: ERR=%s\n" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, fuzzy, c-format msgid "Catalog error updating Media record. %s" msgstr "Błąd uaktualniania rekordu zadania. %s" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "" #: src/dird/catreq.c:342 #, fuzzy, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/dird/catreq.c:344 #, fuzzy msgid "1992 Create JobMedia error\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, fuzzy, c-format msgid "Attribute create error: ERR=%s" msgstr "Błąd stworzenia atrybutu. %s" #: src/dird/catreq.c:556 #, fuzzy, c-format msgid "Restore object create error. %s" msgstr "Błąd stworzenia atrybutu. %s" #: src/dird/catreq.c:564 #, fuzzy, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "Indeks MD5/SHA1 %d nie jest taki sam jak atrybutw %d\n" #: src/dird/catreq.c:595 #, fuzzy, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "Niepoprawne flagi pliku, nie wspierany typ strumienia danych.\n" #: src/dird/catreq.c:613 #, fuzzy, c-format msgid "attribute create error. %s" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/dird/catreq.c:618 #, fuzzy, c-format msgid "Catalog error updating file digest. %s" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, fuzzy, c-format msgid "read attr spool error. ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" #: src/dird/ua_purge.c:197 #, fuzzy msgid "Choose item to purge" msgstr "Wybierz pozycję katalogu do usunięcia" #: src/dird/ua_purge.c:249 #, fuzzy, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "Brak autoryzacji dla Klienta \"%s\"\n" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, fuzzy, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "Nie znaleziono zasobu Zadania dla \"%s\".\n" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, fuzzy, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "Rozłączanie od Klienta %s:%d\n" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, fuzzy, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "Brak autoryzacji dla Klienta \"%s\"\n" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, fuzzy, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "W katalogu utworzono nowy Wolumen \"%s\"\n" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 #, fuzzy msgid "Can't update volume size in the catalog\n" msgstr "W katalogu utworzono nowy Wolumen \"%s\"\n" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "Nie mogę przyci wolumenu \"%s\"\n" #: src/dird/ua_purge.c:819 #, fuzzy, c-format msgid "No Volumes found to perform %s action.\n" msgstr "Nie znaleziono zasobu Zadania dla \"%s\".\n" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 msgid "for Job" msgstr "" #: src/dird/ua_audit.c:71 #, fuzzy msgid "for Client" msgstr "Klient:" #: src/dird/ua_audit.c:74 #, fuzzy msgid "for Storage" msgstr "Demon Skadowania" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 #, fuzzy msgid "for Schedule" msgstr "" "\n" "Zakoczonych Zada:\n" #: src/dird/ua_audit.c:83 msgid "for Pool" msgstr "" #: src/dird/ua_audit.c:86 #, fuzzy msgid "for Command" msgstr "Bdna komenda Job: %s" #: src/dird/ua_audit.c:89 #, fuzzy msgid "for Fileset" msgstr "Zestaw plików" #: src/dird/ua_audit.c:92 #, fuzzy msgid "for Catalog" msgstr "Inicjalizacja Katalogu" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 #, fuzzy msgid "for Plugin Options" msgstr "określony czas uśpienia" #: src/dird/ua_audit.c:114 #, fuzzy, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "Konsola: nazwa=%s\n" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, fuzzy, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "Konsola: nazwa=%s\n" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "zweryfikuj" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 #, fuzzy msgid "base job" msgstr "Anulowane" #: src/dird/inc_conf.c:225 #, fuzzy, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "Oczekiwano dodatniej wartości całkowitej, wprowadzono: %s\n" #: src/dird/inc_conf.c:233 #, fuzzy, c-format msgid "Expected a parseable size, got: %s:" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/dird/inc_conf.c:251 #, fuzzy, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "Błąd kompilacji regex. ERR=%s\n" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "Oczekiwano ciągu znaków wild-card, otrzymano: %s\n" #: src/dird/inc_conf.c:405 #, fuzzy, c-format msgid "Expected a fstype string, got: %s\n" msgstr "Oczekiwano ciągu znaków fstype, otrzymano: %s\n" #: src/dird/inc_conf.c:428 #, fuzzy, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "Oczekiwano ciągu znaków drivetype, otrzymano: %s\n" #: src/dird/inc_conf.c:450 #, fuzzy, c-format msgid "Expected a meta string, got: %s\n" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/dird/inc_conf.c:479 #, fuzzy, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, fuzzy, c-format msgid "Expecting open brace. Got %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, fuzzy, c-format msgid "Expecting keyword, got: %s\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, fuzzy, c-format msgid "expected an equals, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "Klient: " #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "Demona Plików \"%s\" odrzuci komend Job: %s\n" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "Błąd aktualizacji rekordu Klienta. ERR=%s\n" #: src/dird/fd_cmds.c:173 #, fuzzy, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "filed: write error on socket\n" msgstr ">filed: bd zapisu na soket\n" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "Błąd uruchomienia programu: %s. ERR=%s\n" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "Nie można otworzyć pliku wejciowego FileSet: %s. ERR=%s\n" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "Niepowodzenie RunScript'u Klienta \"%s\".\n" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 #, fuzzy msgid "Plugin options failed.\n" msgstr "określony czas uśpienia" #: src/dird/fd_cmds.c:828 #, fuzzy msgid "RestoreObject failed.\n" msgstr "Odtwarzanie Anulowane" #: src/dird/fd_cmds.c:863 #, fuzzy, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "Przykład : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n" " uruchomi 3 wątki i ładowanie dat1, dat and datx do twojego katalogu\n" "Zobacz bbatch.c by wygenerować datafile\n" "\n" "Użycie: bbatch [ options ] -w working/dir -f datafile\n" " -d «nn» ustaw poziom debugging'u na «nn»\n" " -dt wyświetl czasy w danych wyjściowych debugging'u\n" " -n «name» określ nazwę bazy danych (domyślnie bareos)\n" " -u «user» określ nazwę użytkownika bazy danych (domyślnie " "bareos)\n" " -P «password określ hasło bazy danych (domyślnie brak)\n" " -h «host» określ hasta bazy danych (domyślnie NULL)\n" " -w «working» określ katalog roboczy\n" " -r «jobids» wywołaj kod przywracania dla podanych jobid\n" " -v szczegółowe informacje dla użytkownika\n" " -f «file» określ plik danych\n" " -? wyświetl tą podpowiedź.\n" "\n" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "Niepoprawna ilość argumentów: \n" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 #, fuzzy msgid "Could not init Bareos database\n" msgstr "Nie można otworzyć bazy danych katalogu \"%s\".\n" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "Wykorzystywana baza danych: %s, Użytkownik: %s\n" #: src/tests/bbatch.c:329 #, fuzzy, c-format msgid "Error opening datafile %s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/tests/bbatch.c:339 #, fuzzy msgid "Error while inserting file\n" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/tests/bvfs_test.c:51 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "Przykład : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n" " uruchomi 3 wątki i ładowanie dat1, dat and datx do twojego katalogu\n" "Zobacz bbatch.c by wygenerować datafile\n" "\n" "Użycie: bbatch [ options ] -w working/dir -f datafile\n" " -d «nn» ustaw poziom debugging'u na «nn»\n" " -dt wyświetl czasy w danych wyjściowych debugging'u\n" " -n «name» określ nazwę bazy danych (domyślnie bareos)\n" " -u «user» określ nazwę użytkownika bazy danych (domyślnie " "bareos)\n" " -P «password określ hasło bazy danych (domyślnie brak)\n" " -h «host» określ hasta bazy danych (domyślnie NULL)\n" " -w «working» określ katalog roboczy\n" " -r «jobids» wywołaj kod przywracania dla podanych jobid\n" " -v szczegółowe informacje dla użytkownika\n" " -f «file» określ plik danych\n" " -? wyświetl tą podpowiedź.\n" "\n" #: src/tests/ing_test.c:49 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "Przykład : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n" " uruchomi 3 wątki i ładowanie dat1, dat and datx do twojego katalogu\n" "Zobacz bbatch.c by wygenerować datafile\n" "\n" "Użycie: bbatch [ options ] -w working/dir -f datafile\n" " -d «nn» ustaw poziom debugging'u na «nn»\n" " -dt wyświetl czasy w danych wyjściowych debugging'u\n" " -n «name» określ nazwę bazy danych (domyślnie bareos)\n" " -u «user» określ nazwę użytkownika bazy danych (domyślnie " "bareos)\n" " -P «password określ hasło bazy danych (domyślnie brak)\n" " -h «host» określ hasta bazy danych (domyślnie NULL)\n" " -w «working» określ katalog roboczy\n" " -r «jobids» wywołaj kod przywracania dla podanych jobid\n" " -v szczegółowe informacje dla użytkownika\n" " -f «file» określ plik danych\n" " -? wyświetl tą podpowiedź.\n" "\n" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "Przykład : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n" " uruchomi 3 wątki i ładowanie dat1, dat and datx do twojego katalogu\n" "Zobacz bbatch.c by wygenerować datafile\n" "\n" "Użycie: bbatch [ options ] -w working/dir -f datafile\n" " -d «nn» ustaw poziom debugging'u na «nn»\n" " -dt wyświetl czasy w danych wyjściowych debugging'u\n" " -n «name» określ nazwę bazy danych (domyślnie bareos)\n" " -u «user» określ nazwę użytkownika bazy danych (domyślnie " "bareos)\n" " -P «password określ hasło bazy danych (domyślnie brak)\n" " -h «host» określ hasta bazy danych (domyślnie NULL)\n" " -w «working» określ katalog roboczy\n" " -r «jobids» wywołaj kod przywracania dla podanych jobid\n" " -v szczegółowe informacje dla użytkownika\n" " -f «file» określ plik danych\n" " -? wyświetl tą podpowiedź.\n" "\n" #: src/tests/cats_test.c:375 #, fuzzy, c-format msgid "Could not open, database \"%s\".\n" msgstr "Nie można otworzyć bazy danych katalogu \"%s\".\n" #: src/tests/testls.c:50 #, fuzzy, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" "\n" "Użycie: testfind [-d debug_level] [-] [pattern1 ...]\n" " -a wyświetl rozszerzone atrybuty (Win32 debug)\n" " -d «nn» set debug level to «nn»\n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level »= 1 prints each file found.\n" "Debug level »= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len » 255.\n" "Truncation is only in the catalog.\n" "\n" #: src/tests/testls.c:146 #, fuzzy, c-format msgid "Could not open include file: %s\n" msgstr "Nie można ustawi pola Finder Info na %s\n" #: src/tests/testls.c:159 #, fuzzy, c-format msgid "Could not open exclude file: %s\n" msgstr "Nie można otworzyć pliku bootstrap %s: ERR=%s\n" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, fuzzy, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr " Rekursja wyczona. Ominito katalog: %s\n" #: src/tests/testls.c:224 #, fuzzy, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr " Zabroniona zmiana filesystemu. Ominito katalog: %s\n" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, fuzzy, c-format msgid "Could not open data file: %s\n" msgstr "Nie można otworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, fuzzy, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "Nie można zainicjować zmiennej warunkowej zadania: ERR=%s\n" #: src/stored/dir_cmd.c:241 #, fuzzy, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "Nie można zainicjować zmiennej warunkowej zadania: ERR=%s\n" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "Nie mogę zautentykowa Directora\n" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, fuzzy, c-format msgid "Connection request from %s failed.\n" msgstr "Podłączenie do Klienta %s:%d\n" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, fuzzy, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "Rozłączanie od Klienta %s:%d\n" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, fuzzy, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "2991 Bdna komenda setdebug: %s\n" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "2901 Zadanie %s nie znaleziono.\n" #: src/stored/dir_cmd.c:485 #, fuzzy msgid "3903 Error scanning cancel command.\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, fuzzy, c-format msgid "3904 Job %s not found.\n" msgstr "2901 Zadanie %s nie znaleziono.\n" #: src/stored/dir_cmd.c:562 #, fuzzy, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "2001 Zadanie %s oznaczone do anulowania.\n" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, fuzzy, c-format msgid "%s: Failed to resolve %s\n" msgstr "Nieudane pobranie jobid.\n" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, fuzzy, c-format msgid "3903 Error scanning label command: %s\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:743 #, fuzzy, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" "3920 Nie można nadac etykiety wolumenowi ponieważ etykieta jest nadana: \"%s" "\"\n" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "3921 Zamontowano niepoprawny Wolumen.\n" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, fuzzy, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/dir_cmd.c:787 #, fuzzy, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, fuzzy, c-format msgid "3001 Mounted Volume: %s\n" msgstr "Nie mogę przyci wolumenu \"%s\"\n" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, fuzzy, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" "3902 Nie można zamontować Wolumenu na urządzeniu Storage %s ponieważ:\n" "%s" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" "\n" " Żądane przez DIR Urządzenie \"%s\" nie może być otworzone lub nie " "istnieje.\n" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" "\n" " Żądane przez DIR Urządzenie \"%s\" w zmieniarce \"%s\" nie może być " "otworzone lub nie istnieje.\n" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "Zdefiniowany slot został zignorowany. " #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, fuzzy, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, fuzzy, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, fuzzy, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, fuzzy, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1015 #, fuzzy, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1025 #, fuzzy, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "3907 %s" #: src/stored/dir_cmd.c:1030 #, fuzzy, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1038 #, fuzzy, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1042 #, fuzzy, c-format msgid "3905 Unknown wait state %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/dir_cmd.c:1052 #, fuzzy, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, fuzzy, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1086 #, fuzzy, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1101 #, fuzzy, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1105 #, fuzzy, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1140 #, fuzzy, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:1166 #, fuzzy msgid "3916 Error scanning action_on_purge command\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:1209 #, fuzzy, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "Rekord urządzenia %s już istnieje\n" #: src/stored/dir_cmd.c:1216 #, fuzzy, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "Status zadania: Oczekiwanie na nowe media" #: src/stored/dir_cmd.c:1222 #, fuzzy, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1226 #, fuzzy, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1230 #, fuzzy, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1238 #, fuzzy, c-format msgid "3022 Device \"%s\" released.\n" msgstr "3002 Urządzenie %s jest zamontowane.\n" #: src/stored/dir_cmd.c:1249 #, fuzzy, c-format msgid "3927 Error scanning release command: %s\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "Nie można utworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/dir_cmd.c:1360 #, fuzzy, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/stored/dir_cmd.c:1384 #, fuzzy, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:1425 #, fuzzy, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, fuzzy, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" "3601 JobId=%u - urządzenie %s jest ZABLOKOWANE z powodu odmontowania przez " "użytkownika.\n" #: src/stored/dir_cmd.c:1486 #, fuzzy, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "Status zadania: Oczekiwanie na nowe media" #: src/stored/dir_cmd.c:1489 #, fuzzy, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "Status zadania: Oczekiwanie na nowe media" #: src/stored/dir_cmd.c:1492 #, fuzzy, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1496 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/stored/dir_cmd.c:1500 #, fuzzy, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/stored/dir_cmd.c:1505 #, fuzzy, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1507 #, fuzzy, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "3936 Urządzenie %s jest zajęte odczytem.\n" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "Nieudane podłączenie do demona Skadowania: %s:%d\n" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "Nieudana autentykacja demona Skadowania.\n" #: src/stored/dir_cmd.c:1655 #, fuzzy, c-format msgid "Bad passiveclientcmd command: %s" msgstr "Za komenda session: %s" #: src/stored/dir_cmd.c:1673 #, fuzzy msgid "File Daemon" msgstr "Demon Plików" #: src/stored/dir_cmd.c:1679 #, fuzzy, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "Nieudane podłączenie do demona Plików.\n" #: src/stored/dir_cmd.c:1690 #, fuzzy msgid "Failed to authenticate File daemon.\n" msgstr "Nie mogę zautentykowa Directora\n" #: src/stored/dir_cmd.c:1724 #, fuzzy, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "Bdna komenda RunScript: %s\n" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, fuzzy, c-format msgid "Encountered an unknown stream type %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/ndmp_tape.c:590 #, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "DCR jest NULL!!!\n" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "DEVICE jest NULL!!!\n" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, fuzzy, c-format msgid "Write session label failed. ERR=%s\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/ndmp_tape.c:749 #, fuzzy msgid "Creating virtual file attributes failed.\n" msgstr "Nieudane stworzenie pliku bootstrap.\n" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 #, fuzzy msgid "No Volume names found for restore.\n" msgstr "Błąd wersji Zlib" #: src/stored/ndmp_tape.c:811 #, fuzzy, c-format msgid "Read session label failed. ERR=%s\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 #, fuzzy msgid "JCR is NULL!!!\n" msgstr "DCR jest NULL!!!\n" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, fuzzy, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, fuzzy, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "Błąd w getacl na pliku \"%s\": ERR=%s\n" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 #, fuzzy msgid "Cannot initialize new NDMA session\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 #, fuzzy msgid "Cannot initialize new NDMA connection\n" msgstr "Nie można zainicjować Pythona\n" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "Nie można podłączyć się do portu %d: ERR=%s: Powtarzanie ...\n" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "Nie można podłączyć się do portu %d: ERR=%s.\n" #: src/stored/ndmp_tape.c:1414 #, fuzzy, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "Nie można zainicjować kolejki klienta: ERR=%s\n" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "Błąd w funkcji select: %s\n" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, fuzzy, c-format msgid "Error in poll: %s\n" msgstr "Błąd w funkcji select: %s\n" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, fuzzy, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "Nie można dodać zadania do kolejki klienta: ERR=%s\n" #: src/stored/ndmp_tape.c:1557 #, fuzzy, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "Nie można zniszczyć kolejki klienta: ERR=%s\n" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, fuzzy, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "JobId %s, Zadanie %s oznaczone do anulowania.\n" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 #, fuzzy msgid "Unable to authenticate File daemon\n" msgstr "Nie mogę zautentykowa Directora\n" #: src/stored/fd_cmds.c:231 #, fuzzy, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "Błąd komunikacji z SD. za odpowiedź na %s. ERR=%s\n" #: src/stored/fd_cmds.c:234 #, fuzzy msgid "Command error with FD, hanging up.\n" msgstr "Błąd komunikacji z SD. za odpowiedź na %s. ERR=%s\n" #: src/stored/fd_cmds.c:246 #, fuzzy, c-format msgid "FD command not found: %s\n" msgstr "Nie znaleziono tabeli: %s\n" #: src/stored/fd_cmds.c:272 #, fuzzy msgid "Append data error.\n" msgstr "Błąd danych Zlib" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, fuzzy, c-format msgid ">filed: Error Hdr=%s" msgstr "»wprowadzono: Błąd Hdr=%s\n" #: src/stored/read.c:136 src/stored/read.c:153 #, fuzzy, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "Błąd w wysyaniu Hello do demona Plików. ERR=%s\n" #: src/stored/read.c:152 #, fuzzy, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "Błąd w wysyaniu Hello do demona Plików. ERR=%s\n" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, fuzzy, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/stored/stored_conf.c:432 #, fuzzy, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/stored/stored_conf.c:451 #, fuzzy, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "Nie zdefiniowano zasobu %s\n" #: src/stored/stored_conf.c:454 #, fuzzy, c-format msgid "dump_resource type=%d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/stored_conf.c:575 #, fuzzy, c-format msgid "Warning: unknown resource type %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/stored_conf.c:806 #, fuzzy, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "Element %s jest wymagany w zasobie %s, lecz nie został znaleziony.\n" #: src/stored/stored_conf.c:814 #, fuzzy, c-format msgid "Too many items in \"%s\" resource\n" msgstr "Zbyt duo elementw w zasobie %s\n" #: src/stored/stored_conf.c:858 #, fuzzy, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "Nie można znale zasobu Director %s\n" #: src/stored/stored_conf.c:874 #, fuzzy, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/stored_conf.c:913 #, fuzzy, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" "Próba definicji kolejnego zasobu %s nazwanego \"%s\" nie jest dozwolona.\n" #: src/stored/stored_conf.c:1001 #, fuzzy, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/stored/dev.c:148 #, fuzzy, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, fuzzy, c-format msgid "%s has an unknown device type %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/dev.c:286 #, fuzzy, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, fuzzy, c-format msgid "Min block size > max on device %s\n" msgstr "Problem zapętlenia dot. rozmiaru bloku bufora na urządzeniu %s " #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, fuzzy, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" "Rozmiar bloku taśmy (%d) nie jest wielokrotnością rozmiaru systemowego (%d)\n" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/dev.c:332 src/stored/dev.c:339 #, fuzzy, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/dev.c:346 #, fuzzy, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/dev.c:353 #, fuzzy, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/dev.c:360 #, fuzzy, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, fuzzy, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/dev.c:615 #, fuzzy, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, fuzzy, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, fuzzy, c-format msgid "Seek error: ERR=%s\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "Błędne odwołanie dla repozycji. Urządzenie nie otwarte\n" #: src/stored/dev.c:904 #, fuzzy, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/device.c:111 #, fuzzy, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "Nowy wolumen \"%s\" zamontowany na urządzeniu %s w %s.\n" #: src/stored/device.c:142 #, fuzzy, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "Niepowodzenie przepełnienia bloku write_block_to_device. ERR=%s" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" "Katastrofalny błąd. Na urządzeniu %s nie można zapisać bloku przepełnienia. " "ERR=%s" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, fuzzy, c-format msgid "dev open failed: %s\n" msgstr " Przetworzonych plikw: %s\n" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, fuzzy, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/device.c:316 #, fuzzy, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasowu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -k keep readall capabilities\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -s brak sygnałów (dla debugingu)\n" " -t przetestuj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, fuzzy, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, fuzzy, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/stored/bscan.c:295 #, fuzzy, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/stored/bscan.c:299 #, fuzzy, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "Rozmiar Pierwszego Wolumenu = %s\n" #: src/stored/bscan.c:374 #, fuzzy, c-format msgid "Create JobMedia for Job %s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bscan.c:384 #, fuzzy, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "gotowe: %d%%\n" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "Rekord: SessId=%u SessTim=%u FileIndex=%d Strumień=%d długość=%u\n" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" "Wolumen ma już wcześniej nadaną rtykietę. Ta taśma nie może być skanowana.\n" #: src/stored/bscan.c:486 #, fuzzy, c-format msgid "Pool record for %s found in DB.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:490 #, fuzzy, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "VOL_LABEL: Błędnie wprowadzono PoolType. DB=%s Vol=%s\n" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "Rodzaj puli \"%s\" OK.\n" #: src/stored/bscan.c:510 #, fuzzy, c-format msgid "Media record for %s found in DB.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:517 #, fuzzy, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "VOL_LABEL: OK dla Wolumenu: %s\n" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, fuzzy, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "Nie mogę otrzyma rekordu Zadania dla JobId=%s: ERR=%s\n" #: src/stored/bscan.c:561 #, fuzzy, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "Nie znaleziono zasobu Zadania dla \"%s\".\n" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, fuzzy, c-format msgid "Could not update job record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 #, fuzzy msgid "Cannot continue.\n" msgstr "Nie można połączyć się do demona.\n" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, fuzzy, c-format msgid "Got MD5 record: %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:803 #, fuzzy, c-format msgid "Got SHA1 record: %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:811 #, fuzzy, c-format msgid "Got SHA256 record: %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:819 #, fuzzy, c-format msgid "Got SHA512 record: %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, fuzzy, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/bscan.c:982 #, fuzzy, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:988 #, fuzzy, c-format msgid "Created File record: %s\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/stored/bscan.c:1033 #, fuzzy, c-format msgid "Could not create media record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, fuzzy, c-format msgid "Could not update media record. ERR=%s\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/stored/bscan.c:1041 #, fuzzy, c-format msgid "Created Media record for Volume: %s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bscan.c:1062 #, fuzzy, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/bscan.c:1079 #, fuzzy, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1083 #, fuzzy, c-format msgid "Created Pool record for Pool: %s\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/bscan.c:1101 #, fuzzy, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1111 #, fuzzy, c-format msgid "Created Client record for Client: %s\n" msgstr "Nie można znale zasobu Client %s\n" #: src/stored/bscan.c:1128 #, fuzzy, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "rekord puli %s ju istnieje\n" #: src/stored/bscan.c:1132 #, fuzzy, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1137 #, fuzzy, c-format msgid "Created FileSet record \"%s\"\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/stored/bscan.c:1184 #, fuzzy, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1190 #, fuzzy, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "Nie można stworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/bscan.c:1193 #, fuzzy, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bscan.c:1246 #, fuzzy, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, fuzzy, c-format msgid "Job Termination code: %d" msgstr "Status zadania: Zakoczone" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, fuzzy, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bscan.c:1343 #, fuzzy, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, fuzzy, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/bscan.c:1378 #, fuzzy msgid "Updated MD5/SHA1 record\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "Nie mogę ustawić rozmiaru bufora sieciowego.\n" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 #, fuzzy msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "Nieznany strumie=%d zignorowany. To nie powinno się sta!\n" #: src/stored/append.c:123 #, fuzzy, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "Błąd sieci w wysyaniu do SD. ERR=%s\n" #: src/stored/append.c:161 #, fuzzy, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "Błąd odczytywania nagłówka danych z FD. ERR=%s\n" #: src/stored/append.c:169 #, fuzzy, c-format msgid "Malformed data header from %s: %s\n" msgstr "Uszkodzony nagłówek danych z FD: %s\n" #: src/stored/append.c:190 #, fuzzy, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "Indeks Pliku z FD nie jest pozytywny ani sekwencyjny\n" #: src/stored/append.c:243 #, fuzzy, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "Błąd sieci w wysyaniu do SD. ERR=%s\n" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, fuzzy, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" "Rozmiar bloku taśmy (%d) nie jest wielokrotnością rozmiaru systemowego (%d)\n" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "Rozmiar bloku taśmy (%d) nie jest potegą 2\n" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" "\n" "\n" "!!!! Ostrzeżenie o wyłączeniu adresacji dużych dysków. boffset_t=%d a pownno " "być 8 lub wiecej !!!!!\n" "\n" "\n" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "Problem printf/scanf 32 bit. i=%d x32=%u y32=%u\n" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "Granulacja bloku taśmy to %d bajtów.\n" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "Nie podano nazwy archiwum.\n" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "Podano niepoprawną ilość argumentów.\n" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "btape działa tylko z nośnikami w postaci taśm.\n" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "Sumaryczny rozmiar: bajtów=%sB. Całkowita prędkość zapisu = %sB/s\n" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "Wolumen: bajtów=%sB. Prędkość zapisu = %sB/s\n" #: src/stored/btape.c:487 #, fuzzy, c-format msgid "open device %s: OK\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "Wprowadź nazwę wolumenu: " #: src/stored/btape.c:517 #, fuzzy, c-format msgid "Device open failed. ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 #, fuzzy msgid "Volume has no label.\n" msgstr "Wolumen do Katalogu" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, fuzzy, c-format msgid "I/O error on device: ERR=%s" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:545 #, fuzzy msgid "Volume name error\n" msgstr "Błąd wersji Zlib" #: src/stored/btape.c:548 #, fuzzy, c-format msgid "Error creating label. ERR=%s" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:551 #, fuzzy msgid "Volume version error.\n" msgstr "Błąd wersji Zlib" #: src/stored/btape.c:554 #, fuzzy msgid "Bad Volume label type.\n" msgstr "Wolumen do Katalogu" #: src/stored/btape.c:557 #, fuzzy msgid "Unknown error.\n" msgstr "Błąd szyfrowania\n" #: src/stored/btape.c:575 #, fuzzy, c-format msgid "Bad status from load. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:577 #, fuzzy, c-format msgid "Loaded %s\n" msgstr "Zaadowana wtyczka: %s\n" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, fuzzy, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, fuzzy, c-format msgid "Rewound %s\n" msgstr "Nie znaleziono tabeli: %s\n" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, fuzzy, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "Zapisano 1 EOF do %s\n" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "Zapisano %d EOF do %s\n" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "Przeniesiono na koniec medium.\n" #: src/stored/btape.c:667 #, fuzzy, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:669 #, fuzzy, c-format msgid "Backspaced %d file%s.\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:686 #, fuzzy, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:688 #, fuzzy, c-format msgid "Backspaced %d record%s.\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "Skonfigurowano wydajność urządzenia:\n" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "Status urządzenia:\n" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "Parametry urządzenia:\n" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "Status:\n" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "Czy chcesz kontynuować? (y/n): " #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "Blok %d i=%d\n" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 #, fuzzy msgid "Error writing record to block.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 #, fuzzy msgid "Error writing block to device.\n" msgstr "Błąd w wysyaniu Hello do demona Przechowywania. ERR=%s\n" #: src/stored/btape.c:826 #, fuzzy, c-format msgid "Wrote first record of %d bytes.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/btape.c:837 #, fuzzy, c-format msgid "Wrote second record of %d bytes.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/btape.c:848 #, fuzzy, c-format msgid "Wrote third record of %d bytes.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/btape.c:855 src/stored/btape.c:860 #, fuzzy, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, fuzzy, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:869 #, fuzzy msgid "Backspace record OK.\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:872 src/stored/btape.c:878 #, fuzzy, c-format msgid "Read block failed! ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:883 #, fuzzy msgid "Bad data in record. Test failed!\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, fuzzy, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 #, fuzzy msgid "" "\n" "Error writing record to block.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:985 #, fuzzy msgid "" "\n" "Error writing block to device.\n" msgstr "Błąd w wysyaniu Hello do demona Przechowywania. ERR=%s\n" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, fuzzy, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, fuzzy, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:1256 #, fuzzy, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, fuzzy, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "Test pozycji bloku\n" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "Repozycja do plik:blok %d:%d\n" #: src/stored/btape.c:1357 #, fuzzy msgid "Reposition error.\n" msgstr "Błąd odszyfrowywania\n" #: src/stored/btape.c:1370 #, fuzzy, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, fuzzy, c-format msgid "Read record failed! ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "Blok %d został ponownie przeczytany poprawnie.\n" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "To jest prawidłowo!" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "To NIE jest prawidlowo!!!" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "Koniec skanowania taśmy.\n" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" "\n" "Biblioteka taśmowa uaktywniona, ale nie określono nazwy lub urządzenia " "sterującego.\n" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" "\n" "O, widzę że biblioteka taśmowa jest skonfigurowana.\n" "By przetestować bibliotekę taśmową musisz mieć czystą taśmę\n" " w Slocie 1 na której mogę zapisywać.\n" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" "\n" "Czy chcesz kontynuować test biblioteki taśmowej? (y/n): " #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" "\n" "\n" "=== Test biblioteki taśmowej ===\n" "\n" #: src/stored/btape.c:1512 #, fuzzy msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "Za komenda storage: %s" #: src/stored/btape.c:1521 #, fuzzy, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "Za komenda storage: %s" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "3991 wynik=\"%s\": ERR=%s\n" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "Slot %d załadowany. Będzie rozładowany.\n" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "Nic nie załadowano w napędzie. OK.\n" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "status wyąłdowania=%s %d\n" #: src/stored/btape.c:1540 msgid "Bad" msgstr "Błąd" #: src/stored/btape.c:1543 #, fuzzy, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "Za komenda storage: %s" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "3992 wynik=\"%s\": ERR=%s\n" #: src/stored/btape.c:1554 #, fuzzy, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "Za komenda storage: %s" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, fuzzy, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "Za komenda storage: %s" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "3993 wynik=\"%s\": ERR=%s\n" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "Zapisano EOF do %s\n" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" "\n" "Test biblioteki taśmowej zakończony sukcesem!!\n" "\n" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "Bez poprawy tego błędu biblioteka taśmowej nie będzie działać.\n" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, fuzzy, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, fuzzy, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, fuzzy, c-format msgid "Wrote one record of %d bytes.\n" msgstr "Brak rekordu dla %d %s\n" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "Zapisano blok na urzadzenie.\n" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "Wprowadź długość do odczytu: " #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "Wprowadzono błędną dlugość, używam domyślnej długości 1024 bajtów.\n" #: src/stored/btape.c:1961 #, fuzzy, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "Koniec taśmy\n" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "Rozpoczynam skanowanie od pliku %u\n" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, fuzzy, c-format msgid "read error on %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:1996 #, fuzzy, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "Za komenda .status: %s\n" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "1 blok %d bajtów w pliku %d\n" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "%d bloków %d bajtów w pliku %d\n" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "Znacznik konca pliku.\n" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, fuzzy, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "Odczyt krótkiego bloku.\n" #: src/stored/btape.c:2112 #, fuzzy, c-format msgid "Error reading block. ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, fuzzy, c-format msgid "Device status: %u. ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "wybrano prosty test (pojedyńcza taśma).\n" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 #, fuzzy msgid "Wrote Start of Session label.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 #, fuzzy msgid "Flush block failed.\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "Niepoprawnie\n" #: src/stored/btape.c:2367 #, fuzzy msgid "Job canceled.\n" msgstr "Status zadania: Anulowane" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 #, fuzzy msgid "Wrote End of Session label.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, fuzzy, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "Nie można stworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "niepowodzenie do_unfill.\n" #: src/stored/btape.c:2435 #, fuzzy, c-format msgid "%s: Error during test.\n" msgstr "Błąd wysyania listy wcze.\n" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, fuzzy, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "Nie można stworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "Umieść pierwszą taśmę. Naciśnij 'Enter' kiedy gotowe: " #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "Przewijanie.\n" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "Odczytywanie pierwszych 10000 rekordów z %u:%u.\n" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "Repozycja z %u:%u do %u:%u\n" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, fuzzy, c-format msgid "Reposition error. ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/btape.c:2576 #, fuzzy, c-format msgid "Reading block %u.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, fuzzy, c-format msgid "Error reading block: ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" "\n" "Ostatni blok na taśmie zgodny. Test zakończony sukcesem.\n" "\n" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" "\n" "Ostatni blok na pierwszej taśmie zgodny.\n" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "Zamontuj druga taśmę. Naciśnij 'Enter' kiedy gotowe: " #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "Repozycja z %u:%u do 0:1\n" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, fuzzy, c-format msgid "Reading block %d.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" "\n" "Pierwszy blok na drugiej taśmie zgodny.\n" "\n" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" "\n" "Ostatni blok na drugiej taśmie zgodny. Test zakończony sukcesem.\n" "\n" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "10000 rekordów odczytanych na %d:%d\n" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "Ostatni blok zapisany" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "Odczyt zapisanego bloku" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" "\n" "\n" "Blok różni się w bajcie %u\n" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" "\n" "\n" "Uwaga!!!!: Ostatni zapisany blok różni się od bloku odczytanego\n" "Test zakończony niepowodzeniem !!!!\n" "Konieczna poprawa przed użyciem Bareos'i\n" "do zapisu na wielotasmowych Wolumenach.!!!!\n" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "Ostatni blok przy: %u:%u this_dev_block_num=%d\n" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "Blok nie został zapisany: FileIndex=%u blk_block=%u Rozmiar=%u\n" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "Blok nie zostal zapisany" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "Koniec taśmy %d:%d. Rozmiar =%s bajtów. Prędkość zapisu = %sB/s\n" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, fuzzy, c-format msgid "Cannot fixup device error. %s\n" msgstr "Nie można znale zasobu Client %s\n" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "Test zapisu na taśmie bloków 64512 bajtów.\n" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "Ile bloków chcesz zapisać? (1000): " #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "Rozpocznij zapis na taśmę %d bloków Bareos ...\n" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "Rozpocznij zapis surowych bloków po %u bajtów.\n" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "przetestuj bibliotekę taśmową" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "cofnij się o plik" #: src/stored/btape.c:2918 #, fuzzy msgid "backspace record" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "wylistuj właściwości urządzenia" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "wyczyść błędy taśmy" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "idź do końca danych Bareos'i w celu dołączenia (append)" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "idź do fizycznego końca medium" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "wypełnij taśmę, zapisuj na drugim wolumenie" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "odczytaj zapełnioną taśmę" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "wyświetl tą komendę" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "zapisz etykietę Bareos dla taśmy" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "załaduj taśmę" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "zamknij btape" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "użyj write() by zapełnić taśmę" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "odczytaj o wyświetl etykietę taśmy Bareos" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "przetestuj funkcje sterujace zapisu" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "przewiń taśmę" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "read() - odczytaj taśmę blok po bloku do EOT i wygeneruj raport" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "Bareos odczytała blok po bloku do EOT i wygenerowała raport" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] raport " "prędkości dysku" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "wyświetl status taśmy" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "Ogólny test Bareos funkcji taśmy" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "Zapis EOF na taśmie." #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "zapisz pojedyńczy blok Bareos'i" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "odczytaj pojedynczy rekord" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "przeczytaj pojedyńczy blok Bareos'i" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "polecenie szybkiego wypełnienia" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "\"%s\" nie jest poprawnym poleceniem\n" #: src/stored/btape.c:2974 #, fuzzy, c-format msgid "Interactive commands:\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/stored/btape.c:2985 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" "Napisany przez Nicolas Boichat (2004)\n" "\n" "Wersja: %s (%s) %s %s %s\n" "\n" "Użycie: tray-monitor [-c config_file] [-d debug_level]\n" " -c ustaw plik konfiguracyjny na \n" " -d usta poziom debugowania na \n" " -dt wyświetla znaczniki czasowe w debugingu\n" " -t test - odczytuje konfiguracj i kończy działanie\n" " -? wyświetla ten komunikat.\n" "\n" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "Zamontuj drugi Wolumen w urządzeniu %s i kiedy gotowe naciśnij Enter: " #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" "Zamontuj Wolumen \"%s\" w urządzeniu %s i kiedy gotowe naciśnij Enter: " #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "Zamontuj pusty Wolumen w urządzeniu %s i kiedy gotowe naciśnij Enter: " #: src/stored/btape.c:3118 #, fuzzy, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "Nie mogę przyci wolumenu \"%s\"\n" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "Read block =%u, VolBytes=%s rate=%sB/s\n" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, fuzzy, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr " Nie można otworzyć %s: ERR=%s.\n" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "Statystyki spooling'u:\n" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, fuzzy, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, fuzzy, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, fuzzy, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/spool.c:404 #, fuzzy, c-format msgid "Spool header read error. ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, fuzzy, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, fuzzy, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 #, fuzzy msgid "Fatal despooling error." msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, fuzzy, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "Błąd sieci na BlastAttributes.\n" #: src/stored/spool.c:701 #, fuzzy, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/spool.c:716 #, fuzzy, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/spool.c:728 #, fuzzy, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:769 #, fuzzy, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/stored/reserve.c:84 #, fuzzy, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "Nie można zainicjalizowa blokady BD. ERR=%s\n" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "Hej! num_writers=%d!!!!\n" #: src/stored/reserve.c:258 #, fuzzy msgid "3939 Could not get dcr\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/reserve.c:366 #, fuzzy, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "Nieudana walidacja sygnatury dla %s: %s\n" #: src/stored/reserve.c:375 #, fuzzy, c-format msgid "Failed command: %s\n" msgstr "Za komenda level: %s\n" #: src/stored/reserve.c:665 #, fuzzy, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "Nie można ustawi pola Finder Info na %s\n" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" "3601 JobId=%u - urządzenie %s jest ZABLOKOWANE z powodu odmontowania przez " "użytkownika.\n" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "3602 JobId=%u - urządzenie %s jest zajęte (trwa odczyt/zapis).\n" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "3603 JobId=%u - urządzenei %s jest zajęte, trwa odczyt.\n" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" "3604 JobId=%u - urządzenie %s jest ZABLOKOWANE z powodu odmontowania przez " "użytkownika.\n" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" "3608 JobId=%u żąda Pool=\"%s\" ale otrzymało Pool=\"%s\" nreserve=%d na " "dysku %s.\n" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" "3609 JobId=%u - Na dysku %s przekroczono maksymalną ilość równoczesnych " "zadań.\n" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "3610 JobId=%u - Na dysku %s przekroczono maksymalny wolumen zadań.\n" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "3605 JobId=%u żąda wolnego dysku ale urządzenie %s jest zajęte.\n" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" "3606 JobId=%u preferuje zamontowane dyski, jednak dysk %s nie ma Wolumenu.\n" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" "3607 JobId=%u żąda Vol=\"%s\" napęd posiada Vol=\"%s\" w napędzie %s.\n" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "Błąd logiki!!!! JobId=%u Nie powinienem być tutaj.\n" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "3910 JobId=%u Błąd logiki!!!! napęd %s Nie powinienem być tutaj.\n" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "Błąd logiki!!!! Nie powinienem być tutaj.\n" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "Błąd komunikacji z SD. za odpowiedź na %s. ERR=%s\n" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "Za odpowiedź na komend %s. Oczekiwano %s, otrzymano %s\n" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "Błąd sieci w wysyaniu do SD. ERR=%s\n" #: src/stored/mac.c:438 #, fuzzy, c-format msgid "No Volume names found for %s.\n" msgstr "Nie znaleziono zasobu Zadania dla \"%s\".\n" #: src/stored/mac.c:454 msgid "Read device not properly initialized.\n" msgstr "" #: src/stored/mac.c:479 #, fuzzy msgid "Cannot set buffer size SD->SD.\n" msgstr "Nie można ustawić wielkości bufora FD->SD.\n" #: src/stored/mac.c:496 #, fuzzy, c-format msgid "Bad response to start replicate: %s\n" msgstr "Za odpowiedź na SD read open: %s\n" #: src/stored/mac.c:501 #, fuzzy msgid "Bad response from stored to start replicate command\n" msgstr "Za odpowiedź z demona skadowania na komend open\n" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasowu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -k keep readall capabilities\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -s brak sygnałów (dla debugingu)\n" " -t przetestuj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, fuzzy, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "Nie można otworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, fuzzy, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "Nie można otworzyć pliku bootstrap %s: ERR=%s\n" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, fuzzy, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, fuzzy, c-format msgid "Mounted Volume \"%s\".\n" msgstr "Nie mogę przyci wolumenu \"%s\"\n" #: src/stored/bls.c:315 #, fuzzy, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 #, fuzzy msgid "Fresh Volume Label" msgstr "Wolumen do Katalogu" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 #, fuzzy msgid "Volume Label" msgstr "Wolumen do Katalogu" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "Rozpocznij Sesję Zadania" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "Zakończ Sesję Zadania" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "Koniec Medium" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "Koniec Fizycznego Medium" #: src/stored/bls.c:468 msgid "Start of object" msgstr "Początek obiektu" #: src/stored/bls.c:471 msgid "End of object" msgstr "Koniec obiektu" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 #, fuzzy msgid "Unknown" msgstr "Nieznany status." #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" #: src/stored/backends/rados_device.c:49 #, fuzzy, c-format msgid "Unable to parse device %s.\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:62 #, fuzzy, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "Nie mogę utworzyć wątku. ERR=%s\n" #: src/stored/backends/rados_device.c:69 #, fuzzy, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:77 #, fuzzy, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:89 #, fuzzy, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:271 #, fuzzy, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:278 #, fuzzy, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, fuzzy, c-format msgid "Request for unknown devicetype: %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/backends/gfapi_device.c:317 #, fuzzy, c-format msgid "Unable to parse device URI %s.\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/gfapi_device.c:329 #, fuzzy, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "Nie mogę otrzyma rekordu Zadania dla JobId=%s: ERR=%s\n" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, fuzzy, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "Nie można zainicjalizowa blokady Pythona. ERR=%s\n" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, fuzzy, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "%s istnieje ale nie ma go w katalogu.\n" #: src/stored/backends/cephfs_device.c:58 #, fuzzy, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "Nie mogę utworzyć wątku. ERR=%s\n" #: src/stored/backends/cephfs_device.c:65 #, fuzzy, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/stored/backends/cephfs_device.c:72 #, fuzzy, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/backends/cephfs_device.c:101 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "%s istnieje ale nie ma go w katalogu.\n" #: src/stored/backends/cephfs_device.c:111 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "%s istnieje ale nie ma go w katalogu.\n" #: src/stored/backends/generic_tape_device.c:212 #, fuzzy, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, fuzzy, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:339 #, fuzzy, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "Błędne odwołanie do weof_dev. Urządzenie nie otwarte\n" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, fuzzy, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "Błędne odwołanie do fsf. Urządzenie nie otwarte\n" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, fuzzy, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:498 #, fuzzy, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "Błędne odwołanie do bsf. Urządzenie nie otwarte\n" #: src/stored/backends/generic_tape_device.c:611 #, fuzzy, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "Błędne odwołanie do fsr. Urządzenie nie otwarte\n" #: src/stored/backends/generic_tape_device.c:644 #, fuzzy, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/backends/generic_tape_device.c:674 #, fuzzy, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "Błędne odwołanie do bsr_dev. Urządzenie nie otwarte\n" #: src/stored/backends/generic_tape_device.c:699 #, fuzzy, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/backends/generic_tape_device.c:715 #, fuzzy, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "Błędne odwołanie do load_dev. Urządzenie nie otwarte\n" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, fuzzy, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/stored/backends/generic_tape_device.c:947 #, fuzzy, c-format msgid "unknown func code %d" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/backends/generic_tape_device.c:953 #, fuzzy, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/stored/backends/generic_tape_device.c:1055 #, fuzzy, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, fuzzy, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/backends/generic_tape_device.c:1236 #, fuzzy msgid " Bareos status:" msgstr "Monitor statusu demona Bareos" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr " plik=%d blok=%d\n" #: src/stored/backends/generic_tape_device.c:1246 #, fuzzy msgid " Device status:" msgstr "Monitor statusu demona Bareos" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, fuzzy, c-format msgid "Failed to create a new context using config %s\n" msgstr "Nieudane odzyskanie rozszerzonych atrybutw na pliku \"%s\"\n" #: src/stored/backends/object_store_device.c:190 #, fuzzy, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, fuzzy, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:274 #, fuzzy, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:298 #, fuzzy, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/stored/backends/object_store_device.c:406 #, fuzzy, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/stored/backends/object_store_device.c:416 #, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "Status używanego Wolumenu:\n" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" "\n" "Status urządzenia:\n" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 #, fuzzy msgid "waiting for" msgstr "Status zadania: Oczekiwanie na Zamontowanie" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 #, fuzzy msgid "waiting for sysop intervention" msgstr "Status zadania: Oczekiwanie na czas startu" #: src/stored/status.c:275 #, fuzzy msgid "unknown state" msgstr "Nieznany status." #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, fuzzy, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/stored/status.c:317 #, fuzzy, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr " Ustawiony na: Plik=%s Blok=%s\n" #: src/stored/status.c:332 #, fuzzy, c-format msgid "" "\n" "Device %s is not open.\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/stored/status.c:336 #, fuzzy, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/stored/status.c:369 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "Demon wystartowany %s, %d Zada %s uruchomionych od wystartowania.\n" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" "Brak struktury URZĄDZENIA.\n" "\n" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 #, fuzzy msgid " Device is BLOCKED waiting for media.\n" msgstr "Status zadania: Oczekiwanie na nowe media" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 #, fuzzy msgid " Device is blocked labeling a Volume.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/stored/status.c:523 #, fuzzy, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/stored/status.c:527 #, fuzzy, c-format msgid " Drive %d is not loaded.\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 #, fuzzy msgid "Attached Jobs: " msgstr "" "\n" "Zakoczonych Zada:\n" #: src/stored/status.c:604 #, fuzzy, c-format msgid " Archive name: %s Device name: %s\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/stored/status.c:607 #, fuzzy, c-format msgid " File=%u block=%u\n" msgstr "Plik=%u blok=%u\n" #: src/stored/status.c:610 #, fuzzy, c-format msgid " Min block=%u Max block=%u\n" msgstr "Min blok=%u Max blok=%u\n" #: src/stored/status.c:633 #, fuzzy, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "Status zadania: Oczekiwanie na zasoby Klienta" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, fuzzy, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr " SDSocket zamknięto.\n" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" "\n" "Zadania oczekujące na rezerwację napędu:\n" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "===================================================================\n" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "Baza" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "Inicjalizacja Katalogu" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "Wolumen do Katalogu" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "Dysk do Katalogu" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "Dane" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "Nieznany Poziom Zadania" #: src/stored/status.c:955 #, fuzzy, c-format msgid "3900 No arg in status command: %s\n" msgstr "Za komenda .status: %s\n" #: src/stored/status.c:984 #, fuzzy, c-format msgid "3900 No arg in .status command: %s\n" msgstr "Za komenda .status: %s\n" #: src/stored/status.c:1033 #, fuzzy, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "Za komenda .status: %s\n" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "Bareos Storage: Bezczynny" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "Bareos Storage: Uruchomiony" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "Bareos Storage: Ostatnie Zadanie Anulowane" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "Bareos Storage: Ostatnie Zadanie Nieudane" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "Bareos Storage: Ostatnie Zadanie miało Ostrzeżenia" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, fuzzy, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "Nie znaleziono tabeli: %s\n" #: src/stored/sd_cmds.c:131 #, fuzzy msgid "Unable to authenticate Storage daemon\n" msgstr "Nieudana autentykacja demona Skadowania.\n" #: src/stored/sd_cmds.c:182 #, fuzzy, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "Błąd komunikacji z SD. za odpowiedź na %s. ERR=%s\n" #: src/stored/sd_cmds.c:185 #, fuzzy msgid "Command error with SD, hanging up.\n" msgstr "Błąd komunikacji z SD. za odpowiedź na %s. ERR=%s\n" #: src/stored/sd_cmds.c:197 #, fuzzy, c-format msgid "SD command not found: %s\n" msgstr "Nie znaleziono tabeli: %s\n" #: src/stored/sd_cmds.c:338 #, fuzzy msgid "Replicate data error.\n" msgstr "Błąd danych Zlib" #: src/stored/sd_cmds.c:343 #, fuzzy msgid "Attempt to replicate on non-open session.\n" msgstr "Próba zapisu na wolumenie tylko do odczytu.\n" #: src/stored/authenticate.c:53 #, fuzzy, c-format msgid "I only authenticate Directors, not %d\n" msgstr "Autentykuj wycznie directory, nie %d\n" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "Za komenda Hello od Directora przy %s. Len=%d.\n" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "Za komenda Hello od Directora przy %s: %s\n" #: src/stored/authenticate.c:90 #, fuzzy, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "Połączenie od nieznanego Directora %s przy %s odrzucone.\n" #: src/stored/authenticate.c:133 #, fuzzy, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "Niepoprawne haso podane przez Director przy %s.\n" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" "Problem autoryzacji: Zdalny serwer nie zaproponowa wymaganego wsparcia dla " "TLS.\n" #: src/stored/authenticate.c:162 #, fuzzy, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "Negocjacje TLS nie powiody si\n" #: src/stored/authenticate.c:257 #, fuzzy, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "Połączenie od nieznanego Directora %s przy %s odrzucone.\n" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, fuzzy, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "Negocjacje TLS nie powiody si\n" #: src/stored/authenticate.c:336 #, fuzzy, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "Nie mogę zautentykowa Directora\n" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, fuzzy, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/mount.c:103 #, fuzzy, c-format msgid "Job %d canceled.\n" msgstr "2001 Zadanie %s oznaczone do anulowania.\n" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, fuzzy, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "Błąd w dostarczeniu komunikatu: nieudane fopen %s: ERR=%s\n" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, fuzzy, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "Nie mogę odzyska waciciela xattr %s na pliku \"%s\": ERR=%s\n" #: src/stored/mount.c:415 src/stored/mount.c:746 #, fuzzy, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, fuzzy, c-format msgid "Could not reserve volume %s on %s\n" msgstr "Nie można ustawi pola Finder Info na %s\n" #: src/stored/mount.c:621 #, fuzzy, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 #, fuzzy msgid "Error updating Catalog\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, fuzzy, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, fuzzy, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/mount.c:741 #, fuzzy, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "Wymagane TLS lecz nie zostao skonfigurowane w Baculi.\n" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, fuzzy, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" "Na urządzeniu %s zamontowano niepoprawny wolumen: żądano %s otrzymano %s\n" #: src/stored/label.c:123 src/stored/label.c:203 #, fuzzy, c-format msgid "Too many tries: %s" msgstr "Zbyt duo elementw w zasobie %s\n" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" "Wymagany Wolumen \"%s\" na %s nie jest Wolumenem z etykietą Bareos, " "ponieważ: ERR=%s" #: src/stored/label.c:147 #, fuzzy msgid "Could not read Volume label from block.\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/label.c:150 #, fuzzy, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "Zły Header Id: %s\n" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "Wolumen na %s na złą wersję Bareos. Oczekiwano %d, otrzymano %d\n" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "Wolumen na %s ma zły typ etykiety Bareos: %x\n" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "Nie można zapisać etykiety Wolumenu do bloku na urządzeniu %s\n" #: src/stored/label.c:525 #, fuzzy, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/label.c:532 #, fuzzy, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "Błąd w acltotext na pliku \"%s\": ERR=%s\n" #: src/stored/label.c:538 #, fuzzy, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "Nie mogę otworzyć przestrzeni xattr na pliku \"%s\": ERR=%s\n" #: src/stored/label.c:561 #, fuzzy, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" "Usunięty Wolumen \"%s\" na urządzeniu %s, wszystkie wcześniejsze dane " "utracone.\n" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" "Zapisano etykietę na wolumenie z wcześniejszą etykietą \"%s\". Urządzenie %" "s\n" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "Błędna etykieta sesji Wolumenu = %d\n" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "Oczekiwano etykiety Wolumenu, otrzymano FI=%s Stream=%s len=%d\n" #: src/stored/label.c:992 #, fuzzy, c-format msgid "Unknown %d" msgstr "Nieznany status." #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" "\n" "Etykieta Wolumenu:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "Etykieta daty zapisana: %s\n" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "Etykieta daty zapisana: %04d-%02d-%02d przy %02d:%02d\n" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "Data zapisana : %s\n" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "Data zapisana : %04d-%02d-%02d at %02d:%02d\n" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "Nowy Wolumen" #: src/stored/label.c:1113 #, fuzzy msgid "Volume" msgstr "Wolumen do Katalogu" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "Koniec Medium" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "Koniec Taśmy" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "Rekord %s : File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "Fizyczny koniec taśmy.\n" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "Rekord %s: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr " Zadanie=%s Data=%s Poziom=%c Typ=%c\n" #: src/stored/label.c:1176 #, fuzzy, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" "Blok dump'a %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "%d błędów odczytu bloków które nie zostały wyświetlone.\n" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" "Błąd wolumenu danych dla %u:%u! Żądane ID: \"%s\", otrzymano \"%s\". Bufor " "odrzucony.\n" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" "Błąd wielkości danych dla %u:%u! Wielkość bloku %u jest gigantyczna, " "prawdopodobnie z powodu błędnego archiwum.\n" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" "Błąd danych wolumanu przy %u:%u!\n" "Suma kontrolna bloku niezgodna dla block=%u len=%d: calc=%x blk=%x\n" #: src/stored/block.c:457 #, fuzzy, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "Nie można zapisać bloku. EOM urządzenia.\n" #: src/stored/block.c:463 #, fuzzy, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "Próba zapisu na wolumenie tylko do odczytu.\n" #: src/stored/block.c:469 #, fuzzy, c-format msgid "Attempt to write on closed device=%s\n" msgstr "Próba zapisu na wolumenie tylko do odczytu.\n" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" "Użytkownik zdefiniował maksymalną pojemność wolumenu %s która przekracza " "dostępną na urządzeniu %s.\n" #: src/stored/block.c:553 #, fuzzy, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "Nie można zainicjalizowa blokady BD. ERR=%s\n" #: src/stored/block.c:576 src/stored/block.c:610 #, fuzzy msgid "Write block header zeroed.\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, fuzzy, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" "Koniec Wolumenu \"%s\" przy %u:%u na urządzeniu %s. Zapisano %u bajtów, do " "zapisu %d.\n" #: src/stored/block.c:644 #, fuzzy, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/block.c:740 src/stored/block.c:746 #, fuzzy, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/block.c:755 #, fuzzy, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #: src/stored/block.c:774 #, fuzzy, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" "Ponowny odczyt ostatniego bloku: ilość bloków różni się o więcej niż jeden.\n" "Pawdopodobna błędna konfiguracja taśmy i utrata danych. Odczytany blok=%u " "Żądany blok=%u.\n" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" "Ponowny odczyt ostatniego bloku zakończony sukcesem. jednak różna ilość " "bloków.Odczytany blok=%u Żądany blok=%u.\n" #: src/stored/block.c:792 #, fuzzy msgid "Re-read of last block succeeded.\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" "Błąd podczas końcowego zapisu EOF na taśmę. Ten Wolumen może nie nadawać się " "do odczytu.\n" "%s" #: src/stored/block.c:836 #, fuzzy msgid "Error sending Volume info to Director.\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/block.c:949 #, fuzzy msgid "Job failed or canceled.\n" msgstr "2001 Zadanie %s oznaczone do anulowania.\n" #: src/stored/block.c:955 #, fuzzy msgid "Attempt to read past end of tape or file.\n" msgstr "Próba zapisu na wolumenie tylko do odczytu.\n" #: src/stored/block.c:964 #, fuzzy, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "Problem zapętlenia dot. rozmiaru bloku bufora na urządzeniu %s\n" #: src/stored/block.c:1003 #, fuzzy, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/block.c:1021 #, fuzzy, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "Ustawiam rozmiar bloku bufora na %u bajtów.\n" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, fuzzy, c-format msgid "Error getting Volume info: %s" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/stored/askdir.c:381 #, fuzzy, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "Nie można stworzyć fifo %s: ERR=%s\n" #: src/stored/askdir.c:436 #, fuzzy, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/askdir.c:443 #, fuzzy, c-format msgid "Error creating JobMedia record: %s\n" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "błąd pthread w mount_next_volume.\n" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "błąd pthread w mount_volume.\n" #: src/stored/bextract.c:71 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasowu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -k keep readall capabilities\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -s brak sygnałów (dla debugingu)\n" " -t przetestuj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "Nazwa Programu %d i/lub zapisy Strumieni Danych zignorowane.\n" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" "Strumienie zapisu %d danych Win32 lub danych Win32 gzip. Zignorowano.\n" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "Nieznany strumie=%d zignorowany. To nie powinno się sta!\n" #: src/stored/bextract.c:403 #, fuzzy, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "Nie można wykona stat na pliku %s: ERR=%s\n" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "%s musi być katalogiem.\n" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "%u przywróconych plików.\n" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "Błąd zapisu na %s: %s\n" #: src/stored/bextract.c:499 src/stored/bextract.c:708 #, fuzzy msgid "Logic error output file should be open but is not.\n" msgstr "Błąd logiki: plik wyjściowy powinien być otwarty\n" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/stored/bextract.c:523 #, fuzzy, c-format msgid "%s was deleted.\n" msgstr "Status zadania: Anulowane" #: src/stored/bextract.c:571 #, fuzzy, c-format msgid "Seek error on %s: %s\n" msgstr "Błąd zapisu na %s: %s\n" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "Przesunięcie do %s błąd na %s: ERR=%s\n" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "Otrzymano Nazwę Programu lub Strumień Danych. Zignorowano.\n" #: src/stored/lock.c:390 #, fuzzy, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "pthread_create: ERR=%s\n" #: src/stored/lock.c:489 #, fuzzy msgid "unknown blocked code" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/autochanger.c:60 #, fuzzy, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/stored/autochanger.c:66 #, fuzzy, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/stored/autochanger.c:133 #, fuzzy, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" "Zdefiniowany błędny slot=%d w katalogu dla Wolumenu \"%s\" na %s. Może być " "konieczne załadowanie ręczne.\n" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" "Brak \"Changer Device\" dla %s. Może być konieczne ręczne załadowanie " "Wolumenu.\n" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" "Brak \"Changer Command\" dla %s. Może być konieczne ręczne załadowanie " "Wolumenu.\n" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "3305 Autochanger \"załadowany slot %d, napęd %d\", status is OK.\n" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" "3992 Zła biblioteka taśmowa \"załadowany slot %d, napęd %d\": ERR=%s.\n" "Wyniki=%s\n" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "3301 Wywołanie autochanger \"załadowany? napęd %d\" komenda.\n" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, fuzzy, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "Za komenda storage: %s" #: src/stored/autochanger.c:310 #, fuzzy, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "Błąd blokowania muteksa. ERR=%s\n" #: src/stored/autochanger.c:324 #, fuzzy, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "Błąd odblokowania muteksa. ERR=%s\n" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, fuzzy, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "Za komenda storage: %s" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, fuzzy, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "Za komenda storage: %s" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, fuzzy, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/autochanger.c:699 #, fuzzy msgid "3306 Issuing autochanger transfer command.\n" msgstr "Za komenda storage: %s" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, fuzzy, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "JobId=%s, Zadanie %s oczekuje na rezerwację urządzenia.\n" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "częściowy," #: src/stored/butil.c:60 msgid "empty," msgstr "pusty" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, fuzzy, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "Nie można znale zasobu Client %s\n" #: src/stored/butil.c:174 #, fuzzy, c-format msgid "Cannot init device %s\n" msgstr "Nie można znale zasobu Client %s\n" #: src/stored/butil.c:199 #, fuzzy, c-format msgid "Cannot open %s\n" msgstr " Nie można otworzyć %s: ERR=%s.\n" #: src/stored/butil.c:293 #, fuzzy, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "Nieoczekiwany koniec danych\n" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "Nieoczekiwany koniec taśmy\n" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "Nieoczekiwany koniec pliku\n" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "Rozpocznij Sesję" #: src/stored/read_record.c:63 msgid "End Session" msgstr "Zakończ Sesję" #: src/stored/read_record.c:69 #, fuzzy, c-format msgid "Unknown code %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "Koniec Wolumenu na pliku %u urządzenia %s, Wolumen \"%s\"\n" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "Koniec wszystkich Wolumenów.\n" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, fuzzy, c-format msgid "Job %s canceled.\n" msgstr "Status zadania: Anulowane" #: src/stored/acquire.c:225 #, fuzzy, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, fuzzy, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "Nie można ustawi pola Finder Info na %s\n" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, fuzzy, c-format msgid "Could not ready device %s for append.\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "Alert: %s" #: src/stored/acquire.c:577 #, fuzzy, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "2994 Za komenda verify: %s\n" #: src/stored/acquire.c:654 #, fuzzy, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/stored/ansi_label.c:86 #, fuzzy, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "Szaleństwo! Koniec taśmy podczas odczytu etykiety ANSI.\n" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "Brak etykiety VOL1 podczas odczytu etykiety ANSI/IBM.\n" #: src/stored/ansi_label.c:156 #, fuzzy, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "Nie mogę przyci wolumenu \"%s\"\n" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "Brak etykiety HDR1 podczas odczytu etykiety ANSI.\n" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "Wolumen ANSI/IBM \"%s\" nie należy do Bareos.\n" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "Brak etykiety HDR2 podczas odczytu etykiety ANSI/IBM.\n" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "Nieznana etykieta ANSI/IBM lub jej błędny zapis.\n" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "Zbyt wiele rekordów podczas odczytu etykiety ANSI/IBM.\n" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "Etykieta Wolumenu ANSI \"%s\" dłuższa niż 6 znaków.\n" #: src/stored/ansi_label.c:349 #, fuzzy, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, fuzzy, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 #, fuzzy msgid "Could not write ANSI HDR1 label.\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/ansi_label.c:441 #, fuzzy, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "Błąd w wysyaniu Hello do demona Przechowywania. ERR=%s\n" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "write_ansi_ibm_label wywołuje typ non-ANSI/IBM\n" #: src/stored/sd_backends.c:172 #, fuzzy, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, fuzzy, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "Nie można zainicjalizowa blokady BD. ERR=%s\n" #: src/stored/bcopy.c:60 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasowu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -k keep readall capabilities\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -s brak sygnałów (dla debugingu)\n" " -t przetestuj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/stored/bcopy.c:247 #, fuzzy msgid "Write of last block failed.\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "Skopiowano %u Jobów. Skopiowano %u rekordów.\n" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" "wolumen ma nadaną wcześniej etykietę. Ten wolumen nie moze być skopiowany.\n" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "Etykieta wolumenu nie została skopiowana.\n" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "Kopiowanie pominięte. Wpis nie odpowiada filtrowi BSR.\n" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "Etykieta EOM nie została skopiowana.\n" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "Etykieta EOT nie została skopiowana.\n" #: src/stored/stored.c:76 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -k zachowaj właściwości readall\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -s brak sygnałów (dla debugingu)\n" " -t przetestuj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "Nie mogę utworzyć wątku. ERR=%s\n" #: src/stored/stored.c:325 #, fuzzy, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "Dozwolony tylko jeden zasób Client w %s\n" #: src/stored/stored.c:330 #, fuzzy, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/stored/stored.c:335 #, fuzzy, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/stored/stored.c:343 #, fuzzy, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/stored/stored.c:371 #, fuzzy, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "Nie zdefiniowany plik \"TLS Certificate\" dla Dyrektora \"%s\" w %s.\n" #: src/stored/stored.c:377 #, fuzzy, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "Nie zdefiniowany plik \"TLS Key\" dla Dyrektora \"%s\" w %s.\n" #: src/stored/stored.c:383 #, fuzzy, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie s " "zdefiniowane dla Dyrektora \"%s\" w %s. Co najmniej jedno skadowanie " "certyfikatu CA jest wymagane kiedy jest używane \"TLS Verify Peer\".\n" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, fuzzy, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "Nie można zainicjować zmiennej warunkowej zadania: ERR=%s\n" #: src/stored/stored.c:614 #, fuzzy, c-format msgid "Could not initialize %s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/stored/stored.c:633 #, fuzzy, c-format msgid "Could not open device %s\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/stored.c:648 #, fuzzy, c-format msgid "Could not mount device %s\n" msgstr "Nie można stworzyć skrt.\n" #: src/stored/record.c:65 #, fuzzy, c-format msgid "unknown: %d" msgstr "Nieznany status." #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "Zniszczony bufor\n" #: src/stored/record.c:479 #, fuzzy msgid "Quota Exceeded. Job Terminated.\n" msgstr "Przekroczony maksymalny czas uruchomienia. Zadanie anulowane.\n" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" "Niepowodzenie testu zdrowego rozsądku. Wielkości: maxlen=%d a mamy datalen=%" "d. Blok odrzucony.\n" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "Niedowolnony strumie xattr, brak XATTR_MAGIC na pliku \"%s\"\n" #: src/findlib/xattr.c:261 #, fuzzy, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" "Niepoprawny strumie xattr, nieudane przetwarzanie strumienia na pliku \"%s" "\"\n" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, fuzzy, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "Błąd llistxattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, fuzzy, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "Błąd w getacl na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "Strumie Xattr na pliku \"%s\" przekroczy maksymalny rozmiar %d bajtw\n" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "Nieudane serializacja rozszerzonych atrybutw na pliku \"%s\"\n" #: src/findlib/xattr.c:650 #, fuzzy, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "Błąd w setacl na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, fuzzy, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "Błąd extattr_list_link na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:981 #, fuzzy, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "Niedowolnony strumie xattr, brak XATTR_MAGIC na pliku \"%s\"\n" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, fuzzy, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_set na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "Błąd llistxattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "Błąd lgetxattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "Błąd lsetxattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "Błąd extattr_list_link na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "Nieudana konwersja %d w przestrzeni nazw na pliku \"%s\"\n" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "Błąd extattr_get_link na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "Nieudany podzia %s w przestrzeni nazw i czci nazwy na pliku \"%s\"\n" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "Nieudana konwersja %s w przestrzeni nazw na pliku \"%s\"\n" #: src/findlib/xattr.c:1965 #, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "Błąd extattr_set_link na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, fuzzy, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "Błąd w getacl na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2292 #, fuzzy, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "Nie mogę odczyta kontekst xattr %s na pliku \"%s\"\n" #: src/findlib/xattr.c:2321 #, fuzzy, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "Błąd w strtoacl na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę otrzyma acl na xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę otrzyma acl text na xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę otrzyma statusu na xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na \"%s\": ERR=%s\n" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "Nie mogę odczyta kontekst xattr %s na pliku \"%s\"\n" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona chdir do przestrzeni xattr pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć przestrzeni xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona chdir do przestrzeni xattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "Nie mogę wylistowa przestrze xattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "Nie mogę przekonwertowa acl z tekstu na plik \"%s\"\n" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę odtworzy acl xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć przestrzeni xattr na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "" "Nie mogę wykona chdir do przestrzeni xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona mkfifo xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona mknod xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona mkdir xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona link xattr %s do %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" "Nie mogę odzyska danych xattr %s na pliku \"%s\": Nie wszystkie dane s " "dostpne w strumieniu xattr\n" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę odzyska danych xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę wykona symlink xattr %s do %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę odzyska waciciela xattr %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "Nie mogę odzyska xattr filetime %s na pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" "Niepoprawny strumie xattr, nieudane przetwarzanie strumienia na pliku \"%s" "\"\n" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "Nieudane odzyskanie rozszerzalnych atrybutw na pliku \"%s\"\n" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "Nieudane odzyskanie rozszerzonych atrybutw na pliku \"%s\"\n" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, fuzzy, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" "Nie mogę odzyska Rozszrzone Atrybuty %s - osignito niekompatybilny strumie " "xattr - %d\n" #: src/findlib/find.c:180 #, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "Wtyczka: \"%s\" nie znaleziona.\n" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "Atrybuty Unix" #: src/findlib/bfile.c:92 msgid "File data" msgstr "Dane pliku" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "Streszczenie MD5" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "Dane GZIP" #: src/findlib/bfile.c:98 #, fuzzy msgid "Compressed data" msgstr "Dane pliku" #: src/findlib/bfile.c:100 #, fuzzy msgid "Extended attributes" msgstr "Atrybuty Unix" #: src/findlib/bfile.c:102 #, fuzzy msgid "Sparse data" msgstr "Dane pliku" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "" #: src/findlib/bfile.c:106 #, fuzzy msgid "Compressed sparse data" msgstr "Dane pliku" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "Nazwy programu" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "Dane programu" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "Streszczenie SHA1" #: src/findlib/bfile.c:114 #, fuzzy msgid "Win32 data" msgstr "Dane pliku" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "Dane Win32 GZIP" #: src/findlib/bfile.c:118 #, fuzzy msgid "Win32 compressed data" msgstr "Dane pliku" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "Dane MacOS Fork" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "Atrybuty HFS+" #: src/findlib/bfile.c:124 #, fuzzy msgid "Standard Unix ACL attribs" msgstr "Atrybuty Unix" #: src/findlib/bfile.c:126 #, fuzzy msgid "Default Unix ACL attribs" msgstr "Atrybuty Unix" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "Streszczenie SHA256" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "Streszczenie SHA512" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "Podpisane streszczenie" #: src/findlib/bfile.c:134 #, fuzzy msgid "Encrypted File data" msgstr "Dane pliku" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "zakodowane dane Win32" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "zakodowane dane sesji" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "Zakodowane dane GZIP" #: src/findlib/bfile.c:142 #, fuzzy msgid "Encrypted compressed data" msgstr "zakodowane dane sesji" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "Zakodowane dane Win32 GZIP" #: src/findlib/bfile.c:146 #, fuzzy msgid "Encrypted Win32 Compressed data" msgstr "zakodowane dane Win32" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "Zakodowane dane MacOS fork" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "Atrybuty specyficzne ACL dla AIX" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "Atrybuty specyficzne ACL dla Darwin" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "Domyślne atrybuty specyficzne ACL dla FreeBSD" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "Atrybuty specyficzne dostępu ACL dla FreeBSD" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "Atrybuty specyficzne ACL dla HPUX" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "Domyślne atrybuty specyficzne ACL dla Irix" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "Atrybuty specyficzne dostępu ACL dla Irix" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "Domyślne atrybuty specyficzne ACL dla Linux" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "Atrybuty specyficzne dostępu ACL dla Linux" #: src/findlib/bfile.c:168 #, fuzzy msgid "TRU64 Specific Default ACL attribs" msgstr "Domyślne atrybuty specyficzne ACL dla Irix" #: src/findlib/bfile.c:170 #, fuzzy msgid "TRU64 Specific Access ACL attribs" msgstr "Atrybuty specyficzne dostępu ACL dla Irix" #: src/findlib/bfile.c:172 #, fuzzy msgid "Solaris Specific POSIX ACL attribs" msgstr "Atrybuty specyficzne ACL dla Solaris" #: src/findlib/bfile.c:174 #, fuzzy msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "Atrybuty specyficzne ACL dla Solaris" #: src/findlib/bfile.c:176 #, fuzzy msgid "AFS Specific ACL attribs" msgstr "Atrybuty specyficzne ACL dla AIX" #: src/findlib/bfile.c:178 #, fuzzy msgid "AIX Specific POSIX ACL attribs" msgstr "Atrybuty specyficzne ACL dla AIX" #: src/findlib/bfile.c:180 #, fuzzy msgid "AIX Specific NFSv4 ACL attribs" msgstr "Atrybuty specyficzne ACL dla AIX" #: src/findlib/bfile.c:182 #, fuzzy msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "Atrybuty specyficzne dostępu ACL dla FreeBSD" #: src/findlib/bfile.c:184 #, fuzzy msgid "GNU Hurd Specific Default ACL attribs" msgstr "Domyślne atrybuty specyficzne ACL dla Irix" #: src/findlib/bfile.c:186 #, fuzzy msgid "GNU Hurd Specific Access ACL attribs" msgstr "Atrybuty specyficzne dostępu ACL dla Irix" #: src/findlib/bfile.c:188 #, fuzzy msgid "GNU Hurd Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Linux" #: src/findlib/bfile.c:190 #, fuzzy msgid "IRIX Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Linux" #: src/findlib/bfile.c:192 #, fuzzy msgid "TRU64 Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Linux" #: src/findlib/bfile.c:194 #, fuzzy msgid "AIX Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Linux" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla OpenBSD" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" "Rozszeżalne atrybuty specyficzne dla Solaris lub rozszerzone " "atrybutysystemowe" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Solaris" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Darvin" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla FreeBSD" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla Linux" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "Rozszerzone atrybuty specyficzne dla NetBSD" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, fuzzy, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, fuzzy, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, fuzzy, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, fuzzy, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" "Rozmiar odzyskanego pliku %s nie jest poprawny. Oryginalny %s, odzyskany %" "s.\n" #: src/findlib/attribs.c:480 #, fuzzy, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/findlib/attribs.c:714 #, fuzzy, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/findlib/attribs.c:730 #, fuzzy, c-format msgid "Error in %s: ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "Nie można otworzyć aktualnego katalogu: ERR=%s\n" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "Nie można pobra aktualnego katalogu: ERR=%s\n" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "Nie można zresetowa aktualnego katalogu: ERR=%s\n" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "Zbiór AdjustTokenPrivileges " #: src/findlib/create_file.c:119 #, fuzzy, c-format msgid "File skipped. Not newer: %s\n" msgstr "Ominity plik. Ju istnieje: %s\n" #: src/findlib/create_file.c:125 #, fuzzy, c-format msgid "File skipped. Not older: %s\n" msgstr "Ominity plik. Ju istnieje: %s\n" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "Ominity plik. Ju istnieje: %s\n" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "Plik %s już istnieje i nie może być zastąpiony. ERR=%s.\n" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "bpkt już otwarty fid=%d\n" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "Nie można stworzyć fifo %s: ERR=%s\n" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "Nie można stworzyć wza %s: ERR=%s\n" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, fuzzy, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "Nie można stworzyć pliku bootstrap %s: ERR=%s\n" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, fuzzy, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "Nie można stworzyć linka twardego %s -> %s: ERR=%s\n" #: src/findlib/create_file.c:352 #, fuzzy, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "Nie można stworzyć pliku bootstrap %s: ERR=%s\n" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, fuzzy, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "Nie można stworzyć linka symbolicznego %s -> %s: ERR=%s\n" #: src/findlib/create_file.c:449 #, fuzzy, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "Nie zapisany oryginalny plik: typ=%s\n" #: src/findlib/create_file.c:463 #, fuzzy, c-format msgid "Original file %s not saved: type=%d\n" msgstr "Nie zapisany oryginalny plik: typ=%s\n" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "Nieznany typ pliku %d; nie odtworzono: %s\n" #: src/findlib/create_file.c:510 #, fuzzy, c-format msgid "Zero length filename: %s\n" msgstr " Przetworzonych plikw: %s\n" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "Nie można stworzyć katalogu %s: ERR=%s\n" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "%s istnieje ale nie ma go w katalogu.\n" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "Nie można zmieni waciciela i/lub grup dla %s: ERR=%s\n" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "Nie można zmieni uprawnie dla %s: ERR=%s\n" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "%c: nie jest poprawnym napędem.\n" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" "Zbyt wiele podkatalogów. Niektóre uprawnienia nie zostały zresetowane.\n" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr " ustawiona flaga NODUMP - nie będzie procedowania %s\n" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "Nie można wykona stat na pliku %s: ERR=%s\n" #: src/findlib/find_one.c:268 #, fuzzy, c-format msgid "%s: mtime changed during backup.\n" msgstr "%s mtime zmieniony podczas backup'u.\n" #: src/findlib/find_one.c:275 #, fuzzy, c-format msgid "%s: ctime changed during backup.\n" msgstr "%s ctime zmieniony podczas backup'u.\n" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, fuzzy, c-format msgid "%s: size changed during backup.\n" msgstr "Rozmiar %s zmieniony podczas backup'u.\n" #: src/findlib/find_one.c:729 #, fuzzy, c-format msgid "%s: File name too long [%d]\n" msgstr "Komentarz za długi.\n" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, fuzzy, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_get na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:293 #, fuzzy, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "bdne kodowanie typu acl w strumieniu acl na pliku \"%s\"\n" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, fuzzy, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "Nie mogę przekonwertowa acl z tekstu na plik \"%s\"\n" #: src/findlib/acl.c:403 #, fuzzy, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia dla " "acl\n" #: src/findlib/acl.c:411 #, fuzzy, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia dla " "acl\n" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, fuzzy, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_set na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:495 #, fuzzy, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_get na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_to_text na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_get_file na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:929 #, fuzzy, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Błąd w acl_delete_def_file na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_delete_def_file na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_from_text na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:967 #, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_valid na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1000 #, fuzzy, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "Błąd w acl_set_file na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_set_file na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "Błąd w pathconf na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1283 #, fuzzy, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia dla " "acl\n" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "Błąd w getacl na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "Błąd w acltostr na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "Błąd w strtoacl na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1683 #, fuzzy, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia dla " "acl\n" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "Błąd w setacl na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_get na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia dla " "acl\n" #: src/findlib/acl.c:1922 #, fuzzy, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia aclent " "acl\n" #: src/findlib/acl.c:1933 #, fuzzy, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" "Próba odtworzenia acl na pliku \"%s\" na systemie plikw bez wsparcia ace " "acl\n" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_fromtext na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "bdne kodowanie typu acl w strumieniu acl na pliku \"%s\"\n" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl_set na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "Błąd w acltotext na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "Błąd w aclfromtext na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl(SETACL) na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:2196 #, fuzzy, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl(SETACL) na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:2225 #, fuzzy, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "Błąd w acl(SETACL) na pliku \"%s\": ERR=%s\n" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" "Nie mogę odtworzy ACL na %s - napotkano niekompatybilny strumie acl - %d\n" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, fuzzy, c-format msgid "Unparseable size option: %s\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, fuzzy, c-format msgid "Unexpected autodeflate setting on %s" msgstr "Oczekiwano ciągu znaków drivetype, otrzymano: %s\n" #: src/plugins/stored/autoxflate-sd.c:368 #, fuzzy, c-format msgid "Unexpected autoinflate setting on %s" msgstr "Oczekiwano ciągu znaków fstype, otrzymano: %s\n" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "Błąd kompresji w defalteParams: %d\n" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, fuzzy, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "Błąd kompresji w deflateReset: %d\n" #: src/plugins/stored/autoxflate-sd.c:575 #, fuzzy, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "Błąd w getacl na pliku \"%s\": ERR=%s\n" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, fuzzy, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/plugins/filed/bpipe-fd.c:910 #, fuzzy msgid "Plugin File argument not specified.\n" msgstr "Nie znaleziono pakietu zapisu wtyczki.\n" #: src/plugins/filed/bpipe-fd.c:916 #, fuzzy msgid "Plugin Reader argument not specified.\n" msgstr "Nie znaleziono pakietu zapisu wtyczki.\n" #: src/plugins/filed/bpipe-fd.c:922 #, fuzzy msgid "Plugin Writer argument not specified.\n" msgstr "Nie znaleziono pakietu zapisu wtyczki.\n" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, fuzzy, c-format msgid "Enter Key Encryption Key: " msgstr "Wprowadź długość do odczytu: " #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, fuzzy, c-format msgid "Cannot open keyfile %s\n" msgstr " Nie można otworzyć %s: ERR=%s.\n" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, fuzzy, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "Nieudane odzyskanie rozszerzonych atrybutw na pliku \"%s\"\n" #: src/tools/bscrypto.c:401 #, fuzzy, c-format msgid "Enter Encryption Key: " msgstr "Wprowadź długość do odczytu: " #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, fuzzy, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Wyświetl rodzaj napędu dla wybranego pliku/katalogu.\n" " Wspierane są następujące opcje:\n" "\n" " -v wyświetl ścieżkę i rodzaj systemu plików.\n" " -? wyświetl tą podpowiedź.\n" "\n" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, fuzzy, c-format msgid "%s: unknown\n" msgstr "Nieznany status." #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, fuzzy, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/tools/bsmtp.c:177 #, fuzzy, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c uyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -r uruchom teraz zadanie \n" " -s brak sygnaw\n" " -t test - odczytaj plik konfiguracji i zakocz\n" " -u identyfikator uytkownika\n" " -v gadatliwe komunikaty uytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, fuzzy, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/tools/bsmtp.c:403 #, fuzzy, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "Błąd w acltostr na pliku \"%s\": ERR=%s\n" #: src/tools/bsmtp.c:412 #, fuzzy, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "Błąd w acltostr na pliku \"%s\": ERR=%s\n" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, fuzzy, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "Błąd w getacl na pliku \"%s\": ERR=%s\n" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, fuzzy, c-format msgid "Failed to connect to mailhost %s\n" msgstr "Nieudane podłączenie do demona Plików.\n" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, fuzzy, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/tools/bsmtp.c:538 #, fuzzy, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "Błąd w pathconf na pliku \"%s\": ERR=%s\n" #: src/tools/bsmtp.c:547 #, fuzzy, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, fuzzy, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/tools/bsmtp.c:563 #, fuzzy, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" "\n" "Użycie: fstype [-v] path ...\n" "\n" " Wyświetl rodzaj systemu plików dla wybranego pliku/katalogu.\n" " Wspierane są następujące opcje:\n" "\n" " -v wyświetl ścieżkę i rodzaj systemu plików.\n" " -? wyświetl tą podpowiedź.\n" "\n" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "Nie można otworzyć pliku komunikatów konsoli %s: ERR=%s\n" #: src/lib/message.c:380 #, fuzzy, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "Nie można zainicjować kolejki zada: ERR=%s\n" #: src/lib/message.c:491 #, fuzzy msgid "BAREOS Message" msgstr "Komunikat Bareos" #: src/lib/message.c:495 #, fuzzy, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "nieudane połączenie z programem mail: ERR=%s\n" #: src/lib/message.c:591 #, fuzzy msgid "open mail pipe failed.\n" msgstr "nieudane połączenie z programem mail.\n" #: src/lib/message.c:604 #, fuzzy, c-format msgid "close error: ERR=%s\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" "Program Mail zakończony z błędem.\n" "CMD=%s\n" "ERR=%s\n" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "nieudane fopen %s: ERR=%s\n" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" "Błąd dostarczenia komunikatu: Program operatora mail zakończony z błędem.\n" "CMD=%s\n" "ERR=%s\n" #: src/lib/message.c:1054 #, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "Błąd w dostarczeniu komunikatu: nieudane fopen %s: ERR=%s\n" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "%s: BŁĄD: " #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "%s: BŁĄD w %s:%d " #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "%s: Ostrzeżenie: " #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "%s: Naruszenie bezpieczeństwa: " #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "%s JobId %u: Błąd krytyczny: " #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "%s JobId %u: Błąd: " #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "%s JobId %u: Ostrzeżenie: " #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "%s JobId %u: Naruszenie bezpieczeństwa: " #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr " --> Komenda=%s\n" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr " --> Cel=%s\n" #: src/lib/runscript.c:338 #, fuzzy, c-format msgid " --> RunOnSuccess=%u\n" msgstr " --> RunOnSuccess=%s\n" #: src/lib/runscript.c:339 #, fuzzy, c-format msgid " --> RunOnFailure=%u\n" msgstr " --> RunOnFailure=%s\n" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr " --> FailJobOnError=%u\n" #: src/lib/runscript.c:341 #, fuzzy, c-format msgid " --> RunWhen=%u\n" msgstr " --> RunWhen=%s\n" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "Problem najprawdopodobniej zaczyna się od linii %d.\n" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" "Błąd konfiguracji: %s\n" " : Linia %d, kolumna %d w pliku %s\n" "%s\n" "%s" #: src/lib/lex.c:105 #, fuzzy, c-format msgid "Config error: %s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/lib/lex.c:140 #, fuzzy, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" "Błąd konfiguracji: %s\n" " : Linia %d, kolumna %d w pliku %s\n" "%s\n" "%s" #: src/lib/lex.c:144 #, fuzzy, c-format msgid "Config warning: %s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 #, fuzzy msgid "none" msgstr "*brak*" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 #, fuzzy msgid "string" msgstr "Odtwarzanie..." #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 #, fuzzy msgid "include" msgstr "Od" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, fuzzy, c-format msgid "expected a positive integer number, got: %s" msgstr "Oczekiwano dodatniej wartości całkowitej, wprowadzono: %s\n" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, fuzzy, c-format msgid "Cannot open included config file %s: %s\n" msgstr "Nie można otworzyć pliku wejciowego FileSet: %s. ERR=%s\n" #: src/lib/lex.c:779 src/lib/lex.c:836 #, fuzzy, c-format msgid "expected an integer or a range, got %s: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, fuzzy, c-format msgid "expected an integer number, got %s: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/lex.c:850 #, fuzzy, c-format msgid "expected a name, got %s: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, fuzzy, c-format msgid "expected a string, got %s: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "Backup" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "Weryfikowanie" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "Odtwarzanie" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "Archiwizowanie" #: src/lib/jcr.c:248 msgid "Copying" msgstr "Kopiowanie" #: src/lib/jcr.c:250 msgid "Migration" msgstr "Migracja" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "Skanowanie" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "Nieznana operacja" #: src/lib/jcr.c:265 msgid "backup" msgstr "backup" #: src/lib/jcr.c:267 msgid "verified" msgstr "zweryfikowany" #: src/lib/jcr.c:269 msgid "restored" msgstr "odtwarzony" #: src/lib/jcr.c:269 msgid "restore" msgstr "odtwarzanie" #: src/lib/jcr.c:271 msgid "archived" msgstr "zarchiwizowany" #: src/lib/jcr.c:271 msgid "archive" msgstr "archiwizacja" #: src/lib/jcr.c:273 msgid "copied" msgstr "skopiowany" #: src/lib/jcr.c:273 msgid "copy" msgstr "kopia" #: src/lib/jcr.c:275 msgid "migrated" msgstr "zmigrowany" #: src/lib/jcr.c:275 msgid "migrate" msgstr "migracja" #: src/lib/jcr.c:277 msgid "scanned" msgstr "zeskanowany" #: src/lib/jcr.c:277 msgid "scan" msgstr "skanuj" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "nieznana akcja" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "nieudane utworzenie klucza pthread: ERR=%s\n" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "nieudane pthread_once. ERR=%s\n" #: src/lib/jcr.c:394 #, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "Nie można zainicjować muteksa msg_queue. ERR=%s\n" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "NULL jcr.\n" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "JCR use_count=%d JobId=%d\n" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "nieudane pthread_setspecific: ERR=%s\n" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" "Watchdog wysłał kill po %d sekundach do wstrzymanego wątku Demona " "Przechowywania podczas odczytu.\n" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "Nie można znaleźć userid=%s: ERR=%s\n" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "Nie można znaleźć elementu hasła. ERR=%s\n" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "Nie można znaleźć grupy=%s: ERR=%s\n" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "Nie można zainicjować grup dla group=%s, userid=%s: ERR=%s\n" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "Nie można zainicjować grup dla userid=%s: ERR=%s\n" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "Nie można ustawić group=%s: ERR=%s\n" #: src/lib/priv.c:108 #, c-format msgid "prctl failed: ERR=%s\n" msgstr "nieudany prctl: ERR=%s\n" #: src/lib/priv.c:112 #, c-format msgid "setreuid failed: ERR=%s\n" msgstr "nieudane setreuid: ERR=%s\n" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "nieudane cap_from_text: ERR=%s\n" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "nieudane cap_set_proc: ERR=%s\n" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "Nie można ustawić wskazanego userid: %s\n" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 #, fuzzy msgid "invalid expansion configuration" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 #, fuzzy msgid "formatting failure" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/lib/var.c:2727 #, fuzzy msgid "unknown error" msgstr "Błąd szyfrowania\n" #: src/lib/scsi_crypto.c:238 #, fuzzy msgid "Drive encryption status:\n" msgstr "Status urządzenia:\n" #: src/lib/scsi_crypto.c:246 #, fuzzy msgid "Encryption Mode: Disabled\n" msgstr "Błąd szyfrowania\n" #: src/lib/scsi_crypto.c:251 #, fuzzy msgid "Encryption Mode: External\n" msgstr "Błąd szyfrowania\n" #: src/lib/scsi_crypto.c:256 #, fuzzy msgid "Encryption Mode: Encrypt\n" msgstr "Błąd szyfrowania\n" #: src/lib/scsi_crypto.c:269 #, fuzzy msgid "Decryption Mode: Disabled\n" msgstr "Błąd odszyfrowywania\n" #: src/lib/scsi_crypto.c:274 #, fuzzy msgid "Decryption Mode: Raw\n" msgstr "Błąd odszyfrowywania\n" #: src/lib/scsi_crypto.c:279 #, fuzzy msgid "Decryption Mode: Decrypt\n" msgstr "Błąd odszyfrowywania\n" #: src/lib/scsi_crypto.c:284 #, fuzzy msgid "Decryption Mode: Mixed\n" msgstr "Błąd odszyfrowywania\n" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 #, fuzzy msgid "Volume encryption status:\n" msgstr "Status używanego Wolumenu:\n" #: src/lib/scsi_crypto.c:460 #, fuzzy msgid "Compression Status: Unknown\n" msgstr "Status zadania: Nieznany(%c)" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 #, fuzzy msgid "Encryption Status: Unknown\n" msgstr "Status zadania: Nieznany(%c)" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 #, fuzzy msgid "Drive encryption status: Unknown\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "Nieudana inicjalizacja połączenia TLS.\n" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "Nieudana negocjacja TLS.\n" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "Włączone TLS lecz nie zostao skonfigurowane.\n" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "Włączone TLS lecz nie zostao skonfigurowane.\n" #: src/lib/bnet.c:326 msgid "No problem." msgstr "Brak problemu." #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "Autorytatywna odpowiedź dla nie znaleziono hosta." #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "Nie autorytatywna odpowiedź dla nie znaleziono hosta lub Błąd Serwera." #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "Nieznany błąd." #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "Nieznany sig %d." #: src/lib/crypto_cache.c:160 #, fuzzy, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "Nie można stworzyć pliku stanu. %s ERR=%s\n" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 #, fuzzy msgid "Volumename" msgstr "Wolumen do Katalogu" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 #, fuzzy msgid "EncryptionKey" msgstr "Błąd szyfrowania\n" #: src/lib/crypto_cache.c:354 #, fuzzy msgid "Added" msgstr "Dodaj" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "Nie można zainicjalizowa blokady watchdog. ERR=%s\n" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "BUG! register_watchdog wywołanie przed start_watchdog\n" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "BUG! Watchdog %p posiada pusty callback\n" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "BUG! Watchdog %p posiada zerowy interwał\n" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "BUG! unregister_watchdog_unlocked wywołane przed start_watchdog\n" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "nieudane rwl_writelock. ERR=%s\n" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "nieudane rwl_writeunlock. ERR=%s\n" #: src/lib/plugins.c:144 #, fuzzy, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "nieudane fopen %s: ERR=%s\n" #: src/lib/plugins.c:159 #, fuzzy, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/lib/plugins.c:171 #, fuzzy, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/lib/plugins.c:274 #, fuzzy, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, fuzzy, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Nie można skompilowa wzorca regex \"%s\" ERR=%s\n" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "Brak pamięci: ERR=%s\n" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "Przepełnienie bufora.\n" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "Zły errno" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "Memset dla %d bajtów przy %s:%d\n" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "Nie można otworzyć pliku pid. %s ERR=%s\n" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" "%s jest już uruchomiony. pid=%d\n" "Sprawdź plik %s\n" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "Nie można otworzyć pliku pid. %s ERR=%s\n" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "Nie można stworzyć pliku stanu. %s ERR=%s\n" #: src/lib/bsys.c:692 #, fuzzy, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "Błąd zapisu . ERR=%s\n" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "Nie można zniszczyć kolejki klienta: ERR=%s\n" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "Nie można zainicjować kolejki klienta: ERR=%s\n" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "Nie można dodać zadania do kolejki klienta: ERR=%s\n" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 #, fuzzy msgid "No error" msgstr " (%d bd)" #: src/lib/crypto.c:176 #, fuzzy msgid "Signer not found" msgstr "Nie znaleziono wskanika zadania." #: src/lib/crypto.c:178 #, fuzzy msgid "Recipient not found" msgstr "Nie znaleziono wskanika zadania." #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "" #: src/lib/crypto.c:182 #, fuzzy msgid "Unsupported encryption algorithm" msgstr "Zignorowano %d nie wspieranych strumieni kryptograficznych.\n" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 #, fuzzy msgid "Decryption error" msgstr "Błąd odszyfrowywania\n" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 #, fuzzy msgid "Unknown error" msgstr "Błąd szyfrowania\n" #: src/lib/attr.c:72 #, fuzzy, c-format msgid "Error scanning attributes: %s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 #, fuzzy msgid "Selection item too large.\n" msgstr "Komentarz za długi.\n" #: src/lib/sellist.c:160 #, fuzzy msgid "No input string given.\n" msgstr "Brak definicji zasobu Messages w %s\n" #: src/lib/crypto_gnutls.c:243 #, fuzzy, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "Nie mogę zainicjować muteksa: ERR=%s\n" #: src/lib/ini.c:262 src/lib/ini.c:274 #, fuzzy, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Błąd konfiguracji: %s\n" " : Linia %d, kolumna %d w pliku %s\n" "%s\n" "%s" #: src/lib/ini.c:312 src/lib/ini.c:324 #, fuzzy, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Błąd konfiguracji: %s\n" " : Linia %d, kolumna %d w pliku %s\n" "%s\n" "%s" #: src/lib/ini.c:560 src/lib/ini.c:672 #, fuzzy, c-format msgid "Cannot open config file %s: %s\n" msgstr "Nie można otworzyć pliku %s: ERR=%s\n" #: src/lib/edit.c:490 #, fuzzy msgid "Empty name not allowed.\n" msgstr "Etykieta EOM nie została skopiowana.\n" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "Nieprawidłowy znak \"%c\" w nazwie.\n" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "Nazwa za długa.\n" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, fuzzy, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "Nie mogę otworzyć przestrzeni xattr na pliku \"%s\": ERR=%s\n" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, fuzzy, c-format msgid "Error loading CA certificates from %s\n" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, fuzzy, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_gnutls.c:201 #, fuzzy, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_gnutls.c:216 #, fuzzy, c-format msgid "Failed to load DH file %s\n" msgstr "Za komenda level: %s\n" #: src/lib/tls_gnutls.c:224 #, fuzzy msgid "Failed to generate new DH parameters\n" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/lib/tls_gnutls.c:289 #, fuzzy, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "nieudane cap_set_proc: ERR=%s\n" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, fuzzy, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "nieudane rwl_writelock przy %s:%d: ERR=%s\n" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "nieudane rwl_writeunlock przy %s:%d:. ERR=%s\n" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, fuzzy, c-format msgid "expected an =, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:266 #, fuzzy, c-format msgid "Unknown item code: %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/lib/res.c:307 #, fuzzy, c-format msgid "message type: %s not found" msgstr "Fileset \"%s\" nie znaleziony.\n" #: src/lib/res.c:348 #, fuzzy, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" "Próba definicji kolejnego zasobu %s nazwanego \"%s\" nie jest dozwolone.\n" #: src/lib/res.c:520 #, fuzzy, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" "Próba definicji kolejnego zasobu %s nazwanego \"%s\" nie jest dozwolone.\n" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, fuzzy, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "Nie można stworzyć skrt.\n" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:824 #, fuzzy, c-format msgid "expected a size number, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:830 #, fuzzy, c-format msgid "expected a speed number, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:835 #, fuzzy msgid "unknown unit type encountered" msgstr "Nieznany typ pliku %d; nie odtworzono: %s\n" #: src/lib/res.c:853 #, fuzzy, c-format msgid "expected a %s, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:854 #, fuzzy msgid "size" msgstr "Rozmiar" #: src/lib/res.c:854 #, fuzzy msgid "speed" msgstr "Użytkownik" #: src/lib/res.c:998 #, fuzzy, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/lib/res.c:1056 src/lib/res.c:1085 #, fuzzy, c-format msgid "Expected a block begin { , got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, fuzzy, c-format msgid "Expected a string, got: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/res.c:1072 #, fuzzy, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/res.c:1076 #, fuzzy, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/res.c:1081 src/lib/res.c:1111 #, fuzzy, c-format msgid "Expected a equal =, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:1092 src/lib/res.c:1107 #, fuzzy, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "" #: src/lib/res.c:1117 #, fuzzy, c-format msgid "Expected a number or a string, got: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/res.c:1123 src/lib/res.c:1158 #, fuzzy, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, fuzzy, c-format msgid "Expected a end of block }, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "" #: src/lib/res.c:1175 #, fuzzy, c-format msgid "Expected a port number or string, got: %s" msgstr "Oczekiwano ciągu znaków regex, otrzymano: %s\n" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "rwl_writeunlock wywołany zbyt wiele razy.\n" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "Stwórz wątek" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "Dołącz wątek" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, fuzzy, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "Nie można zainicjować kolejki zada: ERR=%s\n" #: src/lib/bsock.c:139 #, fuzzy msgid "attr spool I/O error.\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/lib/bsock.c:276 #, fuzzy, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "Brak autoryzacji dla Zadania \"%s\"\n" #: src/lib/bsock.c:285 #, fuzzy, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" "Problem autoryzacji: Zdalny serwer nie zadeklarował wymaganego wsparcia dla " "TLS.\n" #: src/lib/bsock.c:295 #, fuzzy, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "Problem autoryzacji: Zdalny serwer wymaga TLS.\n" #: src/lib/bsock.c:311 #, fuzzy, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "Negocjacje TLS nie powiody si\n" #: src/lib/bsock.c:321 #, fuzzy, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "Za odpowiedź na komend Hello: ERR=%s\n" #: src/lib/bsock.c:330 #, fuzzy, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "Director odrzuci komend Hello\n" #: src/lib/bsock.c:341 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" #: src/lib/bsock_tcp.c:127 #, fuzzy, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/lib/bsock_tcp.c:133 #, fuzzy, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "Nie mogę otworzyć xattr %s na \"%s\": ERR=%s\n" #: src/lib/bsock_tcp.c:186 #, fuzzy, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "Błąd w acltostr na pliku \"%s\": ERR=%s\n" #: src/lib/bsock_tcp.c:254 #, fuzzy, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/lib/bsock_tcp.c:269 #, fuzzy, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/lib/bsock_tcp.c:292 #, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, fuzzy, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "Błąd w wysyaniu Hello do demona Plików. ERR=%s\n" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, fuzzy, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/lib/bsock_tcp.c:632 #, fuzzy msgid "Could not malloc BSOCK data buffer\n" msgstr "Nie można otworzyć bazy danych katalogu \"%s\".\n" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, fuzzy, c-format msgid "sockopt error: %s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, fuzzy, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, fuzzy, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "Przesunicie do %s na: %s: ERR=%s\n" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "Błąd zapisywania spool attr. ERR=%s\n" #: src/lib/devlock.c:322 #, fuzzy msgid "writeunlock called too many times.\n" msgstr "rwl_writeunlock wywołany zbyt wiele razy.\n" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Błąd pliku inicjalizacyjnego: %s\n" " : Linia %d, kolumna %d w pliku %s\n" "%s\n" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, fuzzy, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" "Błąd pliku inicjalizacyjnego: %s\n" " : Linia %d, kolumna %d w pliku %s\n" "%s\n" #: src/lib/parse_bsr.c:213 #, fuzzy, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "Nie można otworzyć pliku bootstrap %s: ERR=%s\n" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "MediaType %s w bsr jest w niewłaściwym miejscu.\n" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "Urządzenie \"%s\" w bsr jest w niewłaściwym miejscu.\n" #: src/lib/parse_bsr.c:542 #, fuzzy, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "Błąd kompilacji REGEX %s. ERR=%s\n" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "JobType jeszcze nie zaimplementowany\n" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "JobLevel jeszcze nie zaimplementowany\n" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "Slot %d w bsr na nieprawidłowym miejscu.\n" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "VolFile : %u-%u\n" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "VolBlock : %u-%u\n" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "VolAddr : %llu-%llu\n" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "FileIndex : %u\n" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "FileIndex : %u-%u\n" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "JobId : %u\n" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "JobId : %u-%u\n" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "SessId : %u\n" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "SessId : %u-%u\n" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "VolumeName : %s\n" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr " MediaType : %s\n" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr " Urządzenie : %s\n" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr " Slot : %d\n" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "Klient : %s\n" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "Job : %s\n" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "SessTime : %u\n" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "BSR is NULL\n" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "Next : 0x%x\n" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "Root bsr : 0x%x\n" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "zliczone : %u\n" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "znaleziono : %u\n" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "wykonane : %s\n" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "pozycjonowanie : %d\n" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "fast_reject : %d\n" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "Nie można wykonać fork aby stać się demonem: ERR=%s\n" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "1999 Nieudana autoryzacja.\n" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "wywołano stop_btimer z btimer_id równym NULL\n" #: src/lib/parse_conf.c:141 #, fuzzy, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "Nie można zainicjalizowa blokady BD. ERR=%s\n" #: src/lib/parse_conf.c:149 #, fuzzy msgid "Config filename too long.\n" msgstr "Komentarz za długi.\n" #: src/lib/parse_conf.c:181 #, fuzzy, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "Nie można otworzyć pliku %s: ERR=%s\n" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, fuzzy, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/parse_conf.c:220 #, fuzzy, c-format msgid "expected resource name, got: %s" msgstr "Oczekiwano nazwy pliku, otrzymano: %s" #: src/lib/parse_conf.c:231 #, fuzzy, c-format msgid "not in resource definition: %s" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 #, fuzzy msgid "Name not specified for resource" msgstr "Nie można znale zasobu Director %s\n" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "" #: src/lib/parse_conf.c:306 #, fuzzy, c-format msgid "Unknown parser state %d\n" msgstr "Nieznany rodzaj zasobu %d\n" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "" #: src/lib/mem_pool.c:199 #, fuzzy msgid "obuf is NULL\n" msgstr "BSR is NULL\n" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "Brak" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "Zlib errno" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "Błąd strumienia Zlib" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "Błąd danych Zlib" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "Błąd pamici Zlib" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "Błąd bufora Zlib" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "Błąd wersji Zlib" #: src/lib/compression.c:88 #, fuzzy msgid "GZIP compression not supported on this platform\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/lib/compression.c:91 #, fuzzy msgid "LZO2 compression not supported on this platform\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/lib/compression.c:94 #, fuzzy msgid "LZFZ compression not supported on this platform\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/lib/compression.c:97 #, fuzzy msgid "LZ4 compression not supported on this platform\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/lib/compression.c:100 #, fuzzy msgid "LZ4HC compression not supported on this platform\n" msgstr "Strumie %s nie jest wspierany na tym Kliencie.\n" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 #, fuzzy msgid "Failed to initialize ZLIB compression\n" msgstr "Błąd inicjalizacji kontekstu szyfrowania.\n" #: src/lib/compression.c:215 #, fuzzy msgid "Failed to initialize LZO compression\n" msgstr "Błąd inicjalizacji kontekstu szyfrowania.\n" #: src/lib/compression.c:270 #, fuzzy msgid "Failed to initialize FASTLZ compression\n" msgstr "Błąd inicjalizacji kontekstu szyfrowania.\n" #: src/lib/compression.c:300 #, fuzzy msgid "LZO init failed\n" msgstr "Negocjacja TLS nie powiodła się\n" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "Błąd kompresji w deflate: %d\n" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "Błąd kompresji w deflateReset: %d\n" #: src/lib/compression.c:371 #, fuzzy, c-format msgid "Compression LZO error: %d\n" msgstr "Błąd kompresji w deflate: %d\n" #: src/lib/compression.c:402 #, fuzzy, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "Błąd kompresji w deflate: %d\n" #: src/lib/compression.c:413 #, fuzzy, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "Błąd kompresji w deflateReset: %d\n" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "Błąd dekompresji na pliku %s. ERR=%s\n" #: src/lib/compression.c:592 #, fuzzy, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "Błąd dekompresji na pliku %s. ERR=%s\n" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 #, fuzzy msgid "Compressed data stream found, but compression not configured!\n" msgstr "Napotkano strumie GZIP, lecz GZIP nie jest skonfigurowany!\n" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 #, fuzzy msgid "Error initializing SSL context" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 #, fuzzy msgid "Error loading revocation list file" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_openssl.c:483 #, fuzzy msgid "Error loading certificate file" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "" #: src/lib/tls_openssl.c:503 #, fuzzy msgid "Unable to open DH parameters file" msgstr "Nie mogę otworzyć xattr %s na pliku \"%s\": ERR=%s\n" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 #, fuzzy msgid "Error creating file descriptor-based BIO" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 #, fuzzy msgid "Connect failure" msgstr "Utworzone" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 #, fuzzy msgid "TLS shutdown failure." msgstr "Negocjacja TLS nieudana.\n" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 #, fuzzy msgid "Running" msgstr "" "\n" "Uruchomione Zadania:\n" #: src/lib/util.c:214 #, fuzzy msgid "Blocked" msgstr "Odczyt zapisanego bloku" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 #, fuzzy msgid "Fatal Error" msgstr "Bd" #: src/lib/util.c:229 #, fuzzy msgid "Non-fatal error" msgstr "Błąd danych Zlib" #: src/lib/util.c:235 src/lib/util.c:366 #, fuzzy msgid "Canceled" msgstr "Anulowane" #: src/lib/util.c:238 #, fuzzy msgid "Verify differences" msgstr "Rnice przy weryfikacji" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "" #: src/lib/util.c:250 #, fuzzy msgid "Waiting for mount" msgstr "Status zadania: Oczekiwanie na Zamontowanie" #: src/lib/util.c:253 #, fuzzy msgid "Waiting for Storage resource" msgstr "Status zadania: Oczekiwanie na zasoby przechowywania" #: src/lib/util.c:256 #, fuzzy msgid "Waiting for Job resource" msgstr "Status zadania: Oczekiwanie na zasoby zadania" #: src/lib/util.c:259 #, fuzzy msgid "Waiting for Client resource" msgstr "Status zadania: Oczekiwanie na zasoby Klienta" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 #, fuzzy msgid "Waiting for Start Time" msgstr "Status zadania: Oczekiwanie na czas startu" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, fuzzy, c-format msgid "Unknown Job termination status=%d" msgstr "Nieznany status zadania %c." #: src/lib/util.c:302 #, fuzzy msgid "Completed successfully" msgstr "Odtwarzanie wykonane poprawnie." #: src/lib/util.c:305 #, fuzzy msgid "Completed with warnings" msgstr "Przywracanie OK -- z ostrzeżeniami" #: src/lib/util.c:308 #, fuzzy msgid "Terminated with errors" msgstr "Status zadania: Zakoczone przez bd" #: src/lib/util.c:311 #, fuzzy msgid "Fatal error" msgstr "Błąd danych Zlib" #: src/lib/util.c:314 #, fuzzy msgid "Created, not yet running" msgstr "Zadanie odtwarzania stworzone, lecz jeszcze nie uruchomione." #: src/lib/util.c:317 #, fuzzy msgid "Canceled by user" msgstr "Odtwarzanie Anulowane" #: src/lib/util.c:320 #, fuzzy msgid "Verify found differences" msgstr "Rnice przy weryfikacji" #: src/lib/util.c:323 #, fuzzy msgid "Waiting for File daemon" msgstr "Status zadania: Oczekiwanie na demon Plików" #: src/lib/util.c:326 #, fuzzy msgid "Waiting for Storage daemon" msgstr "Status zadania: Oczekiwanie na demon Przechowywania" #: src/lib/util.c:329 #, fuzzy msgid "Waiting for higher priority jobs" msgstr "Status zadania: Oczekiwanie na zakoczenie zada o wyszym priorytecie" #: src/lib/util.c:332 #, fuzzy msgid "Batch inserting file records" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/lib/util.c:369 #, fuzzy msgid "Differences" msgstr "Rnice przy weryfikacji" #: src/lib/util.c:372 #, fuzzy msgid "Unknown term code" msgstr "Nieznany rodzaj zasobu %d\n" #: src/lib/util.c:391 #, fuzzy msgid "Migrated Job" msgstr "" "\n" "Zakoczonych Zada:\n" #: src/lib/util.c:394 #, fuzzy msgid "Verify" msgstr "Weryfikacja OK" #: src/lib/util.c:397 #, fuzzy msgid "Restore" msgstr "Odtwarzanie Anulowane" #: src/lib/util.c:400 #, fuzzy msgid "Console" msgstr "Zamknij" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "" #: src/lib/util.c:412 msgid "Job Copy" msgstr "" #: src/lib/util.c:415 msgid "Copy" msgstr "" #: src/lib/util.c:418 msgid "Migrate" msgstr "" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 #, fuzzy msgid "Unknown Type" msgstr "Nieznany status." #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 #, fuzzy msgid "Verify Init Catalog" msgstr "Weryfikacja Katalogu" #: src/lib/util.c:479 #, fuzzy msgid "Verify Data" msgstr "Weryfikacja Katalogu" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 #, fuzzy msgid "Append" msgstr "Wysłano" #: src/lib/util.c:500 msgid "Disabled" msgstr "" #: src/lib/util.c:502 #, fuzzy msgid "Used" msgstr "Użytkownik" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 msgid "Recycle" msgstr "" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 #, fuzzy msgid "Invalid volume status" msgstr "Status używanego Wolumenu:\n" #: src/lib/util.c:904 #, fuzzy msgid "Working directory not defined. Cannot continue.\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/lib/util.c:907 #, fuzzy, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/lib/util.c:911 #, fuzzy, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "Niepoprawny numer sygnału" #: src/lib/signal.c:152 src/lib/signal.c:154 #, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "Kaboom! exepath=%s\n" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "Błąd funkcji Fork: ERR=%s\n" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "Wywoanie: %s %s %s %s\n" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "nieudane execv: %s: ERR=%s\n" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "NIEZNANY SYGNAŁ" #: src/lib/signal.c:323 msgid "Hangup" msgstr "Zawieszenie" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "Przerwanie" #: src/lib/signal.c:325 msgid "Quit" msgstr "wyjdź" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "Niepoprawna instrukcja" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "Porzuć" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "" #: src/lib/signal.c:335 msgid "BUS error" msgstr "Błąd szyny (Bus error)" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "Kill, nieblokowane" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "Naruszenie segmentacji" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "" #: src/lib/signal.c:343 msgid "Termination" msgstr "Zakończenie" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "Kontynuacja" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "Stop, nieblokowane" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 #, fuzzy msgid "Status OK\n" msgstr "Status:\n" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "Brak pamięci\n" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "Użyto zbyt dużo pamięci." #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "Próba zwolnienia pustego wskaźnika, wywołanie z %s:%d\n" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "podwójne zwolnienie wskaźnika z %s:%d\n" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "qp->qnext->qprev != qp wywołanie z %s:%d\n" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" "\n" "Znaleziono zepsuty bufor przy %s:%d\n" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, fuzzy, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "Nie można stworzyć %s: ERR=%s\n" #: src/lib/scsi_lli.c:92 #, fuzzy, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "Nie mogę odczyta linku symbolicznego %s na \"%s\": ERR=%s\n" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, fuzzy, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, fuzzy, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/scsi_lli.c:314 #, fuzzy, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/scsi_lli.c:323 #, fuzzy, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "Nieudana alokacja nowego obiektu pary kluczy.\n" #: src/lib/scsi_lli.c:348 #, fuzzy, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/scsi_lli.c:464 #, fuzzy, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 #, fuzzy msgid "Program killed by BAREOS (timeout)\n" msgstr "Program zabity przez Bareos (brak czasu)\n" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "Błąd blokowania muteksa. ERR=%s\n" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "Błąd odblokowania muteksa. ERR=%s\n" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "nieudane pthread_create: ERR=%s\n" #: src/lib/crypto_openssl.c:364 #, fuzzy msgid "Unable to open certificate file" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/lib/crypto_openssl.c:371 #, fuzzy msgid "Unable to read certificate from file" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 #, fuzzy msgid "Unable to open private key file" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 #, fuzzy msgid "Unable to read private key from file" msgstr "Proszę popraw plik konfiguracyjny: %s\n" #: src/lib/crypto_openssl.c:551 #, fuzzy, c-format msgid "Unsupported digest type: %d\n" msgstr "Niezaimplementowany poziom weryfikacji %d\n" #: src/lib/crypto_openssl.c:565 #, fuzzy msgid "OpenSSL digest initialization failed" msgstr "Inicjalizacja skrtu %s nieudana\n" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 #, fuzzy msgid "OpenSSL digest finalize failed" msgstr "Inicjalizacja skrtu %s nieudana\n" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "" #: src/lib/crypto_openssl.c:749 #, fuzzy msgid "No signers found for crypto verify.\n" msgstr "Błąd wersji Zlib" #: src/lib/crypto_openssl.c:810 #, fuzzy msgid "Signature creation failed" msgstr "Nieudana walidacja sygnatury dla %s: %s\n" #: src/lib/crypto_openssl.c:888 #, fuzzy msgid "Signature decoding failed" msgstr "Nieudana walidacja sygnatury dla %s: %s\n" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 #, fuzzy msgid "Failure decrypting the session key" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 #, fuzzy msgid "OpenSSL cipher context initialization failed" msgstr "Inicjalizacja skrtu %s nieudana\n" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 #, fuzzy msgid "Encryption session provided an invalid IV" msgstr "zakodowane dane sesji" #: src/lib/crypto_openssl.c:1291 #, fuzzy msgid "OpenSSL cipher context key/IV initialization failed" msgstr "Inicjalizacja skrtu %s nieudana\n" #: src/lib/crypto_openssl.c:1371 #, fuzzy, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "Nie mogę zniszczyć muteksa: ERR=%s\n" #: src/lib/crypto_openssl.c:1615 #, fuzzy, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "Nie mogę zniszczyć muteksa: ERR=%s\n" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" "Rozmiar danych lub strumienia w %s nie jest poprawny. Oryginalny %s, " "odzyskany %s.\n" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "Niepoprawna dugo pola Finder Info (otrzymano %d, a nie 32)\n" #: src/filed/restore.c:132 #, c-format msgid "Could not set Finder Info on %s\n" msgstr "Nie można ustawi pola Finder Info na %s\n" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "Błąd skanowania nagwka rekordu: %s\n" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "Błąd rekordu danych. ERR=%s\n" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "Aktualny rozmiar danych %d nie jest taki sam jak w nagwku %d\n" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "Niespodziewany stumie danych sesji kryptograficznej.\n" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" "Nie zdefiniowano prywatnych kluczy szyfrowania aby odszyfrowa dane " "backupowe.\n" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "Nie można stworzyć skrt.\n" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" "Brakujcy klucz prywatny wymagany do odszyfrowania zaszyfrowanych danych " "backupowych.\n" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "Nieudane odszyfrowanie klucza sesji.\n" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" "Wystpi bd w trakcie dekodowania zaszyfrowanej sesji strumienia danych: %s\n" #: src/filed/restore.c:861 #, c-format msgid "Cannot open resource fork for %s.\n" msgstr "Nie można otworzyć rozwidlenia zasobów.dla %s.\n" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "Niespodziewany strumie danych podpisu kryptograficznego.\n" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "Nieudane dekodowanie podpisu komunikatu dla %s\n" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "Osiągnięto %ld błędów acl w trakcie wykonywania odtwarzania\n" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "Osiągnięto %ld błędów xattr w trakcie wykonywania odtwarzania\n" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" "Zignorowano %d nie wspieranych strumieni danych i %d nie wspieranych " "strumieni atrybutw.\n" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "Zignorowano %d nie wspieranych strumieni rozwidlenia zasobów.\n" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "Zignorowano %d nie wspieranych strumieni Finder Info.\n" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "Zignorowano %d nie wspieranych strumieni acl.\n" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "Zignorowano %d nie wspieranych strumieni kryptograficznych.\n" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "Zignorowano %d nie wspieranych strumieni xattr.\n" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "Błąd zapisu w Dekompozycji Bloku Win32 na %s: %s\n" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "Błąd logiki: plik wyjściowy powinien być otwarty\n" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "Błąd logiki: plik wyjściowy nie powinien być otwarty\n" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "Nie można alokowa %d buforw odczytu sieci\n" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr " Brak dostpu %s: ERR=%s\n" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr " Nie można poda za linkiem %s: ERR=%s\n" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr " Nie można wykona stat %s: ERR=%s\n" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr " Pominity nie zmieniony plik: %s\n" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr " Ominito archiwalny plik: %s\n" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr " Rekursja wyczona. Ominito katalog: %s\n" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr " Zabroniona zmiana filesystemu. Ominito katalog: %s\n" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr " Nie można otworzyć katalogu %s: ERR=%s\n" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr " Nieznany rodziaj pliku %d: %s\n" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "Błąd sieci w wysyaniu do Directora: ERR=%s\n" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "Inicjalizacja skrtu %s nieudana\n" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr " Nie można otworzyć %s: ERR=%s.\n" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr " Nie można otworzyć rozwidlenia zasobu dla %s: ERR=%s.\n" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "Błąd odczytywania pliku %s: ERR=%s\n" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, fuzzy, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "Wtyczka komend \"%s\" zwrcia zy pakiet startBackupFile.\n" #: src/filed/fd_plugins.c:633 #, fuzzy, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "Wtyczka komend \"%s\" zwrcia zy pakiet startBackupFile.\n" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, fuzzy, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "Wtyczka komend \"%s\" zwrcia zy pakiet startBackupFile.\n" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "Nie znaleziono pakietu zapisu wtyczki.\n" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "Wtyczka=%s nie znaleziona.\n" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "Nieudanie wywoanie createFile wtyczki. Stat=%d file=%s\n" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "Nieudanie wywoanie createFile wtyczki. Zwrcono CF_ERROR plik=%s\n" #: src/filed/fd_plugins.c:2378 #, fuzzy msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "Wtyczka komend \"%s\" zwrcia zy pakiet startBackupFile.\n" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "Komenda Storage nie zostaa wysana przed komend Verify.\n" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "Błąd skanowania nagwna rekordu: %s\n" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "Wystpi bd w trakcie szyfrowania strumienia.\n" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "Brakucy podpis kryptograficzny dla %s\n" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "Nieudana walidacja podpisu dla pliku %s: ERR=%s\n" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "Nieudany skrót jednego pliku dla pliku: %s\n" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "Nieudana walidacja sygnatury dla %s: %s\n" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "Błąd odszyfrowywania. buf_len=%d decrypt_len=%d na pliku %s\n" #: src/filed/crypto.c:401 #, fuzzy msgid "Encrypting sparse or offset data not supported.\n" msgstr "Szyfrowanie rzadkich danych nie jest wspierane.\n" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "Błąd inicjalizacji kontekstu szyfrowania.\n" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "Brakujca szyfrowana sesja strumienia danych dla %s\n" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "Nieudana inicjalizacja kontekstu odszyfrowywania dla %s\n" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "Błąd szyfrowania\n" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "Błąd odszyfrowywania\n" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "2001 Zadanie %s oznaczone do anulowania.\n" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "2902 Błąd skanowania komendy anuluj.\n" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "2991 Bdna komenda setdebug: %s\n" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "2992 Bdna komenda estimate.\n" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "Bdna komenda estimate: %s" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "Bdna komenda Job: %s" #: src/filed/dir_cmd.c:870 #, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "Bdna komenda RunBeforeJob: %s\n" #: src/filed/dir_cmd.c:933 #, c-format msgid "Bad RunAfter command: %s\n" msgstr "Bdna komenda RunAfter: %s\n" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "Bdna komenda RunScript: %s\n" #: src/filed/dir_cmd.c:1015 #, fuzzy, c-format msgid "Bad Plugin Options command: %s\n" msgstr "Bdna komenda RunScript: %s\n" #: src/filed/dir_cmd.c:1066 #, fuzzy, c-format msgid "Bad RestoreObject command: %s\n" msgstr "Za komenda storage: %s" #: src/filed/dir_cmd.c:1166 #, fuzzy msgid "2909 Bad RestoreObject command.\n" msgstr "2905 Bdna komenda RunBeforeJob.\n" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" "Zegary DIR i FD rni się o %lld sekund, automatyczne kompensowanie FD.\n" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "Nieznany poziom backupu: %s\n" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "Za komenda level: %s\n" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "Za komenda session: %s" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "Za komenda storage: %s" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "Nie można skontaktowa się z demonem Skadowania\n" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "Za odpowiedź na append open: %s\n" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "Za odpowiedź z demona skadowania na komend open\n" #: src/filed/dir_cmd.c:1691 #, fuzzy, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "Generowanie migawki VSS. Sterownik=\"%s\", Dysk(i)=\"%s\"\n" #: src/filed/dir_cmd.c:1696 #, fuzzy, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "Nieudane generowanie migawki VSS.\n" #: src/filed/dir_cmd.c:1708 #, fuzzy, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "Nieudane generowanie migawki VSS.\n" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "VSS Writer (PrepareForBackup): %s\n" #: src/filed/dir_cmd.c:1723 #, fuzzy msgid "No drive letters found for generating VSS snapshots.\n" msgstr "Nie znaleziono liter dyskw dla generowania migawek VSS.\n" #: src/filed/dir_cmd.c:1728 #, fuzzy, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" "VSS nie zostao poprawnie zainicjowane. Wsparcie dla VSS jest wyczone. ERR=%" "s\n" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "Nieudane Append Close z SD.\n" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "Zwrcono zy status %d z Demona Skadowania.\n" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "2994 Za komenda verify: %s\n" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "2994 Za komenda verify: %s\n" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "Za komenda replace. CMD=%s\n" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "Ze polecenie regexp where. where=%s\n" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" "VSS nie zostao poprawnie zainicjowane. Wsparcie dla VSS jest wyczone. ERR=%" "s\n" #: src/filed/dir_cmd.c:2085 #, fuzzy, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "VSS Writer (BackupComplete): %s\n" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "Niepoprawna sekwencja woania.\n" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "Za odpowiedź na SD read open: %s\n" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "Za odpowiedź ze stored na komend read open\n" #: src/filed/filed_conf.c:520 #, fuzzy, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "Oczekiwano ciągu znaków fstype, otrzymano: %s\n" #: src/filed/filed.c:61 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Wersja: %s (%s)\n" "\n" "Użycie: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -c użyj jako pliku konfiguracyjnego\n" " -d ustaw poziom debugingu na \n" " -dt wyświetl znacznik czasu podczas wywietlania debugingu\n" " -f uruchom na pierwszym planie (dla debugingu)\n" " -g identyfikator grupy\n" " -k utrzymaj właściwości readall\n" " -m wyświetl informacje kaboom (dla debugingu)\n" " -s brak sygnałów (dla debugingu)\n" " -t przetestuj plik konfiguracji i zakończ\n" " -u identyfikator użytkownika\n" " -v gadatliwe komunikaty użytkownika\n" " -? wyświetl ten komunikat.\n" "\n" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "opcja -k nie ma znaczenia bez opcji -u.\n" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" "Brak definicji zasobu demona Plików w %s\n" "Bez tego nie wiem kim jestem :-(\n" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "Dozwolony tylko jeden zasób Client w %s\n" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie zostay " "zdefiniowane dla demona Plików w %s.\n" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" "Szyfrowanie/podpisywanie PKI wczone ale nie jest wkompilowane w Bareos.\n" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" "\"PKI Key Pair\" musi by zdefiniowane dla demona Plików \"%s\" w %s jeli ani " "\"PKI Sign\", ani \"PKI Encrypt\" nie zostay wczone.\n" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "Nieudana alokacja nowego obiektu pary kluczy.\n" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" "Nieudane zaadowanie publicznego certyfikatu dla demona Plików \"%s\" w %s.\n" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "Nieudane zaadowanie prywatnego klucza dla demona Plików \"%s\" w %s.\n" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" "Nieudane zaadowanie prywatnego klucza %s dla demona Plików \"%s\" w %s.\n" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" "Nieudane zaadowanie zaufanego certyfikatu osoby podpisujcej z pliku %s dla " "demona Plików \"%s\" w %s.\n" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" "Nieudane zaadowanie certyfikatu gwnego klucza z pliku %s dla demona Plików " "\"%s\" w %s.\n" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "Brak definicji zasobu Dyrektora w %s\n" #: src/filed/accurate_lmdb.c:64 #, fuzzy, c-format msgid "Unable to create MDB environment: %s\n" msgstr "Nie mogę przyci wolumenu \"%s\"\n" #: src/filed/accurate_lmdb.c:81 #, fuzzy, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/filed/accurate_lmdb.c:90 #, fuzzy, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #: src/filed/accurate_lmdb.c:97 #, fuzzy, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "Nie mogę otworzyć Bazy danych=%s. ERR=%s\n" #: src/filed/accurate_lmdb.c:103 #, fuzzy, c-format msgid "Unable to start a write transaction: %s\n" msgstr "Nie mogę pisać do %s\n" #: src/filed/accurate_lmdb.c:109 #, fuzzy, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "Nie mogę otworzyć Bazy danych=%s. ERR=%s\n" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, fuzzy, c-format msgid "Unable insert new data: %s\n" msgstr "Nie mogę pisać do %s\n" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, fuzzy, c-format msgid "Unable close write transaction: %s\n" msgstr "Nie mogę pisać do %s\n" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, fuzzy, c-format msgid "Unable to create write transaction: %s\n" msgstr "Nie mogę pisać do %s\n" #: src/filed/accurate_lmdb.c:249 #, fuzzy, c-format msgid "Unable to create read transaction: %s\n" msgstr "Nie mogę utworzyć wątku. ERR=%s\n" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, fuzzy, c-format msgid "Unable to renew read transaction: %s\n" msgstr "Nie mogę pisać do %s\n" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, fuzzy, c-format msgid "Unable create cursor: %s\n" msgstr "Nie mogę pisać do %s\n" #: src/filed/status.c:87 #, fuzzy, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "Demon wystartowany %s, %d Zada %s uruchomionych od wystartowania.\n" #: src/filed/status.c:149 #, fuzzy, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr " Wielkoci: boffset_t=%d size_t=%d debug=%d trace=%d\n" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "Dyrektor podłączony o: %s\n" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "JobId %d Zadanie %s jest uruchomione.\n" #: src/filed/status.c:188 #, c-format msgid " %s%s %s Job started: %s\n" msgstr " %s%s %s Zadanie wystartowane: %s\n" #: src/filed/status.c:201 #, fuzzy, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr " Zbadanych Plików=%s\n" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr " Przetworzonych plikw: %s\n" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr " SDSocket zamknięto.\n" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "====\n" #: src/filed/status.c:300 #, fuzzy msgid " SDSocket=closed\n" msgstr " SDSocket zamknięto.\n" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "Za komenda .status: %s\n" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "2900 Za komenda .status, brakujcy argument.\n" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "2900 Za komenda .status, niepoprawny argument.\n" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "Klient Bareos: Bezczynny" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "Klient Bareos: Uruchomiony" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "Klient Bareos: Ostatnie Zadanie Anulowane" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "Klient Bareos: Ostatnie Zadanie Nieudane" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "Klient Bareos: Ostatnie Zadanie miao Ostrzeżenia" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "Autentykuj wycznie directory, nie %d\n" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "Połączenie od nieznanego Directora %s przy %s odrzucone.\n" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "Niepoprawne haso podane przez Director przy %s.\n" #: src/filed/authenticate.c:301 #, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "Ilo szczdzonej przestrzeni z Base jobs: %lld MB\n" #: src/filed/accurate.c:261 #, fuzzy, c-format msgid "Cannot verify checksum for %s\n" msgstr "Nie mogę zweryfikowa sum kontroln dla %s\n" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "2991 Za komenda accurate\n" #: src/filed/fileset.c:86 #, fuzzy, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" "Katalog dla Wtyczek nie jest zdefiniowany. Nie można uy wtyczki: \"%\"\n" #: src/filed/fileset.c:128 #, fuzzy, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "Błąd uruchomienia programu: %s. stat=%d: ERR=%s\n" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "Nie można otworzyć pliku wejciowego FileSet: %s. ERR=%s\n" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "Błąd kompilacji REGEX %s. ERR=%s\n" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "Niepoprawna komenda FileSet: %s\n" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "Nie można ustawić wielkości bufora FD->SD.\n" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "Osiągnięto %ld błędów acl w trakcie wykonywania backupów\n" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "Osiągnięto %ld błędów xattr w trakcie wykonywania backupów\n" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr " Nie można otworzyć rozwidlenia zasobu dla \"%s\": ERR=%s.\n" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "Inicjalizacja skrtu podpisu %s nieudana\n" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "Nieudana alokacja pamici dla podpisu kryptograficznego.\n" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "Wystpi bd w trakcie podpisywania strumienia.\n" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "Wystpi bd w trakcie koczenia podpisywania strumienia.\n" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr " Rekursja jest wyłączona. Nie będę zagłębiał się z %s do %s\n" #: src/filed/backup.c:553 #, fuzzy, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" " %s jest na innym systemie plikw. Nie będę zagłębiał się z %s do %s\n" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr " Niedozwolony system plikw. Nie będę zagłębiał się z %s do %s\n" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr " Niedozwolony typ napdu. Nie będę zagłębiał się do %s\n" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr " Pominity plik gniazda: %s\n" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr " Nie można dostać się do: \"%s\": ERR=%s\n" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr " Nie można podążać za dowiązaniem \"%s\": ERR=%s\n" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr " Nie można wykona stat na \"%s\": ERR=%s\n" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr " Nie zapisany plik archiwum: %s\n" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr " Nie można otworzyć katalogu \"%s\": ERR=%s\n" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr " Nieznany typ pliku %d; nie zapisano: %s\n" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr " Nie można otworzyć \"%s\": ERR=%s.\n" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "Błąd odczytu na pliku %s. ERR=%s\n" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "Zbyt duo bdw. JobErrors=%d.\n" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "Błąd wypeniania szyfrowania\n" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "Niepoprawne flagi pliku, nie wspierany typ strumienia danych.\n" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "VSS Writer (BackupComplete): %s\n" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, fuzzy, c-format msgid "Failed ASSERT: %s\n" msgstr "Za komenda level: %s\n" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "Monitor: nazwa=%s FDtimeout=%s SDtimeout=%s\n" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "Dyrektor: nazwa=%s adres=%s FDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "Klient: nazwa=%s adres=%s FDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "Storage: nazwa=%s adres=%s SDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "ConsoleFont: nazwa=%s krj czcionki=%s\n" #: src/qt-tray-monitor/authenticate.cpp:79 #, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "Za odpowiedź na komend Hello: ERR=%s\n" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "Director odrzucił komendę Hello\n" #: src/qt-tray-monitor/authenticate.cpp:139 msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "Napisany przez Nicolas Boichat (2004)\n" "\n" "Wersja: %s (%s) %s %s %s\n" "\n" "Użycie: tray-monitor [-c config_file] [-d debug_level]\n" " -c ustaw plik konfiguracyjny na \n" " -d ustaw poziom debugowania na \n" " -dt wyświetla znaczniki czasowe w debugingu\n" " -t test - odczytuje konfigurację i kończy działanie\n" " -? wyświetla ten komunikat.\n" "\n" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "Podłączony" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "Przetwarzanie komendy ..." #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Wersja: %s (%s) %s %s %s\n" "\n" "Użycie: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c ustaw plik konfiguracyjny na file\n" " -dnn ustaw poziom debugowania na nn\n" " -s brak sygnałów\n" " -t test - odczytuje konfiguracj i kończy działanie\n" " -? wyświetla ten komunikat.\n" "\n" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "Konsola: nazwa=%s\n" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "Już podłączony\"%s\".\n" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "Podłączenie do Dyrektora %s:%d" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" "Podłączenie do Dyrektora %s:%d\n" "\n" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "Inicjalizowanie ..." #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "Zakończona komenda ..." #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "Główne polecenie czeka na dane ..." #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "Polecenie czeka na dane ..." #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "Nieudana komenda." #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "Dyrektor rozłączony." #, fuzzy #~ msgid "@exec error: ERR=%s\n" #~ msgstr "Przesunicie do %s na: %s: ERR=%s\n" #~ msgid "3911 JobId=%u failed reserve drive %s.\n" #~ msgstr "3911 JobId=%u niepowodzenie przy rezerwacji dysku %s.\n" #, fuzzy #~ msgid "Unable to load any shared library for .\n" #~ msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #, fuzzy #~ msgid "Expected a Console Authentication Type keyword, got: %s" #~ msgstr "Niepoprawna komenda FileSet: %s\n" #~ msgid "Device record %s already exists\n" #~ msgstr "Rekord urządzenia %s już istnieje\n" #~ msgid "Bad response to Hello command: ERR=" #~ msgstr "Zła odpowiedź na komend Hello: ERR=" #~ msgid "Record header file index %ld not equal record index %ld\n" #~ msgstr "" #~ "Indeks pliku w nagwku rekordu %ld nie jest rwny indeksowi rekordu %ld\n" #~ msgid "Open File Manager paused\n" #~ msgstr "Open File Manager zatrzymany\n" #~ msgid "FAILED to pause Open File Manager\n" #~ msgstr "NIEUDANE zatrzymanie Open File Manager\n" #~ msgid "Running as '%s'. Privmask=%#08x\n" #~ msgstr "Uruchomiono jako '%s'. Privmask=%#08x\n" #~ msgid "Failed to retrieve current UserName\n" #~ msgstr "Nieudane pobranie aktualnego UserName\n" #~ msgid "2905 Bad RunBeforeNow command.\n" #~ msgstr "2905 Bdna komenda RunBeforeNow.\n" #~ msgid "2905 Bad RunAfterJob command.\n" #~ msgstr "2905 Bdna komenda RunAfterJob.\n" #~ msgid "2905 Bad RunScript command.\n" #~ msgstr "2905 Bdna komenda RunScript.\n" #~ msgid "ACL support not configured for your machine.\n" #~ msgstr "Nie skonfigurowane wsparcie ACL na twojej maszynie.\n" #~ msgid "XATTR support not configured for your machine.\n" #~ msgstr "Nie skonfigurowane wsparcie XATTR na twojej maszynie.\n" #~ msgid "" #~ "Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled " #~ "on this drive.\n" #~ msgstr "" #~ "Nieudane generowanie migawki VSS dysku \"%c:\\\". Wsparcie dla VSS jest " #~ "wyczone dla tego dysku.\n" #~ msgid "Malformed plugin command. Name not terminated by colon: %s\n" #~ msgstr "" #~ "Znieksztacona komenda wtyczki. Nazwa nie zakoczona dwukropkiem: %s\n" #~ msgid "Loaded plugin: %s\n" #~ msgstr "Zaadowana wtyczka: %s\n" #~ msgid "Daemon started %s, %d Job%s run since started.\n" #~ msgstr "Demon wystartowany %s, %d Zada %s uruchomionych od wystartowania.\n" #~ msgid "Job pointer not found." #~ msgstr "Nie znaleziono wskanika zadania." #~ msgid "Attribute %s not found." #~ msgstr "Atrybut %s nie znaleziony." #~ msgid "Cannot delete attribute %s" #~ msgstr "Nie można skasowa atrybutu %s" #~ msgid "Cannot find attribute %s" #~ msgstr "Nie można znale atrybutu %s" #~ msgid "Read-only attribute" #~ msgstr "Atrybut tylko do odczytu" #~ msgid "" #~ "No Client, Storage or Director resource defined in %s\n" #~ "Without that I don't how to get status from the File, Storage or Director " #~ "Daemon :-(\n" #~ msgstr "" #~ "Brak definicji zasobu Klienta, Przechowywania lub Dyrektora w %s\n" #~ "Bez tego nie wiem jak mam otrzyma status z demonów Plików, Przechowywania " #~ "i Dyrektora. :-(\n" #~ msgid "" #~ "Invalid refresh interval defined in %s\n" #~ "This value must be greater or equal to 1 second and less or equal to 10 " #~ "minutes (read value: %d).\n" #~ msgstr "" #~ "Niepoprawny interwa czasu zdefiniowany w %s\n" #~ "Warto ta musi by wiksza lub rwna 1 sekundzie i mniejsza lub rwna 10 " #~ "minutom (odczytana warto: %d).\n" #~ msgid "Bareos daemon status monitor" #~ msgstr "Monitor statusu demona Bareos" #~ msgid "Open status window..." #~ msgstr "Otwrz okno statusu..." #~ msgid "Exit" #~ msgstr "Wyjcie" # Tray to tacka - nie do końca mi to pasuje: "Tackowy Monitor Baculi" #~ msgid "Bareos tray monitor" #~ msgstr "Tackowy monitor Baculi" #~ msgid " (DIR)" #~ msgstr " (DIR)" #~ msgid " (FD)" #~ msgstr " (FD)" #~ msgid " (SD)" #~ msgstr " (SD)" #~ msgid "Refresh interval in seconds: " #~ msgstr "Interwa odwierzania w sekundach: " #~ msgid "Refresh now" #~ msgstr "Odwierz teraz" #~ msgid "About" #~ msgstr "O Programie" #~ msgid "Close" #~ msgstr "Zamknij" #~ msgid "Disconnecting from Director %s:%d\n" #~ msgstr "Rozłączanie od Dyrektora %s:%d\n" #~ msgid "Disconnecting from Client %s:%d\n" #~ msgstr "Rozłączanie od Klienta %s:%d\n" #~ msgid "Disconnecting from Storage %s:%d\n" #~ msgstr "Rozłączanie od Storage %s:%d\n" #~ msgid "Bareos Tray Monitor" #~ msgstr "Monitor programu Bareos" #~ msgid "Written by Nicolas Boichat\n" #~ msgstr "Napisany przez Nicolas Boichat\n" #~ msgid "Version" #~ msgstr "Wersja" #~ msgid "" #~ "Current job: %s\n" #~ "Last job: %s" #~ msgstr "" #~ "Aktualne zadanie: %s\n" #~ "Ostatnie zadanie: %s" #~ msgid " (%d errors)" #~ msgstr " (%d bdw)" #~ msgid " (%d error)" #~ msgstr " (%d bd)" #~ msgid "No current job." #~ msgstr "Brak aktualnego zadania." #~ msgid "No last job." #~ msgstr "Brak ostatniego zadania." #~ msgid "Job status: Created" #~ msgstr "Status zadania: Stworzone" #~ msgid "Job status: Running" #~ msgstr "Status zadania: Uruchomione" #~ msgid "Job status: Blocked" #~ msgstr "Status zadania: Zablokowane" #~ msgid "Job status: Terminated" #~ msgstr "Status zadania: Zakoczone" #~ msgid "Job status: Terminated in error" #~ msgstr "Status zadania: Zakoczone przez bd" #~ msgid "Job status: Error" #~ msgstr "Status zadania: Bd" #~ msgid "Job status: Fatal error" #~ msgstr "Status zadania: Błąd krytyczny" #~ msgid "Job status: Verify differences" #~ msgstr "Status zadania: Rnice przy weryfikacji" #~ msgid "Job status: Canceled" #~ msgstr "Status zadania: Anulowane" #~ msgid "Job status: Waiting on File daemon" #~ msgstr "Status zadania: Oczekiwanie na demon Plików" #~ msgid "Job status: Waiting on the Storage daemon" #~ msgstr "Status zadania: Oczekiwanie na demon Przechowywania" #~ msgid "Job status: Waiting for new media" #~ msgstr "Status zadania: Oczekiwanie na nowe media" #~ msgid "Job status: Waiting for Mount" #~ msgstr "Status zadania: Oczekiwanie na Zamontowanie" #~ msgid "Job status: Waiting for storage resource" #~ msgstr "Status zadania: Oczekiwanie na zasoby przechowywania" #~ msgid "Job status: Waiting for job resource" #~ msgstr "Status zadania: Oczekiwanie na zasoby zadania" #~ msgid "Job status: Waiting for Client resource" #~ msgstr "Status zadania: Oczekiwanie na zasoby Klienta" #~ msgid "Job status: Waiting for maximum jobs" #~ msgstr "Status zadania: Oczekiwanie ze wzgldu na maksymaln ilo zada" #~ msgid "Job status: Waiting for start time" #~ msgstr "Status zadania: Oczekiwanie na czas uruchomienia" #~ msgid "Job status: Waiting for higher priority jobs to finish" #~ msgstr "" #~ "Status zadania: Oczekiwanie na zakoczenie zadań o wyszym priorytecie" #~ msgid "Unknown job status %c." #~ msgstr "Nieznany status zadania %c." #~ msgid "Bad scan : '%s' %d\n" #~ msgstr "Ze skanowanie : '%s' %d\n" #~ msgid "Director daemon" #~ msgstr "Demon Dyrektora" #~ msgid "Connecting to Client %s:%d\n" #~ msgstr "Podłączenie do Klienta %s:%d\n" #~ msgid "Connecting to Client %s:%d" #~ msgstr "Podłączenie do Klienta %s:%d" #~ msgid "Connecting to Storage %s:%d\n" #~ msgstr "Podłączenie do Storage %s:%d\n" #~ msgid "Connecting to Storage %s:%d" #~ msgstr "Podłączenie do Storage %s:%d" #~ msgid "Error, currentitem is not a Client, a Storage or a Director..\n" #~ msgstr "Błąd currentitem nie jest Klientem, Storage ani Dyrektorem..\n" #~ msgid "Cannot connect to daemon.\n" #~ msgstr "Nie można połączyć się do demona.\n" #~ msgid "Cannot connect to daemon." #~ msgstr "Nie można połączyć się do demona." #~ msgid "Authentication error : %s" #~ msgstr "Bad autentykacji : %s" #~ msgid "Opened connection with Director daemon.\n" #~ msgstr "Otwarte poczenie z demonem Dyrektora.\n" #~ msgid "Opened connection with Director daemon." #~ msgstr "Otwarte poczenie z demonem Dyrektora." #~ msgid "Opened connection with File daemon.\n" #~ msgstr "Otwarte poczenie z demonem plikw.\n" #~ msgid "Opened connection with File daemon." #~ msgstr "Otwarte poczenie z demonem plikw." #~ msgid "Opened connection with Storage daemon.\n" #~ msgstr "Otwarte poczenie z demonem Przechowywania.\n" #~ msgid "Opened connection with Storage daemon." #~ msgstr "Otwarte poczenie z demonem Przechowywania." #~ msgid "<< Error: BNET_PROMPT signal received. >>\n" #~ msgstr "<< Błąd: otrzymano sygnał BNET_PROMPT. >>\n" #~ msgid "<< Heartbeat signal received, answered. >>\n" #~ msgstr "<< Otrzymano sygnał Heartbeat, odpowiedziano. >>\n" #~ msgid "<< Unexpected signal received : %s >>\n" #~ msgstr "<< Otrzymano nieoczekiwany sygnał : %s >>\n" #~ msgid "\n" #~ msgstr "\n" #~ msgid "Error : BNET_HARDEOF or BNET_ERROR" #~ msgstr "Błąd : BNET_HARDEOF lub BNET_ERROR" #~ msgid "\n" #~ msgstr "\n" #~ msgid "Error : Connection closed." #~ msgstr "Błąd : Połączenie zamknięte." #~ msgid "MySQL client library must be thread-safe when using BatchMode.\n" #~ msgstr "" #~ "Biblioteka kliencka MySQL powinna by typu thread-safe jesli używamy trybu " #~ "wsadowego (BatchMode).\n" #~ msgid "Pg client library must be thread-safe when using BatchMode.\n" #~ msgstr "" #~ "Biblioteka kliencka Pg powinna by typu thread-safe jesli używamy trybu " #~ "wsadowego (BatchMode).\n" #~ msgid "SQLite3 client library must be thread-safe when using BatchMode.\n" #~ msgstr "" #~ "Biblioteka kliencka SQLite3 powinna by typu thread-safe jesli używamy " #~ "trybu wsadowego (BatchMode).\n" #~ msgid "A dbi driver for DBI must be supplied.\n" #~ msgstr "Sterownik dbi dla trybu DBI musi być podany.\n" #~ msgid "Could not create Python Job Object.\n" #~ msgstr "Nie można stworzyć Obiektu Pythona Zadanie.\n" #~ msgid "Python function \"%s\" not found.\n" #~ msgstr "Funkcja Pythona \"%s\" nie znaleziona.\n" #~ msgid "Unknown Python daemon event %s\n" #~ msgstr "Nieznane zdarzenie demona Pythona %s\n" #~ msgid "Could not create client BSOCK.\n" #~ msgstr "Nie można stworzyć BSOCK klienta.\n" #, fuzzy #~ msgid "Network buffer size %d not multiple of tape block size.\n" #~ msgstr "" #~ "Rozmiar bloku taśmy (%d) nie jest wielokrotnością rozmiaru systemowego (%" #~ "d)\n" #, fuzzy #~ msgid "Plugin load %s failed: ERR=%s\n" #~ msgstr "Nieudana aktualizacja rekordu Media %s: ERR=%s\n" #, fuzzy #~ msgid "Pool record not found." #~ msgstr "Zasób Puli \"%s\" nie znaleziony.\n" #, fuzzy #~ msgid "" #~ "%s %s %s (%s): %s\n" #~ " Build OS: %s %s %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Backup Level: %s%s\n" #~ " Client: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pool: \"%s\" (From %s)\n" #~ " Catalog: \"%s\" (From %s)\n" #~ " Storage: \"%s\" (From %s)\n" #~ " Scheduled time: %s\n" #~ " Start time: %s\n" #~ " End time: %s\n" #~ " Elapsed time: %s\n" #~ " Priority: %d\n" #~ " FD Files Written: %s\n" #~ " SD Files Written: %s\n" #~ " FD Bytes Written: %s (%sB)\n" #~ " SD Bytes Written: %s (%sB)\n" #~ " Rate: %.1f KB/s\n" #~ " Software Compression: %s\n" #~ "%s VSS: %s\n" #~ " Encryption: %s\n" #~ " Accurate: %s\n" #~ " Volume name(s): %s\n" #~ " Volume Session Id: %d\n" #~ " Volume Session Time: %d\n" #~ " Last Volume Bytes: %s (%sB)\n" #~ " Non-fatal FD errors: %d\n" #~ " SD Errors: %d\n" #~ " FD termination status: %s\n" #~ " SD termination status: %s\n" #~ " Termination: %s\n" #~ "\n" #~ msgstr "" #~ "%s %s %s (%s): %s\n" #~ " Build OS: %s %s %s\n" #~ " JobId: %d\n" #~ " Job: %s\n" #~ " Backup Level: Virtual Full\n" #~ " Klient: \"%s\" %s\n" #~ " FileSet: \"%s\" %s\n" #~ " Pula: \"%s\" (From %s)\n" #~ " Katalog: \"%s\" (From %s)\n" #~ " Storage: \"%s\" (From %s)\n" #~ " Zaplanowany czas: %s\n" #~ " Czas rozpoczęcia: %s\n" #~ " Czas zakończenia: %s\n" #~ " Czas trwania: %s\n" #~ " Priorytet: %d\n" #~ " Zapisano Plików SD: %s\n" #~ " Zapisano Bajtów SD: %s (%sB)\n" #~ " Szybkość: %.1f KB/s\n" #~ " Nazwa Wolumenu: %s\n" #~ " Id Sesji Wolumenu: %d\n" #~ " Czas Sesji Wolumenu: %d\n" #~ " Ostatnie bajty Wolum.: %s (%sB)\n" #~ " Błędy SD: %d\n" #~ " Status zakończenia SD: %s\n" #~ " Zakończenie: %s\n" #~ "\n" #, fuzzy #~ msgid "Plugin Options not yet implemented.\n" #~ msgstr "JobType jeszcze nie zaimplementowany\n" #, fuzzy #~ msgid "Bareos " #~ msgstr "Monitor statusu demona Bareos" #, fuzzy #~ msgid "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n" #~ msgstr "Monitor: nazwa=%s FDtimeout=%s SDtimeout=%s\n" #, fuzzy #~ msgid " query_file=%s\n" #~ msgstr " --> Cel=%s\n" #, fuzzy #~ msgid "Console: name=%s SSL=%d\n" #~ msgstr "ConsoleFont: nazwa=%s krj czcionki=%s\n" #, fuzzy #~ msgid "Counter: name=%s min=%d max=%d\n" #~ msgstr "ConsoleFont: nazwa=%s krj czcionki=%s\n" #, fuzzy #~ msgid "Client: name=%s address=%s FDport=%d MaxJobs=%u\n" #~ msgstr "Klient: nazwa=%s adres=%s FDport=%d\n" #, fuzzy #~ msgid " SelectionType=%d\n" #~ msgstr "Nieznany Typ Selekcji %s.\n" #, fuzzy #~ msgid " --> Where=%s\n" #~ msgstr " --> Cel=%s\n" #, fuzzy #~ msgid " --> RegexWhere=%s\n" #~ msgstr " --> Cel=%s\n" #, fuzzy #~ msgid " --> Bootstrap=%s\n" #~ msgstr "Bootstrap:" #, fuzzy #~ msgid " --> WriteBootstrap=%s\n" #~ msgstr " --> Cel=%s\n" #, fuzzy #~ msgid " --> MaxRunTime=%u\n" #~ msgstr " --> Komenda=%s\n" #, fuzzy #~ msgid " --> Base %s\n" #~ msgstr " --> Cel=%s\n" #, fuzzy #~ msgid " --> Run=%s\n" #~ msgstr " --> Komenda=%s\n" #, fuzzy #~ msgid "Schedule: name=%s\n" #~ msgstr "ConsoleFont: nazwa=%s krj czcionki=%s\n" #, fuzzy #~ msgid " --> Run Level=%s\n" #~ msgstr " --> Komenda=%s\n" #, fuzzy #~ msgid " mins=%d\n" #~ msgstr " Zbadanych Plików=%s\n" #, fuzzy #~ msgid "Pool: name=%s PoolType=%s\n" #~ msgstr "ConsoleFont: nazwa=%s krj czcionki=%s\n" #, fuzzy #~ msgid " MigTime=%s MigHiBytes=%s MigLoBytes=%s\n" #~ msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #, fuzzy #~ msgid " Catalog=%s\n" #~ msgstr "Używam Katalogu \"%s\"\n" #, fuzzy #~ msgid "Messages: name=%s\n" #~ msgstr "ConsoleFont: nazwa=%s krj czcionki=%s\n" #, fuzzy #~ msgid " mailcmd=%s\n" #~ msgstr " Zbadanych Plików=%s\n" #, fuzzy #~ msgid " opcmd=%s\n" #~ msgstr " --> Komenda=%s\n" #, fuzzy #~ msgid "Expected one of: %s, got: %s" #~ msgstr "Oczekiwano ciągu znaków fstype, otrzymano: %s\n" #, fuzzy #~ msgid "Enter autochanger drive[0]: " #~ msgstr "przetestuj bibliotekę taśmową" #, fuzzy #~ msgid "Daemon started %s, 1 Job run since started.\n" #~ msgstr "Demon wystartowany %s, %d Zada %s uruchomionych od wystartowania.\n" #~ msgid "Max sched run time exceeded. Job canceled.\n" #~ msgstr "" #~ "Przekroczony maksymalny czas wykonania zaplanowanego zadania. Zadanie " #~ "anulowane.\n" #~ msgid "OSF1 Specific Default ACL attribs" #~ msgstr "Domyślne atrybuty specyficzne ACL dla OSF1" #~ msgid "OSF1 Specific Access ACL attribs" #~ msgstr "Atrybuty specyficzne dostępu ACL dla Irix" #, fuzzy #~ msgid "TLS negotiation failed with FD at \"%s:%d\"\n" #~ msgstr "Negocjacje TLS nie powiody si\n" #~ msgid "btape does not work with DVD storage.\n" #~ msgstr "btape nie działa z nośnikami DVD.\n" #~ msgid "" #~ "Error writing final part to DVD. This Volume may not be readable.\n" #~ "%s" #~ msgstr "" #~ "Błąd podczas zapisu ostatniej części na DVD. Ten Wolumen może nie nadawać " #~ "się do odczytu.\n" #~ "%s" #~ msgid "" #~ "Error while writing, current part number is less than the total number of " #~ "parts (%d/%d, device=%s)\n" #~ msgstr "" #~ "Błąd podczas zapisu, bieżący numer części urzadzenia jest mniejszy " #~ "niżcałkowita ilość części (%d/%d, urządzenie=%s)\n" #, fuzzy #~ msgid "Unable to open device next part %s: ERR=%s\n" #~ msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #~ msgid "" #~ "End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, " #~ "free_space_errno=%d, errmsg=%s).\n" #~ msgstr "" #~ "Koniec Wolumenu \"%s\" dla %u:%u na urzadzeniu %s (part_size=%s, " #~ "free_space=%s, free_space_errno=%d, errmsg=%s).\n" #, fuzzy #~ msgid "Unable to open device part=%d %s: ERR=%s\n" #~ msgstr "Nie mogę otworzyć pliku \"%s\": ERR=%s\n" #, fuzzy #~ msgid "Uncompression error. ERR=%d\n" #~ msgstr "Błąd dekompresji na pliku %s. ERR=%s\n" #~ msgid "part" #~ msgstr "część" #~ msgid "file" #~ msgstr "plik" #, fuzzy #~ msgid "End of %s %u on device %s, Volume \"%s\"\n" #~ msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #, fuzzy #~ msgid "" #~ "Media Type not the same for all devices in changer %s. Cannot continue.\n" #~ msgstr "Brak definicji zasobu Messages w %s\n" #, fuzzy #~ msgid "3991 Bad setdebug command: %s\n" #~ msgstr "2991 Bdna komenda setdebug: %s\n" #, fuzzy #~ msgid "3000 Job %s marked to be canceled.\n" #~ msgstr "2001 Zadanie %s oznaczone do anulowania.\n" #, fuzzy #~ msgid "No FreeSpace command defined.\n" #~ msgstr "Nie zdefiniowano zasobu %s\n" #, fuzzy #~ msgid "Cannot run free space command. Results=%s ERR=%s\n" #~ msgstr "Nie można uruchomi programu: %s. ERR=%s\n" #, fuzzy #~ msgid "Error writing part %d to the DVD: ERR=%s\n" #~ msgstr "Błąd uruchomienia programu: %s. stat=%d: ERR=%s\n" #, fuzzy #~ msgid "Error while writing current part to the DVD: %s" #~ msgstr "Błąd uruchomienia programu: %s. stat=%d: ERR=%s\n" #, fuzzy #~ msgid "" #~ "====\n" #~ "\n" #~ msgstr "====\n" #, fuzzy #~ msgid " Files=%s Bytes=%s Bytes/sec=%s\n" #~ msgstr " Plików=%s Bajtów=%s Bajtów/sek=%s Błędów=%d\n" #~ msgid "3900 Bad .status command, missing argument.\n" #~ msgstr "3900 Zła komenda .status, brakujcy argument.\n" #~ msgid "3900 Bad .status command, wrong argument.\n" #~ msgstr "3900 Za komenda .status, niepoprawny argument.\n" #~ msgid "Error in ParseTuple\n" #~ msgstr "Bład w ParseTuple\n" #, fuzzy #~ msgid "Error in Python method %s\n" #~ msgstr "Błąd uaktualniania rekordu zadania. %s" #, fuzzy #~ msgid "Ready to append to end of Volume \"%s\" part=%d size=%s\n" #~ msgstr "Nieudane stworzenie rekordu JobMedia %s: ERR=%s\n" #, fuzzy #~ msgid "Could not open DVD device %s. No Volume name given.\n" #~ msgstr "Nie można stworzyć skrt.\n" #, fuzzy #~ msgid "Unable to stat DVD part 1 file %s: ERR=%s\n" #~ msgstr "Nie mogę otrzyma statusu na xattr %s na pliku \"%s\": ERR=%s\n" #, fuzzy #~ msgid "Could not mount DVD device %s.\n" #~ msgstr "Nie można stworzyć skrt.\n" #, fuzzy #~ msgid "Could not fstat: %s, ERR=%s\n" #~ msgstr " Nie można wykona stat %s: ERR=%s\n" #~ msgid "Network send error to FD. ERR=%s\n" #~ msgstr "Błąd sieci w wysyaniu do FD. ERR=%s\n" #~ msgid "&About...\tF1" #~ msgstr "&About...\tF1" #~ msgid "Show about dialog" #~ msgstr "Pokaż dialog o" #~ msgid "Connect" #~ msgstr "Połącz" #~ msgid "Connect to the director" #~ msgstr "Połącz do Dyrektora" #~ msgid "Disconnect" #~ msgstr "Rozłącz" #~ msgid "Disconnect of the director" #~ msgstr "Rozłączanie dyrektora" #~ msgid "Change of configuration file" #~ msgstr "Zmiana pliku konfiguracyjnego" #~ msgid "Change your default configuration file" #~ msgstr "Zmień swój domyślny plik konfiguracyjny" #~ msgid "Edit your configuration file" #~ msgstr "Wyedytuj swój plik konfiguracyjny" #~ msgid "E&xit\tAlt-X" #~ msgstr "&Wyjście\tAlt-X" #~ msgid "Quit this program" #~ msgstr "Zamknij ten program" #~ msgid "&File" #~ msgstr "&Pliki" #~ msgid "&Help" #~ msgstr "&Pomoc" #~ msgid "Welcome to bareos bwx-console %s (%s)!\n" #~ msgstr "Witamy w konsoli baculi bwx-console %s (%s)!\n" #~ msgid "" #~ "Warning : Unicode is disabled because you are using wxWidgets for GTK+ " #~ "1.2.\n" #~ msgstr "" #~ "Ostrzeżenie : Unicode jest wyłączony ponieważ używane jest wxWidgets dla " #~ "GTK+ 1.2.\n" #~ msgid "Type your command below:" #~ msgstr "Napisz swoje polecenie poniżej:" #~ msgid "Send" #~ msgstr "Wysłano" #~ msgid "Error while parsing command line arguments, using defaults.\n" #~ msgstr "" #~ "Błąd podczas parsowania argumentów lini komend, używam domyślnych.\n" #~ msgid "Usage: bwx-console [-c configfile] [-w tmp]\n" #~ msgstr "Użycie: bwx-console [-c configfile] [-w tmp]\n" #~ msgid "" #~ "It seems that it is the first time you run bwx-console.\n" #~ "This file (%s) has been choosen as default configuration file.\n" #~ "Do you want to edit it? (if you click No you will have to select another " #~ "file)" #~ msgstr "" #~ "wydaje się że to twoje pierwsze uruchomienie konsoli bwx.\n" #~ "Ten plik (%s) został wybrany jako domyślny plik konfiguracyjny.\n" #~ "Czy chcesz go edytować? (jeśli wybierzesz 'No' będziesz musiał wybrać " #~ "inny plik)" #~ msgid "First run" #~ msgstr "Pierwsze uruchomienie" #~ msgid "" #~ "Unable to read %s\n" #~ "Error: %s\n" #~ "Do you want to choose another one? (Press no to edit this file)" #~ msgstr "" #~ "Nie można odczytać %s\n" #~ "Błąd: %s\n" #~ "Czy chcesz wybrać inny? (Wybierz 'no' by edytowac ten plik)" #~ msgid "Unable to read configuration file" #~ msgstr "Nie można odczytać pliku konfiguracyjnego" #~ msgid "Please choose a configuration file to use" #~ msgstr "Proszę wybierz używany plik konfiguracyjny" #~ msgid "" #~ "This configuration file has been successfully read, use it as default?" #~ msgstr "" #~ "Ten plik konfiguracyjny został z powodzeniem odczytany, czy użyć go jako " #~ "domyślny?" #~ msgid "Configuration file read successfully" #~ msgstr "Plik konfiguracyjny odczytany z powodzeniem" #~ msgid "Using this configuration file: %s\n" #~ msgstr "Użyj tego pliku konfiguracyjnego: %s\n" #~ msgid "Connecting to the director..." #~ msgstr "Podłączenie do dyrektora..." #~ msgid "Failed to unregister a data parser !" #~ msgstr "Niepowodzenie przy wyrejestrowaniu parsera danych!" #~ msgid "Quitting.\n" #~ msgstr "Wychodzenie.\n" #~ msgid "" #~ "Welcome to Bareos bwx-console.\n" #~ "Written by Nicolas Boichat \n" #~ "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n" #~ msgstr "" #~ "Witamy w Bareos bwx-console.\n" #~ "Napisane przez Nicolas Boichat \n" #~ "Copyright (C), 2005-2007 Free Software Foundation Europe, e.V.\n" #~ msgid "About Bareos bwx-console" #~ msgstr "O Bareos bwx-console" #~ msgid "Please choose your default configuration file" #~ msgstr "Proszę wybierz swój plik konfiguracyjny" #~ msgid "Use this configuration file as default?" #~ msgstr "Użyć tego pliku konfiguracyjnego jako domyślnego?" #~ msgid "Configuration file" #~ msgstr "Plik konfiguracyjny" #~ msgid "Console thread terminated." #~ msgstr "Zakończono wątek konsoli." #~ msgid "Connection to the director lost. Quit program?" #~ msgstr "Podłączenie do dyrektora utracone. Zkończyć program?" #~ msgid "Connection lost" #~ msgstr "Połączenie utracone." #~ msgid "Connected to the director." #~ msgstr "Podłączony do dyrektora." #, fuzzy #~ msgid "Reconnect" #~ msgstr "Utworzone" #, fuzzy #~ msgid "Reconnect to the director" #~ msgstr "Podłączenie do Dyrektora %s:%d" #~ msgid "Disconnected of the director." #~ msgstr "Rozłączanie dyrektora." #~ msgid "Unexpected question has been received.\n" #~ msgstr "Otrzymano nieoczekiwane pytanie.\n" #~ msgid "bwx-console: unexpected director's question." #~ msgstr "bwx-console: nieoczekiwane zapytanie Dyrektora." #~ msgid "Apply" #~ msgstr "Zastosuj" #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Director \"%s\" in config file.\n" #~ "At least one CA certificate store is required.\n" #~ msgstr "" #~ "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie są " #~ "zdefiniowane dla Dyrektora \"%s\" w pliku konfiguracyjnym.\n" #~ " Co najmniej jedno skadowanie certyfikatu CA jest wymagane.\n" #~ msgid "" #~ "No Director resource defined in config file.\n" #~ "Without that I don't how to speak to the Director :-(\n" #~ msgstr "" #~ "Brak definicji zasobu Dyrektora w pliku konfiguracyjnym\n" #~ "Bez tego nie wiem jak rozmawiać z Dyrektorem :-(\n" #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Console \"%s\" in config file.\n" #~ msgstr "" #~ "Ani \"TLS CA Certificate\", ani \"TLS CA Certificate Dir\" nie zostały " #~ "zdefiniowane dla Konsoli \"%s\" w pliku konfiguracyjnym.\n" #~ msgid "Error while initializing windows sockets...\n" #~ msgstr "Błąd w trakcie inicjalizacji gniazd windows...\n" #~ msgid "Error while cleaning up windows sockets...\n" #~ msgstr "Błąd w trakcie czyszczenia gniazd windows...\n" #~ msgid "Error while initializing library." #~ msgstr "Błąd w trakcie inicjalizacji biblioteki." #~ msgid "Cryptographic library initialization failed.\n" #~ msgstr "Nieudana inicjalizacja biblioteki kryptograficznej.\n" #~ msgid "Please correct configuration file.\n" #~ msgstr "Proszę popraw plik konfiguracyjny.\n" #~ msgid "Error : Library not initialized\n" #~ msgstr "Błąd : Nie zainicjalizowana biblioteka\n" #~ msgid "Error : No configuration file loaded\n" #~ msgstr "Błąd : Nie załadowano pliku konfiguracyjnego\n" #~ msgid "Connecting...\n" #~ msgstr "Łączenie...\n" #~ msgid "Error : No director defined in config file.\n" #~ msgstr "Błąd : Brak definicji dyrektora w pliku konfiguracyjnym.\n" #~ msgid "Multiple directors found in your config file.\n" #~ msgstr "Znaleziono wielu dyrektorów w twoim pliku konfiguracyjnym.\n" #~ msgid "Please choose a director (1-%d): " #~ msgstr "Proszę wybierz dyrektora (1-%d): " #~ msgid "Passphrase for Console \"%s\" TLS private key: " #~ msgstr "Hasło dla klucza prywatnego TLS Konsoli \"%s\": " #~ msgid "Passphrase for Director \"%s\" TLS private key: " #~ msgstr "Hasło dla klucza prywatnego TLS Dyrektora \"%s\": " #~ msgid "Failed to connect to the director\n" #~ msgstr "Nieudane podłączenie do dyrektora\n" #~ msgid "Connected\n" #~ msgstr "Podłączony\n" #~ msgid "<< Unexpected signal received : " #~ msgstr "<< Otrzymano nieoczekiwany sygnał : " #~ msgid "Connection terminated\n" #~ msgstr "Podłączenie zakończone\n" #~ msgid "# Bareos bwx-console Configuration File\n" #~ msgstr "# Plik Konfiguracyjny Bareos bwx-console\n" #~ msgid "Save and close" #~ msgstr "Zapisz i zamknij" #~ msgid "Close without saving" #~ msgstr "Zamknij bez zapisywania" #~ msgid "Error while saving" #~ msgstr "Błąd w trakcie zapisywania" #~ msgid "Bareos bwx-console" #~ msgstr "Bareos bwx-console" #~ msgid "Enter restore mode" #~ msgstr "Wprowadź tryb odtwarzania" #~ msgid "Cancel restore" #~ msgstr "Anuluj odtwarzanie" #~ msgid "Remove" #~ msgstr "Usuń" #~ msgid "Refresh" #~ msgstr "Odwierz" #~ msgid "M" #~ msgstr "M" #~ msgid "Filename" #~ msgstr "Nazwa pliku" #~ msgid "Perm." #~ msgstr "Prawa" #~ msgid "User" #~ msgstr "Użytkownik" #~ msgid "Group" #~ msgstr "Grupa" #~ msgid "Job Name" #~ msgstr "Nazwa Zadania" #~ msgid "Before" #~ msgstr "Przed" #~ msgid "Please configure parameters concerning files to restore :" #~ msgstr "Proszę skonfiguruj parametry związane z plikami do odtwarzania :" #~ msgid "always" #~ msgstr "zawsze" #~ msgid "if newer" #~ msgstr "jeśli nowszy" #~ msgid "if older" #~ msgstr "jeśli starszy" #~ msgid "never" #~ msgstr "nigdy" #~ msgid "Please configure parameters concerning files restoration :" #~ msgstr "Proszę skonfigurować parametry dotyczących odtwarzania plików :" #~ msgid "Getting parameters list." #~ msgstr "Pobieranie listy parametrów." #~ msgid "Error : no clients returned by the director." #~ msgstr "Błąd : dyrektor nie zwrócił klientów." #~ msgid "Error : no filesets returned by the director." #~ msgstr "Błąd : dyrektor nie zwrócił żadnych fileset'ów." #~ msgid "Error : no storage returned by the director." #~ msgstr "Błąd : dyrektor nie zwrócił storage." #~ msgid "Error : no jobs returned by the director." #~ msgstr "Błąd : dyrektor nie zwrócił zadań." #~ msgid "RestoreFiles" #~ msgstr "RestoreFiles" #~ msgid "Please configure your restore parameters." #~ msgstr "Proszę skonfiguruj swoje parametry odtwarzania." #~ msgid "Please select a client." #~ msgstr "Proszę zaznacz klienta." #~ msgid "Please select a restore date." #~ msgstr "Proszę wskaż datę odtwarzania." #~ msgid "Building restore tree..." #~ msgstr "Budowanie drzewa odtwarzania..." #~ msgid "Error while starting restore: " #~ msgstr "Błąd w trakcie uruchamiania odtwarzania: " #~ msgid "" #~ "Right click on a file or on a directory, or double-click on its mark to " #~ "add it to the restore list." #~ msgstr "" #~ "Kliknięcie prawym przyciskiem myszy na pliku lub katalogu, lub podwójne " #~ "kliknięcie na nich zaznacza je i dodaje do listy odtwarzania." #~ msgid "bwx-console: unexpected restore question." #~ msgstr "bwx-console: niespodziewane pytanie o odtwarzanie." #~ msgid " files selected to be restored." #~ msgstr " pliki zaznaczone do odtworzenia." #~ msgid " file selected to be restored." #~ msgstr " plik zaznaczony do odtworzenia." #~ msgid "Please configure your restore (%ld files selected to be restored)..." #~ msgstr "" #~ "Proszę skonfiguruj swoje odtwarzanie (%ld plików zaznaczonych do " #~ "odtwarzania)..." #~ msgid "Restore failed : no file selected.\n" #~ msgstr "Nieudane odtwarzanie, nie wskazano pliku.\n" #~ msgid "Restore failed : no file selected." #~ msgstr "Nieudane odtwarzanie, nie wskazano pliku." #~ msgid "Restoring, please wait..." #~ msgstr "Odtwarzanie, proszę czekać..." #~ msgid "Job queued. JobId=" #~ msgstr "Zadanie zakolejkowane. JobId=" #~ msgid "Restore queued, jobid=" #~ msgstr "Odtwarzanie zakolejkowane, jobid=" #~ msgid "Job failed." #~ msgstr "Zadanie nieudane." #~ msgid "Restore failed, please look at messages.\n" #~ msgstr "Nieudane odtwarzanie, proszę zweryfikuj komunikaty.\n" #~ msgid "Restore failed, please look at messages in console." #~ msgstr "Odtwarzanie nieudane, proszę spojrzeć na komunikaty na konsoli." #~ msgid "" #~ "Restore is scheduled to run. bwx-console will not wait for its " #~ "completion.\n" #~ msgstr "" #~ "Zadanie odtwarzania zaplanowane do uruchomienia. bwx-console nie będzie " #~ "czekać na jego zakończenie.\n" #~ msgid "" #~ "Restore is scheduled to run. bwx-console will not wait for its completion." #~ msgstr "" #~ "Zadanie odtwarzania zaplanowane do uruchomienia. bwx-console nie będzie " #~ "czekać na jego zakończenie." #~ msgid "Restore job created, but not yet running." #~ msgstr "Zadanie odtwarzania stworzone, lecz jeszcze nie uruchomione." #~ msgid "Restore job running, please wait (%ld of %ld files restored)..." #~ msgstr "" #~ "Zadanie odtwarzania w trakcie, proszę czekać (%ld z %ld plików " #~ "odtworzonych)..." #~ msgid "Restore job terminated successfully." #~ msgstr "Zadanie odtwarzania zakończone poprawnie." #~ msgid "Restore job terminated successfully.\n" #~ msgstr "Zadanie odtwarzania zakończone poprawnie.\n" #~ msgid "Restore job terminated in error, see messages in console." #~ msgstr "" #~ "Zadanie odtwarzania zakończone z błędem, zobacz komunikaty na konsoli." #~ msgid "Restore job terminated in error, see messages.\n" #~ msgstr "Zadanie odtwarzania zakończone z błędem, zobacz komunikaty.\n" #~ msgid "Restore job reported a non-fatal error." #~ msgstr "Zadanie odtwarzania zaraportowało niekrytyczny błąd." #~ msgid "Restore job reported a fatal error." #~ msgstr "Zadanie odtwarzania zaraportowało błąd krytyczny." #~ msgid "Restore job cancelled by user." #~ msgstr "Zadanie odtwarzania anulowane przez użytkownika." #~ msgid "Restore job cancelled by user.\n" #~ msgstr "Zadanie odtwarzania anulowane przez użytkownika.\n" #~ msgid "Restore job is waiting on File daemon." #~ msgstr "Zadanie odtwarzania oczekuje na Demon Plików." #~ msgid "Restore job is waiting for new media." #~ msgstr "Zadanie odtwarzania oczekuje na nowe medium." #~ msgid "Restore job is waiting for storage resource." #~ msgstr "Zadanie odtwarzania oczekuje na zasoby storage." #~ msgid "Restore job is waiting for job resource." #~ msgstr "Zadanie odtwarzania oczekuje na zasoby dadania." #~ msgid "Restore job is waiting for Client resource." #~ msgstr "Zadanie odtwarzania oczekuje na zasoby Klienta." #~ msgid "Restore job is waiting for maximum jobs." #~ msgstr "Zadanie odtwarzania oczekuje z powodu maksymalnej iloiści zadań." #~ msgid "Restore job is waiting for start time." #~ msgstr "Zadanie odtwarzania oczekuje na czas uruchomienia." #~ msgid "Restore job is waiting for higher priority jobs to finish." #~ msgstr "" #~ "Zadanie odtwarzania oczekuje na zakończenie zadań o wyższym priorytecie." #~ msgid "" #~ "The restore job has not been started within one minute, bwx-console will " #~ "not wait for its completion anymore.\n" #~ msgstr "" #~ "Zadanie odtwarzania nie wystartowało w ciągu minuty, bwx-console nie " #~ "będzie już więcej czekać na jego zakończenie.\n" #~ msgid "" #~ "The restore job has not been started within one minute, bwx-console will " #~ "not wait for its completion anymore." #~ msgstr "" #~ "Zadanie odtwarzania nie wystartowało w ciągu minuty, bwx-console nie " #~ "będzie już więcej czekać na jego zakończenie." #~ msgid "Restore done successfully.\n" #~ msgstr "Odtwarzanie wykonane poprawnie.\n" #~ msgid "Restore done successfully." #~ msgstr "Odtwarzanie wykonane poprawnie." #~ msgid "Applying restore configuration changes..." #~ msgstr "Zastosowanie zmian konfiguracyjnych odtwarzania..." #~ msgid "Failed to find the selected client." #~ msgstr "Nie można znaleźć wskazanego klienta." #~ msgid "Failed to find the selected fileset." #~ msgstr "Nie można znaleźć wskazanego fileset." #~ msgid "Failed to find the selected storage." #~ msgstr "Nie można znaleźć wskazanego storage." #~ msgid "Run Restore job" #~ msgstr "Uruchom zadanie Odtwarzania" #~ msgid "Restore configuration changes were applied." #~ msgstr "Odtworzenie zmian konfiguracji zostało zastosowane." #~ msgid "Restore cancelled.\n" #~ msgstr "Odtwarzanie anulowane.\n" #~ msgid "Restore cancelled." #~ msgstr "Odtwarzanie anulowane." #~ msgid "No results to list." #~ msgstr "Brak rezultatów do wylistowania." #~ msgid "No backup found for this client." #~ msgstr "Nie znaleziono backupu dla tego klienta." #~ msgid "ERROR" #~ msgstr "BŁĄD" #~ msgid "Query failed" #~ msgstr "Nieudane zapytanie" #~ msgid "Cannot get previous backups list, see console." #~ msgstr "Nie moąna otrzymać listy poprzednich backupów, zobacz konsolę." #~ msgid "JobName:" #~ msgstr "Nazwa Zadania:" #~ msgid "Bootstrap:" #~ msgstr "Bootstrap:" #~ msgid "Where:" #~ msgstr "Gdzie:" #~ msgid "Replace:" #~ msgstr "Zamiana:" #~ msgid "ifnewer" #~ msgstr "ifnewer" #~ msgid "ifolder" #~ msgstr "ifolder" #~ msgid "FileSet:" #~ msgstr "FileSet:" #~ msgid "Client:" #~ msgstr "Klient:" #~ msgid "Storage:" #~ msgstr "Storage:" #~ msgid "When:" #~ msgstr "Kiedy:" #~ msgid "Priority:" #~ msgstr "Priorytet:" #~ msgid "Restoring..." #~ msgstr "Odtwarzanie..." #~ msgid "Possible completions: " #~ msgstr "Możliwe uzupełnienia: " bareos-Release-14.2.6/po/quot.sed000066400000000000000000000002311263011562700165370ustar00rootroot00000000000000s/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g bareos-Release-14.2.6/po/remove-potcdate.sin000066400000000000000000000006601263011562700206710ustar00rootroot00000000000000# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } bareos-Release-14.2.6/po/sv.po000066400000000000000000014152301263011562700160540ustar00rootroot00000000000000# Swedish translations for PACKAGE package. # Copyright (C) 2007 Kern Sibbald # This file is distributed under the same license as the PACKAGE package. # Kern Sibbald , 2007. # msgid "" msgstr "" "Project-Id-Version: Bareos 2.1.x\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2007-06-22 19:18+0200\n" "Last-Translator: Kern Sibbald \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "" #: src/cats/sql.c:789 msgid "Could not init database batch connection\n" msgstr "" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:260 #, c-format msgid "More than one Device!: %d\n" msgstr "" #: src/cats/sql_create.c:265 #, c-format msgid "error fetching Device row: %s\n" msgstr "" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1316 #, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1367 #, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1399 #, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1442 #, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1499 #, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1543 #, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 msgid "Could not init database connection" msgstr "" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "" #: src/cats/ingres.c:82 msgid "Failed to allocate space for query filter.\n" msgstr "" #: src/cats/ingres.c:103 msgid "Failed to allocate space for query filters.\n" msgstr "" #: src/cats/ingres.c:257 #, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" #: src/cats/ingres.c:1031 msgid "A user name for Ingres must be supplied.\n" msgstr "" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 msgid "Quota record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 msgid "Catalog Backends Dir not configured.\n" msgstr "" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:236 #, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "" #: src/console/console_conf.c:143 #, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" #: src/console/console.c:170 msgid "input from file" msgstr "" #: src/console/console.c:171 msgid "output to file" msgstr "" #: src/console/console.c:172 msgid "quit" msgstr "" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "" #: src/console/console.c:174 msgid "sleep specified time" msgstr "" #: src/console/console.c:175 msgid "print current time" msgstr "" #: src/console/console.c:176 msgid "print Console's version" msgstr "" #: src/console/console.c:177 msgid "echo command string" msgstr "" #: src/console/console.c:178 msgid "execute an external command" msgstr "" #: src/console/console.c:179 msgid "exit = quit" msgstr "" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "" #: src/console/console.c:181 msgid "help listing" msgstr "" #: src/console/console.c:183 msgid "set command separator" msgstr "" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr "" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "" #: src/console/console.c:996 #, c-format msgid "Can't find %s in Director list\n" msgstr "" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "" #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "" #: src/console/console.c:1600 #, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "" #: src/console/console.c:1612 #, c-format msgid "Autochanger error: ERR=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, c-format msgid "Could not get storage resource '%s'.\n" msgstr "" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 msgid "TLS required but not configured in BAREOS.\n" msgstr "" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "" #: src/dird/dird.c:1110 #, c-format msgid "Could not create storage record for %s\n" msgstr "" #: src/dird/dird.c:1119 #, c-format msgid "Could not update storage record for %s\n" msgstr "" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, c-format msgid "Error getting Quota value: ERR=%s" msgstr "" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:88 #, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:102 #, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:170 #, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:312 msgid "rerun these jobids? (yes/no): " msgstr "" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 msgid "Level" msgstr "" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "" #: src/dird/ua_run.c:555 msgid "Restore Client" msgstr "" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "" #: src/dird/ua_run.c:559 msgid "Backup Format" msgstr "" #: src/dird/ua_run.c:560 msgid "When" msgstr "" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "" #: src/dird/ua_run.c:571 msgid "NextPool" msgstr "" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "" #: src/dird/ua_run.c:582 msgid "Where" msgstr "" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 msgid "Please enter Backup Format: " msgstr "" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "" #: src/dird/ua_run.c:730 msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 msgid "Please enter Plugin Options string: " msgstr "" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 msgid "Storage from Run NextPool override" msgstr "" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, c-format msgid "Level \"%s\" not valid.\n" msgstr "" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 msgid "Please enter the path prefix to strip: " msgstr "" #: src/dird/ua_run.c:1035 msgid "Please enter the path prefix to add (/ for none): " msgstr "" #: src/dird/ua_run.c:1046 msgid "Please enter the file suffix to add: " msgstr "" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "" #: src/dird/ua_run.c:1438 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1498 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "" #: src/dird/ua_run.c:1546 #, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "" #: src/dird/ua_run.c:1602 msgid "Run Migration job\n" msgstr "" #: src/dird/ua_run.c:1604 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1870 msgid "NextPool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1886 msgid "Restore Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1894 msgid "Plugin Options specified twice.\n" msgstr "" #: src/dird/ua_run.c:1899 msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "" #: src/dird/ua_run.c:1906 msgid "Spool flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "" #: src/dird/ua_run.c:1922 msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1929 msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "" #: src/dird/ua_run.c:1934 msgid "Accurate flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1941 msgid "Invalid accurate flag.\n" msgstr "" #: src/dird/ua_run.c:1946 msgid "Backup Format specified twice.\n" msgstr "" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "" #: src/dird/ua_status.c:390 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 msgid "No clients defined.\n" msgstr "" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 msgid "Schedule" msgstr "" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "" #: src/dird/ua_status.c:1034 msgid "has terminated with warnings" msgstr "" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, c-format msgid "is waiting on Storage \"%s\"" msgstr "" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, c-format msgid "is waiting for its start time at %s" msgstr "" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 msgid "is waiting for Client to connect to Storage daemon" msgstr "" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "" #: src/dird/ua_status.c:1177 #, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 msgid "No Volumes found, or no barcodes.\n" msgstr "" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr "" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, c-format msgid "Unknown command: %s\n" msgstr "" #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "" #: src/dird/ua_dotcmds.c:1116 #, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1130 #, c-format msgid "List Media failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1156 #, c-format msgid "List Location failed: ERR=%s\n" msgstr "" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "" #: src/dird/ua_input.c:218 msgid "Comment too long.\n" msgstr "" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "" #: src/dird/ua_cmds.c:112 msgid "Configure director" msgstr "" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 msgid "Disable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 msgid "Terminate Bconsole session" msgstr "" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 msgid "Print current memory usage" msgstr "" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "" #: src/dird/ua_cmds.c:164 msgid "Move slots in an autochanger" msgstr "" #: src/dird/ua_cmds.c:166 msgid "Prune records from catalog" msgstr "" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "" #: src/dird/ua_cmds.c:175 msgid "Restore files" msgstr "" #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 msgid "Rerun a job" msgstr "" #: src/dird/ua_cmds.c:192 msgid "Resolve a hostname" msgstr "" #: src/dird/ua_cmds.c:194 msgid "Run a job" msgstr "" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 msgid "Show resource records" msgstr "" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 msgid "Print current time" msgstr "" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 msgid "Use specific catalog" msgstr "" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 msgid "Print Director version" msgstr "" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, c-format msgid "JobId %s not a number\n" msgstr "" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "" #: src/dird/ua_cmds.c:793 msgid "Failed to set bandwidth limit on Client.\n" msgstr "" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:843 msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, c-format msgid "Client \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1495 msgid "Storage name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1520 #, c-format msgid "%s Failed to resolve %s\n" msgstr "" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, c-format msgid "%s resolves %s to %s\n" msgstr "" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "" #: src/dird/ua_cmds.c:1667 msgid "Accurate value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "" #: src/dird/ua_cmds.c:1696 #, c-format msgid "Wrong job specified of type %s.\n" msgstr "" #: src/dird/ua_cmds.c:1709 msgid "No client specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1714 msgid "No fileset specified or selected.\n" msgstr "" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, c-format msgid "Illegal JobId %s ignored\n" msgstr "" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "" #: src/dird/ua_cmds.c:1979 #, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr "" #: src/dird/ua_cmds.c:2404 #, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:581 #, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:661 #, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "" #: src/dird/ua_select.c:307 #, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "" #: src/dird/ua_select.c:378 msgid "Select Client resource" msgstr "" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "" #: src/dird/ua_select.c:421 msgid "The defined Schedule resources are:\n" msgstr "" #: src/dird/ua_select.c:432 msgid "Select Schedule resource" msgstr "" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "" #: src/dird/ua_select.c:1093 msgid "Select Drive:\n" msgstr "" #: src/dird/ua_select.c:1098 msgid "Drive" msgstr "" #: src/dird/ua_select.c:1098 msgid "Select drive" msgstr "" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, c-format msgid "Selected Job %d for cancelling\n" msgstr "" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "" #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "" #: src/dird/ua_select.c:1443 #, c-format msgid "Choose Job to %s" msgstr "" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "" #: src/dird/catreq.c:203 #, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "" #: src/dird/catreq.c:344 msgid "1992 Create JobMedia error\n" msgstr "" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, c-format msgid "Attribute create error: ERR=%s" msgstr "" #: src/dird/catreq.c:556 #, c-format msgid "Restore object create error. %s" msgstr "" #: src/dird/catreq.c:564 #, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" #: src/dird/catreq.c:613 #, c-format msgid "attribute create error. %s" msgstr "" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, c-format msgid "read attr spool error. ERR=%s\n" msgstr "" #: src/dird/ua_purge.c:95 msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 msgid "Can't update volume size in the catalog\n" msgstr "" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:819 #, c-format msgid "No Volumes found to perform %s action.\n" msgstr "" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 msgid "for Job" msgstr "" #: src/dird/ua_audit.c:71 msgid "for Client" msgstr "" #: src/dird/ua_audit.c:74 msgid "for Storage" msgstr "" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 msgid "for Schedule" msgstr "" #: src/dird/ua_audit.c:83 msgid "for Pool" msgstr "" #: src/dird/ua_audit.c:86 msgid "for Command" msgstr "" #: src/dird/ua_audit.c:89 msgid "for Fileset" msgstr "" #: src/dird/ua_audit.c:92 msgid "for Catalog" msgstr "" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 msgid "for Plugin Options" msgstr "" #: src/dird/ua_audit.c:114 #, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 msgid "base job" msgstr "" #: src/dird/inc_conf.c:225 #, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "" #: src/dird/inc_conf.c:233 #, c-format msgid "Expected a parseable size, got: %s:" msgstr "" #: src/dird/inc_conf.c:251 #, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:405 #, c-format msgid "Expected a fstype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:428 #, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:450 #, c-format msgid "Expected a meta string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr "" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 msgid "Plugin options failed.\n" msgstr "" #: src/dird/fd_cmds.c:828 msgid "RestoreObject failed.\n" msgstr "" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, c-format msgid "Error opening datafile %s\n" msgstr "" #: src/tests/bbatch.c:339 msgid "Error while inserting file\n" msgstr "" #: src/tests/bvfs_test.c:51 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/cats_test.c:375 #, c-format msgid "Could not open, database \"%s\".\n" msgstr "" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:241 #, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:562 #, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, c-format msgid "%s: Failed to resolve %s\n" msgstr "" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1015 #, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:1025 #, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "" #: src/stored/dir_cmd.c:1030 #, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1038 #, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "" #: src/stored/dir_cmd.c:1042 #, c-format msgid "3905 Unknown wait state %d\n" msgstr "" #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1086 #, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1101 #, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1105 #, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "" #: src/stored/dir_cmd.c:1209 #, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "" #: src/stored/dir_cmd.c:1216 #, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "" #: src/stored/dir_cmd.c:1222 #, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "" #: src/stored/dir_cmd.c:1226 #, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1230 #, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1238 #, c-format msgid "3022 Device \"%s\" released.\n" msgstr "" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:1360 #, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "" #: src/stored/dir_cmd.c:1384 #, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1486 #, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" #: src/stored/dir_cmd.c:1489 #, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "" #: src/stored/dir_cmd.c:1492 #, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "" #: src/stored/dir_cmd.c:1496 #, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "" #: src/stored/dir_cmd.c:1500 #, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "" #: src/stored/dir_cmd.c:1505 #, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "" #: src/stored/dir_cmd.c:1507 #, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, c-format msgid "Bad passiveclientcmd command: %s" msgstr "" #: src/stored/dir_cmd.c:1673 msgid "File Daemon" msgstr "" #: src/stored/dir_cmd.c:1679 #, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1690 msgid "Failed to authenticate File daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1724 #, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, c-format msgid "Encountered an unknown stream type %d\n" msgstr "" #: src/stored/ndmp_tape.c:590 #, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:749 msgid "Creating virtual file attributes failed.\n" msgstr "" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, c-format msgid "Read session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 msgid "Cannot initialize new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 msgid "Cannot initialize new NDMA connection\n" msgstr "" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "" #: src/stored/ndmp_tape.c:1414 #, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, c-format msgid "Error in poll: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1557 #, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, c-format msgid "FD command not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:272 msgid "Append data error.\n" msgstr "" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:432 #, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "" #: src/stored/stored_conf.c:874 #, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, c-format msgid "%s has an unknown device type %d\n" msgstr "" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:353 #, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:360 #, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "" #: src/stored/append.c:161 #, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:169 #, c-format msgid "Malformed data header from %s: %s\n" msgstr "" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 msgid "" "\n" "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:985 msgid "" "\n" "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 msgid "Flush block failed.\n" msgstr "" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 msgid "Job canceled.\n" msgstr "" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 msgid "do_unfill failed.\n" msgstr "" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "" #: src/stored/spool.c:701 #, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:716 #, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/reserve.c:84 #, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "" #: src/stored/reserve.c:258 msgid "3939 Could not get dcr\n" msgstr "" #: src/stored/reserve.c:366 #, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "" #: src/stored/mac.c:454 msgid "Read device not properly initialized.\n" msgstr "" #: src/stored/mac.c:479 msgid "Cannot set buffer size SD->SD.\n" msgstr "" #: src/stored/mac.c:496 #, c-format msgid "Bad response to start replicate: %s\n" msgstr "" #: src/stored/mac.c:501 msgid "Bad response from stored to start replicate command\n" msgstr "" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, c-format msgid "Unable to parse device %s.\n" msgstr "" #: src/stored/backends/rados_device.c:62 #, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:69 #, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:77 #, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:89 #, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:271 #, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:278 #, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, c-format msgid "Request for unknown devicetype: %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:317 #, c-format msgid "Unable to parse device URI %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:329 #, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/cephfs_device.c:58 #, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:65 #, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:72 #, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "" #: src/stored/backends/cephfs_device.c:101 #, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/cephfs_device.c:111 #, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, c-format msgid "Failed to create a new context using config %s\n" msgstr "" #: src/stored/backends/object_store_device.c:190 #, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:274 #, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:298 #, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:406 #, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:416 #, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 msgid "waiting for" msgstr "" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 msgid "waiting for sysop intervention" msgstr "" #: src/stored/status.c:275 msgid "unknown state" msgstr "" #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "" #: src/stored/status.c:332 #, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "" #: src/stored/status.c:336 #, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "" #: src/stored/status.c:369 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "" #: src/stored/status.c:523 #, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 msgid "Attached Jobs: " msgstr "" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, c-format msgid " File=%u block=%u\n" msgstr "" #: src/stored/status.c:610 #, c-format msgid " Min block=%u Max block=%u\n" msgstr "" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr "" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, c-format msgid "3900 No arg in status command: %s\n" msgstr "" #: src/stored/status.c:984 #, c-format msgid "3900 No arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1033 #, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "" #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:131 msgid "Unable to authenticate Storage daemon\n" msgstr "" #: src/stored/sd_cmds.c:182 #, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "" #: src/stored/sd_cmds.c:185 msgid "Command error with SD, hanging up.\n" msgstr "" #: src/stored/sd_cmds.c:197 #, c-format msgid "SD command not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:338 msgid "Replicate data error.\n" msgstr "" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:133 #, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:257 #, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, c-format msgid "Could not reserve volume %s on %s\n" msgstr "" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 msgid "Error updating Catalog\n" msgstr "" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "" #: src/stored/mount.c:741 #, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" #: src/stored/block.c:644 #, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 msgid "Error sending Volume info to Director.\n" msgstr "" #: src/stored/block.c:949 msgid "Job failed or canceled.\n" msgstr "" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "" #: src/stored/lock.c:489 msgid "unknown blocked code" msgstr "" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:310 #, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:324 #, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "" #: src/stored/autochanger.c:699 msgid "3306 Issuing autochanger transfer command.\n" msgstr "" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "" #: src/stored/bcopy.c:60 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 msgid "Quota Exceeded. Job Terminated.\n" msgstr "" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:650 #, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:981 #, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1965 #, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2292 #, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:2321 #, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" #: src/findlib/find.c:180 #, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "" #: src/findlib/bfile.c:92 msgid "File data" msgstr "" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "" #: src/findlib/bfile.c:98 msgid "Compressed data" msgstr "" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "" #: src/findlib/bfile.c:106 msgid "Compressed sparse data" msgstr "" #: src/findlib/bfile.c:108 msgid "Program names" msgstr "" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:118 msgid "Win32 compressed data" msgstr "" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "" #: src/findlib/bfile.c:142 msgid "Encrypted compressed data" msgstr "" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "" #: src/findlib/bfile.c:146 msgid "Encrypted Win32 Compressed data" msgstr "" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "" #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:168 msgid "TRU64 Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:170 msgid "TRU64 Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:172 msgid "Solaris Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:174 msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:176 msgid "AFS Specific ACL attribs" msgstr "" #: src/findlib/bfile.c:178 msgid "AIX Specific POSIX ACL attribs" msgstr "" #: src/findlib/bfile.c:180 msgid "AIX Specific NFSv4 ACL attribs" msgstr "" #: src/findlib/bfile.c:182 msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "" #: src/findlib/bfile.c:184 msgid "GNU Hurd Specific Default ACL attribs" msgstr "" #: src/findlib/bfile.c:186 msgid "GNU Hurd Specific Access ACL attribs" msgstr "" #: src/findlib/bfile.c:188 msgid "GNU Hurd Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:190 msgid "IRIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:192 msgid "TRU64 Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:194 msgid "AIX Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:196 msgid "OpenBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "" #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "" #: src/findlib/find_one.c:268 #, c-format msgid "%s: mtime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:275 #, c-format msgid "%s: ctime changed during backup.\n" msgstr "" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, c-format msgid "%s: size changed during backup.\n" msgstr "" #: src/findlib/find_one.c:729 #, c-format msgid "%s: File name too long [%d]\n" msgstr "" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:293 #, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:495 #, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:929 #, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:967 #, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1000 #, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1683 #, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2196 #, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2225 #, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, c-format msgid "Unparseable size option: %s\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, c-format msgid "Unexpected autodeflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:368 #, c-format msgid "Unexpected autoinflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 msgid "Plugin File argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:916 msgid "Plugin Reader argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:922 msgid "Plugin Writer argument not specified.\n" msgstr "" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, c-format msgid "Enter Key Encryption Key: " msgstr "" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, c-format msgid "Cannot open keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "" #: src/tools/bscrypto.c:401 #, c-format msgid "Enter Encryption Key: " msgstr "" #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:177 #, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, c-format msgid "Failed to connect to mailhost %s\n" msgstr "" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 msgid "BAREOS Message" msgstr "" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:1054 #, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "" #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "" #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "" #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "" #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "" #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "" #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr "" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr "" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr "" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr "" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr "" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "" #: src/lib/lex.c:140 #, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:144 #, c-format msgid "Config warning: %s\n" msgstr "" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 msgid "string" msgstr "" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 msgid "include" msgstr "" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "" #: src/lib/jcr.c:248 msgid "Copying" msgstr "" #: src/lib/jcr.c:250 msgid "Migration" msgstr "" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "" #: src/lib/jcr.c:265 msgid "backup" msgstr "" #: src/lib/jcr.c:267 msgid "verified" msgstr "" #: src/lib/jcr.c:269 msgid "restored" msgstr "" #: src/lib/jcr.c:269 msgid "restore" msgstr "" #: src/lib/jcr.c:271 msgid "archived" msgstr "" #: src/lib/jcr.c:271 msgid "archive" msgstr "" #: src/lib/jcr.c:273 msgid "copied" msgstr "" #: src/lib/jcr.c:273 msgid "copy" msgstr "" #: src/lib/jcr.c:275 msgid "migrated" msgstr "" #: src/lib/jcr.c:275 msgid "migrate" msgstr "" #: src/lib/jcr.c:277 msgid "scanned" msgstr "" #: src/lib/jcr.c:277 msgid "scan" msgstr "" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "" #: src/lib/jcr.c:394 #, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:108 #, c-format msgid "prctl failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:112 #, c-format msgid "setreuid failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 msgid "unknown error" msgstr "" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 msgid "Encryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:251 msgid "Encryption Mode: External\n" msgstr "" #: src/lib/scsi_crypto.c:256 msgid "Encryption Mode: Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 msgid "Volume encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:460 msgid "Compression Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 msgid "Encryption Status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 msgid "Drive encryption status: Unknown\n" msgstr "" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "" #: src/lib/bnet.c:326 msgid "No problem." msgstr "" #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "" #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "" #: src/lib/crypto_cache.c:160 #, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 msgid "Volumename" msgstr "" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 msgid "EncryptionKey" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Added" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:274 #, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 msgid "No error" msgstr "" #: src/lib/crypto.c:176 msgid "Signer not found" msgstr "" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 msgid "Selection item too large.\n" msgstr "" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "" #: src/lib/ini.c:262 src/lib/ini.c:274 #, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:312 src/lib/ini.c:324 #, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:560 src/lib/ini.c:672 #, c-format msgid "Cannot open config file %s: %s\n" msgstr "" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, c-format msgid "Error loading CA certificates from %s\n" msgstr "" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "" #: src/lib/tls_gnutls.c:201 #, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "" #: src/lib/tls_gnutls.c:216 #, c-format msgid "Failed to load DH file %s\n" msgstr "" #: src/lib/tls_gnutls.c:224 msgid "Failed to generate new DH parameters\n" msgstr "" #: src/lib/tls_gnutls.c:289 #, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "" #: src/lib/res.c:830 #, c-format msgid "expected a speed number, got: %s" msgstr "" #: src/lib/res.c:835 msgid "unknown unit type encountered" msgstr "" #: src/lib/res.c:853 #, c-format msgid "expected a %s, got: %s" msgstr "" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "" #: src/lib/bsock.c:139 msgid "attr spool I/O error.\n" msgstr "" #: src/lib/bsock.c:276 #, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" #: src/lib/bsock.c:311 #, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "" #: src/lib/bsock.c:321 #, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "" #: src/lib/bsock.c:330 #, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "" #: src/lib/bsock.c:341 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:186 #, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:269 #, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:292 #, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:632 msgid "Could not malloc BSOCK data buffer\n" msgstr "" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "" #: src/lib/devlock.c:322 msgid "writeunlock called too many times.\n" msgstr "" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:542 #, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "" #: src/lib/parse_conf.c:149 msgid "Config filename too long.\n" msgstr "" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "" #: src/lib/compression.c:88 msgid "GZIP compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:91 msgid "LZO2 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:94 msgid "LZFZ compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:97 msgid "LZ4 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:100 msgid "LZ4HC compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 msgid "Failed to initialize ZLIB compression\n" msgstr "" #: src/lib/compression.c:215 msgid "Failed to initialize LZO compression\n" msgstr "" #: src/lib/compression.c:270 msgid "Failed to initialize FASTLZ compression\n" msgstr "" #: src/lib/compression.c:300 msgid "LZO init failed\n" msgstr "" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "" #: src/lib/compression.c:371 #, c-format msgid "Compression LZO error: %d\n" msgstr "" #: src/lib/compression.c:402 #, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "" #: src/lib/compression.c:413 #, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "" #: src/lib/compression.c:592 #, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 msgid "Compressed data stream found, but compression not configured!\n" msgstr "" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 msgid "Error loading revocation list file" msgstr "" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 msgid "Running" msgstr "" #: src/lib/util.c:214 msgid "Blocked" msgstr "" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "" #: src/lib/util.c:238 msgid "Verify differences" msgstr "" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "" #: src/lib/util.c:302 msgid "Completed successfully" msgstr "" #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "" #: src/lib/util.c:311 msgid "Fatal error" msgstr "" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "" #: src/lib/util.c:320 msgid "Verify found differences" msgstr "" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "" #: src/lib/util.c:369 msgid "Differences" msgstr "" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "" #: src/lib/util.c:391 msgid "Migrated Job" msgstr "" #: src/lib/util.c:394 msgid "Verify" msgstr "" #: src/lib/util.c:397 msgid "Restore" msgstr "" #: src/lib/util.c:400 msgid "Console" msgstr "" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "" #: src/lib/util.c:412 msgid "Job Copy" msgstr "" #: src/lib/util.c:415 msgid "Copy" msgstr "" #: src/lib/util.c:418 msgid "Migrate" msgstr "" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "" #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "" #: src/lib/util.c:479 msgid "Verify Data" msgstr "" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 msgid "Append" msgstr "" #: src/lib/util.c:500 msgid "Disabled" msgstr "" #: src/lib/util.c:502 msgid "Used" msgstr "" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 msgid "Recycle" msgstr "" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 msgid "Invalid volume status" msgstr "" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "" #: src/lib/signal.c:152 src/lib/signal.c:154 #, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "" #: src/lib/signal.c:323 msgid "Hangup" msgstr "" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "" #: src/lib/signal.c:325 msgid "Quit" msgstr "" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "" #: src/lib/signal.c:335 msgid "BUS error" msgstr "" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "" #: src/lib/signal.c:343 msgid "Termination" msgstr "" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "" #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:92 #, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:314 #, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:323 #, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "" #: src/lib/scsi_lli.c:348 #, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "" #: src/lib/scsi_lli.c:464 #, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "" #: src/lib/crypto_openssl.c:749 msgid "No signers found for crypto verify.\n" msgstr "" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1615 #, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, c-format msgid "Could not set Finder Info on %s\n" msgstr "" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, c-format msgid "Cannot open resource fork for %s.\n" msgstr "" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "" #: src/filed/dir_cmd.c:933 #, c-format msgid "Bad RunAfter command: %s\n" msgstr "" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1015 #, c-format msgid "Bad Plugin Options command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1066 #, c-format msgid "Bad RestoreObject command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1166 msgid "2909 Bad RestoreObject command.\n" msgstr "" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "" #: src/filed/dir_cmd.c:1696 #, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1708 #, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "" #: src/filed/filed.c:61 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, c-format msgid "Unable to create MDB environment: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:81 #, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:90 #, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:97 #, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:103 #, c-format msgid "Unable to start a write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:109 #, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, c-format msgid "Unable insert new data: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, c-format msgid "Unable close write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, c-format msgid "Unable to create write transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:249 #, c-format msgid "Unable to create read transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, c-format msgid "Unable to renew read transaction: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, c-format msgid "Unable create cursor: %s\n" msgstr "" #: src/filed/status.c:87 #, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, c-format msgid " %s%s %s Job started: %s\n" msgstr "" #: src/filed/status.c:201 #, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr "" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "" #: src/filed/authenticate.c:301 #, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, c-format msgid "Cannot verify checksum for %s\n" msgstr "" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr "" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:79 #, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "" #: src/qt-tray-monitor/authenticate.cpp:139 msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "" #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "" #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "" bareos-Release-14.2.6/po/uk.po000066400000000000000000015625661263011562700160620ustar00rootroot00000000000000# Ukrainian translations for bareos package # Український переклад bareos. # Copyright (C) 2010 Kern Sibbald # This file is distributed under the same license as the bareos package. # Vitaliy Kosharskiy , 2010. # msgid "" msgstr "" "Project-Id-Version: bareos 3.0.3\n" "Report-Msgid-Bugs-To: info@bareos.org\n" "POT-Creation-Date: 2015-11-16 20:36+0100\n" "PO-Revision-Date: 2010-01-08 17:32+0300\n" "Last-Translator: Vitaliy Kosharskiy \n" "Language-Team: Ukrainian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: src/cats/sql.c:178 #, c-format msgid "" "Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than " "Director's MaxConcurrentJobs=%d\n" msgstr "" #: src/cats/sql.c:221 #, c-format msgid "" "query %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:242 #, c-format msgid "" "insert %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:252 #, c-format msgid "Insertion problem: affected_rows=%s\n" msgstr "" #: src/cats/sql.c:273 #, c-format msgid "" "update %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:285 #, c-format msgid "Update failed: affected_rows=%s for %s\n" msgstr "" #: src/cats/sql.c:308 #, c-format msgid "" "delete %s failed:\n" "%s\n" msgstr "" #: src/cats/sql.c:334 src/cats/sql.c:341 src/cats/sql_create.c:634 #: src/cats/sql_get.c:196 src/cats/sql_get.c:249 src/cats/sql_get.c:630 #: src/cats/sql_get.c:716 src/cats/sql_get.c:1046 src/cats/sql_get.c:1511 #: src/cats/sql_get.c:1558 src/cats/postgresql.c:155 #, c-format msgid "error fetching row: %s\n" msgstr "" #: src/cats/sql.c:402 #, c-format msgid "Path length is zero. File=%s\n" msgstr "" #: src/cats/sql.c:637 msgid "No results to list.\n" msgstr "" #: src/cats/sql.c:789 #, fuzzy msgid "Could not init database batch connection\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/cats/dbi.c:113 src/cats/cats_backends.c:123 #, c-format msgid "Unknown database type: %s\n" msgstr "" #: src/cats/dbi.c:218 src/cats/mysql.c:154 src/cats/sqlite.c:156 #: src/cats/ingres.c:245 src/cats/postgresql.c:200 #, c-format msgid "Unable to initialize DB lock. ERR=%s\n" msgstr "" #: src/cats/dbi.c:232 #, c-format msgid "" "Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n" msgstr "" #: src/cats/dbi.c:289 #, c-format msgid "" "Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/dbi.c:569 src/cats/mysql.c:389 src/cats/sqlite.c:324 #: src/cats/ingres.c:386 src/cats/postgresql.c:473 src/dird/fd_cmds.c:882 #: src/dird/fd_cmds.c:941 #, c-format msgid "Attribute create error. %s" msgstr "" #: src/cats/dbi.c:635 src/cats/mysql.c:411 src/cats/cats.c:156 #: src/cats/sqlite.c:399 src/cats/ingres.c:418 src/cats/postgresql.c:525 #: src/cats/postgresql.c:572 #, c-format msgid "Query failed: %s: ERR=%s\n" msgstr "" #: src/cats/dbi.c:1281 src/cats/postgresql.c:1023 #, c-format msgid "error starting batch mode: %s" msgstr "" #: src/cats/dbi.c:1443 #, c-format msgid "error inserting batch mode: %s" msgstr "" #: src/cats/dbi.c:1482 src/cats/cats_backends.c:115 msgid "Driver type not specified in Catalog resource.\n" msgstr "" #: src/cats/dbi.c:1486 msgid "Invalid driver type, must be \"dbi:\"\n" msgstr "" #: src/cats/dbi.c:1490 msgid "A user name for DBI must be supplied.\n" msgstr "" #: src/cats/sql_create.c:97 #, c-format msgid "Create DB Job record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:142 #, c-format msgid "Create JobMedia record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:152 #, c-format msgid "Update Media record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:186 #, c-format msgid "pool record %s already exists\n" msgstr "" #: src/cats/sql_create.c:220 #, c-format msgid "Create db Pool record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:260 #, c-format msgid "More than one Device!: %d\n" msgstr "" #: src/cats/sql_create.c:265 #, c-format msgid "error fetching Device row: %s\n" msgstr "" #: src/cats/sql_create.c:294 #, c-format msgid "Create db Device record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:332 #, c-format msgid "More than one Storage record!: %d\n" msgstr "" #: src/cats/sql_create.c:337 #, c-format msgid "error fetching Storage row: %s\n" msgstr "" #: src/cats/sql_create.c:361 #, c-format msgid "Create DB Storage record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:394 #, c-format msgid "mediatype record %s already exists\n" msgstr "" #: src/cats/sql_create.c:412 #, c-format msgid "Create db mediatype record %s failed: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:450 #, c-format msgid "Volume \"%s\" already exists.\n" msgstr "" #: src/cats/sql_create.c:497 #, c-format msgid "Create DB Media record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:550 #, c-format msgid "More than one Client!: %d\n" msgstr "" #: src/cats/sql_create.c:555 #, c-format msgid "error fetching Client row: %s\n" msgstr "" #: src/cats/sql_create.c:586 #, c-format msgid "Create DB Client record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:625 src/cats/sql_get.c:242 #, c-format msgid "More than one Path!: %s for path: %s\n" msgstr "" #: src/cats/sql_create.c:662 #, c-format msgid "Create db Path record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:712 #, c-format msgid "Create DB Counters record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:751 #, c-format msgid "More than one FileSet!: %d\n" msgstr "" #: src/cats/sql_create.c:756 #, c-format msgid "error fetching FileSet row: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:790 #, c-format msgid "Create DB FileSet record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1028 #, c-format msgid "Create db File record %s failed. ERR=%s" msgstr "" #: src/cats/sql_create.c:1057 #, c-format msgid "More than one Filename! %s for file: %s\n" msgstr "" #: src/cats/sql_create.c:1063 #, c-format msgid "Error fetching row for file=%s: ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1080 #, c-format msgid "Create db Filename record %s failed. ERR=%s\n" msgstr "" #: src/cats/sql_create.c:1102 #, c-format msgid "Attempt to put non-attributes into catalog. Stream=%d\n" msgstr "" #: src/cats/sql_create.c:1118 msgid "Cannot Copy/Migrate job using BaseJob.\n" msgstr "" #: src/cats/sql_create.c:1215 src/cats/sql_get.c:1150 msgid "ERR=JobIds are empty\n" msgstr "" #: src/cats/sql_create.c:1270 #, fuzzy, c-format msgid "Create db Object record %s failed. ERR=%s" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/sql_create.c:1316 #, fuzzy, c-format msgid "Create DB Quota record %s failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/sql_create.c:1367 #, fuzzy, c-format msgid "Create DB NDMP Level Map record %s failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/sql_create.c:1399 #, fuzzy, c-format msgid "Create DB NDMP Job Environment record %s failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/sql_create.c:1442 #, fuzzy, c-format msgid "Create DB JobStats record %s failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/sql_create.c:1499 #, fuzzy, c-format msgid "Create DB DeviceStats record %s failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/sql_create.c:1543 #, fuzzy, c-format msgid "Create DB TapeAlerts record %s failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/cats/mysql.c:197 #, c-format msgid "" "Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is " "incorrect.\n" msgstr "" #: src/cats/mysql.c:732 msgid "A user name for MySQL must be supplied.\n" msgstr "" #: src/cats/sql_delete.c:71 #, c-format msgid "No pool record %s exists\n" msgstr "" #: src/cats/sql_delete.c:75 #, c-format msgid "Expecting one pool record, got %d\n" msgstr "" #: src/cats/sql_delete.c:80 #, c-format msgid "Error fetching row %s\n" msgstr "" #: src/cats/sql_find.c:92 src/cats/sql_find.c:121 src/cats/sql_find.c:174 #, c-format msgid "" "Query error for start time request: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:98 src/cats/sql_find.c:180 msgid "No prior Full backup Job record found.\n" msgstr "" #: src/cats/sql_find.c:110 #, c-format msgid "Unknown level=%d\n" msgstr "" #: src/cats/sql_find.c:127 #, c-format msgid "" "No Job record found: ERR=%s\n" "CMD=%s\n" msgstr "" #: src/cats/sql_find.c:282 #, c-format msgid "Unknown Job level=%d\n" msgstr "" #: src/cats/sql_find.c:290 #, c-format msgid "No Job found for: %s.\n" msgstr "" #: src/cats/sql_find.c:300 #, c-format msgid "No Job found for: %s\n" msgstr "" #: src/cats/sql_find.c:382 #, c-format msgid "Request for Volume item %d greater than max %d or less than 1\n" msgstr "" #: src/cats/sql_find.c:396 #, c-format msgid "No Volume record found for item %d.\n" msgstr "" #: src/cats/sql_list.c:54 #, c-format msgid "Query failed: %s\n" msgstr "" #: src/cats/sql_list.c:272 msgid "These JobIds have copies as follows:\n" msgstr "" #: src/cats/sql_list.c:274 msgid "The catalog contains copies as follows:\n" msgstr "" #: src/cats/sql_pooling.c:79 src/cats/sql_pooling.c:210 #, c-format msgid "Could not open database \"%s\": ERR=%s\n" msgstr "" #: src/cats/sql_pooling.c:164 #, c-format msgid "" "Illegal values for sql pool initialization, min_connections = %d, " "max_connections = %d, increment_connections = %d" msgstr "" #: src/cats/sql_pooling.c:205 src/cats/sql_pooling.c:364 #, fuzzy msgid "Could not init database connection" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/cats/sqlite.c:171 #, c-format msgid "Database %s does not exist, please create it.\n" msgstr "" #: src/cats/sqlite.c:193 #, c-format msgid "Unable to open Database=%s. ERR=%s\n" msgstr "" #: src/cats/sqlite.c:194 msgid "unknown" msgstr "" #: src/cats/ingres.c:82 msgid "Failed to allocate space for query filter.\n" msgstr "" #: src/cats/ingres.c:103 msgid "Failed to allocate space for query filters.\n" msgstr "" #: src/cats/ingres.c:257 #, c-format msgid "" "Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n" msgstr "" #: src/cats/ingres.c:1031 msgid "A user name for Ingres must be supplied.\n" msgstr "" #: src/cats/sql_get.c:143 #, c-format msgid "Error fetching row: %s\n" msgstr "" #: src/cats/sql_get.c:150 #, c-format msgid "get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n" msgstr "" #: src/cats/sql_get.c:158 #, c-format msgid "File record for PathId=%s FilenameId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:164 msgid "File record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:190 #, c-format msgid "More than one Filename!: %s for file: %s\n" msgstr "" #: src/cats/sql_get.c:200 #, c-format msgid "Get DB Filename record %s found bad record: %d\n" msgstr "" #: src/cats/sql_get.c:206 #, c-format msgid "Filename record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:210 #, c-format msgid "Filename record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:253 #, c-format msgid "Get DB path record %s found bad record: %s\n" msgstr "" #: src/cats/sql_get.c:266 #, c-format msgid "Path record: %s not found.\n" msgstr "" #: src/cats/sql_get.c:270 #, c-format msgid "Path record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:309 #, c-format msgid "No Job found for JobId %s\n" msgstr "" #: src/cats/sql_get.c:384 src/cats/sql_get.c:441 #, c-format msgid "No volumes found for JobId=%d\n" msgstr "" #: src/cats/sql_get.c:390 src/cats/sql_get.c:452 #, c-format msgid "Error fetching row %d: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:404 #, c-format msgid "No Volume for JobId %d found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:545 #, c-format msgid "Pool id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:582 #, c-format msgid "Client id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:625 #, c-format msgid "More than one Pool!: %s\n" msgstr "" #: src/cats/sql_get.c:672 msgid "Pool record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:711 #, c-format msgid "More than one Client!: %s\n" msgstr "" #: src/cats/sql_get.c:728 src/cats/sql_get.c:732 msgid "Client record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:760 #, c-format msgid "More than one Counter!: %d\n" msgstr "" #: src/cats/sql_get.c:765 #, c-format msgid "error fetching Counter row: %s\n" msgstr "" #: src/cats/sql_get.c:784 #, c-format msgid "Counter record: %s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:826 #, c-format msgid "Error got %s FileSets but expected only one!\n" msgstr "" #: src/cats/sql_get.c:831 #, c-format msgid "FileSet record \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:841 msgid "FileSet record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:946 #, c-format msgid "Media id select failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:984 #, c-format msgid "query dbids failed: ERR=%s\n" msgstr "" #: src/cats/sql_get.c:1041 #, c-format msgid "More than one Volume!: %s\n" msgstr "" #: src/cats/sql_get.c:1098 #, c-format msgid "Media record MediaId=%s not found.\n" msgstr "" #: src/cats/sql_get.c:1101 #, c-format msgid "Media record for Volume \"%s\" not found.\n" msgstr "" #: src/cats/sql_get.c:1108 #, c-format msgid "Media record for MediaId=%u not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1111 #, c-format msgid "Media record for Vol=%s not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1425 src/cats/sql_get.c:1481 #, fuzzy, c-format msgid "JobBytes sum select failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/cats/sql_get.c:1521 src/cats/sql_get.c:1525 msgid "Quota record not found in Catalog.\n" msgstr "" #: src/cats/sql_get.c:1569 src/cats/sql_get.c:1574 msgid "NDMP Dump Level record not found in Catalog.\n" msgstr "" #: src/cats/postgresql.c:171 #, c-format msgid "Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n" msgstr "" #: src/cats/postgresql.c:236 #, c-format msgid "" "Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections " "exceeded.\n" msgstr "" #: src/cats/postgresql.c:369 msgid "PQescapeStringConn returned non-zero.\n" msgstr "" #: src/cats/postgresql.c:387 msgid "PQescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:418 msgid "PQunescapeByteaConn returned NULL.\n" msgstr "" #: src/cats/postgresql.c:832 #, c-format msgid "error fetching currval: %s\n" msgstr "" #: src/cats/postgresql.c:1053 src/cats/postgresql.c:1062 #, c-format msgid "error ending batch mode: %s" msgstr "" #: src/cats/postgresql.c:1110 #, c-format msgid "error copying in batch mode: %s" msgstr "" #: src/cats/postgresql.c:1152 msgid "A user name for PostgreSQL must be supplied.\n" msgstr "" #: src/cats/cats_backends.c:108 src/stored/sd_backends.c:84 msgid "Catalog Backends Dir not configured.\n" msgstr "" #: src/cats/cats_backends.c:170 src/stored/sd_backends.c:119 #, fuzzy, c-format msgid "Unable to load shared library: %s ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/cats/cats_backends.c:180 src/stored/sd_backends.c:129 #, c-format msgid "Lookup of backend_instantiate in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:192 src/stored/sd_backends.c:141 #, c-format msgid "Lookup of flush_backend in shared library %s failed: ERR=%s\n" msgstr "" #: src/cats/cats_backends.c:236 #, fuzzy, c-format msgid "Unable to load any shared library for libbareoscats-%s%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/cats/cats_backends.c:281 src/cats/cats_backends.c:282 msgid "Please replace this dummy libbareoscats library with a proper one.\n" msgstr "" #: src/console/console_conf.c:134 src/qt-console/bat_conf.cpp:139 #, c-format msgid "No record for %d %s\n" msgstr "Відсутні записи для %d %s\n" #: src/console/console_conf.c:143 #, fuzzy, c-format msgid "Console: name=%s rcfile=%s histfile=%s histsize=%d\n" msgstr "Консоль: назва=%s rcfile=%s histfile=%s\n" #: src/console/console_conf.c:147 src/qt-console/bat_conf.cpp:148 #, c-format msgid "Director: name=%s address=%s DIRport=%d\n" msgstr "Керівник: назва=%s адреса=%s DIRport=%d\n" #: src/console/console_conf.c:151 src/console/console_conf.c:233 #: src/console/console_conf.c:278 src/stored/stored_conf.c:773 #: src/stored/stored_conf.c:879 src/filed/filed_conf.c:367 #: src/filed/filed_conf.c:444 src/qt-console/bat_conf.cpp:159 #: src/qt-console/bat_conf.cpp:245 src/qt-console/bat_conf.cpp:299 #, c-format msgid "Unknown resource type %d\n" msgstr "Невідомий тип ресурсу %d\n" #: src/console/console_conf.c:259 src/dird/dird_conf.c:2169 #: src/dird/dird_conf.c:2187 src/filed/filed_conf.c:397 #: src/qt-tray-monitor/tray_conf.cpp:300 src/qt-console/bat_conf.cpp:274 #, c-format msgid "%s item is required in %s resource, but not found.\n" msgstr "Не знайдено необхідний елемент %s для ресурсу %s.\n" #: src/console/console_conf.c:308 src/dird/dird_conf.c:2402 #: src/filed/filed_conf.c:480 src/qt-tray-monitor/tray_conf.cpp:366 #: src/qt-console/bat_conf.cpp:335 #, c-format msgid "Attempt to define second %s resource named \"%s\" is not permitted.\n" msgstr "Спроба визначити другий %s ресурс із назвою \"%s\" не дозволяється.\n" #: src/console/console.c:116 #, c-format msgid "" "\n" "Version: " msgstr "" "\n" "Вірсія: " #: src/console/console.c:170 msgid "input from file" msgstr "введення із файлу" #: src/console/console.c:171 msgid "output to file" msgstr "вивід до файлу" #: src/console/console.c:172 msgid "quit" msgstr "" #: src/console/console.c:173 msgid "output to file and terminal" msgstr "вивід до файлу та консолі" #: src/console/console.c:174 msgid "sleep specified time" msgstr "зазначений час сну" #: src/console/console.c:175 msgid "print current time" msgstr "вивести поточний час" #: src/console/console.c:176 msgid "print Console's version" msgstr "вивести версію Консолі" #: src/console/console.c:177 msgid "echo command string" msgstr "луна командного рядку" #: src/console/console.c:178 msgid "execute an external command" msgstr "виконати зовнішню команду" #: src/console/console.c:179 msgid "exit = quit" msgstr "" #: src/console/console.c:180 msgid "zed_keys = use zed keys instead of bash keys" msgstr "zed_keys = використовувати zed keys замість bash keys" #: src/console/console.c:181 msgid "help listing" msgstr "допомога" #: src/console/console.c:183 msgid "set command separator" msgstr "задати роздільник команд" #: src/console/console.c:217 msgid ": is an invalid command\n" msgstr ": неправильна команда\n" #: src/console/console.c:712 msgid "Illegal separator character.\n" msgstr "Невірний символ роздільника.\n" #: src/console/console.c:744 msgid "Command logic problem\n" msgstr "Проблеми логіки команди\n" #: src/console/console.c:996 #, fuzzy, c-format msgid "Can't find %s in Director list\n" msgstr ": неправильна команда\n" #: src/console/console.c:1004 msgid "Available Directors:\n" msgstr "Наявні Керівники:\n" #: src/console/console.c:1008 #, c-format msgid "%2d: %s at %s:%d\n" msgstr "" #: src/console/console.c:1012 msgid "Select Director by entering a number: " msgstr "Оберіть Керівника, увівши номер: " #: src/console/console.c:1019 #, c-format msgid "%s is not a number. You must enter a number between 1 and %d\n" msgstr "%s не є номером. Ви повинні увести номер із проміжку 1..%d\n" #: src/console/console.c:1026 #, c-format msgid "You must enter a number between 1 and %d\n" msgstr "Ви повинні увести номер із проміжку 1..%d\n" #: src/console/console.c:1192 src/dird/dird.c:289 src/stored/stored.c:223 #: src/filed/filed.c:217 src/qt-console/main.cpp:155 msgid "Cryptography library initialization failed.\n" msgstr "Ініціалізація криптографії невдала.\n" #: src/console/console.c:1196 src/dird/dird.c:294 src/dird/dird.c:333 #: src/dird/dird.c:342 src/dird/dird.c:577 src/dird/dird.c:581 #: src/stored/stored.c:227 src/filed/filed.c:222 src/qt-console/main.cpp:159 #, c-format msgid "Please correct configuration file: %s\n" msgstr "Будьласка виправте файл конфігурації: %s\n" #: src/console/console.c:1226 #, c-format msgid "Connecting to Director %s:%d\n" msgstr "Підключаюсь до Керівника %s:%d\n" #: src/console/console.c:1253 src/qt-console/bcomm/dircomm.cpp:123 #, c-format msgid "Failed to initialize TLS context for Console \"%s\".\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/console/console.c:1286 src/qt-console/bcomm/dircomm.cpp:150 #, c-format msgid "Failed to initialize TLS context for Director \"%s\".\n" msgstr "Ініціалізація контексту TLS для Керівника невдала \"%s\".\n" #: src/console/console.c:1335 msgid "Enter a period to cancel a command.\n" msgstr "Уведіть цятку для переривання команди.\n" #: src/console/console.c:1445 src/console/console.c:1479 #: src/stored/stored.c:362 src/filed/filed.c:359 src/filed/filed.c:527 #: src/qt-console/main.cpp:214 src/qt-console/main.cpp:244 msgid "TLS required but not configured in Bareos.\n" msgstr "TLS необхідний, але не налаштовано у Bareos.\n" #: src/console/console.c:1453 src/qt-console/main.cpp:222 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required.\n" msgstr "" "Жоден із параметрів \"TLS CA Certificate\" або \"TLS CA Certificate Dir\" не " "задано для Керівника \"%s\" у %s. Необхідне щонайменше одне сховище для " "сертифікату CA.\n" #: src/console/console.c:1462 src/qt-console/main.cpp:231 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n" msgstr "" "У %s не задано ресурсу Керівника\n" "Без цього я не знаю як спілкуватись із Керівником :-(\n" #: src/console/console.c:1486 src/qt-console/main.cpp:252 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s.\n" msgstr "" "Жоден із параметрів \"TLS CA Certificate\" або \"TLS CA Certificate Dir\" не " "задано для Консолі \"%s\" у %s.\n" #: src/console/console.c:1514 msgid "Too many arguments on input command.\n" msgstr "Забагато параметрів команди.\n" #: src/console/console.c:1518 msgid "First argument to input command must be a filename.\n" msgstr "Перший параметр команди повинен бути назвою файлу.\n" #: src/console/console.c:1524 #, c-format msgid "Cannot open file %s for input. ERR=%s\n" msgstr "Не вдається відкрити файл %s для введення. ERR=%s\n" #: src/console/console.c:1555 msgid "Too many arguments on output/tee command.\n" msgstr "Забагато параметрів на виході команди.\n" #: src/console/console.c:1572 #, c-format msgid "Cannot open file %s for output. ERR=%s\n" msgstr "Не вдається відкрити файл %s для виведення. ERR=%s\n" #: src/console/console.c:1591 msgid "Too many arguments. Enclose command in double quotes.\n" msgstr "Забагато параметрів. Оточіть комінду подвійними лапками.\n" #: src/console/console.c:1600 #, c-format msgid "Cannot popen(\"%s\", \"r\"): ERR=%s\n" msgstr "" #: src/console/console.c:1612 #, fuzzy, c-format msgid "Autochanger error: ERR=%s\n" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/dird/ndmp_dma_backup.c:81 #, c-format msgid "Illegal Job Level %c for NDMP Job\n" msgstr "" #: src/dird/ndmp_dma_backup.c:89 msgid "" "NDMP dump format doesn't support more than 8 incrementals, please run a " "Differential or a Full Backup\n" msgstr "" #: src/dird/ndmp_dma_backup.c:350 src/dird/migrate.c:289 #: src/dird/migrate.c:290 src/dird/backup.c:107 src/dird/job.c:210 #: src/dird/job.c:1173 src/dird/job.c:1474 src/dird/job.c:1530 #: src/dird/job.c:1549 src/dird/vbackup.c:80 msgid "Pool resource" msgstr "" #: src/dird/ndmp_dma_backup.c:353 src/dird/backup.c:110 msgid "No Storage specification found in Job or Pool.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:374 msgid "" "Write storage doesn't point to storage definition with paired storage " "option.\n" msgstr "" #: src/dird/ndmp_dma_backup.c:406 #, c-format msgid "Start NDMP Backup JobId %s, Job=%s\n" msgstr "" #: src/dird/ndmp_dma_backup.c:758 src/dird/admin.c:77 src/dird/migrate.c:1603 #: src/dird/backup.c:751 src/dird/vbackup.c:340 #, c-format msgid "Error getting Job record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:765 src/dird/backup.c:758 src/dird/vbackup.c:347 #, c-format msgid "Error getting Client record for Job report: ERR=%s" msgstr "" #: src/dird/ndmp_dma_backup.c:773 src/dird/backup.c:766 src/dird/vbackup.c:355 #: src/stored/bscan.c:1262 msgid "Backup OK" msgstr "" #: src/dird/ndmp_dma_backup.c:776 src/dird/backup.c:772 src/dird/vbackup.c:358 #: src/stored/bscan.c:1265 msgid "Backup OK -- with warnings" msgstr "" #: src/dird/ndmp_dma_backup.c:780 src/dird/backup.c:776 src/dird/vbackup.c:362 #: src/stored/bscan.c:1269 msgid "*** Backup Error ***" msgstr "" #: src/dird/ndmp_dma_backup.c:790 src/dird/backup.c:786 src/dird/vbackup.c:372 #: src/stored/bscan.c:1272 msgid "Backup Canceled" msgstr "" #: src/dird/ndmp_dma_backup.c:800 src/dird/admin.c:97 src/dird/backup.c:796 #: src/dird/ndmp_dma_restore.c:948 src/dird/restore.c:501 #: src/dird/vbackup.c:382 #, c-format msgid "Inappropriate term code: %c\n" msgstr "" #: src/dird/ndmp_dma_backup.c:811 src/dird/ndmp_dma_backup.c:817 #: src/dird/ndmp_dma_backup.c:823 src/dird/ndmp_dma_storage.c:70 #: src/dird/ndmp_dma_restore.c:960 src/dird/ndmp_dma_restore.c:966 #: src/dird/ndmp_dma_restore.c:972 src/dird/ndmp_dma_generic.c:609 msgid "NDMP protocol not supported\n" msgstr "" #: src/dird/bsr.c:209 #, c-format msgid "Unable to get Job record. ERR=%s\n" msgstr "" #: src/dird/bsr.c:220 #, c-format msgid "Unable to get Job Volume Parameters. ERR=%s\n" msgstr "" #: src/dird/bsr.c:269 #, c-format msgid "Unable to create bootstrap file %s. ERR=%s\n" msgstr "" #: src/dird/bsr.c:287 msgid "No files found to read. No bootstrap file written.\n" msgstr "" #: src/dird/bsr.c:291 msgid "Error writing bsr file.\n" msgstr "" #: src/dird/bsr.c:296 #, c-format msgid "Bootstrap records written to %s\n" msgstr "" #: src/dird/bsr.c:348 msgid "" "The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n" msgstr "" #: src/dird/bsr.c:376 msgid "No Volumes found to restore.\n" msgstr "" #: src/dird/bsr.c:378 msgid "" "\n" "Volumes marked with \"*\" are online.\n" msgstr "" #: src/dird/bsr.c:730 src/dird/msgchan.c:120 #, c-format msgid "Could not open bootstrap file %s: ERR=%s\n" msgstr "" #: src/dird/bsr.c:787 src/dird/job.c:1911 #, fuzzy, c-format msgid "Could not get storage resource '%s'.\n" msgstr "Не вдалось відновити прапорці для файлу %s: ERR=%s\n" #: src/dird/admin.c:54 #, c-format msgid "Start Admin JobId %d, Job=%s\n" msgstr "" #: src/dird/admin.c:85 msgid "Admin OK" msgstr "" #: src/dird/admin.c:89 msgid "*** Admin Error ***" msgstr "" #: src/dird/admin.c:93 msgid "Admin Canceled" msgstr "" #: src/dird/admin.c:104 msgid "BAREOS " msgstr "" #: src/dird/dird.c:125 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s без сигналів\n" " -t перевірка - прочитати конфігурацію і вийти\n" " -? print this message.\n" "\n" #: src/dird/dird.c:558 msgid "Too many open reload requests. Request ignored.\n" msgstr "" #: src/dird/dird.c:578 msgid "Out of reload table entries. Giving up.\n" msgstr "" #: src/dird/dird.c:582 msgid "Resetting previous configuration.\n" msgstr "" #: src/dird/dird.c:659 #, c-format msgid "" "No Director resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/dird/dird.c:669 src/filed/filed.c:352 #, c-format msgid "No Messages resource defined in %s\n" msgstr "" #: src/dird/dird.c:681 #, c-format msgid "Cannot optimize for speed and size define only one in %s\n" msgstr "" #: src/dird/dird.c:687 #, c-format msgid "Only one Director resource permitted in %s\n" msgstr "" #: src/dird/dird.c:700 src/dird/dird.c:777 src/dird/dird.c:853 #: src/dird/dird.c:901 #, fuzzy msgid "TLS required but not configured in BAREOS.\n" msgstr "TLS необхідний, але не налаштовано у Bareos.\n" #: src/dird/dird.c:709 src/stored/stored.c:427 src/filed/filed.c:537 #, c-format msgid "\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:715 src/stored/stored.c:433 src/filed/filed.c:543 #, c-format msgid "\"TLS Key\" file not defined for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:722 src/stored/stored.c:439 src/filed/filed.c:549 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Director \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:746 src/stored/stored.c:463 src/filed/filed.c:573 #, c-format msgid "Failed to initialize TLS context for Director \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:755 #, c-format msgid "No Job records defined in %s\n" msgstr "" #: src/dird/dird.c:786 #, c-format msgid "\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:793 #, c-format msgid "\"TLS Key\" file not defined for Console \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:801 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Console \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/dird/dird.c:824 src/dird/dird.c:881 src/filed/filed.c:390 #, c-format msgid "Failed to initialize TLS context for File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:860 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:910 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:930 src/stored/stored.c:407 #, c-format msgid "Failed to initialize TLS context for Storage \"%s\" in %s.\n" msgstr "" #: src/dird/dird.c:946 #, c-format msgid "" "Disabling collectstats for storage \"%s\" as other storage already collects " "from this SD.\n" msgstr "" #: src/dird/dird.c:985 #, fuzzy, c-format msgid "Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/dird/dird.c:1026 src/dird/dird.c:1028 #, c-format msgid "Could not open Catalog \"%s\", database \"%s\".\n" msgstr "" #: src/dird/dird.c:1031 src/tests/cats_test.c:376 #, c-format msgid "%s" msgstr "" #: src/dird/dird.c:1110 #, fuzzy, c-format msgid "Could not create storage record for %s\n" msgstr "Не вдалось відновити прапорці для файлу %s: ERR=%s\n" #: src/dird/dird.c:1119 #, fuzzy, c-format msgid "Could not update storage record for %s\n" msgstr "Не вдалось відновити прапорці для файлу %s: ERR=%s\n" #: src/dird/dird.c:1195 src/dird/migrate.c:1420 src/stored/stored.c:524 #, c-format msgid "Could not compile regex pattern \"%s\" ERR=%s\n" msgstr "" #: src/dird/autoprune.c:67 msgid "" "End auto prune.\n" "\n" msgstr "" #: src/dird/dbcheck.c:194 msgid "" "Warning skipping the additional parameters for working directory/dbname/user/" "password/host.\n" msgstr "" #: src/dird/dbcheck.c:211 #, c-format msgid "Error can not find the Catalog name[%s] in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:213 #, c-format msgid "Error there is no Catalog section in the given config file [%s]\n" msgstr "" #: src/dird/dbcheck.c:221 msgid "Error no Director resource defined.\n" msgstr "" #: src/dird/dbcheck.c:250 msgid "Wrong number of arguments.\n" msgstr "" #: src/dird/dbcheck.c:255 msgid "Working directory not supplied.\n" msgstr "" #: src/dird/dbcheck.c:291 msgid "Database port must be a numeric value.\n" msgstr "" #: src/dird/dbcheck.c:294 msgid "Database port must be a int value.\n" msgstr "" #: src/dird/dbcheck.c:388 #, c-format msgid "Hello, this is the database check/correct program.\n" msgstr "" #: src/dird/dbcheck.c:390 #, c-format msgid "Modify database is on." msgstr "" #: src/dird/dbcheck.c:392 #, c-format msgid "Modify database is off." msgstr "" #: src/dird/dbcheck.c:394 src/dird/dbcheck.c:455 #, c-format msgid " Verbose is on.\n" msgstr "" #: src/dird/dbcheck.c:396 src/dird/dbcheck.c:457 #, c-format msgid " Verbose is off.\n" msgstr "" #: src/dird/dbcheck.c:398 #, c-format msgid "Please select the function you want to perform.\n" msgstr "" #: src/dird/dbcheck.c:402 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:421 #, c-format msgid "" "\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n" msgstr "" #: src/dird/dbcheck.c:441 msgid "Select function number: " msgstr "" #: src/dird/dbcheck.c:448 #, c-format msgid "Database will be modified.\n" msgstr "" #: src/dird/dbcheck.c:450 #, c-format msgid "Database will NOT be modified.\n" msgstr "" #: src/dird/dbcheck.c:541 #, c-format msgid "JobId=%s Name=\"%s\" StartTime=%s\n" msgstr "" #: src/dird/dbcheck.c:548 #, c-format msgid "Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:555 #, c-format msgid "Orphaned FileId=%s JobId=%s Volume=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:562 #, c-format msgid "Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n" msgstr "" #: src/dird/dbcheck.c:569 #, c-format msgid "Orphaned ClientId=%s Name=\"%s\"\n" msgstr "" #: src/dird/dbcheck.c:622 #, c-format msgid "Deleting: %s\n" msgstr "" #: src/dird/dbcheck.c:694 #, c-format msgid "Checking for duplicate Filename entries.\n" msgstr "" #: src/dird/dbcheck.c:705 #, c-format msgid "Found %d duplicate Filename records.\n" msgstr "" #: src/dird/dbcheck.c:706 msgid "Print the list? (yes/no): " msgstr "" #: src/dird/dbcheck.c:729 src/dird/dbcheck.c:794 #, c-format msgid "Found %d for: %s\n" msgstr "" #: src/dird/dbcheck.c:759 #, c-format msgid "Checking for duplicate Path entries.\n" msgstr "" #: src/dird/dbcheck.c:770 #, c-format msgid "Found %d duplicate Path records.\n" msgstr "" #: src/dird/dbcheck.c:771 src/dird/dbcheck.c:833 src/dird/dbcheck.c:879 #: src/dird/dbcheck.c:947 src/dird/dbcheck.c:1005 src/dird/dbcheck.c:1048 #: src/dird/dbcheck.c:1090 src/dird/dbcheck.c:1132 src/dird/dbcheck.c:1169 #: src/dird/dbcheck.c:1202 src/dird/dbcheck.c:1236 src/dird/dbcheck.c:1303 msgid "Print them? (yes/no): " msgstr "" #: src/dird/dbcheck.c:824 #, c-format msgid "Checking for orphaned JobMedia entries.\n" msgstr "" #: src/dird/dbcheck.c:832 #, c-format msgid "Found %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:850 #, c-format msgid "Deleting %d orphaned JobMedia records.\n" msgstr "" #: src/dird/dbcheck.c:867 #, c-format msgid "Checking for orphaned File entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:878 #, c-format msgid "Found %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:895 #, c-format msgid "Deleting %d orphaned File records.\n" msgstr "" #: src/dird/dbcheck.c:914 #, c-format msgid "Pruning orphaned Path entries isn't possible when using BVFS.\n" msgstr "" #: src/dird/dbcheck.c:923 src/dird/dbcheck.c:981 msgid "Create temporary index? (yes/no): " msgstr "" #: src/dird/dbcheck.c:935 #, c-format msgid "Checking for orphaned Path entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:946 #, c-format msgid "Found %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:959 #, c-format msgid "Deleting %d orphaned Path records.\n" msgstr "" #: src/dird/dbcheck.c:993 #, c-format msgid "Checking for orphaned Filename entries. This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1004 #, c-format msgid "Found %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1017 #, c-format msgid "Deleting %d orphaned Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1037 #, c-format msgid "Checking for orphaned FileSet entries. This takes some time!\n" msgstr "" #: src/dird/dbcheck.c:1047 #, c-format msgid "Found %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1062 #, c-format msgid "Deleting %d orphaned FileSet records.\n" msgstr "" #: src/dird/dbcheck.c:1071 #, c-format msgid "Checking for orphaned Client entries.\n" msgstr "" #: src/dird/dbcheck.c:1089 #, c-format msgid "Found %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1104 #, c-format msgid "Deleting %d orphaned Client records.\n" msgstr "" #: src/dird/dbcheck.c:1113 #, c-format msgid "Checking for orphaned Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1131 #, c-format msgid "Found %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1146 #, c-format msgid "Deleting %d orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1148 #, c-format msgid "Deleting JobMedia records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1150 #, c-format msgid "Deleting Log records of orphaned Job records.\n" msgstr "" #: src/dird/dbcheck.c:1159 #, c-format msgid "Checking for Admin Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1168 #, c-format msgid "Found %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1183 #, c-format msgid "Deleting %d Admin Job records.\n" msgstr "" #: src/dird/dbcheck.c:1192 #, c-format msgid "Checking for Restore Job entries.\n" msgstr "" #: src/dird/dbcheck.c:1201 #, c-format msgid "Found %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1216 #, c-format msgid "Deleting %d Restore Job records.\n" msgstr "" #: src/dird/dbcheck.c:1226 #, c-format msgid "Checking for Filenames with a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1235 #, c-format msgid "Found %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1253 src/dird/dbcheck.c:1319 #, c-format msgid "Reparing %d bad Filename records.\n" msgstr "" #: src/dird/dbcheck.c:1293 #, c-format msgid "Checking for Paths without a trailing slash\n" msgstr "" #: src/dird/dbcheck.c:1302 #, c-format msgid "Found %d bad Path records.\n" msgstr "" #: src/dird/dbcheck.c:1375 src/dird/ua_run.c:463 src/dird/ua_run.c:508 #: src/dird/backup.c:1054 src/dird/backup.c:1055 src/dird/backup.c:1056 #: src/dird/backup.c:1065 src/dird/backup.c:1066 src/dird/backup.c:1067 #: src/dird/ua_input.c:120 src/dird/ua_update.c:257 src/dird/ua_update.c:277 #: src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "yes" msgstr "" #: src/dird/dbcheck.c:1463 #, c-format msgid "" "Ok. Index over the %s column already exists and dbcheck will work faster.\n" msgstr "" #: src/dird/dbcheck.c:1466 #, c-format msgid "" "Note. Index over the %s column not found, that can greatly slow down " "dbcheck.\n" msgstr "" #: src/dird/dbcheck.c:1481 #, c-format msgid "Create temporary index... This may take some time!\n" msgstr "" #: src/dird/dbcheck.c:1489 #, c-format msgid "Temporary index created.\n" msgstr "" #: src/dird/dbcheck.c:1504 #, c-format msgid "Drop temporary index.\n" msgstr "" #: src/dird/dbcheck.c:1514 #, c-format msgid "Temporary index %s deleted.\n" msgstr "" #: src/dird/quota.c:118 src/dird/quota.c:125 src/dird/quota.c:175 #: src/dird/quota.c:183 #, fuzzy, c-format msgid "Error getting Quota value: ERR=%s" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/dird/quota.c:187 msgid "Quota does NOT include Failed Jobs\n" msgstr "" #: src/dird/quota.c:207 #, fuzzy, c-format msgid "Error setting Quota gracetime: ERR=%s" msgstr "Не вдалося надіслати Hello до Зберігача. ERR=%s\n" #: src/dird/quota.c:210 msgid "Softquota Exceeded, Grace Period starts now.\n" msgstr "" #: src/dird/quota.c:216 msgid "Softquota Exceeded, will be enforced after Grace Period expires.\n" msgstr "" #: src/dird/quota.c:224 #, fuzzy, c-format msgid "Error setting Quota Softlimit: ERR=%s" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/dird/quota.c:227 msgid "Softquota Exceeded and Grace Period expired.\n" msgstr "" #: src/dird/quota.c:228 #, c-format msgid "Setting Burst Quota to %d Bytes.\n" msgstr "" #: src/dird/quota.c:247 msgid "Softquota Exceeded, enforcing Burst Quota Limit.\n" msgstr "" #: src/dird/ua_run.c:58 #, fuzzy, c-format msgid "Error getting Job record for Job rerun: ERR=%s" msgstr "Не вдалось відновити прапорці для файлу %s: ERR=%s\n" #: src/dird/ua_run.c:88 #, c-format msgid "Error getting Client record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:102 #, c-format msgid "Error getting Pool record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:170 #, c-format msgid "Error getting FileSet record for Job rerun: ERR=%s" msgstr "" #: src/dird/ua_run.c:312 msgid "rerun these jobids? (yes/no): " msgstr "" #: src/dird/ua_run.c:446 msgid "OK to run? (yes/mod/no): " msgstr "" #: src/dird/ua_run.c:465 src/dird/backup.c:1054 src/dird/backup.c:1055 #: src/dird/backup.c:1056 src/dird/backup.c:1065 src/dird/backup.c:1066 #: src/dird/backup.c:1067 src/dird/ua_input.c:124 src/dird/ua_update.c:257 #: src/dird/ua_update.c:277 src/dird/ua_update.c:713 src/lib/parse_bsr.c:943 msgid "no" msgstr "" #: src/dird/ua_run.c:470 #, c-format msgid "Illegal response %s\n" msgstr "" #: src/dird/ua_run.c:525 msgid "Job failed.\n" msgstr "" #: src/dird/ua_run.c:528 #, c-format msgid "Job queued. JobId=%s\n" msgstr "" #: src/dird/ua_run.c:535 msgid "Job not run.\n" msgstr "" #: src/dird/ua_run.c:547 src/dird/ua_select.c:54 msgid "mod" msgstr "" #: src/dird/ua_run.c:548 src/dird/ua_update.c:619 msgid "Parameters to modify:\n" msgstr "" #: src/dird/ua_run.c:550 msgid "Level" msgstr "" #: src/dird/ua_run.c:551 src/dird/ua_dotcmds.c:767 src/dird/ua_cmds.c:1411 #: src/dird/ua_select.c:168 msgid "Storage" msgstr "" #: src/dird/ua_run.c:552 src/dird/ua_select.c:265 src/dird/ua_select.c:288 #: src/dird/ua_select.c:328 src/dird/ua_select.c:1444 src/dird/ua_prune.c:810 msgid "Job" msgstr "" #: src/dird/ua_run.c:553 src/dird/ua_select.c:191 src/dird/ua_restore.c:1344 msgid "FileSet" msgstr "" #: src/dird/ua_run.c:555 msgid "Restore Client" msgstr "" #: src/dird/ua_run.c:557 src/dird/ua_dotcmds.c:768 src/dird/ua_cmds.c:1412 #: src/dird/ua_select.c:351 src/dird/ua_select.c:378 src/dird/ua_select.c:514 msgid "Client" msgstr "" #: src/dird/ua_run.c:559 msgid "Backup Format" msgstr "" #: src/dird/ua_run.c:560 msgid "When" msgstr "" #: src/dird/ua_run.c:561 msgid "Priority" msgstr "" #: src/dird/ua_run.c:566 src/dird/ua_select.c:602 src/dird/ua_select.c:720 #: src/dird/ua_update.c:630 msgid "Pool" msgstr "" #: src/dird/ua_run.c:571 msgid "NextPool" msgstr "" #: src/dird/ua_run.c:573 src/dird/ua_run.c:578 src/dird/ua_run.c:586 msgid "Plugin Options" msgstr "" #: src/dird/ua_run.c:576 msgid "Verify Job" msgstr "" #: src/dird/ua_run.c:581 msgid "Bootstrap" msgstr "" #: src/dird/ua_run.c:582 msgid "Where" msgstr "" #: src/dird/ua_run.c:583 msgid "File Relocation" msgstr "" #: src/dird/ua_run.c:584 msgid "Replace" msgstr "" #: src/dird/ua_run.c:585 msgid "JobId" msgstr "" #: src/dird/ua_run.c:589 src/dird/ua_run.c:1025 src/dird/ua_update.c:638 msgid "Select parameter to modify" msgstr "" #: src/dird/ua_run.c:607 src/dird/ua_run.c:2064 msgid "user selection" msgstr "" #: src/dird/ua_run.c:639 msgid "Please enter Backup Format: " msgstr "" #: src/dird/ua_run.c:650 msgid "" "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): " msgstr "" #: src/dird/ua_run.c:656 src/dird/ua_run.c:886 msgid "Invalid time, using current time.\n" msgstr "" #: src/dird/ua_run.c:665 msgid "Enter new Priority: " msgstr "" #: src/dird/ua_run.c:667 msgid "Priority must be a positive integer.\n" msgstr "" #: src/dird/ua_run.c:688 msgid "Please enter the Bootstrap file name: " msgstr "" #: src/dird/ua_run.c:700 #, c-format msgid "Warning cannot open %s: ERR=%s\n" msgstr "" #: src/dird/ua_run.c:730 msgid "Please enter the full path prefix for restore (/ for none): " msgstr "" #: src/dird/ua_run.c:746 src/dird/ua_run.c:762 src/dird/ua_run.c:794 msgid "Please enter Plugin Options string: " msgstr "" #: src/dird/ua_run.c:774 msgid "Replace:\n" msgstr "" #: src/dird/ua_run.c:778 msgid "Select replace option" msgstr "" #: src/dird/ua_run.c:789 msgid "" "You must set the bootstrap file to NULL to be able to specify a JobId.\n" msgstr "" #: src/dird/ua_run.c:838 src/dird/ua_run.c:846 src/dird/ua_run.c:2058 #: src/dird/ua_status.c:1503 src/dird/ua_impexp.c:1036 src/dird/ua_label.c:150 #: src/dird/ua_update.c:1015 msgid "command line" msgstr "" #: src/dird/ua_run.c:841 src/dird/ua_run.c:849 src/dird/ua_run.c:862 msgid "user input" msgstr "" #: src/dird/ua_run.c:916 #, c-format msgid "Invalid replace option: %s\n" msgstr "" #: src/dird/ua_run.c:951 src/dird/migrate.c:359 src/dird/vbackup.c:96 msgid "Storage from Run NextPool override" msgstr "" #: src/dird/ua_run.c:964 src/dird/ua_cmds.c:1650 #, c-format msgid "Level \"%s\" not valid.\n" msgstr "" #: src/dird/ua_run.c:1014 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s\n" msgstr "" #: src/dird/ua_run.c:1017 msgid "This will replace your current Where value\n" msgstr "" #: src/dird/ua_run.c:1018 msgid "Strip prefix" msgstr "" #: src/dird/ua_run.c:1019 msgid "Add prefix" msgstr "" #: src/dird/ua_run.c:1020 msgid "Add file suffix" msgstr "" #: src/dird/ua_run.c:1021 msgid "Enter a regexp" msgstr "" #: src/dird/ua_run.c:1022 msgid "Test filename manipulation" msgstr "" #: src/dird/ua_run.c:1023 msgid "Use this ?" msgstr "" #: src/dird/ua_run.c:1028 msgid "Please enter the path prefix to strip: " msgstr "" #: src/dird/ua_run.c:1035 msgid "Please enter the path prefix to add (/ for none): " msgstr "" #: src/dird/ua_run.c:1046 msgid "Please enter the file suffix to add: " msgstr "" #: src/dird/ua_run.c:1053 msgid "Please enter a valid regexp (!from!to!): " msgstr "" #: src/dird/ua_run.c:1065 #, c-format msgid "regexwhere=%s\n" msgstr "" #: src/dird/ua_run.c:1071 #, c-format msgid "strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n" msgstr "" #: src/dird/ua_run.c:1078 msgid "Cannot use your regexp\n" msgstr "" #: src/dird/ua_run.c:1081 msgid "Enter a period (.) to stop this test\n" msgstr "" #: src/dird/ua_run.c:1082 msgid "Please enter filename to test: " msgstr "" #: src/dird/ua_run.c:1084 #, c-format msgid "%s -> %s\n" msgstr "" #: src/dird/ua_run.c:1127 msgid "Cannot use your regexp.\n" msgstr "" #: src/dird/ua_run.c:1148 src/dird/ua_run.c:1178 msgid "Levels:\n" msgstr "" #: src/dird/ua_run.c:1150 src/stored/status.c:872 src/lib/util.c:455 #: src/lib/util.c:501 src/filed/status.c:531 msgid "Full" msgstr "" #: src/dird/ua_run.c:1151 src/stored/status.c:875 src/lib/util.c:458 #: src/filed/status.c:534 msgid "Incremental" msgstr "" #: src/dird/ua_run.c:1152 src/stored/status.c:878 src/lib/util.c:461 #: src/filed/status.c:537 msgid "Differential" msgstr "" #: src/dird/ua_run.c:1153 src/stored/status.c:881 src/lib/util.c:464 #: src/filed/status.c:540 msgid "Since" msgstr "" #: src/dird/ua_run.c:1154 msgid "VirtualFull" msgstr "" #: src/dird/ua_run.c:1155 src/dird/ua_run.c:1184 msgid "Select level" msgstr "" #: src/dird/ua_run.c:1179 msgid "Initialize Catalog" msgstr "" #: src/dird/ua_run.c:1180 src/stored/status.c:884 src/lib/util.c:467 #: src/filed/status.c:543 msgid "Verify Catalog" msgstr "" #: src/dird/ua_run.c:1181 src/lib/util.c:473 msgid "Verify Volume to Catalog" msgstr "" #: src/dird/ua_run.c:1182 src/lib/util.c:476 msgid "Verify Disk to Catalog" msgstr "" #: src/dird/ua_run.c:1183 msgid "Verify Volume Data (not yet implemented)" msgstr "" #: src/dird/ua_run.c:1204 msgid "Level not appropriate for this Job. Cannot be changed.\n" msgstr "" #: src/dird/ua_run.c:1232 src/dird/ua_run.c:1246 src/dird/ua_run.c:1279 #: src/dird/ua_run.c:1281 src/dird/ua_run.c:1307 src/dird/ua_run.c:1311 #: src/dird/ua_run.c:1559 src/dird/ua_run.c:1592 src/dird/ua_run.c:1593 #: src/dird/ua_run.c:1594 src/dird/ua_run.c:1618 src/dird/ua_run.c:1620 #: src/dird/ua_run.c:1622 src/dird/migrate.c:1747 src/dird/migrate.c:1751 #: src/dird/migrate.c:1752 src/dird/migrate.c:1754 src/dird/migrate.c:1757 #: src/dird/migrate.c:1759 src/dird/migrate.c:1770 src/dird/ua_dotcmds.c:1234 #: src/dird/ua_dotcmds.c:1240 src/dird/ua_dotcmds.c:1242 #: src/dird/ua_select.c:591 src/dird/ua_select.c:611 src/dird/ua_update.c:365 #: src/include/baconfig.h:88 msgid "*None*" msgstr "" #: src/dird/ua_run.c:1236 #, c-format msgid "" "Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1288 #, c-format msgid "" "Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%sStorage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s" msgstr "" #: src/dird/ua_run.c:1328 #, fuzzy, c-format msgid "Could not get job record for selected JobId. ERR=%s" msgstr "Не вдалось відновити прапорці для файлу %s: ERR=%s\n" #: src/dird/ua_run.c:1367 #, c-format msgid "" "Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1396 msgid "Please enter a JobId for restore: " msgstr "" #: src/dird/ua_run.c:1438 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1498 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1531 #, c-format msgid "" "Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" msgstr "" #: src/dird/ua_run.c:1539 #, c-format msgid "RegexWhere: %s\n" msgstr "" #: src/dird/ua_run.c:1542 #, c-format msgid "Where: %s\n" msgstr "" #: src/dird/ua_run.c:1546 #, c-format msgid "" "Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n" msgstr "" #: src/dird/ua_run.c:1574 msgid "" "Type: Copy\n" "Title: Run Copy Job\n" msgstr "" #: src/dird/ua_run.c:1576 msgid "" "Type: Migration\n" "Title: Run Migration Job\n" msgstr "" #: src/dird/ua_run.c:1578 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1600 msgid "Run Copy job\n" msgstr "" #: src/dird/ua_run.c:1602 msgid "Run Migration job\n" msgstr "" #: src/dird/ua_run.c:1604 #, c-format msgid "" "%sJobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" msgstr "" #: src/dird/ua_run.c:1629 #, c-format msgid "Unknown Job Type=%d\n" msgstr "" #: src/dird/ua_run.c:1706 #, c-format msgid "Value missing for keyword %s\n" msgstr "" #: src/dird/ua_run.c:1713 msgid "Job name specified twice.\n" msgstr "" #: src/dird/ua_run.c:1721 msgid "JobId specified twice.\n" msgstr "" #: src/dird/ua_run.c:1730 src/dird/ua_run.c:1878 msgid "Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1738 msgid "FileSet specified twice.\n" msgstr "" #: src/dird/ua_run.c:1746 msgid "Level specified twice.\n" msgstr "" #: src/dird/ua_run.c:1755 msgid "Storage specified twice.\n" msgstr "" #: src/dird/ua_run.c:1763 msgid "RegexWhere or Where specified twice.\n" msgstr "" #: src/dird/ua_run.c:1768 msgid "No authorization for \"regexwhere\" specification.\n" msgstr "" #: src/dird/ua_run.c:1775 msgid "Where or RegexWhere specified twice.\n" msgstr "" #: src/dird/ua_run.c:1780 msgid "No authoriztion for \"where\" specification.\n" msgstr "" #: src/dird/ua_run.c:1787 msgid "Bootstrap specified twice.\n" msgstr "" #: src/dird/ua_run.c:1795 msgid "Replace specified twice.\n" msgstr "" #: src/dird/ua_run.c:1803 msgid "When specified twice.\n" msgstr "" #: src/dird/ua_run.c:1811 msgid "Priority specified twice.\n" msgstr "" #: src/dird/ua_run.c:1816 msgid "Priority must be positive nonzero setting it to 10.\n" msgstr "" #: src/dird/ua_run.c:1826 msgid "Verify Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1854 msgid "Migration Job specified twice.\n" msgstr "" #: src/dird/ua_run.c:1862 msgid "Pool specified twice.\n" msgstr "" #: src/dird/ua_run.c:1870 #, fuzzy msgid "NextPool specified twice.\n" msgstr "зазначений час сну" #: src/dird/ua_run.c:1886 msgid "Restore Client specified twice.\n" msgstr "" #: src/dird/ua_run.c:1894 msgid "Plugin Options specified twice.\n" msgstr "" #: src/dird/ua_run.c:1899 msgid "No authorization for \"PluginOptions\" specification.\n" msgstr "" #: src/dird/ua_run.c:1906 msgid "Spool flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1913 msgid "Invalid spooldata flag.\n" msgstr "" #: src/dird/ua_run.c:1922 msgid "IgnoreDuplicateCheck flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1929 msgid "Invalid ignoreduplicatecheck flag.\n" msgstr "" #: src/dird/ua_run.c:1934 msgid "Accurate flag specified twice.\n" msgstr "" #: src/dird/ua_run.c:1941 msgid "Invalid accurate flag.\n" msgstr "" #: src/dird/ua_run.c:1946 msgid "Backup Format specified twice.\n" msgstr "" #: src/dird/ua_run.c:1971 #, c-format msgid "Invalid keyword: %s\n" msgstr "" #: src/dird/ua_run.c:1986 #, c-format msgid "Catalog \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:1990 #, c-format msgid "No authorization. Catalog \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2001 #, c-format msgid "Job \"%s\" not found\n" msgstr "" #: src/dird/ua_run.c:2008 msgid "A job name must be specified.\n" msgstr "" #: src/dird/ua_run.c:2014 #, c-format msgid "No authorization. Job \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2022 src/dird/ua_run.c:2041 #, c-format msgid "Pool \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2032 src/dird/ua_run.c:2050 #, c-format msgid "No authorization. Pool \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2061 src/dird/ua_cmds.c:1483 #, c-format msgid "Storage \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2080 src/dird/job.c:1629 msgid "No storage specified.\n" msgstr "" #: src/dird/ua_run.c:2083 #, c-format msgid "No authorization. Storage \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2094 src/dird/ua_cmds.c:956 src/dird/ua_cmds.c:995 #: src/dird/ua_cmds.c:1014 src/dird/ua_cmds.c:1464 src/dird/ua_cmds.c:1591 #, c-format msgid "Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2103 src/dird/ua_run.c:2121 #, c-format msgid "No authorization. Client \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2112 #, c-format msgid "Restore Client \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2130 #, c-format msgid "FileSet \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2138 #, c-format msgid "No authorization. FileSet \"%s\".\n" msgstr "" #: src/dird/ua_run.c:2145 #, c-format msgid "Verify Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_run.c:2155 #, c-format msgid "Migration Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_status.c:225 msgid "Status available for:\n" msgstr "" #: src/dird/ua_status.c:232 msgid "Select daemon type for status" msgstr "" #: src/dird/ua_status.c:387 src/stored/status.c:363 #, c-format msgid "%s Version: %s (%s) %s %s %s\n" msgstr "" #: src/dird/ua_status.c:390 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d mode=%d\n" msgstr "" #: src/dird/ua_status.c:392 src/stored/status.c:419 src/filed/status.c:142 #, c-format msgid " Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n" msgstr "" #: src/dird/ua_status.c:555 msgid "No subscriptions configured in director.\n" msgstr "" #: src/dird/ua_status.c:561 #, fuzzy msgid "No clients defined.\n" msgstr "Ресурс %s не визначено\n" #: src/dird/ua_status.c:566 #, c-format msgid "Warning! No available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:569 #, c-format msgid "Ok: available subscriptions: %d (%d/%d) (used/total)\n" msgstr "" #: src/dird/ua_status.c:602 msgid "Ignoring invalid value for days. Allowed is -366 < days < 366.\n" msgstr "" #: src/dird/ua_status.c:774 msgid "Date" msgstr "" #: src/dird/ua_status.c:774 src/dird/ua_select.c:432 msgid "Schedule" msgstr "" #: src/dird/ua_status.c:774 msgid "Overrides" msgstr "" #: src/dird/ua_status.c:804 msgid "" "\n" "Scheduled Jobs:\n" msgstr "" #: src/dird/ua_status.c:805 msgid "" "Level Type Pri Scheduled Name Volume\n" msgstr "" #: src/dird/ua_status.c:806 msgid "===================================================================================\n" msgstr "" #: src/dird/ua_status.c:864 #, c-format msgid "%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n" msgstr "" #: src/dird/ua_status.c:868 #, c-format msgid "%-14s %-8s %3d %-18s %-18s %s\n" msgstr "" #: src/dird/ua_status.c:924 msgid "Ignoring invalid value for days. Max is 500.\n" msgstr "" #: src/dird/ua_status.c:971 msgid "No Scheduled Jobs.\n" msgstr "" #: src/dird/ua_status.c:988 src/stored/status.c:627 src/filed/status.c:171 msgid "" "\n" "Running Jobs:\n" msgstr "" #: src/dird/ua_status.c:996 #, c-format msgid "Console connected at %s\n" msgstr "" #: src/dird/ua_status.c:1006 msgid "" "No Jobs running.\n" "====\n" msgstr "" #: src/dird/ua_status.c:1012 msgid " JobId Level Name Status\n" msgstr "" #: src/dird/ua_status.c:1013 src/filed/status.c:341 msgid "======================================================================\n" msgstr "" #: src/dird/ua_status.c:1022 msgid "is waiting execution" msgstr "" #: src/dird/ua_status.c:1025 msgid "is running" msgstr "" #: src/dird/ua_status.c:1028 msgid "is blocked" msgstr "" #: src/dird/ua_status.c:1031 msgid "has terminated" msgstr "" #: src/dird/ua_status.c:1034 msgid "has terminated with warnings" msgstr "" #: src/dird/ua_status.c:1037 msgid "has erred" msgstr "" #: src/dird/ua_status.c:1040 msgid "has errors" msgstr "" #: src/dird/ua_status.c:1043 msgid "has a fatal error" msgstr "" #: src/dird/ua_status.c:1046 msgid "has verify differences" msgstr "" #: src/dird/ua_status.c:1049 msgid "has been canceled" msgstr "" #: src/dird/ua_status.c:1054 msgid "is waiting on Client" msgstr "" #: src/dird/ua_status.c:1056 #, c-format msgid "is waiting on Client %s" msgstr "" #: src/dird/ua_status.c:1064 src/dird/ua_status.c:1066 #, fuzzy, c-format msgid "is waiting on Storage \"%s\"" msgstr "Від'єднуюсь від Зберігача %s:%d\n" #: src/dird/ua_status.c:1068 msgid "is waiting on Storage" msgstr "" #: src/dird/ua_status.c:1074 msgid "is waiting on max Storage jobs" msgstr "" #: src/dird/ua_status.c:1077 msgid "is waiting on max Client jobs" msgstr "" #: src/dird/ua_status.c:1080 msgid "is waiting on max Job jobs" msgstr "" #: src/dird/ua_status.c:1083 msgid "is waiting on max total jobs" msgstr "" #: src/dird/ua_status.c:1090 #, fuzzy, c-format msgid "is waiting for its start time at %s" msgstr "Статус задачі: Очікування часу початку" #: src/dird/ua_status.c:1092 msgid "is waiting for its start time" msgstr "" #: src/dird/ua_status.c:1098 msgid "is waiting for higher priority jobs to finish" msgstr "" #: src/dird/ua_status.c:1101 src/dird/ua_status.c:1152 src/lib/util.c:271 msgid "SD committing Data" msgstr "" #: src/dird/ua_status.c:1104 src/dird/ua_status.c:1155 src/lib/util.c:274 msgid "SD despooling Data" msgstr "" #: src/dird/ua_status.c:1107 src/dird/ua_status.c:1158 src/lib/util.c:277 msgid "SD despooling Attributes" msgstr "" #: src/dird/ua_status.c:1110 src/dird/ua_status.c:1161 src/lib/util.c:280 msgid "Dir inserting Attributes" msgstr "" #: src/dird/ua_status.c:1115 #, c-format msgid "is in unknown state %c" msgstr "" #: src/dird/ua_status.c:1129 msgid "is waiting for a mount request" msgstr "" #: src/dird/ua_status.c:1136 msgid "is waiting for an appendable Volume" msgstr "" #: src/dird/ua_status.c:1144 msgid "is waiting for Client to connect to Storage daemon" msgstr "" #: src/dird/ua_status.c:1146 #, c-format msgid "is waiting for Client %s to connect to Storage %s" msgstr "" #: src/dird/ua_status.c:1177 #, c-format msgid "%6d\t%-6s\t%-20s\t%s\t%s\n" msgstr "" #: src/dird/ua_status.c:1181 #, c-format msgid "%6d %-6s %-20s %s\n" msgstr "" #: src/dird/ua_status.c:1185 #, c-format msgid " %-30s\n" msgstr "" #: src/dird/ua_status.c:1205 msgid "No Terminated Jobs.\n" msgstr "" #: src/dird/ua_status.c:1211 src/stored/status.c:762 src/filed/status.c:324 msgid "" "\n" "Terminated Jobs:\n" msgstr "" #: src/dird/ua_status.c:1212 src/stored/status.c:777 src/filed/status.c:339 msgid " JobId Level Files Bytes Status Finished Name \n" msgstr "" #: src/dird/ua_status.c:1213 msgid "====================================================================\n" msgstr "" #: src/dird/ua_status.c:1245 src/stored/status.c:800 src/lib/util.c:208 #: src/filed/status.c:365 msgid "Created" msgstr "" #: src/dird/ua_status.c:1249 src/stored/status.c:804 src/lib/util.c:226 #: src/lib/util.c:360 src/lib/util.c:507 src/filed/status.c:369 msgid "Error" msgstr "" #: src/dird/ua_status.c:1252 src/stored/status.c:807 src/filed/status.c:372 msgid "Diffs" msgstr "" #: src/dird/ua_status.c:1255 src/dird/ua_restore.c:484 src/stored/status.c:810 #: src/filed/status.c:375 msgid "Cancel" msgstr "" #: src/dird/ua_status.c:1258 src/stored/btape.c:1540 src/stored/status.c:813 #: src/lib/util.c:217 src/lib/util.c:353 src/filed/status.c:378 msgid "OK" msgstr "" #: src/dird/ua_status.c:1261 src/stored/status.c:816 src/lib/util.c:232 #: src/lib/util.c:356 msgid "OK -- with warnings" msgstr "" #: src/dird/ua_status.c:1264 src/stored/status.c:819 src/filed/status.c:381 msgid "Other" msgstr "" #: src/dird/ua_status.c:1268 src/stored/status.c:831 src/filed/status.c:396 #, c-format msgid "%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n" msgstr "" #: src/dird/ua_status.c:1276 src/stored/status.c:840 src/filed/status.c:405 #, c-format msgid "%6d %-6s %8s %10s %-7s %-8s %s\n" msgstr "" #: src/dird/ua_status.c:1285 msgid "\n" msgstr "" #: src/dird/ua_status.c:1370 src/dird/ua_status.c:1521 #: src/dird/ua_impexp.c:1068 msgid "No Volumes found, or no barcodes.\n" msgstr "" #: src/dird/ua_status.c:1508 src/dird/ua_label.c:364 src/dird/ua_update.c:1035 msgid "No slots in changer to scan.\n" msgstr "" #: src/dird/ua_status.c:1524 msgid "" " Slot | Volume Name | Status | Media Type | " "Pool |\n" msgstr "" #: src/dird/ua_status.c:1525 msgid "" "------+------------------+-----------+----------------" "+--------------------------|\n" msgstr "" #: src/dird/ua_status.c:1541 src/dird/ua_update.c:1063 #, c-format msgid "Slot %d greater than max %d ignored.\n" msgstr "" #: src/dird/msgchan.c:159 #, fuzzy, c-format msgid "Storage daemon rejected Plugin Options command: %s\n" msgstr "Зберігач відхилив команду Hello\n" #: src/dird/msgchan.c:229 #, c-format msgid "Storage daemon rejected Job command: %s\n" msgstr "" #: src/dird/msgchan.c:237 #, c-format msgid " set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n" msgstr "" #: src/dird/testfind.c:227 #, c-format msgid "" "\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n" msgstr "" #: src/dird/testfind.c:270 #, c-format msgid "Reg: %s\n" msgstr "" #: src/dird/testfind.c:292 msgid "\t[will not descend: recursion turned off]" msgstr "" #: src/dird/testfind.c:294 msgid "\t[will not descend: file system change not allowed]" msgstr "" #: src/dird/testfind.c:296 msgid "\t[will not descend: disallowed file system]" msgstr "" #: src/dird/testfind.c:298 msgid "\t[will not descend: disallowed drive type]" msgstr "" #: src/dird/testfind.c:314 src/tests/testls.c:206 #, c-format msgid "Err: Could not access %s: %s\n" msgstr "" #: src/dird/testfind.c:317 src/tests/testls.c:209 #, c-format msgid "Err: Could not follow ff->link %s: %s\n" msgstr "" #: src/dird/testfind.c:320 src/tests/testls.c:212 #, c-format msgid "Err: Could not stat %s: %s\n" msgstr "" #: src/dird/testfind.c:323 src/tests/testls.c:215 #, c-format msgid "Skip: File not saved. No change. %s\n" msgstr "" #: src/dird/testfind.c:326 src/tests/testls.c:218 #, c-format msgid "Err: Attempt to backup archive. Not saved. %s\n" msgstr "" #: src/dird/testfind.c:329 src/tests/testls.c:227 #, c-format msgid "Err: Could not open directory %s: %s\n" msgstr "" #: src/dird/testfind.c:332 src/tests/testls.c:230 #, c-format msgid "Err: Unknown file ff->type %d: %s\n" msgstr "" #: src/dird/testfind.c:382 #, c-format msgid "===== Filename truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:398 #, c-format msgid "========== Path name truncated to 255 chars: %s\n" msgstr "" #: src/dird/testfind.c:406 #, c-format msgid "========== Path length is zero. File=%s\n" msgstr "" #: src/dird/testfind.c:409 #, c-format msgid "Path: %s\n" msgstr "" #: src/dird/testfind.c:410 src/dird/verify.c:917 #, c-format msgid "File: %s\n" msgstr "" #: src/dird/testfind.c:645 src/dird/dird_conf.c:1483 src/findlib/match.c:301 #: src/filed/fileset.c:714 #, c-format msgid "Unknown include/exclude option: %c\n" msgstr "Не зрозуміла опція параметру include/exclude: %c\n" #: src/dird/expand.c:268 #, c-format msgid "Count not update counter %s: ERR=%s\n" msgstr "Лічильник %s не оновлено: ERR=%s\n" #: src/dird/expand.c:472 #, c-format msgid "Cannot create var context: ERR=%s\n" msgstr "" #: src/dird/expand.c:480 #, c-format msgid "Cannot set var callback: ERR=%s\n" msgstr "" #: src/dird/expand.c:488 #, c-format msgid "Cannot set var operate: ERR=%s\n" msgstr "" #: src/dird/expand.c:496 src/dird/expand.c:514 #, c-format msgid "Cannot unescape string: ERR=%s\n" msgstr "" #: src/dird/expand.c:506 #, c-format msgid "Cannot expand expression \"%s\": ERR=%s\n" msgstr "" #: src/dird/expand.c:527 #, c-format msgid "Cannot destroy var context: ERR=%s\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:569 msgid "NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:716 msgid "NDMP protocol error, FHDB add_node call before add_dir.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:722 msgid "NDMP protocol error, FHDB unable to process out of order metadata.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:736 #, c-format msgid "NDMP protocol error, FHDB add_node request for unknown node %llu.\n" msgstr "" #: src/dird/ndmp_fhdb_mem.c:775 msgid "NDMP protocol error, FHDB add_dirnode_root call more then once.\n" msgstr "" #: src/dird/ua_dotcmds.c:173 src/dird/ua_cmds.c:287 #, c-format msgid "Can't use %s command in a runscript" msgstr "" #: src/dird/ua_dotcmds.c:208 msgid ": is an invalid command.\n" msgstr "" #: src/dird/ua_dotcmds.c:588 src/dird/ua_restore.c:824 #: src/dird/ua_restore.c:867 #, c-format msgid "Unable to get Job record for JobId=%s: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:658 src/dird/sd_cmds.c:177 msgid "Could not open SD socket.\n" msgstr "" #: src/dird/ua_dotcmds.c:662 src/dird/ua_cmds.c:1107 src/dird/sd_cmds.c:771 msgid "Connected to storage daemon\n" msgstr "" #: src/dird/ua_dotcmds.c:681 src/dird/ua_cmds.c:783 src/dird/ua_cmds.c:1154 #: src/dird/ua_cmds.c:1747 src/dird/fd_cmds.c:992 src/dird/fd_cmds.c:1043 #, c-format msgid "Connecting to Client %s at %s:%d\n" msgstr "" #: src/dird/ua_dotcmds.c:684 src/dird/ua_cmds.c:787 src/dird/ua_cmds.c:1158 #: src/dird/ua_cmds.c:1750 msgid "Failed to connect to Client.\n" msgstr "" #: src/dird/ua_dotcmds.c:727 src/dird/ua_dotcmds.c:828 #, c-format msgid "Unknown command: %s\n" msgstr "" #: src/dird/ua_dotcmds.c:765 src/dird/ua_cmds.c:1409 msgid "Available daemons are: \n" msgstr "" #: src/dird/ua_dotcmds.c:766 src/dird/ua_cmds.c:1410 msgid "Director" msgstr "" #: src/dird/ua_dotcmds.c:769 msgid "Select daemon type to make die" msgstr "" #: src/dird/ua_dotcmds.c:804 msgid "The Director will generate a deadlock.\n" msgstr "" #: src/dird/ua_dotcmds.c:808 msgid "The Director will segment fault.\n" msgstr "" #: src/dird/ua_dotcmds.c:1039 msgid "Access to specified Client or FileSet not allowed.\n" msgstr "" #: src/dird/ua_dotcmds.c:1045 src/dird/ua_dotcmds.c:1093 #: src/dird/ua_restore.c:985 src/dird/ua_restore.c:1013 #: src/dird/ua_restore.c:1034 #, c-format msgid "Query failed: %s. ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1087 msgid "query keyword not found.\n" msgstr "" #: src/dird/ua_dotcmds.c:1116 #, c-format msgid "List MediaType failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1130 #, c-format msgid "List Media failed: ERR=%s\n" msgstr "" #: src/dird/ua_dotcmds.c:1156 #, fuzzy, c-format msgid "List Location failed: ERR=%s\n" msgstr "Невдале встановлення з'єднання TLS\n" #: src/dird/ua_input.c:92 msgid "Enter slot" msgstr "" #: src/dird/ua_input.c:96 src/dird/ua_input.c:102 #, c-format msgid "Expected a positive integer, got: %s\n" msgstr "" #: src/dird/ua_input.c:159 msgid "Invalid response. You must answer yes or no.\n" msgstr "" #: src/dird/ua_input.c:183 msgid "Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n" msgstr "" #: src/dird/ua_input.c:211 #, fuzzy, c-format msgid "Illegal character \"%c\" in a comment.\n" msgstr "Заборонені символи у назві Тому \"%s\"\n" #: src/dird/ua_input.c:218 msgid "Comment too long.\n" msgstr "" #: src/dird/ua_input.c:224 msgid "Comment must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:104 msgid "Add media to a pool" msgstr "" #: src/dird/ua_cmds.c:106 msgid "Autodisplay console messages" msgstr "" #: src/dird/ua_cmds.c:108 msgid "Automount after label" msgstr "" #: src/dird/ua_cmds.c:110 msgid "Cancel a job" msgstr "" #: src/dird/ua_cmds.c:112 #, fuzzy msgid "Configure director" msgstr "Приєднуюсь до Керівника %s:%d" #: src/dird/ua_cmds.c:114 msgid "Create DB Pool from resource" msgstr "" #: src/dird/ua_cmds.c:116 msgid "Delete volume, pool or job" msgstr "" #: src/dird/ua_cmds.c:118 msgid "Disable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:120 msgid "Enable a job/client/schedule" msgstr "" #: src/dird/ua_cmds.c:122 msgid "Performs FileSet estimate, listing gives full listing" msgstr "" #: src/dird/ua_cmds.c:124 src/dird/ua_cmds.c:171 #, fuzzy msgid "Terminate Bconsole session" msgstr "вивести версію Консолі" #: src/dird/ua_cmds.c:126 msgid "Export volumes from normal slots to import/export slots" msgstr "" #: src/dird/ua_cmds.c:128 msgid "Non-interactive gui mode" msgstr "" #: src/dird/ua_cmds.c:130 msgid "Print help on specific command" msgstr "" #: src/dird/ua_cmds.c:137 msgid "Import volumes from import/export slots to normal slots" msgstr "" #: src/dird/ua_cmds.c:139 msgid "Label a tape" msgstr "" #: src/dird/ua_cmds.c:141 msgid "List objects from catalog" msgstr "" #: src/dird/ua_cmds.c:149 msgid "Full or long list like list command" msgstr "" #: src/dird/ua_cmds.c:157 msgid "Display pending messages" msgstr "" #: src/dird/ua_cmds.c:159 #, fuzzy msgid "Print current memory usage" msgstr "вивести поточний час" #: src/dird/ua_cmds.c:161 msgid "Mount storage" msgstr "" #: src/dird/ua_cmds.c:164 msgid "Move slots in an autochanger" msgstr "" #: src/dird/ua_cmds.c:166 msgid "Prune records from catalog" msgstr "" #: src/dird/ua_cmds.c:168 msgid "Purge records from catalog" msgstr "" #: src/dird/ua_cmds.c:173 msgid "Query catalog" msgstr "" #: src/dird/ua_cmds.c:175 msgid "Restore files" msgstr "" #: src/dird/ua_cmds.c:183 msgid "Relabel a tape" msgstr "" #: src/dird/ua_cmds.c:186 msgid "Release storage" msgstr "" #: src/dird/ua_cmds.c:188 msgid "Reload conf file" msgstr "" #: src/dird/ua_cmds.c:190 msgid "Rerun a job" msgstr "" #: src/dird/ua_cmds.c:192 msgid "Resolve a hostname" msgstr "" #: src/dird/ua_cmds.c:194 msgid "Run a job" msgstr "" #: src/dird/ua_cmds.c:202 msgid "Report status" msgstr "" #: src/dird/ua_cmds.c:206 msgid "Sets bandwidth" msgstr "" #: src/dird/ua_cmds.c:210 msgid "Sets debug level" msgstr "" #: src/dird/ua_cmds.c:212 msgid "Sets new client address -- if authorized" msgstr "" #: src/dird/ua_cmds.c:214 #, fuzzy msgid "Show resource records" msgstr "Невідомий тип ресурсу %d\n" #: src/dird/ua_cmds.c:219 msgid "Use SQL to query catalog" msgstr "" #: src/dird/ua_cmds.c:221 #, fuzzy msgid "Print current time" msgstr "вивести поточний час" #: src/dird/ua_cmds.c:223 msgid "Turn on/off trace to file" msgstr "" #: src/dird/ua_cmds.c:225 msgid "Unmount storage" msgstr "" #: src/dird/ua_cmds.c:228 msgid "Umount - for old-time Unix guys, see unmount" msgstr "" #: src/dird/ua_cmds.c:231 msgid "Update volume, pool or stats" msgstr "" #: src/dird/ua_cmds.c:240 #, fuzzy msgid "Use specific catalog" msgstr "зазначений час сну" #: src/dird/ua_cmds.c:242 msgid "Does variable expansion" msgstr "" #: src/dird/ua_cmds.c:244 #, fuzzy msgid "Print Director version" msgstr "Керівник" #: src/dird/ua_cmds.c:246 msgid "Wait until no jobs are running" msgstr "" #: src/dird/ua_cmds.c:312 #, c-format msgid "%s: is an invalid command.\n" msgstr "" #: src/dird/ua_cmds.c:355 msgid "" "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:374 #, c-format msgid "Pool already has maximum volumes=%d\n" msgstr "" #: src/dird/ua_cmds.c:375 msgid "Enter new maximum (zero for unlimited): " msgstr "" #: src/dird/ua_cmds.c:395 #, c-format msgid "Enter number of Volumes to create. 0=>fixed name. Max=%d: " msgstr "" #: src/dird/ua_cmds.c:401 #, c-format msgid "The number must be between 0 and %d\n" msgstr "" #: src/dird/ua_cmds.c:409 msgid "Enter Volume name: " msgstr "" #: src/dird/ua_cmds.c:413 msgid "Enter base volume name: " msgstr "" #: src/dird/ua_cmds.c:422 src/dird/ua_label.c:537 msgid "Volume name too long.\n" msgstr "" #: src/dird/ua_cmds.c:426 src/dird/ua_label.c:543 src/lib/edit.c:513 msgid "Volume name must be at least one character long.\n" msgstr "" #: src/dird/ua_cmds.c:437 msgid "Enter the starting number: " msgstr "" #: src/dird/ua_cmds.c:442 msgid "Start number must be greater than zero.\n" msgstr "" #: src/dird/ua_cmds.c:453 msgid "Enter slot (0 for none): " msgstr "" #: src/dird/ua_cmds.c:457 msgid "InChanger? yes/no: " msgstr "" #: src/dird/ua_cmds.c:482 #, c-format msgid "%d Volumes created in pool %s\n" msgstr "" #: src/dird/ua_cmds.c:498 src/dird/ua_cmds.c:1540 msgid "Turn on or off? " msgstr "" #: src/dird/ua_cmds.c:523 #, c-format msgid "JobId %s not a number\n" msgstr "" #: src/dird/ua_cmds.c:528 msgid "Missing jobid=JobId specification\n" msgstr "" #: src/dird/ua_cmds.c:671 #, c-format msgid "" "Can't set %s RecyclePool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:689 #, c-format msgid "" "Can't set %s ScratchPool to %s, %s is not in database.\n" "Try to update it with 'update pool=%s'\n" msgstr "" #: src/dird/ua_cmds.c:756 #, c-format msgid "" "Error: Pool %s already exists.\n" "Use update to change it.\n" msgstr "" #: src/dird/ua_cmds.c:767 #, c-format msgid "Pool %s created.\n" msgstr "" #: src/dird/ua_cmds.c:793 msgid "Failed to set bandwidth limit on Client.\n" msgstr "" #: src/dird/ua_cmds.c:795 src/dird/ua_cmds.c:845 #, c-format msgid "OK Limiting bandwidth to %lldkb/s %s\n" msgstr "" #: src/dird/ua_cmds.c:818 msgid "Storage selected is NDMP storage which cannot have a bandwidth limit\n" msgstr "" #: src/dird/ua_cmds.c:833 src/dird/ua_cmds.c:1099 src/dird/sd_cmds.c:756 #, c-format msgid "Connecting to Storage daemon %s at %s:%d\n" msgstr "" #: src/dird/ua_cmds.c:837 src/dird/ua_cmds.c:1103 src/dird/sd_cmds.c:145 #: src/dird/sd_cmds.c:631 src/dird/sd_cmds.c:677 msgid "Failed to connect to Storage daemon.\n" msgstr "" #: src/dird/ua_cmds.c:843 #, fuzzy msgid "Failed to set bandwidth limit on Storage daemon.\n" msgstr "Відкриті з'єднання із Зберігачем.\n" #: src/dird/ua_cmds.c:881 msgid "Enter new bandwidth limit kb/s: " msgstr "" #: src/dird/ua_cmds.c:948 src/dird/ua_cmds.c:1039 src/dird/ua_cmds.c:1047 #: src/dird/ua_cmds.c:1055 src/dird/ua_select.c:1285 msgid "Unauthorized command from this console.\n" msgstr "" #: src/dird/ua_cmds.c:966 #, c-format msgid "Client \"%s\" address set to %s\n" msgstr "" #: src/dird/ua_cmds.c:1031 src/dird/ua_cmds.c:1609 src/dird/ua_select.c:1468 #, c-format msgid "Job \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1044 #, c-format msgid "Schedule \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1052 #, c-format msgid "Client \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1060 #, c-format msgid "Job \"%s\" %sabled\n" msgstr "" #: src/dird/ua_cmds.c:1305 msgid "Enter new debug level: " msgstr "" #: src/dird/ua_cmds.c:1413 msgid "All" msgstr "" #: src/dird/ua_cmds.c:1415 msgid "Select daemon type to set debug level" msgstr "" #: src/dird/ua_cmds.c:1469 src/dird/ua_cmds.c:1595 src/dird/ua_cmds.c:2544 #, c-format msgid "No authorization for Client \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1476 src/dird/ua_cmds.c:1600 msgid "Client name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1488 #, fuzzy, c-format msgid "No authorization for Storage \"%s\"\n" msgstr "Від'єднуюсь від Зберігача %s:%d\n" #: src/dird/ua_cmds.c:1495 #, fuzzy msgid "Storage name missing.\n" msgstr "Зберігач" #: src/dird/ua_cmds.c:1520 #, fuzzy, c-format msgid "%s Failed to resolve %s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/dird/ua_cmds.c:1523 src/stored/dir_cmd.c:588 src/filed/dir_cmd.c:636 #, c-format msgid "%s resolves %s to %s\n" msgstr "" #: src/dird/ua_cmds.c:1613 src/dird/ua_cmds.c:1687 src/dird/ua_cmds.c:2566 #, c-format msgid "No authorization for Job \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1618 msgid "Job name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1628 #, c-format msgid "Fileset \"%s\" not found.\n" msgstr "" #: src/dird/ua_cmds.c:1632 #, c-format msgid "No authorization for FileSet \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:1637 msgid "Fileset name missing.\n" msgstr "" #: src/dird/ua_cmds.c:1654 msgid "Level value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1662 msgid "Invalid value for accurate. It must be yes or no.\n" msgstr "" #: src/dird/ua_cmds.c:1667 msgid "Accurate value missing.\n" msgstr "" #: src/dird/ua_cmds.c:1682 msgid "No job specified.\n" msgstr "" #: src/dird/ua_cmds.c:1696 #, c-format msgid "Wrong job specified of type %s.\n" msgstr "" #: src/dird/ua_cmds.c:1709 #, fuzzy msgid "No client specified or selected.\n" msgstr "Ресурс %s не визначено\n" #: src/dird/ua_cmds.c:1714 #, fuzzy msgid "No fileset specified or selected.\n" msgstr "зазначений час сну" #: src/dird/ua_cmds.c:1768 msgid "Error sending include list.\n" msgstr "" #: src/dird/ua_cmds.c:1773 msgid "Error sending exclude list.\n" msgstr "" #: src/dird/ua_cmds.c:1862 msgid "" "In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:1865 msgid "Choose catalog item to delete" msgstr "" #: src/dird/ua_cmds.c:1876 msgid "Nothing done.\n" msgstr "" #: src/dird/ua_cmds.c:1915 src/dird/ua_cmds.c:1930 src/dird/ua_cmds.c:1940 #, c-format msgid "Illegal JobId %s ignored\n" msgstr "" #: src/dird/ua_cmds.c:1943 msgid "Enter JobId to delete: " msgstr "" #: src/dird/ua_cmds.c:1979 #, c-format msgid "Are you sure you want to delete %d JobIds ? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:1989 #, c-format msgid "Illegal JobId range %s - %s should define increasing JobIds, ignored\n" msgstr "" #: src/dird/ua_cmds.c:1993 #, c-format msgid "Illegal JobId range %s - %s, ignored\n" msgstr "" #: src/dird/ua_cmds.c:2008 #, c-format msgid "Jobid %s and associated records deleted from the catalog.\n" msgstr "" #: src/dird/ua_cmds.c:2024 #, c-format msgid "" "\n" "This command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n" msgstr "" #: src/dird/ua_cmds.c:2031 #, c-format msgid "Are you sure you want to delete Volume \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2044 msgid "Can't list jobs on this volume\n" msgstr "" #: src/dird/ua_cmds.c:2069 #, c-format msgid "Are you sure you want to delete Pool \"%s\"? (yes/no): " msgstr "" #: src/dird/ua_cmds.c:2190 #, c-format msgid "Using Catalog name=%s DB=%s\n" msgstr "" #: src/dird/ua_cmds.c:2258 msgid "ERR: Can't open db\n" msgstr "" #: src/dird/ua_cmds.c:2305 msgid "Wait on mount timed out\n" msgstr "" #: src/dird/ua_cmds.c:2315 msgid "ERR: Job was not found\n" msgstr "" #: src/dird/ua_cmds.c:2391 msgid "" " Command Description\n" " ======= ===========\n" msgstr "" #: src/dird/ua_cmds.c:2395 #, c-format msgid "" " %-13s %s\n" "\n" "Arguments:\n" "\t%s\n" msgstr "" #: src/dird/ua_cmds.c:2400 #, c-format msgid " %-13s %s\n" msgstr "" #: src/dird/ua_cmds.c:2404 #, fuzzy, c-format msgid "" "\n" "Can't find %s command.\n" "\n" msgstr ": неправильна команда\n" #: src/dird/ua_cmds.c:2406 msgid "" "\n" "When at a prompt, entering a period cancels the command.\n" "\n" msgstr "" #: src/dird/ua_cmds.c:2484 src/filed/status.c:83 #, c-format msgid "%s Version: %s (%s) %s %s %s %s\n" msgstr "" #: src/dird/ua_cmds.c:2527 src/dird/ua_cmds.c:2554 src/dird/ua_cmds.c:2576 #, c-format msgid "No authorization for Catalog \"%s\"\n" msgstr "" #: src/dird/ua_cmds.c:2614 src/dird/ua_select.c:220 msgid "Could not find a Catalog resource\n" msgstr "" #: src/dird/ua_cmds.c:2641 #, c-format msgid "Could not open catalog database \"%s\".\n" msgstr "" #: src/dird/ua_cmds.c:2656 #, c-format msgid "Using Catalog \"%s\"\n" msgstr "" #: src/dird/verify.c:84 src/dird/verify.c:396 #, c-format msgid "Unimplemented Verify level %d(%c)\n" msgstr "" #: src/dird/verify.c:150 msgid "" "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n" msgstr "" #: src/dird/verify.c:155 msgid "Unable to find JobId of previous Job for this client.\n" msgstr "" #: src/dird/verify.c:175 #, c-format msgid "Last Job %d did not terminate normally. JobStatus=%c\n" msgstr "" #: src/dird/verify.c:179 #, c-format msgid "Verifying against JobId=%d Job=%s\n" msgstr "" #: src/dird/verify.c:223 #, c-format msgid "Start Verify JobId=%s Level=%s Job=%s\n" msgstr "" #: src/dird/verify.c:318 msgid "Deprecated feature ... use bootstrap.\n" msgstr "" #: src/dird/verify.c:455 #, c-format msgid "Unimplemented verify level %d\n" msgstr "" #: src/dird/verify.c:511 msgid "Verify OK" msgstr "" #: src/dird/verify.c:515 msgid "*** Verify Error ***" msgstr "" #: src/dird/verify.c:519 msgid "Verify warnings" msgstr "" #: src/dird/verify.c:522 msgid "Verify Canceled" msgstr "" #: src/dird/verify.c:525 msgid "Verify Differences" msgstr "" #: src/dird/verify.c:530 #, c-format msgid "Inappropriate term code: %d %c\n" msgstr "" #: src/dird/verify.c:545 #, c-format msgid "" "%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:581 #, c-format msgid "" "%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n" "\n" msgstr "" #: src/dird/verify.c:661 #, c-format msgid "" "dird\" command before continuing.\n" msgstr "" #: src/dird/ua_select.c:229 msgid "The defined Catalog resources are:\n" msgstr "" #: src/dird/ua_select.c:237 msgid "Catalog" msgstr "" #: src/dird/ua_select.c:237 msgid "Select Catalog resource" msgstr "" #: src/dird/ua_select.c:254 src/dird/ua_select.c:280 msgid "The defined Job resources are:\n" msgstr "" #: src/dird/ua_select.c:265 src/dird/ua_select.c:288 msgid "Select Job resource" msgstr "" #: src/dird/ua_select.c:307 #, c-format msgid "Error: Restore Job resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:320 msgid "The defined Restore Job resources are:\n" msgstr "" #: src/dird/ua_select.c:328 msgid "Select Restore Job" msgstr "" #: src/dird/ua_select.c:343 src/dird/ua_select.c:367 msgid "The defined Client resources are:\n" msgstr "" #: src/dird/ua_select.c:351 msgid "Select Client (File daemon) resource" msgstr "" #: src/dird/ua_select.c:378 msgid "Select Client resource" msgstr "" #: src/dird/ua_select.c:405 #, c-format msgid "Error: Client resource %s does not exist.\n" msgstr "" #: src/dird/ua_select.c:421 msgid "The defined Schedule resources are:\n" msgstr "" #: src/dird/ua_select.c:432 msgid "Select Schedule resource" msgstr "" #: src/dird/ua_select.c:457 #, c-format msgid "Could not find Client %s: ERR=%s" msgstr "" #: src/dird/ua_select.c:467 src/dird/ua_select.c:521 #, c-format msgid "Could not find Client \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:496 #, c-format msgid "Error obtaining client ids. ERR=%s\n" msgstr "" #: src/dird/ua_select.c:500 msgid "No clients defined. You must run a job before using this command.\n" msgstr "" #: src/dird/ua_select.c:504 msgid "Defined Clients:\n" msgstr "" #: src/dird/ua_select.c:514 msgid "Select the Client" msgstr "" #: src/dird/ua_select.c:547 src/dird/ua_select.c:571 src/dird/ua_select.c:615 #, c-format msgid "Could not find Pool \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:585 msgid "No pools defined. Use the \"create\" command to create one.\n" msgstr "" #: src/dird/ua_select.c:589 msgid "Defined Pools:\n" msgstr "" #: src/dird/ua_select.c:602 msgid "Select the Pool" msgstr "" #: src/dird/ua_select.c:640 #, c-format msgid "No access to Pool \"%s\"\n" msgstr "" #: src/dird/ua_select.c:678 msgid "Enter *MediaId or Volume name: " msgstr "" #: src/dird/ua_select.c:712 msgid "The defined Pool resources are:\n" msgstr "" #: src/dird/ua_select.c:720 msgid "Select Pool resource" msgstr "" #: src/dird/ua_select.c:743 src/dird/ua_restore.c:599 #, c-format msgid "Error: Pool resource \"%s\" does not exist.\n" msgstr "" #: src/dird/ua_select.c:754 msgid "Enter the JobId to select: " msgstr "" #: src/dird/ua_select.c:792 #, c-format msgid "Could not find Job \"%s\": ERR=%s" msgstr "" #: src/dird/ua_select.c:871 #, c-format msgid "Automatically selected %s: %s\n" msgstr "" #: src/dird/ua_select.c:883 #, c-format msgid "" "Your request has multiple choices for \"%s\". Selection is not possible in " "batch mode.\n" msgstr "" "Ваш запит до \"%s\" має декілька можливостей вибору. У пакетному режимі " "вибір не можливий.\n" #: src/dird/ua_select.c:901 #, c-format msgid "Selection list for \"%s\" is empty!\n" msgstr "" #: src/dird/ua_select.c:907 #, c-format msgid "Automatically selected: %s\n" msgstr "" #: src/dird/ua_select.c:919 msgid "Selection aborted, nothing done.\n" msgstr "" #: src/dird/ua_select.c:924 #, c-format msgid "Please enter a number between 1 and %d\n" msgstr "" #: src/dird/ua_select.c:988 msgid "Storage name given twice.\n" msgstr "" #: src/dird/ua_select.c:1005 #, c-format msgid "Expecting jobid=nn command, got: %s\n" msgstr "" #: src/dird/ua_select.c:1009 #, c-format msgid "JobId %s is not running.\n" msgstr "" #: src/dird/ua_select.c:1019 #, c-format msgid "Expecting job=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1023 src/dird/ua_select.c:1035 #, c-format msgid "Job \"%s\" is not running.\n" msgstr "" #: src/dird/ua_select.c:1031 #, c-format msgid "Expecting ujobid=xxx, got: %s.\n" msgstr "" #: src/dird/ua_select.c:1051 #, c-format msgid "Storage resource \"%s\": not found\n" msgstr "" #: src/dird/ua_select.c:1093 msgid "Select Drive:\n" msgstr "" #: src/dird/ua_select.c:1098 msgid "Drive" msgstr "" #: src/dird/ua_select.c:1098 msgid "Select drive" msgstr "" #: src/dird/ua_select.c:1125 msgid "Enter autochanger slot: " msgstr "" #: src/dird/ua_select.c:1153 msgid "Media Types defined in conf file:\n" msgstr "" #: src/dird/ua_select.c:1159 msgid "Media Type" msgstr "" #: src/dird/ua_select.c:1159 msgid "Select the Media Type" msgstr "" #: src/dird/ua_select.c:1262 #, c-format msgid "JobId %s is not running. Use Job name to %s inactive jobs.\n" msgstr "" #: src/dird/ua_select.c:1270 src/dird/ua_select.c:1278 #, c-format msgid "Warning Job %s is not running. Continuing anyway ...\n" msgstr "" #: src/dird/ua_select.c:1323 src/stored/status.c:717 src/filed/status.c:232 msgid "No Jobs running.\n" msgstr "" #: src/dird/ua_select.c:1325 msgid "None of your jobs are running.\n" msgstr "" #: src/dird/ua_select.c:1357 msgid "Illegal state either created, blocked, waiting or running\n" msgstr "" #: src/dird/ua_select.c:1406 #, c-format msgid "Selected Job %d for cancelling\n" msgstr "" #: src/dird/ua_select.c:1410 src/dird/ua_restore.c:886 msgid "No Jobs selected.\n" msgstr "" #: src/dird/ua_select.c:1418 src/dird/ua_select.c:1458 msgid "Confirm cancel (yes/no): " msgstr "" #: src/dird/ua_select.c:1429 msgid "Select Job:\n" msgstr "" #: src/dird/ua_select.c:1438 #, c-format msgid "JobId=%s Job=%s" msgstr "" #: src/dird/ua_select.c:1443 #, fuzzy, c-format msgid "Choose Job to %s" msgstr "Оберіть те, що Ви хочете вичистити" #: src/dird/ua_select.c:1452 #, c-format msgid "" "Cancel: %s\n" "\n" "%s" msgstr "" #: src/dird/ua_select.c:1452 msgid "Confirm cancel?" msgstr "" #: src/dird/ua_select.c:1533 msgid "Negative numbers not permitted\n" msgstr "" #: src/dird/ua_select.c:1539 src/lib/sellist.c:69 msgid "Range end is not integer.\n" msgstr "" #: src/dird/ua_select.c:1544 src/lib/sellist.c:74 msgid "Range start is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1550 src/lib/sellist.c:80 msgid "Range end not bigger than start.\n" msgstr "" #: src/dird/ua_select.c:1556 src/lib/sellist.c:87 msgid "Input value is not an integer.\n" msgstr "" #: src/dird/ua_select.c:1562 msgid "Values must be be greater than zero.\n" msgstr "" #: src/dird/ua_select.c:1566 msgid "Slot too large.\n" msgstr "" #: src/dird/catreq.c:127 src/dird/catreq.c:353 #, c-format msgid "1990 Invalid Catalog Request: %s" msgstr "" #: src/dird/catreq.c:128 #, c-format msgid "Invalid Catalog request; DB not open: %s" msgstr "" #: src/dird/catreq.c:153 msgid "1901 No Media.\n" msgstr "" #: src/dird/catreq.c:181 msgid "not in Pool" msgstr "" #: src/dird/catreq.c:183 msgid "not correct MediaType" msgstr "" #: src/dird/catreq.c:194 msgid "is not Enabled" msgstr "" #: src/dird/catreq.c:203 #, c-format msgid "1998 Volume \"%s\" catalog status is %s, %s.\n" msgstr "" #: src/dird/catreq.c:208 #, c-format msgid "1997 Volume \"%s\" not in catalog.\n" msgstr "" #: src/dird/catreq.c:228 #, c-format msgid "Unable to get Media record for Volume %s: ERR=%s\n" msgstr "" #: src/dird/catreq.c:230 #, c-format msgid "1991 Catalog Request for vol=%s failed: %s" msgstr "" #: src/dird/catreq.c:257 #, c-format msgid "" "Volume Files at %u being set to %u for Volume \"%s\". This is incorrect.\n" msgstr "" #: src/dird/catreq.c:260 #, c-format msgid "1992 Update Media error. VolFiles=%u, CatFiles=%u\n" msgstr "" #: src/dird/catreq.c:311 #, c-format msgid "Catalog error updating Media record. %s" msgstr "" #: src/dird/catreq.c:313 msgid "1993 Update Media error\n" msgstr "" #: src/dird/catreq.c:342 #, c-format msgid "Catalog error creating JobMedia record. %s" msgstr "" #: src/dird/catreq.c:344 msgid "1992 Create JobMedia error\n" msgstr "" #: src/dird/catreq.c:354 #, c-format msgid "Invalid Catalog request: %s" msgstr "" #: src/dird/catreq.c:453 src/dird/ndmp_fhdb_helpers.c:47 #: src/dird/ndmp_fhdb_helpers.c:64 #, fuzzy, c-format msgid "Attribute create error: ERR=%s" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/dird/catreq.c:556 #, c-format msgid "Restore object create error. %s" msgstr "" #: src/dird/catreq.c:564 #, c-format msgid "%s not same File=%d as attributes=%d\n" msgstr "" #: src/dird/catreq.c:595 #, c-format msgid "Catalog error updating file digest. Unsupported digest stream type: %d" msgstr "" #: src/dird/catreq.c:613 #, c-format msgid "attribute create error. %s" msgstr "" #: src/dird/catreq.c:618 #, c-format msgid "Catalog error updating file digest. %s" msgstr "Помилка під час оновлення відбитку файлу. %s" #: src/dird/catreq.c:643 #, c-format msgid "1994 Invalid Catalog Update: %s" msgstr "1994 Помилка оновлення Каталогу: %s" #: src/dird/catreq.c:644 #, c-format msgid "Invalid Catalog Update; DB not open: %s" msgstr "Помилка оновлення Каталогу: БД не відкрита: %s" #: src/dird/catreq.c:704 src/lib/bsock.c:159 #, fuzzy, c-format msgid "read attr spool error. ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/dird/ua_purge.c:95 #, fuzzy msgid "" "\n" "This command can be DANGEROUS!!!\n" "\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n" msgstr "" "\n" "Ця команда НЕБЕЗПЕЧНА!!!\n" "\n" "Вона вичистить(знищить) усі Файли із Задачі,\n" "Номера Задачі, Клієнта або Тома; або вичистить(знищить)\n" "усі Задачі із Клієнта або Тома не враховуючи\n" "термінів зберігання. Зазвичай ви повинні використовувати\n" "команду PRUNE для дотримання термінів зберігання.\n" #: src/dird/ua_purge.c:197 msgid "Choose item to purge" msgstr "Оберіть те, що Ви хочете вичистити" #: src/dird/ua_purge.c:249 #, c-format msgid "Begin purging files for Client \"%s\"\n" msgstr "Починається чистка файлів Клієнта \"%s\"\n" #: src/dird/ua_purge.c:258 src/dird/ua_purge.c:308 #, c-format msgid "No Files found for client %s to purge from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:261 #, c-format msgid "Files for %d Jobs for client \"%s\" purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:299 #, c-format msgid "Begin purging jobs from Client \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:311 #, c-format msgid "%d Jobs for client %s purged from %s catalog.\n" msgstr "" #: src/dird/ua_purge.c:439 #, fuzzy, c-format msgid "Purged quota for Client \"%s\"\n" msgstr "Починається чистка файлів Клієнта \"%s\"\n" #: src/dird/ua_purge.c:547 #, c-format msgid "" "\n" "Volume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n" msgstr "" #: src/dird/ua_purge.c:575 #, c-format msgid "%d File%s on Volume \"%s\" purged from catalog.\n" msgstr "" #: src/dird/ua_purge.c:624 #, c-format msgid "" "There are no more Jobs associated with Volume \"%s\". Marking it purged.\n" msgstr "" #: src/dird/ua_purge.c:705 #, fuzzy msgid "Can't update volume size in the catalog\n" msgstr "У картотеці створено новий Том \"%s\".\n" #: src/dird/ua_purge.c:707 #, c-format msgid "The volume \"%s\" has been truncated\n" msgstr "" #: src/dird/ua_purge.c:709 #, c-format msgid "Unable to truncate volume \"%s\"\n" msgstr "" #: src/dird/ua_purge.c:819 #, c-format msgid "No Volumes found to perform %s action.\n" msgstr "" #: src/dird/ua_purge.c:900 #, c-format msgid "Unable move recycled Volume in full Pool \"%s\" MaxVols=%d\n" msgstr "" #: src/dird/ua_purge.c:917 #, c-format msgid "All records pruned from Volume \"%s\"; marking it \"Purged\"\n" msgstr "" #: src/dird/ua_purge.c:923 #, c-format msgid "Cannot purge Volume with VolStatus=%s\n" msgstr "" #: src/dird/ua_audit.c:68 msgid "for Job" msgstr "" #: src/dird/ua_audit.c:71 msgid "for Client" msgstr "" #: src/dird/ua_audit.c:74 #, fuzzy msgid "for Storage" msgstr "Зберігач" #: src/dird/ua_audit.c:77 src/dird/ua_audit.c:80 msgid "for Schedule" msgstr "" #: src/dird/ua_audit.c:83 msgid "for Pool" msgstr "" #: src/dird/ua_audit.c:86 msgid "for Command" msgstr "" #: src/dird/ua_audit.c:89 #, fuzzy msgid "for Fileset" msgstr "Дата файлу" #: src/dird/ua_audit.c:92 msgid "for Catalog" msgstr "" #: src/dird/ua_audit.c:95 msgid "for Where restore location" msgstr "" #: src/dird/ua_audit.c:98 #, fuzzy msgid "for Plugin Options" msgstr "Невдале встановлення з'єднання TLS\n" #: src/dird/ua_audit.c:114 #, fuzzy, c-format msgid "Console [%s] from [%s], Audit acl failure %s %s\n" msgstr "Консоль: назва=%s\n" #: src/dird/ua_audit.c:123 #, c-format msgid "Console [%s] from [%s], Audit acl success %s %s\n" msgstr "" #: src/dird/ua_audit.c:141 #, fuzzy, c-format msgid "Console [%s] from [%s] cmdline %s\n" msgstr "Консоль: назва=%s\n" #: src/dird/inc_conf.c:182 #, c-format msgid "Illegal %s option %c, got option string: %s:" msgstr "" #: src/dird/inc_conf.c:206 src/lib/jcr.c:267 msgid "verify" msgstr "" #: src/dird/inc_conf.c:212 msgid "accurate" msgstr "" #: src/dird/inc_conf.c:218 #, fuzzy msgid "base job" msgstr "Останні задачі відсутні" #: src/dird/inc_conf.c:225 #, fuzzy, c-format msgid "Expected a strip path positive integer, got: %s:" msgstr "Помилка автентифікації : %s" #: src/dird/inc_conf.c:233 #, fuzzy, c-format msgid "Expected a parseable size, got: %s:" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/dird/inc_conf.c:251 #, fuzzy, c-format msgid "Expected a FileSet option keyword, got: %s:" msgstr "Помилка автентифікації : %s" #: src/dird/inc_conf.c:288 #, c-format msgid "Regex compile error. ERR=%s\n" msgstr "" #: src/dird/inc_conf.c:309 #, c-format msgid "Expected a regex string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:382 #, c-format msgid "Expected a wild-card string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:405 #, c-format msgid "Expected a fstype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:428 #, c-format msgid "Expected a drivetype string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:450 #, c-format msgid "Expected a meta string, got: %s\n" msgstr "" #: src/dird/inc_conf.c:479 #, c-format msgid "Expected a FileSet keyword, got: %s" msgstr "" #: src/dird/inc_conf.c:530 msgid "Options section not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:535 src/dird/dird_conf.c:3196 #, c-format msgid "Expecting open brace. Got %s" msgstr "" #: src/dird/inc_conf.c:550 src/dird/inc_conf.c:730 src/dird/dird_conf.c:3213 #, c-format msgid "Expecting keyword, got: %s\n" msgstr "" #: src/dird/inc_conf.c:556 src/dird/inc_conf.c:738 src/lib/parse_conf.c:244 #, c-format msgid "expected an equals, got: %s" msgstr "" #: src/dird/inc_conf.c:592 src/dird/inc_conf.c:764 src/dird/dird_conf.c:3248 #, c-format msgid "Keyword %s not permitted in this resource" msgstr "" #: src/dird/inc_conf.c:616 src/dird/inc_conf.c:660 #, c-format msgid "Backslash found. Use forward slashes or quote the string.: %s\n" msgstr "" #: src/dird/inc_conf.c:631 src/dird/inc_conf.c:675 #, c-format msgid "Expected a filename, got: %s" msgstr "" #: src/dird/inc_conf.c:649 msgid "Plugin directive not permitted in Exclude\n" msgstr "" #: src/dird/inc_conf.c:688 msgid "ExcludeDirContaining directive not permitted in Exclude.\n" msgstr "" #: src/dird/inc_conf.c:814 msgid "Old style Include/Exclude not supported\n" msgstr "" #: src/dird/fd_cmds.c:111 msgid "Client: " msgstr "" #: src/dird/fd_cmds.c:155 #, c-format msgid "File daemon \"%s\" rejected Job command: %s\n" msgstr "" #: src/dird/fd_cmds.c:168 #, c-format msgid "Error updating Client record. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:173 #, c-format msgid "FD gave bad response to JobId command: %s\n" msgstr "" #: src/dird/fd_cmds.c:267 src/dird/fd_cmds.c:270 #, c-format msgid "Unimplemented backup level %d %c\n" msgstr "" #: src/dird/fd_cmds.c:355 msgid "" "FD compression disabled for this Job because AllowCompress=No in Storage " "resource.\n" msgstr "" #: src/dird/fd_cmds.c:475 src/filed/fileset.c:116 #, c-format msgid "Cannot run program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:486 src/dird/fd_cmds.c:511 src/dird/fd_cmds.c:526 msgid ">filed: write error on socket\n" msgstr "" #: src/dird/fd_cmds.c:492 #, c-format msgid "Error running program: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:501 #, c-format msgid "Cannot open included file: %s. ERR=%s\n" msgstr "" #: src/dird/fd_cmds.c:660 #, c-format msgid "Client \"%s\" RunScript failed.\n" msgstr "" #: src/dird/fd_cmds.c:691 #, c-format msgid "" "Client \"%s\" may not be used to restore this job. Please upgrade your " "client.\n" msgstr "" #: src/dird/fd_cmds.c:755 #, fuzzy msgid "Plugin options failed.\n" msgstr "Невдале встановлення з'єднання TLS\n" #: src/dird/fd_cmds.c:828 msgid "RestoreObject failed.\n" msgstr "" #: src/dird/fd_cmds.c:863 #, c-format msgid "" " set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n" "\n" msgstr "" #: src/tests/bbatch.c:194 src/tests/bvfs_test.c:205 src/tests/ing_test.c:178 #: src/tests/cats_test.c:321 src/stored/bscan.c:255 src/stored/bcopy.c:159 msgid "Wrong number of arguments: \n" msgstr "" #: src/tests/bbatch.c:215 src/tests/bbatch.c:264 src/tests/bvfs_test.c:225 #: src/tests/ing_test.c:189 src/stored/bscan.c:327 msgid "Could not init Bareos database\n" msgstr "" #: src/tests/bbatch.c:225 #, c-format msgid "Computing file list for jobid=%s files=%lld secs=%d\n" msgstr "" #: src/tests/bbatch.c:271 src/tests/bvfs_test.c:234 src/tests/ing_test.c:198 #: src/stored/bscan.c:334 #, c-format msgid "Using Database: %s, User: %s\n" msgstr "" #: src/tests/bbatch.c:329 #, c-format msgid "Error opening datafile %s\n" msgstr "" #: src/tests/bbatch.c:339 msgid "Error while inserting file\n" msgstr "" #: src/tests/bvfs_test.c:51 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:49 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/ing_test.c:229 src/tests/ing_test.c:262 src/tests/ing_test.c:300 msgid "Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:318 msgid "CREATE-Stmt went wrong\n" msgstr "" #: src/tests/ing_test.c:323 msgid "DROP-Stmt went wrong\n" msgstr "" #: src/tests/cats_test.c:52 #, c-format msgid "" "\n" "Version: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n" "\n" msgstr "" #: src/tests/cats_test.c:375 #, fuzzy, c-format msgid "Could not open, database \"%s\".\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/tests/testls.c:50 #, c-format msgid "" "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n" msgstr "" #: src/tests/testls.c:146 #, c-format msgid "Could not open include file: %s\n" msgstr "" #: src/tests/testls.c:159 #, c-format msgid "Could not open exclude file: %s\n" msgstr "" #: src/tests/testls.c:173 #, c-format msgid "Files seen = %d\n" msgstr "" #: src/tests/testls.c:221 #, c-format msgid "Recursion turned off. Directory not entered. %s\n" msgstr "" #: src/tests/testls.c:224 #, c-format msgid "Skip: File system change prohibited. Directory not entered. %s\n" msgstr "" #: src/tests/bregtest.c:128 src/tools/bwild.c:114 src/tools/bregex.c:145 #, c-format msgid "Could not open data file: %s\n" msgstr "" #: src/stored/dir_cmd.c:231 src/stored/stored.c:597 #, fuzzy, c-format msgid "Unable to init job start cond variable: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/dir_cmd.c:241 #, fuzzy, c-format msgid "Unable to init job end cond variable: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/dir_cmd.c:253 src/filed/authenticate.c:383 msgid "Unable to authenticate Director\n" msgstr "" #: src/stored/dir_cmd.c:331 src/filed/dir_cmd.c:580 #, c-format msgid "Connection request from %s failed.\n" msgstr "" #: src/stored/dir_cmd.c:342 src/filed/sd_cmds.c:42 src/filed/dir_cmd.c:605 #, c-format msgid "Invalid connection from %s. Len=%d\n" msgstr "" #: src/stored/dir_cmd.c:408 src/filed/dir_cmd.c:717 #, fuzzy, c-format msgid "2991 Bad setbandwidth command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/stored/dir_cmd.c:414 src/filed/dir_cmd.c:665 src/filed/dir_cmd.c:723 #, c-format msgid "2901 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:485 msgid "3903 Error scanning cancel command.\n" msgstr "" #: src/stored/dir_cmd.c:495 src/stored/dir_cmd.c:500 #, c-format msgid "3904 Job %s not found.\n" msgstr "" #: src/stored/dir_cmd.c:562 #, c-format msgid "3000 JobId=%ld Job=\"%s\" marked to be %s.\n" msgstr "" #: src/stored/dir_cmd.c:584 src/filed/dir_cmd.c:632 #, fuzzy, c-format msgid "%s: Failed to resolve %s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/dir_cmd.c:678 src/stored/dir_cmd.c:1048 #: src/stored/dir_cmd.c:1135 src/stored/dir_cmd.c:1244 #: src/stored/dir_cmd.c:1380 src/stored/dir_cmd.c:1421 #, c-format msgid "3999 Device \"%s\" not found or could not be opened.\n" msgstr "" #: src/stored/dir_cmd.c:683 #, c-format msgid "3903 Error scanning label command: %s\n" msgstr "" #: src/stored/dir_cmd.c:743 #, fuzzy, c-format msgid "3910 Unable to open device \"%s\": ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/stored/dir_cmd.c:759 #, c-format msgid "3920 Cannot label Volume because it is already labeled: \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:766 msgid "3921 Wrong volume mounted.\n" msgstr "" #: src/stored/dir_cmd.c:770 msgid "3922 Cannot relabel an ANSI/IBM labeled Volume.\n" msgstr "" #: src/stored/dir_cmd.c:777 #, c-format msgid "3912 Failed to label Volume: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:787 #, c-format msgid "3914 Failed to label Volume (no media): ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:790 #, c-format msgid "3913 Cannot label Volume. Unknown status %d from read_volume_label()\n" msgstr "" #: src/stored/dir_cmd.c:826 #, c-format msgid "3001 Mounted Volume: %s\n" msgstr "" #: src/stored/dir_cmd.c:830 src/stored/dir_cmd.c:1456 #, c-format msgid "" "3902 Cannot mount Volume on Storage Device \"%s\" because:\n" "%s" msgstr "" #: src/stored/dir_cmd.c:858 src/stored/reserve.c:644 #, c-format msgid "" "\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:880 src/stored/reserve.c:640 #, c-format msgid "" "\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or " "does not exist.\n" msgstr "" #: src/stored/dir_cmd.c:944 msgid "Specified slot ignored. " msgstr "" #: src/stored/dir_cmd.c:959 src/stored/dir_cmd.c:1010 #, fuzzy, c-format msgid "3901 Unable to open device \"%s\": ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/stored/dir_cmd.c:978 src/stored/dir_cmd.c:1003 #, c-format msgid "3001 Device \"%s\" is mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:980 src/stored/dir_cmd.c:1005 #: src/stored/dir_cmd.c:1017 #, c-format msgid "" "3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n" msgstr "" #: src/stored/dir_cmd.c:989 #, c-format msgid "3001 Device \"%s\" is doing acquire.\n" msgstr "" #: src/stored/dir_cmd.c:993 src/stored/dir_cmd.c:1108 #, c-format msgid "3903 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1015 #, c-format msgid "3001 Device \"%s\" is already mounted with Volume \"%s\"\n" msgstr "" #: src/stored/dir_cmd.c:1025 #, c-format msgid "3002 Device \"%s\" is mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1027 src/stored/dir_cmd.c:1082 #: src/stored/dir_cmd.c:1098 src/stored/dir_cmd.c:1127 #, c-format msgid "3907 %s" msgstr "" #: src/stored/dir_cmd.c:1030 #, c-format msgid "3906 File device \"%s\" is always mounted.\n" msgstr "" #: src/stored/dir_cmd.c:1038 #, c-format msgid "3930 Device \"%s\" is being released.\n" msgstr "" #: src/stored/dir_cmd.c:1042 #, fuzzy, c-format msgid "3905 Unknown wait state %d\n" msgstr "Невідомий статус задачі %c. " #: src/stored/dir_cmd.c:1052 #, c-format msgid "3909 Error scanning mount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1080 src/stored/dir_cmd.c:1129 #, c-format msgid "3002 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1086 #, c-format msgid "3901 Device \"%s\" is already unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1101 #, c-format msgid "3001 Device \"%s\" unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1105 #, c-format msgid "3902 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1140 #, c-format msgid "3907 Error scanning unmount command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1166 msgid "3916 Error scanning action_on_purge command\n" msgstr "" #: src/stored/dir_cmd.c:1209 #, c-format msgid "3921 Device \"%s\" already released.\n" msgstr "" #: src/stored/dir_cmd.c:1216 #, c-format msgid "3922 Device \"%s\" waiting for sysop.\n" msgstr "" #: src/stored/dir_cmd.c:1222 #, c-format msgid "3922 Device \"%s\" waiting for mount.\n" msgstr "" #: src/stored/dir_cmd.c:1226 #, c-format msgid "3923 Device \"%s\" is busy in acquire.\n" msgstr "" #: src/stored/dir_cmd.c:1230 #, c-format msgid "3914 Device \"%s\" is being labeled.\n" msgstr "" #: src/stored/dir_cmd.c:1238 #, c-format msgid "3022 Device \"%s\" released.\n" msgstr "" #: src/stored/dir_cmd.c:1249 #, c-format msgid "3927 Error scanning release command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1278 src/filed/dir_cmd.c:1262 #, c-format msgid "Could not create bootstrap file %s: ERR=%s\n" msgstr "" #: src/stored/dir_cmd.c:1360 #, c-format msgid "3998 Device \"%s\" is not an autochanger.\n" msgstr "" #: src/stored/dir_cmd.c:1384 #, c-format msgid "3908 Error scanning autochanger drives/list/slots command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1425 #, c-format msgid "3909 Error scanning readlabel command: %s\n" msgstr "" #: src/stored/dir_cmd.c:1452 #, c-format msgid "3001 Volume=%s Slot=%d\n" msgstr "" #: src/stored/dir_cmd.c:1483 #, c-format msgid "3931 Device \"%s\" is BLOCKED. user unmounted.\n" msgstr "" #: src/stored/dir_cmd.c:1486 #, c-format msgid "" "3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n" msgstr "" #: src/stored/dir_cmd.c:1489 #, c-format msgid "3933 Device \"%s\" is BLOCKED waiting for media.\n" msgstr "" #: src/stored/dir_cmd.c:1492 #, c-format msgid "3934 Device \"%s\" is being initialized.\n" msgstr "" #: src/stored/dir_cmd.c:1496 #, c-format msgid "3935 Device \"%s\" is blocked labeling a Volume.\n" msgstr "" #: src/stored/dir_cmd.c:1500 #, c-format msgid "3935 Device \"%s\" is blocked for unknown reason.\n" msgstr "" #: src/stored/dir_cmd.c:1505 #, c-format msgid "3936 Device \"%s\" is busy reading.\n" msgstr "" #: src/stored/dir_cmd.c:1507 #, c-format msgid "3937 Device \"%s\" is busy with writers=%d reserved=%d.\n" msgstr "" #: src/stored/dir_cmd.c:1597 src/filed/dir_cmd.c:1526 #, c-format msgid "Failed to connect to Storage daemon: %s:%d\n" msgstr "" #: src/stored/dir_cmd.c:1609 src/filed/dir_cmd.c:1538 msgid "Failed to authenticate Storage daemon.\n" msgstr "" #: src/stored/dir_cmd.c:1655 #, fuzzy, c-format msgid "Bad passiveclientcmd command: %s" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/stored/dir_cmd.c:1673 #, fuzzy msgid "File Daemon" msgstr "Збирач" #: src/stored/dir_cmd.c:1679 #, fuzzy, c-format msgid "Failed to connect to File daemon: %s:%d\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/stored/dir_cmd.c:1690 #, fuzzy msgid "Failed to authenticate File daemon.\n" msgstr "Відкриті з'єднання із Збирачем.\n" #: src/stored/dir_cmd.c:1724 #, fuzzy, c-format msgid "Bad pluginoptionscmd command: %s" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/stored/ndmp_tape.c:462 msgid "" "Data read from volume bigger then NDMP databuffer, please increase the NDMP " "blocksize.\n" msgstr "" #: src/stored/ndmp_tape.c:472 #, fuzzy, c-format msgid "Encountered an unknown stream type %d\n" msgstr "Невідомий тип ресурсу %d\n" #: src/stored/ndmp_tape.c:590 #, c-format msgid "NDMP tape open failed: Security Key not found: %s\n" msgstr "" #: src/stored/ndmp_tape.c:651 src/stored/append.c:60 msgid "DCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:656 src/stored/append.c:65 msgid "DEVICE is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:717 src/stored/append.c:109 src/stored/btape.c:2253 #, c-format msgid "Write session label failed. ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:749 msgid "Creating virtual file attributes failed.\n" msgstr "" #: src/stored/ndmp_tape.c:763 src/stored/read.c:62 msgid "No Volume names found for restore.\n" msgstr "" #: src/stored/ndmp_tape.c:811 #, fuzzy, c-format msgid "Read session label failed. ERR=%s\n" msgstr "Помилка надсилання Hello до Збирача. ERR=%s\n" #: src/stored/ndmp_tape.c:869 src/stored/ndmp_tape.c:966 #: src/stored/ndmp_tape.c:1028 msgid "JCR is NULL!!!\n" msgstr "" #: src/stored/ndmp_tape.c:1092 src/stored/append.c:326 src/stored/mac.c:657 #, c-format msgid "Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n" msgstr "" #: src/stored/ndmp_tape.c:1110 src/stored/append.c:281 src/stored/btape.c:2372 #, fuzzy, c-format msgid "Error writing end session label. ERR=%s\n" msgstr "Помилка надсилання Hello до Збирача. ERR=%s\n" #: src/stored/ndmp_tape.c:1127 src/stored/append.c:298 src/stored/spool.c:296 #: src/stored/mac.c:175 src/stored/mac.c:635 #, c-format msgid "Fatal append error on device %s: ERR=%s\n" msgstr "" #: src/stored/ndmp_tape.c:1183 msgid "Illegal call to handle_ndmp_client_request with NULL session handle\n" msgstr "" #: src/stored/ndmp_tape.c:1223 msgid "Cannot initialize new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1230 msgid "Cannot commission new NDMA session\n" msgstr "" #: src/stored/ndmp_tape.c:1237 #, fuzzy msgid "Cannot initialize new NDMA connection\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/ndmp_tape.c:1365 src/lib/bnet_server_tcp.c:191 #, c-format msgid "Cannot open stream socket. ERR=%s. Current %s All %s\n" msgstr "" #: src/stored/ndmp_tape.c:1380 src/lib/bnet_server_tcp.c:204 #, c-format msgid "Cannot set SO_REUSEADDR on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1390 src/lib/bnet_server_tcp.c:213 #, c-format msgid "Cannot bind port %d: ERR=%s: Retrying ...\n" msgstr "" #: src/stored/ndmp_tape.c:1396 src/lib/bnet_server_tcp.c:218 #, c-format msgid "Cannot bind port %d: ERR=%s.\n" msgstr "" #: src/stored/ndmp_tape.c:1414 #, fuzzy, c-format msgid "Could not init ndmp client queue: ERR=%s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/ndmp_tape.c:1453 src/lib/bnet_server_tcp.c:288 #, c-format msgid "Error in select: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1468 src/lib/bnet_server_tcp.c:303 #, fuzzy, c-format msgid "Error in poll: %s\n" msgstr "Помилка у %s: ERR=%s\n" #: src/stored/ndmp_tape.c:1493 src/lib/bnet_server_tcp.c:328 #, c-format msgid "Connection from %s:%d refused by hosts.access\n" msgstr "" #: src/stored/ndmp_tape.c:1509 src/lib/bnet_server_tcp.c:342 #: src/lib/bsock_tcp.c:284 src/lib/bsock_tcp.c:330 #, c-format msgid "Cannot set SO_KEEPALIVE on socket: %s\n" msgstr "" #: src/stored/ndmp_tape.c:1534 #, fuzzy, c-format msgid "Could not add job to ndmp client queue: ERR=%s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/ndmp_tape.c:1557 #, fuzzy, c-format msgid "Could not destroy ndmp client queue: ERR=%s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/fd_cmds.c:114 #, c-format msgid "FD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:123 src/stored/sd_cmds.c:113 #, c-format msgid "Hey!!!! JobId %u Job %s already authenticated.\n" msgstr "" #: src/stored/fd_cmds.c:140 src/filed/sd_cmds.c:79 msgid "Unable to authenticate File daemon\n" msgstr "" #: src/stored/fd_cmds.c:231 #, c-format msgid "Command error with FD, hanging up. %s\n" msgstr "" #: src/stored/fd_cmds.c:234 msgid "Command error with FD, hanging up.\n" msgstr "" #: src/stored/fd_cmds.c:246 #, c-format msgid "FD command not found: %s\n" msgstr "" #: src/stored/fd_cmds.c:272 msgid "Append data error.\n" msgstr "" #: src/stored/fd_cmds.c:277 msgid "Attempt to append on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:289 src/stored/fd_cmds.c:330 src/stored/sd_cmds.c:359 msgid "Attempt to close non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:305 src/stored/sd_cmds.c:299 msgid "Attempt to open already open session.\n" msgstr "" #: src/stored/fd_cmds.c:362 msgid "Attempt to read on non-open session.\n" msgstr "" #: src/stored/fd_cmds.c:379 src/stored/fd_cmds.c:388 msgid "Attempt to open read on non-open session.\n" msgstr "" #: src/stored/read.c:135 #, c-format msgid ">filed: Error Hdr=%s" msgstr "" #: src/stored/read.c:136 src/stored/read.c:153 #, c-format msgid "Error sending to File daemon. ERR=%s\n" msgstr "" #: src/stored/read.c:152 #, c-format msgid "Error sending to FD. ERR=%s\n" msgstr "" #: src/stored/sd_plugins.c:470 #, c-format msgid "Illegal SD plugin options encountered, %s skipping\n" msgstr "" #: src/stored/sd_plugins.c:496 #, c-format msgid "Illegal SD plugin options encountered, %s instance %d skipping\n" msgstr "" #: src/stored/stored_conf.c:374 #, c-format msgid "Expected a Device Type keyword, got: %s" msgstr "" #: src/stored/stored_conf.c:388 #, c-format msgid "" "Maximum Block Size configured value %u is greater than allowed maximum: %u" msgstr "" #: src/stored/stored_conf.c:409 #, fuzzy, c-format msgid "Expected a IO direction keyword, got: %s" msgstr "Помилка автентифікації : %s" #: src/stored/stored_conf.c:432 #, fuzzy, c-format msgid "Expected a Compression algorithm keyword, got: %s" msgstr "Помилка автентифікації : %s" #: src/stored/stored_conf.c:451 #, c-format msgid "Warning: no \"%s\" resource (%d) defined.\n" msgstr "" #: src/stored/stored_conf.c:454 #, c-format msgid "dump_resource type=%d\n" msgstr "" #: src/stored/stored_conf.c:575 #, c-format msgid "Warning: unknown resource type %d\n" msgstr "" #: src/stored/stored_conf.c:806 #, c-format msgid "\"%s\" item is required in \"%s\" resource, but not found.\n" msgstr "" #: src/stored/stored_conf.c:814 #, c-format msgid "Too many items in \"%s\" resource\n" msgstr "" #: src/stored/stored_conf.c:858 #, c-format msgid "Cannot find AutoChanger resource %s\n" msgstr "" #: src/stored/stored_conf.c:874 #, fuzzy, c-format msgid "Unable to init lock: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/stored_conf.c:913 #, c-format msgid "" "Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n" msgstr "" #: src/stored/stored_conf.c:1001 #, c-format msgid "No Storage resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/dev.c:148 #, c-format msgid "Unable to stat device %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:160 #, c-format msgid "%s is an unknown device type. Must be tape or directory, st_mode=%x\n" msgstr "" #: src/stored/dev.c:225 #, fuzzy, c-format msgid "%s has an unknown device type %d\n" msgstr "Невідомий тип ресурсу %d\n" #: src/stored/dev.c:286 #, c-format msgid "Unable to stat mount point %s: ERR=%s\n" msgstr "" #: src/stored/dev.c:291 msgid "" "Mount and unmount commands must defined for a device which requires mount.\n" msgstr "" #: src/stored/dev.c:304 src/stored/dev.c:439 #, c-format msgid "Min block size > max on device %s\n" msgstr "" #: src/stored/dev.c:307 src/stored/dev.c:443 #, c-format msgid "Block size %u on device %s is too large, using default %u\n" msgstr "" #: src/stored/dev.c:312 src/stored/dev.c:449 #, c-format msgid "Max block size %u not multiple of device %s block size=%d.\n" msgstr "" #: src/stored/dev.c:316 src/stored/dev.c:454 #, c-format msgid "Max Vol Size < 8 * Max Block Size for device %s\n" msgstr "" #: src/stored/dev.c:325 src/stored/dev.c:370 src/stored/acquire.c:647 #: src/lib/crypto_openssl.c:1517 src/lib/crypto_openssl.c:1576 #, c-format msgid "Unable to init mutex: ERR=%s\n" msgstr "" #: src/stored/dev.c:332 src/stored/dev.c:339 #, c-format msgid "Unable to init cond variable: ERR=%s\n" msgstr "" #: src/stored/dev.c:346 #, fuzzy, c-format msgid "Unable to init spool mutex: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/dev.c:353 #, fuzzy, c-format msgid "Unable to init acquire mutex: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/dev.c:360 #, fuzzy, c-format msgid "Unable to init read acquire mutex: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/dev.c:565 msgid "Illegal mode given to open dev.\n" msgstr "" #: src/stored/dev.c:589 #, c-format msgid "Could not open file device %s. No Volume name given.\n" msgstr "" #: src/stored/dev.c:615 #, c-format msgid "Could not open: %s, ERR=%s\n" msgstr "" #: src/stored/dev.c:654 src/stored/dev.c:726 src/stored/dev.c:761 #: src/stored/dev.c:847 #, c-format msgid "lseek error on %s. ERR=%s.\n" msgstr "" #: src/stored/dev.c:696 src/stored/backends/generic_tape_device.c:160 #: src/stored/backends/unix_fifo_device.c:125 #, c-format msgid "Bad call to eod. Device %s not open\n" msgstr "" #: src/stored/dev.c:745 msgid "Bad device call. Device not open\n" msgstr "" #: src/stored/dev.c:760 #, c-format msgid "Seek error: ERR=%s\n" msgstr "" #: src/stored/dev.c:833 msgid "Bad call to reposition. Device not open\n" msgstr "" #: src/stored/dev.c:904 #, fuzzy, c-format msgid "Unable to close device %s. ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/stored/device.c:111 #, c-format msgid "End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n" msgstr "" #: src/stored/device.c:130 #, c-format msgid "New volume \"%s\" mounted on device %s at %s.\n" msgstr "" #: src/stored/device.c:142 #, c-format msgid "write_block_to_device Volume label failed. ERR=%s" msgstr "" #: src/stored/device.c:177 #, c-format msgid "write_block_to_device overflow block failed. ERR=%s" msgstr "" #: src/stored/device.c:182 #, c-format msgid "Catastrophic error. Cannot write overflow block to device %s. ERR=%s" msgstr "" #: src/stored/device.c:287 src/stored/btape.c:483 src/stored/bcopy.c:232 #, c-format msgid "dev open failed: %s\n" msgstr "" #: src/stored/device.c:314 src/stored/backends/generic_tape_device.c:138 #: src/stored/backends/unix_fifo_device.c:105 #, c-format msgid "Unable to open device %s: ERR=%s\n" msgstr "" #: src/stored/device.c:316 #, c-format msgid "Unable to open archive %s: ERR=%s\n" msgstr "" #: src/stored/device.c:340 #, c-format msgid "Forward spacing Volume \"%s\" to file:block %u:%u.\n" msgstr "" #: src/stored/bscan.c:104 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) " "\n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: " "%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage " "daemon\n" " configuration file for the Key Encryption Key " "selection\n" " -a specify the database backend directory (default %" "s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from " "configuration file)\n" " -? print this message\n" "\n" msgstr "" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s без сигналів\n" " -t перевірка - прочитати конфігурацію і вийти\n" " -? print this message.\n" "\n" #: src/stored/bscan.c:273 src/stored/btape.c:272 src/stored/bls.c:224 #: src/stored/bextract.c:213 src/stored/bcopy.c:181 #, c-format msgid "No Director resource named %s defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:287 src/stored/stored.c:350 #, c-format msgid "No Working Directory defined in %s. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:295 #, c-format msgid "Working Directory: %s not found. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:299 #, c-format msgid "Working Directory: %s is not a directory. Cannot continue.\n" msgstr "" #: src/stored/bscan.c:315 src/stored/bscan.c:402 #, c-format msgid "First Volume Size = %s\n" msgstr "" #: src/stored/bscan.c:374 #, c-format msgid "Create JobMedia for Job %s\n" msgstr "" #: src/stored/bscan.c:384 #, c-format msgid "Could not create JobMedia record for Volume=%s Job=%s\n" msgstr "" #: src/stored/bscan.c:450 #, c-format msgid "done: %d%%\n" msgstr "" #: src/stored/bscan.c:458 src/stored/bcopy.c:269 #, c-format msgid "Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n" msgstr "" #: src/stored/bscan.c:474 msgid "Volume is prelabeled. This tape cannot be scanned.\n" msgstr "" #: src/stored/bscan.c:486 #, c-format msgid "Pool record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:490 #, c-format msgid "VOL_LABEL: Pool record not found for Pool: %s\n" msgstr "" #: src/stored/bscan.c:496 #, c-format msgid "VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:500 #, c-format msgid "Pool type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:510 #, c-format msgid "Media record for %s found in DB.\n" msgstr "" #: src/stored/bscan.c:517 #, c-format msgid "VOL_LABEL: Media record not found for Volume: %s\n" msgstr "" #: src/stored/bscan.c:524 #, c-format msgid "VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n" msgstr "" #: src/stored/bscan.c:528 #, c-format msgid "Media type \"%s\" is OK.\n" msgstr "" #: src/stored/bscan.c:538 #, c-format msgid "VOL_LABEL: OK for Volume: %s\n" msgstr "" #: src/stored/bscan.c:545 #, c-format msgid "%d \"errors\" ignored before first Start of Session record.\n" msgstr "" #: src/stored/bscan.c:556 #, c-format msgid "SOS_LABEL: Found Job record for JobId: %d\n" msgstr "" #: src/stored/bscan.c:561 #, c-format msgid "SOS_LABEL: Job record not found for JobId: %d\n" msgstr "" #: src/stored/bscan.c:601 #, c-format msgid "SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:607 #, c-format msgid "SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:613 #, c-format msgid "SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n" msgstr "" #: src/stored/bscan.c:631 src/stored/bscan.c:1212 #, c-format msgid "Could not find SessId=%d SessTime=%d for EOS record.\n" msgstr "" #: src/stored/bscan.c:676 #, c-format msgid "Could not update job record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:687 #, c-format msgid "End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n" msgstr "" #: src/stored/bscan.c:699 #, c-format msgid "Could not find Job for SessId=%d SessTime=%d record.\n" msgstr "" #: src/stored/bscan.c:717 src/stored/bls.c:402 src/stored/bextract.c:506 msgid "Cannot continue.\n" msgstr "" #: src/stored/bscan.c:730 #, c-format msgid "%s file records. At file:blk=%s:%s bytes=%s\n" msgstr "" #: src/stored/bscan.c:795 #, c-format msgid "Got MD5 record: %s\n" msgstr "" #: src/stored/bscan.c:803 #, c-format msgid "Got SHA1 record: %s\n" msgstr "" #: src/stored/bscan.c:811 #, c-format msgid "Got SHA256 record: %s\n" msgstr "" #: src/stored/bscan.c:819 #, c-format msgid "Got SHA512 record: %s\n" msgstr "" #: src/stored/bscan.c:827 src/stored/bscan.c:834 msgid "Got signed digest record\n" msgstr "Отримано підписаний відбиток запису\n" #: src/stored/bscan.c:840 #, c-format msgid "Got Prog Names Stream: %s\n" msgstr "" #: src/stored/bscan.c:846 msgid "Got Prog Data Stream record.\n" msgstr "" #: src/stored/bscan.c:905 #, c-format msgid "Unknown stream type!!! stream=%d len=%i\n" msgstr "" #: src/stored/bscan.c:982 #, c-format msgid "Could not create File Attributes record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:988 #, c-format msgid "Created File record: %s\n" msgstr "" #: src/stored/bscan.c:1033 #, c-format msgid "Could not create media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1037 src/stored/bscan.c:1058 #, c-format msgid "Could not update media record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1041 #, c-format msgid "Created Media record for Volume: %s\n" msgstr "" #: src/stored/bscan.c:1062 #, c-format msgid "Updated Media record at end of Volume: %s\n" msgstr "" #: src/stored/bscan.c:1079 #, c-format msgid "Could not create pool record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1083 #, c-format msgid "Created Pool record for Pool: %s\n" msgstr "" #: src/stored/bscan.c:1101 #, c-format msgid "Could not get Client record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1111 #, c-format msgid "Created Client record for Client: %s\n" msgstr "" #: src/stored/bscan.c:1128 #, c-format msgid "Fileset \"%s\" already exists.\n" msgstr "" #: src/stored/bscan.c:1132 #, c-format msgid "Could not create FileSet record \"%s\". ERR=%s\n" msgstr "" #: src/stored/bscan.c:1137 #, c-format msgid "Created FileSet record \"%s\"\n" msgstr "" #: src/stored/bscan.c:1184 #, c-format msgid "Could not create JobId record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1190 #, c-format msgid "Could not update job start record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1193 #, c-format msgid "Created new JobId=%u record for original JobId=%u\n" msgstr "" #: src/stored/bscan.c:1246 #, c-format msgid "Could not update JobId=%u record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1251 #, c-format msgid "Updated Job termination record for JobId=%u Level=%s TermStat=%c\n" msgstr "" #: src/stored/bscan.c:1276 #, c-format msgid "Job Termination code: %d" msgstr "" #: src/stored/bscan.c:1281 #, c-format msgid "" "%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n" "\n" msgstr "" #: src/stored/bscan.c:1339 #, c-format msgid "Could not create JobMedia record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1343 #, c-format msgid "Created JobMedia record JobId %d, MediaId %d\n" msgstr "" #: src/stored/bscan.c:1359 #, c-format msgid "Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n" msgstr "" #: src/stored/bscan.c:1373 #, c-format msgid "Could not add MD5/SHA1 to File record. ERR=%s\n" msgstr "" #: src/stored/bscan.c:1378 msgid "Updated MD5/SHA1 record\n" msgstr "" #: src/stored/append.c:72 msgid "Unable to set network buffer size.\n" msgstr "" #: src/stored/append.c:87 src/stored/append.c:102 src/stored/append.c:115 #: src/stored/askdir.c:346 src/stored/askdir.c:347 msgid "NULL Volume name. This shouldn't happen!!!\n" msgstr "" #: src/stored/append.c:123 #, fuzzy, c-format msgid "Network send error to %s. ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/stored/append.c:161 #, fuzzy, c-format msgid "Error reading data header from %s. ERR=%s\n" msgstr "Помилка надсилання Hello до Збирача. ERR=%s\n" #: src/stored/append.c:169 #, c-format msgid "Malformed data header from %s: %s\n" msgstr "" #: src/stored/append.c:190 #, c-format msgid "FI=%d from %s not positive or sequential=%d\n" msgstr "" #: src/stored/append.c:243 #, fuzzy, c-format msgid "Network error reading from %s. ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/stored/append.c:300 src/stored/mac.c:637 msgid "Set ok=FALSE after write_block_to_device.\n" msgstr "" #: src/stored/append.c:367 #, c-format msgid "Error updating file attributes. ERR=%s\n" msgstr "" #: src/stored/btape.c:159 src/stored/stored.c:125 #, c-format msgid "Tape block size (%d) not multiple of system size (%d)\n" msgstr "" #: src/stored/btape.c:163 src/stored/stored.c:129 #, c-format msgid "Tape block size (%d) is not a power of 2\n" msgstr "" #: src/stored/btape.c:166 #, c-format msgid "" "\n" "\n" "!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or " "more !!!!!\n" "\n" "\n" msgstr "" #: src/stored/btape.c:173 #, c-format msgid "32 bit printf/scanf problem. i=%d x32=%u y32=%u\n" msgstr "" #: src/stored/btape.c:182 msgid "64 bit printf/scanf problem. i=%d x64=%" msgstr "" #: src/stored/btape.c:187 #, c-format msgid "Tape block granularity is %d bytes.\n" msgstr "" #: src/stored/btape.c:284 msgid "No archive name specified.\n" msgstr "" #: src/stored/btape.c:288 msgid "Improper number of arguments specified.\n" msgstr "" #: src/stored/btape.c:305 msgid "btape only works with tape storage.\n" msgstr "" #: src/stored/btape.c:393 #, c-format msgid "Total Volume bytes=%sB. Total Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:419 #, c-format msgid "Volume bytes=%sB. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:487 #, c-format msgid "open device %s: OK\n" msgstr "" #: src/stored/btape.c:510 msgid "Enter Volume Name: " msgstr "" #: src/stored/btape.c:517 #, c-format msgid "Device open failed. ERR=%s\n" msgstr "" #: src/stored/btape.c:522 #, c-format msgid "Wrote Volume label for volume \"%s\".\n" msgstr "" #: src/stored/btape.c:536 msgid "Volume has no label.\n" msgstr "" #: src/stored/btape.c:539 msgid "Volume label read correctly.\n" msgstr "" #: src/stored/btape.c:542 #, c-format msgid "I/O error on device: ERR=%s" msgstr "" #: src/stored/btape.c:545 msgid "Volume name error\n" msgstr "" #: src/stored/btape.c:548 #, c-format msgid "Error creating label. ERR=%s" msgstr "" #: src/stored/btape.c:551 msgid "Volume version error.\n" msgstr "" #: src/stored/btape.c:554 msgid "Bad Volume label type.\n" msgstr "" #: src/stored/btape.c:557 msgid "Unknown error.\n" msgstr "" #: src/stored/btape.c:575 #, c-format msgid "Bad status from load. ERR=%s\n" msgstr "" #: src/stored/btape.c:577 #, c-format msgid "Loaded %s\n" msgstr "" #: src/stored/btape.c:586 src/stored/btape.c:1156 src/stored/btape.c:1229 #: src/stored/btape.c:1309 src/stored/btape.c:1580 #, c-format msgid "Bad status from rewind. ERR=%s\n" msgstr "" #: src/stored/btape.c:589 src/stored/btape.c:1588 #, c-format msgid "Rewound %s\n" msgstr "" #: src/stored/btape.c:615 src/stored/btape.c:1592 #, c-format msgid "Bad status from weof. ERR=%s\n" msgstr "" #: src/stored/btape.c:619 #, c-format msgid "Wrote 1 EOF to %s\n" msgstr "" #: src/stored/btape.c:622 #, c-format msgid "Wrote %d EOFs to %s\n" msgstr "" #: src/stored/btape.c:640 msgid "Moved to end of medium.\n" msgstr "" #: src/stored/btape.c:667 #, c-format msgid "Bad status from bsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:669 #, c-format msgid "Backspaced %d file%s.\n" msgstr "" #: src/stored/btape.c:686 #, c-format msgid "Bad status from bsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:688 #, c-format msgid "Backspaced %d record%s.\n" msgstr "" #: src/stored/btape.c:698 src/stored/status.c:544 #, c-format msgid "Configured device capabilities:\n" msgstr "" #: src/stored/btape.c:716 #, c-format msgid "Device status:\n" msgstr "" #: src/stored/btape.c:730 src/stored/status.c:602 #, c-format msgid "Device parameters:\n" msgstr "" #: src/stored/btape.c:735 #, c-format msgid "Status:\n" msgstr "" #: src/stored/btape.c:750 msgid "" "Test writing larger and larger records.\n" "This is a torture test for records.\n" "I am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n" msgstr "" #: src/stored/btape.c:756 msgid "Do you want to continue? (y/n): " msgstr "" #: src/stored/btape.c:758 src/stored/btape.c:2216 msgid "Command aborted.\n" msgstr "" #: src/stored/btape.c:775 #, c-format msgid "Block %d i=%d\n" msgstr "" #: src/stored/btape.c:802 msgid "Skipping read backwards test because BSR turned off.\n" msgstr "" #: src/stored/btape.c:806 msgid "" "\n" "=== Write, backup, and re-read test ===\n" "\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n" "\n" "This is not an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:819 src/stored/btape.c:830 src/stored/btape.c:841 #: src/stored/btape.c:1166 src/stored/btape.c:1182 src/stored/btape.c:1924 #: src/stored/btape.c:2849 msgid "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:823 src/stored/btape.c:834 src/stored/btape.c:845 #: src/stored/btape.c:1170 src/stored/btape.c:1186 src/stored/btape.c:1928 #: src/stored/btape.c:2853 msgid "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:826 #, c-format msgid "Wrote first record of %d bytes.\n" msgstr "" #: src/stored/btape.c:837 #, c-format msgid "Wrote second record of %d bytes.\n" msgstr "" #: src/stored/btape.c:848 #, c-format msgid "Wrote third record of %d bytes.\n" msgstr "" #: src/stored/btape.c:855 src/stored/btape.c:860 #, c-format msgid "Backspace file failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:864 msgid "Backspaced over EOF OK.\n" msgstr "" #: src/stored/btape.c:866 #, c-format msgid "Backspace record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:869 msgid "Backspace record OK.\n" msgstr "" #: src/stored/btape.c:872 src/stored/btape.c:878 #, c-format msgid "Read block failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:883 msgid "Bad data in record. Test failed!\n" msgstr "" #: src/stored/btape.c:887 msgid "" "\n" "Block re-read correct. Test succeeded!\n" msgstr "" #: src/stored/btape.c:888 msgid "" "=== End Write, backup, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:895 msgid "" "This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n" "\n" "Backward Space Record = No\n" "\n" "to your Storage daemon's Device resource definition.\n" msgstr "" #: src/stored/btape.c:917 #, c-format msgid "Begin writing %i files of %sB with raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:938 src/stored/btape.c:2905 #, c-format msgid "Write failed at block %u. status=%d ERR=%s\n" msgstr "" #: src/stored/btape.c:972 #, c-format msgid "Begin writing %i files of %sB with blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:981 msgid "" "\n" "Error writing record to block.\n" msgstr "" #: src/stored/btape.c:985 msgid "" "\n" "Error writing block to device.\n" msgstr "" #: src/stored/btape.c:1040 msgid "The file_size is too big, stop this test with Ctrl-c.\n" msgstr "" #: src/stored/btape.c:1068 msgid "Test with zero data, should give the maximum throughput.\n" msgstr "" #: src/stored/btape.c:1080 src/stored/btape.c:1106 msgid "Test with random data, should give the minimum throughput.\n" msgstr "" #: src/stored/btape.c:1095 msgid "Test with zero data and bareos block structure.\n" msgstr "" #: src/stored/btape.c:1142 #, c-format msgid "" "\n" "=== Write, rewind, and re-read test ===\n" "\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n" "\n" "This is an *essential* feature ...\n" "\n" msgstr "" #: src/stored/btape.c:1174 src/stored/btape.c:1190 #, c-format msgid "Wrote %d blocks of %d bytes.\n" msgstr "" #: src/stored/btape.c:1232 src/stored/btape.c:1312 msgid "Rewind OK.\n" msgstr "" #: src/stored/btape.c:1245 src/stored/btape.c:1364 msgid "Got EOF on tape.\n" msgstr "" #: src/stored/btape.c:1250 #, c-format msgid "Read block %d failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1256 #, c-format msgid "Read record failed. Block %d! ERR=%s\n" msgstr "" #: src/stored/btape.c:1262 src/stored/btape.c:1394 #, c-format msgid "Bad data in record. Expected %d, got %d at byte %d. Test failed!\n" msgstr "" #: src/stored/btape.c:1269 #, c-format msgid "%d blocks re-read correctly.\n" msgstr "" #: src/stored/btape.c:1272 src/stored/btape.c:1401 msgid "" "=== Test Succeeded. End Write, rewind, and re-read test ===\n" "\n" msgstr "" #: src/stored/btape.c:1300 msgid "Block position test\n" msgstr "" #: src/stored/btape.c:1355 #, c-format msgid "Reposition to file:block %d:%d\n" msgstr "" #: src/stored/btape.c:1357 msgid "Reposition error.\n" msgstr "" #: src/stored/btape.c:1370 #, c-format msgid "" "Read block %d failed! file=%d blk=%d. ERR=%s\n" "\n" msgstr "" #: src/stored/btape.c:1372 msgid "" "This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n" msgstr "" #: src/stored/btape.c:1388 #, c-format msgid "Read record failed! ERR=%s\n" msgstr "" #: src/stored/btape.c:1399 #, c-format msgid "Block %d re-read correctly.\n" msgstr "" #: src/stored/btape.c:1420 msgid "" "\n" "\n" "=== Append files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write one record in file 0,\n" " two records in file 1,\n" " and three records in file 2\n" "\n" msgstr "" #: src/stored/btape.c:1444 msgid "Now moving to end of medium.\n" msgstr "" #: src/stored/btape.c:1446 src/stored/btape.c:1675 #, c-format msgid "We should be in file 3. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is correct!" msgstr "" #: src/stored/btape.c:1447 src/stored/btape.c:1465 src/stored/btape.c:1664 #: src/stored/btape.c:1676 src/stored/btape.c:1689 src/stored/btape.c:1706 msgid "This is NOT correct!!!!" msgstr "" #: src/stored/btape.c:1453 msgid "" "\n" "Now the important part, I am going to attempt to append to the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1460 msgid "" "Done appending, there should be no I/O errors\n" "\n" msgstr "" #: src/stored/btape.c:1461 msgid "Doing Bareos scan of blocks:\n" msgstr "" #: src/stored/btape.c:1463 msgid "End scanning the tape.\n" msgstr "" #: src/stored/btape.c:1464 src/stored/btape.c:1688 #, c-format msgid "We should be in file 4. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1489 msgid "" "\n" "Autochanger enabled, but no name or no command device specified.\n" msgstr "" #: src/stored/btape.c:1493 msgid "" "\n" "Ah, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n" msgstr "" #: src/stored/btape.c:1496 msgid "" "\n" "Do you wish to continue with the Autochanger test? (y/n): " msgstr "" #: src/stored/btape.c:1503 msgid "" "\n" "\n" "=== Autochanger test ===\n" "\n" msgstr "" #: src/stored/btape.c:1512 msgid "3301 Issuing autochanger \"loaded\" command.\n" msgstr "" #: src/stored/btape.c:1521 #, c-format msgid "3991 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1522 #, c-format msgid "3991 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1526 #, c-format msgid "Slot %d loaded. I am going to unload it.\n" msgstr "" #: src/stored/btape.c:1528 msgid "Nothing loaded in the drive. OK.\n" msgstr "" #: src/stored/btape.c:1535 #, c-format msgid "3302 Issuing autochanger \"unload %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1540 #, c-format msgid "unload status=%s %d\n" msgstr "" #: src/stored/btape.c:1540 msgid "Bad" msgstr "" #: src/stored/btape.c:1543 #, c-format msgid "3992 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1544 #, c-format msgid "3992 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1554 #, c-format msgid "3303 Issuing autochanger \"load %d %d\" command.\n" msgstr "" #: src/stored/btape.c:1562 #, c-format msgid "3303 Autochanger \"load %d %d\" status is OK.\n" msgstr "" #: src/stored/btape.c:1566 #, c-format msgid "3993 Bad autochanger command: %s\n" msgstr "" #: src/stored/btape.c:1567 #, c-format msgid "3993 result=\"%s\": ERR=%s\n" msgstr "" #: src/stored/btape.c:1582 msgid "" "\n" "The test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n" msgstr "" #: src/stored/btape.c:1595 #, c-format msgid "Wrote EOF to %s\n" msgstr "" #: src/stored/btape.c:1599 #, c-format msgid "" "\n" "The test worked this time. Please add:\n" "\n" " sleep %d\n" "\n" "to your mtx-changer script in the load) case.\n" "\n" msgstr "" #: src/stored/btape.c:1604 msgid "" "\n" "The test autochanger worked!!\n" "\n" msgstr "" #: src/stored/btape.c:1615 msgid "You must correct this error or the Autochanger will not work.\n" msgstr "" #: src/stored/btape.c:1633 msgid "" "\n" "\n" "=== Forward space files test ===\n" "\n" "This test is essential to Bareos.\n" "\n" "I'm going to write five files then test forward spacing\n" "\n" msgstr "" #: src/stored/btape.c:1658 msgid "Now forward spacing 1 file.\n" msgstr "" #: src/stored/btape.c:1660 src/stored/btape.c:1672 src/stored/btape.c:1685 #: src/stored/btape.c:1703 src/stored/btape.c:1879 #, c-format msgid "Bad status from fsr. ERR=%s\n" msgstr "" #: src/stored/btape.c:1663 #, c-format msgid "We should be in file 1. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1670 msgid "Now forward spacing 2 files.\n" msgstr "" #: src/stored/btape.c:1683 msgid "Now forward spacing 4 files.\n" msgstr "" #: src/stored/btape.c:1695 msgid "" "The test worked this time. Please add:\n" "\n" " Fast Forward Space File = no\n" "\n" "to your Device resource for this drive.\n" msgstr "" #: src/stored/btape.c:1701 msgid "Now forward spacing 1 more file.\n" msgstr "" #: src/stored/btape.c:1705 #, c-format msgid "We should be in file 5. I am at file %d. %s\n" msgstr "" #: src/stored/btape.c:1710 msgid "" "\n" "=== End Forward space files test ===\n" "\n" msgstr "" #: src/stored/btape.c:1714 msgid "" "\n" "The forward space file test failed.\n" msgstr "" #: src/stored/btape.c:1716 msgid "" "You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n" msgstr "" #: src/stored/btape.c:1722 msgid "" "You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1756 msgid "" "\n" "Append test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n" "\n" msgstr "" #: src/stored/btape.c:1764 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" "\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1771 msgid "" "\n" "\n" "That appears *NOT* to have corrected the problem.\n" msgstr "" #: src/stored/btape.c:1776 msgid "" "\n" "\n" "It looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n" msgstr "" #: src/stored/btape.c:1781 msgid "" "\n" "\n" "It looks like the test worked this time, please add:\n" "\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n" "\n" "to your Device resource in the Storage conf file.\n" msgstr "" #: src/stored/btape.c:1792 msgid "" "\n" "Append test failed.\n" "\n" "\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\n" "Perhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n" "\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n" "\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n" msgstr "" #: src/stored/btape.c:1814 msgid "" "\n" "The above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n" "\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n" "\n" msgstr "" #: src/stored/btape.c:1857 #, c-format msgid "Bad status from fsf. ERR=%s\n" msgstr "" #: src/stored/btape.c:1861 msgid "Forward spaced 1 file.\n" msgstr "" #: src/stored/btape.c:1864 #, c-format msgid "Forward spaced %d files.\n" msgstr "" #: src/stored/btape.c:1883 msgid "Forward spaced 1 record.\n" msgstr "" #: src/stored/btape.c:1886 #, c-format msgid "Forward spaced %d records.\n" msgstr "" #: src/stored/btape.c:1931 #, c-format msgid "Wrote one record of %d bytes.\n" msgstr "" #: src/stored/btape.c:1933 msgid "Wrote block to device.\n" msgstr "" #: src/stored/btape.c:1947 msgid "Enter length to read: " msgstr "" #: src/stored/btape.c:1952 msgid "Bad length entered, using default of 1024 bytes.\n" msgstr "" #: src/stored/btape.c:1961 #, c-format msgid "Read of %d bytes gives status=%d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1984 src/stored/btape.c:2033 #, c-format msgid "End of tape\n" msgstr "" #: src/stored/btape.c:1989 #, c-format msgid "Starting scan at file %u\n" msgstr "" #: src/stored/btape.c:1994 src/stored/backends/generic_tape_device.c:511 #, c-format msgid "read error on %s. ERR=%s.\n" msgstr "" #: src/stored/btape.c:1996 #, c-format msgid "Bad status from read %d. ERR=%s\n" msgstr "" #: src/stored/btape.c:1999 src/stored/btape.c:2013 src/stored/btape.c:2077 #: src/stored/btape.c:2089 src/stored/btape.c:2102 src/stored/btape.c:2118 #, c-format msgid "1 block of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2002 src/stored/btape.c:2016 src/stored/btape.c:2080 #: src/stored/btape.c:2092 src/stored/btape.c:2105 src/stored/btape.c:2121 #, c-format msgid "%d blocks of %d bytes in file %d\n" msgstr "" #: src/stored/btape.c:2024 src/stored/btape.c:2096 #, c-format msgid "End of File mark.\n" msgstr "" #: src/stored/btape.c:2045 src/stored/btape.c:2149 #, c-format msgid "Total files=%d, blocks=%d, bytes = %s\n" msgstr "" #: src/stored/btape.c:2109 #, c-format msgid "Short block read.\n" msgstr "" #: src/stored/btape.c:2112 #, c-format msgid "Error reading block. ERR=%s\n" msgstr "" #: src/stored/btape.c:2136 #, c-format msgid "" "Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s " "rlen=%d\n" msgstr "" #: src/stored/btape.c:2158 #, c-format msgid "Device status: %u. ERR=%s\n" msgstr "" #: src/stored/btape.c:2189 #, c-format msgid "" "\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n" "\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n" "\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n" "\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n" "\n" "This may take a long time -- hours! ...\n" "\n" msgstr "" #: src/stored/btape.c:2207 msgid "" "Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) " msgstr "" #: src/stored/btape.c:2210 msgid "Simple test (single tape) selected.\n" msgstr "" #: src/stored/btape.c:2213 msgid "Multiple tape test selected.\n" msgstr "" #: src/stored/btape.c:2257 msgid "Wrote Start of Session label.\n" msgstr "" #: src/stored/btape.c:2277 #, c-format msgid "%s Begin writing Bareos records to tape ...\n" msgstr "" #: src/stored/btape.c:2279 #, c-format msgid "%s Begin writing Bareos records to first tape ...\n" msgstr "" #: src/stored/btape.c:2305 msgid "Flush block failed.\n" msgstr "" #: src/stored/btape.c:2319 #, c-format msgid "Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:2329 #, c-format msgid "%s Flush block, write EOF\n" msgstr "" #: src/stored/btape.c:2338 msgid "Wrote 1000 blocks on second tape. Done.\n" msgstr "" #: src/stored/btape.c:2343 msgid "Not OK\n" msgstr "" #: src/stored/btape.c:2367 #, fuzzy msgid "Job canceled.\n" msgstr "Статус задачі: Відмінена" #: src/stored/btape.c:2378 msgid "Set ok=false after write_block_to_device.\n" msgstr "" #: src/stored/btape.c:2382 msgid "Wrote End of Session label.\n" msgstr "" #: src/stored/btape.c:2406 #, c-format msgid "Wrote state file last_block_num1=%d last_block_num2=%d\n" msgstr "" #: src/stored/btape.c:2410 #, c-format msgid "Could not create state file: %s ERR=%s\n" msgstr "" #: src/stored/btape.c:2421 #, c-format msgid "" "\n" "\n" "%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n" msgstr "" #: src/stored/btape.c:2424 #, c-format msgid "" "\n" "\n" "%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n" msgstr "" #: src/stored/btape.c:2430 #, fuzzy msgid "do_unfill failed.\n" msgstr "Помилка команди" #: src/stored/btape.c:2435 #, c-format msgid "%s: Error during test.\n" msgstr "" #: src/stored/btape.c:2470 msgid "" "\n" "The state file level has changed. You must redo\n" "the fill command.\n" msgstr "" #: src/stored/btape.c:2477 #, c-format msgid "" "\n" "Could not find the state file: %s ERR=%s\n" "You must redo the fill command.\n" msgstr "" #: src/stored/btape.c:2543 msgid "Mount first tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2561 msgid "Rewinding.\n" msgstr "" #: src/stored/btape.c:2566 #, c-format msgid "Reading the first 10000 records from %u:%u.\n" msgstr "" #: src/stored/btape.c:2570 src/stored/btape.c:2638 #, c-format msgid "Reposition from %u:%u to %u:%u\n" msgstr "" #: src/stored/btape.c:2573 src/stored/btape.c:2625 src/stored/btape.c:2641 #, c-format msgid "Reposition error. ERR=%s\n" msgstr "" #: src/stored/btape.c:2576 #, c-format msgid "Reading block %u.\n" msgstr "" #: src/stored/btape.c:2578 src/stored/btape.c:2630 src/stored/btape.c:2646 #, c-format msgid "Error reading block: ERR=%s\n" msgstr "" #: src/stored/btape.c:2583 msgid "" "\n" "The last block on the tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2586 msgid "" "\n" "The last block of the first tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2610 msgid "Mount second tape. Press enter when ready: " msgstr "" #: src/stored/btape.c:2623 #, c-format msgid "Reposition from %u:%u to 0:1\n" msgstr "" #: src/stored/btape.c:2628 src/stored/btape.c:2644 #, c-format msgid "Reading block %d.\n" msgstr "" #: src/stored/btape.c:2634 msgid "" "\n" "The first block on the second tape matches.\n" "\n" msgstr "" #: src/stored/btape.c:2650 msgid "" "\n" "The last block on the second tape matches. Test succeeded.\n" "\n" msgstr "" #: src/stored/btape.c:2673 #, c-format msgid "10000 records read now at %d:%d\n" msgstr "" #: src/stored/btape.c:2699 src/stored/btape.c:2710 src/stored/btape.c:2755 msgid "Last block written" msgstr "" #: src/stored/btape.c:2701 src/stored/btape.c:2711 msgid "Block read back" msgstr "" #: src/stored/btape.c:2702 #, c-format msgid "" "\n" "\n" "The blocks differ at byte %u\n" msgstr "" #: src/stored/btape.c:2703 msgid "" "\n" "\n" "!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n" msgstr "" #: src/stored/btape.c:2739 #, c-format msgid "Last block at: %u:%u this_dev_block_num=%d\n" msgstr "" #: src/stored/btape.c:2753 #, c-format msgid "Block not written: FileIndex=%u blk_block=%u Size=%u\n" msgstr "" #: src/stored/btape.c:2757 msgid "Block not written" msgstr "" #: src/stored/btape.c:2772 #, c-format msgid "End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n" msgstr "" #: src/stored/btape.c:2782 src/stored/bcopy.c:311 src/stored/bcopy.c:319 #: src/stored/bcopy.c:347 #, c-format msgid "Cannot fixup device error. %s\n" msgstr "" #: src/stored/btape.c:2823 msgid "Test writing blocks of 64512 bytes to tape.\n" msgstr "" #: src/stored/btape.c:2825 msgid "How many blocks do you want to write? (1000): " msgstr "" #: src/stored/btape.c:2842 #, c-format msgid "Begin writing %d Bareos blocks to tape ...\n" msgstr "" #: src/stored/btape.c:2885 #, c-format msgid "Begin writing raw blocks of %u bytes.\n" msgstr "" #: src/stored/btape.c:2916 msgid "test autochanger" msgstr "" #: src/stored/btape.c:2917 msgid "backspace file" msgstr "" #: src/stored/btape.c:2918 msgid "backspace record" msgstr "" #: src/stored/btape.c:2919 msgid "list device capabilities" msgstr "" #: src/stored/btape.c:2920 msgid "clear tape errors" msgstr "" #: src/stored/btape.c:2921 msgid "go to end of Bareos data for append" msgstr "" #: src/stored/btape.c:2922 msgid "go to the physical end of medium" msgstr "" #: src/stored/btape.c:2923 msgid "fill tape, write onto second volume" msgstr "" #: src/stored/btape.c:2924 msgid "read filled tape" msgstr "" #: src/stored/btape.c:2925 msgid "forward space a file" msgstr "" #: src/stored/btape.c:2926 msgid "forward space a record" msgstr "" #: src/stored/btape.c:2927 msgid "print this command" msgstr "" #: src/stored/btape.c:2928 msgid "write a Bareos label to the tape" msgstr "" #: src/stored/btape.c:2929 msgid "load a tape" msgstr "" #: src/stored/btape.c:2930 msgid "quit btape" msgstr "" #: src/stored/btape.c:2931 msgid "use write() to fill tape" msgstr "" #: src/stored/btape.c:2932 msgid "read and print the Bareos tape label" msgstr "" #: src/stored/btape.c:2933 msgid "test record handling functions" msgstr "" #: src/stored/btape.c:2934 msgid "rewind the tape" msgstr "" #: src/stored/btape.c:2935 msgid "read() tape block by block to EOT and report" msgstr "" #: src/stored/btape.c:2936 msgid "Bareos read block by block to EOT and report" msgstr "" #: src/stored/btape.c:2937 msgid "" "[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report " "drive speed" msgstr "" #: src/stored/btape.c:2938 msgid "print tape status" msgstr "" #: src/stored/btape.c:2939 msgid "General test Bareos tape functions" msgstr "" #: src/stored/btape.c:2940 msgid "write an EOF on the tape" msgstr "" #: src/stored/btape.c:2941 msgid "write a single Bareos block" msgstr "" #: src/stored/btape.c:2942 msgid "read a single record" msgstr "" #: src/stored/btape.c:2943 msgid "read a single Bareos block" msgstr "" #: src/stored/btape.c:2944 msgid "quick fill command" msgstr "" #: src/stored/btape.c:2965 #, c-format msgid "\"%s\" is an invalid command\n" msgstr "" #: src/stored/btape.c:2974 #, c-format msgid "Interactive commands:\n" msgstr "" #: src/stored/btape.c:2985 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: btape \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n" msgstr "" "Автор Nicolas Boichat (2004)\n" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: tray-monitor [-c config_file] [-d debug_level]\n" " -c задати конфігураційний файл \n" " -d встановити рівень відлагоджування у \n" " -dt виводити часову мітку у даних відлагоджування\n" " -t перевірка - прогитати конфігурацію і завершити\n" " -? показати це повідомлення.\n" "\n" #: src/stored/btape.c:3057 #, c-format msgid "Mount second Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3061 src/stored/askdir.c:685 #, c-format msgid "Mount Volume \"%s\" on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3088 #, c-format msgid "Mount blank Volume on device %s and press return when ready: " msgstr "" #: src/stored/btape.c:3118 #, c-format msgid "End of Volume \"%s\" %d records.\n" msgstr "" #: src/stored/btape.c:3132 #, c-format msgid "Read block=%u, VolBytes=%s rate=%sB/s\n" msgstr "" #: src/stored/btape.c:3145 src/stored/mount.c:895 #, c-format msgid "Cannot open Dev=%s, Vol=%s\n" msgstr "" #: src/stored/spool.c:75 msgid "Spooling statistics:\n" msgstr "" #: src/stored/spool.c:78 #, c-format msgid "" "Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n" msgstr "" #: src/stored/spool.c:86 #, c-format msgid "Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n" msgstr "" #: src/stored/spool.c:105 msgid "Spooling data ...\n" msgstr "" #: src/stored/spool.c:131 #, c-format msgid "Bad return from despool WroteVol=%d\n" msgstr "" #: src/stored/spool.c:165 #, c-format msgid "Open data spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:221 msgid "Despooling zero bytes. Your disk is probably FULL!\n" msgstr "" #: src/stored/spool.c:230 #, c-format msgid "Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:235 #, c-format msgid "Writing spooled data to Volume. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:317 src/stored/block.c:387 src/stored/block.c:816 #: src/stored/block.c:888 src/stored/acquire.c:502 #, c-format msgid "Could not create JobMedia record for Volume=\"%s\" Job=%s\n" msgstr "" #: src/stored/spool.c:335 #, c-format msgid "" "Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n" msgstr "" #: src/stored/spool.c:345 src/stored/spool.c:546 src/stored/spool.c:592 #, c-format msgid "Ftruncate spool file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:404 #, c-format msgid "Spool header read error. ERR=%s\n" msgstr "" #: src/stored/spool.c:406 #, c-format msgid "Spool read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:407 #, c-format msgid "Spool header read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:414 src/stored/spool.c:415 #, c-format msgid "Spool block too big. Max %u bytes, got %u\n" msgstr "" #: src/stored/spool.c:421 src/stored/spool.c:422 #, c-format msgid "Spool data read error. Wanted %u bytes, got %d\n" msgstr "" #: src/stored/spool.c:476 #, c-format msgid "" "User specified Job spool size reached: JobSpoolSize=%s MaxJobSpoolSize=%s\n" msgstr "" #: src/stored/spool.c:481 #, c-format msgid "" "User specified Device spool size reached: DevSpoolSize=%s MaxDevSpoolSize=%" "s\n" msgstr "" #: src/stored/spool.c:488 msgid "Bad return from despool in write_block.\n" msgstr "" #: src/stored/spool.c:496 msgid "Spooling data again ...\n" msgstr "" #: src/stored/spool.c:529 #, c-format msgid "Error writing header to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:533 #, c-format msgid "" "Error writing header to spool file. Disk probably full. Attempting recovery. " "Wanted to write=%d got=%d\n" msgstr "" #: src/stored/spool.c:551 src/stored/spool.c:597 msgid "Fatal despooling error." msgstr "" #: src/stored/spool.c:559 msgid "Retrying after header spooling error failed.\n" msgstr "" #: src/stored/spool.c:576 #, c-format msgid "Error writing data to spool file. ERR=%s\n" msgstr "" #: src/stored/spool.c:608 msgid "Retrying after data spooling error failed.\n" msgstr "" #: src/stored/spool.c:677 msgid "Network error on BlastAttributes.\n" msgstr "" #: src/stored/spool.c:701 #, fuzzy, c-format msgid "lseek on attributes file failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/stored/spool.c:716 #, fuzzy, c-format msgid "Truncate on attributes file failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/stored/spool.c:728 #, c-format msgid "Fseek on attributes file failed: ERR=%s\n" msgstr "" #: src/stored/spool.c:742 #, c-format msgid "Sending spooled attrs to the Director. Despooling %s bytes ...\n" msgstr "" #: src/stored/spool.c:769 #, c-format msgid "fopen attr spool file %s failed: ERR=%s\n" msgstr "" #: src/stored/reserve.c:84 #, c-format msgid "Unable to initialize reservation lock. ERR=%s\n" msgstr "" #: src/stored/reserve.c:153 #, c-format msgid "Hey! num_writers=%d!!!!\n" msgstr "" #: src/stored/reserve.c:258 msgid "3939 Could not get dcr\n" msgstr "" #: src/stored/reserve.c:366 #, c-format msgid "Device reservation failed for JobId=%d: %s\n" msgstr "" #: src/stored/reserve.c:375 #, c-format msgid "Failed command: %s\n" msgstr "" #: src/stored/reserve.c:665 #, c-format msgid "3926 Could not get dcr for device: %s\n" msgstr "" #: src/stored/reserve.c:796 #, c-format msgid "3601 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:806 #, c-format msgid "3602 JobId=%u device %s is busy (already reading/writing).\n" msgstr "" #: src/stored/reserve.c:858 #, c-format msgid "3603 JobId=%u device %s is busy reading.\n" msgstr "" #: src/stored/reserve.c:867 #, c-format msgid "3604 JobId=%u device %s is BLOCKED due to user unmount.\n" msgstr "" #: src/stored/reserve.c:909 #, c-format msgid "" "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %" "s.\n" msgstr "" #: src/stored/reserve.c:932 #, c-format msgid "3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:944 #, c-format msgid "3610 JobId=%u Volume max jobs exceeded on drive %s.\n" msgstr "" #: src/stored/reserve.c:996 #, c-format msgid "3605 JobId=%u wants free drive but device %s is busy.\n" msgstr "" #: src/stored/reserve.c:1005 #, c-format msgid "3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n" msgstr "" #: src/stored/reserve.c:1027 #, c-format msgid "3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n" msgstr "" #: src/stored/reserve.c:1081 #, c-format msgid "Logic error!!!! JobId=%u Should not get here.\n" msgstr "" #: src/stored/reserve.c:1082 #, c-format msgid "3910 JobId=%u Logic error!!!! drive %s Should not get here.\n" msgstr "" #: src/stored/reserve.c:1085 msgid "Logic error!!!! Should not get here.\n" msgstr "" #: src/stored/mac.c:87 src/filed/dir_cmd.c:2240 #, c-format msgid "Comm error with SD. bad response to %s. ERR=%s\n" msgstr "" #: src/stored/mac.c:90 src/filed/dir_cmd.c:2243 #, c-format msgid "Bad response to %s command. Wanted %s, got %s\n" msgstr "" #: src/stored/mac.c:291 src/stored/mac.c:304 src/stored/mac.c:325 #: src/stored/mac.c:536 src/findlib/xattr.c:98 src/findlib/xattr.c:113 #: src/findlib/xattr.c:121 src/findlib/acl.c:107 src/findlib/acl.c:122 #: src/findlib/acl.c:130 src/filed/fd_plugins.c:940 src/filed/fd_plugins.c:957 #: src/filed/backup.c:1017 src/filed/backup.c:1171 src/filed/backup.c:1243 #: src/filed/backup.c:1255 src/filed/backup.c:1338 src/filed/backup.c:1448 #, c-format msgid "Network send error to SD. ERR=%s\n" msgstr "" #: src/stored/mac.c:438 #, c-format msgid "No Volume names found for %s.\n" msgstr "" #: src/stored/mac.c:454 msgid "Read device not properly initialized.\n" msgstr "" #: src/stored/mac.c:479 msgid "Cannot set buffer size SD->SD.\n" msgstr "" #: src/stored/mac.c:496 #, fuzzy, c-format msgid "Bad response to start replicate: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/stored/mac.c:501 #, fuzzy msgid "Bad response from stored to start replicate command\n" msgstr "Невірна відповідь від Збирача на команду Hello: ERR=%s\n" #: src/stored/mac.c:568 msgid "Read and write devices not properly initialized.\n" msgstr "" #: src/stored/bls.c:64 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s без сигналів\n" " -t перевірка - прочитати конфігурацію і вийти\n" " -? print this message.\n" "\n" #: src/stored/bls.c:144 src/stored/bextract.c:145 #, c-format msgid "Could not open exclude file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:159 src/stored/bextract.c:160 #, c-format msgid "Could not open include file: %s, ERR=%s\n" msgstr "" #: src/stored/bls.c:206 msgid "No archive name specified\n" msgstr "" #: src/stored/bls.c:260 #, c-format msgid "" "\n" "Warning, this Volume is a continuation of Volume %s\n" msgstr "" #: src/stored/bls.c:302 #, c-format msgid "Got EOM at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:313 #, c-format msgid "Mounted Volume \"%s\".\n" msgstr "" #: src/stored/bls.c:315 #, c-format msgid "End of file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/bls.c:339 #, c-format msgid "" "File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%" "s rlen=%d\n" msgstr "" #: src/stored/bls.c:348 #, c-format msgid "Block: %d size=%d\n" msgstr "" #: src/stored/bls.c:404 msgid "Attrib unpack error!\n" msgstr "" #: src/stored/bls.c:415 #, c-format msgid "FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n" msgstr "" #: src/stored/bls.c:446 src/stored/read_record.c:52 src/stored/bcopy.c:361 msgid "Fresh Volume Label" msgstr "" #: src/stored/bls.c:449 src/stored/read_record.c:55 src/stored/bcopy.c:364 msgid "Volume Label" msgstr "" #: src/stored/bls.c:453 src/stored/label.c:1116 src/stored/bcopy.c:368 msgid "Begin Job Session" msgstr "" #: src/stored/bls.c:458 src/stored/label.c:1119 src/stored/bcopy.c:372 msgid "End Job Session" msgstr "" #: src/stored/bls.c:462 src/stored/bcopy.c:377 msgid "End of Medium" msgstr "" #: src/stored/bls.c:465 msgid "End of Physical Medium" msgstr "" #: src/stored/bls.c:468 msgid "Start of object" msgstr "" #: src/stored/bls.c:471 msgid "End of object" msgstr "" #: src/stored/bls.c:474 src/stored/label.c:1128 src/stored/bcopy.c:380 msgid "Unknown" msgstr "" #: src/stored/bls.c:481 src/stored/read_record.c:73 src/stored/bcopy.c:386 #, c-format msgid "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/backends/rados_device.c:49 #, fuzzy, c-format msgid "Unable to parse device %s.\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:62 #, fuzzy, c-format msgid "Unable to create RADOS cluster: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:69 #, fuzzy, c-format msgid "Unable to read RADOS config %s: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:77 #, fuzzy, c-format msgid "Unable to connect to RADOS cluster: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:89 #, fuzzy, c-format msgid "Unable to create RADOS IO context for pool %s: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:271 #, fuzzy, c-format msgid "Unable to stat volume %s. ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:278 #, fuzzy, c-format msgid "Unable to remove volume %s. ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/rados_device.c:325 #: src/stored/backends/gfapi_device.c:575 #: src/stored/backends/cephfs_device.c:306 #: src/stored/backends/unix_tape_device.c:56 #: src/stored/backends/object_store_device.c:491 #: src/stored/backends/unix_fifo_device.c:349 #, fuzzy, c-format msgid "Request for unknown devicetype: %d\n" msgstr "Невідомий тип ресурсу %d\n" #: src/stored/backends/gfapi_device.c:317 #, fuzzy, c-format msgid "Unable to parse device URI %s.\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/stored/backends/gfapi_device.c:329 #, c-format msgid "Unable to create new Gluster context for volumename %s.\n" msgstr "" #: src/stored/backends/gfapi_device.c:336 #, c-format msgid "" "Unable to initialize Gluster management server for transport %s, servername %" "s, serverport %d\n" msgstr "" #: src/stored/backends/gfapi_device.c:344 #, fuzzy, c-format msgid "Unable to initialize Gluster for volumename %s.\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/stored/backends/gfapi_device.c:372 #, c-format msgid "Specified glusterfs direcory %s cannot be created.\n" msgstr "" #: src/stored/backends/gfapi_device.c:382 #, fuzzy, c-format msgid "Specified glusterfs direcory %s is not a directory.\n" msgstr "%s існує, але не є текою.\n" #: src/stored/backends/cephfs_device.c:58 #, fuzzy, c-format msgid "Unable to create CEPHFS mount: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/cephfs_device.c:65 #, fuzzy, c-format msgid "Unable to read CEPHFS config %s: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/cephfs_device.c:72 #, fuzzy, c-format msgid "Unable to mount CEPHFS: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/backends/cephfs_device.c:101 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s cannot be created.\n" msgstr "%s існує, але не є текою.\n" #: src/stored/backends/cephfs_device.c:111 #, fuzzy, c-format msgid "Specified CEPHFS direcory %s is not a directory.\n" msgstr "%s існує, але не є текою.\n" #: src/stored/backends/generic_tape_device.c:212 #, c-format msgid "ioctl MTEOM error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:221 #: src/stored/backends/generic_tape_device.c:1242 #, c-format msgid "ioctl MTIOCGET error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:339 #, c-format msgid "ioctl MTOFFL error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:361 msgid "Bad call to weof_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:368 msgid "Attempt to WEOF on non-appendable Volume\n" msgstr "" #: src/stored/backends/generic_tape_device.c:387 #, c-format msgid "ioctl MTWEOF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:408 msgid "Bad call to fsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:415 #: src/stored/backends/generic_tape_device.c:561 #, c-format msgid "Device %s at End of Tape.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:449 #: src/stored/backends/generic_tape_device.c:542 #, c-format msgid "ioctl MTFSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:498 #, c-format msgid "read error on %s. ERR=Input/Output error.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:592 msgid "Bad call to bsf. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:611 #, c-format msgid "ioctl MTBSF error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:638 msgid "Bad call to fsr. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:644 #, c-format msgid "ioctl MTFSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:674 #, c-format msgid "ioctl MTFSR %d error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:693 msgid "Bad call to bsr_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:699 #, c-format msgid "ioctl MTBSR not permitted on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:715 #, c-format msgid "ioctl MTBSR error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:735 msgid "Bad call to load_dev. Device not open\n" msgstr "" #: src/stored/backends/generic_tape_device.c:744 #: src/stored/backends/generic_tape_device.c:755 #, c-format msgid "ioctl MTLOAD error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:947 #, c-format msgid "unknown func code %d" msgstr "" #: src/stored/backends/generic_tape_device.c:953 #, c-format msgid "I/O function \"%s\" not supported on this device.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1055 #, c-format msgid "Unable to set eotmodel on device %s: ERR=%s\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1148 #, c-format msgid "No tape loaded or drive offline on %s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1158 #, c-format msgid "Rewind error on %s. ERR=%s.\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1236 msgid " Bareos status:" msgstr "" #: src/stored/backends/generic_tape_device.c:1237 #: src/stored/backends/generic_tape_device.c:1321 #: src/stored/backends/generic_tape_device.c:1323 #, c-format msgid " file=%d block=%d\n" msgstr "" #: src/stored/backends/generic_tape_device.c:1246 msgid " Device status:" msgstr "" #: src/stored/backends/object_store_device.c:95 #, c-format msgid "Object Storage devices are not yet supported, please disable %s\n" msgstr "" #: src/stored/backends/object_store_device.c:173 #, fuzzy, c-format msgid "Failed to create a new context using config %s\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/stored/backends/object_store_device.c:190 #, c-format msgid "Failed to login for voume %s using dpl_login(): ERR=%s.\n" msgstr "" #: src/stored/backends/object_store_device.c:250 #: src/stored/backends/object_store_device.c:446 #, fuzzy, c-format msgid "Failed to open %s using dpl_open(): ERR=%s.\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/backends/object_store_device.c:274 #, fuzzy, c-format msgid "Failed to read %s using dpl_read(): ERR=%s.\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/backends/object_store_device.c:298 #, fuzzy, c-format msgid "Failed to write %s using dpl_write(): ERR=%s.\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/backends/object_store_device.c:406 #, fuzzy, c-format msgid "Failed to close %s using dpl_close(): ERR=%s.\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/backends/object_store_device.c:416 #, fuzzy, c-format msgid "Failed to unlink %s using dpl_unlink(): ERR=%s.\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/stored/status.c:101 msgid "Used Volume status:\n" msgstr "" #: src/stored/status.c:125 msgid "" "\n" "SD Resources:\n" msgstr "" #: src/stored/status.c:198 msgid "" "\n" "Device status:\n" msgstr "" #: src/stored/status.c:210 #, c-format msgid "Autochanger \"%s\" with devices:\n" msgstr "" #: src/stored/status.c:258 msgid "mounted with" msgstr "" #: src/stored/status.c:261 msgid "waiting for" msgstr "" #: src/stored/status.c:264 msgid "being labeled with" msgstr "" #: src/stored/status.c:267 msgid "being acquired with" msgstr "" #: src/stored/status.c:272 msgid "waiting for sysop intervention" msgstr "" #: src/stored/status.c:275 #, fuzzy msgid "unknown state" msgstr "Невідомий статус" #: src/stored/status.c:279 #, c-format msgid "" "\n" "Device %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:289 #, c-format msgid "" "\n" "Device %s open but no Bareos volume is currently mounted.\n" msgstr "" #: src/stored/status.c:302 #, c-format msgid " Total Bytes=%s Blocks=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:317 #, c-format msgid " Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n" msgstr "" #: src/stored/status.c:324 #, c-format msgid " Positioned at File=%s Block=%s\n" msgstr "" #: src/stored/status.c:332 #, c-format msgid "" "\n" "Device %s is not open.\n" msgstr "" #: src/stored/status.c:336 #, c-format msgid "" "\n" "Device \"%s\" is not open or does not exist.\n" msgstr "" #: src/stored/status.c:369 #, c-format msgid "Daemon started %s. Jobs: run=%d, running=%d.\n" msgstr "" #: src/stored/status.c:464 msgid "" "No DEVICE structure.\n" "\n" msgstr "" #: src/stored/status.c:470 msgid " Device is BLOCKED. User unmounted.\n" msgstr "" #: src/stored/status.c:474 msgid " Device is BLOCKED. User unmounted during wait for media/mount.\n" msgstr "" #: src/stored/status.c:484 #, c-format msgid "" " Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:493 #, c-format msgid "" " Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/status.c:504 msgid " Device is BLOCKED waiting for media.\n" msgstr "" #: src/stored/status.c:510 msgid " Device is being initialized.\n" msgstr "" #: src/stored/status.c:514 msgid " Device is blocked labeling a Volume.\n" msgstr "" #: src/stored/status.c:523 #, c-format msgid " Slot %d %s loaded in drive %d.\n" msgstr "" #: src/stored/status.c:527 #, c-format msgid " Drive %d is not loaded.\n" msgstr "" #: src/stored/status.c:563 msgid "Device state:\n" msgstr "" #: src/stored/status.c:581 #, c-format msgid " num_writers=%d reserves=%d block=%d\n" msgstr "" #: src/stored/status.c:585 msgid "Attached Jobs: " msgstr "" #: src/stored/status.c:604 #, c-format msgid " Archive name: %s Device name: %s\n" msgstr "" #: src/stored/status.c:607 #, c-format msgid " File=%u block=%u\n" msgstr "" #: src/stored/status.c:610 #, c-format msgid " Min block=%u Max block=%u\n" msgstr "" #: src/stored/status.c:633 #, c-format msgid "%s Job %s waiting for Client connection.\n" msgstr "" #: src/stored/status.c:649 #, c-format msgid "" "Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:662 #, c-format msgid "" "Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n" msgstr "" #: src/stored/status.c:673 #, c-format msgid " spooling=%d despooling=%d despool_wait=%d\n" msgstr "" #: src/stored/status.c:689 #, c-format msgid " Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n" msgstr "" #: src/stored/status.c:701 #, c-format msgid " FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n" msgstr "" #: src/stored/status.c:707 msgid " FDSocket closed\n" msgstr "" #: src/stored/status.c:735 msgid "" "\n" "Jobs waiting to reserve a drive:\n" msgstr "" #: src/stored/status.c:779 msgid "===================================================================\n" msgstr "" #: src/stored/status.c:869 src/lib/util.c:452 src/filed/status.c:528 msgid "Base" msgstr "" #: src/stored/status.c:887 src/filed/status.c:546 msgid "Init Catalog" msgstr "" #: src/stored/status.c:890 src/filed/status.c:549 msgid "Volume to Catalog" msgstr "" #: src/stored/status.c:893 src/filed/status.c:552 msgid "Disk to Catalog" msgstr "" #: src/stored/status.c:896 src/filed/status.c:555 msgid "Data" msgstr "" #: src/stored/status.c:902 src/lib/util.c:488 src/filed/status.c:561 msgid "Unknown Job Level" msgstr "" #: src/stored/status.c:955 #, fuzzy, c-format msgid "3900 No arg in status command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/stored/status.c:984 #, fuzzy, c-format msgid "3900 No arg in .status command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/stored/status.c:1033 #, fuzzy, c-format msgid "3900 Unknown arg in .status command: %s\n" msgstr "Невідомий статус задачі %c. " #: src/stored/status.c:1051 msgid "Bareos Storage: Idle" msgstr "" #: src/stored/status.c:1062 msgid "Bareos Storage: Running" msgstr "" #: src/stored/status.c:1076 msgid "Bareos Storage: Last Job Canceled" msgstr "" #: src/stored/status.c:1080 msgid "Bareos Storage: Last Job Failed" msgstr "" #: src/stored/status.c:1084 msgid "Bareos Storage: Last Job had Warnings" msgstr "" #: src/stored/sd_cmds.c:103 src/filed/sd_cmds.c:62 #, c-format msgid "SD connect failed: Job name not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:131 #, fuzzy msgid "Unable to authenticate Storage daemon\n" msgstr "Відкриті з'єднання із Зберігачем.\n" #: src/stored/sd_cmds.c:182 #, c-format msgid "Command error with SD, hanging up. %s\n" msgstr "" #: src/stored/sd_cmds.c:185 msgid "Command error with SD, hanging up.\n" msgstr "" #: src/stored/sd_cmds.c:197 #, c-format msgid "SD command not found: %s\n" msgstr "" #: src/stored/sd_cmds.c:338 msgid "Replicate data error.\n" msgstr "" #: src/stored/sd_cmds.c:343 msgid "Attempt to replicate on non-open session.\n" msgstr "" #: src/stored/authenticate.c:53 #, c-format msgid "I only authenticate Directors, not %d\n" msgstr "" #: src/stored/authenticate.c:63 src/filed/authenticate.c:82 #, c-format msgid "Bad Hello command from Director at %s. Len=%d.\n" msgstr "" #: src/stored/authenticate.c:74 src/filed/sd_cmds.c:55 #: src/filed/authenticate.c:94 #, c-format msgid "Bad Hello command from Director at %s: %s\n" msgstr "" #: src/stored/authenticate.c:90 #, fuzzy, c-format msgid "" "Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n" msgstr "" "Відмовлено у з'єднанні від невідомого Керівника %s %s.\n" "Для отримання допомоги, будь ласка, перегляньте http://www.bareos.org/en/rel-" "manual/Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000.\n" #: src/stored/authenticate.c:133 #, c-format msgid "" "Incorrect password given by Director.\n" "Please see %s for help.\n" msgstr "" #: src/stored/authenticate.c:143 src/stored/authenticate.c:267 #: src/filed/authenticate.c:174 src/filed/authenticate.c:310 msgid "" "Authorization problem: Remote server did not advertize required TLS " "support.\n" msgstr "" #: src/stored/authenticate.c:162 #, c-format msgid "TLS negotiation failed with DIR at \"%s:%d\"\n" msgstr "" #: src/stored/authenticate.c:257 #, fuzzy, c-format msgid "" "Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n" msgstr "" "Проблеми під час авторизації Керівником.\n" "Швидше за все, невірні паролі.\n" "Для отримання допомоги, будь ласка, перегляньте http://doc.bareos.org/master/" "html/bareos-manual-main-reference.html#AuthorizationErrors.\n" #: src/stored/authenticate.c:290 src/stored/authenticate.c:297 #, fuzzy, c-format msgid "TLS negotiation failed with %s daemon at \"%s:%d\"\n" msgstr "Встановлення TLS із Керівником невдале \"%s:%d\"\n" #: src/stored/authenticate.c:336 #, c-format msgid "Unable to authenticate Director at %s.\n" msgstr "" #: src/stored/authenticate.c:355 src/stored/authenticate.c:374 #, c-format msgid "" "Authorization problem: Two way security handshake failed with Storage daemon " "at %s\n" msgstr "" #: src/stored/authenticate.c:393 src/stored/authenticate.c:412 #, c-format msgid "" "Authorization problem: Two way security handshake failed with File daemon at " "%s\n" msgstr "" #: src/stored/mount.c:95 #, c-format msgid "Too many errors trying to mount device %s.\n" msgstr "" #: src/stored/mount.c:103 #, c-format msgid "Job %d canceled.\n" msgstr "" #: src/stored/mount.c:206 src/stored/label.c:373 src/stored/label.c:489 #, c-format msgid "Open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/mount.c:284 #, c-format msgid "Volume \"%s\" previously written, moving to end of data.\n" msgstr "" #: src/stored/mount.c:290 #, c-format msgid "Unable to position to end of data on device %s: ERR=%s\n" msgstr "" #: src/stored/mount.c:415 src/stored/mount.c:746 #, c-format msgid "Volume \"%s\" not on device %s.\n" msgstr "" #: src/stored/mount.c:448 #, c-format msgid "" "Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s" msgstr "" #: src/stored/mount.c:467 src/stored/label.c:253 src/stored/label.c:449 #, c-format msgid "Could not reserve volume %s on %s\n" msgstr "" #: src/stored/mount.c:621 #, c-format msgid "Ready to append to end of Volume \"%s\" at file=%d.\n" msgstr "" #: src/stored/mount.c:624 #, c-format msgid "" "For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:631 src/stored/mount.c:660 msgid "Error updating Catalog\n" msgstr "" #: src/stored/mount.c:636 #, c-format msgid "" "Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n" msgstr "" #: src/stored/mount.c:648 #, c-format msgid "Ready to append to end of Volume \"%s\" size=%s\n" msgstr "" #: src/stored/mount.c:652 #, c-format msgid "" "For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n" msgstr "" #: src/stored/mount.c:665 #, c-format msgid "" "Bareos cannot write on disk Volume \"%s\" because: The sizes do not match! " "Volume=%s Catalog=%s\n" msgstr "" #: src/stored/mount.c:678 #, c-format msgid "Don't know how to check if EOD is valid for a device of type %d\n" msgstr "" #: src/stored/mount.c:736 #, c-format msgid "Labeled new Volume \"%s\" on device %s.\n" msgstr "" #: src/stored/mount.c:741 #, c-format msgid "Device %s not configured to autolabel Volumes.\n" msgstr "" #: src/stored/mount.c:761 #, c-format msgid "Marking Volume \"%s\" in Error in Catalog.\n" msgstr "" #: src/stored/mount.c:780 #, c-format msgid "" "Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n" msgstr "" #: src/stored/mount.c:803 msgid "Hey!!!!! WroteVol non-zero !!!!!\n" msgstr "" #: src/stored/mount.c:855 #, c-format msgid "" "Invalid tape position on volume \"%s\" on device %s. Expected %d, got %d\n" msgstr "" #: src/stored/label.c:90 #, c-format msgid "Couldn't rewind device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:120 src/stored/label.c:215 #, c-format msgid "Wrong Volume mounted on device %s: Wanted %s have %s\n" msgstr "" #: src/stored/label.c:123 src/stored/label.c:203 #, c-format msgid "Too many tries: %s" msgstr "" #: src/stored/label.c:142 #, c-format msgid "" "Requested Volume \"%s\" on %s is not a Bareos labeled Volume, because: ERR=%s" msgstr "" #: src/stored/label.c:147 msgid "Could not read Volume label from block.\n" msgstr "" #: src/stored/label.c:150 #, c-format msgid "Could not unserialize Volume label: ERR=%s\n" msgstr "" #: src/stored/label.c:156 #, c-format msgid "Volume Header Id bad: %s\n" msgstr "" #: src/stored/label.c:187 #, c-format msgid "Volume on %s has wrong Bareos version. Wanted %d got %d\n" msgstr "" #: src/stored/label.c:199 #, c-format msgid "Volume on %s has bad Bareos label type: %x\n" msgstr "" #: src/stored/label.c:315 #, c-format msgid "Cannot write Volume label to block for device %s\n" msgstr "" #: src/stored/label.c:525 #, c-format msgid "Rewind error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:532 #, c-format msgid "Truncate error on device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:538 #, fuzzy, c-format msgid "Failed to re-open after truncate on device %s: ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/stored/label.c:561 #, c-format msgid "Unable to write device %s: ERR=%s\n" msgstr "" #: src/stored/label.c:592 #, c-format msgid "Recycled volume \"%s\" on device %s, all previous data lost.\n" msgstr "" #: src/stored/label.c:595 #, c-format msgid "Wrote label to prelabeled Volume \"%s\" on device %s\n" msgstr "" #: src/stored/label.c:812 #, c-format msgid "Bad Volume session label = %d\n" msgstr "" #: src/stored/label.c:866 #, c-format msgid "Expecting Volume Label, got FI=%s Stream=%s len=%d\n" msgstr "" #: src/stored/label.c:992 #, c-format msgid "Unknown %d" msgstr "" #: src/stored/label.c:996 #, c-format msgid "" "\n" "Volume Label:\n" "Id : %sVerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" msgstr "" #: src/stored/label.c:1018 #, c-format msgid "Date label written: %s\n" msgstr "" #: src/stored/label.c:1024 #, c-format msgid "Date label written: %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1043 #, c-format msgid "" "\n" "%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" msgstr "" #: src/stored/label.c:1056 #, c-format msgid "" "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" msgstr "" #: src/stored/label.c:1065 #, c-format msgid "" "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" msgstr "" #: src/stored/label.c:1086 #, c-format msgid "Date written : %s\n" msgstr "" #: src/stored/label.c:1091 #, c-format msgid "Date written : %04d-%02d-%02d at %02d:%02d\n" msgstr "" #: src/stored/label.c:1110 msgid "Fresh Volume" msgstr "" #: src/stored/label.c:1113 msgid "Volume" msgstr "" #: src/stored/label.c:1122 src/stored/read_record.c:66 msgid "End of Media" msgstr "" #: src/stored/label.c:1125 msgid "End of Tape" msgstr "" #: src/stored/label.c:1145 src/stored/label.c:1153 src/stored/label.c:1186 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n" msgstr "" #: src/stored/label.c:1150 msgid "End of physical tape.\n" msgstr "" #: src/stored/label.c:1165 src/stored/label.c:1174 #, c-format msgid "%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n" msgstr "" #: src/stored/label.c:1167 #, c-format msgid " Job=%s Date=%s Level=%c Type=%c\n" msgstr "" #: src/stored/label.c:1176 #, c-format msgid " Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n" msgstr "" #: src/stored/block.c:94 #, c-format msgid "" "Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n" msgstr "" #: src/stored/block.c:107 #, c-format msgid " Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n" msgstr "" #: src/stored/block.c:162 #, c-format msgid "%d block read errors not printed.\n" msgstr "" #: src/stored/block.c:259 src/stored/block.c:275 src/stored/block.c:285 #, c-format msgid "" "Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer " "discarded.\n" msgstr "" #: src/stored/block.c:302 #, c-format msgid "" "Volume data error at %u:%u! Block length %u is insane (too large), probably " "due to a bad archive.\n" msgstr "" #: src/stored/block.c:330 #, c-format msgid "" "Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n" msgstr "" #: src/stored/block.c:457 #, c-format msgid "Cannot write block. Device at EOM. dev=%s\n" msgstr "" #: src/stored/block.c:463 #, c-format msgid "Attempt to write on read-only Volume. dev=%s\n" msgstr "" #: src/stored/block.c:469 #, c-format msgid "Attempt to write on closed device=%s\n" msgstr "" #: src/stored/block.c:536 #, c-format msgid "User defined maximum volume capacity %s exceeded on device %s.\n" msgstr "" #: src/stored/block.c:553 #, c-format msgid "Unable to write EOF. ERR=%s\n" msgstr "" #: src/stored/block.c:576 src/stored/block.c:610 msgid "Write block header zeroed.\n" msgstr "" #: src/stored/block.c:602 #, c-format msgid "Block checksum changed during write: before=%ud after=%ud\n" msgstr "" #: src/stored/block.c:630 #, c-format msgid "Write error at %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:638 #, c-format msgid "End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n" msgstr "" #: src/stored/block.c:644 #, c-format msgid "Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:740 src/stored/block.c:746 #, c-format msgid "Backspace file at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:755 #, c-format msgid "Backspace record at EOT failed. ERR=%s\n" msgstr "" #: src/stored/block.c:774 #, c-format msgid "Re-read last block at EOT failed. ERR=%s" msgstr "" #: src/stored/block.c:783 #, c-format msgid "" "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n" msgstr "" #: src/stored/block.c:788 #, c-format msgid "" "Re-read of last block OK, but block numbers differ. Read block=%u Want block=" "%u.\n" msgstr "" #: src/stored/block.c:792 msgid "Re-read of last block succeeded.\n" msgstr "" #: src/stored/block.c:824 #, c-format msgid "" "Error writing final EOF to tape. This Volume may not be readable.\n" "%s" msgstr "" #: src/stored/block.c:836 #, fuzzy msgid "Error sending Volume info to Director.\n" msgstr "Помилка надсилання Hello до Збирача. ERR=%s\n" #: src/stored/block.c:949 #, fuzzy msgid "Job failed or canceled.\n" msgstr "Статус задачі: Відмінена" #: src/stored/block.c:955 msgid "Attempt to read past end of tape or file.\n" msgstr "" #: src/stored/block.c:964 #, c-format msgid "Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n" msgstr "" #: src/stored/block.c:974 #, c-format msgid "Block buffer size looping problem on device %s\n" msgstr "" #: src/stored/block.c:1003 #, c-format msgid "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" msgstr "" #: src/stored/block.c:1021 #, c-format msgid "Read zero bytes at %u:%u on device %s.\n" msgstr "" #: src/stored/block.c:1046 #, c-format msgid "" "Volume data error at %u:%u! Very short block of %d bytes on device %s " "discarded.\n" msgstr "" #: src/stored/block.c:1072 #, c-format msgid "Block length %u is greater than buffer %u. Attempting recovery.\n" msgstr "" #: src/stored/block.c:1094 #, c-format msgid "Setting block buffer size to %u bytes.\n" msgstr "" #: src/stored/block.c:1111 #, c-format msgid "" "Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n" msgstr "" #: src/stored/askdir.c:171 msgid "Network error on bnet_recv in req_vol_info.\n" msgstr "" #: src/stored/askdir.c:190 #, c-format msgid "Error getting Volume info: %s" msgstr "" #: src/stored/askdir.c:381 #, c-format msgid "Didn't get vol info vol=%s: ERR=%s" msgstr "" #: src/stored/askdir.c:436 #, c-format msgid "Error creating JobMedia record: ERR=%s\n" msgstr "" #: src/stored/askdir.c:443 #, c-format msgid "Error creating JobMedia record: %s\n" msgstr "" #: src/stored/askdir.c:521 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device \"%s\".\n" msgstr "" #: src/stored/askdir.c:532 #, c-format msgid "" "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:557 src/stored/askdir.c:647 #, c-format msgid "Max time exceeded waiting to mount Storage Device %s for Job %s\n" msgstr "" #: src/stored/askdir.c:567 msgid "pthread error in mount_next_volume.\n" msgstr "" #: src/stored/askdir.c:597 msgid "Cannot request another volume: no volume name given.\n" msgstr "" #: src/stored/askdir.c:603 #, c-format msgid "Job %s canceled while waiting for mount on Storage Device %s.\n" msgstr "" #: src/stored/askdir.c:617 #, c-format msgid "" "Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:623 #, c-format msgid "" "Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n" msgstr "" #: src/stored/askdir.c:657 msgid "pthread error in mount_volume\n" msgstr "" #: src/stored/bextract.c:71 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bextract.c:195 msgid "" "Wrong number of arguments. Make sure the last two parameters are \n" msgstr "" #: src/stored/bextract.c:234 #, c-format msgid "%d Program Name and/or Program Data Stream records ignored.\n" msgstr "" #: src/stored/bextract.c:238 #, c-format msgid "%d Win32 data or Win32 gzip data stream records. Ignored.\n" msgstr "" #: src/stored/bextract.c:356 src/stored/bextract.c:713 src/filed/restore.c:343 #: src/filed/restore.c:1048 #, c-format msgid "Unknown stream=%d ignored. This shouldn't happen!\n" msgstr "" #: src/stored/bextract.c:403 #, c-format msgid "Cannot stat %s. It must exist. ERR=%s\n" msgstr "" #: src/stored/bextract.c:407 #, c-format msgid "%s must be a directory.\n" msgstr "" #: src/stored/bextract.c:451 #, c-format msgid "%u files restored.\n" msgstr "" #: src/stored/bextract.c:462 src/stored/bextract.c:468 #: src/filed/restore.c:1223 src/filed/restore.c:1230 src/filed/restore.c:1238 #, c-format msgid "Write error on %s: %s\n" msgstr "" #: src/stored/bextract.c:499 src/stored/bextract.c:708 msgid "Logic error output file should be open but is not.\n" msgstr "" #: src/stored/bextract.c:513 src/filed/restore.c:572 #, c-format msgid "%s stream not supported on this Client.\n" msgstr "" #: src/stored/bextract.c:523 #, c-format msgid "%s was deleted.\n" msgstr "" #: src/stored/bextract.c:571 #, c-format msgid "Seek error on %s: %s\n" msgstr "" #: src/stored/bextract.c:611 src/filed/restore.c:1195 #, c-format msgid "Seek to %s error on %s: ERR=%s\n" msgstr "" #: src/stored/bextract.c:649 msgid "Got Program Name or Data Stream. Ignored.\n" msgstr "" #: src/stored/lock.c:390 #, c-format msgid "pthread_cond_wait failure. ERR=%s\n" msgstr "" #: src/stored/lock.c:489 msgid "unknown blocked code" msgstr "" #: src/stored/autochanger.c:60 #, c-format msgid "No Changer Name given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:66 #, c-format msgid "No Changer Command given for device %s. Cannot continue.\n" msgstr "" #: src/stored/autochanger.c:133 #, c-format msgid "No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n" msgstr "" #: src/stored/autochanger.c:135 msgid "Cartridge change or \"update slots\" may be required.\n" msgstr "" #: src/stored/autochanger.c:141 #, c-format msgid "No \"Changer Device\" for %s. Manual load of Volume may be required.\n" msgstr "" #: src/stored/autochanger.c:148 #, c-format msgid "No \"Changer Command\" for %s. Manual load of Volume may be requird.\n" msgstr "" #: src/stored/autochanger.c:179 #, c-format msgid "3304 Issuing autochanger \"load slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:187 #, c-format msgid "3305 Autochanger \"load slot %d, drive %d\", status is OK.\n" msgstr "" #: src/stored/autochanger.c:200 #, c-format msgid "" "3992 Bad autochanger \"load slot %d, drive %d\": ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:262 #, c-format msgid "3301 Issuing autochanger \"loaded? drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:274 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n" msgstr "" #: src/stored/autochanger.c:281 #, c-format msgid "3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n" msgstr "" #: src/stored/autochanger.c:293 #, c-format msgid "" "3991 Bad autochanger \"loaded? drive %d\" command: ERR=%s.\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:310 #, fuzzy, c-format msgid "Lock failure on autochanger. ERR=%s\n" msgstr "Проігноровано помилку SQL. ERR=%s\n" #: src/stored/autochanger.c:324 #, c-format msgid "Unlock failure on autochanger. ERR=%s\n" msgstr "" #: src/stored/autochanger.c:368 src/stored/autochanger.c:517 #, c-format msgid "3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n" msgstr "" #: src/stored/autochanger.c:381 #, c-format msgid "" "3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s\n" "Results=%s\n" msgstr "" #: src/stored/autochanger.c:467 #, c-format msgid "Volume \"%s\" wanted on %s is in use by device %s\n" msgstr "" #: src/stored/autochanger.c:535 #, c-format msgid "3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n" msgstr "" #: src/stored/autochanger.c:578 src/stored/autochanger.c:686 #, c-format msgid "3993 Device %s not an autochanger device.\n" msgstr "" #: src/stored/autochanger.c:607 #, c-format msgid "3306 Issuing autochanger \"%s\" command.\n" msgstr "" #: src/stored/autochanger.c:615 src/stored/autochanger.c:703 msgid "3996 Open bpipe failed.\n" msgstr "" #: src/stored/autochanger.c:661 src/stored/autochanger.c:718 #, fuzzy, c-format msgid "3998 Autochanger error: ERR=%s\n" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/stored/autochanger.c:699 msgid "3306 Issuing autochanger transfer command.\n" msgstr "" #: src/stored/autochanger.c:720 #, c-format msgid "3308 Successfully transfered volume from slot %d to %d.\n" msgstr "" #: src/stored/wait.c:127 #, c-format msgid "pthread timedwait error. ERR=%s\n" msgstr "" #: src/stored/wait.c:233 #, c-format msgid "JobId=%s, Job %s waiting to reserve a device.\n" msgstr "" #: src/stored/butil.c:54 msgid "Nohdr," msgstr "" #: src/stored/butil.c:57 msgid "partial," msgstr "" #: src/stored/butil.c:60 msgid "empty," msgstr "" #: src/stored/butil.c:63 msgid "Nomatch," msgstr "" #: src/stored/butil.c:66 msgid "cont," msgstr "" #: src/stored/butil.c:147 msgid "Volume name or names is too long. Please use a .bsr file.\n" msgstr "" #: src/stored/butil.c:167 #, c-format msgid "Cannot find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:174 #, c-format msgid "Cannot init device %s\n" msgstr "" #: src/stored/butil.c:199 #, c-format msgid "Cannot open %s\n" msgstr "" #: src/stored/butil.c:293 #, c-format msgid "Could not find device \"%s\" in config file %s.\n" msgstr "" #: src/stored/butil.c:299 #, c-format msgid "Using device: \"%s\" for reading.\n" msgstr "" #: src/stored/butil.c:302 #, c-format msgid "Using device: \"%s\" for writing.\n" msgstr "" #: src/stored/butil.c:318 msgid "Unexpected End of Data\n" msgstr "" #: src/stored/butil.c:320 msgid "Unexpected End of Tape\n" msgstr "" #: src/stored/butil.c:322 msgid "Unexpected End of File\n" msgstr "" #: src/stored/butil.c:324 msgid "Tape Door is Open\n" msgstr "" #: src/stored/butil.c:326 msgid "Unexpected Tape is Off-line\n" msgstr "" #: src/stored/read_record.c:59 msgid "Begin Session" msgstr "" #: src/stored/read_record.c:63 msgid "End Session" msgstr "" #: src/stored/read_record.c:69 #, c-format msgid "Unknown code %d\n" msgstr "" #: src/stored/read_record.c:188 #, c-format msgid "End of Volume at file %u on device %s, Volume \"%s\"\n" msgstr "" #: src/stored/read_record.c:193 msgid "End of all volumes.\n" msgstr "" #: src/stored/read_record.c:248 msgid "Did fsr in attemp to skip bad record.\n" msgstr "" #: src/stored/acquire.c:68 #, c-format msgid "Acquire read: num_writers=%d not zero. Job %d canceled.\n" msgstr "" #: src/stored/acquire.c:77 #, c-format msgid "No volumes specified for reading. Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:86 #, c-format msgid "Logic error: no next volume to read. Numvol=%d Curvol=%d\n" msgstr "" #: src/stored/acquire.c:112 #, c-format msgid "" "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n" msgstr "" #: src/stored/acquire.c:156 #, c-format msgid "Media Type change. New read device %s chosen.\n" msgstr "" #: src/stored/acquire.c:168 #, c-format msgid "No suitable device found to read Volume \"%s\"\n" msgstr "" #: src/stored/acquire.c:207 #, c-format msgid "Job %s canceled.\n" msgstr "" #: src/stored/acquire.c:225 #, c-format msgid "Read open device %s Volume \"%s\" failed: ERR=%s\n" msgstr "" #: src/stored/acquire.c:315 #, c-format msgid "Too many errors trying to mount device %s for reading.\n" msgstr "" #: src/stored/acquire.c:323 #, c-format msgid "Ready to read from volume \"%s\" on device %s.\n" msgstr "" #: src/stored/acquire.c:375 #, c-format msgid "Want to append, but device %s is busy reading.\n" msgstr "" #: src/stored/acquire.c:408 #, c-format msgid "Could not ready device %s for append.\n" msgstr "" #: src/stored/acquire.c:569 #, c-format msgid "Alert: %s" msgstr "" #: src/stored/acquire.c:577 #, c-format msgid "3997 Bad alert command: %s: ERR=%s.\n" msgstr "" #: src/stored/acquire.c:654 #, fuzzy, c-format msgid "Unable to init r_mutex: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/ansi_label.c:86 #, c-format msgid "Read error on device %s in ANSI label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:97 msgid "Insane! End of tape while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:127 msgid "No VOL1 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:156 #, c-format msgid "Wanted ANSI Volume \"%s\" got \"%s\"\n" msgstr "" #: src/stored/ansi_label.c:168 msgid "No HDR1 label while reading ANSI label.\n" msgstr "" #: src/stored/ansi_label.c:176 src/stored/ansi_label.c:182 #, c-format msgid "ANSI/IBM Volume \"%s\" does not belong to Bareos.\n" msgstr "" #: src/stored/ansi_label.c:195 msgid "No HDR2 label while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:212 msgid "Unknown or bad ANSI/IBM label record.\n" msgstr "" #: src/stored/ansi_label.c:221 msgid "Too many records in while reading ANSI/IBM label.\n" msgstr "" #: src/stored/ansi_label.c:318 #, c-format msgid "ANSI Volume label name \"%s\" longer than 6 chars.\n" msgstr "" #: src/stored/ansi_label.c:349 #, c-format msgid "Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:395 src/stored/ansi_label.c:429 #, c-format msgid "Could not write ANSI HDR1 label. ERR=%s\n" msgstr "" #: src/stored/ansi_label.c:400 src/stored/ansi_label.c:436 msgid "Could not write ANSI HDR1 label.\n" msgstr "" #: src/stored/ansi_label.c:441 #, c-format msgid "Error writing EOF to tape. ERR=%s" msgstr "" #: src/stored/ansi_label.c:446 msgid "write_ansi_ibm_label called for non-ANSI/IBM type\n" msgstr "" #: src/stored/sd_backends.c:172 #, fuzzy, c-format msgid "Unable to load any shared library for libbareossd-%s%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/job.c:327 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of " "protocol.\n" msgstr "" #: src/stored/job.c:374 #, c-format msgid "" "Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n" msgstr "" #: src/stored/job.c:524 msgid "In free_jcr(), but still attached to device!!!!\n" msgstr "" #: src/stored/vol_mgr.c:98 #, c-format msgid "Unable to initialize volume list lock. ERR=%s\n" msgstr "" #: src/stored/bcopy.c:60 #, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key " "selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w specify working directory (default /tmp)\n" " -? print this message\n" "\n" msgstr "" #: src/stored/bcopy.c:247 msgid "Write of last block failed.\n" msgstr "" #: src/stored/bcopy.c:251 #, c-format msgid "%u Jobs copied. %u records copied.\n" msgstr "" #: src/stored/bcopy.c:285 msgid "Volume is prelabeled. This volume cannot be copied.\n" msgstr "" #: src/stored/bcopy.c:288 msgid "Volume label not copied.\n" msgstr "" #: src/stored/bcopy.c:294 msgid "Copy skipped. Record does not match BSR filter.\n" msgstr "" #: src/stored/bcopy.c:325 msgid "EOM label not copied.\n" msgstr "" #: src/stored/bcopy.c:328 msgid "EOT label not copied.\n" msgstr "" #: src/stored/stored.c:76 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s без сигналів\n" " -t перевірка - прочитати конфігурацію і вийти\n" " -? print this message.\n" "\n" #: src/stored/stored.c:267 msgid "Volume Session Time is ZERO!\n" msgstr "" #: src/stored/stored.c:276 #, c-format msgid "Unable to create thread. ERR=%s\n" msgstr "" #: src/stored/stored.c:325 #, c-format msgid "Only one Storage resource permitted in %s\n" msgstr "" #: src/stored/stored.c:330 #, c-format msgid "No Director resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:335 #, c-format msgid "No Device resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:343 #, c-format msgid "No Messages resource defined in %s. Cannot continue.\n" msgstr "" #: src/stored/stored.c:371 #, c-format msgid "\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:377 #, c-format msgid "\"TLS Key\" file not defined for Storage \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:383 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "Storage \"%s\" in %s. At least one CA certificate store is required when " "using \"TLS Verify Peer\".\n" msgstr "" #: src/stored/stored.c:476 #, c-format msgid "" "LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n" msgstr "" #: src/stored/stored.c:606 #, fuzzy, c-format msgid "Unable to init job endstart cond variable: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/stored/stored.c:614 #, c-format msgid "Could not initialize %s\n" msgstr "" #: src/stored/stored.c:633 #, c-format msgid "Could not open device %s\n" msgstr "" #: src/stored/stored.c:648 #, c-format msgid "Could not mount device %s\n" msgstr "" #: src/stored/record.c:65 #, c-format msgid "unknown: %d" msgstr "" #: src/stored/record.c:421 msgid "Damaged buffer\n" msgstr "" #: src/stored/record.c:479 msgid "Quota Exceeded. Job Terminated.\n" msgstr "" #: src/stored/record.c:765 #, c-format msgid "Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n" msgstr "" #: src/findlib/xattr.c:247 #, c-format msgid "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:261 #, c-format msgid "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:384 src/findlib/xattr.c:420 #, fuzzy, c-format msgid "llistea error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:470 src/findlib/xattr.c:523 #, fuzzy, c-format msgid "lgetea error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:560 src/findlib/xattr.c:887 src/findlib/xattr.c:1367 #: src/findlib/xattr.c:1841 src/findlib/xattr.c:2203 src/findlib/xattr.c:3014 #: src/filed/fd_plugins.c:1405 #, c-format msgid "Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n" msgstr "" #: src/findlib/xattr.c:581 src/findlib/xattr.c:914 src/findlib/xattr.c:1388 #: src/findlib/xattr.c:1872 src/findlib/xattr.c:2221 #: src/filed/fd_plugins.c:1431 #, c-format msgid "Failed to serialize extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:650 #, fuzzy, c-format msgid "lsetea error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:741 src/findlib/xattr.c:779 src/findlib/xattr.c:842 #: src/findlib/xattr.c:854 #, fuzzy, c-format msgid "attr_list error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:981 #, c-format msgid "Received illegal xattr named %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1014 src/findlib/xattr.c:1024 #, fuzzy, c-format msgid "attr_set error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:1177 src/findlib/xattr.c:1212 #, c-format msgid "llistxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1280 src/findlib/xattr.c:1332 #, c-format msgid "lgetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1453 #, c-format msgid "lsetxattr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:1614 src/findlib/xattr.c:1649 #, fuzzy, c-format msgid "extattr_list_link error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:1669 #, c-format msgid "Failed to convert %d into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1749 src/findlib/xattr.c:1804 #, fuzzy, c-format msgid "extattr_get_link error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:1931 #, c-format msgid "Failed to split %s into namespace and name part on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1944 #, c-format msgid "Failed to convert %s into namespace on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:1965 #, fuzzy, c-format msgid "extattr_set_link error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:2071 src/findlib/xattr.c:2096 #, fuzzy, c-format msgid "getproplist error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:2292 #, c-format msgid "Unable create proper proplist to restore xattrs on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:2321 #, fuzzy, c-format msgid "setproplist error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/xattr.c:2647 src/findlib/xattr.c:2700 #, c-format msgid "Unable to get acl on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2717 #, c-format msgid "Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2799 #, c-format msgid "Unable to get status on xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2932 #, c-format msgid "Unable to open xattr %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:2955 #, c-format msgid "Unable to read symlin %s on \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3030 #, c-format msgid "Unable to read content of xattr %s on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3070 #, c-format msgid "Unable to chdir to xattr space of file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3130 src/findlib/xattr.c:3381 #, c-format msgid "Unable to open file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3158 src/findlib/xattr.c:3442 #, c-format msgid "Unable to open xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3174 src/findlib/xattr.c:3406 #, c-format msgid "Unable to chdir to xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3195 #, c-format msgid "Unable to list the xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3288 #, c-format msgid "Unable to convert acl from text on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3298 src/findlib/xattr.c:3321 #, c-format msgid "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3395 #, c-format msgid "Unable to open xattr space on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3425 src/findlib/xattr.c:3587 #, c-format msgid "Unable to open xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3459 #, c-format msgid "Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3499 #, c-format msgid "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3517 #, c-format msgid "Unable to mknod xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3535 #, c-format msgid "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3555 #, c-format msgid "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3608 #, c-format msgid "" "Unable to restore data of xattr %s on file \"%s\": Not all data available in " "xattr stream\n" msgstr "" #: src/findlib/xattr.c:3621 #, c-format msgid "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3644 #, c-format msgid "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3680 #, c-format msgid "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3708 #, c-format msgid "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/xattr.c:3724 #, c-format msgid "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3788 #, c-format msgid "Failed to restore extensible attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3801 #, c-format msgid "Failed to restore extended attributes on file \"%s\"\n" msgstr "" #: src/findlib/xattr.c:3899 src/findlib/acl.c:2333 #, fuzzy, c-format msgid "Unable to stat file \"%s\": ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/findlib/xattr.c:3949 #, c-format msgid "" "Can't restore Extended Attributes of %s - incompatible xattr stream " "encountered - %d\n" msgstr "" #: src/findlib/find.c:180 #, c-format msgid "Plugin: \"%s\" not found.\n" msgstr "" #: src/findlib/bfile.c:90 msgid "Unix attributes" msgstr "Атрибули Unix" #: src/findlib/bfile.c:92 msgid "File data" msgstr "Дата файлу" #: src/findlib/bfile.c:94 msgid "MD5 digest" msgstr "Відбиток MD5" #: src/findlib/bfile.c:96 msgid "GZIP data" msgstr "Дані, запаковані GZIP" #: src/findlib/bfile.c:98 #, fuzzy msgid "Compressed data" msgstr "Замало даних" #: src/findlib/bfile.c:100 msgid "Extended attributes" msgstr "Додаткові атрибути" #: src/findlib/bfile.c:102 msgid "Sparse data" msgstr "Замало даних" #: src/findlib/bfile.c:104 msgid "GZIP sparse data" msgstr "Замало даних GZIP " #: src/findlib/bfile.c:106 #, fuzzy msgid "Compressed sparse data" msgstr "Замало даних GZIP " #: src/findlib/bfile.c:108 msgid "Program names" msgstr "Назви програми" #: src/findlib/bfile.c:110 msgid "Program data" msgstr "Програмні дані" #: src/findlib/bfile.c:112 msgid "SHA1 digest" msgstr "Відбиток HA1" #: src/findlib/bfile.c:114 msgid "Win32 data" msgstr "Дані Win32" #: src/findlib/bfile.c:116 msgid "Win32 GZIP data" msgstr "Дані Win32 GZIP" #: src/findlib/bfile.c:118 #, fuzzy msgid "Win32 compressed data" msgstr "Дані Win32" #: src/findlib/bfile.c:120 msgid "MacOS Fork data" msgstr "Дані MacOS Fork" #: src/findlib/bfile.c:122 msgid "HFS+ attribs" msgstr "Атрибути HFS+" #: src/findlib/bfile.c:124 msgid "Standard Unix ACL attribs" msgstr "Стандартні атрибути Unix ACL" #: src/findlib/bfile.c:126 msgid "Default Unix ACL attribs" msgstr "Звичійні атрибути Unix ACL" #: src/findlib/bfile.c:128 msgid "SHA256 digest" msgstr "Відбиток SHA256" #: src/findlib/bfile.c:130 msgid "SHA512 digest" msgstr "Відбиток SHA512" #: src/findlib/bfile.c:132 msgid "Signed digest" msgstr "Підписаний відбиток" #: src/findlib/bfile.c:134 msgid "Encrypted File data" msgstr "Зашифровані файли" #: src/findlib/bfile.c:136 msgid "Encrypted Win32 data" msgstr "Зашифровані дані Win32" #: src/findlib/bfile.c:138 msgid "Encrypted session data" msgstr "Зашифровані дані сесій" #: src/findlib/bfile.c:140 msgid "Encrypted GZIP data" msgstr "Зашифровані дані GZIP" #: src/findlib/bfile.c:142 #, fuzzy msgid "Encrypted compressed data" msgstr "Зашифровані дані сесій" #: src/findlib/bfile.c:144 msgid "Encrypted Win32 GZIP data" msgstr "Зашифровані дані Win32 GZIP" #: src/findlib/bfile.c:146 #, fuzzy msgid "Encrypted Win32 Compressed data" msgstr "Зашифровані дані Win32" #: src/findlib/bfile.c:148 msgid "Encrypted MacOS fork data" msgstr "Зашифровані дані MacOS Fork " #: src/findlib/bfile.c:150 msgid "AIX Specific ACL attribs" msgstr "Специфічні атрибути AIX ACL" #: src/findlib/bfile.c:152 msgid "Darwin Specific ACL attribs" msgstr "Специфічні атрибути Darwin ACL" #: src/findlib/bfile.c:154 msgid "FreeBSD Specific Default ACL attribs" msgstr "Специфічні атрибути FreeBSD Default ACL" #: src/findlib/bfile.c:156 msgid "FreeBSD Specific Access ACL attribs" msgstr "Специфічні атрибути FreeBSD Access ACL" #: src/findlib/bfile.c:158 msgid "HPUX Specific ACL attribs" msgstr "Специфічні атрибути HPUX ACL" #: src/findlib/bfile.c:160 msgid "Irix Specific Default ACL attribs" msgstr "Специфічні атрибути Irix Default ACL" #: src/findlib/bfile.c:162 msgid "Irix Specific Access ACL attribs" msgstr "Специфічні атрибути Irix Access ACL" #: src/findlib/bfile.c:164 msgid "Linux Specific Default ACL attribs" msgstr "Специфічні атрибути Linux Default ACL" #: src/findlib/bfile.c:166 msgid "Linux Specific Access ACL attribs" msgstr "Специфічні атрибути Linux Access ACL" #: src/findlib/bfile.c:168 #, fuzzy msgid "TRU64 Specific Default ACL attribs" msgstr "Специфічні атрибути Irix Default ACL" #: src/findlib/bfile.c:170 #, fuzzy msgid "TRU64 Specific Access ACL attribs" msgstr "Специфічні атрибути Irix Access ACL" #: src/findlib/bfile.c:172 #, fuzzy msgid "Solaris Specific POSIX ACL attribs" msgstr "Специфічні атрибути Solaris ACL" #: src/findlib/bfile.c:174 #, fuzzy msgid "Solaris Specific NFSv4/ZFS ACL attribs" msgstr "Специфічні атрибути Solaris ACL" #: src/findlib/bfile.c:176 #, fuzzy msgid "AFS Specific ACL attribs" msgstr "Специфічні атрибути AIX ACL" #: src/findlib/bfile.c:178 #, fuzzy msgid "AIX Specific POSIX ACL attribs" msgstr "Специфічні атрибути AIX ACL" #: src/findlib/bfile.c:180 #, fuzzy msgid "AIX Specific NFSv4 ACL attribs" msgstr "Специфічні атрибути AIX ACL" #: src/findlib/bfile.c:182 #, fuzzy msgid "FreeBSD Specific NFSv4/ZFS ACL attribs" msgstr "Специфічні атрибути FreeBSD Access ACL" #: src/findlib/bfile.c:184 #, fuzzy msgid "GNU Hurd Specific Default ACL attribs" msgstr "Специфічні атрибути Irix Default ACL" #: src/findlib/bfile.c:186 #, fuzzy msgid "GNU Hurd Specific Access ACL attribs" msgstr "Специфічні атрибути Irix Access ACL" #: src/findlib/bfile.c:188 #, fuzzy msgid "GNU Hurd Specific Extended attribs" msgstr "Специфічні додаткові атрибути Linux" #: src/findlib/bfile.c:190 #, fuzzy msgid "IRIX Specific Extended attribs" msgstr "Специфічні додаткові атрибути Linux" #: src/findlib/bfile.c:192 #, fuzzy msgid "TRU64 Specific Extended attribs" msgstr "Специфічні додаткові атрибути Linux" #: src/findlib/bfile.c:194 #, fuzzy msgid "AIX Specific Extended attribs" msgstr "Специфічні додаткові атрибути Linux" #: src/findlib/bfile.c:196 #, fuzzy msgid "OpenBSD Specific Extended attribs" msgstr "Специфічні додаткові атрибути NetBSD" #: src/findlib/bfile.c:198 msgid "Solaris Specific Extensible attribs or System Extended attribs" msgstr "" #: src/findlib/bfile.c:200 msgid "Solaris Specific Extended attribs" msgstr "Специфічні додаткові атрибути Solaris" #: src/findlib/bfile.c:202 msgid "Darwin Specific Extended attribs" msgstr "Специфічні додаткові атрибути Darwin" #: src/findlib/bfile.c:204 msgid "FreeBSD Specific Extended attribs" msgstr "Специфічні додаткові атрибути FreeBS" #: src/findlib/bfile.c:206 msgid "Linux Specific Extended attribs" msgstr "Специфічні додаткові атрибути Linux" #: src/findlib/bfile.c:208 msgid "NetBSD Specific Extended attribs" msgstr "Специфічні додаткові атрибути NetBSD" #: src/findlib/attribs.c:230 src/findlib/attribs.c:240 #: src/findlib/attribs.c:454 #, c-format msgid "Unable to set file owner %s: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/findlib/attribs.c:253 src/findlib/attribs.c:267 #: src/findlib/attribs.c:462 #, c-format msgid "Unable to set file modes %s: ERR=%s\n" msgstr "Не можливо встановити параметри файлу %s: ERR=%s\n" #: src/findlib/attribs.c:287 src/findlib/attribs.c:303 #: src/findlib/attribs.c:321 src/findlib/attribs.c:335 #: src/findlib/attribs.c:347 #, c-format msgid "Unable to set file times %s: ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/findlib/attribs.c:418 src/findlib/attribs.c:430 #, c-format msgid "File size of restored file %s not correct. Original %s, restored %s.\n" msgstr "" "Не правильний розмір відновленого файлу %s. Оригінальний %s, відновлений %" "s.\n" #: src/findlib/attribs.c:480 #, c-format msgid "Unable to set file flags %s: ERR=%s\n" msgstr "Не можливо встановити прапорці файлу %s: ERR=%s\n" #: src/findlib/attribs.c:714 #, c-format msgid "Error in %s file %s: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/attribs.c:730 #, c-format msgid "Error in %s: ERR=%s\n" msgstr "Помилка у %s: ERR=%s\n" #: src/findlib/savecwd.c:52 #, c-format msgid "Cannot open current directory: ERR=%s\n" msgstr "Не можливо відкрити поточну теку: ERR=%s\n" #: src/findlib/savecwd.c:63 #, c-format msgid "Cannot get current directory: ERR=%s\n" msgstr "Не можливо отримати поточну теку: ERR=%s\n" #: src/findlib/savecwd.c:87 src/findlib/savecwd.c:98 #, c-format msgid "Cannot reset current directory: ERR=%s\n" msgstr "Не можливо перевстановити поточну теку: ERR=%s\n" #: src/findlib/enable_priv.c:75 msgid "AdjustTokenPrivileges set " msgstr "" #: src/findlib/create_file.c:119 #, c-format msgid "File skipped. Not newer: %s\n" msgstr "Файл пропущено. Не новий: %s\n" #: src/findlib/create_file.c:125 #, c-format msgid "File skipped. Not older: %s\n" msgstr "Файл пропущено. Не застарілий: %s\n" #: src/findlib/create_file.c:136 #, c-format msgid "File skipped. Already exists: %s\n" msgstr "Файл пропущено. Вже існує: %s\n" #: src/findlib/create_file.c:162 #, c-format msgid "File %s already exists and could not be replaced. ERR=%s.\n" msgstr "Файл %s існує та його не вдалось замінити. ERR=%s.\n" #: src/findlib/create_file.c:216 src/findlib/create_file.c:296 #: src/findlib/create_file.c:424 #, c-format msgid "bpkt already open fid=%d\n" msgstr "" #: src/findlib/create_file.c:224 src/filed/fd_plugins.c:1172 #, c-format msgid "Could not create %s: ERR=%s\n" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/findlib/create_file.c:243 #, c-format msgid "Cannot make fifo %s: ERR=%s\n" msgstr "Не можливо створити чергу(fifo) %s: ERR=%s\n" #: src/findlib/create_file.c:262 #, c-format msgid "Device restore on root failed, device %s missing.\n" msgstr "" #: src/findlib/create_file.c:271 #, c-format msgid "Cannot make node %s: ERR=%s\n" msgstr "Не вдалось створити ноду(node) %s: ERR=%s\n" #: src/findlib/create_file.c:333 src/findlib/create_file.c:348 #, c-format msgid "Could not restore file flags for file %s: ERR=%s\n" msgstr "Не вдалось відновити прапорці для файлу %s: ERR=%s\n" #: src/findlib/create_file.c:337 src/findlib/create_file.c:356 #, c-format msgid "Could not hard link %s -> %s: ERR=%s\n" msgstr "Не вдалось створити жорстку лінку(hardlink) %s -> %s: ERR=%s\n" #: src/findlib/create_file.c:352 #, c-format msgid "Could not reset file flags for file %s: ERR=%s\n" msgstr "Не вдалось перевстановити прапорці для файлу %s: ERR=%s\n" #: src/findlib/create_file.c:385 src/findlib/create_file.c:398 #, c-format msgid "Could not symlink %s -> %s: ERR=%s\n" msgstr "Не вдалось створити лінку(symlink) %s -> %s: ERR=%s\n" #: src/findlib/create_file.c:449 #, c-format msgid "Original file %s have been deleted: type=%d\n" msgstr "Оригінальний файл %s було видалено: тип=%d\n" #: src/findlib/create_file.c:463 #, c-format msgid "Original file %s not saved: type=%d\n" msgstr "Оригінальний файл %s не збережено: тип=%d\n" #: src/findlib/create_file.c:466 #, c-format msgid "Unknown file type %d; not restored: %s\n" msgstr "Невідомий тип файлу %d: не відновлено: %s\n" #: src/findlib/create_file.c:510 #, c-format msgid "Zero length filename: %s\n" msgstr "Пуста назва файлу: %s\n" #: src/findlib/mkpath.c:151 #, c-format msgid "Cannot create directory %s: ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/findlib/mkpath.c:155 src/findlib/mkpath.c:222 #, c-format msgid "%s exists but is not a directory.\n" msgstr "%s існує, але не є текою.\n" #: src/findlib/mkpath.c:184 #, c-format msgid "Cannot change owner and/or group of %s: ERR=%s\n" msgstr "Не можливо змінити власника та/або групу для %s: ERR=%s\n" #: src/findlib/mkpath.c:193 #, c-format msgid "Cannot change permissions of %s: ERR=%s\n" msgstr "Не можливо змінити дозволи для %s: ERR=%s\n" #: src/findlib/mkpath.c:261 #, c-format msgid "%c: is not a valid drive.\n" msgstr "%c: не вірний пристрій.\n" #: src/findlib/mkpath.c:312 msgid "Too many subdirectories. Some permissions not reset.\n" msgstr "Забагато підтек. Деякі обмеження не перевстановлено.\n" #: src/findlib/find_one.c:188 #, c-format msgid " NODUMP flag set - will not process %s\n" msgstr "" #: src/findlib/find_one.c:263 src/findlib/shadowing.c:55 #: src/findlib/shadowing.c:63 #, c-format msgid "Cannot stat file %s: ERR=%s\n" msgstr "" #: src/findlib/find_one.c:268 #, fuzzy, c-format msgid "%s: mtime changed during backup.\n" msgstr "%s mtime змінився під час резервування.\n" #: src/findlib/find_one.c:275 #, fuzzy, c-format msgid "%s: ctime changed during backup.\n" msgstr "%s ctime змінився під час резервування.\n" #: src/findlib/find_one.c:283 src/findlib/find_one.c:291 #, fuzzy, c-format msgid "%s: size changed during backup.\n" msgstr "%s розмір змінився під час резервування.\n" #: src/findlib/find_one.c:729 #, c-format msgid "%s: File name too long [%d]\n" msgstr "" #: src/findlib/find_one.c:850 #, c-format msgid "Top level directory \"%s\" has unlisted fstype \"%s\"\n" msgstr "Вища тека \"%s\" має незрозумілий тип файлової системи \"%s\"\n" #: src/findlib/find_one.c:866 #, c-format msgid "Top level directory \"%s\" has an unlisted drive type \"%s\"\n" msgstr "Вища тека \"%s\" має незрозумілий тип пристрою \"%s\"\n" #: src/findlib/acl.c:236 src/findlib/acl.c:267 #, fuzzy, c-format msgid "aclx_get error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/acl.c:293 #, fuzzy, c-format msgid "Unknown acl type encountered on file \"%s\": %ld\n" msgstr "Невідомий тип файлу %d: не відновлено: %s\n" #: src/findlib/acl.c:317 src/findlib/acl.c:326 #, fuzzy, c-format msgid "Failed to convert acl into text on file \"%s\"\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/findlib/acl.c:403 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl " "support\n" msgstr "" #: src/findlib/acl.c:411 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl " "support\n" msgstr "" #: src/findlib/acl.c:459 src/findlib/acl.c:469 #, fuzzy, c-format msgid "aclx_scanStr error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/acl.c:495 #, fuzzy, c-format msgid "aclx_put error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/acl.c:845 #, c-format msgid "acl_to_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:875 #, c-format msgid "acl_get_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:929 #, c-format msgid "" "acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:935 #, c-format msgid "acl_delete_def_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:946 #, c-format msgid "acl_from_text error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:967 #, fuzzy, c-format msgid "acl_valid error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/acl.c:1000 #, c-format msgid "acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1009 #, c-format msgid "acl_set_file error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1123 src/findlib/acl.c:1152 src/findlib/acl.c:1267 #: src/findlib/acl.c:1796 src/findlib/acl.c:1904 #, c-format msgid "pathconf error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1283 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without %s acl support\n" msgstr "" #: src/findlib/acl.c:1586 #, c-format msgid "getacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1621 #, c-format msgid "acltostr error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1644 src/findlib/acl.c:1654 #, c-format msgid "strtoacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1683 #, c-format msgid "setacl error on file \"%s\": filesystem doesn't support ACLs\n" msgstr "" #: src/findlib/acl.c:1691 #, c-format msgid "setacl error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1818 #, c-format msgid "acl_get error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1893 #, c-format msgid "" "Trying to restore acl on file \"%s\" on filesystem without acl support\n" msgstr "" #: src/findlib/acl.c:1922 #, c-format msgid "" "Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl " "support\n" msgstr "" #: src/findlib/acl.c:1933 #, c-format msgid "" "Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl " "support\n" msgstr "" #: src/findlib/acl.c:1949 #, c-format msgid "acl_fromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:1963 src/findlib/acl.c:1971 #, c-format msgid "wrong encoding of acl type in acl stream on file \"%s\"\n" msgstr "" #: src/findlib/acl.c:1996 #, c-format msgid "acl_set error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2084 #, c-format msgid "acltotext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2108 #, c-format msgid "aclfromtext error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2128 #, c-format msgid "acl(SETACL) error on file \"%s\": ERR=%s\n" msgstr "" #: src/findlib/acl.c:2196 #, fuzzy, c-format msgid "pioctl VIOCGETAL error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/acl.c:2225 #, fuzzy, c-format msgid "pioctl VIOCSETAL error on file \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/findlib/acl.c:2431 #, c-format msgid "Can't restore ACLs of %s - incompatible acl stream encountered - %d\n" msgstr "" #: src/findlib/shadowing.c:232 src/findlib/shadowing.c:253 #: src/findlib/shadowing.c:361 src/findlib/shadowing.c:383 #, c-format msgid "Fileset include block entry %s shadows %s removing it from fileset\n" msgstr "" #: src/findlib/shadowing.c:240 src/findlib/shadowing.c:260 #: src/findlib/shadowing.c:369 src/findlib/shadowing.c:390 #, c-format msgid "Fileset include block entry %s shadows %s\n" msgstr "" #: src/findlib/match.c:297 src/filed/fileset.c:710 #, fuzzy, c-format msgid "Unparseable size option: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/plugins/stored/autoxflate-sd.c:291 #, c-format msgid "autoxflate-sd.c: inflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:300 #, c-format msgid "autoxflate-sd.c: deflate ratio: %0.2f%%\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:346 #, c-format msgid "Unexpected autodeflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:368 #, c-format msgid "Unexpected autoinflate setting on %s" msgstr "" #: src/plugins/stored/autoxflate-sd.c:405 #, c-format msgid "" "autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%" "s->deflate=%s->SD]\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:532 src/filed/compression.c:160 #, c-format msgid "Compression deflateParams error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:564 src/filed/compression.c:197 #, c-format msgid "Compression fastlzlibSetCompressor error: %d\n" msgstr "" #: src/plugins/stored/autoxflate-sd.c:575 #, c-format msgid "autodeflation: Compressor on device %s is %s\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:392 msgid "" "scsicrypto-sd: Failed to unwrap encryption key, probably wrong " "KeyEncryptionKey in config\n" msgstr "" #: src/plugins/stored/scsicrypto-sd.c:529 #, c-format msgid "" "Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:910 msgid "Plugin File argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:916 msgid "Plugin Reader argument not specified.\n" msgstr "" #: src/plugins/filed/bpipe-fd.c:922 msgid "Plugin Writer argument not specified.\n" msgstr "" #: src/tools/bscrypto.c:166 #, c-format msgid "Missing device_name argument for this option\n" msgstr "" #: src/tools/bscrypto.c:173 #, c-format msgid "Either use -g or -k not both\n" msgstr "" #: src/tools/bscrypto.c:179 #, c-format msgid "Either use -c or -s not both\n" msgstr "" #: src/tools/bscrypto.c:188 #, c-format msgid "Either set or clear the crypto key or ask for status not both\n" msgstr "" #: src/tools/bscrypto.c:202 #, c-format msgid "" "Don't mix operations which are incompatible e.g. generate/show vs set/clear " "etc.\n" msgstr "" #: src/tools/bscrypto.c:239 #, c-format msgid "Enter cache entrie(s) (close with ^D): " msgstr "" #: src/tools/bscrypto.c:299 #, c-format msgid "Enter Key Encryption Key: " msgstr "" #: src/tools/bscrypto.c:304 src/tools/bscrypto.c:362 src/tools/bscrypto.c:406 #: src/tools/bscrypto.c:528 #, fuzzy, c-format msgid "Cannot open keyfile %s\n" msgstr "Не можливо створити чергу(fifo) %s: ERR=%s\n" #: src/tools/bscrypto.c:372 src/tools/bscrypto.c:377 #, fuzzy, c-format msgid "Failed to write %d bytes to keyfile %s\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/tools/bscrypto.c:401 #, c-format msgid "Enter Encryption Key: " msgstr "" #: src/tools/bscrypto.c:436 #, c-format msgid "Failed to base64 decode the keydata read from %s, aborting...\n" msgstr "" #: src/tools/bscrypto.c:451 #, c-format msgid "" "Failed to aes unwrap the keydata read from %s using the wrap data from %s, " "aborting...\n" msgstr "" #: src/tools/bscrypto.c:523 #, c-format msgid "Enter Encryption Key (close with ^D): " msgstr "" #: src/tools/drivetype.c:33 #, c-format msgid "" "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/drivetype.c:64 src/tools/fstype.c:88 #, c-format msgid "%s: unknown\n" msgstr "" #: src/tools/bsmtp.c:136 #, c-format msgid "Fatal malformed reply from %s: %s\n" msgstr "" #: src/tools/bsmtp.c:144 #, c-format msgid "Fatal fgets error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:177 #, c-format msgid "" "\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" " -6 forces bsmtp to use IPv6 addresses only.\n" " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: " "unlimited)\n" " -? print this message.\n" "\n" msgstr "" #: src/tools/bsmtp.c:364 msgid "Fatal error: no recipient given.\n" msgstr "" #: src/tools/bsmtp.c:392 #, c-format msgid "Fatal gethostname error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:403 #, fuzzy, c-format msgid "Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/tools/bsmtp.c:412 #, c-format msgid "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:473 src/tools/bsmtp.c:508 #, c-format msgid "Error unknown mail host \"%s\": ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:476 src/tools/bsmtp.c:511 msgid "Retrying connection using \"localhost\".\n" msgstr "" #: src/tools/bsmtp.c:501 #, fuzzy, c-format msgid "Failed to connect to mailhost %s\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/tools/bsmtp.c:519 #, c-format msgid "Fatal error: Unknown address family for smtp host: %d\n" msgstr "" #: src/tools/bsmtp.c:528 src/tools/bsmtp.c:533 #, c-format msgid "Fatal socket error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:538 #, c-format msgid "Fatal connect error to %s: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:547 #, c-format msgid "Fatal _open_osfhandle error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:554 src/tools/bsmtp.c:558 src/tools/bsmtp.c:567 #: src/tools/bsmtp.c:571 #, c-format msgid "Fatal fdopen error: ERR=%s\n" msgstr "" #: src/tools/bsmtp.c:563 #, c-format msgid "Fatal dup error: ERR=%s\n" msgstr "" #: src/tools/fstype.c:34 #, c-format msgid "" "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n" msgstr "" #: src/lib/crypto_nss.c:67 src/lib/crypto_gnutls.c:71 src/lib/crypto_none.c:65 #, c-format msgid "Unsupported digest type=%d specified\n" msgstr "Заданий тип відбитку=%d не підтримується\n" #: src/lib/message.c:365 src/lib/message.c:375 #, c-format msgid "Could not open console message file %s: ERR=%s\n" msgstr "" #: src/lib/message.c:380 #, c-format msgid "Could not get con mutex: ERR=%s\n" msgstr "" #: src/lib/message.c:491 msgid "BAREOS Message" msgstr "" #: src/lib/message.c:495 #, c-format msgid "open mail pipe %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:591 msgid "open mail pipe failed.\n" msgstr "" #: src/lib/message.c:604 #, c-format msgid "close error: ERR=%s\n" msgstr "" #: src/lib/message.c:617 #, c-format msgid "Mail prog: %s" msgstr "" #: src/lib/message.c:626 #, c-format msgid "" "Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:734 #, c-format msgid "fopen %s failed: ERR=%s\n" msgstr "" #: src/lib/message.c:944 msgid "Msg delivery error: Unable to store data in database.\n" msgstr "" #: src/lib/message.c:1034 #, c-format msgid "" "Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n" msgstr "" #: src/lib/message.c:1054 #, fuzzy, c-format msgid "Msg delivery error: fopen %s failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/lib/message.c:1449 src/lib/mem_pool.c:120 src/lib/smartall.c:103 #, c-format msgid "%s: ABORTING due to ERROR in %s:%d\n" msgstr "" #: src/lib/message.c:1452 #, c-format msgid "%s: ERROR TERMINATION at %s:%d\n" msgstr "" #: src/lib/message.c:1456 #, c-format msgid "%s: Fatal Error because: " msgstr "" #: src/lib/message.c:1458 #, c-format msgid "%s: Fatal Error at %s:%d because:\n" msgstr "" #: src/lib/message.c:1462 #, c-format msgid "%s: ERROR: " msgstr "" #: src/lib/message.c:1464 #, c-format msgid "%s: ERROR in %s:%d " msgstr "" #: src/lib/message.c:1467 #, c-format msgid "%s: Warning: " msgstr "" #: src/lib/message.c:1470 #, c-format msgid "%s: Security violation: " msgstr "" #: src/lib/message.c:1586 #, c-format msgid "%s ABORTING due to ERROR\n" msgstr "" #: src/lib/message.c:1589 #, c-format msgid "%s ERROR TERMINATION\n" msgstr "" #: src/lib/message.c:1592 #, c-format msgid "%s JobId %u: Fatal error: " msgstr "" #: src/lib/message.c:1601 #, c-format msgid "%s JobId %u: Error: " msgstr "" #: src/lib/message.c:1607 #, c-format msgid "%s JobId %u: Warning: " msgstr "" #: src/lib/message.c:1613 #, c-format msgid "%s JobId %u: Security violation: " msgstr "" #: src/lib/runscript.c:206 #, c-format msgid "" "Runscript: run %s \"%s\" could not execute, not in one of the allowed " "scripts dirs\n" msgstr "" #: src/lib/runscript.c:272 #, c-format msgid "%s: run %s \"%s\"\n" msgstr "" #: src/lib/runscript.c:282 #, c-format msgid "Runscript: %s could not execute. ERR=%s\n" msgstr "" #: src/lib/runscript.c:289 #, c-format msgid "%s: %s\n" msgstr "" #: src/lib/runscript.c:296 #, c-format msgid "Runscript: %s returned non-zero status=%d. ERR=%s\n" msgstr "" #: src/lib/runscript.c:335 msgid " --> RunScript\n" msgstr "" #: src/lib/runscript.c:336 #, c-format msgid " --> Command=%s\n" msgstr "" #: src/lib/runscript.c:337 #, c-format msgid " --> Target=%s\n" msgstr "" #: src/lib/runscript.c:338 #, c-format msgid " --> RunOnSuccess=%u\n" msgstr "" #: src/lib/runscript.c:339 #, c-format msgid " --> RunOnFailure=%u\n" msgstr "" #: src/lib/runscript.c:340 #, c-format msgid " --> FailJobOnError=%u\n" msgstr "" #: src/lib/runscript.c:341 #, c-format msgid " --> RunWhen=%u\n" msgstr "" #: src/lib/lex.c:95 src/lib/lex.c:134 #, c-format msgid "Problem probably begins at line %d.\n" msgstr "" #: src/lib/lex.c:101 #, c-format msgid "" "Config error: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:105 #, c-format msgid "Config error: %s\n" msgstr "" #: src/lib/lex.c:140 #, c-format msgid "" "Config warning: %s\n" " : line %d, col %d of file %s\n" "%s\n" "%s" msgstr "" #: src/lib/lex.c:144 #, c-format msgid "Config warning: %s\n" msgstr "" #: src/lib/lex.c:178 msgid "Close of NULL file\n" msgstr "" #: src/lib/lex.c:289 msgid "" "get_char: called after EOF. You may have a open double quote without the " "closing double quote.\n" msgstr "" #: src/lib/lex.c:359 msgid "none" msgstr "" #: src/lib/lex.c:360 msgid "comment" msgstr "" #: src/lib/lex.c:361 msgid "number" msgstr "" #: src/lib/lex.c:362 msgid "ip_addr" msgstr "" #: src/lib/lex.c:363 msgid "identifier" msgstr "" #: src/lib/lex.c:364 msgid "string" msgstr "" #: src/lib/lex.c:365 msgid "quoted_string" msgstr "" #: src/lib/lex.c:366 msgid "include" msgstr "" #: src/lib/lex.c:367 msgid "include_quoted_string" msgstr "" #: src/lib/lex.c:368 msgid "UTF-8 Byte Order Mark" msgstr "" #: src/lib/lex.c:369 msgid "UTF-16le Byte Order Mark" msgstr "" #: src/lib/lex.c:407 src/lib/lex.c:413 src/lib/lex.c:424 src/lib/lex.c:430 #, c-format msgid "expected a positive integer number, got: %s" msgstr "" #: src/lib/lex.c:546 msgid "" "This config file appears to be in an unsupported Unicode format (UTF-16be). " "Please resave as UTF-8\n" msgstr "" #: src/lib/lex.c:692 src/lib/lex.c:720 #, c-format msgid "Cannot open included config file %s: %s\n" msgstr "" #: src/lib/lex.c:779 src/lib/lex.c:836 #, c-format msgid "expected an integer or a range, got %s: %s" msgstr "" #: src/lib/lex.c:793 src/lib/lex.c:801 src/lib/lex.c:812 src/lib/lex.c:820 #, c-format msgid "expected an integer number, got %s: %s" msgstr "" #: src/lib/lex.c:850 #, c-format msgid "expected a name, got %s: %s" msgstr "" #: src/lib/lex.c:854 #, c-format msgid "name %s length %d too long, max is %d\n" msgstr "" #: src/lib/lex.c:862 #, c-format msgid "expected a string, got %s: %s" msgstr "" #: src/lib/jcr.c:240 src/lib/util.c:388 msgid "Backup" msgstr "" #: src/lib/jcr.c:242 msgid "Verifying" msgstr "" #: src/lib/jcr.c:244 msgid "Restoring" msgstr "" #: src/lib/jcr.c:246 msgid "Archiving" msgstr "" #: src/lib/jcr.c:248 msgid "Copying" msgstr "" #: src/lib/jcr.c:250 msgid "Migration" msgstr "" #: src/lib/jcr.c:252 msgid "Scanning" msgstr "" #: src/lib/jcr.c:254 msgid "Unknown operation" msgstr "" #: src/lib/jcr.c:265 msgid "backup" msgstr "" #: src/lib/jcr.c:267 msgid "verified" msgstr "" #: src/lib/jcr.c:269 msgid "restored" msgstr "" #: src/lib/jcr.c:269 msgid "restore" msgstr "" #: src/lib/jcr.c:271 msgid "archived" msgstr "" #: src/lib/jcr.c:271 msgid "archive" msgstr "" #: src/lib/jcr.c:273 msgid "copied" msgstr "" #: src/lib/jcr.c:273 msgid "copy" msgstr "" #: src/lib/jcr.c:275 msgid "migrated" msgstr "" #: src/lib/jcr.c:275 msgid "migrate" msgstr "" #: src/lib/jcr.c:277 msgid "scanned" msgstr "" #: src/lib/jcr.c:277 msgid "scan" msgstr "" #: src/lib/jcr.c:279 msgid "unknown action" msgstr "" #: src/lib/jcr.c:339 src/lib/lockmgr.c:268 src/lib/lockmgr.c:602 #: src/lib/lockmgr.c:628 #, c-format msgid "pthread key create failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:365 #, c-format msgid "pthread_once failed. ERR=%s\n" msgstr "" #: src/lib/jcr.c:394 #, fuzzy, c-format msgid "Could not init msg_queue mutex. ERR=%s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/lib/jcr.c:452 msgid "NULL jcr.\n" msgstr "" #: src/lib/jcr.c:568 #, c-format msgid "JCR use_count=%d JobId=%d\n" msgstr "" #: src/lib/jcr.c:686 #, c-format msgid "pthread_setspecific failed: ERR=%s\n" msgstr "" #: src/lib/jcr.c:1173 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Storage " "daemon.\n" msgstr "" #: src/lib/jcr.c:1185 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n" msgstr "" #: src/lib/jcr.c:1197 #, c-format msgid "" "Watchdog sending kill after %d secs to thread stalled reading Director.\n" msgstr "" #: src/lib/priv.c:61 #, c-format msgid "Could not find userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:67 #, c-format msgid "Could not find password entry. ERR=%s\n" msgstr "" #: src/lib/priv.c:80 #, c-format msgid "Could not find group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:88 #, c-format msgid "Could not initgroups for group=%s, userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:91 #, c-format msgid "Could not initgroups for userid=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:98 #, c-format msgid "Could not set group=%s: ERR=%s\n" msgstr "" #: src/lib/priv.c:108 #, fuzzy, c-format msgid "prctl failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/lib/priv.c:112 #, fuzzy, c-format msgid "setreuid failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/lib/priv.c:116 #, c-format msgid "cap_from_text failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:120 #, c-format msgid "cap_set_proc failed: ERR=%s\n" msgstr "" #: src/lib/priv.c:124 msgid "Keep readall caps not implemented this OS or missing libraries.\n" msgstr "" #: src/lib/priv.c:128 #, c-format msgid "Could not set specified userid: %s\n" msgstr "" #: src/lib/var.c:2673 msgid "everything ok" msgstr "" #: src/lib/var.c:2674 msgid "incomplete named character" msgstr "" #: src/lib/var.c:2675 msgid "incomplete hexadecimal value" msgstr "" #: src/lib/var.c:2676 msgid "invalid hexadecimal value" msgstr "" #: src/lib/var.c:2677 msgid "octal value too large" msgstr "" #: src/lib/var.c:2678 msgid "invalid octal value" msgstr "" #: src/lib/var.c:2679 msgid "incomplete octal value" msgstr "" #: src/lib/var.c:2680 msgid "incomplete grouped hexadecimal value" msgstr "" #: src/lib/var.c:2681 msgid "incorrect character class specification" msgstr "" #: src/lib/var.c:2682 msgid "invalid expansion configuration" msgstr "" #: src/lib/var.c:2683 msgid "out of memory" msgstr "" #: src/lib/var.c:2684 msgid "incomplete variable specification" msgstr "" #: src/lib/var.c:2685 msgid "undefined variable" msgstr "" #: src/lib/var.c:2686 msgid "input is neither text nor variable" msgstr "" #: src/lib/var.c:2687 msgid "unknown command character in variable" msgstr "" #: src/lib/var.c:2688 msgid "malformatted search and replace operation" msgstr "" #: src/lib/var.c:2689 msgid "unknown flag in search and replace operation" msgstr "" #: src/lib/var.c:2690 msgid "invalid regex in search and replace operation" msgstr "" #: src/lib/var.c:2691 msgid "missing parameter in command" msgstr "" #: src/lib/var.c:2692 msgid "empty search string in search and replace operation" msgstr "" #: src/lib/var.c:2693 msgid "start offset missing in cut operation" msgstr "" #: src/lib/var.c:2694 msgid "offsets in cut operation delimited by unknown character" msgstr "" #: src/lib/var.c:2695 msgid "range out of bounds in cut operation" msgstr "" #: src/lib/var.c:2696 msgid "offset out of bounds in cut operation" msgstr "" #: src/lib/var.c:2697 msgid "logic error in cut operation" msgstr "" #: src/lib/var.c:2698 msgid "malformatted transpose operation" msgstr "" #: src/lib/var.c:2699 msgid "source and target class mismatch in transpose operation" msgstr "" #: src/lib/var.c:2700 msgid "empty character class in transpose operation" msgstr "" #: src/lib/var.c:2701 msgid "incorrect character class in transpose operation" msgstr "" #: src/lib/var.c:2702 msgid "malformatted padding operation" msgstr "" #: src/lib/var.c:2703 msgid "width parameter missing in padding operation" msgstr "" #: src/lib/var.c:2704 msgid "fill string missing in padding operation" msgstr "" #: src/lib/var.c:2705 msgid "unknown quoted pair in search and replace operation" msgstr "" #: src/lib/var.c:2706 msgid "sub-matching reference out of range" msgstr "" #: src/lib/var.c:2707 msgid "invalid argument" msgstr "" #: src/lib/var.c:2708 msgid "incomplete quoted pair" msgstr "" #: src/lib/var.c:2709 msgid "lookup function does not support variable arrays" msgstr "" #: src/lib/var.c:2710 msgid "index of array variable contains an invalid character" msgstr "" #: src/lib/var.c:2711 msgid "index of array variable is incomplete" msgstr "" #: src/lib/var.c:2712 msgid "bracket expression in array variable's index not closed" msgstr "" #: src/lib/var.c:2713 msgid "division by zero error in index specification" msgstr "" #: src/lib/var.c:2714 msgid "unterminated loop construct" msgstr "" #: src/lib/var.c:2715 msgid "invalid character in loop limits" msgstr "" #: src/lib/var.c:2716 msgid "malformed operation argument list" msgstr "" #: src/lib/var.c:2717 msgid "undefined operation" msgstr "" #: src/lib/var.c:2718 msgid "formatting failure" msgstr "" #: src/lib/var.c:2727 msgid "unknown error" msgstr "" #: src/lib/scsi_crypto.c:238 msgid "Drive encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:246 msgid "Encryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:251 msgid "Encryption Mode: External\n" msgstr "" #: src/lib/scsi_crypto.c:256 msgid "Encryption Mode: Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:269 msgid "Decryption Mode: Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:274 msgid "Decryption Mode: Raw\n" msgstr "" #: src/lib/scsi_crypto.c:279 msgid "Decryption Mode: Decrypt\n" msgstr "" #: src/lib/scsi_crypto.c:284 msgid "Decryption Mode: Mixed\n" msgstr "" #: src/lib/scsi_crypto.c:296 msgid "Raw Decryption Mode Disabled (RDMD): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:300 msgid "Raw Decryption Mode Disabled (RDMD): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:310 msgid "Check External Encryption Mode Status (CEEMS) : No\n" msgstr "" #: src/lib/scsi_crypto.c:315 msgid "Check External Encryption Mode Status (CEEMS) : External\n" msgstr "" #: src/lib/scsi_crypto.c:320 msgid "Check External Encryption Mode Status (CEEMS) : Encrypt\n" msgstr "" #: src/lib/scsi_crypto.c:332 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:336 msgid "Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:346 msgid "Logical Block encryption parameters: No report\n" msgstr "" #: src/lib/scsi_crypto.c:351 msgid "Logical Block encryption parameters: Application Managed\n" msgstr "" #: src/lib/scsi_crypto.c:356 msgid "Logical Block encryption parameters: Drive Managed\n" msgstr "" #: src/lib/scsi_crypto.c:361 msgid "" "Logical Block encryption parameters: Library/Key Management Appliance " "Managed\n" msgstr "" #: src/lib/scsi_crypto.c:366 msgid "Logical Block encryption parameters: Unsupported\n" msgstr "" #: src/lib/scsi_crypto.c:381 msgid "Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:386 msgid "Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:391 msgid "Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:396 msgid "Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:455 msgid "Volume encryption status:\n" msgstr "" #: src/lib/scsi_crypto.c:460 #, fuzzy msgid "Compression Status: Unknown\n" msgstr "Статус задачі: Невідомий(%c)" #: src/lib/scsi_crypto.c:465 msgid "Compression Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:470 msgid "Compression Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:475 msgid "Compression Status: Compression Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:480 msgid "Compression Status: Compression Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:490 #, fuzzy msgid "Encryption Status: Unknown\n" msgstr "Статус задачі: Невідомий(%c)" #: src/lib/scsi_crypto.c:495 msgid "Encryption Status: Unavailable\n" msgstr "" #: src/lib/scsi_crypto.c:500 msgid "Encryption Status: Illegal logical block\n" msgstr "" #: src/lib/scsi_crypto.c:505 msgid "Encryption Status: Encryption Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:510 msgid "" "Encryption Status: Encryption Enabled but with non supported algorithm\n" msgstr "" #: src/lib/scsi_crypto.c:515 msgid "Encryption Status: Encryption Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:520 msgid "" "Encryption Status: Encryption Enabled but no valid key available for " "decryption\n" msgstr "" #: src/lib/scsi_crypto.c:529 msgid "Raw Decryption Mode Disabled Status (RDMDS): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:533 msgid "Raw Decryption Mode Disabled Status (RDMDS): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:539 msgid "Encryption Mode External Status (EMES): Enabled\n" msgstr "" #: src/lib/scsi_crypto.c:543 msgid "Encryption Mode External Status (EMES): Disabled\n" msgstr "" #: src/lib/scsi_crypto.c:555 msgid "Next Block Key Associated Data (KAD) Descriptor: Normal key\n" msgstr "" #: src/lib/scsi_crypto.c:560 msgid "" "Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n" msgstr "" #: src/lib/scsi_crypto.c:565 msgid "Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n" msgstr "" #: src/lib/scsi_crypto.c:570 msgid "Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n" msgstr "" #: src/lib/scsi_crypto.c:725 #, fuzzy msgid "Drive encryption status: Unknown\n" msgstr "Статус задачі: Невідомий(%c)" #: src/lib/scsi_crypto.c:733 msgid "Volume encryption status: Unknown\n" msgstr "" #: src/lib/bnet.c:120 src/lib/bnet.c:163 msgid "TLS connection initialization failed.\n" msgstr "" #: src/lib/bnet.c:130 msgid "TLS Negotiation failed.\n" msgstr "" #: src/lib/bnet.c:136 src/lib/bnet.c:182 msgid "" "TLS certificate verification failed. Peer certificate did not match a " "required commonName\n" msgstr "" #: src/lib/bnet.c:189 #, c-format msgid "" "TLS host certificate verification failed. Host name \"%s\" did not match " "presented certificate\n" msgstr "" #: src/lib/bnet.c:205 msgid "TLS enabled but not configured.\n" msgstr "" #: src/lib/bnet.c:211 msgid "TLS enable but not configured.\n" msgstr "" #: src/lib/bnet.c:326 msgid "No problem." msgstr "" #: src/lib/bnet.c:329 msgid "Authoritative answer for host not found." msgstr "" #: src/lib/bnet.c:332 msgid "Non-authoritative for host not found, or ServerFail." msgstr "" #: src/lib/bnet.c:335 msgid "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP." msgstr "" #: src/lib/bnet.c:338 msgid "Valid name, no data record of resquested type." msgstr "" #: src/lib/bnet.c:341 msgid "Unknown error." msgstr "" #: src/lib/bnet.c:585 #, c-format msgid "Unknown sig %d" msgstr "" #: src/lib/crypto_cache.c:160 #, fuzzy, c-format msgid "Could not create crypto cache file. %s ERR=%s\n" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/lib/crypto_cache.c:339 src/lib/crypto_cache.c:352 #, fuzzy msgid "Volumename" msgstr "Збирач" #: src/lib/crypto_cache.c:340 src/lib/crypto_cache.c:353 msgid "EncryptionKey" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Added" msgstr "" #: src/lib/crypto_cache.c:354 msgid "Expires" msgstr "" #: src/lib/watchdog.c:88 #, c-format msgid "Unable to initialize watchdog lock. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:185 msgid "BUG! register_watchdog called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:188 #, c-format msgid "BUG! Watchdog %p has NULL callback\n" msgstr "" #: src/lib/watchdog.c:191 #, c-format msgid "BUG! Watchdog %p has zero interval\n" msgstr "" #: src/lib/watchdog.c:211 msgid "BUG! unregister_watchdog_unlocked called before start_watchdog\n" msgstr "" #: src/lib/watchdog.c:331 #, c-format msgid "rwl_writelock failure. ERR=%s\n" msgstr "" #: src/lib/watchdog.c:346 #, c-format msgid "rwl_writeunlock failure. ERR=%s\n" msgstr "" #: src/lib/plugins.c:144 #, fuzzy, c-format msgid "dlopen plugin %s failed: ERR=%s\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/lib/plugins.c:159 #, c-format msgid "Lookup of loadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:171 #, c-format msgid "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n" msgstr "" #: src/lib/plugins.c:274 #, c-format msgid "Failed to open Plugin directory %s: ERR=%s\n" msgstr "" #: src/lib/plugins.c:285 #, c-format msgid "Failed to find any plugins in %s\n" msgstr "" #: src/lib/bsys.c:64 #, fuzzy, c-format msgid "safe_unlink could not compile regex pattern \"%s\" ERR=%s\n" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/lib/bsys.c:317 src/lib/bsys.c:334 src/lib/bsys.c:358 src/lib/bsys.c:370 #, c-format msgid "Out of memory: ERR=%s\n" msgstr "" #: src/lib/bsys.c:412 msgid "Buffer overflow.\n" msgstr "" #: src/lib/bsys.c:476 msgid "Bad errno" msgstr "" #: src/lib/bsys.c:491 #, c-format msgid "Memset for %d bytes at %s:%d\n" msgstr "" #: src/lib/bsys.c:522 #, c-format msgid "Cannot open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:538 #, c-format msgid "" "%s is already running. pid=%d\n" "Check file %s\n" msgstr "" #: src/lib/bsys.c:563 #, c-format msgid "Could not open pid file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:673 #, c-format msgid "Could not create state file. %s ERR=%s\n" msgstr "" #: src/lib/bsys.c:692 #, c-format msgid "Write final hdr error: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:101 #, c-format msgid "Could not destroy client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:237 #, c-format msgid "Could not init client queue: ERR=%s\n" msgstr "" #: src/lib/bnet_server_tcp.c:371 #, c-format msgid "Could not add job to client queue: ERR=%s\n" msgstr "" #: src/lib/berrno.c:54 msgid "Child exited normally." msgstr "" #: src/lib/berrno.c:61 msgid "Unknown error during program execvp" msgstr "" #: src/lib/berrno.c:64 #, c-format msgid "Child exited with code %d" msgstr "" #: src/lib/berrno.c:72 #, c-format msgid "Child died from signal %d: %s" msgstr "" #: src/lib/berrno.c:78 msgid "Invalid errno. No error message possible." msgstr "" #: src/lib/crypto.c:174 msgid "No error" msgstr "" #: src/lib/crypto.c:176 msgid "Signer not found" msgstr "" #: src/lib/crypto.c:178 msgid "Recipient not found" msgstr "" #: src/lib/crypto.c:180 msgid "Unsupported digest algorithm" msgstr "Відбиток" #: src/lib/crypto.c:182 msgid "Unsupported encryption algorithm" msgstr "" #: src/lib/crypto.c:184 msgid "Signature is invalid" msgstr "" #: src/lib/crypto.c:186 msgid "Decryption error" msgstr "" #: src/lib/crypto.c:189 msgid "Internal error" msgstr "" #: src/lib/crypto.c:191 msgid "Unknown error" msgstr "" #: src/lib/attr.c:72 #, c-format msgid "Error scanning attributes: %s\n" msgstr "" #: src/lib/sellist.c:62 msgid "Negative numbers not permitted.\n" msgstr "" #: src/lib/sellist.c:99 msgid "Selection items must be be greater than zero.\n" msgstr "" #: src/lib/sellist.c:103 msgid "Selection item too large.\n" msgstr "" #: src/lib/sellist.c:160 msgid "No input string given.\n" msgstr "" #: src/lib/crypto_gnutls.c:243 #, fuzzy, c-format msgid "Unable to init GNUTLS: ERR=%d\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/lib/ini.c:262 src/lib/ini.c:274 #, c-format msgid "" "Config file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:312 src/lib/ini.c:324 #, c-format msgid "" "Config file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/ini.c:560 src/lib/ini.c:672 #, fuzzy, c-format msgid "Cannot open config file %s: %s\n" msgstr "Не можливо створити чергу(fifo) %s: ERR=%s\n" #: src/lib/edit.c:490 msgid "Empty name not allowed.\n" msgstr "" #: src/lib/edit.c:500 #, c-format msgid "Illegal character \"%c\" in name.\n" msgstr "" #: src/lib/edit.c:507 msgid "Name too long.\n" msgstr "" #: src/lib/address_conf.c:51 #, c-format msgid "Only ipv4 and ipv6 are supported (%d)\n" msgstr "" #: src/lib/address_conf.c:55 #, c-format msgid "Only ipv4 is supported (%d)\n" msgstr "" #: src/lib/address_conf.c:164 #, c-format msgid "It was tried to assign a ipv6 address to a ipv4(%d)\n" msgstr "" #: src/lib/address_conf.c:173 #, c-format msgid "It was tried to assign a ipv4 address to a ipv6(%d)\n" msgstr "" #: src/lib/address_conf.c:291 msgid "the old style addresses cannot be mixed with new style" msgstr "" #: src/lib/address_conf.c:312 #, c-format msgid "can't resolve service(%s)" msgstr "" #: src/lib/address_conf.c:321 #, c-format msgid "can't resolve hostname(%s) %s" msgstr "" #: src/lib/address_conf.c:373 #, c-format msgid "Can't add default address (%s)\n" msgstr "" #: src/lib/tls_gnutls.c:124 #, fuzzy, c-format msgid "Failed to create a new GNUTLS certificate credential: ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/lib/tls_gnutls.c:135 msgid "GNUTLS doesn't support certdir use certfile instead\n" msgstr "" #: src/lib/tls_gnutls.c:152 #, c-format msgid "Error loading CA certificates from %s\n" msgstr "" #: src/lib/tls_gnutls.c:162 msgid "Certificate file must be specified as a verification store\n" msgstr "" #: src/lib/tls_gnutls.c:179 #, c-format msgid "Error loading certificate revocation list from %s\n" msgstr "" #: src/lib/tls_gnutls.c:201 #, c-format msgid "Error loading key from %s or certificate from %s\n" msgstr "" #: src/lib/tls_gnutls.c:216 #, fuzzy, c-format msgid "Failed to load DH file %s\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/lib/tls_gnutls.c:224 msgid "Failed to generate new DH parameters\n" msgstr "" #: src/lib/tls_gnutls.c:289 #, c-format msgid "gnutls_certificate_verify_peers2 failed: ERR=%s\n" msgstr "" #: src/lib/tls_gnutls.c:296 #, c-format msgid "peer certificate untrusted or revoked (0x%x)\n" msgstr "" #: src/lib/tls_gnutls.c:303 msgid "gnutls_certificate_expiration_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:307 msgid "peer certificate is expired\n" msgstr "" #: src/lib/tls_gnutls.c:313 msgid "gnutls_certificate_activation_time_peers failed\n" msgstr "" #: src/lib/tls_gnutls.c:317 msgid "peer certificate not yet active\n" msgstr "" #: src/lib/tls_gnutls.c:476 #, fuzzy, c-format msgid "Failed to create a new GNUTLS session: ERR=%s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/lib/res.c:67 #, c-format msgid "rwl_writelock failure at %s:%d: ERR=%s\n" msgstr "" #: src/lib/res.c:77 #, c-format msgid "rwl_writeunlock failure at %s:%d:. ERR=%s\n" msgstr "" #: src/lib/res.c:129 msgid "***UNKNOWN***" msgstr "" #: src/lib/res.c:236 src/lib/res.c:258 #, c-format msgid "expected an =, got: %s" msgstr "" #: src/lib/res.c:266 #, c-format msgid "Unknown item code: %d\n" msgstr "" #: src/lib/res.c:307 #, c-format msgid "message type: %s not found" msgstr "" #: src/lib/res.c:348 #, c-format msgid "Attempt to redefine name \"%s\" to \"%s\"." msgstr "" #: src/lib/res.c:520 #, c-format msgid "Attempt to redefine resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:557 #, c-format msgid "Too many %s directives. Max. is %d. line %d: %s\n" msgstr "" #: src/lib/res.c:569 #, c-format msgid "Could not find config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:730 #, c-format msgid "Missing config Resource \"%s\" referenced on line %d : %s\n" msgstr "" #: src/lib/res.c:824 #, c-format msgid "expected a size number, got: %s" msgstr "" #: src/lib/res.c:830 #, c-format msgid "expected a speed number, got: %s" msgstr "" #: src/lib/res.c:835 #, fuzzy msgid "unknown unit type encountered" msgstr "Невідомий тип файлу %d: не відновлено: %s\n" #: src/lib/res.c:853 #, c-format msgid "expected a %s, got: %s" msgstr "" #: src/lib/res.c:854 msgid "size" msgstr "" #: src/lib/res.c:854 msgid "speed" msgstr "" #: src/lib/res.c:998 #, c-format msgid "Expected a Tape Label keyword, got: %s" msgstr "" #: src/lib/res.c:1056 src/lib/res.c:1085 #, c-format msgid "Expected a block begin { , got: %s" msgstr "" #: src/lib/res.c:1060 msgid "Empty addr block is not allowed" msgstr "" #: src/lib/res.c:1064 #, c-format msgid "Expected a string, got: %s" msgstr "" #: src/lib/res.c:1072 #, c-format msgid "Expected a string [ip|ipv4|ipv6], got: %s" msgstr "" #: src/lib/res.c:1076 #, c-format msgid "Expected a string [ip|ipv4], got: %s" msgstr "" #: src/lib/res.c:1081 src/lib/res.c:1111 #, c-format msgid "Expected a equal =, got: %s" msgstr "" #: src/lib/res.c:1092 src/lib/res.c:1107 #, c-format msgid "Expected a identifier [addr|port], got: %s" msgstr "" #: src/lib/res.c:1097 msgid "Only one port per address block" msgstr "" #: src/lib/res.c:1103 msgid "Only one addr per address block" msgstr "" #: src/lib/res.c:1117 #, c-format msgid "Expected a number or a string, got: %s" msgstr "" #: src/lib/res.c:1123 src/lib/res.c:1158 #, c-format msgid "Expected an IP number or a hostname, got: %s" msgstr "" #: src/lib/res.c:1129 msgid "State machine missmatch" msgstr "" #: src/lib/res.c:1135 src/lib/res.c:1146 #, c-format msgid "Expected a end of block }, got: %s" msgstr "" #: src/lib/res.c:1140 #, c-format msgid "Can't add hostname(%s) and port(%s) to addrlist (%s)" msgstr "" #: src/lib/res.c:1163 src/lib/res.c:1180 #, c-format msgid "can't add port (%s) to (%s)" msgstr "" #: src/lib/res.c:1175 #, c-format msgid "Expected a port number or string, got: %s" msgstr "" #: src/lib/rwlock.c:298 msgid "rwl_writeunlock called too many times.\n" msgstr "" #: src/lib/rwlock.c:303 msgid "rwl_writeunlock by non-owner.\n" msgstr "" #: src/lib/rwlock.c:428 src/lib/devlock.c:493 #, c-format msgid "Thread %d found unchanged elements %d times\n" msgstr "" #: src/lib/rwlock.c:498 src/lib/devlock.c:563 #, c-format msgid "%02d: interval %d, writes %d, reads %d\n" msgstr "" #: src/lib/rwlock.c:508 src/lib/devlock.c:573 #, c-format msgid "data %02d: value %d, %d writes\n" msgstr "" #: src/lib/rwlock.c:513 src/lib/devlock.c:578 #, c-format msgid "Total: %d thread writes, %d data writes\n" msgstr "" #: src/lib/rwlock.c:585 src/lib/devlock.c:650 msgid "Try write lock" msgstr "" #: src/lib/rwlock.c:591 src/lib/devlock.c:656 msgid "Try read lock" msgstr "" #: src/lib/rwlock.c:647 src/lib/devlock.c:712 msgid "Create thread" msgstr "" #: src/lib/rwlock.c:657 src/lib/devlock.c:722 msgid "Join thread" msgstr "" #: src/lib/rwlock.c:659 src/lib/devlock.c:724 #, c-format msgid "%02d: interval %d, updates %d, r_collisions %d, w_collisions %d\n" msgstr "" #: src/lib/rwlock.c:671 src/lib/devlock.c:736 #, c-format msgid "data %02d: value %d, %d updates\n" msgstr "" #: src/lib/bsock.c:97 #, c-format msgid "Could not init bsock mutex. ERR=%s\n" msgstr "" #: src/lib/bsock.c:139 msgid "attr spool I/O error.\n" msgstr "" #: src/lib/bsock.c:276 #, c-format msgid "Director authorization problem at \"%s:%d\"\n" msgstr "Проблеми авторизації Директора \"%s:%d\"\n" #: src/lib/bsock.c:285 #, c-format msgid "" "Authorization problem: Remote server at \"%s:%d\" did not advertise required " "TLS support.\n" msgstr "" "Проблеми авторизації: Віддалений сервер \"%s:%d\" не повідомляє про " "необхідність використання TLS.\n" #: src/lib/bsock.c:295 #, c-format msgid "" "Authorization problem with Director at \"%s:%d\": Remote server requires " "TLS.\n" msgstr "" "Проблеми авторизації Керівника \"%s:%d\": Віддалений сепвер вимагає TLS.\n" #: src/lib/bsock.c:311 #, c-format msgid "TLS negotiation failed with Director at \"%s:%d\"\n" msgstr "Встановлення TLS із Керівником невдале \"%s:%d\"\n" #: src/lib/bsock.c:321 #, c-format msgid "" "Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n" msgstr "" "Погана відповідь на команду Hello: ERR=%s\n" "Керівник \"%s:%d\" ймовірно не запущений.\n" #: src/lib/bsock.c:330 #, c-format msgid "Director at \"%s:%d\" rejected Hello command\n" msgstr "Керівник \"%s:%d\" відкинув команду Hello\n" #: src/lib/bsock.c:341 #, fuzzy, c-format msgid "" "Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate validation error " "during the TLS handshake.\n" "Please see %s for help.\n" msgstr "" "Проблеми авторизації із Керівником \"%s:%d\"\n" "Швидше за все, проблема у паролях.\n" "Якщо Ви використовуєте TLS, можливо, невдала перевірка сертифікату під час " "TLS handshake.\n" "Для отримання допомоги, будь ласка, перегляньте http://doc.bareos.org/master/" "html/bareos-manual-main-reference.html#AuthorizationErrors.\n" #: src/lib/bsock_tcp.c:127 #, c-format msgid "" "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n" msgstr "" #: src/lib/bsock_tcp.c:133 #, c-format msgid "Unable to connect to %s on %s:%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:186 #, c-format msgid "bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:254 #, c-format msgid "Socket open error. proto=%d port=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:269 #, c-format msgid "Source address bind error. proto=%d. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:292 #, c-format msgid "Cannot set TCP_KEEPIDLE on socket: %s\n" msgstr "" #: src/lib/bsock_tcp.c:356 #, c-format msgid "Socket has errors=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:363 #, c-format msgid "Socket is terminated=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:371 #, c-format msgid "Socket has insane msglen=%d on call to %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:420 #, c-format msgid "Write error sending %d bytes to %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:426 #, c-format msgid "Wrote %d bytes to %s:%s:%d, but only %d accepted.\n" msgstr "" #: src/lib/bsock_tcp.c:496 src/lib/bsock_tcp.c:564 #, c-format msgid "Read expected %d got %d from %s:%s:%d\n" msgstr "" #: src/lib/bsock_tcp.c:518 #, c-format msgid "Packet size too big from \"%s:%s:%d. Terminating connection.\n" msgstr "" #: src/lib/bsock_tcp.c:553 #, c-format msgid "Read error from %s:%s:%d: ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:632 msgid "Could not malloc BSOCK data buffer\n" msgstr "" #: src/lib/bsock_tcp.c:650 src/lib/bsock_tcp.c:669 #, c-format msgid "sockopt error: %s\n" msgstr "" #: src/lib/bsock_tcp.c:656 src/lib/bsock_tcp.c:675 #, c-format msgid "Warning network buffer = %d bytes not max size.\n" msgstr "" #: src/lib/bsock_tcp.c:698 src/lib/bsock_tcp.c:738 #, c-format msgid "fcntl F_GETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:706 src/lib/bsock_tcp.c:746 src/lib/bsock_tcp.c:771 #, c-format msgid "fcntl F_SETFL error. ERR=%s\n" msgstr "" #: src/lib/bsock_tcp.c:965 #, c-format msgid "Attr spool write error. ERR=%s\n" msgstr "" #: src/lib/devlock.c:322 msgid "writeunlock called too many times.\n" msgstr "" #: src/lib/devlock.c:327 msgid "writeunlock by non-owner.\n" msgstr "" #: src/lib/parse_bsr.c:125 src/lib/parse_bsr.c:129 #, c-format msgid "" "Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:160 src/lib/parse_bsr.c:164 #, c-format msgid "" "Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n" "%s\n" msgstr "" #: src/lib/parse_bsr.c:213 #, c-format msgid "Cannot open bootstrap file %s: %s\n" msgstr "" #: src/lib/parse_bsr.c:321 #, c-format msgid "MediaType %s in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:355 #, c-format msgid "Device \"%s\" in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:542 #, c-format msgid "REGEX '%s' compile error. ERR=%s\n" msgstr "" #: src/lib/parse_bsr.c:552 msgid "JobType not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:559 msgid "JobLevel not yet implemented\n" msgstr "" #: src/lib/parse_bsr.c:801 #, c-format msgid "Slot %d in bsr at inappropriate place.\n" msgstr "" #: src/lib/parse_bsr.c:825 #, c-format msgid "VolFile : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:833 #, c-format msgid "VolBlock : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:841 #, c-format msgid "VolAddr : %llu-%llu\n" msgstr "" #: src/lib/parse_bsr.c:850 #, c-format msgid "FileIndex : %u\n" msgstr "" #: src/lib/parse_bsr.c:852 #, c-format msgid "FileIndex : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:862 #, c-format msgid "JobId : %u\n" msgstr "" #: src/lib/parse_bsr.c:864 #, c-format msgid "JobId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:874 #, c-format msgid "SessId : %u\n" msgstr "" #: src/lib/parse_bsr.c:876 #, c-format msgid "SessId : %u-%u\n" msgstr "" #: src/lib/parse_bsr.c:885 #, c-format msgid "VolumeName : %s\n" msgstr "" #: src/lib/parse_bsr.c:886 #, c-format msgid " MediaType : %s\n" msgstr "" #: src/lib/parse_bsr.c:887 #, c-format msgid " Device : %s\n" msgstr "" #: src/lib/parse_bsr.c:888 #, c-format msgid " Slot : %d\n" msgstr "" #: src/lib/parse_bsr.c:896 #, c-format msgid "Client : %s\n" msgstr "" #: src/lib/parse_bsr.c:904 #, c-format msgid "Job : %s\n" msgstr "" #: src/lib/parse_bsr.c:912 #, c-format msgid "SessTime : %u\n" msgstr "" #: src/lib/parse_bsr.c:922 msgid "BSR is NULL\n" msgstr "" #: src/lib/parse_bsr.c:926 #, c-format msgid "Next : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:927 #, c-format msgid "Root bsr : 0x%x\n" msgstr "" #: src/lib/parse_bsr.c:939 #, c-format msgid "count : %u\n" msgstr "" #: src/lib/parse_bsr.c:940 #, c-format msgid "found : %u\n" msgstr "" #: src/lib/parse_bsr.c:943 #, c-format msgid "done : %s\n" msgstr "" #: src/lib/parse_bsr.c:944 #, c-format msgid "positioning : %d\n" msgstr "" #: src/lib/parse_bsr.c:945 #, c-format msgid "fast_reject : %d\n" msgstr "" #: src/lib/daemon.c:56 #, c-format msgid "Cannot fork to become daemon: ERR=%s\n" msgstr "" #: src/lib/cram-md5.c:105 src/lib/cram-md5.c:130 msgid "1999 Authorization failed.\n" msgstr "" #: src/lib/btimers.c:258 msgid "stop_btimer called with NULL btimer_id\n" msgstr "" #: src/lib/parse_conf.c:141 #, c-format msgid "Unable to initialize resource lock. ERR=%s\n" msgstr "" #: src/lib/parse_conf.c:149 msgid "Config filename too long.\n" msgstr "" #: src/lib/parse_conf.c:181 #, c-format msgid "Cannot open config file \"%s\": %s\n" msgstr "" #: src/lib/parse_conf.c:200 msgid "" "Currently we cannot handle UTF-16 source files. Please convert the conf file " "to UTF-8\n" msgstr "" #: src/lib/parse_conf.c:204 #, c-format msgid "Expected a Resource name identifier, got: %s" msgstr "" #: src/lib/parse_conf.c:220 #, c-format msgid "expected resource name, got: %s" msgstr "" #: src/lib/parse_conf.c:231 #, c-format msgid "not in resource definition: %s" msgstr "" #: src/lib/parse_conf.c:253 #, c-format msgid "using deprecated keyword %s on line %d" msgstr "" #: src/lib/parse_conf.c:279 #, c-format msgid "" "Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource." msgstr "" #: src/lib/parse_conf.c:290 msgid "Name not specified for resource" msgstr "" #: src/lib/parse_conf.c:300 #, c-format msgid "unexpected token %d %s in resource definition" msgstr "" #: src/lib/parse_conf.c:306 #, c-format msgid "Unknown parser state %d\n" msgstr "" #: src/lib/parse_conf.c:311 msgid "End of conf file reached with unclosed resource." msgstr "" #: src/lib/parse_conf.c:486 #, c-format msgid "" "Found config item %s which has default value but no CFG_ITEM_DEFAULT flag " "set\n" msgstr "" #: src/lib/mem_pool.c:138 #, c-format msgid "MemPool index %d larger than max %d\n" msgstr "" #: src/lib/mem_pool.c:157 src/lib/mem_pool.c:178 src/lib/mem_pool.c:220 #: src/lib/mem_pool.c:290 src/lib/mem_pool.c:312 src/lib/mem_pool.c:349 #: src/lib/mem_pool.c:673 #, c-format msgid "Out of memory requesting %d bytes\n" msgstr "" #: src/lib/mem_pool.c:199 msgid "obuf is NULL\n" msgstr "" #: src/lib/compression.c:63 src/lib/util.c:438 msgid "None" msgstr "" #: src/lib/compression.c:67 msgid "Zlib errno" msgstr "" #: src/lib/compression.c:69 msgid "Zlib stream error" msgstr "" #: src/lib/compression.c:71 msgid "Zlib data error" msgstr "" #: src/lib/compression.c:73 msgid "Zlib memory error" msgstr "" #: src/lib/compression.c:75 msgid "Zlib buffer error" msgstr "" #: src/lib/compression.c:77 msgid "Zlib version error" msgstr "" #: src/lib/compression.c:88 msgid "GZIP compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:91 msgid "LZO2 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:94 msgid "LZFZ compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:97 msgid "LZ4 compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:100 msgid "LZ4HC compression not supported on this platform\n" msgstr "" #: src/lib/compression.c:103 #, c-format msgid "Unknown compression algorithm specified %d\n" msgstr "" #: src/lib/compression.c:112 msgid "Illegal compression algorithm LZFZ for compatible mode\n" msgstr "" #: src/lib/compression.c:115 msgid "Illegal compression algorithm LZ4 for compatible mode\n" msgstr "" #: src/lib/compression.c:118 msgid "Illegal compression algorithm LZ4HC for compatible mode\n" msgstr "" #: src/lib/compression.c:178 #, fuzzy msgid "Failed to initialize ZLIB compression\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/lib/compression.c:215 #, fuzzy msgid "Failed to initialize LZO compression\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/lib/compression.c:270 #, fuzzy msgid "Failed to initialize FASTLZ compression\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/lib/compression.c:300 #, fuzzy msgid "LZO init failed\n" msgstr "Невдале встановлення з'єднання TLS\n" #: src/lib/compression.c:328 #, c-format msgid "Compression deflate error: %d\n" msgstr "" #: src/lib/compression.c:339 #, c-format msgid "Compression deflateReset error: %d\n" msgstr "" #: src/lib/compression.c:371 #, c-format msgid "Compression LZO error: %d\n" msgstr "" #: src/lib/compression.c:402 #, c-format msgid "Compression fastlzlibCompress error: %d\n" msgstr "" #: src/lib/compression.c:413 #, c-format msgid "Compression fastlzlibCompressReset error: %d\n" msgstr "" #: src/lib/compression.c:529 src/lib/compression.c:700 #, c-format msgid "Uncompression error on file %s. ERR=%s\n" msgstr "" #: src/lib/compression.c:592 #, fuzzy, c-format msgid "LZO uncompression error on file %s. ERR=%d\n" msgstr "Помилка у %s файл %s: ERR=%s\n" #: src/lib/compression.c:741 #, c-format msgid "Compressed header version error. version=0x%x\n" msgstr "" #: src/lib/compression.c:749 #, c-format msgid "Compressed header size error. comp_len=%d, msglen=%d\n" msgstr "" #: src/lib/compression.c:788 #, c-format msgid "Compression algorithm 0x%x found, but not supported!\n" msgstr "" #: src/lib/compression.c:802 msgid "Compression algorithm GZIP found, but not supported!\n" msgstr "" #: src/lib/compression.c:879 msgid "Compressed data stream found, but compression not configured!\n" msgstr "" #: src/lib/passphrase.c:71 #, c-format msgid "Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n" msgstr "" #: src/lib/passphrase.c:85 #, c-format msgid "Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n" msgstr "" #: src/lib/tls_openssl.c:352 #, c-format msgid "" "Error with certificate at depth: %d, issuer = %s, subject = %s, ERR=%d:%s\n" msgstr "" #: src/lib/tls_openssl.c:402 msgid "Error initializing SSL context" msgstr "" #: src/lib/tls_openssl.c:438 msgid "Error loading certificate verification stores" msgstr "" #: src/lib/tls_openssl.c:443 msgid "" "Either a certificate file or a directory must be specified as a verification " "store\n" msgstr "" #: src/lib/tls_openssl.c:458 src/lib/tls_openssl.c:464 #: src/lib/tls_openssl.c:469 #, fuzzy msgid "Error loading revocation list file" msgstr "Помилка : З'єднання завершено" #: src/lib/tls_openssl.c:483 msgid "Error loading certificate file" msgstr "" #: src/lib/tls_openssl.c:493 msgid "Error loading private key" msgstr "" #: src/lib/tls_openssl.c:503 msgid "Unable to open DH parameters file" msgstr "" #: src/lib/tls_openssl.c:509 msgid "Unable to load DH parameters from specified file" msgstr "" #: src/lib/tls_openssl.c:513 msgid "Failed to set TLS Diffie-Hellman parameters" msgstr "" #: src/lib/tls_openssl.c:526 msgid "Error setting cipher list, no valid ciphers available\n" msgstr "" #: src/lib/tls_openssl.c:617 msgid "Peer failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:671 #, c-format msgid "Peer %s failed to present a TLS certificate\n" msgstr "" #: src/lib/tls_openssl.c:797 msgid "Error creating file descriptor-based BIO" msgstr "" #: src/lib/tls_openssl.c:811 msgid "Error creating new SSL object" msgstr "" #: src/lib/tls_openssl.c:869 src/lib/tls_openssl.c:880 msgid "Connect failure" msgstr "" #: src/lib/tls_openssl.c:957 src/lib/tls_openssl.c:961 msgid "TLS shutdown failure." msgstr "" #: src/lib/tls_openssl.c:1009 src/lib/tls_openssl.c:1022 msgid "TLS read/write failure." msgstr "" #: src/lib/util.c:211 msgid "Running" msgstr "" #: src/lib/util.c:214 msgid "Blocked" msgstr "" #: src/lib/util.c:220 msgid "Error: incomplete job" msgstr "" #: src/lib/util.c:223 src/lib/util.c:363 msgid "Fatal Error" msgstr "" #: src/lib/util.c:229 msgid "Non-fatal error" msgstr "" #: src/lib/util.c:235 src/lib/util.c:366 msgid "Canceled" msgstr "" #: src/lib/util.c:238 msgid "Verify differences" msgstr "" #: src/lib/util.c:241 msgid "Waiting on FD" msgstr "" #: src/lib/util.c:244 msgid "Wait on SD" msgstr "" #: src/lib/util.c:247 msgid "Wait for new Volume" msgstr "" #: src/lib/util.c:250 msgid "Waiting for mount" msgstr "" #: src/lib/util.c:253 msgid "Waiting for Storage resource" msgstr "" #: src/lib/util.c:256 msgid "Waiting for Job resource" msgstr "" #: src/lib/util.c:259 msgid "Waiting for Client resource" msgstr "" #: src/lib/util.c:262 msgid "Waiting on Max Jobs" msgstr "" #: src/lib/util.c:265 msgid "Waiting for Start Time" msgstr "" #: src/lib/util.c:268 msgid "Waiting on Priority" msgstr "" #: src/lib/util.c:286 #, c-format msgid "Unknown Job termination status=%d" msgstr "" #: src/lib/util.c:302 msgid "Completed successfully" msgstr "" #: src/lib/util.c:305 msgid "Completed with warnings" msgstr "" #: src/lib/util.c:308 msgid "Terminated with errors" msgstr "" #: src/lib/util.c:311 msgid "Fatal error" msgstr "" #: src/lib/util.c:314 msgid "Created, not yet running" msgstr "" #: src/lib/util.c:317 msgid "Canceled by user" msgstr "" #: src/lib/util.c:320 msgid "Verify found differences" msgstr "" #: src/lib/util.c:323 msgid "Waiting for File daemon" msgstr "" #: src/lib/util.c:326 msgid "Waiting for Storage daemon" msgstr "" #: src/lib/util.c:329 msgid "Waiting for higher priority jobs" msgstr "" #: src/lib/util.c:332 msgid "Batch inserting file records" msgstr "" #: src/lib/util.c:369 msgid "Differences" msgstr "" #: src/lib/util.c:372 msgid "Unknown term code" msgstr "" #: src/lib/util.c:391 msgid "Migrated Job" msgstr "" #: src/lib/util.c:394 msgid "Verify" msgstr "" #: src/lib/util.c:397 msgid "Restore" msgstr "" #: src/lib/util.c:400 msgid "Console" msgstr "" #: src/lib/util.c:403 msgid "System or Console" msgstr "" #: src/lib/util.c:406 msgid "Admin" msgstr "" #: src/lib/util.c:409 src/lib/util.c:499 msgid "Archive" msgstr "" #: src/lib/util.c:412 msgid "Job Copy" msgstr "" #: src/lib/util.c:415 msgid "Copy" msgstr "" #: src/lib/util.c:418 msgid "Migrate" msgstr "" #: src/lib/util.c:421 msgid "Scan" msgstr "" #: src/lib/util.c:425 msgid "Unknown Type" msgstr "" #: src/lib/util.c:435 msgid "Truncate" msgstr "" #: src/lib/util.c:470 msgid "Verify Init Catalog" msgstr "" #: src/lib/util.c:479 msgid "Verify Data" msgstr "" #: src/lib/util.c:482 msgid "Virtual Full" msgstr "" #: src/lib/util.c:498 msgid "Append" msgstr "" #: src/lib/util.c:500 msgid "Disabled" msgstr "" #: src/lib/util.c:502 msgid "Used" msgstr "" #: src/lib/util.c:503 msgid "Cleaning" msgstr "" #: src/lib/util.c:504 msgid "Purged" msgstr "" #: src/lib/util.c:505 msgid "Recycle" msgstr "" #: src/lib/util.c:506 msgid "Read-Only" msgstr "" #: src/lib/util.c:518 msgid "Invalid volume status" msgstr "" #: src/lib/util.c:904 msgid "Working directory not defined. Cannot continue.\n" msgstr "" #: src/lib/util.c:907 #, c-format msgid "Working Directory: \"%s\" not found. Cannot continue.\n" msgstr "" #: src/lib/util.c:911 #, c-format msgid "Working Directory: \"%s\" is not a directory. Cannot continue.\n" msgstr "" #: src/lib/signal.c:59 msgid "Invalid signal number" msgstr "" #: src/lib/signal.c:152 src/lib/signal.c:154 #, c-format msgid "BAREOS interrupted by signal %d: %s\n" msgstr "" #: src/lib/signal.c:167 #, c-format msgid "Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n" msgstr "" #: src/lib/signal.c:169 #, c-format msgid "Kaboom! exepath=%s\n" msgstr "" #: src/lib/signal.c:211 #, c-format msgid "Fork error: ERR=%s\n" msgstr "" #: src/lib/signal.c:219 #, c-format msgid "Calling: %s %s %s %s\n" msgstr "" #: src/lib/signal.c:223 #, c-format msgid "execv: %s failed: ERR=%s\n" msgstr "" #: src/lib/signal.c:247 #, c-format msgid "It looks like the traceback worked...\n" msgstr "" #: src/lib/signal.c:249 #, c-format msgid "The btraceback call returned %d\n" msgstr "" #: src/lib/signal.c:314 #, c-format msgid "BA_NSIG too small (%d) should be (%d)\n" msgstr "" #: src/lib/signal.c:322 msgid "UNKNOWN SIGNAL" msgstr "" #: src/lib/signal.c:323 msgid "Hangup" msgstr "" #: src/lib/signal.c:324 msgid "Interrupt" msgstr "" #: src/lib/signal.c:325 msgid "Quit" msgstr "" #: src/lib/signal.c:326 msgid "Illegal instruction" msgstr "" #: src/lib/signal.c:327 msgid "Trace/Breakpoint trap" msgstr "" #: src/lib/signal.c:328 msgid "Abort" msgstr "" #: src/lib/signal.c:330 msgid "EMT instruction (Emulation Trap)" msgstr "" #: src/lib/signal.c:333 msgid "IOT trap" msgstr "" #: src/lib/signal.c:335 msgid "BUS error" msgstr "" #: src/lib/signal.c:336 msgid "Floating-point exception" msgstr "" #: src/lib/signal.c:337 msgid "Kill, unblockable" msgstr "" #: src/lib/signal.c:338 msgid "User-defined signal 1" msgstr "" #: src/lib/signal.c:339 msgid "Segmentation violation" msgstr "" #: src/lib/signal.c:340 msgid "User-defined signal 2" msgstr "" #: src/lib/signal.c:341 msgid "Broken pipe" msgstr "" #: src/lib/signal.c:342 msgid "Alarm clock" msgstr "" #: src/lib/signal.c:343 msgid "Termination" msgstr "" #: src/lib/signal.c:345 msgid "Stack fault" msgstr "" #: src/lib/signal.c:347 msgid "Child status has changed" msgstr "" #: src/lib/signal.c:348 msgid "Continue" msgstr "" #: src/lib/signal.c:349 msgid "Stop, unblockable" msgstr "" #: src/lib/signal.c:350 msgid "Keyboard stop" msgstr "" #: src/lib/signal.c:351 msgid "Background read from tty" msgstr "" #: src/lib/signal.c:352 msgid "Background write to tty" msgstr "" #: src/lib/signal.c:353 msgid "Urgent condition on socket" msgstr "" #: src/lib/signal.c:354 msgid "CPU limit exceeded" msgstr "" #: src/lib/signal.c:355 msgid "File size limit exceeded" msgstr "" #: src/lib/signal.c:356 msgid "Virtual alarm clock" msgstr "" #: src/lib/signal.c:357 msgid "Profiling alarm clock" msgstr "" #: src/lib/signal.c:358 msgid "Window size change" msgstr "" #: src/lib/signal.c:359 msgid "I/O now possible" msgstr "" #: src/lib/signal.c:361 msgid "Power failure restart" msgstr "" #: src/lib/signal.c:364 msgid "No runnable lwp" msgstr "" #: src/lib/signal.c:367 msgid "SIGLWP special signal used by thread library" msgstr "" #: src/lib/signal.c:370 msgid "Checkpoint Freeze" msgstr "" #: src/lib/signal.c:373 msgid "Checkpoint Thaw" msgstr "" #: src/lib/signal.c:376 msgid "Thread Cancellation" msgstr "" #: src/lib/signal.c:379 msgid "Resource Lost (e.g. record-lock lost)" msgstr "" #: src/lib/bget_msg.c:89 msgid "Status OK\n" msgstr "" #: src/lib/bget_msg.c:93 #, c-format msgid "bget_msg: unknown signal %d\n" msgstr "" #: src/lib/smartall.c:164 src/lib/smartall.c:270 src/lib/smartall.c:285 msgid "Out of memory\n" msgstr "" #: src/lib/smartall.c:168 msgid "Too much memory used." msgstr "" #: src/lib/smartall.c:198 #, c-format msgid "Attempt to free NULL called from %s:%d\n" msgstr "" #: src/lib/smartall.c:208 #, c-format msgid "double free from %s:%d\n" msgstr "" #: src/lib/smartall.c:216 #, c-format msgid "qp->qnext->qprev != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:220 #, c-format msgid "qp->qprev->qnext != qp called from %s:%d\n" msgstr "" #: src/lib/smartall.c:229 #, c-format msgid "Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n" msgstr "" #: src/lib/smartall.c:306 #, c-format msgid "sm_realloc size: %d\n" msgstr "" #: src/lib/smartall.c:401 #, c-format msgid "" "\n" "Orphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n" msgstr "" #: src/lib/smartall.c:446 #, c-format msgid "Damaged buffer found. Called from %s:%d\n" msgstr "" #: src/lib/smartall.c:479 #, c-format msgid "" "\n" "Damaged buffers found at %s:%d\n" msgstr "" #: src/lib/smartall.c:482 msgid " discovery of bad prev link.\n" msgstr "" #: src/lib/smartall.c:485 msgid " discovery of bad next link.\n" msgstr "" #: src/lib/smartall.c:488 msgid " discovery of data overrun.\n" msgstr "" #: src/lib/smartall.c:491 msgid " NULL pointer.\n" msgstr "" #: src/lib/smartall.c:497 #, c-format msgid " Buffer address: %p\n" msgstr "" #: src/lib/smartall.c:503 #, c-format msgid "Damaged buffer: %6u bytes allocated at line %d of %s %s\n" msgstr "" #: src/lib/scsi_lli.c:68 src/lib/scsi_lli.c:194 src/lib/scsi_lli.c:441 #, fuzzy, c-format msgid "Failed to open %s: ERR=%s\n" msgstr "Не вдалось відкрити%s: ERR=%s\n" #: src/lib/scsi_lli.c:92 #, fuzzy, c-format msgid "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/lib/scsi_lli.c:100 #, c-format msgid "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:102 #, c-format msgid " host status 0x%02x driver status 0x%02x\n" msgstr "" #: src/lib/scsi_lli.c:218 #, fuzzy, c-format msgid "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/lib/scsi_lli.c:220 src/lib/scsi_lli.c:477 #, c-format msgid "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n" msgstr "" #: src/lib/scsi_lli.c:303 #, fuzzy, c-format msgid "Failed to find CAM device for %s: ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/lib/scsi_lli.c:314 #, fuzzy, c-format msgid "Failed to open CAM device for %s: ERR=%s\n" msgstr "Не можливо встановити час файлу %s: ERR=%s\n" #: src/lib/scsi_lli.c:323 #, c-format msgid "Failed to allocate new ccb for %s\n" msgstr "" #: src/lib/scsi_lli.c:348 #, fuzzy, c-format msgid "Failed to send ccb to device %s: %s\n" msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #: src/lib/scsi_lli.c:464 #, fuzzy, c-format msgid "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/lib/scsi_lli.c:483 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n" msgstr "" #: src/lib/scsi_lli.c:489 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned device is busy\n" msgstr "" #: src/lib/scsi_lli.c:497 #, c-format msgid "SCIOCCOMMAND ioctl on %s returned unknown status %d\n" msgstr "" #: src/lib/bpipe.c:366 src/lib/bpipe.c:449 msgid "Program killed by BAREOS (timeout)\n" msgstr "" #: src/lib/lockmgr.c:58 #, c-format msgid "ASSERT failed at %s:%i: %s\n" msgstr "" #: src/lib/lockmgr.c:63 #, c-format msgid "ASSERT failed at %s:%i: %s \n" msgstr "" #: src/lib/lockmgr.c:93 #, c-format msgid "Mutex lock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:103 #, c-format msgid "Mutex unlock failure. ERR=%s\n" msgstr "" #: src/lib/lockmgr.c:613 #, c-format msgid "pthread_create failed: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:364 msgid "Unable to open certificate file" msgstr "" #: src/lib/crypto_openssl.c:371 msgid "Unable to read certificate from file" msgstr "" #: src/lib/crypto_openssl.c:377 msgid "Unable to extract public key from certificate" msgstr "" #: src/lib/crypto_openssl.c:384 msgid "" "Provided certificate does not include the required subjectKeyIdentifier " "extension." msgstr "" #: src/lib/crypto_openssl.c:391 #, c-format msgid "Unsupported key type provided: %d\n" msgstr "" #: src/lib/crypto_openssl.c:428 src/lib/crypto_openssl.c:476 msgid "Unable to open private key file" msgstr "" #: src/lib/crypto_openssl.c:458 src/lib/crypto_openssl.c:492 msgid "Unable to read private key from file" msgstr "" #: src/lib/crypto_openssl.c:551 #, c-format msgid "Unsupported digest type: %d\n" msgstr "Цей тип відбитку не підтримується: %d\n" #: src/lib/crypto_openssl.c:565 msgid "OpenSSL digest initialization failed" msgstr "Відбиток" #: src/lib/crypto_openssl.c:579 msgid "OpenSSL digest update failed" msgstr "Відбиток" #: src/lib/crypto_openssl.c:597 msgid "OpenSSL digest finalize failed" msgstr "Відбиток" #: src/lib/crypto_openssl.c:695 msgid "OpenSSL digest_new failed" msgstr "" #: src/lib/crypto_openssl.c:701 msgid "OpenSSL sign get digest failed" msgstr "Відбиток" #: src/lib/crypto_openssl.c:740 src/lib/crypto_openssl.c:744 msgid "OpenSSL digest Verify final failed" msgstr "Відбиток" #: src/lib/crypto_openssl.c:749 msgid "No signers found for crypto verify.\n" msgstr "" #: src/lib/crypto_openssl.c:810 msgid "Signature creation failed" msgstr "" #: src/lib/crypto_openssl.c:888 msgid "Signature decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1012 msgid "Unsupported cipher type specified\n" msgstr "" #: src/lib/crypto_openssl.c:1161 msgid "CryptoData decoding failed" msgstr "" #: src/lib/crypto_openssl.c:1205 msgid "Failure decrypting the session key" msgstr "" #: src/lib/crypto_openssl.c:1256 #, c-format msgid "Unsupported contentEncryptionAlgorithm: %d\n" msgstr "" #: src/lib/crypto_openssl.c:1266 src/lib/crypto_openssl.c:1272 msgid "OpenSSL cipher context initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1279 msgid "Encryption session provided an invalid symmetric key" msgstr "" #: src/lib/crypto_openssl.c:1285 msgid "Encryption session provided an invalid IV" msgstr "" #: src/lib/crypto_openssl.c:1291 msgid "OpenSSL cipher context key/IV initialization failed" msgstr "" #: src/lib/crypto_openssl.c:1371 #, c-format msgid "Unable to init OpenSSL threading: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1384 msgid "Failed to seed OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1430 msgid "Failed to save OpenSSL PRNG\n" msgstr "" #: src/lib/crypto_openssl.c:1538 #, c-format msgid "Unable to destroy mutex: ERR=%s\n" msgstr "" #: src/lib/crypto_openssl.c:1615 #, fuzzy, c-format msgid "Unable to destroy mutex: %d ERR=%s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/restore.c:107 #, c-format msgid "Size of data or stream of %s not correct. Original %s, restored %s.\n" msgstr "" #: src/filed/restore.c:127 #, c-format msgid "Invalid length of Finder Info (got %d, not 32)\n" msgstr "" #: src/filed/restore.c:132 #, fuzzy, c-format msgid "Could not set Finder Info on %s\n" msgstr "Не вдалось перевстановити прапорці для файлу %s: ERR=%s\n" #: src/filed/restore.c:489 src/filed/verify_vol.c:90 #, c-format msgid "Record header scan error: %s\n" msgstr "" #: src/filed/restore.c:501 src/filed/verify_vol.c:99 #, c-format msgid "Data record error. ERR=%s\n" msgstr "" #: src/filed/restore.c:505 src/filed/verify_vol.c:103 #, c-format msgid "Actual data size %d not same as header %d\n" msgstr "" #: src/filed/restore.c:665 msgid "Unexpected cryptographic session data stream.\n" msgstr "" #: src/filed/restore.c:675 msgid "" "No private decryption keys have been defined to decrypt encrypted backup " "data.\n" msgstr "" #: src/filed/restore.c:686 msgid "Could not create digest.\n" msgstr "Не можливо створити відбиток.\n" #: src/filed/restore.c:704 msgid "Missing private key required to decrypt encrypted backup data.\n" msgstr "" #: src/filed/restore.c:707 msgid "Decrypt of the session key failed.\n" msgstr "" #: src/filed/restore.c:713 #, c-format msgid "An error occurred while decoding encrypted session data stream: %s\n" msgstr "" #: src/filed/restore.c:861 #, fuzzy, c-format msgid "Cannot open resource fork for %s.\n" msgstr "Не вдається відкрити файл %s для виведення. ERR=%s\n" #: src/filed/restore.c:1007 msgid "Unexpected cryptographic signature data stream.\n" msgstr "" #: src/filed/restore.c:1015 #, c-format msgid "Failed to decode message signature for %s\n" msgstr "" #: src/filed/restore.c:1088 #, c-format msgid "Encountered %ld acl errors while doing restore\n" msgstr "" #: src/filed/restore.c:1092 #, c-format msgid "Encountered %ld xattr errors while doing restore\n" msgstr "" #: src/filed/restore.c:1096 #, c-format msgid "" "%d non-supported data streams and %d non-supported attrib streams ignored.\n" msgstr "" #: src/filed/restore.c:1100 #, c-format msgid "%d non-supported resource fork streams ignored.\n" msgstr "" #: src/filed/restore.c:1103 #, c-format msgid "%d non-supported Finder Info streams ignored.\n" msgstr "" #: src/filed/restore.c:1106 #, c-format msgid "%d non-supported acl streams ignored.\n" msgstr "" #: src/filed/restore.c:1109 #, c-format msgid "%d non-supported crypto streams ignored.\n" msgstr "" #: src/filed/restore.c:1112 #, c-format msgid "%d non-supported xattr streams ignored.\n" msgstr "" #: src/filed/restore.c:1214 #, c-format msgid "Write error in Win32 Block Decomposition on %s: %s\n" msgstr "" #: src/filed/restore.c:1329 msgid "Logic error: output file should be open\n" msgstr "" #: src/filed/restore.c:1373 msgid "Logic error: output file should not be open\n" msgstr "" #: src/filed/verify.c:52 #, c-format msgid "Cannot malloc %d network read buffer\n" msgstr "" #: src/filed/verify.c:120 #, c-format msgid " Could not access %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:127 #, c-format msgid " Could not follow link %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:134 #, c-format msgid " Could not stat %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:140 src/filed/backup.c:609 #, c-format msgid " Unchanged file skipped: %s\n" msgstr "" #: src/filed/verify.c:143 #, c-format msgid " Archive file skipped: %s\n" msgstr "" #: src/filed/verify.c:146 #, c-format msgid " Recursion turned off. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:150 #, c-format msgid " File system change prohibited. Directory skipped: %s\n" msgstr "" #: src/filed/verify.c:158 #, c-format msgid " Could not open directory %s: ERR=%s\n" msgstr "" #: src/filed/verify.c:163 #, c-format msgid " Unknown file type %d: %s\n" msgstr "" #: src/filed/verify.c:211 src/filed/verify_vol.c:199 #, c-format msgid "Network error in send to Director: ERR=%s\n" msgstr "" #: src/filed/verify.c:231 src/filed/verify.c:429 src/filed/backup.c:286 #, c-format msgid "%s digest initialization failed\n" msgstr "Невдала ініціалізація відбитку %s\n" #: src/filed/verify.c:271 #, c-format msgid " Cannot open %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:286 #, c-format msgid " Cannot open resource fork for %s: ERR=%s.\n" msgstr "" #: src/filed/verify.c:349 #, c-format msgid "Error reading file %s: ERR=%s\n" msgstr "" #: src/filed/fd_plugins.c:614 src/filed/fd_plugins.c:841 #, c-format msgid "Command plugin \"%s\": no type in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:633 #, c-format msgid "Command plugin \"%s\": no object_name in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:644 src/filed/fd_plugins.c:848 #, c-format msgid "Command plugin \"%s\": no fname in startBackupFile packet.\n" msgstr "" #: src/filed/fd_plugins.c:924 msgid "Plugin save packet not found.\n" msgstr "" #: src/filed/fd_plugins.c:1076 #, c-format msgid "Plugin=%s not found.\n" msgstr "" #: src/filed/fd_plugins.c:1139 #, c-format msgid "Plugin createFile call failed. Stat=%d file=%s\n" msgstr "" #: src/filed/fd_plugins.c:1144 #, c-format msgid "Plugin createFile call failed. Returned CF_ERROR file=%s\n" msgstr "" #: src/filed/fd_plugins.c:2378 msgid "Command plugin: no fname in bareosCheckChanges packet.\n" msgstr "" #: src/filed/verify_vol.c:56 msgid "Storage command not issued before Verify.\n" msgstr "" #: src/filed/verify_vol.c:136 #, c-format msgid "Error scanning record header: %s\n" msgstr "" #: src/filed/crypto.c:74 msgid "" "Cannot create a new crypto session probably unsupported cipher configured.\n" msgstr "" #: src/filed/crypto.c:80 src/filed/crypto.c:89 msgid "An error occurred while encrypting the stream.\n" msgstr "" #: src/filed/crypto.c:164 #, c-format msgid "Missing cryptographic signature for %s\n" msgstr "" #: src/filed/crypto.c:197 src/filed/crypto.c:226 #, c-format msgid "Signature validation failed for file %s: ERR=%s\n" msgstr "" #: src/filed/crypto.c:214 #, c-format msgid "Digest one file failed for file: %s\n" msgstr "" #: src/filed/crypto.c:253 #, c-format msgid "Signature validation failed for %s: %s\n" msgstr "" #: src/filed/crypto.c:295 #, c-format msgid "Decryption error. buf_len=%d decrypt_len=%d on file %s\n" msgstr "" #: src/filed/crypto.c:401 msgid "Encrypting sparse or offset data not supported.\n" msgstr "" #: src/filed/crypto.c:412 msgid "Failed to initialize encryption context.\n" msgstr "" #: src/filed/crypto.c:442 #, c-format msgid "Missing encryption session data stream for %s\n" msgstr "" #: src/filed/crypto.c:447 #, c-format msgid "Failed to initialize decryption context for %s\n" msgstr "" #: src/filed/crypto.c:494 src/filed/crypto.c:520 msgid "Encryption error\n" msgstr "" #: src/filed/crypto.c:558 msgid "Decryption error\n" msgstr "" #: src/filed/dir_cmd.c:316 #, c-format msgid "" "Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this " "filed.\n" msgstr "" #: src/filed/dir_cmd.c:675 #, c-format msgid "2001 Job %s marked to be canceled.\n" msgstr "" #: src/filed/dir_cmd.c:678 msgid "2902 Error scanning cancel command.\n" msgstr "" #: src/filed/dir_cmd.c:759 #, c-format msgid "2991 Bad setdebug command: %s\n" msgstr "" #: src/filed/dir_cmd.c:797 src/filed/dir_cmd.c:804 msgid "2992 Bad estimate command.\n" msgstr "" #: src/filed/dir_cmd.c:803 #, c-format msgid "Bad estimate command: %s" msgstr "" #: src/filed/dir_cmd.c:831 #, c-format msgid "Bad Job Command: %s" msgstr "" #: src/filed/dir_cmd.c:870 #, fuzzy, c-format msgid "Bad RunBeforeJob command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/filed/dir_cmd.c:933 #, fuzzy, c-format msgid "Bad RunAfter command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/filed/dir_cmd.c:983 #, c-format msgid "Bad RunScript command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1015 #, fuzzy, c-format msgid "Bad Plugin Options command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/filed/dir_cmd.c:1066 #, fuzzy, c-format msgid "Bad RestoreObject command: %s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/filed/dir_cmd.c:1166 msgid "2909 Bad RestoreObject command.\n" msgstr "" #: src/filed/dir_cmd.c:1381 #, c-format msgid "" "DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n" msgstr "" #: src/filed/dir_cmd.c:1390 #, c-format msgid "Unknown backup level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1403 #, c-format msgid "Bad level command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1425 #, c-format msgid "Bad session command: %s" msgstr "" #: src/filed/dir_cmd.c:1489 #, c-format msgid "Bad storage command: %s" msgstr "" #: src/filed/dir_cmd.c:1568 msgid "Filed in restore only mode, backups are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1606 msgid "" "ACL support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1610 msgid "" "XATTR support requested in fileset but not available on this platform. " "Disabling ...\n" msgstr "" #: src/filed/dir_cmd.c:1619 msgid "Cannot contact Storage daemon\n" msgstr "" #: src/filed/dir_cmd.c:1638 #, c-format msgid "Bad response to append open: %s\n" msgstr "" #: src/filed/dir_cmd.c:1643 msgid "Bad response from stored to open command\n" msgstr "" #: src/filed/dir_cmd.c:1691 #, fuzzy, c-format msgid "Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/filed/dir_cmd.c:1696 #, fuzzy, c-format msgid "CreateSGenerate VSS snapshots failed. ERR=%s\n" msgstr "Не можливо створити теку %s: ERR=%s\n" #: src/filed/dir_cmd.c:1708 #, c-format msgid "Generate VSS snapshot of drive \"%c:\\\" failed.\n" msgstr "" #: src/filed/dir_cmd.c:1717 #, c-format msgid "VSS Writer (PrepareForBackup): %s\n" msgstr "" #: src/filed/dir_cmd.c:1723 msgid "No drive letters found for generating VSS snapshots.\n" msgstr "" #: src/filed/dir_cmd.c:1728 #, c-format msgid "VSS was not initialized properly. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:1782 msgid "Append Close with SD failed.\n" msgstr "" #: src/filed/dir_cmd.c:1786 #, c-format msgid "Bad status %d returned from Storage Daemon.\n" msgstr "" #: src/filed/dir_cmd.c:1821 src/filed/dir_cmd.c:1827 #, c-format msgid "2994 Bad verify command: %s\n" msgstr "" #: src/filed/dir_cmd.c:1842 src/filed/dir_cmd.c:1882 #, c-format msgid "2994 Bad verify level: %s\n" msgstr "" #: src/filed/dir_cmd.c:1928 msgid "Filed in backup only mode, restores are not allowed, aborting...\n" msgstr "" #: src/filed/dir_cmd.c:1977 #, c-format msgid "Bad replace command. CMD=%s\n" msgstr "" #: src/filed/dir_cmd.c:2000 #, c-format msgid "Bad where regexp. where=%s\n" msgstr "" #: src/filed/dir_cmd.c:2037 #, c-format msgid "VSS was not initialized properly. VSS support is disabled. ERR=%s\n" msgstr "" #: src/filed/dir_cmd.c:2085 #, c-format msgid "VSS Writer (RestoreComplete): %s\n" msgstr "" #: src/filed/dir_cmd.c:2135 msgid "Improper calling sequence.\n" msgstr "" #: src/filed/dir_cmd.c:2155 #, c-format msgid "Bad response to SD read open: %s\n" msgstr "" #: src/filed/dir_cmd.c:2160 msgid "Bad response from stored to read open command\n" msgstr "" #: src/filed/filed_conf.c:520 #, fuzzy, c-format msgid "Expected a Crypto Cipher option, got: %s" msgstr "Помилка автентифікації : %s" #: src/filed/filed.c:61 #, fuzzy, c-format msgid "" "\n" "Version: %s (%s)\n" "\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n" msgstr "" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s без сигналів\n" " -t перевірка - прочитати конфігурацію і вийти\n" " -? print this message.\n" "\n" #: src/filed/filed.c:191 msgid "-k option has no meaning without -u option.\n" msgstr "" #: src/filed/filed.c:339 #, c-format msgid "" "No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n" msgstr "" #: src/filed/filed.c:344 #, c-format msgid "Only one Client resource permitted in %s\n" msgstr "" #: src/filed/filed.c:368 #, c-format msgid "" "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for " "File daemon in %s.\n" msgstr "" #: src/filed/filed.c:401 msgid "PKI encryption/signing enabled but not compiled into Bareos.\n" msgstr "" #: src/filed/filed.c:412 #, c-format msgid "" "\"PKI Key Pair\" must be defined for File daemon \"%s\" in %s if either " "\"PKI Sign\" or \"PKI Encrypt\" are enabled.\n" msgstr "" #: src/filed/filed.c:424 src/filed/filed.c:455 src/filed/filed.c:496 msgid "Failed to allocate a new keypair object.\n" msgstr "" #: src/filed/filed.c:428 #, c-format msgid "Failed to load public certificate for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:434 #, c-format msgid "Failed to load private key for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:464 #, c-format msgid "Failed to load private key from file %s for File daemon \"%s\" in %s.\n" msgstr "" #: src/filed/filed.c:471 #, c-format msgid "" "Failed to load trusted signer certificate from file %s for File daemon \"%s" "\" in %s.\n" msgstr "" #: src/filed/filed.c:502 #, c-format msgid "" "Failed to load master key certificate from file %s for File daemon \"%s\" in " "%s.\n" msgstr "" #: src/filed/filed.c:518 #, c-format msgid "No Director resource defined in %s\n" msgstr "" #: src/filed/accurate_lmdb.c:64 #, fuzzy, c-format msgid "Unable to create MDB environment: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:81 #, fuzzy, c-format msgid "Unable to set MDB mapsize: %s\n" msgstr "Не можливо встановити параметри файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:90 #, fuzzy, c-format msgid "Unable to set MDB maxreaders: %s\n" msgstr "Не можливо встановити параметри файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:97 #, c-format msgid "Unable create LDMD database %s: %s\n" msgstr "" #: src/filed/accurate_lmdb.c:103 #, fuzzy, c-format msgid "Unable to start a write transaction: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:109 #, fuzzy, c-format msgid "Unable to open LMDB internal database: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:216 src/filed/accurate_lmdb.c:387 #, fuzzy, c-format msgid "Unable insert new data: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:233 src/filed/accurate_lmdb.c:368 #: src/filed/accurate_lmdb.c:415 src/filed/accurate_lmdb.c:476 #, fuzzy, c-format msgid "Unable close write transaction: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:238 src/filed/accurate_lmdb.c:363 #, fuzzy, c-format msgid "Unable to create write transaction: %s\n" msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #: src/filed/accurate_lmdb.c:249 #, fuzzy, c-format msgid "Unable to create read transaction: %s\n" msgstr "Будьласка виправте файл конфігурації: %s\n" #: src/filed/accurate_lmdb.c:294 src/filed/accurate_lmdb.c:443 #: src/filed/accurate_lmdb.c:510 #, fuzzy, c-format msgid "Unable to renew read transaction: %s\n" msgstr "Будьласка виправте файл конфігурації: %s\n" #: src/filed/accurate_lmdb.c:437 src/filed/accurate_lmdb.c:504 #, fuzzy, c-format msgid "Unable create cursor: %s\n" msgstr "Не вдалось створити %s: ERR=%s\n" #: src/filed/status.c:87 #, c-format msgid "Daemon started %s. Jobs: run=%d running=%d.\n" msgstr "" #: src/filed/status.c:149 #, c-format msgid " Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d bwlimit=%skB/s\n" msgstr "" #: src/filed/status.c:183 #, c-format msgid "Director connected at: %s\n" msgstr "" #: src/filed/status.c:185 #, c-format msgid "JobId %d Job %s is running.\n" msgstr "" #: src/filed/status.c:188 #, c-format msgid " %s%s %s Job started: %s\n" msgstr "" #: src/filed/status.c:201 #, c-format msgid "" " Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n" msgstr "" #: src/filed/status.c:209 #, c-format msgid " Files Examined=%s\n" msgstr "" #: src/filed/status.c:214 #, c-format msgid " Processing file: %s\n" msgstr "" #: src/filed/status.c:225 msgid " SDSocket closed.\n" msgstr "" #: src/filed/status.c:236 src/filed/status.c:330 src/filed/status.c:420 msgid "====\n" msgstr "" #: src/filed/status.c:300 msgid " SDSocket=closed\n" msgstr "" #: src/filed/status.c:474 src/filed/status.c:507 #, c-format msgid "Bad .status command: %s\n" msgstr "" #: src/filed/status.c:475 msgid "2900 Bad .status command, missing argument.\n" msgstr "" #: src/filed/status.c:508 msgid "2900 Bad .status command, wrong argument.\n" msgstr "" #: src/filed/status.c:577 msgid "Bareos Client: Idle" msgstr "" #: src/filed/status.c:588 msgid "Bareos Client: Running" msgstr "" #: src/filed/status.c:602 msgid "Bareos Client: Last Job Canceled" msgstr "" #: src/filed/status.c:606 msgid "Bareos Client: Last Job Failed" msgstr "" #: src/filed/status.c:610 msgid "Bareos Client: Last Job had Warnings" msgstr "" #: src/filed/authenticate.c:73 #, c-format msgid "I only authenticate directors, not %d\n" msgstr "" #: src/filed/authenticate.c:106 #, c-format msgid "Connection from unknown Director %s at %s rejected.\n" msgstr "" #: src/filed/authenticate.c:165 #, c-format msgid "Incorrect password given by Director at %s.\n" msgstr "" #: src/filed/authenticate.c:301 #, fuzzy, c-format msgid "" "Authorization key rejected by %s daemon.\n" "Please see %s for help.\n" msgstr "" "Проблеми під час авторизації Керівником.\n" "Швидше за все, невірні паролі.\n" "Для отримання допомоги, будь ласка, перегляньте http://doc.bareos.org/master/" "html/bareos-manual-main-reference.html#AuthorizationErrors.\n" #: src/filed/accurate.c:93 #, c-format msgid "Space saved with Base jobs: %lld MB\n" msgstr "" #: src/filed/accurate.c:261 #, fuzzy, c-format msgid "Cannot verify checksum for %s\n" msgstr "Не вдається відкрити файл %s для виведення. ERR=%s\n" #: src/filed/accurate.c:312 msgid "2991 Bad accurate command\n" msgstr "" #: src/filed/fileset.c:86 #, c-format msgid "Plugin Directory not defined. Cannot use plugin: \"%s\"\n" msgstr "" #: src/filed/fileset.c:128 #, fuzzy, c-format msgid "Error running program: %s. status=%d: ERR=%s\n" msgstr "Помилка у %s: ERR=%s\n" #: src/filed/fileset.c:139 #, c-format msgid "Cannot open FileSet input file: %s. ERR=%s\n" msgstr "" #: src/filed/fileset.c:190 #, c-format msgid "REGEX %s compile error. ERR=%s\n" msgstr "" #: src/filed/fileset.c:346 #, c-format msgid "Invalid FileSet command: %s\n" msgstr "" #: src/filed/backup.c:97 msgid "Cannot set buffer size FD->SD.\n" msgstr "" #: src/filed/backup.c:143 #, c-format msgid "Encountered %ld acl errors while doing backup\n" msgstr "" #: src/filed/backup.c:147 #, c-format msgid "Encountered %ld xattr errors while doing backup\n" msgstr "" #: src/filed/backup.c:200 #, c-format msgid " Cannot open resource fork for \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:304 #, c-format msgid "%s signature digest initialization failed\n" msgstr "" #: src/filed/backup.c:334 msgid "Failed to allocate memory for crypto signature.\n" msgstr "" #: src/filed/backup.c:339 src/filed/backup.c:347 src/filed/backup.c:368 msgid "An error occurred while signing the stream.\n" msgstr "" #: src/filed/backup.c:406 msgid "An error occurred finalizing signing the stream.\n" msgstr "" #: src/filed/backup.c:546 #, c-format msgid " Recursion turned off. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:553 #, c-format msgid " %s is a different filesystem. Will not descend from %s into it.\n" msgstr "" #: src/filed/backup.c:559 #, c-format msgid " Disallowed filesystem. Will not descend from %s into %s\n" msgstr "" #: src/filed/backup.c:564 #, c-format msgid " Disallowed drive type. Will not descend into %s\n" msgstr "" #: src/filed/backup.c:575 #, c-format msgid " Socket file skipped: %s\n" msgstr "" #: src/filed/backup.c:588 #, c-format msgid " Could not access \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:595 #, c-format msgid " Could not follow link \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:602 #, c-format msgid " Could not stat \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:612 #, c-format msgid " Archive file not saved: %s\n" msgstr "" #: src/filed/backup.c:616 #, c-format msgid " Could not open directory \"%s\": ERR=%s\n" msgstr "" #: src/filed/backup.c:625 #, c-format msgid " Unknown file type %d; not saved: %s\n" msgstr "" #: src/filed/backup.c:776 #, c-format msgid " Cannot open \"%s\": ERR=%s.\n" msgstr "" #: src/filed/backup.c:1080 msgid "Encrypted file but no EFS support functions\n" msgstr "" #: src/filed/backup.c:1217 #, c-format msgid "Read error on file %s. ERR=%s\n" msgstr "" #: src/filed/backup.c:1219 #, c-format msgid "Too many errors. JobErrors=%d.\n" msgstr "" #: src/filed/backup.c:1231 msgid "Encryption padding error\n" msgstr "" #: src/filed/backup.c:1301 msgid "Invalid file flags, no supported data stream type.\n" msgstr "" #: src/filed/backup.c:1586 #, c-format msgid "VSS Writer (BackupComplete): %s\n" msgstr "" #: src/include/baconfig.h:71 src/include/baconfig.h:72 #: src/include/baconfig.h:76 src/include/baconfig.h:77 #, c-format msgid "Failed ASSERT: %s\n" msgstr "" #: src/qt-tray-monitor/tray_conf.cpp:181 #, c-format msgid "Monitor: name=%s FDtimeout=%s SDtimeout=%s\n" msgstr "Споглядач: назва=%s FDtimeout=%s SDtimeout=%s\n" #: src/qt-tray-monitor/tray_conf.cpp:187 #, c-format msgid "Director: name=%s address=%s FDport=%d\n" msgstr "Керівник: назва=%s address=%s FDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:191 #, c-format msgid "Client: name=%s address=%s FDport=%d\n" msgstr "Клієнт: назва=%s address=%s FDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:195 #, c-format msgid "Storage: name=%s address=%s SDport=%d\n" msgstr "Сховище: назва=%s address=%s SDport=%d\n" #: src/qt-tray-monitor/tray_conf.cpp:199 src/qt-console/bat_conf.cpp:155 #, fuzzy, c-format msgid "ConsoleFont: name=%s font face=%s\n" msgstr "Консоль: назва=%s rcfile=%s histfile=%s\n" #: src/qt-tray-monitor/authenticate.cpp:79 #, fuzzy, c-format msgid "" "Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n" msgstr "" "Проблеми під час авторизації Керівником.\n" "Швидше за все, невірні паролі.\n" "Для отримання допомоги, будь ласка, перегляньте http://doc.bareos.org/master/" "html/bareos-manual-main-reference.html#AuthorizationErrors.\n" #: src/qt-tray-monitor/authenticate.cpp:88 #, c-format msgid "Bad response to Hello command: ERR=%s\n" msgstr "Погана відповідь на команду Hello: ERR=%s\n" #: src/qt-tray-monitor/authenticate.cpp:96 msgid "Director rejected Hello command\n" msgstr "Керівник не прийняв команду Hello\n" #: src/qt-tray-monitor/authenticate.cpp:139 msgid "" "Director and Storage daemon passwords or names not the same.\n" "Please see " msgstr "" #: src/qt-tray-monitor/authenticate.cpp:147 #, c-format msgid "bdird set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n" msgstr "" "Автор Nicolas Boichat (2004)\n" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: tray-monitor [-c config_file] [-d debug_level]\n" " -c задати конфігураційний файл \n" " -d встановити рівень відлагоджування у \n" " -dt виводити часову мітку у даних відлагоджування\n" " -t перевірка - прогитати конфігурацію і завершити\n" " -? показати це повідомлення.\n" "\n" #: src/qt-console/console/console.cpp:134 src/qt-console/bcomm/dircomm.cpp:225 msgid "Connected" msgstr "З'єднано" #: src/qt-console/console/console.cpp:149 #, c-format msgid "" "Failed to connect to director %s for populateLists. Check, if director's " "address or hostname is configured properly\n" msgstr "" #: src/qt-console/console/console.cpp:372 src/qt-console/bcomm/dircomm.cpp:356 msgid "Processing command ..." msgstr "Виконання команди ..." #: src/qt-console/main.cpp:181 #, c-format msgid "" "\n" "Version: %s (%s) %s %s %s\n" "\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n" msgstr "" "\n" "Версія: %s (%s) %s %s %s\n" "\n" "Використання: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s без сигналів\n" " -t перевірка - прочитати конфігурацію і вийти\n" " -? print this message.\n" "\n" #: src/qt-console/bat_conf.cpp:152 #, c-format msgid "Console: name=%s\n" msgstr "Консоль: назва=%s\n" #: src/qt-console/bcomm/dircomm.cpp:84 #, c-format msgid "Already connected\"%s\".\n" msgstr "Вже приєднано\"%s\".\n" #: src/qt-console/bcomm/dircomm.cpp:95 #, c-format msgid "Connecting to Director %s:%d" msgstr "Приєднуюсь до Керівника %s:%d" #: src/qt-console/bcomm/dircomm.cpp:97 #, c-format msgid "" "Connecting to Director %s:%d\n" "\n" msgstr "" "З'єднуюсь із Керівником %s:%d\n" "\n" #: src/qt-console/bcomm/dircomm.cpp:209 msgid "Initializing ..." msgstr "Ініціалізація ..." #: src/qt-console/bcomm/dircomm.cpp:349 msgid "Command completed ..." msgstr "Команду виконано ..." #: src/qt-console/bcomm/dircomm.cpp:363 msgid "At main prompt waiting for input ..." msgstr "Очікуться введення у основній рядку ..." #: src/qt-console/bcomm/dircomm.cpp:370 src/qt-console/bcomm/dircomm.cpp:383 msgid "At prompt waiting for input ..." msgstr "Очікуться введення у рядку ..." #: src/qt-console/bcomm/dircomm.cpp:391 msgid "Command failed." msgstr "Помилка команди" #: src/qt-console/bcomm/dircomm.cpp:464 msgid "Director disconnected." msgstr "Керівник від'єднано" #, fuzzy #~ msgid "@exec error: ERR=%s\n" #~ msgstr "Помилка у %s: ERR=%s\n" #, fuzzy #~ msgid "Unable to load any shared library for .\n" #~ msgstr "Не можливо встановити власника файлу %s: ERR=%s\n" #, fuzzy #~ msgid "Expected a Console Authentication Type keyword, got: %s" #~ msgstr "Помилка автентифікації : %s" #, fuzzy #~ msgid "" #~ "Director authorization problem.\n" #~ "Most likely the passwords do not agree.\n" #~ "If you are using TLS, there may have been a certificate validation error " #~ "during the TLS handshake.\n" #~ "Please see " #~ msgstr "" #~ "Проблеми авторизації Керівника.\n" #~ "Швидше за все, проблема у паролях.\n" #~ "Якщо Ви використовуєте TLS, можливо, невдала перевірка сертифікату під " #~ "час TLS handshake.\n" #~ "Для отримання допомоги, будь ласка, перегляньте http://doc.bareos.org/" #~ "master/html/bareos-manual-main-reference.html#AuthorizationErrors.\n" #, fuzzy #~ msgid "" #~ "Client: name=%s protocol=%d authtype=%d address=%s FDport=%d MaxJobs=%u\n" #~ msgstr "Клієнт: назва=%s address=%s FDport=%d\n" #~ msgid "" #~ "No Client, Storage or Director resource defined in %s\n" #~ "Without that I don't how to get status from the File, Storage or Director " #~ "Daemon :-(\n" #~ msgstr "" #~ "У %s не визначено жодного ресурсу Клієнту, Зберігача або Керівника\n" #~ "Без цього я не знаю як отримати статус Зберігача, Збирача або Керівника\n" #~ msgid "" #~ "Invalid refresh interval defined in %s\n" #~ "This value must be greater or equal to 1 second and less or equal to 10 " #~ "minutes (read value: %d).\n" #~ msgstr "" #~ "Задано поганий інтервал оновлення у %s\n" #~ "Це значення повинно бути не меньше 1 секунди та не більше 10 хвилин " #~ "(теперішнє значення: %d).\n" #~ msgid "Director daemon" #~ msgstr "Керівник" #~ msgid "Connecting to Client %s:%d" #~ msgstr "Приєднуюсь до Клієнта %s:%d" #~ msgid "Connecting to Storage %s:%d" #~ msgstr "Приєднуюсь до Зберігача %s:%d" #~ msgid "Error, currentitem is not a Client, a Storage or a Director..\n" #~ msgstr "Помилка. Поточний пункт не є Клієнтом або Зберігачем.\n" #~ msgid "Cannot connect to daemon." #~ msgstr "Не можу приєднатись до демону." #~ msgid "Authentication error : %s" #~ msgstr "Помилка автентифікації : %s" #~ msgid "Opened connection with Director daemon." #~ msgstr "Відкриті з'єднання із Керівником." #~ msgid "Opened connection with File daemon." #~ msgstr "Відкриті з'єднання із Збирачем." #~ msgid "Opened connection with Storage daemon." #~ msgstr "Відкриті з'єднання із Зберігачем." #~ msgid "" #~ "Written by Nicolas Boichat (2004)\n" #~ "\n" #~ "Version: %s (%s) %s %s %s\n" #~ "\n" #~ "Usage: tray-monitor [-c config_file] [-d debug_level]\n" #~ " -c set configuration file to file\n" #~ " -d set debug level to \n" #~ " -dt print timestamp in debug output\n" #~ " -t test - read configuration and exit\n" #~ " -? print this message.\n" #~ "\n" #~ msgstr "" #~ "Автор Nicolas Boichat (2004)\n" #~ "\n" #~ "Версія: %s (%s) %s %s %s\n" #~ "\n" #~ "Використання: tray-monitor [-c config_file] [-d debug_level]\n" #~ " -c задати конфігураційний файл \n" #~ " -d встановити рівень відлагоджування у \n" #~ " -dt виводити часову мітку у даних відлагоджування\n" #~ " -t перевірка - прогитати конфігурацію і завершити\n" #~ " -? показати це повідомлення.\n" #~ "\n" #~ msgid "Bareos daemon status monitor" #~ msgstr "Монітор статусу демонів Bareos" #~ msgid "Open status window..." #~ msgstr "Відкрити вікно статусу" #~ msgid "Exit" #~ msgstr "Закінчити" #~ msgid " (DIR)" #~ msgstr "Керівник" #~ msgid " (FD)" #~ msgstr "Збирач" #~ msgid " (SD)" #~ msgstr "(Зберігач)" #~ msgid "Refresh interval in seconds: " #~ msgstr "Інтервал оновлення у секундах" #~ msgid "Refresh now" #~ msgstr "Оновити зараз" #~ msgid "About" #~ msgstr "Про..." #~ msgid "Close" #~ msgstr "Зачинити" #~ msgid "Disconnecting from Director %s:%d\n" #~ msgstr "Від'єднуюсь від Керівника %s:%d\n" #~ msgid "Disconnecting from Client %s:%d\n" #~ msgstr "Від'єднуюсь від Клієнта %s:%d\n" #~ msgid "Disconnecting from Storage %s:%d\n" #~ msgstr "Від'єднуюсь від Зберігача %s:%d\n" #~ msgid "Version" #~ msgstr "Версія" #~ msgid "" #~ "Current job: %s\n" #~ "Last job: %s" #~ msgstr "" #~ "Поточна задача: %s\n" #~ "Остання задача: %s" #~ msgid " (%d errors)" #~ msgstr " (%d помилок)" #~ msgid " (%d error)" #~ msgstr " (%d помилка)" #~ msgid "No current job." #~ msgstr "Задачі відсутні" #~ msgid "Job status: Created" #~ msgstr "Статус задачі: Створена" #~ msgid "Job status: Running" #~ msgstr "Статус задачі: Працює" #~ msgid "Job status: Blocked" #~ msgstr "Статус задачі: Заблокована" #~ msgid "Job status: Terminated" #~ msgstr "Статус задачі: Виконана" #~ msgid "Job status: Terminated in error" #~ msgstr "Статус задачі: Виконана із помилками" #~ msgid "Job status: Error" #~ msgstr "Статус задачі: Помилка" #~ msgid "Job status: Fatal error" #~ msgstr "Статус задачі: Ватальна помилка" #~ msgid "Job status: Verify differences" #~ msgstr "Статус задачі: Паревірка різниць" #~ msgid "Job status: Canceled" #~ msgstr "Статус задачі: Відмінена" #~ msgid "Job status: Waiting on File daemon" #~ msgstr "Статус задачі: Очікування Збирача" #~ msgid "Job status: Waiting on the Storage daemon" #~ msgstr "Статус задачі: Очікування Зберігача" #~ msgid "Job status: Waiting for new media" #~ msgstr "Статус задачі: Очікування нового носія" #~ msgid "Job status: Waiting for Mount" #~ msgstr "Статус задачі: Очікування монтування" #~ msgid "Job status: Waiting for storage resource" #~ msgstr "Статус задачі: Очікування ресурсу зберігання" #~ msgid "Job status: Waiting for job resource" #~ msgstr "Статус задачі: Очікування ресурсу задачі" #~ msgid "Job status: Waiting for Client resource" #~ msgstr "Статус задачі: Очікування ресурсу Слієнту" #~ msgid "Job status: Waiting for maximum jobs" #~ msgstr "Статус задачі: Очікування кількості задач" #~ msgid "Job status: Waiting for start time" #~ msgstr "Статус задачі: Очікування часу початку" #~ msgid "Job status: Waiting for higher priority jobs to finish" #~ msgstr "Статус задачі: Очікування завершення пріоритетніших задач" #~ msgid "Unknown job status %c." #~ msgstr "Невідомий статус задачі %c. " #~ msgid "Connecting to Client %s:%d\n" #~ msgstr "Приєднуюсь до Клієнта %s:%d\n" #~ msgid "Connecting to Storage %s:%d\n" #~ msgstr "Приєднуюсь до Зберігача %s:%d\n" #~ msgid "Cannot connect to daemon.\n" #~ msgstr "Не можу приєднатись до демону.\n" #~ msgid "Opened connection with Director daemon.\n" #~ msgstr "Відкриті з'єднання із Керівником.\n" #~ msgid "Bad response to Hello command: ERR=" #~ msgstr "Погана відповідь на команду Hello: ERR=" #, fuzzy #~ msgid "# Bareos bwx-console Configuration File\n" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Refresh" #~ msgstr "Оновити зараз" #, fuzzy #~ msgid "Job failed." #~ msgstr "Статус задачі: Відмінена" #, fuzzy #~ msgid "Restore job is waiting on File daemon." #~ msgstr "Статус задачі: Очікування Збирача" #, fuzzy #~ msgid "Restore job is waiting for new media." #~ msgstr "Статус задачі: Очікування нового носія" #, fuzzy #~ msgid "Restore job is waiting for storage resource." #~ msgstr "Статус задачі: Очікування ресурсу зберігання" #, fuzzy #~ msgid "Restore job is waiting for job resource." #~ msgstr "Статус задачі: Очікування ресурсу задачі" #, fuzzy #~ msgid "Restore job is waiting for Client resource." #~ msgstr "Статус задачі: Очікування ресурсу Слієнту" #, fuzzy #~ msgid "Restore job is waiting for maximum jobs." #~ msgstr "Статус задачі: Очікування кількості задач" #, fuzzy #~ msgid "Restore job is waiting for higher priority jobs to finish." #~ msgstr "Статус задачі: Очікування завершення пріоритетніших задач" #, fuzzy #~ msgid "Restore cancelled.\n" #~ msgstr "Статус задачі: Відмінена" #, fuzzy #~ msgid "Restore cancelled." #~ msgstr "Статус задачі: Відмінена" #, fuzzy #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Director \"%s\" in config file.\n" #~ "At least one CA certificate store is required.\n" #~ msgstr "" #~ "Жоден із параметрів \"TLS CA Certificate\" або \"TLS CA Certificate Dir\" " #~ "не задано для Керівника \"%s\" у %s. Необхідне щонайменше одне сховище " #~ "для сертифікату CA.\n" #, fuzzy #~ msgid "" #~ "No Director resource defined in config file.\n" #~ "Without that I don't how to speak to the Director :-(\n" #~ msgstr "" #~ "У %s не задано ресурсу Керівника\n" #~ "Без цього я не знаю як спілкуватись із Керівником :-(\n" #, fuzzy #~ msgid "" #~ "Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined " #~ "for Console \"%s\" in config file.\n" #~ msgstr "" #~ "Жоден із параметрів \"TLS CA Certificate\" або \"TLS CA Certificate Dir\" " #~ "не задано для Консолі \"%s\" у %s.\n" #, fuzzy #~ msgid "Cryptographic library initialization failed.\n" #~ msgstr "Ініціалізація криптографії невдала.\n" #, fuzzy #~ msgid "Please correct configuration file.\n" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Error : Library not initialized\n" #~ msgstr "Ініціалізація криптографії невдала.\n" #, fuzzy #~ msgid "Error : No configuration file loaded\n" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Connecting...\n" #~ msgstr "З'єднано" #~ msgid "Passphrase for Console \"%s\" TLS private key: " #~ msgstr "Пароль для закритого ключа TLS Консолі \"%s\": " #~ msgid "Passphrase for Director \"%s\" TLS private key: " #~ msgstr "Пароль для закритого ключа TLS Керівника \"%s\": " #, fuzzy #~ msgid "Failed to connect to the director\n" #~ msgstr "Ініціалізація контексту TLS для Консолі невдала \"%s\".\n" #, fuzzy #~ msgid "Connected\n" #~ msgstr "З'єднано" #, fuzzy #~ msgid "Connection terminated\n" #~ msgstr "Приєднуюсь до Клієнта %s:%d\n" #, fuzzy #~ msgid "Unknown command." #~ msgstr "Невідомий статус" #~ msgid "Welcome to bareos bwx-console %s (%s)!\n" #~ msgstr "Ласкаво просимо до bareos bwx-console %s (%s)!\n" #, fuzzy #~ msgid "Connect" #~ msgstr "З'єднано" #, fuzzy #~ msgid "Connect to the director" #~ msgstr "Приєднуюсь до Керівника %s:%d" #, fuzzy #~ msgid "Disconnect" #~ msgstr "З'єднано" #, fuzzy #~ msgid "Disconnect of the director" #~ msgstr "Від'єднуюсь від Керівника %s:%d\n" #, fuzzy #~ msgid "Change of configuration file" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Change your default configuration file" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Edit your configuration file" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Please choose a configuration file to use" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Using this configuration file: %s\n" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "About Bareos bwx-console" #~ msgstr "Ласкаво просимо до bareos bwx-console %s (%s)!\n" #, fuzzy #~ msgid "Please choose your default configuration file" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Use this configuration file as default?" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Configuration file" #~ msgstr "Будьласка виправте файл конфігурації: %s\n" #, fuzzy #~ msgid "Connection lost" #~ msgstr "Помилка : З'єднання завершено" #, fuzzy #~ msgid "Connected to the director." #~ msgstr "Приєднуюсь до Керівника %s:%d" #, fuzzy #~ msgid "Reconnect" #~ msgstr "З'єднано" #, fuzzy #~ msgid "Reconnect to the director" #~ msgstr "Приєднуюсь до Керівника %s:%d" #, fuzzy #~ msgid "Disconnected of the director." #~ msgstr "Від'єднуюсь від Керівника %s:%d\n" #~ msgid "" #~ "Authorization key rejected by Storage daemon.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Для отримання допомоги, будь ласка, перегляньте http://www.bareos.org/en/" #~ "rel-manual/Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000.\n" #~ msgid "" #~ "Director and Storage daemon passwords or names not the same.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Керівник та Зберігач мають не однакові назви або паролі.\n" #~ "Для отримання допомоги, будь ласка, перегляньте http://www.bareos.org/en/" #~ "rel-manual/Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000.\n" #~ msgid "" #~ "Incorrect password given by Director.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Невірний пароль, наданий Керівником.\n" #~ "Для отримання допомоги, будь ласка, перегляньте http://www.bareos.org/en/" #~ "rel-manual/Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000.\n" #~ msgid "" #~ "Incorrect authorization key from File daemon at %s rejected.\n" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Авторизаційний ключ, отриманий від Збирача %s відкинуто.\n" #~ "Для отримання допомоги, будь ласка, перегляньте http://www.bareos.org/en/" #~ "rel-manual/Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000.\n" #~ msgid "OSF1 Specific Default ACL attribs" #~ msgstr "Специфічні атрибути OSF1 Default ACL" #~ msgid "OSF1 Specific Access ACL attribs" #~ msgstr "Специфічні атрибути OSF1 Access ACL" #~ msgid "" #~ "Please see http://www.bareos.org/en/rel-manual/Bareos_Freque_Asked_Questi." #~ "html#SECTION003760000000000000000 for help.\n" #~ msgstr "" #~ "Для отримання допомоги, будь ласка, перегляньте http://www.bareos.org/en/" #~ "rel-manual/Bareos_Freque_Asked_Questi.html#SECTION003760000000000000000.\n" bareos-Release-14.2.6/scripts/000077500000000000000000000000001263011562700161275ustar00rootroot00000000000000bareos-Release-14.2.6/scripts/Makefile.in000077500000000000000000000070361263011562700202050ustar00rootroot00000000000000# # @MCOMMON@ working_dir=@working_dir@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ topdir = .. thisdir = scripts first_rule: all dummy: MKDIR = $(topdir)/autoconf/mkinstalldirs #------------------------------------------------------------------------- all: Makefile depend: #------------------------------------------------------------------------- installdirs: $(MKDIR) $(DESTDIR)$(sysconfdir) #$(MKDIR) $(DESTDIR)/etc/logrotate.d/ $(MKDIR) $(DESTDIR)$(sbindir) $(MKDIR) $(DESTDIR)$(scriptdir) $(MKDIR) $(DESTDIR)$(mandir) install: installdirs $(INSTALL_SCRIPT) bconsole $(DESTDIR)$(scriptdir)/bconsole $(INSTALL_SCRIPT) bareos $(DESTDIR)$(scriptdir)/bareos $(INSTALL_SCRIPT) bareos_config $(DESTDIR)$(scriptdir)/bareos_config $(INSTALL_SCRIPT) bareos $(DESTDIR)$(sbindir)/bareos $(INSTALL_SCRIPT) bareos-ctl-funcs $(DESTDIR)$(scriptdir)/bareos-ctl-funcs $(INSTALL_SCRIPT) bareos-ctl-dir $(DESTDIR)$(scriptdir)/bareos-ctl-dir $(INSTALL_SCRIPT) bareos-ctl-fd $(DESTDIR)$(scriptdir)/bareos-ctl-fd $(INSTALL_SCRIPT) bareos-ctl-sd $(DESTDIR)$(scriptdir)/bareos-ctl-sd @if test -f ${DESTDIR}${scriptdir}/mtx-changer; then \ echo " ==> Saving existing mtx-changer to mtx-changer.old"; \ $(MV) -f ${DESTDIR}${scriptdir}/mtx-changer ${DESTDIR}${scriptdir}/mtx-changer.old; \ fi $(INSTALL_SCRIPT) mtx-changer $(DESTDIR)$(scriptdir)/mtx-changer @if test -f ${DESTDIR}${sysconfdir}/mtx-changer.conf; then \ echo " ==> Installing mtx-changer.conf to mtx-changer.conf.new"; \ $(INSTALL_DATA) mtx-changer.conf $(DESTDIR)$(sysconfdir)/mtx-changer.conf.new; \ else \ $(INSTALL_DATA) mtx-changer.conf $(DESTDIR)$(sysconfdir)/mtx-changer.conf; \ fi @if test -f ${DESTDIR}${scriptdir}/disk-changer; then \ echo " ==> Saving existing disk-changer to disk-changer.old"; \ $(MV) -f ${DESTDIR}${scriptdir}/disk-changer ${DESTDIR}${scriptdir}/disk-changer.old; \ fi $(INSTALL_SCRIPT) disk-changer $(DESTDIR)$(scriptdir)/disk-changer $(INSTALL_DATA) btraceback.gdb $(DESTDIR)$(scriptdir)/btraceback.gdb $(INSTALL_DATA) btraceback.dbx $(DESTDIR)$(scriptdir)/btraceback.dbx $(INSTALL_DATA) btraceback.mdb $(DESTDIR)$(scriptdir)/btraceback.mdb #$(INSTALL_SCRIPT) -m 700 bareos-password-setup.sh ${DESTDIR}${scriptdir}/bareos-password-setup.sh $(INSTALL_SCRIPT) bareos-config ${DESTDIR}${scriptdir}/bareos-config $(INSTALL_SCRIPT) bareos-config-lib.sh ${DESTDIR}${scriptdir}/bareos-config-lib.sh $(INSTALL_SCRIPT) bareos-explorer ${DESTDIR}${scriptdir}/bareos-explorer $(INSTALL_SCRIPT) btraceback $(DESTDIR)$(sbindir)/btraceback #$(INSTALL_DATA) logrotate $(DESTDIR)/etc/logrotate.d/bareos-dir Makefile: Makefile.in cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status chmod 755 bareos btraceback chmod 755 bareos-ctl-dir bareos-ctl-fd bareos-ctl-sd bareos_config chmod 755 disk-changer mtx-changer bconsole Makefiles: $(SHELL) config.status chmod 755 bareos btraceback chmod 755 bareos-ctl-dir bareos-ctl-fd bareos-ctl-sd chmod 755 mtx-changer bconsole clean: @$(RMF) *~ 1 2 3 # clean for distribution distclean: clean @$(RMF) bareos fd btraceback @$(RMF) bareos-ctl-dir bareos-ctl-fd bareos-ctl-sd bareos_config @$(RMF) bconsole bareos.desktop @$(RMF) bareos.desktop.gnome1 bareos.desktop.gnome2 mtx-changer @$(RMF) gnome-console.console_apps bareos.desktop.gnome2.xsu @$(RMF) bgnome-console.console_apps @$(RMF) bareos.desktop.gnome2.consolehelper bareos.desktop.gnome1.xsu @$(RMF) bareos.desktop.gnome1.consolehelper # ------------------------------------------------------------------------ bareos-Release-14.2.6/scripts/bareos-config-lib.sh.in000066400000000000000000000470521263011562700223620ustar00rootroot00000000000000#!/bin/sh CONFIG_LIB=@scriptdir@/bareos-config-lib.sh DIR_CFG=@sysconfdir@ CFG_DIR=${DIR_CFG}/bareos-dir.conf DIR_SCRIPTS=@scriptdir@ DBCHECK="@sbindir@/bareos-dbcheck -B -c ${CFG_DIR}" SEC_GROUPS="tape disk" WORKING_DIR="@working_dir@" FILE_DAEMON_USER="@fd_user@" FILE_DAEMON_GROUP="@fd_group@" STORAGE_DAEMON_USER="@sd_user@" STORAGE_DAEMON_GROUP="@sd_group@" DIRECTOR_DAEMON_USER="@dir_user@" DIRECTOR_DAEMON_GROUP="@dir_group@" DB_VERSION="@BDB_VERSION@" SQL_DDL_DIR="@scriptdir@/ddl" SQLITE_BINDIR="@SQLITE_BINDIR@" MYSQL_BINDIR="@MYSQL_BINDIR@" POSTGRESQL_BINDIR="@POSTGRESQL_BINDIR@" INGRES_BINDIR="@INGRES_BINDIR@" PASSWORD_SUBST="\ XXX_REPLACE_WITH_DIRECTOR_PASSWORD_XXX \ XXX_REPLACE_WITH_CLIENT_PASSWORD_XXX \ XXX_REPLACE_WITH_STORAGE_PASSWORD_XXX \ XXX_REPLACE_WITH_DIRECTOR_MONITOR_PASSWORD_XXX \ XXX_REPLACE_WITH_CLIENT_MONITOR_PASSWORD_XXX \ XXX_REPLACE_WITH_STORAGE_MONITOR_PASSWORD_XXX \ " os_type=`uname -s` is_function() { func=${1-} test "$func" && type "$func" > /dev/null 2>&1 return $? } # does not work on all shells (only bash), # therefore removed until a better solution is found # list_functions() # { # if type typeset >/dev/null 2>&1; then # # show available shell functions, # # but exclude internal functions (name starts with "_" ...) # typeset -F | cut -d " " -f 3 | grep "^[a-z]" # else # echo "function list not available" # fi # } info() { echo "$@" >&2 } warn() { echo "Warning: $@" >&2 } error() { echo "Error: $@" >&2 } get_config_lib_file() { # can be used in following way: # LIB=`bareos-config get_config_lib_file` # . $LIB echo "${CONFIG_LIB}" } get_user_fd() { echo "${FILE_DAEMON_USER}" } get_group_fd() { echo "${FILE_DAEMON_GROUP}" } get_user_sd() { echo "${STORAGE_DAEMON_USER}" } get_group_sd() { echo "${STORAGE_DAEMON_GROUP}" } get_user_dir() { echo "${DIRECTOR_DAEMON_USER}" } get_group_dir() { echo "${DIRECTOR_DAEMON_GROUP}" } get_working_dir() { echo "${WORKING_DIR}" } get_database_ddl_dir() { echo "${SQL_DDL_DIR}" } get_database_version() { echo "${DB_VERSION}" } get_database_version_by_release() { param="$1" # get release from parameter by stripping everthing after the "-". # Example parameter: 13.2.2-926.1 release=`echo "$param" | sed 's/-.*//'` if [ -z "$release" ]; then error "failed to get database version for release $param" return 1 fi MAP=${SQL_DDL_DIR}/versions.map if [ ! -r "$MAP" ]; then error "failed to read Bareos database versions map file $MAP" return 1 fi MARKER=0 VERSIONS=`cat "$MAP"; echo "$release=$MARKER"` # add marker to list, # sort the list reverse, assuming versions x.y.z and lines x.y.z=db_version, # get entry one line after marker db_version=`printf "$VERSIONS" | sort -t. -k 1,1rn -k 2,2rn -k 3,3rn | sed -r -n "/[0-9\.]=$MARKER$/{ N; s/(.*)=(.*)\n(.*)=(.*)/\4/p }"` if [ -z "$db_version" ]; then db_version=`sed -n "s/^default=//p" $MAP` if [ "$db_version" ]; then warn "no database version defined for release $release ($param). Using default version: $db_version" else error "neither found database version for release $release ($param), nor found default database version in map file $MAP" return 1 fi fi echo "$db_version" return } get_database_utility_path() { db_type="${1-}" case ${db_type} in sqlite3) utility="sqlite3" bindir="${SQLITE_BINDIR}" ;; mysql) utility="mysql" bindir="${MYSQL_BINDIR}" ;; postgresql) utility="psql" pg_config --bindir > /dev/null 2>&1 if [ $? = 0 ]; then bindir=`pg_config --bindir` else bindir="${POSTGRESQL_BINDIR}" fi ;; ingres) utility="sql" bindir="${INGRES_BINDIR}" ;; *) ;; esac # # First see if the utility is already on the path # which ${utility} > /dev/null 2>&1 if [ $? = 0 ]; then echo "" else echo "${bindir}" fi } [ ${os_type} = Linux ] && \ setup_sd_user() { # # Guaranties that storage-daemon user and group exists # and storage-daemon user belongs to the required groups. # # normally, storage-daemon user # is already installed by the package preinstall script. # getent group ${STORAGE_DAEMON_GROUP} > /dev/null || groupadd -r ${STORAGE_DAEMON_GROUP} # # If the user doesn't exist create a new one otherwise modify it to have the wanted secondary groups. # if [ -z "${STORAGE_DAEMON_USER}" ]; then info "SKIPPED: no storage daemon user specified." return 0 fi if getent passwd ${STORAGE_DAEMON_USER} > /dev/null; then if [ "${STORAGE_DAEMON_USER}" != "root" ]; then # # Build a list of all groups the user is already in. # ADD_GROUPS="" CUR_ADD_GROUPS=`id -Gn ${STORAGE_DAEMON_USER}` for sec_group in ${CUR_ADD_GROUPS}; do [ -z "${USERMOD_CMDLINE}" ] && USERMOD_CMDLINE="usermod -G ${sec_group}" || USERMOD_CMDLINE="${USERMOD_CMDLINE},${sec_group}" done # # See what secondary groups exist for the SD user to be added to. # for sec_group in ${SEC_GROUPS}; do if getent group ${sec_group} >/dev/null; then found=0 for group in ${CUR_ADD_GROUPS}; do if [ ${group} = ${sec_group} ]; then found=1 fi done if [ ${found} = 0 ]; then [ -z "${ADD_GROUPS}" ] && ADD_GROUPS="${sec_group}" || ADD_GROUPS="${ADD_GROUPS} ${sec_group}" [ -z "${USERMOD_CMDLINE}" ] && USERMOD_CMDLINE="usermod -G ${sec_group}" || USERMOD_CMDLINE="${USERMOD_CMDLINE},${sec_group}" fi fi done # # If the user was already created before, # Make sure the correct primary group is set otherwise fix it. # if [ "`id -gn ${STORAGE_DAEMON_USER}`" != "${STORAGE_DAEMON_GROUP}" ]; then usermod -g ${STORAGE_DAEMON_GROUP} ${STORAGE_DAEMON_USER} || warn "failed to add groups ${STORAGE_DAEMON_GROUP} to ${STORAGE_DAEMON_USER}" fi # # Add the storage_daemon_user to additional groups (if needed) # if [ -n "${ADD_GROUPS}" ]; then ${USERMOD_CMDLINE} ${STORAGE_DAEMON_USER} || warn "failed: ${USERMOD_CMDLINE} ${STORAGE_DAEMON_USER}" fi fi else # # User doesn't exist so create it. # Determine additional groups the user should be in. # NEW_ADD_GROUPS="" for sec_group in ${SEC_GROUPS}; do if getent group ${sec_group}; then [ -z "${NEW_ADD_GROUPS}" ] && NEW_ADD_GROUPS="-G ${sec_group}" || NEW_ADD_GROUPS="${NEW_ADD_GROUPS},${sec_group}" fi done # # Create a new storage_daemon_user # useradd -r --comment "bareos" --home ${WORKING_DIR} -g ${STORAGE_DAEMON_GROUP} ${NEW_ADD_GROUPS} --shell /bin/false ${STORAGE_DAEMON_USER} || warn "failed to create user ${STORAGE_DAEMON_USER}" fi } [ ${os_type} != Linux ] && \ setup_sd_user() { echo "setup_sd_user() is not supported on this platform" exit 1 } get_config_param() { # # get parameter values from a Bareos configuration file # # configuration file CFG_FILE="${1-}" # section, currently ignored SECTION="${2-}" # name of the section, currently ignored NAME="${3-}" # parameter to get from config file PARAM="${4-}" # default value, if parameter is not found DEFAULT="${5-}" if [ ! -r "${CFG_FILE}" ]; then warn "failed to get parameter ${SECTION} ${NAME} ${PARAM}: can't read ${CFG_FILE}" # if default value is given, return it anyway [ "$DEFAULT" ] && echo "$DEFAULT" return 1 fi # get parameter from configuration file VALUE=`egrep -i "^[ ]*${PARAM}[ ]*=" ${CFG_FILE} |\ cut -d'=' -f2 | \ sed -e 's/[ ]*"//' -e 's/"//'` [ "$VALUE" ] || VALUE="$DEFAULT" echo "$VALUE" } [ ${os_type} = Linux ] && \ set_config_param() { # # set parameter values to a Bareos configuration file # # configuration file CFG_FILE="${1}" # section, currently ignored SECTION="${2}" # name of the section, currently ignored NAME="${3}" # parameter to set in the config file PARAM="${4}" # value to set VALUE="${5}" if ! [ -r "${CFG_FILE}" ]; then warn "failed to set parameter ${SECTION} ${NAME} ${PARAM} = ${VALUE}: can't read ${CFG_FILE}" return 1 fi if egrep -i "^[ ]*${PARAM}[ ]*=" ${CFG_FILE}; then sed -r -i "s#^[ ]*${PARAM}[ ]*=.*# ${PARAM} = \"${VALUE}\"#" ${CFG_FILE} echo "$CFG_FILE: set ${SECTION} ${NAME} ${PARAM} = ${VALUE}" else echo "FAILED to set ${SECTION} ${NAME} ${PARAM} = ${VALUE} ($CFG_FILE)" return 1 fi } [ ${os_type} != Linux ] && \ set_config_param() { echo "set_config_param() is not supported on this platform" exit 1 } get_database_param() { PARAM="${1-}" DEFAULT="${2-}" # use || to prevent errors rc=0 temp_log="/tmp/bareos-config.$$.log" DBCHECK_OUTPUT=`$DBCHECK 2>> $temp_log` || rc=$? if [ $rc != 0 ]; then echo "${DBCHECK_OUTPUT}" >> $temp_log echo "Error: executing $DBCHECK" >> $temp_log echo "" >> $temp_log # if default value is given, return it anyway if [ -n "$DEFAULT" ]; then warn "failed to get \"${PARAM}\" from config, using default value \"${DEFAULT}\", see $temp_log" echo "$DEFAULT" else warn "failed to get \"${PARAM}\" from config, see $temp_log" fi return 1 fi # if $temp_log exists, but have only size 0, remove it. if [ -f $temp_log ] && ! [ -s $temp_log ]; then rm $temp_log fi # DBCHECK gets the database parameter from the Director config file in a standard format, # however, it writes "db_name" (like the environment variables) # instead of "dbname" like in the config file. # Replace "db_" by "db" to be compatible with the config file. VALUE=`echo "$DBCHECK_OUTPUT" | sed "s/^db_/db/" | sed -n "s/^${PARAM}=//p"` [ -z "$VALUE" ] && VALUE="$DEFAULT" echo "$VALUE" return $rc } get_database_driver() { DEFAULT="${1-}" get_database_param "dbdriver" "$DEFAULT" | grep -v "XXX_REPLACE_WITH_DATABASE_DRIVER_XXX" return $? } get_database_name() { DEFAULT="${1-}" get_database_param "dbname" "$DEFAULT" return $? } get_database_user() { DEFAULT="${1-}" get_database_param "dbuser" "$DEFAULT" return $? } get_database_password() { DEFAULT="${1-}" get_database_param "dbpassword" "$DEFAULT" return $? } get_databases_installed() { # manually check different backends, to get the correct order [ -f ${SQL_DDL_DIR}/creates/postgresql.sql ] && echo "postgresql" [ -f ${SQL_DDL_DIR}/creates/mysql.sql ] && echo "mysql" [ -f ${SQL_DDL_DIR}/creates/sqlite3.sql ] && echo "sqlite3" return 0 } get_database_driver_default() { DBDRIVER=`get_database_driver` if [ -z "$DBDRIVER" ]; then DBDRIVER=`get_databases_installed | head -n 1` fi if [ -z "$DBDRIVER" ]; then # fallback and first choice DBDRIVER="postgresql" fi echo "$DBDRIVER" } initialize_database_driver() { DBDRIVER=`get_database_driver_default` replace "XXX_REPLACE_WITH_DATABASE_DRIVER_XXX" "${DBDRIVER}" } is_template_sql_file() { input_file=${1-} if [ -z "${input_file}" ]; then return 1 fi egrep '@DB_NAME@|@DB_USER@|@DB_PASS@|@DB_VERSION@' ${input_file} > /dev/null 2>&1 if [ $? != 0 ]; then # no variables found in file, this file is not a template. return 0 else # variables found, this file is a template, therefore return FALSE return 1 fi } get_translated_sql_file() { # replaces variables in a SQL DDL file # and returns the result as stdout. input_file=${1-} if [ -z "${input_file}" ]; then return 1 fi if [ ! -f ${input_file} ]; then return 2 fi db_type="${db_type:-`get_database_driver_default`}" db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" # if $db_password is defined but empty, an empty password will be used ("-" instead of ":-") db_password="${db_password-`get_database_password @db_password@`}" db_version=`get_database_version` if echo "$db_password" | grep -q '#'; then error "database passwords containing # are not supported." return 3 fi case ${db_type} in sqlite3) ;; mysql) if [ "$db_password" != "" ]; then pass="IDENTIFIED BY '$db_password'" fi ;; postgresql) if [ "$db_password" != "" ]; then pass="PASSWORD '$db_password'" fi ;; ingres) if [ "$db_password" != "" ]; then pass="WITH PASSWORD = '$db_password'" fi ;; *) ;; esac sed -e "s#@DB_NAME@#${db_name}#" \ -e "s#@DB_USER@#${db_user}#" \ -e "s#@DB_PASS@#${pass}#" \ -e "s#@DB_VERSION@#${db_version}#" \ ${input_file} } get_database_grant_privileges() { # Returns the DDL for granting privileges for a database user. # Can be used, to get the SQL commands # to create additional database users. # If requested, this user can be limited to read-only database access. #db_name="$1" db_type="${1:-${db_type:-`get_database_driver_default`}}" db_user="${2-}" db_password="${3-}" case "$4" in "") # full access privileges="" ;; "readonly") privileges="-readonly" ;; *) echo "Unknown privileges parameter $4" return 1 ;; esac case ${db_type} in sqlite3) ;; mysql) sql_definitions="${SQL_DDL_DIR}/grants/mysql${privileges}.sql" ;; postgresql) sql_definitions="${SQL_DDL_DIR}/grants/postgresql${privileges}.sql" ;; ingres) sql_definitions="${SQL_DDL_DIR}/grants/ingres${privileges}.sql" ;; *) echo "Unknown database type $1" return 1 ;; esac if [ ! -z "${sql_definitions}" ]; then if [ ! -f ${sql_definitions} ]; then echo "Unable to open database table definitions in file ${sql_definitions}" return 1 fi get_translated_sql_file ${sql_definitions} fi return } translate_sql_files() { # Translates all available DDL files for one database type. # However, currently not used, because it reduced flexibility. SOURCE_DIR=${1:-$SQL_DDL_DIR} DEST_DIR=${2:-"@working_dir@/ddl"} db_type="${db_type:-`get_database_driver_default`}" for i in `find "$SOURCE_DIR" -name "${db_type}*.sql" -printf "%P\n"`; do dest_file=${DEST_DIR}/$i mkdir -p `dirname $dest_file` get_translated_sql_file ${SOURCE_DIR}/$i > $dest_file # in case of errors, remove file if [ $? != 0 ]; then rm -f $dest_file fi done } apply_dbconfig_settings() { # this function is only useful on Debian Linux based distributions # as dbconfig-common is only available there # check if bareos-director configuration file already exists [ -r "${CFG_DIR}" ] || return 0 # check if dbconfig configuration file exists [ -r "/etc/dbconfig-common/bareos-database-common.conf" ] || return 0 . /etc/dbconfig-common/bareos-database-common.conf # check if dbconfig is enabled [ $dbc_upgrade = 'true' ] || return 0 case "$dbc_dbtype" in pgsql) set_config_param "${CFG_DIR}" "Catalog" "MyCatalog" "dbdriver" "postgresql" ;; mysql) set_config_param "${CFG_DIR}" "Catalog" "MyCatalog" "dbdriver" "mysql" ;; sqlite3) set_config_param "${CFG_DIR}" "Catalog" "MyCatalog" "dbdriver" "sqlite3" # dbconfig creates the db file as ${dbc_basepath}/${dbc_dbname} # while bareos expects the sqlite3 db file # as ${dbc_basepath}/${dbc_dbname}.db # Therefore a link is created. if [ -r "${dbc_basepath}/${dbc_dbname}" ]; then BAREOS_SQLITE_DB="`get_working_dir`/`get_database_name`.db" if [ ! -f $BAREOS_SQLITE_DB ]; then ln -s "${dbc_basepath}/${dbc_dbname}" "$BAREOS_SQLITE_DB" ls -a `get_working_dir`/bareos* || true fi fi ;; *) error "unknown database type $dbc_dbtype in /etc/dbconfig-common/bareos-database-common.conf" return 1 esac if [ "$dbc_authmethod_user" != "ident" ] && [ "$dbc_dbpass" ]; then set_config_param "${CFG_DIR}" "Catalog" "MyCatalog" "dbpassword" "$dbc_dbpass" fi } get_local_hostname() { # put actual short hostname in configuration files # try to get short hostname hname=`hostname -s` if [ -z "$hname" ]; then # try to get long hostname hname=`hostname|sed 's/\..*//g'` if [ -z "$hname" ]; then # set to "localhost" hname='localhost' fi fi echo "$hname" } replace() { if [ $# -ne 2 ]; then return 1 fi SEARCH="$1" REPLACE="$2" for file in `grep -l ${SEARCH} ${DIR_CFG}/*.conf` do echo "replacing '${SEARCH}' with '${REPLACE}' in $file" sed -i'' "s#${SEARCH}#${REPLACE}#g" ${file}; done return 0 } initialize_local_hostname() { # # Replace all XXX_REPLACE_WITH_LOCAL_HOSTNAME by the local hostname. # hname=`get_local_hostname` replace "XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX-dir" "${hname}-dir" replace "XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX-fd" "${hname}-fd" replace "XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX-sd" "${hname}-sd" replace "XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX-mon" "${hname}-mon" replace "XXX_REPLACE_WITH_LOCAL_HOSTNAME_XXX" "${hname}" } replace_password() { if [ $# -ne 2 ]; then return 1 fi SEARCH="$1" REPLACE="$2" for file in `grep -l ${SEARCH} ${DIR_CFG}/*.conf` do echo "replacing '${SEARCH}' in $file" sed -i'' "s#${SEARCH}#${REPLACE}#g" ${file}; done return 0 } initialize_passwords() { # # See if we need to generate a set of random passwords. # if [ ! -f ${DIR_CFG}/.rndpwd ]; then for string in ${PASSWORD_SUBST} do pass=`openssl rand -base64 33` echo "${string}=${pass}" >> ${DIR_CFG}/.rndpwd done chmod 400 ${DIR_CFG}/.rndpwd fi # Source the passwords . ${DIR_CFG}/.rndpwd for string in ${PASSWORD_SUBST} do eval "pass=\${$string}" if [ ! -z "${pass}" ]; then replace_password "${string}" "${pass}" fi done } init() { initialize_local_hostname #initialize_director_hostname initialize_passwords initialize_database_driver } bareos-Release-14.2.6/scripts/bareos-config.in000066400000000000000000000010431263011562700211730ustar00rootroot00000000000000#!/bin/sh LIB=@scriptdir@/bareos-config-lib.sh if ! [ -r "$LIB" ]; then echo "failed to read library $LIB" exit 1 fi . $LIB usage() { cat <<-EOT usage: $0 EOT exit 1 } help() { usage } # number of args passed args=$# # without parameter, nothing is done. # this allows this script to be sourced # to use its functions if [ $args -ge 1 ]; then # executes given arguments if is_function $1; then "$@" else echo "failed to execute $*. Not found." #usage exit 127 fi fi bareos-Release-14.2.6/scripts/bareos-ctl-dir.in000066400000000000000000000041441263011562700212710ustar00rootroot00000000000000#! /bin/sh # # bareos-ctl-dir This shell script takes care of starting and stopping # the bareos Director daemon # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # description: Backup Archiving REcovery Open Sourced. # PSCMD="@PSCMD@" PS="ps" # # On Solaris, you may need to use nawk, or alternatively, # add the GNU binaries to your path, such as /usr/xpg4/bin # AWK=@AWK@ # All these are not *really* needed but it makes it # easier to "steal" this code for the development # environment where they are different. # BACDIRBIN=@sbindir@ BACDIRCFG=@sysconfdir@ PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ DIR_PORT=@dir_port@ DIR_USER=@dir_user@ DIR_GROUP=@dir_group@ Bareos="@BAREOS@" PIDOF="@PIDOF@" PGREP="@PGREP@" OS=`uname -s` # # Source the generic functions. # . @scriptdir@/bareos-ctl-funcs # if /lib/tls exists, force Bareos to use the glibc pthreads instead if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then export LD_ASSUME_KERNEL=2.4.19 fi case "$1" in start) [ -x ${BACDIRBIN}/bareos-dir ] && { echo "Starting the $Bareos Director daemon" OPTIONS='' if [ "${DIR_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${DIR_USER}" fi if [ "${DIR_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${DIR_GROUP}" fi checkcfg if [ $? != 0 ]; then exit 1 fi if [ "x${VALGRIND_DIR}" = "x1" ]; then valgrind --leak-check=full ${BACDIRBIN}/bareos-dir $2 $3 ${OPTIONS} -v -c ${BACDIRCFG}/bareos-dir.conf else ${BACDIRBIN}/bareos-dir $2 $3 ${OPTIONS} -v -c ${BACDIRCFG}/bareos-dir.conf fi sleep 1 } ;; stop) [ -x ${BACDIRBIN}/bareos-dir ] && { echo "Stopping the $Bareos Director daemon" killproc ${BACDIRBIN}/bareos-dir ${DIR_PORT} } ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACDIRBIN}/bareos-dir ] && status ${BACDIRBIN}/bareos-dir ${DIR_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/scripts/bareos-ctl-fd.in000066400000000000000000000040441263011562700211030ustar00rootroot00000000000000#! /bin/sh # # bareos-ctl-fd This shell script takes care of starting and stopping # the bareos File daemon. # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # description: Backup Archiving REcovery Open Sourced. # PSCMD="@PSCMD@" PS="ps" # # On Solaris, you may need to use nawk, or alternatively, # add the GNU binaries to your path, such as /usr/xpg4/bin # AWK=@AWK@ # All these are not *really* needed but it makes it # easier to "steal" this code for the development # environment where they are different. # BACFDBIN=@sbindir@ BACFDCFG=@sysconfdir@ PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ FD_PORT=@fd_port@ FD_USER=@fd_user@ FD_GROUP=@fd_group@ Bareos="@BAREOS@" PIDOF="@PIDOF@" PGREP="@PGREP@" OS=`uname -s` # # Source the generic functions. # . @scriptdir@/bareos-ctl-funcs # if /lib/tls exists, force Bareos to use the glibc pthreads instead if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then export LD_ASSUME_KERNEL=2.4.19 fi case "$1" in start) [ -x ${BACFDBIN}/bareos-fd ] && { echo "Starting the $Bareos File daemon" OPTIONS='' if [ "${FD_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${FD_USER}" fi if [ "${FD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${FD_GROUP}" fi if [ "x${VALGRIND_FD}" = "x1" ]; then valgrind --leak-check=full ${BACFDBIN}/bareos-fd $2 $3 ${OPTIONS} -v -c ${BACFDCFG}/bareos-fd.conf else ${BACFDBIN}/bareos-fd $2 $3 ${OPTIONS} -v -c ${BACFDCFG}/bareos-fd.conf fi } ;; stop) # Stop the FD first so that SD will fail jobs and update catalog [ -x ${BACFDBIN}/bareos-fd ] && { echo "Stopping the $Bareos File daemon" killproc ${BACFDBIN}/bareos-fd ${FD_PORT} } ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACFDBIN}/bareos-fd ] && status ${BACFDBIN}/bareos-fd ${FD_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/scripts/bareos-ctl-funcs000066400000000000000000000101331263011562700212170ustar00rootroot00000000000000#! /bin/sh # A function to find the pid of a program. pidofproc() { pid="" # Test syntax. if [ $# = 0 ] ; then echo "Usage: pidofproc {program} {port}" return 1 fi # Get base program name base=`basename $1` # First try PID file if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -n 1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Next try "pidof" if [ ! -z "${PIDOF}" -a -x "${PIDOF}" ] ; then pid=`${PIDOF} $1` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Next try "pgrep" if [ ! -z "${PGREP}" -a -x "${PGREP}" ] ; then pid=`${PGREP} $1` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Finally try to extract it from ps pid=`${PSCMD} | grep $1 | ${AWK} '{ print $1 }' | tr '\n' ' '` echo $pid return 0 } # A function to stop a program. killproc() { RC=0 # Test syntax. if [ $# = 0 ]; then echo "Usage: killproc {program} {port} [signal]" return 1 fi notset=0 # check for third arg to be kill level if [ "$3" != "" ] ; then killlevel=$3 else notset=1 killlevel="-9" fi # Get base program name base=`basename $1` # Find pid. pid=`pidofproc $base $2` # Kill it. if [ "$pid" != "" ] ; then if [ "$notset" = "1" ] ; then if ${PS} -p "$pid">/dev/null 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid 2>/dev/null sleep 1 if ${PS} -p "$pid" >/dev/null 2>&1 ; then sleep 1 if ${PS} -p "$pid" >/dev/null 2>&1 ; then sleep 3 if ${PS} -p "$pid" >/dev/null 2>&1 ; then kill -KILL $pid 2>/dev/null fi fi fi fi ${PS} -p "$pid" >/dev/null 2>&1 RC=$? [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" # RC=$((! $RC)) # use specified level only else if ${PS} -p "$pid" >/dev/null 2>&1; then kill $killlevel $pid 2>/dev/null RC=$? [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" fi fi else failure "$base shutdown" fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f ${PIDDIR}/$base.$2.pid fi return $RC } # Function that checks if the configuration is OK and the Database can be connected checkcfg() { echo "Checking Configuration and Database connection ... " if [ ! -z "${DIR_USER}" ]; then su -s /bin/sh ${DIR_USER} -c "${BACDIRBIN}/bareos-dir ${OPTIONS} -f -t -c ${BACDIRCFG}/bareos-dir.conf" else ${BACDIRBIN}/bareos-dir ${OPTIONS} -f -t -c ${BACDIRCFG}/bareos-dir.conf fi if [ $? -eq 0 ]; then return 0 else return 1 fi } status() { pid="" # Test syntax. if [ $# = 0 ] ; then echo "Usage: status {program} {port}" return 1 fi # Get base program name base=`basename $1` # First try "pidof" if [ ! -z "${PIDOF}" -a -x "${PIDOF}" ] ; then pid=`${PIDOF} $1` if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 fi fi # Next try "pgrep" if [ ! -z "${PGREP}" -a -x "${PGREP}" ] ; then pid=`${PGREP} $1` if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 fi fi pid=`${PSCMD} | ${AWK} 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $2) || (("(" prog ")") == $2) || (("[" prog "]") == $2) || ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 fi # Next try the PID files if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -n 1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo "$base dead but pid file exists" return 1 fi fi # See if the subsys lock exists if [ -f ${SUBSYSDIR}/$base ] ; then echo "$base dead but subsys locked" return 2 fi echo "$base is stopped" return 3 } success() { return 0 } failure() { rc=$? return $rc } bareos-Release-14.2.6/scripts/bareos-ctl-sd.in000066400000000000000000000037501263011562700211230ustar00rootroot00000000000000#! /bin/sh # # bareos-ctl-sd This shell script takes care of starting and stopping # the bareos Storage daemon # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # description: Backup Archiving REcovery Open Sourced. # PSCMD="@PSCMD@" PS="ps" # # On Solaris, you may need to use nawk, or alternatively, # add the GNU binaries to your path, such as /usr/xpg4/bin # AWK=@AWK@ # All these are not *really* needed but it makes it # easier to "steal" this code for the development # environment where they are different. # BACSDBIN=@sbindir@ BACSDCFG=@sysconfdir@ PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ SD_PORT=@sd_port@ SD_USER=@sd_user@ SD_GROUP=@sd_group@ Bareos="@BAREOS@" PIDOF="@PIDOF@" PGREP="@PGREP@" OS=`uname -s` # # Source the generic functions. # . @scriptdir@/bareos-ctl-funcs # if /lib/tls exists, force Bareos to use the glibc pthreads instead if [ -d "/lib/tls" -a $OS = "Linux" -a `uname -r | cut -c1-3` = "2.4" ] ; then export LD_ASSUME_KERNEL=2.4.19 fi case "$1" in start) [ -x ${BACSDBIN}/bareos-sd ] && { echo "Starting the $Bareos Storage daemon" OPTIONS='' if [ "${SD_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${SD_USER}" fi if [ "${SD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi if [ "x${VALGRIND_SD}" = "x1" ]; then valgrind --leak-check=full ${BACSDBIN}/bareos-sd $2 $3 ${OPTIONS} -v -c ${BACSDCFG}/bareos-sd.conf else ${BACSDBIN}/bareos-sd $2 $3 ${OPTIONS} -v -c ${BACSDCFG}/bareos-sd.conf fi } ;; stop) [ -x ${BACSDBIN}/bareos-sd ] && { echo "Stopping the $Bareos Storage daemon" killproc ${BACSDBIN}/bareos-sd ${SD_PORT} } ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACSDBIN}/bareos-sd ] && status ${BACSDBIN}/bareos-sd ${SD_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/scripts/bareos-explorer.in000077500000000000000000000134601263011562700215770ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This script will collect all info of a bareos install like: # - logfiles # - bactraces # - tracebacks # - core files # set -a # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh working_dir=`get_working_dir` get_compression_method() { # # See what compression is available on the platform # bzip2=`which bzip2 2> /dev/null` gzip=`which gzip 2> /dev/null` if [ ! -z "${bzip2}" ]; then compressor="${bzip2} -z -c" comp_suffix=".bz2" else if [ ! -z "${gzip}" ]; then compressor="${gzip} -c" comp_suffix=".gz" else compressor="cat" comp_suffix="" fi fi } collect_debug_info() { # # If there is a logfile capture it and compress them when possible. # if [ -f log ]; then ${compressor} log > collect.$$/log${comp_suffix} fi # # Capture all core files and compress them when possible. # for file in *.core.* do ${compressor} ${file} > collect.$$/${file}${comp_suffix} if [ ${REMOVE:-NO} = YES ]; then rm -f ${file} fi done # # Capture all bactrace files # for file in *.bactrace do cp -p ${file} collect.$$ if [ ${REMOVE:-NO} = YES ]; then rm -f ${file} fi done # # Capture all traceback files # for file in *.traceback do cp -p ${file} collect.$$ if [ ${REMOVE:-NO} = YES ]; then rm -f ${file} fi done } collect_pkg_info() { case `uname -s` in Linux) LSB_DISTRIBUTOR=`lsb_release -i -s` case ${LSB_DISTRIBUTOR} in "SUSE LINUX") PKG_TYPE="rpm" if [ -f /etc/os-release ]; then cat /etc/os-release else if [ -f /etc/SuSE-release ]; then cat /etc/SuSE-release fi fi ;; "openSUSE project") PKG_TYPE="rpm" if [ -f /etc/os-release ]; then cat /etc/os-release else if [ -f /etc/SuSE-release ]; then cat /etc/SuSE-release fi fi ;; CentOS) PKG_TYPE="rpm" if [ -f /etc/redhat-release ]; then cat /etc/redhat-release fi ;; Fedora) PKG_TYPE="rpm" if [ -f /etc/fedora-release ]; then cat /etc/fedora-release fi ;; RedHatEnterprise*) PKG_TYPE="rpm" if [ -f /etc/redhat-release ]; then cat /etc/redhat-release fi ;; Oracle*) PKG_TYPE="rpm" ;; MandrivaLinux) PKG_TYPE="rpm" ;; Arch|archlinux) ;; LinuxMint) ;; Debian) PKG_TYPE="deb" if [ -f /etc/debian_version ]; then cat /etc/debian_version fi ;; Ubuntu) PKG_TYPE="deb" if [ -f /etc/debian_version ]; then cat /etc/debian_version fi ;; Univention) PKG_TYPE="deb" if [ -f /etc/debian_version ]; then cat /etc/debian_version fi ;; *) ;; esac case ${PKG_TYPE} in deb) dpkg-query -l '*bareos*' ;; rpm) rpm -qa | grep bareos ;; *) ;; esac ;; SunOS) for pkgname in `pkginfo | grep bareos | cut -d' ' -f2` do pkginfo -l ${pkgname} done ;; *) ;; esac > collect.$$/pkginfo } collect() { output="bareos.capture.`date +%Y%m%d%H%M`.tar" cd ${working_dir} || exit 1 # # Create a collection dir # mkdir collect.$$ # # See what compression we can use to make things somewhat smaller. # get_compression_method # # Collect the debug information like postmortem core files, logs # and bactrace and traceback files. # collect_debug_info # # Collect the installed packages. # collect_pkg_info # # tar up the whole capture folder # tar cf ${output} collect.$$ rm -rf collect.$$ echo "Please upload the following file for support: ${workdir}/${output}" } usage() { echo "Usage: $0 [-hr]" } main() { # # Parse options. # while getopts "hr" arg do case ${arg} in r) REMOVE="YES" ;; h|\?) usage exit 0 ;; *) usage exit 1 ;; esac done nr_shift=`expr $OPTIND - 1` shift ${nr_shift} collect $* } main $* bareos-Release-14.2.6/scripts/bareos.in000066400000000000000000000031021263011562700177260ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos daemons. # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # description: Backup Archiving REcovery Open Sourced. # # All these are not *really* needed but it makes it # easier to "steal" this code for the development # environment where they are different. # SCRIPTDIR=@scriptdir@ # # Disable Glibc malloc checks, it doesn't help and it keeps from getting # good dumps MALLOC_CHECK_=0 export MALLOC_CHECK_ case "$1" in start) [ -x ${SCRIPTDIR}/bareos-ctl-sd ] && ${SCRIPTDIR}/bareos-ctl-sd $1 $2 [ -x ${SCRIPTDIR}/bareos-ctl-fd ] && ${SCRIPTDIR}/bareos-ctl-fd $1 $2 [ -x ${SCRIPTDIR}/bareos-ctl-dir ] && ${SCRIPTDIR}/bareos-ctl-dir $1 $2 ;; stop) # Stop the FD first so that SD will fail jobs and update catalog [ -x ${SCRIPTDIR}/bareos-ctl-fd ] && ${SCRIPTDIR}/bareos-ctl-fd $1 $2 [ -x ${SCRIPTDIR}/bareos-ctl-sd ] && ${SCRIPTDIR}/bareos-ctl-sd $1 $2 [ -x ${SCRIPTDIR}/bareos-ctl-dir ] && ${SCRIPTDIR}/bareos-ctl-dir $1 $2 ;; restart) $0 stop sleep 2 $0 start ;; status) [ -x ${SCRIPTDIR}/bareos-ctl-sd ] && ${SCRIPTDIR}/bareos-ctl-sd status [ -x ${SCRIPTDIR}/bareos-ctl-fd ] && ${SCRIPTDIR}/bareos-ctl-fd status [ -x ${SCRIPTDIR}/bareos-ctl-dir ] && ${SCRIPTDIR}/bareos-ctl-dir status ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/scripts/bareos.png000066400000000000000000000014151263011562700201110ustar00rootroot00000000000000PNG  ЦH%+H>ˮ(^eKkR_~aG6jR}!pP *N.D)m0d9:,\RF)K^@Ųʅmy^G.'nS_(u:@c޽} omlaH9XTتVˣsiJaG(8+QcX &s9," C(""|$%qȇt"_hvs " URL: " Latest Revision: 2007-02-11 if version < 600 syntax clear elseif exists("b:current_syntax") finish endif " comments syn region BacComment display oneline start="#" end="$" keepend contains=BacTodo syn region BacComment2 start="/\*" end="\*/" syn region BacInclude start=/^@/ end="$" syntax region xCond start=/\w+\s*{/ms=e+1 end=/}/me=s-1 syntax keyword BacName Name syn case ignore syn keyword LevelElt contained Full Incremental Differential " todo syn keyword BacTodo contained TODO FIXME XXX NOTE syn region BacString start=/"/ skip=/\\"/ end=/"/ " Specifique Client { syn region BacClient display start=/Client {/ end="^}" contains=BacString,BacComment,BacC1,BacC2,BacC3,BacC4 syn match BacC1 contained /File\s*Retention/ syn match BacC2 contained /Maximum\s*Concurrent\s*Jobs/ syn match BacC3 contained /Job\s*Retention/ syn keyword BacC4 contained Name Password Address Catalog AutoPrune FDPort " FileSet { syn region BacFileSet display start="FileSet {" end="^}" contains=BacString,BacComment,BacName,BacFSInc,BacFSExc,BacFS2 syn region BacFSInc contained display start="Include {" end="}" contains=BacString,BacComment,BacFSOpt,BacFS1 syn region BacFSExc contained display start="Exclude {" end="}" contains=BacString,BacComment,BacFSOpt,BacFS1 syn region BacFSOpt contained display start="Options {" end="}" contains=BacString,BacComment,BacFSOpt1,BacFSOpt2 syn keyword BacFSOpt1 contained verify signature onefs noatime RegexFile Exclude Wild WildDir WildFile CheckChanges aclsupport syn match BacFSOpt2 contained /ignore case/ syn keyword BacFS1 contained File syn match BacFS2 contained /Enable VSS/ " Storage { syn region BacSto display start="Storage {" end="}" contains=BacName,BacComment,BacString,BacSto1,BacSto2 syn keyword BacSto1 contained Address SDPort Password Device Autochanger syn match BacSto2 contained /Media\s*Type/ " Director { syn region BacDir display start="Director {" end="}" contains=BacName,BacComment,BacString,BacDir,BacDir1,BacDir2 syn keyword BacDir1 contained DIRport QueryFile WorkingDirectory PidDirectory Password Messages syn match BacDir2 contained /Maximum\s*Concurrent\s*Jobs/ " Catalog { syn region BacCat display start="Catalog {" end="}" contains=BacName,BacComment,BacString,BacCat1 syn keyword BacCat1 contained dbname user password dbport " Job { syn region BacJob display start="Job {" end="^}" contains=BacJ1,BacJ2,BacString,BacComment,Level,BacC2,BacJ3,BacRun syn region BacJobDefs display start="JobDefs {" end="^}" contains=BacJ1,BacJ2,BacString,BacComment,Level,BacC2,BacJ3 syn region Level display start="Level =" end="$" contains=LevelElt syn keyword BacJ1 contained Schedule Name Priority Client Pool JobDefs FileSet SpoolData Storage where syn keyword BacJ2 contained RunBeforeJob RunAfterJob Type Messages ClientRunAfterJob syn match BacJ3 contained /Write Bootstrap/ " RunScript { syn region BacRun contained display start="RunScript {" end="}" contains=BacR1,BacR2,BacR3,BacR4,BacRW,BacString,BacComment syn match BacR1 contained /Runs\s*When/ syn match BacR2 contained /Runs\s*On\s*Client/ syn match BacR3 contained /Runs\s*On\s*Failure/ syn keyword BacR4 contained Command syn keyword BacRW contained After Before Always " Schedule { syn region BacSched display start="Schedule {" end="^}" contains=BacSR,BacString,BacComment,BacName,BacRun syn keyword BacS1 contained Pool FullPool on at syn keyword BacS2 contained sun mon tue wed thu fri sat sunday monday tuesday wednesday thursday friday saturday syn keyword BacS3 contained jan feb mar apr may jun jul aug sep oct nov dec syn keyword BacS4 contained 1st 2nd 3rd 4th 5th first second third fourth fifth syn region BacSR contained display start="Run = " end="$" contains=BacS1,BacS2,BacS3,BacS4,LevelElt syn keyword BacSpecial false true yes no " Pool syn region BacPool display start="Pool {" end="^}" contains=BacP1,BacP2,BacP3,BacString,BacComment syn match BacP1 contained /Pool\s*Type/ syn match BacP2 contained /Volume\s*Retention/ syn keyword BacP3 contained Name AutoPrune Recycle syn case match if version >= 508 || !exists("did_screen_syn_inits") if version < 508 let did_screen_syn_inits = 1 command -nargs=+ HiLink hi link else command -nargs=+ HiLink hi def link endif " Define the default highlighting. HiLink BacFileSet Function HiLink BacFSInc Function HiLink BacFSExc Function HiLink BacFSOpt Function HiLink BacFSOpt1 Keyword HiLink BacFSOpt2 Keyword HiLink BacFS1 Keyword HiLink BacFS2 Keyword HiLink BacInclude Include HiLink BacComment Comment HiLink BacComment2 Comment HiLink BacTodo Todo HiLink LevelElt String HiLink BacRun Function HiLink BacCat Function HiLink BacCat1 Keyword HiLink BacSto Function HiLink BacSto1 Keyword HiLink BacSto2 Keyword HiLink BacDir Function HiLink BacDir1 keyword HiLink BacDir2 keyword HiLink BacJob Function HiLink BacJobDefs Function HiLink BacJ1 Keyword HiLink BacJ2 Keyword HiLink BacJ3 Keyword HiLink BacClient Function HiLink BacC1 Keyword HiLink BacC2 Keyword HiLink BacC3 Keyword HiLink BacC4 Keyword HiLink Level Keyword HiLink BacSched Function HiLink BacS1 Keyword HiLink BacS2 String HiLink BacS3 String HiLink BacS4 String HiLink BacR1 Keyword HiLink BacR2 Keyword HiLink BacR3 Keyword HiLink BacR4 Keyword HiLink BacRW String HiLink BacPool Function HiLink BacP1 Keyword HiLink BacP2 Keyword HiLink BacP3 Keyword HiLink BacName Keyword HiLink BacString String HiLink BacNumber Number HiLink BacCommand BacCommands HiLink BacCommands Keyword HiLink BacSpecial Boolean HiLink BacKey Function HiLink Equal Comment delcommand HiLink endif bareos-Release-14.2.6/scripts/bat.console_apps.in000066400000000000000000000000731263011562700217110ustar00rootroot00000000000000USER=root PROGRAM=@sbindir@/bat SESSION=true FALLBACK=true bareos-Release-14.2.6/scripts/bat.pamd000066400000000000000000000004061263011562700175400ustar00rootroot00000000000000#%PAM-1.0 auth sufficient pam_rootok.so auth sufficient pam_timestamp.so auth required pam_stack.so service=system-auth session optional pam_xauth.so session optional pam_timestamp.so account required pam_permit.so bareos-Release-14.2.6/scripts/bconsole.in000077500000000000000000000007451263011562700202740ustar00rootroot00000000000000#!/bin/sh which dirname >/dev/null # does dirname exit? if [ $? = 0 ] ; then cwd=`dirname $0` if [ x$cwd = x. ]; then cwd=`pwd` fi if [ x$cwd = x@sbindir@ ] ; then echo "bconsole not properly installed." exit 1 fi fi if [ x@sbindir@ = x@sysconfdir@ ]; then echo "bconsole not properly installed." exit 1 fi if [ $# = 1 ] ; then echo "doing bconsole $1.conf" @sbindir@/bconsole -c $1.conf else @sbindir@/bconsole -c @sysconfdir@/bconsole.conf fi bareos-Release-14.2.6/scripts/breload000066400000000000000000000021531263011562700174630ustar00rootroot00000000000000#! /bin/sh # # breload This shell script takes care of reloading the director after # a backup of the configuration and a bareos-dir -t test # # BACDIRBIN=/sbin BACDIRCFG=/etc/bareos BACWORKDIR=/var/bareos/working BACBKPDIR=$BACWORKDIR/bkp Bareos="Bareos" DIR_USER= RET=0 if [ -x ${BACDIRBIN}/bareos-dir -a -r ${BACDIRCFG}/bareos-dir.conf ]; then echo "Testing the $Bareos Director daemon configuration" if [ $(whoami) != "$DIR_USER" ]; then USER_OPT="-u $DIR_USER" fi ${BACDIRBIN}/bareos-dir -t $USER_OPT -c ${BACDIRCFG}/bareos-dir.conf RET=$? if [ $RET = 0 ]; then if [ ! -d $BACBKPDIR ]; then echo "Creating Backup configuration directory" mkdir -p $BACBKPDIR chmod 700 $BACBKPDIR chown $DIR_USER $BACBKPDIR fi if [ -d $BACBKPDIR ]; then echo "Backup configuration" tar cfz $BACBKPDIR/bareos-dir-conf.$(date +%s).tgz $BACDIRCFG/*conf fi echo reload | ${BACDIRBIN}/bconsole >/dev/null echo "Reloading configuration" else echo "Can't reload configuration, please correct errors first" fi fi exit $RET bareos-Release-14.2.6/scripts/btraceback.dbx000066400000000000000000000020121263011562700207020ustar00rootroot00000000000000# btraceback.dbx dbxenv language_mode c++ echo "exename ==> \c"; print -l (char *)exename echo "exepath ==> \c"; print -l (char *)exepath echo "catalog_db ==> \c"; print -l (char *)catalog_db echo "version ==> \c"; print -l (char *)version echo "host_os ==> \c"; print -l (char *)host_os echo "distname ==> \c"; print -l (char *)distname echo "distver ==> \c"; print -l (char *)distver echo "dist_name ==> \c"; print -l (char *)dist_name echo "******** RUNNING THREADS/LWPS:" echo lwps echo echo echo "******** STACK TRACE OF CURRENT THREAD/LWP:" echo where echo echo echo "******** VARIABLES DUMP OF CURRENT THREAD/LWP:" echo dump for LWP in $(lwps | sh sed -e 's/.*@//' -e 's/ .*//'); do ( if lwp l@$LWP; then echo "******************************************" echo echo "******** STACK TRACE OF THREAD/LWP ${LWP}:" echo where echo echo "******** VARIABLES DUMP OF THREAD/LWP ${LWP}:" echo dump echo "******************************************" fi ) done quit bareos-Release-14.2.6/scripts/btraceback.gdb000066400000000000000000000005111263011562700206630ustar00rootroot00000000000000print my_name print exename print exepath print catalog_db print version print host_os print distname print distver print host_name print dist_name show env TestName bt thread apply all bt f 0 info locals f 1 info locals f 2 info locals f 3 info locals f 4 info locals f 5 info locals f 6 info locals f 7 info locals detach quit bareos-Release-14.2.6/scripts/btraceback.in000077500000000000000000000063521263011562700205510ustar00rootroot00000000000000#!/bin/sh # # Script to do a stack trace of a Bareos daemon/program # and create a core-file for postmortem debugging. # # We attempt to attach to running program # # Arguments to this script are # $1 = path to executable # $2 = main pid of running program to be traced back. # $3 = working directory # PNAME="`basename $1`" WD="$3" GCORE="@GCORE@" GDB="@GDB@" DBX="@DBX@" MDB="@MDB@" # # Try to generate a core dump for postmortem analyzing. # POSTMORTEM="NONE" if [ ! -z "${GCORE}" -a -x "${GCORE}" ]; then POSTMORTEM="${WD}/${PNAME}.core" ${GCORE} -o ${POSTMORTEM} $2 > /dev/null 2>&1 POSTMORTEM="${POSTMORTEM}.$2" echo "Created ${POSTMORTEM} for doing postmortem debugging" > ${WD}/bareos.$2.traceback else which gcore > /dev/null 2>&1 && GCORE="`which gcore`" || GCORE='' if [ ! -z "${GCORE}" -a -x "${GCORE}" ]; then POSTMORTEM="${WD}/${PNAME}.core" ${GCORE} -o ${POSTMORTEM} $2 > /dev/null 2>&1 POSTMORTEM="${POSTMORTEM}.$2" echo "Created ${POSTMORTEM} for doing postmortem debugging" > ${WD}/bareos.$2.traceback fi fi # # Try to find out what debugger is available on this platform. # if [ ! -z "${DBX}" -a -x "${DBX}" ]; then DEBUGGER="DBX" elif [ ! -z "${GDB}" -a -x "${GDB}" ]; then DEBUGGER="GDB" elif [ ! -z "${MDB}" -a -x "${MDB}" ]; then DEBUGGER="MDB" else # # If we fail to find the configured debugger do a last try to find it on the PATH. # which gdb > /dev/null 2>&1 && GDB="`which gdb`" || GDB='' which dbx > /dev/null 2>&1 && DBX="`which dbx`" || DBX='' which mdb > /dev/null 2>&1 && MDB="`which mdb`" || MDB='' if [ ! -z "${DBX}" -a -x "${DBX}" ]; then DEBUGGER="DBX" elif [ ! -z "${GDB}" -a -x "${GDB}" ]; then DEBUGGER="GDB" elif [ ! -z "${MDB}" -a -x "${MDB}" ]; then DEBUGGER="MDB" else DEBUGGER="NONE" fi fi # # Try to run a debugger on the crashing program or the generated postmortem dump for getting a strack trace. # case ${DEBUGGER} in DBX) if [ ${POSTMORTEM} != NONE -a -s ${POSTMORTEM} ]; then ${DBX} $1 ${POSTMORTEM} < @scriptdir@/btraceback.dbx >> ${WD}/bareos.$2.traceback 2>&1 else ${DBX} $1 $2 < @scriptdir@/btraceback.dbx >> ${WD}/bareos.$2.traceback 2>&1 fi ;; GDB) if [ ${POSTMORTEM} != NONE -a -s ${POSTMORTEM} ]; then ${GDB} -quiet -batch -x @scriptdir@/btraceback.gdb $1 ${POSTMORTEM} >> ${WD}/bareos.$2.traceback 2>&1 else ${GDB} -quiet -batch -x @scriptdir@/btraceback.gdb $1 $2 >> ${WD}/bareos.$2.traceback 2>&1 fi ;; MDB) if [ ${POSTMORTEM} != NONE -a -s ${POSTMORTEM} ]; then ${MDB} -u $1 ${POSTMORTEM} < @scriptdir@/btraceback.mdb >> ${WD}/bareos.$2.traceback 2>&1 else ${MDB} -u -p $2 < @scriptdir@/btraceback.mdb >> ${WD}/bareos.$2.traceback 2>&1 fi ;; NONE) echo "No debugger available on this platform," \ " please install one to get proper stack traces" >> ${WD}/bareos.$2.traceback ;; esac # # Send the stack trace info to someone for analyzing or at least letting someone know we crashed. # PNAME="${PNAME} on `hostname`" cat ${WD}/bareos.$2.traceback | \ @sbindir@/bsmtp -h @smtp_host@ -f @dump_email@ -s "Bareos ${DEBUGGER} traceback of ${PNAME}" @dump_email@ bareos-Release-14.2.6/scripts/btraceback.mdb000066400000000000000000000005271263011562700207000ustar00rootroot00000000000000# btraceback.mdb $G ::echo "******** RUNNING LWPS/THREADS:" ::echo ::walk thread ::echo ::echo ::echo "******** STACK TRACE OF CURRENT LWP:" ::echo $C ::echo ::echo ::echo "******** VARIABLES DUMP OF CURRENT LWP:" ::echo ::echo "******** STACK TRACE OF LWPS:" ::walk thread | ::findstack ::echo "******** VARIABLES DUMP OF LWPS:" ::quit bareos-Release-14.2.6/scripts/defaultconfig000077500000000000000000000012421263011562700206660ustar00rootroot00000000000000#!/bin/sh # # This is a default configuration file for Bareos that # sets reasonable defaults, and assumes that you do not # have MySQL running. It will "install" Bareos into # bin and etc in the current directory. # CFLAGS="-g -Wall" \ ./configure \ --sbindir=$HOME/bareos/bin \ --sysconfdir=$HOME/bareos/bin \ --with-pid-dir=$HOME/bareos/bin \ --with-subsys-dir=$HOME/bareos/bin \ --enable-smartalloc \ --enable-gnome \ --with-mysql=$HOME/mysql \ --with-working-dir=$HOME/bareos/bin/working \ --with-dump-email=root@localhost \ --with-job-email=root@localhost \ --with-smtp-host=localhost \ --with-baseport=9101 exit 0 bareos-Release-14.2.6/scripts/devel_bareos.in000066400000000000000000000136731263011562700211230ustar00rootroot00000000000000#! /bin/sh # # bareos This shell script takes care of starting and stopping # the bareos daemons. # # It runs with different ports than the production version, # and using the current development enviornment. # # This is pretty much watered down version of the RedHat script # that works on Solaris as well as Linux, but it won't work everywhere. # # description: Backup Archiving REcovery Open Sourced. # PSCMD="@PSCMD@" pwd=`pwd` BACDIRBIN=${pwd}/src/dird BACDIRCFG=${pwd}/src/dird BACFDBIN=${pwd}/src/filed BACFDCFG=${pwd}/src/filed BACSDBIN=${pwd}/src/stored BACSDCFG=${pwd}/src/stored PIDDIR=@piddir@ SUBSYSDIR=@subsysdir@ # Use non-production ports DIR_PORT=8101 FD_PORT=8102 SD_PORT=8103 DIR_USER=@dir_user@ DIR_GROUP=@dir_group@ FD_USER=@fd_user@ FD_GROUP=@fd_group@ SD_USER=@sd_user@ SD_GROUP=@sd_group@ # A function to stop a program. killproc() { RC=0 # Test syntax. if [ $# = 0 ]; then echo "Usage: killproc {program} [signal]" return 1 fi notset=0 # check for third arg to be kill level if [ "$3" != "" ] ; then killlevel=$3 else notset=1 killlevel="-9" fi # Get base program name base=`basename $1` # Find pid. pid=`pidofproc $base $2` # Kill it. if [ "$pid" != "" ] ; then if [ "$notset" = "1" ] ; then if ps -p $pid>/dev/null 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid 2>/dev/null sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 3 if ps -p $pid >/dev/null 2>&1 ; then kill -KILL $pid 2>/dev/null fi fi fi fi ps -p $pid >/dev/null 2>&1 RC=$? [ $RC -eq 0 ] && failure "$base shutdown" || success "$base shutdown" # RC=$((! $RC)) # use specified level only else if ps -p $pid >/dev/null 2>&1; then kill $killlevel $pid 2>/dev/null RC=$? [ $RC -eq 0 ] && success "$base $killlevel" || failure "$base $killlevel" fi fi else failure "$base shutdown" fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f ${PIDDIR}/$base.$2.pid fi return $RC } # A function to find the pid of a program. pidofproc() { pid="" # Test syntax. if [ $# = 0 ] ; then echo "Usage: pidofproc {program}" return 1 fi # Get base program name base=`basename $1` # First try PID file if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Next try "pidof" if [ -x /sbin/pidof ] ; then pid=`/sbin/pidof $1` fi if [ "$pid" != "" ] ; then echo $pid return 0 fi # Finally try to extract it from ps ${PSCMD} | grep $1 | awk '{ print $1 }' | tr '\n' ' ' return 0 } status() { # Test syntax. if [ $# = 0 ] ; then echo "Usage: status {program}" return 1 fi # Get base program name base=`basename $1` # First try "pidof" if [ -x /sbin/pidof ] ; then pid=`/sbin/pidof $1` fi if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 else pid=`${PSCMD} | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $2) || (("(" prog ")") == $2) || (("[" prog "]") == $2) || ((prog ":") == $2)) { print $1 ; exit 0 } }' $1` if [ "$pid" != "" ] ; then echo "$base (pid $pid) is running..." return 0 fi fi # Next try the PID files if [ -f ${PIDDIR}/$base.$2.pid ] ; then pid=`head -1 ${PIDDIR}/$base.$2.pid` if [ "$pid" != "" ] ; then echo "$base dead but pid file exists" return 1 fi fi # See if the subsys lock exists if [ -f ${SUBSYSDIR}/$base ] ; then echo "$base dead but subsys locked" return 2 fi echo "$base is stopped" return 3 } success() { return 0 } failure() { rc=$? return $rc } case "$1" in start) [ -x ${BACSDBIN}/bareos-sd ] && { echo "Starting the Storage daemon" OPTIONS='' if [ "${SD_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${SD_USER}" fi if [ "${SD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${SD_GROUP}" fi ${BACSDBIN}/bareos-sd $2 ${OPTIONS} -v -c ${BACSDCFG}/stored.conf } [ -x ${BACFDBIN}/bareos-fd ] && { echo "Starting the File daemon" OPTIONS='' if [ "${FD_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${FD_USER}" fi if [ "${FD_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${FD_GROUP}" fi ${BACFDBIN}/bareos-fd $2 ${OPTIONS} -v -c ${BACFDCFG}/filed.conf } [ -x ${BACDIRBIN}/bareos-dir ] && { sleep 2 echo "Starting the Director daemon" OPTIONS='' if [ "${DIR_USER}" != '' ]; then OPTIONS="${OPTIONS} -u ${DIR_USER}" fi if [ "${DIR_GROUP}" != '' ]; then OPTIONS="${OPTIONS} -g ${DIR_GROUP}" fi if [ "${VALGRIND}" != '' ]; then valgrind --leak-check=full ${BACDIRBIN}/bareos-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf else ${BACDIRBIN}/bareos-dir $2 ${OPTIONS} -v -c ${BACDIRCFG}/dird.conf fi } ;; stop) # Stop the FD first so that SD will fail jobs and update catalog [ -x ${BACFDBIN}/bareos-fd ] && { echo "Stopping the File daemon" killproc ${BACFDBIN}/bareos-fd ${FD_PORT} } [ -x ${BACSDBIN}/bareos-sd ] && { echo "Stopping the Storage daemon" killproc ${BACSDBIN}/bareos-sd ${SD_PORT} } [ -x ${BACDIRBIN}/bareos-dir ] && { echo "Stopping the Director daemon" killproc ${BACDIRBIN}/bareos-dir ${DIR_PORT} } echo ;; restart) $0 stop sleep 5 $0 start ;; status) [ -x ${BACSDBIN}/bareos-sd ] && status ${BACSDBIN}/bareos-sd ${SD_PORT} [ -x ${BACFDBIN}/bareos-fd ] && status ${BACFDBIN}/bareos-fd ${FD_PORT} [ -x ${BACDIRBIN}/bareos-dir ] && status ${BACDIRBIN}/bareos-dir ${DIR_PORT} ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 bareos-Release-14.2.6/scripts/disk-changer.in000066400000000000000000000245131263011562700210230ustar00rootroot00000000000000#!/bin/sh # # BAREOS interface to virtual autoloader using disk storage # # Written by Kern Sibbald # # Copyright (C) 2000-2010 Free Software Foundation Europe e.V. # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # If you set in your Device resource # # Changer Command = "path-to-this-script/disk-changer %c %o %S %a %d" # you will have the following input to this script: # # So Bareos will always call with all the following arguments, even though # in come cases, not all are used. Note, the Volume name is not always # included. # # disk-changer "changer-device" "command" "slot" "archive-device" "drive-index" "volume" # $1 $2 $3 $4 $5 $6 # # By default the autochanger has 10 Volumes and 1 Drive. # # Note: For this script to work, you *must" specify # Device Type = File # in each of the Devices associated with your AutoChanger resource. # # changer-device is the name of a file that overrides the default # volumes and drives. It may have: # maxslot=n where n is one based (default 10) # maxdrive=m where m is zero based (default 1 -- i.e. 2 drives) # # This code can also simulate barcodes. You simply put # a list of the slots and barcodes in the "base" directory/barcodes. # See below for the base directory definition. Example of a # barcodes file: # /var/bareos/barcodes # 1:Vol001 # 2:Vol002 # ... # # archive-device is the name of the base directory where you want the # Volumes stored appended with /drive0 for the first drive; /drive1 # for the second drive, ... For example, you might use # /var/bareos/drive0 Note: you must not have a trailing slash, and # the string (e.g. /drive0) must be unique, and it must not match # any other part of the directory name. These restrictions could be # easily removed by any clever script jockey. # # Full example: disk-changer /var/bareos/conf load 1 /var/bareos/drive0 0 TestVol001 # # The Volumes will be created with names slot1, slot2, slot3, ... maxslot in the # base directory. In the above example the base directory is /var/bareos. # However, as with tapes, their Bareos Volume names will be stored inside the # Volume label. In addition to the Volumes (e.g. /var/bareos/slot1, # /var/bareos/slot3, ...) this script will create a /var/bareos/loadedn # file to keep track of what Slot is loaded. You should not change this file. # # Modified 8 June 2010 to accept Volume names from the calling program as arg 6. # In this case, rather than storing the data in slotn, it is stored in the # Volume name. Note: for this to work, Volume names may not include spaces. # wd=@working_dir@ # # log whats done # # to turn on logging, uncomment the following line #touch $wd/disk-changer.log # dbgfile="$wd/disk-changer.log" debug() { if test -f $dbgfile; then echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile fi } # # Create a temporary file # make_temp_file() { TMPFILE=`mktemp -t mtx.XXXXXXXXXX` if test x${TMPFILE} = x; then TMPFILE="$wd/disk-changer.$$" if test -f ${TMPFILE}; then echo "Temp file security problem on: ${TMPFILE}" exit 1 fi fi } # check parameter count on commandline # check_parm_count() { pCount=$1 pCountNeed=$2 if test $pCount -lt $pCountNeed; then echo "usage: disk-changer ctl-device command [slot archive-device drive-index]" echo " Insufficient number of arguments arguments given." if test $pCount -lt 2; then echo " Mimimum usage is first two arguments ..." else echo " Command expected $pCountNeed arguments" fi exit 1 fi } # # Strip off the final name in order to get the Directory ($dir) # that we are dealing with. # get_dir() { bn=`basename $device` dir=`echo "$device" | sed -e s%/$bn%%g` if [ ! -d $dir ]; then echo "ERROR: Autochanger directory \"$dir\" does not exist." echo " You must create it." exit 1 fi } # # Get the Volume name from the call line, or directly from # the volslotn information. # get_vol() { havevol=0 debug "vol=$volume" if test "x$volume" != x && test "x$volume" != "x*NONE*" ; then debug "touching $dir/$volume" touch $dir/$volume echo "$volume" >$dir/volslot${slot} havevol=1 elif [ -f $dir/volslot${slot} ]; then volume=`cat $dir/volslot${slot}` havevol=1 fi } # Setup arguments ctl=$1 cmd="$2" slot=$3 device=$4 drive=$5 volume=$6 # set defaults maxdrive=1 maxslot=10 # Pull in conf file if [ -f $ctl ]; then . $ctl fi # Check for special cases where only 2 arguments are needed, # all others are a minimum of 5 # case $2 in list|listall) check_parm_count $# 2 ;; slots) check_parm_count $# 2 ;; transfer) check_parm_count $# 4 if [ $slot -gt $maxslot ]; then echo "Slot ($slot) out of range (1-$maxslot)" exit 1 fi ;; *) check_parm_count $# 5 if [ $drive -gt $maxdrive ]; then echo "Drive ($drive) out of range (0-$maxdrive)" exit 1 fi if [ $slot -gt $maxslot ]; then echo "Slot ($slot) out of range (1-$maxslot)" exit 1 fi ;; esac debug "Parms: $ctl $cmd $slot $device $drive $volume $havevol" case $cmd in unload) debug "Doing disk -f $ctl unload $slot $device $drive $volume" get_dir if [ -f $dir/loaded${drive} ]; then ld=`cat $dir/loaded${drive}` else echo "Storage Element $slot is Already Full" exit 1 fi if [ $slot -eq $ld ]; then echo "0" >$dir/loaded${drive} unlink $device 2>/dev/null >/dev/null rm -f $device else echo "Storage Element $slot is Already Full" exit 1 fi ;; load) debug "Doing disk $ctl load $slot $device $drive $volume" get_dir i=0 while [ $i -le $maxdrive ]; do if [ -f $dir/loaded${i} ]; then ld=`cat $dir/loaded${i}` else ld=0 fi if [ $ld -eq $slot ]; then echo "Drive ${i} Full (Storage element ${ld} loaded)" exit 1 fi i=`expr $i + 1` done # Check if we have a Volume name get_vol if [ $havevol -eq 0 ]; then # check if slot exists if [ ! -f $dir/slot${slot} ] ; then echo "source Element Address $slot is Empty" exit 1 fi fi if [ -f $dir/loaded${drive} ]; then ld=`cat $dir/loaded${drive}` else ld=0 fi if [ $ld -ne 0 ]; then echo "Drive ${drive} Full (Storage element ${ld} loaded)" exit 1 fi echo "0" >$dir/loaded${drive} unlink $device 2>/dev/null >/dev/null rm -f $device if [ $havevol -ne 0 ]; then ln -s $dir/$volume $device rtn=$? else ln -s $dir/slot${slot} $device rtn=$? fi if [ $rtn -eq 0 ]; then echo $slot >$dir/loaded${drive} fi exit $rtn ;; list) debug "Doing disk -f $ctl -- to list volumes" get_dir if [ -f $dir/barcodes ]; then cat $dir/barcodes else i=1 while [ $i -le $maxslot ]; do slot=$i volume= get_vol if [ $havevol -eq 0 ]; then echo "$i:" else echo "$i:$volume" fi i=`expr $i + 1` done fi exit 0 ;; listall) # ***FIXME*** must add new Volume stuff make_temp_file debug "Doing disk -f $ctl -- to list volumes" get_dir if [ ! -f $dir/barcodes ]; then exit 0 fi # we print drive content seen by autochanger # and we also remove loaded media from the barcode list i=0 while [ $i -le $maxdrive ]; do if [ -f $dir/loaded${i} ]; then ld=`cat $dir/loaded${i}` v=`awk -F: "/^$ld:/"' { print $2 }' $dir/barcodes` echo "D:$i:F:$ld:$v" echo "^$ld:" >> $TMPFILE fi i=`expr $i + 1` done # Empty slots are not in barcodes file # When we detect a gap, we print missing rows as empty # At the end, we fill the gap between the last entry and maxslot grep -v -f $TMPFILE $dir/barcodes | sort -n | \ perl -ne 'BEGIN { $cur=1 } if (/(\d+):(.+)?/) { if ($cur == $1) { print "S:$1:F:$2\n" } else { while ($cur < $1) { print "S:$cur:E\n"; $cur++; } } $cur++; } END { while ($cur < '"$maxslot"') { print "S:$cur:E\n"; $cur++; } } ' rm -f $TMPFILE exit 0 ;; transfer) # ***FIXME*** must add new Volume stuff get_dir make_temp_file slotdest=$device if [ -f $dir/slot{$slotdest} ]; then echo "destination Element Address $slot is Full" exit 1 fi if [ ! -f $dir/slot${slot} ] ; then echo "source Element Address $slot is Empty" exit 1 fi echo "Transfering $slot to $slotdest" mv $dir/slot${slot} $dir/slot{$slotdest} if [ -f $dir/barcodes ]; then sed "s/^$slot:/$slotdest:/" > $TMPFILE sort -n $TMPFILE > $dir/barcodes fi exit 0 ;; loaded) debug "Doing disk -f $ctl $drive -- to find what is loaded" get_dir if [ -f $dir/loaded${drive} ]; then cat $dir/loaded${drive} else echo "0" fi exit ;; slots) debug "Doing disk -f $ctl -- to get count of slots" echo $maxslot ;; esac bareos-Release-14.2.6/scripts/filetype.vim000066400000000000000000000002651263011562700204700ustar00rootroot00000000000000" put this file to $HOME/.vim if exists("have_load_filetypes") finish endif augroup filetypedetect au! BufRead,BufNewFile bareos-dir.conf setfiletype bareos augroup END bareos-Release-14.2.6/scripts/git-info.sh000077500000000000000000000021431263011562700202020ustar00rootroot00000000000000#!/bin/sh DESTDIR=${1:-"./"} GIT="git" which git >/dev/null 2>&1 if test $? != 0; then echo "skipped: git not available" exit 0 fi git status >/dev/null 2>&1 if test $? != 0; then echo "skipped: this directory isn't a git directory" exit 0 fi LANG=C git_branch_info() { #git rev-parse --abbrev-ref --symbolic-full-name @{upstream} > git/branch LOCAL_BRANCH=`git name-rev --name-only HEAD` TRACKING_BRANCH=`git config branch.$LOCAL_BRANCH.merge` TRACKING_REMOTE=`git config branch.$LOCAL_BRANCH.remote` # remove credentials from url REMOTE_URL=`git config remote.$TRACKING_REMOTE.url | sed -r "s|(http[s]://).*@|\1|"` printf "remote_url=$REMOTE_URL\n" # OBS return always "master" therefore disabled # (because OBS uses clone $GITURL + reset --hard $BRANCH) #printf "remote_branch=$TRACKING_BRANCH\n" RELEASE=`git describe --tags --match "Release/*" --always --abbrev=40` printf "release=$RELEASE\n" } git_branch_info > $DESTDIR/git-info DIFF=`$GIT diff --stat` [ "$DIFF" ] && printf "$DIFF" > $DESTDIR/git-diff $GIT log --stat > $DESTDIR/git-log bareos-Release-14.2.6/scripts/logrotate.in000066400000000000000000000005041263011562700204560ustar00rootroot00000000000000# # If you are appending to a log file (default), to # have your log file compressed, rotated, and after a time # deleted, after possibly editing the values below, # copy this file to: # # /etc/logrotate.d/bareos # @logdir@/bareos*.log { monthly rotate 6 notifempty missingok @logrotate_su@ } bareos-Release-14.2.6/scripts/logwatch/000077500000000000000000000000001263011562700177375ustar00rootroot00000000000000bareos-Release-14.2.6/scripts/logwatch/Makefile.in000066400000000000000000000007401263011562700220050ustar00rootroot00000000000000# Makefile to install logwatch script # 08 Jan 2005 D. Scott Barninger SYSCONFDIR=/etc/log.d INSTALL=@INSTALL@ all: install install: $(INSTALL) -m 755 bareos $(DESTDIR)$(SYSCONFDIR)/scripts/services/bareos $(INSTALL) -m 755 applybareosdate $(DESTDIR)$(SYSCONFDIR)/scripts/shared/applybareosdate $(INSTALL) -m 644 logfile.bareos.conf $(DESTDIR)$(SYSCONFDIR)/conf/logfiles/bareos.conf $(INSTALL) -m 644 services.bareos.conf $(DESTDIR)$(SYSCONFDIR)/conf/services/bareos.conf bareos-Release-14.2.6/scripts/logwatch/README000066400000000000000000000025621263011562700206240ustar00rootroot00000000000000Installation instructions for bareos logwatch script 04 Sep 2005 Installation into a standard logwatch configuration is fairly straightforward. Run 'make install' as root from this directory. For manual install copy the files as indicated below: cp -p scripts/logwatch/bareos /etc/log.d/scripts/services/bareos cp -p scripts/logwatch/applybareos /etc/log.d/scripts/shared/applybareosdate cp -p scripts/logwatch/logfile.bareos.conf /etc/log.d/conf/logfiles/bareos.conf cp -p scripts/logwatch/services.bareos.conf /etc/log.d/conf/services/bareos.conf chmod 755 /etc/log.d/scripts/services/bareos chmod 755 /etc/log.d/scripts/shared/applybareosdate chmod 644 /etc/log.d/conf/logfiles/bareos.conf chmod 644 /etc/log.d/conf/services/bareos.conf To test your installation run logwatch (as root): /etc/log.d/logwatch The following is the kind of output you could expect to be added to the standard logwatch listing: --------------------- bareos Begin ------------------------ Jobs Run: 2005-09-02 2012 backupNightlySave.2005-09-02_01.05.00 BackupOK 2005-09-02 2013 scottNightlySave.2005-09-02_01.05.01 BackupOK 2005-09-02 2014 marthaNightlySave.2005-09-02_01.05.02 BackupOK 2005-09-02 2015 lyndaNightlySave.2005-09-02_01.05.03 BackupOK 2005-09-02 2016 backupBackupCatalog.2005-09-02_01.10.00 BackupOK ---------------------- bareos End ------------------------- bareos-Release-14.2.6/scripts/logwatch/applybareosdate000066400000000000000000000026241263011562700230450ustar00rootroot00000000000000#!/usr/bin/perl ######################################################################## ## Copyright (c) 2009 Sigma Consulting Services Limited ## v1.00 2009/06/21 16:54:23 Ian McMichael ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## 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 . ######################################################################## use Logwatch ':dates'; my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; $SearchDate = TimeFilter('%d-%b %H:%M'); if ( $Debug > 5 ) { print STDERR "DEBUG: Inside ApplyBareosDate...\n"; print STDERR "DEBUG: Looking For: " . $SearchDate . "\n"; } my $OutputLine = 0; while (defined($ThisLine = )) { if ($ThisLine =~ m/^$SearchDate /o) { $OutputLine = 1; } elsif ($ThisLine !~ m/^\s+/o) { $OutputLine = 0; } if ($OutputLine) { print $ThisLine; } } # vi: shiftwidth=3 syntax=perl tabstop=3 et bareos-Release-14.2.6/scripts/logwatch/bareos000066400000000000000000000034461263011562700211440ustar00rootroot00000000000000#!/usr/bin/perl -w # # logwatch filter script for bareos log files # # Mon Jan 03 2005 # D. Scott Barninger and Karl Cunningham # # Copyright 2005-2006 Free Software Foundation Europe e.V. # licensed under GPL-v2 use strict; use POSIX qw(strftime); my (@JobName,$JobStatus,$ThisName,$ThisStatus,$ThisDate); my ($Job,$JobId,$JobDate,$Debug,$DebugCounter,%data); # set debug level $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; if ( $Debug >= 5 ) { print STDERR "\n\nDEBUG: Inside Bareos Filter \n\n"; $DebugCounter = 1; } while () { chomp; if ( $Debug >= 5 ) { print STDERR "DEBUG($DebugCounter): $_\n"; $DebugCounter++; } # Test the line for a new entry, which is a jobid record if (/^\s*JobId:\s+(\d+)/) { $JobId = $1; next; } (/^\s*Job:\s*(.*)/) and $Job = $1; (/^\s*Termination:\s*(.*)/) and $JobStatus = $1; (/^\s*Job:.*(\d{4}-\d{2}-\d{2})/) and $JobDate = $1; if ($JobId and $Job and $JobStatus and $JobDate) { $data{$JobId} = { "Job" => $Job, "JobStatus" => $JobStatus, "JobDate" => $JobDate, }; $JobId = $Job = $JobStatus = $JobDate = ""; } } # if we have data print it out, otherwise do nothing if (scalar(keys(%data))) { print "\nJobs Run:\n"; foreach my $Id (sort {$a<=>$b} (keys(%data))) { $ThisName = $data{$Id}{Job}; $ThisStatus = $data{$Id}{JobStatus}; $ThisDate = $data{$Id}{JobDate}; $ThisName =~ s/\s//g; $ThisStatus =~ s/\s//g; print "$ThisDate $Id $ThisName\n $ThisStatus\n\n"; } } exit(0); bareos-Release-14.2.6/scripts/logwatch/logfile.bareos.conf.in000066400000000000000000000001401263011562700241010ustar00rootroot00000000000000# What actual file? Defaults to LogPath if not absolute path.... LogFile = @logdir@/bareos.log bareos-Release-14.2.6/scripts/logwatch/services.bareos.conf000066400000000000000000000001201263011562700236740ustar00rootroot00000000000000Title = "bareos" # Which logfile group... LogFile = bareos *ApplyBareosDate = bareos-Release-14.2.6/scripts/magic.bareos000066400000000000000000000004521263011562700204050ustar00rootroot00000000000000### Old Bareos volume 12 string BB01 old Bareos volume data, >20 bedate x session time %s ### Current Bareos volume 12 string BB02 Bareos volume data, >20 bedate x session time %s, >24 belong -1 PRE_LABEL, >24 belong -2 VOL_LABEL, >>57 belong x version %d, >>93 string x name '%s' bareos-Release-14.2.6/scripts/magic.bareos.txt000066400000000000000000000010321263011562700212160ustar00rootroot00000000000000The file magic.bareos can be added to your system files so that the file command will recognize Bareos Volumes as such. If I understand this correctly, you add that to the database of "magic" that the command file uses. See 'man 1 file' and 'man 5 magic'. On my system, there are many ways to add to the magic. For testing, you'd add it to /etc/magic, usually. This is an interesting contribution that might also be relevant to the maintainers of magic, IMO. Explanation by: Arno magic.bareos submitted in bug #715 by "shattered". bareos-Release-14.2.6/scripts/mtx-changer.conf000066400000000000000000000027351263011562700212220ustar00rootroot00000000000000# # This file is sourced by the mtx-changer script every time it runs. # You can put your site customization here, and when you do an # upgrade, the process should not modify this file. Thus you # preserve your mtx-changer configuration. # # Set to 1 if you want to do offline before unload offline=0 # Set to amount of time in seconds to wait after an offline offline_sleep=0 # Set to amount of time in seconds to wait after a load load_sleep=0 # Set to 1 to do an inventory before a status. Not normally needed. inventory=0 # If you have a VXA PacketLoader, it might display a different # Storage Element line, so try setting the following to 1 vxa_packetloader=0 # Set to 1 if you want debug info written to a log debug_log=0 # mt status output # SunOS No Additional Sense # FreeBSD Current Driver State: at rest. # Linux ONLINE # Note Debian has a different mt than the standard Linux version. # When no tape is in the drive it waits 2 minutes. # When a tape is in the drive, it prints user unfriendly output. # Note, with Ubuntu Gusty (8.04), there are two versions of mt, # so we attempt to figure out which one. # OS=`uname` case ${OS} in SunOS) ready="No Additional Sense" ;; FreeBSD) ready="Current Driver State: at rest." ;; Linux) ready="ONLINE" if test -f /etc/debian_version ; then mt --version|grep "mt-st" >/dev/null 2>&1 if test $? -eq 1 ; then ready="drive status" fi fi ;; esac bareos-Release-14.2.6/scripts/mtx-changer.in000066400000000000000000000203431263011562700206760ustar00rootroot00000000000000#!/bin/sh # # Bareos interface to mtx autoloader # # If you set in your Device resource # # Changer Command = "path-to-this-script/mtx-changer %c %o %S %a %d" # you will have the following input to this script: # # So Bareos will always call with all the following arguments, even though # in come cases, not all are used. # # mtx-changer "changer-device" "command" "slot" "archive-device" "drive-index" # $1 $2 $3 $4 $5 # # for example: # # mtx-changer /dev/sg0 load 1 /dev/nst0 0 (on a Linux system) # # will request to load the first cartidge into drive 0, where # the SCSI control channel is /dev/sg0, and the read/write device # is /dev/nst0. # # The commands are: # Command Function # unload unload a given slot # load load a given slot # loaded which slot is loaded? # list list Volume names (requires barcode reader) # slots how many slots total? # listall list all info # transfer # # Slots are numbered from 1 ... # Drives are numbered from 0 ... # # # If you need to an offline, refer to the drive as $4 # e.g. mt -f $4 offline # # Many changers need an offline after the unload. Also many # changers need a sleep 60 after the mtx load. # # N.B. If you change the script, take care to return either # the mtx exit code or a 0. If the script exits with a non-zero # exit code, Bareos will assume the request failed. # # source our conf file if test ! -r @sysconfdir@/mtx-changer.conf ; then echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" echo "ERROR: @sysconfdir@/mtx-changer.conf file not found!!!!" echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" exit 1 fi . @sysconfdir@/mtx-changer.conf MTX=@MTX@ if test ! -x "$MTX" ; then echo "ERROR: mtx program not found ($MTX)" exit 1 fi dbgfile="@logdir@/mtx.log" if test ${debug_log} -ne 0 ; then touch $dbgfile fi debug() { if test -f $dbgfile; then echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile fi } # # Create a temporary file # make_temp_file() { TMPFILE=`mktemp @working_dir@/mtx.XXXXXXXXXX` if test x${TMPFILE} = x; then TMPFILE="@working_dir@/mtx.$$" if test -f ${TMPFILE}; then echo "ERROR: Temp file security problem on: ${TMPFILE}" exit 1 fi fi } # # Create a temporary file for stderr # # Note, this file is used because sometime mtx emits # unexpected error messages followed by the output # expected during success. # So we separate STDOUT and STDERR in # certain of the mtx commands. The contents of STDERR # is then printed after the STDOUT produced by mtx # thus we sometimes get better changer results. # make_err_file() { ERRFILE=`mktemp @working_dir@/mtx.err.XXXXXXXXXX` if test x${ERRFILE} = x; then ERRFILE="@working_dir@/mtx.err.$$" if test -f ${ERRFILE}; then echo "ERROR: Temp file security problem on: ${ERRFILE}" exit 1 fi fi } # # The purpose of this function to wait a maximum # time for the drive. It will # return as soon as the drive is ready, or after # waiting a maximum of 300 seconds. # Note, this is very system dependent, so if you are # not running on Linux, you will probably need to # re-write it, or at least change the grep target. # We've attempted to get the appropriate OS grep targets # in the code at the top of this script. # wait_for_drive() { i=0 while [ $i -le 300 ]; do # Wait max 300 seconds if mt -f $1 status 2>&1 | grep "${ready}" >/dev/null 2>&1; then break fi debug "Device $1 - not ready, retrying..." sleep 1 i=`expr $i + 1` done } # check parameter count on commandline # check_parm_count() { pCount=$1 pCountNeed=$2 if test $pCount -lt $pCountNeed; then echo "ERROR: usage: mtx-changer ctl-device command [slot archive-device drive-index]" echo " Insufficient number of arguments given." if test $pCount -lt 2; then echo " Mimimum usage is first two arguments ..." else echo " Command expected $pCountNeed arguments" fi exit 1 fi } # Check for special cases where only 2 arguments are needed, # all others are a minimum of 5 # case $2 in list|listall) check_parm_count $# 2 ;; slots) check_parm_count $# 2 ;; transfer) check_parm_count $# 4 ;; *) check_parm_count $# 5 ;; esac # Setup arguments ctl=$1 cmd="$2" slot=$3 device=$4 drive=$5 debug "Parms: $ctl $cmd $slot $device $drive" case $cmd in unload) debug "Doing mtx -f $ctl unload $slot $drive" if test ${offline} -eq 1 ; then mt -f $device offline fi if test ${offline_sleep} -ne 0 ; then sleep ${offline_sleep} fi make_err_file ${MTX} -f $ctl unload $slot $drive 2>${ERRFILE} rtn=$? cat ${ERRFILE} rm -f ${ERRFILE} >/dev/null 2>&1 exit $rtn ;; load) debug "Doing mtx -f $ctl load $slot $drive" make_err_file ${MTX} -f $ctl load $slot $drive 2>${ERRFILE} rtn=$? if test ${load_sleep} -ne 0 ; then sleep ${load_sleep} fi wait_for_drive $device cat ${ERRFILE} rm -f ${ERRFILE} >/dev/null 2>&1 exit $rtn ;; list) debug "Doing mtx -f $ctl -- to list volumes" make_temp_file if test ${inventory} -ne 0 ; then ${MTX} -f $ctl inventory fi ${MTX} -f $ctl status >${TMPFILE} rtn=$? if test ${vxa_packetloader} -ne 0 ; then cat ${TMPFILE} | grep " *Storage Element [0-9]*:.*Full" | sed "s/ Storage Element //" | sed "s/Full :VolumeTag=//" else cat ${TMPFILE} | grep " Storage Element [0-9]*:.*Full" | awk "{print \$3 \$4}" | sed "s/Full *\(:VolumeTag=\)*//" fi cat ${TMPFILE} | grep "^Data Transfer Element [0-9]*:Full (Storage Element [0-9]" | awk '{printf "%s:%s\n",$7,$10}' rm -f ${TMPFILE} >/dev/null 2>&1 exit $rtn ;; listall) # Drive content: D:Drive num:F:Slot loaded:Volume Name # D:0:F:2:vol2 or D:Drive num:E # D:1:F:42:vol42 # D:3:E # # Slot content: # S:1:F:vol1 S:Slot num:F:Volume Name # S:2:E or S:Slot num:E # S:3:F:vol4 # # Import/Export tray slots: # I:10:F:vol10 I:Slot num:F:Volume Name # I:11:E or I:Slot num:E # I:12:F:vol40 debug "Doing mtx -f $ctl -- to list all" make_temp_file if test ${inventory} -ne 0 ; then ${MTX} -f $ctl inventory fi ${MTX} -f $ctl status >${TMPFILE} rtn=$? # can be converted to awk+sed+cut, see below perl -ne ' /Data Transfer Element (\d+):Empty/ && print "D:$1:E\n"; /Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "D:$1:F:$2:$4\n"; /Storage Element (\d+):Empty/ && print "S:$1:E\n"; /Storage Element (\d+):Full( :VolumeTag=(.+))?/ && print "S:$1:F:$3\n"; /Storage Element (\d+) IMPORT.EXPORT:Empty/ && print "I:$1:E\n"; /Storage Element (\d+) IMPORT.EXPORT:Full( :VolumeTag=(.+))?/ && print "I:$1:F:$3\n";' ${TMPFILE} # If perl isn't installed, you can use by those commands #cat ${TMPFILE} | grep "Data Transfer Element" | awk "{print \"D:\"\$4 \$7 \$9 \$10}" | sed "s/=/:/" | sed "s/Full/F:/" | sed "s/Empty/E/" #cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep -v "IMPORT/EXPORT" | awk "{print \"S:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/" #cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep "IMPORT/EXPORT" | awk "{print \"I:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/" rm -f ${TMPFILE} >/dev/null 2>&1 exit $rtn ;; transfer) slotdest=$device debug "Doing transfer from $slot to $slotdest" ${MTX} -f $ctl transfer $slot $slotdest rtn=$? exit $rtn ;; loaded) debug "Doing mtx -f $ctl $drive -- to find what is loaded" make_temp_file ${MTX} -f $ctl status >${TMPFILE} rtn=$? cat ${TMPFILE} | grep "^Data Transfer Element $drive:Full" | awk "{print \$7}" cat ${TMPFILE} | grep "^Data Transfer Element $drive:Empty" | awk "{print 0}" rm -f ${TMPFILE} >/dev/null 2>&1 exit $rtn ;; slots) debug "Doing mtx -f $ctl -- to get count of slots" ${MTX} -f $ctl status | grep " *Storage Changer" | awk "{print \$5}" ;; esac bareos-Release-14.2.6/src/000077500000000000000000000000001263011562700152275ustar00rootroot00000000000000bareos-Release-14.2.6/src/.indent.pro000066400000000000000000000012471263011562700173140ustar00rootroot00000000000000--dont-format-comments --procnames-start-lines --parameter-indentation4 --indent-level4 --line-comments-indentation4 --cuddle-else --brace-indent0 --start-left-side-of-comments --no-blank-lines-after-commas --blank-lines-after-declarations --blank-lines-after-procedures --comment-indentation33 --declaration-comment-column33 --no-comment-delimiters-on-blank-lines --continuation-indentation4 --case-indentation0 --else-endif-column33 --no-space-after-casts --no-blank-before-sizeof --declaration-indentation16 --continue-at-parentheses --no-space-after-function-call-names --swallow-optional-blank-lines --space-special-semicolon --tab-size8 --line-length79 --braces-on-if-line bareos-Release-14.2.6/src/Makefile.in000066400000000000000000000015551263011562700173020ustar00rootroot00000000000000@MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = .. # this dir relative to top dir thisdir = src first_rule: all dummy: .PHONY: .DONTCARE: all: Makefile Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status clean: @$(RMF) core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 @$(RMF) AUTHORS ChangeLog Makefile.am NEWS README acconfig.h autogen.sh @$(RMF) configure.in stamp.h stamp-h.in @$(RMF) -r po realclean: clean @$(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi @(cd $(srcdir) && $(RMF) Makefile) @$(RMF) config.h host.h devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi @(cd $(srcdir) && $(RMF) Makefile) @$(RMF) config.h host.h install: depend: bareos-Release-14.2.6/src/cats/000077500000000000000000000000001263011562700161615ustar00rootroot00000000000000bareos-Release-14.2.6/src/cats/Makefile.in000066400000000000000000000310161263011562700202270ustar00rootroot00000000000000# @MCOMMON@ srcdir = . .PATH: . # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/cats DEFS += -D_BDB_PRIV_INTERFACE_ #CPPFLAGS += @DBI_DBD_DRIVERDIR@ DEBUG=@DEBUG@ MKDIR=$(topdir)/autoconf/mkinstalldirs first_rule: all dummy: # # include files installed when using libtool # INCLUDE_FILES = cats.h protos.h sql_cmds.h MYSQL_INCLUDE = @MYSQL_INCLUDE@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_SRCS = mysql.c MYSQL_OBJS = $(MYSQL_SRCS:.c=.o) MYSQL_LOBJS = $(MYSQL_SRCS:.c=.lo) POSTGRESQL_INCLUDE = @POSTGRESQL_INCLUDE@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_SRCS = postgresql.c POSTGRESQL_OBJS = $(POSTGRESQL_SRCS:.c=.o) POSTGRESQL_LOBJS = $(POSTGRESQL_SRCS:.c=.lo) SQLITE_INCLUDE = @SQLITE_INCLUDE@ SQLITE_LIBS = @SQLITE_LIBS@ SQLITE_SRCS = sqlite.c SQLITE_OBJS = $(SQLITE_SRCS:.c=.o) SQLITE_LOBJS = $(SQLITE_SRCS:.c=.lo) #INGRES_INCLUDE = @INGRES_INCLUDE@ #INGRES_LIBS = @INGRES_LIBS@ #INGRES_SRCS = ingres.c myingres.c #INGRES_OBJS = $(INGRES_SRCS:.c=.o) #INGRES_LOBJS = $(INGRES_SRCS:.c=.lo) #DBI_INCLUDE = @DBI_INCLUDE@ #DBI_LIBS = @DBI_LIBS@ #DBI_SRCS = dbi.c #DBI_OBJS = $(DBI_SRCS:.c=.o) #DBI_LOBJS = $(DBI_SRCS:.c=.lo) DB_LIBS=@DB_LIBS@ LIBBAREOSSQL_SRCS = bvfs.c cats.c sql.c sql_cmds.c sql_create.c sql_delete.c \ sql_find.c sql_get.c sql_glue.c sql_list.c sql_pooling.c \ sql_update.c LIBBAREOSSQL_OBJS = $(LIBBAREOSSQL_SRCS:.c=.o) LIBBAREOSSQL_LOBJS = $(LIBBAREOSSQL_SRCS:.c=.lo) LIBBAREOSSQL_LT_RELEASE = @LIBBAREOSSQL_LT_RELEASE@ LIBBAREOSCATS_SRCS = mysql.c postgresql.c sqlite.c LIBBAREOSCATS_DYN_SRCS = cats_backends.c LIBBAREOSCATS_OBJS = $(LIBBAREOSCATS_SRCS:.c=.o) LIBBAREOSCATS_LOBJS = $(LIBBAREOSCATS_DYN_SRCS:.c=.lo) LIBBAREOSCATS_LT_RELEASE = @LIBBAREOSCATS_LT_RELEASE@ INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .o .lo .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< .c.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< $(MYSQL_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(MYSQL_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) $(POSTGRESQL_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(POSTGRESQL_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) $(SQLITE_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(SQLITE_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) #$(DBI_LOBJS): # @echo "Compiling $(@:.lo=.c)" # $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DBI_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) #$(INGRES_LOBJS): # @echo "Compiling $(@:.lo=.c)" # $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(INGRES_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) $(MYSQL_OBJS): @echo "Compiling $(@:.o=.c)" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(MYSQL_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.o=.c) $(POSTGRESQL_OBJS): @echo "Compiling $(@:.o=.c)" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(POSTGRESQL_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.o=.c) $(SQLITE_OBJS): @echo "Compiling $(@:.o=.c)" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(SQLITE_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.o=.c) #$(INGRES_OBJS): # @echo "Compiling $(@:.o=.c)" # $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(INGRES_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.o=.c) #$(DBI_OBJS): # @echo "Compiling $(@:.o=.c)" # $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DBI_INCLUDE) $(DINCLUDE) $(CXXFLAGS) $(@:.o=.c) #------------------------------------------------------------------------- all: Makefile libbareoscats$(DEFAULT_ARCHIVE_TYPE) libbareossql$(DEFAULT_ARCHIVE_TYPE) @SHARED_CATALOG_TARGETS@ @echo "==== Make of sqllibs is good ====" @echo " " #esql: # @echo "Generating myingres.c from myingres.sc" # $(NO_ECHO)$(II_SYSTEM)/ingres/bin/esqlcc -multi -extension=c myingres.sc # @echo "Generating myingres.h from myingres.sh" # $(NO_ECHO)$(II_SYSTEM)/ingres/bin/esqlcc -extension=h myingres.sh libbareossql.a: $(LIBBAREOSSQL_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOSSQL_OBJS) $(RANLIB) $@ libbareoscats.a: $(LIBBAREOSCATS_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOSCATS_OBJS) $(RANLIB) $@ libbareoscats.la: Makefile $(LIBBAREOSCATS_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(LIBBAREOSCATS_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOSCATS_LT_RELEASE) -lbareos libbareossql.la: Makefile $(LIBBAREOSSQL_LOBJS) libbareoscats.la @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(LIBBAREOSSQL_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOSSQL_LT_RELEASE) $(DB_LIBS) -lbareos -lbareoscats libbareoscats-mysql.la: Makefile $(MYSQL_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(MYSQL_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSCATS_LT_RELEASE) \ -soname libbareoscats-$(LIBBAREOSCATS_LT_RELEASE).so $(MYSQL_LIBS) libbareoscats-postgresql.la: Makefile $(POSTGRESQL_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(POSTGRESQL_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSCATS_LT_RELEASE) \ -soname libbareoscats-$(LIBBAREOSCATS_LT_RELEASE).so $(POSTGRESQL_LIBS) libbareoscats-sqlite3.la: Makefile $(SQLITE_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(SQLITE_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSCATS_LT_RELEASE) \ -soname libbareoscats-$(LIBBAREOSCATS_LT_RELEASE).so $(SQLITE_LIBS) #libbareoscats-ingres.la: Makefile $(INGRES_LOBJS) # @echo "Making $@ ..." # $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(INGRES_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSCATS_LT_RELEASE) \ # -soname libbareoscats-$(LIBBAREOSCATS_LT_RELEASE).so $(INGRES_LIBS) #libbareoscats-dbi.la: Makefile $(DBI_LOBJS) # @echo "Making $@ ..." # $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(DBI_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSCATS_LT_RELEASE) \ # -soname libbareoscats-$(LIBBAREOSCATS_LT_RELEASE).so $(DBI_LIBS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) core a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 realclean: clean $(RMF) tags $(RMF) create_bareos_database update_bareos_tables make_bareos_tables $(RMF) grant_bareos_privileges drop_bareos_tables drop_bareos_database $(RMF) make_catalog_backup make_catalog_backup.pl delete_catalog_backup distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) install-includes: $(MKDIR) $(DESTDIR)/$(includedir)/bareos/sql for I in $(INCLUDE_FILES); do \ $(INSTALL_DATA) $$I $(DESTDIR)$(includedir)/bareos/sql/`basename $$I`; \ done libtool-install-default-backend: ./install-default-backend @DEFAULT_DB_TYPE@ $(LIBBAREOSCATS_LT_RELEASE) $(DESTDIR)$(libdir) libtool-install: all $(MKDIR) $(DESTDIR)$(libdir) $(RMF) $(DESTDIR)$(libdir)/libbareossql-[0-9]*.so $(DESTDIR)$(libdir)/libbareossql.la $(RMF) $(DESTDIR)$(libdir)/libbareoscats-[0-9]*.so $(DESTDIR)$(libdir)/libbareoscats.la $(RMF) $(DESTDIR)$(backenddir)/libbareoscats-*.so $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareoscats.la $(DESTDIR)$(libdir) $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareossql.la $(DESTDIR)$(libdir) $(MKDIR) $(DESTDIR)$(backenddir)/ for db_type in @DB_BACKENDS@; do \ $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareoscats-$${db_type}.la $(DESTDIR)$(backenddir); \ $(RM) $(DESTDIR)$(backenddir)/libbareoscats-$${db_type}.la; \ done install: @LIBTOOL_INSTALL_TARGET@ @LIBTOOL_INSTALL_DEFAULT_BACKEND_TARGET@ @INCLUDE_INSTALL_TARGET@ $(INSTALL_SCRIPT) create_bareos_database $(DESTDIR)$(scriptdir)/create_bareos_database $(INSTALL_SCRIPT) update_bareos_tables $(DESTDIR)$(scriptdir)/update_bareos_tables $(INSTALL_SCRIPT) make_bareos_tables $(DESTDIR)$(scriptdir)/make_bareos_tables $(INSTALL_SCRIPT) grant_bareos_privileges $(DESTDIR)$(scriptdir)/grant_bareos_privileges $(INSTALL_SCRIPT) drop_bareos_tables $(DESTDIR)$(scriptdir)/drop_bareos_tables $(INSTALL_SCRIPT) drop_bareos_database $(DESTDIR)$(scriptdir)/drop_bareos_database # # Make sure the DDL subdir exists. # @if test ! -d $(DESTDIR)$(scriptdir)/ddl; then \ $(MKDIR) $(DESTDIR)$(scriptdir)/ddl; \ fi; $(INSTALL_DATA) ddl/versions.map $(DESTDIR)$(scriptdir)/ddl/ # # Install all DDL schemas for Drop, Grant, Create and Update # @for db_type in @DB_BACKENDS@; do \ for dir in drops grants creates updates; do \ if test ! -d $(DESTDIR)$(scriptdir)/ddl/$$dir; then \ $(MKDIR) $(DESTDIR)$(scriptdir)/ddl/$$dir; \ fi; \ if test `ls -1 ddl/$$dir/$$db_type*.sql 2>/dev/null | wc -l` -gt 0; then \ $(INSTALL_DATA) ddl/$$dir/$$db_type*.sql $(DESTDIR)$(scriptdir)/ddl/$$dir; \ fi; \ done \ done @filename=make_catalog_backup.pl; \ if test -f $(DESTDIR)$(scriptdir)/$$filename; then \ destname=$$filename.new; \ echo " ==> Found existing $$filename, installing new file as $$destname"; \ else \ destname=$$filename; \ fi; \ echo "$(INSTALL_SCRIPT) $$filename $(DESTDIR)$(scriptdir)/$$destname"; \ $(INSTALL_SCRIPT) $$filename $(DESTDIR)$(scriptdir)/$$destname @filename=make_catalog_backup; \ if test -f $(DESTDIR)$(scriptdir)/$$filename; then \ destname=$$filename.new; \ echo " ==> Found existing $$filename, installing new file as $$destname"; \ else \ destname=$$filename; \ fi; \ echo "$(INSTALL_SCRIPT) $$filename $(DESTDIR)$(scriptdir)/$$destname"; \ $(INSTALL_SCRIPT) $$filename $(DESTDIR)$(scriptdir)/$$destname @filename=delete_catalog_backup; \ if test -f $(DESTDIR)$(scriptdir)/$$filename; then \ destname=$$filename.new; \ echo " ==> Found existing $$filename, installing new file as $$destname"; \ else \ destname=$$filename; \ fi; \ echo "$(INSTALL_SCRIPT) $$filename $(DESTDIR)$(scriptdir)/$$destname"; \ $(INSTALL_SCRIPT) $$filename $(DESTDIR)$(scriptdir)/$$destname # Semi-automatic generation of dependencies: # Use gcc -M because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. #depend: esql <- SRE: if generating from 'real' ingres source depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @for src in $(LIBBAREOSSQL_SRCS); do \ $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(DEFS) $(INCLUDES) $$src >> Makefile; \ done @for src in $(MYSQL_SRCS); do \ $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(DEFS) $(INCLUDES) $(MYSQL_INCLUDE) $$src >> Makefile; \ done @for src in $(POSTGRESQL_SRCS); do \ $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(DEFS) $(INCLUDES) $(POSTGRESQL_INCLUDE) $$src >> Makefile; \ done @for src in $(SQLITE_SRCS); do \ $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(DEFS) $(INCLUDES) $(SQLITE_INCLUDE) $$src >> Makefile; \ done # @for src in $(DBI_SRCS); do \ # $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(DEFS) $(INCLUDES) $(DBI_INCLUDE) $$src >> Makefile; \ # done @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/cats/bdb_dbi.h000066400000000000000000000052451263011562700177050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BDB_DBI_H_ #define __BDB_DBI_H_ 1 struct DBI_FIELD_GET { dlink link; char *value; }; class B_DB_DBI: public B_DB_PRIV { private: dbi_inst m_instance; dbi_conn *m_db_handle; dbi_result *m_result; DBI_FIELD_GET *m_field_get; public: B_DB_DBI(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool is_private); ~B_DB_DBI(); /* low level operations */ bool db_open_database(JCR *jcr); void db_close_database(JCR *jcr); bool db_validate_connection(void); void db_escape_string(JCR *jcr, char *snew, char *old, int len); char *db_escape_object(JCR *jcr, char *old, int len); void db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *len); void db_start_transaction(JCR *jcr); void db_end_transaction(JCR *jcr); bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); void sql_free_result(void); SQL_ROW sql_fetch_row(void); bool sql_query(const char *query, int flags=0); const char *sql_strerror(void); int sql_num_rows(void); void sql_data_seek(int row); int sql_affected_rows(void); uint64_t sql_insert_autokey_record(const char *query, const char *table_name); void sql_field_seek(int field); SQL_FIELD *sql_fetch_field(void); int sql_num_fields(void); bool sql_field_is_not_null(int field_type); bool sql_field_is_numeric(int field_type); bool sql_batch_start(JCR *jcr); bool sql_batch_end(JCR *jcr, const char *error); bool sql_batch_insert(JCR *jcr, ATTR_DBR *ar); }; #endif /* __BDB_DBI_H_ */ bareos-Release-14.2.6/src/cats/bdb_ingres.h000066400000000000000000000046571263011562700204440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BDB_INGRES_H_ #define __BDB_INGRES_H_ 1 class B_DB_INGRES: public B_DB_PRIV { private: INGconn *m_db_handle; INGresult *m_result; bool m_explicit_commit; int m_session_id; alist *m_query_filters; public: B_DB_INGRES(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool is_private); ~B_DB_INGRES(); /* low level operations */ bool db_open_database(JCR *jcr); void db_close_database(JCR *jcr); bool db_validate_connection(void); void db_start_transaction(JCR *jcr); void db_end_transaction(JCR *jcr); bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); void sql_free_result(void); SQL_ROW sql_fetch_row(void); bool sql_query(const char *query, int flags=0); const char *sql_strerror(void); int sql_num_rows(void); void sql_data_seek(int row); int sql_affected_rows(void); uint64_t sql_insert_autokey_record(const char *query, const char *table_name); void sql_field_seek(int field); SQL_FIELD *sql_fetch_field(void); int sql_num_fields(void); bool sql_field_is_not_null(int field_type); bool sql_field_is_numeric(int field_type); bool sql_batch_start(JCR *jcr); bool sql_batch_end(JCR *jcr, const char *error); bool sql_batch_insert(JCR *jcr, ATTR_DBR *ar); }; #endif /* __BDB_INGRES_H_ */ bareos-Release-14.2.6/src/cats/bdb_mysql.h000066400000000000000000000055231263011562700203130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BDB_MYSQL_H_ #define __BDB_MYSQL_H_ 1 /* * Number of insert statements to batch-up in batch insert * mode. We use multi-row inserts only in the batch mode * on the private database connection. */ #define MYSQL_CHANGES_PER_BATCH_INSERT 32 class B_DB_MYSQL: public B_DB_PRIV { private: MYSQL *m_db_handle; MYSQL m_instance; MYSQL_RES *m_result; public: B_DB_MYSQL(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool is_private); ~B_DB_MYSQL(); /* low level operations */ bool db_open_database(JCR *jcr); void db_close_database(JCR *jcr); bool db_validate_connection(void); void db_thread_cleanup(void); void db_escape_string(JCR *jcr, char *snew, char *old, int len); char *db_escape_object(JCR *jcr, char *old, int len); void db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *len); void db_start_transaction(JCR *jcr); void db_end_transaction(JCR *jcr); bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); void sql_free_result(void); SQL_ROW sql_fetch_row(void); bool sql_query(const char *query, int flags=0); const char *sql_strerror(void); int sql_num_rows(void); void sql_data_seek(int row); int sql_affected_rows(void); uint64_t sql_insert_autokey_record(const char *query, const char *table_name); void sql_field_seek(int field); SQL_FIELD *sql_fetch_field(void); int sql_num_fields(void); bool sql_field_is_not_null(int field_type); bool sql_field_is_numeric(int field_type); bool sql_batch_start(JCR *jcr); bool sql_batch_end(JCR *jcr, const char *error); bool sql_batch_insert(JCR *jcr, ATTR_DBR *ar); }; #endif /* __BDB_MYSQL_H_ */ bareos-Release-14.2.6/src/cats/bdb_postgresql.h000066400000000000000000000055101263011562700213450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BDB_POSTGRESQL_H_ #define __BDB_POSTGRESQL_H_ 1 class B_DB_POSTGRESQL: public B_DB_PRIV { private: PGconn *m_db_handle; PGresult *m_result; POOLMEM *m_buf; /* Buffer to manipulate queries */ public: B_DB_POSTGRESQL(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool is_private); ~B_DB_POSTGRESQL(); /* low level operations */ bool db_open_database(JCR *jcr); void db_close_database(JCR *jcr); bool db_validate_connection(void); void db_escape_string(JCR *jcr, char *snew, char *old, int len); char *db_escape_object(JCR *jcr, char *old, int len); void db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *len); void db_start_transaction(JCR *jcr); void db_end_transaction(JCR *jcr); bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); bool db_big_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); void sql_free_result(void); SQL_ROW sql_fetch_row(void); bool sql_query(const char *query, int flags=0); const char *sql_strerror(void); int sql_num_rows(void); void sql_data_seek(int row); int sql_affected_rows(void); uint64_t sql_insert_autokey_record(const char *query, const char *table_name); void sql_field_seek(int field); SQL_FIELD *sql_fetch_field(void); int sql_num_fields(void); bool sql_field_is_not_null(int field_type); bool sql_field_is_numeric(int field_type); bool sql_batch_start(JCR *jcr); bool sql_batch_end(JCR *jcr, const char *error); bool sql_batch_insert(JCR *jcr, ATTR_DBR *ar); }; #endif /* __BDB_POSTGRESQL_H_ */ bareos-Release-14.2.6/src/cats/bdb_priv.h000066400000000000000000000061051263011562700201230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BDB_PRIV_H_ #define __BDB_PRIV_H_ 1 #ifndef _BDB_PRIV_INTERFACE_ #error "Illegal inclusion of catalog private interface" #endif /* * Generic definition of a sql_row. */ typedef char ** SQL_ROW; /* * Generic definition of a a sql_field. */ typedef struct sql_field { char *name; /* name of column */ int max_length; /* max length */ uint32_t type; /* type */ uint32_t flags; /* flags */ } SQL_FIELD; class CATS_IMP_EXP B_DB_PRIV: public B_DB { protected: int m_status; /* status */ int m_num_rows; /* number of rows returned by last query */ int m_num_fields; /* number of fields returned by last query */ int m_rows_size; /* size of malloced rows */ int m_fields_size; /* size of malloced fields */ int m_row_number; /* row number from xx_data_seek */ int m_field_number; /* field number from sql_field_seek */ SQL_ROW m_rows; /* defined rows */ SQL_FIELD *m_fields; /* defined fields */ bool m_allow_transactions; /* transactions allowed */ bool m_transaction; /* transaction started */ public: /* methods */ B_DB_PRIV() {}; virtual ~B_DB_PRIV() {}; int sql_num_rows(void) { return m_num_rows; }; void sql_field_seek(int field) { m_field_number = field; }; int sql_num_fields(void) { return m_num_fields; }; virtual void sql_free_result(void) = 0; virtual SQL_ROW sql_fetch_row(void) = 0; virtual bool sql_query(const char *query, int flags=0) = 0; virtual const char *sql_strerror(void) = 0; virtual void sql_data_seek(int row) = 0; virtual int sql_affected_rows(void) = 0; virtual uint64_t sql_insert_autokey_record(const char *query, const char *table_name) = 0; virtual SQL_FIELD *sql_fetch_field(void) = 0; virtual bool sql_field_is_not_null(int field_type) = 0; virtual bool sql_field_is_numeric(int field_type) = 0; virtual bool sql_batch_start(JCR *jcr) = 0; virtual bool sql_batch_end(JCR *jcr, const char *error) = 0; virtual bool sql_batch_insert(JCR *jcr, ATTR_DBR *ar) = 0; }; #endif /* __BDB_PRIV_H_ */ bareos-Release-14.2.6/src/cats/bdb_sqlite.h000066400000000000000000000055231263011562700204470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BDB_SQLITE_H_ #define __BDB_SQLITE_H_ 1 class B_DB_SQLITE: public B_DB_PRIV { private: struct sqlite3 *m_db_handle; char **m_result; /* sql_store_results() and sql_query() */ char **m_col_names; /* used to access fields when using db_sql_query() */ char *m_lowlevel_errmsg; SQL_FIELD m_sql_field; /* used when using db_sql_query() and sql_fetch_field() */ public: B_DB_SQLITE(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool is_private); ~B_DB_SQLITE(); /* Used internaly by sqlite.c to access fields in db_sql_query() */ void set_column_names(char **res, int nb) { m_col_names = res; m_num_fields = nb; m_field_number = 0; } /* low level operations */ bool db_open_database(JCR *jcr); void db_close_database(JCR *jcr); bool db_validate_connection(void); void db_thread_cleanup(void); void db_start_transaction(JCR *jcr); void db_end_transaction(JCR *jcr); bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); void sql_free_result(void); SQL_ROW sql_fetch_row(void); bool sql_query(const char *query, int flags=0); const char *sql_strerror(void); int sql_num_rows(void); void sql_data_seek(int row); int sql_affected_rows(void); uint64_t sql_insert_autokey_record(const char *query, const char *table_name); void sql_field_seek(int field); SQL_FIELD *sql_fetch_field(void); int sql_num_fields(void); bool sql_field_is_not_null(int field_type); bool sql_field_is_numeric(int field_type); bool sql_batch_start(JCR *jcr); bool sql_batch_end(JCR *jcr, const char *error); bool sql_batch_insert(JCR *jcr, ATTR_DBR *ar); }; #endif /* __BDB_SQLITE_H_ */ bareos-Release-14.2.6/src/cats/bvfs.c000066400000000000000000000720051263011562700172710ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" #include "lib/htable.h" #include "bvfs.h" #define dbglevel 10 #define dbglevel_sql 15 static int result_handler(void *ctx, int fields, char **row) { if (fields == 4) { Pmsg4(0, "%s\t%s\t%s\t%s\n", row[0], row[1], row[2], row[3]); } else if (fields == 5) { Pmsg5(0, "%s\t%s\t%s\t%s\t%s\n", row[0], row[1], row[2], row[3], row[4]); } else if (fields == 6) { Pmsg6(0, "%s\t%s\t%s\t%s\t%s\t%s\n", row[0], row[1], row[2], row[3], row[4], row[5]); } else if (fields == 7) { Pmsg7(0, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", row[0], row[1], row[2], row[3], row[4], row[5], row[6]); } return 0; } Bvfs::Bvfs(JCR *j, B_DB *mdb) { jcr = j; jcr->inc_use_count(); db = mdb; /* need to inc ref count */ jobids = get_pool_memory(PM_NAME); prev_dir = get_pool_memory(PM_NAME); pattern = get_pool_memory(PM_NAME); *jobids = *prev_dir = *pattern = 0; dir_filenameid = pwd_id = offset = 0; see_copies = see_all_versions = false; limit = 1000; attr = new_attr(jcr); list_entries = result_handler; user_data = this; username = NULL; } Bvfs::~Bvfs() { free_pool_memory(jobids); free_pool_memory(pattern); free_pool_memory(prev_dir); if (username) { free(username); } free_attr(attr); jcr->dec_use_count(); } void Bvfs::filter_jobid() { if (!username) { return; } /* Query used by Bweb to filter clients, activated when using * set_username() */ POOL_MEM query; Mmsg(query, "SELECT DISTINCT JobId FROM Job JOIN Client USING (ClientId) " "JOIN (SELECT ClientId FROM client_group_member " "JOIN client_group USING (client_group_id) " "JOIN bweb_client_group_acl USING (client_group_id) " "JOIN bweb_user USING (userid) " "WHERE bweb_user.username = '%s' " ") AS filter USING (ClientId) " " WHERE JobId IN (%s)", username, jobids); db_list_ctx ctx; Dmsg1(dbglevel_sql, "q=%s\n", query.c_str()); db_sql_query(db, query.c_str(), db_list_handler, &ctx); pm_strcpy(jobids, ctx.list); } void Bvfs::set_jobid(JobId_t id) { Mmsg(jobids, "%lld", (uint64_t)id); filter_jobid(); } void Bvfs::set_jobids(char *ids) { pm_strcpy(jobids, ids); filter_jobid(); } /* * TODO: Find a way to let the user choose how he wants to display * files and directories */ /* * Working Object to store PathId already seen (avoid * database queries), equivalent to %cache_ppathid in perl */ #define NITEMS 50000 class pathid_cache { private: hlink *nodes; int nb_node; int max_node; alist *table_node; htable *cache_ppathid; public: pathid_cache() { hlink link; cache_ppathid = (htable *)malloc(sizeof(htable)); cache_ppathid->init(&link, &link, NITEMS); max_node = NITEMS; nodes = (hlink *) malloc(max_node * sizeof (hlink)); nb_node = 0; table_node = New(alist(5, owned_by_alist)); table_node->append(nodes); } hlink *get_hlink() { if (++nb_node >= max_node) { nb_node = 0; nodes = (hlink *)malloc(max_node * sizeof(hlink)); table_node->append(nodes); } return nodes + nb_node; } bool lookup(char *pathid) { return (cache_ppathid->lookup(pathid) != NULL); } void insert(char *pathid) { hlink *h = get_hlink(); cache_ppathid->insert(pathid, h); } ~pathid_cache() { cache_ppathid->destroy(); free(cache_ppathid); delete table_node; } private: pathid_cache(const pathid_cache &); /* prohibit pass by value */ pathid_cache &operator= (const pathid_cache &);/* prohibit class assignment*/ } ; /* Return the parent_dir with the trailing / (update the given string) * TODO: see in the rest of bareos if we don't have already this function * dir=/tmp/toto/ * dir=/tmp/ * dir=/ * dir= */ char *bvfs_parent_dir(char *path) { char *p = path; int len = strlen(path) - 1; /* windows directory / */ if (len == 2 && B_ISALPHA(path[0]) && path[1] == ':' && path[2] == '/') { len = 0; path[0] = '\0'; } if (len >= 0 && path[len] == '/') { /* if directory, skip last / */ path[len] = '\0'; } if (len > 0) { p += len; while (p > path && !IsPathSeparator(*p)) { p--; } p[1] = '\0'; } return path; } /* Return the basename of the with the trailing / * TODO: see in the rest of bareos if we don't have * this function already */ char *bvfs_basename_dir(char *path) { char *p = path; int len = strlen(path) - 1; if (path[len] == '/') { /* if directory, skip last / */ len -= 1; } if (len > 0) { p += len; while (p > path && !IsPathSeparator(*p)) { p--; } if (*p == '/') { p++; /* skip first / */ } } return p; } static void build_path_hierarchy(JCR *jcr, B_DB *mdb, pathid_cache &ppathid_cache, char *org_pathid, char *path) { Dmsg1(dbglevel, "build_path_hierarchy(%s)\n", path); char pathid[50]; ATTR_DBR parent; char *bkp = mdb->path; bstrncpy(pathid, org_pathid, sizeof(pathid)); /* Does the ppathid exist for this ? we use a memory cache... In order to * avoid the full loop, we consider that if a dir is allready in the * PathHierarchy table, then there is no need to calculate all the * hierarchy */ while (path && *path) { if (!ppathid_cache.lookup(pathid)) { Mmsg(mdb->cmd, "SELECT PPathId FROM PathHierarchy WHERE PathId = %s", pathid); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; /* Query failed, just leave */ } /* Do we have a result ? */ if (sql_num_rows(mdb) > 0) { ppathid_cache.insert(pathid); /* This dir was in the db ... * It means we can leave, the tree has allready been built for * this dir */ goto bail_out; } else { /* search or create parent PathId in Path table */ mdb->path = bvfs_parent_dir(path); mdb->pnl = strlen(mdb->path); if (!db_create_path_record(jcr, mdb, &parent)) { goto bail_out; } ppathid_cache.insert(pathid); Mmsg(mdb->cmd, "INSERT INTO PathHierarchy (PathId, PPathId) " "VALUES (%s,%lld)", pathid, (uint64_t) parent.PathId); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { goto bail_out; /* Can't insert the record, just leave */ } edit_uint64(parent.PathId, pathid); path = mdb->path; /* already done */ } } else { /* It's already in the cache. We can leave, no time to waste here, * all the parent dirs have allready been done */ goto bail_out; } } bail_out: mdb->path = bkp; mdb->fnl = 0; } /* * Internal function to update path_hierarchy cache with a shared pathid cache * return Error 0 * OK 1 */ static bool update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, pathid_cache &ppathid_cache, JobId_t JobId) { Dmsg0(dbglevel, "update_path_hierarchy_cache()\n"); bool retval = false; uint32_t num; char jobid[50]; edit_uint64(JobId, jobid); db_lock(mdb); db_start_transaction(jcr, mdb); Mmsg(mdb->cmd, "SELECT 1 FROM Job WHERE JobId = %s AND HasCache=1", jobid); if (!QUERY_DB(jcr, mdb, mdb->cmd) || sql_num_rows(mdb) > 0) { Dmsg1(dbglevel, "already computed %d\n", (uint32_t)JobId ); retval = true; goto bail_out; } /* Inserting path records for JobId */ Mmsg(mdb->cmd, "INSERT INTO PathVisibility (PathId, JobId) " "SELECT DISTINCT PathId, JobId " "FROM (SELECT PathId, JobId FROM File WHERE JobId = %s " "UNION " "SELECT PathId, BaseFiles.JobId " "FROM BaseFiles JOIN File AS F USING (FileId) " "WHERE BaseFiles.JobId = %s) AS B", jobid, jobid); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Dmsg1(dbglevel, "Can't fill PathVisibility %d\n", (uint32_t)JobId ); goto bail_out; } /* Now we have to do the directory recursion stuff to determine missing * visibility We try to avoid recursion, to be as fast as possible We also * only work on not allready hierarchised directories... */ Mmsg(mdb->cmd, "SELECT PathVisibility.PathId, Path " "FROM PathVisibility " "JOIN Path ON( PathVisibility.PathId = Path.PathId) " "LEFT JOIN PathHierarchy " "ON (PathVisibility.PathId = PathHierarchy.PathId) " "WHERE PathVisibility.JobId = %s " "AND PathHierarchy.PathId IS NULL " "ORDER BY Path", jobid); Dmsg1(dbglevel_sql, "q=%s\n", mdb->cmd); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Dmsg1(dbglevel, "Can't get new Path %d\n", (uint32_t)JobId ); goto bail_out; } /* TODO: I need to reuse the DB connection without emptying the result * So, now i'm copying the result in memory to be able to query the * catalog descriptor again. */ num = sql_num_rows(mdb); if (num > 0) { char **result = (char **)malloc (num * 2 * sizeof(char *)); SQL_ROW row; int i=0; while((row = sql_fetch_row(mdb))) { result[i++] = bstrdup(row[0]); result[i++] = bstrdup(row[1]); } i=0; while (num > 0) { build_path_hierarchy(jcr, mdb, ppathid_cache, result[i], result[i+1]); free(result[i++]); free(result[i++]); num--; } free(result); } if (mdb->db_get_type_index() == SQL_TYPE_SQLITE3) { Mmsg(mdb->cmd, "INSERT INTO PathVisibility (PathId, JobId) " "SELECT DISTINCT h.PPathId AS PathId, %s " "FROM PathHierarchy AS h " "WHERE h.PathId IN (SELECT PathId FROM PathVisibility WHERE JobId=%s) " "AND h.PPathId NOT IN (SELECT PathId FROM PathVisibility WHERE JobId=%s)", jobid, jobid, jobid ); } else { Mmsg(mdb->cmd, "INSERT INTO PathVisibility (PathId, JobId) " "SELECT a.PathId,%s " "FROM ( " "SELECT DISTINCT h.PPathId AS PathId " "FROM PathHierarchy AS h " "JOIN PathVisibility AS p ON (h.PathId=p.PathId) " "WHERE p.JobId=%s) AS a LEFT JOIN " "(SELECT PathId " "FROM PathVisibility " "WHERE JobId=%s) AS b ON (a.PathId = b.PathId) " "WHERE b.PathId IS NULL", jobid, jobid, jobid); } do { retval = QUERY_DB(jcr, mdb, mdb->cmd); } while (retval && sql_affected_rows(mdb) > 0); Mmsg(mdb->cmd, "UPDATE Job SET HasCache=1 WHERE JobId=%s", jobid); UPDATE_DB(jcr, mdb, mdb->cmd); bail_out: db_end_transaction(jcr, mdb); db_unlock(mdb); return retval; } /* * Find an store the filename descriptor for empty directories Filename.Name='' */ DBId_t Bvfs::get_dir_filenameid() { uint32_t id; if (dir_filenameid) { return dir_filenameid; } POOL_MEM q; Mmsg(q, "SELECT FilenameId FROM Filename WHERE Name = ''"); db_sql_query(db, q.c_str(), db_int_handler, &id); dir_filenameid = id; return dir_filenameid; } void bvfs_update_cache(JCR *jcr, B_DB *mdb) { uint32_t nb=0; db_list_ctx jobids_list; db_lock(mdb); #ifdef xxx /* TODO: Remove this code when updating make_bareos_table script */ Mmsg(mdb->cmd, "SELECT 1 FROM Job WHERE HasCache<>2 LIMIT 1"); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Dmsg0(dbglevel, "Creating cache table\n"); Mmsg(mdb->cmd, "ALTER TABLE Job ADD HasCache int DEFAULT 0"); QUERY_DB(jcr, mdb, mdb->cmd); Mmsg(mdb->cmd, "CREATE TABLE PathHierarchy ( " "PathId integer NOT NULL, " "PPathId integer NOT NULL, " "CONSTRAINT pathhierarchy_pkey " "PRIMARY KEY (PathId))"); QUERY_DB(jcr, mdb, mdb->cmd); Mmsg(mdb->cmd, "CREATE INDEX pathhierarchy_ppathid " "ON PathHierarchy (PPathId)"); QUERY_DB(jcr, mdb, mdb->cmd); Mmsg(mdb->cmd, "CREATE TABLE PathVisibility (" "PathId integer NOT NULL, " "JobId integer NOT NULL, " "Size int8 DEFAULT 0, " "Files int4 DEFAULT 0, " "CONSTRAINT pathvisibility_pkey " "PRIMARY KEY (JobId, PathId))"); QUERY_DB(jcr, mdb, mdb->cmd); Mmsg(mdb->cmd, "CREATE INDEX pathvisibility_jobid " "ON PathVisibility (JobId)"); QUERY_DB(jcr, mdb, mdb->cmd); } #endif Mmsg(mdb->cmd, "SELECT JobId from Job " "WHERE HasCache = 0 " "AND Type IN ('B') AND JobStatus IN ('T', 'W', 'f', 'A') " "ORDER BY JobId"); db_sql_query(mdb, mdb->cmd, db_list_handler, &jobids_list); bvfs_update_path_hierarchy_cache(jcr, mdb, jobids_list.list); db_start_transaction(jcr, mdb); Dmsg0(dbglevel, "Cleaning pathvisibility\n"); Mmsg(mdb->cmd, "DELETE FROM PathVisibility " "WHERE NOT EXISTS " "(SELECT 1 FROM Job WHERE JobId=PathVisibility.JobId)"); nb = DELETE_DB(jcr, mdb, mdb->cmd); Dmsg1(dbglevel, "Affected row(s) = %d\n", nb); db_end_transaction(jcr, mdb); db_unlock(mdb); } /* * Update the bvfs cache for given jobids (1,2,3,4) */ bool bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, char *jobids) { char *p; int status; JobId_t JobId; bool retval = false; pathid_cache ppathid_cache; p = jobids; while (1) { status = get_next_jobid_from_list(&p, &JobId); if (status < 0) { goto bail_out; } if (status == 0) { /* * We reached the end of the list. */ retval = true; goto bail_out; } Dmsg1(dbglevel, "Updating cache for %lld\n", (uint64_t)JobId); if (!update_path_hierarchy_cache(jcr, mdb, ppathid_cache, JobId)) { goto bail_out; } } bail_out: return retval; } /* * Update the bvfs cache for current jobids */ void Bvfs::update_cache() { bvfs_update_path_hierarchy_cache(jcr, db, jobids); } /* Change the current directory, returns true if the path exists */ bool Bvfs::ch_dir(const char *path) { pm_strcpy(db->path, path); db->pnl = strlen(db->path); db_lock(db); ch_dir(db_get_path_record(jcr, db)); db_unlock(db); return pwd_id != 0; } /* * Get all file versions for a specified client * TODO: Handle basejobs using different client */ void Bvfs::get_all_file_versions(DBId_t pathid, DBId_t fnid, const char *client) { Dmsg3(dbglevel, "get_all_file_versions(%lld, %lld, %s)\n", (uint64_t)pathid, (uint64_t)fnid, client); char ed1[50], ed2[50]; POOL_MEM q; if (see_copies) { Mmsg(q, " AND Job.Type IN ('C', 'B') "); } else { Mmsg(q, " AND Job.Type = 'B' "); } POOL_MEM query; Mmsg(query,// 1 2 3 "SELECT 'V', File.PathId, File.FilenameId, File.Md5, " // 4 5 6 "File.JobId, File.LStat, File.FileId, " // 7 8 "Media.VolumeName, Media.InChanger " "FROM File, Job, Client, JobMedia, Media " "WHERE File.FilenameId = %s " "AND File.PathId=%s " "AND File.JobId = Job.JobId " "AND Job.JobId = JobMedia.JobId " "AND File.FileIndex >= JobMedia.FirstIndex " "AND File.FileIndex <= JobMedia.LastIndex " "AND JobMedia.MediaId = Media.MediaId " "AND Job.ClientId = Client.ClientId " "AND Client.Name = '%s' " "%s ORDER BY FileId LIMIT %d OFFSET %d" ,edit_uint64(fnid, ed1), edit_uint64(pathid, ed2), client, q.c_str(), limit, offset); Dmsg1(dbglevel_sql, "q=%s\n", query.c_str()); db_sql_query(db, query.c_str(), list_entries, user_data); } DBId_t Bvfs::get_root() { int p; *db->path = 0; db_lock(db); p = db_get_path_record(jcr, db); db_unlock(db); return p; } static int path_handler(void *ctx, int fields, char **row) { Bvfs *fs = (Bvfs *) ctx; return fs->_handle_path(ctx, fields, row); } int Bvfs::_handle_path(void *ctx, int fields, char **row) { if (bvfs_is_dir(row)) { /* can have the same path 2 times */ if (!bstrcmp(row[BVFS_Name], prev_dir)) { pm_strcpy(prev_dir, row[BVFS_Name]); return list_entries(user_data, fields, row); } } return 0; } /* * Retrieve . and .. information */ void Bvfs::ls_special_dirs() { Dmsg1(dbglevel, "ls_special_dirs(%lld)\n", (uint64_t)pwd_id); char ed1[50], ed2[50]; if (*jobids == 0) { return; } if (!dir_filenameid) { get_dir_filenameid(); } /* Will fetch directories */ *prev_dir = 0; POOL_MEM query; Mmsg(query, "(SELECT PPathId AS PathId, '..' AS Path " "FROM PathHierarchy " "WHERE PathId = %s " "UNION " "SELECT %s AS PathId, '.' AS Path)", edit_uint64(pwd_id, ed1), ed1); POOL_MEM query2; Mmsg(query2,// 1 2 3 4 5 6 "SELECT 'D', tmp.PathId, 0, tmp.Path, JobId, LStat, FileId " "FROM %s AS tmp LEFT JOIN ( " // get attributes if any "SELECT File1.PathId AS PathId, File1.JobId AS JobId, " "File1.LStat AS LStat, File1.FileId AS FileId FROM File AS File1 " "WHERE File1.FilenameId = %s " "AND File1.JobId IN (%s)) AS listfile1 " "ON (tmp.PathId = listfile1.PathId) " "ORDER BY tmp.Path, JobId DESC ", query.c_str(), edit_uint64(dir_filenameid, ed2), jobids); Dmsg1(dbglevel_sql, "q=%s\n", query2.c_str()); db_sql_query(db, query2.c_str(), path_handler, this); } /* Returns true if we have dirs to read */ bool Bvfs::ls_dirs() { Dmsg1(dbglevel, "ls_dirs(%lld)\n", (uint64_t)pwd_id); char ed1[50], ed2[50]; if (*jobids == 0) { return false; } POOL_MEM query; POOL_MEM filter; if (*pattern) { Mmsg(filter, " AND Path2.Path %s '%s' ", match_query[db_get_type_index(db)], pattern); } if (!dir_filenameid) { get_dir_filenameid(); } /* the sql query displays same directory multiple time, take the first one */ *prev_dir = 0; /* Let's retrieve the list of the visible dirs in this dir ... * First, I need the empty filenameid to locate efficiently * the dirs in the file table * my $dir_filenameid = $self->get_dir_filenameid(); */ /* Then we get all the dir entries from File ... */ Mmsg(query, // 0 1 2 3 4 5 6 "SELECT 'D', PathId, 0, Path, JobId, LStat, FileId FROM ( " "SELECT Path1.PathId AS PathId, Path1.Path AS Path, " "lower(Path1.Path) AS lpath, " "listfile1.JobId AS JobId, listfile1.LStat AS LStat, " "listfile1.FileId AS FileId " "FROM ( " "SELECT DISTINCT PathHierarchy1.PathId AS PathId " "FROM PathHierarchy AS PathHierarchy1 " "JOIN Path AS Path2 " "ON (PathHierarchy1.PathId = Path2.PathId) " "JOIN PathVisibility AS PathVisibility1 " "ON (PathHierarchy1.PathId = PathVisibility1.PathId) " "WHERE PathHierarchy1.PPathId = %s " "AND PathVisibility1.JobId IN (%s) " "%s " ") AS listpath1 " "JOIN Path AS Path1 ON (listpath1.PathId = Path1.PathId) " "LEFT JOIN ( " /* get attributes if any */ "SELECT File1.PathId AS PathId, File1.JobId AS JobId, " "File1.LStat AS LStat, File1.FileId AS FileId FROM File AS File1 " "WHERE File1.FilenameId = %s " "AND File1.JobId IN (%s)) AS listfile1 " "ON (listpath1.PathId = listfile1.PathId) " ") AS A ORDER BY 2,3 DESC LIMIT %d OFFSET %d", edit_uint64(pwd_id, ed1), jobids, filter.c_str(), edit_uint64(dir_filenameid, ed2), jobids, limit, offset); Dmsg1(dbglevel_sql, "q=%s\n", query.c_str()); db_lock(db); db_sql_query(db, query.c_str(), path_handler, this); nb_record = sql_num_rows(db); db_unlock(db); return nb_record == limit; } void build_ls_files_query(B_DB *db, POOL_MEM &query, const char *JobId, const char *PathId, const char *filter, int64_t limit, int64_t offset) { if (db_get_type_index(db) == SQL_TYPE_POSTGRESQL) { Mmsg(query, sql_bvfs_list_files[db_get_type_index(db)], JobId, PathId, JobId, PathId, filter, limit, offset); } else { Mmsg(query, sql_bvfs_list_files[db_get_type_index(db)], JobId, PathId, JobId, PathId, limit, offset, filter, JobId, JobId); } } /* Returns true if we have files to read */ bool Bvfs::ls_files() { POOL_MEM query; POOL_MEM filter; char pathid[50]; Dmsg1(dbglevel, "ls_files(%lld)\n", (uint64_t)pwd_id); if (*jobids == 0) { return false; } if (!pwd_id) { ch_dir(get_root()); } edit_uint64(pwd_id, pathid); if (*pattern) { Mmsg(filter, " AND Filename.Name %s '%s' ", match_query[db_get_type_index(db)], pattern); } build_ls_files_query(db, query, jobids, pathid, filter.c_str(), limit, offset); Dmsg1(dbglevel_sql, "q=%s\n", query.c_str()); db_lock(db); db_sql_query(db, query.c_str(), list_entries, user_data); nb_record = sql_num_rows(db); db_unlock(db); return nb_record == limit; } /* * Return next Id from comma separated list * * Returns: * 1 if next Id returned * 0 if no more Ids are in list * -1 there is an error * TODO: merge with get_next_jobid_from_list() and get_next_dbid_from_list() */ static int get_next_id_from_list(char **p, int64_t *Id) { const int maxlen = 30; char id[maxlen+1]; char *q = *p; id[0] = 0; for (int i=0; isql_query(query, flags); if (!retval) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), query, ((B_DB_PRIV *)this)->sql_strerror()); } db_unlock(this); return retval; } void B_DB::print_lock_info(FILE *fp) { if (m_lock.valid == RWLOCK_VALID) { fprintf(fp, "\tRWLOCK=%p w_active=%i w_wait=%i\n", &m_lock, m_lock.w_active, m_lock.w_wait); } } /* * Escape strings so that database engine is happy. * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. */ void B_DB::db_escape_string(JCR *jcr, char *snew, char *old, int len) { char *n, *o; n = snew; o = old; while (len--) { switch (*o) { case '\'': *n++ = '\''; *n++ = '\''; o++; break; case 0: *n++ = '\\'; *n++ = 0; o++; break; default: *n++ = *o++; break; } } *n = 0; } /* * Escape binary object. * We base64 encode the data so its normal ASCII * Memory is stored in B_DB struct, no need to free it. */ char *B_DB::db_escape_object(JCR *jcr, char *old, int len) { int length; int max_length; max_length = (len * 4) / 3; esc_obj = check_pool_memory_size(esc_obj, max_length + 1); length = bin_to_base64(esc_obj, max_length, old, len, true); esc_obj[length] = '\0'; return esc_obj; } /* * Unescape binary object * We base64 encode the data so its normal ASCII */ void B_DB::db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *dest_len) { if (!from) { *dest[0] = '\0'; *dest_len = 0; return; } *dest = check_pool_memory_size(*dest, expected_len + 1); base64_to_bin(*dest, expected_len + 1, from, strlen(from)); *dest_len = expected_len; (*dest)[expected_len] = '\0'; } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/cats.h000066400000000000000000000641211263011562700172700ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Catalog header file * * by Kern E. Sibbald * * Anyone who accesses the database will need to include * this file. */ #ifndef __CATS_H_ #define __CATS_H_ 1 /* ============================================================== * * What follows are definitions that are used "globally" for all * the different SQL engines and both inside and external to the * cats directory. */ #define faddr_t long /* * Generic definitions of list types, list handlers and result handlers. */ enum e_list_type { NF_LIST, RAW_LIST, HORZ_LIST, VERT_LIST }; /* * Structure used when calling db_get_query_ids() * allows the subroutine to return a list of ids. */ class dbid_list : public SMARTALLOC { public: DBId_t *DBId; /* array of DBIds */ char *PurgedFiles; /* Array of PurgedFile flags */ int num_ids; /* num of ids actually stored */ int max_ids; /* size of id array */ int num_seen; /* number of ids processed */ int tot_ids; /* total to process */ dbid_list(); /* in sql.c */ ~dbid_list(); /* in sql.c */ }; /* Job information passed to create job record and update * job record at end of job. Note, although this record * contains all the fields found in the Job database record, * it also contains fields found in the JobMedia record. */ /* * Job record */ struct JOB_DBR { JobId_t JobId; char Job[MAX_NAME_LENGTH]; /* Job unique name */ char Name[MAX_NAME_LENGTH]; /* Job base name */ int JobType; /* actually char(1) */ int JobLevel; /* actually char(1) */ int JobStatus; /* actually char(1) */ DBId_t ClientId; /* Id of client */ DBId_t PoolId; /* Id of pool */ DBId_t FileSetId; /* Id of FileSet */ DBId_t PriorJobId; /* Id of migrated (prior) job */ time_t SchedTime; /* Time job scheduled */ time_t StartTime; /* Job start time */ time_t EndTime; /* Job termination time of orig job */ time_t RealEndTime; /* Job termination time of this job */ utime_t JobTDate; /* Backup time/date in seconds */ uint32_t VolSessionId; uint32_t VolSessionTime; uint32_t JobFiles; uint32_t JobErrors; uint32_t JobMissingFiles; uint64_t JobBytes; uint64_t ReadBytes; uint64_t JobSumTotalBytes; /* Total sum in bytes of all jobs but this one */ int PurgedFiles; int HasBase; /* Note, FirstIndex, LastIndex, Start/End File and Block * are only used in the JobMedia record. */ uint32_t FirstIndex; /* First index this Volume */ uint32_t LastIndex; /* Last index this Volume */ uint32_t StartFile; uint32_t EndFile; uint32_t StartBlock; uint32_t EndBlock; char cSchedTime[MAX_TIME_LENGTH]; char cStartTime[MAX_TIME_LENGTH]; char cEndTime[MAX_TIME_LENGTH]; char cRealEndTime[MAX_TIME_LENGTH]; /* * Extra stuff not in DB */ int limit; /* limit records to display */ faddr_t rec_addr; uint32_t FileIndex; /* added during Verify */ }; /* Job Media information used to create the media records * for each Volume used for the job. */ /* * JobMedia record */ struct JOBMEDIA_DBR { DBId_t JobMediaId; /* record id */ JobId_t JobId; /* JobId */ DBId_t MediaId; /* MediaId */ uint32_t FirstIndex; /* First index this Volume */ uint32_t LastIndex; /* Last index this Volume */ uint32_t StartFile; /* File for start of data */ uint32_t EndFile; /* End file on Volume */ uint32_t StartBlock; /* start block on tape */ uint32_t EndBlock; /* last block */ // uint32_t Copy; /* identical copy */ }; /* Volume Parameter structure */ struct VOL_PARAMS { char VolumeName[MAX_NAME_LENGTH]; /* Volume name */ char MediaType[MAX_NAME_LENGTH]; /* Media Type */ char Storage[MAX_NAME_LENGTH]; /* Storage name */ uint32_t VolIndex; /* Volume seqence no. */ uint32_t FirstIndex; /* First index this Volume */ uint32_t LastIndex; /* Last index this Volume */ int32_t Slot; /* Slot */ uint64_t StartAddr; /* Start address */ uint64_t EndAddr; /* End address */ int32_t InChanger; /* InChanger flag */ // uint32_t Copy; /* identical copy */ // uint32_t Stripe; /* RAIT strip number */ }; /* * Attributes record -- NOT same as in database because * in general, this "record" creates multiple database * records (e.g. pathname, filename, fileattributes). */ struct ATTR_DBR { char *fname; /* full path & filename */ char *link; /* link if any */ char *attr; /* attributes statp */ uint32_t FileIndex; uint32_t Stream; uint32_t FileType; uint32_t DeltaSeq; JobId_t JobId; DBId_t ClientId; DBId_t PathId; DBId_t FilenameId; FileId_t FileId; char *Digest; int DigestType; }; struct ROBJECT_DBR { char *object_name; char *object; char *plugin_name; uint32_t object_len; uint32_t object_full_len; uint32_t object_index; int32_t object_compression; uint32_t FileIndex; uint32_t Stream; uint32_t FileType; JobId_t JobId; DBId_t RestoreObjectId; }; /* * File record -- same format as database */ struct FILE_DBR { FileId_t FileId; uint32_t FileIndex; JobId_t JobId; DBId_t FilenameId; DBId_t PathId; JobId_t MarkId; uint32_t DeltaSeq; char LStat[256]; char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; int DigestType; /* NO_SIG/MD5_SIG/SHA1_SIG */ }; /* * Pool record -- same format as database */ struct POOL_DBR { DBId_t PoolId; char Name[MAX_NAME_LENGTH]; /* Pool name */ uint32_t NumVols; /* total number of volumes */ uint32_t MaxVols; /* max allowed volumes */ int32_t LabelType; /* BAREOS/ANSI/IBM */ int32_t UseOnce; /* set to use once only */ int32_t UseCatalog; /* set to use catalog */ int32_t AcceptAnyVolume; /* set to accept any volume sequence */ int32_t AutoPrune; /* set to prune automatically */ int32_t Recycle; /* default Vol recycle flag */ uint32_t ActionOnPurge; /* action on purge, e.g. truncate the disk volume */ utime_t VolRetention; /* retention period in seconds */ utime_t VolUseDuration; /* time in secs volume can be used */ uint32_t MaxVolJobs; /* Max Jobs on Volume */ uint32_t MaxVolFiles; /* Max files on Volume */ uint64_t MaxVolBytes; /* Max bytes on Volume */ DBId_t RecyclePoolId; /* RecyclePool destination when media is purged */ DBId_t ScratchPoolId; /* ScratchPool source when media is needed */ char PoolType[MAX_NAME_LENGTH]; char LabelFormat[MAX_NAME_LENGTH]; uint32_t MinBlocksize; /* Minimum Block Size */ uint32_t MaxBlocksize; /* Maximum Block Size */ /* * Extra stuff not in DB */ faddr_t rec_addr; }; struct DEVICE_DBR { DBId_t DeviceId; char Name[MAX_NAME_LENGTH]; /* Device name */ DBId_t MediaTypeId; /* MediaType */ DBId_t StorageId; /* Storage id if autochanger */ uint32_t DevMounts; /* Number of times mounted */ uint32_t DevErrors; /* Number of read/write errors */ uint64_t DevReadBytes; /* Number of bytes read */ uint64_t DevWriteBytes; /* Number of bytes written */ uint64_t DevReadTime; /* time spent reading volume */ uint64_t DevWriteTime; /* time spent writing volume */ uint64_t DevReadTimeSincCleaning; /* read time since cleaning */ uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */ time_t CleaningDate; /* time last cleaned */ utime_t CleaningPeriod; /* time between cleanings */ }; struct STORAGE_DBR { DBId_t StorageId; char Name[MAX_NAME_LENGTH]; /* Device name */ int AutoChanger; /* Set if autochanger */ /* * Extra stuff not in DB */ bool created; /* set if created by db_create ... */ }; struct MEDIATYPE_DBR { DBId_t MediaTypeId; char MediaType[MAX_NAME_LENGTH]; /* MediaType string */ int ReadOnly; /* Set if read-only */ }; /* * Media record -- same as the database */ struct MEDIA_DBR { DBId_t MediaId; /* Unique volume id */ char VolumeName[MAX_NAME_LENGTH]; /* Volume name */ char MediaType[MAX_NAME_LENGTH]; /* Media type */ char EncrKey[MAX_NAME_LENGTH]; /* Encryption Key */ DBId_t PoolId; /* Pool id */ time_t FirstWritten; /* Time Volume first written this usage */ time_t LastWritten; /* Time Volume last written */ time_t LabelDate; /* Date/Time Volume labeled */ time_t InitialWrite; /* Date/Time Volume first written */ int32_t LabelType; /* Label (BAREOS/ANSI/IBM) */ uint32_t VolJobs; /* number of jobs on this medium */ uint32_t VolFiles; /* Number of files */ uint32_t VolBlocks; /* Number of blocks */ uint32_t VolMounts; /* Number of times mounted */ uint32_t VolErrors; /* Number of read/write errors */ uint32_t VolWrites; /* Number of writes */ uint32_t VolReads; /* Number of reads */ uint64_t VolBytes; /* Number of bytes written */ uint64_t MaxVolBytes; /* Max bytes to write to Volume */ uint64_t VolCapacityBytes; /* capacity estimate */ uint64_t VolReadTime; /* time spent reading volume */ uint64_t VolWriteTime; /* time spent writing volume */ utime_t VolRetention; /* Volume retention in seconds */ utime_t VolUseDuration; /* time in secs volume can be used */ uint32_t ActionOnPurge; /* action on purge, e.g. truncate the disk volume */ uint32_t MaxVolJobs; /* Max Jobs on Volume */ uint32_t MaxVolFiles; /* Max files on Volume */ int32_t Recycle; /* recycle yes/no */ int32_t Slot; /* slot in changer */ int32_t Enabled; /* 0=disabled, 1=enabled, 2=archived */ int32_t InChanger; /* Volume currently in changer */ DBId_t StorageId; /* Storage record Id */ uint32_t EndFile; /* Last file on volume */ uint32_t EndBlock; /* Last block on volume */ uint32_t RecycleCount; /* Number of times recycled */ uint32_t MinBlocksize; /* Minimum Block Size */ uint32_t MaxBlocksize; /* Maximum Block Size */ char VolStatus[20]; /* Volume status */ DBId_t DeviceId; /* Device where Vol last written */ DBId_t LocationId; /* Where Volume is -- user defined */ DBId_t ScratchPoolId; /* Where to move if scratch */ DBId_t RecyclePoolId; /* Where to move when recycled */ /* * Extra stuff not in DB */ faddr_t rec_addr; /* found record address */ /* * Since the database returns times as strings, this is how we pass them back. */ char cFirstWritten[MAX_TIME_LENGTH]; /* FirstWritten returned from DB */ char cLastWritten[MAX_TIME_LENGTH]; /* LastWritten returned from DB */ char cLabelDate[MAX_TIME_LENGTH]; /* LabelData returned from DB */ char cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */ bool set_first_written; bool set_label_date; }; /* * Client record -- same as the database */ struct CLIENT_DBR { DBId_t ClientId; /* Unique Client id */ int AutoPrune; utime_t GraceTime; /* Time remaining on gracetime */ uint32_t QuotaLimit; /* The total softquota supplied if over grace */ utime_t FileRetention; utime_t JobRetention; char Name[MAX_NAME_LENGTH]; /* Client name */ char Uname[256]; /* Uname for client */ }; /* * Counter record -- same as in database */ struct COUNTER_DBR { char Counter[MAX_NAME_LENGTH]; int32_t MinValue; int32_t MaxValue; int32_t CurrentValue; char WrapCounter[MAX_NAME_LENGTH]; }; /* * FileSet record -- same as the database */ struct FILESET_DBR { DBId_t FileSetId; /* Unique FileSet id */ char FileSet[MAX_NAME_LENGTH]; /* FileSet name */ char MD5[50]; /* MD5 signature of include/exclude */ time_t CreateTime; /* date created */ /* * This is where we return CreateTime */ char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */ /* * Not in DB but returned by db_create_fileset() */ bool created; /* set when record newly created */ }; /* * Device Statistics record -- same as in database */ struct DEVICE_STATS_DBR { DBId_t DeviceId; /* Device record id */ time_t SampleTime; /* Timestamp statistic was captured */ uint64_t ReadTime; /* Time spent reading volume */ uint64_t WriteTime; /* Time spent writing volume */ uint64_t ReadBytes; /* Number of bytes read */ uint64_t WriteBytes; /* Number of bytes written */ uint64_t SpoolSize; /* Number of bytes spooled */ uint32_t NumWaiting; /* Number of Jobs waiting for device */ uint32_t NumWriters; /* Number of writers to device */ DBId_t MediaId; /* MediaId used */ uint64_t VolCatBytes; /* Volume Bytes */ uint64_t VolCatFiles; /* Volume Files */ uint64_t VolCatBlocks; /* Volume Blocks */ }; /* * TapeAlert record -- same as in database */ struct TAPEALERT_STATS_DBR { DBId_t DeviceId; /* Device record id */ time_t SampleTime; /* Timestamp statistic was captured */ uint64_t AlertFlags; /* Tape Alerts raised */ }; /* * Job Statistics record -- same as in database */ struct JOB_STATS_DBR { DBId_t DeviceId; /* Device record id */ time_t SampleTime; /* Timestamp statistic was captured */ JobId_t JobId; /* Job record id */ uint32_t JobFiles; /* Number of Files in Job */ uint64_t JobBytes; /* Number of Bytes in Job */ }; /* * Call back context for getting a 32/64 bit value from the database */ class db_int64_ctx { public: int64_t value; /* value returned */ int count; /* number of values seen */ db_int64_ctx() : value(0), count(0) {}; ~db_int64_ctx() {}; private: db_int64_ctx(const db_int64_ctx&); /* prohibit pass by value */ db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */ }; /* * Call back context for getting a list of comma separated strings from the database */ class db_list_ctx { public: POOLMEM *list; /* list */ int count; /* number of values seen */ db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); } ~db_list_ctx() { free_pool_memory(list); list = NULL; } void reset() { *list = 0; count = 0;} void add(const db_list_ctx &str) { if (str.count > 0) { if (*list) { pm_strcat(list, ","); } pm_strcat(list, str.list); count += str.count; } } void add(const char *str) { if (count > 0) { pm_strcat(list, ","); } pm_strcat(list, str); count++; } private: db_list_ctx(const db_list_ctx&); /* prohibit pass by value */ db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */ }; typedef enum { SQL_INTERFACE_TYPE_MYSQL = 0, SQL_INTERFACE_TYPE_POSTGRESQL = 1, SQL_INTERFACE_TYPE_SQLITE3 = 2, SQL_INTERFACE_TYPE_INGRES = 3, SQL_INTERFACE_TYPE_DBI = 4 } SQL_INTERFACETYPE; typedef enum { SQL_TYPE_MYSQL = 0, SQL_TYPE_POSTGRESQL = 1, SQL_TYPE_SQLITE3 = 2, SQL_TYPE_INGRES = 3, SQL_TYPE_UNKNOWN = 99 } SQL_DBTYPE; typedef void (DB_LIST_HANDLER)(void *, const char *); typedef int (DB_RESULT_HANDLER)(void *, int, char **); #define db_lock(mdb) mdb->_db_lock(__FILE__, __LINE__) #define db_unlock(mdb) mdb->_db_unlock(__FILE__, __LINE__) /* * Current database version number for all drivers */ #define BDB_VERSION 2003 class CATS_IMP_EXP B_DB: public SMARTALLOC { protected: brwlock_t m_lock; /* transaction lock */ dlink m_link; /* queue control */ SQL_INTERFACETYPE m_db_interface_type; /* type of backend used */ SQL_DBTYPE m_db_type; /* database type */ int m_ref_count; /* reference count */ bool m_connected; /* connection made to db */ bool m_have_batch_insert; /* have batch insert support ? */ char *m_db_driver; /* database driver */ char *m_db_driverdir; /* database driver dir */ char *m_db_name; /* database name */ char *m_db_user; /* database user */ char *m_db_address; /* host name address */ char *m_db_socket; /* socket for local access */ char *m_db_password; /* database password */ int m_db_port; /* port for host name address */ bool m_disabled_batch_insert; /* explicitly disabled batch insert mode ? */ bool m_is_private; /* private connection ? */ public: POOLMEM *errmsg; /* nicely edited error message */ POOLMEM *cmd; /* SQL command string */ POOLMEM *cached_path; /* cached path name */ int cached_path_len; /* length of cached path */ uint32_t cached_path_id; /* cached path id */ int changes; /* changes during transaction */ POOLMEM *fname; /* Filename only */ POOLMEM *path; /* Path only */ POOLMEM *esc_name; /* Escaped file name */ POOLMEM *esc_path; /* Escaped path name */ POOLMEM *esc_obj; /* Escaped restore object */ int fnl; /* file name length */ int pnl; /* path name length */ /* methods */ B_DB() {}; virtual ~B_DB() {}; const char *get_db_name(void) { return m_db_name; }; const char *get_db_user(void) { return m_db_user; }; bool is_connected(void) { return m_connected; }; bool batch_insert_available(void) { return m_have_batch_insert; }; bool is_private(void) { return m_is_private; }; void set_private(bool is_private) { m_is_private = is_private; }; void increment_refcount(void) { m_ref_count++; }; /* low level methods */ bool db_match_database(const char *db_driver, const char *db_name, const char *db_address, int db_port); B_DB *db_clone_database_connection(JCR *jcr, bool mult_db_connections, bool get_pooled_connection = true, bool need_private = false); int db_get_type_index(void) { return m_db_type; }; const char *db_get_type(void); void _db_lock(const char *file, int line); void _db_unlock(const char *file, int line); bool db_sql_query(const char *query, int flags=0); void print_lock_info(FILE *fp); /* Virtual low level methods */ virtual void db_thread_cleanup(void) {}; virtual void db_escape_string(JCR *jcr, char *snew, char *old, int len); virtual char *db_escape_object(JCR *jcr, char *old, int len); virtual void db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *len); /* Pure virtual low level methods */ virtual bool db_open_database(JCR *jcr) = 0; virtual void db_close_database(JCR *jcr) = 0; virtual bool db_validate_connection(void) = 0; virtual void db_start_transaction(JCR *jcr) = 0; virtual void db_end_transaction(JCR *jcr) = 0; virtual bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) = 0; /* By default, we use db_sql_query */ virtual bool db_big_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { return db_sql_query(query, result_handler, ctx); }; }; /* sql_query Query Flags */ #define QF_STORE_RESULT 0x01 /* flush the batch insert connection every x changes */ #define BATCH_FLUSH 800000 /* Use for better error location printing */ #define UPDATE_DB(jcr, db, cmd) UpdateDB(__FILE__, __LINE__, jcr, db, cmd, 1) #define UPDATE_DB_NO_AFR(jcr, db, cmd) UpdateDB(__FILE__, __LINE__, jcr, db, cmd, 0) #define INSERT_DB(jcr, db, cmd) InsertDB(__FILE__, __LINE__, jcr, db, cmd) #define QUERY_DB(jcr, db, cmd) QueryDB(__FILE__, __LINE__, jcr, db, cmd) #define DELETE_DB(jcr, db, cmd) DeleteDB(__FILE__, __LINE__, jcr, db, cmd) /* * Pooled backend connection. */ struct SQL_POOL_ENTRY { int id; /* Unique ID, connection numbering can have holes and the pool is not sorted on it */ int reference_count; /* Reference count for this entry */ time_t last_update; /* When was this connection last updated either used or put back on the pool */ B_DB *db_handle; /* Connection handle to the database */ dlink link; /* list management */ }; /* * Pooled backend list descriptor (one defined per backend defined in config) */ struct SQL_POOL_DESCRIPTOR { dlist *pool_entries; /* Linked list of all pool entries */ bool active; /* Is this an active pool, after a config reload an pool is made inactive */ time_t last_update; /* When was this pool last updated */ int min_connections; /* Minimum number of connections in the connection pool */ int max_connections; /* Maximum number of connections in the connection pool */ int increment_connections; /* Increase/Decrease the number of connection in the pool with this value */ int idle_timeout; /* Number of seconds to wait before tearing down a connection */ int validate_timeout; /* Number of seconds after which an idle connection should be validated */ int nr_connections; /* Number of active connections in the pool */ dlink link; /* list management */ }; #include "protos.h" #include "jcr.h" #include "sql_cmds.h" /* * Object used in db_list_xxx function */ class LIST_CTX { public: char line[256]; /* Used to print last dash line */ int32_t num_rows; e_list_type type; /* Vertical/Horizontal */ DB_LIST_HANDLER *send; /* send data back */ bool once; /* Used to print header one time */ void *ctx; /* send() user argument */ B_DB *mdb; JCR *jcr; void empty() { once = false; line[0] = '\0'; } void send_dashes() { if (*line) { send(ctx, line); } } LIST_CTX(JCR *j, B_DB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) { line[0] = '\0'; once = false; num_rows = 0; type = t; send = h; ctx = c; jcr = j; mdb = m; } }; /* * Some functions exported by sql.c for use within the cats directory. */ int list_result(void *vctx, int cols, char **row); int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type); void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx); int get_sql_record_max(JCR *jcr, B_DB *mdb); bool check_tables_version(JCR *jcr, B_DB *mdb); bool db_check_max_connections(JCR *jcr, B_DB *mdb, uint32_t nb); void print_dashes(B_DB *mdb); void print_result(B_DB *mdb); bool QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd); bool InsertDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd); int DeleteDB(const char *file, int line, JCR *jcr, B_DB *db, char *delete_cmd); bool UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update_cmd, int nr_afr); void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname); #endif /* __CATS_H_ */ bareos-Release-14.2.6/src/cats/cats_backends.c000066400000000000000000000244651263011562700211240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dynamic loading of catalog plugins. * * Marco van Wieringen, November 2010 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #if defined(HAVE_DYNAMIC_CATS_BACKENDS) #include "cats_backends.h" #include #ifndef RTLD_NOW #define RTLD_NOW 2 #endif /* * All loaded backends. */ static alist *loaded_backends = NULL; static alist *backend_dirs = NULL; void db_set_backend_dirs(alist *new_backend_dirs) { backend_dirs = new_backend_dirs; } static inline backend_interface_mapping_t *lookup_backend_interface_mapping(const char *interface_name) { backend_interface_mapping_t *backend_interface_mapping; for (backend_interface_mapping = backend_interface_mappings; backend_interface_mapping->interface_name != NULL; backend_interface_mapping++) { Dmsg3(100, "db_init_database: Trying to find mapping of given interfacename %s to mapping interfacename %s, partly_compare = %s\n", interface_name, backend_interface_mapping->interface_name, (backend_interface_mapping->partly_compare) ? "true" : "false"); /* * See if this is a match. */ if (backend_interface_mapping->partly_compare) { if (bstrncasecmp(interface_name, backend_interface_mapping->interface_name, strlen(backend_interface_mapping->interface_name))) { return backend_interface_mapping; } } else { if (bstrcasecmp(interface_name, backend_interface_mapping->interface_name)) { return backend_interface_mapping; } } } return NULL; } B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { struct stat st; char *backend_dir; void *dl_handle = NULL; POOL_MEM shared_library_name(PM_FNAME); backend_interface_mapping_t *backend_interface_mapping; backend_shared_library_t *backend_shared_library; t_backend_instantiate backend_instantiate; t_flush_backend flush_backend; /* * For dynamic loading catalog backends there must be a list of backend dirs set. */ if (!backend_dirs) { Jmsg(jcr, M_ABORT, 0, _("Catalog Backends Dir not configured.\n")); } /* * A db_driver is mandatory for dynamic loading of backends to work. */ if (!db_driver) { Jmsg(jcr, M_ABORT, 0, _("Driver type not specified in Catalog resource.\n")); } /* * If we didn't find a mapping its fatal because we don't know what database backend to use. */ backend_interface_mapping = lookup_backend_interface_mapping(db_driver); if (backend_interface_mapping == NULL) { Jmsg(jcr, M_ABORT, 0, _("Unknown database type: %s\n"), db_driver); return (B_DB *)NULL; } /* * See if the backend is already loaded. */ if (loaded_backends) { foreach_alist(backend_shared_library, loaded_backends) { if (backend_shared_library->interface_type_id == backend_interface_mapping->interface_type_id) { return backend_shared_library->backend_instantiate(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); } } } /* * This is a new backend try to use dynamic loading to load the backend library. */ foreach_alist(backend_dir, backend_dirs) { #ifndef HAVE_WIN32 Mmsg(shared_library_name, "%s/libbareoscats-%s%s", backend_dir, backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); Dmsg3(100, "db_init_database: testing backend %s/libbareoscats-%s%s\n", backend_dir, backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); /* * Make sure the shared library with this name exists. */ if (stat(shared_library_name.c_str(), &st) == 0) { #else Mmsg(shared_library_name, "libbareoscats-%s%s", backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); { #endif dl_handle = dlopen(shared_library_name.c_str(), RTLD_NOW); if (!dl_handle) { Jmsg(jcr, M_ERROR, 0, _("Unable to load shared library: %s ERR=%s\n"), shared_library_name.c_str(), NPRT(dlerror())); continue; } /* * Lookup the backend_instantiate function. */ backend_instantiate = (t_backend_instantiate)dlsym(dl_handle, "backend_instantiate"); if (backend_instantiate == NULL) { Jmsg(jcr, M_ERROR, 0, _("Lookup of backend_instantiate in shared library %s failed: ERR=%s\n"), shared_library_name.c_str(), NPRT(dlerror())); dlclose(dl_handle); dl_handle = NULL; continue; } /* * Lookup the flush_backend function. */ flush_backend = (t_flush_backend)dlsym(dl_handle, "flush_backend"); if (flush_backend == NULL) { Jmsg(jcr, M_ERROR, 0, _("Lookup of flush_backend in shared library %s failed: ERR=%s\n"), shared_library_name.c_str(), NPRT(dlerror())); dlclose(dl_handle); dl_handle = NULL; continue; } /* * We found the shared library and it has the right entry points. */ break; } } if (dl_handle) { /* * Create a new loaded shared library entry and tack it onto the list of loaded backend shared libs. */ backend_shared_library = (backend_shared_library_t *)malloc(sizeof(backend_shared_library_t)); backend_shared_library->interface_type_id = backend_interface_mapping->interface_type_id; backend_shared_library->handle = dl_handle; backend_shared_library->backend_instantiate = backend_instantiate; backend_shared_library->flush_backend = flush_backend; if (loaded_backends == NULL) { loaded_backends = New(alist(10, not_owned_by_alist)); } loaded_backends->append(backend_shared_library); Dmsg1(100, "db_init_database: loaded backend %s\n", shared_library_name.c_str() ); return backend_shared_library->backend_instantiate(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); } else { Jmsg(jcr, M_ABORT, 0, _("Unable to load any shared library for libbareoscats-%s%s\n"), backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); return (B_DB *)NULL; } } void db_flush_backends(void) { backend_shared_library_t *backend_shared_library; if (loaded_backends) { foreach_alist(backend_shared_library, loaded_backends) { /* * Call the flush entry point in the lib. */ backend_shared_library->flush_backend(); /* * Close the shared library and unload it. */ dlclose(backend_shared_library->handle); free(backend_shared_library); } delete loaded_backends; loaded_backends = NULL; } } #else /* * Dummy bareos backend function replaced with the correct one at install time. */ B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { Jmsg(jcr, M_FATAL, 0, _("Please replace this dummy libbareoscats library with a proper one.\n")); Dmsg0(0, _("Please replace this dummy libbareoscats library with a proper one.\n")); return NULL; } void db_flush_backends(void) { } #endif /* HAVE_DYNAMIC_CATS_BACKENDS */ #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/cats_backends.h000066400000000000000000000052421263011562700211210ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dynamic loading of catalog plugins. * * Marco van Wieringen, November 2010 */ #ifndef __CATS_BACKENDS_H_ #define __CATS_BACKENDS_H_ 1 extern "C" { typedef B_DB *(*t_backend_instantiate)(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private); typedef void (*t_flush_backend)(void); } /* * Loaded shared library with a certain backend interface type. */ struct backend_shared_library_t { int interface_type_id; void *handle; /* * Entry points into loaded shared library. */ t_backend_instantiate backend_instantiate; t_flush_backend flush_backend; }; #if defined(HAVE_WIN32) #define DYN_LIB_EXTENSION ".dll" #elif defined(HAVE_DARWIN_OS) #define DYN_LIB_EXTENSION ".dylib" #else #define DYN_LIB_EXTENSION ".so" #endif /* * Known backend to interface mappings. */ static struct backend_interface_mapping_t { const char *interface_name; bool partly_compare; int interface_type_id; } backend_interface_mappings[] = { { "dbi", TRUE, SQL_INTERFACE_TYPE_DBI }, { "mysql", FALSE, SQL_INTERFACE_TYPE_MYSQL }, { "postgresql", FALSE, SQL_INTERFACE_TYPE_POSTGRESQL }, { "sqlite3", FALSE, SQL_INTERFACE_TYPE_SQLITE3 }, { "ingres", FALSE, SQL_INTERFACE_TYPE_INGRES }, { NULL, FALSE, 0 } }; #endif /* __CATS_BACKENDS_H_ */ bareos-Release-14.2.6/src/cats/create_bareos_database.in000066400000000000000000000110671263011562700231400ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This routine makes the appropriately configured # Bareos database for PostgreSQL, Ingres, MySQL, or SQLite. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" dir_user=`get_user_dir` dir_group=`get_group_dir` default_db_type=`get_database_driver_default` working_dir=`get_working_dir` # # See if the first argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -gt 0 ]; then case $1 in sqlite3) db_type=$1 shift ;; mysql) db_type=$1 shift ;; postgresql) db_type=$1 shift ;; ingres) db_type=$1 shift ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi echo "Creating ${db_type} database" bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi case ${db_type} in sqlite3) sqlite3 $* ${working_dir}/${db_name}.db ".tables" # Allow non root access chown ${dir_user}:${dir_group} ${working_dir}/${db_name}.db chmod 0640 ${working_dir}/${db_name}.db retval=0 ;; mysql) mysql $* -e "CREATE DATABASE ${db_name};" retval=$? ;; postgresql) # # use SQL_ASCII to be able to put any filename into # the database even those created with unusual character sets PSQLVERSION=`psql -d template1 -c 'SELECT version()' $* 2>/dev/null | \ awk '/PostgreSQL/ { print $2 }' | \ cut -d '.' -f 1,2` if [ -z "${PSQLVERSION}" ]; then echo "Unable to determine PostgreSQL version." exit 1 fi # # Note, LC_COLLATE and LC_TYPE are needed on 8.4 and beyond, but are not implemented in 8.3 or below. # This must be updated for future versions of PostgreSQL # case ${PSQLVERSION} in 9.*) ENCODING="ENCODING 'SQL_ASCII' LC_COLLATE 'C' LC_CTYPE 'C'" ;; 8.[456789]) ENCODING="ENCODING 'SQL_ASCII' LC_COLLATE 'C' LC_CTYPE 'C'" ;; *) ENCODING="ENCODING 'SQL_ASCII'" ;; esac psql -f - -d template1 $* << END-OF-DATA \set ON_ERROR_STOP on CREATE DATABASE ${db_name} $ENCODING TEMPLATE template0; ALTER DATABASE ${db_name} SET datestyle TO 'ISO, YMD'; END-OF-DATA retval=$? if psql -l ${dbname} | grep " ${db_name}.*SQL_ASCII" >/dev/null; then echo "Database encoding OK" else echo " " echo "Database encoding bad. Do not use this database" echo " " fi ;; ingres) # # Use SQL_ASCII to be able to put any filename into # the database even those created with unusual character sets # ENCODING="ENCODING 'SQL_ASCII'" # # use UTF8 if you are using standard Unix/Linux LANG specifications # that use UTF8 -- this is normally the default and *should* be # your standard. Bareos works correctly *only* with correct UTF8. # # Note, with this encoding, if you have any "weird" filenames on # your system (names generated from Win32 or Mac OS), you may # get Bareos batch insert failures. # #ENCODING="ENCODING 'UTF8'" createdb -u${db_user} $* ${db_name} retval=$? ;; *) echo "Unknown database type $1" exit 1 ;; esac if [ "${retval}" = 0 ]; then echo "Creating of ${db_name} database succeeded." else echo "Creating of ${db_name} database failed." fi exit ${retval} bareos-Release-14.2.6/src/cats/dbi.c000066400000000000000000001231251263011562700170670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database routines specific to DBI * These are DBI specific routines * * João Henrique Freitas, December 2007 * based upon work done by Dan Langille, December 2003 and * by Kern Sibbald, March 2000 * * Major rewrite by Marco van Wieringen, January 2010 for catalog refactoring. */ /* * This code only compiles against a recent version of libdbi. The current * release found on the libdbi website (0.8.3) won't work for this code. * * You find the libdbi library on http://sourceforge.net/projects/libdbi * * A fairly recent version of libdbi from CVS works, so either make sure * your distribution has a fairly recent version of libdbi installed or * clone the CVS repositories from sourceforge and compile that code and * install it. * * You need: * cvs co :pserver:anonymous@libdbi.cvs.sourceforge.net:/cvsroot/libdbi * cvs co :pserver:anonymous@libdbi-drivers.cvs.sourceforge.net:/cvsroot/libdbi-drivers */ #include "bareos.h" #ifdef HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include #include #include /* ----------------------------------------------------------------------- * * DBI dependent defines and subroutines * * ----------------------------------------------------------------------- */ /* * List of open databases */ static dlist *db_list = NULL; /* * Control allocated fields by dbi_getvalue */ static dlist *dbi_getvalue_list = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; typedef int (*custom_function_insert_t)(void*, const char*, int); typedef char* (*custom_function_error_t)(void*); typedef int (*custom_function_end_t)(void*, const char*); B_DB_DBI::B_DB_DBI(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { char *p; char new_db_driver[10]; char db_driverdir[256]; DBI_FIELD_GET *field; p = (char *)(db_driver + 4); if (bstrcasecmp(p, "mysql")) { m_db_type = SQL_TYPE_MYSQL; bstrncpy(new_db_driver, "mysql", sizeof(new_db_driver)); } else if (bstrcasecmp(p, "postgresql")) { m_db_type = SQL_TYPE_POSTGRESQL; bstrncpy(new_db_driver, "pgsql", sizeof(new_db_driver)); } else if (bstrcasecmp(p, "sqlite3")) { m_db_type = SQL_TYPE_SQLITE3; bstrncpy(new_db_driver, "sqlite3", sizeof(new_db_driver)); } else if (bstrcasecmp(p, "ingres")) { m_db_type = SQL_TYPE_INGRES; bstrncpy(new_db_driver, "ingres", sizeof(new_db_driver)); } else { Jmsg(jcr, M_ABORT, 0, _("Unknown database type: %s\n"), p); return; } /* * Set db_driverdir whereis is the libdbi drivers */ bstrncpy(db_driverdir, DBI_DRIVER_DIR, 255); /* * Initialize the parent class members. */ m_db_interface_type = SQL_INTERFACE_TYPE_DBI; m_db_name = bstrdup(db_name); m_db_user = bstrdup(db_user); if (db_password) { m_db_password = bstrdup(db_password); } if (db_address) { m_db_address = bstrdup(db_address); } if (db_socket) { m_db_socket = bstrdup(db_socket); } if (db_driverdir) { m_db_driverdir = bstrdup(db_driverdir); } m_db_driver = bstrdup(new_db_driver); m_db_port = db_port; if (disable_batch_insert) { m_disabled_batch_insert = true; m_have_batch_insert = false; } else { m_disabled_batch_insert = false; #if defined(USE_BATCH_FILE_INSERT) #ifdef HAVE_DBI_BATCH_FILE_INSERT m_have_batch_insert = true; #else m_have_batch_insert = false; #endif /* HAVE_DBI_BATCH_FILE_INSERT */ #else m_have_batch_insert = false; #endif /* USE_BATCH_FILE_INSERT */ } errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */ *errmsg = 0; cmd = get_pool_memory(PM_EMSG); /* get command buffer */ cached_path = get_pool_memory(PM_FNAME); cached_path_id = 0; m_ref_count = 1; fname = get_pool_memory(PM_FNAME); path = get_pool_memory(PM_FNAME); esc_name = get_pool_memory(PM_FNAME); esc_path = get_pool_memory(PM_FNAME); esc_obj = get_pool_memory(PM_FNAME); m_allow_transactions = mult_db_connections; m_is_private = need_private; /* * Initialize the private members. */ m_db_handle = NULL; m_result = NULL; m_field_get = NULL; /* * Put the db in the list. */ if (db_list == NULL) { db_list = New(dlist(this, &this->m_link)); dbi_getvalue_list = New(dlist(field, &field->link)); } db_list->append(this); } B_DB_DBI::~B_DB_DBI() { } /* * Now actually open the database. This can generate errors, * which are returned in the errmsg * * DO NOT close the database or delete mdb here !!!! */ bool B_DB_DBI::db_open_database(JCR *jcr) { bool retval = false; int errstat; int dbstat; uint8_t len; const char *dbi_errmsg; char buf[10], *port; int numdrivers; char *new_db_name = NULL; char *new_db_dir = NULL; P(mutex); if (m_connected) { retval = true; goto bail_out; } if ((errstat=rwl_init(&m_lock)) != 0) { berrno be; Mmsg1(&errmsg, _("Unable to initialize DB lock. ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } if (m_db_port) { bsnprintf(buf, sizeof(buf), "%d", m_db_port); port = buf; } else { port = NULL; } numdrivers = dbi_initialize_r(m_db_driverdir, &(m_instance)); if (numdrivers < 0) { Mmsg2(&errmsg, _("Unable to locate the DBD drivers to DBI interface in: \n" "db_driverdir=%s. It is probaly not found any drivers\n"), m_db_driverdir,numdrivers); goto bail_out; } m_db_handle = (void **)dbi_conn_new_r(m_db_driver, m_instance); /* * Can be many types of databases */ switch (m_db_type) { case SQL_TYPE_MYSQL: dbi_conn_set_option(m_db_handle, "host", m_db_address); /* default = localhost */ dbi_conn_set_option(m_db_handle, "port", port); /* default port */ dbi_conn_set_option(m_db_handle, "username", m_db_user); /* login name */ dbi_conn_set_option(m_db_handle, "password", m_db_password); /* password */ dbi_conn_set_option(m_db_handle, "dbname", m_db_name); /* database name */ break; case SQL_TYPE_POSTGRESQL: dbi_conn_set_option(m_db_handle, "host", m_db_address); dbi_conn_set_option(m_db_handle, "port", port); dbi_conn_set_option(m_db_handle, "username", m_db_user); dbi_conn_set_option(m_db_handle, "password", m_db_password); dbi_conn_set_option(m_db_handle, "dbname", m_db_name); break; case SQL_TYPE_SQLITE3: len = strlen(working_directory) + 5; new_db_dir = (char *)malloc(len); strcpy(new_db_dir, working_directory); strcat(new_db_dir, "/"); len = strlen(m_db_name) + 5; new_db_name = (char *)malloc(len); strcpy(new_db_name, m_db_name); strcat(new_db_name, ".db"); dbi_conn_set_option(m_db_handle, "sqlite3_dbdir", new_db_dir); dbi_conn_set_option(m_db_handle, "dbname", new_db_name); Dmsg2(500, "SQLITE: %s %s\n", new_db_dir, new_db_name); free(new_db_dir); free(new_db_name); break; } /* * If connection fails, try at 5 sec intervals for 30 seconds. */ for (int retry=0; retry < 6; retry++) { dbstat = dbi_conn_connect(m_db_handle); if (dbstat == 0) { break; } dbi_conn_error(m_db_handle, &dbi_errmsg); Dmsg1(50, "dbi error: %s\n", dbi_errmsg); bmicrosleep(5, 0); } if (dbstat != 0 ) { Mmsg3(&errmsg, _("Unable to connect to DBI interface. Type=%s Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections exceeded.\n"), m_db_driver, m_db_name, m_db_user); goto bail_out; } Dmsg0(50, "dbi_real_connect done\n"); Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", m_db_user, m_db_name, (m_db_password == NULL) ? "(NULL)" : m_db_password); m_connected = true; if (!check_tables_version(jcr, this)) { goto bail_out; } switch (m_db_type) { case SQL_TYPE_MYSQL: /* * Set connection timeout to 8 days specialy for batch mode */ sql_query("SET wait_timeout=691200"); sql_query("SET interactive_timeout=691200"); break; case SQL_TYPE_POSTGRESQL: /* * Tell PostgreSQL we are using standard conforming strings * and avoid warnings such as: * WARNING: nonstandard use of \\ in a string literal */ sql_query("SET datestyle TO 'ISO, YMD'"); sql_query("SET standard_conforming_strings=on"); break; } retval = true; bail_out: V(mutex); return retval; } void B_DB_DBI::db_close_database(JCR *jcr) { if (m_connected) { db_end_transaction(jcr); } P(mutex); m_ref_count--; if (m_ref_count == 0) { if (m_connected) { sql_free_result(); } db_list->remove(this); if (m_connected && m_db_handle) { dbi_shutdown_r(m_instance); m_db_handle = NULL; m_instance = NULL; } if (rwl_is_init(&m_lock)) { rwl_destroy(&m_lock); } free_pool_memory(errmsg); free_pool_memory(cmd); free_pool_memory(cached_path); free_pool_memory(fname); free_pool_memory(path); free_pool_memory(esc_name); free_pool_memory(esc_path); free_pool_memory(esc_obj); if (m_db_driver) { free(m_db_driver); } if (m_db_name) { free(m_db_name); } if (m_db_user) { free(m_db_user); } if (m_db_password) { free(m_db_password); } if (m_db_address) { free(m_db_address); } if (m_db_socket) { free(m_db_socket); } if (m_db_driverdir) { free(m_db_driverdir); } delete this; if (db_list->size() == 0) { delete db_list; db_list = NULL; } } V(mutex); } bool B_DB_DBI::db_validate_connection(void) { bool retval; db_lock(this); if (dbi_conn_ping(m_db_handle) == 1) { retval = true; goto bail_out; } else { retval = false; goto bail_out; } bail_out: db_unlock(this); return retval; } /* * Escape strings so that DBI is happy * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. * * dbi_conn_quote_string_copy receives a pointer to pointer. * We need copy the value of pointer to snew because libdbi change the * pointer */ void B_DB_DBI::db_escape_string(JCR *jcr, char *snew, char *old, int len) { char *inew; char *pnew; if (len == 0) { snew[0] = 0; } else { /* * Correct the size of old basead in len and copy new string to inew */ inew = (char *)malloc(sizeof(char) * len + 1); bstrncpy(inew,old,len + 1); /* * Escape the correct size of old */ dbi_conn_escape_string_copy(m_db_handle, inew, &pnew); free(inew); /* * Copy the escaped string to snew */ bstrncpy(snew, pnew, 2 * len + 1); } Dmsg2(500, "dbi_conn_escape_string_copy %p %s\n",snew,snew); } /* * Escape binary object so that DBI is happy * Memory is stored in B_DB struct, no need to free it */ char *B_DB_DBI::db_escape_object(JCR *jcr, char *old, int len) { size_t new_len; char *pnew; if (len == 0) { esc_obj[0] = 0; } else { new_len = dbi_conn_escape_string_copy(m_db_handle, esc_obj, &pnew); esc_obj = check_pool_memory_size(esc_obj, new_len+1); memcpy(esc_obj, pnew, new_len); } return esc_obj; } /* * Unescape binary object so that DBI is happy */ void B_DB_DBI::db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *dest_len) { if (!from) { *dest[0] = 0; *dest_len = 0; return; } *dest = check_pool_memory_size(*dest, expected_len+1); *dest_len = expected_len; memcpy(*dest, from, expected_len); (*dest)[expected_len]=0; } /* * Start a transaction. This groups inserts and makes things * much more efficient. Usually started when inserting * file attributes. */ void B_DB_DBI::db_start_transaction(JCR *jcr) { if (!jcr->attr) { jcr->attr = get_pool_memory(PM_FNAME); } if (!jcr->ar) { jcr->ar = (ATTR_DBR *)malloc(sizeof(ATTR_DBR)); } switch (m_db_type) { case SQL_TYPE_SQLITE3: if (!m_allow_transactions) { return; } db_lock(this); /* * Allow only 10,000 changes per transaction */ if (m_transaction && changes > 10000) { db_end_transaction(jcr); } if (!m_transaction) { sql_query("BEGIN"); /* begin transaction */ Dmsg0(400, "Start SQLite transaction\n"); m_transaction = true; } db_unlock(this); break; case SQL_TYPE_POSTGRESQL: /* * This is turned off because transactions break * if multiple simultaneous jobs are run. */ if (!m_allow_transactions) { return; } db_lock(this); /* * Allow only 25,000 changes per transaction */ if (m_transaction && changes > 25000) { db_end_transaction(jcr); } if (!m_transaction) { sql_query("BEGIN"); /* begin transaction */ Dmsg0(400, "Start PosgreSQL transaction\n"); m_transaction = true; } db_unlock(this); break; case SQL_TYPE_INGRES: if (!m_allow_transactions) { return; } db_lock(this); /* * Allow only 25,000 changes per transaction */ if (m_transaction && changes > 25000) { db_end_transaction(jcr); } if (!m_transaction) { sql_query("BEGIN"); /* begin transaction */ Dmsg0(400, "Start Ingres transaction\n"); m_transaction = true; } db_unlock(this); break; default: break; } } void B_DB_DBI::db_end_transaction(JCR *jcr) { if (jcr && jcr->cached_attribute) { Dmsg0(400, "Flush last cached attribute.\n"); if (!db_create_attributes_record(jcr, this, jcr->ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } switch (m_db_type) { case SQL_TYPE_SQLITE3: if (!m_allow_transactions) { return; } db_lock(this); if (m_transaction) { sql_query("COMMIT"); /* end transaction */ m_transaction = false; Dmsg1(400, "End SQLite transaction changes=%d\n", changes); } changes = 0; db_unlock(this); break; case SQL_TYPE_POSTGRESQL: if (!m_allow_transactions) { return; } db_lock(this); if (m_transaction) { sql_query("COMMIT"); /* end transaction */ m_transaction = false; Dmsg1(400, "End PostgreSQL transaction changes=%d\n", changes); } changes = 0; db_unlock(this); break; case SQL_TYPE_INGRES: if (!m_allow_transactions) { return; } db_lock(this); if (m_transaction) { sql_query("COMMIT"); /* end transaction */ m_transaction = false; Dmsg1(400, "End Ingres transaction changes=%d\n", changes); } changes = 0; db_unlock(this); break; default: break; } } /* * Submit a general SQL command (cmd), and for each row returned, * the result_handler is called with the ctx. */ bool B_DB_DBI::db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { bool retval = true; SQL_ROW row; Dmsg1(500, "db_sql_query starts with %s\n", query); db_lock(this); if (!sql_query(query, QF_STORE_RESULT)) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror()); Dmsg0(500, "db_sql_query failed\n"); retval = false; goto bail_out; } Dmsg0(500, "db_sql_query succeeded. checking handler\n"); if (result_handler != NULL) { Dmsg0(500, "db_sql_query invoking handler\n"); while ((row = sql_fetch_row()) != NULL) { Dmsg0(500, "db_sql_query sql_fetch_row worked\n"); if (result_handler(ctx, m_num_fields, row)) break; } sql_free_result(); } Dmsg0(500, "db_sql_query finished\n"); bail_out: db_unlock(this); return retval; } /* * Note, if this routine returns 1 (failure), BAREOS expects * that no result has been stored. * * Returns: true on success * false on failure */ bool B_DB_DBI::sql_query(const char *query, int flags) { bool retval = false; const char *dbi_errmsg; Dmsg1(500, "sql_query starts with %s\n", query); /* * We are starting a new query. reset everything. */ m_num_rows = -1; m_row_number = -1; m_field_number = -1; if (m_result) { dbi_result_free(m_result); /* hmm, someone forgot to free?? */ m_result = NULL; } m_result = (void **)dbi_conn_query(m_db_handle, query); if (!m_result) { Dmsg2(50, "Query failed: %s %p\n", query, m_result); goto bail_out; } m_status = (dbi_error_flag) dbi_conn_error(m_db_handle, &dbi_errmsg); if (m_status == DBI_ERROR_NONE) { Dmsg1(500, "we have a result\n", query); /* * How many fields in the set? * num_fields starting at 1 */ m_num_fields = dbi_result_get_numfields(m_result); Dmsg1(500, "we have %d fields\n", m_num_fields); /* * If no result num_rows is 0 */ m_num_rows = dbi_result_get_numrows(m_result); Dmsg1(500, "we have %d rows\n", m_num_rows); m_status = (dbi_error_flag) 0; /* succeed */ } else { Dmsg1(50, "Result status failed: %s\n", query); goto bail_out; } Dmsg0(500, "sql_query finishing\n"); retval = true; goto ok_out; bail_out: m_status = (dbi_error_flag) dbi_conn_error(m_db_handle, &dbi_errmsg); //dbi_conn_error(m_db_handle, &dbi_errmsg); Dmsg4(500, "sql_query we failed dbi error: " "'%s' '%p' '%d' flag '%d''\n", dbi_errmsg, m_result, m_result, m_status); dbi_result_free(m_result); m_result = NULL; m_status = (dbi_error_flag) 1; /* failed */ ok_out: return retval; } void B_DB_DBI::sql_free_result(void) { DBI_FIELD_GET *f; db_lock(this); if (m_result) { dbi_result_free(m_result); m_result = NULL; } if (m_rows) { free(m_rows); m_rows = NULL; } /* * Now is time to free all value return by dbi_get_value * this is necessary because libdbi don't free memory return by yours results * and BAREOS has some routine wich call more than once time sql_fetch_row * * Using a queue to store all pointer allocate is a good way to free all things * when necessary */ foreach_dlist(f, dbi_getvalue_list) { free(f->value); free(f); } if (m_fields) { free(m_fields); m_fields = NULL; } m_num_rows = m_num_fields = 0; db_unlock(this); } /* dbi_getvalue * like PQgetvalue; * char *PQgetvalue(const PGresult *res, * int row_number, * int column_number); * * use dbi_result_seek_row to search in result set * use example to return only strings */ static char *dbi_getvalue(dbi_result *result, int row_number, unsigned int column_number) { char *buf = NULL; const char *dbi_errmsg; const char *field_name; unsigned short dbitype; size_t field_length; int64_t num; /* correct the index for dbi interface * dbi index begins 1 * I prefer do not change others functions */ Dmsg3(600, "dbi_getvalue pre-starting result '%p' row number '%d' column number '%d'\n", result, row_number, column_number); column_number++; if(row_number == 0) { row_number++; } Dmsg3(600, "dbi_getvalue starting result '%p' row number '%d' column number '%d'\n", result, row_number, column_number); if(dbi_result_seek_row(result, row_number)) { field_name = dbi_result_get_field_name(result, column_number); field_length = dbi_result_get_field_length(result, field_name); dbitype = dbi_result_get_field_type_idx(result,column_number); Dmsg3(500, "dbi_getvalue start: type: '%d' " "field_length bytes: '%d' fieldname: '%s'\n", dbitype, field_length, field_name); if(field_length) { //buf = (char *)malloc(sizeof(char *) * field_length + 1); buf = (char *)malloc(field_length + 1); } else { /* * if numbers */ buf = (char *)malloc(sizeof(char *) * 50); } switch (dbitype) { case DBI_TYPE_INTEGER: num = dbi_result_get_longlong(result, field_name); edit_int64(num, buf); field_length = strlen(buf); break; case DBI_TYPE_STRING: if(field_length) { field_length = bsnprintf(buf, field_length + 1, "%s", dbi_result_get_string(result, field_name)); } else { buf[0] = 0; } break; case DBI_TYPE_BINARY: /* * dbi_result_get_binary return a NULL pointer if value is empty * following, change this to what BAREOS expected */ if(field_length) { field_length = bsnprintf(buf, field_length + 1, "%s", dbi_result_get_binary(result, field_name)); } else { buf[0] = 0; } break; case DBI_TYPE_DATETIME: time_t last; struct tm tm; last = dbi_result_get_datetime(result, field_name); if(last == -1) { field_length = bsnprintf(buf, 20, "0000-00-00 00:00:00"); } else { blocaltime(&last, &tm); field_length = bsnprintf(buf, 20, "%04d-%02d-%02d %02d:%02d:%02d", (tm.tm_year + 1900), (tm.tm_mon + 1), tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } break; } } else { dbi_conn_error(dbi_result_get_conn(result), &dbi_errmsg); Dmsg1(500, "dbi_getvalue error: %s\n", dbi_errmsg); } Dmsg3(500, "dbi_getvalue finish buffer: '%p' num bytes: '%d' data: '%s'\n", buf, field_length, buf); /* * Don't worry about this buf */ return buf; } SQL_ROW B_DB_DBI::sql_fetch_row(void) { int j; SQL_ROW row = NULL; /* by default, return NULL */ Dmsg0(500, "sql_fetch_row start\n"); if ((!m_rows || m_rows_size < m_num_fields) && m_num_rows > 0) { if (m_rows) { Dmsg0(500, "sql_fetch_row freeing space\n"); Dmsg2(500, "sql_fetch_row row: '%p' num_fields: '%d'\n", m_rows, m_num_fields); if (m_num_rows != 0) { for (j = 0; j < m_num_fields; j++) { Dmsg2(500, "sql_fetch_row row '%p' '%d'\n", m_rows[j], j); if (m_rows[j]) { free(m_rows[j]); } } } free(m_rows); } Dmsg1(500, "we need space for %d bytes\n", sizeof(char *) * m_num_fields); m_rows = (SQL_ROW)malloc(sizeof(char *) * m_num_fields); m_rows_size = m_num_fields; /* * Now reset the row_number now that we have the space allocated */ m_row_number = 1; } /* * If still within the result set */ if (m_row_number <= m_num_rows && m_row_number != DBI_ERROR_BADPTR) { Dmsg2(500, "sql_fetch_row row number '%d' is acceptable (1..%d)\n", m_row_number, m_num_rows); /* * Get each value from this row */ for (j = 0; j < m_num_fields; j++) { m_rows[j] = dbi_getvalue(m_result, m_row_number, j); /* * Allocate space to queue row */ m_field_get = (DBI_FIELD_GET *)malloc(sizeof(DBI_FIELD_GET)); /* * Store the pointer in queue */ m_field_get->value = m_rows[j]; Dmsg4(500, "sql_fetch_row row[%d] field: '%p' in queue: '%p' has value: '%s'\n", j, m_rows[j], m_field_get->value, m_rows[j]); /* * Insert in queue to future free */ dbi_getvalue_list->append(m_field_get); } /* * Increment the row number for the next call */ m_row_number++; row = m_rows; } else { Dmsg2(500, "sql_fetch_row row number '%d' is NOT acceptable (1..%d)\n", m_row_number, m_num_rows); } Dmsg1(500, "sql_fetch_row finishes returning %p\n", row); return row; } const char *B_DB_DBI::sql_strerror(void) { const char *dbi_errmsg; dbi_conn_error(m_db_handle, &dbi_errmsg); return dbi_errmsg; } void B_DB_DBI::sql_data_seek(int row) { /* * Set the row number to be returned on the next call to sql_fetch_row */ m_row_number = row; } int B_DB_DBI::sql_affected_rows(void) { #if 0 return dbi_result_get_numrows_affected(result); #else return 1; #endif } uint64_t B_DB_DBI::sql_insert_autokey_record(const char *query, const char *table_name) { char sequence[30]; uint64_t id = 0; /* * First execute the insert query and then retrieve the currval. */ if (!sql_query(query)) { return 0; } m_num_rows = sql_affected_rows(); if (m_num_rows != 1) { return 0; } changes++; /* * Obtain the current value of the sequence that * provides the serial value for primary key of the table. * * currval is local to our session. It is not affected by * other transactions. * * Determine the name of the sequence. * PostgreSQL automatically creates a sequence using * __seq. * At the time of writing, all tables used this format for * for their primary key:
id * Except for basefiles which has a primary key on baseid. * Therefore, we need to special case that one table. * * everything else can use the PostgreSQL formula. */ if (m_db_type == SQL_TYPE_POSTGRESQL) { if (bstrcasecmp(table_name, "basefiles")) { bstrncpy(sequence, "basefiles_baseid", sizeof(sequence)); } else { bstrncpy(sequence, table_name, sizeof(sequence)); bstrncat(sequence, "_", sizeof(sequence)); bstrncat(sequence, table_name, sizeof(sequence)); bstrncat(sequence, "id", sizeof(sequence)); } bstrncat(sequence, "_seq", sizeof(sequence)); id = dbi_conn_sequence_last(m_db_handle, NT_(sequence)); } else { id = dbi_conn_sequence_last(m_db_handle, NT_(table_name)); } return id; } /* dbi_getisnull * like PQgetisnull * int PQgetisnull(const PGresult *res, * int row_number, * int column_number); * * use dbi_result_seek_row to search in result set */ static int dbi_getisnull(dbi_result *result, int row_number, int column_number) { int i; if (row_number == 0) { row_number++; } column_number++; if (dbi_result_seek_row(result, row_number)) { i = dbi_result_field_is_null_idx(result,column_number); return i; } else { return 0; } } SQL_FIELD *B_DB_DBI::sql_fetch_field(void) { int i, j; int dbi_index; int max_length; int this_length; char *cbuf = NULL; Dmsg0(500, "sql_fetch_field starts\n"); if (!m_fields || m_fields_size < m_num_fields) { if (m_fields) { free(m_fields); m_fields = NULL; } Dmsg1(500, "allocating space for %d fields\n", m_num_fields); m_fields = (SQL_FIELD *)malloc(sizeof(SQL_FIELD) * m_num_fields); m_fields_size = m_num_fields; for (i = 0; i < m_num_fields; i++) { /* * num_fields is starting at 1, increment i by 1 */ dbi_index = i + 1; Dmsg1(500, "filling field %d\n", i); m_fields[i].name = (char *)dbi_result_get_field_name(m_result, dbi_index); m_fields[i].type = dbi_result_get_field_type_idx(m_result, dbi_index); m_fields[i].flags = dbi_result_get_field_attribs_idx(m_result, dbi_index); /* * For a given column, find the max length. */ max_length = 0; for (j = 0; j < m_num_rows; j++) { if (dbi_getisnull(m_result, j, dbi_index)) { this_length = 4; /* "NULL" */ } else { cbuf = dbi_getvalue(m_result, j, dbi_index); this_length = cstrlen(cbuf); /* * cbuf is always free */ free(cbuf); } if (max_length < this_length) { max_length = this_length; } } m_fields[i].max_length = max_length; Dmsg4(500, "sql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", m_fields[i].name, m_fields[i].max_length, m_fields[i].type, m_fields[i].flags); } } /* * Increment field number for the next time around */ return &m_fields[m_field_number++]; } bool B_DB_DBI::sql_field_is_not_null(int field_type) { switch (field_type) { case (1 << 0): return true; default: return false; } } bool B_DB_DBI::sql_field_is_numeric(int field_type) { switch (field_type) { case 1: case 2: return true; default: return false; } } /* * Escape strings so that PostgreSQL is happy on COPY * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. */ static char *postgresql_copy_escape(char *dest, char *src, size_t len) { /* * We have to escape \t, \n, \r, \ */ char c = '\0' ; while (len > 0 && *src) { switch (*src) { case '\n': c = 'n'; break; case '\\': c = '\\'; break; case '\t': c = 't'; break; case '\r': c = 'r'; break; default: c = '\0' ; } if (c) { *dest = '\\'; dest++; *dest = c; } else { *dest = *src; } len--; src++; dest++; } *dest = '\0'; return dest; } /* * This can be a bit strang but is the one way to do * * Returns true if OK * false if failed */ bool B_DB_DBI::sql_batch_start(JCR *jcr) { bool retval = true; const char *query = "COPY batch FROM STDIN"; Dmsg0(500, "sql_batch_start started\n"); db_lock(this); switch (m_db_type) { case SQL_TYPE_MYSQL: if (!sql_query("CREATE TEMPORARY TABLE batch (" "FileIndex integer," "JobId integer," "Path blob," "Name blob," "LStat tinyblob," "MD5 tinyblob," "DeltaSeq smallint)")) { Dmsg0(500, "sql_batch_start failed\n"); goto bail_out; } Dmsg0(500, "sql_batch_start finishing\n"); goto ok_out; case SQL_TYPE_POSTGRESQL: if (!sql_query("CREATE TEMPORARY TABLE batch (" "FileIndex int," "JobId int," "Path varchar," "Name varchar," "LStat varchar," "MD5 varchar," "DeltaSeq int)")) { Dmsg0(500, "sql_batch_start failed\n"); goto bail_out; } /* * We are starting a new query. reset everything. */ m_num_rows = -1; m_row_number = -1; m_field_number = -1; sql_free_result(); for (int i=0; i < 10; i++) { sql_query(query); if (m_result) { break; } bmicrosleep(5, 0); } if (!m_result) { Dmsg1(50, "Query failed: %s\n", query); goto bail_out; } m_status = (dbi_error_flag)dbi_conn_error(m_db_handle, NULL); //m_status = DBI_ERROR_NONE; if (m_status == DBI_ERROR_NONE) { /* * How many fields in the set? */ m_num_fields = dbi_result_get_numfields(m_result); m_num_rows = dbi_result_get_numrows(m_result); m_status = (dbi_error_flag) 1; } else { Dmsg1(50, "Result status failed: %s\n", query); goto bail_out; } Dmsg0(500, "sql_batch_start finishing\n"); goto ok_out; case SQL_TYPE_SQLITE3: if (!sql_query("CREATE TEMPORARY TABLE batch (" "FileIndex integer," "JobId integer," "Path blob," "Name blob," "LStat tinyblob," "MD5 tinyblob," "DeltaSeq smallint)")) { Dmsg0(500, "sql_batch_start failed\n"); goto bail_out; } Dmsg0(500, "sql_batch_start finishing\n"); goto ok_out; } bail_out: Mmsg1(&errmsg, _("error starting batch mode: %s"), sql_strerror()); m_status = (dbi_error_flag) 0; sql_free_result(); m_result = NULL; retval = false; ok_out: db_unlock(this); return retval; } /* * Set error to something to abort operation */ bool B_DB_DBI::sql_batch_end(JCR *jcr, const char *error) { int res = 0; int count = 30; int (*custom_function)(void*, const char*) = NULL; dbi_conn_t *myconn = (dbi_conn_t *)(m_db_handle); Dmsg0(500, "sql_batch_start started\n"); switch (m_db_type) { case SQL_TYPE_MYSQL: m_status = (dbi_error_flag) 0; break; case SQL_TYPE_POSTGRESQL: custom_function = (custom_function_end_t)dbi_driver_specific_function(dbi_conn_get_driver(myconn), "PQputCopyEnd"); do { res = (*custom_function)(myconn->connection, error); } while (res == 0 && --count > 0); if (res == 1) { Dmsg0(500, "ok\n"); m_status = (dbi_error_flag) 1; } if (res <= 0) { Dmsg0(500, "we failed\n"); m_status = (dbi_error_flag) 0; //Mmsg1(&errmsg, _("error ending batch mode: %s"), PQerrorMessage(myconn)); } break; case SQL_TYPE_SQLITE3: m_status = (dbi_error_flag) 0; break; } Dmsg0(500, "sql_batch_start finishing\n"); return true; } /* * This function is big and use a big switch. * In near future is better split in small functions * and refactory. */ bool B_DB_DBI::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) { int res; int count=30; dbi_conn_t *myconn = (dbi_conn_t *)(m_db_handle); int (*custom_function)(void*, const char*, int) = NULL; char* (*custom_function_error)(void*) = NULL; size_t len; char *digest; char ed1[50]; Dmsg0(500, "sql_batch_start started \n"); esc_name = check_pool_memory_size(esc_name, fnl*2+1); esc_path = check_pool_memory_size(esc_path, pnl*2+1); if (ar->Digest == NULL || ar->Digest[0] == 0) { *digest = '\0'; } else { digest = ar->Digest; } switch (m_db_type) { case SQL_TYPE_MYSQL: db_escape_string(jcr, esc_name, fname, fnl); db_escape_string(jcr, esc_path, path, pnl); len = Mmsg(cmd, "INSERT INTO batch VALUES " "(%u,%s,'%s','%s','%s','%s',%u)", ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); if (!sql_query(cmd)) { Dmsg0(500, "sql_batch_start failed\n"); goto bail_out; } Dmsg0(500, "sql_batch_start finishing\n"); return true; break; case SQL_TYPE_POSTGRESQL: postgresql_copy_escape(esc_name, fname, fnl); postgresql_copy_escape(esc_path, path, pnl); len = Mmsg(cmd, "%u\t%s\t%s\t%s\t%s\t%s\t%u\n", ar->FileIndex, edit_int64(ar->JobId, ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); /* * libdbi don't support CopyData and we need call a postgresql * specific function to do this work */ Dmsg2(500, "sql_batch_insert :\n %s \ncmd_size: %d",cmd, len); custom_function = (custom_function_insert_t)dbi_driver_specific_function(dbi_conn_get_driver(myconn),"PQputCopyData"); if (custom_function != NULL) { do { res = (*custom_function)(myconn->connection, cmd, len); } while (res == 0 && --count > 0); if (res == 1) { Dmsg0(500, "ok\n"); changes++; m_status = (dbi_error_flag) 1; } if (res <= 0) { Dmsg0(500, "sql_batch_insert failed\n"); goto bail_out; } Dmsg0(500, "sql_batch_insert finishing\n"); return true; } else { /* * Ensure to detect a PQerror */ custom_function_error = (custom_function_error_t)dbi_driver_specific_function(dbi_conn_get_driver(myconn), "PQerrorMessage"); Dmsg1(500, "sql_batch_insert failed\n PQerrorMessage: %s", (*custom_function_error)(myconn->connection)); goto bail_out; } break; case SQL_TYPE_SQLITE3: db_escape_string(jcr, esc_name, fname, fnl); db_escape_string(jcr, esc_path, path, pnl); len = Mmsg(cmd, "INSERT INTO batch VALUES " "(%u,%s,'%s','%s','%s','%s',%u)", ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); if (!sql_query(cmd)) { Dmsg0(500, "sql_batch_insert failed\n"); goto bail_out; } Dmsg0(500, "sql_batch_insert finishing\n"); return true; break; } bail_out: Mmsg1(&errmsg, _("error inserting batch mode: %s"), sql_strerror()); m_status = (dbi_error_flag) 0; sql_free_result(); return false; } /* * Initialize database data structure. In principal this should * never have errors, or it is really fatal. */ #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" B_DB CATS_IMP_EXP *backend_instantiate(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #else B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #endif { B_DB_DBI *mdb = NULL; if (!db_driver) { Jmsg(jcr, M_ABORT, 0, _("Driver type not specified in Catalog resource.\n")); } if (strlen(db_driver) < 5 || db_driver[3] != ':' || !bstrncasecmp(db_driver, "dbi", 3)) { Jmsg(jcr, M_ABORT, 0, _("Invalid driver type, must be \"dbi:\"\n")); } if (!db_user) { Jmsg(jcr, M_FATAL, 0, _("A user name for DBI must be supplied.\n")); return NULL; } P(mutex); /* lock DB queue */ /* * Look to see if DB already open */ if (db_list && !mult_db_connections && !need_private) { foreach_dlist(mdb, db_list) { if (mdb->is_private()) { continue; } if (mdb->db_match_database(db_driver, db_name, db_address, db_port)) { Dmsg1(100, "DB REopen %s\n", db_name); mdb->increment_refcount(); goto bail_out; } } } Dmsg0(100, "db_init_database first time\n"); mdb = New(B_DB_DBI(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private)); bail_out: V(mutex); return mdb; } #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" void CATS_IMP_EXP flush_backend(void) #else void db_flush_backends(void) #endif { } #endif /* HAVE_DBI */ bareos-Release-14.2.6/src/cats/ddl/000077500000000000000000000000001263011562700167245ustar00rootroot00000000000000bareos-Release-14.2.6/src/cats/ddl/creates/000077500000000000000000000000001263011562700203525ustar00rootroot00000000000000bareos-Release-14.2.6/src/cats/ddl/creates/ingres.sql000066400000000000000000000422751263011562700223740ustar00rootroot00000000000000-- -- When using batch insert make sure you adhere to the following -- minimum Ingres version: -- -- Ingres 9.2 or higher with the fix for bug 123652 and bug 117256 -- For Solaris x86 this is Ingres 9.2. + patch 13785 or higher -- For Linux x86_64 this is Ingres 9.2 + patch 13790 or higher -- -- -- As it seems the upper limit for a VARCHAR/VARBYTE column is 32000 bytes -- We could have used a BLOB as storage type which can go up to 2 Gb but -- you cannot create indexes based on a BLOB (and we don't seem to be able -- to limit the part of the field which should be used for the index to lets -- say 255 chars like we can in MySQL) and the storage for a BLOB is also far -- from optimal so for now we decided that the upper limit for File and Path -- fields is the 32000 bytes. -- -- To use the big VARBYTE colums we need the bigger page sizes enabled in -- ingres (which at this time supports 2K, 4K, 8K, 16K, 32K, 64K) -- Make sure you have the following settings in your -- ${II_SYSTEM}/ingres/files/config.dat -- -- ii..dbms.private.*.cache.p8k_status: ON -- ii..dbms.private.*.cache.p16k_status: ON -- ii..dbms.private.*.cache.p32k_status: ON -- ii..dbms.private.*.cache.p64k_status: ON -- ii..rcp.dmf_cache_size8k: 200 -- ii..rcp.dmf_cache_size16k: 200 -- ii..rcp.dmf_cache_size32k: 200 -- ii..rcp.dmf_cache_size64k: 200 -- SET AUTOCOMMIT ON\g CREATE SEQUENCE Filename_Seq; CREATE TABLE Filename ( FilenameId INTEGER NOT NULL DEFAULT Filename_Seq.nextval, Name VARBYTE(32000) NOT NULL, PRIMARY KEY (FilenameId) ); CREATE UNIQUE INDEX (filename_name_idx ON filename (Name) WITH STRUCTURE=HASH,PAGE_SIZE=32768); CREATE SEQUENCE Path_Seq; CREATE TABLE path ( Pathid INTEGER NOT NULL DEFAULT Path_Seq.nextval, Path VARBYTE(32000) NOT NULL, PRIMARY KEY (Pathid) ); CREATE UNIQUE INDEX (path_name_idx ON path (Path) WITH STRUCTURE=HASH,PAGE_SIZE=32768); CREATE SEQUENCE File_Seq; CREATE TABLE file ( FileId BIGINT NOT NULL DEFAULT File_Seq.nextval, FileIndex INTEGER NOT NULL DEFAULT 0, JobId INTEGER NOT NULL, PathId INTEGER NOT NULL, FilenameId INTEGER NOT NULL, DeltaSeq INTEGER NOT NULL DEFAULT 0, MarkId INTEGER NOT NULL DEFAULT 0, LStat VARBYTE(255) NOT NULL, Md5 VARBYTE(255) NOT NULL, PRIMARY KEY (fileid) ); CREATE INDEX file_jpfid_idx ON File (jobid, pathid, filenameid); -- If you need performances, you can remove this index -- the database engine is able to use the composite index -- to find all records with a given JobId CREATE INDEX file_jobid_idx ON File(jobid); CREATE SEQUENCE RestoreObject_Seq; CREATE TABLE RestoreObject ( RestoreObjectId INTEGER NOT NULL DEFAULT RestoreObject_Seq.nextval, ObjectName VARBYTE(128) NOT NULL, RestoreObject BLOB NOT NULL, PluginName VARBYTE(128) NOT NULL, ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER DEFAULT 0, JobId INTEGER, ObjectCompression INTEGER DEFAULT 0, PRIMARY KEY (RestoreObjectId) ); CREATE INDEX restore_jobid_idx on RestoreObject(JobId); CREATE SEQUENCE Job_Seq; CREATE TABLE Job ( JobId INTEGER NOT NULL DEFAULT Job_Seq.nextval, Job VARBYTE(128) NOT NULL, Name VARBYTE(128) NOT NULL, Type CHAR(1) NOT NULL, Level CHAR(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus CHAR(1) NOT NULL, SchedTime TIMESTAMP WITHOUT TIME ZONE, StartTime TIMESTAMP WITHOUT TIME ZONE, EndTime TIMESTAMP WITHOUT TIME ZONE, RealEndTime TIMESTAMP WITHOUT TIME ZONE, JobTDate BIGINT DEFAULT 0, VolSessionId INTEGER DEFAULT 0, volSessionTime INTEGER DEFAULT 0, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0, ReadBytes BIGINT DEFAULT 0, JobErrors INTEGER DEFAULT 0, JobMissingFiles INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, FilesetId INTEGER DEFAULT 0, PriorJobid INTEGER DEFAULT 0, PurgedFiles SMALLINT DEFAULT 0, HasBase SMALLINT DEFAULT 0, HasCache SMALLINT DEFAULT 0, Reviewed SMALLINT DEFAULT 0, Comment VARBYTE(4096), PRIMARY KEY (JobId) ); CREATE INDEX job_name_idx ON Job (Name); -- Create a table like Job for long term statistics CREATE SEQUENCE JobHisto_Seq; CREATE TABLE JobHisto ( JobId INTEGER NOT NULL DEFAULT JobHisto_Seq.nextval, Job VARBYTE(128) NOT NULL, Name VARBYTE(128) NOT NULL, Type CHAR(1) NOT NULL, Level CHAR(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus CHAR(1) NOT NULL, SchedTime TIMESTAMP WITHOUT TIME ZONE, StartTime TIMESTAMP WITHOUT TIME ZONE, EndTime TIMESTAMP WITHOUT TIME ZONE, RealEndTime TIMESTAMP WITHOUT TIME ZONE, JobTDate BIGINT DEFAULT 0, VolSessionId INTEGER DEFAULT 0, volSessionTime INTEGER DEFAULT 0, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0, ReadBytes BIGINT DEFAULT 0, JobErrors INTEGER DEFAULT 0, JobMissingFiles INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, FilesetId INTEGER DEFAULT 0, PriorJobid INTEGER DEFAULT 0, PurgedFiles SMALLINT DEFAULT 0, HasBase SMALLINT DEFAULT 0, HasCache SMALLINT DEFAULT 0, Reviewed SMALLINT DEFAULT 0, Comment VARBYTE(4096), PRIMARY KEY (JobId) ); CREATE INDEX jobhisto_idx ON JobHisto (StartTime); CREATE SEQUENCE Location_Seq; CREATE TABLE Location ( LocationId INTEGER NOT NULL DEFAULT Location_Seq.nextval, Location VARBYTE(128) NOT NULL, Cost INTEGER DEFAULT 0, Enabled SMALLINT, PRIMARY KEY (LocationId) ); CREATE SEQUENCE Fileset_Seq; CREATE TABLE Fileset ( FilesetId INTEGER NOT NULL DEFAULT Fileset_Seq.nextval, Fileset VARBYTE(128) NOT NULL, Md5 VARBYTE(128) NOT NULL, Createtime TIMESTAMP WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (filesetid) ); CREATE INDEX fileset_name_idx ON Fileset (fileset); CREATE SEQUENCE JobMedia_Seq; CREATE TABLE JobMedia ( JobMediaId INTEGER NOT NULL DEFAULT JobMedia_Seq.nextval, JobId INTEGER NOT NULL, MediaId INTEGER NOT NULL, FirstIndex INTEGER DEFAULT 0, LastIndex INTEGER DEFAULT 0, StartFile INTEGER DEFAULT 0, EndFile INTEGER DEFAULT 0, StartBlock BIGINT DEFAULT 0, EndBlock BIGINT DEFAULT 0, VolIndex INTEGER DEFAULT 0, PRIMARY KEY (jobmediaid) ); CREATE INDEX job_media_job_id_media_id_idx ON JobMedia (jobid, mediaid); CREATE SEQUENCE Media_Seq; CREATE TABLE Media ( MediaId INTEGER NOT NULL DEFAULT Media_Seq.nextval, VolumeName VARBYTE(128) NOT NULL, Slot INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, MediaType VARBYTE(128) NOT NULL, MediaTypeId INTEGER DEFAULT 0, LabelType INTEGER DEFAULT 0, FirstWritten TIMESTAMP WITHOUT TIME ZONE, LastWritten TIMESTAMP WITHOUT TIME ZONE, LabelDate TIMESTAMP WITHOUT TIME ZONE, VolJobs INTEGER DEFAULT 0, VolFiles INTEGER DEFAULT 0, VolBlocks INTEGER DEFAULT 0, VolMounts INTEGER DEFAULT 0, VolBytes BIGINT DEFAULT 0, VolErrors INTEGER DEFAULT 0, VolWrites INTEGER DEFAULT 0, VolCapacitybytes BIGINT DEFAULT 0, VolStatus VARBYTE(128) NOT NULL CHECK (volstatus in ('Full','Archive','Append', 'Recycle','Purged','Read-Only','Disabled', 'Error','Busy','Used','Cleaning','Scratch')), Enabled SMALLINT DEFAULT 1, Recycle SMALLINT DEFAULT 0, ActionOnPurge SMALLINT DEFAULT 0, VolRetention BIGINT DEFAULT 0, VolUseDuration BIGINT DEFAULT 0, MaxVolJobs INTEGER DEFAULT 0, MaxVolFiles INTEGER DEFAULT 0, MaxVolBytes BIGINT DEFAULT 0, InChanger SMALLINT DEFAULT 0, StorageId BIGINT DEFAULT 0, DeviceId INTEGER DEFAULT 0, MediaAddressing SMALLINT DEFAULT 0, VolReadTime BIGINT DEFAULT 0, VolWriteTime BIGINT DEFAULT 0, EndFile INTEGER DEFAULT 0, EndBlock BIGINT DEFAULT 0, LocationId INTEGER DEFAULT 0, RecycleCount INTEGER DEFAULT 0, MinBlockSize INTEGER DEFAULT 0, MaxBlockSize INTEGER DEFAULT 0, InitialWrite TIMESTAMP WITHOUT TIME ZONE, ScratchPoolId INTEGER DEFAULT 0, RecyclePoolId INTEGER DEFAULT 0, EncryptionKey VARBYTE(128), Comment VARBYTE(4096), PRIMARY KEY (mediaid) ); CREATE UNIQUE INDEX media_volumename_id ON Media (VolumeName); CREATE INDEX media_poolid_idx ON Media (PoolId); CREATE SEQUENCE MediaType_Seq; CREATE TABLE MediaType ( MediaTypeId INTEGER NOT NULL DEFAULT MediaType_Seq.nextval, MediaType VARBYTE(128) NOT NULL, ReadOnly INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (MediaTypeId) ); CREATE SEQUENCE Storage_Seq; CREATE TABLE Storage ( StorageId INTEGER NOT NULL DEFAULT Storage_Seq.nextval, Name VARBYTE(128) NOT NULL, AutoChanger INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (StorageId) ); CREATE SEQUENCE Device_Seq; CREATE TABLE Device ( DeviceId INTEGER NOT NULL DEFAULT Device_Seq.nextval, Name VARBYTE(128) NOT NULL, MediaTypeId INTEGER NOT NULL, StorageId INTEGER NOT NULL, DevMounts INTEGER NOT NULL DEFAULT 0, DevReadBytes BIGINT NOT NULL DEFAULT 0, DevWriteBytes BIGINT NOT NULL DEFAULT 0, DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, DevReadTime BIGINT NOT NULL DEFAULT 0, DevWriteTime BIGINT NOT NULL DEFAULT 0, DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, DevWriteTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, CleaningDate TIMESTAMP WITHOUT TIME ZONE, CleaningPeriod BIGINT NOT NULL DEFAULT 0, PRIMARY KEY (DeviceId) ); CREATE SEQUENCE Pool_Seq; CREATE TABLE Pool ( PoolId INTEGER NOT NULL DEFAULT pool_Seq.nextval, Name VARBYTE(128) NOT NULL, NumVols INTEGER DEFAULT 0, MaxVols INTEGER DEFAULT 0, UseOnce SMALLINT DEFAULT 0, UseCatalog SMALLINT DEFAULT 0, AcceptAnyVolume SMALLINT DEFAULT 0, VolRetention BIGINT DEFAULT 0, VolUseDuration BIGINT DEFAULT 0, MaxVolJobs INTEGER DEFAULT 0, MaxVolFiles INTEGER DEFAULT 0, MaxVolBytes BIGINT DEFAULT 0, AutoPrune SMALLINT DEFAULT 0, Recycle SMALLINT DEFAULT 0, ActionOnPurge SMALLINT DEFAULT 0, PoolType VARBYTE(32) CHECK (pooltype in ('Backup','Copy','Cloned','Archive','Migration','Scratch')), LabelType INTEGER DEFAULT 0, LabelFormat VARBYTE(128) NOT NULL, Enabled SMALLINT DEFAULT 1, ScratchPoolId INTEGER DEFAULT 0, RecyclePoolId INTEGER DEFAULT 0, NextPoolId INTEGER DEFAULT 0, MinBlockSize INTEGER DEFAULT 0, MaxBlockSize INTEGER DEFAULT 0, MigrationHighBytes BIGINT DEFAULT 0, MigrationLowBytes BIGINT DEFAULT 0, MigrationTime BIGINT DEFAULT 0, PRIMARY KEY (poolid) ); CREATE INDEX pool_name_idx ON Pool (name); CREATE SEQUENCE Client_Seq; CREATE TABLE Client ( ClientId INTEGER NOT NULL DEFAULT Client_Seq.nextval, Name VARBYTE(128) NOT NULL, Uname VARBYTE(256) NOT NULL, AutoPrune SMALLINT DEFAULT 0, FileRetention BIGINT DEFAULT 0, JobRetention BIGINT DEFAULT 0, PRIMARY KEY (clientid) ); CREATE UNIQUE INDEX client_name_idx ON Client (Name); CREATE SEQUENCE Log_Seq; CREATE TABLE Log ( LogId INTEGER NOT NULL DEFAULT Log_Seq.nextval, JobId INTEGER NOT NULL, Time TIMESTAMP WITHOUT TIME ZONE, LogText VARBYTE(4096) NOT NULL, PRIMARY KEY (LogId) ); CREATE INDEX log_name_idx ON Log (JobId); CREATE SEQUENCE LocationLog_Seq; CREATE TABLE LocationLog ( LocLogId INTEGER NOT NULL DEFAULT LocationLog_Seq.nextval, Date TIMESTAMP WITHOUT TIME ZONE, Comment VARBYTE(4096) NOT NULL, MediaId INTEGER DEFAULT 0, LocationId INTEGER DEFAULT 0, NewVolStatus VARBYTE(32) NOT NULL CHECK (newvolstatus in ('Full','Archive','Append', 'Recycle','Purged','Read-Only','Disabled', 'Error','Busy','Used','Cleaning','Scratch')), NewEnabled SMALLINT, PRIMARY KEY (LocLogId) ); CREATE TABLE Counters ( Counter VARBYTE(128) NOT NULL, MinValue INTEGER DEFAULT 0, MaxValue INTEGER DEFAULT 0, CurrentValue INTEGER DEFAULT 0, WrapCounter VARBYTE(128) NOT NULL, PRIMARY KEY (counter) ); CREATE SEQUENCE BaseFiles_Seq; CREATE TABLE BaseFiles ( BaseId INTEGER NOT NULL DEFAULT BaseFiles_Seq.nextval, JobId INTEGER NOT NULL, FileId BIGINT NOT NULL, FileIndex INTEGER, BaseJobid INTEGER, PRIMARY KEY (BaseId) ); CREATE INDEX basefiles_jobid_idx ON BaseFiles (JobId); CREATE TABLE UnsavedFiles ( UnsavedId INTEGER NOT NULL, JobId INTEGER NOT NULL, PathId INTEGER NOT NULL, FilenameId INTEGER NOT NULL, PRIMARY KEY (UnsavedId) ); CREATE TABLE PathHierarchy ( PathId INTEGER NOT NULL, PPathId INTEGER NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId INTEGER NOT NULL, JobId INTEGER NOT NULL, Size BIGINT DEFAULT 0, Files INTEGER DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE TABLE version ( versionid INTEGER NOT NULL ); CREATE TABLE Status ( JobStatus CHAR(1) NOT NULL, JobStatusLong VARBYTE(128), Severity INTEGER, PRIMARY KEY (JobStatus) ); CREATE TABLE Quota ( ClientId INTEGER NOT NULL, GraceTime INTEGER DEFAULT 0, QuotaLimit BIGINT DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER NOT NULL, FilesetId INTEGER DEFAULT 0, FileSystem VARBYTE(256) NOT NULL, DumpLevel INTEGER DEFAULT 0, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem) ); CREATE TABLE NDMPJobEnvironment ( JobId INTEGER NOT NULL, FileIndex INTEGER NOT NULL, EnvName VARBYTE(256) NOT NULL, EnvValue VARBYTE(256) NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName) ); CREATE TABLE DeviceStats ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, ReadTime BIGINT DEFAULT 0, WriteTime BIGINT DEFAULT 0, ReadBytes BIGINT DEFAULT 0, WriteBytes BIGINT DEFAULT 0, SpoolSize BIGINT DEFAULT 0, NumWaiting INTEGER DEFAULT 0, NumWriters INTEGER DEFAULT 0, MediaId INTEGER DEFAULT 0, VolCatBytes BIGINT DEFAULT 0, VolCatFiles BIGINT DEFAULT 0, VolCatBlocks BIGINT DEFAULT 0 ); CREATE TABLE JobStats ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, JobId INTEGER NOT NULL, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, AlertFlags BIGINT DEFAULT 0 ); \g INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('C', 'Created, not yet running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('R', 'Running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('B', 'Blocked',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('T', 'Completed successfully', 10); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('E', 'Terminated with errors', 25); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('e', 'Non-fatal error',20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('f', 'Fatal error',100); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('D', 'Verify found differences',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('A', 'Canceled by user',90); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('I', 'Incomplete job', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('L', 'Committing data', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('W', 'Terminated with warnings', 20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('l', 'Doing data despooling', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('q', 'Queued waiting for device', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('F', 'Waiting for Client',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('S', 'Waiting for Storage daemon',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('m', 'Waiting for new media',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('M', 'Waiting for media mount',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('s', 'Waiting for storage resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('j', 'Waiting for job resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('c', 'Waiting for client resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('d', 'Waiting on maximum jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('t', 'Waiting on start time',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('p', 'Waiting on higher priority jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('a', 'SD despooling attributes',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('i', 'Doing batch insert file records',15); INSERT INTO Version (VersionId) VALUES (2003); -- Make sure we have appropriate permissions \g bareos-Release-14.2.6/src/cats/ddl/creates/mysql.sql000066400000000000000000000360641263011562700222510ustar00rootroot00000000000000-- -- Note, we use BLOB rather than TEXT because in MySQL, -- BLOBs are identical to TEXT except that BLOB is case -- sensitive in sorts, which is what we want, and TEXT -- is case insensitive. -- CREATE TABLE Filename ( FilenameId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name BLOB NOT NULL, PRIMARY KEY(FilenameId), INDEX (Name(255)) ); CREATE TABLE Path ( PathId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Path BLOB NOT NULL, PRIMARY KEY(PathId), INDEX (Path(255)) ); -- We strongly recommend to avoid the temptation to add new indexes. -- In general, these will cause very significant performance -- problems in other areas. A better approch is to carefully check -- that all your memory configuation parameters are -- suitable for the size of your installation. If you backup -- millions of files, you need to adapt the database memory -- configuration parameters concerning sorting, joining and global -- memory. By default, sort and join parameters are very small -- (sometimes 8Kb), and having sufficient memory specified by those -- parameters is extremely important to run fast. -- In File table -- FileIndex can be 0 for FT_DELETED files -- FileNameId can link to Filename.Name='' for directories CREATE TABLE File ( FileId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, FileIndex INTEGER UNSIGNED DEFAULT 0, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, PathId INTEGER UNSIGNED NOT NULL REFERENCES Path, FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename, DeltaSeq SMALLINT UNSIGNED DEFAULT 0, MarkId INTEGER UNSIGNED DEFAULT 0, LStat TINYBLOB NOT NULL, MD5 TINYBLOB, PRIMARY KEY(FileId), INDEX (JobId), INDEX (JobId, PathId, FilenameId) ); CREATE TABLE RestoreObject ( RestoreObjectId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, ObjectName BLOB NOT NULL, RestoreObject LONGBLOB NOT NULL, PluginName TINYBLOB NOT NULL, ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER UNSIGNED DEFAULT 0, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, ObjectCompression INTEGER DEFAULT 0, PRIMARY KEY(RestoreObjectId), INDEX (JobId) ); -- -- Possibly add one or more of the following indexes -- to the above File table if your Verifies are -- too slow, but they can slow down backups. -- -- INDEX (PathId), -- INDEX (FilenameId), -- CREATE TABLE MediaType ( MediaTypeId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, MediaType TINYBLOB NOT NULL, ReadOnly TINYINT DEFAULT 0, PRIMARY KEY(MediaTypeId) ); CREATE TABLE Storage ( StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name TINYBLOB NOT NULL, AutoChanger TINYINT DEFAULT 0, PRIMARY KEY(StorageId) ); CREATE TABLE Device ( DeviceId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name TINYBLOB NOT NULL, MediaTypeId INTEGER UNSIGNED DEFAULT 0 REFERENCES MediaType, StorageId INTEGER UNSIGNED DEFAULT 0 REFERENCES Storage, DevMounts INTEGER UNSIGNED DEFAULT 0, DevReadBytes BIGINT UNSIGNED DEFAULT 0, DevWriteBytes BIGINT UNSIGNED DEFAULT 0, DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, DevReadTime BIGINT UNSIGNED DEFAULT 0, DevWriteTime BIGINT UNSIGNED DEFAULT 0, DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, CleaningDate DATETIME DEFAULT 0, CleaningPeriod BIGINT UNSIGNED DEFAULT 0, PRIMARY KEY(DeviceId) ); CREATE TABLE Job ( JobId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Job TINYBLOB NOT NULL, Name TINYBLOB NOT NULL, Type BINARY(1) NOT NULL, Level BINARY(1) NOT NULL, ClientId INTEGER DEFAULT 0 REFERENCES Client, JobStatus BINARY(1) NOT NULL, SchedTime DATETIME DEFAULT 0, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, FileSetId INTEGER UNSIGNED DEFAULT 0 REFERENCES FileSet, PriorJobId INTEGER UNSIGNED DEFAULT 0 REFERENCES Job, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0, HasCache TINYINT DEFAULT 0, Reviewed TINYINT DEFAULT 0, Comment BLOB, PRIMARY KEY(JobId), INDEX (Name(128)) ); -- Create a table like Job for long term statistics CREATE TABLE JobHisto ( JobId INTEGER UNSIGNED NOT NULL, Job TINYBLOB NOT NULL, Name TINYBLOB NOT NULL, Type BINARY(1) NOT NULL, Level BINARY(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus BINARY(1) NOT NULL, SchedTime DATETIME DEFAULT 0, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED DEFAULT 0, FileSetId INTEGER UNSIGNED DEFAULT 0, PriorJobId INTEGER UNSIGNED DEFAULT 0, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0, HasCache TINYINT DEFAULT 0, Reviewed TINYINT DEFAULT 0, Comment BLOB, INDEX (JobId), INDEX (StartTime) ); CREATE TABLE Location ( LocationId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Location TINYBLOB NOT NULL, Cost INTEGER DEFAULT 0, Enabled TINYINT, PRIMARY KEY(LocationId) ); CREATE TABLE LocationLog ( LocLogId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Date DATETIME DEFAULT 0, Comment BLOB NOT NULL, MediaId INTEGER UNSIGNED DEFAULT 0 REFERENCES Media, LocationId INTEGER UNSIGNED DEFAULT 0 REFERENCES Location, NewVolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged', 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL, NewEnabled TINYINT, PRIMARY KEY(LocLogId) ); CREATE TABLE FileSet ( FileSetId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, FileSet TINYBLOB NOT NULL, MD5 TINYBLOB, CreateTime DATETIME DEFAULT 0, PRIMARY KEY(FileSetId) ); CREATE TABLE JobMedia ( JobMediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, MediaId INTEGER UNSIGNED NOT NULL REFERENCES Media, FirstIndex INTEGER UNSIGNED DEFAULT 0, LastIndex INTEGER UNSIGNED DEFAULT 0, StartFile INTEGER UNSIGNED DEFAULT 0, EndFile INTEGER UNSIGNED DEFAULT 0, StartBlock INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, VolIndex INTEGER UNSIGNED DEFAULT 0, PRIMARY KEY(JobMediaId), INDEX (JobId, MediaId) ); CREATE TABLE Media ( MediaId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, VolumeName TINYBLOB NOT NULL, Slot INTEGER DEFAULT 0, PoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, MediaType TINYBLOB NOT NULL, MediaTypeId INTEGER UNSIGNED DEFAULT 0 REFERENCES MediaType, LabelType TINYINT DEFAULT 0, FirstWritten DATETIME DEFAULT 0, LastWritten DATETIME DEFAULT 0, LabelDate DATETIME DEFAULT 0, VolJobs INTEGER UNSIGNED DEFAULT 0, VolFiles INTEGER UNSIGNED DEFAULT 0, VolBlocks INTEGER UNSIGNED DEFAULT 0, VolMounts INTEGER UNSIGNED DEFAULT 0, VolBytes BIGINT UNSIGNED DEFAULT 0, VolErrors INTEGER UNSIGNED DEFAULT 0, VolWrites INTEGER UNSIGNED DEFAULT 0, VolCapacityBytes BIGINT UNSIGNED DEFAULT 0, VolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged', 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL, Enabled TINYINT DEFAULT 1, Recycle TINYINT DEFAULT 0, ActionOnPurge TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, MaxVolFiles INTEGER UNSIGNED DEFAULT 0, MaxVolBytes BIGINT UNSIGNED DEFAULT 0, InChanger TINYINT DEFAULT 0, StorageId INTEGER UNSIGNED DEFAULT 0 REFERENCES Storage, DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, MediaAddressing TINYINT DEFAULT 0, VolReadTime BIGINT UNSIGNED DEFAULT 0, VolWriteTime BIGINT UNSIGNED DEFAULT 0, EndFile INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, LocationId INTEGER UNSIGNED DEFAULT 0 REFERENCES Location, RecycleCount INTEGER UNSIGNED DEFAULT 0, MinBlockSize INTEGER UNSIGNED DEFAULT 0, MaxBlockSize INTEGER UNSIGNED DEFAULT 0, InitialWrite DATETIME DEFAULT 0, ScratchPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, RecyclePoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, EncryptionKey TINYBLOB, Comment BLOB, PRIMARY KEY(MediaId), UNIQUE (VolumeName(128)), INDEX (PoolId) ); CREATE TABLE Pool ( PoolId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name TINYBLOB NOT NULL, NumVols INTEGER UNSIGNED DEFAULT 0, MaxVols INTEGER UNSIGNED DEFAULT 0, UseOnce TINYINT DEFAULT 0, UseCatalog TINYINT DEFAULT 0, AcceptAnyVolume TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, MaxVolFiles INTEGER UNSIGNED DEFAULT 0, MaxVolBytes BIGINT UNSIGNED DEFAULT 0, AutoPrune TINYINT DEFAULT 0, Recycle TINYINT DEFAULT 0, ActionOnPurge TINYINT DEFAULT 0, PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch') NOT NULL, LabelType TINYINT DEFAULT 0, LabelFormat TINYBLOB, Enabled TINYINT DEFAULT 1, ScratchPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, RecyclePoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, NextPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool, MinBlockSize INTEGER UNSIGNED DEFAULT 0, MaxBlockSize INTEGER UNSIGNED DEFAULT 0, MigrationHighBytes BIGINT UNSIGNED DEFAULT 0, MigrationLowBytes BIGINT UNSIGNED DEFAULT 0, MigrationTime BIGINT UNSIGNED DEFAULT 0, UNIQUE (Name(128)), PRIMARY KEY (PoolId) ); CREATE TABLE Client ( ClientId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name TINYBLOB NOT NULL, Uname TINYBLOB NOT NULL, /* full uname -a of client */ AutoPrune TINYINT DEFAULT 0, FileRetention BIGINT UNSIGNED DEFAULT 0, JobRetention BIGINT UNSIGNED DEFAULT 0, UNIQUE (Name(128)), PRIMARY KEY(ClientId) ); CREATE TABLE Log ( LogId INTEGER UNSIGNED AUTO_INCREMENT, JobId INTEGER UNSIGNED DEFAULT 0 REFERENCES Job, Time DATETIME DEFAULT 0, LogText BLOB NOT NULL, PRIMARY KEY(LogId), INDEX (JobId) ); CREATE TABLE BaseFiles ( BaseId INTEGER UNSIGNED AUTO_INCREMENT, BaseJobId INTEGER UNSIGNED NOT NULL REFERENCES Job, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, FileId BIGINT UNSIGNED NOT NULL REFERENCES File, FileIndex INTEGER UNSIGNED, PRIMARY KEY(BaseId) ); CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId ); CREATE TABLE UnsavedFiles ( UnsavedId INTEGER UNSIGNED AUTO_INCREMENT, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, PathId INTEGER UNSIGNED NOT NULL REFERENCES Path, FilenameId INTEGER UNSIGNED NOT NULL REFERENCES Filename, PRIMARY KEY (UnsavedId) ); CREATE TABLE Counters ( Counter TINYBLOB NOT NULL, `MinValue` INTEGER DEFAULT 0, `MaxValue` INTEGER DEFAULT 0, CurrentValue INTEGER DEFAULT 0, WrapCounter TINYBLOB NOT NULL, PRIMARY KEY (Counter(128)) ); CREATE TABLE Status ( JobStatus CHAR(1) BINARY NOT NULL, JobStatusLong BLOB, Severity INT, PRIMARY KEY (JobStatus) ); CREATE TABLE PathHierarchy ( PathId integer NOT NULL, PPathId integer NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId integer NOT NULL, JobId integer NOT NULL, Size int8 DEFAULT 0, Files int4 DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE TABLE Version ( VersionId INTEGER UNSIGNED NOT NULL ); CREATE TABLE Quota ( ClientId INT UNSIGNED DEFAULT NULL, GraceTime BIGINT DEFAULT 0, QuotaLimit BIGINT UNSIGNED DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER DEFAULT 0 REFERENCES Client, FileSetId INTEGER UNSIGNED DEFAULT 0 REFERENCES FileSet, FileSystem TINYBLOB NOT NULL, DumpLevel INTEGER NOT NULL, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem(256)) ); CREATE TABLE NDMPJobEnvironment ( JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, FileIndex INTEGER UNSIGNED NOT NULL, EnvName TINYBLOB NOT NULL, EnvValue TINYBLOB NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName(256)) ); CREATE TABLE DeviceStats ( DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, SampleTime DATETIME NOT NULL, ReadTime BIGINT UNSIGNED DEFAULT 0, WriteTime BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, WriteBytes BIGINT UNSIGNED DEFAULT 0, SpoolSize BIGINT UNSIGNED DEFAULT 0, NumWaiting INTEGER DEFAULT 0, NumWriters INTEGER DEFAULT 0, MediaId INTEGER UNSIGNED DEFAULT 0 REFERENCES Media, VolCatBytes BIGINT UNSIGNED DEFAULT 0, VolCatFiles BIGINT UNSIGNED DEFAULT 0, VolCatBlocks BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE JobStats ( DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, SampleTime DATETIME NOT NULL, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, SampleTime DATETIME NOT NULL, AlertFlags BIGINT UNSIGNED DEFAULT 0 ); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('C', 'Created, not yet running', 15), ('R', 'Running', 15), ('B', 'Blocked', 15), ('T', 'Completed successfully', 10), ('E', 'Terminated with errors', 25), ('e', 'Non-fatal error', 20), ('f', 'Fatal error', 100), ('D', 'Verify found differences', 15), ('A', 'Canceled by user', 90), ('I', 'Incomplete job', 15), ('L', 'Committing data', 15), ('W', 'Terminated with warnings', 20), ('l', 'Doing data despooling', 15), ('q', 'Queued waiting for device', 15), ('F', 'Waiting for Client', 15), ('S', 'Waiting for Storage daemon', 15), ('m', 'Waiting for new media', 15), ('M', 'Waiting for media mount', 15), ('s', 'Waiting for storage resource', 15), ('j', 'Waiting for job resource', 15), ('c', 'Waiting for client resource', 15), ('d', 'Waiting on maximum jobs', 15), ('t', 'Waiting on start time', 15), ('p', 'Waiting on higher priority jobs', 15), ('i', 'Doing batch insert file records', 15), ('a', 'SD despooling attributes', 15); -- Initialize Version -- DELETE should not be required, -- but prevents errors if create script is called multiple times DELETE FROM Version WHERE VersionId<=2003; INSERT INTO Version (VersionId) VALUES (2003); bareos-Release-14.2.6/src/cats/ddl/creates/postgresql.sql000066400000000000000000000427271263011562700233120ustar00rootroot00000000000000CREATE TABLE Filename ( FilenameId SERIAL NOT NULL, Name TEXT NOT NULL, PRIMARY KEY (FilenameId) ); ALTER TABLE Filename ALTER COLUMN Name SET STATISTICS 1000; CREATE UNIQUE INDEX filename_name_idx ON Filename (Name); CREATE TABLE Path ( PathId SERIAL NOT NULL, Path TEXT NOT NULL, PRIMARY KEY (PathId) ); ALTER TABLE Path ALTER COLUMN Path SET STATISTICS 1000; CREATE UNIQUE INDEX path_name_idx ON Path (Path); -- We strongly recommend to avoid the temptation to add new indexes. -- In general, these will cause very significant performance -- problems in other areas. A better approch is to carefully check -- that all your memory configuation parameters are -- suitable for the size of your installation. If you backup -- millions of files, you need to adapt the database memory -- configuration parameters concerning sorting, joining and global -- memory. By DEFAULT, sort and join parameters are very small -- (sometimes 8Kb), and having sufficient memory specified by those -- parameters is extremely important to run fast. -- In File table -- FileIndex can be 0 for FT_DELETED files -- FileNameId can link to Filename.Name='' for directories CREATE TABLE File ( FileId BIGSERIAL NOT NULL, FileIndex INTEGER NOT NULL DEFAULT 0, JobId INTEGER NOT NULL, PathId INTEGER NOT NULL, FilenameId INTEGER NOT NULL, DeltaSeq SMALLINT NOT NULL DEFAULT 0, MarkId INTEGER NOT NULL DEFAULT 0, LStat TEXT NOT NULL, Md5 TEXT NOT NULL, PRIMARY KEY (FileId) ); CREATE INDEX file_jpfid_idx ON File (JobId, PathId, FilenameId); CREATE INDEX file_jobid_idx ON File (JobId); -- -- Add this if you have a good number of job -- that run at the same time -- ALTER SEQUENCE file_fileid_seq CACHE 1000; -- -- Possibly add one or more of the following indexes -- if your Verifies are too slow, but they can slow down -- backups. -- -- CREATE INDEX file_pathid_idx ON file(pathid); -- CREATE INDEX file_filenameid_idx ON file(filenameid); CREATE TABLE RestoreObject ( RestoreObjectId SERIAL NOT NULL, ObjectName TEXT NOT NULL, RestoreObject BYTEA NOT NULL, PluginName TEXT NOT NULL, ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER DEFAULT 0, JobId INTEGER, ObjectCompression INTEGER DEFAULT 0, PRIMARY KEY(RestoreObjectId) ); CREATE INDEX restore_jobid_idx ON RestoreObject(JobId); CREATE TABLE Job ( JobId SERIAL NOT NULL, Job TEXT NOT NULL, Name TEXT NOT NULL, Type CHAR(1) NOT NULL, Level CHAR(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus CHAR(1) NOT NULL, SchedTime TIMESTAMP WITHOUT TIME ZONE, StartTime TIMESTAMP WITHOUT TIME ZONE, EndTime TIMESTAMP WITHOUT TIME ZONE, RealEndTime TIMESTAMP WITHOUT TIME ZONE, JobTDate BIGINT DEFAULT 0, VolSessionId INTEGER DEFAULT 0, volSessionTime INTEGER DEFAULT 0, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0, ReadBytes BIGINT DEFAULT 0, JobErrors INTEGER DEFAULT 0, JobMissingFiles INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, FilesetId INTEGER DEFAULT 0, PriorJobid INTEGER DEFAULT 0, PurgedFiles SMALLINT DEFAULT 0, HasBase SMALLINT DEFAULT 0, HasCache SMALLINT DEFAULT 0, Reviewed SMALLINT DEFAULT 0, Comment TEXT, PRIMARY KEY (JobId) ); CREATE INDEX job_name_idx ON job (Name); -- Create a table like Job for long term statistics CREATE TABLE JobHisto (LIKE Job); CREATE INDEX jobhisto_idx ON JobHisto (StartTime); CREATE TABLE Location ( LocationId SERIAL NOT NULL, Location TEXT NOT NULL, Cost INTEGER DEFAULT 0, Enabled SMALLINT, PRIMARY KEY (LocationId) ); CREATE TABLE Fileset ( FileSetId SERIAL NOT NULL, Fileset TEXT NOT NULL, Md5 TEXT NOT NULL, CreateTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (filesetid) ); CREATE INDEX fileset_name_idx ON fileset (fileset); CREATE TABLE JobMedia ( JobMediaId SERIAL NOT NULL, JobId INTEGER NOT NULL, MediaId INTEGER NOT NULL, FirstIndex INTEGER DEFAULT 0, LastIndex INTEGER DEFAULT 0, StartFile INTEGER DEFAULT 0, EndFile INTEGER DEFAULT 0, StartBlock BIGINT DEFAULT 0, EndBlock BIGINT DEFAULT 0, VolIndex INTEGER DEFAULT 0, PRIMARY KEY (jobmediaid) ); CREATE INDEX job_media_job_id_media_id_idx ON jobmedia (JobId, MediaId); CREATE TABLE Media ( MediaId SERIAL NOT NULL, VolumeName TEXT NOT NULL, Slot INTEGER DEFAULT 0, PoolId INTEGER DEFAULT 0, MediaType TEXT NOT NULL, MediaTypeId INTEGER DEFAULT 0, LabelType INTEGER DEFAULT 0, FirstWritten TIMESTAMP WITHOUT TIME ZONE, LastWritten TIMESTAMP WITHOUT TIME ZONE, LabelDate TIMESTAMP WITHOUT TIME ZONE, VolJobs INTEGER DEFAULT 0, VolFiles INTEGER DEFAULT 0, VolBlocks INTEGER DEFAULT 0, VolMounts INTEGER DEFAULT 0, VolBytes BIGINT DEFAULT 0, VolErrors INTEGER DEFAULT 0, VolWrites INTEGER DEFAULT 0, VolCapacityBytes BIGINT DEFAULT 0, VolStatus TEXT NOT NULL CHECK (VolStatus IN ('Full', 'Archive', 'Append', 'Recycle', 'Purged', 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning', 'Scratch')), Enabled SMALLINT DEFAULT 1, Recycle SMALLINT DEFAULT 0, ActionOnPurge SMALLINT DEFAULT 0, VolRetention BIGINT DEFAULT 0, VolUseDuration BIGINT DEFAULT 0, MaxVolJobs INTEGER DEFAULT 0, MaxVolFiles INTEGER DEFAULT 0, MaxVolBytes BIGINT DEFAULT 0, InChanger SMALLINT DEFAULT 0, StorageId INTEGER DEFAULT 0, DeviceId INTEGER DEFAULT 0, MediaAddressing SMALLINT DEFAULT 0, VolReadTime BIGINT DEFAULT 0, VolWriteTime BIGINT DEFAULT 0, EndFile INTEGER DEFAULT 0, EndBlock BIGINT DEFAULT 0, LocationId INTEGER DEFAULT 0, RecycleCount INTEGER DEFAULT 0, MinBlockSize INTEGER DEFAULT 0, MaxBlockSize INTEGER DEFAULT 0, InitialWrite TIMESTAMP WITHOUT TIME ZONE, ScratchPoolId INTEGER DEFAULT 0, RecyclePoolId INTEGER DEFAULT 0, EncryptionKey TEXT, Comment TEXT, PRIMARY KEY (MediaId) ); CREATE UNIQUE INDEX media_volumename_id ON Media (VolumeName); CREATE INDEX media_poolid_idx ON Media (PoolId); CREATE TABLE MediaType ( MediaTypeId SERIAL, MediaType TEXT NOT NULL, ReadOnly INTEGER DEFAULT 0, PRIMARY KEY(MediaTypeId) ); CREATE TABLE Storage ( StorageId SERIAL, Name TEXT NOT NULL, AutoChanger INTEGER DEFAULT 0, PRIMARY KEY(StorageId) ); CREATE TABLE Device ( DeviceId SERIAL, Name TEXT NOT NULL, MediaTypeId INTEGER NOT NULL, StorageId INTEGER NOT NULL, DevMounts INTEGER NOT NULL DEFAULT 0, DevReadBytes BIGINT NOT NULL DEFAULT 0, DevWriteBytes BIGINT NOT NULL DEFAULT 0, DevReadBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, DevWriteBytesSinceCleaning BIGINT NOT NULL DEFAULT 0, DevReadTime BIGINT NOT NULL DEFAULT 0, DevWriteTime BIGINT NOT NULL DEFAULT 0, DevReadTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, DevWriteTimeSinceCleaning BIGINT NOT NULL DEFAULT 0, CleaningDate TIMESTAMP WITHOUT TIME ZONE, CleaningPeriod BIGINT NOT NULL DEFAULT 0, PRIMARY KEY(DeviceId) ); CREATE TABLE Pool ( PoolId SERIAL NOT NULL, Name TEXT NOT NULL, NumVols INTEGER DEFAULT 0, MaxVols INTEGER DEFAULT 0, UseOnce SMALLINT DEFAULT 0, UseCatalog SMALLINT DEFAULT 0, AcceptAnyVolume SMALLINT DEFAULT 0, VolRetention BIGINT DEFAULT 0, VolUseDuration BIGINT DEFAULT 0, MaxVolJobs INTEGER DEFAULT 0, MaxVolFiles INTEGER DEFAULT 0, MaxVolBytes BIGINT DEFAULT 0, AutoPrune SMALLINT DEFAULT 0, Recycle SMALLINT DEFAULT 0, ActionOnPurge SMALLINT DEFAULT 0, PoolType TEXT CHECK (PoolType IN ('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch')), LabelType INTEGER DEFAULT 0, LabelFormat TEXT NOT NULL, Enabled SMALLINT DEFAULT 1, ScratchPoolId INTEGER DEFAULT 0, RecyclePoolId INTEGER DEFAULT 0, NextPoolId INTEGER DEFAULT 0, MinBlockSize INTEGER DEFAULT 0, MaxBlockSize INTEGER DEFAULT 0, MigrationHighBytes BIGINT DEFAULT 0, MigrationLowBytes BIGINT DEFAULT 0, MigrationTime BIGINT DEFAULT 0, PRIMARY KEY (PoolId) ); CREATE INDEX pool_name_idx ON Pool (Name); CREATE TABLE Client ( ClientId SERIAL NOT NULL, Name TEXT NOT NULL, UName TEXT NOT NULL, AutoPrune SMALLINT DEFAULT 0, FileRetention BIGINT DEFAULT 0, JobRetention BIGINT DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE UNIQUE INDEX client_name_idx ON Client (Name); CREATE TABLE Log ( LogId SERIAL NOT NULL, JobId INTEGER NOT NULL, Time TIMESTAMP WITHOUT TIME ZONE, LogText TEXT NOT NULL, PRIMARY KEY (LogId) ); CREATE INDEX log_name_idx ON Log (JobId); CREATE TABLE LocationLog ( LocLogId SERIAL NOT NULL, Date TIMESTAMP WITHOUT TIME ZONE, Comment TEXT NOT NULL, MediaId INTEGER DEFAULT 0, LocationId INTEGER DEFAULT 0, NewVolStatus TEXT NOT NULL CHECK (NewVolStatus IN ('Full', 'Archive', 'Append', 'Recycle', 'Purged', 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning', 'Scratch')), newenabled SMALLINT, PRIMARY KEY(LocLogId) ); CREATE TABLE counters ( Counter TEXT NOT NULL, MinValue INTEGER DEFAULT 0, MaxValue INTEGER DEFAULT 0, CurrentValue INTEGER DEFAULT 0, wrapcounter TEXT NOT NULL, PRIMARY KEY (Counter) ); CREATE TABLE basefiles ( BaseId SERIAL NOT NULL, JobId INTEGER NOT NULL, FileId BIGINT NOT NULL, FileIndex INTEGER, BaseJobId INTEGER, PRIMARY KEY (BaseId) ); CREATE INDEX basefiles_jobid_idx ON BaseFiles (JobId); CREATE TABLE UnsavedFiles ( UnsavedId INTEGER NOT NULL, JobId INTEGER NOT NULL, PathId INTEGER NOT NULL, FilenameId INTEGER NOT NULL, PRIMARY KEY (UnsavedId) ); CREATE TABLE PathHierarchy ( PathId INTEGER NOT NULL, PPathId INTEGER NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId INTEGER NOT NULL, JobId INTEGER NOT NULL, Size BIGINT DEFAULT 0, Files INTEGER DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE TABLE version ( VersionId INTEGER NOT NULL ); CREATE TABLE Status ( JobStatus CHAR(1) NOT NULL, JobStatusLong TEXT, Severity INTEGER, PRIMARY KEY (JobStatus) ); CREATE TABLE Quota ( ClientId INTEGER NOT NULL, GraceTime BIGINT DEFAULT 0, QuotaLimit BIGINT DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER NOT NULL, FilesetId INTEGER DEFAULT 0, FileSystem TEXT NOT NULL, DumpLevel INTEGER NOT NULL, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem) ); CREATE TABLE NDMPJobEnvironment ( JobId INTEGER NOT NULL, FileIndex INTEGER NOT NULL, EnvName TEXT NOT NULL, EnvValue TEXT NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName) ); CREATE TABLE DeviceStats ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, ReadTime BIGINT NOT NULL DEFAULT 0, WriteTime BIGINT NOT NULL DEFAULT 0, ReadBytes BIGINT DEFAULT 0, WriteBytes BIGINT DEFAULT 0, SpoolSize BIGINT DEFAULT 0, NumWaiting SMALLINT DEFAULT 0, NumWriters SMALLINT DEFAULT 0, MediaId INTEGER NOT NULL, VolCatBytes BIGINT DEFAULT 0, VolCatFiles BIGINT DEFAULT 0, VolCatBlocks BIGINT DEFAULT 0 ); CREATE TABLE JobStats ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, JobId INTEGER NOT NULL, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, AlertFlags BIGINT DEFAULT 0 ); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('C', 'Created, not yet running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('R', 'Running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('B', 'Blocked',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('T', 'Completed successfully', 10); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('E', 'Terminated with errors', 25); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('e', 'Non-fatal error',20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('f', 'Fatal error',100); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('D', 'Verify found differences',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('A', 'Canceled by user',90); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('I', 'Incomplete job', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('L', 'Committing data', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('W', 'Terminated with warnings', 20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('l', 'Doing data despooling', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('q', 'Queued waiting for device', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('F', 'Waiting for Client',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('S', 'Waiting for Storage daemon',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('m', 'Waiting for new media',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('M', 'Waiting for media mount',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('s', 'Waiting for storage resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('j', 'Waiting for job resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('c', 'Waiting for client resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('d', 'Waiting on maximum jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('t', 'Waiting on start time',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('p', 'Waiting on higher priority jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('a', 'SD despooling attributes',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('i', 'Doing batch insert file records',15); -- Initialize Version -- DELETE should not be required, -- but prevents errors if create script is called multiple times DELETE FROM Version WHERE VersionId<=2003; INSERT INTO Version (VersionId) VALUES (2003); -- Make sure we have appropriate permissions bareos-Release-14.2.6/src/cats/ddl/creates/sqlite3.sql000066400000000000000000000363751263011562700224750ustar00rootroot00000000000000CREATE TABLE Filename ( FilenameId INTEGER, Name TEXT DEFAULT '', PRIMARY KEY(FilenameId) ); CREATE INDEX inx1 ON Filename (Name); CREATE TABLE Path ( PathId INTEGER, Path TEXT DEFAULT '', PRIMARY KEY(PathId) ); CREATE INDEX inx2 ON Path (Path); -- In File table -- FileIndex can be 0 for FT_DELETED files -- FileNameId can link to Filename.Name='' for directories CREATE TABLE File ( FileId INTEGER, FileIndex INTEGER UNSIGNED NOT NULL, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, PathId INTEGER UNSIGNED REFERENCES Path NOT NULL, FilenameId INTEGER UNSIGNED REFERENCES Filename NOT NULL, DeltaSeq SMALLINT UNSIGNED DEFAULT 0, MarkId INTEGER UNSIGNED DEFAULT 0, LStat VARCHAR(255) NOT NULL, MD5 VARCHAR(255) NOT NULL, PRIMARY KEY(FileId) ); CREATE INDEX inx3 ON File (JobId); CREATE INDEX file_jpf_idx ON File (JobId, PathId, FilenameId); -- -- Possibly add one or more of the following indexes -- if your Verifies are too slow. -- -- CREATE INDEX inx4 ON File (PathId); -- CREATE INDEX inx5 ON File (FileNameId); CREATE TABLE RestoreObject ( RestoreObjectId INTEGER, ObjectName TEXT DEFAULT '', RestoreObject TEXT DEFAULT '', PluginName TEXT DEFAULT '', ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER UNSIGNED DEFAULT 0, ObjectCompression INTEGER DEFAULT 0, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, PRIMARY KEY(RestoreObjectId) ); CREATE INDEX restore_jobid_idx ON RestoreObject (JobId); CREATE TABLE Job ( JobId INTEGER, Job VARCHAR(128) NOT NULL, Name VARCHAR(128) NOT NULL, Type CHAR(1) NOT NULL, Level CHAR(1) NOT NULL, ClientId INTEGER REFERENCES Client DEFAULT 0, JobStatus CHAR(1) NOT NULL, SchedTime DATETIME NOT NULL, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0, PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0, HasCache TINYINT DEFAULT 0, Reviewed TINYINT DEFAULT 0, Comment TEXT, PRIMARY KEY(JobId) ); CREATE INDEX inx6 ON Job (Name); -- Create a table like Job for long term statistics CREATE TABLE JobHisto ( JobId INTEGER, Job VARCHAR(128) NOT NULL, Name VARCHAR(128) NOT NULL, Type CHAR(1) NOT NULL, Level CHAR(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus CHAR(1) NOT NULL, SchedTime DATETIME NOT NULL, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED DEFAULT 0, FileSetId INTEGER UNSIGNED DEFAULT 0, PriorJobId INTEGER UNSIGNED DEFAULT 0, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0, HasCache TINYINT DEFAULT 0, Reviewed TINYINT DEFAULT 0, Comment TEXT ); CREATE INDEX inx61 ON JobHisto (StartTime); CREATE TABLE Location ( LocationId INTEGER, Location TEXT NOT NULL, Cost INTEGER DEFAULT 0, Enabled TINYINT, PRIMARY KEY(LocationId) ); CREATE TABLE LocationLog ( LocLogId INTEGER, Date DATETIME NOT NULL, Comment TEXT NOT NULL, MediaId INTEGER UNSIGNED REFERENCES Media DEFAULT 0, LocationId INTEGER UNSIGNED REFERENCES LocationId DEFAULT 0, NewVolStatus VARCHAR(20) NOT NULL, NewEnabled TINYINT NOT NULL, PRIMARY KEY(LocLogId) ); CREATE TABLE Log ( LogId INTEGER, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, Time DATETIME NOT NULL, LogText TEXT NOT NULL, PRIMARY KEY(LogId) ); CREATE INDEX LogInx1 ON Log (JobId); CREATE TABLE FileSet ( FileSetId INTEGER, FileSet VARCHAR(128) NOT NULL, MD5 VARCHAR(25) NOT NULL, CreateTime DATETIME DEFAULT 0, PRIMARY KEY(FileSetId) ); CREATE TABLE JobMedia ( JobMediaId INTEGER, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, MediaId INTEGER UNSIGNED REFERENCES Media NOT NULL, FirstIndex INTEGER UNSIGNED NOT NULL, LastIndex INTEGER UNSIGNED NOT NULL, StartFile INTEGER UNSIGNED DEFAULT 0, EndFile INTEGER UNSIGNED DEFAULT 0, StartBlock INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, VolIndex INTEGER UNSIGNED DEFAULT 0, PRIMARY KEY(JobMediaId) ); CREATE INDEX inx7 ON JobMedia (JobId, MediaId); CREATE TABLE Media ( MediaId INTEGER, VolumeName VARCHAR(128) NOT NULL, Slot INTEGER DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, MediaType VARCHAR(128) NOT NULL, MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0, LabelType TINYINT DEFAULT 0, FirstWritten DATETIME DEFAULT 0, LastWritten DATETIME DEFAULT 0, LabelDate DATETIME DEFAULT 0, VolJobs INTEGER UNSIGNED DEFAULT 0, VolFiles INTEGER UNSIGNED DEFAULT 0, VolBlocks INTEGER UNSIGNED DEFAULT 0, VolMounts INTEGER UNSIGNED DEFAULT 0, VolBytes BIGINT UNSIGNED DEFAULT 0, VolErrors INTEGER UNSIGNED DEFAULT 0, VolWrites INTEGER UNSIGNED DEFAULT 0, VolCapacityBytes BIGINT UNSIGNED DEFAULT 0, VolStatus VARCHAR(20) NOT NULL, Enabled TINYINT DEFAULT 1, Recycle TINYINT DEFAULT 0, ActionOnPurge TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, MaxVolFiles INTEGER UNSIGNED DEFAULT 0, MaxVolBytes BIGINT UNSIGNED DEFAULT 0, InChanger TINYINT DEFAULT 0, StorageId INTEGER UNSIGNED REFERENCES Storage DEFAULT 0, DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, MediaAddressing TINYINT DEFAULT 0, VolReadTime BIGINT UNSIGNED DEFAULT 0, VolWriteTime BIGINT UNSIGNED DEFAULT 0, EndFile INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, LocationId INTEGER UNSIGNED REFERENCES Location DEFAULT 0, RecycleCount INTEGER UNSIGNED DEFAULT 0, MinBlockSize INTEGER UNSIGNED DEFAULT 0, MaxBlockSize INTEGER UNSIGNED DEFAULT 0, InitialWrite DATETIME DEFAULT 0, ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, EncryptionKey VARCHAR(128), Comment TEXT, PRIMARY KEY(MediaId) ); CREATE INDEX inx8 ON Media (PoolId); CREATE TABLE MediaType ( MediaTypeId INTEGER, MediaType VARCHAR(128) NOT NULL, ReadOnly TINYINT DEFAULT 0, PRIMARY KEY(MediaTypeId) ); CREATE TABLE Storage ( StorageId INTEGER, Name VARCHAR(128) NOT NULL, AutoChanger TINYINT DEFAULT 0, PRIMARY KEY(StorageId) ); CREATE TABLE Device ( DeviceId INTEGER, Name VARCHAR(128) NOT NULL, MediaTypeId INTEGER UNSIGNED REFERENCES MediaType NOT NULL, StorageId INTEGER UNSIGNED REFERENCES Storage, DevMounts INTEGER UNSIGNED DEFAULT 0, DevReadBytes BIGINT UNSIGNED DEFAULT 0, DevWriteBytes BIGINT UNSIGNED DEFAULT 0, DevReadBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, DevWriteBytesSinceCleaning BIGINT UNSIGNED DEFAULT 0, DevReadTime BIGINT UNSIGNED DEFAULT 0, DevWriteTime BIGINT UNSIGNED DEFAULT 0, DevReadTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, DevWriteTimeSinceCleaning BIGINT UNSIGNED DEFAULT 0, CleaningDate DATETIME DEFAULT 0, CleaningPeriod BIGINT UNSIGNED DEFAULT 0, PRIMARY KEY(DeviceId) ); CREATE TABLE Pool ( PoolId INTEGER, Name VARCHAR(128) NOT NULL, NumVols INTEGER UNSIGNED DEFAULT 0, MaxVols INTEGER UNSIGNED DEFAULT 0, UseOnce TINYINT DEFAULT 0, UseCatalog TINYINT DEFAULT 1, AcceptAnyVolume TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, MaxVolFiles INTEGER UNSIGNED DEFAULT 0, MaxVolBytes BIGINT UNSIGNED DEFAULT 0, AutoPrune TINYINT DEFAULT 0, Recycle TINYINT DEFAULT 0, ActionOnPurge TINYINT DEFAULT 0, PoolType VARCHAR(20) NOT NULL, LabelType TINYINT DEFAULT 0, LabelFormat VARCHAR(128) NOT NULL, Enabled TINYINT DEFAULT 1, ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, NextPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, MinBlockSize INTEGER UNSIGNED DEFAULT 0, MaxBlockSize INTEGER UNSIGNED DEFAULT 0, MigrationHighBytes BIGINT UNSIGNED DEFAULT 0, MigrationLowBytes BIGINT UNSIGNED DEFAULT 0, MigrationTime BIGINT UNSIGNED DEFAULT 0, UNIQUE (Name), PRIMARY KEY (PoolId) ); CREATE TABLE Client ( ClientId INTEGER, Name VARCHAR(128) NOT NULL, Uname VARCHAR(255) NOT NULL, -- uname -a field AutoPrune TINYINT DEFAULT 0, FileRetention BIGINT UNSIGNED DEFAULT 0, JobRetention BIGINT UNSIGNED DEFAULT 0, UNIQUE (Name), PRIMARY KEY(ClientId) ); CREATE TABLE BaseFiles ( BaseId INTEGER, BaseJobId INTEGER UNSIGNED REFERENCES Job NOT NULL, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, FileId INTEGER UNSIGNED REFERENCES File NOT NULL, FileIndex INTEGER UNSIGNED, PRIMARY KEY(BaseId) ); CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId ); CREATE TABLE UnsavedFiles ( UnsavedId INTEGER, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, PathId INTEGER UNSIGNED REFERENCES Path NOT NULL, FilenameId INTEGER UNSIGNED REFERENCES Filename NOT NULL, PRIMARY KEY (UnsavedId) ); CREATE TABLE NextId ( id INTEGER UNSIGNED DEFAULT 0, TableName TEXT NOT NULL, PRIMARY KEY (TableName) ); -- Initialize JobId to start at 1 INSERT INTO NextId (id, TableName) VALUES (1, 'Job'); CREATE TABLE Version ( VersionId INTEGER UNSIGNED NOT NULL ); CREATE TABLE Counters ( Counter TEXT NOT NULL, MinValue INTEGER DEFAULT 0, MaxValue INTEGER DEFAULT 0, CurrentValue INTEGER DEFAULT 0, WrapCounter TEXT NOT NULL, PRIMARY KEY (Counter) ); CREATE TABLE PathHierarchy ( PathId integer NOT NULL, PPathId integer NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId integer NOT NULL, JobId integer NOT NULL, Size int8 DEFAULT 0, Files int4 DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE TABLE Status ( JobStatus CHAR(1) NOT NULL, JobStatusLong BLOB, Severity INT, PRIMARY KEY (JobStatus) ); CREATE TABLE Quota ( ClientId INTEGER REFERENCES Client DEFAULT 0, GraceTime INTEGER UNSIGNED DEFAULT 0, QuotaLimit BIGINT UNSIGNED DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER REFERENCES Client DEFAULT 0, FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0, FileSystem TEXT DEFAULT '', DumpLevel INTEGER UNSIGNED DEFAULT 0, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem) ); CREATE TABLE NDMPJobEnvironment ( JobId integer NOT NULL, FileIndex INTEGER UNSIGNED NOT NULL, EnvName TEXT NOT NULL, EnvValue TEXT NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName) ); CREATE TABLE DeviceStats ( DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, SampleTime DATETIME NOT NULL, ReadTime BIGINT UNSIGNED DEFAULT 0, WriteTime BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, WriteBytes BIGINT UNSIGNED DEFAULT 0, SpoolSize BIGINT UNSIGNED DEFAULT 0, NumWaiting INTEGER DEFAULT 0, NumWriters INTEGER DEFAULT 0, MediaId INTEGER UNSIGNED REFERENCES Media DEFAULT 0, VolCatBytes BIGINT UNSIGNED DEFAULT 0, VolCatFiles BIGINT UNSIGNED DEFAULT 0, VolCatBlocks BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE JobStats ( DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, SampleTime DATETIME NOT NULL, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, SampleTime DATETIME NOT NULL, AlertFlags BIGINT UNSIGNED DEFAULT 0 ); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('C', 'Created, not yet running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('R', 'Running',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('B', 'Blocked',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('T', 'Completed successfully', 10); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('E', 'Terminated with errors', 25); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('e', 'Non-fatal error',20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('f', 'Fatal error',100); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('D', 'Verify found differences',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('A', 'Canceled by user',90); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('I', 'Incomplete job', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('L', 'Committing data', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('W', 'Terminated with warnings', 20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('l', 'Doing data despooling', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('q', 'Queued waiting for device', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('F', 'Waiting for Client',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('S', 'Waiting for Storage daemon',15); INSERT INTO Status (JobStatus,JobStatusLong) VALUES ('m', 'Waiting for new media'); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('M', 'Waiting for media mount',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('s', 'Waiting for storage resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('j', 'Waiting for job resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('c', 'Waiting for client resource',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('d', 'Waiting on maximum jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('t', 'Waiting on start time',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('p', 'Waiting on higher priority jobs',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('a', 'SD despooling attributes',15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('i', 'Doing batch insert file records',15); -- Initialize Version -- DELETE should not be required, -- but prevents errors if create script is called multiple times DELETE FROM Version WHERE VersionId<=2003; INSERT INTO Version (VersionId) VALUES (2003); PRAGMA default_cache_size = 100000; PRAGMA synchronous = NORMAL; bareos-Release-14.2.6/src/cats/ddl/drops/000077500000000000000000000000001263011562700200535ustar00rootroot00000000000000bareos-Release-14.2.6/src/cats/ddl/drops/ingres.sql000066400000000000000000000021431263011562700220630ustar00rootroot00000000000000DROP TABLE Filename; DROP TABLE Path; DROP TABLE File; DROP TABLE RestoreObject; DROP TABLE Job; DROP TABLE JobHisto; DROP TABLE Location; DROP TABLE Fileset; DROP TABLE JobMedia; DROP TABLE Media; DROP TABLE MediaType; DROP TABLE Storage; DROP TABLE Device; DROP TABLE Pool; DROP TABLE Client; DROP TABLE Log; DROP TABLE LocationLog; DROP TABLE Counters; DROP TABLE BaseFiles; DROP TABLE UnsavedFiles; DROP TABLE PathHierarchy; DROP TABLE PathVisibility; DROP TABLE Version; DROP TABLE Status; DROP TABLE Quota; DROP TABLE NDMPLevelMap; DROP TABLE NDMPJobEnvironment; DROP TABLE DeviceStats; DROP TABLE JobStats; DROP TABLE TapeAlerts; DROP SEQUENCE Filename_Seq; DROP SEQUENCE Path_Seq; DROP SEQUENCE File_Seq; DROP SEQUENCE RestoreObject_Seq; DROP SEQUENCE Job_Seq; DROP SEQUENCE JobHisto_Seq; DROP SEQUENCE Location_Seq; DROP SEQUENCE Fileset_Seq; DROP SEQUENCE JobMedia_Seq; DROP SEQUENCE Media_Seq; DROP SEQUENCE MediaType_Seq; DROP SEQUENCE Storage_Seq; DROP SEQUENCE Device_Seq; DROP SEQUENCE Pool_Seq; DROP SEQUENCE Client_Seq; DROP SEQUENCE Log_Seq; DROP SEQUENCE LocationLog_Seq; DROP SEQUENCE BaseFiles_Seq; \g bareos-Release-14.2.6/src/cats/ddl/drops/mysql.sql000066400000000000000000000020431263011562700217400ustar00rootroot00000000000000DROP TABLE IF EXISTS Filename; DROP TABLE IF EXISTS Path; DROP TABLE IF EXISTS LongName; DROP TABLE IF EXISTS Device; DROP TABLE IF EXISTS Storage; DROP TABLE IF EXISTS MediaType; DROP TABLE IF EXISTS File; DROP TABLE IF EXISTS Client; DROP TABLE IF EXISTS Job; DROP TABLE IF EXISTS JobHisto; DROP TABLE IF EXISTS Media; DROP TABLE IF EXISTS JobMedia; DROP TABLE IF EXISTS Pool; DROP TABLE IF EXISTS MultiVolume; DROP TABLE IF EXISTS FileSave; DROP TABLE IF EXISTS FileSet; DROP TABLE IF EXISTS Version; DROP TABLE IF EXISTS Counters; DROP TABLE IF EXISTS BaseFiles; DROP TABLE IF EXISTS UnsavedFiles; DROP TABLE IF EXISTS Status; DROP TABLE IF EXISTS Quota; DROP TABLE IF EXISTS NDMPLevelMap; DROP TABLE IF EXISTS NDMPJobEnvironment; DROP TABLE IF EXISTS DeviceStats; DROP TABLE IF EXISTS JobStats; DROP TABLE IF EXISTS TapeAlerts; DROP TABLE IF EXISTS MAC; DROP TABLE IF EXISTS Log; DROP TABLE IF EXISTS Location; DROP TABLE IF EXISTS LocationLog; DROP TABLE IF EXISTS PathVisibility; DROP TABLE IF EXISTS PathHierarchy; DROP TABLE IF EXISTS RestoreObject; bareos-Release-14.2.6/src/cats/ddl/drops/postgresql.sql000066400000000000000000000016511263011562700230020ustar00rootroot00000000000000DROP TABLE IF EXISTS unsavedfiles; DROP TABLE IF EXISTS basefiles; DROP TABLE IF EXISTS jobmedia; DROP TABLE IF EXISTS file; DROP TABLE IF EXISTS job; DROP TABLE IF EXISTS jobhisto; DROP TABLE IF EXISTS media; DROP TABLE IF EXISTS client; DROP TABLE IF EXISTS pool; DROP TABLE IF EXISTS fileset; DROP TABLE IF EXISTS path; DROP TABLE IF EXISTS filename; DROP TABLE IF EXISTS counters; DROP TABLE IF EXISTS version; DROP TABLE IF EXISTS Device; DROP TABLE IF EXISTS Storage; DROP TABLE IF EXISTS MediaType; DROP TABLE IF EXISTS Status; DROP TABLE IF EXISTS Quota; DROP TABLE IF EXISTS NDMPLevelMap; DROP TABLE IF EXISTS NDMPJobEnvironment; DROP TABLE IF EXISTS DeviceStats; DROP TABLE IF EXISTS JobStats; DROP TABLE IF EXISTS TapeAlerts; DROP TABLE IF EXISTS log; DROP TABLE IF EXISTS Location; DROP TABLE IF EXISTS locationlog; DROP TABLE IF EXISTS PathVisibility; DROP TABLE IF EXISTS PathHierarchy; DROP TABLE IF EXISTS RestoreObject; bareos-Release-14.2.6/src/cats/ddl/grants/000077500000000000000000000000001263011562700202225ustar00rootroot00000000000000bareos-Release-14.2.6/src/cats/ddl/grants/ingres-readonly.sql000066400000000000000000000025451263011562700240530ustar00rootroot00000000000000-- read-only access for third-party applications -- for tables GRANT SELECT ON TABLE Filename TO @DB_USER@; GRANT SELECT ON TABLE Path TO @DB_USER@; GRANT SELECT ON TABLE File TO @DB_USER@; GRANT SELECT ON TABLE RestoreObject TO @DB_USER@; GRANT SELECT ON TABLE Job TO @DB_USER@; GRANT SELECT ON TABLE JobHisto TO @DB_USER@; GRANT SELECT ON TABLE Location TO @DB_USER@; GRANT SELECT ON TABLE Fileset TO @DB_USER@; GRANT SELECT ON TABLE JobMedia TO @DB_USER@; GRANT SELECT ON TABLE Media TO @DB_USER@; GRANT SELECT ON TABLE MediaType TO @DB_USER@; GRANT SELECT ON TABLE Storage TO @DB_USER@; GRANT SELECT ON TABLE Device TO @DB_USER@; GRANT SELECT ON TABLE Pool TO @DB_USER@; GRANT SELECT ON TABLE Client TO @DB_USER@; GRANT SELECT ON TABLE Log TO @DB_USER@; GRANT SELECT ON TABLE LocationLog TO @DB_USER@; GRANT SELECT ON TABLE Counters TO @DB_USER@; GRANT SELECT ON TABLE BaseFiles TO @DB_USER@; GRANT SELECT ON TABLE UnsavedFiles TO @DB_USER@; GRANT SELECT ON TABLE PathHierarchy TO @DB_USER@; GRANT SELECT ON TABLE PathVisibility TO @DB_USER@; GRANT SELECT ON TABLE Version TO @DB_USER@; GRANT SELECT ON TABLE Status TO @DB_USER@; GRANT SELECT ON TABLE NDMPLevelMap TO @DB_USER@; GRANT SELECT ON TABLE NDMPJobEnvironment TO @DB_USER@; GRANT SELECT ON TABLE DeviceStats TO @DB_USER@; GRANT SELECT ON TABLE JobStats TO @DB_USER@; GRANT SELECT ON TABLE TapeAlerts TO @DB_USER@; \g bareos-Release-14.2.6/src/cats/ddl/grants/ingres.sql000066400000000000000000000041561263011562700222400ustar00rootroot00000000000000-- for tables GRANT ALL ON TABLE Filename TO @DB_USER@; GRANT ALL ON TABLE Path TO @DB_USER@; GRANT ALL ON TABLE File TO @DB_USER@; GRANT ALL ON TABLE RestoreObject TO @DB_USER@; GRANT ALL ON TABLE Job TO @DB_USER@; GRANT ALL ON TABLE JobHisto TO @DB_USER@; GRANT ALL ON TABLE Location TO @DB_USER@; GRANT ALL ON TABLE Fileset TO @DB_USER@; GRANT ALL ON TABLE JobMedia TO @DB_USER@; GRANT ALL ON TABLE Media TO @DB_USER@; GRANT ALL ON TABLE MediaType TO @DB_USER@; GRANT ALL ON TABLE Storage TO @DB_USER@; GRANT ALL ON TABLE Device TO @DB_USER@; GRANT ALL ON TABLE Pool TO @DB_USER@; GRANT ALL ON TABLE Client TO @DB_USER@; GRANT ALL ON TABLE Log TO @DB_USER@; GRANT ALL ON TABLE LocationLog TO @DB_USER@; GRANT ALL ON TABLE Counters TO @DB_USER@; GRANT ALL ON TABLE BaseFiles TO @DB_USER@; GRANT ALL ON TABLE UnsavedFiles TO @DB_USER@; GRANT ALL ON TABLE PathHierarchy TO @DB_USER@; GRANT ALL ON TABLE PathVisibility TO @DB_USER@; GRANT ALL ON TABLE Version TO @DB_USER@; GRANT ALL ON TABLE Status TO @DB_USER@; GRANT ALL ON TABLE NDMPLevelMap TO @DB_USER@; GRANT ALL ON TABLE NDMPJobEnvironment TO @DB_USER@; GRANT ALL ON TABLE DeviceStats TO @DB_USER@; GRANT ALL ON TABLE JobStats TO @DB_USER@; GRANT ALL ON TABLE TapeAlerts TO @DB_USER@; -- for sequences ON those tables GRANT NEXT ON SEQUENCE Filename_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Path_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE File_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE RestoreObject_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Job_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE JobHisto_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Location_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Fileset_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Jobmedia_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Media_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE MediaType_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Storage_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Device_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Pool_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Client_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE Log_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE LocationLog_Seq TO @DB_USER@; GRANT NEXT ON SEQUENCE BaseFiles_Seq TO @DB_USER@; \g bareos-Release-14.2.6/src/cats/ddl/grants/mysql-readonly.sql000066400000000000000000000004271263011562700237260ustar00rootroot00000000000000USE mysql -- read-only access for third party applications GRANT SELECT ON TABLE @DB_NAME@.* TO @DB_USER@@localhost @DB_PASS@; GRANT SELECT ON TABLE @DB_NAME@.* TO @DB_USER@@'127.0.0.1' @DB_PASS@; GRANT SELECT ON TABLE @DB_NAME@.* TO @DB_USER@@'::1' @DB_PASS@; FLUSH PRIVILEGES; bareos-Release-14.2.6/src/cats/ddl/grants/mysql.sql000066400000000000000000000003761263011562700221160ustar00rootroot00000000000000USE mysql GRANT ALL PRIVILEGES ON TABLE @DB_NAME@.* TO @DB_USER@@localhost @DB_PASS@; GRANT ALL PRIVILEGES ON TABLE @DB_NAME@.* TO @DB_USER@@'127.0.0.1' @DB_PASS@; GRANT ALL PRIVILEGES ON TABLE @DB_NAME@.* TO @DB_USER@@'::1' @DB_PASS@; FLUSH PRIVILEGES; bareos-Release-14.2.6/src/cats/ddl/grants/postgresql-readonly.sql000066400000000000000000000023541263011562700247650ustar00rootroot00000000000000-- read-only access for third party applications CREATE USER @DB_USER@ @DB_PASS@; GRANT SELECT ON UnSavedFiles TO @DB_USER@; GRANT SELECT ON BaseFiles TO @DB_USER@; GRANT SELECT ON JobMedia TO @DB_USER@; GRANT SELECT ON File TO @DB_USER@; GRANT SELECT ON Job TO @DB_USER@; GRANT SELECT ON Media TO @DB_USER@; GRANT SELECT ON Client TO @DB_USER@; GRANT SELECT ON Pool TO @DB_USER@; GRANT SELECT ON Fileset TO @DB_USER@; GRANT SELECT ON Path TO @DB_USER@; GRANT SELECT ON Filename TO @DB_USER@; GRANT SELECT ON Counters TO @DB_USER@; GRANT SELECT ON Version TO @DB_USER@; GRANT SELECT ON MediaType TO @DB_USER@; GRANT SELECT ON Storage TO @DB_USER@; GRANT SELECT ON Device TO @DB_USER@; GRANT SELECT ON Status TO @DB_USER@; GRANT SELECT ON Location TO @DB_USER@; GRANT SELECT ON LocationLog TO @DB_USER@; GRANT SELECT ON Log TO @DB_USER@; GRANT SELECT ON JobHisto TO @DB_USER@; GRANT SELECT ON PathHierarchy TO @DB_USER@; GRANT SELECT ON PathVisibility TO @DB_USER@; GRANT SELECT ON RestoreObject TO @DB_USER@; GRANT SELECT ON Quota TO @DB_USER@; GRANT SELECT ON NDMPLevelMap TO @DB_USER@; GRANT SELECT ON NDMPJobEnvironment TO @DB_USER@; GRANT SELECT ON DeviceStats TO @DB_USER@; GRANT SELECT ON JobStats TO @DB_USER@; GRANT SELECT ON TapeAlerts TO @DB_USER@; bareos-Release-14.2.6/src/cats/ddl/grants/postgresql.sql000066400000000000000000000041731263011562700231530ustar00rootroot00000000000000CREATE USER @DB_USER@ @DB_PASS@; -- For tables GRANT ALL ON UnSavedFiles TO @DB_USER@; GRANT ALL ON BaseFiles TO @DB_USER@; GRANT ALL ON JobMedia TO @DB_USER@; GRANT ALL ON File TO @DB_USER@; GRANT ALL ON Job TO @DB_USER@; GRANT ALL ON Media TO @DB_USER@; GRANT ALL ON Client TO @DB_USER@; GRANT ALL ON Pool TO @DB_USER@; GRANT ALL ON Fileset TO @DB_USER@; GRANT ALL ON Path TO @DB_USER@; GRANT ALL ON Filename TO @DB_USER@; GRANT ALL ON Counters TO @DB_USER@; GRANT ALL ON Version TO @DB_USER@; GRANT ALL ON MediaType TO @DB_USER@; GRANT ALL ON Storage TO @DB_USER@; GRANT ALL ON Device TO @DB_USER@; GRANT ALL ON Status TO @DB_USER@; GRANT ALL ON Location TO @DB_USER@; GRANT ALL ON LocationLog TO @DB_USER@; GRANT ALL ON Log TO @DB_USER@; GRANT ALL ON JobHisto TO @DB_USER@; GRANT ALL ON PathHierarchy TO @DB_USER@; GRANT ALL ON PathVisibility TO @DB_USER@; GRANT ALL ON RestoreObject TO @DB_USER@; GRANT ALL ON Quota TO @DB_USER@; GRANT ALL ON NDMPLevelMap TO @DB_USER@; GRANT ALL ON NDMPJobEnvironment TO @DB_USER@; GRANT ALL ON DeviceStats TO @DB_USER@; GRANT ALL ON JobStats TO @DB_USER@; GRANT ALL ON TapeAlerts TO @DB_USER@; -- For sequences ON those tables GRANT SELECT, UPDATE ON filename_filenameid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON path_pathid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON fileset_filesetid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON pool_poolid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON client_clientid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON media_mediaid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON job_jobid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON file_fileid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON jobmedia_jobmediaid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON basefiles_baseid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON storage_storageid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON mediatype_mediatypeid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON device_deviceid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON location_locationid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON locationlog_loclogid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON log_logid_seq TO @DB_USER@; GRANT SELECT, UPDATE ON restoreobject_restoreobjectid_seq TO @DB_USER@; bareos-Release-14.2.6/src/cats/ddl/updates/000077500000000000000000000000001263011562700203715ustar00rootroot00000000000000bareos-Release-14.2.6/src/cats/ddl/updates/mysql.10_11.sql000066400000000000000000000027361263011562700230070ustar00rootroot00000000000000-- Fix bad index on Media table DROP INDEX inx8 ON Media; CREATE UNIQUE INDEX inx8 ON Media (VolumeName(128)); ALTER TABLE File CHANGE FileId FileId BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; ALTER TABLE BaseFiles CHANGE FileId FileId BIGINT UNSIGNED NOT NULL; ALTER TABLE Job ADD ReadBytes BIGINT UNSIGNED DEFAULT 0 AFTER JobBytes; ALTER TABLE Media ADD ActionOnPurge TINYINT DEFAULT 0 AFTER Recycle; ALTER TABLE Pool ADD ActionOnPurge TINYINT DEFAULT 0 AFTER Recycle; DROP TABLE IF EXISTS JobHistory; -- Create a table like Job for long term statistics CREATE TABLE JobHisto ( JobId INTEGER UNSIGNED NOT NULL, Job TINYBLOB NOT NULL, Name TINYBLOB NOT NULL, Type BINARY(1) NOT NULL, Level BINARY(1) NOT NULL, ClientId INTEGER DEFAULT 0, JobStatus BINARY(1) NOT NULL, SchedTime DATETIME DEFAULT 0, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED DEFAULT 0, FileSetId INTEGER UNSIGNED DEFAULT 0, PriorJobId INTEGER UNSIGNED DEFAULT 0, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0, INDEX (StartTime) ); UPDATE Version SET VersionId = 11; bareos-Release-14.2.6/src/cats/ddl/updates/mysql.11_12.sql000066400000000000000000000026141263011562700230040ustar00rootroot00000000000000ALTER TABLE JobMedia DROP Stripe ; ALTER TABLE JobMedia DROP Copy ; ALTER TABLE Job ADD COLUMN HasCache tinyint default 0 after HasBase; ALTER TABLE Job ADD COLUMN Reviewed tinyint default 0 after HasCache; ALTER TABLE Job ADD COLUMN Comment BLOB AFTER Reviewed; ALTER TABLE JobHisto ADD COLUMN HasCache tinyint default 0 after HasBase; ALTER TABLE JobHisto ADD COLUMN Reviewed tinyint default 0 after HasCache; ALTER TABLE JobHisto ADD COLUMN Comment BLOB AFTER Reviewed; ALTER TABLE Status ADD COLUMN Severity int; UPDATE Status SET Severity = 15; UPDATE Status SET Severity = 100 where JobStatus = 'f'; UPDATE Status SET Severity = 90 where JobStatus = 'A'; UPDATE Status SET Severity = 10 where JobStatus = 'T'; UPDATE Status SET Severity = 20 where JobStatus = 'e'; UPDATE Status SET Severity = 25 where JobStatus = 'E'; CREATE TABLE PathHierarchy ( PathId integer NOT NULL, PPathId integer NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId integer NOT NULL, JobId integer NOT NULL, Size int8 DEFAULT 0, Files int4 DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId ); UPDATE Version SET VersionId = 12; bareos-Release-14.2.6/src/cats/ddl/updates/mysql.12_14.sql000066400000000000000000000012261263011562700230050ustar00rootroot00000000000000CREATE TABLE RestoreObject ( RestoreObjectId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, ObjectName BLOB NOT NULL, RestoreObject LONGBLOB NOT NULL, PluginName TINYBLOB NOT NULL, ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER UNSIGNED DEFAULT 0, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, ObjectCompression INTEGER DEFAULT 0, PRIMARY KEY(RestoreObjectId), INDEX (JobId) ); CREATE INDEX jobhisto_jobid_idx ON JobHisto (JobId); ALTER TABLE File ADD COLUMN DeltaSeq smallint default 0; UPDATE Version SET VersionId = 14; bareos-Release-14.2.6/src/cats/ddl/updates/mysql.14_2001.sql000066400000000000000000000015001263011562700231400ustar00rootroot00000000000000CREATE TABLE Quota ( ClientId INT UNSIGNED DEFAULT NULL, GraceTime BIGINT DEFAULT 0, QuotaLimit BIGINT UNSIGNED DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER DEFAULT 0 REFERENCES Client, FileSetId INTEGER UNSIGNED DEFAULT 0 REFERENCES FileSet, FileSystem TINYBLOB NOT NULL, DumpLevel INTEGER NOT NULL, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem(256)) ); ALTER TABLE Media DROP COLUMN VolParts; ALTER TABLE Media ADD COLUMN EncryptionKey TINYBLOB; INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('I', 'Incomplete job', 15), ('L', 'Committing data', 15), ('W', 'Terminated with warnings', 20), ('l', 'Doing data despooling', 15), ('q', 'Queued waiting for device', 15); UPDATE Version SET VersionId = 2001; bareos-Release-14.2.6/src/cats/ddl/updates/mysql.2001_2002.sql000066400000000000000000000027141263011562700233070ustar00rootroot00000000000000CREATE TABLE NDMPJobEnvironment ( JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, FileIndex INTEGER UNSIGNED NOT NULL, EnvName TINYBLOB NOT NULL, EnvValue TINYBLOB NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName(256)) ); CREATE TABLE DeviceStats ( SampleTime DATETIME NOT NULL, ReadTime BIGINT UNSIGNED DEFAULT 0, WriteTime BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, WriteBytes BIGINT UNSIGNED DEFAULT 0, Spool INTEGER UNSIGNED DEFAULT 0, Waiting INTEGER DEFAULT 0, Writers INTEGER DEFAULT 0, MediaId INTEGER UNSIGNED DEFAULT 0 REFERENCES Media, VolCatBytes BIGINT UNSIGNED DEFAULT 0, VolCatFiles BIGINT UNSIGNED DEFAULT 0, VolCatBlocks BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE JobStats ( SampleTime DATETIME NOT NULL, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0 ); ALTER TABLE Media ADD COLUMN MinBlockSize INTEGER UNSIGNED DEFAULT 0; ALTER TABLE Media ADD COLUMN MaxBlockSize INTEGER UNSIGNED DEFAULT 0; ALTER TABLE Pool ADD COLUMN MinBlockSize INTEGER UNSIGNED DEFAULT 0; ALTER TABLE Pool ADD COLUMN MaxBlockSize INTEGER UNSIGNED DEFAULT 0; UPDATE Version SET VersionId = 2002; -- remove unsecure user entry, -- created by older Bareos versions, -- if configured to run without password DELETE FROM mysql.user where User='bareos' and Host="%" and Password=""; FLUSH PRIVILEGES; bareos-Release-14.2.6/src/cats/ddl/updates/mysql.2002_2003.sql000066400000000000000000000023071263011562700233070ustar00rootroot00000000000000-- -- We drop and recreate the stats table which was not used yet. -- DROP TABLE DeviceStats; CREATE TABLE DeviceStats ( DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, SampleTime DATETIME NOT NULL, ReadTime BIGINT UNSIGNED DEFAULT 0, WriteTime BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, WriteBytes BIGINT UNSIGNED DEFAULT 0, SpoolSize BIGINT UNSIGNED DEFAULT 0, NumWaiting INTEGER DEFAULT 0, NumWriters INTEGER DEFAULT 0, MediaId INTEGER UNSIGNED DEFAULT 0 REFERENCES Media, VolCatBytes BIGINT UNSIGNED DEFAULT 0, VolCatFiles BIGINT UNSIGNED DEFAULT 0, VolCatBlocks BIGINT UNSIGNED DEFAULT 0 ); -- -- We drop and recreate the stats table which was not used yet. -- DROP TABLE JobStats; CREATE TABLE JobStats ( DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, SampleTime DATETIME NOT NULL, JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device, SampleTime DATETIME NOT NULL, AlertFlags BIGINT UNSIGNED DEFAULT 0 ); DROP TABLE CDImages; UPDATE Version SET VersionId = 2003; bareos-Release-14.2.6/src/cats/ddl/updates/postgresql.10_11.sql000066400000000000000000000012511263011562700240340ustar00rootroot00000000000000-- The alter table operation can be faster with a big maintenance_work_mem -- Uncomment and adapt this value to your environment -- SET maintenance_work_mem = '1GB'; BEGIN; ALTER TABLE file ALTER fileid TYPE bigint ; ALTER TABLE basefiles ALTER fileid TYPE bigint; ALTER TABLE job ADD COLUMN readbytes bigint default 0; ALTER TABLE media ADD COLUMN ActionOnPurge smallint default 0; ALTER TABLE pool ADD COLUMN ActionOnPurge smallint default 0; -- Create a table like Job for long term statistics DROP TABLE IF EXISTS JobHistory; CREATE TABLE JobHisto (LIKE Job); CREATE INDEX jobhisto_idx ON JobHisto ( starttime ); UPDATE Version SET VersionId=11; COMMIT; -- vacuum analyse; bareos-Release-14.2.6/src/cats/ddl/updates/postgresql.11_12.sql000066400000000000000000000036511263011562700240440ustar00rootroot00000000000000BEGIN; -- Necessary for Bacula core ALTER TABLE JobMedia DROP Copy ; ALTER TABLE Job ADD COLUMN HasCache smallint default 0; ALTER TABLE Job ADD COLUMN Reviewed smallint default 0; ALTER TABLE Job ADD COLUMN Comment text; ALTER TABLE JobHisto ADD COLUMN HasCache smallint default 0; ALTER TABLE JobHisto ADD COLUMN Reviewed smallint default 0; ALTER TABLE JobHisto ADD COLUMN Comment text; UPDATE Version SET VersionId=12; COMMIT; BEGIN; -- Can conflict with previous Bweb installation ALTER TABLE Status ADD COLUMN Severity int; UPDATE Status SET Severity = 15; UPDATE Status SET Severity = 100 where JobStatus = 'f'; UPDATE Status SET Severity = 90 where JobStatus = 'A'; UPDATE Status SET Severity = 10 where JobStatus = 'T'; UPDATE Status SET Severity = 20 where JobStatus = 'e'; UPDATE Status SET Severity = 25 where JobStatus = 'E'; COMMIT; BEGIN; -- Can already exists if using 3.1.x release CREATE TABLE PathHierarchy ( PathId integer NOT NULL, PPathId integer NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId integer NOT NULL, JobId integer NOT NULL, Size int8 DEFAULT 0, Files int4 DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); COMMIT; CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId ); -- suppress output for index modification SET client_min_messages TO 'fatal'; -- Remove bad PostgreSQL index DROP INDEX file_fp_idx; -- Create the good one -- If you want to create this index during production, you can use -- CREATE INDEX CONCURRENTLY file_jpf_idx ON File (JobId, PathId, FilenameId) -- to make it without locks (require PostgreSQL 8.2 version) CREATE INDEX file_jpfid_idx on File (JobId, PathId, FilenameId); -- restore output SET client_min_messages TO DEFAULT; ANALYSE; bareos-Release-14.2.6/src/cats/ddl/updates/postgresql.12_14.sql000066400000000000000000000013041263011562700240400ustar00rootroot00000000000000BEGIN; -- Necessary for Bacula core CREATE TABLE RestoreObject ( RestoreObjectId SERIAL NOT NULL, ObjectName TEXT NOT NULL, RestoreObject BYTEA NOT NULL, PluginName TEXT NOT NULL, ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER DEFAULT 0, JobId INTEGER, ObjectCompression INTEGER DEFAULT 0, PRIMARY KEY(RestoreObjectId) ); CREATE INDEX restore_jobid_idx on RestoreObject(JobId); ALTER TABLE File ADD COLUMN DeltaSeq smallint default 0; UPDATE Version SET VersionId=14; COMMIT; set client_min_messages = fatal; CREATE INDEX media_poolid_idx on Media (PoolId); ANALYSE; bareos-Release-14.2.6/src/cats/ddl/updates/postgresql.14_2001.sql000066400000000000000000000023331263011562700242030ustar00rootroot00000000000000BEGIN; -- Necessary for Bareos core CREATE TABLE Quota ( ClientId INTEGER NOT NULL, GraceTime BIGINT DEFAULT 0, QuotaLimit BIGINT DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER NOT NULL, FilesetId INTEGER DEFAULT 0, FileSystem TEXT NOT NULL, DumpLevel INTEGER NOT NULL, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem) ); ALTER TABLE Media DROP COLUMN VolParts RESTRICT; ALTER TABLE Media ADD COLUMN EncryptionKey text; INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('I', 'Incomplete job', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('L', 'Committing data', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('W', 'Terminated with warnings', 20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('l', 'Doing data despooling', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('q', 'Queued waiting for device', 15); UPDATE Version SET VersionId = 2001; COMMIT; set client_min_messages = fatal; CREATE INDEX media_poolid_idx on Media (PoolId); ANALYSE; bareos-Release-14.2.6/src/cats/ddl/updates/postgresql.2001_2002.sql000066400000000000000000000027221263011562700243440ustar00rootroot00000000000000BEGIN; -- Necessary for Bareos core CREATE TABLE NDMPJobEnvironment ( JobId INTEGER NOT NULL, FileIndex INTEGER NOT NULL, EnvName TEXT NOT NULL, EnvValue TEXT NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName) ); CREATE TABLE DeviceStats ( SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, ReadTime BIGINT NOT NULL DEFAULT 0, WriteTime BIGINT NOT NULL DEFAULT 0, ReadBytes BIGINT DEFAULT 0, WriteBytes BIGINT DEFAULT 0, Spool SMALLINT DEFAULT 0, Waiting SMALLINT DEFAULT 0, Writers SMALLINT DEFAULT 0, MediaId INTEGER NOT NULL, VolCatBytes BIGINT DEFAULT 0, VolCatFiles BIGINT DEFAULT 0, VolCatBlocks BIGINT DEFAULT 0 ); CREATE TABLE JobStats ( SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, JobId INTEGER NOT NULL, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0 ); ALTER TABLE Media ADD COLUMN MinBlockSize INTEGER DEFAULT 0; ALTER TABLE Media ADD COLUMN MaxBlockSize INTEGER DEFAULT 0; ALTER TABLE Pool ADD COLUMN MinBlockSize INTEGER DEFAULT 0; ALTER TABLE Pool ADD COLUMN MaxBlockSize INTEGER DEFAULT 0; UPDATE Version SET VersionId = 2002; COMMIT; set client_min_messages = fatal; ANALYSE; bareos-Release-14.2.6/src/cats/ddl/updates/postgresql.2002_2003.sql000066400000000000000000000026241263011562700243470ustar00rootroot00000000000000BEGIN; -- Necessary for Bareos core -- -- We drop and recreate the stats table which was not used yet. -- DROP TABLE DeviceStats; CREATE TABLE DeviceStats ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, ReadTime BIGINT NOT NULL DEFAULT 0, WriteTime BIGINT NOT NULL DEFAULT 0, ReadBytes BIGINT DEFAULT 0, WriteBytes BIGINT DEFAULT 0, SpoolSize BIGINT DEFAULT 0, NumWaiting SMALLINT DEFAULT 0, NumWriters SMALLINT DEFAULT 0, MediaId INTEGER NOT NULL, VolCatBytes BIGINT DEFAULT 0, VolCatFiles BIGINT DEFAULT 0, VolCatBlocks BIGINT DEFAULT 0 ); -- -- We drop and recreate the stats table which was not used yet. -- DROP TABLE JobStats; CREATE TABLE JobStats ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, JobId INTEGER NOT NULL, JobFiles INTEGER DEFAULT 0, JobBytes BIGINT DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER DEFAULT 0, SampleTime TIMESTAMP WITHOUT TIME ZONE NOT NULL, AlertFlags BIGINT DEFAULT 0 ); DROP TABLE CDImages; UPDATE Version SET VersionId = 2003; COMMIT; set client_min_messages = fatal; ANALYSE; bareos-Release-14.2.6/src/cats/ddl/updates/sqlite3.10_11.sql000066400000000000000000000171601263011562700232230ustar00rootroot00000000000000-- Can be replaced by -- ALTER TABLE Job ADD COLUMN (ReadBytes BIGINT UNSIGNED DEFAULT 0); BEGIN TRANSACTION; CREATE TEMPORARY TABLE job_backup AS SELECT * FROM Job; DROP TABLE Job; CREATE TABLE Job ( JobId INTEGER, Job VARCHAR(128) NOT NULL, Name VARCHAR(128) NOT NULL, Type CHAR NOT NULL, Level CHAR NOT NULL, ClientId INTEGER REFERENCES Client DEFAULT 0, JobStatus CHAR NOT NULL, SchedTime DATETIME NOT NULL, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0, PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0, PRIMARY KEY(JobId) ); CREATE INDEX inx6 ON Job (Name); INSERT INTO Job (JobId, Job, Name, Type, Level, ClientId, JobStatus, SchedTime, StartTime, EndTime, RealEndTime, JobTDate, VolSessionId, VolSessionTime, JobFiles, JobBytes, JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase) SELECT JobId, Job, Name, Type, Level, ClientId, JobStatus, SchedTime, StartTime, EndTime, RealEndTime, JobTDate, VolSessionId, VolSessionTime, JobFiles, JobBytes, JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase FROM Job_backup; DROP TABLE Job_backup; -- ---------------------------------------------------------------- -- New ActionOnPurge field CREATE TEMPORARY TABLE pool_backup AS SELECT * FROM Pool; DROP TABLE Pool; CREATE TABLE Pool ( PoolId INTEGER, Name VARCHAR(128) NOT NULL, NumVols INTEGER UNSIGNED DEFAULT 0, MaxVols INTEGER UNSIGNED DEFAULT 0, UseOnce TINYINT DEFAULT 0, UseCatalog TINYINT DEFAULT 1, AcceptAnyVolume TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, MaxVolFiles INTEGER UNSIGNED DEFAULT 0, MaxVolBytes BIGINT UNSIGNED DEFAULT 0, AutoPrune TINYINT DEFAULT 0, Recycle TINYINT DEFAULT 0, ActionOnPurge TINYINT DEFAULT 0, PoolType VARCHAR(20) NOT NULL, LabelType TINYINT DEFAULT 0, LabelFormat VARCHAR(128) NOT NULL, Enabled TINYINT DEFAULT 1, ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, NextPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, MigrationHighBytes BIGINT UNSIGNED DEFAULT 0, MigrationLowBytes BIGINT UNSIGNED DEFAULT 0, MigrationTime BIGINT UNSIGNED DEFAULT 0, UNIQUE (Name), PRIMARY KEY (PoolId) ); INSERT INTO Pool (PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog, AcceptAnyVolume, VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles, MaxVolBytes, AutoPrune, Recycle, PoolType, LabelType, LabelFormat, Enabled, ScratchPoolId, RecyclePoolId, NextPoolId, MigrationHighBytes, MigrationLowBytes, MigrationTime) SELECT PoolId, Name, NumVols, MaxVols, UseOnce, UseCatalog, AcceptAnyVolume, VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles, MaxVolBytes, AutoPrune, Recycle, PoolType, LabelType, LabelFormat, Enabled, ScratchPoolId, RecyclePoolId, NextPoolId, MigrationHighBytes, MigrationLowBytes, MigrationTime FROM pool_backup; DROP TABLE pool_backup; -- ---------------------------------------------------------------- -- New ActionOnPurge field CREATE TEMPORARY TABLE media_backup AS SELECT * FROM Media; DROP TABLE Media; CREATE TABLE Media ( MediaId INTEGER, VolumeName VARCHAR(128) NOT NULL, Slot INTEGER DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, MediaType VARCHAR(128) NOT NULL, MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0, LabelType TINYINT DEFAULT 0, FirstWritten DATETIME DEFAULT 0, LastWritten DATETIME DEFAULT 0, LabelDate DATETIME DEFAULT 0, VolJobs INTEGER UNSIGNED DEFAULT 0, VolFiles INTEGER UNSIGNED DEFAULT 0, VolBlocks INTEGER UNSIGNED DEFAULT 0, VolMounts INTEGER UNSIGNED DEFAULT 0, VolBytes BIGINT UNSIGNED DEFAULT 0, VolParts INTEGER UNSIGNED DEFAULT 0, VolErrors INTEGER UNSIGNED DEFAULT 0, VolWrites INTEGER UNSIGNED DEFAULT 0, VolCapacityBytes BIGINT UNSIGNED DEFAULT 0, VolStatus VARCHAR(20) NOT NULL, Enabled TINYINT DEFAULT 1, Recycle TINYINT DEFAULT 0, ActionOnPurge TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, MaxVolFiles INTEGER UNSIGNED DEFAULT 0, MaxVolBytes BIGINT UNSIGNED DEFAULT 0, InChanger TINYINT DEFAULT 0, StorageId INTEGER UNSIGNED REFERENCES Storage DEFAULT 0, DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, MediaAddressing TINYINT DEFAULT 0, VolReadTime BIGINT UNSIGNED DEFAULT 0, VolWriteTime BIGINT UNSIGNED DEFAULT 0, EndFile INTEGER UNSIGNED DEFAULT 0, EndBlock INTEGER UNSIGNED DEFAULT 0, LocationId INTEGER UNSIGNED REFERENCES Location DEFAULT 0, RecycleCount INTEGER UNSIGNED DEFAULT 0, InitialWrite DATETIME DEFAULT 0, ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, Comment TEXT, PRIMARY KEY(MediaId) ); CREATE INDEX inx8 ON Media (PoolId); INSERT INTO Media ( MediaId, VolumeName, Slot, PoolId, MediaType, MediaTypeId, LabelType, FirstWritten, LastWritten, LabelDate, VolJobs, VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors, VolWrites, VolCapacityBytes, VolStatus, Enabled, Recycle, VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles, MaxVolBytes, InChanger, StorageId, DeviceId, MediaAddressing, VolReadTime, VolWriteTime, EndFile, EndBlock, LocationId, RecycleCount, InitialWrite, ScratchPoolId, RecyclePoolId, Comment) SELECT MediaId, VolumeName, Slot, PoolId, MediaType, MediaTypeId, LabelType, FirstWritten, LastWritten, LabelDate, VolJobs, VolFiles, VolBlocks, VolMounts, VolBytes, VolParts, VolErrors, VolWrites, VolCapacityBytes, VolStatus, Enabled, Recycle, VolRetention, VolUseDuration, MaxVolJobs, MaxVolFiles, MaxVolBytes, InChanger, StorageId, DeviceId, MediaAddressing, VolReadTime, VolWriteTime, EndFile, EndBlock, LocationId, RecycleCount, InitialWrite, ScratchPoolId, RecyclePoolId, Comment FROM media_backup; DROP TABLE media_backup; UPDATE Version SET VersionId=11; COMMIT; DROP TABLE IF EXISTS JobHistory; -- Create a table like Job for long term statistics CREATE TABLE JobHisto ( JobId INTEGER, Job VARCHAR(128) NOT NULL, Name VARCHAR(128) NOT NULL, Type CHAR NOT NULL, Level CHAR NOT NULL, ClientId INTEGER REFERENCES Client DEFAULT 0, JobStatus CHAR NOT NULL, SchedTime DATETIME NOT NULL, StartTime DATETIME DEFAULT 0, EndTime DATETIME DEFAULT 0, RealEndTime DATETIME DEFAULT 0, JobTDate BIGINT UNSIGNED DEFAULT 0, VolSessionId INTEGER UNSIGNED DEFAULT 0, VolSessionTime INTEGER UNSIGNED DEFAULT 0, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, JobErrors INTEGER UNSIGNED DEFAULT 0, JobMissingFiles INTEGER UNSIGNED DEFAULT 0, PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0, FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0, PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0, PurgedFiles TINYINT DEFAULT 0, HasBase TINYINT DEFAULT 0 ); CREATE INDEX inx61 ON JobHisto (StartTime); bareos-Release-14.2.6/src/cats/ddl/updates/sqlite3.11_12.sql000066400000000000000000000025501263011562700232220ustar00rootroot00000000000000BEGIN; ALTER TABLE Job ADD COLUMN HasCache TINYINT DEFAULT 0; ALTER TABLE Job ADD COLUMN Reviewed TINYINT DEFAULT 0; ALTER TABLE Job ADD COLUMN Comment TEXT; ALTER TABLE JobHisto ADD COLUMN HasCache TINYINT DEFAULT 0; ALTER TABLE JobHisto ADD COLUMN Reviewed TINYINT DEFAULT 0; ALTER TABLE JobHisto ADD COLUMN Comment TEXT; ALTER TABLE Status ADD COLUMN Severity int; UPDATE Status SET Severity = 15; UPDATE Status SET Severity = 100 where JobStatus = 'f'; UPDATE Status SET Severity = 90 where JobStatus = 'A'; UPDATE Status SET Severity = 10 where JobStatus = 'T'; UPDATE Status SET Severity = 20 where JobStatus = 'e'; UPDATE Status SET Severity = 25 where JobStatus = 'E'; CREATE TABLE PathHierarchy ( PathId integer NOT NULL, PPathId integer NOT NULL, CONSTRAINT pathhierarchy_pkey PRIMARY KEY (PathId) ); CREATE INDEX pathhierarchy_ppathid ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( PathId integer NOT NULL, JobId integer NOT NULL, Size int8 DEFAULT 0, Files int4 DEFAULT 0, CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid ON PathVisibility (JobId); CREATE INDEX basefiles_jobid_idx ON BaseFiles ( JobId ); UPDATE Version SET VersionId=12; COMMIT; DROP INDEX inx4; DROP INDEX IF EXISTS inx9; CREATE INDEX file_jpf_idx ON File (JobId, PathId, FilenameId); bareos-Release-14.2.6/src/cats/ddl/updates/sqlite3.12_14.sql000066400000000000000000000011651263011562700232260ustar00rootroot00000000000000BEGIN; CREATE TABLE RestoreObject ( RestoreObjectId INTEGER, ObjectName TEXT DEFAULT '', RestoreObject TEXT DEFAULT '', PluginName TEXT DEFAULT '', ObjectLength INTEGER DEFAULT 0, ObjectFullLength INTEGER DEFAULT 0, ObjectIndex INTEGER DEFAULT 0, ObjectType INTEGER DEFAULT 0, FileIndex INTEGER UNSIGNED DEFAULT 0, ObjectCompression INTEGER DEFAULT 0, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, PRIMARY KEY(RestoreObjectId) ); CREATE INDEX restore_jobid_idx ON RestoreObject (JobId); ALTER TABLE File ADD COLUMN DeltaSeq smallint default 0; UPDATE Version SET VersionId=14; COMMIT; bareos-Release-14.2.6/src/cats/ddl/updates/sqlite3.14_2001.sql000066400000000000000000000020671263011562700233700ustar00rootroot00000000000000BEGIN; CREATE TABLE Quota ( ClientId INTEGER REFERENCES Client DEFAULT 0, GraceTime INTEGER UNSIGNED DEFAULT 0, QuotaLimit BIGINT UNSIGNED DEFAULT 0, PRIMARY KEY (ClientId) ); CREATE TABLE NDMPLevelMap ( ClientId INTEGER REFERENCES Client DEFAULT 0, FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0, FileSystem TEXT DEFAULT '', DumpLevel INTEGER UNSIGNED DEFAULT 0, CONSTRAINT NDMPLevelMap_pkey PRIMARY KEY (ClientId, FilesetId, FileSystem) ); ALTER TABLE Media ADD COLUMN EncryptionKey VARCHAR(128); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('I', 'Incomplete job', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('L', 'Committing data', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('W', 'Terminated with warnings', 20); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('l', 'Doing data despooling', 15); INSERT INTO Status (JobStatus,JobStatusLong,Severity) VALUES ('q', 'Queued waiting for device', 15); UPDATE Version SET VersionId = 2001; COMMIT; bareos-Release-14.2.6/src/cats/ddl/updates/sqlite3.2001_2002.sql000066400000000000000000000023631263011562700235260ustar00rootroot00000000000000BEGIN; CREATE TABLE NDMPJobEnvironment ( JobId integer NOT NULL, FileIndex INTEGER UNSIGNED NOT NULL, EnvName TEXT NOT NULL, EnvValue TEXT NOT NULL, CONSTRAINT NDMPJobEnvironment_pkey PRIMARY KEY (JobId, FileIndex, EnvName) ); CREATE TABLE DeviceStats ( SampleTime DATETIME NOT NULL, ReadTime BIGINT UNSIGNED DEFAULT 0, WriteTime BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, WriteBytes BIGINT UNSIGNED DEFAULT 0, Spool INTEGER UNSIGNED DEFAULT 0, Waiting INTEGER DEFAULT 0, Writers INTEGER DEFAULT 0, MediaId INTEGER UNSIGNED REFERENCES Media DEFAULT 0, VolCatBytes BIGINT UNSIGNED DEFAULT 0, VolCatFiles BIGINT UNSIGNED DEFAULT 0, VolCatBlocks BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE JobStats ( SampleTime DATETIME NOT NULL, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0 ); ALTER TABLE Media ADD COLUMN MinBlockSize INTEGER UNSIGNED DEFAULT 0; ALTER TABLE Media ADD COLUMN MaxBlockSize INTEGER UNSIGNED DEFAULT 0; ALTER TABLE Pool ADD COLUMN MinBlockSize INTEGER UNSIGNED DEFAULT 0; ALTER TABLE Pool ADD COLUMN MaxBlockSize INTEGER UNSIGNED DEFAULT 0; UPDATE Version SET VersionId = 2002; COMMIT; bareos-Release-14.2.6/src/cats/ddl/updates/sqlite3.2002_2003.sql000066400000000000000000000023271263011562700235300ustar00rootroot00000000000000BEGIN; -- -- We drop and recreate the stats table which was not used yet. -- DROP TABLE DeviceStats; CREATE TABLE DeviceStats ( DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, SampleTime DATETIME NOT NULL, ReadTime BIGINT UNSIGNED DEFAULT 0, WriteTime BIGINT UNSIGNED DEFAULT 0, ReadBytes BIGINT UNSIGNED DEFAULT 0, WriteBytes BIGINT UNSIGNED DEFAULT 0, SpoolSize BIGINT UNSIGNED DEFAULT 0, NumWaiting INTEGER DEFAULT 0, NumWriters INTEGER DEFAULT 0, MediaId INTEGER UNSIGNED REFERENCES Media DEFAULT 0, VolCatBytes BIGINT UNSIGNED DEFAULT 0, VolCatFiles BIGINT UNSIGNED DEFAULT 0, VolCatBlocks BIGINT UNSIGNED DEFAULT 0 ); -- -- We drop and recreate the stats table which was not used yet. -- DROP TABLE JobStats; CREATE TABLE JobStats ( DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, SampleTime DATETIME NOT NULL, JobId INTEGER UNSIGNED REFERENCES Job NOT NULL, JobFiles INTEGER UNSIGNED DEFAULT 0, JobBytes BIGINT UNSIGNED DEFAULT 0 ); CREATE TABLE TapeAlerts ( DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0, SampleTime DATETIME NOT NULL, AlertFlags BIGINT UNSIGNED DEFAULT 0 ); DROP TABLE CDImages; UPDATE Version SET VersionId = 2003; COMMIT; bareos-Release-14.2.6/src/cats/ddl/versions.map.in000066400000000000000000000004751263011562700217060ustar00rootroot00000000000000# This file defines per release of Bareos what database version it uses. # Use the function get_database_version_by_release # from bareos-config to retrieve the matching version. # It is used by the dbconfig mechanismen of Debian distributions. 12.4.0=2001 13.2.0=2001 13.2.3=2002 14.2.0=2003 default=@BDB_VERSION@ bareos-Release-14.2.6/src/cats/delete_catalog_backup.in000077500000000000000000000021161263011562700227750ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This script deletes a catalog dump # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-@db_name@}" working_dir=`get_working_dir` rm -f ${working_dir}/${db_name}.sql bareos-Release-14.2.6/src/cats/drop_bareos_database.in000066400000000000000000000045601263011562700226410ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This scripts drops the Bareos tables for PostgreSQL, Ingres, MySQL, or SQLite. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" default_db_type=`get_database_driver_default` working_dir=`get_working_dir` # # See if the first argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -gt 0 ]; then case $1 in sqlite3) db_type=$1 shift ;; mysql) db_type=$1 shift ;; postgresql) db_type=$1 shift ;; ingres) db_type=$1 shift ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi echo "Dropping ${db_type} database" bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi PATH="$bindir:$PATH" case ${db_type} in sqlite3) rm -f ${working_dir}/${db_name}.db retval=0 ;; mysql) mysql $* -e "DROP DATABASE ${db_name};" retval=$? ;; postgresql) dropdb $* ${db_name} retval=$? ;; ingres) destroydb -u${db_user} ${db_name} retval=$? ;; esac if [ ${retval} = 0 ]; then echo "Drop of ${db_name} database succeeded." else echo "Drop of ${db_name} database failed." fi exit ${retval} bareos-Release-14.2.6/src/cats/drop_bareos_tables.in000066400000000000000000000072101263011562700223420ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This routine drops the appropriately configured # Bareos tables for PostgreSQL, Ingres, MySQL, or SQLite. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" db_version=`get_database_version` bareos_sql_ddl=`get_database_ddl_dir` temp_sql_schema="/tmp/drops.sql.$$" default_db_type=`get_database_driver_default` working_dir=`get_working_dir` # # See if the first argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -gt 0 ]; then case $1 in sqlite3) db_type=$1 shift ;; mysql) db_type=$1 shift ;; postgresql) db_type=$1 shift ;; ingres) db_type=$1 shift ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi echo "Dropping ${db_type} tables" case ${db_type} in sqlite3) ;; mysql) sql_definitions="${bareos_sql_ddl}/drops/mysql.sql" ;; postgresql) sql_definitions="${bareos_sql_ddl}/drops/postgresql.sql" ;; ingres) sql_definitions="${bareos_sql_ddl}/drops/ingres.sql" ;; *) echo "Unknown database type $1" exit 1 ;; esac if [ ! -z "${sql_definitions}" ]; then if [ ! -f ${sql_definitions} ]; then echo "Unable to open database table definitions in file ${sql_definitions}" exit 1 fi get_translated_sql_file ${sql_definitions} > ${temp_sql_schema} if [ $? != 0 ]; then echo "Failed to translate SQL definitions in ${sql_definitions}" exit 1 fi fi bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi case ${db_type} in sqlite3) rm -f ${working_dir}/${db_name}.db retval=0 ;; mysql) mysql $* --database=${db_name} -f < ${temp_sql_schema} retval=$? if test $retval = 0; then echo "Dropping of Bareos MySQL tables succeeded." else echo "Dropping of Bareos MySQL tables failed." fi ;; postgresql) psql -f ${temp_sql_schema} -d ${db_name} $* retval=$? if test $retval = 0; then echo "Dropping of Bareos PostgreSQL tables succeeded." else echo "Dropping of Bareos PostgreSQL tables failed." fi ;; ingres) sql -u${db_user} $* ${db_name} < ${temp_sql_schema} retval=$? if test $retval = 0; then echo "Dropping of Bareos Ingres tables succeeded." else echo "Dropping of Bareos Ingres tables failed." fi ;; esac rm -f ${temp_sql_schema} exit ${retval} bareos-Release-14.2.6/src/cats/grant_bareos_privileges.in000066400000000000000000000057761263011562700234270ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # shell script to grant privileges to the bareos database # for PostgreSQL, Ingres, MySQL, or SQLite. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" # if $db_password is defined but empty, an empty password will be used ("-" instead of ":-") db_password="${db_password-`get_database_password @db_password@`}" db_version=`get_database_version` bareos_sql_ddl=`get_database_ddl_dir` temp_sql_grants="/tmp/grants.sql.$$" default_db_type=`get_database_driver_default` # # See if the first argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -gt 0 ]; then case $1 in sqlite3) db_type=$1 shift ;; mysql) db_type=$1 shift ;; postgresql) db_type=$1 shift ;; ingres) db_type=$1 shift ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi echo "Granting ${db_type} tables" get_database_grant_privileges "${db_type}" "${db_user}" "${db_password}" > ${temp_sql_grants} if [ $? != 0 ]; then echo "Error creating privileges." exit 1 fi bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi case ${db_type} in sqlite3) # # Nothing to do for SQLite3 # retval=0 ;; mysql) mysql $* -f < ${temp_sql_grants} retval=$? ;; postgresql) psql -f ${temp_sql_grants} -d ${db_name} $* retval=$? ;; ingres) sql iidbdb $* << END-OF-DATA CREATE USER ${db_user} ${pass} \g END-OF-DATA sql -u${db_user} $* ${db_name} < ${temp_sql_grants} retval=$? ;; *) echo "Unknown database type $1" exit 1 ;; esac rm -f ${temp_sql_grants} if [ "${retval}" = 0 ]; then echo "Privileges for user ${db_user} granted ON database ${db_name}." else echo "Error creating privileges." fi exit ${retval} bareos-Release-14.2.6/src/cats/ingres.c000077500000000000000000000677471263011562700176440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database routines specific to Ingres * These are Ingres specific routines * * Stefan Reddig, June 2009 with help of Marco van Wieringen April 2010 * based upon work done * by Dan Langille, December 2003 and * by Kern Sibbald, March 2000 * * Major rewrite by Marco van Wieringen, January 2010 for catalog refactoring. */ #include "bareos.h" #ifdef HAVE_INGRES #include "cats.h" #include "bdb_priv.h" #include "myingres.h" #include "bdb_ingres.h" #include "lib/breg.h" /* ----------------------------------------------------------------------- * * Ingres dependent defines and subroutines * * ----------------------------------------------------------------------- */ /* * List of open databases. */ static dlist *db_list = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct B_DB_RWRULE { int pattern_length; char *search_pattern; BREGEXP *rewrite_regexp; bool trigger; }; /* * Create a new query filter. */ static bool db_allocate_query_filter(JCR *jcr, alist *query_filters, int pattern_length, const char *search_pattern, const char *filter) { B_DB_RWRULE *rewrite_rule; rewrite_rule = (B_DB_RWRULE *)malloc(sizeof(B_DB_RWRULE)); rewrite_rule->pattern_length = pattern_length; rewrite_rule->search_pattern = bstrdup(search_pattern); rewrite_rule->rewrite_regexp = new_bregexp(filter); rewrite_rule->trigger = false; if (!rewrite_rule->rewrite_regexp) { Jmsg(jcr, M_FATAL, 0, _("Failed to allocate space for query filter.\n")); free(rewrite_rule->search_pattern); free(rewrite_rule); return false; } else { query_filters->append(rewrite_rule); return true; } } /* * Create a stack of all filters that should be applied to a SQL query * before submitting it to the database backend. */ static inline alist *db_initialize_query_filters(JCR *jcr) { alist *query_filters; query_filters = New(alist(10, not_owned_by_alist)); if (!query_filters) { Jmsg(jcr, M_FATAL, 0, _("Failed to allocate space for query filters.\n")); return NULL; } db_allocate_query_filter(jcr, query_filters, 6, "OFFSET", "/LIMIT ([0-9]+) OFFSET ([0-9]+)/OFFSET $2 FETCH NEXT $1 ROWS ONLY/ig"); db_allocate_query_filter(jcr, query_filters, 5, "LIMIT", "/LIMIT ([0-9]+)/FETCH FIRST $1 ROWS ONLY/ig"); db_allocate_query_filter(jcr, query_filters, 9, "TEMPORARY", "/CREATE TEMPORARY TABLE (.+)/DECLARE GLOBAL TEMPORARY TABLE $1 ON COMMIT PRESERVE ROWS WITH NORECOVERY/i"); return query_filters; } /* * Free all query filters. */ static inline void db_destroy_query_filters(alist *query_filters) { B_DB_RWRULE *rewrite_rule; foreach_alist(rewrite_rule, query_filters) { free_bregexp(rewrite_rule->rewrite_regexp); free(rewrite_rule->search_pattern); free(rewrite_rule); } delete query_filters; } B_DB_INGRES::B_DB_INGRES(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { B_DB_INGRES *mdb; int next_session_id = 0; /* * See what the next available session_id is. * We first see what the highest session_id is used now. */ if (db_list) { foreach_dlist(mdb, db_list) { if (mdb->m_session_id > next_session_id) { next_session_id = mdb->m_session_id; } } } /* * Initialize the parent class members. */ m_db_interface_type = SQL_INTERFACE_TYPE_INGRES; m_db_type = SQL_TYPE_INGRES; m_db_driver = bstrdup("ingres"); m_db_name = bstrdup(db_name); m_db_user = bstrdup(db_user); if (db_password) { m_db_password = bstrdup(db_password); } if (db_address) { m_db_address = bstrdup(db_address); } if (db_socket) { m_db_socket = bstrdup(db_socket); } m_db_port = db_port; if (disable_batch_insert) { m_disabled_batch_insert = true; m_have_batch_insert = false; } else { m_disabled_batch_insert = false; #if defined(USE_BATCH_FILE_INSERT) m_have_batch_insert = true; #else m_have_batch_insert = false; #endif } errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */ *errmsg = 0; cmd = get_pool_memory(PM_EMSG); /* get command buffer */ cached_path = get_pool_memory(PM_FNAME); cached_path_id = 0; m_ref_count = 1; fname = get_pool_memory(PM_FNAME); path = get_pool_memory(PM_FNAME); esc_name = get_pool_memory(PM_FNAME); esc_path = get_pool_memory(PM_FNAME); esc_obj = get_pool_memory(PM_FNAME); m_allow_transactions = mult_db_connections; m_is_private = need_private; /* * Initialize the private members. */ m_db_handle = NULL; m_result = NULL; m_explicit_commit = true; m_session_id = ++next_session_id; m_query_filters = db_initialize_query_filters(jcr); /* * Put the db in the list. */ if (db_list == NULL) { db_list = New(dlist(this, &this->m_link)); } db_list->append(this); } B_DB_INGRES::~B_DB_INGRES() { } /* * Now actually open the database. This can generate errors, * which are returned in the errmsg * * DO NOT close the database or delete mdb here !!!! */ bool B_DB_INGRES::db_open_database(JCR *jcr) { bool retval = false; int errstat; P(mutex); if (m_connected) { retval = true; goto bail_out; } if ((errstat=rwl_init(&m_lock)) != 0) { berrno be; Mmsg1(&errmsg, _("Unable to initialize DB lock. ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } m_db_handle = INGconnectDB(m_db_name, m_db_user, m_db_password, m_session_id); Dmsg0(50, "Ingres real CONNECT done\n"); Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", m_db_user, m_db_name, m_db_password == NULL ? "(NULL)" : m_db_password); if (!m_db_handle) { Mmsg2(&errmsg, _("Unable to connect to Ingres server.\n" "Database=%s User=%s\n" "It is probably not running or your password is incorrect.\n"), m_db_name, m_db_user); goto bail_out; } m_connected = true; INGsetDefaultLockingMode(m_db_handle); if (!check_tables_version(jcr, this)) { goto bail_out; } retval = true; bail_out: V(mutex); return retval; } void B_DB_INGRES::db_close_database(JCR *jcr) { if (m_connected) { db_end_transaction(jcr); } P(mutex); m_ref_count--; if (m_ref_count == 0) { if (m_connected) { sql_free_result(); } db_list->remove(this); if (m_connected && m_db_handle) { INGdisconnectDB(m_db_handle); } if (m_query_filters) { db_destroy_query_filters(m_query_filters); } if (rwl_is_init(&m_lock)) { rwl_destroy(&m_lock); } free_pool_memory(errmsg); free_pool_memory(cmd); free_pool_memory(cached_path); free_pool_memory(fname); free_pool_memory(path); free_pool_memory(esc_name); free_pool_memory(esc_path); free_pool_memory(esc_obj); free(m_db_driver); free(m_db_name); free(m_db_user); if (m_db_password) { free(m_db_password); } if (m_db_address) { free(m_db_address); } if (m_db_socket) { free(m_db_socket); } delete this; if (db_list->size() == 0) { delete db_list; db_list = NULL; } } V(mutex); } bool B_DB_INGRES::db_validate_connection(void) { bool retval; /* * Perform a null query to see if the connection is still valid. */ db_lock(this); if (!sql_query("SELECT 1", true)) { retval = false; goto bail_out; } sql_free_result(); retval = true; bail_out: db_unlock(this); return retval; } /* * Start a transaction. This groups inserts and makes things * much more efficient. Usually started when inserting * file attributes. */ void B_DB_INGRES::db_start_transaction(JCR *jcr) { if (!jcr->attr) { jcr->attr = get_pool_memory(PM_FNAME); } if (!jcr->ar) { jcr->ar = (ATTR_DBR *)malloc(sizeof(ATTR_DBR)); } if (!m_allow_transactions) { return; } db_lock(this); /* Allow only 25,000 changes per transaction */ if (m_transaction && changes > 25000) { db_end_transaction(jcr); } if (!m_transaction) { sql_query("BEGIN"); /* begin transaction */ Dmsg0(400, "Start Ingres transaction\n"); m_transaction = true; } db_unlock(this); } void B_DB_INGRES::db_end_transaction(JCR *jcr) { if (jcr && jcr->cached_attribute) { Dmsg0(400, "Flush last cached attribute.\n"); if (!db_create_attributes_record(jcr, this, jcr->ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } if (!m_allow_transactions) { return; } db_lock(this); if (m_transaction) { sql_query("COMMIT"); /* end transaction */ m_transaction = false; Dmsg1(400, "End Ingres transaction changes=%d\n", changes); } changes = 0; db_unlock(this); } /* * Submit a general SQL command (cmd), and for each row returned, * the result_handler is called with the ctx. */ bool B_DB_INGRES::db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { SQL_ROW row; bool retval = true; Dmsg1(500, "db_sql_query starts with %s\n", query); db_lock(this); if (!sql_query(query, QF_STORE_RESULT)) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror()); Dmsg0(500, "db_sql_query failed\n"); retval = false; goto bail_out; } if (result_handler != NULL) { Dmsg0(500, "db_sql_query invoking handler\n"); while ((row = sql_fetch_row()) != NULL) { Dmsg0(500, "db_sql_query sql_fetch_row worked\n"); if (result_handler(ctx, m_num_fields, row)) break; } sql_free_result(); } Dmsg0(500, "db_sql_query finished\n"); bail_out: db_unlock(this); return retval; } /* * Note, if this routine returns false (failure), BAREOS expects * that no result has been stored. * * Returns: true on success * false on failure * */ bool B_DB_INGRES::sql_query(const char *query, int flags) { int cols; char *cp, *bp; char *dup_query, *new_query; bool retval = true; bool start_of_transaction = false; bool end_of_transaction = false; B_DB_RWRULE *rewrite_rule; Dmsg1(500, "query starts with '%s'\n", query); /* * We always make a private copy of the query as we are doing serious * rewrites in this engine. When running the private copy through the * different query filters we loose the orginal private copy so we * first make a extra reference to it so we can free it on exit from the * function. */ dup_query = new_query = bstrdup(query); /* * Iterate over the query string and perform any needed operations. * We use a sliding window over the query string where bp points to * the previous position in the query and cp to the current position * in the query. */ bp = new_query; while (bp != NULL) { if ((cp = strchr(bp, ' ')) != NULL) { *cp++; } if (bstrncasecmp(bp, "BEGIN", 5)) { /* * This is the start of a transaction. * Inline copy the rest of the query over the BEGIN keyword. */ if (cp) { bstrinlinecpy(bp, cp); } else { *bp = '\0'; } start_of_transaction = true; } else if (bstrncasecmp(bp, "COMMIT", 6) && (cp == NULL || !bstrncasecmp(cp, "PRESERVE", 8))) { /* * This is the end of a transaction. We cannot check for just the COMMIT * keyword as a DECLARE of an tempory table also has the word COMMIT in it * but its followed by the word PRESERVE. * Inline copy the rest of the query over the COMMIT keyword. */ if (cp) { bstrinlinecpy(bp, cp); } else { *bp = '\0'; } end_of_transaction = true; } /* * See what query filter might match. */ foreach_alist(rewrite_rule, m_query_filters) { if (bstrncasecmp(bp, rewrite_rule->search_pattern, rewrite_rule->pattern_length)) { rewrite_rule->trigger = true; } } /* * Slide window. */ bp = cp; } /* * Run the query through all query filters that apply e.g. have the trigger set in the * previous loop. */ foreach_alist(rewrite_rule, m_query_filters) { if (rewrite_rule->trigger) { new_query = rewrite_rule->rewrite_regexp->replace(new_query); rewrite_rule->trigger = false; } } if (start_of_transaction) { Dmsg0(500,"sql_query: Start of transaction\n"); m_explicit_commit = false; } /* * See if there is any query left after filtering for certain keywords. */ bp = new_query; while (bp != NULL && strlen(bp) > 0) { /* * We are starting a new query. reset everything. */ m_num_rows = -1; m_row_number = -1; m_field_number = -1; if (m_result) { INGclear(m_result); /* hmm, someone forgot to free?? */ m_result = NULL; } /* * See if this is a multi-statement query. We split a multi-statement query * on the semi-column and feed the individual queries to the Ingres functions. * We use a sliding window over the query string where bp points to * the previous position in the query and cp to the current position * in the query. */ if ((cp = strchr(bp, ';')) != NULL) { *cp++ = '\0'; } Dmsg1(500, "sql_query after rewrite continues with '%s'\n", bp); /* * See if we got a store_result hint which could mean we are running a select. * If flags has QF_STORE_RESULT not set we are sure its not a query that we * need to store anything for. */ if (flags & QF_STORE_RESULT) { cols = INGgetCols(m_db_handle, bp, m_explicit_commit); } else { cols = 0; } if (cols <= 0) { if (cols < 0 ) { Dmsg0(500,"sql_query: neg.columns: no DML stmt!\n"); retval = false; goto bail_out; } Dmsg0(500,"sql_query (non SELECT) starting...\n"); /* * non SELECT */ m_num_rows = INGexec(m_db_handle, bp, m_explicit_commit); if (m_num_rows == -1) { Dmsg0(500,"sql_query (non SELECT) went wrong\n"); retval = false; goto bail_out; } else { Dmsg0(500,"sql_query (non SELECT) seems ok\n"); } } else { /* * SELECT */ Dmsg0(500,"sql_query (SELECT) starting...\n"); m_result = INGquery(m_db_handle, bp, m_explicit_commit); if (m_result != NULL) { Dmsg0(500, "we have a result\n"); /* * How many fields in the set? */ m_num_fields = (int)INGnfields(m_result); Dmsg1(500, "we have %d fields\n", m_num_fields); m_num_rows = INGntuples(m_result); Dmsg1(500, "we have %d rows\n", m_num_rows); } else { Dmsg0(500, "No resultset...\n"); retval = false; goto bail_out; } } bp = cp; } bail_out: if (end_of_transaction) { Dmsg0(500,"sql_query: End of transaction, commiting work\n"); m_explicit_commit = true; INGcommit(m_db_handle); } free(dup_query); Dmsg0(500, "sql_query finishing\n"); return retval; } void B_DB_INGRES::sql_free_result(void) { db_lock(this); if (m_result) { INGclear(m_result); m_result = NULL; } if (m_rows) { free(m_rows); m_rows = NULL; } if (m_fields) { free(m_fields); m_fields = NULL; } m_num_rows = m_num_fields = 0; db_unlock(this); } SQL_ROW B_DB_INGRES::sql_fetch_row(void) { int j; SQL_ROW row = NULL; /* by default, return NULL */ if (!m_result) { return row; } if (m_result->num_rows <= 0) { return row; } Dmsg0(500, "sql_fetch_row start\n"); if (!m_rows || m_rows_size < m_num_fields) { if (m_rows) { Dmsg0(500, "sql_fetch_row freeing space\n"); free(m_rows); } Dmsg1(500, "we need space for %d bytes\n", sizeof(char *) * m_num_fields); m_rows = (SQL_ROW)malloc(sizeof(char *) * m_num_fields); m_rows_size = m_num_fields; /* * Now reset the row_number now that we have the space allocated */ m_row_number = 0; } /* * If still within the result set */ if (m_row_number < m_num_rows) { Dmsg2(500, "sql_fetch_row row number '%d' is acceptable (0..%d)\n", m_row_number, m_num_rows); /* * Get each value from this row */ for (j = 0; j < m_num_fields; j++) { m_rows[j] = INGgetvalue(m_result, m_row_number, j); Dmsg2(500, "sql_fetch_row field '%d' has value '%s'\n", j, m_rows[j]); } /* * Increment the row number for the next call */ m_row_number++; row = m_rows; } else { Dmsg2(500, "sql_fetch_row row number '%d' is NOT acceptable (0..%d)\n", m_row_number, m_num_rows); } Dmsg1(500, "sql_fetch_row finishes returning %p\n", row); return row; } const char *B_DB_INGRES::sql_strerror(void) { return INGerrorMessage(m_db_handle); } void B_DB_INGRES::sql_data_seek(int row) { /* * Set the row number to be returned on the next call to sql_fetch_row */ m_row_number = row; } int B_DB_INGRES::sql_affected_rows(void) { return m_num_rows; } /* * First execute the insert query and then retrieve the currval. * By setting transaction to true we make it an atomic transaction * and as such we can get the currval after which we commit if * transaction is false. This way things are an atomic operation * for Ingres and things work. We save the current transaction status * and set transaction in the mdb to true and at the end of this * function we restore the actual transaction status. */ uint64_t B_DB_INGRES::sql_insert_autokey_record(const char *query, const char *table_name) { char sequence[64]; char getkeyval_query[256]; char *currval; uint64_t id = 0; bool current_explicit_commit; /* * Save the current transaction status and pretend we are in a transaction. */ current_explicit_commit = m_explicit_commit; m_explicit_commit = false; /* * Execute the INSERT query. */ m_num_rows = INGexec(m_db_handle, query, m_explicit_commit); if (m_num_rows == -1) { goto bail_out; } changes++; /* * Obtain the current value of the sequence that * provides the serial value for primary key of the table. * * currval is local to our session. It is not affected by * other transactions. * * Determine the name of the sequence. * As we name all sequences as
_seq this is easy. */ bstrncpy(sequence, table_name, sizeof(sequence)); bstrncat(sequence, "_seq", sizeof(sequence)); bsnprintf(getkeyval_query, sizeof(getkeyval_query), "SELECT %s.currval FROM %s", sequence, table_name); if (m_result) { INGclear(m_result); m_result = NULL; } m_result = INGquery(m_db_handle, getkeyval_query, m_explicit_commit); if (!m_result) { Dmsg1(50, "Query failed: %s\n", getkeyval_query); goto bail_out; } Dmsg0(500, "exec done"); currval = INGgetvalue(m_result, 0, 0); if (currval) { id = str_to_uint64(currval); } INGclear(m_result); m_result = NULL; bail_out: /* * Restore the actual explicit_commit status. */ m_explicit_commit = current_explicit_commit; /* * Commit if explicit_commit is not set. */ if (m_explicit_commit) { INGcommit(m_db_handle); } return id; } SQL_FIELD *B_DB_INGRES::sql_fetch_field(void) { int i, j; int max_length; int this_length; if (!m_fields || m_fields_size < m_num_fields) { if (m_fields) { free(m_fields); m_fields = NULL; } Dmsg1(500, "allocating space for %d fields\n", m_num_fields); m_fields = (SQL_FIELD *)malloc(sizeof(SQL_FIELD) * m_num_fields); m_fields_size = m_num_fields; for (i = 0; i < m_num_fields; i++) { Dmsg1(500, "filling field %d\n", i); m_fields[i].name = INGfname(m_result, i); m_fields[i].type = INGftype(m_result, i); m_fields[i].flags = 0; /* * For a given column, find the max length. */ max_length = 0; for (j = 0; j < m_num_rows; j++) { if (INGgetisnull(m_result, j, i)) { this_length = 4; /* "NULL" */ } else { this_length = cstrlen(INGgetvalue(m_result, j, i)); } if (max_length < this_length) { max_length = this_length; } } m_fields[i].max_length = max_length; Dmsg4(500, "sql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", m_fields[i].name, m_fields[i].max_length, m_fields[i].type, m_fields[i].flags); } } /* * Increment field number for the next time around */ return &m_fields[m_field_number++]; } bool B_DB_INGRES::sql_field_is_not_null(int field_type) { switch (field_type) { case 1: return true; default: return false; } } bool B_DB_INGRES::sql_field_is_numeric(int field_type) { /* * See ${II_SYSTEM}/ingres/files/eqsqlda.h for numeric types. */ switch (field_type) { case IISQ_DEC_TYPE: case IISQ_INT_TYPE: case IISQ_FLT_TYPE: return true; default: return false; } } /* * Escape strings so that Ingres is happy on COPY * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. */ static char *ingres_copy_escape(char *dest, char *src, size_t len) { /* we have to escape \t, \n, \r, \ */ char c = '\0' ; while (len > 0 && *src) { switch (*src) { case '\n': c = 'n'; break; case '\\': c = '\\'; break; case '\t': c = 't'; break; case '\r': c = 'r'; break; default: c = '\0' ; } if (c) { *dest = '\\'; dest++; *dest = c; } else { *dest = *src; } len--; src++; dest++; } *dest = '\0'; return dest; } /* * Returns true if OK * false if failed */ bool B_DB_INGRES::sql_batch_start(JCR *jcr) { bool ok; db_lock(this); ok = sql_query("DECLARE GLOBAL TEMPORARY TABLE batch (" "FileIndex INTEGER," "JobId INTEGER," "Path VARBYTE(32000)," "Name VARBYTE(32000)," "LStat VARBYTE(255)," "MD5 VARBYTE(255)," "DeltaSeq SMALLINT)" " ON COMMIT PRESERVE ROWS WITH NORECOVERY"); db_unlock(this); return ok; } /* * Returns true if OK * false if failed */ bool B_DB_INGRES::sql_batch_end(JCR *jcr, const char *error) { m_status = 0; return true; } /* * Returns true if OK * false if failed */ bool B_DB_INGRES::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) { size_t len; const char *digest; char ed1[50]; esc_name = check_pool_memory_size(esc_name, fnl*2+1); db_escape_string(jcr, esc_name, fname, fnl); esc_path = check_pool_memory_size(esc_path, pnl*2+1); db_escape_string(jcr, esc_path, path, pnl); if (ar->Digest == NULL || ar->Digest[0] == 0) { digest = "0"; } else { digest = ar->Digest; } len = Mmsg(cmd, "INSERT INTO batch VALUES " "(%u,%s,'%s','%s','%s','%s',%u)", ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); return sql_query(cmd); } /* * Initialize database data structure. In principal this should * never have errors, or it is really fatal. */ #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" B_DB CATS_IMP_EXP *backend_instantiate(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #else B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #endif { B_DB_INGRES *mdb = NULL; if (!db_user) { Jmsg(jcr, M_FATAL, 0, _("A user name for Ingres must be supplied.\n")); return NULL; } P(mutex); /* lock DB queue */ /* * Look to see if DB already open */ if (db_list && !mult_db_connections && !need_private) { foreach_dlist(mdb, db_list) { if (mdb->is_private()) { continue; } if (mdb->db_match_database(db_driver, db_name, db_address, db_port)) { Dmsg1(100, "DB REopen %s\n", db_name); mdb->increment_refcount(); goto bail_out; } } } Dmsg0(100, "db_init_database first time\n"); mdb = New(B_DB_INGRES(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private)); bail_out: V(mutex); return mdb; } #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" void CATS_IMP_EXP flush_backend(void) #else void db_flush_backends(void) #endif { } #endif /* HAVE_INGRES */ bareos-Release-14.2.6/src/cats/install-default-backend.in000077500000000000000000000017311263011562700231730ustar00rootroot00000000000000#!/bin/sh LIBTOOL="@BUILD_DIR@/libtool" if [ $# -lt 3 ]; then echo "Usage: $0 " exit 1 fi default_backend=$1 library_version=$2 install_dir=$3 # # Find out what the shared lib extension is for this platform. # eval `${LIBTOOL} --config | grep shrext_cmds` eval SHLIB_EXT=$shrext_cmds if [ -z "${SHLIB_EXT}" ]; then echo "Failed to determine default shared library extension" exit 1 fi if [ -f ${install_dir}/libbareoscats-${default_backend}-${library_version}${SHLIB_EXT} ]; then # # Create a default catalog library pointing to one of the shared libs. # rm -f ${install_dir}/libbareoscats-${library_version}${SHLIB_EXT} # # Create a relative symlink to the default backend # As all backends are in the same directory anyhow this should # always work. # ln -s libbareoscats-${default_backend}${SHLIB_EXT} \ ${install_dir}/libbareoscats-${library_version}${SHLIB_EXT} fi exit 0 bareos-Release-14.2.6/src/cats/lock_check000066400000000000000000000011061263011562700201670ustar00rootroot00000000000000#!/bin/sh # # This is a small script which counts the number of db_lock and db_unlocks are # used in the code. With the current coding standard you should have exactly # the same number of db_lock and db_unlock calls. # if [ $# -gt 0 ]; then files="$*" else files=`ls -1 *.c` fi for file in ${files} do nr_locks=`grep -c ' db_lock(' ${file}` nr_unlocks=`grep -c ' db_unlock(' ${file}` if [ ${nr_locks} -gt 0 ]; then if [ ${nr_locks} != ${nr_unlocks} ]; then echo "${file} ==> ${nr_locks} db_locks and ${nr_unlocks} db_unlocks !!!" fi fi done bareos-Release-14.2.6/src/cats/make_bareos_tables.in000066400000000000000000000074211263011562700223170ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This routine makes the appropriately configured # Bareos tables for PostgreSQL, Ingres, MySQL, or SQLite. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" db_version=`get_database_version` bareos_sql_ddl=`get_database_ddl_dir` temp_sql_schema="/tmp/creates.sql.$$" default_db_type=`get_database_driver_default` working_dir=`get_working_dir` # # See if the first argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -gt 0 ]; then case $1 in sqlite3) db_type=$1 shift ;; mysql) db_type=$1 shift ;; postgresql) db_type=$1 shift ;; ingres) db_type=$1 shift ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi echo "Making ${db_type} tables" case ${db_type} in sqlite3) sql_definitions="${bareos_sql_ddl}/creates/sqlite3.sql" ;; mysql) sql_definitions="${bareos_sql_ddl}/creates/mysql.sql" ;; postgresql) sql_definitions="${bareos_sql_ddl}/creates/postgresql.sql" ;; ingres) sql_definitions="${bareos_sql_ddl}/creates/ingres.sql" ;; *) echo "Unknown database type $1" exit 1 ;; esac if [ ! -z "${sql_definitions}" ]; then if [ ! -f ${sql_definitions} ]; then echo "Unable to open database table definitions in file ${sql_definitions}" exit 1 fi get_translated_sql_file ${sql_definitions} > ${temp_sql_schema} if [ $? != 0 ]; then echo "Failed to translate SQL definitions in ${sql_definitions}" exit 1 fi fi bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi case ${db_type} in sqlite3) sqlite3 $* ${working_dir}/${db_name}.db < ${temp_sql_schema} chmod 640 ${working_dir}/${db_name}.db retval=0 ;; mysql) mysql $* --database=${db_name} -f < ${temp_sql_schema} retval=$? if test $retval = 0; then echo "Creation of Bareos MySQL tables succeeded." else echo "Creation of Bareos MySQL tables failed." fi ;; postgresql) psql -f ${temp_sql_schema} -d ${db_name} $* retval=$? if test $retval = 0; then echo "Creation of Bareos PostgreSQL tables succeeded." else echo "Creation of Bareos PostgreSQL tables failed." fi ;; ingres) sql -u${db_user} $* ${db_name} < ${temp_sql_schema} retval=$? if test $retval = 0; then echo "Creation of Bareos Ingres tables succeeded." else echo "Creation of Bareos Ingres tables failed." fi ;; esac rm -f ${temp_sql_schema} exit ${retval} bareos-Release-14.2.6/src/cats/make_catalog_backup.in000077500000000000000000000066661263011562700224660ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This script dumps your Bareos catalog in ASCII format # It works for MySQL, SQLite, and PostgreSQL # # $1 is the name of the database to be backed up and the name # of the output file (default = bareos). # $2 is the user name with which to access the database # (default = bareos). # $3 is the password with which to access the database or "" if no password # (default ""). WARNING!!! Passing the password via the command line is # insecure and should not be used since any user can display the command # line arguments and the environment using ps. Please consult your # MySQL or PostgreSQL manual for secure methods of specifying the # password. # $4 is the host on which the database is located # (default "") # $5 is the type of database # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh working_dir=`get_working_dir` default_db_type=`get_database_driver_default` # # See if the fifth argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -ge 5 ]; then case $5 in sqlite3) db_type=$5 ;; mysql) db_type=$5 ;; postgresql) db_type=$5 ;; ingres) db_type=$5 ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi cd ${working_dir} rm -f $1.sql bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi case ${db_type} in sqlite3) echo ".dump" | sqlite3 $1.db > $1.sql ;; mysql) if test $# -gt 2; then MYSQLPASSWORD=" --password=$3" else MYSQLPASSWORD="" fi if test $# -gt 3; then MYSQLHOST=" --host=$4" else MYSQLHOST="" fi mysqldump -u ${2}${MYSQLPASSWORD}${MYSQLHOST} -f --opt $1 > $1.sql ;; postgresql) if test $# -gt 2; then PGPASSWORD=$3 export PGPASSWORD fi if test $# -gt 3; then PGHOST=" --host=$4" else PGHOST="" fi # you could also add --compress for compression. See man pg_dump pg_dump -c $PGHOST -U $2 $1 > $1.sql ;; esac # # To read back a MySQL database use: # cd @working_dir@ # rm -f ${BINDIR}/../var/bareos/* # mysql '$wd/$args{db_name}.sql'"); print "Error while executing sqlite dump $!\n"; return 1; } # TODO: use just ENV and drop the pg_service.conf file sub dump_pgsql { my %args = @_; umask(0077); if ($args{db_address}) { $ENV{PGHOST}=$args{db_address}; } if ($args{db_socket}) { $ENV{PGHOST}=$args{db_socket}; } if ($args{db_port}) { $ENV{PGPORT}=$args{db_port}; } if ($args{db_user}) { $ENV{PGUSER}=$args{db_user}; } if ($args{db_password}) { $ENV{PGPASSWORD}=$args{db_password}; } $ENV{PGDATABASE}=$args{db_name}; exec("HOME='$wd' pg_dump -c > '$wd/$args{db_name}.sql'"); print "Error while executing postgres dump $!\n"; return 1; # in case of error } sub dump_mysql { my %args = @_; umask(0077); unlink("$wd/.my.cnf"); open(MY, ">$wd/.my.cnf") or die "Can't open $wd/.my.cnf for writing $@"; $args{db_address} = $args{db_address} || "localhost"; my $addr = "host=$args{db_address}"; if ($args{db_socket}) { # unix socket is fastest than net socket $addr = "socket=$args{db_socket}"; } print MY "[client] $addr user=$args{db_user} password=\"$args{db_password}\" "; if ($args{db_port}) { print MY "port=$args{db_port}\n"; } close(MY); exec("HOME='$wd' mysqldump -f --opt $args{db_name} > '$wd/$args{db_name}.sql'"); print "Error while executing mysql dump $!\n"; return 1; } sub dump_catalog { my %args = @_; if ($args{db_type} eq 'SQLite3') { $ENV{PATH}="@SQLITE_BINDIR@:$ENV{PATH}"; dump_sqlite3(%args); } elsif ($args{db_type} eq 'PostgreSQL') { $ENV{PATH}="@POSTGRESQL_BINDIR@:$ENV{PATH}"; dump_pgsql(%args); } elsif ($args{db_type} eq 'MySQL') { $ENV{PATH}="@MYSQL_BINDIR@:$ENV{PATH}"; dump_mysql(%args); } else { die "This database type isn't supported"; } } open(FP, "$dir_conf -C '$cat'|") or die "Can't get catalog information $@"; # catalog=MyCatalog # db_type=SQLite # db_name=regress # db_driver= # db_user=regress # db_password= # db_address= # db_port=0 # db_socket= my %cfg; while(my $l = ) { if ($l =~ /catalog=(.+)/) { if (exists $cfg{catalog} and $cfg{catalog} eq $cat) { exit dump_catalog(%cfg); } %cfg = (); # reset } if ($l =~ /(\w+)=(.+)/) { $cfg{$1}=$2; } } if (exists $cfg{catalog} and $cfg{catalog} eq $cat) { exit dump_catalog(%cfg); } print "Can't find your catalog ($cat) in director configuration\n"; exit 1; bareos-Release-14.2.6/src/cats/make_ingres_catalog_backup.in000077500000000000000000000046011263011562700240200ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # shell script to make a dump of the bareos Ingres database using copydb and make # a base64 encoded tar of the content. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-@db_name@}" db_user="${db_user:-@db_user@}" working_dir=`get_working_dir` bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi # # Source the Ingres settings when they exist. # if [ ! -z "${bindir}" ]; then [ -f ${bindir}/../../.ingIIsh ] && . ${bindir}/../../.ingIIsh fi # # See if the dumpdir exists. # [ ! -d ${working_dir}/ingres_dump ] && mkdir -p ${working_dir}/ingres_dump # # Generate the copy.in and copy.out file # copydb \ ${db_name} \ -u${db_user} \ -dest=${working_dir}/ingres_dump \ -d ${working_dir}/ingres_dump \ > /dev/null 2>&1 # # If copydb created a copy.out file run it. # if [ -f ${working_dir}/ingres_dump/copy.out ]; then # # Run the sql to create the dumps of the tables. # sql \ -u${db_user} \ ${db_name} \ < ${working_dir}/ingres_dump/copy.out \ > /dev/null 2>&1 && rm ${working_dir}/ingres_dump/copy.out # # Tar up the dump and uuencode it. # cd ${working_dir}/ingres_dump || exit 1 case `uname -s` in Linux) tar cf - . | gzip -c | base64 ;; SunOS) tar cf - . | gzip -c | uuencode -m - ;; *) echo "Unsupported OS type encountered, `uname -s`" exit 1 ;; esac cd / rm -rf ${working_dir}/ingres_dump fi exit 0 bareos-Release-14.2.6/src/cats/myingres.c000066400000000000000000000660171263011562700201740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA */ /* * BAREOS Catalog Database routines specific to Ingres * These are Ingres specific routines * * Stefan Reddig, June 2009 with help of Marco van Wieringen April 2010 */ #include "bareos.h" /* # line 37 "myingres.sc" */ #ifdef HAVE_INGRES #include #include #include #include #include #include #include #include "myingres.h" #ifdef __cplusplus extern "C" { #endif IISQLCA *IIsqlca(); #ifdef __cplusplus } #endif #define sqlca (*(IIsqlca())) /* * ---Implementations--- */ int INGgetCols(INGconn *dbconn, const char *query, bool explicit_commit) { /* # line 52 "myingres.sc" */ int sess_id; char *stmt; /* # line 55 "myingres.sc" */ IISQLDA *sqlda; int number = -1; sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + IISQDA_VAR_SIZE); memset(sqlda, 0, (IISQDA_HEAD_SIZE + IISQDA_VAR_SIZE)); sqlda->sqln = number; stmt = bstrdup(query); /* # line 68 "myingres.sc" */ /* host code */ /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; /* # line 72 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } /* # line 74 "myingres.sc" */ /* prepare */ { IIsqInit(&sqlca); IIsqPrepare(0,(char *)"s1",sqlda,0,stmt); if (sqlca.sqlcode < 0) goto bail_out; } /* # line 78 "myingres.sc" */ /* host code */ number = sqlda->sqld; bail_out: /* * If explicit_commit is set we commit our work now. */ if (explicit_commit) { /* # line 85 "myingres.sc" */ /* commit */ { IIsqInit(&sqlca); IIxact(3); } /* # line 86 "myingres.sc" */ /* host code */ } /* * Switch to no default session for this thread. */ /* # line 91 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 92 "myingres.sc" */ /* host code */ free(stmt); free(sqlda); return number; } static inline IISQLDA *INGgetDescriptor(int numCols, const char *query) { /* # line 99 "myingres.sc" */ char *stmt; /* # line 101 "myingres.sc" */ int i; IISQLDA *sqlda; sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)); memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE))); sqlda->sqln = numCols; stmt = bstrdup(query); /* # line 112 "myingres.sc" */ /* prepare */ { IIsqInit(&sqlca); IIsqPrepare(0,(char *)"s2",sqlda,0,stmt); } /* # line 114 "myingres.sc" */ /* host code */ for (i = 0; i < sqlda->sqld; ++i) { /* * Negative type indicates nullable columns, so an indicator * is allocated, otherwise it's null */ if (sqlda->sqlvar[i].sqltype > 0) { sqlda->sqlvar[i].sqlind = NULL; } else { sqlda->sqlvar[i].sqlind = (short *)malloc(sizeof(short)); } /* * Alloc space for variable like indicated in sqllen * for date types sqllen is always 0 -> allocate by type */ switch (abs(sqlda->sqlvar[i].sqltype)) { case IISQ_TSW_TYPE: sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN); break; case IISQ_TSWO_TYPE: sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN); break; case IISQ_TSTMP_TYPE: sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN); break; default: /* * plus one to avoid zero mem allocs */ sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen + 1); break; } } free(stmt); return sqlda; } static void INGfreeDescriptor(IISQLDA *sqlda) { int i; if (!sqlda) { return; } for (i = 0; i < sqlda->sqld; ++i) { if (sqlda->sqlvar[i].sqldata) { free(sqlda->sqlvar[i].sqldata); } if (sqlda->sqlvar[i].sqlind) { free(sqlda->sqlvar[i].sqlind); } } free(sqlda); } static inline int INGgetTypeSize(IISQLVAR *ingvar) { int inglength = 0; switch (ingvar->sqltype) { case IISQ_TSWO_TYPE: inglength = 20; break; case IISQ_TSW_TYPE: inglength = 20; break; case IISQ_DTE_TYPE: inglength = 25; break; case IISQ_MNY_TYPE: inglength = 8; break; default: inglength = ingvar->sqllen; break; } return inglength; } static inline INGresult *INGgetINGresult(int numCols, const char *query) { int i; INGresult *ing_res; ing_res = (INGresult *)malloc(sizeof(INGresult)); memset(ing_res, 0, sizeof(INGresult)); if ((ing_res->sqlda = INGgetDescriptor(numCols, query)) == NULL) { return NULL; } ing_res->num_fields = ing_res->sqlda->sqld; ing_res->num_rows = 0; ing_res->first_row = NULL; ing_res->status = ING_EMPTY_RESULT; ing_res->act_row = NULL; if (ing_res->num_fields) { ing_res->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * ing_res->num_fields); memset(ing_res->fields, 0, sizeof(INGRES_FIELD) * ing_res->num_fields); for (i = 0; i < ing_res->num_fields; ++i) { ing_res->fields[i].name = (char *)malloc(ing_res->sqlda->sqlvar[i].sqlname.sqlnamel + 1); bstrncpy(ing_res->fields[i].name, ing_res->sqlda->sqlvar[i].sqlname.sqlnamec, ing_res->sqlda->sqlvar[i].sqlname.sqlnamel + 1); ing_res->fields[i].name[ing_res->sqlda->sqlvar[i].sqlname.sqlnamel] = '\0'; ing_res->fields[i].max_length = INGgetTypeSize(&ing_res->sqlda->sqlvar[i]); ing_res->fields[i].type = abs(ing_res->sqlda->sqlvar[i].sqltype); ing_res->fields[i].flags = (ing_res->sqlda->sqlvar[i].sqltype < 0) ? 1 : 0; } } return ing_res; } static inline void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda) { int i; if (row == NULL || sqlda == NULL) { return; } for (i = 0; i < sqlda->sqld; ++i) { if (row->sqlvar[i].sqldata) { free(row->sqlvar[i].sqldata); } if (row->sqlvar[i].sqlind) { free(row->sqlvar[i].sqlind); } } free(row->sqlvar); free(row); } static void INGfreeINGresult(INGresult *ing_res) { int i; int rows; ING_ROW *rowtemp; if (!ing_res) { return; } /* * Use of rows is a nasty workaround til I find the reason, * why aggregates like max() don't work */ rows = ing_res->num_rows; ing_res->act_row = ing_res->first_row; while (ing_res->act_row != NULL && rows > 0) { rowtemp = ing_res->act_row->next; INGfreeRowSpace(ing_res->act_row, ing_res->sqlda); ing_res->act_row = rowtemp; --rows; } if (ing_res->fields) { for (i = 0; i < ing_res->num_fields; ++i) { free(ing_res->fields[i].name); } free(ing_res->fields); } INGfreeDescriptor(ing_res->sqlda); free(ing_res); } static inline ING_ROW *INGgetRowSpace(INGresult *ing_res) { int i; unsigned short len; /* used for VARCHAR type length */ unsigned short th, tm, ts; IISQLDA *sqlda; ING_ROW *row = NULL; ING_TIMESTAMP *tsp; IISQLVAR *vars = NULL; row = (ING_ROW *)malloc(sizeof(ING_ROW)); memset(row, 0, sizeof(ING_ROW)); sqlda = ing_res->sqlda; vars = (IISQLVAR *)malloc(sizeof(IISQLVAR) * sqlda->sqld); memset(vars, 0, sizeof(IISQLVAR) * sqlda->sqld); row->sqlvar = vars; row->next = NULL; for (i = 0; i < sqlda->sqld; ++i) { /* * Make strings out of the data, then the space and assign * (why string? at least it seems that way, looking into the sources) */ vars[i].sqlind = (short *)malloc(sizeof(short)); if (sqlda->sqlvar[i].sqlind) { memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short)); } else { *vars[i].sqlind = NULL; } /* * if sqlind pointer exists AND points to -1 -> column is 'null' */ if ( *vars[i].sqlind && (*vars[i].sqlind == -1)) { vars[i].sqldata = NULL; } else { switch (ing_res->fields[i].type) { case IISQ_VCH_TYPE: case IISQ_LVCH_TYPE: case IISQ_VBYTE_TYPE: case IISQ_LBYTE_TYPE: case IISQ_NVCHR_TYPE: case IISQ_LNVCHR_TYPE: len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len; vars[i].sqldata = (char *)malloc(len + 1); memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata + 2,len); vars[i].sqldata[len] = '\0'; break; case IISQ_CHA_TYPE: case IISQ_BYTE_TYPE: case IISQ_NCHR_TYPE: vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length + 1); memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen); vars[i].sqldata[ing_res->fields[i].max_length] = '\0'; break; case IISQ_INT_TYPE: switch (sqlda->sqlvar[i].sqllen) { case 2: vars[i].sqldata = (char *)malloc(6); memset(vars[i].sqldata, 0, 6); bsnprintf(vars[i].sqldata, 6, "%d",*(int16_t *)sqlda->sqlvar[i].sqldata); break; case 4: vars[i].sqldata = (char *)malloc(11); memset(vars[i].sqldata, 0, 11); bsnprintf(vars[i].sqldata, 11, "%ld",*(int32_t *)sqlda->sqlvar[i].sqldata); break; case 8: vars[i].sqldata = (char *)malloc(20); memset(vars[i].sqldata, 0, 20); bsnprintf(vars[i].sqldata, 20, "%lld",*(int64_t *)sqlda->sqlvar[i].sqldata); break; } break; case IISQ_TSTMP_TYPE: vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN + 1); vars[i].sqldata[IISQ_TSTMP_LEN] = '\0'; break; case IISQ_TSWO_TYPE: tsp = (ING_TIMESTAMP *)sqlda->sqlvar[i].sqldata; th = tsp->secs / 3600; /* hours */ tm = tsp->secs % 3600; /* remaining seconds */ tm = tm / 60; /* minutes */ ts = tsp->secs - (th * 3600) - (tm * 60); /* seconds */ vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN + 1); bsnprintf(vars[i].sqldata, IISQ_TSWO_LEN + 1, "%04u-%02u-%02u %02u:%02u:%02u", tsp->year, tsp->month, tsp->day, th, tm, ts); break; case IISQ_TSW_TYPE: tsp = (ING_TIMESTAMP *)sqlda->sqlvar[i].sqldata; th = tsp->secs / 3600; /* hours */ tm = tsp->secs % 3600; /* remaining seconds */ tm = tm / 60; /* minutes */ ts = tsp->secs - (th * 3600) - (tm * 60); /* seconds */ vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN + 1); bsnprintf(vars[i].sqldata, IISQ_TSW_LEN + 1, "%04u-%02u-%02u %02u:%02u:%02u", tsp->year, tsp->month, tsp->day, th, tm, ts); break; default: Jmsg(NULL, M_FATAL, 0, "INGgetRowSpace: encountered unhandled database datatype %d please report this as a bug\n", ing_res->fields[i].type); break; } } } return row; } static inline int INGfetchAll(INGresult *ing_res) { ING_ROW *row; IISQLDA *desc; int linecount = -1; desc = ing_res->sqlda; /* # line 409 "myingres.sc" */ /* open */ { IIsqInit(&sqlca); IIcsOpen((char *)"c2",20273,8927); IIwritio(0,(short *)0,1,32,0,(char *)"s2"); IIcsQuery((char *)"c2",20273,8927); if (sqlca.sqlcode < 0) goto bail_out; } /* # line 413 "myingres.sc" */ /* host code */ linecount = 0; do { /* # line 415 "myingres.sc" */ /* fetch */ { IIsqInit(&sqlca); if (IIcsRetScroll((char *)"c2",20273,8927,-1,-1) != 0) { IIcsDaGet(0,desc); IIcsERetrieve(); } /* IIcsRetrieve */ } /* # line 417 "myingres.sc" */ /* host code */ if (sqlca.sqlcode == 0 || sqlca.sqlcode == -40202) { /* * Allocate space for fetched row */ row = INGgetRowSpace(ing_res); /* * Initialize list when encountered first time */ if (ing_res->first_row == 0) { ing_res->first_row = row; /* head of the list */ ing_res->first_row->next = NULL; ing_res->act_row = ing_res->first_row; } ing_res->act_row->next = row; /* append row to old act_row */ ing_res->act_row = row; /* set row as act_row */ row->row_number = linecount++; } } while ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) ); /* # line 438 "myingres.sc" */ /* close */ { IIsqInit(&sqlca); IIcsClose((char *)"c2",20273,8927); } /* # line 440 "myingres.sc" */ /* host code */ ing_res->status = ING_COMMAND_OK; ing_res->num_rows = linecount; bail_out: return linecount; } static inline ING_STATUS INGresultStatus(INGresult *ing_res) { if (ing_res == NULL) { return ING_NO_RESULT; } else { return ing_res->status; } } static void INGrowSeek(INGresult *ing_res, int row_number) { ING_ROW *trow = NULL; if (ing_res->act_row->row_number == row_number) { return; } /* * TODO: real error handling */ if (row_number < 0 || row_number > ing_res->num_rows) { return; } for (trow = ing_res->first_row; trow->row_number != row_number; trow = trow->next) ; ing_res->act_row = trow; /* * Note - can be null - if row_number not found, right? */ } char *INGgetvalue(INGresult *ing_res, int row_number, int column_number) { if (row_number != ing_res->act_row->row_number) { INGrowSeek(ing_res, row_number); } return ing_res->act_row->sqlvar[column_number].sqldata; } bool INGgetisnull(INGresult *ing_res, int row_number, int column_number) { if (row_number != ing_res->act_row->row_number) { INGrowSeek(ing_res, row_number); } return (*ing_res->act_row->sqlvar[column_number].sqlind == -1) ? true : false; } int INGntuples(const INGresult *ing_res) { return ing_res->num_rows; } int INGnfields(const INGresult *ing_res) { return ing_res->num_fields; } char *INGfname(const INGresult *ing_res, int column_number) { if ((column_number > ing_res->num_fields) || (column_number < 0)) { return NULL; } else { return ing_res->fields[column_number].name; } } short INGftype(const INGresult *ing_res, int column_number) { return ing_res->fields[column_number].type; } int INGexec(INGconn *dbconn, const char *query, bool explicit_commit) { /* # line 522 "myingres.sc" */ int sess_id; int rowcount; int errors; char *stmt; /* # line 527 "myingres.sc" */ rowcount = -1; stmt = bstrdup(query); /* # line 534 "myingres.sc" */ /* host code */ /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; /* # line 538 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } /* # line 540 "myingres.sc" */ /* execute */ { IIsqInit(&sqlca); IIsqExImmed(stmt); IIsyncup((char *)0,0); if (sqlca.sqlcode < 0) goto bail_out; } /* # line 541 "myingres.sc" */ /* inquire_ingres */ { IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8); } /* # line 543 "myingres.sc" */ /* host code */ /* * See if the negative rowcount is due to errors. */ if (rowcount < 0) { /* # line 547 "myingres.sc" */ /* inquire_ingres */ { IILQisInqSqlio((short *)0,1,30,sizeof(errors),&errors,0); } /* # line 549 "myingres.sc" */ /* host code */ /* * If the number of errors is 0 we got a negative rowcount * because the statement we executed doesn't give a rowcount back. * Lets pretend we have a rowcount of 1 then. */ if (errors == 0) { rowcount = 1; } } /* # line 561 "myingres.sc" */ /* host code */ bail_out: /* * If explicit_commit is set we commit our work now. */ if (explicit_commit) { /* # line 566 "myingres.sc" */ /* commit */ { IIsqInit(&sqlca); IIxact(3); } /* # line 567 "myingres.sc" */ /* host code */ } /* * Switch to no default session for this thread. */ /* # line 572 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 573 "myingres.sc" */ /* host code */ free(stmt); return rowcount; } INGresult *INGquery(INGconn *dbconn, const char *query, bool explicit_commit) { /* * TODO: error handling */ INGresult *ing_res = NULL; int rows; int cols; /* # line 585 "myingres.sc" */ int sess_id; /* # line 587 "myingres.sc" */ cols = INGgetCols(dbconn, query, explicit_commit); /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; /* # line 595 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } /* # line 597 "myingres.sc" */ /* host code */ ing_res = INGgetINGresult(cols, query); if (!ing_res) { goto bail_out; } rows = INGfetchAll(ing_res); if (rows < 0) { INGfreeINGresult(ing_res); ing_res = NULL; goto bail_out; } bail_out: /* * If explicit_commit is set we commit our work now. */ if (explicit_commit) { /* # line 615 "myingres.sc" */ /* commit */ { IIsqInit(&sqlca); IIxact(3); } /* # line 616 "myingres.sc" */ /* host code */ } /* * Switch to no default session for this thread. */ /* # line 621 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 622 "myingres.sc" */ /* host code */ return ing_res; } void INGclear(INGresult *ing_res) { if (ing_res == NULL) { return; } INGfreeINGresult(ing_res); } void INGcommit(const INGconn *dbconn) { /* # line 636 "myingres.sc" */ int sess_id; /* # line 638 "myingres.sc" */ if (dbconn != NULL) { /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; /* # line 645 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } /* # line 647 "myingres.sc" */ /* host code */ /* * Commit our work. */ /* # line 650 "myingres.sc" */ /* commit */ { IIsqInit(&sqlca); IIxact(3); } /* # line 652 "myingres.sc" */ /* host code */ /* * Switch to no default session for this thread. */ /* # line 655 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 656 "myingres.sc" */ /* host code */ } } INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) { /* # line 661 "myingres.sc" */ char *ingdbname; char *ingdbuser = NULL; char *ingdbpasswd = NULL; int sess_id; /* # line 666 "myingres.sc" */ INGconn *dbconn = NULL; if (dbname == NULL || strlen(dbname) == 0) { return NULL; } sess_id = session_id; ingdbname = dbname; /* # line 678 "myingres.sc" */ /* host code */ if (user != NULL) { ingdbuser = user; if (passwd != NULL) { ingdbpasswd = passwd; /* # line 682 "myingres.sc" */ /* connect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); IIsqUser(ingdbuser); IIsqConnect(0,ingdbname,(char *)"-dbms_password",ingdbpasswd,(char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0); if (sqlca.sqlcode < 0) goto bail_out; } /* # line 687 "myingres.sc" */ /* host code */ } else { /* # line 688 "myingres.sc" */ /* connect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); IIsqUser(ingdbuser); IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0); if (sqlca.sqlcode < 0) goto bail_out; } /* # line 692 "myingres.sc" */ /* host code */ } } else { /* # line 694 "myingres.sc" */ /* connect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0); if (sqlca.sqlcode < 0) goto bail_out; } /* # line 697 "myingres.sc" */ /* host code */ } /* # line 701 "myingres.sc" */ /* host code */ dbconn = (INGconn *)malloc(sizeof(INGconn)); memset(dbconn, 0, sizeof(INGconn)); dbconn->dbname = bstrdup(ingdbname); if (user != NULL) { dbconn->user = bstrdup(ingdbuser); dbconn->password = bstrdup(ingdbpasswd); } dbconn->session_id = sess_id; dbconn->msg = (char *)malloc(257); memset(dbconn->msg, 0, 257); /* * Switch to no default session for this thread undo default settings from SQL CONNECT. */ /* # line 716 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 718 "myingres.sc" */ /* host code */ bail_out: return dbconn; } void INGsetDefaultLockingMode(INGconn *dbconn) { /* * Set the default Ingres session locking mode: * * SET LOCKMODE provides four different parameters to govern * the nature of locking in an INGRES session: * * Level: This refers to the level of granularity desired when * the table is accessed. You can specify any of the following * locking levels: * * row Specifies locking at the level of the row (subject to * escalation criteria; see below) * page Specifies locking at the level of the data page (subject to * escalation criteria; see below) * table Specifies table-level locking in the database * session Specifies the current default for your INGRES session * system Specifies that INGRES will start with page-level locking, * unless it estimates that more than Maxlocks pages will be * referenced, in which case table-level locking will be used. * * Readlock: This refers to locking in situations where table access * is required for reading data only (as opposed to updating * data). You can specify any of the following Readlock modes: * * nolock Specifies no locking when reading data * shared Specifies the default mode of locking when reading data * exclusive Specifies exclusive locking when reading data (useful in * "select-for-update" processing within a multi-statement * transaction) * system Specifies the general Readlock default for the INGRES system * * Maxlocks: This refers to an escalation factor, or number of locks on * data pages, at which locking escalates from page-level * to table-level. The number of locks available to you is * dependent upon your system configuration. You can specify the * following Maxlocks escalation factors: * * n A specific (integer) number of page locks to allow before * escalating to table-level locking. The default "n" is 10, * and "n" must be greater than 0. * session Specifies the current Maxlocks default for your INGRES * session * system Specifies the general Maxlocks default for the INGRES system * * Note: If you specify page-level locking, and the number of locks granted * during a query exceeds the system-wide lock limit, or if the operating * system's locking resources are depleted, locking escalates to table-level. * This escalation occurs automatically and is independent of the user. * * Timeout: This refers to a time limit, expressed in seconds, for which * a lock request should remain pending. If INGRES cannot grant the lock * request within the specified time, then the query that requested the * lock aborts. You can specify the following timeout characteristics: * * n A specific (integer) number of seconds to wait for a lock * (setting "n" to 0 requires INGRES to wait indefinitely for * the lock) * session Specifies the current timeout default for your INGRES * session (which is also the INGRES default) * system Specifies the general timeout default for the INGRES system * */ /* # line 786 "myingres.sc" */ int sess_id; /* # line 788 "myingres.sc" */ if (dbconn != NULL) { /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; /* # line 795 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } /* # line 797 "myingres.sc" */ /* set */ { IIsqInit(&sqlca); IIwritio(0,(short *)0,1,32,0,(char *) "set LOCKMODE session where level=row, readlock=nolock"); IIsyncup((char *)0,0); } /* # line 799 "myingres.sc" */ /* host code */ /* * Switch to no default session for this thread. */ /* # line 802 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 803 "myingres.sc" */ /* host code */ } } void INGdisconnectDB(INGconn *dbconn) { /* # line 808 "myingres.sc" */ int sess_id; /* # line 810 "myingres.sc" */ if (dbconn != NULL) { sess_id = dbconn->session_id; /* # line 814 "myingres.sc" */ /* disconnect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); IIsqDisconnect(); } /* # line 816 "myingres.sc" */ /* host code */ free(dbconn->dbname); if (dbconn->user) { free(dbconn->user); } if (dbconn->password) { free(dbconn->password); } free(dbconn->msg); free(dbconn); } } char *INGerrorMessage(const INGconn *dbconn) { /* # line 830 "myingres.sc" */ int sess_id; char errbuf[256]; /* # line 833 "myingres.sc" */ if (dbconn != NULL) { /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; /* # line 840 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } /* # line 842 "myingres.sc" */ /* inquire_ingres */ { IILQisInqSqlio((short *)0,1,32,255,errbuf,63); } /* # line 843 "myingres.sc" */ /* host code */ bstrncpy(dbconn->msg, errbuf, sizeof(dbconn->msg)); /* * Switch to no default session for this thread. */ /* # line 848 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } /* # line 849 "myingres.sc" */ /* host code */ } return dbconn->msg; } /* # line 854 "myingres.sc" */ #endif bareos-Release-14.2.6/src/cats/myingres.h000066400000000000000000000057761263011562700202060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA */ #ifndef _MYINGRES_SH #define _MYINGRES_SH #include #include #include /* ---typedefs--- */ typedef struct ing_timestamp { unsigned short year; unsigned char month; unsigned char day; unsigned int secs; unsigned int nsecs; unsigned char tzh; unsigned char tzm; } ING_TIMESTAMP; typedef struct ing_field { char *name; int max_length; unsigned int type; unsigned int flags; /* 1 == not null */ } INGRES_FIELD; typedef struct ing_row { IISQLVAR *sqlvar; /* ptr to sqlvar[sqld] for one row */ struct ing_row *next; int row_number; } ING_ROW; typedef enum ing_status { ING_COMMAND_OK, ING_TUPLES_OK, ING_NO_RESULT, ING_NO_ROWS_PROCESSED, ING_EMPTY_RESULT, ING_ERROR } ING_STATUS; typedef struct ing_varchar { short len; char* value; } ING_VARCHAR; /* It seems, BAREOS needs the complete query result stored in one data structure */ typedef struct ing_result { IISQLDA *sqlda; /* descriptor */ INGRES_FIELD *fields; int num_rows; int num_fields; ING_STATUS status; ING_ROW *first_row; ING_ROW *act_row; /* just for iterating */ } INGresult; typedef struct ing_conn { char *dbname; char *user; char *password; int session_id; char *msg; } INGconn; /* ---Prototypes--- */ int INGgetCols(INGconn *dbconn, const char *query, bool transaction); char *INGgetvalue(INGresult *ing_res, int row_number, int column_number); bool INGgetisnull(INGresult *ing_res, int row_number, int column_number); int INGntuples(const INGresult *ing_res); int INGnfields(const INGresult *ing_res); char *INGfname(const INGresult *ing_res, int column_number); short INGftype(const INGresult *ing_res, int column_number); int INGexec(INGconn *dbconn, const char *query, bool transaction); INGresult *INGquery(INGconn *dbconn, const char *query, bool transaction); void INGclear(INGresult *ing_res); void INGcommit(const INGconn *dbconn); INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id); void INGsetDefaultLockingMode(INGconn *dbconn); void INGdisconnectDB(INGconn *dbconn); char *INGerrorMessage(const INGconn *dbconn); char *INGcmdTuples(INGresult *ing_res); /* # line 109 "myingres.sh" */ #endif /* _MYINGRES_SH */ bareos-Release-14.2.6/src/cats/myingres.sc000066400000000000000000000554411263011562700203560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version two of the GNU General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos Catalog Database routines specific to Ingres * These are Ingres specific routines * * Stefan Reddig, June 2009 with help of Marco van Wieringen April 2010 */ #include "bareos.h" #ifdef HAVE_INGRES EXEC SQL INCLUDE SQLCA; EXEC SQL INCLUDE SQLDA; #include #include #include #include "myingres.h" /* * ---Implementations--- */ int INGgetCols(INGconn *dbconn, const char *query, bool explicit_commit) { EXEC SQL BEGIN DECLARE SECTION; int sess_id; char *stmt; EXEC SQL END DECLARE SECTION; IISQLDA *sqlda; int number = -1; sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + IISQDA_VAR_SIZE); memset(sqlda, 0, (IISQDA_HEAD_SIZE + IISQDA_VAR_SIZE)); sqlda->sqln = number; stmt = bstrdup(query); EXEC SQL WHENEVER SQLERROR GOTO bail_out; /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; EXEC SQL SET_SQL (SESSION = :sess_id); EXEC SQL PREPARE s1 INTO :sqlda FROM :stmt; EXEC SQL WHENEVER SQLERROR CONTINUE; number = sqlda->sqld; bail_out: /* * If explicit_commit is set we commit our work now. */ if (explicit_commit) { EXEC SQL COMMIT WORK; } /* * Switch to no default session for this thread. */ EXEC SQL SET_SQL (SESSION = NONE); free(stmt); free(sqlda); return number; } static inline IISQLDA *INGgetDescriptor(int numCols, const char *query) { EXEC SQL BEGIN DECLARE SECTION; char *stmt; EXEC SQL END DECLARE SECTION; int i; IISQLDA *sqlda; sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)); memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE))); sqlda->sqln = numCols; stmt = bstrdup(query); EXEC SQL PREPARE s2 INTO :sqlda FROM :stmt; for (i = 0; i < sqlda->sqld; ++i) { /* * Negative type indicates nullable columns, so an indicator * is allocated, otherwise it's null */ if (sqlda->sqlvar[i].sqltype > 0) { sqlda->sqlvar[i].sqlind = NULL; } else { sqlda->sqlvar[i].sqlind = (short *)malloc(sizeof(short)); } /* * Alloc space for variable like indicated in sqllen * for date types sqllen is always 0 -> allocate by type */ switch (abs(sqlda->sqlvar[i].sqltype)) { case IISQ_TSW_TYPE: sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN); break; case IISQ_TSWO_TYPE: sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN); break; case IISQ_TSTMP_TYPE: sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN); break; default: /* * plus one to avoid zero mem allocs */ sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen + 1); break; } } free(stmt); return sqlda; } static void INGfreeDescriptor(IISQLDA *sqlda) { int i; if (!sqlda) { return; } for (i = 0; i < sqlda->sqld; ++i) { if (sqlda->sqlvar[i].sqldata) { free(sqlda->sqlvar[i].sqldata); } if (sqlda->sqlvar[i].sqlind) { free(sqlda->sqlvar[i].sqlind); } } free(sqlda); } static inline int INGgetTypeSize(IISQLVAR *ingvar) { int inglength = 0; switch (ingvar->sqltype) { case IISQ_TSWO_TYPE: inglength = 20; break; case IISQ_TSW_TYPE: inglength = 20; break; case IISQ_DTE_TYPE: inglength = 25; break; case IISQ_MNY_TYPE: inglength = 8; break; default: inglength = ingvar->sqllen; break; } return inglength; } static inline INGresult *INGgetINGresult(int numCols, const char *query) { int i; INGresult *ing_res; ing_res = (INGresult *)malloc(sizeof(INGresult)); memset(ing_res, 0, sizeof(INGresult)); if ((ing_res->sqlda = INGgetDescriptor(numCols, query)) == NULL) { return NULL; } ing_res->num_fields = ing_res->sqlda->sqld; ing_res->num_rows = 0; ing_res->first_row = NULL; ing_res->status = ING_EMPTY_RESULT; ing_res->act_row = NULL; if (ing_res->num_fields) { ing_res->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * ing_res->num_fields); memset(ing_res->fields, 0, sizeof(INGRES_FIELD) * ing_res->num_fields); for (i = 0; i < ing_res->num_fields; ++i) { ing_res->fields[i].name = (char *)malloc(ing_res->sqlda->sqlvar[i].sqlname.sqlnamel + 1); bstrncpy(ing_res->fields[i].name, ing_res->sqlda->sqlvar[i].sqlname.sqlnamec, ing_res->sqlda->sqlvar[i].sqlname.sqlnamel + 1); ing_res->fields[i].name[ing_res->sqlda->sqlvar[i].sqlname.sqlnamel] = '\0'; ing_res->fields[i].max_length = INGgetTypeSize(&ing_res->sqlda->sqlvar[i]); ing_res->fields[i].type = abs(ing_res->sqlda->sqlvar[i].sqltype); ing_res->fields[i].flags = (ing_res->sqlda->sqlvar[i].sqltype < 0) ? 1 : 0; } } return ing_res; } static inline void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda) { int i; if (row == NULL || sqlda == NULL) { return; } for (i = 0; i < sqlda->sqld; ++i) { if (row->sqlvar[i].sqldata) { free(row->sqlvar[i].sqldata); } if (row->sqlvar[i].sqlind) { free(row->sqlvar[i].sqlind); } } free(row->sqlvar); free(row); } static void INGfreeINGresult(INGresult *ing_res) { int i; int rows; ING_ROW *rowtemp; if (!ing_res) { return; } /* * Use of rows is a nasty workaround til I find the reason, * why aggregates like max() don't work */ rows = ing_res->num_rows; ing_res->act_row = ing_res->first_row; while (ing_res->act_row != NULL && rows > 0) { rowtemp = ing_res->act_row->next; INGfreeRowSpace(ing_res->act_row, ing_res->sqlda); ing_res->act_row = rowtemp; --rows; } if (ing_res->fields) { for (i = 0; i < ing_res->num_fields; ++i) { free(ing_res->fields[i].name); } free(ing_res->fields); } INGfreeDescriptor(ing_res->sqlda); free(ing_res); } static inline ING_ROW *INGgetRowSpace(INGresult *ing_res) { int i; unsigned short len; /* used for VARCHAR type length */ unsigned short th, tm, ts; IISQLDA *sqlda; ING_ROW *row = NULL; ING_TIMESTAMP *tsp; IISQLVAR *vars = NULL; row = (ING_ROW *)malloc(sizeof(ING_ROW)); memset(row, 0, sizeof(ING_ROW)); sqlda = ing_res->sqlda; vars = (IISQLVAR *)malloc(sizeof(IISQLVAR) * sqlda->sqld); memset(vars, 0, sizeof(IISQLVAR) * sqlda->sqld); row->sqlvar = vars; row->next = NULL; for (i = 0; i < sqlda->sqld; ++i) { /* * Make strings out of the data, then the space and assign * (why string? at least it seems that way, looking into the sources) */ vars[i].sqlind = (short *)malloc(sizeof(short)); if (sqlda->sqlvar[i].sqlind) { memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short)); } else { *vars[i].sqlind = NULL; } /* * if sqlind pointer exists AND points to -1 -> column is 'null' */ if ( *vars[i].sqlind && (*vars[i].sqlind == -1)) { vars[i].sqldata = NULL; } else { switch (ing_res->fields[i].type) { case IISQ_VCH_TYPE: case IISQ_LVCH_TYPE: case IISQ_VBYTE_TYPE: case IISQ_LBYTE_TYPE: case IISQ_NVCHR_TYPE: case IISQ_LNVCHR_TYPE: len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len; vars[i].sqldata = (char *)malloc(len + 1); memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata + 2,len); vars[i].sqldata[len] = '\0'; break; case IISQ_CHA_TYPE: case IISQ_BYTE_TYPE: case IISQ_NCHR_TYPE: vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length + 1); memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen); vars[i].sqldata[ing_res->fields[i].max_length] = '\0'; break; case IISQ_INT_TYPE: switch (sqlda->sqlvar[i].sqllen) { case 2: vars[i].sqldata = (char *)malloc(6); memset(vars[i].sqldata, 0, 6); bsnprintf(vars[i].sqldata, 6, "%d",*(int16_t *)sqlda->sqlvar[i].sqldata); break; case 4: vars[i].sqldata = (char *)malloc(11); memset(vars[i].sqldata, 0, 11); bsnprintf(vars[i].sqldata, 11, "%ld",*(int32_t *)sqlda->sqlvar[i].sqldata); break; case 8: vars[i].sqldata = (char *)malloc(20); memset(vars[i].sqldata, 0, 20); bsnprintf(vars[i].sqldata, 20, "%lld",*(int64_t *)sqlda->sqlvar[i].sqldata); break; } break; case IISQ_TSTMP_TYPE: vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN + 1); vars[i].sqldata[IISQ_TSTMP_LEN] = '\0'; break; case IISQ_TSWO_TYPE: tsp = (ING_TIMESTAMP *)sqlda->sqlvar[i].sqldata; th = tsp->secs / 3600; /* hours */ tm = tsp->secs % 3600; /* remaining seconds */ tm = tm / 60; /* minutes */ ts = tsp->secs - (th * 3600) - (tm * 60); /* seconds */ vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN + 1); bsnprintf(vars[i].sqldata, IISQ_TSWO_LEN + 1, "%04u-%02u-%02u %02u:%02u:%02u", tsp->year, tsp->month, tsp->day, th, tm, ts); break; case IISQ_TSW_TYPE: tsp = (ING_TIMESTAMP *)sqlda->sqlvar[i].sqldata; th = tsp->secs / 3600; /* hours */ tm = tsp->secs % 3600; /* remaining seconds */ tm = tm / 60; /* minutes */ ts = tsp->secs - (th * 3600) - (tm * 60); /* seconds */ vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN + 1); bsnprintf(vars[i].sqldata, IISQ_TSW_LEN + 1, "%04u-%02u-%02u %02u:%02u:%02u", tsp->year, tsp->month, tsp->day, th, tm, ts); break; default: Jmsg(NULL, M_FATAL, 0, "INGgetRowSpace: encountered unhandled database datatype %d please report this as a bug\n", ing_res->fields[i].type); break; } } } return row; } static inline int INGfetchAll(INGresult *ing_res) { ING_ROW *row; IISQLDA *desc; int linecount = -1; desc = ing_res->sqlda; EXEC SQL WHENEVER SQLERROR GOTO bail_out; EXEC SQL DECLARE c2 CURSOR FOR s2; EXEC SQL OPEN c2; EXEC SQL WHENEVER SQLERROR CONTINUE; linecount = 0; do { EXEC SQL FETCH c2 USING DESCRIPTOR :desc; if (sqlca.sqlcode == 0 || sqlca.sqlcode == -40202) { /* * Allocate space for fetched row */ row = INGgetRowSpace(ing_res); /* * Initialize list when encountered first time */ if (ing_res->first_row == 0) { ing_res->first_row = row; /* head of the list */ ing_res->first_row->next = NULL; ing_res->act_row = ing_res->first_row; } ing_res->act_row->next = row; /* append row to old act_row */ ing_res->act_row = row; /* set row as act_row */ row->row_number = linecount++; } } while ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) ); EXEC SQL CLOSE c2; ing_res->status = ING_COMMAND_OK; ing_res->num_rows = linecount; bail_out: return linecount; } static inline ING_STATUS INGresultStatus(INGresult *ing_res) { if (ing_res == NULL) { return ING_NO_RESULT; } else { return ing_res->status; } } static void INGrowSeek(INGresult *ing_res, int row_number) { ING_ROW *trow = NULL; if (ing_res->act_row->row_number == row_number) { return; } /* * TODO: real error handling */ if (row_number < 0 || row_number > ing_res->num_rows) { return; } for (trow = ing_res->first_row; trow->row_number != row_number; trow = trow->next) ; ing_res->act_row = trow; /* * Note - can be null - if row_number not found, right? */ } char *INGgetvalue(INGresult *ing_res, int row_number, int column_number) { if (row_number != ing_res->act_row->row_number) { INGrowSeek(ing_res, row_number); } return ing_res->act_row->sqlvar[column_number].sqldata; } bool INGgetisnull(INGresult *ing_res, int row_number, int column_number) { if (row_number != ing_res->act_row->row_number) { INGrowSeek(ing_res, row_number); } return (*ing_res->act_row->sqlvar[column_number].sqlind == -1) ? true : false; } int INGntuples(const INGresult *ing_res) { return ing_res->num_rows; } int INGnfields(const INGresult *ing_res) { return ing_res->num_fields; } char *INGfname(const INGresult *ing_res, int column_number) { if ((column_number > ing_res->num_fields) || (column_number < 0)) { return NULL; } else { return ing_res->fields[column_number].name; } } short INGftype(const INGresult *ing_res, int column_number) { return ing_res->fields[column_number].type; } int INGexec(INGconn *dbconn, const char *query, bool explicit_commit) { EXEC SQL BEGIN DECLARE SECTION; int sess_id; int rowcount; int errors; char *stmt; EXEC SQL END DECLARE SECTION; rowcount = -1; stmt = bstrdup(query); EXEC SQL WHENEVER SQLERROR GOTO bail_out; /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; EXEC SQL SET_SQL (SESSION = :sess_id); EXEC SQL EXECUTE IMMEDIATE :stmt; EXEC SQL INQUIRE_INGRES(:rowcount = ROWCOUNT); /* * See if the negative rowcount is due to errors. */ if (rowcount < 0) { EXEC SQL INQUIRE_INGRES(:errors = DBMSERROR); /* * If the number of errors is 0 we got a negative rowcount * because the statement we executed doesn't give a rowcount back. * Lets pretend we have a rowcount of 1 then. */ if (errors == 0) { rowcount = 1; } } EXEC SQL WHENEVER SQLERROR CONTINUE; bail_out: /* * If explicit_commit is set we commit our work now. */ if (explicit_commit) { EXEC SQL COMMIT WORK; } /* * Switch to no default session for this thread. */ EXEC SQL SET_SQL (SESSION = NONE); free(stmt); return rowcount; } INGresult *INGquery(INGconn *dbconn, const char *query, bool explicit_commit) { /* * TODO: error handling */ INGresult *ing_res = NULL; int rows; int cols; EXEC SQL BEGIN DECLARE SECTION; int sess_id; EXEC SQL END DECLARE SECTION; cols = INGgetCols(dbconn, query, explicit_commit); /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; EXEC SQL SET_SQL (SESSION = :sess_id); ing_res = INGgetINGresult(cols, query); if (!ing_res) { goto bail_out; } rows = INGfetchAll(ing_res); if (rows < 0) { INGfreeINGresult(ing_res); ing_res = NULL; goto bail_out; } bail_out: /* * If explicit_commit is set we commit our work now. */ if (explicit_commit) { EXEC SQL COMMIT WORK; } /* * Switch to no default session for this thread. */ EXEC SQL SET_SQL (SESSION = NONE); return ing_res; } void INGclear(INGresult *ing_res) { if (ing_res == NULL) { return; } INGfreeINGresult(ing_res); } void INGcommit(const INGconn *dbconn) { EXEC SQL BEGIN DECLARE SECTION; int sess_id; EXEC SQL END DECLARE SECTION; if (dbconn != NULL) { /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; EXEC SQL SET_SQL (SESSION = :sess_id); /* * Commit our work. */ EXEC SQL COMMIT WORK; /* * Switch to no default session for this thread. */ EXEC SQL SET_SQL (SESSION = NONE); } } INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) { EXEC SQL BEGIN DECLARE SECTION; char *ingdbname; char *ingdbuser = NULL; char *ingdbpasswd = NULL; int sess_id; EXEC SQL END DECLARE SECTION; INGconn *dbconn = NULL; if (dbname == NULL || strlen(dbname) == 0) { return NULL; } sess_id = session_id; ingdbname = dbname; EXEC SQL WHENEVER SQLERROR GOTO bail_out; if (user != NULL) { ingdbuser = user; if (passwd != NULL) { ingdbpasswd = passwd; EXEC SQL CONNECT :ingdbname SESSION :sess_id IDENTIFIED BY :ingdbuser DBMS_PASSWORD = :ingdbpasswd; } else { EXEC SQL CONNECT :ingdbname SESSION :sess_id IDENTIFIED BY :ingdbuser; } } else { EXEC SQL CONNECT :ingdbname SESSION :sess_id; } EXEC SQL WHENEVER SQLERROR CONTINUE; dbconn = (INGconn *)malloc(sizeof(INGconn)); memset(dbconn, 0, sizeof(INGconn)); dbconn->dbname = bstrdup(ingdbname); if (user != NULL) { dbconn->user = bstrdup(ingdbuser); dbconn->password = bstrdup(ingdbpasswd); } dbconn->session_id = sess_id; dbconn->msg = (char *)malloc(257); memset(dbconn->msg, 0, 257); /* * Switch to no default session for this thread undo default settings from SQL CONNECT. */ EXEC SQL SET_SQL (SESSION = NONE); bail_out: return dbconn; } void INGsetDefaultLockingMode(INGconn *dbconn) { /* * Set the default Ingres session locking mode: * * SET LOCKMODE provides four different parameters to govern * the nature of locking in an INGRES session: * * Level: This refers to the level of granularity desired when * the table is accessed. You can specify any of the following * locking levels: * * row Specifies locking at the level of the row (subject to * escalation criteria; see below) * page Specifies locking at the level of the data page (subject to * escalation criteria; see below) * table Specifies table-level locking in the database * session Specifies the current default for your INGRES session * system Specifies that INGRES will start with page-level locking, * unless it estimates that more than Maxlocks pages will be * referenced, in which case table-level locking will be used. * * Readlock: This refers to locking in situations where table access * is required for reading data only (as opposed to updating * data). You can specify any of the following Readlock modes: * * nolock Specifies no locking when reading data * shared Specifies the default mode of locking when reading data * exclusive Specifies exclusive locking when reading data (useful in * "select-for-update" processing within a multi-statement * transaction) * system Specifies the general Readlock default for the INGRES system * * Maxlocks: This refers to an escalation factor, or number of locks on * data pages, at which locking escalates from page-level * to table-level. The number of locks available to you is * dependent upon your system configuration. You can specify the * following Maxlocks escalation factors: * * n A specific (integer) number of page locks to allow before * escalating to table-level locking. The default "n" is 10, * and "n" must be greater than 0. * session Specifies the current Maxlocks default for your INGRES * session * system Specifies the general Maxlocks default for the INGRES system * * Note: If you specify page-level locking, and the number of locks granted * during a query exceeds the system-wide lock limit, or if the operating * system's locking resources are depleted, locking escalates to table-level. * This escalation occurs automatically and is independent of the user. * * Timeout: This refers to a time limit, expressed in seconds, for which * a lock request should remain pending. If INGRES cannot grant the lock * request within the specified time, then the query that requested the * lock aborts. You can specify the following timeout characteristics: * * n A specific (integer) number of seconds to wait for a lock * (setting "n" to 0 requires INGRES to wait indefinitely for * the lock) * session Specifies the current timeout default for your INGRES * session (which is also the INGRES default) * system Specifies the general timeout default for the INGRES system * */ EXEC SQL BEGIN DECLARE SECTION; int sess_id; EXEC SQL END DECLARE SECTION; if (dbconn != NULL) { /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; EXEC SQL SET_SQL (SESSION = :sess_id); EXEC SQL SET LOCKMODE SESSION WHERE level = row, readlock = nolock; /* * Switch to no default session for this thread. */ EXEC SQL SET_SQL (SESSION = NONE); } } void INGdisconnectDB(INGconn *dbconn) { EXEC SQL BEGIN DECLARE SECTION; int sess_id; EXEC SQL END DECLARE SECTION; if (dbconn != NULL) { sess_id = dbconn->session_id; EXEC SQL DISCONNECT SESSION :sess_id; free(dbconn->dbname); if (dbconn->user) { free(dbconn->user); } if (dbconn->password) { free(dbconn->password); } free(dbconn->msg); free(dbconn); } } char *INGerrorMessage(const INGconn *dbconn) { EXEC SQL BEGIN DECLARE SECTION; int sess_id; char errbuf[256]; EXEC SQL END DECLARE SECTION; if (dbconn != NULL) { /* * Switch to the correct default session for this thread. */ sess_id = dbconn->session_id; EXEC SQL SET_SQL (SESSION = :sess_id); EXEC SQL INQUIRE_INGRES (:errbuf = ERRORTEXT); strncpy(dbconn->msg, errbuf, sizeof(dbconn->msg)); /* * Switch to no default session for this thread. */ EXEC SQL SET_SQL (SESSION = NONE); } return dbconn->msg; } #endif bareos-Release-14.2.6/src/cats/myingres.sh000066400000000000000000000057121263011562700203570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version two of the GNU General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MYINGRES_SH #define _MYINGRES_SH EXEC SQL INCLUDE SQLDA; /* ---typedefs--- */ typedef struct ing_timestamp { unsigned short year; unsigned char month; unsigned char day; unsigned int secs; unsigned int nsecs; unsigned char tzh; unsigned char tzm; } ING_TIMESTAMP; typedef struct ing_field { char *name; int max_length; unsigned int type; unsigned int flags; /* 1 == not null */ } INGRES_FIELD; typedef struct ing_row { IISQLVAR *sqlvar; /* ptr to sqlvar[sqld] for one row */ struct ing_row *next; int row_number; } ING_ROW; typedef enum ing_status { ING_COMMAND_OK, ING_TUPLES_OK, ING_NO_RESULT, ING_NO_ROWS_PROCESSED, ING_EMPTY_RESULT, ING_ERROR } ING_STATUS; typedef struct ing_varchar { short len; char* value; } ING_VARCHAR; /* It seems, Bareos needs the complete query result stored in one data structure */ typedef struct ing_result { IISQLDA *sqlda; /* descriptor */ INGRES_FIELD *fields; int num_rows; int num_fields; ING_STATUS status; ING_ROW *first_row; ING_ROW *act_row; /* just for iterating */ } INGresult; typedef struct ing_conn { char *dbname; char *user; char *password; int session_id; char *msg; } INGconn; /* ---Prototypes--- */ int INGgetCols(INGconn *dbconn, const char *query, bool transaction); char *INGgetvalue(INGresult *ing_res, int row_number, int column_number); bool INGgetisnull(INGresult *ing_res, int row_number, int column_number); int INGntuples(const INGresult *ing_res); int INGnfields(const INGresult *ing_res); char *INGfname(const INGresult *ing_res, int column_number); short INGftype(const INGresult *ing_res, int column_number); int INGexec(INGconn *dbconn, const char *query, bool transaction); INGresult *INGquery(INGconn *dbconn, const char *query, bool transaction); void INGclear(INGresult *ing_res); void INGcommit(const INGconn *dbconn); INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id); void INGsetDefaultLockingMode(INGconn *dbconn); void INGdisconnectDB(INGconn *dbconn); char *INGerrorMessage(const INGconn *dbconn); char *INGcmdTuples(INGresult *ing_res); #endif /* _MYINGRES_SH */ bareos-Release-14.2.6/src/cats/mysql.c000066400000000000000000000507021263011562700174760ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database routines specific to MySQL * These are MySQL specific routines -- hopefully all * other files are generic. * * Kern Sibbald, March 2000 * * Major rewrite by Marco van Wieringen, January 2010 for catalog refactoring. */ #include "bareos.h" #ifdef HAVE_MYSQL #include "cats.h" #include "bdb_priv.h" #include #include /* ----------------------------------------------------------------------- * * MySQL dependent defines and subroutines * * ----------------------------------------------------------------------- */ /* * List of open databases */ static dlist *db_list = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; B_DB_MYSQL::B_DB_MYSQL(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { /* * Initialize the parent class members. */ m_db_interface_type = SQL_INTERFACE_TYPE_MYSQL; m_db_type = SQL_TYPE_MYSQL; m_db_driver = bstrdup("MySQL"); m_db_name = bstrdup(db_name); m_db_user = bstrdup(db_user); if (db_password) { m_db_password = bstrdup(db_password); } if (db_address) { m_db_address = bstrdup(db_address); } if (db_socket) { m_db_socket = bstrdup(db_socket); } m_db_port = db_port; if (disable_batch_insert) { m_disabled_batch_insert = true; m_have_batch_insert = false; } else { m_disabled_batch_insert = false; #if defined(USE_BATCH_FILE_INSERT) # if defined(HAVE_MYSQL_THREAD_SAFE) m_have_batch_insert = mysql_thread_safe(); # else m_have_batch_insert = false; # endif /* HAVE_MYSQL_THREAD_SAFE */ #else m_have_batch_insert = false; #endif /* USE_BATCH_FILE_INSERT */ } errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */ *errmsg = 0; cmd = get_pool_memory(PM_EMSG); /* get command buffer */ cached_path = get_pool_memory(PM_FNAME); cached_path_id = 0; m_ref_count = 1; fname = get_pool_memory(PM_FNAME); path = get_pool_memory(PM_FNAME); esc_name = get_pool_memory(PM_FNAME); esc_path = get_pool_memory(PM_FNAME); esc_obj = get_pool_memory(PM_FNAME); m_allow_transactions = mult_db_connections; m_is_private = need_private; /* * Initialize the private members. */ m_db_handle = NULL; m_result = NULL; /* * Put the db in the list. */ if (db_list == NULL) { db_list = New(dlist(this, &this->m_link)); } db_list->append(this); } B_DB_MYSQL::~B_DB_MYSQL() { } /* * Now actually open the database. This can generate errors, * which are returned in the errmsg * * DO NOT close the database or delete mdb here !!!! */ bool B_DB_MYSQL::db_open_database(JCR *jcr) { bool retval = false; int errstat; P(mutex); if (m_connected) { retval = true; goto bail_out; } if ((errstat=rwl_init(&m_lock)) != 0) { berrno be; Mmsg1(&errmsg, _("Unable to initialize DB lock. ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } /* * Connect to the database */ #ifdef xHAVE_EMBEDDED_MYSQL // mysql_server_init(0, NULL, NULL); #endif mysql_init(&m_instance); Dmsg0(50, "mysql_init done\n"); /* * If connection fails, try at 5 sec intervals for 30 seconds. */ for (int retry=0; retry < 6; retry++) { m_db_handle = mysql_real_connect( &(m_instance), /* db */ m_db_address, /* default = localhost */ m_db_user, /* login name */ m_db_password, /* password */ m_db_name, /* database name */ m_db_port, /* default port */ m_db_socket, /* default = socket */ CLIENT_FOUND_ROWS); /* flags */ /* * If no connect, try once more in case it is a timing problem */ if (m_db_handle != NULL) { break; } bmicrosleep(5,0); } m_instance.reconnect = 1; /* so connection does not timeout */ Dmsg0(50, "mysql_real_connect done\n"); Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", m_db_user, m_db_name, (m_db_password == NULL) ? "(NULL)" : m_db_password); if (m_db_handle == NULL) { Mmsg2(&errmsg, _("Unable to connect to MySQL server.\n" "Database=%s User=%s\n" "MySQL connect failed either server not running or your authorization is incorrect.\n"), m_db_name, m_db_user); #if MYSQL_VERSION_ID >= 40101 Dmsg3(50, "Error %u (%s): %s\n", mysql_errno(&(m_instance)), mysql_sqlstate(&(m_instance)), mysql_error(&(m_instance))); #else Dmsg2(50, "Error %u: %s\n", mysql_errno(&(m_instance)), mysql_error(&(m_instance))); #endif goto bail_out; } m_connected = true; if (!check_tables_version(jcr, this)) { goto bail_out; } Dmsg3(100, "opendb ref=%d connected=%d db=%p\n", m_ref_count, m_connected, m_db_handle); /* * Set connection timeout to 8 days specialy for batch mode */ sql_query("SET wait_timeout=691200"); sql_query("SET interactive_timeout=691200"); retval = true; bail_out: V(mutex); return retval; } void B_DB_MYSQL::db_close_database(JCR *jcr) { if (m_connected) { db_end_transaction(jcr); } P(mutex); m_ref_count--; Dmsg3(100, "closedb ref=%d connected=%d db=%p\n", m_ref_count, m_connected, m_db_handle); if (m_ref_count == 0) { if (m_connected) { sql_free_result(); } db_list->remove(this); if (m_connected) { Dmsg1(100, "close db=%p\n", m_db_handle); mysql_close(&m_instance); #ifdef xHAVE_EMBEDDED_MYSQL // mysql_server_end(); #endif } if (rwl_is_init(&m_lock)) { rwl_destroy(&m_lock); } free_pool_memory(errmsg); free_pool_memory(cmd); free_pool_memory(cached_path); free_pool_memory(fname); free_pool_memory(path); free_pool_memory(esc_name); free_pool_memory(esc_path); free_pool_memory(esc_obj); if (m_db_driver) { free(m_db_driver); } if (m_db_name) { free(m_db_name); } if (m_db_user) { free(m_db_user); } if (m_db_password) { free(m_db_password); } if (m_db_address) { free(m_db_address); } if (m_db_socket) { free(m_db_socket); } delete this; if (db_list->size() == 0) { delete db_list; db_list = NULL; } } V(mutex); } bool B_DB_MYSQL::db_validate_connection(void) { bool retval; unsigned long mysql_threadid; /* * See if the connection is still valid by using a ping to * the server. We also catch a changing threadid which means * a reconnect has taken place. */ db_lock(this); mysql_threadid = mysql_thread_id(m_db_handle); if (mysql_ping(m_db_handle) == 0) { Dmsg2(500, "db_validate_connection connection valid previous threadid %ld new threadid %ld\n", mysql_threadid, mysql_thread_id(m_db_handle)); retval = true; goto bail_out; } else { Dmsg0(500, "db_validate_connection connection invalid unable to ping server\n"); retval = false; goto bail_out; } bail_out: db_unlock(this); return retval; } /* * This call is needed because the message channel thread * opens a database on behalf of a jcr that was created in * a different thread. MySQL then allocates thread specific * data, which is NOT freed when the original jcr thread * closes the database. Thus the msgchan must call here * to cleanup any thread specific data that it created. */ void B_DB_MYSQL::db_thread_cleanup(void) { #ifndef HAVE_WIN32 mysql_thread_end(); #endif } /* * Escape strings so that MySQL is happy * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. */ void B_DB_MYSQL::db_escape_string(JCR *jcr, char *snew, char *old, int len) { mysql_real_escape_string(m_db_handle, snew, old, len); } /* * Escape binary object so that MySQL is happy * Memory is stored in B_DB struct, no need to free it */ char *B_DB_MYSQL::db_escape_object(JCR *jcr, char *old, int len) { esc_obj = check_pool_memory_size(esc_obj, len*2+1); mysql_real_escape_string(m_db_handle, esc_obj, old, len); return esc_obj; } /* * Unescape binary object so that MySQL is happy */ void B_DB_MYSQL::db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *dest_len) { if (!from) { *dest[0] = 0; *dest_len = 0; return; } *dest = check_pool_memory_size(*dest, expected_len+1); *dest_len = expected_len; memcpy(*dest, from, expected_len); (*dest)[expected_len]=0; } void B_DB_MYSQL::db_start_transaction(JCR *jcr) { if (!jcr->attr) { jcr->attr = get_pool_memory(PM_FNAME); } if (!jcr->ar) { jcr->ar = (ATTR_DBR *)malloc(sizeof(ATTR_DBR)); } } void B_DB_MYSQL::db_end_transaction(JCR *jcr) { if (jcr && jcr->cached_attribute) { Dmsg0(400, "Flush last cached attribute.\n"); if (!db_create_attributes_record(jcr, this, jcr->ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } } /* * Submit a general SQL command (cmd), and for each row returned, * the result_handler is called with the ctx. */ bool B_DB_MYSQL::db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { int status; SQL_ROW row; bool send = true; bool retval = false; Dmsg1(500, "db_sql_query starts with %s\n", query); db_lock(this); status = mysql_query(m_db_handle, query); if (status != 0) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror()); Dmsg0(500, "db_sql_query failed\n"); goto bail_out; } Dmsg0(500, "db_sql_query succeeded. checking handler\n"); if (result_handler != NULL) { if ((m_result = mysql_use_result(m_db_handle)) != NULL) { m_num_fields = mysql_num_fields(m_result); /* * We *must* fetch all rows */ while ((row = mysql_fetch_row(m_result)) != NULL) { if (send) { /* the result handler returns 1 when it has * seen all the data it wants. However, we * loop to the end of the data. */ if (result_handler(ctx, m_num_fields, row)) { send = false; } } } sql_free_result(); } } Dmsg0(500, "db_sql_query finished\n"); retval = true; bail_out: db_unlock(this); return retval; } bool B_DB_MYSQL::sql_query(const char *query, int flags) { int status; bool retval = true; Dmsg1(500, "sql_query starts with '%s'\n", query); /* * We are starting a new query. reset everything. */ m_num_rows = -1; m_row_number = -1; m_field_number = -1; if (m_result) { mysql_free_result(m_result); m_result = NULL; } status = mysql_query(m_db_handle, query); if (status == 0) { Dmsg0(500, "we have a result\n"); if (flags & QF_STORE_RESULT) { m_result = mysql_store_result(m_db_handle); if (m_result != NULL) { m_num_fields = mysql_num_fields(m_result); Dmsg1(500, "we have %d fields\n", m_num_fields); m_num_rows = mysql_num_rows(m_result); Dmsg1(500, "we have %d rows\n", m_num_rows); } else { m_num_fields = 0; m_num_rows = mysql_affected_rows(m_db_handle); Dmsg1(500, "we have %d rows\n", m_num_rows); } } else { m_num_fields = 0; m_num_rows = mysql_affected_rows(m_db_handle); Dmsg1(500, "we have %d rows\n", m_num_rows); } } else { Dmsg0(500, "we failed\n"); m_status = 1; /* failed */ retval = false; } return retval; } void B_DB_MYSQL::sql_free_result(void) { db_lock(this); if (m_result) { mysql_free_result(m_result); m_result = NULL; } if (m_fields) { free(m_fields); m_fields = NULL; } m_num_rows = m_num_fields = 0; db_unlock(this); } SQL_ROW B_DB_MYSQL::sql_fetch_row(void) { if (!m_result) { return NULL; } else { return mysql_fetch_row(m_result); } } const char *B_DB_MYSQL::sql_strerror(void) { return mysql_error(m_db_handle); } void B_DB_MYSQL::sql_data_seek(int row) { return mysql_data_seek(m_result, row); } int B_DB_MYSQL::sql_affected_rows(void) { return mysql_affected_rows(m_db_handle); } uint64_t B_DB_MYSQL::sql_insert_autokey_record(const char *query, const char *table_name) { /* * First execute the insert query and then retrieve the currval. */ if (mysql_query(m_db_handle, query) != 0) { return 0; } m_num_rows = mysql_affected_rows(m_db_handle); if (m_num_rows != 1) { return 0; } changes++; return mysql_insert_id(m_db_handle); } SQL_FIELD *B_DB_MYSQL::sql_fetch_field(void) { int i; MYSQL_FIELD *field; if (!m_fields || m_fields_size < m_num_fields) { if (m_fields) { free(m_fields); m_fields = NULL; } Dmsg1(500, "allocating space for %d fields\n", m_num_fields); m_fields = (SQL_FIELD *)malloc(sizeof(SQL_FIELD) * m_num_fields); m_fields_size = m_num_fields; for (i = 0; i < m_num_fields; i++) { Dmsg1(500, "filling field %d\n", i); if ((field = mysql_fetch_field(m_result)) != NULL) { m_fields[i].name = field->name; m_fields[i].max_length = field->max_length; m_fields[i].type = field->type; m_fields[i].flags = field->flags; Dmsg4(500, "sql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", m_fields[i].name, m_fields[i].max_length, m_fields[i].type, m_fields[i].flags); } } } /* * Increment field number for the next time around */ return &m_fields[m_field_number++]; } bool B_DB_MYSQL::sql_field_is_not_null(int field_type) { return IS_NOT_NULL(field_type); } bool B_DB_MYSQL::sql_field_is_numeric(int field_type) { return IS_NUM(field_type); } /* * Returns true if OK * false if failed */ bool B_DB_MYSQL::sql_batch_start(JCR *jcr) { bool retval; db_lock(this); retval = sql_query("CREATE TEMPORARY TABLE batch (" "FileIndex integer," "JobId integer," "Path blob," "Name blob," "LStat tinyblob," "MD5 tinyblob," "DeltaSeq integer)"); db_unlock(this); /* * Keep track of the number of changes in batch mode. */ changes = 0; return retval; } /* set error to something to abort operation */ /* * Returns true if OK * false if failed */ bool B_DB_MYSQL::sql_batch_end(JCR *jcr, const char *error) { m_status = 0; /* * Flush any pending inserts. */ if (changes) { return sql_query(cmd); } return true; } /* * Returns true if OK * false if failed */ bool B_DB_MYSQL::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) { const char *digest; char ed1[50]; esc_name = check_pool_memory_size(esc_name, fnl*2+1); db_escape_string(jcr, esc_name, fname, fnl); esc_path = check_pool_memory_size(esc_path, pnl*2+1); db_escape_string(jcr, esc_path, path, pnl); if (ar->Digest == NULL || ar->Digest[0] == 0) { digest = "0"; } else { digest = ar->Digest; } /* * Try to batch up multiple inserts using multi-row inserts. */ if (changes == 0) { Mmsg(cmd, "INSERT INTO batch VALUES " "(%u,%s,'%s','%s','%s','%s',%u)", ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); changes++; } else { /* * We use the esc_obj for temporary storage otherwise * we keep on copying data. */ Mmsg(esc_obj, ",(%u,%s,'%s','%s','%s','%s',%u)", ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); pm_strcat(cmd, esc_obj); changes++; } /* * See if we need to flush the query buffer filled * with multi-row inserts. */ if ((changes % MYSQL_CHANGES_PER_BATCH_INSERT) == 0) { if (!sql_query(cmd)) { changes = 0; return false; } else { changes = 0; } } return true; } /* * Initialize database data structure. In principal this should * never have errors, or it is really fatal. */ #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" B_DB CATS_IMP_EXP *backend_instantiate(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #else B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #endif { B_DB_MYSQL *mdb = NULL; if (!db_user) { Jmsg(jcr, M_FATAL, 0, _("A user name for MySQL must be supplied.\n")); return NULL; } P(mutex); /* lock DB queue */ /* * Look to see if DB already open */ if (db_list && !mult_db_connections && !need_private) { foreach_dlist(mdb, db_list) { if (mdb->is_private()) { continue; } if (mdb->db_match_database(db_driver, db_name, db_address, db_port)) { Dmsg1(100, "DB REopen %s\n", db_name); mdb->increment_refcount(); goto bail_out; } } } Dmsg0(100, "db_init_database first time\n"); mdb = New(B_DB_MYSQL(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private)); bail_out: V(mutex); return mdb; } #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" void CATS_IMP_EXP flush_backend(void) #else void db_flush_backends(void) #endif { } #endif /* HAVE_MYSQL */ bareos-Release-14.2.6/src/cats/postgresql.c000066400000000000000000000751131263011562700205370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database routines specific to PostgreSQL * These are PostgreSQL specific routines * * Dan Langille, December 2003 * based upon work done by Kern Sibbald, March 2000 * * Major rewrite by Marco van Wieringen, January 2010 for catalog refactoring. */ #include "bareos.h" #ifdef HAVE_POSTGRESQL #include "cats.h" #include "bdb_priv.h" #include "libpq-fe.h" #include "postgres_ext.h" /* needed for NAMEDATALEN */ #include "pg_config_manual.h" /* get NAMEDATALEN on version 8.3 or later */ #include "bdb_postgresql.h" /* ----------------------------------------------------------------------- * * PostgreSQL dependent defines and subroutines * * ----------------------------------------------------------------------- */ /* * List of open databases */ static dlist *db_list = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; B_DB_POSTGRESQL::B_DB_POSTGRESQL(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { /* * Initialize the parent class members. */ m_db_interface_type = SQL_INTERFACE_TYPE_POSTGRESQL; m_db_type = SQL_TYPE_POSTGRESQL; m_db_driver = bstrdup("PostgreSQL"); m_db_name = bstrdup(db_name); m_db_user = bstrdup(db_user); if (db_password) { m_db_password = bstrdup(db_password); } if (db_address) { m_db_address = bstrdup(db_address); } if (db_socket) { m_db_socket = bstrdup(db_socket); } m_db_port = db_port; if (disable_batch_insert) { m_disabled_batch_insert = true; m_have_batch_insert = false; } else { m_disabled_batch_insert = false; #if defined(USE_BATCH_FILE_INSERT) #if defined(HAVE_POSTGRESQL_BATCH_FILE_INSERT) || defined(HAVE_PQISTHREADSAFE) #ifdef HAVE_PQISTHREADSAFE m_have_batch_insert = PQisthreadsafe(); #else m_have_batch_insert = true; #endif /* HAVE_PQISTHREADSAFE */ #else m_have_batch_insert = true; #endif /* HAVE_POSTGRESQL_BATCH_FILE_INSERT || HAVE_PQISTHREADSAFE */ #else m_have_batch_insert = false; #endif /* USE_BATCH_FILE_INSERT */ } errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */ *errmsg = 0; cmd = get_pool_memory(PM_EMSG); /* get command buffer */ cached_path = get_pool_memory(PM_FNAME); cached_path_id = 0; m_ref_count = 1; fname = get_pool_memory(PM_FNAME); path = get_pool_memory(PM_FNAME); esc_name = get_pool_memory(PM_FNAME); esc_path = get_pool_memory(PM_FNAME); esc_obj = get_pool_memory(PM_FNAME); m_buf = get_pool_memory(PM_FNAME); m_allow_transactions = mult_db_connections; m_is_private = need_private; /* * Initialize the private members. */ m_db_handle = NULL; m_result = NULL; /* * Put the db in the list. */ if (db_list == NULL) { db_list = New(dlist(this, &this->m_link)); } db_list->append(this); } B_DB_POSTGRESQL::~B_DB_POSTGRESQL() { } /* * Check that the database correspond to the encoding we want */ static bool pgsql_check_database_encoding(JCR *jcr, B_DB_POSTGRESQL *mdb) { SQL_ROW row; bool retval = false; if (!mdb->sql_query("SELECT getdatabaseencoding()", QF_STORE_RESULT)) { Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); return false; } if ((row = mdb->sql_fetch_row()) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), mdb->sql_strerror()); Jmsg(jcr, M_ERROR, 0, "Can't check database encoding %s", mdb->errmsg); } else { retval = bstrcmp(row[0], "SQL_ASCII"); if (retval) { /* * If we are in SQL_ASCII, we can force the client_encoding to SQL_ASCII too */ mdb->sql_query("SET client_encoding TO 'SQL_ASCII'"); } else { /* * Something is wrong with database encoding */ Mmsg(mdb->errmsg, _("Encoding error for database \"%s\". Wanted SQL_ASCII, got %s\n"), mdb->get_db_name(), row[0]); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); Dmsg1(50, "%s", mdb->errmsg); } } return retval; } /* * Now actually open the database. This can generate errors, * which are returned in the errmsg * * DO NOT close the database or delete mdb here !!!! */ bool B_DB_POSTGRESQL::db_open_database(JCR *jcr) { bool retval = false; int errstat; char buf[10], *port; P(mutex); if (m_connected) { retval = true; goto bail_out; } if ((errstat=rwl_init(&m_lock)) != 0) { berrno be; Mmsg1(&errmsg, _("Unable to initialize DB lock. ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } if (m_db_port) { bsnprintf(buf, sizeof(buf), "%d", m_db_port); port = buf; } else { port = NULL; } /* If connection fails, try at 5 sec intervals for 30 seconds. */ for (int retry=0; retry < 6; retry++) { /* connect to the database */ m_db_handle = PQsetdbLogin( m_db_address, /* default = localhost */ port, /* default port */ NULL, /* pg options */ NULL, /* tty, ignored */ m_db_name, /* database name */ m_db_user, /* login name */ m_db_password); /* password */ /* If no connect, try once more in case it is a timing problem */ if (PQstatus(m_db_handle) == CONNECTION_OK) { break; } bmicrosleep(5, 0); } Dmsg0(50, "pg_real_connect done\n"); Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", m_db_user, m_db_name, (m_db_password == NULL) ? "(NULL)" : m_db_password); if (PQstatus(m_db_handle) != CONNECTION_OK) { Mmsg2(&errmsg, _("Unable to connect to PostgreSQL server. Database=%s User=%s\n" "Possible causes: SQL server not running; password incorrect; max_connections exceeded.\n"), m_db_name, m_db_user); goto bail_out; } m_connected = true; if (!check_tables_version(jcr, this)) { goto bail_out; } sql_query("SET datestyle TO 'ISO, YMD'"); sql_query("SET cursor_tuple_fraction=1"); /* * Tell PostgreSQL we are using standard conforming strings * and avoid warnings such as: * WARNING: nonstandard use of \\ in a string literal */ sql_query("SET standard_conforming_strings=on"); /* * Check that encoding is SQL_ASCII */ pgsql_check_database_encoding(jcr, this); retval = true; bail_out: V(mutex); return retval; } void B_DB_POSTGRESQL::db_close_database(JCR *jcr) { if (m_connected) { db_end_transaction(jcr); } P(mutex); m_ref_count--; if (m_ref_count == 0) { if (m_connected) { sql_free_result(); } db_list->remove(this); if (m_connected && m_db_handle) { PQfinish(m_db_handle); } if (rwl_is_init(&m_lock)) { rwl_destroy(&m_lock); } free_pool_memory(errmsg); free_pool_memory(cmd); free_pool_memory(cached_path); free_pool_memory(fname); free_pool_memory(path); free_pool_memory(esc_name); free_pool_memory(esc_path); free_pool_memory(esc_obj); free_pool_memory(m_buf); if (m_db_driver) { free(m_db_driver); } if (m_db_name) { free(m_db_name); } if (m_db_user) { free(m_db_user); } if (m_db_password) { free(m_db_password); } if (m_db_address) { free(m_db_address); } if (m_db_socket) { free(m_db_socket); } delete this; if (db_list->size() == 0) { delete db_list; db_list = NULL; } } V(mutex); } bool B_DB_POSTGRESQL::db_validate_connection(void) { bool retval = false; /* * Perform a null query to see if the connection is still valid. */ db_lock(this); if (!sql_query("SELECT 1", true)) { /* * Try resetting the connection. */ PQreset(m_db_handle); if (PQstatus(m_db_handle) != CONNECTION_OK) { goto bail_out; } /* * Retry the null query. */ if (!sql_query("SELECT 1", true)) { goto bail_out; } } sql_free_result(); retval = true; bail_out: db_unlock(this); return retval; } /* * Escape strings so that PostgreSQL is happy * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. */ void B_DB_POSTGRESQL::db_escape_string(JCR *jcr, char *snew, char *old, int len) { int error; PQescapeStringConn(m_db_handle, snew, old, len, &error); if (error) { Jmsg(jcr, M_FATAL, 0, _("PQescapeStringConn returned non-zero.\n")); /* error on encoding, probably invalid multibyte encoding in the source string see PQescapeStringConn documentation for details. */ Dmsg0(500, "PQescapeStringConn failed\n"); } } /* * Escape binary so that PostgreSQL is happy * */ char *B_DB_POSTGRESQL::db_escape_object(JCR *jcr, char *old, int len) { size_t new_len; unsigned char *obj; obj = PQescapeByteaConn(m_db_handle, (unsigned const char *)old, len, &new_len); if (!obj) { Jmsg(jcr, M_FATAL, 0, _("PQescapeByteaConn returned NULL.\n")); } esc_obj = check_pool_memory_size(esc_obj, new_len+1); memcpy(esc_obj, obj, new_len); esc_obj[new_len]=0; PQfreemem(obj); return (char *)esc_obj; } /* * Unescape binary object so that PostgreSQL is happy * */ void B_DB_POSTGRESQL::db_unescape_object(JCR *jcr, char *from, int32_t expected_len, POOLMEM **dest, int32_t *dest_len) { size_t new_len; unsigned char *obj; if (!from) { *dest[0] = 0; *dest_len = 0; return; } obj = PQunescapeBytea((unsigned const char *)from, &new_len); if (!obj) { Jmsg(jcr, M_FATAL, 0, _("PQunescapeByteaConn returned NULL.\n")); } *dest_len = new_len; *dest = check_pool_memory_size(*dest, new_len+1); memcpy(*dest, obj, new_len); (*dest)[new_len]=0; PQfreemem(obj); Dmsg1(010, "obj size: %d\n", *dest_len); } /* * Start a transaction. This groups inserts and makes things * much more efficient. Usually started when inserting * file attributes. */ void B_DB_POSTGRESQL::db_start_transaction(JCR *jcr) { if (!jcr->attr) { jcr->attr = get_pool_memory(PM_FNAME); } if (!jcr->ar) { jcr->ar = (ATTR_DBR *)malloc(sizeof(ATTR_DBR)); } /* * This is turned off because transactions break * if multiple simultaneous jobs are run. */ if (!m_allow_transactions) { return; } db_lock(this); /* * Allow only 25,000 changes per transaction */ if (m_transaction && changes > 25000) { db_end_transaction(jcr); } if (!m_transaction) { sql_query("BEGIN"); /* begin transaction */ Dmsg0(400, "Start PosgreSQL transaction\n"); m_transaction = true; } db_unlock(this); } void B_DB_POSTGRESQL::db_end_transaction(JCR *jcr) { if (jcr && jcr->cached_attribute) { Dmsg0(400, "Flush last cached attribute.\n"); if (!db_create_attributes_record(jcr, this, jcr->ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } if (!m_allow_transactions) { return; } db_lock(this); if (m_transaction) { sql_query("COMMIT"); /* end transaction */ m_transaction = false; Dmsg1(400, "End PostgreSQL transaction changes=%d\n", changes); } changes = 0; db_unlock(this); } /* * Submit a general SQL command (cmd), and for each row returned, * the result_handler is called with the ctx. */ bool B_DB_POSTGRESQL::db_big_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { SQL_ROW row; bool retval = false; bool in_transaction = m_transaction; Dmsg1(500, "db_sql_query starts with '%s'\n", query); /* This code handles only SELECT queries */ if (!bstrncasecmp(query, "SELECT", 6)) { return db_sql_query(query, result_handler, ctx); } if (!result_handler) { /* no need of big_query without handler */ return false; } db_lock(this); if (!in_transaction) { /* CURSOR needs transaction */ sql_query("BEGIN"); } Mmsg(m_buf, "DECLARE _bac_cursor CURSOR FOR %s", query); if (!sql_query(m_buf)) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), m_buf, sql_strerror()); Dmsg0(50, "db_sql_query failed\n"); goto bail_out; } do { if (!sql_query("FETCH 100 FROM _bac_cursor")) { goto bail_out; } while ((row = sql_fetch_row()) != NULL) { Dmsg1(500, "Fetching %d rows\n", m_num_rows); if (result_handler(ctx, m_num_fields, row)) break; } PQclear(m_result); m_result = NULL; } while (m_num_rows > 0); sql_query("CLOSE _bac_cursor"); Dmsg0(500, "db_big_sql_query finished\n"); sql_free_result(); retval = true; bail_out: if (!in_transaction) { sql_query("COMMIT"); /* end transaction */ } db_unlock(this); return retval; } /* * Submit a general SQL command (cmd), and for each row returned, * the result_handler is called with the ctx. */ bool B_DB_POSTGRESQL::db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { SQL_ROW row; bool retval = true; Dmsg1(500, "db_sql_query starts with '%s'\n", query); db_lock(this); if (!sql_query(query, QF_STORE_RESULT)) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror()); Dmsg0(500, "db_sql_query failed\n"); retval = false; goto bail_out; } Dmsg0(500, "db_sql_query succeeded. checking handler\n"); if (result_handler != NULL) { Dmsg0(500, "db_sql_query invoking handler\n"); while ((row = sql_fetch_row()) != NULL) { Dmsg0(500, "db_sql_query sql_fetch_row worked\n"); if (result_handler(ctx, m_num_fields, row)) break; } sql_free_result(); } Dmsg0(500, "db_sql_query finished\n"); bail_out: db_unlock(this); return retval; } /* * Note, if this routine returns false (failure), BAREOS expects * that no result has been stored. * This is where QUERY_DB comes with Postgresql. * * Returns: true on success * false on failure * */ bool B_DB_POSTGRESQL::sql_query(const char *query, int flags) { int i; bool retval = false; Dmsg1(500, "sql_query starts with '%s'\n", query); /* * We are starting a new query. reset everything. */ m_num_rows = -1; m_row_number = -1; m_field_number = -1; if (m_result) { PQclear(m_result); /* hmm, someone forgot to free?? */ m_result = NULL; } for (i = 0; i < 10; i++) { m_result = PQexec(m_db_handle, query); if (m_result) { break; } bmicrosleep(5, 0); } if (!m_result) { Dmsg1(50, "Query failed: %s\n", query); goto bail_out; } m_status = PQresultStatus(m_result); if (m_status == PGRES_TUPLES_OK || m_status == PGRES_COMMAND_OK) { Dmsg0(500, "we have a result\n"); /* * How many fields in the set? */ m_num_fields = (int)PQnfields(m_result); Dmsg1(500, "we have %d fields\n", m_num_fields); m_num_rows = PQntuples(m_result); Dmsg1(500, "we have %d rows\n", m_num_rows); m_row_number = 0; /* we can start to fetch something */ m_status = 0; /* succeed */ retval = true; } else { Dmsg1(50, "Result status failed: %s\n", query); goto bail_out; } Dmsg0(500, "sql_query finishing\n"); goto ok_out; bail_out: Dmsg0(500, "we failed\n"); PQclear(m_result); m_result = NULL; m_status = 1; /* failed */ ok_out: return retval; } void B_DB_POSTGRESQL::sql_free_result(void) { db_lock(this); if (m_result) { PQclear(m_result); m_result = NULL; } if (m_rows) { free(m_rows); m_rows = NULL; } if (m_fields) { free(m_fields); m_fields = NULL; } m_num_rows = m_num_fields = 0; db_unlock(this); } SQL_ROW B_DB_POSTGRESQL::sql_fetch_row(void) { int j; SQL_ROW row = NULL; /* by default, return NULL */ Dmsg0(500, "sql_fetch_row start\n"); if (m_num_fields == 0) { /* No field, no row */ Dmsg0(500, "sql_fetch_row finishes returning NULL, no fields\n"); return NULL; } if (!m_rows || m_rows_size < m_num_fields) { if (m_rows) { Dmsg0(500, "sql_fetch_row freeing space\n"); free(m_rows); } Dmsg1(500, "we need space for %d bytes\n", sizeof(char *) * m_num_fields); m_rows = (SQL_ROW)malloc(sizeof(char *) * m_num_fields); m_rows_size = m_num_fields; /* * Now reset the row_number now that we have the space allocated */ m_row_number = 0; } /* * If still within the result set */ if (m_row_number >= 0 && m_row_number < m_num_rows) { Dmsg2(500, "sql_fetch_row row number '%d' is acceptable (0..%d)\n", m_row_number, m_num_rows); /* * Get each value from this row */ for (j = 0; j < m_num_fields; j++) { m_rows[j] = PQgetvalue(m_result, m_row_number, j); Dmsg2(500, "sql_fetch_row field '%d' has value '%s'\n", j, m_rows[j]); } /* * Increment the row number for the next call */ m_row_number++; row = m_rows; } else { Dmsg2(500, "sql_fetch_row row number '%d' is NOT acceptable (0..%d)\n", m_row_number, m_num_rows); } Dmsg1(500, "sql_fetch_row finishes returning %p\n", row); return row; } const char *B_DB_POSTGRESQL::sql_strerror(void) { return PQerrorMessage(m_db_handle); } void B_DB_POSTGRESQL::sql_data_seek(int row) { /* * Set the row number to be returned on the next call to sql_fetch_row */ m_row_number = row; } int B_DB_POSTGRESQL::sql_affected_rows(void) { return (unsigned) str_to_int32(PQcmdTuples(m_result)); } uint64_t B_DB_POSTGRESQL::sql_insert_autokey_record(const char *query, const char *table_name) { int i; uint64_t id = 0; char sequence[NAMEDATALEN-1]; char getkeyval_query[NAMEDATALEN+50]; PGresult *pg_result; /* * First execute the insert query and then retrieve the currval. */ if (!sql_query(query)) { return 0; } m_num_rows = sql_affected_rows(); if (m_num_rows != 1) { return 0; } changes++; /* * Obtain the current value of the sequence that * provides the serial value for primary key of the table. * * currval is local to our session. It is not affected by * other transactions. * * Determine the name of the sequence. * PostgreSQL automatically creates a sequence using *
__seq. * At the time of writing, all tables used this format for * for their primary key:
id * Except for basefiles which has a primary key on baseid. * Therefore, we need to special case that one table. * * everything else can use the PostgreSQL formula. */ if (bstrcasecmp(table_name, "basefiles")) { bstrncpy(sequence, "basefiles_baseid", sizeof(sequence)); } else { bstrncpy(sequence, table_name, sizeof(sequence)); bstrncat(sequence, "_", sizeof(sequence)); bstrncat(sequence, table_name, sizeof(sequence)); bstrncat(sequence, "id", sizeof(sequence)); } bstrncat(sequence, "_seq", sizeof(sequence)); bsnprintf(getkeyval_query, sizeof(getkeyval_query), "SELECT currval('%s')", sequence); Dmsg1(500, "sql_insert_autokey_record executing query '%s'\n", getkeyval_query); for (i = 0; i < 10; i++) { pg_result = PQexec(m_db_handle, getkeyval_query); if (pg_result) { break; } bmicrosleep(5, 0); } if (!pg_result) { Dmsg1(50, "Query failed: %s\n", getkeyval_query); goto bail_out; } Dmsg0(500, "exec done"); if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) { Dmsg0(500, "getting value"); id = str_to_uint64(PQgetvalue(pg_result, 0, 0)); Dmsg2(500, "got value '%s' which became %d\n", PQgetvalue(pg_result, 0, 0), id); } else { Dmsg1(50, "Result status failed: %s\n", getkeyval_query); Mmsg1(&errmsg, _("error fetching currval: %s\n"), PQerrorMessage(m_db_handle)); } bail_out: PQclear(pg_result); return id; } SQL_FIELD *B_DB_POSTGRESQL::sql_fetch_field(void) { int i, j; int max_length; int this_length; Dmsg0(500, "sql_fetch_field starts\n"); if (!m_fields || m_fields_size < m_num_fields) { if (m_fields) { free(m_fields); m_fields = NULL; } Dmsg1(500, "allocating space for %d fields\n", m_num_fields); m_fields = (SQL_FIELD *)malloc(sizeof(SQL_FIELD) * m_num_fields); m_fields_size = m_num_fields; for (i = 0; i < m_num_fields; i++) { Dmsg1(500, "filling field %d\n", i); m_fields[i].name = PQfname(m_result, i); m_fields[i].type = PQftype(m_result, i); m_fields[i].flags = 0; /* * For a given column, find the max length. */ max_length = 0; for (j = 0; j < m_num_rows; j++) { if (PQgetisnull(m_result, j, i)) { this_length = 4; /* "NULL" */ } else { this_length = cstrlen(PQgetvalue(m_result, j, i)); } if (max_length < this_length) { max_length = this_length; } } m_fields[i].max_length = max_length; Dmsg4(500, "sql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", m_fields[i].name, m_fields[i].max_length, m_fields[i].type, m_fields[i].flags); } } /* * Increment field number for the next time around */ return &m_fields[m_field_number++]; } bool B_DB_POSTGRESQL::sql_field_is_not_null(int field_type) { switch (field_type) { case 1: return true; default: return false; } } bool B_DB_POSTGRESQL::sql_field_is_numeric(int field_type) { /* * TEMP: the following is taken from select OID, typname from pg_type; */ switch (field_type) { case 20: case 21: case 23: case 700: case 701: return true; default: return false; } } /* * Escape strings so that PostgreSQL is happy on COPY * * NOTE! len is the length of the old string. Your new * string must be long enough (max 2*old+1) to hold * the escaped output. */ static char *pgsql_copy_escape(char *dest, char *src, size_t len) { /* we have to escape \t, \n, \r, \ */ char c = '\0' ; while (len > 0 && *src) { switch (*src) { case '\n': c = 'n'; break; case '\\': c = '\\'; break; case '\t': c = 't'; break; case '\r': c = 'r'; break; default: c = '\0' ; } if (c) { *dest = '\\'; dest++; *dest = c; } else { *dest = *src; } len--; src++; dest++; } *dest = '\0'; return dest; } bool B_DB_POSTGRESQL::sql_batch_start(JCR *jcr) { const char *query = "COPY batch FROM STDIN"; Dmsg0(500, "sql_batch_start started\n"); if (!sql_query("CREATE TEMPORARY TABLE batch (" "FileIndex int," "JobId int," "Path varchar," "Name varchar," "LStat varchar," "Md5 varchar," "DeltaSeq smallint)")) { Dmsg0(500, "sql_batch_start failed\n"); return false; } /* * We are starting a new query. reset everything. */ m_num_rows = -1; m_row_number = -1; m_field_number = -1; sql_free_result(); for (int i=0; i < 10; i++) { m_result = PQexec(m_db_handle, query); if (m_result) { break; } bmicrosleep(5, 0); } if (!m_result) { Dmsg1(50, "Query failed: %s\n", query); goto bail_out; } m_status = PQresultStatus(m_result); if (m_status == PGRES_COPY_IN) { /* * How many fields in the set? */ m_num_fields = (int) PQnfields(m_result); m_num_rows = 0; m_status = 1; } else { Dmsg1(50, "Result status failed: %s\n", query); goto bail_out; } Dmsg0(500, "sql_batch_start finishing\n"); return true; bail_out: Mmsg1(&errmsg, _("error starting batch mode: %s"), PQerrorMessage(m_db_handle)); m_status = 0; PQclear(m_result); m_result = NULL; return false; } /* * Set error to something to abort operation */ bool B_DB_POSTGRESQL::sql_batch_end(JCR *jcr, const char *error) { int res; int count=30; PGresult *pg_result; Dmsg0(500, "sql_batch_end started\n"); do { res = PQputCopyEnd(m_db_handle, error); } while (res == 0 && --count > 0); if (res == 1) { Dmsg0(500, "ok\n"); m_status = 1; } if (res <= 0) { Dmsg0(500, "we failed\n"); m_status = 0; Mmsg1(&errmsg, _("error ending batch mode: %s"), PQerrorMessage(m_db_handle)); Dmsg1(500, "failure %s\n", errmsg); } /* * Check command status and return to normal libpq state */ pg_result = PQgetResult(m_db_handle); if (PQresultStatus(pg_result) != PGRES_COMMAND_OK) { Mmsg1(&errmsg, _("error ending batch mode: %s"), PQerrorMessage(m_db_handle)); m_status = 0; } PQclear(pg_result); Dmsg0(500, "sql_batch_end finishing\n"); return true; } bool B_DB_POSTGRESQL::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) { int res; int count=30; size_t len; const char *digest; char ed1[50]; esc_name = check_pool_memory_size(esc_name, fnl*2+1); pgsql_copy_escape(esc_name, fname, fnl); esc_path = check_pool_memory_size(esc_path, pnl*2+1); pgsql_copy_escape(esc_path, path, pnl); if (ar->Digest == NULL || ar->Digest[0] == 0) { digest = "0"; } else { digest = ar->Digest; } len = Mmsg(cmd, "%u\t%s\t%s\t%s\t%s\t%s\t%u\n", ar->FileIndex, edit_int64(ar->JobId, ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); do { res = PQputCopyData(m_db_handle, cmd, len); } while (res == 0 && --count > 0); if (res == 1) { Dmsg0(500, "ok\n"); changes++; m_status = 1; } if (res <= 0) { Dmsg0(500, "we failed\n"); m_status = 0; Mmsg1(&errmsg, _("error copying in batch mode: %s"), PQerrorMessage(m_db_handle)); Dmsg1(500, "failure %s\n", errmsg); } Dmsg0(500, "sql_batch_insert finishing\n"); return true; } /* * Initialize database data structure. In principal this should * never have errors, or it is really fatal. */ #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" B_DB CATS_IMP_EXP *backend_instantiate(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #else B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #endif { B_DB_POSTGRESQL *mdb = NULL; if (!db_user) { Jmsg(jcr, M_FATAL, 0, _("A user name for PostgreSQL must be supplied.\n")); return NULL; } P(mutex); /* lock DB queue */ /* * Look to see if DB already open */ if (db_list && !mult_db_connections && !need_private) { foreach_dlist(mdb, db_list) { if (mdb->is_private()) { continue; } if (mdb->db_match_database(db_driver, db_name, db_address, db_port)) { Dmsg1(100, "DB REopen %s\n", db_name); mdb->increment_refcount(); goto bail_out; } } } Dmsg0(100, "db_init_database first time\n"); mdb = New(B_DB_POSTGRESQL(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private)); bail_out: V(mutex); return mdb; } #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" void CATS_IMP_EXP flush_backend(void) #else void db_flush_backends(void) #endif { } #endif /* HAVE_POSTGRESQL */ bareos-Release-14.2.6/src/cats/protos.h000066400000000000000000000252161263011562700176660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Database routines that are exported by the cats library for * use elsewhere in BAREOS (mainly the Director). */ #ifndef __SQL_PROTOS_H #define __SQL_PROTOS_H #include "cats.h" /* Database prototypes */ /* cats_backends.c */ #if defined(HAVE_DYNAMIC_CATS_BACKENDS) void db_set_backend_dirs(alist *new_backend_dirs); #endif void db_flush_backends(void); /* sql.c */ bool db_open_batch_connection(JCR *jcr, B_DB *mdb); char *db_strerror(B_DB *mdb); int db_int64_handler(void *ctx, int num_fields, char **row); int db_strtime_handler(void *ctx, int num_fields, char **row); int db_list_handler(void *ctx, int num_fields, char **row); void db_debug_print(JCR *jcr, FILE *fp); int db_int_handler(void *ctx, int num_fields, char **row); /* sql_create.c */ bool db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); bool db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); bool db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr); bool db_create_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *media_dbr); bool db_create_client_record(JCR *jcr, B_DB *db, CLIENT_DBR *cr); bool db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr); bool db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr); bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jr); bool db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr); bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr); bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr); bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr); bool db_write_batch_file_records(JCR *jcr); bool db_create_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ar); bool db_create_base_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb); bool db_create_base_file_list(JCR *jcr, B_DB *mdb, char *jobids); bool db_create_quota_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr); bool db_create_ndmp_level_mapping(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *filesystem); bool db_create_ndmp_environment_string(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *name, char *value); bool db_create_job_statistics(JCR *jcr, B_DB *mdb, JOB_STATS_DBR *jsr); bool db_create_device_statistics(JCR *jcr, B_DB *mdb, DEVICE_STATS_DBR *dsr); bool db_create_tapealert_statistics(JCR *jcr, B_DB *mdb, TAPEALERT_STATS_DBR *tsr); /* sql_delete.c */ bool db_delete_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr); bool db_delete_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr); /* sql_find.c */ bool db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job, int JobLevel); bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job); bool db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr); int db_find_next_volume(JCR *jcr, B_DB *mdb, int index, bool InChanger, MEDIA_DBR *mr); bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel); /* sql_get.c */ bool db_get_volume_jobids(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr, db_list_ctx *lst); bool db_get_base_file_list(JCR *jcr, B_DB *mdb, bool use_md5, DB_RESULT_HANDLER *result_handler,void *ctx); int db_get_path_record(JCR *jcr, B_DB *mdb); bool db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr); bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr); int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames); bool db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr); int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr); bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr); int db_get_num_media_records(JCR *jcr, B_DB *mdb); int db_get_num_pool_records(JCR *jcr, B_DB *mdb); int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, DBId_t **ids); bool db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, DBId_t **ids); bool db_get_media_ids(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr, POOL_MEM &volumes, int *num_ids, uint32_t **ids); int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS **VolParams); bool db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr); bool db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr); bool db_get_query_dbids(JCR *jcr, B_DB *mdb, POOL_MEM &query, dbid_list &ids); bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids, bool use_md5, bool use_delta, DB_RESULT_HANDLER *result_handler, void *ctx); bool db_get_base_jobid(JCR *jcr, B_DB *mdb, JOB_DBR *jr, JobId_t *jobid); bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, db_list_ctx *jobids); bool db_get_used_base_jobids(JCR *jcr, B_DB *mdb, POOLMEM *jobids, db_list_ctx *result); bool db_get_quota_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr); bool db_get_quota_jobbytes(JCR *jcr, B_DB *mdb, JOB_DBR *jr, utime_t JobRetention); bool db_get_quota_jobbytes_nofailed(JCR *jcr, B_DB *mdb, JOB_DBR *jr, utime_t JobRetention); int db_get_ndmp_level_mapping(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *filesystem); bool db_get_ndmp_environment_string(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_RESULT_HANDLER *result_handler, void *ctx); /* sql_list.c */ void db_list_pool_records(JCR *jcr, B_DB *db, POOL_DBR *pr, DB_LIST_HANDLER sendit, void *ctx, e_list_type type); void db_list_job_records(JCR *jcr, B_DB *db, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx, e_list_type type); void db_list_job_totals(JCR *jcr, B_DB *db, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx); void db_list_files_for_job(JCR *jcr, B_DB *db, uint32_t jobid, DB_LIST_HANDLER sendit, void *ctx); void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void db_list_joblog_records(JCR *jcr, B_DB *mdb, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); bool db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query, DB_LIST_HANDLER *sendit, void *ctx, bool verbose, e_list_type type); void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void db_list_copies_records(JCR *jcr, B_DB *mdb, uint32_t limit, char *jobids, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void db_list_base_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx); /* sql_pooling.c */ bool db_sql_pool_initialize(const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool disable_batch_insert, int min_connections, int max_connections, int increment_connections, int idle_timeout, int validate_timeout); void db_sql_pool_destroy(void); void db_sql_pool_flush(void); B_DB *db_sql_get_non_pooled_connection(JCR *jcr, const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections = false, bool disable_batch_insert = false, bool need_private = false); B_DB *db_sql_get_pooled_connection(JCR *jcr, const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections = false, bool disable_batch_insert = false, bool need_private = false); void db_sql_close_pooled_connection(JCR *jcr, B_DB *mdb, bool abort=false); /* sql_update.c */ bool db_update_job_start_record(JCR *jcr, B_DB *db, JOB_DBR *jr); bool db_update_job_end_record(JCR *jcr, B_DB *db, JOB_DBR *jr); bool db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr); bool db_update_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pr); bool db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr); bool db_update_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *mr); bool db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr); bool db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr); bool db_update_quota_gracetime(JCR *jcr, B_DB *mdb, JOB_DBR *jr); bool db_update_quota_softlimit(JCR *jcr, B_DB *mdb, JOB_DBR *jr); bool db_reset_quota_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *jr); bool db_update_ndmp_level_mapping(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *filesystem, int level); bool db_add_digest_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *digest, int type); bool db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId); void db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr); int db_update_stats(JCR *jcr, B_DB *mdb, utime_t age); #endif /* __SQL_PROTOS_H */ bareos-Release-14.2.6/src/cats/restore_ingres_catalog_backup.in000077500000000000000000000037211263011562700245700ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # shell script to restore a dump of the bareos Ingres database using # a base64 encoded tar of the content. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-@db_name@}" db_user="${db_user:-@db_user@}" working_dir=`get_working_dir` bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi # # Source the Ingres settings when they exist. # if [ ! -z "${bindir}" ]; then [ -f ${bindir}/../../.ingIIsh ] && . ${bindir}/../../.ingIIsh fi # # See if the dumpdir exists. # [ ! -d ${working_dir}/ingres_dump ] && mkdir -p ${working_dir}/ingres_dump # # Decode the tar and restore it. # cd ${working_dir}/ingres_dump || exit 1 case `uname -s` in Linux) base64 -d | gzip -dc | tar xf - ;; SunOS) uudecode -p | gzip -dc | tar xf - ;; *) echo "Unsupported OS type encountered, `uname -s`" exit 1 ;; esac if [ $? = 0 ]; then # # Restore the data # sql -u${db_user} ${db_name} < copy.in sysmod ${db_name} fi cd / rm -rf ${working_dir}/ingres_dump exit 0 bareos-Release-14.2.6/src/cats/sql.c000066400000000000000000000556531263011562700171420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database interface routines * * Almost generic set of SQL database interface routines * (with a little more work) SQL engine specific routines are in * mysql.c, postgresql.c, sqlite.c, ... * * Kern Sibbald, March 2000 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* Forward referenced subroutines */ void print_dashes(B_DB *mdb); void print_result(B_DB *mdb); dbid_list::dbid_list() { memset(this, 0, sizeof(dbid_list)); max_ids = 1000; DBId = (DBId_t *)malloc(max_ids * sizeof(DBId_t)); num_ids = num_seen = tot_ids = 0; PurgedFiles = NULL; } dbid_list::~dbid_list() { free(DBId); } /* * Called here to retrieve an integer from the database */ int db_int_handler(void *ctx, int num_fields, char **row) { uint32_t *val = (uint32_t *)ctx; Dmsg1(800, "int_handler starts with row pointing at %x\n", row); if (row[0]) { Dmsg1(800, "int_handler finds '%s'\n", row[0]); *val = str_to_int64(row[0]); } else { Dmsg0(800, "int_handler finds zero\n"); *val = 0; } Dmsg0(800, "int_handler finishes\n"); return 0; } /* * Called here to retrieve a 32/64 bit integer from the database. * The returned integer will be extended to 64 bit. */ int db_int64_handler(void *ctx, int num_fields, char **row) { db_int64_ctx *lctx = (db_int64_ctx *)ctx; if (row[0]) { lctx->value = str_to_int64(row[0]); lctx->count++; } return 0; } /* * Called here to retrieve a btime from the database. * The returned integer will be extended to 64 bit. */ int db_strtime_handler(void *ctx, int num_fields, char **row) { db_int64_ctx *lctx = (db_int64_ctx *)ctx; if (row[0]) { lctx->value = str_to_utime(row[0]); lctx->count++; } return 0; } /* * Use to build a comma separated list of values from a query. "10,20,30" */ int db_list_handler(void *ctx, int num_fields, char **row) { db_list_ctx *lctx = (db_list_ctx *)ctx; if (num_fields == 1 && row[0]) { lctx->add(row[0]); } return 0; } /* * specific context passed from db_check_max_connections to db_max_connections_handler. */ struct max_connections_context { B_DB *db; uint32_t nr_connections; }; /* * Called here to retrieve an integer from the database */ static inline int db_max_connections_handler(void *ctx, int num_fields, char **row) { struct max_connections_context *context; uint32_t index; context = (struct max_connections_context *)ctx; switch (db_get_type_index(context->db)) { case SQL_TYPE_MYSQL: index = 1; break; default: index = 0; break; } if (row[index]) { context->nr_connections = str_to_int64(row[index]); } else { Dmsg0(800, "int_handler finds zero\n"); context->nr_connections = 0; } return 0; } /* * Check catalog max_connections setting */ bool db_check_max_connections(JCR *jcr, B_DB *mdb, uint32_t max_concurrent_jobs) { struct max_connections_context context; /* Without Batch insert, no need to verify max_connections */ if (!mdb->batch_insert_available()) return true; context.db = mdb; context.nr_connections = 0; /* Check max_connections setting */ if (!db_sql_query(mdb, sql_get_max_connections[db_get_type_index(mdb)], db_max_connections_handler, &context)) { Jmsg(jcr, M_ERROR, 0, "Can't verify max_connections settings %s", mdb->errmsg); return false; } if (context.nr_connections && max_concurrent_jobs && max_concurrent_jobs > context.nr_connections) { Mmsg(mdb->errmsg, _("Potential performance problem:\n" "max_connections=%d set for %s database \"%s\" should be larger than Director's " "MaxConcurrentJobs=%d\n"), context.nr_connections, db_get_type(mdb), mdb->get_db_name(), max_concurrent_jobs); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); return false; } return true; } /* NOTE!!! The following routines expect that the * calling subroutine sets and clears the mutex */ /* Check that the tables correspond to the version we want */ bool check_tables_version(JCR *jcr, B_DB *mdb) { uint32_t bareos_db_version = 0; const char *query = "SELECT VersionId FROM Version"; if (!db_sql_query(mdb, query, db_int_handler, (void *)&bareos_db_version)) { Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); return false; } if (bareos_db_version != BDB_VERSION) { Mmsg(mdb->errmsg, "Version error for database \"%s\". Wanted %d, got %d\n", mdb->get_db_name(), BDB_VERSION, bareos_db_version); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); return false; } return true; } /* * Utility routine for queries. The database MUST be locked before calling here. * Returns: false on failure * true on success */ bool QueryDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd) { sql_free_result(mdb); if (!sql_query(mdb, cmd, QF_STORE_RESULT)) { m_msg(file, line, &mdb->errmsg, _("query %s failed:\n%s\n"), cmd, sql_strerror(mdb)); j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg); if (verbose) { j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd); } return false; } return true; } /* * Utility routine to do inserts * Returns: false on failure * true on success */ bool InsertDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd) { int num_rows; if (!sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("insert %s failed:\n%s\n"), cmd, sql_strerror(mdb)); j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg); if (verbose) { j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd); } return false; } num_rows = sql_affected_rows(mdb); if (num_rows != 1) { char ed1[30]; m_msg(file, line, &mdb->errmsg, _("Insertion problem: affected_rows=%s\n"), edit_uint64(num_rows, ed1)); if (verbose) { j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd); } return false; } mdb->changes++; return true; } /* * Utility routine for updates. * Returns: false on failure * true on success */ bool UpdateDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd, int nr_afr) { int num_rows; if (!sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("update %s failed:\n%s\n"), cmd, sql_strerror(mdb)); j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg); if (verbose) { j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd); } return false; } if (nr_afr > 0) { num_rows = sql_affected_rows(mdb); if (num_rows < nr_afr) { char ed1[30]; m_msg(file, line, &mdb->errmsg, _("Update failed: affected_rows=%s for %s\n"), edit_uint64(num_rows, ed1), cmd); if (verbose) { // j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd); } return false; } } mdb->changes++; return true; } /* * Utility routine for deletes * * Returns: -1 on error * n number of rows affected */ int DeleteDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd) { if (!sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("delete %s failed:\n%s\n"), cmd, sql_strerror(mdb)); j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg); if (verbose) { j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd); } return -1; } mdb->changes++; return sql_affected_rows(mdb); } /* * Get record max. Query is already in mdb->cmd * No locking done * * Returns: -1 on failure * count on success */ int get_sql_record_max(JCR *jcr, B_DB *mdb) { SQL_ROW row; int retval = 0; if (QUERY_DB(jcr, mdb, mdb->cmd)) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); retval = -1; } else { retval = str_to_int64(row[0]); } sql_free_result(mdb); } else { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); retval = -1; } return retval; } /* * Return pre-edited error message */ char *db_strerror(B_DB *mdb) { return mdb->errmsg; } /* * Given a full filename, split it into its path * and filename parts. They are returned in pool memory * in the mdb structure. */ void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname) { const char *p, *f; /* Find path without the filename. * I.e. everything after the last / is a "filename". * OK, maybe it is a directory name, but we treat it like * a filename. If we don't find a / then the whole name * must be a path name (e.g. c:). */ for (p=f=fname; *p; p++) { if (IsPathSeparator(*p)) { f = p; /* set pos of last slash */ } } if (IsPathSeparator(*f)) { /* did we find a slash? */ f++; /* yes, point to filename */ } else { f = p; /* no, whole thing must be path name */ } /* If filename doesn't exist (i.e. root directory), we * simply create a blank name consisting of a single * space. This makes handling zero length filenames * easier. */ mdb->fnl = p - f; if (mdb->fnl > 0) { mdb->fname = check_pool_memory_size(mdb->fname, mdb->fnl+1); memcpy(mdb->fname, f, mdb->fnl); /* copy filename */ mdb->fname[mdb->fnl] = 0; } else { mdb->fname[0] = 0; mdb->fnl = 0; } mdb->pnl = f - fname; if (mdb->pnl > 0) { mdb->path = check_pool_memory_size(mdb->path, mdb->pnl+1); memcpy(mdb->path, fname, mdb->pnl); mdb->path[mdb->pnl] = 0; } else { Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), fname); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); mdb->path[0] = 0; mdb->pnl = 0; } Dmsg2(500, "split path=%s file=%s\n", mdb->path, mdb->fname); } /* * Set maximum field length to something reasonable */ static int max_length(int max_length) { int max_len = max_length; /* Sanity check */ if (max_len < 0) { max_len = 2; } else if (max_len > 100) { max_len = 100; } return max_len; } /* * List dashes as part of header for listing SQL results in a table */ void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx) { SQL_FIELD *field; int i, j; int len; int num_fields; sql_field_seek(mdb, 0); send(ctx, "+"); num_fields = sql_num_fields(mdb); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } len = max_length(field->max_length + 2); for (j = 0; j < len; j++) { send(ctx, "-"); } send(ctx, "+"); } send(ctx, "\n"); } /* Small handler to print the last line of a list xxx command */ static void last_line_handler(void *vctx, const char *str) { LIST_CTX *ctx = (LIST_CTX *)vctx; bstrncat(ctx->line, str, sizeof(ctx->line)); } int list_result(void *vctx, int nb_col, char **row) { SQL_FIELD *field; int i, col_len, max_len = 0; int num_fields; char buf[2000], ewc[30]; LIST_CTX *pctx = (LIST_CTX *)vctx; DB_LIST_HANDLER *send = pctx->send; e_list_type type = pctx->type; B_DB *mdb = pctx->mdb; void *ctx = pctx->ctx; JCR *jcr = pctx->jcr; num_fields = sql_num_fields(mdb); switch (type) { case NF_LIST: case RAW_LIST: /* * No need to calculate things like maximum field lenght for * unformated or raw output. */ break; case HORZ_LIST: case VERT_LIST: if (!pctx->once) { pctx->once = true; Dmsg1(800, "list_result starts looking at %d fields\n", num_fields); /* * Determine column display widths */ sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result processing field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } col_len = cstrlen(field->name); if (type == VERT_LIST) { if (col_len > max_len) { max_len = col_len; } } else { if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */ field->max_length += (field->max_length - 1) / 3; } if (col_len < (int)field->max_length) { col_len = field->max_length; } if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) { col_len = 4; /* 4 = length of the word "NULL" */ } field->max_length = col_len; /* reset column info */ } } pctx->num_rows++; Dmsg0(800, "list_result finished first loop\n"); if (type == VERT_LIST) { break; } Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields); /* * Keep the result to display the same line at the end of the table */ list_dashes(mdb, last_line_handler, pctx); send(ctx, pctx->line); send(ctx, "|"); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result looking at field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); bsnprintf(buf, sizeof(buf), " %-*s |", max_len, field->name); send(ctx, buf); } send(ctx, "\n"); list_dashes(mdb, send, ctx); } break; default: break; } switch (type) { case NF_LIST: case RAW_LIST: Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { bsnprintf(buf, sizeof(buf), " %s", "NULL"); } else { bsnprintf(buf, sizeof(buf), " %s", row[i]); } send(ctx, buf); } if (type != RAW_LIST) { send(ctx, "\n"); } break; case HORZ_LIST: Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields); sql_field_seek(mdb, 0); send(ctx, "|"); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); if (row[i] == NULL) { bsnprintf(buf, sizeof(buf), " %-*s |", max_len, "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { bsnprintf(buf, sizeof(buf), " %*s |", max_len, add_commas(row[i], ewc)); } else { bsnprintf(buf, sizeof(buf), " %-*s |", max_len, row[i]); } send(ctx, buf); } send(ctx, "\n"); break; case VERT_LIST: Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, add_commas(row[i], ewc)); } else { bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]); } send(ctx, buf); } send(ctx, "\n"); break; default: break; } return 0; } /* * If full_list is set, we list vertically, otherwise, we * list on one line horizontally. * Return number of rows */ int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type) { SQL_FIELD *field; SQL_ROW row; int i, col_len, max_len = 0; int num_fields; char buf[2000], ewc[30]; Dmsg0(800, "list_result starts\n"); if (sql_num_rows(mdb) == 0) { send(ctx, _("No results to list.\n")); return sql_num_rows(mdb); } num_fields = sql_num_fields(mdb); switch (type) { case NF_LIST: case RAW_LIST: /* * No need to calculate things like column widths for * unformated or raw output. */ break; case HORZ_LIST: case VERT_LIST: Dmsg1(800, "list_result starts looking at %d fields\n", num_fields); /* * Determine column display widths */ sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result processing field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } col_len = cstrlen(field->name); if (type == VERT_LIST) { if (col_len > max_len) { max_len = col_len; } } else { if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */ field->max_length += (field->max_length - 1) / 3; } if (col_len < (int)field->max_length) { col_len = field->max_length; } if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) { col_len = 4; /* 4 = length of the word "NULL" */ } field->max_length = col_len; /* reset column info */ } } break; } Dmsg0(800, "list_result finished first loop\n"); switch (type) { case NF_LIST: case RAW_LIST: Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields); while ((row = sql_fetch_row(mdb)) != NULL) { sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { bsnprintf(buf, sizeof(buf), " %s", "NULL"); } else { bsnprintf(buf, sizeof(buf), " %s", row[i]); } send(ctx, buf); } if (type != RAW_LIST) { send(ctx, "\n"); } } break; case HORZ_LIST: Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields); list_dashes(mdb, send, ctx); send(ctx, "|"); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result looking at field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); bsnprintf(buf, sizeof(buf), " %-*s |", max_len, field->name); send(ctx, buf); } send(ctx, "\n"); list_dashes(mdb, send, ctx); Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields); while ((row = sql_fetch_row(mdb)) != NULL) { sql_field_seek(mdb, 0); send(ctx, "|"); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); if (row[i] == NULL) { bsnprintf(buf, sizeof(buf), " %-*s |", max_len, "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { bsnprintf(buf, sizeof(buf), " %*s |", max_len, add_commas(row[i], ewc)); } else { bsnprintf(buf, sizeof(buf), " %-*s |", max_len, row[i]); } send(ctx, buf); } send(ctx, "\n"); } list_dashes(mdb, send, ctx); break; case VERT_LIST: Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields); while ((row = sql_fetch_row(mdb)) != NULL) { sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, add_commas(row[i], ewc)); } else { bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]); } send(ctx, buf); } send(ctx, "\n"); } break; } return sql_num_rows(mdb); } /* * Open a new connexion to mdb catalog. This function is used * by batch and accurate mode. */ bool db_open_batch_connection(JCR *jcr, B_DB *mdb) { bool multi_db; multi_db = mdb->batch_insert_available(); if (!jcr->db_batch) { jcr->db_batch = db_clone_database_connection(mdb, jcr, multi_db, multi_db); if (!jcr->db_batch) { Mmsg0(&mdb->errmsg, _("Could not init database batch connection\n")); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); return false; } } return true; } /* * !!! WARNING !!! Use this function only when bareos is stopped. * ie, after a fatal signal and before exiting the program * Print information about a B_DB object. */ void db_debug_print(JCR *jcr, FILE *fp) { B_DB *mdb = jcr->db; if (!mdb) { return; } fprintf(fp, "B_DB=%p db_name=%s db_user=%s connected=%s\n", mdb, NPRTB(mdb->get_db_name()), NPRTB(mdb->get_db_user()), mdb->is_connected() ? "true" : "false"); fprintf(fp, "\tcmd=\"%s\" changes=%i\n", NPRTB(mdb->cmd), mdb->changes); mdb->print_lock_info(fp); } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_cmds.c000066400000000000000000001117421263011562700201400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file contains all the SQL commands that are either issued by the * Director or which are database backend specific. * * Kern Sibbald, July MMII */ /* * Note, PostgreSQL imposes some constraints on using DISTINCT and GROUP BY * for example, the following is illegal in PostgreSQL: * SELECT DISTINCT JobId FROM temp ORDER BY StartTime ASC; * because all the ORDER BY expressions must appear in the SELECT list! */ #include "bareos.h" const char *get_restore_objects = "SELECT JobId,ObjectLength,ObjectFullLength,ObjectIndex," "ObjectType,ObjectCompression,FileIndex,ObjectName," "RestoreObject,PluginName " "FROM RestoreObject " "WHERE JobId IN (%s) " "AND ObjectType = %d " "ORDER BY ObjectIndex ASC"; const char *cleanup_created_job = "UPDATE Job SET JobStatus='f', StartTime=SchedTime, EndTime=SchedTime " "WHERE JobStatus = 'C'"; const char *cleanup_running_job = "UPDATE Job SET JobStatus='f', EndTime=StartTime WHERE JobStatus = 'R'"; /* For sql_update.c db_update_stats */ const char *fill_jobhisto = "INSERT INTO JobHisto (" "JobId, Job, Name, Type, Level, ClientId, JobStatus, " "SchedTime, StartTime, EndTime, RealEndTime, JobTDate, " "VolSessionId, VolSessionTime, JobFiles, JobBytes, ReadBytes, " "JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, " "PurgedFiles, HasBase, Reviewed, Comment ) " "SELECT " "JobId, Job, Name, Type, Level, ClientId, JobStatus, " "SchedTime, StartTime, EndTime, RealEndTime, JobTDate, " "VolSessionId, VolSessionTime, JobFiles, JobBytes, ReadBytes, " "JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, " "PurgedFiles, HasBase, Reviewed, Comment " "FROM Job " "WHERE JobStatus IN ('T','W','f','A','E') " "AND NOT EXISTS " "(SELECT JobHisto.JobId " "FROM JobHisto WHERE JobHisto.Jobid=Job.JobId) " "AND JobTDate < %s "; /* For ua_update.c */ const char *list_pool = "SELECT * FROM Pool WHERE PoolId=%s"; /* For ua_dotcmds.c */ const char *client_backups = "SELECT DISTINCT Job.JobId,Client.Name as Client,Level,StartTime," "JobFiles,JobBytes,VolumeName,MediaType,FileSet,Media.Enabled as Enabled" " FROM Client,Job,JobMedia,Media,FileSet" " WHERE Client.Name='%s'" " AND FileSet='%s'" " AND Client.ClientId=Job.ClientId" " AND JobStatus IN ('T','W') AND Type='B'" " AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId" " AND Job.FileSetId=FileSet.FileSetId" " ORDER BY Job.StartTime"; /* ====== ua_prune.c */ const char *sel_JobMedia = "SELECT DISTINCT JobMedia.JobId FROM JobMedia,Job " "WHERE MediaId=%s AND Job.JobId=JobMedia.JobId " "AND Job.JobTDate<%s"; /* Delete temp tables and indexes */ const char *drop_deltabs[] = { "DROP TABLE DelCandidates", NULL}; const char *create_delindex = "CREATE INDEX DelInx1 ON DelCandidates (JobId)"; /* ======= ua_restore.c */ const char *uar_count_files = "SELECT JobFiles FROM Job WHERE JobId=%s"; /* List last 20 Jobs */ const char *uar_list_jobs = "SELECT JobId,Client.Name as Client,StartTime,Level as " "JobLevel,JobFiles,JobBytes " "FROM Client,Job WHERE Client.ClientId=Job.ClientId AND JobStatus IN ('T','W') " "AND Type='B' ORDER BY StartTime DESC LIMIT 20"; const char *uar_print_jobs = "SELECT DISTINCT JobId,Level,JobFiles,JobBytes,StartTime,VolumeName" " FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) " " WHERE JobId IN (%s) " " ORDER BY StartTime ASC"; /* * Find all files for a particular JobId and insert them into * the tree during a restore. */ const char *uar_sel_files = "SELECT Path.Path,Filename.Name,FileIndex,JobId,LStat " "FROM File,Filename,Path " "WHERE File.JobId IN (%s) AND Filename.FilenameId=File.FilenameId " "AND Path.PathId=File.PathId"; const char *uar_del_temp = "DROP TABLE temp"; const char *uar_del_temp1 = "DROP TABLE temp1"; const char *uar_last_full = "INSERT INTO temp1 SELECT Job.JobId,JobTdate " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.ClientId=%s " "AND Job.StartTime < '%s' " "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' " "AND JobMedia.JobId=Job.JobId " "AND Media.Enabled=1 " "AND JobMedia.MediaId=Media.MediaId " "AND Job.FileSetId=FileSet.FileSetId " "AND FileSet.FileSet='%s' " "%s" "ORDER BY Job.JobTDate DESC LIMIT 1"; const char *uar_last_full_no_pool = "INSERT INTO temp1 SELECT Job.JobId,JobTdate " "FROM Job,FileSet " "WHERE Job.ClientId=%s " "AND Job.StartTime < '%s' " "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' " "AND Job.FileSetId=FileSet.FileSetId " "AND FileSet.FileSet='%s' " "ORDER BY Job.JobTDate DESC LIMIT 1"; const char *uar_full = "INSERT INTO temp SELECT Job.JobId,Job.JobTDate," "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes," "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime " "FROM temp1,Job,JobMedia,Media " "WHERE temp1.JobId=Job.JobId " "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' " "AND Media.Enabled=1 " "AND JobMedia.JobId=Job.JobId " "AND JobMedia.MediaId=Media.MediaId"; const char *uar_dif = "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,Job.ClientId," "Job.Level,Job.JobFiles,Job.JobBytes," "Job.StartTime,Media.VolumeName,JobMedia.StartFile," "Job.VolSessionId,Job.VolSessionTime " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' " "AND Job.ClientId=%s " "AND JobMedia.JobId=Job.JobId " "AND Media.Enabled=1 " "AND JobMedia.MediaId=Media.MediaId " "AND Job.Level='D' AND JobStatus IN ('T','W') AND Type='B' " "AND Job.FileSetId=FileSet.FileSetId " "AND FileSet.FileSet='%s' " "%s" "ORDER BY Job.JobTDate DESC LIMIT 1"; const char *uar_inc = "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,Job.ClientId," "Job.Level,Job.JobFiles,Job.JobBytes," "Job.StartTime,Media.VolumeName,JobMedia.StartFile," "Job.VolSessionId,Job.VolSessionTime " "FROM Job,JobMedia,Media,FileSet " "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' " "AND Job.ClientId=%s " "AND Media.Enabled=1 " "AND JobMedia.JobId=Job.JobId " "AND JobMedia.MediaId=Media.MediaId " "AND Job.Level='I' AND JobStatus IN ('T','W') AND Type='B' " "AND Job.FileSetId=FileSet.FileSetId " "AND FileSet.FileSet='%s' " "%s"; const char *uar_list_temp = "SELECT DISTINCT JobId,Level,JobFiles,JobBytes,StartTime,VolumeName" " FROM temp" " ORDER BY StartTime ASC"; const char *uar_sel_jobid_temp = "SELECT DISTINCT JobId,StartTime FROM temp ORDER BY StartTime ASC"; const char *uar_sel_all_temp1 = "SELECT * FROM temp1"; const char *uar_sel_all_temp = "SELECT * FROM temp"; /* Select FileSet names for this Client */ const char *uar_sel_fileset = "SELECT DISTINCT FileSet.FileSet FROM Job," "Client,FileSet WHERE Job.FileSetId=FileSet.FileSetId " "AND Job.ClientId=%s AND Client.ClientId=%s " "ORDER BY FileSet.FileSet"; /* Select all different FileSet for this client * This query doesn't guarantee that the Id is the latest * version of the FileSet. Can be used with other queries that * use Ids to select the FileSet name. (like in accurate) */ const char *uar_sel_filesetid = "SELECT MAX(FileSet.FileSetId) " "FROM FileSet JOIN Job USING (FileSetId) " "WHERE Job.ClientId=%s " "GROUP BY FileSet"; /* * Find JobId, FileIndex for a given path/file and date * for use when inserting individual files into the tree. */ const char *uar_jobid_fileindex = "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " "WHERE Job.JobId=File.JobId " "AND Job.StartTime<='%s' " "AND Path.Path='%s' " "AND Filename.Name='%s' " "AND Client.Name='%s' " "AND Job.ClientId=Client.ClientId " "AND Path.PathId=File.PathId " "AND Filename.FilenameId=File.FilenameId " "AND JobStatus IN ('T','W') AND Type='B' " "ORDER BY Job.StartTime DESC LIMIT 1"; const char *uar_jobids_fileindex = "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " "WHERE Job.JobId IN (%s) " "AND Job.JobId=File.JobId " "AND Job.StartTime<='%s' " "AND Path.Path='%s' " "AND Filename.Name='%s' " "AND Client.Name='%s' " "AND Job.ClientId=Client.ClientId " "AND Path.PathId=File.PathId " "AND Filename.FilenameId=File.FilenameId " "ORDER BY Job.StartTime DESC LIMIT 1"; /* Query to get list of files from table -- presuably built by an external program */ const char *uar_jobid_fileindex_from_table = "SELECT JobId,FileIndex FROM %s ORDER BY JobId, FileIndex ASC"; /* Get the list of the last recent version per Delta with a given jobid list * This is a tricky part because with SQL the result of * * SELECT MAX(A), B, C, D FROM... GROUP BY (B,C) * * doesn't give the good result (for D). * * With PostgreSQL, we can use DISTINCT ON(), but with Mysql or Sqlite, * we need an extra join using JobTDate. */ static const char *select_recent_version_with_basejob_default = "SELECT FileId, Job.JobId AS JobId, FileIndex, File.PathId AS PathId, " "File.FilenameId AS FilenameId, LStat, MD5, DeltaSeq, " "Job.JobTDate AS JobTDate " "FROM Job, File, ( " "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId " "FROM ( " "SELECT JobTDate, PathId, FilenameId " /* Get all normal files */ "FROM File JOIN Job USING (JobId) " /* from selected backup */ "WHERE File.JobId IN (%s) " "UNION ALL " "SELECT JobTDate, PathId, FilenameId " /* Get all files from */ "FROM BaseFiles " /* BaseJob */ "JOIN File USING (FileId) " "JOIN Job ON (BaseJobId = Job.JobId) " "WHERE BaseFiles.JobId IN (%s) " /* Use Max(JobTDate) to find */ ") AS tmp " "GROUP BY PathId, FilenameId " /* the latest file version */ ") AS T1 " "WHERE (Job.JobId IN ( " /* Security, we force JobId to be valid */ "SELECT DISTINCT BaseJobId FROM BaseFiles WHERE JobId IN (%s)) " "OR Job.JobId IN (%s)) " "AND T1.JobTDate = Job.JobTDate " /* Join on JobTDate to get the orginal */ "AND Job.JobId = File.JobId " /* Job/File record */ "AND T1.PathId = File.PathId " "AND T1.FilenameId = File.FilenameId"; const char *select_recent_version_with_basejob[] = { /* MySQL */ select_recent_version_with_basejob_default, /* Postgresql */ /* The DISTINCT ON () permits to avoid extra join */ "SELECT DISTINCT ON (FilenameId, PathId) JobTDate, JobId, FileId, " "FileIndex, PathId, FilenameId, LStat, MD5, DeltaSeq " "FROM " "(SELECT FileId, JobId, PathId, FilenameId, FileIndex, LStat, MD5, DeltaSeq " "FROM File WHERE JobId IN (%s) " "UNION ALL " "SELECT File.FileId, File.JobId, PathId, FilenameId, " "File.FileIndex, LStat, MD5, DeltaSeq " "FROM BaseFiles JOIN File USING (FileId) " "WHERE BaseFiles.JobId IN (%s) " ") AS T JOIN Job USING (JobId) " "ORDER BY FilenameId, PathId, JobTDate DESC ", /* SQLite3 */ select_recent_version_with_basejob_default, /* Ingres */ select_recent_version_with_basejob_default }; /* We do the same thing than the previous query, but we include * all delta parts. If the file has been deleted, we can have irrelevant * parts. * * The code that uses results should control the delta sequence with * the following rules: * First Delta = 0 * Delta = Previous Delta + 1 * * If we detect a gap, we can discard further pieces * If a file starts at 1 instead of 0, the file has been deleted, and further * pieces are useless. * * This control should be reset for each new file */ static const char *select_recent_version_with_basejob_and_delta_default = "SELECT FileId, Job.JobId AS JobId, FileIndex, File.PathId AS PathId, " "File.FilenameId AS FilenameId, LStat, MD5, File.DeltaSeq AS DeltaSeq, " "Job.JobTDate AS JobTDate " "FROM Job, File, ( " "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId, DeltaSeq " "FROM ( " "SELECT JobTDate, PathId, FilenameId, DeltaSeq " /*Get all normal files*/ "FROM File JOIN Job USING (JobId) " /* from selected backup */ "WHERE File.JobId IN (%s) " "UNION ALL " "SELECT JobTDate, PathId, FilenameId, DeltaSeq " /*Get all files from */ "FROM BaseFiles " /* BaseJob */ "JOIN File USING (FileId) " "JOIN Job ON (BaseJobId = Job.JobId) " "WHERE BaseFiles.JobId IN (%s) " /* Use Max(JobTDate) to find */ ") AS tmp " "GROUP BY PathId, FilenameId, DeltaSeq " /* the latest file version */ ") AS T1 " "WHERE (Job.JobId IN ( " /* Security, we force JobId to be valid */ "SELECT DISTINCT BaseJobId FROM BaseFiles WHERE JobId IN (%s)) " "OR Job.JobId IN (%s)) " "AND T1.JobTDate = Job.JobTDate " /* Join on JobTDate to get the orginal */ "AND Job.JobId = File.JobId " /* Job/File record */ "AND T1.PathId = File.PathId " "AND T1.FilenameId = File.FilenameId"; const char *select_recent_version_with_basejob_and_delta[] = { /* MySQL */ select_recent_version_with_basejob_and_delta_default, /* Postgresql */ /* The DISTINCT ON () permits to avoid extra join */ "SELECT DISTINCT ON (FilenameId, PathId, DeltaSeq) JobTDate, JobId, FileId, " "FileIndex, PathId, FilenameId, LStat, MD5, DeltaSeq " "FROM " "(SELECT FileId, JobId, PathId, FilenameId, FileIndex, LStat, MD5,DeltaSeq " "FROM File WHERE JobId IN (%s) " "UNION ALL " "SELECT File.FileId, File.JobId, PathId, FilenameId, " "File.FileIndex, LStat, MD5, DeltaSeq " "FROM BaseFiles JOIN File USING (FileId) " "WHERE BaseFiles.JobId IN (%s) " ") AS T JOIN Job USING (JobId) " "ORDER BY FilenameId, PathId, DeltaSeq, JobTDate DESC ", /* SQLite3 */ select_recent_version_with_basejob_and_delta_default, /* Ingres */ select_recent_version_with_basejob_and_delta_default }; /* Get the list of the last recent version with a given BaseJob jobid list * We don't handle Delta with BaseJobs, they have only Full files */ static const char *select_recent_version_default = "SELECT j1.JobId AS JobId, f1.FileId AS FileId, f1.FileIndex AS FileIndex, " "f1.PathId AS PathId, f1.FilenameId AS FilenameId, " "f1.LStat AS LStat, f1.MD5 AS MD5, j1.JobTDate " "FROM ( " /* Choose the last version for each Path/Filename */ "SELECT max(JobTDate) AS JobTDate, PathId, FilenameId " "FROM File JOIN Job USING (JobId) " "WHERE File.JobId IN (%s) " "GROUP BY PathId, FilenameId " ") AS t1, Job AS j1, File AS f1 " "WHERE t1.JobTDate = j1.JobTDate " "AND j1.JobId IN (%s) " "AND t1.FilenameId = f1.FilenameId " "AND t1.PathId = f1.PathId " "AND j1.JobId = f1.JobId"; const char *select_recent_version[] = { /* MySQL */ select_recent_version_default, /* Postgresql */ "SELECT DISTINCT ON (FilenameId, PathId) JobTDate, JobId, FileId, " "FileIndex, PathId, FilenameId, LStat, MD5 " "FROM File JOIN Job USING (JobId) " "WHERE JobId IN (%s) " "ORDER BY FilenameId, PathId, JobTDate DESC ", /* SQLite3 */ select_recent_version_default, /* Ingres */ select_recent_version_default }; /* We don't create this table as TEMPORARY because MySQL MyISAM * 5.0 and 5.1 are unable to run further queries in this mode */ static const char *create_temp_accurate_jobids_default = "CREATE TABLE btemp3%s AS " "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles " "FROM Job JOIN FileSet USING (FileSetId) " "WHERE ClientId = %s " "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' " "AND StartTime<'%s' " "AND FileSet.FileSet=(SELECT FileSet FROM FileSet WHERE FileSetId = %s) " "ORDER BY Job.JobTDate DESC LIMIT 1"; const char *create_temp_accurate_jobids[] = { /* Mysql */ create_temp_accurate_jobids_default, /* Postgresql */ create_temp_accurate_jobids_default, /* SQLite3 */ create_temp_accurate_jobids_default, /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE btemp3%s AS " "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles " "FROM Job JOIN FileSet USING (FileSetId) " "WHERE ClientId = %s " "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' " "AND StartTime<'%s' " "AND FileSet.FileSet=(SELECT FileSet FROM FileSet WHERE FileSetId = %s) " "ORDER BY Job.JobTDate DESC FETCH FIRST 1 ROW ONLY " "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; const char *create_temp_basefile[] = { /* Mysql */ "CREATE TEMPORARY TABLE basefile%lld (" "Path BLOB NOT NULL," "Name BLOB NOT NULL," "INDEX (Path(255), Name(255)))", /* Postgresql */ "CREATE TEMPORARY TABLE basefile%lld (" "Path TEXT," "Name TEXT)", /* SQLite3 */ "CREATE TEMPORARY TABLE basefile%lld (" "Path TEXT," "Name TEXT)", /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE basefile%lld (" "Path VARBYTE(32000) NOT NULL," "Name VARBYTE(32000) NOT NULL) " "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; const char *create_temp_new_basefile[] = { /* Mysql */ "CREATE TEMPORARY TABLE new_basefile%lld AS " "SELECT Path.Path AS Path, Filename.Name AS Name, Temp.FileIndex AS FileIndex," "Temp.JobId AS JobId, Temp.LStat AS LStat, Temp.FileId AS FileId, " "Temp.MD5 AS MD5 " "FROM ( %s ) AS Temp " "JOIN Filename ON (Filename.FilenameId = Temp.FilenameId) " "JOIN Path ON (Path.PathId = Temp.PathId) " "WHERE Temp.FileIndex > 0", /* Postgresql */ "CREATE TEMPORARY TABLE new_basefile%lld AS " "SELECT Path.Path AS Path, Filename.Name AS Name, Temp.FileIndex AS FileIndex," "Temp.JobId AS JobId, Temp.LStat AS LStat, Temp.FileId AS FileId, " "Temp.MD5 AS MD5 " "FROM ( %s ) AS Temp " "JOIN Filename ON (Filename.FilenameId = Temp.FilenameId) " "JOIN Path ON (Path.PathId = Temp.PathId) " "WHERE Temp.FileIndex > 0", /* SQLite3 */ "CREATE TEMPORARY TABLE new_basefile%lld AS " "SELECT Path.Path AS Path, Filename.Name AS Name, Temp.FileIndex AS FileIndex," "Temp.JobId AS JobId, Temp.LStat AS LStat, Temp.FileId AS FileId, " "Temp.MD5 AS MD5 " "FROM ( %s ) AS Temp " "JOIN Filename ON (Filename.FilenameId = Temp.FilenameId) " "JOIN Path ON (Path.PathId = Temp.PathId) " "WHERE Temp.FileIndex > 0", /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE new_basefile%lld AS " "SELECT Path.Path AS Path, Filename.Name AS Name, Temp.FileIndex AS FileIndex," "Temp.JobId AS JobId, Temp.LStat AS LStat, Temp.FileId AS FileId, " "Temp.MD5 AS MD5 " "FROM ( %s ) AS Temp " "JOIN Filename ON (Filename.FilenameId = Temp.FilenameId) " "JOIN Path ON (Path.PathId = Temp.PathId) " "WHERE Temp.FileIndex > 0 " "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; /* ====== ua_prune.c */ /* List of SQL commands to create temp table and indicies */ const char *create_deltabs[] = { /* MySQL */ "CREATE TEMPORARY TABLE DelCandidates (" "JobId INTEGER UNSIGNED NOT NULL, " "PurgedFiles TINYINT, " "FileSetId INTEGER UNSIGNED, " "JobFiles INTEGER UNSIGNED, " "JobStatus BINARY(1))", /* Postgresql */ "CREATE TEMPORARY TABLE DelCandidates (" "JobId INTEGER NOT NULL, " "PurgedFiles SMALLINT, " "FileSetId INTEGER, " "JobFiles INTEGER, " "JobStatus char(1))", /* SQLite3 */ "CREATE TEMPORARY TABLE DelCandidates (" "JobId INTEGER UNSIGNED NOT NULL, " "PurgedFiles TINYINT, " "FileSetId INTEGER UNSIGNED, " "JobFiles INTEGER UNSIGNED, " "JobStatus CHAR)", /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE DelCandidates (" "JobId INTEGER NOT NULL, " "PurgedFiles SMALLINT, " "FileSetId INTEGER, " "JobFiles INTEGER, " "JobStatus CHAR(1)) " "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; /* ======= ua_purge.c */ /* Select the first available Copy Job that must be upgraded to a Backup job when the original backup job is expired. */ static const char *uap_upgrade_copies_oldest_job_default = "CREATE TEMPORARY TABLE cpy_tmp AS " "SELECT MIN(JobId) AS JobId FROM Job " /* Choose the oldest job */ "WHERE Type='%c' " /* JT_JOB_COPY */ "AND ( PriorJobId IN (%s) " /* JobId selection */ "OR " " PriorJobId IN ( " "SELECT PriorJobId " "FROM Job " "WHERE JobId IN (%s) " /* JobId selection */ " AND Type='B' " ") " ") " "GROUP BY PriorJobId "; /* one result per copy */ const char *uap_upgrade_copies_oldest_job[] = { /* Mysql */ uap_upgrade_copies_oldest_job_default, /* Postgresql */ uap_upgrade_copies_oldest_job_default, /* SQLite3 */ uap_upgrade_copies_oldest_job_default, /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE cpy_tmp AS " "SELECT MIN(JobId) AS JobId FROM Job " /* Choose the oldest job */ "WHERE Type='%c' " /* JT_JOB_COPY */ "AND ( PriorJobId IN (%s) " /* JobId selection */ "OR " " PriorJobId IN ( " "SELECT PriorJobId " "FROM Job " "WHERE JobId IN (%s) " /* JobId selection */ " AND Type='B' " ") " ") " "GROUP BY PriorJobId " /* one result per copy */ "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; /* ======= ua_restore.c */ /* List Jobs where a particular file is saved */ const char *uar_file[] = { /* Mysql */ "SELECT Job.JobId as JobId," "CONCAT(Path.Path,Filename.Name) as Name, " "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes " "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' " "AND Client.ClientId=Job.ClientId " "AND Job.JobId=File.JobId AND File.FileIndex > 0 " "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId " "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20", /* Postgresql */ "SELECT Job.JobId as JobId," "Path.Path||Filename.Name as Name, " "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes " "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' " "AND Client.ClientId=Job.ClientId " "AND Job.JobId=File.JobId AND File.FileIndex > 0 " "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId " "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20", /* SQLite3 */ "SELECT Job.JobId as JobId," "Path.Path||Filename.Name as Name, " "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes " "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' " "AND Client.ClientId=Job.ClientId " "AND Job.JobId=File.JobId AND File.FileIndex > 0 " "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId " "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20", /* Ingres */ "SELECT Job.JobId as JobId," "Path.Path||Filename.Name as Name, " "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes " "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' " "AND Client.ClientId=Job.ClientId " "AND Job.JobId=File.JobId AND File.FileIndex > 0 " "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId " "AND Filename.Name='%s' ORDER BY StartTime DESC FETCH FIRST 20 ROWS ONLY" }; const char *uar_create_temp[] = { /* Mysql */ "CREATE TEMPORARY TABLE temp (" "JobId INTEGER UNSIGNED NOT NULL," "JobTDate BIGINT UNSIGNED," "ClientId INTEGER UNSIGNED," "Level CHAR," "JobFiles INTEGER UNSIGNED," "JobBytes BIGINT UNSIGNED," "StartTime TEXT," "VolumeName TEXT," "StartFile INTEGER UNSIGNED," "VolSessionId INTEGER UNSIGNED," "VolSessionTime INTEGER UNSIGNED)", /* Postgresql */ "CREATE TEMPORARY TABLE temp (" "JobId INTEGER NOT NULL," "JobTDate BIGINT," "ClientId INTEGER," "Level CHAR," "JobFiles INTEGER," "JobBytes BIGINT," "StartTime TEXT," "VolumeName TEXT," "StartFile INTEGER," "VolSessionId INTEGER," "VolSessionTime INTEGER)", /* SQLite3 */ "CREATE TEMPORARY TABLE temp (" "JobId INTEGER UNSIGNED NOT NULL," "JobTDate BIGINT UNSIGNED," "ClientId INTEGER UNSIGNED," "Level CHAR," "JobFiles INTEGER UNSIGNED," "JobBytes BIGINT UNSIGNED," "StartTime TEXT," "VolumeName TEXT," "StartFile INTEGER UNSIGNED," "VolSessionId INTEGER UNSIGNED," "VolSessionTime INTEGER UNSIGNED)", /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE temp (" "JobId INTEGER NOT NULL," "JobTDate BIGINT," "ClientId INTEGER," "Level CHAR(1)," "JobFiles INTEGER," "JobBytes BIGINT," "StartTime TIMESTAMP WITHOUT TIME ZONE," "VolumeName VARBYTE(128)," "StartFile INTEGER," "VolSessionId INTEGER," "VolSessionTime INTEGER) " "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; const char *uar_create_temp1[] = { /* Mysql */ "CREATE TEMPORARY TABLE temp1 (" "JobId INTEGER UNSIGNED NOT NULL," "JobTDate BIGINT UNSIGNED)", /* Postgresql */ "CREATE TEMPORARY TABLE temp1 (" "JobId INTEGER NOT NULL," "JobTDate BIGINT)", /* SQLite3 */ "CREATE TEMPORARY TABLE temp1 (" "JobId INTEGER UNSIGNED NOT NULL," "JobTDate BIGINT UNSIGNED)", /* Ingres */ "DECLARE GLOBAL TEMPORARY TABLE temp1 (" "JobId INTEGER NOT NULL," "JobTDate BIGINT) " "ON COMMIT PRESERVE ROWS WITH NORECOVERY" }; /* Query to get all files in a directory -- no recursing * Note, for PostgreSQL since it respects the "Single Value * rule", the results of the SELECT will be unoptimized. * I.e. the same file will be restored multiple times, once * for each time it was backed up. */ const char *uar_jobid_fileindex_from_dir[] = { /* Mysql */ "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " "WHERE Job.JobId IN (%s) " "AND Job.JobId=File.JobId " "AND Path.Path='%s' " "AND Client.Name='%s' " "AND Job.ClientId=Client.ClientId " "AND Path.PathId=File.Pathid " "AND Filename.FilenameId=File.FilenameId " "GROUP BY File.FileIndex ", /* Postgresql */ "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " "WHERE Job.JobId IN (%s) " "AND Job.JobId=File.JobId " "AND Path.Path='%s' " "AND Client.Name='%s' " "AND Job.ClientId=Client.ClientId " "AND Path.PathId=File.Pathid " "AND Filename.FilenameId=File.FilenameId", /* SQLite3 */ "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " "WHERE Job.JobId IN (%s) " "AND Job.JobId=File.JobId " "AND Path.Path='%s' " "AND Client.Name='%s' " "AND Job.ClientId=Client.ClientId " "AND Path.PathId=File.Pathid " "AND Filename.FilenameId=File.FilenameId " "GROUP BY File.FileIndex ", /* Ingres */ "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Filename,Client " "WHERE Job.JobId IN (%s) " "AND Job.JobId=File.JobId " "AND Path.Path='%s' " "AND Client.Name='%s' " "AND Job.ClientId=Client.ClientId " "AND Path.PathId=File.Pathid " "AND Filename.FilenameId=File.FilenameId" }; const char *sql_media_order_most_recently_written[] = { /* Mysql */ "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId", /* Postgresql */ "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId", /* SQLite3 */ "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId", /* Ingres */ "ORDER BY IFNULL(LastWritten, '1970-01-01 00:00:00') DESC,MediaId" }; const char *sql_get_max_connections[] = { /* Mysql */ "SHOW VARIABLES LIKE 'max_connections'", /* Postgresql */ "SHOW max_connections", /* SQLite3 */ "SELECT 0", /* Ingres (TODO) */ "SELECT 0" }; /* * The Group By can return strange numbers when having multiple * version of a file in the same dataset. */ const char *default_sql_bvfs_select = "CREATE TABLE %s AS " "SELECT File.JobId, File.FileIndex, File.FileId " "FROM Job, File, ( " "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId " "FROM btemp%s GROUP BY PathId, FilenameId " ") AS T1 JOIN Filename USING (FilenameId) " "WHERE T1.JobTDate = Job.JobTDate " "AND Job.JobId = File.JobId " "AND T1.PathId = File.PathId " "AND T1.FilenameId = File.FilenameId " "AND File.FileIndex > 0 " "AND Job.JobId IN (SELECT DISTINCT JobId FROM btemp%s) "; const char *sql_bvfs_select[] = { /* Mysql */ default_sql_bvfs_select, /* Postgresql */ "CREATE TABLE %s AS ( " "SELECT JobId, FileIndex, FileId " "FROM ( " "SELECT DISTINCT ON (PathId, FilenameId) " "JobId, FileIndex, FileId " "FROM btemp%s " "ORDER BY PathId, FilenameId, JobTDate DESC " ") AS T " "WHERE FileIndex > 0)", /* SQLite3 */ default_sql_bvfs_select, /* Ingres (TODO) */ "SELECT 0" }; static const char *sql_bvfs_list_files_default = "SELECT 'F', T1.PathId, T1.FilenameId, Filename.Name, " "File.JobId, File.LStat, File.FileId " "FROM Job, File, ( " "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId " "FROM ( " "SELECT JobTDate, PathId, FilenameId " "FROM File JOIN Job USING (JobId) " "WHERE File.JobId IN (%s) AND PathId = %s " "UNION ALL " "SELECT JobTDate, PathId, FilenameId " "FROM BaseFiles " "JOIN File USING (FileId) " "JOIN Job ON (BaseJobId = Job.JobId) " "WHERE BaseFiles.JobId IN (%s) AND PathId = %s " ") AS tmp GROUP BY PathId, FilenameId " "LIMIT %lld OFFSET %lld" ") AS T1 JOIN Filename USING (FilenameId) " "WHERE T1.JobTDate = Job.JobTDate " "AND Job.JobId = File.JobId " "AND T1.PathId = File.PathId " "AND T1.FilenameId = File.FilenameId " "AND Filename.Name != '' " "AND File.FileIndex > 0 " " %s " /* AND Name LIKE '' */ "AND (Job.JobId IN ( " "SELECT DISTINCT BaseJobId FROM BaseFiles WHERE JobId IN (%s)) " "OR Job.JobId IN (%s)) "; const char *sql_bvfs_list_files[] = { /* Mysql */ /* JobId PathId JobId PathId Limit Offset AND? Filename? JobId JobId*/ sql_bvfs_list_files_default, /* JobId PathId JobId PathId WHERE? Filename? Limit Offset*/ /* Postgresql */ "SELECT Type, PathId, FilenameId, Name, JobId, LStat, FileId " "FROM (" "SELECT DISTINCT ON (FilenameId) 'F' as Type, PathId, T.FilenameId, " "Filename.Name, JobId, LStat, FileId, FileIndex " "FROM " "(SELECT FileId, JobId, PathId, FilenameId, FileIndex, LStat, MD5 " "FROM File WHERE JobId IN (%s) AND PathId = %s " "UNION ALL " "SELECT File.FileId, File.JobId, PathId, FilenameId, " "File.FileIndex, LStat, MD5 " "FROM BaseFiles JOIN File USING (FileId) " "WHERE BaseFiles.JobId IN (%s) AND File.PathId = %s " ") AS T JOIN Job USING (JobId) JOIN Filename USING (FilenameId) " " WHERE Filename.Name != '' " " %s " /* AND Name LIKE '' */ "ORDER BY FilenameId, StartTime DESC " ") AS A WHERE A.FileIndex > 0 " "LIMIT %lld OFFSET %lld ", /* SQLite */ sql_bvfs_list_files_default, /* SQLite3 */ sql_bvfs_list_files_default, /* Ingres (TODO) */ sql_bvfs_list_files_default }; const char *batch_lock_path_query[] = { /* Mysql */ "LOCK TABLES Path write, batch write, Path as p write", /* Postgresql */ "BEGIN; LOCK TABLE Path IN SHARE ROW EXCLUSIVE MODE", /* SQLite3 */ "BEGIN", /* Ingres */ "BEGIN" }; const char *batch_lock_filename_query[] = { /* Mysql */ "LOCK TABLES Filename write, batch write, Filename as f write", /* Postgresql */ "BEGIN; LOCK TABLE Filename IN SHARE ROW EXCLUSIVE MODE", /* SQLite3 */ "BEGIN", /* Ingres */ "BEGIN" }; const char *batch_unlock_tables_query[] = { /* Mysql */ "UNLOCK TABLES", /* Postgresql */ "COMMIT", /* SQLite3 */ "COMMIT", /* Ingres */ "COMMIT" }; const char *batch_fill_path_query[] = { /* Mysql */ "INSERT INTO Path (Path) " "SELECT a.Path FROM " "(SELECT DISTINCT Path FROM batch) AS a WHERE NOT EXISTS " "(SELECT Path FROM Path AS p WHERE p.Path = a.Path)", /* Postgresql */ "INSERT INTO Path (Path) " "SELECT a.Path FROM " "(SELECT DISTINCT Path FROM batch) AS a " "WHERE NOT EXISTS (SELECT Path FROM Path WHERE Path = a.Path) ", /* SQLite3 */ "INSERT INTO Path (Path) " "SELECT DISTINCT Path FROM batch " "EXCEPT SELECT Path FROM Path", /* Ingres */ "INSERT INTO Path (Path) " "SELECT DISTINCT b.Path FROM batch b " "WHERE NOT EXISTS (SELECT Path FROM Path p WHERE p.Path = b.Path)" }; const char *batch_fill_filename_query[] = { /* Mysql */ "INSERT INTO Filename (Name) " "SELECT a.Name FROM " "(SELECT DISTINCT Name FROM batch) AS a WHERE NOT EXISTS " "(SELECT Name FROM Filename AS f WHERE f.Name = a.Name)", /* Postgresql */ "INSERT INTO Filename (Name) " "SELECT a.Name FROM " "(SELECT DISTINCT Name FROM batch) as a " "WHERE NOT EXISTS " "(SELECT Name FROM Filename WHERE Name = a.Name)", /* SQLite3 */ "INSERT INTO Filename (Name) " "SELECT DISTINCT Name FROM batch " "EXCEPT SELECT Name FROM Filename", /* Ingres */ "INSERT INTO Filename (Name) " "SELECT DISTINCT b.Name FROM batch b " "WHERE NOT EXISTS (SELECT Name FROM Filename f WHERE f.Name = b.Name)" }; const char *match_query[] = { /* Mysql */ "REGEXP", /* Postgresql */ "~", /* SQLite3 */ "LIKE", /* MATCH doesn't seems to work anymore... */ /* Ingres */ "~" }; static const char *insert_counter_values_default = "INSERT INTO Counters (Counter, MinValue, " "MaxValue, CurrentValue, WrapCounter) " "VALUES ('%s','%d','%d','%d','%s')"; const char *insert_counter_values[] = { /* Mysql */ "INSERT INTO Counters (Counter, Counters.MinValue, " "Counters.MaxValue, CurrentValue, WrapCounter) " "VALUES ('%s','%d','%d','%d','%s')", /* Postgresql */ insert_counter_values_default, /* SQLite3 */ insert_counter_values_default, /* Ingres */ insert_counter_values_default }; static const char *select_counter_values_default = "SELECT MinValue, MaxValue, CurrentValue, WrapCounter " "FROM Counters WHERE Counter='%s'"; const char *select_counter_values[] = { /* Mysql */ "SELECT Counters.MinValue, Counters.MaxValue, CurrentValue, WrapCounter " "FROM Counters WHERE Counter='%s'", /* Postgresql */ select_counter_values_default, /* SQLite3 */ select_counter_values_default, /* Ingres */ select_counter_values_default }; static const char *update_counter_values_default = "UPDATE Counters SET " "MinValue=%d, MaxValue=%d, CurrentValue=%d, WrapCounter='%s'" "WHERE Counter='%s'"; const char *update_counter_values[] = { /* Mysql */ "UPDATE Counters SET " "Counters.MinValue=%d, Counters.MaxValue=%d, CurrentValue=%d, WrapCounter='%s'" "WHERE Counter='%s'", /* Postgresql */ update_counter_values_default, /* SQLite3 */ update_counter_values_default, /* Ingres */ update_counter_values_default }; static const char *get_quota_jobbytes_default = "SELECT SUM(JobBytes) " "FROM Job " "WHERE ClientId = %s " "AND JobId != %s " "AND SchedTime > '%s'"; const char *get_quota_jobbytes[] = { /* Mysql */ get_quota_jobbytes_default, /* Postgresql */ "SELECT SUM(JobBytes) " "FROM Job " "WHERE ClientId = %s " "AND JobId != %s " "AND SchedTime > TIMESTAMP '%s'", /* SQLite3 */ get_quota_jobbytes_default, /* Ingres */ get_quota_jobbytes_default }; static const char *get_quota_jobbytes_nofailed_default = "SELECT SUM(JobBytes) " "FROM Job " "WHERE ClientId = %s " "AND Job.JobId != %s " "AND SchedTime > '%s' " "AND JobStatus NOT IN ('E','f','A')"; const char *get_quota_jobbytes_nofailed[] = { /* Mysql */ get_quota_jobbytes_nofailed_default, /* Postgresql */ "SELECT SUM(JobBytes) " "FROM Job " "WHERE ClientId = %s " "AND Job.JobId != %s " "AND SchedTime > TIMESTAMP '%s' " "AND JobStatus NOT IN ('E','f','A')", /* SQLite3 */ get_quota_jobbytes_nofailed_default, /* Ingres */ get_quota_jobbytes_nofailed_default }; bareos-Release-14.2.6/src/cats/sql_cmds.h000066400000000000000000000100421263011562700201340ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ extern const char CATS_IMP_EXP *get_restore_objects; extern const char CATS_IMP_EXP *fill_jobhisto; extern const char CATS_IMP_EXP *client_backups; extern const char CATS_IMP_EXP *list_pool; extern const char CATS_IMP_EXP *drop_deltabs[]; extern const char CATS_IMP_EXP *create_delindex; extern const char CATS_IMP_EXP *cnt_File; extern const char CATS_IMP_EXP *del_MAC; extern const char CATS_IMP_EXP *sel_JobMedia; extern const char CATS_IMP_EXP *cleanup_created_job; extern const char CATS_IMP_EXP *cleanup_running_job; extern const char CATS_IMP_EXP *uar_list_jobs; extern const char CATS_IMP_EXP *uar_print_jobs; extern const char CATS_IMP_EXP *uar_count_files; extern const char CATS_IMP_EXP *uar_sel_files; extern const char CATS_IMP_EXP *uar_del_temp; extern const char CATS_IMP_EXP *uar_del_temp1; extern const char CATS_IMP_EXP *uar_last_full; extern const char CATS_IMP_EXP *uar_last_full_no_pool; extern const char CATS_IMP_EXP *uar_full; extern const char CATS_IMP_EXP *uar_inc; extern const char CATS_IMP_EXP *uar_list_temp; extern const char CATS_IMP_EXP *uar_sel_all_temp1; extern const char CATS_IMP_EXP *uar_sel_fileset; extern const char CATS_IMP_EXP *uar_sel_filesetid; extern const char CATS_IMP_EXP *uar_mediatype; extern const char CATS_IMP_EXP *uar_jobid_fileindex; extern const char CATS_IMP_EXP *uar_dif; extern const char CATS_IMP_EXP *uar_sel_all_temp; extern const char CATS_IMP_EXP *uar_count_files; extern const char CATS_IMP_EXP *uar_jobids_fileindex; extern const char CATS_IMP_EXP *uar_jobid_fileindex_from_table; extern const char CATS_IMP_EXP *uar_sel_jobid_temp; extern const char CATS_IMP_EXP *select_recent_version[]; extern const char CATS_IMP_EXP *select_recent_version_with_basejob[]; extern const char CATS_IMP_EXP *select_recent_version_with_basejob_and_delta[]; extern const char CATS_IMP_EXP *create_temp_accurate_jobids[]; extern const char CATS_IMP_EXP *create_temp_basefile[]; extern const char CATS_IMP_EXP *create_temp_new_basefile[]; extern const char CATS_IMP_EXP *create_deltabs[]; extern const char CATS_IMP_EXP *uap_upgrade_copies_oldest_job[]; extern const char CATS_IMP_EXP *uar_file[]; extern const char CATS_IMP_EXP *uar_create_temp[]; extern const char CATS_IMP_EXP *uar_create_temp1[]; extern const char CATS_IMP_EXP *uar_jobid_fileindex_from_dir[]; extern const char CATS_IMP_EXP *sql_media_order_most_recently_written[]; extern const char CATS_IMP_EXP *sql_get_max_connections[]; extern const char CATS_IMP_EXP *sql_bvfs_select[]; extern const char CATS_IMP_EXP *sql_bvfs_list_files[]; extern const char CATS_IMP_EXP *batch_lock_path_query[]; extern const char CATS_IMP_EXP *batch_lock_filename_query[]; extern const char CATS_IMP_EXP *batch_unlock_tables_query[]; extern const char CATS_IMP_EXP *batch_fill_path_query[]; extern const char CATS_IMP_EXP *batch_fill_filename_query[]; extern const char CATS_IMP_EXP *match_query[]; extern const char CATS_IMP_EXP *insert_counter_values[]; extern const char CATS_IMP_EXP *select_counter_values[]; extern const char CATS_IMP_EXP *update_counter_values[]; extern const char CATS_IMP_EXP *get_quota_jobbytes[]; extern const char CATS_IMP_EXP *get_quota_jobbytes_nofailed[]; bareos-Release-14.2.6/src/cats/sql_create.c000066400000000000000000001337361263011562700204640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database Create record interface routines * * Kern Sibbald, March 2000 */ #include "bareos.h" static const int dbglevel = 100; #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* * Forward referenced subroutines */ static bool db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); static bool db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); /** * Create a new record for the Job * Returns: false on failure * true on success */ bool db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { bool retval = false;; POOL_MEM buf; char dt[MAX_TIME_LENGTH]; time_t stime; int len; utime_t JobTDate; char ed1[30], ed2[30]; char esc_job[MAX_ESCAPE_NAME_LENGTH]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); stime = jr->SchedTime; ASSERT(stime != 0); bstrutime(dt, sizeof(dt), stime); JobTDate = (utime_t)stime; len = strlen(jcr->comment); /* TODO: use jr instead of jcr to get comment */ buf.check_size(len*2+1); mdb->db_escape_string(jcr, buf.c_str(), jcr->comment, len); mdb->db_escape_string(jcr, esc_job, jr->Job, strlen(jr->Job)); mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name)); /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate," "ClientId,Comment) " "VALUES ('%s','%s','%c','%c','%c','%s',%s,%s,'%s')", esc_job, esc_name, (char)(jr->JobType), (char)(jr->JobLevel), (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1), edit_int64(jr->ClientId, ed2), buf.c_str()); jr->JobId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Job")); if (jr->JobId == 0) { Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); } else { retval = true; } db_unlock(mdb); return retval; } /** * Create a JobMedia record for medium used this job * Returns: false on failure * true on success */ bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm) { bool retval = false; int count; char ed1[50], ed2[50]; db_lock(mdb); /* * Now get count for VolIndex */ Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s", edit_int64(jm->JobId, ed1)); count = get_sql_record_max(jcr, mdb); if (count < 0) { count = 0; } count++; Mmsg(mdb->cmd, "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex," "StartFile,EndFile,StartBlock,EndBlock,VolIndex) " "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u)", edit_int64(jm->JobId, ed1), edit_int64(jm->MediaId, ed2), jm->FirstIndex, jm->LastIndex, jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count); Dmsg0(300, mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); } else { /* * Worked, now update the Media record with the EndFile and EndBlock */ Mmsg(mdb->cmd, "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u", jm->EndFile, jm->EndBlock, jm->MediaId); if (!UPDATE_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); } else { retval = true; } } db_unlock(mdb); Dmsg0(300, "Return from JobMedia\n"); return retval; } /** * Create Unique Pool record * Returns: false on failure * true on success */ bool db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) { bool retval = false; char ed1[30], ed2[30], ed3[50], ed4[50], ed5[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; char esc_lf[MAX_ESCAPE_NAME_LENGTH]; int num_rows; Dmsg0(200, "In create pool\n"); db_lock(mdb); mdb->db_escape_string(jcr, esc_name, pr->Name, strlen(pr->Name)); mdb->db_escape_string(jcr, esc_lf, pr->LabelFormat, strlen(pr->LabelFormat)); Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", esc_name); Dmsg1(200, "selectpool: %s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 0) { Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name); sql_free_result(mdb); goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog," "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration," "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat," "RecyclePoolId,ScratchPoolId,ActionOnPurge,MinBlocksize,MaxBlocksize) " "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s',%s,%s,%d,%d,%d)", esc_name, pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog, pr->AcceptAnyVolume, pr->AutoPrune, pr->Recycle, edit_uint64(pr->VolRetention, ed1), edit_uint64(pr->VolUseDuration, ed2), pr->MaxVolJobs, pr->MaxVolFiles, edit_uint64(pr->MaxVolBytes, ed3), pr->PoolType, pr->LabelType, esc_lf, edit_int64(pr->RecyclePoolId,ed4), edit_int64(pr->ScratchPoolId,ed5), pr->ActionOnPurge, pr->MinBlocksize, pr->MaxBlocksize); Dmsg1(200, "Create Pool: %s\n", mdb->cmd); pr->PoolId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Pool")); if (pr->PoolId == 0) { Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); } else { retval = true; } bail_out: db_unlock(mdb); Dmsg0(500, "Create Pool: done\n"); return retval; } /** * Create Unique Device record * Returns: false on failure * true on success */ bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr) { bool retval = false; SQL_ROW row; char ed1[30], ed2[30]; char esc[MAX_ESCAPE_NAME_LENGTH]; int num_rows; Dmsg0(200, "In create Device\n"); db_lock(mdb); mdb->db_escape_string(jcr, esc, dr->Name, strlen(dr->Name)); Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s' AND StorageId = %s", esc, edit_int64(dr->StorageId, ed1)); Dmsg1(200, "selectdevice: %s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); /* * If more than one, report error, but return first row */ if (num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Device!: %d\n"), num_rows); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching Device row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); goto bail_out; } dr->DeviceId = str_to_int64(row[0]); if (row[1]) { bstrncpy(dr->Name, row[1], sizeof(dr->Name)); } else { dr->Name[0] = 0; /* no name */ } sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)", esc, edit_uint64(dr->MediaTypeId, ed1), edit_int64(dr->StorageId, ed2)); Dmsg1(200, "Create Device: %s\n", mdb->cmd); dr->DeviceId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Device")); if (dr->DeviceId == 0) { Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a Unique record for Storage -- no duplicates * Returns: false on failure * true on success with id in sr->StorageId */ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) { SQL_ROW row; bool retval = false; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, sr->Name, strlen(sr->Name)); Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", esc); sr->StorageId = 0; sr->created = false; /* * Check if it already exists */ if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); /* * If more than one, report error, but return first row */ if (num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), num_rows); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); goto bail_out; } sr->StorageId = str_to_int64(row[0]); sr->AutoChanger = atoi(row[1]); /* bool */ sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)" " VALUES ('%s',%d)", esc, sr->AutoChanger); sr->StorageId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Storage")); if (sr->StorageId == 0) { Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { sr->created = true; retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create Unique MediaType record * Returns: false on failure * true on success */ bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr) { bool retval = false; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; Dmsg0(200, "In create mediatype\n"); db_lock(mdb); mdb->db_escape_string(jcr, esc, mr->MediaType, strlen(mr->MediaType)); Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", esc); Dmsg1(200, "selectmediatype: %s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 0) { Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType); sql_free_result(mdb); goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO MediaType (MediaType,ReadOnly) " "VALUES ('%s',%d)", mr->MediaType, mr->ReadOnly); Dmsg1(200, "Create mediatype: %s\n", mdb->cmd); mr->MediaTypeId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("MediaType")); if (mr->MediaTypeId == 0) { Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); goto bail_out; } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create Media record. VolumeName and non-zero Slot must be unique * Returns: false on failure * true on success with id in mr->MediaId */ bool db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { bool retval = false; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50]; char ed9[50], ed10[50], ed11[50], ed12[50]; int num_rows; char esc_name[MAX_ESCAPE_NAME_LENGTH]; char esc_mtype[MAX_ESCAPE_NAME_LENGTH]; char esc_status[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc_name, mr->VolumeName, strlen(mr->VolumeName)); mdb->db_escape_string(jcr, esc_mtype, mr->MediaType, strlen(mr->MediaType)); mdb->db_escape_string(jcr, esc_status, mr->VolStatus, strlen(mr->VolStatus)); Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'", esc_name); Dmsg1(500, "selectpool: %s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 0) { Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName); sql_free_result(mdb); goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes," "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime," "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId," "ScratchPoolId,RecyclePoolId,Enabled,ActionOnPurge,EncryptionKey," "MinBlocksize,MaxBlocksize) " "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,0,0,%d,%s," "%s,%s,%s,%s,%d,%d,'%s',%d,%d)", esc_name, esc_mtype, mr->PoolId, edit_uint64(mr->MaxVolBytes,ed1), edit_uint64(mr->VolCapacityBytes, ed2), mr->Recycle, edit_uint64(mr->VolRetention, ed3), edit_uint64(mr->VolUseDuration, ed4), mr->MaxVolJobs, mr->MaxVolFiles, esc_status, mr->Slot, edit_uint64(mr->VolBytes, ed5), mr->InChanger, edit_int64(mr->VolReadTime, ed6), edit_int64(mr->VolWriteTime, ed7), mr->LabelType, edit_int64(mr->StorageId, ed8), edit_int64(mr->DeviceId, ed9), edit_int64(mr->LocationId, ed10), edit_int64(mr->ScratchPoolId, ed11), edit_int64(mr->RecyclePoolId, ed12), mr->Enabled, mr->ActionOnPurge, mr->EncrKey, mr->MinBlocksize, mr->MaxBlocksize); Dmsg1(500, "Create Volume: %s\n", mdb->cmd); mr->MediaId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Media")); if (mr->MediaId == 0) { Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); } else { retval = true; if (mr->set_label_date) { char dt[MAX_TIME_LENGTH]; if (mr->LabelDate == 0) { mr->LabelDate = time(NULL); } bstrutime(dt, sizeof(dt), mr->LabelDate); Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' " "WHERE MediaId=%d", dt, mr->MediaId); retval = UPDATE_DB(jcr, mdb, mdb->cmd); } /* * Make sure that if InChanger is non-zero any other identical slot * has InChanger zero. */ db_make_inchanger_unique(jcr, mdb, mr); } bail_out: db_unlock(mdb); return retval; } /** * Create a Unique record for the client -- no duplicates * Returns: false on failure * true on success with id in cr->ClientId */ bool db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) { bool retval = false; SQL_ROW row; char ed1[50], ed2[50]; int num_rows; char esc_name[MAX_ESCAPE_NAME_LENGTH]; char esc_uname[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc_name, cr->Name, strlen(cr->Name)); mdb->db_escape_string(jcr, esc_uname, cr->Uname, strlen(cr->Uname)); Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", esc_name); cr->ClientId = 0; if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); /* * If more than one, report error, but return first row */ if (num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), num_rows); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); goto bail_out; } cr->ClientId = str_to_int64(row[0]); if (row[1]) { bstrncpy(cr->Uname, row[1], sizeof(cr->Uname)); } else { cr->Uname[0] = 0; /* no name */ } sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune," "FileRetention,JobRetention) VALUES " "('%s','%s',%d,%s,%s)", esc_name, esc_uname, cr->AutoPrune, edit_uint64(cr->FileRetention, ed1), edit_uint64(cr->JobRetention, ed2)); cr->ClientId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Client")); if (cr->ClientId == 0) { Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a Unique record for the Path -- no duplicates * Returns: false on failure * true on success with id in cr->ClientId */ bool db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { bool retval = false; SQL_ROW row; int num_rows; mdb->errmsg[0] = 0; mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2); db_escape_string(jcr, mdb, mdb->esc_name, mdb->path, mdb->pnl); if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl && bstrcmp(mdb->cached_path, mdb->path)) { ar->PathId = mdb->cached_path_id; return true; } Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 1) { char ed1[30]; Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"), edit_uint64(num_rows, ed1), mdb->path); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } /* * Even if there are multiple paths, take the first one */ if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); ar->PathId = 0; ASSERT(ar->PathId); goto bail_out; } ar->PathId = str_to_int64(row[0]); sql_free_result(mdb); /* * Cache path */ if (ar->PathId != mdb->cached_path_id) { mdb->cached_path_id = ar->PathId; mdb->cached_path_len = mdb->pnl; pm_strcpy(mdb->cached_path, mdb->path); } ASSERT(ar->PathId); retval = true; goto bail_out; } sql_free_result(mdb); } Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name); ar->PathId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Path")); if (ar->PathId == 0) { Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); ar->PathId = 0; goto bail_out; } /* * Cache path */ if (ar->PathId != mdb->cached_path_id) { mdb->cached_path_id = ar->PathId; mdb->cached_path_len = mdb->pnl; pm_strcpy(mdb->cached_path, mdb->path); } retval = true; bail_out: return retval; } /** * Create a Unique record for the counter -- no duplicates * Returns: false on failure * true on success with counter filled in */ bool db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) { bool retval = false; char esc[MAX_ESCAPE_NAME_LENGTH]; COUNTER_DBR mcr; db_lock(mdb); memset(&mcr, 0, sizeof(mcr)); bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter)); if (db_get_counter_record(jcr, mdb, &mcr)) { memcpy(cr, &mcr, sizeof(COUNTER_DBR)); retval = true; goto bail_out; } mdb->db_escape_string(jcr, esc, cr->Counter, strlen(cr->Counter)); /* * Must create it */ Mmsg(mdb->cmd, insert_counter_values[db_get_type_index(mdb)], esc, cr->MinValue, cr->MaxValue, cr->CurrentValue, cr->WrapCounter); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a FileSet record. This record is unique in the * name and the MD5 signature of the include/exclude sets. * Returns: false on failure * true on success with FileSetId in record */ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) { bool retval = false; SQL_ROW row; int num_rows; char esc_fs[MAX_ESCAPE_NAME_LENGTH]; char esc_md5[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); fsr->created = false; mdb->db_escape_string(jcr, esc_fs, fsr->FileSet, strlen(fsr->FileSet)); mdb->db_escape_string(jcr, esc_md5, fsr->MD5, strlen(fsr->MD5)); Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE " "FileSet='%s' AND MD5='%s'", esc_fs, esc_md5); fsr->FileSetId = 0; if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), num_rows); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); goto bail_out; } fsr->FileSetId = str_to_int64(row[0]); if (row[1] == NULL) { fsr->cCreateTime[0] = 0; } else { bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime)); } sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) { fsr->CreateTime = time(NULL); } bstrutime(fsr->cCreateTime, sizeof(fsr->cCreateTime), fsr->CreateTime); /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) " "VALUES ('%s','%s','%s')", esc_fs, esc_md5, fsr->cCreateTime); fsr->FileSetId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("FileSet")); if (fsr->FileSetId == 0) { Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); goto bail_out; } else { fsr->created = true; retval = true; } bail_out: db_unlock(mdb); return retval; } /** * All sql_batch_* functions are used to do bulk batch insert in File/Filename/Path * tables. * * To sum up : * - bulk load a temp table * - insert missing filenames into filename with a single query (lock filenames * - table before that to avoid possible duplicate inserts with concurrent update) * - insert missing paths into path with another single query * - then insert the join between the temp, filename and path tables into file. * * Returns: false on failure * true on success */ bool db_write_batch_file_records(JCR *jcr) { bool retval = false; int JobStatus = jcr->JobStatus; if (!jcr->batch_started) { /* no files to backup ? */ Dmsg0(50,"db_create_file_record : no files\n"); return true; } if (job_canceled(jcr)) { goto bail_out; } Dmsg1(50,"db_create_file_record changes=%u\n",jcr->db_batch->changes); jcr->JobStatus = JS_AttrInserting; if (!sql_batch_end(jcr, jcr->db_batch, NULL)) { Jmsg1(jcr, M_FATAL, 0, "Batch end %s\n", jcr->db_batch->errmsg); goto bail_out; } if (job_canceled(jcr)) { goto bail_out; } /* * We have to lock tables */ if (!db_sql_query(jcr->db_batch, batch_lock_path_query[db_get_type_index(jcr->db_batch)])) { Jmsg1(jcr, M_FATAL, 0, "Lock Path table %s\n", jcr->db_batch->errmsg); goto bail_out; } if (!db_sql_query(jcr->db_batch, batch_fill_path_query[db_get_type_index(jcr->db_batch)])) { Jmsg1(jcr, M_FATAL, 0, "Fill Path table %s\n",jcr->db_batch->errmsg); db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)]); goto bail_out; } if (!db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)])) { Jmsg1(jcr, M_FATAL, 0, "Unlock Path table %s\n", jcr->db_batch->errmsg); goto bail_out; } /* * We have to lock tables */ if (!db_sql_query(jcr->db_batch, batch_lock_filename_query[db_get_type_index(jcr->db_batch)])) { Jmsg1(jcr, M_FATAL, 0, "Lock Filename table %s\n", jcr->db_batch->errmsg); goto bail_out; } if (!db_sql_query(jcr->db_batch, batch_fill_filename_query[db_get_type_index(jcr->db_batch)])) { Jmsg1(jcr,M_FATAL,0,"Fill Filename table %s\n",jcr->db_batch->errmsg); db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)]); goto bail_out; } if (!db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)])) { Jmsg1(jcr, M_FATAL, 0, "Unlock Filename table %s\n", jcr->db_batch->errmsg); goto bail_out; } if (!db_sql_query(jcr->db_batch, "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, LStat, MD5, DeltaSeq) " "SELECT batch.FileIndex, batch.JobId, Path.PathId, " "Filename.FilenameId,batch.LStat, batch.MD5, batch.DeltaSeq " "FROM batch " "JOIN Path ON (batch.Path = Path.Path) " "JOIN Filename ON (batch.Name = Filename.Name)")) { Jmsg1(jcr, M_FATAL, 0, "Fill File table %s\n", jcr->db_batch->errmsg); goto bail_out; } jcr->JobStatus = JobStatus; /* reset entry status */ retval = true; bail_out: db_sql_query(jcr->db_batch, "DROP TABLE batch"); jcr->batch_started = false; return retval; } /** * Create File record in B_DB * * In order to reduce database size, we store the File attributes, * the FileName, and the Path separately. In principle, there * is a single FileName record and a single Path record, no matter * how many times it occurs. This is this subroutine, we separate * the file and the path and fill temporary tables with this three records. * * Note: all routines that call this expect to be able to call * db_strerror(mdb) to get the error message, so the error message * MUST be edited into mdb->errmsg before returning an error status. * * Returns: false on failure * true on success */ bool db_create_batch_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { ASSERT(ar->FileType != FT_BASE); Dmsg1(dbglevel, "Fname=%s\n", ar->fname); Dmsg0(dbglevel, "put_file_into_catalog\n"); if (jcr->batch_started && jcr->db_batch->changes > BATCH_FLUSH) { db_write_batch_file_records(jcr); jcr->db_batch->changes = 0; } /* * Open the dedicated connection */ if (!jcr->batch_started) { if (!db_open_batch_connection(jcr, mdb)) { return false; /* error already printed */ } if (!sql_batch_start(jcr, jcr->db_batch)) { Mmsg1(&mdb->errmsg, "Can't start batch mode: ERR=%s", db_strerror(jcr->db_batch)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); return false; } jcr->batch_started = true; } split_path_and_file(jcr, jcr->db_batch, ar->fname); return sql_batch_insert(jcr, jcr->db_batch, ar); } /** * Create File record in B_DB * * In order to reduce database size, we store the File attributes, * the FileName, and the Path separately. In principle, there * is a single FileName record and a single Path record, no matter * how many times it occurs. This is this subroutine, we separate * the file and the path and create three database records. * Returns: false on failure * true on success */ bool db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { bool retval = false; db_lock(mdb); Dmsg1(dbglevel, "Fname=%s\n", ar->fname); Dmsg0(dbglevel, "put_file_into_catalog\n"); split_path_and_file(jcr, mdb, ar->fname); if (!db_create_filename_record(jcr, mdb, ar)) { goto bail_out; } Dmsg1(dbglevel, "db_create_filename_record: %s\n", mdb->esc_name); if (!db_create_path_record(jcr, mdb, ar)) { goto bail_out; } Dmsg1(dbglevel, "db_create_path_record: %s\n", mdb->esc_name); /* Now create master File record */ if (!db_create_file_record(jcr, mdb, ar)) { goto bail_out; } Dmsg0(dbglevel, "db_create_file_record OK\n"); Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId); retval = true; bail_out: db_unlock(mdb); return retval; } /** * This is the master File entry containing the attributes. * The filename and path records have already been created. * Returns: false on failure * true on success with fileid filled in */ static bool db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { bool retval = false; static const char *no_digest = "0"; const char *digest; ASSERT(ar->JobId); ASSERT(ar->PathId); ASSERT(ar->FilenameId); if (ar->Digest == NULL || ar->Digest[0] == 0) { digest = no_digest; } else { digest = ar->Digest; } /* Must create it */ Mmsg(mdb->cmd, "INSERT INTO File (FileIndex,JobId,PathId,FilenameId," "LStat,MD5,DeltaSeq) VALUES (%u,%u,%u,%u,'%s','%s',%u)", ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, ar->attr, digest, ar->DeltaSeq); ar->FileId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("File")); if (ar->FileId == 0) { Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); } else { retval = true; } return retval; } /** * Create a Unique record for the filename -- no duplicates * Returns: false on failure * true on success with filenameid filled in */ static bool db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { SQL_ROW row; int num_rows; mdb->errmsg[0] = 0; mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2); db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl); Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 1) { char ed1[30]; Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"), edit_uint64(num_rows, ed1), mdb->fname); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"), mdb->fname, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); ar->FilenameId = 0; } else { ar->FilenameId = str_to_int64(row[0]); } sql_free_result(mdb); return ar->FilenameId > 0; } sql_free_result(mdb); } Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name); ar->FilenameId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Filename")); if (ar->FilenameId == 0) { Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); } return ar->FilenameId > 0; } /** * Create file attributes record, or base file attributes record * Returns: false on failure * true on success */ bool db_create_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { bool retval; mdb->errmsg[0] = 0; /* * Make sure we have an acceptable attributes record. */ if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES || ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) { Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"), ar->Stream); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); return false; } if (ar->FileType != FT_BASE) { if (mdb->batch_insert_available()) { retval = db_create_batch_file_attributes_record(jcr, mdb, ar); /* Error message already printed */ } else { retval = db_create_file_attributes_record(jcr, mdb, ar); } } else if (jcr->HasBase) { retval = db_create_base_file_attributes_record(jcr, mdb, ar); } else { Mmsg0(&mdb->errmsg, _("Cannot Copy/Migrate job using BaseJob.\n")); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); retval = true; /* in copy/migration what do we do ? */ } return retval; } /** * Create Base File record in B_DB * Returns: false on failure * true on success */ bool db_create_base_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { bool retval; Dmsg1(dbglevel, "create_base_file Fname=%s\n", ar->fname); Dmsg0(dbglevel, "put_base_file_into_catalog\n"); db_lock(mdb); split_path_and_file(jcr, mdb, ar->fname); mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1); db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl); mdb->esc_path = check_pool_memory_size(mdb->esc_path, mdb->pnl*2+1); db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl); Mmsg(mdb->cmd, "INSERT INTO basefile%lld (Path, Name) VALUES ('%s','%s')", (uint64_t)jcr->JobId, mdb->esc_path, mdb->esc_name); retval = INSERT_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /** * Cleanup the base file temporary tables */ static void db_cleanup_base_file(JCR *jcr, B_DB *mdb) { POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "DROP TABLE new_basefile%lld", (uint64_t) jcr->JobId); db_sql_query(mdb, buf.c_str()); Mmsg(buf, "DROP TABLE basefile%lld", (uint64_t) jcr->JobId); db_sql_query(mdb, buf.c_str()); } /** * Put all base file seen in the backup to the BaseFile table * and cleanup temporary tables * Returns: false on failure * true on success */ bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb) { bool retval; char ed1[50]; db_lock(mdb); Mmsg(mdb->cmd, "INSERT INTO BaseFiles (BaseJobId, JobId, FileId, FileIndex) " "SELECT B.JobId AS BaseJobId, %s AS JobId, " "B.FileId, B.FileIndex " "FROM basefile%s AS A, new_basefile%s AS B " "WHERE A.Path = B.Path " "AND A.Name = B.Name " "ORDER BY B.FileId", edit_uint64(jcr->JobId, ed1), ed1, ed1); retval = db_sql_query(mdb, mdb->cmd); jcr->nb_base_files_used = sql_affected_rows(mdb); db_cleanup_base_file(jcr, mdb); db_unlock(mdb); return retval; } /** * Find the last "accurate" backup state with Base jobs * 1) Get all files with jobid in list (F subquery) * 2) Take only the last version of each file (Temp subquery) => accurate list is ok * 3) Put the result in a temporary table for the end of job * Returns: false on failure * true on success */ bool db_create_base_file_list(JCR *jcr, B_DB *mdb, char *jobids) { bool retval = false; POOL_MEM buf; db_lock(mdb); if (!*jobids) { Mmsg(mdb->errmsg, _("ERR=JobIds are empty\n")); goto bail_out; } Mmsg(mdb->cmd, create_temp_basefile[db_get_type_index(mdb)], (uint64_t) jcr->JobId); if (!db_sql_query(mdb, mdb->cmd)) { goto bail_out; } Mmsg(buf, select_recent_version[db_get_type_index(mdb)], jobids, jobids); Mmsg(mdb->cmd, create_temp_new_basefile[db_get_type_index(mdb)], (uint64_t)jcr->JobId, buf.c_str()); retval = db_sql_query(mdb, mdb->cmd); bail_out: db_unlock(mdb); return retval; } /** * Create Restore Object record in B_DB * Returns: false on failure * true on success */ bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ro) { bool retval = false; int plug_name_len; POOLMEM *esc_plug_name = get_pool_memory(PM_MESSAGE); db_lock(mdb); Dmsg1(dbglevel, "Oname=%s\n", ro->object_name); Dmsg0(dbglevel, "put_object_into_catalog\n"); mdb->fnl = strlen(ro->object_name); mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1); db_escape_string(jcr, mdb, mdb->esc_name, ro->object_name, mdb->fnl); db_escape_object(jcr, mdb, ro->object, ro->object_len); plug_name_len = strlen(ro->plugin_name); esc_plug_name = check_pool_memory_size(esc_plug_name, plug_name_len*2+1); db_escape_string(jcr, mdb, esc_plug_name, ro->plugin_name, plug_name_len); Mmsg(mdb->cmd, "INSERT INTO RestoreObject (ObjectName,PluginName,RestoreObject," "ObjectLength,ObjectFullLength,ObjectIndex,ObjectType," "ObjectCompression,FileIndex,JobId) " "VALUES ('%s','%s','%s',%d,%d,%d,%d,%d,%d,%u)", mdb->esc_name, esc_plug_name, mdb->esc_obj, ro->object_len, ro->object_full_len, ro->object_index, ro->FileType, ro->object_compression, ro->FileIndex, ro->JobId); ro->RestoreObjectId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("RestoreObject")); if (ro->RestoreObjectId == 0) { Mmsg2(&mdb->errmsg, _("Create db Object record %s failed. ERR=%s"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); } else { retval = true; } db_unlock(mdb); free_pool_memory(esc_plug_name); return retval; } /** * Create a quota record if it does not exist. * Returns: false on failure * true on success */ bool db_create_quota_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) { bool retval = false; char ed1[50]; int num_rows; db_lock(mdb); Mmsg(mdb->cmd, "SELECT ClientId FROM Quota WHERE ClientId='%s'", edit_uint64(cr->ClientId,ed1)); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 1) { sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO Quota (ClientId, GraceTime, QuotaLimit)" " VALUES ('%s', '%s', %s)", edit_uint64(cr->ClientId, ed1), "0", "0"); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB Quota record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a NDMP level mapping if it does not exist. * Returns: false on failure * true on success */ bool db_create_ndmp_level_mapping(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *filesystem) { bool retval = false; char ed1[50], ed2[50]; int num_rows; db_lock(mdb); mdb->esc_name = check_pool_memory_size(mdb->esc_name, strlen(filesystem) * 2 + 1); db_escape_string(jcr, mdb, mdb->esc_name, filesystem, strlen(filesystem)); Mmsg(mdb->cmd, "SELECT ClientId FROM NDMPLevelMap WHERE " "ClientId='%s' AND FileSetId='%s' AND FileSystem='%s'", edit_uint64(jr->ClientId, ed1), edit_uint64(jr->FileSetId, ed2), mdb->esc_name); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 1) { sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } /* * Must create it */ Mmsg(mdb->cmd, "INSERT INTO NDMPLevelMap (ClientId, FilesetId, FileSystem, DumpLevel)" " VALUES ('%s', '%s', '%s', %s)", edit_uint64(jr->ClientId, ed1), edit_uint64(jr->FileSetId, ed2), mdb->esc_name, "0"); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB NDMP Level Map record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a NDMP Job Environment String * Returns: false on failure * true on success */ bool db_create_ndmp_environment_string(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *name, char *value) { bool retval = false; char ed1[50], ed2[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; char esc_value[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc_name, name, strlen(name)); mdb->db_escape_string(jcr, esc_value, value, strlen(value)); Mmsg(mdb->cmd, "INSERT INTO NDMPJobEnvironment (JobId, FileIndex, EnvName, EnvValue)" " VALUES ('%s', '%s', '%s', '%s')", edit_int64(jr->JobId, ed1), edit_uint64(jr->FileIndex, ed2), esc_name, esc_value); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB NDMP Job Environment record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { retval = true; } db_unlock(mdb); return retval; } /** * Create a Job Statistics record. * Returns: false on failure * true on success */ bool db_create_job_statistics(JCR *jcr, B_DB *mdb, JOB_STATS_DBR *jsr) { time_t stime; bool retval = false; char dt[MAX_TIME_LENGTH]; char ed1[50], ed2[50], ed3[50], ed4[50]; db_lock(mdb); stime = jsr->SampleTime; ASSERT(stime != 0); bstrutime(dt, sizeof(dt), stime); /* * Create job statistics record */ Mmsg(mdb->cmd, "INSERT INTO JobStats (SampleTime, JobId, JobFiles, JobBytes, DeviceId)" " VALUES ('%s', %s, %s, %s, %s)", dt, edit_int64(jsr->JobId, ed1), edit_uint64(jsr->JobFiles, ed2), edit_uint64(jsr->JobBytes, ed3), edit_int64(jsr->DeviceId, ed4)); Dmsg1(200, "Create job stats: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB JobStats record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); goto bail_out; } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a Device Statistics record. * Returns: false on failure * true on success */ bool db_create_device_statistics(JCR *jcr, B_DB *mdb, DEVICE_STATS_DBR *dsr) { time_t stime; bool retval = false; char dt[MAX_TIME_LENGTH]; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; char ed7[50], ed8[50], ed9[50], ed10[50], ed11[50], ed12[50]; db_lock(mdb); stime = dsr->SampleTime; ASSERT(stime != 0); bstrutime(dt, sizeof(dt), stime); /* * Create device statistics record */ Mmsg(mdb->cmd, "INSERT INTO DeviceStats (DeviceId, SampleTime, ReadTime, WriteTime," " ReadBytes, WriteBytes, SpoolSize, NumWaiting, NumWriters, MediaId," " VolCatBytes, VolCatFiles, VolCatBlocks)" " VALUES (%s, '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", edit_int64(dsr->DeviceId, ed1), dt, edit_uint64(dsr->ReadTime, ed2), edit_uint64(dsr->WriteTime, ed3), edit_uint64(dsr->ReadBytes, ed4), edit_uint64(dsr->WriteBytes, ed5), edit_uint64(dsr->SpoolSize, ed6), edit_uint64(dsr->NumWaiting, ed7), edit_uint64(dsr->NumWriters, ed8), edit_int64(dsr->MediaId, ed9), edit_uint64(dsr->VolCatBytes, ed10), edit_uint64(dsr->VolCatFiles, ed11), edit_uint64(dsr->VolCatBlocks, ed12)); Dmsg1(200, "Create device stats: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB DeviceStats record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); goto bail_out; } else { retval = true; } bail_out: db_unlock(mdb); return retval; } /** * Create a tapealert record. * Returns: false on failure * true on success */ bool db_create_tapealert_statistics(JCR *jcr, B_DB *mdb, TAPEALERT_STATS_DBR *tsr) { time_t stime; bool retval = false; char dt[MAX_TIME_LENGTH]; char ed1[50], ed2[50]; db_lock(mdb); stime = tsr->SampleTime; ASSERT(stime != 0); bstrutime(dt, sizeof(dt), stime); /* * Create device statistics record */ Mmsg(mdb->cmd, "INSERT INTO TapeAlerts (DeviceId, SampleTime, AlertFlags)" " VALUES (%s, '%s', %s)", edit_int64(tsr->DeviceId, ed1), dt, edit_uint64(tsr->AlertFlags, ed2)); Dmsg1(200, "Create tapealert: %s\n", mdb->cmd); if (!INSERT_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Create DB TapeAlerts record %s failed. ERR=%s\n"), mdb->cmd, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); goto bail_out; } else { retval = true; } bail_out: db_unlock(mdb); return retval; } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_delete.c000066400000000000000000000156361263011562700204610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database Delete record interface routines * * Kern Sibbald, December 2000 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* * Delete Pool record, must also delete all associated * Media records. * * Returns: false on error * true on success * PoolId = number of Pools deleted (should be 1) * NumVols = number of Media records deleted */ bool db_delete_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) { bool retval = false; SQL_ROW row; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, pr->Name, strlen(pr->Name)); Mmsg(mdb->cmd, "SELECT PoolId FROM Pool WHERE Name='%s'", esc); Dmsg1(10, "selectpool: %s\n", mdb->cmd); pr->PoolId = pr->NumVols = 0; if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 0) { Mmsg(mdb->errmsg, _("No pool record %s exists\n"), pr->Name); sql_free_result(mdb); goto bail_out; } else if (num_rows != 1) { Mmsg(mdb->errmsg, _("Expecting one pool record, got %d\n"), num_rows); sql_free_result(mdb); goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("Error fetching row %s\n"), sql_strerror(mdb)); goto bail_out; } pr->PoolId = str_to_int64(row[0]); sql_free_result(mdb); } /* Delete Media owned by this pool */ Mmsg(mdb->cmd, "DELETE FROM Media WHERE Media.PoolId = %d", pr->PoolId); pr->NumVols = DELETE_DB(jcr, mdb, mdb->cmd); Dmsg1(200, "Deleted %d Media records\n", pr->NumVols); /* Delete Pool */ Mmsg(mdb->cmd, "DELETE FROM Pool WHERE Pool.PoolId = %d", pr->PoolId); pr->PoolId = DELETE_DB(jcr, mdb, mdb->cmd); Dmsg1(200, "Deleted %d Pool records\n", pr->PoolId); retval = true; bail_out: db_unlock(mdb); return retval; } #define MAX_DEL_LIST_LEN 1000000 struct s_del_ctx { JobId_t *JobId; int num_ids; /* ids stored */ int max_ids; /* size of array */ int num_del; /* number deleted */ int tot_ids; /* total to process */ }; /* * Called here to make in memory list of JobIds to be * deleted. The in memory list will then be transversed * to issue the SQL DELETE commands. Note, the list * is allowed to get to MAX_DEL_LIST_LEN to limit the * maximum malloc'ed memory. */ static int delete_handler(void *ctx, int num_fields, char **row) { struct s_del_ctx *del = (struct s_del_ctx *)ctx; if (del->num_ids == MAX_DEL_LIST_LEN) { return 1; } if (del->num_ids == del->max_ids) { del->max_ids = (del->max_ids * 3) / 2; del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids); } del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]); return 0; } /* * This routine will purge (delete) all records * associated with a particular Volume. It will * not delete the media record itself. * TODO: This function is broken and it doesn't purge * File, BaseFiles, Log, ... * We call it from relabel and delete volume=, both ensure * that the volume is properly purged. */ static int do_media_purge(B_DB *mdb, MEDIA_DBR *mr) { POOLMEM *query = get_pool_memory(PM_MESSAGE); struct s_del_ctx del; char ed1[50]; int i; del.num_ids = 0; del.tot_ids = 0; del.num_del = 0; del.max_ids = 0; Mmsg(mdb->cmd, "SELECT JobId from JobMedia WHERE MediaId=%d", mr->MediaId); del.max_ids = mr->VolJobs; if (del.max_ids < 100) { del.max_ids = 100; } else if (del.max_ids > MAX_DEL_LIST_LEN) { del.max_ids = MAX_DEL_LIST_LEN; } del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); db_sql_query(mdb, mdb->cmd, delete_handler, (void *)&del); for (i=0; i < del.num_ids; i++) { Dmsg1(400, "Delete JobId=%d\n", del.JobId[i]); Mmsg(query, "DELETE FROM Job WHERE JobId=%s", edit_int64(del.JobId[i], ed1)); db_sql_query(mdb, query); Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(del.JobId[i], ed1)); db_sql_query(mdb, query); Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", edit_int64(del.JobId[i], ed1)); db_sql_query(mdb, query); } free(del.JobId); free_pool_memory(query); return 1; } /* * Delete Media record and all records that are associated with it. * Returns: false on error * true on success */ bool db_delete_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { bool retval = false; db_lock(mdb); if (mr->MediaId == 0 && !db_get_media_record(jcr, mdb, mr)) { goto bail_out; } /* Do purge if not already purged */ if (!bstrcmp(mr->VolStatus, "Purged")) { /* Delete associated records */ do_media_purge(mdb, mr); } Mmsg(mdb->cmd, "DELETE FROM Media WHERE MediaId=%d", mr->MediaId); db_sql_query(mdb, mdb->cmd); retval = true; bail_out: db_unlock(mdb); return retval; } /* * Purge all records associated with a * media record. This does not delete the * media record itself. But the media status * is changed to "Purged". */ bool db_purge_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { bool retval = false; db_lock(mdb); if (mr->MediaId == 0 && !db_get_media_record(jcr, mdb, mr)) { goto bail_out; } /* Delete associated records */ do_media_purge(mdb, mr); /* Note, always purge */ /* Mark Volume as purged */ strcpy(mr->VolStatus, "Purged"); if (!db_update_media_record(jcr, mdb, mr)) { goto bail_out; } retval = true; bail_out: db_unlock(mdb); return retval; } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES */ bareos-Release-14.2.6/src/cats/sql_find.c000066400000000000000000000400171263011562700201260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database Find record interface routines * * Note, generally, these routines are more complicated * that a simple search by name or id. Such simple * request are in get.c * * Kern Sibbald, December 2000 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* * Find job start time if JobId specified, otherwise * find last Job start time Incremental and Differential saves. * * StartTime is returned in stime * Job name is returned in job (MAX_NAME_LENGTH) * * Returns: 0 on failure * 1 on success, jr is unchanged, but stime and job are set */ bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job) { bool retval = false; SQL_ROW row; char ed1[50], ed2[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name)); pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ job[0] = 0; /* If no Id given, we must find corresponding job */ if (jr->JobId == 0) { /* Differential is since last Full backup */ Mmsg(mdb->cmd, "SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND " "Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s " "ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_FULL, esc_name, edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2)); if (jr->JobLevel == L_DIFFERENTIAL) { /* SQL cmd for Differential backup already edited above */ /* Incremental is since last Full, Incremental, or Differential */ } else if (jr->JobLevel == L_INCREMENTAL) { /* * For an Incremental job, we must first ensure * that a Full backup was done (cmd edited above) * then we do a second look to find the most recent * backup */ if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"), sql_strerror(mdb), mdb->cmd); goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { sql_free_result(mdb); Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n")); goto bail_out; } sql_free_result(mdb); /* Now edit SQL command for Incremental Job */ Mmsg(mdb->cmd, "SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND " "Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%s " "AND FileSetId=%s ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_INCREMENTAL, L_DIFFERENTIAL, L_FULL, esc_name, edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2)); } else { Mmsg1(mdb->errmsg, _("Unknown level=%d\n"), jr->JobLevel); goto bail_out; } } else { Dmsg1(100, "Submitting: %s\n", mdb->cmd); Mmsg(mdb->cmd, "SELECT StartTime, Job FROM Job WHERE Job.JobId=%s", edit_int64(jr->JobId, ed1)); } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { pm_strcpy(stime, ""); /* set EOS */ Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"), sql_strerror(mdb), mdb->cmd); goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(&mdb->errmsg, _("No Job record found: ERR=%s\nCMD=%s\n"), sql_strerror(mdb), mdb->cmd); sql_free_result(mdb); goto bail_out; } Dmsg2(100, "Got start time: %s, job: %s\n", row[0], row[1]); pm_strcpy(stime, row[0]); bstrncpy(job, row[1], MAX_NAME_LENGTH); sql_free_result(mdb); retval = true; bail_out: db_unlock(mdb); return retval; } /* * Find the last job start time for the specified JobLevel * * StartTime is returned in stime * Job name is returned in job (MAX_NAME_LENGTH) * * Returns: false on failure * true on success, jr is unchanged, but stime and job are set */ bool db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, char *job, int JobLevel) { bool retval = false; SQL_ROW row; char ed1[50], ed2[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name)); pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ job[0] = 0; Mmsg(mdb->cmd, "SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND " "Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s " "ORDER BY StartTime DESC LIMIT 1", jr->JobType, JobLevel, esc_name, edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2)); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"), sql_strerror(mdb), mdb->cmd); goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { sql_free_result(mdb); Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n")); goto bail_out; } Dmsg1(100, "Got start time: %s\n", row[0]); pm_strcpy(stime, row[0]); bstrncpy(job, row[1], MAX_NAME_LENGTH); sql_free_result(mdb); retval = true; bail_out: db_unlock(mdb); return retval; } /* * Find last failed job since given start-time * it must be either Full or Diff. * * Returns: false on failure * true on success, jr is unchanged and stime unchanged * level returned in JobLevel */ bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel) { bool retval = false; SQL_ROW row; char ed1[50], ed2[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name)); /* Differential is since last Full backup */ Mmsg(mdb->cmd, "SELECT Level FROM Job WHERE JobStatus NOT IN ('T','W') AND " "Type='%c' AND Level IN ('%c','%c') AND Name='%s' AND ClientId=%s " "AND FileSetId=%s AND StartTime>'%s' " "ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_FULL, L_DIFFERENTIAL, esc_name, edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2), stime); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { sql_free_result(mdb); goto bail_out; } JobLevel = (int)*row[0]; sql_free_result(mdb); retval = true; bail_out: db_unlock(mdb); return retval; } /* * Find JobId of last job that ran. E.g. for * VERIFY_CATALOG we want the JobId of the last INIT. * For VERIFY_VOLUME_TO_CATALOG, we want the JobId of the last Job. * * Returns: true on success * false on failure */ bool db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr) { bool retval = false; SQL_ROW row; char ed1[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); /* Find last full */ Dmsg2(100, "JobLevel=%d JobType=%d\n", jr->JobLevel, jr->JobType); if (jr->JobLevel == L_VERIFY_CATALOG) { mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name)); Mmsg(mdb->cmd, "SELECT JobId FROM Job WHERE Type='V' AND Level='%c' AND " " JobStatus IN ('T','W') AND Name='%s' AND " "ClientId=%s ORDER BY StartTime DESC LIMIT 1", L_VERIFY_INIT, esc_name, edit_int64(jr->ClientId, ed1)); } else if (jr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG || jr->JobLevel == L_VERIFY_DISK_TO_CATALOG || jr->JobType == JT_BACKUP) { if (Name) { mdb->db_escape_string(jcr, esc_name, (char*)Name, MIN(strlen(Name), sizeof(esc_name))); Mmsg(mdb->cmd, "SELECT JobId FROM Job WHERE Type='B' AND JobStatus IN ('T','W') AND " "Name='%s' ORDER BY StartTime DESC LIMIT 1", esc_name); } else { Mmsg(mdb->cmd, "SELECT JobId FROM Job WHERE Type='B' AND JobStatus IN ('T','W') AND " "ClientId=%s ORDER BY StartTime DESC LIMIT 1", edit_int64(jr->ClientId, ed1)); } } else { Mmsg1(&mdb->errmsg, _("Unknown Job level=%d\n"), jr->JobLevel); goto bail_out; } Dmsg1(100, "Query: %s\n", mdb->cmd); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("No Job found for: %s.\n"), mdb->cmd); sql_free_result(mdb); goto bail_out; } jr->JobId = str_to_int64(row[0]); sql_free_result(mdb); Dmsg1(100, "db_get_last_jobid: got JobId=%d\n", jr->JobId); if (jr->JobId <= 0) { Mmsg1(&mdb->errmsg, _("No Job found for: %s\n"), mdb->cmd); goto bail_out; } retval = true; bail_out: db_unlock(mdb); return retval; } /* * Find Available Media (Volume) for Pool * * Find a Volume for a given PoolId, MediaType, and Status. * * Returns: 0 on failure * numrows on success */ int db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr) { SQL_ROW row = NULL; int num_rows = 0; const char *order; char esc_type[MAX_ESCAPE_NAME_LENGTH]; char esc_status[MAX_ESCAPE_NAME_LENGTH]; char ed1[50]; db_lock(mdb); mdb->db_escape_string(jcr, esc_type, mr->MediaType, strlen(mr->MediaType)); mdb->db_escape_string(jcr, esc_status, mr->VolStatus, strlen(mr->VolStatus)); if (item == -1) { /* find oldest volume */ /* Find oldest volume */ Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs," "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime," "ActionOnPurge,EncryptionKey,MinBlocksize,MaxBlocksize " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND VolStatus IN ('Full'," "'Recycle','Purged','Used','Append') AND Enabled=1 " "ORDER BY LastWritten LIMIT 1", edit_int64(mr->PoolId, ed1), esc_type); item = 1; } else { POOL_MEM changer(PM_FNAME); /* Find next available volume */ if (InChanger) { Mmsg(changer, "AND InChanger=1 AND StorageId=%s", edit_int64(mr->StorageId, ed1)); } if (bstrcmp(mr->VolStatus, "Recycle") || bstrcmp(mr->VolStatus, "Purged")) { order = "AND Recycle=1 ORDER BY LastWritten ASC,MediaId"; /* take oldest that can be recycled */ } else { order = sql_media_order_most_recently_written[db_get_type_index(mdb)]; /* take most recently written */ } Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs," "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime," "ActionOnPurge,EncryptionKey,MinBlocksize,MaxBlocksize " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND Enabled=1 " "AND VolStatus='%s' " "%s " "%s LIMIT %d", edit_int64(mr->PoolId, ed1), esc_type, esc_status, changer.c_str(), order, item); } Dmsg1(100, "fnextvol=%s\n", mdb->cmd); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } num_rows = sql_num_rows(mdb); if (item > num_rows || item < 1) { Dmsg2(050, "item=%d got=%d\n", item, num_rows); Mmsg2(&mdb->errmsg, _("Request for Volume item %d greater than max %d or less than 1\n"), item, num_rows); num_rows = 0; goto bail_out; } /* Note, we previously seeked to the row using: sql_data_seek(mdb, item-1); * but this failed on PostgreSQL, so now we loop over all the records. * This should not be too horrible since the maximum Volumes we look at * in any case is 20. */ while (item-- > 0) { if ((row = sql_fetch_row(mdb)) == NULL) { Dmsg1(050, "Fail fetch item=%d\n", item+1); Mmsg1(&mdb->errmsg, _("No Volume record found for item %d.\n"), item); sql_free_result(mdb); num_rows = 0; goto bail_out; } } /* Return fields in Media Record */ mr->MediaId = str_to_int64(row[0]); bstrncpy(mr->VolumeName, (row[1] != NULL) ? row[1] : "", sizeof(mr->VolumeName)); mr->VolJobs = str_to_int64(row[2]); mr->VolFiles = str_to_int64(row[3]); mr->VolBlocks = str_to_int64(row[4]); mr->VolBytes = str_to_uint64(row[5]); mr->VolMounts = str_to_int64(row[6]); mr->VolErrors = str_to_int64(row[7]); mr->VolWrites = str_to_int64(row[8]); mr->MaxVolBytes = str_to_uint64(row[9]); mr->VolCapacityBytes = str_to_uint64(row[10]); bstrncpy(mr->MediaType, (row[11] != NULL) ? row[11] : "", sizeof(mr->MediaType)); bstrncpy(mr->VolStatus, (row[12] != NULL) ? row[12] : "", sizeof(mr->VolStatus)); mr->PoolId = str_to_int64(row[13]); mr->VolRetention = str_to_uint64(row[14]); mr->VolUseDuration = str_to_uint64(row[15]); mr->MaxVolJobs = str_to_int64(row[16]); mr->MaxVolFiles = str_to_int64(row[17]); mr->Recycle = str_to_int64(row[18]); mr->Slot = str_to_int64(row[19]); bstrncpy(mr->cFirstWritten, (row[20] != NULL) ? row[20] : "", sizeof(mr->cFirstWritten)); mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten); bstrncpy(mr->cLastWritten, (row[21] != NULL) ? row[21] : "", sizeof(mr->cLastWritten)); mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten); mr->InChanger = str_to_uint64(row[22]); mr->EndFile = str_to_uint64(row[23]); mr->EndBlock = str_to_uint64(row[24]); mr->LabelType = str_to_int64(row[25]); bstrncpy(mr->cLabelDate, (row[26] != NULL) ? row[26] : "", sizeof(mr->cLabelDate)); mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate); mr->StorageId = str_to_int64(row[27]); mr->Enabled = str_to_int64(row[28]); mr->LocationId = str_to_int64(row[29]); mr->RecycleCount = str_to_int64(row[30]); bstrncpy(mr->cInitialWrite, (row[31] != NULL) ? row[31] : "", sizeof(mr->cInitialWrite)); mr->InitialWrite = (time_t)str_to_utime(mr->cInitialWrite); mr->ScratchPoolId = str_to_int64(row[32]); mr->RecyclePoolId = str_to_int64(row[33]); mr->VolReadTime = str_to_int64(row[34]); mr->VolWriteTime = str_to_int64(row[35]); mr->ActionOnPurge = str_to_int64(row[36]); bstrncpy(mr->EncrKey, (row[37] != NULL) ? row[37] : "", sizeof(mr->EncrKey)); mr->MinBlocksize = str_to_int32(row[38]); mr->MaxBlocksize = str_to_int32(row[39]); sql_free_result(mdb); bail_out: db_unlock(mdb); Dmsg1(050, "Rtn numrows=%d\n", num_rows); return num_rows; } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_get.c000066400000000000000000001501741263011562700177730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * BAREOS Catalog Database Get record interface routines * * Note, these routines generally get a record by id or * by name. If more logic is involved, the routine * should be in find.c * * Kern Sibbald, March 2000 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* Forward referenced functions */ static bool db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr); static int db_get_filename_record(JCR *jcr, B_DB *mdb); /** * Given a full filename (with path), look up the File record * (with attributes) in the database. * * Returns: 0 on failure * 1 on success with the File record in FILE_DBR */ bool db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr) { bool retval; Dmsg1(100, "db_get_file_attributes_record fname=%s \n", fname); db_lock(mdb); split_path_and_file(jcr, mdb, fname); fdbr->FilenameId = db_get_filename_record(jcr, mdb); fdbr->PathId = db_get_path_record(jcr, mdb); retval = db_get_file_record(jcr, mdb, jr, fdbr); db_unlock(mdb); return retval; } /** * Get a File record * Returns: false on failure * true on success * * DO NOT use Jmsg in this routine. * * Note in this routine, we do not use Jmsg because it may be * called to get attributes of a non-existent file, which is * "normal" if a new file is found during Verify. * * The following is a bit of a kludge: because we always backup a * directory entry, we can end up with two copies of the directory * in the backup. One is when we encounter the directory and find * we cannot recurse into it, and the other is when we find an * explicit mention of the directory. This can also happen if the * use includes the directory twice. In this case, Verify * VolumeToCatalog fails because we have two copies in the catalog, * and only the first one is marked (twice). So, when calling from Verify, * VolumeToCatalog jr is not NULL and we know jr->FileIndex is the fileindex * of the version of the directory/file we actually want and do * a more explicit SQL search. */ static bool db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr) { bool retval = false; SQL_ROW row; char ed1[50], ed2[50], ed3[50]; int num_rows; if (jcr->getJobLevel() == L_VERIFY_DISK_TO_CATALOG) { Mmsg(mdb->cmd, "SELECT FileId, LStat, MD5 FROM File,Job WHERE " "File.JobId=Job.JobId AND File.PathId=%s AND " "File.FilenameId=%s AND Job.Type='B' AND Job.JobStatus IN ('T','W') AND " "ClientId=%s ORDER BY StartTime DESC LIMIT 1", edit_int64(fdbr->PathId, ed1), edit_int64(fdbr->FilenameId, ed2), edit_int64(jr->ClientId,ed3)); } else if (jcr->getJobLevel() == L_VERIFY_VOLUME_TO_CATALOG) { Mmsg(mdb->cmd, "SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%s AND File.PathId=%s AND " "File.FilenameId=%s AND File.FileIndex=%u", edit_int64(fdbr->JobId, ed1), edit_int64(fdbr->PathId, ed2), edit_int64(fdbr->FilenameId,ed3), jr->FileIndex); } else { Mmsg(mdb->cmd, "SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%s AND File.PathId=%s AND " "File.FilenameId=%s", edit_int64(fdbr->JobId, ed1), edit_int64(fdbr->PathId, ed2), edit_int64(fdbr->FilenameId,ed3)); } Dmsg3(450, "Get_file_record JobId=%u FilenameId=%u PathId=%u\n", fdbr->JobId, fdbr->FilenameId, fdbr->PathId); Dmsg1(100, "Query=%s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); Dmsg1(050, "get_file_record num_rows=%d\n", num_rows); if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb)); } else { fdbr->FileId = (FileId_t)str_to_int64(row[0]); bstrncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat)); bstrncpy(fdbr->Digest, row[2], sizeof(fdbr->Digest)); retval = true; if (num_rows > 1) { Mmsg3(mdb->errmsg, _("get_file_record want 1 got rows=%d PathId=%s FilenameId=%s\n"), num_rows, edit_int64(fdbr->PathId, ed1), edit_int64(fdbr->FilenameId, ed2)); Dmsg1(000, "=== Problem! %s", mdb->errmsg); } } } else { Mmsg2(mdb->errmsg, _("File record for PathId=%s FilenameId=%s not found.\n"), edit_int64(fdbr->PathId, ed1), edit_int64(fdbr->FilenameId, ed2)); } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("File record not found in Catalog.\n")); } return retval; } /** * Get Filename record * Returns: 0 on failure * FilenameId on success * * DO NOT use Jmsg in this routine (see notes for get_file_record) */ static int db_get_filename_record(JCR *jcr, B_DB *mdb) { SQL_ROW row; int FilenameId = 0; int num_rows; mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2); db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl); Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name); if (QUERY_DB(jcr, mdb, mdb->cmd)) { char ed1[30]; num_rows = sql_num_rows(mdb); if (num_rows > 1) { Mmsg2(mdb->errmsg, _("More than one Filename!: %s for file: %s\n"), edit_uint64(num_rows, ed1), mdb->fname); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); } else { FilenameId = str_to_int64(row[0]); if (FilenameId <= 0) { Mmsg2(mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"), mdb->cmd, FilenameId); FilenameId = 0; } } } else { Mmsg1(mdb->errmsg, _("Filename record: %s not found.\n"), mdb->fname); } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("Filename record: %s not found in Catalog.\n"), mdb->fname); } return FilenameId; } /** * Get path record * Returns: 0 on failure * PathId on success * * DO NOT use Jmsg in this routine (see notes for get_file_record) */ int db_get_path_record(JCR *jcr, B_DB *mdb) { SQL_ROW row; uint32_t PathId = 0; int num_rows; mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2); db_escape_string(jcr, mdb, mdb->esc_name, mdb->path, mdb->pnl); if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl && bstrcmp(mdb->cached_path, mdb->path)) { return mdb->cached_path_id; } Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name); if (QUERY_DB(jcr, mdb, mdb->cmd)) { char ed1[30]; num_rows = sql_num_rows(mdb); if (num_rows > 1) { Mmsg2(mdb->errmsg, _("More than one Path!: %s for path: %s\n"), edit_uint64(num_rows, ed1), mdb->path); Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg); } /* Even if there are multiple paths, take the first one */ if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); } else { PathId = str_to_int64(row[0]); if (PathId <= 0) { Mmsg2(mdb->errmsg, _("Get DB path record %s found bad record: %s\n"), mdb->cmd, edit_int64(PathId, ed1)); PathId = 0; } else { /* Cache path */ if (PathId != mdb->cached_path_id) { mdb->cached_path_id = PathId; mdb->cached_path_len = mdb->pnl; pm_strcpy(mdb->cached_path, mdb->path); } } } } else { Mmsg1(mdb->errmsg, _("Path record: %s not found.\n"), mdb->path); } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("Path record: %s not found in Catalog.\n"), mdb->path); } return PathId; } /** * Get Job record for given JobId or Job name * Returns: false on failure * true on success */ bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { bool retval = false; SQL_ROW row; char ed1[50]; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (jr->JobId == 0) { mdb->db_escape_string(jcr, esc, jr->Job, strlen(jr->Job)); Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime," "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus," "Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId," "SchedTime,RealEndTime,ReadBytes,HasBase,PurgedFiles " "FROM Job WHERE Job='%s'", esc); } else { Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime," "PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus," "Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId," "SchedTime,RealEndTime,ReadBytes,HasBase,PurgedFiles " "FROM Job WHERE JobId=%s", edit_int64(jr->JobId, ed1)); } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("No Job found for JobId %s\n"), edit_int64(jr->JobId, ed1)); sql_free_result(mdb); goto bail_out; } jr->VolSessionId = str_to_uint64(row[0]); jr->VolSessionTime = str_to_uint64(row[1]); jr->PoolId = str_to_int64(row[2]); bstrncpy(jr->cStartTime, (row[3] != NULL) ? row[3] : "", sizeof(jr->cStartTime)); bstrncpy(jr->cEndTime, (row[4] != NULL) ? row[4] : "", sizeof(jr->cEndTime)); jr->JobFiles = str_to_int64(row[5]); jr->JobBytes = str_to_int64(row[6]); jr->JobTDate = str_to_int64(row[7]); bstrncpy(jr->Job, (row[8] != NULL) ? row[8] : "", sizeof(jr->Job)); jr->JobStatus = (row[9] != NULL) ? (int)*row[9] : JS_FatalError; jr->JobType = (row[10] !=NULL) ? (int)*row[10] : JT_BACKUP; jr->JobLevel = (row[11] !=NULL) ? (int)*row[11] : L_NONE; jr->ClientId = str_to_uint64((row[12] != NULL) ? row[12] : (char *)""); bstrncpy(jr->Name, (row[13] != NULL) ? row[13] : "", sizeof(jr->Name)); jr->PriorJobId = str_to_uint64((row[14] !=NULL) ? row[14] : (char *)""); bstrncpy(jr->cRealEndTime, (row[15] != NULL) ? row[15] : "", sizeof(jr->cRealEndTime)); if (jr->JobId == 0) { jr->JobId = str_to_int64(row[16]); } jr->FileSetId = str_to_int64(row[17]); bstrncpy(jr->cSchedTime, (row[18] != NULL) ? row[18] : "", sizeof(jr->cSchedTime)); bstrncpy(jr->cRealEndTime, (row[19] != NULL) ? row[19] : "", sizeof(jr->cRealEndTime)); jr->ReadBytes = str_to_int64(row[20]); jr->StartTime = str_to_utime(jr->cStartTime); jr->SchedTime = str_to_utime(jr->cSchedTime); jr->EndTime = str_to_utime(jr->cEndTime); jr->RealEndTime = str_to_utime(jr->cRealEndTime); jr->HasBase = str_to_int64(row[21]); jr->PurgedFiles = str_to_int64(row[22]); sql_free_result(mdb); retval = true; bail_out: db_unlock(mdb); return retval; } /** * Find VolumeNames for a given JobId * Returns: 0 on error or no Volumes found * number of volumes on success * Volumes are concatenated in VolumeNames * separated by a vertical bar (|) in the order * that they were written. * * Returns: number of volumes on success */ int db_get_job_volume_names(JCR *jcr, B_DB *mdb, JobId_t JobId, POOLMEM **VolumeNames) { SQL_ROW row; char ed1[50]; int retval = 0; int i; int num_rows; db_lock(mdb); /* Get one entry per VolumeName, but "sort" by VolIndex */ Mmsg(mdb->cmd, "SELECT VolumeName,MAX(VolIndex) FROM JobMedia,Media WHERE " "JobMedia.JobId=%s AND JobMedia.MediaId=Media.MediaId " "GROUP BY VolumeName " "ORDER BY 2 ASC", edit_int64(JobId,ed1)); Dmsg1(130, "VolNam=%s\n", mdb->cmd); *VolumeNames[0] = 0; if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); Dmsg1(130, "Num rows=%d\n", num_rows); if (num_rows <= 0) { Mmsg1(mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); retval = 0; } else { retval = num_rows; for (i=0; i < retval; i++) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); retval = 0; break; } else { if (*VolumeNames[0] != 0) { pm_strcat(VolumeNames, "|"); } pm_strcat(VolumeNames, row[0]); } } } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("No Volume for JobId %d found in Catalog.\n"), JobId); } db_unlock(mdb); return retval; } /** * Find Volume parameters for a give JobId * Returns: 0 on error or no Volumes found * number of volumes on success * List of Volumes and start/end file/blocks (malloced structure!) * * Returns: number of volumes on success */ int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, JobId_t JobId, VOL_PARAMS **VolParams) { SQL_ROW row; char ed1[50]; int retval = 0; int i; VOL_PARAMS *Vols = NULL; int num_rows; db_lock(mdb); Mmsg(mdb->cmd, "SELECT VolumeName,MediaType,FirstIndex,LastIndex,StartFile," "JobMedia.EndFile,StartBlock,JobMedia.EndBlock," "Slot,StorageId,InChanger" " FROM JobMedia,Media WHERE JobMedia.JobId=%s" " AND JobMedia.MediaId=Media.MediaId ORDER BY VolIndex,JobMediaId", edit_int64(JobId, ed1)); Dmsg1(130, "VolNam=%s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); Dmsg1(200, "Num rows=%d\n", num_rows); if (num_rows <= 0) { Mmsg1(mdb->errmsg, _("No volumes found for JobId=%d\n"), JobId); retval = 0; } else { retval = num_rows; DBId_t *SId = NULL; if (retval > 0) { *VolParams = Vols = (VOL_PARAMS *)malloc(retval * sizeof(VOL_PARAMS)); SId = (DBId_t *)malloc(retval * sizeof(DBId_t)); } for (i=0; i < retval; i++) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); retval = 0; break; } else { DBId_t StorageId; uint32_t StartBlock, EndBlock, StartFile, EndFile; bstrncpy(Vols[i].VolumeName, row[0], MAX_NAME_LENGTH); bstrncpy(Vols[i].MediaType, row[1], MAX_NAME_LENGTH); Vols[i].FirstIndex = str_to_uint64(row[2]); Vols[i].LastIndex = str_to_uint64(row[3]); StartFile = str_to_uint64(row[4]); EndFile = str_to_uint64(row[5]); StartBlock = str_to_uint64(row[6]); EndBlock = str_to_uint64(row[7]); Vols[i].StartAddr = (((uint64_t)StartFile)<<32) | StartBlock; Vols[i].EndAddr = (((uint64_t)EndFile)<<32) | EndBlock; Vols[i].Slot = str_to_uint64(row[8]); StorageId = str_to_uint64(row[9]); Vols[i].InChanger = str_to_uint64(row[10]); Vols[i].Storage[0] = 0; SId[i] = StorageId; } } for (i=0; i < retval; i++) { if (SId[i] != 0) { Mmsg(mdb->cmd, "SELECT Name from Storage WHERE StorageId=%s", edit_int64(SId[i], ed1)); if (QUERY_DB(jcr, mdb, mdb->cmd)) { if ((row = sql_fetch_row(mdb)) && row[0]) { bstrncpy(Vols[i].Storage, row[0], MAX_NAME_LENGTH); } } } } if (SId) { free(SId); } } sql_free_result(mdb); } db_unlock(mdb); return retval; } /** * Get the number of pool records * * Returns: -1 on failure * number on success */ int db_get_num_pool_records(JCR *jcr, B_DB *mdb) { int retval = 0; db_lock(mdb); Mmsg(mdb->cmd, "SELECT count(*) from Pool"); retval = get_sql_record_max(jcr, mdb); db_unlock(mdb); return retval; } /** * This function returns a list of all the Pool record ids. * The caller must free ids if non-NULL. * * Returns 0: on failure * 1: on success */ int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) { SQL_ROW row; int retval = 0; int i = 0; uint32_t *id; db_lock(mdb); *ids = NULL; Mmsg(mdb->cmd, "SELECT PoolId FROM Pool"); if (QUERY_DB(jcr, mdb, mdb->cmd)) { *num_ids = sql_num_rows(mdb); if (*num_ids > 0) { id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); while ((row = sql_fetch_row(mdb)) != NULL) { id[i++] = str_to_uint64(row[0]); } *ids = id; } sql_free_result(mdb); retval = 1; } else { Mmsg(mdb->errmsg, _("Pool id select failed: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); retval = 0; } db_unlock(mdb); return retval; } /** * This function returns a list of all the Client record ids. * The caller must free ids if non-NULL. * * Returns false: on failure * true: on success */ bool db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[]) { bool retval = false; SQL_ROW row; int i = 0; uint32_t *id; db_lock(mdb); *ids = NULL; Mmsg(mdb->cmd, "SELECT ClientId FROM Client ORDER BY Name"); if (QUERY_DB(jcr, mdb, mdb->cmd)) { *num_ids = sql_num_rows(mdb); if (*num_ids > 0) { id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); while ((row = sql_fetch_row(mdb)) != NULL) { id[i++] = str_to_uint64(row[0]); } *ids = id; } sql_free_result(mdb); retval = true; } else { Mmsg(mdb->errmsg, _("Client id select failed: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } db_unlock(mdb); return retval; } /** * Get Pool Record * If the PoolId is non-zero, we get its record, * otherwise, we search on the PoolName * * Returns: false on failure * true on success */ bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr) { SQL_ROW row; bool ok = false; char ed1[50]; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (pdbr->PoolId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume," "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," "MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId," "ActionOnPurge,MinBlocksize,MaxBlocksize FROM Pool WHERE Pool.PoolId=%s", edit_int64(pdbr->PoolId, ed1)); } else { /* find by name */ mdb->db_escape_string(jcr, esc, pdbr->Name, strlen(pdbr->Name)); Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,AcceptAnyVolume," "AutoPrune,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles," "MaxVolBytes,PoolType,LabelType,LabelFormat,RecyclePoolId,ScratchPoolId," "ActionOnPurge,MinBlocksize,MaxBlocksize FROM Pool WHERE Pool.Name='%s'", esc); } if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 1) { char ed1[30]; Mmsg1(mdb->errmsg, _("More than one Pool!: %s\n"), edit_uint64(num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { pdbr->PoolId = str_to_int64(row[0]); bstrncpy(pdbr->Name, (row[1] != NULL) ? row[1] : "", sizeof(pdbr->Name)); pdbr->NumVols = str_to_int64(row[2]); pdbr->MaxVols = str_to_int64(row[3]); pdbr->UseOnce = str_to_int64(row[4]); pdbr->UseCatalog = str_to_int64(row[5]); pdbr->AcceptAnyVolume = str_to_int64(row[6]); pdbr->AutoPrune = str_to_int64(row[7]); pdbr->Recycle = str_to_int64(row[8]); pdbr->VolRetention = str_to_int64(row[9]); pdbr->VolUseDuration = str_to_int64(row[10]); pdbr->MaxVolJobs = str_to_int64(row[11]); pdbr->MaxVolFiles = str_to_int64(row[12]); pdbr->MaxVolBytes = str_to_uint64(row[13]); bstrncpy(pdbr->PoolType, (row[14] != NULL) ? row[14] : "", sizeof(pdbr->PoolType)); pdbr->LabelType = str_to_int64(row[15]); bstrncpy(pdbr->LabelFormat, (row[16] != NULL) ? row[16] : "", sizeof(pdbr->LabelFormat)); pdbr->RecyclePoolId = str_to_int64(row[17]); pdbr->ScratchPoolId = str_to_int64(row[18]); pdbr->ActionOnPurge = str_to_int32(row[19]); pdbr->MinBlocksize = str_to_int32(row[20]); pdbr->MaxBlocksize = str_to_int32(row[21]); ok = true; } } sql_free_result(mdb); } if (ok) { uint32_t NumVols; Mmsg(mdb->cmd, "SELECT count(*) from Media WHERE PoolId=%s", edit_int64(pdbr->PoolId, ed1)); NumVols = get_sql_record_max(jcr, mdb); Dmsg2(400, "Actual NumVols=%d Pool NumVols=%d\n", NumVols, pdbr->NumVols); if (NumVols != pdbr->NumVols) { pdbr->NumVols = NumVols; ok = db_update_pool_record(jcr, mdb, pdbr); } } else { Mmsg(mdb->errmsg, _("Pool record not found in Catalog.\n")); } db_unlock(mdb); return ok; } /** * Get Client Record * If the ClientId is non-zero, we get its record, * otherwise, we search on the Client Name * * Returns: false on failure * true on success */ bool db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) { bool retval = false; SQL_ROW row; char ed1[50]; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (cdbr->ClientId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention " "FROM Client WHERE Client.ClientId=%s", edit_int64(cdbr->ClientId, ed1)); } else { /* find by name */ mdb->db_escape_string(jcr, esc, cdbr->Name, strlen(cdbr->Name)); Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,JobRetention " "FROM Client WHERE Client.Name='%s'", esc); } if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 1) { Mmsg1(mdb->errmsg, _("More than one Client!: %s\n"), edit_uint64(num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { cdbr->ClientId = str_to_int64(row[0]); bstrncpy(cdbr->Name, (row[1] != NULL) ? row[1] : "", sizeof(cdbr->Name)); bstrncpy(cdbr->Uname, (row[2] != NULL) ? row[2] : "", sizeof(cdbr->Uname)); cdbr->AutoPrune = str_to_int64(row[3]); cdbr->FileRetention = str_to_int64(row[4]); cdbr->JobRetention = str_to_int64(row[5]); retval = true; } } else { Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n")); } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("Client record not found in Catalog.\n")); } db_unlock(mdb); return retval; } /** * Get Counter Record * * Returns: false on failure * true on success */ bool db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) { bool retval = false; SQL_ROW row; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, cr->Counter, strlen(cr->Counter)); Mmsg(mdb->cmd, select_counter_values[mdb->db_get_type_index()], esc); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); /* If more than one, report error, but return first row */ if (num_rows > 1) { Mmsg1(mdb->errmsg, _("More than one Counter!: %d\n"), num_rows); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } if (num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching Counter row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); goto bail_out; } cr->MinValue = str_to_int64(row[0]); cr->MaxValue = str_to_int64(row[1]); cr->CurrentValue = str_to_int64(row[2]); if (row[3]) { bstrncpy(cr->WrapCounter, row[3], sizeof(cr->WrapCounter)); } else { cr->WrapCounter[0] = 0; } sql_free_result(mdb); retval = true; goto bail_out; } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("Counter record: %s not found in Catalog.\n"), cr->Counter); } bail_out: db_unlock(mdb); return retval; } /** * Get FileSet Record * If the FileSetId is non-zero, we get its record, * otherwise, we search on the name * * Returns: 0 on failure * id on success */ int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr) { SQL_ROW row; int retval = 0; char ed1[50]; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (fsr->FileSetId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet " "WHERE FileSetId=%s", edit_int64(fsr->FileSetId, ed1)); } else { /* find by name */ mdb->db_escape_string(jcr, esc, fsr->FileSet, strlen(fsr->FileSet)); Mmsg(mdb->cmd, "SELECT FileSetId,FileSet,MD5,CreateTime FROM FileSet " "WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1", esc); } if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows > 1) { char ed1[30]; Mmsg1(mdb->errmsg, _("Error got %s FileSets but expected only one!\n"), edit_uint64(num_rows, ed1)); sql_data_seek(mdb, num_rows-1); } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("FileSet record \"%s\" not found.\n"), fsr->FileSet); } else { fsr->FileSetId = str_to_int64(row[0]); bstrncpy(fsr->FileSet, (row[1] != NULL) ? row[1] : "", sizeof(fsr->FileSet)); bstrncpy(fsr->MD5, (row[2] != NULL) ? row[2] : "", sizeof(fsr->MD5)); bstrncpy(fsr->cCreateTime, (row[3] != NULL) ? row[3] : "", sizeof(fsr->cCreateTime)); retval = fsr->FileSetId; } sql_free_result(mdb); } else { Mmsg(mdb->errmsg, _("FileSet record not found in Catalog.\n")); } db_unlock(mdb); return retval; } /** * Get the number of Media records * * Returns: -1 on failure * number on success */ int db_get_num_media_records(JCR *jcr, B_DB *mdb) { int retval = 0; db_lock(mdb); Mmsg(mdb->cmd, "SELECT count(*) from Media"); retval = get_sql_record_max(jcr, mdb); db_unlock(mdb); return retval; } /** * This function returns a list of all the Media record ids for * the current Pool, the correct Media Type, Recyle, Enabled, StorageId, VolBytes and * volumes or VolumeName if specified. Comma separated list of volumes takes precedence * over VolumeName. The caller must free ids if non-NULL. * * Returns false: on failure * true: on success */ bool db_get_media_ids(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr, POOL_MEM &volumes, int *num_ids, uint32_t *ids[]) { SQL_ROW row; int i = 0; uint32_t *id; char ed1[50]; bool ok = false; char esc[MAX_NAME_LENGTH * 2 + 1]; bool have_volumes = false; POOL_MEM buf(PM_MESSAGE); db_lock(mdb); *ids = NULL; if (*volumes.c_str()) { have_volumes = true; } Mmsg(mdb->cmd, "SELECT DISTINCT MediaId FROM Media WHERE Recycle=%d AND Enabled=%d ", mr->Recycle, mr->Enabled); if (*mr->MediaType) { db_escape_string(jcr, mdb, esc, mr->MediaType, strlen(mr->MediaType)); Mmsg(buf, "AND MediaType='%s' ", esc); pm_strcat(mdb->cmd, buf.c_str()); } if (mr->StorageId) { Mmsg(buf, "AND StorageId=%s ", edit_uint64(mr->StorageId, ed1)); pm_strcat(mdb->cmd, buf.c_str()); } if (mr->PoolId) { Mmsg(buf, "AND PoolId=%s ", edit_uint64(mr->PoolId, ed1)); pm_strcat(mdb->cmd, buf.c_str()); } if (mr->VolBytes) { Mmsg(buf, "AND VolBytes > %s ", edit_uint64(mr->VolBytes, ed1)); pm_strcat(mdb->cmd, buf.c_str()); } if (*mr->VolStatus) { db_escape_string(jcr, mdb, esc, mr->VolStatus, strlen(mr->VolStatus)); Mmsg(buf, "AND VolStatus = '%s' ", esc); pm_strcat(mdb->cmd, buf.c_str()); } if (*mr->VolumeName && !have_volumes) { db_escape_string(jcr, mdb, esc, mr->VolumeName, strlen(mr->VolumeName)); Mmsg(buf, "AND VolumeName = '%s' ", esc); pm_strcat(mdb->cmd, buf.c_str()); } if (have_volumes) { Mmsg(buf, "AND VolumeName IN (%s) ", volumes.c_str()); pm_strcat(mdb->cmd, buf.c_str()); } Dmsg1(100, "q=%s\n", mdb->cmd); if (QUERY_DB(jcr, mdb, mdb->cmd)) { *num_ids = sql_num_rows(mdb); if (*num_ids > 0) { id = (uint32_t *)malloc(*num_ids * sizeof(uint32_t)); while ((row = sql_fetch_row(mdb)) != NULL) { id[i++] = str_to_uint64(row[0]); } *ids = id; } sql_free_result(mdb); ok = true; } else { Mmsg(mdb->errmsg, _("Media id select failed: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); ok = false; } db_unlock(mdb); return ok; } /** * This function returns a list of all the DBIds that are returned * for the query. * * Returns false: on failure * true: on success */ bool db_get_query_dbids(JCR *jcr, B_DB *mdb, POOL_MEM &query, dbid_list &ids) { SQL_ROW row; int i = 0; bool ok = false; db_lock(mdb); ids.num_ids = 0; if (QUERY_DB(jcr, mdb, query.c_str())) { ids.num_ids = sql_num_rows(mdb); if (ids.num_ids > 0) { if (ids.max_ids < ids.num_ids) { free(ids.DBId); ids.DBId = (DBId_t *)malloc(ids.num_ids * sizeof(DBId_t)); } while ((row = sql_fetch_row(mdb)) != NULL) { ids.DBId[i++] = str_to_uint64(row[0]); } } sql_free_result(mdb); ok = true; } else { Mmsg(mdb->errmsg, _("query dbids failed: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); ok = false; } db_unlock(mdb); return ok; } /** * Get Media Record * * Returns: false: on failure * true: on success */ bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { bool retval = false; SQL_ROW row; char ed1[50]; int num_rows; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (mr->MediaId == 0 && mr->VolumeName[0] == 0) { Mmsg(mdb->cmd, "SELECT count(*) from Media"); mr->MediaId = get_sql_record_max(jcr, mdb); retval = true; goto bail_out; } if (mr->MediaId != 0) { /* find by id */ Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs," "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime," "ActionOnPurge,EncryptionKey,MinBlocksize,MaxBlocksize " "FROM Media WHERE MediaId=%s", edit_int64(mr->MediaId, ed1)); } else { /* find by name */ mdb->db_escape_string(jcr, esc, mr->VolumeName, strlen(mr->VolumeName)); Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," "MediaType,VolStatus,PoolId,VolRetention,VolUseDuration,MaxVolJobs," "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime," "ActionOnPurge,EncryptionKey,MinBlocksize,MaxBlocksize " "FROM Media WHERE VolumeName='%s'", esc); } if (QUERY_DB(jcr, mdb, mdb->cmd)) { char ed1[50]; num_rows = sql_num_rows(mdb); if (num_rows > 1) { Mmsg1(mdb->errmsg, _("More than one Volume!: %s\n"), edit_uint64(num_rows, ed1)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { /* return values */ mr->MediaId = str_to_int64(row[0]); bstrncpy(mr->VolumeName, (row[1] != NULL) ? row[1] : "", sizeof(mr->VolumeName)); mr->VolJobs = str_to_int64(row[2]); mr->VolFiles = str_to_int64(row[3]); mr->VolBlocks = str_to_int64(row[4]); mr->VolBytes = str_to_uint64(row[5]); mr->VolMounts = str_to_int64(row[6]); mr->VolErrors = str_to_int64(row[7]); mr->VolWrites = str_to_int64(row[8]); mr->MaxVolBytes = str_to_uint64(row[9]); mr->VolCapacityBytes = str_to_uint64(row[10]); bstrncpy(mr->MediaType, (row[11] != NULL) ? row[11] : "", sizeof(mr->MediaType)); bstrncpy(mr->VolStatus, (row[12] != NULL) ? row[12] : "", sizeof(mr->VolStatus)); mr->PoolId = str_to_int64(row[13]); mr->VolRetention = str_to_uint64(row[14]); mr->VolUseDuration = str_to_uint64(row[15]); mr->MaxVolJobs = str_to_int64(row[16]); mr->MaxVolFiles = str_to_int64(row[17]); mr->Recycle = str_to_int64(row[18]); mr->Slot = str_to_int64(row[19]); bstrncpy(mr->cFirstWritten, (row[20] != NULL) ? row[20] : "", sizeof(mr->cFirstWritten)); mr->FirstWritten = (time_t)str_to_utime(mr->cFirstWritten); bstrncpy(mr->cLastWritten, (row[21] != NULL) ? row[21] : "", sizeof(mr->cLastWritten)); mr->LastWritten = (time_t)str_to_utime(mr->cLastWritten); mr->InChanger = str_to_uint64(row[22]); mr->EndFile = str_to_uint64(row[23]); mr->EndBlock = str_to_uint64(row[24]); mr->LabelType = str_to_int64(row[25]); bstrncpy(mr->cLabelDate, (row[26] != NULL) ? row[26] : "", sizeof(mr->cLabelDate)); mr->LabelDate = (time_t)str_to_utime(mr->cLabelDate); mr->StorageId = str_to_int64(row[27]); mr->Enabled = str_to_int64(row[28]); mr->LocationId = str_to_int64(row[29]); mr->RecycleCount = str_to_int64(row[30]); bstrncpy(mr->cInitialWrite, (row[31] != NULL) ? row[31] : "", sizeof(mr->cInitialWrite)); mr->InitialWrite = (time_t)str_to_utime(mr->cInitialWrite); mr->ScratchPoolId = str_to_int64(row[32]); mr->RecyclePoolId = str_to_int64(row[33]); mr->VolReadTime = str_to_int64(row[34]); mr->VolWriteTime = str_to_int64(row[35]); mr->ActionOnPurge = str_to_int32(row[36]); bstrncpy(mr->EncrKey, (row[37] != NULL) ? row[37] : "", sizeof(mr->EncrKey)); mr->MinBlocksize = str_to_int32(row[38]); mr->MaxBlocksize = str_to_int32(row[39]); retval = true; } } else { if (mr->MediaId != 0) { Mmsg1(mdb->errmsg, _("Media record MediaId=%s not found.\n"), edit_int64(mr->MediaId, ed1)); } else { Mmsg1(mdb->errmsg, _("Media record for Volume \"%s\" not found.\n"), mr->VolumeName); } } sql_free_result(mdb); } else { if (mr->MediaId != 0) { Mmsg(mdb->errmsg, _("Media record for MediaId=%u not found in Catalog.\n"), mr->MediaId); } else { Mmsg(mdb->errmsg, _("Media record for Vol=%s not found in Catalog.\n"), mr->VolumeName); } } bail_out: db_unlock(mdb); return retval; } /* Remove all MD5 from a query (can save lot of memory with many files) */ static void strip_md5(char *q) { char *p = q; while ((p = strstr(p, ", MD5"))) { memset(p, ' ', 5 * sizeof(char)); } } /** * Find the last "accurate" backup state (that can take deleted files in * account) * 1) Get all files with jobid in list (F subquery) * Get all files in BaseFiles with jobid in list * 2) Take only the last version of each file (Temp subquery) => accurate list * is ok * 3) Join the result to file table to get fileindex, jobid and lstat information * * TODO: See if we can do the SORT only if needed (as an argument) */ bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids, bool use_md5, bool use_delta, DB_RESULT_HANDLER *result_handler, void *ctx) { POOL_MEM query(PM_FNAME); POOL_MEM query2(PM_FNAME); if (!*jobids) { db_lock(mdb); Mmsg(mdb->errmsg, _("ERR=JobIds are empty\n")); db_unlock(mdb); return false; } if (use_delta) { Mmsg(query2, select_recent_version_with_basejob_and_delta[db_get_type_index(mdb)], jobids, jobids, jobids, jobids); } else { Mmsg(query2, select_recent_version_with_basejob[db_get_type_index(mdb)], jobids, jobids, jobids, jobids); } /* * BSR code is optimized for JobId sorted, with Delta, we need to get * them ordered by date. JobTDate and JobId can be mixed if using Copy * or Migration */ Mmsg(query, "SELECT Path.Path, Filename.Name, T1.FileIndex, T1.JobId, LStat, DeltaSeq, MD5 " "FROM ( %s ) AS T1 " "JOIN Filename ON (Filename.FilenameId = T1.FilenameId) " "JOIN Path ON (Path.PathId = T1.PathId) " "WHERE FileIndex > 0 " "ORDER BY T1.JobTDate, FileIndex ASC",/* Return sorted by JobTDate */ /* FileIndex for restore code */ query2.c_str()); if (!use_md5) { strip_md5(query.c_str()); } Dmsg1(100, "q=%s\n", query.c_str()); return db_big_sql_query(mdb, query.c_str(), result_handler, ctx); } /** * This procedure gets the base jobid list used by jobids, */ bool db_get_used_base_jobids(JCR *jcr, B_DB *mdb, POOLMEM *jobids, db_list_ctx *result) { POOL_MEM query(PM_FNAME); Mmsg(query, "SELECT DISTINCT BaseJobId " " FROM Job JOIN BaseFiles USING (JobId) " " WHERE Job.HasBase = 1 " " AND Job.JobId IN (%s) ", jobids); return db_sql_query(mdb, query.c_str(), db_list_handler, result); } /** * The decision do change an incr/diff was done before * Full : do nothing * Differential : get the last full id * Incremental : get the last full + last diff + last incr(s) ids * * If you specify jr->StartTime, it will be used to limit the search * in the time. (usually now) * * TODO: look and merge from ua_restore.c */ bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, db_list_ctx *jobids) { bool retval = false; char clientid[50], jobid[50], filesetid[50]; char date[MAX_TIME_LENGTH]; POOL_MEM query(PM_FNAME); /* Take the current time as upper limit if nothing else specified */ utime_t StartTime = (jr->StartTime) ? jr->StartTime : time(NULL); bstrutime(date, sizeof(date), StartTime + 1); jobids->reset(); /* First, find the last good Full backup for this job/client/fileset */ Mmsg(query, create_temp_accurate_jobids[db_get_type_index(mdb)], edit_uint64(jcr->JobId, jobid), edit_uint64(jr->ClientId, clientid), date, edit_uint64(jr->FileSetId, filesetid)); if (!db_sql_query(mdb, query.c_str())) { goto bail_out; } if (jr->JobLevel == L_INCREMENTAL || jr->JobLevel == L_VIRTUAL_FULL) { /* Now, find the last differential backup after the last full */ Mmsg(query, "INSERT INTO btemp3%s (JobId, StartTime, EndTime, JobTDate, PurgedFiles) " "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles " "FROM Job JOIN FileSet USING (FileSetId) " "WHERE ClientId = %s " "AND Level='D' AND JobStatus IN ('T','W') AND Type='B' " "AND StartTime > (SELECT EndTime FROM btemp3%s ORDER BY EndTime DESC LIMIT 1) " "AND StartTime < '%s' " "AND FileSet.FileSet= (SELECT FileSet FROM FileSet WHERE FileSetId = %s) " "ORDER BY Job.JobTDate DESC LIMIT 1 ", jobid, clientid, jobid, date, filesetid); if (!db_sql_query(mdb, query.c_str())) { goto bail_out; } /* We just have to take all incremental after the last Full/Diff */ Mmsg(query, "INSERT INTO btemp3%s (JobId, StartTime, EndTime, JobTDate, PurgedFiles) " "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles " "FROM Job JOIN FileSet USING (FileSetId) " "WHERE ClientId = %s " "AND Level='I' AND JobStatus IN ('T','W') AND Type='B' " "AND StartTime > (SELECT EndTime FROM btemp3%s ORDER BY EndTime DESC LIMIT 1) " "AND StartTime < '%s' " "AND FileSet.FileSet= (SELECT FileSet FROM FileSet WHERE FileSetId = %s) " "ORDER BY Job.JobTDate DESC ", jobid, clientid, jobid, date, filesetid); if (!db_sql_query(mdb, query.c_str())) { goto bail_out; } } /* build a jobid list ie: 1,2,3,4 */ Mmsg(query, "SELECT JobId FROM btemp3%s ORDER by JobTDate", jobid); db_sql_query(mdb, query.c_str(), db_list_handler, jobids); Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids->list); retval = true; bail_out: Mmsg(query, "DROP TABLE btemp3%s", jobid); db_sql_query(mdb, query.c_str()); return retval; } bool db_get_base_file_list(JCR *jcr, B_DB *mdb, bool use_md5, DB_RESULT_HANDLER *result_handler, void *ctx) { POOL_MEM query(PM_FNAME); Mmsg(query, "SELECT Path, Name, FileIndex, JobId, LStat, 0 As DeltaSeq, MD5 " "FROM new_basefile%lld ORDER BY JobId, FileIndex ASC", (uint64_t) jcr->JobId); if (!use_md5) { strip_md5(query.c_str()); } return db_big_sql_query(mdb, query.c_str(), result_handler, ctx); } bool db_get_base_jobid(JCR *jcr, B_DB *mdb, JOB_DBR *jr, JobId_t *jobid) { POOL_MEM query(PM_FNAME); utime_t StartTime; db_int64_ctx lctx; char date[MAX_TIME_LENGTH]; char esc[MAX_ESCAPE_NAME_LENGTH]; bool retval = false; // char clientid[50], filesetid[50]; *jobid = 0; lctx.count = 0; lctx.value = 0; StartTime = (jr->StartTime) ? jr->StartTime : time(NULL); bstrutime(date, sizeof(date), StartTime + 1); mdb->db_escape_string(jcr, esc, jr->Name, strlen(jr->Name)); /* we can take also client name, fileset, etc... */ Mmsg(query, "SELECT JobId, Job, StartTime, EndTime, JobTDate, PurgedFiles " "FROM Job " // "JOIN FileSet USING (FileSetId) JOIN Client USING (ClientId) " "WHERE Job.Name = '%s' " "AND Level='B' AND JobStatus IN ('T','W') AND Type='B' " // "AND FileSet.FileSet= '%s' " // "AND Client.Name = '%s' " "AND StartTime<'%s' " "ORDER BY Job.JobTDate DESC LIMIT 1", esc, // edit_uint64(jr->ClientId, clientid), // edit_uint64(jr->FileSetId, filesetid)); date); Dmsg1(10, "db_get_base_jobid q=%s\n", query.c_str()); if (!db_sql_query(mdb, query.c_str(), db_int64_handler, &lctx)) { goto bail_out; } *jobid = (JobId_t) lctx.value; Dmsg1(10, "db_get_base_jobid=%lld\n", *jobid); retval = true; bail_out: return retval; } /* * Get JobIds associated with a volume */ bool db_get_volume_jobids(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr, db_list_ctx *lst) { char ed1[50]; bool retval; db_lock(mdb); Mmsg(mdb->cmd, "SELECT DISTINCT JobId FROM JobMedia WHERE MediaId=%s", edit_int64(mr->MediaId, ed1)); retval = db_sql_query(mdb, mdb->cmd, db_list_handler, lst); db_unlock(mdb); return retval; } /** * This function returns the sum of all the Clients JobBytes. * * Returns false: on failure * true: on success */ bool db_get_quota_jobbytes(JCR *jcr, B_DB *mdb, JOB_DBR *jr, utime_t JobRetention) { SQL_ROW row; int num_rows; char dt[MAX_TIME_LENGTH]; char ed1[50], ed2[50]; bool retval = false; time_t now, schedtime; /* * Determine the first schedtime we are interested in. */ now = time(NULL); schedtime = now - JobRetention; /* * Bugfix, theres a small timing bug in the scheduler. * Add 5 seconds to the schedtime to ensure the * last job from the job retention gets excluded. */ schedtime += 5; bstrutime(dt, sizeof(dt), schedtime); db_lock(mdb); Mmsg(mdb->cmd, get_quota_jobbytes[mdb->db_get_type_index()], edit_uint64(jr->ClientId, ed1), edit_uint64(jr->JobId, ed2), dt); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 1) { row = sql_fetch_row(mdb); jr->JobSumTotalBytes = str_to_uint64(row[0]); } else if (num_rows < 1) { jr->JobSumTotalBytes = 0; } sql_free_result(mdb); retval = true; } else { Mmsg(mdb->errmsg, _("JobBytes sum select failed: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } db_unlock(mdb); return retval; } /** * This function returns the sum of all the Clients JobBytes of non failed jobs. * * Returns false: on failure * true: on success */ bool db_get_quota_jobbytes_nofailed(JCR *jcr, B_DB *mdb, JOB_DBR *jr, utime_t JobRetention) { SQL_ROW row; char ed1[50], ed2[50]; int num_rows; char dt[MAX_TIME_LENGTH]; bool retval = false; time_t now, schedtime; /* * Determine the first schedtime we are interested in. */ now = time(NULL); schedtime = now - JobRetention; /* * Bugfix, theres a small timing bug in the scheduler. * Add 5 seconds to the schedtime to ensure the * last job from the job retention gets excluded. */ schedtime += 5; bstrutime(dt, sizeof(dt), schedtime); db_lock(mdb); Mmsg(mdb->cmd, get_quota_jobbytes_nofailed[mdb->db_get_type_index()], edit_uint64(jr->ClientId, ed1), edit_uint64(jr->JobId, ed2), dt); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 1) { row = sql_fetch_row(mdb); jr->JobSumTotalBytes = str_to_uint64(row[0]); } else if (num_rows < 1) { jr->JobSumTotalBytes = 0; } sql_free_result(mdb); retval = true; } else { Mmsg(mdb->errmsg, _("JobBytes sum select failed: ERR=%s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); } db_unlock(mdb); return retval; } /** * Fetch the quota value and grace time for a quota. * Returns false: on failure * true: on success */ bool db_get_quota_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr) { SQL_ROW row; char ed1[50]; int num_rows; bool retval = false; db_lock(mdb); Mmsg(mdb->cmd, "SELECT GraceTime, QuotaLimit " "FROM Quota " "WHERE ClientId = %s", edit_int64(cdbr->ClientId, ed1)); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); } else { cdbr->GraceTime = str_to_uint64(row[0]); cdbr->QuotaLimit = str_to_int64(row[1]); sql_free_result(mdb); retval = true; } } else { Mmsg(mdb->errmsg, _("Quota record not found in Catalog.\n")); sql_free_result(mdb); } } else { Mmsg(mdb->errmsg, _("Quota record not found in Catalog.\n")); } db_unlock(mdb); return retval; } /** * Fetch the NDMP Dump Level value. * * Returns dumplevel on success * 0: on failure */ int db_get_ndmp_level_mapping(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *filesystem) { SQL_ROW row; char ed1[50], ed2[50]; int num_rows; int dumplevel = 0; db_lock(mdb); mdb->esc_name = check_pool_memory_size(mdb->esc_name, strlen(filesystem) * 2 + 1); db_escape_string(jcr, mdb, mdb->esc_name, filesystem, strlen(filesystem)); Mmsg(mdb->cmd, "SELECT DumpLevel FROM NDMPLevelMap WHERE " "ClientId='%s' AND FileSetId='%s' AND FileSystem='%s'", edit_uint64(jr->ClientId, ed1), edit_uint64(jr->FileSetId, ed2), mdb->esc_name); if (QUERY_DB(jcr, mdb, mdb->cmd)) { num_rows = sql_num_rows(mdb); if (num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); goto bail_out; } else { dumplevel = str_to_uint64(row[0]); dumplevel++; /* select next dumplevel */ sql_free_result(mdb); goto bail_out; } } else { Mmsg(mdb->errmsg, _("NDMP Dump Level record not found in Catalog.\n")); sql_free_result(mdb); goto bail_out; } } else { Mmsg(mdb->errmsg, _("NDMP Dump Level record not found in Catalog.\n")); goto bail_out; } bail_out: db_unlock(mdb); return dumplevel; } /** * Fetch the NDMP Job Environment Strings * * Returns false: on failure * true: on success */ bool db_get_ndmp_environment_string(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_RESULT_HANDLER *result_handler, void *ctx) { POOL_MEM query(PM_FNAME); char ed1[50], ed2[50]; db_int64_ctx lctx; JobId_t JobId; bool retval = false; lctx.count = 0; lctx.value = 0; /* * Lookup the JobId */ Mmsg(query, "SELECT JobId FROM Job " "WHERE VolSessionId = '%s' " "AND VolSessionTime = '%s'", edit_uint64(jr->VolSessionId, ed1), edit_uint64(jr->VolSessionTime, ed2)); if (!db_sql_query(mdb, query.c_str(), db_int64_handler, &lctx)) { goto bail_out; } JobId = (JobId_t) lctx.value; /* * Lookup all environment settings belonging to this JobId and FileIndex. */ Mmsg(query, "SELECT EnvName, EnvValue FROM NDMPJobEnvironment " "WHERE JobId='%s' " "AND FileIndex='%s'", edit_uint64(JobId, ed1), edit_uint64(jr->FileIndex, ed2)); retval = db_sql_query(mdb, query.c_str(), result_handler, ctx); bail_out: return retval; } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_glue.c000066400000000000000000000126021263011562700201410ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Glue code for the catalog refactoring. * * Written by Marco van Wieringen, November 2009 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Glue Routines * Wrappers around class methods. * * ----------------------------------------------------------------------- */ bool db_match_database(B_DB *mdb, const char *db_driver, const char *db_name, const char *db_address, int db_port) { return mdb->db_match_database(db_driver, db_name, db_address, db_port); } B_DB *db_clone_database_connection(B_DB *mdb, JCR *jcr, bool mult_db_connections, bool get_pooled_connection, bool need_private) { return mdb->db_clone_database_connection(jcr, mult_db_connections, get_pooled_connection, need_private); } const char *db_get_type(B_DB *mdb) { return mdb->db_get_type(); } int db_get_type_index(B_DB *mdb) { return mdb->db_get_type_index(); } bool db_open_database(JCR *jcr, B_DB *mdb) { return mdb->db_open_database(jcr); } void db_close_database(JCR *jcr, B_DB *mdb) { if (mdb) { mdb->db_close_database(jcr); } } bool db_validate_connection(B_DB *mdb) { return mdb->db_validate_connection(); } void db_thread_cleanup(B_DB *mdb) { mdb->db_thread_cleanup(); } void db_escape_string(JCR *jcr, B_DB *mdb, char *snew, char *old, int len) { mdb->db_escape_string(jcr, snew, old, len); } char *db_escape_object(JCR *jcr, B_DB *mdb, char *old, int len) { return mdb->db_escape_object(jcr, old, len); } void db_unescape_object(JCR *jcr, B_DB *mdb, char *from, int32_t expected_len, POOLMEM **dest, int32_t *len) { mdb->db_unescape_object(jcr, from, expected_len, dest, len); } void db_start_transaction(JCR *jcr, B_DB *mdb) { mdb->db_start_transaction(jcr); } void db_end_transaction(JCR *jcr, B_DB *mdb) { mdb->db_end_transaction(jcr); } bool db_sql_query(B_DB *mdb, const char *query, int flags) { mdb->errmsg[0] = 0; return mdb->db_sql_query(query, flags); } bool db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { mdb->errmsg[0] = 0; return mdb->db_sql_query(query, result_handler, ctx); } bool db_big_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { mdb->errmsg[0] = 0; return mdb->db_big_sql_query(query, result_handler, ctx); } void sql_free_result(B_DB *mdb) { ((B_DB_PRIV *)mdb)->sql_free_result(); } SQL_ROW sql_fetch_row(B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_fetch_row(); } bool sql_query(B_DB *mdb, const char *query, int flags) { mdb->errmsg[0] = 0; return ((B_DB_PRIV *)mdb)->sql_query(query, flags); } const char *sql_strerror(B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_strerror(); } int sql_num_rows(B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_num_rows(); } void sql_data_seek(B_DB *mdb, int row) { ((B_DB_PRIV *)mdb)->sql_data_seek(row); } int sql_affected_rows(B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_affected_rows(); } uint64_t sql_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name) { return ((B_DB_PRIV *)mdb)->sql_insert_autokey_record(query, table_name); } void sql_field_seek(B_DB *mdb, int field) { ((B_DB_PRIV *)mdb)->sql_field_seek(field); } SQL_FIELD *sql_fetch_field(B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_fetch_field(); } int sql_num_fields(B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_num_fields(); } bool sql_field_is_not_null(B_DB *mdb, int field_type) { return ((B_DB_PRIV *)mdb)->sql_field_is_not_null(field_type); } bool sql_field_is_numeric(B_DB *mdb, int field_type) { return ((B_DB_PRIV *)mdb)->sql_field_is_numeric(field_type); } bool sql_batch_start(JCR *jcr, B_DB *mdb) { return ((B_DB_PRIV *)mdb)->sql_batch_start(jcr); } bool sql_batch_end(JCR *jcr, B_DB *mdb, const char *error) { return ((B_DB_PRIV *)mdb)->sql_batch_end(jcr, error); } bool sql_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { return ((B_DB_PRIV *)mdb)->sql_batch_insert(jcr, ar); } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_glue.h000066400000000000000000000073441263011562700201550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SQL_GLUE_H_ #define __SQL_GLUE_H_ 1 /* * Prototypes for entry points into the different backends. */ B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections = false, bool disable_batch_insert = false, bool is_private = false); /* * Glue functions from sql_glue.c */ bool db_match_database(B_DB *mdb, const char *db_driver, const char *db_name, const char *db_address, int db_port); B_DB *db_clone_database_connection(B_DB *mdb, JCR *jcr, bool mult_db_connections, bool get_pooled_connection = true, bool need_private = false); int db_get_type_index(B_DB *mdb); const char *db_get_type(B_DB *mdb); bool db_open_database(JCR *jcr, B_DB *mdb); void db_close_database(JCR *jcr, B_DB *mdb); bool db_validate_connection(B_DB *mdb); void db_thread_cleanup(B_DB *mdb); void db_escape_string(JCR *jcr, B_DB *mdb, char *snew, char *old, int len); char *db_escape_object(JCR *jcr, B_DB *mdb, char *old, int len); void db_unescape_object(JCR *jcr, B_DB *mdb, char *from, int32_t expected_len, POOLMEM **dest, int32_t *len); void db_start_transaction(JCR *jcr, B_DB *mdb); void db_end_transaction(JCR *jcr, B_DB *mdb); bool db_sql_query(B_DB *mdb, const char *query, int flags=0); bool db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); bool db_big_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx); #ifdef _BDB_PRIV_INTERFACE_ void sql_free_result(B_DB *mdb); SQL_ROW sql_fetch_row(B_DB *mdb); bool sql_query(B_DB *mdb, const char *query, int flags=0); const char *sql_strerror(B_DB *mdb); int sql_num_rows(B_DB *mdb); void sql_data_seek(B_DB *mdb, int row); int sql_affected_rows(B_DB *mdb); uint64_t sql_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name); void sql_field_seek(B_DB *mdb, int field); SQL_FIELD *sql_fetch_field(B_DB *mdb); int sql_num_fields(B_DB *mdb); bool sql_field_is_not_null(B_DB *mdb, int field_type); bool sql_field_is_numeric(B_DB *mdb, int field_type); bool sql_batch_start(JCR *jcr, B_DB *mdb); bool sql_batch_end(JCR *jcr, B_DB *mdb, const char *error); bool sql_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); #endif /* _BDB_PRIV_INTERFACE_ */ #endif /* __SQL_GLUE_H_ */ bareos-Release-14.2.6/src/cats/sql_list.c000066400000000000000000000411521263011562700201620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database List records interface routines * * Kern Sibbald, March 2000 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* * Submit general SQL query */ bool db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query, DB_LIST_HANDLER *sendit, void *ctx, bool verbose, e_list_type type) { bool retval = false; db_lock(mdb); if (!sql_query(mdb, query, QF_STORE_RESULT)) { Mmsg(mdb->errmsg, _("Query failed: %s\n"), sql_strerror(mdb)); if (verbose) { sendit(ctx, mdb->errmsg); } goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); retval = true; bail_out: db_unlock(mdb); return retval; } void db_list_pool_records(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, pdbr->Name, strlen(pdbr->Name)); if (type == VERT_LIST) { if (pdbr->Name[0] != 0) { Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog," "AcceptAnyVolume,VolRetention,VolUseDuration,MaxVolJobs,MaxVolBytes," "AutoPrune,Recycle,PoolType,LabelFormat,Enabled,ScratchPoolId," "RecyclePoolId,LabelType " " FROM Pool WHERE Name='%s'", esc); } else { Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog," "AcceptAnyVolume,VolRetention,VolUseDuration,MaxVolJobs,MaxVolBytes," "AutoPrune,Recycle,PoolType,LabelFormat,Enabled,ScratchPoolId," "RecyclePoolId,LabelType " " FROM Pool ORDER BY PoolId"); } } else { if (pdbr->Name[0] != 0) { Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,PoolType,LabelFormat " "FROM Pool WHERE Name='%s'", esc); } else { Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,PoolType,LabelFormat " "FROM Pool ORDER BY PoolId"); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); bail_out: db_unlock(mdb); } void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { db_lock(mdb); if (type == VERT_LIST) { Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention," "JobRetention " "FROM Client ORDER BY ClientId"); } else { Mmsg(mdb->cmd, "SELECT ClientId,Name,FileRetention,JobRetention " "FROM Client ORDER BY ClientId"); } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); bail_out: db_unlock(mdb); } /* * If VolumeName is non-zero, list the record for that Volume * otherwise, list the Volumes in the Pool specified by PoolId */ void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char ed1[50]; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, mdbr->VolumeName, strlen(mdbr->VolumeName)); if (type == VERT_LIST) { if (mdbr->VolumeName[0] != 0) { Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId," "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs," "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites," "VolCapacityBytes,VolStatus,Enabled,Recycle,VolRetention," "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger," "EndFile,EndBlock,LabelType,StorageId,DeviceId," "LocationId,RecycleCount,InitialWrite,ScratchPoolId,RecyclePoolId, " "Comment" " FROM Media WHERE Media.VolumeName='%s'", esc); } else { Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId," "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs," "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites," "VolCapacityBytes,VolStatus,Enabled,Recycle,VolRetention," "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger," "EndFile,EndBlock,LabelType,StorageId,DeviceId," "LocationId,RecycleCount,InitialWrite,ScratchPoolId,RecyclePoolId, " "Comment" " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", edit_int64(mdbr->PoolId, ed1)); } } else { if (mdbr->VolumeName[0] != 0) { Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,Enabled," "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten " "FROM Media WHERE Media.VolumeName='%s'", esc); } else { Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,Enabled," "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten " "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", edit_int64(mdbr->PoolId, ed1)); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); bail_out: db_unlock(mdb); } void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char ed1[50]; db_lock(mdb); if (type == VERT_LIST) { if (JobId > 0) { /* do by JobId */ Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," "JobMedia.EndBlock " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId " "AND JobMedia.JobId=%s", edit_int64(JobId, ed1)); } else { Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName," "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock," "JobMedia.EndBlock " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId"); } } else { if (JobId > 0) { /* do by JobId */ Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId " "AND JobMedia.JobId=%s", edit_int64(JobId, ed1)); } else { Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex " "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId"); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); bail_out: db_unlock(mdb); } void db_list_copies_records(JCR *jcr, B_DB *mdb, uint32_t limit, char *JobIds, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { POOL_MEM str_limit(PM_MESSAGE); POOL_MEM str_jobids(PM_MESSAGE); if (limit > 0) { Mmsg(str_limit, " LIMIT %d", limit); } if (JobIds && JobIds[0]) { Mmsg(str_jobids, " AND (Job.PriorJobId IN (%s) OR Job.JobId IN (%s)) ", JobIds, JobIds); } db_lock(mdb); Mmsg(mdb->cmd, "SELECT DISTINCT Job.PriorJobId AS JobId, Job.Job, " "Job.JobId AS CopyJobId, Media.MediaType " "FROM Job " "JOIN JobMedia USING (JobId) " "JOIN Media USING (MediaId) " "WHERE Job.Type = '%c' %s ORDER BY Job.PriorJobId DESC %s", (char) JT_JOB_COPY, str_jobids.c_str(), str_limit.c_str()); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } if (sql_num_rows(mdb)) { if (JobIds && JobIds[0]) { sendit(ctx, _("These JobIds have copies as follows:\n")); } else { sendit(ctx, _("The catalog contains copies as follows:\n")); } list_result(jcr, mdb, sendit, ctx, type); } sql_free_result(mdb); bail_out: db_unlock(mdb); } void db_list_joblog_records(JCR *jcr, B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char ed1[50]; if (JobId <= 0) { return; } db_lock(mdb); if (type == VERT_LIST) { Mmsg(mdb->cmd, "SELECT LogText FROM Log " "WHERE Log.JobId=%s ORDER BY Log.LogId", edit_int64(JobId, ed1)); } else { Mmsg(mdb->cmd, "SELECT LogText FROM Log " "WHERE Log.JobId=%s ORDER BY Log.LogId", edit_int64(JobId, ed1)); /* * When something else then a vertical list is requested set the list type * to RAW_LIST e.g. non formated raw data as that makes the only sense for * the logtext output. The logtext already has things like \n etc in it * so we should just dump the raw content out for the best visible output. */ type = RAW_LIST; } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); bail_out: db_unlock(mdb); } /* * List Job record(s) that match JOB_DBR * * Currently, we return all jobs or if jr->JobId is set, * only the job with the specified id. */ void db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { char ed1[50]; char limit[100]; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (jr->limit > 0) { snprintf(limit, sizeof(limit), " LIMIT %d", jr->limit); } else { limit[0] = 0; } if (type == VERT_LIST) { if (jr->JobId == 0 && jr->Job[0] == 0) { Mmsg(mdb->cmd, "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level," "Job.ClientId,Client.Name as ClientName,JobStatus,SchedTime," "StartTime,EndTime,RealEndTime,JobTDate," "VolSessionId,VolSessionTime,JobFiles,JobErrors," "JobMissingFiles,Job.PoolId,Pool.Name as PooLname,PriorJobId," "Job.FileSetId,FileSet.FileSet " "FROM Job,Client,Pool,FileSet WHERE " "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId " "AND FileSet.FileSetId=Job.FileSetId ORDER BY StartTime%s", limit); } else { /* single record */ Mmsg(mdb->cmd, "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level," "Job.ClientId,Client.Name,JobStatus,SchedTime," "StartTime,EndTime,RealEndTime,JobTDate," "VolSessionId,VolSessionTime,JobFiles,JobErrors," "JobMissingFiles,Job.PoolId,Pool.Name as PooLname,PriorJobId," "Job.FileSetId,FileSet.FileSet " "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%s AND " "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId " "AND FileSet.FileSetId=Job.FileSetId", edit_int64(jr->JobId, ed1)); } } else { if (jr->Name[0] != 0) { mdb->db_escape_string(jcr, esc, jr->Name, strlen(jr->Name)); Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " "FROM Job WHERE Name='%s' ORDER BY JobId ASC", esc); } else if (jr->Job[0] != 0) { mdb->db_escape_string(jcr, esc, jr->Job, strlen(jr->Job)); Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " "FROM Job WHERE Job='%s' ORDER BY JobId ASC", esc); } else if (jr->JobId != 0) { Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " "FROM Job WHERE JobId=%s", edit_int64(jr->JobId, ed1)); } else { /* all records */ Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus " "FROM Job ORDER BY JobId ASC%s", limit); } } if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, type); sql_free_result(mdb); bail_out: db_unlock(mdb); } /* * List Job totals * */ void db_list_job_totals(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx) { db_lock(mdb); /* List by Job */ Mmsg(mdb->cmd, "SELECT count(*) AS Jobs,sum(JobFiles) " "AS Files,sum(JobBytes) AS Bytes,Name AS Job FROM Job GROUP BY Name"); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, HORZ_LIST); sql_free_result(mdb); /* Do Grand Total */ Mmsg(mdb->cmd, "SELECT count(*) AS Jobs,sum(JobFiles) " "AS Files,sum(JobBytes) As Bytes FROM Job"); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { goto bail_out; } list_result(jcr, mdb, sendit, ctx, HORZ_LIST); sql_free_result(mdb); bail_out: db_unlock(mdb); } void db_list_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx) { char ed1[50]; LIST_CTX lctx(jcr, mdb, sendit, ctx, NF_LIST); db_lock(mdb); /* * Stupid MySQL is NON-STANDARD ! */ if (db_get_type_index(mdb) == SQL_TYPE_MYSQL) { Mmsg(mdb->cmd, "SELECT CONCAT(Path.Path,Filename.Name) AS Filename " "FROM (SELECT PathId, FilenameId FROM File WHERE JobId=%s " "UNION ALL " "SELECT PathId, FilenameId " "FROM BaseFiles JOIN File " "ON (BaseFiles.FileId = File.FileId) " "WHERE BaseFiles.JobId = %s" ") AS F, Filename,Path " "WHERE Filename.FilenameId=F.FilenameId " "AND Path.PathId=F.PathId", edit_int64(jobid, ed1), ed1); } else { Mmsg(mdb->cmd, "SELECT Path.Path||Filename.Name AS Filename " "FROM (SELECT PathId, FilenameId FROM File WHERE JobId=%s " "UNION ALL " "SELECT PathId, FilenameId " "FROM BaseFiles JOIN File " "ON (BaseFiles.FileId = File.FileId) " "WHERE BaseFiles.JobId = %s" ") AS F, Filename,Path " "WHERE Filename.FilenameId=F.FilenameId " "AND Path.PathId=F.PathId", edit_int64(jobid, ed1), ed1); } if (!db_big_sql_query(mdb, mdb->cmd, list_result, &lctx)) { goto bail_out; } sql_free_result(mdb); bail_out: db_unlock(mdb); } void db_list_base_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx) { char ed1[50]; LIST_CTX lctx(jcr, mdb, sendit, ctx, NF_LIST); db_lock(mdb); /* * Stupid MySQL is NON-STANDARD ! */ if (db_get_type_index(mdb) == SQL_TYPE_MYSQL) { Mmsg(mdb->cmd, "SELECT CONCAT(Path.Path,Filename.Name) AS Filename " "FROM BaseFiles, File, Filename, Path " "WHERE BaseFiles.JobId=%s AND BaseFiles.BaseJobId = File.JobId " "AND BaseFiles.FileId = File.FileId " "AND Filename.FilenameId=File.FilenameId " "AND Path.PathId=File.PathId", edit_int64(jobid, ed1)); } else { Mmsg(mdb->cmd, "SELECT Path.Path||Filename.Name AS Filename " "FROM BaseFiles, File, Filename, Path " "WHERE BaseFiles.JobId=%s AND BaseFiles.BaseJobId = File.JobId " "AND BaseFiles.FileId = File.FileId " "AND Filename.FilenameId=File.FilenameId " "AND Path.PathId=File.PathId", edit_int64(jobid, ed1)); } if (!db_big_sql_query(mdb, mdb->cmd, list_result, &lctx)) { goto bail_out; } sql_free_result(mdb); bail_out: db_unlock(mdb); } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_pooling.c000066400000000000000000000675111263011562700206650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2010-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS sql pooling code that manages the database connection pools. * * Written by Marco van Wieringen, March 2010 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* * Get a non-pooled connection used when either sql pooling is * runtime disabled or at compile time. Or when we run out of * pooled connections and need more database connections. */ B_DB *db_sql_get_non_pooled_connection(JCR *jcr, const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { B_DB *mdb; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) Dmsg2(100, "db_sql_get_non_pooled_connection allocating 1 new non pooled database connection to database %s, backend type %s\n", db_name, db_drivername); #else Dmsg1(100, "db_sql_get_non_pooled_connection allocating 1 new non pooled database connection to database %s\n", db_name); #endif mdb = db_init_database(jcr, db_drivername, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); if (mdb == NULL) { return NULL; } if (!db_open_database(jcr, mdb)) { Mmsg2(mdb->errmsg, _("Could not open database \"%s\": ERR=%s\n"), db_name, db_strerror(mdb)); Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); db_close_database(jcr, mdb); return NULL; } return mdb; } #ifdef HAVE_SQL_POOLING static dlist *db_pooling_descriptors = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static void destroy_pool_descriptor(SQL_POOL_DESCRIPTOR *spd, bool flush_only) { SQL_POOL_ENTRY *spe, *spe_next; spe = (SQL_POOL_ENTRY *)spd->pool_entries->first(); while (spe) { spe_next = (SQL_POOL_ENTRY *)spd->pool_entries->get_next(spe); if (!flush_only || spe->reference_count == 0) { Dmsg3(100, "db_sql_pool_destroy destroy db pool connection %d to %s, backend type %s\n", spe->id, spe->db_handle->get_db_name(), spe->db_handle->db_get_type()); db_close_database(NULL, spe->db_handle); if (flush_only) { spd->pool_entries->remove(spe); free(spe); } spd->nr_connections--; } spe = spe_next; } /* * See if there is anything left on this pool and we are flushing the pool. */ if (flush_only && spd->nr_connections == 0) { db_pooling_descriptors->remove(spd); delete spd->pool_entries; free(spd); } } /* * Initialize the sql connection pool. */ bool db_sql_pool_initialize(const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool disable_batch_insert, int min_connections, int max_connections, int increment_connections, int idle_timeout, int validate_timeout) { int cnt; B_DB *mdb; time_t now; SQL_POOL_DESCRIPTOR *spd = NULL; SQL_POOL_ENTRY *spe = NULL; bool retval = false; /* * See if pooling is runtime disabled. */ if (max_connections == 0) { Dmsg0(100, "db_sql_pool_initialize pooling disabled as max_connections == 0\n"); return true; } /* * First make sure the values make any sense. */ if (min_connections <= 0 || max_connections <= 0 || increment_connections <= 0 || min_connections > max_connections) { Jmsg(NULL, M_FATAL, 0, _("Illegal values for sql pool initialization, min_connections = %d, max_connections = %d, increment_connections = %d"), min_connections, max_connections, increment_connections); return false; } P(mutex); time(&now); if (db_pooling_descriptors == NULL) { db_pooling_descriptors = New(dlist(spd, &spd->link)); } /* * Create a new pool descriptor. */ spd = (SQL_POOL_DESCRIPTOR *)malloc(sizeof(SQL_POOL_DESCRIPTOR)); memset(spd, 0, sizeof(SQL_POOL_DESCRIPTOR)); spd->pool_entries = New(dlist(spe, &spe->link)); spd->min_connections = min_connections; spd->max_connections = max_connections; spd->increment_connections = increment_connections; spd->idle_timeout = idle_timeout; spd->validate_timeout = validate_timeout; spd->last_update = now; spd->active = true; /* * Create a number of database connections. */ for (cnt = 0; cnt < min_connections; cnt++) { mdb = db_init_database(NULL, db_drivername, db_name, db_user, db_password, db_address, db_port, db_socket, true, disable_batch_insert); if (mdb == NULL) { Jmsg(NULL, M_FATAL, 0, "%s", _("Could not init database connection")); goto bail_out; } if (!db_open_database(NULL, mdb)) { Mmsg2(mdb->errmsg, _("Could not open database \"%s\": ERR=%s\n"), db_name, db_strerror(mdb)); Jmsg(NULL, M_FATAL, 0, "%s", mdb->errmsg); db_close_database(NULL, mdb); goto bail_out; } /* * Push this new connection onto the connection pool. */ spe = (SQL_POOL_ENTRY *)malloc(sizeof(SQL_POOL_ENTRY)); memset(spe, 0, sizeof(SQL_POOL_ENTRY)); spe->id = spd->nr_connections++; spe->last_update = now; spe->db_handle = mdb; spd->pool_entries->append(spe); spe = NULL; } #if defined(HAVE_DYNAMIC_CATS_BACKENDS) Dmsg3(100, "db_sql_pool_initialize created %d connections to database %s, backend type %s\n", cnt, db_name, db_drivername); #else Dmsg2(100, "db_sql_pool_initialize created %d connections to database %s\n", cnt, db_name); #endif db_pooling_descriptors->append(spd); retval = true; goto ok_out; bail_out: if (spe) { free(spe); } if (spd) { destroy_pool_descriptor(spd, false); } ok_out: V(mutex); return retval; } /* * Cleanup the sql connection pools. * This gets called on shutdown. */ void db_sql_pool_destroy(void) { SQL_POOL_DESCRIPTOR *spd, *spd_next; /* * See if pooling is enabled. */ if (!db_pooling_descriptors) { return; } P(mutex); spd = (SQL_POOL_DESCRIPTOR *)db_pooling_descriptors->first(); while (spd) { spd_next = (SQL_POOL_DESCRIPTOR *)db_pooling_descriptors->get_next(spd); destroy_pool_descriptor(spd, false); spd = spd_next; } delete db_pooling_descriptors; db_pooling_descriptors = NULL; V(mutex); } /* * Flush the sql connection pools. * This gets called on config reload. We close all unreferenced connections. */ void db_sql_pool_flush(void) { SQL_POOL_ENTRY *spe; SQL_POOL_DESCRIPTOR *spd, *spd_next; /* * See if pooling is enabled. */ if (!db_pooling_descriptors) { return; } P(mutex); spd = (SQL_POOL_DESCRIPTOR *)db_pooling_descriptors->first(); while (spd) { spd_next = (SQL_POOL_DESCRIPTOR *)db_pooling_descriptors->get_next(spd); if (spd->active) { /* * On a flush all current available pools are invalidated. */ spd->active = false; destroy_pool_descriptor(spd, true); } spd = spd_next; } V(mutex); } /* * Grow the sql connection pool. * This function should be called with the mutex held. */ static inline void sql_pool_grow(SQL_POOL_DESCRIPTOR *spd) { int cnt, next_id; B_DB *mdb; time_t now; SQL_POOL_ENTRY *spe; B_DB *db_handle; /* * Get the first entry from the list to be able to clone it. * If the pool is empty its not initialized ok so we cannot really * grow its size. */ spe = (SQL_POOL_ENTRY *)spd->pool_entries->first(); if (spe != NULL) { /* * Save the handle of the first entry so we can clone it later on. */ db_handle = spe->db_handle; /* * Now that the pool is about to be grown give each entry a new id. */ cnt = 0; foreach_dlist(spe, spd->pool_entries) { spe->id = cnt++; } /* * Remember the next available id to use. */ next_id = cnt; /* * Create a number of database connections. */ time(&now); for (cnt = 0; cnt < spd->increment_connections; cnt++) { /* * Get a new non-pooled connection to the database. * We want to add a non pooled connection to the pool as otherwise * we are creating a deadlock as db_clone_database_connection will * call sql_pool_get_connection which means a recursive enter into * the pooling code and as such the mutex will deadlock. */ mdb = db_clone_database_connection(db_handle, NULL, true, false); if (mdb == NULL) { Jmsg(NULL, M_FATAL, 0, "%s", _("Could not init database connection")); break; } /* * Push this new connection onto the connection pool. */ spe = (SQL_POOL_ENTRY *)malloc(sizeof(SQL_POOL_ENTRY)); memset(spe, 0, sizeof(SQL_POOL_ENTRY)); spe->id = next_id++; spe->last_update = now; spe->db_handle = mdb; spd->pool_entries->append(spe); } Dmsg3(100, "sql_pool_grow created %d connections to database %s, backend type %s\n", cnt, spe->db_handle->get_db_name(), spe->db_handle->db_get_type()); spd->last_update = now; } else { Dmsg0(100, "sql_pool_grow unable to determine first entry on pool list\n"); } } /* * Shrink the sql connection pool. * This function should be called with the mutex held. */ static inline void sql_pool_shrink(SQL_POOL_DESCRIPTOR *spd) { int cnt; time_t now; SQL_POOL_ENTRY *spe, *spe_next; time(&now); spd->last_update = now; /* * See if we want to shrink. */ if (spd->min_connections && spd->nr_connections <= spd->min_connections) { Dmsg0(100, "sql_pool_shrink cannot shrink connection pool already minimum size\n"); return; } /* * See how much we should shrink. * No need to shrink under min_connections, and when things are greater * shrink with increment_connections per shrink run. */ cnt = spd->nr_connections - spd->min_connections; if (cnt > spd->increment_connections) { cnt = spd->increment_connections; } /* * Sanity check. */ if (cnt <= 0) { return; } /* * For debugging purposes get the first entry on the connection pool. */ spe = (SQL_POOL_ENTRY *)spd->pool_entries->first(); if (spe) { Dmsg3(100, "sql_pool_shrink shrinking connection pool with %d connections to database %s, backend type %s\n", cnt, spe->db_handle->get_db_name(), spe->db_handle->db_get_type()); } /* * Loop over all entries on the pool and see if the can be removed. */ spe = (SQL_POOL_ENTRY *)spd->pool_entries->first(); while (spe) { spe_next = (SQL_POOL_ENTRY *)spd->pool_entries->get_next(spe); /* * See if this is a unreferenced connection. * And its been idle for more then idle_timeout seconds. */ if (spe->reference_count == 0 && ((now - spe->last_update) >= spd->idle_timeout)) { spd->pool_entries->remove(spe); db_close_database(NULL, spe->db_handle); free(spe); spd->nr_connections--; cnt--; /* * See if we have freed enough. */ if (cnt <= 0) { break; } } spe = spe_next; } /* * Now that the pool has shrunk give each entry a new id. */ cnt = 0; foreach_dlist(spe, spd->pool_entries) { spe->id = cnt++; } } /* * Find the connection pool with the correct connections. * This function should be called with the mutex held. */ static inline SQL_POOL_DESCRIPTOR *sql_find_pool_descriptor(const char *db_drivername, const char *db_name, const char *db_address, int db_port) { SQL_POOL_DESCRIPTOR *spd; SQL_POOL_ENTRY *spe; foreach_dlist(spd, db_pooling_descriptors) { if (spd->active) { foreach_dlist(spe, spd->pool_entries) { if (spe->db_handle->db_match_database(db_drivername, db_name, db_address, db_port)) { return spd; } } } } return NULL; } /* * Find a free connection in a certain connection pool. * This function should be called with the mutex held. */ static inline SQL_POOL_ENTRY *sql_find_free_connection(SQL_POOL_DESCRIPTOR *spd) { SQL_POOL_ENTRY *spe; foreach_dlist(spe, spd->pool_entries) { if (spe->reference_count == 0) { return spe; } } return NULL; } /* * Find a connection in a certain connection pool. * This function should be called with the mutex held. */ static inline SQL_POOL_ENTRY *sql_find_first_connection(SQL_POOL_DESCRIPTOR *spd) { SQL_POOL_ENTRY *spe; foreach_dlist(spe, spd->pool_entries) { return spe; } return NULL; } /* * Get a new connection from the pool. */ B_DB *db_sql_get_pooled_connection(JCR *jcr, const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { int cnt = 0; SQL_POOL_DESCRIPTOR *wanted_pool; SQL_POOL_ENTRY *use_connection = NULL; B_DB *db_handle = NULL; time_t now; now = time(NULL); #if defined(HAVE_DYNAMIC_CATS_BACKENDS) Dmsg2(100, "db_sql_get_pooled_connection get new connection for connection to database %s, backend type %s\n", db_name, db_drivername); #else Dmsg1(100, "db_sql_get_pooled_connection get new connection for connection to database %s\n", db_name); #endif /* * See if pooling is enabled. */ if (!db_pooling_descriptors) { return db_sql_get_non_pooled_connection(jcr, db_drivername, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); } P(mutex); /* * Try to lookup the pool. */ wanted_pool = sql_find_pool_descriptor(db_drivername, db_name, db_address, db_port); if (wanted_pool) { /* * Loop while trying to find a connection. */ while (1) { /* * If we can return a shared connection and when need_private is not * explicitly set try to match an existing connection. Otherwise we * want a free connection. */ if (!mult_db_connections && !need_private) { use_connection = sql_find_first_connection(wanted_pool); } else { use_connection = sql_find_free_connection(wanted_pool); } if (use_connection) { /* * See if the connection match needs validation. */ if ((now - use_connection->last_update) >= wanted_pool->validate_timeout) { if (!db_validate_connection(use_connection->db_handle)) { /* * Connection seems to be dead kill it from the pool. */ wanted_pool->pool_entries->remove(use_connection); db_close_database(jcr, use_connection->db_handle); free(use_connection); wanted_pool->nr_connections--; continue; } } goto ok_out; } else { if (mult_db_connections || need_private) { /* * Cannot find an already open connection that is unused. * See if there is still room to grow the pool if not this is it. * We just give back a non pooled connection which gets a proper cleanup * anyhow when it discarded using db_sql_close_pooled_connection. */ if (wanted_pool->nr_connections >= wanted_pool->max_connections) { db_handle = db_sql_get_non_pooled_connection(jcr, db_drivername, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); goto bail_out; } Dmsg0(100, "db_sql_get_pooled_connection trying to grow connection pool for getting free connection\n"); sql_pool_grow(wanted_pool); } else { /* * Request for a shared connection and no connection gets through the validation. * e.g. all connections in the pool have failed. * This should never happen so lets abort things and let the upper layer handle this. */ goto bail_out; } } } } else { /* * Pooling not enabled for this connection use non pooling. */ db_handle = db_sql_get_non_pooled_connection(jcr, db_drivername, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); goto bail_out; } ok_out: use_connection->reference_count++; use_connection->last_update = now; db_handle = use_connection->db_handle; /* * Set the is_private flag of this database connection to the wanted state. */ db_handle->set_private(need_private); bail_out: V(mutex); return db_handle; } /* * Put a connection back onto the pool for reuse. * * The abort flag is set when we encounter a dead or misbehaving connection * which needs to be closed right away and should not be reused. */ void db_sql_close_pooled_connection(JCR *jcr, B_DB *mdb, bool abort) { SQL_POOL_ENTRY *spe, *spe_next; SQL_POOL_DESCRIPTOR *spd, *spd_next; bool found = false; time_t now; /* * See if pooling is enabled. */ if (!db_pooling_descriptors) { db_close_database(jcr, mdb); return; } P(mutex); /* * See what connection is freed. */ now = time(NULL); spd = (SQL_POOL_DESCRIPTOR *)db_pooling_descriptors->first(); while (spd) { spd_next = (SQL_POOL_DESCRIPTOR *)db_pooling_descriptors->get_next(spd); if (!spd->pool_entries) { spd = spd_next; continue; } spe = (SQL_POOL_ENTRY *)spd->pool_entries->first(); while (spe) { spe_next = (SQL_POOL_ENTRY *)spd->pool_entries->get_next(spe); if (spe->db_handle == mdb) { found = true; if (!abort) { /* * End any active transactions. */ db_end_transaction(jcr, mdb); /* * Decrement reference count and update last update field. */ spe->reference_count--; time(&spe->last_update); Dmsg3(100, "db_sql_close_pooled_connection decrementing reference count of connection %d now %d, backend type %s\n", spe->id, spe->reference_count, spe->db_handle->db_get_type()); /* * Clear the is_private flag if this is a free connection again. */ if (spe->reference_count == 0) { mdb->set_private(false); } /* * See if this is a free on an inactive pool and this was the last reference. */ if (!spd->active && spe->reference_count == 0) { spd->pool_entries->remove(spe); db_close_database(jcr, spe->db_handle); free(spe); spd->nr_connections--; } } else { Dmsg3(100, "db_sql_close_pooled_connection aborting connection to database %s reference count %d, backend type %s\n", spe->db_handle->get_db_name(), spe->reference_count, spe->db_handle->db_get_type()); spd->pool_entries->remove(spe); db_close_database(jcr, spe->db_handle); free(spe); spd->nr_connections--; } /* * No need to search further if we found the item we were looking for. */ break; } spe = spe_next; } /* * See if this is an inactive pool and it has no connections on it anymore. */ if (!spd->active && spd->nr_connections == 0) { db_pooling_descriptors->remove(spd); delete spd->pool_entries; free(spd); } else { /* * See if we can shrink the connection pool. * Only try to shrink when the last update on the pool was more then the validate time ago. */ if ((now - spd->last_update) >= spd->validate_timeout) { Dmsg0(100, "db_sql_close_pooled_connection trying to shrink connection pool\n"); sql_pool_shrink(spd); } } /* * No need to search further if we found the item we were looking for. */ if (found) { break; } spd = spd_next; } /* * If we didn't find this mdb on any pooling chain we are not pooling * this connection and we just close the connection. */ if (!found) { db_close_database(jcr, mdb); } V(mutex); } #else /* HAVE_SQL_POOLING */ /* * Initialize the sql connection pool. * For non pooling this is a no-op. */ bool db_sql_pool_initialize(const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool disable_batch_insert, int min_connections, int max_connections, int increment_connections, int idle_timeout, int validate_timeout) { return true; } /* * Cleanup the sql connection pools. * For non pooling this is a no-op. */ void db_sql_pool_destroy(void) { } /* * Flush the sql connection pools. * For non pooling this is a no-op. */ void db_sql_pool_flush(void) { } /* * Get a new connection from the pool. * For non pooling we just call db_sql_get_non_pooled_connection. */ B_DB *db_sql_get_pooled_connection(JCR *jcr, const char *db_drivername, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { return db_sql_get_non_pooled_connection(jcr, db_drivername, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private); } /* * Put a connection back onto the pool for reuse. * For non pooling we just do a db_close_database. */ void db_sql_close_pooled_connection(JCR *jcr, B_DB *mdb, bool abort) { db_close_database(jcr, mdb); } #endif /* HAVE_SQL_POOLING */ #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sql_update.c000066400000000000000000000420031263011562700204650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database Update record interface routines * * Kern Sibbald, March 2000 */ #include "bareos.h" #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI #include "cats.h" #include "bdb_priv.h" #include "sql_glue.h" /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- * * Generic Routines (or almost generic) * * ----------------------------------------------------------------------- */ /* Update the attributes record by adding the file digest */ bool db_add_digest_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *digest, int type) { bool retval; char ed1[50]; int len = strlen(digest); db_lock(mdb); mdb->esc_name = check_pool_memory_size(mdb->esc_name, len*2+1); mdb->db_escape_string(jcr, mdb->esc_name, digest, len); Mmsg(mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%s", mdb->esc_name, edit_int64(FileId, ed1)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* Mark the file record as being visited during database * verify compare. Stuff JobId into the MarkId field */ bool db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId) { bool retval; char ed1[50], ed2[50]; db_lock(mdb); Mmsg(mdb->cmd, "UPDATE File SET MarkId=%s WHERE FileId=%s", edit_int64(JobId, ed1), edit_int64(FileId, ed2)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* * Update the Job record at start of Job * * Returns: false on failure * true on success */ bool db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { char dt[MAX_TIME_LENGTH]; time_t stime; btime_t JobTDate; bool retval; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50]; stime = jr->StartTime; bstrutime(dt, sizeof(dt), stime); JobTDate = (btime_t)stime; db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Job SET JobStatus='%c',Level='%c',StartTime='%s'," "ClientId=%s,JobTDate=%s,PoolId=%s,FileSetId=%s WHERE JobId=%s", (char)(jcr->JobStatus), (char)(jr->JobLevel), dt, edit_int64(jr->ClientId, ed1), edit_uint64(JobTDate, ed2), edit_int64(jr->PoolId, ed3), edit_int64(jr->FileSetId, ed4), edit_int64(jr->JobId, ed5)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); mdb->changes = 0; db_unlock(mdb); return retval; } /* * Update Long term statistics with all jobs that were run before age seconds */ int db_update_stats(JCR *jcr, B_DB *mdb, utime_t age) { char ed1[30]; int rows; utime_t now = (utime_t)time(NULL); edit_uint64(now - age, ed1); db_lock(mdb); Mmsg(mdb->cmd, fill_jobhisto, ed1); if (QUERY_DB(jcr, mdb, mdb->cmd)) { rows = sql_affected_rows(mdb); } else { rows = -1; } db_unlock(mdb); return rows; } /* * Update the Job record at end of Job * * Returns: false on failure * true on success */ bool db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { bool retval; char dt[MAX_TIME_LENGTH]; char rdt[MAX_TIME_LENGTH]; time_t ttime; char ed1[30], ed2[30], ed3[50], ed4[50]; btime_t JobTDate; char PriorJobId[50]; if (jr->PriorJobId) { bstrncpy(PriorJobId, edit_int64(jr->PriorJobId, ed1), sizeof(PriorJobId)); } else { bstrncpy(PriorJobId, "0", sizeof(PriorJobId)); } ttime = jr->EndTime; bstrutime(dt, sizeof(dt), ttime); if (jr->RealEndTime < jr->EndTime) { jr->RealEndTime = jr->EndTime; } ttime = jr->RealEndTime; bstrutime(rdt, sizeof(rdt), ttime); JobTDate = ttime; db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Job SET JobStatus='%c',Level='%c',EndTime='%s'," "ClientId=%u,JobBytes=%s,ReadBytes=%s,JobFiles=%u,JobErrors=%u,VolSessionId=%u," "VolSessionTime=%u,PoolId=%u,FileSetId=%u,JobTDate=%s," "RealEndTime='%s',PriorJobId=%s,HasBase=%u,PurgedFiles=%u WHERE JobId=%s", (char)(jr->JobStatus), (char)(jr->JobLevel), dt, jr->ClientId, edit_uint64(jr->JobBytes, ed1), edit_uint64(jr->ReadBytes, ed4), jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime, jr->PoolId, jr->FileSetId, edit_uint64(JobTDate, ed2), rdt, PriorJobId, jr->HasBase, jr->PurgedFiles, edit_int64(jr->JobId, ed3)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* * Update Client record * Returns: false on failure * true on success */ bool db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) { bool retval = false; char ed1[50], ed2[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; char esc_uname[MAX_ESCAPE_NAME_LENGTH]; CLIENT_DBR tcr; db_lock(mdb); memcpy(&tcr, cr, sizeof(tcr)); if (!db_create_client_record(jcr, mdb, &tcr)) { goto bail_out; } mdb->db_escape_string(jcr, esc_name, cr->Name, strlen(cr->Name)); mdb->db_escape_string(jcr, esc_uname, cr->Uname, strlen(cr->Uname)); Mmsg(mdb->cmd, "UPDATE Client SET AutoPrune=%d,FileRetention=%s,JobRetention=%s," "Uname='%s' WHERE Name='%s'", cr->AutoPrune, edit_uint64(cr->FileRetention, ed1), edit_uint64(cr->JobRetention, ed2), esc_uname, esc_name); retval = UPDATE_DB(jcr, mdb, mdb->cmd); bail_out: db_unlock(mdb); return retval; } /* * Update Counters record * Returns: false on failure * true on success */ bool db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr) { bool retval; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, cr->Counter, strlen(cr->Counter)); Mmsg(mdb->cmd, update_counter_values[mdb->db_get_type_index()], cr->MinValue, cr->MaxValue, cr->CurrentValue, cr->WrapCounter, esc); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } bool db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr) { bool retval; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); mdb->db_escape_string(jcr, esc, pr->LabelFormat, strlen(pr->LabelFormat)); Mmsg(mdb->cmd, "SELECT count(*) from Media WHERE PoolId=%s", edit_int64(pr->PoolId, ed4)); pr->NumVols = get_sql_record_max(jcr, mdb); Dmsg1(400, "NumVols=%d\n", pr->NumVols); Mmsg(mdb->cmd, "UPDATE Pool SET NumVols=%u,MaxVols=%u,UseOnce=%d,UseCatalog=%d," "AcceptAnyVolume=%d,VolRetention='%s',VolUseDuration='%s'," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,Recycle=%d," "AutoPrune=%d,LabelType=%d,LabelFormat='%s',RecyclePoolId=%s," "ScratchPoolId=%s,ActionOnPurge=%d,MinBlockSize=%d,MaxBlockSize=%d WHERE PoolId=%s", pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog, pr->AcceptAnyVolume, edit_uint64(pr->VolRetention, ed1), edit_uint64(pr->VolUseDuration, ed2), pr->MaxVolJobs, pr->MaxVolFiles, edit_uint64(pr->MaxVolBytes, ed3), pr->Recycle, pr->AutoPrune, pr->LabelType, esc, edit_int64(pr->RecyclePoolId,ed5), edit_int64(pr->ScratchPoolId,ed6), pr->ActionOnPurge, pr->MinBlocksize, pr->MaxBlocksize, ed4); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } bool db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr) { bool retval; char ed1[50]; db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Storage SET AutoChanger=%d WHERE StorageId=%s", sr->AutoChanger, edit_int64(sr->StorageId, ed1)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* * Update the Media Record at end of Session * * Returns: false on failure * true on success */ bool db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { bool retval; char dt[MAX_TIME_LENGTH]; time_t ttime; char ed1[50], ed2[50], ed3[50], ed4[50]; char ed5[50], ed6[50], ed7[50], ed8[50]; char ed9[50], ed10[50], ed11[50]; char esc_name[MAX_ESCAPE_NAME_LENGTH]; char esc_status[MAX_ESCAPE_NAME_LENGTH]; Dmsg1(100, "update_media: FirstWritten=%d\n", mr->FirstWritten); db_lock(mdb); mdb->db_escape_string(jcr, esc_name, mr->VolumeName, strlen(mr->VolumeName)); mdb->db_escape_string(jcr, esc_status, mr->VolStatus, strlen(mr->VolStatus)); if (mr->set_first_written) { Dmsg1(400, "Set FirstWritten Vol=%s\n", mr->VolumeName); ttime = mr->FirstWritten; bstrutime(dt, sizeof(dt), ttime); Mmsg(mdb->cmd, "UPDATE Media SET FirstWritten='%s'" " WHERE VolumeName='%s'", dt, esc_name); retval = UPDATE_DB(jcr, mdb, mdb->cmd); Dmsg1(400, "Firstwritten=%d\n", mr->FirstWritten); } /* Label just done? */ if (mr->set_label_date) { ttime = mr->LabelDate; if (ttime == 0) { ttime = time(NULL); } bstrutime(dt, sizeof(dt), ttime); Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' " "WHERE VolumeName='%s'", dt, esc_name); UPDATE_DB(jcr, mdb, mdb->cmd); } if (mr->LastWritten != 0) { ttime = mr->LastWritten; bstrutime(dt, sizeof(dt), ttime); Mmsg(mdb->cmd, "UPDATE Media Set LastWritten='%s' " "WHERE VolumeName='%s'", dt, esc_name); UPDATE_DB(jcr, mdb, mdb->cmd); } Mmsg(mdb->cmd, "UPDATE Media SET VolJobs=%u," "VolFiles=%u,VolBlocks=%u,VolBytes=%s,VolMounts=%u,VolErrors=%u," "VolWrites=%u,MaxVolBytes=%s,VolStatus='%s'," "Slot=%d,InChanger=%d,VolReadTime=%s,VolWriteTime=%s," "LabelType=%d,StorageId=%s,PoolId=%s,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%d,MaxVolFiles=%d,Enabled=%d,LocationId=%s," "ScratchPoolId=%s,RecyclePoolId=%s,RecycleCount=%d,Recycle=%d,ActionOnPurge=%d," "MinBlocksize=%u,MaxBlocksize=%u" " WHERE VolumeName='%s'", mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1), mr->VolMounts, mr->VolErrors, mr->VolWrites, edit_uint64(mr->MaxVolBytes, ed2), esc_status, mr->Slot, mr->InChanger, edit_int64(mr->VolReadTime, ed3), edit_int64(mr->VolWriteTime, ed4), mr->LabelType, edit_int64(mr->StorageId, ed5), edit_int64(mr->PoolId, ed6), edit_uint64(mr->VolRetention, ed7), edit_uint64(mr->VolUseDuration, ed8), mr->MaxVolJobs, mr->MaxVolFiles, mr->Enabled, edit_uint64(mr->LocationId, ed9), edit_uint64(mr->ScratchPoolId, ed10), edit_uint64(mr->RecyclePoolId, ed11), mr->RecycleCount, mr->Recycle, mr->ActionOnPurge, mr->MinBlocksize, mr->MaxBlocksize, esc_name); Dmsg1(400, "%s\n", mdb->cmd); retval = UPDATE_DB(jcr, mdb, mdb->cmd); /* Make sure InChanger is 0 for any record having the same Slot */ db_make_inchanger_unique(jcr, mdb, mr); db_unlock(mdb); return retval; } /* * Update the Media Record Default values from Pool * * Returns: false on failure * true on success */ bool db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { bool retval; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50]; char esc[MAX_ESCAPE_NAME_LENGTH]; db_lock(mdb); if (mr->VolumeName[0]) { mdb->db_escape_string(jcr, esc, mr->VolumeName, strlen(mr->VolumeName)); Mmsg(mdb->cmd, "UPDATE Media SET " "ActionOnPurge=%d,Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s," "MinBlocksize=%d,MaxBlocksize=%d" " WHERE VolumeName='%s'", mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1), edit_uint64(mr->VolUseDuration, ed2), mr->MaxVolJobs, mr->MaxVolFiles, edit_uint64(mr->MaxVolBytes, ed3), edit_uint64(mr->RecyclePoolId, ed4), mr->MinBlocksize, mr->MaxBlocksize, esc); } else { Mmsg(mdb->cmd, "UPDATE Media SET " "ActionOnPurge=%d,Recycle=%d,VolRetention=%s,VolUseDuration=%s," "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s," "MinBlocksize=%d,MaxBlocksize=%d" " WHERE PoolId=%s", mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1), edit_uint64(mr->VolUseDuration, ed2), mr->MaxVolJobs, mr->MaxVolFiles, edit_uint64(mr->MaxVolBytes, ed3), edit_int64(mr->RecyclePoolId, ed4), mr->MinBlocksize, mr->MaxBlocksize, edit_int64(mr->PoolId, ed5)); } Dmsg1(400, "%s\n", mdb->cmd); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* * If we have a non-zero InChanger, ensure that no other Media * record has InChanger set on the same Slot. * * This routine assumes the database is already locked. */ void db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) { char ed1[50], ed2[50]; char esc[MAX_ESCAPE_NAME_LENGTH]; if (mr->InChanger != 0 && mr->Slot != 0 && mr->StorageId != 0) { if (mr->MediaId != 0) { Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0, Slot=0 WHERE " "Slot=%d AND StorageId=%s AND MediaId!=%s", mr->Slot, edit_int64(mr->StorageId, ed1), edit_int64(mr->MediaId, ed2)); } else if (*mr->VolumeName) { mdb->db_escape_string(jcr, esc,mr->VolumeName,strlen(mr->VolumeName)); Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0, Slot=0 WHERE " "Slot=%d AND StorageId=%s AND VolumeName!='%s'", mr->Slot, edit_int64(mr->StorageId, ed1), esc); } else { /* used by ua_label to reset all volume with this slot */ Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0, Slot=0 WHERE " "Slot=%d AND StorageId=%s", mr->Slot, edit_int64(mr->StorageId, ed1), mr->VolumeName); } Dmsg1(100, "%s\n", mdb->cmd); UPDATE_DB_NO_AFR(jcr, mdb, mdb->cmd); } } /* * Update Quota record * * Returns: false on failure * true on success */ bool db_update_quota_gracetime(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { bool retval; char ed1[50], ed2[50]; time_t now = time(NULL); db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Quota SET GraceTime=%s WHERE ClientId='%s'", edit_uint64(now, ed1), edit_uint64(jr->ClientId, ed2)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* * Update Quota Softlimit * * Returns: false on failure * true on success */ bool db_update_quota_softlimit(JCR *jcr, B_DB *mdb, JOB_DBR *jr) { bool retval; char ed1[50], ed2[50]; db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Quota SET QuotaLimit=%s WHERE ClientId='%s'", edit_uint64((jr->JobSumTotalBytes + jr->JobBytes), ed1), edit_uint64(jr->ClientId, ed2)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /* * Reset Quota Gracetime * * Returns: false on failure * true on success */ bool db_reset_quota_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr) { bool retval; char ed1[50]; db_lock(mdb); Mmsg(mdb->cmd, "UPDATE Quota SET GraceTime='0', QuotaLimit='0' WHERE ClientId='%s'", edit_uint64(cr->ClientId, ed1)); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } /** * Update NDMP level mapping * * Returns: false on failure * true on success */ bool db_update_ndmp_level_mapping(JCR *jcr, B_DB *mdb, JOB_DBR *jr, char *filesystem, int level) { bool retval; char ed1[50], ed2[50], ed3[50]; db_lock(mdb); mdb->esc_name = check_pool_memory_size(mdb->esc_name, strlen(filesystem) * 2 + 1); db_escape_string(jcr, mdb, mdb->esc_name, filesystem, strlen(filesystem)); Mmsg(mdb->cmd, "UPDATE NDMPLevelMap SET DumpLevel='%s' WHERE " "ClientId='%s' AND FileSetId='%s' AND FileSystem='%s'", edit_uint64(level, ed1), edit_uint64(jr->ClientId, ed2), edit_uint64(jr->FileSetId, ed3), mdb->esc_name); retval = UPDATE_DB(jcr, mdb, mdb->cmd); db_unlock(mdb); return retval; } #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ bareos-Release-14.2.6/src/cats/sqlite.c000066400000000000000000000445331263011562700176370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Catalog Database routines specific to SQLite * * Kern Sibbald, January 2002 * * Major rewrite by Marco van Wieringen, January 2010 for catalog refactoring. */ #include "bareos.h" #if HAVE_SQLITE3 #include "cats.h" #include "bdb_priv.h" #include #include "bdb_sqlite.h" /* ----------------------------------------------------------------------- * * SQLite dependent defines and subroutines * * ----------------------------------------------------------------------- */ /* * List of open databases */ static dlist *db_list = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* * When using mult_db_connections = true, * sqlite can be BUSY. We just need sleep a little in this case. */ static int sqlite_busy_handler(void *arg, int calls) { bmicrosleep(0, 500); return 1; } B_DB_SQLITE::B_DB_SQLITE(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) { /* * Initialize the parent class members. */ m_db_interface_type = SQL_INTERFACE_TYPE_SQLITE3; m_db_type = SQL_TYPE_SQLITE3; m_db_driver = bstrdup("SQLite3"); m_db_name = bstrdup(db_name); if (disable_batch_insert) { m_disabled_batch_insert = true; m_have_batch_insert = false; } else { m_disabled_batch_insert = false; #if defined(USE_BATCH_FILE_INSERT) #if defined(HAVE_SQLITE3_THREADSAFE) m_have_batch_insert = sqlite3_threadsafe(); #else m_have_batch_insert = false; #endif /* HAVE_SQLITE3_THREADSAFE */ #else m_have_batch_insert = false; #endif /* USE_BATCH_FILE_INSERT */ } errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */ *errmsg = 0; cmd = get_pool_memory(PM_EMSG); /* get command buffer */ cached_path = get_pool_memory(PM_FNAME); cached_path_id = 0; m_ref_count = 1; fname = get_pool_memory(PM_FNAME); path = get_pool_memory(PM_FNAME); esc_name = get_pool_memory(PM_FNAME); esc_path = get_pool_memory(PM_FNAME); esc_obj = get_pool_memory(PM_FNAME); m_allow_transactions = mult_db_connections; m_is_private = need_private; /* * Initialize the private members. */ m_db_handle = NULL; m_result = NULL; m_lowlevel_errmsg = NULL; /* * Put the db in the list. */ if (db_list == NULL) { db_list = New(dlist(this, &this->m_link)); } db_list->append(this); } B_DB_SQLITE::~B_DB_SQLITE() { } /* * Now actually open the database. This can generate errors, * which are returned in the errmsg * * DO NOT close the database or delete mdb here !!!! */ bool B_DB_SQLITE::db_open_database(JCR *jcr) { bool retval = false; char *db_path; int len; struct stat statbuf; int status; int errstat; int retry = 0; P(mutex); if (m_connected) { retval = true; goto bail_out; } if ((errstat=rwl_init(&m_lock)) != 0) { berrno be; Mmsg1(&errmsg, _("Unable to initialize DB lock. ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } /* * Open the database */ len = strlen(working_directory) + strlen(m_db_name) + 5; db_path = (char *)malloc(len); strcpy(db_path, working_directory); strcat(db_path, "/"); strcat(db_path, m_db_name); strcat(db_path, ".db"); if (stat(db_path, &statbuf) != 0) { Mmsg1(&errmsg, _("Database %s does not exist, please create it.\n"), db_path); free(db_path); goto bail_out; } for (m_db_handle = NULL; !m_db_handle && retry++ < 10; ) { status = sqlite3_open(db_path, &m_db_handle); if (status != SQLITE_OK) { m_lowlevel_errmsg = (char *)sqlite3_errmsg(m_db_handle); sqlite3_close(m_db_handle); m_db_handle = NULL; } else { m_lowlevel_errmsg = NULL; } Dmsg0(300, "sqlite_open\n"); if (!m_db_handle) { bmicrosleep(1, 0); } } if (m_db_handle == NULL) { Mmsg2(&errmsg, _("Unable to open Database=%s. ERR=%s\n"), db_path, m_lowlevel_errmsg ? m_lowlevel_errmsg : _("unknown")); free(db_path); goto bail_out; } m_connected = true; free(db_path); /* * Set busy handler to wait when we use mult_db_connections = true */ sqlite3_busy_handler(m_db_handle, sqlite_busy_handler, NULL); #if defined(SQLITE3_INIT_QUERY) sql_query(SQLITE3_INIT_QUERY); #endif if (!check_tables_version(jcr, this)) { goto bail_out; } retval = true; bail_out: V(mutex); return retval; } void B_DB_SQLITE::db_close_database(JCR *jcr) { if (m_connected) { db_end_transaction(jcr); } P(mutex); m_ref_count--; if (m_ref_count == 0) { if (m_connected) { sql_free_result(); } db_list->remove(this); if (m_connected && m_db_handle) { sqlite3_close(m_db_handle); } if (rwl_is_init(&m_lock)) { rwl_destroy(&m_lock); } free_pool_memory(errmsg); free_pool_memory(cmd); free_pool_memory(cached_path); free_pool_memory(fname); free_pool_memory(path); free_pool_memory(esc_name); free_pool_memory(esc_path); free_pool_memory(esc_obj); if (m_db_driver) { free(m_db_driver); } if (m_db_name) { free(m_db_name); } delete this; if (db_list->size() == 0) { delete db_list; db_list = NULL; } } V(mutex); } bool B_DB_SQLITE::db_validate_connection(void) { bool retval; db_lock(this); if (sql_query("SELECT 1", true)) { sql_free_result(); retval = true; goto bail_out; } else { retval = false; goto bail_out; } bail_out: db_unlock(this); return retval; } void B_DB_SQLITE::db_thread_cleanup(void) { sqlite3_thread_cleanup(); } /* * Start a transaction. This groups inserts and makes things * much more efficient. Usually started when inserting * file attributes. */ void B_DB_SQLITE::db_start_transaction(JCR *jcr) { if (!jcr->attr) { jcr->attr = get_pool_memory(PM_FNAME); } if (!jcr->ar) { jcr->ar = (ATTR_DBR *)malloc(sizeof(ATTR_DBR)); } if (!m_allow_transactions) { return; } db_lock(this); /* * Allow only 10,000 changes per transaction */ if (m_transaction && changes > 10000) { db_end_transaction(jcr); } if (!m_transaction) { sql_query("BEGIN"); /* begin transaction */ Dmsg0(400, "Start SQLite transaction\n"); m_transaction = true; } db_unlock(this); } void B_DB_SQLITE::db_end_transaction(JCR *jcr) { if (jcr && jcr->cached_attribute) { Dmsg0(400, "Flush last cached attribute.\n"); if (!db_create_attributes_record(jcr, this, jcr->ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } if (!m_allow_transactions) { return; } db_lock(this); if (m_transaction) { sql_query("COMMIT"); /* end transaction */ m_transaction = false; Dmsg1(400, "End SQLite transaction changes=%d\n", changes); } changes = 0; db_unlock(this); } struct rh_data { B_DB_SQLITE *mdb; DB_RESULT_HANDLER *result_handler; void *ctx; bool initialized; }; /* * Convert SQLite's callback into BAREOS DB callback */ static int sqlite_result_handler(void *arh_data, int num_fields, char **rows, char **col_names) { struct rh_data *rh_data = (struct rh_data *)arh_data; /* The db_sql_query doesn't have access to m_results, so if we wan't to get * fields information, we need to use col_names */ if (!rh_data->initialized) { rh_data->mdb->set_column_names(col_names, num_fields); rh_data->initialized = true; } if (rh_data->result_handler) { (*(rh_data->result_handler))(rh_data->ctx, num_fields, rows); } return 0; } /* * Submit a general SQL command (cmd), and for each row returned, * the result_handler is called with the ctx. */ bool B_DB_SQLITE::db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { bool retval = false; int status; struct rh_data rh_data; Dmsg1(500, "db_sql_query starts with '%s'\n", query); db_lock(this); if (m_lowlevel_errmsg) { sqlite3_free(m_lowlevel_errmsg); m_lowlevel_errmsg = NULL; } sql_free_result(); rh_data.ctx = ctx; rh_data.mdb = this; rh_data.initialized = false; rh_data.result_handler = result_handler; status = sqlite3_exec(m_db_handle, query, sqlite_result_handler, (void *)&rh_data, &m_lowlevel_errmsg); if (status != SQLITE_OK) { Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror()); Dmsg0(500, "db_sql_query finished\n"); goto bail_out; } Dmsg0(500, "db_sql_query finished\n"); sql_free_result(); retval = true; bail_out: db_unlock(this); return retval; } /* * Submit a sqlite query and retrieve all the data */ bool B_DB_SQLITE::sql_query(const char *query, int flags) { int status; bool retval = false; Dmsg1(500, "sql_query starts with '%s'\n", query); sql_free_result(); if (m_lowlevel_errmsg) { sqlite3_free(m_lowlevel_errmsg); m_lowlevel_errmsg = NULL; } status = sqlite3_get_table(m_db_handle, (char *)query, &m_result, &m_num_rows, &m_num_fields, &m_lowlevel_errmsg); m_row_number = 0; /* no row fetched */ if (status != 0) { /* something went wrong */ m_num_rows = m_num_fields = 0; Dmsg0(500, "sql_query finished\n"); } else { Dmsg0(500, "sql_query finished\n"); retval = true; } return retval; } void B_DB_SQLITE::sql_free_result(void) { db_lock(this); if (m_fields) { free(m_fields); m_fields = NULL; } if (m_result) { sqlite3_free_table(m_result); m_result = NULL; } m_col_names = NULL; m_num_rows = m_num_fields = 0; db_unlock(this); } /* * Fetch one row at a time */ SQL_ROW B_DB_SQLITE::sql_fetch_row(void) { if (!m_result || (m_row_number >= m_num_rows)) { return NULL; } m_row_number++; return &m_result[m_num_fields * m_row_number]; } const char *B_DB_SQLITE::sql_strerror(void) { return m_lowlevel_errmsg ? m_lowlevel_errmsg : "unknown"; } void B_DB_SQLITE::sql_data_seek(int row) { /* * Set the row number to be returned on the next call to sql_fetch_row */ m_row_number = row; } int B_DB_SQLITE::sql_affected_rows(void) { return sqlite3_changes(m_db_handle); } uint64_t B_DB_SQLITE::sql_insert_autokey_record(const char *query, const char *table_name) { /* * First execute the insert query and then retrieve the currval. */ if (!sql_query(query)) { return 0; } m_num_rows = sql_affected_rows(); if (m_num_rows != 1) { return 0; } changes++; return sqlite3_last_insert_rowid(m_db_handle); } SQL_FIELD *B_DB_SQLITE::sql_fetch_field(void) { int i, j, len; /* We are in the middle of a db_sql_query and we want to get fields info */ if (m_col_names != NULL) { if (m_num_fields > m_field_number) { m_sql_field.name = m_col_names[m_field_number]; /* We don't have the maximum field length, so we can use 80 as * estimation. */ len = MAX(cstrlen(m_sql_field.name), 80/m_num_fields); m_sql_field.max_length = len; m_field_number++; m_sql_field.type = 0; /* not numeric */ m_sql_field.flags = 1; /* not null */ return &m_sql_field; } else { /* too much fetch_field() */ return NULL; } } /* We are after a sql_query() that stores the result in m_results */ if (!m_fields || m_fields_size < m_num_fields) { if (m_fields) { free(m_fields); m_fields = NULL; } Dmsg1(500, "allocating space for %d fields\n", m_num_fields); m_fields = (SQL_FIELD *)malloc(sizeof(SQL_FIELD) * m_num_fields); m_fields_size = m_num_fields; for (i = 0; i < m_num_fields; i++) { Dmsg1(500, "filling field %d\n", i); m_fields[i].name = m_result[i]; m_fields[i].max_length = cstrlen(m_fields[i].name); for (j = 1; j <= m_num_rows; j++) { if (m_result[i + m_num_fields * j]) { len = (uint32_t)cstrlen(m_result[i + m_num_fields * j]); } else { len = 0; } if (len > m_fields[i].max_length) { m_fields[i].max_length = len; } } m_fields[i].type = 0; m_fields[i].flags = 1; /* not null */ Dmsg4(500, "sql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", m_fields[i].name, m_fields[i].max_length, m_fields[i].type, m_fields[i].flags); } } /* * Increment field number for the next time around */ return &m_fields[m_field_number++]; } bool B_DB_SQLITE::sql_field_is_not_null(int field_type) { switch (field_type) { case 1: return true; default: return false; } } bool B_DB_SQLITE::sql_field_is_numeric(int field_type) { switch (field_type) { case 1: return true; default: return false; } } /* * Returns true if OK * false if failed */ bool B_DB_SQLITE::sql_batch_start(JCR *jcr) { bool retval; db_lock(this); retval = sql_query("CREATE TEMPORARY TABLE batch (" "FileIndex integer," "JobId integer," "Path blob," "Name blob," "LStat tinyblob," "MD5 tinyblob," "DeltaSeq integer)"); db_unlock(this); return retval; } /* set error to something to abort operation */ /* * Returns true if OK * false if failed */ bool B_DB_SQLITE::sql_batch_end(JCR *jcr, const char *error) { m_status = 0; return true; } /* * Returns true if OK * false if failed */ bool B_DB_SQLITE::sql_batch_insert(JCR *jcr, ATTR_DBR *ar) { const char *digest; char ed1[50]; esc_name = check_pool_memory_size(esc_name, fnl*2+1); db_escape_string(jcr, esc_name, fname, fnl); esc_path = check_pool_memory_size(esc_path, pnl*2+1); db_escape_string(jcr, esc_path, path, pnl); if (ar->Digest == NULL || ar->Digest[0] == 0) { digest = "0"; } else { digest = ar->Digest; } Mmsg(cmd, "INSERT INTO batch VALUES " "(%u,%s,'%s','%s','%s','%s',%u)", ar->FileIndex, edit_int64(ar->JobId,ed1), esc_path, esc_name, ar->attr, digest, ar->DeltaSeq); return sql_query(cmd); } /* * Initialize database data structure. In principal this should * never have errors, or it is really fatal. */ #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" B_DB CATS_IMP_EXP *backend_instantiate(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #else B_DB *db_init_database(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, const char *db_password, const char *db_address, int db_port, const char *db_socket, bool mult_db_connections, bool disable_batch_insert, bool need_private) #endif { B_DB *mdb = NULL; P(mutex); /* lock DB queue */ /* * Look to see if DB already open */ if (db_list && !mult_db_connections && !need_private) { foreach_dlist(mdb, db_list) { if (mdb->is_private()) { continue; } if (mdb->db_match_database(db_driver, db_name, db_address, db_port)) { Dmsg1(300, "DB REopen %s\n", db_name); mdb->increment_refcount(); goto bail_out; } } } Dmsg0(300, "db_init_database first time\n"); mdb = New(B_DB_SQLITE(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, db_socket, mult_db_connections, disable_batch_insert, need_private)); bail_out: V(mutex); return mdb; } #ifdef HAVE_DYNAMIC_CATS_BACKENDS extern "C" void CATS_IMP_EXP flush_backend(void) #else void db_flush_backends(void) #endif { } #endif /* HAVE_SQLITE3 */ bareos-Release-14.2.6/src/cats/update_bareos_tables.in000066400000000000000000000110671263011562700226650ustar00rootroot00000000000000#!/bin/sh # # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2000-2011 Free Software Foundation Europe e.V. # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # This script will update a BAREOS database to the latest version. # # # Source the Bareos config functions. # . @scriptdir@/bareos-config-lib.sh db_name="${db_name:-`get_database_name @db_name@`}" db_user="${db_user:-`get_database_user @db_user@`}" db_version=`get_database_version` bareos_sql_ddl=`get_database_ddl_dir` temp_sql_schema="/tmp/tables.sql.$$" default_db_type=`get_database_driver_default` working_dir=`get_working_dir` # # See if the first argument is a valid backend name. # If so the user overrides the default database backend. # if [ $# -gt 0 ]; then case $1 in sqlite3) db_type=$1 shift ;; mysql) db_type=$1 shift ;; postgresql) db_type=$1 shift ;; ingres) db_type=$1 shift ;; *) ;; esac fi # # If no new db_type is gives use the default db_type. # if [ -z "${db_type}" ]; then db_type="${default_db_type}" fi echo "Updating ${db_type} tables" bindir=`get_database_utility_path ${db_type}` if [ ! -z "${bindir}" ]; then PATH="$bindir:$PATH" fi while [ 1 ] do # # Figure out what the current version of the database is. # case ${db_type} in sqlite3) DBVERSION=`echo 'SELECT MAX(VersionId) FROM Version;' | sqlite3 ${working_dir}/${db_name}.db` ;; mysql) DBVERSION=`mysql -D ${db_name} $* -e "SELECT MAX(VersionId) FROM Version\G" | \ sed -n -e 's/^.*VersionId.*: \(.*\)$/\1/p'` ;; postgresql) DBVERSION=`psql -d ${db_name} -t --pset format=unaligned -c "SELECT MAX(VersionId) FROM Version;" $*` ;; ingres) DBVERSION="@BDB_VERSION@" ;; *) echo "Unknown database type ${db_type}" exit 1 ;; esac if [ -z "${DBVERSION}" ]; then echo "Unable to determine version of Bareos ${db_type} database" exit 1 fi if [ ${DBVERSION} = ${db_version} ]; then echo "Finished upgrading database to version ${db_version}" exit 0 fi # # See if its a known conversion. # found=0 known_conversions=`ls ${bareos_sql_ddl}/updates/${db_type}* 2>/dev/null| \ sed -e 's#.*/##' | \ cut -d'.' -f2` for conversion in ${known_conversions} do start_version=`echo ${conversion} | cut -d_ -f1` end_version=`echo ${conversion} | cut -d_ -f2` if [ ${start_version} = ${DBVERSION} ]; then found=1 break fi done if [ ${found} = 0 ]; then echo "Don't know how to upgrade from version ${DBVERSION} to ${db_version}" exit 1 fi sql_definitions="${bareos_sql_ddl}/updates/${db_type}.${conversion}.sql" if [ ! -f ${sql_definitions} ]; then echo "Unable to open database update definitions in file ${sql_definitions}" exit 1 fi sed -e "s/@DB_NAME@/${db_name}/" \ -e "s/@DB_USER@/${db_user}/" \ ${sql_definitions} > ${temp_sql_schema} echo "Upgrading database schema from version ${start_version} to ${end_version}" case ${db_type} in sqlite3) sqlite3 $* ${working_dir}/${db_name}.db < ${temp_sql_schema} retval=0 ;; mysql) mysql -D ${db_name} $* < ${temp_sql_schema} retval=$? ;; postgresql) psql -f ${temp_sql_schema} -d ${db_name} $* retval=$? ;; ingres) sql -u${db_user} $* ${db_name} < ${temp_sql_schema} retval=$? ;; esac rm -f ${temp_sql_schema} if [ ${retval} != 0 ]; then echo "Failed to upgrade database schema from version ${start_version} to ${end_version}" break; fi done exit ${retval} bareos-Release-14.2.6/src/console/000077500000000000000000000000001263011562700166715ustar00rootroot00000000000000bareos-Release-14.2.6/src/console/Makefile.in000066400000000000000000000102211263011562700207320ustar00rootroot00000000000000@MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/console DEBUG=@DEBUG@ first_rule: all dummy: # CONSSRCS = console.c console_conf.c @CONS_SRC@ CONSOBJS = $(CONSSRCS:.c=.o) GETTEXT_LIBS = @LIBINTL@ OPENSSL_LIBS_NONSHARED = @OPENSSL_LIBS_NONSHARED@ GNUTLS_LIBS_NONSHARED = @GNUTLS_LIBS_NONSHARED@ CONS_INC = @CONS_INC@ CONS_LIBS = @CONS_LIBS@ CONS_LDFLAGS = @CONS_LDFLAGS@ INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .o .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(CONS_INC) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile bconsole @STATIC_CONS@ @echo "==== Make of console is good ====" @echo " " bconsole: Makefile $(CONSOBJS) ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) $(CONS_LDFLAGS) -L../lib -L../cats -o $@ $(CONSOBJS) \ $(DLIB) $(CONS_LIBS) -lbareoscfg -lbareos -lm $(LIBS) $(GETTEXT_LIBS) \ $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) static-bconsole: Makefile $(CONSOBJS) ../lib/libbareos.a ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) -static $(LDFLAGS) $(CONS_LDFLAGS) -L../lib -L../cats -o $@ $(CONSOBJS) \ $(DLIB) $(CONS_LIBS) -lbareoscfg -lbareos -lm $(LIBS) $(GETTEXT_LIBS) \ $(OPENSSL_LIBS) $(GNUTLS_LIBS) strip $@ Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) console bconsole core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 @$(RMF) static-console static-bconsole gmon.out realclean: clean @$(RMF) tags console.conf bconsole.conf distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) install: all @if test -f ${DESTDIR}${sbindir}/console; then \ echo " "; \ echo "Warning!!! ${DESTDIR}${sbindir}/console found."; \ echo " console has been renamed bconsole, so console"; \ echo " is no longer used, and you might want to delete it."; \ echo " "; \ fi $(MKDIR) $(DESTDIR)$(bindir) $(MKDIR) $(DESTDIR)$(sbindir) $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bconsole $(DESTDIR)$(bindir)/bconsole; @if ! [ -r $(DESTDIR)$(sbindir)/bconsole ]; then $(SYMLINK) $(bindir)/bconsole $(DESTDIR)$(sbindir)/bconsole; fi @srcconf=bconsole.conf; \ if test -f ${DESTDIR}${sysconfdir}/$$srcconf; then \ destconf=$$srcconf.new; \ echo " ==> Found existing $$srcconf, installing new conf file as $$destconf"; \ else \ destconf=$$srcconf; \ if test -f ${DESTDIR}${sysconfdir}/console.conf; then \ echo "Existing console.conf moved to bconsole.conf"; \ @$(MV) ${DESTDIR}${sysconfdir}/console.conf ${DESTDIR}${sysconfdir}/bconsole.conf; \ destconf=$$srcconf.new; \ fi; \ fi; \ echo "${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf"; \ ${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf if test -f static-bconsole; then \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) static-bconsole $(DESTDIR)$(sbindir)/static-bconsole; \ fi # Semi-automatic generation of dependencies: # Use gcc -MM because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @$(CXX) -S -M $(CPPFLAGS) $(CONS_INC) $(INCLUDES) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/console/bconsole.conf.in000066400000000000000000000002521263011562700217500ustar00rootroot00000000000000# # Bareos User Agent (or Console) Configuration File # Director { Name = @basename@-dir DIRport = @dir_port@ address = @hostname@ Password = "@dir_password@" } bareos-Release-14.2.6/src/console/conio.c000077500000000000000000001001301263011562700201420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 1981-2012 Free Software Foundation Europe e.V. Yes, that is 1981 no error. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Generalized console input/output handler * A maintanable replacement for readline() * * Kern Sibbald, December MMIII * * This code is in part derived from code that I wrote in * 1981, so some of it is a bit old and could use a cleanup. */ /* * UTF-8 * If the top bit of a UTF-8 string is 0 (8 bits), then it * is a normal ASCII character. * If the top two bits are 11 (i.e. (c & 0xC0) == 0xC0 then * it is the start of a series of chars (up to 5) * Each subsequent character starts with 10 (i.e. (c & 0xC0) == 0x80) */ #ifdef TEST_PROGRAM #include #include #include #include #include #include #define HAVE_CONIO 1 #else /* We are in Bareos */ #include "bareos.h" #endif #ifdef HAVE_CONIO #include #include #if defined(HAVE_SUN_OS) #if !defined(_TERM_H) extern "C" int tgetent(void *, const char *); extern "C" int tgetnum(const char *); extern "C" char *tgetstr (const char*, char**); /* * Note: the following on older (Solaris 10) systems * may need to be moved to after the #endif */ extern "C" char *tgoto (const char *, int, int); #endif #elif defined(__sgi) extern "C" int tgetent(char *, char *); extern "C" int tgetnum(char id[2]); extern "C" char *tgetstr(char id[2], char **); extern "C" char *tgoto(char *, int, int); #elif defined (__digital__) && defined (__unix__) extern "C" int tgetent(void *, const char *); extern "C" int tgetnum(const char *); extern "C" char *tgetstr (const char*, char**); extern "C" char *tgoto (const char *, int, int); #endif #include "func.h" /* From termios library */ #if defined(HAVE_HPUX_OS) || defined(HAVE_AIX_OS) static char *BC; static char *UP; #else extern char *BC; extern char *UP; #endif /* Forward referenced functions */ extern "C" { static void sigintcatcher(int); } static void add_smap(char *str, int func); /* Global variables */ static const char *t_up = "\n"; /* scroll up character */ static const char *t_honk = "\007"; /* sound beep */ static char *t_il; /* insert line */ static char *t_dl; /* delete line */ static char *t_cs; /* clear screen */ static char *t_cl; /* clear line */ static int t_width = 79; /* terminal width */ static int t_height = 24; /* terminal height */ static int linsdel_ok = 0; /* set if term has line insert & delete fncs */ static char *t_cm; /* cursor positioning */ static char *t_ti; /* init sequence */ static char *t_te; /* end sequence */ static char *t_do; /* down one line */ static char *t_sf; /* scroll screen one line up */ /* Keypad and Function Keys */ static char *kl; /* left key */ static char *kr; /* right */ static char *ku; /* up */ static char *kd; /* down */ static char *kh; /* home */ static char *kb; /* backspace */ static char *kD; /* delete key */ static char *kI; /* insert */ static char *kN; /* next page */ static char *kP; /* previous page */ static char *kH; /* home */ static char *kE; /* end */ #ifndef EOS #define EOS '\0' /* end of string terminator */ #endif #define TRUE 1 #define FALSE 0 /* * Stab entry. Input chars (str), the length, and the desired * func code. */ typedef struct s_stab { struct s_stab *next; char *str; int len; int func; } stab_t; #define MAX_STAB 30 static stab_t **stab = NULL; /* array of stabs by length */ static int num_stab; /* size of stab array */ static bool old_term_params_set = false; static struct termios old_term_params; /* Maintain lines in a doubly linked circular pool of lines. Each line is preceded by a header defined by the lstr structure */ struct lstr { /* line pool structure */ struct lstr *prevl; /* link to previous line */ struct lstr *nextl; /* link to next line */ long len; /* length of line+header */ char used; /* set if line valid */ char line; /* line is actually varying length */ }; #ifdef unix #define POOLEN 128000 /* bytes in line pool */ #else #define POOLEN 500 /* bytes in line pool */ #endif char pool[POOLEN]; /* line pool */ #define PHDRL ((int)sizeof(struct lstr)) /* length of line header */ static struct lstr *lptr; /* current line pointer */ static struct lstr *slptr; /* store line pointer */ static int cl, cp; static char *getnext(), *getprev(); static int first = 1; static int mode_insert = 1; static int mode_wspace = 1; /* words separated by spaces */ static short char_map[600]= { 0, F_SOL, /* ^a Line start */ F_PRVWRD, /* ^b Previous word */ F_BREAK, /* ^C break */ F_DELCHR, /* ^D Delete character */ F_EOL, /* ^e End of line */ F_CSRRGT, /* ^f Right */ F_TABBAK, /* ^G Back tab */ F_CSRLFT, /* ^H Left */ F_TAB, /* ^I Tab */ F_CSRDWN, /* ^J Down */ F_DELEOL, /* ^K kill to eol */ F_CLRSCRN,/* ^L clear screen */ F_RETURN, /* ^M Carriage return */ F_RETURN, /* ^N enter line */ F_CONCAT, /* ^O Concatenate lines */ F_CSRUP, /* ^P cursor up */ F_TINS, /* ^Q Insert character mode */ F_PAGUP, /* ^R Page up */ F_CENTER, /* ^S Center text */ F_PAGDWN, /* ^T Page down */ F_DELSOL, /* ^U delete to start of line */ F_DELWRD, /* ^V Delete word */ F_PRVWRD, /* ^W Previous word */ F_NXTMCH, /* ^X Next match */ F_DELEOL, /* ^Y Delete to end of line */ F_BACKGND,/* ^Z Background */ 0x1B, /* ^[=ESC escape */ F_TENTRY, /* ^\ Entry mode */ F_PASTECB,/* ^]=paste clipboard */ F_HOME, /* ^^ Home */ F_ERSLIN, /* ^_ Erase line */ ' ','!','"','#','$','%','&','\047', '(',')','*','+','\054','-','.','/', '0','1','2','3','4','5','6','7', '8','9',':',';','<','=','>','?', '@','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O', 'P','Q','R','S','T','U','V','W', 'X','Y','Z','[','\\',']','^','_', '\140','a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w', 'x','y','z','{','|','}','\176',F_ERSCHR /* erase character */ }; /* Local variables */ #define CR '\r' /* carriage return */ /* Function Prototypes */ static unsigned int input_char(void); static unsigned int t_gnc(void); static void insert_space(char *curline, int line_len); static void insert_hole(char *curline, int line_len); static void forward(char *str, int str_len); static void backup(char *curline); static void delchr(int cnt, char *curline, int line_len); static int iswordc(char c); static int next_word(char *ldb_buf); static int prev_word(char *ldb_buf); static void prtcur(char *str); static void poolinit(void); static char * getnext(void); static char * getprev(void); static void putline(char *newl, int newlen); static void t_honk_horn(void); static void t_insert_line(void); static void t_delete_line(void); static void t_clrline(int pos, int width); void t_sendl(const char *msg, int len); void t_send(const char *msg); void t_char(char c); static void asclrs(); static void ascurs(int y, int x); static void rawmode(FILE *input); static void normode(void); static unsigned t_getch(); static void asclrl(int pos, int width); static void asinsl(); static void asdell(); int input_line(char *string, int length); extern "C" { void con_term(); } void trapctlc(); int usrbrk(); void clrbrk(); void con_init(FILE *input) { atexit(con_term); rawmode(input); trapctlc(); } /* * Zed control keys */ void con_set_zed_keys(void) { char_map[1] = F_NXTWRD; /* ^A Next Word */ char_map[2] = F_SPLIT; /* ^B Split line */ char_map[3] = F_EOI; /* ^C Quit */ char_map[4] = F_DELCHR; /* ^D Delete character */ char_map[5] = F_EOF; /* ^E End of file */ char_map[6] = F_INSCHR; /* ^F Insert character */ char_map[7] = F_TABBAK; /* ^G Back tab */ char_map[8] = F_CSRLFT; /* ^H Left */ char_map[9] = F_TAB; /* ^I Tab */ char_map[10] = F_CSRDWN; /* ^J Down */ char_map[11] = F_CSRUP; /* ^K Up */ char_map[12] = F_CSRRGT; /* ^L Right */ char_map[13] = F_RETURN; /* ^M Carriage return */ char_map[14] = F_EOL; /* ^N End of line */ char_map[15] = F_CONCAT; /* ^O Concatenate lines */ char_map[16] = F_MARK; /* ^P Set marker */ char_map[17] = F_TINS; /* ^Q Insert character mode */ char_map[18] = F_PAGUP; /* ^R Page up */ char_map[19] = F_CENTER; /* ^S Center text */ char_map[20] = F_PAGDWN; /* ^T Page down */ char_map[21] = F_SOL; /* ^U Line start */ char_map[22] = F_DELWRD; /* ^V Delete word */ char_map[23] = F_PRVWRD; /* ^W Previous word */ char_map[24] = F_NXTMCH; /* ^X Next match */ char_map[25] = F_DELEOL; /* ^Y Delete to end of line */ char_map[26] = F_DELLIN; /* ^Z Delete line */ /* 27 = ESC */ char_map[28] = F_TENTRY; /* ^\ Entry mode */ char_map[29] = F_PASTECB;/* ^]=paste clipboard */ char_map[30] = F_HOME; /* ^^ Home */ char_map[31] = F_ERSLIN; /* ^_ Erase line */ } void con_term() { normode(); } #ifdef TEST_PROGRAM /* * Guarantee that the string is properly terminated */ char *bstrncpy(char *dest, const char *src, int maxlen) { strncpy(dest, src, maxlen-1); dest[maxlen-1] = 0; return dest; } #endif /* * New style string mapping to function code */ static unsigned do_smap(unsigned c) { char str[MAX_STAB]; int len = 0; stab_t *tstab; int i, found; unsigned cm; len = 1; str[0] = c; str[1] = 0; cm = char_map[c]; if (cm == 0) { return c; } else { c = cm; } for ( ;; ) { found = 0; for (i=len-1; inext) { if (bstrncmp(str, tstab->str, len)) { if (len == tstab->len) { return tstab->func; } found = 1; break; /* found possibility continue searching */ } } } if (!found) { return len==1?c:0; } /* found partial match, so get next character and retry */ str[len++] = t_gnc(); str[len] = 0; } } #ifdef DEBUG_x static void dump_stab() { int i, j, c; stab_t *tstab; char buf[100]; for (i=0; inext) { for (j=0; jlen; j++) { c = tstab->str[j]; if (c < 0x20 || c > 0x7F) { sprintf(buf, " 0x%x ", c); t_send(buf); } else { buf[0] = c; buf[1] = 0; t_sendl(buf, 1); } } sprintf(buf, " func=%d len=%d\n\r", tstab->func, tstab->len); t_send(buf); } } } #endif /* * New routine. Add string to string->func mapping table. */ static void add_smap(char *str, int func) { stab_t *tstab; int len; if (!str) { return; } len = strlen(str); if (len == 0) { /* errmsg("String for func %d is zero length\n", func); */ return; } tstab = (stab_t *)malloc(sizeof(stab_t)); memset(tstab, 0, sizeof(stab_t)); tstab->len = len; tstab->str = (char *)malloc(tstab->len + 1); bstrncpy(tstab->str, str, tstab->len + 1); tstab->func = func; if (tstab->len > num_stab) { printf("stab string too long %d. Max is %d\n", tstab->len, num_stab); exit(1); } tstab->next = stab[tstab->len-1]; stab[tstab->len-1] = tstab; /* printf("Add_smap tstab=%x len=%d func=%d tstab->next=%x\n\r", tstab, len, func, tstab->next); */ } /* Get the next character from the terminal - performs table lookup on the character to do the desired translation */ static unsigned int input_char() { unsigned c; if ((c=t_gnc()) <= 599) { /* IBM generates codes up to 260 */ c = do_smap(c); } else if (c > 1000) { /* stuffed function */ c -= 1000; /* convert back to function code */ } if (c <= 0) { t_honk_horn(); } /* if we got a screen size escape sequence, read height, width */ if (c == F_SCRSIZ) { t_gnc(); /* - 0x20 = y */ t_gnc(); /* - 0x20 = x */ c = input_char(); } return c; } /* Get a complete input line */ int input_line(char *string, int length) { char curline[2000]; /* edit buffer */ int noline; unsigned c; int more; int i; if (first) { poolinit(); /* build line pool */ first = 0; } noline = 1; /* no line fetched yet */ for (cl=cp=0; cl cp) cl = cp; break; case F_NXTWRD: i = next_word(curline); while (i--) { forward(curline, sizeof(curline)); } break; case F_PRVWRD: i = prev_word(curline); while (i--) { backup(curline); } break; case F_DELWRD: delchr(next_word(curline), curline, sizeof(curline)); /* delete word */ break; case F_NXTMCH: /* Ctl-X */ if (cl==0) { *string = EOS; /* terminate string */ return(c); /* give it to him */ } /* Note fall through */ case F_DELLIN: case F_ERSLIN: while (cp > 0) { backup(curline); /* backup to beginning of line */ } t_clrline(0, t_width); /* erase line */ cp = 0; cl = 0; /* reset cursor counter */ t_char(' '); t_char(0x8); break; case F_SOL: while (cp > 0) { backup(curline); } break; case F_EOL: while (cp < cl) { forward(curline, sizeof(curline)); } while (cp > cl) { backup(curline); } break; case F_TINS: /* toggle insert mode */ mode_insert = !mode_insert; /* flip bit */ break; default: if (c > 255) { /* function key hit */ if (cl==0) { /* if first character then */ *string = EOS; /* terminate string */ return c; /* return it */ } t_honk_horn(); /* complain */ } else { if ((c & 0xC0) == 0xC0) { if ((c & 0xFC) == 0xFC) { more = 5; } else if ((c & 0xF8) == 0xF8) { more = 4; } else if ((c & 0xF0) == 0xF0) { more = 3; } else if ((c & 0xE0) == 0xE0) { more = 2; } else { more = 1; } } else { more = 0; } if (mode_insert) { insert_space(curline, sizeof(curline)); } curline[cp++] = c; /* store character in line being built */ t_char(c); /* echo character to terminal */ while (more--) { c= input_char(); insert_hole(curline, sizeof(curline)); curline[cp++] = c; /* store character in line being built */ t_char(c); /* echo character to terminal */ } if (cp > cl) { cl = cp; /* keep current length */ curline[cp] = 0; } } break; } /* end switch */ } /* If we fall through here rather than goto done, the line is too long simply return what we have now. */ done: curline[cl++] = EOS; /* terminate */ bstrncpy(string,curline,length); /* return line to caller */ /* Save non-blank lines. Note, put line zaps curline */ if (curline[0] != EOS) { putline(curline,cl); /* save line for posterity */ } return 0; /* give it to him/her */ } /* Insert a space at the current cursor position */ static void insert_space(char *curline, int curline_len) { int i; if (cp >= cl || cl+1 > curline_len) { return; } /* Note! source and destination overlap */ memmove(&curline[cp+1],&curline[cp],i=cl-cp); cl++; curline[cp] = ' '; i = 0; while (cl > cp) { forward(curline, curline_len); i++; } while (i--) { backup(curline); } } static void insert_hole(char *curline, int curline_len) { int i; if (cp > cl || cl+1 > curline_len) { return; } /* Note! source and destination overlap */ memmove(&curline[cp+1], &curline[cp], i=cl-cp); cl++; curline[cl] = 0; } /* Move cursor forward keeping characters under it */ static void forward(char *str, int str_len) { if (cp > str_len) { return; } if (cp >= cl) { t_char(' '); str[cp+1] = ' '; str[cp+2] = 0; } else { t_char(str[cp]); if ((str[cp] & 0xC0) == 0xC0) { cp++; while ((str[cp] & 0xC0) == 0x80) { t_char(str[cp]); cp++; } cp--; } } cp++; } /* How many characters under the cursor */ static int char_count(int cptr, char *str) { int cnt = 1; if (cptr > cl) { return 0; } if ((str[cptr] & 0xC0) == 0xC0) { cptr++; while ((str[cptr] & 0xC0) == 0x80) { cnt++; cptr++; } } return cnt; } /* Backup cursor keeping characters under it */ static void backup(char *str) { if (cp == 0) { return; } while ((str[cp] & 0xC0) == 0x80) { cp--; } t_char('\010'); cp--; } /* Delete the character under the cursor */ static void delchr(int del, char *curline, int line_len) { int i, cnt; if (cp > cl || del == 0) { return; } while (del-- && cl > 0) { cnt = char_count(cp, curline); if ((i=cl-cp-cnt) > 0) { memcpy(&curline[cp], &curline[cp+cnt], i); } cl -= cnt; curline[cl] = EOS; t_clrline(0, t_width); i = 0; while (cl > cp) { forward(curline, line_len); i++; } while (i--) { backup(curline); } } } /* Determine if character is part of a word */ static int iswordc(char c) { if (mode_wspace) return !isspace(c); if (c >= '0' && c <= '9') return true; if (c == '$' || c == '%') return true; return isalpha(c); } /* Return number of characters to get to next word */ static int next_word(char *ldb_buf) { int ncp; if (cp > cl) return 0; ncp = cp; for ( ; ncp cl) /* if past eol start at eol */ ncp=cl+1; else ncp = cp; /* backup to end of previous word - i.e. skip special chars */ for (i=ncp-1; i && !iswordc(*(ldb_buf+i)); i--) ; if (i == 0) { /* at beginning of line? */ return cp; /* backup to beginning */ } /* now move back through word to beginning of word */ for ( ; i && iswordc(*(ldb_buf+i)); i--) ; ncp = i+1; /* position to first char of word */ if (i==0 && iswordc(*ldb_buf)) /* check for beginning of line */ ncp = 0; return cp-ncp; /* return count */ } /* Display new current line */ static void prtcur(char *str) { while (cp > 0) { backup(str); } t_clrline(0,t_width); cp = cl = strlen(str); t_sendl(str, cl); } /* Initialize line pool. Split pool into two pieces. */ static void poolinit() { slptr = lptr = (struct lstr *)pool; lptr->nextl = lptr; lptr->prevl = lptr; lptr->used = 1; lptr->line = 0; lptr->len = POOLEN; } /* Return pointer to next line in the pool and advance current line pointer */ static char * getnext() { do { /* find next used line */ lptr = lptr->nextl; } while (!lptr->used); return (char *)&lptr->line; } /* Return pointer to previous line in the pool */ static char * getprev() { do { /* find previous used line */ lptr = lptr->prevl; } while (!lptr->used); return (char *)&lptr->line; } static void putline(char *newl, int newlen) { struct lstr *nptr; /* points to next line */ char *p; lptr = slptr; /* get ptr to last line stored */ lptr = lptr->nextl; /* advance pointer */ if ((char *)lptr-pool+newlen+PHDRL > POOLEN) { /* not enough room */ lptr->used = 0; /* delete line */ lptr = (struct lstr *)pool; /* start at beginning of buffer */ } while (lptr->len < newlen+PHDRL) { /* concatenate buffers */ nptr = lptr->nextl; /* point to next line */ lptr->nextl = nptr->nextl; /* unlink it from list */ nptr->nextl->prevl = lptr; lptr->len += nptr->len; } if (lptr->len > newlen + 2 * PHDRL + 7) { /* split buffer */ nptr = (struct lstr *)((char *)lptr + newlen + PHDRL); /* Appropriate byte alignment - for Intel 2 byte, but on Sparc we need 8 byte alignment, so we always do 8 */ if (((long unsigned)nptr & 7) != 0) { /* test eight byte alignment */ p = (char *)nptr; nptr = (struct lstr *)((((long unsigned) p) & ~7) + 8); } nptr->len = lptr->len - ((char *)nptr - (char *)lptr); lptr->len -= nptr->len; nptr->nextl = lptr->nextl; /* link in new buffer */ lptr->nextl->prevl = nptr; lptr->nextl = nptr; nptr->prevl = lptr; nptr->used = 0; } memcpy(&lptr->line,newl,newlen); lptr->used = 1; /* mark line used */ slptr = lptr; /* save as stored line */ } #ifdef DEBUGOUT static void dump(struct lstr *ptr, char *msg) { printf("%s buf=%x nextl=%x prevl=%x len=%d used=%d\n", msg,ptr,ptr->nextl,ptr->prevl,ptr->len,ptr->used); if (ptr->used) printf("line=%s\n",&ptr->line); } #endif /* DEBUGOUT */ /* Honk horn on terminal */ static void t_honk_horn() { t_send(t_honk); } /* Insert line on terminal */ static void t_insert_line() { asinsl(); } /* Delete line from terminal */ static void t_delete_line() { asdell(); } /* clear line from pos to width */ static void t_clrline(int pos, int width) { asclrl(pos, width); /* clear to end of line */ } /* Helper function to add string preceded by * ESC to smap table */ static void add_esc_smap(const char *str, int func) { char buf[1000]; buf[0] = 0x1B; /* esc */ bstrncpy(buf+1, str, sizeof(buf)-1); add_smap(buf, func); } /* Set raw mode on terminal file. Basically, get the terminal into a mode in which all characters can be read as they are entered. CBREAK mode is not sufficient. */ static void rawmode(FILE *input) { struct termios t; static char term_buf[2048]; static char *term_buffer = term_buf; char *termtype = (char *)getenv("TERM"); /* Make sure we are dealing with a terminal */ if (!isatty(fileno(input))) { return; } if (tcgetattr(0, &old_term_params) != 0) { printf("conio: Cannot tcgetattr()\n"); exit(1); } old_term_params_set = true; t = old_term_params; t.c_cc[VMIN] = 1; /* satisfy read after 1 char */ t.c_cc[VTIME] = 0; t.c_iflag &= ~(BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | ICRNL | IXON | IXOFF | INLCR | IGNCR); t.c_iflag |= IGNBRK; t.c_oflag |= ONLCR; t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON | NOFLSH | TOSTOP); tcflush(0, TCIFLUSH); if (tcsetattr(0, TCSANOW, &t) == -1) { printf("Cannot tcsetattr()\n"); } /* Defaults, the main program can override these */ signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGINT, sigintcatcher); signal(SIGWINCH, SIG_IGN); if (!termtype) { printf("Cannot get terminal type.\n"); normode(); exit(1); } if (tgetent(term_buffer, termtype) < 0) { printf("Cannot get terminal termcap entry.\n"); normode(); exit(1); } t_width = t_height = -1; /* Note (char *)casting is due to really stupid compiler warnings */ t_width = tgetnum((char *)"co") - 1; t_height = tgetnum((char *)"li"); BC = NULL; UP = NULL; t_cm = (char *)tgetstr((char *)"cm", &term_buffer); t_cs = (char *)tgetstr((char *)"cl", &term_buffer); /* clear screen */ t_cl = (char *)tgetstr((char *)"ce", &term_buffer); /* clear line */ t_dl = (char *)tgetstr((char *)"dl", &term_buffer); /* delete line */ t_il = (char *)tgetstr((char *)"al", &term_buffer); /* insert line */ t_honk = (char *)tgetstr((char *)"bl", &term_buffer); /* beep */ t_ti = (char *)tgetstr((char *)"ti", &term_buffer); t_te = (char *)tgetstr((char *)"te", &term_buffer); t_up = (char *)tgetstr((char *)"up", &term_buffer); t_do = (char *)tgetstr((char *)"do", &term_buffer); t_sf = (char *)tgetstr((char *)"sf", &term_buffer); num_stab = MAX_STAB; /* get default stab size */ stab = (stab_t **)malloc(sizeof(stab_t *) * num_stab); memset(stab, 0, sizeof(stab_t *) * num_stab); /* Key bindings */ kl = (char *)tgetstr((char *)"kl", &term_buffer); kr = (char *)tgetstr((char *)"kr", &term_buffer); ku = (char *)tgetstr((char *)"ku", &term_buffer); kd = (char *)tgetstr((char *)"kd", &term_buffer); kh = (char *)tgetstr((char *)"kh", &term_buffer); kb = (char *)tgetstr((char *)"kb", &term_buffer); kD = (char *)tgetstr((char *)"kD", &term_buffer); kI = (char *)tgetstr((char *)"kI", &term_buffer); kN = (char *)tgetstr((char *)"kN", &term_buffer); kP = (char *)tgetstr((char *)"kP", &term_buffer); kH = (char *)tgetstr((char *)"kH", &term_buffer); kE = (char *)tgetstr((char *)"kE", &term_buffer); add_smap(kl, F_CSRLFT); add_smap(kr, F_CSRRGT); add_smap(ku, F_CSRUP); add_smap(kd, F_CSRDWN); add_smap(kI, F_TINS); add_smap(kN, F_PAGDWN); add_smap(kP, F_PAGUP); add_smap(kH, F_HOME); add_smap(kE, F_EOF); add_esc_smap("[A", F_CSRUP); add_esc_smap("[B", F_CSRDWN); add_esc_smap("[C", F_CSRRGT); add_esc_smap("[D", F_CSRLFT); add_esc_smap("[1~", F_HOME); add_esc_smap("[2~", F_TINS); add_esc_smap("[3~", F_DELCHR); add_esc_smap("[4~", F_EOF); add_esc_smap("f", F_NXTWRD); add_esc_smap("b", F_PRVWRD); } /* Restore tty mode */ static void normode() { if (old_term_params_set) { tcsetattr(0, TCSANOW, &old_term_params); old_term_params_set = false; } } /* Get next character from terminal/script file/unget buffer */ static unsigned t_gnc() { return t_getch(); } /* Get next character from OS */ static unsigned t_getch(void) { unsigned char c; if (read(0, &c, 1) != 1) { c = 0; } return (unsigned)c; } /* Send message to terminal - primitive routine */ void t_sendl(const char *msg, int len) { write(1, msg, len); } void t_send(const char *msg) { if (msg == NULL) { return; } t_sendl(msg, strlen(msg)); /* faster than one char at time */ } /* Send single character to terminal - primitive routine - */ void t_char(char c) { (void)write(1, &c, 1); } static int brkflg = 0; /* set on user break */ /* Routine to return true if user types break */ int usrbrk() { return brkflg; } /* Clear break flag */ void clrbrk() { brkflg = 0; } /* Interrupt caught here */ static void sigintcatcher(int sig) { brkflg++; if (brkflg > 3) { normode(); exit(1); } signal(SIGINT, sigintcatcher); } /* Trap Ctl-C */ void trapctlc() { signal(SIGINT, sigintcatcher); } /* ASCLRL() -- Clear to end of line from current position */ static void asclrl(int pos, int width) { int i; if (t_cl) { t_send(t_cl); /* use clear to eol function */ return; } if (pos==1 && linsdel_ok) { t_delete_line(); /* delete line */ t_insert_line(); /* reinsert it */ return; } for (i=1; i<=width-pos+1; i++) t_char(' '); /* last resort, blank it out */ for (i=1; i<=width-pos+1; i++) /* backspace to original position */ t_char(0x8); return; } /* ASCURS -- Set cursor position */ static void ascurs(int y, int x) { t_send((char *)tgoto(t_cm, x, y)); } /* ASCLRS -- Clear whole screen */ static void asclrs() { ascurs(0,0); t_send(t_cs); } /* ASINSL -- insert new line after cursor */ static void asinsl() { t_clrline(0, t_width); t_send(t_il); /* insert before */ } /* ASDELL -- Delete line at cursor */ static void asdell() { t_send(t_dl); } #endif bareos-Release-14.2.6/src/console/conio.h000066400000000000000000000023011263011562700201450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __CONIO_H #define __CONIO_H extern int input_line(char *line, int len); extern void con_init(FILE *input); extern "C" { extern void con_term(); } extern void con_set_zed_keys(); extern void t_sendl(char *buf, int len); extern void t_send(char *buf); extern void t_char(char c); extern int usrbrk(void); extern void clrbrk(void); extern void trapctlc(void); #endif bareos-Release-14.2.6/src/console/console.c000066400000000000000000001230351263011562700205030ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos Console interface to the Director * * Kern Sibbald, September MM */ #include "bareos.h" #include "console_conf.h" #include "jcr.h" #ifdef HAVE_CONIO #include "conio.h" //#define CONIO_FIX 1 #else #define con_init(x) #define con_term() #define con_set_zed_keys(); #define trapctlc() #define clrbrk() #define usrbrk() 0 #endif #if defined(HAVE_WIN32) #define isatty(fd) (fd==0) #endif /* Exported variables */ CONRES *me = NULL; /* Our Global resource */ CONFIG *my_config = NULL; /* Our Global config */ //extern int rl_catch_signals; /* Imported functions */ extern bool parse_cons_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ static void terminate_console(int sig); static int check_resources(); int get_cmd(FILE *input, const char *prompt, BSOCK *sock, int sec); static int do_outputcmd(FILE *input, BSOCK *UA_sock); void senditf(const char *fmt, ...); void sendit(const char *buf); extern "C" void got_sigstop(int sig); extern "C" void got_sigcontinue(int sig); extern "C" void got_sigtout(int sig); extern "C" void got_sigtin(int sig); /* Static variables */ static char *configfile = NULL; static BSOCK *UA_sock = NULL; static DIRRES *dir = NULL; static CONRES *cons = NULL; static FILE *output = stdout; static bool teeout = false; /* output to output and stdout */ static bool stop = false; static bool no_conio = false; static int timeout = 0; static int argc; static int numdir; static POOLMEM *args; static char *argk[MAX_CMD_ARGS]; static char *argv[MAX_CMD_ARGS]; static bool file_selection = false; /* Command prototypes */ static int versioncmd(FILE *input, BSOCK *UA_sock); static int inputcmd(FILE *input, BSOCK *UA_sock); static int outputcmd(FILE *input, BSOCK *UA_sock); static int teecmd(FILE *input, BSOCK *UA_sock); static int quitcmd(FILE *input, BSOCK *UA_sock); static int helpcmd(FILE *input, BSOCK *UA_sock); static int echocmd(FILE *input, BSOCK *UA_sock); static int timecmd(FILE *input, BSOCK *UA_sock); static int sleepcmd(FILE *input, BSOCK *UA_sock); static int execcmd(FILE *input, BSOCK *UA_sock); #ifdef HAVE_READLINE static int eolcmd(FILE *input, BSOCK *UA_sock); #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif #endif #define CONFIG_FILE "bconsole.conf" /* default configuration file */ static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: " VERSION " (" BDATE ") %s %s %s\n\n" "Usage: bconsole [-s] [-c config_file] [-d debug_level]\n" " -D select a Director\n" " -l list Directors defined\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n no conio\n" " -s no signals\n" " -u set command execution timeout to seconds\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n"), 2000, HOST_OS, DISTNAME, DISTVER); } extern "C" void got_sigstop(int sig) { stop = true; } extern "C" void got_sigcontinue(int sig) { stop = false; } extern "C" void got_sigtout(int sig) { // printf("Got tout\n"); } extern "C" void got_sigtin(int sig) { // printf("Got tin\n"); } static int zed_keyscmd(FILE *input, BSOCK *UA_sock) { con_set_zed_keys(); return 1; } /* * These are the @command */ struct cmdstruct { const char *key; int (*func)(FILE *input, BSOCK *UA_sock); const char *help; }; static struct cmdstruct commands[] = { { N_("input"), inputcmd, _("input from file")}, { N_("output"), outputcmd, _("output to file")}, { N_("quit"), quitcmd, _("quit")}, { N_("tee"), teecmd, _("output to file and terminal")}, { N_("sleep"), sleepcmd, _("sleep specified time")}, { N_("time"), timecmd, _("print current time")}, { N_("version"), versioncmd, _("print Console's version")}, { N_("echo"), echocmd, _("echo command string")}, { N_("exec"), execcmd, _("execute an external command")}, { N_("exit"), quitcmd, _("exit = quit")}, { N_("zed_keys"), zed_keyscmd, _("zed_keys = use zed keys instead of bash keys")}, { N_("help"), helpcmd, _("help listing")}, #ifdef HAVE_READLINE { N_("separator"), eolcmd, _("set command separator")}, #endif }; #define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct))) static int do_a_command(FILE *input, BSOCK *UA_sock) { unsigned int i; int status; int found; int len; char *cmd; found = 0; status = 1; Dmsg1(120, "Command: %s\n", UA_sock->msg); if (argc == 0) { return 1; } cmd = argk[0]+1; if (*cmd == '#') { /* comment */ return 1; } len = strlen(cmd); for (i=0; imsg, _(": is an invalid command\n")); UA_sock->msglen = strlen(UA_sock->msg); sendit(UA_sock->msg); } return status; } static void read_and_process_input(FILE *input, BSOCK *UA_sock) { const char *prompt = "*"; bool at_prompt = false; int tty_input = isatty(fileno(input)); int status; btimer_t *tid = NULL; while (1) { if (at_prompt) { /* don't prompt multiple times */ prompt = ""; } else { prompt = "*"; at_prompt = true; } if (tty_input) { status = get_cmd(input, prompt, UA_sock, 30); if (usrbrk() == 1) { clrbrk(); } if (usrbrk()) { break; } } else { /* * Reading input from a file */ int len = sizeof_pool_memory(UA_sock->msg) - 1; if (usrbrk()) { break; } if (fgets(UA_sock->msg, len, input) == NULL) { status = -1; } else { sendit(UA_sock->msg); /* echo to terminal */ strip_trailing_junk(UA_sock->msg); UA_sock->msglen = strlen(UA_sock->msg); status = 1; } } if (status < 0) { break; /* error or interrupt */ } else if (status == 0) { /* timeout */ if (bstrcmp(prompt, "*")) { tid = start_bsock_timer(UA_sock, timeout); UA_sock->fsend(".messages"); stop_bsock_timer(tid); } else { continue; } } else { at_prompt = false; /* * @ => internal command for us */ if (UA_sock->msg[0] == '@') { parse_args(UA_sock->msg, &args, &argc, argk, argv, MAX_CMD_ARGS); if (!do_a_command(input, UA_sock)) { break; } continue; } tid = start_bsock_timer(UA_sock, timeout); if (!UA_sock->send()) { /* send command */ stop_bsock_timer(tid); break; /* error */ } stop_bsock_timer(tid); } if (bstrcmp(UA_sock->msg, ".quit") || bstrcmp(UA_sock->msg, ".exit")) { break; } tid = start_bsock_timer(UA_sock, timeout); while ((status = UA_sock->recv()) >= 0 || (status == BNET_SIGNAL && (UA_sock->msglen == BNET_START_RTREE || UA_sock->msglen == BNET_END_RTREE))) { if (status == BNET_SIGNAL) { if (UA_sock->msglen == BNET_START_RTREE) { file_selection = true; } else if (UA_sock->msglen == BNET_END_RTREE) { file_selection = false; } continue; } if (at_prompt) { if (!stop) { sendit("\n"); } at_prompt = false; } /* * Suppress output if running in background or user hit ctl-c */ if (!stop && !usrbrk()) { sendit(UA_sock->msg); } } stop_bsock_timer(tid); if (usrbrk() > 1) { break; } else { clrbrk(); } if (!stop) { fflush(stdout); } if (is_bnet_stop(UA_sock)) { break; /* error or term */ } else if (status == BNET_SIGNAL) { if (UA_sock->msglen == BNET_SUB_PROMPT) { at_prompt = true; } Dmsg1(100, "Got poll %s\n", bnet_sig_to_ascii(UA_sock)); } } } /* * Call-back for reading a passphrase for an encrypted PEM file * This function uses getpass(), * which uses a static buffer and is NOT thread-safe. */ static int tls_pem_callback(char *buf, int size, const void *userdata) { #ifdef HAVE_TLS const char *prompt = (const char *)userdata; #if defined(HAVE_WIN32) sendit(prompt); if (win32_cgets(buf, size) == NULL) { buf[0] = 0; return 0; } else { return strlen(buf); } #else char *passwd; passwd = getpass(prompt); bstrncpy(buf, passwd, size); return strlen(buf); #endif #else buf[0] = 0; return 0; #endif } #ifdef HAVE_READLINE #define READLINE_LIBRARY 1 #include "readline/readline.h" #include "readline/history.h" /* * Get the first keyword of the line */ static char *get_first_keyword() { char *ret = NULL; int len; char *first_space = strchr(rl_line_buffer, ' '); if (first_space) { len = first_space - rl_line_buffer; ret = (char *) malloc((len + 1) * sizeof(char)); memcpy(ret, rl_line_buffer, len); ret[len]=0; } return ret; } /* * Return the command before the current point. * Set nb to the number of command to skip */ static char *get_previous_keyword(int current_point, int nb) { int i, end=-1, start, inquotes=0; char *s = NULL; while (nb-- >= 0) { /* * First we look for a space before the current word */ for (i = current_point; i >= 0; i--) { if (rl_line_buffer[i] == ' ' || rl_line_buffer[i] == '=') { break; } } /* * Find the end of the command */ for (; i >= 0; i--) { if (rl_line_buffer[i] != ' ') { end = i; break; } } /* * No end of string */ if (end == -1) { return NULL; } /* * Look for the start of the command */ for (start = end; start > 0; start--) { if (rl_line_buffer[start] == '"') { inquotes = !inquotes; } if ((rl_line_buffer[start - 1] == ' ') && inquotes == 0) { break; } current_point = start; } } s = (char *)malloc(end - start + 2); memcpy(s, rl_line_buffer + start, end - start + 1); s[end - start + 1] = 0; // printf("=======> %i:%i <%s>\n", start, end, s); return s; } /* * Simple structure that will contain the completion list */ struct ItemList { alist list; }; static ItemList *items = NULL; void init_items() { if (!items) { items = (ItemList*) malloc(sizeof(ItemList)); memset(items, 0, sizeof(ItemList)); } else { items->list.destroy(); } items->list.init(); } /* Match a regexp and add the result to the items list * This function is recursive */ static void match_kw(regex_t *preg, const char *what, int len, POOLMEM **buf) { int rc, size; int nmatch = 20; regmatch_t pmatch[20]; if (len <= 0) { return; } rc = regexec(preg, what, nmatch, pmatch, 0); if (rc == 0) { #if 0 Pmsg1(0, "\n\n%s\n0123456789012345678901234567890123456789\n 10 20 30\n", what); Pmsg2(0, "%i-%i\n", pmatch[0].rm_so, pmatch[0].rm_eo); Pmsg2(0, "%i-%i\n", pmatch[1].rm_so, pmatch[1].rm_eo); Pmsg2(0, "%i-%i\n", pmatch[2].rm_so, pmatch[2].rm_eo); Pmsg2(0, "%i-%i\n", pmatch[3].rm_so, pmatch[3].rm_eo); #endif size = pmatch[1].rm_eo - pmatch[1].rm_so; *buf = check_pool_memory_size(*buf, size + 1); memcpy(*buf, what+pmatch[1].rm_so, size); (*buf)[size] = 0; items->list.append(bstrdup(*buf)); /* We search for the next keyword in the line */ match_kw(preg, what + pmatch[1].rm_eo, len - pmatch[1].rm_eo, buf); } } /* fill the items list with the output of the help command */ void get_arguments(const char *what) { regex_t preg; POOLMEM *buf; int rc; init_items(); rc = regcomp(&preg, "(([a-z_]+=)|([a-z]+)( |$))", REG_EXTENDED); if (rc != 0) { return; } buf = get_pool_memory(PM_MESSAGE); UA_sock->fsend(".help item=%s", what); while (UA_sock->recv() > 0) { strip_trailing_junk(UA_sock->msg); match_kw(&preg, UA_sock->msg, UA_sock->msglen, &buf); } free_pool_memory(buf); regfree(&preg); } /* retreive a simple list (.pool, .client) and store it into items */ void get_items(const char *what) { init_items(); UA_sock->fsend("%s", what); while (UA_sock->recv() > 0) { strip_trailing_junk(UA_sock->msg); items->list.append(bstrdup(UA_sock->msg)); } } typedef enum { ITEM_ARG, /* item with simple list like .jobs */ ITEM_HELP /* use help item=xxx and detect all arguments */ } cpl_item_t; /* Generator function for command completion. STATE lets us know whether * to start from scratch; without any state (i.e. STATE == 0), then we * start at the top of the list. */ static char *item_generator(const char *text, int state, const char *item, cpl_item_t type) { static int list_index, len; char *name; /* If this is a new word to complete, initialize now. This includes * saving the length of TEXT for efficiency, and initializing the index * variable to 0. */ if (!state) { list_index = 0; len = strlen(text); switch(type) { case ITEM_ARG: get_items(item); break; case ITEM_HELP: get_arguments(item); break; } } /* Return the next name which partially matches from the command list. */ while (items && list_index < items->list.size()) { name = (char *)items->list[list_index]; list_index++; if (bstrncmp(name, text, len)) { char *ret = (char *) actuallymalloc(strlen(name)+1); strcpy(ret, name); return ret; } } /* If no names matched, then return NULL. */ return ((char *)NULL); } /* gobal variables for the type and the item to search * the readline API doesn' permit to pass user data. */ static const char *cpl_item; static cpl_item_t cpl_type; static char *cpl_generator(const char *text, int state) { return item_generator(text, state, cpl_item, cpl_type); } /* this function is used to not use the default filename completion */ static char *dummy_completion_function(const char *text, int state) { return NULL; } struct cpl_keywords_t { const char *key; const char *cmd; bool file_selection; }; static struct cpl_keywords_t cpl_keywords[] = { { "pool=", ".pool", false }, { "nextpool=", ".pool", false }, { "fileset=", ".fileset", false }, { "client=", ".client", false }, { "jobdefs=", ".jobdefs", false }, { "job=", ".jobs", false }, { "restore_job=",".jobs type=R", false }, { "level=", ".level", false }, { "storage=", ".storage", false }, { "schedule=", ".schedule", false }, { "volume=", ".media", false }, { "oldvolume=", ".media", false }, { "volstatus=", ".volstatus", false }, { "catalog=", ".catalogs", false }, { "message=", ".msgs", false }, { "profile=", ".profiles", false }, { "actiononpurge=", ".actiononpurge", false }, { "ls", ".ls", true }, { "cd", ".lsdir", true }, { "add", ".ls", true }, { "mark", ".ls", true }, { "m", ".ls", true }, { "delete", ".lsmark", true }, { "unmark", ".lsmark", true } }; #define key_size ((int)(sizeof(cpl_keywords)/sizeof(struct cpl_keywords_t))) /* Attempt to complete on the contents of TEXT. START and END bound the * region of rl_line_buffer that contains the word to complete. TEXT is * the word to complete. We can use the entire contents of rl_line_buffer * in case we want to do some simple parsing. Return the array of matches, * or NULL if there aren't any. */ static char **readline_completion(const char *text, int start, int end) { bool found = false; char **matches; char *s, *cmd; matches = (char **)NULL; /* If this word is at the start of the line, then it is a command * to complete. Otherwise it is the name of a file in the current * directory. */ s = get_previous_keyword(start, 0); cmd = get_first_keyword(); if (s) { for (int i = 0; i < key_size; i++) { /* * See if this keyword is allowed with the current file_selection setting. */ if (cpl_keywords[i].file_selection != file_selection) { continue; } if (bstrcasecmp(s, cpl_keywords[i].key)) { cpl_item = cpl_keywords[i].cmd; cpl_type = ITEM_ARG; matches = rl_completion_matches(text, cpl_generator); found = true; break; } } if (!found) { /* we try to get help with the first command */ cpl_item = cmd; cpl_type = ITEM_HELP; /* we don't want to append " " at the end */ rl_completion_suppress_append = true; matches = rl_completion_matches(text, cpl_generator); } free(s); } else { /* nothing on the line, display all commands */ cpl_item = ".help all"; cpl_type = ITEM_ARG; matches = rl_completion_matches(text, cpl_generator); } if (cmd) { free(cmd); } return (matches); } static char eol = '\0'; static int eolcmd(FILE *input, BSOCK *UA_sock) { if ((argc > 1) && (strchr("!$%&'()*+,-/:;<>?[]^`{|}~", argk[1][0]) != NULL)) { eol = argk[1][0]; } else if (argc == 1) { eol = '\0'; } else { sendit(_("Illegal separator character.\n")); } return 1; } /* * Return 1 if OK * 0 if no input * -1 error (must stop) */ int get_cmd(FILE *input, const char *prompt, BSOCK *sock, int sec) { static char *line = NULL; static char *next = NULL; static int do_history = 0; char *command; if (line == NULL) { do_history = 0; rl_catch_signals = 0; /* do it ourselves */ /* Here, readline does ***real*** malloc * so, be we have to use the real free */ line = readline((char *)prompt); /* cast needed for old readlines */ if (!line) { return -1; /* error return and exit */ } strip_trailing_junk(line); command = line; } else if (next) { command = next + 1; } else { sendit(_("Command logic problem\n")); sock->msglen = 0; sock->msg[0] = 0; return 0; /* No input */ } /* * Split "line" into multiple commands separated by the eol character. * Each part is pointed to by "next" until finally it becomes null. */ if (eol == '\0') { next = NULL; } else { next = strchr(command, eol); if (next) { *next = '\0'; } } if (command != line && isatty(fileno(input))) { senditf("%s%s\n", prompt, command); } sock->msglen = pm_strcpy(&sock->msg, command); if (sock->msglen) { do_history++; } if (!next) { if (do_history) { add_history(line); } actuallyfree(line); /* allocated by readline() malloc */ line = NULL; } return 1; /* OK */ } #else /* no readline, do it ourselves */ #ifdef HAVE_CONIO static bool bisatty(int fd) { if (no_conio) { return false; } return isatty(fd); } #endif #ifdef HAVE_WIN32 /* use special console for input on win32 */ /* * Get next input command from terminal. * * Returns: 1 if got input * -1 if EOF or error */ int get_cmd(FILE *input, const char *prompt, BSOCK *sock, int sec) { int len; if (!stop) { if (output == stdout || teeout) { sendit(prompt); } } again: len = sizeof_pool_memory(sock->msg) - 1; if (stop) { sleep(1); goto again; } #ifdef HAVE_CONIO if (bisatty(fileno(input))) { input_line(sock->msg, len); goto ok_out; } #endif if (input == stdin) { if (win32_cgets(sock->msg, len) == NULL) { return -1; } } else { if (fgets(sock->msg, len, input) == NULL) { return -1; } } if (usrbrk()) { clrbrk(); } strip_trailing_junk(sock->msg); sock->msglen = strlen(sock->msg); return 1; } #else /* * Get next input command from terminal. * * Returns: 1 if got input * 0 if timeout * -1 if EOF or error */ int get_cmd(FILE *input, const char *prompt, BSOCK *sock, int sec) { int len; if (!stop) { if (output == stdout || teeout) { sendit(prompt); } } again: switch (wait_for_readable_fd(fileno(input), sec, true)) { case 0: return 0; /* timeout */ case -1: return -1; /* error */ default: len = sizeof_pool_memory(sock->msg) - 1; if (stop) { sleep(1); goto again; } #ifdef HAVE_CONIO if (bisatty(fileno(input))) { input_line(sock->msg, len); break; } #endif if (fgets(sock->msg, len, input) == NULL) { return -1; } break; } if (usrbrk()) { clrbrk(); } strip_trailing_junk(sock->msg); sock->msglen = strlen(sock->msg); return 1; } #endif /* HAVE_WIN32 */ #endif /* ! HAVE_READLINE */ static int console_update_history(const char *histfile) { int ret = 0; #ifdef HAVE_READLINE int max_history_length, truncate_entries; /* * Calculate how much we should keep in the current history file. */ max_history_length = (me) ? me->history_length : 100; truncate_entries = max_history_length - history_length; if (truncate_entries < 0) { truncate_entries = 0; } /* * First, try to truncate the history file, and if it * fails, the file is probably not present, and we * can use write_history to create it. */ if (history_truncate_file(histfile, truncate_entries) == 0) { ret = append_history(history_length, histfile); } else { ret = write_history(histfile); } #endif return ret; } static int console_init_history(const char *histfile) { int ret = 0; #ifdef HAVE_READLINE int max_history_length; using_history(); /* * First truncate the history size to an reasonable size. */ max_history_length = (me) ? me->history_length : 100; history_truncate_file(histfile, max_history_length); /* * Read the content of the history file into memory. */ ret = read_history(histfile); /* * Tell the completer that we want a complete. */ rl_completion_entry_function = dummy_completion_function; rl_attempted_completion_function = readline_completion; rl_filename_completion_desired = 0; stifle_history(max_history_length); #endif return ret; } static bool select_director(const char *director, DIRRES **ret_dir, CONRES **ret_cons) { int numcon=0, numdir=0; int i=0, item=0; BSOCK *UA_sock; DIRRES *dir = NULL; CONRES *cons = NULL; *ret_cons = NULL; *ret_dir = NULL; LockRes(); numdir = 0; foreach_res(dir, R_DIRECTOR) { numdir++; } numcon = 0; foreach_res(cons, R_CONSOLE) { numcon++; } UnlockRes(); if (numdir == 1) { /* No choose */ dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); } if (director) { /* Command line choice overwrite the no choose option */ LockRes(); foreach_res(dir, R_DIRECTOR) { if (bstrcmp(dir->hdr.name, director)) { break; } } UnlockRes(); if (!dir) { /* Can't find Director used as argument */ senditf(_("Can't find %s in Director list\n"), director); return 0; } } if (!dir) { /* prompt for director */ UA_sock = New(BSOCK_TCP); try_again: sendit(_("Available Directors:\n")); LockRes(); numdir = 0; foreach_res(dir, R_DIRECTOR) { senditf( _("%2d: %s at %s:%d\n"), 1+numdir++, dir->hdr.name, dir->address, dir->DIRport); } UnlockRes(); if (get_cmd(stdin, _("Select Director by entering a number: "), UA_sock, 600) < 0) { WSACleanup(); /* Cleanup Windows sockets */ return 0; } if (!is_a_number(UA_sock->msg)) { senditf(_("%s is not a number. You must enter a number between " "1 and %d\n"), UA_sock->msg, numdir); goto try_again; } item = atoi(UA_sock->msg); if (item < 0 || item > numdir) { senditf(_("You must enter a number between 1 and %d\n"), numdir); goto try_again; } delete UA_sock; LockRes(); for (i=0; idirector && bstrcmp(cons->director, dir->hdr.name)) { break; } cons = NULL; } /* * Look for the first non-linked console */ if (cons == NULL) { for (i=0; idirector == NULL) break; cons = NULL; } } /* * If no console, take first one */ if (!cons) { cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL); } UnlockRes(); *ret_dir = dir; *ret_cons = cons; return 1; } /* * Main Bareos Console -- User Interface Program */ int main(int argc, char *argv[]) { int ch; int errmsg_len; char *director = NULL; const char *name; char *password; char errmsg[1024]; bool list_directors = false; bool no_signals = false; bool test_config = false; JCR jcr; TLS_CONTEXT *tls_ctx = NULL; POOL_MEM history_file; utime_t heart_beat; errmsg_len = sizeof(errmsg); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); lmgr_init_thread(); my_name_is(argc, argv, "bconsole"); init_msg(NULL, NULL); working_directory = "/tmp"; args = get_pool_memory(PM_FNAME); while ((ch = getopt(argc, argv, "D:lc:d:nstu:?")) != -1) { switch (ch) { case 'D': /* Director */ if (director) { free(director); } director = bstrdup(optarg); break; case 'l': list_directors = true; test_config = true; break; case 'c': /* configuration file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'n': /* no conio */ no_conio = true; break; case 's': /* turn off signals */ no_signals = true; break; case 't': test_config = true; break; case 'u': timeout = atoi(optarg); break; case '?': default: usage(); exit(1); } } argc -= optind; argv += optind; if (!no_signals) { init_signals(terminate_console); } #if !defined(HAVE_WIN32) /* Override Bareos default signals */ signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, got_sigstop); signal(SIGCONT, got_sigcontinue); signal(SIGTTIN, got_sigtin); signal(SIGTTOU, got_sigtout); trapctlc(); #endif OSDependentInit(); if (argc) { usage(); exit(1); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_cons_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Emsg0(M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n")); } if (!check_resources()) { Emsg1(M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); } if (!no_conio) { con_init(stdin); } if (list_directors) { LockRes(); foreach_res(dir, R_DIRECTOR) { senditf("%s\n", dir->hdr.name); } UnlockRes(); } if (test_config) { terminate_console(0); exit(0); } memset(&jcr, 0, sizeof(jcr)); (void)WSA_Init(); /* Initialize Windows sockets */ start_watchdog(); /* Start socket watchdog */ if (!select_director(director, &dir, &cons)) { return 1; } senditf(_("Connecting to Director %s:%d\n"), dir->address,dir->DIRport); /* * Initialize Console TLS context */ if (cons && (cons->tls_enable || cons->tls_require)) { /* * Generate passphrase prompt */ bsnprintf(errmsg, errmsg_len, "Passphrase for Console \"%s\" TLS private key: ", cons->hdr.name); /* * Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ cons->tls_ctx = new_tls_context(cons->tls_ca_certfile, cons->tls_ca_certdir, cons->tls_crlfile, cons->tls_certfile, cons->tls_keyfile, tls_pem_callback, &errmsg, NULL, cons->tls_verify_peer); if (!cons->tls_ctx) { senditf(_("Failed to initialize TLS context for Console \"%s\".\n"), cons->hdr.name); terminate_console(0); return 1; } set_tls_enable(cons->tls_ctx, cons->tls_enable); set_tls_require(cons->tls_ctx, cons->tls_require); } /* * Initialize Director TLS context */ if (dir->tls_enable || dir->tls_require) { /* * Generate passphrase prompt */ bsnprintf(errmsg, errmsg_len, "Passphrase for Director \"%s\" TLS private key: ", dir->hdr.name); /* * Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ dir->tls_ctx = new_tls_context(dir->tls_ca_certfile, dir->tls_ca_certdir, dir->tls_crlfile, dir->tls_certfile, dir->tls_keyfile, tls_pem_callback, &errmsg, NULL, dir->tls_verify_peer); if (!dir->tls_ctx) { senditf(_("Failed to initialize TLS context for Director \"%s\".\n"), dir->hdr.name); terminate_console(0); return 1; } set_tls_enable(dir->tls_ctx, dir->tls_enable); set_tls_require(dir->tls_ctx, dir->tls_require); } if (dir->heartbeat_interval) { heart_beat = dir->heartbeat_interval; } else if (cons) { heart_beat = cons->heartbeat_interval; } else { heart_beat = 0; } UA_sock = New(BSOCK_TCP); if (!UA_sock->connect(NULL, 5, 15, heart_beat, "Director daemon", dir->address, NULL, dir->DIRport, false)) { delete UA_sock; terminate_console(0); return 1; } jcr.dir_bsock = UA_sock; /* * If cons == NULL, default console will be used */ if (cons) { name = cons->hdr.name; ASSERT(cons->password.encoding == p_encoding_md5); password = cons->password.value; tls_ctx = cons->tls_ctx; } else { name = "*UserAgent*"; ASSERT(dir->password.encoding == p_encoding_md5); password = dir->password.value; tls_ctx = dir->tls_ctx; } if (!UA_sock->authenticate_with_director(name, password, tls_ctx, errmsg, errmsg_len)) { sendit(errmsg); terminate_console(0); return 1; } sendit(errmsg); Dmsg0(40, "Opened connection with Director daemon\n"); sendit(_("Enter a period to cancel a command.\n")); #if defined(HAVE_WIN32) /* * Read/Update history file if USERPROFILE exists */ char *env = getenv("USERPROFILE"); #else /* * Read/Update history file if HOME exists */ char *env = getenv("HOME"); #endif /* * Run commands in ~/.bconsolerc if any */ if (env) { FILE *fp; pm_strcpy(&UA_sock->msg, env); pm_strcat(&UA_sock->msg, "/.bconsolerc"); fp = fopen(UA_sock->msg, "rb"); if (fp) { read_and_process_input(fp, UA_sock); fclose(fp); } } /* * See if there is an explicit setting of a history file to use. */ if (me && me->history_file) { pm_strcpy(history_file, me->history_file); console_init_history(history_file.c_str()); } else { if (env) { pm_strcpy(history_file, env); pm_strcat(history_file, "/.bconsole_history"); console_init_history(history_file.c_str()); } else { pm_strcpy(history_file, ""); } } read_and_process_input(stdin, UA_sock); if (UA_sock) { UA_sock->signal(BNET_TERMINATE); /* send EOF */ UA_sock->close(); } if (history_file.size()) { console_update_history(history_file.c_str()); } terminate_console(0); return 0; } /* Cleanup and then exit */ static void terminate_console(int sig) { static bool already_here = false; if (already_here) { /* avoid recursive temination problems */ exit(1); } already_here = true; stop_watchdog(); my_config->free_resources(); free(my_config); my_config = NULL; cleanup_crypto(); free_pool_memory(args); if (!no_conio) { con_term(); } WSACleanup(); /* Cleanup Windows sockets */ lmgr_cleanup_main(); if (sig != 0) { exit(1); } return; } /* * Make a quick check to see that we have all the resources needed. */ static int check_resources() { bool OK = true; DIRRES *director; bool tls_needed; LockRes(); numdir = 0; foreach_res(director, R_DIRECTOR) { numdir++; /* * tls_require implies tls_enable */ if (director->tls_require) { if (have_tls) { director->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); OK = false; continue; } } tls_needed = director->tls_enable || director->tls_authenticate; if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed) { Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s." " At least one CA certificate store is required.\n"), director->hdr.name, configfile); OK = false; } } if (numdir == 0) { Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n"), configfile); OK = false; } CONRES *cons; /* * Loop over Consoles */ foreach_res(cons, R_CONSOLE) { /* * tls_require implies tls_enable */ if (cons->tls_require) { if (have_tls) { cons->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); OK = false; continue; } } tls_needed = cons->tls_enable || cons->tls_authenticate; if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && tls_needed) { Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in %s.\n"), cons->hdr.name, configfile); OK = false; } } me = (CONRES *)GetNextRes(R_CONSOLE, NULL); UnlockRes(); return OK; } /* @version */ static int versioncmd(FILE *input, BSOCK *UA_sock) { senditf("Version: " VERSION " (" BDATE ") %s %s %s\n", HOST_OS, DISTNAME, DISTVER); return 1; } /* @input */ static int inputcmd(FILE *input, BSOCK *UA_sock) { FILE *fd; if (argc > 2) { sendit(_("Too many arguments on input command.\n")); return 1; } if (argc == 1) { sendit(_("First argument to input command must be a filename.\n")); return 1; } fd = fopen(argk[1], "rb"); if (!fd) { berrno be; senditf(_("Cannot open file %s for input. ERR=%s\n"), argk[1], be.bstrerror()); return 1; } read_and_process_input(fd, UA_sock); fclose(fd); return 1; } /* @tee */ /* Send output to both terminal and specified file */ static int teecmd(FILE *input, BSOCK *UA_sock) { teeout = true; return do_outputcmd(input, UA_sock); } /* @output */ /* Send output to specified "file" */ static int outputcmd(FILE *input, BSOCK *UA_sock) { teeout = false; return do_outputcmd(input, UA_sock); } static int do_outputcmd(FILE *input, BSOCK *UA_sock) { FILE *fd; const char *mode = "a+b"; if (argc > 3) { sendit(_("Too many arguments on output/tee command.\n")); return 1; } if (argc == 1) { if (output != stdout) { fclose(output); output = stdout; teeout = false; } return 1; } if (argc == 3) { mode = argk[2]; } fd = fopen(argk[1], mode); if (!fd) { berrno be; senditf(_("Cannot open file %s for output. ERR=%s\n"), argk[1], be.bstrerror(errno)); return 1; } output = fd; return 1; } /* * @exec "some-command" [wait-seconds] */ static int execcmd(FILE *input, BSOCK *UA_sock) { BPIPE *bpipe; char line[5000]; int status; int wait = 0; if (argc > 3) { sendit(_("Too many arguments. Enclose command in double quotes.\n")); return 1; } if (argc == 3) { wait = atoi(argk[2]); } bpipe = open_bpipe(argk[1], wait, "r"); if (!bpipe) { berrno be; senditf(_("Cannot popen(\"%s\", \"r\"): ERR=%s\n"), argk[1], be.bstrerror(errno)); return 1; } while (fgets(line, sizeof(line), bpipe->rfd)) { senditf("%s", line); } status = close_bpipe(bpipe); if (status != 0) { berrno be; be.set_errno(status); senditf(_("Autochanger error: ERR=%s\n"), be.bstrerror()); } return 1; } /* @echo xxx yyy */ static int echocmd(FILE *input, BSOCK *UA_sock) { for (int i=1; i < argc; i++) { senditf("%s ", argk[i]); } sendit("\n"); return 1; } /* @quit */ static int quitcmd(FILE *input, BSOCK *UA_sock) { return 0; } /* @help */ static int helpcmd(FILE *input, BSOCK *UA_sock) { int i; for (i=0; i 1) { sleep(atoi(argk[1])); } return 1; } /* @time */ static int timecmd(FILE *input, BSOCK *UA_sock) { char sdt[50]; bstrftimes(sdt, sizeof(sdt), time(NULL)); senditf("%s\n", sdt); return 1; } /* * Send a line to the output file and or the terminal */ void senditf(const char *fmt,...) { char buf[3000]; va_list arg_ptr; va_start(arg_ptr, fmt); bvsnprintf(buf, sizeof(buf), (char *)fmt, arg_ptr); va_end(arg_ptr); sendit(buf); } void sendit(const char *buf) { #ifdef CONIO_FIX char obuf[3000]; if (output == stdout || teeout) { const char *p, *q; /* * Here, we convert every \n into \r\n because the * terminal is in raw mode when we are using * conio. */ for (p=q=buf; (p=strchr(q, '\n')); ) { int len = p - q; if (len > 0) { memcpy(obuf, q, len); } memcpy(obuf+len, "\r\n", 3); q = ++p; /* point after \n */ fputs(obuf, output); } if (*q) { fputs(q, output); } fflush(output); } if (output != stdout) { fputs(buf, output); } #else fputs(buf, output); fflush(output); if (teeout) { fputs(buf, stdout); fflush(stdout); } #endif } bareos-Release-14.2.6/src/console/console_conf.c000066400000000000000000000265771263011562700215250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main configuration file parser for Bareos User Agent * some parts may be split into separate files such as * the schedule configuration (sch_config.c). * * Note, the configuration file parser consists of three parts * * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and * lib/parse_config.h. These files contain the parser code, * some utility routines, and the common store routines * (name, int, string). * * 3. The daemon specific file, which contains the Resource * definitions as well as any specific store routines * for the resource records. * * Kern Sibbald, January MM, September MM */ #include "bareos.h" #include "console_conf.h" /* * Define the first and last resource ID record * types. Note, these should be unique for each * daemon though not a requirement. */ static RES *sres_head[R_LAST - R_FIRST + 1]; static RES **res_head = sres_head; /* Forward referenced subroutines */ /* We build the current resource here as we are * scanning the resource configuration definition, * then move it to allocated memory when the resource * scan is complete. */ static URES res_all; static int32_t res_all_size = sizeof(res_all); /* Definition of records permitted within each * resource with the routine to process the record * information. */ /* Console "globals" */ static RES_ITEM cons_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_cons.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_cons.hdr.desc), 0, 0, NULL }, { "rcfile", CFG_TYPE_DIR, ITEM(res_cons.rc_file), 0, 0, NULL }, { "historyfile", CFG_TYPE_DIR, ITEM(res_cons.history_file), 0, 0, NULL }, { "historylength", CFG_TYPE_PINT32, ITEM(res_cons.history_length), 0, CFG_ITEM_DEFAULT, "100" }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(res_cons.password), 0, CFG_ITEM_REQUIRED, NULL }, { "tlsauthenticate",CFG_TYPE_BOOL, ITEM(res_cons.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(res_cons.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(res_cons.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(res_cons.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(res_cons.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(res_cons.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(res_cons.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(res_cons.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(res_cons.tls_keyfile), 0, 0, NULL }, { "director", CFG_TYPE_STR, ITEM(res_cons.director), 0, 0, NULL }, { "heartbeatinterval", CFG_TYPE_TIME, ITEM(res_cons.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* Director's that we can contact */ static RES_ITEM dir_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_dir.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_dir.hdr.desc), 0, 0, NULL }, { "dirport", CFG_TYPE_PINT32, ITEM(res_dir.DIRport), 0, CFG_ITEM_DEFAULT, DIR_DEFAULT_PORT }, { "address", CFG_TYPE_STR, ITEM(res_dir.address), 0, 0, NULL }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(res_dir.password), 0, CFG_ITEM_REQUIRED, NULL }, { "tlsauthenticate",CFG_TYPE_BOOL, ITEM(res_dir.tls_enable), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(res_dir.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(res_dir.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(res_dir.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(res_dir.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(res_dir.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(res_dir.tls_keyfile), 0, 0, NULL }, { "heartbeatinterval", CFG_TYPE_TIME, ITEM(res_dir.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * This is the master resource definition. * It must have one item for each of the resources. */ static RES_TABLE resources[] = { { "console", cons_items, R_CONSOLE, sizeof(CONRES) }, { "director", dir_items, R_DIRECTOR, sizeof(DIRRES) }, { NULL, NULL, 0 } }; /* * Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { URES *res = (URES *)reshdr; bool recurse = true; if (res == NULL) { printf(_("No record for %d %s\n"), type, res_to_str(type)); return; } if (type < 0) { /* no recursion */ type = - type; recurse = false; } switch (type) { case R_CONSOLE: printf(_("Console: name=%s rcfile=%s histfile=%s histsize=%d\n"), reshdr->name, res->res_cons.rc_file, res->res_cons.history_file, res->res_cons.history_length); break; case R_DIRECTOR: printf(_("Director: name=%s address=%s DIRport=%d\n"), reshdr->name, res->res_dir.address, res->res_dir.DIRport); break; default: printf(_("Unknown resource type %d\n"), type); } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } } /* * Free memory of resource. * NB, we don't need to worry about freeing any references * to other resources as they will be freed when that * resource chain is traversed. Mainly we worry about freeing * allocated strings (names). */ void free_resource(RES *sres, int type) { RES *nres; URES *res = (URES *)sres; if (res == NULL) return; /* common stuff -- free the resource name */ nres = (RES *)res->res_dir.hdr.next; if (res->res_dir.hdr.name) { free(res->res_dir.hdr.name); } if (res->res_dir.hdr.desc) { free(res->res_dir.hdr.desc); } switch (type) { case R_CONSOLE: if (res->res_cons.rc_file) { free(res->res_cons.rc_file); } if (res->res_cons.history_file) { free(res->res_cons.history_file); } if (res->res_cons.tls_ctx) { free_tls_context(res->res_cons.tls_ctx); } if (res->res_cons.tls_ca_certfile) { free(res->res_cons.tls_ca_certfile); } if (res->res_cons.tls_ca_certdir) { free(res->res_cons.tls_ca_certdir); } if (res->res_cons.tls_crlfile) { free(res->res_cons.tls_crlfile); } if (res->res_cons.tls_certfile) { free(res->res_cons.tls_certfile); } if (res->res_cons.tls_keyfile) { free(res->res_cons.tls_keyfile); } break; case R_DIRECTOR: if (res->res_dir.address) { free(res->res_dir.address); } if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } if (res->res_dir.tls_ca_certfile) { free(res->res_dir.tls_ca_certfile); } if (res->res_dir.tls_ca_certdir) { free(res->res_dir.tls_ca_certdir); } if (res->res_dir.tls_crlfile) { free(res->res_dir.tls_crlfile); } if (res->res_dir.tls_certfile) { free(res->res_dir.tls_certfile); } if (res->res_dir.tls_keyfile) { free(res->res_dir.tls_keyfile); } break; default: printf(_("Unknown resource type %d\n"), type); } /* Common stuff again -- free the resource, recurse to next one */ free(res); if (nres) { free_resource(nres, type); } } /* Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * pointers (currently only in the Job resource). */ void save_resource(int type, RES_ITEM *items, int pass) { URES *res; int rindex = type - R_FIRST; int i; int error = 0; /* * Ensure that all required items are present */ for (i = 0; items[i].name; i++) { if (items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"), items[i].name, resources[rindex]); } } } /* During pass 2, we looked up pointers to all the resources * referrenced in the current resource, , now we * must copy their address from the static record to the allocated * record. */ if (pass == 2) { switch (type) { /* Resources not containing a resource */ case R_CONSOLE: case R_DIRECTOR: break; default: Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type); error = 1; break; } /* Note, the resoure name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { free(res_all.res_dir.hdr.name); res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { free(res_all.res_dir.hdr.desc); res_all.res_dir.hdr.desc = NULL; } return; } /* Common */ if (!error) { res = (URES *)malloc(resources[rindex].size); memcpy(res, &res_all, resources[rindex].size); if (!res_head[rindex]) { res_head[rindex] = (RES *)res; /* store first entry */ } else { RES *next, *last; for (last=next=res_head[rindex]; next; next=next->next) { last = next; if (bstrcmp(next->name, res->res_dir.hdr.name)) { Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), resources[rindex].name, res->res_dir.hdr.name); } } last->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), res->res_dir.hdr.name); } } } bool parse_cons_config(CONFIG *config, const char *configfile, int exit_code) { config->init(configfile, NULL, NULL, NULL, NULL, NULL, exit_code, (void *)&res_all, res_all_size, R_FIRST, R_LAST, resources, res_head); return config->parse_config(); } bareos-Release-14.2.6/src/console/console_conf.h000066400000000000000000000072601263011562700215160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos User Agent specific configuration and defines * * Kern Sibbald, Sep MM */ /* * Resource codes -- they must be sequential for indexing */ enum { R_CONSOLE = 1001, R_DIRECTOR, R_FIRST = R_CONSOLE, R_LAST = R_DIRECTOR /* Keep this updated */ }; /* * Some resource attributes */ enum { R_NAME = 1020, R_ADDRESS, R_PASSWORD, R_TYPE, R_BACKUP }; /* Definition of the contents of each Resource */ /* Console "globals" */ struct CONRES { RES hdr; char *rc_file; /* startup file */ char *history_file; /* command history file */ s_password password; /* UA server password */ uint32_t history_length; /* readline history length */ bool tls_authenticate; /* Authenticate with TLS */ bool tls_enable; /* Enable TLS on all connections */ bool tls_require; /* Require TLS on all connections */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ char *director; /* bind to director */ utime_t heartbeat_interval; /* Interval to send heartbeats to Dir */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; /* Director */ struct DIRRES { RES hdr; uint32_t DIRport; /* UA server port */ char *address; /* UA server address */ s_password password; /* UA server password */ bool tls_authenticate; /* Authenticate with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ utime_t heartbeat_interval; /* Interval to send heartbeats to Dir */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; /* Define the Union of all the above * resource structure definitions. */ union URES { DIRRES res_dir; CONRES res_cons; RES hdr; }; extern CONRES *me; /* "Global" Client resource */ bareos-Release-14.2.6/src/console/func.h000077500000000000000000000117661263011562700200130ustar00rootroot00000000000000/* Definitions of internal function codes */ /* Functions that work on current line */ #define F_CSRRGT 301 /* cursor right */ #define F_CSRLFT 302 /* cursor left */ #define F_ERSCHR 303 /* erase character */ #define F_INSCHR 304 /* insert character */ #define F_DELCHR 305 /* delete next character character */ #define F_SOL 306 /* go to start of line */ #define F_EOL 307 /* go to end of line */ #define F_DELEOL 308 /* delete to end of line */ #define F_NXTWRD 309 /* go to next word */ #define F_PRVWRD 310 /* go to previous word */ #define F_DELWRD 311 /* delete word */ #define F_ERSLIN 312 /* erase line */ #define F_TAB 313 /* tab */ #define F_TABBAK 314 /* tab backwards */ #define F_DELSOL 315 /* delete from start of line to cursor */ #define F_LEFT40 316 /* move cursor left 40 cols */ #define F_RIGHT40 317 /* move cursor right 40 cols */ #define F_CASE 318 /* change case of next char advance csr */ #define F_CENTERL 319 /* center line */ /* Functions that move the cursor line or work on groups of lines */ #define F_CSRDWN 401 /* cursor down */ #define F_CSRUP 402 /* cursor up */ #define F_HOME 403 /* home cursor */ #define F_EOF 404 /* go to end of file */ #define F_PAGDWN 405 /* page down */ #define F_PAGUP 406 /* page up */ #define F_CENTER 407 /* center cursor on screen */ #define F_SPLIT 408 /* split line at cursor */ #define F_DELLIN 409 /* delete line */ #define F_CONCAT 410 /* concatenate next line to current */ #define F_RETURN 411 /* carriage return */ #define F_NXTMCH 412 /* next match */ #define F_DWN5 413 /* cursor down 5 lines */ #define F_UP5 414 /* cursor up 5 lines */ #define F_PUSH 415 /* push current location */ #define F_POP 416 /* pop previous location */ #define F_PAREN 417 /* find matching paren */ #define F_POPVIEW 418 /* pop to saved view */ #define F_OOPS 419 /* restore last oops buffer */ #define F_PARENB 420 /* find matching paren backwards */ #define F_BOTSCR 421 /* cursor to bottom of screen */ #define F_TOPSCR 422 /* cursor to top of screen */ #define F_TOPMARK 423 /* cursor to top marker line */ #define F_BOTMARK 424 /* cursor to bottom marker line */ #define F_CPYMARK 425 /* copy marked lines */ #define F_MOVMARK 426 /* move marked lines */ #define F_DELMARK 427 /* delete marked lines */ #define F_SHFTLEFT 428 /* shift marked text left one char */ #define F_SHFTRIGHT 429 /* shift marked text right one char */ /* Miscellaneous */ #define F_ESCAPE 501 /* escape character */ #define F_ESC 501 /* escape character */ #define F_EOI 502 /* end of input */ #define F_TENTRY 503 /* toggle entry mode */ #define F_TINS 504 /* toggle insert mode */ #define F_MARK 505 /* set marker on lines */ #define F_CRESC 506 /* carriage return, escape */ #define F_MACDEF 507 /* begin "macro" definition */ #define F_MACEND 508 /* end "macro" definition */ #define F_ZAPESC 509 /* clear screen, escape */ #define F_CLRMARK 510 /* clear marked text */ #define F_MARKBLK 511 /* mark blocks */ #define F_MARKCHR 512 /* mark characters */ #define F_HOLD 513 /* hold line */ #define F_DUP 514 /* duplicate line */ #define F_CHANGE 515 /* apply last change command */ #define F_RCHANGE 516 /* reverse last change command */ #define F_NXTFILE 517 /* next file */ #define F_INCLUDE 518 /* include */ #define F_FORMAT 519 /* format paragraph */ #define F_HELP 520 /* help */ #define F_JUSTIFY 521 /* justify paragraph */ #define F_SAVE 522 /* save file -- not implemented */ #define F_MOUSEI 523 /* mouse input coming -- not completed */ #define F_SCRSIZ 524 /* Screen size coming */ #define F_PASTECB 525 /* Paste clipboard */ #define F_CLRSCRN 526 /* Clear the screen */ #define F_CRNEXT 527 /* Send line, get next line */ #define F_BREAK 528 /* Break */ #define F_BACKGND 529 /* go into background */ bareos-Release-14.2.6/src/defaultconfigs/000077500000000000000000000000001263011562700202245ustar00rootroot00000000000000bareos-Release-14.2.6/src/defaultconfigs/bareos-sd.d/000077500000000000000000000000001263011562700223255ustar00rootroot00000000000000bareos-Release-14.2.6/src/defaultconfigs/bareos-sd.d/device-ceph-rados.conf000066400000000000000000000010611263011562700264540ustar00rootroot00000000000000# # Preparations: # # Copy ceph.conf and ceph.keyring from server /etc/ceph to clients /etc/ceph. # # Create a rados volume on the server: # /usr/bin/rados lspools # /usr/bin/rados mkpool bareos # /usr/bin/rados df # # include this configuration file in bareos-sd.conf by # @/etc/bareos/bareos-sd.d/device-ceph-rados.conf # Device { Name = RadosStorage Archive Device = /etc/ceph/ceph.conf:poolname Device Type = rados Media Type = RadosFile Label Media = yes Random Access = yes Automatic Mount = yes Removable Media = no Always Open = no } bareos-Release-14.2.6/src/defaultconfigs/bareos-sd.d/device-fifo.conf000066400000000000000000000011471263011562700253570ustar00rootroot00000000000000# # example of a Storage daemon dummy device to test the backup. # This example is write-only, so obviously, there is no way to restore data. # In other cases, Fifo backends are often combined this by RunBeforeJobs, # to start a corresponding reader/writer program. # # # Preparations: # # include this configuration file in bareos-sd.conf by # @/etc/bareos/bareos-sd.d/device-fifo.conf # Device { Name = NULL Archive Device = /dev/null Device Type = fifo Media Type = null Label Media = yes Random Access = no Automatic Mount = no Removable Media = no Always Open = no MaximumOpenWait = 60 } bareos-Release-14.2.6/src/defaultconfigs/bareos-sd.d/device-gluster.conf000066400000000000000000000005771263011562700261270ustar00rootroot00000000000000# # Preparations: # # include this configuration file in bareos-sd.conf by # @/etc/bareos/bareos-sd.d/device-gluster.conf # Device { Name = GlusterStorage Archive Device = gluster://server.example.com/volumename/bareos Device Type = gfapi Media Type = GlusterFile Label Media = yes Random Access = yes Automatic Mount = yes Removable Media = no Always Open = no } bareos-Release-14.2.6/src/defaultconfigs/bareos-sd.d/device-tape-with-autoloader.conf000066400000000000000000000030451263011562700304720ustar00rootroot00000000000000# # Preparations: # # include this configuration file in bareos-sd.conf by # @/etc/bareos/bareos-sd.d/device-tape-with-autoloader.conf # # on Linux use "lsscsi --generic" # to get a list of your SCSI devices. # However, normaly you should access your devices by-id # (eg. /dev/tape/by-id/scsi-350011d00018a5f03-nst), # because the short device names like /dev/nst1 # might change on reboot. Device { Name = "tapedrive-0" DeviceType = tape # default:0, only required if the autoloader have multiple drives. DriveIndex = 0 # if only one drive is available, this is normally /dev/nst0. # However, it is advised to access it via id (/dev/tape/by-id/...). ArchiveDevice = /dev/nst0 #ArchiveDevice = /dev/tape/by-id/scsi-350011d00018a5f03-nst # arbitrary string that descripes the the storage media. # Bareos uses this to determine, which device can be handle what media. MediaType = lto # enable "Check Labels" if tapes with ANSI/IBM labels # should be preserved #Check Labels = yes AutoChanger = yes # default: no AutomaticMount = yes # default: no MaximumFileSize = 10GB # default: 1000000000 (1GB) } Autochanger { Name = "autochanger-0" # adapt this, to match your storage loader Changer Device = /dev/tape/by-id/scsi-1TANDBERGStorageLoader_AA45JC001732 # an Autochanger can contain multiple drive devices Device = tapedrive-0 #Device = tapedrive-1 Changer Command = "/usr/lib/bareos/scripts/mtx-changer %c %o %S %a %d" } bareos-Release-14.2.6/src/defaultconfigs/diskonly/000077500000000000000000000000001263011562700220605ustar00rootroot00000000000000bareos-Release-14.2.6/src/defaultconfigs/diskonly/bareos-dir.conf.in000066400000000000000000000237621263011562700253750ustar00rootroot00000000000000# # Default Bareos Director configuration file for disk-only backup # (C) 2013-2014 Bareos GmbH & Co.KG # # Each configuration item has a reference number that shows # where this property can be changed in the configuration file. # Search for the number to find the correct line. # # You have to configure the following accoring to your environment: # # (#01)Email Address for bareos disaster recovery. # Specify a mailaddress outside of your backupserver. # There will be one mail per day. # # (#02)Email Address for bareos reports. (Mail Command) # This mail address will recieve a report about each backup job. # It will be sent after the backupjob is complete. # Has to be configured twice ("Standard" and "Daemon" Message Ressources) # # (#03)Email Address for bareos operator. (Operator Command) # This mail address will recieve a mail immediately when the # bareos system needs an operator intervention. # May be the same address as in (#02) # # # This disk-only setup stores all data into @archivedir@ # # The preconfigured backup scheme is as follows: # # Full Backups are done on first Saturday at 21:00 (#04) # Full Backups are written into the "Full" Pool (#05) # Full Backups are kept for 365 Days (#06) # # Differential Backups are done on 2nd to 5th Saturday at 21:00 (#07) # Differential Backups are written into the "Differential" Pool (#08) # Differential Backups are kept for 90 Days (#09) # # Incremental Backups are done monday to friday at 21:00 (#10) # Incremental Backups are written into the "Incremental" Pool (#11) # Incremental Backups are kept for 30 Days (#12) # # What you also have to do is to change the default fileset (#13) # to either one of the demo filesets given or create our own fileset. # # # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ @DISTVER@ # # Director { # define myself Name = @basename@-dir QueryFile = "@scriptdir@/query.sql" Maximum Concurrent Jobs = 10 Password = "@dir_password@" # Console password Messages = Daemon Auditing = yes # remove comment in next line to load dynamic backends from specified directory # Backend Directory = @backenddir@ # remove comment from "Plugin Directory" to load plugins from specified directory. # if "Plugin Names" is defined, only the specified plugins will be loaded, # otherwise all director plugins (*-dir.so) from the "Plugin Directory". # # Plugin Directory = @plugindir@ # Plugin Names = "" } JobDefs { Name = "DefaultJob" Type = Backup Level = Incremental Client = @basename@-fd FileSet = "SelfTest" # selftest fileset (#13) Schedule = "WeeklyCycle" Storage = File Messages = Standard Pool = Incremental Priority = 10 Write Bootstrap = "@working_dir@/%c.bsr" Full Backup Pool = Full # write Full Backups into "Full" Pool (#05) Differential Backup Pool = Differential # write Diff Backups into "Differential" Pool (#08) Incremental Backup Pool = Incremental # write Incr Backups into "Incremental" Pool (#11) } # # Define the main nightly save backup job # By default, this job will back up to disk in @archivedir@ Job { Name = "BackupClient1" JobDefs = "DefaultJob" } # # Backup the catalog database (after the nightly save) # Job { Name = "BackupCatalog" JobDefs = "DefaultJob" Level = Full FileSet="Catalog" Schedule = "WeeklyCycleAfterBackup" # This creates an ASCII copy of the catalog # Arguments to make_catalog_backup.pl are: # make_catalog_backup.pl RunBeforeJob = "@scriptdir@/make_catalog_backup.pl MyCatalog" # This deletes the copy of the catalog RunAfterJob = "@scriptdir@/delete_catalog_backup" # This sends the bootstrap via mail for disaster recovery. # Should be sent to another system, please change recipient accordingly Write Bootstrap = "|@bindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \" -s \"Bootstrap for Job %j\" @job_email@" # (#01) Priority = 11 # run after main backup } # # Standard Restore template, to be changed by Console program # Only one such job is needed for all Jobs/Clients/Storage ... # Job { Name = "RestoreFiles" Type = Restore Client=@basename@-fd FileSet = "Linux All" Storage = File Pool = Incremental Messages = Standard Where = /tmp/bareos-restores } FileSet { Name = "Windows All Drives" Enable VSS = yes Include { Options { Signature = MD5 Drive Type = fixed IgnoreCase = yes WildFile = "[A-Z]:/pagefile.sys" WildDir = "[A-Z]:/RECYCLER" WildDir = "[A-Z]:/$RECYCLE.BIN" WildDir = "[A-Z]:/System Volume Information" Exclude = yes } File = / } } FileSet { Name = "Linux All" Include { Options { Signature = MD5 # calculate md5 checksum per file One FS = No # change into other filessytems FS Type = ext2 # filesystems of given types will be backed up FS Type = ext3 # others will be ignored FS Type = ext4 FS Type = xfs FS Type = reiserfs FS Type = jfs FS Type = btrfs } File = / } # Things that usually have to be excluded # You have to exclude @archivedir@ # on your bareos server Exclude { File = @working_dir@ File = @archivedir@ File = /proc File = /tmp File = /.journal File = /.fsck } } # fileset just to backup some files for selftest FileSet { Name = "SelfTest" Include { Options { Signature = MD5 # calculate md5 checksum per file } File = "@sbindir@" } } Schedule { Name = "WeeklyCycle" Run = Full 1st sat at 21:00 # (#04) Run = Differential 2nd-5th sat at 21:00 # (#07) Run = Incremental mon-fri at 21:00 # (#10) } # This schedule does the catalog. It starts after the WeeklyCycle Schedule { Name = "WeeklyCycleAfterBackup" Run = Full mon-fri at 21:10 } # This is the backup of the catalog FileSet { Name = "Catalog" Include { Options { signature = MD5 } File = "@working_dir@/@db_name@.sql" # database dump File = "@sysconfdir@" # configuration } } # Client (File Services) to backup Client { Name = @basename@-fd Address = @hostname@ Password = "@fd_password@" # password for FileDaemon File Retention = 30 days # 30 days Job Retention = 6 months # six months AutoPrune = no # Prune expired Jobs/Files } # # Definition of file storage device # Storage { Name = File # Do not use "localhost" here Address = @hostname@ # N.B. Use a fully qualified name here Password = "@sd_password@" Device = FileStorage Media Type = File } # # Generic catalog service # Catalog { Name = MyCatalog # Uncomment the following lines if you want the dbi driver @uncomment_dbi@ dbdriver = "dbi:@DEFAULT_DB_TYPE@"; dbaddress = 127.0.0.1; dbport = @db_port@ #dbdriver = "@DEFAULT_DB_TYPE@" dbdriver = "XXX_REPLACE_WITH_DATABASE_DRIVER_XXX" dbname = "@db_name@" dbuser = "@db_user@" dbpassword = "@db_password@" } # # Reasonable message delivery -- send most everything to email address and to the console # Messages { Name = Standard mailcommand = "@bindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \<%r\>\" -s \"Bareos: %t %e of %c %l\" %r" operatorcommand = "@bindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \<%r\>\" -s \"Bareos: Intervention needed for %j\" %r" mail = @job_email@ = all, !skipped, !audit # (#02) operator = @job_email@ = mount # (#03) console = all, !skipped, !saved, !audit append = "@logdir@/bareos.log" = all, !skipped, !audit catalog = all, !audit } # # Message delivery for daemon messages (no job). # Messages { Name = Daemon mailcommand = "@bindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \<%r\>\" -s \"Bareos daemon message\" %r" mail = @job_email@ = all, !skipped, !audit # (#02) console = all, !skipped, !saved, !audit append = "@logdir@/bareos.log" = all, !skipped, !audit append = "@logdir@/bareos-audit.log" = audit } # # Full Pool definition # Pool { Name = Full Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 365 days # How long should the Full Backups be kept? (#06) Maximum Volume Bytes = 50G # Limit Volume size to something reasonable Maximum Volumes = 100 # Limit number of Volumes in Pool Label Format = "Full-" # Volumes will be labeled "Full-" } # # Differential Pool definition # Pool { Name = Differential Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 90 days # How long should the Differential Backups be kept? (#09) Maximum Volume Bytes = 10G # Limit Volume size to something reasonable Maximum Volumes = 100 # Limit number of Volumes in Pool Label Format = "Differential-" # Volumes will be labeled "Differential-" } # # Incremental Pool definition # Pool { Name = Incremental Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 30 days # How long should the Incremental Backups be kept? (#12) Maximum Volume Bytes = 1G # Limit Volume size to something reasonable Maximum Volumes = 100 # Limit number of Volumes in Pool Label Format = "Incremental-" # Volumes will be labeled "Incremental-" } # # Scratch pool definition # Pool { Name = Scratch Pool Type = Backup } # # Restricted console used by tray-monitor to get the status of the director # Console { Name = @basename@-mon Password = "@mon_dir_password@" CommandACL = status, .status JobACL = *all* } bareos-Release-14.2.6/src/defaultconfigs/diskonly/bareos-sd.conf.in000066400000000000000000000034101263011562700252110ustar00rootroot00000000000000# # Default Bareos Storage Daemon Configuration file # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ @DISTVER@ # # You may need to change the name of your tape drive # on the "Archive Device" directive in the Device # resource. If you change the Name and/or the # "Media Type" in the Device resource, please ensure # that dird.conf has corresponding changes. # Storage { # definition of myself Name = @basename@-sd Maximum Concurrent Jobs = 20 # remove comment from "Plugin Directory" to load plugins from specified directory. # if "Plugin Names" is defined, only the specified plugins will be loaded, # otherwise all storage plugins (*-sd.so) from the "Plugin Directory". # # Plugin Directory = @plugindir@ # Plugin Names = "" } # # List Directors who are permitted to contact Storage daemon # Director { Name = @basename@-dir Password = "@sd_password@" } # # Restricted Director, used by tray-monitor to get the # status of the storage daemon # Director { Name = @basename@-mon Password = "@mon_sd_password@" Monitor = yes } # # Devices supported by this Storage daemon # To connect, the Director's bareos-dir.conf must have the same Name and MediaType. # Device { Name = FileStorage Media Type = File Archive Device = @archivedir@ LabelMedia = yes; # lets Bareos label unlabeled media Random Access = yes; AutomaticMount = yes; # when device opened, read it RemovableMedia = no; AlwaysOpen = no; } # # include additional configuration files, if required # # eg. #@/etc/bareos/bareos-sd.d/device-gluster.conf # # Send all messages to the Director, # mount messages also are sent to the email address # Messages { Name = Standard director = @basename@-dir = all } bareos-Release-14.2.6/src/defaultconfigs/legacy/000077500000000000000000000000001263011562700214705ustar00rootroot00000000000000bareos-Release-14.2.6/src/defaultconfigs/legacy/README000066400000000000000000000001151263011562700223450ustar00rootroot00000000000000These are the default configuration files inherited from the bacula project. bareos-Release-14.2.6/src/defaultconfigs/legacy/bareos-dir.conf.in000066400000000000000000000214541263011562700250010ustar00rootroot00000000000000# # Default Bareos Director Configuration file # # The only thing that MUST be changed is to add one or more # file or directory names in the Include directive of the # FileSet resource. # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ @DISTVER@ # # You might also want to change the default email address # from root to your address. See the "mail" and "operator" # directives in the Messages resource. # Director { # define myself Name = @basename@-dir QueryFile = "@scriptdir@/query.sql" Maximum Concurrent Jobs = 1 Password = "@dir_password@" # Console password Messages = Daemon # remove comment in next line to load plugins from specified directory # Plugin Directory = @plugindir@ } JobDefs { Name = "DefaultJob" Type = Backup Level = Incremental Client = @basename@-fd FileSet = "Full Set" Schedule = "WeeklyCycle" Storage = File Messages = Standard Pool = File Priority = 10 Write Bootstrap = "@working_dir@/%c.bsr" } # # Define the main nightly save backup job # By default, this job will back up to disk in @archivedir@ Job { Name = "BackupClient1" JobDefs = "DefaultJob" } #Job { # Name = "BackupClient2" # Client = @basename@2-fd # JobDefs = "DefaultJob" #} # Backup the catalog database (after the nightly save) Job { Name = "BackupCatalog" JobDefs = "DefaultJob" Level = Full FileSet="Catalog" Schedule = "WeeklyCycleAfterBackup" # This creates an ASCII copy of the catalog # Arguments to make_catalog_backup.pl are: # make_catalog_backup.pl RunBeforeJob = "@scriptdir@/make_catalog_backup.pl MyCatalog" # This deletes the copy of the catalog RunAfterJob = "@scriptdir@/delete_catalog_backup" # This sends the bootstrap via mail for disaster recovery. # Should be sent to another system, please change recipient accordingly Write Bootstrap = "|@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \" -s \"Bootstrap for Job %j\" @job_email@" Priority = 11 # run after main backup } # # Standard Restore template, to be changed by Console program # Only one such job is needed for all Jobs/Clients/Storage ... # Job { Name = "RestoreFiles" Type = Restore Client=@basename@-fd FileSet="Full Set" Storage = File Pool = Default Messages = Standard Where = /tmp/bareos-restores } # List of files to be backed up FileSet { Name = "Full Set" Include { Options { signature = MD5 } # # Put your list of files here, preceded by 'File =', one per line # or include an external list with: # # File = \" -s \"Bareos: %t %e of %c %l\" %r" operatorcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \<%r\>\" -s \"Bareos: Intervention needed for %j\" %r" mail = @job_email@ = all, !skipped operator = @job_email@ = mount console = all, !skipped, !saved # # WARNING! the following will create a file that you must cycle from # time to time as it will grow indefinitely. However, it will # also keep all your messages if they scroll off the console. # append = "@logdir@/bareos.log" = all, !skipped catalog = all } # # Message delivery for daemon messages (no job). Messages { Name = Daemon mailcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bareos\) \<%r\>\" -s \"Bareos daemon message\" %r" mail = @job_email@ = all, !skipped console = all, !skipped, !saved append = "@logdir@/bareos.log" = all, !skipped } # Default pool definition Pool { Name = Default Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 365 days # one year } # File Pool definition Pool { Name = File Pool Type = Backup Recycle = yes # Bareos can automatically recycle Volumes AutoPrune = yes # Prune expired volumes Volume Retention = 365 days # one year Maximum Volume Bytes = 50G # Limit Volume size to something reasonable Maximum Volumes = 100 # Limit number of Volumes in Pool } # Scratch pool definition Pool { Name = Scratch Pool Type = Backup } # # Restricted console used by tray-monitor to get the status of the director # Console { Name = @basename@-mon Password = "@mon_dir_password@" CommandACL = status, .status JobACL = *all* } bareos-Release-14.2.6/src/defaultconfigs/legacy/bareos-sd.conf.in000066400000000000000000000133651263011562700246330ustar00rootroot00000000000000# # Default Bareos Storage Daemon Configuration file # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ @DISTVER@ # # You may need to change the name of your tape drive # on the "Archive Device" directive in the Device # resource. If you change the Name and/or the # "Media Type" in the Device resource, please ensure # that dird.conf has corresponding changes. # Storage { # definition of myself Name = @basename@-sd Maximum Concurrent Jobs = 20 # remove comment in next line to load plugins from specified directory # Plugin Directory = @plugindir@ } # # List Directors who are permitted to contact Storage daemon # Director { Name = @basename@-dir Password = "@sd_password@" } # # Restricted Director, used by tray-monitor to get the # status of the storage daemon # Director { Name = @basename@-mon Password = "@mon_sd_password@" Monitor = yes } # # # # Devices supported by this Storage daemon # To connect, the Director's bareos-dir.conf must have the # same Name and MediaType. # Device { Name = FileStorage Media Type = File Archive Device = @archivedir@ LabelMedia = yes; # lets Bareos label unlabeled media Random Access = Yes; AutomaticMount = yes; # when device opened, read it RemovableMedia = no; AlwaysOpen = no; } # # An autochanger device with two drives # #Autochanger { # Name = Autochanger # Device = Drive-1 # Device = Drive-2 # Changer Command = "@scriptdir@/mtx-changer %c %o %S %a %d" # Changer Device = /dev/sg0 #} # For the settings of Max/Min Block Size and File Size, see # http://www.bareos.org/en/Whitepapers/articles/Speed_Tuning_of_Tape_Drives.html #Device { # Name = Drive-1 # # Drive Index = 0 # Media Type = LTO # Minimum Block Size = 1048576 # Maximum Block Size = 1048576 # Maximum File Size = 50g # Archive Device = /dev/nst0 # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes; # RemovableMedia = yes; # RandomAccess = no; # AutoChanger = yes # # # # Enable the Alert command only if you have the mtx package loaded # # Note, apparently on some systems, tapeinfo resets the SCSI controller # # thus if you turn this on, make sure it does not reset your SCSI # # controller. I have never had any problems, and smartctl does # # not seem to cause such problems. # # # Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" # If you have smartctl, enable this, it has more info than tapeinfo # Alert Command = "sh -c 'smartctl -H -l error %c'" #} #Device { # Name = Drive-2 # # Drive Index = 1 # Media Type = LTO # Minimum Block Size = 1048576 # Maximum Block Size = 1048576 # Maximum File Size = 50g # Archive Device = /dev/nst1 # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes; # RemovableMedia = yes; # RandomAccess = no; # AutoChanger = yes # # Enable the Alert command only if you have the mtx package loaded # Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" # If you have smartctl, enable this, it has more info than tapeinfo # Alert Command = "sh -c 'smartctl -H -l error %c'" #} # # A Linux or Solaris LTO-2 tape drive # #Device { # Name = LTO-2 # Media Type = LTO-2 # Archive Device = @TAPEDRIVE@ # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes; # RemovableMedia = yes; # RandomAccess = no; # Maximum File Size = 3GB ## Changer Command = "@scriptdir@/mtx-changer %c %o %S %a %d" ## Changer Device = /dev/sg0 ## AutoChanger = yes # # Enable the Alert command only if you have the mtx package loaded ## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" ## If you have smartctl, enable this, it has more info than tapeinfo ## Alert Command = "sh -c 'smartctl -H -l error %c'" #} # # A Linux or Solaris LTO-3 tape drive # #Device { # Name = LTO-3 # Media Type = LTO-3 # Archive Device = @TAPEDRIVE@ # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes; # RemovableMedia = yes; # RandomAccess = no; # Maximum File Size = 4GB ## Changer Command = "@scriptdir@/mtx-changer %c %o %S %a %d" ## Changer Device = /dev/sg0 ## AutoChanger = yes # # Enable the Alert command only if you have the mtx package loaded ## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" ## If you have smartctl, enable this, it has more info than tapeinfo ## Alert Command = "sh -c 'smartctl -H -l error %c'" #} # # A Linux or Solaris LTO-4 tape drive # #Device { # Name = LTO-4 # Media Type = LTO-4 # Archive Device = @TAPEDRIVE@ # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes; # RemovableMedia = yes; # RandomAccess = no; # Maximum File Size = 5GB ## Changer Command = "@scriptdir@/mtx-changer %c %o %S %a %d" ## Changer Device = /dev/sg0 ## AutoChanger = yes # # Enable the Alert command only if you have the mtx package loaded ## Alert Command = "sh -c 'tapeinfo -f %c |grep TapeAlert|cat'" ## If you have smartctl, enable this, it has more info than tapeinfo ## Alert Command = "sh -c 'smartctl -H -l error %c'" #} # # A FreeBSD tape drive # #Device { # Name = DDS-4 # Description = "DDS-4 for FreeBSD" # Media Type = DDS-4 # Archive Device = /dev/nsa1 # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = yes # Offline On Unmount = no # Hardware End of Medium = no # BSF at EOM = yes # Backward Space Record = no # Fast Forward Space File = no # TWO EOF = yes # If you have smartctl, enable this, it has more info than tapeinfo # Alert Command = "sh -c 'smartctl -H -l error %c'" #} # # Send all messages to the Director, # mount messages also are sent to the email address # Messages { Name = Standard director = @basename@-dir = all } bareos-Release-14.2.6/src/dird/000077500000000000000000000000001263011562700161515ustar00rootroot00000000000000bareos-Release-14.2.6/src/dird/Makefile.in000066400000000000000000000151551263011562700202250ustar00rootroot00000000000000# # Bareos Director Makefile # @MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ dir_group=@dir_group@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/dird DEBUG=@DEBUG@ GETTEXT_LIBS = @LIBINTL@ CAP_LIBS = @CAP_LIBS@ NDMP_LIBS = @NDMP_LIBS@ DB_LIBS=@DB_LIBS@ OPENSSL_LIBS_NONSHARED = @OPENSSL_LIBS_NONSHARED@ GNUTLS_LIBS_NONSHARED = @GNUTLS_LIBS_NONSHARED@ first_rule: all dummy: SVRSRCS = admin.c authenticate.c autoprune.c backup.c bsr.c catreq.c \ dir_plugins.c dird_conf.c dird.c expand.c fd_cmds.c getmsg.c \ inc_conf.c job.c jobq.c migrate.c mountreq.c msgchan.c \ ndmp_dma_backup.c ndmp_dma_generic.c ndmp_dma_restore.c \ ndmp_dma_storage.c ndmp_fhdb_helpers.c ndmp_fhdb_mem.c \ ndmp_fhdb_lmdb.c newvol.c next_vol.c quota.c recycle.c restore.c \ run_conf.c sd_cmds.c scheduler.c stats.c ua_acl.c ua_audit.c \ ua_cmds.c ua_configure.c ua_dotcmds.c ua_input.c ua_impexp.c \ ua_label.c ua_output.c ua_prune.c ua_purge.c ua_query.c \ ua_restore.c ua_run.c ua_select.c ua_server.c ua_status.c \ ua_tree.c ua_update.c vbackup.c verify.c SVROBJS = $(SVRSRCS:.c=.o) DBCHKSRCS = dbcheck.c dird_conf.c ua_acl.c ua_audit.c run_conf.c inc_conf.c DBCHKOBJS = $(DBCHKSRCS:.c=.o) TSTFNDSRCS = testfind.c dird_conf.c ua_acl.c ua_audit.c run_conf.c inc_conf.c TSTFNDOBJS = $(TSTFNDSRCS:.c=.o) INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .o .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile bareos-dir bareos-dbcheck @STATIC_DIR@ @echo "==== Make of dird is good ====" @echo " " bareos-dir: Makefile $(SVROBJS) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ @NDMP_DEPS@ @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(WLDFLAGS) $(LDFLAGS) -L../lib -L../cats -L../findlib -o $@ $(SVROBJS) \ $(NDMP_LIBS) -lbareosfind -lbareossql -lbareoscats -lbareoscfg -lbareos -lm $(DLIB) \ $(DB_LIBS) $(LIBS) $(WRAPLIBS) $(GETTEXT_LIBS) $(CAP_LIBS) \ $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bareos-dbcheck: Makefile $(DBCHKOBJS) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -L../findlib -L../cats -o $@ $(DBCHKOBJS) \ -lbareoscats -lbareossql -lbareoscfg -lbareosfind -lbareos -lm $(DB_LIBS) $(LIBS) $(GETTEXT_LIBS) \ $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) testfind: Makefile $(TSTFNDOBJS) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -L../findlib -L../cats -o $@ $(TSTFNDOBJS) \ -lbareoscats -lbareossql -lbareoscfg -lbareosfind -lbareos -lm $(DB_LIBS) $(LIBS) $(GETTEXT_LIBS) \ $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) static-bareos-dir: Makefile $(SVROBJS) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ @NDMP_DEPS@ @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -L../cats -L../findlib -o $@ $(SVROBJS) \ $(NDMP_LIBS) -lbareosfind -lbareossql -lbareoscats -lbareoscfg -lbareos -lm $(DLIB) $(DB_LIBS) $(LIBS) \ $(WRAPLIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS) $(GNUTLS_LIBS) $(CAP_LIBS) strip $@ Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) dird bareos-dir static-bareos-dir bareos-dbcheck @$(RMF) core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 realclean: clean @$(RMF) tags bareos-dir.conf distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) install: all $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bareos-dir $(DESTDIR)$(sbindir)/bareos-dir $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bareos-dbcheck $(DESTDIR)$(sbindir)/bareos-dbcheck @srcconf=bareos-dir.conf; \ $(MKDIR) ${DESTDIR}${sysconfdir}/bareos-dir.d/; \ if test -f ${DESTDIR}${sysconfdir}/$$srcconf; then \ destconf=$$srcconf.new; \ echo " ==> Found existing $$srcconf, installing new conf file as $$destconf"; \ else \ destconf=$$srcconf; \ fi; \ echo "${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf"; \ ${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf -@if test "x${dir_group}" != "x"; then \ chgrp -f ${dir_group} ${DESTDIR}${sysconfdir}/$$destconf ; \ fi @if test -f ${DESTDIR}${scriptdir}/query.sql; then \ echo " ==> Saving existing query.sql to query.sql.old"; \ $(MV) -f ${DESTDIR}${scriptdir}/query.sql ${DESTDIR}${scriptdir}/query.sql.old; \ fi ${INSTALL_DATA} query.sql ${DESTDIR}${scriptdir}/query.sql @if test -f static-bareos-dir; then \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) static-bareos-dir $(DESTDIR)$(sbindir)/static-bareos-dir; \ fi # Semi-automatic generation of dependencies: # Use gcc -MM because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(INCLUDES) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/dird/admin.c000066400000000000000000000062161263011562700174120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- admin.c -- responsible for doing admin jobs * * Kern Sibbald, May MMIII * * Basic tasks done here: * Display the job report. */ #include "bareos.h" #include "dird.h" bool do_admin_init(JCR *jcr) { free_rstorage(jcr); if (!allow_duplicate_job(jcr)) { return false; } return true; } /* * Returns: false on failure * true on success */ bool do_admin(JCR *jcr) { jcr->jr.JobId = jcr->JobId; jcr->fname = (char *)get_pool_memory(PM_FNAME); /* Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Admin JobId %d, Job=%s\n"), jcr->JobId, jcr->Job); jcr->setJobStatus(JS_Running); admin_cleanup(jcr, JS_Terminated); return true; } /* * Release resources allocated during backup. */ void admin_cleanup(JCR *jcr, int TermCode) { char sdt[50], edt[50], schedt[50]; char term_code[100]; const char *term_msg; int msg_type; Dmsg0(100, "Enter backup_cleanup()\n"); update_job_end(jcr, TermCode); if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"), db_strerror(jcr->db)); jcr->setJobStatus(JS_ErrorTerminated); } msg_type = M_INFO; /* by default INFO message */ switch (jcr->JobStatus) { case JS_Terminated: term_msg = _("Admin OK"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Admin Error ***"); msg_type = M_ERROR; /* Generate error message */ break; case JS_Canceled: term_msg = _("Admin Canceled"); break; default: term_msg = term_code; sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus); break; } bstrftimes(schedt, sizeof(schedt), jcr->jr.SchedTime); bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime); bstrftimes(edt, sizeof(edt), jcr->jr.EndTime); Jmsg(jcr, msg_type, 0, _("BAREOS " VERSION " (" LSMDATE "): %s\n" " JobId: %d\n" " Job: %s\n" " Scheduled time: %s\n" " Start time: %s\n" " End time: %s\n" " Termination: %s\n\n"), edt, jcr->jr.JobId, jcr->jr.Job, schedt, sdt, edt, term_msg); Dmsg0(100, "Leave admin_cleanup()\n"); } bareos-Release-14.2.6/src/dird/authenticate.c000066400000000000000000000340161263011562700207770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- authenticate.c -- handles authorization of Storage and File daemons. * * Kern Sibbald, May MMI * * This routine runs as a thread and must be thread reentrant. */ #include "bareos.h" #include "dird.h" static const int dbglvl = 50; /* * Commands sent to Storage daemon and File daemon and received from the User Agent */ static char hello[] = "Hello Director %s calling\n"; /* * Response from Storage daemon */ static char OKhello[] = "3000 OK Hello\n"; static char FDOKhello[] = "2000 OK Hello\n"; static char FDOKnewHello[] = "2000 OK Hello %d\n"; /* * Sent to User Agent */ static char Dir_sorry[] = "1999 You are not authorized.\n"; /* * Authenticate Storage daemon connection */ bool authenticate_storage_daemon(JCR *jcr, STORERES *store) { BSOCK *sd = jcr->store_bsock; char dirname[MAX_NAME_LENGTH]; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; bool auth_success = false; btimer_t *tid = NULL; /* * Send my name to the Storage daemon then do authentication */ bstrncpy(dirname, me->hdr.name, sizeof(dirname)); bash_spaces(dirname); /* * Timeout Hello after 10 min */ tid = start_bsock_timer(sd, AUTH_TIMEOUT); if (!sd->fsend(hello, dirname)) { stop_bsock_timer(tid); Dmsg1(dbglvl, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd)); Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd)); return false; } /* * TLS Requirement */ if (store->tls_enable) { if (store->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } if (store->tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } ASSERT(store->password.encoding == p_encoding_md5); auth_success = cram_md5_respond(sd, store->password.value, &tls_remote_need, &compatible); if (auth_success) { auth_success = cram_md5_challenge(sd, store->password.value, tls_local_need, compatible); if (!auth_success) { Dmsg1(dbglvl, "cram_challenge failed for %s\n", sd->who()); } } else { Dmsg1(dbglvl, "cram_respond failed for %s\n", sd->who()); } if (!auth_success) { stop_bsock_timer(tid); Dmsg0(dbglvl, _("Director and Storage daemon passwords or names not the same.\n")); Jmsg(jcr, M_FATAL, 0, _("Director unable to authenticate with Storage daemon at \"%s:%d\". Possible causes:\n" "Passwords or names not the same or\n" "Maximum Concurrent Jobs exceeded on the SD or\n" "SD networking messed up (restart daemon).\n" "Please see %s for help.\n"), sd->host(), sd->port(), MANUAL_AUTH_URL); return false; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not advertise required TLS support.\n")); return false; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n")); return false; } /* * Is TLS Enabled? */ if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { if (!bnet_tls_client(store->tls_ctx, sd, NULL)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD at \"%s:%d\"\n"), sd->host(), sd->port()); return false; } if (store->tls_authenticate) { /* authentication only? */ sd->free_tls(); /* yes, stop tls */ } } Dmsg1(116, ">stored: %s", sd->msg); if (sd->recv() <= 0) { stop_bsock_timer(tid); Jmsg3(jcr, M_FATAL, 0, _("dirwho(), sd->host(), sd->bstrerror()); return false; } Dmsg1(110, "msg); stop_bsock_timer(tid); if (!bstrncmp(sd->msg, OKhello, sizeof(OKhello))) { Dmsg0(dbglvl, _("Storage daemon rejected Hello command\n")); Jmsg2(jcr, M_FATAL, 0, _("Storage daemon at \"%s:%d\" rejected Hello command\n"), sd->host(), sd->port()); return false; } return true; } /* * Authenticate File daemon connection */ bool authenticate_file_daemon(JCR *jcr) { BSOCK *fd = jcr->file_bsock; CLIENTRES *client = jcr->res.client; char dirname[MAX_NAME_LENGTH]; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; bool auth_success = false; btimer_t *tid = NULL; /* * Send my name to the File daemon then do authentication */ bstrncpy(dirname, me->name(), sizeof(dirname)); bash_spaces(dirname); /* * Timeout Hello after 10 min */ tid = start_bsock_timer(fd, AUTH_TIMEOUT); if (!fd->fsend(hello, dirname)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon at \"%s:%d\". ERR=%s\n"), fd->host(), fd->port(), fd->bstrerror()); return false; } Dmsg1(dbglvl, "Sent: %s", fd->msg); /* * TLS Requirement */ if (client->tls_enable) { if (client->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } if (client->tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } ASSERT(client->password.encoding == p_encoding_md5); auth_success = cram_md5_respond(fd, client->password.value, &tls_remote_need, &compatible); if (auth_success) { auth_success = cram_md5_challenge(fd, client->password.value, tls_local_need, compatible); if (!auth_success) { Dmsg1(dbglvl, "cram_auth failed for %s\n", fd->who()); } } else { Dmsg1(dbglvl, "cram_get_auth failed for %s\n", fd->who()); } if (!auth_success) { stop_bsock_timer(tid); Dmsg0(dbglvl, _("Director and File daemon passwords or names not the same.\n")); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate with File daemon at \"%s:%d\". Possible causes:\n" "Passwords or names not the same or\n" "Maximum Concurrent Jobs exceeded on the FD or\n" "FD networking messed up (restart daemon).\n" "Please see %s for help.\n"), fd->host(), fd->port(), MANUAL_AUTH_URL); return false; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD \"%s:%s\" did not advertise required TLS support.\n"), fd->who(), fd->host()); return false; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Authorization problem: FD at \"%s:%d\" requires TLS.\n"), fd->host(), fd->port()); return false; } /* * Is TLS Enabled? */ if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD at \"%s:%d\".\n"), fd->host(), fd->port()); return false; } if (client->tls_authenticate) { /* tls authentication only? */ fd->free_tls(); /* yes, shutdown tls */ } } Dmsg1(116, ">filed: %s", fd->msg); if (fd->recv() <= 0) { stop_bsock_timer(tid); Dmsg1(dbglvl, _("Bad response from File daemon to Hello command: ERR=%s\n"), bnet_strerror(fd)); Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon at \"%s:%d\" to Hello command: ERR=%s\n"), fd->host(), fd->port(), fd->bstrerror()); return false; } Dmsg1(110, "msg); stop_bsock_timer(tid); jcr->FDVersion = 0; if (!bstrncmp(fd->msg, FDOKhello, sizeof(FDOKhello)) && sscanf(fd->msg, FDOKnewHello, &jcr->FDVersion) != 1) { Dmsg0(dbglvl, _("File daemon rejected Hello command\n")); Jmsg(jcr, M_FATAL, 0, _("File daemon at \"%s:%d\" rejected Hello command\n"), fd->host(), fd->port()); return false; } return true; } /* * Authenticate user agent. */ bool authenticate_user_agent(UAContext *uac) { char name[MAX_NAME_LENGTH]; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool tls_authenticate; bool compatible = true; CONRES *cons = NULL; BSOCK *ua = uac->UA_sock; bool auth_success = false; TLS_CONTEXT *tls_ctx = NULL; alist *verify_list = NULL; if (ua->msglen < 16 || ua->msglen >= MAX_NAME_LENGTH + 15) { Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Len=%d\n"), ua->who(), ua->host(), ua->port(), ua->msglen); return false; } if (sscanf(ua->msg, "Hello %127s calling\n", name) != 1) { ua->msg[100] = 0; /* terminate string */ Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua->who(), ua->host(), ua->port(), ua->msg); return false; } name[sizeof(name)-1] = 0; /* terminate name */ if (bstrcmp(name, "*UserAgent*")) { /* default console */ /* * TLS Requirement */ if (me->tls_enable) { if (me->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } tls_authenticate = me->tls_authenticate; if (tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } if (me->tls_verify_peer) { verify_list = me->tls_allowed_cns; } ASSERT(me->password.encoding == p_encoding_md5); auth_success = cram_md5_challenge(ua, me->password.value, tls_local_need, compatible) && cram_md5_respond(ua, me->password.value, &tls_remote_need, &compatible); } else { unbash_spaces(name); cons = (CONRES *)GetResWithName(R_CONSOLE, name); if (cons) { /* * TLS Requirement */ if (cons->tls_enable) { if (cons->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } tls_authenticate = cons->tls_authenticate; if (tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } if (cons->tls_verify_peer) { verify_list = cons->tls_allowed_cns; } ASSERT(cons->password.encoding == p_encoding_md5); auth_success = cram_md5_challenge(ua, cons->password.value, tls_local_need, compatible) && cram_md5_respond(ua, cons->password.value, &tls_remote_need, &compatible); if (auth_success) { uac->cons = cons; /* save console resource pointer */ } } else { auth_success = false; goto auth_done; } } /* * Verify that the remote peer is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Emsg0(M_FATAL, 0, _("Authorization problem:" " Remote client did not advertise required TLS support.\n")); auth_success = false; goto auth_done; } /* * Verify that we are willing to meet the peer's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Emsg0(M_FATAL, 0, _("Authorization problem:" " Remote client requires TLS.\n")); auth_success = false; goto auth_done; } if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { if (cons) { tls_ctx = cons->tls_ctx; } else { tls_ctx = me->tls_ctx; } if (!bnet_tls_server(tls_ctx, ua, verify_list)) { Emsg0(M_ERROR, 0, _("TLS negotiation failed.\n")); auth_success = false; goto auth_done; } if (tls_authenticate) { /* authentication only? */ ua->free_tls(); /* stop tls */ } } /* * Authorization Completed */ auth_done: if (!auth_success) { ua->fsend("%s", _(Dir_sorry)); Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"), name, ua->who(), ua->host(), ua->port()); sleep(5); return false; } ua->fsend(_("1000 OK: %s Version: %s (%s)\n"), my_name, VERSION, BDATE); return true; } bareos-Release-14.2.6/src/dird/autoprune.c000066400000000000000000000161141263011562700203420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Automatic Pruning Applies retention periods * * Kern Sibbald, May MMII */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ /* * Auto Prune Jobs and Files. This is called at the end of every * Job. We do not prune volumes here. */ void do_autoprune(JCR *jcr) { UAContext *ua; JOBRES *job; CLIENTRES *client; POOLRES *pool; bool pruned; if (!jcr->res.client) { /* temp -- remove me */ return; } ua = new_ua_context(jcr); job = jcr->res.job; client = jcr->res.client; pool = jcr->res.pool; if (job->PruneJobs || client->AutoPrune) { prune_jobs(ua, client, pool, jcr->getJobType()); pruned = true; } else { pruned = false; } if (job->PruneFiles || client->AutoPrune) { prune_files(ua, client, pool); pruned = true; } if (pruned) { Jmsg(jcr, M_INFO, 0, _("End auto prune.\n\n")); } free_ua_context(ua); return; } /* * Prune at least one Volume in current Pool. This is called from catreq.c => next_vol.c * when the Storage daemon is asking for another volume and no appendable volumes are available. */ void prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store) { int i; int count; POOL_DBR spr; UAContext *ua; dbid_list ids; struct del_ctx prune_list; POOL_MEM query(PM_MESSAGE); char ed1[50], ed2[100], ed3[50]; Dmsg1(100, "Prune volumes PoolId=%d\n", jcr->jr.PoolId); if (!jcr->res.job->PruneVolumes && !jcr->res.pool->AutoPrune) { Dmsg0(100, "AutoPrune not set in Pool.\n"); return; } memset(&prune_list, 0, sizeof(prune_list)); prune_list.max_ids = 10000; prune_list.JobId = (JobId_t *)malloc(sizeof(JobId_t) * prune_list.max_ids); ua = new_ua_context(jcr); db_lock(jcr->db); /* * Edit PoolId */ edit_int64(mr->PoolId, ed1); /* * Get Pool record for Scratch Pool */ memset(&spr, 0, sizeof(spr)); bstrncpy(spr.Name, "Scratch", sizeof(spr.Name)); if (db_get_pool_record(jcr, jcr->db, &spr)) { edit_int64(spr.PoolId, ed2); bstrncat(ed2, ",", sizeof(ed2)); } else { ed2[0] = 0; } if (mr->ScratchPoolId) { edit_int64(mr->ScratchPoolId, ed3); bstrncat(ed2, ed3, sizeof(ed2)); bstrncat(ed2, ",", sizeof(ed2)); } Dmsg1(100, "Scratch pool(s)=%s\n", ed2); /* * ed2 ends up with scratch poolid and current poolid or * just current poolid if there is no scratch pool */ bstrncat(ed2, ed1, sizeof(ed2)); /* * Get the List of all media ids in the current Pool or whose * RecyclePoolId is the current pool or the scratch pool */ const char *select = "SELECT DISTINCT MediaId,LastWritten FROM Media WHERE " "(PoolId=%s OR RecyclePoolId IN (%s)) AND MediaType='%s' %s" "ORDER BY LastWritten ASC,MediaId"; if (InChanger) { char changer[100]; /* Ensure it is in this autochanger */ bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s ", edit_int64(mr->StorageId, ed3)); Mmsg(query, select, ed1, ed2, mr->MediaType, changer); } else { Mmsg(query, select, ed1, ed2, mr->MediaType, ""); } Dmsg1(100, "query=%s\n", query.c_str()); if (!db_get_query_dbids(ua->jcr, ua->db, query, ids)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); goto bail_out; } Dmsg1(100, "Volume prune num_ids=%d\n", ids.num_ids); /* Visit each Volume and Prune it until we find one that is purged */ for (i=0; idb, &lmr)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); continue; } Dmsg1(100, "Examine vol=%s\n", lmr.VolumeName); /* Don't prune archived volumes */ if (lmr.Enabled == VOL_ARCHIVED) { Dmsg1(100, "Vol=%s disabled\n", lmr.VolumeName); continue; } /* Prune only Volumes with status "Full", or "Used" */ if (bstrcmp(lmr.VolStatus, "Full") || bstrcmp(lmr.VolStatus, "Used")) { Dmsg2(100, "Add prune list MediaId=%d Volume %s\n", (int)lmr.MediaId, lmr.VolumeName); count = get_prune_list_for_volume(ua, &lmr, &prune_list); Dmsg1(100, "Num pruned = %d\n", count); if (count != 0) { purge_job_list_from_catalog(ua, prune_list); prune_list.num_ids = 0; /* reset count */ } if (!is_volume_purged(ua, &lmr)) { Dmsg1(050, "Vol=%s not pruned\n", lmr.VolumeName); continue; } Dmsg1(050, "Vol=%s is purged\n", lmr.VolumeName); /* * Since we are also pruning the Scratch pool, continue until and check if * this volume is available (InChanger + StorageId) If not, just skip this * volume and try the next one */ if (InChanger) { if (!lmr.InChanger || (lmr.StorageId != mr->StorageId)) { Dmsg1(100, "Vol=%s not inchanger or correct StoreId\n", lmr.VolumeName); continue; /* skip this volume, ie not loadable */ } } if (!lmr.Recycle) { Dmsg1(100, "Vol=%s not recyclable\n", lmr.VolumeName); continue; } if (has_volume_expired(jcr, &lmr)) { Dmsg1(100, "Vol=%s has expired\n", lmr.VolumeName); continue; /* Volume not usable */ } /* * If purged and not moved to another Pool, then we stop pruning and take this volume. */ if (lmr.PoolId == mr->PoolId) { Dmsg2(100, "Got Vol=%s MediaId=%d purged.\n", lmr.VolumeName, (int)lmr.MediaId); memcpy(mr, &lmr, sizeof(MEDIA_DBR)); set_storageid_in_mr(store, mr); break; /* got a volume */ } } } bail_out: Dmsg0(100, "Leave prune volumes\n"); db_unlock(jcr->db); free_ua_context(ua); if (prune_list.JobId) { free(prune_list.JobId); } return; } bareos-Release-14.2.6/src/dird/backup.c000066400000000000000000001053141263011562700175660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- backup.c -- responsible for doing backup jobs * * Kern Sibbald, March MM * * Basic tasks done here: * Open DB and create records for this job. * Open Message Channel with Storage daemon to tell him a job will be starting. * Open connection with File daemon and pass him commands to do the backup. * When the File daemon finishes the job, update the DB. */ #include "bareos.h" #include "dird.h" /* Commands sent to File daemon */ static char backupcmd[] = "backup FileIndex=%ld\n"; static char storaddrcmd[] = "storage address=%s port=%d ssl=%d\n"; static char passiveclientcmd[] = "passive client address=%s port=%d ssl=%d\n"; /* Responses received from File daemon */ static char OKbackup[] = "2000 OK backup\n"; static char OKstore[] = "2000 OK storage\n"; static char OKpassiveclient[] = "2000 OK passive client\n"; static char EndJob[] = "2800 End Job TermCode=%d JobFiles=%u " "ReadBytes=%llu JobBytes=%llu Errors=%u " "VSS=%d Encrypt=%d\n"; static inline bool validate_client(JCR *jcr) { switch (jcr->res.client->Protocol) { case APT_NATIVE: return true; default: Jmsg(jcr, M_FATAL, 0, _("Client %s has illegal backup protocol %s for Native backup\n"), jcr->res.client->name(), auth_protocol_to_str(jcr->res.client->Protocol)); return false; } } static inline bool validate_storage(JCR *jcr) { STORERES *store; foreach_alist(store, jcr->wstorage) { switch (store->Protocol) { case APT_NATIVE: continue; default: Jmsg(jcr, M_FATAL, 0, _("Storage %s has illegal backup protocol %s for Native backup\n"), store->name(), auth_protocol_to_str(store->Protocol)); return false; } } return true; } /* * Called here before the job is run to do the job specific setup. */ bool do_native_backup_init(JCR *jcr) { free_rstorage(jcr); /* we don't read so release */ if (!allow_duplicate_job(jcr)) { return false; } jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->res.pool->name()); if (jcr->jr.PoolId == 0) { return false; } /* * If pool storage specified, use it instead of job storage */ copy_wstorage(jcr, jcr->res.pool->storage, _("Pool resource")); if (!jcr->wstorage) { Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Job or Pool.\n")); return false; } /* * Validate that we have a native client and storage(s). */ if (!validate_client(jcr) || !validate_storage(jcr)) { return false; } create_clones(jcr); /* run any clone jobs */ return true; } /* * Take all base jobs from job resource and find the last L_BASE jobid. */ static bool get_base_jobids(JCR *jcr, db_list_ctx *jobids) { JOB_DBR jr; JOBRES *job; JobId_t id; char str_jobid[50]; if (!jcr->res.job->base) { return false; /* no base job, stop accurate */ } memset(&jr, 0, sizeof(jr)); jr.StartTime = jcr->jr.StartTime; foreach_alist(job, jcr->res.job->base) { bstrncpy(jr.Name, job->name(), sizeof(jr.Name)); db_get_base_jobid(jcr, jcr->db, &jr, &id); if (id) { if (jobids->count) { pm_strcat(jobids->list, ","); } pm_strcat(jobids->list, edit_uint64(id, str_jobid)); jobids->count++; } } return jobids->count > 0; } /* * Foreach files in currrent list, send "/path/fname\0LStat\0MD5\0Delta" to FD * row[0]=Path, row[1]=Filename, row[2]=FileIndex * row[3]=JobId row[4]=LStat row[5]=DeltaSeq row[6]=MD5 */ static int accurate_list_handler(void *ctx, int num_fields, char **row) { JCR *jcr = (JCR *)ctx; if (job_canceled(jcr)) { return 1; } if (row[2][0] == '0') { /* discard when file_index == 0 */ return 0; } /* sending with checksum */ if (jcr->use_accurate_chksum && num_fields == 7 && row[6][0] && /* skip checksum = '0' */ row[6][1]) { jcr->file_bsock->fsend("%s%s%c%s%c%s%c%s", row[0], row[1], 0, row[4], 0, row[6], 0, row[5]); } else { jcr->file_bsock->fsend("%s%s%c%s%c%c%s", row[0], row[1], 0, row[4], 0, 0, row[5]); } return 0; } /* In this procedure, we check if the current fileset is using checksum * FileSet-> Include-> Options-> Accurate/Verify/BaseJob=checksum * This procedure uses jcr->HasBase, so it must be call after the initialization */ static bool is_checksum_needed_by_fileset(JCR *jcr) { INCEXE *inc; FOPTS *fopts; FILESETRES *fs; bool in_block=false; bool have_basejob_option=false; if (!jcr->res.job || !jcr->res.job->fileset) { return false; } fs = jcr->res.job->fileset; for (int i = 0; i < fs->num_includes; i++) { /* Parse all Include {} */ inc = fs->include_items[i]; for (int j = 0; j < inc->num_opts; j++) { /* Parse all Options {} */ fopts = inc->opts_list[j]; for (char *k = fopts->opts; *k; k++) { /* Try to find one request */ switch (*k) { case 'V': /* verify */ in_block = jcr->is_JobType(JT_VERIFY); /* not used now */ break; case 'J': /* Basejob keyword */ have_basejob_option = in_block = jcr->HasBase; break; case 'C': /* Accurate keyword */ in_block = !jcr->is_JobLevel(L_FULL); break; case ':': /* End of keyword */ in_block = false; break; case '5': /* MD5 */ case '1': /* SHA1 */ if (in_block) { Dmsg0(50, "Checksum will be sent to FD\n"); return true; } break; default: break; } } } } /* By default for BaseJobs, we send the checksum */ if (!have_basejob_option && jcr->HasBase) { return true; } Dmsg0(50, "Checksum will be sent to FD\n"); return false; } /* * Send current file list to FD * DIR -> FD : accurate files=xxxx * DIR -> FD : /path/to/file\0Lstat\0MD5\0Delta * DIR -> FD : /path/to/dir/\0Lstat\0MD5\0Delta * ... * DIR -> FD : EOD */ bool send_accurate_current_files(JCR *jcr) { POOL_MEM buf; db_list_ctx jobids; db_list_ctx nb; /* * In base level, no previous job is used and no restart incomplete jobs */ if (jcr->is_canceled() || jcr->is_JobLevel(L_BASE)) { return true; } if (!jcr->accurate) { return true; } if (jcr->is_JobLevel(L_FULL)) { /* * On Full mode, if no previous base job, no accurate things */ if (get_base_jobids(jcr, &jobids)) { jcr->HasBase = true; Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids.list); } else { return true; } } else { /* * For Incr/Diff level, we search for older jobs */ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids); /* * We are in Incr/Diff, but no Full to build the accurate list... */ if (jobids.count == 0) { Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n")); return false; /* fail */ } } /* * Don't send and store the checksum if fileset doesn't require it */ jcr->use_accurate_chksum = is_checksum_needed_by_fileset(jcr); if (jcr->JobId) { /* display the message only for real jobs */ Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n")); } /* * To be able to allocate the right size for htable */ Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)", jobids.list); db_sql_query(jcr->db, buf.c_str(), db_list_handler, &nb); Dmsg2(200, "jobids=%s nb=%s\n", jobids.list, nb.list); jcr->file_bsock->fsend("accurate files=%s\n", nb.list); if (jcr->HasBase) { jcr->nb_base_files = str_to_int64(nb.list); db_create_base_file_list(jcr, jcr->db, jobids.list); db_get_base_file_list(jcr, jcr->db, jcr->use_accurate_chksum, accurate_list_handler, (void *)jcr); } else { if (!db_open_batch_connection(jcr, jcr->db)) { Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connection"); return false; /* Fail */ } db_get_file_list(jcr, jcr->db_batch, jobids.list, jcr->use_accurate_chksum, false /* no delta */, accurate_list_handler, (void *)jcr); } jcr->file_bsock->signal(BNET_EOD); return true; } /* * Do a backup of the specified FileSet * * Returns: false on failure * true on success */ bool do_native_backup(JCR *jcr) { int status; int tls_need = BNET_TLS_NONE; BSOCK *fd = NULL; BSOCK *sd = NULL; STORERES *store = NULL; CLIENTRES *client = NULL; char ed1[100]; db_int64_ctx job; POOL_MEM buf; /* Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Backup JobId %s, Job=%s\n"), edit_uint64(jcr->JobId, ed1), jcr->Job); jcr->setJobStatus(JS_Running); Dmsg2(100, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel); if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); return false; } if (check_hardquotas(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Quota Exceeded. Job terminated.\n")); return false; } if (check_softquotas(jcr)) { Dmsg0(10, "Quota exceeded\n"); Jmsg(jcr, M_FATAL, 0, _("Soft Quota Exceeded / Grace Time expired. Job terminated.\n")); return false; } /* * Open a message channel connection with the Storage * daemon. This is to let him know that our client * will be contacting him for a backup session. */ Dmsg0(110, "Open connection with storage daemon\n"); jcr->setJobStatus(JS_WaitSD); /* * Start conversation with Storage daemon */ if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { return false; } sd = jcr->store_bsock; /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, NULL, jcr->wstorage)) { return false; } /* * When the client is not in passive mode we can put the SD in * listen mode for the FD connection. */ jcr->passive_client = jcr->res.client->passive; if (!jcr->passive_client) { /* * Start the job prior to starting the message thread below * to avoid two threads from using the BSOCK structure at * the same time. */ if (!sd->fsend("run")) { return false; } /* * Now start a Storage daemon message thread. Note, * this thread is used to provide the catalog services * for the backup job, including inserting the attributes * into the catalog. See catalog_update() in catreq.c */ if (!start_storage_daemon_message_thread(jcr)) { return false; } Dmsg0(150, "Storage daemon connection OK\n"); } jcr->setJobStatus(JS_WaitFD); if (!connect_to_file_daemon(jcr, 10, me->FDConnectTimeout, true, true)) { goto bail_out; } fd = jcr->file_bsock; /* * Check if the file daemon supports passive client mode. */ if (jcr->passive_client && jcr->FDVersion < FD_VERSION_51) { Jmsg(jcr, M_FATAL, 0, _("Client \"%s\" doesn't support passive client mode. " "Please upgrade your client or disable compat mode.\n"), jcr->res.client->name()); goto close_fd; } jcr->setJobStatus(JS_Running); if (!send_level_command(jcr)) { goto bail_out; } if (!send_include_list(jcr)) { goto bail_out; } if (!send_exclude_list(jcr)) { goto bail_out; } if (!send_previous_restore_objects(jcr)) { goto bail_out; } if (jcr->res.job->max_bandwidth > 0) { jcr->max_bandwidth = jcr->res.job->max_bandwidth; } else if (jcr->res.client->max_bandwidth > 0) { jcr->max_bandwidth = jcr->res.client->max_bandwidth; } if (jcr->max_bandwidth > 0) { send_bwlimit_to_fd(jcr, jcr->Job); /* Old clients don't have this command */ } /* * See if the client is a passive client or not. */ if (!jcr->passive_client) { /* * Send Storage daemon address to the File daemon */ store = jcr->res.wstore; if (store->SDDport == 0) { store->SDDport = store->SDport; } /* * TLS Requirement */ if (store->tls_enable) { if (store->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } fd->fsend(storaddrcmd, store->address, store->SDDport, tls_need); if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) { goto bail_out; } } else { client = jcr->res.client; /* * TLS Requirement */ if (client->tls_enable) { if (client->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } /* * Tell the SD to connect to the FD. */ sd->fsend(passiveclientcmd, client->address, client->FDport, tls_need); if (!response(jcr, sd, OKpassiveclient, "Passive client", DISPLAY_ERROR)) { goto bail_out; } /* * Start the job prior to starting the message thread below * to avoid two threads from using the BSOCK structure at * the same time. */ if (!jcr->store_bsock->fsend("run")) { return false; } /* * Now start a Storage daemon message thread. Note, * this thread is used to provide the catalog services * for the backup job, including inserting the attributes * into the catalog. See catalog_update() in catreq.c */ if (!start_storage_daemon_message_thread(jcr)) { return false; } Dmsg0(150, "Storage daemon connection OK\n"); } /* * Declare the job started to start the MaxRunTime check */ jcr->setJobStarted(); /* * Send and run the RunBefore */ if (!send_runscripts_commands(jcr)) { goto bail_out; } /* * We re-update the job start record so that the start * time is set after the run before job. This avoids * that any files created by the run before job will * be saved twice. They will be backed up in the current * job, but not in the next one unless they are changed. * Without this, they will be backed up in this job and * in the next job run because in that case, their date * is after the start of this run. */ jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } /* * If backup is in accurate mode, we send the list of * all files to FD. */ if (!send_accurate_current_files(jcr)) { goto bail_out; /* error */ } /* * Send backup command */ fd->fsend(backupcmd, jcr->JobFiles); Dmsg1(100, ">filed: %s", fd->msg); if (!response(jcr, fd, OKbackup, "Backup", DISPLAY_ERROR)) { goto bail_out; } /* * Pickup Job termination data */ status = wait_for_job_termination(jcr); db_write_batch_file_records(jcr); /* used by bulk batch file insert */ if (jcr->HasBase && !db_commit_base_file_attributes_record(jcr, jcr->db)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } if (status == JS_Terminated) { native_backup_cleanup(jcr, status); return true; } return false; close_fd: if (jcr->file_bsock) { jcr->file_bsock->signal(BNET_TERMINATE); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } bail_out: jcr->setJobStatus(JS_ErrorTerminated); wait_for_job_termination(jcr, me->FDConnectTimeout); return false; } /* * Here we wait for the File daemon to signal termination, * then we wait for the Storage daemon. When both are done, * we return the job status. * * Also used by restore.c */ int wait_for_job_termination(JCR *jcr, int timeout) { int32_t n = 0; BSOCK *fd = jcr->file_bsock; bool fd_ok = false; uint32_t JobFiles, JobErrors; uint32_t JobWarnings = 0; uint64_t ReadBytes = 0; uint64_t JobBytes = 0; int VSS = 0; int Encrypt = 0; btimer_t *tid=NULL; jcr->setJobStatus(JS_Running); if (fd) { if (timeout) { tid = start_bsock_timer(fd, timeout); /* TODO: New timeout directive??? */ } /* * Wait for Client to terminate */ while ((n = bget_dirmsg(fd)) >= 0) { if (!fd_ok && sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles, &ReadBytes, &JobBytes, &JobErrors, &VSS, &Encrypt) == 7) { fd_ok = true; jcr->setJobStatus(jcr->FDJobStatus); Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus); } else { Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"), fd->msg); } if (job_canceled(jcr)) { break; } } if (tid) { stop_bsock_timer(tid); } if (is_bnet_error(fd)) { int i = 0; Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"), job_type_to_str(jcr->getJobType()), fd->bstrerror()); while (i++ < 10 && jcr->res.job->RescheduleIncompleteJobs && jcr->is_canceled()) { bmicrosleep(3, 0); } } fd->signal(BNET_TERMINATE); /* tell Client we are terminating */ } /* * Force cancel in SD if failing, but not for Incomplete jobs so that we let the SD despool. */ Dmsg5(100, "cancel=%d fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", jcr->is_canceled(), fd_ok, jcr->FDJobStatus, jcr->JobStatus, jcr->SDJobStatus); if (jcr->is_canceled() || (!jcr->res.job->RescheduleIncompleteJobs && !fd_ok)) { Dmsg4(100, "fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", fd_ok, jcr->FDJobStatus, jcr->JobStatus, jcr->SDJobStatus); cancel_storage_daemon_job(jcr); } /* * Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */ wait_for_storage_daemon_termination(jcr); /* * Return values from FD */ if (fd_ok) { jcr->JobFiles = JobFiles; jcr->JobErrors += JobErrors; /* Keep total errors */ jcr->ReadBytes = ReadBytes; jcr->JobBytes = JobBytes; jcr->JobWarnings = JobWarnings; jcr->VSS = VSS; jcr->Encrypt = Encrypt; } else { Jmsg(jcr, M_FATAL, 0, _("No Job status returned from FD.\n")); } // Dmsg4(100, "fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", fd_ok, jcr->FDJobStatus, // jcr->JobStatus, jcr->SDJobStatus); /* * Return the first error status we find Dir, FD, or SD */ if (!fd_ok || is_bnet_error(fd)) { /* if fd not set, that use !fd_ok */ jcr->FDJobStatus = JS_ErrorTerminated; } if (jcr->JobStatus != JS_Terminated) { return jcr->JobStatus; } if (jcr->FDJobStatus != JS_Terminated) { return jcr->FDJobStatus; } return jcr->SDJobStatus; } /* * Release resources allocated during backup. */ void native_backup_cleanup(JCR *jcr, int TermCode) { const char *term_msg; char term_code[100]; int msg_type = M_INFO; CLIENT_DBR cr; Dmsg2(100, "Enter backup_cleanup %d %c\n", TermCode, TermCode); memset(&cr, 0, sizeof(cr)); if (jcr->is_JobStatus(JS_Terminated) && (jcr->JobErrors || jcr->SDErrors || jcr->JobWarnings)) { TermCode = JS_Warnings; } update_job_end(jcr, TermCode); if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"), db_strerror(jcr->db)); jcr->setJobStatus(JS_ErrorTerminated); } bstrncpy(cr.Name, jcr->res.client->name(), sizeof(cr.Name)); if (!db_get_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Client record for Job report: ERR=%s"), db_strerror(jcr->db)); } update_bootstrap_file(jcr); switch (jcr->JobStatus) { case JS_Terminated: term_msg = _("Backup OK"); break; case JS_Incomplete: term_msg = _("Backup failed -- incomplete"); break; case JS_Warnings: term_msg = _("Backup OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Backup Error ***"); msg_type = M_ERROR; /* Generate error message */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; case JS_Canceled: term_msg = _("Backup Canceled"); if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; default: term_msg = term_code; sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus); break; } generate_backup_summary(jcr, &cr, msg_type, term_msg); Dmsg0(100, "Leave backup_cleanup()\n"); } void update_bootstrap_file(JCR *jcr) { /* * Now update the bootstrap file if any */ if (jcr->is_terminated_ok() && jcr->jr.JobBytes && jcr->res.job->WriteBootstrap) { FILE *fd; int VolCount; int got_pipe = 0; BPIPE *bpipe = NULL; VOL_PARAMS *VolParams = NULL; char edt[50], ed1[50], ed2[50]; POOLMEM *fname = get_pool_memory(PM_FNAME); fname = edit_job_codes(jcr, fname, jcr->res.job->WriteBootstrap, ""); if (*fname == '|') { got_pipe = 1; bpipe = open_bpipe(fname+1, 0, "w"); /* skip first char "|" */ fd = bpipe ? bpipe->wfd : NULL; } else { /* ***FIXME*** handle BASE */ fd = fopen(fname, jcr->is_JobLevel(L_FULL)?"w+b":"a+b"); } if (fd) { VolCount = db_get_job_volume_parameters(jcr, jcr->db, jcr->JobId, &VolParams); if (VolCount == 0) { Jmsg(jcr, M_ERROR, 0, _("Could not get Job Volume Parameters to " "update Bootstrap file. ERR=%s\n"), db_strerror(jcr->db)); if (jcr->SDJobFiles != 0) { jcr->setJobStatus(JS_ErrorTerminated); } } /* Start output with when and who wrote it */ bstrftimes(edt, sizeof(edt), time(NULL)); fprintf(fd, "# %s - %s - %s%s\n", edt, jcr->jr.Job, level_to_str(jcr->getJobLevel()), jcr->since); for (int i=0; i < VolCount; i++) { /* Write the record */ fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName); fprintf(fd, "MediaType=\"%s\"\n", VolParams[i].MediaType); if (VolParams[i].Slot > 0) { fprintf(fd, "Slot=%d\n", VolParams[i].Slot); } fprintf(fd, "VolSessionId=%u\n", jcr->VolSessionId); fprintf(fd, "VolSessionTime=%u\n", jcr->VolSessionTime); fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(VolParams[i].StartAddr, ed1), edit_uint64(VolParams[i].EndAddr, ed2)); fprintf(fd, "FileIndex=%d-%d\n", VolParams[i].FirstIndex, VolParams[i].LastIndex); } if (VolParams) { free(VolParams); } if (got_pipe) { close_bpipe(bpipe); } else { fclose(fd); } } else { berrno be; Jmsg(jcr, M_ERROR, 0, _("Could not open WriteBootstrap file:\n" "%s: ERR=%s\n"), fname, be.bstrerror()); jcr->setJobStatus(JS_ErrorTerminated); } free_pool_memory(fname); } } /* * Generic function which generates a backup summary message. * Used by: * - native_backup_cleanup e.g. normal backups * - native_vbackup_cleanup e.g. virtual backups * - ndmp_backup_cleanup e.g. NDMP backups */ void generate_backup_summary(JCR *jcr, CLIENT_DBR *cr, int msg_type, const char *term_msg) { char sdt[50], edt[50], schedt[50], gdt[50]; char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], compress[50]; char ec6[30], ec7[30], ec8[30], elapsed[50]; char fd_term_msg[100], sd_term_msg[100]; double kbps, compression; utime_t RunTime; MEDIA_DBR mr; POOL_MEM level_info, statistics, quota_info, client_options, daemon_status, compress_algo_list; memset(&mr, 0, sizeof(mr)); bstrftimes(schedt, sizeof(schedt), jcr->jr.SchedTime); bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime); bstrftimes(edt, sizeof(edt), jcr->jr.EndTime); RunTime = jcr->jr.EndTime - jcr->jr.StartTime; bstrftimes(gdt, sizeof(gdt), jcr->res.client->GraceTime + jcr->res.client->SoftQuotaGracePeriod); if (RunTime <= 0) { kbps = 0; } else { kbps = ((double)jcr->jr.JobBytes) / (1000.0 * (double)RunTime); } if (!db_get_job_volume_names(jcr, jcr->db, jcr->jr.JobId, &jcr->VolumeName)) { /* * Note, if the job has erred, most likely it did not write any * tape, so suppress this "error" message since in that case * it is normal. Or look at it the other way, only for a * normal exit should we complain about this error. */ if (jcr->is_terminated_ok() && jcr->jr.JobBytes) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); } jcr->VolumeName[0] = 0; /* none */ } if (jcr->VolumeName[0]) { /* * Find last volume name. Multiple vols are separated by | */ char *p = strrchr(jcr->VolumeName, '|'); if (p) { p++; /* skip | */ } else { p = jcr->VolumeName; /* no |, take full name */ } bstrncpy(mr.VolumeName, p, sizeof(mr.VolumeName)); if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"), mr.VolumeName, db_strerror(jcr->db)); } } if (jcr->ReadBytes == 0) { bstrncpy(compress, "None", sizeof(compress)); } else { compression = (double)100 - 100.0 * ((double)jcr->JobBytes / (double)jcr->ReadBytes); if (compression < 0.5) { bstrncpy(compress, "None", sizeof(compress)); } else { bsnprintf(compress, sizeof(compress), "%.1f %%", compression); find_used_compressalgos(&compress_algo_list, jcr); } } jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg)); jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg)); switch (jcr->getJobProtocol()) { case PT_NDMP: Mmsg(level_info, _( " Backup Level: %s%s\n"), level_to_str(jcr->getJobLevel()), jcr->since); Mmsg(statistics, _( " NDMP Files Written: %s\n" " SD Files Written: %s\n" " NDMP Bytes Written: %s (%sB)\n" " SD Bytes Written: %s (%sB)\n"), edit_uint64_with_commas(jcr->jr.JobFiles, ec1), edit_uint64_with_commas(jcr->SDJobFiles, ec2), edit_uint64_with_commas(jcr->jr.JobBytes, ec3), edit_uint64_with_suffix(jcr->jr.JobBytes, ec4), edit_uint64_with_commas(jcr->SDJobBytes, ec5), edit_uint64_with_suffix(jcr->SDJobBytes, ec6)); break; default: if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { Mmsg(level_info, _( " Backup Level: Virtual Full\n")); Mmsg(statistics, _( " SD Files Written: %s\n" " SD Bytes Written: %s (%sB)\n"), edit_uint64_with_commas(jcr->SDJobFiles, ec2), edit_uint64_with_commas(jcr->SDJobBytes, ec5), edit_uint64_with_suffix(jcr->SDJobBytes, ec6)); } else { Mmsg(level_info, _( " Backup Level: %s%s\n"), level_to_str(jcr->getJobLevel()), jcr->since); Mmsg(statistics, _( " FD Files Written: %s\n" " SD Files Written: %s\n" " FD Bytes Written: %s (%sB)\n" " SD Bytes Written: %s (%sB)\n"), edit_uint64_with_commas(jcr->jr.JobFiles, ec1), edit_uint64_with_commas(jcr->SDJobFiles, ec2), edit_uint64_with_commas(jcr->jr.JobBytes, ec3), edit_uint64_with_suffix(jcr->jr.JobBytes, ec4), edit_uint64_with_commas(jcr->SDJobBytes, ec5), edit_uint64_with_suffix(jcr->SDJobBytes, ec6)); } break; } if (jcr->HasQuota) { if (jcr->res.client->GraceTime != 0) { bstrftimes(gdt, sizeof(gdt), jcr->res.client->GraceTime + jcr->res.client->SoftQuotaGracePeriod); } else { bstrncpy(gdt, "Soft Quota was never exceeded", sizeof(gdt)); } Mmsg(quota_info, _( " Quota Used: %s (%sB)\n" " Burst Quota: %s (%sB)\n" " Soft Quota: %s (%sB)\n" " Hard Quota: %s (%sB)\n" " Grace Expiry Date: %s\n"), edit_uint64_with_commas(jcr->jr.JobSumTotalBytes+jcr->SDJobBytes, ec1), edit_uint64_with_suffix(jcr->jr.JobSumTotalBytes+jcr->SDJobBytes, ec2), edit_uint64_with_commas(jcr->res.client->QuotaLimit, ec3), edit_uint64_with_suffix(jcr->res.client->QuotaLimit, ec4), edit_uint64_with_commas(jcr->res.client->SoftQuota, ec5), edit_uint64_with_suffix(jcr->res.client->SoftQuota, ec6), edit_uint64_with_commas(jcr->res.client->HardQuota, ec7), edit_uint64_with_suffix(jcr->res.client->HardQuota, ec8), gdt); } switch (jcr->getJobProtocol()) { case PT_NDMP: break; default: if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { Mmsg(daemon_status, _( " SD Errors: %d\n" " SD termination status: %s\n"), jcr->SDErrors, sd_term_msg); } else { if (jcr->HasBase) { Mmsg(client_options, _( " Software Compression: %s%s\n" " Base files/Used files: %lld/%lld (%.2f%%)\n" " VSS: %s\n" " Encryption: %s\n" " Accurate: %s\n"), compress, compress_algo_list.c_str(), jcr->nb_base_files, jcr->nb_base_files_used, jcr->nb_base_files_used * 100.0 / jcr->nb_base_files, jcr->VSS ? _("yes") : _("no"), jcr->Encrypt ? _("yes") : _("no"), jcr->accurate ? _("yes") : _("no")); } else { Mmsg(client_options, _( " Software Compression: %s%s\n" " VSS: %s\n" " Encryption: %s\n" " Accurate: %s\n"), compress, compress_algo_list.c_str(), jcr->VSS ? _("yes") : _("no"), jcr->Encrypt ? _("yes") : _("no"), jcr->accurate ? _("yes") : _("no")); } Mmsg(daemon_status, _( " Non-fatal FD errors: %d\n" " SD Errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n"), jcr->JobErrors, jcr->SDErrors, fd_term_msg, sd_term_msg); } break; } // bmicrosleep(15, 0); /* for debugging SIGHUP */ Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" "%s" " Client: \"%s\" %s\n" " FileSet: \"%s\" %s\n" " Pool: \"%s\" (From %s)\n" " Catalog: \"%s\" (From %s)\n" " Storage: \"%s\" (From %s)\n" " Scheduled time: %s\n" " Start time: %s\n" " End time: %s\n" " Elapsed time: %s\n" " Priority: %d\n" "%s" /* FD/SD Statistics */ "%s" /* Quota info */ " Rate: %.1f KB/s\n" "%s" /* Client options */ " Volume name(s): %s\n" " Volume Session Id: %d\n" " Volume Session Time: %d\n" " Last Volume Bytes: %s (%sB)\n" "%s" /* Daemon status info */ " Termination: %s\n\n"), BAREOS, my_name, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER, jcr->jr.JobId, jcr->jr.Job, level_info.c_str(), jcr->res.client->name(), cr->Uname, jcr->res.fileset->name(), jcr->FSCreateTime, jcr->res.pool->name(), jcr->res.pool_source, jcr->res.catalog->name(), jcr->res.catalog_source, jcr->res.wstore->name(), jcr->res.wstore_source, schedt, sdt, edt, edit_utime(RunTime, elapsed, sizeof(elapsed)), jcr->JobPriority, statistics.c_str(), quota_info.c_str(), kbps, client_options.c_str(), jcr->VolumeName, jcr->VolSessionId, jcr->VolSessionTime, edit_uint64_with_commas(mr.VolBytes, ec7), edit_uint64_with_suffix(mr.VolBytes, ec8), daemon_status.c_str(), term_msg); } bareos-Release-14.2.6/src/dird/bareos-dir.conf.in000077700000000000000000000000001263011562700320162../defaultconfigs/diskonly/bareos-dir.conf.inustar00rootroot00000000000000bareos-Release-14.2.6/src/dird/bsr.c000066400000000000000000000542111263011562700171060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Bootstrap routines. * * BSR (bootstrap record) handling routines split from ua_restore.c July 2003 * Bootstrap send handling routines split from restore.c July 2012 * * Kern Sibbald, July 2002 */ #include "bareos.h" #include "dird.h" #define UA_CMD_SIZE 1000 /* Forward referenced functions */ /* * Create new FileIndex entry for BSR */ RBSR_FINDEX *new_findex() { RBSR_FINDEX *fi = (RBSR_FINDEX *)bmalloc(sizeof(RBSR_FINDEX)); memset(fi, 0, sizeof(RBSR_FINDEX)); return fi; } /* * Free all BSR FileIndex entries */ static inline void free_findex(RBSR_FINDEX *fi) { RBSR_FINDEX *next; for ( ; fi; fi=next) { next = fi->next; free(fi); } } /* * Get storage device name from Storage resource */ static bool get_storage_device(char *device, char *storage) { STORERES *store; if (storage[0] == 0) { return false; } store = (STORERES *)GetResWithName(R_STORAGE, storage); if (!store) { return false; } DEVICERES *dev = (DEVICERES *)(store->device->first()); if (!dev) { return false; } bstrncpy(device, dev->hdr.name, MAX_NAME_LENGTH); return true; } /* * Print a BSR entry into a memory buffer. */ static void print_bsr_item(POOL_MEM *pool_buf, const char *fmt, ...) { va_list arg_ptr; int len, maxlen; POOL_MEM item(PM_MESSAGE); while (1) { maxlen = item.max_size() - 1; va_start(arg_ptr, fmt); len = bvsnprintf(item.c_str(), maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen - 5)) { item.realloc_pm(maxlen + maxlen / 2); continue; } break; } pool_buf->strcat(item.c_str()); } /* * Our data structures were not designed completely * correctly, so the file indexes cover the full * range regardless of volume. The FirstIndex and LastIndex * passed in here are for the current volume, so when * writing out the fi, constrain them to those values. * * We are called here once for each JobMedia record * for each Volume. */ static inline uint32_t write_findex(RBSR_FINDEX *fi, int32_t FirstIndex, int32_t LastIndex, POOL_MEM *buffer) { int32_t findex, findex2; uint32_t count = 0; while (fi) { if ((fi->findex >= FirstIndex && fi->findex <= LastIndex) || (fi->findex2 >= FirstIndex && fi->findex2 <= LastIndex) || (fi->findex < FirstIndex && fi->findex2 > LastIndex)) { findex = fi->findex < FirstIndex ? FirstIndex : fi->findex; findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2; if (findex == findex2) { print_bsr_item(buffer, "FileIndex=%d\n", findex); count++; } else { print_bsr_item(buffer, "FileIndex=%d-%d\n", findex, findex2); count += findex2 - findex + 1; } } fi = fi->next; } return count; } /* * Find out if Volume defined with FirstIndex and LastIndex * falls within the range of selected files in the bsr. */ static inline bool is_volume_selected(RBSR_FINDEX *fi, int32_t FirstIndex, int32_t LastIndex) { while (fi) { if ((fi->findex >= FirstIndex && fi->findex <= LastIndex) || (fi->findex2 >= FirstIndex && fi->findex2 <= LastIndex) || (fi->findex < FirstIndex && fi->findex2 > LastIndex)) { return true; } fi = fi->next; } return false; } /* * Create a new bootstrap record */ RBSR *new_bsr() { RBSR *bsr = (RBSR *)bmalloc(sizeof(RBSR)); memset(bsr, 0, sizeof(RBSR)); return bsr; } /* * Free the entire BSR */ void free_bsr(RBSR *bsr) { RBSR *next; while (bsr) { free_findex(bsr->fi); if (bsr->VolParams) { free(bsr->VolParams); } if (bsr->fileregex) { free(bsr->fileregex); } next = bsr->next; free(bsr); bsr = next; } } /* * Complete the BSR by filling in the VolumeName and * VolSessionId and VolSessionTime using the JobId */ bool complete_bsr(UAContext *ua, RBSR *bsr) { for ( ; bsr; bsr=bsr->next) { JOB_DBR jr; memset(&jr, 0, sizeof(jr)); jr.JobId = bsr->JobId; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { ua->error_msg(_("Unable to get Job record. ERR=%s\n"), db_strerror(ua->db)); return false; } bsr->VolSessionId = jr.VolSessionId; bsr->VolSessionTime = jr.VolSessionTime; if (jr.JobFiles == 0) { /* zero files is OK, not an error, but */ bsr->VolCount = 0; /* there are no volumes */ continue; } if ((bsr->VolCount=db_get_job_volume_parameters(ua->jcr, ua->db, bsr->JobId, &(bsr->VolParams))) == 0) { ua->error_msg(_("Unable to get Job Volume Parameters. ERR=%s\n"), db_strerror(ua->db)); if (bsr->VolParams) { free(bsr->VolParams); bsr->VolParams = NULL; } return false; } } return true; } static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static uint32_t uniq = 0; static void make_unique_restore_filename(UAContext *ua, POOL_MEM &fname) { JCR *jcr = ua->jcr; int i = find_arg_with_value(ua, "bootstrap"); if (i >= 0) { Mmsg(fname, "%s", ua->argv[i]); jcr->unlink_bsr = false; } else { P(mutex); uniq++; V(mutex); Mmsg(fname, "%s/%s.restore.%u.bsr", working_directory, my_name, uniq); jcr->unlink_bsr = true; } if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); } jcr->RestoreBootstrap = bstrdup(fname.c_str()); } /* * Write the bootstrap records to file */ uint32_t write_bsr_file(UAContext *ua, RESTORE_CTX &rx) { FILE *fd; bool err; uint32_t count = 0; POOL_MEM fname(PM_MESSAGE); POOL_MEM buffer(PM_MESSAGE); make_unique_restore_filename(ua, fname); fd = fopen(fname.c_str(), "w+b"); if (!fd) { berrno be; ua->error_msg(_("Unable to create bootstrap file %s. ERR=%s\n"), fname.c_str(), be.bstrerror()); goto bail_out; } /* * Write them to a buffer. */ count = write_bsr(ua, rx, &buffer); /* * Write the buffer to file */ fprintf(fd, "%s", buffer.c_str()); err = ferror(fd); fclose(fd); if (count == 0) { ua->info_msg(_("No files found to read. No bootstrap file written.\n")); goto bail_out; } if (err) { ua->error_msg(_("Error writing bsr file.\n")); count = 0; goto bail_out; } ua->send_msg(_("Bootstrap records written to %s\n"), fname.c_str()); if (debug_level >= 10) { print_bsr(ua, rx); } bail_out: return count; } static void display_vol_info(UAContext *ua, RESTORE_CTX &rx, JobId_t JobId) { int i; RBSR *bsr; char online; POOL_MEM volmsg(PM_MESSAGE); char Device[MAX_NAME_LENGTH]; for (bsr = rx.bsr; bsr; bsr = bsr->next) { if (JobId && JobId != bsr->JobId) { continue; } for (i = 0; i < bsr->VolCount; i++) { if (bsr->VolParams[i].VolumeName[0]) { if (!get_storage_device(Device, bsr->VolParams[i].Storage)) { Device[0] = 0; } if (bsr->VolParams[i].InChanger && bsr->VolParams[i].Slot) { online = '*'; } else { online = ' '; } Mmsg(volmsg, "%c%-25s %-25s %-25s", online, bsr->VolParams[i].VolumeName, bsr->VolParams[i].Storage, Device); add_prompt(ua, volmsg.c_str()); } } } } void display_bsr_info(UAContext *ua, RESTORE_CTX &rx) { int i; char *p; JobId_t JobId; /* * Tell the user what he will need to mount */ ua->send_msg("\n"); ua->send_msg(_("The job will require the following\n" " Volume(s) Storage(s) SD Device(s)\n" "===========================================================================\n")); /* * Create Unique list of Volumes using prompt list */ start_prompt(ua, ""); if (*rx.JobIds == 0) { /* * Print Volumes in any order */ display_vol_info(ua, rx, 0); } else { /* * Ensure that the volumes are printed in JobId order */ for (p = rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { display_vol_info(ua, rx, JobId); } } for (i = 0; i < ua->num_prompts; i++) { ua->send_msg(" %s\n", ua->prompt[i]); free(ua->prompt[i]); } if (ua->num_prompts == 0) { ua->send_msg(_("No Volumes found to restore.\n")); } else { ua->send_msg(_("\nVolumes marked with \"*\" are online.\n")); } ua->num_prompts = 0; ua->send_msg("\n"); return; } /* * Write bsr data for a single bsr record */ static uint32_t write_bsr_item(RBSR *bsr, UAContext *ua, RESTORE_CTX &rx, POOL_MEM *buffer, bool &first, uint32_t &LastIndex) { int i; char ed1[50], ed2[50]; uint32_t count = 0; uint32_t total_count = 0; char device[MAX_NAME_LENGTH]; /* * For a given volume, loop over all the JobMedia records. * VolCount is the number of JobMedia records. */ for (i = 0; i < bsr->VolCount; i++) { if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex)) { bsr->VolParams[i].VolumeName[0] = 0; /* zap VolumeName */ continue; } if (!rx.store) { find_storage_resource(ua, rx, bsr->VolParams[i].Storage, bsr->VolParams[i].MediaType); } print_bsr_item(buffer, "Storage=\"%s\"\n", bsr->VolParams[i].Storage); print_bsr_item(buffer, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName); print_bsr_item(buffer, "MediaType=\"%s\"\n", bsr->VolParams[i].MediaType); if (bsr->fileregex) { print_bsr_item(buffer, "FileRegex=%s\n", bsr->fileregex); } if (get_storage_device(device, bsr->VolParams[i].Storage)) { print_bsr_item(buffer, "Device=\"%s\"\n", device); } if (bsr->VolParams[i].Slot > 0) { print_bsr_item(buffer, "Slot=%d\n", bsr->VolParams[i].Slot); } print_bsr_item(buffer, "VolSessionId=%u\n", bsr->VolSessionId); print_bsr_item(buffer, "VolSessionTime=%u\n", bsr->VolSessionTime); print_bsr_item(buffer, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1), edit_uint64(bsr->VolParams[i].EndAddr, ed2)); // Dmsg2(100, "bsr VolParam FI=%u LI=%u\n", // bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex); count = write_findex(bsr->fi, bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex, buffer); if (count) { print_bsr_item(buffer, "Count=%u\n", count); } total_count += count; /* * If the same file is present on two tapes or in two files * on a tape, it is a continuation, and should not be treated * twice in the totals. */ if (!first && LastIndex == bsr->VolParams[i].FirstIndex) { total_count--; } first = false; LastIndex = bsr->VolParams[i].LastIndex; } return total_count; } /* * Here we actually write out the details of the bsr file. * Note, there is one bsr for each JobId, but the bsr may * have multiple volumes, which have been entered in the * order they were written. * * The bsrs must be written out in the order the JobIds * are found in the jobid list. */ uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, POOL_MEM *buffer) { bool first = true; uint32_t LastIndex = 0; uint32_t total_count = 0; char *p; JobId_t JobId; RBSR *bsr; if (*rx.JobIds == 0) { for (bsr = rx.bsr; bsr; bsr = bsr->next) { total_count += write_bsr_item(bsr, ua, rx, buffer, first, LastIndex); } return total_count; } for (p = rx.JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { for (bsr = rx.bsr; bsr; bsr = bsr->next) { if (JobId == bsr->JobId) { total_count += write_bsr_item(bsr, ua, rx, buffer, first, LastIndex); } } } return total_count; } void print_bsr(UAContext *ua, RESTORE_CTX &rx) { POOL_MEM buffer(PM_MESSAGE); write_bsr(ua, rx, &buffer); fprintf(stdout, "%s", buffer.c_str()); } /* * Add a FileIndex to the list of BootStrap records. * Here we are only dealing with JobId's and the FileIndexes * associated with those JobIds. * * We expect that JobId, FileIndex are sorted ascending. */ void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex) { RBSR *nbsr; RBSR_FINDEX *fi, *lfi; if (findex == 0) { return; /* probably a dummy directory */ } if (bsr->fi == NULL) { /* if no FI add one */ /* * This is the first FileIndex item in the chain */ bsr->fi = new_findex(); bsr->JobId = JobId; bsr->fi->findex = findex; bsr->fi->findex2 = findex; return; } /* * Walk down list of bsrs until we find the JobId */ if (bsr->JobId != JobId) { for (nbsr = bsr->next; nbsr; nbsr = nbsr->next) { if (nbsr->JobId == JobId) { bsr = nbsr; break; } } if (!nbsr) { /* Must add new JobId */ /* * Add new JobId at end of chain */ for (nbsr = bsr; nbsr->next; nbsr = nbsr->next) { } nbsr->next = new_bsr(); nbsr->next->JobId = JobId; nbsr->next->fi = new_findex(); nbsr->next->fi->findex = findex; nbsr->next->fi->findex2 = findex; return; } } /* * At this point, bsr points to bsr containing this JobId, * and we are sure that there is at least one fi record. */ lfi = fi = bsr->fi; /* * Check if this findex is a duplicate. */ if (findex >= fi->findex && findex <= fi->findex2) { return; } /* * Check if this findex is smaller than first item */ if (findex < fi->findex) { if ((findex + 1) == fi->findex) { fi->findex = findex; /* extend down */ return; } fi = new_findex(); /* yes, insert before first item */ fi->findex = findex; fi->findex2 = findex; fi->next = lfi; bsr->fi = fi; return; } /* * Walk down fi chain and find where to insert insert new FileIndex */ while (fi) { /* * Check if this findex is a duplicate. */ if (findex >= fi->findex && findex <= fi->findex2) { return; } if (findex == (fi->findex2 + 1)) { /* extend up */ RBSR_FINDEX *nfi; fi->findex2 = findex; /* * If the following record contains one higher, merge its * file index by extending it up. */ if (fi->next && ((findex + 1) == fi->next->findex)) { nfi = fi->next; fi->findex2 = nfi->findex2; fi->next = nfi->next; free(nfi); } return; } if (findex < fi->findex) { /* add before */ if ((findex + 1) == fi->findex) { fi->findex = findex; return; } break; } lfi = fi; fi = fi->next; } /* * Add to last place found */ fi = new_findex(); fi->findex = findex; fi->findex2 = findex; fi->next = lfi->next; lfi->next = fi; return; } /* * Add all possible FileIndexes to the list of BootStrap records. * Here we are only dealing with JobId's and the FileIndexes * associated with those JobIds. */ void add_findex_all(RBSR *bsr, uint32_t JobId) { RBSR *nbsr; RBSR_FINDEX *fi; if (bsr->fi == NULL) { /* if no FI add one */ /* * This is the first FileIndex item in the chain */ bsr->fi = new_findex(); bsr->JobId = JobId; bsr->fi->findex = 1; bsr->fi->findex2 = INT32_MAX; return; } /* * Walk down list of bsrs until we find the JobId */ if (bsr->JobId != JobId) { for (nbsr = bsr->next; nbsr; nbsr = nbsr->next) { if (nbsr->JobId == JobId) { bsr = nbsr; break; } } if (!nbsr) { /* Must add new JobId */ /* * Add new JobId at end of chain */ for (nbsr = bsr; nbsr->next; nbsr = nbsr->next) { } nbsr->next = new_bsr(); nbsr->next->JobId = JobId; /* * If we use regexp to restore, set it for each jobid */ if (bsr->fileregex) { nbsr->next->fileregex = bstrdup(bsr->fileregex); } nbsr->next->fi = new_findex(); nbsr->next->fi->findex = 1; nbsr->next->fi->findex2 = INT32_MAX; return; } } /* * At this point, bsr points to bsr containing this JobId, * and we are sure that there is at least one fi record. */ fi = bsr->fi; fi->findex = 1; fi->findex2 = INT32_MAX; return; } /* * Open the bootstrap file and find the first Storage= * Returns ok if able to open * * It fills the storage name (should be the first line) * and the file descriptor to the bootstrap file, * it should be used for next operations, and need to be * closed at the end. */ bool open_bootstrap_file(JCR *jcr, bootstrap_info &info) { FILE *bs; UAContext *ua; info.bs = NULL; info.ua = NULL; if (!jcr->RestoreBootstrap) { return false; } bstrncpy(info.storage, jcr->res.rstore->name(), MAX_NAME_LENGTH); bs = fopen(jcr->RestoreBootstrap, "rb"); if (!bs) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), jcr->RestoreBootstrap, be.bstrerror()); jcr->setJobStatus(JS_ErrorTerminated); return false; } ua = new_ua_context(jcr); ua->cmd = check_pool_memory_size(ua->cmd, UA_CMD_SIZE + 1); while (!fgets(ua->cmd, UA_CMD_SIZE, bs)) { parse_ua_args(ua); if (ua->argc != 1) { continue; } if (bstrcasecmp(ua->argk[0], "Storage")) { bstrncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH); break; } } info.bs = bs; info.ua = ua; fseek(bs, 0, SEEK_SET); /* return to the top of the file */ return true; } /* * This function compare the given storage name with the * the current one. We compare the name and the address:port. * Returns true if we use the same storage. */ static inline bool is_on_same_storage(JCR *jcr, char *new_one) { STORERES *new_store; /* * With old FD, we send the whole bootstrap to the storage */ if (jcr->FDVersion < FD_VERSION_2) { return true; } /* * We are in init loop ? shoudn't fail here */ if (!*new_one) { return true; } /* * Same name */ if (bstrcmp(new_one, jcr->res.rstore->name())) { return true; } new_store = (STORERES *)GetResWithName(R_STORAGE, new_one); if (!new_store) { Jmsg(jcr, M_WARNING, 0, _("Could not get storage resource '%s'.\n"), new_one); return false; } /* * If Port and Hostname/IP are same, we are talking to the same * Storage Daemon */ if (jcr->res.rstore->SDport != new_store->SDport || !bstrcmp(jcr->res.rstore->address, new_store->address)) { return false; } return true; } /* * Check if the current line contains Storage="xxx", and compare the * result to the current storage. We use UAContext to analyse the bsr * string. * * Returns true if we need to change the storage, and it set the new * Storage resource name in "storage" arg. */ static inline bool check_for_new_storage(JCR *jcr, bootstrap_info &info) { UAContext *ua = info.ua; parse_ua_args(ua); if (ua->argc != 1) { return false; } if (bstrcasecmp(ua->argk[0], "Storage")) { /* * Continue if this is a volume from the same storage. */ if (is_on_same_storage(jcr, ua->argv[0])) { return false; } /* * Note the next storage name */ bstrncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH); Dmsg1(5, "Change storage to %s\n", info.storage); return true; } return false; } /* * Send bootstrap file to Storage daemon section by section. */ bool send_bootstrap_file(JCR *jcr, BSOCK *sock, bootstrap_info &info) { boffset_t pos; const char *bootstrap = "bootstrap\n"; UAContext *ua = info.ua; FILE *bs = info.bs; Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap); if (!jcr->RestoreBootstrap) { return false; } sock->fsend(bootstrap); pos = ftello(bs); while (fgets(ua->cmd, UA_CMD_SIZE, bs)) { if (check_for_new_storage(jcr, info)) { /* * Otherwise, we need to contact another storage daemon. * Reset bs to the beginning of the current segment. */ fseeko(bs, pos, SEEK_SET); break; } sock->fsend("%s", ua->cmd); pos = ftello(bs); } sock->signal(BNET_EOD); return true; } /* * Clean the bootstrap_info struct */ void close_bootstrap_file(bootstrap_info &info) { if (info.bs) { fclose(info.bs); } if (info.ua) { free_ua_context(info.ua); } } bareos-Release-14.2.6/src/dird/bsr.h000066400000000000000000000042041263011562700171100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bootstrap Record header file * * BSR (bootstrap record) handling routines split from ua_restore.c July 2003 * Bootstrap send handling routines split from restore.c July 2012 * * Kern Sibbald, July 2002 */ /* * FileIndex entry in restore bootstrap record */ struct RBSR_FINDEX { RBSR_FINDEX *next; int32_t findex; int32_t findex2; }; /* * Restore bootstrap record -- not the real one, but useful here * The restore bsr is a chain of BSR records (linked by next). * Each BSR represents a single JobId, and within it, it * contains a linked list of file indexes for that JobId. * The complete_bsr() routine, will then add all the volumes * on which the Job is stored to the BSR. */ struct RBSR { RBSR *next; /* next JobId */ JobId_t JobId; /* JobId this bsr */ uint32_t VolSessionId; uint32_t VolSessionTime; int VolCount; /* Volume parameter count */ VOL_PARAMS *VolParams; /* Volume, start/end file/blocks */ RBSR_FINDEX *fi; /* File indexes this JobId */ char *fileregex; /* Only restore files matching regex */ }; class UAContext; /* * Open bootstrap file. */ struct bootstrap_info { FILE *bs; UAContext *ua; char storage[MAX_NAME_LENGTH + 1]; }; bareos-Release-14.2.6/src/dird/catreq.c000066400000000000000000000612031263011562700175760ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- catreq.c -- handles the message channel * catalog request from the Storage daemon. * * Kern Sibbald, March MMI * * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: * Handle Catalog services. */ #include "bareos.h" #include "dird.h" #include "findlib/find.h" /* * Handle catalog request * For now, we simply return next Volume to be used */ /* * Requests from the Storage daemon */ static char Find_media[] = "CatReq Job=%127s FindMedia=%d pool_name=%127s media_type=%127s\n"; static char Get_Vol_Info[] = "CatReq Job=%127s GetVolInfo VolName=%127s write=%d\n"; static char Update_media[] = "CatReq Job=%127s UpdateMedia VolName=%s" " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%lld VolMounts=%u" " VolErrors=%u VolWrites=%u MaxVolBytes=%lld EndTime=%lld VolStatus=%10s" " Slot=%d relabel=%d InChanger=%d VolReadTime=%lld VolWriteTime=%lld" " VolFirstWritten=%lld\n"; static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia " " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u " " StartBlock=%u EndBlock=%u Copy=%d Strip=%d MediaId=%" lld "\n"; /* * Responses sent to Storage daemon */ static char OK_media[] = "1000 OK VolName=%s VolJobs=%u VolFiles=%u" " VolBlocks=%u VolBytes=%s VolMounts=%u VolErrors=%u VolWrites=%u" " MaxVolBytes=%s VolCapacityBytes=%s VolStatus=%s Slot=%d" " MaxVolJobs=%u MaxVolFiles=%u InChanger=%d VolReadTime=%s" " VolWriteTime=%s EndFile=%u EndBlock=%u LabelType=%d" " MediaId=%s EncryptionKey=%s MinBlocksize=%d MaxBlocksize=%d\n"; static char OK_create[] = "1000 OK CreateJobMedia\n"; static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr) { int status; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; jcr->MediaId = mr->MediaId; pm_strcpy(jcr->VolumeName, mr->VolumeName); bash_spaces(mr->VolumeName); status = sd->fsend(OK_media, mr->VolumeName, mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1), mr->VolMounts, mr->VolErrors, mr->VolWrites, edit_uint64(mr->MaxVolBytes, ed2), edit_uint64(mr->VolCapacityBytes, ed3), mr->VolStatus, mr->Slot, mr->MaxVolJobs, mr->MaxVolFiles, mr->InChanger, edit_int64(mr->VolReadTime, ed4), edit_int64(mr->VolWriteTime, ed5), mr->EndFile, mr->EndBlock, mr->LabelType, edit_uint64(mr->MediaId, ed6), mr->EncrKey, mr->MinBlocksize, mr->MaxBlocksize); unbash_spaces(mr->VolumeName); Dmsg2(100, "Vol Info for %s: %s", jcr->Job, sd->msg); return status; } void catalog_request(JCR *jcr, BSOCK *bs) { MEDIA_DBR mr, sdmr; JOBMEDIA_DBR jm; char Job[MAX_NAME_LENGTH]; char pool_name[MAX_NAME_LENGTH]; int index, ok, label, writing; POOLMEM *omsg; POOL_DBR pr; uint32_t Stripe, Copy; uint64_t MediaId; utime_t VolFirstWritten; utime_t VolLastWritten; memset(&sdmr, 0, sizeof(sdmr)); memset(&jm, 0, sizeof(jm)); memset(&mr, 0, sizeof(mr)); Dsm_check(100); /* * Request to find next appendable Volume for this Job */ Dmsg1(100, "catreq %s", bs->msg); if (!jcr->db) { omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); bs->fsend(_("1990 Invalid Catalog Request: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog request; DB not open: %s"), omsg); free_memory(omsg); return; } /* * Find next appendable medium for SD */ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) { memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool_name, sizeof(pr.Name)); unbash_spaces(pr.Name); ok = db_get_pool_record(jcr, jcr->db, &pr); if (ok) { mr.PoolId = pr.PoolId; set_storageid_in_mr(jcr->res.wstore, &mr); mr.ScratchPoolId = pr.ScratchPoolId; ok = find_next_volume_for_append(jcr, &mr, index, fnv_create_vol, fnv_prune); Dmsg3(050, "find_media ok=%d idx=%d vol=%s\n", ok, index, mr.VolumeName); } /* * Send Find Media response to Storage daemon */ if (ok) { send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { bs->fsend(_("1901 No Media.\n")); Dmsg0(500, "1901 No Media.\n"); } /* * Request to find specific Volume information */ } else if (sscanf(bs->msg, Get_Vol_Info, &Job, &mr.VolumeName, &writing) == 3) { Dmsg1(100, "CatReq GetVolInfo Vol=%s\n", mr.VolumeName); /* * Find the Volume */ unbash_spaces(mr.VolumeName); if (db_get_media_record(jcr, jcr->db, &mr)) { const char *reason = NULL; /* detailed reason for rejection */ /* * If we are reading, accept any volume (reason == NULL) * If we are writing, check if the Volume is valid * for this job, and do a recycle if necessary */ if (writing) { /* * SD wants to write this Volume, so make * sure it is suitable for this job, i.e. * Pool matches, and it is either Append or Recycle * and Media Type matches and Pool allows any volume. */ if (mr.PoolId != jcr->jr.PoolId) { reason = _("not in Pool"); } else if (!bstrcmp(mr.MediaType, jcr->res.wstore->media_type)) { reason = _("not correct MediaType"); } else { /* * Now try recycling if necessary * reason set non-NULL if we cannot use it */ check_if_volume_valid_or_recyclable(jcr, &mr, &reason); } } if (!reason && mr.Enabled != VOL_ENABLED) { reason = _("is not Enabled"); } if (reason == NULL) { /* * Send Find Media response to Storage daemon */ send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { /* Not suitable volume */ bs->fsend(_("1998 Volume \"%s\" catalog status is %s, %s.\n"), mr.VolumeName, mr.VolStatus, reason); } } else { bs->fsend(_("1997 Volume \"%s\" not in catalog.\n"), mr.VolumeName); Dmsg1(100, "1997 Volume \"%s\" not in catalog.\n", mr.VolumeName); } /* * Request to update Media record. Comes typically at the end * of a Storage daemon Job Session, when labeling/relabeling a * Volume, or when an EOF mark is written. */ } else if (sscanf(bs->msg, Update_media, &Job, &sdmr.VolumeName, &sdmr.VolJobs, &sdmr.VolFiles, &sdmr.VolBlocks, &sdmr.VolBytes, &sdmr.VolMounts, &sdmr.VolErrors, &sdmr.VolWrites, &sdmr.MaxVolBytes, &VolLastWritten, &sdmr.VolStatus, &sdmr.Slot, &label, &sdmr.InChanger, &sdmr.VolReadTime, &sdmr.VolWriteTime, &VolFirstWritten) == 18) { db_lock(jcr->db); Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, mr.VolStatus, sdmr.VolStatus); bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */ unbash_spaces(mr.VolumeName); if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"), mr.VolumeName, db_strerror(jcr->db)); bs->fsend(_("1991 Catalog Request for vol=%s failed: %s"), mr.VolumeName, db_strerror(jcr->db)); goto bail_out; } /* Set first written time if this is first job */ if (mr.FirstWritten == 0) { if (VolFirstWritten == 0) { mr.FirstWritten = jcr->start_time; /* use Job start time as first write */ } else { mr.FirstWritten = VolFirstWritten; } mr.set_first_written = true; } /* If we just labeled the tape set time */ if (label || mr.LabelDate == 0) { mr.LabelDate = jcr->start_time; mr.set_label_date = true; if (mr.InitialWrite == 0) { mr.InitialWrite = jcr->start_time; } Dmsg2(400, "label=%d labeldate=%d\n", label, mr.LabelDate); } else { /* * Insanity check for VolFiles get set to a smaller value */ if (sdmr.VolFiles < mr.VolFiles) { Jmsg(jcr, M_FATAL, 0, _("Volume Files at %u being set to %u" " for Volume \"%s\". This is incorrect.\n"), mr.VolFiles, sdmr.VolFiles, mr.VolumeName); bs->fsend(_("1992 Update Media error. VolFiles=%u, CatFiles=%u\n"), sdmr.VolFiles, mr.VolFiles); goto bail_out; } } Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs); /* * Check if the volume has been written by the job, * and update the LastWritten field if needed. */ if (mr.VolBlocks != sdmr.VolBlocks && VolLastWritten != 0) { mr.LastWritten = VolLastWritten; } /* * Update to point to the last device used to write the Volume. * However, do so only if we are writing the tape, i.e. * the number of VolWrites has increased. */ if (jcr->res.wstore && sdmr.VolWrites > mr.VolWrites) { Dmsg2(050, "Update StorageId old=%d new=%d\n", mr.StorageId, jcr->res.wstore->StorageId); /* Update StorageId after write */ set_storageid_in_mr(jcr->res.wstore, &mr); } else { /* Nothing written, reset same StorageId */ set_storageid_in_mr(NULL, &mr); } /* Copy updated values to original media record */ mr.VolJobs = sdmr.VolJobs; mr.VolFiles = sdmr.VolFiles; mr.VolBlocks = sdmr.VolBlocks; mr.VolBytes = sdmr.VolBytes; mr.VolMounts = sdmr.VolMounts; mr.VolErrors = sdmr.VolErrors; mr.VolWrites = sdmr.VolWrites; mr.Slot = sdmr.Slot; mr.InChanger = sdmr.InChanger; bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus)); mr.VolReadTime = sdmr.VolReadTime; mr.VolWriteTime = sdmr.VolWriteTime; Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName); /* * Update the database, then before sending the response to the * SD, check if the Volume has expired. */ if (!db_update_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_FATAL, 0, _("Catalog error updating Media record. %s"), db_strerror(jcr->db)); bs->fsend(_("1993 Update Media error\n")); Dmsg0(400, "send error\n"); } else { (void)has_volume_expired(jcr, &mr); send_volume_info_to_storage_daemon(jcr, bs, &mr); } bail_out: db_unlock(jcr->db); Dmsg1(400, ">CatReq response: %s", bs->msg); Dmsg1(400, "Leave catreq jcr 0x%x\n", jcr); return; /* * Request to create a JobMedia record */ } else if (sscanf(bs->msg, Create_job_media, &Job, &jm.FirstIndex, &jm.LastIndex, &jm.StartFile, &jm.EndFile, &jm.StartBlock, &jm.EndBlock, &Copy, &Stripe, &MediaId) == 10) { if (jcr->mig_jcr) { jm.JobId = jcr->mig_jcr->JobId; } else { jm.JobId = jcr->JobId; } jm.MediaId = MediaId; Dmsg6(400, "create_jobmedia JobId=%d MediaId=%d SF=%d EF=%d FI=%d LI=%d\n", jm.JobId, jm.MediaId, jm.StartFile, jm.EndFile, jm.FirstIndex, jm.LastIndex); if (!db_create_jobmedia_record(jcr, jcr->db, &jm)) { Jmsg(jcr, M_FATAL, 0, _("Catalog error creating JobMedia record. %s"), db_strerror(jcr->db)); bs->fsend(_("1992 Create JobMedia error\n")); } else { Dmsg0(400, "JobMedia record created\n"); bs->fsend(OK_create); } } else { omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); bs->fsend(_("1990 Invalid Catalog Request: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog request: %s"), omsg); free_memory(omsg); } Dmsg1(400, ">CatReq response: %s", bs->msg); Dmsg1(400, "Leave catreq jcr 0x%x\n", jcr); return; } /* * Note, we receive the whole attribute record, but we select out only the stat * packet, VolSessionId, VolSessionTime, FileIndex, file type, and file name to * store in the catalog. */ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) { unser_declare; uint32_t VolSessionId, VolSessionTime; int32_t Stream; uint32_t FileIndex; char *p; int len; char *fname, *attr; ATTR_DBR *ar = NULL; uint32_t reclen; /* * Start transaction allocates jcr->attr and jcr->ar if needed */ db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ ar = jcr->ar; /* * Start by scanning directly in the message buffer to get Stream * there may be a cached attr so we cannot yet write into * jcr->attr or jcr->ar */ p = msg; skip_nonspaces(&p); /* UpdCat */ skip_spaces(&p); skip_nonspaces(&p); /* Job=nnn */ skip_spaces(&p); skip_nonspaces(&p); /* "FileAttributes" */ p += 1; /* * The following "SD header" fields are serialized */ unser_begin(p, 0); unser_uint32(VolSessionId); /* VolSessionId */ unser_uint32(VolSessionTime); /* VolSessionTime */ unser_int32(FileIndex); /* FileIndex */ unser_int32(Stream); /* Stream */ unser_uint32(reclen); /* Record length */ p += unser_length(p); /* Raw record follows */ /** * At this point p points to the raw record, which varies according * to what kind of a record (Stream) was sent. Note, the integer * fields at the beginning of these "raw" records are in ASCII with * spaces between them so one can use scanf or manual scanning to * extract the fields. * * File Attributes * File_index * File type * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK or FT_LNKSAVED) * Encoded extended-attributes (for Win32) * Delta sequence number (32 bit int) * * Restore Object * File_index * File_type * Object_index * Object_len (possibly compressed) * Object_full_len (not compressed) * Object_compression * Plugin_name * Object_name * Binary Object data */ Dmsg1(400, "UpdCat msg=%s\n", msg); Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d reclen=%d\n", VolSessionId, VolSessionTime, FileIndex, Stream, reclen); jcr->SDJobBytes += reclen; /* update number of bytes transferred for quotas */ /* * Depending on the stream we are handling dispatch. */ switch (Stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: if (jcr->cached_attribute) { Dmsg2(400, "Cached attr. Stream=%d fname=%s\n", ar->Stream, ar->fname); if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error: ERR=%s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } /* * Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */ jcr->attr = check_pool_memory_size(jcr->attr, msglen); memcpy(jcr->attr, msg, msglen); p = jcr->attr - msg + p; /* point p into jcr->attr */ skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); ar->FileType = str_to_int32(p); skip_nonspaces(&p); /* skip FileType */ skip_spaces(&p); fname = p; len = strlen(fname); /* length before attributes */ attr = &fname[len+1]; ar->DeltaSeq = 0; if (ar->FileType == FT_REG) { p = attr + strlen(attr) + 1; /* point to link */ p = p + strlen(p) + 1; /* point to extended attributes */ p = p + strlen(p) + 1; /* point to delta sequence */ /* * Older FDs don't have a delta sequence, so check if it is there */ if (p - jcr->attr < msglen) { ar->DeltaSeq = str_to_int32(p); /* delta_seq */ } } Dmsg2(400, "dirdattr = attr; ar->fname = fname; if (ar->FileType == FT_DELETED) { ar->FileIndex = 0; /* special value */ } else { ar->FileIndex = FileIndex; } ar->Stream = Stream; ar->link = NULL; if (jcr->mig_jcr) { ar->JobId = jcr->mig_jcr->JobId; } else { ar->JobId = jcr->JobId; } ar->Digest = NULL; ar->DigestType = CRYPTO_DIGEST_NONE; jcr->cached_attribute = true; Dmsg2(400, "dirdmig_jcr) { ro.JobId = jcr->mig_jcr->JobId; } else { ro.JobId = jcr->JobId; } Dmsg1(100, "Robj=%s\n", p); skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); ro.FileType = str_to_int32(p); /* FileType */ skip_nonspaces(&p); skip_spaces(&p); ro.object_index = str_to_int32(p); /* Object Index */ skip_nonspaces(&p); skip_spaces(&p); ro.object_len = str_to_int32(p); /* object length possibly compressed */ skip_nonspaces(&p); skip_spaces(&p); ro.object_full_len = str_to_int32(p); /* uncompressed object length */ skip_nonspaces(&p); skip_spaces(&p); ro.object_compression = str_to_int32(p); /* compression */ skip_nonspaces(&p); skip_spaces(&p); ro.plugin_name = p; /* point to plugin name */ len = strlen(ro.plugin_name); ro.object_name = &ro.plugin_name[len+1]; /* point to object name */ len = strlen(ro.object_name); ro.object = &ro.object_name[len+1]; /* point to object */ ro.object[ro.object_len] = 0; /* add zero for those who attempt printing */ Dmsg7(100, "oname=%s stream=%d FT=%d FI=%d JobId=%d, obj_len=%d\nobj=\"%s\"\n", ro.object_name, ro.Stream, ro.FileType, ro.FileIndex, ro.JobId, ro.object_len, ro.object); /* * Store it. */ if (!db_create_restore_object_record(jcr, jcr->db, &ro)) { Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db)); } break; } default: if (crypto_digest_stream_type(Stream) != CRYPTO_DIGEST_NONE) { fname = p; if (ar->FileIndex != FileIndex) { Jmsg3(jcr, M_WARNING, 0, _("%s not same File=%d as attributes=%d\n"), stream_to_ascii(Stream), FileIndex, ar->FileIndex); } else { /* * Update digest in catalog */ char digestbuf[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; int len = 0; int type = CRYPTO_DIGEST_NONE; switch(Stream) { case STREAM_MD5_DIGEST: len = CRYPTO_DIGEST_MD5_SIZE; type = CRYPTO_DIGEST_MD5; break; case STREAM_SHA1_DIGEST: len = CRYPTO_DIGEST_SHA1_SIZE; type = CRYPTO_DIGEST_SHA1; break; case STREAM_SHA256_DIGEST: len = CRYPTO_DIGEST_SHA256_SIZE; type = CRYPTO_DIGEST_SHA256; break; case STREAM_SHA512_DIGEST: len = CRYPTO_DIGEST_SHA512_SIZE; type = CRYPTO_DIGEST_SHA512; break; default: /* * Never reached ... */ Jmsg(jcr, M_ERROR, 0, _("Catalog error updating file digest. Unsupported digest stream type: %d"), Stream); } bin_to_base64(digestbuf, sizeof(digestbuf), fname, len, true); Dmsg3(400, "DigestLen=%d Digest=%s type=%d\n", strlen(digestbuf), digestbuf, Stream); if (jcr->cached_attribute) { ar->Digest = digestbuf; ar->DigestType = type; Dmsg2(400, "Cached attr with digest. Stream=%d fname=%s\n", ar->Stream, ar->fname); /* * Update BaseFile table */ if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } else { if (!db_add_digest_to_file_record(jcr, jcr->db, ar->FileId, digestbuf, type)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating file digest. %s"), db_strerror(jcr->db)); } } } } break; } } /* * Update File Attributes in the catalog with data sent by the Storage daemon. */ void catalog_update(JCR *jcr, BSOCK *bs) { if (!jcr->res.pool->catalog_files) { return; /* user disabled cataloging */ } if (jcr->is_job_canceled()) { goto bail_out; } if (!jcr->db) { POOLMEM *omsg = get_memory(bs->msglen+1); pm_strcpy(omsg, bs->msg); bs->fsend(_("1994 Invalid Catalog Update: %s"), omsg); Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog Update; DB not open: %s"), omsg); free_memory(omsg); goto bail_out; } update_attribute(jcr, bs->msg, bs->msglen); bail_out: if (jcr->is_job_canceled()) { cancel_storage_daemon_job(jcr); } } /* * Update File Attributes in the catalog with data read from * the storage daemon spool file. We receive the filename and * we try to read it. */ bool despool_attributes_from_file(JCR *jcr, const char *file) { bool retval = false; int32_t pktsiz; size_t nbytes; ssize_t size = 0; int32_t msglen; /* message length */ int spool_fd = -1; POOLMEM *msg = get_pool_memory(PM_MESSAGE); Dmsg0(100, "Begin despool_attributes_from_file\n"); if (jcr->is_job_canceled() || !jcr->res.pool->catalog_files || !jcr->db) { goto bail_out; /* user disabled cataloging */ } spool_fd = open(file, O_RDONLY | O_BINARY); if (spool_fd == -1) { Dmsg0(100, "cancel despool_attributes_from_file\n"); /* send an error message */ goto bail_out; } #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) posix_fadvise(spool_fd, 0, 0, POSIX_FADV_WILLNEED); #endif while ((nbytes = read(spool_fd, (char *)&pktsiz, sizeof(int32_t))) == sizeof(int32_t)) { size += sizeof(int32_t); msglen = ntohl(pktsiz); if (msglen > 0) { /* * check for msglen + \0 */ if ((msglen + 1) > (int32_t) sizeof_pool_memory(msg)) { msg = realloc_pool_memory(msg, msglen + 1); } nbytes = read(spool_fd, msg, msglen); if (nbytes != (size_t) msglen) { berrno be; Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, msglen); Qmsg1(jcr, M_FATAL, 0, _("read attr spool error. ERR=%s\n"), be.bstrerror()); goto bail_out; } msg[nbytes] = '\0'; size += nbytes; } if (!jcr->is_job_canceled()) { update_attribute(jcr, msg, msglen); if (jcr->is_job_canceled()) { goto bail_out; } } } retval = true; bail_out: if (spool_fd != -1) { close(spool_fd); } if (jcr->is_job_canceled()) { cancel_storage_daemon_job(jcr); } free_pool_memory(msg); Dmsg1(100, "End despool_attributes_from_file retval=%i\n", retval); return retval; } bareos-Release-14.2.6/src/dird/dbcheck.c000066400000000000000000001317501263011562700177070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to check a BAREOS database for consistency and to make repairs * * Kern E. Sibbald, August 2002 */ #include "bareos.h" #include "cats/cats.h" #include "cats/sql_glue.h" #include "lib/runscript.h" #include "dird/dird_conf.h" extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code); typedef struct s_id_ctx { int64_t *Id; /* ids to be modified */ int num_ids; /* ids stored */ int max_ids; /* size of array */ int num_del; /* number deleted */ int tot_ids; /* total to process */ } ID_LIST; typedef struct s_name_ctx { char **name; /* list of names */ int num_ids; /* ids stored */ int max_ids; /* size of array */ int num_del; /* number deleted */ int tot_ids; /* total to process */ } NAME_LIST; /* * Global variables */ static bool fix = false; static bool batch = false; static B_DB *db; static ID_LIST id_list; static NAME_LIST name_list; static char buf[20000]; static bool quit = false; static const char *idx_tmp_name; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) static const char *backend_directory = _PATH_BAREOS_BACKENDDIR; #endif DIRRES *me = NULL; /* Our Global resource */ CONFIG *my_config = NULL; /* Our Global config */ #define MAX_ID_LIST_LEN 10000000 /* * Forward referenced functions */ static void print_catalog_details(CATRES *catalog, const char *working_dir); static int make_id_list(const char *query, ID_LIST *id_list); static int delete_id_list(const char *query, ID_LIST *id_list); static int make_name_list(const char *query, NAME_LIST *name_list); static void print_name_list(NAME_LIST *name_list); static void free_name_list(NAME_LIST *name_list); static char *get_cmd(const char *prompt); static void eliminate_duplicate_filenames(); static void eliminate_duplicate_paths(); static void eliminate_orphaned_jobmedia_records(); static void eliminate_orphaned_file_records(); static void eliminate_orphaned_path_records(); static void eliminate_orphaned_filename_records(); static void eliminate_orphaned_fileset_records(); static void eliminate_orphaned_client_records(); static void eliminate_orphaned_job_records(); static void eliminate_admin_records(); static void eliminate_restore_records(); static void repair_bad_paths(); static void repair_bad_filenames(); static void do_interactive_mode(); static bool yes_no(const char *prompt); static bool check_idx(const char *col_name); static bool create_tmp_idx(const char *idx_name, const char *table_name, const char *col_name); static bool drop_tmp_idx(const char *idx_name, const char *table_name); static int check_idx_handler(void *ctx, int num_fields, char **row); static void usage() { fprintf(stderr, "Usage: dbcheck [ options ] [] []\n" " -b batch mode\n" " -B print catalog configuration and exit\n" " -c Director configuration filename\n" " -C catalog name in the director configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -D specify the database driver name (default NULL) \n" " -f fix inconsistencies\n" " -v verbose\n" " -? print this message\n\n"); exit(1); } int main (int argc, char *argv[]) { int ch; const char *db_driver = NULL; const char *user, *password, *db_name, *dbhost; int dbport = 0; bool print_catalog=false; char *configfile = NULL; char *catalogname = NULL; char *endptr; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) alist *backend_directories = NULL; #endif setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); lmgr_init_thread(); my_name_is(argc, argv, "dbcheck"); init_msg(NULL, NULL); /* setup message handler */ memset(&id_list, 0, sizeof(id_list)); memset(&name_list, 0, sizeof(name_list)); while ((ch = getopt(argc, argv, "bc:C:D:d:fvBt?")) != -1) { switch (ch) { case 'B': print_catalog = true; /* get catalog information from config */ break; case 'b': /* batch */ batch = true; break; case 'C': /* CatalogName */ catalogname = optarg; break; case 'c': /* configfile */ configfile = optarg; break; case 'D': /* db_driver */ db_driver = optarg; break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* fix inconsistencies */ fix = true; break; case 'v': verbose++; break; case '?': default: usage(); } } argc -= optind; argv += optind; OSDependentInit(); if (configfile) { CATRES *catalog = NULL; int found = 0; if (argc > 0) { Pmsg0(0, _("Warning skipping the additional parameters for working directory/dbname/user/password/host.\n")); } my_config = new_config_parser(); parse_dir_config(my_config, configfile, M_ERROR_TERM); LockRes(); foreach_res(catalog, R_CATALOG) { if (catalogname && bstrcmp(catalog->hdr.name, catalogname)) { ++found; break; } else if (!catalogname) { // stop on first if no catalogname is given ++found; break; } } UnlockRes(); if (!found) { if (catalogname) { Pmsg2(0, _("Error can not find the Catalog name[%s] in the given config file [%s]\n"), catalogname, configfile); } else { Pmsg1(0, _("Error there is no Catalog section in the given config file [%s]\n"), configfile); } exit(1); } else { LockRes(); me = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); UnlockRes(); if (!me) { Pmsg0(0, _("Error no Director resource defined.\n")); exit(1); } set_working_directory(me->working_directory); #if defined(HAVE_DYNAMIC_CATS_BACKENDS) db_set_backend_dirs(me->backend_directories); #endif /* * Print catalog information and exit (-B) */ if (print_catalog) { print_catalog_details(catalog, me->working_directory); exit(0); } db_name = catalog->db_name; user = catalog->db_user; password = catalog->db_password.value; dbhost = catalog->db_address; db_driver = catalog->db_driver; if (dbhost && dbhost[0] == 0) { dbhost = NULL; } dbport = catalog->db_port; } } else { if (argc > 6) { Pmsg0(0, _("Wrong number of arguments.\n")); usage(); } if (argc < 1) { Pmsg0(0, _("Working directory not supplied.\n")); usage(); } /* * This is needed by SQLite to find the db */ working_directory = argv[0]; db_name = "bareos"; user = db_name; password = ""; dbhost = NULL; if (argc == 2) { db_name = argv[1]; user = db_name; } else if (argc == 3) { db_name = argv[1]; user = argv[2]; } else if (argc == 4) { db_name = argv[1]; user = argv[2]; password = argv[3]; } else if (argc == 5) { db_name = argv[1]; user = argv[2]; password = argv[3]; dbhost = argv[4]; } else if (argc == 6) { db_name = argv[1]; user = argv[2]; password = argv[3]; dbhost = argv[4]; errno = 0; dbport = strtol(argv[5], &endptr, 10); if (*endptr != '\0') { Pmsg0(0, _("Database port must be a numeric value.\n")); exit(1); } else if (errno == ERANGE) { Pmsg0(0, _("Database port must be a int value.\n")); exit(1); } } #if defined(HAVE_DYNAMIC_CATS_BACKENDS) backend_directories = New(alist(10, owned_by_alist)); backend_directories->append((char *)backend_directory); db_set_backend_dirs( backend_directories ); #endif } /* * Open database */ db = db_init_database(NULL, db_driver, db_name, user, password, dbhost, dbport, NULL); if (!db_open_database(NULL, db)) { Emsg1(M_FATAL, 0, "%s", db_strerror(db)); return 1; } /* * Drop temporary index idx_tmp_name if it already exists */ drop_tmp_idx("idxPIchk", "File"); if (batch) { repair_bad_paths(); repair_bad_filenames(); eliminate_duplicate_filenames(); eliminate_duplicate_paths(); eliminate_orphaned_jobmedia_records(); eliminate_orphaned_file_records(); eliminate_orphaned_path_records(); eliminate_orphaned_filename_records(); eliminate_orphaned_fileset_records(); eliminate_orphaned_client_records(); eliminate_orphaned_job_records(); eliminate_admin_records(); eliminate_restore_records(); } else { do_interactive_mode(); } /* * Drop temporary index idx_tmp_name */ drop_tmp_idx("idxPIchk", "File"); db_close_database(NULL, db); db_flush_backends(); close_msg(NULL); term_msg(); lmgr_cleanup_main(); return 0; } static void print_catalog_details(CATRES *catalog, const char *working_dir) { POOLMEM *catalog_details = get_pool_memory(PM_MESSAGE); /* * Instantiate a B_DB class and see what db_type gets assigned to it. */ db = db_init_database(NULL, catalog->db_driver, catalog->db_name, catalog->db_user, catalog->db_password.value, catalog->db_address, catalog->db_port, catalog->db_socket, catalog->mult_db_connections, catalog->disable_batch_insert); if (db) { printf("%sdb_type=%s\nworking_dir=%s\n", catalog->display(catalog_details), db->db_get_type(), working_directory); db_close_database(NULL, db); } free_pool_memory(catalog_details); } static void do_interactive_mode() { const char *cmd; printf(_("Hello, this is the database check/correct program.\n")); if (fix) printf(_("Modify database is on.")); else printf(_("Modify database is off.")); if (verbose) printf(_(" Verbose is on.\n")); else printf(_(" Verbose is off.\n")); printf(_("Please select the function you want to perform.\n")); while (!quit) { if (fix) { printf(_("\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Repair bad Filename records\n" " 4) Repair bad Path records\n" " 5) Eliminate duplicate Filename records\n" " 6) Eliminate duplicate Path records\n" " 7) Eliminate orphaned Jobmedia records\n" " 8) Eliminate orphaned File records\n" " 9) Eliminate orphaned Path records\n" " 10) Eliminate orphaned Filename records\n" " 11) Eliminate orphaned FileSet records\n" " 12) Eliminate orphaned Client records\n" " 13) Eliminate orphaned Job records\n" " 14) Eliminate all Admin records\n" " 15) Eliminate all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n")); } else { printf(_("\n" " 1) Toggle modify database flag\n" " 2) Toggle verbose flag\n" " 3) Check for bad Filename records\n" " 4) Check for bad Path records\n" " 5) Check for duplicate Filename records\n" " 6) Check for duplicate Path records\n" " 7) Check for orphaned Jobmedia records\n" " 8) Check for orphaned File records\n" " 9) Check for orphaned Path records\n" " 10) Check for orphaned Filename records\n" " 11) Check for orphaned FileSet records\n" " 12) Check for orphaned Client records\n" " 13) Check for orphaned Job records\n" " 14) Check for all Admin records\n" " 15) Check for all Restore records\n" " 16) All (3-15)\n" " 17) Quit\n")); } cmd = get_cmd(_("Select function number: ")); if (cmd) { int item = atoi(cmd); switch (item) { case 1: fix = !fix; if (fix) printf(_("Database will be modified.\n")); else printf(_("Database will NOT be modified.\n")); break; case 2: verbose = verbose ? 0 : 1; if (verbose) printf(_(" Verbose is on.\n")); else printf(_(" Verbose is off.\n")); break; case 3: repair_bad_filenames(); break; case 4: repair_bad_paths(); break; case 5: eliminate_duplicate_filenames(); break; case 6: eliminate_duplicate_paths(); break; case 7: eliminate_orphaned_jobmedia_records(); break; case 8: eliminate_orphaned_file_records(); break; case 9: eliminate_orphaned_path_records(); break; case 10: eliminate_orphaned_filename_records(); break; case 11: eliminate_orphaned_fileset_records(); break; case 12: eliminate_orphaned_client_records(); break; case 13: eliminate_orphaned_job_records(); break; case 14: eliminate_admin_records(); break; case 15: eliminate_restore_records(); break; case 16: repair_bad_filenames(); repair_bad_paths(); eliminate_duplicate_filenames(); eliminate_duplicate_paths(); eliminate_orphaned_jobmedia_records(); eliminate_orphaned_file_records(); eliminate_orphaned_path_records(); eliminate_orphaned_filename_records(); eliminate_orphaned_fileset_records(); eliminate_orphaned_client_records(); eliminate_orphaned_job_records(); eliminate_admin_records(); eliminate_restore_records(); break; case 17: quit = true; break; } } } } static int print_name_handler(void *ctx, int num_fields, char **row) { if (row[0]) { printf("%s\n", row[0]); } return 0; } static int get_name_handler(void *ctx, int num_fields, char **row) { POOLMEM *name = (POOLMEM *)ctx; if (row[0]) { pm_strcpy(&name, row[0]); } return 0; } static int print_job_handler(void *ctx, int num_fields, char **row) { printf(_("JobId=%s Name=\"%s\" StartTime=%s\n"), NPRT(row[0]), NPRT(row[1]), NPRT(row[2])); return 0; } static int print_jobmedia_handler(void *ctx, int num_fields, char **row) { printf(_("Orphaned JobMediaId=%s JobId=%s Volume=\"%s\"\n"), NPRT(row[0]), NPRT(row[1]), NPRT(row[2])); return 0; } static int print_file_handler(void *ctx, int num_fields, char **row) { printf(_("Orphaned FileId=%s JobId=%s Volume=\"%s\"\n"), NPRT(row[0]), NPRT(row[1]), NPRT(row[2])); return 0; } static int print_fileset_handler(void *ctx, int num_fields, char **row) { printf(_("Orphaned FileSetId=%s FileSet=\"%s\" MD5=%s\n"), NPRT(row[0]), NPRT(row[1]), NPRT(row[2])); return 0; } static int print_client_handler(void *ctx, int num_fields, char **row) { printf(_("Orphaned ClientId=%s Name=\"%s\"\n"), NPRT(row[0]), NPRT(row[1])); return 0; } /* * Called here with each id to be added to the list */ static int id_list_handler(void *ctx, int num_fields, char **row) { ID_LIST *lst = (ID_LIST *)ctx; if (lst->num_ids == MAX_ID_LIST_LEN) { return 1; } if (lst->num_ids == lst->max_ids) { if (lst->max_ids == 0) { lst->max_ids = 10000; lst->Id = (int64_t *)bmalloc(sizeof(int64_t) * lst->max_ids); } else { lst->max_ids = (lst->max_ids * 3) / 2; lst->Id = (int64_t *)brealloc(lst->Id, sizeof(int64_t) * lst->max_ids); } } lst->Id[lst->num_ids++] = str_to_int64(row[0]); return 0; } /* * Construct record id list */ static int make_id_list(const char *query, ID_LIST *id_list) { id_list->num_ids = 0; id_list->num_del = 0; id_list->tot_ids = 0; if (!db_sql_query(db, query, id_list_handler, (void *)id_list)) { printf("%s", db_strerror(db)); return 0; } return 1; } /* * Delete all entries in the list */ static int delete_id_list(const char *query, ID_LIST *id_list) { char ed1[50]; for (int i=0; i < id_list->num_ids; i++) { bsnprintf(buf, sizeof(buf), query, edit_int64(id_list->Id[i], ed1)); if (verbose) { printf(_("Deleting: %s\n"), buf); } db_sql_query(db, buf, NULL, NULL); } return 1; } /* * Called here with each name to be added to the list */ static int name_list_handler(void *ctx, int num_fields, char **row) { NAME_LIST *name = (NAME_LIST *)ctx; if (name->num_ids == MAX_ID_LIST_LEN) { return 1; } if (name->num_ids == name->max_ids) { if (name->max_ids == 0) { name->max_ids = 10000; name->name = (char **)bmalloc(sizeof(char *) * name->max_ids); } else { name->max_ids = (name->max_ids * 3) / 2; name->name = (char **)brealloc(name->name, sizeof(char *) * name->max_ids); } } name->name[name->num_ids++] = bstrdup(row[0]); return 0; } /* * Construct name list */ static int make_name_list(const char *query, NAME_LIST *name_list) { name_list->num_ids = 0; name_list->num_del = 0; name_list->tot_ids = 0; if (!db_sql_query(db, query, name_list_handler, (void *)name_list)) { printf("%s", db_strerror(db)); return 0; } return 1; } /* * Print names in the list */ static void print_name_list(NAME_LIST *name_list) { for (int i=0; i < name_list->num_ids; i++) { printf("%s\n", name_list->name[i]); } } /* * Free names in the list */ static void free_name_list(NAME_LIST *name_list) { for (int i=0; i < name_list->num_ids; i++) { free(name_list->name[i]); } name_list->num_ids = 0; } static void eliminate_duplicate_filenames() { const char *query; char esc_name[5000]; printf(_("Checking for duplicate Filename entries.\n")); /* * Make list of duplicated names */ query = "SELECT Name, count(Name) as Count FROM Filename GROUP BY Name " "HAVING count(Name) > 1"; if (!make_name_list(query, &name_list)) { exit(1); } printf(_("Found %d duplicate Filename records.\n"), name_list.num_ids); if (name_list.num_ids && verbose && yes_no(_("Print the list? (yes/no): "))) { print_name_list(&name_list); } if (quit) { return; } if (fix) { /* * Loop through list of duplicate names */ for (int i=0; i 1) { printf("%s\n", buf); } if (!make_id_list(buf, &id_list)) { exit(1); } if (verbose) { printf(_("Found %d for: %s\n"), id_list.num_ids, name_list.name[i]); } /* * Force all records to use the first id then delete the other ids */ for (int j=1; j 1) { printf("%s\n", buf); } db_sql_query(db, buf, NULL, NULL); bsnprintf(buf, sizeof(buf), "DELETE FROM Filename WHERE FilenameId=%s", ed2); if (verbose > 2) { printf("%s\n", buf); } db_sql_query(db, buf, NULL, NULL); } } } free_name_list(&name_list); } static void eliminate_duplicate_paths() { const char *query; char esc_name[5000]; printf(_("Checking for duplicate Path entries.\n")); /* * Make list of duplicated names */ query = "SELECT Path, count(Path) as Count FROM Path " "GROUP BY Path HAVING count(Path) > 1"; if (!make_name_list(query, &name_list)) { exit(1); } printf(_("Found %d duplicate Path records.\n"), name_list.num_ids); if (name_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { print_name_list(&name_list); } if (quit) { return; } if (fix) { /* * Loop through list of duplicate names */ for (int i=0; i 1) { printf("%s\n", buf); } if (!make_id_list(buf, &id_list)) { exit(1); } if (verbose) { printf(_("Found %d for: %s\n"), id_list.num_ids, name_list.name[i]); } /* * Force all records to use the first id then delete the other ids */ for (int j=1; j 1) { printf("%s\n", buf); } db_sql_query(db, buf, NULL, NULL); bsnprintf(buf, sizeof(buf), "DELETE FROM Path WHERE PathId=%s", ed2); if (verbose > 2) { printf("%s\n", buf); } db_sql_query(db, buf, NULL, NULL); } } } free_name_list(&name_list); } static void eliminate_orphaned_jobmedia_records() { const char *query = "SELECT JobMedia.JobMediaId,Job.JobId FROM JobMedia " "LEFT OUTER JOIN Job ON (JobMedia.JobId=Job.JobId) " "WHERE Job.JobId IS NULL LIMIT 300000"; printf(_("Checking for orphaned JobMedia entries.\n")); if (!make_id_list(query, &id_list)) { exit(1); } /* * Loop doing 300000 at a time */ while (id_list.num_ids != 0) { printf(_("Found %d orphaned JobMedia records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT JobMedia.JobMediaId,JobMedia.JobId,Media.VolumeName FROM JobMedia,Media " "WHERE JobMedia.JobMediaId=%s AND Media.MediaId=JobMedia.MediaId", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_jobmedia_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned JobMedia records.\n"), id_list.num_ids); delete_id_list("DELETE FROM JobMedia WHERE JobMediaId=%s", &id_list); } else { break; /* get out if not updating db */ } if (!make_id_list(query, &id_list)) { exit(1); } } } static void eliminate_orphaned_file_records() { const char *query = "SELECT File.FileId,Job.JobId FROM File " "LEFT OUTER JOIN Job ON (File.JobId=Job.JobId) " "WHERE Job.JobId IS NULL LIMIT 300000"; printf(_("Checking for orphaned File entries. This may take some time!\n")); if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } /* * Loop doing 300000 at a time */ while (id_list.num_ids != 0) { printf(_("Found %d orphaned File records.\n"), id_list.num_ids); if (name_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT File.FileId,File.JobId,Filename.Name FROM File,Filename " "WHERE File.FileId=%s AND File.FilenameId=Filename.FilenameId", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_file_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned File records.\n"), id_list.num_ids); delete_id_list("DELETE FROM File WHERE FileId=%s", &id_list); } else { break; /* get out if not updating db */ } if (!make_id_list(query, &id_list)) { exit(1); } } } static void eliminate_orphaned_path_records() { db_int64_ctx lctx; lctx.count=0; db_sql_query(db, "SELECT 1 FROM Job WHERE HasCache=1 LIMIT 1", db_int64_handler, &lctx); if (lctx.count == 1) { printf(_("Pruning orphaned Path entries isn't possible when using BVFS.\n")); return; } idx_tmp_name = NULL; /* * Check the existence of the required "one column" index */ if (!check_idx("PathId")) { if (yes_no(_("Create temporary index? (yes/no): "))) { /* * create temporary index PathId */ create_tmp_idx("idxPIchk", "File", "PathId"); } } const char *query = "SELECT DISTINCT Path.PathId,File.PathId FROM Path " "LEFT OUTER JOIN File ON (Path.PathId=File.PathId) " "WHERE File.PathId IS NULL LIMIT 300000"; printf(_("Checking for orphaned Path entries. This may take some time!\n")); if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } /* * Loop doing 300000 at a time */ while (id_list.num_ids != 0) { printf(_("Found %d orphaned Path records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT Path FROM Path WHERE PathId=%s", edit_int64(id_list.Id[i], ed1)); db_sql_query(db, buf, print_name_handler, NULL); } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned Path records.\n"), id_list.num_ids); delete_id_list("DELETE FROM Path WHERE PathId=%s", &id_list); } else { break; /* get out if not updating db */ } if (!make_id_list(query, &id_list)) { exit(1); } } /* * Drop temporary index idx_tmp_name */ drop_tmp_idx("idxPIchk", "File"); } static void eliminate_orphaned_filename_records() { idx_tmp_name = NULL; /* * Check the existence of the required "one column" index */ if (!check_idx("FilenameId") ) { if (yes_no(_("Create temporary index? (yes/no): "))) { /* * Create temporary index FilenameId */ create_tmp_idx("idxFIchk", "File", "FilenameId"); } } const char *query = "SELECT Filename.FilenameId,File.FilenameId FROM Filename " "LEFT OUTER JOIN File ON (Filename.FilenameId=File.FilenameId) " "WHERE File.FilenameId IS NULL LIMIT 300000"; printf(_("Checking for orphaned Filename entries. This may take some time!\n")); if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } /* * Loop doing 300000 at a time */ while (id_list.num_ids != 0) { printf(_("Found %d orphaned Filename records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT Name FROM Filename WHERE FilenameId=%s", edit_int64(id_list.Id[i], ed1)); db_sql_query(db, buf, print_name_handler, NULL); } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned Filename records.\n"), id_list.num_ids); delete_id_list("DELETE FROM Filename WHERE FilenameId=%s", &id_list); } else { break; /* get out if not updating db */ } if (!make_id_list(query, &id_list)) { exit(1); } } /* * Drop temporary index idx_tmp_name */ drop_tmp_idx("idxFIchk", "File"); } static void eliminate_orphaned_fileset_records() { const char *query; printf(_("Checking for orphaned FileSet entries. This takes some time!\n")); query = "SELECT FileSet.FileSetId,Job.FileSetId FROM FileSet " "LEFT OUTER JOIN Job ON (FileSet.FileSetId=Job.FileSetId) " "WHERE Job.FileSetId IS NULL"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d orphaned FileSet records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT FileSetId,FileSet,MD5 FROM FileSet " "WHERE FileSetId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_fileset_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned FileSet records.\n"), id_list.num_ids); delete_id_list("DELETE FROM FileSet WHERE FileSetId=%s", &id_list); } } static void eliminate_orphaned_client_records() { const char *query; printf(_("Checking for orphaned Client entries.\n")); /* * In English: * Wiffle through Client for every Client * joining with the Job table including every Client even if * there is not a match in Job (left outer join), then * filter out only those where no Job points to a Client * i.e. Job.Client is NULL */ query = "SELECT Client.ClientId,Client.Name FROM Client " "LEFT OUTER JOIN Job ON (Client.ClientId=Job.ClientId) " "WHERE Job.ClientId IS NULL"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d orphaned Client records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT ClientId,Name FROM Client " "WHERE ClientId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_client_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned Client records.\n"), id_list.num_ids); delete_id_list("DELETE FROM Client WHERE ClientId=%s", &id_list); } } static void eliminate_orphaned_job_records() { const char *query; printf(_("Checking for orphaned Job entries.\n")); /* * In English: * Wiffle through Job for every Job * joining with the Client table including every Job even if * there is not a match in Client (left outer join), then * filter out only those where no Client exists * i.e. Client.Name is NULL */ query = "SELECT Job.JobId,Job.Name FROM Job " "LEFT OUTER JOIN Client ON (Job.ClientId=Client.ClientId) " "WHERE Client.Name IS NULL"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d orphaned Job records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT JobId,Name,StartTime FROM Job " "WHERE JobId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_job_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d orphaned Job records.\n"), id_list.num_ids); delete_id_list("DELETE FROM Job WHERE JobId=%s", &id_list); printf(_("Deleting JobMedia records of orphaned Job records.\n")); delete_id_list("DELETE FROM JobMedia WHERE JobId=%s", &id_list); printf(_("Deleting Log records of orphaned Job records.\n")); delete_id_list("DELETE FROM Log WHERE JobId=%s", &id_list); } } static void eliminate_admin_records() { const char *query; printf(_("Checking for Admin Job entries.\n")); query = "SELECT Job.JobId FROM Job " "WHERE Job.Type='D'"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d Admin Job records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT JobId,Name,StartTime FROM Job " "WHERE JobId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_job_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d Admin Job records.\n"), id_list.num_ids); delete_id_list("DELETE FROM Job WHERE JobId=%s", &id_list); } } static void eliminate_restore_records() { const char *query; printf(_("Checking for Restore Job entries.\n")); query = "SELECT Job.JobId FROM Job " "WHERE Job.Type='R'"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d Restore Job records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (int i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT JobId,Name,StartTime FROM Job " "WHERE JobId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_job_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { printf(_("Deleting %d Restore Job records.\n"), id_list.num_ids); delete_id_list("DELETE FROM Job WHERE JobId=%s", &id_list); } } static void repair_bad_filenames() { const char *query; int i; printf(_("Checking for Filenames with a trailing slash\n")); query = "SELECT FilenameId,Name from Filename " "WHERE Name LIKE '%/'"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d bad Filename records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT Name FROM Filename WHERE FilenameId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_name_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { POOLMEM *name = get_pool_memory(PM_FNAME); char esc_name[5000]; printf(_("Reparing %d bad Filename records.\n"), id_list.num_ids); for (i=0; i < id_list.num_ids; i++) { int len; char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT Name FROM Filename WHERE FilenameId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, get_name_handler, name)) { printf("%s\n", db_strerror(db)); } /* * Strip trailing slash(es) */ for (len=strlen(name); len > 0 && IsPathSeparator(name[len-1]); len--) { } if (len == 0) { len = 1; esc_name[0] = ' '; esc_name[1] = 0; } else { name[len-1] = 0; db_escape_string(NULL, db, esc_name, name, len); } bsnprintf(buf, sizeof(buf), "UPDATE Filename SET Name='%s' WHERE FilenameId=%s", esc_name, edit_int64(id_list.Id[i], ed1)); if (verbose > 1) { printf("%s\n", buf); } db_sql_query(db, buf, NULL, NULL); } free_pool_memory(name); } } static void repair_bad_paths() { const char *query; int i; printf(_("Checking for Paths without a trailing slash\n")); query = "SELECT PathId,Path from Path " "WHERE Path NOT LIKE '%/'"; if (verbose > 1) { printf("%s\n", query); } if (!make_id_list(query, &id_list)) { exit(1); } printf(_("Found %d bad Path records.\n"), id_list.num_ids); if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) { for (i=0; i < id_list.num_ids; i++) { char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT Path FROM Path WHERE PathId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, print_name_handler, NULL)) { printf("%s\n", db_strerror(db)); } } } if (quit) { return; } if (fix && id_list.num_ids > 0) { POOLMEM *name = get_pool_memory(PM_FNAME); char esc_name[5000]; printf(_("Reparing %d bad Filename records.\n"), id_list.num_ids); for (i=0; i < id_list.num_ids; i++) { int len; char ed1[50]; bsnprintf(buf, sizeof(buf), "SELECT Path FROM Path WHERE PathId=%s", edit_int64(id_list.Id[i], ed1)); if (!db_sql_query(db, buf, get_name_handler, name)) { printf("%s\n", db_strerror(db)); } /* * Strip trailing blanks */ for (len=strlen(name); len > 0 && name[len-1]==' '; len--) { name[len-1] = 0; } /* * Add trailing slash */ len = pm_strcat(&name, "/"); db_escape_string(NULL, db, esc_name, name, len); bsnprintf(buf, sizeof(buf), "UPDATE Path SET Path='%s' WHERE PathId=%s", esc_name, edit_int64(id_list.Id[i], ed1)); if (verbose > 1) { printf("%s\n", buf); } db_sql_query(db, buf, NULL, NULL); } free_pool_memory(name); } } /* * Gen next input command from the terminal */ static char *get_cmd(const char *prompt) { static char cmd[1000]; printf("%s", prompt); if (fgets(cmd, sizeof(cmd), stdin) == NULL) { printf("\n"); quit = true; return NULL; } strip_trailing_junk(cmd); return cmd; } static bool yes_no(const char *prompt) { char *cmd; cmd = get_cmd(prompt); if (!cmd) { quit = true; return false; } return (bstrcasecmp(cmd, "yes")) || (bstrcasecmp(cmd, _("yes"))); } /* * The code below to add indexes is needed only for MySQL, and * that to improve the performance. */ #define MAXIDX 100 typedef struct s_idx_list { char *key_name; int count_key; /* how many times the index meets *key_name */ int count_col; /* how many times meets the desired column name */ } IDX_LIST; static IDX_LIST idx_list[MAXIDX]; /* * Called here with each table index to be added to the list */ static int check_idx_handler(void *ctx, int num_fields, char **row) { /* * Table | Non_unique | Key_name | Seq_in_index | Column_name |... * File | 0 | PRIMARY | 1 | FileId |... */ char *name, *key_name, *col_name; int i, len; int found = false; name = (char *)ctx; key_name = row[2]; col_name = row[4]; for(i = 0; (idx_list[i].key_name != NULL) && (i < (MAXIDX - 1)); i++) { if (bstrcasecmp(idx_list[i].key_name, key_name)) { idx_list[i].count_key++; found = true; if (bstrcasecmp(col_name, name)) { idx_list[i].count_col++; } break; } } /* * If the new Key_name, add it to the list */ if (!found) { len = strlen(key_name) + 1; idx_list[i].key_name = (char *)malloc(len); bstrncpy(idx_list[i].key_name, key_name, len); idx_list[i].count_key = 1; if (bstrcasecmp(col_name, name)) { idx_list[i].count_col = 1; } else { idx_list[i].count_col = 0; } } return 0; } /* * Return TRUE if "one column" index over *col_name exists */ static bool check_idx(const char *col_name) { int i; int found = false; const char *query = "SHOW INDEX FROM File"; switch (db_get_type_index(db)) { case SQL_TYPE_MYSQL: memset(&idx_list, 0, sizeof(idx_list)); if (!db_sql_query(db, query, check_idx_handler, (void *)col_name)) { printf("%s\n", db_strerror(db)); } for (i = 0; (idx_list[i].key_name != NULL) && (i < (MAXIDX - 1)) ; i++) { /* * NOTE : if (idx_list[i].count_key > 1) then index idx_list[i].key_name is "multiple-column" index */ if ((idx_list[i].count_key == 1) && (idx_list[i].count_col == 1)) { /* * "one column" index over *col_name found */ found = true; } } if (found) { if (verbose) { printf(_("Ok. Index over the %s column already exists and dbcheck will work faster.\n"), col_name); } } else { printf(_("Note. Index over the %s column not found, that can greatly slow down dbcheck.\n"), col_name); } return found; default: return true; } } /* * Create temporary one-column index */ static bool create_tmp_idx(const char *idx_name, const char *table_name, const char *col_name) { idx_tmp_name = NULL; printf(_("Create temporary index... This may take some time!\n")); bsnprintf(buf, sizeof(buf), "CREATE INDEX %s ON %s (%s)", idx_name, table_name, col_name); if (verbose) { printf("%s\n", buf); } if (db_sql_query(db, buf, NULL, NULL)) { idx_tmp_name = idx_name; if (verbose) { printf(_("Temporary index created.\n")); } } else { printf("%s\n", db_strerror(db)); return false; } return true; } /* * Drop temporary index */ static bool drop_tmp_idx(const char *idx_name, const char *table_name) { if (idx_tmp_name != NULL) { printf(_("Drop temporary index.\n")); bsnprintf(buf, sizeof(buf), "DROP INDEX %s ON %s", idx_name, table_name); if (verbose) { printf("%s\n", buf); } if (!db_sql_query(db, buf, NULL, NULL)) { printf("%s\n", db_strerror(db)); return false; } else { if (verbose) { printf(_("Temporary index %s deleted.\n"), idx_tmp_name); } } } idx_tmp_name = NULL; return true; } bareos-Release-14.2.6/src/dird/dir_plugins.c000066400000000000000000000536351263011562700206500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS pluginloader * * Kern Sibbald, October 2007 */ #include "bareos.h" #include "dird.h" #include "dir_plugins.h" const int dbglvl = 150; const char *plugin_type = "-dir.so"; static alist *dird_plugin_list; /* Forward referenced functions */ static bRC bareosGetValue(bpContext *ctx, brDirVariable var, void *value); static bRC bareosSetValue(bpContext *ctx, bwDirVariable var, void *value); static bRC bareosRegisterEvents(bpContext *ctx, int nr_events, ...); static bRC bareosJobMsg(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); static bRC bareosDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); static bool is_plugin_compatible(Plugin *plugin); /* BAREOS info */ static bDirInfo binfo = { sizeof(bDirFuncs), DIR_PLUGIN_INTERFACE_VERSION }; /* BAREOS entry points */ static bDirFuncs bfuncs = { sizeof(bDirFuncs), DIR_PLUGIN_INTERFACE_VERSION, bareosRegisterEvents, bareosGetValue, bareosSetValue, bareosJobMsg, bareosDebugMsg }; /* * BAREOS private context */ struct b_plugin_ctx { JCR *jcr; /* jcr for plugin */ bRC rc; /* last return code */ bool disabled; /* set if plugin disabled */ char events[nbytes_for_bits(DIR_NR_EVENTS + 1)]; /* enabled events bitmask */ }; static inline bool is_event_enabled(bpContext *ctx, bDirEventType eventType) { b_plugin_ctx *b_ctx; if (!ctx) { return true; } b_ctx = (b_plugin_ctx *)ctx->bContext; if (!b_ctx) { return true; } return bit_is_set(eventType, b_ctx->events); } static inline bool is_plugin_disabled(bpContext *ctx) { b_plugin_ctx *b_ctx; if (!ctx) { return true; } b_ctx = (b_plugin_ctx *)ctx->bContext; return b_ctx->disabled; } #ifdef needed static inline bool is_plugin_disabled(JCR *jcr) { return is_plugin_disabled(jcr->ctx); } #endif static inline bRC trigger_plugin_event(JCR *jcr, bDirEventType eventType, bDirEvent *event, bpContext *ctx, void *value) { if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); return bRC_OK; } if (is_plugin_disabled(ctx)) { Dmsg0(dbglvl, "Plugin disabled.\n"); return bRC_OK; } return dirplug_func(ctx->plugin)->handlePluginEvent(ctx, event, value); } /* * Create a plugin event */ int generate_plugin_event(JCR *jcr, bDirEventType eventType, void *value, bool reverse) { int i; bDirEvent event; alist *plugin_ctx_list; bRC rc = bRC_OK; if (!dird_plugin_list || !jcr || !jcr->plugin_ctx_list) { return bRC_OK; /* Return if no plugins loaded */ } plugin_ctx_list = jcr->plugin_ctx_list; event.eventType = eventType; Dmsg2(dbglvl, "dir-plugin_ctx_list=%p JobId=%d\n", plugin_ctx_list, jcr->JobId); /* * See if we need to trigger the loaded plugins in reverse order. */ if (reverse) { bpContext *ctx; foreach_alist_rindex(i, ctx, plugin_ctx_list) { rc = trigger_plugin_event(jcr, eventType, &event, ctx, value); if (rc != bRC_OK) { break; } } } else { bpContext *ctx; foreach_alist_index(i, ctx, plugin_ctx_list) { rc = trigger_plugin_event(jcr, eventType, &event, ctx, value); if (rc != bRC_OK) { break; } } } if (jcr->is_job_canceled()) { return bRC_Cancel; } return rc; } /* * Print to file the plugin info. */ void dump_dir_plugin(Plugin *plugin, FILE *fp) { genpInfo *info; if (!plugin) { return ; } info = (genpInfo *) plugin->pinfo; fprintf(fp, "\tversion=%d\n", info->version); fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date)); fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic)); fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author)); fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license)); fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version)); fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description)); } static void dump_dir_plugins(FILE *fp) { dump_plugins(dird_plugin_list, fp); } /** * This entry point is called internally by BAREOS to ensure * that the plugin IO calls come into this code. */ void load_dir_plugins(const char *plugin_dir, alist *plugin_names) { Plugin *plugin; int i; Dmsg0(dbglvl, "Load dir plugins\n"); if (!plugin_dir) { Dmsg0(dbglvl, "No dir plugin dir!\n"); return; } dird_plugin_list = New(alist(10, not_owned_by_alist)); if (!load_plugins((void *)&binfo, (void *)&bfuncs, dird_plugin_list, plugin_dir, plugin_names, plugin_type, is_plugin_compatible)) { /* Either none found, or some error */ if (dird_plugin_list->size() == 0) { delete dird_plugin_list; dird_plugin_list = NULL; Dmsg0(dbglvl, "No plugins loaded\n"); return; } } /* * Verify that the plugin is acceptable, and print information * about it. */ foreach_alist_index(i, plugin, dird_plugin_list) { Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); } Dmsg1(dbglvl, "num plugins=%d\n", dird_plugin_list->size()); dbg_plugin_add_hook(dump_dir_plugin); dbg_print_plugin_add_hook(dump_dir_plugins); } void unload_dir_plugins(void) { unload_plugins(dird_plugin_list); delete dird_plugin_list; dird_plugin_list = NULL; } int list_dir_plugins(POOL_MEM &msg) { return list_plugins(dird_plugin_list, msg); } /** * Check if a plugin is compatible. Called by the load_plugin function * to allow us to verify the plugin. */ static bool is_plugin_compatible(Plugin *plugin) { genpInfo *info = (genpInfo *)plugin->pinfo; Dmsg0(50, "is_plugin_compatible called\n"); if (debug_level >= 50) { dump_dir_plugin(plugin, stdin); } if (!bstrcmp(info->plugin_magic, DIR_PLUGIN_MAGIC)) { Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), plugin->file, DIR_PLUGIN_MAGIC, info->plugin_magic); Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", plugin->file, DIR_PLUGIN_MAGIC, info->plugin_magic); return false; } if (info->version != DIR_PLUGIN_INTERFACE_VERSION) { Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), plugin->file, DIR_PLUGIN_INTERFACE_VERSION, info->version); Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", plugin->file, DIR_PLUGIN_INTERFACE_VERSION, info->version); return false; } if (!bstrcasecmp(info->plugin_license, "Bareos AGPLv3") && !bstrcasecmp(info->plugin_license, "AGPLv3")) { Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), plugin->file, info->plugin_license); Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", plugin->file, info->plugin_license); return false; } if (info->size != sizeof(genpInfo)) { Jmsg(NULL, M_ERROR, 0, _("Plugin size incorrect. Plugin=%s wanted=%d got=%d\n"), plugin->file, sizeof(genpInfo), info->size); return false; } return true; } /* * Instantiate a new plugin instance. */ static inline bpContext *instantiate_plugin(JCR *jcr, Plugin *plugin, uint32_t instance) { bpContext *ctx; b_plugin_ctx *b_ctx; b_ctx = (b_plugin_ctx *)malloc(sizeof(b_plugin_ctx)); memset(b_ctx, 0, sizeof(b_plugin_ctx)); b_ctx->jcr = jcr; Dmsg2(dbglvl, "Instantiate dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); ctx = (bpContext *)malloc(sizeof(bpContext)); ctx->instance = instance; ctx->plugin = plugin; ctx->bContext = (void *)b_ctx; ctx->pContext = NULL; jcr->plugin_ctx_list->append(ctx); if (dirplug_func(plugin)->newPlugin(ctx) != bRC_OK) { b_ctx->disabled = true; } return ctx; } /* * Send a bDirEventNewPluginOptions event to all plugins configured in * jcr->res.Job.DirPluginOptions */ void dispatch_new_plugin_options(JCR *jcr) { int i, j, len; Plugin *plugin; bpContext *ctx; uint32_t instance; bDirEvent event; bDirEventType eventType; char *bp, *plugin_name, *option; const char *plugin_options; POOL_MEM priv_plugin_options(PM_MESSAGE); if (!dird_plugin_list || dird_plugin_list->empty()) { return; } if (jcr->res.job && jcr->res.job->DirPluginOptions && jcr->res.job->DirPluginOptions->size()) { eventType = bDirEventNewPluginOptions; event.eventType = eventType; foreach_alist_index(i, plugin_options, jcr->res.job->DirPluginOptions) { /* * Make a private copy of plugin options. */ pm_strcpy(priv_plugin_options, plugin_options); plugin_name = priv_plugin_options.c_str(); if (!(bp = strchr(plugin_name, ':'))) { Jmsg(NULL, M_ERROR, 0, _("Illegal DIR plugin options encountered, %s skipping\n"), priv_plugin_options.c_str()); continue; } *bp++ = '\0'; /* * See if there is any instance named in the options string. */ instance = 0; option = bp; while (option) { bp = strchr(bp, ':'); if (bp) { *bp++ = '\0'; } if (bstrncasecmp(option, "instance=", 9)) { instance = str_to_int64(option + 9); break; } option = bp; } if (instance < LOWEST_PLUGIN_INSTANCE || instance > HIGHEST_PLUGIN_INSTANCE) { Jmsg(NULL, M_ERROR, 0, _("Illegal DIR plugin options encountered, %s instance %d skipping\n"), plugin_options, instance); continue; } len = strlen(plugin_name); /* * See if this plugin options are for an already instantiated plugin instance. */ foreach_alist(ctx, jcr->plugin_ctx_list) { if (ctx->instance == instance && ctx->plugin->file_len == len && bstrncasecmp(ctx->plugin->file, plugin_name, len)) { break; } } /* * Found a context in the previous loop ? */ if (!ctx) { foreach_alist_index(j, plugin, dird_plugin_list) { if (plugin->file_len == len && bstrncasecmp(plugin->file, plugin_name, len)) { ctx = instantiate_plugin(jcr, plugin, instance); break; } } } if (ctx) { trigger_plugin_event(jcr, eventType, &event, ctx, (void *)plugin_options); } } } } /* * Create a new instance of each plugin for this Job */ void new_plugins(JCR *jcr) { int i, num; Plugin *plugin; Dmsg0(dbglvl, "=== enter new_plugins ===\n"); if (!dird_plugin_list) { Dmsg0(dbglvl, "No dir plugin list!\n"); return; } if (jcr->is_job_canceled()) { return; } num = dird_plugin_list->size(); Dmsg1(dbglvl, "dir-plugin-list size=%d\n", num); if (num == 0) { return; } jcr->plugin_ctx_list = New(alist(10, owned_by_alist)); foreach_alist_index(i, plugin, dird_plugin_list) { /* * Start a new instance of each plugin */ instantiate_plugin(jcr, plugin, 0); } } /* * Free the plugin instances for this Job */ void free_plugins(JCR *jcr) { bpContext *ctx; if (!dird_plugin_list || !jcr->plugin_ctx_list) { return; } Dmsg2(dbglvl, "Free instance dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(ctx, jcr->plugin_ctx_list) { /* * Free the plugin instance */ dirplug_func(ctx->plugin)->freePlugin(ctx); free(ctx->bContext); /* Free BAREOS private context */ } delete jcr->plugin_ctx_list; jcr->plugin_ctx_list = NULL; } /* ============================================================== * * Callbacks from the plugin * * ============================================================== */ static bRC bareosGetValue(bpContext *ctx, brDirVariable var, void *value) { JCR *jcr = NULL; bRC ret = bRC_OK; if (!value) { return bRC_Error; } switch (var) { /* General variables, no need of ctx */ case bDirVarPluginDir: *((char **)value) = me->plugin_directory; Dmsg1(dbglvl, "dir-plugin: return bDirVarPluginDir=%s\n", NPRT(*((char **)value))); break; default: if (!ctx) { return bRC_Error; } jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; if (!jcr) { return bRC_Error; } break; } if (jcr) { switch (var) { case bDirVarJobId: *((int *)value) = jcr->JobId; Dmsg1(dbglvl, "dir-plugin: return bDirVarJobId=%d\n", jcr->JobId); break; case bDirVarJobName: *((char **)value) = jcr->Job; Dmsg1(dbglvl, "dir-plugin: return Job name=%s\n", NPRT(*((char **)value))); break; case bDirVarJob: *((char **)value) = jcr->res.job->hdr.name; Dmsg1(dbglvl, "dir-plugin: return bDirVarJob=%s\n", NPRT(*((char **)value))); break; case bDirVarLevel: *((int *)value) = jcr->getJobLevel(); Dmsg1(dbglvl, "dir-plugin: return bDirVarLevel=%c\n", jcr->getJobLevel()); break; case bDirVarType: *((int *)value) = jcr->getJobType(); Dmsg1(dbglvl, "dir-plugin: return bDirVarType=%c\n", jcr->getJobType()); break; case bDirVarClient: *((char **)value) = jcr->res.client->hdr.name; Dmsg1(dbglvl, "dir-plugin: return bDirVarClient=%s\n", NPRT(*((char **)value))); break; case bDirVarNumVols: POOL_DBR pr; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, jcr->res.pool->hdr.name, sizeof(pr.Name)); if (!db_get_pool_record(jcr, jcr->db, &pr)) { ret = bRC_Error; } *((int *)value) = pr.NumVols; Dmsg1(dbglvl, "dir-plugin: return bDirVarNumVols=%d\n", pr.NumVols); break; case bDirVarPool: *((char **)value) = jcr->res.pool->hdr.name; Dmsg1(dbglvl, "dir-plugin: return bDirVarPool=%s\n", NPRT(*((char **)value))); break; case bDirVarStorage: if (jcr->res.wstore) { *((char **)value) = jcr->res.wstore->hdr.name; } else if (jcr->res.rstore) { *((char **)value) = jcr->res.rstore->hdr.name; } else { *((char **)value) = NULL; ret = bRC_Error; } Dmsg1(dbglvl, "dir-plugin: return bDirVarStorage=%s\n", NPRT(*((char **)value))); break; case bDirVarWriteStorage: if (jcr->res.wstore) { *((char **)value) = jcr->res.wstore->hdr.name; } else { *((char **)value) = NULL; ret = bRC_Error; } Dmsg1(dbglvl, "dir-plugin: return bDirVarWriteStorage=%s\n", NPRT(*((char **)value))); break; case bDirVarReadStorage: if (jcr->res.rstore) { *((char **)value) = jcr->res.rstore->hdr.name; } else { *((char **)value) = NULL; ret = bRC_Error; } Dmsg1(dbglvl, "dir-plugin: return bDirVarReadStorage=%s\n", NPRT(*((char **)value))); break; case bDirVarCatalog: *((char **)value) = jcr->res.catalog->hdr.name; Dmsg1(dbglvl, "dir-plugin: return bDirVarCatalog=%s\n", NPRT(*((char **)value))); break; case bDirVarMediaType: if (jcr->res.wstore) { *((char **)value) = jcr->res.wstore->media_type; } else if (jcr->res.rstore) { *((char **)value) = jcr->res.rstore->media_type; } else { *((char **)value) = NULL; ret = bRC_Error; } Dmsg1(dbglvl, "dir-plugin: return bDirVarMediaType=%s\n", NPRT(*((char **)value))); break; case bDirVarJobStatus: *((int *)value) = jcr->JobStatus; Dmsg1(dbglvl, "dir-plugin: return bDirVarJobStatus=%c\n", jcr->JobStatus); break; case bDirVarPriority: *((int *)value) = jcr->JobPriority; Dmsg1(dbglvl, "dir-plugin: return bDirVarPriority=%d\n", jcr->JobPriority); break; case bDirVarVolumeName: *((char **)value) = jcr->VolumeName; Dmsg1(dbglvl, "dir-plugin: return bDirVarVolumeName=%s\n", NPRT(*((char **)value))); break; case bDirVarCatalogRes: ret = bRC_Error; break; case bDirVarJobErrors: *((int *)value) = jcr->JobErrors; Dmsg1(dbglvl, "dir-plugin: return bDirVarErrors=%d\n", jcr->JobErrors); break; case bDirVarJobFiles: *((int *)value) = jcr->JobFiles; Dmsg1(dbglvl, "dir-plugin: return bDirVarFiles=%d\n", jcr->JobFiles); break; case bDirVarSDJobFiles: *((int *)value) = jcr->SDJobFiles; Dmsg1(dbglvl, "dir-plugin: return bDirVarSDFiles=%d\n", jcr->SDJobFiles); break; case bDirVarSDErrors: *((int *)value) = jcr->SDErrors; Dmsg1(dbglvl, "dir-plugin: return bDirVarSDErrors=%d\n", jcr->SDErrors); break; case bDirVarFDJobStatus: *((int *)value) = jcr->FDJobStatus; Dmsg1(dbglvl, "dir-plugin: return bDirVarFDJobStatus=%c\n", jcr->FDJobStatus); break; case bDirVarSDJobStatus: *((int *)value) = jcr->SDJobStatus; Dmsg1(dbglvl, "dir-plugin: return bDirVarSDJobStatus=%c\n", jcr->SDJobStatus); break; case bDirVarLastRate: *((int *)value) = jcr->LastRate; Dmsg1(dbglvl, "dir-plugin: return bDirVarLastRate=%d\n", jcr->LastRate); break; case bDirVarJobBytes: *((uint64_t *)value) = jcr->JobBytes; Dmsg1(dbglvl, "dir-plugin: return bDirVarJobBytes=%u\n", jcr->JobBytes); break; case bDirVarReadBytes: *((uint64_t *)value) = jcr->ReadBytes; Dmsg1(dbglvl, "dir-plugin: return bDirVarReadBytes=%u\n", jcr->ReadBytes); break; default: break; } } return ret; } static bRC bareosSetValue(bpContext *ctx, bwDirVariable var, void *value) { JCR *jcr; if (!value || !ctx) { return bRC_Error; } jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; if (!jcr) { return bRC_Error; } Dmsg1(dbglvl, "dir-plugin: bareosSetValue var=%d\n", var); switch (var) { case bwDirVarVolumeName: pm_strcpy(jcr->VolumeName, ((char *)value)); break; case bwDirVarPriority: jcr->JobPriority = *((int *)value); break; case bwDirVarJobLevel: jcr->setJobLevel(*((int *)value)); break; default: break; } return bRC_OK; } static bRC bareosRegisterEvents(bpContext *ctx, int nr_events, ...) { int i; va_list args; uint32_t event; b_plugin_ctx *b_ctx; if (!ctx) { return bRC_Error; } b_ctx = (b_plugin_ctx *)ctx->bContext; va_start(args, nr_events); for (i = 0; i < nr_events; i++) { event = va_arg(args, uint32_t); Dmsg1(dbglvl, "dir-Plugin wants event=%u\n", event); set_bit(event, b_ctx->events); } va_end(args); return bRC_OK; } static bRC bareosJobMsg(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...) { JCR *jcr; va_list arg_ptr; POOL_MEM buffer(PM_MESSAGE); if (ctx) { jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; } else { jcr = NULL; } va_start(arg_ptr, fmt); buffer.bvsprintf(fmt, arg_ptr); va_end(arg_ptr); Jmsg(jcr, type, mtime, "%s", buffer.c_str()); return bRC_OK; } static bRC bareosDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...) { va_list arg_ptr; POOL_MEM buffer(PM_MESSAGE); va_start(arg_ptr, fmt); buffer.bvsprintf(fmt, arg_ptr); va_end(arg_ptr); d_msg(file, line, level, "%s", buffer.c_str()); return bRC_OK; } #ifdef TEST_PROGRAM bool db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr) { return true; } int main(int argc, char *argv[]) { char plugin_dir[1000]; JCR mjcr1, mjcr2; JCR *jcr1 = &mjcr1; JCR *jcr2 = &mjcr2; my_name_is(argc, argv, "plugtest"); init_msg(NULL, NULL); OSDependentInit(); if (argc != 1) { bstrncpy(plugin_dir, argv[1], sizeof(plugin_dir)); } else { getcwd(plugin_dir, sizeof(plugin_dir)-1); } load_dir_plugins(plugin_dir, NULL); jcr1->JobId = 111; new_plugins(jcr1); jcr2->JobId = 222; new_plugins(jcr2); generate_plugin_event(jcr1, bDirEventJobStart, (void *)"Start Job 1"); generate_plugin_event(jcr1, bDirEventJobEnd); generate_plugin_event(jcr2, bDirEventJobStart, (void *)"Start Job 1"); free_plugins(jcr1); generate_plugin_event(jcr2, bDirEventJobEnd); free_plugins(jcr2); unload_dir_plugins(); term_msg(); close_memory_pool(); lmgr_cleanup_main(); sm_dump(false); exit(0); } #endif /* TEST_PROGRAM */ bareos-Release-14.2.6/src/dird/dir_plugins.h000066400000000000000000000127251263011562700206500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Interface definition for Bareos DIR Plugins * * Kern Sibbald, October 2007 */ #ifndef __DIR_PLUGINS_H #define __DIR_PLUGINS_H #ifndef _BAREOS_H #ifdef __cplusplus /* Workaround for SGI IRIX 6.5 */ #define _LANGUAGE_C_PLUS_PLUS 1 #endif #define _REENTRANT 1 #define _THREAD_SAFE 1 #define _POSIX_PTHREAD_SEMANTICS 1 #define _FILE_OFFSET_BITS 64 #define _LARGEFILE_SOURCE 1 #define _LARGE_FILES 1 #endif #include #include "hostconfig.h" #include "bc_types.h" #include "lib/plugins.h" /**************************************************************************** * * * Bareos definitions * * * ****************************************************************************/ /* * Bareos Variable Ids (Read) */ typedef enum { bDirVarJob = 1, bDirVarLevel = 2, bDirVarType = 3, bDirVarJobId = 4, bDirVarClient = 5, bDirVarNumVols = 6, bDirVarPool = 7, bDirVarStorage = 8, bDirVarWriteStorage = 9, bDirVarReadStorage = 10, bDirVarCatalog = 11, bDirVarMediaType = 12, bDirVarJobName = 13, bDirVarJobStatus = 14, bDirVarPriority = 15, bDirVarVolumeName = 16, bDirVarCatalogRes = 17, bDirVarJobErrors = 18, bDirVarJobFiles = 19, bDirVarSDJobFiles = 20, bDirVarSDErrors = 21, bDirVarFDJobStatus = 22, bDirVarSDJobStatus = 23, bDirVarPluginDir = 24, bDirVarLastRate = 25, bDirVarJobBytes = 26, bDirVarReadBytes = 27 } brDirVariable; /* * Bareos Variable Ids (Write) */ typedef enum { bwDirVarJobReport = 1, bwDirVarVolumeName = 2, bwDirVarPriority = 3, bwDirVarJobLevel = 4 } bwDirVariable; /* * Events that are passed to plugin */ typedef enum { bDirEventJobStart = 1, bDirEventJobEnd = 2, bDirEventJobInit = 3, bDirEventJobRun = 4, bDirEventVolumePurged = 5, bDirEventNewVolume = 6, bDirEventNeedVolume = 7, bDirEventVolumeFull = 8, bDirEventRecyle = 9, bDirEventGetScratch = 10, bDirEventNewPluginOptions = 11 } bDirEventType; #define DIR_NR_EVENTS bDirEventNewPluginOptions /* keep this updated ! */ typedef struct s_bDirEvent { uint32_t eventType; } bDirEvent; typedef struct s_dirbareosInfo { uint32_t size; uint32_t version; } bDirInfo; #ifdef __cplusplus extern "C" { #endif /* * Bareos interface version and function pointers */ typedef struct s_dirbareosFuncs { uint32_t size; uint32_t version; bRC (*registerBareosEvents)(bpContext *ctx, int nr_events, ...); bRC (*getBareosValue)(bpContext *ctx, brDirVariable var, void *value); bRC (*setBareosValue)(bpContext *ctx, bwDirVariable var, void *value); bRC (*JobMessage)(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); bRC (*DebugMessage)(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); } bDirFuncs; /* * Bareos Core Routines -- not used within a plugin */ #ifdef DIRECTOR_DAEMON void load_dir_plugins(const char *plugin_dir, alist *plugin_names); void unload_dir_plugins(void); int list_dir_plugins(POOL_MEM &msg); void dispatch_new_plugin_options(JCR *jcr); void new_plugins(JCR *jcr); void free_plugins(JCR *jcr); int generate_plugin_event(JCR *jcr, bDirEventType event, void *value = NULL, bool reverse = false); #endif /**************************************************************************** * * * Plugin definitions * * * ****************************************************************************/ typedef enum { pDirVarName = 1, pDirVarDescription = 2 } pDirVariable; #define DIR_PLUGIN_MAGIC "*DirPluginData*" #define DIR_PLUGIN_INTERFACE_VERSION 3 typedef struct s_dirpluginFuncs { uint32_t size; uint32_t version; bRC (*newPlugin)(bpContext *ctx); bRC (*freePlugin)(bpContext *ctx); bRC (*getPluginValue)(bpContext *ctx, pDirVariable var, void *value); bRC (*setPluginValue)(bpContext *ctx, pDirVariable var, void *value); bRC (*handlePluginEvent)(bpContext *ctx, bDirEvent *event, void *value); } pDirFuncs; #define dirplug_func(plugin) ((pDirFuncs *)(plugin->pfuncs)) #define dirplug_info(plugin) ((genpInfo *)(plugin->pinfo)) #ifdef __cplusplus } #endif #endif /* __FD_PLUGINS_H */ bareos-Release-14.2.6/src/dird/dird.c000066400000000000000000001137671263011562700172560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director daemon -- this is the main program * * Kern Sibbald, March MM */ #include "bareos.h" #include "dird.h" #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif #ifdef HAVE_DIRENT_H #include #define NAMELEN(dirent) (strlen((dirent)->d_name)) #endif #ifndef HAVE_READDIR_R int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #endif /* Forward referenced subroutines */ #if !defined(HAVE_WIN32) static #endif void terminate_dird(int sig); static bool check_resources(); static bool initialize_sql_pooling(void); static void cleanup_old_files(); /* Exported subroutines */ extern "C" void reload_config(int sig); extern void invalidate_schedules(); extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code); /* Imported subroutines */ void start_UA_server(dlist *addrs); void stop_UA_server(void); void init_job_server(int max_workers); void term_job_server(); void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass); void store_protocoltype(LEX *lc, RES_ITEM *item, int index, int pass); void store_level(LEX *lc, RES_ITEM *item, int index, int pass); void store_replace(LEX *lc, RES_ITEM *item, int index, int pass); void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass); void init_device_resources(); static char *runjob = NULL; static bool background = true; static bool test_config = false; static void init_reload(void); /* Globals Exported */ DIRRES *me = NULL; /* Our Global resource */ CONFIG *my_config = NULL; /* Our Global config */ char *configfile = NULL; void *start_heap; /* Globals Imported */ extern RES_ITEM job_items[]; typedef enum { CHECK_CONNECTION, /* Check catalog connection */ UPDATE_CATALOG, /* Ensure that catalog is ok with conf */ UPDATE_AND_FIX /* Ensure that catalog is ok, and fix old jobs */ } cat_op; static bool check_catalog(cat_op mode); #define CONFIG_FILE "bareos-dir.conf" /* default configuration file */ /* * This allows the message handler to operate on the database by using a pointer * to this function. The pointer is needed because the other daemons do not have * access to the database. If the pointer is not defined (other daemons), then * writing the database is disabled. */ static bool dir_db_log_insert(JCR *jcr, utime_t mtime, char *msg) { int length; char ed1[50]; char dt[MAX_TIME_LENGTH]; POOL_MEM query(PM_MESSAGE), esc_msg(PM_MESSAGE); if (!jcr || !jcr->db || !jcr->db->is_connected()) { return false; } length = strlen(msg); esc_msg.check_size(length * 2 + 1); db_escape_string(jcr, jcr->db, esc_msg.c_str(), msg, length); bstrutime(dt, sizeof(dt), mtime); Mmsg(query, "INSERT INTO Log (JobId, Time, LogText) VALUES (%s,'%s','%s')", edit_int64(jcr->JobId, ed1), dt, esc_msg.c_str()); return db_sql_query(jcr->db, query.c_str()); } static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bareos-dir [-f -s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -m print kaboom output (for debugging)\n" " -r run now\n" " -s no signals\n" " -t test - read configuration and exit\n" " -u userid\n" " -v verbose user messages\n" " -x print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n"), 2000, VERSION, BDATE); exit(1); } /********************************************************************* * * Main BAREOS Director Server program * */ #if defined(HAVE_WIN32) #define main BareosMain #endif int main (int argc, char *argv[]) { int ch; JCR *jcr; cat_op mode; bool no_signals = false; bool export_config_schema = false; char *uid = NULL; char *gid = NULL; start_heap = sbrk(0); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "bareos-dir"); init_msg(NULL, NULL); /* initialize message handler */ init_reload(); daemon_start_time = time(NULL); console_command = run_console_command; while ((ch = getopt(argc, argv, "c:d:fg:mr:stu:vx?")) != -1) { switch (ch) { case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } Dmsg1(10, "Debug level = %d\n", debug_level); break; case 'f': /* run in foreground */ background = false; break; case 'g': /* set group id */ gid = optarg; break; case 'm': /* print kaboom output */ prt_kaboom = true; break; case 'r': /* run job */ if (runjob != NULL) { free(runjob); } if (optarg) { runjob = bstrdup(optarg); } break; case 's': /* turn off signals */ no_signals = true; break; case 't': /* test config */ test_config = true; break; case 'u': /* set uid */ uid = optarg; break; case 'v': /* verbose */ verbose++; break; case 'x': /* export configuration file schema (json) and exit */ export_config_schema = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (!no_signals) { init_signals(terminate_dird); } if (argc) { if (configfile != NULL) { free(configfile); } configfile = bstrdup(*argv); argc--; argv++; } if (argc) { usage(); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } /* * See if we want to drop privs. */ if (geteuid() == 0) { drop(uid, gid, false); /* reduce privileges if requested */ } if (export_config_schema) { my_config = new_config_parser(); init_dir_config(my_config, configfile, M_ERROR_TERM); POOL_MEM buffer; print_config_schema_json(buffer); printf( "%s\n", buffer.c_str() ); goto bail_out; } my_config = new_config_parser(); parse_dir_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n")); goto bail_out; } if (!check_resources()) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); goto bail_out; } if (!test_config) { /* we don't need to do this block in test mode */ if (background) { daemon_start(); init_stack_dump(); /* grab new pid */ } /* Create pid must come after we are a daemon -- so we have our final pid */ create_pid_file(me->pid_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); read_state_file(me->working_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); } set_jcr_in_tsd(INVALID_JCR); set_thread_concurrency(me->MaxConcurrentJobs * 2 + 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */); lmgr_init_thread(); /* initialize the lockmanager stack */ #if defined(HAVE_DYNAMIC_CATS_BACKENDS) char *backend_dir; foreach_alist(backend_dir, me->backend_directories) { Dmsg1(100, "backend path: %s\n", backend_dir); } db_set_backend_dirs(me->backend_directories); #endif load_dir_plugins(me->plugin_directory, me->plugin_names); /* * If we are in testing mode, we don't try to fix the catalog */ mode = (test_config) ? CHECK_CONNECTION : UPDATE_AND_FIX; if (!check_catalog(mode)) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); goto bail_out; } if (test_config) { terminate_dird(0); } if (!initialize_sql_pooling()) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); goto bail_out; } my_name_is(0, NULL, me->name()); /* set user defined name */ cleanup_old_files(); p_db_log_insert = (db_log_insert_func)dir_db_log_insert; #if !defined(HAVE_WIN32) signal(SIGHUP, reload_config); #endif init_console_msg(working_directory); Dmsg0(200, "Start UA server\n"); start_UA_server(me->DIRaddrs); start_watchdog(); /* start network watchdog thread */ if (me->jcr_watchdog_time) { init_jcr_subsystem(me->jcr_watchdog_time); /* start JCR watchdogs etc. */ } init_job_server(me->MaxConcurrentJobs); dbg_jcr_add_hook(db_debug_print); /* used to debug B_DB connexion after fatal signal */ // init_device_resources(); start_statistics_thread(); Dmsg0(200, "wait for next job\n"); /* Main loop -- call scheduler to get next job to run */ while ((jcr = wait_for_next_job(runjob))) { run_job(jcr); /* run job */ free_jcr(jcr); /* release jcr */ set_jcr_in_tsd(INVALID_JCR); if (runjob) { /* command line, run a single job? */ break; /* yes, terminate */ } } terminate_dird(0); bail_out: return 0; } /* Cleanup and then exit */ #if !defined(HAVE_WIN32) static #endif void terminate_dird(int sig) { static bool already_here = false; if (already_here) { /* avoid recursive temination problems */ bmicrosleep(2, 0); /* yield */ exit(1); } already_here = true; debug_level = 0; /* turn off debug */ stop_statistics_thread(); stop_watchdog(); db_sql_pool_destroy(); db_flush_backends(); unload_dir_plugins(); if (!test_config) { /* we don't need to do this block in test mode */ write_state_file(me->working_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); delete_pid_file(me->pid_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); } term_scheduler(); term_job_server(); if (runjob) { free(runjob); } if (configfile != NULL) { free(configfile); } if (debug_level > 5) { print_memory_pool_stats(); } if (my_config) { my_config->free_resources(); free(my_config); my_config = NULL; } stop_UA_server(); term_msg(); /* terminate message handler */ cleanup_crypto(); close_memory_pool(); /* release free memory in pool */ lmgr_cleanup_main(); sm_dump(false); exit(sig); } struct RELOAD_TABLE { int job_count; RES **res_table; }; static const int max_reloads = 32; static RELOAD_TABLE reload_table[max_reloads]; static void init_reload(void) { for (int i=0; i < max_reloads; i++) { reload_table[i].job_count = 0; reload_table[i].res_table = NULL; } } static void free_saved_resources(int table) { int num = my_config->m_r_last - my_config->m_r_first + 1; RES **res_tab = reload_table[table].res_table; if (!res_tab) { Dmsg1(100, "res_tab for table %d already released.\n", table); return; } Dmsg1(100, "Freeing resources for table %d\n", table); for (int j=0; jm_r_first + j); } free(res_tab); reload_table[table].job_count = 0; reload_table[table].res_table = NULL; } /* * Called here at the end of every job that was * hooked decrementing the active job_count. When * it goes to zero, no one is using the associated * resource table, so free it. */ static void reload_job_end_cb(JCR *jcr, void *ctx) { int reload_id = (int)((intptr_t)ctx); Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId, reload_id, reload_table[reload_id].job_count); lock_jobs(); LockRes(); if (--reload_table[reload_id].job_count <= 0) { free_saved_resources(reload_id); } UnlockRes(); unlock_jobs(); } static int find_free_reload_table_entry() { int table = -1; for (int i=0; i < max_reloads; i++) { if (reload_table[i].res_table == NULL) { table = i; break; } } return table; } /* * If we get here, we have received a SIGHUP, which means to * reread our configuration file. * * The algorithm used is as follows: we count how many jobs are * running and mark the running jobs to make a callback on * exiting. The old config is saved with the reload table * id in a reload table. The new config file is read. Now, as * each job exits, it calls back to the reload_job_end_cb(), which * decrements the count of open jobs for the given reload table. * When the count goes to zero, we release those resources. * This allows us to have pointers into the resource table (from * jobs), and once they exit and all the pointers are released, we * release the old table. Note, if no new jobs are running since the * last reload, then the old resources will be immediately release. * A console is considered a job because it may have pointers to * resources, but a SYSTEM job is not since it *should* not have any * permanent pointers to jobs. */ extern "C" void reload_config(int sig) { static bool already_here = false; #if !defined(HAVE_WIN32) sigset_t set; #endif JCR *jcr; int njobs = 0; /* number of running jobs */ int table, rtable; bool ok; if (already_here) { abort(); /* Oops, recursion -> die */ } already_here = true; #if !defined(HAVE_WIN32) sigemptyset(&set); sigaddset(&set, SIGHUP); sigprocmask(SIG_BLOCK, &set, NULL); #endif lock_jobs(); LockRes(); table = find_free_reload_table_entry(); if (table < 0) { Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n")); goto bail_out; } /** * Flush the sql connection pools. */ db_sql_pool_flush(); Dmsg1(100, "Reload_config njobs=%d\n", njobs); reload_table[table].res_table = my_config->save_resources(); Dmsg1(100, "Saved old config in table %d\n", table); ok = parse_dir_config(my_config, configfile, M_ERROR); Dmsg0(100, "Reloaded config file\n"); if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG) || !initialize_sql_pooling()) { rtable = find_free_reload_table_entry(); /* save new, bad table */ if (rtable < 0) { Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n")); goto bail_out; } else { Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n")); } reload_table[rtable].res_table = my_config->save_resources(); /* Now restore old resource values */ int num = my_config->m_r_last - my_config->m_r_first + 1; RES **res_tab = reload_table[table].res_table; for (int i=0; im_res_head[i] = res_tab[i]; } table = rtable; /* release new, bad, saved table below */ } else { invalidate_schedules(); /* * Hook all active jobs so that they release this table */ foreach_jcr(jcr) { if (jcr->getJobType() != JT_SYSTEM) { reload_table[table].job_count++; job_end_push(jcr, reload_job_end_cb, (void *)((long int)table)); njobs++; } } endeach_jcr(jcr); } /* Reset globals */ set_working_directory(me->working_directory); Dmsg0(10, "Director's configuration file reread.\n"); /* Now release saved resources, if no jobs using the resources */ if (njobs == 0) { free_saved_resources(table); } bail_out: UnlockRes(); unlock_jobs(); #if !defined(HAVE_WIN32) sigprocmask(SIG_UNBLOCK, &set, NULL); signal(SIGHUP, reload_config); #endif already_here = false; } /* * See if two storage definitions point to the same Storage Daemon. * * We compare: * - address * - SDport * - password */ static inline bool is_same_storage_daemon(STORERES *store1, STORERES *store2) { return store1->SDport == store2->SDport && bstrcasecmp(store1->address, store2->address) && bstrcasecmp(store1->password.value, store2->password.value); } /* * Make a quick check to see that we have all the * resources needed. * * **** FIXME **** this routine could be a lot more * intelligent and comprehensive. */ static bool check_resources() { bool OK = true; JOBRES *job; bool need_tls; LockRes(); job = (JOBRES *)GetNextRes(R_JOB, NULL); me = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); if (!me) { Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n" "Without that I don't know who I am :-(\n"), configfile); OK = false; goto bail_out; } else { my_config->m_omit_defaults = me->omit_defaults; set_working_directory(me->working_directory); if (!me->messages) { /* If message resource not specified */ me->messages = (MSGSRES *)GetNextRes(R_MSGS, NULL); if (!me->messages) { Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile); OK = false; goto bail_out; } } /* * When the user didn't force us we optimize for size. */ if (!me->optimize_for_size && !me->optimize_for_speed) { me->optimize_for_size = true; } else if (me->optimize_for_size && me->optimize_for_speed) { Jmsg(NULL, M_FATAL, 0, _("Cannot optimize for speed and size define only one in %s\n"), configfile); OK = false; goto bail_out; } if (GetNextRes(R_DIRECTOR, (RES *)me) != NULL) { Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"), configfile); OK = false; goto bail_out; } /* * tls_require implies tls_enable */ if (me->tls_require) { if (have_tls) { me->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in BAREOS.\n")); OK = false; goto bail_out; } } need_tls = me->tls_enable || me->tls_authenticate; if (!me->tls_certfile && need_tls) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"), me->name(), configfile); OK = false; goto bail_out; } if (!me->tls_keyfile && need_tls) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"), me->name(), configfile); OK = false; goto bail_out; } if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls && me->tls_verify_peer) { Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA" " Certificate Dir\" are defined for Director \"%s\" in %s." " At least one CA certificate store is required" " when using \"TLS Verify Peer\".\n"), me->name(), configfile); OK = false; goto bail_out; } /* * If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (need_tls || me->tls_require)) { /* * Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ me->tls_ctx = new_tls_context(me->tls_ca_certfile, me->tls_ca_certdir, me->tls_crlfile, me->tls_certfile, me->tls_keyfile, NULL, NULL, me->tls_dhfile, me->tls_verify_peer); if (!me->tls_ctx) { Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"), me->name(), configfile); OK = false; goto bail_out; } } } if (!job) { Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile); OK = false; goto bail_out; } if (!populate_jobdefs()) { OK = false; goto bail_out; } /* * Loop over Consoles */ CONRES *cons; foreach_res(cons, R_CONSOLE) { /* * tls_require implies tls_enable */ if (cons->tls_require) { if (have_tls) { cons->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in BAREOS.\n")); OK = false; goto bail_out; } } need_tls = cons->tls_enable || cons->tls_authenticate; if (!cons->tls_certfile && need_tls) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"), cons->name(), configfile); OK = false; goto bail_out; } if (!cons->tls_keyfile && need_tls) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Console \"%s\" in %s.\n"), cons->name(), configfile); OK = false; goto bail_out; } if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && need_tls && cons->tls_verify_peer) { Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\" or \"TLS CA" " Certificate Dir\" are defined for Console \"%s\" in %s." " At least one CA certificate store is required" " when using \"TLS Verify Peer\".\n"), cons->name(), configfile); OK = false; goto bail_out; } /* * If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (need_tls || cons->tls_require)) { /* * Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ cons->tls_ctx = new_tls_context(cons->tls_ca_certfile, cons->tls_ca_certdir, cons->tls_crlfile, cons->tls_certfile, cons->tls_keyfile, NULL, NULL, cons->tls_dhfile, cons->tls_verify_peer); if (!cons->tls_ctx) { Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"), cons->name(), configfile); OK = false; goto bail_out; } } } /* * Loop over Clients */ me->subscriptions_used = 0; CLIENTRES *client; foreach_res(client, R_CLIENT) { /* * Count the number of clients * * Only used as indication not an enforced limit. */ me->subscriptions_used++; /* * tls_require implies tls_enable */ if (client->tls_require) { if (have_tls) { client->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in BAREOS.\n")); OK = false; goto bail_out; } } need_tls = client->tls_enable || client->tls_authenticate; if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && need_tls) { Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for File daemon \"%s\" in %s.\n"), client->name(), configfile); OK = false; goto bail_out; } /* * If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (need_tls || client->tls_require)) { /* * Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ client->tls_ctx = new_tls_context(client->tls_ca_certfile, client->tls_ca_certdir, client->tls_crlfile, client->tls_certfile, client->tls_keyfile, NULL, NULL, NULL, true); if (!client->tls_ctx) { Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"), client->name(), configfile); OK = false; goto bail_out; } } } /* * Loop over Storages */ STORERES *store, *nstore; foreach_res(store, R_STORAGE) { /* * tls_require implies tls_enable */ if (store->tls_require) { if (have_tls) { store->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in BAREOS.\n")); OK = false; goto bail_out; } } need_tls = store->tls_enable || store->tls_authenticate; if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && need_tls) { Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s.\n"), store->name(), configfile); OK = false; goto bail_out; } /* * If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (need_tls || store->tls_require)) { /* * Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ store->tls_ctx = new_tls_context(store->tls_ca_certfile, store->tls_ca_certdir, store->tls_crlfile, store->tls_certfile, store->tls_keyfile, NULL, NULL, NULL, true); if (!store->tls_ctx) { Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"), store->name(), configfile); OK = false; goto bail_out; } } /* * If we collect statistics on this SD make sure any other entry pointing to the same SD does not * collect statistics otherwise we collect the same data multiple times. */ if (store->collectstats) { nstore = store; while ((nstore = (STORERES *)GetNextRes(R_STORAGE, (RES *)nstore))) { if (is_same_storage_daemon(store, nstore) && nstore->collectstats) { nstore->collectstats = false; Dmsg1(200, _("Disabling collectstats for storage \"%s\"" " as other storage already collects from this SD.\n"), nstore->name()); } } } } UnlockRes(); if (OK) { close_msg(NULL); /* close temp message handler */ init_msg(NULL, me->messages); /* open daemon message handler */ } bail_out: return OK; } /* * Initialize the sql pooling. */ static bool initialize_sql_pooling(void) { bool retval = true; CATRES *catalog; foreach_res(catalog, R_CATALOG) { if (!db_sql_pool_initialize(catalog->db_driver, catalog->db_name, catalog->db_user, catalog->db_password.value, catalog->db_address, catalog->db_port, catalog->db_socket, catalog->disable_batch_insert, catalog->pooling_min_connections, catalog->pooling_max_connections, catalog->pooling_increment_connections, catalog->pooling_idle_timeout, catalog->pooling_validate_timeout)) { Jmsg(NULL, M_FATAL, 0, _("Could not setup sql pooling for Catalog \"%s\", database \"%s\".\n"), catalog->name(), catalog->db_name); retval = false; goto bail_out; } } bail_out: return retval; } /* * In this routine, * - we can check the connection (mode=CHECK_CONNECTION) * - we can synchronize the catalog with the configuration (mode=UPDATE_CATALOG) * - we can synchronize, and fix old job records (mode=UPDATE_AND_FIX) */ static bool check_catalog(cat_op mode) { bool OK = true; /* Loop over databases */ CATRES *catalog; foreach_res(catalog, R_CATALOG) { B_DB *db; /* * Make sure we can open catalog, otherwise print a warning * message because the server is probably not running. */ db = db_init_database(NULL, catalog->db_driver, catalog->db_name, catalog->db_user, catalog->db_password.value, catalog->db_address, catalog->db_port, catalog->db_socket, catalog->mult_db_connections, catalog->disable_batch_insert); if (!db || !db_open_database(NULL, db)) { Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"), catalog->name(), catalog->db_name); Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"), catalog->name(), catalog->db_name); if (db) { Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db)); Pmsg1(000, "%s", db_strerror(db)); db_close_database(NULL, db); } OK = false; goto bail_out; } /* Display a message if the db max_connections is too low */ if (!db_check_max_connections(NULL, db, me->MaxConcurrentJobs)) { Pmsg1(000, "Warning, settings problem for Catalog=%s\n", catalog->name()); Pmsg1(000, "%s", db_strerror(db)); } /* we are in testing mode, so don't touch anything in the catalog */ if (mode == CHECK_CONNECTION) { db_close_database(NULL, db); continue; } /* Loop over all pools, defining/updating them in each database */ POOLRES *pool; foreach_res(pool, R_POOL) { /* * If the Pool has a catalog resource create the pool only * in that catalog. */ if (!pool->catalog || pool->catalog == catalog) { create_pool(NULL, db, pool, POOL_OP_UPDATE); /* update request */ } } /* Once they are created, we can loop over them again, updating * references (RecyclePool) */ foreach_res(pool, R_POOL) { /* * If the Pool has a catalog resource update the pool only * in that catalog. */ if (!pool->catalog || pool->catalog == catalog) { update_pool_references(NULL, db, pool); } } /* Ensure basic client record is in DB */ CLIENTRES *client; foreach_res(client, R_CLIENT) { CLIENT_DBR cr; /* Create clients only if they use the current catalog */ if (client->catalog != catalog) { Dmsg3(500, "Skip client=%s with cat=%s not catalog=%s\n", client->name(), client->catalog->name(), catalog->name()); continue; } Dmsg2(500, "create cat=%s for client=%s\n", client->catalog->name(), client->name()); memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); db_create_client_record(NULL, db, &cr); } /* Ensure basic storage record is in DB */ STORERES *store; foreach_res(store, R_STORAGE) { STORAGE_DBR sr; MEDIATYPE_DBR mtr; memset(&sr, 0, sizeof(sr)); memset(&mtr, 0, sizeof(mtr)); if (store->media_type) { bstrncpy(mtr.MediaType, store->media_type, sizeof(mtr.MediaType)); mtr.ReadOnly = 0; db_create_mediatype_record(NULL, db, &mtr); } else { mtr.MediaTypeId = 0; } bstrncpy(sr.Name, store->name(), sizeof(sr.Name)); sr.AutoChanger = store->autochanger; if (!db_create_storage_record(NULL, db, &sr)) { Jmsg(NULL, M_FATAL, 0, _("Could not create storage record for %s\n"), store->name()); OK = false; goto bail_out; } store->StorageId = sr.StorageId; /* set storage Id */ if (!sr.created) { /* if not created, update it */ sr.AutoChanger = store->autochanger; if (!db_update_storage_record(NULL, db, &sr)) { Jmsg(NULL, M_FATAL, 0, _("Could not update storage record for %s\n"), store->name()); OK = false; goto bail_out; } } } /* Loop over all counters, defining them in each database */ /* Set default value in all counters */ COUNTERRES *counter; foreach_res(counter, R_COUNTER) { /* Write to catalog? */ if (!counter->created && counter->Catalog == catalog) { COUNTER_DBR cr; bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter)); cr.MinValue = counter->MinValue; cr.MaxValue = counter->MaxValue; cr.CurrentValue = counter->MinValue; if (counter->WrapCounter) { bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter)); } else { cr.WrapCounter[0] = 0; /* empty string */ } if (db_create_counter_record(NULL, db, &cr)) { counter->CurrentValue = cr.CurrentValue; counter->created = true; Dmsg2(100, "Create counter %s val=%d\n", counter->name(), counter->CurrentValue); } } if (!counter->created) { counter->CurrentValue = counter->MinValue; /* default value */ } } /* cleanup old job records */ if (mode == UPDATE_AND_FIX) { db_sql_query(db, cleanup_created_job); db_sql_query(db, cleanup_running_job); } /* Set type in global for debugging */ set_db_type(db_get_type(db)); db_close_database(NULL, db); } bail_out: return OK; } static void cleanup_old_files() { DIR* dp; struct dirent *entry, *result; int rc, name_max; int my_name_len = strlen(my_name); int len = strlen(me->working_directory); POOLMEM *cleanup = get_pool_memory(PM_MESSAGE); POOLMEM *basename = get_pool_memory(PM_MESSAGE); regex_t preg1; char prbuf[500]; berrno be; /* Exclude spaces and look for .mail or .restore.xx.bsr files */ const char *pat1 = "^[^ ]+\\.(restore\\.[^ ]+\\.bsr|mail)$"; /* Setup working directory prefix */ pm_strcpy(basename, me->working_directory); if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) { pm_strcat(basename, "/"); } /* Compile regex expressions */ rc = regcomp(&preg1, pat1, REG_EXTENDED); if (rc != 0) { regerror(rc, &preg1, prbuf, sizeof(prbuf)); Pmsg2(000, _("Could not compile regex pattern \"%s\" ERR=%s\n"), pat1, prbuf); goto get_out2; } name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (!(dp = opendir(me->working_directory))) { berrno be; Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n", me->working_directory, be.bstrerror()); goto get_out1; return; } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); while (1) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { break; } /* Exclude any name with ., .., not my_name or containing a space */ if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 || strncmp(result->d_name, my_name, my_name_len) != 0) { Dmsg1(500, "Skipped: %s\n", result->d_name); continue; } /* Unlink files that match regexes */ if (regexec(&preg1, result->d_name, 0, NULL, 0) == 0) { pm_strcpy(cleanup, basename); pm_strcat(cleanup, result->d_name); Dmsg1(100, "Unlink: %s\n", cleanup); unlink(cleanup); } } free(entry); closedir(dp); /* Be careful to free up the correct resources */ get_out1: regfree(&preg1); get_out2: free_pool_memory(cleanup); free_pool_memory(basename); } bareos-Release-14.2.6/src/dird/dird.h000066400000000000000000000067431263011562700172560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Includes specific to the Director * * Kern Sibbald, December MM */ #include "lib/runscript.h" #include "lib/breg.h" #include "lib/bsr.h" #include "dird_conf.h" #define DIRECTOR_DAEMON 1 #include "dir_plugins.h" #include "cats/cats.h" #include "cats/sql_glue.h" #include "jcr.h" #include "bsr.h" #include "ua.h" #include "jobq.h" /* Globals that dird.c exports */ extern DIRRES *me; /* Our Global resource */ extern CONFIG *my_config; /* Our Global config */ /* Used in ua_prune.c and ua_purge.c */ struct s_count_ctx { int count; }; #define MAX_DEL_LIST_LEN 2000000 struct del_ctx { JobId_t *JobId; /* array of JobIds */ char *PurgedFiles; /* Array of PurgedFile flags */ int num_ids; /* ids stored */ int max_ids; /* size of array */ int num_del; /* number deleted */ int tot_ids; /* total to process */ }; /* Flags for find_next_volume_for_append() */ enum { fnv_create_vol = true, fnv_no_create_vol = false, fnv_prune = true, fnv_no_prune = false }; enum e_enabled_val { VOL_NOT_ENABLED = 0, VOL_ENABLED = 1, VOL_ARCHIVED = 2 }; enum e_prtmsg { DISPLAY_ERROR, NO_DISPLAY }; enum e_pool_op { POOL_OP_UPDATE, POOL_OP_CREATE }; enum e_move_op { VOLUME_IMPORT, VOLUME_EXPORT, VOLUME_MOVE }; typedef enum { slot_type_unknown, /* unknown slot type */ slot_type_drive, /* drive slot */ slot_type_normal, /* normal slot */ slot_type_import /* import/export slot */ } slot_type; typedef enum { slot_content_unknown, /* slot content is unknown */ slot_content_empty, /* slot is empty */ slot_content_full /* slot is full */ } slot_content; /* Slot list definition */ typedef struct s_vol_list { dlink link; /* link for list */ int Index; /* Unique index */ slot_type Type; /* See slot_type_* */ slot_content Content; /* See slot_content_* */ int Slot; /* Drive number when slot_type_drive or actual slot number */ int Loaded; /* Volume loaded in drive when slot_type_drive */ char *VolName; /* Actual Volume Name */ } vol_list_t; #define INDEX_DRIVE_OFFSET 0 #define INDEX_MAX_DRIVES 100 #define INDEX_SLOT_OFFSET 100 #define FD_VERSION_1 1 #define FD_VERSION_2 2 #define FD_VERSION_3 3 #define FD_VERSION_4 4 #define FD_VERSION_5 5 #define FD_VERSION_51 51 #define FD_VERSION_52 52 #define FD_VERSION_53 53 #include "protos.h" bareos-Release-14.2.6/src/dird/dird_conf.c000066400000000000000000004142101263011562700202460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main configuration file parser for BAREOS Directors, * some parts may be split into separate files such as * the schedule configuration (run_config.c). * * Note, the configuration file parser consists of three parts * * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and * lib/parse_config.h. * * These files contain the parser code, some utility * routines, and the common store routines (name, int, * string). * * 3. The daemon specific file, which contains the Resource * definitions as well as any specific store routines * for the resource records. * * Kern Sibbald, January MM */ #include "bareos.h" #include "dird.h" /* * Define the first and last resource ID record * types. Note, these should be unique for each * daemon though not a requirement. */ static RES *sres_head[R_LAST - R_FIRST + 1]; static RES **res_head = sres_head; /* * Set default indention e.g. 2 spaces. */ #define DEFAULT_INDENT_STRING " " /* * Imported subroutines */ extern void store_inc(LEX *lc, RES_ITEM *item, int index, int pass); extern void store_run(LEX *lc, RES_ITEM *item, int index, int pass); /* * Forward referenced subroutines */ /* * We build the current resource here as we are * scanning the resource configuration definition, * then move it to allocated memory when the resource * scan is complete. */ static URES res_all; static int32_t res_all_size = sizeof(res_all); /* * Definition of records permitted within each * resource with the routine to process the record * information. NOTE! quoted names must be in lower case. * * Director Resource * * name handler value code flags default_value */ static RES_ITEM dir_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_dir.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_dir.hdr.desc), 0, 0, NULL }, { "Messages", CFG_TYPE_RES, ITEM(res_dir.messages), R_MSGS, 0, NULL }, { "DirPort", CFG_TYPE_ADDRESSES_PORT, ITEM(res_dir.DIRaddrs), 0, CFG_ITEM_DEFAULT, DIR_DEFAULT_PORT }, { "DirAddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_dir.DIRaddrs), 0, CFG_ITEM_DEFAULT, DIR_DEFAULT_PORT }, { "DirAddresses", CFG_TYPE_ADDRESSES, ITEM(res_dir.DIRaddrs), 0, CFG_ITEM_DEFAULT, DIR_DEFAULT_PORT }, { "DirSourceAddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_dir.DIRsrc_addr), 0, CFG_ITEM_DEFAULT, "0" }, { "QueryFile", CFG_TYPE_DIR, ITEM(res_dir.query_file), 0, CFG_ITEM_REQUIRED, NULL }, { "WorkingDirectory", CFG_TYPE_DIR, ITEM(res_dir.working_directory), 0, CFG_ITEM_DEFAULT | CFG_ITEM_PLATFORM_SPECIFIC, _PATH_BAREOS_WORKINGDIR }, { "PidDirectory", CFG_TYPE_DIR, ITEM(res_dir.pid_directory), 0, CFG_ITEM_DEFAULT | CFG_ITEM_PLATFORM_SPECIFIC, _PATH_BAREOS_PIDDIR }, { "PluginDirectory", CFG_TYPE_DIR, ITEM(res_dir.plugin_directory), 0, 0, NULL }, { "PluginNames", CFG_TYPE_PLUGIN_NAMES, ITEM(res_dir.plugin_names), 0, 0, NULL }, { "ScriptsDirectory", CFG_TYPE_DIR, ITEM(res_dir.scripts_directory), 0, 0, NULL }, #if defined(HAVE_DYNAMIC_CATS_BACKENDS) { "BackendDirectory", CFG_TYPE_ALIST_DIR, ITEM(res_dir.backend_directories), 0, CFG_ITEM_DEFAULT | CFG_ITEM_PLATFORM_SPECIFIC, _PATH_BAREOS_BACKENDDIR }, #endif { "Subscriptions", CFG_TYPE_PINT32, ITEM(res_dir.subscriptions), 0, CFG_ITEM_DEFAULT, "0" }, { "SubSysDirectory", CFG_TYPE_DIR, ITEM(res_dir.subsys_directory), CFG_ITEM_DEPRECATED, 0, NULL }, { "MaximumConcurrentJobs", CFG_TYPE_PINT32, ITEM(res_dir.MaxConcurrentJobs), 0, CFG_ITEM_DEFAULT, "1" }, { "MaximumConsoleConnections", CFG_TYPE_PINT32, ITEM(res_dir.MaxConsoleConnect), 0, CFG_ITEM_DEFAULT, "20" }, { "Password", CFG_TYPE_AUTOPASSWORD, ITEM(res_dir.password), 0, CFG_ITEM_REQUIRED, NULL }, { "FdConnectTimeout", CFG_TYPE_TIME, ITEM(res_dir.FDConnectTimeout), 0, CFG_ITEM_DEFAULT, "180" /* 3 minutes */ }, { "SdConnectTimeout", CFG_TYPE_TIME, ITEM(res_dir.SDConnectTimeout), 0, CFG_ITEM_DEFAULT, "1800" /* 30 minutes */ }, { "HeartbeatInterval", CFG_TYPE_TIME, ITEM(res_dir.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { "TlsAuthenticate", CFG_TYPE_BOOL, ITEM(res_dir.tls_authenticate), 0, 0, NULL }, { "TlsEnable", CFG_TYPE_BOOL, ITEM(res_dir.tls_enable), 0, 0, NULL }, { "TlsRequire", CFG_TYPE_BOOL, ITEM(res_dir.tls_require), 0, 0, NULL }, { "TlsVerifyPeer", CFG_TYPE_BOOL, ITEM(res_dir.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "TlsCaCertificateFile", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certfile), 0, 0, NULL }, { "TlsCaCertificateDir", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certdir), 0, 0, NULL }, { "TlsCertificateRevocationList", CFG_TYPE_DIR, ITEM(res_dir.tls_crlfile), 0, 0, NULL }, { "TlsCertificate", CFG_TYPE_DIR, ITEM(res_dir.tls_certfile), 0, 0, NULL }, { "TlsKey", CFG_TYPE_DIR, ITEM(res_dir.tls_keyfile), 0, 0, NULL }, { "TlsDhFile", CFG_TYPE_DIR, ITEM(res_dir.tls_dhfile), 0, 0, NULL }, { "TlsAllowedCN", CFG_TYPE_ALIST_STR, ITEM(res_dir.tls_allowed_cns), 0, 0, NULL }, { "StatisticsRetention", CFG_TYPE_TIME, ITEM(res_dir.stats_retention), 0, CFG_ITEM_DEFAULT, "160704000" /* 5 years */ }, { "StatisticsCollectInterval", CFG_TYPE_PINT32, ITEM(res_dir.stats_collect_interval), 0, CFG_ITEM_DEFAULT, "150" }, { "VerId", CFG_TYPE_STR, ITEM(res_dir.verid), 0, 0, NULL }, { "OptimizeForSize", CFG_TYPE_BOOL, ITEM(res_dir.optimize_for_size), 0, CFG_ITEM_DEFAULT, "false" }, { "OptimizeForSpeed", CFG_TYPE_BOOL, ITEM(res_dir.optimize_for_speed), 0, CFG_ITEM_DEFAULT, "false" }, { "OmitDefaults", CFG_TYPE_BOOL, ITEM(res_dir.omit_defaults), 0, CFG_ITEM_DEFAULT, "true" }, { "KeyEncryptionKey", CFG_TYPE_AUTOPASSWORD, ITEM(res_dir.keyencrkey), 1, 0, NULL }, { "NdmpSnooping", CFG_TYPE_BOOL, ITEM(res_dir.ndmp_snooping), 0, 0, NULL }, { "NdmpLogLevel", CFG_TYPE_PINT32, ITEM(res_dir.ndmp_loglevel), 0, CFG_ITEM_DEFAULT, "4" }, { "AbsoluteJobTimeout", CFG_TYPE_PINT32, ITEM(res_dir.jcr_watchdog_time), 0, 0, NULL }, { "Auditing", CFG_TYPE_BOOL, ITEM(res_dir.auditing), 0, CFG_ITEM_DEFAULT, "false" }, { "AuditEvents", CFG_TYPE_AUDIT, ITEM(res_dir.audit_events), 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Profile Resource * * name handler value code flags default_value */ static RES_ITEM profile_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_profile.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_profile.hdr.desc), 0, 0, NULL }, { "JobACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Job_ACL, 0, NULL }, { "ClientACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Client_ACL, 0, NULL }, { "StorageACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Storage_ACL, 0, NULL }, { "ScheduleACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Schedule_ACL, 0, NULL }, { "RunACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Run_ACL, 0, NULL }, { "PoolACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Pool_ACL, 0, NULL }, { "CommandACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Command_ACL, 0, NULL }, { "FileSetACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), FileSet_ACL, 0, NULL }, { "CatalogACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Catalog_ACL, 0, NULL }, { "WhereACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), Where_ACL, 0, NULL }, { "PluginOptionsACL", CFG_TYPE_ACL, ITEM(res_profile.ACL_lists), PluginOptions_ACL, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Console Resource * * name handler value code flags default_value */ static RES_ITEM con_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_con.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_con.hdr.desc), 0, 0, NULL }, { "Password", CFG_TYPE_AUTOPASSWORD, ITEM(res_con.password), 0, CFG_ITEM_REQUIRED, NULL }, { "JobACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Job_ACL, 0, NULL }, { "ClientACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Client_ACL, 0, NULL }, { "StorageACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Storage_ACL, 0, NULL }, { "ScheduleACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Schedule_ACL, 0, NULL }, { "RunACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Run_ACL, 0, NULL }, { "PoolACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Pool_ACL, 0, NULL }, { "CommandACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Command_ACL, 0, NULL }, { "FileSetACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), FileSet_ACL, 0, NULL }, { "CatalogACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Catalog_ACL, 0, NULL }, { "WhereACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), Where_ACL, 0, NULL }, { "PluginOptionsACL", CFG_TYPE_ACL, ITEM(res_con.ACL_lists), PluginOptions_ACL, 0, NULL }, { "TlsAuthenticate", CFG_TYPE_BOOL, ITEM(res_con.tls_authenticate), 0, 0, NULL }, { "TlsEnable", CFG_TYPE_BOOL, ITEM(res_con.tls_enable), 0, 0, NULL }, { "TlsRequire", CFG_TYPE_BOOL, ITEM(res_con.tls_require), 0, 0, NULL }, { "TlsVerifyPeer", CFG_TYPE_BOOL, ITEM(res_con.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "TlsCaCertificateFile", CFG_TYPE_DIR, ITEM(res_con.tls_ca_certfile), 0, 0, NULL }, { "TlsCaCertificateDir", CFG_TYPE_DIR, ITEM(res_con.tls_ca_certdir), 0, 0, NULL }, { "TlsCertificateRevocationList", CFG_TYPE_DIR, ITEM(res_con.tls_crlfile), 0, 0, NULL }, { "TlsCertificate", CFG_TYPE_DIR, ITEM(res_con.tls_certfile), 0, 0, NULL }, { "TlsKey", CFG_TYPE_DIR, ITEM(res_con.tls_keyfile), 0, 0, NULL }, { "TlsDhFile", CFG_TYPE_DIR, ITEM(res_con.tls_dhfile), 0, 0, NULL }, { "TlsAllowedCN", CFG_TYPE_ALIST_STR, ITEM(res_con.tls_allowed_cns), 0, 0, NULL }, { "Profile", CFG_TYPE_ALIST_RES, ITEM(res_con.profiles), R_PROFILE, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Client or File daemon resource * * name handler value code flags default_value */ static RES_ITEM cli_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_client.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_client.hdr.desc), 0, 0, NULL }, { "Protocol", CFG_TYPE_AUTHPROTOCOLTYPE, ITEM(res_client.Protocol), 0, CFG_ITEM_DEFAULT, "Native" }, { "AuthType", CFG_TYPE_AUTHTYPE, ITEM(res_client.AuthType), 0, CFG_ITEM_DEFAULT, "None" }, { "Address", CFG_TYPE_STR, ITEM(res_client.address), 0, CFG_ITEM_REQUIRED, NULL }, { "FdAddress", CFG_TYPE_STR, ITEM(res_client.address), 0, CFG_ITEM_ALIAS, NULL }, { "Port", CFG_TYPE_PINT32, ITEM(res_client.FDport), 0, CFG_ITEM_DEFAULT, FD_DEFAULT_PORT }, { "FdPort", CFG_TYPE_PINT32, ITEM(res_client.FDport), 0, CFG_ITEM_DEFAULT | CFG_ITEM_ALIAS, FD_DEFAULT_PORT }, { "Username", CFG_TYPE_STR, ITEM(res_client.username), 0, 0, NULL }, { "Password", CFG_TYPE_AUTOPASSWORD, ITEM(res_client.password), 0, CFG_ITEM_REQUIRED, NULL }, { "FdPassword", CFG_TYPE_AUTOPASSWORD, ITEM(res_client.password), 0, CFG_ITEM_ALIAS, NULL }, { "Catalog", CFG_TYPE_RES, ITEM(res_client.catalog), R_CATALOG, 0, NULL }, { "Passive", CFG_TYPE_BOOL, ITEM(res_client.passive), 0, CFG_ITEM_DEFAULT, "false" }, { "Enabled", CFG_TYPE_BOOL, ITEM(res_client.enabled), 0, CFG_ITEM_DEFAULT, "true" }, { "HardQuota", CFG_TYPE_SIZE64, ITEM(res_client.HardQuota), 0, CFG_ITEM_DEFAULT, "0" }, { "SoftQuota", CFG_TYPE_SIZE64, ITEM(res_client.SoftQuota), 0, CFG_ITEM_DEFAULT, "0" }, { "SoftQuotaGracePeriod", CFG_TYPE_TIME, ITEM(res_client.SoftQuotaGracePeriod), 0, CFG_ITEM_DEFAULT, "0" }, { "StrictQuotas", CFG_TYPE_BOOL, ITEM(res_client.StrictQuotas), 0, CFG_ITEM_DEFAULT, "false" }, { "QuotaIncludeFailedJobs", CFG_TYPE_BOOL, ITEM(res_client.QuotaIncludeFailedJobs), 0, CFG_ITEM_DEFAULT, "true" }, { "FileRetention", CFG_TYPE_TIME, ITEM(res_client.FileRetention), 0, CFG_ITEM_DEFAULT, "5184000" /* 60 days */ }, { "JobRetention", CFG_TYPE_TIME, ITEM(res_client.JobRetention), 0, CFG_ITEM_DEFAULT, "15552000" /* 180 days */ }, { "HeartbeatInterval", CFG_TYPE_TIME, ITEM(res_client.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { "AutoPrune", CFG_TYPE_BOOL, ITEM(res_client.AutoPrune), 0, CFG_ITEM_DEFAULT, "false" }, { "MaximumConcurrentJobs", CFG_TYPE_PINT32, ITEM(res_client.MaxConcurrentJobs), 0, CFG_ITEM_DEFAULT, "1" }, { "TlsAuthenticate", CFG_TYPE_BOOL, ITEM(res_client.tls_authenticate), 0, 0, NULL }, { "TlsEnable", CFG_TYPE_BOOL, ITEM(res_client.tls_enable), 0, 0, NULL }, { "TlsRequire", CFG_TYPE_BOOL, ITEM(res_client.tls_require), 0, 0, NULL }, { "TlsCaCertificateFile", CFG_TYPE_DIR, ITEM(res_client.tls_ca_certfile), 0, 0, NULL }, { "TlsCaCertificateDir", CFG_TYPE_DIR, ITEM(res_client.tls_ca_certdir), 0, 0, NULL }, { "TlsCertificateRevocationList", CFG_TYPE_DIR, ITEM(res_client.tls_crlfile), 0, 0, NULL }, { "TlsCertificate", CFG_TYPE_DIR, ITEM(res_client.tls_certfile), 0, 0, NULL }, { "TlsKey", CFG_TYPE_DIR, ITEM(res_client.tls_keyfile), 0, 0, NULL }, { "TlsAllowedCN", CFG_TYPE_ALIST_STR, ITEM(res_client.tls_allowed_cns), 0, 0, NULL }, { "MaximumBandwidthPerJob", CFG_TYPE_SPEED, ITEM(res_client.max_bandwidth), 0, 0, NULL }, { "NdmpLogLevel", CFG_TYPE_PINT32, ITEM(res_client.ndmp_loglevel), 0, CFG_ITEM_DEFAULT, "4" }, { "NdmpBlockSize", CFG_TYPE_PINT32, ITEM(res_client.ndmp_blocksize), 0, CFG_ITEM_DEFAULT, "64512" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* Storage daemon resource * * name handler value code flags default_value */ static RES_ITEM store_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_store.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_store.hdr.desc), 0, 0, NULL }, { "Protocol", CFG_TYPE_AUTHPROTOCOLTYPE, ITEM(res_store.Protocol), 0, CFG_ITEM_DEFAULT, "Native" }, { "AuthType", CFG_TYPE_AUTHTYPE, ITEM(res_store.AuthType), 0, CFG_ITEM_DEFAULT, "None" }, { "Address", CFG_TYPE_STR, ITEM(res_store.address), 0, CFG_ITEM_REQUIRED, NULL }, { "SdAddress", CFG_TYPE_STR, ITEM(res_store.address), 0, CFG_ITEM_ALIAS, NULL }, { "Port", CFG_TYPE_PINT32, ITEM(res_store.SDport), 0, CFG_ITEM_DEFAULT, SD_DEFAULT_PORT }, { "SdPort", CFG_TYPE_PINT32, ITEM(res_store.SDport), 0, CFG_ITEM_DEFAULT | CFG_ITEM_ALIAS, SD_DEFAULT_PORT }, { "Username", CFG_TYPE_STR, ITEM(res_store.username), 0, 0, NULL }, { "Password", CFG_TYPE_AUTOPASSWORD, ITEM(res_store.password), 0, CFG_ITEM_REQUIRED, NULL }, { "SdPassword", CFG_TYPE_AUTOPASSWORD, ITEM(res_store.password), 0, CFG_ITEM_ALIAS, NULL }, { "Device", CFG_TYPE_DEVICE, ITEM(res_store.device), R_DEVICE, CFG_ITEM_REQUIRED, NULL }, { "MediaType", CFG_TYPE_STRNAME, ITEM(res_store.media_type), 0, CFG_ITEM_REQUIRED, NULL }, { "AutoChanger", CFG_TYPE_BOOL, ITEM(res_store.autochanger), 0, CFG_ITEM_DEFAULT, "false" }, { "Enabled", CFG_TYPE_BOOL, ITEM(res_store.enabled), 0, CFG_ITEM_DEFAULT, "true" }, { "AllowCompression", CFG_TYPE_BOOL, ITEM(res_store.AllowCompress), 0, CFG_ITEM_DEFAULT, "true" }, { "HeartbeatInterval", CFG_TYPE_TIME, ITEM(res_store.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { "MaximumConcurrentJobs", CFG_TYPE_PINT32, ITEM(res_store.MaxConcurrentJobs), 0, CFG_ITEM_DEFAULT, "1" }, { "MaximumConcurrentReadJobs", CFG_TYPE_PINT32, ITEM(res_store.MaxConcurrentReadJobs), 0, CFG_ITEM_DEFAULT, "0" }, { "SddPort", CFG_TYPE_PINT32, ITEM(res_store.SDDport), 0, CFG_ITEM_DEPRECATED, NULL }, { "TlsAuthenticate", CFG_TYPE_BOOL, ITEM(res_store.tls_authenticate), 0, 0, NULL }, { "TlsEnable", CFG_TYPE_BOOL, ITEM(res_store.tls_enable), 0, 0, NULL }, { "TlsRequire", CFG_TYPE_BOOL, ITEM(res_store.tls_require), 0, 0, NULL }, { "TlsCaCertificateFile", CFG_TYPE_DIR, ITEM(res_store.tls_ca_certfile), 0, 0, NULL }, { "TlsCacertificateDir", CFG_TYPE_DIR, ITEM(res_store.tls_ca_certdir), 0, 0, NULL }, { "TlsCertificateRevocationList", CFG_TYPE_DIR, ITEM(res_store.tls_crlfile), 0, 0, NULL }, { "TlsCertificate", CFG_TYPE_DIR, ITEM(res_store.tls_certfile), 0, 0, NULL }, { "TlsKey", CFG_TYPE_DIR, ITEM(res_store.tls_keyfile), 0, 0, NULL }, { "PairedStorage", CFG_TYPE_RES, ITEM(res_store.paired_storage), R_STORAGE, 0, NULL }, { "MaximumBandwidthPerJob", CFG_TYPE_SPEED, ITEM(res_store.max_bandwidth), 0, 0, NULL }, { "CollectStatistics", CFG_TYPE_BOOL, ITEM(res_store.collectstats), 0, CFG_ITEM_DEFAULT, "false" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Catalog Resource Directives * * name handler value code flags default_value */ static RES_ITEM cat_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_cat.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_cat.hdr.desc), 0, 0, NULL }, { "Address", CFG_TYPE_STR, ITEM(res_cat.db_address), 0, CFG_ITEM_ALIAS, NULL }, { "DbAddress", CFG_TYPE_STR, ITEM(res_cat.db_address), 0, 0, NULL }, { "DbPort", CFG_TYPE_PINT32, ITEM(res_cat.db_port), 0, 0, NULL }, { "Password", CFG_TYPE_AUTOPASSWORD, ITEM(res_cat.db_password), 0, CFG_ITEM_ALIAS, NULL }, { "DbPassword", CFG_TYPE_AUTOPASSWORD, ITEM(res_cat.db_password), 0, 0, NULL }, { "DbUser", CFG_TYPE_STR, ITEM(res_cat.db_user), 0, 0, NULL }, { "User", CFG_TYPE_STR, ITEM(res_cat.db_user), 0, CFG_ITEM_ALIAS, NULL }, { "DbName", CFG_TYPE_STR, ITEM(res_cat.db_name), 0, CFG_ITEM_REQUIRED, NULL }, #ifdef HAVE_DYNAMIC_CATS_BACKENDS { "DbDriver", CFG_TYPE_STR, ITEM(res_cat.db_driver), 0, CFG_ITEM_REQUIRED, NULL }, #else { "DbDriver", CFG_TYPE_STR, ITEM(res_cat.db_driver), 0, 0, NULL }, #endif { "DbSocket", CFG_TYPE_STR, ITEM(res_cat.db_socket), 0, 0, NULL }, /* Turned off for the moment */ { "MultipleConnections", CFG_TYPE_BIT, ITEM(res_cat.mult_db_connections), 0, 0, NULL }, { "DisableBatchInsert", CFG_TYPE_BOOL, ITEM(res_cat.disable_batch_insert), 0, CFG_ITEM_DEFAULT, "false" }, { "MinConnections", CFG_TYPE_PINT32, ITEM(res_cat.pooling_min_connections), 0, CFG_ITEM_DEFAULT, "1" }, { "MaxConnections", CFG_TYPE_PINT32, ITEM(res_cat.pooling_max_connections), 0, CFG_ITEM_DEFAULT, "5" }, { "IncConnections", CFG_TYPE_PINT32, ITEM(res_cat.pooling_increment_connections), 0, CFG_ITEM_DEFAULT, "1" }, { "IdleTimeout", CFG_TYPE_PINT32, ITEM(res_cat.pooling_idle_timeout), 0, CFG_ITEM_DEFAULT, "30" }, { "ValidateTimeout", CFG_TYPE_PINT32, ITEM(res_cat.pooling_validate_timeout), 0, CFG_ITEM_DEFAULT, "120" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Job Resource Directives * * name handler value code flags default_value */ RES_ITEM job_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_job.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_job.hdr.desc), 0, 0, NULL }, { "Type", CFG_TYPE_JOBTYPE, ITEM(res_job.JobType), 0, CFG_ITEM_REQUIRED, NULL }, { "Protocol", CFG_TYPE_PROTOCOLTYPE, ITEM(res_job.Protocol), 0, CFG_ITEM_DEFAULT, "Native" }, { "BackupFormat", CFG_TYPE_STR, ITEM(res_job.backup_format), 0, CFG_ITEM_DEFAULT, "Native" }, { "Level", CFG_TYPE_LEVEL, ITEM(res_job.JobLevel), 0, 0, NULL }, { "Messages", CFG_TYPE_RES, ITEM(res_job.messages), R_MSGS, CFG_ITEM_REQUIRED, NULL }, { "Storage", CFG_TYPE_ALIST_RES, ITEM(res_job.storage), R_STORAGE, 0, NULL }, { "Pool", CFG_TYPE_RES, ITEM(res_job.pool), R_POOL, CFG_ITEM_REQUIRED, NULL }, { "FullBackupPool", CFG_TYPE_RES, ITEM(res_job.full_pool), R_POOL, 0, NULL }, { "VirtualFullBackupPool", CFG_TYPE_RES, ITEM(res_job.vfull_pool), R_POOL, 0, NULL }, { "IncrementalBackupPool", CFG_TYPE_RES, ITEM(res_job.inc_pool), R_POOL, 0, NULL }, { "DifferentialBackupPool", CFG_TYPE_RES, ITEM(res_job.diff_pool), R_POOL, 0, NULL }, { "NextPool", CFG_TYPE_RES, ITEM(res_job.next_pool), R_POOL, 0, NULL }, { "Client", CFG_TYPE_RES, ITEM(res_job.client), R_CLIENT, 0, NULL }, { "FileSet", CFG_TYPE_RES, ITEM(res_job.fileset), R_FILESET, 0, NULL }, { "Schedule", CFG_TYPE_RES, ITEM(res_job.schedule), R_SCHEDULE, 0, NULL }, { "VerifyJob", CFG_TYPE_RES, ITEM(res_job.verify_job), R_JOB, CFG_ITEM_ALIAS, NULL }, { "JobToVerify", CFG_TYPE_RES, ITEM(res_job.verify_job), R_JOB, 0, NULL }, { "Catalog", CFG_TYPE_RES, ITEM(res_job.catalog), R_CATALOG, 0, NULL }, { "JobDefs", CFG_TYPE_RES, ITEM(res_job.jobdefs), R_JOBDEFS, 0, NULL }, { "Run", CFG_TYPE_ALIST_STR, ITEM(res_job.run_cmds), 0, 0, NULL }, /* Root of where to restore files */ { "Where", CFG_TYPE_DIR, ITEM(res_job.RestoreWhere), 0, 0, NULL }, { "RegexWhere", CFG_TYPE_STR, ITEM(res_job.RegexWhere), 0, 0, NULL }, { "StripPrefix", CFG_TYPE_STR, ITEM(res_job.strip_prefix), 0, 0, NULL }, { "AddPrefix", CFG_TYPE_STR, ITEM(res_job.add_prefix), 0, 0, NULL }, { "AddSuffix", CFG_TYPE_STR, ITEM(res_job.add_suffix), 0, 0, NULL }, /* Where to find bootstrap during restore */ { "Bootstrap", CFG_TYPE_DIR, ITEM(res_job.RestoreBootstrap), 0, 0, NULL }, /* Where to write bootstrap file during backup */ { "WriteBootstrap", CFG_TYPE_DIR, ITEM(res_job.WriteBootstrap), 0, 0, NULL }, { "WriteVerifyList", CFG_TYPE_DIR, ITEM(res_job.WriteVerifyList), 0, 0, NULL }, { "Replace", CFG_TYPE_REPLACE, ITEM(res_job.replace), 0, CFG_ITEM_DEFAULT, "Always" }, { "MaximumBandwidth", CFG_TYPE_SPEED, ITEM(res_job.max_bandwidth), 0, 0, NULL }, { "MaxrunSchedTime", CFG_TYPE_TIME, ITEM(res_job.MaxRunSchedTime), 0, 0, NULL }, { "MaxRunTime", CFG_TYPE_TIME, ITEM(res_job.MaxRunTime), 0, 0, NULL }, { "FullMaxWaitTime", CFG_TYPE_TIME, ITEM(res_job.FullMaxRunTime), 0, CFG_ITEM_DEPRECATED, NULL }, { "IncrementalMaxWaitTime", CFG_TYPE_TIME, ITEM(res_job.IncMaxRunTime), 0, CFG_ITEM_DEPRECATED, NULL }, { "DifferentialMaxWaitTime", CFG_TYPE_TIME, ITEM(res_job.DiffMaxRunTime), 0, CFG_ITEM_DEPRECATED, NULL }, { "FullMaxRuntime", CFG_TYPE_TIME, ITEM(res_job.FullMaxRunTime), 0, 0, NULL }, { "IncrementalMaxRuntime", CFG_TYPE_TIME, ITEM(res_job.IncMaxRunTime), 0, 0, NULL }, { "DifferentialMaxRuntime", CFG_TYPE_TIME, ITEM(res_job.DiffMaxRunTime), 0, 0, NULL }, { "MaxWaitTime", CFG_TYPE_TIME, ITEM(res_job.MaxWaitTime), 0, 0, NULL }, { "MaxStartDelay", CFG_TYPE_TIME, ITEM(res_job.MaxStartDelay), 0, 0, NULL }, { "MaxFullInterval", CFG_TYPE_TIME, ITEM(res_job.MaxFullInterval), 0, 0, NULL }, { "MaxVirtualFullInterval", CFG_TYPE_TIME, ITEM(res_job.MaxVFullInterval), 0, 0, NULL }, { "MaxDiffInterval", CFG_TYPE_TIME, ITEM(res_job.MaxDiffInterval), 0, 0, NULL }, { "PrefixLinks", CFG_TYPE_BOOL, ITEM(res_job.PrefixLinks), 0, CFG_ITEM_DEFAULT, "false" }, { "PruneJobs", CFG_TYPE_BOOL, ITEM(res_job.PruneJobs), 0, CFG_ITEM_DEFAULT, "false" }, { "PruneFiles", CFG_TYPE_BOOL, ITEM(res_job.PruneFiles), 0, CFG_ITEM_DEFAULT, "false" }, { "PruneVolumes", CFG_TYPE_BOOL, ITEM(res_job.PruneVolumes), 0, CFG_ITEM_DEFAULT, "false" }, { "PurgeMigrationJob", CFG_TYPE_BOOL, ITEM(res_job.PurgeMigrateJob), 0, CFG_ITEM_DEFAULT, "false" }, { "Enabled", CFG_TYPE_BOOL, ITEM(res_job.enabled), 0, CFG_ITEM_DEFAULT, "true" }, { "SpoolAttributes", CFG_TYPE_BOOL, ITEM(res_job.SpoolAttributes), 0, CFG_ITEM_DEFAULT, "false" }, { "SpoolData", CFG_TYPE_BOOL, ITEM(res_job.spool_data), 0, CFG_ITEM_DEFAULT, "false" }, { "SpoolSize", CFG_TYPE_SIZE64, ITEM(res_job.spool_size), 0, 0, NULL }, { "RerunFailedLevels", CFG_TYPE_BOOL, ITEM(res_job.rerun_failed_levels), 0, CFG_ITEM_DEFAULT, "false" }, { "PreferMountedVolumes", CFG_TYPE_BOOL, ITEM(res_job.PreferMountedVolumes), 0, CFG_ITEM_DEFAULT, "true" }, { "RunBeforeJob", CFG_TYPE_SHRTRUNSCRIPT, ITEM(res_job.RunScripts), 0, 0, NULL }, { "RunAfterJob", CFG_TYPE_SHRTRUNSCRIPT, ITEM(res_job.RunScripts), 0, 0, NULL }, { "RunAfterFailedJob", CFG_TYPE_SHRTRUNSCRIPT, ITEM(res_job.RunScripts), 0, 0, NULL }, { "ClientRunBeforeJob", CFG_TYPE_SHRTRUNSCRIPT, ITEM(res_job.RunScripts), 0, 0, NULL }, { "ClientRunAfterJob", CFG_TYPE_SHRTRUNSCRIPT, ITEM(res_job.RunScripts), 0, 0, NULL }, { "MaximumConcurrentJobs", CFG_TYPE_PINT32, ITEM(res_job.MaxConcurrentJobs), 0, CFG_ITEM_DEFAULT, "1" }, { "RescheduleOnError", CFG_TYPE_BOOL, ITEM(res_job.RescheduleOnError), 0, CFG_ITEM_DEFAULT, "false" }, { "RescheduleInterval", CFG_TYPE_TIME, ITEM(res_job.RescheduleInterval), 0, CFG_ITEM_DEFAULT, "1800" /* 30 minutes */ }, { "RescheduleTimes", CFG_TYPE_PINT32, ITEM(res_job.RescheduleTimes), 0, CFG_ITEM_DEFAULT, "5" }, { "Priority", CFG_TYPE_PINT32, ITEM(res_job.Priority), 0, CFG_ITEM_DEFAULT, "10" }, { "AllowMixedPriority", CFG_TYPE_BOOL, ITEM(res_job.allow_mixed_priority), 0, CFG_ITEM_DEFAULT, "false" }, { "WritePartAfterJob", CFG_TYPE_BOOL, ITEM(res_job.write_part_after_job), 0, CFG_ITEM_DEPRECATED, NULL }, { "SelectionPattern", CFG_TYPE_STR, ITEM(res_job.selection_pattern), 0, 0, NULL }, { "RunScript", CFG_TYPE_RUNSCRIPT, ITEM(res_job.RunScripts), 0, CFG_ITEM_NO_EQUALS, NULL }, { "SelectionType", CFG_TYPE_MIGTYPE, ITEM(res_job.selection_type), 0, 0, NULL }, { "Accurate", CFG_TYPE_BOOL, ITEM(res_job.accurate), 0, CFG_ITEM_DEFAULT, "false" }, { "AllowDuplicateJobs", CFG_TYPE_BOOL, ITEM(res_job.AllowDuplicateJobs), 0, CFG_ITEM_DEFAULT, "true" }, { "AllowHigherDuplicates", CFG_TYPE_BOOL, ITEM(res_job.AllowHigherDuplicates), 0, CFG_ITEM_DEFAULT, "true" }, { "CancelLowerLevelDuplicates", CFG_TYPE_BOOL, ITEM(res_job.CancelLowerLevelDuplicates), 0, CFG_ITEM_DEFAULT, "false" }, { "CancelQueuedDuplicates", CFG_TYPE_BOOL, ITEM(res_job.CancelQueuedDuplicates), 0, CFG_ITEM_DEFAULT, "false" }, { "CancelRunningDuplicates", CFG_TYPE_BOOL, ITEM(res_job.CancelRunningDuplicates), 0, CFG_ITEM_DEFAULT, "false" }, { "SaveFileHistory", CFG_TYPE_BOOL, ITEM(res_job.SaveFileHist), 0, CFG_ITEM_DEFAULT, "true" }, { "PluginOptions", CFG_TYPE_ALIST_STR, ITEM(res_job.FdPluginOptions), 0, CFG_ITEM_DEPRECATED | CFG_ITEM_ALIAS, NULL }, { "FdPluginOptions", CFG_TYPE_ALIST_STR, ITEM(res_job.FdPluginOptions), 0, 0, NULL }, { "SdPluginOptions", CFG_TYPE_ALIST_STR, ITEM(res_job.SdPluginOptions), 0, 0, NULL }, { "DirPluginOptions", CFG_TYPE_ALIST_STR, ITEM(res_job.DirPluginOptions), 0, 0, NULL }, { "Base", CFG_TYPE_ALIST_RES, ITEM(res_job.base), R_JOB, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * FileSet resource * * name handler value code flags default_value */ static RES_ITEM fs_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_fs.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_fs.hdr.desc), 0, 0, NULL }, { "Include", CFG_TYPE_INCEXC, { 0 }, 0, CFG_ITEM_NO_EQUALS, NULL }, { "Exclude", CFG_TYPE_INCEXC, { 0 }, 1, CFG_ITEM_NO_EQUALS, NULL }, { "IgnoreFileSetChanges", CFG_TYPE_BOOL, ITEM(res_fs.ignore_fs_changes), 0, CFG_ITEM_DEFAULT, "false" }, { "EnableVSS", CFG_TYPE_BOOL, ITEM(res_fs.enable_vss), 0, CFG_ITEM_DEFAULT, "true" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Schedule -- see run_conf.c * * name handler value code flags default_value */ static RES_ITEM sch_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_sch.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_sch.hdr.desc), 0, 0, NULL }, { "Run", CFG_TYPE_RUN, ITEM(res_sch.run), 0, 0, NULL }, { "Enabled", CFG_TYPE_BOOL, ITEM(res_sch.enabled), 0, CFG_ITEM_DEFAULT, "true" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Pool resource * * name handler value code flags default_value */ static RES_ITEM pool_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_pool.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_pool.hdr.desc), 0, 0, NULL }, { "PoolType", CFG_TYPE_STRNAME, ITEM(res_pool.pool_type), 0, CFG_ITEM_REQUIRED, NULL }, { "LabelFormat", CFG_TYPE_STRNAME, ITEM(res_pool.label_format), 0, 0, NULL }, { "LabelType", CFG_TYPE_LABEL, ITEM(res_pool.LabelType), 0, 0, NULL }, { "CleaningPrefix", CFG_TYPE_STRNAME, ITEM(res_pool.cleaning_prefix), 0, CFG_ITEM_DEFAULT, "CLN" }, { "UseCatalog", CFG_TYPE_BOOL, ITEM(res_pool.use_catalog), 0, CFG_ITEM_DEFAULT, "true" }, { "UseVolumeOnce", CFG_TYPE_BOOL, ITEM(res_pool.use_volume_once), 0, CFG_ITEM_DEPRECATED, NULL }, { "PurgeOldestVolume", CFG_TYPE_BOOL, ITEM(res_pool.purge_oldest_volume), 0, 0, NULL }, { "ActionOnPurge", CFG_TYPE_ACTIONONPURGE, ITEM(res_pool.action_on_purge), 0, 0, NULL }, { "RecycleOldestVolume", CFG_TYPE_BOOL, ITEM(res_pool.recycle_oldest_volume), 0, 0, NULL }, { "RecycleCurrentVolume", CFG_TYPE_BOOL, ITEM(res_pool.recycle_current_volume), 0, 0, NULL }, { "MaximumVolumes", CFG_TYPE_PINT32, ITEM(res_pool.max_volumes), 0, 0, NULL }, { "MaximumVolumeJobs", CFG_TYPE_PINT32, ITEM(res_pool.MaxVolJobs), 0, 0, NULL }, { "MaximumVolumeFiles", CFG_TYPE_PINT32, ITEM(res_pool.MaxVolFiles), 0, 0, NULL }, { "MaximumVolumeBytes", CFG_TYPE_SIZE64, ITEM(res_pool.MaxVolBytes), 0, 0, NULL }, { "CatalogFiles", CFG_TYPE_BOOL, ITEM(res_pool.catalog_files), 0, CFG_ITEM_DEFAULT, "true" }, { "VolumeRetention", CFG_TYPE_TIME, ITEM(res_pool.VolRetention), 0, CFG_ITEM_DEFAULT, "31536000" /* 365 days */ }, { "VolumeUseDuration", CFG_TYPE_TIME, ITEM(res_pool.VolUseDuration), 0, 0, NULL }, { "MigrationTime", CFG_TYPE_TIME, ITEM(res_pool.MigrationTime), 0, 0, NULL }, { "MigrationHighBytes", CFG_TYPE_SIZE64, ITEM(res_pool.MigrationHighBytes), 0, 0, NULL }, { "MigrationLowBytes", CFG_TYPE_SIZE64, ITEM(res_pool.MigrationLowBytes), 0, 0, NULL }, { "NextPool", CFG_TYPE_RES, ITEM(res_pool.NextPool), R_POOL, 0, NULL }, { "Storage", CFG_TYPE_ALIST_RES, ITEM(res_pool.storage), R_STORAGE, 0, NULL }, { "AutoPrune", CFG_TYPE_BOOL, ITEM(res_pool.AutoPrune), 0, CFG_ITEM_DEFAULT, "true" }, { "Recycle", CFG_TYPE_BOOL, ITEM(res_pool.Recycle), 0, CFG_ITEM_DEFAULT, "true" }, { "RecyclePool", CFG_TYPE_RES, ITEM(res_pool.RecyclePool), R_POOL, 0, NULL }, { "ScratchPool", CFG_TYPE_RES, ITEM(res_pool.ScratchPool), R_POOL, 0, NULL }, { "Catalog", CFG_TYPE_RES, ITEM(res_pool.catalog), R_CATALOG, 0, NULL }, { "FileRetention", CFG_TYPE_TIME, ITEM(res_pool.FileRetention), 0, 0, NULL }, { "JobRetention", CFG_TYPE_TIME, ITEM(res_pool.JobRetention), 0, 0, NULL }, { "MinimumBlocksize", CFG_TYPE_PINT32, ITEM(res_pool.MinBlocksize), 0, 0, NULL }, { "MaximumBlocksize", CFG_TYPE_PINT32, ITEM(res_pool.MaxBlocksize), 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Counter Resource * * name handler value code flags default_value */ static RES_ITEM counter_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_counter.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_counter.hdr.desc), 0, 0, NULL }, { "Minimum", CFG_TYPE_INT32, ITEM(res_counter.MinValue), 0, CFG_ITEM_DEFAULT, "0" }, { "Maximum", CFG_TYPE_PINT32, ITEM(res_counter.MaxValue), 0, CFG_ITEM_DEFAULT, "2147483647" /* INT32_MAX */ }, { "WrapCounter", CFG_TYPE_RES, ITEM(res_counter.WrapCounter), R_COUNTER, 0, NULL }, { "Catalog", CFG_TYPE_RES, ITEM(res_counter.Catalog), R_CATALOG, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Message resource */ #include "lib/msg_res.h" /* * This is the master resource definition. * It must have one item for each of the resources. * * NOTE!!! keep it in the same order as the R_codes * or eliminate all resources[rindex].name * * name handler value code flags default_value */ static RES_TABLE resources[] = { { "Director", dir_items, R_DIRECTOR, sizeof(DIRRES) }, { "Client", cli_items, R_CLIENT, sizeof(CLIENTRES) }, { "JobDefs", job_items, R_JOBDEFS, sizeof(JOBRES) }, { "Job", job_items, R_JOB, sizeof(JOBRES) }, { "Storage", store_items, R_STORAGE, sizeof(STORERES) }, { "Catalog", cat_items, R_CATALOG, sizeof(CATRES) }, { "Schedule", sch_items, R_SCHEDULE, sizeof(SCHEDRES) }, { "FileSet", fs_items, R_FILESET, sizeof(FILESETRES) }, { "Pool", pool_items, R_POOL, sizeof(POOLRES) }, { "Messages", msgs_items, R_MSGS, sizeof(MSGSRES) }, { "Counter", counter_items, R_COUNTER, sizeof(COUNTERRES) }, { "Profile", profile_items, R_PROFILE, sizeof(PROFILERES) }, { "Console", con_items, R_CONSOLE, sizeof(CONRES) }, { "Device", NULL, R_DEVICE, sizeof(DEVICERES) }, /* info obtained from SD */ { NULL, NULL, 0, 0 } }; /* * Note, when this resource is used, we are inside a Job * resource. We treat the RunScript like a sort of * mini-resource within the Job resource. As such we * don't use the URES union because that contains * a Job resource (and it would corrupt the Job resource) * but use a global separate resource for holding the * runscript data. */ static RUNSCRIPT res_runscript; /* * new RunScript items * name handler value code flags default_value */ static RES_ITEM runscript_items[] = { { "Command", CFG_TYPE_RUNSCRIPT_CMD, { (char **)&res_runscript }, SHELL_CMD, 0, NULL }, { "Console", CFG_TYPE_RUNSCRIPT_CMD, { (char **)&res_runscript }, CONSOLE_CMD, 0, NULL }, { "Target", CFG_TYPE_RUNSCRIPT_TARGET, { (char **)&res_runscript }, 0, 0, NULL }, { "RunsOnSuccess", CFG_TYPE_RUNSCRIPT_BOOL, { (char **)&res_runscript.on_success }, 0, 0, NULL }, { "RunsOnFailure", CFG_TYPE_RUNSCRIPT_BOOL, { (char **)&res_runscript.on_failure }, 0, 0, NULL }, { "FailJobOnError", CFG_TYPE_RUNSCRIPT_BOOL, { (char **)&res_runscript.fail_on_error }, 0, 0, NULL }, { "AbortJobOnError", CFG_TYPE_RUNSCRIPT_BOOL, { (char **)&res_runscript.fail_on_error }, 0, 0, NULL }, { "RunsWhen", CFG_TYPE_RUNSCRIPT_WHEN, { (char **)&res_runscript.when }, 0, 0, NULL }, { "RunsOnClient", CFG_TYPE_RUNSCRIPT_TARGET, { (char **)&res_runscript }, 0, 0, NULL }, /* TODO */ { NULL, 0, { 0 }, 0, 0, NULL } }; /* * The following arrays are referenced from else where and * used for display to the user so the keyword are pretty * printed with additional capitals. As the code uses * strcasecmp anyhow this doesn't matter. */ /* * Keywords (RHS) permitted in Job Level records * * name level job_type */ struct s_jl joblevels[] = { { "Full", L_FULL, JT_BACKUP }, { "Base", L_BASE, JT_BACKUP }, { "Incremental", L_INCREMENTAL, JT_BACKUP }, { "Differential", L_DIFFERENTIAL, JT_BACKUP }, { "Since", L_SINCE, JT_BACKUP }, { "VirtualFull", L_VIRTUAL_FULL, JT_BACKUP }, { "Catalog", L_VERIFY_CATALOG, JT_VERIFY }, { "InitCatalog", L_VERIFY_INIT, JT_VERIFY }, { "VolumeToCatalog", L_VERIFY_VOLUME_TO_CATALOG, JT_VERIFY }, { "DiskToCatalog", L_VERIFY_DISK_TO_CATALOG, JT_VERIFY }, { "Data", L_VERIFY_DATA, JT_VERIFY }, { "Full", L_FULL, JT_COPY }, { "Incremental", L_INCREMENTAL, JT_COPY }, { "Differential", L_DIFFERENTIAL, JT_COPY }, { "Full", L_FULL, JT_MIGRATE }, { "Incremental", L_INCREMENTAL, JT_MIGRATE }, { "Differential", L_DIFFERENTIAL, JT_MIGRATE }, { " ", L_NONE, JT_ADMIN }, { " ", L_NONE, JT_RESTORE }, { NULL, 0, 0 } }; /* Keywords (RHS) permitted in Job type records * * type_name job_type */ struct s_jt jobtypes[] = { { "Backup", JT_BACKUP }, { "Admin", JT_ADMIN }, { "Verify", JT_VERIFY }, { "Restore", JT_RESTORE }, { "Migrate",JT_MIGRATE }, { "Copy", JT_COPY }, { NULL, 0 } }; /* Keywords (RHS) permitted in Protocol type records * * name token */ static struct s_kw backupprotocols[] = { { "Native", PT_NATIVE }, { "NDMP", PT_NDMP }, { NULL, 0 } }; /* Keywords (RHS) permitted in AuthProtocol type records * * name token */ static struct s_kw authprotocols[] = { { "Native", APT_NATIVE }, { "NDMPV2", APT_NDMPV2 }, { "NDMPV3", APT_NDMPV3 }, { "NDMPV4", APT_NDMPV4 }, { NULL, 0 } }; /* Keywords (RHS) permitted in Authentication type records * * name token */ static struct s_kw authmethods[] = { { "None", AT_NONE }, { "Clear", AT_CLEAR }, { "MD5", AT_MD5 }, { NULL, 0 } }; /* * Keywords (RHS) permitted in Selection type records * * type_name job_type */ static struct s_jt migtypes[] = { { "SmallestVolume", MT_SMALLEST_VOL }, { "OldestVolume", MT_OLDEST_VOL }, { "PoolOccupancy", MT_POOL_OCCUPANCY }, { "PoolTime", MT_POOL_TIME }, { "PoolUncopiedJobs", MT_POOL_UNCOPIED_JOBS }, { "Client", MT_CLIENT }, { "Volume", MT_VOLUME }, { "Job", MT_JOB }, { "SqlQuery", MT_SQLQUERY }, { NULL, 0 } }; /* * Options permitted in Restore replace= */ struct s_kw ReplaceOptions[] = { { "Always", REPLACE_ALWAYS }, { "IfNewer", REPLACE_IFNEWER }, { "IfOlder", REPLACE_IFOLDER }, { "Never", REPLACE_NEVER }, { NULL, 0 } }; /* * Options permited in ActionOnPurge= */ struct s_kw ActionOnPurgeOptions[] = { { "None", ON_PURGE_NONE }, { "Truncate", ON_PURGE_TRUNCATE }, { NULL, 0 } }; /* * Volume status allowed for a Volume. */ struct s_kw VolumeStatus[] = { { "Append", 0 }, { "Full", 0 }, { "Used", 0 }, { "Recycle", 0 }, { "Purged", 0 }, { "Cleaning", 0 }, { "Error", 0 }, { NULL, 0 } }; char *CATRES::display(POOLMEM *dst) { Mmsg(dst, "catalog=%s\ndb_name=%s\ndb_driver=%s\ndb_user=%s\n" "db_password=%s\ndb_address=%s\ndb_port=%i\n" "db_socket=%s\n", name(), NPRTB(db_name), NPRTB(db_driver), NPRTB(db_user), NPRTB(db_password.value), NPRTB(db_address), db_port, NPRTB(db_socket)); return dst; } static void indent_config_item(POOL_MEM &cfg_str, int level, const char *config_item) { for (int i = 0; i < level; i++) { pm_strcat(cfg_str, DEFAULT_INDENT_STRING); } pm_strcat(cfg_str, config_item); } static inline void print_config_runscript(RES_ITEM *item, POOL_MEM &cfg_str) { POOL_MEM temp; RUNSCRIPT* runscript; alist *list; list = *item->alistvalue; if (bstrcmp(item->name, "runscript")) { if (list != NULL) { foreach_alist(runscript, list) { int len; POOLMEM *cmdbuf; len = strlen(runscript->command); cmdbuf = get_pool_memory(PM_NAME); cmdbuf = check_pool_memory_size(cmdbuf, len * 2); escape_string(cmdbuf, runscript->command, len); /* * Don't print runscript when its inherited from a JobDef. */ if (runscript->from_jobdef) { continue; } /* * Check if runscript must be written as short runscript */ if (runscript->short_form) { if (runscript->when == SCRIPT_Before && /* runbeforejob */ (bstrcmp(runscript->target, ""))) { Mmsg(temp, "run before job = \"%s\"\n", cmdbuf); } else if (runscript->when == SCRIPT_After && /* runafterjob */ runscript->on_success && !runscript->on_failure && !runscript->fail_on_error && bstrcmp(runscript->target, "")) { Mmsg(temp, "run after job = \"%s\"\n", cmdbuf); } else if (runscript->when == SCRIPT_After && /* client run after job */ runscript->on_success && !runscript->on_failure && !runscript->fail_on_error && !bstrcmp(runscript->target, "")) { Mmsg(temp, "client run after job = \"%s\"\n", cmdbuf); } else if (runscript->when == SCRIPT_Before && /* client run before job */ !bstrcmp(runscript->target, "")) { Mmsg(temp, "before job = \"%s\"\n", cmdbuf); } else if (runscript->when == SCRIPT_After && /* run after failed job */ runscript->on_failure && !runscript->on_success && !runscript->fail_on_error && bstrcmp(runscript->target, "")) { Mmsg(temp, "run after failed job = \"%s\"\n", cmdbuf); } indent_config_item(cfg_str, 1, temp.c_str()); } else { Mmsg(temp, "runscript {\n"); indent_config_item(cfg_str, 1, temp.c_str()); char *cmdstring = (char *)"command"; /* '|' */ if (runscript->cmd_type == '@') { cmdstring = (char *)"console"; } Mmsg(temp, "%s = \"%s\"\n", cmdstring, cmdbuf); indent_config_item(cfg_str, 2, temp.c_str()); /* * Default: never */ char *when = (char *)"never"; switch (runscript->when) { case SCRIPT_Before: when = (char *)"before"; break; case SCRIPT_After: when = (char *)"after"; break; case SCRIPT_AfterVSS: when = (char *)"aftervss"; break; case SCRIPT_Any: when = (char *)"always"; break; } if (!bstrcmp(when, "never")) { /* suppress default value */ Mmsg(temp, "runswhen = %s\n", when); indent_config_item(cfg_str, 2, temp.c_str()); } /* * Default: fail_on_error = true */ char *fail_on_error = (char *)"Yes"; if (!runscript->fail_on_error){ fail_on_error = (char *)"No"; Mmsg(temp, "failonerror = %s\n", fail_on_error); indent_config_item(cfg_str, 2, temp.c_str()); } /* * Default: on_success = true */ char *run_on_success = (char *)"Yes"; if (!runscript->on_success){ run_on_success = (char *)"No"; Mmsg(temp, "runsonsuccess = %s\n", run_on_success); indent_config_item(cfg_str, 2, temp.c_str()); } /* * Default: on_failure = false */ char *run_on_failure = (char *)"No"; if (runscript->on_failure) { run_on_failure = (char *)"Yes"; Mmsg(temp, "runsonfailure = %s\n", run_on_failure); indent_config_item(cfg_str, 2, temp.c_str()); } /* level is not implemented Dmsg1(200, " level = %d\n", runscript->level); */ /* * Default: runsonclient = yes */ char *runsonclient = (char *)"Yes"; if (bstrcmp(runscript->target, "")) { runsonclient = (char *)"No"; Mmsg(temp, "runsonclient = %s\n", runsonclient); indent_config_item(cfg_str, 2, temp.c_str()); } indent_config_item(cfg_str, 1, "}\n"); } free_pool_memory(cmdbuf); } } /* foreach runscript */ } } static inline void print_config_run(RES_ITEM *item, POOL_MEM &cfg_str) { POOL_MEM temp; RUNRES *run; bool all_set; int i, nr_items; int interval_start; char *weekdays[] = { (char *)"Sun", (char *)"Mon", (char *)"Tue", (char *)"Wed", (char *)"Thu", (char *)"Fri", (char *)"Sat" }; char *months[] = { (char *)"Jan", (char *)"Feb", (char *)"Mar", (char *)"Apr", (char *)"May", (char *)"Jun", (char *)"Jul", (char *)"Aug", (char *)"Sep", (char *)"Oct", (char *)"Nov", (char *)"Dec" }; char *ordinals[] = { (char *)"1st", (char *)"2nd", (char *)"3rd", (char *)"4th", (char *)"5th" }; run = (RUNRES *)*(item->value); if (run != NULL) { while (run) { POOL_MEM run_str; /* holds the complete run= ... line */ POOL_MEM interval; /* is one entry of day/month/week etc. */ indent_config_item(cfg_str, 1, "run = "); /* * Overrides */ if (run->pool) { Mmsg(temp, "pool=\"%s\" ", run->pool->name()); pm_strcat(run_str, temp.c_str()); } if (run->full_pool) { Mmsg(temp, "fullpool=\"%s\" ", run->full_pool->name()); pm_strcat(run_str, temp.c_str()); } if (run->vfull_pool) { Mmsg(temp, "virtualfullpool=\"%s\" ", run->vfull_pool->name()); pm_strcat(run_str, temp.c_str()); } if (run->inc_pool) { Mmsg(temp, "incrementalpool=\"%s\" ", run->inc_pool->name()); pm_strcat(run_str, temp.c_str()); } if (run->diff_pool) { Mmsg(temp, "differentialpool=\"%s\" ", run->diff_pool->name()); pm_strcat(run_str, temp.c_str()); } if (run->next_pool) { Mmsg(temp, "nextpool=\"%s\" ", run->next_pool->name()); pm_strcat(run_str, temp.c_str()); } if (run->level) { for (int j = 0; joblevels[j].level_name; j++) { if (joblevels[j].level == run->level) { pm_strcat(run_str, joblevels[j].level_name); pm_strcat(run_str, " "); break; } } } if (run->storage) { Mmsg(temp, "storage=\"%s\" ", run->storage->name()); pm_strcat(run_str, temp.c_str()); } if (run->msgs) { Mmsg(temp, "messages=\"%s\" ", run->msgs->name()); pm_strcat(run_str, temp.c_str()); } if (run->Priority && run->Priority != 10) { Mmsg(temp, "priority=%d ", run->Priority); pm_strcat(run_str, temp.c_str()); } if (run->MaxRunSchedTime) { Mmsg(temp, "maxrunschedtime=%d ", run->MaxRunSchedTime); pm_strcat(run_str, temp.c_str()); } if (run->accurate) { /* * TODO: You cannot distinct if accurate was not set or if it was set to no * maybe we need an additional variable like "accurate_set". */ Mmsg(temp, "accurate=\"%s\" ","yes"); pm_strcat(run_str, temp.c_str()); } /* * Now the time specification */ /* * run->mday , output is just the number comma separated */ pm_strcpy(temp, ""); /* * First see if not all bits are set. */ all_set = true; nr_items = 31; for (i = 0; i < nr_items; i++) { if (!bit_is_set(i, run->mday)) { all_set = false; } } if (!all_set) { interval_start = -1; for (i = 0; i < nr_items; i++) { if (bit_is_set(i, run->mday)) { if (interval_start == -1) { /* bit is set and we are not in an interval */ interval_start = i; /* start an interval */ Dmsg1(200, "starting interval at %d\n", i + 1); Mmsg(interval, ",%d", i + 1); pm_strcat(temp, interval.c_str()); } } if (!bit_is_set(i, run->mday)) { if (interval_start != -1) { /* bit is unset and we are in an interval */ if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %d to %d\n", interval_start + 1, i); Mmsg(interval, "-%d", i); pm_strcat(temp, interval.c_str()); } interval_start = -1; /* end the interval */ } } } /* * See if we are still in an interval and the last bit is also set then the interval stretches to the last item. */ i = nr_items - 1; if (interval_start != -1 && bit_is_set(i, run->mday)) { if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %d to %d\n", interval_start + 1, i + 1); Mmsg(interval, "-%d", i + 1); pm_strcat(temp, interval.c_str()); } } pm_strcat(temp, " "); pm_strcat(run_str, temp.c_str() + 1); /* jump over first comma*/ } /* * run->wom output is 1st, 2nd... 5th comma separated * first, second, third... is also allowed * but we ignore that for now */ all_set = true; nr_items = 5; for (i = 0; i < nr_items; i++) { if (!bit_is_set(i, run->wom)) { all_set = false; } } if (!all_set) { interval_start = -1; pm_strcpy(temp, ""); for (i = 0; i < nr_items; i++) { if (bit_is_set(i, run->wom)) { if (interval_start == -1) { /* bit is set and we are not in an interval */ interval_start = i; /* start an interval */ Dmsg1(200, "starting interval at %s\n", ordinals[i]); Mmsg(interval, ",%s", ordinals[i]); pm_strcat(temp, interval.c_str()); } } if (!bit_is_set(i, run->wom)) { if (interval_start != -1) { /* bit is unset and we are in an interval */ if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %s to %s\n", ordinals[interval_start], ordinals[i - 1]); Mmsg(interval, "-%s", ordinals[i - 1]); pm_strcat(temp, interval.c_str()); } interval_start = -1; /* end the interval */ } } } /* * See if we are still in an interval and the last bit is also set then the interval stretches to the last item. */ i = nr_items - 1; if (interval_start != -1 && bit_is_set(i, run->wom)) { if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %s to %s\n", ordinals[interval_start], ordinals[i]); Mmsg(interval, "-%s", ordinals[i]); pm_strcat(temp, interval.c_str()); } } pm_strcat(temp, " "); pm_strcat(run_str, temp.c_str() + 1); /* jump over first comma*/ } /* * run->wday output is Sun, Mon, ..., Sat comma separated */ all_set = true; nr_items = 7; for (i = 0; i < nr_items; i++) { if (!bit_is_set(i, run->wday)) { all_set = false; } } if (!all_set) { interval_start = -1; pm_strcpy(temp, ""); for (i = 0; i < nr_items; i++) { if (bit_is_set(i, run->wday)) { if (interval_start == -1) { /* bit is set and we are not in an interval */ interval_start = i; /* start an interval */ Dmsg1(200, "starting interval at %s\n", weekdays[i]); Mmsg(interval, ",%s", weekdays[i]); pm_strcat(temp, interval.c_str()); } } if (!bit_is_set(i, run->wday)) { if (interval_start != -1) { /* bit is unset and we are in an interval */ if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %s to %s\n", weekdays[interval_start], weekdays[i - 1]); Mmsg(interval, "-%s", weekdays[i - 1]); pm_strcat(temp, interval.c_str()); } interval_start = -1; /* end the interval */ } } } /* * See if we are still in an interval and the last bit is also set then the interval stretches to the last item. */ i = nr_items - 1; if (interval_start != -1 && bit_is_set(i, run->wday)) { if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %s to %s\n", weekdays[interval_start], weekdays[i]); Mmsg(interval, "-%s", weekdays[i]); pm_strcat(temp, interval.c_str()); } } pm_strcat(temp, " "); pm_strcat(run_str, temp.c_str() + 1); /* jump over first comma*/ } /* * run->month output is Jan, Feb, ..., Dec comma separated */ all_set = true; nr_items = 12; for (i = 0; i < nr_items; i++) { if (!bit_is_set(i, run->month)) { all_set = false; } } if (!all_set) { interval_start = -1; pm_strcpy(temp, ""); for (i = 0; i < nr_items; i++) { if (bit_is_set(i, run->month)) { if (interval_start == -1) { /* bit is set and we are not in an interval */ interval_start = i; /* start an interval */ Dmsg1(200, "starting interval at %s\n", months[i]); Mmsg(interval, ",%s", months[i]); pm_strcat(temp, interval.c_str()); } } if (!bit_is_set(i, run->month)) { if (interval_start != -1) { /* bit is unset and we are in an interval */ if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %s to %s\n", months[interval_start], months[i - 1]); Mmsg(interval, "-%s", months[i - 1]); pm_strcat(temp, interval.c_str()); } interval_start = -1; /* end the interval */ } } } /* * See if we are still in an interval and the last bit is also set then the interval stretches to the last item. */ i = nr_items - 1; if (interval_start != -1 && bit_is_set(i, run->month)) { if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from %s to %s\n", months[interval_start], months[i]); Mmsg(interval, "-%s", months[i]); pm_strcat(temp, interval.c_str()); } } pm_strcat(temp, " "); pm_strcat(run_str, temp.c_str() + 1); /* jump over first comma*/ } /* * run->woy output is w00 - w53, comma separated */ all_set = true; nr_items = 54; for (i = 0; i < nr_items; i++) { if (!bit_is_set(i, run->woy)) { all_set = false; } } if (!all_set) { interval_start = -1; pm_strcpy(temp, ""); for (i = 0; i < nr_items; i++) { if (bit_is_set(i, run->woy)) { if (interval_start == -1) { /* bit is set and we are not in an interval */ interval_start = i; /* start an interval */ Dmsg1(200, "starting interval at w%02d\n", i); Mmsg(interval, ",w%02d", i); pm_strcat(temp, interval.c_str()); } } if (!bit_is_set(i, run->woy)) { if (interval_start != -1) { /* bit is unset and we are in an interval */ if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from w%02d to w%02d\n", interval_start, i - 1); Mmsg(interval, "-w%02d", i - 1); pm_strcat(temp, interval.c_str()); } interval_start = -1; /* end the interval */ } } } /* * See if we are still in an interval and the last bit is also set then the interval stretches to the last item. */ i = nr_items - 1; if (interval_start != -1 && bit_is_set(i, run->woy)) { if ((i - interval_start) > 1) { Dmsg2(200, "found end of interval from w%02d to w%02d\n", interval_start, i); Mmsg(interval, "-w%02d", i); pm_strcat(temp, interval.c_str()); } } pm_strcat(temp, " "); pm_strcat(run_str, temp.c_str() + 1); /* jump over first comma*/ } /* * run->hour output is HH:MM for hour and minute though its a bitfield. * only "hourly" sets all bits. */ pm_strcpy(temp, ""); for (i = 0; i < 24; i++) { if bit_is_set(i, run->hour) { Mmsg(temp, "at %02d:%02d\n", i, run->minute); pm_strcat(run_str, temp.c_str()); } } /* run->minute output is smply the minute in HH:MM */ pm_strcat(cfg_str, run_str.c_str()); run = run->next; } // loop over runs } } bool FILESETRES::print_config(POOL_MEM &buff, bool hide_sensitive_data) { POOL_MEM cfg_str; POOL_MEM temp; const char *p; Dmsg0(200,"FILESETRES::print_config\n"); Mmsg(temp, "FileSet {\n"); pm_strcat(cfg_str, temp.c_str()); Mmsg(temp, "Name = \"%s\"\n", this->name()); indent_config_item(cfg_str, 1, temp.c_str()); if (num_includes) { /* * Loop over all exclude blocks. */ for (int i = 0; i < num_includes; i++) { INCEXE *incexe = include_items[i]; Mmsg(temp, "Include {\n"); indent_config_item(cfg_str, 1, temp.c_str()); /* * Start options block */ if (incexe->num_opts > 0) { Mmsg(temp, "Options {\n"); indent_config_item(cfg_str, 2, temp.c_str()); for (int j = 0; j < incexe->num_opts; j++) { FOPTS *fo = incexe->opts_list[j]; bool enhanced_wild = false; for (int k = 0; fo->opts[k] != '\0'; k++) { if (fo->opts[k]=='W') { enhanced_wild = true; break; } } for (p = &fo->opts[0]; *p; p++) { switch (*p) { case '0': /* no option */ break; case 'a': /* alway replace */ indent_config_item(cfg_str, 3, "Replace = Always\n"); break; case 'C': /* */ indent_config_item(cfg_str, 3, "Accurate = "); p++; /* skip C */ for (; *p && *p != ':'; p++) { Mmsg(temp, "%c", *p); pm_strcat(cfg_str, temp.c_str()); } pm_strcat(cfg_str, "\n"); break; case 'c': indent_config_item(cfg_str, 3, "CheckFileChanges = yes\n"); break; case 'd': switch(*(p + 1)) { case '1': indent_config_item(cfg_str, 3, "Shadowing = LocalWarn\n"); p++; break; case '2': indent_config_item(cfg_str, 3, "Shadowing = LocalRemove\n"); p++; break; case '3': indent_config_item(cfg_str, 3, "Shadowing = GlobalWarn\n"); p++; break; case '4': indent_config_item(cfg_str, 3, "Shadowing = GlobalRemove\n"); p++; break; } break; case 'e': indent_config_item(cfg_str, 3, "Exclude = yes\n"); break; case 'f': indent_config_item(cfg_str, 3, "OneFS = no\n"); break; case 'h': /* no recursion */ indent_config_item(cfg_str, 3, "Recurse = no\n"); break; case 'H': /* no hard link handling */ indent_config_item(cfg_str, 3, "Hardlinks = no\n"); break; case 'i': indent_config_item(cfg_str, 3, "IgnoreCase = yes\n"); break; case 'J': /* Base Job */ indent_config_item(cfg_str, 3, "BaseJob = "); p++; /* skip J */ for (; *p && *p != ':'; p++) { Mmsg(temp, "%c", *p); pm_strcat(cfg_str, temp.c_str()); } pm_strcat(cfg_str, "\n"); break; case 'M': /* MD5 */ indent_config_item(cfg_str, 3, "Signature = MD5\n"); break; case 'n': indent_config_item(cfg_str, 3, "Replace = Never\n"); break; case 'p': /* use portable data format */ indent_config_item(cfg_str, 3, "Portable = Yes\n"); break; case 'P': /* strip path */ indent_config_item(cfg_str, 3, "Strip = "); p++; /* skip P */ for (; *p && *p != ':'; p++) { Mmsg(temp, "%c", *p); pm_strcat(cfg_str, temp.c_str()); } pm_strcat(cfg_str, "\n"); break; case 'R': /* Resource forks and Finder Info */ indent_config_item(cfg_str, 3, "HFSPlusSupport = Yes\n"); break; case 'r': /* read fifo */ indent_config_item(cfg_str, 3, "ReadFifo = Yes\n"); break; case 'S': switch(*(p + 1)) { #ifdef HAVE_SHA2 case '2': indent_config_item(cfg_str, 3, "Signature = SHA256\n"); p++; break; case '3': indent_config_item(cfg_str, 3, "Signature = SHA512\n"); p++; break; #endif default: indent_config_item(cfg_str, 3, "Signature = SHA1\n"); break; } break; case 's': indent_config_item(cfg_str, 3, "Sparse = Yes\n"); break; case 'm': indent_config_item(cfg_str, 3, "MtimeOnly = Yes\n"); break; case 'k': indent_config_item(cfg_str, 3, "KeepAtime = Yes\n"); break; case 'K': indent_config_item(cfg_str, 3, "NoAtime = Yes\n"); break; case 'A': indent_config_item(cfg_str, 3, "AclSupport = Yes\n"); break; case 'V': /* verify options */ indent_config_item(cfg_str, 3, "Verify = "); p++; /* skip V */ for (; *p && *p != ':'; p++) { Mmsg(temp, "%c", *p); pm_strcat(cfg_str, temp.c_str()); } pm_strcat(cfg_str, "\n"); break; case 'w': indent_config_item(cfg_str, 3, "Replace = IfNewer\n"); break; case 'W': indent_config_item(cfg_str, 3, "EnhancedWild = Yes\n"); break; case 'z': /* size */ indent_config_item(cfg_str, 3, "Size = "); p++; /* skip z */ for (; *p && *p != ':'; p++) { Mmsg(temp, "%c", *p); pm_strcat(cfg_str, temp.c_str()); } pm_strcat(cfg_str, "\n"); break; case 'Z': /* compression */ indent_config_item(cfg_str, 3, "Compression = "); p++; /* skip Z */ if (*p >= '0' && *p <= '9') { Mmsg(temp, "GZIP"); pm_strcat(cfg_str, temp.c_str()); Mmsg(temp, "%c\n", *p); pm_strcat(cfg_str, temp.c_str()); } else if (*p == 'o') { Mmsg(temp, "LZO\n"); pm_strcat(cfg_str, temp.c_str()); } else if (*p == 'f') { p++; if (*p == 'f') { Mmsg(temp, "LZFAST\n"); pm_strcat(cfg_str, temp.c_str()); } else if (*p == '4') { Mmsg(temp, "LZ4\n"); pm_strcat(cfg_str, temp.c_str()); } else if (*p == 'h') { Mmsg(temp, "LZ4HC\n"); pm_strcat(cfg_str, temp.c_str()); } } break; case 'X': indent_config_item(cfg_str, 3, "Xattr = Yes\n"); break; case 'x': indent_config_item(cfg_str, 3, "AutoExclude = No\n"); break; default: Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p); break; } } for (int k = 0; k < fo->regex.size(); k++) { Mmsg(temp, "Regex = \"%s\"\n", fo->regex.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->regexdir.size(); k++) { Mmsg(temp, "Regex Dir = \"%s\"\n", fo->regexdir.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->regexfile.size(); k++) { Mmsg(temp, "Regex File = \"%s\"\n", fo->regexfile.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->wild.size(); k++) { Mmsg(temp, "Wild = \"%s\"\n", fo->wild.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->wilddir.size(); k++) { Mmsg(temp, "Wild Dir = \"%s\"\n", fo->wilddir.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->wildfile.size(); k++) { Mmsg(temp, "Wild File = \"%s\"\n", fo->wildfile.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->wildbase.size(); k++) { Mmsg(temp, "Wild Base = \"%c %s\"\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->base.size(); k++) { Mmsg(temp, "Base = \"%s\"\n", fo->base.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->fstype.size(); k++) { Mmsg(temp, "Fs Type = \"%s\"\n", fo->fstype.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->drivetype.size(); k++) { Mmsg(temp, "Drive Type = \"%s\"\n", fo->drivetype.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } for (int k = 0; k < fo->meta.size(); k++) { Mmsg(temp, "Meta = \"%s\"\n", fo->meta.get(k)); indent_config_item(cfg_str, 3, temp.c_str()); } if (fo->plugin) { Mmsg(temp, "Plugin = \"%s\"\n", fo->plugin); indent_config_item(cfg_str, 3, temp.c_str()); } if (fo->reader) { Mmsg(temp, "Reader = \"%s\"\n", fo->reader); indent_config_item(cfg_str, 3, temp.c_str()); } if (fo->writer) { Mmsg(temp, "Writer = \"%s\"\n", fo->writer); indent_config_item(cfg_str, 3, temp.c_str()); } } if (incexe->num_opts > 0) { indent_config_item(cfg_str, 2, "}\n"); } } /* end options block */ /* * File = entries. */ if (incexe->name_list.size()) { for (int l = 0; l < incexe->name_list.size(); l++) { Mmsg(temp, "File = \"%s\"\n", incexe->name_list.get(l)); indent_config_item(cfg_str, 2, temp.c_str()); } } /* * Plugin = entries. */ if (incexe->plugin_list.size()) { for (int l = 0; l < incexe->plugin_list.size(); l++) { Mmsg(temp, "Plugin = %s\n", incexe->plugin_list.get(l)); indent_config_item(cfg_str, 2, temp.c_str()); } } /* * Exclude Dir Containing = entry. */ if (incexe->ignoredir.size()) { for (int l = 0; l < incexe->ignoredir.size(); l++) { Mmsg(temp, "Exclude Dir Containing = \"%s\"\n", incexe->ignoredir.get(l)); indent_config_item(cfg_str, 2, temp.c_str()); } } indent_config_item(cfg_str, 1, "}\n"); /* * End Include block */ } /* loop over all include blocks */ } if (num_excludes) { /* * Loop over all exclude blocks. */ for (int j = 0; j < num_excludes; j++) { INCEXE *incexe = exclude_items[j]; if (incexe->name_list.size()) { indent_config_item(cfg_str, 1, "Exclude {\n"); for (int k = 0; k < incexe->name_list.size(); k++) { Mmsg(temp, "File = \"%s\"\n", incexe->name_list.get(k)); indent_config_item(cfg_str, 2, temp.c_str()); } indent_config_item(cfg_str, 1, "}\n"); } } /* loop over all exclude blocks */ } pm_strcat(cfg_str, "}\n\n"); pm_strcat(buff, cfg_str.c_str()); return true; } const char *auth_protocol_to_str(uint32_t auth_protocol) { for (int i = 0; authprotocols[i].name; i++) { if (authprotocols[i].token == auth_protocol) { return authprotocols[i].name; } } return "Unknown"; } const char *level_to_str(int level) { static char level_no[30]; const char *str = level_no; bsnprintf(level_no, sizeof(level_no), "%c (%d)", level, level); /* default if not found */ for (int i = 0; joblevels[i].level_name; i++) { if (level == (int)joblevels[i].level) { str = joblevels[i].level_name; break; } } return str; } /* * Dump contents of resource */ void dump_resource(int type, RES *ures, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { URES *res = (URES *)ures; bool recurse = true; POOL_MEM buf; UAContext *ua = (UAContext *)sock; if (res == NULL) { sendit(sock, _("No %s resource defined\n"), res_to_str(type)); return; } if (type < 0) { /* no recursion */ type = -type; recurse = false; } switch (type) { case R_DIRECTOR: res->res_dir.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_PROFILE: res->res_profile.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_CONSOLE: res->res_con.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_COUNTER: res->res_counter.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_CLIENT: if (!ua || acl_access_ok(ua, Client_ACL, res->res_client.hdr.name)) { res->res_client.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_DEVICE: res->res_dev.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; case R_STORAGE: if (!ua || acl_access_ok(ua, Storage_ACL, res->res_store.hdr.name)) { res->res_store.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_CATALOG: if (!ua || acl_access_ok(ua, Catalog_ACL, res->res_cat.hdr.name)) { res->res_cat.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_JOBDEFS: case R_JOB: if (!ua || acl_access_ok(ua, Job_ACL, res->res_job.hdr.name)) { res->res_job.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_FILESET: { if (!ua || acl_access_ok(ua, FileSet_ACL, res->res_fs.hdr.name)) { res->res_fs.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; } case R_SCHEDULE: if (!ua || acl_access_ok(ua, Schedule_ACL, res->res_sch.hdr.name)) { res->res_sch.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_POOL: if (!ua || acl_access_ok(ua, Pool_ACL, res->res_pool.hdr.name)) { res->res_pool.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); } break; case R_MSGS: res->res_msgs.print_config(buf, hide_sensitive_data); sendit(sock, "%s", buf.c_str()); break; default: sendit(sock, _("Unknown resource type %d in dump_resource.\n"), type); break; } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } } /* * Free all the members of an INCEXE structure */ static void free_incexe(INCEXE *incexe) { incexe->name_list.destroy(); incexe->plugin_list.destroy(); for (int i = 0; i < incexe->num_opts; i++) { FOPTS *fopt = incexe->opts_list[i]; fopt->regex.destroy(); fopt->regexdir.destroy(); fopt->regexfile.destroy(); fopt->wild.destroy(); fopt->wilddir.destroy(); fopt->wildfile.destroy(); fopt->wildbase.destroy(); fopt->base.destroy(); fopt->fstype.destroy(); fopt->drivetype.destroy(); fopt->meta.destroy(); if (fopt->plugin) { free(fopt->plugin); } if (fopt->reader) { free(fopt->reader); } if (fopt->writer) { free(fopt->writer); } free(fopt); } if (incexe->opts_list) { free(incexe->opts_list); } incexe->ignoredir.destroy(); free(incexe); } /* * Free memory of resource -- called when daemon terminates. * NB, we don't need to worry about freeing any references * to other resources as they will be freed when that * resource chain is traversed. Mainly we worry about freeing * allocated strings (names). */ void free_resource(RES *sres, int type) { int num; RES *nres; /* next resource if linked */ URES *res = (URES *)sres; if (res == NULL) return; /* * Common stuff -- free the resource name and description */ nres = (RES *)res->res_dir.hdr.next; if (res->res_dir.hdr.name) { free(res->res_dir.hdr.name); } if (res->res_dir.hdr.desc) { free(res->res_dir.hdr.desc); } switch (type) { case R_DIRECTOR: if (res->res_dir.working_directory) { free(res->res_dir.working_directory); } if (res->res_dir.scripts_directory) { free(res->res_dir.scripts_directory); } if (res->res_dir.plugin_directory) { free(res->res_dir.plugin_directory); } if (res->res_dir.plugin_names) { delete res->res_dir.plugin_names; } if (res->res_dir.pid_directory) { free(res->res_dir.pid_directory); } if (res->res_dir.subsys_directory) { free(res->res_dir.subsys_directory); } if (res->res_dir.backend_directories) { delete res->res_dir.backend_directories; } if (res->res_dir.password.value) { free(res->res_dir.password.value); } if (res->res_dir.query_file) { free(res->res_dir.query_file); } if (res->res_dir.DIRaddrs) { free_addresses(res->res_dir.DIRaddrs); } if (res->res_dir.DIRsrc_addr) { free_addresses(res->res_dir.DIRsrc_addr); } if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } if (res->res_dir.tls_ca_certfile) { free(res->res_dir.tls_ca_certfile); } if (res->res_dir.tls_ca_certdir) { free(res->res_dir.tls_ca_certdir); } if (res->res_dir.tls_crlfile) { free(res->res_dir.tls_crlfile); } if (res->res_dir.tls_certfile) { free(res->res_dir.tls_certfile); } if (res->res_dir.tls_keyfile) { free(res->res_dir.tls_keyfile); } if (res->res_dir.tls_dhfile) { free(res->res_dir.tls_dhfile); } if (res->res_dir.tls_allowed_cns) { delete res->res_dir.tls_allowed_cns; } if (res->res_dir.verid) { free(res->res_dir.verid); } if (res->res_dir.keyencrkey.value) { free(res->res_dir.keyencrkey.value); } if (res->res_dir.audit_events) { delete res->res_dir.audit_events; } break; case R_DEVICE: case R_COUNTER: break; case R_PROFILE: for (int i = 0; i < Num_ACL; i++) { if (res->res_profile.ACL_lists[i]) { delete res->res_profile.ACL_lists[i]; res->res_profile.ACL_lists[i] = NULL; } } break; case R_CONSOLE: if (res->res_con.password.value) { free(res->res_con.password.value); } if (res->res_con.tls_ctx) { free_tls_context(res->res_con.tls_ctx); } if (res->res_con.tls_ca_certfile) { free(res->res_con.tls_ca_certfile); } if (res->res_con.tls_ca_certdir) { free(res->res_con.tls_ca_certdir); } if (res->res_con.tls_crlfile) { free(res->res_con.tls_crlfile); } if (res->res_con.tls_certfile) { free(res->res_con.tls_certfile); } if (res->res_con.tls_keyfile) { free(res->res_con.tls_keyfile); } if (res->res_con.tls_dhfile) { free(res->res_con.tls_dhfile); } if (res->res_con.tls_allowed_cns) { delete res->res_con.tls_allowed_cns; } if (res->res_con.profiles) { delete res->res_con.profiles; } for (int i = 0; i < Num_ACL; i++) { if (res->res_con.ACL_lists[i]) { delete res->res_con.ACL_lists[i]; res->res_con.ACL_lists[i] = NULL; } } break; case R_CLIENT: if (res->res_client.address) { free(res->res_client.address); } if (res->res_client.username) { free(res->res_client.username); } if (res->res_client.password.value) { free(res->res_client.password.value); } if (res->res_client.tls_ctx) { free_tls_context(res->res_client.tls_ctx); } if (res->res_client.tls_ca_certfile) { free(res->res_client.tls_ca_certfile); } if (res->res_client.tls_ca_certdir) { free(res->res_client.tls_ca_certdir); } if (res->res_client.tls_crlfile) { free(res->res_client.tls_crlfile); } if (res->res_client.tls_certfile) { free(res->res_client.tls_certfile); } if (res->res_client.tls_keyfile) { free(res->res_client.tls_keyfile); } if (res->res_client.tls_allowed_cns) { delete res->res_client.tls_allowed_cns; } break; case R_STORAGE: if (res->res_store.address) { free(res->res_store.address); } if (res->res_store.username) { free(res->res_store.username); } if (res->res_store.password.value) { free(res->res_store.password.value); } if (res->res_store.media_type) { free(res->res_store.media_type); } if (res->res_store.device) { delete res->res_store.device; } if (res->res_store.tls_ctx) { free_tls_context(res->res_store.tls_ctx); } if (res->res_store.tls_ca_certfile) { free(res->res_store.tls_ca_certfile); } if (res->res_store.tls_ca_certdir) { free(res->res_store.tls_ca_certdir); } if (res->res_store.tls_crlfile) { free(res->res_store.tls_crlfile); } if (res->res_store.tls_certfile) { free(res->res_store.tls_certfile); } if (res->res_store.tls_keyfile) { free(res->res_store.tls_keyfile); } break; case R_CATALOG: if (res->res_cat.db_address) { free(res->res_cat.db_address); } if (res->res_cat.db_socket) { free(res->res_cat.db_socket); } if (res->res_cat.db_user) { free(res->res_cat.db_user); } if (res->res_cat.db_name) { free(res->res_cat.db_name); } if (res->res_cat.db_driver) { free(res->res_cat.db_driver); } if (res->res_cat.db_password.value) { free(res->res_cat.db_password.value); } break; case R_FILESET: if ((num=res->res_fs.num_includes)) { while (--num >= 0) { free_incexe(res->res_fs.include_items[num]); } free(res->res_fs.include_items); } res->res_fs.num_includes = 0; if ((num=res->res_fs.num_excludes)) { while (--num >= 0) { free_incexe(res->res_fs.exclude_items[num]); } free(res->res_fs.exclude_items); } res->res_fs.num_excludes = 0; break; case R_POOL: if (res->res_pool.pool_type) { free(res->res_pool.pool_type); } if (res->res_pool.label_format) { free(res->res_pool.label_format); } if (res->res_pool.cleaning_prefix) { free(res->res_pool.cleaning_prefix); } if (res->res_pool.storage) { delete res->res_pool.storage; } break; case R_SCHEDULE: if (res->res_sch.run) { RUNRES *nrun, *next; nrun = res->res_sch.run; while (nrun) { next = nrun->next; free(nrun); nrun = next; } } break; case R_JOBDEFS: case R_JOB: if (res->res_job.backup_format) { free(res->res_job.backup_format); } if (res->res_job.RestoreWhere) { free(res->res_job.RestoreWhere); } if (res->res_job.RegexWhere) { free(res->res_job.RegexWhere); } if (res->res_job.strip_prefix) { free(res->res_job.strip_prefix); } if (res->res_job.add_prefix) { free(res->res_job.add_prefix); } if (res->res_job.add_suffix) { free(res->res_job.add_suffix); } if (res->res_job.RestoreBootstrap) { free(res->res_job.RestoreBootstrap); } if (res->res_job.WriteBootstrap) { free(res->res_job.WriteBootstrap); } if (res->res_job.WriteVerifyList) { free(res->res_job.WriteVerifyList); } if (res->res_job.selection_pattern) { free(res->res_job.selection_pattern); } if (res->res_job.run_cmds) { delete res->res_job.run_cmds; } if (res->res_job.storage) { delete res->res_job.storage; } if (res->res_job.FdPluginOptions) { delete res->res_job.FdPluginOptions; } if (res->res_job.SdPluginOptions) { delete res->res_job.SdPluginOptions; } if (res->res_job.DirPluginOptions) { delete res->res_job.DirPluginOptions; } if (res->res_job.base) { delete res->res_job.base; } if (res->res_job.RunScripts) { free_runscripts(res->res_job.RunScripts); delete res->res_job.RunScripts; } break; case R_MSGS: if (res->res_msgs.mail_cmd) { free(res->res_msgs.mail_cmd); } if (res->res_msgs.operator_cmd) { free(res->res_msgs.operator_cmd); } free_msgs_res((MSGSRES *)res); /* free message resource */ res = NULL; break; default: printf(_("Unknown resource type %d in free_resource.\n"), type); } /* * Common stuff again -- free the resource, recurse to next one */ if (res) { free(res); } if (nres) { free_resource(nres, type); } } /* * Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * pointers because they may not have been defined until * later in pass 1. */ void save_resource(int type, RES_ITEM *items, int pass) { URES *res; int rindex = type - R_FIRST; bool error = false; /* * Check Job requirements after applying JobDefs */ if (type != R_JOBDEFS && type != R_JOB) { /* * Ensure that all required items are present */ for (int i = 0; items[i].name; i++) { if (items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ERROR_TERM, 0, _("%s item is required in %s resource, but not found.\n"), items[i].name, resources[rindex]); } } /* * If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]); } } } else if (type == R_JOB) { /* * Ensure that the name item is present */ if (items[0].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(0, res_all.res_dir.hdr.item_present)) { Emsg2(M_ERROR_TERM, 0, _("%s item is required in %s resource, but not found.\n"), items[0].name, resources[rindex]); } } } /* * During pass 2 in each "store" routine, we looked up pointers * to all the resources referrenced in the current resource, now we * must copy their addresses from the static record to the allocated * record. */ if (pass == 2) { switch (type) { case R_PROFILE: case R_CATALOG: case R_MSGS: case R_FILESET: case R_DEVICE: /* * Resources not containing a resource */ break; case R_POOL: /* * Resources containing another resource or alist. First * look up the resource which contains another resource. It * was written during pass 1. Then stuff in the pointers to * the resources it contains, which were inserted this pass. * Finally, it will all be stored back. * * Find resource saved in pass 1 */ if ((res = (URES *)GetResWithName(R_POOL, res_all.res_con.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Pool resource %s\n"), res_all.res_con.hdr.name); } else { /* * Explicitly copy resource pointers from this pass (res_all) */ res->res_pool.NextPool = res_all.res_pool.NextPool; res->res_pool.RecyclePool = res_all.res_pool.RecyclePool; res->res_pool.ScratchPool = res_all.res_pool.ScratchPool; res->res_pool.storage = res_all.res_pool.storage; if (res_all.res_pool.catalog || !res->res_pool.use_catalog) { res->res_pool.catalog = res_all.res_pool.catalog; } } break; case R_CONSOLE: if ((res = (URES *)GetResWithName(R_CONSOLE, res_all.res_con.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Console resource %s\n"), res_all.res_con.hdr.name); } else { res->res_con.tls_allowed_cns = res_all.res_con.tls_allowed_cns; res->res_con.profiles = res_all.res_con.profiles; } break; case R_DIRECTOR: if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Director resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_dir.plugin_names = res_all.res_dir.plugin_names; res->res_dir.messages = res_all.res_dir.messages; res->res_dir.backend_directories = res_all.res_dir.backend_directories; res->res_dir.tls_allowed_cns = res_all.res_dir.tls_allowed_cns; } break; case R_STORAGE: if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Storage resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_store.paired_storage = res_all.res_store.paired_storage; /* * We must explicitly copy the device alist pointer */ res->res_store.device = res_all.res_store.device; } break; case R_JOBDEFS: case R_JOB: if ((res = (URES *)GetResWithName(type, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Job resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_job.messages = res_all.res_job.messages; res->res_job.schedule = res_all.res_job.schedule; res->res_job.client = res_all.res_job.client; res->res_job.fileset = res_all.res_job.fileset; res->res_job.storage = res_all.res_job.storage; res->res_job.catalog = res_all.res_job.catalog; res->res_job.FdPluginOptions = res_all.res_job.FdPluginOptions; res->res_job.SdPluginOptions = res_all.res_job.SdPluginOptions; res->res_job.DirPluginOptions = res_all.res_job.DirPluginOptions; res->res_job.base = res_all.res_job.base; res->res_job.pool = res_all.res_job.pool; res->res_job.full_pool = res_all.res_job.full_pool; res->res_job.vfull_pool = res_all.res_job.vfull_pool; res->res_job.inc_pool = res_all.res_job.inc_pool; res->res_job.diff_pool = res_all.res_job.diff_pool; res->res_job.next_pool = res_all.res_job.next_pool; res->res_job.verify_job = res_all.res_job.verify_job; res->res_job.jobdefs = res_all.res_job.jobdefs; res->res_job.run_cmds = res_all.res_job.run_cmds; res->res_job.RunScripts = res_all.res_job.RunScripts; /* * TODO: JobDefs where/regexwhere doesn't work well (but this is not very useful) * We have to set_bit(index, res_all.hdr.item_present); or something like that * * We take RegexWhere before all other options */ if (!res->res_job.RegexWhere && (res->res_job.strip_prefix || res->res_job.add_suffix || res->res_job.add_prefix)) { int len = bregexp_get_build_where_size(res->res_job.strip_prefix, res->res_job.add_prefix, res->res_job.add_suffix); res->res_job.RegexWhere = (char *) bmalloc (len * sizeof(char)); bregexp_build_where(res->res_job.RegexWhere, len, res->res_job.strip_prefix, res->res_job.add_prefix, res->res_job.add_suffix); /* * TODO: test bregexp */ } if (res->res_job.RegexWhere && res->res_job.RestoreWhere) { free(res->res_job.RestoreWhere); res->res_job.RestoreWhere = NULL; } } break; case R_COUNTER: if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Counter resource %s\n"), res_all.res_counter.hdr.name); } else { res->res_counter.Catalog = res_all.res_counter.Catalog; res->res_counter.WrapCounter = res_all.res_counter.WrapCounter; } break; case R_CLIENT: if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Client resource %s\n"), res_all.res_client.hdr.name); } else { if (res_all.res_client.catalog) { res->res_client.catalog = res_all.res_client.catalog; } else { /* * No catalog overwrite given use the first catalog definition. */ res->res_client.catalog = (CATRES *)GetNextRes(R_CATALOG, NULL); } res->res_client.tls_allowed_cns = res_all.res_client.tls_allowed_cns; } break; case R_SCHEDULE: /* * Schedule is a bit different in that it contains a RUNRES record * chain which isn't a "named" resource. This chain was linked * in by run_conf.c during pass 2, so here we jam the pointer * into the Schedule resource. */ if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Schedule resource %s\n"), res_all.res_client.hdr.name); } else { res->res_sch.run = res_all.res_sch.run; } break; default: Emsg1(M_ERROR, 0, _("Unknown resource type %d in save_resource.\n"), type); error = true; break; } /* * Note, the resource name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { free(res_all.res_dir.hdr.name); res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { free(res_all.res_dir.hdr.desc); res_all.res_dir.hdr.desc = NULL; } return; } /* * Common */ if (!error) { res = (URES *)malloc(resources[rindex].size); memcpy(res, &res_all, resources[rindex].size); if (!res_head[rindex]) { res_head[rindex] = (RES *)res; /* store first entry */ Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(type), res->res_dir.hdr.name, rindex); } else { RES *next, *last; if (res->res_dir.hdr.name == NULL) { Emsg1(M_ERROR_TERM, 0, _("Name item is required in %s resource, but not found.\n"), resources[rindex]); } /* * Add new res to end of chain */ for (last = next = res_head[rindex]; next; next = next->next) { last = next; if (bstrcmp(next->name, res->res_dir.hdr.name)) { Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), resources[rindex].name, res->res_dir.hdr.name); } } last->next = (RES *)res; Dmsg4(900, _("Inserting %s res: %s index=%d pass=%d\n"), res_to_str(type), res->res_dir.hdr.name, rindex, pass); } } } bool populate_jobdefs() { JOBRES *job; bool retval = true; foreach_res(job, R_JOB) { if (job->jobdefs) { JOBRES *jobdefs = job->jobdefs; /* * Handle Storage alists specifically */ if (jobdefs->storage && !job->storage) { STORERES *store; job->storage = New(alist(10, not_owned_by_alist)); foreach_alist(store, jobdefs->storage) { job->storage->append(store); } } /* * Handle RunScripts alists specifically */ if (jobdefs->RunScripts) { RUNSCRIPT *rs, *elt; if (!job->RunScripts) { job->RunScripts = New(alist(10, not_owned_by_alist)); } foreach_alist(rs, jobdefs->RunScripts) { elt = copy_runscript(rs); elt->from_jobdef = true; job->RunScripts->append(elt); /* we have to free it */ } } /* * Transfer default items from JobDefs Resource */ for (int i = 0; job_items[i].name; i++) { char **def_svalue, **svalue; /* string value */ uint32_t *def_ivalue, *ivalue; /* integer value */ bool *def_bvalue, *bvalue; /* bool value */ int64_t *def_lvalue, *lvalue; /* 64 bit values */ uint32_t offset; Dmsg4(1400, "Job \"%s\", field \"%s\" bit=%d def=%d\n", job->name(), job_items[i].name, bit_is_set(i, job->hdr.item_present), bit_is_set(i, jobdefs->hdr.item_present)); if (!bit_is_set(i, job->hdr.item_present) && bit_is_set(i, jobdefs->hdr.item_present)) { Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n", job->name(), job_items[i].name); offset = (char *)(job_items[i].value) - (char *)&res_all; switch (job_items[i].type) { case CFG_TYPE_STR: case CFG_TYPE_DIR: /* * Handle strings and directory strings */ def_svalue = (char **)((char *)(jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n", job->name(), job_items[i].name, *def_svalue, i, offset); svalue = (char **)((char *)job + offset); if (*svalue) { free(*svalue); } *svalue = bstrdup(*def_svalue); set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); break; case CFG_TYPE_RES: /* * Handle resources */ def_svalue = (char **)((char *)(jobdefs) + offset); Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n", job->name(), job_items[i].name, i, offset); svalue = (char **)((char *)job + offset); if (*svalue) { Pmsg1(000, _("Hey something is wrong. p=0x%lu\n"), *svalue); } *svalue = *def_svalue; set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); break; case CFG_TYPE_ALIST_STR: { const char *str; alist *orig_list, **new_list; /* * Handle alist strings */ orig_list = *(alist **)((char *)(jobdefs) + offset); /* * See if there is anything on the list. */ if (orig_list && orig_list->size()) { new_list = (alist **)((char *)(job) + offset); if (!*new_list) { *new_list = New(alist(10, owned_by_alist)); } foreach_alist(str, orig_list) { (*new_list)->append(bstrdup(str)); } set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); } break; } case CFG_TYPE_ALIST_RES: /* * Handle alist resources */ if (bit_is_set(i, jobdefs->hdr.item_present)) { set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); } break; case CFG_TYPE_BIT: case CFG_TYPE_PINT32: case CFG_TYPE_JOBTYPE: case CFG_TYPE_PROTOCOLTYPE: case CFG_TYPE_LEVEL: case CFG_TYPE_INT32: case CFG_TYPE_SIZE32: case CFG_TYPE_MIGTYPE: case CFG_TYPE_REPLACE: /* * Handle integer fields * Note, our store_bit does not handle bitmaped fields */ def_ivalue = (uint32_t *)((char *)(jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n", job->name(), job_items[i].name, *def_ivalue, i, offset); ivalue = (uint32_t *)((char *)job + offset); *ivalue = *def_ivalue; set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); break; case CFG_TYPE_TIME: case CFG_TYPE_SIZE64: case CFG_TYPE_INT64: case CFG_TYPE_SPEED: /* * Handle 64 bit integer fields */ def_lvalue = (int64_t *)((char *)(jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n", job->name(), job_items[i].name, *def_lvalue, i, offset); lvalue = (int64_t *)((char *)job + offset); *lvalue = *def_lvalue; set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); break; case CFG_TYPE_BOOL: /* * Handle bool fields */ def_bvalue = (bool *)((char *)(jobdefs) + offset); Dmsg5(400, "Job \"%s\", field \"%s\" def_bvalue=%d item %d offset=%u\n", job->name(), job_items[i].name, *def_bvalue, i, offset); bvalue = (bool *)((char *)job + offset); *bvalue = *def_bvalue; set_bit(i, job->hdr.item_present); set_bit(i, job->hdr.inherit_content); break; default: break; } } } } /* * Ensure that all required items are present */ for (int i = 0; job_items[i].name; i++) { if (job_items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, job->hdr.item_present)) { Jmsg(NULL, M_ERROR_TERM, 0, _("\"%s\" directive in Job \"%s\" resource is required, but not found.\n"), job_items[i].name, job->name()); retval = false; goto bail_out; } } /* * If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { Emsg0(M_ERROR_TERM, 0, _("Too many items in Job resource\n")); goto bail_out; } } /* * For Copy and Migrate we can have Jobs without a client or fileset. * As for a copy we use the original Job as a reference for the Read storage * we also don't need to check if there is an explicit storage definition in * either the Job or the Read pool. */ switch (job->JobType) { case JT_COPY: case JT_MIGRATE: break; default: /* * All others must have a client and fileset. */ if (!job->client) { Jmsg(NULL, M_ERROR_TERM, 0, _("\"client\" directive in Job \"%s\" resource is required, but not found.\n"), job->name()); retval = false; goto bail_out; } if (!job->fileset) { Jmsg(NULL, M_ERROR_TERM, 0, _("\"fileset\" directive in Job \"%s\" resource is required, but not found.\n"), job->name()); retval = false; goto bail_out; } if (!job->storage && !job->pool->storage) { Jmsg(NULL, M_FATAL, 0, _("No storage specified in Job \"%s\" nor in Pool.\n"), job->name()); retval = false; goto bail_out; } break; } } /* End loop over Job res */ bail_out: return retval; } static void store_actiononpurge(LEX *lc, RES_ITEM *item, int index, int pass) { int i; uint32_t *destination = item->ui32value; lex_get_token(lc, T_NAME); /* * Scan ActionOnPurge options */ for (i = 0; ActionOnPurgeOptions[i].name; i++) { if (bstrcasecmp(lc->str, ActionOnPurgeOptions[i].name)) { *destination = (*destination) | ActionOnPurgeOptions[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected an Action On Purge option, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store Device. Note, the resource is created upon the * first reference. The details of the resource are obtained * later from the SD. */ static void store_device(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res; int rindex = R_DEVICE - R_FIRST; bool found = false; if (pass == 1) { lex_get_token(lc, T_NAME); if (!res_head[rindex]) { res = (URES *)malloc(resources[rindex].size); memset(res, 0, resources[rindex].size); res->res_dev.hdr.name = bstrdup(lc->str); res_head[rindex] = (RES *)res; /* store first entry */ Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(R_DEVICE), res->res_dir.hdr.name, rindex); } else { RES *next; /* * See if it is already defined */ for (next = res_head[rindex]; next->next; next = next->next) { if (bstrcmp(next->name, lc->str)) { found = true; break; } } if (!found) { res = (URES *)malloc(resources[rindex].size); memset(res, 0, resources[rindex].size); res->res_dev.hdr.name = bstrdup(lc->str); next->next = (RES *)res; Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(R_DEVICE), res->res_dir.hdr.name, rindex, pass); } } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } else { store_resource(CFG_TYPE_ALIST_RES, lc, item, index, pass); } } /* * Store Migration/Copy type */ static void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the type both pass 1 and pass 2 */ for (i = 0; migtypes[i].type_name; i++) { if (bstrcasecmp(lc->str, migtypes[i].type_name)) { *(item->ui32value) = migtypes[i].job_type; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Migration Job Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store JobType (backup, verify, restore) */ static void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the type both pass 1 and pass 2 */ for (i = 0; jobtypes[i].type_name; i++) { if (bstrcasecmp(lc->str, jobtypes[i].type_name)) { *(item->ui32value) = jobtypes[i].job_type; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Job Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store Protocol (Native, NDMP) */ static void store_protocoltype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the type both pass 1 and pass 2 */ for (i = 0; backupprotocols[i].name; i++) { if (bstrcasecmp(lc->str, backupprotocols[i].name)) { *(item->ui32value) = backupprotocols[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Protocol Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } static void store_replace(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Scan Replacement options */ for (i = 0; ReplaceOptions[i].name; i++) { if (bstrcasecmp(lc->str, ReplaceOptions[i].name)) { *(item->ui32value) = ReplaceOptions[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Restore replacement option, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store Auth Protocol (Native, NDMPv2, NDMPv3, NDMPv4) */ static void store_authprotocoltype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the type both pass 1 and pass 2 */ for (i = 0; authprotocols[i].name; i++) { if (bstrcasecmp(lc->str, authprotocols[i].name)) { *(item->ui32value) = authprotocols[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Auth Protocol Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store authentication type (Mostly for NDMP like clear or MD5). */ static void store_authtype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the type both pass 1 and pass 2 */ for (i = 0; authmethods[i].name; i++) { if (bstrcasecmp(lc->str, authmethods[i].name)) { *(item->ui32value) = authmethods[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Authentication Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store Job Level (Full, Incremental, ...) */ static void store_level(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the level pass 2 so that type is defined */ for (i = 0; joblevels[i].level_name; i++) { if (bstrcasecmp(lc->str, joblevels[i].level_name)) { *(item->ui32value) = joblevels[i].level; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Job Level keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store password either clear if for NDMP and catalog or MD5 hashed for native. */ static void store_autopassword(LEX *lc, RES_ITEM *item, int index, int pass) { switch (res_all.hdr.rcode) { case R_DIRECTOR: /* * As we need to store both clear and MD5 hashed within the same * resource class we use the item->code as a hint default is 0 * and for clear we need a code of 1. */ switch (item->code) { case 1: store_resource(CFG_TYPE_CLEARPASSWORD, lc, item, index, pass); break; default: store_resource(CFG_TYPE_MD5PASSWORD, lc, item, index, pass); break; } break; case R_CLIENT: switch (res_all.res_client.Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: store_resource(CFG_TYPE_CLEARPASSWORD, lc, item, index, pass); break; default: store_resource(CFG_TYPE_MD5PASSWORD, lc, item, index, pass); break; } break; case R_STORAGE: switch (res_all.res_store.Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: store_resource(CFG_TYPE_CLEARPASSWORD, lc, item, index, pass); break; default: store_resource(CFG_TYPE_MD5PASSWORD, lc, item, index, pass); break; } break; case R_CATALOG: store_resource(CFG_TYPE_CLEARPASSWORD, lc, item, index, pass); break; default: store_resource(CFG_TYPE_MD5PASSWORD, lc, item, index, pass); break; } } /* * Store ACL (access control list) */ static void store_acl(LEX *lc, RES_ITEM *item, int index, int pass) { int token; alist *list; if (pass == 1) { if (!item->alistvalue[item->code]) { item->alistvalue[item->code] = New(alist(10, owned_by_alist)); Dmsg1(900, "Defined new ACL alist at %d\n", item->code); } } list = item->alistvalue[item->code]; for (;;) { lex_get_token(lc, T_STRING); if (pass == 1) { list->append(bstrdup(lc->str)); Dmsg2(900, "Appended to %d %s\n", item->code, lc->str); } token = lex_get_token(lc, T_ALL); if (token == T_COMMA) { continue; /* get another ACL */ } break; } set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store Audit event. */ static void store_audit(LEX *lc, RES_ITEM *item, int index, int pass) { int token; alist *list; if (pass == 1) { if (!*item->alistvalue) { *(item->alistvalue) = New(alist(10, owned_by_alist)); } } list = *item->alistvalue; for (;;) { lex_get_token(lc, T_STRING); if (pass == 1) { list->append(bstrdup(lc->str)); } token = lex_get_token(lc, T_ALL); if (token == T_COMMA) { continue; } break; } set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store a runscript->when in a bit field */ static void store_runscript_when(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); if (bstrcasecmp(lc->str, "before")) { *(item->ui32value) = SCRIPT_Before; } else if (bstrcasecmp(lc->str, "after")) { *(item->ui32value) = SCRIPT_After; } else if (bstrcasecmp(lc->str, "aftervss")) { *(item->ui32value) = SCRIPT_AfterVSS; } else if (bstrcasecmp(lc->str, "always")) { *(item->ui32value) = SCRIPT_Any; } else { scan_err2(lc, _("Expect %s, got: %s"), "Before, After, AfterVSS or Always", lc->str); } scan_to_eol(lc); } /* * Store a runscript->target */ static void store_runscript_target(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_STRING); if (pass == 2) { if (bstrcmp(lc->str, "%c")) { ((RUNSCRIPT *)item->value)->set_target(lc->str); } else if (bstrcasecmp(lc->str, "yes")) { ((RUNSCRIPT *)item->value)->set_target("%c"); } else if (bstrcasecmp(lc->str, "no")) { ((RUNSCRIPT *)item->value)->set_target(""); } else { RES *res = GetResWithName(R_CLIENT, lc->str); if (res == NULL) { scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"), lc->str, lc->line_no, lc->line); } ((RUNSCRIPT *)item->value)->set_target(lc->str); } } scan_to_eol(lc); } /* * Store a runscript->command as a string and runscript->cmd_type as a pointer */ static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_STRING); if (pass == 2) { Dmsg2(1, "runscript cmd=%s type=%c\n", lc->str, item->code); POOLMEM *c = get_pool_memory(PM_FNAME); /* * Each runscript command takes 2 entries in commands list */ pm_strcpy(c, lc->str); ((RUNSCRIPT *)item->value)->commands->prepend(c); /* command line */ ((RUNSCRIPT *)item->value)->commands->prepend((void *)(intptr_t)item->code); /* command type */ } scan_to_eol(lc); } static void store_short_runscript(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_STRING); alist **runscripts = item->alistvalue; if (pass == 2) { RUNSCRIPT *script = new_runscript(); script->set_job_code_callback(job_code_callback_director); script->set_command(lc->str); if (bstrcasecmp(item->name, "runbeforejob")) { script->when = SCRIPT_Before; script->set_target(""); } else if (bstrcasecmp(item->name, "runafterjob")) { script->when = SCRIPT_After; script->on_success = true; script->on_failure = false; script->fail_on_error = false; script->set_target(""); } else if (bstrcasecmp(item->name, "clientrunafterjob")) { script->when = SCRIPT_After; script->on_success = true; script->on_failure = false; script->fail_on_error = false; script->set_target("%c"); } else if (bstrcasecmp(item->name, "clientrunbeforejob")) { script->when = SCRIPT_Before; script->set_target("%c"); } else if (bstrcasecmp(item->name, "runafterfailedjob")) { script->when = SCRIPT_After; script->on_failure = true; script->on_success = false; script->fail_on_error = false; script->set_target(""); } /* * Remember that the entry was configured in the short runscript form. */ script->short_form = true; if (*runscripts == NULL) { *runscripts = New(alist(10, not_owned_by_alist)); } (*runscripts)->append(script); script->debug(); } scan_to_eol(lc); } /* * Store a bool in a bit field without modifing res_all.hdr * We can also add an option to store_bool to skip res_all.hdr */ static void store_runscript_bool(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) { *(item->boolvalue) = true; } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) { *(item->boolvalue) = false; } else { scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */ } scan_to_eol(lc); } /* * Store RunScript info * * Note, when this routine is called, we are inside a Job * resource. We treat the RunScript like a sort of * mini-resource within the Job resource. */ static void store_runscript(LEX *lc, RES_ITEM *item, int index, int pass) { char *c; int token, i, t; alist **runscripts = item->alistvalue; Dmsg1(200, "store_runscript: begin store_runscript pass=%i\n", pass); token = lex_get_token(lc, T_SKIP_EOL); if (token != T_BOB) { scan_err1(lc, _("Expecting open brace. Got %s"), lc->str); } /* * Setting on_success, on_failure, fail_on_error */ res_runscript.reset_default(); if (pass == 2) { res_runscript.commands = New(alist(10, not_owned_by_alist)); } while ((token = lex_get_token(lc, T_SKIP_EOL)) != T_EOF) { if (token == T_EOB) { break; } if (token != T_IDENTIFIER) { scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); } for (i = 0; runscript_items[i].name; i++) { if (bstrcasecmp(runscript_items[i].name, lc->str)) { token = lex_get_token(lc, T_SKIP_EOL); if (token != T_EQUALS) { scan_err1(lc, _("Expected an equals, got: %s"), lc->str); } /* * Call item handler */ switch (runscript_items[i].type) { case CFG_TYPE_RUNSCRIPT_CMD: store_runscript_cmd(lc, &runscript_items[i], i, pass); break; case CFG_TYPE_RUNSCRIPT_TARGET: store_runscript_target(lc, &runscript_items[i], i, pass); break; case CFG_TYPE_RUNSCRIPT_BOOL: store_runscript_bool(lc, &runscript_items[i], i, pass); break; case CFG_TYPE_RUNSCRIPT_WHEN: store_runscript_when(lc, &runscript_items[i], i, pass); break; default: break; } i = -1; break; } } if (i >=0) { scan_err1(lc, _("Keyword %s not permitted in this resource"), lc->str); } } if (pass == 2) { /* * Run on client by default */ if (res_runscript.target == NULL) { res_runscript.set_target("%c"); } if (*runscripts == NULL) { *runscripts = New(alist(10, not_owned_by_alist)); } /* * commands list contains 2 values per command * - POOLMEM command string (ex: /bin/true) * - int command type (ex: SHELL_CMD) */ res_runscript.set_job_code_callback(job_code_callback_director); while ((c = (char *)res_runscript.commands->pop()) != NULL) { t = (intptr_t)res_runscript.commands->pop(); RUNSCRIPT *script = new_runscript(); memcpy(script, &res_runscript, sizeof(RUNSCRIPT)); script->command = c; script->cmd_type = t; /* * target is taken from res_runscript, * each runscript object have a copy */ script->target = NULL; script->set_target(res_runscript.target); /* * Remember that the entry was configured in the short runscript form. */ script->short_form = false; (*runscripts)->append(script); script->debug(); } delete res_runscript.commands; /* * setting on_success, on_failure... cleanup target field */ res_runscript.reset_default(true); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * callback function for edit_job_codes * See ../lib/util.c, function edit_job_codes, for more remaining codes * * %f = Filesetname * %h = Client Address * %p = Poolname * %w = Write storage * %x = Spooling (yes/no) * %C = Cloning (yes/no) * %D = Director name * %V = Volume name(s) (Destination) */ extern "C" char *job_code_callback_director(JCR *jcr, const char *param) { static char yes[] = "yes"; static char no[] = "no"; switch (param[0]) { case 'f': if (jcr->res.fileset) { return jcr->res.fileset->name(); } break; case 'h': if (jcr->res.client) { return jcr->res.client->address; } break; case 'p': if (jcr->res.pool) { return jcr->res.pool->name(); } break; case 'w': if (jcr->res.wstore) { return jcr->res.wstore->name(); } break; case 'x': return jcr->spool_data ? yes : no; case 'C': return jcr->cloned ? yes : no; case 'D': return my_name; case 'V': if (jcr) { /* * If this is a migration/copy we need the volume name from the mig_jcr. */ if (jcr->mig_jcr) { jcr = jcr->mig_jcr; } if (jcr->VolumeName) { return jcr->VolumeName; } else { return (char *)_("*none*"); } } else { return (char *)_("*none*"); } break; } return NULL; } /* * callback function for init_resource * See ../lib/parse_conf.c, function init_resource, for more generic handling. */ static void init_resource_cb(RES_ITEM *item, int pass) { switch (pass) { case 1: switch (item->type) { case CFG_TYPE_REPLACE: for (int i = 0; ReplaceOptions[i].name; i++) { if (bstrcasecmp(item->default_value, ReplaceOptions[i].name)) { *(item->ui32value) = ReplaceOptions[i].token; } } break; case CFG_TYPE_AUTHPROTOCOLTYPE: for (int i = 0; authprotocols[i].name; i++) { if (bstrcasecmp(item->default_value, authprotocols[i].name)) { *(item->ui32value) = authprotocols[i].token; } } break; case CFG_TYPE_AUTHTYPE: for (int i = 0; authmethods[i].name; i++) { if (bstrcasecmp(item->default_value, authmethods[i].name)) { *(item->ui32value) = authmethods[i].token; } } break; default: break; } break; default: break; } } /* * callback function for parse_config * See ../lib/parse_conf.c, function parse_config, for more generic handling. */ static void parse_config_cb(LEX *lc, RES_ITEM *item, int index, int pass) { switch (item->type) { case CFG_TYPE_AUTOPASSWORD: store_autopassword(lc, item, index, pass); break; case CFG_TYPE_ACL: store_acl(lc, item, index, pass); break; case CFG_TYPE_AUDIT: store_audit(lc, item, index, pass); break; case CFG_TYPE_AUTHPROTOCOLTYPE: store_authprotocoltype(lc, item, index, pass); break; case CFG_TYPE_AUTHTYPE: store_authtype(lc, item, index, pass); break; case CFG_TYPE_DEVICE: store_device(lc, item, index, pass); break; case CFG_TYPE_JOBTYPE: store_jobtype(lc, item, index, pass); break; case CFG_TYPE_PROTOCOLTYPE: store_protocoltype(lc, item, index, pass); break; case CFG_TYPE_LEVEL: store_level(lc, item, index, pass); break; case CFG_TYPE_REPLACE: store_replace(lc, item, index, pass); break; case CFG_TYPE_SHRTRUNSCRIPT: store_short_runscript(lc, item, index, pass); break; case CFG_TYPE_RUNSCRIPT: store_runscript(lc, item, index, pass); break; case CFG_TYPE_MIGTYPE: store_migtype(lc, item, index, pass); break; case CFG_TYPE_INCEXC: store_inc(lc, item, index, pass); break; case CFG_TYPE_RUN: store_run(lc, item, index, pass); break; case CFG_TYPE_ACTIONONPURGE: store_actiononpurge(lc, item, index, pass); break; default: break; } } /* * callback function for print_config * See ../lib/res.c, function BRSRES::print_config, for more generic handling. */ static void print_config_cb(RES_ITEM *items, int i, POOL_MEM &cfg_str, bool hide_sensitive_data) { POOL_MEM temp; switch (items[i].type) { case CFG_TYPE_DEVICE: { /* * Each member of the list is comma-separated */ int cnt = 0; RES *res; alist* list; POOL_MEM res_names; list = *(items[i].alistvalue); if (list != NULL) { Mmsg(temp, "%s = ", items[i].name); indent_config_item(cfg_str, 1, temp.c_str()); pm_strcpy(res_names, ""); foreach_alist(res, list) { if (cnt) { Mmsg(temp, ",\"%s\"", res->name); } else { Mmsg(temp, "\"%s\"", res->name); } pm_strcat(res_names, temp.c_str()); cnt++; } pm_strcat(cfg_str, res_names.c_str()); pm_strcat(cfg_str, "\n"); } break; } case CFG_TYPE_RUNSCRIPT: Dmsg0(200, "CFG_TYPE_RUNSCRIPT\n"); print_config_runscript(&items[i], cfg_str); break; case CFG_TYPE_SHRTRUNSCRIPT: /* * We don't get here as this type is converted to a CFG_TYPE_RUNSCRIPT when parsed */ break; case CFG_TYPE_ACL: { int cnt = 0; char *value; alist *list; POOL_MEM acl; list = items[i].alistvalue[items[i].code]; if (list != NULL) { Mmsg(temp, "%s = ", items[i].name); indent_config_item(cfg_str, 1, temp.c_str()); foreach_alist(value, list) { if (cnt) { Mmsg(temp, ",\"%s\"", value); } else { Mmsg(temp, "\"%s\"", value); } pm_strcat(acl, temp.c_str()); cnt++; } pm_strcat(cfg_str, acl.c_str()); pm_strcat(cfg_str, "\n"); } break; } case CFG_TYPE_RUN: print_config_run(&items[i], cfg_str); break; case CFG_TYPE_JOBTYPE: { int32_t jobtype = *(items[i].ui32value); if (jobtype) { for (int j = 0; jobtypes[j].type_name; j++) { if (jobtypes[j].job_type == jobtype) { Mmsg(temp, "%s = %s\n", items[i].name, jobtypes[j].type_name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_PROTOCOLTYPE: { uint32_t protocol = *(items[i].ui32value); if (protocol) { for (int j = 0; backupprotocols[j].name; j++) { if (backupprotocols[j].token == protocol) { /* * Supress printing default value. */ if (items[i].flags & CFG_ITEM_DEFAULT) { if (bstrcasecmp(items[i].default_value, backupprotocols[j].name)) { break; } } Mmsg(temp, "%s = %s\n", items[i].name, backupprotocols[j].name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_MIGTYPE: { int32_t migtype = *(items[i].ui32value); if (migtype) { for (int j = 0; migtypes[j].type_name; j++) { if (migtypes[j].job_type == migtype) { Mmsg(temp, "%s = %s\n", items[i].name, migtypes[j].type_name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_REPLACE: { uint32_t replace = *(items[i].ui32value); if (replace) { for (int j = 0; ReplaceOptions[j].name; j++) { if (ReplaceOptions[j].token == replace) { /* * Supress printing default value. */ if (items[i].flags & CFG_ITEM_DEFAULT) { if (bstrcasecmp(items[i].default_value, ReplaceOptions[j].name)) { break; } } Mmsg(temp, "%s = %s\n", items[i].name, ReplaceOptions[j].name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_LEVEL: { uint32_t level = *(items[i].ui32value); if (level) { for (int j = 0; joblevels[j].level_name; j++) { if (joblevels[j].level == level) { Mmsg(temp, "%s = %s\n", items[i].name, joblevels[j].level_name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_ACTIONONPURGE: { uint32_t action = *(items[i].ui32value); if (action) { for (int j = 0; ActionOnPurgeOptions[j].name; j++) { if (ActionOnPurgeOptions[j].token == action) { Mmsg(temp, "%s = %s\n", items[i].name, ActionOnPurgeOptions[j].name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_AUTHPROTOCOLTYPE: { uint32_t authprotocol = *(items[i].ui32value); if (authprotocol) { for (int j = 0; authprotocols[j].name; j++) { if (authprotocols[j].token == authprotocol) { Mmsg(temp, "%s = %s\n", items[i].name, authprotocols[j].name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_AUTHTYPE: { uint32_t authtype = *(items[i].ui32value); if (authtype) { for (int j = 0; authmethods[j].name; j++) { if (authprotocols[j].token == authtype) { Mmsg(temp, "%s = %s\n", items[i].name, authmethods[j].name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } } break; } case CFG_TYPE_AUDIT: { /* * Each member of the list is comma-separated */ int cnt = 0; char *audit_event; alist* list; POOL_MEM audit_events; list = *(items[i].alistvalue); if (list != NULL) { Mmsg(temp, "%s = ", items[i].name); indent_config_item(cfg_str, 1, temp.c_str()); pm_strcpy(audit_events, ""); foreach_alist(audit_event, list) { if (cnt) { Mmsg(temp, ",\"%s\"", audit_event); } else { Mmsg(temp, "\"%s\"", audit_event); } pm_strcat(audit_events, temp.c_str()); cnt++; } pm_strcat(cfg_str, audit_events.c_str()); pm_strcat(cfg_str, "\n"); } break; } default: Dmsg2(200, "%s is UNSUPPORTED TYPE: %d\n", items[i].name, items[i].type); break; } } void init_dir_config(CONFIG *config, const char *configfile, int exit_code) { config->init(configfile, NULL, NULL, init_resource_cb, parse_config_cb, print_config_cb, exit_code, (void *)&res_all, res_all_size, R_FIRST, R_LAST, resources, res_head); } bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code) { init_dir_config( config, configfile, exit_code ); return config->parse_config(); } bareos-Release-14.2.6/src/dird/dird_conf.h000066400000000000000000000704551263011562700202640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Director specific configuration and defines * * Kern Sibbald, Feb MM */ /* NOTE: #includes at the end of this file */ /* * Resource codes -- they must be sequential for indexing */ enum { R_DIRECTOR = 1001, R_CLIENT, R_JOBDEFS, R_JOB, R_STORAGE, R_CATALOG, R_SCHEDULE, R_FILESET, R_POOL, R_MSGS, R_COUNTER, R_PROFILE, R_CONSOLE, R_DEVICE, R_FIRST = R_DIRECTOR, R_LAST = R_DEVICE /* keep this updated */ }; /* * Some resource attributes */ enum { R_NAME = 1020, R_ADDRESS, R_PASSWORD, R_TYPE, R_BACKUP }; /* * Job Level keyword structure */ struct s_jl { const char *level_name; /* level keyword */ uint32_t level; /* level */ int32_t job_type; /* JobType permitting this level */ }; /* * Job Type keyword structure */ struct s_jt { const char *type_name; int32_t job_type; }; /* * Definition of the contents of each Resource * Needed for forward references */ class SCHEDRES; class CLIENTRES; class FILESETRES; class POOLRES; class RUNRES; class DEVICERES; class RUNSCRIPTRES; /* * Director Resource */ class DIRRES: public BRSRES { public: dlist *DIRaddrs; dlist *DIRsrc_addr; /* Address to source connections from */ s_password password; /* Password for UA access */ char *query_file; /* SQL query file */ char *working_directory; /* WorkingDirectory */ char *scripts_directory; /* ScriptsDirectory */ char *plugin_directory; /* Plugin Directory */ alist *plugin_names; /* Plugin names to load */ char *pid_directory; /* PidDirectory */ char *subsys_directory; /* SubsysDirectory */ alist *backend_directories; /* Backend Directories */ MSGSRES *messages; /* Daemon message handler */ uint32_t MaxConcurrentJobs; /* Max concurrent jobs for whole director */ uint32_t MaxConsoleConnect; /* Max concurrent console session */ utime_t FDConnectTimeout; /* timeout for connect in seconds */ utime_t SDConnectTimeout; /* timeout in seconds */ utime_t heartbeat_interval; /* Interval to send heartbeats */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Server Certificate File */ char *tls_keyfile; /* TLS Server Key File */ char *tls_dhfile; /* TLS Diffie-Hellman Parameters */ alist *tls_allowed_cns; /* TLS Allowed Clients */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ utime_t stats_retention; /* Statistics retention period in seconds */ bool tls_authenticate; /* Authenticated with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ bool optimize_for_size; /* Optimize daemon for minimum memory size */ bool optimize_for_speed; /* Optimize daemon for speed which may need more memory */ bool nokeepalive; /* Don't use SO_KEEPALIVE on sockets */ bool omit_defaults; /* Omit config variables with default values when dumping the config */ bool ndmp_snooping; /* NDMP Protocol specific snooping enabled */ bool auditing; /* Auditing enabled */ alist *audit_events; /* Specific audit events to enable */ uint32_t ndmp_loglevel; /* NDMP Protocol specific loglevel to use */ uint32_t subscriptions; /* Number of subscribtions available */ uint32_t subscriptions_used; /* Number of subscribtions used */ uint32_t jcr_watchdog_time; /* Absolute time after which a Job gets terminated regardless of its progress */ uint32_t stats_collect_interval; /* Statistics collect interval in seconds */ char *verid; /* Custom Id to print in version command */ s_password keyencrkey; /* Key Encryption Key */ }; /* * Device Resource * * This resource is a bit different from the other resources * because it is not defined in the Director * by DEVICE { ... }, but rather by a "reference" such as * DEVICE = xxx; Then when the Director connects to the * SD, it requests the information about the device. */ class DEVICERES : public BRSRES { public: bool found; /* found with SD */ int32_t num_writers; /* number of writers */ int32_t max_writers; /* = 1 for files */ int32_t reserved; /* number of reserves */ int32_t num_drives; /* for autochanger */ bool autochanger; /* set if device is autochanger */ bool open; /* drive open */ bool append; /* in append mode */ bool read; /* in read mode */ bool labeled; /* Volume name valid */ bool offline; /* not available */ bool autoselect; /* can be selected via autochanger */ uint32_t PoolId; char ChangerName[MAX_NAME_LENGTH]; char VolumeName[MAX_NAME_LENGTH]; char MediaType[MAX_NAME_LENGTH]; }; /* * Console ACL positions */ enum { Job_ACL = 0, Client_ACL, Storage_ACL, Schedule_ACL, Run_ACL, Pool_ACL, Command_ACL, FileSet_ACL, Catalog_ACL, Where_ACL, PluginOptions_ACL, Num_ACL /* keep last */ }; /* * Profile Resource */ class PROFILERES : public BRSRES { public: alist *ACL_lists[Num_ACL]; /* Pointers to ACLs */ }; /* * Console Resource */ class CONRES : public BRSRES { public: s_password password; /* UA server password */ alist *ACL_lists[Num_ACL]; /* Pointers to ACLs */ alist *profiles; /* Pointers to profile resources */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Server Certificate File */ char *tls_keyfile; /* TLS Server Key File */ char *tls_dhfile; /* TLS Diffie-Hellman Parameters */ alist *tls_allowed_cns; /* TLS Allowed Clients */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ bool tls_authenticate; /* Authenticated with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ }; /* * Catalog Resource */ class CATRES : public BRSRES { public: uint32_t db_port; /* Port */ char *db_address; /* Hostname for remote access */ char *db_socket; /* Socket for local access */ s_password db_password; char *db_user; char *db_name; char *db_driver; /* Select appropriate driver */ uint32_t mult_db_connections; /* set if multiple connections wanted */ bool disable_batch_insert; /* set if batch inserts should be disabled */ uint32_t pooling_min_connections; /* When using sql pooling start with this number of connections to the database */ uint32_t pooling_max_connections; /* When using sql pooling maximum number of connections to the database */ uint32_t pooling_increment_connections; /* When using sql pooling increment the pool with this amount when its to small */ uint32_t pooling_idle_timeout; /* When using sql pooling set this to the number of seconds to keep an idle connection */ uint32_t pooling_validate_timeout; /* When using sql pooling set this to the number of seconds after a idle connection should be validated */ /* Methods */ char *display(POOLMEM *dst); /* Get catalog information */ }; /* * Client Resource */ class CLIENTRES: public BRSRES { public: uint32_t Protocol; /* Protocol to use to connect */ uint32_t AuthType; /* Authentication Type to use for protocol */ uint32_t ndmp_loglevel; /* NDMP Protocol specific loglevel to use */ uint32_t ndmp_blocksize; /* NDMP Protocol specific blocksize to use */ uint32_t FDport; /* Where File daemon listens */ uint64_t SoftQuota; /* Soft Quota permitted in bytes */ uint64_t HardQuota; /* Maximum permitted quota in bytes */ uint64_t GraceTime; /* Time remaining on gracetime */ uint64_t QuotaLimit; /* The total softquota supplied if over grace */ utime_t SoftQuotaGracePeriod; /* Grace time for softquota */ utime_t FileRetention; /* file retention period in seconds */ utime_t JobRetention; /* job retention period in seconds */ utime_t heartbeat_interval; /* Interval to send heartbeats */ char *address; /* Hostname for remote access to Client */ char *username; /* Username to use for authentication if protocol supports it */ s_password password; CATRES *catalog; /* Catalog resource */ int32_t MaxConcurrentJobs; /* Maximum concurrent jobs */ int32_t NumConcurrentJobs; /* number of concurrent jobs running */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ alist *tls_allowed_cns; /* TLS Allowed Clients */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ bool passive; /* Passive Client */ bool enabled; /* Set if client is enabled */ bool tls_authenticate; /* Authenticated with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool AutoPrune; /* Do automatic pruning? */ bool StrictQuotas; /* Enable strict quotas? */ bool QuotaIncludeFailedJobs; /* Ignore failed jobs when calculating quota */ int64_t max_bandwidth; /* Limit speed on this client */ }; /* * Store Resource */ class STORERES : public BRSRES { public: uint32_t Protocol; /* Protocol to use to connect */ uint32_t AuthType; /* Authentication Type to use for protocol */ uint32_t SDport; /* Port where Directors connect */ uint32_t SDDport; /* Data port for File daemon */ char *address; /* Hostname for remote access to Storage */ char *username; /* Username to use for authentication if protocol supports it */ s_password password; char *media_type; /* Media Type provided by this Storage */ alist *device; /* Alternate devices for this Storage */ int32_t MaxConcurrentJobs; /* Maximum concurrent jobs */ int32_t MaxConcurrentReadJobs; /* Maximum concurrent jobs reading */ int32_t NumConcurrentJobs; /* Number of concurrent jobs running */ int32_t NumConcurrentReadJobs; /* Number of jobs reading */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ bool tls_authenticate; /* Authenticated with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool enabled; /* Set if device is enabled */ bool autochanger; /* Set if autochanger */ bool collectstats; /* Set if statistics should be collected of this SD */ bool AllowCompress; /* Set if this Storage should allow jobs to enable compression */ int64_t StorageId; /* Set from Storage DB record */ int64_t max_bandwidth; /* Limit speed on this storage daemon for replication */ utime_t heartbeat_interval; /* Interval to send heartbeats */ uint32_t drives; /* Number of drives in autochanger */ STORERES *paired_storage; /* Paired storage configuration item for protocols like NDMP */ /* Methods */ char *dev_name() const; }; inline char *STORERES::dev_name() const { DEVICERES *dev = (DEVICERES *)device->first(); return dev->name(); } /* * This is a sort of "unified" store that has both the * storage pointer and the text of where the pointer was * found. */ class USTORERES { public: STORERES *store; POOLMEM *store_source; /* Methods */ USTORERES() { store = NULL; store_source = get_pool_memory(PM_MESSAGE); *store_source = 0; }; ~USTORERES() { destroy(); } void set_source(const char *where); void destroy(); }; inline void USTORERES::destroy() { if (store_source) { free_pool_memory(store_source); store_source = NULL; } } inline void USTORERES::set_source(const char *where) { if (!store_source) { store_source = get_pool_memory(PM_MESSAGE); } pm_strcpy(store_source, where); } /* * Job Resource */ class JOBRES : public BRSRES { public: uint32_t Protocol; /* Protocol to use to connect */ uint32_t JobType; /* job type (backup, verify, restore */ uint32_t JobLevel; /* default backup/verify level */ int32_t Priority; /* Job priority */ uint32_t RestoreJobId; /* What -- JobId to restore */ int32_t RescheduleTimes; /* Number of times to reschedule job */ uint32_t replace; /* How (overwrite, ..) */ uint32_t selection_type; char *RestoreWhere; /* Where on disk to restore -- directory */ char *RegexWhere; /* RegexWhere option */ char *strip_prefix; /* remove prefix from filename */ char *add_prefix; /* add prefix to filename */ char *add_suffix; /* add suffix to filename -- .old */ char *backup_format; /* Format of backup to use for protocols supporting multiple backup formats */ char *RestoreBootstrap; /* Bootstrap file */ char *WriteBootstrap; /* Where to write bootstrap Job updates */ char *WriteVerifyList; /* List of changed files */ utime_t MaxRunTime; /* max run time in seconds */ utime_t MaxWaitTime; /* max blocking time in seconds */ utime_t FullMaxRunTime; /* Max Full job run time */ utime_t DiffMaxRunTime; /* Max Differential job run time */ utime_t IncMaxRunTime; /* Max Incremental job run time */ utime_t MaxStartDelay; /* max start delay in seconds */ utime_t MaxRunSchedTime; /* max run time in seconds from Scheduled time*/ utime_t RescheduleInterval; /* Reschedule interval */ utime_t MaxFullInterval; /* Maximum time interval between Fulls */ utime_t MaxVFullInterval; /* Maximum time interval between Virtual Fulls */ utime_t MaxDiffInterval; /* Maximum time interval between Diffs */ utime_t DuplicateJobProximity; /* Permitted time between duplicicates */ int64_t spool_size; /* Size of spool file for this job */ int32_t MaxConcurrentJobs; /* Maximum concurrent jobs */ int32_t NumConcurrentJobs; /* number of concurrent jobs running */ bool allow_mixed_priority; /* Allow jobs with higher priority concurrently with this */ MSGSRES *messages; /* How and where to send messages */ SCHEDRES *schedule; /* When -- Automatic schedule */ CLIENTRES *client; /* Who to backup */ FILESETRES *fileset; /* What to backup -- Fileset */ CATRES *catalog; /* Which Catalog to use */ alist *storage; /* Where is device -- list of Storage to be used */ POOLRES *pool; /* Where is media -- Media Pool */ POOLRES *full_pool; /* Pool for Full backups */ POOLRES *vfull_pool; /* Pool for Virtual Full backups */ POOLRES *inc_pool; /* Pool for Incremental backups */ POOLRES *diff_pool; /* Pool for Differental backups */ POOLRES *next_pool; /* Next Pool for Copy/Migration Jobs and Virtual backups */ char *selection_pattern; JOBRES *verify_job; /* Job name to verify */ JOBRES *jobdefs; /* Job defaults */ alist *run_cmds; /* Run commands */ alist *RunScripts; /* Run {client} program {after|before} Job */ bool where_use_regexp; /* true if RestoreWhere is a BREGEXP */ bool RescheduleOnError; /* Set to reschedule on error */ bool RescheduleIncompleteJobs; /* Set to reschedule incomplete Jobs */ bool PrefixLinks; /* prefix soft links with Where path */ bool PruneJobs; /* Force pruning of Jobs */ bool PruneFiles; /* Force pruning of Files */ bool PruneVolumes; /* Force pruning of Volumes */ bool SpoolAttributes; /* Set to spool attributes in SD */ bool spool_data; /* Set to spool data in SD */ bool rerun_failed_levels; /* Upgrade to rerun failed levels */ bool PreferMountedVolumes; /* Prefer vols mounted rather than new one */ bool write_part_after_job; /* Set to write part after job in SD */ bool enabled; /* Set if job enabled */ bool accurate; /* Set if it is an accurate backup job */ bool AllowDuplicateJobs; /* Allow duplicate jobs */ bool AllowHigherDuplicates; /* Permit Higher Level */ bool CancelLowerLevelDuplicates; /* Cancel lower level backup jobs */ bool CancelQueuedDuplicates; /* Cancel queued jobs */ bool CancelRunningDuplicates; /* Cancel Running jobs */ bool PurgeMigrateJob; /* Purges source job on completion */ bool IgnoreDuplicateJobChecking; /* Ignore Duplicate Job Checking */ bool SaveFileHist; /* Ability to disable File history saving for certain protocols */ alist *FdPluginOptions; /* Generic FD plugin options used by this Job */ alist *SdPluginOptions; /* Generic SD plugin options used by this Job */ alist *DirPluginOptions; /* Generic DIR plugin options used by this Job */ alist *base; /* Base jobs */ int64_t max_bandwidth; /* Speed limit on this job */ /* Methods */ }; #undef MAX_FOPTS #define MAX_FOPTS 40 /* * File options structure */ struct FOPTS { char opts[MAX_FOPTS]; /* Options string */ alist regex; /* Regex string(s) */ alist regexdir; /* Regex string(s) for directories */ alist regexfile; /* Regex string(s) for files */ alist wild; /* Wild card strings */ alist wilddir; /* Wild card strings for directories */ alist wildfile; /* Wild card strings for files */ alist wildbase; /* Wild card strings for files without '/' */ alist base; /* List of base names */ alist fstype; /* File system type limitation */ alist drivetype; /* Drive type limitation */ alist meta; /* Backup meta information */ char *reader; /* Reader program */ char *writer; /* Writer program */ char *plugin; /* Plugin program */ }; /* * This is either an include item or an exclude item */ struct INCEXE { FOPTS *current_opts; /* Points to current options structure */ FOPTS **opts_list; /* Options list */ int32_t num_opts; /* Number of options items */ alist name_list; /* Filename list -- holds char * */ alist plugin_list; /* Filename list for plugins */ alist ignoredir; /* Ignoredir string */ }; /* * FileSet Resource */ class FILESETRES : public BRSRES { public: bool new_include; /* Set if new include used */ INCEXE **include_items; /* Array of incexe structures */ int32_t num_includes; /* Number in array */ INCEXE **exclude_items; int32_t num_excludes; bool have_MD5; /* Set if MD5 initialized */ MD5_CTX md5c; /* MD5 of include/exclude */ char MD5[30]; /* Base 64 representation of MD5 */ bool ignore_fs_changes; /* Don't force Full if FS changed */ bool enable_vss; /* Enable Volume Shadow Copy */ /* Methods */ bool print_config(POOL_MEM& buff, bool hide_sensitive_data); }; /* * Schedule Resource */ class SCHEDRES: public BRSRES { public: RUNRES *run; bool enabled; /* Set if schedule is enabled */ }; /* * Counter Resource */ class COUNTERRES: public BRSRES { public: int32_t MinValue; /* Minimum value */ int32_t MaxValue; /* Maximum value */ int32_t CurrentValue ; /* Current value */ COUNTERRES *WrapCounter; /* Wrap counter name */ CATRES *Catalog; /* Where to store */ bool created; /* Created in DB */ }; /* * Pool Resource */ class POOLRES: public BRSRES { public: char *pool_type; /* Pool type */ char *label_format; /* Label format string */ char *cleaning_prefix; /* Cleaning label prefix */ int32_t LabelType; /* Bareos/ANSI/IBM label type */ uint32_t max_volumes; /* max number of volumes */ utime_t VolRetention; /* volume retention period in seconds */ utime_t VolUseDuration; /* duration volume can be used */ uint32_t MaxVolJobs; /* Maximum jobs on the Volume */ uint32_t MaxVolFiles; /* Maximum files on the Volume */ uint64_t MaxVolBytes; /* Maximum bytes on the Volume */ utime_t MigrationTime; /* Time to migrate to next pool */ uint64_t MigrationHighBytes; /* When migration starts */ uint64_t MigrationLowBytes; /* When migration stops */ POOLRES *NextPool; /* Next pool for migration */ alist *storage; /* Where is device -- list of Storage to be used */ bool use_catalog; /* maintain catalog for media */ bool catalog_files; /* maintain file entries in catalog */ bool use_volume_once; /* write on volume only once */ bool purge_oldest_volume; /* purge oldest volume */ bool recycle_oldest_volume; /* attempt to recycle oldest volume */ bool recycle_current_volume; /* attempt recycle of current volume */ bool AutoPrune; /* default for pool auto prune */ bool Recycle; /* default for media recycle yes/no */ uint32_t action_on_purge; /* action on purge, e.g. truncate the disk volume */ POOLRES *RecyclePool; /* RecyclePool destination when media is purged */ POOLRES *ScratchPool; /* ScratchPool source when requesting media */ CATRES *catalog; /* Catalog to be used */ utime_t FileRetention; /* file retention period in seconds */ utime_t JobRetention; /* job retention period in seconds */ uint32_t MinBlocksize; /* Minimum Blocksize */ uint32_t MaxBlocksize; /* Maximum Blocksize */ }; /* * Define the Union of all the above * resource structure definitions. */ union URES { DIRRES res_dir; CONRES res_con; PROFILERES res_profile; CLIENTRES res_client; STORERES res_store; CATRES res_cat; JOBRES res_job; FILESETRES res_fs; SCHEDRES res_sch; POOLRES res_pool; MSGSRES res_msgs; COUNTERRES res_counter; DEVICERES res_dev; RES hdr; }; /* * Run structure contained in Schedule Resource */ class RUNRES: public BRSRES { public: RUNRES *next; /* points to next run record */ uint32_t level; /* level override */ int32_t Priority; /* priority override */ uint32_t job_type; utime_t MaxRunSchedTime; /* max run time in sec from Sched time */ bool MaxRunSchedTime_set; /* MaxRunSchedTime given */ bool spool_data; /* Data spooling override */ bool spool_data_set; /* Data spooling override given */ bool accurate; /* accurate */ bool accurate_set; /* accurate given */ POOLRES *pool; /* Pool override */ POOLRES *full_pool; /* Full Pool override */ POOLRES *vfull_pool; /* Virtual Full Pool override */ POOLRES *inc_pool; /* Incr Pool override */ POOLRES *diff_pool; /* Diff Pool override */ POOLRES *next_pool; /* Next Pool override */ STORERES *storage; /* Storage override */ MSGSRES *msgs; /* Messages override */ char *since; uint32_t level_no; uint32_t minute; /* minute to run job */ time_t last_run; /* last time run */ time_t next_run; /* next time to run */ char hour[nbytes_for_bits(24 + 1)]; /* bit set for each hour */ char mday[nbytes_for_bits(31 + 1)]; /* bit set for each day of month */ char month[nbytes_for_bits(12 + 1)]; /* bit set for each month */ char wday[nbytes_for_bits(7 + 1)]; /* bit set for each day of the week */ char wom[nbytes_for_bits(5 + 1)]; /* week of month */ char woy[nbytes_for_bits(54 + 1)]; /* week of year */ bool last_set; /* last week of month */ }; void init_dir_config(CONFIG *config, const char *configfile, int exit_code); #define GetPoolResWithName(x) ((POOLRES *)GetResWithName(R_POOL, (x))) #define GetStoreResWithName(x) ((STORERES *)GetResWithName(R_STORAGE, (x))) #define GetClientResWithName(x) ((CLIENTRES *)GetResWithName(R_CLIENT, (x))) #define GetJobResWithName(x) ((JOBRES *)GetResWithName(R_JOB, (x))) #define GetFileSetResWithName(x) ((FILESETRES *)GetResWithName(R_FILESET, (x))) #define GetCatalogResWithName(x) ((CATRES *)GetResWithName(R_CATALOG, (x))) #define GetScheduleResWithName(x) ((SCHEDRES *)GetResWithName(R_SCHEDULE, (x))) bareos-Release-14.2.6/src/dird/expand.c000066400000000000000000000361301263011562700175770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2006 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- expand.c -- does variable expansion * in particular for the LabelFormat specification. * * Kern Sibbald, June MMIII */ #include "bareos.h" #include "dird.h" static int date_item(JCR *jcr, int code, const char **val_ptr, int *val_len, int *val_size) { int val = 0; char buf[10]; struct tm tm; time_t now = time(NULL); blocaltime(&now, &tm); switch (code) { case 1: /* year */ val = tm.tm_year + 1900; break; case 2: /* month */ val = tm.tm_mon + 1; break; case 3: /* day */ val = tm.tm_mday; break; case 4: /* hour */ val = tm.tm_hour; break; case 5: /* minute */ val = tm.tm_min; break; case 6: /* second */ val = tm.tm_sec; break; case 7: /* Week day */ val = tm.tm_wday; break; } bsnprintf(buf, sizeof(buf), "%d", val); *val_ptr = bstrdup(buf); *val_len = strlen(buf); *val_size = *val_len + 1; return 1; } static int job_item(JCR *jcr, int code, const char **val_ptr, int *val_len, int *val_size) { const char *str = " "; char buf[20]; switch (code) { case 1: /* Job */ str = jcr->res.job->name(); break; case 2: /* Director's name */ str = my_name; break; case 3: /* level */ str = job_level_to_str(jcr->getJobLevel()); break; case 4: /* type */ str = job_type_to_str(jcr->getJobType()); break; case 5: /* JobId */ bsnprintf(buf, sizeof(buf), "%d", jcr->JobId); str = buf; break; case 6: /* Client */ str = jcr->res.client->name(); if (!str) { str = " "; } break; case 7: /* NumVols */ bsnprintf(buf, sizeof(buf), "%d", jcr->NumVols); str = buf; break; case 8: /* Pool */ str = jcr->res.pool->name(); break; case 9: /* Storage */ if (jcr->res.wstore) { str = jcr->res.wstore->name(); } else { str = jcr->res.rstore->name(); } break; case 10: /* Catalog */ str = jcr->res.catalog->name(); break; case 11: /* MediaType */ if (jcr->res.wstore) { str = jcr->res.wstore->media_type; } else { str = jcr->res.rstore->media_type; } break; case 12: /* JobName */ str = jcr->Job; break; } *val_ptr = bstrdup(str); *val_len = strlen(str); *val_size = *val_len + 1; return 1; } struct s_built_in_vars { const char *var_name; int code; int (*func)(JCR *jcr, int code, const char **val_ptr, int *val_len, int *val_size); }; /* * Table of build in variables */ static struct s_built_in_vars built_in_vars[] = { { NT_("Year"), 1, date_item }, { NT_("Month"), 2, date_item }, { NT_("Day"), 3, date_item }, { NT_("Hour"), 4, date_item }, { NT_("Minute"), 5, date_item }, { NT_("Second"), 6, date_item }, { NT_("WeekDay"), 7, date_item }, { NT_("Job"), 1, job_item }, { NT_("Dir"), 2, job_item }, { NT_("Level"), 3, job_item }, { NT_("Type"), 4, job_item }, { NT_("JobId"), 5, job_item }, { NT_("Client"), 6, job_item }, { NT_("NumVols"), 7, job_item }, { NT_("Pool"), 8, job_item }, { NT_("Storage"), 9, job_item }, { NT_("Catalog"), 10, job_item }, { NT_("MediaType"), 11, job_item }, { NT_("JobName"), 12, job_item }, { NULL, 0, NULL } }; /* * Search the table of built-in variables, and if found, * call the appropriate subroutine to do the work. */ static var_rc_t lookup_built_in_var(var_t *ctx, void *my_ctx, const char *var_ptr, int var_len, int var_index, const char **val_ptr, int *val_len, int *val_size) { JCR *jcr = (JCR *)my_ctx; int status, i; for (i = 0; _(built_in_vars[i].var_name); i++) { if (bstrncmp(_(built_in_vars[i].var_name), var_ptr, var_len)) { status = (*built_in_vars[i].func)(jcr, built_in_vars[i].code, val_ptr, val_len, val_size); if (status) { return VAR_OK; } break; } } return VAR_ERR_UNDEFINED_VARIABLE; } /* * Search counter variables */ static var_rc_t lookup_counter_var(var_t *ctx, void *my_ctx, const char *var_ptr, int var_len, int var_inc, int var_index, const char **val_ptr, int *val_len, int *val_size) { COUNTERRES *counter; POOL_MEM buf(PM_NAME); var_rc_t status = VAR_ERR_UNDEFINED_VARIABLE; buf.check_size(var_len + 1); pm_memcpy(buf, var_ptr, var_len); (buf.c_str())[var_len] = 0; LockRes(); for (counter = NULL; (counter = (COUNTERRES *)GetNextRes(R_COUNTER, (RES *)counter)); ) { if (bstrcmp(counter->name(), buf.c_str())) { Dmsg2(100, "Counter=%s val=%d\n", buf.c_str(), counter->CurrentValue); /* * -1 => return size of array */ if (var_index == -1) { Mmsg(buf, "%d", counter->CurrentValue); *val_len = Mmsg(buf, "%d", strlen(buf.c_str())); *val_ptr = bstrdup(buf.c_str()); *val_size = 0; /* don't try to free val_ptr */ return VAR_OK; } else { Mmsg(buf, "%d", counter->CurrentValue); *val_ptr = bstrdup(buf.c_str()); *val_len = strlen(buf.c_str()); *val_size = *val_len + 1; } if (var_inc) { /* increment the variable? */ if (counter->CurrentValue == counter->MaxValue) { counter->CurrentValue = counter->MinValue; } else { counter->CurrentValue++; } if (counter->Catalog) { /* update catalog if need be */ COUNTER_DBR cr; JCR *jcr = (JCR *)my_ctx; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Counter, counter->name(), sizeof(cr.Counter)); cr.MinValue = counter->MinValue; cr.MaxValue = counter->MaxValue; cr.CurrentValue = counter->CurrentValue; Dmsg1(100, "New value=%d\n", cr.CurrentValue); if (counter->WrapCounter) { bstrncpy(cr.WrapCounter, counter->WrapCounter->name(), sizeof(cr.WrapCounter)); } else { cr.WrapCounter[0] = 0; } if (!db_update_counter_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_ERROR, 0, _("Count not update counter %s: ERR=%s\n"), counter->name(), db_strerror(jcr->db)); } } } status = VAR_OK; break; } } UnlockRes(); return status; } /* * Called here from "core" expand code to look up a variable */ static var_rc_t lookup_var(var_t *ctx, void *my_ctx, const char *var_ptr, int var_len, int var_inc, int var_index, const char **val_ptr, int *val_len, int *val_size) { POOL_MEM buf(PM_NAME); char *val, *p, *v; var_rc_t status; int count; /* * Note, if val_size > 0 and val_ptr!=NULL, the core code will free() it */ if ((status = lookup_built_in_var(ctx, my_ctx, var_ptr, var_len, var_index, val_ptr, val_len, val_size)) == VAR_OK) { return VAR_OK; } if ((status = lookup_counter_var(ctx, my_ctx, var_ptr, var_len, var_inc, var_index, val_ptr, val_len, val_size)) == VAR_OK) { return VAR_OK; } /* * Look in environment */ buf.check_size(var_len + 1); pm_memcpy(buf, var_ptr, var_len); (buf.c_str())[var_len] = 0; Dmsg1(100, "Var=%s\n", buf.c_str()); if ((val = getenv(buf.c_str())) == NULL) { return VAR_ERR_UNDEFINED_VARIABLE; } /* * He wants to index the "array" */ count = 1; /* * Find the size of the "array" each element is separated by a | */ for (p = val; *p; p++) { if (*p == '|') { count++; } } Dmsg3(100, "For %s, reqest index=%d have=%d\n", buf.c_str(), var_index, count); /* * -1 => return size of array */ if (var_index == -1) { int len; if (count == 1) { /* if not array */ len = strlen(val); /* return length of string */ } else { len = count; /* else return # array items */ } *val_len = Mmsg(buf, "%d", len); *val_ptr = bstrdup(buf.c_str()); *val_size = 0; /* don't try to free val_ptr */ return VAR_OK; } if (var_index < -1 || var_index > --count) { // return VAR_ERR_SUBMATCH_OUT_OF_RANGE; return VAR_ERR_UNDEFINED_VARIABLE; } /* * Now find the particular item (var_index) he wants */ count = 0; for (p = val; *p; ) { if (*p == '|') { if (count < var_index) { val = ++p; count++; continue; } break; } p++; } buf.check_size(p - val); Dmsg2(100, "val=%s len=%d\n", val, p - val); /* * Make a copy of item, and pass it back */ v = (char *)malloc(p-val+1); memcpy(v, val, p-val); v[p-val] = 0; *val_ptr = v; *val_len = p-val; *val_size = p-val+1; Dmsg1(100, "v=%s\n", v); return VAR_OK; } /* * Called here to do a special operation on a variable * op_ptr points to the special operation code (not EOS terminated) * arg_ptr points to argument to special op code * val_ptr points to the value string * out_ptr points to string to be returned */ static var_rc_t operate_var(var_t *var, void *my_ctx, const char *op_ptr, int op_len, const char *arg_ptr, int arg_len, const char *val_ptr, int val_len, char **out_ptr, int *out_len, int *out_size) { COUNTERRES *counter; POOL_MEM buf(PM_NAME); var_rc_t status = VAR_ERR_UNDEFINED_OPERATION; Dmsg0(100, "Enter operate_var\n"); if (!val_ptr) { *out_size = 0; return status; } if (op_len == 3 && bstrncmp(op_ptr, "inc", 3)) { buf.check_size(val_len + 1); pm_memcpy(buf, arg_ptr, val_len); (buf.c_str())[val_len] = 0; Dmsg1(100, "Arg=%s\n", buf.c_str()); pm_memcpy(buf, val_ptr, val_len); (buf.c_str())[val_len] = 0; Dmsg1(100, "Val=%s\n", buf.c_str()); LockRes(); for (counter = NULL; (counter = (COUNTERRES *)GetNextRes(R_COUNTER, (RES *)counter)); ) { if (bstrcmp(counter->name(), buf.c_str())) { Dmsg2(100, "counter=%s val=%s\n", counter->name(), buf.c_str()); break; } } UnlockRes(); return status; } *out_size = 0; return status; } /* * Expand an input line and return it. * * Returns: 0 on failure * 1 on success and exp has expanded input */ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp) { var_t *var_ctx; var_rc_t status; char *outp; int in_len, out_len; int rtn_stat = 0; in_len = strlen(inp); outp = NULL; out_len = 0; /* * Create context */ if ((status = var_create(&var_ctx)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot create var context: ERR=%s\n"), var_strerror(var_ctx, status)); goto bail_out; } /* * Define callback */ if ((status = var_config(var_ctx, VAR_CONFIG_CB_VALUE, lookup_var, (void *)jcr)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot set var callback: ERR=%s\n"), var_strerror(var_ctx, status)); goto bail_out; } /* * Define special operations */ if ((status = var_config(var_ctx, VAR_CONFIG_CB_OPERATION, operate_var, (void *)jcr)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot set var operate: ERR=%s\n"), var_strerror(var_ctx, status)); goto bail_out; } /* * Unescape in place */ if ((status = var_unescape(var_ctx, inp, in_len, inp, in_len+1, 0)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot unescape string: ERR=%s\n"), var_strerror(var_ctx, status)); goto bail_out; } in_len = strlen(inp); /* * Expand variables */ if ((status = var_expand(var_ctx, inp, in_len, &outp, &out_len, 0)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot expand expression \"%s\": ERR=%s\n"), inp, var_strerror(var_ctx, status)); goto bail_out; } /* * Unescape once more in place */ if ((status = var_unescape(var_ctx, outp, out_len, outp, out_len+1, 1)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot unescape string: ERR=%s\n"), var_strerror(var_ctx, status)); goto bail_out; } pm_strcpy(exp, outp); rtn_stat = 1; bail_out: /* * Destroy expansion context */ if ((status = var_destroy(var_ctx)) != VAR_OK) { Jmsg(jcr, M_ERROR, 0, _("Cannot destroy var context: ERR=%s\n"), var_strerror(var_ctx, status)); } if (outp) { free(outp); } return rtn_stat; } bareos-Release-14.2.6/src/dird/fd_cmds.c000066400000000000000000000754531263011562700177320ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- fd_cmds.c -- send commands to File daemon * * Kern Sibbald, October MM * * This routine is run as a separate thread. There may be more * work to be done to make it totally reentrant!!!! * * Utility functions for sending info to File Daemon. * These functions are used by both backup and verify. */ #include "bareos.h" #include "dird.h" #include "findlib/find.h" const int dbglvl = 400; /* Commands sent to File daemon */ static char filesetcmd[] = "fileset%s\n"; /* set full fileset */ static char jobcmd[] = "JobId=%s Job=%s SDid=%u SDtime=%u Authorization=%s\n"; /* Note, mtime_only is not used here -- implemented as file option */ static char levelcmd[] = "level = %s%s%s mtime_only=%d %s%s\n"; static char runscriptcmd[] = "Run OnSuccess=%u OnFailure=%u AbortOnError=%u When=%u Command=%s\n"; static char runbeforenowcmd[] = "RunBeforeNow\n"; static char restoreobjectendcmd[] = "restoreobject end\n"; static char bandwidthcmd[] = "setbandwidth=%lld Job=%s\n"; static char pluginoptionscmd[] = "pluginoptions %s\n"; /* Responses received from File daemon */ static char OKinc[] = "2000 OK include\n"; static char OKjob[] = "2000 OK Job"; static char OKlevel[] = "2000 OK level\n"; static char OKRunScript[] = "2000 OK RunScript\n"; static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n"; static char OKRestoreObject[] = "2000 OK ObjectRestored\n"; static char OKBandwidth[] = "2000 OK Bandwidth\n"; static char OKPluginOptions[] = "2000 OK PluginOptions\n"; /* Forward referenced functions */ static bool send_list_item(JCR *jcr, const char *code, char *item, BSOCK *fd); /* External functions */ extern DIRRES *director; #define INC_LIST 0 #define EXC_LIST 1 /* * Open connection with File daemon. * Try connecting every retry_interval (default 10 sec), and * give up after max_retry_time (default 30 mins). */ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time, bool verbose, bool start_job) { BSOCK *fd; char ed1[30]; utime_t heart_beat; fd = New(BSOCK_TCP); if (me->nokeepalive) { fd->clear_keepalive(); } if (jcr->res.client->heartbeat_interval) { heart_beat = jcr->res.client->heartbeat_interval; } else { heart_beat = me->heartbeat_interval; } if (!jcr->file_bsock) { char name[MAX_NAME_LENGTH + 100]; bstrncpy(name, _("Client: "), sizeof(name)); bstrncat(name, jcr->res.client->name(), sizeof(name)); fd->set_source_address(me->DIRsrc_addr); if (!fd->connect(jcr,retry_interval,max_retry_time, heart_beat, name, jcr->res.client->address, NULL, jcr->res.client->FDport, verbose)) { delete fd; fd = NULL; } if (fd == NULL) { jcr->setJobStatus(JS_ErrorTerminated); return 0; } Dmsg0(10, "Opened connection with File daemon\n"); } else { fd = jcr->file_bsock; /* use existing connection */ } fd->res = (RES *)jcr->res.client; /* save resource in BSOCK */ jcr->file_bsock = fd; jcr->setJobStatus(JS_Running); if (!authenticate_file_daemon(jcr)) { jcr->setJobStatus(JS_ErrorTerminated); return 0; } if (start_job) { /* * Now send JobId and authorization key */ if (jcr->sd_auth_key == NULL) { jcr->sd_auth_key = bstrdup("dummy"); } fd->fsend(jobcmd, edit_int64(jcr->JobId, ed1), jcr->Job, jcr->VolSessionId, jcr->VolSessionTime, jcr->sd_auth_key); if (!jcr->keep_sd_auth_key && !bstrcmp(jcr->sd_auth_key, "dummy")) { memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); } Dmsg1(100, ">filed: %s", fd->msg); if (bget_dirmsg(fd) > 0) { Dmsg1(110, "msg); if (!bstrncmp(fd->msg, OKjob, strlen(OKjob))) { Jmsg(jcr, M_FATAL, 0, _("File daemon \"%s\" rejected Job command: %s\n"), jcr->res.client->hdr.name, fd->msg); jcr->setJobStatus(JS_ErrorTerminated); return 0; } else if (jcr->db) { CLIENT_DBR cr; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, jcr->res.client->hdr.name, sizeof(cr.Name)); cr.AutoPrune = jcr->res.client->AutoPrune; cr.FileRetention = jcr->res.client->FileRetention; cr.JobRetention = jcr->res.client->JobRetention; bstrncpy(cr.Uname, fd->msg+strlen(OKjob)+1, sizeof(cr.Uname)); if (!db_update_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_WARNING, 0, _("Error updating Client record. ERR=%s\n"), db_strerror(jcr->db)); } } } else { Jmsg(jcr, M_FATAL, 0, _("FD gave bad response to JobId command: %s\n"), bnet_strerror(fd)); jcr->setJobStatus(JS_ErrorTerminated); return 0; } } return 1; } bool send_previous_restore_objects(JCR *jcr) { int JobLevel; JobLevel = jcr->getJobLevel(); switch (JobLevel) { case L_DIFFERENTIAL: case L_INCREMENTAL: if (jcr->previous_jr.JobId > 0) { if (!send_restore_objects(jcr, jcr->previous_jr.JobId, false)) { return false; } } break; default: break; } return true; } bool send_bwlimit_to_fd(JCR *jcr, const char *Job) { BSOCK *fd = jcr->file_bsock; if (jcr->FDVersion >= FD_VERSION_4) { fd->fsend(bandwidthcmd, jcr->max_bandwidth, Job); if (!response(jcr, fd, OKBandwidth, "Bandwidth", DISPLAY_ERROR)) { jcr->max_bandwidth = 0; /* can't set bandwidth limit */ return false; } } return true; } static inline void send_since_time(JCR *jcr) { char ed1[50]; utime_t stime; BSOCK *fd = jcr->file_bsock; stime = str_to_utime(jcr->stime); fd->fsend(levelcmd, "", NT_("since_utime "), edit_uint64(stime, ed1), 0, NT_("prev_job="), jcr->PrevJob); while (bget_dirmsg(fd) >= 0) { /* allow him to poll us to sync clocks */ Jmsg(jcr, M_INFO, 0, "%s\n", fd->msg); } } /* * Send level command to FD. * Used for backup jobs and estimate command. */ bool send_level_command(JCR *jcr) { int JobLevel; BSOCK *fd = jcr->file_bsock; const char *accurate = jcr->accurate ? "accurate_" : ""; const char *not_accurate = ""; const char *rerunning = jcr->rerunning ? " rerunning " : " "; /* * Send Level command to File daemon */ JobLevel = jcr->getJobLevel(); switch (JobLevel) { case L_BASE: fd->fsend(levelcmd, not_accurate, "base", rerunning, 0, "", ""); break; case L_NONE: /* L_NONE is the console, sending something off to the FD */ case L_FULL: fd->fsend(levelcmd, not_accurate, "full", rerunning, 0, "", ""); break; case L_DIFFERENTIAL: fd->fsend(levelcmd, accurate, "differential", rerunning, 0, "", ""); send_since_time(jcr); break; case L_INCREMENTAL: fd->fsend(levelcmd, accurate, "incremental", rerunning, 0, "", ""); send_since_time(jcr); break; case L_SINCE: Jmsg2(jcr, M_FATAL, 0, _("Unimplemented backup level %d %c\n"), JobLevel, JobLevel); break; default: Jmsg2(jcr, M_FATAL, 0, _("Unimplemented backup level %d %c\n"), JobLevel, JobLevel); return 0; } Dmsg1(120, ">filed: %s", fd->msg); if (!response(jcr, fd, OKlevel, "Level", DISPLAY_ERROR)) { return false; } return true; } /* * Send either an Included or an Excluded list to FD */ static bool send_fileset(JCR *jcr) { FILESETRES *fileset = jcr->res.fileset; BSOCK *fd = jcr->file_bsock; STORERES *store = jcr->res.wstore; int num; bool include = true; while (1) { if (include) { num = fileset->num_includes; } else { num = fileset->num_excludes; } for (int i = 0; i < num; i++) { char *item; INCEXE *ie; if (include) { ie = fileset->include_items[i]; fd->fsend("I\n"); } else { ie = fileset->exclude_items[i]; fd->fsend("E\n"); } for (int j = 0; j < ie->ignoredir.size(); j++) { fd->fsend("Z %s\n", ie->ignoredir.get(j)); } for (int j = 0; j < ie->num_opts; j++) { FOPTS *fo = ie->opts_list[j]; bool enhanced_wild = false; for (int k = 0; fo->opts[k] != '\0'; k++) { if (fo->opts[k] == 'W') { enhanced_wild = true; break; } } /* * Strip out compression option Zn if disallowed for this Storage */ if (store && !store->AllowCompress) { char newopts[MAX_FOPTS]; bool done = false; /* print warning only if compression enabled in FS */ int l = 0; for (int k = 0; fo->opts[k] != '\0'; k++) { /* * Z compress option is followed by the single-digit compress level or 'o' * For fastlz its Zf with a single char selecting the actual compression algo. */ if (fo->opts[k] == 'Z' && fo->opts[k + 1] == 'f') { done = true; k += 2; /* skip option */ } else if (fo->opts[k] == 'Z') { done = true; k++; /* skip option and level */ } else { newopts[l] = fo->opts[k]; l++; } } newopts[l] = '\0'; if (done) { Jmsg(jcr, M_INFO, 0, _("FD compression disabled for this Job because AllowCompress=No in Storage resource.\n") ); } /* * Send the new trimmed option set without overwriting fo->opts */ fd->fsend("O %s\n", newopts); } else { /* * Send the original options */ fd->fsend("O %s\n", fo->opts); } for (int k = 0; k < fo->regex.size(); k++) { fd->fsend("R %s\n", fo->regex.get(k)); } for (int k = 0; k < fo->regexdir.size(); k++) { fd->fsend("RD %s\n", fo->regexdir.get(k)); } for (int k = 0; k < fo->regexfile.size(); k++) { fd->fsend("RF %s\n", fo->regexfile.get(k)); } for (int k = 0; kwild.size(); k++) { fd->fsend("W %s\n", fo->wild.get(k)); } for (int k = 0; k < fo->wilddir.size(); k++) { fd->fsend("WD %s\n", fo->wilddir.get(k)); } for (int k = 0; k < fo->wildfile.size(); k++) { fd->fsend("WF %s\n", fo->wildfile.get(k)); } for (int k = 0; k < fo->wildbase.size(); k++) { fd->fsend("W%c %s\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k)); } for (int k = 0; k < fo->base.size(); k++) { fd->fsend("B %s\n", fo->base.get(k)); } for (int k = 0; k < fo->fstype.size(); k++) { fd->fsend("X %s\n", fo->fstype.get(k)); } for (int k = 0; k < fo->drivetype.size(); k++) { fd->fsend("XD %s\n", fo->drivetype.get(k)); } if (fo->plugin) { fd->fsend("G %s\n", fo->plugin); } if (fo->reader) { fd->fsend("D %s\n", fo->reader); } if (fo->writer) { fd->fsend("T %s\n", fo->writer); } fd->fsend("N\n"); } for (int j = 0; j < ie->name_list.size(); j++) { item = (char *)ie->name_list.get(j); if (!send_list_item(jcr, "F ", item, fd)) { goto bail_out; } } fd->fsend("N\n"); for (int j = 0; j < ie->plugin_list.size(); j++) { item = (char *)ie->plugin_list.get(j); if (!send_list_item(jcr, "P ", item, fd)) { goto bail_out; } } fd->fsend("N\n"); } if (!include) { /* If we just did excludes */ break; /* all done */ } include = false; /* Now do excludes */ } fd->signal(BNET_EOD); /* end of data */ if (!response(jcr, fd, OKinc, "Include", DISPLAY_ERROR)) { goto bail_out; } return true; bail_out: jcr->setJobStatus(JS_ErrorTerminated); return false; } static bool send_list_item(JCR *jcr, const char *code, char *item, BSOCK *fd) { BPIPE *bpipe; FILE *ffd; char buf[2000]; int optlen, status; char *p = item; switch (*p) { case '|': p++; /* skip over the | */ fd->msg = edit_job_codes(jcr, fd->msg, p, ""); bpipe = open_bpipe(fd->msg, 0, "r"); if (!bpipe) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"), p, be.bstrerror()); return false; } bstrncpy(buf, code, sizeof(buf)); Dmsg1(500, "code=%s\n", buf); optlen = strlen(buf); while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) { fd->msglen = Mmsg(fd->msg, "%s", buf); Dmsg2(500, "Inc/exc len=%d: %s", fd->msglen, fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); return false; } } if ((status = close_bpipe(bpipe)) != 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. ERR=%s\n"), p, be.bstrerror(status)); return false; } break; case '<': p++; /* skip over < */ if ((ffd = fopen(p, "rb")) == NULL) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Cannot open included file: %s. ERR=%s\n"), p, be.bstrerror()); return false; } bstrncpy(buf, code, sizeof(buf)); Dmsg1(500, "code=%s\n", buf); optlen = strlen(buf); while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) { fd->msglen = Mmsg(fd->msg, "%s", buf); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); fclose(ffd); return false; } } fclose(ffd); break; case '\\': p++; /* skip over \ */ /* Note, fall through wanted */ default: pm_strcpy(fd->msg, code); fd->msglen = pm_strcat(fd->msg, p); Dmsg1(500, "Inc/Exc name=%s\n", fd->msg); if (!fd->send()) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); return false; } break; } return true; } /* * Send include list to File daemon */ bool send_include_list(JCR *jcr) { BSOCK *fd = jcr->file_bsock; if (jcr->res.fileset->new_include) { fd->fsend(filesetcmd, jcr->res.fileset->enable_vss ? " vss=1" : ""); return send_fileset(jcr); } return true; } /* * Send exclude list to File daemon * Under the new scheme, the Exclude list * is part of the FileSet sent with the * "include_list" above. */ bool send_exclude_list(JCR *jcr) { return true; } /* * This checks to see if there are any non local runscripts for this job. */ static inline bool have_client_runscripts(alist *run_scripts) { RUNSCRIPT *cmd; bool retval = false; if (run_scripts->empty()) { return false; } foreach_alist(cmd, run_scripts) { if (!cmd->is_local()) { retval = true; } } return retval; } /* * Send RunScripts to File daemon * 1) We send all runscript to FD, they can be executed Before, After, or twice * 2) Then, we send a "RunBeforeNow" command to the FD to tell him to do the * first run_script() call. (ie ClientRunBeforeJob) */ int send_runscripts_commands(JCR *jcr) { int result; RUNSCRIPT *cmd; POOLMEM *msg, *ehost; BSOCK *fd = jcr->file_bsock; bool has_before_jobs = false; /* * See if there are any runscripts that need to be ran on the client. */ if (!have_client_runscripts(jcr->res.job->RunScripts)) { return 1; } Dmsg0(120, "bdird: sending runscripts to fd\n"); msg = get_pool_memory(PM_FNAME); ehost = get_pool_memory(PM_FNAME); foreach_alist(cmd, jcr->res.job->RunScripts) { if (cmd->can_run_at_level(jcr->getJobLevel()) && cmd->target) { ehost = edit_job_codes(jcr, ehost, cmd->target, ""); Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost); if (bstrcmp(ehost, jcr->res.client->name())) { pm_strcpy(msg, cmd->command); bash_spaces(msg); Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command); fd->fsend(runscriptcmd, cmd->on_success, cmd->on_failure, cmd->fail_on_error, cmd->when, msg); result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR); if (!result) { goto bail_out; } } /* TODO : we have to play with other client */ /* else { send command to an other client } */ } /* * See if this is a ClientRunBeforeJob. */ if (cmd->when & SCRIPT_Before || cmd->when & SCRIPT_AfterVSS) { has_before_jobs = true; } } /* * Tell the FD to execute the ClientRunBeforeJob */ if (has_before_jobs) { fd->fsend(runbeforenowcmd); if (!response(jcr, fd, OKRunBeforeNow, "RunBeforeNow", DISPLAY_ERROR)) { goto bail_out; } } free_pool_memory(msg); free_pool_memory(ehost); return 1; bail_out: Jmsg(jcr, M_FATAL, 0, _("Client \"%s\" RunScript failed.\n"), ehost); free_pool_memory(msg); free_pool_memory(ehost); return 0; } struct OBJ_CTX { JCR *jcr; int count; }; /* * restore_object_handler is called for each file found */ static int restore_object_handler(void *ctx, int num_fields, char **row) { BSOCK *fd; bool is_compressed; OBJ_CTX *octx = (OBJ_CTX *)ctx; JCR *jcr = octx->jcr; fd = jcr->file_bsock; if (jcr->is_job_canceled()) { return 1; } /* * Old File Daemon doesn't handle restore objects */ if (jcr->FDVersion < FD_VERSION_3) { Jmsg(jcr, M_WARNING, 0, _("Client \"%s\" may not be used to restore " "this job. Please upgrade your client.\n"), jcr->res.client->name()); return 1; } if (jcr->FDVersion < FD_VERSION_5) { /* Old version without PluginName */ fd->fsend("restoreobject JobId=%s %s,%s,%s,%s,%s,%s\n", row[0], row[1], row[2], row[3], row[4], row[5], row[6]); } else { /* * bash spaces from PluginName */ bash_spaces(row[9]); fd->fsend("restoreobject JobId=%s %s,%s,%s,%s,%s,%s,%s\n", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[9]); } Dmsg1(010, "Send obj hdr=%s", fd->msg); fd->msglen = pm_strcpy(fd->msg, row[7]); fd->send(); /* send Object name */ Dmsg1(010, "Send obj: %s\n", fd->msg); db_unescape_object(jcr, jcr->db, row[8], /* Object */ str_to_uint64(row[1]), /* Object length */ &fd->msg, &fd->msglen); fd->send(); /* send object */ octx->count++; /* * Don't try to print compressed objects. */ is_compressed = str_to_uint64(row[5]) > 0; if (debug_level >= 100 && !is_compressed) { for (int i = 0; i < fd->msglen; i++) { if (!fd->msg[i]) { fd->msg[i] = ' '; } } Dmsg1(100, "Send obj: %s\n", fd->msg); } return 0; } bool send_plugin_options(JCR *jcr) { BSOCK *fd = jcr->file_bsock; POOLMEM *msg; if (jcr->plugin_options) { msg = get_pool_memory(PM_FNAME); pm_strcpy(msg, jcr->plugin_options); bash_spaces(msg); fd->fsend(pluginoptionscmd, msg); free_pool_memory(msg); if (!response(jcr, fd, OKPluginOptions, "PluginOptions", DISPLAY_ERROR)) { Jmsg(jcr, M_FATAL, 0, _("Plugin options failed.\n")); return false; } } return true; } static inline void send_global_restore_objects(JCR *jcr, OBJ_CTX *octx) { POOL_MEM query(PM_MESSAGE); char ed1[50]; if (!jcr->JobIds || !jcr->JobIds[0]) { return; } /* * Send restore objects for all jobs involved */ Mmsg(query, get_restore_objects, jcr->JobIds, FT_RESTORE_FIRST); db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)octx); Mmsg(query, get_restore_objects, jcr->JobIds, FT_PLUGIN_CONFIG); db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)octx); /* * Send config objects for the current restore job */ Mmsg(query, get_restore_objects, edit_uint64(jcr->JobId, ed1), FT_PLUGIN_CONFIG_FILLED); db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)octx); } static inline void send_job_specific_restore_objects(JCR *jcr, JobId_t JobId, OBJ_CTX *octx) { POOL_MEM query(PM_MESSAGE); char ed1[50]; /* * Send restore objects for specific JobId. */ Mmsg(query, get_restore_objects, edit_uint64(JobId, ed1), FT_RESTORE_FIRST); db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)octx); Mmsg(query, get_restore_objects, edit_uint64(JobId, ed1), FT_PLUGIN_CONFIG); db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)octx); } bool send_restore_objects(JCR *jcr, JobId_t JobId, bool send_global) { BSOCK *fd; OBJ_CTX octx; octx.jcr = jcr; octx.count = 0; if (send_global) { send_global_restore_objects(jcr, &octx); } else { send_job_specific_restore_objects(jcr, JobId, &octx); } /* * Send to FD only if we have at least one restore object. * This permits backward compatibility with older FDs. */ if (octx.count > 0) { fd = jcr->file_bsock; fd->fsend(restoreobjectendcmd); if (!response(jcr, fd, OKRestoreObject, "RestoreObject", DISPLAY_ERROR)) { Jmsg(jcr, M_FATAL, 0, _("RestoreObject failed.\n")); return false; } } return true; } /* * Read the attributes from the File daemon for * a Verify job and store them in the catalog. */ int get_attributes_and_put_in_catalog(JCR *jcr) { BSOCK *fd; int n = 0; ATTR_DBR *ar = NULL; POOL_MEM digest(PM_FNAME); fd = jcr->file_bsock; jcr->jr.FirstIndex = 1; jcr->FileIndex = 0; /* Start transaction allocates jcr->attr and jcr->ar if needed */ db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ ar = jcr->ar; Dmsg0(120, "bdird: waiting to receive file attributes\n"); /* Pickup file attributes and digest */ while (!fd->errors && (n = bget_dirmsg(fd)) > 0) { uint32_t file_index; int stream, len; char *p, *fn; POOL_MEM Digest(PM_NAME); /* either Verify opts or MD5/SHA1 digest */ if ((len = sscanf(fd->msg, "%ld %d %s", &file_index, &stream, Digest.c_str())) != 3) { Jmsg(jcr, M_FATAL, 0, _("msglen, fd->msg); jcr->setJobStatus(JS_ErrorTerminated); return 0; } p = fd->msg; /* The following three fields were sscanf'ed above so skip them */ skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); skip_nonspaces(&p); /* skip Stream */ skip_spaces(&p); skip_nonspaces(&p); /* skip Opts_Digest */ p++; /* skip space */ Dmsg1(dbglvl, "Stream=%d\n", stream); if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX) { if (jcr->cached_attribute) { Dmsg3(dbglvl, "Cached attr. Stream=%d fname=%s\n", ar->Stream, ar->fname, ar->attr); if (!db_create_file_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } } /* Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */ fn = jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen); while (*p != 0) { *fn++ = *p++; /* copy filename */ } *fn = *p++; /* term filename and point p to attribs */ pm_strcpy(jcr->attr, p); /* save attributes */ jcr->JobFiles++; jcr->FileIndex = file_index; ar->attr = jcr->attr; ar->fname = jcr->fname; ar->FileIndex = file_index; ar->Stream = stream; ar->link = NULL; ar->JobId = jcr->JobId; ar->ClientId = jcr->ClientId; ar->PathId = 0; ar->FilenameId = 0; ar->Digest = NULL; ar->DigestType = CRYPTO_DIGEST_NONE; ar->DeltaSeq = 0; jcr->cached_attribute = true; Dmsg2(dbglvl, "dirdfname); Dmsg1(dbglvl, "dirdattr); jcr->FileId = ar->FileId; /* * First, get STREAM_UNIX_ATTRIBUTES and fill ATTR_DBR structure * Next, we CAN have a CRYPTO_DIGEST, so we fill ATTR_DBR with it (or not) * When we get a new STREAM_UNIX_ATTRIBUTES, we known that we can add file to the catalog * At the end, we have to add the last file */ } else if (crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) { if (jcr->FileIndex != (uint32_t)file_index) { Jmsg3(jcr, M_ERROR, 0, _("%s index %d not same as attributes %d\n"), stream_to_ascii(stream), file_index, jcr->FileIndex); continue; } ar->Digest = digest.c_str(); ar->DigestType = crypto_digest_stream_type(stream); db_escape_string(jcr, jcr->db, digest.c_str(), Digest.c_str(), strlen(Digest.c_str())); Dmsg4(dbglvl, "stream=%d DigestLen=%d Digest=%s type=%d\n", stream, strlen(digest.c_str()), digest.c_str(), ar->DigestType); } jcr->jr.JobFiles = jcr->JobFiles = file_index; jcr->jr.LastIndex = file_index; } if (is_bnet_error(fd)) { Jmsg1(jcr, M_FATAL, 0, _("bstrerror()); return 0; } if (jcr->cached_attribute) { Dmsg3(dbglvl, "Cached attr with digest. Stream=%d fname=%s attr=%s\n", ar->Stream, ar->fname, ar->attr); if (!db_create_file_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } jcr->setJobStatus(JS_Terminated); return 1; } /* * Cancel a job running in the File daemon */ bool cancel_file_daemon_job(UAContext *ua, JCR *jcr) { BSOCK *fd; ua->jcr->res.client = jcr->res.client; if (!connect_to_file_daemon(ua->jcr, 10, me->FDConnectTimeout, true, false)) { ua->error_msg(_("Failed to connect to File daemon.\n")); return false; } Dmsg0(200, "Connected to file daemon\n"); fd = ua->jcr->file_bsock; fd->fsend("cancel Job=%s\n", jcr->Job); while (fd->recv() >= 0) { ua->send_msg("%s", fd->msg); } fd->signal(BNET_TERMINATE); fd->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; jcr->file_bsock->set_terminated(); jcr->my_thread_send_signal(TIMEOUT_SIGNAL); return true; } /* * Get the status of a remote File Daemon. */ void do_native_client_status(UAContext *ua, CLIENTRES *client, char *cmd) { BSOCK *fd; /* * Connect to File daemon */ ua->jcr->res.client = client; /* * Try to connect for 15 seconds */ if (!ua->api) { ua->send_msg(_("Connecting to Client %s at %s:%d\n"), client->name(), client->address, client->FDport); } if (!connect_to_file_daemon(ua->jcr, 1, 15, false, false)) { ua->send_msg(_("Failed to connect to Client %s.\n====\n"), client->name()); if (ua->jcr->file_bsock) { ua->jcr->file_bsock->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; } return; } Dmsg0(20, _("Connected to file daemon\n")); fd = ua->jcr->file_bsock; if (cmd) { fd->fsend(".status %s", cmd); } else { fd->fsend("status"); } while (fd->recv() >= 0) { ua->send_msg("%s", fd->msg); } fd->signal(BNET_TERMINATE); fd->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; return; } /* * resolve a host on a filedaemon */ void do_client_resolve(UAContext *ua, CLIENTRES *client) { BSOCK *fd; /* * Connect to File daemon */ ua->jcr->res.client = client; /* * Try to connect for 15 seconds */ if (!ua->api) { ua->send_msg(_("Connecting to Client %s at %s:%d\n"), client->name(), client->address, client->FDport); } if (!connect_to_file_daemon(ua->jcr, 1, 15, false, false)) { ua->send_msg(_("Failed to connect to Client %s.\n====\n"), client->name()); if (ua->jcr->file_bsock) { ua->jcr->file_bsock->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; } return; } Dmsg0(20, _("Connected to file daemon\n")); fd = ua->jcr->file_bsock; for (int i = 1; i < ua->argc; i++) { if (!*ua->argk[i]) { continue; } fd->fsend("resolve %s", ua->argk[i]); while (fd->recv() >= 0) { ua->send_msg("%s", fd->msg); } } fd->signal(BNET_TERMINATE); fd->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; return; } bareos-Release-14.2.6/src/dird/getmsg.c000066400000000000000000000322371263011562700176120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- routines to receive network data and * handle network signals. These routines handle the connections * to the Storage daemon and the File daemon. * * Kern Sibbald, August MM * * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: * Handle network signals (signals). * Signals always have return status 0 from bnet_recv() and * a zero or negative message length. * Pass appropriate messages back to the caller (responses). * Responses always have a digit as the first character. * Handle requests for message and catalog services (requests). * Requests are any message that does not begin with a digit. * In affect, they are commands. */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ static char *find_msg_start(char *msg); static char Job_status[] = "Status Job=%127s JobStatus=%d\n"; #ifdef needed static char Device_update[] = "DevUpd Job=%127s " "device=%127s " "append=%d read=%d num_writers=%d " "open=%d labeled=%d offline=%d " "reserved=%d max_writers=%d " "autoselect=%d autochanger=%d " "changer_name=%127s media_type=%127s volume_name=%127s " "DevReadTime=%d DevWriteTime=%d DevReadBytes=%d " "DevWriteBytes=%d\n"; #endif static char OK_msg[] = "1000 OK\n"; static void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus) { bool set_waittime = false; Dmsg2(800, "set_jcr_sd_job_status(%s, %c)\n", jcr->Job, SDJobStatus); /* * If wait state is new, we keep current time for watchdog MaxWaitTime */ switch (SDJobStatus) { case JS_WaitMedia: case JS_WaitMount: case JS_WaitMaxJobs: set_waittime = true; default: break; } if (job_waiting(jcr)) { set_waittime = false; } if (set_waittime) { /* * Set it before JobStatus */ Dmsg0(800, "Setting wait_time\n"); jcr->wait_time = time(NULL); } jcr->SDJobStatus = SDJobStatus; /* * Some SD Job status setting are propagated to the controlling Job. */ switch (jcr->SDJobStatus) { case JS_Incomplete: jcr->setJobStatus(JS_Incomplete); break; case JS_FatalError: jcr->setJobStatus(JS_FatalError); break; default: break; } } /* * Get a message * Call appropriate processing routine * If it is not a Jmsg or a ReqCat message, * return it to the caller. * * This routine is called to get the next message from * another daemon. If the message is in canonical message * format and the type is known, it will be dispatched * to the appropriate handler. If the message is * in any other format, it will be returned. * * E.g. any message beginning with a digit will be passed * through to the caller. * All other messages are expected begin with some identifier * -- for the moment only the first character is checked, but * at a later time, the whole identifier (e.g. Jmsg, CatReq, ...) * could be checked. This is followed by Job=Jobname * info. The identifier is used to dispatch the message to the right * place (Job message, catalog request, ...). The Job is used to lookup * the JCR so that the action is performed on the correct jcr, and * the rest of the message is up to the user. Note, DevUpd uses * *System* for the Job name, and hence no JCR is obtained. This * is a *rare* case where a jcr is not really needed. * */ int bget_dirmsg(BSOCK *bs, bool allow_any_message) { int32_t n = BNET_TERMINATE; char Job[MAX_NAME_LENGTH]; char MsgType[20]; int type; utime_t mtime; /* message time */ JCR *jcr = bs->jcr(); char *msg; for ( ; !bs->is_stop() && !bs->is_timed_out(); ) { n = bs->recv(); Dmsg2(200, "bget_dirmsg %d: %s\n", n, bs->msg); if (bs->is_stop() || bs->is_timed_out()) { return n; /* error or terminate */ } if (n == BNET_SIGNAL) { /* handle signal */ /* BNET_SIGNAL (-1) return from bnet_recv() => network signal */ switch (bs->msglen) { case BNET_EOD: /* end of data */ return n; case BNET_EOD_POLL: bs->fsend(OK_msg);/* send response */ return n; /* end of data */ case BNET_TERMINATE: bs->set_terminated(); return n; case BNET_POLL: bs->fsend(OK_msg); /* send response */ break; case BNET_HEARTBEAT: // encode_time(time(NULL), Job); // Dmsg1(100, "%s got heartbeat.\n", Job); break; case BNET_HB_RESPONSE: break; case BNET_STATUS: /* *****FIXME***** Implement more completely */ bs->fsend("Status OK\n"); bs->signal(BNET_EOD); break; case BNET_BTIME: /* send BAREOS time */ char ed1[50]; bs->fsend("btime %s\n", edit_uint64(get_current_btime(),ed1)); break; default: Jmsg1(jcr, M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen); return n; } continue; } /* * Handle normal data */ if (n > 0 && B_ISDIGIT(bs->msg[0])) { /* response? */ return n; /* yes, return it */ } /* * If we get here, it must be a request. Either * a message to dispatch, or a catalog request. * Try to fulfill it. */ if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) { /* * If the special flag allow_any_message is given ignore * the error and just return it as normal data. */ if (allow_any_message) { return n; } else { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); continue; } } /* * Skip past "Jmsg Job=nnn" */ if (!(msg=find_msg_start(bs->msg))) { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); continue; } /* * Here we are expecting a message of the following format: * Jmsg Job=nnn type=nnn level=nnn Message-string * Note, level should really be mtime, but that changes * the protocol. */ if (bs->msg[0] == 'J') { /* Job message */ if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%lld", Job, &type, &mtime) != 3) { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); continue; } Dmsg1(900, "Got msg: %s\n", bs->msg); skip_spaces(&msg); skip_nonspaces(&msg); /* skip type=nnn */ skip_spaces(&msg); skip_nonspaces(&msg); /* skip level=nnn */ if (*msg == ' ') { msg++; /* skip leading space */ } Dmsg1(900, "Dispatch msg: %s", msg); dispatch_message(jcr, type, mtime, msg); continue; } /* * Here we expact a CatReq message * CatReq Job=nn Catalog-Request-Message */ if (bs->msg[0] == 'C') { /* Catalog request */ Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg); catalog_request(jcr, bs); continue; } if (bs->msg[0] == 'U') { /* SD sending attributes */ Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg); catalog_update(jcr, bs); continue; } if (bs->msg[0] == 'B') { /* SD sending file spool attributes */ Dmsg2(100, "Blast attributes jcr 0x%x: %s", jcr, bs->msg); char filename[256]; if (sscanf(bs->msg, "BlastAttr Job=%127s File=%255s", Job, filename) != 2) { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); continue; } unbash_spaces(filename); if (despool_attributes_from_file(jcr, filename)) { bs->fsend("1000 OK BlastAttr\n"); } else { bs->fsend("1990 ERROR BlastAttr\n"); } continue; } if (bs->msg[0] == 'M') { /* Mount request */ Dmsg1(900, "Mount req: %s", bs->msg); mount_request(jcr, bs, msg); continue; } if (bs->msg[0] == 'S') { /* Status change */ int JobStatus; char Job[MAX_NAME_LENGTH]; if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) { set_jcr_sd_job_status(jcr, JobStatus); /* current status */ } else { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); } continue; } #ifdef needed /* No JCR for Device Updates! */ if (bs->msg[0] = 'D') { /* Device update */ DEVICE *dev; POOL_MEM dev_name, changer_name, media_type, volume_name; int dev_open, dev_append, dev_read, dev_labeled; int dev_offline, dev_autochanger, dev_autoselect; int dev_num_writers, dev_max_writers, dev_reserved; uint64_t dev_read_time, dev_write_time, dev_write_bytes, dev_read_bytes; uint64_t dev_PoolId; Dmsg1(100, "msg); if (sscanf(bs->msg, Device_update, &Job, dev_name.c_str(), &dev_append, &dev_read, &dev_num_writers, &dev_open, &dev_labeled, &dev_offline, &dev_reserved, &dev_max_writers, &dev_autoselect, &dev_autochanger, changer_name.c_str(), media_type.c_str(), volume_name.c_str(), &dev_read_time, &dev_write_time, &dev_read_bytes, &dev_write_bytes) != 19) { Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); } else { unbash_spaces(dev_name); dev = (DEVICE *)GetResWithName(R_DEVICE, dev_name.c_str()); if (!dev) { continue; } unbash_spaces(changer_name); unbash_spaces(media_type); unbash_spaces(volume_name); bstrncpy(dev->ChangerName, changer_name.c_str(), sizeof(dev->ChangerName)); bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType)); bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName)); /* Note, these are copied because they are boolean rather than * integer. */ dev->open = dev_open; dev->append = dev_append; dev->read = dev_read; dev->labeled = dev_labeled; dev->offline = dev_offline; dev->autoselect = dev_autoselect; dev->autochanger = dev_autochanger > 0; dev->num_drives = dev_autochanger; /* does double duty */ dev->PoolId = dev_PoolId; dev->num_writers = dev_num_writers; dev->max_writers = dev_max_writers; dev->reserved = dev_reserved; dev->found = true; dev->DevReadTime = dev_read_time; /* TODO : have to update database */ dev->DevWriteTime = dev_write_time; dev->DevReadBytes = dev_read_bytes; dev->DevWriteBytes = dev_write_bytes; } continue; } #endif return n; } return n; } static char *find_msg_start(char *msg) { char *p = msg; skip_nonspaces(&p); /* skip message type */ skip_spaces(&p); skip_nonspaces(&p); /* skip Job */ skip_spaces(&p); /* after spaces come the message */ return p; } /* * Get response from FD or SD to a command we * sent. Check that the response agrees with what we expect. * * Returns: false on failure * true on success */ bool response(JCR *jcr, BSOCK *bs, char *resp, const char *cmd, e_prtmsg prtmsg) { int n; if (is_bnet_error(bs)) { return false; } if ((n = bget_dirmsg(bs)) >= 0) { if (bstrcmp(bs->msg, resp)) { return true; } if (prtmsg == DISPLAY_ERROR) { Jmsg(jcr, M_FATAL, 0, _("Bad response to %s command: wanted %s, got %s\n"), cmd, resp, bs->msg); } return false; } Jmsg(jcr, M_FATAL, 0, _("Socket error on %s command: ERR=%s\n"), cmd, bnet_strerror(bs)); return false; } bareos-Release-14.2.6/src/dird/inc_conf.c000066400000000000000000000632561263011562700201070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Configuration file parser for new and old Include and * Exclude records * * Kern Sibbald, March MMIII */ #include "bareos.h" #include "dird.h" #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif #include "findlib/find.h" /* Forward referenced subroutines */ /* * Imported subroutines */ extern void store_inc(LEX *lc, RES_ITEM *item, int index, int pass); /* We build the current new Include and Exclude items here */ static INCEXE res_incexe; /* * new Include/Exclude items * name handler value code flags default_value */ static RES_ITEM newinc_items[] = { { "file", CFG_TYPE_FNAME, { 0 }, 0, 0, NULL }, { "plugin", CFG_TYPE_PLUGINNAME, { 0 }, 0, 0, NULL }, { "excludedircontaining", CFG_TYPE_EXCLUDEDIR, { 0 }, 0, 0, NULL }, { "options", CFG_TYPE_OPTIONS, { 0 }, 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Items that are valid in an Options resource * name handler value code flags default_value */ static RES_ITEM options_items[] = { { "compression", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "signature", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "basejob", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "accurate", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "verify", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "onefs", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "recurse", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "sparse", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "hardlinks", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "readfifo", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "replace", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "portable", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "mtimeonly", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "keepatime", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "regex", CFG_TYPE_REGEX, { 0 }, 0, 0, NULL }, { "regexdir", CFG_TYPE_REGEX, { 0 }, 1, 0, NULL }, { "regexfile", CFG_TYPE_REGEX, { 0 }, 2, 0, NULL }, { "base", CFG_TYPE_BASE, { 0 }, 0, 0, NULL }, { "wild", CFG_TYPE_WILD, { 0 }, 0, 0, NULL }, { "wilddir", CFG_TYPE_WILD, { 0 }, 1, 0, NULL }, { "wildfile", CFG_TYPE_WILD, { 0 }, 2, 0, NULL }, { "exclude", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "aclsupport", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "plugin", CFG_TYPE_PLUGIN, { 0 }, 0, 0, NULL }, { "ignorecase", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "fstype", CFG_TYPE_FSTYPE, { 0 }, 0, 0, NULL }, { "hfsplussupport", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "noatime", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "enhancedwild", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "drivetype", CFG_TYPE_DRIVETYPE, { 0 }, 0, 0, NULL }, { "checkfilechanges", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "strippath", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "honornodumpflag", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "xattrsupport", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "size", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "shadowing", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "autoexclude", CFG_TYPE_OPTION, { 0 }, 0, 0, NULL }, { "meta", CFG_TYPE_META, { 0 }, 0, 0, 0 }, { NULL, 0, { 0 }, 0, 0, NULL } }; #include "inc_conf.h" /* * determine used compression algorithms */ void find_used_compressalgos(POOL_MEM *compressalgos, JCR *jcr) { int cnt = 0; INCEXE *inc; FOPTS *fopts; FILESETRES *fs; struct s_fs_opt *fs_opt; if (!jcr->res.job || !jcr->res.job->fileset) { return; } fs = jcr->res.job->fileset; for (int i = 0; i < fs->num_includes; i++) { /* Parse all Include {} */ inc = fs->include_items[i]; for (int j = 0; j < inc->num_opts; j++) { /* Parse all Options {} */ fopts = inc->opts_list[j]; for (char *k = fopts->opts; *k; k++) { /* Try to find one request */ switch (*k) { case 'Z': /* Compression */ for (fs_opt = FS_options; fs_opt->name; fs_opt++) { if (fs_opt->keyword != INC_KW_COMPRESSION) { continue; } if (bstrncmp(k, fs_opt->option, strlen(fs_opt->option))) { if (cnt > 0) { compressalgos->strcat(","); } else { compressalgos->strcat(" ("); } compressalgos->strcat(fs_opt->name); k += strlen(fs_opt->option) - 1; cnt++; continue; } } break; default: break; } } } } if (cnt > 0) { compressalgos->strcat(")"); } } /* * Check if the configured options are valid. */ static inline void is_in_permitted_set(LEX *lc, const char *set_type, const char *permitted_set) { const char *p, *q; bool found; for (p = lc->str; *p; p++) { found = false; for (q = permitted_set; *q; q++) { if (*p == *q) { found = true; break; } } if (!found) { scan_err3(lc, _("Illegal %s option %c, got option string: %s:"), set_type, *p, lc->str); } } } /* * Scan for right hand side of Include options (keyword=option) is * converted into one or two characters. Verifyopts=xxxx is Vxxxx: * Whatever is found is concatenated to the opts string. * * This code is also used inside an Options resource. */ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) { int i; char option[64]; int lcopts = lc->options; struct s_sz_matching size_matching; memset(option, 0, sizeof(option)); lc->options |= LOPT_STRING; /* force string */ lex_get_token(lc, T_STRING); /* expect at least one option */ if (keyword == INC_KW_VERIFY) { /* special case */ is_in_permitted_set(lc, _("verify"), PERMITTED_VERIFY_OPTIONS); bstrncat(opts, "V", optlen); /* indicate Verify */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } else if (keyword == INC_KW_ACCURATE) { /* special case */ is_in_permitted_set(lc, _("accurate"), PERMITTED_ACCURATE_OPTIONS); bstrncat(opts, "C", optlen); /* indicate Accurate */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } else if (keyword == INC_KW_BASEJOB) { /* special case */ is_in_permitted_set(lc, _("base job"), PERMITTED_BASEJOB_OPTIONS); bstrncat(opts, "J", optlen); /* indicate BaseJob */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } else if (keyword == INC_KW_STRIPPATH) { /* special case */ if (!is_an_integer(lc->str)) { scan_err1(lc, _("Expected a strip path positive integer, got: %s:"), lc->str); } bstrncat(opts, "P", optlen); /* indicate strip path */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } else if (keyword == INC_KW_SIZE) { /* special case */ if (!parse_size_match(lc->str, &size_matching)) { scan_err1(lc, _("Expected a parseable size, got: %s:"), lc->str); } bstrncat(opts, "z", optlen); /* indicate size */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } else { /* * Standard keyword options for Include/Exclude */ for (i = 0; FS_options[i].name; i++) { if (FS_options[i].keyword == keyword && bstrcasecmp(lc->str, FS_options[i].name)) { bstrncpy(option, FS_options[i].option, sizeof(option)); i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a FileSet option keyword, got: %s:"), lc->str); } else { /* add option */ bstrncat(opts, option, optlen); Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } } lc->options = lcopts; /* * If option terminated by comma, eat it */ if (lc->ch == ',') { lex_get_token(lc, T_ALL); /* yes, eat comma */ } } /* Store regex info */ static void store_regex(LEX *lc, RES_ITEM *item, int index, int pass) { int token, rc; regex_t preg; char prbuf[500]; const char *type; int newsize; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup regex string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: rc = regcomp(&preg, lc->str, REG_EXTENDED); if (rc != 0) { regerror(rc, &preg, prbuf, sizeof(prbuf)); regfree(&preg); scan_err1(lc, _("Regex compile error. ERR=%s\n"), prbuf); break; } regfree(&preg); if (item->code == 1) { type = "regexdir"; res_incexe.current_opts->regexdir.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->regexdir.size(); } else if (item->code == 2) { type = "regexfile"; res_incexe.current_opts->regexfile.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->regexfile.size(); } else { type = "regex"; res_incexe.current_opts->regex.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->regex.size(); } Dmsg4(900, "set %s %p size=%d %s\n", type, res_incexe.current_opts, newsize, lc->str); break; default: scan_err1(lc, _("Expected a regex string, got: %s\n"), lc->str); } } scan_to_eol(lc); } /* Store Base info */ static void store_base(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); if (pass == 1) { /* * Pickup Base Job Name */ res_incexe.current_opts->base.append(bstrdup(lc->str)); } scan_to_eol(lc); } /* Store reader info */ static void store_plugin(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); if (pass == 1) { /* * Pickup plugin command */ res_incexe.current_opts->plugin = bstrdup(lc->str); } scan_to_eol(lc); } /* Store Wild-card info */ static void store_wild(LEX *lc, RES_ITEM *item, int index, int pass) { int token; const char *type; int newsize; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* * Pickup Wild-card string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: if (item->code == 1) { type = "wilddir"; res_incexe.current_opts->wilddir.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->wilddir.size(); } else if (item->code == 2) { if (strpbrk(lc->str, "/\\") != NULL) { type = "wildfile"; res_incexe.current_opts->wildfile.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->wildfile.size(); } else { type = "wildbase"; res_incexe.current_opts->wildbase.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->wildbase.size(); } } else { type = "wild"; res_incexe.current_opts->wild.append(bstrdup(lc->str)); newsize = res_incexe.current_opts->wild.size(); } Dmsg4(9, "set %s %p size=%d %s\n", type, res_incexe.current_opts, newsize, lc->str); break; default: scan_err1(lc, _("Expected a wild-card string, got: %s\n"), lc->str); } } scan_to_eol(lc); } /* Store fstype info */ static void store_fstype(LEX *lc, RES_ITEM *item, int index, int pass) { int token; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup fstype string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: res_incexe.current_opts->fstype.append(bstrdup(lc->str)); Dmsg3(900, "set fstype %p size=%d %s\n", res_incexe.current_opts, res_incexe.current_opts->fstype.size(), lc->str); break; default: scan_err1(lc, _("Expected a fstype string, got: %s\n"), lc->str); } } scan_to_eol(lc); } /* Store drivetype info */ static void store_drivetype(LEX *lc, RES_ITEM *item, int index, int pass) { int token; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup drivetype string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: res_incexe.current_opts->drivetype.append(bstrdup(lc->str)); Dmsg3(900, "set drivetype %p size=%d %s\n", res_incexe.current_opts, res_incexe.current_opts->drivetype.size(), lc->str); break; default: scan_err1(lc, _("Expected a drivetype string, got: %s\n"), lc->str); } } scan_to_eol(lc); } static void store_meta(LEX *lc, RES_ITEM *item, int index, int pass) { int token; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup fstype string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: case T_QUOTED_STRING: res_incexe.current_opts->meta.append(bstrdup(lc->str)); Dmsg3(900, "set meta %p size=%d %s\n", res_incexe.current_opts, res_incexe.current_opts->meta.size(), lc->str); break; default: scan_err1(lc, _("Expected a meta string, got: %s\n"), lc->str); } } scan_to_eol(lc); } /* * New style options come here */ static void store_option(LEX *lc, RES_ITEM *item, int index, int pass) { int i; int keyword; char inc_opts[100]; inc_opts[0] = 0; keyword = INC_KW_NONE; /* * Look up the keyword */ for (i = 0; FS_option_kw[i].name; i++) { if (bstrcasecmp(item->name, FS_option_kw[i].name)) { keyword = FS_option_kw[i].token; break; } } if (keyword == INC_KW_NONE) { scan_err1(lc, _("Expected a FileSet keyword, got: %s"), lc->str); } /* * Now scan for the value */ scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts)); if (pass == 1) { bstrncat(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); Dmsg2(900, "new pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); } scan_to_eol(lc); } /* * If current_opts not defined, create first entry */ static void setup_current_opts(void) { FOPTS *fo = (FOPTS *)malloc(sizeof(FOPTS)); memset(fo, 0, sizeof(FOPTS)); fo->regex.init(1, true); fo->regexdir.init(1, true); fo->regexfile.init(1, true); fo->wild.init(1, true); fo->wilddir.init(1, true); fo->wildfile.init(1, true); fo->wildbase.init(1, true); fo->base.init(1, true); fo->fstype.init(1, true); fo->drivetype.init(1, true); fo->meta.init(1, true); res_incexe.current_opts = fo; if (res_incexe.num_opts == 0) { res_incexe.opts_list = (FOPTS **)malloc(sizeof(FOPTS *)); } else { res_incexe.opts_list = (FOPTS **)realloc(res_incexe.opts_list, sizeof(FOPTS *) * (res_incexe.num_opts + 1)); } res_incexe.opts_list[res_incexe.num_opts++] = fo; } /* * Come here when Options seen in Include/Exclude */ static void store_options_res(LEX *lc, RES_ITEM *item, int index, int pass, bool exclude) { int token, i; if (exclude) { scan_err0(lc, _("Options section not permitted in Exclude\n")); /* NOT REACHED */ } token = lex_get_token(lc, T_SKIP_EOL); if (token != T_BOB) { scan_err1(lc, _("Expecting open brace. Got %s"), lc->str); } if (pass == 1) { setup_current_opts(); } while ((token = lex_get_token(lc, T_ALL)) != T_EOF) { if (token == T_EOL) { continue; } if (token == T_EOB) { break; } if (token != T_IDENTIFIER) { scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); } for (i=0; options_items[i].name; i++) { if (bstrcasecmp(options_items[i].name, lc->str)) { token = lex_get_token(lc, T_SKIP_EOL); if (token != T_EQUALS) { scan_err1(lc, _("expected an equals, got: %s"), lc->str); } /* Call item handler */ switch (options_items[i].type) { case CFG_TYPE_OPTION: store_option(lc, &options_items[i], i, pass); break; case CFG_TYPE_REGEX: store_regex(lc, &options_items[i], i, pass); break; case CFG_TYPE_BASE: store_base(lc, &options_items[i], i, pass); break; case CFG_TYPE_WILD: store_wild(lc, &options_items[i], i, pass); break; case CFG_TYPE_PLUGIN: store_plugin(lc, &options_items[i], i, pass); break; case CFG_TYPE_FSTYPE: store_fstype(lc, &options_items[i], i, pass); break; case CFG_TYPE_DRIVETYPE: store_drivetype(lc, &options_items[i], i, pass); break; case CFG_TYPE_META: store_meta(lc, &options_items[i], i, pass); break; default: break; } i = -1; break; } } if (i >=0) { scan_err1(lc, _("Keyword %s not permitted in this resource"), lc->str); } } } /* * Store Filename info. Note, for minor efficiency reasons, we * always increase the name buffer by 10 items because we expect * to add more entries. */ static void store_fname(LEX *lc, RES_ITEM *item, int index, int pass, bool exclude) { int token; INCEXE *incexe; URES *res_all = (URES *)my_config->m_res_all; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup Filename string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: if (strchr(lc->str, '\\')) { scan_err1(lc, _("Backslash found. Use forward slashes or quote the string.: %s\n"), lc->str); /* NOT REACHED */ } case T_QUOTED_STRING: if (res_all->res_fs.have_MD5) { MD5_Update(&res_all->res_fs.md5c, (unsigned char *)lc->str, lc->str_len); } incexe = &res_incexe; if (incexe->name_list.size() == 0) { incexe->name_list.init(10, true); } incexe->name_list.append(bstrdup(lc->str)); Dmsg1(900, "Add to name_list %s\n", lc->str); break; default: scan_err1(lc, _("Expected a filename, got: %s"), lc->str); } } scan_to_eol(lc); } /* * Store Filename info. Note, for minor efficiency reasons, we * always increase the name buffer by 10 items because we expect * to add more entries. */ static void store_plugin_name(LEX *lc, RES_ITEM *item, int index, int pass, bool exclude) { int token; INCEXE *incexe; URES *res_all = (URES *)my_config->m_res_all; if (exclude) { scan_err0(lc, _("Plugin directive not permitted in Exclude\n")); /* NOT REACHED */ } token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup Filename string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: if (strchr(lc->str, '\\')) { scan_err1(lc, _("Backslash found. Use forward slashes or quote the string.: %s\n"), lc->str); /* NOT REACHED */ } case T_QUOTED_STRING: if (res_all->res_fs.have_MD5) { MD5_Update(&res_all->res_fs.md5c, (unsigned char *)lc->str, lc->str_len); } incexe = &res_incexe; if (incexe->plugin_list.size() == 0) { incexe->plugin_list.init(10, true); } incexe->plugin_list.append(bstrdup(lc->str)); Dmsg1(900, "Add to plugin_list %s\n", lc->str); break; default: scan_err1(lc, _("Expected a filename, got: %s"), lc->str); /* NOT REACHED */ } } scan_to_eol(lc); } /* Store exclude directory containing info */ static void store_excludedir(LEX *lc, RES_ITEM *item, int index, int pass, bool exclude) { INCEXE *incexe; if (exclude) { scan_err0(lc, _("ExcludeDirContaining directive not permitted in Exclude.\n")); /* NOT REACHED */ return; } lex_get_token(lc, T_NAME); if (pass == 1) { incexe = &res_incexe; if (incexe->ignoredir.size() == 0) { incexe->ignoredir.init(10, true); } incexe->ignoredir.append(bstrdup(lc->str)); Dmsg1(900, "Add to ignoredir_list %s\n", lc->str); } scan_to_eol(lc); } /* * Store new style FileSet Include/Exclude info * * Note, when this routine is called, we are inside a FileSet * resource. We treat the Include/Exclude like a sort of * mini-resource within the FileSet resource. */ static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass) { bool options; int token, i; INCEXE *incexe; URES *res_all = (URES *)my_config->m_res_all; if (!res_all->res_fs.have_MD5) { MD5_Init(&res_all->res_fs.md5c); res_all->res_fs.have_MD5 = true; } memset(&res_incexe, 0, sizeof(res_incexe)); res_all->res_fs.new_include = true; while ((token = lex_get_token(lc, T_SKIP_EOL)) != T_EOF) { if (token == T_EOB) { break; } if (token != T_IDENTIFIER) { scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); } for (i=0; newinc_items[i].name; i++) { options = bstrcasecmp(lc->str, "options"); if (bstrcasecmp(newinc_items[i].name, lc->str)) { if (!options) { token = lex_get_token(lc, T_SKIP_EOL); if (token != T_EQUALS) { scan_err1(lc, _("expected an equals, got: %s"), lc->str); } } /* Call item handler */ switch (newinc_items[i].type) { case CFG_TYPE_FNAME: store_fname(lc, &newinc_items[i], i, pass, item->code); break; case CFG_TYPE_PLUGINNAME: store_plugin_name(lc, &newinc_items[i], i, pass, item->code); break; case CFG_TYPE_EXCLUDEDIR: store_excludedir(lc, &newinc_items[i], i, pass, item->code); break; case CFG_TYPE_OPTIONS: store_options_res(lc, &newinc_items[i], i, pass, item->code); break; default: break; } i = -1; break; } } if (i >=0) { scan_err1(lc, _("Keyword %s not permitted in this resource"), lc->str); } } if (pass == 1) { incexe = (INCEXE *)malloc(sizeof(INCEXE)); memcpy(incexe, &res_incexe, sizeof(INCEXE)); memset(&res_incexe, 0, sizeof(res_incexe)); if (item->code == 0) { /* include */ if (res_all->res_fs.num_includes == 0) { res_all->res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *)); } else { res_all->res_fs.include_items = (INCEXE **)realloc(res_all->res_fs.include_items, sizeof(INCEXE *) * (res_all->res_fs.num_includes + 1)); } res_all->res_fs.include_items[res_all->res_fs.num_includes++] = incexe; Dmsg1(900, "num_includes=%d\n", res_all->res_fs.num_includes); } else { /* exclude */ if (res_all->res_fs.num_excludes == 0) { res_all->res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *)); } else { res_all->res_fs.exclude_items = (INCEXE **)realloc(res_all->res_fs.exclude_items, sizeof(INCEXE *) * (res_all->res_fs.num_excludes + 1)); } res_all->res_fs.exclude_items[res_all->res_fs.num_excludes++] = incexe; Dmsg1(900, "num_excludes=%d\n", res_all->res_fs.num_excludes); } } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store FileSet Include/Exclude info * new style includes are handled in store_newinc() */ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) { int token; /* * Decide if we are doing a new Include or an old include. The * new Include is followed immediately by open brace, whereas the * old include has options following the Include. */ token = lex_get_token(lc, T_SKIP_EOL); if (token == T_BOB) { store_newinc(lc, item, index, pass); return; } scan_err0(lc, _("Old style Include/Exclude not supported\n")); } bareos-Release-14.2.6/src/dird/inc_conf.h000066400000000000000000000136151263011562700201060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, June 2013 */ #ifndef _INC_CONF_H #define _INC_CONF_H 1 /* * Define FileSet KeyWord values */ enum { INC_KW_NONE, INC_KW_COMPRESSION, INC_KW_DIGEST, INC_KW_ENCRYPTION, INC_KW_VERIFY, INC_KW_BASEJOB, INC_KW_ACCURATE, INC_KW_ONEFS, INC_KW_RECURSE, INC_KW_SPARSE, INC_KW_HARDLINK, INC_KW_REPLACE, /* restore options */ INC_KW_READFIFO, /* Causes fifo data to be read */ INC_KW_PORTABLE, INC_KW_MTIMEONLY, INC_KW_KEEPATIME, INC_KW_EXCLUDE, INC_KW_ACL, INC_KW_IGNORECASE, INC_KW_HFSPLUS, INC_KW_NOATIME, INC_KW_ENHANCEDWILD, INC_KW_CHKCHANGES, INC_KW_STRIPPATH, INC_KW_HONOR_NODUMP, INC_KW_XATTR, INC_KW_SIZE, INC_KW_SHADOWING, INC_KW_AUTO_EXCLUDE }; /* * This is the list of options that can be stored by store_opts * Note, now that the old style Include/Exclude code is gone, * the INC_KW code could be put into the "code" field of the * options given above. */ static struct s_kw FS_option_kw[] = { { "compression", INC_KW_COMPRESSION }, { "signature", INC_KW_DIGEST }, { "encryption", INC_KW_ENCRYPTION }, { "verify", INC_KW_VERIFY }, { "basejob", INC_KW_BASEJOB }, { "accurate", INC_KW_ACCURATE }, { "onefs", INC_KW_ONEFS }, { "recurse", INC_KW_RECURSE }, { "sparse", INC_KW_SPARSE }, { "hardlinks", INC_KW_HARDLINK }, { "replace", INC_KW_REPLACE }, { "readfifo", INC_KW_READFIFO }, { "portable", INC_KW_PORTABLE }, { "mtimeonly", INC_KW_MTIMEONLY }, { "keepatime", INC_KW_KEEPATIME }, { "exclude", INC_KW_EXCLUDE }, { "aclsupport", INC_KW_ACL }, { "ignorecase", INC_KW_IGNORECASE }, { "hfsplussupport", INC_KW_HFSPLUS }, { "noatime", INC_KW_NOATIME }, { "enhancedwild", INC_KW_ENHANCEDWILD }, { "checkfilechanges", INC_KW_CHKCHANGES }, { "strippath", INC_KW_STRIPPATH }, { "honornodumpflag", INC_KW_HONOR_NODUMP }, { "xattrsupport", INC_KW_XATTR }, { "size", INC_KW_SIZE }, { "shadowing", INC_KW_SHADOWING }, { "autoexclude", INC_KW_AUTO_EXCLUDE }, { NULL, 0 } }; /* * Options for FileSet keywords */ struct s_fs_opt { const char *name; int keyword; const char *option; }; /* * Options permitted for each keyword and resulting value. * The output goes into opts, which are then transmitted to * the FD for application as options to the following list of * included files. */ static struct s_fs_opt FS_options[] = { { "md5", INC_KW_DIGEST, "M" }, { "sha1", INC_KW_DIGEST, "S" }, { "sha256", INC_KW_DIGEST, "S2" }, { "sha512", INC_KW_DIGEST, "S3" }, { "gzip", INC_KW_COMPRESSION, "Z6" }, { "gzip1", INC_KW_COMPRESSION, "Z1" }, { "gzip2", INC_KW_COMPRESSION, "Z2" }, { "gzip3", INC_KW_COMPRESSION, "Z3" }, { "gzip4", INC_KW_COMPRESSION, "Z4" }, { "gzip5", INC_KW_COMPRESSION, "Z5" }, { "gzip6", INC_KW_COMPRESSION, "Z6" }, { "gzip7", INC_KW_COMPRESSION, "Z7" }, { "gzip8", INC_KW_COMPRESSION, "Z8" }, { "gzip9", INC_KW_COMPRESSION, "Z9" }, { "lzo", INC_KW_COMPRESSION, "Zo" }, { "lzfast", INC_KW_COMPRESSION, "Zff" }, { "lz4", INC_KW_COMPRESSION, "Zf4" }, { "lz4hc", INC_KW_COMPRESSION, "Zfh" }, { "blowfish", INC_KW_ENCRYPTION, "B"}, /* ***FIXME*** not implemented */ { "3des", INC_KW_ENCRYPTION, "3"}, /* ***FIXME*** not implemented */ { "yes", INC_KW_ONEFS, "0" }, { "no", INC_KW_ONEFS, "f" }, { "yes", INC_KW_RECURSE, "0" }, { "no", INC_KW_RECURSE, "h" }, { "yes", INC_KW_SPARSE, "s" }, { "no", INC_KW_SPARSE, "0" }, { "yes", INC_KW_HARDLINK, "0" }, { "no", INC_KW_HARDLINK, "H" }, { "always", INC_KW_REPLACE, "a" }, { "ifnewer", INC_KW_REPLACE, "w" }, { "never", INC_KW_REPLACE, "n" }, { "yes", INC_KW_READFIFO, "r" }, { "no", INC_KW_READFIFO, "0" }, { "yes", INC_KW_PORTABLE, "p" }, { "no", INC_KW_PORTABLE, "0" }, { "yes", INC_KW_MTIMEONLY, "m" }, { "no", INC_KW_MTIMEONLY, "0" }, { "yes", INC_KW_KEEPATIME, "k" }, { "no", INC_KW_KEEPATIME, "0" }, { "yes", INC_KW_EXCLUDE, "e" }, { "no", INC_KW_EXCLUDE, "0" }, { "yes", INC_KW_ACL, "A" }, { "no", INC_KW_ACL, "0" }, { "yes", INC_KW_IGNORECASE, "i" }, { "no", INC_KW_IGNORECASE, "0" }, { "yes", INC_KW_HFSPLUS, "R"}, /* "R" for resource fork */ { "no", INC_KW_HFSPLUS, "0" }, { "yes", INC_KW_NOATIME, "K" }, { "no", INC_KW_NOATIME, "0" }, { "yes", INC_KW_ENHANCEDWILD, "K" }, { "no", INC_KW_ENHANCEDWILD, "0" }, { "yes", INC_KW_CHKCHANGES, "c" }, { "no", INC_KW_CHKCHANGES, "0" }, { "yes", INC_KW_HONOR_NODUMP, "N" }, { "no", INC_KW_HONOR_NODUMP, "0" }, { "yes", INC_KW_XATTR, "X" }, { "no", INC_KW_XATTR, "0" }, { "localwarn", INC_KW_SHADOWING, "d1" }, { "localremove", INC_KW_SHADOWING, "d2" }, { "globalwarn", INC_KW_SHADOWING, "d3" }, { "globalremove", INC_KW_SHADOWING, "d4" }, { "none", INC_KW_SHADOWING, "0" }, { "yes", INC_KW_AUTO_EXCLUDE, "0" }, { "no", INC_KW_AUTO_EXCLUDE, "x" }, { NULL, 0, 0 } }; #define PERMITTED_VERIFY_OPTIONS (const char *)"ipnugsamcd51" #define PERMITTED_ACCURATE_OPTIONS (const char *)"ipnugsamcd51A" #define PERMITTED_BASEJOB_OPTIONS (const char *)"ipnugsamcd51" #endif /* _INC_CONF_H */ bareos-Release-14.2.6/src/dird/job.c000066400000000000000000001703631263011562700171010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director Job processing routines * * Kern Sibbald, October MM */ #include "bareos.h" #include "dird.h" /* Forward referenced subroutines */ static void *job_thread(void *arg); static void job_monitor_watchdog(watchdog_t *self); static void job_monitor_destructor(watchdog_t *self); static bool job_check_maxwaittime(JCR *jcr); static bool job_check_maxruntime(JCR *jcr); static bool job_check_maxrunschedtime(JCR *jcr); /* Imported subroutines */ /* Imported variables */ jobq_t job_queue; void init_job_server(int max_workers) { int status; watchdog_t *wd; if ((status = jobq_init(&job_queue, max_workers, job_thread)) != 0) { berrno be; Emsg1(M_ABORT, 0, _("Could not init job queue: ERR=%s\n"), be.bstrerror(status)); } wd = new_watchdog(); wd->callback = job_monitor_watchdog; wd->destructor = job_monitor_destructor; wd->one_shot = false; wd->interval = 60; wd->data = new_control_jcr("*JobMonitor*", JT_SYSTEM); register_watchdog(wd); } void term_job_server() { jobq_destroy(&job_queue); /* ignore any errors */ } /* * Run a job -- typically called by the scheduler, but may also * be called by the UA (Console program). * * Returns: 0 on failure * JobId on success */ JobId_t run_job(JCR *jcr) { int status; if (setup_job(jcr)) { Dmsg0(200, "Add jrc to work queue\n"); /* * Queue the job to be run */ if ((status = jobq_add(&job_queue, jcr)) != 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not add job queue: ERR=%s\n"), be.bstrerror(status)); return 0; } return jcr->JobId; } return 0; } bool setup_job(JCR *jcr, bool suppress_output) { int errstat; jcr->lock(); Dsm_check(100); /* * See if we should suppress all output. */ if (!suppress_output) { init_msg(jcr, jcr->res.messages, job_code_callback_director); } else { jcr->suppress_output = true; } /* * Initialize termination condition variable */ if ((errstat = pthread_cond_init(&jcr->term_wait, NULL)) != 0) { berrno be; Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat)); jcr->unlock(); goto bail_out; } jcr->term_wait_inited = true; /* * Initialize nextrun ready condition variable */ if ((errstat = pthread_cond_init(&jcr->nextrun_ready, NULL)) != 0) { berrno be; Jmsg1(jcr, M_FATAL, 0, _("Unable to init job nextrun cond variable: ERR=%s\n"), be.bstrerror(errstat)); jcr->unlock(); goto bail_out; } jcr->nextrun_ready_inited = true; create_unique_job_name(jcr, jcr->res.job->name()); jcr->setJobStatus(JS_Created); jcr->unlock(); /* * Open database */ Dmsg0(100, "Open database\n"); jcr->db = db_sql_get_pooled_connection(jcr, jcr->res.catalog->db_driver, jcr->res.catalog->db_name, jcr->res.catalog->db_user, jcr->res.catalog->db_password.value, jcr->res.catalog->db_address, jcr->res.catalog->db_port, jcr->res.catalog->db_socket, jcr->res.catalog->mult_db_connections, jcr->res.catalog->disable_batch_insert); if (jcr->db == NULL) { Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"), jcr->res.catalog->db_name); goto bail_out; } Dmsg0(150, "DB opened\n"); if (!jcr->fname) { jcr->fname = get_pool_memory(PM_FNAME); } if (!jcr->res.pool_source) { jcr->res.pool_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.pool_source, _("unknown source")); } if (!jcr->res.npool_source) { jcr->res.npool_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.npool_source, _("unknown source")); } if (jcr->JobReads()) { if (!jcr->res.rpool_source) { jcr->res.rpool_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.rpool_source, _("unknown source")); } } /* * Create Job record */ init_jcr_job_record(jcr); if (jcr->res.client) { if (!get_or_create_client_record(jcr)) { goto bail_out; } } if (!db_create_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); goto bail_out; } jcr->JobId = jcr->jr.JobId; Dmsg4(100, "Created job record JobId=%d Name=%s Type=%c Level=%c\n", jcr->JobId, jcr->Job, jcr->jr.JobType, jcr->jr.JobLevel); new_plugins(jcr); /* instantiate plugins for this jcr */ dispatch_new_plugin_options(jcr); generate_plugin_event(jcr, bDirEventJobStart); if (job_canceled(jcr)) { goto bail_out; } if (jcr->JobReads() && !jcr->rstorage) { if (jcr->res.job->storage) { copy_rwstorage(jcr, jcr->res.job->storage, _("Job resource")); } else { copy_rwstorage(jcr, jcr->res.job->pool->storage, _("Pool resource")); } } if (!jcr->JobReads()) { free_rstorage(jcr); } /* * Now, do pre-run stuff, like setting job level (Inc/diff, ...) * this allows us to setup a proper job start record for restarting * in case of later errors. */ switch (jcr->getJobType()) { case JT_BACKUP: if (!jcr->is_JobLevel(L_VIRTUAL_FULL)) { if (get_or_create_fileset_record(jcr)) { /* * See if we need to upgrade the level. If get_level_since_time returns true * it has updated the level of the backup and we run apply_pool_overrides * with the force flag so the correct pool (full, diff, incr) is selected. * For all others we respect any set ignore flags. */ if (get_level_since_time(jcr)) { apply_pool_overrides(jcr, true); } else { apply_pool_overrides(jcr, false); } } else { goto bail_out; } } switch (jcr->getJobProtocol()) { case PT_NDMP: if (!do_ndmp_backup_init(jcr)) { ndmp_backup_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } break; default: if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { if (!do_native_vbackup_init(jcr)) { native_vbackup_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } } else { if (!do_native_backup_init(jcr)) { native_backup_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } } break; } break; case JT_VERIFY: if (!do_verify_init(jcr)) { verify_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } break; case JT_RESTORE: switch (jcr->getJobProtocol()) { case PT_NDMP: if (!do_ndmp_restore_init(jcr)) { ndmp_restore_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } break; default: /* * Any non NDMP restore is not interested at the items * that were selected for restore so drop them now. */ if (jcr->restore_tree_root) { free_tree(jcr->restore_tree_root); jcr->restore_tree_root = NULL; } if (!do_native_restore_init(jcr)) { native_restore_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } break; } break; case JT_ADMIN: if (!do_admin_init(jcr)) { admin_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } break; case JT_COPY: case JT_MIGRATE: if (!do_migration_init(jcr)) { migration_cleanup(jcr, JS_ErrorTerminated); goto bail_out; } break; default: Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType()); jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } generate_plugin_event(jcr, bDirEventJobInit); Dsm_check(100); return true; bail_out: return false; } void update_job_end(JCR *jcr, int TermCode) { dequeue_messages(jcr); /* display any queued messages */ jcr->setJobStatus(TermCode); update_job_end_record(jcr); } /* * This is the engine called by jobq.c:jobq_add() when we were pulled from the work queue. * * At this point, we are running in our own thread and all necessary resources are * allocated -- see jobq.c */ static void *job_thread(void *arg) { JCR *jcr = (JCR *)arg; pthread_detach(pthread_self()); Dsm_check(100); Dmsg0(200, "=====Start Job=========\n"); jcr->setJobStatus(JS_Running); /* this will be set only if no error */ jcr->start_time = time(NULL); /* set the real start time */ jcr->jr.StartTime = jcr->start_time; /* * Let the statistics subsystem know a new Job was started. */ stats_job_started(); if (jcr->res.job->MaxStartDelay != 0 && jcr->res.job->MaxStartDelay < (utime_t)(jcr->start_time - jcr->sched_time)) { jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n")); } if (job_check_maxrunschedtime(jcr)) { jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("Job canceled because max run sched time exceeded.\n")); } /* * TODO : check if it is used somewhere */ if (jcr->res.job->RunScripts == NULL) { Dmsg0(200, "Warning, job->RunScripts is empty\n"); jcr->res.job->RunScripts = New(alist(10, not_owned_by_alist)); } if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } /* * Run any script BeforeJob on dird */ run_scripts(jcr, jcr->res.job->RunScripts, "BeforeJob"); /* * We re-update the job start record so that the start time is set after the run before job. * This avoids that any files created by the run before job will be saved twice. They will * be backed up in the current job, but not in the next one unless they are changed. * * Without this, they will be backed up in this job and in the next job run because in that * case, their date is after the start of this run. */ jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } generate_plugin_event(jcr, bDirEventJobRun); switch (jcr->getJobType()) { case JT_BACKUP: switch (jcr->getJobProtocol()) { case PT_NDMP: if (!job_canceled(jcr)) { if (do_ndmp_backup(jcr)) { do_autoprune(jcr); } else { ndmp_backup_cleanup(jcr, JS_ErrorTerminated); } } else { ndmp_backup_cleanup(jcr, JS_Canceled); } break; default: if (!job_canceled(jcr)) { if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { if (do_native_vbackup(jcr)) { do_autoprune(jcr); } else { native_vbackup_cleanup(jcr, JS_ErrorTerminated); } } else { if (do_native_backup(jcr)) { do_autoprune(jcr); } else { native_backup_cleanup(jcr, JS_ErrorTerminated); } } } else { if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { native_vbackup_cleanup(jcr, JS_Canceled); } else { native_backup_cleanup(jcr, JS_Canceled); } } break; } break; case JT_VERIFY: if (!job_canceled(jcr)) { if (do_verify(jcr)) { do_autoprune(jcr); } else { verify_cleanup(jcr, JS_ErrorTerminated); } } else { verify_cleanup(jcr, JS_Canceled); } break; case JT_RESTORE: switch (jcr->getJobProtocol()) { case PT_NDMP: if (!job_canceled(jcr)) { if (do_ndmp_restore(jcr)) { do_autoprune(jcr); } else { ndmp_restore_cleanup(jcr, JS_ErrorTerminated); } } else { ndmp_restore_cleanup(jcr, JS_Canceled); } break; default: if (!job_canceled(jcr)) { if (do_native_restore(jcr)) { do_autoprune(jcr); } else { native_restore_cleanup(jcr, JS_ErrorTerminated); } } else { native_restore_cleanup(jcr, JS_Canceled); } break; } break; case JT_ADMIN: if (!job_canceled(jcr)) { if (do_admin(jcr)) { do_autoprune(jcr); } else { admin_cleanup(jcr, JS_ErrorTerminated); } } else { admin_cleanup(jcr, JS_Canceled); } break; case JT_COPY: case JT_MIGRATE: if (!job_canceled(jcr)) { if (do_migration(jcr)) { do_autoprune(jcr); } else { migration_cleanup(jcr, JS_ErrorTerminated); } } else { migration_cleanup(jcr, JS_Canceled); } break; default: Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType()); break; } /* * Check for subscriptions and issue a warning when exceeded. */ if (me->subscriptions && me->subscriptions < me->subscriptions_used) { Jmsg(jcr, M_WARNING, 0, _("Subscriptions exceeded: (used/total) (%d/%d)\n"), me->subscriptions_used, me->subscriptions); } run_scripts(jcr, jcr->res.job->RunScripts, "AfterJob"); /* * Send off any queued messages */ if (jcr->msg_queue && jcr->msg_queue->size() > 0) { dequeue_messages(jcr); } generate_plugin_event(jcr, bDirEventJobEnd); Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus); Dsm_check(100); return NULL; } void sd_msg_thread_send_signal(JCR *jcr, int sig) { jcr->lock(); if (!jcr->sd_msg_thread_done && jcr->SD_msg_chan_started && !pthread_equal(jcr->SD_msg_chan, pthread_self())) { Dmsg1(800, "Send kill to SD msg chan jid=%d\n", jcr->JobId); pthread_kill(jcr->SD_msg_chan, sig); } jcr->unlock(); } /* * Cancel a job -- typically called by the UA (Console program), but may also * be called by the job watchdog. * * Returns: true if cancel appears to be successful * false on failure. Message sent to ua->jcr. */ bool cancel_job(UAContext *ua, JCR *jcr) { char ed1[50]; int32_t old_status = jcr->JobStatus; jcr->setJobStatus(JS_Canceled); switch (old_status) { case JS_Created: case JS_WaitJobRes: case JS_WaitClientRes: case JS_WaitStoreRes: case JS_WaitPriority: case JS_WaitMaxJobs: case JS_WaitStartTime: ua->info_msg(_("JobId %s, Job %s marked to be canceled.\n"), edit_uint64(jcr->JobId, ed1), jcr->Job); jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */ break; default: /* * Cancel File daemon */ if (jcr->file_bsock) { if (!cancel_file_daemon_job(ua, jcr)) { return false; } } /* * Cancel Storage daemon */ if (jcr->store_bsock) { if (!cancel_storage_daemon_job(ua, jcr)) { return false; } } /* * Cancel second Storage daemon for SD-SD replication. */ if (jcr->mig_jcr && jcr->mig_jcr->store_bsock) { if (!cancel_storage_daemon_job(ua, jcr->mig_jcr)) { return false; } } break; } run_scripts(jcr, jcr->res.job->RunScripts, "AfterJob"); return true; } static void job_monitor_destructor(watchdog_t *self) { JCR *control_jcr = (JCR *)self->data; free_jcr(control_jcr); } static void job_monitor_watchdog(watchdog_t *self) { JCR *control_jcr, *jcr; control_jcr = (JCR *)self->data; Dsm_check(100); Dmsg1(800, "job_monitor_watchdog %p called\n", self); foreach_jcr(jcr) { bool cancel = false; if (jcr->JobId == 0 || job_canceled(jcr) || jcr->no_maxtime) { Dmsg2(800, "Skipping JCR=%p Job=%s\n", jcr, jcr->Job); continue; } /* check MaxWaitTime */ if (job_check_maxwaittime(jcr)) { jcr->setJobStatus(JS_Canceled); Qmsg(jcr, M_FATAL, 0, _("Max wait time exceeded. Job canceled.\n")); cancel = true; /* check MaxRunTime */ } else if (job_check_maxruntime(jcr)) { jcr->setJobStatus(JS_Canceled); Qmsg(jcr, M_FATAL, 0, _("Max run time exceeded. Job canceled.\n")); cancel = true; /* check MaxRunSchedTime */ } else if (job_check_maxrunschedtime(jcr)) { jcr->setJobStatus(JS_Canceled); Qmsg(jcr, M_FATAL, 0, _("Max run sched time exceeded. Job canceled.\n")); cancel = true; } if (cancel) { Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n", jcr, jcr->JobId, jcr->Job); UAContext *ua = new_ua_context(jcr); ua->jcr = control_jcr; cancel_job(ua, jcr); free_ua_context(ua); Dmsg2(800, "Have cancelled JCR %p Job=%d\n", jcr, jcr->JobId); } } /* Keep reference counts correct */ endeach_jcr(jcr); } /* * Check if the maxwaittime has expired and it is possible * to cancel the job. */ static bool job_check_maxwaittime(JCR *jcr) { bool cancel = false; JOBRES *job = jcr->res.job; utime_t current=0; if (!job_waiting(jcr)) { return false; } if (jcr->wait_time) { current = watchdog_time - jcr->wait_time; } Dmsg2(200, "check maxwaittime %u >= %u\n", current + jcr->wait_time_sum, job->MaxWaitTime); if (job->MaxWaitTime != 0 && (current + jcr->wait_time_sum) >= job->MaxWaitTime) { cancel = true; } return cancel; } /* * Check if maxruntime has expired and if the job can be * canceled. */ static bool job_check_maxruntime(JCR *jcr) { bool cancel = false; JOBRES *job = jcr->res.job; utime_t run_time; if (job_canceled(jcr) || !jcr->job_started) { return false; } if (job->MaxRunTime == 0 && job->FullMaxRunTime == 0 && job->IncMaxRunTime == 0 && job->DiffMaxRunTime == 0) { return false; } run_time = watchdog_time - jcr->start_time; Dmsg7(200, "check_maxruntime %llu-%u=%llu >= %llu|%llu|%llu|%llu\n", watchdog_time, jcr->start_time, run_time, job->MaxRunTime, job->FullMaxRunTime, job->IncMaxRunTime, job->DiffMaxRunTime); if (jcr->getJobLevel() == L_FULL && job->FullMaxRunTime != 0 && run_time >= job->FullMaxRunTime) { Dmsg0(200, "check_maxwaittime: FullMaxcancel\n"); cancel = true; } else if (jcr->getJobLevel() == L_DIFFERENTIAL && job->DiffMaxRunTime != 0 && run_time >= job->DiffMaxRunTime) { Dmsg0(200, "check_maxwaittime: DiffMaxcancel\n"); cancel = true; } else if (jcr->getJobLevel() == L_INCREMENTAL && job->IncMaxRunTime != 0 && run_time >= job->IncMaxRunTime) { Dmsg0(200, "check_maxwaittime: IncMaxcancel\n"); cancel = true; } else if (job->MaxRunTime > 0 && run_time >= job->MaxRunTime) { Dmsg0(200, "check_maxwaittime: Maxcancel\n"); cancel = true; } return cancel; } /* * Check if MaxRunSchedTime has expired and if the job can be * canceled. */ static bool job_check_maxrunschedtime(JCR *jcr) { if (jcr->MaxRunSchedTime == 0 || job_canceled(jcr)) { return false; } if ((watchdog_time - jcr->initial_sched_time) < jcr->MaxRunSchedTime) { Dmsg3(200, "Job %p (%s) with MaxRunSchedTime %d not expired\n", jcr, jcr->Job, jcr->MaxRunSchedTime); return false; } return true; } /* * Get or create a Pool record with the given name. * Returns: 0 on error * poolid if OK */ DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool_name, sizeof(pr.Name)); Dmsg1(110, "get_or_create_pool=%s\n", pool_name); while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */ /* Try to create the pool */ if (create_pool(jcr, jcr->db, jcr->res.pool, POOL_OP_CREATE) < 0) { Jmsg(jcr, M_FATAL, 0, _("Pool \"%s\" not in database. ERR=%s"), pr.Name, db_strerror(jcr->db)); return 0; } else { Jmsg(jcr, M_INFO, 0, _("Created database record for Pool \"%s\".\n"), pr.Name); } } return pr.PoolId; } /* * Check for duplicate jobs. * Returns: true if current job should continue * false if current job should terminate */ bool allow_duplicate_job(JCR *jcr) { JCR *djcr; /* possible duplicate job */ JOBRES *job = jcr->res.job; bool cancel_dup = false; bool cancel_me = false; /* * See if AllowDuplicateJobs is set or * if duplicate checking is disabled for this job. */ if (job->AllowDuplicateJobs || jcr->IgnoreDuplicateJobChecking) { return true; } Dmsg0(800, "Enter allow_duplicate_job\n"); /* * After this point, we do not want to allow any duplicate * job to run. */ foreach_jcr(djcr) { if (jcr == djcr || djcr->JobId == 0) { continue; /* do not cancel this job or consoles */ } /* * See if this Job has the IgnoreDuplicateJobChecking flag set, ignore it * for any checking against other jobs. */ if (djcr->IgnoreDuplicateJobChecking) { continue; } if (bstrcmp(job->name(), djcr->res.job->name())) { if (job->DuplicateJobProximity > 0) { utime_t now = (utime_t)time(NULL); if ((now - djcr->start_time) > job->DuplicateJobProximity) { continue; /* not really a duplicate */ } } if (job->CancelLowerLevelDuplicates && djcr->is_JobType(JT_BACKUP) && jcr->is_JobType(JT_BACKUP)) { switch (jcr->getJobLevel()) { case L_FULL: if (djcr->getJobLevel() == L_DIFFERENTIAL || djcr->getJobLevel() == L_INCREMENTAL) { cancel_dup = true; } break; case L_DIFFERENTIAL: if (djcr->getJobLevel() == L_INCREMENTAL) { cancel_dup = true; } if (djcr->getJobLevel() == L_FULL) { cancel_me = true; } break; case L_INCREMENTAL: if (djcr->getJobLevel() == L_FULL || djcr->getJobLevel() == L_DIFFERENTIAL) { cancel_me = true; } } /* * cancel_dup will be done below */ if (cancel_me) { /* Zap current job */ jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), djcr->JobId); break; /* get out of foreach_jcr */ } } /* * Cancel one of the two jobs (me or dup) * If CancelQueuedDuplicates is set do so only if job is queued. */ if (job->CancelQueuedDuplicates) { switch (djcr->JobStatus) { case JS_Created: case JS_WaitJobRes: case JS_WaitClientRes: case JS_WaitStoreRes: case JS_WaitPriority: case JS_WaitMaxJobs: case JS_WaitStartTime: cancel_dup = true; /* cancel queued duplicate */ break; default: break; } } if (cancel_dup || job->CancelRunningDuplicates) { /* * Zap the duplicated job djcr */ UAContext *ua = new_ua_context(jcr); Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%d.\n"), djcr->JobId); cancel_job(ua, djcr); bmicrosleep(0, 500000); djcr->setJobStatus(JS_Canceled); cancel_job(ua, djcr); free_ua_context(ua); Dmsg2(800, "Cancel dup %p JobId=%d\n", djcr, djcr->JobId); } else { /* * Zap current job */ jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), djcr->JobId); Dmsg2(800, "Cancel me %p JobId=%d\n", jcr, jcr->JobId); } Dmsg4(800, "curJobId=%d use_cnt=%d dupJobId=%d use_cnt=%d\n", jcr->JobId, jcr->use_count(), djcr->JobId, djcr->use_count()); break; /* did our work, get out of foreach loop */ } } endeach_jcr(djcr); return true; } /* * This subroutine edits the last job start time into a * "since=date/time" buffer that is returned in the * variable since. This is used for display purposes in * the job report. The time in jcr->stime is later * passed to tell the File daemon what to do. */ bool get_level_since_time(JCR *jcr) { int JobLevel; bool have_full; bool do_full = false; bool do_vfull = false; bool do_diff = false; bool pool_updated = false; utime_t now; utime_t last_full_time = 0; utime_t last_diff_time; char prev_job[MAX_NAME_LENGTH]; jcr->since[0] = 0; /* * If job cloned and a since time already given, use it */ if (jcr->cloned && jcr->stime && jcr->stime[0]) { bstrncpy(jcr->since, _(", since="), sizeof(jcr->since)); bstrncat(jcr->since, jcr->stime, sizeof(jcr->since)); return pool_updated; } /* * Make sure stime buffer is allocated */ if (!jcr->stime) { jcr->stime = get_pool_memory(PM_MESSAGE); } jcr->PrevJob[0] = 0; jcr->stime[0] = 0; /* * Lookup the last FULL backup job to get the time/date for a * differential or incremental save. */ JobLevel = jcr->getJobLevel(); switch (JobLevel) { case L_DIFFERENTIAL: case L_INCREMENTAL: POOLMEM *stime = get_pool_memory(PM_MESSAGE); /* * Look up start time of last Full job */ now = (utime_t)time(NULL); jcr->jr.JobId = 0; /* flag to return since time */ /* * This is probably redundant, but some of the code below * uses jcr->stime, so don't remove unless you are sure. */ if (!db_find_job_start_time(jcr,jcr->db, &jcr->jr, &jcr->stime, jcr->PrevJob)) { do_full = true; } have_full = db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, prev_job, L_FULL); if (have_full) { last_full_time = str_to_utime(stime); } else { do_full = true; /* No full, upgrade to one */ } Dmsg4(50, "have_full=%d do_full=%d now=%lld full_time=%lld\n", have_full, do_full, now, last_full_time); /* * Make sure the last diff is recent enough */ if (have_full && JobLevel == L_INCREMENTAL && jcr->res.job->MaxDiffInterval > 0) { /* * Lookup last diff job */ if (db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, prev_job, L_DIFFERENTIAL)) { last_diff_time = str_to_utime(stime); /* * If no Diff since Full, use Full time */ if (last_diff_time < last_full_time) { last_diff_time = last_full_time; } Dmsg2(50, "last_diff_time=%lld last_full_time=%lld\n", last_diff_time, last_full_time); } else { /* * No last differential, so use last full time */ last_diff_time = last_full_time; Dmsg1(50, "No last_diff_time setting to full_time=%lld\n", last_full_time); } do_diff = ((now - last_diff_time) >= jcr->res.job->MaxDiffInterval); Dmsg2(50, "do_diff=%d diffInter=%lld\n", do_diff, jcr->res.job->MaxDiffInterval); } /* * Note, do_full takes precedence over do_vfull and do_diff */ if (have_full && jcr->res.job->MaxFullInterval > 0) { do_full = ((now - last_full_time) >= jcr->res.job->MaxFullInterval); } else if (have_full && jcr->res.job->MaxVFullInterval > 0) { do_vfull = ((now - last_full_time) >= jcr->res.job->MaxVFullInterval); } free_pool_memory(stime); if (do_full) { /* * No recent Full job found, so upgrade this one to Full */ Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db)); Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing FULL backup.\n")); bsnprintf(jcr->since, sizeof(jcr->since), _(" (upgraded from %s)"), level_to_str(JobLevel)); jcr->setJobLevel(jcr->jr.JobLevel = L_FULL); pool_updated = true; } else if (do_vfull) { /* * No recent Full job found, and MaxVirtualFull is set so upgrade this one to Virtual Full */ Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db)); Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing Virtual FULL backup.\n")); bsnprintf(jcr->since, sizeof(jcr->since), _(" (upgraded from %s)"), level_to_str(jcr->getJobLevel())); jcr->setJobLevel(jcr->jr.JobLevel = L_VIRTUAL_FULL); pool_updated = true; /* * If we get upgraded to a Virtual Full we will be using a read pool so make sure we have a rpool_source. */ if (!jcr->res.rpool_source) { jcr->res.rpool_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.rpool_source, _("unknown source")); } } else if (do_diff) { /* * No recent diff job found, so upgrade this one to Diff */ Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n")); bsnprintf(jcr->since, sizeof(jcr->since), _(" (upgraded from %s)"), level_to_str(JobLevel)); jcr->setJobLevel(jcr->jr.JobLevel = L_DIFFERENTIAL); pool_updated = true; } else { if (jcr->res.job->rerun_failed_levels) { if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr, jcr->stime, JobLevel)) { Jmsg(jcr, M_INFO, 0, _("Prior failed job found in catalog. Upgrading to %s.\n"), level_to_str(JobLevel)); bsnprintf(jcr->since, sizeof(jcr->since), _(" (upgraded from %s)"), level_to_str(JobLevel)); jcr->setJobLevel(jcr->jr.JobLevel = JobLevel); jcr->jr.JobId = jcr->JobId; pool_updated = true; break; } } bstrncpy(jcr->since, _(", since="), sizeof(jcr->since)); bstrncat(jcr->since, jcr->stime, sizeof(jcr->since)); } jcr->jr.JobId = jcr->JobId; /* * Lookup the Job record of the previous Job and store it in jcr->previous_jr. */ if (jcr->PrevJob[0]) { bstrncpy(jcr->previous_jr.Job, jcr->PrevJob, sizeof(jcr->previous_jr.Job)); if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) { Jmsg(jcr, M_FATAL, 0, _("Could not get job record for previous Job. ERR=%s"), db_strerror(jcr->db)); } } break; } Dmsg3(100, "Level=%c last start time=%s job=%s\n", JobLevel, jcr->stime, jcr->PrevJob); return pool_updated; } void apply_pool_overrides(JCR *jcr, bool force) { Dmsg0(100, "entering apply_pool_overrides()\n"); bool pool_override = false; /* * If a cmdline pool override is given ignore any level pool overrides. * Unless a force is given then we always apply any overrides. */ if (!force && jcr->IgnoreLevelPoolOverides) { return; } /* * If only a pool override and no level overrides are given in run entry choose this pool */ if (jcr->res.run_pool_override && !jcr->res.run_full_pool_override && !jcr->res.run_vfull_pool_override && !jcr->res.run_inc_pool_override && !jcr->res.run_diff_pool_override) { pm_strcpy(jcr->res.pool_source, _("Run Pool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.pool->name(), _("Run Pool override\n")); } else { /* * Apply any level related Pool selections */ switch (jcr->getJobLevel()) { case L_FULL: if (jcr->res.full_pool) { jcr->res.pool = jcr->res.full_pool; pool_override = true; if (jcr->res.run_full_pool_override) { pm_strcpy(jcr->res.pool_source, _("Run FullPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Run FullPool override\n"); } else { pm_strcpy(jcr->res.pool_source, _("Job FullPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Job FullPool override\n"); } } break; case L_VIRTUAL_FULL: if (jcr->res.vfull_pool) { jcr->res.pool = jcr->res.vfull_pool; pool_override = true; if (jcr->res.run_vfull_pool_override) { pm_strcpy(jcr->res.pool_source, _("Run VFullPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.vfull_pool->name(), "Run VFullPool override\n"); } else { pm_strcpy(jcr->res.pool_source, _("Job VFullPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.vfull_pool->name(), "Job VFullPool override\n"); } } break; case L_INCREMENTAL: if (jcr->res.inc_pool) { jcr->res.pool = jcr->res.inc_pool; pool_override = true; if (jcr->res.run_inc_pool_override) { pm_strcpy(jcr->res.pool_source, _("Run IncPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Run IncPool override\n"); } else { pm_strcpy(jcr->res.pool_source, _("Job IncPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Job IncPool override\n"); } } break; case L_DIFFERENTIAL: if (jcr->res.diff_pool) { jcr->res.pool = jcr->res.diff_pool; pool_override = true; if (jcr->res.run_diff_pool_override) { pm_strcpy(jcr->res.pool_source, _("Run DiffPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Run DiffPool override\n"); } else { pm_strcpy(jcr->res.pool_source, _("Job DiffPool override")); Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Job DiffPool override\n"); } } break; } } /* * Update catalog if pool overridden */ if (pool_override && jcr->res.pool->catalog) { jcr->res.catalog = jcr->res.pool->catalog; pm_strcpy(jcr->res.catalog_source, _("Pool resource")); } } /* * Get or create a Client record for this Job */ bool get_or_create_client_record(JCR *jcr) { CLIENT_DBR cr; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, jcr->res.client->hdr.name, sizeof(cr.Name)); cr.AutoPrune = jcr->res.client->AutoPrune; cr.FileRetention = jcr->res.client->FileRetention; cr.JobRetention = jcr->res.client->JobRetention; if (!jcr->client_name) { jcr->client_name = get_pool_memory(PM_NAME); } pm_strcpy(jcr->client_name, jcr->res.client->hdr.name); if (!db_create_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"), db_strerror(jcr->db)); return false; } /* * Only initialize quota when a Soft or Hard Limit is set. */ if (jcr->res.client->HardQuota != 0 || jcr->res.client->SoftQuota != 0) { if (!db_get_quota_record(jcr, jcr->db, &cr)) { if (!db_create_quota_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_FATAL, 0, _("Could not create Quota record. ERR=%s\n"), db_strerror(jcr->db)); } jcr->res.client->QuotaLimit = 0; jcr->res.client->GraceTime = 0; } } jcr->jr.ClientId = cr.ClientId; jcr->res.client->QuotaLimit = cr.QuotaLimit; jcr->res.client->GraceTime = cr.GraceTime; if (cr.Uname[0]) { if (!jcr->client_uname) { jcr->client_uname = get_pool_memory(PM_NAME); } pm_strcpy(jcr->client_uname, cr.Uname); } Dmsg2(100, "Created Client %s record %d\n", jcr->res.client->hdr.name, jcr->jr.ClientId); return true; } bool get_or_create_fileset_record(JCR *jcr) { FILESET_DBR fsr; /* * Get or Create FileSet record */ memset(&fsr, 0, sizeof(fsr)); bstrncpy(fsr.FileSet, jcr->res.fileset->hdr.name, sizeof(fsr.FileSet)); if (jcr->res.fileset->have_MD5) { MD5_CTX md5c; unsigned char digest[MD5HashSize]; memcpy(&md5c, &jcr->res.fileset->md5c, sizeof(md5c)); MD5_Final(digest, &md5c); /* * Keep the flag (last arg) set to false otherwise old FileSets will * get new MD5 sums and the user will get Full backups on everything */ bin_to_base64(fsr.MD5, sizeof(fsr.MD5), (char *)digest, MD5HashSize, false); bstrncpy(jcr->res.fileset->MD5, fsr.MD5, sizeof(jcr->res.fileset->MD5)); } else { Jmsg(jcr, M_WARNING, 0, _("FileSet MD5 digest not found.\n")); } if (!jcr->res.fileset->ignore_fs_changes || !db_get_fileset_record(jcr, jcr->db, &fsr)) { if (!db_create_fileset_record(jcr, jcr->db, &fsr)) { Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"), fsr.FileSet, db_strerror(jcr->db)); return false; } } jcr->jr.FileSetId = fsr.FileSetId; bstrncpy(jcr->FSCreateTime, fsr.cCreateTime, sizeof(jcr->FSCreateTime)); Dmsg2(119, "Created FileSet %s record %u\n", jcr->res.fileset->hdr.name, jcr->jr.FileSetId); return true; } void init_jcr_job_record(JCR *jcr) { jcr->jr.SchedTime = jcr->sched_time; jcr->jr.StartTime = jcr->start_time; jcr->jr.EndTime = 0; /* perhaps rescheduled, clear it */ jcr->jr.JobType = jcr->getJobType(); jcr->jr.JobLevel = jcr->getJobLevel(); jcr->jr.JobStatus = jcr->JobStatus; jcr->jr.JobId = jcr->JobId; jcr->jr.JobSumTotalBytes = 18446744073709551615LLU; bstrncpy(jcr->jr.Name, jcr->res.job->name(), sizeof(jcr->jr.Name)); bstrncpy(jcr->jr.Job, jcr->Job, sizeof(jcr->jr.Job)); } /* * Write status and such in DB */ void update_job_end_record(JCR *jcr) { jcr->jr.EndTime = time(NULL); jcr->end_time = jcr->jr.EndTime; jcr->jr.JobId = jcr->JobId; jcr->jr.JobStatus = jcr->JobStatus; jcr->jr.JobFiles = jcr->JobFiles; jcr->jr.JobBytes = jcr->JobBytes; jcr->jr.ReadBytes = jcr->ReadBytes; jcr->jr.VolSessionId = jcr->VolSessionId; jcr->jr.VolSessionTime = jcr->VolSessionTime; jcr->jr.JobErrors = jcr->JobErrors; jcr->jr.HasBase = jcr->HasBase; if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), db_strerror(jcr->db)); } } /* * Takes base_name and appends (unique) current * date and time to form unique job name. * * Note, the seconds are actually a sequence number. This * permits us to start a maximum fo 59 unique jobs a second, which * should be sufficient. * * Returns: unique job name in jcr->Job * date/time in jcr->start_time */ void create_unique_job_name(JCR *jcr, const char *base_name) { /* Job start mutex */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static time_t last_start_time = 0; static int seq = 0; time_t now = time(NULL); char dt[MAX_TIME_LENGTH]; char name[MAX_NAME_LENGTH]; char *p; int len; /* Guarantee unique start time -- maximum one per second, and * thus unique Job Name */ P(mutex); /* lock creation of jobs */ seq++; if (seq > 59) { /* wrap as if it is seconds */ seq = 0; while (now == last_start_time) { bmicrosleep(0, 500000); now = time(NULL); } } last_start_time = now; V(mutex); /* allow creation of jobs */ jcr->start_time = now; /* * Form Unique JobName * Use only characters that are permitted in Windows filenames */ bstrftime(dt, sizeof(dt), jcr->start_time, "%Y-%m-%d_%H.%M.%S"); len = strlen(dt) + 5; /* dt + .%02d EOS */ bstrncpy(name, base_name, sizeof(name)); name[sizeof(name)-len] = 0; /* truncate if too long */ bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s_%02d", name, dt, seq); /* add date & time */ /* Convert spaces into underscores */ for (p=jcr->Job; *p; p++) { if (*p == ' ') { *p = '_'; } } Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job); } /* Called directly from job rescheduling */ void dird_free_jcr_pointers(JCR *jcr) { if (jcr->file_bsock) { Dmsg0(200, "Close File bsock\n"); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } if (jcr->store_bsock) { Dmsg0(200, "Close Store bsock\n"); jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; } bfree_and_null(jcr->sd_auth_key); bfree_and_null(jcr->where); bfree_and_null(jcr->backup_format); bfree_and_null(jcr->RestoreBootstrap); bfree_and_null(jcr->ar); free_and_null_pool_memory(jcr->JobIds); free_and_null_pool_memory(jcr->client_uname); free_and_null_pool_memory(jcr->attr); free_and_null_pool_memory(jcr->fname); } /* * Free the Job Control Record if no one is still using it. * Called from main free_jcr() routine in src/lib/jcr.c so * that we can do our Director specific cleanup of the jcr. */ void dird_free_jcr(JCR *jcr) { Dmsg0(200, "Start dird free_jcr\n"); if (jcr->mig_jcr) { free_jcr(jcr->mig_jcr); jcr->mig_jcr = NULL; } dird_free_jcr_pointers(jcr); if (jcr->term_wait_inited) { pthread_cond_destroy(&jcr->term_wait); jcr->term_wait_inited = false; } if (jcr->nextrun_ready_inited) { pthread_cond_destroy(&jcr->nextrun_ready); jcr->nextrun_ready_inited = false; } if (jcr->db_batch) { db_sql_close_pooled_connection(jcr, jcr->db_batch); jcr->db_batch = NULL; jcr->batch_started = false; } if (jcr->db) { db_sql_close_pooled_connection(jcr, jcr->db); jcr->db = NULL; } if (jcr->restore_tree_root) { free_tree(jcr->restore_tree_root); } if (jcr->bsr) { free_bsr(jcr->bsr); jcr->bsr = NULL; } free_and_null_pool_memory(jcr->stime); free_and_null_pool_memory(jcr->fname); free_and_null_pool_memory(jcr->res.pool_source); free_and_null_pool_memory(jcr->res.npool_source); free_and_null_pool_memory(jcr->res.rpool_source); free_and_null_pool_memory(jcr->res.wstore_source); free_and_null_pool_memory(jcr->res.rstore_source); free_and_null_pool_memory(jcr->res.catalog_source); /* * Delete lists setup to hold storage pointers */ free_rwstorage(jcr); jcr->job_end_push.destroy(); if (jcr->JobId != 0) { write_state_file(me->working_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); } free_plugins(jcr); /* release instantiated plugins */ Dmsg0(200, "End dird free_jcr\n"); } /* * The Job storage definition must be either in the Job record * or in the Pool record. The Pool record overrides the Job record. */ void get_job_storage(USTORERES *store, JOBRES *job, RUNRES *run) { if (run && run->pool && run->pool->storage) { store->store = (STORERES *)run->pool->storage->first(); pm_strcpy(store->store_source, _("Run pool override")); return; } if (run && run->storage) { store->store = run->storage; pm_strcpy(store->store_source, _("Run storage override")); return; } if (job->pool->storage) { store->store = (STORERES *)job->pool->storage->first(); pm_strcpy(store->store_source, _("Pool resource")); } else { if (job->storage) { store->store = (STORERES *)job->storage->first(); pm_strcpy(store->store_source, _("Job resource")); } } } /* * Set some defaults in the JCR necessary to * run. These items are pulled from the job * definition as defaults, but can be overridden * later either by the Run record in the Schedule resource, * or by the Console program. */ void set_jcr_defaults(JCR *jcr, JOBRES *job) { jcr->res.job = job; jcr->setJobType(job->JobType); jcr->setJobProtocol(job->Protocol); jcr->JobStatus = JS_Created; switch (jcr->getJobType()) { case JT_ADMIN: jcr->setJobLevel(L_NONE); break; default: jcr->setJobLevel(job->JobLevel); break; } if (!jcr->fname) { jcr->fname = get_pool_memory(PM_FNAME); } if (!jcr->res.pool_source) { jcr->res.pool_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.pool_source, _("unknown source")); } if (!jcr->res.npool_source) { jcr->res.npool_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.npool_source, _("unknown source")); } if (!jcr->res.catalog_source) { jcr->res.catalog_source = get_pool_memory(PM_MESSAGE); pm_strcpy(jcr->res.catalog_source, _("unknown source")); } jcr->JobPriority = job->Priority; /* * Copy storage definitions -- deleted in dir_free_jcr above */ if (job->storage) { copy_rwstorage(jcr, job->storage, _("Job resource")); } else { copy_rwstorage(jcr, job->pool->storage, _("Pool resource")); } jcr->res.client = job->client; if (jcr->res.client) { if (!jcr->client_name) { jcr->client_name = get_pool_memory(PM_NAME); } pm_strcpy(jcr->client_name, jcr->res.client->hdr.name); } pm_strcpy(jcr->res.pool_source, _("Job resource")); jcr->res.pool = job->pool; jcr->res.full_pool = job->full_pool; jcr->res.inc_pool = job->inc_pool; jcr->res.diff_pool = job->diff_pool; if (job->pool->catalog) { jcr->res.catalog = job->pool->catalog; pm_strcpy(jcr->res.catalog_source, _("Pool resource")); } else { if (job->catalog) { jcr->res.catalog = job->catalog; pm_strcpy(jcr->res.catalog_source, _("Job resource")); } else { if (job->client) { jcr->res.catalog = job->client->catalog; pm_strcpy(jcr->res.catalog_source, _("Client resource")); } else { jcr->res.catalog = (CATRES *)GetNextRes(R_CATALOG, NULL); pm_strcpy(jcr->res.catalog_source, _("Default catalog")); } } } jcr->res.fileset = job->fileset; jcr->accurate = job->accurate; jcr->res.messages = job->messages; jcr->spool_data = job->spool_data; jcr->spool_size = job->spool_size; jcr->IgnoreDuplicateJobChecking = job->IgnoreDuplicateJobChecking; jcr->MaxRunSchedTime = job->MaxRunSchedTime; jcr->backup_format = bstrdup(job->backup_format); if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; } /* * This can be overridden by Console program */ if (job->RestoreBootstrap) { jcr->RestoreBootstrap = bstrdup(job->RestoreBootstrap); } /* * This can be overridden by Console program */ jcr->res.verify_job = job->verify_job; /* * If no default level given, set one */ if (jcr->getJobLevel() == 0) { switch (jcr->getJobType()) { case JT_VERIFY: jcr->setJobLevel(L_VERIFY_CATALOG); break; case JT_BACKUP: jcr->setJobLevel(L_INCREMENTAL); break; case JT_RESTORE: case JT_ADMIN: jcr->setJobLevel(L_NONE); break; default: jcr->setJobLevel(L_FULL); break; } } } /* * Copy the storage definitions from an alist to the JCR */ void copy_rwstorage(JCR *jcr, alist *storage, const char *where) { if (jcr->JobReads()) { copy_rstorage(jcr, storage, where); } copy_wstorage(jcr, storage, where); } /* Set storage override. Releases any previous storage definition */ void set_rwstorage(JCR *jcr, USTORERES *store) { if (!store) { Jmsg(jcr, M_FATAL, 0, _("No storage specified.\n")); return; } if (jcr->JobReads()) { set_rstorage(jcr, store); } set_wstorage(jcr, store); } void free_rwstorage(JCR *jcr) { free_rstorage(jcr); free_wstorage(jcr); } /* * Copy the storage definitions from an alist to the JCR */ void copy_rstorage(JCR *jcr, alist *storage, const char *where) { if (storage) { STORERES *store; if (jcr->rstorage) { delete jcr->rstorage; } jcr->rstorage = New(alist(10, not_owned_by_alist)); foreach_alist(store, storage) { jcr->rstorage->append(store); } if (!jcr->res.rstore_source) { jcr->res.rstore_source = get_pool_memory(PM_MESSAGE); } pm_strcpy(jcr->res.rstore_source, where); if (jcr->rstorage) { jcr->res.rstore = (STORERES *)jcr->rstorage->first(); } } } /* Set storage override. Remove all previous storage */ void set_rstorage(JCR *jcr, USTORERES *store) { STORERES *storage; if (!store->store) { return; } if (jcr->rstorage) { free_rstorage(jcr); } if (!jcr->rstorage) { jcr->rstorage = New(alist(10, not_owned_by_alist)); } jcr->res.rstore = store->store; if (!jcr->res.rstore_source) { jcr->res.rstore_source = get_pool_memory(PM_MESSAGE); } pm_strcpy(jcr->res.rstore_source, store->store_source); foreach_alist(storage, jcr->rstorage) { if (store->store == storage) { return; } } /* Store not in list, so add it */ jcr->rstorage->prepend(store->store); } void free_rstorage(JCR *jcr) { if (jcr->rstorage) { delete jcr->rstorage; jcr->rstorage = NULL; } jcr->res.rstore = NULL; } /* * Copy the storage definitions from an alist to the JCR */ void copy_wstorage(JCR *jcr, alist *storage, const char *where) { if (storage) { STORERES *st; if (jcr->wstorage) { delete jcr->wstorage; } jcr->wstorage = New(alist(10, not_owned_by_alist)); foreach_alist(st, storage) { Dmsg1(100, "wstorage=%s\n", st->name()); jcr->wstorage->append(st); } if (!jcr->res.wstore_source) { jcr->res.wstore_source = get_pool_memory(PM_MESSAGE); } pm_strcpy(jcr->res.wstore_source, where); if (jcr->wstorage) { jcr->res.wstore = (STORERES *)jcr->wstorage->first(); Dmsg2(100, "wstore=%s where=%s\n", jcr->res.wstore->name(), jcr->res.wstore_source); } } } /* Set storage override. Remove all previous storage */ void set_wstorage(JCR *jcr, USTORERES *store) { STORERES *storage; if (!store->store) { return; } if (jcr->wstorage) { free_wstorage(jcr); } if (!jcr->wstorage) { jcr->wstorage = New(alist(10, not_owned_by_alist)); } jcr->res.wstore = store->store; if (!jcr->res.wstore_source) { jcr->res.wstore_source = get_pool_memory(PM_MESSAGE); } pm_strcpy(jcr->res.wstore_source, store->store_source); Dmsg2(50, "wstore=%s where=%s\n", jcr->res.wstore->name(), jcr->res.wstore_source); foreach_alist(storage, jcr->wstorage) { if (store->store == storage) { return; } } /* Store not in list, so add it */ jcr->wstorage->prepend(store->store); } void free_wstorage(JCR *jcr) { if (jcr->wstorage) { delete jcr->wstorage; jcr->wstorage = NULL; } jcr->res.wstore = NULL; } /* * For NDMP backup we can setup the backup to run to a NDMP instance * of the same Storage Daemon that also does native native backups. * This way a Normal Storage Daemon can perform NDMP protocol based * saves and restores. */ void set_paired_storage(JCR *jcr) { STORERES *store, *pstore; if (jcr->wstorage) { /* * Setup the jcr->wstorage to point to all paired_storage * entries of all the storage currently in the jcr->wstorage. * Save the original list under jcr->pstorage. */ jcr->pstorage = jcr->wstorage; jcr->wstorage = New(alist(10, not_owned_by_alist)); foreach_alist(store, jcr->pstorage) { if (store->paired_storage) { Dmsg1(100, "wstorage=%s\n", store->paired_storage->name()); jcr->wstorage->append(store->paired_storage); } } /* * Swap the actual jcr->res.wstore to point to the paired storage entry. * We save the actual storage entry in pstore which is for restore * in the free_paired_storage() function. */ store = jcr->res.wstore; if (store->paired_storage) { jcr->res.wstore = store->paired_storage; jcr->res.pstore = store; } } else { /* * Setup the jcr->pstorage to point to all paired_storage * entries of all the storage currently in the jcr->rstorage. */ jcr->pstorage = New(alist(10, not_owned_by_alist)); foreach_alist(pstore, jcr->rstorage) { store = (STORERES *)GetNextRes(R_STORAGE, NULL); while (store) { if (store->paired_storage == pstore) { break; } store = (STORERES *)GetNextRes(R_STORAGE, (RES *)store); } /* * See if we found a store that has the current pstore as * its paired storage. */ if (store) { jcr->pstorage->append(store); /* * If the current processed pstore is also the current * entry in jcr->res.rstore update the jcr->pstore to point * to this storage entry. */ if (pstore == jcr->res.rstore) { jcr->res.pstore = store; } } } } } /* * This performs an undo of the actions the set_paired_storage() function * performed. We reset the storage write storage back to its original * and remove the paired storage override if any. */ void free_paired_storage(JCR *jcr) { if (jcr->pstorage) { if (jcr->wstorage) { /* * The jcr->wstorage contain a set of paired storages. * We just delete it content and swap back to the real master storage. */ delete jcr->wstorage; jcr->wstorage = jcr->pstorage; jcr->pstorage = NULL; jcr->res.wstore = jcr->res.pstore; jcr->res.pstore = NULL; } else { /* * The jcr->rstorage contain a set of paired storages. * For the read we created a list of alternative storage which we * can just drop now. */ delete jcr->pstorage; jcr->pstorage = NULL; jcr->res.pstore = NULL; } } } /* * Check if every possible storage has paired storage associated. */ bool has_paired_storage(JCR *jcr) { STORERES *store; if (jcr->wstorage) { foreach_alist(store, jcr->wstorage) { if (!store->paired_storage) { return false; } } } else { foreach_alist(store, jcr->rstorage) { if (!store->paired_storage) { return false; } } } return true; } #define MAX_TRIES 6 * 360 /* 6 hours (10 sec intervals) */ /* * Change the read storage resource for the current job. */ bool select_next_rstore(JCR *jcr, bootstrap_info &info) { USTORERES ustore; int i; if (bstrcmp(jcr->res.rstore->name(), info.storage)) { return true; /* Same SD nothing to change */ } if (!(ustore.store = (STORERES *)GetResWithName(R_STORAGE,info.storage))) { Jmsg(jcr, M_FATAL, 0, _("Could not get storage resource '%s'.\n"), info.storage); jcr->setJobStatus(JS_ErrorTerminated); return false; } /* * We start communicating with a new storage daemon so close the * old connection when it is still open. */ if (jcr->store_bsock) { jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; } /* * Release current read storage and get a new one */ dec_read_store(jcr); free_rstorage(jcr); set_rstorage(jcr, &ustore); jcr->setJobStatus(JS_WaitSD); /* * Wait for up to 6 hours to increment read stoage counter */ for (i=0; i < MAX_TRIES; i++) { /* * Try to get read storage counter incremented */ if (inc_read_store(jcr)) { jcr->setJobStatus(JS_Running); return true; } bmicrosleep(10, 0); /* Sleep 10 secs */ if (job_canceled(jcr)) { free_rstorage(jcr); return false; } } /* * Failed to inc_read_store() */ free_rstorage(jcr); Jmsg(jcr, M_FATAL, 0, _("Could not acquire read storage lock for \"%s\""), info.storage); return false; } void create_clones(JCR *jcr) { /* * Fire off any clone jobs (run directives) */ Dmsg2(900, "cloned=%d run_cmds=%p\n", jcr->cloned, jcr->res.job->run_cmds); if (!jcr->cloned && jcr->res.job->run_cmds) { char *runcmd; JOBRES *job = jcr->res.job; POOLMEM *cmd = get_pool_memory(PM_FNAME); UAContext *ua = new_ua_context(jcr); ua->batch = true; foreach_alist(runcmd, job->run_cmds) { cmd = edit_job_codes(jcr, cmd, runcmd, "", job_code_callback_director); Mmsg(ua->cmd, "run %s cloned=yes", cmd); Dmsg1(900, "=============== Clone cmd=%s\n", ua->cmd); parse_ua_args(ua); /* parse command */ int status = run_cmd(ua, ua->cmd); if (status == 0) { Jmsg(jcr, M_ERROR, 0, _("Could not start clone job: \"%s\".\n"), ua->cmd); } else { Jmsg(jcr, M_INFO, 0, _("Clone JobId %d started.\n"), status); } } free_ua_context(ua); free_pool_memory(cmd); } } /* * Given: a JobId in jcr->previous_jr.JobId, * this subroutine writes a bsr file to restore that job. * Returns: -1 on error * number of files if OK */ int create_restore_bootstrap_file(JCR *jcr) { RESTORE_CTX rx; UAContext *ua; int files; memset(&rx, 0, sizeof(rx)); rx.bsr = new_bsr(); rx.JobIds = (char *)""; rx.bsr->JobId = jcr->previous_jr.JobId; ua = new_ua_context(jcr); if (!complete_bsr(ua, rx.bsr)) { files = -1; goto bail_out; } rx.bsr->fi = new_findex(); rx.bsr->fi->findex = 1; rx.bsr->fi->findex2 = jcr->previous_jr.JobFiles; jcr->ExpectedFiles = write_bsr_file(ua, rx); if (jcr->ExpectedFiles == 0) { files = 0; goto bail_out; } free_ua_context(ua); free_bsr(rx.bsr); jcr->needs_sd = true; return jcr->ExpectedFiles; bail_out: free_ua_context(ua); free_bsr(rx.bsr); return files; } /* TODO: redirect command ouput to job log */ bool run_console_command(JCR *jcr, const char *cmd) { UAContext *ua; bool ok; JCR *ljcr = new_control_jcr("-RunScript-", JT_CONSOLE); ua = new_ua_context(ljcr); /* run from runscript and check if commands are authorized */ ua->runscript = true; Mmsg(ua->cmd, "%s", cmd); Dmsg1(100, "Console command: %s\n", ua->cmd); parse_ua_args(ua); if (ua->argc > 0 && ua->argk[0][0] == '.') { ok = do_a_dot_command(ua); } else { ok = do_a_command(ua); } free_ua_context(ua); free_jcr(ljcr); return ok; } bareos-Release-14.2.6/src/dird/jobq.c000066400000000000000000000714001263011562700172520ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS job queue routines. * * This code consists of three queues, the waiting_jobs * queue, where jobs are initially queued, the ready_jobs * queue, where jobs are placed when all the resources are * allocated and they can immediately be run, and the * running queue where jobs are placed when they are * running. * * Kern Sibbald, July MMIII * * * This code was adapted from the Bareos workq, which was * adapted from "Programming with POSIX Threads", by * David R. Butenhof */ #include "bareos.h" #include "dird.h" extern JCR *jobs; /* Forward referenced functions */ extern "C" void *jobq_server(void *arg); extern "C" void *sched_wait(void *arg); static int start_server(jobq_t *jq); static bool acquire_resources(JCR *jcr); static bool reschedule_job(JCR *jcr, jobq_t *jq, jobq_item_t *je); static void dec_write_store(JCR *jcr); /* * Initialize a job queue * * Returns: 0 on success * errno on failure */ int jobq_init(jobq_t *jq, int threads, void *(*engine)(void *arg)) { int status; jobq_item_t *item = NULL; if ((status = pthread_attr_init(&jq->attr)) != 0) { berrno be; Jmsg1(NULL, M_ERROR, 0, _("pthread_attr_init: ERR=%s\n"), be.bstrerror(status)); return status; } if ((status = pthread_attr_setdetachstate(&jq->attr, PTHREAD_CREATE_DETACHED)) != 0) { pthread_attr_destroy(&jq->attr); return status; } if ((status = pthread_mutex_init(&jq->mutex, NULL)) != 0) { berrno be; Jmsg1(NULL, M_ERROR, 0, _("pthread_mutex_init: ERR=%s\n"), be.bstrerror(status)); pthread_attr_destroy(&jq->attr); return status; } if ((status = pthread_cond_init(&jq->work, NULL)) != 0) { berrno be; Jmsg1(NULL, M_ERROR, 0, _("pthread_cond_init: ERR=%s\n"), be.bstrerror(status)); pthread_mutex_destroy(&jq->mutex); pthread_attr_destroy(&jq->attr); return status; } jq->quit = false; jq->max_workers = threads; /* max threads to create */ jq->num_workers = 0; /* no threads yet */ jq->idle_workers = 0; /* no idle threads */ jq->engine = engine; /* routine to run */ jq->valid = JOBQ_VALID; /* Initialize the job queues */ jq->waiting_jobs = New(dlist(item, &item->link)); jq->running_jobs = New(dlist(item, &item->link)); jq->ready_jobs = New(dlist(item, &item->link)); return 0; } /* * Destroy the job queue * * Returns: 0 on success * errno on failure */ int jobq_destroy(jobq_t *jq) { int status, status1, status2; if (jq->valid != JOBQ_VALID) { return EINVAL; } P(jq->mutex); jq->valid = 0; /* prevent any more operations */ /* * If any threads are active, wake them */ if (jq->num_workers > 0) { jq->quit = true; if (jq->idle_workers) { if ((status = pthread_cond_broadcast(&jq->work)) != 0) { berrno be; Jmsg1(NULL, M_ERROR, 0, _("pthread_cond_broadcast: ERR=%s\n"), be.bstrerror(status)); V(jq->mutex); return status; } } while (jq->num_workers > 0) { if ((status = pthread_cond_wait(&jq->work, &jq->mutex)) != 0) { berrno be; Jmsg1(NULL, M_ERROR, 0, _("pthread_cond_wait: ERR=%s\n"), be.bstrerror(status)); V(jq->mutex); return status; } } } V(jq->mutex); status = pthread_mutex_destroy(&jq->mutex); status1 = pthread_cond_destroy(&jq->work); status2 = pthread_attr_destroy(&jq->attr); delete jq->waiting_jobs; delete jq->running_jobs; delete jq->ready_jobs; return (status != 0 ? status : (status1 != 0 ? status1 : status2)); } struct wait_pkt { JCR *jcr; jobq_t *jq; }; /* * Wait until schedule time arrives before starting. Normally * this routine is only used for jobs started from the console * for which the user explicitly specified a start time. Otherwise * most jobs are put into the job queue only when their * scheduled time arives. */ extern "C" void *sched_wait(void *arg) { JCR *jcr = ((wait_pkt *)arg)->jcr; jobq_t *jq = ((wait_pkt *)arg)->jq; set_jcr_in_tsd(INVALID_JCR); Dmsg0(2300, "Enter sched_wait.\n"); free(arg); time_t wtime = jcr->sched_time - time(NULL); jcr->setJobStatus(JS_WaitStartTime); /* Wait until scheduled time arrives */ if (wtime > 0) { Jmsg(jcr, M_INFO, 0, _("Job %s waiting %d seconds for scheduled start time.\n"), jcr->Job, wtime); } /* Check every 30 seconds if canceled */ while (wtime > 0) { Dmsg3(2300, "Waiting on sched time, jobid=%d secs=%d use=%d\n", jcr->JobId, wtime, jcr->use_count()); if (wtime > 30) { wtime = 30; } bmicrosleep(wtime, 0); if (job_canceled(jcr)) { break; } wtime = jcr->sched_time - time(NULL); } Dmsg1(200, "resched use=%d\n", jcr->use_count()); jobq_add(jq, jcr); free_jcr(jcr); /* we are done with jcr */ Dmsg0(2300, "Exit sched_wait\n"); return NULL; } /* * Add a job to the queue * jq is a queue that was created with jobq_init */ int jobq_add(jobq_t *jq, JCR *jcr) { int status; jobq_item_t *item, *li; bool inserted = false; time_t wtime = jcr->sched_time - time(NULL); pthread_t id; wait_pkt *sched_pkt; if (!jcr->term_wait_inited) { /* Initialize termination condition variable */ if ((status = pthread_cond_init(&jcr->term_wait, NULL)) != 0) { berrno be; Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(status)); return status; } jcr->term_wait_inited = true; } Dmsg3(2300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count()); if (jq->valid != JOBQ_VALID) { Jmsg0(jcr, M_ERROR, 0, "Jobq_add queue not initialized.\n"); return EINVAL; } jcr->inc_use_count(); /* mark jcr in use by us */ Dmsg3(2300, "jobq_add jobid=%d jcr=0x%x use_count=%d\n", jcr->JobId, jcr, jcr->use_count()); if (!job_canceled(jcr) && wtime > 0) { set_thread_concurrency(jq->max_workers + 2); sched_pkt = (wait_pkt *)malloc(sizeof(wait_pkt)); sched_pkt->jcr = jcr; sched_pkt->jq = jq; status = pthread_create(&id, &jq->attr, sched_wait, (void *)sched_pkt); if (status != 0) { /* thread not created */ berrno be; Jmsg1(jcr, M_ERROR, 0, _("pthread_thread_create: ERR=%s\n"), be.bstrerror(status)); } return status; } P(jq->mutex); if ((item = (jobq_item_t *)malloc(sizeof(jobq_item_t))) == NULL) { free_jcr(jcr); /* release jcr */ return ENOMEM; } item->jcr = jcr; /* While waiting in a queue this job is not attached to a thread */ set_jcr_in_tsd(INVALID_JCR); if (job_canceled(jcr)) { /* Add job to ready queue so that it is canceled quickly */ jq->ready_jobs->prepend(item); Dmsg1(2300, "Prepended job=%d to ready queue\n", jcr->JobId); } else { /* Add this job to the wait queue in priority sorted order */ foreach_dlist(li, jq->waiting_jobs) { Dmsg2(2300, "waiting item jobid=%d priority=%d\n", li->jcr->JobId, li->jcr->JobPriority); if (li->jcr->JobPriority > jcr->JobPriority) { jq->waiting_jobs->insert_before(item, li); Dmsg2(2300, "insert_before jobid=%d before waiting job=%d\n", li->jcr->JobId, jcr->JobId); inserted = true; break; } } /* If not jobs in wait queue, append it */ if (!inserted) { jq->waiting_jobs->append(item); Dmsg1(2300, "Appended item jobid=%d to waiting queue\n", jcr->JobId); } } /* Ensure that at least one server looks at the queue. */ status = start_server(jq); V(jq->mutex); Dmsg0(2300, "Return jobq_add\n"); return status; } /* * Remove a job from the job queue. Used only by cancel_job(). * jq is a queue that was created with jobq_init * work_item is an element of work * * Note, it is "removed" from the job queue. * If you want to cancel it, you need to provide some external means * of doing so (e.g. pthread_kill()). */ int jobq_remove(jobq_t *jq, JCR *jcr) { int status; bool found = false; jobq_item_t *item; Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x\n", jcr->JobId, jcr); if (jq->valid != JOBQ_VALID) { return EINVAL; } P(jq->mutex); foreach_dlist(item, jq->waiting_jobs) { if (jcr == item->jcr) { found = true; break; } } if (!found) { V(jq->mutex); Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x not in wait queue\n", jcr->JobId, jcr); return EINVAL; } /* Move item to be the first on the list */ jq->waiting_jobs->remove(item); jq->ready_jobs->prepend(item); Dmsg2(2300, "jobq_remove jobid=%d jcr=0x%x moved to ready queue\n", jcr->JobId, jcr); status = start_server(jq); V(jq->mutex); Dmsg0(2300, "Return jobq_remove\n"); return status; } /* * Start the server thread if it isn't already running */ static int start_server(jobq_t *jq) { int status = 0; pthread_t id; /* * if any threads are idle, wake one. * Actually we do a broadcast because on /lib/tls * these signals seem to get lost from time to time. */ if (jq->idle_workers > 0) { Dmsg0(2300, "Signal worker to wake up\n"); if ((status = pthread_cond_broadcast(&jq->work)) != 0) { berrno be; Jmsg1(NULL, M_ERROR, 0, _("pthread_cond_signal: ERR=%s\n"), be.bstrerror(status)); return status; } } else if (jq->num_workers < jq->max_workers) { Dmsg0(2300, "Create worker thread\n"); /* No idle threads so create a new one */ set_thread_concurrency(jq->max_workers + 1); jq->num_workers++; if ((status = pthread_create(&id, &jq->attr, jobq_server, (void *)jq)) != 0) { berrno be; jq->num_workers--; Jmsg1(NULL, M_ERROR, 0, _("pthread_create: ERR=%s\n"), be.bstrerror(status)); return status; } } return status; } /* * This is the worker thread that serves the job queue. * When all the resources are acquired for the job, * it will call the user's engine. */ extern "C" void *jobq_server(void *arg) { struct timespec timeout; jobq_t *jq = (jobq_t *)arg; jobq_item_t *je; /* job entry in queue */ int status; bool timedout = false; bool work = true; set_jcr_in_tsd(INVALID_JCR); Dmsg0(2300, "Start jobq_server\n"); P(jq->mutex); for (;;) { struct timeval tv; struct timezone tz; Dmsg0(2300, "Top of for loop\n"); if (!work && !jq->quit) { gettimeofday(&tv, &tz); timeout.tv_nsec = 0; timeout.tv_sec = tv.tv_sec + 4; while (!jq->quit) { /* * Wait 4 seconds, then if no more work, exit */ Dmsg0(2300, "pthread_cond_timedwait()\n"); status = pthread_cond_timedwait(&jq->work, &jq->mutex, &timeout); if (status == ETIMEDOUT) { Dmsg0(2300, "timedwait timedout.\n"); timedout = true; break; } else if (status != 0) { /* * This shouldn't happen */ Dmsg0(2300, "This shouldn't happen\n"); jq->num_workers--; V(jq->mutex); return NULL; } break; } } /* * If anything is in the ready queue, run it */ Dmsg0(2300, "Checking ready queue.\n"); while (!jq->ready_jobs->empty() && !jq->quit) { JCR *jcr; je = (jobq_item_t *)jq->ready_jobs->first(); jcr = je->jcr; jq->ready_jobs->remove(je); if (!jq->ready_jobs->empty()) { Dmsg0(2300, "ready queue not empty start server\n"); if (start_server(jq) != 0) { jq->num_workers--; V(jq->mutex); return NULL; } } jq->running_jobs->append(je); /* * Attach jcr to this thread while we run the job */ jcr->set_killable(true); set_jcr_in_tsd(jcr); Dmsg1(2300, "Took jobid=%d from ready and appended to run\n", jcr->JobId); /* * Release job queue lock */ V(jq->mutex); /* * Call user's routine here */ Dmsg3(2300, "Calling user engine for jobid=%d use=%d stat=%c\n", jcr->JobId, jcr->use_count(), jcr->JobStatus); jq->engine(je->jcr); /* * Job finished detach from thread */ remove_jcr_from_tsd(je->jcr); je->jcr->set_killable(false); Dmsg2(2300, "Back from user engine jobid=%d use=%d.\n", jcr->JobId, jcr->use_count()); /* * Reacquire job queue lock */ P(jq->mutex); Dmsg0(200, "Done lock mutex after running job. Release locks.\n"); jq->running_jobs->remove(je); /* * Release locks if acquired. Note, they will not have * been acquired for jobs canceled before they were * put into the ready queue. */ if (jcr->acquired_resource_locks) { dec_read_store(jcr); dec_write_store(jcr); if (jcr->res.client) { /* * Some Job Types are excluded from the client concurrency as they have no * interaction with the client at all. */ switch (jcr->getJobType()) { case JT_MIGRATE: case JT_COPY: break; default: jcr->res.client->NumConcurrentJobs--; break; } } jcr->res.job->NumConcurrentJobs--; jcr->acquired_resource_locks = false; } if (reschedule_job(jcr, jq, je)) { continue; /* go look for more work */ } /* * Clean up and release old jcr */ Dmsg2(2300, "====== Termination job=%d use_cnt=%d\n", jcr->JobId, jcr->use_count()); jcr->SDJobStatus = 0; V(jq->mutex); /* release internal lock */ free_jcr(jcr); free(je); /* release job entry */ P(jq->mutex); /* reacquire job queue lock */ } /* * If any job in the wait queue can be run, move it to the ready queue */ Dmsg0(2300, "Done check ready, now check wait queue.\n"); if (!jq->waiting_jobs->empty() && !jq->quit) { int Priority; bool running_allow_mix = false; je = (jobq_item_t *)jq->waiting_jobs->first(); jobq_item_t *re = (jobq_item_t *)jq->running_jobs->first(); if (re) { Priority = re->jcr->JobPriority; Dmsg2(2300, "JobId %d is running. Look for pri=%d\n", re->jcr->JobId, Priority); running_allow_mix = true; for ( ; re; ) { Dmsg2(2300, "JobId %d is also running with %s\n", re->jcr->JobId, re->jcr->res.job->allow_mixed_priority ? "mix" : "no mix"); if (!re->jcr->res.job->allow_mixed_priority) { running_allow_mix = false; break; } re = (jobq_item_t *)jq->running_jobs->next(re); } Dmsg1(2300, "The running job(s) %s mixing priorities.\n", running_allow_mix ? "allow" : "don't allow"); } else { Priority = je->jcr->JobPriority; Dmsg1(2300, "No job running. Look for Job pri=%d\n", Priority); } /* * Walk down the list of waiting jobs and attempt to acquire the resources it needs. */ for ( ; je; ) { /* * je is current job item on the queue, jn is the next one */ JCR *jcr = je->jcr; jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je); Dmsg4(2300, "Examining Job=%d JobPri=%d want Pri=%d (%s)\n", jcr->JobId, jcr->JobPriority, Priority, jcr->res.job->allow_mixed_priority ? "mix" : "no mix"); /* * Take only jobs of correct Priority */ if (!(jcr->JobPriority == Priority || (jcr->JobPriority < Priority && jcr->res.job->allow_mixed_priority && running_allow_mix))) { jcr->setJobStatus(JS_WaitPriority); break; } if (!acquire_resources(jcr)) { /* * If resource conflict, job is canceled */ if (!job_canceled(jcr)) { je = jn; /* point to next waiting job */ continue; } } /* * Got all locks, now remove it from wait queue and append it * to the ready queue. Note, we may also get here if the * job was canceled. Once it is "run", it will quickly terminate. */ jq->waiting_jobs->remove(je); jq->ready_jobs->append(je); Dmsg1(2300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId); je = jn; /* Point to next waiting job */ } /* end for loop */ } /* end if */ Dmsg0(2300, "Done checking wait queue.\n"); /* * If no more ready work and we are asked to quit, then do it */ if (jq->ready_jobs->empty() && jq->quit) { jq->num_workers--; if (jq->num_workers == 0) { Dmsg0(2300, "Wake up destroy routine\n"); /* * Wake up destroy routine if he is waiting */ pthread_cond_broadcast(&jq->work); } break; } Dmsg0(2300, "Check for work request\n"); /* * If no more work requests, and we waited long enough, quit */ Dmsg2(2300, "timedout=%d read empty=%d\n", timedout, jq->ready_jobs->empty()); if (jq->ready_jobs->empty() && timedout) { Dmsg0(2300, "break big loop\n"); jq->num_workers--; break; } work = !jq->ready_jobs->empty() || !jq->waiting_jobs->empty(); if (work) { /* * If a job is waiting on a Resource, don't consume all * the CPU time looping looking for work, and even more * important, release the lock so that a job that has * terminated can give us the resource. */ V(jq->mutex); bmicrosleep(2, 0); /* pause for 2 seconds */ P(jq->mutex); /* * Recompute work as something may have changed in last 2 secs */ work = !jq->ready_jobs->empty() || !jq->waiting_jobs->empty(); } Dmsg1(2300, "Loop again. work=%d\n", work); } /* end of big for loop */ Dmsg0(200, "unlock mutex\n"); V(jq->mutex); Dmsg0(2300, "End jobq_server\n"); return NULL; } /* * Returns true if cleanup done and we should look for more work */ static bool reschedule_job(JCR *jcr, jobq_t *jq, jobq_item_t *je) { bool resched = false, retval = false; /* * Reschedule the job if requested and possible */ /* * Basic condition is that more reschedule times remain */ if (jcr->res.job->RescheduleTimes == 0 || jcr->reschedule_count < jcr->res.job->RescheduleTimes) { resched = /* * Check for incomplete jobs */ (jcr->res.job->RescheduleIncompleteJobs && jcr->is_incomplete() && jcr->is_JobType(JT_BACKUP) && !jcr->is_JobLevel(L_BASE)) || /* * Check for failed jobs */ (jcr->res.job->RescheduleOnError && !jcr->is_terminated_ok() && !jcr->is_JobStatus(JS_Canceled) && jcr->is_JobType(JT_BACKUP)); } if (resched) { char dt[50], dt2[50]; time_t now; /* * Reschedule this job by cleaning it up, but reuse the same JobId if possible. */ now = time(NULL); jcr->reschedule_count++; jcr->sched_time = now + jcr->res.job->RescheduleInterval; bstrftime(dt, sizeof(dt), now); bstrftime(dt2, sizeof(dt2), jcr->sched_time); Dmsg4(2300, "Rescheduled Job %s to re-run in %d seconds.(now=%u,then=%u)\n", jcr->Job, (int)jcr->res.job->RescheduleInterval, now, jcr->sched_time); Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds (%s).\n"), jcr->Job, dt, (int)jcr->res.job->RescheduleInterval, dt2); dird_free_jcr_pointers(jcr); /* partial cleanup old stuff */ jcr->JobStatus = -1; jcr->setJobStatus(JS_WaitStartTime); jcr->SDJobStatus = 0; jcr->JobErrors = 0; if (!allow_duplicate_job(jcr)) { return false; } /* * Only jobs with no output or Incomplete jobs can run on same JCR */ if (jcr->JobBytes == 0) { Dmsg2(2300, "Requeue job=%d use=%d\n", jcr->JobId, jcr->use_count()); V(jq->mutex); jcr->jr.RealEndTime = 0; jobq_add(jq, jcr); /* queue the job to run again */ P(jq->mutex); free_jcr(jcr); /* release jcr */ free(je); /* free the job entry */ retval = true; /* we already cleaned up */ } else { JCR *njcr; /* * Something was actually backed up, so we cannot reuse * the old JobId or there will be database record * conflicts. We now create a new job, copying the * appropriate fields. */ njcr = new_jcr(sizeof(JCR), dird_free_jcr); set_jcr_defaults(njcr, jcr->res.job); njcr->reschedule_count = jcr->reschedule_count; njcr->sched_time = jcr->sched_time; njcr->initial_sched_time = jcr->initial_sched_time; njcr->setJobLevel(jcr->getJobLevel()); njcr->res.pool = jcr->res.pool; njcr->res.run_pool_override = jcr->res.run_pool_override; njcr->res.full_pool = jcr->res.full_pool; njcr->res.run_full_pool_override = jcr->res.run_full_pool_override; njcr->res.inc_pool = jcr->res.inc_pool; njcr->res.run_inc_pool_override = jcr->res.run_inc_pool_override; njcr->res.diff_pool = jcr->res.diff_pool; njcr->res.run_diff_pool_override = jcr->res.run_diff_pool_override; njcr->res.next_pool = jcr->res.next_pool; njcr->res.run_next_pool_override = jcr->res.run_next_pool_override; njcr->JobStatus = -1; njcr->setJobStatus(jcr->JobStatus); if (jcr->res.rstore) { copy_rstorage(njcr, jcr->rstorage, _("previous Job")); } else { free_rstorage(njcr); } if (jcr->res.wstore) { copy_wstorage(njcr, jcr->wstorage, _("previous Job")); } else { free_wstorage(njcr); } njcr->res.messages = jcr->res.messages; njcr->spool_data = jcr->spool_data; Dmsg0(2300, "Call to run new job\n"); V(jq->mutex); run_job(njcr); /* This creates a "new" job */ free_jcr(njcr); /* release "new" jcr */ P(jq->mutex); Dmsg0(2300, "Back from running new job.\n"); } } return retval; } /* * See if we can acquire all the necessary resources for the job (JCR) * * Returns: true if successful * false if resource failure */ static bool acquire_resources(JCR *jcr) { bool skip_this_jcr = false; jcr->acquired_resource_locks = false; /* * Turning this code off is likely to cause some deadlocks, * but we do not really have enough information here to * know if this is really a deadlock (it may be a dual drive * autochanger), and in principle, the SD reservation system * should detect these deadlocks, so push the work off on it. */ #ifdef xxx if (jcr->res.rstore && jcr->res.rstore == jcr->res.wstore) { /* possible deadlock */ Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n" " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"), jcr->res.rstore->name(), jcr->res.rstore_source, jcr->res.wstore->name(), jcr->res.wstore_source); jcr->setJobStatus(JS_Canceled); return false; } #endif if (jcr->res.rstore) { Dmsg1(200, "Rstore=%s\n", jcr->res.rstore->name()); if (!inc_read_store(jcr)) { Dmsg1(200, "Fail rncj=%d\n", jcr->res.rstore->NumConcurrentJobs); jcr->setJobStatus(JS_WaitStoreRes); return false; } } if (jcr->res.wstore) { Dmsg1(200, "Wstore=%s\n", jcr->res.wstore->name()); if (jcr->res.wstore->NumConcurrentJobs < jcr->res.wstore->MaxConcurrentJobs) { jcr->res.wstore->NumConcurrentJobs++; Dmsg1(200, "Inc wncj=%d\n", jcr->res.wstore->NumConcurrentJobs); } else if (jcr->res.rstore) { dec_read_store(jcr); skip_this_jcr = true; } else { Dmsg1(200, "Fail wncj=%d\n", jcr->res.wstore->NumConcurrentJobs); skip_this_jcr = true; } } if (skip_this_jcr) { jcr->setJobStatus(JS_WaitStoreRes); return false; } /* * Some Job Types are excluded from the client concurrency as they have no * interaction with the client at all. */ switch (jcr->getJobType()) { case JT_MIGRATE: case JT_COPY: break; default: if (jcr->res.client) { if (jcr->res.client->NumConcurrentJobs < jcr->res.client->MaxConcurrentJobs) { jcr->res.client->NumConcurrentJobs++; } else { /* * Back out previous locks */ dec_write_store(jcr); dec_read_store(jcr); jcr->setJobStatus(JS_WaitClientRes); return false; } } break; } if (jcr->res.job->NumConcurrentJobs < jcr->res.job->MaxConcurrentJobs) { jcr->res.job->NumConcurrentJobs++; } else { /* * Back out previous locks */ dec_write_store(jcr); dec_read_store(jcr); /* * Some Job Types are excluded from the client concurrency as they have no * interaction with the client at all. */ switch (jcr->getJobType()) { case JT_MIGRATE: case JT_COPY: break; default: if (jcr->res.client) { jcr->res.client->NumConcurrentJobs--; } break; } jcr->setJobStatus(JS_WaitJobRes); return false; } jcr->acquired_resource_locks = true; return true; } static pthread_mutex_t rstore_mutex = PTHREAD_MUTEX_INITIALIZER; /* * Note: inc_read_store() and dec_read_store() are * called from select_rstore() in src/dird/restore.c */ bool inc_read_store(JCR *jcr) { P(rstore_mutex); if (jcr->res.rstore->NumConcurrentJobs < jcr->res.rstore->MaxConcurrentJobs) { jcr->res.rstore->NumConcurrentReadJobs++; jcr->res.rstore->NumConcurrentJobs++; Dmsg1(200, "Inc rncj=%d\n", jcr->res.rstore->NumConcurrentJobs); V(rstore_mutex); return true; } V(rstore_mutex); return false; } void dec_read_store(JCR *jcr) { if (jcr->res.rstore) { P(rstore_mutex); jcr->res.rstore->NumConcurrentReadJobs--; /* back out rstore */ jcr->res.rstore->NumConcurrentJobs--; /* back out rstore */ Dmsg1(200, "Dec rncj=%d\n", jcr->res.rstore->NumConcurrentJobs); V(rstore_mutex); ASSERT(jcr->res.rstore->NumConcurrentReadJobs >= 0); ASSERT(jcr->res.rstore->NumConcurrentJobs >= 0); } } static void dec_write_store(JCR *jcr) { if (jcr->res.wstore) { jcr->res.wstore->NumConcurrentJobs--; Dmsg1(200, "Dec wncj=%d\n", jcr->res.wstore->NumConcurrentJobs); ASSERT(jcr->res.wstore->NumConcurrentJobs >= 0); } } bareos-Release-14.2.6/src/dird/jobq.h000066400000000000000000000044721263011562700172640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos job queue routines. * * Kern Sibbald, July MMIII * * This code adapted from Bareos work queue code, which was * adapted from "Programming with POSIX Threads", by David R. Butenhof */ #ifndef __JOBQ_H #define __JOBQ_H 1 /* * Structure to keep track of job queue request */ struct jobq_item_t { dlink link; JCR *jcr; }; /* * Structure describing a work queue */ struct jobq_t { pthread_mutex_t mutex; /* queue access control */ pthread_cond_t work; /* wait for work */ pthread_attr_t attr; /* create detached threads */ dlist *waiting_jobs; /* list of jobs waiting */ dlist *running_jobs; /* jobs running */ dlist *ready_jobs; /* jobs ready to run */ int valid; /* queue initialized */ bool quit; /* jobq should quit */ int max_workers; /* max threads */ int num_workers; /* current threads */ int idle_workers; /* idle threads */ void *(*engine)(void *arg); /* user engine */ }; #define JOBQ_VALID 0xdec1993 extern int jobq_init( jobq_t *wq, int threads, /* maximum threads */ void *(*engine)(void *) /* engine routine */ ); extern int jobq_destroy(jobq_t *wq); extern int jobq_add(jobq_t *wq, JCR *jcr); extern int jobq_remove(jobq_t *wq, JCR *jcr); #endif /* __JOBQ_H */ bareos-Release-14.2.6/src/dird/migrate.c000066400000000000000000001676121263011562700177620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- migrate.c -- responsible for doing migration and copy jobs. * * Also handles Copy jobs (March 2008) * * Kern Sibbald, September 2004 * SD-SD Migration by Marco van Wieringen, November 2012 * * Basic tasks done here: * Open DB and create records for this job. * Open Message Channel with Storage daemon to tell him a job will be starting. * Open connection with Storage daemon and pass him commands to do the backup. * When the Storage daemon finishes the job, update the DB. */ #include "bareos.h" #include "dird.h" #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif /* Commands sent to other storage daemon */ static char replicatecmd[] = "replicate Job=%s address=%s port=%d ssl=%d Authorization=%s\n"; static const int dbglevel = 10; static int getJob_to_migrate(JCR *jcr); struct idpkt; static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1, const char *query2, const char *type); static bool find_mediaid_then_jobids(JCR *jcr, idpkt *ids, const char *query1, const char *type); static bool find_jobids_from_mediaid_list(JCR *jcr, idpkt *ids, const char *type); static bool find_jobids_of_pool_uncopied_jobs(JCR *jcr, idpkt *ids); static void start_migration_job(JCR *jcr); static int get_next_dbid_from_list(char **p, DBId_t *DBId); static bool set_migration_next_pool(JCR *jcr, POOLRES **pool); /* * See if two storage definitions point to the same Storage Daemon. * * We compare: * - address * - SDport * - password */ static inline bool is_same_storage_daemon(STORERES *rstore, STORERES *wstore) { return rstore->SDport == wstore->SDport && bstrcasecmp(rstore->address, wstore->address) && bstrcasecmp(rstore->password.value, wstore->password.value); } /* * Called here before the job is run to do the job * specific setup. Note, one of the important things to * complete in this init code is to make the definitive * choice of input and output storage devices. This is * because immediately after the init, the job is queued * in the jobq.c code, and it checks that all the resources * (storage resources in particular) are available, so these * must all be properly defined. * * - previous_jr refers to the job DB record of the Job that is * going to be migrated. * - prev_job refers to the job resource of the Job that is * going to be migrated. * - jcr is the jcr for the current "migration" job. It is a * control job that is put in the DB as a migration job, which * means that this job migrated a previous job to a new job. * No Volume or File data is associated with this control * job. * - mig_jcr refers to the newly migrated job that is run by * the current jcr. It is a backup job that moves (migrates) the * data written for the previous_jr into the new pool. This * job (mig_jcr) becomes the new backup job that replaces * the original backup job. Note, when this is a migration * on a single storage daemon this jcr is not really run. It * is simply attached to the current jcr. It will show up in * the Director's status output, but not in the SD or FD, both of * which deal only with the current migration job (i.e. jcr). * When this is is a migration between two storage daemon this * mig_jcr is used to control the second connection to the * remote storage daemon. */ bool do_migration_init(JCR *jcr) { POOLRES *pool = NULL; JOBRES *job, *prev_job; JCR *mig_jcr; /* newly migrated job */ int count; apply_pool_overrides(jcr); if (!allow_duplicate_job(jcr)) { return false; } jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->res.pool->name()); if (jcr->jr.PoolId == 0) { Dmsg1(dbglevel, "JobId=%d no PoolId\n", (int)jcr->JobId); Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n")); return false; } /* * Note, at this point, pool is the pool for this job. * We transfer it to rpool (read pool), and a bit later, * pool will be changed to point to the write pool, * which comes from pool->NextPool. */ jcr->res.rpool = jcr->res.pool; /* save read pool */ pm_strcpy(jcr->res.rpool_source, jcr->res.pool_source); Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->res.rpool->name(), jcr->res.rpool_source); /* * If we find a job or jobs to migrate it is previous_jr.JobId */ count = getJob_to_migrate(jcr); if (count < 0) { return false; } if (count == 0) { set_migration_next_pool(jcr, &pool); return true; /* no work */ } Dmsg1(dbglevel, "Back from getJob_to_migrate JobId=%d\n", (int)jcr->JobId); if (jcr->previous_jr.JobId == 0) { Dmsg1(dbglevel, "JobId=%d no previous JobId\n", (int)jcr->JobId); Jmsg(jcr, M_INFO, 0, _("No previous Job found to %s.\n"), jcr->get_ActionName()); set_migration_next_pool(jcr, &pool); return true; /* no work */ } if (create_restore_bootstrap_file(jcr) < 0) { Jmsg(jcr, M_FATAL, 0, _("Create bootstrap file failed.\n")); return false; } if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) { jcr->setJobStatus(JS_Terminated); Dmsg1(dbglevel, "JobId=%d expected files == 0\n", (int)jcr->JobId); if (jcr->previous_jr.JobId == 0) { Jmsg(jcr, M_INFO, 0, _("No previous Job found to %s.\n"), jcr->get_ActionName()); } else { Jmsg(jcr, M_INFO, 0, _("Previous Job has no data to %s.\n"), jcr->get_ActionName()); } set_migration_next_pool(jcr, &pool); return true; /* no work */ } Dmsg5(dbglevel, "JobId=%d: Current: Name=%s JobId=%d Type=%c Level=%c\n", (int)jcr->JobId, jcr->jr.Name, (int)jcr->jr.JobId, jcr->jr.JobType, jcr->jr.JobLevel); LockRes(); job = (JOBRES *)GetResWithName(R_JOB, jcr->jr.Name); prev_job = (JOBRES *)GetResWithName(R_JOB, jcr->previous_jr.Name); UnlockRes(); if (!job) { Jmsg(jcr, M_FATAL, 0, _("Job resource not found for \"%s\".\n"), jcr->jr.Name); return false; } if (!prev_job) { Jmsg(jcr, M_FATAL, 0, _("Previous Job resource not found for \"%s\".\n"), jcr->previous_jr.Name); return false; } /* * Copy the actual level setting of the previous Job to this Job. * This overrides the dummy backup level given to the migrate/copy Job and replaces it * with the actual level the backup run at. */ jcr->setJobLevel(prev_job->JobLevel); /* * If the current Job has no explicit client set use the client setting of the previous Job. */ if (!jcr->res.client && prev_job->client) { jcr->res.client = prev_job->client; if (!jcr->client_name) { jcr->client_name = get_pool_memory(PM_NAME); } pm_strcpy(jcr->client_name, jcr->res.client->hdr.name); } /* * If the current Job has no explicit fileset set use the client setting of the previous Job. */ if (!jcr->res.fileset) { jcr->res.fileset = prev_job->fileset; } /* * See if spooling data is not enabled yet. If so turn on spooling if requested in job */ if (!jcr->spool_data) { jcr->spool_data = job->spool_data; } /* * Create a migration jcr */ mig_jcr = jcr->mig_jcr = new_jcr(sizeof(JCR), dird_free_jcr); memcpy(&mig_jcr->previous_jr, &jcr->previous_jr, sizeof(mig_jcr->previous_jr)); /* * Turn the mig_jcr into a "real" job that takes on the aspects of * the previous backup job "prev_job". We only don't want it to * ever send any messages to the database or mail messages when * we are doing a migrate or copy to a remote storage daemon. When * doing such operations the mig_jcr is used for tracking some of * the remote state and it might want to send some captured state * info on tear down of the mig_jcr so we call setup_job with the * suppress_output argument set to true (e.g. don't init messages * and set the jcr suppress_output boolean to true). */ set_jcr_defaults(mig_jcr, prev_job); /* * Don't let WatchDog checks Max*Time value on this Job */ mig_jcr->no_maxtime = true; /* * Don't check for duplicates on migration and copy jobs */ mig_jcr->IgnoreDuplicateJobChecking = true; if (!setup_job(mig_jcr, true)) { Jmsg(jcr, M_FATAL, 0, _("setup job failed.\n")); return false; } /* * Keep track that the mig_jcr has a controling JCR. */ mig_jcr->cjcr = jcr; /* * Now reset the job record from the previous job */ memcpy(&mig_jcr->jr, &jcr->previous_jr, sizeof(mig_jcr->jr)); /* * Update the jr to reflect the new values of PoolId and JobId. */ mig_jcr->jr.PoolId = jcr->jr.PoolId; mig_jcr->jr.JobId = mig_jcr->JobId; Dmsg4(dbglevel, "mig_jcr: Name=%s JobId=%d Type=%c Level=%c\n", mig_jcr->jr.Name, (int)mig_jcr->jr.JobId, mig_jcr->jr.JobType, mig_jcr->jr.JobLevel); if (set_migration_next_pool(jcr, &pool)) { /* * If pool storage specified, use it as source */ copy_rstorage(mig_jcr, pool->storage, _("Pool resource")); copy_rstorage(jcr, pool->storage, _("Pool resource")); mig_jcr->res.pool = jcr->res.pool; mig_jcr->res.next_pool = jcr->res.next_pool; mig_jcr->jr.PoolId = jcr->jr.PoolId; } /* * Get the storage that was used for the original Job. * This only happens when the original pool used doesn't have an explicit storage. */ if (!jcr->rstorage) { copy_rstorage(jcr, prev_job->storage, _("previous Job")); } /* * See if the read and write storage is the same. * When they are we do the migrate/copy over one SD connection * otherwise we open a connection to the reading SD and a second * one to the writing SD. */ jcr->remote_replicate = !is_same_storage_daemon(jcr->res.rstore, jcr->res.wstore); return true; } /* * set_migration_next_pool() called by do_migration_init() * at differents stages. * * The idea here is to make a common subroutine for the * NextPool's search code and to permit do_migration_init() * to return with NextPool set in jcr struct. */ static bool set_migration_next_pool(JCR *jcr, POOLRES **retpool) { POOL_DBR pr; char ed1[100]; POOLRES *pool; const char *storage_source; /* * Get the PoolId used with the original job. Then * find the pool name from the database record. */ memset(&pr, 0, sizeof(pr)); pr.PoolId = jcr->jr.PoolId; if (!db_get_pool_record(jcr, jcr->db, &pr)) { Jmsg(jcr, M_FATAL, 0, _("Pool for JobId %s not in database. ERR=%s\n"), edit_int64(pr.PoolId, ed1), db_strerror(jcr->db)); return false; } /* * Get the pool resource corresponding to the original job */ pool = (POOLRES *)GetResWithName(R_POOL, pr.Name); *retpool = pool; if (!pool) { Jmsg(jcr, M_FATAL, 0, _("Pool resource \"%s\" not found.\n"), pr.Name); return false; } /* * See if there is a next pool override. */ if (jcr->res.run_next_pool_override) { pm_strcpy(jcr->res.npool_source, _("Run NextPool override")); pm_strcpy(jcr->res.pool_source, _("Run NextPool override")); storage_source = _("Storage from Run NextPool override"); } else { /* * See if there is a next pool override in the Job definition. */ if (jcr->res.job->next_pool) { jcr->res.next_pool = jcr->res.job->next_pool; pm_strcpy(jcr->res.npool_source, _("Job's NextPool resource")); pm_strcpy(jcr->res.pool_source, _("Job's NextPool resource")); storage_source = _("Storage from Job's NextPool resource"); } else { /* * Fall back to the pool's NextPool definition. */ jcr->res.next_pool = pool->NextPool; pm_strcpy(jcr->res.npool_source, _("Job Pool's NextPool resource")); pm_strcpy(jcr->res.pool_source, _("Job Pool's NextPool resource")); storage_source = _("Storage from Pool's NextPool resource"); } } /* * If the original backup pool has a NextPool, make sure a * record exists in the database. Note, in this case, we * will be migrating from pool to pool->NextPool. */ if (jcr->res.next_pool) { jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->res.next_pool->name()); if (jcr->jr.PoolId == 0) { return false; } } if (!set_migration_wstorage(jcr, pool, jcr->res.next_pool, storage_source)) { return false; } jcr->res.pool = jcr->res.next_pool; Dmsg2(dbglevel, "Write pool=%s read rpool=%s\n", jcr->res.pool->name(), jcr->res.rpool->name()); return true; } /* * Sanity check that we are not using the same storage for reading and writing. */ static inline bool same_storage(JCR *jcr) { STORERES *read_store, *write_store; read_store = (STORERES *)jcr->rstorage->first(); write_store = (STORERES *)jcr->wstorage->first(); if (!read_store->autochanger && !write_store->autochanger && bstrcmp(read_store->name(), write_store->name())) { return true; } return false; } /* * Do a Migration of a previous job * * Returns: false on failure * true on success */ bool do_migration(JCR *jcr) { char ed1[100]; bool retval = false; JCR *mig_jcr = jcr->mig_jcr; /* newly migrated job */ /* * If mig_jcr is NULL, there is nothing to do for this job, * so set a normal status, cleanup and return OK. */ if (!mig_jcr) { jcr->setJobStatus(JS_Terminated); migration_cleanup(jcr, jcr->JobStatus); return true; } if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) { Jmsg(jcr, M_FATAL, 0, _("Could not get job record for JobId %s to %s. ERR=%s"), edit_int64(jcr->previous_jr.JobId, ed1), jcr->get_ActionName(), db_strerror(jcr->db)); jcr->setJobStatus(JS_Terminated); migration_cleanup(jcr, jcr->JobStatus); return true; } /* * Make sure this job was not already migrated */ if (jcr->previous_jr.JobType != JT_BACKUP && jcr->previous_jr.JobType != JT_JOB_COPY) { Jmsg(jcr, M_INFO, 0, _("JobId %s already %s probably by another Job. %s stopped.\n"), edit_int64(jcr->previous_jr.JobId, ed1), jcr->get_ActionName(true), jcr->get_OperationName()); jcr->setJobStatus(JS_Terminated); migration_cleanup(jcr, jcr->JobStatus); return true; } if (same_storage(jcr)) { Jmsg(jcr, M_FATAL, 0, _("JobId %s cannot %s using the same read and write storage.\n"), edit_int64(jcr->previous_jr.JobId, ed1), jcr->get_OperationName()); jcr->setJobStatus(JS_Terminated); migration_cleanup(jcr, jcr->JobStatus); return true; } /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start %s JobId %s, Job=%s\n"), jcr->get_OperationName(), edit_uint64(jcr->JobId, ed1), jcr->Job); Dmsg2(dbglevel, "Read store=%s, write store=%s\n", ((STORERES *)jcr->rstorage->first())->name(), ((STORERES *)jcr->wstorage->first())->name()); if (!jcr->remote_replicate) { /* * Open a message channel connection with the Storage daemon. */ Dmsg0(110, "Open connection with storage daemon\n"); jcr->setJobStatus(JS_WaitSD); mig_jcr->setJobStatus(JS_WaitSD); /* * Start conversation with Storage daemon */ if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { return false; } /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /* send_bsr */ true)) { return false; } Dmsg0(150, "Storage daemon connection OK\n"); } else { alist *wstorage; /* * See if we need to apply any bandwidth limiting. * We search the bandwidth limiting in the following way: * - Job bandwith limiting * - Writing Storage Daemon bandwidth limiting * - Reading Storage Daemon bandwidth limiting */ if (jcr->res.job->max_bandwidth > 0) { jcr->max_bandwidth = jcr->res.job->max_bandwidth; } else if (jcr->res.wstore->max_bandwidth > 0) { jcr->max_bandwidth = jcr->res.wstore->max_bandwidth; } else if (jcr->res.rstore->max_bandwidth > 0) { jcr->max_bandwidth = jcr->res.rstore->max_bandwidth; } /* * Open a message channel connection with the Reading Storage daemon. */ Dmsg0(110, "Open connection with reading storage daemon\n"); /* * Clear the wstore of the jcr and assign it to the mig_jcr so * the jcr is connected to the reading storage daemon and the * mig_jcr to the writing storage daemon. */ mig_jcr->res.wstore = jcr->res.wstore; jcr->res.wstore = NULL; /* * Swap the wstorage between the jcr and the mig_jcr. */ wstorage = mig_jcr->wstorage; mig_jcr->wstorage = jcr->wstorage; jcr->wstorage = wstorage; /* * Start conversation with Reading Storage daemon */ jcr->setJobStatus(JS_WaitSD); if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { goto bail_out; } /* * Open a message channel connection with the Writing Storage daemon. */ Dmsg0(110, "Open connection with writing storage daemon\n"); /* * Start conversation with Writing Storage daemon */ mig_jcr->setJobStatus(JS_WaitSD); if (!connect_to_storage_daemon(mig_jcr, 10, me->SDConnectTimeout, true)) { goto bail_out; } /* * Now start a job with the Reading Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL, /* send_bsr */ true)) { goto bail_out; } Dmsg0(150, "Reading Storage daemon connection OK\n"); /* * Now start a job with the Writing Storage daemon */ if (!start_storage_daemon_job(mig_jcr, NULL, mig_jcr->wstorage, /* send_bsr */ false)) { goto bail_out; } Dmsg0(150, "Writing Storage daemon connection OK\n"); } /* * We re-update the job start record so that the start * time is set after the run before job. This avoids * that any files created by the run before job will * be saved twice. They will be backed up in the current * job, but not in the next one unless they are changed. * Without this, they will be backed up in this job and * in the next job run because in that case, their date * is after the start of this run. */ jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; jcr->jr.JobTDate = jcr->start_time; jcr->setJobStatus(JS_Running); /* * Update job start record for this migration control job */ if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); goto bail_out; } /* * Declare the job started to start the MaxRunTime check */ jcr->setJobStarted(); mig_jcr->start_time = time(NULL); mig_jcr->jr.StartTime = mig_jcr->start_time; mig_jcr->jr.JobTDate = mig_jcr->start_time; mig_jcr->setJobStatus(JS_Running); /* * Update job start record for the real migration backup job */ if (!db_update_job_start_record(mig_jcr, mig_jcr->db, &mig_jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(mig_jcr->db)); goto bail_out; } Dmsg4(dbglevel, "mig_jcr: Name=%s JobId=%d Type=%c Level=%c\n", mig_jcr->jr.Name, (int)mig_jcr->jr.JobId, mig_jcr->jr.JobType, mig_jcr->jr.JobLevel); /* * If we are connected to two different SDs tell the writing one * to be ready to receive the data and tell the reading one * to replicate to the other. */ if (jcr->remote_replicate) { STORERES *store; POOL_MEM command(PM_MESSAGE); int tls_need = BNET_TLS_NONE; if (jcr->max_bandwidth > 0) { send_bwlimit_to_sd(jcr, jcr->Job); } /* * Start the job prior to starting the message thread below * to avoid two threads from using the BSOCK structure at * the same time. */ if (!mig_jcr->store_bsock->fsend("listen")) { goto bail_out; } if (!start_storage_daemon_message_thread(mig_jcr)) { goto bail_out; } /* * Send Storage daemon address to the other Storage daemon */ store = mig_jcr->res.wstore; if (store->SDDport == 0) { store->SDDport = store->SDport; } /* * TLS Requirement */ if (store->tls_enable) { if (store->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } Mmsg(command, replicatecmd, mig_jcr->Job, store->address, store->SDDport, tls_need, mig_jcr->sd_auth_key); if (!jcr->store_bsock->fsend(command.c_str())) { return false; } } /* * Start the job prior to starting the message thread below * to avoid two threads from using the BSOCK structure at * the same time. */ if (!jcr->store_bsock->fsend("run")) { goto bail_out; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { goto bail_out; } jcr->setJobStatus(JS_Running); mig_jcr->setJobStatus(JS_Running); /* * Pickup Job termination data * Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors or * mig_jcr->JobFiles/ReadBytes/JobBytes/JobErrors when replicating to * a remote storage daemon. */ if (jcr->remote_replicate) { wait_for_storage_daemon_termination(jcr); wait_for_storage_daemon_termination(mig_jcr); jcr->setJobStatus(jcr->SDJobStatus); db_write_batch_file_records(mig_jcr); } else { wait_for_storage_daemon_termination(jcr); jcr->setJobStatus(jcr->SDJobStatus); db_write_batch_file_records(jcr); } bail_out: if (jcr->remote_replicate) { alist *wstorage; /* * Swap the wstorage between the jcr and the mig_jcr. */ wstorage = mig_jcr->wstorage; mig_jcr->wstorage = jcr->wstorage; jcr->wstorage = wstorage; /* * Undo the clear of the wstore in the jcr and assign the mig_jcr wstore * back to the jcr. This is an undo of the clearing we did earlier * as we want the jcr connected to the reading storage daemon and the * mig_jcr to the writing jcr. By clearing the wstore of the jcr the * connect_to_storage_daemon function will do the right thing e.g. connect * the jcrs in the way we want them to. */ jcr->res.wstore = mig_jcr->res.wstore; mig_jcr->res.wstore = NULL; } if (jcr->is_JobStatus(JS_Terminated)) { migration_cleanup(jcr, jcr->JobStatus); retval = true; } return retval; } struct idpkt { POOLMEM *list; uint32_t count; }; /* * Add an item to the list if it is unique */ static void add_unique_id(idpkt *ids, char *item) { const int maxlen = 30; char id[maxlen+1]; char *q = ids->list; /* * Walk through current list to see if each item is the same as item */ while (*q) { id[0] = 0; for (int i=0; icount == 0) { ids->list[0] = 0; } else { pm_strcat(ids->list, ","); } pm_strcat(ids->list, item); ids->count++; // Dmsg3(0, "add_uniq count=%d Ids=%p %s\n", ids->count, ids->list, ids->list); return; } /* * Callback handler make list of DB Ids */ static int unique_dbid_handler(void *ctx, int num_fields, char **row) { idpkt *ids = (idpkt *)ctx; /* * Sanity check */ if (!row || !row[0]) { Dmsg0(dbglevel, "dbid_hdlr error empty row\n"); return 1; /* stop calling us */ } add_unique_id(ids, row[0]); Dmsg3(dbglevel, "dbid_hdlr count=%d Ids=%p %s\n", ids->count, ids->list, ids->list); return 0; } struct uitem { dlink link; char *item; }; static int item_compare(void *item1, void *item2) { uitem *i1 = (uitem *)item1; uitem *i2 = (uitem *)item2; return strcmp(i1->item, i2->item); } static int unique_name_handler(void *ctx, int num_fields, char **row) { dlist *list = (dlist *)ctx; uitem *new_item = (uitem *)malloc(sizeof(uitem)); uitem *item; memset(new_item, 0, sizeof(uitem)); new_item->item = bstrdup(row[0]); Dmsg1(dbglevel, "Unique_name_hdlr Item=%s\n", row[0]); item = (uitem *)list->binary_insert((void *)new_item, item_compare); if (item != new_item) { /* already in list */ free(new_item->item); free((char *)new_item); return 0; } return 0; } /* Get Job names in Pool */ static const char *sql_job = "SELECT DISTINCT Job.Name from Job,Pool" " WHERE Pool.Name='%s' AND Job.PoolId=Pool.PoolId"; /* Get JobIds from regex'ed Job names */ static const char *sql_jobids_from_job = "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool" " WHERE Job.Name='%s' AND Pool.Name='%s' AND Job.PoolId=Pool.PoolId" " ORDER by Job.StartTime"; /* Get Client names in Pool */ static const char *sql_client = "SELECT DISTINCT Client.Name from Client,Pool,Job" " WHERE Pool.Name='%s' AND Job.ClientId=Client.ClientId AND" " Job.PoolId=Pool.PoolId"; /* Get JobIds from regex'ed Client names */ static const char *sql_jobids_from_client = "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool,Client" " WHERE Client.Name='%s' AND Pool.Name='%s' AND Job.PoolId=Pool.PoolId" " AND Job.ClientId=Client.ClientId AND Job.Type IN ('B','C')" " AND Job.JobStatus IN ('T','W')" " ORDER by Job.StartTime"; /* Get Volume names in Pool */ static const char *sql_vol = "SELECT DISTINCT VolumeName FROM Media,Pool WHERE" " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND" " Media.PoolId=Pool.PoolId AND Pool.Name='%s'"; /* Get JobIds from regex'ed Volume names */ static const char *sql_jobids_from_vol = "SELECT DISTINCT Job.JobId,Job.StartTime FROM Media,JobMedia,Job" " WHERE Media.VolumeName='%s' AND Media.MediaId=JobMedia.MediaId" " AND JobMedia.JobId=Job.JobId AND Job.Type IN ('B','C')" " AND Job.JobStatus IN ('T','W') AND Media.Enabled=1" " ORDER by Job.StartTime"; static const char *sql_smallest_vol = "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE" " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND" " Media.VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND" " Media.PoolId=Pool.PoolId AND Pool.Name='%s'" " ORDER BY VolBytes ASC LIMIT 1"; static const char *sql_oldest_vol = "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE" " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND" " Media.VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND" " Media.PoolId=Pool.PoolId AND Pool.Name='%s'" " ORDER BY LastWritten ASC LIMIT 1"; /* Get JobIds when we have selected MediaId */ static const char *sql_jobids_from_mediaid = "SELECT DISTINCT Job.JobId,Job.StartTime FROM JobMedia,Job" " WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId IN (%s)" " AND Job.Type IN ('B','C') AND Job.JobStatus IN ('T','W')" " ORDER by Job.StartTime"; /* Get the number of bytes in the pool */ static const char *sql_pool_bytes = "SELECT SUM(JobBytes) FROM Job WHERE JobId IN" " (SELECT DISTINCT Job.JobId from Pool,Job,Media,JobMedia WHERE" " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND" " VolStatus in ('Full','Used','Error','Append') AND Media.Enabled=1 AND" " Job.Type IN ('B','C') AND Job.JobStatus IN ('T','W') AND" " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId)"; /* Get the number of bytes in the Jobs */ static const char *sql_job_bytes = "SELECT SUM(JobBytes) FROM Job WHERE JobId IN (%s)"; /* Get Media Ids in Pool */ static const char *sql_mediaids = "SELECT MediaId FROM Media,Pool WHERE" " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND" " Media.PoolId=Pool.PoolId AND Pool.Name='%s' ORDER BY LastWritten ASC"; /* Get JobIds in Pool longer than specified time */ static const char *sql_pool_time = "SELECT DISTINCT Job.JobId FROM Pool,Job,Media,JobMedia WHERE" " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND" " VolStatus IN ('Full','Used','Error') AND Media.Enabled=1 AND" " Job.Type IN ('B','C') AND Job.JobStatus IN ('T','W') AND" " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId" " AND Job.RealEndTime<='%s'"; /* Get JobIds from successfully completed backup jobs which have not been copied before */ static const char *sql_jobids_of_pool_uncopied_jobs = "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool" " WHERE Pool.Name = '%s' AND Pool.PoolId = Job.PoolId" " AND Job.Type = 'B' AND Job.JobStatus IN ('T','W')" " AND Job.jobBytes > 0" " AND Job.JobId NOT IN" " (SELECT PriorJobId FROM Job WHERE" " Type IN ('B','C') AND Job.JobStatus IN ('T','W')" " AND PriorJobId != 0)" " ORDER by Job.StartTime"; /* * const char *sql_ujobid = * "SELECT DISTINCT Job.Job from Client,Pool,Media,Job,JobMedia " * " WHERE Media.PoolId=Pool.PoolId AND Pool.Name='%s' AND" * " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId"; */ /* * * This is the central piece of code that finds a job or jobs * actually JobIds to migrate. It first looks to see if one * has been "manually" specified in jcr->MigrateJobId, and if * so, it returns that JobId to be run. Otherwise, it * examines the Selection Type to see what kind of migration * we are doing (Volume, Job, Client, ...) and applies any * Selection Pattern if appropriate to obtain a list of JobIds. * Finally, it will loop over all the JobIds found, except the last * one starting a new job with MigrationJobId set to that JobId, and * finally, it returns the last JobId to the caller. * * Returns: -1 on error * 0 if no jobs to migrate * 1 if OK and jcr->previous_jr filled in */ static int getJob_to_migrate(JCR *jcr) { char ed1[30], ed2[30]; POOL_MEM query(PM_MESSAGE); JobId_t JobId; DBId_t DBId = 0; int status; char *p; idpkt ids, mid, jids; db_int64_ctx ctx; int64_t pool_bytes; time_t ttime; struct tm tm; char dt[MAX_TIME_LENGTH]; int count = 0; int limit = 99; /* limit + 1 is max jobs to start */ ids.list = get_pool_memory(PM_MESSAGE); ids.list[0] = 0; ids.count = 0; mid.list = get_pool_memory(PM_MESSAGE); mid.list[0] = 0; mid.count = 0; jids.list = get_pool_memory(PM_MESSAGE); jids.list[0] = 0; jids.count = 0; /* * If MigrateJobId is set, then we migrate only that Job, * otherwise, we go through the full selection of jobs to * migrate. */ if (jcr->MigrateJobId != 0) { Dmsg1(dbglevel, "At Job start previous jobid=%u\n", jcr->MigrateJobId); JobId = jcr->MigrateJobId; } else { switch (jcr->res.job->selection_type) { case MT_JOB: if (!regex_find_jobids(jcr, &ids, sql_job, sql_jobids_from_job, "Job")) { goto bail_out; } break; case MT_CLIENT: if (!regex_find_jobids(jcr, &ids, sql_client, sql_jobids_from_client, "Client")) { goto bail_out; } break; case MT_VOLUME: if (!regex_find_jobids(jcr, &ids, sql_vol, sql_jobids_from_vol, "Volume")) { goto bail_out; } break; case MT_SQLQUERY: if (!jcr->res.job->selection_pattern) { Jmsg(jcr, M_FATAL, 0, _("No %s SQL selection pattern specified.\n"), jcr->get_OperationName()); goto bail_out; } Dmsg1(dbglevel, "SQL=%s\n", jcr->res.job->selection_pattern); if (!db_sql_query(jcr->db, jcr->res.job->selection_pattern, unique_dbid_handler, (void *)&ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } break; case MT_SMALLEST_VOL: if (!find_mediaid_then_jobids(jcr, &ids, sql_smallest_vol, "Smallest Volume")) { goto bail_out; } break; case MT_OLDEST_VOL: if (!find_mediaid_then_jobids(jcr, &ids, sql_oldest_vol, "Oldest Volume")) { goto bail_out; } break; case MT_POOL_OCCUPANCY: ctx.count = 0; /* Find count of bytes in pool */ Mmsg(query, sql_pool_bytes, jcr->res.rpool->name()); if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } if (ctx.count == 0) { Jmsg(jcr, M_INFO, 0, _("No Volumes found to %s.\n"), jcr->get_ActionName()); goto ok_out; } pool_bytes = ctx.value; Dmsg2(dbglevel, "highbytes=%lld pool=%lld\n", jcr->res.rpool->MigrationHighBytes, pool_bytes); if (pool_bytes < (int64_t)jcr->res.rpool->MigrationHighBytes) { Jmsg(jcr, M_INFO, 0, _("No Volumes found to %s.\n"), jcr->get_ActionName()); goto ok_out; } Dmsg0(dbglevel, "We should do Occupation migration.\n"); ids.count = 0; /* Find a list of MediaIds that could be migrated */ Mmsg(query, sql_mediaids, jcr->res.rpool->name()); Dmsg1(dbglevel, "query=%s\n", query.c_str()); if (!db_sql_query(jcr->db, query.c_str(), unique_dbid_handler, (void *)&ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } if (ids.count == 0) { Jmsg(jcr, M_INFO, 0, _("No Volumes found to %s.\n"), jcr->get_ActionName()); goto ok_out; } Dmsg2(dbglevel, "Pool Occupancy ids=%d MediaIds=%s\n", ids.count, ids.list); if (!find_jobids_from_mediaid_list(jcr, &ids, "Volume")) { goto bail_out; } /* ids == list of jobs */ p = ids.list; for (int i = 0; i < (int)ids.count; i++) { status = get_next_dbid_from_list(&p, &DBId); Dmsg2(dbglevel, "get_next_dbid status=%d JobId=%u\n", status, (uint32_t)DBId); if (status < 0) { Jmsg(jcr, M_FATAL, 0, _("Invalid JobId found.\n")); goto bail_out; } else if (status == 0) { break; } mid.count = 1; Mmsg(mid.list, "%s", edit_int64(DBId, ed1)); if (jids.count > 0) { pm_strcat(jids.list, ","); } pm_strcat(jids.list, mid.list); jids.count += mid.count; /* Find count of bytes from Jobs */ Mmsg(query, sql_job_bytes, mid.list); Dmsg1(dbglevel, "Jobbytes query: %s\n", query.c_str()); if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } pool_bytes -= ctx.value; Dmsg2(dbglevel, "Total %s Job bytes=%s\n", jcr->get_ActionName(), edit_int64_with_commas(ctx.value, ed1)); Dmsg2(dbglevel, "lowbytes=%s poolafter=%s\n", edit_int64_with_commas(jcr->res.rpool->MigrationLowBytes, ed1), edit_int64_with_commas(pool_bytes, ed2)); if (pool_bytes <= (int64_t)jcr->res.rpool->MigrationLowBytes) { Dmsg0(dbglevel, "We should be done.\n"); break; } } /* Transfer jids to ids, where the jobs list is expected */ ids.count = jids.count; pm_strcpy(ids.list, jids.list); Dmsg2(dbglevel, "Pool Occupancy ids=%d JobIds=%s\n", ids.count, ids.list); break; case MT_POOL_TIME: ttime = time(NULL) - (time_t)jcr->res.rpool->MigrationTime; (void)localtime_r(&ttime, &tm); strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm); ids.count = 0; Mmsg(query, sql_pool_time, jcr->res.rpool->name(), dt); Dmsg1(dbglevel, "query=%s\n", query.c_str()); if (!db_sql_query(jcr->db, query.c_str(), unique_dbid_handler, (void *)&ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } if (ids.count == 0) { Jmsg(jcr, M_INFO, 0, _("No Volumes found to %s.\n"), jcr->get_ActionName()); goto ok_out; } Dmsg2(dbglevel, "PoolTime ids=%d JobIds=%s\n", ids.count, ids.list); break; case MT_POOL_UNCOPIED_JOBS: if (!find_jobids_of_pool_uncopied_jobs(jcr, &ids)) { goto bail_out; } break; default: Jmsg(jcr, M_FATAL, 0, _("Unknown %s Selection Type.\n"), jcr->get_OperationName()); goto bail_out; } /* * Loop over all jobids except the last one, sending * them to start_migration_job(), which will start a job * for each of them. For the last JobId, we handle it below. */ p = ids.list; if (ids.count == 0) { Jmsg(jcr, M_INFO, 0, _("No JobIds found to %s.\n"), jcr->get_ActionName()); goto ok_out; } Jmsg(jcr, M_INFO, 0, _("The following %u JobId%s chosen to be %s: %s\n"), ids.count, (ids.count < 2) ? _(" was") : _("s were"), jcr->get_ActionName(true), ids.list); Dmsg2(dbglevel, "Before loop count=%d ids=%s\n", ids.count, ids.list); /* * Note: to not over load the system, limit the number * of new jobs started to 100 (see limit above) */ for (int i = 1; i < (int)ids.count; i++) { JobId = 0; status = get_next_jobid_from_list(&p, &JobId); Dmsg3(dbglevel, "getJobid_no=%d status=%d JobId=%u\n", i, status, JobId); if (status < 0) { Jmsg(jcr, M_FATAL, 0, _("Invalid JobId found.\n")); goto bail_out; } else if (status == 0) { Jmsg(jcr, M_INFO, 0, _("No JobIds found to %s.\n"), jcr->get_ActionName()); goto ok_out; } jcr->MigrateJobId = JobId; /* Don't start any more when limit reaches zero */ limit--; if (limit > 0) { start_migration_job(jcr); Dmsg0(dbglevel, "Back from start_migration_job\n"); } } /* Now get the last JobId and handle it in the current job */ JobId = 0; status = get_next_jobid_from_list(&p, &JobId); Dmsg2(dbglevel, "Last get_next_jobid status=%d JobId=%u\n", status, (int)JobId); if (status < 0) { Jmsg(jcr, M_FATAL, 0, _("Invalid JobId found.\n")); goto bail_out; } else if (status == 0) { Jmsg(jcr, M_INFO, 0, _("No JobIds found to %s.\n"), jcr->get_ActionName()); goto ok_out; } } jcr->previous_jr.JobId = JobId; Dmsg1(dbglevel, "Previous jobid=%d\n", (int)jcr->previous_jr.JobId); if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) { Jmsg(jcr, M_FATAL, 0, _("Could not get job record for JobId %s to %s. ERR=%s"), edit_int64(jcr->previous_jr.JobId, ed1), jcr->get_ActionName(), db_strerror(jcr->db)); goto bail_out; } Jmsg(jcr, M_INFO, 0, _("%s using JobId=%s Job=%s\n"), jcr->get_OperationName(), edit_int64(jcr->previous_jr.JobId, ed1), jcr->previous_jr.Job); Dmsg4(dbglevel, "%s JobId=%d using JobId=%s Job=%s\n", jcr->get_OperationName(), jcr->JobId, edit_int64(jcr->previous_jr.JobId, ed1), jcr->previous_jr.Job); count = 1; ok_out: goto out; bail_out: count = -1; out: free_pool_memory(ids.list); free_pool_memory(mid.list); free_pool_memory(jids.list); return count; } static void start_migration_job(JCR *jcr) { char ed1[50]; JobId_t jobid; UAContext *ua; POOL_MEM cmd(PM_MESSAGE); ua = new_ua_context(jcr); ua->batch = true; Mmsg(ua->cmd, "run job=\"%s\" jobid=%s ignoreduplicatecheck=yes", jcr->res.job->name(), edit_uint64(jcr->MigrateJobId, ed1)); /* * Make sure we have something to compare against. */ if (jcr->res.pool) { /* * See if there was actually a pool override. */ if (jcr->res.pool != jcr->res.job->pool) { Mmsg(cmd, " pool=\"%s\"", jcr->res.pool->name()); pm_strcat(ua->cmd, cmd.c_str()); } /* * See if there was actually a next pool override. */ if (jcr->res.next_pool && jcr->res.next_pool != jcr->res.pool->NextPool) { Mmsg(cmd, " nextpool=\"%s\"", jcr->res.next_pool->name()); pm_strcat(ua->cmd, cmd.c_str()); } } Dmsg2(dbglevel, "=============== %s cmd=%s\n", jcr->get_OperationName(), ua->cmd); parse_ua_args(ua); /* parse command */ jobid = run_cmd(ua, ua->cmd); if (jobid == 0) { Jmsg(jcr, M_ERROR, 0, _("Could not start migration job.\n")); } else { Jmsg(jcr, M_INFO, 0, _("%s JobId %d started.\n"), jcr->get_OperationName(), (int)jobid); } free_ua_context(ua); } static bool find_mediaid_then_jobids(JCR *jcr, idpkt *ids, const char *query1, const char *type) { bool ok = false; POOL_MEM query(PM_MESSAGE); ids->count = 0; /* Basic query for MediaId */ Mmsg(query, query1, jcr->res.rpool->name()); if (!db_sql_query(jcr->db, query.c_str(), unique_dbid_handler, (void *)ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } if (ids->count == 0) { Jmsg(jcr, M_INFO, 0, _("No %s found to %s.\n"), type, jcr->get_ActionName()); ok = true; /* Not an error */ goto bail_out; } else if (ids->count != 1) { Jmsg(jcr, M_FATAL, 0, _("SQL error. Expected 1 MediaId got %d\n"), ids->count); goto bail_out; } Dmsg2(dbglevel, "%s MediaIds=%s\n", type, ids->list); ok = find_jobids_from_mediaid_list(jcr, ids, type); bail_out: return ok; } /* * This routine returns: * false if an error occurred * true otherwise * ids.count number of jobids found (may be zero) */ static bool find_jobids_from_mediaid_list(JCR *jcr, idpkt *ids, const char *type) { bool ok = false; POOL_MEM query(PM_MESSAGE); Mmsg(query, sql_jobids_from_mediaid, ids->list); ids->count = 0; if (!db_sql_query(jcr->db, query.c_str(), unique_dbid_handler, (void *)ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } if (ids->count == 0) { Jmsg(jcr, M_INFO, 0, _("No %ss found to %s.\n"), type, jcr->get_ActionName()); } ok = true; bail_out: return ok; } /* * This routine returns: * false if an error occurred * true otherwise * ids.count number of jobids found (may be zero) */ static bool find_jobids_of_pool_uncopied_jobs(JCR *jcr, idpkt *ids) { bool ok = false; POOL_MEM query(PM_MESSAGE); /* * Only a copy job is allowed */ if (!jcr->is_JobType(JT_COPY)) { Jmsg(jcr, M_FATAL, 0, _("Selection Type 'pooluncopiedjobs' only applies to Copy Jobs")); goto bail_out; } Dmsg1(dbglevel, "copy selection pattern=%s\n", jcr->res.rpool->name()); Mmsg(query, sql_jobids_of_pool_uncopied_jobs, jcr->res.rpool->name()); Dmsg1(dbglevel, "get uncopied jobs query=%s\n", query.c_str()); if (!db_sql_query(jcr->db, query.c_str(), unique_dbid_handler, (void *)ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL to get uncopied jobs failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } ok = true; bail_out: return ok; } static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1, const char *query2, const char *type) { dlist *item_chain; uitem *item = NULL; uitem *last_item = NULL; regex_t preg; char prbuf[500]; int rc; bool ok = false; POOL_MEM query(PM_MESSAGE); item_chain = New(dlist(item, &item->link)); if (!jcr->res.job->selection_pattern) { Jmsg(jcr, M_FATAL, 0, _("No %s %s selection pattern specified.\n"), jcr->get_OperationName(), type); goto bail_out; } Dmsg1(dbglevel, "regex-sel-pattern=%s\n", jcr->res.job->selection_pattern); /* Basic query for names */ Mmsg(query, query1, jcr->res.rpool->name()); Dmsg1(dbglevel, "get name query1=%s\n", query.c_str()); if (!db_sql_query(jcr->db, query.c_str(), unique_name_handler, (void *)item_chain)) { Jmsg(jcr, M_FATAL, 0, _("SQL to get %s failed. ERR=%s\n"), type, db_strerror(jcr->db)); goto bail_out; } Dmsg1(dbglevel, "query1 returned %d names\n", item_chain->size()); if (item_chain->size() == 0) { Jmsg(jcr, M_INFO, 0, _("Query of Pool \"%s\" returned no Jobs to %s.\n"), jcr->res.rpool->name(), jcr->get_ActionName()); ok = true; goto bail_out; /* skip regex match */ } else { /* Compile regex expression */ rc = regcomp(&preg, jcr->res.job->selection_pattern, REG_EXTENDED); if (rc != 0) { regerror(rc, &preg, prbuf, sizeof(prbuf)); Jmsg(jcr, M_FATAL, 0, _("Could not compile regex pattern \"%s\" ERR=%s\n"), jcr->res.job->selection_pattern, prbuf); goto bail_out; } /* Now apply the regex to the names and remove any item not matched */ foreach_dlist(item, item_chain) { if (last_item) { Dmsg1(dbglevel, "Remove item %s\n", last_item->item); free(last_item->item); item_chain->remove(last_item); } Dmsg1(dbglevel, "get name Item=%s\n", item->item); rc = regexec(&preg, item->item, 0, NULL, 0); if (rc == 0) { last_item = NULL; /* keep this one */ } else { last_item = item; } } if (last_item) { free(last_item->item); Dmsg1(dbglevel, "Remove item %s\n", last_item->item); item_chain->remove(last_item); } regfree(&preg); } if (item_chain->size() == 0) { Jmsg(jcr, M_INFO, 0, _("Regex pattern matched no Jobs to %s.\n"), jcr->get_ActionName()); ok = true; goto bail_out; /* skip regex match */ } /* * At this point, we have a list of items in item_chain * that have been matched by the regex, so now we need * to look up their jobids. */ ids->count = 0; foreach_dlist(item, item_chain) { Dmsg2(dbglevel, "Got %s: %s\n", type, item->item); Mmsg(query, query2, item->item, jcr->res.rpool->name()); Dmsg1(dbglevel, "get id from name query2=%s\n", query.c_str()); if (!db_sql_query(jcr->db, query.c_str(), unique_dbid_handler, (void *)ids)) { Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } } if (ids->count == 0) { Jmsg(jcr, M_INFO, 0, _("No %ss found to %s.\n"), type, jcr->get_ActionName()); } ok = true; bail_out: Dmsg2(dbglevel, "Count=%d Jobids=%s\n", ids->count, ids->list); foreach_dlist(item, item_chain) { free(item->item); } delete item_chain; return ok; } /* * Release resources allocated during backup. */ void migration_cleanup(JCR *jcr, int TermCode) { char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH]; char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], elapsed[50]; char ec6[50], ec7[50], ec8[50]; char term_code[100], sd_term_msg[100]; const char *term_msg; int msg_type = M_INFO; MEDIA_DBR mr; double kbps; utime_t RunTime; JCR *mig_jcr = jcr->mig_jcr; POOL_MEM query(PM_MESSAGE); memset(&mr, 0, sizeof(mr)); Dmsg2(100, "Enter migrate_cleanup %d %c\n", TermCode, TermCode); update_job_end(jcr, TermCode); /* * Check if we actually did something. * mig_jcr is jcr of the newly migrated job. */ if (mig_jcr) { char old_jobid[50], new_jobid[50]; edit_uint64(jcr->previous_jr.JobId, old_jobid); edit_uint64(mig_jcr->jr.JobId, new_jobid); /* * See if we used a remote SD if so the mig_jcr contains * the jobfiles and jobbytes and the new volsessionid * and volsessiontime as the writing SD generates this info. */ if (jcr->remote_replicate) { mig_jcr->JobFiles = jcr->JobFiles = mig_jcr->SDJobFiles; mig_jcr->JobBytes = jcr->JobBytes = mig_jcr->SDJobBytes; } else { mig_jcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles; mig_jcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes; mig_jcr->VolSessionId = jcr->VolSessionId; mig_jcr->VolSessionTime = jcr->VolSessionTime; } mig_jcr->jr.RealEndTime = 0; mig_jcr->jr.PriorJobId = jcr->previous_jr.JobId; if (jcr->is_JobStatus(JS_Terminated) && (jcr->JobErrors || jcr->SDErrors)) { TermCode = JS_Warnings; } update_job_end(mig_jcr, TermCode); /* * Update final items to set them to the previous job's values */ Mmsg(query, "UPDATE Job SET StartTime='%s',EndTime='%s'," "JobTDate=%s WHERE JobId=%s", jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime, edit_uint64(jcr->previous_jr.JobTDate, ec1), new_jobid); db_sql_query(mig_jcr->db, query.c_str()); /* * If we terminated a migration normally: * - mark the previous job as migrated * - move any Log records to the new JobId * - Purge the File records from the previous job */ if (jcr->is_JobType(JT_MIGRATE) && jcr->is_terminated_ok()) { UAContext *ua; Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", (char)JT_MIGRATED_JOB, old_jobid); db_sql_query(mig_jcr->db, query.c_str()); /* * Move JobLog to new JobId */ ua = new_ua_context(jcr); Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s", new_jobid, old_jobid); db_sql_query(mig_jcr->db, query.c_str()); if (jcr->res.job->PurgeMigrateJob) { /* * Purge old Job record */ purge_jobs_from_catalog(ua, old_jobid); } else { /* * Purge all old file records, but leave Job record */ purge_files_from_jobs(ua, old_jobid); } free_ua_context(ua); } /* * If we terminated a Copy (rather than a Migration) normally: * - copy any Log records to the new JobId * - set type="Job Copy" for the new job */ if (jcr->is_JobType(JT_COPY) && jcr->is_terminated_ok()) { /* * Copy JobLog to new JobId */ Mmsg(query, "INSERT INTO Log (JobId, Time, LogText ) " "SELECT %s, Time, LogText FROM Log WHERE JobId=%s", new_jobid, old_jobid); db_sql_query(mig_jcr->db, query.c_str()); Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", (char)JT_JOB_COPY, new_jobid); db_sql_query(mig_jcr->db, query.c_str()); } if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"), db_strerror(jcr->db)); jcr->setJobStatus(JS_ErrorTerminated); } update_bootstrap_file(mig_jcr); if (!db_get_job_volume_names(mig_jcr, mig_jcr->db, mig_jcr->jr.JobId, &mig_jcr->VolumeName)) { /* * Note, if the job has failed, most likely it did not write any * tape, so suppress this "error" message since in that case * it is normal. Or look at it the other way, only for a * normal exit should we complain about this error. */ if (jcr->is_terminated_ok() && jcr->jr.JobBytes) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(mig_jcr->db)); } mig_jcr->VolumeName[0] = 0; /* none */ } if (mig_jcr->VolumeName[0]) { /* * Find last volume name. Multiple vols are separated by | */ char *p = strrchr(mig_jcr->VolumeName, '|'); if (p) { p++; /* skip | */ } else { p = mig_jcr->VolumeName; /* no |, take full name */ } bstrncpy(mr.VolumeName, p, sizeof(mr.VolumeName)); if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Media record for Volume \"%s\": ERR=%s"), mr.VolumeName, db_strerror(jcr->db)); } } switch (jcr->JobStatus) { case JS_Terminated: term_msg = _("%s OK"); break; case JS_Warnings: term_msg = _("%s OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: case JS_Canceled: /* * We catch any error here as the close of the SD sessions is mandatory for each * failure path. The termination message and the message type can be different * so that is why we do a second switch inside the switch on the JobStatus. */ switch (jcr->JobStatus) { case JS_Canceled: term_msg = _("%s Canceled"); break; default: term_msg = _("*** %s Error ***"); msg_type = M_ERROR; /* Generate error message */ break; } /* * Close connection to Reading SD. */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } /* * Close connection to Writing SD (if SD-SD replication) */ if (mig_jcr->store_bsock) { mig_jcr->store_bsock->signal(BNET_TERMINATE); if (mig_jcr->SD_msg_chan_started) { pthread_cancel(mig_jcr->SD_msg_chan); } } break; default: term_msg = _("Inappropriate %s term code"); break; } } else { if (jcr->is_JobType(JT_MIGRATE) && jcr->previous_jr.JobId != 0 && jcr->is_terminated_ok()) { /* * Mark previous job as migrated */ Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1)); db_sql_query(jcr->db, query.c_str()); } term_msg = _("%s -- no files to %s"); } bsnprintf(term_code, sizeof(term_code), term_msg, jcr->get_OperationName(), jcr->get_ActionName()); bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime); bstrftimes(edt, sizeof(edt), jcr->jr.EndTime); RunTime = jcr->jr.EndTime - jcr->jr.StartTime; if (RunTime <= 0) { kbps = 0; } else { kbps = (double)jcr->SDJobBytes / (1000 * RunTime); } jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg)); Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n" " Build OS: %s %s %s\n" " Prev Backup JobId: %s\n" " Prev Backup Job: %s\n" " New Backup JobId: %s\n" " Current JobId: %s\n" " Current Job: %s\n" " Backup Level: %s\n" " Client: %s\n" " FileSet: \"%s\"\n" " Read Pool: \"%s\" (From %s)\n" " Read Storage: \"%s\" (From %s)\n" " Write Pool: \"%s\" (From %s)\n" " Write Storage: \"%s\" (From %s)\n" " Next Pool: \"%s\" (From %s)\n" " Catalog: \"%s\" (From %s)\n" " Start time: %s\n" " End time: %s\n" " Elapsed time: %s\n" " Priority: %d\n" " SD Files Written: %s\n" " SD Bytes Written: %s (%sB)\n" " Rate: %.1f KB/s\n" " Volume name(s): %s\n" " Volume Session Id: %d\n" " Volume Session Time: %d\n" " Last Volume Bytes: %s (%sB)\n" " SD Errors: %d\n" " SD termination status: %s\n" " Termination: %s\n\n"), BAREOS, my_name, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER, edit_uint64(jcr->previous_jr.JobId, ec6), jcr->previous_jr.Job, mig_jcr ? edit_uint64(mig_jcr->jr.JobId, ec7) : _("*None*"), edit_uint64(jcr->jr.JobId, ec8), jcr->jr.Job, level_to_str(jcr->getJobLevel()), jcr->res.client ? jcr->res.client->name() : _("*None*"), jcr->res.fileset ? jcr->res.fileset->name() : _("*None*"), jcr->res.rpool->name(), jcr->res.rpool_source, jcr->res.rstore ? jcr->res.rstore->name() : _("*None*"), NPRT(jcr->res.rstore_source), jcr->res.pool->name(), jcr->res.pool_source, jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), NPRT(jcr->res.wstore_source), jcr->res.next_pool ? jcr->res.next_pool->name() : _("*None*"), NPRT(jcr->res.npool_source), jcr->res.catalog->name(), jcr->res.catalog_source, sdt, edt, edit_utime(RunTime, elapsed, sizeof(elapsed)), jcr->JobPriority, edit_uint64_with_commas(jcr->SDJobFiles, ec1), edit_uint64_with_commas(jcr->SDJobBytes, ec2), edit_uint64_with_suffix(jcr->SDJobBytes, ec3), (float)kbps, mig_jcr ? mig_jcr->VolumeName : _("*None*"), jcr->VolSessionId, jcr->VolSessionTime, edit_uint64_with_commas(mr.VolBytes, ec4), edit_uint64_with_suffix(mr.VolBytes, ec5), jcr->SDErrors, sd_term_msg, term_code); Dmsg0(100, "Leave migrate_cleanup()\n"); } /* * Return next DBId from comma separated list * * Returns: * 1 if next DBId returned * 0 if no more DBIds are in list * -1 there is an error */ static int get_next_dbid_from_list(char **p, DBId_t *DBId) { int i; const int maxlen = 30; char id[maxlen+1]; char *q = *p; id[0] = 0; for (i = 0; i < maxlen; i++) { if (*q == 0) { break; } else if (*q == ',') { q++; break; } id[i] = *q++; id[i+1] = 0; } if (id[0] == 0) { return 0; } else if (!is_a_number(id)) { return -1; /* error */ } *p = q; *DBId = str_to_int64(id); return 1; } bool set_migration_wstorage(JCR *jcr, POOLRES *pool, POOLRES *next_pool, const char *where) { if (!next_pool) { Jmsg(jcr, M_FATAL, 0, _("No Next Pool specification found in Pool \"%s\".\n"), pool->hdr.name); return false; } if (!next_pool->storage || next_pool->storage->size() == 0) { Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Next Pool \"%s\".\n"), next_pool->name()); return false; } copy_wstorage(jcr, next_pool->storage, where); return true; } bareos-Release-14.2.6/src/dird/mountreq.c000066400000000000000000000035531263011562700201750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- mountreq.c -- handles the message channel * Mount request from the Storage daemon. * * Kern Sibbald, March MMI * * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: * Handle Mount services. */ #include "bareos.h" #include "dird.h" /* * Handle mount request * For now, we put the bsock in the UA's queue */ /* Requests from the Storage daemon */ /* Responses sent to Storage daemon */ #ifdef xxx static char OK_mount[] = "1000 OK MountVolume\n"; #endif static BQUEUE mountq = {&mountq, &mountq}; static int num_reqs = 0; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; typedef struct mnt_req_s { BQUEUE bq; BSOCK *bs; JCR *jcr; } MNT_REQ; void mount_request(JCR *jcr, BSOCK *bs, char *buf) { MNT_REQ *mreq; mreq = (MNT_REQ *) malloc(sizeof(MNT_REQ)); memset(mreq, 0, sizeof(MNT_REQ)); mreq->jcr = jcr; mreq->bs = bs; P(mutex); num_reqs++; qinsert(&mountq, &mreq->bq); V(mutex); return; } bareos-Release-14.2.6/src/dird/msgchan.c000066400000000000000000000430511263011562700177400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- msgchan.c -- handles the message channel * to the Storage daemon and the File daemon. * * Kern Sibbald, August MM * * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: * Open a message channel with the Storage daemon * to authenticate ourself and to pass the JobId. * Create a thread to interact with the Storage daemon * who returns a job status and requests Catalog services, etc. */ #include "bareos.h" #include "dird.h" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Commands sent to Storage daemon */ static char jobcmd[] = "JobId=%s job=%s job_name=%s client_name=%s " "type=%d level=%d FileSet=%s NoAttr=%d SpoolAttr=%d FileSetMD5=%s " "SpoolData=%d PreferMountedVols=%d SpoolSize=%s " "rerunning=%d VolSessionId=%d VolSessionTime=%d Quota=%llu " "Protocol=%d BackupFormat=%s DumpLevel=%d\n"; static char use_storage[] = "use storage=%s media_type=%s pool_name=%s " "pool_type=%s append=%d copy=%d stripe=%d\n"; static char use_device[] = "use device=%s\n"; //static char query_device[] = // "query device=%s"; /* Response from Storage daemon */ static char OKbootstrap[] = "3000 OK bootstrap\n"; static char OK_job[] = "3000 OK Job SDid=%d SDtime=%d Authorization=%100s\n"; static char OK_nextrun[] = "3000 OK Job Authorization=%100s\n"; static char OK_device[] = "3000 OK use device device=%s\n"; /* Storage Daemon requests */ static char Job_start[] = "3010 Job %127s start\n"; static char Job_end[] = "3099 Job %127s end JobStatus=%d JobFiles=%d JobBytes=%lld JobErrors=%u\n"; /* Forward referenced functions */ extern "C" void *msg_thread(void *arg); /* * Here we ask the SD to send us the info for a * particular device resource. */ #ifdef xxx bool update_device_res(JCR *jcr, DEVICERES *dev) { POOL_MEM device_name; BSOCK *sd; if (!connect_to_storage_daemon(jcr, 5, 30, false)) { return false; } sd = jcr->store_bsock; pm_strcpy(device_name, dev->name()); bash_spaces(device_name); sd->fsend(query_device, device_name.c_str()); Dmsg1(100, ">stored: %s\n", sd->msg); /* The data is returned through Device_update */ if (bget_dirmsg(sd) <= 0) { return false; } return true; } #endif /* * Send bootstrap file to Storage daemon. * This is used for restore, verify VolumeToCatalog, migration, * and copy Jobs. */ static inline bool send_bootstrap_file_to_sd(JCR *jcr, BSOCK *sd) { FILE *bs; char buf[1000]; const char *bootstrap = "bootstrap\n"; Dmsg1(400, "send_bootstrap_file_to_sd: %s\n", jcr->RestoreBootstrap); if (!jcr->RestoreBootstrap) { return true; } bs = fopen(jcr->RestoreBootstrap, "rb"); if (!bs) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), jcr->RestoreBootstrap, be.bstrerror()); jcr->setJobStatus(JS_ErrorTerminated); return false; } sd->fsend(bootstrap); while (fgets(buf, sizeof(buf), bs)) { sd->fsend("%s", buf); } sd->signal(BNET_EOD); fclose(bs); if (jcr->unlink_bsr) { unlink(jcr->RestoreBootstrap); jcr->unlink_bsr = false; } return true; } /* * Start a job with the Storage daemon */ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore, bool send_bsr) { bool ok = true; STORERES *storage; char auth_key[100]; const char *fileset_md5; POOL_MEM store_name, device_name, pool_name, pool_type, media_type, backup_format; POOL_MEM job_name, client_name, fileset_name; int copy = 0; int stripe = 0; uint64_t remainingquota = 0; char ed1[30], ed2[30]; BSOCK *sd = jcr->store_bsock; /* * Before actually starting a new Job on the SD make sure we send any specific plugin options for this Job. */ if (!do_storage_plugin_options(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Storage daemon rejected Plugin Options command: %s\n"), sd->msg); return false; } /* * Now send JobId and permissions, and get back the authorization key. */ pm_strcpy(job_name, jcr->res.job->name()); bash_spaces(job_name); if (jcr->res.client) { pm_strcpy(client_name, jcr->res.client->name()); } else { pm_strcpy(client_name, "**None**"); } bash_spaces(client_name); if (jcr->res.fileset) { pm_strcpy(fileset_name, jcr->res.fileset->name()); } else { pm_strcpy(fileset_name, "**None**"); } bash_spaces(fileset_name); pm_strcpy(backup_format, jcr->backup_format); bash_spaces(backup_format); if (jcr->res.fileset && jcr->res.fileset->MD5[0] == 0) { bstrncpy(jcr->res.fileset->MD5, "**Dummy**", sizeof(jcr->res.fileset->MD5)); fileset_md5 = jcr->res.fileset->MD5; } else if (jcr->res.fileset) { fileset_md5 = jcr->res.fileset->MD5; } else { fileset_md5 = "**Dummy**"; } /* * If rescheduling, cancel the previous incarnation of this job * with the SD, which might be waiting on the FD connection. * If we do not cancel it the SD will not accept a new connection * for the same jobid. */ if (jcr->reschedule_count) { sd->fsend("cancel Job=%s\n", jcr->Job); while (sd->recv() >= 0) { continue; } } /* * Retrieve available quota 0 bytes means dont perform the check */ remainingquota = fetch_remaining_quotas(jcr); Dmsg1(50,"Remainingquota: %llu\n", remainingquota); sd->fsend(jobcmd, edit_int64(jcr->JobId, ed1), jcr->Job, job_name.c_str(), client_name.c_str(), jcr->getJobType(), jcr->getJobLevel(), fileset_name.c_str(), !jcr->res.pool->catalog_files, jcr->res.job->SpoolAttributes, fileset_md5, jcr->spool_data, jcr->res.job->PreferMountedVolumes, edit_int64(jcr->spool_size, ed2), jcr->rerunning, jcr->VolSessionId, jcr->VolSessionTime, remainingquota, jcr->getJobProtocol(), backup_format.c_str(), jcr->DumpLevel); Dmsg1(100, ">stored: %s", sd->msg); if (bget_dirmsg(sd) > 0) { Dmsg1(100, "msg); if (sscanf(sd->msg, OK_job, &jcr->VolSessionId, &jcr->VolSessionTime, &auth_key) != 3) { Dmsg1(100, "BadJob=%s\n", sd->msg); Jmsg(jcr, M_FATAL, 0, _("Storage daemon rejected Job command: %s\n"), sd->msg); return false; } else { bfree_and_null(jcr->sd_auth_key); jcr->sd_auth_key = bstrdup(auth_key); Dmsg1(150, "sd_auth_key=%s\n", jcr->sd_auth_key); } } else { Jmsg(jcr, M_FATAL, 0, _("bstrerror()); return false; } if (send_bsr && (!send_bootstrap_file_to_sd(jcr, sd) || !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR))) { return false; } /* * We have two loops here. The first comes from the * Storage = associated with the Job, and we need * to attach to each one. * The inner loop loops over all the alternative devices * associated with each Storage. It selects the first * available one. * */ /* Do read side of storage daemon */ if (ok && rstore) { /* For the moment, only migrate, copy and vbackup have rpool */ if (jcr->is_JobType(JT_MIGRATE) || jcr->is_JobType(JT_COPY) || (jcr->is_JobType(JT_BACKUP) && jcr->is_JobLevel(L_VIRTUAL_FULL))) { pm_strcpy(pool_type, jcr->res.rpool->pool_type); pm_strcpy(pool_name, jcr->res.rpool->name()); } else { pm_strcpy(pool_type, jcr->res.pool->pool_type); pm_strcpy(pool_name, jcr->res.pool->name()); } bash_spaces(pool_type); bash_spaces(pool_name); foreach_alist(storage, rstore) { Dmsg1(100, "Rstore=%s\n", storage->name()); pm_strcpy(store_name, storage->name()); bash_spaces(store_name); pm_strcpy(media_type, storage->media_type); bash_spaces(media_type); sd->fsend(use_storage, store_name.c_str(), media_type.c_str(), pool_name.c_str(), pool_type.c_str(), 0, copy, stripe); Dmsg1(100, "rstore >stored: %s", sd->msg); DEVICERES *dev; /* Loop over alternative storage Devices until one is OK */ foreach_alist(dev, storage->device) { pm_strcpy(device_name, dev->name()); bash_spaces(device_name); sd->fsend(use_device, device_name.c_str()); Dmsg1(100, ">stored: %s", sd->msg); } sd->signal(BNET_EOD); /* end of Devices */ } sd->signal(BNET_EOD); /* end of Storages */ if (bget_dirmsg(sd) > 0) { Dmsg1(100, "msg); /* ****FIXME**** save actual device name */ ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; } else { ok = false; } if (ok) { Jmsg(jcr, M_INFO, 0, _("Using Device \"%s\" to read.\n"), device_name.c_str()); } } /* Do write side of storage daemon */ if (ok && wstore) { pm_strcpy(pool_type, jcr->res.pool->pool_type); pm_strcpy(pool_name, jcr->res.pool->name()); bash_spaces(pool_type); bash_spaces(pool_name); foreach_alist(storage, wstore) { pm_strcpy(store_name, storage->name()); bash_spaces(store_name); pm_strcpy(media_type, storage->media_type); bash_spaces(media_type); sd->fsend(use_storage, store_name.c_str(), media_type.c_str(), pool_name.c_str(), pool_type.c_str(), 1, copy, stripe); Dmsg1(100, "wstore >stored: %s", sd->msg); DEVICERES *dev; /* Loop over alternative storage Devices until one is OK */ foreach_alist(dev, storage->device) { pm_strcpy(device_name, dev->name()); bash_spaces(device_name); sd->fsend(use_device, device_name.c_str()); Dmsg1(100, ">stored: %s", sd->msg); } sd->signal(BNET_EOD); /* end of Devices */ } sd->signal(BNET_EOD); /* end of Storages */ if (bget_dirmsg(sd) > 0) { Dmsg1(100, "msg); /* ****FIXME**** save actual device name */ ok = sscanf(sd->msg, OK_device, device_name.c_str()) == 1; } else { ok = false; } if (ok) { Jmsg(jcr, M_INFO, 0, _("Using Device \"%s\" to write.\n"), device_name.c_str()); } } if (!ok) { POOL_MEM err_msg; if (sd->msg[0]) { pm_strcpy(err_msg, sd->msg); /* save message */ Jmsg(jcr, M_FATAL, 0, _("\n" " Storage daemon didn't accept Device \"%s\" because:\n %s"), device_name.c_str(), err_msg.c_str()/* sd->msg */); } else { Jmsg(jcr, M_FATAL, 0, _("\n" " Storage daemon didn't accept Device \"%s\" command.\n"), device_name.c_str()); } } return ok; } /* * Start a thread to handle Storage daemon messages and * Catalog requests. */ bool start_storage_daemon_message_thread(JCR *jcr) { int status; pthread_t thid; jcr->inc_use_count(); /* mark in use by msg thread */ jcr->sd_msg_thread_done = false; jcr->SD_msg_chan_started = false; Dmsg0(100, "Start SD msg_thread.\n"); if ((status = pthread_create(&thid, NULL, msg_thread, (void *)jcr)) != 0) { berrno be; Jmsg1(jcr, M_ABORT, 0, _("Cannot create message thread: %s\n"), be.bstrerror(status)); } /* Wait for thread to start */ while (!jcr->SD_msg_chan_started) { bmicrosleep(0, 50); if (job_canceled(jcr) || jcr->sd_msg_thread_done) { return false; } } Dmsg1(100, "SD msg_thread started. use=%d\n", jcr->use_count()); return true; } extern "C" void msg_thread_cleanup(void *arg) { JCR *jcr = (JCR *)arg; db_end_transaction(jcr, jcr->db); /* terminate any open transaction */ jcr->lock(); jcr->sd_msg_thread_done = true; jcr->SD_msg_chan_started = false; jcr->unlock(); pthread_cond_broadcast(&jcr->nextrun_ready); /* wakeup any waiting threads */ pthread_cond_broadcast(&jcr->term_wait); /* wakeup any waiting threads */ Dmsg2(100, "=== End msg_thread. JobId=%d usecnt=%d\n", jcr->JobId, jcr->use_count()); db_thread_cleanup(jcr->db); /* remove thread specific data */ free_jcr(jcr); /* release jcr */ } /* * Handle the message channel (i.e. requests from the * Storage daemon). * Note, we are running in a separate thread. */ extern "C" void *msg_thread(void *arg) { JCR *jcr = (JCR *)arg; BSOCK *sd; int JobStatus; int n; char auth_key[100]; char Job[MAX_NAME_LENGTH]; uint32_t JobFiles, JobErrors; uint64_t JobBytes; pthread_detach(pthread_self()); set_jcr_in_tsd(jcr); jcr->SD_msg_chan = pthread_self(); jcr->SD_msg_chan_started = true; pthread_cleanup_push(msg_thread_cleanup, arg); sd = jcr->store_bsock; /* * Read the Storage daemon's output. */ Dmsg0(100, "Start msg_thread loop\n"); n = 0; while (!job_canceled(jcr) && (n=bget_dirmsg(sd)) >= 0) { Dmsg1(400, "msg); /* * Check for "3000 OK Job Authorization=" * Returned by a rerun cmd. */ if (sscanf(sd->msg, OK_nextrun, &auth_key) == 1) { if (jcr->sd_auth_key) { free(jcr->sd_auth_key); } jcr->sd_auth_key = bstrdup(auth_key); pthread_cond_broadcast(&jcr->nextrun_ready); /* wakeup any waiting threads */ continue; } /* * Check for "3010 Job start" */ if (sscanf(sd->msg, Job_start, Job) == 1) { continue; } /* * Check for "3099 Job end JobStatus= JobFiles= JobBytes= JobErrors=" */ if (sscanf(sd->msg, Job_end, Job, &JobStatus, &JobFiles, &JobBytes, &JobErrors) == 5) { jcr->SDJobStatus = JobStatus; /* termination status */ jcr->SDJobFiles = JobFiles; jcr->SDJobBytes = JobBytes; jcr->SDErrors = JobErrors; break; } Dmsg1(400, "end loop use=%d\n", jcr->use_count()); } if (n == BNET_HARDEOF) { /* * This probably should be M_FATAL, but I am not 100% sure * that this return *always* corresponds to a dropped line. */ Qmsg(jcr, M_ERROR, 0, _("Director's comm line to SD dropped.\n")); } if (is_bnet_error(sd)) { jcr->SDJobStatus = JS_ErrorTerminated; } pthread_cleanup_pop(1); /* remove and execute the handler */ return NULL; } void wait_for_storage_daemon_termination(JCR *jcr) { int cancel_count = 0; /* Now wait for Storage daemon to terminate our message thread */ while (!jcr->sd_msg_thread_done) { struct timeval tv; struct timezone tz; struct timespec timeout; gettimeofday(&tv, &tz); timeout.tv_nsec = 0; timeout.tv_sec = tv.tv_sec + 5; /* wait 5 seconds */ Dmsg0(400, "I'm waiting for message thread termination.\n"); P(mutex); pthread_cond_timedwait(&jcr->term_wait, &mutex, &timeout); V(mutex); if (jcr->is_canceled()) { if (jcr->SD_msg_chan_started) { jcr->store_bsock->set_timed_out(); jcr->store_bsock->set_terminated(); sd_msg_thread_send_signal(jcr, TIMEOUT_SIGNAL); } cancel_count++; } /* Give SD 30 seconds to clean up after cancel */ if (cancel_count == 6) { break; } } jcr->setJobStatus(JS_Terminated); } #ifdef needed #define MAX_TRIES 30 #define WAIT_TIME 2 extern "C" void *device_thread(void *arg) { int i; JCR *jcr; DEVICERES *dev; pthread_detach(pthread_self()); jcr = new_control_jcr("*DeviceInit*", JT_SYSTEM); for (i=0; i < MAX_TRIES; i++) { if (!connect_to_storage_daemon(jcr, 10, 30, true)) { Dmsg0(900, "Failed connecting to SD.\n"); continue; } LockRes(); foreach_res(dev, R_DEVICE) { if (!update_device_res(jcr, dev)) { Dmsg1(900, "Error updating device=%s\n", dev->name()); } else { Dmsg1(900, "Updated Device=%s\n", dev->name()); } } UnlockRes(); jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; break; } free_jcr(jcr); return NULL; } /* * Start a thread to handle getting Device resource information * from SD. This is called once at startup of the Director. */ void init_device_resources() { int status; pthread_t thid; Dmsg0(100, "Start Device thread.\n"); if ((status = pthread_create(&thid, NULL, device_thread, NULL)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("Cannot create message thread: %s\n"), be.bstrerror(status)); } } #endif bareos-Release-14.2.6/src/dird/ndmp_dma_backup.c000066400000000000000000000555041263011562700214320ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2015 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Backup specific NDMP Data Management Application (DMA) routines * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if HAVE_NDMP #define NDMP_NEED_ENV_KEYWORDS 1 #include "ndmp/ndmagents.h" #include "ndmp_dma_priv.h" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Imported variables */ /* Forward referenced functions */ /* * This glues the NDMP File Handle DB with internal code. */ static inline void register_callback_hooks(struct ndmlog *ixlog) { ndmp_fhdb_mem_register(ixlog); } static inline void unregister_callback_hooks(struct ndmlog *ixlog) { ndmp_fhdb_mem_unregister(ixlog); } static inline void process_fhdb(struct ndmlog *ixlog) { ndmp_fhdb_mem_process_db(ixlog); } static inline int native_to_ndmp_level(JCR *jcr, char *filesystem) { int level = -1; if (!db_create_ndmp_level_mapping(jcr, jcr->db, &jcr->jr, filesystem)) { return -1; } switch (jcr->getJobLevel()) { case L_FULL: level = 0; break; case L_DIFFERENTIAL: level = 1; break; case L_INCREMENTAL: level = db_get_ndmp_level_mapping(jcr, jcr->db, &jcr->jr, filesystem); break; default: Jmsg(jcr, M_FATAL, 0, _("Illegal Job Level %c for NDMP Job\n"), jcr->getJobLevel()); break; } /* * Dump level can be from 0 - 9 */ if (level < 0 || level > 9) { Jmsg(jcr, M_FATAL, 0, _("NDMP dump format doesn't support more than 8 " "incrementals, please run a Differential or a Full Backup\n")); level = -1; } return level; } /* * Fill the NDMP backup environment table with the data for the data agent to act on. */ static inline bool fill_backup_environment(JCR *jcr, INCEXE *ie, char *filesystem, struct ndm_job_param *job) { int i, j, cnt; bool exclude; FOPTS *fo; ndmp9_pval pv; POOL_MEM pattern; POOL_MEM tape_device; ndmp_backup_format_option *nbf_options; /* * See if we know this backup format and get it options. */ nbf_options = ndmp_lookup_backup_format_options(job->bu_type); if (!nbf_options || nbf_options->uses_file_history) { /* * We want to receive file history info from the NDMP backup. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_HIST]; pv.value = ndmp_env_values[NDMP_ENV_VALUE_YES]; ndma_store_env_list(&job->env_tab, &pv); } else { /* * We don't want to receive file history info from the NDMP backup. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_HIST]; pv.value = ndmp_env_values[NDMP_ENV_VALUE_NO]; ndma_store_env_list(&job->env_tab, &pv); } /* * Tell the data agent what type of backup to make. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_TYPE]; pv.value = job->bu_type; ndma_store_env_list(&job->env_tab, &pv); /* * See if we are doing a backup type that uses dumplevels. */ if (nbf_options && nbf_options->uses_level) { char text_level[50]; /* * Set the dump level for the backup. */ jcr->DumpLevel = native_to_ndmp_level(jcr, filesystem); job->bu_level = jcr->DumpLevel; if (job->bu_level == -1) { return false; } pv.name = ndmp_env_keywords[NDMP_ENV_KW_LEVEL]; pv.value = edit_uint64(job->bu_level, text_level); ndma_store_env_list(&job->env_tab, &pv); /* * Update the dumpdates */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_UPDATE]; pv.value = ndmp_env_values[NDMP_ENV_VALUE_YES]; ndma_store_env_list(&job->env_tab, &pv); } /* * Tell the data engine what to backup. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_FILESYSTEM]; pv.value = filesystem; ndma_store_env_list(&job->env_tab, &pv); /* * Loop over each option block for this fileset and append any * INCLUDE/EXCLUDE and/or META tags to the env_tab of the NDMP backup. */ for (i = 0; i < ie->num_opts; i++) { fo = ie->opts_list[i]; /* * Pickup any interesting patterns. */ cnt = 0; pm_strcpy(pattern, ""); for (j = 0; j < fo->wild.size(); j++) { if (cnt != 0) { pm_strcat(pattern, ","); } pm_strcat(pattern, (char *)fo->wild.get(j)); cnt++; } for (j = 0; j < fo->wildfile.size(); j++) { if (cnt != 0) { pm_strcat(pattern, ","); } pm_strcat(pattern, (char *)fo->wildfile.get(j)); cnt++; } for (j = 0; j < fo->wilddir.size(); j++) { if (cnt != 0) { pm_strcat(pattern, ","); } pm_strcat(pattern, (char *)fo->wilddir.get(j)); cnt++; } /* * See if this is a INCLUDE or EXCLUDE block. */ if (cnt > 0) { exclude = false; for (j = 0; fo->opts[j] != '\0'; j++) { if (fo->opts[j] == 'e') { exclude = true; break; } } if (exclude) { pv.name = ndmp_env_keywords[NDMP_ENV_KW_EXCLUDE]; } else { pv.name = ndmp_env_keywords[NDMP_ENV_KW_INCLUDE]; } pv.value = pattern.c_str(); ndma_store_env_list(&job->env_tab, &pv); } /* * Parse all specific META tags for this option block. */ for (j = 0; j < fo->meta.size(); j++) { ndmp_parse_meta_tag(&job->env_tab, (char *)fo->meta.get(j)); } } /* * If we have a paired storage definition we put the storage daemon * auth key and the filesystem into the tape device name of the * NDMP session. This way the storage daemon can link the NDMP * data and the normal save session together. */ if (jcr->store_bsock) { Mmsg(tape_device, "%s@%s", jcr->sd_auth_key, filesystem); job->tape_device = bstrdup(tape_device.c_str()); } return true; } /* * Extract any post backup statistics. */ static inline bool extract_post_backup_stats(JCR *jcr, char *filesystem, struct ndm_session *sess) { bool retval = true; struct ndmmedia *media; ndmp_backup_format_option *nbf_options; struct ndm_env_entry *ndm_ee; /* * See if we know this backup format and get it options. */ nbf_options = ndmp_lookup_backup_format_options(sess->control_acb->job.bu_type); /* * See if an error was raised during the backup session. */ if (sess->error_raised) { return false; } /* * See if there is any media error. */ for (media = sess->control_acb->job.result_media_tab.head; media; media = media->next) { if (media->media_open_error || media->media_io_error || media->label_io_error || media->label_mismatch || media->fmark_error) { retval = false; } } /* * Process the FHDB. */ process_fhdb(&sess->control_acb->job.index_log); /* * Update the Job statistics from the NDMP statistics. */ jcr->JobBytes += sess->control_acb->job.bytes_written; /* * After a successfull backup we need to store all NDMP ENV variables * for doing a successfull restore operation. */ ndm_ee = sess->control_acb->job.result_env_tab.head; while (ndm_ee) { if (!db_create_ndmp_environment_string(jcr, jcr->db, &jcr->jr, ndm_ee->pval.name, ndm_ee->pval.value)) { break; } ndm_ee = ndm_ee->next; } /* * If we are doing a backup type that uses dumplevels save the last used dump level. */ if (nbf_options && nbf_options->uses_level) { db_update_ndmp_level_mapping(jcr, jcr->db, &jcr->jr, filesystem, sess->control_acb->job.bu_level); } return retval; } /* * Setup a NDMP backup session. */ bool do_ndmp_backup_init(JCR *jcr) { free_rstorage(jcr); /* we don't read so release */ if (!allow_duplicate_job(jcr)) { return false; } jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->res.pool->name()); if (jcr->jr.PoolId == 0) { return false; } jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); return false; } /* * If pool storage specified, use it instead of job storage */ copy_wstorage(jcr, jcr->res.pool->storage, _("Pool resource")); if (!jcr->wstorage) { Jmsg(jcr, M_FATAL, 0, _("No Storage specification found in Job or Pool.\n")); return false; } /* * Validate the Job to have a NDMP client and NDMP storage. */ if (!ndmp_validate_client(jcr)) { return false; } if (!ndmp_validate_storage(jcr)) { return false; } /* * For now we only allow NDMP backups to bareos SD's * so we need a paired storage definition. */ if (!has_paired_storage(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Write storage doesn't point to storage definition with paired storage option.\n")); return false; } return true; } /* * Run a NDMP backup session. */ bool do_ndmp_backup(JCR *jcr) { unsigned int cnt; int i, status; char ed1[100]; NIS *nis = NULL; FILESETRES *fileset; struct ndm_job_param ndmp_job; struct ndm_session ndmp_sess; bool session_initialized = false; bool retval = false; int NdmpLoglevel; if (jcr->res.client->ndmp_loglevel > me->ndmp_loglevel) { NdmpLoglevel = jcr->res.client->ndmp_loglevel; } else { NdmpLoglevel = me->ndmp_loglevel; } /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start NDMP Backup JobId %s, Job=%s\n"), edit_uint64(jcr->JobId, ed1), jcr->Job); jcr->setJobStatus(JS_Running); Dmsg2(100, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel); if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); return false; } if (check_hardquotas(jcr)) { Jmsg(jcr, M_FATAL, 0, "Quota Exceeded. Job terminated."); return false; } if (check_softquotas(jcr)) { Dmsg0(10, "Quota exceeded\n"); Jmsg(jcr, M_FATAL, 0, "Soft Quota Exceeded / Grace Time expired. Job terminated."); return false; } /* * If we have a paired storage definition create a native connection * to a Storage daemon and make it ready to receive a backup. * The setup is more or less the same as for a normal non NDMP backup * only the data doesn't come in from a FileDaemon but from a NDMP * data mover which moves the data from the NDMP DATA AGENT to the NDMP * TAPE AGENT. */ if (jcr->res.wstore->paired_storage) { set_paired_storage(jcr); jcr->setJobStatus(JS_WaitSD); if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { return false; } /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, NULL, jcr->wstorage)) { return false; } /* * Start the job prior to starting the message thread below * to avoid two threads from using the BSOCK structure at * the same time. */ if (!jcr->store_bsock->fsend("run")) { return false; } /* * Now start a Storage daemon message thread. Note, * this thread is used to provide the catalog services * for the backup job. */ if (!start_storage_daemon_message_thread(jcr)) { return false; } Dmsg0(150, "Storage daemon connection OK\n"); } status = 0; /* * Initialize the ndmp backup job. We build the generic job only once * and reuse the job definition for each seperate sub-backup we perform as * part of the whole job. We only free the env_table between every sub-backup. */ if (!ndmp_build_client_job(jcr, jcr->res.client, jcr->res.pstore, NDM_JOB_OP_BACKUP, &ndmp_job)) { goto bail_out; } nis = (NIS *)malloc(sizeof(NIS)); memset(nis, 0, sizeof(NIS)); /* * Loop over each include set of the fileset and fire off a NDMP backup of the included fileset. */ cnt = 0; fileset = jcr->res.fileset; for (i = 0; i < fileset->num_includes; i++) { int j; char *item; INCEXE *ie = fileset->include_items[i]; POOL_MEM virtual_filename(PM_FNAME); /* * Loop over each file = entry of the fileset. */ for (j = 0; j < ie->name_list.size(); j++) { item = (char *)ie->name_list.get(j); /* * See if this is the first Backup run or not. For NDMP we can have multiple Backup * runs as part of the same Job. When we are saving data to a Native Storage Daemon * we let it know to expect a new backup session. It will generate a new authorization * key so we wait for the nextrun_ready conditional variable to be raised by the msg_thread. */ if (jcr->store_bsock && cnt > 0) { jcr->store_bsock->fsend("nextrun"); P(mutex); pthread_cond_wait(&jcr->nextrun_ready, &mutex); V(mutex); } /* * Perform the actual NDMP job. * Initialize a new NDMP session */ memset(&ndmp_sess, 0, sizeof(ndmp_sess)); ndmp_sess.conn_snooping = (me->ndmp_snooping) ? 1 : 0; ndmp_sess.control_agent_enabled = 1; ndmp_sess.param = (struct ndm_session_param *)malloc(sizeof(struct ndm_session_param)); memset(ndmp_sess.param, 0, sizeof(struct ndm_session_param)); ndmp_sess.param->log.deliver = ndmp_loghandler; ndmp_sess.param->log_level = native_to_ndmp_loglevel(NdmpLoglevel, debug_level, nis); nis->filesystem = item; nis->FileIndex = cnt + 1; nis->jcr = jcr; nis->save_filehist = jcr->res.job->SaveFileHist; /* * The full ndmp archive has a virtual filename, we need it to hardlink the individual * file records to it. So we allocate it here once so its available during the whole * NDMP session. */ if (bstrcasecmp(jcr->backup_format, "dump")) { Mmsg(virtual_filename, "/@NDMP%s%%%d", nis->filesystem, jcr->DumpLevel); } else { Mmsg(virtual_filename, "/@NDMP%s", nis->filesystem); } if (nis->virtual_filename) { free(nis->virtual_filename); } nis->virtual_filename = bstrdup(virtual_filename.c_str()); ndmp_sess.param->log.ctx = nis; ndmp_sess.param->log_tag = bstrdup("DIR-NDMP"); /* * Initialize the session structure. */ if (ndma_session_initialize(&ndmp_sess)) { goto cleanup; } session_initialized = true; /* * Copy the actual job to perform. */ memcpy(&ndmp_sess.control_acb->job, &ndmp_job, sizeof(struct ndm_job_param)); if (!fill_backup_environment(jcr, ie, nis->filesystem, &ndmp_sess.control_acb->job)) { goto cleanup; } ndma_job_auto_adjust(&ndmp_sess.control_acb->job); if (!ndmp_validate_job(jcr, &ndmp_sess.control_acb->job)) { goto cleanup; } /* * Commission the session for a run. */ if (ndma_session_commission(&ndmp_sess)) { goto cleanup; } /* * Setup the DMA. */ if (ndmca_connect_control_agent(&ndmp_sess)) { goto cleanup; } ndmp_sess.conn_open = 1; ndmp_sess.conn_authorized = 1; /* * We can use the same private pointer used in the logging with the JCR in * the file index generation. We don't setup a index_log.deliver * function as we catch the index information via callbacks. */ ndmp_sess.control_acb->job.index_log.ctx = ndmp_sess.param->log.ctx; register_callback_hooks(&ndmp_sess.control_acb->job.index_log); /* * Let the DMA perform its magic. */ if (ndmca_control_agent(&ndmp_sess) != 0) { goto cleanup; } /* * See if there were any errors during the backup. */ jcr->jr.FileIndex = cnt + 1; if (!extract_post_backup_stats(jcr, item, &ndmp_sess)) { goto cleanup; } unregister_callback_hooks(&ndmp_sess.control_acb->job.index_log); /* * Reset the NDMP session states. */ ndma_session_decommission(&ndmp_sess); /* * Cleanup the job after it has run. */ ndma_destroy_env_list(&ndmp_sess.control_acb->job.env_tab); ndma_destroy_env_list(&ndmp_sess.control_acb->job.result_env_tab); ndma_destroy_nlist(&ndmp_sess.control_acb->job.nlist_tab); /* * Release any tape device name allocated. */ if (ndmp_sess.control_acb->job.tape_device) { free(ndmp_sess.control_acb->job.tape_device); ndmp_sess.control_acb->job.tape_device = NULL; } /* * Destroy the session. */ ndma_session_destroy(&ndmp_sess); /* * Free the param block. */ free(ndmp_sess.param->log_tag); free(ndmp_sess.param); ndmp_sess.param = NULL; /* * Reset the initialized state so we don't try to cleanup again. */ session_initialized = false; cnt++; } } status = JS_Terminated; retval = true; /* * Tell the storage daemon we are done. */ if (jcr->store_bsock) { jcr->store_bsock->fsend("finish"); wait_for_storage_daemon_termination(jcr); db_write_batch_file_records(jcr); /* used by bulk batch file insert */ } /* * If we do incremental backups it can happen that the backup is empty if * nothing changed but we always write a filestream. So we use the counter * which counts the number of actual NDMP backup sessions we run to completion. */ if (jcr->JobFiles < cnt) { jcr->JobFiles = cnt; } /* * Jump to the generic cleanup done for every Job. */ goto ok_out; cleanup: /* * Only need to cleanup when things are initialized. */ if (session_initialized) { ndma_destroy_env_list(&ndmp_sess.control_acb->job.env_tab); ndma_destroy_env_list(&ndmp_sess.control_acb->job.result_env_tab); ndma_destroy_nlist(&ndmp_sess.control_acb->job.nlist_tab); if (ndmp_sess.control_acb->job.tape_device) { free(ndmp_sess.control_acb->job.tape_device); } unregister_callback_hooks(&ndmp_sess.control_acb->job.index_log); /* * Destroy the session. */ ndma_session_destroy(&ndmp_sess); } if (ndmp_sess.param) { free(ndmp_sess.param->log_tag); free(ndmp_sess.param); } bail_out: /* * Error handling of failed Job. */ status = JS_ErrorTerminated; jcr->setJobStatus(JS_ErrorTerminated); if (jcr->store_bsock) { cancel_storage_daemon_job(jcr); wait_for_storage_daemon_termination(jcr); } ok_out: if (nis) { if (nis->virtual_filename) { free(nis->virtual_filename); } free(nis); } free_paired_storage(jcr); if (status == JS_Terminated) { ndmp_backup_cleanup(jcr, status); } return retval; } /* * Cleanup a NDMP backup session. */ void ndmp_backup_cleanup(JCR *jcr, int TermCode) { const char *term_msg; char term_code[100]; int msg_type = M_INFO; CLIENT_DBR cr; Dmsg2(100, "Enter ndmp_backup_cleanup %d %c\n", TermCode, TermCode); memset(&cr, 0, sizeof(cr)); if (jcr->is_JobStatus(JS_Terminated) && (jcr->JobErrors || jcr->SDErrors || jcr->JobWarnings)) { TermCode = JS_Warnings; } update_job_end(jcr, TermCode); if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"), db_strerror(jcr->db)); jcr->setJobStatus(JS_ErrorTerminated); } bstrncpy(cr.Name, jcr->res.client->name(), sizeof(cr.Name)); if (!db_get_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Client record for Job report: ERR=%s"), db_strerror(jcr->db)); } update_bootstrap_file(jcr); switch (jcr->JobStatus) { case JS_Terminated: term_msg = _("Backup OK"); break; case JS_Warnings: term_msg = _("Backup OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Backup Error ***"); msg_type = M_ERROR; /* Generate error message */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; case JS_Canceled: term_msg = _("Backup Canceled"); if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; default: term_msg = term_code; sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus); break; } generate_backup_summary(jcr, &cr, msg_type, term_msg); Dmsg0(100, "Leave ndmp_backup_cleanup\n"); } #else bool do_ndmp_backup_init(JCR *jcr) { Jmsg(jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); return false; } bool do_ndmp_backup(JCR *jcr) { Jmsg(jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); return false; } void ndmp_backup_cleanup(JCR *jcr, int TermCode) { Jmsg(jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); } #endif /* HAVE_NDMP */ bareos-Release-14.2.6/src/dird/ndmp_dma_generic.c000066400000000000000000000407621263011562700216010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2015 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Generic NDMP Data Management Application (DMA) routines * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if HAVE_NDMP #define SMTAPE_MIN_BLOCKSIZE 4096 /* 4 Kb */ #define SMTAPE_MAX_BLOCKSIZE 262144 /* 256 Kb */ #define SMTAPE_BLOCKSIZE_INCREMENTS 4096 /* 4 Kb */ #include "ndmp/ndmagents.h" #include "ndmp_dma_priv.h" /* Imported variables */ /* Forward referenced functions */ /* * Per NDMP format specific options. */ static ndmp_backup_format_option ndmp_backup_format_options[] = { { (char *)"dump", true, true, true, true }, { (char *)"tar", true, false, true, true }, { (char *)"smtape", false, true, false, true }, { (char *)"zfs", false, true, false, true }, { (char *)"vbb", false, true, false, true }, { (char *)"image", false, true, false, true }, { NULL, false, false, false } }; ndmp_backup_format_option *ndmp_lookup_backup_format_options(const char *backup_format) { int i = 0; while (ndmp_backup_format_options[i].format) { if (bstrcasecmp(backup_format, ndmp_backup_format_options[i].format)) { break; } i++; } if (ndmp_backup_format_options[i].format) { return &ndmp_backup_format_options[i]; } return (ndmp_backup_format_option *)NULL; } /* * Validation functions. */ bool ndmp_validate_client(JCR *jcr) { switch (jcr->res.client->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: if (jcr->res.client->password.encoding != p_encoding_clear) { Jmsg(jcr, M_FATAL, 0, _("Client %s, has incompatible password encoding for running NDMP backup.\n"), jcr->res.client->name()); return false; } break; default: Jmsg(jcr, M_FATAL, 0, _("Client %s, with backup protocol %s not compatible for running NDMP backup.\n"), jcr->res.client->name(), auth_protocol_to_str(jcr->res.client->Protocol)); return false; } return true; } static inline bool ndmp_validate_storage(JCR *jcr, STORERES *store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: if (store->password.encoding != p_encoding_clear) { Jmsg(jcr, M_FATAL, 0, _("Storage %s, has incompatible password encoding for running NDMP backup.\n"), store->name()); return false; } break; default: Jmsg(jcr, M_FATAL, 0, _("Storage %s has illegal backup protocol %s for NDMP backup\n"), store->name(), auth_protocol_to_str(store->Protocol)); return false; } return true; } bool ndmp_validate_storage(JCR *jcr) { STORERES *store; if (jcr->wstorage) { foreach_alist(store, jcr->wstorage) { if (!ndmp_validate_storage(jcr, store)) { return false; } } } else { foreach_alist(store, jcr->rstorage) { if (!ndmp_validate_storage(jcr, store)) { return false; } } } return true; } bool ndmp_validate_job(JCR *jcr, struct ndm_job_param *job) { int n_err, i; char audit_buffer[256]; /* * Audit the job so we only submit a valid NDMP job. */ n_err = 0; i = 0; do { n_err = ndma_job_audit(job, audit_buffer, i); if (n_err) { Jmsg(jcr, M_ERROR, 0, _("NDMP Job validation error = %s\n"), audit_buffer); } i++; } while (i < n_err); if (n_err) { return false; } return true; } /* * Fill a ndmagent structure with the correct info. Instead of calling ndmagent_from_str * we fill the structure ourself from info provides in a resource. */ static inline bool fill_ndmp_agent_config(JCR *jcr, struct ndmagent *agent, uint32_t protocol, uint32_t authtype, char *address, uint32_t port, char *username, char *password) { agent->conn_type = NDMCONN_TYPE_REMOTE; switch (protocol) { case APT_NDMPV2: agent->protocol_version = 2; break; case APT_NDMPV3: agent->protocol_version = 3; break; case APT_NDMPV4: agent->protocol_version = 4; break; default: Jmsg(jcr, M_FATAL, 0, _("Illegal protocol %d for NDMP Job\n"), protocol); return false; } switch (authtype) { case AT_NONE: agent->auth_type = 'n'; break; case AT_CLEAR: agent->auth_type = 't'; break; case AT_MD5: agent->auth_type = 'm'; break; case AT_VOID: agent->auth_type = 'v'; break; default: Jmsg(jcr, M_FATAL, 0, _("Illegal authtype %d for NDMP Job\n"), authtype); return false; } agent->port = port; bstrncpy(agent->host, address, sizeof(agent->host)); bstrncpy(agent->account, username, sizeof(agent->account)); bstrncpy(agent->password, password, sizeof(agent->password)); return true; } /* * Parse a meta-tag and convert it into a ndmp_pval */ void ndmp_parse_meta_tag(struct ndm_env_table *env_tab, char *meta_tag) { char *p; ndmp9_pval pv; /* * See if the meta-tag is parseable. */ if ((p = strchr(meta_tag, '=')) == NULL) { return; } /* * Split the tag on the '=' */ *p = '\0'; pv.name = meta_tag; pv.value = p + 1; ndma_update_env_list(env_tab, &pv); /* * Restore the '=' */ *p = '='; } /* * Calculate the wanted NDMP loglevel from the current debug level and * any configure minimum level. */ int native_to_ndmp_loglevel(int NdmpLoglevel, int debuglevel, NIS *nis) { unsigned int level; nis->LogLevel = NdmpLoglevel; /* * NDMP loglevels run from 0 - 9 so we take a look at the * current debug level and divide it by 100 to get a proper * value. If the debuglevel is below the wanted initial level * we set the loglevel to the wanted initial level. As the * debug logging takes care of logging messages that are * unwanted we can set the loglevel higher and still don't * get debug messages. */ level = debuglevel / 100; if (level < nis->LogLevel) { level = nis->LogLevel; } /* * Make sure the level is in the wanted range. */ if (level > 9) { level = 9; } return level; } bool ndmp_build_client_job(JCR *jcr, CLIENTRES *client, STORERES *store, int operation, struct ndm_job_param *job) { memset(job, 0, sizeof(struct ndm_job_param)); job->operation = operation; job->bu_type = jcr->backup_format; /* * For NDMP the backupformat is a prerequite abort the backup job when * it is not supplied in the config definition. */ if (!job->bu_type) { Jmsg(jcr, M_FATAL, 0, _("No backup type specified in NDMP job\n")); goto bail_out; } /* * The data_agent is the client being backuped or restored using NDMP. */ ASSERT(client->password.encoding == p_encoding_clear); if (!fill_ndmp_agent_config(jcr, &job->data_agent, client->Protocol, client->AuthType, client->address, client->FDport, client->username, client->password.value)) { goto bail_out; } /* * The tape_agent is the storage daemon via the NDMP protocol. */ ASSERT(store->password.encoding == p_encoding_clear); if (!fill_ndmp_agent_config(jcr, &job->tape_agent, store->Protocol, store->AuthType, store->address, store->SDport, store->username, store->password.value)) { goto bail_out; } if (bstrcasecmp(jcr->backup_format, "smtape")) { /* * SMTAPE only wants certain blocksizes. */ if (jcr->res.client->ndmp_blocksize < SMTAPE_MIN_BLOCKSIZE || jcr->res.client->ndmp_blocksize > SMTAPE_MAX_BLOCKSIZE) { Jmsg(jcr, M_FATAL, 0, _("For SMTAPE NDMP jobs the NDMP blocksize needs to be between %d and %d, but is set to %d\n"), SMTAPE_MIN_BLOCKSIZE, SMTAPE_MAX_BLOCKSIZE, jcr->res.client->ndmp_blocksize); goto bail_out; } if ((jcr->res.client->ndmp_blocksize % SMTAPE_BLOCKSIZE_INCREMENTS) != 0) { Jmsg(jcr, M_FATAL, 0, _("For SMTAPE NDMP jobs the NDMP blocksize needs to be in increments of %d bytes, but is set to %d\n"), SMTAPE_BLOCKSIZE_INCREMENTS, jcr->res.client->ndmp_blocksize); goto bail_out; } job->record_size = jcr->res.client->ndmp_blocksize; } else { job->record_size = jcr->res.client->ndmp_blocksize; } return true; bail_out: return false; } bool ndmp_build_storage_job(JCR *jcr, STORERES *store, bool init_tape, bool init_robot, int operation, struct ndm_job_param *job) { memset(job, 0, sizeof(struct ndm_job_param)); job->operation = operation; job->bu_type = jcr->backup_format; if (init_tape) { /* * Setup the TAPE agent of the NDMP job. */ ASSERT(store->password.encoding == p_encoding_clear); if (!fill_ndmp_agent_config(jcr, &job->tape_agent, store->Protocol, store->AuthType, store->address, store->SDport, store->username, store->password.value)) { goto bail_out; } } if (init_robot) { /* * Setup the ROBOT agent of the NDMP job. */ if (!fill_ndmp_agent_config(jcr, &job->robot_agent, store->Protocol, store->AuthType, store->address, store->SDport, store->username, store->password.value)) { goto bail_out; } } return true; bail_out: return false; } /* * Interface function which glues the logging infra of the NDMP lib with the daemon. */ extern "C" void ndmp_loghandler(struct ndmlog *log, char *tag, int level, char *msg) { int internal_level; NIS *nis; /* * We don't want any trailing newline in log messages. */ strip_trailing_newline(msg); /* * Make sure if the logging system was setup properly. */ nis = (NIS *)log->ctx; if (!nis) { return; } /* * If the log level of this message is under our logging treshold we * log it as part of the Job. */ if (level <= (int)nis->LogLevel) { if (nis->jcr) { /* * Look at the tag field to see what is logged. */ if (bstrncmp(tag + 1, "LM", 2)) { /* * *LM* messages. E.g. log message NDMP protocol msgs. * First character of the tag is the agent sending the * message e.g. 'D' == Data Agent * 'T' == Tape Agent * 'R' == Robot Agent * 'C' == Control Agent (DMA) * * Last character is the type of message e.g. * 'n' - normal message * 'd' - debug message * 'e' - error message * 'w' - warning message * '?' - unknown message level */ switch (*(tag + 3)) { case 'n': Jmsg(nis->jcr, M_INFO, 0, "%s\n", msg); break; case 'e': Jmsg(nis->jcr, M_ERROR, 0, "%s\n", msg); break; case 'w': Jmsg(nis->jcr, M_WARNING, 0, "%s\n", msg); break; case '?': Jmsg(nis->jcr, M_INFO, 0, "%s\n", msg); break; default: break; } } else { Jmsg(nis->jcr, M_INFO, 0, "%s\n", msg); } } } /* * Print any debug message we convert the NDMP level back to an internal * level and let the normal debug logging handle if it needs to be printed * or not. */ internal_level = level * 100; Dmsg3(internal_level, "NDMP: [%s] [%d] %s\n", tag, level, msg); } /* * Interface function which glues the logging infra of the NDMP lib with the user context. */ extern "C" void ndmp_client_status_handler(struct ndmlog *log, char *tag, int lev, char *msg) { NIS *nis; /* * Make sure if the logging system was setup properly. */ nis = (NIS *)log->ctx; if (!nis) { return; } nis->ua->send_msg("%s\n", msg); } /* * Generic function to query the NDMP server using the NDM_JOB_OP_QUERY_AGENTS * operation. Callback is the above ndmp_client_status_handler which prints * the data to the user context. */ void ndmp_do_query(UAContext *ua, ndm_job_param *ndmp_job, int NdmpLoglevel) { NIS *nis; struct ndm_session ndmp_sess; /* * Initialize a new NDMP session */ memset(&ndmp_sess, 0, sizeof(ndmp_sess)); ndmp_sess.conn_snooping = (me->ndmp_snooping) ? 1 : 0; ndmp_sess.control_agent_enabled = 1; ndmp_sess.param = (struct ndm_session_param *)malloc(sizeof(struct ndm_session_param)); memset(ndmp_sess.param, 0, sizeof(struct ndm_session_param)); ndmp_sess.param->log.deliver = ndmp_client_status_handler; nis = (NIS *)malloc(sizeof(NIS)); memset(nis, 0, sizeof(NIS)); ndmp_sess.param->log_level = native_to_ndmp_loglevel(NdmpLoglevel, debug_level, nis); nis->ua = ua; ndmp_sess.param->log.ctx = nis; ndmp_sess.param->log_tag = bstrdup("DIR-NDMP"); /* * Initialize the session structure. */ if (ndma_session_initialize(&ndmp_sess)) { goto bail_out; } /* * Copy the actual job to perform. */ memcpy(&ndmp_sess.control_acb->job, ndmp_job, sizeof(struct ndm_job_param)); if (!ndmp_validate_job(ua->jcr, &ndmp_sess.control_acb->job)) { goto cleanup; } /* * Commission the session for a run. */ if (ndma_session_commission(&ndmp_sess)) { goto cleanup; } /* * Setup the DMA. */ if (ndmca_connect_control_agent(&ndmp_sess)) { goto cleanup; } ndmp_sess.conn_open = 1; ndmp_sess.conn_authorized = 1; /* * Let the DMA perform its magic. */ if (ndmca_control_agent(&ndmp_sess) != 0) { goto cleanup; } cleanup: /* * Destroy the session. */ ndma_session_destroy(&ndmp_sess); bail_out: /* * Free the param block. */ free(ndmp_sess.param->log_tag); free(ndmp_sess.param); free(nis); ndmp_sess.param = NULL; } /* * Output the status of a NDMP client. Query the DATA agent of a * native NDMP server to give some info. */ void do_ndmp_client_status(UAContext *ua, CLIENTRES *client, char *cmd) { struct ndm_job_param ndmp_job; memset(&ndmp_job, 0, sizeof(struct ndm_job_param)); ndmp_job.operation = NDM_JOB_OP_QUERY_AGENTS; /* * Query the DATA agent of the NDMP server. */ ASSERT(client->password.encoding == p_encoding_clear); if (!fill_ndmp_agent_config(ua->jcr, &ndmp_job.data_agent, client->Protocol, client->AuthType, client->address, client->FDport, client->username, client->password.value)) { return; } ndmp_do_query(ua, &ndmp_job, (client->ndmp_loglevel > me->ndmp_loglevel) ? client->ndmp_loglevel : me->ndmp_loglevel); } #else void do_ndmp_client_status(UAContext *ua, CLIENTRES *client, char *cmd) { Jmsg(ua->jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); } #endif /* HAVE_NDMP */ bareos-Release-14.2.6/src/dird/ndmp_dma_priv.h000066400000000000000000000077061263011562700211530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2015-2015 Planets Communications B.V. Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * NDMP internal routines used by the different NDMP components. * * Marco van Wieringen, May 2015 */ #ifndef BNDMP_DMA_PRIV_H #define BNDMP_DMA_PRIV_H 1 #ifdef NDMP_NEED_ENV_KEYWORDS /* * Array used for storing fixed NDMP env keywords. * Anything special should go into a so called meta-tag in the fileset options. */ static char *ndmp_env_keywords[] = { (char *)"HIST", (char *)"TYPE", (char *)"DIRECT", (char *)"LEVEL", (char *)"UPDATE", (char *)"EXCLUDE", (char *)"INCLUDE", (char *)"FILESYSTEM", (char *)"PREFIX" }; /* * Index values for above keyword. */ enum { NDMP_ENV_KW_HIST = 0, NDMP_ENV_KW_TYPE, NDMP_ENV_KW_DIRECT, NDMP_ENV_KW_LEVEL, NDMP_ENV_KW_UPDATE, NDMP_ENV_KW_EXCLUDE, NDMP_ENV_KW_INCLUDE, NDMP_ENV_KW_FILESYSTEM, NDMP_ENV_KW_PREFIX }; /* * Array used for storing fixed NDMP env values. * Anything special should go into a so called meta-tag in the fileset options. */ static char *ndmp_env_values[] = { (char *)"n", (char *)"y" }; /* * Index values for above values. */ enum { NDMP_ENV_VALUE_NO = 0, NDMP_ENV_VALUE_YES }; #endif /* NDMP_NEED_ENV_KEYWORDS */ struct ndmp_backup_format_option { char *format; bool uses_file_history; bool uses_level; bool restore_prefix_relative; bool needs_namelist; }; /* * Internal structure to keep track of private data. */ struct ndmp_internal_state { uint32_t LogLevel; JCR *jcr; UAContext *ua; char *filesystem; int32_t FileIndex; char *virtual_filename; bool save_filehist; void *fhdb_state; }; typedef struct ndmp_internal_state NIS; /* * Generic DMA functions. */ ndmp_backup_format_option *ndmp_lookup_backup_format_options(const char *backup_format); bool ndmp_validate_job(JCR *jcr, struct ndm_job_param *job); void ndmp_parse_meta_tag(struct ndm_env_table *env_tab, char *meta_tag); int native_to_ndmp_loglevel(int NdmpLoglevel, int debuglevel, NIS *nis); bool ndmp_build_client_job(JCR *jcr, CLIENTRES *client, STORERES *store, int operation, struct ndm_job_param *job); bool ndmp_build_storage_job(JCR *jcr, STORERES *store, bool init_tape, bool init_robot, int operation, struct ndm_job_param *job); extern "C" void ndmp_loghandler(struct ndmlog *log, char *tag, int level, char *msg); void ndmp_do_query(UAContext *ua, ndm_job_param *ndmp_job, int NdmpLoglevel); /* * NDMP FHDB specific helpers. */ void ndmp_store_attribute_record(JCR *jcr, char *fname, char *linked_fname, char *attributes, int8_t FileType, uint64_t Node, uint64_t Offset); void ndmp_convert_fstat(ndmp9_file_stat *fstat, int32_t FileIndex, int8_t *FileType, POOL_MEM &attribs); /* * FHDB using LMDB. */ void ndmp_fhdb_lmdb_register(struct ndmlog *ixlog); void ndmp_fhdb_lmdb_unregister(struct ndmlog *ixlog); void ndmp_fhdb_lmdb_process_db(struct ndmlog *ixlog); /* * FHDB using in memory tree. */ void ndmp_fhdb_mem_register(struct ndmlog *ixlog); void ndmp_fhdb_mem_unregister(struct ndmlog *ixlog); void ndmp_fhdb_mem_process_db(struct ndmlog *ixlog); #endif bareos-Release-14.2.6/src/dird/ndmp_dma_restore.c000066400000000000000000000673301263011562700216500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2015 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Restore specific NDMP Data Management Application (DMA) routines * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if HAVE_NDMP #define NDMP_NEED_ENV_KEYWORDS 1 #include "ndmp/ndmagents.h" #include "ndmp_dma_priv.h" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Imported variables */ /* Forward referenced functions */ static char OKbootstrap[] = "3000 OK bootstrap\n"; /* * Walk the tree of selected files for restore and lookup the * correct fileid. Return the actual full pathname of the file * corresponding to the given fileid. */ static inline char *lookup_fileindex(JCR *jcr, int32_t FileIndex) { TREE_NODE *node, *parent; POOL_MEM restore_pathname, tmp; node = first_tree_node(jcr->restore_tree_root); while (node) { /* * See if this is the wanted FileIndex. */ if (node->FileIndex == FileIndex) { pm_strcpy(restore_pathname, node->fname); /* * Walk up the parent until we hit the head of the list. */ for (parent = node->parent; parent; parent = parent->parent) { pm_strcpy(tmp, restore_pathname.c_str()); Mmsg(restore_pathname, "%s/%s", parent->fname, tmp.c_str()); } if (bstrncmp(restore_pathname.c_str(), "/@NDMP/", 7)) { return bstrdup(restore_pathname.c_str()); } } node = next_tree_node(node); } return NULL; } /* * Add a filename to the files we want to restore. * * The RFC says this: * * original_path - The original path name of the data to be recovered, * relative to the backup root. If original_path is the null * string, the server shall recover all data contained in the * backup image. * * destination_path, name, other_name * - Together, these identify the absolute path name to which * data are to be recovered. * * If name is the null string: * - destination_path identifies the name to which the data * identified by original_path are to be recovered. * - other_name must be the null string. * * If name is not the null string: * - destination_path, when concatenated with the server- * specific path name delimiter and name, identifies the * name to which the data identified by original_path are * to be recovered. * * If other_name is not the null string: * - destination_path, when concatenated with the server- * specific path name delimiter and other_name, * identifies the alternate name-space name of the data * to be recovered. The definition of such alternate * name-space is server-specific. * * Neither name nor other_name may contain a path name delimiter. * * Under no circumstance may destination_path be the null string. * * If intermediate directories that lead to the path name to * recover do not exist, the server should create them. */ static inline void add_to_namelist(struct ndm_job_param *job, char *filename, char *restore_prefix, char *name, char *other_name, int64_t node) { ndmp9_name nl; POOL_MEM destination_path; memset(&nl, 0, sizeof(ndmp9_name)); /* * See if the filename is an absolute pathname. */ if (*filename == '\0') { pm_strcpy(destination_path, restore_prefix); } else if (*filename == '/') { Mmsg(destination_path, "%s%s", restore_prefix, filename); } else { Mmsg(destination_path, "%s/%s", restore_prefix, filename); } nl.original_path = filename; nl.destination_path = destination_path.c_str(); nl.name = name; nl.other_name = other_name; nl.node = node; ndma_store_nlist(&job->nlist_tab, &nl); } /* * See in the tree with selected files what files were selected to be restored. */ static inline int set_files_to_restore(JCR *jcr, struct ndm_job_param *job, int32_t FileIndex, char *restore_prefix) { int len; int cnt = 0; TREE_NODE *node, *parent; POOL_MEM restore_pathname, tmp; node = first_tree_node(jcr->restore_tree_root); while (node) { /* * See if this is the wanted FileIndex and the user asked to extract it. */ if (node->FileIndex == FileIndex && node->extract) { pm_strcpy(restore_pathname, node->fname); /* * Walk up the parent until we hit the head of the list. */ for (parent = node->parent; parent; parent = parent->parent) { pm_strcpy(tmp, restore_pathname.c_str()); Mmsg(restore_pathname, "%s/%s", parent->fname, tmp.c_str()); } /* * We only want to restore the non pseudo NDMP names e.g. not the full backup stream name. */ if (!bstrncmp(restore_pathname.c_str(), "/@NDMP/", 7)) { /* * See if we need to strip the prefix from the filename. */ len = strlen(restore_prefix); if (bstrncmp(restore_pathname.c_str(), restore_prefix, len)) { add_to_namelist(job, restore_pathname.c_str() + len, restore_prefix, (char *)"", (char *)"", NDMP_INVALID_U_QUAD); } else { add_to_namelist(job, restore_pathname.c_str(), restore_prefix, (char *)"", (char *)"", NDMP_INVALID_U_QUAD); } cnt++; } } node = next_tree_node(node); } return cnt; } /* * Database handler that handles the returned environment data for a given JobId. */ static int ndmp_env_handler(void *ctx, int num_fields, char **row) { struct ndm_env_table *envtab; ndmp9_pval pv; if (row[0] && row[1]) { envtab = (struct ndm_env_table *)ctx; pv.name = row[0]; pv.value = row[1]; ndma_store_env_list(envtab, &pv); } return 0; } /* * Fill the NDMP restore environment table with the data for the data agent to act on. */ static inline bool fill_restore_environment(JCR *jcr, int32_t current_fi, struct ndm_job_param *job) { int i; char *bp; ndmp9_pval pv; FILESETRES *fileset; char *restore_pathname, *original_pathname, *restore_prefix, *level; POOL_MEM tape_device; POOL_MEM destination_path; ndmp_backup_format_option *nbf_options; /* * See if we know this backup format and get it options. */ nbf_options = ndmp_lookup_backup_format_options(job->bu_type); /* * Lookup the current fileindex and map it to an actual pathname. */ restore_pathname = lookup_fileindex(jcr, current_fi); if (!restore_pathname) { return false; } else { /* * Skip over the /@NDMP prefix. */ original_pathname = restore_pathname + 6; } /* * See if there is a level embedded in the pathname. */ bp = strrchr(original_pathname, '%'); if (bp) { *bp++ = '\0'; level = bp; } else { level = NULL; } /* * Lookup the environment stack saved during the backup so we can restore it. */ if (!db_get_ndmp_environment_string(jcr, jcr->db, &jcr->jr, ndmp_env_handler, &job->env_tab)) { /* * Fallback code try to build a environment stack that is good enough to * restore this NDMP backup. This is used when the data is not available in * the database when its either expired or when an old NDMP backup is restored * where the whole environment was not saved. */ if (!nbf_options || nbf_options->uses_file_history) { /* * We asked during the NDMP backup to receive file history info. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_HIST]; pv.value = ndmp_env_values[NDMP_ENV_VALUE_YES]; ndma_store_env_list(&job->env_tab, &pv); } /* * Tell the data agent what type of restore stream to expect. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_TYPE]; pv.value = job->bu_type; ndma_store_env_list(&job->env_tab, &pv); /* * Tell the data agent that this is a NDMP backup which uses a level indicator. */ if (level) { pv.name = ndmp_env_keywords[NDMP_ENV_KW_LEVEL]; pv.value = level; ndma_store_env_list(&job->env_tab, &pv); } /* * Tell the data engine what was backuped. */ pv.name = ndmp_env_keywords[NDMP_ENV_KW_FILESYSTEM]; pv.value = original_pathname; ndma_store_env_list(&job->env_tab, &pv); } /* * Lookup any meta tags that need to be added. */ fileset = jcr->res.fileset; for (i = 0; i < fileset->num_includes; i++) { int j; char *item; INCEXE *ie = fileset->include_items[i]; /* * Loop over each file = entry of the fileset. */ for (j = 0; j < ie->name_list.size(); j++) { item = (char *)ie->name_list.get(j); /* * See if the original path matches. */ if (bstrcasecmp(item, original_pathname)) { int k, l; FOPTS *fo; for (k = 0; k < ie->num_opts; k++) { fo = ie->opts_list[i]; /* * Parse all specific META tags for this option block. */ for (l = 0; l < fo->meta.size(); l++) { ndmp_parse_meta_tag(&job->env_tab, (char *)fo->meta.get(l)); } } } } } /* * See where to restore the data. */ restore_prefix = NULL; if (jcr->where) { restore_prefix = jcr->where; } else { restore_prefix = jcr->res.job->RestoreWhere; } if (!restore_prefix) { return false; } /* * Tell the data engine where to restore. */ if (nbf_options && nbf_options->restore_prefix_relative) { switch (*restore_prefix) { case '^': /* * Use the restore_prefix as an absolute restore prefix. * We skip the leading ^ that is the trigger for absolute restores. */ pm_strcpy(destination_path, restore_prefix + 1); break; default: /* * Use the restore_prefix as an relative restore prefix. */ if (strlen(restore_prefix) == 1 && *restore_prefix == '/') { pm_strcpy(destination_path, original_pathname); } else { pm_strcpy(destination_path, restore_prefix); pm_strcat(destination_path, original_pathname); } } } else { if (strlen(restore_prefix) == 1 && *restore_prefix == '/') { /* * Use the original pathname as restore prefix. */ pm_strcpy(destination_path, original_pathname); } else { /* * Use the restore_prefix as an absolute restore prefix. */ pm_strcpy(destination_path, restore_prefix); } } pv.name = ndmp_env_keywords[NDMP_ENV_KW_PREFIX]; pv.value = destination_path.c_str(); ndma_store_env_list(&job->env_tab, &pv); if (!nbf_options || nbf_options->needs_namelist) { if (set_files_to_restore(jcr, job, current_fi, destination_path.c_str()) == 0) { /* * There is no specific filename selected so restore everything. */ add_to_namelist(job, (char *)"", destination_path.c_str(), (char *)"", (char *)"", NDMP_INVALID_U_QUAD); } } /* * If we have a paired storage definition we put the storage daemon * auth key and the filesystem into the tape device name of the * NDMP session. This way the storage daemon can link the NDMP * data and the normal save session together. */ if (jcr->store_bsock) { Mmsg(tape_device, "%s@%s", jcr->sd_auth_key, restore_pathname + 6); job->tape_device = bstrdup(tape_device.c_str()); } free(restore_pathname); return true; } /* * Extract any post backup statistics. */ static inline bool extract_post_restore_stats(JCR *jcr, struct ndm_session *sess) { bool retval = true; struct ndmmedia *media; /* * See if an error was raised during the backup session. */ if (sess->error_raised) { return false; } /* * See if there is any media error. */ for (media = sess->control_acb->job.result_media_tab.head; media; media = media->next) { if (media->media_open_error || media->media_io_error || media->label_io_error || media->label_mismatch || media->fmark_error) { retval = false; } } /* * Update the Job statistics from the NDMP statistics. */ jcr->JobBytes += sess->control_acb->job.bytes_read; jcr->JobFiles++; return retval; } /* * Setup a NDMP restore session. */ bool do_ndmp_restore_init(JCR *jcr) { free_wstorage(jcr); /* we don't write */ if (!jcr->restore_tree_root) { Jmsg(jcr, M_FATAL, 0, _("Cannot NDMP restore without a file selection.\n")); return false; } return true; } static inline int ndmp_wait_for_job_termination(JCR *jcr) { jcr->setJobStatus(JS_Running); /* * Force cancel in SD if failing, but not for Incomplete jobs * so that we let the SD despool. */ Dmsg4(100, "cancel=%d FDJS=%d JS=%d SDJS=%d\n", jcr->is_canceled(), jcr->FDJobStatus, jcr->JobStatus, jcr->SDJobStatus); if (jcr->is_canceled() || (!jcr->res.job->RescheduleIncompleteJobs)) { Dmsg3(100, "FDJS=%d JS=%d SDJS=%d\n", jcr->FDJobStatus, jcr->JobStatus, jcr->SDJobStatus); cancel_storage_daemon_job(jcr); } /* * Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */ wait_for_storage_daemon_termination(jcr); jcr->FDJobStatus = JS_Terminated; if (jcr->JobStatus != JS_Terminated) { return jcr->JobStatus; } if (jcr->FDJobStatus != JS_Terminated) { return jcr->FDJobStatus; } return jcr->SDJobStatus; } /* * The bootstrap is stored in a file, so open the file, and loop * through it processing each storage device in turn. If the * storage is different from the prior one, we open a new connection * to the new storage and do a restore for that part. * * This permits handling multiple storage daemons for a single * restore. E.g. your Full is stored on tape, and Incrementals * on disk. */ static inline bool do_ndmp_restore_bootstrap(JCR *jcr) { int cnt; BSOCK *sd; BSR *bsr; NIS *nis = NULL; int32_t current_fi; bootstrap_info info; BSR_FINDEX *fileindex; struct ndm_session ndmp_sess; struct ndm_job_param ndmp_job; bool session_initialized = false; bool retval = false; int NdmpLoglevel; if (jcr->res.client->ndmp_loglevel > me->ndmp_loglevel) { NdmpLoglevel = jcr->res.client->ndmp_loglevel; } else { NdmpLoglevel = me->ndmp_loglevel; } /* * We first parse the BSR ourself so we know what to restore. */ jcr->bsr = parse_bsr(jcr, jcr->RestoreBootstrap); if (!jcr->bsr) { Jmsg(jcr, M_FATAL, 0, _("Error parsing bootstrap file.\n")); goto bail_out; } /* * Setup all paired read storage. */ set_paired_storage(jcr); if (!jcr->res.pstore) { Jmsg(jcr, M_FATAL, 0, _("Read storage %s doesn't point to storage definition with paired storage option.\n"), jcr->res.rstore->name()); goto bail_out; } /* * Open the bootstrap file */ if (!open_bootstrap_file(jcr, info)) { goto bail_out; } nis = (NIS *)malloc(sizeof(NIS)); memset(nis, 0, sizeof(NIS)); /* * Read the bootstrap file */ bsr = jcr->bsr; while (!feof(info.bs)) { if (!select_next_rstore(jcr, info)) { goto cleanup; } /* * Initialize the ndmp restore job. We build the generic job once per storage daemon * and reuse the job definition for each seperate sub-restore we perform as * part of the whole job. We only free the env_table between every sub-restore. */ if (!ndmp_build_client_job(jcr, jcr->res.client, jcr->res.pstore, NDM_JOB_OP_EXTRACT, &ndmp_job)) { goto cleanup; } /* * Open a message channel connection with the Storage * daemon. This is to let him know that our client * will be contacting him for a backup session. * */ Dmsg0(10, "Open connection with storage daemon\n"); jcr->setJobStatus(JS_WaitSD); /* * Start conversation with Storage daemon */ if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { goto cleanup; } sd = jcr->store_bsock; /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) { goto cleanup; } jcr->setJobStatus(JS_Running); /* * Send the bootstrap file -- what Volumes/files to restore */ if (!send_bootstrap_file(jcr, sd, info) || !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) { goto cleanup; } if (!sd->fsend("run")) { goto cleanup; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { goto cleanup; } Dmsg0(50, "Storage daemon connection OK\n"); /* * Walk each fileindex of the current BSR record. Each different fileindex is * a seperate NDMP stream. */ cnt = 0; for (fileindex = bsr->FileIndex; fileindex; fileindex = fileindex->next) { for (current_fi = fileindex->findex; current_fi <= fileindex->findex2; current_fi++) { /* * See if this is the first Restore NDMP stream or not. For NDMP we can have multiple Backup * runs as part of the same Job. When we are restoring data from a Native Storage Daemon * we let it know to expect a next restore session. It will generate a new authorization * key so we wait for the nextrun_ready conditional variable to be raised by the msg_thread. */ if (jcr->store_bsock && cnt > 0) { jcr->store_bsock->fsend("nextrun"); P(mutex); pthread_cond_wait(&jcr->nextrun_ready, &mutex); V(mutex); } /* * Perform the actual NDMP job. * Initialize a new NDMP session */ memset(&ndmp_sess, 0, sizeof(ndmp_sess)); ndmp_sess.conn_snooping = (me->ndmp_snooping) ? 1 : 0; ndmp_sess.control_agent_enabled = 1; ndmp_sess.param = (struct ndm_session_param *)malloc(sizeof(struct ndm_session_param)); memset(ndmp_sess.param, 0, sizeof(struct ndm_session_param)); ndmp_sess.param->log.deliver = ndmp_loghandler; ndmp_sess.param->log_level = native_to_ndmp_loglevel(NdmpLoglevel, debug_level, nis); nis->jcr = jcr; ndmp_sess.param->log.ctx = nis; ndmp_sess.param->log_tag = bstrdup("DIR-NDMP"); /* * Initialize the session structure. */ if (ndma_session_initialize(&ndmp_sess)) { goto cleanup_ndmp; } session_initialized = true; /* * Copy the actual job to perform. */ jcr->jr.FileIndex = current_fi; if (bsr->sessid && bsr->sesstime) { jcr->jr.VolSessionId = bsr->sessid->sessid; jcr->jr.VolSessionTime = bsr->sesstime->sesstime; } else { Jmsg(jcr, M_FATAL, 0, _("Wrong BSR missing sessid and/or sesstime\n")); goto cleanup_ndmp; } memcpy(&ndmp_sess.control_acb->job, &ndmp_job, sizeof(struct ndm_job_param)); if (!fill_restore_environment(jcr, current_fi, &ndmp_sess.control_acb->job)) { goto cleanup_ndmp; } ndma_job_auto_adjust(&ndmp_sess.control_acb->job); if (!ndmp_validate_job(jcr, &ndmp_sess.control_acb->job)) { goto cleanup_ndmp; } /* * Commission the session for a run. */ if (ndma_session_commission(&ndmp_sess)) { goto cleanup_ndmp; } /* * Setup the DMA. */ if (ndmca_connect_control_agent(&ndmp_sess)) { goto cleanup_ndmp; } ndmp_sess.conn_open = 1; ndmp_sess.conn_authorized = 1; /* * Let the DMA perform its magic. */ if (ndmca_control_agent(&ndmp_sess) != 0) { goto cleanup_ndmp; } /* * See if there were any errors during the restore. */ if (!extract_post_restore_stats(jcr, &ndmp_sess)) { goto cleanup_ndmp; } /* * Reset the NDMP session states. */ ndma_session_decommission(&ndmp_sess); /* * Cleanup the job after it has run. */ ndma_destroy_env_list(&ndmp_sess.control_acb->job.env_tab); ndma_destroy_env_list(&ndmp_sess.control_acb->job.result_env_tab); ndma_destroy_nlist(&ndmp_sess.control_acb->job.nlist_tab); /* * Release any tape device name allocated. */ if (ndmp_sess.control_acb->job.tape_device) { free(ndmp_sess.control_acb->job.tape_device); ndmp_sess.control_acb->job.tape_device = NULL; } /* * Destroy the session. */ ndma_session_destroy(&ndmp_sess); /* * Free the param block. */ free(ndmp_sess.param->log_tag); free(ndmp_sess.param); ndmp_sess.param = NULL; /* * Reset the initialized state so we don't try to cleanup again. */ session_initialized = false; /* * Keep track that we finished this part of the restore. */ cnt++; } } /* * Tell the storage daemon we are done. */ jcr->store_bsock->fsend("finish"); wait_for_storage_daemon_termination(jcr); } /* * Jump to the generic cleanup done for every Job. */ retval = true; goto cleanup; cleanup_ndmp: /* * Only need to cleanup when things are initialized. */ if (session_initialized) { ndma_destroy_env_list(&ndmp_sess.control_acb->job.env_tab); ndma_destroy_env_list(&ndmp_sess.control_acb->job.result_env_tab); ndma_destroy_nlist(&ndmp_sess.control_acb->job.nlist_tab); if (ndmp_sess.control_acb->job.tape_device) { free(ndmp_sess.control_acb->job.tape_device); } /* * Destroy the session. */ ndma_session_destroy(&ndmp_sess); } if (ndmp_sess.param) { free(ndmp_sess.param->log_tag); free(ndmp_sess.param); } cleanup: if (nis) { free(nis); } free_paired_storage(jcr); close_bootstrap_file(info); bail_out: free_tree(jcr->restore_tree_root); jcr->restore_tree_root = NULL; return retval; } /* * Run a NDMP restore session. */ bool do_ndmp_restore(JCR *jcr) { JOB_DBR rjr; /* restore job record */ int status; memset(&rjr, 0, sizeof(rjr)); jcr->jr.JobLevel = L_FULL; /* Full restore */ if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); goto bail_out; } Dmsg0(20, "Updated job start record\n"); Dmsg1(20, "RestoreJobId=%d\n", jcr->res.job->RestoreJobId); /* * Validate the Job to have a NDMP client. */ if (!ndmp_validate_client(jcr)) { return false; } if (!jcr->RestoreBootstrap) { Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n" "You probably ran a restore job directly. All restore jobs must\n" "be run using the restore command.\n")); goto bail_out; } /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job); /* * Read the bootstrap file and do the restore */ if (!do_ndmp_restore_bootstrap(jcr)) { goto bail_out; } /* * Wait for Job Termination */ status = ndmp_wait_for_job_termination(jcr); ndmp_restore_cleanup(jcr, status); return true; bail_out: return false; } /* * Cleanup a NDMP restore session. */ void ndmp_restore_cleanup(JCR *jcr, int TermCode) { char term_code[100]; const char *term_msg; int msg_type = M_INFO; Dmsg0(20, "In ndmp_restore_cleanup\n"); update_job_end(jcr, TermCode); if (jcr->unlink_bsr && jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); jcr->unlink_bsr = false; } if (job_canceled(jcr)) { cancel_storage_daemon_job(jcr); } switch (TermCode) { case JS_Terminated: if (jcr->ExpectedFiles > jcr->jr.JobFiles) { term_msg = _("Restore OK -- warning file count mismatch"); } else { term_msg = _("Restore OK"); } break; case JS_Warnings: term_msg = _("Restore OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Restore Error ***"); msg_type = M_ERROR; /* Generate error message */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; case JS_Canceled: term_msg = _("Restore Canceled"); if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; default: term_msg = term_code; sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode); break; } generate_restore_summary(jcr, msg_type, term_msg); Dmsg0(20, "Leaving ndmp_restore_cleanup\n"); } #else bool do_ndmp_restore_init(JCR *jcr) { Jmsg(jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); return false; } bool do_ndmp_restore(JCR *jcr) { Jmsg(jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); return false; } void ndmp_restore_cleanup(JCR *jcr, int TermCode) { Jmsg(jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); } #endif /* HAVE_NDMP */ bareos-Release-14.2.6/src/dird/ndmp_dma_storage.c000066400000000000000000000042611263011562700216230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2015 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Storage specific NDMP Data Management Application (DMA) routines * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if HAVE_NDMP #include "ndmp/ndmagents.h" #include "ndmp_dma_priv.h" /* Imported variables */ /* Forward referenced functions */ /* * Output the status of a storage daemon when its a normal storage * daemon accessed via the NDMP protocol or query the TAPE and ROBOT * agent of a native NDMP server. */ void do_ndmp_storage_status(UAContext *ua, STORERES *store, char *cmd) { /* * See if the storage is just a NDMP instance of a normal storage daemon. */ if (store->paired_storage) { do_native_storage_status(ua, store->paired_storage, cmd); } else { struct ndm_job_param ndmp_job; if (!ndmp_build_storage_job(ua->jcr, store, true, /* Query Tape Agent */ true, /* Query Robot Agent */ NDM_JOB_OP_QUERY_AGENTS, &ndmp_job)) { return; } ndmp_do_query(ua, &ndmp_job, me->ndmp_loglevel); } } #else void do_ndmp_storage_status(UAContext *ua, STORERES *store, char *cmd) { Jmsg(ua->jcr, M_FATAL, 0, _("NDMP protocol not supported\n")); } #endif /* HAVE_NDMP */ bareos-Release-14.2.6/src/dird/ndmp_fhdb_helpers.c000066400000000000000000000111061263011562700217570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2015-2015 Planets Communications B.V. Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * FHDB helper routines for NDMP Data Management Application (DMA) * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if HAVE_NDMP #include "ndmp/ndmagents.h" /* * Store all entries in the FHDB as hardlinked items to the NDMP archive in the backup catalog. */ void ndmp_store_attribute_record(JCR *jcr, char *fname, char *linked_fname, char *attributes, int8_t FileType, uint64_t Node, uint64_t Offset) { ATTR_DBR *ar; ar = jcr->ar; if (jcr->cached_attribute) { Dmsg2(400, "Cached attr. Stream=%d fname=%s\n", ar->Stream, ar->fname); if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error: ERR=%s"), db_strerror(jcr->db)); return; } jcr->cached_attribute = false; } /* * We only update some fields of this structure the rest is already filled * before by initial attributes saved by the tape agent in the storage daemon. */ jcr->ar->fname = fname; jcr->ar->link = linked_fname; jcr->ar->attr = attributes; jcr->ar->Stream = STREAM_UNIX_ATTRIBUTES; jcr->ar->FileType = FileType; if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error: ERR=%s"), db_strerror(jcr->db)); return; } } void ndmp_convert_fstat(ndmp9_file_stat *fstat, int32_t FileIndex, int8_t *FileType, POOL_MEM &attribs) { struct stat statp; /* * Convert the NDMP file_stat structure into a UNIX one. */ memset(&statp, 0, sizeof(statp)); /* * If we got a valid mode of the file fill the UNIX stat struct. */ if (fstat->mode.valid == NDMP9_VALIDITY_VALID) { switch (fstat->ftype) { case NDMP9_FILE_DIR: statp.st_mode = fstat->mode.value | S_IFDIR; *FileType = FT_DIREND; break; case NDMP9_FILE_FIFO: statp.st_mode = fstat->mode.value | S_IFIFO; *FileType = FT_FIFO; break; case NDMP9_FILE_CSPEC: statp.st_mode = fstat->mode.value | S_IFCHR; *FileType = FT_SPEC; break; case NDMP9_FILE_BSPEC: statp.st_mode = fstat->mode.value | S_IFBLK; *FileType = FT_SPEC; break; case NDMP9_FILE_REG: statp.st_mode = fstat->mode.value | S_IFREG; *FileType = FT_REG; break; case NDMP9_FILE_SLINK: statp.st_mode = fstat->mode.value | S_IFLNK; *FileType = FT_LNK; break; case NDMP9_FILE_SOCK: statp.st_mode = fstat->mode.value | S_IFSOCK; *FileType = FT_SPEC; break; case NDMP9_FILE_REGISTRY: statp.st_mode = fstat->mode.value | S_IFREG; *FileType = FT_REG; break; case NDMP9_FILE_OTHER: statp.st_mode = fstat->mode.value | S_IFREG; *FileType = FT_REG; break; default: break; } if (fstat->mtime.valid == NDMP9_VALIDITY_VALID) { statp.st_mtime = fstat->mtime.value; } if (fstat->atime.valid == NDMP9_VALIDITY_VALID) { statp.st_atime = fstat->atime.value; } if (fstat->ctime.valid == NDMP9_VALIDITY_VALID) { statp.st_ctime = fstat->ctime.value; } if (fstat->uid.valid == NDMP9_VALIDITY_VALID) { statp.st_uid = fstat->uid.value; } if (fstat->gid.valid == NDMP9_VALIDITY_VALID) { statp.st_gid = fstat->gid.value; } if (fstat->links.valid == NDMP9_VALIDITY_VALID) { statp.st_nlink = fstat->links.value; } } /* * Encode a stat structure into an ASCII string. */ encode_stat(attribs.c_str(), &statp, sizeof(statp), FileIndex, STREAM_UNIX_ATTRIBUTES); } #endif bareos-Release-14.2.6/src/dird/ndmp_fhdb_lmdb.c000066400000000000000000000115141263011562700212360ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2015-2015 Planets Communications B.V. Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * FHDB using LMDB for NDMP Data Management Application (DMA) * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if defined(HAVE_NDMP) && defined(HAVE_LMDB) #include "ndmp/ndmagents.h" #include "ndmp_dma_priv.h" extern "C" int bndmp_fhdb_lmdb_add_file(struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat) { NIS *nis; nis = (NIS *)ixlog->ctx; nis->jcr->lock(); nis->jcr->JobFiles++; nis->jcr->unlock(); if (nis->save_filehist) { int8_t FileType = 0; char namebuf[NDMOS_CONST_PATH_MAX]; POOL_MEM attribs(PM_FNAME), pathname(PM_FNAME); ndmcstr_from_str(raw_name, namebuf, sizeof(namebuf)); /* * Every file entry is releative from the filesystem currently being backuped. */ Dmsg2(100, "bndmp_add_file: New filename ==> %s/%s\n", nis->filesystem, namebuf); if (nis->jcr->ar) { /* * See if this is the top level entry of the tree e.g. len == 0 */ if (strlen(namebuf) == 0) { ndmp_convert_fstat(fstat, nis->FileIndex, &FileType, attribs); pm_strcpy(pathname, nis->filesystem); pm_strcat(pathname, "/"); return 0; } else { ndmp_convert_fstat(fstat, nis->FileIndex, &FileType, attribs); pm_strcpy(pathname, nis->filesystem); pm_strcat(pathname, "/"); pm_strcat(pathname, namebuf); if (FileType == FT_DIREND) { /* * A directory needs to end with a slash. */ pm_strcat(pathname, "/"); } } ndmp_store_attribute_record(nis->jcr, pathname.c_str(), nis->virtual_filename, attribs.c_str(), FileType, 0, (fstat->fh_info.valid == NDMP9_VALIDITY_VALID) ? fstat->fh_info.value : 0); } } return 0; } extern "C" int bndmp_fhdb_lmdb_add_dir(struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node) { NIS *nis; char namebuf[NDMOS_CONST_PATH_MAX]; ndmcstr_from_str(raw_name, namebuf, sizeof(namebuf)); /* * Ignore . and .. directory entries. */ if (bstrcmp(namebuf, ".") || bstrcmp(namebuf, "..")) { return 0; } nis = (NIS *)ixlog->ctx; nis->jcr->lock(); nis->jcr->JobFiles++; nis->jcr->unlock(); if (nis->save_filehist) { Dmsg3(100, "bndmp_add_dir: New filename ==> %s [%llu] - [%llu]\n", namebuf, dir_node, node); } return 0; } extern "C" int bndmp_fhdb_lmdb_add_node(struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat) { NIS *nis; nis = (NIS *)ixlog->ctx; if (nis->save_filehist) { Dmsg1(100, "bndmp_add_node: New node [%llu]\n", node); } return 0; } extern "C" int bndmp_fhdb_lmdb_add_dirnode_root(struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node) { NIS *nis; nis = (NIS *)ixlog->ctx; if (nis->save_filehist) { Dmsg1(100, "bndmp_add_dirnode_root: New root node [%llu]\n", root_node); } return 0; } /* * This glues the NDMP File Handle DB with internal code. */ void ndmp_fhdb_lmdb_register_callback_hooks(struct ndmlog *ixlog) { NIS *nis = (NIS *)ixlog->ctx; struct ndm_fhdb_callbacks fhdb_callbacks; /* * Register the FileHandleDB callbacks. */ fhdb_callbacks.add_file = bndmp_fhdb_lmdb_add_file; fhdb_callbacks.add_dir = bndmp_fhdb_lmdb_add_dir; fhdb_callbacks.add_node = bndmp_fhdb_lmdb_add_node; fhdb_callbacks.add_dirnode_root = bndmp_fhdb_lmdb_add_dirnode_root; ndmfhdb_register_callbacks(ixlog, &fhdb_callbacks); } void ndmp_fhdb_lmdb_unregister(struct ndmlog *ixlog) { NIS *nis = (NIS *)ixlog->ctx; ndmfhdb_unregister_callbacks(ixlog); } void ndmp_fhdb_lmdb_process_db(struct ndmlog *ixlog) { NIS *nis = (NIS *)ixlog->ctx; } #endif bareos-Release-14.2.6/src/dird/ndmp_fhdb_mem.c000066400000000000000000000630211263011562700210760ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2015-2015 Planets Communications B.V. Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * In memory FHDB for NDMP Data Management Application (DMA) * * Marco van Wieringen, May 2015 */ #include "bareos.h" #include "dird.h" #if HAVE_NDMP #include "ndmp/ndmagents.h" #include "ndmp_dma_priv.h" #define B_PAGE_SIZE 4096 #define MIN_PAGES 128 #define MAX_PAGES 2400 #define MAX_BUF_SIZE (MAX_PAGES * B_PAGE_SIZE) /* approx 10MB */ /* * Lightweight version of Bareos tree layout for holding the NDMP * filehandle index database. See lib/tree.[ch] for the full version. */ struct ndmp_fhdb_mem { struct ndmp_fhdb_mem *next; /* Next buffer */ int rem; /* Remaining bytes */ char *mem; /* Memory pointer */ char first[1]; /* First byte */ }; struct ndmp_fhdb_node { /* * KEEP sibling as the first member to avoid having to do initialization of child */ rblink sibling; rblist child; char *fname; /* File name */ char *attr; /* Encoded stat struct */ int8_t FileType; /* Type of File */ int32_t FileIndex; /* File index */ uint64_t Offset; /* File Offset in NDMP stream */ uint64_t inode; /* Inode nr */ uint16_t fname_len; /* Filename length */ ndmp_fhdb_node *next; ndmp_fhdb_node *parent; }; typedef struct ndmp_fhdb_node N_TREE_NODE; struct ndmp_fhdb_root { /* * KEEP sibling as the first member to avoid having to do initialization of child */ rblink sibling; rblist child; char *fname; /* File name */ char *attr; /* Encoded stat struct */ int8_t FileType; /* Type of File */ int32_t FileIndex; /* File index */ uint64_t Offset; /* File Offset in NDMP stream */ uint64_t inode; /* Inode nr */ uint16_t fname_len; /* Filename length */ ndmp_fhdb_node *next; ndmp_fhdb_node *parent; /* * The above ^^^ must be identical to a ndmp_fhdb_node structure * The below vvv is only for the root of the tree. */ ndmp_fhdb_node *first; /* first entry in the tree */ ndmp_fhdb_node *last; /* last entry in the tree */ ndmp_fhdb_mem *mem; /* tree memory */ uint32_t total_size; /* total bytes allocated */ uint32_t blocks; /* total mallocs */ ndmp_fhdb_node *cached_parent; /* cached parent */ }; typedef struct ndmp_fhdb_root N_TREE_ROOT; struct ooo_metadata { hlink link; uint64_t dir_node; N_TREE_NODE *nt_node; }; typedef struct ooo_metadata OOO_MD; struct fhdb_state { N_TREE_ROOT *fhdb_root; htable *out_of_order_metadata; }; /* * Lightweight version of Bareos tree functions for holding the NDMP * filehandle index database. See lib/tree.[ch] for the full version. */ static void malloc_buf(N_TREE_ROOT *root, int size) { struct ndmp_fhdb_mem *mem; mem = (struct ndmp_fhdb_mem *)malloc(size); root->total_size += size; root->blocks++; mem->next = root->mem; root->mem = mem; mem->mem = mem->first; mem->rem = (char *)mem + size - mem->mem; } /* * Note, we allocate a big buffer in the tree root from which we * allocate nodes. This runs more than 100 times as fast as directly * using malloc() for each of the nodes. */ static inline N_TREE_ROOT *ndmp_fhdb_new_tree() { int count = 512; N_TREE_ROOT *root; uint32_t size; root = (N_TREE_ROOT *)malloc(sizeof(N_TREE_ROOT)); memset(root, 0, sizeof(N_TREE_ROOT)); /* * Assume filename + node = 40 characters average length */ size = count * (BALIGN(sizeof(N_TREE_ROOT)) + 40); if (size > (MAX_BUF_SIZE / 2)) { size = MAX_BUF_SIZE; } Dmsg2(400, "count=%d size=%d\n", count, size); malloc_buf(root, size); return root; } /* * Allocate bytes for filename in tree structure. * Keep the pointers properly aligned by allocating sizes that are aligned. */ static inline char *ndmp_fhdb_tree_alloc(N_TREE_ROOT *root, int size) { char *buf; int asize = BALIGN(size); if (root->mem->rem < asize) { uint32_t mb_size; if (root->total_size >= (MAX_BUF_SIZE / 2)) { mb_size = MAX_BUF_SIZE; } else { mb_size = MAX_BUF_SIZE / 2; } malloc_buf(root, mb_size); } root->mem->rem -= asize; buf = root->mem->mem; root->mem->mem += asize; return buf; } /* * This routine can be called to release the previously allocated tree node. */ static inline void ndmp_fhdb_free_tree_node(N_TREE_ROOT *root) { int asize = BALIGN(sizeof(N_TREE_NODE)); root->mem->rem += asize; root->mem->mem -= asize; } /* * Create a new tree node. */ static N_TREE_NODE *ndmp_fhdb_new_tree_node(N_TREE_ROOT *root) { N_TREE_NODE *node; int size = sizeof(N_TREE_NODE); node = (N_TREE_NODE *)ndmp_fhdb_tree_alloc(root, size); memset(node, 0, size); return node; } /* * This routine frees the whole tree */ static inline void ndmp_fhdb_free_tree(N_TREE_ROOT *root) { struct ndmp_fhdb_mem *mem, *rel; uint32_t freed_blocks = 0; for (mem = root->mem; mem; ) { rel = mem; mem = mem->next; free(rel); freed_blocks++; } Dmsg3(100, "Total size=%u blocks=%u freed_blocks=%u\n", root->total_size, root->blocks, freed_blocks); free(root); garbage_collect_memory(); return; } static int node_compare_by_name(void *item1, void *item2) { N_TREE_NODE *tn1 = (N_TREE_NODE *)item1; N_TREE_NODE *tn2 = (N_TREE_NODE *)item2; if (tn1->fname[0] > tn2->fname[0]) { return 1; } else if (tn1->fname[0] < tn2->fname[0]) { return -1; } return strcmp(tn1->fname, tn2->fname); } static int node_compare_by_id(void *item1, void *item2) { N_TREE_NODE *tn1 = (N_TREE_NODE *)item1; N_TREE_NODE *tn2 = (N_TREE_NODE *)item2; if (tn1->inode > tn2->inode) { return 1; } else if (tn1->inode < tn2->inode) { return -1; } else { return 0; } } static N_TREE_NODE *search_and_insert_tree_node(char *fname, int32_t FileIndex, uint64_t inode, N_TREE_ROOT *root, N_TREE_NODE *parent) { N_TREE_NODE *node, *found_node; node = ndmp_fhdb_new_tree_node(root); if (inode) { node->inode = inode; found_node = (N_TREE_NODE *)parent->child.insert(node, node_compare_by_id); } else { node->fname = fname; found_node = (N_TREE_NODE *)parent->child.insert(node, node_compare_by_name); } /* * Already in list ? */ if (found_node != node) { /* * Free node allocated above. */ ndmp_fhdb_free_tree_node(root); return found_node; } /* * Its was not found, but now inserted. */ node->parent = parent; node->FileIndex = FileIndex; node->fname_len = strlen(fname); /* * Allocate a new entry with 2 bytes extra e.g. the extra slash * needed for directories and the \0. */ node->fname = ndmp_fhdb_tree_alloc(root, node->fname_len + 2); bstrncpy(node->fname, fname, node->fname_len + 1); /* * Maintain a linear chain of nodes. */ if (!root->first) { root->first = node; root->last = node; } else { root->last->next = node; root->last = node; } return node; } static N_TREE_NODE *search_and_insert_tree_node(N_TREE_NODE *node, N_TREE_ROOT *root, N_TREE_NODE *parent) { N_TREE_NODE *found_node; /* * Insert the node into the right parent. We should always insert * this node and never get back a found_node that is not the same * as the original node but if we do we better return as then there * is nothing todo. */ found_node = (N_TREE_NODE *)parent->child.insert(node, node_compare_by_id); if (found_node != node) { return found_node; } node->parent = parent; /* * Maintain a linear chain of nodes. */ if (!root->first) { root->first = node; root->last = node; } else { root->last->next = node; root->last = node; } return node; } /* * Recursively search the tree for a certain inode number. */ static N_TREE_NODE *find_tree_node(N_TREE_NODE *node, uint64_t inode) { N_TREE_NODE match_node; N_TREE_NODE *found_node, *walker; match_node.inode = inode; /* * Start searching in the children of this node. */ found_node = (N_TREE_NODE *)node->child.search(&match_node, node_compare_by_id); if (found_node) { return found_node; } /* * The node we are searching for is not one of the top nodes so need to search deeper. */ foreach_rblist(walker, &node->child) { /* * See if the node has any children otherwise no need to search it. */ if (walker->child.empty()) { continue; } found_node = find_tree_node(walker, inode); if (found_node) { return found_node; } } return (N_TREE_NODE *)NULL; } /* * Recursively search the tree for a certain inode number. */ static N_TREE_NODE *find_tree_node(N_TREE_ROOT *root, uint64_t inode) { N_TREE_NODE match_node; N_TREE_NODE *found_node, *walker; /* * See if this is a request for the root of the tree. */ if (root->inode == inode) { return (N_TREE_NODE *)root; } match_node.inode = inode; /* * First do the easy lookup e.g. is this inode part of the parent of the current parent. */ if (root->cached_parent && root->cached_parent->parent) { found_node = (N_TREE_NODE *)root->cached_parent->parent->child.search(&match_node, node_compare_by_id); if (found_node) { return found_node; } } /* * Start searching from the root node. */ found_node = (N_TREE_NODE *)root->child.search(&match_node, node_compare_by_id); if (found_node) { return found_node; } /* * The node we are searching for is not one of the top nodes so need to search deeper. */ foreach_rblist(walker, &root->child) { /* * See if the node has any children otherwise no need to search it. */ if (walker->child.empty()) { continue; } found_node = find_tree_node(walker, inode); if (found_node) { return found_node; } } return (N_TREE_NODE *)NULL; } extern "C" int bndmp_fhdb_mem_add_file(struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat) { NIS *nis = (NIS *)ixlog->ctx; nis->jcr->lock(); nis->jcr->JobFiles++; nis->jcr->unlock(); if (nis->save_filehist) { int8_t FileType = 0; char namebuf[NDMOS_CONST_PATH_MAX]; POOL_MEM attribs(PM_FNAME), pathname(PM_FNAME); ndmcstr_from_str(raw_name, namebuf, sizeof(namebuf)); /* * Every file entry is releative from the filesystem currently being backuped. */ Dmsg2(100, "bndmp_fhdb_mem_add_file: New filename ==> %s/%s\n", nis->filesystem, namebuf); if (nis->jcr->ar) { /* * See if this is the top level entry of the tree e.g. len == 0 */ if (strlen(namebuf) == 0) { ndmp_convert_fstat(fstat, nis->FileIndex, &FileType, attribs); pm_strcpy(pathname, nis->filesystem); pm_strcat(pathname, "/"); return 0; } else { ndmp_convert_fstat(fstat, nis->FileIndex, &FileType, attribs); pm_strcpy(pathname, nis->filesystem); pm_strcat(pathname, "/"); pm_strcat(pathname, namebuf); if (FileType == FT_DIREND) { /* * A directory needs to end with a slash. */ pm_strcat(pathname, "/"); } } ndmp_store_attribute_record(nis->jcr, pathname.c_str(), nis->virtual_filename, attribs.c_str(), FileType, 0, (fstat->fh_info.valid == NDMP9_VALIDITY_VALID) ? fstat->fh_info.value : 0); } } return 0; } /* * This inserts a piece of meta data we receive out or order in a hash table * for later processing. Most NDMP DMAs send things kind of in order some do not * and for those we have this workaround. */ static inline void add_out_of_order_metadata(NIS *nis, N_TREE_ROOT *fhdb_root, const char *namebuf, ndmp9_u_quad dir_node, ndmp9_u_quad node) { N_TREE_NODE *nt_node; OOO_MD *md_entry = NULL; htable *meta_data = ((struct fhdb_state *)nis->fhdb_state)->out_of_order_metadata; nt_node = ndmp_fhdb_new_tree_node(fhdb_root); nt_node->inode = node; nt_node->FileIndex = fhdb_root->FileIndex; nt_node->fname_len = strlen(namebuf); /* * Allocate a new entry with 2 bytes extra e.g. the extra slash * needed for directories and the \0. */ nt_node->fname = ndmp_fhdb_tree_alloc(fhdb_root, nt_node->fname_len + 2); bstrncpy(nt_node->fname, namebuf, nt_node->fname_len + 1); /* * See if we already allocated the htable. */ if (!meta_data) { uint32_t nr_pages, nr_items, item_size; nr_pages = MIN_PAGES; item_size = sizeof(OOO_MD); nr_items = (nr_pages * B_PAGE_SIZE) / item_size; meta_data = (htable *)malloc(sizeof(htable)); meta_data->init(md_entry, &md_entry->link, nr_items, nr_pages); ((struct fhdb_state *)nis->fhdb_state)->out_of_order_metadata = meta_data; } /* * Create a new entry and insert it into the hash with the node number as key. */ md_entry = (OOO_MD *)meta_data->hash_malloc(sizeof(OOO_MD)); md_entry->dir_node = dir_node; md_entry->nt_node = nt_node; meta_data->insert((uint64_t)node, (void *)md_entry); Dmsg2(100, "bndmp_fhdb_mem_add_dir: Added out of order metadata entry for node %llu with parent %llu\n", node, dir_node); } extern "C" int bndmp_fhdb_mem_add_dir(struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node) { NIS *nis = (NIS *)ixlog->ctx; char namebuf[NDMOS_CONST_PATH_MAX]; ndmcstr_from_str(raw_name, namebuf, sizeof(namebuf)); /* * Ignore . and .. directory entries. */ if (bstrcmp(namebuf, ".") || bstrcmp(namebuf, "..")) { return 0; } nis->jcr->lock(); nis->jcr->JobFiles++; nis->jcr->unlock(); if (nis->save_filehist) { N_TREE_ROOT *fhdb_root; Dmsg3(100, "bndmp_fhdb_mem_add_dir: New filename ==> %s [%llu] - [%llu]\n", namebuf, dir_node, node); fhdb_root = ((struct fhdb_state *)nis->fhdb_state)->fhdb_root; if (!fhdb_root) { Jmsg(nis->jcr, M_FATAL, 0, _("NDMP protocol error, FHDB add_dir call before add_dirnode_root.\n")); return 1; } /* * See if this entry is in the cached parent. */ if (fhdb_root->cached_parent && fhdb_root->cached_parent->inode == dir_node) { search_and_insert_tree_node(namebuf, fhdb_root->FileIndex, node, fhdb_root, fhdb_root->cached_parent); } else { /* * Not the cached parent search the tree where it need to be put. */ fhdb_root->cached_parent = find_tree_node(fhdb_root, dir_node); if (fhdb_root->cached_parent) { search_and_insert_tree_node(namebuf, fhdb_root->FileIndex, node, fhdb_root, fhdb_root->cached_parent); } else { add_out_of_order_metadata(nis, fhdb_root, namebuf, dir_node, node); } } } return 0; } /* * This tries recursivly to add the missing parents to the tree. */ static N_TREE_NODE *insert_metadata_parent_node(htable *meta_data, N_TREE_ROOT *fhdb_root, uint64_t dir_node) { N_TREE_NODE *parent; OOO_MD *md_entry; Dmsg1(100, "bndmp_fhdb_mem_add_dir: Inserting node for parent %llu into tree\n", dir_node); /* * lookup the dir_node */ md_entry = (OOO_MD *)meta_data->lookup(dir_node); if (!md_entry || !md_entry->nt_node) { /* * If we got called the parent node is not in the current tree if we * also cannot find it in the metadata things are inconsistent so give up. */ return (N_TREE_NODE *)NULL; } /* * Lookup the parent of this new node we are about to insert. */ parent = find_tree_node(fhdb_root, md_entry->dir_node); if (!parent) { /* * If our parent doesn't exist try finding it and inserting it. */ parent = insert_metadata_parent_node(meta_data, fhdb_root, md_entry->dir_node); if (!parent) { /* * If by recursive calling insert_metadata_parent_node we cannot create linked * set of parent nodes our metadata is really inconsistent so give up. */ return (N_TREE_NODE *)NULL; } } /* * Now we have a working parent in the current tree so we can add the this parent node. */ parent = search_and_insert_tree_node(md_entry->nt_node, fhdb_root, parent); /* * Keep track we used this entry. */ md_entry->nt_node = (N_TREE_NODE *)NULL; return parent; } /* * This processes all saved out of order metadata and adds these entries to the tree. * Only used for NDMP DMAs which are sending their metadata fully at random. */ static inline bool process_out_of_order_metadata(htable *meta_data, N_TREE_ROOT *fhdb_root) { OOO_MD *md_entry; foreach_htable(md_entry, meta_data) { /* * Alread visited ? */ if (!md_entry->nt_node) { continue; } Dmsg1(100, "bndmp_fhdb_mem_add_dir: Inserting node for %llu into tree\n", md_entry->nt_node->inode); /* * See if this entry is in the cached parent. */ if (fhdb_root->cached_parent && fhdb_root->cached_parent->inode == md_entry->dir_node) { search_and_insert_tree_node(md_entry->nt_node, fhdb_root, fhdb_root->cached_parent); } else { /* * See if parent exists in tree. */ fhdb_root->cached_parent = find_tree_node(fhdb_root, md_entry->dir_node); if (fhdb_root->cached_parent) { search_and_insert_tree_node(md_entry->nt_node, fhdb_root, fhdb_root->cached_parent); } else { fhdb_root->cached_parent = insert_metadata_parent_node(meta_data, fhdb_root, md_entry->dir_node); if (!fhdb_root->cached_parent) { /* * The metadata seems to be fully inconsistent. */ Dmsg0(100, "bndmp_fhdb_mem_add_dir: Inconsistent metadata, giving up\n"); return false; } search_and_insert_tree_node(md_entry->nt_node, fhdb_root, fhdb_root->cached_parent); } } } return true; } extern "C" int bndmp_fhdb_mem_add_node(struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat) { NIS *nis = (NIS *)ixlog->ctx; if (nis->save_filehist) { int attr_size; int8_t FileType = 0; N_TREE_ROOT *fhdb_root; N_TREE_NODE *wanted_node; POOL_MEM attribs(PM_FNAME); htable *meta_data = ((struct fhdb_state *)nis->fhdb_state)->out_of_order_metadata; Dmsg1(100, "bndmp_fhdb_mem_add_node: New node [%llu]\n", node); fhdb_root = ((struct fhdb_state *)nis->fhdb_state)->fhdb_root; if (!fhdb_root) { Jmsg(nis->jcr, M_FATAL, 0, _("NDMP protocol error, FHDB add_node call before add_dir.\n")); return 1; } if (meta_data) { if (!process_out_of_order_metadata(meta_data, fhdb_root)) { Jmsg(nis->jcr, M_FATAL, 0, _("NDMP protocol error, FHDB unable to process out of order metadata.\n")); meta_data->destroy(); free(meta_data); ((struct fhdb_state *)nis->fhdb_state)->out_of_order_metadata = NULL; return 1; } meta_data->destroy(); free(meta_data); ((struct fhdb_state *)nis->fhdb_state)->out_of_order_metadata = NULL; } wanted_node = find_tree_node(fhdb_root, node); if (!wanted_node) { Jmsg(nis->jcr, M_FATAL, 0, _("NDMP protocol error, FHDB add_node request for unknown node %llu.\n"), node); return 1; } ndmp_convert_fstat(fstat, nis->FileIndex, &FileType, attribs); attr_size = strlen(attribs.c_str()) + 1; wanted_node->attr = ndmp_fhdb_tree_alloc(fhdb_root, attr_size); bstrncpy(wanted_node->attr, attribs, attr_size); wanted_node->FileType = FileType; if (fstat->fh_info.valid == NDMP9_VALIDITY_VALID) { wanted_node->Offset = fstat->fh_info.value; } if (FileType == FT_DIREND) { /* * A directory needs to end with a slash. */ strcat(wanted_node->fname, "/"); } } return 0; } extern "C" int bndmp_fhdb_mem_add_dirnode_root(struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node) { NIS *nis = (NIS *)ixlog->ctx; if (nis->save_filehist) { N_TREE_ROOT *fhdb_root; struct fhdb_state *fhdb_state; Dmsg1(100, "bndmp_fhdb_mem_add_dirnode_root: New root node [%llu]\n", root_node); fhdb_state = ((struct fhdb_state *)nis->fhdb_state); fhdb_root = fhdb_state->fhdb_root; if (fhdb_root) { Jmsg(nis->jcr, M_FATAL, 0, _("NDMP protocol error, FHDB add_dirnode_root call more then once.\n")); return 1; } fhdb_state->fhdb_root = ndmp_fhdb_new_tree(); fhdb_root = fhdb_state->fhdb_root; fhdb_root->inode = root_node; fhdb_root->FileIndex = nis->FileIndex; fhdb_root->fname_len = strlen(nis->filesystem); /* * Allocate a new entry with 2 bytes extra e.g. the extra slash * needed for directories and the \0. */ fhdb_root->fname = ndmp_fhdb_tree_alloc(fhdb_root, fhdb_root->fname_len + 2); bstrncpy(fhdb_root->fname, nis->filesystem, fhdb_root->fname_len + 1); fhdb_root->cached_parent = (N_TREE_NODE *)fhdb_root; } return 0; } /* * This glues the NDMP File Handle DB with internal code. */ void ndmp_fhdb_mem_register(struct ndmlog *ixlog) { NIS *nis = (NIS *)ixlog->ctx; struct ndm_fhdb_callbacks fhdb_callbacks; /* * Register the FileHandleDB callbacks. */ fhdb_callbacks.add_file = bndmp_fhdb_mem_add_file; fhdb_callbacks.add_dir = bndmp_fhdb_mem_add_dir; fhdb_callbacks.add_node = bndmp_fhdb_mem_add_node; fhdb_callbacks.add_dirnode_root = bndmp_fhdb_mem_add_dirnode_root; ndmfhdb_register_callbacks(ixlog, &fhdb_callbacks); nis->fhdb_state = malloc(sizeof(struct fhdb_state)); memset(nis->fhdb_state, 0, sizeof(struct fhdb_state)); } void ndmp_fhdb_mem_unregister(struct ndmlog *ixlog) { NIS *nis = (NIS *)ixlog->ctx; if (nis->fhdb_state) { N_TREE_ROOT *fhdb_root; fhdb_root = ((struct fhdb_state *)nis->fhdb_state)->fhdb_root; if (fhdb_root) { ndmp_fhdb_free_tree(fhdb_root); } free(nis->fhdb_state); nis->fhdb_state = NULL; } ndmfhdb_unregister_callbacks(ixlog); } void ndmp_fhdb_mem_process_db(struct ndmlog *ixlog) { N_TREE_ROOT *fhdb_root; NIS *nis = (NIS *)ixlog->ctx; struct fhdb_state *fhdb_state; fhdb_state = ((struct fhdb_state *)nis->fhdb_state); fhdb_root = fhdb_state->fhdb_root; if (fhdb_root) { if (nis->jcr->ar) { N_TREE_NODE *node, *parent; POOL_MEM fname, tmp; /* * Store the toplevel entry of the tree. */ Dmsg2(100, "==> %s [%s]\n", fhdb_root->fname, fhdb_root->attr); ndmp_store_attribute_record(nis->jcr, fhdb_root->fname, nis->virtual_filename, fhdb_root->attr, fhdb_root->FileType, fhdb_root->inode, fhdb_root->Offset); /* * Store all the other entries in the tree. */ for (node = fhdb_root->first; node; node = node->next) { pm_strcpy(fname, node->fname); /* * Walk up the parent until we hit the head of the list. * As directories are store including there trailing slash we * can just concatenate the two parts. */ for (parent = node->parent; parent; parent = parent->parent) { pm_strcpy(tmp, fname.c_str()); pm_strcpy(fname, parent->fname); pm_strcat(fname, tmp.c_str()); } /* * Now we have the full pathname of the file in fname. * Store the entry as a hardlinked entry to the original NDMP archive. */ Dmsg2(100, "==> %s [%s]\n", fname.c_str(), node->attr); ndmp_store_attribute_record(nis->jcr, fname.c_str(), nis->virtual_filename, node->attr, node->FileType, node->inode, node->Offset); } } /* * Destroy the tree. */ ndmp_fhdb_free_tree(fhdb_root); fhdb_state->fhdb_root = NULL; } } #endif bareos-Release-14.2.6/src/dird/newvol.c000066400000000000000000000132751263011562700176370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- newvol.c -- creates new Volumes in * catalog Media table from the * LabelFormat specification. * * Kern Sibbald, May MMI * * This routine runs as a thread and must be thread reentrant. * * Basic tasks done here: * If possible create a new Media entry */ #include "bareos.h" #include "dird.h" /* * Forward referenced functions */ static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr); static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr); /* * Automatic Volume name creation using the LabelFormat * * The media record must have the PoolId filled in when * calling this routine. */ bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORERES *store) { bool retval = false; POOL_DBR pr; memset(&pr, 0, sizeof(pr)); /* * See if we can create a new Volume */ db_lock(jcr->db); pr.PoolId = mr->PoolId; if (!db_get_pool_record(jcr, jcr->db, &pr)) { goto bail_out; } if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) { memset(mr, 0, sizeof(MEDIA_DBR)); set_pool_dbr_defaults_in_media_dbr(mr, &pr); jcr->VolumeName[0] = 0; bstrncpy(mr->MediaType, jcr->res.wstore->media_type, sizeof(mr->MediaType)); generate_plugin_event(jcr, bDirEventNewVolume); /* return void... */ if (jcr->VolumeName[0] && is_volume_name_legal(NULL, jcr->VolumeName)) { bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName)); } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') { /* * Check for special characters */ if (is_volume_name_legal(NULL, pr.LabelFormat)) { /* * No special characters, so apply simple algorithm */ if (!create_simple_name(jcr, mr, &pr)) { goto bail_out; } } else { /* * Found special characters, so try full substitution */ if (!perform_full_name_substitution(jcr, mr, &pr)) { goto bail_out; } if (!is_volume_name_legal(NULL, mr->VolumeName)) { Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"), mr->VolumeName); goto bail_out; } } } else { goto bail_out; } pr.NumVols++; mr->Enabled = VOL_ENABLED; set_storageid_in_mr(store, mr); if (db_create_media_record(jcr, jcr->db, mr) && db_update_pool_record(jcr, jcr->db, &pr)) { Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName); Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName); retval = true; goto bail_out; } else { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); } } bail_out: db_unlock(jcr->db); return retval; } static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) { char num[20]; db_int64_ctx ctx; POOL_MEM query(PM_MESSAGE), name(PM_NAME); char ed1[50]; /* See if volume already exists */ mr->VolumeName[0] = 0; pm_strcpy(name, pr->LabelFormat); ctx.value = 0; Mmsg(query, "SELECT MAX(MediaId) FROM Media,Pool WHERE Pool.PoolId=%s", edit_int64(pr->PoolId, ed1)); if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) { Jmsg(jcr, M_WARNING, 0, _("SQL failed, but ignored. ERR=%s\n"), db_strerror(jcr->db)); ctx.value = pr->NumVols+1; } for (int i=(int)ctx.value+1; i<(int)ctx.value+100; i++) { MEDIA_DBR tmr; memset(&tmr, 0, sizeof(tmr)); sprintf(num, "%04d", i); bstrncpy(tmr.VolumeName, name.c_str(), sizeof(tmr.VolumeName)); bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName)); if (db_get_media_record(jcr, jcr->db, &tmr)) { Jmsg(jcr, M_WARNING, 0, _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"), tmr.VolumeName); continue; } bstrncpy(mr->VolumeName, name.c_str(), sizeof(mr->VolumeName)); bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName)); break; /* Got good name */ } if (mr->VolumeName[0] == 0) { Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n")); return false; } return true; } /* * Perform full substitution on Label */ static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) { bool ok = false; POOLMEM *label = get_pool_memory(PM_FNAME); jcr->NumVols = pr->NumVols; if (variable_expansion(jcr, pr->LabelFormat, &label)) { bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName)); ok = true; } free_pool_memory(label); return ok; } bareos-Release-14.2.6/src/dird/next_vol.c000066400000000000000000000402231263011562700201540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- next_vol -- handles finding the next volume for append. * * Split out of catreq.c August MMIII catalog request from the Storage daemon. * * Kern Sibbald, March MMI */ #include "bareos.h" #include "dird.h" static int const dbglvl = 50; /* debug level */ /* Set storage id if possible */ void set_storageid_in_mr(STORERES *store, MEDIA_DBR *mr) { if (store != NULL) { mr->StorageId = store->StorageId; } } /* * Items needed: * mr.PoolId must be set * mr.ScratchPoolId could be set (used if create==true) * jcr->wstore * jcr->db * jcr->pool * MEDIA_DBR mr with PoolId set * create -- whether or not to create a new volume */ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, bool create, bool prune) { int retry = 0; bool ok; bool InChanger; STORERES *store = jcr->res.wstore; bstrncpy(mr->MediaType, store->media_type, sizeof(mr->MediaType)); Dmsg3(dbglvl, "find_next_vol_for_append: JobId=%u PoolId=%d, MediaType=%s\n", (uint32_t)jcr->JobId, (int)mr->PoolId, mr->MediaType); /* * If we are using an Autochanger, restrict Volume * search to the Autochanger on the first pass */ InChanger = store->autochanger; /* * Find the Next Volume for Append */ db_lock(jcr->db); for ( ;; ) { bstrncpy(mr->VolStatus, "Append", sizeof(mr->VolStatus)); /* want only appendable volumes */ /* * 1. Look for volume with "Append" status. */ set_storageid_in_mr(store, mr); /* put StorageId in new record */ ok = db_find_next_volume(jcr, jcr->db, index, InChanger, mr); if (!ok) { /* * No volume found, apply algorithm */ Dmsg4(dbglvl, "after find_next_vol ok=%d index=%d InChanger=%d Vstat=%s\n", ok, index, InChanger, mr->VolStatus); /* * 2. Try finding a recycled volume */ ok = find_recycled_volume(jcr, InChanger, mr, store); set_storageid_in_mr(store, mr); /* put StorageId in new record */ Dmsg2(dbglvl, "find_recycled_volume ok=%d FW=%d\n", ok, mr->FirstWritten); if (!ok) { /* * 3. Try recycling any purged volume */ ok = recycle_oldest_purged_volume(jcr, InChanger, mr, store); set_storageid_in_mr(store, mr); /* put StorageId in new record */ if (!ok) { /* * 4. Try pruning Volumes */ if (prune) { Dmsg0(dbglvl, "Call prune_volumes\n"); prune_volumes(jcr, InChanger, mr, store); } ok = recycle_oldest_purged_volume(jcr, InChanger, mr, store); set_storageid_in_mr(store, mr); /* put StorageId in new record */ if (!ok && create) { Dmsg4(dbglvl, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n", ok, index, InChanger, mr->VolStatus); /* * 5. Try pulling a volume from the Scratch pool */ ok = get_scratch_volume(jcr, InChanger, mr, store); set_storageid_in_mr(store, mr); /* put StorageId in new record */ Dmsg4(dbglvl, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n", ok, index, InChanger, mr->VolStatus); } /* * If we are using an Autochanger and have not found * a volume, retry looking for any volume. */ if (!ok && InChanger) { InChanger = false; continue; /* retry again accepting any volume */ } } } if (!ok && create) { /* * 6. Try "creating" a new Volume */ ok = newVolume(jcr, mr, store); } /* * Look at more drastic ways to find an Appendable Volume */ if (!ok && (jcr->res.pool->purge_oldest_volume || jcr->res.pool->recycle_oldest_volume)) { Dmsg2(dbglvl, "No next volume found. PurgeOldest=%d\n RecyleOldest=%d", jcr->res.pool->purge_oldest_volume, jcr->res.pool->recycle_oldest_volume); /* Find oldest volume to recycle */ set_storageid_in_mr(store, mr); /* update storage id */ ok = db_find_next_volume(jcr, jcr->db, -1, InChanger, mr); set_storageid_in_mr(store, mr); /* update storageid */ Dmsg1(dbglvl, "Find oldest=%d Volume\n", ok); if (ok && prune) { UAContext *ua; Dmsg0(dbglvl, "Try purge Volume.\n"); /* * 7. Try to purging oldest volume only if not UA calling us. */ ua = new_ua_context(jcr); if (jcr->res.pool->purge_oldest_volume && create) { Jmsg(jcr, M_INFO, 0, _("Purging oldest volume \"%s\"\n"), mr->VolumeName); ok = purge_jobs_from_volume(ua, mr); /* * 8. or try recycling the oldest volume */ } else if (jcr->res.pool->recycle_oldest_volume) { Jmsg(jcr, M_INFO, 0, _("Pruning oldest volume \"%s\"\n"), mr->VolumeName); ok = prune_volume(ua, mr); } free_ua_context(ua); if (ok) { ok = recycle_volume(jcr, mr); Dmsg1(dbglvl, "Recycle after purge oldest=%d\n", ok); } } } } Dmsg2(dbglvl, "VolJobs=%d FirstWritten=%d\n", mr->VolJobs, mr->FirstWritten); if (ok) { /* If we can use the volume, check if it is expired */ if (has_volume_expired(jcr, mr)) { if (retry++ < 200) { /* sanity check */ continue; /* try again from the top */ } else { Jmsg(jcr, M_ERROR, 0, _( "We seem to be looping trying to find the next volume. I give up.\n")); } } } break; } /* end for loop */ db_unlock(jcr->db); Dmsg1(dbglvl, "return ok=%d find_next_vol\n", ok); return ok; } /* * Check if any time limits or use limits have expired * if so, set the VolStatus appropriately. */ bool has_volume_expired(JCR *jcr, MEDIA_DBR *mr) { bool expired = false; char ed1[50]; /* * Check limits and expirations if "Append" and it has been used * i.e. mr->VolJobs > 0 * */ if (bstrcmp(mr->VolStatus, "Append") && mr->VolJobs > 0) { /* First handle Max Volume Bytes */ if ((mr->MaxVolBytes > 0 && mr->VolBytes >= mr->MaxVolBytes)) { Jmsg(jcr, M_INFO, 0, _("Max Volume bytes=%s exceeded. " "Marking Volume \"%s\" as Full.\n"), edit_uint64_with_commas(mr->MaxVolBytes, ed1), mr->VolumeName); bstrncpy(mr->VolStatus, "Full", sizeof(mr->VolStatus)); expired = true; /* Now see if Volume should only be used once */ } else if (mr->VolBytes > 0 && jcr->res.pool->use_volume_once) { Jmsg(jcr, M_INFO, 0, _("Volume used once. " "Marking Volume \"%s\" as Used.\n"), mr->VolumeName); bstrncpy(mr->VolStatus, "Used", sizeof(mr->VolStatus)); expired = true; /* Now see if Max Jobs written to volume */ } else if (mr->MaxVolJobs > 0 && mr->MaxVolJobs <= mr->VolJobs) { Jmsg(jcr, M_INFO, 0, _("Max Volume jobs=%s exceeded. " "Marking Volume \"%s\" as Used.\n"), edit_uint64_with_commas(mr->MaxVolJobs, ed1), mr->VolumeName); Dmsg3(dbglvl, "MaxVolJobs=%d JobId=%d Vol=%s\n", mr->MaxVolJobs, (uint32_t)jcr->JobId, mr->VolumeName); bstrncpy(mr->VolStatus, "Used", sizeof(mr->VolStatus)); expired = true; /* Now see if Max Files written to volume */ } else if (mr->MaxVolFiles > 0 && mr->MaxVolFiles <= mr->VolFiles) { Jmsg(jcr, M_INFO, 0, _("Max Volume files=%s exceeded. " "Marking Volume \"%s\" as Used.\n"), edit_uint64_with_commas(mr->MaxVolFiles, ed1), mr->VolumeName); bstrncpy(mr->VolStatus, "Used", sizeof(mr->VolStatus)); expired = true; /* Finally, check Use duration expiration */ } else if (mr->VolUseDuration > 0) { utime_t now = time(NULL); /* See if Vol Use has expired */ if (mr->VolUseDuration <= (now - mr->FirstWritten)) { Jmsg(jcr, M_INFO, 0, _("Max configured use duration=%s sec. exceeded. " "Marking Volume \"%s\" as Used.\n"), edit_uint64_with_commas(mr->VolUseDuration, ed1), mr->VolumeName); bstrncpy(mr->VolStatus, "Used", sizeof(mr->VolStatus)); expired = true; } } } if (expired) { /* Need to update media */ Dmsg1(dbglvl, "Vol=%s has expired update media record\n", mr->VolumeName); set_storageid_in_mr(NULL, mr); if (!db_update_media_record(jcr, jcr->db, mr)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating volume \"%s\". ERR=%s"), mr->VolumeName, db_strerror(jcr->db)); } } Dmsg2(dbglvl, "Vol=%s expired=%d\n", mr->VolumeName, expired); return expired; } /* * Try hard to recycle the current volume * * Returns: on failure - reason = NULL * on success - reason - pointer to reason */ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **reason) { int ok; *reason = NULL; /* Check if a duration or limit has expired */ if (has_volume_expired(jcr, mr)) { *reason = _("volume has expired"); /* Keep going because we may be able to recycle volume */ } /* * Now see if we can use the volume as is */ if (bstrcmp(mr->VolStatus, "Append") || bstrcmp(mr->VolStatus, "Recycle")) { *reason = NULL; return; } /* * Check if the Volume is already marked for recycling */ if (bstrcmp(mr->VolStatus, "Purged")) { if (recycle_volume(jcr, mr)) { Jmsg(jcr, M_INFO, 0, _("Recycled current volume \"%s\"\n"), mr->VolumeName); *reason = NULL; return; } else { /* In principle this shouldn't happen */ *reason = _("and recycling of current volume failed"); return; } } /* At this point, the volume is not valid for writing */ *reason = _("but should be Append, Purged or Recycle"); /* * What we're trying to do here is see if the current volume is * "recyclable" - ie. if we prune all expired jobs off it, is * it now possible to reuse it for the job that it is currently * needed for? */ if (!mr->Recycle) { *reason = _("volume has recycling disabled"); return; } /* * Check retention period from last written, but recycle to within * a minute to try to catch close calls ... */ if ((mr->LastWritten + mr->VolRetention - 60) < (utime_t)time(NULL) && jcr->res.pool->recycle_current_volume && (bstrcmp(mr->VolStatus, "Full") || bstrcmp(mr->VolStatus, "Used"))) { /* * Attempt prune of current volume to see if we can * recycle it for use. */ UAContext *ua; ua = new_ua_context(jcr); ok = prune_volume(ua, mr); free_ua_context(ua); if (ok) { /* If fully purged, recycle current volume */ if (recycle_volume(jcr, mr)) { Jmsg(jcr, M_INFO, 0, _("Recycled current volume \"%s\"\n"), mr->VolumeName); *reason = NULL; } else { *reason = _("but should be Append, Purged or Recycle (recycling of the " "current volume failed)"); } } else { *reason = _("but should be Append, Purged or Recycle (cannot automatically " "recycle current volume, as it still contains unpruned data " "or the Volume Retention time has not expired.)"); } } } static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store) { MEDIA_DBR smr; /* for searching scratch pool */ POOL_DBR spr, pr; bool ok = false; bool found = false; /* * Only one thread at a time can pull from the scratch pool */ P(mutex); /* * Get Pool record for Scratch Pool * choose between ScratchPoolId and Scratch * db_get_pool_record will first try ScratchPoolId, * and then try the pool named Scratch */ memset(&smr, 0, sizeof(smr)); memset(&spr, 0, sizeof(spr)); bstrncpy(spr.Name, "Scratch", sizeof(spr.Name)); spr.PoolId = mr->ScratchPoolId; if (db_get_pool_record(jcr, jcr->db, &spr)) { smr.PoolId = spr.PoolId; if (InChanger) { smr.StorageId = mr->StorageId; /* want only Scratch Volumes in changer */ } bstrncpy(smr.VolStatus, "Append", sizeof(smr.VolStatus)); /* want only appendable volumes */ bstrncpy(smr.MediaType, mr->MediaType, sizeof(smr.MediaType)); /* * If we do not find a valid Scratch volume, try * recycling any existing purged volumes, then * try to take the oldest volume. */ set_storageid_in_mr(store, &smr); /* put StorageId in new record */ if (db_find_next_volume(jcr, jcr->db, 1, InChanger, &smr)) { found = true; } else if (find_recycled_volume(jcr, InChanger, &smr, store)) { found = true; } else if (recycle_oldest_purged_volume(jcr, InChanger, &smr, store)) { found = true; } if (found) { POOL_MEM query(PM_MESSAGE); /* * Get pool record where the Scratch Volume will go to ensure * that we can add a Volume. */ memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, jcr->res.pool->name(), sizeof(pr.Name)); if (!db_get_pool_record(jcr, jcr->db, &pr)) { Jmsg(jcr, M_WARNING, 0, _("Unable to get Pool record: ERR=%s"), db_strerror(jcr->db)); goto bail_out; } /* Make sure there is room for another volume */ if (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) { Jmsg(jcr, M_WARNING, 0, _("Unable add Scratch Volume, Pool \"%s\" full MaxVols=%d\n"), jcr->res.pool->name(), pr.MaxVols); goto bail_out; } memcpy(mr, &smr, sizeof(MEDIA_DBR)); set_storageid_in_mr(store, mr); /* Set default parameters from current pool */ set_pool_dbr_defaults_in_media_dbr(mr, &pr); /* * set_pool_dbr_defaults_in_media_dbr set VolStatus to Append, * we could have Recycled media, also, we retain the old * RecyclePoolId. */ bstrncpy(mr->VolStatus, smr.VolStatus, sizeof(smr.VolStatus)); mr->RecyclePoolId = smr.RecyclePoolId; if (!db_update_media_record(jcr, jcr->db, mr)) { Jmsg(jcr, M_WARNING, 0, _("Failed to move Scratch Volume. ERR=%s\n"), db_strerror(jcr->db)); goto bail_out; } Jmsg(jcr, M_INFO, 0, _("Using Volume \"%s\" from 'Scratch' pool.\n"), mr->VolumeName); ok = true; } } bail_out: V(mutex); return ok; } bareos-Release-14.2.6/src/dird/protos.h000066400000000000000000000371661263011562700176650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Director external function prototypes */ /* admin.c */ bool do_admin_init(JCR *jcr); bool do_admin(JCR *jcr); void admin_cleanup(JCR *jcr, int TermCode); /* authenticate.c */ bool authenticate_storage_daemon(JCR *jcr, STORERES *store); bool authenticate_file_daemon(JCR *jcr); bool authenticate_user_agent(UAContext *ua); /* autoprune.c */ void do_autoprune(JCR *jcr); void prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store); /* autorecycle.c */ bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store); int recycle_volume(JCR *jcr, MEDIA_DBR *mr); bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store); /* backup.c */ int wait_for_job_termination(JCR *jcr, int timeout = 0); bool do_native_backup_init(JCR *jcr); bool do_native_backup(JCR *jcr); void native_backup_cleanup(JCR *jcr, int TermCode); void update_bootstrap_file(JCR *jcr); bool send_accurate_current_files(JCR *jcr); void generate_backup_summary(JCR *jcr, CLIENT_DBR *cr, int msg_type, const char *term_msg); /* vbackup.c */ bool do_native_vbackup_init(JCR *jcr); bool do_native_vbackup(JCR *jcr); void native_vbackup_cleanup(JCR *jcr, int TermCode); /* bsr.c */ RBSR *new_bsr(); void free_bsr(RBSR *bsr); bool complete_bsr(UAContext *ua, RBSR *bsr); uint32_t write_bsr_file(UAContext *ua, RESTORE_CTX &rx); void display_bsr_info(UAContext *ua, RESTORE_CTX &rx); uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, POOL_MEM *buffer); void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex); void add_findex_all(RBSR *bsr, uint32_t JobId); RBSR_FINDEX *new_findex(); void make_unique_restore_filename(UAContext *ua, POOLMEM **fname); void print_bsr(UAContext *ua, RESTORE_CTX &rx); bool open_bootstrap_file(JCR *jcr, bootstrap_info &info); bool send_bootstrap_file(JCR *jcr, BSOCK *sock, bootstrap_info &info); void close_bootstrap_file(bootstrap_info &info); /* catreq.c */ void catalog_request(JCR *jcr, BSOCK *bs); void catalog_update(JCR *jcr, BSOCK *bs); bool despool_attributes_from_file(JCR *jcr, const char *file); /* dird_conf.c */ const char *auth_protocol_to_str(uint32_t auth_protocol); const char *level_to_str(int level); extern "C" char *job_code_callback_director(JCR *jcr, const char*); bool populate_jobdefs(); /* expand.c */ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp); /* fd_cmds.c */ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time, bool verbose, bool start_job); bool send_include_list(JCR *jcr); bool send_exclude_list(JCR *jcr); bool send_level_command(JCR *jcr); bool send_bwlimit_to_fd(JCR *jcr, const char *Job); bool send_previous_restore_objects(JCR *jcr); int get_attributes_and_put_in_catalog(JCR *jcr); void get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId); int put_file_into_catalog(JCR *jcr, long file_index, char *fname, char *link, char *attr, int stream); int send_runscripts_commands(JCR *jcr); bool send_plugin_options(JCR *jcr); bool send_restore_objects(JCR *jcr, JobId_t JobId, bool send_global); bool cancel_file_daemon_job(UAContext *ua, JCR *jcr); void do_native_client_status(UAContext *ua, CLIENTRES *client, char *cmd); void do_client_resolve(UAContext *ua, CLIENTRES *client); /* getmsg.c */ bool response(JCR *jcr, BSOCK *fd, char *resp, const char *cmd, e_prtmsg prtmsg); /* inc_conf.c */ void find_used_compressalgos(POOL_MEM* compressalgos, JCR* jcr); /* job.c */ bool allow_duplicate_job(JCR *jcr); void set_jcr_defaults(JCR *jcr, JOBRES *job); void create_unique_job_name(JCR *jcr, const char *base_name); void update_job_end_record(JCR *jcr); bool get_or_create_client_record(JCR *jcr); bool get_or_create_fileset_record(JCR *jcr); DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name); bool get_level_since_time(JCR *jcr); void apply_pool_overrides(JCR *jcr, bool force = false); JobId_t run_job(JCR *jcr); bool cancel_job(UAContext *ua, JCR *jcr); void get_job_storage(USTORERES *store, JOBRES *job, RUNRES *run); void init_jcr_job_record(JCR *jcr); void update_job_end(JCR *jcr, int TermCode); void copy_rwstorage(JCR *jcr, alist *storage, const char *where); void set_rwstorage(JCR *jcr, USTORERES *store); void free_rwstorage(JCR *jcr); void copy_wstorage(JCR *jcr, alist *storage, const char *where); void set_wstorage(JCR *jcr, USTORERES *store); void free_wstorage(JCR *jcr); void copy_rstorage(JCR *jcr, alist *storage, const char *where); void set_rstorage(JCR *jcr, USTORERES *store); void free_rstorage(JCR *jcr); bool select_next_rstore(JCR *jcr, bootstrap_info &info); void set_paired_storage(JCR *jcr); void free_paired_storage(JCR *jcr); bool has_paired_storage(JCR *jcr); bool setup_job(JCR *jcr, bool suppress_output = false); void create_clones(JCR *jcr); int create_restore_bootstrap_file(JCR *jcr); void dird_free_jcr(JCR *jcr); void dird_free_jcr_pointers(JCR *jcr); void cancel_storage_daemon_job(JCR *jcr); bool run_console_command(JCR *jcr, const char *cmd); void sd_msg_thread_send_signal(JCR *jcr, int sig); /* jobq.c */ bool inc_read_store(JCR *jcr); void dec_read_store(JCR *jcr); /* migration.c */ bool do_migration(JCR *jcr); bool do_migration_init(JCR *jcr); void migration_cleanup(JCR *jcr, int TermCode); bool set_migration_wstorage(JCR *jcr, POOLRES *pool, POOLRES *next_pool, const char *where); /* mountreq.c */ void mount_request(JCR *jcr, BSOCK *bs, char *buf); /* msgchan.c */ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore, bool send_bsr = false); bool start_storage_daemon_message_thread(JCR *jcr); int bget_dirmsg(BSOCK *bs, bool allow_any_msg = false); void wait_for_storage_daemon_termination(JCR *jcr); /* ndmp_dma_backup.c */ bool do_ndmp_backup_init(JCR *jcr); bool do_ndmp_backup(JCR *jcr); void ndmp_backup_cleanup(JCR *jcr, int TermCode); /* ndmp_dma_generic.c */ bool ndmp_validate_client(JCR *jcr); bool ndmp_validate_storage(JCR *jcr); void do_ndmp_client_status(UAContext *ua, CLIENTRES *client, char *cmd); /* ndmp_dma_restore.c */ bool do_ndmp_restore_init(JCR *jcr); bool do_ndmp_restore(JCR *jcr); void ndmp_restore_cleanup(JCR *jcr, int TermCode); /* ndmp_dma_storage.c */ void do_ndmp_storage_status(UAContext *ua, STORERES *store, char *cmd); /* next_vol.c */ void set_storageid_in_mr(STORERES *store, MEDIA_DBR *mr); int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, bool create, bool purge); bool has_volume_expired(JCR *jcr, MEDIA_DBR *mr); void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **reason); bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store); /* newvol.c */ bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORERES *store); /* quota.c */ uint64_t fetch_remaining_quotas(JCR *jcr); bool check_hardquotas(JCR *jcr); bool check_softquotas(JCR *jcr); /* restore.c */ bool do_native_restore(JCR *jcr); bool do_native_restore_init(JCR *jcr); void native_restore_cleanup(JCR *jcr, int TermCode); void generate_restore_summary(JCR *jcr, int msg_type, const char *term_msg); /* sd_cmds.c */ bool connect_to_storage_daemon(JCR *jcr, int retry_interval, int max_retry_time, bool verbose); BSOCK *open_sd_bsock(UAContext *ua); void close_sd_bsock(UAContext *ua); char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive); dlist *get_vol_list_from_SD(UAContext *ua, STORERES *store, bool listall, bool scan); void free_vol_list(dlist *vol_list); int get_num_slots_from_SD(UAContext *ua); int get_num_drives_from_SD(UAContext *ua); bool cancel_storage_daemon_job(UAContext *ua, STORERES *store, char *JobId); bool cancel_storage_daemon_job(UAContext *ua, JCR *jcr, bool interactive = true); void cancel_storage_daemon_job(JCR *jcr); void do_native_storage_status(UAContext *ua, STORERES *store, char *cmd); bool transfer_volume(UAContext *ua, STORERES *store, int src_slot, int dst_slot); bool do_autochanger_volume_operation(UAContext *ua, STORERES *store, const char *operation, int drive, int slot); bool send_bwlimit_to_sd(JCR *jcr, const char *Job); bool do_storage_resolve(UAContext *ua, STORERES *store); bool do_storage_plugin_options(JCR *jcr); /* scheduler.c */ JCR *wait_for_next_job(char *one_shot_job_to_run); bool is_doy_in_last_week(int year, int doy); void term_scheduler(); /* stats.c */ int start_statistics_thread(void); void stop_statistics_thread(); void stats_job_started(); /* ua_acl.c */ bool acl_access_ok(UAContext *ua, int acl, const char *item, bool audit_event = false); bool acl_access_ok(UAContext *ua, int acl, const char *item, int len, bool audit_event = false); /* ua_audit.c */ bool audit_event_wanted(UAContext *ua, bool audit_event_enabled); void log_audit_event_acl_failure(UAContext *ua, int acl, const char *item); void log_audit_event_acl_success(UAContext *ua, int acl, const char *item); void log_audit_event_cmdline(UAContext *ua); /* ua_cmds.c */ bool do_a_command(UAContext *ua); bool do_a_dot_command(UAContext *ua); int qmessages_cmd(UAContext *ua, const char *cmd); bool open_client_db(UAContext *ua, bool use_private = false); bool open_db(UAContext *ua, bool use_private = false); void close_db(UAContext *ua); int create_pool(JCR *jcr, B_DB *db, POOLRES *pool, e_pool_op op); void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr); bool set_pooldbr_references(JCR *jcr, B_DB *db, POOL_DBR *pr, POOLRES *pool); void set_pooldbr_from_poolres(POOL_DBR *pr, POOLRES *pool, e_pool_op op); int update_pool_references(JCR *jcr, B_DB *db, POOLRES *pool); /* ua_impexp.c */ int import_cmd(UAContext *ua, const char *cmd); int export_cmd(UAContext *ua, const char *cmd); int move_cmd(UAContext *ua, const char *cmd); /* ua_input.c */ int get_cmd(UAContext *ua, const char *prompt, bool subprompt = false); bool get_pint(UAContext *ua, const char *prompt); bool get_yesno(UAContext *ua, const char *prompt); bool is_yesno(char *val, int *ret); int get_enabled(UAContext *ua, const char *val); void parse_ua_args(UAContext *ua); bool is_comment_legal(UAContext *ua, const char *name); /* ua_label.c */ bool is_volume_name_legal(UAContext *ua, const char *name); /* ua_update.c */ void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr); void update_slots_from_vol_list(UAContext *ua, STORERES *store, dlist *vol_list, char *slot_list); void update_inchanger_for_export(UAContext *ua, STORERES *store, dlist *vol_list, char *slot_list); /* ua_output.c */ void printit(void *ctx, const char *msg); bool complete_jcr_for_job(JCR *jcr, JOBRES *job, POOLRES *pool); RUNRES *find_next_run(RUNRES *run, JOBRES *job, utime_t &runtime, int ndays); /* ua_restore.c */ void find_storage_resource(UAContext *ua, RESTORE_CTX &rx, char *Storage, char *MediaType); /* ua_server.c */ void bsendmsg(void *ua_ctx, const char *fmt, ...); void berrormsg(void *ua_ctx, const char *fmt, ...); void bwarningmsg(void *ua_ctx, const char *fmt, ...); void binfomsg(void *ua_ctx, const char *fmt, ...); UAContext *new_ua_context(JCR *jcr); JCR *new_control_jcr(const char *base_name, int job_type); void free_ua_context(UAContext *ua); /* ua_select.c */ STORERES *select_storage_resource(UAContext *ua, bool autochanger_only = false); JOBRES *select_job_resource(UAContext *ua); JOBRES *select_enable_disable_job_resource(UAContext *ua, bool enable); JOBRES *select_restore_job_resource(UAContext *ua); CLIENTRES *select_client_resource(UAContext *ua); CLIENTRES *select_enable_disable_client_resource(UAContext *ua, bool enable); FILESETRES *select_fileset_resource(UAContext *ua); SCHEDRES *select_enable_disable_schedule_resource(UAContext *ua, bool enable); int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); int select_media_dbr(UAContext *ua, MEDIA_DBR *mr); bool select_pool_dbr(UAContext *ua, POOL_DBR *pr, const char *argk = "pool"); bool select_client_dbr(UAContext *ua, CLIENT_DBR *cr); void start_prompt(UAContext *ua, const char *msg); void add_prompt(UAContext *ua, const char *prompt); int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt); CATRES *get_catalog_resource(UAContext *ua); STORERES *get_storage_resource(UAContext *ua, bool use_default = false, bool autochanger_only = false); int get_storage_drive(UAContext *ua, STORERES *store); int get_storage_slot(UAContext *ua, STORERES *store); int get_media_type(UAContext *ua, char *MediaType, int max_media); bool get_pool_dbr(UAContext *ua, POOL_DBR *pr, const char *argk = "pool"); bool get_client_dbr(UAContext *ua, CLIENT_DBR *cr); POOLRES *get_pool_resource(UAContext *ua); JOBRES *get_restore_job(UAContext *ua); POOLRES *select_pool_resource(UAContext *ua); alist *select_jobs(UAContext *ua, const char *reason); CLIENTRES *get_client_resource(UAContext *ua); int get_job_dbr(UAContext *ua, JOB_DBR *jr); bool get_user_slot_list(UAContext *ua, char *slot_list, const char *argument, int num_slots); int find_arg_keyword(UAContext *ua, const char **list); int find_arg(UAContext *ua, const char *keyword); int find_arg_with_value(UAContext *ua, const char *keyword); int do_keyword_prompt(UAContext *ua, const char *msg, const char **list); int confirm_retention(UAContext *ua, utime_t *ret, const char *msg); bool get_level_from_name(JCR *jcr, const char *level_name); /* ua_status.c */ void list_dir_status_header(UAContext *ua); /* ua_tree.c */ bool user_select_files_from_tree(TREE_CTX *tree); int insert_tree_handler(void *ctx, int num_fields, char **row); /* ua_prune.c */ bool prune_files(UAContext *ua, CLIENTRES *client, POOLRES *pool); bool prune_jobs(UAContext *ua, CLIENTRES *client, POOLRES *pool, int JobType); bool prune_volume(UAContext *ua, MEDIA_DBR *mr); int job_delete_handler(void *ctx, int num_fields, char **row); int del_count_handler(void *ctx, int num_fields, char **row); int file_delete_handler(void *ctx, int num_fields, char **row); int get_prune_list_for_volume(UAContext *ua, MEDIA_DBR *mr, del_ctx *del); int exclude_running_jobs_from_list(del_ctx *prune_list); /* ua_purge.c */ bool is_volume_purged(UAContext *ua, MEDIA_DBR *mr, bool force = false); bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr); void purge_files_from_volume(UAContext *ua, MEDIA_DBR *mr); bool purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr, bool force = false); void purge_files_from_jobs(UAContext *ua, char *jobs); void purge_jobs_from_catalog(UAContext *ua, char *jobs); void purge_job_list_from_catalog(UAContext *ua, del_ctx &del); void purge_files_from_job_list(UAContext *ua, del_ctx &del); /* ua_run.c */ int rerun_cmd(UAContext *ua, const char *cmd); int run_cmd(UAContext *ua, const char *cmd); /* verify.c */ bool do_verify(JCR *jcr); bool do_verify_init(JCR *jcr); void verify_cleanup(JCR *jcr, int TermCode); bareos-Release-14.2.6/src/dird/query.sql000066400000000000000000000212731263011562700200440ustar00rootroot00000000000000# # This file contains sample queries # that you can possibly use with the bconsole query command. # # 1 :List up to 20 places where a File is saved regardless of the directory and Client *Enter Filename (no path): SELECT DISTINCT Job.JobId AS JobId, Client.Name AS Client, Path.Path,Filename.Name,StartTime,Level,JobFiles,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS SIZE_GB FROM Client,Job,File,Filename,Path WHERE Client.ClientId=Job.ClientId AND JobStatus IN ('T','W') AND Job.JobId=File.JobId AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId AND Filename.Name='%1' ORDER BY Job.StartTime LIMIT 20; # 2 :List where the most recent copies of a file with path of a Client are saved *Enter path with trailing slash: *Enter filename: *Enter Client name: SELECT DISTINCT Job.JobId,StartTime AS JobStartTime,VolumeName,Client.Name AS ClientName FROM Job,File,Path,Filename,Media,JobMedia,Client WHERE File.JobId=Job.JobId AND Path.Path='%1' AND Filename.Name='%2' AND Client.Name='%3' AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId AND Client.ClientId=Job.ClientId ORDER BY Job.StartTime DESC LIMIT 5; # 3 :List last 20 Full Backups for a Client *Enter Client name: SELECT DISTINCT Job.JobId,Client.Name AS Client,Starttime,JobFiles,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS GB FROM Client,Job,JobMedia,Media WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId AND Level='F' AND JobStatus IN ('T', 'W') AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId ORDER BY Job.StartTime DESC LIMIT 20; # 4 :List all backups for a Client after a specified time *Enter Client Name: *Enter time in YYYY-MM-DD HH:MM:SS format: SELECT DISTINCT Job.JobId,Client.Name AS Client,Level,StartTime,JobFiles,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS GB,Count(VolumeName) AS Volumes FROM Client,Job,JobMedia,Media WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId AND JobStatus IN ('T', 'W') AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId AND Job.StartTime >= '%2' GROUP BY Job.JobId,Client.Name,Level,StartTime,JobFiles,JobBytes ORDER BY Job.StartTime; # 5 :List all backups for a Client and COUNT the Volumes which been used *Enter Client Name: SELECT DISTINCT Job.JobId AS JobId,Client.Name AS Client, FileSet.FileSet AS FileSet,Level,StartTime, JobFiles,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS GB,Count(VolumeName) AS Volumes FROM Client,Job,JobMedia,Media,FileSet WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId AND Job.Type='B' AND Job.JobStatus IN ('T','W') AND Job.FileSetId=FileSet.FileSetId AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId GROUP BY Job.JobId,Client.Name,FileSet.FileSet,Level,StartTime,JobFiles,JobBytes ORDER BY Job.StartTime; # 6 :List Volume Attributes for a selected Volume *Enter Volume name: SELECT Slot,MaxVolBytes,VolCapacityBytes,VolStatus,Recycle,VolRetention, VolUseDuration,MaxVolJobs,MaxVolFiles FROM Media WHERE VolumeName='%1'; # 7 :List Volumes used by selected JobId *Enter JobId: SELECT DISTINCT Job.JobId,VolumeName FROM Job,JobMedia,Media WHERE Job.JobId=%1 AND Job.JobId=JobMedia.JobId AND JobMedia.MediaId=Media.MediaId; # 8 :List Volumes to Restore All Files *Enter Client Name: !DROP TABLE temp; !DROP TABLE temp2; CREATE TABLE temp (JobId BIGINT NOT NULL, JobTDate BIGINT, ClientId BIGINT, Level CHAR, StartTime TEXT, VolumeName TEXT, StartFile BIGINT, VolSessionId BIGINT, VolSessionTime BIGINT ); CREATE TABLE temp2 (JobId BIGINT NOT NULL, StartTime TEXT, VolumeName TEXT, Level CHAR, StartFile BIGINT, VolSessionId BIGINT, VolSessionTime BIGINT); # Select last Full save INSERT INTO temp SELECT Job.JobId,JobTDate,Job.ClientId,Job.Level, StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime FROM Client,Job,JobMedia,Media WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId AND Level='F' AND JobStatus IN ('T', 'W') AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId ORDER BY Job.JobTDate DESC LIMIT 1; # Copy into temp 2 getting all volumes of Full save INSERT INTO temp2 SELECT Job.JobId,Job.StartTime,Media.VolumeName,Job.Level, JobMedia.StartFile,Job.VolSessionId,Job.VolSessionTime FROM temp,Job,JobMedia,Media WHERE temp.JobId=Job.JobId AND Job.Level='F' AND Job.JobStatus IN ('T', 'W') AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId; # Now add subsequent incrementals INSERT INTO temp2 SELECT DISTINCT Job.JobId,Job.StartTime,Media.VolumeName, Job.Level,JobMedia.StartFile,Job.VolSessionId,Job.VolSessionTime FROM Job,temp,JobMedia,Media WHERE Job.JobTDate>temp.JobTDate AND Job.ClientId=temp.ClientId AND Job.Level IN ('I','D') AND JobStatus IN ('T', 'W') AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId; # list results SELECT DISTINCT VolumeName from temp2; !DROP TABLE temp; !DROP TABLE temp2; # 9 :List Pool Attributes for a selected Pool *Enter Pool name: SELECT Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes FROM Pool WHERE Name='%1'; # 10 :List total files/bytes by Job SELECT COUNT(*) AS Jobs,SUM(JobFiles) AS Files,ROUND(SUM(JobBytes/1024.0/1024.0/1024.0),3) AS GB, Name AS Job FROM Job GROUP by Name; # 11 :List total files/bytes by Volume SELECT COUNT(*) AS Jobs,SUM(JobFiles) AS Files,ROUND(SUM(JobBytes/1024.0/1024.0/1024.0),3) AS GB, VolumeName FROM Job,JobMedia,Media WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId GROUP by VolumeName; # 12 :List Files for a selected JobId *Enter JobId: SELECT Path.Path,Filename.Name FROM File,Filename,Path WHERE File.JobId=%1 AND Filename.FilenameId=File.FilenameId AND Path.PathId=File.PathId ORDER BY Path.Path,Filename.Name; # 13 :List Jobs stored on a selected MediaId *Enter MediaId: SELECT DISTINCT Job.JobId,Job.Name,Job.StartTime,Job.Type, Job.Level,Job.JobFiles,ROUND(Job.JobBytes/1024.0/1024.0/1024.0,3) AS GB,Job.JobStatus FROM JobMedia,Job WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId=%1 ORDER by Job.StartTime; # 14 :List Jobs stored for a given Volume name *Enter Volume name: SELECT DISTINCT Job.JobId AS JobId,Job.Name AS Name,Job.StartTime AS StartTime, Job.Type AS Type,Job.Level AS Level,Job.JobFiles AS Files, ROUND(Job.JobBytes/1024.0/1024.0/1024.0,3) AS GB ,Job.JobStatus AS Status FROM Media,JobMedia,Job WHERE Media.VolumeName='%1' AND Media.MediaId=JobMedia.MediaId AND JobMedia.JobId=Job.JobId ORDER by Job.StartTime; # 15 :List Volumes Bareos thinks are in changer SELECT MediaId,VolumeName,ROUND(VolBytes/(1024.0*1024.0*1024.0),3) AS GB,Storage.Name AS Storage,Slot,Pool.Name AS Pool,MediaType,VolStatus FROM Media,Pool,Storage WHERE Media.PoolId=Pool.PoolId AND Slot>0 AND InChanger=1 AND Media.StorageId=Storage.StorageId ORDER BY MediaType ASC, Slot ASC; # 16 :List Volumes likely to need replacement from age or errors SELECT VolumeName AS Volume,VolErrors AS Errors, VolMounts AS Mounts, VolWrites AS Writes,RecycleCount,VolStatus AS Status FROM Media WHERE (VolErrors>0) OR (VolStatus='Error') OR (VolMounts>50) OR (VolStatus='Disabled') OR (VolWrites>3999999) ORDER BY VolErrors DESC, VolStatus, VolMounts,VolumeName DESC; # 17 :List Volumes Bareos thinks are eligible for the changer SELECT VolumeName,VolStatus,Storage.Name AS Location, VolBytes/(1024*1024*1024) AS GB,MediaId,MediaType,Pool.Name AS Pool FROM Media,Pool,Storage WHERE Media.PoolId=Pool.PoolId AND Media.StorageId=Storage.StorageId AND InChanger=0 AND ((VolStatus='Purged') OR (VolStatus='Append') OR (VolStatus='Recycle')) ORDER BY VolMounts ASC, Pool.Name ASC, VolumeName ASC # 18 :List Volumes by Volume: SELECT VolumeName, Job.JobId AS JobID, Job.Name AS JobName, Job.StartTime AS Start, JobFiles AS Files,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS GB FROM Job,JobMedia,Media WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId GROUP by VolumeName, Job.JobID, Job.Name, JobBytes, JobFiles, Job.StartTime ORDER by VolumeName; # 19 :List Volumes by Jobs: SELECT Job.Name AS JobName, Job.JobId AS JobID, VolumeName, Job.StartTime AS Start, JobFiles AS Files,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS GB FROM Job,JobMedia,Media WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId GROUP by VolumeName, Job.JobID, Job.Name, JobBytes, JobFiles, Job.StartTime ORDER by JobName, Start; # 20 :List Volumes for a jobname: *Enter Job name: SELECT Job.Name AS JobName, Job.JobId AS JobID, VolumeName, Job.StartTime AS Start, JobFiles AS Files,ROUND(JobBytes/1024.0/1024.0/1024.0,3) AS Bytes FROM Job,JobMedia,Media WHERE Job.Name='%1' AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId GROUP by VolumeName, Job.JobID, Job.Name, JobBytes, JobFiles, Job.StartTime ORDER by JobName, Start; bareos-Release-14.2.6/src/dird/quota.c000066400000000000000000000231471263011562700174550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version two of the GNU General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Quota procesing routines. * * Matthew Ife Matthew.Ife@ukfast.co.uk */ #include "bareos.h" #include "dird.h" #define dbglvl 100 /* * This function returns the total number of bytes difference remaining before going over quota. * Returns: unsigned long long containing remaining bytes before going over quota. * 0 if over quota */ uint64_t fetch_remaining_quotas(JCR *jcr) { uint64_t remaining = 0; uint64_t now = (uint64_t)time(NULL); /* * Quotas not being used ? */ if (!jcr->HasQuota) { return 0; } Dmsg2(dbglvl, "JobSumTotalBytes for JobId %d is %llu\n", jcr->JobId, jcr->jr.JobSumTotalBytes); Dmsg1(dbglvl, "Fetching remaining quotas for JobId %d\n", jcr->JobId); /* * If strict quotas on and grace exceeded, enforce the softquota */ if (jcr->res.client->StrictQuotas && jcr->res.client->SoftQuota && jcr->res.client->GraceTime > 0 && (now - (uint64_t)jcr->res.client->GraceTime) > (uint64_t)jcr->res.client->SoftQuotaGracePeriod && jcr->res.client->SoftQuotaGracePeriod > 0) { remaining = jcr->res.client->SoftQuota - jcr->jr.JobSumTotalBytes; } else if (!jcr->res.client->StrictQuotas && jcr->res.client->SoftQuota && jcr->res.client->GraceTime > 0 && jcr->res.client->SoftQuotaGracePeriod > 0 && (now - (uint64_t)jcr->res.client->GraceTime) > (uint64_t)jcr->res.client->SoftQuotaGracePeriod) { /* * If strict quotas turned off and grace exceeded use the last known limit */ if (jcr->res.client->QuotaLimit > jcr->res.client->SoftQuota) { remaining = jcr->res.client->QuotaLimit - jcr->jr.JobSumTotalBytes; } else { remaining = jcr->res.client->SoftQuota - jcr->jr.JobSumTotalBytes; } } else if (jcr->jr.JobSumTotalBytes < jcr->res.client->HardQuota) { /* * If within the hardquota. */ remaining = jcr->res.client->HardQuota - jcr->jr.JobSumTotalBytes; } else { /* * If just over quota return 0. This shouldnt happen because quotas * are checked properly prior to this code. */ remaining = 0; } Dmsg4(dbglvl, "Quota for %s is %llu. Remainder is %llu, QuotaLimit: %llu\n", jcr->jr.Name, jcr->jr.JobSumTotalBytes, remaining, jcr->res.client->QuotaLimit); return remaining; } /* * This function returns a truth value depending on the state of hard quotas. * The function compares the total jobbytes against the hard quota. * If the value is true, the quota is reached and termination of the job should occur. * * Returns: true on reaching quota * false on not reaching quota. */ bool check_hardquotas(JCR *jcr) { bool retval = false; /* * Do not check if hardquota is not set */ if (jcr->res.client->HardQuota == 0) { goto bail_out; } Dmsg1(dbglvl, "Checking hard quotas for JobId %d\n", jcr->JobId); if (!jcr->HasQuota) { if (jcr->res.client->QuotaIncludeFailedJobs) { if (!db_get_quota_jobbytes(jcr, jcr->db, &jcr->jr, jcr->res.client->JobRetention)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Quota value: ERR=%s"), db_strerror(jcr->db)); goto bail_out; } } else { if (!db_get_quota_jobbytes_nofailed(jcr, jcr->db, &jcr->jr, jcr->res.client->JobRetention)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Quota value: ERR=%s"), db_strerror(jcr->db)); goto bail_out; } } jcr->HasQuota = true; } if (jcr->jr.JobSumTotalBytes > jcr->res.client->HardQuota) { retval = true; goto bail_out; } Dmsg2(dbglvl, "Quota for JobID: %d is %llu\n", jcr->jr.JobId, jcr->jr.JobSumTotalBytes); bail_out: return retval; } /* * This function returns a truth value depending on the state of soft quotas. * The function compares the total jobbytes against the soft quota. * * If the quotas are not strict (the default) it checks the jobbytes value against * the quota limit previously when running in burst mode during the grace period. * * It checks if we have exceeded our grace time. * * If the value is true, the quota is reached and termination of the job should occur. * * Returns: true on reaching soft quota * false on not reaching soft quota. */ bool check_softquotas(JCR *jcr) { bool retval = false; uint64_t now = (uint64_t)time(NULL); /* * Do not check if the softquota is not set */ if (jcr->res.client->SoftQuota == 0) { goto bail_out; } Dmsg1(dbglvl, "Checking soft quotas for JobId %d\n", jcr->JobId); if (!jcr->HasQuota) { if (jcr->res.client->QuotaIncludeFailedJobs) { if (!db_get_quota_jobbytes(jcr, jcr->db, &jcr->jr, jcr->res.client->JobRetention)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Quota value: ERR=%s"), db_strerror(jcr->db)); goto bail_out; } Dmsg0(dbglvl, "Quota Includes Failed Jobs\n"); } else { if (!db_get_quota_jobbytes_nofailed(jcr, jcr->db, &jcr->jr, jcr->res.client->JobRetention)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Quota value: ERR=%s"), db_strerror(jcr->db)); goto bail_out; } Jmsg(jcr, M_INFO, 0, _("Quota does NOT include Failed Jobs\n")); } jcr->HasQuota = true; } Dmsg2(dbglvl, "Quota for %s is %llu\n", jcr->jr.Name, jcr->jr.JobSumTotalBytes); Dmsg2(dbglvl, "QuotaLimit for %s is %llu\n", jcr->jr.Name, jcr->res.client->QuotaLimit); Dmsg2(dbglvl, "HardQuota for %s is %llu\n", jcr->jr.Name, jcr->res.client->HardQuota); Dmsg2(dbglvl, "SoftQuota for %s is %llu\n", jcr->jr.Name, jcr->res.client->SoftQuota); Dmsg2(dbglvl, "SoftQuota Grace Period for %s is %d\n", jcr->jr.Name, jcr->res.client->SoftQuotaGracePeriod); Dmsg2(dbglvl, "SoftQuota Grace Time for %s is %d\n", jcr->jr.Name, jcr->res.client->GraceTime); if (jcr->jr.JobSumTotalBytes > jcr->res.client->SoftQuota) { /* * Only warn once about softquotas in the job * Check if gracetime has been set */ if (jcr->res.client->GraceTime == 0 && jcr->res.client->SoftQuotaGracePeriod) { Dmsg1(dbglvl, "update_quota_gracetime: %d\n", now); if (!db_update_quota_gracetime(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error setting Quota gracetime: ERR=%s"), db_strerror(jcr->db)); } else { Jmsg(jcr, M_ERROR, 0, _("Softquota Exceeded, Grace Period starts now.\n")); } jcr->res.client->GraceTime = now; goto bail_out; } else if (jcr->res.client->SoftQuotaGracePeriod && (now - (uint64_t)jcr->res.client->GraceTime) < (uint64_t)jcr->res.client->SoftQuotaGracePeriod) { Jmsg(jcr, M_ERROR, 0, _("Softquota Exceeded, will be enforced after Grace Period expires.\n")); } else if (jcr->res.client->SoftQuotaGracePeriod && (now - (uint64_t)jcr->res.client->GraceTime) > (uint64_t)jcr->res.client->SoftQuotaGracePeriod) { /* * If gracetime has expired update else check more if not set softlimit yet then set and bail out. */ if (jcr->res.client->QuotaLimit < 1) { if (!db_update_quota_softlimit(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error setting Quota Softlimit: ERR=%s"), db_strerror(jcr->db)); } Jmsg(jcr, M_WARNING, 0, _("Softquota Exceeded and Grace Period expired.\n")); Jmsg(jcr, M_INFO, 0, _("Setting Burst Quota to %d Bytes.\n"), jcr->jr.JobSumTotalBytes); jcr->res.client->QuotaLimit = jcr->jr.JobSumTotalBytes; retval = true; goto bail_out; } else { /* * If we use strict quotas enforce the pure soft quota limit. */ if (jcr->res.client->StrictQuotas && jcr->jr.JobSumTotalBytes > jcr->res.client->SoftQuota) { Dmsg0(dbglvl, "Softquota Exceeded, enforcing Strict Quota Limit.\n"); retval = true; goto bail_out; } else if (!jcr->res.client->StrictQuotas && jcr->jr.JobSumTotalBytes >= jcr->res.client->QuotaLimit) { /* * If strict quotas turned off use the last known limit */ Jmsg(jcr, M_WARNING, 0, _("Softquota Exceeded, enforcing Burst Quota Limit.\n")); retval = true; goto bail_out; } } } } bail_out: return retval; } bareos-Release-14.2.6/src/dird/recycle.c000066400000000000000000000052331263011562700177460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Automatic Recycling of Volumes * Recycles Volumes that have been purged * * Kern Sibbald, May MMII */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store) { bstrncpy(mr->VolStatus, "Recycle", sizeof(mr->VolStatus)); set_storageid_in_mr(store, mr); if (db_find_next_volume(jcr, jcr->db, 1, InChanger, mr)) { jcr->MediaId = mr->MediaId; Dmsg1(20, "Find_next_vol MediaId=%u\n", jcr->MediaId); pm_strcpy(jcr->VolumeName, mr->VolumeName); set_storageid_in_mr(store, mr); return true; } return false; } /* * Look for oldest Purged volume */ bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORERES *store) { bstrncpy(mr->VolStatus, "Purged", sizeof(mr->VolStatus)); if (db_find_next_volume(jcr, jcr->db, 1, InChanger, mr)) { set_storageid_in_mr(store, mr); if (recycle_volume(jcr, mr)) { Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\"\n"), mr->VolumeName); Dmsg1(100, "return 1 recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName); return true; } } Dmsg0(100, "return 0 recycle_oldest_purged_volume end\n"); return false; } /* * Recycle the specified volume */ int recycle_volume(JCR *jcr, MEDIA_DBR *mr) { bstrncpy(mr->VolStatus, "Recycle", sizeof(mr->VolStatus)); mr->VolJobs = mr->VolFiles = mr->VolBlocks = mr->VolErrors = 0; mr->VolBytes = 1; mr->FirstWritten = mr->LastWritten = 0; mr->RecycleCount++; mr->set_first_written = true; set_storageid_in_mr(NULL, mr); return db_update_media_record(jcr, jcr->db, mr); } bareos-Release-14.2.6/src/dird/restore.c000066400000000000000000000431051263011562700200030ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * BAREOS Director -- restore.c -- responsible for restoring files * * Kern Sibbald, November MM * * This routine is run as a separate thread. * * Current implementation is Catalog verification only (i.e. no verification versus tape). * * Basic tasks done here: * Open DB * Open Message Channel with Storage daemon to tell him a job will be starting. * Open connection with File daemon and pass him commands to do the restore. */ #include "bareos.h" #include "dird.h" /* Commands sent to File daemon */ static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n"; static char storaddrcmd[] = "storage address=%s port=%d ssl=%d Authorization=%s\n"; static char setauthorizationcmd[] = "setauthorization Authorization=%s\n"; static char passiveclientcmd[] = "passive client address=%s port=%d ssl=%d\n"; /* Responses received from File daemon */ static char OKrestore[] = "2000 OK restore\n"; static char OKstore[] = "2000 OK storage\n"; static char OKstoreend[] = "2000 OK storage end\n"; static char OKAuthorization[] = "2000 OK Authorization\n"; static char OKpassiveclient[] = "2000 OK passive client\n"; /* Responses received from the Storage daemon */ static char OKbootstrap[] = "3000 OK bootstrap\n"; static void build_restore_command(JCR *jcr, POOL_MEM &ret) { char replace, *where, *cmd; char empty = '\0'; /* * Build the restore command */ if (jcr->replace != 0) { replace = jcr->replace; } else if (jcr->res.job->replace != 0) { replace = jcr->res.job->replace; } else { replace = REPLACE_ALWAYS; /* always replace */ } if (jcr->RegexWhere) { where = jcr->RegexWhere; /* override */ cmd = restorecmdR; } else if (jcr->res.job->RegexWhere) { where = jcr->res.job->RegexWhere; /* no override take from job */ cmd = restorecmdR; } else if (jcr->where) { where = jcr->where; /* override */ cmd = restorecmd; } else if (jcr->res.job->RestoreWhere) { where = jcr->res.job->RestoreWhere; /* no override take from job */ cmd = restorecmd; } else { /* nothing was specified */ where = ∅ /* use default */ cmd = restorecmd; } jcr->prefix_links = jcr->res.job->PrefixLinks; bash_spaces(where); Mmsg(ret, cmd, replace, jcr->prefix_links, where); unbash_spaces(where); } /** * The bootstrap is stored in a file, so open the file, and loop * through it processing each storage device in turn. If the * storage is different from the prior one, we open a new connection * to the new storage and do a restore for that part. * * This permits handling multiple storage daemons for a single * restore. E.g. your Full is stored on tape, and Incrementals * on disk. */ static inline bool do_native_restore_bootstrap(JCR *jcr) { STORERES *store; bootstrap_info info; BSOCK *fd = NULL; BSOCK *sd = NULL; bool first_time = true; POOL_MEM restore_cmd(PM_MESSAGE); /* * This command is used for each part */ build_restore_command(jcr, restore_cmd); /* * Open the bootstrap file */ if (!open_bootstrap_file(jcr, info)) { goto bail_out; } /* * Read the bootstrap file */ jcr->passive_client = jcr->res.client->passive; while (!feof(info.bs)) { if (!select_next_rstore(jcr, info)) { goto bail_out; } store = jcr->res.rstore; /** * Open a message channel connection with the Storage * daemon. This is to let him know that our client * will be contacting him for a backup session. * */ Dmsg0(10, "Open connection with storage daemon\n"); jcr->setJobStatus(JS_WaitSD); /* * Start conversation with Storage daemon */ if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { goto bail_out; } sd = jcr->store_bsock; /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL)) { goto bail_out; } if (first_time) { /* * Start conversation with File daemon */ jcr->setJobStatus(JS_WaitFD); jcr->keep_sd_auth_key = true; /* don't clear the sd_auth_key now */ if (!connect_to_file_daemon(jcr, 10, me->FDConnectTimeout, true, true)) { goto bail_out; } fd = jcr->file_bsock; /* * Check if the file daemon supports passive client mode. */ if (jcr->passive_client && jcr->FDVersion < FD_VERSION_51) { Jmsg(jcr, M_FATAL, 0, _("Client \"%s\" doesn't support passive client mode. " "Please upgrade your client or disable compat mode.\n"), jcr->res.client->name()); goto bail_out; } } jcr->setJobStatus(JS_Running); /* * Send the bootstrap file -- what Volumes/files to restore */ if (!send_bootstrap_file(jcr, sd, info) || !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) { goto bail_out; } if (!jcr->passive_client) { int tls_need = BNET_TLS_NONE; /* * When the client is not in passive mode we can put the SD in * listen mode for the FD connection. And ask the FD to connect * to the SD. */ if (!sd->fsend("run")) { goto bail_out; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { goto bail_out; } Dmsg0(50, "Storage daemon connection OK\n"); /* * Send Storage daemon address to the File daemon, * then wait for File daemon to make connection * with Storage daemon. */ if (store->SDDport == 0) { store->SDDport = store->SDport; } /* * TLS Requirement */ if (store->tls_enable) { if (store->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } fd->fsend(storaddrcmd, store->address, store->SDDport, tls_need, jcr->sd_auth_key); memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); Dmsg1(6, "dird>filed: %s", fd->msg); if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) { goto bail_out; } } else { int tls_need = BNET_TLS_NONE; CLIENTRES *client = jcr->res.client; /* * In passive mode we tell the FD what authorization key to use * and the ask the SD to initiate the connection. */ fd->fsend(setauthorizationcmd, jcr->sd_auth_key); memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); Dmsg1(6, "dird>filed: %s", fd->msg); if (!response(jcr, fd, OKAuthorization, "Setauthorization", DISPLAY_ERROR)) { goto bail_out; } /* * TLS Requirement */ tls_need = BNET_TLS_NONE; if (client->tls_enable) { if (client->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } /* * Tell the SD to connect to the FD. */ sd->fsend(passiveclientcmd, client->address, client->FDport, tls_need); if (!response(jcr, sd, OKpassiveclient, "Passive client", DISPLAY_ERROR)) { goto bail_out; } /* * Start the Job in the SD. */ if (!sd->fsend("run")) { goto bail_out; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { goto bail_out; } Dmsg0(50, "Storage daemon connection OK\n"); } /* * Declare the job started to start the MaxRunTime check */ jcr->setJobStarted(); /* * Only pass "global" commands to the FD once */ if (first_time) { first_time = false; if (!send_runscripts_commands(jcr)) { goto bail_out; } /* * Only FD version 52 and later understand the sending of plugin options. */ if (jcr->FDVersion >= FD_VERSION_52) { if (!send_plugin_options(jcr)) { Dmsg0(000, "FAIL: Send plugin options\n"); goto bail_out; } } else { /* * Plugin options specified and not a FD that understands the new protocol keyword. */ if (jcr->plugin_options) { Jmsg(jcr, M_FATAL, 0, _("Client \"%s\" doesn't support plugin option passing. " "Please upgrade your client or disable compat mode.\n"), jcr->res.client->name()); goto bail_out; } } if (!send_restore_objects(jcr, 0, true)) { Dmsg0(000, "FAIL: Send restore objects\n"); goto bail_out; } } fd->fsend("%s", restore_cmd.c_str()); if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) { goto bail_out; } if (jcr->FDVersion < FD_VERSION_2) { /* Old FD */ break; /* we do only one loop */ } else { if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) { goto bail_out; } wait_for_storage_daemon_termination(jcr); } } /* the whole boostrap has been send */ if (fd && jcr->FDVersion >= FD_VERSION_2) { fd->fsend("endrestore"); } close_bootstrap_file(info); return true; bail_out: if (jcr->file_bsock) { jcr->file_bsock->signal(BNET_TERMINATE); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } close_bootstrap_file(info); return false; } /** * Do a restore initialization. * * Returns: false on failure * true on success */ bool do_native_restore_init(JCR *jcr) { free_wstorage(jcr); /* we don't write */ return true; } /** * Do a restore of the specified files * * Returns: false on failure * true on success */ bool do_native_restore(JCR *jcr) { JOB_DBR rjr; /* restore job record */ int status; memset(&rjr, 0, sizeof(rjr)); jcr->jr.JobLevel = L_FULL; /* Full restore */ if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); goto bail_out; } Dmsg0(20, "Updated job start record\n"); Dmsg1(20, "RestoreJobId=%d\n", jcr->res.job->RestoreJobId); if (!jcr->RestoreBootstrap) { Jmsg(jcr, M_FATAL, 0, _("Cannot restore without a bootstrap file.\n" "You probably ran a restore job directly. All restore jobs must\n" "be run using the restore command.\n")); goto bail_out; } /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Restore Job %s\n"), jcr->Job); /* * Read the bootstrap file and do the restore */ if (!do_native_restore_bootstrap(jcr)) { goto bail_out; } /* * Wait for Job Termination */ status = wait_for_job_termination(jcr); native_restore_cleanup(jcr, status); return true; bail_out: native_restore_cleanup(jcr, JS_ErrorTerminated); return false; } /** * Release resources allocated during restore. */ void native_restore_cleanup(JCR *jcr, int TermCode) { char term_code[100]; const char *term_msg; int msg_type = M_INFO; Dmsg0(20, "In native_restore_cleanup\n"); update_job_end(jcr, TermCode); if (jcr->unlink_bsr && jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); jcr->unlink_bsr = false; } if (job_canceled(jcr)) { cancel_storage_daemon_job(jcr); } switch (TermCode) { case JS_Terminated: if (jcr->ExpectedFiles > jcr->jr.JobFiles) { term_msg = _("Restore OK -- warning file count mismatch"); } else { term_msg = _("Restore OK"); } break; case JS_Warnings: term_msg = _("Restore OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Restore Error ***"); msg_type = M_ERROR; /* Generate error message */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; case JS_Canceled: term_msg = _("Restore Canceled"); if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; default: term_msg = term_code; sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode); break; } generate_restore_summary(jcr, msg_type, term_msg); Dmsg0(20, "Leaving native_restore_cleanup\n"); } /* * Generic function which generates a restore summary message. * Used by: * - native_restore_cleanup e.g. normal restores * - ndmp_restore_cleanup e.g. NDMP restores */ void generate_restore_summary(JCR *jcr, int msg_type, const char *term_msg) { char sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH]; char ec1[30], ec2[30], ec3[30], elapsed[50]; char fd_term_msg[100], sd_term_msg[100]; utime_t RunTime; double kbps; bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime); bstrftimes(edt, sizeof(edt), jcr->jr.EndTime); RunTime = jcr->jr.EndTime - jcr->jr.StartTime; if (RunTime <= 0) { kbps = 0; } else { kbps = ((double)jcr->jr.JobBytes) / (1000.0 * (double)RunTime); } if (kbps < 0.05) { kbps = 0; } jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg)); jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg)); switch (jcr->getJobProtocol()) { case PT_NDMP: Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " Restore Client: %s\n" " Start time: %s\n" " End time: %s\n" " Elapsed time: %s\n" " Files Expected: %s\n" " Files Restored: %s\n" " Bytes Restored: %s\n" " Rate: %.1f KB/s\n" " SD termination status: %s\n" " Termination: %s\n\n"), BAREOS, my_name, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER, jcr->jr.JobId, jcr->jr.Job, jcr->res.client->name(), sdt, edt, edit_utime(RunTime, elapsed, sizeof(elapsed)), edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1), edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2), edit_uint64_with_commas(jcr->jr.JobBytes, ec3), (float)kbps, sd_term_msg, term_msg); break; default: Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " Restore Client: %s\n" " Start time: %s\n" " End time: %s\n" " Elapsed time: %s\n" " Files Expected: %s\n" " Files Restored: %s\n" " Bytes Restored: %s\n" " Rate: %.1f KB/s\n" " FD Errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n\n"), BAREOS, my_name, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER, jcr->jr.JobId, jcr->jr.Job, jcr->res.client->name(), sdt, edt, edit_utime(RunTime, elapsed, sizeof(elapsed)), edit_uint64_with_commas((uint64_t)jcr->ExpectedFiles, ec1), edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec2), edit_uint64_with_commas(jcr->jr.JobBytes, ec3), (float)kbps, jcr->JobErrors, fd_term_msg, sd_term_msg, term_msg); break; } } bareos-Release-14.2.6/src/dird/run_conf.c000066400000000000000000000577231263011562700201440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Configuration parser for Director Run Configuration * directives, which are part of the Schedule Resource * * Kern Sibbald, May MM */ #include "bareos.h" #include "dird.h" extern struct s_jl joblevels[]; /* * Forward referenced subroutines */ enum e_state { s_none = 0, s_range, s_mday, s_month, s_time, s_at, s_wday, s_daily, s_weekly, s_monthly, s_hourly, s_wom, /* 1st, 2nd, ...*/ s_woy, /* week of year w00 - w53 */ s_last, /* last week of month */ s_modulo /* every nth monthday/week */ }; struct s_keyw { const char *name; /* keyword */ enum e_state state; /* parser state */ int code; /* state value */ }; /* * Keywords understood by parser */ static struct s_keyw keyw[] = { { NT_("on"), s_none, 0 }, { NT_("at"), s_at, 0 }, { NT_("last"), s_last, 0 }, { NT_("sun"), s_wday, 0 }, { NT_("mon"), s_wday, 1 }, { NT_("tue"), s_wday, 2 }, { NT_("wed"), s_wday, 3 }, { NT_("thu"), s_wday, 4 }, { NT_("fri"), s_wday, 5 }, { NT_("sat"), s_wday, 6 }, { NT_("jan"), s_month, 0 }, { NT_("feb"), s_month, 1 }, { NT_("mar"), s_month, 2 }, { NT_("apr"), s_month, 3 }, { NT_("may"), s_month, 4 }, { NT_("jun"), s_month, 5 }, { NT_("jul"), s_month, 6 }, { NT_("aug"), s_month, 7 }, { NT_("sep"), s_month, 8 }, { NT_("oct"), s_month, 9 }, { NT_("nov"), s_month, 10 }, { NT_("dec"), s_month, 11 }, { NT_("sunday"), s_wday, 0 }, { NT_("monday"), s_wday, 1 }, { NT_("tuesday"), s_wday, 2 }, { NT_("wednesday"), s_wday, 3 }, { NT_("thursday"), s_wday, 4 }, { NT_("friday"), s_wday, 5 }, { NT_("saturday"), s_wday, 6 }, { NT_("january"), s_month, 0 }, { NT_("february"), s_month, 1 }, { NT_("march"), s_month, 2 }, { NT_("april"), s_month, 3 }, { NT_("june"), s_month, 5 }, { NT_("july"), s_month, 6 }, { NT_("august"), s_month, 7 }, { NT_("september"), s_month, 8 }, { NT_("october"), s_month, 9 }, { NT_("november"), s_month, 10 }, { NT_("december"), s_month, 11 }, { NT_("daily"), s_daily, 0 }, { NT_("weekly"), s_weekly, 0 }, { NT_("monthly"), s_monthly, 0 }, { NT_("hourly"), s_hourly, 0 }, { NT_("1st"), s_wom, 0 }, { NT_("2nd"), s_wom, 1 }, { NT_("3rd"), s_wom, 2 }, { NT_("4th"), s_wom, 3 }, { NT_("5th"), s_wom, 4 }, { NT_("first"), s_wom, 0 }, { NT_("second"), s_wom, 1 }, { NT_("third"), s_wom, 2 }, { NT_("fourth"), s_wom, 3 }, { NT_("fifth"), s_wom, 4 }, { NULL, s_none, 0 } }; static bool have_hour, have_mday, have_wday, have_month, have_wom; static bool have_at, have_woy; static RUNRES lrun; static void set_defaults() { have_hour = have_mday = have_wday = have_month = have_wom = have_woy = false; have_at = false; set_bits(0, 23, lrun.hour); set_bits(0, 30, lrun.mday); set_bits(0, 6, lrun.wday); set_bits(0, 11, lrun.month); set_bits(0, 4, lrun.wom); set_bits(0, 53, lrun.woy); } /* * Keywords (RHS) permitted in Run records */ static struct s_kw RunFields[] = { { "pool", 'P' }, { "fullpool", 'f' }, { "incrementalpool", 'i' }, { "differentialpool", 'd' }, { "nextpool", 'n' }, { "level", 'L' }, { "storage", 'S' }, { "messages", 'M' }, { "priority", 'p' }, { "spooldata", 's' }, { "maxrunschedtime", 'm' }, { "accurate", 'a' }, { NULL, 0 } }; /* * Store Schedule Run information * * Parse Run statement: * * Run [on] 2 january at 23:45 * * Default Run time is daily at 0:0 * * There can be multiple run statements, they are simply chained * together. * */ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) { char *p; int i, j; int options = lc->options; int token, state, state2 = 0, code = 0, code2 = 0; bool found; utime_t utime; RES *res; RUNRES **run = (RUNRES **)(item->value); URES *res_all = (URES *)my_config->m_res_all; lc->options |= LOPT_NO_IDENT; /* Want only "strings" */ /* * Clear local copy of run record */ memset(&lrun, 0, sizeof(lrun)); /* * Scan for Job level "full", "incremental", ... */ for (found = true; found; ) { found = false; token = lex_get_token(lc, T_NAME); for (i = 0; !found && RunFields[i].name; i++) { if (bstrcasecmp(lc->str, RunFields[i].name)) { found = true; if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, _("Expected an equals, got: %s"), lc->str); /* NOT REACHED */ } switch (RunFields[i].token) { case 's': /* Data spooling */ token = lex_get_token(lc, T_NAME); if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) { lrun.spool_data = true; lrun.spool_data_set = true; } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) { lrun.spool_data = false; lrun.spool_data_set = true; } else { scan_err1(lc, _("Expect a YES or NO, got: %s"), lc->str); } break; case 'L': /* Level */ token = lex_get_token(lc, T_NAME); for (j = 0; joblevels[j].level_name; j++) { if (bstrcasecmp(lc->str, joblevels[j].level_name)) { lrun.level = joblevels[j].level; lrun.job_type = joblevels[j].job_type; j = 0; break; } } if (j != 0) { scan_err1(lc, _("Job level field: %s not found in run record"), lc->str); /* NOT REACHED */ } break; case 'p': /* Priority */ token = lex_get_token(lc, T_PINT32); if (pass == 2) { lrun.Priority = lc->pint32_val; } break; case 'P': /* Pool */ case 'f': /* FullPool */ case 'v': /* VFullPool */ case 'i': /* IncPool */ case 'd': /* DiffPool */ case 'n': /* NextPool */ token = lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(R_POOL, lc->str); if (res == NULL) { scan_err1(lc, _("Could not find specified Pool Resource: %s"), lc->str); /* NOT REACHED */ } switch(RunFields[i].token) { case 'P': lrun.pool = (POOLRES *)res; break; case 'f': lrun.full_pool = (POOLRES *)res; break; case 'v': lrun.vfull_pool = (POOLRES *)res; break; case 'i': lrun.inc_pool = (POOLRES *)res; break; case 'd': lrun.diff_pool = (POOLRES *)res; break; case 'n': lrun.next_pool = (POOLRES *)res; break; } } break; case 'S': /* Storage */ token = lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(R_STORAGE, lc->str); if (res == NULL) { scan_err1(lc, _("Could not find specified Storage Resource: %s"), lc->str); /* NOT REACHED */ } lrun.storage = (STORERES *)res; } break; case 'M': /* Messages */ token = lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(R_MSGS, lc->str); if (res == NULL) { scan_err1(lc, _("Could not find specified Messages Resource: %s"), lc->str); /* NOT REACHED */ } lrun.msgs = (MSGSRES *)res; } break; case 'm': /* Max run sched time */ token = lex_get_token(lc, T_QUOTED_STRING); if (!duration_to_utime(lc->str, &utime)) { scan_err1(lc, _("expected a time period, got: %s"), lc->str); return; } lrun.MaxRunSchedTime = utime; lrun.MaxRunSchedTime_set = true; break; case 'a': /* Accurate */ token = lex_get_token(lc, T_NAME); if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) { lrun.accurate = true; lrun.accurate_set = true; } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) { lrun.accurate = false; lrun.accurate_set = true; } else { scan_err1(lc, _("Expect a YES or NO, got: %s"), lc->str); } break; default: scan_err1(lc, _("Expected a keyword name, got: %s"), lc->str); /* NOT REACHED */ break; } /* end switch */ } /* end if bstrcasecmp */ } /* end for RunFields */ /* * At this point, it is not a keyword. Check for old syle * Job Levels without keyword. This form is depreciated!!! */ if (!found) { for (j = 0; joblevels[j].level_name; j++) { if (bstrcasecmp(lc->str, joblevels[j].level_name)) { lrun.level = joblevels[j].level; lrun.job_type = joblevels[j].job_type; found = true; break; } } } } /* end for found */ /* * Scan schedule times. * Default is: daily at 0:0 */ state = s_none; set_defaults(); for (; token != T_EOL; (token = lex_get_token(lc, T_ALL))) { int len; bool pm = false; bool am = false; switch (token) { case T_NUMBER: state = s_mday; code = atoi(lc->str) - 1; if (code < 0 || code > 30) { scan_err0(lc, _("Day number out of range (1-31)")); } break; case T_NAME: /* This handles drop through from keyword */ case T_UNQUOTED_STRING: if (strchr(lc->str, (int)'-')) { state = s_range; break; } if (strchr(lc->str, (int)':')) { state = s_time; break; } if (strchr(lc->str, (int)'/')) { state = s_modulo; break; } if (lc->str_len == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && is_an_integer(lc->str+1)) { code = atoi(lc->str+1); if (code < 0 || code > 53) { scan_err0(lc, _("Week number out of range (0-53)")); /* NOT REACHED */ } state = s_woy; /* Week of year */ break; } /* * Everything else must be a keyword */ for (i = 0; keyw[i].name; i++) { if (bstrcasecmp(lc->str, keyw[i].name)) { state = keyw[i].state; code = keyw[i].code; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Job type field: %s in run record not found"), lc->str); /* NOT REACHED */ } break; case T_COMMA: continue; default: scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str); /* NOT REACHED */ break; } switch (state) { case s_none: continue; case s_mday: /* Day of month */ if (!have_mday) { clear_bits(0, 30, lrun.mday); have_mday = true; } set_bit(code, lrun.mday); break; case s_month: /* Month of year */ if (!have_month) { clear_bits(0, 11, lrun.month); have_month = true; } set_bit(code, lrun.month); break; case s_wday: /* Week day */ if (!have_wday) { clear_bits(0, 6, lrun.wday); have_wday = true; } set_bit(code, lrun.wday); break; case s_wom: /* Week of month 1st, ... */ if (!have_wom) { clear_bits(0, 4, lrun.wom); have_wom = true; } set_bit(code, lrun.wom); break; case s_woy: if (!have_woy) { clear_bits(0, 53, lrun.woy); have_woy = true; } set_bit(code, lrun.woy); break; case s_time: /* Time */ if (!have_at) { scan_err0(lc, _("Time must be preceded by keyword AT.")); /* NOT REACHED */ } if (!have_hour) { clear_bits(0, 23, lrun.hour); } // Dmsg1(000, "s_time=%s\n", lc->str); p = strchr(lc->str, ':'); if (!p) { scan_err0(lc, _("Time logic error.\n")); /* NOT REACHED */ } *p++ = 0; /* Separate two halves */ code = atoi(lc->str); /* Pick up hour */ code2 = atoi(p); /* Pick up minutes */ len = strlen(p); if (len >= 2) { p += 2; } if (bstrcasecmp(p, "pm")) { pm = true; } else if (bstrcasecmp(p, "am")) { am = true; } else if (len != 2) { scan_err0(lc, _("Bad time specification.")); /* NOT REACHED */ } /* * Note, according to NIST, 12am and 12pm are ambiguous and * can be defined to anything. However, 12:01am is the same * as 00:01 and 12:01pm is the same as 12:01, so we define * 12am as 00:00 and 12pm as 12:00. */ if (pm) { /* * Convert to 24 hour time */ if (code != 12) { code += 12; } } else if (am && code == 12) { /* * AM */ code -= 12; } if (code < 0 || code > 23 || code2 < 0 || code2 > 59) { scan_err0(lc, _("Bad time specification.")); /* NOT REACHED */ } set_bit(code, lrun.hour); lrun.minute = code2; have_hour = true; break; case s_at: have_at = true; break; case s_last: lrun.last_set = true; if (!have_wom) { clear_bits(0, 4, lrun.wom); have_wom = true; } break; case s_modulo: p = strchr(lc->str, '/'); if (!p) { scan_err0(lc, _("Modulo logic error.\n")); } *p++ = 0; /* Separate two halves */ if (is_an_integer(lc->str) && is_an_integer(p)) { /* * Check for day modulo specification. */ code = atoi(lc->str) - 1; code2 = atoi(p); if (code < 0 || code > 30 || code2 < 0 || code2 > 30) { scan_err0(lc, _("Bad day specification in modulo.")); } if (code > code2) { scan_err0(lc, _("Bad day specification, offset must always be <= than modulo.")); } if (!have_mday) { clear_bits(0, 30, lrun.mday); have_mday = true; } /* * Set the bits according to the modulo specification. */ for (i = 0; i < 31; i++) { if (i % code2 == 0) { set_bit(i + code, lrun.mday); } } } else if (strlen(lc->str) == 3 && strlen(p) == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && (p[0] == 'w' || p[0] == 'W') && is_an_integer(lc->str + 1) && is_an_integer(p + 1)) { /* * Check for week modulo specification. */ code = atoi(lc->str + 1); code2 = atoi(p + 1); if (code < 0 || code > 53 || code2 < 0 || code2 > 53) { scan_err0(lc, _("Week number out of range (0-53) in modulo")); } if (code > code2) { scan_err0(lc, _("Bad week number specification in modulo, offset must always be <= than modulo.")); } if (!have_woy) { clear_bits(0, 53, lrun.woy); have_woy = true; } /* * Set the bits according to the modulo specification. */ for (i = 0; i < 54; i++) { if (i % code2 == 0) { set_bit(i + code - 1, lrun.woy); } } } else { scan_err0(lc, _("Bad modulo time specification. Format for weekdays is '01/02', for yearweeks is 'w01/w02'.")); } break; case s_range: p = strchr(lc->str, '-'); if (!p) { scan_err0(lc, _("Range logic error.\n")); } *p++ = 0; /* Separate two halves */ if (is_an_integer(lc->str) && is_an_integer(p)) { /* * Check for day range. */ code = atoi(lc->str) - 1; code2 = atoi(p) - 1; if (code < 0 || code > 30 || code2 < 0 || code2 > 30) { scan_err0(lc, _("Bad day range specification.")); } if (!have_mday) { clear_bits(0, 30, lrun.mday); have_mday = true; } if (code < code2) { set_bits(code, code2, lrun.mday); } else { set_bits(code, 30, lrun.mday); set_bits(0, code2, lrun.mday); } } else if (strlen(lc->str) == 3 && strlen(p) == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && (p[0] == 'w' || p[0] == 'W') && is_an_integer(lc->str + 1) && is_an_integer(p + 1)) { /* * Check for week of year range. */ code = atoi(lc->str + 1); code2 = atoi(p + 1); if (code < 0 || code > 53 || code2 < 0 || code2 > 53) { scan_err0(lc, _("Week number out of range (0-53)")); } if (!have_woy) { clear_bits(0, 53, lrun.woy); have_woy = true; } if (code < code2) { set_bits(code, code2, lrun.woy); } else { set_bits(code, 53, lrun.woy); set_bits(0, code2, lrun.woy); } } else { /* * lookup first half of keyword range (week days or months). */ lcase(lc->str); for (i = 0; keyw[i].name; i++) { if (bstrcmp(lc->str, keyw[i].name)) { state = keyw[i].state; code = keyw[i].code; i = 0; break; } } if (i != 0 || (state != s_month && state != s_wday && state != s_wom)) { scan_err0(lc, _("Invalid month, week or position day range")); /* NOT REACHED */ } /* * Lookup end of range. */ lcase(p); for (i = 0; keyw[i].name; i++) { if (bstrcmp(p, keyw[i].name)) { state2 = keyw[i].state; code2 = keyw[i].code; i = 0; break; } } if (i != 0 || state != state2 || code == code2) { scan_err0(lc, _("Invalid month, weekday or position range")); /* NOT REACHED */ } if (state == s_wday) { if (!have_wday) { clear_bits(0, 6, lrun.wday); have_wday = true; } if (code < code2) { set_bits(code, code2, lrun.wday); } else { set_bits(code, 6, lrun.wday); set_bits(0, code2, lrun.wday); } } else if (state == s_month) { if (!have_month) { clear_bits(0, 11, lrun.month); have_month = true; } if (code < code2) { set_bits(code, code2, lrun.month); } else { /* * This is a bit odd, but we accept it anyway */ set_bits(code, 11, lrun.month); set_bits(0, code2, lrun.month); } } else { /* * Must be position */ if (!have_wom) { clear_bits(0, 4, lrun.wom); have_wom = true; } if (code < code2) { set_bits(code, code2, lrun.wom); } else { set_bits(code, 4, lrun.wom); set_bits(0, code2, lrun.wom); } } } break; case s_hourly: have_hour = true; set_bits(0, 23, lrun.hour); break; case s_weekly: have_mday = have_wom = have_woy = true; set_bits(0, 30, lrun.mday); set_bits(0, 4, lrun.wom); set_bits(0, 53, lrun.woy); break; case s_daily: have_mday = true; set_bits(0, 6, lrun.wday); break; case s_monthly: have_month = true; set_bits(0, 11, lrun.month); break; default: scan_err0(lc, _("Unexpected run state\n")); /* NOT REACHED */ break; } } /* Allocate run record, copy new stuff into it, * and append it to the list of run records * in the schedule resource. */ if (pass == 2) { RUNRES *tail; /* Create new run record */ RUNRES *nrun = (RUNRES *)malloc(sizeof(RUNRES)); memcpy(nrun, &lrun, sizeof(RUNRES)); nrun ->next = NULL; if (!*run) { /* If empty list */ *run = nrun; /* Add new record */ } else { for (tail = *run; tail->next; tail=tail->next) { } tail->next = nrun; } } lc->options = options; /* Restore scanner options */ set_bit(index, res_all->res_sch.hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } bareos-Release-14.2.6/src/dird/scheduler.c000066400000000000000000000362041263011562700203000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS scheduler * * It looks at what jobs are to be run and when * and waits around until it is time to * fire them up. * * Kern Sibbald, May MM, major revision December MMIII */ #include "bareos.h" #include "dird.h" #if 0 #define SCHED_DEBUG #define DBGLVL 0 #else #undef SCHED_DEBUG #define DBGLVL 200 #endif const int dbglvl = DBGLVL; /* Local variables */ struct job_item { RUNRES *run; JOBRES *job; time_t runtime; int Priority; dlink link; /* link for list */ }; /* List of jobs to be run. They were scheduled in this hour or the next */ static dlist *jobs_to_run; /* list of jobs to be run */ /* Time interval in secs to sleep if nothing to be run */ static int const next_check_secs = 60; /* Forward referenced subroutines */ static void find_runs(); static void add_job(JOBRES *job, RUNRES *run, time_t now, time_t runtime); static void dump_job(job_item *ji, const char *msg); /* Imported subroutines */ /* Imported variables */ /** * called by reload_config to tell us that the schedules * we may have based our next jobs to run queues have been * invalidated. In fact the schedules may not have changed * but the run object that we have recorded the last_run time * on are new and no longer have a valid last_run time which * causes us to double run schedules that get put into the list * because run_nh = 1. */ static bool schedules_invalidated = false; void invalidate_schedules(void) { schedules_invalidated = true; } /********************************************************************* * * Main Bareos Scheduler * */ JCR *wait_for_next_job(char *one_shot_job_to_run) { JCR *jcr; JOBRES *job; RUNRES *run; time_t now, prev; static bool first = true; job_item *next_job = NULL; Dmsg0(dbglvl, "Enter wait_for_next_job\n"); if (first) { first = false; /* Create scheduled jobs list */ jobs_to_run = New(dlist(next_job, &next_job->link)); if (one_shot_job_to_run) { /* one shot */ job = (JOBRES *)GetResWithName(R_JOB, one_shot_job_to_run); if (!job) { Emsg1(M_ABORT, 0, _("Job %s not found\n"), one_shot_job_to_run); } Dmsg1(5, "Found one_shot_job_to_run %s\n", one_shot_job_to_run); jcr = new_jcr(sizeof(JCR), dird_free_jcr); set_jcr_defaults(jcr, job); return jcr; } } /* Wait until we have something in the * next hour or so. */ again: while (jobs_to_run->empty()) { find_runs(); if (!jobs_to_run->empty()) { break; } bmicrosleep(next_check_secs, 0); /* recheck once per minute */ } #ifdef list_chain job_item *je; foreach_dlist(je, jobs_to_run) { dump_job(je, _("Walk queue")); } #endif /* * Pull the first job to run (already sorted by runtime and * Priority, then wait around until it is time to run it. */ next_job = (job_item *)jobs_to_run->first(); jobs_to_run->remove(next_job); dump_job(next_job, _("Dequeued job")); if (!next_job) { /* we really should have something now */ Emsg0(M_ABORT, 0, _("Scheduler logic error\n")); } /* Now wait for the time to run the job */ for (;;) { time_t twait; /** discard scheduled queue and rebuild with new schedule objects. **/ lock_jobs(); if (schedules_invalidated) { dump_job(next_job, "Invalidated job"); free(next_job); while (!jobs_to_run->empty()) { next_job = (job_item *)jobs_to_run->first(); jobs_to_run->remove(next_job); dump_job(next_job, "Invalidated job"); free(next_job); } schedules_invalidated = false; unlock_jobs(); goto again; } unlock_jobs(); prev = now = time(NULL); twait = next_job->runtime - now; if (twait <= 0) { /* time to run it */ break; } /* Recheck at least once per minute */ bmicrosleep((next_check_secs < twait)?next_check_secs:twait, 0); /* Attempt to handle clock shift (but not daylight savings time changes) * we allow a skew of 10 seconds before invalidating everything. */ now = time(NULL); if (now < prev-10 || now > (prev+next_check_secs+10)) { schedules_invalidated = true; } } jcr = new_jcr(sizeof(JCR), dird_free_jcr); run = next_job->run; /* pick up needed values */ job = next_job->job; if (job->enabled && (!job->client || job->client->enabled)) { dump_job(next_job, _("Run job")); } free(next_job); if (!job->enabled || (job->client && !job->client->enabled)) { free_jcr(jcr); goto again; /* ignore this job */ } run->last_run = now; /* mark as run now */ ASSERT(job); set_jcr_defaults(jcr, job); if (run->level) { jcr->setJobLevel(run->level); /* override run level */ } if (run->pool) { jcr->res.pool = run->pool; /* override pool */ jcr->res.run_pool_override = true; } if (run->full_pool) { jcr->res.full_pool = run->full_pool; /* override full pool */ jcr->res.run_full_pool_override = true; } if (run->vfull_pool) { jcr->res.vfull_pool = run->vfull_pool; /* override virtual full pool */ jcr->res.run_vfull_pool_override = true; } if (run->inc_pool) { jcr->res.inc_pool = run->inc_pool; /* override inc pool */ jcr->res.run_inc_pool_override = true; } if (run->diff_pool) { jcr->res.diff_pool = run->diff_pool; /* override diff pool */ jcr->res.run_diff_pool_override = true; } if (run->next_pool) { jcr->res.next_pool = run->next_pool; /* override next pool */ jcr->res.run_next_pool_override = true; } if (run->storage) { USTORERES store; store.store = run->storage; pm_strcpy(store.store_source, _("run override")); set_rwstorage(jcr, &store); /* override storage */ } if (run->msgs) { jcr->res.messages = run->msgs; /* override messages */ } if (run->Priority) { jcr->JobPriority = run->Priority; } if (run->spool_data_set) { jcr->spool_data = run->spool_data; } if (run->accurate_set) { jcr->accurate = run->accurate; /* overwrite accurate mode */ } if (run->MaxRunSchedTime_set) { jcr->MaxRunSchedTime = run->MaxRunSchedTime; } Dmsg0(dbglvl, "Leave wait_for_next_job()\n"); return jcr; } /* * Shutdown the scheduler */ void term_scheduler() { if (jobs_to_run) { delete jobs_to_run; } } /* * check if given day of year is in last week of the month in the current year * depending if the year is leap year or not, the doy of the last day of the month * is varying one day. */ bool is_doy_in_last_week(int year, int doy) { int i; int *last_dom; int last_day_of_month[] = { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; int last_day_of_month_leap[] = { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; /* * Determine if this is a leap year. */ if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) { last_dom = last_day_of_month_leap; } else { last_dom = last_day_of_month; } for (i = 0; i < 12; i++) { /* doy is zero-based */ if (doy > ((last_dom[i] - 1) - 7) && doy <= (last_dom[i] - 1)) { return true; } } return false; } /* * Find all jobs to be run this hour and the next hour. */ static void find_runs() { time_t now, next_hour, runtime; RUNRES *run; JOBRES *job; SCHEDRES *sched; struct tm tm; bool is_last_week = false; /* are we in the last week of a month? */ bool nh_is_last_week = false; /* are we in the last week of a month? */ int hour, mday, wday, month, wom, woy, yday; /* Items corresponding to above at the next hour */ int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy, nh_yday; Dmsg0(dbglvl, "enter find_runs()\n"); /* * Compute values for time now */ now = time(NULL); blocaltime(&now, &tm); hour = tm.tm_hour; mday = tm.tm_mday - 1; wday = tm.tm_wday; month = tm.tm_mon; wom = mday / 7; woy = tm_woy(now); /* get week of year */ yday = tm.tm_yday; /* get day of year */ Dmsg8(dbglvl, "now = %x: h=%d m=%d md=%d wd=%d wom=%d woy=%d yday=%d\n", now, hour, month, mday, wday, wom, woy, yday); is_last_week = is_doy_in_last_week(tm.tm_year + 1900 , yday); /* * Compute values for next hour from now. * We do this to be sure we don't miss a job while * sleeping. */ next_hour = now + 3600; blocaltime(&next_hour, &tm); nh_hour = tm.tm_hour; nh_mday = tm.tm_mday - 1; nh_wday = tm.tm_wday; nh_month = tm.tm_mon; nh_wom = nh_mday / 7; nh_woy = tm_woy(next_hour); /* get week of year */ nh_yday = tm.tm_yday; /* get day of year */ Dmsg8(dbglvl, "nh = %x: h=%d m=%d md=%d wd=%d wom=%d woy=%d yday=%d\n", next_hour, nh_hour, nh_month, nh_mday, nh_wday, nh_wom, nh_woy, nh_yday); nh_is_last_week = is_doy_in_last_week(tm.tm_year + 1900 , nh_yday); /* * Loop through all jobs */ LockRes(); foreach_res(job, R_JOB) { sched = job->schedule; if (sched == NULL || !sched->enabled || !job->enabled || (job->client && !job->client->enabled)) { /* scheduled? or enabled? */ continue; /* no, skip this job */ } Dmsg1(dbglvl, "Got job: %s\n", job->hdr.name); for (run = sched->run; run; run = run->next) { bool run_now, run_nh; /* * Find runs scheduled between now and the next hour. */ #ifdef xxxx Dmsg0(000, "\n"); Dmsg7(000, "run h=%d m=%d md=%d wd=%d wom=%d woy=%d yday=%d\n", hour, month, mday, wday, wom, woy, yday); Dmsg6(000, "bitset bsh=%d bsm=%d bsmd=%d bswd=%d bswom=%d bswoy=%d\n", bit_is_set(hour, run->hour), bit_is_set(month, run->month), bit_is_set(mday, run->mday), bit_is_set(wday, run->wday), bit_is_set(wom, run->wom), bit_is_set(woy, run->woy)); Dmsg7(000, "nh_run h=%d m=%d md=%d wd=%d wom=%d woy=%d yday=%d\n", nh_hour, nh_month, nh_mday, nh_wday, nh_wom, nh_woy, nh_yday); Dmsg6(000, "nh_bitset bsh=%d bsm=%d bsmd=%d bswd=%d bswom=%d bswoy=%d\n", bit_is_set(nh_hour, run->hour), bit_is_set(nh_month, run->month), bit_is_set(nh_mday, run->mday), bit_is_set(nh_wday, run->wday), bit_is_set(nh_wom, run->wom), bit_is_set(nh_woy, run->woy)); Dmsg2(000, "run->last_set:%d, is_last_week:%d\n", run->last_set, is_last_week); Dmsg2(000, "run->last_set:%d, nh_is_last_week:%d\n", run->last_set, nh_is_last_week); #endif run_now = bit_is_set(hour, run->hour) && bit_is_set(mday, run->mday) && bit_is_set(wday, run->wday) && bit_is_set(month, run->month) && (bit_is_set(wom, run->wom) || (run->last_set && is_last_week)) && bit_is_set(woy, run->woy); run_nh = bit_is_set(nh_hour, run->hour) && bit_is_set(nh_mday, run->mday) && bit_is_set(nh_wday, run->wday) && bit_is_set(nh_month, run->month) && (bit_is_set(nh_wom, run->wom) || (run->last_set && nh_is_last_week)) && bit_is_set(nh_woy, run->woy); Dmsg3(dbglvl, "run@%p: run_now=%d run_nh=%d\n", run, run_now, run_nh); if (run_now || run_nh) { /* * find time (time_t) job is to be run */ blocaltime(&now, &tm); /* reset tm structure */ tm.tm_min = run->minute; /* set run minute */ tm.tm_sec = 0; /* zero secs */ runtime = mktime(&tm); if (run_now) { add_job(job, run, now, runtime); } /* If job is to be run in the next hour schedule it */ if (run_nh) { add_job(job, run, now, runtime + 3600); } } } } UnlockRes(); Dmsg0(dbglvl, "Leave find_runs()\n"); } static void add_job(JOBRES *job, RUNRES *run, time_t now, time_t runtime) { job_item *ji; bool inserted = false; /* * Don't run any job that ran less than a minute ago, but * do run any job scheduled less than a minute ago. */ if (((runtime - run->last_run) < 61) || ((runtime+59) < now)) { #ifdef SCHED_DEBUG Dmsg4(000, "Drop: Job=\"%s\" run=%lld. last_run=%lld. now=%lld\n", job->hdr.name, (utime_t)runtime, (utime_t)run->last_run, (utime_t)now); fflush(stdout); #endif return; } #ifdef SCHED_DEBUG Dmsg4(000, "Add: Job=\"%s\" run=%lld last_run=%lld now=%lld\n", job->hdr.name, (utime_t)runtime, (utime_t)run->last_run, (utime_t)now); #endif /* accept to run this job */ job_item *je = (job_item *)malloc(sizeof(job_item)); je->run = run; je->job = job; je->runtime = runtime; if (run->Priority) { je->Priority = run->Priority; } else { je->Priority = job->Priority; } /* Add this job to the wait queue in runtime, priority sorted order */ foreach_dlist(ji, jobs_to_run) { if (ji->runtime > je->runtime || (ji->runtime == je->runtime && ji->Priority > je->Priority)) { jobs_to_run->insert_before(je, ji); dump_job(je, _("Inserted job")); inserted = true; break; } } /* If place not found in queue, append it */ if (!inserted) { jobs_to_run->append(je); dump_job(je, _("Appended job")); } #ifdef SCHED_DEBUG foreach_dlist(ji, jobs_to_run) { dump_job(ji, _("Run queue")); } Dmsg0(000, "End run queue\n"); #endif } static void dump_job(job_item *ji, const char *msg) { #ifdef SCHED_DEBUG char dt[MAX_TIME_LENGTH]; int save_debug = debug_level; if (debug_level < dbglvl) { return; } bstrftime_nc(dt, sizeof(dt), ji->runtime); Dmsg4(dbglvl, "%s: Job=%s priority=%d run %s\n", msg, ji->job->hdr.name, ji->Priority, dt); fflush(stdout); debug_level = save_debug; #endif } bareos-Release-14.2.6/src/dird/sd_cmds.c000066400000000000000000000624311263011562700177370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- sd_cmds.c -- send commands to Storage daemon * * Kern Sibbald, August MM * * Extracted from other source files by Marco van Wieringen, December 2011 */ #include "bareos.h" #include "dird.h" /* Commands sent to Storage daemon */ static char readlabelcmd[] = "readlabel %s Slot=%d drive=%d\n"; static char changerlistallcmd[] = "autochanger listall %s \n"; static char changerlistcmd[] = "autochanger list %s \n"; static char changerslotscmd[] = "autochanger slots %s\n"; static char changerdrivescmd[] = "autochanger drives %s\n"; static char changertransfercmd[] = "autochanger transfer %s %d %d \n"; static char changervolopslotcmd[] = "%s %s drive=%d slot=%d\n"; static char changervolopcmd[] = "%s %s drive=%d\n"; static char canceljobcmd[] = "cancel Job=%s\n"; static char dotstatuscmd[] = ".status %s\n"; static char statuscmd[] = "status %s\n"; static char bandwidthcmd[] = "setbandwidth=%lld Job=%s\n"; static char pluginoptionscmd[] = "pluginoptions %s\n"; /* Responses received from Storage daemon */ static char OKBandwidth[] = "2000 OK Bandwidth\n"; static char OKpluginoptions[] = "2000 OK plugin options\n"; /* Commands received from storage daemon that need scanning */ static char readlabelresponse[] = "3001 Volume=%s Slot=%d"; static char changerslotsresponse[] = "slots=%d\n"; static char changerdrivesresponse[] = "drives=%d\n"; /* * Establish a connection with the Storage daemon and perform authentication. */ bool connect_to_storage_daemon(JCR *jcr, int retry_interval, int max_retry_time, bool verbose) { BSOCK *sd; STORERES *store; utime_t heart_beat; if (jcr->store_bsock) { return true; /* already connected */ } sd = New(BSOCK_TCP); /* * If there is a write storage use it */ if (jcr->res.wstore) { store = jcr->res.wstore; } else { store = jcr->res.rstore; } if (store->heartbeat_interval) { heart_beat = store->heartbeat_interval; } else { heart_beat = me->heartbeat_interval; } /* * Open message channel with the Storage daemon */ Dmsg2(100, "bnet_connect to Storage daemon %s:%d\n", store->address, store->SDport); sd->set_source_address(me->DIRsrc_addr); if (!sd->connect(jcr, retry_interval, max_retry_time, heart_beat, _("Storage daemon"), store->address, NULL, store->SDport, verbose)) { delete sd; sd = NULL; } if (sd == NULL) { return false; } sd->res = (RES *)store; /* save pointer to other end */ jcr->store_bsock = sd; if (!authenticate_storage_daemon(jcr, store)) { sd->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; return false; } return true; } /* * Open a connection to a SD. */ BSOCK *open_sd_bsock(UAContext *ua) { STORERES *store = ua->jcr->res.wstore; if (!ua->jcr->store_bsock) { ua->send_msg(_("Connecting to Storage daemon %s at %s:%d ...\n"), store->name(), store->address, store->SDport); if (!connect_to_storage_daemon(ua->jcr, 10, me->SDConnectTimeout, true)) { ua->error_msg(_("Failed to connect to Storage daemon.\n")); return NULL; } } return ua->jcr->store_bsock; } /* * Close a connection to a SD. */ void close_sd_bsock(UAContext *ua) { if (ua->jcr->store_bsock) { ua->jcr->store_bsock->signal(BNET_TERMINATE); ua->jcr->store_bsock->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; } } /* * We get the volume name from the SD */ char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive) { BSOCK *sd; STORERES *store = ua->jcr->res.wstore; char dev_name[MAX_NAME_LENGTH]; char *VolName = NULL; int rtn_slot; if (!(sd = open_sd_bsock(ua))) { ua->error_msg(_("Could not open SD socket.\n")); return NULL; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* * Ask storage daemon to read the label of the volume in a * specific slot of the autochanger using the drive number given. * This could change the loaded volume in the drive. */ sd->fsend(readlabelcmd, dev_name, Slot, drive); Dmsg1(100, "Sent: %s", sd->msg); /* * Get Volume name in this Slot */ while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); Dmsg1(100, "Got: %s", sd->msg); if (strncmp(sd->msg, NT_("3001 Volume="), 12) == 0) { VolName = (char *)malloc(sd->msglen); if (sscanf(sd->msg, readlabelresponse, VolName, &rtn_slot) == 2) { break; } free(VolName); VolName = NULL; } } close_sd_bsock(ua); Dmsg1(100, "get_vol_name=%s\n", NPRT(VolName)); return VolName; } /* * Simple comparison function for binary insert of vol_list_t */ static int compare_vol_list_entry(void *e1, void *e2) { vol_list_t *v1, *v2; v1 = (vol_list_t *)e1; v2 = (vol_list_t *)e2; if (v1->Index == v2->Index) { return 0; } else { return (v1->Index < v2->Index) ? -1 : 1; } } /* * We get the slot list from the Storage daemon. * If listall is set we run an 'autochanger listall' cmd * otherwise an 'autochanger list' cmd * If scan is set and listall is not, we return all slots found, * otherwise, we return only slots with valid barcodes (Volume names) * * Input (output of mxt-changer list): * * 0:vol2 Slot num:Volume Name * * Input (output of mxt-changer listall): * * Drive content: D:Drive num:F:Slot loaded:Volume Name * D:0:F:2:vol2 or D:Drive num:E * D:1:F:42:vol42 * D:3:E * * Slot content: * S:1:F:vol1 S:Slot num:F:Volume Name * S:2:E or S:Slot num:E * S:3:F:vol4 * * Import/Export tray slots: * I:10:F:vol10 I:Slot num:F:Volume Name * I:11:E or I:Slot num:E * I:12:F:vol40 * * If a drive is loaded, the slot *should* be empty */ dlist *get_vol_list_from_SD(UAContext *ua, STORERES *store, bool listall, bool scan) { int nr_fields; char *bp; char dev_name[MAX_NAME_LENGTH]; char *field1, *field2, *field3, *field4, *field5; vol_list_t *vl = NULL; dlist *vol_list; BSOCK *sd = NULL; if (!(sd = open_sd_bsock(ua))) { return NULL; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* * Ask for autochanger list of volumes */ if (listall) { sd->fsend(changerlistallcmd , dev_name); } else { sd->fsend(changerlistcmd, dev_name); } vol_list = New(dlist(vl, &vl->link)); /* * Read and organize list of Volumes */ while (bnet_recv(sd) >= 0) { strip_trailing_junk(sd->msg); /* * Check for returned SD messages */ if (sd->msg[0] == '3' && B_ISDIGIT(sd->msg[1]) && B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) && sd->msg[4] == ' ') { ua->send_msg("%s\n", sd->msg); /* pass them on to user */ continue; } /* * Parse the message. list gives max 2 fields listall max 5. * We always make sure all fields are initialized to either * a value or NULL. * * For autochanger list the following mapping is used: * - field1 == slotnr * - field2 == volumename * * For autochanger listall the following mapping is used: * - field1 == type * - field2 == slotnr * - field3 == content (E for Empty, F for Full) * - field4 == loaded (loaded slot if type == D) * - field4 == volumename (if type == S or I) * - field5 == volumename (if type == D) */ field1 = sd->msg; field2 = strchr(sd->msg, ':'); if (field2) { *field2++ = '\0'; if (listall) { field3 = strchr(field2, ':'); if (field3) { *field3++ = '\0'; field4 = strchr(field3, ':'); if (field4) { *field4++ = '\0'; field5 = strchr(field4, ':'); if (field5) { *field5++ = '\0'; nr_fields = 5; } else { nr_fields = 4; } } else { nr_fields = 3; field5 = NULL; } } else { nr_fields = 2; field4 = NULL; field5 = NULL; } } else { nr_fields = 2; field3 = NULL; field4 = NULL; field5 = NULL; } } else { nr_fields = 1; field3 = NULL; field4 = NULL; field5 = NULL; } /* * See if this is a parsable string from either list or listall * e.g. at least f1:f2 */ if (!field1 && !field2) { goto parse_error; } vl = (vol_list_t *)malloc(sizeof(vol_list_t)); memset(vl, 0, sizeof(vol_list_t)); if (scan && !listall) { /* * Scanning -- require only valid slot */ vl->Slot = atoi(field1); if (vl->Slot <= 0) { ua->error_msg(_("Invalid Slot number: %s\n"), sd->msg); free(vl); continue; } vl->Type = slot_type_normal; if (strlen(field2) > 0) { vl->Content = slot_content_full; vl->VolName = bstrdup(field2); } else { vl->Content = slot_content_empty; } vl->Index = INDEX_SLOT_OFFSET + vl->Slot; } else if (!listall) { /* * Not scanning and not listall. */ if (strlen(field2) == 0) { free(vl); continue; } if (!is_an_integer(field1) || (vl->Slot = atoi(field1)) <= 0) { ua->error_msg(_("Invalid Slot number: %s\n"), field1); free(vl); continue; } if (!is_volume_name_legal(ua, field2)) { ua->error_msg(_("Invalid Volume name: %s\n"), field2); free(vl); continue; } vl->Type = slot_type_normal; vl->Content = slot_content_full; vl->VolName = bstrdup(field2); vl->Index = INDEX_SLOT_OFFSET + vl->Slot; } else { /* * Listall. */ if (!field3) { goto parse_error; } switch (*field1) { case 'D': vl->Type = slot_type_drive; break; case 'S': vl->Type = slot_type_normal; break; case 'I': vl->Type = slot_type_import; break; default: vl->Type = slot_type_unknown; break; } /* * For drives the Slot is the actual drive number. * For any other type its the actual slot number. */ switch (vl->Type) { case slot_type_drive: if (!is_an_integer(field2) || (vl->Slot = atoi(field2)) < 0) { ua->error_msg(_("Invalid Drive number: %s\n"), field2); free(vl); continue; } vl->Index = INDEX_DRIVE_OFFSET + vl->Slot; if (vl->Index >= INDEX_MAX_DRIVES) { ua->error_msg(_("Drive number %d greater then INDEX_MAX_DRIVES(%d) please increase define\n"), vl->Slot, INDEX_MAX_DRIVES); free(vl); continue; } break; default: if (!is_an_integer(field2) || (vl->Slot = atoi(field2)) <= 0) { ua->error_msg(_("Invalid Slot number: %s\n"), field2); free(vl); continue; } vl->Index = INDEX_SLOT_OFFSET + vl->Slot; break; } switch (*field3) { case 'E': vl->Content = slot_content_empty; break; case 'F': vl->Content = slot_content_full; switch (vl->Type) { case slot_type_normal: case slot_type_import: if (field4) { vl->VolName = bstrdup(field4); } break; case slot_type_drive: if (field4) { vl->Loaded = atoi(field4); } if (field5) { vl->VolName = bstrdup(field5); } break; default: break; } break; default: vl->Content = slot_content_unknown; break; } } if (vl->VolName) { Dmsg6(100, "Add index = %d slot=%d loaded=%d type=%d content=%d Vol=%s to SD list.\n", vl->Index, vl->Slot, vl->Loaded, vl->Type, vl->Content, NPRT(vl->VolName)); } else { Dmsg5(100, "Add index = %d slot=%d loaded=%d type=%d content=%d Vol=NULL to SD list.\n", vl->Index, vl->Slot, vl->Loaded, vl->Type, vl->Content); } vol_list->binary_insert(vl, compare_vol_list_entry); continue; parse_error: /* * We encountered a parse error, see how many replacements * we done of ':' with '\0' by looking at the nr_fields * variable and undo those. Number of undo's are nr_fields - 1 */ while (nr_fields > 1 && (bp = strchr(sd->msg, '\0')) != NULL) { *bp = ':'; nr_fields--; } ua->error_msg(_("Illegal output from autochanger %s: %s\n"), (listall) ? _("listall") : _("list"), sd->msg); free(vl); continue; } close_sd_bsock(ua); if (vol_list->size() == 0) { delete vol_list; vol_list = NULL; } return vol_list; } /* * Destroy the volume list returned from get_vol_list_from_SD */ void free_vol_list(dlist *vol_list) { vol_list_t *vl; foreach_dlist(vl, vol_list) { if (vl->VolName) { free(vl->VolName); } } vol_list->destroy(); delete vol_list; } /* * We get the number of slots in the changer from the SD */ int get_num_slots_from_SD(UAContext *ua) { STORERES *store = ua->jcr->res.wstore; char dev_name[MAX_NAME_LENGTH]; BSOCK *sd; int slots = 0; if (!(sd = open_sd_bsock(ua))) { return 0; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* * Ask for autochanger number of slots */ sd->fsend(changerslotscmd, dev_name); while (sd->recv() >= 0) { if (sscanf(sd->msg, changerslotsresponse, &slots) == 1) { break; } else { ua->send_msg("%s", sd->msg); } } close_sd_bsock(ua); ua->send_msg(_("Device \"%s\" has %d slots.\n"), store->dev_name(), slots); return slots; } /* * We get the number of drives in the changer from the SD */ int get_num_drives_from_SD(UAContext *ua) { STORERES *store = ua->jcr->res.wstore; char dev_name[MAX_NAME_LENGTH]; BSOCK *sd; int drives = 0; if (!(sd = open_sd_bsock(ua))) { return 0; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* * Ask for autochanger number of drives */ sd->fsend(changerdrivescmd, dev_name); while (sd->recv() >= 0) { if (sscanf(sd->msg, changerdrivesresponse, &drives) == 1) { break; } else { ua->send_msg("%s", sd->msg); } } close_sd_bsock(ua); // bsendmsg(ua, _("Device \"%s\" has %d drives.\n"), store->dev_name(), drives); return drives; } /* * Cancel a running job on a storage daemon. Used by the interactive cancel * command to cancel a JobId on a Storage Daemon this can be used when the * Director already removed the Job and thinks it finished but the Storage * Daemon still thinks its active. */ bool cancel_storage_daemon_job(UAContext *ua, STORERES *store, char *JobId) { BSOCK *sd; JCR *control_jcr; control_jcr = new_control_jcr("*JobCancel*", JT_SYSTEM); control_jcr->res.wstore = store; if (!connect_to_storage_daemon(control_jcr, 10, me->SDConnectTimeout, true)) { ua->error_msg(_("Failed to connect to Storage daemon.\n")); } Dmsg0(200, "Connected to storage daemon\n"); sd = control_jcr->store_bsock; sd->fsend("cancel Job=%s\n", JobId); while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); } sd->signal(BNET_TERMINATE); sd->close(); delete control_jcr->store_bsock; control_jcr->store_bsock = NULL; free_jcr(control_jcr); return true; } /* * Cancel a running job on a storage daemon. The interactive flag sets * if we are interactive or not e.g. when doing an interactive cancel * or a system invoked one. */ bool cancel_storage_daemon_job(UAContext *ua, JCR *jcr, bool interactive) { BSOCK *sd; USTORERES store; if (!ua->jcr->wstorage) { if (jcr->rstorage) { copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource")); } else { copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); } } else { if (jcr->rstorage) { store.store = jcr->res.rstore; } else { store.store = jcr->res.wstore; } set_wstorage(ua->jcr, &store); } if (!connect_to_storage_daemon(ua->jcr, 10, me->SDConnectTimeout, true)) { if (interactive) { ua->error_msg(_("Failed to connect to Storage daemon.\n")); } return false; } Dmsg0(200, "Connected to storage daemon\n"); sd = ua->jcr->store_bsock; sd->fsend(canceljobcmd, jcr->Job); while (sd->recv() >= 0) { if (interactive) { ua->send_msg("%s", sd->msg); } } sd->signal(BNET_TERMINATE); sd->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; if (!interactive) { jcr->sd_canceled = true; } jcr->store_bsock->set_timed_out(); jcr->store_bsock->set_terminated(); sd_msg_thread_send_signal(jcr, TIMEOUT_SIGNAL); /* * An interactive cancel means we need to send a signal to the actual * controlling JCR of the Job to let it know it got canceled. */ if (interactive) { jcr->my_thread_send_signal(TIMEOUT_SIGNAL); } return true; } /* * Cancel a running job on a storage daemon. System invoked * non interactive version this builds a ua context and calls * the interactive one with the interactive flag set to false. */ void cancel_storage_daemon_job(JCR *jcr) { UAContext *ua; JCR *control_jcr; if (jcr->sd_canceled) { return; /* cancel only once */ } ua = new_ua_context(jcr); control_jcr = new_control_jcr("*JobCancel*", JT_SYSTEM); ua->jcr = control_jcr; if (jcr->store_bsock) { if (!cancel_storage_daemon_job(ua, jcr, false)) { goto bail_out; } } bail_out: free_jcr(control_jcr); free_ua_context(ua); } /* * Get the status of a remote storage daemon. */ void do_native_storage_status(UAContext *ua, STORERES *store, char *cmd) { BSOCK *sd; USTORERES lstore; lstore.store = store; pm_strcpy(lstore.store_source, _("unknown source")); set_wstorage(ua->jcr, &lstore); /* * Try connecting for up to 15 seconds */ if (!ua->api) { ua->send_msg(_("Connecting to Storage daemon %s at %s:%d\n"), store->name(), store->address, store->SDport); } if (!connect_to_storage_daemon(ua->jcr, 10, me->SDConnectTimeout, false)) { ua->send_msg(_("\nFailed to connect to Storage daemon %s.\n====\n"), store->name()); if (ua->jcr->store_bsock) { ua->jcr->store_bsock->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; } return; } Dmsg0(20, _("Connected to storage daemon\n")); sd = ua->jcr->store_bsock; if (cmd) { sd->fsend(dotstatuscmd, cmd); } else { int cnt = 0; DEVICERES *device; POOL_MEM devicenames; /* * Build a list of devicenames that belong to this storage defintion. */ foreach_alist(device, store->device) { if (cnt == 0) { pm_strcpy(devicenames, device->name()); } else { pm_strcat(devicenames, ","); pm_strcat(devicenames, device->name()); } } bash_spaces(devicenames); sd->fsend(statuscmd, devicenames.c_str()); } while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); } sd->signal( BNET_TERMINATE); sd->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; return; } /* * Ask the autochanger to move a volume from one slot to an other. * You have to update the database slots yourself afterwards. */ bool transfer_volume(UAContext *ua, STORERES *store, int src_slot, int dst_slot) { BSOCK *sd = NULL; bool retval = true; char dev_name[MAX_NAME_LENGTH]; if (!(sd = open_sd_bsock(ua))) { return false; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* * Ask for autochanger transfer of volumes */ sd->fsend(changertransfercmd, dev_name, src_slot, dst_slot); while (bnet_recv(sd) >= 0) { strip_trailing_junk(sd->msg); /* * Check for returned SD messages */ if (sd->msg[0] == '3' && B_ISDIGIT(sd->msg[1]) && B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) && sd->msg[4] == ' ') { /* * See if this is a failure msg. */ if (sd->msg[0] == '3' && sd->msg[0] == '9') retval = false; ua->send_msg("%s\n", sd->msg); /* pass them on to user */ continue; } ua->send_msg("%s\n", sd->msg); /* pass them on to user */ } close_sd_bsock(ua); return retval; } /* * Ask the autochanger to perform a mount, umount or release operation. */ bool do_autochanger_volume_operation(UAContext *ua, STORERES *store, const char *operation, int drive, int slot) { BSOCK *sd = NULL; bool retval = true; char dev_name[MAX_NAME_LENGTH]; if (!(sd = open_sd_bsock(ua))) { return false; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); if (slot > 0) { sd->fsend(changervolopslotcmd, operation, dev_name, drive, slot); } else { sd->fsend(changervolopcmd, operation, dev_name, drive); } /* * We use bget_dirmsg here and not bnet_recv because as part of * the mount request the stored can request catalog information for * any plugin who listens to the bsdEventLabelVerified event. * As we don't want to loose any non protocol data e.g. errors * without a 3xxx prefix we set the allow_any_message of * bget_dirmsg to true and as such is behaves like a normal * bnet_recv for any non protocol messages. */ while (bget_dirmsg(sd, true) >= 0) { ua->send_msg("%s", sd->msg); } close_sd_bsock(ua); return retval; } bool send_bwlimit_to_sd(JCR *jcr, const char *Job) { BSOCK *sd = jcr->store_bsock; sd->fsend(bandwidthcmd, jcr->max_bandwidth, Job); if (!response(jcr, sd, OKBandwidth, "Bandwidth", DISPLAY_ERROR)) { jcr->max_bandwidth = 0; /* can't set bandwidth limit */ return false; } return true; } /* * resolve a host on a storage daemon */ bool do_storage_resolve(UAContext *ua, STORERES *store) { BSOCK *sd; USTORERES lstore; lstore.store = store; pm_strcpy(lstore.store_source, _("unknown source")); set_wstorage(ua->jcr, &lstore); if (!(sd = open_sd_bsock(ua))) { return false; } for (int i = 1; i < ua->argc; i++) { if (!*ua->argk[i]) { continue; } sd->fsend("resolve %s", ua->argk[i]); while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); } } sd->signal(BNET_TERMINATE); sd->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; return true; } /* * send Job specific plugin options to a storage daemon */ bool do_storage_plugin_options(JCR *jcr) { int i; POOL_MEM cur_plugin_options(PM_MESSAGE); const char *plugin_options; BSOCK *sd = jcr->store_bsock; if (jcr->res.job && jcr->res.job->SdPluginOptions && jcr->res.job->SdPluginOptions->size()) { foreach_alist_index(i, plugin_options, jcr->res.job->SdPluginOptions) { pm_strcpy(cur_plugin_options, plugin_options); bash_spaces(cur_plugin_options.c_str()); sd->fsend(pluginoptionscmd, cur_plugin_options.c_str()); if (!response(jcr, sd, OKpluginoptions, "PluginOptions", DISPLAY_ERROR)) { return false; } } } return true; } bareos-Release-14.2.6/src/dird/stats.c000066400000000000000000000272451263011562700174650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Statistics collector thread. * * Written by Marco van Wieringen and Philipp Storz, April 2014 */ #include "bareos.h" #include "dird.h" /* * Commands received from storage daemon that need scanning */ static char DevStats[] = "Devicestats [%lld]: Device=%s Read=%llu, Write=%llu, SpoolSize=%llu, NumWaiting=%lu, NumWriters=%lu, " "ReadTime=%lld, WriteTime=%lld, MediaId=%ld, VolBytes=%llu, VolFiles=%llu, VolBlocks=%llu"; static char TapeAlerts[] = "Tapealerts [%lld]: Device=%s TapeAlert=%llu"; static char JobStats[] = "Jobstats [%lld]: JobId=%ld, JobFiles=%lu, JobBytes=%llu, DevName=%s"; /* Static globals */ static bool quit = false; static bool statistics_initialized = false; static bool need_flush = true; static pthread_t statistics_tid; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t wait_for_next_run_cond = PTHREAD_COND_INITIALIZER; /* * Cache the last lookup of a DeviceId. */ static struct cached_device { char device_name[MAX_NAME_LENGTH]; DBId_t StorageId; DBId_t DeviceId; } cached_device; static inline bool lookup_device(JCR *jcr, const char *device_name, DBId_t StorageId, DBId_t *DeviceId) { DEVICE_DBR dr; memset(&dr, 0, sizeof(dr)); /* * See if we can use the cached DeviceId. */ if (cached_device.StorageId == StorageId && bstrcmp(cached_device.device_name, device_name)) { *DeviceId = cached_device.DeviceId; return true; } /* * Find or create device record */ dr.StorageId = StorageId; bstrncpy(dr.Name, device_name, sizeof(dr.Name)); if (!db_create_device_record(jcr, jcr->db, &dr)){ Dmsg0(100, "Failed to create new Device record\n"); goto bail_out; } Dmsg3(200, "Deviceid of \"%s\" on StorageId %d is %d\n", dr.Name, dr.StorageId, dr.DeviceId); /* * Cache the result. */ bstrncpy(cached_device.device_name, device_name, sizeof(cached_device.device_name)); cached_device.StorageId = StorageId; cached_device.DeviceId = dr.DeviceId; *DeviceId = dr.DeviceId; return true; bail_out: return false; } /* * Wait for the next run. */ static inline void wait_for_next_run() { struct timeval tv; struct timezone tz; struct timespec timeout; /* * Wait for a next run. Normally this waits exactly me->stats_collect_interval seconds. * It can be interrupted when signaled by the stop_statistics_thread() function. */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + me->stats_collect_interval; P(mutex); pthread_cond_timedwait(&wait_for_next_run_cond, &mutex, &timeout); V(mutex); } /* * Entry point for a seperate statistics thread. */ extern "C" void *statistics_thread_runner(void *arg) { JCR *jcr; utime_t now; POOL_MEM current_store(PM_NAME); memset(&cached_device, 0, sizeof(struct cached_device)); pm_strcpy(current_store, ""); /* * Create a dummy JCR for the statistics thread. */ jcr = new_control_jcr("*StatisticsCollector*", JT_SYSTEM); /* * Open a connection to the database for storing long term statistics. */ jcr->res.catalog = (CATRES *)GetNextRes(R_CATALOG, NULL); jcr->db = db_sql_get_pooled_connection(jcr, jcr->res.catalog->db_driver, jcr->res.catalog->db_name, jcr->res.catalog->db_user, jcr->res.catalog->db_password.value, jcr->res.catalog->db_address, jcr->res.catalog->db_port, jcr->res.catalog->db_socket, jcr->res.catalog->mult_db_connections, jcr->res.catalog->disable_batch_insert); if (jcr->db == NULL) { Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"), jcr->res.catalog->db_name); goto bail_out; } /* * Do our work as long as we are not signaled to quit. */ while (!quit) { now = (utime_t)time(NULL); Dmsg1(200, "statistics_thread_runner: Doing work at %ld\n", now); /* * Do nothing if no job is running currently. */ if (job_count() == 0) { if (!need_flush) { Dmsg0(200, "statistics_thread_runner: do nothing as no jobs are running\n"); wait_for_next_run(); continue; } else { /* * Flush any pending statistics data one more time and then sleep until new jobs start running. */ Dmsg0(200, "statistics_thread_runner: flushing pending statistics\n"); need_flush = false; } } else { /* * We have running jobs so on a next run we still need to flush any collected data. */ need_flush = true; } while (1) { BSOCK *sd; STORERES *store; int64_t StorageId; LockRes(); if ((current_store.c_str())[0]) { store = (STORERES *)GetResWithName(R_STORAGE, current_store.c_str()); } else { store = NULL; } store = (STORERES *)GetNextRes(R_STORAGE, (RES *)store); if (!store) { pm_strcpy(current_store, ""); UnlockRes(); break; } pm_strcpy(current_store, store->name()); if (!store->collectstats) { UnlockRes(); continue; } switch (store->Protocol) { case APT_NATIVE: break; default: UnlockRes(); continue; } /* * Try connecting 2 times with a max time to wait of 1 seconds. * We don't want to lock the resources to long. And as the stored * will cache the stats anyway we can always try collecting things * in the next run. */ jcr->res.rstore = store; if (!connect_to_storage_daemon(jcr, 2, 1, false)) { UnlockRes(); continue; } StorageId = store->StorageId; sd = jcr->store_bsock; UnlockRes(); /* * Do our work retrieving the statistics from the remote SD. */ if (sd->fsend("stats")) { while (bnet_recv(sd) >= 0) { Dmsg1(200, "msg); if (bstrncmp(sd->msg, "Devicestats", 10)) { POOL_MEM DevName(PM_NAME); DEVICE_STATS_DBR dsr; memset(&dsr, 0, sizeof(dsr)); if (sscanf(sd->msg, DevStats, &dsr.SampleTime, DevName.c_str(), &dsr.ReadBytes, &dsr.WriteBytes, &dsr.SpoolSize, &dsr.NumWaiting, &dsr.NumWriters, &dsr.ReadTime, &dsr.WriteTime, &dsr.MediaId, &dsr.VolCatBytes, &dsr.VolCatFiles, &dsr.VolCatBlocks) == 13) { Dmsg5(200, "New Devstats [%lld]: Device=%s Read=%llu, Write=%llu, SpoolSize=%llu,\n", dsr.SampleTime, DevName.c_str(), dsr.ReadBytes, dsr.WriteBytes, dsr.SpoolSize); Dmsg4(200, "NumWaiting=%lu, NumWriters=%lu, ReadTime=%lld, WriteTime=%lld,\n", dsr.NumWaiting, dsr.NumWriters, dsr.ReadTime, dsr.WriteTime); Dmsg4(200, "MediaId=%ld, VolBytes=%llu, VolFiles=%llu, VolBlocks=%llu\n", dsr.MediaId, dsr.VolCatBytes, dsr.VolCatFiles, dsr.VolCatBlocks); if (!lookup_device(jcr, DevName.c_str(), StorageId, &dsr.DeviceId)) { continue; } if (!db_create_device_statistics(jcr, jcr->db, &dsr)) { continue; } } else { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), sd->msg); } } else if (bstrncmp(sd->msg, "Tapealerts", 10)) { POOL_MEM DevName(PM_NAME); TAPEALERT_STATS_DBR tsr; memset(&tsr, 0, sizeof(tsr)); if (sscanf(sd->msg, TapeAlerts, &tsr.SampleTime, DevName.c_str(), &tsr.AlertFlags) == 3) { unbash_spaces(DevName); Dmsg3(200, "New stats [%lld]: Device %s TapeAlert %llu\n", tsr.SampleTime, DevName.c_str(), tsr.AlertFlags); if (!lookup_device(jcr, DevName.c_str(), StorageId, &tsr.DeviceId)) { continue; } if (!db_create_tapealert_statistics(jcr, jcr->db, &tsr)) { continue; } } else { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), sd->msg); } } else if (bstrncmp(sd->msg, "Jobstats", 8)) { POOL_MEM DevName(PM_NAME); JOB_STATS_DBR jsr; memset(&jsr, 0, sizeof(jsr)); if (sscanf(sd->msg, JobStats, &jsr.SampleTime, &jsr.JobId, &jsr.JobFiles, &jsr.JobBytes, DevName.c_str()) == 5) { unbash_spaces(DevName); Dmsg5(200, "New Jobstats [%lld]: JobId %ld, JobFiles %lu, JobBytes %llu, DevName %s\n", jsr.SampleTime, jsr.JobId, jsr.JobFiles, jsr.JobBytes, DevName.c_str()); if (!lookup_device(jcr, DevName.c_str(), StorageId, &jsr.DeviceId)) { continue; } if (!db_create_job_statistics(jcr, jcr->db, &jsr)) { continue; } } else { Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), sd->msg); } } } } /* * Disconnect. */ jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; } wait_for_next_run(); } db_sql_close_pooled_connection(jcr, jcr->db); bail_out: free_jcr(jcr); return NULL; } int start_statistics_thread(void) { int status; if (!me->stats_collect_interval) { return 0; } if ((status = pthread_create(&statistics_tid, NULL, statistics_thread_runner, NULL)) != 0) { return status; } statistics_initialized = true; return 0; } void stop_statistics_thread() { if (!statistics_initialized) { return; } quit = true; pthread_cond_broadcast(&wait_for_next_run_cond); if (!pthread_equal(statistics_tid, pthread_self())) { pthread_join(statistics_tid, NULL); } } void stats_job_started() { /* * A new Job was started so we need to flush any pending statistics the next run. */ if (!statistics_initialized) { need_flush = true; } } bareos-Release-14.2.6/src/dird/testfind.c000066400000000000000000000457271263011562700201540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Test program for find files * * Kern Sibbald, MM */ #include "bareos.h" #include "dird/dird.h" #include "findlib/find.h" #include "lib/mntent_cache.h" #include "ch.h" #if defined(HAVE_WIN32) #define isatty(fd) (fd==0) #endif /* Dummy functions */ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) { } extern bool parse_dir_config(CONFIG *config, const char *configfile, int exit_code); /* Global variables */ static int num_files = 0; static int max_file_len = 0; static int max_path_len = 0; static int trunc_fname = 0; static int trunc_path = 0; static int attrs = 0; DIRRES *me = NULL; /* Our Global resource */ CONFIG *my_config = NULL; /* Our Global config */ static JCR *jcr; static int print_file(JCR *jcr, FF_PKT *ff, bool); static void count_files(FF_PKT *ff); static bool copy_fileset(FF_PKT *ff, JCR *jcr); static void set_options(findFOPTS *fo, const char *opts); static void usage() { fprintf(stderr, _( "\n" "Usage: testfind [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -c specify config file containing FileSet resources\n" " -f specify which FileSet to use\n" " -? print this message.\n" "\n" "Patterns are used for file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors are always printed.\n" "Files/paths truncated is the number of files/paths with len > 255.\n" "Truncation is only in the catalog.\n" "\n")); exit(1); } int main (int argc, char *const *argv) { FF_PKT *ff; const char *configfile = "bareos-dir.conf"; const char *fileset_name = "Windows-Full-Set"; int ch, hard_links; OSDependentInit(); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); lmgr_init_thread(); while ((ch = getopt(argc, argv, "ac:d:f:?")) != -1) { switch (ch) { case 'a': /* print extended attributes *debug* */ attrs = 1; break; case 'c': /* set debug level */ configfile = optarg; break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* exclude patterns */ fileset_name = optarg; break; case '?': default: usage(); } } argc -= optind; argv += optind; my_config = new_config_parser(); parse_dir_config(my_config, configfile, M_ERROR_TERM); MSGSRES *msg; foreach_res(msg, R_MSGS) { init_msg(NULL, msg); } jcr = new_jcr(sizeof(JCR), NULL); jcr->res.fileset = (FILESETRES *)GetResWithName(R_FILESET, fileset_name); if (jcr->res.fileset == NULL) { fprintf(stderr, "%s: Fileset not found\n", fileset_name); FILESETRES *var; fprintf(stderr, "Valid FileSets:\n"); foreach_res(var, R_FILESET) { fprintf(stderr, " %s\n", var->hdr.name); } exit(1); } ff = init_find_files(); copy_fileset(ff, jcr); find_files(jcr, ff, print_file, NULL); free_jcr(jcr); if (my_config) { my_config->free_resources(); free(my_config); my_config = NULL; } term_last_jobs_list(); /* Clean up fileset */ findFILESET *fileset = ff->fileset; if (fileset) { int i, j, k; /* Delete FileSet Include lists */ for (i=0; iinclude_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); for (j=0; jopts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); for (k=0; kregex.size(); k++) { regfree((regex_t *)fo->regex.get(k)); } fo->regex.destroy(); fo->regexdir.destroy(); fo->regexfile.destroy(); fo->wild.destroy(); fo->wilddir.destroy(); fo->wildfile.destroy(); fo->wildbase.destroy(); fo->fstype.destroy(); fo->drivetype.destroy(); } incexe->opts_list.destroy(); incexe->name_list.destroy(); } fileset->include_list.destroy(); /* Delete FileSet Exclude lists */ for (i=0; iexclude_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); for (j=0; jopts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); fo->regex.destroy(); fo->regexdir.destroy(); fo->regexfile.destroy(); fo->wild.destroy(); fo->wilddir.destroy(); fo->wildfile.destroy(); fo->wildbase.destroy(); fo->fstype.destroy(); fo->drivetype.destroy(); } incexe->opts_list.destroy(); incexe->name_list.destroy(); } fileset->exclude_list.destroy(); free(fileset); } ff->fileset = NULL; hard_links = term_find_files(ff); printf(_("\n" "Total files : %d\n" "Max file length: %d\n" "Max path length: %d\n" "Files truncated: %d\n" "Paths truncated: %d\n" "Hard links : %d\n"), num_files, max_file_len, max_path_len, trunc_fname, trunc_path, hard_links); flush_mntent_cache(); term_msg(); close_memory_pool(); lmgr_cleanup_main(); sm_dump(false); exit(0); } static int print_file(JCR *jcr, FF_PKT *ff, bool top_level) { switch (ff->type) { case FT_LNKSAVED: if (debug_level == 1) { printf("%s\n", ff->fname); } else if (debug_level > 1) { printf("Lnka: %s -> %s\n", ff->fname, ff->link); } break; case FT_REGE: if (debug_level == 1) { printf("%s\n", ff->fname); } else if (debug_level > 1) { printf("Empty: %s\n", ff->fname); } count_files(ff); break; case FT_REG: if (debug_level == 1) { printf("%s\n", ff->fname); } else if (debug_level > 1) { printf(_("Reg: %s\n"), ff->fname); } count_files(ff); break; case FT_LNK: if (debug_level == 1) { printf("%s\n", ff->fname); } else if (debug_level > 1) { printf("Lnk: %s -> %s\n", ff->fname, ff->link); } count_files(ff); break; case FT_DIRBEGIN: return 1; case FT_NORECURSE: case FT_NOFSCHG: case FT_INVALIDFS: case FT_INVALIDDT: case FT_DIREND: if (debug_level) { char errmsg[100] = ""; if (ff->type == FT_NORECURSE) { bstrncpy(errmsg, _("\t[will not descend: recursion turned off]"), sizeof(errmsg)); } else if (ff->type == FT_NOFSCHG) { bstrncpy(errmsg, _("\t[will not descend: file system change not allowed]"), sizeof(errmsg)); } else if (ff->type == FT_INVALIDFS) { bstrncpy(errmsg, _("\t[will not descend: disallowed file system]"), sizeof(errmsg)); } else if (ff->type == FT_INVALIDDT) { bstrncpy(errmsg, _("\t[will not descend: disallowed drive type]"), sizeof(errmsg)); } printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg); } ff->type = FT_DIREND; count_files(ff); break; case FT_SPEC: if (debug_level == 1) { printf("%s\n", ff->fname); } else if (debug_level > 1) { printf("Spec: %s\n", ff->fname); } count_files(ff); break; case FT_NOACCESS: printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno)); break; case FT_NOFOLLOW: printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno)); break; case FT_NOSTAT: printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno)); break; case FT_NOCHG: printf(_("Skip: File not saved. No change. %s\n"), ff->fname); break; case FT_ISARCH: printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname); break; case FT_NOOPEN: printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno)); break; default: printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname); break; } if (attrs) { char attr[200]; encode_attribsEx(NULL, attr, ff); if (*attr != 0) { printf("AttrEx=%s\n", attr); } // set_attribsEx(NULL, ff->fname, NULL, NULL, ff->type, attr); } return 1; } static void count_files(FF_PKT *ar) { int fnl, pnl; char *l, *p; POOL_MEM file(PM_FNAME); POOL_MEM spath(PM_FNAME); num_files++; /* Find path without the filename. * I.e. everything after the last / is a "filename". * OK, maybe it is a directory name, but we treat it like * a filename. If we don't find a / then the whole name * must be a path name (e.g. c:). */ for (p=l=ar->fname; *p; p++) { if (IsPathSeparator(*p)) { l = p; /* set pos of last slash */ } } if (IsPathSeparator(*l)) { /* did we find a slash? */ l++; /* yes, point to filename */ } else { /* no, whole thing must be path name */ l = p; } /* If filename doesn't exist (i.e. root directory), we * simply create a blank name consisting of a single * space. This makes handling zero length filenames * easier. */ fnl = p - l; if (fnl > max_file_len) { max_file_len = fnl; } if (fnl > 255) { printf(_("===== Filename truncated to 255 chars: %s\n"), l); fnl = 255; trunc_fname++; } if (fnl > 0) { pm_strcpy(file, l); /* copy filename */ } else { pm_strcpy(file, " "); /* blank filename */ } pnl = l - ar->fname; if (pnl > max_path_len) { max_path_len = pnl; } if (pnl > 255) { printf(_("========== Path name truncated to 255 chars: %s\n"), ar->fname); pnl = 255; trunc_path++; } pm_strcpy(spath, ar->fname); if (pnl == 0) { pm_strcpy(spath, " "); printf(_("========== Path length is zero. File=%s\n"), ar->fname); } if (debug_level >= 10) { printf(_("Path: %s\n"), spath.c_str()); printf(_("File: %s\n"), file.c_str()); } } static bool copy_fileset(FF_PKT *ff, JCR *jcr) { FILESETRES *jcr_fileset = jcr->res.fileset; int num; bool include = true; findFILESET *fileset; findFOPTS *current_opts; fileset = (findFILESET *)malloc(sizeof(findFILESET)); memset(fileset, 0, sizeof(findFILESET)); ff->fileset = fileset; fileset->state = state_none; fileset->include_list.init(1, true); fileset->exclude_list.init(1, true); for ( ;; ) { if (include) { num = jcr_fileset->num_includes; } else { num = jcr_fileset->num_excludes; } for (int i=0; iinclude_items[i]; /* New include */ fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE)); memset(fileset->incexe, 0, sizeof(findINCEXE)); fileset->incexe->opts_list.init(1, true); fileset->incexe->name_list.init(0, 0); fileset->include_list.append(fileset->incexe); } else { ie = jcr_fileset->exclude_items[i]; /* New exclude */ fileset->incexe = (findINCEXE *)malloc(sizeof(findINCEXE)); memset(fileset->incexe, 0, sizeof(findINCEXE)); fileset->incexe->opts_list.init(1, true); fileset->incexe->name_list.init(0, 0); fileset->exclude_list.append(fileset->incexe); } for (j=0; jnum_opts; j++) { FOPTS *fo = ie->opts_list[j]; current_opts = (findFOPTS *)malloc(sizeof(findFOPTS)); memset(current_opts, 0, sizeof(findFOPTS)); fileset->incexe->current_opts = current_opts; fileset->incexe->opts_list.append(current_opts); current_opts->regex.init(1, true); current_opts->regexdir.init(1, true); current_opts->regexfile.init(1, true); current_opts->wild.init(1, true); current_opts->wilddir.init(1, true); current_opts->wildfile.init(1, true); current_opts->wildbase.init(1, true); current_opts->fstype.init(1, true); current_opts->drivetype.init(1, true); set_options(current_opts, fo->opts); for (k=0; kregex.size(); k++) { // fd->fsend("R %s\n", fo->regex.get(k)); current_opts->regex.append(bstrdup((const char *)fo->regex.get(k))); } for (k=0; kregexdir.size(); k++) { // fd->fsend("RD %s\n", fo->regexdir.get(k)); current_opts->regexdir.append(bstrdup((const char *)fo->regexdir.get(k))); } for (k=0; kregexfile.size(); k++) { // fd->fsend("RF %s\n", fo->regexfile.get(k)); current_opts->regexfile.append(bstrdup((const char *)fo->regexfile.get(k))); } for (k=0; kwild.size(); k++) { current_opts->wild.append(bstrdup((const char *)fo->wild.get(k))); } for (k=0; kwilddir.size(); k++) { current_opts->wilddir.append(bstrdup((const char *)fo->wilddir.get(k))); } for (k=0; kwildfile.size(); k++) { current_opts->wildfile.append(bstrdup((const char *)fo->wildfile.get(k))); } for (k=0; kwildbase.size(); k++) { current_opts->wildbase.append(bstrdup((const char *)fo->wildbase.get(k))); } for (k=0; kfstype.size(); k++) { current_opts->fstype.append(bstrdup((const char *)fo->fstype.get(k))); } for (k=0; kdrivetype.size(); k++) { current_opts->drivetype.append(bstrdup((const char *)fo->drivetype.get(k))); } } for (j=0; jname_list.size(); j++) { fileset->incexe->name_list.append(bstrdup((const char *)ie->name_list.get(j))); } } if (!include) { /* If we just did excludes */ break; /* all done */ } include = false; /* Now do excludes */ } return true; } static void set_options(findFOPTS *fo, const char *opts) { int j; const char *p; for (p=opts; *p; p++) { switch (*p) { case 'a': /* alway replace */ case '0': /* no option */ break; case 'e': set_bit(FO_EXCLUDE, fo->flags); break; case 'f': set_bit(FO_MULTIFS, fo->flags); break; case 'h': /* no recursion */ set_bit(FO_NO_RECURSION, fo->flags); break; case 'H': /* no hard link handling */ set_bit(FO_NO_HARDLINK, fo->flags); break; case 'i': set_bit(FO_IGNORECASE, fo->flags); break; case 'M': /* MD5 */ set_bit(FO_MD5, fo->flags); break; case 'n': set_bit(FO_NOREPLACE, fo->flags); break; case 'p': /* use portable data format */ set_bit(FO_PORTABLE, fo->flags); break; case 'R': /* Resource forks and Finder Info */ set_bit(FO_HFSPLUS, fo->flags); case 'r': /* read fifo */ set_bit(FO_READFIFO, fo->flags); break; case 'S': switch(*(p + 1)) { case ' ': /* Old director did not specify SHA variant */ set_bit(FO_SHA1, fo->flags); break; case '1': set_bit(FO_SHA1, fo->flags); p++; break; #ifdef HAVE_SHA2 case '2': set_bit(FO_SHA256, fo->flags); p++; break; case '3': set_bit(FO_SHA512, fo->flags); p++; break; #endif default: /* Automatically downgrade to SHA-1 if an unsupported * SHA variant is specified */ set_bit(FO_SHA1, fo->flags); p++; break; } break; case 's': set_bit(FO_SPARSE, fo->flags); break; case 'm': set_bit(FO_MTIMEONLY, fo->flags); break; case 'k': set_bit(FO_KEEPATIME, fo->flags); break; case 'A': set_bit(FO_ACL, fo->flags); break; case 'V': /* verify options */ /* Copy Verify Options */ for (j=0; *p && *p != ':'; p++) { fo->VerifyOpts[j] = *p; if (j < (int)sizeof(fo->VerifyOpts) - 1) { j++; } } fo->VerifyOpts[j] = 0; break; case 'w': set_bit(FO_IF_NEWER, fo->flags); break; case 'W': set_bit(FO_ENHANCEDWILD, fo->flags); break; case 'Z': /* compression */ p++; /* skip Z */ if (*p >= '0' && *p <= '9') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_GZIP; fo->Compress_level = *p - '0'; } else if (*p == 'o') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_LZO1X; fo->Compress_level = 1; /* not used with LZO */ } Dmsg2(200, "Compression alg=%d level=%d\n", fo->Compress_algo, fo->Compress_level); break; case 'x': set_bit(FO_NO_AUTOEXCL, fo->flags); break; case 'X': set_bit(FO_XATTR, fo->flags); break; default: Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p); break; } } } bareos-Release-14.2.6/src/dird/ua.h000066400000000000000000000141401263011562700167270ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Includes specific to the Director User Agent Server * * Kern Sibbald, August MMI */ #ifndef __UA_H_ #define __UA_H_ 1 #define MAX_ID_LIST_LEN 2000000 class UAContext { public: BSOCK *UA_sock; BSOCK *sd; JCR *jcr; B_DB *db; B_DB *shared_db; /* Shared database connection used by multiple ua's */ B_DB *private_db; /* Private database connection only used by this ua */ CATRES *catalog; CONRES *cons; /* Console resource */ POOLMEM *cmd; /* Return command/name buffer */ POOLMEM *args; /* Command line arguments */ POOLMEM *errmsg; /* Store error message */ char *argk[MAX_CMD_ARGS]; /* Argument keywords */ char *argv[MAX_CMD_ARGS]; /* Argument values */ int argc; /* Number of arguments */ char **prompt; /* List of prompts */ int max_prompts; /* Max size of list */ int num_prompts; /* Current number in list */ int api; /* For programs want an API */ int cmd_index; /* Index in command table */ bool auto_display_messages; /* If set, display messages */ bool user_notified_msg_pending; /* Set when user notified */ bool automount; /* If set, mount after label */ bool quit; /* If set, quit */ bool verbose; /* Set for normal UA verbosity */ bool batch; /* Set for non-interactive mode */ bool gui; /* Set if talking to GUI program */ bool runscript; /* Set if we are in runscript */ uint32_t pint32_val; /* Positive integer */ int32_t int32_val; /* Positive/negative */ int64_t int64_val; /* Big int */ void signal(int sig) { UA_sock->signal(sig); }; /* The below are in ua_output.c */ void send_msg(const char *fmt, ...); void error_msg(const char *fmt, ...); void warning_msg(const char *fmt, ...); void info_msg(const char *fmt, ...); }; /* * Context for insert_tree_handler() */ struct TREE_CTX { TREE_ROOT *root; /* Root */ TREE_NODE *node; /* Current node */ TREE_NODE *avail_node; /* Unused node last insert */ int cnt; /* Count for user feedback */ bool all; /* If set mark all as default */ UAContext *ua; uint32_t FileEstimate; /* Estimate of number of files */ uint32_t FileCount; /* Current count of files */ uint32_t LastCount; /* Last count of files */ uint32_t DeltaCount; /* Trigger for printing */ }; struct NAME_LIST { char **name; /* List of names */ int num_ids; /* Ids stored */ int max_ids; /* Size of array */ int num_del; /* Number deleted */ int tot_ids; /* Total to process */ }; /* * Context for restore job. */ struct RESTORE_CTX { utime_t JobTDate; uint32_t TotalFiles; JobId_t JobId; char *backup_format; char *ClientName; /* Backup client */ char *RestoreClientName; /* Restore client */ char last_jobid[20]; POOLMEM *JobIds; /* User entered string of JobIds */ POOLMEM *BaseJobIds; /* Base jobids */ STORERES *store; JOBRES *restore_job; POOLRES *pool; int restore_jobs; uint32_t selected_files; char *comment; char *where; char *RegexWhere; char *replace; char *plugin_options; RBSR *bsr; POOLMEM *fname; /* Filename only */ POOLMEM *path; /* Path only */ POOLMEM *query; int fnl; /* Filename length */ int pnl; /* Path length */ bool found; bool all; /* Mark all as default */ NAME_LIST name_list; }; /* * Context for run job. */ class RUN_CTX { public: char *backup_format; char *bootstrap; char *catalog_name; char *client_name; char *comment; char *fileset_name; char *jid; char *job_name; char *level_name; char *next_pool_name; char *plugin_options; char *pool_name; char *previous_job_name; char *regexwhere; char *restore_client_name; char *since; char *store_name; char *verify_job_name; char *when; char *where; const char *replace; const char *verify_list; JOBRES *job; JOBRES *verify_job; JOBRES *previous_job; USTORERES *store; CLIENTRES *client; FILESETRES *fileset; POOLRES *pool; POOLRES *next_pool; CATRES *catalog; int Priority; int files; int spool_data; int accurate; int ignoreduplicatecheck; bool cloned; bool mod; bool spool_data_set; bool nextpool_set; bool accurate_set; bool ignoreduplicatecheck_set; /* * Methods */ RUN_CTX() { memset(this, 0, sizeof(RUN_CTX)); store = new USTORERES; }; ~RUN_CTX() { delete store; }; }; #endif bareos-Release-14.2.6/src/dird/ua_acl.c000066400000000000000000000126541263011562700175510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2008 Free Software Foundation Europe e.V. Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Access Control List (ACL) handling * * Kern Sibbald, January MMIV */ #include "bareos.h" #include "dird.h" /* * Check if access is permitted to item in acl */ bool acl_access_ok(UAContext *ua, int acl, const char *item, bool audit_event) { return acl_access_ok(ua, acl, item, strlen(item), audit_event); } /* * Loop over the items in the alist and verify if they match the given item * that access was requested for. */ static inline bool find_in_acl_list(alist *list, int acl, const char *item, int len) { int rc; regex_t preg; bool retval = false; const char *list_value; /* * See if we have an empty list. */ if (!list) { /* * Empty list for Where => empty where accept anything. * For any other list, reject everything. */ if (len == 0 && acl == Where_ACL) { Dmsg0(1400, "Empty Where_ACL allowing restore anywhere\n"); retval = true; } goto bail_out; } /* * Search list for item */ for (int i = 0; i < list->size(); i++) { list_value = (char *)list->get(i); /* * See if this is a deny acl. */ if (*list_value == '!') { if (bstrcasecmp(item, list_value + 1)) { /* * Explicit deny. */ Dmsg3(1400, "Deny ACL found %s in %d %s\n", item, acl, list_value); goto bail_out; } /* * If we didn't get an exact match see if we can use the pattern as a regex. */ rc = regcomp(&preg, list_value + 1, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (rc != 0) { /* * Not a valid regular expression so skip it. */ Dmsg1(1400, "Not a valid regex %s, ignoring for regex compare\n", list_value); continue; } if (regexec(&preg, item, 0, NULL, 0) == 0) { Dmsg3(1400, "ACL found %s in %d using regex %s\n", item, acl, list_value); regfree(&preg); goto bail_out; } regfree(&preg); } else { /* * Special case *all* gives full access */ if (bstrcasecmp("*all*", list_value)) { Dmsg2(1400, "Global ACL found in %d %s\n", acl, list_value); retval = true; goto bail_out; } if (bstrcasecmp(item, list_value)) { Dmsg3(1400, "ACL found %s in %d %s\n", item, acl, list_value); retval = true; goto bail_out; } /* * If we didn't get an exact match see if we can use the pattern as a regex. */ rc = regcomp(&preg, list_value, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (rc != 0) { /* * Not a valid regular expression so skip it. */ Dmsg1(1400, "Not a valid regex %s, ignoring for regex compare\n", list_value); continue; } if (regexec(&preg, item, 0, NULL, 0) == 0) { Dmsg3(1400, "ACL found %s in %d using regex %s\n", item, acl, list_value); retval = true; regfree(&preg); goto bail_out; } regfree(&preg); } } bail_out: return retval; } /* * This version expects the length of the item which we must check. */ bool acl_access_ok(UAContext *ua, int acl, const char *item, int len, bool audit_event) { bool retval = false; /* * The resource name contains nasty characters */ switch (acl) { case Where_ACL: case PluginOptions_ACL: break; default: if (!is_name_valid(item, NULL)) { Dmsg1(1400, "Access denied for item=%s\n", item); goto bail_out; } break; } /* * If no console resource => default console and all is permitted */ if (!ua->cons) { Dmsg0(1400, "Root cons access OK.\n"); retval = true; goto bail_out; } retval = find_in_acl_list(ua->cons->ACL_lists[acl], acl, item, len); /* * If we didn't find a matching ACL try to use the profiles this console is connected to. */ if (!retval && ua->cons->profiles && ua->cons->profiles->size()) { PROFILERES *profile; foreach_alist(profile, ua->cons->profiles) { retval = find_in_acl_list(profile->ACL_lists[acl], acl, item, len); /* * If we found a match break the loop. */ if (retval) { break; } } } bail_out: if (audit_event && !retval) { log_audit_event_acl_failure(ua, acl, item); } return retval; } bareos-Release-14.2.6/src/dird/ua_audit.c000066400000000000000000000070411263011562700201120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User agent auditing. * * Written by Marco van Wieringen, April 2014 */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ /* * See if we need to audit this event. */ bool audit_event_wanted(UAContext *ua, bool audit_event_enabled) { if (!me->audit_events) { return audit_event_enabled; } if (audit_event_enabled) { const char *event; foreach_alist(event, me->audit_events) { if (bstrcasecmp(event, ua->argk[0])) { return true; } } } return false; } /* * Log an audit event for a console that accesses an resource or cmd that is not allowed. */ static inline void log_audit_event_acl_msg(UAContext *ua, const char *audit_msg, int acl, const char *item) { const char *console_name; const char *host; const char *acl_type_name; console_name = (ua->cons) ? ua->cons->name() : "default"; host = (ua->UA_sock) ? ua->UA_sock->host() : "unknown"; switch (acl) { case Job_ACL: acl_type_name = _("for Job"); break; case Client_ACL: acl_type_name = _("for Client"); break; case Storage_ACL: acl_type_name = _("for Storage"); break; case Schedule_ACL: acl_type_name = _("for Schedule"); break; case Run_ACL: acl_type_name = _("for Schedule"); break; case Pool_ACL: acl_type_name = _("for Pool"); break; case Command_ACL: acl_type_name = _("for Command"); break; case FileSet_ACL: acl_type_name = _("for Fileset"); break; case Catalog_ACL: acl_type_name = _("for Catalog"); break; case Where_ACL: acl_type_name = _("for Where restore location"); break; case PluginOptions_ACL: acl_type_name = _("for Plugin Options"); break; default: acl_type_name = ""; break; } Emsg4(M_AUDIT, 0, audit_msg, console_name, host, acl_type_name, item); } void log_audit_event_acl_failure(UAContext *ua, int acl, const char *item) { if (!me->auditing) { return; } log_audit_event_acl_msg(ua, _("Console [%s] from [%s], Audit acl failure %s %s\n"), acl, item); } void log_audit_event_acl_success(UAContext *ua, int acl, const char *item) { if (!me->auditing) { return; } log_audit_event_acl_msg(ua, _("Console [%s] from [%s], Audit acl success %s %s\n"), acl, item); } /* * Log an audit event */ void log_audit_event_cmdline(UAContext *ua) { const char *console_name; const char *host; if (!me->auditing) { return; } console_name = (ua->cons) ? ua->cons->name() : "default"; host = (ua->UA_sock) ? ua->UA_sock->host() : "unknown"; Emsg3(M_AUDIT, 0, _("Console [%s] from [%s] cmdline %s\n"), console_name, host, ua->cmd); } bareos-Release-14.2.6/src/dird/ua_cmds.c000066400000000000000000002260471263011562700177430ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Commands * * Kern Sibbald, September MM */ #include "bareos.h" #include "dird.h" /* Imported subroutines */ /* Imported variables */ extern jobq_t job_queue; /* job queue */ /* Imported functions */ extern int autodisplay_cmd(UAContext *ua, const char *cmd); extern int configure_cmd(UAContext *ua, const char *cmd); extern int gui_cmd(UAContext *ua, const char *cmd); extern int label_cmd(UAContext *ua, const char *cmd); extern int list_cmd(UAContext *ua, const char *cmd); extern int llist_cmd(UAContext *ua, const char *cmd); extern int messages_cmd(UAContext *ua, const char *cmd); extern int prune_cmd(UAContext *ua, const char *cmd); extern int purge_cmd(UAContext *ua, const char *cmd); extern int query_cmd(UAContext *ua, const char *cmd); extern int relabel_cmd(UAContext *ua, const char *cmd); extern int restore_cmd(UAContext *ua, const char *cmd); extern int show_cmd(UAContext *ua, const char *cmd); extern int sqlquery_cmd(UAContext *ua, const char *cmd); extern int status_cmd(UAContext *ua, const char *cmd); extern int update_cmd(UAContext *ua, const char *cmd); /* Forward referenced functions */ static int add_cmd(UAContext *ua, const char *cmd); static int automount_cmd(UAContext *ua, const char *cmd); static int cancel_cmd(UAContext *ua, const char *cmd); static int create_cmd(UAContext *ua, const char *cmd); static int delete_cmd(UAContext *ua, const char *cmd); static int disable_cmd(UAContext *ua, const char *cmd); static int enable_cmd(UAContext *ua, const char *cmd); static int estimate_cmd(UAContext *ua, const char *cmd); static int help_cmd(UAContext *ua, const char *cmd); static int memory_cmd(UAContext *ua, const char *cmd); static int mount_cmd(UAContext *ua, const char *cmd); static int release_cmd(UAContext *ua, const char *cmd); static int reload_cmd(UAContext *ua, const char *cmd); static int setdebug_cmd(UAContext *ua, const char *cmd); static int setbwlimit_cmd(UAContext *ua, const char *cmd); static int setip_cmd(UAContext *ua, const char *cmd); static int time_cmd(UAContext *ua, const char *cmd); static int resolve_cmd(UAContext *ua, const char *cmd); static int trace_cmd(UAContext *ua, const char *cmd); static int unmount_cmd(UAContext *ua, const char *cmd); static int use_cmd(UAContext *ua, const char *cmd); static int var_cmd(UAContext *ua, const char *cmd); static int version_cmd(UAContext *ua, const char *cmd); static int wait_cmd(UAContext *ua, const char *cmd); static void do_job_delete(UAContext *ua, JobId_t JobId); static bool delete_job_id_range(UAContext *ua, char *tok); static int delete_volume(UAContext *ua); static int delete_pool(UAContext *ua); static void delete_job(UAContext *ua); int qhelp_cmd(UAContext *ua, const char *cmd); int quit_cmd(UAContext *ua, const char *cmd); /* * Not all in alphabetical order. * New commands are added after existing commands with similar letters * to prevent breakage of existing user scripts. */ struct cmdstruct { const char *key; /* Command */ int (*func)(UAContext *ua, const char *cmd); /* Handler */ const char *help; /* Main purpose */ const char *usage; /* All arguments to build usage */ const bool use_in_rs; /* Can use it in Console RunScript */ const bool audit_event; /* Log an audit event when this Command is executed */ }; static struct cmdstruct commands[] = { { NT_("add"), add_cmd, _("Add media to a pool"), NT_("pool= storage= jobid="), false, true }, { NT_("autodisplay"), autodisplay_cmd,_("Autodisplay console messages"), NT_("on | off"), false, false }, { NT_("automount"), automount_cmd, _("Automount after label"), NT_("on | off"), false, true }, { NT_("cancel"), cancel_cmd, _("Cancel a job"), NT_("storage= | jobid= | job= | ujobid= | state= | all yes"), false, true }, { NT_("configure"), configure_cmd, _("Configure director"), NT_("terminal"), false, true }, { NT_("create"), create_cmd, _("Create DB Pool from resource"), NT_("pool="), false, true }, { NT_("delete"), delete_cmd, _("Delete volume, pool or job"), NT_("volume= pool= jobid="), true, true }, { NT_("disable"), disable_cmd, _("Disable a job/client/schedule"), NT_("job= client= schedule="), true, true }, { NT_("enable"), enable_cmd, _("Enable a job/client/schedule"), NT_("job= client= schedule="), true, true }, { NT_("estimate"), estimate_cmd, _("Performs FileSet estimate, listing gives full listing"), NT_("fileset= client= level= accurate= job= listing"), true, true }, { NT_("exit"), quit_cmd, _("Terminate Bconsole session"), NT_(""), false, false }, { NT_("export"), export_cmd,_("Export volumes from normal slots to import/export slots"), NT_("storage= srcslots= [ dstslots= volume= scan ]"), true, true }, { NT_("gui"), gui_cmd, _("Non-interactive gui mode"), NT_("on | off"), false, false }, { NT_("help"), help_cmd, _("Print help on specific command"), NT_("add autodisplay automount cancel create delete disable\n" "\tenable estimate exit gui label list llist\n" "\tmessages memory mount prune purge quit query\n" "\trestore relabel release reload run status\n" "\tsetbandwidth setdebug setip show sqlquery time trace unmount\n" "\tumount update use var version wait"), false, false }, { NT_("import"), import_cmd, _("Import volumes from import/export slots to normal slots"), NT_("storage= [ srcslots= dstslots= volume= scan ]"), true, true }, { NT_("label"), label_cmd, _("Label a tape"), NT_("storage= volume= pool= slot= [ barcodes ] [ encrypt ]"), false, true }, { NT_("list"), list_cmd, _("List objects from catalog"), NT_("jobs | jobid= | ujobid= | job= | jobmedia jobid= |\n" "\tjobmedia ujobid= | joblog jobid= | joblog ujobid= |\n" "\tbasefiles jobid= | basefiles ujobid= |\n" "\tfiles jobid= | files ujobid= | pools | jobtotals |\n" "\tvolumes [ jobid= ujobid= pool= ] |\n" "\tmedia [ jobid= ujobid= pool= ] | clients |\n" "\tnextvol job= | nextvolume ujobid= | copies jobid="), true, true }, { NT_("llist"), llist_cmd, _("Full or long list like list command"), NT_("jobs | jobid= | ujobid= | job= | jobmedia jobid= |\n" "\tjobmedia ujobid= | joblog jobid= | joblog ujobid= |\n" "\tbasefiles jobid= | basefiles ujobid= |\n" "\tfiles jobid= | files ujobid= | pools | jobtotals |\n" "\tvolumes [ jobid= ujobid= pool= ] |\n" "\tmedia [ jobid= ujobid= pool= ] | clients |\n" "\tnextvol job= | nextvolume ujobid= | copies jobid="), true, true }, { NT_("messages"), messages_cmd, _("Display pending messages"), NT_(""), false, false }, { NT_("memory"), memory_cmd, _("Print current memory usage"), NT_(""), true, false }, { NT_("mount"), mount_cmd, _("Mount storage"), NT_("storage= slot= drive=\n" "\tjobid= | job= | ujobid="), false, true }, { NT_("move"), move_cmd, _("Move slots in an autochanger"), NT_("storage= srcslots= dstslots="), true, true }, { NT_("prune"), prune_cmd, _("Prune records from catalog"), NT_("files | jobs | jobtype= | pool= | client= | volume= | directory= | recursive"), true, true }, { NT_("purge"), purge_cmd, _("Purge records from catalog"), NT_("files jobs volume= [ action= devicetype= pool=\n" "\tallpools storage= drive= ]"), true, true }, { NT_("quit"), quit_cmd, _("Terminate Bconsole session"), NT_(""), false, false }, { NT_("query"), query_cmd, _("Query catalog"), NT_(""), false, true }, { NT_("restore"), restore_cmd, _("Restore files"), NT_("where= client= storage= bootstrap=\n" "\trestorejob= comment= jobid= fileset=\n" "\treplace= pluginoptions=\n" "\tregexwhere= restoreclient= backupformat=\n" "\tpool= file= directory= before=\n" "\tstrip_prefix= add_prefix= add_suffix=\n" "\tselect= select before current copies done all"), false, true }, { NT_("relabel"), relabel_cmd, _("Relabel a tape"), NT_("storage= oldvolume=\n" "\tvolume= pool= [ encrypt ]"), false, true }, { NT_("release"), release_cmd, _("Release storage"), NT_("storage= [ drive= ] [ alldrives ]"), false, true }, { NT_("reload"), reload_cmd, _("Reload conf file"), NT_(""), true, true }, { NT_("rerun"), rerun_cmd, _("Rerun a job"), NT_("jobid= | since_jobid= [ until_jobid= ] | days= | hours= | yes"), false, true }, { NT_("resolve"), resolve_cmd, _("Resolve a hostname"), NT_("client= | storage= "), false, true }, { NT_("run"), run_cmd, _("Run a job"), NT_("job= client= fileset= level=\n" "\tstorage= where= when=\n" "\tpool= pluginoptions= accurate= comment=\n" "\tspooldata= priority= jobid= catalog= migrationjob=<>\n" "\tbackupclient= backupformat= nextpool=\n" "\tsince= verifyjob= verifylist=\n" "\tmigrationjob= yes"), false, true }, { NT_("status"), status_cmd, _("Report status"), NT_("all | dir= | director | scheduler | schedule= | client= |\n" "\tstorage= slots | days= | job= | schedule= |\n" "\tsubscriptions" ), true, true }, { NT_("setbandwidth"), setbwlimit_cmd, _("Sets bandwidth"), NT_("client= | storage= | jobid= |\n" "\tjob= | ujobid= state= | all\n" "\tlimit= yes"), true, true }, { NT_("setdebug"), setdebug_cmd, _("Sets debug level"), NT_("level= trace=0/1 timestamp=0/1 client= | dir | storage= | all"), true, true }, { NT_("setip"), setip_cmd, _("Sets new client address -- if authorized"), NT_(""), false, true }, { NT_("show"), show_cmd, _("Show resource records"), NT_("jobdefs=| job= | pool= | fileset= |\n" "\tschedule= | client= | message= |\n" "\tprofile= | jobdefs | jobs | pools | filesets | schedules | clients |\n" "\tmessages | profiles | consoles | disabled | all"), true, true }, { NT_("sqlquery"), sqlquery_cmd, _("Use SQL to query catalog"), NT_(""), false, true }, { NT_("time"), time_cmd, _("Print current time"), NT_(""), true, false }, { NT_("trace"), trace_cmd, _("Turn on/off trace to file"), NT_("on | off"), true, true }, { NT_("unmount"), unmount_cmd, _("Unmount storage"), NT_("storage= [ drive= ]\n" "\tjobid= | job= | ujobid="), false, true }, { NT_("umount"), unmount_cmd, _("Umount - for old-time Unix guys, see unmount"), NT_("storage= [ drive= ]\n" "\tjobid= | job= | ujobid="), false, true }, { NT_("update"), update_cmd, _("Update volume, pool or stats"), NT_("stats\n" "\tpool=\n" "\tslots storage= scan\n" "\tvolume= volstatus= volretention=\n" "\tpool= recycle= slot=\n" "\tinchanger=\n" "\tmaxvolbytes= maxvolfiles= maxvoljobs=\n" "\tenabled= recyclepool= actiononpurge="), true, true }, { NT_("use"), use_cmd, _("Use specific catalog"), NT_("catalog="), false, true }, { NT_("var"), var_cmd, _("Does variable expansion"), NT_(""), false, true }, { NT_("version"), version_cmd, _("Print Director version"), NT_(""), true, false }, { NT_("wait"), wait_cmd, _("Wait until no jobs are running"), NT_("jobname= | jobid= | ujobid="), false, false } }; #define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct))) /* * Execute a command from the UA */ bool do_a_command(UAContext *ua) { int i; int len; bool ok = false; bool found = false; BSOCK *user = ua->UA_sock; Dmsg1(900, "Command: %s\n", ua->argk[0]); if (ua->argc == 0) { return false; } while (ua->jcr->wstorage->size()) { ua->jcr->wstorage->remove(0); } len = strlen(ua->argk[0]); for (i = 0; i < comsize; i++) { /* search for command */ if (bstrncasecmp(ua->argk[0], commands[i].key, len)) { /* * Check if command permitted, but "quit" is always OK */ if (!bstrcmp(ua->argk[0], NT_("quit")) && !acl_access_ok(ua, Command_ACL, ua->argk[0], len, true)) { break; } /* * Check if this command is authorized in RunScript */ if (ua->runscript && !commands[i].use_in_rs) { ua->error_msg(_("Can't use %s command in a runscript"), ua->argk[0]); break; } /* * If we need to audit this event do it now. */ if (audit_event_wanted(ua, commands[i].audit_event)) { log_audit_event_cmdline(ua); } if (ua->api) { user->signal(BNET_CMD_BEGIN); } ok = (*commands[i].func)(ua, ua->cmd); /* go execute command */ if (ua->api) { user->signal(ok ? BNET_CMD_OK : BNET_CMD_FAILED); } found = true; break; } } if (!found) { ua->error_msg(_("%s: is an invalid command.\n"), ua->argk[0]); ok = false; } return ok; } /* * This is a common routine used to stuff the Pool DB record defaults * into the Media DB record just before creating a media (Volume) * record. */ void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr) { mr->PoolId = pr->PoolId; bstrncpy(mr->VolStatus, NT_("Append"), sizeof(mr->VolStatus)); mr->Recycle = pr->Recycle; mr->VolRetention = pr->VolRetention; mr->VolUseDuration = pr->VolUseDuration; mr->ActionOnPurge = pr->ActionOnPurge; mr->RecyclePoolId = pr->RecyclePoolId; mr->MaxVolJobs = pr->MaxVolJobs; mr->MaxVolFiles = pr->MaxVolFiles; mr->MaxVolBytes = pr->MaxVolBytes; mr->LabelType = pr->LabelType; mr->MinBlocksize = pr->MinBlocksize; mr->MaxBlocksize = pr->MaxBlocksize; mr->Enabled = VOL_ENABLED; } /* * Add Volumes to an existing Pool */ static int add_cmd(UAContext *ua, const char *cmd) { POOL_DBR pr; MEDIA_DBR mr; int num, i, max, startnum; char name[MAX_NAME_LENGTH]; STORERES *store; int Slot = 0, InChanger = 0; ua->send_msg(_("You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" "You probably want to use the \"label\" command.\n\n")); if (!open_client_db(ua)) { return 1; } memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); if (!get_pool_dbr(ua, &pr)) { return 1; } Dmsg4(120, "id=%d Num=%d Max=%d type=%s\n", pr.PoolId, pr.NumVols, pr.MaxVols, pr.PoolType); while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) { ua->warning_msg(_("Pool already has maximum volumes=%d\n"), pr.MaxVols); if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) { return 1; } pr.MaxVols = ua->pint32_val; } /* Get media type */ if ((store = get_storage_resource(ua)) != NULL) { bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); } else if (!get_media_type(ua, mr.MediaType, sizeof(mr.MediaType))) { return 1; } if (pr.MaxVols == 0) { max = 1000; } else { max = pr.MaxVols - pr.NumVols; } for (;;) { char buf[100]; bsnprintf(buf, sizeof(buf), _("Enter number of Volumes to create. 0=>fixed name. Max=%d: "), max); if (!get_pint(ua, buf)) { return 1; } num = ua->pint32_val; if (num < 0 || num > max) { ua->warning_msg(_("The number must be between 0 and %d\n"), max); continue; } break; } for (;;) { if (num == 0) { if (!get_cmd(ua, _("Enter Volume name: "))) { return 1; } } else { if (!get_cmd(ua, _("Enter base volume name: "))) { return 1; } } /* Don't allow | in Volume name because it is the volume separator character */ if (!is_volume_name_legal(ua, ua->cmd)) { continue; } if (strlen(ua->cmd) >= MAX_NAME_LENGTH-10) { ua->warning_msg(_("Volume name too long.\n")); continue; } if (strlen(ua->cmd) == 0) { ua->warning_msg(_("Volume name must be at least one character long.\n")); continue; } break; } bstrncpy(name, ua->cmd, sizeof(name)); if (num > 0) { bstrncat(name, "%04d", sizeof(name)); for (;;) { if (!get_pint(ua, _("Enter the starting number: "))) { return 1; } startnum = ua->pint32_val; if (startnum < 1) { ua->warning_msg(_("Start number must be greater than zero.\n")); continue; } break; } } else { startnum = 1; num = 1; } if (store && store->autochanger) { if (!get_pint(ua, _("Enter slot (0 for none): "))) { return 1; } Slot = ua->pint32_val; if (!get_yesno(ua, _("InChanger? yes/no: "))) { return 1; } InChanger = ua->pint32_val; } set_pool_dbr_defaults_in_media_dbr(&mr, &pr); for (i=startnum; i < num+startnum; i++) { bsnprintf(mr.VolumeName, sizeof(mr.VolumeName), name, i); mr.Slot = Slot++; mr.InChanger = InChanger; mr.Enabled = VOL_ENABLED; set_storageid_in_mr(store, &mr); Dmsg1(200, "Create Volume %s\n", mr.VolumeName); if (!db_create_media_record(ua->jcr, ua->db, &mr)) { ua->error_msg("%s", db_strerror(ua->db)); return 1; } } pr.NumVols += num; Dmsg0(200, "Update pool record.\n"); if (db_update_pool_record(ua->jcr, ua->db, &pr) != 1) { ua->warning_msg("%s", db_strerror(ua->db)); return 1; } ua->send_msg(_("%d Volumes created in pool %s\n"), num, pr.Name); return 1; } /* * Turn auto mount on/off * * automount on * automount off */ int automount_cmd(UAContext *ua, const char *cmd) { char *onoff; if (ua->argc != 2) { if (!get_cmd(ua, _("Turn on or off? "))) { return 1; } onoff = ua->cmd; } else { onoff = ua->argk[1]; } ua->automount = (bstrcasecmp(onoff, NT_("off"))) ? 0 : 1; return 1; } static inline int cancel_storage_daemon_job(UAContext *ua, const char *cmd) { int i; STORERES *store; store = get_storage_resource(ua); if (store) { /* * See what JobId to cancel on the storage daemon. */ i = find_arg_with_value(ua, NT_("jobid")); if (i >= 0) { if (!is_a_number(ua->argv[i])) { ua->warning_msg(_("JobId %s not a number\n"), ua->argv[i]); } cancel_storage_daemon_job(ua, store, ua->argv[i]); } else { ua->warning_msg(_("Missing jobid=JobId specification\n")); } } return 1; } static inline int cancel_jobs(UAContext *ua, const char *cmd) { JCR *jcr; JobId_t *JobId; alist *selection; selection = select_jobs(ua, "cancel"); if (!selection) { return 1; } /* * Loop over the different JobIds selected. */ foreach_alist(JobId, selection) { if (!(jcr = get_jcr_by_id(*JobId))) { continue; } cancel_job(ua, jcr); free_jcr(jcr); } delete selection; return 1; } /* * Cancel a job */ static int cancel_cmd(UAContext *ua, const char *cmd) { int i; /* * See if we need to explicitly cancel a storage daemon Job. */ i = find_arg_with_value(ua, NT_("storage")); if (i >= 0) { return cancel_storage_daemon_job(ua, cmd); } else { return cancel_jobs(ua, cmd); } } /* * This is a common routine to create or update a * Pool DB base record from a Pool Resource. We handle * the setting of MaxVols and NumVols slightly differently * depending on if we are creating the Pool or we are * simply bringing it into agreement with the resource (update). * * Caution : RecyclePoolId isn't setup in this function. * You can use set_pooldbr_recyclepoolid(); */ void set_pooldbr_from_poolres(POOL_DBR *pr, POOLRES *pool, e_pool_op op) { bstrncpy(pr->PoolType, pool->pool_type, sizeof(pr->PoolType)); if (op == POOL_OP_CREATE) { pr->MaxVols = pool->max_volumes; pr->NumVols = 0; } else { /* update pool */ if (pr->MaxVols != pool->max_volumes) { pr->MaxVols = pool->max_volumes; } if (pr->MaxVols != 0 && pr->MaxVols < pr->NumVols) { pr->MaxVols = pr->NumVols; } } pr->LabelType = pool->LabelType; pr->UseOnce = pool->use_volume_once; pr->UseCatalog = pool->use_catalog; pr->Recycle = pool->Recycle; pr->VolRetention = pool->VolRetention; pr->VolUseDuration = pool->VolUseDuration; pr->MaxVolJobs = pool->MaxVolJobs; pr->MaxVolFiles = pool->MaxVolFiles; pr->MaxVolBytes = pool->MaxVolBytes; pr->AutoPrune = pool->AutoPrune; pr->ActionOnPurge = pool->action_on_purge; pr->ActionOnPurge = pool->action_on_purge; pr->MinBlocksize = pool->MinBlocksize; pr->MaxBlocksize = pool->MaxBlocksize; pr->Recycle = pool->Recycle; if (pool->label_format) { bstrncpy(pr->LabelFormat, pool->label_format, sizeof(pr->LabelFormat)); } else { bstrncpy(pr->LabelFormat, "*", sizeof(pr->LabelFormat)); /* none */ } } /* set/update Pool.RecyclePoolId and Pool.ScratchPoolId in Catalog */ int update_pool_references(JCR *jcr, B_DB *db, POOLRES *pool) { POOL_DBR pr; if (!pool->RecyclePool && !pool->ScratchPool) { return 1; } memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool->name(), sizeof(pr.Name)); if (!db_get_pool_record(jcr, db, &pr)) { return -1; /* not exists in database */ } set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); if (!set_pooldbr_references(jcr, db, &pr, pool)) { return -1; /* error */ } if (!db_update_pool_record(jcr, db, &pr)) { return -1; /* error */ } return 1; } /* set POOL_DBR.RecyclePoolId and POOL_DBR.ScratchPoolId from Pool resource * works with set_pooldbr_from_poolres */ bool set_pooldbr_references(JCR *jcr, B_DB *db, POOL_DBR *pr, POOLRES *pool) { POOL_DBR rpool; bool ret = true; if (pool->RecyclePool) { memset(&rpool, 0, sizeof(rpool)); bstrncpy(rpool.Name, pool->RecyclePool->name(), sizeof(rpool.Name)); if (db_get_pool_record(jcr, db, &rpool)) { pr->RecyclePoolId = rpool.PoolId; } else { Jmsg(jcr, M_WARNING, 0, _("Can't set %s RecyclePool to %s, %s is not in database.\n" \ "Try to update it with 'update pool=%s'\n"), pool->name(), rpool.Name, rpool.Name,pool->name()); ret = false; } } else { /* no RecyclePool used, set it to 0 */ pr->RecyclePoolId = 0; } if (pool->ScratchPool) { memset(&rpool, 0, sizeof(rpool)); bstrncpy(rpool.Name, pool->ScratchPool->name(), sizeof(rpool.Name)); if (db_get_pool_record(jcr, db, &rpool)) { pr->ScratchPoolId = rpool.PoolId; } else { Jmsg(jcr, M_WARNING, 0, _("Can't set %s ScratchPool to %s, %s is not in database.\n" \ "Try to update it with 'update pool=%s'\n"), pool->name(), rpool.Name, rpool.Name,pool->name()); ret = false; } } else { /* no ScratchPool used, set it to 0 */ pr->ScratchPoolId = 0; } return ret; } /* * Create a pool record from a given Pool resource * Also called from backup.c * Returns: -1 on error * 0 record already exists * 1 record created */ int create_pool(JCR *jcr, B_DB *db, POOLRES *pool, e_pool_op op) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool->name(), sizeof(pr.Name)); if (db_get_pool_record(jcr, db, &pr)) { /* Pool Exists */ if (op == POOL_OP_UPDATE) { /* update request */ set_pooldbr_from_poolres(&pr, pool, op); set_pooldbr_references(jcr, db, &pr, pool); db_update_pool_record(jcr, db, &pr); } return 0; /* exists */ } set_pooldbr_from_poolres(&pr, pool, op); set_pooldbr_references(jcr, db, &pr, pool); if (!db_create_pool_record(jcr, db, &pr)) { return -1; /* error */ } return 1; } /* * Create a Pool Record in the database. * It is always created from the Resource record. */ static int create_cmd(UAContext *ua, const char *cmd) { POOLRES *pool; if (!open_client_db(ua)) { return 1; } pool = get_pool_resource(ua); if (!pool) { return 1; } switch (create_pool(ua->jcr, ua->db, pool, POOL_OP_CREATE)) { case 0: ua->error_msg(_("Error: Pool %s already exists.\n" "Use update to change it.\n"), pool->name()); break; case -1: ua->error_msg("%s", db_strerror(ua->db)); break; default: break; } ua->send_msg(_("Pool %s created.\n"), pool->name()); return 1; } static inline int setbwlimit_filed(UAContext *ua, CLIENTRES *client, int64_t limit, char *Job) { /* * Connect to File daemon */ ua->jcr->res.client = client; ua->jcr->max_bandwidth = limit; /* * Try to connect for 15 seconds */ ua->send_msg(_("Connecting to Client %s at %s:%d\n"), client->name(), client->address, client->FDport); if (!connect_to_file_daemon(ua->jcr, 1, 15, false, false)) { ua->error_msg(_("Failed to connect to Client.\n")); return 1; } Dmsg0(120, "Connected to file daemon\n"); if (!send_bwlimit_to_fd(ua->jcr, Job)) { ua->error_msg(_("Failed to set bandwidth limit on Client.\n")); } else { ua->info_msg(_("OK Limiting bandwidth to %lldkb/s %s\n"), limit / 1024, Job); } ua->jcr->file_bsock->signal(BNET_TERMINATE); ua->jcr->file_bsock->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; ua->jcr->res.client = NULL; ua->jcr->max_bandwidth = 0; return 1; } static inline int setbwlimit_stored(UAContext *ua, STORERES *store, int64_t limit, char *Job) { /* * Check the storage daemon protocol. */ switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->error_msg(_("Storage selected is NDMP storage which cannot have a bandwidth limit\n")); return 1; default: break; } /* * Connect to Storage daemon */ ua->jcr->res.wstore = store; ua->jcr->max_bandwidth = limit; /* * Try to connect for 15 seconds */ ua->send_msg(_("Connecting to Storage daemon %s at %s:%d\n"), store->name(), store->address, store->SDport); if (!connect_to_storage_daemon(ua->jcr, 1, 15, false)) { ua->error_msg(_("Failed to connect to Storage daemon.\n")); return 1; } Dmsg0(120, "Connected to Storage daemon\n"); if (!send_bwlimit_to_fd(ua->jcr, Job)) { ua->error_msg(_("Failed to set bandwidth limit on Storage daemon.\n")); } else { ua->info_msg(_("OK Limiting bandwidth to %lldkb/s %s\n"), limit / 1024, Job); } ua->jcr->store_bsock->signal(BNET_TERMINATE); ua->jcr->store_bsock->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; ua->jcr->res.wstore = NULL; ua->jcr->max_bandwidth = 0; return 1; } static int setbwlimit_cmd(UAContext *ua, const char *cmd) { int i; int64_t limit = -1; CLIENTRES *client = NULL; STORERES *store = NULL; char Job[MAX_NAME_LENGTH]; const char *lst[] = { "job", "jobid", "ujobid", "all", "state", NULL }; memset(Job, 0, sizeof(Job)); i = find_arg_with_value(ua, NT_("limit")); if (i >= 0) { limit = ((int64_t)atoi(ua->argv[i]) * 1024); } if (limit < 0) { if (!get_pint(ua, _("Enter new bandwidth limit kb/s: "))) { return 1; } limit = ((int64_t)ua->pint32_val * 1024); /* kb/s */ } if (find_arg_keyword(ua, lst) > 0) { JCR *jcr; JobId_t *JobId; alist *selection; selection = select_jobs(ua, "limit"); if (!selection) { return 1; } /* * Loop over the different JobIds selected. */ foreach_alist(JobId, selection) { if (!(jcr = get_jcr_by_id(*JobId))) { continue; } jcr->max_bandwidth = limit; bstrncpy(Job, jcr->Job, sizeof(Job)); switch (jcr->getJobType()) { case JT_COPY: case JT_MIGRATE: store = jcr->res.rstore; break; default: client = jcr->res.client; break; } free_jcr(jcr); } delete selection; } else if (find_arg(ua, NT_("storage")) >= 0) { store = get_storage_resource(ua); } else { client = get_client_resource(ua); } if (client) { return setbwlimit_filed(ua, client, limit, Job); } if (store) { return setbwlimit_stored(ua, store, limit, Job); } return 1; } /* * Set a new address in a Client resource. We do this only * if the Console name is the same as the Client name * and the Console can access the client. */ static int setip_cmd(UAContext *ua, const char *cmd) { CLIENTRES *client; char buf[1024]; if (!ua->cons || !acl_access_ok(ua, Client_ACL, ua->cons->name(), true)) { ua->error_msg(_("Unauthorized command from this console.\n")); return 1; } LockRes(); client = GetClientResWithName(ua->cons->name()); if (!client) { ua->error_msg(_("Client \"%s\" not found.\n"), ua->cons->name()); goto get_out; } if (client->address) { free(client->address); } sockaddr_to_ascii(&(ua->UA_sock->client_addr), buf, sizeof(buf)); client->address = bstrdup(buf); ua->send_msg(_("Client \"%s\" address set to %s\n"), client->name(), client->address); get_out: UnlockRes(); return 1; } static void do_en_disable_cmd(UAContext *ua, bool setting) { SCHEDRES *sched = NULL; CLIENTRES *client = NULL; JOBRES *job = NULL; int i; i = find_arg(ua, NT_("schedule")); if (i >= 0) { i = find_arg_with_value(ua, NT_("schedule")); if (i >= 0) { LockRes(); sched = GetScheduleResWithName(ua->argv[i]); UnlockRes(); } else { sched = select_enable_disable_schedule_resource(ua, setting); if (!sched) { return; } } if (!sched) { ua->error_msg(_("Client \"%s\" not found.\n"), ua->argv[i]); return; } } else { i = find_arg(ua, NT_("client")); if (i >= 0) { i = find_arg_with_value(ua, NT_("client")); if (i >= 0) { LockRes(); client = GetClientResWithName(ua->argv[i]); UnlockRes(); } else { client = select_enable_disable_client_resource(ua, setting); if (!client) { return; } } if (!client) { ua->error_msg(_("Client \"%s\" not found.\n"), ua->argv[i]); return; } } else { i = find_arg_with_value(ua, NT_("job")); if (i >= 0) { LockRes(); job = GetJobResWithName(ua->argv[i]); UnlockRes(); } else { job = select_enable_disable_job_resource(ua, setting); if (!job) { return; } } if (!job) { ua->error_msg(_("Job \"%s\" not found.\n"), ua->argv[i]); return; } } } if (sched) { if (!acl_access_ok(ua, Schedule_ACL, sched->name(), true)) { ua->error_msg(_("Unauthorized command from this console.\n")); return; } sched->enabled = setting; ua->send_msg(_("Schedule \"%s\" %sabled\n"), sched->name(), setting ? "en" : "dis"); } else if (client) { if (!acl_access_ok(ua, Client_ACL, client->name(), true)) { ua->error_msg(_("Unauthorized command from this console.\n")); return; } client->enabled = setting; ua->send_msg(_("Client \"%s\" %sabled\n"), client->name(), setting ? "en" : "dis"); } else if (job) { if (!acl_access_ok(ua, Job_ACL, job->name(), true)) { ua->error_msg(_("Unauthorized command from this console.\n")); return; } job->enabled = setting; ua->send_msg(_("Job \"%s\" %sabled\n"), job->name(), setting ? "en" : "dis"); } } static int enable_cmd(UAContext *ua, const char *cmd) { do_en_disable_cmd(ua, true); return 1; } static int disable_cmd(UAContext *ua, const char *cmd) { do_en_disable_cmd(ua, false); return 1; } static void do_storage_setdebug(UAContext *ua, STORERES *store, int level, int trace_flag, int timestamp_flag) { BSOCK *sd; JCR *jcr = ua->jcr; USTORERES lstore; switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: return; default: break; } lstore.store = store; pm_strcpy(lstore.store_source, _("unknown source")); set_wstorage(jcr, &lstore); /* * Try connecting for up to 15 seconds */ ua->send_msg(_("Connecting to Storage daemon %s at %s:%d\n"), store->name(), store->address, store->SDport); if (!connect_to_storage_daemon(jcr, 1, 15, false)) { ua->error_msg(_("Failed to connect to Storage daemon.\n")); return; } Dmsg0(120, _("Connected to storage daemon\n")); sd = jcr->store_bsock; sd->fsend("setdebug=%d trace=%d timestamp=%d\n", level, trace_flag, timestamp_flag); if (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); } sd->signal(BNET_TERMINATE); sd->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; return; } /* * For the client, we have the following values that can be set : * * level = debug level * trace = send debug output to a file * hangup = how many records to send to SD before hanging up * obviously this is most useful for testing restarting * failed jobs. * timestamp = set debug msg timestamping */ static void do_client_setdebug(UAContext *ua, CLIENTRES *client, int level, int trace_flag, int hangup_flag, int timestamp_flag) { BSOCK *fd; switch (client->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: return; default: break; } /* * Connect to File daemon */ ua->jcr->res.client = client; /* * Try to connect for 15 seconds */ ua->send_msg(_("Connecting to Client %s at %s:%d\n"), client->name(), client->address, client->FDport); if (!connect_to_file_daemon(ua->jcr, 1, 15, false, false)) { ua->error_msg(_("Failed to connect to Client.\n")); return; } Dmsg0(120, "Connected to file daemon\n"); fd = ua->jcr->file_bsock; if (ua->jcr->FDVersion >= FD_VERSION_53) { fd->fsend("setdebug=%d trace=%d hangup=%d timestamp=%d\n", level, trace_flag, hangup_flag); } else { fd->fsend("setdebug=%d trace=%d hangup=%d\n", level, trace_flag, hangup_flag); } if (fd->recv() >= 0) { ua->send_msg("%s", fd->msg); } fd->signal(BNET_TERMINATE); fd->close(); delete ua->jcr->file_bsock; ua->jcr->file_bsock = NULL; return; } static void do_director_setdebug(UAContext *ua, int level, int trace_flag, int timestamp_flag) { POOL_MEM tracefilename(PM_FNAME); debug_level = level; set_trace(trace_flag); set_timestamp(timestamp_flag); Mmsg(tracefilename, "%s/%s.trace", TRACEFILEDIRECTORY, my_name); ua->send_msg("level=%d trace=%d hangup=%d timestamp=%d tracefilename=%s\n", level, get_trace(), get_hangup(), get_timestamp(), tracefilename.c_str()); } static void do_all_setdebug(UAContext *ua, int level, int trace_flag, int hangup_flag, int timestamp_flag) { STORERES *store, **unique_store; CLIENTRES *client, **unique_client; int i, j, found; /* Director */ do_director_setdebug(ua, level, trace_flag, timestamp_flag); /* Count Storage items */ LockRes(); store = NULL; i = 0; foreach_res(store, R_STORAGE) { i++; } unique_store = (STORERES **) malloc(i * sizeof(STORERES)); /* * Find Unique Storage address/port */ store = (STORERES *)GetNextRes(R_STORAGE, NULL); i = 0; unique_store[i++] = store; while ((store = (STORERES *)GetNextRes(R_STORAGE, (RES *)store))) { found = 0; for (j = 0; j < i; j++) { if (bstrcmp(unique_store[j]->address, store->address) && unique_store[j]->SDport == store->SDport) { found = 1; break; } } if (!found) { unique_store[i++] = store; Dmsg2(140, "Stuffing: %s:%d\n", store->address, store->SDport); } } UnlockRes(); /* * Call each unique Storage daemon */ for (j = 0; j < i; j++) { do_storage_setdebug(ua, unique_store[j], level, trace_flag, timestamp_flag); } free(unique_store); /* * Count Client items */ LockRes(); client = NULL; i = 0; foreach_res(client, R_CLIENT) { i++; } unique_client = (CLIENTRES **) malloc(i * sizeof(CLIENTRES)); /* * Find Unique Client address/port */ client = (CLIENTRES *)GetNextRes(R_CLIENT, NULL); i = 0; unique_client[i++] = client; while ((client = (CLIENTRES *)GetNextRes(R_CLIENT, (RES *)client))) { found = 0; for (j = 0; j < i; j++) { if (bstrcmp(unique_client[j]->address, client->address) && unique_client[j]->FDport == client->FDport) { found = 1; break; } } if (!found) { unique_client[i++] = client; Dmsg2(140, "Stuffing: %s:%d\n", client->address, client->FDport); } } UnlockRes(); /* * Call each unique File daemon */ for (j = 0; j < i; j++) { do_client_setdebug(ua, unique_client[j], level, trace_flag, hangup_flag, timestamp_flag); } free(unique_client); } /* * setdebug level=nn all trace=1/0 timestamp=1/0 */ static int setdebug_cmd(UAContext *ua, const char *cmd) { int i; int level; int trace_flag; int hangup_flag; int timestamp_flag; STORERES *store; CLIENTRES *client; Dmsg1(120, "setdebug:%s:\n", cmd); level = -1; i = find_arg_with_value(ua, NT_("level")); if (i >= 0) { level = atoi(ua->argv[i]); } if (level < 0) { if (!get_pint(ua, _("Enter new debug level: "))) { return 1; } level = ua->pint32_val; } /* * Look for trace flag. -1 => not change */ i = find_arg_with_value(ua, NT_("trace")); if (i >= 0) { trace_flag = atoi(ua->argv[i]); if (trace_flag > 0) { trace_flag = 1; } } else { trace_flag = -1; } /* * Look for hangup (debug only) flag. -1 => not change */ i = find_arg_with_value(ua, NT_("hangup")); if (i >= 0) { hangup_flag = atoi(ua->argv[i]); } else { hangup_flag = -1; } /* * Look for timestamp flag. -1 => not change */ i = find_arg_with_value(ua, NT_("timestamp")); if (i >= 0) { timestamp_flag = atoi(ua->argv[i]); if (timestamp_flag > 0) { timestamp_flag = 1; } } else { timestamp_flag = -1; } /* * General debug? */ for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], "all")) { do_all_setdebug(ua, level, trace_flag, hangup_flag, timestamp_flag); return 1; } if (bstrcasecmp(ua->argk[i], "dir") || bstrcasecmp(ua->argk[i], "director")) { do_director_setdebug(ua, level, trace_flag, timestamp_flag); return 1; } if (bstrcasecmp(ua->argk[i], "client") || bstrcasecmp(ua->argk[i], "fd")) { client = NULL; if (ua->argv[i]) { client = GetClientResWithName(ua->argv[i]); if (client) { do_client_setdebug(ua, client, level, trace_flag, hangup_flag, timestamp_flag); return 1; } } client = select_client_resource(ua); if (client) { do_client_setdebug(ua, client, level, trace_flag, hangup_flag, timestamp_flag); return 1; } } if (bstrcasecmp(ua->argk[i], NT_("store")) || bstrcasecmp(ua->argk[i], NT_("storage")) || bstrcasecmp(ua->argk[i], NT_("sd"))) { store = NULL; if (ua->argv[i]) { store = GetStoreResWithName(ua->argv[i]); if (store) { do_storage_setdebug(ua, store, level, trace_flag, timestamp_flag); return 1; } } store = get_storage_resource(ua); if (store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); return 1; default: break; } do_storage_setdebug(ua, store, level, trace_flag, timestamp_flag); return 1; } } } /* * We didn't find an appropriate keyword above, so prompt the user. */ start_prompt(ua, _("Available daemons are: \n")); add_prompt(ua, _("Director")); add_prompt(ua, _("Storage")); add_prompt(ua, _("Client")); add_prompt(ua, _("All")); switch(do_prompt(ua, "", _("Select daemon type to set debug level"), NULL, 0)) { case 0: /* Director */ do_director_setdebug(ua, level, trace_flag, timestamp_flag); break; case 1: store = get_storage_resource(ua); if (store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); return 1; default: break; } do_storage_setdebug(ua, store, level, trace_flag, timestamp_flag); } break; case 2: client = select_client_resource(ua); if (client) { do_client_setdebug(ua, client, level, trace_flag, hangup_flag, timestamp_flag); } break; case 3: do_all_setdebug(ua, level, trace_flag, hangup_flag, timestamp_flag); break; default: break; } return 1; } /* * Resolve a hostname. */ static int resolve_cmd(UAContext *ua, const char *cmd) { STORERES *storage = NULL; CLIENTRES *client = NULL; for (int i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("client")) || bstrcasecmp(ua->argk[i], NT_("fd"))) { if (ua->argv[i]) { client = GetClientResWithName(ua->argv[i]); if (!client) { ua->error_msg(_("Client \"%s\" not found.\n"), ua->argv[i]); return 1; } if (!acl_access_ok(ua, Client_ACL, client->name(), true)) { ua->error_msg(_("No authorization for Client \"%s\"\n"), client->name()); return 1; } *ua->argk[i] = 0; /* zap keyword already visited */ continue; } else { ua->error_msg(_("Client name missing.\n")); return 1; } } else if (bstrcasecmp(ua->argk[i], NT_("storage"))) { if (ua->argv[i]) { storage = GetStoreResWithName(ua->argv[i]); if (!storage) { ua->error_msg(_("Storage \"%s\" not found.\n"), ua->argv[i]); return 1; } if (!acl_access_ok(ua, Storage_ACL, storage->name(), true)) { ua->error_msg(_("No authorization for Storage \"%s\"\n"), storage->name()); return 1; } *ua->argk[i] = 0; /* zap keyword already visited */ continue; } else { ua->error_msg(_("Storage name missing.\n")); return 1; } } } if (client) { do_client_resolve(ua, client); } if (storage) { do_storage_resolve(ua, storage); } if (!client && !storage) { dlist *addr_list; const char *errstr; char addresses[2048]; for (int i = 1; i < ua->argc; i++) { if (!*ua->argk[i]) { continue; } if ((addr_list = bnet_host2ipaddrs(ua->argk[i], 0, &errstr)) == NULL) { ua->error_msg(_("%s Failed to resolve %s\n"), my_name, ua->argk[i]); return 0; } ua->send_msg(_("%s resolves %s to %s\n"), my_name, ua->argk[i], build_addresses_str(addr_list, addresses, sizeof(addresses), false)); free_addresses(addr_list); } } return 1; } /* * Turn debug tracing to file on/off */ static int trace_cmd(UAContext *ua, const char *cmd) { char *onoff; if (ua->argc != 2) { if (!get_cmd(ua, _("Turn on or off? "))) { return 1; } onoff = ua->cmd; } else { onoff = ua->argk[1]; } set_trace((bstrcasecmp(onoff, NT_("off"))) ? false : true); return 1; } static int var_cmd(UAContext *ua, const char *cmd) { POOLMEM *val = get_pool_memory(PM_FNAME); char *var; if (!open_client_db(ua)) { return 1; } for (var=ua->cmd; *var != ' '; ) { /* skip command */ var++; } while (*var == ' ') { /* skip spaces */ var++; } Dmsg1(100, "Var=%s:\n", var); variable_expansion(ua->jcr, var, &val); ua->send_msg("%s\n", val); free_pool_memory(val); return 1; } static int estimate_cmd(UAContext *ua, const char *cmd) { JOBRES *job = NULL; CLIENTRES *client = NULL; FILESETRES *fileset = NULL; int listing = 0; JCR *jcr = ua->jcr; int accurate=-1; jcr->setJobLevel(L_FULL); for (int i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("client")) || bstrcasecmp(ua->argk[i], NT_("fd"))) { if (ua->argv[i]) { client = GetClientResWithName(ua->argv[i]); if (!client) { ua->error_msg(_("Client \"%s\" not found.\n"), ua->argv[i]); return 1; } if (!acl_access_ok(ua, Client_ACL, client->name(), true)) { ua->error_msg(_("No authorization for Client \"%s\"\n"), client->name()); return 1; } continue; } else { ua->error_msg(_("Client name missing.\n")); return 1; } } if (bstrcasecmp(ua->argk[i], NT_("job"))) { if (ua->argv[i]) { job = GetJobResWithName(ua->argv[i]); if (!job) { ua->error_msg(_("Job \"%s\" not found.\n"), ua->argv[i]); return 1; } if (!acl_access_ok(ua, Job_ACL, job->name(), true)) { ua->error_msg(_("No authorization for Job \"%s\"\n"), job->name()); return 1; } continue; } else { ua->error_msg(_("Job name missing.\n")); return 1; } } if (bstrcasecmp(ua->argk[i], NT_("fileset"))) { if (ua->argv[i]) { fileset = GetFileSetResWithName(ua->argv[i]); if (!fileset) { ua->error_msg(_("Fileset \"%s\" not found.\n"), ua->argv[i]); return 1; } if (!acl_access_ok(ua, FileSet_ACL, fileset->name(), true)) { ua->error_msg(_("No authorization for FileSet \"%s\"\n"), fileset->name()); return 1; } continue; } else { ua->error_msg(_("Fileset name missing.\n")); return 1; } } if (bstrcasecmp(ua->argk[i], NT_("listing"))) { listing = 1; continue; } if (bstrcasecmp(ua->argk[i], NT_("level"))) { if (ua->argv[i]) { if (!get_level_from_name(jcr, ua->argv[i])) { ua->error_msg(_("Level \"%s\" not valid.\n"), ua->argv[i]); } continue; } else { ua->error_msg(_("Level value missing.\n")); return 1; } } if (bstrcasecmp(ua->argk[i], NT_("accurate"))) { if (ua->argv[i]) { if (!is_yesno(ua->argv[i], &accurate)) { ua->error_msg(_("Invalid value for accurate. " "It must be yes or no.\n")); } continue; } else { ua->error_msg(_("Accurate value missing.\n")); return 1; } } } if (!job && !(client && fileset)) { if (!(job = select_job_resource(ua))) { return 1; } } if (!job) { job = GetJobResWithName(ua->argk[1]); if (!job) { ua->error_msg(_("No job specified.\n")); return 1; } if (!acl_access_ok(ua, Job_ACL, job->name(), true)) { ua->error_msg(_("No authorization for Job \"%s\"\n"), job->name()); return 1; } } switch (job->JobType) { case JT_BACKUP: break; default: ua->error_msg(_("Wrong job specified of type %s.\n"), job_type_to_str(job->JobType)); return 1; } if (!client) { client = job->client; } if (!fileset) { fileset = job->fileset; } if (!client) { ua->error_msg(_("No client specified or selected.\n")); return 1; } if (!fileset) { ua->error_msg(_("No fileset specified or selected.\n")); return 1; } jcr->res.client = client; jcr->res.fileset = fileset; close_db(ua); if (job->pool->catalog) { ua->catalog = job->pool->catalog; } else { ua->catalog = client->catalog; } if (!open_db(ua)) { return 1; } jcr->res.job = job; jcr->setJobType(JT_BACKUP); jcr->start_time = time(NULL); init_jcr_job_record(jcr); if (!get_or_create_client_record(jcr)) { return 1; } if (!get_or_create_fileset_record(jcr)) { return 1; } get_level_since_time(jcr); ua->send_msg(_("Connecting to Client %s at %s:%d\n"), jcr->res.client->name(), jcr->res.client->address, jcr->res.client->FDport); if (!connect_to_file_daemon(jcr, 1, 15, false, true)) { ua->error_msg(_("Failed to connect to Client.\n")); return 1; } /* * The level string change if accurate mode is enabled */ if (accurate >= 0) { jcr->accurate = accurate; } else { jcr->accurate = job->accurate; } if (!send_level_command(jcr)) { goto bail_out; } if (!send_include_list(jcr)) { ua->error_msg(_("Error sending include list.\n")); goto bail_out; } if (!send_exclude_list(jcr)) { ua->error_msg(_("Error sending exclude list.\n")); goto bail_out; } /* * If the job is in accurate mode, we send the list of all files to FD. */ Dmsg1(40, "estimate accurate=%d\n", jcr->accurate); if (!send_accurate_current_files(jcr)) { goto bail_out; } jcr->file_bsock->fsend("estimate listing=%d\n", listing); while (jcr->file_bsock->recv() >= 0) { ua->send_msg("%s", jcr->file_bsock->msg); } bail_out: if (jcr->file_bsock) { jcr->file_bsock->signal(BNET_TERMINATE); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } return 1; } /* * print time */ static int time_cmd(UAContext *ua, const char *cmd) { char sdt[50]; time_t ttime = time(NULL); bstrftime(sdt, sizeof(sdt), ttime, "%a %d-%b-%Y %H:%M:%S"); ua->send_msg("%s\n", sdt); return 1; } /* * reload the conf file */ extern "C" void reload_config(int sig); static int reload_cmd(UAContext *ua, const char *cmd) { reload_config(1); return 1; } /* * Delete Pool records (should purge Media with it). * * delete pool= * delete volume pool= volume= * delete jobid= */ static int delete_cmd(UAContext *ua, const char *cmd) { static const char *keywords[] = { NT_("volume"), NT_("pool"), NT_("jobid"), NULL }; if (!open_client_db(ua, true)) { return 1; } switch (find_arg_keyword(ua, keywords)) { case 0: delete_volume(ua); return 1; case 1: delete_pool(ua); return 1; case 2: int i; while ((i = find_arg(ua, "jobid")) > 0) { delete_job(ua); *ua->argk[i] = 0; /* zap keyword already visited */ } return 1; default: break; } ua->warning_msg(_("In general it is not a good idea to delete either a\n" "Pool or a Volume since they may contain data.\n\n")); switch (do_keyword_prompt(ua, _("Choose catalog item to delete"), keywords)) { case 0: delete_volume(ua); break; case 1: delete_pool(ua); break; case 2: delete_job(ua); return 1; default: ua->warning_msg(_("Nothing done.\n")); break; } return 1; } /* * delete_job has been modified to parse JobID lists like the following: * delete JobID=3,4,6,7-11,14 * * Thanks to Phil Stracchino for the above addition. */ static void delete_job(UAContext *ua) { int i; JobId_t JobId; char *s, *sep, *tok; i = find_arg_with_value(ua, NT_("jobid")); if (i >= 0) { if (strchr(ua->argv[i], ',') || strchr(ua->argv[i], '-')) { s = bstrdup(ua->argv[i]); tok = s; /* * We could use strtok() here. But we're not going to, because: * (a) strtok() is deprecated, having been replaced by strsep(); * (b) strtok() is broken in significant ways. * we could use strsep() instead, but it's not universally available. * so we grow our own using strchr(). */ sep = strchr(tok, ','); while (sep != NULL) { *sep = '\0'; if (!delete_job_id_range(ua, tok)) { if (is_a_number(tok)) { JobId = (JobId_t)str_to_uint64(tok); do_job_delete(ua, JobId); } else { ua->warning_msg(_("Illegal JobId %s ignored\n"), tok); } } tok = ++sep; sep = strchr(tok, ','); } /* * Pick up the last token */ if (!delete_job_id_range(ua, tok)) { if (is_a_number(tok)) { JobId = (JobId_t)str_to_uint64(tok); do_job_delete(ua, JobId); } else { ua->warning_msg(_("Illegal JobId %s ignored\n"), tok); } } free(s); } else { if (is_a_number(ua->argv[i])) { JobId = (JobId_t)str_to_uint64(ua->argv[i]); do_job_delete(ua, JobId); } else { ua->warning_msg(_("Illegal JobId %s ignored\n"), ua->argv[i]); } } } else if (!get_pint(ua, _("Enter JobId to delete: "))) { return; } else { JobId = ua->int64_val; do_job_delete(ua, JobId); } } /* * We call delete_job_id_range to parse range tokens and iterate over ranges */ static bool delete_job_id_range(UAContext *ua, char *tok) { char buf[64]; char *tok2; JobId_t j, j1, j2; tok2 = strchr(tok, '-'); if (!tok2) { return false; } *tok2 = '\0'; tok2++; if (is_a_number(tok) && is_a_number(tok2)) { j1 = (JobId_t)str_to_uint64(tok); j2 = (JobId_t)str_to_uint64(tok2); if (j2 > j1) { /* * See if the range is big if more then 25 Jobs are deleted * ask the user for confirmation. */ if ((j2 - j1) > 25) { bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete %d JobIds ? (yes/no): "), j2 - j1); if (!get_yesno(ua, buf)) { return true; } } for (j = j1; j <= j2; j++) { do_job_delete(ua, j); } } else { ua->warning_msg(_("Illegal JobId range %s - %s should define increasing JobIds, ignored\n"), tok, tok2); } } else { ua->warning_msg(_("Illegal JobId range %s - %s, ignored\n"), tok, tok2); } return true; } /* * do_job_delete now performs the actual delete operation atomically */ static void do_job_delete(UAContext *ua, JobId_t JobId) { char ed1[50]; edit_int64(JobId, ed1); purge_jobs_from_catalog(ua, ed1); ua->send_msg(_("Jobid %s and associated records deleted from the catalog.\n"), ed1); } /* * Delete media records from database -- dangerous */ static int delete_volume(UAContext *ua) { MEDIA_DBR mr; char buf[1000]; db_list_ctx lst; memset(&mr, 0, sizeof(mr)); if (!select_media_dbr(ua, &mr)) { return 1; } ua->warning_msg(_("\nThis command will delete volume %s\n" "and all Jobs saved on that volume from the Catalog\n"), mr.VolumeName); if (find_arg(ua, "yes") >= 0) { ua->pint32_val = 1; /* Have "yes" on command line already" */ } else { bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete Volume \"%s\"? (yes/no): "), mr.VolumeName); if (!get_yesno(ua, buf)) { return 1; } } if (!ua->pint32_val) { return 1; } /* If not purged, do it */ if (!bstrcmp(mr.VolStatus, "Purged")) { if (!db_get_volume_jobids(ua->jcr, ua->db, &mr, &lst)) { ua->error_msg(_("Can't list jobs on this volume\n")); return 1; } if (lst.count) { purge_jobs_from_catalog(ua, lst.list); } } db_delete_media_record(ua->jcr, ua->db, &mr); return 1; } /* * Delete a pool record from the database -- dangerous */ static int delete_pool(UAContext *ua) { POOL_DBR pr; char buf[200]; memset(&pr, 0, sizeof(pr)); if (!get_pool_dbr(ua, &pr)) { return 1; } bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete Pool \"%s\"? (yes/no): "), pr.Name); if (!get_yesno(ua, buf)) { return 1; } if (ua->pint32_val) { db_delete_pool_record(ua->jcr, ua->db, &pr); } return 1; } int memory_cmd(UAContext *ua, const char *cmd) { garbage_collect_memory(); list_dir_status_header(ua); sm_dump(false, true); return 1; } static void do_mount_cmd(UAContext *ua, const char *cmd) { USTORERES store; int nr_drives, i; int drive = -1; int slot = -1; bool do_alldrives = false; if ((bstrcmp(cmd, "release") || bstrcmp(cmd, "unmount")) && find_arg(ua, "alldrives") >= 0) { do_alldrives = true; } if (!open_client_db(ua)) { return; } Dmsg2(120, "%s: %s\n", cmd, ua->UA_sock->msg); store.store = get_storage_resource(ua, true, false); if (!store.store) { return; } switch (store.store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); return; default: break; } pm_strcpy(store.store_source, _("unknown source")); set_wstorage(ua->jcr, &store); if (!do_alldrives) { drive = get_storage_drive(ua, store.store); if (drive == -1) { return; } } if (bstrcmp(cmd, "mount")) { slot = get_storage_slot(ua, store.store); } Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n", store.store->media_type, store.store->dev_name(), drive); if (!do_alldrives) { do_autochanger_volume_operation(ua, store.store, cmd, drive, slot); } else { nr_drives = get_num_drives_from_SD(ua); for (i = 0; i < nr_drives; i++) { do_autochanger_volume_operation(ua, store.store, cmd, i, slot); } } } /* * mount [storage=] [drive=nn] [slot=mm] */ static int mount_cmd(UAContext *ua, const char *cmd) { do_mount_cmd(ua, "mount"); /* mount */ return 1; } /* * unmount [storage=] [drive=nn] */ static int unmount_cmd(UAContext *ua, const char *cmd) { do_mount_cmd(ua, "unmount"); /* unmount */ return 1; } /* * release [storage=] [drive=nn] */ static int release_cmd(UAContext *ua, const char *cmd) { do_mount_cmd(ua, "release"); /* release */ return 1; } /* * Switch databases * use catalog= */ static int use_cmd(UAContext *ua, const char *cmd) { CATRES *oldcatalog, *catalog; close_db(ua); /* close any previously open db */ oldcatalog = ua->catalog; if (!(catalog = get_catalog_resource(ua))) { ua->catalog = oldcatalog; } else { ua->catalog = catalog; } if (open_db(ua)) { ua->send_msg(_("Using Catalog name=%s DB=%s\n"), ua->catalog->name(), ua->catalog->db_name); } return 1; } int quit_cmd(UAContext *ua, const char *cmd) { ua->quit = true; return 1; } /* Handler to get job status */ static int status_handler(void *ctx, int num_fields, char **row) { char *val = (char *)ctx; if (row[0]) { *val = row[0][0]; } else { *val = '?'; /* Unknown by default */ } return 0; } /* * Wait until no job is running */ int wait_cmd(UAContext *ua, const char *cmd) { JCR *jcr; int i; time_t stop_time = 0; /* * no args * Wait until no job is running */ if (ua->argc == 1) { bmicrosleep(0, 200000); /* let job actually start */ for (bool running=true; running; ) { running = false; foreach_jcr(jcr) { if (jcr->JobId != 0) { running = true; break; } } endeach_jcr(jcr); if (running) { bmicrosleep(1, 0); } } return 1; } i = find_arg_with_value(ua, NT_("timeout")); if (i > 0 && ua->argv[i]) { stop_time = time(NULL) + str_to_int64(ua->argv[i]); } /* we have jobid, jobname or ujobid argument */ uint32_t jobid = 0 ; if (!open_client_db(ua)) { ua->error_msg(_("ERR: Can't open db\n")) ; return 1; } for (int i=1; iargc; i++) { if (bstrcasecmp(ua->argk[i], "jobid")) { if (!ua->argv[i]) { break; } jobid = str_to_int64(ua->argv[i]); break; } else if (bstrcasecmp(ua->argk[i], "jobname") || bstrcasecmp(ua->argk[i], "job")) { if (!ua->argv[i]) { break; } jcr=get_jcr_by_partial_name(ua->argv[i]) ; if (jcr) { jobid = jcr->JobId ; free_jcr(jcr); } break; } else if (bstrcasecmp(ua->argk[i], "ujobid")) { if (!ua->argv[i]) { break; } jcr=get_jcr_by_full_name(ua->argv[i]) ; if (jcr) { jobid = jcr->JobId ; free_jcr(jcr); } break; /* Wait for a mount request */ } else if (bstrcasecmp(ua->argk[i], "mount")) { for (bool waiting=false; !waiting; ) { foreach_jcr(jcr) { if (jcr->JobId != 0 && (jcr->JobStatus == JS_WaitMedia || jcr->JobStatus == JS_WaitMount)) { waiting = true; break; } } endeach_jcr(jcr); if (waiting) { break; } if (stop_time && (time(NULL) >= stop_time)) { ua->warning_msg(_("Wait on mount timed out\n")); return 1; } bmicrosleep(1, 0); } return 1; } } if (jobid == 0) { ua->error_msg(_("ERR: Job was not found\n")); return 1 ; } /* * We wait the end of a specific job */ bmicrosleep(0, 200000); /* let job actually start */ for (bool running=true; running; ) { running = false; jcr=get_jcr_by_id(jobid) ; if (jcr) { running = true ; free_jcr(jcr); } if (running) { bmicrosleep(1, 0); } } /* * We have to get JobStatus */ int status ; char jobstatus = '?'; /* Unknown by default */ char buf[256] ; bsnprintf(buf, sizeof(buf), "SELECT JobStatus FROM Job WHERE JobId='%i'", jobid); db_sql_query(ua->db, buf, status_handler, (void *)&jobstatus); switch (jobstatus) { case JS_Error: status = 1 ; /* Warning */ break; case JS_FatalError: case JS_ErrorTerminated: case JS_Canceled: status = 2 ; /* Critical */ break; case JS_Warnings: case JS_Terminated: status = 0 ; /* Ok */ break; default: status = 3 ; /* Unknown */ break; } ua->send_msg("JobId=%i\n", jobid) ; ua->send_msg("JobStatus=%s (%c)\n", job_status_to_str(jobstatus), jobstatus) ; if (ua->gui || ua->api) { ua->send_msg("ExitStatus=%i\n", status) ; } return 1; } static int help_cmd(UAContext *ua, const char *cmd) { int i; ua->send_msg(_(" Command Description\n ======= ===========\n")); for (i = 0; i < comsize; i++) { if (ua->argc == 2) { if (bstrcasecmp(ua->argk[1], commands[i].key)) { ua->send_msg(_(" %-13s %s\n\nArguments:\n\t%s\n"), commands[i].key, commands[i].help, commands[i].usage); break; } } else { ua->send_msg(_(" %-13s %s\n"), commands[i].key, commands[i].help); } } if (i == comsize && ua->argc == 2) { ua->send_msg(_("\nCan't find %s command.\n\n"), ua->argk[1]); } ua->send_msg(_("\nWhen at a prompt, entering a period cancels the command.\n\n")); return 1; } /* * Output the usage string as a machine parseable string. * e.g. remove newlines and replace tabs with a single space. */ static inline void usage_to_machine(UAContext *ua, struct cmdstruct *cmd) { char *p; POOL_MEM usage(PM_MESSAGE); pm_strcpy(usage, cmd->usage); p = usage.c_str(); while (*p) { switch (*p) { case '\n': /* * Copy the rest of the string over the unwanted character. * Use bstrinlinecpy as we are doing an inline copy which * isn't officially supported by (b)strcpy. */ bstrinlinecpy(p, p + 1); continue; case '\t': *p = ' '; break; default: break; } p++; } ua->send_msg("%s\n", usage.c_str()); } int qhelp_cmd(UAContext *ua, const char *cmd) { int i, j; /* * Want to display only commands */ j = find_arg(ua, NT_("all")); if (j >= 0) { for (i = 0; i < comsize; i++) { ua->send_msg("%s\n", commands[i].key); } return 1; } /* * Want to display a specific help section */ j = find_arg_with_value(ua, NT_("item")); if (j >= 0 && ua->argk[j]) { for (i = 0; i < comsize; i++) { if (bstrcmp(commands[i].key, ua->argv[j])) { usage_to_machine(ua, &commands[i]); break; } } return 1; } /* * Want to display everything */ for (i = 0; i < comsize; i++) { ua->send_msg("%s %s -- ", commands[i].key, commands[i].help); usage_to_machine(ua, &commands[i]); } return 1; } #if 1 static int version_cmd(UAContext *ua, const char *cmd) { ua->send_msg(_("%s Version: %s (%s) %s %s %s %s\n"), my_name, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER, NPRTB(me->verid)); return 1; } #else /* * Test code -- turned on only for debug testing */ static int version_cmd(UAContext *ua, const char *cmd) { dbid_list ids; POOL_MEM query(PM_MESSAGE); open_db(ua); Mmsg(query, "select MediaId from Media,Pool where Pool.PoolId=Media.PoolId and Pool.Name='Full'"); db_get_query_dbids(ua->jcr, ua->db, query, ids); ua->send_msg("num_ids=%d max_ids=%d tot_ids=%d\n", ids.num_ids, ids.max_ids, ids.tot_ids); for (int i=0; i < ids.num_ids; i++) { ua->send_msg("id=%d\n", ids.DBId[i]); } close_db(ua); return 1; } #endif /* * This call explicitly checks for a catalog=catalog-name and * if given, opens that catalog. It also checks for * client=client-name and if found, opens the catalog * corresponding to that client. If we still don't * have a catalog, look for a Job keyword and get the * catalog from its client record. */ bool open_client_db(UAContext *ua, bool use_private) { int i; CATRES *catalog; CLIENTRES *client; JOBRES *job; /* Try for catalog keyword */ i = find_arg_with_value(ua, NT_("catalog")); if (i >= 0) { if (!acl_access_ok(ua, Catalog_ACL, ua->argv[i], true)) { ua->error_msg(_("No authorization for Catalog \"%s\"\n"), ua->argv[i]); return false; } catalog = GetCatalogResWithName(ua->argv[i]); if (catalog) { if (ua->catalog && ua->catalog != catalog) { close_db(ua); } ua->catalog = catalog; return open_db(ua, use_private); } } /* Try for client keyword */ i = find_arg_with_value(ua, NT_("client")); if (i >= 0) { if (!acl_access_ok(ua, Client_ACL, ua->argv[i], true)) { ua->error_msg(_("No authorization for Client \"%s\"\n"), ua->argv[i]); return false; } client = GetClientResWithName(ua->argv[i]); if (client) { catalog = client->catalog; if (ua->catalog && ua->catalog != catalog) { close_db(ua); } if (!acl_access_ok(ua, Catalog_ACL, catalog->name(), true)) { ua->error_msg(_("No authorization for Catalog \"%s\"\n"), catalog->name()); return false; } ua->catalog = catalog; return open_db(ua, use_private); } } /* Try for Job keyword */ i = find_arg_with_value(ua, NT_("job")); if (i >= 0) { if (!acl_access_ok(ua, Job_ACL, ua->argv[i], true)) { ua->error_msg(_("No authorization for Job \"%s\"\n"), ua->argv[i]); return false; } job = GetJobResWithName(ua->argv[i]); if (job && job->client) { catalog = job->client->catalog; if (ua->catalog && ua->catalog != catalog) { close_db(ua); } if (!acl_access_ok(ua, Catalog_ACL, catalog->name(), true)) { ua->error_msg(_("No authorization for Catalog \"%s\"\n"), catalog->name()); return false; } ua->catalog = catalog; return open_db(ua, use_private); } } return open_db(ua, use_private); } /* * Open the catalog database. */ bool open_db(UAContext *ua, bool use_private) { bool mult_db_conn; /* * See if we need to do any work at all. * Point the current used db e.g. ua->db to the correct database connection. */ if (use_private) { if (ua->private_db) { ua->db = ua->private_db; return true; } } else if (ua->shared_db) { ua->db = ua->shared_db; return true; } /* * Select the right catalog to use. */ if (!ua->catalog) { ua->catalog = get_catalog_resource(ua); if (!ua->catalog) { ua->error_msg( _("Could not find a Catalog resource\n")); return false; } } /* * Some modules like bvfs need their own private catalog connection */ mult_db_conn = ua->catalog->mult_db_connections; if (use_private) { mult_db_conn = true; } ua->jcr->res.catalog = ua->catalog; Dmsg0(100, "UA Open database\n"); ua->db = db_sql_get_pooled_connection(ua->jcr, ua->catalog->db_driver, ua->catalog->db_name, ua->catalog->db_user, ua->catalog->db_password.value, ua->catalog->db_address, ua->catalog->db_port, ua->catalog->db_socket, mult_db_conn, ua->catalog->disable_batch_insert, use_private); if (ua->db == NULL) { ua->error_msg(_("Could not open catalog database \"%s\".\n"), ua->catalog->db_name); return false; } ua->jcr->db = ua->db; /* * Save the new database connection under the right label e.g. shared or private. */ if (use_private) { ua->private_db = ua->db; } else { ua->shared_db = ua->db; } if (!ua->api) { ua->send_msg(_("Using Catalog \"%s\"\n"), ua->catalog->name()); } Dmsg1(150, "DB %s opened\n", ua->catalog->db_name); return true; } void close_db(UAContext *ua) { if (ua->jcr) { ua->jcr->db = NULL; } if (ua->shared_db) { db_sql_close_pooled_connection(ua->jcr, ua->shared_db); ua->shared_db = NULL; } if (ua->private_db) { db_sql_close_pooled_connection(ua->jcr, ua->private_db); ua->private_db = NULL; } } bareos-Release-14.2.6/src/dird/ua_configure.c000066400000000000000000000022061263011562700207630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Interactive configuration engine for director. * * Written by Marco van Wieringen, January 2015 */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ int configure_cmd(UAContext *ua, const char *cmd) { ua->send_msg("Interactive configuration not implemented\n"); return 1; } bareos-Release-14.2.6/src/dird/ua_dotcmds.c000066400000000000000000001073571263011562700204540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Commands * * These are "dot" commands, i.e. commands preceded * by a period. These commands are meant to be used * by a program, so there is no prompting, and the * returned results are (supposed to be) predictable. * * Kern Sibbald, April MMII */ #include "bareos.h" #include "dird.h" #include "cats/bvfs.h" #include "findlib/find.h" /* Imported variables */ extern struct s_jl joblevels[]; extern struct s_jt jobtypes[]; extern struct s_kw ActionOnPurgeOptions[]; extern struct s_kw VolumeStatus[]; /* Imported functions */ extern void do_messages(UAContext *ua, const char *cmd); extern int quit_cmd(UAContext *ua, const char *cmd); extern int qhelp_cmd(UAContext *ua, const char *cmd); extern bool dot_status_cmd(UAContext *ua, const char *cmd); /* Forward referenced functions */ static bool catalogscmd(UAContext *ua, const char *cmd); static bool admin_cmds(UAContext *ua, const char *cmd); static bool jobdefscmd(UAContext *ua, const char *cmd); static bool jobscmd(UAContext *ua, const char *cmd); static bool filesetscmd(UAContext *ua, const char *cmd); static bool clientscmd(UAContext *ua, const char *cmd); static bool msgscmd(UAContext *ua, const char *cmd); static bool poolscmd(UAContext *ua, const char *cmd); static bool schedulecmd(UAContext *ua, const char *cmd); static bool storagecmd(UAContext *ua, const char *cmd); static bool defaultscmd(UAContext *ua, const char *cmd); static bool typescmd(UAContext *ua, const char *cmd); static bool backupscmd(UAContext *ua, const char *cmd); static bool levelscmd(UAContext *ua, const char *cmd); static bool getmsgscmd(UAContext *ua, const char *cmd); static bool volstatuscmd(UAContext *ua, const char *cmd); static bool mediatypescmd(UAContext *ua, const char *cmd); static bool locationscmd(UAContext *ua, const char *cmd); static bool mediacmd(UAContext *ua, const char *cmd); static bool profilescmd(UAContext *ua, const char *cmd); static bool aopcmd(UAContext *ua, const char *cmd); static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd); static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd); static bool dot_bvfs_update(UAContext *ua, const char *cmd); static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd); static bool dot_bvfs_versions(UAContext *ua, const char *cmd); static bool dot_bvfs_restore(UAContext *ua, const char *cmd); static bool dot_bvfs_cleanup(UAContext *ua, const char *cmd); static bool dot_bvfs_clear_cache(UAContext *ua, const char *cmd); static bool api_cmd(UAContext *ua, const char *cmd); static bool sql_cmd(UAContext *ua, const char *cmd); static bool dot_quit_cmd(UAContext *ua, const char *cmd); static bool dot_help_cmd(UAContext *ua, const char *cmd); static int one_handler(void *ctx, int num_field, char **row); struct cmdstruct { const char *key; bool (*func)(UAContext *ua, const char *cmd); const char *help; /* Help */ const bool use_in_rs; /* Can be used in runscript */ const bool audit_event; /* Log an audit event when this Command is executed */ }; static struct cmdstruct commands[] = { { NT_(".api"), api_cmd, NULL, false, false }, { NT_(".backups"), backupscmd, NULL, false, false }, { NT_(".clients"), clientscmd, NULL, true, false }, { NT_(".catalogs"), catalogscmd, NULL, false, false }, { NT_(".defaults"), defaultscmd, NULL, false, false }, { NT_(".die"), admin_cmds, NULL, false, true }, { NT_(".dump"), admin_cmds, NULL, false, true }, { NT_(".exit"), admin_cmds, NULL, false, false }, { NT_(".filesets"), filesetscmd, NULL, false, false }, { NT_(".help"), dot_help_cmd, NULL, false, false }, { NT_(".jobdefs"), jobdefscmd, NULL, true, false }, { NT_(".jobs"), jobscmd, NULL, true, false }, { NT_(".levels"), levelscmd, NULL, false, false }, { NT_(".messages"), getmsgscmd, NULL, false, false }, { NT_(".msgs"), msgscmd, NULL, false, false }, { NT_(".pools"), poolscmd, NULL, true, false }, { NT_(".quit"), dot_quit_cmd, NULL, false, false }, { NT_(".sql"), sql_cmd, NULL, false, true }, { NT_(".schedule"), schedulecmd, NULL, false, false }, { NT_(".status"), dot_status_cmd, NULL, false, true }, { NT_(".storage"), storagecmd, NULL, true, false }, { NT_(".volstatus"), volstatuscmd, NULL, true, false }, { NT_(".media"), mediacmd, NULL, true, false }, { NT_(".mediatypes"), mediatypescmd, NULL, true, false }, { NT_(".locations"), locationscmd, NULL, true, false }, { NT_(".profiles"), profilescmd, NULL, true, false }, { NT_(".actiononpurge"), aopcmd, NULL, true, false }, { NT_(".bvfs_lsdirs"), dot_bvfs_lsdirs, NULL, true, true }, { NT_(".bvfs_lsfiles"),dot_bvfs_lsfiles, NULL, true, true }, { NT_(".bvfs_update"), dot_bvfs_update, NULL, true, true }, { NT_(".bvfs_get_jobids"), dot_bvfs_get_jobids, NULL, true, true }, { NT_(".bvfs_versions"), dot_bvfs_versions, NULL, true, true }, { NT_(".bvfs_restore"), dot_bvfs_restore, NULL, true, true }, { NT_(".bvfs_cleanup"), dot_bvfs_cleanup, NULL, true, true }, { NT_(".bvfs_clear_cache"), dot_bvfs_clear_cache, NULL, false, true }, { NT_(".types"), typescmd, NULL, false, false } }; #define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct))) /* * Execute a command from the UA */ bool do_a_dot_command(UAContext *ua) { int i; int len; bool ok = false; bool found = false; BSOCK *user = ua->UA_sock; Dmsg1(1400, "Dot command: %s\n", user->msg); if (ua->argc == 0) { return false; } len = strlen(ua->argk[0]); if (len == 1) { if (ua->api) { user->signal(BNET_CMD_BEGIN); } if (ua->api) { user->signal(BNET_CMD_OK); } return true; /* no op */ } for (i = 0; i < comsize; i++) { /* search for command */ if (bstrncasecmp(ua->argk[0], _(commands[i].key), len)) { bool gui = ua->gui; /* * Check if this command is authorized in RunScript */ if (ua->runscript && !commands[i].use_in_rs) { ua->error_msg(_("Can't use %s command in a runscript"), ua->argk[0]); break; } /* * If we need to audit this event do it now. */ if (audit_event_wanted(ua, commands[i].audit_event)) { log_audit_event_cmdline(ua); } /* * Check if command permitted, but "quit" is always OK */ if (!bstrcmp(ua->argk[0], NT_(".quit")) && !acl_access_ok(ua, Command_ACL, ua->argk[0], len, true)) { break; } Dmsg1(100, "Cmd: %s\n", ua->cmd); ua->gui = true; if (ua->api) { user->signal(BNET_CMD_BEGIN); } ok = (*commands[i].func)(ua, ua->cmd); /* go execute command */ if (ua->api) { user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED); } ua->gui = gui; found = true; break; } } if (!found) { ua->error_msg("%s%s", ua->argk[0], _(": is an invalid command.\n")); ok = false; } return ok; } static bool dot_bvfs_update(UAContext *ua, const char *cmd) { int pos; if (!open_client_db(ua, true)) { return 1; } pos = find_arg_with_value(ua, "jobid"); if (pos != -1 && is_a_number_list(ua->argv[pos])) { if (!bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, ua->argv[pos])) { ua->error_msg("ERROR: BVFS reported a problem for %s\n", ua->argv[pos]); } } else { /* update cache for all jobids */ bvfs_update_cache(ua->jcr, ua->db); } return true; } static bool dot_bvfs_clear_cache(UAContext *ua, const char *cmd) { if (!open_client_db(ua, true)) { return 1; } int pos = find_arg(ua, "yes"); if (pos != -1) { Bvfs fs(ua->jcr, ua->db); fs.clear_cache(); ua->info_msg("OK\n"); } else { ua->error_msg("Can't find 'yes' argument\n"); } return true; } static int bvfs_result_handler(void *ctx, int fields, char **row) { UAContext *ua = (UAContext *)ctx; struct stat statp; int32_t LinkFI; char *fileid=row[BVFS_FileId]; char *lstat=row[BVFS_LStat]; char *jobid=row[BVFS_JobId]; char empty[] = "A A A A A A A A A A A A A A"; char zero[] = "0"; /* We need to deal with non existant path */ if (!fileid || !is_a_number(fileid)) { lstat = empty; jobid = zero; fileid = zero; } memset(&statp, 0, sizeof(struct stat)); decode_stat(lstat, &statp, sizeof(statp), &LinkFI); Dmsg1(100, "type=%s\n", row[0]); if (bvfs_is_dir(row)) { char *path = bvfs_basename_dir(row[BVFS_Name]); ua->send_msg("%s\t0\t%s\t%s\t%s\t%s\n", row[BVFS_PathId], fileid, jobid, lstat, path); } else if (bvfs_is_version(row)) { ua->send_msg("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", row[BVFS_PathId], row[BVFS_FilenameId], fileid, jobid, lstat, row[BVFS_Md5], row[BVFS_VolName], row[BVFS_VolInchanger]); } else if (bvfs_is_file(row)) { ua->send_msg("%s\t%s\t%s\t%s\t%s\t%s\n", row[BVFS_PathId], row[BVFS_FilenameId], fileid, jobid, lstat, row[BVFS_Name]); } return 0; } static bool bvfs_parse_arg_version(UAContext *ua, char **client, DBId_t *fnid, bool *versions, bool *copies) { *fnid = 0; *client = NULL; *versions = false; *copies = false; for (int i = 1; i < ua->argc; i++) { if (fnid && bstrcasecmp(ua->argk[i], NT_("fnid"))) { if (is_a_number(ua->argv[i])) { *fnid = str_to_int64(ua->argv[i]); } } if (bstrcasecmp(ua->argk[i], NT_("client"))) { *client = ua->argv[i]; } if (copies && bstrcasecmp(ua->argk[i], NT_("copies"))) { *copies = true; } if (versions && bstrcasecmp(ua->argk[i], NT_("versions"))) { *versions = true; } } return (*client && *fnid > 0); } static bool bvfs_parse_arg(UAContext *ua, DBId_t *pathid, char **path, char **jobid, char **username, int *limit, int *offset) { *pathid = 0; *limit = 2000; *offset = 0; *path = NULL; *jobid = NULL; *username = NULL; for (int i=1; iargc; i++) { if (bstrcasecmp(ua->argk[i], NT_("pathid"))) { if (is_a_number(ua->argv[i])) { *pathid = str_to_int64(ua->argv[i]); } } if (bstrcasecmp(ua->argk[i], NT_("path"))) { *path = ua->argv[i]; } if (bstrcasecmp(ua->argk[i], NT_("username"))) { *username = ua->argv[i]; } if (bstrcasecmp(ua->argk[i], NT_("jobid"))) { if (is_a_number_list(ua->argv[i])) { *jobid = ua->argv[i]; } } if (bstrcasecmp(ua->argk[i], NT_("limit"))) { if (is_a_number(ua->argv[i])) { *limit = str_to_int64(ua->argv[i]); } } if (bstrcasecmp(ua->argk[i], NT_("offset"))) { if (is_a_number(ua->argv[i])) { *offset = str_to_int64(ua->argv[i]); } } } if (!((*pathid || *path) && *jobid)) { return false; } if (!open_client_db(ua, true)) { return false; } return true; } /* * .bvfs_cleanup path=b2XXXXX */ static bool dot_bvfs_cleanup(UAContext *ua, const char *cmd) { int i; if ((i = find_arg_with_value(ua, "path")) >= 0) { if (!open_client_db(ua, true)) { return false; } Bvfs fs(ua->jcr, ua->db); fs.drop_restore_list(ua->argv[i]); } return true; } /* * .bvfs_restore path=b2XXXXX jobid=1,2 fileid=1,2 dirid=1,2 hardlink=1,2,3,4 */ static bool dot_bvfs_restore(UAContext *ua, const char *cmd) { DBId_t pathid=0; int limit=2000, offset=0, i; char *path=NULL, *jobid=NULL, *username=NULL; char *empty = (char *)""; char *fileid, *dirid, *hardlink; fileid = dirid = hardlink = empty; if (!bvfs_parse_arg(ua, &pathid, &path, &jobid, &username, &limit, &offset)) { ua->error_msg("Can't find jobid, pathid or path argument\n"); return false; /* not enough param */ } Bvfs fs(ua->jcr, ua->db); fs.set_username(username); fs.set_jobids(jobid); if ((i = find_arg_with_value(ua, "fileid")) >= 0) { fileid = ua->argv[i]; } if ((i = find_arg_with_value(ua, "dirid")) >= 0) { dirid = ua->argv[i]; } if ((i = find_arg_with_value(ua, "hardlink")) >= 0) { hardlink = ua->argv[i]; } if (fs.compute_restore_list(fileid, dirid, hardlink, path)) { ua->send_msg("OK\n"); } else { ua->error_msg("Can't create restore list\n"); } return true; } /* * .bvfs_lsfiles jobid=1,2,3,4 pathid=10 * .bvfs_lsfiles jobid=1,2,3,4 path=/ */ static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd) { DBId_t pathid=0; int limit=2000, offset=0; char *path=NULL, *jobid=NULL, *username=NULL; char *pattern=NULL; int i; if (!bvfs_parse_arg(ua, &pathid, &path, &jobid, &username, &limit, &offset)) { ua->error_msg("Can't find jobid, pathid or path argument\n"); return false; /* not enough param */ } if ((i = find_arg_with_value(ua, "pattern")) >= 0) { pattern = ua->argv[i]; } Bvfs fs(ua->jcr, ua->db); fs.set_username(username); fs.set_jobids(jobid); fs.set_handler(bvfs_result_handler, ua); fs.set_limit(limit); if (pattern) { fs.set_pattern(pattern); } if (pathid) { fs.ch_dir(pathid); } else { fs.ch_dir(path); } fs.set_offset(offset); fs.ls_files(); return true; } /* * .bvfs_lsdirs jobid=1,2,3,4 pathid=10 * .bvfs_lsdirs jobid=1,2,3,4 path=/ * .bvfs_lsdirs jobid=1,2,3,4 path= */ static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd) { DBId_t pathid=0; int limit=2000, offset=0; char *path=NULL, *jobid=NULL, *username=NULL; if (!bvfs_parse_arg(ua, &pathid, &path, &jobid, &username, &limit, &offset)) { ua->error_msg("Can't find jobid, pathid or path argument\n"); return true; /* not enough param */ } Bvfs fs(ua->jcr, ua->db); fs.set_username(username); fs.set_jobids(jobid); fs.set_limit(limit); fs.set_handler(bvfs_result_handler, ua); if (pathid) { fs.ch_dir(pathid); } else { fs.ch_dir(path); } fs.set_offset(offset); fs.ls_special_dirs(); fs.ls_dirs(); return true; } /* * .bvfs_versions jobid=x fnid=10 pathid=10 copies versions (jobid isn't used) */ static bool dot_bvfs_versions(UAContext *ua, const char *cmd) { DBId_t pathid=0, fnid=0; int limit=2000, offset=0; char *path=NULL, *jobid=NULL, *client=NULL, *username=NULL; bool copies=false, versions=false; if (!bvfs_parse_arg(ua, &pathid, &path, &jobid, &username, &limit, &offset)) { ua->error_msg("Can't find jobid, pathid or path argument\n"); return false; /* not enough param */ } if (!bvfs_parse_arg_version(ua, &client, &fnid, &versions, &copies)) { ua->error_msg("Can't find client or fnid argument\n"); return true; /* not enough param */ } Bvfs fs(ua->jcr, ua->db); fs.set_limit(limit); fs.set_see_all_versions(versions); fs.set_see_copies(copies); fs.set_handler(bvfs_result_handler, ua); fs.set_offset(offset); fs.get_all_file_versions(pathid, fnid, client); return true; } /* * .bvfs_get_jobids jobid=1 * -> returns needed jobids to restore * .bvfs_get_jobids jobid=1 all * -> returns needed jobids to restore with all filesets a JobId=1 time * .bvfs_get_jobids ujobid=JobName * -> returns needed jobids to restore */ static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd) { JOB_DBR jr; db_list_ctx jobids, tempids; int pos; char ed1[50]; POOL_MEM query; dbid_list ids; /* Store all FileSetIds for this client */ if (!open_client_db(ua, true)) { return true; } memset(&jr, 0, sizeof(jr)); if ((pos = find_arg_with_value(ua, "ujobid")) >= 0) { bstrncpy(jr.Job, ua->argv[pos], sizeof(jr.Job)); } if ((pos = find_arg_with_value(ua, "jobid")) >= 0) { jr.JobId = str_to_int64(ua->argv[pos]); } if (!db_get_job_record(ua->jcr, ua->db, &jr)) { ua->error_msg(_("Unable to get Job record for JobId=%s: ERR=%s\n"), ua->cmd, db_strerror(ua->db)); return true; } /* When in level base, we don't rely on any Full/Incr/Diff */ if (jr.JobLevel == L_BASE) { ua->send_msg("%s\n", edit_int64(jr.JobId, ed1)); return true; } /* If we have the "all" option, we do a search on all defined fileset * for this client */ if (find_arg(ua, "all") > 0) { edit_int64(jr.ClientId, ed1); Mmsg(query, uar_sel_filesetid, ed1); db_get_query_dbids(ua->jcr, ua->db, query, ids); } else { ids.num_ids = 1; ids.DBId[0] = jr.FileSetId; } jr.JobLevel = L_INCREMENTAL; /* Take Full+Diff+Incr */ /* Foreach different FileSet, we build a restore jobid list */ for (int i=0; i < ids.num_ids; i++) { jr.FileSetId = ids.DBId[i]; if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, &tempids)) { return true; } jobids.add(tempids); } ua->send_msg("%s\n", jobids.list); return true; } static bool dot_quit_cmd(UAContext *ua, const char *cmd) { quit_cmd(ua, cmd); return true; } static bool dot_help_cmd(UAContext *ua, const char *cmd) { qhelp_cmd(ua, cmd); return true; } static bool getmsgscmd(UAContext *ua, const char *cmd) { if (console_msg_pending) { do_messages(ua, cmd); } return 1; } #ifdef DEVELOPER static void do_storage_cmd(UAContext *ua, STORERES *store, const char *cmd) { BSOCK *sd; JCR *jcr = ua->jcr; USTORERES lstore; lstore.store = store; pm_strcpy(lstore.store_source, _("unknown source")); set_wstorage(jcr, &lstore); if (!(sd = open_sd_bsock(ua))) { ua->error_msg(_("Could not open SD socket.\n")); return; } Dmsg0(120, _("Connected to storage daemon\n")); sd = jcr->store_bsock; sd->fsend("%s", cmd); if (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); } close_sd_bsock(ua); return; } static void do_client_cmd(UAContext *ua, CLIENTRES *client, const char *cmd) { BSOCK *fd; /* Connect to File daemon */ ua->jcr->res.client = client; /* Try to connect for 15 seconds */ ua->send_msg(_("Connecting to Client %s at %s:%d\n"), client->name(), client->address, client->FDport); if (!connect_to_file_daemon(ua->jcr, 1, 15, false, false)) { ua->error_msg(_("Failed to connect to Client.\n")); return; } Dmsg0(120, "Connected to file daemon\n"); fd = ua->jcr->file_bsock; fd->fsend("%s", cmd); if (fd->recv() >= 0) { ua->send_msg("%s", fd->msg); } fd->signal(BNET_TERMINATE); fd->close(); ua->jcr->file_bsock = NULL; return; } /* * .die (seg fault) * .dump (sm_dump) * .exit (no arg => .quit) */ static bool admin_cmds(UAContext *ua, const char *cmd) { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; STORERES *store = NULL; CLIENTRES *client = NULL; bool dir=false; bool do_deadlock=false; const char *remote_cmd; int i; JCR *jcr = NULL; int a; if (strncmp(ua->argk[0], ".die", 4) == 0) { if (find_arg(ua, "deadlock") > 0) { do_deadlock = true; remote_cmd = ".die deadlock"; } else { remote_cmd = ".die"; } } else if (strncmp(ua->argk[0], ".dump", 5) == 0) { remote_cmd = "sm_dump"; } else if (strncmp(ua->argk[0], ".exit", 5) == 0) { remote_cmd = "exit"; } else { ua->error_msg(_("Unknown command: %s\n"), ua->argk[0]); return true; } /* General debug? */ for (i=1; iargc; i++) { if (bstrcasecmp(ua->argk[i], "dir") || bstrcasecmp(ua->argk[i], "director")) { dir = true; } if (bstrcasecmp(ua->argk[i], "client") || bstrcasecmp(ua->argk[i], "fd")) { client = NULL; if (ua->argv[i]) { client = (CLIENTRES *)GetResWithName(R_CLIENT, ua->argv[i]); } if (!client) { client = select_client_resource(ua); } } if (bstrcasecmp(ua->argk[i], NT_("store")) || bstrcasecmp(ua->argk[i], NT_("storage")) || bstrcasecmp(ua->argk[i], NT_("sd"))) { store = NULL; if (ua->argv[i]) { store = (STORERES *)GetResWithName(R_STORAGE, ua->argv[i]); } if (!store) { store = get_storage_resource(ua); } } } if (!dir && !store && !client) { /* * We didn't find an appropriate keyword above, so * prompt the user. */ start_prompt(ua, _("Available daemons are: \n")); add_prompt(ua, _("Director")); add_prompt(ua, _("Storage")); add_prompt(ua, _("Client")); switch(do_prompt(ua, "", _("Select daemon type to make die"), NULL, 0)) { case 0: /* Director */ dir=true; break; case 1: store = get_storage_resource(ua); break; case 2: client = select_client_resource(ua); break; default: break; } } if (store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); break; default: do_storage_cmd(ua, store, remote_cmd); break; } } if (client) { do_client_cmd(ua, client, remote_cmd); } if (dir) { if (strncmp(remote_cmd, ".die", 4) == 0) { if (do_deadlock) { ua->send_msg(_("The Director will generate a deadlock.\n")); P(mutex); P(mutex); } ua->send_msg(_("The Director will segment fault.\n")); a = jcr->JobId; /* ref NULL pointer */ jcr->JobId = 1000; /* another ref NULL pointer */ jcr->JobId = a; } else if (strncmp(remote_cmd, ".dump", 5) == 0) { sm_dump(false, true); } else if (strncmp(remote_cmd, ".exit", 5) == 0) { dot_quit_cmd(ua, cmd); } } return true; } #else /* * Dummy routine for non-development version */ static bool admin_cmds(UAContext *ua, const char *cmd) { ua->error_msg(_("Unknown command: %s\n"), ua->argk[0]); return true; } #endif static bool jobdefscmd(UAContext *ua, const char *cmd) { JOBRES *jobdefs; LockRes(); foreach_res(jobdefs, R_JOBDEFS) { if (acl_access_ok(ua, Job_ACL, jobdefs->name())) { ua->send_msg("%s\n", jobdefs->name()); } } UnlockRes(); return true; } /* * Can use an argument to filter on JobType * .jobs [type=B] */ static bool jobscmd(UAContext *ua, const char *cmd) { JOBRES *job; uint32_t type = 0; int pos; if ((pos = find_arg_with_value(ua, "type")) >= 0) { type = ua->argv[pos][0]; } LockRes(); foreach_res(job, R_JOB) { if (!type || type == job->JobType) { if (acl_access_ok(ua, Job_ACL, job->name())) { ua->send_msg("%s\n", job->name()); } } } UnlockRes(); return true; } static bool filesetscmd(UAContext *ua, const char *cmd) { FILESETRES *fs; LockRes(); foreach_res(fs, R_FILESET) { if (acl_access_ok(ua, FileSet_ACL, fs->name())) { ua->send_msg("%s\n", fs->name()); } } UnlockRes(); return true; } static bool catalogscmd(UAContext *ua, const char *cmd) { CATRES *cat; LockRes(); foreach_res(cat, R_CATALOG) { if (acl_access_ok(ua, Catalog_ACL, cat->name())) { ua->send_msg("%s\n", cat->name()); } } UnlockRes(); return true; } static bool clientscmd(UAContext *ua, const char *cmd) { CLIENTRES *client; LockRes(); foreach_res(client, R_CLIENT) { if (acl_access_ok(ua, Client_ACL, client->name())) { ua->send_msg("%s\n", client->name()); } } UnlockRes(); return true; } static bool msgscmd(UAContext *ua, const char *cmd) { MSGSRES *msgs = NULL; LockRes(); foreach_res(msgs, R_MSGS) { ua->send_msg("%s\n", msgs->name()); } UnlockRes(); return true; } static bool poolscmd(UAContext *ua, const char *cmd) { POOLRES *pool; LockRes(); foreach_res(pool, R_POOL) { if (acl_access_ok(ua, Pool_ACL, pool->name())) { ua->send_msg("%s\n", pool->name()); } } UnlockRes(); return true; } static bool storagecmd(UAContext *ua, const char *cmd) { STORERES *store; LockRes(); foreach_res(store, R_STORAGE) { if (acl_access_ok(ua, Storage_ACL, store->name())) { ua->send_msg("%s\n", store->name()); } } UnlockRes(); return true; } static bool profilescmd(UAContext *ua, const char *cmd) { PROFILERES *profile; LockRes(); foreach_res(profile, R_PROFILE) { ua->send_msg("%s\n", profile->name()); } UnlockRes(); return true; } static bool aopcmd(UAContext *ua, const char *cmd) { int i; for (i = 0; ActionOnPurgeOptions[i].name; i++) { ua->send_msg("%s\n", ActionOnPurgeOptions[i].name); } return true; } static bool typescmd(UAContext *ua, const char *cmd) { int i; for (i = 0; jobtypes[i].type_name; i++) { ua->send_msg("%s\n", jobtypes[i].type_name); } return true; } /* * If this command is called, it tells the director that we * are a program that wants a sort of API, and hence, * we will probably suppress certain output, include more * error codes, and most of all send back a good number * of new signals that indicate whether or not the command * succeeded. */ static bool api_cmd(UAContext *ua, const char *cmd) { if (ua->argc == 2) { ua->api = atoi(ua->argk[1]); } else { ua->api = 1; } return true; } static int client_backups_handler(void *ctx, int num_field, char **row) { UAContext *ua = (UAContext *)ctx; ua->send_msg("| %s | %s | %s | %s | %s | %s | %s | %s |\n", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]); return 0; } /* * Return the backups for this client * * .backups client=xxx fileset=yyy */ static bool backupscmd(UAContext *ua, const char *cmd) { if (!open_client_db(ua)) { return true; } if (ua->argc != 3 || !bstrcmp(ua->argk[1], "client") || !bstrcmp(ua->argk[2], "fileset")) { return true; } if (!acl_access_ok(ua, Client_ACL, ua->argv[1], true) || !acl_access_ok(ua, FileSet_ACL, ua->argv[2], true)) { ua->error_msg(_("Access to specified Client or FileSet not allowed.\n")); return true; } Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]); if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) { ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db)); return true; } return true; } static int sql_handler(void *ctx, int num_field, char **row) { UAContext *ua = (UAContext *)ctx; POOL_MEM rows(PM_MESSAGE); /* Check for nonsense */ if (num_field == 0 || row == NULL || row[0] == NULL) { return 0; /* nothing returned */ } for (int i=0; num_field--; i++) { if (i == 0) { pm_strcpy(rows, NPRT(row[0])); } else { pm_strcat(rows, NPRT(row[i])); } pm_strcat(rows, "\t"); } if (!rows.c_str() || !*rows.c_str()) { ua->send_msg("\t"); } else { ua->send_msg("%s", rows.c_str()); } return 0; } static bool sql_cmd(UAContext *ua, const char *cmd) { int index; if (!open_client_db(ua, true)) { return true; } index = find_arg_with_value(ua, "query"); if (index < 0) { ua->error_msg(_("query keyword not found.\n")); return true; } if (!db_sql_query(ua->db, ua->argv[index], sql_handler, (void *)ua)) { Dmsg1(100, "Query failed: ERR=%s\n", db_strerror(ua->db)); ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db)); return true; } return true; } static int one_handler(void *ctx, int num_field, char **row) { UAContext *ua = (UAContext *)ctx; ua->send_msg("%s\n", row[0]); return 0; } static bool mediatypescmd(UAContext *ua, const char *cmd) { if (!open_client_db(ua)) { return true; } if (!db_sql_query(ua->db, "SELECT DISTINCT MediaType FROM MediaType ORDER BY MediaType", one_handler, (void *)ua)) { ua->error_msg(_("List MediaType failed: ERR=%s\n"), db_strerror(ua->db)); } return true; } static bool mediacmd(UAContext *ua, const char *cmd) { if (!open_client_db(ua)) { return true; } if (!db_sql_query(ua->db, "SELECT DISTINCT Media.VolumeName FROM Media ORDER BY VolumeName", one_handler, (void *)ua)) { ua->error_msg(_("List Media failed: ERR=%s\n"), db_strerror(ua->db)); } return true; } static bool schedulecmd(UAContext *ua, const char *cmd) { SCHEDRES *sched; LockRes(); foreach_res(sched, R_SCHEDULE) { ua->send_msg("%s\n", sched->hdr.name); } UnlockRes(); return true; } static bool locationscmd(UAContext *ua, const char *cmd) { if (!open_client_db(ua)) { return true; } if (!db_sql_query(ua->db, "SELECT DISTINCT Location FROM Location ORDER BY Location", one_handler, (void *)ua)) { ua->error_msg(_("List Location failed: ERR=%s\n"), db_strerror(ua->db)); } return true; } static bool levelscmd(UAContext *ua, const char *cmd) { int i; /* * Note some levels are blank, which means none is needed */ if (ua->argc == 1) { for (i=0; joblevels[i].level_name; i++) { if (joblevels[i].level_name[0] != ' ') { ua->send_msg("%s\n", joblevels[i].level_name); } } } else if (ua->argc == 2) { int jobtype = 0; /* * Assume that first argument is the Job Type */ for (i=0; jobtypes[i].type_name; i++) { if (bstrcasecmp(ua->argk[1], jobtypes[i].type_name)) { jobtype = jobtypes[i].job_type; break; } } for (i=0; joblevels[i].level_name; i++) { if ((joblevels[i].job_type == jobtype) && (joblevels[i].level_name[0] != ' ')) { ua->send_msg("%s\n", joblevels[i].level_name); } } } return true; } static bool volstatuscmd(UAContext *ua, const char *cmd) { int i; for (i = 0; VolumeStatus[i].name; i++) { ua->send_msg("%s\n", VolumeStatus[i].name); } return true; } /* * Return default values for a job */ static bool defaultscmd(UAContext *ua, const char *cmd) { char ed1[50]; if (ua->argc != 2 || !ua->argv[1]) { return true; } if (bstrcmp(ua->argk[1], "job")) { JOBRES *job; /* * Job defaults */ if (!acl_access_ok(ua, Job_ACL, ua->argv[1], true)) { return true; } job = (JOBRES *)GetResWithName(R_JOB, ua->argv[1]); if (job) { USTORERES store; ua->send_msg("job=%s", job->name()); ua->send_msg("pool=%s", job->pool->name()); ua->send_msg("messages=%s", job->messages->name()); ua->send_msg("client=%s", (job->client) ? job->client->name() : _("*None*")); get_job_storage(&store, job, NULL); ua->send_msg("storage=%s", store.store->name()); ua->send_msg("where=%s", job->RestoreWhere ? job->RestoreWhere : ""); ua->send_msg("level=%s", level_to_str(job->JobLevel)); ua->send_msg("type=%s", job_type_to_str(job->JobType)); ua->send_msg("fileset=%s", (job->fileset) ? job->fileset->name() : _("*None*")); ua->send_msg("enabled=%d", job->enabled); ua->send_msg("catalog=%s", (job->client) ? job->client->catalog->name() : _("*None*")); } } else if (bstrcmp(ua->argk[1], "client")) { CLIENTRES *client; /* * Client defaults */ if (!acl_access_ok(ua, Client_ACL, ua->argv[1], true)) { return true; } client = (CLIENTRES *)GetResWithName(R_CLIENT, ua->argv[1]); if (client) { ua->send_msg("client=%s", client->name()); ua->send_msg("address=%s", client->address); ua->send_msg("fdport=%d", client->FDport); ua->send_msg("file_retention=%s", edit_uint64(client->FileRetention, ed1)); ua->send_msg("job_retention=%s", edit_uint64(client->JobRetention, ed1)); ua->send_msg("autoprune=%d", client->AutoPrune); ua->send_msg("enabled=%d", client->enabled); ua->send_msg("catalog=%s", client->catalog->name()); } } else if (bstrcmp(ua->argk[1], "storage")) { STORERES *storage; DEVICERES *device; /* * Storage defaults */ if (!acl_access_ok(ua, Storage_ACL, ua->argv[1], true)) { return true; } storage = (STORERES *)GetResWithName(R_STORAGE, ua->argv[1]); if (storage) { ua->send_msg("storage=%s", storage->name()); ua->send_msg("address=%s", storage->address); ua->send_msg("enabled=%d", storage->enabled); ua->send_msg("media_type=%s", storage->media_type); ua->send_msg("sdport=%d", storage->SDport); device = (DEVICERES *)storage->device->first(); ua->send_msg("device=%s", device->name()); if (storage->device->size() > 1) { while ((device = (DEVICERES *)storage->device->next())) { ua->send_msg(",%s", device->name()); } } } } else if (bstrcmp(ua->argk[1], "pool")) { POOLRES *pool; /* * Pool defaults */ if (!acl_access_ok(ua, Pool_ACL, ua->argv[1], true)) { return true; } pool = (POOLRES *)GetResWithName(R_POOL, ua->argv[1]); if (pool) { ua->send_msg("pool=%s", pool->name()); ua->send_msg("pool_type=%s", pool->pool_type); ua->send_msg("label_format=%s", pool->label_format?pool->label_format:""); ua->send_msg("use_volume_once=%d", pool->use_volume_once); ua->send_msg("purge_oldest_volume=%d", pool->purge_oldest_volume); ua->send_msg("recycle_oldest_volume=%d", pool->recycle_oldest_volume); ua->send_msg("recycle_current_volume=%d", pool->recycle_current_volume); ua->send_msg("max_volumes=%d", pool->max_volumes); ua->send_msg("vol_retention=%s", edit_uint64(pool->VolRetention, ed1)); ua->send_msg("vol_use_duration=%s", edit_uint64(pool->VolUseDuration, ed1)); ua->send_msg("max_vol_jobs=%d", pool->MaxVolJobs); ua->send_msg("max_vol_files=%d", pool->MaxVolFiles); ua->send_msg("max_vol_bytes=%s", edit_uint64(pool->MaxVolBytes, ed1)); ua->send_msg("auto_prune=%d", pool->AutoPrune); ua->send_msg("recycle=%d", pool->Recycle); ua->send_msg("file_retention=%s", edit_uint64(pool->FileRetention, ed1)); ua->send_msg("job_retention=%s", edit_uint64(pool->JobRetention, ed1)); } } return true; } bareos-Release-14.2.6/src/dird/ua_impexp.c000066400000000000000000001264041263011562700203130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Import/Export and Move functions. * * Written by Marco van Wieringen, December 2011 */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ /* * Import/Export and Move volumes in an autochanger. * * The following things apply here: * - the source and destination slot list is walked in order * So when you give a selection of 1-3,7,5 it will visit the * slots 1,2,3,5,7 in that order. * - moving volumes from a source slot specification to a * destination slot specification also is performed in order. * So when you specify the source slots as 1-3,7,5 and * the destination slots as 22-24,25,27 the following moves * will take place: * 1 --> 22 * 2 --> 23 * 3 --> 24 * 5 --> 25 * 7 --> 27 * * When you want to be sure the moves are performed in the * way you expect them to happen make sure the selection * cannot be wrongly interpreted by the code e.g. use * unambigious ranges. Or ranges of only one slot for * both the source and destination. */ /* * Walk the slot list and count the number of slots enabled in * the list. */ static inline int count_enabled_slots(char *slot_list, int max_slots) { int i; int cnt = 0; for (i = 0; i < max_slots; i++) { if (bit_is_set(i, slot_list)) { cnt++; } } return cnt; } /* * See if a specific slotnr is loaded in one of the drives. * As the slot list is sorted on the index the drive slots * are always first on the list. So when we reach the first * non drive slot we can abort the loop. */ static inline vol_list_t *is_loaded_in_drive(dlist *vol_list, int slotnr) { vol_list_t *vl; vl = (vol_list_t *)vol_list->first(); while (vl && vl->Type == slot_type_drive) { Dmsg2(100, "Checking drive %d for loaded volume == %d\n", vl->Slot, vl->Loaded); if (vl->Loaded == slotnr) { return vl; } vl = (vol_list_t *)vol_list->next((void *)vl); } return NULL; } /* * See if a selected slot list has the wanted content and * deselect any slot which has not. */ static inline void validate_slot_list(UAContext *ua, dlist *vol_list, char *slot_list, slot_content content) { vol_list_t *vl; /* * Walk the list of drives and slots available. */ foreach_dlist(vl, vol_list) { switch (vl->Type) { case slot_type_normal: case slot_type_import: if (bit_is_set(vl->Slot - 1, slot_list)) { switch (content) { case slot_content_full: /* * If it has the correct content we are done. */ if (vl->Content == content) { continue; } /* * If the request is for a slot with content * we check the actual content. When its empty * but loaded in the drive we just pretend * that it has content. We just unload the drive * on the export move operation. */ if (vl->Type == slot_type_normal && vl->Content == slot_content_empty && is_loaded_in_drive(vol_list, vl->Slot) != NULL) { continue; } Dmsg1(100, "Deselecting slot %d doesn't have wanted content.\n", vl->Slot); ua->warning_msg(_("Deselecting slot %d doesn't have wanted content.\n"), vl->Slot); clear_bit(vl->Slot - 1, slot_list); break; case slot_content_empty: /* * If it has the correct content we are done. */ if (vl->Content == content) { continue; } /* * If the slot is empty and this is normal slot * make sure its not loaded in a drive because * then the slot is not really empty. */ if (vl->Type == slot_type_normal && vl->Content == slot_content_empty && is_loaded_in_drive(vol_list, vl->Slot) == NULL) { continue; } Dmsg1(100, "Deselecting slot %d doesn't have wanted content.\n", vl->Slot); ua->warning_msg(_("Deselecting slot %d doesn't have wanted content.\n"), vl->Slot); clear_bit(vl->Slot - 1, slot_list); break; default: break; } } break; default: break; } } } /* * See where a certain slot is referenced. * For a drive slot we check the loaded variable * and for all other slots the exact slotnr. * We only check slots which have content. */ static inline vol_list_t *find_slot_in_list(dlist *vol_list, int slotnr) { vol_list_t *vl; foreach_dlist(vl, vol_list) { switch (vl->Content) { case slot_content_full: switch (vl->Type) { case slot_type_drive: if (vl->Loaded == slotnr) { return vl; } break; default: if (vl->Slot == slotnr) { return vl; } break; } break; default: continue; } } return NULL; } /* * Check if a source and destination slot list overlap. * An overlap is solved when there is a slot enabled * in either the source or destination slot list before * the overlap is detected. e.g. then on a move the volume * is first moved somewhere else before either the source * or destination slot is referenced by the next operation. * Then again it wise not to perform to crazy operations * as we will cancel any crazy-ness as soon as we encounter * it. */ static inline bool slot_lists_overlap(char *src_slot_list, char *dst_slot_list, int max_slots) { int i; bool other_slot_enabled = false; for (i = 0; i < max_slots; i++) { /* * See if both the source and destination slot are selected * and there has not been a source or destination slot * which has been selected before. */ if (bit_is_set(i, src_slot_list) && bit_is_set(i, dst_slot_list) && !other_slot_enabled) { Dmsg0(100, "Found slot enabled in either source or destination selection which overlap\n"); return true; } else { if (bit_is_set(i, src_slot_list) || bit_is_set(i, dst_slot_list)) { Dmsg0(100, "Found slot enabled in either source or destination selection\n"); other_slot_enabled = true; } } } Dmsg0(100, "Found no slot enabled in either source or destination selection which overlap\n"); return false; } /* * Simple comparison function for binary search of vol_list_t */ static int compare_vol_list_entry(void *e1, void *e2) { vol_list_t *v1, *v2; v1 = (vol_list_t *)e1; v2 = (vol_list_t *)e2; if (v1->Index == v2->Index) { return 0; } else { return (v1->Index < v2->Index) ? -1 : 1; } } /* * Scan all slots that are not empty for the exact volumename * by reading the label of the volume replacing the scanned * barcode when available. When a valid source slot list * is given we only check the slots enabled in that slot list. * We return an updated dlist with the new content of the * autochanger after the scan as that may move some volumes * around. We free the old list and return the new. */ static inline dlist *scan_slots_for_volnames(UAContext *ua, STORERES *store, int drive, dlist *vol_list, char *src_slot_list) { dlist *new_vol_list; vol_list_t vls; vol_list_t *vl1, *vl2; /* * Walk the list of drives and slots available. */ foreach_dlist(vl1, vol_list) { switch (vl1->Type) { case slot_type_drive: continue; default: /* * See if a slot list selection was done and * if so only get the content for this slot when * it is selected in the slot list. */ if (src_slot_list && !bit_is_set(vl1->Slot - 1, src_slot_list)) { continue; } switch (vl1->Content) { case slot_content_full: if (vl1->VolName) { free(vl1->VolName); vl1->VolName = NULL; } vl1->VolName = get_volume_name_from_SD(ua, vl1->Slot, drive); Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl1->VolName, vl1->Slot); break; case slot_content_empty: /* * See if the slot is empty because the volume is * loaded in a drive. */ if (vl1->Type == slot_type_normal && (vl2 = is_loaded_in_drive(vol_list, vl1->Slot)) != NULL) { if (vl2->VolName) { free(vl2->VolName); vl2->VolName = NULL; } vl2->VolName = get_volume_name_from_SD(ua, vl1->Slot, drive); Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl2->VolName, vl1->Slot); } break; default: continue; } break; } } /* * As the scan for volumes can alter the location of * the volumes in the autochanger e.g. volumes in drives * being put back into slots etc we rescan the changer. */ new_vol_list = get_vol_list_from_SD(ua, store, true /* listall */, true /* want to see all slots */); if (!new_vol_list) { /* * Free the old vol_list and return a NULL vol_list. */ free_vol_list(vol_list); return NULL; } /* * Walk the list of drives and slots available. * And copy the new scanned volume names from the old list * to the new list. * * This is optimized for the case the slots are still * filled with the same volume. */ foreach_dlist(vl1, new_vol_list) { switch (vl1->Type) { case slot_type_drive: switch (vl1->Content) { case slot_content_full: /* * Lookup the drive in the old list. */ vls.Index = vl1->Index; vl2 = (vol_list_t *)vol_list->binary_search((void *)&vls, compare_vol_list_entry); if (vl2 && vl2->Content == slot_content_full && vl2->Loaded == vl1->Loaded) { /* * Volume in drive is the same copy the volume name. */ if (vl2->VolName) { free(vl2->VolName); } vl2->VolName = vl1->VolName; vl1->VolName = NULL; } else { /* * Drive is loaded with a volume which was previously * loaded somewhere else. Lookup the currently loaded * volume in the old list. */ vl2 = find_slot_in_list(vol_list, vl1->Loaded); if (vl2) { if (vl2->VolName) { free(vl2->VolName); } vl2->VolName = vl1->VolName; vl1->VolName = NULL; } } break; default: continue; } break; case slot_type_normal: case slot_type_import: /* * See if a slot list selection was done and * if so only get the content for this slot when * it is selected in the slot list. */ if (src_slot_list && !bit_is_set(vl1->Slot - 1, src_slot_list)) { continue; } switch (vl1->Content) { case slot_content_full: /* * Lookup the slot in the old list. */ vls.Index = vl1->Index; vl2 = (vol_list_t *)vol_list->binary_search((void *)&vls, compare_vol_list_entry); if (vl2 && vl2->Content == slot_content_full && vl2->Slot == vl1->Slot) { /* * Volume in slot is the same copy the volume name. */ if (vl2->VolName) { free(vl2->VolName); } vl2->VolName = vl1->VolName; vl1->VolName = NULL; } else { /* * This should never happen as a volume is always put back * into the same slot it was taken from. But as we have the * code to lookup the old place we take a shot at it. */ vl2 = find_slot_in_list(vol_list, vl1->Slot); if (vl2) { if (vl2->VolName) { free(vl2->VolName); } vl2->VolName = vl1->VolName; vl1->VolName = NULL; } } break; default: continue; } break; default: break; } } /* * Free the old vol_list and return the new data. */ free_vol_list(vol_list); return new_vol_list; } /* * Convert a volume name into a slot selection. */ static inline bool get_slot_list_using_volname(UAContext *ua, const char *volumename, dlist *vol_list, char *wanted_slot_list, char *selected_slot_list, int max_slots) { vol_list_t *vl1, *vl2; bool found = false; if (is_name_valid(volumename, NULL)) { foreach_dlist(vl1, vol_list) { /* * We only select normal and import/export slots. */ switch (vl1->Type) { case slot_type_normal: case slot_type_import: /* * When the source slot list is limited we check to * see if this slot should be taken into consideration. */ if (wanted_slot_list && !bit_is_set(vl1->Slot - 1, wanted_slot_list)) { continue; } switch (vl1->Content) { case slot_content_full: /* * See if the wanted volume is loaded in this slot. */ Dmsg3(100, "Checking for volume name in slot %d, wanted %s, found %s\n", vl1->Slot, volumename, (vl1->VolName) ? vl1->VolName : "NULL"); if (vl1->VolName && bstrcmp(vl1->VolName, volumename)) { found = true; } break; case slot_content_empty: /* * See if this slot is loaded in drive and drive contains wanted volume */ vl2 = is_loaded_in_drive(vol_list, vl1->Slot); if (vl2 != NULL) { Dmsg3(100, "Checking for volume name in drive %d, wanted %s, found %s\n", vl2->Slot, volumename, (vl2->VolName) ? vl2->VolName : "NULL"); if (vl2->VolName && bstrcmp(vl2->VolName, volumename)) { found = true; } } else { Dmsg1(100, "Skipping empty slot %d\n", vl1->Slot); } break; default: break; } break; default: break; } /* * If we found a match break the loop. */ if (found) { break; } } /* * See if we found the wanted volumename in the list * of available slots in the autochanger and mark the * slot in the slot_list or give a warning when the * volumename was not found. */ if (found) { set_bit(vl1->Slot - 1, selected_slot_list); } else { Dmsg1(100, "No volume named %s in changer or in selected source slots.\n", volumename); ua->warning_msg(_("No volume named %s in changer or in selected source slots.\n"), volumename); } } else { Dmsg1(100, "Skipping illegal volumename %s.\n", volumename); ua->warning_msg(_("Skipping illegal volumename %s.\n"), volumename); } return found; } /* * Convert a number of volume names into a slot selection. */ static inline int get_slot_list_using_volnames(UAContext *ua, int arg, dlist *vol_list, char *wanted_slot_list, char *selected_slot_list, int max_slots) { int i; int cnt = 0; char *s, *token, *sep; /* * The arg argument contains the index of the first occurence * of the volume keyword. We scan the whole cmdline for one * or more volume= cmdline parameters. */ for (i = arg; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], "volume")) { /* * Parse a volumelist e.g. vol1|vol2 and a single volume e.g. vol1 */ s = bstrdup(ua->argv[i]); token = s; /* * We could use strtok() here. But we're not going to, because: * (a) strtok() is deprecated, having been replaced by strsep(); * (b) strtok() is broken in significant ways. * we could use strsep() instead, but it's not universally available. * so we grow our own using strchr(). */ sep = strchr(token, '|'); while (sep != NULL) { *sep = '\0'; if (get_slot_list_using_volname(ua, token, vol_list, wanted_slot_list, selected_slot_list, max_slots)) { cnt++; } token = ++sep; sep = strchr(token, '|'); } /* * Pick up the last token. */ if (*token) { if (get_slot_list_using_volname(ua, token, vol_list, wanted_slot_list, selected_slot_list, max_slots)) { cnt++; } } free(s); } } return cnt; } /* * Create a slot list selection based on the slot type * and slot content. All slots which have the wanted * slot type and wanted slot content are selected. */ static inline int auto_fill_slot_selection(dlist *vol_list, char *slot_list, slot_type type, slot_content content) { int cnt = 0; vol_list_t *vl; /* * Walk the list of drives and slots available. */ foreach_dlist(vl, vol_list) { /* * Make sure slot_type and slot_content match. */ if (vl->Type != type || vl->Content != content) { Dmsg3(100, "Skipping slot %d, Type %d, Content %d\n", vl->Slot, vl->Type, vl->Content); continue; } /* * If the slot is empty and this is normal slot * make sure its not loaded in a drive because * then the slot is not really empty. */ if (type == slot_type_normal && content == slot_content_empty && is_loaded_in_drive(vol_list, vl->Slot) != NULL) { Dmsg3(100, "Skipping slot %d, Type %d, Content %d is empty but loaded in drive\n", vl->Slot, vl->Type, vl->Content); continue; } /* * Mark the slot as selected in the slot list. * And increase the number of slots selected. */ Dmsg3(100, "Selected slot %d which has slot_type %d and content_type %d\n", vl->Slot, vl->Type, vl->Content); set_bit(vl->Slot - 1, slot_list); cnt++; } return cnt; } /* * Verify if all slots in the given slot list are of a certain * type and have a given content. */ static inline bool verify_slot_list(dlist *vol_list, char *slot_list, slot_type type, slot_content content) { vol_list_t *vl; /* * Walk the list of drives and slots available. */ foreach_dlist(vl, vol_list) { /* * Move operations are only allowed between * normal slots and import/export slots so * don't consider any other slot type. */ switch (vl->Type) { case slot_type_normal: case slot_type_import: if (bit_is_set(vl->Slot - 1, slot_list)) { /* * If the type and content is ok we can continue with the next one. */ if (vl->Type == type && vl->Content == content) { continue; } /* * When the content is not the wanted and this is a normal * slot take into consideration if its loaded into the drive. * When we are asked for an empty slot it should NOT be loaded * in the drive but when we are asked for a full slot it being * loaded in the drive also makes that the slot is filled as * we can just release the drive so that its put back into * the slot and then moved. */ if (vl->Type == slot_type_normal) { switch (content) { case slot_content_empty: if (is_loaded_in_drive(vol_list, vl->Slot) != NULL) { Dmsg3(100, "Skipping slot %d, Type %d, Content %d is empty but loaded in drive\n", vl->Slot, vl->Type, vl->Content); return false; } break; case slot_content_full: if (is_loaded_in_drive(vol_list, vl->Slot) != NULL) { continue; } break; default: break; } } /* * Not the wanted type or content and not a special case. */ Dmsg3(100, "Skipping slot %d, Type %d, Content %d\n", vl->Slot, vl->Type, vl->Content); return false; } break; default: break; } } return true; } /* * Perform an internal update of our view of the autochanger on a move instruction * without requesting the new status from the SD again. */ static inline bool update_internal_slot_list(dlist *vol_list, int source, int destination) { bool found; vol_list_t *vl1, *vl2; /* * First lookup the source and destination slots in the vol_list. */ found = false; foreach_dlist(vl1, vol_list) { switch (vl1->Type) { case slot_type_drive: continue; default: if (vl1->Slot == source) { found = true; } break; } if (found) { break; } } found = false; foreach_dlist(vl2, vol_list) { switch (vl2->Type) { case slot_type_drive: continue; default: if (vl2->Slot == destination) { found = true; } break; } if (found) { break; } } if (vl1 && vl2) { /* * Swap the data. */ vl2->VolName = vl1->VolName; vl2->Content = slot_content_full; vl1->VolName = NULL; vl1->Content = slot_content_empty; Dmsg5(100, "Update internal slotlist slot %d with volname %s, content %d and slot %d with content %d and volname NULL\n", vl2->Slot, (vl2->VolName) ? vl2->VolName : "NULL", vl2->Content, vl1->Slot, vl1->Content); return true; } return false; } /* * Unload a volume currently loaded in a drive. */ static bool release_loaded_volume(UAContext *ua, STORERES *store, int drive, dlist *vol_list) { bool found; vol_list_t *vl1, *vl2; if (!do_autochanger_volume_operation(ua, store, "release", drive, -1)) { return false; } /* * Lookup the drive in the vol_list. */ found = false; foreach_dlist(vl1, vol_list) { switch (vl1->Type) { case slot_type_drive: if (vl1->Slot == drive) { found = true; } break; default: break; } /* * As drives are at the front of the list * when we see the first non drive we are done. */ if (found || vl1->Type != slot_type_drive) { break; } } /* * Lookup the slot in the slotlist referenced by the loaded value in the drive slot. */ found = false; foreach_dlist(vl2, vol_list) { switch (vl2->Type) { case slot_type_drive: continue; default: if (vl2->Slot == vl1->Loaded) { found = true; } break; } if (found) { break; } } if (vl1 && vl2) { /* * Swap the data. */ vl2->VolName = vl1->VolName; vl2->Content = slot_content_full; vl1->VolName = NULL; vl1->Content = slot_content_empty; vl1->Loaded = 0; Dmsg5(100, "Update internal slotlist slot %d with volname %s, content %d and slot %d with content %d and volname NULL\n", vl2->Slot, (vl2->VolName) ? vl2->VolName : "NULL", vl2->Content, vl1->Slot, vl1->Content); return true; } return false; } /* * Ask the autochanger to move volume from a source slot * to a destination slot by walking the two filled * slot lists and marking every visited slot. */ static char *move_volumes_in_autochanger(UAContext *ua, enum e_move_op operation, STORERES *store, dlist *vol_list, char *src_slot_list, char *dst_slot_list, int max_slots) { int i, j; vol_list_t *vl; char *visited_slot_list; int nr_enabled_src_slots, nr_enabled_dst_slots; /* * Sanity check. */ nr_enabled_src_slots = count_enabled_slots(src_slot_list, max_slots); nr_enabled_dst_slots = count_enabled_slots(dst_slot_list, max_slots); if (nr_enabled_src_slots == 0 || nr_enabled_dst_slots == 0) { ua->warning_msg(_("Nothing to do\n")); return NULL; } /* * When doing an export we first set all slots in the database * to inchanger = 0 so we cannot get surprises that a running * backup can grab such a volume. */ switch (operation) { case VOLUME_EXPORT: update_inchanger_for_export(ua, store, vol_list, src_slot_list); break; default: break; } /* * Create an empty slot list in which we keep track of the slots * we visited during this move operation so we can return that data * to the caller which can use it to update only the slots updated * by the move operation. */ visited_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, visited_slot_list); j = 1; for (i = 1; i <= max_slots; i++) { /* * See if the slot is marked in the source slot list. */ if (bit_is_set(i - 1, src_slot_list)) { /* * Search for the first marked slot in the destination selection. */ while (j <= max_slots) { if (bit_is_set(j - 1, dst_slot_list)) { break; } j++; } /* * This should never happen but a sanity check just in case. */ if (j > max_slots) { Dmsg0(100, "Failed to find suitable destination slot in slot range.\n"); ua->warning_msg(_("Failed to find suitable destination slot in slot range.\n")); break; } /* * Based on the operation see if we need to unload the drive. */ switch (operation) { case VOLUME_EXPORT: /* * Sanity check to see if the volume being exported is in the drive. * If so we release the drive and then perform the actual move. */ vl = is_loaded_in_drive(vol_list, i); if (vl != NULL) { if (!release_loaded_volume(ua, store, vl->Slot, vol_list)) { Dmsg1(100, "Failed to release volume in drive %d\n", vl->Slot); ua->warning_msg(_("Failed to release volume in drive %d\n"), vl->Slot); continue; } } break; default: break; } /* * If we found a source and destination slot perform the move. */ if (transfer_volume(ua, store, i, j)) { Dmsg2(100, "Successfully moved volume from source slot %d to destination slot %d\n", i, j); update_internal_slot_list(vol_list, i, j); set_bit(i - 1, visited_slot_list); set_bit(j - 1, visited_slot_list); } else { Dmsg2(100, "Failed to move volume from source slot %d to destination slot %d\n", i, j); ua->warning_msg(_("Failed to move volume from source slot %d to destination slot %d\n"), i, j); switch (operation) { case VOLUME_EXPORT: /* * For an export we always set the source slot as visited so when the * move operation fails we update the inchanger flag in the database back * to 1 so we know it still is in the changer. */ set_bit(i - 1, visited_slot_list); break; default: break; } } j++; } } return visited_slot_list; } /* * Perform the actual move operation which is either a: * - import of import slots into normal slots * - export of normal slots into export slots * - move from one normal slot to an other normal slot */ static int perform_move_operation(UAContext *ua, enum e_move_op operation) { bool scan; USTORERES store; dlist *vol_list; char *src_slot_list = NULL, *dst_slot_list = NULL, *tmp_slot_list = NULL, *visited_slot_list = NULL; int nr_enabled_src_slots = 0, nr_enabled_dst_slots = 0; int drive = -1; int i, max_slots; int retval = 0; store.store = get_storage_resource(ua, false, true); if (!store.store) { return retval; } switch (store.store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); return retval; default: break; } pm_strcpy(store.store_source, _("command line")); set_wstorage(ua->jcr, &store); /* * See if the scan option was given. * We need a drive for the scanning so ask if * the scan option was specified. */ scan = find_arg(ua, NT_("scan")) >= 0; if (scan) { drive = get_storage_drive(ua, store.store); } /* * Get the number of slots in the autochanger for * sizing the slot lists. */ max_slots = get_num_slots_from_SD(ua); if (max_slots <= 0) { ua->warning_msg(_("No slots in changer.\n")); return retval; } /* * Get the current content of the autochanger for * validation and selection purposes. */ vol_list = get_vol_list_from_SD(ua, store.store, true /* listall */, true /* want to see all slots */); if (!vol_list) { ua->warning_msg(_("No Volumes found, or no barcodes.\n")); goto bail_out; } /* * See if there are any source slot selections. */ i = find_arg_with_value(ua, "srcslots"); if (i < 0) { i = find_arg_with_value(ua, "srcslot"); } if (i >= 0) { src_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, src_slot_list); if (!get_user_slot_list(ua, src_slot_list, "srcslots", max_slots)) { goto bail_out; } else { /* * See if we should scan slots for the correct * volume name or that we can use the barcodes. * If a set of src slots was given we only scan * the content of those slots. */ if (scan) { vol_list = scan_slots_for_volnames(ua, store.store, drive, vol_list, src_slot_list); if (!vol_list) { goto bail_out; } } /* * Clear any slot that has no content in the source selection. */ validate_slot_list(ua, vol_list, src_slot_list, slot_content_full); nr_enabled_src_slots = count_enabled_slots(src_slot_list, max_slots); } } else { /* * See if we should scan slots for the correct * volume name or that we can use the barcodes. */ if (scan) { vol_list = scan_slots_for_volnames(ua, store.store, drive, vol_list, src_slot_list); if (!vol_list) { goto bail_out; } } } /* * See if there are any destination slot selections. */ i = find_arg_with_value(ua, "dstslots"); if (i < 0) { i = find_arg_with_value(ua, "dstslot"); } if (i >= 0) { dst_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, dst_slot_list); if (!get_user_slot_list(ua, dst_slot_list, "dstslots", max_slots)) { goto bail_out; } else { /* * Clear any slot in the destination slot list which has not the wanted content. */ switch (operation) { case VOLUME_IMPORT: case VOLUME_EXPORT: validate_slot_list(ua, vol_list, dst_slot_list, slot_content_empty); break; default: break; } nr_enabled_dst_slots = count_enabled_slots(dst_slot_list, max_slots); } } /* * For Import and Export operations we can also use a list * of volume names for which we lookup the slot they are * loaded in. */ switch (operation) { case VOLUME_IMPORT: case VOLUME_EXPORT: i = find_arg_with_value(ua, "volume"); if (i > 0) { /* * Create a new temporary slot list with gets filled * by the selection criteria on the cmdline. We provide * the current src_slot_list as an extra selection criteria. */ tmp_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, tmp_slot_list); nr_enabled_src_slots = get_slot_list_using_volnames(ua, i, vol_list, src_slot_list, tmp_slot_list, max_slots); if (src_slot_list) { free(src_slot_list); } src_slot_list = tmp_slot_list; } break; default: break; } Dmsg2(100, "src_slots = %d, dst_slots = %d\n", nr_enabled_src_slots, nr_enabled_dst_slots); /* * First generic sanity check if there is a source selection the number * of selected slots in the source must be less or equal to the * number of slots in the destination */ if (nr_enabled_src_slots && nr_enabled_dst_slots && nr_enabled_src_slots > nr_enabled_dst_slots) { ua->warning_msg(_("Source slot selection doesn't fit into destination slot selection.\n")); goto bail_out; } /* * Detect any conflicting overlaps in source and destination selection. */ if (nr_enabled_src_slots && nr_enabled_dst_slots && slot_lists_overlap(src_slot_list, dst_slot_list, max_slots)) { ua->warning_msg(_("Source slot selection and destination slot selection overlap.\n")); goto bail_out; } /* * Operation specific checks. */ switch (operation) { case VOLUME_EXPORT: if (nr_enabled_src_slots == 0) { ua->warning_msg(_("Cannot perform an export operation without source slot selection\n")); goto bail_out; } break; case VOLUME_MOVE: if (nr_enabled_src_slots == 0 || nr_enabled_dst_slots == 0) { ua->warning_msg(_("Cannot perform a move operation without source and/or destination selection\n")); goto bail_out; } break; default: break; } switch (operation) { case VOLUME_IMPORT: /* * Perform an autofill of the source slots when none are selected. */ if (nr_enabled_src_slots == 0) { src_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, src_slot_list); nr_enabled_src_slots = auto_fill_slot_selection(vol_list, src_slot_list, slot_type_import, slot_content_full); } else { /* * All slots in the source selection need to be import/export slots and filled. */ if (!verify_slot_list(vol_list, src_slot_list, slot_type_import, slot_content_full)) { ua->warning_msg(_("Not all slots in source selection are import slots and filled.\n")); goto bail_out; } } /* * Perform an autofill of the destination slots when none are selected. */ if (nr_enabled_dst_slots == 0) { dst_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, dst_slot_list); nr_enabled_dst_slots = auto_fill_slot_selection(vol_list, dst_slot_list, slot_type_normal, slot_content_empty); if (nr_enabled_src_slots > nr_enabled_dst_slots) { ua->warning_msg(_("Not enough free slots available to import %d volumes\n"), nr_enabled_src_slots); goto bail_out; } } else { /* * All slots in the destination selection need to be normal slots and empty. */ if (!verify_slot_list(vol_list, dst_slot_list, slot_type_normal, slot_content_empty)) { ua->warning_msg(_("Not all slots in destination selection are normal slots and empty.\n")); goto bail_out; } } visited_slot_list = move_volumes_in_autochanger(ua, operation, store.store, vol_list, src_slot_list, dst_slot_list, max_slots); break; case VOLUME_EXPORT: /* * All slots in the source selection need to be normal slots. */ if (!verify_slot_list(vol_list, src_slot_list, slot_type_normal, slot_content_full)) { ua->warning_msg(_("Not all slots in source selection are normal slots and filled.\n")); goto bail_out; } /* * Perform an autofill of the destination slots when none are selected. */ if (nr_enabled_dst_slots == 0) { dst_slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, dst_slot_list); nr_enabled_dst_slots = auto_fill_slot_selection(vol_list, dst_slot_list, slot_type_import, slot_content_empty); if (nr_enabled_src_slots > nr_enabled_dst_slots) { ua->warning_msg(_("Not enough free export slots available to export %d volume%s\n"), nr_enabled_src_slots, nr_enabled_src_slots > 1 ? "s" : ""); goto bail_out; } } else { /* * All slots in the destination selection need to be import/export slots and empty. */ if (!verify_slot_list(vol_list, dst_slot_list, slot_type_import, slot_content_empty)) { ua->warning_msg(_("Not all slots in destination selection are export slots and empty.\n")); goto bail_out; } } visited_slot_list = move_volumes_in_autochanger(ua, operation, store.store, vol_list, src_slot_list, dst_slot_list, max_slots); break; case VOLUME_MOVE: visited_slot_list = move_volumes_in_autochanger(ua, operation, store.store, vol_list, src_slot_list, dst_slot_list, max_slots); break; default: break; } /* * If we actually moved some volumes update the database with the * new info for those slots. */ if (visited_slot_list && count_enabled_slots(visited_slot_list, max_slots) > 0) { Dmsg0(100, "Updating database with new info for visited slots\n"); update_slots_from_vol_list(ua, store.store, vol_list, visited_slot_list); } retval = 1; bail_out: close_sd_bsock(ua); if (vol_list) { free_vol_list(vol_list); } if (src_slot_list) { free(src_slot_list); } if (dst_slot_list) { free(dst_slot_list); } if (visited_slot_list) { free(visited_slot_list); } return retval; } /* * Import volumes from Import/Export Slots into normal Slots. */ int import_cmd(UAContext *ua, const char *cmd) { return perform_move_operation(ua, VOLUME_IMPORT); } /* * Export volumes from normal slots to Import/Export Slots. */ int export_cmd(UAContext *ua, const char *cmd) { return perform_move_operation(ua, VOLUME_EXPORT); } /* * Move volume from one slot to an other. */ int move_cmd(UAContext *ua, const char *cmd) { return perform_move_operation(ua, VOLUME_MOVE); } bareos-Release-14.2.6/src/dird/ua_input.c000066400000000000000000000132211263011562700201400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Input and scanning code * * Kern Sibbald, October MMI */ #include "bareos.h" #include "dird.h" /* Imported variables */ /* Exported functions */ /* * If subprompt is set, we send a BNET_SUB_PROMPT signal otherwise * send a BNET_TEXT_INPUT signal. */ int get_cmd(UAContext *ua, const char *prompt, bool subprompt) { BSOCK *sock = ua->UA_sock; int status; ua->cmd[0] = 0; if (!sock || ua->batch) { /* No UA or batch mode */ return 0; } if (!subprompt && ua->api) { sock->signal(BNET_TEXT_INPUT); } sock->fsend("%s", prompt); if (!ua->api || subprompt) { sock->signal(BNET_SUB_PROMPT); } for ( ;; ) { status = sock->recv(); if (status == BNET_SIGNAL) { continue; /* ignore signals */ } if (is_bnet_stop(sock)) { return 0; /* error or terminate */ } pm_strcpy(ua->cmd, sock->msg); strip_trailing_junk(ua->cmd); if (bstrcmp(ua->cmd, ".messages")) { qmessages_cmd(ua, ua->cmd); } /* Lone dot => break */ if (ua->cmd[0] == '.' && ua->cmd[1] == 0) { return 0; } break; } return 1; } /* * Get a positive integer * Returns: false if failure * true if success => value in ua->pint32_val */ bool get_pint(UAContext *ua, const char *prompt) { double dval; ua->pint32_val = 0; ua->int64_val = 0; for (;;) { ua->cmd[0] = 0; if (!get_cmd(ua, prompt)) { return false; } /* Kludge for slots blank line => 0 */ if (ua->cmd[0] == 0 && bstrncmp(prompt, _("Enter slot"), strlen(_("Enter slot")))) { return true; } if (!is_a_number(ua->cmd)) { ua->warning_msg(_("Expected a positive integer, got: %s\n"), ua->cmd); continue; } errno = 0; dval = strtod(ua->cmd, NULL); if (errno != 0 || dval < 0) { ua->warning_msg(_("Expected a positive integer, got: %s\n"), ua->cmd); continue; } ua->pint32_val = (uint32_t)dval; ua->int64_val = (int64_t)dval; return true; } } /* * Test a yes or no response * Returns: false if failure * true if success => ret == 1 for yes * ret == 0 for no */ bool is_yesno(char *val, int *ret) { *ret = 0; if (bstrcasecmp(val, _("yes")) || bstrcasecmp(val, NT_("yes"))) { *ret = 1; } else if (bstrcasecmp(val, _("no")) || bstrcasecmp(val, NT_("no"))) { *ret = 0; } else { return false; } return true; } /* * Gets a yes or no response * Returns: false if failure * true if success => ua->pint32_val == 1 for yes * ua->pint32_val == 0 for no */ bool get_yesno(UAContext *ua, const char *prompt) { int len; int ret; ua->pint32_val = 0; for (;;) { if (ua->api) ua->UA_sock->signal(BNET_YESNO); if (!get_cmd(ua, prompt)) { return false; } len = strlen(ua->cmd); if (len < 1 || len > 3) { continue; } if (is_yesno(ua->cmd, &ret)) { ua->pint32_val = ret; return true; } ua->warning_msg(_("Invalid response. You must answer yes or no.\n")); } } /* * Gets an Enabled value => 0, 1, 2, yes, no, archived * Returns: 0, 1, 2 if OK * -1 on error */ int get_enabled(UAContext *ua, const char *val) { int Enabled = -1; if (bstrcasecmp(val, "yes") || bstrcasecmp(val, "true")) { Enabled = VOL_ENABLED; } else if (bstrcasecmp(val, "no") || bstrcasecmp(val, "false")) { Enabled = VOL_NOT_ENABLED; } else if (bstrcasecmp(val, "archived")) { Enabled = VOL_ARCHIVED; } else { Enabled = atoi(val); } if (Enabled < 0 || Enabled > 2) { ua->error_msg(_("Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n")); return -1; } return Enabled; } void parse_ua_args(UAContext *ua) { parse_args(ua->cmd, &ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS); } /* * Check if the comment has legal characters * If ua is non-NULL send the message */ bool is_comment_legal(UAContext *ua, const char *name) { int len; const char *p; const char *forbid = "'<>&\\\""; /* Restrict the characters permitted in the comment */ for (p=name; *p; p++) { if (!strchr(forbid, (int)(*p))) { continue; } if (ua) { ua->error_msg(_("Illegal character \"%c\" in a comment.\n"), *p); } return 0; } len = strlen(name); if (len >= MAX_NAME_LENGTH) { if (ua) { ua->error_msg(_("Comment too long.\n")); } return 0; } if (len == 0) { if (ua) { ua->error_msg(_("Comment must be at least one character long.\n")); } return 0; } return 1; } bareos-Release-14.2.6/src/dird/ua_label.c000066400000000000000000000533221263011562700200660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Tape labeling commands * * Kern Sibbald, April MMIII */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ static void label_from_barcodes(UAContext *ua, int drive, bool label_encrypt); static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, POOL_DBR *pr, bool relabel, bool media_record_exists, int drive); static bool generate_new_encryption_key(UAContext *ua, MEDIA_DBR *mr); /* External functions */ extern DIRRES *director; /* * Check if this is a cleaning tape by comparing the Volume name * with the Cleaning Prefix. If they match, this is a cleaning * tape. */ static inline bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr) { bool retval; /* * Find Pool resource */ ua->jcr->res.pool = (POOLRES *)GetResWithName(R_POOL, pr->Name); if (!ua->jcr->res.pool) { ua->error_msg(_("Pool \"%s\" resource not found for volume \"%s\"!\n"), pr->Name, mr->VolumeName); return false; } retval = bstrncmp(mr->VolumeName, ua->jcr->res.pool->cleaning_prefix, strlen(ua->jcr->res.pool->cleaning_prefix)); Dmsg4(100, "CLNprefix=%s: Vol=%s: len=%d bstrncmp=%s\n", ua->jcr->res.pool->cleaning_prefix, mr->VolumeName, strlen(ua->jcr->res.pool->cleaning_prefix), retval ? "true" : "false"); return retval; } /* * Common routine for both label and relabel */ static int do_label(UAContext *ua, const char *cmd, bool relabel) { USTORERES store; BSOCK *sd; char dev_name[MAX_NAME_LENGTH]; MEDIA_DBR mr, omr; POOL_DBR pr; bool print_reminder = true; bool label_barcodes = false; bool label_encrypt = false; int ok = FALSE; int i, j; int drive; bool media_record_exists = false; static const char *barcode_keywords[] = { "barcode", "barcodes", NULL }; if (!open_client_db(ua)) { return 1; } memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); memset(&omr, 0, sizeof(omr)); /* * Look for one of the barcode keywords */ if (!relabel && (i = find_arg_keyword(ua, barcode_keywords)) >= 0) { /* * Now find the keyword in the list */ if ((j = find_arg(ua, barcode_keywords[i])) > 0) { *ua->argk[j] = 0; /* zap barcode keyword */ } label_barcodes = true; } /* * Look for the encrypt keyword */ if ((i = find_arg(ua, "encrypt")) > 0) { *ua->argk[i] = 0; /* zap encrypt keyword */ label_encrypt = true; } store.store = get_storage_resource(ua, true, label_barcodes); if (!store.store) { return 1; } switch (store.store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: /* * See if the user selected a NDMP storage device but its * handled by a native Bareos storage daemon e.g. we have * a paired_storage pointer. */ if (store.store->paired_storage) { store.store = store.store->paired_storage; } else { ua->warning_msg(_("Storage has non-native protocol.\n")); return 1; } break; default: break; } pm_strcpy(store.store_source, _("command line")); set_wstorage(ua->jcr, &store); drive = get_storage_drive(ua, store.store); if (label_barcodes) { label_from_barcodes(ua, drive, label_encrypt); return 1; } /* * If relabel get name of Volume to relabel */ if (relabel) { /* * Check for oldvolume=name */ i = find_arg_with_value(ua, "oldvolume"); if (i >= 0) { bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName)); if (db_get_media_record(ua->jcr, ua->db, &omr)) { goto checkVol; } ua->error_msg("%s", db_strerror(ua->db)); } /* * No keyword or Vol not found, ask user to select */ if (!select_media_dbr(ua, &omr)) { return 1; } /* * Require Volume to be Purged or Recycled */ checkVol: if (!bstrcmp(omr.VolStatus, "Purged") && !bstrcmp(omr.VolStatus, "Recycle")) { ua->error_msg(_("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"), omr.VolumeName, omr.VolStatus); return 1; } } /* * Check for volume=NewVolume */ i = find_arg_with_value(ua, "volume"); if (i >= 0) { pm_strcpy(ua->cmd, ua->argv[i]); goto checkName; } /* * Get a new Volume name */ for ( ;; ) { media_record_exists = false; if (!get_cmd(ua, _("Enter new Volume name: "))) { return 1; } checkName: if (!is_volume_name_legal(ua, ua->cmd)) { continue; } /* * Search by Media name so set VolumeName and clear MediaId. */ mr.MediaId = 0; bstrncpy(mr.VolumeName, ua->cmd, sizeof(mr.VolumeName)); /* * If VolBytes are zero the Volume is not labeled */ if (db_get_media_record(ua->jcr, ua->db, &mr)) { if (mr.VolBytes != 0) { ua->error_msg(_("Media record for new Volume \"%s\" already exists.\n"), mr.VolumeName); continue; } media_record_exists = true; } break; /* Got it */ } /* * If autochanger, request slot */ i = find_arg_with_value(ua, "slot"); if (i >= 0) { mr.Slot = atoi(ua->argv[i]); if (mr.Slot < 0) { mr.Slot = 0; } mr.InChanger = mr.Slot > 0; /* if slot give assume in changer */ } else if (store.store->autochanger) { if (!get_pint(ua, _("Enter slot (0 or Enter for none): "))) { return 1; } mr.Slot = ua->pint32_val; if (mr.Slot < 0) { mr.Slot = 0; } mr.InChanger = mr.Slot > 0; /* if slot give assume in changer */ } set_storageid_in_mr(store.store, &mr); bstrncpy(mr.MediaType, store.store->media_type, sizeof(mr.MediaType)); /* * Must select Pool if not already done */ if (pr.PoolId == 0) { memset(&pr, 0, sizeof(pr)); if (!select_pool_dbr(ua, &pr)) { return 1; } } /* * See if we need to generate a new passphrase for hardware encryption. */ if (label_encrypt) { ua->info_msg(_("Generating new hardware encryption key\n")); if (!generate_new_encryption_key(ua, &mr)) { return 1; } } ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists, drive); if (ok) { sd = ua->jcr->store_bsock; if (relabel) { /* * Delete the old media record */ if (!db_delete_media_record(ua->jcr, ua->db, &omr)) { ua->error_msg(_("Delete of Volume \"%s\" failed. ERR=%s"), omr.VolumeName, db_strerror(ua->db)); } else { ua->info_msg(_("Old volume \"%s\" deleted from catalog.\n"), omr.VolumeName); /* * Update the number of Volumes in the pool */ pr.NumVols--; if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); } } } if (ua->automount) { bstrncpy(dev_name, store.store->dev_name(), sizeof(dev_name)); ua->info_msg(_("Requesting to mount %s ...\n"), dev_name); bash_spaces(dev_name); sd->fsend("mount %s drive=%d", dev_name, drive); unbash_spaces(dev_name); /* * We use bget_dirmsg here and not bnet_recv because as part of * the mount request the stored can request catalog information for * any plugin who listens to the bsdEventLabelVerified event. * As we don't want to loose any non protocol data e.g. errors * without a 3xxx prefix we set the allow_any_message of * bget_dirmsg to true and as such is behaves like a normal * bnet_recv for any non protocol messages. */ while (bget_dirmsg(sd, true) >= 0) { ua->send_msg("%s", sd->msg); /* * Here we can get * 3001 OK mount. Device=xxx or * 3001 Mounted Volume vvvv * 3002 Device "DVD-Writer" (/dev/hdc) is mounted. * 3906 is cannot mount non-tape * So for those, no need to print a reminder */ if (bstrncmp(sd->msg, "3001 ", 5) || bstrncmp(sd->msg, "3002 ", 5) || bstrncmp(sd->msg, "3906 ", 5)) { print_reminder = false; } } } } if (print_reminder) { ua->info_msg(_("Do not forget to mount the drive!!!\n")); } close_sd_bsock(ua); return 1; } /* * Request SD to send us the slot:barcodes, then wiffle through them all labeling them. */ static void label_from_barcodes(UAContext *ua, int drive, bool label_encrypt) { STORERES *store = ua->jcr->res.wstore; POOL_DBR pr; MEDIA_DBR mr; vol_list_t *vl; dlist *vol_list = NULL; bool media_record_exists; char *slot_list; int max_slots; memset(&mr, 0, sizeof(mr)); max_slots = get_num_slots_from_SD(ua); if (max_slots <= 0) { ua->warning_msg(_("No slots in changer to scan.\n")); return; } slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, slot_list); if (!get_user_slot_list(ua, slot_list, "slots", max_slots)) { goto bail_out; } vol_list = get_vol_list_from_SD(ua, store, false /* no listall */ , false /*no scan*/); if (!vol_list) { ua->warning_msg(_("No Volumes found to label, or no barcodes.\n")); goto bail_out; } /* * Display list of Volumes and ask if he really wants to proceed */ ua->send_msg(_("The following Volumes will be labeled:\n" "Slot Volume\n" "==============\n")); foreach_dlist(vl, vol_list) { if (!vl->VolName || !bit_is_set(vl->Slot - 1, slot_list)) { continue; } ua->send_msg("%4d %s\n", vl->Slot, vl->VolName); } if (!get_yesno(ua, _("Do you want to label these Volumes? (yes|no): ")) || (ua->pint32_val == 0)) { goto bail_out; } /* * Select a pool */ memset(&pr, 0, sizeof(pr)); if (!select_pool_dbr(ua, &pr)) { goto bail_out; } /* * Fire off the label requests */ foreach_dlist(vl, vol_list) { if (!vl->VolName || !bit_is_set(vl->Slot - 1, slot_list)) { continue; } memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); media_record_exists = false; if (db_get_media_record(ua->jcr, ua->db, &mr)) { if (mr.VolBytes != 0) { ua->warning_msg(_("Media record for Slot %d Volume \"%s\" already exists.\n"), vl->Slot, mr.VolumeName); mr.Slot = vl->Slot; mr.InChanger = mr.Slot > 0; /* if slot give assume in changer */ set_storageid_in_mr(store, &mr); if (!db_update_media_record(ua->jcr, ua->db, &mr)) { ua->error_msg(_("Error setting InChanger: ERR=%s"), db_strerror(ua->db)); } continue; } media_record_exists = true; } mr.InChanger = mr.Slot > 0; /* if slot give assume in changer */ set_storageid_in_mr(store, &mr); /* * Deal with creating cleaning tape here. Normal tapes created in send_label_request() below */ if (is_cleaning_tape(ua, &mr, &pr)) { if (media_record_exists) { /* we update it */ mr.VolBytes = 1; /* any bytes to indicate it exists */ bstrncpy(mr.VolStatus, "Cleaning", sizeof(mr.VolStatus)); mr.MediaType[0] = 0; set_storageid_in_mr(store, &mr); if (!db_update_media_record(ua->jcr, ua->db, &mr)) { ua->error_msg("%s", db_strerror(ua->db)); } } else { /* create the media record */ if (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) { ua->error_msg(_("Maximum pool Volumes=%d reached.\n"), pr.MaxVols); goto bail_out; } set_pool_dbr_defaults_in_media_dbr(&mr, &pr); bstrncpy(mr.VolStatus, "Cleaning", sizeof(mr.VolStatus)); mr.MediaType[0] = 0; set_storageid_in_mr(store, &mr); if (db_create_media_record(ua->jcr, ua->db, &mr)) { ua->send_msg(_("Catalog record for cleaning tape \"%s\" successfully created.\n"), mr.VolumeName); pr.NumVols++; /* this is a bit suspect */ if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); } } else { ua->error_msg(_("Catalog error on cleaning tape: %s"), db_strerror(ua->db)); } } continue; /* done, go handle next volume */ } bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); /* * See if we need to generate a new passphrase for hardware encryption. */ if (label_encrypt) { if (!generate_new_encryption_key(ua, &mr)) { continue; } } mr.Slot = vl->Slot; send_label_request(ua, &mr, NULL, &pr, false, media_record_exists, drive); } bail_out: free(slot_list); if (vol_list) { free_vol_list(vol_list); } close_sd_bsock(ua); return; } /* * Label a tape * * label storage=xxx volume=vvv */ int label_cmd(UAContext *ua, const char *cmd) { return do_label(ua, cmd, false); /* standard label */ } int relabel_cmd(UAContext *ua, const char *cmd) { return do_label(ua, cmd, true); /* relabel tape */ } /* * Check if the Volume name has legal characters * If ua is non-NULL send the message */ bool is_volume_name_legal(UAContext *ua, const char *name) { int len; const char *p; const char *accept = ":.-_/"; if (name[0] == '/') { if (ua) { ua->error_msg(_("Volume name can not start with \"/\".\n")); } return 0; } /* * Restrict the characters permitted in the Volume name */ for (p=name; *p; p++) { if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) { continue; } if (ua) { ua->error_msg(_("Illegal character \"%c\" in a volume name.\n"), *p); } return 0; } len = strlen(name); if (len >= MAX_NAME_LENGTH) { if (ua) { ua->error_msg(_("Volume name too long.\n")); } return 0; } if (len == 0) { if (ua) { ua->error_msg(_("Volume name must be at least one character long.\n")); } return 0; } return 1; } /* * NOTE! This routine opens the SD socket but leaves it open */ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, POOL_DBR *pr, bool relabel, bool media_record_exists, int drive) { BSOCK *sd; char dev_name[MAX_NAME_LENGTH]; bool ok = false; uint64_t VolBytes = 0; if (!(sd=open_sd_bsock(ua))) { return false; } bstrncpy(dev_name, ua->jcr->res.wstore->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); bash_spaces(mr->VolumeName); bash_spaces(mr->MediaType); bash_spaces(pr->Name); if (relabel) { bash_spaces(omr->VolumeName); sd->fsend("relabel %s OldName=%s NewName=%s PoolName=%s " "MediaType=%s Slot=%d drive=%d MinBlocksize=%d MaxBlocksize=%d", dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot, drive, /* * if relabeling, keep blocksize settings */ omr->MinBlocksize, omr->MaxBlocksize); ua->send_msg(_("Sending relabel command from \"%s\" to \"%s\" ...\n"), omr->VolumeName, mr->VolumeName); } else { sd->fsend("label %s VolumeName=%s PoolName=%s MediaType=%s " "Slot=%d drive=%d MinBlocksize=%d MaxBlocksize=%d", dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot, drive, /* * If labeling, use blocksize defined in pool */ pr->MinBlocksize, pr->MaxBlocksize); ua->send_msg(_("Sending label command for Volume \"%s\" Slot %d ...\n"), mr->VolumeName, mr->Slot); Dmsg8(100, "label %s VolumeName=%s PoolName=%s MediaType=%s " "Slot=%d drive=%d MinBlocksize=%d MaxBlocksize=%d\n", dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot, drive, pr->MinBlocksize, pr->MaxBlocksize); } /* * We use bget_dirmsg here and not bnet_recv because as part of * the label request the stored can request catalog information for * any plugin who listens to the bsdEventLabelVerified event. * As we don't want to loose any non protocol data e.g. errors * without a 3xxx prefix we set the allow_any_message of * bget_dirmsg to true and as such is behaves like a normal * bnet_recv for any non protocol messages. */ while (bget_dirmsg(sd, true) >= 0) { ua->send_msg("%s", sd->msg); if (sscanf(sd->msg, "3000 OK label. VolBytes=%llu ", &VolBytes) == 1) { ok = true; } } unbash_spaces(mr->VolumeName); unbash_spaces(mr->MediaType); unbash_spaces(pr->Name); mr->LabelDate = time(NULL); mr->set_label_date = true; if (ok) { if (media_record_exists) { /* we update it */ mr->VolBytes = VolBytes; mr->InChanger = mr->Slot > 0; /* if slot give assume in changer */ set_storageid_in_mr(ua->jcr->res.wstore, mr); if (!db_update_media_record(ua->jcr, ua->db, mr)) { ua->error_msg("%s", db_strerror(ua->db)); ok = false; } } else { /* create the media record */ set_pool_dbr_defaults_in_media_dbr(mr, pr); mr->VolBytes = VolBytes; mr->InChanger = mr->Slot > 0; /* if slot give assume in changer */ mr->Enabled = VOL_ENABLED; set_storageid_in_mr(ua->jcr->res.wstore, mr); if (db_create_media_record(ua->jcr, ua->db, mr)) { ua->info_msg(_("Catalog record for Volume \"%s\", Slot %d successfully created.\n"), mr->VolumeName, mr->Slot); /* * Update number of volumes in pool */ pr->NumVols++; if (!db_update_pool_record(ua->jcr, ua->db, pr)) { ua->error_msg("%s", db_strerror(ua->db)); } } else { ua->error_msg("%s", db_strerror(ua->db)); ok = false; } } } else { ua->error_msg(_("Label command failed for Volume %s.\n"), mr->VolumeName); } return ok; } /* * Generate a new encryption key for use in volume encryption. * We don't ask the user for a encryption key but generate a semi * random passphrase of the wanted length which is way stronger. * When the config has a wrap key we use that to wrap the newly * created passphrase using RFC3394 aes wrap and always convert * the passphrase into a base64 encoded string. This key is * stored in the database and is passed to the storage daemon * when needed. The storage daemon has the same wrap key per * director so it can unwrap the passphrase for use. * * Changing the wrap key will render any previously created * crypto keys useless so only change the wrap key after initial * setting when you know what you are doing and always store * the old key somewhere save so you can use bscrypto to * convert them for the new wrap key. */ static bool generate_new_encryption_key(UAContext *ua, MEDIA_DBR *mr) { int length; char *passphrase; passphrase = generate_crypto_passphrase(DEFAULT_PASSPHRASE_LENGTH); if (!passphrase) { ua->error_msg(_("Failed to generate new encryption passphrase for Volume %s.\n"), mr->VolumeName); return false; } /* * See if we need to wrap the passphrase. */ if (me->keyencrkey.value) { char *wrapped_passphrase; length = DEFAULT_PASSPHRASE_LENGTH + 8; wrapped_passphrase = (char *)malloc(length); memset(wrapped_passphrase, 0, length); aes_wrap((unsigned char *)me->keyencrkey.value, DEFAULT_PASSPHRASE_LENGTH / 8, (unsigned char *)passphrase, (unsigned char *)wrapped_passphrase); free(passphrase); passphrase = wrapped_passphrase; } else { length = DEFAULT_PASSPHRASE_LENGTH; } /* * The passphrase is always base64 encoded. */ bin_to_base64(mr->EncrKey, sizeof(mr->EncrKey), passphrase, length, true); free(passphrase); return true; } bareos-Release-14.2.6/src/dird/ua_output.c000066400000000000000000000752341263011562700203550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Output Commands * * I.e. messages, listing database, showing resources, ... * * Kern Sibbald, September MM */ #include "bareos.h" #include "dird.h" /* Imported subroutines */ /* Imported variables */ /* Imported functions */ /* Forward referenced functions */ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist); static bool list_nextvol(UAContext *ua, int ndays); /* * Turn auto display of console messages on/off */ int autodisplay_cmd(UAContext *ua, const char *cmd) { static const char *kw[] = { NT_("on"), NT_("off"), NULL }; switch (find_arg_keyword(ua, kw)) { case 0: ua->auto_display_messages = true; break; case 1: ua->auto_display_messages = false; break; default: ua->error_msg(_("ON or OFF keyword missing.\n")); break; } return 1; } /* * Turn GUI mode on/off */ int gui_cmd(UAContext *ua, const char *cmd) { static const char *kw[] = { NT_("on"), NT_("off"), NULL }; switch (find_arg_keyword(ua, kw)) { case 0: ua->jcr->gui = ua->gui = true; break; case 1: ua->jcr->gui = ua->gui = false; break; default: ua->error_msg(_("ON or OFF keyword missing.\n")); break; } return 1; } /* * Enter with Resources locked */ static void show_disabled_jobs(UAContext *ua) { JOBRES *job; bool first = true; foreach_res(job, R_JOB) { if (!acl_access_ok(ua, Job_ACL, job->name())) { continue; } if (!job->enabled) { if (first) { first = false; ua->send_msg(_("Disabled Jobs:\n")); } ua->send_msg(" %s\n", job->name()); } } if (first) { ua->send_msg(_("No disabled Jobs.\n")); } } /* * Enter with Resources locked */ static void show_disabled_clients(UAContext *ua) { CLIENTRES *client; bool first = true; foreach_res(client, R_CLIENT) { if (!acl_access_ok(ua, Client_ACL, client->name())) { continue; } if (!client->enabled) { if (first) { first = false; ua->send_msg(_("Disabled Clients:\n")); } ua->send_msg(" %s\n", client->name()); } } if (first) { ua->send_msg(_("No disabled Clients.\n")); } } /* * Enter with Resources locked */ static void show_disabled_schedules(UAContext *ua) { SCHEDRES *sched; bool first = true; foreach_res(sched, R_SCHEDULE) { if (!acl_access_ok(ua, Schedule_ACL, sched->name())) { continue; } if (!sched->enabled) { if (first) { first = false; ua->send_msg(_("Disabled Scedules:\n")); } ua->send_msg(" %s\n", sched->name()); } } if (first) { ua->send_msg(_("No disabled Schedules.\n")); } } struct showstruct { const char *res_name; int type; }; static struct showstruct avail_resources[] = { { NT_("directors"), R_DIRECTOR }, { NT_("clients"), R_CLIENT }, { NT_("counters"), R_COUNTER }, { NT_("devices"), R_DEVICE }, { NT_("jobs"), R_JOB }, { NT_("jobdefs"), R_JOBDEFS }, { NT_("storages"), R_STORAGE }, { NT_("catalogs"), R_CATALOG }, { NT_("schedules"), R_SCHEDULE }, { NT_("filesets"), R_FILESET }, { NT_("pools"), R_POOL }, { NT_("messages"), R_MSGS }, { NT_("profiles"), R_PROFILE }, { NT_("consoles"), R_CONSOLE }, { NT_("all"), -1 }, { NT_("help"), -2 }, { NULL, 0 } }; /* * Displays Resources * * show all * show - e.g. show directors * show = - e.g. show director=HeadMan * show disabled - shows disabled jobs, clients and schedules * show disabled jobs - shows disabled jobs * show disabled clients - shows disabled clients * show disabled schedules - shows disabled schedules */ int show_cmd(UAContext *ua, const char *cmd) { int i, j, type, len; int recurse; char *res_name; RES *res = NULL; bool hide_sensitive_data; Dmsg1(20, "show: %s\n", ua->UA_sock->msg); /* * When the console has no access to the configure cmd then any show cmd * will suppress all sensitive information like for instance passwords. */ hide_sensitive_data = !acl_access_ok(ua, Command_ACL, "configure", false); LockRes(); for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], _("disabled"))) { if (((i + 1) < ua->argc) && bstrcasecmp(ua->argk[i + 1], NT_("jobs"))) { show_disabled_jobs(ua); } else if (((i + 1) < ua->argc) && bstrcasecmp(ua->argk[i + 1], NT_("clients"))) { show_disabled_clients(ua); } else if (((i + 1) < ua->argc) && bstrcasecmp(ua->argk[i + 1], NT_("schedules"))) { show_disabled_schedules(ua); } else { show_disabled_jobs(ua); show_disabled_clients(ua); show_disabled_schedules(ua); } goto bail_out; } type = 0; res_name = ua->argk[i]; if (!ua->argv[i]) { /* was a name given? */ /* * No name, dump all resources of specified type */ recurse = 1; len = strlen(res_name); for (j = 0; avail_resources[j].res_name; j++) { if (bstrncasecmp(res_name, _(avail_resources[j].res_name), len)) { type = avail_resources[j].type; if (type > 0) { res = my_config->m_res_head[type - my_config->m_r_first]; } else { res = NULL; } break; } } } else { /* * Dump a single resource with specified name */ recurse = 0; len = strlen(res_name); for (j = 0; avail_resources[j].res_name; j++) { if (bstrncasecmp(res_name, _(avail_resources[j].res_name), len)) { type = avail_resources[j].type; res = (RES *)GetResWithName(type, ua->argv[i]); if (!res) { type = -3; } break; } } } switch (type) { case -1: /* all */ for (j = my_config->m_r_first; j <= my_config->m_r_last; j++) { switch (j) { case R_DEVICE: /* * Skip R_DEVICE since it is really not used or updated */ continue; default: if (my_config->m_res_head[j - my_config->m_r_first]) { dump_resource(j, my_config->m_res_head[j - my_config->m_r_first], bsendmsg, ua, hide_sensitive_data); } break; } } break; case -2: ua->send_msg(_("Keywords for the show command are:\n")); for (j = 0; avail_resources[j].res_name; j++) { ua->error_msg("%s\n", _(avail_resources[j].res_name)); } goto bail_out; case -3: ua->error_msg(_("%s resource %s not found.\n"), res_name, ua->argv[i]); goto bail_out; case 0: ua->error_msg(_("Resource %s not found\n"), res_name); goto bail_out; default: dump_resource(recurse ? type : -type, res, bsendmsg, ua, hide_sensitive_data); break; } } bail_out: UnlockRes(); return 1; } /* * List contents of database * * list jobs - lists all jobs run * list jobid=nnn - list job data for jobid * list ujobid=uname - list job data for unique jobid * list job=name - list all jobs with "name" * list jobname=name - same as above * list jobmedia jobid=nnn * list jobmedia ujobid=uname * list joblog jobid= * list joblog job=name * list basefiles jobid=nnn - list files saved for job nn * list basefiles ujobid=uname * list files jobid= - list files saved for job nn * list files ujobid=name * list pools - list pool records * list jobtotals - list totals for all jobs * list media - list media for given pool (deprecated) * list volumes - list Volumes * list clients - list clients * list nextvol job=xx - list the next vol to be used by job * list nextvolume job=xx - same as above. * list copies jobid=x,y,z */ /* Do long or full listing */ int llist_cmd(UAContext *ua, const char *cmd) { return do_list_cmd(ua, cmd, VERT_LIST); } /* Do short or summary listing */ int list_cmd(UAContext *ua, const char *cmd) { return do_list_cmd(ua, cmd, HORZ_LIST); } static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist) { POOLMEM *VolumeName; int jobid, n; int i, j; JOB_DBR jr; POOL_DBR pr; MEDIA_DBR mr; if (!open_client_db(ua, true)) { return 1; } memset(&jr, 0, sizeof(jr)); memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); Dmsg1(20, "list: %s\n", cmd); if (!ua->db) { ua->error_msg(_("Hey! DB is NULL\n")); } /* Apply any limit */ j = find_arg_with_value(ua, NT_("limit")); if (j >= 0) { jr.limit = atoi(ua->argv[j]); } /* Scan arguments looking for things to do */ for (i = 1; i < ua->argc; i++) { /* List JOBS */ if (bstrcasecmp(ua->argk[i], NT_("jobs"))) { db_list_job_records(ua->jcr, ua->db, &jr, printit, ua, llist); /* List JOBTOTALS */ } else if (bstrcasecmp(ua->argk[i], NT_("jobtotals"))) { db_list_job_totals(ua->jcr, ua->db, &jr, printit, ua); /* List JOBID=nn */ } else if (bstrcasecmp(ua->argk[i], NT_("jobid"))) { if (ua->argv[i]) { jobid = str_to_int64(ua->argv[i]); if (jobid > 0) { jr.JobId = jobid; db_list_job_records(ua->jcr, ua->db, &jr, printit, ua, llist); } } /* List JOB=xxx */ } else if ((bstrcasecmp(ua->argk[i], NT_("job")) || bstrcasecmp(ua->argk[i], NT_("jobname"))) && ua->argv[i]) { bstrncpy(jr.Name, ua->argv[i], MAX_NAME_LENGTH); jr.JobId = 0; db_list_job_records(ua->jcr, ua->db, &jr, printit, ua, llist); /* List UJOBID=xxx */ } else if (bstrcasecmp(ua->argk[i], NT_("ujobid")) && ua->argv[i]) { bstrncpy(jr.Job, ua->argv[i], MAX_NAME_LENGTH); jr.JobId = 0; db_list_job_records(ua->jcr, ua->db, &jr, printit, ua, llist); /* List Base files */ } else if (bstrcasecmp(ua->argk[i], NT_("basefiles"))) { for (j=i+1; jargc; j++) { if (bstrcasecmp(ua->argk[j], NT_("ujobid")) && ua->argv[j]) { bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH); jr.JobId = 0; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { continue; } jobid = jr.JobId; } else if (bstrcasecmp(ua->argk[j], NT_("jobid")) && ua->argv[j]) { jobid = str_to_int64(ua->argv[j]); } else { continue; } if (jobid > 0) { db_list_base_files_for_job(ua->jcr, ua->db, jobid, printit, ua); } } /* List FILES */ } else if (bstrcasecmp(ua->argk[i], NT_("files"))) { for (j=i+1; jargc; j++) { if (bstrcasecmp(ua->argk[j], NT_("ujobid")) && ua->argv[j]) { bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH); jr.JobId = 0; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { continue; } jobid = jr.JobId; } else if (bstrcasecmp(ua->argk[j], NT_("jobid")) && ua->argv[j]) { jobid = str_to_int64(ua->argv[j]); } else { continue; } if (jobid > 0) { db_list_files_for_job(ua->jcr, ua->db, jobid, printit, ua); } } /* List JOBMEDIA */ } else if (bstrcasecmp(ua->argk[i], NT_("jobmedia"))) { bool done = false; for (j=i+1; jargc; j++) { if (bstrcasecmp(ua->argk[j], NT_("ujobid")) && ua->argv[j]) { bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH); jr.JobId = 0; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { continue; } jobid = jr.JobId; } else if (bstrcasecmp(ua->argk[j], NT_("jobid")) && ua->argv[j]) { jobid = str_to_int64(ua->argv[j]); } else { continue; } db_list_jobmedia_records(ua->jcr, ua->db, jobid, printit, ua, llist); done = true; } if (!done) { /* List for all jobs (jobid=0) */ db_list_jobmedia_records(ua->jcr, ua->db, 0, printit, ua, llist); } /* List JOBLOG */ } else if (bstrcasecmp(ua->argk[i], NT_("joblog"))) { bool done = false; for (j=i+1; jargc; j++) { if (bstrcasecmp(ua->argk[j], NT_("ujobid")) && ua->argv[j]) { bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH); jr.JobId = 0; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { continue; } jobid = jr.JobId; } else if (bstrcasecmp(ua->argk[j], NT_("jobid")) && ua->argv[j]) { jobid = str_to_int64(ua->argv[j]); } else { continue; } db_list_joblog_records(ua->jcr, ua->db, jobid, printit, ua, llist); done = true; } if (!done) { /* List for all jobs (jobid=0) */ db_list_joblog_records(ua->jcr, ua->db, 0, printit, ua, llist); } /* List POOLS */ } else if (bstrcasecmp(ua->argk[i], NT_("pool")) || bstrcasecmp(ua->argk[i], NT_("pools"))) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); if (ua->argv[i]) { bstrncpy(pr.Name, ua->argv[i], sizeof(pr.Name)); } db_list_pool_records(ua->jcr, ua->db, &pr, printit, ua, llist); } else if (bstrcasecmp(ua->argk[i], NT_("clients"))) { db_list_client_records(ua->jcr, ua->db, printit, ua, llist); /* List MEDIA or VOLUMES */ } else if (bstrcasecmp(ua->argk[i], NT_("media")) || bstrcasecmp(ua->argk[i], NT_("volume")) || bstrcasecmp(ua->argk[i], NT_("volumes"))) { bool done = false; for (j=i+1; jargc; j++) { if (bstrcasecmp(ua->argk[j], NT_("ujobid")) && ua->argv[j]) { bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH); jr.JobId = 0; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { continue; } jobid = jr.JobId; } else if (bstrcasecmp(ua->argk[j], NT_("jobid")) && ua->argv[j]) { jobid = str_to_int64(ua->argv[j]); } else { continue; } VolumeName = get_pool_memory(PM_FNAME); n = db_get_job_volume_names(ua->jcr, ua->db, jobid, &VolumeName); ua->send_msg(_("Jobid %d used %d Volume(s): %s\n"), jobid, n, VolumeName); free_pool_memory(VolumeName); done = true; } /* if no job or jobid keyword found, then we list all media */ if (!done) { int num_pools; uint32_t *ids; /* List a specific volume? */ if (ua->argv[i]) { bstrncpy(mr.VolumeName, ua->argv[i], sizeof(mr.VolumeName)); db_list_media_records(ua->jcr, ua->db, &mr, printit, ua, llist); return 1; } /* Is a specific pool wanted? */ for (i=1; iargc; i++) { if (bstrcasecmp(ua->argk[i], NT_("pool"))) { if (!get_pool_dbr(ua, &pr)) { ua->error_msg(_("No Pool specified.\n")); return 1; } mr.PoolId = pr.PoolId; db_list_media_records(ua->jcr, ua->db, &mr, printit, ua, llist); return 1; } } /* List Volumes in all pools */ if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) { ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db)); return 1; } if (num_pools <= 0) { return 1; } for (i=0; i < num_pools; i++) { pr.PoolId = ids[i]; if (db_get_pool_record(ua->jcr, ua->db, &pr)) { ua->send_msg(_("Pool: %s\n"), pr.Name); } mr.PoolId = ids[i]; db_list_media_records(ua->jcr, ua->db, &mr, printit, ua, llist); } free(ids); return 1; } /* List next volume */ } else if (bstrcasecmp(ua->argk[i], NT_("nextvol")) || bstrcasecmp(ua->argk[i], NT_("nextvolume"))) { n = 1; j = find_arg_with_value(ua, NT_("days")); if (j >= 0) { n = atoi(ua->argv[j]); if ((n < 0) || (n > 50)) { ua->warning_msg(_("Ignoring invalid value for days. Max is 50.\n")); n = 1; } } list_nextvol(ua, n); } else if (bstrcasecmp(ua->argk[i], NT_("copies"))) { char *jobids = NULL; uint32_t limit=0; for (j=i+1; jargc; j++) { if (bstrcasecmp(ua->argk[j], NT_("jobid")) && ua->argv[j]) { if (is_a_number_list(ua->argv[j])) { jobids = ua->argv[j]; } } else if (bstrcasecmp(ua->argk[j], NT_("limit")) && ua->argv[j]) { limit = atoi(ua->argv[j]); } } db_list_copies_records(ua->jcr,ua->db,limit,jobids,printit,ua,llist); } else if (bstrcasecmp(ua->argk[i], NT_("limit")) || bstrcasecmp(ua->argk[i], NT_("days"))) { /* Ignore it */ } else { ua->error_msg(_("Unknown list keyword: %s\n"), NPRT(ua->argk[i])); } } return 1; } static bool list_nextvol(UAContext *ua, int ndays) { int i; JOBRES *job; JCR *jcr; USTORERES store; RUNRES *run; utime_t runtime; bool found = false; MEDIA_DBR mr; POOL_DBR pr; memset(&mr, 0, sizeof(mr)); i = find_arg_with_value(ua, "job"); if (i <= 0) { if ((job = select_job_resource(ua)) == NULL) { return false; } } else { job = (JOBRES *)GetResWithName(R_JOB, ua->argv[i]); if (!job) { Jmsg(ua->jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]); if ((job = select_job_resource(ua)) == NULL) { return false; } } } jcr = new_jcr(sizeof(JCR), dird_free_jcr); for (run=NULL; (run = find_next_run(run, job, runtime, ndays)); ) { if (!complete_jcr_for_job(jcr, job, run->pool)) { found = false; goto get_out; } if (!jcr->jr.PoolId) { ua->error_msg(_("Could not find Pool for Job %s\n"), job->name()); continue; } memset(&pr, 0, sizeof(pr)); pr.PoolId = jcr->jr.PoolId; if (!db_get_pool_record(jcr, jcr->db, &pr)) { bstrncpy(pr.Name, "*UnknownPool*", sizeof(pr.Name)); } mr.PoolId = jcr->jr.PoolId; get_job_storage(&store, job, run); set_storageid_in_mr(store.store, &mr); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune)) { ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).\n"), job->name(), pr.Name, level_to_str(run->level)); } else { ua->send_msg( _("The next Volume to be used by Job \"%s\" (Pool=%s, Level=%s) will be %s\n"), job->name(), pr.Name, level_to_str(run->level), mr.VolumeName); found = true; } } get_out: if (jcr->db) { db_sql_close_pooled_connection(jcr, jcr->db); jcr->db = NULL; } free_jcr(jcr); if (!found) { ua->error_msg(_("Could not find next Volume for Job %s.\n"), job->hdr.name); return false; } return true; } /* * For a given job, we examine all his run records * to see if it is scheduled today or tomorrow. */ RUNRES *find_next_run(RUNRES *run, JOBRES *job, utime_t &runtime, int ndays) { time_t now, future, endtime; SCHEDRES *sched; struct tm tm, runtm; int mday, wday, month, wom, i; int woy; int day; int is_scheduled; sched = job->schedule; if (sched == NULL) { /* scheduled? */ return NULL; /* no nothing to report */ } /* Break down the time into components */ now = time(NULL); endtime = now + (ndays * 60 * 60 * 24); if (run == NULL) { run = sched->run; } else { run = run->next; } for ( ; run; run=run->next) { /* * Find runs in next 24 hours. Day 0 is today, so if * ndays=1, look at today and tomorrow. */ for (day = 0; day <= ndays; day++) { future = now + (day * 60 * 60 * 24); /* Break down the time into components */ blocaltime(&future, &tm); mday = tm.tm_mday - 1; wday = tm.tm_wday; month = tm.tm_mon; wom = mday / 7; woy = tm_woy(future); is_scheduled = bit_is_set(mday, run->mday) && bit_is_set(wday, run->wday) && bit_is_set(month, run->month) && bit_is_set(wom, run->wom) && bit_is_set(woy, run->woy); #ifdef xxx Pmsg2(000, "day=%d is_scheduled=%d\n", day, is_scheduled); Pmsg1(000, "bit_set_mday=%d\n", bit_is_set(mday, run->mday)); Pmsg1(000, "bit_set_wday=%d\n", bit_is_set(wday, run->wday)); Pmsg1(000, "bit_set_month=%d\n", bit_is_set(month, run->month)); Pmsg1(000, "bit_set_wom=%d\n", bit_is_set(wom, run->wom)); Pmsg1(000, "bit_set_woy=%d\n", bit_is_set(woy, run->woy)); #endif if (is_scheduled) { /* Jobs scheduled on that day */ #ifdef xxx char buf[300], num[10]; bsnprintf(buf, sizeof(buf), "tm.hour=%d hour=", tm.tm_hour); for (i=0; i<24; i++) { if (bit_is_set(i, run->hour)) { bsnprintf(num, sizeof(num), "%d ", i); bstrncat(buf, num, sizeof(buf)); } } bstrncat(buf, "\n", sizeof(buf)); Pmsg1(000, "%s", buf); #endif /* find time (time_t) job is to be run */ blocaltime(&future, &runtm); for (i= 0; i < 24; i++) { if (bit_is_set(i, run->hour)) { runtm.tm_hour = i; runtm.tm_min = run->minute; runtm.tm_sec = 0; runtime = mktime(&runtm); Dmsg2(200, "now=%d runtime=%lld\n", now, runtime); if ((runtime > now) && (runtime < endtime)) { Dmsg2(200, "Found it level=%d %c\n", run->level, run->level); return run; /* found it, return run resource */ } } } } } } /* end for loop over runs */ /* Nothing found */ return NULL; } /* * Fill in the remaining fields of the jcr as if it * is going to run the job. */ bool complete_jcr_for_job(JCR *jcr, JOBRES *job, POOLRES *pool) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); set_jcr_defaults(jcr, job); if (pool) { jcr->res.pool = pool; /* override */ } if (jcr->db) { Dmsg0(100, "complete_jcr close db\n"); db_sql_close_pooled_connection(jcr, jcr->db); jcr->db = NULL; } Dmsg0(100, "complete_jcr open db\n"); jcr->db = db_sql_get_pooled_connection(jcr, jcr->res.catalog->db_driver, jcr->res.catalog->db_name, jcr->res.catalog->db_user, jcr->res.catalog->db_password.value, jcr->res.catalog->db_address, jcr->res.catalog->db_port, jcr->res.catalog->db_socket, jcr->res.catalog->mult_db_connections, jcr->res.catalog->disable_batch_insert); if (jcr->db == NULL) { Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"), jcr->res.catalog->db_name); return false; } bstrncpy(pr.Name, jcr->res.pool->name(), sizeof(pr.Name)); while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */ /* Try to create the pool */ if (create_pool(jcr, jcr->db, jcr->res.pool, POOL_OP_CREATE) < 0) { Jmsg(jcr, M_FATAL, 0, _("Pool %s not in database. %s"), pr.Name, db_strerror(jcr->db)); if (jcr->db) { db_sql_close_pooled_connection(jcr, jcr->db); jcr->db = NULL; } return false; } else { Jmsg(jcr, M_INFO, 0, _("Pool %s created in database.\n"), pr.Name); } } jcr->jr.PoolId = pr.PoolId; return true; } static void con_lock_release(void *arg) { Vw(con_lock); } void do_messages(UAContext *ua, const char *cmd) { char msg[2000]; int mlen; bool do_truncate = false; /* * Flush any queued messages. */ if (ua->jcr) { dequeue_messages(ua->jcr); } Pw(con_lock); pthread_cleanup_push(con_lock_release, (void *)NULL); rewind(con_fd); while (fgets(msg, sizeof(msg), con_fd)) { mlen = strlen(msg); ua->UA_sock->msg = check_pool_memory_size(ua->UA_sock->msg, mlen+1); strcpy(ua->UA_sock->msg, msg); ua->UA_sock->msglen = mlen; ua->UA_sock->send(); do_truncate = true; } if (do_truncate) { (void)ftruncate(fileno(con_fd), 0L); } console_msg_pending = FALSE; ua->user_notified_msg_pending = FALSE; pthread_cleanup_pop(0); Vw(con_lock); } int qmessages_cmd(UAContext *ua, const char *cmd) { if (console_msg_pending && ua->auto_display_messages) { do_messages(ua, cmd); } return 1; } int messages_cmd(UAContext *ua, const char *cmd) { if (console_msg_pending) { do_messages(ua, cmd); } else { ua->UA_sock->fsend(_("You have no messages.\n")); } return 1; } /* * Callback routine for "printing" database file listing */ void printit(void *ctx, const char *msg) { UAContext *ua = (UAContext *)ctx; if (ua) { ua->send_msg("%s", msg); } } /* * Format message and send to other end. * * If the UA_sock is NULL, it means that there is no user * agent, so we are being called from BAREOS core. In * that case direct the messages to the Job. */ #ifdef HAVE_VA_COPY void bmsg(UAContext *ua, const char *fmt, va_list arg_ptr) { BSOCK *bs = ua->UA_sock; int maxlen, len; POOLMEM *msg = NULL; va_list ap; if (bs) { msg = bs->msg; } if (!msg) { msg = get_pool_memory(PM_EMSG); } again: maxlen = sizeof_pool_memory(msg) - 1; va_copy(ap, arg_ptr); len = bvsnprintf(msg, maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= maxlen) { msg = realloc_pool_memory(msg, maxlen + maxlen/2); goto again; } if (bs) { bs->msg = msg; bs->msglen = len; bs->send(); } else { /* No UA, send to Job */ Jmsg(ua->jcr, M_INFO, 0, "%s", msg); free_pool_memory(msg); } } #else /* no va_copy() -- brain damaged version of variable arguments */ void bmsg(UAContext *ua, const char *fmt, va_list arg_ptr) { BSOCK *bs = ua->UA_sock; int maxlen, len; POOLMEM *msg = NULL; if (bs) { msg = bs->msg; } if (!msg) { msg = get_memory(5000); } maxlen = sizeof_pool_memory(msg) - 1; if (maxlen < 4999) { msg = realloc_pool_memory(msg, 5000); maxlen = 4999; } len = bvsnprintf(msg, maxlen, fmt, arg_ptr); if (len < 0 || len >= maxlen) { pm_strcpy(msg, _("Message too long to display.\n")); len = strlen(msg); } if (bs) { bs->msg = msg; bs->msglen = len; bs->send(); } else { /* No UA, send to Job */ Jmsg(ua->jcr, M_INFO, 0, "%s", msg); free_pool_memory(msg); } } #endif void bsendmsg(void *ctx, const char *fmt, ...) { va_list arg_ptr; va_start(arg_ptr, fmt); bmsg((UAContext *)ctx, fmt, arg_ptr); va_end(arg_ptr); } /* * The following UA methods are mainly intended for GUI * programs */ /* * This is a message that should be displayed on the user's * console. */ void UAContext::send_msg(const char *fmt, ...) { va_list arg_ptr; va_start(arg_ptr, fmt); bmsg(this, fmt, arg_ptr); va_end(arg_ptr); } /* * This is an error condition with a command. The gui should put * up an error or critical dialog box. The command is aborted. */ void UAContext::error_msg(const char *fmt, ...) { BSOCK *bs = UA_sock; va_list arg_ptr; if (bs && api) bs->signal(BNET_ERROR_MSG); va_start(arg_ptr, fmt); bmsg(this, fmt, arg_ptr); va_end(arg_ptr); } /* * This is a warning message, that should bring up a warning * dialog box on the GUI. The command is not aborted, but something * went wrong. */ void UAContext::warning_msg(const char *fmt, ...) { BSOCK *bs = UA_sock; va_list arg_ptr; if (bs && api) bs->signal(BNET_WARNING_MSG); va_start(arg_ptr, fmt); bmsg(this, fmt, arg_ptr); va_end(arg_ptr); } /* * This is an information message that should probably be put * into the status line of a GUI program. */ void UAContext::info_msg(const char *fmt, ...) { BSOCK *bs = UA_sock; va_list arg_ptr; if (bs && api) bs->signal(BNET_INFO_MSG); va_start(arg_ptr, fmt); bmsg(this, fmt, arg_ptr); va_end(arg_ptr); } bareos-Release-14.2.6/src/dird/ua_prune.c000066400000000000000000000652261263011562700201460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Database prune Command * * Applies retention periods * * Kern Sibbald, February MMII */ #include "bareos.h" #include "dird.h" /* Imported variables */ extern struct s_jt jobtypes[]; /* Imported functions */ /* Forward referenced functions */ static bool prune_directory(UAContext *ua, CLIENTRES *client); static bool prune_stats(UAContext *ua, utime_t retention); static bool grow_del_list(struct del_ctx *del); /* * Called here to count entries to be deleted */ int del_count_handler(void *ctx, int num_fields, char **row) { struct s_count_ctx *cnt = (struct s_count_ctx *)ctx; if (row[0]) { cnt->count = str_to_int64(row[0]); } else { cnt->count = 0; } return 0; } /* * Called here to make in memory list of JobIds to be * deleted and the associated PurgedFiles flag. * The in memory list will then be transversed * to issue the SQL DELETE commands. Note, the list * is allowed to get to MAX_DEL_LIST_LEN to limit the * maximum malloc'ed memory. */ int job_delete_handler(void *ctx, int num_fields, char **row) { struct del_ctx *del = (struct del_ctx *)ctx; if (!grow_del_list(del)) { return 1; } del->JobId[del->num_ids] = (JobId_t)str_to_int64(row[0]); Dmsg2(60, "job_delete_handler row=%d val=%d\n", del->num_ids, del->JobId[del->num_ids]); del->PurgedFiles[del->num_ids++] = (char)str_to_int64(row[1]); return 0; } int file_delete_handler(void *ctx, int num_fields, char **row) { struct del_ctx *del = (struct del_ctx *)ctx; if (!grow_del_list(del)) { return 1; } del->JobId[del->num_ids++] = (JobId_t)str_to_int64(row[0]); // Dmsg2(150, "row=%d val=%d\n", del->num_ids-1, del->JobId[del->num_ids-1]); return 0; } /* * Prune records from database * * prune files client=xxx [pool=yyy] * prune jobs client=xxx [pool=yyy] * prune volume=xxx * prune stats * prune directory=xxx [client=xxx] [recursive] */ int prune_cmd(UAContext *ua, const char *cmd) { CLIENTRES *client; POOLRES *pool; POOL_DBR pr; MEDIA_DBR mr; utime_t retention; int kw; static const char *keywords[] = { NT_("Files"), NT_("Jobs"), NT_("Volume"), NT_("Stats"), NT_("Directory"), NULL }; if (!open_client_db(ua, true)) { return false; } memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); /* * First search args */ kw = find_arg_keyword(ua, keywords); if (kw < 0 || kw > 4) { /* * No args, so ask user */ kw = do_keyword_prompt(ua, _("Choose item to prune"), keywords); } switch (kw) { case 0: /* prune files */ if (!(client = get_client_resource(ua))) { return false; } if (find_arg_with_value(ua, NT_("pool")) >= 0) { pool = get_pool_resource(ua); } else { pool = NULL; } /* * Pool File Retention takes precedence over client File Retention */ if (pool && pool->FileRetention > 0) { if (!confirm_retention(ua, &pool->FileRetention, "File")) { return false; } } else if (!confirm_retention(ua, &client->FileRetention, "File")) { return false; } prune_files(ua, client, pool); return true; case 1: { /* prune jobs */ int i; char jobtype[MAX_NAME_LENGTH]; if (!(client = get_client_resource(ua))) { return false; } if (find_arg_with_value(ua, NT_("pool")) >= 0) { pool = get_pool_resource(ua); } else { pool = NULL; } /* * Ask what jobtype to prune. */ if ((i = find_arg_with_value(ua, NT_("jobtype"))) >= 0) { bstrncpy(jobtype, ua->argv[i], sizeof(jobtype)); } else { start_prompt(ua, _("Jobtype to prune:\n")); for (i = 0; jobtypes[i].type_name; i++) { add_prompt(ua, jobtypes[i].type_name); } if (do_prompt(ua, _("JobType"), _("Select Job Type"), jobtype, sizeof(jobtype)) < 0) { return true; } } for (i = 0; jobtypes[i].type_name; i++) { if (bstrcasecmp(jobtypes[i].type_name, jobtype)) { break; } } if (!jobtypes[i].type_name) { ua->warning_msg(_("Illegal jobtype %s.\n"), jobtype); return false; } /* * Pool Job Retention takes precedence over client Job Retention */ if (pool && pool->JobRetention > 0) { if (!confirm_retention(ua, &pool->JobRetention, "Job")) { return false; } } else if (!confirm_retention(ua, &client->JobRetention, "Job")) { return false; } if (jobtypes[i].type_name) { return prune_jobs(ua, client, pool, jobtypes[i].job_type); } return false; } case 2: /* prune volume */ if (!select_pool_and_media_dbr(ua, &pr, &mr)) { return false; } if (mr.Enabled == VOL_ARCHIVED) { ua->error_msg(_("Cannot prune Volume \"%s\" because it is archived.\n"), mr.VolumeName); return false; } if (!confirm_retention(ua, &mr.VolRetention, "Volume")) { return false; } return prune_volume(ua, &mr); case 3: /* prune stats */ if (!me->stats_retention) { return false; } retention = me->stats_retention; if (!confirm_retention(ua, &retention, "Statistics")) { return false; } return prune_stats(ua, retention); case 4: /* prune directory */ if (find_arg_with_value(ua, NT_("client")) >= 0) { if (!(client = get_client_resource(ua))) { return false; } } else { client = NULL; } return prune_directory(ua, client); default: break; } return true; } /* * Prune Directory meta data records from the database. */ static bool prune_directory(UAContext *ua, CLIENTRES *client) { int i, len; CLIENT_DBR cr; char *prune_topdir = NULL; POOL_MEM query(PM_MESSAGE), temp(PM_MESSAGE); bool recursive = false; bool retval = false; /* * See if a client was selected. */ if (!client) { if (!get_yesno(ua, _("No client restriction given really remove " "directory for all clients (yes/no): ")) || ua->pint32_val == 0) { if (!(client = get_client_resource(ua))) { return false; } } } /* * See if we need to recursively remove all directories under a certain path. */ recursive = find_arg(ua, NT_("recursive")) >= 0; /* * Get the directory to prune. */ i = find_arg_with_value(ua, NT_("directory")); if (i >= 0) { pm_strcpy(temp, ua->argv[i]); } else { if (recursive) { if (!get_cmd(ua, _("Please enter the full path prefix to remove: "), false)) { return false; } } else { if (!get_cmd(ua, _("Please enter the full path to remove: "), false)) { return false; } } pm_strcpy(temp, ua->cmd); } /* * See if the directory ends in a / and escape it for usage in a database query. */ len = strlen(temp.c_str()); if (*(temp.c_str() + len - 1) != '/') { pm_strcat(temp, "/"); len++; } prune_topdir = (char *)malloc(len * 2 + 1); db_escape_string(ua->jcr, ua->db, prune_topdir, temp.c_str(), len); /* * Remove all files in particular directory. */ if (recursive) { Mmsg(query, "DELETE FROM file WHERE pathid IN (" "SELECT pathid FROM path " "WHERE path LIKE '%s%%'" ")", prune_topdir); } else { Mmsg(query, "DELETE FROM file WHERE pathid IN (" "SELECT pathid FROM path " "WHERE path LIKE '%s'" ")", prune_topdir); } if (client) { char ed1[50]; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); if (!db_create_client_record(ua->jcr, ua->db, &cr)) { goto bail_out; } Mmsg(temp, " AND JobId IN (" "SELECT JobId FROM Job " "WHERE ClientId=%s" ")", edit_int64(cr.ClientId, ed1)); pm_strcat(query, temp.c_str()); } db_lock(ua->db); db_sql_query(ua->db, query.c_str()); db_unlock(ua->db); /* * If we removed the entries from the file table without limiting it to a * certain client we created orphaned path entries as no one is referencing * them anymore. */ if (!client) { if (!get_yesno(ua, _("Cleanup orphaned path records (yes/no):")) || ua->pint32_val == 0) { retval = true; goto bail_out; } if (recursive) { Mmsg(query, "DELETE FROM path " "WHERE path LIKE '%s%%'", prune_topdir); } else { Mmsg(query, "DELETE FROM path " "WHERE path LIKE '%s'", prune_topdir); } db_lock(ua->db); db_sql_query(ua->db, query.c_str()); db_unlock(ua->db); } retval = true; bail_out: if (prune_topdir) { free(prune_topdir); } return retval; } /* * Prune Job stat records from the database. */ static bool prune_stats(UAContext *ua, utime_t retention) { char ed1[50]; char dt[MAX_TIME_LENGTH]; POOL_MEM query(PM_MESSAGE); utime_t now = (utime_t)time(NULL); db_lock(ua->db); Mmsg(query, "DELETE FROM JobHisto WHERE JobTDate < %s", edit_int64(now - retention, ed1)); db_sql_query(ua->db, query.c_str()); db_unlock(ua->db); ua->info_msg(_("Pruned Jobs from JobHisto in catalog.\n")); bstrutime(dt, sizeof(dt), now - retention); db_lock(ua->db); Mmsg(query, "DELETE FROM DeviceStats WHERE SampleTime < '%s'", dt); db_sql_query(ua->db, query.c_str()); db_unlock(ua->db); ua->info_msg(_("Pruned Statistics from DeviceStats in catalog.\n")); db_lock(ua->db); Mmsg(query, "DELETE FROM JobStats WHERE SampleTime < '%s'", dt); db_sql_query(ua->db, query.c_str()); db_unlock(ua->db); ua->info_msg(_("Pruned Statistics from JobStats in catalog.\n")); return true; } /* * Use pool and client specified by user to select jobs to prune * returns add_from string to add in FROM clause * add_where string to add in WHERE clause */ static bool prune_set_filter(UAContext *ua, CLIENTRES *client, POOLRES *pool, utime_t period, POOL_MEM *add_from, POOL_MEM *add_where) { utime_t now; char ed1[50], ed2[MAX_ESCAPE_NAME_LENGTH]; POOL_MEM tmp(PM_MESSAGE); now = (utime_t)time(NULL); edit_int64(now - period, ed1); Dmsg3(150, "now=%lld period=%lld JobTDate=%s\n", now, period, ed1); Mmsg(tmp, " AND JobTDate < %s ", ed1); pm_strcat(*add_where, tmp.c_str()); db_lock(ua->db); if (client) { db_escape_string(ua->jcr, ua->db, ed2, client->name(), strlen(client->name())); Mmsg(tmp, " AND Client.Name = '%s' ", ed2); pm_strcat(*add_where, tmp.c_str()); pm_strcat(*add_from, " JOIN Client USING (ClientId) "); } if (pool) { db_escape_string(ua->jcr, ua->db, ed2, pool->name(), strlen(pool->name())); Mmsg(tmp, " AND Pool.Name = '%s' ", ed2); pm_strcat(*add_where, tmp.c_str()); /* Use ON() instead of USING for some old SQLite */ pm_strcat(*add_from, " JOIN Pool ON (Job.PoolId = Pool.PoolId) "); } Dmsg2(150, "f=%s w=%s\n", add_from->c_str(), add_where->c_str()); db_unlock(ua->db); return true; } /* * Prune File records from the database. For any Job which * is older than the retention period, we unconditionally delete * all File records for that Job. This is simple enough that no * temporary tables are needed. We simply make an in memory list of * the JobIds meeting the prune conditions, then delete all File records * pointing to each of those JobIds. * * This routine assumes you want the pruning to be done. All checking * must be done before calling this routine. * * Note: client or pool can possibly be NULL (not both). */ bool prune_files(UAContext *ua, CLIENTRES *client, POOLRES *pool) { struct del_ctx del; struct s_count_ctx cnt; POOL_MEM query(PM_MESSAGE); POOL_MEM sql_where(PM_MESSAGE); POOL_MEM sql_from(PM_MESSAGE); utime_t period; char ed1[50]; memset(&del, 0, sizeof(del)); if (pool && pool->FileRetention > 0) { period = pool->FileRetention; } else if (client) { period = client->FileRetention; } else { /* should specify at least pool or client */ return false; } db_lock(ua->db); /* Specify JobTDate and Pool.Name= and/or Client.Name= in the query */ if (!prune_set_filter(ua, client, pool, period, &sql_from, &sql_where)) { goto bail_out; } // edit_utime(now-period, ed1, sizeof(ed1)); // Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s secs.\n"), ed1); Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Files.\n")); /* Select Jobs -- for counting */ Mmsg(query, "SELECT COUNT(1) FROM Job %s WHERE PurgedFiles=0 %s", sql_from.c_str(), sql_where.c_str()); Dmsg1(050, "select sql=%s\n", query.c_str()); cnt.count = 0; if (!db_sql_query(ua->db, query.c_str(), del_count_handler, (void *)&cnt)) { ua->error_msg("%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); goto bail_out; } if (cnt.count == 0) { if (ua->verbose) { ua->warning_msg(_("No Files found to prune.\n")); } goto bail_out; } if (cnt.count < MAX_DEL_LIST_LEN) { del.max_ids = cnt.count + 1; } else { del.max_ids = MAX_DEL_LIST_LEN; } del.tot_ids = 0; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); /* Now process same set but making a delete list */ Mmsg(query, "SELECT JobId FROM Job %s WHERE PurgedFiles=0 %s", sql_from.c_str(), sql_where.c_str()); Dmsg1(050, "select sql=%s\n", query.c_str()); db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del); purge_files_from_job_list(ua, del); edit_uint64_with_commas(del.num_del, ed1); ua->info_msg(_("Pruned Files from %s Jobs for client %s from catalog.\n"), ed1, client->name()); bail_out: db_unlock(ua->db); if (del.JobId) { free(del.JobId); } return 1; } static void drop_temp_tables(UAContext *ua) { int i; for (i=0; drop_deltabs[i]; i++) { db_sql_query(ua->db, drop_deltabs[i]); } } static bool create_temp_tables(UAContext *ua) { /* Create temp tables and indicies */ if (!db_sql_query(ua->db, create_deltabs[db_get_type_index(ua->db)])) { ua->error_msg("%s", db_strerror(ua->db)); Dmsg0(050, "create DelTables table failed\n"); return false; } if (!db_sql_query(ua->db, create_delindex)) { ua->error_msg("%s", db_strerror(ua->db)); Dmsg0(050, "create DelInx1 index failed\n"); return false; } return true; } static bool grow_del_list(struct del_ctx *del) { if (del->num_ids == MAX_DEL_LIST_LEN) { return false; } if (del->num_ids == del->max_ids) { del->max_ids = (del->max_ids * 3) / 2; del->JobId = (JobId_t *)brealloc(del->JobId, sizeof(JobId_t) * del->max_ids); del->PurgedFiles = (char *)brealloc(del->PurgedFiles, del->max_ids); } return true; } struct accurate_check_ctx { DBId_t ClientId; /* Id of client */ DBId_t FileSetId; /* Id of FileSet */ }; /* row: Job.Name, FileSet, Client.Name, FileSetId, ClientId, Type */ static int job_select_handler(void *ctx, int num_fields, char **row) { alist *lst = (alist *)ctx; struct accurate_check_ctx *res; ASSERT(num_fields == 6); /* Quick fix for #5507, avoid locking res_head after db_lock() */ #ifdef bug5507 /* If this job doesn't exist anymore in the configuration, delete it */ if (GetResWithName(R_JOB, row[0]) == NULL) { return 0; } /* If this fileset doesn't exist anymore in the configuration, delete it */ if (GetResWithName(R_FILESET, row[1]) == NULL) { return 0; } /* If this client doesn't exist anymore in the configuration, delete it */ if (GetResWithName(R_CLIENT, row[2]) == NULL) { return 0; } #endif /* Don't compute accurate things for Verify jobs */ if (*row[5] == 'V') { return 0; } res = (struct accurate_check_ctx*) malloc(sizeof(struct accurate_check_ctx)); res->FileSetId = str_to_int64(row[3]); res->ClientId = str_to_int64(row[4]); lst->append(res); // Dmsg2(150, "row=%d val=%d\n", del->num_ids-1, del->JobId[del->num_ids-1]); return 0; } /* * Pruning Jobs is a bit more complicated than purging Files * because we delete Job records only if there is a more current * backup of the FileSet. Otherwise, we keep the Job record. * In other words, we never delete the only Job record that * contains a current backup of a FileSet. This prevents the * Volume from being recycled and destroying a current backup. * * For Verify Jobs, we do not delete the last InitCatalog. * * For Restore Jobs there are no restrictions. */ static bool prune_backup_jobs(UAContext *ua, CLIENTRES *client, POOLRES *pool) { POOL_MEM query(PM_MESSAGE); POOL_MEM sql_where(PM_MESSAGE); POOL_MEM sql_from(PM_MESSAGE); utime_t period; char ed1[50]; alist *jobids_check=NULL; struct accurate_check_ctx *elt; db_list_ctx jobids, tempids; JOB_DBR jr; struct del_ctx del; memset(&del, 0, sizeof(del)); if (pool && pool->JobRetention > 0) { period = pool->JobRetention; } else if (client) { period = client->JobRetention; } else { /* should specify at least pool or client */ return false; } db_lock(ua->db); if (!prune_set_filter(ua, client, pool, period, &sql_from, &sql_where)) { goto bail_out; } /* Drop any previous temporary tables still there */ drop_temp_tables(ua); /* Create temp tables and indicies */ if (!create_temp_tables(ua)) { goto bail_out; } edit_utime(period, ed1, sizeof(ed1)); Jmsg(ua->jcr, M_INFO, 0, _("Begin pruning Jobs older than %s.\n"), ed1); del.max_ids = 100; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); del.PurgedFiles = (char *)malloc(del.max_ids); /* * Select all files that are older than the JobRetention period * and add them into the "DeletionCandidates" table. */ Mmsg(query, "INSERT INTO DelCandidates " "SELECT JobId,PurgedFiles,FileSetId,JobFiles,JobStatus " "FROM Job %s " /* JOIN Pool/Client */ "WHERE Type IN ('B', 'C', 'M', 'V', 'D', 'R', 'c', 'm', 'g') " " %s ", /* Pool/Client + JobTDate */ sql_from.c_str(), sql_where.c_str()); Dmsg1(050, "select sql=%s\n", query.c_str()); if (!db_sql_query(ua->db, query.c_str())) { if (ua->verbose) { ua->error_msg("%s", db_strerror(ua->db)); } goto bail_out; } /* Now, for the selection, we discard some of them in order to be always * able to restore files. (ie, last full, last diff, last incrs) * Note: The DISTINCT could be more useful if we don't get FileSetId */ jobids_check = New(alist(10, owned_by_alist)); Mmsg(query, "SELECT DISTINCT Job.Name, FileSet, Client.Name, Job.FileSetId, " "Job.ClientId, Job.Type " "FROM DelCandidates " "JOIN Job USING (JobId) " "JOIN Client USING (ClientId) " "JOIN FileSet ON (Job.FileSetId = FileSet.FileSetId) " "WHERE Job.Type IN ('B') " /* Look only Backup jobs */ "AND Job.JobStatus IN ('T', 'W') " /* Look only useful jobs */ ); /* The job_select_handler will skip jobs or filesets that are no longer * in the configuration file. Interesting ClientId/FileSetId will be * added to jobids_check (currently disabled in 6.0.7b) */ if (!db_sql_query(ua->db, query.c_str(), job_select_handler, jobids_check)) { ua->error_msg("%s", db_strerror(ua->db)); } /* For this selection, we exclude current jobs used for restore or * accurate. This will prevent to prune the last full backup used for * current backup & restore */ memset(&jr, 0, sizeof(jr)); /* To find useful jobs, we do like an incremental */ jr.JobLevel = L_INCREMENTAL; foreach_alist(elt, jobids_check) { jr.ClientId = elt->ClientId; /* should be always the same */ jr.FileSetId = elt->FileSetId; db_accurate_get_jobids(ua->jcr, ua->db, &jr, &tempids); jobids.add(tempids); } /* Discard latest Verify level=InitCatalog job * TODO: can have multiple fileset */ Mmsg(query, "SELECT JobId, JobTDate " "FROM Job %s " /* JOIN Client/Pool */ "WHERE Type='V' AND Level='V' " " %s " /* Pool, JobTDate, Client */ "ORDER BY JobTDate DESC LIMIT 1", sql_from.c_str(), sql_where.c_str()); if (!db_sql_query(ua->db, query.c_str(), db_list_handler, &jobids)) { ua->error_msg("%s", db_strerror(ua->db)); } /* If we found jobs to exclude from the DelCandidates list, we should * also remove BaseJobs that can be linked with them */ if (jobids.count > 0) { Dmsg1(60, "jobids to exclude before basejobs = %s\n", jobids.list); /* We also need to exclude all basejobs used */ db_get_used_base_jobids(ua->jcr, ua->db, jobids.list, &jobids); /* Removing useful jobs from the DelCandidates list */ Mmsg(query, "DELETE FROM DelCandidates " "WHERE JobId IN (%s) " /* JobId used in accurate */ "AND JobFiles!=0", /* Discard when JobFiles=0 */ jobids.list); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); goto bail_out; /* Don't continue if the list isn't clean */ } Dmsg1(60, "jobids to exclude = %s\n", jobids.list); } /* We use DISTINCT because we can have two times the same job */ Mmsg(query, "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles " "FROM DelCandidates"); if (!db_sql_query(ua->db, query.c_str(), job_delete_handler, (void *)&del)) { ua->error_msg("%s", db_strerror(ua->db)); } purge_job_list_from_catalog(ua, del); if (del.num_del > 0) { ua->info_msg(_("Pruned %d %s for client %s from catalog.\n"), del.num_del, del.num_del==1?_("Job"):_("Jobs"), client->name()); } else if (ua->verbose) { ua->info_msg(_("No Jobs found to prune.\n")); } bail_out: drop_temp_tables(ua); db_unlock(ua->db); if (del.JobId) { free(del.JobId); } if (del.PurgedFiles) { free(del.PurgedFiles); } if (jobids_check) { delete jobids_check; } return 1; } /* * Dispatch to the right prune jobs function. */ bool prune_jobs(UAContext *ua, CLIENTRES *client, POOLRES *pool, int JobType) { switch (JobType) { case JT_BACKUP: return prune_backup_jobs(ua, client, pool); default: return true; } } /* * Prune a given Volume */ bool prune_volume(UAContext *ua, MEDIA_DBR *mr) { POOL_MEM query(PM_MESSAGE); struct del_ctx del; bool ok = false; int count; if (mr->Enabled == VOL_ARCHIVED) { return false; /* Cannot prune archived volumes */ } memset(&del, 0, sizeof(del)); del.max_ids = 10000; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); db_lock(ua->db); /* Prune only Volumes with status "Full", or "Used" */ if (bstrcmp(mr->VolStatus, "Full") || bstrcmp(mr->VolStatus, "Used")) { Dmsg2(050, "get prune list MediaId=%d Volume %s\n", (int)mr->MediaId, mr->VolumeName); count = get_prune_list_for_volume(ua, mr, &del); Dmsg1(050, "Num pruned = %d\n", count); if (count != 0) { purge_job_list_from_catalog(ua, del); } ok = is_volume_purged(ua, mr); } db_unlock(ua->db); if (del.JobId) { free(del.JobId); } return ok; } /* * Get prune list for a volume */ int get_prune_list_for_volume(UAContext *ua, MEDIA_DBR *mr, del_ctx *del) { POOL_MEM query(PM_MESSAGE); int count = 0; utime_t now, period; char ed1[50], ed2[50]; if (mr->Enabled == VOL_ARCHIVED) { return 0; /* cannot prune Archived volumes */ } /* * Now add to the list of JobIds for Jobs written to this Volume */ edit_int64(mr->MediaId, ed1); period = mr->VolRetention; now = (utime_t)time(NULL); edit_int64(now-period, ed2); Mmsg(query, sel_JobMedia, ed1, ed2); Dmsg3(250, "Now=%d period=%d now-period=%s\n", (int)now, (int)period, ed2); Dmsg1(050, "Query=%s\n", query.c_str()); if (!db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)del)) { if (ua->verbose) { ua->error_msg("%s", db_strerror(ua->db)); } Dmsg0(050, "Count failed\n"); goto bail_out; } count = exclude_running_jobs_from_list(del); bail_out: return count; } /* * We have a list of jobs to prune or purge. If any of them is * currently running, we set its JobId to zero which effectively * excludes it. * * Returns the number of jobs that can be prunned or purged. */ int exclude_running_jobs_from_list(del_ctx *prune_list) { int count = 0; JCR *jcr; bool skip; int i; /* Do not prune any job currently running */ for (i=0; i < prune_list->num_ids; i++) { skip = false; foreach_jcr(jcr) { if (jcr->JobId == prune_list->JobId[i]) { Dmsg2(050, "skip running job JobId[%d]=%d\n", i, (int)prune_list->JobId[i]); prune_list->JobId[i] = 0; skip = true; break; } } endeach_jcr(jcr); if (skip) { continue; /* don't increment count */ } Dmsg2(050, "accept JobId[%d]=%d\n", i, (int)prune_list->JobId[i]); count++; } return count; } bareos-Release-14.2.6/src/dird/ua_purge.c000066400000000000000000000647641263011562700201450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Database Purge Command * * Purges Files from specific JobIds * or * Purges Jobs from Volumes * * Kern Sibbald, February MMII */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ static int purge_files_from_client(UAContext *ua, CLIENTRES *client); static int purge_jobs_from_client(UAContext *ua, CLIENTRES *client); static int purge_quota_from_client(UAContext *ua, CLIENTRES *client); static int action_on_purge_cmd(UAContext *ua, const char *cmd); static const char *select_jobsfiles_from_client = "SELECT JobId FROM Job " "WHERE ClientId=%s " "AND PurgedFiles=0"; static const char *select_jobs_from_client = "SELECT JobId, PurgedFiles FROM Job " "WHERE ClientId=%s"; /* * Purge records from database * * Purge Files (from) [Job|JobId|Client|Volume] * Purge Jobs (from) [Client|Volume] * * N.B. Not all above is implemented yet. */ int purge_cmd(UAContext *ua, const char *cmd) { int i; CLIENTRES *client; MEDIA_DBR mr; JOB_DBR jr; POOL_MEM cmd_holder(PM_MESSAGE); static const char *keywords[] = { NT_("files"), NT_("jobs"), NT_("volume"), NT_("quota"), NULL }; static const char *files_keywords[] = { NT_("Job"), NT_("JobId"), NT_("Client"), NT_("Volume"), NULL }; static const char *quota_keywords[] = { NT_("Client"), NULL }; static const char *jobs_keywords[] = { NT_("Client"), NT_("Volume"), NULL }; ua->warning_msg(_( "\nThis command can be DANGEROUS!!!\n\n" "It purges (deletes) all Files from a Job,\n" "JobId, Client or Volume; or it purges (deletes)\n" "all Jobs from a Client or Volume without regard\n" "to retention periods. Normally you should use the\n" "PRUNE command, which respects retention periods.\n")); if (!open_client_db(ua, true)) { return 1; } memset(&jr, 0, sizeof(jr)); memset(&mr, 0, sizeof(mr)); switch (find_arg_keyword(ua, keywords)) { /* Files */ case 0: switch(find_arg_keyword(ua, files_keywords)) { case 0: /* Job */ case 1: /* JobId */ if (get_job_dbr(ua, &jr)) { char jobid[50]; edit_int64(jr.JobId, jobid); purge_files_from_jobs(ua, jobid); } return 1; case 2: /* client */ client = get_client_resource(ua); if (client) { purge_files_from_client(ua, client); } return 1; case 3: /* Volume */ if (select_media_dbr(ua, &mr)) { purge_files_from_volume(ua, &mr); } return 1; } /* Jobs */ case 1: switch(find_arg_keyword(ua, jobs_keywords)) { case 0: /* client */ client = get_client_resource(ua); if (client) { purge_jobs_from_client(ua, client); } return 1; case 1: /* Volume */ if (select_media_dbr(ua, &mr)) { purge_jobs_from_volume(ua, &mr, /*force*/true); } return 1; } /* Volume */ case 2: /* * Store cmd for later reuse. */ pm_strcpy(cmd_holder, ua->cmd); while ((i=find_arg(ua, NT_("volume"))) >= 0) { if (select_media_dbr(ua, &mr)) { purge_jobs_from_volume(ua, &mr, /*force*/true); } *ua->argk[i] = 0; /* zap keyword already seen */ ua->send_msg("\n"); /* * Add volume=mr.VolumeName to cmd_holder if we have a new volume name from interactive selection. * In certain cases this can produce duplicates, which we don't prevent as there are no side effects. */ if (!bstrcmp(ua->cmd, cmd_holder.c_str())) { pm_strcat(cmd_holder, " volume="); pm_strcat(cmd_holder, mr.VolumeName); } } /* * Restore ua args based on cmd_holder */ pm_strcpy(ua->cmd, cmd_holder); parse_args(ua->cmd, &ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS); /* * Perform ActionOnPurge (action=truncate) */ if (find_arg(ua, "action") >= 0) { return action_on_purge_cmd(ua, ua->cmd); } return 1; /* Quota */ case 3: switch(find_arg_keyword(ua, quota_keywords)) { case 0: /* client */ client = get_client_resource(ua); if (client) { purge_quota_from_client(ua, client); } return 1; } default: break; } switch (do_keyword_prompt(ua, _("Choose item to purge"), keywords)) { case 0: /* files */ client = get_client_resource(ua); if (client) { purge_files_from_client(ua, client); } break; case 1: /* jobs */ client = get_client_resource(ua); if (client) { purge_jobs_from_client(ua, client); } break; case 2: /* Volume */ if (select_media_dbr(ua, &mr)) { purge_jobs_from_volume(ua, &mr, /*force*/true); } break; case 3: client = get_client_resource(ua); /* Quota */ if (client) { purge_quota_from_client(ua, client); } } return 1; } /* * Purge File records from the database. For any Job which * is older than the retention period, we unconditionally delete * all File records for that Job. This is simple enough that no * temporary tables are needed. We simply make an in memory list of * the JobIds meeting the prune conditions, then delete all File records * pointing to each of those JobIds. */ static int purge_files_from_client(UAContext *ua, CLIENTRES *client) { struct del_ctx del; POOL_MEM query(PM_MESSAGE); CLIENT_DBR cr; char ed1[50]; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); if (!db_create_client_record(ua->jcr, ua->db, &cr)) { return 0; } memset(&del, 0, sizeof(del)); del.max_ids = 1000; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); ua->info_msg(_("Begin purging files for Client \"%s\"\n"), cr.Name); Mmsg(query, select_jobsfiles_from_client, edit_int64(cr.ClientId, ed1)); Dmsg1(050, "select sql=%s\n", query.c_str()); db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del); purge_files_from_job_list(ua, del); if (del.num_ids == 0) { ua->warning_msg(_("No Files found for client %s to purge from %s catalog.\n"), client->name(), client->catalog->name()); } else { ua->info_msg(_("Files for %d Jobs for client \"%s\" purged from %s catalog.\n"), del.num_ids, client->name(), client->catalog->name()); } if (del.JobId) { free(del.JobId); } return 1; } /* * Purge Job records from the database. For any Job which * is older than the retention period, we unconditionally delete * it and all File records for that Job. This is simple enough that no * temporary tables are needed. We simply make an in memory list of * the JobIds then delete the Job, Files, and JobMedia records in that list. */ static int purge_jobs_from_client(UAContext *ua, CLIENTRES *client) { struct del_ctx del; POOL_MEM query(PM_MESSAGE); CLIENT_DBR cr; char ed1[50]; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); if (!db_create_client_record(ua->jcr, ua->db, &cr)) { return 0; } memset(&del, 0, sizeof(del)); del.max_ids = 1000; del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); del.PurgedFiles = (char *)malloc(del.max_ids); ua->info_msg(_("Begin purging jobs from Client \"%s\"\n"), cr.Name); Mmsg(query, select_jobs_from_client, edit_int64(cr.ClientId, ed1)); Dmsg1(150, "select sql=%s\n", query.c_str()); db_sql_query(ua->db, query.c_str(), job_delete_handler, (void *)&del); purge_job_list_from_catalog(ua, del); if (del.num_ids == 0) { ua->warning_msg(_("No Files found for client %s to purge from %s catalog.\n"), client->name(), client->catalog->name()); } else { ua->info_msg(_("%d Jobs for client %s purged from %s catalog.\n"), del.num_ids, client->name(), client->catalog->name()); } if (del.JobId) { free(del.JobId); } if (del.PurgedFiles) { free(del.PurgedFiles); } return 1; } /* * Remove File records from a list of JobIds */ void purge_files_from_jobs(UAContext *ua, char *jobs) { POOL_MEM query(PM_MESSAGE); Mmsg(query, "DELETE FROM File WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete File sql=%s\n", query.c_str()); Mmsg(query, "DELETE FROM BaseFiles WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete BaseFiles sql=%s\n", query.c_str()); /* * Now mark Job as having files purged. This is necessary to * avoid having too many Jobs to process in future prunings. If * we don't do this, the number of JobId's in our in memory list * could grow very large. */ Mmsg(query, "UPDATE Job SET PurgedFiles=1 WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Mark purged sql=%s\n", query.c_str()); } /* * Delete jobs (all records) from the catalog in groups of 1000 * at a time. */ void purge_job_list_from_catalog(UAContext *ua, del_ctx &del) { POOL_MEM jobids(PM_MESSAGE); char ed1[50]; for (int i=0; del.num_ids; ) { Dmsg1(150, "num_ids=%d\n", del.num_ids); pm_strcat(jobids, ""); for (int j=0; j<1000 && del.num_ids>0; j++) { del.num_ids--; if (del.JobId[i] == 0 || ua->jcr->JobId == del.JobId[i]) { Dmsg2(150, "skip JobId[%d]=%d\n", i, (int)del.JobId[i]); i++; continue; } if (*jobids.c_str() != 0) { pm_strcat(jobids, ","); } pm_strcat(jobids, edit_int64(del.JobId[i++], ed1)); Dmsg1(150, "Add id=%s\n", ed1); del.num_del++; } Dmsg1(150, "num_ids=%d\n", del.num_ids); purge_jobs_from_catalog(ua, jobids.c_str()); } } /* * Delete files from a list of jobs in groups of 1000 * at a time. */ void purge_files_from_job_list(UAContext *ua, del_ctx &del) { POOL_MEM jobids(PM_MESSAGE); char ed1[50]; /* * OK, now we have the list of JobId's to be pruned, send them * off to be deleted batched 1000 at a time. */ for (int i=0; del.num_ids; ) { pm_strcat(jobids, ""); for (int j=0; j<1000 && del.num_ids>0; j++) { del.num_ids--; if (del.JobId[i] == 0 || ua->jcr->JobId == del.JobId[i]) { Dmsg2(150, "skip JobId[%d]=%d\n", i, (int)del.JobId[i]); i++; continue; } if (*jobids.c_str() != 0) { pm_strcat(jobids, ","); } pm_strcat(jobids, edit_int64(del.JobId[i++], ed1)); Dmsg1(150, "Add id=%s\n", ed1); del.num_del++; } purge_files_from_jobs(ua, jobids.c_str()); } } /* * This resets quotas in the database table Quota for the matching client * It is necessary to purge this if you want to reset the quota and let it count * from scratch. * * This function does not actually delete records, rather it updates them to nil * It should also be noted that if a quota record does not exist it will actually * end up creating it! */ static int purge_quota_from_client(UAContext *ua, CLIENTRES *client) { CLIENT_DBR cr; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, client->name(), sizeof(cr.Name)); if (!db_create_client_record(ua->jcr, ua->db, &cr)) { return 0; } if (!db_create_quota_record(ua->jcr, ua->db, &cr)) { return 0; } if (!db_reset_quota_record(ua->jcr, ua->db, &cr)) { return 0; } ua->info_msg(_("Purged quota for Client \"%s\"\n"), cr.Name); return 1; } /* * Change the type of the next copy job to backup. * We need to upgrade the next copy of a normal job, * and also upgrade the next copy when the normal job * already have been purged. * * JobId: 1 PriorJobId: 0 (original) * JobId: 2 PriorJobId: 1 (first copy) * JobId: 3 PriorJobId: 1 (second copy) * * JobId: 2 PriorJobId: 1 (first copy, now regular backup) * JobId: 3 PriorJobId: 1 (second copy) * * => Search through PriorJobId in jobid and * PriorJobId in PriorJobId (jobid) */ void upgrade_copies(UAContext *ua, char *jobs) { POOL_MEM query(PM_MESSAGE); db_lock(ua->db); /* Do it in two times for mysql */ Mmsg(query, uap_upgrade_copies_oldest_job[db_get_type_index(ua->db)], JT_JOB_COPY, jobs, jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Upgrade copies Log sql=%s\n", query.c_str()); /* Now upgrade first copy to Backup */ Mmsg(query, "UPDATE Job SET Type='B' " /* JT_JOB_COPY => JT_BACKUP */ "WHERE JobId IN ( SELECT JobId FROM cpy_tmp )"); db_sql_query(ua->db, query.c_str()); Mmsg(query, "DROP TABLE cpy_tmp"); db_sql_query(ua->db, query.c_str()); db_unlock(ua->db); } /* * Remove all records from catalog for a list of JobIds */ void purge_jobs_from_catalog(UAContext *ua, char *jobs) { POOL_MEM query(PM_MESSAGE); /* Delete (or purge) records associated with the job */ purge_files_from_jobs(ua, jobs); Mmsg(query, "DELETE FROM JobMedia WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete JobMedia sql=%s\n", query.c_str()); Mmsg(query, "DELETE FROM Log WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete Log sql=%s\n", query.c_str()); Mmsg(query, "DELETE FROM RestoreObject WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete RestoreObject sql=%s\n", query.c_str()); Mmsg(query, "DELETE FROM PathVisibility WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete PathVisibility sql=%s\n", query.c_str()); Mmsg(query, "DELETE FROM NDMPJobEnvironment WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete NDMPJobEnvironment sql=%s\n", query.c_str()); Mmsg(query, "DELETE FROM JobStats WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete JobStats sql=%s\n", query.c_str()); upgrade_copies(ua, jobs); /* Now remove the Job record itself */ Mmsg(query, "DELETE FROM Job WHERE JobId IN (%s)", jobs); db_sql_query(ua->db, query.c_str()); Dmsg1(050, "Delete Job sql=%s\n", query.c_str()); } void purge_files_from_volume(UAContext *ua, MEDIA_DBR *mr ) {} /* ***FIXME*** implement */ /* * Returns: 1 if Volume purged * 0 if Volume not purged */ bool purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr, bool force) { POOL_MEM query(PM_MESSAGE); db_list_ctx lst; char *jobids=NULL; int i; bool purged = false; bool status; status = bstrcmp(mr->VolStatus, "Append") || bstrcmp(mr->VolStatus, "Full") || bstrcmp(mr->VolStatus, "Used") || bstrcmp(mr->VolStatus, "Error"); if (!status) { ua->error_msg(_("\nVolume \"%s\" has VolStatus \"%s\" and cannot be purged.\n" "The VolStatus must be: Append, Full, Used, or Error to be purged.\n"), mr->VolumeName, mr->VolStatus); return 0; } /* * Check if he wants to purge a single jobid */ i = find_arg_with_value(ua, "jobid"); if (i >= 0 && is_a_number_list(ua->argv[i])) { jobids = ua->argv[i]; } else { /* * Purge ALL JobIds */ if (!db_get_volume_jobids(ua->jcr, ua->db, mr, &lst)) { ua->error_msg("%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); goto bail_out; } jobids = lst.list; } if (*jobids) { purge_jobs_from_catalog(ua, jobids); } ua->info_msg(_("%d File%s on Volume \"%s\" purged from catalog.\n"), lst.count, lst.count<=1?"":"s", mr->VolumeName); purged = is_volume_purged(ua, mr, force); bail_out: return purged; } /* * This routine will check the JobMedia records to see if the * Volume has been purged. If so, it marks it as such and * * Returns: true if volume purged * false if not * * Note, we normally will not purge a volume that has Firstor LastWritten * zero, because it means the volume is most likely being written * however, if the user manually purges using the purge command in * the console, he has been warned, and we go ahead and purge * the volume anyway, if possible). */ bool is_volume_purged(UAContext *ua, MEDIA_DBR *mr, bool force) { POOL_MEM query(PM_MESSAGE); struct s_count_ctx cnt; bool purged = false; char ed1[50]; if (!force && (mr->FirstWritten == 0 || mr->LastWritten == 0)) { goto bail_out; /* not written cannot purge */ } if (bstrcmp(mr->VolStatus, "Purged")) { purged = true; goto bail_out; } /* If purged, mark it so */ cnt.count = 0; Mmsg(query, "SELECT 1 FROM JobMedia WHERE MediaId=%s LIMIT 1", edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query.c_str(), del_count_handler, (void *)&cnt)) { ua->error_msg("%s", db_strerror(ua->db)); Dmsg0(050, "Count failed\n"); goto bail_out; } if (cnt.count == 0) { ua->warning_msg(_("There are no more Jobs associated with Volume \"%s\". Marking it purged.\n"), mr->VolumeName); if (!(purged = mark_media_purged(ua, mr))) { ua->error_msg("%s", db_strerror(ua->db)); } } bail_out: return purged; } /* * Called here to send the appropriate commands to the SD * to do truncate on purge. */ static void do_truncate_on_purge(UAContext *ua, MEDIA_DBR *mr, char *pool, char *storage, int drive, BSOCK *sd) { bool ok=false; uint64_t VolBytes = 0; /* * TODO: Return if not mr->Recyle ? */ if (!mr->Recycle) { return; } /* * Do it only if action on purge = truncate is set */ if (!(mr->ActionOnPurge & ON_PURGE_TRUNCATE)) { return; } /* * Send the command to truncate the volume after purge. If this feature * is disabled for the specific device, this will be a no-op. */ /* * Protect us from spaces */ bash_spaces(mr->VolumeName); bash_spaces(mr->MediaType); bash_spaces(pool); bash_spaces(storage); /* * Do it by relabeling the Volume, which truncates it */ sd->fsend("relabel %s OldName=%s NewName=%s PoolName=%s " "MediaType=%s Slot=%d drive=%d MinBlocksize=%d MaxBlocksize=%d\n", storage, mr->VolumeName, mr->VolumeName, pool, mr->MediaType, mr->Slot, drive, /* * If relabeling, keep blocksize settings */ mr->MinBlocksize, mr->MaxBlocksize); unbash_spaces(mr->VolumeName); unbash_spaces(mr->MediaType); unbash_spaces(pool); unbash_spaces(storage); /* * Send relabel command, and check for valid response */ while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); if (sscanf(sd->msg, "3000 OK label. VolBytes=%llu ", &VolBytes) == 1) { ok = true; } } if (ok) { mr->VolBytes = VolBytes; mr->VolFiles = 0; set_storageid_in_mr(NULL, mr); if (!db_update_media_record(ua->jcr, ua->db, mr)) { ua->error_msg(_("Can't update volume size in the catalog\n")); } ua->send_msg(_("The volume \"%s\" has been truncated\n"), mr->VolumeName); } else { ua->warning_msg(_("Unable to truncate volume \"%s\"\n"), mr->VolumeName); } } /* * Implement Bareos bconsole command purge action * purge action= pool= volume= storage= devicetype= */ static int action_on_purge_cmd(UAContext *ua, const char *cmd) { bool allpools = false; int drive = -1; int nb = 0; uint32_t *results = NULL; const char *action = "all"; STORERES *store = NULL; POOLRES *pool = NULL; MEDIA_DBR mr; POOL_DBR pr; BSOCK *sd = NULL; char esc[MAX_NAME_LENGTH * 2 + 1]; POOL_MEM buf(PM_MESSAGE), volumes(PM_MESSAGE); memset(&mr, 0, sizeof(mr)); memset(&pr, 0, sizeof(pr)); pm_strcpy(volumes, ""); /* * Look at arguments */ for (int i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("allpools"))) { allpools = true; } else if (bstrcasecmp(ua->argk[i], NT_("volume")) && is_name_valid(ua->argv[i], NULL)) { db_escape_string(ua->jcr, ua->db, esc, ua->argv[i], strlen(ua->argv[i])); if (!*volumes.c_str()) { Mmsg(buf, "'%s'", esc); } else { Mmsg(buf, ",'%s'", esc); } pm_strcat(volumes, buf.c_str()); } else if (bstrcasecmp(ua->argk[i], NT_("devicetype")) && ua->argv[i]) { bstrncpy(mr.MediaType, ua->argv[i], sizeof(mr.MediaType)); } else if (bstrcasecmp(ua->argk[i], NT_("drive")) && ua->argv[i]) { drive = atoi(ua->argv[i]); } else if (bstrcasecmp(ua->argk[i], NT_("action")) && is_name_valid(ua->argv[i], NULL)) { action=ua->argv[i]; } } /* * Choose storage */ ua->jcr->res.wstore = store = get_storage_resource(ua); if (!store) { goto bail_out; } switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); goto bail_out; default: break; } if (!open_db(ua)) { Dmsg0(100, "Can't open db\n"); goto bail_out; } if (!allpools) { /* * Force pool selection */ pool = get_pool_resource(ua); if (!pool) { Dmsg0(100, "Can't get pool resource\n"); goto bail_out; } bstrncpy(pr.Name, pool->name(), sizeof(pr.Name)); if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { Dmsg0(100, "Can't get pool record\n"); goto bail_out; } mr.PoolId = pr.PoolId; } /* * Look for all Purged volumes that can be recycled, are enabled and have more the 10,000 bytes. */ mr.Recycle = 1; mr.Enabled = VOL_ENABLED; mr.VolBytes = 10000; set_storageid_in_mr(store, &mr); bstrncpy(mr.VolStatus, "Purged", sizeof(mr.VolStatus)); if (!db_get_media_ids(ua->jcr, ua->db, &mr, volumes, &nb, &results)) { Dmsg0(100, "No results from db_get_media_ids\n"); goto bail_out; } if (!nb) { ua->send_msg(_("No Volumes found to perform %s action.\n"), action); goto bail_out; } if ((sd = open_sd_bsock(ua)) == NULL) { Dmsg0(100, "Can't open connection to sd\n"); goto bail_out; } /* * Loop over the candidate Volumes and actually truncate them */ for (int i = 0; i < nb; i++) { memset(&mr, 0, sizeof(mr)); mr.MediaId = results[i]; if (db_get_media_record(ua->jcr, ua->db, &mr)) { /* TODO: ask for drive and change Pool */ if (bstrcasecmp("truncate", action) || bstrcasecmp("all", action)) { do_truncate_on_purge(ua, &mr, pr.Name, store->dev_name(), drive, sd); } } else { Dmsg1(0, "Can't find MediaId=%lld\n", (uint64_t) mr.MediaId); } } bail_out: close_db(ua); if (sd) { sd->signal(BNET_TERMINATE); sd->close(); delete ua->jcr->store_bsock; ua->jcr->store_bsock = NULL; } ua->jcr->res.wstore = NULL; if (results) { free(results); } return 1; } /* * If volume status is Append, Full, Used, or Error, mark it Purged * Purged volumes can then be recycled (if enabled). */ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) { JCR *jcr = ua->jcr; bool status; status = bstrcmp(mr->VolStatus, "Append") || bstrcmp(mr->VolStatus, "Full") || bstrcmp(mr->VolStatus, "Used") || bstrcmp(mr->VolStatus, "Error"); if (status) { bstrncpy(mr->VolStatus, "Purged", sizeof(mr->VolStatus)); set_storageid_in_mr(NULL, mr); if (!db_update_media_record(jcr, ua->db, mr)) { return false; } pm_strcpy(jcr->VolumeName, mr->VolumeName); generate_plugin_event(jcr, bDirEventVolumePurged); /* * If the RecyclePool is defined, move the volume there */ if (mr->RecyclePoolId && mr->RecyclePoolId != mr->PoolId) { POOL_DBR oldpr, newpr; memset(&oldpr, 0, sizeof(oldpr)); memset(&newpr, 0, sizeof(newpr)); newpr.PoolId = mr->RecyclePoolId; oldpr.PoolId = mr->PoolId; if (db_get_pool_record(jcr, ua->db, &oldpr) && db_get_pool_record(jcr, ua->db, &newpr)) { /* * Check if destination pool size is ok */ if (newpr.MaxVols > 0 && newpr.NumVols >= newpr.MaxVols) { ua->error_msg(_("Unable move recycled Volume in full " "Pool \"%s\" MaxVols=%d\n"), newpr.Name, newpr.MaxVols); } else { /* move media */ update_vol_pool(ua, newpr.Name, mr, &oldpr); } } else { ua->error_msg("%s", db_strerror(ua->db)); } } /* * Send message to Job report, if it is a *real* job */ if (jcr->JobId > 0) { Jmsg(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"), mr->VolumeName); } return true; } else { ua->error_msg(_("Cannot purge Volume with VolStatus=%s\n"), mr->VolStatus); } return bstrcmp(mr->VolStatus, "Purged"); } bareos-Release-14.2.6/src/dird/ua_query.c000066400000000000000000000167251263011562700201620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2006 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Database Query Commands * * Kern Sibbald, December MMI */ #include "bareos.h" #include "dird.h" extern DIRRES *director; static POOLMEM *substitute_prompts(UAContext *ua, POOLMEM *query, char **prompt, int nprompt); /* * Read a file containing SQL queries and prompt * the user to select which one. * * File format: * # => comment * :prompt for query * *prompt for subst %1 * *prompt for subst %2 * ... * SQL statement possibly terminated by ; * :next query prompt */ int query_cmd(UAContext *ua, const char *cmd) { FILE *fd = NULL; POOLMEM *query = get_pool_memory(PM_MESSAGE); char line[1000]; int i, item, len; char *prompt[9]; int nprompt = 0; char *query_file = me->query_file; if (!open_client_db(ua, true)) { goto bail_out; } if ((fd=fopen(query_file, "rb")) == NULL) { berrno be; ua->error_msg(_("Could not open %s: ERR=%s\n"), query_file, be.bstrerror()); goto bail_out; } start_prompt(ua, _("Available queries:\n")); while (fgets(line, sizeof(line), fd) != NULL) { if (line[0] == ':') { strip_trailing_junk(line); add_prompt(ua, line+1); } } if ((item=do_prompt(ua, "", _("Choose a query"), NULL, 0)) < 0) { goto bail_out; } rewind(fd); i = -1; while (fgets(line, sizeof(line), fd) != NULL) { if (line[0] == ':') { i++; } if (i == item) { break; } } if (i != item) { ua->error_msg(_("Could not find query.\n")); goto bail_out; } query[0] = 0; for (i=0; i<9; i++) { prompt[i] = NULL; } while (fgets(line, sizeof(line), fd) != NULL) { if (line[0] == '#') { continue; } if (line[0] == ':') { break; } strip_trailing_junk(line); len = strlen(line); if (line[0] == '*') { /* prompt */ if (nprompt >= 9) { ua->error_msg(_("Too many prompts in query, max is 9.\n")); } else { line[len++] = ' '; line[len] = 0; prompt[nprompt++] = bstrdup(line+1); continue; } } if (*query != 0) { pm_strcat(query, " "); } pm_strcat(query, line); if (line[len-1] != ';') { continue; } line[len-1] = 0; /* zap ; */ if (query[0] != 0) { query = substitute_prompts(ua, query, prompt, nprompt); Dmsg1(100, "Query2=%s\n", query); if (query[0] == '!') { db_list_sql_query(ua->jcr, ua->db, query+1, printit, ua, false, VERT_LIST); } else if (!db_list_sql_query(ua->jcr, ua->db, query, printit, ua, true, HORZ_LIST)) { ua->send_msg("%s\n", query); } query[0] = 0; } } /* end while */ if (query[0] != 0) { query = substitute_prompts(ua, query, prompt, nprompt); Dmsg1(100, "Query2=%s\n", query); if (query[0] == '!') { db_list_sql_query(ua->jcr, ua->db, query+1, printit, ua, false, VERT_LIST); } else if (!db_list_sql_query(ua->jcr, ua->db, query, printit, ua, true, HORZ_LIST)) { ua->error_msg("%s\n", query); } } bail_out: if (fd) { fclose(fd); } free_pool_memory(query); for (i=0; icmd); p = (char *)malloc(len * 2 + 1); db_escape_string(ua->jcr, ua->db, p, ua->cmd, len); subst[n] = p; olen = o - new_query; new_query = check_pool_memory_size(new_query, olen + strlen(p) + 10); o = new_query + olen; while (*p) { *o++ = *p++; } } else { ua->error_msg(_("Warning prompt %d missing.\n"), n+1); } q += 2; break; case '%': *o++ = '%'; q += 2; break; default: *o++ = '%'; q++; break; } } } olen = o - new_query; new_query = check_pool_memory_size(new_query, olen + strlen(q) + 10); o = new_query + olen; while (*q) { *o++ = *q++; } *o = 0; for (i=0; i<9; i++) { if (subst[i]) { free(subst[i]); } } free_pool_memory(query); return new_query; } /* * Get general SQL query for Catalog */ int sqlquery_cmd(UAContext *ua, const char *cmd) { POOL_MEM query(PM_MESSAGE); int len; const char *msg; if (!open_client_db(ua, true)) { return 1; } *query.c_str() = 0; ua->send_msg(_("Entering SQL query mode.\n" "Terminate each query with a semicolon.\n" "Terminate query mode with a blank line.\n")); msg = _("Enter SQL query: "); while (get_cmd(ua, msg)) { len = strlen(ua->cmd); Dmsg2(400, "len=%d cmd=%s:\n", len, ua->cmd); if (len == 0) { break; } if (*query.c_str() != 0) { pm_strcat(query, " "); } pm_strcat(query, ua->cmd); if (ua->cmd[len-1] == ';') { ua->cmd[len-1] = 0; /* zap ; */ /* Submit query */ db_list_sql_query(ua->jcr, ua->db, query.c_str(), printit, ua, true, HORZ_LIST); *query.c_str() = 0; /* start new query */ msg = _("Enter SQL query: "); } else { msg = _("Add to SQL query: "); } } ua->send_msg(_("End query mode.\n")); return 1; } bareos-Release-14.2.6/src/dird/ua_restore.c000066400000000000000000001422021263011562700204660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Database restore Command * Creates a bootstrap file for restoring files and * starts the restore job. * * Tree handling routines split into ua_tree.c July MMIII. * BSR (bootstrap record) handling routines split into * bsr.c July MMIII * * Kern Sibbald, July MMII */ #include "bareos.h" #include "dird.h" /* Imported functions */ extern void print_bsr(UAContext *ua, RBSR *bsr); /* Forward referenced functions */ static int last_full_handler(void *ctx, int num_fields, char **row); static int jobid_handler(void *ctx, int num_fields, char **row); static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx); static int fileset_handler(void *ctx, int num_fields, char **row); static void free_name_list(NAME_LIST *name_list); static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date); static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx); static void free_rx(RESTORE_CTX *rx); static void split_path_and_filename(UAContext *ua, RESTORE_CTX *rx, char *fname); static int jobid_fileindex_handler(void *ctx, int num_fields, char **row); static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, char *date); static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, char *date); static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, bool dir); static int get_client_name(UAContext *ua, RESTORE_CTX *rx); static int get_restore_client_name(UAContext *ua, RESTORE_CTX &rx); static bool get_date(UAContext *ua, char *date, int date_len); static int restore_count_handler(void *ctx, int num_fields, char **row); static bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table); static void get_and_display_basejobs(UAContext *ua, RESTORE_CTX *rx); /* * Restore files */ int restore_cmd(UAContext *ua, const char *cmd) { RESTORE_CTX rx; /* restore context */ POOL_MEM buf; JOBRES *job; int i; JCR *jcr = ua->jcr; char *escaped_bsr_name = NULL; char *escaped_where_name = NULL; char *strip_prefix, *add_prefix, *add_suffix, *regexp; strip_prefix = add_prefix = add_suffix = regexp = NULL; memset(&rx, 0, sizeof(rx)); rx.path = get_pool_memory(PM_FNAME); rx.fname = get_pool_memory(PM_FNAME); rx.JobIds = get_pool_memory(PM_FNAME); rx.JobIds[0] = 0; rx.BaseJobIds = get_pool_memory(PM_FNAME); rx.query = get_pool_memory(PM_FNAME); rx.bsr = new_bsr(); i = find_arg_with_value(ua, "comment"); if (i >= 0) { rx.comment = ua->argv[i]; if (!is_comment_legal(ua, rx.comment)) { goto bail_out; } } i = find_arg_with_value(ua, "backupformat"); if (i >= 0) { rx.backup_format = ua->argv[i]; } i = find_arg_with_value(ua, "where"); if (i >= 0) { rx.where = ua->argv[i]; } i = find_arg_with_value(ua, "replace"); if (i >= 0) { rx.replace = ua->argv[i]; } i = find_arg_with_value(ua, "pluginoptions"); if (i >= 0) { rx.plugin_options = ua->argv[i]; } i = find_arg_with_value(ua, "strip_prefix"); if (i >= 0) { strip_prefix = ua->argv[i]; } i = find_arg_with_value(ua, "add_prefix"); if (i >= 0) { add_prefix = ua->argv[i]; } i = find_arg_with_value(ua, "add_suffix"); if (i >= 0) { add_suffix = ua->argv[i]; } i = find_arg_with_value(ua, "regexwhere"); if (i >= 0) { rx.RegexWhere = ua->argv[i]; } if (strip_prefix || add_suffix || add_prefix) { int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix); regexp = (char *)bmalloc(len * sizeof(char)); bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix); rx.RegexWhere = regexp; } /* TODO: add acl for regexwhere ? */ if (rx.RegexWhere) { if (!acl_access_ok(ua, Where_ACL, rx.RegexWhere, true)) { ua->error_msg(_("\"RegexWhere\" specification not authorized.\n")); goto bail_out; } } if (rx.where) { if (!acl_access_ok(ua, Where_ACL, rx.where, true)) { ua->error_msg(_("\"where\" specification not authorized.\n")); goto bail_out; } } if (!open_client_db(ua, true)) { goto bail_out; } /* Ensure there is at least one Restore Job */ LockRes(); foreach_res(job, R_JOB) { if (job->JobType == JT_RESTORE) { if (!rx.restore_job) { rx.restore_job = job; } rx.restore_jobs++; } } UnlockRes(); if (!rx.restore_jobs) { ua->error_msg(_( "No Restore Job Resource found in bareos-dir.conf.\n" "You must create at least one before running this command.\n")); goto bail_out; } /* * Request user to select JobIds or files by various different methods * last 20 jobs, where File saved, most recent backup, ... * In the end, a list of files are pumped into * add_findex() */ switch (user_select_jobids_or_files(ua, &rx)) { case 0: /* error */ goto bail_out; case 1: /* selected by jobid */ get_and_display_basejobs(ua, &rx); if (!build_directory_tree(ua, &rx)) { ua->send_msg(_("Restore not done.\n")); goto bail_out; } break; case 2: /* selected by filename, no tree needed */ break; } if (rx.bsr->JobId) { char ed1[50]; if (!complete_bsr(ua, rx.bsr)) { /* find Vol, SessId, SessTime from JobIds */ ua->error_msg(_("Unable to construct a valid BSR. Cannot continue.\n")); goto bail_out; } if (!(rx.selected_files = write_bsr_file(ua, rx))) { ua->warning_msg(_("No files selected to be restored.\n")); goto bail_out; } display_bsr_info(ua, rx); /* display vols needed, etc */ if (rx.selected_files==1) { ua->info_msg(_("\n1 file selected to be restored.\n\n")); } else { ua->info_msg(_("\n%s files selected to be restored.\n\n"), edit_uint64_with_commas(rx.selected_files, ed1)); } } else { ua->warning_msg(_("No files selected to be restored.\n")); goto bail_out; } if (rx.restore_jobs == 1) { job = rx.restore_job; } else { job = get_restore_job(ua); } if (!job) { goto bail_out; } get_client_name(ua, &rx); if (!rx.ClientName) { ua->error_msg(_("No Client resource found!\n")); goto bail_out; } get_restore_client_name(ua, rx); escaped_bsr_name = escape_filename(jcr->RestoreBootstrap); Mmsg(ua->cmd, "run job=\"%s\" client=\"%s\" restoreclient=\"%s\" storage=\"%s\"" " bootstrap=\"%s\" files=%u catalog=\"%s\"", job->name(), rx.ClientName, rx.RestoreClientName, rx.store?rx.store->name():"", escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap, rx.selected_files, ua->catalog->name()); /* * Build run command */ if (rx.backup_format) { Mmsg(buf, " backupformat=%s", rx.backup_format); pm_strcat(ua->cmd, buf); } pm_strcpy(buf, ""); if (rx.RegexWhere) { escaped_where_name = escape_filename(rx.RegexWhere); Mmsg(buf, " regexwhere=\"%s\"", escaped_where_name ? escaped_where_name : rx.RegexWhere); } else if (rx.where) { escaped_where_name = escape_filename(rx.where); Mmsg(buf," where=\"%s\"", escaped_where_name ? escaped_where_name : rx.where); } pm_strcat(ua->cmd, buf); if (rx.replace) { Mmsg(buf, " replace=%s", rx.replace); pm_strcat(ua->cmd, buf); } if (rx.plugin_options) { Mmsg(buf, " pluginoptions=%s", rx.plugin_options); pm_strcat(ua->cmd, buf); } if (rx.comment) { Mmsg(buf, " comment=\"%s\"", rx.comment); pm_strcat(ua->cmd, buf); } if (escaped_bsr_name != NULL) { bfree(escaped_bsr_name); } if (escaped_where_name != NULL) { bfree(escaped_where_name); } if (regexp) { bfree(regexp); } if (find_arg(ua, NT_("yes")) > 0) { pm_strcat(ua->cmd, " yes"); /* pass it on to the run command */ } Dmsg1(200, "Submitting: %s\n", ua->cmd); /* * Transfer jobids to jcr to for picking up restore objects */ jcr->JobIds = rx.JobIds; rx.JobIds = NULL; parse_ua_args(ua); run_cmd(ua, ua->cmd); free_rx(&rx); garbage_collect_memory(); /* release unused memory */ return 1; bail_out: if (escaped_bsr_name != NULL) { bfree(escaped_bsr_name); } if (escaped_where_name != NULL) { bfree(escaped_where_name); } if (regexp) { bfree(regexp); } free_rx(&rx); garbage_collect_memory(); /* release unused memory */ return 0; } /* * Fill the rx->BaseJobIds and display the list */ static void get_and_display_basejobs(UAContext *ua, RESTORE_CTX *rx) { db_list_ctx jobids; if (!db_get_used_base_jobids(ua->jcr, ua->db, rx->JobIds, &jobids)) { ua->warning_msg("%s", db_strerror(ua->db)); } if (jobids.count) { POOL_MEM q; Mmsg(q, uar_print_jobs, jobids.list); ua->send_msg(_("The restore will use the following job(s) as Base\n")); db_list_sql_query(ua->jcr, ua->db, q.c_str(), printit, ua, true, HORZ_LIST); } pm_strcpy(rx->BaseJobIds, jobids.list); } static void free_rx(RESTORE_CTX *rx) { free_bsr(rx->bsr); rx->bsr = NULL; if (rx->ClientName) { free(rx->ClientName); rx->ClientName = NULL; } if (rx->RestoreClientName) { free(rx->RestoreClientName); rx->RestoreClientName = NULL; } free_and_null_pool_memory(rx->JobIds); free_and_null_pool_memory(rx->BaseJobIds); free_and_null_pool_memory(rx->fname); free_and_null_pool_memory(rx->path); free_and_null_pool_memory(rx->query); free_name_list(&rx->name_list); } static bool has_value(UAContext *ua, int i) { if (!ua->argv[i]) { ua->error_msg(_("Missing value for keyword: %s\n"), ua->argk[i]); return false; } return true; } /* * This gets the client name from which the backup was made */ static int get_client_name(UAContext *ua, RESTORE_CTX *rx) { int i; CLIENT_DBR cr; /* * If no client name specified yet, get it now */ if (!rx->ClientName) { /* * Try command line argument */ i = find_arg_with_value(ua, NT_("client")); if (i < 0) { i = find_arg_with_value(ua, NT_("backupclient")); } if (i >= 0) { if (!is_name_valid(ua->argv[i], &ua->errmsg)) { ua->error_msg("%s argument: %s", ua->argk[i], ua->errmsg); return 0; } rx->ClientName = bstrdup(ua->argv[i]); return 1; } memset(&cr, 0, sizeof(cr)); if (!get_client_dbr(ua, &cr)) { return 0; } rx->ClientName = bstrdup(cr.Name); } return 1; } /* * This is where we pick up a client name to restore to. */ static int get_restore_client_name(UAContext *ua, RESTORE_CTX &rx) { int i; /* * Try command line argument */ i = find_arg_with_value(ua, NT_("restoreclient")); if (i >= 0) { if (!is_name_valid(ua->argv[i], &ua->errmsg)) { ua->error_msg("%s argument: %s", ua->argk[i], ua->errmsg); return 0; } rx.RestoreClientName = bstrdup(ua->argv[i]); return 1; } rx.RestoreClientName = bstrdup(rx.ClientName); return 1; } /* * The first step in the restore process is for the user to * select a list of JobIds from which he will subsequently * select which files are to be restored. * * Returns: 2 if filename list made * 1 if jobid list made * 0 on error */ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx) { char *p; char date[MAX_TIME_LENGTH]; bool have_date = false; /* Include current second if using current time */ utime_t now = time(NULL) + 1; JobId_t JobId; JOB_DBR jr = { (JobId_t)-1 }; bool done = false; int i, j; const char *list[] = { _("List last 20 Jobs run"), _("List Jobs where a given File is saved"), _("Enter list of comma separated JobIds to select"), _("Enter SQL list command"), _("Select the most recent backup for a client"), _("Select backup for a client before a specified time"), _("Enter a list of files to restore"), _("Enter a list of files to restore before a specified time"), _("Find the JobIds of the most recent backup for a client"), _("Find the JobIds for a backup for a client before a specified time"), _("Enter a list of directories to restore for found JobIds"), _("Select full restore to a specified Job date"), _("Cancel"), NULL }; const char *kw[] = { /* * These keywords are handled in a for loop */ "jobid", /* 0 */ "current", /* 1 */ "before", /* 2 */ "file", /* 3 */ "directory", /* 4 */ "select", /* 5 */ "pool", /* 6 */ "all", /* 7 */ /* * The keyword below are handled by individual arg lookups */ "client", /* 8 */ "storage", /* 9 */ "fileset", /* 10 */ "where", /* 11 */ "yes", /* 12 */ "bootstrap", /* 13 */ "done", /* 14 */ "strip_prefix", /* 15 */ "add_prefix", /* 16 */ "add_suffix", /* 17 */ "regexwhere", /* 18 */ "restoreclient", /* 19 */ "copies", /* 20 */ "comment", /* 21 */ "restorejob", /* 22 */ "replace", /* 23 */ "pluginoptions", /* 24 */ NULL }; rx->JobIds[0] = 0; for (i = 1; iargc; i++) { /* loop through arguments */ bool found_kw = false; for (j = 0; kw[j]; j++) { /* loop through keywords */ if (bstrcasecmp(kw[j], ua->argk[i])) { found_kw = true; break; } } if (!found_kw) { ua->error_msg(_("Unknown keyword: %s\n"), ua->argk[i]); return 0; } /* Found keyword in kw[] list, process it */ switch (j) { case 0: /* jobid */ if (!has_value(ua, i)) { return 0; } if (*rx->JobIds != 0) { pm_strcat(rx->JobIds, ","); } pm_strcat(rx->JobIds, ua->argv[i]); done = true; break; case 1: /* current */ /* * Note, we add one second here just to include any job * that may have finished within the current second, * which happens a lot in scripting small jobs. */ bstrutime(date, sizeof(date), now); have_date = true; break; case 2: /* before */ if (have_date || !has_value(ua, i)) { return 0; } if (str_to_utime(ua->argv[i]) == 0) { ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]); return 0; } bstrncpy(date, ua->argv[i], sizeof(date)); have_date = true; break; case 3: /* file */ case 4: /* dir */ if (!has_value(ua, i)) { return 0; } if (!have_date) { bstrutime(date, sizeof(date), now); } if (!get_client_name(ua, rx)) { return 0; } pm_strcpy(ua->cmd, ua->argv[i]); insert_one_file_or_dir(ua, rx, date, j==4); return 2; case 5: /* select */ if (!have_date) { bstrutime(date, sizeof(date), now); } if (!select_backups_before_date(ua, rx, date)) { return 0; } done = true; break; case 6: /* pool specified */ if (!has_value(ua, i)) { return 0; } rx->pool = (POOLRES *)GetResWithName(R_POOL, ua->argv[i]); if (!rx->pool) { ua->error_msg(_("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]); return 0; } if (!acl_access_ok(ua, Pool_ACL, ua->argv[i], true)) { rx->pool = NULL; ua->error_msg(_("Error: Pool resource \"%s\" access not allowed.\n"), ua->argv[i]); return 0; } break; case 7: /* all specified */ rx->all = true; break; default: /* * All keywords 7 or greater are ignored or handled by a select prompt */ break; } } if (!done) { ua->send_msg(_("\nFirst you select one or more JobIds that contain files\n" "to be restored. You will be presented several methods\n" "of specifying the JobIds. Then you will be allowed to\n" "select which files from those JobIds are to be restored.\n\n")); } /* If choice not already made above, prompt */ for ( ; !done; ) { char *fname; int len; bool gui_save; db_list_ctx jobids; start_prompt(ua, _("To select the JobIds, you have the following choices:\n")); for (int i=0; list[i]; i++) { add_prompt(ua, list[i]); } done = true; switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) { case -1: /* error or cancel */ return 0; case 0: /* list last 20 Jobs run */ if (!acl_access_ok(ua, Command_ACL, NT_("sqlquery"), true)) { ua->error_msg(_("SQL query not authorized.\n")); return 0; } gui_save = ua->jcr->gui; ua->jcr->gui = true; db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, printit, ua, true, HORZ_LIST); ua->jcr->gui = gui_save; done = false; break; case 1: /* list where a file is saved */ if (!get_client_name(ua, rx)) { return 0; } if (!get_cmd(ua, _("Enter Filename (no path):"))) { return 0; } len = strlen(ua->cmd); fname = (char *)malloc(len * 2 + 1); db_escape_string(ua->jcr, ua->db, fname, ua->cmd, len); Mmsg(rx->query, uar_file[db_get_type_index(ua->db)], rx->ClientName, fname); free(fname); gui_save = ua->jcr->gui; ua->jcr->gui = true; db_list_sql_query(ua->jcr, ua->db, rx->query, printit, ua, true, HORZ_LIST); ua->jcr->gui = gui_save; done = false; break; case 2: /* enter a list of JobIds */ if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { return 0; } pm_strcpy(rx->JobIds, ua->cmd); break; case 3: /* Enter an SQL list command */ if (!acl_access_ok(ua, Command_ACL, NT_("sqlquery"), true)) { ua->error_msg(_("SQL query not authorized.\n")); return 0; } if (!get_cmd(ua, _("Enter SQL list command: "))) { return 0; } gui_save = ua->jcr->gui; ua->jcr->gui = true; db_list_sql_query(ua->jcr, ua->db, ua->cmd, printit, ua, true, HORZ_LIST); ua->jcr->gui = gui_save; done = false; break; case 4: /* Select the most recent backups */ if (!have_date) { bstrutime(date, sizeof(date), now); } if (!select_backups_before_date(ua, rx, date)) { return 0; } break; case 5: /* select backup at specified time */ if (!have_date) { if (!get_date(ua, date, sizeof(date))) { return 0; } } if (!select_backups_before_date(ua, rx, date)) { return 0; } break; case 6: /* Enter files */ if (!have_date) { bstrutime(date, sizeof(date), now); } if (!get_client_name(ua, rx)) { return 0; } ua->send_msg(_("Enter file names with paths, or < to enter a filename\n" "containing a list of file names with paths, and terminate\n" "them with a blank line.\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { return 0; } len = strlen(ua->cmd); if (len == 0) { break; } insert_one_file_or_dir(ua, rx, date, false); } return 2; case 7: /* enter files backed up before specified time */ if (!have_date) { if (!get_date(ua, date, sizeof(date))) { return 0; } } if (!get_client_name(ua, rx)) { return 0; } ua->send_msg(_("Enter file names with paths, or < to enter a filename\n" "containing a list of file names with paths, and terminate\n" "them with a blank line.\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter full filename: "))) { return 0; } len = strlen(ua->cmd); if (len == 0) { break; } insert_one_file_or_dir(ua, rx, date, false); } return 2; case 8: /* Find JobIds for current backup */ if (!have_date) { bstrutime(date, sizeof(date), now); } if (!select_backups_before_date(ua, rx, date)) { return 0; } done = false; break; case 9: /* Find JobIds for give date */ if (!have_date) { if (!get_date(ua, date, sizeof(date))) { return 0; } } if (!select_backups_before_date(ua, rx, date)) { return 0; } done = false; break; case 10: /* Enter directories */ if (*rx->JobIds != 0) { ua->send_msg(_("You have already selected the following JobIds: %s\n"), rx->JobIds); } else if (get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) { if (*rx->JobIds != 0 && *ua->cmd) { pm_strcat(rx->JobIds, ","); } pm_strcat(rx->JobIds, ua->cmd); } if (*rx->JobIds == 0 || *rx->JobIds == '.') { *rx->JobIds = 0; return 0; /* nothing entered, return */ } if (!have_date) { bstrutime(date, sizeof(date), now); } if (!get_client_name(ua, rx)) { return 0; } ua->send_msg(_("Enter full directory names or start the name\n" "with a < to indicate it is a filename containing a list\n" "of directories and terminate them with a blank line.\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter directory name: "))) { return 0; } len = strlen(ua->cmd); if (len == 0) { break; } /* Add trailing slash to end of directory names */ if (ua->cmd[0] != '<' && !IsPathSeparator(ua->cmd[len-1])) { strcat(ua->cmd, "/"); } insert_one_file_or_dir(ua, rx, date, true); } return 2; case 11: /* Choose a jobid and select jobs */ if (!get_cmd(ua, _("Enter JobId to get the state to restore: ")) || !is_an_integer(ua->cmd)) { return 0; } memset(&jr, 0, sizeof(jr)); jr.JobId = str_to_int64(ua->cmd); if (!db_get_job_record(ua->jcr, ua->db, &jr)) { ua->error_msg(_("Unable to get Job record for JobId=%s: ERR=%s\n"), ua->cmd, db_strerror(ua->db)); return 0; } ua->send_msg(_("Selecting jobs to build the Full state at %s\n"), jr.cStartTime); jr.JobLevel = L_INCREMENTAL; /* Take Full+Diff+Incr */ if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, &jobids)) { return 0; } pm_strcpy(rx->JobIds, jobids.list); Dmsg1(30, "Item 12: jobids = %s\n", rx->JobIds); break; case 12: /* Cancel or quit */ return 0; } } memset(&jr, 0, sizeof(jr)); POOLMEM *JobIds = get_pool_memory(PM_FNAME); *JobIds = 0; rx->TotalFiles = 0; /* * Find total number of files to be restored, and filter the JobId * list to contain only ones permitted by the ACL conditions. */ for (p=rx->JobIds; ; ) { char ed1[50]; int status = get_next_jobid_from_list(&p, &JobId); if (status < 0) { ua->error_msg(_("Invalid JobId in list.\n")); free_pool_memory(JobIds); return 0; } if (status == 0) { break; } if (jr.JobId == JobId) { continue; /* duplicate of last JobId */ } memset(&jr, 0, sizeof(jr)); jr.JobId = JobId; if (!db_get_job_record(ua->jcr, ua->db, &jr)) { ua->error_msg(_("Unable to get Job record for JobId=%s: ERR=%s\n"), edit_int64(JobId, ed1), db_strerror(ua->db)); free_pool_memory(JobIds); return 0; } if (!acl_access_ok(ua, Job_ACL, jr.Name, true)) { ua->error_msg(_("Access to JobId=%s (Job \"%s\") not authorized. Not selected.\n"), edit_int64(JobId, ed1), jr.Name); continue; } if (*JobIds != 0) { pm_strcat(JobIds, ","); } pm_strcat(JobIds, edit_int64(JobId, ed1)); rx->TotalFiles += jr.JobFiles; } free_pool_memory(rx->JobIds); rx->JobIds = JobIds; /* Set ACL filtered list */ if (*rx->JobIds == 0) { ua->warning_msg(_("No Jobs selected.\n")); return 0; } if (strchr(rx->JobIds,',')) { ua->info_msg(_("You have selected the following JobIds: %s\n"), rx->JobIds); } else { ua->info_msg(_("You have selected the following JobId: %s\n"), rx->JobIds); } return 1; } /* * Get date from user */ static bool get_date(UAContext *ua, char *date, int date_len) { ua->send_msg(_("The restored files will the most current backup\n" "BEFORE the date you specify below.\n\n")); for ( ;; ) { if (!get_cmd(ua, _("Enter date as YYYY-MM-DD HH:MM:SS :"))) { return false; } if (str_to_utime(ua->cmd) != 0) { break; } ua->error_msg(_("Improper date format.\n")); } bstrncpy(date, ua->cmd, date_len); return true; } /* * Insert a single file, or read a list of files from a file */ static void insert_one_file_or_dir(UAContext *ua, RESTORE_CTX *rx, char *date, bool dir) { FILE *ffd; char file[5000]; char *p = ua->cmd; int line = 0; switch (*p) { case '<': p++; if ((ffd = fopen(p, "rb")) == NULL) { berrno be; ua->error_msg(_("Cannot open file %s: ERR=%s\n"), p, be.bstrerror()); break; } while (fgets(file, sizeof(file), ffd)) { line++; if (dir) { if (!insert_dir_into_findex_list(ua, rx, file, date)) { ua->error_msg(_("Error occurred on line %d of file \"%s\"\n"), line, p); } } else { if (!insert_file_into_findex_list(ua, rx, file, date)) { ua->error_msg(_("Error occurred on line %d of file \"%s\"\n"), line, p); } } } fclose(ffd); break; case '?': p++; insert_table_into_findex_list(ua, rx, p); break; default: if (dir) { insert_dir_into_findex_list(ua, rx, ua->cmd, date); } else { insert_file_into_findex_list(ua, rx, ua->cmd, date); } break; } } /* * For a given file (path+filename), split into path and file, then * lookup the most recent backup in the catalog to get the JobId * and FileIndex, then insert them into the findex list. */ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *file, char *date) { strip_trailing_newline(file); split_path_and_filename(ua, rx, file); if (*rx->JobIds == 0) { Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, rx->ClientName); } else { Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date, rx->path, rx->fname, rx->ClientName); } rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { ua->error_msg(_("Query failed: %s. ERR=%s\n"), rx->query, db_strerror(ua->db)); } if (!rx->found) { ua->error_msg(_("No database record found for: %s\n"), file); // ua->error_msg("Query=%s\n", rx->query); return true; } return true; } /* * For a given path lookup the most recent backup in the catalog * to get the JobId and FileIndexes of all files in that directory. */ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir, char *date) { strip_trailing_junk(dir); if (*rx->JobIds == 0) { ua->error_msg(_("No JobId specified cannot continue.\n")); return false; } else { Mmsg(rx->query, uar_jobid_fileindex_from_dir[db_get_type_index(ua->db)], rx->JobIds, dir, rx->ClientName); } rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { ua->error_msg(_("Query failed: %s. ERR=%s\n"), rx->query, db_strerror(ua->db)); } if (!rx->found) { ua->error_msg(_("No database record found for: %s\n"), dir); return true; } return true; } /* * Get the JobId and FileIndexes of all files in the specified table */ static bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table) { strip_trailing_junk(table); Mmsg(rx->query, uar_jobid_fileindex_from_table, table); rx->found = false; /* Find and insert jobid and File Index */ if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) { ua->error_msg(_("Query failed: %s. ERR=%s\n"), rx->query, db_strerror(ua->db)); } if (!rx->found) { ua->error_msg(_("No table found: %s\n"), table); return true; } return true; } static void split_path_and_filename(UAContext *ua, RESTORE_CTX *rx, char *name) { char *p, *f; /* Find path without the filename. * I.e. everything after the last / is a "filename". * OK, maybe it is a directory name, but we treat it like * a filename. If we don't find a / then the whole name * must be a path name (e.g. c:). */ for (p=f=name; *p; p++) { if (IsPathSeparator(*p)) { f = p; /* set pos of last slash */ } } if (IsPathSeparator(*f)) { /* did we find a slash? */ f++; /* yes, point to filename */ } else { /* no, whole thing must be path name */ f = p; } /* If filename doesn't exist (i.e. root directory), we * simply create a blank name consisting of a single * space. This makes handling zero length filenames * easier. */ rx->fnl = p - f; if (rx->fnl > 0) { rx->fname = check_pool_memory_size(rx->fname, 2*(rx->fnl)+1); db_escape_string(ua->jcr, ua->db, rx->fname, f, rx->fnl); } else { rx->fname[0] = 0; rx->fnl = 0; } rx->pnl = f - name; if (rx->pnl > 0) { rx->path = check_pool_memory_size(rx->path, 2*(rx->pnl)+1); db_escape_string(ua->jcr, ua->db, rx->path, name, rx->pnl); } else { rx->path[0] = 0; rx->pnl = 0; } Dmsg2(100, "split path=%s file=%s\n", rx->path, rx->fname); } static bool ask_for_fileregex(UAContext *ua, RESTORE_CTX *rx) { if (find_arg(ua, NT_("all")) >= 0) { /* if user enters all on command line */ return true; /* select everything */ } ua->send_msg(_("\n\nFor one or more of the JobIds selected, no files were found,\n" "so file selection is not possible.\n" "Most likely your retention policy pruned the files.\n")); if (get_yesno(ua, _("\nDo you want to restore all the files? (yes|no): "))) { if (ua->pint32_val == 1) return true; while (get_cmd(ua, _("\nRegexp matching files to restore? (empty to abort): "))) { if (ua->cmd[0] == '\0') { break; } else { regex_t *fileregex_re = NULL; int rc; char errmsg[500] = ""; fileregex_re = (regex_t *)bmalloc(sizeof(regex_t)); rc = regcomp(fileregex_re, ua->cmd, REG_EXTENDED|REG_NOSUB); if (rc != 0) { regerror(rc, fileregex_re, errmsg, sizeof(errmsg)); } regfree(fileregex_re); free(fileregex_re); if (*errmsg) { ua->send_msg(_("Regex compile error: %s\n"), errmsg); } else { rx->bsr->fileregex = bstrdup(ua->cmd); return true; } } } } return false; } /* Walk on the delta_list of a TREE_NODE item and insert all parts * TODO: Optimize for bootstrap creation, remove recursion * 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 * should insert as * 0, 1, 2, 3, 4, 5, 6 */ static void add_delta_list_findex(RESTORE_CTX *rx, struct delta_list *lst) { if (lst == NULL) { return; } if (lst->next) { add_delta_list_findex(rx, lst->next); } add_findex(rx->bsr, lst->JobId, lst->FileIndex); } static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx) { TREE_CTX tree; JobId_t JobId, last_JobId; char *p; bool OK = true; char ed1[50]; memset(&tree, 0, sizeof(tree)); /* * Build the directory tree containing JobIds user selected */ tree.root = new_tree(rx->TotalFiles); tree.ua = ua; tree.all = rx->all; last_JobId = 0; /* * For display purposes, the same JobId, with different volumes may * appear more than once, however, we only insert it once. */ p = rx->JobIds; tree.FileEstimate = 0; if (get_next_jobid_from_list(&p, &JobId) > 0) { /* * Use first JobId as estimate of the number of files to restore */ Mmsg(rx->query, uar_count_files, edit_int64(JobId, ed1)); if (!db_sql_query(ua->db, rx->query, restore_count_handler, (void *)rx)) { ua->error_msg("%s\n", db_strerror(ua->db)); } if (rx->found) { /* * Add about 25% more than this job for over estimate */ tree.FileEstimate = rx->JobId + (rx->JobId >> 2); tree.DeltaCount = rx->JobId / 50; /* print 50 ticks */ } } ua->info_msg(_("\nBuilding directory tree for JobId(s) %s ... "), rx->JobIds); if (!db_get_file_list(ua->jcr, ua->db, rx->JobIds, false /* do not use md5 */, true /* get delta */, insert_tree_handler, (void *)&tree)) { ua->error_msg("%s", db_strerror(ua->db)); } if (*rx->BaseJobIds) { pm_strcat(rx->JobIds, ","); pm_strcat(rx->JobIds, rx->BaseJobIds); } /* * At this point, the tree is built, so we can garbage collect * any memory released by the SQL engine that RedHat has * not returned to the OS :-( */ garbage_collect_memory(); /* * Look at the first JobId on the list (presumably the oldest) and * if it is marked purged, don't do the manual selection because * the Job was pruned, so the tree is incomplete. */ if (tree.FileCount != 0) { /* * Find out if any Job is purged */ Mmsg(rx->query, "SELECT SUM(PurgedFiles) FROM Job WHERE JobId IN (%s)", rx->JobIds); if (!db_sql_query(ua->db, rx->query, restore_count_handler, (void *)rx)) { ua->error_msg("%s\n", db_strerror(ua->db)); } /* * rx->JobId is the PurgedFiles flag */ if (rx->found && rx->JobId > 0) { tree.FileCount = 0; /* set count to zero, no tree selection */ } } if (tree.FileCount == 0) { OK = ask_for_fileregex(ua, rx); if (OK) { last_JobId = 0; for (p=rx->JobIds; get_next_jobid_from_list(&p, &JobId) > 0; ) { if (JobId == last_JobId) { continue; /* eliminate duplicate JobIds */ } add_findex_all(rx->bsr, JobId); } } } else { char ec1[50]; if (tree.all) { ua->info_msg(_("\n%s files inserted into the tree and marked for extraction.\n"), edit_uint64_with_commas(tree.FileCount, ec1)); } else { ua->info_msg(_("\n%s files inserted into the tree.\n"), edit_uint64_with_commas(tree.FileCount, ec1)); } if (find_arg(ua, NT_("done")) < 0) { /* * Let the user interact in selecting which files to restore */ OK = user_select_files_from_tree(&tree); } /* * Walk down through the tree finding all files marked to be * extracted making a bootstrap file. */ if (OK) { for (TREE_NODE *node=first_tree_node(tree.root); node; node=next_tree_node(node)) { Dmsg2(400, "FI=%d node=0x%x\n", node->FileIndex, node); if (node->extract || node->extract_dir) { Dmsg3(400, "JobId=%lld type=%d FI=%d\n", (uint64_t)node->JobId, node->type, node->FileIndex); /* TODO: optimize bsr insertion when jobid are non sorted */ add_delta_list_findex(rx, node->delta_list); add_findex(rx->bsr, node->JobId, node->FileIndex); if (node->extract && node->type != TN_NEWDIR) { rx->selected_files++; /* count only saved files */ } } } } } /* * We keep the tree with selected restore files. * For NDMP restores its used in the DMA to know what to restore. * The tree is freed by the DMA when its done. */ ua->jcr->restore_tree_root = tree.root; return OK; } /* * This routine is used to get the current backup or a backup before the specified date. */ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *date) { bool ok = false; FILESET_DBR fsr; CLIENT_DBR cr; char fileset_name[MAX_NAME_LENGTH]; char ed1[50], ed2[50]; char pool_select[MAX_NAME_LENGTH]; int i; /* Create temp tables */ db_sql_query(ua->db, uar_del_temp); db_sql_query(ua->db, uar_del_temp1); if (!db_sql_query(ua->db, uar_create_temp[db_get_type_index(ua->db)])) { ua->error_msg("%s\n", db_strerror(ua->db)); } if (!db_sql_query(ua->db, uar_create_temp1[db_get_type_index(ua->db)])) { ua->error_msg("%s\n", db_strerror(ua->db)); } /* * Select Client from the Catalog */ memset(&cr, 0, sizeof(cr)); if (!get_client_dbr(ua, &cr)) { goto bail_out; } rx->ClientName = bstrdup(cr.Name); /* * Get FileSet */ memset(&fsr, 0, sizeof(fsr)); i = find_arg_with_value(ua, "FileSet"); if (i >= 0 && is_name_valid(ua->argv[i], &ua->errmsg)) { bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet)); if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) { ua->error_msg(_("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet, db_strerror(ua->db)); i = -1; } } else if (i >= 0) { /* name is invalid */ ua->error_msg(_("FileSet argument: %s\n"), ua->errmsg); } if (i < 0) { /* fileset not found */ edit_int64(cr.ClientId, ed1); Mmsg(rx->query, uar_sel_fileset, ed1, ed1); start_prompt(ua, _("The defined FileSet resources are:\n")); if (!db_sql_query(ua->db, rx->query, fileset_handler, (void *)ua)) { ua->error_msg("%s\n", db_strerror(ua->db)); } if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), fileset_name, sizeof(fileset_name)) < 0) { ua->error_msg(_("No FileSet found for client \"%s\".\n"), cr.Name); goto bail_out; } bstrncpy(fsr.FileSet, fileset_name, sizeof(fsr.FileSet)); if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) { ua->warning_msg(_("Error getting FileSet record: %s\n"), db_strerror(ua->db)); ua->send_msg(_("This probably means you modified the FileSet.\n" "Continuing anyway.\n")); } } /* * If Pool specified, add PoolId specification */ pool_select[0] = 0; if (rx->pool) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, rx->pool->name(), sizeof(pr.Name)); if (db_get_pool_record(ua->jcr, ua->db, &pr)) { bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ", edit_int64(pr.PoolId, ed1)); } else { ua->warning_msg(_("Pool \"%s\" not found, using any pool.\n"), pr.Name); } } /* * Find JobId of last Full backup for this client, fileset */ if (pool_select[0]) { edit_int64(cr.ClientId, ed1); Mmsg(rx->query, uar_last_full, ed1, date, fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query)) { ua->error_msg("%s\n", db_strerror(ua->db)); goto bail_out; } } else { edit_int64(cr.ClientId, ed1); Mmsg(rx->query, uar_last_full_no_pool, ed1, date, fsr.FileSet); if (!db_sql_query(ua->db, rx->query)) { ua->error_msg("%s\n", db_strerror(ua->db)); goto bail_out; } } /* * Find all Volumes used by that JobId */ if (!db_sql_query(ua->db, uar_full)) { ua->error_msg("%s\n", db_strerror(ua->db)); goto bail_out; } /* * Note, this is needed because I don't seem to get the callback from the call just above. */ rx->JobTDate = 0; if (!db_sql_query(ua->db, uar_sel_all_temp1, last_full_handler, (void *)rx)) { ua->warning_msg("%s\n", db_strerror(ua->db)); } if (rx->JobTDate == 0) { ua->error_msg(_("No Full backup before %s found.\n"), date); goto bail_out; } /* * Now find most recent Differental Job after Full save, if any */ Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date, edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query)) { ua->warning_msg("%s\n", db_strerror(ua->db)); } /* * Now update JobTDate to look into Differental, if any */ rx->JobTDate = 0; if (!db_sql_query(ua->db, uar_sel_all_temp, last_full_handler, (void *)rx)) { ua->warning_msg("%s\n", db_strerror(ua->db)); } if (rx->JobTDate == 0) { ua->error_msg(_("No Full backup before %s found.\n"), date); goto bail_out; } /* * Now find all Incremental Jobs after Full/dif save */ Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date, edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select); if (!db_sql_query(ua->db, rx->query)) { ua->warning_msg("%s\n", db_strerror(ua->db)); } /* * Get the JobIds from that list */ rx->last_jobid[0] = rx->JobIds[0] = 0; if (!db_sql_query(ua->db, uar_sel_jobid_temp, jobid_handler, (void *)rx)) { ua->warning_msg("%s\n", db_strerror(ua->db)); } if (rx->JobIds[0] != 0) { if (find_arg(ua, NT_("copies")) > 0) { /* * Display a list of all copies */ db_list_copies_records(ua->jcr, ua->db, 0, rx->JobIds, printit, ua, HORZ_LIST); } /* * Display a list of Jobs selected for this restore */ db_list_sql_query(ua->jcr, ua->db, uar_list_temp, printit, ua, true, HORZ_LIST); ok = true; } else { ua->warning_msg(_("No jobs found.\n")); } bail_out: db_sql_query(ua->db, uar_del_temp); db_sql_query(ua->db, uar_del_temp1); return ok; } static int restore_count_handler(void *ctx, int num_fields, char **row) { RESTORE_CTX *rx = (RESTORE_CTX *)ctx; rx->JobId = str_to_int64(row[0]); rx->found = true; return 0; } /* * Callback handler to get JobId and FileIndex for files * can insert more than one depending on the caller. */ static int jobid_fileindex_handler(void *ctx, int num_fields, char **row) { RESTORE_CTX *rx = (RESTORE_CTX *)ctx; Dmsg2(200, "JobId=%s FileIndex=%s\n", row[0], row[1]); rx->JobId = str_to_int64(row[0]); add_findex(rx->bsr, rx->JobId, str_to_int64(row[1])); rx->found = true; rx->selected_files++; return 0; } /* * Callback handler make list of JobIds */ static int jobid_handler(void *ctx, int num_fields, char **row) { RESTORE_CTX *rx = (RESTORE_CTX *)ctx; if (bstrcmp(rx->last_jobid, row[0])) { return 0; /* duplicate id */ } bstrncpy(rx->last_jobid, row[0], sizeof(rx->last_jobid)); if (rx->JobIds[0] != 0) { pm_strcat(rx->JobIds, ","); } pm_strcat(rx->JobIds, row[0]); return 0; } /* * Callback handler to pickup last Full backup JobTDate */ static int last_full_handler(void *ctx, int num_fields, char **row) { RESTORE_CTX *rx = (RESTORE_CTX *)ctx; rx->JobTDate = str_to_int64(row[1]); return 0; } /* * Callback handler build FileSet name prompt list */ static int fileset_handler(void *ctx, int num_fields, char **row) { /* row[0] = FileSet (name) */ if (row[0]) { add_prompt((UAContext *)ctx, row[0]); } return 0; } /* * Free names in the list */ static void free_name_list(NAME_LIST *name_list) { int i; for (i = 0; i < name_list->num_ids; i++) { free(name_list->name[i]); } bfree_and_null(name_list->name); name_list->max_ids = 0; name_list->num_ids = 0; } void find_storage_resource(UAContext *ua, RESTORE_CTX &rx, char *Storage, char *MediaType) { STORERES *store; if (rx.store) { Dmsg1(200, "Already have store=%s\n", rx.store->name()); return; } /* * Try looking up Storage by name */ LockRes(); foreach_res(store, R_STORAGE) { if (bstrcmp(Storage, store->name())) { if (acl_access_ok(ua, Storage_ACL, store->name())) { rx.store = store; } break; } } UnlockRes(); if (rx.store) { int i; /* * Check if an explicit storage resource is given */ store = NULL; i = find_arg_with_value(ua, "storage"); if (i > 0) { store = (STORERES *)GetResWithName(R_STORAGE, ua->argv[i]); if (store && !acl_access_ok(ua, Storage_ACL, store->name(), true)) { store = NULL; } } if (store && (store != rx.store)) { ua->info_msg(_("Warning default storage overridden by \"%s\" on command line.\n"), store->name()); rx.store = store; Dmsg1(200, "Set store=%s\n", rx.store->name()); } return; } /* * If no storage resource, try to find one from MediaType */ if (!rx.store) { LockRes(); foreach_res(store, R_STORAGE) { if (bstrcmp(MediaType, store->media_type)) { if (acl_access_ok(ua, Storage_ACL, store->name())) { rx.store = store; Dmsg1(200, "Set store=%s\n", rx.store->name()); if (Storage == NULL) { ua->warning_msg(_("Using Storage \"%s\" from MediaType \"%s\".\n"), store->name(), MediaType); } else { ua->warning_msg(_("Storage \"%s\" not found, using Storage \"%s\" from MediaType \"%s\".\n"), Storage, store->name(), MediaType); } } UnlockRes(); return; } } UnlockRes(); ua->warning_msg(_("\nUnable to find Storage resource for\n" "MediaType \"%s\", needed by the Jobs you selected.\n"), MediaType); } /* * Take command line arg, or ask user if none */ rx.store = get_storage_resource(ua); if (rx.store) { Dmsg1(200, "Set store=%s\n", rx.store->name()); } } bareos-Release-14.2.6/src/dird/ua_run.c000066400000000000000000002136661263011562700176240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Run Command * * Kern Sibbald, December MMI */ #include "bareos.h" #include "dird.h" /* Forward referenced subroutines */ static void select_job_level(UAContext *ua, JCR *jcr); static bool display_job_parameters(UAContext *ua, JCR *jcr, RUN_CTX &rc); static void select_where_regexp(UAContext *ua, JCR *jcr); static bool scan_command_line_arguments(UAContext *ua, RUN_CTX &rc); static bool reset_restore_context(UAContext *ua, JCR *jcr, RUN_CTX &rc); static int modify_job_parameters(UAContext *ua, JCR *jcr, RUN_CTX &rc); /* Imported variables */ extern struct s_kw ReplaceOptions[]; /* * Rerun a job by jobid. Lookup the job data and rerun the job with that data. * * Returns: false on error * true if OK */ static inline bool rerun_job(UAContext *ua, JobId_t JobId, bool yes, utime_t now) { JOB_DBR jr; char dt[MAX_TIME_LENGTH]; POOL_MEM cmdline(PM_MESSAGE); memset(&jr, 0, sizeof(jr)); jr.JobId = JobId; ua->send_msg("rerunning jobid %d\n", jr.JobId); if (!db_get_job_record(ua->jcr, ua->db, &jr)) { Jmsg(ua->jcr, M_WARNING, 0, _("Error getting Job record for Job rerun: ERR=%s"), db_strerror(ua->jcr->db)); goto bail_out; } /* * Only perform rerun on JobTypes where it makes sense. */ switch (jr.JobType) { case JT_BACKUP: case JT_COPY: case JT_MIGRATE: break; default: return true; } if (jr.JobLevel == L_NONE) { Mmsg(cmdline, "run job=\"%s\"", jr.Name); } else { Mmsg(cmdline, "run job=\"%s\" level=\"%s\"", jr.Name, level_to_str(jr.JobLevel)); } pm_strcpy(ua->cmd, cmdline); if (jr.ClientId) { CLIENT_DBR cr; memset(&cr, 0, sizeof(cr)); cr.ClientId = jr.ClientId; if (!db_get_client_record(ua->jcr, ua->db, &cr)) { Jmsg(ua->jcr, M_WARNING, 0, _("Error getting Client record for Job rerun: ERR=%s"), db_strerror(ua->jcr->db)); goto bail_out; } Mmsg(cmdline, " client=\"%s\"", cr.Name); pm_strcat(ua->cmd, cmdline); } if (jr.PoolId) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); pr.PoolId = jr.PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { Jmsg(ua->jcr, M_WARNING, 0, _("Error getting Pool record for Job rerun: ERR=%s"), db_strerror(ua->jcr->db)); goto bail_out; } /* * Source pool. */ switch (jr.JobType) { case JT_COPY: case JT_MIGRATE: { JOBRES *job = NULL; job = GetJobResWithName(jr.Name); if (job) { Mmsg(cmdline, " pool=\"%s\"", job->pool->name()); pm_strcat(ua->cmd, cmdline); } break; } case JT_BACKUP: switch (jr.JobLevel) { case L_VIRTUAL_FULL: { JOBRES *job = NULL; job = GetJobResWithName(jr.Name); if (job) { Mmsg(cmdline, " pool=\"%s\"", job->pool->name()); pm_strcat(ua->cmd, cmdline); } break; } default: Mmsg(cmdline, " pool=\"%s\"", pr.Name); pm_strcat(ua->cmd, cmdline); break; } } /* * Next pool. */ switch (jr.JobType) { case JT_COPY: case JT_MIGRATE: Mmsg(cmdline, " nextpool=\"%s\"", pr.Name); pm_strcat(ua->cmd, cmdline); break; case JT_BACKUP: switch (jr.JobLevel) { case L_VIRTUAL_FULL: Mmsg(cmdline, " nextpool=\"%s\"", pr.Name); pm_strcat(ua->cmd, cmdline); break; default: break; } break; } } if (jr.FileSetId) { FILESET_DBR fs; memset(&fs, 0, sizeof(fs)); fs.FileSetId = jr.FileSetId; if (!db_get_fileset_record(ua->jcr, ua->db, &fs)) { Jmsg(ua->jcr, M_WARNING, 0, _("Error getting FileSet record for Job rerun: ERR=%s"), db_strerror(ua->jcr->db)); goto bail_out; } Mmsg(cmdline, " fileset=\"%s\"", fs.FileSet); pm_strcat(ua->cmd, cmdline); } bstrutime(dt, sizeof(dt), now); Mmsg(cmdline, " when=\"%s\"", dt); pm_strcat(ua->cmd, cmdline); if (yes) { pm_strcat(ua->cmd, " yes"); } Dmsg1(100, "rerun cmdline=%s\n", ua->cmd); parse_ua_args(ua); return (run_cmd(ua, ua->cmd) != 0); bail_out: return false; } /* * Rerun a job selection. * * Returns: 0 on error * 1 if OK */ int rerun_cmd(UAContext *ua, const char *cmd) { int i, j, d, h, s, u; int days = 0; int hours = 0; int since_jobid = 0; int until_jobid = 0; JobId_t JobId; dbid_list ids; POOL_MEM query(PM_MESSAGE); utime_t now; time_t schedtime; char dt[MAX_TIME_LENGTH]; char ed1[50]; char ed2[50]; bool yes = false; /* Was "yes" given on cmdline*/ bool timeframe = false; /* Should the selection happen based on timeframe? */ bool since_jobid_given = false; /* Was since_jobid given? */ bool until_jobid_given = false; /* Was until_jobid given? */ const int secs_in_day = 86400; const int secs_in_hour = 3600; if (!open_client_db(ua)) { return 1; } now = (utime_t)time(NULL); /* * Determine what cmdline arguments are given. */ j = find_arg_with_value(ua, NT_("jobid")); d = find_arg_with_value(ua, NT_("days")); h = find_arg_with_value(ua, NT_("hours")); s = find_arg_with_value(ua, NT_("since_jobid")); u = find_arg_with_value(ua, NT_("until_jobid")); if (s > 0) { since_jobid = str_to_int64(ua->argv[s]); since_jobid_given = true; } if (u > 0) { until_jobid = str_to_int64(ua->argv[u]); until_jobid_given = true; } if (d > 0 || h > 0) { timeframe = true; } if (find_arg(ua, NT_("yes")) > 0) { yes = true; } if (j < 0 && !timeframe && !since_jobid_given) { ua->send_msg("Please specifiy jobid, since_jobid, hours or days\n"); goto bail_out; } if (j >= 0 && since_jobid_given) { ua->send_msg("Please specifiy either jobid or since_jobid (and optionally until_jobid)\n"); goto bail_out; } if (j >= 0 && timeframe) { ua->send_msg("Please specifiy either jobid or timeframe\n"); goto bail_out; } if (timeframe || since_jobid_given) { schedtime = now; if (d > 0) { days = str_to_int64(ua->argv[d]); schedtime = now - secs_in_day * days; /* Days in the past */ } if (h > 0) { hours = str_to_int64(ua->argv[h]); schedtime = now - secs_in_hour * hours; /* Hours in the past */ } /* * Job Query Start */ bstrutime(dt, sizeof(dt), schedtime); if (since_jobid_given) { if (until_jobid_given) { Mmsg(query, "SELECT JobId FROM Job WHERE JobStatus = 'f' AND JobId >= %s AND JobId <= %s ORDER BY JobId", edit_int64(since_jobid, ed1), edit_int64(until_jobid, ed2)); } else { Mmsg(query, "SELECT JobId FROM Job WHERE JobStatus = 'f' AND JobId >= %s ORDER BY JobId", edit_int64(since_jobid, ed1)); } } else { Mmsg(query, "SELECT JobId FROM Job WHERE JobStatus = 'f' AND SchedTime > '%s' ORDER BY JobId", dt); } db_get_query_dbids(ua->jcr, ua->db, query, ids); ua->send_msg("The following ids were selected for rerun:\n"); for (i = 0; i < ids.num_ids; i++) { if (i > 0) { ua->send_msg(",%d", ids.DBId[i]); } else { ua->send_msg("%d", ids.DBId[i]); } } ua->send_msg("\n"); if (!yes && (!get_yesno(ua, _("rerun these jobids? (yes/no): ")) || ua->pint32_val == 0 )) { goto bail_out; } /* * Job Query End */ /* * Loop over all selected JobIds. */ for (i = 0; i < ids.num_ids; i++) { JobId = ids.DBId[i]; if (!rerun_job(ua, JobId, yes, now)) { goto bail_out; } } } else { JobId = str_to_int64(ua->argv[j]); if (!rerun_job(ua, JobId, yes, now)) { goto bail_out; } } return 1; bail_out: return 0; } /* * For Backup and Verify Jobs * run [job=] level= * * For Restore Jobs * run * * Returns: 0 on error * JobId if OK * */ int run_cmd(UAContext *ua, const char *cmd) { JCR *jcr = NULL; RUN_CTX rc; int status, length; bool valid_response; bool do_pool_overrides = true; if (!open_client_db(ua)) { return 1; } if (!scan_command_line_arguments(ua, rc)) { return 0; } if (find_arg(ua, NT_("fdcalled")) > 0) { jcr->file_bsock = ua->UA_sock->clone(); ua->quit = true; } /* * Create JCR to run job. NOTE!!! after this point, free_jcr() * before returning. */ if (!jcr) { jcr = new_jcr(sizeof(JCR), dird_free_jcr); set_jcr_defaults(jcr, rc.job); jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */ ua->jcr->unlink_bsr = false; } /* * Transfer JobIds to new restore Job */ if (ua->jcr->JobIds) { jcr->JobIds = ua->jcr->JobIds; ua->jcr->JobIds = NULL; } /* * Transfer selected restore tree to new restore Job */ if (ua->jcr->restore_tree_root) { jcr->restore_tree_root = ua->jcr->restore_tree_root; ua->jcr->restore_tree_root = NULL; } try_again: if (!reset_restore_context(ua, jcr, rc)) { goto bail_out; } /* * Run without prompting? */ if (ua->batch || find_arg(ua, NT_("yes")) > 0) { goto start_job; } /* * When doing interactive runs perform the pool level overrides * early this way the user doesn't get nasty surprisses when * a level override changes the pool the data will be saved to * later. We only want to do these overrides once so we use * a tracking boolean do_pool_overrides to see if we still * need to do this (e.g. we pass by here multiple times when * the user interactivly changes options. */ if (do_pool_overrides) { switch (jcr->getJobType()) { case JT_BACKUP: if (!jcr->is_JobLevel(L_VIRTUAL_FULL)) { apply_pool_overrides(jcr); } break; default: break; } do_pool_overrides = false; } /* * Prompt User to see if all run job parameters are correct, and * allow him to modify them. */ if (!display_job_parameters(ua, jcr, rc)) { goto bail_out; } /* * Prompt User until we have a valid response. */ do { if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) { goto bail_out; } /* * Empty line equals yes, anything other we compare * the cmdline for the length of the given input unless * its mod or .mod where we compare only the keyword * and a space as it can be followed by a full cmdline * with new cmdline arguments that need to be parsed. */ valid_response = false; length = strlen(ua->cmd); if (ua->cmd[0] == 0 || bstrncasecmp(ua->cmd, ".mod ", MIN(length, 5)) || bstrncasecmp(ua->cmd, "mod ", MIN(length, 4)) || bstrncasecmp(ua->cmd, NT_("yes"), length) || bstrncasecmp(ua->cmd, _("yes"), length) || bstrncasecmp(ua->cmd, NT_("no"), length) || bstrncasecmp(ua->cmd, _("no"), length)) { valid_response = true; } if (!valid_response) { ua->warning_msg(_("Illegal response %s\n"), ua->cmd); } } while (!valid_response); /* * See if the .mod or mod has arguments. */ if (bstrncasecmp(ua->cmd, ".mod ", 5) || (bstrncasecmp(ua->cmd, "mod ", 4) && strlen(ua->cmd) > 6)) { parse_ua_args(ua); rc.mod = true; if (!scan_command_line_arguments(ua, rc)) { return 0; } goto try_again; } /* * Allow the user to modify the settings */ status = modify_job_parameters(ua, jcr, rc); switch (status) { case 0: goto try_again; case 1: break; case -1: goto bail_out; } /* * For interactive runs we set IgnoreLevelPoolOverrides as we already * performed the actual overrrides. */ jcr->IgnoreLevelPoolOverides = true; if (ua->cmd[0] == 0 || bstrncasecmp(ua->cmd, NT_("yes"), strlen(ua->cmd)) || bstrncasecmp(ua->cmd, _("yes"), strlen(ua->cmd))) { JobId_t JobId; Dmsg1(800, "Calling run_job job=%x\n", jcr->res.job); start_job: Dmsg3(100, "JobId=%u using pool %s priority=%d\n", (int)jcr->JobId, jcr->res.pool->name(), jcr->JobPriority); Dmsg1(900, "Running a job; its spool_data = %d\n", jcr->spool_data); JobId = run_job(jcr); Dmsg4(100, "JobId=%u NewJobId=%d using pool %s priority=%d\n", (int)jcr->JobId, JobId, jcr->res.pool->name(), jcr->JobPriority); free_jcr(jcr); /* release jcr */ if (JobId == 0) { ua->error_msg(_("Job failed.\n")); } else { char ed1[50]; ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1)); } return JobId; } bail_out: ua->send_msg(_("Job not run.\n")); free_jcr(jcr); return 0; /* do not run */ } int modify_job_parameters(UAContext *ua, JCR *jcr, RUN_CTX &rc) { int opt; /* * At user request modify parameters of job to be run. */ if (ua->cmd[0] != 0 && bstrncasecmp(ua->cmd, _("mod"), strlen(ua->cmd))) { start_prompt(ua, _("Parameters to modify:\n")); add_prompt(ua, _("Level")); /* 0 */ add_prompt(ua, _("Storage")); /* 1 */ add_prompt(ua, _("Job")); /* 2 */ add_prompt(ua, _("FileSet")); /* 3 */ if (jcr->is_JobType(JT_RESTORE)) { add_prompt(ua, _("Restore Client")); /* 4 */ } else { add_prompt(ua, _("Client")); /* 4 */ } add_prompt(ua, _("Backup Format")); /* 5 */ add_prompt(ua, _("When")); /* 6 */ add_prompt(ua, _("Priority")); /* 7 */ if (jcr->is_JobType(JT_BACKUP) || jcr->is_JobType(JT_COPY) || jcr->is_JobType(JT_MIGRATE) || jcr->is_JobType(JT_VERIFY)) { add_prompt(ua, _("Pool")); /* 8 */ if (jcr->is_JobType(JT_MIGRATE) || jcr->is_JobType(JT_COPY) || (jcr->is_JobType(JT_BACKUP) && jcr->is_JobLevel(L_VIRTUAL_FULL))) { /* NextPool */ add_prompt(ua, _("NextPool")); /* 9 */ if (jcr->is_JobType(JT_BACKUP)) { add_prompt(ua, _("Plugin Options")); /* 10 */ } } else if (jcr->is_JobType(JT_VERIFY)) { add_prompt(ua, _("Verify Job")); /* 9 */ } else if (jcr->is_JobType(JT_BACKUP)) { add_prompt(ua, _("Plugin Options")); /* 9 */ } } else if (jcr->is_JobType(JT_RESTORE)) { add_prompt(ua, _("Bootstrap")); /* 8 */ add_prompt(ua, _("Where")); /* 9 */ add_prompt(ua, _("File Relocation")); /* 10 */ add_prompt(ua, _("Replace")); /* 11 */ add_prompt(ua, _("JobId")); /* 12 */ add_prompt(ua, _("Plugin Options")); /* 13 */ } switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { case 0: /* Level */ select_job_level(ua, jcr); switch (jcr->getJobType()) { case JT_BACKUP: if (!jcr->is_JobLevel(L_VIRTUAL_FULL)) { apply_pool_overrides(jcr, true); } break; default: break; } goto try_again; case 1: /* Storage */ rc.store->store = select_storage_resource(ua); if (rc.store->store) { pm_strcpy(rc.store->store_source, _("user selection")); set_rwstorage(jcr, rc.store); goto try_again; } break; case 2: /* Job */ rc.job = select_job_resource(ua); if (rc.job) { jcr->res.job = rc.job; set_jcr_defaults(jcr, rc.job); goto try_again; } break; case 3: /* FileSet */ rc.fileset = select_fileset_resource(ua); if (rc.fileset) { jcr->res.fileset = rc.fileset; goto try_again; } break; case 4: /* Client */ rc.client = select_client_resource(ua); if (rc.client) { jcr->res.client = rc.client; goto try_again; } break; case 5: /* Backup Format */ if (get_cmd(ua, _("Please enter Backup Format: "))) { if (jcr->backup_format) { free(jcr->backup_format); jcr->backup_format = NULL; } jcr->backup_format = bstrdup(ua->cmd); goto try_again; } break; case 6: /* When */ if (get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) { if (ua->cmd[0] == 0) { jcr->sched_time = time(NULL); } else { jcr->sched_time = str_to_utime(ua->cmd); if (jcr->sched_time == 0) { ua->send_msg(_("Invalid time, using current time.\n")); jcr->sched_time = time(NULL); } } goto try_again; } break; case 7: /* Priority */ if (get_pint(ua, _("Enter new Priority: "))) { if (ua->pint32_val == 0) { ua->send_msg(_("Priority must be a positive integer.\n")); } else { jcr->JobPriority = ua->pint32_val; } goto try_again; } break; case 8: /* Pool or Bootstrap depending on JobType */ if (jcr->is_JobType(JT_BACKUP) || jcr->is_JobType(JT_COPY) || jcr->is_JobType(JT_MIGRATE) || jcr->is_JobType(JT_VERIFY)) { /* Pool */ rc.pool = select_pool_resource(ua); if (rc.pool) { jcr->res.pool = rc.pool; Dmsg1(100, "Set new pool=%s\n", jcr->res.pool->name()); goto try_again; } } else { /* Bootstrap */ if (get_cmd(ua, _("Please enter the Bootstrap file name: "))) { if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; } if (ua->cmd[0] != 0) { FILE *fd; jcr->RestoreBootstrap = bstrdup(ua->cmd); fd = fopen(jcr->RestoreBootstrap, "rb"); if (!fd) { berrno be; ua->send_msg(_("Warning cannot open %s: ERR=%s\n"), jcr->RestoreBootstrap, be.bstrerror()); free(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; } else { fclose(fd); } } goto try_again; } } break; case 9: /* NextPool/Verify Job/Where/Plugin Options depending on JobType */ if (jcr->is_JobType(JT_MIGRATE) || jcr->is_JobType(JT_COPY) || (jcr->is_JobType(JT_BACKUP) && jcr->is_JobLevel(L_VIRTUAL_FULL))) { /* NextPool */ rc.next_pool = select_pool_resource(ua); if (rc.next_pool) { jcr->res.next_pool = rc.next_pool; Dmsg1(100, "Set new next_pool=%s\n", jcr->res.next_pool->name()); goto try_again; } } else if (jcr->is_JobType(JT_VERIFY)) { /* Verify Job */ rc.verify_job = select_job_resource(ua); if (rc.verify_job) { jcr->res.verify_job = rc.verify_job; } goto try_again; } else if (jcr->is_JobType(JT_RESTORE)) { /* Where */ if (get_cmd(ua, _("Please enter the full path prefix for restore (/ for none): "))) { if (jcr->RegexWhere) { /* cannot use regexwhere and where */ free(jcr->RegexWhere); jcr->RegexWhere = NULL; } if (jcr->where) { free(jcr->where); jcr->where = NULL; } if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') { ua->cmd[0] = 0; } jcr->where = bstrdup(ua->cmd); goto try_again; } } else { /* Plugin Options */ if (get_cmd(ua, _("Please enter Plugin Options string: "))) { if (jcr->plugin_options) { free(jcr->plugin_options); jcr->plugin_options = NULL; } jcr->plugin_options = bstrdup(ua->cmd); goto try_again; } } break; case 10: /* File relocation/Plugin Options depending on JobType */ if (jcr->is_JobType(JT_RESTORE)) { select_where_regexp(ua, jcr); goto try_again; } else if (jcr->is_JobType(JT_BACKUP)) { if (get_cmd(ua, _("Please enter Plugin Options string: "))) { if (jcr->plugin_options) { free(jcr->plugin_options); jcr->plugin_options = NULL; } jcr->plugin_options = bstrdup(ua->cmd); goto try_again; } } break; case 11: /* Replace */ start_prompt(ua, _("Replace:\n")); for (int i = 0; ReplaceOptions[i].name; i++) { add_prompt(ua, ReplaceOptions[i].name); } opt = do_prompt(ua, "", _("Select replace option"), NULL, 0); if (opt >= 0) { rc.replace = ReplaceOptions[opt].name; jcr->replace = ReplaceOptions[opt].token; } goto try_again; case 12: /* JobId */ rc.jid = NULL; /* force reprompt */ jcr->RestoreJobId = 0; if (jcr->RestoreBootstrap) { ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n")); } goto try_again; case 13: /* Plugin Options */ if (get_cmd(ua, _("Please enter Plugin Options string: "))) { if (jcr->plugin_options) { free(jcr->plugin_options); jcr->plugin_options = NULL; } jcr->plugin_options = bstrdup(ua->cmd); goto try_again; } break; case -1: /* error or cancel */ goto bail_out; default: goto try_again; } goto bail_out; } return 1; bail_out: return -1; try_again: return 0; } /* * Reset the restore context. * This subroutine can be called multiple times, so it * must keep any prior settings. */ static bool reset_restore_context(UAContext *ua, JCR *jcr, RUN_CTX &rc) { jcr->res.verify_job = rc.verify_job; jcr->res.previous_job = rc.previous_job; jcr->res.pool = rc.pool; jcr->res.next_pool = rc.next_pool; /* * See if an explicit pool override was performed. * If so set the pool_source to command line and * set the IgnoreLevelPoolOverides so any level Pool * overrides are ignored. */ if (rc.pool_name) { pm_strcpy(jcr->res.pool_source, _("command line")); jcr->IgnoreLevelPoolOverides = true; } else if (jcr->res.pool != jcr->res.job->pool) { pm_strcpy(jcr->res.pool_source, _("user input")); } set_rwstorage(jcr, rc.store); if (rc.next_pool_name) { pm_strcpy(jcr->res.npool_source, _("command line")); jcr->res.run_next_pool_override = true; } else if (jcr->res.next_pool != jcr->res.pool->NextPool) { pm_strcpy(jcr->res.npool_source, _("user input")); jcr->res.run_next_pool_override = true; } jcr->res.client = rc.client; if (jcr->res.client) { pm_strcpy(jcr->client_name, rc.client->name()); } jcr->res.fileset = rc.fileset; jcr->ExpectedFiles = rc.files; if (rc.catalog) { jcr->res.catalog = rc.catalog; pm_strcpy(jcr->res.catalog_source, _("user input")); } pm_strcpy(jcr->comment, rc.comment); if (rc.where) { if (jcr->where) { free(jcr->where); } jcr->where = bstrdup(rc.where); rc.where = NULL; } if (rc.regexwhere) { if (jcr->RegexWhere) { free(jcr->RegexWhere); } jcr->RegexWhere = bstrdup(rc.regexwhere); rc.regexwhere = NULL; } if (rc.when) { jcr->sched_time = str_to_utime(rc.when); if (jcr->sched_time == 0) { ua->send_msg(_("Invalid time, using current time.\n")); jcr->sched_time = time(NULL); } rc.when = NULL; } if (rc.bootstrap) { if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); } jcr->RestoreBootstrap = bstrdup(rc.bootstrap); rc.bootstrap = NULL; } if (rc.plugin_options) { if (jcr->plugin_options) { free(jcr->plugin_options); } jcr->plugin_options = bstrdup(rc.plugin_options); rc.plugin_options = NULL; } if (rc.replace) { jcr->replace = 0; for (int i = 0; ReplaceOptions[i].name; i++) { if (bstrcasecmp(rc.replace, ReplaceOptions[i].name)) { jcr->replace = ReplaceOptions[i].token; } } if (!jcr->replace) { ua->send_msg(_("Invalid replace option: %s\n"), rc.replace); return false; } } else if (rc.job->replace) { jcr->replace = rc.job->replace; } else { jcr->replace = REPLACE_ALWAYS; } rc.replace = NULL; if (rc.Priority) { jcr->JobPriority = rc.Priority; rc.Priority = 0; } if (rc.since) { if (!jcr->stime) { jcr->stime = get_pool_memory(PM_MESSAGE); } pm_strcpy(jcr->stime, rc.since); rc.since = NULL; } if (rc.cloned) { jcr->cloned = rc.cloned; rc.cloned = false; } /* * If pool changed, update migration write storage */ if (jcr->is_JobType(JT_MIGRATE) || jcr->is_JobType(JT_COPY) || (jcr->is_JobType(JT_BACKUP) && jcr->is_JobLevel(L_VIRTUAL_FULL))) { if (!set_migration_wstorage(jcr, rc.pool, rc.next_pool, _("Storage from Run NextPool override"))) { return false; } } rc.replace = ReplaceOptions[0].name; for (int i = 0; ReplaceOptions[i].name; i++) { if (ReplaceOptions[i].token == jcr->replace) { rc.replace = ReplaceOptions[i].name; } } if (rc.level_name) { if (!get_level_from_name(jcr, rc.level_name)) { ua->send_msg(_("Level \"%s\" not valid.\n"), rc.level_name); return false; } rc.level_name = NULL; } if (rc.jid) { /* Note, this is also MigrateJobId and a VerifyJobId */ jcr->RestoreJobId = str_to_int64(rc.jid); rc.jid = 0; } if (rc.backup_format) { if (jcr->backup_format) { free(jcr->backup_format); } jcr->backup_format = bstrdup(rc.backup_format); rc.backup_format = NULL; } /* * Some options are not available through the menu * TODO: Add an advanced menu? */ if (rc.spool_data_set) { jcr->spool_data = rc.spool_data; } if (rc.accurate_set) { jcr->accurate = rc.accurate; } /* * Used by migration jobs that can have the same name, * but can run at the same time */ if (rc.ignoreduplicatecheck_set) { jcr->IgnoreDuplicateJobChecking = rc.ignoreduplicatecheck; } return true; } static void select_where_regexp(UAContext *ua, JCR *jcr) { alist *regs; char *strip_prefix, *add_prefix, *add_suffix, *rwhere; strip_prefix = add_suffix = rwhere = add_prefix = NULL; try_again_reg: ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"), NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix)); start_prompt(ua, _("This will replace your current Where value\n")); add_prompt(ua, _("Strip prefix")); /* 0 */ add_prompt(ua, _("Add prefix")); /* 1 */ add_prompt(ua, _("Add file suffix")); /* 2 */ add_prompt(ua, _("Enter a regexp")); /* 3 */ add_prompt(ua, _("Test filename manipulation")); /* 4 */ add_prompt(ua, _("Use this ?")); /* 5 */ switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { case 0: /* Strip prefix */ if (get_cmd(ua, _("Please enter the path prefix to strip: "))) { if (strip_prefix) bfree(strip_prefix); strip_prefix = bstrdup(ua->cmd); } goto try_again_reg; case 1: /* Add prefix */ if (get_cmd(ua, _("Please enter the path prefix to add (/ for none): "))) { if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') { ua->cmd[0] = 0; } if (add_prefix) bfree(add_prefix); add_prefix = bstrdup(ua->cmd); } goto try_again_reg; case 2: /* Add suffix */ if (get_cmd(ua, _("Please enter the file suffix to add: "))) { if (add_suffix) bfree(add_suffix); add_suffix = bstrdup(ua->cmd); } goto try_again_reg; case 3: /* Add rwhere */ if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) { if (rwhere) bfree(rwhere); rwhere = bstrdup(ua->cmd); } goto try_again_reg; case 4: /* Test regexp */ char *result; char *regexp; if (rwhere && rwhere[0] != '\0') { regs = get_bregexps(rwhere); ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere)); } else { int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix); regexp = (char *) bmalloc (len * sizeof(char)); bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix); regs = get_bregexps(regexp); ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"), NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp)); bfree(regexp); } if (!regs) { ua->send_msg(_("Cannot use your regexp\n")); goto try_again_reg; } ua->send_msg(_("Enter a period (.) to stop this test\n")); while (get_cmd(ua, _("Please enter filename to test: "))) { apply_bregexps(ua->cmd, regs, &result); ua->send_msg(_("%s -> %s\n"), ua->cmd, result); } free_bregexps(regs); delete regs; goto try_again_reg; case 5: /* OK */ break; case -1: /* error or cancel */ goto bail_out_reg; default: goto try_again_reg; } /* replace the existing where */ if (jcr->where) { bfree(jcr->where); jcr->where = NULL; } /* replace the existing regexwhere */ if (jcr->RegexWhere) { bfree(jcr->RegexWhere); jcr->RegexWhere = NULL; } if (rwhere) { jcr->RegexWhere = bstrdup(rwhere); } else if (strip_prefix || add_prefix || add_suffix) { int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix); jcr->RegexWhere = (char *) bmalloc(len*sizeof(char)); bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix); } regs = get_bregexps(jcr->RegexWhere); if (regs) { free_bregexps(regs); delete regs; } else { if (jcr->RegexWhere) { bfree(jcr->RegexWhere); jcr->RegexWhere = NULL; } ua->send_msg(_("Cannot use your regexp.\n")); } bail_out_reg: if (strip_prefix) { bfree(strip_prefix); } if (add_prefix) { bfree(add_prefix); } if (add_suffix) { bfree(add_suffix); } if (rwhere) { bfree(rwhere); } } static void select_job_level(UAContext *ua, JCR *jcr) { if (jcr->is_JobType(JT_BACKUP)) { start_prompt(ua, _("Levels:\n")); // add_prompt(ua, _("Base")); add_prompt(ua, _("Full")); add_prompt(ua, _("Incremental")); add_prompt(ua, _("Differential")); add_prompt(ua, _("Since")); add_prompt(ua, _("VirtualFull")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { // case 0: // jcr->JobLevel = L_BASE; // break; case 0: jcr->setJobLevel(L_FULL); break; case 1: jcr->setJobLevel(L_INCREMENTAL); break; case 2: jcr->setJobLevel(L_DIFFERENTIAL); break; case 3: jcr->setJobLevel(L_SINCE); break; case 4: jcr->setJobLevel(L_VIRTUAL_FULL); break; default: break; } } else if (jcr->is_JobType(JT_VERIFY)) { start_prompt(ua, _("Levels:\n")); add_prompt(ua, _("Initialize Catalog")); add_prompt(ua, _("Verify Catalog")); add_prompt(ua, _("Verify Volume to Catalog")); add_prompt(ua, _("Verify Disk to Catalog")); add_prompt(ua, _("Verify Volume Data (not yet implemented)")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { case 0: jcr->setJobLevel(L_VERIFY_INIT); break; case 1: jcr->setJobLevel(L_VERIFY_CATALOG); break; case 2: jcr->setJobLevel(L_VERIFY_VOLUME_TO_CATALOG); break; case 3: jcr->setJobLevel(L_VERIFY_DISK_TO_CATALOG); break; case 4: jcr->setJobLevel(L_VERIFY_DATA); break; default: break; } } else { ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n")); } return; } static bool display_job_parameters(UAContext *ua, JCR *jcr, RUN_CTX &rc) { char ec1[30]; JOBRES *job = rc.job; char dt[MAX_TIME_LENGTH]; const char *verify_list = rc.verify_list; Dmsg1(800, "JobType=%c\n", jcr->getJobType()); switch (jcr->getJobType()) { case JT_ADMIN: if (ua->api) { ua->signal(BNET_RUN_CMD); ua->send_msg("Type: Admin\n" "Title: Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n", job->name(), jcr->res.fileset->name(), NPRT(jcr->res.client->name()), jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->JobPriority); } else { ua->send_msg(_("Run Admin Job\n" "JobName: %s\n" "FileSet: %s\n" "Client: %s\n" "Storage: %s\n" "When: %s\n" "Priority: %d\n"), job->name(), jcr->res.fileset->name(), NPRT(jcr->res.client->name()), jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->JobPriority); } jcr->setJobLevel(L_FULL); break; case JT_BACKUP: case JT_VERIFY: if (jcr->is_JobType(JT_BACKUP)) { bool is_virtual = jcr->is_JobLevel(L_VIRTUAL_FULL); if (ua->api) { ua->signal(BNET_RUN_CMD); ua->send_msg("Type: Backup\n" "Title: Run Backup Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s\n" "%s%s%s" "Storage: %s\n" "When: %s\n" "Priority: %d\n" "%s%s%s", job->name(), level_to_str(jcr->getJobLevel()), jcr->res.client->name(), jcr->backup_format, jcr->res.fileset->name(), NPRT(jcr->res.pool->name()), is_virtual ? "NextPool: " : "", is_virtual ? (jcr->res.next_pool ? jcr->res.next_pool->name() : _("*None*")) : "", is_virtual ? "\n" : "", jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->JobPriority, jcr->plugin_options ? "Plugin Options: " : "", jcr->plugin_options ? jcr->plugin_options : "", jcr->plugin_options ? "\n" : ""); } else { ua->send_msg(_("Run Backup job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "Format: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "%s%s%s%s%s" "Storage: %s (From %s)\n" "When: %s\n" "Priority: %d\n" "%s%s%s"), job->name(), level_to_str(jcr->getJobLevel()), jcr->res.client->name(), jcr->backup_format, jcr->res.fileset->name(), NPRT(jcr->res.pool->name()), jcr->res.pool_source, is_virtual ? "NextPool: " : "", is_virtual ? (jcr->res.next_pool ? jcr->res.next_pool->name() : _("*None*")) : "", is_virtual ? " (From " : "", is_virtual ? jcr->res.npool_source : "", is_virtual ? ")\n" : "", jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), jcr->res.wstore_source, bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->JobPriority, jcr->plugin_options ? "Plugin Options: " : "", jcr->plugin_options ? jcr->plugin_options : "", jcr->plugin_options ? "\n" : ""); } } else { /* JT_VERIFY */ JOB_DBR jr; const char *Name; if (jcr->res.verify_job) { Name = jcr->res.verify_job->name(); } else if (jcr->RestoreJobId) { /* Display job name if jobid requested */ memset(&jr, 0, sizeof(jr)); jr.JobId = jcr->RestoreJobId; if (!db_get_job_record(jcr, ua->db, &jr)) { ua->error_msg(_("Could not get job record for selected JobId. ERR=%s"), db_strerror(ua->db)); return false; } Name = jr.Job; } else { Name = ""; } if (!verify_list) { verify_list = job->WriteVerifyList; } if (!verify_list) { verify_list = ""; } if (ua->api) { ua->signal(BNET_RUN_CMD); ua->send_msg("Type: Verify\n" "Title: Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n", job->name(), level_to_str(jcr->getJobLevel()), jcr->res.client->name(), jcr->res.fileset->name(), NPRT(jcr->res.pool->name()), jcr->res.pool_source, jcr->res.rstore->name(), jcr->res.rstore_source, Name, verify_list, bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->JobPriority); } else { ua->send_msg(_("Run Verify Job\n" "JobName: %s\n" "Level: %s\n" "Client: %s\n" "FileSet: %s\n" "Pool: %s (From %s)\n" "Storage: %s (From %s)\n" "Verify Job: %s\n" "Verify List: %s\n" "When: %s\n" "Priority: %d\n"), job->name(), level_to_str(jcr->getJobLevel()), jcr->res.client->name(), jcr->res.fileset->name(), NPRT(jcr->res.pool->name()), jcr->res.pool_source, jcr->res.rstore->name(), jcr->res.rstore_source, Name, verify_list, bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->JobPriority); } } break; case JT_RESTORE: if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) { if (rc.jid) { jcr->RestoreJobId = str_to_int64(rc.jid); } else { if (!get_pint(ua, _("Please enter a JobId for restore: "))) { return false; } jcr->RestoreJobId = ua->int64_val; } } jcr->setJobLevel(L_FULL); /* default level */ Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId); if (jcr->RestoreJobId == 0) { /* RegexWhere is take before RestoreWhere */ if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) { if (ua->api) { ua->signal(BNET_RUN_CMD); ua->send_msg("Type: Restore\n" "Title: Run Restore Job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n", job->name(), NPRT(jcr->RestoreBootstrap), jcr->RegexWhere ? jcr->RegexWhere : job->RegexWhere, rc.replace, jcr->res.fileset->name(), rc.client_name, jcr->res.client->name(), jcr->backup_format, jcr->res.rstore->name(), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority, NPRT(jcr->plugin_options)); } else { ua->send_msg(_("Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "RegexWhere: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n"), job->name(), NPRT(jcr->RestoreBootstrap), jcr->RegexWhere ? jcr->RegexWhere : job->RegexWhere, rc.replace, jcr->res.fileset->name(), rc.client_name, jcr->res.client->name(), jcr->backup_format, jcr->res.rstore->name(), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority, NPRT(jcr->plugin_options)); } } else { if (ua->api) { ua->signal(BNET_RUN_CMD); ua->send_msg("Type: Restore\n" "Title: Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n", job->name(), NPRT(jcr->RestoreBootstrap), jcr->where ? jcr->where : NPRT(job->RestoreWhere), rc.replace, jcr->res.fileset->name(), rc.client_name, jcr->res.client->name(), jcr->backup_format, jcr->res.rstore->name(), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority, NPRT(jcr->plugin_options)); } else { ua->send_msg(_("Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n" "Where: %s\n" "Replace: %s\n" "FileSet: %s\n" "Backup Client: %s\n" "Restore Client: %s\n" "Format: %s\n" "Storage: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n"), job->name(), NPRT(jcr->RestoreBootstrap), jcr->where ? jcr->where : NPRT(job->RestoreWhere), rc.replace, jcr->res.fileset->name(), rc.client_name, jcr->res.client->name(), jcr->backup_format, jcr->res.rstore->name(), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority, NPRT(jcr->plugin_options)); } } } else { /* ***FIXME*** This needs to be fixed for bat */ if (ua->api) ua->signal(BNET_RUN_CMD); ua->send_msg(_("Run Restore job\n" "JobName: %s\n" "Bootstrap: %s\n"), job->name(), NPRT(jcr->RestoreBootstrap)); /* RegexWhere is take before RestoreWhere */ if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) { ua->send_msg(_("RegexWhere: %s\n"), jcr->RegexWhere ? jcr->RegexWhere : job->RegexWhere); } else { ua->send_msg(_("Where: %s\n"), jcr->where ? jcr->where : NPRT(job->RestoreWhere)); } ua->send_msg(_("Replace: %s\n" "Client: %s\n" "Format: %s\n" "Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n" "Plugin Options: %s\n"), rc.replace, jcr->res.client->name(), jcr->backup_format, jcr->res.rstore->name(), (jcr->RestoreJobId == 0) ? _("*None*") : edit_uint64(jcr->RestoreJobId, ec1), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority, NPRT(jcr->plugin_options)); } break; case JT_COPY: case JT_MIGRATE: const char *prt_type; jcr->setJobLevel(L_FULL); /* default level */ if (ua->api) { ua->signal(BNET_RUN_CMD); if (jcr->is_JobType(JT_COPY)) { prt_type = _("Type: Copy\nTitle: Run Copy Job\n"); } else { prt_type = _("Type: Migration\nTitle: Run Migration Job\n"); } ua->send_msg(_("%s" "JobName: %s\n" "Bootstrap: %s\n" "Pool: %s\n" "NextPool: %s\n" "Write Storage: %s\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n"), prt_type, job->name(), NPRT(jcr->RestoreBootstrap), NPRT(jcr->res.pool->name()), jcr->res.next_pool ? jcr->res.next_pool->name() : _("*None*"), jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), (jcr->MigrateJobId == 0) ? _("*None*") : edit_uint64(jcr->MigrateJobId, ec1), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority); } else { if (jcr->is_JobType(JT_COPY)) { prt_type = _("Run Copy job\n"); } else { prt_type = _("Run Migration job\n"); } ua->send_msg(_("%s" "JobName: %s\n" "Bootstrap: %s\n" "Pool: %s (From %s)\n" "NextPool: %s (From %s)\n" "Write Storage: %s (From %s)\n" "JobId: %s\n" "When: %s\n" "Catalog: %s\n" "Priority: %d\n"), prt_type, job->name(), NPRT(jcr->RestoreBootstrap), NPRT(jcr->res.pool->name()), jcr->res.pool_source, jcr->res.next_pool ? jcr->res.next_pool->name() : _("*None*"), NPRT(jcr->res.npool_source), jcr->res.wstore ? jcr->res.wstore->name() : _("*None*"), jcr->res.wstore_source, jcr->MigrateJobId == 0 ? _("*None*") : edit_uint64(jcr->MigrateJobId, ec1), bstrutime(dt, sizeof(dt), jcr->sched_time), jcr->res.catalog->name(), jcr->JobPriority); } break; default: ua->error_msg(_("Unknown Job Type=%d\n"), jcr->getJobType()); return false; } return true; } static bool scan_command_line_arguments(UAContext *ua, RUN_CTX &rc) { bool kw_ok; int i, j; static const char *kw[] = { /* command line arguments */ "job", /* 0 */ "jobid", /* 1 */ "client", /* 2 */ "fd", /* 3 */ "fileset", /* 4 */ "level", /* 5 */ "storage", /* 6 */ "sd", /* 7 */ "regexwhere", /* 8 - where string as a bregexp */ "where", /* 9 */ "bootstrap", /* 10 */ "replace", /* 11 */ "when", /* 12 */ "priority", /* 13 */ "yes", /* 14 -- if you change this change YES_POS too */ "verifyjob", /* 15 */ "files", /* 16 - number of files to restore */ "catalog", /* 17 - override catalog */ "since", /* 18 - since */ "cloned", /* 19 - cloned */ "verifylist", /* 20 - verify output list */ "migrationjob", /* 21 - migration job name */ "pool", /* 22 */ "nextpool", /* 23 */ "backupclient", /* 24 */ "restoreclient", /* 25 */ "pluginoptions", /* 26 */ "spooldata", /* 27 */ "comment", /* 28 */ "ignoreduplicatecheck", /* 29 */ "accurate", /* 30 */ "backupformat", /* 31 */ NULL }; #define YES_POS 14 rc.catalog_name = NULL; rc.job_name = NULL; rc.pool_name = NULL; rc.next_pool_name = NULL; rc.store_name = NULL; rc.client_name = NULL; rc.restore_client_name = NULL; rc.fileset_name = NULL; rc.verify_job_name = NULL; rc.previous_job_name = NULL; rc.accurate_set = false; rc.spool_data_set = false; rc.ignoreduplicatecheck = false; rc.comment = NULL; rc.backup_format = NULL; for (i = 1; i < ua->argc; i++) { Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]); kw_ok = false; /* * Keep looking until we find a good keyword */ for (j = 0; !kw_ok && kw[j]; j++) { if (bstrcasecmp(ua->argk[i], kw[j])) { /* * Note, yes and run have no value, so do not fail */ if (!ua->argv[i] && j != YES_POS /*yes*/) { ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]); return false; } Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j])); switch (j) { case 0: /* job */ if (rc.job_name) { ua->send_msg(_("Job name specified twice.\n")); return false; } rc.job_name = ua->argv[i]; kw_ok = true; break; case 1: /* JobId */ if (rc.jid && !rc.mod) { ua->send_msg(_("JobId specified twice.\n")); return false; } rc.jid = ua->argv[i]; kw_ok = true; break; case 2: /* client */ case 3: /* fd */ if (rc.client_name) { ua->send_msg(_("Client specified twice.\n")); return false; } rc.client_name = ua->argv[i]; kw_ok = true; break; case 4: /* fileset */ if (rc.fileset_name) { ua->send_msg(_("FileSet specified twice.\n")); return false; } rc.fileset_name = ua->argv[i]; kw_ok = true; break; case 5: /* level */ if (rc.level_name) { ua->send_msg(_("Level specified twice.\n")); return false; } rc.level_name = ua->argv[i]; kw_ok = true; break; case 6: /* storage */ case 7: /* sd */ if (rc.store_name) { ua->send_msg(_("Storage specified twice.\n")); return false; } rc.store_name = ua->argv[i]; kw_ok = true; break; case 8: /* regexwhere */ if ((rc.regexwhere || rc.where) && !rc.mod) { ua->send_msg(_("RegexWhere or Where specified twice.\n")); return false; } rc.regexwhere = ua->argv[i]; if (!acl_access_ok(ua, Where_ACL, rc.regexwhere, true)) { ua->send_msg(_("No authorization for \"regexwhere\" specification.\n")); return false; } kw_ok = true; break; case 9: /* where */ if ((rc.where || rc.regexwhere) && !rc.mod) { ua->send_msg(_("Where or RegexWhere specified twice.\n")); return false; } rc.where = ua->argv[i]; if (!acl_access_ok(ua, Where_ACL, rc.where, true)) { ua->send_msg(_("No authoriztion for \"where\" specification.\n")); return false; } kw_ok = true; break; case 10: /* bootstrap */ if (rc.bootstrap && !rc.mod) { ua->send_msg(_("Bootstrap specified twice.\n")); return false; } rc.bootstrap = ua->argv[i]; kw_ok = true; break; case 11: /* replace */ if (rc.replace && !rc.mod) { ua->send_msg(_("Replace specified twice.\n")); return false; } rc.replace = ua->argv[i]; kw_ok = true; break; case 12: /* When */ if (rc.when && !rc.mod) { ua->send_msg(_("When specified twice.\n")); return false; } rc.when = ua->argv[i]; kw_ok = true; break; case 13: /* Priority */ if (rc.Priority && !rc.mod) { ua->send_msg(_("Priority specified twice.\n")); return false; } rc.Priority = atoi(ua->argv[i]); if (rc.Priority <= 0) { ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n")); rc.Priority = 10; } kw_ok = true; break; case 14: /* yes */ kw_ok = true; break; case 15: /* Verify Job */ if (rc.verify_job_name) { ua->send_msg(_("Verify Job specified twice.\n")); return false; } rc.verify_job_name = ua->argv[i]; kw_ok = true; break; case 16: /* files */ rc.files = atoi(ua->argv[i]); kw_ok = true; break; case 17: /* catalog */ rc.catalog_name = ua->argv[i]; kw_ok = true; break; case 18: /* since */ rc.since = ua->argv[i]; kw_ok = true; break; case 19: /* cloned */ rc. cloned = true; kw_ok = true; break; case 20: /* write verify list output */ rc.verify_list = ua->argv[i]; kw_ok = true; break; case 21: /* Migration Job */ if (rc.previous_job_name) { ua->send_msg(_("Migration Job specified twice.\n")); return false; } rc.previous_job_name = ua->argv[i]; kw_ok = true; break; case 22: /* pool */ if (rc.pool_name) { ua->send_msg(_("Pool specified twice.\n")); return false; } rc.pool_name = ua->argv[i]; kw_ok = true; break; case 23: /* nextpool */ if (rc.next_pool_name) { ua->send_msg(_("NextPool specified twice.\n")); return false; } rc.next_pool_name = ua->argv[i]; kw_ok = true; break; case 24: /* backupclient */ if (rc.client_name) { ua->send_msg(_("Client specified twice.\n")); return 0; } rc.client_name = ua->argv[i]; kw_ok = true; break; case 25: /* restoreclient */ if (rc.restore_client_name && !rc.mod) { ua->send_msg(_("Restore Client specified twice.\n")); return false; } rc.restore_client_name = ua->argv[i]; kw_ok = true; break; case 26: /* pluginoptions */ if (rc.plugin_options) { ua->send_msg(_("Plugin Options specified twice.\n")); return false; } rc.plugin_options = ua->argv[i]; if (!acl_access_ok(ua, PluginOptions_ACL, rc.plugin_options, true)) { ua->send_msg(_("No authorization for \"PluginOptions\" specification.\n")); return false; } kw_ok = true; break; case 27: /* spooldata */ if (rc.spool_data_set) { ua->send_msg(_("Spool flag specified twice.\n")); return false; } if (is_yesno(ua->argv[i], &rc.spool_data)) { rc.spool_data_set = true; kw_ok = true; } else { ua->send_msg(_("Invalid spooldata flag.\n")); } break; case 28: /* comment */ rc.comment = ua->argv[i]; kw_ok = true; break; case 29: /* ignoreduplicatecheck */ if (rc.ignoreduplicatecheck_set) { ua->send_msg(_("IgnoreDuplicateCheck flag specified twice.\n")); return false; } if (is_yesno(ua->argv[i], &rc.ignoreduplicatecheck)) { rc.ignoreduplicatecheck_set = true; kw_ok = true; } else { ua->send_msg(_("Invalid ignoreduplicatecheck flag.\n")); } break; case 30: /* accurate */ if (rc.accurate_set) { ua->send_msg(_("Accurate flag specified twice.\n")); return false; } if (is_yesno(ua->argv[i], &rc.accurate)) { rc.accurate_set = true; kw_ok = true; } else { ua->send_msg(_("Invalid accurate flag.\n")); } break; case 31: /* backupformat */ if (rc.backup_format && !rc.mod) { ua->send_msg(_("Backup Format specified twice.\n")); return false; } rc.backup_format = ua->argv[i]; kw_ok = true; break; default: break; } } /* end strcase compare */ } /* end keyword loop */ /* * End of keyword for loop -- if not found, we got a bogus keyword */ if (!kw_ok) { Dmsg1(800, "%s not found\n", ua->argk[i]); /* * Special case for Job Name, it can be the first * keyword that has no value. */ if (!rc.job_name && !ua->argv[i]) { rc.job_name = ua->argk[i]; /* use keyword as job name */ Dmsg1(800, "Set jobname=%s\n", rc.job_name); } else { ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]); return false; } } } /* end argc loop */ Dmsg0(800, "Done scan.\n"); if (rc.comment) { if (!is_comment_legal(ua, rc.comment)) { return false; } } if (rc.catalog_name) { rc.catalog = GetCatalogResWithName(rc.catalog_name); if (rc.catalog == NULL) { ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name); return false; } if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name(), true)) { ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name()); return false; } } Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name)); if (rc.job_name) { /* Find Job */ rc.job = GetJobResWithName(rc.job_name); if (!rc.job) { if (*rc.job_name != 0) { ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name); } rc.job = select_job_resource(ua); } else { Dmsg1(800, "Found job=%s\n", rc.job_name); } } else if (!rc.job) { ua->send_msg(_("A job name must be specified.\n")); rc.job = select_job_resource(ua); } if (!rc.job) { return false; } else if (!acl_access_ok(ua, Job_ACL, rc.job->name(), true)) { ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name()); return false; } if (rc.pool_name) { rc.pool = GetPoolResWithName(rc.pool_name); if (!rc.pool) { if (*rc.pool_name != 0) { ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name); } rc.pool = select_pool_resource(ua); } } else if (!rc.pool) { rc.pool = rc.job->pool; /* use default */ } if (!rc.pool) { return false; } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name(), true)) { ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name()); return false; } Dmsg1(100, "Using pool %s\n", rc.pool->name()); if (rc.next_pool_name) { rc.next_pool = GetPoolResWithName(rc.next_pool_name); if (!rc.next_pool) { if (*rc.next_pool_name != 0) { ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.next_pool_name); } rc.next_pool = select_pool_resource(ua); } } else if (!rc.next_pool) { rc.next_pool = rc.pool->NextPool; /* use default */ } if (rc.next_pool) { if (!acl_access_ok(ua, Pool_ACL, rc.pool->name(), true)) { ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.next_pool->name()); return false; } Dmsg1(100, "Using next pool %s\n", rc.pool->name()); } if (rc.store_name) { rc.store->store = GetStoreResWithName(rc.store_name); pm_strcpy(rc.store->store_source, _("command line")); if (!rc.store->store) { if (*rc.store_name != 0) { ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name); } rc.store->store = select_storage_resource(ua); pm_strcpy(rc.store->store_source, _("user selection")); } } else if (!rc.store->store) { get_job_storage(rc.store, rc.job, NULL); /* use default */ } /* * For certain Jobs an explicit setting of the read storage is not * required as its determined when the Job is executed automatically. */ switch (rc.job->JobType) { case JT_COPY: case JT_MIGRATE: break; default: if (!rc.store->store) { ua->error_msg(_("No storage specified.\n")); return false; } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name(), true)) { ua->error_msg(_("No authorization. Storage \"%s\".\n"), rc.store->store->name()); return false; } Dmsg1(800, "Using storage=%s\n", rc.store->store->name()); break; } if (rc.client_name) { rc.client = GetClientResWithName(rc.client_name); if (!rc.client) { if (*rc.client_name != 0) { ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name); } rc.client = select_client_resource(ua); } } else if (!rc.client) { rc.client = rc.job->client; /* use default */ } if (rc.client && !acl_access_ok(ua, Client_ACL, rc.client->name(), true)) { ua->error_msg(_("No authorization. Client \"%s\".\n"), rc.client->name()); return false; } Dmsg1(800, "Using client=%s\n", rc.client->name()); if (rc.restore_client_name) { rc.client = GetClientResWithName(rc.restore_client_name); if (!rc.client) { if (*rc.restore_client_name != 0) { ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name); } rc.client = select_client_resource(ua); } } else if (!rc.client) { rc.client = rc.job->client; /* use default */ } if (rc.client && !acl_access_ok(ua, Client_ACL, rc.client->name(), true)) { ua->error_msg(_("No authorization. Client \"%s\".\n"), rc.client->name()); return false; } Dmsg1(800, "Using restore client=%s\n", rc.client->name()); if (rc.fileset_name) { rc.fileset = GetFileSetResWithName(rc.fileset_name); if (!rc.fileset) { ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name); rc.fileset = select_fileset_resource(ua); } } else if (!rc.fileset) { rc.fileset = rc.job->fileset; /* use default */ } if (rc.fileset && !acl_access_ok(ua, FileSet_ACL, rc.fileset->name(), true)) { ua->send_msg(_("No authorization. FileSet \"%s\".\n"), rc.fileset->name()); return false; } if (rc.verify_job_name) { rc.verify_job = GetJobResWithName(rc.verify_job_name); if (!rc.verify_job) { ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name); rc.verify_job = select_job_resource(ua); } } else if (!rc.verify_job) { rc.verify_job = rc.job->verify_job; } if (rc.previous_job_name) { rc.previous_job = GetJobResWithName(rc.previous_job_name); if (!rc.previous_job) { ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name); rc.previous_job = select_job_resource(ua); } } else { rc.previous_job = rc.job->verify_job; } return true; } bareos-Release-14.2.6/src/dird/ua_select.c000066400000000000000000001263511263011562700202710ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Prompt and Selection code * * Kern Sibbald, October MMI */ #include "bareos.h" #include "dird.h" /* Imported variables */ extern struct s_jl joblevels[]; /* * Confirm a retention period */ int confirm_retention(UAContext *ua, utime_t *ret, const char *msg) { char ed1[100]; int val; int yes_in_arg = find_arg(ua, NT_("yes")); for ( ;; ) { ua->info_msg(_("The current %s retention period is: %s\n"), msg, edit_utime(*ret, ed1, sizeof(ed1))); if (yes_in_arg != -1) { return 1; } if (!get_cmd(ua, _("Continue? (yes/mod/no): "))) { return 0; } if (bstrcasecmp(ua->cmd, _("mod"))) { if (!get_cmd(ua, _("Enter new retention period: "))) { return 0; } if (!duration_to_utime(ua->cmd, ret)) { ua->error_msg(_("Invalid period.\n")); continue; } continue; } if (is_yesno(ua->cmd, &val)) { return val; /* is 1 for yes, 0 for no */ } } return 1; } /* * Given a list of keywords, find the first one * that is in the argument list. * Returns: -1 if not found * index into list (base 0) on success */ int find_arg_keyword(UAContext *ua, const char **list) { for (int i = 1; i < ua->argc; i++) { for(int j=0; list[j]; j++) { if (bstrcasecmp(list[j], ua->argk[i])) { return j; } } } return -1; } /* * Given one keyword, find the first one that * is in the argument list. * Returns: argk index (always gt 0) * -1 if not found */ int find_arg(UAContext *ua, const char *keyword) { for (int i = 1; i < ua->argc; i++) { if (bstrcasecmp(keyword, ua->argk[i])) { return i; } } return -1; } /* * Given a single keyword, find it in the argument list, but * it must have a value * Returns: -1 if not found or no value * list index (base 0) on success */ int find_arg_with_value(UAContext *ua, const char *keyword) { for (int i = 1; i < ua->argc; i++) { if (bstrcasecmp(keyword, ua->argk[i])) { if (ua->argv[i]) { return i; } else { return -1; } } } return -1; } /* * Given a list of keywords, prompt the user * to choose one. * * Returns: -1 on failure * index into list (base 0) on success */ int do_keyword_prompt(UAContext *ua, const char *msg, const char **list) { int i; start_prompt(ua, _("You have the following choices:\n")); for (i = 0; list[i]; i++) { add_prompt(ua, list[i]); } return do_prompt(ua, "", msg, NULL, 0); } /* * Select a Storage resource from prompt list */ STORERES *select_storage_resource(UAContext *ua, bool autochanger_only) { char name[MAX_NAME_LENGTH]; STORERES *store; if (autochanger_only) { start_prompt(ua, _("The defined Autochanger Storage resources are:\n")); } else { start_prompt(ua, _("The defined Storage resources are:\n")); } LockRes(); foreach_res(store, R_STORAGE) { if (acl_access_ok(ua, Storage_ACL, store->name())) { if (autochanger_only && !store->autochanger) { continue; } else { add_prompt(ua, store->name()); } } } UnlockRes(); if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) { return NULL; } store = (STORERES *)GetResWithName(R_STORAGE, name); return store; } /* * Select a FileSet resource from prompt list */ FILESETRES *select_fileset_resource(UAContext *ua) { char name[MAX_NAME_LENGTH]; FILESETRES *fs; start_prompt(ua, _("The defined FileSet resources are:\n")); LockRes(); foreach_res(fs, R_FILESET) { if (acl_access_ok(ua, FileSet_ACL, fs->name())) { add_prompt(ua, fs->name()); } } UnlockRes(); if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) { return NULL; } fs = (FILESETRES *)GetResWithName(R_FILESET, name); return fs; } /* * Get a catalog resource from prompt list */ CATRES *get_catalog_resource(UAContext *ua) { char name[MAX_NAME_LENGTH]; CATRES *catalog = NULL; int i; for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("catalog")) && ua->argv[i]) { if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) { catalog = (CATRES *)GetResWithName(R_CATALOG, ua->argv[i]); break; } } } if (ua->gui && !catalog) { LockRes(); catalog = (CATRES *)GetNextRes(R_CATALOG, NULL); UnlockRes(); if (!catalog) { ua->error_msg(_("Could not find a Catalog resource\n")); return NULL; } else if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) { ua->error_msg(_("You must specify a \"use \" command before continuing.\n")); return NULL; } return catalog; } if (!catalog) { start_prompt(ua, _("The defined Catalog resources are:\n")); LockRes(); foreach_res(catalog, R_CATALOG) { if (acl_access_ok(ua, Catalog_ACL, catalog->name())) { add_prompt(ua, catalog->name()); } } UnlockRes(); if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) { return NULL; } catalog = (CATRES *)GetResWithName(R_CATALOG, name); } return catalog; } /* * Select a job to enable or disable */ JOBRES *select_enable_disable_job_resource(UAContext *ua, bool enable) { char name[MAX_NAME_LENGTH]; JOBRES *job; LockRes(); start_prompt(ua, _("The defined Job resources are:\n")); foreach_res(job, R_JOB) { if (!acl_access_ok(ua, Job_ACL, job->name())) { continue; } if (job->enabled == enable) { /* Already enabled/disabled? */ continue; /* yes, skip */ } add_prompt(ua, job->name()); } UnlockRes(); if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) { return NULL; } job = (JOBRES *)GetResWithName(R_JOB, name); return job; } /* * Select a Job resource from prompt list */ JOBRES *select_job_resource(UAContext *ua) { char name[MAX_NAME_LENGTH]; JOBRES *job; start_prompt(ua, _("The defined Job resources are:\n")); LockRes(); foreach_res(job, R_JOB) { if (acl_access_ok(ua, Job_ACL, job->name())) { add_prompt(ua, job->name()); } } UnlockRes(); if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) { return NULL; } job = (JOBRES *)GetResWithName(R_JOB, name); return job; } /* * Select a Restore Job resource from argument or prompt */ JOBRES *get_restore_job(UAContext *ua) { JOBRES *job; int i = find_arg_with_value(ua, NT_("restorejob")); if (i >= 0 && acl_access_ok(ua, Job_ACL, ua->argv[i])) { job = (JOBRES *)GetResWithName(R_JOB, ua->argv[i]); if (job && job->JobType == JT_RESTORE) { return job; } ua->error_msg(_("Error: Restore Job resource \"%s\" does not exist.\n"), ua->argv[i]); } return select_restore_job_resource(ua); } /* * Select a Restore Job resource from prompt list */ JOBRES *select_restore_job_resource(UAContext *ua) { char name[MAX_NAME_LENGTH]; JOBRES *job; start_prompt(ua, _("The defined Restore Job resources are:\n")); LockRes(); foreach_res(job, R_JOB) { if (job->JobType == JT_RESTORE && acl_access_ok(ua, Job_ACL, job->name())) { add_prompt(ua, job->name()); } } UnlockRes(); if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) { return NULL; } job = (JOBRES *)GetResWithName(R_JOB, name); return job; } /* * Select a client resource from prompt list */ CLIENTRES *select_client_resource(UAContext *ua) { char name[MAX_NAME_LENGTH]; CLIENTRES *client; start_prompt(ua, _("The defined Client resources are:\n")); LockRes(); foreach_res(client, R_CLIENT) { if (acl_access_ok(ua, Client_ACL, client->name())) { add_prompt(ua, client->name()); } } UnlockRes(); if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) { return NULL; } client = (CLIENTRES *)GetResWithName(R_CLIENT, name); return client; } /* * Select a client to enable or disable */ CLIENTRES *select_enable_disable_client_resource(UAContext *ua, bool enable) { char name[MAX_NAME_LENGTH]; CLIENTRES *client; LockRes(); start_prompt(ua, _("The defined Client resources are:\n")); foreach_res(client, R_CLIENT) { if (!acl_access_ok(ua, Client_ACL, client->name())) { continue; } if (client->enabled == enable) { /* Already enabled/disabled? */ continue; /* yes, skip */ } add_prompt(ua, client->name()); } UnlockRes(); if (do_prompt(ua, _("Client"), _("Select Client resource"), name, sizeof(name)) < 0) { return NULL; } client = (CLIENTRES *)GetResWithName(R_CLIENT, name); return client; } /* * Get client resource, start by looking for * client= * if we don't find the keyword, we prompt the user. */ CLIENTRES *get_client_resource(UAContext *ua) { CLIENTRES *client = NULL; int i; for (i = 1; i < ua->argc; i++) { if ((bstrcasecmp(ua->argk[i], NT_("client")) || bstrcasecmp(ua->argk[i], NT_("fd"))) && ua->argv[i]) { if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { break; } client = (CLIENTRES *)GetResWithName(R_CLIENT, ua->argv[i]); if (client) { return client; } ua->error_msg(_("Error: Client resource %s does not exist.\n"), ua->argv[i]); break; } } return select_client_resource(ua); } /* * Select a schedule to enable or disable */ SCHEDRES *select_enable_disable_schedule_resource(UAContext *ua, bool enable) { char name[MAX_NAME_LENGTH]; SCHEDRES *sched; LockRes(); start_prompt(ua, _("The defined Schedule resources are:\n")); foreach_res(sched, R_SCHEDULE) { if (!acl_access_ok(ua, Schedule_ACL, sched->name())) { continue; } if (sched->enabled == enable) { /* Already enabled/disabled? */ continue; /* yes, skip */ } add_prompt(ua, sched->name()); } UnlockRes(); if (do_prompt(ua, _("Schedule"), _("Select Schedule resource"), name, sizeof(name)) < 0) { return NULL; } sched = (SCHEDRES *)GetResWithName(R_SCHEDULE, name); return sched; } /* Scan what the user has entered looking for: * * client= * * if error or not found, put up a list of client DBRs * to choose from. * * returns: 0 on error * 1 on success and fills in CLIENT_DBR */ bool get_client_dbr(UAContext *ua, CLIENT_DBR *cr) { int i; if (cr->Name[0]) { /* If name already supplied */ if (db_get_client_record(ua->jcr, ua->db, cr)) { return 1; } ua->error_msg(_("Could not find Client %s: ERR=%s"), cr->Name, db_strerror(ua->db)); } for (i = 1; i < ua->argc; i++) { if ((bstrcasecmp(ua->argk[i], NT_("client")) || bstrcasecmp(ua->argk[i], NT_("fd"))) && ua->argv[i]) { if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) { break; } bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name)); if (!db_get_client_record(ua->jcr, ua->db, cr)) { ua->error_msg(_("Could not find Client \"%s\": ERR=%s"), ua->argv[i], db_strerror(ua->db)); cr->ClientId = 0; break; } return 1; } } if (!select_client_dbr(ua, cr)) { /* try once more by proposing a list */ return 0; } return 1; } /* * Select a Client record from the catalog * Returns 1 on success * 0 on failure */ bool select_client_dbr(UAContext *ua, CLIENT_DBR *cr) { CLIENT_DBR ocr; char name[MAX_NAME_LENGTH]; int num_clients, i; uint32_t *ids; cr->ClientId = 0; if (!db_get_client_ids(ua->jcr, ua->db, &num_clients, &ids)) { ua->error_msg(_("Error obtaining client ids. ERR=%s\n"), db_strerror(ua->db)); return 0; } if (num_clients <= 0) { ua->error_msg(_("No clients defined. You must run a job before using this command.\n")); return 0; } start_prompt(ua, _("Defined Clients:\n")); for (i = 0; i < num_clients; i++) { ocr.ClientId = ids[i]; if (!db_get_client_record(ua->jcr, ua->db, &ocr) || !acl_access_ok(ua, Client_ACL, ocr.Name)) { continue; } add_prompt(ua, ocr.Name); } free(ids); if (do_prompt(ua, _("Client"), _("Select the Client"), name, sizeof(name)) < 0) { return 0; } memset(&ocr, 0, sizeof(ocr)); bstrncpy(ocr.Name, name, sizeof(ocr.Name)); if (!db_get_client_record(ua->jcr, ua->db, &ocr)) { ua->error_msg(_("Could not find Client \"%s\": ERR=%s"), name, db_strerror(ua->db)); return 0; } memcpy(cr, &ocr, sizeof(ocr)); return 1; } /* Scan what the user has entered looking for: * * argk= * * where argk can be : pool, recyclepool, scratchpool, nextpool etc.. * * if error or not found, put up a list of pool DBRs * to choose from. * * returns: false on error * true on success and fills in POOL_DBR */ bool get_pool_dbr(UAContext *ua, POOL_DBR *pr, const char *argk) { if (pr->Name[0]) { /* If name already supplied */ if (db_get_pool_record(ua->jcr, ua->db, pr) && acl_access_ok(ua, Pool_ACL, pr->Name)) { return true; } ua->error_msg(_("Could not find Pool \"%s\": ERR=%s"), pr->Name, db_strerror(ua->db)); } if (!select_pool_dbr(ua, pr, argk)) { /* try once more */ return false; } return true; } /* * Select a Pool record from catalog * argk can be pool, recyclepool, scratchpool etc.. */ bool select_pool_dbr(UAContext *ua, POOL_DBR *pr, const char *argk) { POOL_DBR opr; char name[MAX_NAME_LENGTH]; int num_pools, i; uint32_t *ids; for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], argk) && ua->argv[i] && acl_access_ok(ua, Pool_ACL, ua->argv[i])) { bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name)); if (!db_get_pool_record(ua->jcr, ua->db, pr)) { ua->error_msg(_("Could not find Pool \"%s\": ERR=%s"), ua->argv[i], db_strerror(ua->db)); pr->PoolId = 0; break; } return true; } } pr->PoolId = 0; if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) { ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db)); return 0; } if (num_pools <= 0) { ua->error_msg(_("No pools defined. Use the \"create\" command to create one.\n")); return false; } start_prompt(ua, _("Defined Pools:\n")); if (bstrcmp(argk, NT_("recyclepool"))) { add_prompt(ua, _("*None*")); } for (i = 0; i < num_pools; i++) { opr.PoolId = ids[i]; if (!db_get_pool_record(ua->jcr, ua->db, &opr) || !acl_access_ok(ua, Pool_ACL, opr.Name)) { continue; } add_prompt(ua, opr.Name); } free(ids); if (do_prompt(ua, _("Pool"), _("Select the Pool"), name, sizeof(name)) < 0) { return false; } memset(&opr, 0, sizeof(opr)); /* *None* is only returned when selecting a recyclepool, and in that case * the calling code is only interested in opr.Name, so then we can leave * pr as all zero. */ if (!bstrcmp(name, _("*None*"))) { bstrncpy(opr.Name, name, sizeof(opr.Name)); if (!db_get_pool_record(ua->jcr, ua->db, &opr)) { ua->error_msg(_("Could not find Pool \"%s\": ERR=%s"), name, db_strerror(ua->db)); return false; } } memcpy(pr, &opr, sizeof(opr)); return true; } /* * Select a Pool and a Media (Volume) record from the database */ int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr) { if (!select_media_dbr(ua, mr)) { return 0; } memset(pr, 0, sizeof(POOL_DBR)); pr->PoolId = mr->PoolId; if (!db_get_pool_record(ua->jcr, ua->db, pr)) { ua->error_msg("%s", db_strerror(ua->db)); return 0; } if (!acl_access_ok(ua, Pool_ACL, pr->Name, true)) { ua->error_msg(_("No access to Pool \"%s\"\n"), pr->Name); return 0; } return 1; } /* * Select a Media (Volume) record from the database */ int select_media_dbr(UAContext *ua, MEDIA_DBR *mr) { int i; int ret = 0; POOLMEM *err = get_pool_memory(PM_FNAME); *err=0; memset(mr, 0, sizeof(MEDIA_DBR)); i = find_arg_with_value(ua, NT_("volume")); if (i >= 0) { if (is_name_valid(ua->argv[i], &err)) { bstrncpy(mr->VolumeName, ua->argv[i], sizeof(mr->VolumeName)); } else { goto bail_out; } } if (mr->VolumeName[0] == 0) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); /* * Get the pool from pool= */ if (!get_pool_dbr(ua, &pr)) { goto bail_out; } mr->PoolId = pr.PoolId; db_list_media_records(ua->jcr, ua->db, mr, printit, ua, HORZ_LIST); if (!get_cmd(ua, _("Enter *MediaId or Volume name: "))) { goto bail_out; } if (ua->cmd[0] == '*' && is_a_number(ua->cmd+1)) { mr->MediaId = str_to_int64(ua->cmd+1); } else if (is_name_valid(ua->cmd, &err)) { bstrncpy(mr->VolumeName, ua->cmd, sizeof(mr->VolumeName)); } else { goto bail_out; } } if (!db_get_media_record(ua->jcr, ua->db, mr)) { pm_strcpy(err, db_strerror(ua->db)); goto bail_out; } ret = 1; bail_out: if (!ret && *err) { ua->error_msg("%s", err); } free_pool_memory(err); return ret; } /* * Select a pool resource from prompt list */ POOLRES *select_pool_resource(UAContext *ua) { char name[MAX_NAME_LENGTH]; POOLRES *pool; start_prompt(ua, _("The defined Pool resources are:\n")); LockRes(); foreach_res(pool, R_POOL) { if (acl_access_ok(ua, Pool_ACL, pool->name())) { add_prompt(ua, pool->name()); } } UnlockRes(); if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) { return NULL; } pool = (POOLRES *)GetResWithName(R_POOL, name); return pool; } /* * If you are thinking about using it, you * probably want to use select_pool_dbr() * or get_pool_dbr() above. */ POOLRES *get_pool_resource(UAContext *ua) { POOLRES *pool = NULL; int i; i = find_arg_with_value(ua, NT_("pool")); if (i >= 0 && acl_access_ok(ua, Pool_ACL, ua->argv[i])) { pool = (POOLRES *)GetResWithName(R_POOL, ua->argv[i]); if (pool) { return pool; } ua->error_msg(_("Error: Pool resource \"%s\" does not exist.\n"), ua->argv[i]); } return select_pool_resource(ua); } /* * List all jobs and ask user to select one */ int select_job_dbr(UAContext *ua, JOB_DBR *jr) { db_list_job_records(ua->jcr, ua->db, jr, printit, ua, HORZ_LIST); if (!get_pint(ua, _("Enter the JobId to select: "))) { return 0; } jr->JobId = ua->int64_val; if (!db_get_job_record(ua->jcr, ua->db, jr)) { ua->error_msg("%s", db_strerror(ua->db)); return 0; } return jr->JobId; } /* * Scan what the user has entered looking for: * * jobid=nn * * if error or not found, put up a list of Jobs * to choose from. * * returns: 0 on error * JobId on success and fills in JOB_DBR */ int get_job_dbr(UAContext *ua, JOB_DBR *jr) { int i; for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("ujobid")) && ua->argv[i]) { jr->JobId = 0; bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job)); } else if (bstrcasecmp(ua->argk[i], NT_("jobid")) && ua->argv[i]) { jr->JobId = str_to_int64(ua->argv[i]); jr->Job[0] = 0; } else { continue; } if (!db_get_job_record(ua->jcr, ua->db, jr)) { ua->error_msg(_("Could not find Job \"%s\": ERR=%s"), ua->argv[i], db_strerror(ua->db)); jr->JobId = 0; break; } return jr->JobId; } jr->JobId = 0; jr->Job[0] = 0; for (i = 1; i < ua->argc; i++) { if ((bstrcasecmp(ua->argk[i], NT_("jobname")) || bstrcasecmp(ua->argk[i], NT_("job"))) && ua->argv[i]) { jr->JobId = 0; bstrncpy(jr->Name, ua->argv[i], sizeof(jr->Name)); break; } } if (!select_job_dbr(ua, jr)) { /* try once more */ return 0; } return jr->JobId; } /* * Implement unique set of prompts */ void start_prompt(UAContext *ua, const char *msg) { if (ua->max_prompts == 0) { ua->max_prompts = 10; ua->prompt = (char **)bmalloc(sizeof(char *) * ua->max_prompts); } ua->num_prompts = 1; ua->prompt[0] = bstrdup(msg); } /* * Add to prompts -- keeping them unique */ void add_prompt(UAContext *ua, const char *prompt) { int i; if (ua->num_prompts == ua->max_prompts) { ua->max_prompts *= 2; ua->prompt = (char **)brealloc(ua->prompt, sizeof(char *) * ua->max_prompts); } for (i = 1; i < ua->num_prompts; i++) { if (bstrcmp(ua->prompt[i], prompt)) { return; } } ua->prompt[ua->num_prompts++] = bstrdup(prompt); } /* * Display prompts and get user's choice * * Returns: -1 on error * index base 0 on success, and choice is copied to prompt if not NULL * prompt is set to the chosen prompt item string */ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt) { int i, item; POOL_MEM pmsg(PM_MESSAGE); BSOCK *user = ua->UA_sock; if (prompt) { *prompt = 0; } if (ua->num_prompts == 2) { item = 1; if (prompt) { bstrncpy(prompt, ua->prompt[1], max_prompt); } if (!ua->api) { ua->send_msg(_("Automatically selected %s: %s\n"), automsg, ua->prompt[1]); } goto done; } /* If running non-interactive, bail out */ if (ua->batch) { /* First print the choices he wanted to make */ ua->send_msg(ua->prompt[0]); for (i = 1; i < ua->num_prompts; i++) { ua->send_msg("%6d: %s\n", i, ua->prompt[i]); } /* Now print error message */ ua->send_msg(_("Your request has multiple choices for \"%s\". Selection is not possible in batch mode.\n"), automsg); item = -1; goto done; } if (ua->api) user->signal(BNET_START_SELECT); ua->send_msg(ua->prompt[0]); for (i = 1; i < ua->num_prompts; i++) { if (ua->api) { ua->send_msg("%s", ua->prompt[i]); } else { ua->send_msg("%6d: %s\n", i, ua->prompt[i]); } } if (ua->api) user->signal(BNET_END_SELECT); for ( ;; ) { /* First item is the prompt string, not the items */ if (ua->num_prompts == 1) { ua->error_msg(_("Selection list for \"%s\" is empty!\n"), automsg); item = -1; /* list is empty ! */ break; } if (ua->num_prompts == 2) { item = 1; ua->send_msg(_("Automatically selected: %s\n"), ua->prompt[1]); if (prompt) { bstrncpy(prompt, ua->prompt[1], max_prompt); } break; } else { Mmsg(pmsg, "%s (1-%d): ", msg, ua->num_prompts - 1); } /* Either a . or an @ will get you out of the loop */ if (ua->api) user->signal(BNET_SELECT_INPUT); if (!get_pint(ua, pmsg.c_str())) { item = -1; /* error */ ua->info_msg(_("Selection aborted, nothing done.\n")); break; } item = ua->pint32_val; if (item < 1 || item >= ua->num_prompts) { ua->warning_msg(_("Please enter a number between 1 and %d\n"), ua->num_prompts-1); continue; } if (prompt) { bstrncpy(prompt, ua->prompt[item], max_prompt); } break; } done: for (i = 0; i < ua->num_prompts; i++) { free(ua->prompt[i]); } ua->num_prompts = 0; return item>0 ? item-1 : item; } /* * We scan what the user has entered looking for : * - storage= * - job= * - jobid= * - ? (prompt him with storage list) * - (prompt him with storage list) * * If use_default is set, we assume that any keyword without a value * is the name of the Storage resource wanted. * * If autochangers_only is given, we limit the output to autochangers only. */ STORERES *get_storage_resource(UAContext *ua, bool use_default, bool autochangers_only) { int i; JCR *jcr; int jobid; char ed1[50]; char *store_name = NULL; STORERES *store = NULL; Dmsg1(100, "get_storage_resource: autochangers_only is %d\n", autochangers_only); for (i = 1; i < ua->argc; i++) { /* * Ignore any zapped keyword. */ if (*ua->argk[i] == 0) { continue; } if (use_default && !ua->argv[i]) { /* * Ignore barcode, barcodes, encrypt, scan and slots keywords. */ if (bstrcasecmp("barcode", ua->argk[i]) || bstrcasecmp("barcodes", ua->argk[i]) || bstrcasecmp("encrypt", ua->argk[i]) || bstrcasecmp("scan", ua->argk[i]) || bstrcasecmp("slots", ua->argk[i])) { continue; } /* * Default argument is storage */ if (store_name) { ua->error_msg(_("Storage name given twice.\n")); return NULL; } store_name = ua->argk[i]; if (*store_name == '?') { *store_name = 0; break; } } else { if (bstrcasecmp(ua->argk[i], NT_("storage")) || bstrcasecmp(ua->argk[i], NT_("sd"))) { store_name = ua->argv[i]; break; } else if (bstrcasecmp(ua->argk[i], NT_("jobid"))) { jobid = str_to_int64(ua->argv[i]); if (jobid <= 0) { ua->error_msg(_("Expecting jobid=nn command, got: %s\n"), ua->argk[i]); return NULL; } if (!(jcr = get_jcr_by_id(jobid))) { ua->error_msg(_("JobId %s is not running.\n"), edit_int64(jobid, ed1)); return NULL; } store = jcr->res.wstore; free_jcr(jcr); break; } else if (bstrcasecmp(ua->argk[i], NT_("job")) || bstrcasecmp(ua->argk[i], NT_("jobname"))) { if (!ua->argv[i]) { ua->error_msg(_("Expecting job=xxx, got: %s.\n"), ua->argk[i]); return NULL; } if (!(jcr = get_jcr_by_partial_name(ua->argv[i]))) { ua->error_msg(_("Job \"%s\" is not running.\n"), ua->argv[i]); return NULL; } store = jcr->res.wstore; free_jcr(jcr); break; } else if (bstrcasecmp(ua->argk[i], NT_("ujobid"))) { if (!ua->argv[i]) { ua->error_msg(_("Expecting ujobid=xxx, got: %s.\n"), ua->argk[i]); return NULL; } if (!(jcr = get_jcr_by_full_name(ua->argv[i]))) { ua->error_msg(_("Job \"%s\" is not running.\n"), ua->argv[i]); return NULL; } store = jcr->res.wstore; free_jcr(jcr); break; } } } if (store && !acl_access_ok(ua, Storage_ACL, store->name())) { store = NULL; } if (!store && store_name && store_name[0] != 0) { store = (STORERES *)GetResWithName(R_STORAGE, store_name); if (!store) { ua->error_msg(_("Storage resource \"%s\": not found\n"), store_name); } } if (store && !acl_access_ok(ua, Storage_ACL, store->name())) { store = NULL; } /* No keywords found, so present a selection list */ if (!store) { store = select_storage_resource(ua, autochangers_only); } return store; } /* Get drive that we are working with for this storage */ int get_storage_drive(UAContext *ua, STORERES *store) { int i, drive = -1; unsigned int cnt; char drivename[10]; /* * Get drive for autochanger if possible */ i = find_arg_with_value(ua, NT_("drive")); if (i >= 0) { drive = atoi(ua->argv[i]); } else if (store && store->autochanger) { /* * If our structure is not set ask SD for # drives */ if (store->drives == 0) { store->drives = get_num_drives_from_SD(ua); } /* * If only one drive, default = 0 */ if (store->drives == 1) { drive = 0; } else { /* * Ask user to enter drive number */ start_prompt(ua, _("Select Drive:\n")); for (cnt = 0; cnt < store->drives; cnt++) { bsnprintf(drivename, sizeof(drivename), "Drive %d", cnt); add_prompt(ua, drivename); } if (do_prompt(ua, _("Drive"), _("Select drive"), drivename, sizeof(drivename)) < 0) { drive = -1; /* None */ } else { sscanf(drivename, "Drive %d", &drive); } } } else { /* * If only one drive, default = 0 */ drive = 0; } return drive; } /* Get slot that we are working with for this storage */ int get_storage_slot(UAContext *ua, STORERES *store) { int i, slot = -1; /* Get slot for autochanger if possible */ i = find_arg_with_value(ua, NT_("slot")); if (i >=0) { slot = atoi(ua->argv[i]); } else if (store && store->autochanger) { /* Ask user to enter slot number */ ua->cmd[0] = 0; if (!get_cmd(ua, _("Enter autochanger slot: "))) { slot = -1; /* None */ } else { slot = atoi(ua->cmd); } } return slot; } /* * Scan looking for mediatype= * * if not found or error, put up selection list * * Returns: 0 on error * 1 on success, MediaType is set */ int get_media_type(UAContext *ua, char *MediaType, int max_media) { STORERES *store; int i; i = find_arg_with_value(ua, NT_("mediatype")); if (i >= 0) { bstrncpy(MediaType, ua->argv[i], max_media); return 1; } start_prompt(ua, _("Media Types defined in conf file:\n")); LockRes(); foreach_res(store, R_STORAGE) { add_prompt(ua, store->media_type); } UnlockRes(); return (do_prompt(ua, _("Media Type"), _("Select the Media Type"), MediaType, max_media) < 0) ? 0 : 1; } bool get_level_from_name(JCR *jcr, const char *level_name) { /* Look up level name and pull code */ bool found = false; for (int i = 0; joblevels[i].level_name; i++) { if (bstrcasecmp(level_name, joblevels[i].level_name)) { jcr->setJobLevel(joblevels[i].level); found = true; break; } } return found; } /* * Insert an JobId into the list of selected JobIds when its a unique new id. */ static inline bool insert_selected_jobid(alist *selected_jobids, JobId_t JobId) { bool found; JobId_t *selected_jobid; found = false; foreach_alist(selected_jobid, selected_jobids) { if (*selected_jobid == JobId) { found = true; break; } } if (!found) { selected_jobid = (JobId_t *)malloc(sizeof(JobId_t)); *selected_jobid = JobId; selected_jobids->append(selected_jobid); return true; } return false; } /* * Get a job selection, "reason" is used in user messages and can be: cancel, limit, ... * * Returns: NULL on error * alist on success with the selected jobids. */ alist *select_jobs(UAContext *ua, const char *reason) { int i; int cnt = 0; int njobs = 0; JCR *jcr = NULL; bool select_all = false; bool select_by_state = false; alist *selected_jobids; const char *lst[] = { "job", "jobid", "ujobid", NULL }; enum { none, all_jobs, created_jobs, blocked_jobs, waiting_jobs, running_jobs } selection_criterium; /* * Allocate a list for holding the selected JobIds. */ selected_jobids = New(alist(10, owned_by_alist)); /* * See if "all" is given. */ if (find_arg(ua, NT_("all")) > 0) { select_all = true; } /* * See if "state=" is given. */ if (find_arg_with_value(ua, NT_("state")) > 0) { select_by_state = true; } /* * See if there are any jobid, job or ujobid keywords. */ if (find_arg_keyword(ua, lst) > 0) { for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("jobid"))) { JobId_t JobId = str_to_int64(ua->argv[i]); if (!JobId) { continue; } if (!(jcr = get_jcr_by_id(JobId))) { ua->error_msg(_("JobId %s is not running. Use Job name to %s inactive jobs.\n"), ua->argv[i], _(reason)); continue; } } else if (bstrcasecmp(ua->argk[i], NT_("job"))) { if (!ua->argv[i]) { continue; } if (!(jcr = get_jcr_by_partial_name(ua->argv[i]))) { ua->warning_msg(_("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]); continue; } } else if (bstrcasecmp(ua->argk[i], NT_("ujobid"))) { if (!ua->argv[i]) { continue; } if (!(jcr = get_jcr_by_full_name(ua->argv[i]))) { ua->warning_msg(_("Warning Job %s is not running. Continuing anyway ...\n"), ua->argv[i]); continue; } } if (jcr) { if (jcr->res.job && !acl_access_ok(ua, Job_ACL, jcr->res.job->name(), true)) { ua->error_msg(_("Unauthorized command from this console.\n")); goto bail_out; } if (insert_selected_jobid(selected_jobids, jcr->JobId)) { cnt++; } free_jcr(jcr); jcr = NULL; } } } /* * If we didn't select any Jobs using jobid, job or ujobid keywords try other selections. */ if (cnt == 0) { char buf[1000]; int tjobs = 0; /* Total # number jobs */ /* * Count Jobs running */ foreach_jcr(jcr) { if (jcr->JobId == 0) { /* This is us */ continue; } tjobs++; /* Count of all jobs */ if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { continue; /* Skip not authorized */ } njobs++; /* Count of authorized jobs */ } endeach_jcr(jcr); if (njobs == 0) { /* No authorized */ if (tjobs == 0) { ua->send_msg(_("No Jobs running.\n")); } else { ua->send_msg(_("None of your jobs are running.\n")); } goto bail_out; } if (select_all || select_by_state) { /* * Set selection criterium. */ selection_criterium = none; if (select_all) { selection_criterium = all_jobs; } else { i = find_arg_with_value(ua, NT_("state")); if (i > 0) { if (bstrcasecmp(ua->argv[i], NT_("created"))) { selection_criterium = created_jobs; } if (bstrcasecmp(ua->argv[i], NT_("blocked"))) { selection_criterium = blocked_jobs; } if (bstrcasecmp(ua->argv[i], NT_("waiting"))) { selection_criterium = waiting_jobs; } if (bstrcasecmp(ua->argv[i], NT_("running"))) { selection_criterium = running_jobs; } if (selection_criterium == none) { ua->error_msg(_("Illegal state either created, blocked, waiting or running\n")); goto bail_out; } } } /* * Select from all available Jobs the Jobs matching the selection criterium. */ foreach_jcr(jcr) { if (jcr->JobId == 0) { /* This is us */ continue; } if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { continue; /* Skip not authorized */ } /* * See if we need to select this JobId. */ switch (selection_criterium) { case all_jobs: break; case created_jobs: if (jcr->JobStatus != JS_Created) { continue; } break; case blocked_jobs: if (!jcr->job_started || jcr->JobStatus != JS_Blocked) { continue; } break; case waiting_jobs: if (!job_waiting(jcr)) { continue; } break; case running_jobs: if (!jcr->job_started || jcr->JobStatus != JS_Running) { continue; } break; default: break; } insert_selected_jobid(selected_jobids, jcr->JobId); ua->send_msg(_("Selected Job %d for cancelling\n") , jcr->JobId); } if (selected_jobids->empty()) { ua->send_msg(_("No Jobs selected.\n")); goto bail_out; } /* * Only ask for confirmation when not in batch mode and there is no yes on the cmdline. */ if (!ua->batch && find_arg(ua, NT_("yes")) == -1) { if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) { goto bail_out; } } } else { char temp[256]; char JobName[MAX_NAME_LENGTH]; /* * Interactivly select a Job. */ start_prompt(ua, _("Select Job:\n")); foreach_jcr(jcr) { char ed1[50]; if (jcr->JobId == 0) { /* This is us */ continue; } if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { continue; /* Skip not authorized */ } bsnprintf(buf, sizeof(buf), _("JobId=%s Job=%s"), edit_int64(jcr->JobId, ed1), jcr->Job); add_prompt(ua, buf); } endeach_jcr(jcr); bsnprintf(temp, sizeof(temp), _("Choose Job to %s"), _(reason)); if (do_prompt(ua, _("Job"), temp, buf, sizeof(buf)) < 0) { goto bail_out; } if (bstrcmp(reason, "cancel")) { if (ua->api && njobs == 1) { char nbuf[1000]; bsnprintf(nbuf, sizeof(nbuf), _("Cancel: %s\n\n%s"), buf, _("Confirm cancel?")); if (!get_yesno(ua, nbuf) || ua->pint32_val == 0) { goto bail_out; } } else { if (njobs == 1) { if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) { goto bail_out; } } } } sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName); jcr = get_jcr_by_full_name(JobName); if (!jcr) { ua->warning_msg(_("Job \"%s\" not found.\n"), JobName); goto bail_out; } insert_selected_jobid(selected_jobids, jcr->JobId); free_jcr(jcr); } } return selected_jobids; bail_out: delete selected_jobids; return NULL; } /* * Get a slot selection. * * Returns: false on error * true on success with the selected slots set in the slot_list. */ bool get_user_slot_list(UAContext *ua, char *slot_list, const char *argument, int num_slots) { int i, len, beg, end; const char *msg; char search_argument[20]; char *p, *e, *h; /* * See if the argument given is found on the cmdline. */ bstrncpy(search_argument, argument, sizeof(search_argument)); i = find_arg_with_value(ua, search_argument); if (i == -1) { /* not found */ /* * See if the last letter of search_argument is a 's' * When it is strip it and try if that argument is given. */ len = strlen(search_argument); if (len > 0 && search_argument[len - 1] == 's') { search_argument[len - 1] = '\0'; i = find_arg_with_value(ua, search_argument); } } if (i > 0) { /* * Scan slot list in ua->argv[i] */ strip_trailing_junk(ua->argv[i]); for (p = ua->argv[i]; p && *p; p = e) { /* * Check for list */ e = strchr(p, ','); if (e) { *e++ = 0; } /* * Check for range */ h = strchr(p, '-'); /* range? */ if (h == p) { msg = _("Negative numbers not permitted\n"); goto bail_out; } if (h) { *h++ = 0; if (!is_an_integer(h)) { msg = _("Range end is not integer.\n"); goto bail_out; } skip_spaces(&p); if (!is_an_integer(p)) { msg = _("Range start is not an integer.\n"); goto bail_out; } beg = atoi(p); end = atoi(h); if (end < beg) { msg = _("Range end not bigger than start.\n"); goto bail_out; } } else { skip_spaces(&p); if (!is_an_integer(p)) { msg = _("Input value is not an integer.\n"); goto bail_out; } beg = end = atoi(p); } if (beg <= 0 || end <= 0) { msg = _("Values must be be greater than zero.\n"); goto bail_out; } if (end > num_slots) { msg = _("Slot too large.\n"); goto bail_out; } /* * Turn on specified range */ for (i = beg; i <= end; i++) { set_bit(i - 1, slot_list); } } } else { /* * Turn everything on */ for (i = 1; i <= num_slots; i++) { set_bit(i - 1, slot_list); } } if (debug_level >= 100) { Dmsg0(100, "Slots turned on:\n"); for (i = 1; i <= num_slots; i++) { if (bit_is_set(i - 1, slot_list)) { Dmsg1(100, "%d\n", i); } } } return true; bail_out: Dmsg1(100, "Problem with user selection ERR=%s\n", msg); return false; } bareos-Release-14.2.6/src/dird/ua_server.c000066400000000000000000000141461263011562700203160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Server * * Kern Sibbald, September MM */ #include "bareos.h" #include "dird.h" /* Imported variables */ /* Forward referenced functions */ extern "C" void *connect_thread(void *arg); static void *handle_UA_client_request(void *arg); /* Global variables */ static int started = FALSE; static workq_t ua_workq; static alist *sock_fds; static pthread_t tcp_server_tid; struct s_addr_port { char *addr; char *port; }; /* Called here by Director daemon to start UA (user agent) * command thread. This routine creates the thread and then * returns. */ void start_UA_server(dlist *addrs) { int status; static dlist *myaddrs = addrs; if ((status = pthread_create(&tcp_server_tid, NULL, connect_thread, (void *)myaddrs)) != 0) { berrno be; Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.bstrerror(status)); } started = TRUE; return; } void stop_UA_server() { if (!started) { return; } bnet_stop_thread_server_tcp(tcp_server_tid); cleanup_bnet_thread_server_tcp(sock_fds, &ua_workq); delete sock_fds; sock_fds = NULL; } extern "C" void *connect_thread(void *arg) { pthread_detach(pthread_self()); set_jcr_in_tsd(INVALID_JCR); /* Permit MaxConsoleConnect console connections */ sock_fds = New(alist(10, not_owned_by_alist)); bnet_thread_server_tcp((dlist*)arg, me->MaxConsoleConnect, sock_fds, &ua_workq, me->nokeepalive, handle_UA_client_request); return NULL; } /* * Create a Job Control Record for a control "job", filling in all the appropriate fields. */ JCR *new_control_jcr(const char *base_name, int job_type) { JCR *jcr; jcr = new_jcr(sizeof(JCR), dird_free_jcr); /* * The job and defaults are not really used, but * we set them up to ensure that everything is correctly * initialized. */ LockRes(); jcr->res.job = (JOBRES *)GetNextRes(R_JOB, NULL); set_jcr_defaults(jcr, jcr->res.job); UnlockRes(); jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */ create_unique_job_name(jcr, base_name); jcr->sched_time = jcr->start_time; jcr->setJobType(job_type); jcr->setJobLevel(L_NONE); jcr->setJobStatus(JS_Running); jcr->JobId = 0; return jcr; } /* * Handle Director User Agent commands */ static void *handle_UA_client_request(void *arg) { int status; UAContext *ua; JCR *jcr; BSOCK *user = (BSOCK *)arg; pthread_detach(pthread_self()); jcr = new_control_jcr("-Console-", JT_CONSOLE); ua = new_ua_context(jcr); ua->UA_sock = user; set_jcr_in_tsd(INVALID_JCR); user->recv(); /* Get first message */ if (!authenticate_user_agent(ua)) { goto getout; } while (!ua->quit) { if (ua->api) { user->signal(BNET_MAIN_PROMPT); } status = user->recv(); if (status >= 0) { pm_strcpy(ua->cmd, ua->UA_sock->msg); parse_ua_args(ua); if (ua->argc > 0 && ua->argk[0][0] == '.') { do_a_dot_command(ua); } else { do_a_command(ua); } dequeue_messages(ua->jcr); if (!ua->quit) { if (console_msg_pending && acl_access_ok(ua, Command_ACL, "messages")) { if (ua->auto_display_messages) { pm_strcpy(ua->cmd, "messages"); qmessages_cmd(ua, ua->cmd); ua->user_notified_msg_pending = false; } else if (!ua->gui && !ua->user_notified_msg_pending && console_msg_pending) { if (ua->api) { user->signal(BNET_MSGS_PENDING); } else { bsendmsg(ua, _("You have messages.\n")); } ua->user_notified_msg_pending = true; } } if (!ua->api) { user->signal(BNET_EOD); /* send end of command */ } } } else if (is_bnet_stop(user)) { ua->quit = true; } else { /* signal */ user->signal(BNET_POLL); } } getout: close_db(ua); free_ua_context(ua); free_jcr(jcr); user->close(); delete user; return NULL; } /* * Create a UAContext for a Job that is running so that * it can the User Agent routines and * to ensure that the Job gets the proper output. * This is a sort of mini-kludge, and should be * unified at some point. */ UAContext *new_ua_context(JCR *jcr) { UAContext *ua; ua = (UAContext *)malloc(sizeof(UAContext)); memset(ua, 0, sizeof(UAContext)); ua->jcr = jcr; ua->db = jcr->db; ua->cmd = get_pool_memory(PM_FNAME); ua->args = get_pool_memory(PM_FNAME); ua->errmsg = get_pool_memory(PM_FNAME); ua->verbose = true; ua->automount = true; return ua; } void free_ua_context(UAContext *ua) { if (ua->cmd) { free_pool_memory(ua->cmd); } if (ua->args) { free_pool_memory(ua->args); } if (ua->errmsg) { free_pool_memory(ua->errmsg); } if (ua->prompt) { free(ua->prompt); } if (ua->UA_sock) { ua->UA_sock->close(); ua->UA_sock = NULL; } free(ua); } bareos-Release-14.2.6/src/dird/ua_status.c000066400000000000000000001405441263011562700203350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Status Command * * Kern Sibbald, August MMI */ #include "bareos.h" #include "dird.h" #define DEFAULT_STATUS_SCHED_DAYS 7 extern void *start_heap; static void list_scheduled_jobs(UAContext *ua); static void list_running_jobs(UAContext *ua); static void list_terminated_jobs(UAContext *ua); static void do_director_status(UAContext *ua); static void do_scheduler_status(UAContext *ua); static bool do_subscription_status(UAContext *ua); static void do_all_status(UAContext *ua); static void status_slots(UAContext *ua, STORERES *store); static void status_content(UAContext *ua, STORERES *store); static char OKqstatus[] = "1000 OK .status\n"; static char DotStatusJob[] = "JobId=%s JobStatus=%c JobErrors=%d\n"; /* * .status command */ bool dot_status_cmd(UAContext *ua, const char *cmd) { STORERES *store; CLIENTRES *client; JCR* njcr = NULL; s_last_job* job; char ed1[50]; Dmsg2(20, "status=\"%s\" argc=%d\n", cmd, ua->argc); if (ua->argc < 3) { ua->send_msg("1900 Bad .status command, missing arguments.\n"); return false; } if (bstrcasecmp(ua->argk[1], "dir")) { if (bstrcasecmp(ua->argk[2], "current")) { ua->send_msg(OKqstatus, ua->argk[2]); foreach_jcr(njcr) { if (njcr->JobId != 0 && acl_access_ok(ua, Job_ACL, njcr->res.job->name())) { ua->send_msg(DotStatusJob, edit_int64(njcr->JobId, ed1), njcr->JobStatus, njcr->JobErrors); } } endeach_jcr(njcr); } else if (bstrcasecmp(ua->argk[2], "last")) { ua->send_msg(OKqstatus, ua->argk[2]); if ((last_jobs) && (last_jobs->size() > 0)) { job = (s_last_job*)last_jobs->last(); if (acl_access_ok(ua, Job_ACL, job->Job)) { ua->send_msg(DotStatusJob, edit_int64(job->JobId, ed1), job->JobStatus, job->Errors); } } } else if (bstrcasecmp(ua->argk[2], "header")) { list_dir_status_header(ua); } else if (bstrcasecmp(ua->argk[2], "scheduled")) { list_scheduled_jobs(ua); } else if (bstrcasecmp(ua->argk[2], "running")) { list_running_jobs(ua); } else if (bstrcasecmp(ua->argk[2], "terminated")) { list_terminated_jobs(ua); } else { ua->send_msg("1900 Bad .status command, wrong argument.\n"); return false; } } else if (bstrcasecmp(ua->argk[1], "client")) { client = get_client_resource(ua); if (client) { Dmsg2(200, "Client=%s arg=%s\n", client->name(), NPRT(ua->argk[2])); switch (client->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_client_status(ua, client, ua->argk[2]); break; default: do_native_client_status(ua, client, ua->argk[2]); break; } } } else if (bstrcasecmp(ua->argk[1], "storage")) { store = get_storage_resource(ua); if (store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_storage_status(ua, store, ua->argk[2]); break; default: do_native_storage_status(ua, store, ua->argk[2]); break; } } } else { ua->send_msg("1900 Bad .status command, wrong argument.\n"); return false; } return true; } /* This is the *old* command handler, so we must return * 1 or it closes the connection */ int qstatus_cmd(UAContext *ua, const char *cmd) { dot_status_cmd(ua, cmd); return 1; } /* * status command */ int status_cmd(UAContext *ua, const char *cmd) { STORERES *store; CLIENTRES *client; int item, i; bool autochangers_only; Dmsg1(20, "status:%s:\n", cmd); for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], NT_("all"))) { do_all_status(ua); return 1; } else if (bstrncasecmp(ua->argk[i], NT_("dir"), 3)) { do_director_status(ua); return 1; } else if (bstrcasecmp(ua->argk[i], NT_("client"))) { client = get_client_resource(ua); if (client) { switch (client->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_client_status(ua, client, NULL); break; default: do_native_client_status(ua, client, NULL); break; } } return 1; } else if (bstrncasecmp(ua->argk[i], NT_("sched"), 5)) { do_scheduler_status(ua); return 1; } else if (bstrncasecmp(ua->argk[i], NT_("sub"), 3)) { if (do_subscription_status(ua)) { return 1; } else { return 0; } } else { /* * limit storages to autochangers if slots is given */ autochangers_only = (find_arg(ua, NT_("slots")) > 0); store = get_storage_resource(ua, false, autochangers_only); if (store) { if (find_arg(ua, NT_("slots")) > 0) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: break; default: status_slots(ua, store); break; } } else { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_storage_status(ua, store, NULL); break; default: do_native_storage_status(ua, store, NULL); break; } } } return 1; } } /* If no args, ask for status type */ if (ua->argc == 1) { char prmt[MAX_NAME_LENGTH]; start_prompt(ua, _("Status available for:\n")); add_prompt(ua, NT_("Director")); add_prompt(ua, NT_("Storage")); add_prompt(ua, NT_("Client")); add_prompt(ua, NT_("Scheduler")); add_prompt(ua, NT_("All")); Dmsg0(20, "do_prompt: select daemon\n"); if ((item=do_prompt(ua, "", _("Select daemon type for status"), prmt, sizeof(prmt))) < 0) { return 1; } Dmsg1(20, "item=%d\n", item); switch (item) { case 0: /* Director */ do_director_status(ua); break; case 1: store = select_storage_resource(ua); if (store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_storage_status(ua, store, NULL); break; default: do_native_storage_status(ua, store, NULL); break; } } break; case 2: client = select_client_resource(ua); if (client) { switch (client->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_client_status(ua, client, NULL); break; default: do_native_client_status(ua, client, NULL); break; } } break; case 3: do_scheduler_status(ua); break; case 4: do_all_status(ua); break; default: break; } } return 1; } static void do_all_status(UAContext *ua) { STORERES *store, **unique_store; CLIENTRES *client, **unique_client; int i, j; bool found; do_director_status(ua); /* Count Storage items */ LockRes(); i = 0; foreach_res(store, R_STORAGE) { i++; } unique_store = (STORERES **) malloc(i * sizeof(STORERES)); /* Find Unique Storage address/port */ i = 0; foreach_res(store, R_STORAGE) { found = false; if (!acl_access_ok(ua, Storage_ACL, store->name())) { continue; } for (j = 0; j < i; j++) { if (bstrcmp(unique_store[j]->address, store->address) && unique_store[j]->SDport == store->SDport) { found = true; break; } } if (!found) { unique_store[i++] = store; Dmsg2(40, "Stuffing: %s:%d\n", store->address, store->SDport); } } UnlockRes(); /* Call each unique Storage daemon */ for (j = 0; j < i; j++) { switch (unique_store[j]->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_storage_status(ua, unique_store[j], NULL); break; default: do_native_storage_status(ua, unique_store[j], NULL); break; } } free(unique_store); /* Count Client items */ LockRes(); i = 0; foreach_res(client, R_CLIENT) { i++; } unique_client = (CLIENTRES **)malloc(i * sizeof(CLIENTRES)); /* Find Unique Client address/port */ i = 0; foreach_res(client, R_CLIENT) { found = false; if (!acl_access_ok(ua, Client_ACL, client->name())) { continue; } for (j = 0; j < i; j++) { if (bstrcmp(unique_client[j]->address, client->address) && unique_client[j]->FDport == client->FDport) { found = true; break; } } if (!found) { unique_client[i++] = client; Dmsg2(40, "Stuffing: %s:%d\n", client->address, client->FDport); } } UnlockRes(); /* Call each unique File daemon */ for (j = 0; j < i; j++) { switch (unique_client[j]->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: do_ndmp_client_status(ua, unique_client[j], NULL); break; default: do_native_client_status(ua, unique_client[j], NULL); break; } } free(unique_client); } void list_dir_status_header(UAContext *ua) { int len; char dt[MAX_TIME_LENGTH]; char b1[35], b2[35], b3[35], b4[35], b5[35]; POOL_MEM msg(PM_FNAME); ua->send_msg(_("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER); bstrftime_nc(dt, sizeof(dt), daemon_start_time); ua->send_msg(_("Daemon started %s. Jobs: run=%d, running=%d mode=%d\n"), dt, num_jobs_run, job_count(), (int)DEVELOPER_MODE); ua->send_msg(_(" Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"), edit_uint64_with_commas((char *)sbrk(0)-(char *)start_heap, b1), edit_uint64_with_commas(sm_bytes, b2), edit_uint64_with_commas(sm_max_bytes, b3), edit_uint64_with_commas(sm_buffers, b4), edit_uint64_with_commas(sm_max_buffers, b5)); len = list_dir_plugins(msg); if (len > 0) { ua->send_msg("%s\n", msg.c_str()); } } static bool show_scheduled_preview(UAContext *ua, SCHEDRES *sched, POOL_MEM &overview, int *max_date_len, struct tm tm, time_t time_to_check) { int date_len, hour, mday, wday, month, wom, woy, yday; bool is_last_week = false; /* Are we in the last week of a month? */ char dt[MAX_TIME_LENGTH]; time_t runtime; RUNRES *run; POOL_MEM temp(PM_NAME); hour = tm.tm_hour; mday = tm.tm_mday - 1; wday = tm.tm_wday; month = tm.tm_mon; wom = mday / 7; woy = tm_woy(time_to_check); /* Get week of year */ yday = tm.tm_yday; /* Get day of year */ is_last_week = is_doy_in_last_week(tm.tm_year + 1900 , yday); for (run = sched->run; run; run = run->next) { bool run_now; int cnt = 0; run_now = bit_is_set(hour, run->hour) && bit_is_set(mday, run->mday) && bit_is_set(wday, run->wday) && bit_is_set(month, run->month) && (bit_is_set(wom, run->wom) || (run->last_set && is_last_week)) && bit_is_set(woy, run->woy); if (run_now) { /* * Find time (time_t) job is to be run */ blocaltime(&time_to_check, &tm); /* Reset tm structure */ tm.tm_min = run->minute; /* Set run minute */ tm.tm_sec = 0; /* Zero secs */ /* * Convert the time into a user parsable string. * As we use locale specific strings for weekday and month we * need to keep track of the longest data string used. */ runtime = mktime(&tm); bstrftime_wd(dt, sizeof(dt), runtime); date_len = strlen(dt); if (date_len > *max_date_len) { if (*max_date_len == 0) { /* * When the datelen changes during the loop the locale generates a date string that * is variable. Only thing we can do about that is start from scratch again. * We invoke this by return false from this function. */ *max_date_len = date_len; pm_strcpy(overview, ""); return false; } else { /* * This is the first determined length we use this until we are proven wrong. */ *max_date_len = date_len; } } Mmsg(temp, "%-*s %-22.22s ", *max_date_len, dt, sched->hdr.name); pm_strcat(overview, temp.c_str()); if (run->level) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Level=%s", level_to_str(run->level)); pm_strcat(overview, temp.c_str()); } if (run->Priority) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Priority=%d", run->Priority); pm_strcat(overview, temp.c_str()); } if (run->spool_data_set) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Spool Data=%d", run->spool_data); pm_strcat(overview, temp.c_str()); } if (run->accurate_set) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Accurate=%d", run->accurate); pm_strcat(overview, temp.c_str()); } if (run->pool) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Pool=%s", run->pool->name()); pm_strcat(overview, temp.c_str()); } if (run->storage) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Storage=%s", run->storage->name()); pm_strcat(overview, temp.c_str()); } if (run->msgs) { if (cnt++ > 0) { pm_strcat(overview, " "); } Mmsg(temp, "Messages=%s", run->msgs->name()); pm_strcat(overview, temp.c_str()); } pm_strcat(overview, "\n"); } } /* * If we make it till here the length of the datefield is constant or didn't change. */ return true; } /* * Check the number of clients in the DB against the configured number of subscriptions * * Return true if (number of clients < number of subscriptions), else * return false */ static bool do_subscription_status(UAContext *ua) { int available; bool retval = false; /* * See if we need to check. */ if (me->subscriptions == 0) { ua->send_msg(_("No subscriptions configured in director.\n")); retval = true; goto bail_out; } if (me->subscriptions_used <= 0) { ua->error_msg(_("No clients defined.\n")); goto bail_out; } else { available = me->subscriptions - me->subscriptions_used; if (available < 0) { ua->send_msg(_("Warning! No available subscriptions: %d (%d/%d) (used/total)\n"), available, me->subscriptions_used, me->subscriptions); } else { ua->send_msg(_("Ok: available subscriptions: %d (%d/%d) (used/total)\n"), available, me->subscriptions_used, me->subscriptions); retval = true; } } bail_out: return retval; } static void do_scheduler_status(UAContext *ua) { int i; int max_date_len = 0; int days = DEFAULT_STATUS_SCHED_DAYS; /* Default days for preview */ bool schedulegiven = false; time_t time_to_check, now, start, stop; char schedulename[MAX_NAME_LENGTH]; const int seconds_per_day = 86400; /* Number of seconds in one day */ const int seconds_per_hour = 3600; /* Number of seconds in one hour */ struct tm tm; CLIENTRES *client = NULL; JOBRES *job = NULL; SCHEDRES *sched; POOL_MEM overview(PM_MESSAGE); now = time(NULL); /* Initialize to now */ time_to_check = now; i = find_arg_with_value(ua, NT_("days")); if (i >= 0) { days = atoi(ua->argv[i]); if (((days < -366) || (days > 366)) && !ua->api) { ua->send_msg(_("Ignoring invalid value for days. Allowed is -366 < days < 366.\n")); days = DEFAULT_STATUS_SCHED_DAYS; } } /* * Schedule given ? */ i = find_arg_with_value(ua, NT_("schedule")); if (i >= 0) { bstrncpy(schedulename, ua->argv[i], sizeof(schedulename)); schedulegiven = true; } /* * Client given ? */ i = find_arg_with_value(ua, NT_("client")); if (i >= 0) { client = get_client_resource(ua); } /* * Jobname given ? */ i = find_arg_with_value(ua, NT_("job")); if (i >= 0) { job = GetJobResWithName(ua->argv[i]); /* * If a bogus jobname was given ask for it interactively. */ if (!job) { job = select_job_resource(ua); } } ua->send_msg("Scheduler Jobs:\n\n"); ua->send_msg("Schedule Jobs Triggered\n"); ua->send_msg("===========================================================\n"); LockRes(); foreach_res(sched, R_SCHEDULE) { int cnt = 0; if (!schedulegiven && !sched->enabled) { continue; } if (!acl_access_ok(ua, Schedule_ACL, sched->hdr.name)) { continue; } if (schedulegiven) { if (!bstrcmp(sched->hdr.name, schedulename)) { continue; } } if (job) { if (job->schedule && bstrcmp(sched->hdr.name, job->schedule->hdr.name)) { if (cnt++ == 0) { ua->send_msg("%s\n", sched->hdr.name); } ua->send_msg(" %s\n", job->name()); } } else { foreach_res(job, R_JOB) { if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) { continue; } if (client && job->client != client) { continue; } if (job->schedule && bstrcmp(sched->hdr.name, job->schedule->hdr.name)) { if (cnt++ == 0) { ua->send_msg("%s\n", sched->hdr.name); } if (job->enabled && (!job->client || job->client->enabled)) { ua->send_msg(" %s\n", job->name()); } else { ua->send_msg(" %s (disabled)\n", job->name()); } } } } if (cnt > 0) { ua->send_msg("\n"); } } UnlockRes(); /* * Build an overview. */ if (days > 0) { /* future */ start = now; stop = now + (days * seconds_per_day); } else { /* past */ start = now + (days * seconds_per_day); stop = now; } start_again: time_to_check = start; while (time_to_check < stop) { blocaltime(&time_to_check, &tm); if (client || job) { /* * List specific schedule. */ if (job) { if (job->schedule) { if (!show_scheduled_preview(ua, job->schedule, overview, &max_date_len, tm, time_to_check)) { goto start_again; } } } else { LockRes(); foreach_res(job, R_JOB) { if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) { continue; } if (job->schedule && job->client == client) { if (!show_scheduled_preview(ua, job->schedule, overview, &max_date_len, tm, time_to_check)) { job = NULL; UnlockRes(); goto start_again; } } } UnlockRes(); job = NULL; } } else { /* * List all schedules. */ LockRes(); foreach_res(sched, R_SCHEDULE) { if (!acl_access_ok(ua, Schedule_ACL, sched->hdr.name)) { continue; } if (schedulegiven) { if (!bstrcmp(sched->hdr.name, schedulename)) { continue; } } if (!show_scheduled_preview(ua, sched, overview, &max_date_len, tm, time_to_check)) { UnlockRes(); goto start_again; } } UnlockRes(); } time_to_check += seconds_per_hour; /* next hour */ } ua->send_msg("====\n\n"); ua->send_msg("Scheduler Preview for %d days:\n\n", days); ua->send_msg("%-*s %-22s %s\n", max_date_len, _("Date"), _("Schedule"), _("Overrides")); ua->send_msg("==============================================================\n"); ua->send_msg(overview.c_str()); ua->send_msg("====\n"); } static void do_director_status(UAContext *ua) { list_dir_status_header(ua); /* * List scheduled Jobs */ list_scheduled_jobs(ua); /* * List running jobs */ list_running_jobs(ua); /* * List terminated jobs */ list_terminated_jobs(ua); ua->send_msg("====\n"); } static void prt_runhdr(UAContext *ua) { if (!ua->api) { ua->send_msg(_("\nScheduled Jobs:\n")); ua->send_msg(_("Level Type Pri Scheduled Name Volume\n")); ua->send_msg(_("===================================================================================\n")); } } /* Scheduling packet */ struct sched_pkt { dlink link; /* keep this as first item!!! */ JOBRES *job; int level; int priority; utime_t runtime; POOLRES *pool; STORERES *store; }; static void prt_runtime(UAContext *ua, sched_pkt *sp) { char dt[MAX_TIME_LENGTH]; const char *level_ptr; bool ok = false; bool close_db = false; JCR *jcr = ua->jcr; MEDIA_DBR mr; int orig_jobtype; memset(&mr, 0, sizeof(mr)); orig_jobtype = jcr->getJobType(); if (sp->job->JobType == JT_BACKUP) { jcr->db = NULL; ok = complete_jcr_for_job(jcr, sp->job, sp->pool); Dmsg1(250, "Using pool=%s\n", jcr->res.pool->name()); if (jcr->db) { close_db = true; /* new db opened, remember to close it */ } if (ok) { mr.PoolId = jcr->jr.PoolId; jcr->res.wstore = sp->store; set_storageid_in_mr(jcr->res.wstore, &mr); Dmsg0(250, "call find_next_volume_for_append\n"); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ ok = find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_no_prune); } if (!ok) { bstrncpy(mr.VolumeName, "*unknown*", sizeof(mr.VolumeName)); } } bstrftime_nc(dt, sizeof(dt), sp->runtime); switch (sp->job->JobType) { case JT_ADMIN: case JT_RESTORE: level_ptr = " "; break; default: level_ptr = level_to_str(sp->level); break; } if (ua->api) { ua->send_msg(_("%-14s\t%-8s\t%3d\t%-18s\t%-18s\t%s\n"), level_ptr, job_type_to_str(sp->job->JobType), sp->priority, dt, sp->job->name(), mr.VolumeName); } else { ua->send_msg(_("%-14s %-8s %3d %-18s %-18s %s\n"), level_ptr, job_type_to_str(sp->job->JobType), sp->priority, dt, sp->job->name(), mr.VolumeName); } if (close_db) { db_sql_close_pooled_connection(jcr, jcr->db); } jcr->db = ua->db; /* restore ua db to jcr */ jcr->setJobType(orig_jobtype); } /* * Sort items by runtime, priority */ static int compare_by_runtime_priority(void *item1, void *item2) { sched_pkt *p1 = (sched_pkt *)item1; sched_pkt *p2 = (sched_pkt *)item2; if (p1->runtime < p2->runtime) { return -1; } else if (p1->runtime > p2->runtime) { return 1; } if (p1->priority < p2->priority) { return -1; } else if (p1->priority > p2->priority) { return 1; } return 0; } /* * Find all jobs to be run in roughly the next 24 hours. */ static void list_scheduled_jobs(UAContext *ua) { utime_t runtime; RUNRES *run; JOBRES *job; int level, num_jobs = 0; int priority; bool hdr_printed = false; dlist sched; sched_pkt *sp; int days, i; Dmsg0(200, "enter list_sched_jobs()\n"); days = 1; i = find_arg_with_value(ua, NT_("days")); if (i >= 0) { days = atoi(ua->argv[i]); if (((days < 0) || (days > 500)) && !ua->api) { ua->send_msg(_("Ignoring invalid value for days. Max is 500.\n")); days = 1; } } /* * Loop through all jobs */ LockRes(); foreach_res(job, R_JOB) { if (!acl_access_ok(ua, Job_ACL, job->name()) || !job->enabled || (job->client && !job->client->enabled)) { continue; } for (run = NULL; (run = find_next_run(run, job, runtime, days)); ) { USTORERES store; level = job->JobLevel; if (run->level) { level = run->level; } priority = job->Priority; if (run->Priority) { priority = run->Priority; } if (!hdr_printed) { prt_runhdr(ua); hdr_printed = true; } sp = (sched_pkt *)malloc(sizeof(sched_pkt)); sp->job = job; sp->level = level; sp->priority = priority; sp->runtime = runtime; sp->pool = run->pool; get_job_storage(&store, job, run); sp->store = store.store; Dmsg3(250, "job=%s store=%s MediaType=%s\n", job->name(), sp->store->name(), sp->store->media_type); sched.binary_insert_multiple(sp, compare_by_runtime_priority); num_jobs++; } } /* end for loop over resources */ UnlockRes(); foreach_dlist(sp, &sched) { prt_runtime(ua, sp); } if (num_jobs == 0 && !ua->api) { ua->send_msg(_("No Scheduled Jobs.\n")); } if (!ua->api) ua->send_msg("====\n"); Dmsg0(200, "Leave list_sched_jobs_runs()\n"); } static void list_running_jobs(UAContext *ua) { JCR *jcr; int njobs = 0; const char *msg; char *emsg; /* edited message */ char dt[MAX_TIME_LENGTH]; char level[10]; bool pool_mem = false; Dmsg0(200, "enter list_run_jobs()\n"); if (!ua->api) ua->send_msg(_("\nRunning Jobs:\n")); foreach_jcr(jcr) { if (jcr->JobId == 0) { /* this is us */ /* this is a console or other control job. We only show console * jobs in the status output. */ if (jcr->is_JobType(JT_CONSOLE) && !ua->api) { bstrftime_nc(dt, sizeof(dt), jcr->start_time); ua->send_msg(_("Console connected at %s\n"), dt); } continue; } njobs++; } endeach_jcr(jcr); if (njobs == 0) { /* Note the following message is used in regress -- don't change */ if (!ua->api) ua->send_msg(_("No Jobs running.\n====\n")); Dmsg0(200, "leave list_run_jobs()\n"); return; } njobs = 0; if (!ua->api) { ua->send_msg(_(" JobId Level Name Status\n")); ua->send_msg(_("======================================================================\n")); } foreach_jcr(jcr) { if (jcr->JobId == 0 || !acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { continue; } njobs++; switch (jcr->JobStatus) { case JS_Created: msg = _("is waiting execution"); break; case JS_Running: msg = _("is running"); break; case JS_Blocked: msg = _("is blocked"); break; case JS_Terminated: msg = _("has terminated"); break; case JS_Warnings: msg = _("has terminated with warnings"); break; case JS_ErrorTerminated: msg = _("has erred"); break; case JS_Error: msg = _("has errors"); break; case JS_FatalError: msg = _("has a fatal error"); break; case JS_Differences: msg = _("has verify differences"); break; case JS_Canceled: msg = _("has been canceled"); break; case JS_WaitFD: emsg = (char *) get_pool_memory(PM_FNAME); if (!jcr->res.client) { Mmsg(emsg, _("is waiting on Client")); } else { Mmsg(emsg, _("is waiting on Client %s"), jcr->res.client->name()); } pool_mem = true; msg = emsg; break; case JS_WaitSD: emsg = (char *) get_pool_memory(PM_FNAME); if (jcr->res.wstore) { Mmsg(emsg, _("is waiting on Storage \"%s\""), jcr->res.wstore->name()); } else if (jcr->res.rstore) { Mmsg(emsg, _("is waiting on Storage \"%s\""), jcr->res.rstore->name()); } else { Mmsg(emsg, _("is waiting on Storage")); } pool_mem = true; msg = emsg; break; case JS_WaitStoreRes: msg = _("is waiting on max Storage jobs"); break; case JS_WaitClientRes: msg = _("is waiting on max Client jobs"); break; case JS_WaitJobRes: msg = _("is waiting on max Job jobs"); break; case JS_WaitMaxJobs: msg = _("is waiting on max total jobs"); break; case JS_WaitStartTime: emsg = (char *) get_pool_memory(PM_FNAME); if (jcr->sched_time) { char dt[MAX_TIME_LENGTH]; bstrftime_nc(dt, sizeof(dt), jcr->sched_time); Mmsg(emsg, _("is waiting for its start time at %s"), dt); } else { Mmsg(emsg, _("is waiting for its start time")); } pool_mem = true; msg = emsg; break; case JS_WaitPriority: msg = _("is waiting for higher priority jobs to finish"); break; case JS_DataCommitting: msg = _("SD committing Data"); break; case JS_DataDespooling: msg = _("SD despooling Data"); break; case JS_AttrDespooling: msg = _("SD despooling Attributes"); break; case JS_AttrInserting: msg = _("Dir inserting Attributes"); break; default: emsg = (char *)get_pool_memory(PM_FNAME); Mmsg(emsg, _("is in unknown state %c"), jcr->JobStatus); pool_mem = true; msg = emsg; break; } /* * Now report Storage daemon status code */ switch (jcr->SDJobStatus) { case JS_WaitMount: if (pool_mem) { free_pool_memory(emsg); pool_mem = false; } msg = _("is waiting for a mount request"); break; case JS_WaitMedia: if (pool_mem) { free_pool_memory(emsg); pool_mem = false; } msg = _("is waiting for an appendable Volume"); break; case JS_WaitFD: if (!pool_mem) { emsg = (char *)get_pool_memory(PM_FNAME); pool_mem = true; } if (!jcr->res.client || !jcr->res.wstore) { Mmsg(emsg, _("is waiting for Client to connect to Storage daemon")); } else { Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"), jcr->res.client->name(), jcr->res.wstore->name()); } msg = emsg; break; case JS_DataCommitting: msg = _("SD committing Data"); break; case JS_DataDespooling: msg = _("SD despooling Data"); break; case JS_AttrDespooling: msg = _("SD despooling Attributes"); break; case JS_AttrInserting: msg = _("Dir inserting Attributes"); break; } switch (jcr->getJobType()) { case JT_ADMIN: case JT_RESTORE: bstrncpy(level, " ", sizeof(level)); break; default: bstrncpy(level, level_to_str(jcr->getJobLevel()), sizeof(level)); level[7] = 0; break; } if (ua->api) { bash_spaces(jcr->comment); ua->send_msg(_("%6d\t%-6s\t%-20s\t%s\t%s\n"), jcr->JobId, level, jcr->Job, msg, jcr->comment); unbash_spaces(jcr->comment); } else { ua->send_msg(_("%6d %-6s %-20s %s\n"), jcr->JobId, level, jcr->Job, msg); /* Display comments if any */ if (*jcr->comment) { ua->send_msg(_(" %-30s\n"), jcr->comment); } } if (pool_mem) { free_pool_memory(emsg); pool_mem = false; } } endeach_jcr(jcr); if (!ua->api) ua->send_msg("====\n"); Dmsg0(200, "leave list_run_jobs()\n"); } static void list_terminated_jobs(UAContext *ua) { char dt[MAX_TIME_LENGTH], b1[30], b2[30]; char level[10]; if (last_jobs->empty()) { if (!ua->api) ua->send_msg(_("No Terminated Jobs.\n")); return; } lock_last_jobs_list(); struct s_last_job *je; if (!ua->api) { ua->send_msg(_("\nTerminated Jobs:\n")); ua->send_msg(_(" JobId Level Files Bytes Status Finished Name \n")); ua->send_msg(_("====================================================================\n")); } foreach_dlist(je, last_jobs) { char JobName[MAX_NAME_LENGTH]; const char *termstat; bstrncpy(JobName, je->Job, sizeof(JobName)); /* There are three periods after the Job name */ char *p; for (int i = 0; i < 3; i++) { if ((p=strrchr(JobName, '.')) != NULL) { *p = 0; } } if (!acl_access_ok(ua, Job_ACL, JobName)) { continue; } bstrftime_nc(dt, sizeof(dt), je->end_time); switch (je->JobType) { case JT_ADMIN: case JT_RESTORE: bstrncpy(level, " ", sizeof(level)); break; default: bstrncpy(level, level_to_str(je->JobLevel), sizeof(level)); level[4] = 0; break; } switch (je->JobStatus) { case JS_Created: termstat = _("Created"); break; case JS_FatalError: case JS_ErrorTerminated: termstat = _("Error"); break; case JS_Differences: termstat = _("Diffs"); break; case JS_Canceled: termstat = _("Cancel"); break; case JS_Terminated: termstat = _("OK"); break; case JS_Warnings: termstat = _("OK -- with warnings"); break; default: termstat = _("Other"); break; } if (ua->api) { ua->send_msg(_("%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"), je->JobId, level, edit_uint64_with_commas(je->JobFiles, b1), edit_uint64_with_suffix(je->JobBytes, b2), termstat, dt, JobName); } else { ua->send_msg(_("%6d %-6s %8s %10s %-7s %-8s %s\n"), je->JobId, level, edit_uint64_with_commas(je->JobFiles, b1), edit_uint64_with_suffix(je->JobBytes, b2), termstat, dt, JobName); } } if (!ua->api) ua->send_msg(_("\n")); unlock_last_jobs_list(); } static void content_send_info(UAContext *ua, char type, int Slot, char *vol_name) { char ed1[50], ed2[50], ed3[50]; POOL_DBR pr; MEDIA_DBR mr; /* Type|Slot|RealSlot|Volume|Bytes|Status|MediaType|Pool|LastW|Expire */ const char *slot_api_full_format="%c|%d|%d|%s|%s|%s|%s|%s|%s|%s\n"; memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, vol_name, sizeof(mr.VolumeName)); if (db_get_media_record(ua->jcr, ua->db, &mr)) { pr.PoolId = mr.PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { strcpy(pr.Name, "?"); } ua->send_msg(slot_api_full_format, type, Slot, mr.Slot, mr.VolumeName, edit_uint64(mr.VolBytes, ed1), mr.VolStatus, mr.MediaType, pr.Name, edit_uint64(mr.LastWritten, ed2), edit_uint64(mr.LastWritten+mr.VolRetention, ed3)); } else { /* Media unknown */ ua->send_msg(slot_api_full_format, type, Slot, 0, mr.VolumeName, "?", "?", "?", "?", "0", "0"); } } /* * Input (output of mxt-changer listall): * * Drive content: D:Drive num:F:Slot loaded:Volume Name * D:0:F:2:vol2 or D:Drive num:E * D:1:F:42:vol42 * D:3:E * * Slot content: * S:1:F:vol1 S:Slot num:F:Volume Name * S:2:E or S:Slot num:E * S:3:F:vol4 * * Import/Export tray slots: * I:10:F:vol10 I:Slot num:F:Volume Name * I:11:E or I:Slot num:E * I:12:F:vol40 * * If a drive is loaded, the slot *should* be empty * * Output: * * Drive list: D|Drive num|Slot loaded|Volume Name * D|0|45|vol45 * D|1|42|vol42 * D|3|| * * Slot list: Type|Slot|RealSlot|Volume|Bytes|Status|MediaType|Pool|LastW|Expire * * S|1|1|vol1|31417344|Full|LTO1-ANSI|Inc|1250858902|1282394902 * S|2|||||||| * S|3|3|vol4|15869952|Append|LTO1-ANSI|Inc|1250858907|1282394907 * */ static void status_content(UAContext *ua, STORERES *store) { bool found; vol_list_t *vl1, *vl2; dlist *vol_list = NULL; const char *slot_api_drive_full_format="%c|%d|%d|%s\n"; const char *slot_api_drive_empty_format="%c|%d||\n"; const char *slot_api_slot_empty_format="%c|%d||||||||\n"; if (!open_client_db(ua)) { return; } vol_list = get_vol_list_from_SD(ua, store, true /* listall */ , true /* want to see all slots */); if (!vol_list) { ua->warning_msg(_("No Volumes found, or no barcodes.\n")); goto bail_out; } foreach_dlist(vl1, vol_list) { switch (vl1->Type) { case slot_type_drive: switch (vl1->Content) { case slot_content_full: ua->send_msg(slot_api_drive_full_format, 'D', vl1->Slot, vl1->Loaded, vl1->VolName); break; case slot_content_empty: ua->send_msg(slot_api_drive_empty_format, 'D', vl1->Slot); break; default: break; } break; case slot_type_normal: case slot_type_import: switch (vl1->Content) { case slot_content_full: switch (vl1->Type) { case slot_type_normal: content_send_info(ua, 'S', vl1->Slot, vl1->VolName); break; case slot_type_import: content_send_info(ua, 'I', vl1->Slot, vl1->VolName); break; default: break; } break; case slot_content_empty: /* * See if this empty slot is empty because the volume is loaded * in one of the drives. */ found = false; vl2 = (vol_list_t *)vol_list->first(); while (!found && vl2) { switch (vl2->Type) { case slot_type_drive: if (vl1->Slot == vl2->Loaded) { switch (vl1->Type) { case slot_type_normal: content_send_info(ua, 'S', vl1->Slot, vl2->VolName); break; case slot_type_import: content_send_info(ua, 'I', vl1->Slot, vl2->VolName); break; default: break; } found = true; /* * When we used this entry we can remove it from * the list so we limit the search time next round. */ vol_list->remove(vl2); if (vl2->VolName) { free(vl2->VolName); } free(vl2); continue; } break; default: break; } vl2 = (vol_list_t *)vol_list->next((void *)vl2); } if (!found) { switch (vl1->Type) { case slot_type_normal: ua->send_msg(slot_api_slot_empty_format, 'S', vl1->Slot); break; case slot_type_import: ua->send_msg(slot_api_slot_empty_format, 'I', vl1->Slot); break; default: break; } } break; default: break; } default: break; } } bail_out: if (vol_list) { free_vol_list(vol_list); } close_sd_bsock(ua); return; } /* * Print slots from AutoChanger */ static void status_slots(UAContext *ua, STORERES *store_r) { USTORERES store; POOL_DBR pr; vol_list_t *vl1, *vl2; dlist *vol_list = NULL; MEDIA_DBR mr; char *slot_list; int max_slots; bool is_loaded_in_drive; /* * Slot | Volume | Status | MediaType | Pool */ const char *slot_hformat=" %4i%c| %16s | %9s | %14s | %24s |\n"; if (ua->api) { status_content(ua, store_r); return; } if (!open_client_db(ua)) { return; } memset(&mr, 0, sizeof(mr)); store.store = store_r; pm_strcpy(store.store_source, _("command line")); set_wstorage(ua->jcr, &store); max_slots = get_num_slots_from_SD(ua); if (max_slots <= 0) { ua->warning_msg(_("No slots in changer to scan.\n")); return; } slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, slot_list); if (!get_user_slot_list(ua, slot_list, "slots", max_slots)) { free(slot_list); return; } vol_list = get_vol_list_from_SD(ua, store.store, true /* listall */ , true /* want to see all slots */); if (!vol_list) { ua->warning_msg(_("No Volumes found, or no barcodes.\n")); goto bail_out; } ua->send_msg(_(" Slot | Volume Name | Status | Media Type | Pool |\n")); ua->send_msg(_("------+------------------+-----------+----------------+--------------------------|\n")); /* * Walk through the list getting the media records * Slots start numbering at 1. */ foreach_dlist(vl1, vol_list) { switch (vl1->Type) { case slot_type_drive: /* * We are not interested in drive slots. */ continue; case slot_type_normal: case slot_type_import: if (vl1->Slot > max_slots) { ua->warning_msg(_("Slot %d greater than max %d ignored.\n"), vl1->Slot, max_slots); continue; } /* * Check if user wants us to look at this slot */ if (!bit_is_set(vl1->Slot - 1, slot_list)) { Dmsg1(100, "Skipping slot=%d\n", vl1->Slot); continue; } vl2 = NULL; is_loaded_in_drive = false; switch (vl1->Content) { case slot_content_empty: if (vl1->Type == slot_type_normal) { /* * See if this empty slot is empty because the volume is loaded * in one of the drives. */ vl2 = (vol_list_t *)vol_list->first(); while (!is_loaded_in_drive && vl2) { switch (vl2->Type) { case slot_type_drive: if (vl1->Slot == vl2->Loaded) { is_loaded_in_drive = true; continue; } break; default: break; } vl2 = (vol_list_t *)vol_list->next((void *)vl2); } if (!is_loaded_in_drive) { ua->send_msg(slot_hformat, vl1->Slot, '*', "?", "?", "?", "?"); continue; } } else { ua->send_msg(slot_hformat, vl1->Slot, '@', "?", "?", "?", "?"); continue; } /* * Note, fall through wanted */ case slot_content_full: /* * We get here for all slots with content and for empty * slots with their volume loaded in a drive. */ if (vl1->Content == slot_content_full) { if (!vl1->VolName) { Dmsg1(100, "No VolName for Slot=%d.\n", vl1->Slot); ua->send_msg(slot_hformat, vl1->Slot, (vl1->Type == slot_type_import) ? '@' : '*', "?", "?", "?", "?"); continue; } memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, vl1->VolName, sizeof(mr.VolumeName)); } else { if (!vl2 || !vl2->VolName) { Dmsg1(100, "No VolName for Slot=%d.\n", vl1->Slot); ua->send_msg(slot_hformat, vl1->Slot, (vl1->Type == slot_type_import) ? '@' : '*', "?", "?", "?", "?"); continue; } memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, vl2->VolName, sizeof(mr.VolumeName)); } if (mr.VolumeName[0] && db_get_media_record(ua->jcr, ua->db, &mr)) { memset(&pr, 0, sizeof(pr)); pr.PoolId = mr.PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { strcpy(pr.Name, "?"); } /* * Print information */ if (vl1->Type == slot_type_import) { ua->send_msg(slot_hformat, vl1->Slot, '@', mr.VolumeName, mr.VolStatus, mr.MediaType, pr.Name); } else { ua->send_msg(slot_hformat, vl1->Slot, ((vl1->Slot == mr.Slot) ? (is_loaded_in_drive ? '%' : ' ') : '*'), mr.VolumeName, mr.VolStatus, mr.MediaType, pr.Name); } } else { ua->send_msg(slot_hformat, vl1->Slot, (vl1->Type == slot_type_import) ? '@' : '*', mr.VolumeName, "?", "?", "?"); } break; default: break; } break; default: break; } } bail_out: if (vol_list) { free_vol_list(vol_list); } free(slot_list); close_sd_bsock(ua); return; } bareos-Release-14.2.6/src/dird/ua_tree.c000066400000000000000000001020021263011562700177340ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- User Agent Database File tree for Restore * command. This file interacts with the user implementing the * UA tree commands. * * Kern Sibbald, July MMII */ #include "bareos.h" #include "dird.h" #ifdef HAVE_FNMATCH #include #else #include "lib/fnmatch.h" #endif #include "findlib/find.h" /* Forward referenced commands */ static int markcmd(UAContext *ua, TREE_CTX *tree); static int markdircmd(UAContext *ua, TREE_CTX *tree); static int countcmd(UAContext *ua, TREE_CTX *tree); static int findcmd(UAContext *ua, TREE_CTX *tree); static int lscmd(UAContext *ua, TREE_CTX *tree); static int lsmarkcmd(UAContext *ua, TREE_CTX *tree); static int dircmd(UAContext *ua, TREE_CTX *tree); static int dot_dircmd(UAContext *ua, TREE_CTX *tree); static int estimatecmd(UAContext *ua, TREE_CTX *tree); static int helpcmd(UAContext *ua, TREE_CTX *tree); static int cdcmd(UAContext *ua, TREE_CTX *tree); static int pwdcmd(UAContext *ua, TREE_CTX *tree); static int dot_pwdcmd(UAContext *ua, TREE_CTX *tree); static int unmarkcmd(UAContext *ua, TREE_CTX *tree); static int unmarkdircmd(UAContext *ua, TREE_CTX *tree); static int quitcmd(UAContext *ua, TREE_CTX *tree); static int donecmd(UAContext *ua, TREE_CTX *tree); static int dot_lsdircmd(UAContext *ua, TREE_CTX *tree); static int dot_lscmd(UAContext *ua, TREE_CTX *tree); static int dot_helpcmd(UAContext *ua, TREE_CTX *tree); static int dot_lsmarkcmd(UAContext *ua, TREE_CTX *tree); struct cmdstruct { const char *key; int (*func)(UAContext *ua, TREE_CTX *tree); const char *help; }; static struct cmdstruct commands[] = { { NT_("abort"), quitcmd, _("abort and do not do restore") }, { NT_("add"), markcmd, _("add dir/file to be restored recursively, wildcards allowed") }, { NT_("cd"), cdcmd, _("change current directory") }, { NT_("count"), countcmd, _("count marked files in and below the cd") }, { NT_("delete"), unmarkcmd, _("delete dir/file to be restored recursively in dir") }, { NT_("dir"), dircmd, _("long list current directory, wildcards allowed") }, { NT_(".dir"), dot_dircmd, _("long list current directory, wildcards allowed") }, { NT_("done"), donecmd, _("leave file selection mode") }, { NT_("estimate"), estimatecmd, _("estimate restore size") }, { NT_("exit"), donecmd, _("same as done command") }, { NT_("find"), findcmd, _("find files, wildcards allowed") }, { NT_("help"), helpcmd, _("print help") }, { NT_("ls"), lscmd, _("list current directory, wildcards allowed") }, { NT_(".ls"), dot_lscmd, _("list current directory, wildcards allowed") }, { NT_(".lsdir"), dot_lsdircmd, _("list subdir in current directory, wildcards allowed") }, { NT_("lsmark"), lsmarkcmd, _("list the marked files in and below the cd") }, { NT_(".lsmark"), dot_lsmarkcmd,_("list the marked files in") }, { NT_("mark"), markcmd, _("mark dir/file to be restored recursively, wildcards allowed") }, { NT_("markdir"), markdircmd, _("mark directory name to be restored (no files)") }, { NT_("pwd"), pwdcmd, _("print current working directory") }, { NT_(".pwd"), dot_pwdcmd, _("print current working directory") }, { NT_("unmark"), unmarkcmd, _("unmark dir/file to be restored recursively in dir") }, { NT_("unmarkdir"), unmarkdircmd, _("unmark directory name only no recursion") }, { NT_("quit"), quitcmd, _("quit and do not do restore") }, { NT_(".help"), dot_helpcmd, _("print help") }, { NT_("?"), helpcmd, _("print help") }, }; #define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct))) /* * Enter a prompt mode where the user can select/deselect * files to be restored. This is sort of like a mini-shell * that allows "cd", "pwd", "add", "rm", ... */ bool user_select_files_from_tree(TREE_CTX *tree) { POOLMEM *cwd; UAContext *ua; BSOCK *user; bool status; /* * Get a new context so we don't destroy restore command args */ ua = new_ua_context(tree->ua->jcr); ua->UA_sock = tree->ua->UA_sock; /* patch in UA socket */ ua->api = tree->ua->api; /* keep API flag too */ user = ua->UA_sock; ua->send_msg(_("\nYou are now entering file selection mode where you add (mark) and\n" "remove (unmark) files to be restored. No files are initially added, unless\n" "you used the \"all\" keyword on the command line.\n" "Enter \"done\" to leave this mode.\n\n")); user->signal(BNET_START_RTREE); /* * Enter interactive command handler allowing selection of individual files. */ tree->node = (TREE_NODE *)tree->root; cwd = tree_getpath(tree->node); if (cwd) { ua->send_msg(_("cwd is: %s\n"), cwd); free_pool_memory(cwd); } while (1) { int found, len, i; if (!get_cmd(ua, "$ ", true)) { break; } if (ua->api) { user->signal(BNET_CMD_BEGIN); } parse_args_only(ua->cmd, &ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS); if (ua->argc == 0) { ua->warning_msg(_("Invalid command \"%s\". Enter \"done\" to exit.\n"), ua->cmd); if (ua->api) { user->signal(BNET_CMD_FAILED); } continue; } found = 0; status = false; len = strlen(ua->argk[0]); for (i = 0; i < comsize; i++) { /* search for command */ if (bstrncasecmp(ua->argk[0], commands[i].key, len)) { status = (*commands[i].func)(ua, tree); /* go execute command */ found = 1; break; } } if (!found) { if (*ua->argk[0] == '.') { /* Some unknow dot command -- probably .messages, ignore it */ continue; } ua->warning_msg(_("Invalid command \"%s\". Enter \"done\" to exit.\n"), ua->cmd); if (ua->api) { user->signal(BNET_CMD_FAILED); } continue; } if (ua->api) { user->signal(BNET_CMD_OK); } if (!status) { break; } } user->signal(BNET_END_RTREE); ua->UA_sock = NULL; /* don't release restore socket */ status = !ua->quit; ua->quit = false; free_ua_context(ua); /* get rid of temp UA context */ return status; } /* * This callback routine is responsible for inserting the * items it gets into the directory tree. For each JobId selected * this routine is called once for each file. We do not allow * duplicate filenames, but instead keep the info from the most * recent file entered (i.e. the JobIds are assumed to be sorted) * * See uar_sel_files in sql_cmds.c for query that calls us. * row[0]=Path, row[1]=Filename, row[2]=FileIndex * row[3]=JobId row[4]=LStat row[5]=DeltaSeq */ int insert_tree_handler(void *ctx, int num_fields, char **row) { struct stat statp; TREE_CTX *tree = (TREE_CTX *)ctx; TREE_NODE *node; int type; bool hard_link, ok; int FileIndex; int32_t delta_seq; JobId_t JobId; HL_ENTRY *entry = NULL; int32_t LinkFI; Dmsg4(150, "Path=%s%s FI=%s JobId=%s\n", row[0], row[1], row[2], row[3]); if (*row[1] == 0) { /* no filename => directory */ if (!IsPathSeparator(*row[0])) { /* Must be Win32 directory */ type = TN_DIR_NLS; } else { type = TN_DIR; } } else { type = TN_FILE; } decode_stat(row[4], &statp, sizeof(statp), &LinkFI); hard_link = (LinkFI != 0); node = insert_tree_node(row[0], row[1], type, tree->root, NULL); JobId = str_to_int64(row[3]); FileIndex = str_to_int64(row[2]); delta_seq = str_to_int64(row[5]); Dmsg6(150, "node=0x%p JobId=%s FileIndex=%s Delta=%s node.delta=%d LinkFI=%d\n", node, row[3], row[2], row[5], node->delta_seq, LinkFI); /* * TODO: check with hardlinks */ if (delta_seq > 0) { if (delta_seq == (node->delta_seq + 1)) { tree_add_delta_part(tree->root, node, node->JobId, node->FileIndex); } else { /* File looks to be deleted */ if (node->delta_seq == -1) { /* just created */ tree_remove_node(tree->root, node); } else { tree->ua->warning_msg(_("Something is wrong with the Delta sequence of %s, " "skiping new parts. Current sequence is %d\n"), row[1], node->delta_seq); Dmsg3(0, "Something is wrong with Delta, skip it " "fname=%s d1=%d d2=%d\n", row[1], node->delta_seq, delta_seq); } return 0; } } /* * - The first time we see a file (node->inserted==true), we accept it. * - In the same JobId, we accept only the first copy of a * hard linked file (the others are simply pointers). * - In the same JobId, we accept the last copy of any other * file -- in particular directories. * * All the code to set ok could be condensed to a single * line, but it would be even harder to read. */ ok = true; if (!node->inserted && JobId == node->JobId) { if ((hard_link && FileIndex > node->FileIndex) || (!hard_link && FileIndex < node->FileIndex)) { ok = false; } } if (ok) { node->hard_link = hard_link; node->FileIndex = FileIndex; node->JobId = JobId; node->type = type; node->soft_link = S_ISLNK(statp.st_mode) != 0; node->delta_seq = delta_seq; if (tree->all) { node->extract = true; /* extract all by default */ if (type == TN_DIR || type == TN_DIR_NLS) { node->extract_dir = true; /* if dir, extract it */ } } /* * Insert file having hardlinks into hardlink hashtable. */ if (statp.st_nlink > 1 && type != TN_DIR && type != TN_DIR_NLS) { if (!LinkFI) { /* * First occurence - file hardlinked to */ entry = (HL_ENTRY *)tree->root->hardlinks.hash_malloc(sizeof(HL_ENTRY)); entry->key = (((uint64_t) JobId) << 32) + FileIndex; entry->node = node; tree->root->hardlinks.insert(entry->key, entry); } else { /* * See if we are optimizing for speed or size. */ if (!me->optimize_for_size && me->optimize_for_speed) { /* * Hardlink to known file index: lookup original file */ uint64_t file_key = (((uint64_t) JobId) << 32) + LinkFI; HL_ENTRY *first_hl = (HL_ENTRY *) tree->root->hardlinks.lookup(file_key); if (first_hl && first_hl->node) { /* * Then add hardlink entry to linked node. */ entry = (HL_ENTRY *)tree->root->hardlinks.hash_malloc(sizeof(HL_ENTRY)); entry->key = (((uint64_t) JobId) << 32) + FileIndex; entry->node = first_hl->node; tree->root->hardlinks.insert(entry->key, entry); } } } } } if (node->inserted) { tree->FileCount++; if (tree->DeltaCount > 0 && (tree->FileCount-tree->LastCount) > tree->DeltaCount) { tree->ua->send_msg("+"); tree->LastCount = tree->FileCount; } } tree->cnt++; return 0; } /* * Set extract to value passed. We recursively walk down the tree setting all children * if the node is a directory. */ static int set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, bool extract) { TREE_NODE *n; int count = 0; node->extract = extract; if (node->type == TN_DIR || node->type == TN_DIR_NLS) { node->extract_dir = extract; /* set/clear dir too */ } if (node->type != TN_NEWDIR) { count++; } /* * For a non-file (i.e. directory), we see all the children */ if (node->type != TN_FILE || (node->soft_link && tree_node_has_child(node))) { /* * Recursive set children within directory */ foreach_child(n, node) { count += set_extract(ua, n, tree, extract); } /* * Walk up tree marking any unextracted parent to be extracted. */ if (extract) { while (node->parent && !node->parent->extract_dir) { node = node->parent; node->extract_dir = true; } } } else { if (extract) { uint64_t key = 0; bool is_hardlinked = false; /* * See if we are optimizing for speed or size. */ if (!me->optimize_for_size && me->optimize_for_speed) { if (node->hard_link) { /* * Every hardlink is in hashtable, and it points to linked file. */ key = (((uint64_t) node->JobId) << 32) + node->FileIndex; is_hardlinked = true; } } else { FILE_DBR fdbr; POOLMEM *cwd; /* * Ordinary file, we get the full path, look up the attributes, decode them, * and if we are hard linked to a file that was saved, we must load that file too. */ cwd = tree_getpath(node); if (cwd) { fdbr.FileId = 0; fdbr.JobId = node->JobId; if (node->hard_link && db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) { int32_t LinkFI; struct stat statp; decode_stat(fdbr.LStat, &statp, sizeof(statp), &LinkFI); /* decode stat pkt */ key = (((uint64_t) node->JobId) << 32) + LinkFI; /* lookup by linked file's fileindex */ is_hardlinked = true; } free_pool_memory(cwd); } } if (is_hardlinked) { /* * If we point to a hard linked file, find that file in hardlinks hashmap, * and mark it to be restored as well. */ HL_ENTRY *entry = (HL_ENTRY *) tree->root->hardlinks.lookup(key); if (entry && entry->node) { n = entry->node; n->extract = true; n->extract_dir = (n->type == TN_DIR || n->type == TN_DIR_NLS); } } } } return count; } static void strip_trailing_slash(char *arg) { int len = strlen(arg); if (len == 0) { return; } len--; if (arg[len] == '/') { /* strip any trailing slash */ arg[len] = 0; } } /* * Recursively mark the current directory to be restored as * well as all directories and files below it. */ static int markcmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; int count = 0; char ec1[50]; POOLMEM *cwd; bool restore_cwd = false; if (ua->argc < 2 || !tree_node_has_child(tree->node)) { ua->send_msg(_("No files marked.\n")); return 1; } /* * Save the current CWD. */ cwd = tree_getpath(tree->node); for (int i = 1; i < ua->argc; i++) { strip_trailing_slash(ua->argk[i]); /* * See if this is a full path. */ if (strchr(ua->argk[i], '/')) { int pnl, fnl; POOLMEM *file = get_pool_memory(PM_FNAME); POOLMEM *path = get_pool_memory(PM_FNAME); /* * Split the argument into a path and file part. */ split_path_and_filename(ua->argk[i], &path, &pnl, &file, &fnl); /* * First change the CWD to the correct PATH. */ node = tree_cwd(path, tree->root, tree->node); if (!node) { ua->warning_msg(_("Invalid path %s given.\n"), path); free_pool_memory(file); free_pool_memory(path); continue; } tree->node = node; restore_cwd = true; foreach_child(node, tree->node) { if (fnmatch(file, node->fname, 0) == 0) { count += set_extract(ua, node, tree, true); } } free_pool_memory(file); free_pool_memory(path); } else { /* * Only a pattern without a / so do things relative to CWD. */ foreach_child(node, tree->node) { if (fnmatch(ua->argk[i], node->fname, 0) == 0) { count += set_extract(ua, node, tree, true); } } } } if (count == 0) { ua->send_msg(_("No files marked.\n")); } else if (count == 1) { ua->send_msg(_("1 file marked.\n")); } else { ua->send_msg(_("%s files marked.\n"), edit_uint64_with_commas(count, ec1)); } /* * Restore the CWD when we changed it. */ if (restore_cwd && cwd) { node = tree_cwd(cwd, tree->root, tree->node); if (!node) { ua->warning_msg(_("Invalid path %s given.\n"), cwd); } else { tree->node = node; } } if (cwd) { free_pool_memory(cwd); } return 1; } static int markdircmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; int count = 0; char ec1[50]; if (ua->argc < 2 || !tree_node_has_child(tree->node)) { ua->send_msg(_("No files marked.\n")); return 1; } for (int i = 1; i < ua->argc; i++) { strip_trailing_slash(ua->argk[i]); foreach_child(node, tree->node) { if (fnmatch(ua->argk[i], node->fname, 0) == 0) { if (node->type == TN_DIR || node->type == TN_DIR_NLS) { node->extract_dir = true; count++; } } } } if (count == 0) { ua->send_msg(_("No directories marked.\n")); } else if (count == 1) { ua->send_msg(_("1 directory marked.\n")); } else { ua->send_msg(_("%s directories marked.\n"), edit_uint64_with_commas(count, ec1)); } return 1; } static int countcmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; int total, num_extract; char ec1[50], ec2[50]; total = num_extract = 0; for (node = first_tree_node(tree->root); node; node = next_tree_node(node)) { if (node->type != TN_NEWDIR) { total++; if (node->extract || node->extract_dir) { num_extract++; } } } ua->send_msg(_("%s total files/dirs. %s marked to be restored.\n"), edit_uint64_with_commas(total, ec1), edit_uint64_with_commas(num_extract, ec2)); return 1; } static int findcmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; POOLMEM *cwd; if (ua->argc == 1) { ua->send_msg(_("No file specification given.\n")); return 1; /* make it non-fatal */ } for (int i = 1; i < ua->argc; i++) { for (node = first_tree_node(tree->root); node; node = next_tree_node(node)) { if (fnmatch(ua->argk[i], node->fname, 0) == 0) { const char *tag; cwd = tree_getpath(node); if (node->extract) { tag = "*"; } else if (node->extract_dir) { tag = "+"; } else { tag = ""; } ua->send_msg("%s%s\n", tag, cwd); free_pool_memory(cwd); } } } return 1; } static int dot_lsdircmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; if (!tree_node_has_child(tree->node)) { return 1; } foreach_child(node, tree->node) { if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) { if (tree_node_has_child(node)) { ua->send_msg("%s/\n", node->fname); } } } return 1; } static int dot_helpcmd(UAContext *ua, TREE_CTX *tree) { for (int i = 0; i < comsize; i++) { /* List only non-dot commands */ if (commands[i].key[0] != '.') { ua->send_msg("%s\n", commands[i].key); } } return 1; } static int dot_lscmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; if (!tree_node_has_child(tree->node)) { return 1; } foreach_child(node, tree->node) { if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) { ua->send_msg("%s%s\n", node->fname, tree_node_has_child(node)?"/":""); } } return 1; } static int lscmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; if (!tree_node_has_child(tree->node)) { return 1; } foreach_child(node, tree->node) { if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) { const char *tag; if (node->extract) { tag = "*"; } else if (node->extract_dir) { tag = "+"; } else { tag = ""; } ua->send_msg("%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":""); } } return 1; } /* * Ls command that lists only the marked files */ static int dot_lsmarkcmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; if (!tree_node_has_child(tree->node)) { return 1; } foreach_child(node, tree->node) { if ((ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) && (node->extract || node->extract_dir)) { ua->send_msg("%s%s\n", node->fname, tree_node_has_child(node)?"/":""); } } return 1; } /* * This recursive ls command that lists only the marked files */ static void rlsmark(UAContext *ua, TREE_NODE *tnode, int level) { TREE_NODE *node; const int max_level = 100; char indent[max_level*2+1]; int i, j; if (!tree_node_has_child(tnode)) { return; } level = MIN(level, max_level); j = 0; for (i = 0; i < level; i++) { indent[j++] = ' '; indent[j++] = ' '; } indent[j] = 0; foreach_child(node, tnode) { if ((ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) && (node->extract || node->extract_dir)) { const char *tag; if (node->extract) { tag = "*"; } else if (node->extract_dir) { tag = "+"; } else { tag = ""; } ua->send_msg("%s%s%s%s\n", indent, tag, node->fname, tree_node_has_child(node)?"/":""); if (tree_node_has_child(node)) { rlsmark(ua, node, level+1); } } } } static int lsmarkcmd(UAContext *ua, TREE_CTX *tree) { rlsmark(ua, tree->node, 0); return 1; } /* * This is actually the long form used for "dir" */ static inline void ls_output(guid_list *guid, POOLMEM **buf, const char *fname, const char *tag, struct stat *statp, bool dot_cmd) { char mode_str[11]; char time_str[22]; char ec1[30]; char en1[30], en2[30]; /* * Insert mode e.g. -r-xr-xr-x */ encode_mode(statp->st_mode, mode_str); if (dot_cmd) { encode_time(statp->st_mtime, time_str); Mmsg(buf, "%s,%d,%s,%s,%s,%s,%c,%s", mode_str, (uint32_t)statp->st_nlink, guid->uid_to_name(statp->st_uid, en1, sizeof(en1)), guid->gid_to_name(statp->st_gid, en2, sizeof(en2)), edit_int64(statp->st_size, ec1), time_str, *tag, fname); } else { time_t time; if (statp->st_ctime > statp->st_mtime) { time = statp->st_ctime; } else { time = statp->st_mtime; } /* * Display most recent time */ encode_time(time, time_str); Mmsg(buf, "%s %2d %-8.8s %-8.8s %12.12s %s %c%s", mode_str, (uint32_t)statp->st_nlink, guid->uid_to_name(statp->st_uid, en1, sizeof(en1)), guid->gid_to_name(statp->st_gid, en2, sizeof(en2)), edit_int64(statp->st_size, ec1), time_str, *tag, fname); } } /* * Like ls command, but give more detail on each file */ static int do_dircmd(UAContext *ua, TREE_CTX *tree, bool dot_cmd) { TREE_NODE *node; POOLMEM *cwd, *buf; FILE_DBR fdbr; struct stat statp; char *pcwd; guid_list *guid; if (!tree_node_has_child(tree->node)) { ua->send_msg(_("Node %s has no children.\n"), tree->node->fname); return 1; } guid = new_guid_list(); buf = get_pool_memory(PM_FNAME); foreach_child(node, tree->node) { const char *tag; if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) { if (node->extract) { tag = "*"; } else if (node->extract_dir) { tag = "+"; } else { tag = " "; } cwd = tree_getpath(node); fdbr.FileId = 0; fdbr.JobId = node->JobId; /* * Strip / from soft links to directories. * * This is because soft links to files have a trailing slash * when returned from tree_getpath, but db_get_file_attr... * treats soft links as files, so they do not have a trailing * slash like directory names. */ if (node->type == TN_FILE && tree_node_has_child(node)) { pm_strcpy(buf, cwd); pcwd = buf; int len = strlen(buf); if (len > 1) { buf[len - 1] = '\0'; /* strip trailing / */ } } else { pcwd = cwd; } if (db_get_file_attributes_record(ua->jcr, ua->db, pcwd, NULL, &fdbr)) { int32_t LinkFI; decode_stat(fdbr.LStat, &statp, sizeof(statp), &LinkFI); /* decode stat pkt */ } else { /* Something went wrong getting attributes -- print name */ memset(&statp, 0, sizeof(statp)); } ls_output(guid, &buf, cwd, tag, &statp, dot_cmd); ua->send_msg("%s\n", buf); free_pool_memory(cwd); } } free_pool_memory(buf); free_guid_list(guid); return 1; } int dot_dircmd(UAContext *ua, TREE_CTX *tree) { return do_dircmd(ua, tree, true/*dot command*/); } static int dircmd(UAContext *ua, TREE_CTX *tree) { return do_dircmd(ua, tree, false/*not dot command*/); } static int estimatecmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; POOLMEM *cwd; int total, num_extract; uint64_t total_bytes = 0; FILE_DBR fdbr; struct stat statp; char ec1[50]; total = num_extract = 0; for (node = first_tree_node(tree->root); node; node = next_tree_node(node)) { if (node->type != TN_NEWDIR) { total++; if (node->extract && node->type == TN_FILE) { /* * If regular file, get size */ num_extract++; cwd = tree_getpath(node); fdbr.FileId = 0; fdbr.JobId = node->JobId; if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) { int32_t LinkFI; decode_stat(fdbr.LStat, &statp, sizeof(statp), &LinkFI); /* decode stat pkt */ if (S_ISREG(statp.st_mode) && statp.st_size > 0) { total_bytes += statp.st_size; } } free_pool_memory(cwd); } else if (node->extract || node->extract_dir) { /* * Directory, count only */ num_extract++; } } } ua->send_msg(_("%d total files; %d marked to be restored; %s bytes.\n"), total, num_extract, edit_uint64_with_commas(total_bytes, ec1)); return 1; } static int helpcmd(UAContext *ua, TREE_CTX *tree) { unsigned int i; ua->send_msg(_(" Command Description\n ======= ===========\n")); for (i = 0; i < comsize; i++) { /* * List only non-dot commands */ if (commands[i].key[0] != '.') { ua->send_msg(" %-10s %s\n", _(commands[i].key), _(commands[i].help)); } } ua->send_msg("\n"); return 1; } /* * Change directories. Note, if the user specifies x: and it fails, * we assume it is a Win32 absolute cd rather than relative and * try a second time with /x: ... Win32 kludge. */ static int cdcmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; POOLMEM *cwd; if (ua->argc != 2) { ua->error_msg(_("Too few or too many arguments. Try using double quotes.\n")); return 1; } node = tree_cwd(ua->argk[1], tree->root, tree->node); if (!node) { /* * Try once more if Win32 drive -- make absolute */ if (ua->argk[1][1] == ':') { /* win32 drive */ cwd = get_pool_memory(PM_FNAME); pm_strcpy(cwd, "/"); pm_strcat(cwd, ua->argk[1]); node = tree_cwd(cwd, tree->root, tree->node); free_pool_memory(cwd); } if (!node) { ua->warning_msg(_("Invalid path given.\n")); } else { tree->node = node; } } else { tree->node = node; } return pwdcmd(ua, tree); } static int pwdcmd(UAContext *ua, TREE_CTX *tree) { POOLMEM *cwd; cwd = tree_getpath(tree->node); if (cwd) { if (ua->api) { ua->send_msg("%s", cwd); } else { ua->send_msg(_("cwd is: %s\n"), cwd); } free_pool_memory(cwd); } return 1; } static int dot_pwdcmd(UAContext *ua, TREE_CTX *tree) { POOLMEM *cwd; cwd = tree_getpath(tree->node); if (cwd) { ua->send_msg("%s", cwd); free_pool_memory(cwd); } return 1; } static int unmarkcmd(UAContext *ua, TREE_CTX *tree) { POOLMEM *cwd; TREE_NODE *node; int count = 0; bool restore_cwd = false; if (ua->argc < 2 || !tree_node_has_child(tree->node)) { ua->send_msg(_("No files unmarked.\n")); return 1; } /* * Save the current CWD. */ cwd = tree_getpath(tree->node); for (int i = 1; i < ua->argc; i++) { strip_trailing_slash(ua->argk[i]); /* * See if this is a full path. */ if (strchr(ua->argk[i], '/')) { int pnl, fnl; POOLMEM *file = get_pool_memory(PM_FNAME); POOLMEM *path = get_pool_memory(PM_FNAME); /* * Split the argument into a path and file part. */ split_path_and_filename(ua->argk[i], &path, &pnl, &file, &fnl); /* * First change the CWD to the correct PATH. */ node = tree_cwd(path, tree->root, tree->node); if (!node) { ua->warning_msg(_("Invalid path %s given.\n"), path); free_pool_memory(file); free_pool_memory(path); continue; } tree->node = node; restore_cwd = true; foreach_child(node, tree->node) { if (fnmatch(file, node->fname, 0) == 0) { count += set_extract(ua, node, tree, false); } } free_pool_memory(file); free_pool_memory(path); } else { /* * Only a pattern without a / so do things relative to CWD. */ foreach_child(node, tree->node) { if (fnmatch(ua->argk[i], node->fname, 0) == 0) { count += set_extract(ua, node, tree, false); } } } } if (count == 0) { ua->send_msg(_("No files unmarked.\n")); } else if (count == 1) { ua->send_msg(_("1 file unmarked.\n")); } else { char ed1[50]; ua->send_msg(_("%s files unmarked.\n"), edit_uint64_with_commas(count, ed1)); } /* * Restore the CWD when we changed it. */ if (restore_cwd && cwd) { node = tree_cwd(cwd, tree->root, tree->node); if (!node) { ua->warning_msg(_("Invalid path %s given.\n"), cwd); } else { tree->node = node; } } if (cwd) { free_pool_memory(cwd); } return 1; } static int unmarkdircmd(UAContext *ua, TREE_CTX *tree) { TREE_NODE *node; int count = 0; if (ua->argc < 2 || !tree_node_has_child(tree->node)) { ua->send_msg(_("No directories unmarked.\n")); return 1; } for (int i = 1; i < ua->argc; i++) { strip_trailing_slash(ua->argk[i]); foreach_child(node, tree->node) { if (fnmatch(ua->argk[i], node->fname, 0) == 0) { if (node->type == TN_DIR || node->type == TN_DIR_NLS) { node->extract_dir = false; count++; } } } } if (count == 0) { ua->send_msg(_("No directories unmarked.\n")); } else if (count == 1) { ua->send_msg(_("1 directory unmarked.\n")); } else { ua->send_msg(_("%d directories unmarked.\n"), count); } return 1; } static int donecmd(UAContext *ua, TREE_CTX *tree) { return 0; } static int quitcmd(UAContext *ua, TREE_CTX *tree) { ua->quit = true; return 0; } bareos-Release-14.2.6/src/dird/ua_update.c000066400000000000000000001175521263011562700202770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- Update command processing * * Split from ua_cmds.c March 2005 * * Kern Sibbald, September MM */ #include "bareos.h" #include "dird.h" /* Forward referenced functions */ static int update_volume(UAContext *ua); static bool update_pool(UAContext *ua); static bool update_job(UAContext *ua); static bool update_stats(UAContext *ua); static void update_slots(UAContext *ua); /* * Update a Pool Record in the database. * It is always updated from the Resource record. * * update pool= * updates pool from Pool resource * update media pool= volume= * changes pool info for volume * update slots[=..] [scan] * updates autochanger slots * update stats [days=...] * updates long term statistics */ int update_cmd(UAContext *ua, const char *cmd) { static const char *kw[] = { NT_("media"), /* 0 */ NT_("volume"), /* 1 */ NT_("pool"), /* 2 */ NT_("slots"), /* 3 */ NT_("slot"), /* 4 */ NT_("jobid"), /* 5 */ NT_("stats"), /* 6 */ NULL }; if (!open_client_db(ua)) { return 1; } switch (find_arg_keyword(ua, kw)) { case 0: case 1: update_volume(ua); return 1; case 2: update_pool(ua); return 1; case 3: case 4: update_slots(ua); return 1; case 5: update_job(ua); return 1; case 6: update_stats(ua); return 1; default: break; } start_prompt(ua, _("Update choice:\n")); add_prompt(ua, _("Volume parameters")); add_prompt(ua, _("Pool from resource")); add_prompt(ua, _("Slots from autochanger")); add_prompt(ua, _("Long term statistics")); switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) { case 0: update_volume(ua); break; case 1: update_pool(ua); break; case 2: update_slots(ua); break; case 3: update_stats(ua); break; default: break; } return 1; } static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr) { POOL_MEM query(PM_MESSAGE); const char *kw[] = { NT_("Append"), NT_("Archive"), NT_("Disabled"), NT_("Full"), NT_("Used"), NT_("Cleaning"), NT_("Recycle"), NT_("Read-Only"), NT_("Error"), NULL }; bool found = false; int i; for (i = 0; kw[i]; i++) { if (bstrcasecmp(val, kw[i])) { found = true; break; } } if (!found) { ua->error_msg(_("Invalid VolStatus specified: %s\n"), val); } else { char ed1[50]; bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus)); Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s", mr->VolStatus, edit_int64(mr->MediaId,ed1)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New Volume status is: %s\n"), mr->VolStatus); } } } static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr) { char ed1[150], ed2[50]; POOL_MEM query(PM_MESSAGE); if (!duration_to_utime(val, &mr->VolRetention)) { ua->error_msg(_("Invalid retention period specified: %s\n"), val); return; } Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s", edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New retention period is: %s\n"), edit_utime(mr->VolRetention, ed1, sizeof(ed1))); } } static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr) { char ed1[150], ed2[50]; POOL_MEM query(PM_MESSAGE); if (!duration_to_utime(val, &mr->VolUseDuration)) { ua->error_msg(_("Invalid use duration specified: %s\n"), val); return; } Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s", edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New use duration is: %s\n"), edit_utime(mr->VolUseDuration, ed1, sizeof(ed1))); } } static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_MEM query(PM_MESSAGE); char ed1[50]; Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s", val, edit_int64(mr->MediaId,ed1)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New max jobs is: %s\n"), val); } } static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_MEM query(PM_MESSAGE); char ed1[50]; Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s", val, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New max files is: %s\n"), val); } } static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr) { uint64_t maxbytes; char ed1[50], ed2[50]; POOL_MEM query(PM_MESSAGE); if (!size_to_uint64(val, &maxbytes)) { ua->error_msg(_("Invalid max. bytes specification: %s\n"), val); return; } Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s", edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1)); } } static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr) { int recycle; char ed1[50]; POOL_MEM query(PM_MESSAGE); if (!is_yesno(val, &recycle)) { ua->error_msg(_("Invalid value. It must be yes or no.\n")); return; } Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s", recycle, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New Recycle flag is: %s\n"), recycle==1?_("yes"):_("no")); } } static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr) { int InChanger; char ed1[50]; POOL_MEM query(PM_MESSAGE); if (!is_yesno(val, &InChanger)) { ua->error_msg(_("Invalid value. It must be yes or no.\n")); return; } Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s", InChanger, edit_int64(mr->MediaId, ed1)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New InChanger flag is: %s\n"), InChanger==1?_("yes"):_("no")); } } static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); pr.PoolId = mr->PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); return; } mr->Slot = atoi(val); if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) { ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"), pr.MaxVols); return; } /* * Make sure to use db_update... rather than doing this directly, * so that any Slot is handled correctly. */ set_storageid_in_mr(NULL, mr); if (!db_update_media_record(ua->jcr, ua->db, mr)) { ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("New Slot is: %d\n"), mr->Slot); } } /* Modify the Pool in which this Volume is located */ void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr) { POOL_DBR pr; POOL_MEM query(PM_MESSAGE); char ed1[50], ed2[50]; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return; } mr->PoolId = pr.PoolId; /* set new PoolId */ /* */ db_lock(ua->db); Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s", edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New Pool is: %s\n"), pr.Name); opr->NumVols--; if (!db_update_pool_record(ua->jcr, ua->db, opr)) { ua->error_msg("%s", db_strerror(ua->db)); } pr.NumVols++; if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); } } db_unlock(ua->db); } /* Modify the RecyclePool of a Volume */ void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_DBR pr; POOL_MEM query(PM_MESSAGE); char ed1[50], ed2[50]; const char *poolname; if (val && *val) { /* update volume recyclepool="Scratch" */ /* If a pool name is given, look up the PoolId */ memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) { return; } /* pool = select_pool_resource(ua); */ mr->RecyclePoolId = pr.PoolId; /* get the PoolId */ poolname = pr.Name; } else { /* update volume recyclepool="" */ /* If no pool name is given, set the PoolId to 0 (the default) */ mr->RecyclePoolId = 0; poolname = _("*None*"); } db_lock(ua->db); Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s", edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2)); if (!db_sql_query(ua->db, query.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New RecyclePool is: %s\n"), poolname); } db_unlock(ua->db); } /* * Refresh the Volume information from the Pool record */ static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr) { POOL_DBR pr; memset(&pr, 0, sizeof(pr)); pr.PoolId = mr->PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr) || !acl_access_ok(ua, Pool_ACL, pr.Name, true)) { return; } set_pool_dbr_defaults_in_media_dbr(mr, &pr); if (!db_update_media_defaults(ua->jcr, ua->db, mr)) { ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"), pr.Name); } } /* * Refresh the Volume information from the Pool record for all Volumes */ static void update_all_vols_from_pool(UAContext *ua, const char *pool_name) { POOL_DBR pr; MEDIA_DBR mr; memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); bstrncpy(pr.Name, pool_name, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return; } set_pool_dbr_defaults_in_media_dbr(&mr, &pr); mr.PoolId = pr.PoolId; if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) { ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"), pr.Name); } } static void update_all_vols(UAContext *ua) { int i, num_pools; uint32_t *ids; POOL_DBR pr; MEDIA_DBR mr; memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) { ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db)); return; } for (i = 0; ijcr, ua->db, &pr)) { ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db)); continue; } /* * Check access to pool. */ if (!acl_access_ok(ua, Pool_ACL, pr.Name, false)) { continue; } set_pool_dbr_defaults_in_media_dbr(&mr, &pr); mr.PoolId = pr.PoolId; if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) { ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"), pr.Name); } } free(ids); } static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr) { mr->Enabled = get_enabled(ua, val); if (mr->Enabled < 0) { return; } set_storageid_in_mr(NULL, mr); if (!db_update_media_record(ua->jcr, ua->db, mr)) { ua->error_msg(_("Error updating media record Enabled: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled); } } static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_MEM ret; if (bstrcasecmp(val, "truncate")) { mr->ActionOnPurge = ON_PURGE_TRUNCATE; } else { mr->ActionOnPurge = 0; } set_storageid_in_mr(NULL, mr); if (!db_update_media_record(ua->jcr, ua->db, mr)) { ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("New ActionOnPurge is: %s\n"), action_on_purge_to_string(mr->ActionOnPurge, ret)); } } /* * Update a media record -- allows you to change the * Volume status. E.g. if you want BAREOS to stop * writing on the volume, set it to anything other * than Append. */ static int update_volume(UAContext *ua) { POOLRES *pool; POOLMEM *query; POOL_MEM ret; char buf[1000]; char ed1[130]; bool done = false; int i; const char *kw[] = { NT_("VolStatus"), /* 0 */ NT_("VolRetention"), /* 1 */ NT_("VolUse"), /* 2 */ NT_("MaxVolJobs"), /* 3 */ NT_("MaxVolFiles"), /* 4 */ NT_("MaxVolBytes"), /* 5 */ NT_("Recycle"), /* 6 */ NT_("InChanger"), /* 7 */ NT_("Slot"), /* 8 */ NT_("Pool"), /* 9 */ NT_("FromPool"), /* 10 */ NT_("AllFromPool"), /* 11 !!! see below !!! */ NT_("Enabled"), /* 12 */ NT_("RecyclePool"), /* 13 */ NT_("ActionOnPurge"), /* 14 */ NULL }; #define AllFromPool 11 /* keep this updated with above */ for (i = 0; kw[i]; i++) { int j; POOL_DBR pr; MEDIA_DBR mr; memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); if ((j = find_arg_with_value(ua, kw[i])) > 0) { /* If all from pool don't select a media record */ if (i != AllFromPool && !select_media_dbr(ua, &mr)) { return 0; } switch (i) { case 0: update_volstatus(ua, ua->argv[j], &mr); break; case 1: update_volretention(ua, ua->argv[j], &mr); break; case 2: update_voluseduration(ua, ua->argv[j], &mr); break; case 3: update_volmaxjobs(ua, ua->argv[j], &mr); break; case 4: update_volmaxfiles(ua, ua->argv[j], &mr); break; case 5: update_volmaxbytes(ua, ua->argv[j], &mr); break; case 6: update_volrecycle(ua, ua->argv[j], &mr); break; case 7: update_volinchanger(ua, ua->argv[j], &mr); break; case 8: update_volslot(ua, ua->argv[j], &mr); break; case 9: pr.PoolId = mr.PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); break; } update_vol_pool(ua, ua->argv[j], &mr, &pr); break; case 10: update_vol_from_pool(ua, &mr); return 1; case 11: update_all_vols_from_pool(ua, ua->argv[j]); return 1; case 12: update_volenabled(ua, ua->argv[j], &mr); break; case 13: update_vol_recyclepool(ua, ua->argv[j], &mr); break; case 14: update_vol_actiononpurge(ua, ua->argv[j], &mr); break; } done = true; } } /* Allow user to simply update all volumes */ if (find_arg(ua, NT_("fromallpools")) > 0) { update_all_vols(ua); return 1; } for ( ; !done; ) { POOL_DBR pr; MEDIA_DBR mr; memset(&pr, 0, sizeof(pr)); memset(&mr, 0, sizeof(mr)); start_prompt(ua, _("Parameters to modify:\n")); add_prompt(ua, _("Volume Status")); /* 0 */ add_prompt(ua, _("Volume Retention Period")); /* 1 */ add_prompt(ua, _("Volume Use Duration")); /* 2 */ add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */ add_prompt(ua, _("Maximum Volume Files")); /* 4 */ add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */ add_prompt(ua, _("Recycle Flag")); /* 6 */ add_prompt(ua, _("Slot")); /* 7 */ add_prompt(ua, _("InChanger Flag")); /* 8 */ add_prompt(ua, _("Volume Files")); /* 9 */ add_prompt(ua, _("Pool")); /* 10 */ add_prompt(ua, _("Volume from Pool")); /* 11 */ add_prompt(ua, _("All Volumes from Pool")); /* 12 */ add_prompt(ua, _("All Volumes from all Pools")); /* 13 */ add_prompt(ua, _("Enabled")), /* 14 */ add_prompt(ua, _("RecyclePool")), /* 15 */ add_prompt(ua, _("Action On Purge")), /* 16 */ add_prompt(ua, _("Done")); /* 17 */ i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0); /* For All Volumes, All Volumes from Pool, and Done, we don't need * a Volume record */ if ( i != 12 && i != 13 && i != 17) { if (!select_media_dbr(ua, &mr)) { /* Get Volume record */ return 0; } ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName); } switch (i) { case 0: /* Volume Status */ /* Modify Volume Status */ ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus); start_prompt(ua, _("Possible Values are:\n")); add_prompt(ua, NT_("Append")); add_prompt(ua, NT_("Archive")); add_prompt(ua, NT_("Disabled")); add_prompt(ua, NT_("Full")); add_prompt(ua, NT_("Used")); add_prompt(ua, NT_("Cleaning")); if (bstrcmp(mr.VolStatus, NT_("Purged"))) { add_prompt(ua, NT_("Recycle")); } add_prompt(ua, NT_("Read-Only")); if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) { return 1; } update_volstatus(ua, ua->cmd, &mr); break; case 1: /* Retention */ ua->info_msg(_("Current retention period is: %s\n"), edit_utime(mr.VolRetention, ed1, sizeof(ed1))); if (!get_cmd(ua, _("Enter Volume Retention period: "))) { return 0; } update_volretention(ua, ua->cmd, &mr); break; case 2: /* Use Duration */ ua->info_msg(_("Current use duration is: %s\n"), edit_utime(mr.VolUseDuration, ed1, sizeof(ed1))); if (!get_cmd(ua, _("Enter Volume Use Duration: "))) { return 0; } update_voluseduration(ua, ua->cmd, &mr); break; case 3: /* Max Jobs */ ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs); if (!get_pint(ua, _("Enter new Maximum Jobs: "))) { return 0; } update_volmaxjobs(ua, ua->cmd, &mr); break; case 4: /* Max Files */ ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles); if (!get_pint(ua, _("Enter new Maximum Files: "))) { return 0; } update_volmaxfiles(ua, ua->cmd, &mr); break; case 5: /* Max Bytes */ ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1)); if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) { return 0; } update_volmaxbytes(ua, ua->cmd, &mr); break; case 6: /* Recycle */ ua->info_msg(_("Current recycle flag is: %s\n"), mr.Recycle==1?_("yes"):_("no")); if (!get_yesno(ua, _("Enter new Recycle status: "))) { return 0; } update_volrecycle(ua, ua->cmd, &mr); break; case 7: /* Slot */ ua->info_msg(_("Current Slot is: %d\n"), mr.Slot); if (!get_pint(ua, _("Enter new Slot: "))) { return 0; } update_volslot(ua, ua->cmd, &mr); break; case 8: /* InChanger */ ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger); bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "), mr.VolumeName); if (!get_yesno(ua, buf)) { return 0; } mr.InChanger = ua->pint32_val; /* * Make sure to use db_update... rather than doing this directly, * so that any Slot is handled correctly. */ set_storageid_in_mr(NULL, &mr); if (!db_update_media_record(ua->jcr, ua->db, &mr)) { ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); } else { ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger); } break; case 9: /* Volume Files */ int32_t VolFiles; ua->warning_msg(_("Warning changing Volume Files can result\n" "in loss of data on your Volume\n\n")); ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles); if (!get_pint(ua, _("Enter new number of Files for Volume: "))) { return 0; } VolFiles = ua->pint32_val; if (VolFiles != (int)(mr.VolFiles + 1)) { ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n")); if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) { break; } } query = get_pool_memory(PM_MESSAGE); Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s", VolFiles, edit_int64(mr.MediaId, ed1)); if (!db_sql_query(ua->db, query)) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New Volume Files is: %u\n"), VolFiles); } free_pool_memory(query); break; case 10: /* Volume's Pool */ pr.PoolId = mr.PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); return 0; } ua->info_msg(_("Current Pool is: %s\n"), pr.Name); if (!get_cmd(ua, _("Enter new Pool name: "))) { return 0; } update_vol_pool(ua, ua->cmd, &mr, &pr); return 1; case 11: update_vol_from_pool(ua, &mr); return 1; case 12: pool = select_pool_resource(ua); if (pool) { update_all_vols_from_pool(ua, pool->name()); } return 1; case 13: update_all_vols(ua); return 1; case 14: ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled); if (!get_cmd(ua, _("Enter new Enabled: "))) { return 0; } update_volenabled(ua, ua->cmd, &mr); break; case 15: pr.PoolId = mr.RecyclePoolId; if (db_get_pool_record(ua->jcr, ua->db, &pr)) { ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name); } else { ua->info_msg(_("No current RecyclePool\n")); } if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) { return 0; } update_vol_recyclepool(ua, pr.Name, &mr); return 1; case 16: pm_strcpy(ret, ""); ua->info_msg(_("Current ActionOnPurge is: %s\n"), action_on_purge_to_string(mr.ActionOnPurge, ret)); if (!get_cmd(ua, _("Enter new ActionOnPurge (one of: Truncate, None): "))) { return 0; } update_vol_actiononpurge(ua, ua->cmd, &mr); break; default: /* Done or error */ ua->info_msg(_("Selection terminated.\n")); return 1; } } return 1; } /* * Update long term statistics */ static bool update_stats(UAContext *ua) { int i = find_arg_with_value(ua, NT_("days")); utime_t since = 0; if (i >= 0) { since = ((int64_t)atoi(ua->argv[i]) * 24 * 60 * 60); } int nb = db_update_stats(ua->jcr, ua->db, since); ua->info_msg(_("Updating %i job(s).\n"), nb); return true; } /* * Update pool record -- pull info from current POOL resource */ static bool update_pool(UAContext *ua) { POOL_DBR pr; int id; POOLRES *pool; POOLMEM *query; char ed1[50]; pool = get_pool_resource(ua); if (!pool) { return false; } memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool->name(), sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return false; } set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */ set_pooldbr_references(ua->jcr, ua->db, &pr, pool); id = db_update_pool_record(ua->jcr, ua->db, &pr); if (id <= 0) { ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"), id, db_strerror(ua->db)); } query = get_pool_memory(PM_MESSAGE); Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1)); db_list_sql_query(ua->jcr, ua->db, query, printit, ua, true, HORZ_LIST); free_pool_memory(query); ua->info_msg(_("Pool DB record updated from resource.\n")); return true; } /* * Update a Job record -- allows you to change the * date fields in a Job record. This helps when * providing migration from other vendors. */ static bool update_job(UAContext *ua) { int i; char ed1[50], ed2[50]; POOL_MEM cmd(PM_MESSAGE); JOB_DBR jr; CLIENT_DBR cr; utime_t StartTime; char *client_name = NULL; char *start_time = NULL; const char *kw[] = { NT_("starttime"), /* 0 */ NT_("client"), /* 1 */ NULL }; Dmsg1(200, "cmd=%s\n", ua->cmd); i = find_arg_with_value(ua, NT_("jobid")); if (i < 0) { ua->error_msg(_("Expect JobId keyword, not found.\n")); return false; } memset(&jr, 0, sizeof(jr)); memset(&cr, 0, sizeof(cr)); jr.JobId = str_to_int64(ua->argv[i]); if (!db_get_job_record(ua->jcr, ua->db, &jr)) { ua->error_msg("%s", db_strerror(ua->db)); return false; } for (i = 0; kw[i]; i++) { int j; if ((j=find_arg_with_value(ua, kw[i])) >= 0) { switch (i) { case 0: /* start time */ start_time = ua->argv[j]; break; case 1: /* Client name */ client_name = ua->argv[j]; break; } } } if (!client_name && !start_time) { ua->error_msg(_("Neither Client nor StartTime specified.\n")); return 0; } if (client_name) { if (!get_client_dbr(ua, &cr)) { return false; } jr.ClientId = cr.ClientId; } if (start_time) { utime_t delta_start; StartTime = str_to_utime(start_time); if (StartTime == 0) { ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]); return false; } delta_start = StartTime - jr.StartTime; Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime, (utime_t)jr.StartTime, delta_start); jr.StartTime = (time_t)StartTime; jr.SchedTime += (time_t)delta_start; jr.EndTime += (time_t)delta_start; jr.JobTDate += delta_start; /* Convert to DB times */ bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime); bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime); bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime); } Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s'," "EndTime='%s',JobTDate=%s WHERE JobId=%s", edit_int64(jr.ClientId, ed1), jr.cStartTime, jr.cSchedTime, jr.cEndTime, edit_uint64(jr.JobTDate, ed1), edit_int64(jr.JobId, ed2)); if (!db_sql_query(ua->db, cmd.c_str())) { ua->error_msg("%s", db_strerror(ua->db)); return false; } return true; } /* * Update Slots corresponding to Volumes in autochanger */ static void update_slots(UAContext *ua) { USTORERES store; vol_list_t *vl; dlist *vol_list = NULL; MEDIA_DBR mr; char *slot_list; bool scan; int max_slots; int drive = -1; int Enabled = VOL_ENABLED; bool have_enabled; int i; if (!open_client_db(ua)) { return; } store.store = get_storage_resource(ua, true, true); if (!store.store) { return; } pm_strcpy(store.store_source, _("command line")); set_wstorage(ua->jcr, &store); scan = find_arg(ua, NT_("scan")) >= 0; if (scan) { drive = get_storage_drive(ua, store.store); } if ((i=find_arg_with_value(ua, NT_("Enabled"))) >= 0) { Enabled = get_enabled(ua, ua->argv[i]); if (Enabled < 0) { return; } have_enabled = true; } else { have_enabled = false; } max_slots = get_num_slots_from_SD(ua); Dmsg1(100, "max_slots=%d\n", max_slots); if (max_slots <= 0) { ua->warning_msg(_("No slots in changer to scan.\n")); return; } slot_list = (char *)malloc(nbytes_for_bits(max_slots)); clear_all_bits(max_slots, slot_list); if (!get_user_slot_list(ua, slot_list, "slots", max_slots)) { free(slot_list); return; } vol_list = get_vol_list_from_SD(ua, store.store, false, scan); if (!vol_list) { ua->warning_msg(_("No Volumes found to update, or no barcodes.\n")); goto bail_out; } /* * First zap out any InChanger with StorageId=0 */ db_sql_query(ua->db, "UPDATE Media SET InChanger=0 WHERE StorageId=0"); /* * Walk through the list updating the media records */ memset(&mr, 0, sizeof(mr)); foreach_dlist(vl, vol_list) { if (vl->Slot > max_slots) { ua->warning_msg(_("Slot %d greater than max %d ignored.\n"), vl->Slot, max_slots); continue; } /* * Check if user wants us to look at this slot */ if (!bit_is_set(vl->Slot - 1, slot_list)) { Dmsg1(100, "Skipping slot=%d\n", vl->Slot); continue; } /* * If scanning, we read the label rather than the barcode */ if (scan) { if (vl->VolName) { free(vl->VolName); vl->VolName = NULL; } vl->VolName = get_volume_name_from_SD(ua, vl->Slot, drive); Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot); } clear_bit(vl->Slot - 1, slot_list); /* clear Slot */ set_storageid_in_mr(store.store, &mr); mr.Slot = vl->Slot; mr.InChanger = 1; mr.MediaId = 0; /* Get by VolumeName */ if (vl->VolName) { bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); } else { mr.VolumeName[0] = 0; } set_storageid_in_mr(store.store, &mr); Dmsg4(100, "Before make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); db_lock(ua->db); /* * Set InChanger to zero for this Slot */ db_make_inchanger_unique(ua->jcr, ua->db, &mr); db_unlock(ua->db); Dmsg4(100, "After make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); if (!vl->VolName) { Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot); ua->info_msg(_("No VolName for Slot=%d InChanger set to zero.\n"), vl->Slot); continue; } db_lock(ua->db); Dmsg4(100, "Before get MR: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); if (db_get_media_record(ua->jcr, ua->db, &mr)) { Dmsg4(100, "After get MR: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); /* * If Slot, Inchanger, and StorageId have changed, update the Media record */ if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store.store->StorageId) { mr.Slot = vl->Slot; mr.InChanger = 1; if (have_enabled) { mr.Enabled = Enabled; } set_storageid_in_mr(store.store, &mr); if (!db_update_media_record(ua->jcr, ua->db, &mr)) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("Catalog record for Volume \"%s\" updated to reference slot %d.\n"), mr.VolumeName, mr.Slot); } } else { ua->info_msg(_("Catalog record for Volume \"%s\" is up to date.\n"), mr.VolumeName); } } else { ua->warning_msg(_("Volume \"%s\" not found in catalog. Slot=%d InChanger set to zero.\n"), mr.VolumeName, vl->Slot); } db_unlock(ua->db); } memset(&mr, 0, sizeof(mr)); mr.InChanger = 1; set_storageid_in_mr(store.store, &mr); /* * Any slot not visited gets it Inchanger flag reset. */ db_lock(ua->db); for (i = 1; i <= max_slots; i++) { if (bit_is_set(i - 1, slot_list)) { /* * Set InChanger to zero for this Slot */ mr.Slot = i; db_make_inchanger_unique(ua->jcr, ua->db, &mr); } } db_unlock(ua->db); bail_out: if (vol_list) { free_vol_list(vol_list); } free(slot_list); close_sd_bsock(ua); return; } /* * Update Slots corresponding to Volumes in autochanger. * We only update any new volume location of slots marked in * the given slot_list. If you want to do funky stuff * run an "update slots" with the options you want. This * is a simple function which syncs the info from the * vol_list to the database for each slot marked in * the slot_list. * * The vol_list passed here needs to be from an "autochanger listall" cmd. */ void update_slots_from_vol_list(UAContext *ua, STORERES *store, dlist *vol_list, char *slot_list) { vol_list_t *vl; MEDIA_DBR mr; if (!open_client_db(ua)) { return; } /* * Walk through the list updating the media records */ foreach_dlist(vl, vol_list) { /* * We are only interested in normal slots. */ switch (vl->Type) { case slot_type_normal: break; default: continue; } /* * Only update entries of slots marked in the slot_list. */ if (!bit_is_set(vl->Slot - 1, slot_list)) { continue; } /* * Set InChanger to zero for this Slot */ memset(&mr, 0, sizeof(mr)); mr.Slot = vl->Slot; mr.InChanger = 1; mr.MediaId = 0; /* Get by VolumeName */ if (vl->VolName) { bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); } else { mr.VolumeName[0] = 0; } set_storageid_in_mr(store, &mr); Dmsg4(100, "Before make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); db_lock(ua->db); /* * Set InChanger to zero for this Slot */ db_make_inchanger_unique(ua->jcr, ua->db, &mr); db_unlock(ua->db); Dmsg4(100, "After make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); /* * See if there is anything in the slot. */ switch (vl->Content) { case slot_content_full: if (!vl->VolName) { Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot); continue; } break; default: continue; } /* * There is something in the slot and it has a VolumeName so we can check * the database and perform an update if needed. */ db_lock(ua->db); Dmsg4(100, "Before get MR: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); if (db_get_media_record(ua->jcr, ua->db, &mr)) { Dmsg4(100, "After get MR: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); /* If Slot, Inchanger, and StorageId have changed, update the Media record */ if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store->StorageId) { mr.Slot = vl->Slot; mr.InChanger = 1; set_storageid_in_mr(store, &mr); if (!db_update_media_record(ua->jcr, ua->db, &mr)) { ua->error_msg("%s", db_strerror(ua->db)); } } } else { ua->warning_msg(_("Volume \"%s\" not found in catalog. Slot=%d InChanger set to zero.\n"), mr.VolumeName, vl->Slot); } db_unlock(ua->db); } return; } /* * Set the inchanger flag to zero for each slot marked in * the given slot_list. * * The vol_list passed here needs to be from an "autochanger listall" cmd. */ void update_inchanger_for_export(UAContext *ua, STORERES *store, dlist *vol_list, char *slot_list) { vol_list_t *vl; MEDIA_DBR mr; if (!open_client_db(ua)) { return; } /* * Walk through the list updating the media records */ foreach_dlist(vl, vol_list) { /* * We are only interested in normal slots. */ switch (vl->Type) { case slot_type_normal: break; default: continue; } /* * Only update entries of slots marked in the slot_list. */ if (!bit_is_set(vl->Slot - 1, slot_list)) { continue; } /* * Set InChanger to zero for this Slot */ memset(&mr, 0, sizeof(mr)); mr.Slot = vl->Slot; mr.InChanger = 1; mr.MediaId = 0; /* Get by VolumeName */ if (vl->VolName) { bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); } else { mr.VolumeName[0] = 0; } set_storageid_in_mr(store, &mr); Dmsg4(100, "Before make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); db_lock(ua->db); /* * Set InChanger to zero for this Slot */ db_make_inchanger_unique(ua->jcr, ua->db, &mr); db_unlock(ua->db); Dmsg4(100, "After make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); } return; } bareos-Release-14.2.6/src/dird/vbackup.c000066400000000000000000000324671263011562700177640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2008-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- vbackup.c -- responsible for doing virtual * backup jobs or in other words, consolidation or synthetic * backups. * * Kern Sibbald, July MMVIII * * Basic tasks done here: * Open DB and create records for this job. * Figure out what Jobs to copy. * Open Message Channel with Storage daemon to tell him a job will be starting. * Open connection with File daemon and pass him commands to do the backup. * When the File daemon finishes the job, update the DB. */ #include "bareos.h" #include "dird.h" static const int dbglevel = 10; static bool create_bootstrap_file(JCR *jcr, char *jobids); /* * Called here before the job is run to do the job * specific setup. */ bool do_native_vbackup_init(JCR *jcr) { const char *storage_source; if (!get_or_create_fileset_record(jcr)) { Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId); return false; } apply_pool_overrides(jcr); if (!allow_duplicate_job(jcr)) { return false; } jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->res.pool->name()); if (jcr->jr.PoolId == 0) { Dmsg1(dbglevel, "JobId=%d no PoolId\n", (int)jcr->JobId); Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n")); return false; } /* * Note, at this point, pool is the pool for this job. We * transfer it to rpool (read pool), and a bit later, * pool will be changed to point to the write pool, * which comes from pool->NextPool. */ jcr->res.rpool = jcr->res.pool; /* save read pool */ pm_strcpy(jcr->res.rpool_source, jcr->res.pool_source); /* If pool storage specified, use it for restore */ copy_rstorage(jcr, jcr->res.pool->storage, _("Pool resource")); Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->res.rpool->name(), jcr->res.rpool_source); jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } /* * See if there is a next pool override. */ if (jcr->res.run_next_pool_override) { pm_strcpy(jcr->res.npool_source, _("Run NextPool override")); pm_strcpy(jcr->res.pool_source, _("Run NextPool override")); storage_source = _("Storage from Run NextPool override"); } else { /* * See if there is a next pool override in the Job definition. */ if (jcr->res.job->next_pool) { jcr->res.next_pool = jcr->res.job->next_pool; pm_strcpy(jcr->res.npool_source, _("Job's NextPool resource")); pm_strcpy(jcr->res.pool_source, _("Job's NextPool resource")); storage_source = _("Storage from Job's NextPool resource"); } else { /* * Fall back to the pool's NextPool definition. */ jcr->res.next_pool = jcr->res.pool->NextPool; pm_strcpy(jcr->res.npool_source, _("Job Pool's NextPool resource")); pm_strcpy(jcr->res.pool_source, _("Job Pool's NextPool resource")); storage_source = _("Storage from Pool's NextPool resource"); } } /* * If the original backup pool has a NextPool, make sure a * record exists in the database. Note, in this case, we * will be migrating from pool to pool->NextPool. */ if (jcr->res.next_pool) { jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->res.next_pool->name()); if (jcr->jr.PoolId == 0) { return false; } } if (!set_migration_wstorage(jcr, jcr->res.pool, jcr->res.next_pool, storage_source)) { return false; } jcr->res.pool = jcr->res.next_pool; Dmsg2(dbglevel, "Write pool=%s read rpool=%s\n", jcr->res.pool->name(), jcr->res.rpool->name()); // create_clones(jcr); return true; } /* * Do a virtual backup, which consolidates all previous backups into * a sort of synthetic Full. * * Returns: false on failure * true on success */ bool do_native_vbackup(JCR *jcr) { char ed1[100]; BSOCK *sd; char *p; db_list_ctx jobids; Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage); Dmsg2(100, "Read store=%s, write store=%s\n", ((STORERES *)jcr->rstorage->first())->name(), ((STORERES *)jcr->wstorage->first())->name()); /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Virtual Backup JobId %s, Job=%s\n"), edit_uint64(jcr->JobId, ed1), jcr->Job); if (!jcr->accurate) { Jmsg(jcr, M_WARNING, 0, _("This Job is not an Accurate backup so is not equivalent to a Full backup.\n")); } db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids); Dmsg1(10, "Accurate jobids=%s\n", jobids.list); if (jobids.count == 0) { Jmsg(jcr, M_FATAL, 0, _("No previous Jobs found.\n")); return false; } /* * Now we find the last job that ran and store it's info in * the previous_jr record. We will set our times to the * values from that job so that anything changed after that * time will be picked up on the next backup. */ p = strrchr(jobids.list, ','); /* find last jobid */ if (p != NULL) { p++; } else { p = jobids.list; } memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr)); jcr->previous_jr.JobId = str_to_int64(p); Dmsg1(10, "Previous JobId=%s\n", p); if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) { Jmsg(jcr, M_FATAL, 0, _("Error getting Job record for previous Job: ERR=%s"), db_strerror(jcr->db)); return false; } if (!create_bootstrap_file(jcr, jobids.list)) { Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n")); return false; } /* * Open a message channel connection with the Storage * daemon. This is to let him know that our client * will be contacting him for a backup session. * */ Dmsg0(110, "Open connection with storage daemon\n"); jcr->setJobStatus(JS_WaitSD); /* * Start conversation with Storage daemon */ if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { return false; } sd = jcr->store_bsock; /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /* send_bsr */ true)) { return false; } Dmsg0(100, "Storage daemon connection OK\n"); /* * We re-update the job start record so that the start * time is set after the run before job. This avoids * that any files created by the run before job will * be saved twice. They will be backed up in the current * job, but not in the next one unless they are changed. * Without this, they will be backed up in this job and * in the next job run because in that case, their date * is after the start of this run. */ jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; jcr->jr.JobTDate = jcr->start_time; jcr->setJobStatus(JS_Running); /* * Update job start record */ if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); return false; } /* * Declare the job started to start the MaxRunTime check */ jcr->setJobStarted(); /* * Start the job prior to starting the message thread below * to avoid two threads from using the BSOCK structure at * the same time. */ if (!sd->fsend("run")) { return false; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { return false; } jcr->setJobStatus(JS_Running); /* * Pickup Job termination data * Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */ wait_for_storage_daemon_termination(jcr); jcr->setJobStatus(jcr->SDJobStatus); db_write_batch_file_records(jcr); /* used by bulk batch file insert */ if (!jcr->is_JobStatus(JS_Terminated)) { return false; } native_vbackup_cleanup(jcr, jcr->JobStatus); return true; } /* * Release resources allocated during backup. */ void native_vbackup_cleanup(JCR *jcr, int TermCode) { char ec1[30], ec2[30]; char term_code[100]; const char *term_msg; int msg_type = M_INFO; CLIENT_DBR cr; POOL_MEM query(PM_MESSAGE); Dmsg2(100, "Enter backup_cleanup %d %c\n", TermCode, TermCode); memset(&cr, 0, sizeof(cr)); switch (jcr->JobStatus) { case JS_Terminated: case JS_Warnings: jcr->jr.JobLevel = L_FULL; /* we want this to appear as a Full backup */ break; default: break; } jcr->JobFiles = jcr->SDJobFiles; jcr->JobBytes = jcr->SDJobBytes; if (jcr->getJobStatus() == JS_Terminated && (jcr->JobErrors || jcr->SDErrors)) { TermCode = JS_Warnings; } update_job_end(jcr, TermCode); /* * Update final items to set them to the previous job's values */ Mmsg(query, "UPDATE Job SET StartTime='%s',EndTime='%s'," "JobTDate=%s WHERE JobId=%s", jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime, edit_uint64(jcr->previous_jr.JobTDate, ec1), edit_uint64(jcr->JobId, ec2)); db_sql_query(jcr->db, query.c_str()); /* * Get the fully updated job record */ if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Job record for Job report: ERR=%s"), db_strerror(jcr->db)); jcr->setJobStatus(JS_ErrorTerminated); } bstrncpy(cr.Name, jcr->res.client->name(), sizeof(cr.Name)); if (!db_get_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting Client record for Job report: ERR=%s"), db_strerror(jcr->db)); } update_bootstrap_file(jcr); switch (jcr->JobStatus) { case JS_Terminated: term_msg = _("Backup OK"); break; case JS_Warnings: term_msg = _("Backup OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Backup Error ***"); msg_type = M_ERROR; /* Generate error message */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; case JS_Canceled: term_msg = _("Backup Canceled"); if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); if (jcr->SD_msg_chan_started) { pthread_cancel(jcr->SD_msg_chan); } } break; default: term_msg = term_code; sprintf(term_code, _("Inappropriate term code: %c\n"), jcr->JobStatus); break; } generate_backup_summary(jcr, &cr, msg_type, term_msg); Dmsg0(100, "Leave vbackup_cleanup()\n"); } /* * This callback routine is responsible for inserting the * items it gets into the bootstrap structure. For each JobId selected * this routine is called once for each file. We do not allow * duplicate filenames, but instead keep the info from the most * recent file entered (i.e. the JobIds are assumed to be sorted) * * See uar_sel_files in sql_cmds.c for query that calls us. * row[0]=Path, row[1]=Filename, row[2]=FileIndex * row[3]=JobId row[4]=LStat */ static int insert_bootstrap_handler(void *ctx, int num_fields, char **row) { JobId_t JobId; int FileIndex; RBSR *bsr = (RBSR *)ctx; JobId = str_to_int64(row[3]); FileIndex = str_to_int64(row[2]); add_findex(bsr, JobId, FileIndex); return 0; } static bool create_bootstrap_file(JCR *jcr, char *jobids) { RESTORE_CTX rx; UAContext *ua; memset(&rx, 0, sizeof(rx)); rx.bsr = new_bsr(); ua = new_ua_context(jcr); rx.JobIds = jobids; if (!db_open_batch_connection(jcr, jcr->db)) { Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connexion"); return false; } if (!db_get_file_list(jcr, jcr->db_batch, jobids, false /* don't use md5 */, true /* use delta */, insert_bootstrap_handler, (void *)rx.bsr)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db_batch)); } complete_bsr(ua, rx.bsr); jcr->ExpectedFiles = write_bsr_file(ua, rx); if (debug_level >= 10) { Dmsg1(000, "Found %d files to consolidate.\n", jcr->ExpectedFiles); } if (jcr->ExpectedFiles == 0) { free_ua_context(ua); free_bsr(rx.bsr); return false; } free_ua_context(ua); free_bsr(rx.bsr); return true; } bareos-Release-14.2.6/src/dird/verify.c000066400000000000000000000726251263011562700176350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Director -- verify.c -- responsible for running file verification * * Kern Sibbald, October MM * * Basic tasks done here: * Open DB * Open connection with File daemon and pass him commands to do the verify. * When the File daemon sends the attributes, compare them to what is in the DB. */ #include "bareos.h" #include "dird.h" #include "findlib/find.h" /* Commands sent to File daemon */ static char verifycmd[] = "verify level=%s\n"; static char storaddrcmd[] = "storage address=%s port=%d ssl=%d Authorization=%s\n"; static char passiveclientcmd[] = "passive client address=%s port=%d ssl=%d\n"; /* Responses received from File daemon */ static char OKverify[] = "2000 OK verify\n"; static char OKstore[] = "2000 OK storage\n"; static char OKpassiveclient[] = "2000 OK passive client\n"; /* Forward referenced functions */ static void prt_fname(JCR *jcr); static int missing_handler(void *ctx, int num_fields, char **row); /* * Called here before the job is run to do the job * specific setup. */ bool do_verify_init(JCR *jcr) { int JobLevel; if (!allow_duplicate_job(jcr)) { return false; } JobLevel = jcr->getJobLevel(); switch (JobLevel) { case L_VERIFY_INIT: case L_VERIFY_CATALOG: case L_VERIFY_DISK_TO_CATALOG: free_rstorage(jcr); free_wstorage(jcr); break; case L_VERIFY_VOLUME_TO_CATALOG: free_wstorage(jcr); break; case L_VERIFY_DATA: break; default: Jmsg2(jcr, M_FATAL, 0, _("Unimplemented Verify level %d(%c)\n"), JobLevel, JobLevel); return false; } return true; } /* * Do a verification of the specified files against the Catlaog * * Returns: false on failure * true on success */ bool do_verify(JCR *jcr) { int JobLevel; const char *level; BSOCK *fd = NULL; BSOCK *sd = NULL; int status; char ed1[100]; JOB_DBR jr; JobId_t verify_jobid = 0; const char *Name; free_wstorage(jcr); /* we don't write */ memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr)); /* * Find JobId of last job that ran. Note, we do this when * the job actually starts running, not at schedule time, * so that we find the last job that terminated before * this job runs rather than before it is scheduled. This * permits scheduling a Backup and Verify at the same time, * but with the Verify at a lower priority. * * For VERIFY_CATALOG we want the JobId of the last INIT. * For VERIFY_VOLUME_TO_CATALOG, we want the JobId of the * last backup Job. */ JobLevel = jcr->getJobLevel(); switch (JobLevel) { case L_VERIFY_CATALOG: case L_VERIFY_VOLUME_TO_CATALOG: case L_VERIFY_DISK_TO_CATALOG: memcpy(&jr, &jcr->jr, sizeof(jr)); if (jcr->res.verify_job && (JobLevel == L_VERIFY_VOLUME_TO_CATALOG || JobLevel == L_VERIFY_DISK_TO_CATALOG)) { Name = jcr->res.verify_job->name(); } else { Name = NULL; } Dmsg1(100, "find last jobid for: %s\n", NPRT(Name)); /* * See if user supplied a jobid= as run argument or from menu */ if (jcr->RestoreJobId) { verify_jobid = jcr->RestoreJobId; Dmsg1(100, "Supplied jobid=%d\n", verify_jobid); } else { if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) { if (JobLevel == L_VERIFY_CATALOG) { Jmsg(jcr, M_FATAL, 0, _( "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n")); } else { Jmsg(jcr, M_FATAL, 0, _( "Unable to find JobId of previous Job for this client.\n")); } return false; } verify_jobid = jr.JobId; } Dmsg1(100, "Last full jobid=%d\n", verify_jobid); /* * Now get the job record for the previous backup that interests * us. We use the verify_jobid that we found above. */ jcr->previous_jr.JobId = verify_jobid; if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) { Jmsg(jcr, M_FATAL, 0, _("Could not get job record for previous Job. ERR=%s"), db_strerror(jcr->db)); return false; } if (!(jcr->previous_jr.JobStatus == JS_Terminated || jcr->previous_jr.JobStatus == JS_Warnings)) { Jmsg(jcr, M_FATAL, 0, _("Last Job %d did not terminate normally. JobStatus=%c\n"), verify_jobid, jcr->previous_jr.JobStatus); return false; } Jmsg(jcr, M_INFO, 0, _("Verifying against JobId=%d Job=%s\n"), jcr->previous_jr.JobId, jcr->previous_jr.Job); } /* * If we are verifying a Volume, we need the Storage * daemon, so open a connection, otherwise, just * create a dummy authorization key (passed to * File daemon but not used). */ switch (JobLevel) { case L_VERIFY_VOLUME_TO_CATALOG: /* * Note: negative status is an error, zero status, means * no files were backed up, so skip calling SD and * client. */ status = create_restore_bootstrap_file(jcr); if (status < 0) { /* error */ return false; } else if (status == 0) { /* No files, nothing to do */ verify_cleanup(jcr, JS_Terminated); /* clean up */ return true; /* get out */ } if (jcr->res.verify_job) { jcr->res.fileset = jcr->res.verify_job->fileset; } break; default: jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */ break; } Dmsg2(100, "ClientId=%u JobLevel=%c\n", jcr->previous_jr.ClientId, JobLevel); if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); return false; } /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Verify JobId=%s Level=%s Job=%s\n"), edit_uint64(jcr->JobId, ed1), level_to_str(JobLevel), jcr->Job); switch (JobLevel) { case L_VERIFY_VOLUME_TO_CATALOG: /* * Start conversation with Storage daemon */ jcr->setJobStatus(JS_Blocked); if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { return false; } sd = jcr->store_bsock; /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->rstorage, NULL, /* send_bsr */ true)) { return false; } jcr->passive_client = jcr->res.client->passive; if (!jcr->passive_client) { /* * Start the Job in the SD. */ if (!sd->fsend("run")) { return false; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { return false; } Dmsg0(50, "Storage daemon connection OK\n"); } /* * OK, now connect to the File daemon and ask him for the files. */ jcr->setJobStatus(JS_Blocked); if (!connect_to_file_daemon(jcr, 10, me->FDConnectTimeout, true, true)) { goto bail_out; } fd = jcr->file_bsock; /* * Check if the file daemon supports passive client mode. */ if (jcr->passive_client && jcr->FDVersion < FD_VERSION_51) { Jmsg(jcr, M_FATAL, 0, _("Client \"%s\" doesn't support passive client mode. " "Please upgrade your client or disable compat mode.\n"), jcr->res.client->name()); goto bail_out; } break; default: /* * OK, now connect to the File daemon and ask him for the files. */ jcr->setJobStatus(JS_Blocked); if (!connect_to_file_daemon(jcr, 10, me->FDConnectTimeout, true, true)) { goto bail_out; } fd = jcr->file_bsock; break; } jcr->setJobStatus(JS_Running); Dmsg0(30, ">filed: Send include list\n"); if (!send_include_list(jcr)) { goto bail_out; } Dmsg0(30, ">filed: Send exclude list\n"); if (!send_exclude_list(jcr)) { goto bail_out; } /* * Send Level command to File daemon, as well as the Storage address if appropriate. */ switch (JobLevel) { case L_VERIFY_INIT: level = "init"; break; case L_VERIFY_CATALOG: level = "catalog"; break; case L_VERIFY_VOLUME_TO_CATALOG: if (!jcr->RestoreBootstrap) { Jmsg0(jcr, M_FATAL, 0, _("Deprecated feature ... use bootstrap.\n")); goto bail_out; } if (!jcr->passive_client) { int tls_need = BNET_TLS_NONE; STORERES *store = jcr->res.rstore; /* * Send Storage daemon address to the File daemon */ if (store->SDDport == 0) { store->SDDport = store->SDport; } /* * TLS Requirement */ if (store->tls_enable) { if (store->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } fd->fsend(storaddrcmd, store->address, store->SDDport, tls_need, jcr->sd_auth_key); if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) { goto bail_out; } } else { int tls_need = BNET_TLS_NONE; CLIENTRES *client = jcr->res.client; /* * TLS Requirement */ if (client->tls_enable) { if (client->tls_require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } /* * Tell the SD to connect to the FD. */ sd->fsend(passiveclientcmd, client->address, client->FDport, tls_need); if (!response(jcr, sd, OKpassiveclient, "Passive client", DISPLAY_ERROR)) { goto bail_out; } /* * Start the Job in the SD. */ if (!sd->fsend("run")) { goto bail_out; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { goto bail_out; } Dmsg0(50, "Storage daemon connection OK\n"); } level = "volume"; break; case L_VERIFY_DATA: level = "data"; break; case L_VERIFY_DISK_TO_CATALOG: level="disk_to_catalog"; break; default: Jmsg2(jcr, M_FATAL, 0, _("Unimplemented Verify level %d(%c)\n"), JobLevel, JobLevel); goto bail_out; } if (!send_runscripts_commands(jcr)) { goto bail_out; } /* * Send verify command/level to File daemon */ fd->fsend(verifycmd, level); if (!response(jcr, fd, OKverify, "Verify", DISPLAY_ERROR)) { goto bail_out; } /* * Now get data back from File daemon and * compare it to the catalog or store it in the * catalog depending on the run type. */ switch (JobLevel) { case L_VERIFY_CATALOG: /* * Verify from catalog */ Dmsg0(10, "Verify level=catalog\n"); jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ jcr->SDJobStatus = JS_Terminated; get_attributes_and_compare_to_catalog(jcr, jcr->previous_jr.JobId); break; case L_VERIFY_VOLUME_TO_CATALOG: /* * Verify Volume to catalog entries */ Dmsg0(10, "Verify level=volume\n"); get_attributes_and_compare_to_catalog(jcr, jcr->previous_jr.JobId); break; case L_VERIFY_DISK_TO_CATALOG: /* * Verify Disk attributes to catalog */ Dmsg0(10, "Verify level=disk_to_catalog\n"); jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ jcr->SDJobStatus = JS_Terminated; get_attributes_and_compare_to_catalog(jcr, jcr->previous_jr.JobId); break; case L_VERIFY_INIT: /* * Build catalog */ Dmsg0(10, "Verify level=init\n"); jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ jcr->SDJobStatus = JS_Terminated; get_attributes_and_put_in_catalog(jcr); db_end_transaction(jcr, jcr->db); /* terminate any open transaction */ db_write_batch_file_records(jcr); break; default: Jmsg1(jcr, M_FATAL, 0, _("Unimplemented verify level %d\n"), JobLevel); goto bail_out; } status = wait_for_job_termination(jcr); verify_cleanup(jcr, status); return true; bail_out: if (jcr->file_bsock) { jcr->file_bsock->signal(BNET_TERMINATE); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } return false; } /* * Release resources allocated during verify. */ void verify_cleanup(JCR *jcr, int TermCode) { int JobLevel; char sdt[50], edt[50]; char ec1[30], ec2[30]; char term_code[100], fd_term_msg[100], sd_term_msg[100]; const char *term_msg; int msg_type; const char *Name; // Dmsg1(100, "Enter verify_cleanup() TermCod=%d\n", TermCode); JobLevel = jcr->getJobLevel(); Dmsg3(900, "JobLevel=%c Expected=%u JobFiles=%u\n", JobLevel, jcr->ExpectedFiles, jcr->JobFiles); if (JobLevel == L_VERIFY_VOLUME_TO_CATALOG && jcr->ExpectedFiles != jcr->JobFiles) { TermCode = JS_ErrorTerminated; } update_job_end(jcr, TermCode); if (job_canceled(jcr)) { cancel_storage_daemon_job(jcr); } if (jcr->unlink_bsr && jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); jcr->unlink_bsr = false; } msg_type = M_INFO; /* By default INFO message */ switch (TermCode) { case JS_Terminated: term_msg = _("Verify OK"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Verify Error ***"); msg_type = M_ERROR; /* Generate error message */ break; case JS_Error: term_msg = _("Verify warnings"); break; case JS_Canceled: term_msg = _("Verify Canceled"); break; case JS_Differences: term_msg = _("Verify Differences"); break; default: term_msg = term_code; bsnprintf(term_code, sizeof(term_code), _("Inappropriate term code: %d %c\n"), TermCode, TermCode); break; } bstrftimes(sdt, sizeof(sdt), jcr->jr.StartTime); bstrftimes(edt, sizeof(edt), jcr->jr.EndTime); if (jcr->res.verify_job) { Name = jcr->res.verify_job->hdr.name; } else { Name = ""; } jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg)); switch (JobLevel) { case L_VERIFY_VOLUME_TO_CATALOG: jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg)); Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n" " Build OS: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Expected: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " SD termination status: %s\n" " Termination: %s\n\n"), BAREOS, my_name, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER, jcr->jr.JobId, jcr->jr.Job, jcr->res.fileset->hdr.name, level_to_str(JobLevel), jcr->res.client->hdr.name, jcr->previous_jr.JobId, Name, sdt, edt, edit_uint64_with_commas(jcr->ExpectedFiles, ec1), edit_uint64_with_commas(jcr->JobFiles, ec2), jcr->JobErrors, fd_term_msg, sd_term_msg, term_msg); break; default: Jmsg(jcr, msg_type, 0, _("%s %s %s (%s):\n" " Build: %s %s %s\n" " JobId: %d\n" " Job: %s\n" " FileSet: %s\n" " Verify Level: %s\n" " Client: %s\n" " Verify JobId: %d\n" " Verify Job: %s\n" " Start time: %s\n" " End time: %s\n" " Files Examined: %s\n" " Non-fatal FD errors: %d\n" " FD termination status: %s\n" " Termination: %s\n\n"), BAREOS, my_name, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER, jcr->jr.JobId, jcr->jr.Job, jcr->res.fileset->hdr.name, level_to_str(JobLevel), jcr->res.client->name(), jcr->previous_jr.JobId, Name, sdt, edt, edit_uint64_with_commas(jcr->JobFiles, ec1), jcr->JobErrors, fd_term_msg, term_msg); break; } Dmsg0(100, "Leave verify_cleanup()\n"); } /* * This routine is called only during a Verify */ void get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId) { BSOCK *fd; int n, len; FILE_DBR fdbr; struct stat statf; /* file stat */ struct stat statc; /* catalog stat */ POOL_MEM buf(PM_MESSAGE); POOLMEM *fname = get_pool_memory(PM_FNAME); int do_Digest = CRYPTO_DIGEST_NONE; int32_t file_index = 0; memset(&fdbr, 0, sizeof(fdbr)); fd = jcr->file_bsock; fdbr.JobId = JobId; jcr->FileIndex = 0; Dmsg0(20, "dir: waiting to receive file attributes\n"); /* * Get Attributes and Signature from File daemon * We expect: * FileIndex * Stream * Options or Digest (MD5/SHA1) * Filename * Attributes * Link name ??? */ while ((n=bget_dirmsg(fd)) >= 0 && !job_canceled(jcr)) { int stream; char *attr, *p, *fn; POOL_MEM Opts_Digest(PM_MESSAGE); /* Verify Opts or MD5/SHA1 digest */ if (job_canceled(jcr)) { goto bail_out; } fname = check_pool_memory_size(fname, fd->msglen); jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen); Dmsg1(200, "Atts+Digest=%s\n", fd->msg); if ((len = sscanf(fd->msg, "%ld %d %100s", &file_index, &stream, fname)) != 3) { Jmsg3(jcr, M_FATAL, 0, _("dirdmsglen, fd->msg); goto bail_out; } /* * We read the Options or Signature into fname * to prevent overrun, now copy it to proper location. */ pm_strcpy(Opts_Digest, fname); p = fd->msg; skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); skip_nonspaces(&p); /* skip Stream */ skip_spaces(&p); skip_nonspaces(&p); /* skip Opts_Digest */ p++; /* skip space */ fn = fname; while (*p != 0) { *fn++ = *p++; /* copy filename */ } *fn = *p++; /* term filename and point to attribs */ attr = p; /* * Got attributes stream, decode it */ switch (stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: int32_t LinkFIf, LinkFIc; Dmsg2(400, "file_index=%d attr=%s\n", file_index, attr); jcr->JobFiles++; jcr->FileIndex = file_index; /* remember attribute file_index */ jcr->previous_jr.FileIndex = file_index; decode_stat(attr, &statf, sizeof(statf), &LinkFIf); /* decode file stat packet */ do_Digest = CRYPTO_DIGEST_NONE; jcr->fn_printed = false; pm_strcpy(jcr->fname, fname); /* move filename into JCR */ Dmsg2(040, "dirdfname); Dmsg1(020, "dirddb, jcr->fname, &jcr->previous_jr, &fdbr)) { Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname); Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname); jcr->setJobStatus(JS_Differences); continue; } else { /* * mark file record as visited by stuffing the * current JobId, which is unique, into the MarkId field. */ db_mark_file_record(jcr, jcr->db, fdbr.FileId, jcr->JobId); } Dmsg3(400, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname, file_index, Opts_Digest.c_str()); decode_stat(fdbr.LStat, &statc, sizeof(statc), &LinkFIc); /* decode catalog stat */ /* * Loop over options supplied by user and verify the * fields he requests. */ for (p = Opts_Digest.c_str(); *p; p++) { char ed1[30], ed2[30]; switch (*p) { case 'i': /* compare INODEs */ if (statc.st_ino != statf.st_ino) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %s File: %s\n"), edit_uint64((uint64_t)statc.st_ino, ed1), edit_uint64((uint64_t)statf.st_ino, ed2)); jcr->setJobStatus(JS_Differences); } break; case 'p': /* permissions bits */ if (statc.st_mode != statf.st_mode) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"), (uint32_t)statc.st_mode, (uint32_t)statf.st_mode); jcr->setJobStatus(JS_Differences); } break; case 'n': /* number of links */ if (statc.st_nlink != statf.st_nlink) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"), (uint32_t)statc.st_nlink, (uint32_t)statf.st_nlink); jcr->setJobStatus(JS_Differences); } break; case 'u': /* user id */ if (statc.st_uid != statf.st_uid) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %u File: %u\n"), (uint32_t)statc.st_uid, (uint32_t)statf.st_uid); jcr->setJobStatus(JS_Differences); } break; case 'g': /* group id */ if (statc.st_gid != statf.st_gid) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %u File: %u\n"), (uint32_t)statc.st_gid, (uint32_t)statf.st_gid); jcr->setJobStatus(JS_Differences); } break; case 's': /* size */ if (statc.st_size != statf.st_size) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %s File: %s\n"), edit_uint64((uint64_t)statc.st_size, ed1), edit_uint64((uint64_t)statf.st_size, ed2)); jcr->setJobStatus(JS_Differences); } break; case 'a': /* access time */ if (statc.st_atime != statf.st_atime) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n")); jcr->setJobStatus(JS_Differences); } break; case 'm': if (statc.st_mtime != statf.st_mtime) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n")); jcr->setJobStatus(JS_Differences); } break; case 'c': /* ctime */ if (statc.st_ctime != statf.st_ctime) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n")); jcr->setJobStatus(JS_Differences); } break; case 'd': /* file size decrease */ if (statc.st_size > statf.st_size) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %s File: %s\n"), edit_uint64((uint64_t)statc.st_size, ed1), edit_uint64((uint64_t)statf.st_size, ed2)); jcr->setJobStatus(JS_Differences); } break; case '5': /* compare MD5 */ Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname); do_Digest = CRYPTO_DIGEST_MD5; break; case '1': /* compare SHA1 */ do_Digest = CRYPTO_DIGEST_SHA1; break; case ':': case 'V': default: break; } } break; case STREAM_RESTORE_OBJECT: Dmsg1(400, "RESTORE_OBJECT %s\n", jcr->fname); break; default: /* * Got Digest Signature from Storage daemon * It came across in the Opts_Digest field. */ if (crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) { Dmsg2(400, "stream=Digest inx=%d Digest=%s\n", file_index, Opts_Digest.c_str()); /* * When ever we get a digest it MUST have been * preceded by an attributes record, which sets attr_file_index */ if (jcr->FileIndex != (uint32_t)file_index) { Jmsg2(jcr, M_FATAL, 0, _("MD5/SHA1 index %d not same as attributes %d\n"), file_index, jcr->FileIndex); goto bail_out; } if (do_Digest != CRYPTO_DIGEST_NONE) { db_escape_string(jcr, jcr->db, buf.c_str(), Opts_Digest.c_str(), strlen(Opts_Digest.c_str())); if (!bstrcmp(buf.c_str(), fdbr.Digest)) { prt_fname(jcr); Jmsg(jcr, M_INFO, 0, _(" %s differs. File=%s Cat=%s\n"), stream_to_ascii(stream), buf.c_str(), fdbr.Digest); jcr->setJobStatus(JS_Differences); } do_Digest = CRYPTO_DIGEST_NONE; } } break; } jcr->JobFiles = file_index; } if (is_bnet_error(fd)) { berrno be; Jmsg2(jcr, M_FATAL, 0, _("dirfn_printed = false; Mmsg(buf, "SELECT Path.Path,Filename.Name FROM File,Path,Filename " "WHERE File.JobId=%d AND File.FileIndex > 0 " "AND File.MarkId!=%d AND File.PathId=Path.PathId " "AND File.FilenameId=Filename.FilenameId", JobId, jcr->JobId); /* missing_handler is called for each file found */ db_sql_query(jcr->db, buf.c_str(), missing_handler, (void *)jcr); if (jcr->fn_printed) { jcr->setJobStatus(JS_Differences); } bail_out: free_pool_memory(fname); } /* * We are called here for each record that matches the above * SQL query -- that is for each file contained in the Catalog * that was not marked earlier. This means that the file in * question is a missing file (in the Catalog but not on Disk). */ static int missing_handler(void *ctx, int num_fields, char **row) { JCR *jcr = (JCR *)ctx; if (job_canceled(jcr)) { return 1; } if (!jcr->fn_printed) { Qmsg(jcr, M_WARNING, 0, _("The following files are in the Catalog but not on %s:\n"), jcr->getJobLevel() == L_VERIFY_VOLUME_TO_CATALOG ? "the Volume(s)" : "disk"); jcr->fn_printed = true; } Qmsg(jcr, M_INFO, 0, " %s%s\n", row[0]?row[0]:"", row[1]?row[1]:""); return 0; } /* * Print filename for verify */ static void prt_fname(JCR *jcr) { if (!jcr->fn_printed) { Jmsg(jcr, M_INFO, 0, _("File: %s\n"), jcr->fname); jcr->fn_printed = true; } } bareos-Release-14.2.6/src/filed/000077500000000000000000000000001263011562700163125ustar00rootroot00000000000000bareos-Release-14.2.6/src/filed/Makefile.in000066400000000000000000000121541263011562700203620ustar00rootroot00000000000000# # Bareos Makefile for the File daemon # # @MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ fd_group=@fd_group@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/filed DEBUG=@DEBUG@ GETTEXT_LIBS = @LIBINTL@ OPENSSL_LIBS_NONSHARED = @OPENSSL_LIBS_NONSHARED@ GNUTLS_LIBS_NONSHARED = @GNUTLS_LIBS_NONSHARED@ COMPRESS_CPPFLAGS += @ZLIB_INC@ @LZO_INC@ @FASTLZ_INC@ first_rule: all dummy: # SVRSRCS = accurate.c accurate_htable.c accurate_lmdb.c authenticate.c \ backup.c compression.c crypto.c dir_cmd.c estimate.c \ fd_plugins.c filed_conf.c filed.c fileset.c heartbeat.c \ restore.c sd_cmds.c status.c verify_vol.c verify.c SVROBJS = $(SVRSRCS:.c=.o) FDLIBS += @LMDB_LIBS@ FDLIBS += @CAP_LIBS@ FDLIBS += @ZLIB_LIBS_NONSHARED@ FDLIBS += @LZO_LIBS_NONSHARED@ FDLIBS += @FASTLZ_LIBS_NONSHARED@ FDLIBS += @AFS_LIBS_NONSHARED@ FDLIBS += @ACL_LIBS_NONSHARED@ FDLIBS += @XATTR_LIBS_NONSHARED@ INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include -I$(basedir)/lmdb .SUFFIXES: .c .o .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- compression.o: compression.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(COMPRESS_CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< all: Makefile bareos-fd @STATIC_FD@ @echo "==== Make of filed is good ====" @echo " " win32/winlib.a: @if test -f win32/Makefile -a "${GMAKE}" != "none"; then \ (cd win32; $(GMAKE) DESTDIR=$(DESTDIR)); \ fi @rm -f bareos-fd.exe win32/winmain.o: @if test -f win32/Makefile -a "${GMAKE}" != "none"; then \ (cd win32; $(GMAKE) DESTDIR=$(DESTDIR)); \ fi @rm -f bareos-fd.exe win32/winres.res: @if test -f win32/Makefile -a "${GMAKE}" != "none"; then \ (cd win32; $(GMAKE) DESTDIR=$(DESTDIR)); \ fi @rm -f bareos-fd.exe bareos-fd: Makefile $(SVROBJS) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(WLDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(SVROBJS) \ $(FDLIBS) -lbareosfind -lbareoscfg -lbareos -lm $(LIBS) \ $(DLIB) $(WRAPLIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) static-bareos-fd: Makefile $(SVROBJS) \ ../findlib/libbareosfind.a \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -L../findlib -o $@ $(SVROBJS) \ $(FDLIBS) -lbareosfind -lbareoscfg -lbareos -lm $(LIBS) \ $(DLIB) $(WRAPLIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS) $(GNUTLS_LIBS) strip $@ Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) bareos-fd filed core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 @$(RMF) static-bareos-fd @if test -f win32/Makefile -a "${GMAKE}" != "none"; then \ (cd win32; $(GMAKE) clean); \ fi realclean: clean @$(RMF) tags bareos-fd.conf distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) @if test -f win32/Makefile -a "${GMAKE}" != "none"; then \ (cd win32; $(GMAKE) distclean); \ fi devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) @if test -f win32/Makefile -a "${GMAKE}" != "none"; then \ (cd win32; $(GMAKE) devclean); \ fi install: all $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bareos-fd $(DESTDIR)$(sbindir)/bareos-fd @srcconf=bareos-fd.conf; \ if test -f ${DESTDIR}${sysconfdir}/$$srcconf; then \ destconf=$$srcconf.new; \ echo " ==> Found existing $$srcconf, installing new conf file as $$destconf"; \ else \ destconf=$$srcconf; \ fi; \ echo "${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf"; \ ${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf -@if test "x${fd_group}" != "x"; then \ chgrp -f ${fd_group} ${DESTDIR}${sysconfdir}/$$destconf ; \ fi @if test -f static-bareos-fd; then \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) static-bareos-fd $(DESTDIR)$(sbindir)/static-bareos-fd; \ fi # Semi-automatic generation of dependencies: # Use gcc -MM because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(INCLUDES) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/filed/accurate.c000066400000000000000000000255731263011562700202610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bareos.h" #include "filed.h" #include "accurate.h" static int dbglvl = 100; bool accurate_mark_file_as_seen(JCR *jcr, char *fname) { accurate_payload *temp; if (!jcr->accurate || !jcr->file_list) { return false; } temp = jcr->file_list->lookup_payload(jcr, fname); if (temp) { jcr->file_list->mark_file_as_seen(jcr, temp); Dmsg1(dbglvl, "marked <%s> as seen\n", fname); } else { Dmsg1(dbglvl, "<%s> not found to be marked as seen\n", fname); } return true; } static inline bool accurate_lookup(JCR *jcr, char *fname, accurate_payload **payload) { bool found = false; *payload = jcr->file_list->lookup_payload(jcr, fname); if (*payload) { found = true; Dmsg1(dbglvl, "lookup <%s> ok\n", fname); } return found; } void accurate_free(JCR *jcr) { if (jcr->file_list) { jcr->file_list->destroy(jcr); delete jcr->file_list; jcr->file_list = NULL; } } /* * Send the deleted or the base file list and cleanup. */ bool accurate_finish(JCR *jcr) { bool retval = true; if (jcr->is_canceled() || jcr->is_incomplete()) { accurate_free(jcr); return retval; } if (jcr->accurate && jcr->file_list) { if (jcr->is_JobLevel(L_FULL)) { if (!jcr->rerunning) { retval = jcr->file_list->send_base_file_list(jcr); } } else { retval = jcr->file_list->send_deleted_list(jcr); } accurate_free(jcr); if (jcr->is_JobLevel(L_FULL)) { Jmsg(jcr, M_INFO, 0, _("Space saved with Base jobs: %lld MB\n"), jcr->base_size / (1024 * 1024)); } } return retval; } /* * This function is called for each file seen in fileset. * We check in file_list hash if fname have been backuped * the last time. After we can compare Lstat field. * Full Lstat usage have been removed on 6612 * * Returns: true if file has changed (must be backed up) * false file not changed */ bool accurate_check_file(JCR *jcr, FF_PKT *ff_pkt) { char *opts; char *fname; int32_t LinkFIc; struct stat statc; bool status = false; accurate_payload *payload; ff_pkt->delta_seq = 0; ff_pkt->accurate_found = false; if (!jcr->accurate && !jcr->rerunning) { return true; } if (!jcr->file_list) { return true; /* Not initialized properly */ } /* * Apply path stripping for lookup in accurate data. */ strip_path(ff_pkt); if (S_ISDIR(ff_pkt->statp.st_mode)) { fname = ff_pkt->link; } else { fname = ff_pkt->fname; } if (!accurate_lookup(jcr, fname, &payload)) { Dmsg1(dbglvl, "accurate %s (not found)\n", fname); status = true; unstrip_path(ff_pkt); goto bail_out; } /* * Restore original name so we can check the actual file when we check * the accurate options later on. This is mostly important for the * calculate_and_compare_file_chksum() function as that needs to calulate * the checksum of the real file and not try to open the stripped pathname. */ unstrip_path(ff_pkt); ff_pkt->accurate_found = true; ff_pkt->delta_seq = payload->delta_seq; decode_stat(payload->lstat, &statc, sizeof(statc), &LinkFIc); /* decode catalog stat */ if (!jcr->rerunning && (jcr->getJobLevel() == L_FULL)) { opts = ff_pkt->BaseJobOpts; } else { opts = ff_pkt->AccurateOpts; } /* * Loop over options supplied by user and verify the fields he requests. */ for (char *p = opts; !status && *p; p++) { char ed1[30], ed2[30]; switch (*p) { case 'i': /* Compare INODE numbers */ if (statc.st_ino != ff_pkt->statp.st_ino) { Dmsg3(dbglvl-1, "%s st_ino differ. Cat: %s File: %s\n", fname, edit_uint64((uint64_t)statc.st_ino, ed1), edit_uint64((uint64_t)ff_pkt->statp.st_ino, ed2)); status = true; } break; case 'p': /* Permissions bits */ /* * TODO: If something change only in perm, user, group * Backup only the attribute stream */ if (statc.st_mode != ff_pkt->statp.st_mode) { Dmsg3(dbglvl-1, "%s st_mode differ. Cat: %x File: %x\n", fname, (uint32_t)statc.st_mode, (uint32_t)ff_pkt->statp.st_mode); status = true; } break; case 'n': /* Number of links */ if (statc.st_nlink != ff_pkt->statp.st_nlink) { Dmsg3(dbglvl-1, "%s st_nlink differ. Cat: %d File: %d\n", fname, (uint32_t)statc.st_nlink, (uint32_t)ff_pkt->statp.st_nlink); status = true; } break; case 'u': /* User id */ if (statc.st_uid != ff_pkt->statp.st_uid) { Dmsg3(dbglvl-1, "%s st_uid differ. Cat: %u File: %u\n", fname, (uint32_t)statc.st_uid, (uint32_t)ff_pkt->statp.st_uid); status = true; } break; case 'g': /* Group id */ if (statc.st_gid != ff_pkt->statp.st_gid) { Dmsg3(dbglvl-1, "%s st_gid differ. Cat: %u File: %u\n", fname, (uint32_t)statc.st_gid, (uint32_t)ff_pkt->statp.st_gid); status = true; } break; case 's': /* Size */ if (statc.st_size != ff_pkt->statp.st_size) { Dmsg3(dbglvl-1, "%s st_size differ. Cat: %s File: %s\n", fname, edit_uint64((uint64_t)statc.st_size, ed1), edit_uint64((uint64_t)ff_pkt->statp.st_size, ed2)); status = true; } break; case 'a': /* Access time */ if (statc.st_atime != ff_pkt->statp.st_atime) { Dmsg1(dbglvl-1, "%s st_atime differs\n", fname); status = true; } break; case 'm': /* Modification time */ if (statc.st_mtime != ff_pkt->statp.st_mtime) { Dmsg1(dbglvl-1, "%s st_mtime differs\n", fname); status = true; } break; case 'c': /* Change time */ if (statc.st_ctime != ff_pkt->statp.st_ctime) { Dmsg1(dbglvl-1, "%s st_ctime differs\n", fname); status = true; } break; case 'd': /* File size decrease */ if (statc.st_size > ff_pkt->statp.st_size) { Dmsg3(dbglvl-1, "%s st_size decrease. Cat: %s File: %s\n", fname, edit_uint64((uint64_t)statc.st_size, ed1), edit_uint64((uint64_t)ff_pkt->statp.st_size, ed2)); status = true; } break; case 'A': /* Always backup a file */ status = true; break; case '5': /* Compare MD5 */ case '1': /* Compare SHA1 */ if (!status && ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && (bit_is_set(FO_MD5, ff_pkt->flags) || bit_is_set(FO_SHA1, ff_pkt->flags) || bit_is_set(FO_SHA256, ff_pkt->flags) || bit_is_set(FO_SHA512, ff_pkt->flags)))) { if (!*payload->chksum && !jcr->rerunning) { Jmsg(jcr, M_WARNING, 0, _("Cannot verify checksum for %s\n"), ff_pkt->fname); status = true; } else { status = !calculate_and_compare_file_chksum(jcr, ff_pkt, fname, payload->chksum); } } break; case ':': case 'J': case 'C': break; default: break; } } /* * In Incr/Diff accurate mode, we mark all files as seen * When in Full+Base mode, we mark only if the file match exactly */ if (jcr->getJobLevel() == L_FULL) { if (!status) { /* * Compute space saved with basefile. */ jcr->base_size += ff_pkt->statp.st_size; jcr->file_list->mark_file_as_seen(jcr, payload); } } else { jcr->file_list->mark_file_as_seen(jcr, payload); } bail_out: return status; } bool accurate_cmd(JCR *jcr) { uint32_t nb; int fname_length, lstat_length, chksum_length; char *fname, *lstat, *chksum; uint16_t delta_seq; BSOCK *dir = jcr->dir_bsock; if (job_canceled(jcr)) { return true; } if (sscanf(dir->msg, "accurate files=%u", &nb) != 1) { dir->fsend(_("2991 Bad accurate command\n")); return false; } #ifdef HAVE_LMDB if (me->always_use_lmdb) { jcr->file_list = New(B_ACCURATE_LMDB); } else { if (me->lmdb_threshold > 0 && nb >= me->lmdb_threshold) { jcr->file_list = New(B_ACCURATE_LMDB); } else { jcr->file_list = New(B_ACCURATE_HTABLE); } } #else jcr->file_list = New(B_ACCURATE_HTABLE); #endif jcr->file_list->init(jcr, nb); jcr->accurate = true; /* * dirmsg = fname + \0 + lstat + \0 + checksum + \0 + delta_seq + \0 */ while (dir->recv() >= 0) { fname = dir->msg; fname_length = strlen(fname); lstat = dir->msg + fname_length + 1; lstat_length = strlen(lstat); /* * No checksum. */ if ((fname_length + lstat_length + 2) >= dir->msglen) { chksum = NULL; chksum_length = 0; delta_seq = 0; } else { chksum = lstat + lstat_length + 1; chksum_length = strlen(chksum); delta_seq = str_to_int32(chksum + chksum_length + 1); /* * Sanity check total length of the received msg must be at least * total of the 3 lengths calculcated + 3 (\0) */ if ((fname_length + lstat_length + chksum_length + 3) > dir->msglen) { continue; } } jcr->file_list->add_file(jcr, fname, fname_length, lstat, lstat_length, chksum, chksum_length, delta_seq); } if (!jcr->file_list->end_load(jcr)) { return false; } return true; } bareos-Release-14.2.6/src/filed/accurate.h000066400000000000000000000114451263011562700202570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ACCURATE_H #define ACCURATE_H /* * Generic accurate payload is the same for any storage class. * * We store the lstat field as a character field as it makes storing of the * data much more efficient then storing it in a normal stat structure. * Nowadays most of these structures are 64 bits and they will use 136 * bytes (32 bits) and 128 bytes (64 bits) on Solaris. The ASCII encoding * of the lstat field most of the time is between 43 and 75 bytes with an * average of 60 bytes. (From live data of 152562393 files.) * * The seen flag is not in the actual accurate payload but stored in a * bitmap. This makes it much more efficient for a storage engine that has * to update the whole data when something changes. For things like a in * memory hash table it doesn't make much difference and it has the * disadvantage that we need to keep a filenr to index the bitmap which * also cost some bytes. */ struct accurate_payload { int64_t filenr; int32_t delta_seq; char *lstat; char *chksum; }; /* * Accurate payload storage abstraction classes. */ class B_ACCURATE: public SMARTALLOC { protected: int64_t m_filenr; char *m_seen_bitmap; public: /* methods */ B_ACCURATE() { m_filenr = 0; m_seen_bitmap = NULL; }; virtual ~B_ACCURATE() {}; virtual bool init(JCR *jcr, uint32_t nbfile) = 0; virtual bool add_file(JCR *jcr, char *fname, int fname_length, char *lstat, int lstat_length, char *chksum, int chksum_length, int32_t delta_seq) = 0; virtual bool end_load(JCR *jcr) = 0; virtual accurate_payload *lookup_payload(JCR *jcr, char *fname) = 0; virtual bool update_payload(JCR *jcr, char *fname, accurate_payload *payload) = 0; virtual bool send_base_file_list(JCR *jcr) = 0; virtual bool send_deleted_list(JCR *jcr) = 0; virtual void destroy(JCR *jcr) = 0; void mark_file_as_seen(JCR *jcr, accurate_payload *payload) { set_bit(payload->filenr, m_seen_bitmap); }; }; /* * Hash table specific storage abstraction class using the internal htable datastructure. */ struct CurFile { hlink link; char *fname; accurate_payload payload; }; class B_ACCURATE_HTABLE: public B_ACCURATE { protected: htable *m_file_list; public: /* methods */ B_ACCURATE_HTABLE(); ~B_ACCURATE_HTABLE(); bool init(JCR *jcr, uint32_t nbfile); bool add_file(JCR *jcr, char *fname, int fname_length, char *lstat, int lstat_length, char *chksum, int chksum_length, int32_t delta_seq); bool end_load(JCR *jcr); accurate_payload *lookup_payload(JCR *jcr, char *fname); bool update_payload(JCR *jcr, char *fname, accurate_payload *payload); bool send_base_file_list(JCR *jcr); bool send_deleted_list(JCR *jcr); void destroy(JCR *jcr); }; #ifdef HAVE_LMDB #include "lmdb.h" /* * Lighning Memory DataBase (LMDB) specific storage abstraction class using the Symas LMDB. */ class B_ACCURATE_LMDB: public B_ACCURATE { protected: int m_pay_load_length; POOLMEM *m_pay_load; POOLMEM *m_lmdb_name; MDB_env *m_db_env; MDB_dbi m_db_dbi; MDB_txn *m_db_rw_txn; MDB_txn *m_db_ro_txn; public: /* methods */ B_ACCURATE_LMDB(); ~B_ACCURATE_LMDB(); bool init(JCR *jcr, uint32_t nbfile); bool add_file(JCR *jcr, char *fname, int fname_length, char *lstat, int lstat_length, char *chksum, int chksum_length, int32_t delta_seq); bool end_load(JCR *jcr); accurate_payload *lookup_payload(JCR *jcr, char *fname); bool update_payload(JCR *jcr, char *fname, accurate_payload *payload); bool send_base_file_list(JCR *jcr); bool send_deleted_list(JCR *jcr); void destroy(JCR *jcr); }; #endif /* HAVE_LMDB */ #endif /* ACCURATE_H */ bareos-Release-14.2.6/src/filed/accurate_htable.c000066400000000000000000000124601263011562700215670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * This file contains the HTABLE abstraction of the accurate payload storage. * * Marco van Wieringen, December 2013 */ #include "bareos.h" #include "filed.h" #include "accurate.h" static int dbglvl = 100; B_ACCURATE_HTABLE::B_ACCURATE_HTABLE() { m_filenr = 0; m_file_list = NULL; m_seen_bitmap = NULL; } B_ACCURATE_HTABLE::~B_ACCURATE_HTABLE() { } bool B_ACCURATE_HTABLE::init(JCR *jcr, uint32_t nbfile) { CurFile *elt = NULL; if (!m_file_list) { m_file_list = (htable *)malloc(sizeof(htable)); m_file_list->init(elt, &elt->link, nbfile); } if (!m_seen_bitmap) { m_seen_bitmap = (char *)malloc(nbytes_for_bits(nbfile)); clear_all_bits(nbfile, m_seen_bitmap); } return true; } bool B_ACCURATE_HTABLE::add_file(JCR *jcr, char *fname, int fname_length, char *lstat, int lstat_length, char *chksum, int chksum_length, int32_t delta_seq) { CurFile *item; int total_length; bool retval = true; total_length = sizeof(CurFile) + fname_length + lstat_length + chksum_length + 3; item = (CurFile *)m_file_list->hash_malloc(total_length); item->fname = (char *)item + sizeof(CurFile); memcpy(item->fname, fname, fname_length); item->fname[fname_length] = '\0'; item->payload.lstat = item->fname + fname_length + 1; memcpy(item->payload.lstat, lstat, lstat_length); item->payload.lstat[lstat_length] = '\0'; item->payload.chksum = item->payload.lstat + lstat_length + 1; if (chksum_length) { memcpy(item->payload.chksum, chksum, chksum_length); } item->payload.chksum[chksum_length] = '\0'; item->payload.delta_seq = delta_seq; item->payload.filenr = m_filenr++; m_file_list->insert(item->fname, item); if (chksum) { Dmsg4(dbglvl, "add fname=<%s> lstat=%s delta_seq=%i chksum=%s\n", fname, lstat, delta_seq, chksum); } else { Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat); } return retval; } bool B_ACCURATE_HTABLE::end_load(JCR *jcr) { /* * Nothing to do. */ return true; } accurate_payload *B_ACCURATE_HTABLE::lookup_payload(JCR *jcr, char *fname) { CurFile *temp; temp = (CurFile *)m_file_list->lookup(fname); return (temp) ? &temp->payload : NULL; } bool B_ACCURATE_HTABLE::update_payload(JCR *jcr, char *fname, accurate_payload *payload) { /* * Nothing to do. */ return true; } bool B_ACCURATE_HTABLE::send_base_file_list(JCR *jcr) { CurFile *elt; FF_PKT *ff_pkt; int32_t LinkFIc; struct stat statp; int stream = STREAM_UNIX_ATTRIBUTES; if (!jcr->accurate || jcr->getJobLevel() != L_FULL) { return true; } if (m_file_list == NULL) { return true; } ff_pkt = init_find_files(); ff_pkt->type = FT_BASE; foreach_htable(elt, m_file_list) { if (bit_is_set(elt->payload.filenr, m_seen_bitmap)) { Dmsg1(dbglvl, "base file fname=%s\n", elt->fname); decode_stat(elt->payload.lstat, &statp, sizeof(statp), &LinkFIc); /* decode catalog stat */ ff_pkt->fname = elt->fname; ff_pkt->statp = statp; encode_and_send_attributes(jcr, ff_pkt, stream); } } term_find_files(ff_pkt); return true; } bool B_ACCURATE_HTABLE::send_deleted_list(JCR *jcr) { CurFile *elt; FF_PKT *ff_pkt; int32_t LinkFIc; struct stat statp; int stream = STREAM_UNIX_ATTRIBUTES; if (!jcr->accurate) { return true; } ff_pkt = init_find_files(); ff_pkt->type = FT_DELETED; foreach_htable(elt, m_file_list) { if (bit_is_set(elt->payload.filenr, m_seen_bitmap) || plugin_check_file(jcr, elt->fname)) { continue; } Dmsg1(dbglvl, "deleted fname=%s\n", elt->fname); ff_pkt->fname = elt->fname; decode_stat(elt->payload.lstat, &statp, sizeof(statp), &LinkFIc); /* decode catalog stat */ ff_pkt->statp.st_mtime = statp.st_mtime; ff_pkt->statp.st_ctime = statp.st_ctime; encode_and_send_attributes(jcr, ff_pkt, stream); } term_find_files(ff_pkt); return true; } void B_ACCURATE_HTABLE::destroy(JCR *jcr) { if (m_file_list) { m_file_list->destroy(); free(m_file_list); m_file_list = NULL; } if (m_seen_bitmap) { free(m_seen_bitmap); m_seen_bitmap = NULL; } m_filenr = 0; } bareos-Release-14.2.6/src/filed/accurate_lmdb.c000066400000000000000000000366371263011562700212620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * This file contains the LMDB abstraction of the accurate payload storage. * * Marco van Wieringen, December 2013 */ #include "bareos.h" #include "filed.h" #ifdef HAVE_LMDB #include "accurate.h" static int dbglvl = 100; #define AVG_NR_BYTES_PER_ENTRY 256 #define B_PAGE_SIZE 4096 B_ACCURATE_LMDB::B_ACCURATE_LMDB() { m_filenr = 0; m_pay_load = NULL; m_lmdb_name = NULL; m_seen_bitmap = NULL; m_db_env = NULL; m_db_ro_txn = NULL; m_db_rw_txn = NULL; m_db_dbi = 0; } B_ACCURATE_LMDB::~B_ACCURATE_LMDB() { } bool B_ACCURATE_LMDB::init(JCR *jcr, uint32_t nbfile) { int result; MDB_env *env; size_t mapsize = 10485760; if (!m_db_env) { result = mdb_env_create(&env); if (result) { Jmsg1(jcr, M_FATAL, 0, _("Unable to create MDB environment: %s\n"), mdb_strerror(result)); return false; } if ((nbfile * AVG_NR_BYTES_PER_ENTRY) > mapsize) { size_t pagesize; #ifdef HAVE_GETPAGESIZE pagesize = getpagesize(); #else pagesize = B_PAGE_SIZE; #endif mapsize = (((nbfile * AVG_NR_BYTES_PER_ENTRY) / pagesize) + 1) * pagesize; } result = mdb_env_set_mapsize(env, mapsize); if (result) { Jmsg1(jcr, M_FATAL, 0, _("Unable to set MDB mapsize: %s\n"), mdb_strerror(result)); goto bail_out; } /* * Explicitly set the number of readers to 1. */ result = mdb_env_set_maxreaders(env, 1); if (result) { Jmsg1(jcr, M_FATAL, 0, _("Unable to set MDB maxreaders: %s\n"), mdb_strerror(result)); goto bail_out; } Mmsg(m_lmdb_name, "%s/.accurate_lmdb.%d", me->working_directory, jcr->JobId); result = mdb_env_open(env, m_lmdb_name, MDB_NOSUBDIR | MDB_NOLOCK | MDB_NOSYNC, 0600); if (result) { Jmsg2(jcr, M_FATAL, 0, _("Unable create LDMD database %s: %s\n"), m_lmdb_name, mdb_strerror(result)); goto bail_out; } result = mdb_txn_begin(env, NULL, 0, &m_db_rw_txn); if (result) { Jmsg1(jcr, M_FATAL, 0, _("Unable to start a write transaction: %s\n"), mdb_strerror(result)); goto bail_out; } result = mdb_dbi_open(m_db_rw_txn, NULL, MDB_CREATE, &m_db_dbi); if (result) { Jmsg1(jcr, M_FATAL, 0, _("Unable to open LMDB internal database: %s\n"), mdb_strerror(result)); mdb_txn_abort(m_db_rw_txn); m_db_rw_txn = NULL; goto bail_out; } m_db_env = env; } if (!m_pay_load) { m_pay_load = get_pool_memory(PM_MESSAGE); } if (!m_lmdb_name) { m_lmdb_name = get_pool_memory(PM_FNAME); } if (!m_seen_bitmap) { m_seen_bitmap = (char *)malloc(nbytes_for_bits(nbfile)); clear_all_bits(nbfile, m_seen_bitmap); } return true; bail_out: if (env) { mdb_env_close(env); } return false; } bool B_ACCURATE_LMDB::add_file(JCR *jcr, char *fname, int fname_length, char *lstat, int lstat_length, char *chksum, int chksum_length, int32_t delta_seq) { accurate_payload *payload; int result; int total_length; MDB_val key, data; bool retval = false; total_length = sizeof(accurate_payload) + lstat_length + chksum_length + 2; /* * Make sure m_pay_load is large enough. */ m_pay_load = check_pool_memory_size(m_pay_load, total_length); /* * We store the total pay load as: * * accurate_payload structure\0lstat\0chksum\0 */ payload = (accurate_payload *)m_pay_load; payload->lstat = (char *)payload + sizeof(accurate_payload); memcpy(payload->lstat, lstat, lstat_length); payload->lstat[lstat_length] = '\0'; payload->chksum = (char *)payload->lstat + lstat_length + 1; if (chksum_length) { memcpy(payload->chksum, chksum, chksum_length); } payload->chksum[chksum_length] = '\0'; payload->delta_seq = delta_seq; payload->filenr = m_filenr++; key.mv_data = fname; key.mv_size = strlen(fname) + 1; data.mv_data = payload; data.mv_size = total_length; retry: result = mdb_put(m_db_rw_txn, m_db_dbi, &key, &data, MDB_NOOVERWRITE); switch (result) { case 0: if (chksum) { Dmsg4(dbglvl, "add fname=<%s> lstat=%s delta_seq=%i chksum=%s\n", fname, lstat, delta_seq, chksum); } else { Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat); } retval = true; break; case MDB_TXN_FULL: /* * Seems we filled the transaction. * Flush the current transaction start a new one and retry the put. */ result = mdb_txn_commit(m_db_rw_txn); if (result == 0) { result = mdb_txn_begin(m_db_env, NULL, 0, &m_db_rw_txn); if (result == 0) { goto retry; } } /* * Fallthrough wanted. */ default: Jmsg1(jcr, M_FATAL, 0, _("Unable insert new data: %s\n"), mdb_strerror(result)); break; } return retval; } bool B_ACCURATE_LMDB::end_load(JCR *jcr) { int result; /* * Commit any pending write transactions. */ if (m_db_rw_txn) { result = mdb_txn_commit(m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable close write transaction: %s\n"), mdb_strerror(result)); return false; } result = mdb_txn_begin(m_db_env, NULL, 0, &m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to create write transaction: %s\n"), mdb_strerror(result)); return false; } } /* * From now on we also will be doing read transactions so create a read transaction context. */ if (!m_db_ro_txn) { result = mdb_txn_begin(m_db_env, NULL, MDB_RDONLY, &m_db_ro_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to create read transaction: %s\n"), mdb_strerror(result)); return false; } } return true; } accurate_payload *B_ACCURATE_LMDB::lookup_payload(JCR *jcr, char *fname) { int result; int lstat_length; MDB_val key, data; accurate_payload *payload = NULL; key.mv_data = fname; key.mv_size = strlen(fname) + 1; result = mdb_get(m_db_ro_txn, m_db_dbi, &key, &data); switch (result) { case 0: /* * Success. * * We need to make a private copy of the LDMB data as we are not * allowed to change its content and we need to update the lstat * and chksum pointer to point to the actual lstat and chksum that * is stored behind the accurate_payload structure in the LMDB. */ m_pay_load = check_pool_memory_size(m_pay_load, data.mv_size); payload = (accurate_payload *)m_pay_load; memcpy(payload, data.mv_data, data.mv_size); payload->lstat = (char *)payload + sizeof(accurate_payload); lstat_length = strlen(payload->lstat); payload->chksum = (char *)payload->lstat + lstat_length + 1; /* * We keep the transaction as short a possible so after a lookup * and copying the actual data out we reset the read transaction * and do a renew of the read transaction for a new run. */ mdb_txn_reset(m_db_ro_txn); result = mdb_txn_renew(m_db_ro_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to renew read transaction: %s\n"), mdb_strerror(result)); return NULL; } break; case MDB_NOTFOUND: /* * Failed to find the given key. */ break; default: break; } return payload; } bool B_ACCURATE_LMDB::update_payload(JCR *jcr, char *fname, accurate_payload *payload) { int result, total_length, lstat_length, chksum_length; MDB_val key, data; bool retval = false; accurate_payload *new_payload; lstat_length = strlen(payload->lstat); chksum_length = strlen(payload->chksum); total_length = sizeof(accurate_payload) + lstat_length + chksum_length + 2; /* * Make sure m_pay_load is large enough. */ m_pay_load = check_pool_memory_size(m_pay_load, total_length); /* * We store the total pay load as: * * accurate_payload structure\0lstat\0chksum\0 */ new_payload = (accurate_payload *)m_pay_load; new_payload->lstat = (char *)payload + sizeof(accurate_payload); memcpy(new_payload->lstat, payload->lstat, lstat_length); new_payload->lstat[lstat_length] = '\0'; new_payload->chksum = (char *)new_payload->lstat + lstat_length + 1; if (chksum_length) { memcpy(new_payload->chksum, payload->chksum, chksum_length); } new_payload->chksum[chksum_length] = '\0'; new_payload->delta_seq = payload->delta_seq; new_payload->filenr = payload->filenr; key.mv_data = fname; key.mv_size = strlen(fname) + 1; data.mv_data = new_payload; data.mv_size = total_length; retry: result = mdb_put(m_db_rw_txn, m_db_dbi, &key, &data, 0); switch (result) { case 0: result = mdb_txn_commit(m_db_rw_txn); if (result == 0) { result = mdb_txn_begin(m_db_env, NULL, 0, &m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to create write transaction: %s\n"), mdb_strerror(result)); } else { retval = true; } } else { Jmsg1(jcr, M_FATAL, 0, _("Unable close write transaction: %s\n"), mdb_strerror(result)); } break; case MDB_TXN_FULL: /* * Seems we filled the transaction. * Flush the current transaction start a new one and retry the put. */ result = mdb_txn_commit(m_db_rw_txn); if (result == 0) { result = mdb_txn_begin(m_db_env, NULL, 0, &m_db_rw_txn); if (result == 0) { goto retry; } } /* * Fallthrough wanted. */ default: Jmsg1(jcr, M_FATAL, 0, _("Unable insert new data: %s\n"), mdb_strerror(result)); break; } return retval; } bool B_ACCURATE_LMDB::send_base_file_list(JCR *jcr) { int result; int32_t LinkFIc; FF_PKT *ff_pkt; MDB_cursor *cursor; MDB_val key, data; bool retval = false; accurate_payload *payload; int stream = STREAM_UNIX_ATTRIBUTES; if (!jcr->accurate || jcr->getJobLevel() != L_FULL) { return true; } /* * Commit any pending write transactions. */ if (m_db_rw_txn) { result = mdb_txn_commit(m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable close write transaction: %s\n"), mdb_strerror(result)); return false; } m_db_rw_txn = NULL; } ff_pkt = init_find_files(); ff_pkt->type = FT_BASE; result = mdb_cursor_open(m_db_ro_txn, m_db_dbi, &cursor); if (result == 0) { while ((result = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { payload = (accurate_payload *)data.mv_data; if (bit_is_set(payload->filenr, m_seen_bitmap)) { Dmsg1(dbglvl, "base file fname=%s\n", key.mv_data); decode_stat(payload->lstat, &ff_pkt->statp, sizeof(struct stat), &LinkFIc); /* decode catalog stat */ ff_pkt->fname = (char *)key.mv_data; encode_and_send_attributes(jcr, ff_pkt, stream); } } mdb_cursor_close(cursor); } else { Jmsg1(jcr, M_FATAL, 0, _("Unable create cursor: %s\n"), mdb_strerror(result)); } mdb_txn_reset(m_db_ro_txn); result = mdb_txn_renew(m_db_ro_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to renew read transaction: %s\n"), mdb_strerror(result)); goto bail_out; } retval = true; bail_out: term_find_files(ff_pkt); return retval; } bool B_ACCURATE_LMDB::send_deleted_list(JCR *jcr) { int result; int32_t LinkFIc; struct stat statp; FF_PKT *ff_pkt; MDB_cursor *cursor; MDB_val key, data; bool retval = false; accurate_payload *payload; int stream = STREAM_UNIX_ATTRIBUTES; if (!jcr->accurate) { return true; } /* * Commit any pending write transactions. */ if (m_db_rw_txn) { result = mdb_txn_commit(m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable close write transaction: %s\n"), mdb_strerror(result)); return false; } m_db_rw_txn = NULL; } ff_pkt = init_find_files(); ff_pkt->type = FT_DELETED; result = mdb_cursor_open(m_db_ro_txn, m_db_dbi, &cursor); if (result == 0) { while ((result = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { payload = (accurate_payload *)data.mv_data; if (bit_is_set(payload->filenr, m_seen_bitmap) || plugin_check_file(jcr, (char *)key.mv_data)) { continue; } Dmsg1(dbglvl, "deleted fname=%s\n", key.mv_data); decode_stat(payload->lstat, &statp, sizeof(struct stat), &LinkFIc); /* decode catalog stat */ ff_pkt->fname = (char *)key.mv_data; ff_pkt->statp.st_mtime = statp.st_mtime; ff_pkt->statp.st_ctime = statp.st_ctime; encode_and_send_attributes(jcr, ff_pkt, stream); } mdb_cursor_close(cursor); } else { Jmsg1(jcr, M_FATAL, 0, _("Unable create cursor: %s\n"), mdb_strerror(result)); } mdb_txn_reset(m_db_ro_txn); result = mdb_txn_renew(m_db_ro_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to renew read transaction: %s\n"), mdb_strerror(result)); goto bail_out; } retval = true; bail_out: term_find_files(ff_pkt); return retval; } void B_ACCURATE_LMDB::destroy(JCR *jcr) { /* * Abort any pending read transaction. */ if (m_db_ro_txn) { mdb_txn_abort(m_db_ro_txn); m_db_ro_txn = NULL; } /* * Abort any pending write transaction. */ if (m_db_rw_txn) { mdb_txn_abort(m_db_rw_txn); m_db_rw_txn = NULL; } if (m_db_env) { /* * Drop the contents of the LMDB. */ if (m_db_dbi) { int result; MDB_txn *txn; result = mdb_txn_begin(m_db_env, NULL, 0, &txn); if (result == 0) { result = mdb_drop(txn, m_db_dbi, 1); if (result == 0) { mdb_txn_commit(txn); } else { mdb_txn_abort(txn); } } m_db_dbi = 0; } /* * Close the environment. */ mdb_env_close(m_db_env); m_db_env = NULL; } if (m_pay_load) { free_pool_memory(m_pay_load); m_pay_load = NULL; } if (m_lmdb_name) { unlink(m_lmdb_name); free_pool_memory(m_lmdb_name); m_lmdb_name = NULL; } if (m_seen_bitmap) { free(m_seen_bitmap); m_seen_bitmap = NULL; } m_filenr = 0; } #endif /* HAVE_LMDB */ bareos-Release-14.2.6/src/filed/authenticate.c000066400000000000000000000301261263011562700211360ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Authenticate Director who is attempting to connect. * * Kern Sibbald, October 2000 */ #include "bareos.h" #include "filed.h" const int dbglvl = 50; /* Version at end of Hello * prior to 10Mar08 no version * 1 10Mar08 * 2 13Mar09 - Added the ability to restore from multiple storages * 3 03Sep10 - Added the restore object command for vss plugin 4.0 * 4 25Nov10 - Added bandwidth command 5.1 * 5 24Nov11 - Added new restore object command format (pluginname) 6.0 * * 51 21Mar13 - Added reverse datachannel initialization * 52 13Jul13 - Added plugin options * 53 02Apr15 - Added setdebug timestamp */ static char OK_hello_compat[] = "2000 OK Hello 5\n"; static char OK_hello[] = "2000 OK Hello 53\n"; static char Dir_sorry[] = "2999 Authentication failed.\n"; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* * See who is connecting and lookup the authentication information. * First make him prove his identity and then prove our identity to the Remote daemon. */ static inline bool two_way_authenticate(int rcode, BSOCK *bs, JCR* jcr) { POOLMEM *dirname = get_pool_memory(PM_MESSAGE); DIRRES *director = NULL; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; /* Want md5 compatible DIR */ bool auth_success = false; alist *verify_list = NULL; btimer_t *tid = NULL; if (rcode != R_DIRECTOR) { Dmsg1(dbglvl, "I only authenticate directors, not %d\n", rcode); Jmsg1(jcr, M_FATAL, 0, _("I only authenticate directors, not %d\n"), rcode); goto auth_fatal; } if (bs->msglen < 25 || bs->msglen > 500) { Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n", bs->who(), bs->msglen); char addr[64]; char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"), who, bs->msglen); goto auth_fatal; } dirname = check_pool_memory_size(dirname, bs->msglen); if (sscanf(bs->msg, "Hello Director %s calling", dirname) != 1) { char addr[64]; char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; bs->msg[100] = 0; Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n", bs->who(), bs->msg); Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"), who, bs->msg); goto auth_fatal; } unbash_spaces(dirname); foreach_res(director, R_DIRECTOR) { if (bstrcmp(director->hdr.name, dirname)) break; } if (!director) { char addr[64]; char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), dirname, who); goto auth_fatal; } if (have_tls) { /* * TLS Requirement */ if (director->tls_enable) { if (director->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } if (director->tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } if (director->tls_verify_peer) { verify_list = director->tls_allowed_cns; } } /* * Timeout Hello after 10 min */ tid = start_bsock_timer(bs, AUTH_TIMEOUT); /* * Sanity check. */ ASSERT(director->password.encoding == p_encoding_md5); /* * Challenge the director */ auth_success = cram_md5_challenge(bs, director->password.value, tls_local_need, compatible); if (job_canceled(jcr)) { auth_success = false; goto auth_fatal; /* quick exit */ } if (auth_success) { auth_success = cram_md5_respond(bs, director->password.value, &tls_remote_need, &compatible); if (!auth_success) { char addr[64]; char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Dmsg1(dbglvl, "cram_get_auth failed for %s\n", who); } } else { char addr[64]; char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who() : addr; Dmsg1(dbglvl, "cram_auth failed for %s\n", who); } if (!auth_success) { Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"), bs->who()); goto auth_fatal; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" " advertize required TLS support.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) { Jmsg0(jcr, M_FATAL, 0, _("TLS negotiation failed.\n")); auth_success = false; goto auth_fatal; } if (director->tls_authenticate) { /* authentication only? */ bs->free_tls(); /* shutodown tls */ } } auth_fatal: if (tid) { stop_bsock_timer(tid); tid = NULL; } free_pool_memory(dirname); jcr->director = director; /* * Single thread all failures to avoid DOS */ if (!auth_success) { P(mutex); bmicrosleep(6, 0); V(mutex); } return auth_success; } /* * First prove our identity to the Remote daemon and then make him prove his identity. */ static inline bool two_way_authenticate(BSOCK *bs, JCR *jcr, bool initiate, const char *what) { int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; bool auth_success = false; alist *verify_list = NULL; btimer_t *tid = NULL; /* * TLS Requirement */ if (have_tls && me->tls_enable) { if (me->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } if (me->tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } if (job_canceled(jcr)) { auth_success = false; /* force quick exit */ goto auth_fatal; } /* * Timeout Hello after 10 min */ tid = start_bsock_timer(bs, AUTH_TIMEOUT); /* * See if we initiate the challenge or respond to a challenge. */ if (initiate) { /* * Challenge SD */ auth_success = cram_md5_challenge(bs, jcr->sd_auth_key, tls_local_need, compatible); if (auth_success) { /* * Respond to his challenge */ auth_success = cram_md5_respond(bs, jcr->sd_auth_key, &tls_remote_need, &compatible); if (!auth_success) { Dmsg1(dbglvl, "Respond cram-get-auth failed with %s\n", bs->who()); } } else { Dmsg1(dbglvl, "Challenge cram-auth failed with %s\n", bs->who()); } } else { /* * Respond to challenge */ auth_success = cram_md5_respond(bs, jcr->sd_auth_key, &tls_remote_need, &compatible); if (job_canceled(jcr)) { auth_success = false; /* force quick exit */ goto auth_fatal; } if (!auth_success) { Dmsg1(dbglvl, "cram_respond failed for %s\n", bs->who()); } else { /* * Challenge SD. */ auth_success = cram_md5_challenge(bs, jcr->sd_auth_key, tls_local_need, compatible); if (!auth_success) { Dmsg1(dbglvl, "cram_challenge failed for %s\n", bs->who()); } } } if (!auth_success) { Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by %s daemon.\n" "Please see %s for help.\n"), what, MANUAL_AUTH_URL); goto auth_fatal; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" " advertize required TLS support.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { /* * See if we are handshaking a passive client connection. */ if (initiate) { verify_list = me->tls_allowed_cns; if (!bnet_tls_server(me->tls_ctx, bs, verify_list)) { Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n")); auth_success = false; goto auth_fatal; } } else { if (!bnet_tls_client(me->tls_ctx, bs, verify_list)) { Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n")); auth_success = false; goto auth_fatal; } } if (me->tls_authenticate) { /* tls authentication only? */ bs->free_tls(); /* yes, shutdown tls */ } } auth_fatal: /* * Destroy session key */ memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); stop_bsock_timer(tid); /* * Single thread all failures to avoid DOS */ if (!auth_success) { P(mutex); bmicrosleep(6, 0); V(mutex); } return auth_success; } /* * Inititiate the communications with the Director. * He has made a connection to our server. * * Basic tasks done here: * We read Director's initial message and authorize him. */ bool authenticate_director(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; if (!two_way_authenticate(R_DIRECTOR, dir, jcr)) { dir->fsend("%s", Dir_sorry); Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n")); return false; } return dir->fsend("%s", (me->compatible) ? OK_hello_compat : OK_hello); } /* * Authenticate a remote storage daemon. */ bool authenticate_storagedaemon(JCR *jcr) { BSOCK *sd = jcr->store_bsock; return two_way_authenticate(sd, jcr, true, "Storage"); } /* * Authenticate with a remote storage daemon. */ bool authenticate_with_storagedaemon(JCR *jcr) { BSOCK *sd = jcr->store_bsock; return two_way_authenticate(sd, jcr, false, "Storage"); } bareos-Release-14.2.6/src/filed/backup.c000066400000000000000000001355031263011562700177320ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Bareos File Daemon backup.c send file attributes and data to the Storage daemon. * * Kern Sibbald, March MM */ #include "bareos.h" #include "filed.h" #include "ch.h" #ifdef HAVE_DARWIN_OS const bool have_darwin_os = true; #else const bool have_darwin_os = false; #endif #if defined(HAVE_ACL) const bool have_acl = true; #else const bool have_acl = false; #endif #if defined(HAVE_XATTR) const bool have_xattr = true; #else const bool have_xattr = false; #endif #ifndef compressBound #define compressBound(sourceLen) (sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13) #endif /* Forward referenced functions */ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level); static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest); bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream); static void close_vss_backup_session(JCR *jcr); /** * Find all the requested files and send them * to the Storage daemon. * * Note, we normally carry on a one-way * conversation from this point on with the SD, simply blasting * data to him. To properly know what is going on, we * also run a "heartbeat" monitor which reads the socket and * reacts accordingly (at the moment it has nothing to do * except echo the heartbeat to the Director). * */ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) { BSOCK *sd; bool ok = true; // TODO landonf: Allow user to specify encryption algorithm sd = jcr->store_bsock; jcr->setJobStatus(JS_Running); Dmsg1(300, "filed: opened data connection %d to stored\n", sd->m_fd); LockRes(); CLIENTRES *client = (CLIENTRES *)GetNextRes(R_CLIENT, NULL); UnlockRes(); uint32_t buf_size; if (client) { buf_size = client->max_network_buffer_size; } else { buf_size = 0; /* use default */ } if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) { jcr->setJobStatus(JS_ErrorTerminated); Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n")); return false; } jcr->buf_size = sd->msglen; if (!adjust_compression_buffers(jcr)) { return false; } if (!crypto_session_start(jcr)) { return false; } set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime); /** in accurate mode, we overload the find_one check function */ if (jcr->accurate) { set_find_changed_function((FF_PKT *)jcr->ff, accurate_check_file); } start_heartbeat_monitor(jcr); if (have_acl) { jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t)); memset(jcr->acl_data, 0, sizeof(acl_data_t)); jcr->acl_data->u.build = (acl_build_data_t *)malloc(sizeof(acl_build_data_t)); memset(jcr->acl_data->u.build, 0, sizeof(acl_build_data_t)); jcr->acl_data->u.build->content = get_pool_memory(PM_MESSAGE); } if (have_xattr) { jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t)); memset(jcr->xattr_data, 0, sizeof(xattr_data_t)); jcr->xattr_data->u.build = (xattr_build_data_t *)malloc(sizeof(xattr_build_data_t)); memset(jcr->xattr_data->u.build, 0, sizeof(xattr_build_data_t)); jcr->xattr_data->u.build->content = get_pool_memory(PM_MESSAGE); } /** Subroutine save_file() is called for each file */ if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) { ok = false; /* error */ jcr->setJobStatus(JS_ErrorTerminated); } if (have_acl && jcr->acl_data->u.build->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing backup\n"), jcr->acl_data->u.build->nr_errors); } if (have_xattr && jcr->xattr_data->u.build->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing backup\n"), jcr->xattr_data->u.build->nr_errors); } close_vss_backup_session(jcr); accurate_finish(jcr); /* send deleted or base file list to SD */ stop_heartbeat_monitor(jcr); sd->signal(BNET_EOD); /* end of sending data */ if (have_acl && jcr->acl_data) { free_pool_memory(jcr->acl_data->u.build->content); free(jcr->acl_data->u.build); free(jcr->acl_data); jcr->acl_data = NULL; } if (have_xattr && jcr->xattr_data) { free_pool_memory(jcr->xattr_data->u.build->content); free(jcr->xattr_data->u.build); free(jcr->xattr_data); jcr->xattr_data = NULL; } if (jcr->big_buf) { free(jcr->big_buf); jcr->big_buf = NULL; } cleanup_compression(jcr); crypto_session_end(jcr); Dmsg1(100, "end blast_data ok=%d\n", ok); return ok; } /** * Save OSX specific resource forks and finder info. */ static inline bool save_rsrc_and_finder(b_save_ctx &bsctx) { char flags[FOPTS_BYTES]; int rsrc_stream; BSOCK *sd = bsctx.jcr->store_bsock; bool retval = false; if (bsctx.ff_pkt->hfsinfo.rsrclength > 0) { if (bopen_rsrc(&bsctx.ff_pkt->bfd, bsctx.ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) { bsctx.ff_pkt->ff_errno = errno; berrno be; Jmsg(bsctx.jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"), bsctx.ff_pkt->fname, be.bstrerror()); bsctx.jcr->JobErrors++; if (is_bopen(&bsctx.ff_pkt->bfd)) { bclose(&bsctx.ff_pkt->bfd); } } else { int status; memcpy(flags, bsctx.ff_pkt->flags, sizeof(flags)); clear_bit(FO_COMPRESS, bsctx.ff_pkt->flags); clear_bit(FO_SPARSE, bsctx.ff_pkt->flags); clear_bit(FO_OFFSETS, bsctx.ff_pkt->flags); rsrc_stream = bit_is_set(FO_ENCRYPT, flags) ? STREAM_ENCRYPTED_MACOS_FORK_DATA : STREAM_MACOS_FORK_DATA; status = send_data(bsctx.jcr, rsrc_stream, bsctx.ff_pkt, bsctx.digest, bsctx.signing_digest); memcpy(bsctx.ff_pkt->flags, flags, sizeof(flags)); bclose(&bsctx.ff_pkt->bfd); if (!status) { goto bail_out; } } } Dmsg1(300, "Saving Finder Info for \"%s\"\n", bsctx.ff_pkt->fname); sd->fsend("%ld %d 0", bsctx.jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES); Dmsg1(300, "filed>stored:header %s", sd->msg); pm_memcpy(sd->msg, bsctx.ff_pkt->hfsinfo.fndrinfo, 32); sd->msglen = 32; if (bsctx.digest) { crypto_digest_update(bsctx.digest, (uint8_t *)sd->msg, sd->msglen); } if (bsctx.signing_digest) { crypto_digest_update(bsctx.signing_digest, (uint8_t *)sd->msg, sd->msglen); } sd->send(); sd->signal(BNET_EOD); retval = true; bail_out: return retval; } /** * Setup for digest handling. If this fails, the digest will be set to NULL * and not used. Note, the digest (file hash) can be any one of the four * algorithms below. * * The signing digest is a single algorithm depending on * whether or not we have SHA2. * ****FIXME**** the signing algorithm should really be * determined a different way!!!!!! What happens if * sha2 was available during backup but not restore? */ static inline bool setup_encryption_digests(b_save_ctx &bsctx) { bool retval = false; // TODO landonf: Allow the user to specify the digest algorithm #ifdef HAVE_SHA2 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256; #else crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1; #endif if (bit_is_set(FO_MD5, bsctx.ff_pkt->flags)) { bsctx.digest = crypto_digest_new(bsctx.jcr, CRYPTO_DIGEST_MD5); bsctx.digest_stream = STREAM_MD5_DIGEST; } else if (bit_is_set(FO_SHA1, bsctx.ff_pkt->flags)) { bsctx.digest = crypto_digest_new(bsctx.jcr, CRYPTO_DIGEST_SHA1); bsctx.digest_stream = STREAM_SHA1_DIGEST; } else if (bit_is_set(FO_SHA256, bsctx.ff_pkt->flags)) { bsctx.digest = crypto_digest_new(bsctx.jcr, CRYPTO_DIGEST_SHA256); bsctx.digest_stream = STREAM_SHA256_DIGEST; } else if (bit_is_set(FO_SHA512, bsctx.ff_pkt->flags)) { bsctx.digest = crypto_digest_new(bsctx.jcr, CRYPTO_DIGEST_SHA512); bsctx.digest_stream = STREAM_SHA512_DIGEST; } /* * Did digest initialization fail? */ if (bsctx.digest_stream != STREAM_NONE && bsctx.digest == NULL) { Jmsg(bsctx.jcr, M_WARNING, 0, _("%s digest initialization failed\n"), stream_to_ascii(bsctx.digest_stream)); } /** * Set up signature digest handling. If this fails, the signature digest * will be set to NULL and not used. */ /* TODO landonf: We should really only calculate the digest once, for * both verification and signing. */ if (bsctx.jcr->crypto.pki_sign) { bsctx.signing_digest = crypto_digest_new(bsctx.jcr, signing_algorithm); /* * Full-stop if a failure occurred initializing the signature digest */ if (bsctx.signing_digest == NULL) { Jmsg(bsctx.jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"), stream_to_ascii(signing_algorithm)); bsctx.jcr->JobErrors++; goto bail_out; } } /* * Enable encryption */ if (bsctx.jcr->crypto.pki_encrypt) { set_bit(FO_ENCRYPT, bsctx.ff_pkt->flags); } retval = true; bail_out: return retval; } /* * Terminate the signing digest and send it to the Storage daemon */ static inline bool terminate_signing_digest(b_save_ctx &bsctx) { uint32_t size = 0; bool retval = false; SIGNATURE *signature = NULL; BSOCK *sd = bsctx.jcr->store_bsock; if ((signature = crypto_sign_new(bsctx.jcr)) == NULL) { Jmsg(bsctx.jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n")); goto bail_out; } if (!crypto_sign_add_signer(signature, bsctx.signing_digest, bsctx.jcr->crypto.pki_keypair)) { Jmsg(bsctx.jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n")); goto bail_out; } /* * Get signature size */ if (!crypto_sign_encode(signature, NULL, &size)) { Jmsg(bsctx.jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n")); goto bail_out; } /* * Grow the bsock buffer to fit our message if necessary */ if (sizeof_pool_memory(sd->msg) < (int32_t)size) { sd->msg = realloc_pool_memory(sd->msg, size); } /* * Send our header */ sd->fsend("%ld %ld 0", bsctx.jcr->JobFiles, STREAM_SIGNED_DIGEST); Dmsg1(300, "filed>stored:header %s", sd->msg); /* * Encode signature data */ if (!crypto_sign_encode(signature, (uint8_t *)sd->msg, &size)) { Jmsg(bsctx.jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n")); goto bail_out; } sd->msglen = size; sd->send(); sd->signal(BNET_EOD); /* end of checksum */ retval = true; bail_out: if (signature) { crypto_sign_free(signature); } return retval; } /* * Terminate any digest and send it to Storage daemon */ static inline bool terminate_digest(b_save_ctx &bsctx) { uint32_t size; bool retval = false; BSOCK *sd = bsctx.jcr->store_bsock; sd->fsend("%ld %d 0", bsctx.jcr->JobFiles, bsctx.digest_stream); Dmsg1(300, "filed>stored:header %s", sd->msg); size = CRYPTO_DIGEST_MAX_SIZE; /* * Grow the bsock buffer to fit our message if necessary */ if (sizeof_pool_memory(sd->msg) < (int32_t)size) { sd->msg = realloc_pool_memory(sd->msg, size); } if (!crypto_digest_finalize(bsctx.digest, (uint8_t *)sd->msg, &size)) { Jmsg(bsctx.jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n")); goto bail_out; } /* * Keep the checksum if this file is a hardlink */ if (bsctx.ff_pkt->linked) { ff_pkt_set_link_digest(bsctx.ff_pkt, bsctx.digest_stream, sd->msg, size); } sd->msglen = size; sd->send(); sd->signal(BNET_EOD); /* end of checksum */ retval = true; bail_out: return retval; } static inline bool do_backup_acl(JCR *jcr, FF_PKT *ff_pkt) { bacl_exit_code retval; jcr->acl_data->filetype = ff_pkt->type; jcr->acl_data->last_fname = jcr->last_fname; if (jcr->is_plugin()) { retval = plugin_build_acl_streams(jcr, jcr->acl_data, ff_pkt); } else { retval = build_acl_streams(jcr, jcr->acl_data, ff_pkt); } switch (retval) { case bacl_exit_fatal: return false; case bacl_exit_error: /* * Non-fatal errors, count them and when the number is under * ACL_REPORT_ERR_MAX_PER_JOB print the error message set by the * lower level routine in jcr->errmsg. */ if (jcr->acl_data->u.build->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } jcr->acl_data->u.build->nr_errors++; break; case bacl_exit_ok: break; } return true; } static inline bool do_backup_xattr(JCR *jcr, FF_PKT *ff_pkt) { bxattr_exit_code retval; jcr->xattr_data->last_fname = jcr->last_fname; if (jcr->is_plugin()) { retval = plugin_build_xattr_streams(jcr, jcr->xattr_data, ff_pkt); } else { retval = build_xattr_streams(jcr, jcr->xattr_data, ff_pkt); } switch (retval) { case bxattr_exit_fatal: return false; case bxattr_exit_error: /* * Non-fatal errors, count them and when the number is under * XATTR_REPORT_ERR_MAX_PER_JOB print the error message set by the * lower level routine in jcr->errmsg. */ if (jcr->xattr_data->u.build->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } jcr->xattr_data->u.build->nr_errors++; break; case bxattr_exit_ok: break; } return true; } /** * Called here by find() for each file included. * This is a callback. The original is find_files() above. * * Send the file and its data to the Storage daemon. * * Returns: 1 if OK * 0 if error * -1 to ignore file/directory (not used here) */ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { bool do_read = false; bool plugin_started = false; bool do_plugin_set = false; int status, data_stream; int rtnstat = 0; b_save_ctx bsctx; bool has_file_data = false; struct save_pkt sp; /* use by option plugin */ BSOCK *sd = jcr->store_bsock; if (jcr->is_canceled() || jcr->is_incomplete()) { return 0; } jcr->num_files_examined++; /* bump total file count */ switch (ff_pkt->type) { case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_REGE: Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_REG: Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_LNK: Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_RESTORE_FIRST: Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname); break; case FT_PLUGIN_CONFIG: Dmsg1(100, "FT_PLUGIN_CONFIG saving: %s\n", ff_pkt->fname); break; case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ return 1; /* not used */ case FT_NORECURSE: Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"), ff_pkt->top_fname, ff_pkt->fname); ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_NOFSCHG: /* Suppress message for /dev filesystems */ if (!is_in_fileset(ff_pkt)) { Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"), ff_pkt->fname, ff_pkt->top_fname); } ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_INVALIDFS: Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"), ff_pkt->top_fname, ff_pkt->fname); ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_INVALIDDT: Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"), ff_pkt->fname); break; case FT_REPARSE: case FT_JUNCTION: case FT_DIREND: Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link); break; case FT_SPEC: Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname); if (S_ISSOCK(ff_pkt->statp.st_mode)) { Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname); return 1; } break; case FT_RAW: Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_FIFO: Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname); break; case FT_NOACCESS: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_NOFOLLOW: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_NOSTAT: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_DIRNOCHG: case FT_NOCHG: Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname); return 1; case FT_ISARCH: Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname); return 1; case FT_NOOPEN: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_DELETED: Dmsg1(130, "FT_DELETED: %s\n", ff_pkt->fname); break; default: Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname); jcr->JobErrors++; return 1; } Dmsg1(130, "filed: sending %s to stored\n", ff_pkt->fname); /* * Setup backup signing context. */ memset(&bsctx, 0, sizeof(b_save_ctx)); bsctx.digest_stream = STREAM_NONE; bsctx.jcr = jcr; bsctx.ff_pkt = ff_pkt; /* * Digests and encryption are only useful if there's file data */ if (has_file_data) { if (!setup_encryption_digests(bsctx)) { goto good_rtn; } } /* * Initialize the file descriptor we use for data and other streams. */ binit(&ff_pkt->bfd); if (bit_is_set(FO_PORTABLE, ff_pkt->flags)) { set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */ } /* * Option and cmd plugin are not compatible together */ if (ff_pkt->cmd_plugin) { do_plugin_set = true; } else if (ff_pkt->opt_plugin) { /* * Ask the option plugin what to do with this file */ switch (plugin_option_handle_file(jcr, ff_pkt, &sp)) { case bRC_OK: Dmsg2(10, "Option plugin %s will be used to backup %s\n", ff_pkt->plugin, ff_pkt->fname); jcr->opt_plugin = true; jcr->plugin_sp = &sp; plugin_update_ff_pkt(ff_pkt, &sp); do_plugin_set = true; break; case bRC_Skip: Dmsg2(10, "Option plugin %s decided to skip %s\n", ff_pkt->plugin, ff_pkt->fname); goto good_rtn; case bRC_Core: Dmsg2(10, "Option plugin %s decided to let bareos handle %s\n", ff_pkt->plugin, ff_pkt->fname); break; default: goto bail_out; } } if (do_plugin_set) { /* * Tell bfile that it needs to call plugin */ if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) { goto bail_out; } send_plugin_name(jcr, sd, true); /* signal start of plugin data */ plugin_started = true; } /* * Send attributes -- must be done after binit() */ if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) { goto bail_out; } /* * Meta data only for restore object */ if (IS_FT_OBJECT(ff_pkt->type)) { goto good_rtn; } /* * Meta data only for deleted files */ if (ff_pkt->type == FT_DELETED) { goto good_rtn; } /* * Set up the encryption context and send the session data to the SD */ if (has_file_data && jcr->crypto.pki_encrypt) { if (!crypto_session_send(jcr, sd)) { goto bail_out; } } /* * For a command plugin use the setting from the plugins savepkt no_read field * which is saved in the ff_pkt->no_read variable. do_read is the inverted * value of this variable as no_read == TRUE means do_read == FALSE */ if (ff_pkt->cmd_plugin) { do_read = !ff_pkt->no_read; } else { /* * Open any file with data that we intend to save, then save it. * * Note, if is_win32_backup, we must open the Directory so that * the BackupRead will save its permissions and ownership streams. */ if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) { #ifdef HAVE_WIN32 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0; #else do_read = ff_pkt->statp.st_size > 0; #endif } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO || ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION || (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { do_read = true; } } Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read); if (do_read) { btimer_t *tid; int noatime; if (ff_pkt->type == FT_FIFO) { tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } noatime = bit_is_set(FO_NOATIME, ff_pkt->flags) ? O_NOATIME : 0; ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION); if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0, ff_pkt->statp.st_rdev) < 0) { ff_pkt->ff_errno = errno; berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; if (tid) { stop_thread_timer(tid); tid = NULL; } goto good_rtn; } if (tid) { stop_thread_timer(tid); tid = NULL; } status = send_data(jcr, data_stream, ff_pkt, bsctx.digest, bsctx.signing_digest); if (bit_is_set(FO_CHKCHANGES, ff_pkt->flags)) { has_file_changed(jcr, ff_pkt); } bclose(&ff_pkt->bfd); if (!status) { goto bail_out; } } if (have_darwin_os) { /* * Regular files can have resource forks and Finder Info */ if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && bit_is_set(FO_HFSPLUS, ff_pkt->flags))) { if (!save_rsrc_and_finder(bsctx)) { goto bail_out; } } } /* * Save ACLs when requested and available for anything not being a symlink. */ if (have_acl) { if (bit_is_set(FO_ACL, ff_pkt->flags) && ff_pkt->type != FT_LNK) { if (!do_backup_acl(jcr, ff_pkt)) { goto bail_out; } } } /* * Save Extended Attributes when requested and available for all files. */ if (have_xattr) { if (bit_is_set(FO_XATTR, ff_pkt->flags)) { if (!do_backup_xattr(jcr, ff_pkt)) { goto bail_out; } } } /* * Terminate the signing digest and send it to the Storage daemon */ if (bsctx.signing_digest) { if (!terminate_signing_digest(bsctx)) { goto bail_out; } } /* * Terminate any digest and send it to Storage daemon */ if (bsctx.digest) { if (!terminate_digest(bsctx)) { goto bail_out; } } /* * Check if original file has a digest, and send it */ if (ff_pkt->type == FT_LNKSAVED && ff_pkt->digest) { Dmsg2(300, "Link %s digest %d\n", ff_pkt->fname, ff_pkt->digest_len); sd->fsend("%ld %d 0", jcr->JobFiles, ff_pkt->digest_stream); sd->msg = check_pool_memory_size(sd->msg, ff_pkt->digest_len); memcpy(sd->msg, ff_pkt->digest, ff_pkt->digest_len); sd->msglen = ff_pkt->digest_len; sd->send(); sd->signal(BNET_EOD); /* end of hardlink record */ } good_rtn: rtnstat = jcr->is_canceled() ? 0 : 1; /* good return if not canceled */ bail_out: if (jcr->is_incomplete() || jcr->is_canceled()) { rtnstat = 0; } if (plugin_started) { send_plugin_name(jcr, sd, false); /* signal end of plugin data */ } if (ff_pkt->opt_plugin) { jcr->plugin_sp = NULL; /* sp is local to this function */ jcr->opt_plugin = false; } if (bsctx.digest) { crypto_digest_free(bsctx.digest); } if (bsctx.signing_digest) { crypto_digest_free(bsctx.signing_digest); } return rtnstat; } /* * Handle the data just read and send it to the SD after doing any postprocessing needed. */ static inline bool send_data_to_sd(b_ctx *bctx) { BSOCK *sd = bctx->jcr->store_bsock; bool need_more_data; /* * Check for sparse blocks */ if (bit_is_set(FO_SPARSE, bctx->ff_pkt->flags)) { bool allZeros; ser_declare; allZeros = false; if ((sd->msglen == bctx->rsize && (bctx->fileAddr + sd->msglen < (uint64_t)bctx->ff_pkt->statp.st_size)) || ((bctx->ff_pkt->type == FT_RAW || bctx->ff_pkt->type == FT_FIFO) && ((uint64_t)bctx->ff_pkt->statp.st_size == 0))) { allZeros = is_buf_zero(bctx->rbuf, bctx->rsize); } if (!allZeros) { /* * Put file address as first data in buffer */ ser_begin(bctx->wbuf, OFFSET_FADDR_SIZE); ser_uint64(bctx->fileAddr); /* store fileAddr in begin of buffer */ } bctx->fileAddr += sd->msglen; /* update file address */ /* * Skip block of all zeros */ if (allZeros) { return true; } } else if (bit_is_set(FO_OFFSETS, bctx->ff_pkt->flags)) { ser_declare; ser_begin(bctx->wbuf, OFFSET_FADDR_SIZE); ser_uint64(bctx->ff_pkt->bfd.offset); /* store offset in begin of buffer */ } bctx->jcr->ReadBytes += sd->msglen; /* count bytes read */ /* * Uncompressed cipher input length */ bctx->cipher_input_len = sd->msglen; /* * Update checksum if requested */ if (bctx->digest) { crypto_digest_update(bctx->digest, (uint8_t *)bctx->rbuf, sd->msglen); } /* * Update signing digest if requested */ if (bctx->signing_digest) { crypto_digest_update(bctx->signing_digest, (uint8_t *)bctx->rbuf, sd->msglen); } /* * Compress the data. */ if (bit_is_set(FO_COMPRESS, bctx->ff_pkt->flags)) { if (!compress_data(bctx->jcr, bctx->ff_pkt->Compress_algo, bctx->rbuf, bctx->jcr->store_bsock->msglen, bctx->cbuf, bctx->max_compress_len, &bctx->compress_len)) { return false; } /* * See if we need to generate a compression header. */ if (bctx->chead) { ser_declare; /* * Complete header */ ser_begin(bctx->chead, sizeof(comp_stream_header)); ser_uint32(bctx->ch.magic); ser_uint32(bctx->compress_len); ser_uint16(bctx->ch.level); ser_uint16(bctx->ch.version); ser_end(bctx->chead, sizeof(comp_stream_header)); bctx->compress_len += sizeof(comp_stream_header); /* add size of header */ } bctx->jcr->store_bsock->msglen = bctx->compress_len; /* set compressed length */ bctx->cipher_input_len = bctx->compress_len; } /* * Encrypt the data. */ need_more_data = false; if (bit_is_set(FO_ENCRYPT, bctx->ff_pkt->flags) && !encrypt_data(bctx, &need_more_data)) { if (need_more_data) { return true; } return false; } /* * Send the buffer to the Storage daemon */ if (bit_is_set(FO_SPARSE, bctx->ff_pkt->flags) || bit_is_set(FO_OFFSETS, bctx->ff_pkt->flags)) { sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */ } sd->msg = bctx->wbuf; /* set correct write buffer */ if (!sd->send()) { if (!bctx->jcr->is_job_canceled()) { Jmsg1(bctx->jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } return false; } Dmsg1(130, "Send data to SD len=%d\n", sd->msglen); bctx->jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */ sd->msg = bctx->msgsave; /* restore read buffer */ return true; } #ifdef HAVE_WIN32 /* * Callback method for ReadEncryptedFileRaw() */ static DWORD WINAPI send_efs_data(PBYTE pbData, PVOID pvCallbackContext, ULONG ulLength) { b_ctx *bctx = (b_ctx *)pvCallbackContext; BSOCK *sd = bctx->jcr->store_bsock; if (ulLength == 0) { return ERROR_SUCCESS; } /* * See if we can fit the data into the current bctx->rbuf which can hold bctx->rsize bytes. */ if (ulLength <= (ULONG)bctx->rsize) { sd->msglen = ulLength; memcpy(bctx->rbuf, pbData, ulLength); if (!send_data_to_sd(bctx)) { return ERROR_NET_WRITE_FAULT; } } else { /* * Need to chunk the data into pieces. */ ULONG offset = 0; while (ulLength > 0) { sd->msglen = MIN((ULONG)bctx->rsize, ulLength); memcpy(bctx->rbuf, pbData + offset, sd->msglen); if (!send_data_to_sd(bctx)) { return ERROR_NET_WRITE_FAULT; } offset += sd->msglen; ulLength -= sd->msglen; } } return ERROR_SUCCESS; } /* * Send the content of an Encrypted file on an EFS filesystem. */ static inline bool send_encrypted_data(b_ctx &bctx) { bool retval = false; if (!p_ReadEncryptedFileRaw) { Jmsg0(bctx.jcr, M_FATAL, 0, _("Encrypted file but no EFS support functions\n")); } /* * The EFS read function, ReadEncryptedFileRaw(), works in a specific way. * You have to give it a function that it calls repeatedly every time the * read buffer is filled. * * So ReadEncryptedFileRaw() will not return until it has read the whole file. */ if (p_ReadEncryptedFileRaw((PFE_EXPORT_FUNC)send_efs_data, &bctx, bctx.ff_pkt->bfd.pvContext)) { goto bail_out; } retval = true; bail_out: return retval; } #endif /* * Send the content of a file on anything but an EFS filesystem. */ static inline bool send_plain_data(b_ctx &bctx) { bool retval = false; BSOCK *sd = bctx.jcr->store_bsock; /* * Read the file data */ while ((sd->msglen = (uint32_t)bread(&bctx.ff_pkt->bfd, bctx.rbuf, bctx.rsize)) > 0) { if (!send_data_to_sd(&bctx)) { goto bail_out; } } retval = true; bail_out: return retval; } /** * Send data read from an already open file descriptor. * * We return 1 on sucess and 0 on errors. * * ***FIXME*** * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop reading. * Currently this is not a problem as the only other stream, resource forks, * are not handled as sparse files. */ static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signing_digest) { b_ctx bctx; BSOCK *sd = jcr->store_bsock; #ifdef FD_NO_SEND_TEST return 1; #endif /* * Setup backup context. */ memset(&bctx, 0, sizeof(b_ctx)); bctx.jcr = jcr; bctx.ff_pkt = ff_pkt; bctx.msgsave = sd->msg; /* save the original sd buffer */ bctx.rbuf = sd->msg; /* read buffer */ bctx.wbuf = sd->msg; /* write buffer */ bctx.rsize = jcr->buf_size; /* read buffer size */ bctx.cipher_input = (uint8_t *)bctx.rbuf; /* encrypt uncompressed data */ bctx.digest = digest; /* encryption digest */ bctx.signing_digest = signing_digest; /* signing digest */ Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type); if (!setup_compression_context(bctx)) { goto bail_out; } if (!setup_encryption_context(bctx)) { goto bail_out; } /* * Send Data header to Storage daemon * */ if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) { if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } goto bail_out; } Dmsg1(300, ">stored: datahdr %s", sd->msg); /* * Make space at beginning of buffer for fileAddr because this * same buffer will be used for writing if compression is off. */ if (bit_is_set(FO_SPARSE, ff_pkt->flags) || bit_is_set(FO_OFFSETS, ff_pkt->flags)) { bctx.rbuf += OFFSET_FADDR_SIZE; bctx.rsize -= OFFSET_FADDR_SIZE; #ifdef HAVE_FREEBSD_OS /* * To read FreeBSD partitions, the read size must be a multiple of 512. */ bctx.rsize = (bctx.rsize / 512) * 512; #endif } /* * A RAW device read on win32 only works if the buffer is a multiple of 512 */ #ifdef HAVE_WIN32 if (S_ISBLK(ff_pkt->statp.st_mode)) { bctx.rsize = (bctx.rsize / 512) * 512; } if (ff_pkt->statp.st_rdev & FILE_ATTRIBUTE_ENCRYPTED) { if (!send_encrypted_data(bctx)) { goto bail_out; } } else { if (!send_plain_data(bctx)) { goto bail_out; } } #else if (!send_plain_data(bctx)) { goto bail_out; } #endif if (sd->msglen < 0) { /* error */ berrno be; Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno)); if (jcr->JobErrors++ > 1000) { /* insanity check */ Jmsg(jcr, M_FATAL, 0, _("Too many errors. JobErrors=%d.\n"), jcr->JobErrors); } } else if (bit_is_set(FO_ENCRYPT, ff_pkt->flags)) { /* * For encryption, we must call finalize to push out any buffered data. */ if (!crypto_cipher_finalize(bctx.cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf, &bctx.encrypted_len)) { /* * Padding failed. Shouldn't happen. */ Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n")); goto bail_out; } /* * Note, on SSL pre-0.9.7, there is always some output */ if (bctx.encrypted_len > 0) { sd->msglen = bctx.encrypted_len; /* set encrypted length */ sd->msg = jcr->crypto.crypto_buf; /* set correct write buffer */ if (!sd->send()) { if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } goto bail_out; } Dmsg1(130, "Send data to SD len=%d\n", sd->msglen); jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */ sd->msg = bctx.msgsave; /* restore bnet buffer */ } } if (!sd->signal(BNET_EOD)) { /* indicate end of file data */ if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } goto bail_out; } /* * Free the cipher context */ if (bctx.cipher_ctx) { crypto_cipher_free(bctx.cipher_ctx); } return 1; bail_out: /* * Free the cipher context */ if (bctx.cipher_ctx) { crypto_cipher_free(bctx.cipher_ctx); } sd->msg = bctx.msgsave; /* restore bnet buffer */ sd->msglen = 0; return 0; } bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) { BSOCK *sd = jcr->store_bsock; POOL_MEM attribs(PM_NAME), attribsExBuf(PM_NAME); char *attribsEx = NULL; int attr_stream; int comp_len; bool status; int hangup = get_hangup(); #ifdef FD_NO_SEND_TEST return true; #endif Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname); /** Find what data stream we will use, then encode the attributes */ if ((data_stream = select_data_stream(ff_pkt, me->compatible)) == STREAM_NONE) { /* This should not happen */ Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n")); return false; } encode_stat(attribs.c_str(), &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, data_stream); /** Now possibly extend the attributes */ if (IS_FT_OBJECT(ff_pkt->type)) { attr_stream = STREAM_RESTORE_OBJECT; } else { attribsEx = attribsExBuf.c_str(); attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt); } Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs.c_str(), attribsEx); jcr->lock(); jcr->JobFiles++; /* increment number of files sent */ ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */ pm_strcpy(jcr->last_fname, ff_pkt->fname); jcr->unlock(); /* * Debug code: check if we must hangup */ if (hangup && (jcr->JobFiles > (uint32_t)hangup)) { jcr->setJobStatus(JS_Incomplete); Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup); set_hangup(0); return false; } /** * Send Attributes header to Storage daemon * */ if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) { if (!jcr->is_canceled() && !jcr->is_incomplete()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } return false; } Dmsg1(300, ">stored: attrhdr %s", sd->msg); /** * Send file attributes to Storage daemon * File_index * File type * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK or FT_LNKSAVED) * Encoded extended-attributes (for Win32) * Delta Sequence Number * * or send Restore Object to Storage daemon * File_index * File_type * Object_index * Object_len (possibly compressed) * Object_full_len (not compressed) * Object_compression * Plugin_name * Object_name * Binary Object data * * For a directory, link is the same as fname, but with trailing * slash. For a linked file, link is the link. */ if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) { /* already stripped */ strip_path(ff_pkt); } switch (ff_pkt->type) { case FT_JUNCTION: case FT_LNK: case FT_LNKSAVED: Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link); status = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles, ff_pkt->type, ff_pkt->fname, 0, attribs.c_str(), 0, ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0); break; case FT_DIREND: case FT_REPARSE: /* Here link is the canonical filename (i.e. with trailing slash) */ status = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles, ff_pkt->type, ff_pkt->link, 0, attribs.c_str(), 0, 0, attribsEx, 0, ff_pkt->delta_seq, 0); break; case FT_PLUGIN_CONFIG: case FT_RESTORE_FIRST: comp_len = ff_pkt->object_len; ff_pkt->object_compression = 0; if (ff_pkt->object_len > 1000) { /* * Big object, compress it */ comp_len = compressBound(ff_pkt->object_len); POOLMEM *comp_obj = get_memory(comp_len); /* * FIXME: check Zdeflate error */ Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len); if (comp_len < ff_pkt->object_len) { ff_pkt->object = comp_obj; ff_pkt->object_compression = 1; /* zlib level 9 compression */ } else { /* * Uncompressed object smaller, use it */ comp_len = ff_pkt->object_len; } Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len); } sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->object_index, comp_len, ff_pkt->object_len, ff_pkt->object_compression, ff_pkt->fname, 0, ff_pkt->object_name, 0); sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2); memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len); /* * Note we send one extra byte so Dir can store zero after object */ sd->msglen += comp_len + 1; status = sd->send(); if (ff_pkt->object_compression) { free_and_null_pool_memory(ff_pkt->object); } break; case FT_REG: status = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles, ff_pkt->type, ff_pkt->fname, 0, attribs.c_str(), 0, 0, attribsEx, 0, ff_pkt->delta_seq, 0); break; default: status = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles, ff_pkt->type, ff_pkt->fname, 0, attribs.c_str(), 0, 0, attribsEx, 0, ff_pkt->delta_seq, 0); break; } if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) { unstrip_path(ff_pkt); } Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg); if (!status && !jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } sd->signal(BNET_EOD); /* indicate end of attributes data */ return status; } /** * Do in place strip of path */ static bool do_strip(int count, char *in) { char *out = in; int stripped; int numsep = 0; /** * Copy to first path separator -- Win32 might have c: ... */ while (*in && !IsPathSeparator(*in)) { out++; in++; } if (*in) { /* Not at the end of the string */ out++; in++; numsep++; /* one separator seen */ } for (stripped=0; strippedcount=%d\n", stripped, count, numsep, numsep>count); return stripped==count && numsep>count; } /** * If requested strip leading components of the path so that we can * save file as if it came from a subdirectory. This is most useful * for dealing with snapshots, by removing the snapshot directory, or * in handling vendor migrations where files have been restored with * a vendor product into a subdirectory. */ void strip_path(FF_PKT *ff_pkt) { if (!bit_is_set(FO_STRIPPATH, ff_pkt->flags) || ff_pkt->strip_path <= 0) { Dmsg1(200, "No strip for %s\n", ff_pkt->fname); return; } if (!ff_pkt->fname_save) { ff_pkt->fname_save = get_pool_memory(PM_FNAME); ff_pkt->link_save = get_pool_memory(PM_FNAME); } pm_strcpy(ff_pkt->fname_save, ff_pkt->fname); if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { pm_strcpy(ff_pkt->link_save, ff_pkt->link); Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save), strlen(ff_pkt->link)); Dsm_check(200); } /** * Strip path. If it doesn't succeed put it back. If it does, and there * is a different link string, attempt to strip the link. If it fails, * back them both back. Do not strip symlinks. I.e. if either stripping * fails don't strip anything. */ if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) { unstrip_path(ff_pkt); goto rtn; } /** * Strip links but not symlinks */ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) { unstrip_path(ff_pkt); } } rtn: Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname, ff_pkt->link); } void unstrip_path(FF_PKT *ff_pkt) { if (!bit_is_set(FO_STRIPPATH, ff_pkt->flags) || ff_pkt->strip_path <= 0) { return; } strcpy(ff_pkt->fname, ff_pkt->fname_save); if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) { Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link, ff_pkt->link_save); strcpy(ff_pkt->link, ff_pkt->link_save); Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link), strlen(ff_pkt->link_save)); Dsm_check(200); } } static void close_vss_backup_session(JCR *jcr) { #if defined(WIN32_VSS) /* * STOP VSS ON WIN32 * Tell vss to close the backup session */ if (jcr->VSS) { if (g_pVSSClient->CloseBackup()) { /* * Inform user about writer states */ for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) { int msg_type = M_INFO; if (g_pVSSClient->GetWriterState(i) < 1) { msg_type = M_WARNING; jcr->JobErrors++; } Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i)); } } /* * Generate Job global writer metadata */ WCHAR *metadata = g_pVSSClient->GetMetadata(); if (metadata) { FF_PKT *ff_pkt = jcr->ff; ff_pkt->fname = (char *)"*all*"; /* for all plugins */ ff_pkt->type = FT_RESTORE_FIRST; ff_pkt->LinkFI = 0; ff_pkt->object_name = (char *)"job_metadata.xml"; ff_pkt->object = (char *)metadata; ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR); ff_pkt->object_index = (int)time(NULL); save_file(jcr, ff_pkt, true); } } #endif } bareos-Release-14.2.6/src/filed/backup.h000066400000000000000000000047541263011562700177420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BACKUP_H #define __BACKUP_H struct b_save_ctx { JCR *jcr; /* Current Job Control Record */ FF_PKT *ff_pkt; /* File being processed */ DIGEST *digest; /* Encryption Digest */ DIGEST *signing_digest; /* Signing Digest */ int digest_stream; /* Type of Signing Digest */ }; struct b_ctx { JCR *jcr; /* Current Job Control Record */ FF_PKT *ff_pkt; /* File being processed */ POOLMEM *msgsave; /* Saved sd->msg */ char *rbuf; /* Read buffer */ char *wbuf; /* Write buffer */ int32_t rsize; /* Read size */ uint64_t fileAddr; /* File address */ /* * Compression data. */ const unsigned char *chead; /* Compression header */ unsigned char *cbuf; /* Compression buffer when using generic comp_stream_header */ uint32_t compress_len; /* Actual length after compression */ uint32_t max_compress_len; /* Maximum size that will fit into compression buffer */ comp_stream_header ch; /* Compression Stream Header with info about compression used */ /* * Encryption data. */ uint32_t cipher_input_len; /* Actual length of the data to encrypt */ const uint8_t *cipher_input; /* Data to encrypt */ uint32_t encrypted_len; /* Actual length after encryption */ DIGEST *digest; /* Encryption Digest */ DIGEST *signing_digest; /* Signing Digest */ CIPHER_CONTEXT *cipher_ctx; /* Cipher context */ }; #endif bareos-Release-14.2.6/src/filed/bareos-fd.conf.in000066400000000000000000000023451263011562700214340ustar00rootroot00000000000000# # Default Bareos File Daemon Configuration file # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ @DISTVER@ # # There is not much to change here except perhaps the # File daemon Name to # # # List Directors who are permitted to contact this File daemon # Director { Name = @basename@-dir Password = "@fd_password@" } # # Restricted Director, used by tray-monitor to get the # status of the file daemon # Director { Name = @basename@-mon Password = "@mon_fd_password@" Monitor = yes } # # "Global" File daemon configuration specifications # FileDaemon { # this is me Name = @basename@-fd Maximum Concurrent Jobs = 20 # remove comment from "Plugin Directory" to load plugins from specified directory. # if "Plugin Names" is defined, only the specified plugins will be loaded, # otherwise all storage plugins (*-fd.so) from the "Plugin Directory". # # Plugin Directory = @plugindir@ # Plugin Names = "" # if compatible is set to yes, we are compatible with bacula # if you want to use new bareos features, please set # compatible = no } # Send all messages except skipped files back to Director Messages { Name = Standard director = @basename@-dir = all, !skipped, !restored } bareos-Release-14.2.6/src/filed/compression.c000066400000000000000000000165171263011562700210310ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Functions to handle compression/decompression of data. * * Kern Sibbald, March MM * * Extracted from other source files by Marco van Wieringen, June 2011 */ #include "bareos.h" #include "filed.h" #if defined(HAVE_LZO) || defined(HAVE_LIBZ) || defined(HAVE_FASTLZ) #if defined(HAVE_LIBZ) #include #endif #if defined(HAVE_FASTLZ) #include #endif /* * For compression we enable all used compressors in the fileset. */ bool adjust_compression_buffers(JCR *jcr) { findFILESET *fileset = jcr->ff->fileset; uint32_t compress_buf_size = 0; if (fileset) { int i, j; for (i = 0; i < fileset->include_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); for (j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); if (!setup_compression_buffers(jcr, me->compatible, fo->Compress_algo, &compress_buf_size)) { return false; } } } if (compress_buf_size > 0) { jcr->compress.deflate_buffer = get_memory(compress_buf_size); jcr->compress.deflate_buffer_size = compress_buf_size; } } return true; } /* * For decompression we use the same decompression buffer for each algorithm. */ bool adjust_decompression_buffers(JCR *jcr) { uint32_t decompress_buf_size; setup_decompression_buffers(jcr, &decompress_buf_size); if (decompress_buf_size > 0) { jcr->compress.inflate_buffer = get_memory(decompress_buf_size); jcr->compress.inflate_buffer_size = decompress_buf_size; } return true; } bool setup_compression_context(b_ctx &bctx) { bool retval = false; if (bit_is_set(FO_COMPRESS, bctx.ff_pkt->flags)) { /* * See if we need to be compatible with the old GZIP stream encoding. */ if (!me->compatible || bctx.ff_pkt->Compress_algo != COMPRESS_GZIP) { memset(&bctx.ch, 0, sizeof(comp_stream_header)); /* * Calculate buffer offsets. */ if (bit_is_set(FO_SPARSE, bctx.ff_pkt->flags) || bit_is_set(FO_OFFSETS, bctx.ff_pkt->flags)) { bctx.chead = (uint8_t *)bctx.jcr->compress.deflate_buffer + OFFSET_FADDR_SIZE; bctx.cbuf = (uint8_t *)bctx.jcr->compress.deflate_buffer + OFFSET_FADDR_SIZE + sizeof(comp_stream_header); bctx.max_compress_len = bctx.jcr->compress.deflate_buffer_size - (sizeof(comp_stream_header) + OFFSET_FADDR_SIZE); } else { bctx.chead = (uint8_t *)bctx.jcr->compress.deflate_buffer; bctx.cbuf = (uint8_t *)bctx.jcr->compress.deflate_buffer + sizeof(comp_stream_header); bctx.max_compress_len = bctx.jcr->compress.deflate_buffer_size - sizeof(comp_stream_header); } bctx.wbuf = bctx.jcr->compress.deflate_buffer; /* compressed output here */ bctx.cipher_input = (uint8_t *)bctx.jcr->compress.deflate_buffer; /* encrypt compressed data */ bctx.ch.magic = bctx.ff_pkt->Compress_algo; bctx.ch.version = COMP_HEAD_VERSION; } else { /* * Calculate buffer offsets. */ bctx.chead = NULL; if (bit_is_set(FO_SPARSE, bctx.ff_pkt->flags) || bit_is_set(FO_OFFSETS, bctx.ff_pkt->flags)) { bctx.cbuf = (uint8_t *)bctx.jcr->compress.deflate_buffer + OFFSET_FADDR_SIZE; bctx.max_compress_len = bctx.jcr->compress.deflate_buffer_size - OFFSET_FADDR_SIZE; } else { bctx.cbuf = (uint8_t *)bctx.jcr->compress.deflate_buffer; bctx.max_compress_len = bctx.jcr->compress.deflate_buffer_size; } bctx.wbuf = bctx.jcr->compress.deflate_buffer; /* compressed output here */ bctx.cipher_input = (uint8_t *)bctx.jcr->compress.deflate_buffer; /* encrypt compressed data */ } /* * Do compression specific actions and set the magic, header version and compression level. */ switch (bctx.ff_pkt->Compress_algo) { #if defined(HAVE_LIBZ) case COMPRESS_GZIP: { z_stream *pZlibStream; /** * Only change zlib parameters if there is no pending operation. * This should never happen as deflateReset is called after each * deflate. */ pZlibStream = (z_stream *)bctx.jcr->compress.workset.pZLIB; if (pZlibStream->total_in == 0) { int zstat; /* * Set gzip compression level - must be done per file */ if ((zstat = deflateParams(pZlibStream, bctx.ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) { Jmsg(bctx.jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat); bctx.jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } } bctx.ch.level = bctx.ff_pkt->Compress_level; break; } #endif #if defined(HAVE_LZO) case COMPRESS_LZO1X: break; #endif #if defined(HAVE_FASTLZ) case COMPRESS_FZFZ: case COMPRESS_FZ4L: case COMPRESS_FZ4H: { int zstat; zfast_stream *pZfastStream; zfast_stream_compressor compressor = COMPRESSOR_FASTLZ; /** * Only change fastlz parameters if there is no pending operation. * This should never happen as fastlzlibCompressReset is called after each * fastlzlibCompress. */ pZfastStream = (zfast_stream *)bctx.jcr->compress.workset.pZFAST; if (pZfastStream->total_in == 0) { switch (bctx.ff_pkt->Compress_algo) { case COMPRESS_FZ4L: case COMPRESS_FZ4H: compressor = COMPRESSOR_LZ4; break; } if ((zstat = fastlzlibSetCompressor(pZfastStream, compressor)) != Z_OK) { Jmsg(bctx.jcr, M_FATAL, 0, _("Compression fastlzlibSetCompressor error: %d\n"), zstat); bctx.jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } } bctx.ch.level = bctx.ff_pkt->Compress_level; break; } #endif default: break; } } retval = true; bail_out: return retval; } #else bool adjust_compression_buffers(JCR *jcr) { return true; } bool setup_compression_context(b_ctx &bctx) { return true; } #endif /* defined(HAVE_LZO) || defined(HAVE_LIBZ) || defined(HAVE_FASTLZ) */ bareos-Release-14.2.6/src/filed/crypto.c000066400000000000000000000460771263011562700200140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Functions to handle cryptology * * Kern Sibbald, March MM * * Extracted from other source files by Marco van Wieringen, June 2011 */ #include "bareos.h" #include "filed.h" #ifdef HAVE_SHA2 const bool have_sha2 = true; #else const bool have_sha2 = false; #endif static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx) { unser_declare; if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) { unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE); unser_uint32(ctx->packet_len); ctx->packet_len += CRYPTO_LEN_SIZE; } } bool crypto_session_start(JCR *jcr) { crypto_cipher_t cipher; /* * See if we are in compatible mode then we are hardcoded to CRYPTO_CIPHER_AES_128_CBC. */ if (me->compatible) { cipher = CRYPTO_CIPHER_AES_128_CBC; } else { cipher = me->pki_cipher; } /** * Create encryption session data and a cached, DER-encoded session data * structure. We use a single session key for each backup, so we'll encode * the session data only once. */ if (jcr->crypto.pki_encrypt) { uint32_t size = 0; /** Create per-job session encryption context */ jcr->crypto.pki_session = crypto_session_new(cipher, jcr->crypto.pki_recipients); if (!jcr->crypto.pki_session) { Jmsg(jcr, M_FATAL, 0, _("Cannot create a new crypto session probably unsupported cipher configured.\n")); return false; } /** Get the session data size */ if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)0, &size)) { Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n")); return false; } /** Allocate buffer */ jcr->crypto.pki_session_encoded = get_memory(size); /** Encode session data */ if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)jcr->crypto.pki_session_encoded, &size)) { Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n")); return false; } /** ... and store the encoded size */ jcr->crypto.pki_session_encoded_size = size; /** Allocate the encryption/decryption buffer */ jcr->crypto.crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE); } return true; } void crypto_session_end(JCR *jcr) { if (jcr->crypto.crypto_buf) { free_pool_memory(jcr->crypto.crypto_buf); jcr->crypto.crypto_buf = NULL; } if (jcr->crypto.pki_session) { crypto_session_free(jcr->crypto.pki_session); } if (jcr->crypto.pki_session_encoded) { free_pool_memory(jcr->crypto.pki_session_encoded); jcr->crypto.pki_session_encoded = NULL; } } bool crypto_session_send(JCR *jcr, BSOCK *sd) { POOLMEM *msgsave; /** Send our header */ Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA); sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA); msgsave = sd->msg; sd->msg = jcr->crypto.pki_session_encoded; sd->msglen = jcr->crypto.pki_session_encoded_size; jcr->JobBytes += sd->msglen; Dmsg1(100, "Send data len=%d\n", sd->msglen); sd->send(); sd->msg = msgsave; sd->signal(BNET_EOD); return true; } /* * Verify the signature for the last restored file * Return value is either true (signature correct) * or false (signature could not be verified). * TODO landonf: Implement without using find_one_file and * without re-reading the file. */ bool verify_signature(JCR *jcr, r_ctx &rctx) { X509_KEYPAIR *keypair; DIGEST *digest = NULL; crypto_error_t err; uint64_t saved_bytes; crypto_digest_t signing_algorithm = have_sha2 ? CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1; crypto_digest_t algorithm; SIGNATURE *sig = rctx.sig; if (!jcr->crypto.pki_sign) { /* * no signature OK */ return true; } if (!sig) { if (rctx.type == FT_REGE || rctx.type == FT_REG || rctx.type == FT_RAW) { Jmsg1(jcr, M_ERROR, 0, _("Missing cryptographic signature for %s\n"), jcr->last_fname); goto bail_out; } return true; } /* * Iterate through the trusted signers */ foreach_alist(keypair, jcr->crypto.pki_signers) { err = crypto_sign_get_digest(sig, jcr->crypto.pki_keypair, algorithm, &digest); switch (err) { case CRYPTO_ERROR_NONE: Dmsg0(50, "== Got digest\n"); /* * We computed jcr->crypto.digest using signing_algorithm while writing * the file. If it is not the same as the algorithm used for * this file, punt by releasing the computed algorithm and * computing by re-reading the file. */ if (algorithm != signing_algorithm) { if (jcr->crypto.digest) { crypto_digest_free(jcr->crypto.digest); jcr->crypto.digest = NULL; } } if (jcr->crypto.digest) { /* * Use digest computed while writing the file to verify the signature */ if ((err = crypto_sign_verify(sig, keypair, jcr->crypto.digest)) != CRYPTO_ERROR_NONE) { Dmsg1(50, "Bad signature on %s\n", jcr->last_fname); Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), jcr->last_fname, crypto_strerror(err)); goto bail_out; } } else { /* * Signature found, digest allocated. Old method, * re-read the file and compute the digest */ jcr->crypto.digest = digest; /* * Checksum the entire file * Make sure we don't modify JobBytes by saving and restoring it */ saved_bytes = jcr->JobBytes; if (find_one_file(jcr, jcr->ff, do_file_digest, jcr->last_fname, (dev_t)-1, 1) != 0) { Jmsg(jcr, M_ERROR, 0, _("Digest one file failed for file: %s\n"), jcr->last_fname); jcr->JobBytes = saved_bytes; goto bail_out; } jcr->JobBytes = saved_bytes; /* * Verify the signature */ if ((err = crypto_sign_verify(sig, keypair, digest)) != CRYPTO_ERROR_NONE) { Dmsg1(50, "Bad signature on %s\n", jcr->last_fname); Jmsg2(jcr, M_ERROR, 0, _("Signature validation failed for file %s: ERR=%s\n"), jcr->last_fname, crypto_strerror(err)); goto bail_out; } jcr->crypto.digest = NULL; } /* * Valid signature */ Dmsg1(50, "Signature good on %s\n", jcr->last_fname); crypto_digest_free(digest); return true; case CRYPTO_ERROR_NOSIGNER: /* * Signature not found, try again */ if (digest) { crypto_digest_free(digest); digest = NULL; } continue; default: /* * Something strange happened (that shouldn't happen!)... */ Qmsg2(jcr, M_ERROR, 0, _("Signature validation failed for %s: %s\n"), jcr->last_fname, crypto_strerror(err)); goto bail_out; } } /* * No signer */ Dmsg1(50, "Could not find a valid public key for signature on %s\n", jcr->last_fname); bail_out: if (digest) { crypto_digest_free(digest); } return false; } /* * In the context of jcr, flush any remaining data from the cipher context, * writing it to bfd. * Return value is true on success, false on failure. */ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, char *flags, int32_t stream, RESTORE_CIPHER_CTX *cipher_ctx) { uint32_t decrypted_len = 0; char *wbuf; /* write buffer */ uint32_t wsize; /* write size */ char ec1[50]; /* Buffer printing huge values */ bool second_pass = false; again: /* * Write out the remaining block and free the cipher context */ cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len + cipher_ctx->block_size); if (!crypto_cipher_finalize(cipher_ctx->cipher, (uint8_t *)&cipher_ctx->buf[cipher_ctx->buf_len], &decrypted_len)) { /* * Writing out the final, buffered block failed. Shouldn't happen. */ Jmsg3(jcr, M_ERROR, 0, _("Decryption error. buf_len=%d decrypt_len=%d on file %s\n"), cipher_ctx->buf_len, decrypted_len, jcr->last_fname); } Dmsg2(130, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len); /* * If nothing new was decrypted, and our output buffer is empty, return */ if (decrypted_len == 0 && cipher_ctx->buf_len == 0) { return true; } cipher_ctx->buf_len += decrypted_len; unser_crypto_packet_len(cipher_ctx); Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE); wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE; /* * Decrypted, possibly decompressed output here. */ wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; cipher_ctx->buf_len -= cipher_ctx->packet_len; Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len); if (bit_is_set(FO_SPARSE, flags) || bit_is_set(FO_OFFSETS, flags)) { if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) { return false; } } if (bit_is_set(FO_COMPRESS, flags)) { if (!decompress_data(jcr, jcr->last_fname, stream, &wbuf, &wsize, false)) { return false; } } Dmsg0(130, "Call store_data\n"); if (!store_data(jcr, bfd, wbuf, wsize, bit_is_set(FO_WIN32DECOMP, flags))) { return false; } jcr->JobBytes += wsize; Dmsg2(130, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); /* * Move any remaining data to start of buffer */ if (cipher_ctx->buf_len > 0) { Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len); memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], cipher_ctx->buf_len); } /* * The packet was successfully written, reset the length so that the next * packet length may be re-read by unser_crypto_packet_len() */ cipher_ctx->packet_len = 0; if (cipher_ctx->buf_len >0 && !second_pass) { second_pass = true; goto again; } /* * Stop decryption */ cipher_ctx->buf_len = 0; cipher_ctx->packet_len = 0; return true; } void deallocate_cipher(r_ctx &rctx) { /* * Flush and deallocate previous stream's cipher context */ if (rctx.cipher_ctx.cipher) { flush_cipher(rctx.jcr, &rctx.bfd, &rctx.fileAddr, rctx.flags, rctx.comp_stream, &rctx.cipher_ctx); crypto_cipher_free(rctx.cipher_ctx.cipher); rctx.cipher_ctx.cipher = NULL; } } void deallocate_fork_cipher(r_ctx &rctx) { /* * Flush and deallocate previous stream's fork cipher context */ if (rctx.fork_cipher_ctx.cipher) { flush_cipher(rctx.jcr, &rctx.forkbfd, &rctx.fork_addr, rctx.fork_flags, rctx.comp_stream, &rctx.fork_cipher_ctx); crypto_cipher_free(rctx.fork_cipher_ctx.cipher); rctx.fork_cipher_ctx.cipher = NULL; } } /* * Setup a encryption context */ bool setup_encryption_context(b_ctx &bctx) { uint32_t cipher_block_size; bool retval = false; if (bit_is_set(FO_ENCRYPT, bctx.ff_pkt->flags)) { if (bit_is_set(FO_SPARSE, bctx.ff_pkt->flags) || bit_is_set(FO_OFFSETS, bctx.ff_pkt->flags)) { Jmsg0(bctx.jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n")); goto bail_out; } /* * Allocate the cipher context */ if ((bctx.cipher_ctx = crypto_cipher_new(bctx.jcr->crypto.pki_session, true, &cipher_block_size)) == NULL) { /* * Shouldn't happen! */ Jmsg0(bctx.jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n")); goto bail_out; } /* * Grow the crypto buffer, if necessary. * crypto_cipher_update() will buffer up to (cipher_block_size - 1). * We grow crypto_buf to the maximum number of blocks that * could be returned for the given read buffer size. * (Using the larger of either rsize or max_compress_len) */ bctx.jcr->crypto.crypto_buf = check_pool_memory_size(bctx.jcr->crypto.crypto_buf, (MAX(bctx.jcr->buf_size + (int)sizeof(uint32_t), (int32_t)bctx.max_compress_len) + cipher_block_size - 1) / cipher_block_size * cipher_block_size); bctx.wbuf = bctx.jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */ } retval = true; bail_out: return retval; } /* * Setup a decryption context */ bool setup_decryption_context(r_ctx &rctx, RESTORE_CIPHER_CTX &rcctx) { if (!rctx.cs) { Jmsg1(rctx.jcr, M_ERROR, 0, _("Missing encryption session data stream for %s\n"), rctx.jcr->last_fname); return false; } if ((rcctx.cipher = crypto_cipher_new(rctx.cs, false, &rcctx.block_size)) == NULL) { Jmsg1(rctx.jcr, M_ERROR, 0, _("Failed to initialize decryption context for %s\n"), rctx.jcr->last_fname); free_session(rctx); return false; } return true; } bool encrypt_data(b_ctx *bctx, bool *need_more_data) { bool retval = false; uint32_t initial_len = 0; /* * Note, here we prepend the current record length to the beginning * of the encrypted data. This is because both sparse and compression * restore handling want records returned to them with exactly the * same number of bytes that were processed in the backup handling. * That is, both are block filters rather than a stream. When doing * compression, the compression routines may buffer data, so that for * any one record compressed, when it is decompressed the same size * will not be obtained. Of course, the buffered data eventually comes * out in subsequent crypto_cipher_update() calls or at least * when crypto_cipher_finalize() is called. Unfortunately, this * "feature" of encryption enormously complicates the restore code. */ ser_declare; if (bit_is_set(FO_SPARSE, bctx->ff_pkt->flags) || bit_is_set(FO_OFFSETS, bctx->ff_pkt->flags)) { bctx->cipher_input_len += OFFSET_FADDR_SIZE; } /* * Encrypt the length of the input block */ uint8_t packet_len[sizeof(uint32_t)]; ser_begin(packet_len, sizeof(uint32_t)); ser_uint32(bctx->cipher_input_len); /* store data len in begin of buffer */ Dmsg1(20, "Encrypt len=%d\n", bctx->cipher_input_len); if (!crypto_cipher_update(bctx->cipher_ctx, packet_len, sizeof(packet_len), (uint8_t *)bctx->jcr->crypto.crypto_buf, &initial_len)) { /* * Encryption failed. Shouldn't happen. */ Jmsg(bctx->jcr, M_FATAL, 0, _("Encryption error\n")); goto bail_out; } /* * Encrypt the input block */ if (crypto_cipher_update(bctx->cipher_ctx, bctx->cipher_input, bctx->cipher_input_len, (uint8_t *)&bctx->jcr->crypto.crypto_buf[initial_len], &bctx->encrypted_len)) { if ((initial_len + bctx->encrypted_len) == 0) { /* * No full block of data available, read more data */ *need_more_data = true; goto bail_out; } Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", bctx->encrypted_len, bctx->jcr->store_bsock->msglen); bctx->jcr->store_bsock->msglen = initial_len + bctx->encrypted_len; /* set encrypted length */ } else { /* * Encryption failed. Shouldn't happen. */ Jmsg(bctx->jcr, M_FATAL, 0, _("Encryption error\n")); goto bail_out; } retval = true; bail_out: return retval; } bool decrypt_data(JCR *jcr, char **data, uint32_t *length, RESTORE_CIPHER_CTX *cipher_ctx) { uint32_t decrypted_len = 0; /* Decryption output length */ ASSERT(cipher_ctx->cipher); /* * NOTE: We must implement block preserving semantics for the * non-streaming compression and sparse code. * * Grow the crypto buffer, if necessary. * crypto_cipher_update() will process only whole blocks, * buffering the remaining input. */ cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len + *length + cipher_ctx->block_size); /* * Decrypt the input block */ if (!crypto_cipher_update(cipher_ctx->cipher, (const u_int8_t *)*data, *length, (u_int8_t *)&cipher_ctx->buf[cipher_ctx->buf_len], &decrypted_len)) { /* * Decryption failed. Shouldn't happen. */ Jmsg(jcr, M_FATAL, 0, _("Decryption error\n")); goto bail_out; } if (decrypted_len == 0) { /* * No full block of encrypted data available, write more data */ *length = 0; return true; } Dmsg2(200, "decrypted len=%d encrypted len=%d\n", decrypted_len, *length); cipher_ctx->buf_len += decrypted_len; *data = cipher_ctx->buf; /* * If one full preserved block is available, write it to disk, * and then buffer any remaining data. This should be effecient * as long as Bareos's block size is not significantly smaller than the * encryption block size (extremely unlikely!) */ unser_crypto_packet_len(cipher_ctx); Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE); if (cipher_ctx->packet_len == 0 || cipher_ctx->buf_len < cipher_ctx->packet_len) { /* * No full preserved block is available. */ *length = 0; return true; } /* * We have one full block, set up the filter input buffers */ *length = cipher_ctx->packet_len - CRYPTO_LEN_SIZE; *data = &((*data)[CRYPTO_LEN_SIZE]); /* Skip the block length header */ cipher_ctx->buf_len -= cipher_ctx->packet_len; Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", *length, cipher_ctx->buf_len); return true; bail_out: return false; } bareos-Release-14.2.6/src/filed/dir_cmd.c000066400000000000000000001757201263011562700200730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file handles accepting Director Commands * * Kern Sibbald, October MM */ #include "bareos.h" #include "filed.h" #include "ch.h" #if defined(WIN32_VSS) #include "vss.h" static pthread_mutex_t vss_mutex = PTHREAD_MUTEX_INITIALIZER; static bool enable_vss = false; #endif extern bool backup_only_mode; extern bool restore_only_mode; /** * As Windows saves ACLs as part of the standard backup stream * we just pretend here that is has implicit acl support. */ #if defined(HAVE_ACL) || defined(HAVE_WIN32) const bool have_acl = true; #else const bool have_acl = false; #endif #if defined(HAVE_XATTR) const bool have_xattr = true; #else const bool have_xattr = false; #endif /* Imported functions */ extern bool accurate_cmd(JCR *jcr); extern bool status_cmd(JCR *jcr); extern bool qstatus_cmd(JCR *jcr); extern "C" char *job_code_callback_filed(JCR *jcr, const char* param); /* Forward referenced functions */ static bool backup_cmd(JCR *jcr); static bool bootstrap_cmd(JCR *jcr); static bool cancel_cmd(JCR *jcr); static bool end_restore_cmd(JCR *jcr); static bool estimate_cmd(JCR *jcr); #ifdef DEVELOPER static bool exit_cmd(JCR *jcr); #endif static bool fileset_cmd(JCR *jcr); static bool job_cmd(JCR *jcr); static bool level_cmd(JCR *jcr); static bool pluginoptions_cmd(JCR *jcr); static bool runafter_cmd(JCR *jcr); static bool runbeforenow_cmd(JCR *jcr); static bool runbefore_cmd(JCR *jcr); static bool runscript_cmd(JCR *jcr); static bool resolve_cmd(JCR *jcr); static bool restore_object_cmd(JCR *jcr); static bool restore_cmd(JCR *jcr); static bool session_cmd(JCR *jcr); static bool setauthorization_cmd(JCR *jcr); static bool setbandwidth_cmd(JCR *jcr); static bool setdebug_cmd(JCR *jcr); static bool storage_cmd(JCR *jcr); static bool sm_dump_cmd(JCR *jcr); static bool verify_cmd(JCR *jcr); static bool response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd); static void filed_free_jcr(JCR *jcr); static bool open_sd_read_session(JCR *jcr); static void set_storage_auth_key(JCR *jcr, char *key); /* Exported functions */ struct s_cmds { const char *cmd; bool (*func)(JCR *); bool monitoraccess; /* specify if monitors have access to this function */ }; /** * The following are the recognized commands from the Director. * * Keywords are sorted first longest match when the keywords start with the same string. */ static struct s_cmds cmds[] = { { "accurate", accurate_cmd, false }, { "backup", backup_cmd, false }, { "bootstrap", bootstrap_cmd, false }, { "cancel", cancel_cmd, false }, { "endrestore", end_restore_cmd, false }, { "estimate", estimate_cmd, false }, #ifdef DEVELOPER { "exit", exit_cmd, false }, #endif { "fileset", fileset_cmd, false }, { "JobId=", job_cmd, false }, { "level = ", level_cmd, false }, { "pluginoptions", pluginoptions_cmd, false }, { "RunAfterJob", runafter_cmd, false }, { "RunBeforeNow", runbeforenow_cmd, false }, { "RunBeforeJob", runbefore_cmd, false }, { "Run", runscript_cmd, false }, { "restoreobject", restore_object_cmd, false }, { "restore ", restore_cmd, false }, { "resolve ", resolve_cmd, false }, { "session", session_cmd, false }, { "setauthorization", setauthorization_cmd, false }, { "setbandwidth=", setbandwidth_cmd, false }, { "setdebug=", setdebug_cmd, false }, { "status", status_cmd, true }, { ".status", qstatus_cmd, true }, { "storage ", storage_cmd, false }, { "sm_dump", sm_dump_cmd, false }, { "verify", verify_cmd, false }, { NULL, NULL, false } /* list terminator */ }; /* * Commands received from director that need scanning */ static char setauthorizationcmd[] = "setauthorization Authorization=%100s"; static char setbandwidthcmd[] = "setbandwidth=%lld Job=%127s"; static char setdebugv0cmd[] = "setdebug=%d trace=%d"; static char setdebugv1cmd[] = "setdebug=%d trace=%d hangup=%d"; static char setdebugv2cmd[] = "setdebug=%d trace=%d hangup=%d timestamp=%d"; static char jobcmd[] = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s"; static char storaddrv0cmd[] = "storage address=%s port=%d ssl=%d"; static char storaddrv1cmd[] = "storage address=%s port=%d ssl=%d Authorization=%100s"; static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n"; static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n"; static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n"; static char restoreobjcmd[] = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d,%s"; static char restoreobjcmd1[] = "restoreobject JobId=%u %d,%d,%d,%d,%d,%d\n"; static char endrestoreobjectcmd[] = "restoreobject end\n"; static char pluginoptionscmd[] = "pluginoptions %s"; static char verifycmd[] = "verify level=%30s"; static char estimatecmd[] = "estimate listing=%d"; static char runbeforecmd[] = "RunBeforeJob %s"; static char runaftercmd[] = "RunAfterJob %s"; static char runscriptcmd[] = "Run OnSuccess=%d OnFailure=%d AbortOnError=%d When=%d Command=%s"; static char resolvecmd[] = "resolve %s"; /* * Responses sent to Director */ static char errmsg[] = "2999 Invalid command\n"; static char invalid_cmd[] = "2997 Invalid command for a Director with Monitor directive enabled.\n"; static char OkAuthorization[] = "2000 OK Authorization\n"; static char OKBandwidth[] = "2000 OK Bandwidth\n"; static char OKinc[] = "2000 OK include\n"; static char OKest[] = "2000 OK estimate files=%s bytes=%s\n"; static char OKlevel[] = "2000 OK level\n"; static char OKbackup[] = "2000 OK backup\n"; static char OKbootstrap[] = "2000 OK bootstrap\n"; static char OKverify[] = "2000 OK verify\n"; static char OKrestore[] = "2000 OK restore\n"; static char OKsession[] = "2000 OK session\n"; static char OKstore[] = "2000 OK storage\n"; static char OKstoreend[] = "2000 OK storage end\n"; static char OKjob[] = #if !defined(IS_BUILD_ON_OBS) "2000 OK Job %s (%s) %s,%s,%s"; #else "2000 OK Job %s (%s) %s,%s,%s,%s,%s"; #endif static char OKsetdebugv0[] = "2000 OK setdebug=%d trace=%d hangup=%d tracefile=%s\n"; static char OKsetdebugv1[] = "2000 OK setdebug=%d trace=%d hangup=%d timestamp=%d tracefile=%s\n"; static char BADjob[] = "2901 Bad Job\n"; static char EndJob[] = "2800 End Job TermCode=%d JobFiles=%u ReadBytes=%s" " JobBytes=%s Errors=%u VSS=%d Encrypt=%d\n"; static char OKRunBefore[] = "2000 OK RunBefore\n"; static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n"; static char OKRunAfter[] = "2000 OK RunAfter\n"; static char OKRunScript[] = "2000 OK RunScript\n"; static char BadRunBeforeJob[] = "2905 Bad RunBeforeJob command.\n"; static char FailedRunScript[] = "2905 Failed RunScript\n"; static char BadRunAfterJob[] = "2905 Bad RunAfterJob command.\n"; static char BADcmd[] = "2902 Bad %s\n"; static char OKRestoreObject[] = "2000 OK ObjectRestored\n"; static char OKPluginOptions[] = "2000 OK PluginOptions\n"; static char BadPluginOptions[] = "2905 Bad PluginOptions command.\n"; /* * Responses received from Storage Daemon */ static char OK_end[] = "3000 OK end\n"; static char OK_close[] = "3000 OK close Status = %d\n"; static char OK_open[] = "3000 OK open ticket = %d\n"; static char OK_data[] = "3000 OK data\n"; static char OK_append[] = "3000 OK append data\n"; /* * Commands sent to Storage Daemon */ static char append_open[] = "append open session\n"; static char append_data[] = "append data %d\n"; static char append_end[] = "append end session %d\n"; static char append_close[] = "append close session %d\n"; static char read_open[] = "read open session = %s %ld %ld %ld %ld %ld %ld\n"; static char read_data[] = "read data %d\n"; static char read_close[] = "read close session %d\n"; /* * See if we are allowed to execute the command issued. */ static bool validate_command(JCR *jcr, const char *cmd, alist *allowed_job_cmds) { char *allowed_job_cmd; bool allowed = false; /* * If there is no explicit list of allowed cmds allow all cmds. */ if (!allowed_job_cmds) { return true; } foreach_alist(allowed_job_cmd, allowed_job_cmds) { if (bstrcasecmp(cmd, allowed_job_cmd)) { allowed = true; break; } } if (!allowed) { Jmsg(jcr, M_FATAL, 0, _("Illegal \"%s\" command not allowed by Allowed Job Cmds setting of this filed.\n"), cmd); } return allowed; } static inline void cleanup_fileset(JCR *jcr) { findFILESET *fileset; findINCEXE *incexe; findFOPTS *fo; fileset = jcr->ff->fileset; if (fileset) { /* * Delete FileSet Include lists */ for (int i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); for (int j = 0; j < incexe->opts_list.size(); j++) { fo = (findFOPTS *)incexe->opts_list.get(j); if (fo->plugin) { free(fo->plugin); } for (int k = 0; kregex.size(); k++) { regfree((regex_t *)fo->regex.get(k)); } for (int k = 0; kregexdir.size(); k++) { regfree((regex_t *)fo->regexdir.get(k)); } for (int k = 0; kregexfile.size(); k++) { regfree((regex_t *)fo->regexfile.get(k)); } if (fo->size_match) { free(fo->size_match); } fo->regex.destroy(); fo->regexdir.destroy(); fo->regexfile.destroy(); fo->wild.destroy(); fo->wilddir.destroy(); fo->wildfile.destroy(); fo->wildbase.destroy(); fo->base.destroy(); fo->fstype.destroy(); fo->drivetype.destroy(); } incexe->opts_list.destroy(); incexe->name_list.destroy(); incexe->plugin_list.destroy(); incexe->ignoredir.destroy(); } fileset->include_list.destroy(); /* * Delete FileSet Exclude lists */ for (int i = 0; iexclude_list.size(); i++) { incexe = (findINCEXE *)fileset->exclude_list.get(i); for (int j = 0; jopts_list.size(); j++) { fo = (findFOPTS *)incexe->opts_list.get(j); if (fo->size_match) { free(fo->size_match); } fo->regex.destroy(); fo->regexdir.destroy(); fo->regexfile.destroy(); fo->wild.destroy(); fo->wilddir.destroy(); fo->wildfile.destroy(); fo->wildbase.destroy(); fo->base.destroy(); fo->fstype.destroy(); fo->drivetype.destroy(); } incexe->opts_list.destroy(); incexe->name_list.destroy(); incexe->plugin_list.destroy(); incexe->ignoredir.destroy(); } fileset->exclude_list.destroy(); free(fileset); } jcr->ff->fileset = NULL; } /* * Connection request from an director. * * Accept commands one at a time from the Director and execute them. * * Concerning ClientRunBefore/After, the sequence of events * is rather critical. If they are not done in the right * order one can easily get FD->SD timeouts if the script * runs a long time. * * The current sequence of events is: * 1. Dir starts job with FD * 2. Dir connects to SD * 3. Dir connects to FD * 4. FD connects to SD * 5. FD gets/runs ClientRunBeforeJob and sends ClientRunAfterJob * 6. Dir sends include/exclude * 7. FD sends data to SD * 8. SD/FD disconnects while SD despools data and attributes (optional) * 9. FD runs ClientRunAfterJob */ static void *handle_director_connection(BSOCK *dir) { JCR *jcr; bool found; bool quit = false; const char jobname[12] = "*Director*"; // saveCWD save_cwd; #ifdef HAVE_WIN32 prevent_os_suspensions(); #endif jcr = new_jcr(sizeof(JCR), filed_free_jcr); /* create JCR */ jcr->dir_bsock = dir; jcr->ff = init_find_files(); // save_cwd.save(jcr); jcr->start_time = time(NULL); jcr->RunScripts = New(alist(10, not_owned_by_alist)); jcr->last_fname = get_pool_memory(PM_FNAME); jcr->last_fname[0] = 0; jcr->client_name = get_memory(strlen(my_name) + 1); pm_strcpy(jcr->client_name, my_name); bstrncpy(jcr->Job, jobname, sizeof(jobname)); /* dummy */ jcr->crypto.pki_sign = me->pki_sign; jcr->crypto.pki_encrypt = me->pki_encrypt; jcr->crypto.pki_keypair = me->pki_keypair; jcr->crypto.pki_signers = me->pki_signers; jcr->crypto.pki_recipients = me->pki_recipients; dir->set_jcr(jcr); set_jcr_in_tsd(jcr); enable_backup_privileges(NULL, 1 /* ignore_errors */); Dmsg0(120, "Calling Authenticate\n"); if (!authenticate_director(jcr)) { return NULL; } Dmsg0(120, "OK Authenticate\n"); jcr->authenticated = true; /**********FIXME******* add command handler error code */ while (!quit) { /* * Read command */ if (dir->recv() < 0) { break; /* connection terminated */ } dir->msg[dir->msglen] = 0; Dmsg1(100, "msg); found = false; for (int i = 0; cmds[i].cmd; i++) { if (bstrncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd))) { found = true; /* indicate command found */ if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) { Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd); dir->fsend(invalid_cmd); dir->signal(BNET_EOD); break; } Dmsg1(100, "Executing %s command.\n", cmds[i].cmd); if (!cmds[i].func(jcr)) { /* do command */ quit = true; /* error or fully terminated, get out */ Dmsg1(100, "Quit command loop. Canceled=%d\n", job_canceled(jcr)); } break; } } if (!found) { /* command not found */ dir->fsend(errmsg); quit = true; break; } } /* * Inform Storage daemon that we are done */ if (jcr->store_bsock) { jcr->store_bsock->signal(BNET_TERMINATE); } /* * Run the after job */ if (jcr->RunScripts) { run_scripts(jcr, jcr->RunScripts, "ClientAfterJob", (jcr->director && jcr->director->allowed_script_dirs) ? jcr->director->allowed_script_dirs : me->allowed_script_dirs); } if (jcr->JobId) { /* send EndJob if running a job */ char ed1[50], ed2[50]; /* Send termination status back to Dir */ dir->fsend(EndJob, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->ReadBytes, ed1), edit_uint64(jcr->JobBytes, ed2), jcr->JobErrors, jcr->VSS, jcr->crypto.pki_encrypt); Dmsg1(110, "End FD msg: %s\n", dir->msg); } generate_plugin_event(jcr, bEventJobEnd); dequeue_messages(jcr); /* send any queued messages */ /* * Inform Director that we are done */ dir->signal(BNET_TERMINATE); free_plugins(jcr); /* release instantiated plugins */ free_and_null_pool_memory(jcr->job_metadata); /* * Clean up fileset */ cleanup_fileset(jcr); Dmsg0(100, "Calling term_find_files\n"); term_find_files(jcr->ff); // save_cwd.restore(jcr); // save_cwd.release(); jcr->ff = NULL; Dmsg0(100, "Done with term_find_files\n"); free_jcr(jcr); /* destroy JCR record */ Dmsg0(100, "Done with free_jcr\n"); Dsm_check(100); garbage_collect_memory_pool(); #ifdef HAVE_WIN32 allow_os_suspensions(); #endif return NULL; } /* * Connection request. We accept connections either from the Director or the Storage Daemon * * NOTE! We are running as a separate thread * * Send output one line at a time followed by a zero length transmission. * Return when the connection is terminated or there is an error. * * Basic tasks done here: * - If it was a connection from an SD, call handle_stored_connection() * - Otherwise it was a connection from the DIR, call handle_director_connection() */ void *handle_connection_request(void *arg) { BSOCK *bs = (BSOCK *)arg; char tbuf[100]; if (bs->recv() <= 0) { Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who()); bmicrosleep(5, 0); /* make user wait 5 seconds */ bs->close(); delete bs; return NULL; } Dmsg1(110, "Conn: %s", bs->msg); /* * See if its a director making a connection. */ if (bstrncmp(bs->msg, "Hello Director", 14)) { Dmsg1(110, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); return handle_director_connection(bs); } /* * See if its a storage daemon making a connection. */ if (bstrncmp(bs->msg, "Hello Storage", 13)) { Dmsg1(110, "Got a SD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); return handle_stored_connection(bs); } Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen); return NULL; } static bool sm_dump_cmd(JCR *jcr) { close_memory_pool(); sm_dump(false, true); jcr->dir_bsock->fsend("2000 sm_dump OK\n"); return true; } /* * Resolve a hostname */ static bool resolve_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; dlist *addr_list; const char *errstr; char addresses[2048]; char hostname[2048]; sscanf(dir->msg, resolvecmd, &hostname); if ((addr_list = bnet_host2ipaddrs(hostname, 0, &errstr)) == NULL) { dir->fsend(_("%s: Failed to resolve %s\n"), my_name, hostname); goto bail_out; } dir->fsend(_("%s resolves %s to %s\n"),my_name, hostname, build_addresses_str(addr_list, addresses, sizeof(addresses), false)); free_addresses(addr_list); bail_out: dir->signal(BNET_EOD); return true; } #ifdef DEVELOPER static bool exit_cmd(JCR *jcr) { jcr->dir_bsock->fsend("2000 exit OK\n"); terminate_filed(0); return false; } #endif /** * Cancel a Job */ static bool cancel_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; char Job[MAX_NAME_LENGTH]; JCR *cjcr; if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) { if (!(cjcr=get_jcr_by_full_name(Job))) { dir->fsend(_("2901 Job %s not found.\n"), Job); } else { generate_plugin_event(cjcr, bEventCancelCommand, NULL); cjcr->setJobStatus(JS_Canceled); if (cjcr->store_bsock) { cjcr->store_bsock->set_timed_out(); cjcr->store_bsock->set_terminated(); cjcr->my_thread_send_signal(TIMEOUT_SIGNAL); } free_jcr(cjcr); dir->fsend(_("2001 Job %s marked to be canceled.\n"), Job); } } else { dir->fsend(_("2902 Error scanning cancel command.\n")); } dir->signal(BNET_EOD); return true; } /** * Set new authorization key as requested by the Director */ static bool setauthorization_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOL_MEM sd_auth_key(PM_MESSAGE); sd_auth_key.check_size(dir->msglen); if (sscanf(dir->msg, setauthorizationcmd, sd_auth_key.c_str()) != 1) { dir->fsend(BADcmd, "setauthorization"); return false; } set_storage_auth_key(jcr, sd_auth_key.c_str()); Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key); return dir->fsend(OkAuthorization); } /** * Set bandwidth limit as requested by the Director */ static bool setbandwidth_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; int64_t bw = 0; JCR *cjcr; char Job[MAX_NAME_LENGTH]; *Job = 0; if (sscanf(dir->msg, setbandwidthcmd, &bw, Job) != 2 || bw < 0) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("2991 Bad setbandwidth command: %s\n"), jcr->errmsg); return false; } if (*Job) { if (!(cjcr = get_jcr_by_full_name(Job))) { dir->fsend(_("2901 Job %s not found.\n"), Job); } else { cjcr->max_bandwidth = bw; if (cjcr->store_bsock) { cjcr->store_bsock->set_bwlimit(bw); if (me->allow_bw_bursting) { cjcr->store_bsock->set_bwlimit_bursting(); } } free_jcr(cjcr); } } else { /* No job requested, apply globally */ me->max_bandwidth_per_job = bw; /* Overwrite directive */ } return dir->fsend(OKBandwidth); } /** * Set debug level as requested by the Director */ static bool setdebug_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; int32_t level, trace_flag, hangup_flag, timestamp_flag; int scan; Dmsg1(50, "setdebug_cmd: %s", dir->msg); scan = sscanf(dir->msg, setdebugv2cmd, &level, &trace_flag, &hangup_flag, ×tamp_flag); if (scan != 4) { scan = sscanf(dir->msg, setdebugv1cmd, &level, &trace_flag, &hangup_flag); } if (scan != 3 && scan != 4) { scan = sscanf(dir->msg, setdebugv0cmd, &level, &trace_flag); if (scan != 2) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("2991 Bad setdebug command: %s\n"), jcr->errmsg); return false; } else { hangup_flag = -1; } } POOL_MEM tracefilename(PM_FNAME); Mmsg(tracefilename, "%s/%s.trace", TRACEFILEDIRECTORY, my_name); if (level >= 0) { debug_level = level; } set_trace(trace_flag); set_hangup(hangup_flag); if (scan == 4) { set_timestamp(timestamp_flag); Dmsg5(50, "level=%d trace=%d hangup=%d timestamp=%d tracefilename=%s\n", level, get_trace(), get_hangup(), get_timestamp(), tracefilename.c_str()); return dir->fsend(OKsetdebugv1, level, get_trace(), get_hangup(), get_timestamp(), tracefilename.c_str()); } else { Dmsg4(50, "level=%d trace=%d hangup=%d tracefilename=%s\n", level, get_trace(), get_hangup(), tracefilename.c_str()); return dir->fsend(OKsetdebugv0, level, get_trace(), get_hangup(), tracefilename.c_str()); } } static bool estimate_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; char ed1[50], ed2[50]; /* * See if we are allowed to run estimate cmds. */ if (!validate_command(jcr, "estimate", (jcr->director && jcr->director->allowed_job_cmds) ? jcr->director->allowed_job_cmds : me->allowed_job_cmds)) { dir->fsend(_("2992 Bad estimate command.\n")); return 0; } if (sscanf(dir->msg, estimatecmd, &jcr->listing) != 1) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad estimate command: %s"), jcr->errmsg); dir->fsend(_("2992 Bad estimate command.\n")); return false; } make_estimate(jcr); dir->fsend(OKest, edit_uint64_with_commas(jcr->num_files_examined, ed1), edit_uint64_with_commas(jcr->JobBytes, ed2)); dir->signal(BNET_EOD); return true; } /** * Get JobId and Storage Daemon Authorization key from Director */ static bool job_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOL_MEM sd_auth_key(PM_MESSAGE); sd_auth_key.check_size(dir->msglen); const char *os_version; if (sscanf(dir->msg, jobcmd, &jcr->JobId, jcr->Job, &jcr->VolSessionId, &jcr->VolSessionTime, sd_auth_key.c_str()) != 5) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad Job Command: %s"), jcr->errmsg); dir->fsend(BADjob); return false; } set_storage_auth_key(jcr, sd_auth_key.c_str()); Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key); Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job); new_plugins(jcr); /* instantiate plugins for this jcr */ generate_plugin_event(jcr, bEventJobStart, (void *)jcr->errmsg); #ifdef HAVE_WIN32 os_version = win_os; #else os_version = HOST_OS; #endif #if !defined(IS_BUILD_ON_OBS) return dir->fsend(OKjob, VERSION, LSMDATE, os_version, DISTNAME, DISTVER); #else return dir->fsend(OKjob, VERSION, LSMDATE, os_version, DISTNAME, DISTVER, OBS_DISTRIBUTION, OBS_ARCH); #endif } static bool runbefore_cmd(JCR *jcr) { bool ok; POOLMEM *cmd; RUNSCRIPT *script; BSOCK *dir = jcr->dir_bsock; if (!me->compatible) { dir->fsend(BadRunBeforeJob); return false; } Dmsg1(100, "runbefore_cmd: %s", dir->msg); cmd = get_memory(dir->msglen + 1); if (sscanf(dir->msg, runbeforecmd, cmd) != 1) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad RunBeforeJob command: %s\n"), jcr->errmsg); dir->fsend(BadRunBeforeJob); free_memory(cmd); return false; } unbash_spaces(cmd); /* * Run the command now */ script = new_runscript(); script->set_job_code_callback(job_code_callback_filed); script->set_command(cmd); script->when = SCRIPT_Before; free_memory(cmd); ok = script->run(jcr, "ClientRunBeforeJob"); free_runscript(script); if (ok) { dir->fsend(OKRunBefore); return true; } else { dir->fsend(BadRunBeforeJob); return false; } } static bool runbeforenow_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; run_scripts(jcr, jcr->RunScripts, "ClientBeforeJob", (jcr->director && jcr->director->allowed_script_dirs) ? jcr->director->allowed_script_dirs : me->allowed_script_dirs); if (job_canceled(jcr)) { dir->fsend(FailedRunScript); Dmsg0(100, "Back from run_scripts ClientBeforeJob now: FAILED\n"); return false; } else { dir->fsend(OKRunBeforeNow); Dmsg0(100, "Back from run_scripts ClientBeforeJob now: OK\n"); return true; } } static bool runafter_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOLMEM *cmd; RUNSCRIPT *script; if (!me->compatible) { dir->fsend(BadRunAfterJob); return false; } Dmsg1(100, "runafter_cmd: %s", dir->msg); cmd = get_memory(dir->msglen + 1); if (sscanf(dir->msg, runaftercmd, cmd) != 1) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad RunAfter command: %s\n"), jcr->errmsg); dir->fsend(BadRunAfterJob); free_memory(cmd); return false; } unbash_spaces(cmd); script = new_runscript(); script->set_job_code_callback(job_code_callback_filed); script->set_command(cmd); script->on_success = true; script->on_failure = false; script->when = SCRIPT_After; free_memory(cmd); jcr->RunScripts->append(script); return dir->fsend(OKRunAfter); } static bool runscript_cmd(JCR *jcr) { POOLMEM *msg; RUNSCRIPT *cmd; BSOCK *dir = jcr->dir_bsock; int on_success, on_failure, fail_on_error; /* * See if we are allowed to run runscript cmds. */ if (!validate_command(jcr, "runscript", (jcr->director && jcr->director->allowed_job_cmds) ? jcr->director->allowed_job_cmds : me->allowed_job_cmds)) { dir->fsend(FailedRunScript); return 0; } msg = get_memory(dir->msglen + 1); cmd = new_runscript(); cmd->set_job_code_callback(job_code_callback_filed); Dmsg1(100, "runscript_cmd: '%s'\n", dir->msg); /* * Note, we cannot sscanf into bools */ if (sscanf(dir->msg, runscriptcmd, &on_success, &on_failure, &fail_on_error, &cmd->when, msg) != 5) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad RunScript command: %s\n"), jcr->errmsg); dir->fsend(FailedRunScript); free_runscript(cmd); free_memory(msg); return false; } cmd->on_success = on_success; cmd->on_failure = on_failure; cmd->fail_on_error = fail_on_error; unbash_spaces(msg); cmd->set_command(msg); cmd->debug(); jcr->RunScripts->append(cmd); free_pool_memory(msg); return dir->fsend(OKRunScript); } /* * This passes plugin specific options. */ static bool pluginoptions_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOLMEM *msg; msg = get_memory(dir->msglen + 1); if (sscanf(dir->msg, pluginoptionscmd, msg) != 1) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad Plugin Options command: %s\n"), jcr->errmsg); dir->fsend(BadPluginOptions); free_memory(msg); return false; } unbash_spaces(msg); generate_plugin_event(jcr, bEventNewPluginOptions, (void *)msg); free_memory(msg); return dir->fsend(OKPluginOptions); } /* * This reads data sent from the Director from the * RestoreObject table that allows us to get objects * that were backed up (VSS .xml data) and are needed * before starting the restore. */ static bool restore_object_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; int32_t FileIndex; restore_object_pkt rop; memset(&rop, 0, sizeof(rop)); rop.pkt_size = sizeof(rop); rop.pkt_end = sizeof(rop); Dmsg1(100, "Enter restoreobject_cmd: %s", dir->msg); if (bstrcmp(dir->msg, endrestoreobjectcmd)) { generate_plugin_event(jcr, bEventRestoreObject, NULL); return dir->fsend(OKRestoreObject); } rop.plugin_name = (char *) malloc (dir->msglen); *rop.plugin_name = 0; if (sscanf(dir->msg, restoreobjcmd, &rop.JobId, &rop.object_len, &rop.object_full_len, &rop.object_index, &rop.object_type, &rop.object_compression, &FileIndex, rop.plugin_name) != 8) { /* * Old version, no plugin_name */ if (sscanf(dir->msg, restoreobjcmd1, &rop.JobId, &rop.object_len, &rop.object_full_len, &rop.object_index, &rop.object_type, &rop.object_compression, &FileIndex) != 7) { Dmsg0(5, "Bad restore object command\n"); pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg); goto bail_out; } } unbash_spaces(rop.plugin_name); Dmsg7(100, "Recv object: JobId=%u objlen=%d full_len=%d objinx=%d objtype=%d " "FI=%d plugin_name=%s\n", rop.JobId, rop.object_len, rop.object_full_len, rop.object_index, rop.object_type, FileIndex, rop.plugin_name); /* * Read Object name */ if (dir->recv() < 0) { goto bail_out; } Dmsg2(100, "Recv Oname object: len=%d Oname=%s\n", dir->msglen, dir->msg); rop.object_name = bstrdup(dir->msg); /* * Read Object */ if (dir->recv() < 0) { goto bail_out; } /* * Transfer object from message buffer, and get new message buffer */ rop.object = dir->msg; dir->msg = get_pool_memory(PM_MESSAGE); /* * If object is compressed, uncompress it */ switch (rop.object_compression) { case 1: { /* zlib level 9 */ int status; int out_len = rop.object_full_len + 100; POOLMEM *obj = get_memory(out_len); Dmsg2(100, "Inflating from %d to %d\n", rop.object_len, rop.object_full_len); status = Zinflate(rop.object, rop.object_len, obj, out_len); Dmsg1(100, "Zinflate status=%d\n", status); if (out_len != rop.object_full_len) { Jmsg3(jcr, M_ERROR, 0, ("Decompression failed. Len wanted=%d got=%d. Object_name=%s\n"), rop.object_full_len, out_len, rop.object_name); } free_pool_memory(rop.object); /* Release compressed object */ rop.object = obj; /* New uncompressed object */ rop.object_len = out_len; break; } default: break; } if (debug_level >= 100) { POOL_MEM object_content(PM_MESSAGE); /* * Convert the object into a null terminated string. */ object_content.check_size(rop.object_len + 1); memset(object_content.c_str(), 0, rop.object_len + 1); memcpy(object_content.c_str(), rop.object, rop.object_len); Dmsg2(100, "Recv Object: len=%d Object=%s\n", rop.object_len, object_content.c_str()); } /* * We still need to do this to detect a vss restore */ if (bstrcmp(rop.object_name, "job_metadata.xml")) { Dmsg0(100, "got job metadata\n"); jcr->got_metadata = true; } generate_plugin_event(jcr, bEventRestoreObject, (void *)&rop); if (rop.object_name) { free(rop.object_name); } if (rop.object) { free_pool_memory(rop.object); } if (rop.plugin_name) { free(rop.plugin_name); } Dmsg1(100, "Send: %s", OKRestoreObject); return true; bail_out: dir->fsend(_("2909 Bad RestoreObject command.\n")); return false; } #if defined(WIN32_VSS) static inline int count_include_list_file_entries(JCR *jcr) { int cnt = 0; findFILESET *fileset; findINCEXE *incexe; fileset = jcr->ff->fileset; if (fileset) { for (int i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); cnt += incexe->name_list.size(); } } return cnt; } #endif /** * Director is passing his Fileset */ static bool fileset_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; bool retval; #if defined(WIN32_VSS) int vss = 0; sscanf(dir->msg, "fileset vss=%d", &vss); #endif if (!init_fileset(jcr)) { return false; } while (dir->recv() >= 0) { strip_trailing_junk(dir->msg); Dmsg1(500, "Fileset: %s\n", dir->msg); add_fileset(jcr, dir->msg); } if (!term_fileset(jcr)) { return false; } #if defined(WIN32_VSS) enable_vss = (vss && (count_include_list_file_entries(jcr) > 0)) ? true : false; #endif retval = dir->fsend(OKinc); generate_plugin_event(jcr, bEventEndFileSet); check_include_list_shadowing(jcr, jcr->ff->fileset); return retval; } static void free_bootstrap(JCR *jcr) { if (jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); free_pool_memory(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; } } static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER; static uint32_t bsr_uniq = 0; /** * The Director sends us the bootstrap file, which * we will in turn pass to the SD. * Deprecated. The bsr is now sent directly from the * Director to the SD. */ static bool bootstrap_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOLMEM *fname = get_pool_memory(PM_FNAME); FILE *bs; free_bootstrap(jcr); P(bsr_mutex); bsr_uniq++; Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name, jcr->Job, bsr_uniq); V(bsr_mutex); Dmsg1(400, "bootstrap=%s\n", fname); jcr->RestoreBootstrap = fname; bs = fopen(fname, "a+b"); /* create file */ if (!bs) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"), jcr->RestoreBootstrap, be.bstrerror()); /* * Suck up what he is sending to us so that he will then * read our error message. */ while (dir->recv() >= 0) { } free_bootstrap(jcr); jcr->setJobStatus(JS_ErrorTerminated); return false; } while (dir->recv() >= 0) { Dmsg1(200, "filedmsg); fputs(dir->msg, bs); } fclose(bs); /* * Note, do not free the bootstrap yet -- it needs to be * sent to the SD */ return dir->fsend(OKbootstrap); } /** * Get backup level from Director * */ static bool level_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOLMEM *level, *buf = NULL; int mtime_only; level = get_memory(dir->msglen+1); Dmsg1(10, "level_cmd: %s", dir->msg); /* keep compatibility with older directors */ if (strstr(dir->msg, "accurate")) { jcr->accurate = true; } if (strstr(dir->msg, "rerunning")) { jcr->rerunning = true; } if (sscanf(dir->msg, "level = %s ", level) != 1) { goto bail_out; } /* Base backup requested? */ if (bstrcmp(level, "base")) { jcr->setJobLevel(L_BASE); /* Full backup requested? */ } else if (bstrcmp(level, "full")) { jcr->setJobLevel(L_FULL); } else if (strstr(level, "differential")) { jcr->setJobLevel(L_DIFFERENTIAL); free_memory(level); return true; } else if (strstr(level, "incremental")) { jcr->setJobLevel(L_INCREMENTAL); free_memory(level); return true; /* * We get his UTC since time, then sync the clocks and correct it * to agree with our clock. */ } else if (bstrcmp(level, "since_utime")) { buf = get_memory(dir->msglen+1); utime_t since_time, adj; btime_t his_time, bt_start, rt=0, bt_adj=0; if (jcr->getJobLevel() == L_NONE) { jcr->setJobLevel(L_SINCE); /* if no other job level set, do it now */ } if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d prev_job=%127s", buf, &mtime_only, jcr->PrevJob) != 3) { if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d", buf, &mtime_only) != 2) { goto bail_out; } } since_time = str_to_uint64(buf); /* this is the since time */ Dmsg2(100, "since_time=%lld prev_job=%s\n", since_time, jcr->PrevJob); char ed1[50], ed2[50]; /* * Sync clocks by polling him for the time. We take * 10 samples of his time throwing out the first two. */ for (int i = 0; i < 10; i++) { bt_start = get_current_btime(); dir->signal(BNET_BTIME); /* poll for time */ if (dir->recv() <= 0) { /* get response */ goto bail_out; } if (sscanf(dir->msg, "btime %s", buf) != 1) { goto bail_out; } if (i < 2) { /* toss first two results */ continue; } his_time = str_to_uint64(buf); rt = get_current_btime() - bt_start; /* compute round trip time */ Dmsg2(100, "Dirtime=%s FDtime=%s\n", edit_uint64(his_time, ed1), edit_uint64(bt_start, ed2)); bt_adj += bt_start - his_time - rt/2; Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2)); } bt_adj = bt_adj / 8; /* compute average time */ Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2)); adj = btime_to_utime(bt_adj); since_time += adj; /* adjust for clock difference */ /* Don't notify if time within 3 seconds */ if (adj > 3 || adj < -3) { int type; if (adj > 600 || adj < -600) { type = M_WARNING; } else { type = M_INFO; } Jmsg(jcr, type, 0, _("DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n"), adj); } dir->signal(BNET_EOD); Dmsg2(100, "adj=%lld since_time=%lld\n", adj, since_time); jcr->incremental = true; /* set incremental or decremental backup */ jcr->mtime = since_time; /* set since time */ generate_plugin_event(jcr, bEventSince, (void *)(time_t)jcr->mtime); } else { Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level); free_memory(level); return false; } free_memory(level); if (buf) { free_memory(buf); } generate_plugin_event(jcr, bEventLevel, (void*)(intptr_t)jcr->getJobLevel()); return dir->fsend(OKlevel); bail_out: pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg); free_memory(level); if (buf) { free_memory(buf); } return false; } /** * Get session parameters from Director -- this is for a Restore command * This is deprecated. It is now passed via the bsr. */ static bool session_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; Dmsg1(100, "SessionCmd: %s", dir->msg); if (sscanf(dir->msg, sessioncmd, jcr->VolumeName, &jcr->VolSessionId, &jcr->VolSessionTime, &jcr->StartFile, &jcr->EndFile, &jcr->StartBlock, &jcr->EndBlock) != 7) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad session command: %s"), jcr->errmsg); return false; } return dir->fsend(OKsession); } static void set_storage_auth_key(JCR *jcr, char *key) { /* if no key don't update anything */ if (!*key) { return; } /** * We can be contacting multiple storage daemons. * So, make sure that any old jcr->store_bsock is cleaned up. */ if (jcr->store_bsock) { delete jcr->store_bsock; jcr->store_bsock = NULL; } /** * We can be contacting multiple storage daemons. * So, make sure that any old jcr->sd_auth_key is cleaned up. */ if (jcr->sd_auth_key) { /* * If we already have a Authorization key, director can do multi * storage restore */ Dmsg0(5, "set multi_restore=true\n"); jcr->multi_restore = true; bfree(jcr->sd_auth_key); } jcr->sd_auth_key = bstrdup(key); Dmsg0(5, "set sd auth key\n"); } /** * Get address of storage daemon from Director */ static bool storage_cmd(JCR *jcr) { int stored_port; /* storage daemon port */ int enable_ssl; /* enable ssl to sd */ char stored_addr[MAX_NAME_LENGTH]; POOL_MEM sd_auth_key(PM_MESSAGE); BSOCK *dir = jcr->dir_bsock; BSOCK *sd; /* storage daemon bsock */ sd = New(BSOCK_TCP); if (me->nokeepalive) { sd->clear_keepalive(); } Dmsg1(100, "StorageCmd: %s", dir->msg); sd_auth_key.check_size(dir->msglen); if (sscanf(dir->msg, storaddrv1cmd, stored_addr, &stored_port, &enable_ssl, sd_auth_key.c_str()) != 4) { if (sscanf(dir->msg, storaddrv0cmd, stored_addr, &stored_port, &enable_ssl) != 3) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), jcr->errmsg); goto bail_out; } } set_storage_auth_key(jcr, sd_auth_key.c_str()); Dmsg3(110, "Open storage: %s:%d ssl=%d\n", stored_addr, stored_port, enable_ssl); sd->set_source_address(me->FDsrc_addr); /* * TODO: see if we put limit on restore and backup... */ if (!jcr->max_bandwidth) { if (jcr->director->max_bandwidth_per_job) { jcr->max_bandwidth = jcr->director->max_bandwidth_per_job; } else if (me->max_bandwidth_per_job) { jcr->max_bandwidth = me->max_bandwidth_per_job; } } sd->set_bwlimit(jcr->max_bandwidth); if (me->allow_bw_bursting) { sd->set_bwlimit_bursting(); } /* * Open command communications with Storage daemon */ if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval, _("Storage daemon"), stored_addr, NULL, stored_port, 1)) { delete sd; sd = NULL; } if (sd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"), stored_addr, stored_port); Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n", stored_addr, stored_port); goto bail_out; } Dmsg0(110, "Connection OK to SD.\n"); jcr->store_bsock = sd; sd->fsend("Hello Start Job %s\n", jcr->Job); if (!authenticate_with_storagedaemon(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Failed to authenticate Storage daemon.\n")); goto bail_out; } Dmsg0(110, "Authenticated with SD.\n"); /* * Send OK to Director */ return dir->fsend(OKstore); bail_out: dir->fsend(BADcmd, "storage"); return false; } /** * Do a backup. */ static bool backup_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; BSOCK *sd = jcr->store_bsock; int ok = 0; int SDJobStatus; int32_t FileIndex; /* * See if we are in restore only mode then we don't allow a backup to be initiated. */ if (restore_only_mode) { Jmsg(jcr, M_FATAL, 0, _("Filed in restore only mode, backups are not allowed, aborting...\n")); goto cleanup; } /* * See if we are allowed to run backup cmds. */ if (!validate_command(jcr, "backup", (jcr->director && jcr->director->allowed_job_cmds) ? jcr->director->allowed_job_cmds : me->allowed_job_cmds)) { goto cleanup; } #if defined(WIN32_VSS) /* * Capture state here, if client is backed up by multiple directors * and one enables vss and the other does not then enable_vss can change * between here and where its evaluated after the job completes. */ jcr->VSS = g_pVSSClient && enable_vss; if (jcr->VSS) { /* * Run only one at a time */ P(vss_mutex); } #endif if (sscanf(dir->msg, "backup FileIndex=%ld\n", &FileIndex) == 1) { jcr->JobFiles = FileIndex; Dmsg1(100, "JobFiles=%ld\n", jcr->JobFiles); } /** * Validate some options given to the backup make sense for the compiled in options of this filed. */ if (bit_is_set(FO_ACL, jcr->ff->flags) && !have_acl) { Jmsg(jcr, M_WARNING, 0, _("ACL support requested in fileset but not available on this platform. Disabling ...\n")); clear_bit(FO_ACL, jcr->ff->flags); } if (bit_is_set(FO_XATTR, jcr->ff->flags) && !have_xattr) { Jmsg(jcr, M_WARNING, 0, _("XATTR support requested in fileset but not available on this platform. Disabling ...\n")); clear_bit(FO_XATTR, jcr->ff->flags); } jcr->setJobStatus(JS_Blocked); jcr->setJobType(JT_BACKUP); Dmsg1(100, "begin backup ff=%p\n", jcr->ff); if (sd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n")); dir->fsend(BADcmd, "backup"); goto cleanup; } dir->fsend(OKbackup); Dmsg1(110, "filed>dird: %s", dir->msg); /** * Send Append Open Session to Storage daemon */ sd->fsend(append_open); Dmsg1(110, ">stored: %s", sd->msg); /** * Expect to receive back the Ticket number */ if (bget_msg(sd) >= 0) { Dmsg1(110, "msg); if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) { Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg); goto cleanup; } Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket); } else { Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to open command\n")); goto cleanup; } /** * Send Append data command to Storage daemon */ sd->fsend(append_data, jcr->Ticket); Dmsg1(110, ">stored: %s", sd->msg); /** * Expect to get OK data */ if (!response(jcr, sd, OK_data, "Append Data")) { Dmsg1(110, "msg); goto cleanup; } Dmsg1(110, "msg); generate_plugin_event(jcr, bEventStartBackupJob); #if defined(WIN32_VSS) /* * START VSS ON WIN32 */ if (jcr->VSS) { if (g_pVSSClient->InitializeForBackup(jcr)) { int drive_count; char szWinDriveLetters[27]; bool onefs_disabled; generate_plugin_event(jcr, bEventVssBackupAddComponents); /* * Tell vss which drives to snapshot */ *szWinDriveLetters = 0; /* * Plugin driver can return drive letters */ generate_plugin_event(jcr, bEventVssPrepareSnapshot, szWinDriveLetters); drive_count = get_win32_driveletters(jcr->ff->fileset, szWinDriveLetters); onefs_disabled = win32_onefs_is_disabled(jcr->ff->fileset); if (drive_count > 0) { Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"), g_pVSSClient->GetDriverName(), (drive_count) ? szWinDriveLetters : "None"); if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters, onefs_disabled)) { berrno be; Jmsg(jcr, M_FATAL, 0, _("CreateSGenerate VSS snapshots failed. ERR=%s\n"), be.bstrerror()); } else { /* * Inform about VMPs if we have them */ g_pVSSClient->ShowVolumeMountPointStats(jcr); /* * Tell user if snapshot creation of a specific drive failed */ for (int i = 0; i < (int)strlen(szWinDriveLetters); i++) { if (islower(szWinDriveLetters[i])) { Jmsg(jcr, M_FATAL, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed.\n"), szWinDriveLetters[i]); } } /* * Inform user about writer states */ for (int i = 0; i < (int)g_pVSSClient->GetWriterCount(); i++) { if (g_pVSSClient->GetWriterState(i) < 1) { Jmsg(jcr, M_INFO, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i)); } } } } else { Jmsg(jcr, M_FATAL, 0, _("No drive letters found for generating VSS snapshots.\n")); } } else { berrno be; Jmsg(jcr, M_FATAL, 0, _("VSS was not initialized properly. ERR=%s\n"), be.bstrerror()); } run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS", (jcr->director && jcr->director->allowed_script_dirs) ? jcr->director->allowed_script_dirs : me->allowed_script_dirs); } #endif /** * Send Files to Storage daemon */ Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff); if (!blast_data_to_storage_daemon(jcr, NULL)) { jcr->setJobStatus(JS_ErrorTerminated); bnet_suppress_error_messages(sd, 1); Dmsg0(110, "Error in blast_data.\n"); } else { jcr->setJobStatus(JS_Terminated); /* Note, the above set status will not override an error */ if (!jcr->is_terminated_ok()) { bnet_suppress_error_messages(sd, 1); goto cleanup; /* bail out now */ } /** * Expect to get response to append_data from Storage daemon */ if (!response(jcr, sd, OK_append, "Append Data")) { jcr->setJobStatus(JS_ErrorTerminated); goto cleanup; } /** * Send Append End Data to Storage daemon */ sd->fsend(append_end, jcr->Ticket); /* Get end OK */ if (!response(jcr, sd, OK_end, "Append End")) { jcr->setJobStatus(JS_ErrorTerminated); goto cleanup; } /** * Send Append Close to Storage daemon */ sd->fsend(append_close, jcr->Ticket); while (bget_msg(sd) >= 0) { /* stop on signal or error */ if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) { ok = 1; Dmsg2(200, "SDJobStatus = %d %c\n", SDJobStatus, (char)SDJobStatus); } } if (!ok) { Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n")); goto cleanup; } if (!(SDJobStatus == JS_Terminated || SDJobStatus == JS_Warnings)) { Jmsg(jcr, M_FATAL, 0, _("Bad status %d returned from Storage Daemon.\n"), SDJobStatus); } } cleanup: #if defined(WIN32_VSS) if (jcr->VSS) { Win32ConvCleanupCache(); g_pVSSClient->DestroyWriterInfo(); V(vss_mutex); } #endif generate_plugin_event(jcr, bEventEndBackupJob); return false; /* return and stop command loop */ } /** * Do a Verify for Director * */ static bool verify_cmd(JCR *jcr) { char level[100]; BSOCK *dir = jcr->dir_bsock; BSOCK *sd = jcr->store_bsock; /* * See if we are allowed to run verify cmds. */ if (!validate_command(jcr, "verify", (jcr->director && jcr->director->allowed_job_cmds) ? jcr->director->allowed_job_cmds : me->allowed_job_cmds)) { dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg); return 0; } jcr->setJobType(JT_VERIFY); if (sscanf(dir->msg, verifycmd, level) != 1) { dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg); return false; } if (bstrcasecmp(level, "init")) { jcr->setJobLevel(L_VERIFY_INIT); } else if (bstrcasecmp(level, "catalog")){ jcr->setJobLevel(L_VERIFY_CATALOG); } else if (bstrcasecmp(level, "volume")){ jcr->setJobLevel(L_VERIFY_VOLUME_TO_CATALOG); } else if (bstrcasecmp(level, "data")){ jcr->setJobLevel(L_VERIFY_DATA); } else if (bstrcasecmp(level, "disk_to_catalog")) { jcr->setJobLevel(L_VERIFY_DISK_TO_CATALOG); } else { dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg); return false; } dir->fsend(OKverify); generate_plugin_event(jcr, bEventLevel,(void *)(intptr_t)jcr->getJobLevel()); generate_plugin_event(jcr, bEventStartVerifyJob); Dmsg1(110, "filed>dird: %s", dir->msg); switch (jcr->getJobLevel()) { case L_VERIFY_INIT: case L_VERIFY_CATALOG: do_verify(jcr); break; case L_VERIFY_VOLUME_TO_CATALOG: if (!open_sd_read_session(jcr)) { return false; } start_dir_heartbeat(jcr); do_verify_volume(jcr); stop_dir_heartbeat(jcr); /* * Send Close session command to Storage daemon */ sd->fsend(read_close, jcr->Ticket); Dmsg1(130, "filed>stored: %s", sd->msg); /* ****FIXME**** check response */ bget_msg(sd); /* get OK */ /* Inform Storage daemon that we are done */ sd->signal(BNET_TERMINATE); break; case L_VERIFY_DISK_TO_CATALOG: do_verify(jcr); break; default: dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg); return false; } dir->signal(BNET_EOD); generate_plugin_event(jcr, bEventEndVerifyJob); return false; /* return and terminate command loop */ } #if 0 #ifdef WIN32_VSS static bool vss_restore_init_callback(JCR *jcr, int init_type) { switch (init_type) { case VSS_INIT_RESTORE_AFTER_INIT: generate_plugin_event(jcr, bEventVssRestoreLoadComponentMetadata); return true; case VSS_INIT_RESTORE_AFTER_GATHER: generate_plugin_event(jcr, bEventVssRestoreSetComponentsSelected); return true; default: return false; break; } } #endif #endif /** * Do a Restore for Director * */ static bool restore_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; BSOCK *sd = jcr->store_bsock; POOLMEM *args; bool use_regexwhere = false; bool retval; int prefix_links; char replace; /* * See if we are in backup only mode then we don't allow a restore to be initiated. */ if (backup_only_mode) { Jmsg(jcr, M_FATAL, 0, _("Filed in backup only mode, restores are not allowed, aborting...\n")); return false; } /* * See if we are allowed to run restore cmds. */ if (!validate_command(jcr, "restore", (jcr->director && jcr->director->allowed_job_cmds) ? jcr->director->allowed_job_cmds : me->allowed_job_cmds)) { return 0; } /** * Scan WHERE (base directory for restore) from command */ Dmsg0(100, "restore command\n"); #if defined(WIN32_VSS) /** * No need to enable VSS for restore if we do not have plugin data to restore */ enable_vss = jcr->got_metadata; Dmsg2(50, "g_pVSSClient = %p, enable_vss = %d\n", g_pVSSClient, enable_vss); /* * Capture state here, if client is backed up by multiple directors * and one enables vss and the other does not then enable_vss can change * between here and where its evaluated after the job completes. */ jcr->VSS = g_pVSSClient && enable_vss; if (jcr->VSS) { /* * Run only one at a time */ P(vss_mutex); } #endif /* * Pickup where string */ args = get_memory(dir->msglen+1); *args = 0; if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, args) != 3) { if (sscanf(dir->msg, restorecmdR, &replace, &prefix_links, args) != 3){ if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg); return false; } *args = 0; } use_regexwhere = true; } /* Turn / into nothing */ if (IsPathSeparator(args[0]) && args[1] == '\0') { args[0] = '\0'; } Dmsg2(150, "Got replace %c, where=%s\n", replace, args); unbash_spaces(args); /* Keep track of newly created directories to apply them correct attributes */ if (replace == REPLACE_NEVER) { jcr->keep_path_list = true; } if (use_regexwhere) { jcr->where_bregexp = get_bregexps(args); if (!jcr->where_bregexp) { Jmsg(jcr, M_FATAL, 0, _("Bad where regexp. where=%s\n"), args); free_pool_memory(args); return false; } } else { jcr->where = bstrdup(args); } free_pool_memory(args); jcr->replace = replace; jcr->prefix_links = prefix_links; dir->fsend(OKrestore); Dmsg1(110, "filed>dird: %s", dir->msg); jcr->setJobType(JT_RESTORE); jcr->setJobStatus(JS_Blocked); if (!open_sd_read_session(jcr)) { jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } jcr->setJobStatus(JS_Running); /** * Do restore of files and data */ start_dir_heartbeat(jcr); generate_plugin_event(jcr, bEventStartRestoreJob); #if defined(WIN32_VSS) /* START VSS ON WIN32 */ if (jcr->VSS) { if (!g_pVSSClient->InitializeForRestore(jcr)) { berrno be; Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror()); } //free_and_null_pool_memory(jcr->job_metadata); run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS", (jcr->director && jcr->director->allowed_script_dirs) ? jcr->director->allowed_script_dirs : me->allowed_script_dirs); } #endif do_restore(jcr); stop_dir_heartbeat(jcr); jcr->setJobStatus(JS_Terminated); if (!jcr->is_JobStatus(JS_Terminated)) { bnet_suppress_error_messages(sd, 1); } /** * Send Close session command to Storage daemon */ sd->fsend(read_close, jcr->Ticket); Dmsg1(100, "filed>stored: %s", sd->msg); bget_msg(sd); /* get OK */ /* Inform Storage daemon that we are done */ sd->signal(BNET_TERMINATE); #if defined(WIN32_VSS) /* STOP VSS ON WIN32 */ /* tell vss to close the restore session */ Dmsg0(100, "About to call CloseRestore\n"); if (jcr->VSS) { #if 0 generate_plugin_event(jcr, bEventVssBeforeCloseRestore); #endif Dmsg0(100, "Really about to call CloseRestore\n"); if (g_pVSSClient->CloseRestore()) { Dmsg0(100, "CloseRestore success\n"); #if 0 /* inform user about writer states */ for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) { int msg_type = M_INFO; if (g_pVSSClient->GetWriterState(i) < 1) { //msg_type = M_WARNING; //jcr->JobErrors++; } Jmsg(jcr, msg_type, 0, _("VSS Writer (RestoreComplete): %s\n"), g_pVSSClient->GetWriterInfo(i)); } #endif } else Dmsg1(100, "CloseRestore fail - %08x\n", errno); V(vss_mutex); } #endif bail_out: bfree_and_null(jcr->where); if (jcr->JobErrors) { jcr->setJobStatus(JS_ErrorTerminated); } Dmsg0(100, "Done in job.c\n"); if (jcr->multi_restore) { Dmsg0(100, OKstoreend); dir->fsend(OKstoreend); retval = true; /* we continue the loop, waiting for next part */ } else { retval = false; /* we stop here */ } if (job_canceled(jcr)) { retval = false; /* we stop here */ } if (!retval) { end_restore_cmd(jcr); /* stopping so send bEventEndRestoreJob */ } return retval; } static bool end_restore_cmd(JCR *jcr) { Dmsg0(5, "end_restore_cmd\n"); generate_plugin_event(jcr, bEventEndRestoreJob); return false; /* return and terminate command loop */ } static bool open_sd_read_session(JCR *jcr) { BSOCK *sd = jcr->store_bsock; if (!sd) { Jmsg(jcr, M_FATAL, 0, _("Improper calling sequence.\n")); return false; } Dmsg4(120, "VolSessId=%ld VolsessT=%ld SF=%ld EF=%ld\n", jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile); Dmsg2(120, "JobId=%d vol=%s\n", jcr->JobId, "DummyVolume"); /* * Open Read Session with Storage daemon */ sd->fsend(read_open, "DummyVolume", jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile, jcr->StartBlock, jcr->EndBlock); Dmsg1(110, ">stored: %s", sd->msg); /* * Get ticket number */ if (bget_msg(sd) >= 0) { Dmsg1(110, "filedmsg); if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) { Jmsg(jcr, M_FATAL, 0, _("Bad response to SD read open: %s\n"), sd->msg); return false; } Dmsg1(110, "filed: got Ticket=%d\n", jcr->Ticket); } else { Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to read open command\n")); return false; } /* * Start read of data with Storage daemon */ sd->fsend(read_data, jcr->Ticket); Dmsg1(110, ">stored: %s", sd->msg); /* * Get OK data */ if (!response(jcr, sd, OK_data, "Read Data")) { return false; } return true; } /** * Destroy the Job Control Record and associated * resources (sockets). */ static void filed_free_jcr(JCR *jcr) { if (jcr->store_bsock) { jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; } if (jcr->dir_bsock) { jcr->dir_bsock->close(); delete jcr->dir_bsock; jcr->dir_bsock = NULL; } if (jcr->last_fname) { free_pool_memory(jcr->last_fname); } free_bootstrap(jcr); free_runscripts(jcr->RunScripts); delete jcr->RunScripts; if (jcr->path_list) { free_path_list(jcr->path_list); jcr->path_list = NULL; } if (jcr->JobId != 0) { write_state_file(me->working_directory, "bareos-fd", get_first_port_host_order(me->FDaddrs)); } return; } /** * Get response from Storage daemon to a command we * sent. Check that the response is OK. * * Returns: false on failure * true on success */ bool response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd) { if (sd->errors) { return false; } if (bget_msg(sd) > 0) { Dmsg0(110, sd->msg); if (bstrcmp(sd->msg, resp)) { return true; } } if (job_canceled(jcr)) { return false; /* if canceled avoid useless error messages */ } if (is_bnet_error(sd)) { Jmsg2(jcr, M_FATAL, 0, _("Comm error with SD. bad response to %s. ERR=%s\n"), cmd, bnet_strerror(sd)); } else { Jmsg3(jcr, M_FATAL, 0, _("Bad response to %s command. Wanted %s, got %s\n"), cmd, resp, sd->msg); } return false; } bareos-Release-14.2.6/src/filed/estimate.c000066400000000000000000000060521263011562700202740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon estimate.c * Make and estimate of the number of files and size to be saved. * * Kern Sibbald, September MMI */ #include "bareos.h" #include "filed.h" static int tally_file(JCR *jcr, FF_PKT *ff_pkt, bool); /* * Find all the requested files and count them. */ int make_estimate(JCR *jcr) { int status; jcr->setJobStatus(JS_Running); set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime); /* in accurate mode, we overwrite the find_one check function */ if (jcr->accurate) { set_find_changed_function((FF_PKT *)jcr->ff, accurate_check_file); } status = find_files(jcr, (FF_PKT *)jcr->ff, tally_file, plugin_estimate); accurate_free(jcr); return status; } /* * Called here by find() for each file included. * */ static int tally_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { ATTR attr; if (job_canceled(jcr)) { return 0; } switch (ff_pkt->type) { case FT_LNKSAVED: /* Hard linked, file already saved */ case FT_REGE: case FT_REG: case FT_LNK: case FT_NORECURSE: case FT_NOFSCHG: case FT_INVALIDFS: case FT_INVALIDDT: case FT_REPARSE: case FT_JUNCTION: case FT_DIREND: case FT_SPEC: case FT_RAW: case FT_FIFO: break; case FT_DIRBEGIN: case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: case FT_DIRNOCHG: case FT_NOCHG: case FT_ISARCH: case FT_NOOPEN: default: return 1; } if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) { if (ff_pkt->statp.st_size > 0) { jcr->JobBytes += ff_pkt->statp.st_size; } #ifdef HAVE_DARWIN_OS if (bit_is_set(FO_HFSPLUS, ff_pkt->flags)) { if (ff_pkt->hfsinfo.rsrclength > 0) { jcr->JobBytes += ff_pkt->hfsinfo.rsrclength; } jcr->JobBytes += 32; /* Finder info */ } #endif } jcr->num_files_examined++; jcr->JobFiles++; /* increment number of files seen */ if (jcr->listing) { memcpy(&attr.statp, &ff_pkt->statp, sizeof(struct stat)); attr.type = ff_pkt->type; attr.ofname = (POOLMEM *)ff_pkt->fname; attr.olname = (POOLMEM *)ff_pkt->link; print_ls_output(jcr, &attr); } return 1; } bareos-Release-14.2.6/src/filed/fd_plugins.c000066400000000000000000002031601263011562700206120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos pluginloader * * Kern Sibbald, October 2007 */ #include "bareos.h" #include "filed.h" extern CLIENTRES *me; extern DLL_IMP_EXP char *exepath; extern DLL_IMP_EXP char *version; extern DLL_IMP_EXP char *dist_name; const int dbglvl = 150; #ifdef HAVE_WIN32 const char *plugin_type = "-fd.dll"; #else const char *plugin_type = "-fd.so"; #endif static alist *fd_plugin_list = NULL; extern int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level); extern bool check_changes(JCR *jcr, FF_PKT *ff_pkt); /* * Function pointers to be set here */ extern DLL_IMP_EXP int (*plugin_bopen)(BFILE *bfd, const char *fname, int flags, mode_t mode); extern DLL_IMP_EXP int (*plugin_bclose)(BFILE *bfd); extern DLL_IMP_EXP ssize_t (*plugin_bread)(BFILE *bfd, void *buf, size_t count); extern DLL_IMP_EXP ssize_t (*plugin_bwrite)(BFILE *bfd, void *buf, size_t count); extern DLL_IMP_EXP boffset_t (*plugin_blseek)(BFILE *bfd, boffset_t offset, int whence); /* * Forward referenced functions */ static bRC bareosGetValue(bpContext *ctx, bVariable var, void *value); static bRC bareosSetValue(bpContext *ctx, bVariable var, void *value); static bRC bareosRegisterEvents(bpContext *ctx, int nr_events, ...); static bRC bareosJobMsg(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); static bRC bareosDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); static void *bareosMalloc(bpContext *ctx, const char *file, int line, size_t size); static void bareosFree(bpContext *ctx, const char *file, int line, void *mem); static bRC bareosAddExclude(bpContext *ctx, const char *file); static bRC bareosAddInclude(bpContext *ctx, const char *file); static bRC bareosAddOptions(bpContext *ctx, const char *opts); static bRC bareosAddRegex(bpContext *ctx, const char *item, int type); static bRC bareosAddWild(bpContext *ctx, const char *item, int type); static bRC bareosNewOptions(bpContext *ctx); static bRC bareosNewInclude(bpContext *ctx); static bRC bareosNewPreInclude(bpContext *ctx); static bool is_plugin_compatible(Plugin *plugin); static bool get_plugin_name(JCR *jcr, char *cmd, int *ret); static bRC bareosCheckChanges(bpContext *ctx, struct save_pkt *sp); static bRC bareosAcceptFile(bpContext *ctx, struct save_pkt *sp); /* * These will be plugged into the global pointer structure for the findlib. */ static int my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode); static int my_plugin_bclose(BFILE *bfd); static ssize_t my_plugin_bread(BFILE *bfd, void *buf, size_t count); static ssize_t my_plugin_bwrite(BFILE *bfd, void *buf, size_t count); static boffset_t my_plugin_blseek(BFILE *bfd, boffset_t offset, int whence); /* Bareos info */ static bInfo binfo = { sizeof(bInfo), FD_PLUGIN_INTERFACE_VERSION }; /* Bareos entry points */ static bFuncs bfuncs = { sizeof(bFuncs), FD_PLUGIN_INTERFACE_VERSION, bareosRegisterEvents, bareosGetValue, bareosSetValue, bareosJobMsg, bareosDebugMsg, bareosMalloc, bareosFree, bareosAddExclude, bareosAddInclude, bareosAddOptions, bareosAddRegex, bareosAddWild, bareosNewOptions, bareosNewInclude, bareosNewPreInclude, bareosCheckChanges, bareosAcceptFile }; /* * Bareos private context */ struct b_plugin_ctx { JCR *jcr; /* jcr for plugin */ bRC ret; /* last return code */ bool disabled; /* set if plugin disabled */ bool restoreFileStarted; bool createFileCalled; char events[nbytes_for_bits(FD_NR_EVENTS + 1)]; /* enabled events bitmask */ findINCEXE *exclude; /* pointer to exclude files */ findINCEXE *include; /* pointer to include/exclude files */ }; static inline bool is_event_enabled(bpContext *ctx, bEventType eventType) { b_plugin_ctx *b_ctx; if (!ctx) { return false; } b_ctx = (b_plugin_ctx *)ctx->bContext; if (!b_ctx) { return false; } return bit_is_set(eventType, b_ctx->events); } static inline bool is_plugin_disabled(bpContext *ctx) { b_plugin_ctx *b_ctx; if (!ctx) { return true; } b_ctx = (b_plugin_ctx *)ctx->bContext; if (!b_ctx) { return true; } return b_ctx->disabled; } /** * Test if event is for this plugin */ static bool for_this_plugin(Plugin *plugin, char *name, int len) { Dmsg4(dbglvl, "name=%s len=%d plugin=%s plen=%d\n", name, len, plugin->file, plugin->file_len); if (!name) { /* if no plugin name, all plugins get it */ return true; } /* * Return global VSS job metadata to all plugins */ if (bstrcmp("job", name)) { /* old V4.0 name for VSS job metadata */ return true; } if (bstrcmp("*all*", name)) { /* new v6.0 name for VSS job metadata */ return true; } /* * Check if this is the correct plugin */ if (len == plugin->file_len && bstrncmp(plugin->file, name, len)) { return true; } return false; } /** * Raise a certain plugin event. */ static inline bRC trigger_plugin_event(JCR *jcr, bEventType eventType, bEvent *event, bpContext *ctx, void *value) { if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); return bRC_OK; } if (is_plugin_disabled(ctx)) { return bRC_OK; } if (eventType == bEventEndRestoreJob) { b_plugin_ctx *b_ctx = (b_plugin_ctx *)ctx->bContext; Dmsg0(50, "eventType == bEventEndRestoreJob\n"); if (b_ctx && b_ctx->restoreFileStarted) { plug_func(ctx->plugin)->endRestoreFile(ctx); } if (b_ctx) { b_ctx->restoreFileStarted = false; b_ctx->createFileCalled = false; } } return plug_func(ctx->plugin)->handlePluginEvent(ctx, event, value); } /** * Create a plugin event When receiving bEventCancelCommand, this function is called by an other thread. */ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value, bool reverse) { bEvent event; char *name = NULL; int i; int len = 0; bool call_if_canceled = false; restore_object_pkt *rop; bpContext *ctx; alist *plugin_ctx_list; if (!fd_plugin_list || !jcr || !jcr->plugin_ctx_list) { return; /* Return if no plugins loaded */ } plugin_ctx_list = jcr->plugin_ctx_list; /* * Some events are sent to only a particular plugin or must be called even if the job is canceled. */ switch(eventType) { case bEventPluginCommand: case bEventOptionPlugin: name = (char *)value; if (!get_plugin_name(jcr, name, &len)) { return; } break; case bEventRestoreObject: /* * After all RestoreObject, we have it one more time with value = NULL */ if (value) { /* * Some RestoreObjects may not have a plugin name */ rop = (restore_object_pkt *)value; if (*rop->plugin_name) { name = rop->plugin_name; if (!get_plugin_name(jcr, name, &len)) { return; } } } break; case bEventEndBackupJob: case bEventEndVerifyJob: call_if_canceled = true; /* plugin *must* see this call */ break; case bEventStartRestoreJob: foreach_alist(ctx, plugin_ctx_list) { ((b_plugin_ctx *)ctx->bContext)->restoreFileStarted = false; ((b_plugin_ctx *)ctx->bContext)->createFileCalled = false; } break; case bEventEndRestoreJob: call_if_canceled = true; /* plugin *must* see this call */ break; default: break; } /* * If call_if_canceled is set, we call the plugin anyway */ if (!call_if_canceled && jcr->is_job_canceled()) { return; } event.eventType = eventType; Dmsg2(dbglvl, "plugin_ctx=%p JobId=%d\n", plugin_ctx_list, jcr->JobId); /* * Pass event to every plugin that has requested this event type (except if name is set). * If name is set, we pass it only to the plugin with that name. * * See if we need to trigger the loaded plugins in reverse order. */ if (reverse) { foreach_alist_rindex(i, ctx, plugin_ctx_list) { if (!for_this_plugin(ctx->plugin, name, len)) { Dmsg2(dbglvl, "Not for this plugin name=%s NULL=%d\n", name, (name == NULL) ? 1 : 0); continue; } trigger_plugin_event(jcr, eventType, &event, ctx, value); } } else { foreach_alist_index(i, ctx, plugin_ctx_list) { if (!for_this_plugin(ctx->plugin, name, len)) { Dmsg2(dbglvl, "Not for this plugin name=%s NULL=%d\n", name, (name == NULL) ? 1 : 0); continue; } trigger_plugin_event(jcr, eventType, &event, ctx, value); } } return; } /** * Check if file was seen for accurate */ bool plugin_check_file(JCR *jcr, char *fname) { bpContext *ctx; alist *plugin_ctx_list; int ret = bRC_OK; if (!fd_plugin_list || !jcr || !jcr->plugin_ctx_list || jcr->is_job_canceled()) { return false; /* Return if no plugins loaded */ } plugin_ctx_list = jcr->plugin_ctx_list; Dmsg2(dbglvl, "plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); /* * Pass event to every plugin */ foreach_alist(ctx, plugin_ctx_list) { if (is_plugin_disabled(ctx)) { continue; } jcr->plugin_ctx = ctx; if (plug_func(ctx->plugin)->checkFile == NULL) { continue; } ret = plug_func(ctx->plugin)->checkFile(ctx, fname); if (ret == bRC_Seen) { break; } } return ret == bRC_Seen; } /** * Get the first part of the the plugin command * systemstate:/@SYSTEMSTATE/ * => ret = 11 * => can use for_this_plugin(plug, cmd, ret); * * The plugin command can contain only the plugin name * Plugin = alldrives * => ret = 9 */ static bool get_plugin_name(JCR *jcr, char *cmd, int *ret) { char *p; int len; if (!cmd || (*cmd == '\0')) { return false; } /* * Handle plugin command here backup */ Dmsg1(dbglvl, "plugin cmd=%s\n", cmd); if ((p = strchr(cmd, ':')) == NULL) { if (strchr(cmd, ' ') == NULL) { /* we have just the plugin name */ len = strlen(cmd); } else { Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd); return false; } } else { /* plugin:argument */ len = p - cmd; if (len <= 0) { return false; } } *ret = len; return true; } void plugin_update_ff_pkt(FF_PKT *ff_pkt, struct save_pkt *sp) { ff_pkt->no_read = sp->no_read; ff_pkt->delta_seq = sp->delta_seq; if (bit_is_set(FO_DELTA, sp->flags)) { set_bit(FO_DELTA, ff_pkt->flags); ff_pkt->delta_seq++; /* make new delta sequence number */ } else { clear_bit(FO_DELTA, ff_pkt->flags); ff_pkt->delta_seq = 0; /* clean delta sequence number */ } if (bit_is_set(FO_OFFSETS, sp->flags)) { set_bit(FO_OFFSETS, ff_pkt->flags); } else { clear_bit(FO_OFFSETS, ff_pkt->flags); } /* * Sparse code doesn't work with plugins * that use FIFO or STDOUT/IN to communicate */ if (bit_is_set(FO_SPARSE, sp->flags)) { set_bit(FO_SPARSE, ff_pkt->flags); } else { clear_bit(FO_SPARSE, ff_pkt->flags); } if (bit_is_set(FO_PORTABLE_DATA, sp->flags)) { set_bit(FO_PORTABLE_DATA, ff_pkt->flags); } else { clear_bit(FO_PORTABLE_DATA, ff_pkt->flags); } set_bit(FO_PLUGIN, ff_pkt->flags); /* data from plugin */ } /** * Ask to a Option Plugin what to do with the current file */ bRC plugin_option_handle_file(JCR *jcr, FF_PKT *ff_pkt, struct save_pkt *sp) { int len; char *cmd; bRC ret = bRC_Core; bEvent event; bEventType eventType; bpContext *ctx; alist *plugin_ctx_list; cmd = ff_pkt->plugin; eventType = bEventHandleBackupFile; event.eventType = eventType; memset(sp, 0, sizeof(struct save_pkt)); sp->pkt_size = sp->pkt_end = sizeof(struct save_pkt); sp->portable = true; copy_bits(FO_MAX, ff_pkt->flags, sp->flags); sp->cmd = cmd; sp->link = ff_pkt->link; sp->statp = ff_pkt->statp; sp->type = ff_pkt->type; sp->fname = ff_pkt->fname; sp->delta_seq = ff_pkt->delta_seq; sp->accurate_found = ff_pkt->accurate_found; plugin_ctx_list = jcr->plugin_ctx_list; if (!fd_plugin_list || !plugin_ctx_list || jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" requested, but is not loaded.\n", cmd); goto bail_out; /* Return if no plugins loaded */ } if (!get_plugin_name(jcr, cmd, &len)) { goto bail_out; } /* * Note, we stop the loop on the first plugin that matches the name */ foreach_alist(ctx, plugin_ctx_list) { Dmsg4(dbglvl, "plugin=%s plen=%d cmd=%s len=%d\n", ctx->plugin->file, ctx->plugin->file_len, cmd, len); if (!for_this_plugin(ctx->plugin, cmd, len)) { continue; } if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); continue; } if (is_plugin_disabled(ctx)) { goto bail_out; } jcr->plugin_ctx = ctx; ret = plug_func(ctx->plugin)->handlePluginEvent(ctx, &event, sp); goto bail_out; } /* end foreach loop */ bail_out: return ret; } /** * Sequence of calls for a backup: * 1. plugin_save() here is called with ff_pkt * 2. we find the plugin requested on the command string * 3. we generate a bEventBackupCommand event to the specified plugin * and pass it the command string. * 4. we make a startPluginBackup call to the plugin, which gives * us the data we need in save_pkt * 5. we call Bareos's save_file() subroutine to save the specified * file. The plugin will be called at pluginIO() to supply the * file data. * * Sequence of calls for restore: * See subroutine plugin_name_stream() below. */ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { int len; bRC ret; char *cmd; bEvent event; bpContext *ctx; struct save_pkt sp; bEventType eventType; POOL_MEM fname(PM_FNAME); POOL_MEM link(PM_FNAME); alist *plugin_ctx_list; char flags[FOPTS_BYTES]; cmd = ff_pkt->top_fname; plugin_ctx_list = jcr->plugin_ctx_list; if (!fd_plugin_list || !plugin_ctx_list || jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" requested, but is not loaded.\n", cmd); return 1; /* Return if no plugins loaded */ } jcr->cmd_plugin = true; eventType = bEventBackupCommand; event.eventType = eventType; if (!get_plugin_name(jcr, cmd, &len)) { goto bail_out; } /* * Note, we stop the loop on the first plugin that matches the name */ foreach_alist(ctx, plugin_ctx_list) { Dmsg4(dbglvl, "plugin=%s plen=%d cmd=%s len=%d\n", ctx->plugin->file, ctx->plugin->file_len, cmd, len); if (!for_this_plugin(ctx->plugin, cmd, len)) { continue; } /* * We put the current plugin pointer, and the plugin context into the jcr, because during save_file(), * the plugin will be called many times and these values are needed. */ if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); continue; } if (is_plugin_disabled(ctx)) { goto bail_out; } jcr->plugin_ctx = ctx; /* * Send the backup command to the right plugin */ Dmsg1(dbglvl, "Command plugin = %s\n", cmd); if (plug_func(ctx->plugin)->handlePluginEvent(jcr->plugin_ctx, &event, cmd) != bRC_OK) { goto bail_out; } /* * Loop getting filenames to backup then saving them */ while (!jcr->is_job_canceled()) { memset(&sp, 0, sizeof(sp)); sp.pkt_size = sizeof(sp); sp.pkt_end = sizeof(sp); sp.portable = true; sp.no_read = false; copy_bits(FO_MAX, ff_pkt->flags, sp.flags); sp.cmd = cmd; Dmsg3(dbglvl, "startBackup st_size=%p st_blocks=%p sp=%p\n", &sp.statp.st_size, &sp.statp.st_blocks, &sp); /* * Get the file save parameters. I.e. the stat pkt ... */ if (plug_func(ctx->plugin)->startBackupFile(ctx, &sp) != bRC_OK) { goto bail_out; } if (sp.type == 0) { Jmsg1(jcr, M_FATAL, 0, _("Command plugin \"%s\": no type in startBackupFile packet.\n"), cmd); goto bail_out; } jcr->plugin_sp = &sp; ff_pkt = jcr->ff; /* * Save original flags. */ copy_bits(FO_MAX, ff_pkt->flags, flags); /* * Copy fname and link because save_file() zaps them. This avoids zaping the plugin's strings. */ ff_pkt->type = sp.type; if (IS_FT_OBJECT(sp.type)) { if (!sp.object_name) { Jmsg1(jcr, M_FATAL, 0, _("Command plugin \"%s\": no object_name in startBackupFile packet.\n"), cmd); goto bail_out; } ff_pkt->fname = cmd; /* full plugin string */ ff_pkt->object_name = sp.object_name; ff_pkt->object_index = sp.index; /* restore object index */ ff_pkt->object_compression = 0; /* no compression for now */ ff_pkt->object = sp.object; ff_pkt->object_len = sp.object_len; } else { if (!sp.fname) { Jmsg1(jcr, M_FATAL, 0, _("Command plugin \"%s\": no fname in startBackupFile packet.\n"), cmd); goto bail_out; } pm_strcpy(fname, sp.fname); pm_strcpy(link, sp.link); ff_pkt->fname = fname.c_str(); ff_pkt->link = link.c_str(); plugin_update_ff_pkt(ff_pkt, &sp); } memcpy(&ff_pkt->statp, &sp.statp, sizeof(ff_pkt->statp)); Dmsg2(dbglvl, "startBackup returned type=%d, fname=%s\n", sp.type, sp.fname); if (sp.object) { Dmsg2(dbglvl, "index=%d object=%s\n", sp.index, sp.object); } /* * Handle hard linked files * * Maintain a list of hard linked files already backed up. This allows us to ensure * that the data of each file gets backed up only once. */ ff_pkt->LinkFI = 0; if (!bit_is_set(FO_NO_HARDLINK, ff_pkt->flags) && ff_pkt->statp.st_nlink > 1) { CurLink *hl; switch (ff_pkt->statp.st_mode & S_IFMT) { case S_IFREG: case S_IFCHR: case S_IFBLK: case S_IFIFO: #ifdef S_IFSOCK case S_IFSOCK: #endif hl = lookup_hardlink(jcr, ff_pkt, ff_pkt->statp.st_ino, ff_pkt->statp.st_dev); if (hl) { /* * If we have already backed up the hard linked file don't do it again */ if (bstrcmp(hl->name, sp.fname)) { Dmsg2(400, "== Name identical skip FI=%d file=%s\n", hl->FileIndex, fname.c_str()); ff_pkt->no_read = true; } else { ff_pkt->link = hl->name; ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */ ff_pkt->LinkFI = hl->FileIndex; ff_pkt->linked = NULL; ff_pkt->digest = hl->digest; ff_pkt->digest_stream = hl->digest_stream; ff_pkt->digest_len = hl->digest_len; Dmsg3(400, "FT_LNKSAVED FI=%d LinkFI=%d file=%s\n", ff_pkt->FileIndex, hl->FileIndex, hl->name); ff_pkt->no_read = true; } } else { /* * File not previously dumped. Chain it into our list. */ hl = new_hardlink(jcr, ff_pkt, sp.fname, ff_pkt->statp.st_ino, ff_pkt->statp.st_dev); ff_pkt->linked = hl; /* Mark saved link */ Dmsg2(400, "Added to hash FI=%d file=%s\n", ff_pkt->FileIndex, hl->name); } break; default: ff_pkt->linked = NULL; break; } } else { ff_pkt->linked = NULL; } /* * Call Bareos core code to backup the plugin's file */ save_file(jcr, ff_pkt, true); /* * Restore original flags. */ copy_bits(FO_MAX, flags, ff_pkt->flags); ret = plug_func(ctx->plugin)->endBackupFile(ctx); if (ret == bRC_More || ret == bRC_OK) { accurate_mark_file_as_seen(jcr, fname.c_str()); } if (ret == bRC_More) { continue; } goto bail_out; } /* end while loop */ goto bail_out; } /* end loop over all plugins */ Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" not found.\n", cmd); bail_out: jcr->cmd_plugin = false; return 1; } /** * Sequence of calls for a estimate: * 1. plugin_estimate() here is called with ff_pkt * 2. we find the plugin requested on the command string * 3. we generate a bEventEstimateCommand event to the specified plugin * and pass it the command string. * 4. we make a startPluginBackup call to the plugin, which gives * us the data we need in save_pkt * */ int plugin_estimate(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { int len; char *cmd = ff_pkt->top_fname; struct save_pkt sp; bEvent event; bEventType eventType; POOL_MEM fname(PM_FNAME); POOL_MEM link(PM_FNAME); bpContext *ctx; alist *plugin_ctx_list; ATTR attr; plugin_ctx_list = jcr->plugin_ctx_list; if (!fd_plugin_list || !plugin_ctx_list) { Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" requested, but is not loaded.\n", cmd); return 1; /* Return if no plugins loaded */ } jcr->cmd_plugin = true; eventType = bEventEstimateCommand; event.eventType = eventType; if (!get_plugin_name(jcr, cmd, &len)) { goto bail_out; } /* * Note, we stop the loop on the first plugin that matches the name */ foreach_alist(ctx, plugin_ctx_list) { Dmsg4(dbglvl, "plugin=%s plen=%d cmd=%s len=%d\n", ctx->plugin->file, ctx->plugin->file_len, cmd, len); if (!for_this_plugin(ctx->plugin, cmd, len)) { continue; } /* * We put the current plugin pointer, and the plugin context into the jcr, because during save_file(), * the plugin will be called many times and these values are needed. */ if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); continue; } if (is_plugin_disabled(ctx)) { goto bail_out; } jcr->plugin_ctx = ctx; /* * Send the backup command to the right plugin */ Dmsg1(dbglvl, "Command plugin = %s\n", cmd); if (plug_func(ctx->plugin)->handlePluginEvent(ctx, &event, cmd) != bRC_OK) { goto bail_out; } /* * Loop getting filenames to backup then saving them */ while (!jcr->is_job_canceled()) { memset(&sp, 0, sizeof(sp)); sp.pkt_size = sizeof(sp); sp.pkt_end = sizeof(sp); sp.portable = true; copy_bits(FO_MAX, ff_pkt->flags, sp.flags); sp.cmd = cmd; Dmsg3(dbglvl, "startBackup st_size=%p st_blocks=%p sp=%p\n", &sp.statp.st_size, &sp.statp.st_blocks, &sp); /* * Get the file save parameters. I.e. the stat pkt ... */ if (plug_func(ctx->plugin)->startBackupFile(ctx, &sp) != bRC_OK) { goto bail_out; } if (sp.type == 0) { Jmsg1(jcr, M_FATAL, 0, _("Command plugin \"%s\": no type in startBackupFile packet.\n"), cmd); goto bail_out; } if (!IS_FT_OBJECT(sp.type)) { if (!sp.fname) { Jmsg1(jcr, M_FATAL, 0, _("Command plugin \"%s\": no fname in startBackupFile packet.\n"), cmd); goto bail_out; } /* * Count only files backed up */ switch (sp.type) { case FT_REGE: case FT_REG: case FT_LNK: case FT_DIREND: case FT_SPEC: case FT_RAW: case FT_FIFO: case FT_LNKSAVED: jcr->JobFiles++; /* increment number of files backed up */ break; default: break; } jcr->num_files_examined++; if (sp.type != FT_LNKSAVED && S_ISREG(sp.statp.st_mode)) { if (sp.statp.st_size > 0) { jcr->JobBytes += sp.statp.st_size; } } if (jcr->listing) { memcpy(&attr.statp, &sp.statp, sizeof(struct stat)); attr.type = sp.type; attr.ofname = (POOLMEM *)sp.fname; attr.olname = (POOLMEM *)sp.link; print_ls_output(jcr, &attr); } } Dmsg2(dbglvl, "startBackup returned type=%d, fname=%s\n", sp.type, sp.fname); if (sp.object) { Dmsg2(dbglvl, "index=%d object=%s\n", sp.index, sp.object); } bRC ret = plug_func(ctx->plugin)->endBackupFile(ctx); if (ret == bRC_More || ret == bRC_OK) { accurate_mark_file_as_seen(jcr, sp.fname); } if (ret == bRC_More) { continue; } goto bail_out; } /* end while loop */ goto bail_out; } /* end loop over all plugins */ Jmsg1(jcr, M_FATAL, 0, "Command plugin \"%s\" not found.\n", cmd); bail_out: jcr->cmd_plugin = false; return 1; } /** * Send plugin name start/end record to SD */ bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start) { int status; int index = jcr->JobFiles; struct save_pkt *sp = (struct save_pkt *)jcr->plugin_sp; if (!sp) { Jmsg0(jcr, M_FATAL, 0, _("Plugin save packet not found.\n")); return false; } if (jcr->is_job_canceled()) { return false; } if (start) { index++; /* JobFiles not incremented yet */ } Dmsg1(dbglvl, "send_plugin_name=%s\n", sp->cmd); /* * Send stream header */ if (!sd->fsend("%ld %d 0", index, STREAM_PLUGIN_NAME)) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return false; } Dmsg1(dbglvl, "send plugin name hdr: %s\n", sd->msg); if (start) { /* * Send data -- not much */ status = sd->fsend("%ld 1 %d %s%c", index, sp->portable, sp->cmd, 0); } else { /* * Send end of data */ status = sd->fsend("%ld 0", jcr->JobFiles); } if (!status) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return false; } Dmsg1(dbglvl, "send plugin start/end: %s\n", sd->msg); sd->signal(BNET_EOD); /* indicate end of plugin name data */ return true; } /** * Plugin name stream found during restore. The record passed in argument name was * generated in send_plugin_name() above. * * Returns: true if start of stream * false if end of steam */ bool plugin_name_stream(JCR *jcr, char *name) { int len; char *cmd; char *p = name; bool start; bpContext *ctx; alist *plugin_ctx_list; Dmsg1(dbglvl, "Read plugin stream string=%s\n", name); skip_nonspaces(&p); /* skip over jcr->JobFiles */ skip_spaces(&p); start = *p == '1'; if (start) { /* * Start of plugin data */ skip_nonspaces(&p); /* skip start/end flag */ skip_spaces(&p); skip_nonspaces(&p); /* skip portable flag */ skip_spaces(&p); cmd = p; } else { /* * End of plugin data, notify plugin, then clear flags */ if (jcr->plugin_ctx) { Plugin *plugin = jcr->plugin_ctx->plugin; b_plugin_ctx *b_ctx = (b_plugin_ctx *)jcr->plugin_ctx->bContext; Dmsg2(dbglvl, "End plugin data plugin=%p ctx=%p\n", plugin, jcr->plugin_ctx); if (b_ctx->restoreFileStarted) { plug_func(plugin)->endRestoreFile(jcr->plugin_ctx); } b_ctx->restoreFileStarted = false; b_ctx->createFileCalled = false; } goto bail_out; } plugin_ctx_list = jcr->plugin_ctx_list; if (!plugin_ctx_list) { goto bail_out; } /* * After this point, we are dealing with a restore start */ if (!get_plugin_name(jcr, cmd, &len)) { goto bail_out; } /* * Search for correct plugin as specified on the command */ foreach_alist(ctx, plugin_ctx_list) { bEvent event; bEventType eventType; b_plugin_ctx *b_ctx; Dmsg3(dbglvl, "plugin=%s cmd=%s len=%d\n", ctx->plugin->file, cmd, len); if (!for_this_plugin(ctx->plugin, cmd, len)) { continue; } if (is_plugin_disabled(ctx)) { Dmsg1(dbglvl, "Plugin %s disabled\n", cmd); goto bail_out; } Dmsg1(dbglvl, "Restore Command plugin = %s\n", cmd); eventType = bEventRestoreCommand; event.eventType = eventType; if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); continue; } jcr->plugin_ctx = ctx; jcr->cmd_plugin = true; b_ctx = (b_plugin_ctx *)ctx->bContext; if (plug_func(ctx->plugin)->handlePluginEvent(jcr->plugin_ctx, &event, cmd) != bRC_OK) { Dmsg1(dbglvl, "Handle event failed. Plugin=%s\n", cmd); goto bail_out; } if (b_ctx->restoreFileStarted) { Jmsg2(jcr, M_FATAL, 0, "Second call to startRestoreFile. plugin=%s cmd=%s\n", ctx->plugin->file, cmd); b_ctx->restoreFileStarted = false; goto bail_out; } if (plug_func(ctx->plugin)->startRestoreFile(jcr->plugin_ctx, cmd) == bRC_OK) { b_ctx->restoreFileStarted = true; goto bail_out; } else { Dmsg1(dbglvl, "startRestoreFile failed. plugin=%s\n", cmd); goto bail_out; } } Jmsg1(jcr, M_WARNING, 0, _("Plugin=%s not found.\n"), cmd); bail_out: return start; } /** * Tell the plugin to create the file. this is called only during Restore. * Return values are: * * CF_ERROR -> error * CF_SKIP -> skip processing this file * CF_EXTRACT -> extract the file (i.e.call i/o routines) * CF_CREATED -> created, but no content to extract (typically directories) */ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) { int flags; int ret; int status; Plugin *plugin; struct restore_pkt rp; bpContext *ctx = jcr->plugin_ctx; b_plugin_ctx *b_ctx = (b_plugin_ctx *)jcr->plugin_ctx->bContext; if (!ctx || !set_cmd_plugin(bfd, jcr) || jcr->is_job_canceled()) { return CF_ERROR; } plugin = ctx->plugin; rp.pkt_size = sizeof(rp); rp.pkt_end = sizeof(rp); rp.delta_seq = attr->delta_seq; rp.stream = attr->stream; rp.data_stream = attr->data_stream; rp.type = attr->type; rp.file_index = attr->file_index; rp.LinkFI = attr->LinkFI; rp.uid = attr->uid; memcpy(&rp.statp, &attr->statp, sizeof(rp.statp)); rp.attrEx = attr->attrEx; rp.ofname = attr->ofname; rp.olname = attr->olname; rp.where = jcr->where; rp.RegexWhere = jcr->RegexWhere; rp.replace = jcr->replace; rp.create_status = CF_ERROR; Dmsg4(dbglvl, "call plugin createFile stream=%d type=%d LinkFI=%d File=%s\n", rp.stream, rp.type, rp.LinkFI, rp.ofname); if (rp.attrEx) { Dmsg1(dbglvl, "attrEx=\"%s\"\n", rp.attrEx); } if (!b_ctx->restoreFileStarted || b_ctx->createFileCalled) { Jmsg2(jcr, M_FATAL, 0, "Unbalanced call to createFile=%d %d\n", b_ctx->createFileCalled, b_ctx->restoreFileStarted); b_ctx->createFileCalled = false; return CF_ERROR; } ret = plug_func(plugin)->createFile(ctx, &rp); if (ret != bRC_OK) { Qmsg2(jcr, M_ERROR, 0, _("Plugin createFile call failed. Stat=%d file=%s\n"), ret, attr->ofname); return CF_ERROR; } if (rp.create_status == CF_ERROR) { Qmsg1(jcr, M_ERROR, 0, _("Plugin createFile call failed. Returned CF_ERROR file=%s\n"), attr->ofname); return CF_ERROR; } if (rp.create_status == CF_SKIP) { return CF_SKIP; } if (rp.create_status == CF_CORE) { return CF_CORE; /* Let Bareos core handle the file creation */ } /* * Created link or directory? */ if (rp.create_status == CF_CREATED) { return rp.create_status; /* yes, no need to bopen */ } flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; Dmsg0(dbglvl, "call bopen\n"); status = bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR, attr->statp.st_rdev); Dmsg1(dbglvl, "bopen status=%d\n", status); if (status < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(dbglvl,"Could not bopen file %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } if (!is_bopen(bfd)) { Dmsg0(000, "===== BFD is not open!!!!\n"); } return CF_EXTRACT; } /** * Reset the file attributes after all file I/O is done -- this allows the previous access time/dates * to be set properly, and it also allows us to properly set directory permissions. */ bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { Plugin *plugin; struct restore_pkt rp; Dmsg0(dbglvl, "plugin_set_attributes\n"); if (!jcr->plugin_ctx) { return false; } plugin = (Plugin *)jcr->plugin_ctx->plugin; memset(&rp, 0, sizeof(rp)); rp.pkt_size = sizeof(rp); rp.pkt_end = sizeof(rp); rp.stream = attr->stream; rp.data_stream = attr->data_stream; rp.type = attr->type; rp.file_index = attr->file_index; rp.LinkFI = attr->LinkFI; rp.uid = attr->uid; memcpy(&rp.statp, &attr->statp, sizeof(rp.statp)); rp.attrEx = attr->attrEx; rp.ofname = attr->ofname; rp.olname = attr->olname; rp.where = jcr->where; rp.RegexWhere = jcr->RegexWhere; rp.replace = jcr->replace; rp.create_status = CF_ERROR; plug_func(plugin)->setFileAttributes(jcr->plugin_ctx, &rp); if (rp.create_status == CF_CORE) { set_attributes(jcr, attr, ofd); } else { if (is_bopen(ofd)) { bclose(ofd); } pm_strcpy(attr->ofname, "*none*"); } return true; } /** * Plugin specific callback for getting ACL information. */ bacl_exit_code plugin_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { Plugin *plugin; Dmsg0(dbglvl, "plugin_build_acl_streams\n"); if (!jcr->plugin_ctx) { return bacl_exit_ok; } plugin = (Plugin *)jcr->plugin_ctx->plugin; if (plug_func(plugin)->getAcl == NULL) { return bacl_exit_ok; } else { bacl_exit_code retval = bacl_exit_error; #if defined(HAVE_ACL) struct acl_pkt ap; memset(&ap, 0, sizeof(ap)); ap.pkt_size = ap.pkt_end = sizeof(struct acl_pkt); ap.fname = acl_data->last_fname; switch (plug_func(plugin)->getAcl(jcr->plugin_ctx, &ap)) { case bRC_OK: if (ap.content_length && ap.content) { acl_data->u.build->content = check_pool_memory_size(acl_data->u.build->content, ap.content_length); memcpy(acl_data->u.build->content, ap.content, ap.content_length); acl_data->u.build->content_length = ap.content_length; free(ap.content); retval = send_acl_stream(jcr, acl_data, STREAM_ACL_PLUGIN); } else { retval = bacl_exit_ok; } break; default: break; } #endif return retval; } } /** * Plugin specific callback for setting ACL information. */ bacl_exit_code plugin_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { Plugin *plugin; Dmsg0(dbglvl, "plugin_parse_acl_streams\n"); if (!jcr->plugin_ctx) { return bacl_exit_ok; } plugin = (Plugin *)jcr->plugin_ctx->plugin; if (plug_func(plugin)->setAcl == NULL) { return bacl_exit_error; } else { bacl_exit_code retval = bacl_exit_error; #if defined(HAVE_ACL) struct acl_pkt ap; memset(&ap, 0, sizeof(ap)); ap.pkt_size = ap.pkt_end = sizeof(struct acl_pkt); ap.fname = acl_data->last_fname; ap.content = content; ap.content_length = content_length; switch (plug_func(plugin)->setAcl(jcr->plugin_ctx, &ap)) { case bRC_OK: retval = bacl_exit_ok; break; default: break; } #endif return retval; } } /** * Plugin specific callback for getting XATTR information. */ bxattr_exit_code plugin_build_xattr_streams(JCR *jcr, struct xattr_data_t *xattr_data, FF_PKT *ff_pkt) { Plugin *plugin; #if defined(HAVE_XATTR) alist *xattr_value_list = NULL; #endif bxattr_exit_code retval = bxattr_exit_error; Dmsg0(dbglvl, "plugin_build_xattr_streams\n"); if (!jcr->plugin_ctx) { return bxattr_exit_ok; } plugin = (Plugin *)jcr->plugin_ctx->plugin; if (plug_func(plugin)->getXattr == NULL) { return bxattr_exit_ok; } else { #if defined(HAVE_XATTR) bool more; int xattr_count = 0; xattr_t *current_xattr; struct xattr_pkt xp; uint32_t expected_serialize_len = 0; while (1) { memset(&xp, 0, sizeof(xp)); xp.pkt_size = xp.pkt_end = sizeof(struct xattr_pkt); xp.fname = xattr_data->last_fname; switch (plug_func(plugin)->getXattr(jcr->plugin_ctx, &xp)) { case bRC_OK: more = false; break; case bRC_More: more = true; break; default: goto bail_out; } /* * Make sure the plugin filled a XATTR name. * The name and value returned by the plugin need to be in allocated memory * and are freed by xattr_drop_internal_table() function when we are done * processing the data. */ if (xp.name_length && xp.name) { /* * Each xattr valuepair starts with a magic so we can parse it easier. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); current_xattr->magic = XATTR_MAGIC; expected_serialize_len += sizeof(current_xattr->magic); current_xattr->name_length = xp.name_length; current_xattr->name = xp.name; expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; current_xattr->value_length = xp.value_length; current_xattr->value = xp.value; expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; if (xattr_value_list == NULL) { xattr_value_list = New(alist(10, not_owned_by_alist)); } xattr_value_list->append(current_xattr); xattr_count++; /* * Protect ourself against things getting out of hand. */ if (expected_serialize_len >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } } /* * Does the plugin have more xattrs ? */ if (!more) { break; } } /* * If we found any xattr send them to the SD. */ if (xattr_count > 0) { /* * Serialize the datastream. */ if (serialize_xattr_stream(jcr, xattr_data, expected_serialize_len, xattr_value_list) < expected_serialize_len) { Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Send the datastream to the SD. */ retval = send_xattr_stream(jcr, xattr_data, STREAM_XATTR_PLUGIN); } else { retval = bxattr_exit_ok; } #endif } #if defined(HAVE_XATTR) bail_out: if (xattr_value_list) { xattr_drop_internal_table(xattr_value_list); } #endif return retval; } /** * Plugin specific callback for setting XATTR information. */ bxattr_exit_code plugin_parse_xattr_streams(JCR *jcr, struct xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { #if defined(HAVE_XATTR) Plugin *plugin; alist *xattr_value_list = NULL; #endif bxattr_exit_code retval = bxattr_exit_error; Dmsg0(dbglvl, "plugin_parse_xattr_streams\n"); if (!jcr->plugin_ctx) { return bxattr_exit_ok; } #if defined(HAVE_XATTR) plugin = (Plugin *)jcr->plugin_ctx->plugin; if (plug_func(plugin)->setXattr != NULL) { xattr_t *current_xattr; struct xattr_pkt xp; xattr_value_list = New(alist(10, not_owned_by_alist)); if (unserialize_xattr_stream(jcr, xattr_data, content, content_length, xattr_value_list) != bxattr_exit_ok) { goto bail_out; } memset(&xp, 0, sizeof(xp)); xp.pkt_size = xp.pkt_end = sizeof(struct xattr_pkt); xp.fname = xattr_data->last_fname; foreach_alist(current_xattr, xattr_value_list) { xp.name = current_xattr->name; xp.name_length = current_xattr->name_length; xp.value = current_xattr->value; xp.value_length = current_xattr->value_length; switch (plug_func(plugin)->setXattr(jcr->plugin_ctx, &xp)) { case bRC_OK: break; default: goto bail_out; } } retval = bxattr_exit_ok; } bail_out: if (xattr_value_list) { xattr_drop_internal_table(xattr_value_list); } #endif return retval; } /** * Print to file the plugin info. */ static void dump_fd_plugin(Plugin *plugin, FILE *fp) { genpInfo *info; if (!plugin) { return ; } info = (genpInfo *)plugin->pinfo; fprintf(fp, "\tversion=%d\n", info->version); fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date)); fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic)); fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author)); fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license)); fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version)); fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description)); } static void dump_fd_plugins(FILE *fp) { dump_plugins(fd_plugin_list, fp); } /** * This entry point is called internally by Bareos to ensure that the plugin IO calls come into this code. */ void load_fd_plugins(const char *plugin_dir, alist *plugin_names) { Plugin *plugin; int i; if (!plugin_dir) { Dmsg0(dbglvl, "plugin dir is NULL\n"); return; } fd_plugin_list = New(alist(10, not_owned_by_alist)); if (!load_plugins((void *)&binfo, (void *)&bfuncs, fd_plugin_list, plugin_dir, plugin_names, plugin_type, is_plugin_compatible)) { /* * Either none found, or some error */ if (fd_plugin_list->size() == 0) { delete fd_plugin_list; fd_plugin_list = NULL; Dmsg0(dbglvl, "No plugins loaded\n"); return; } } /* * Plug entry points called from findlib */ plugin_bopen = my_plugin_bopen; plugin_bclose = my_plugin_bclose; plugin_bread = my_plugin_bread; plugin_bwrite = my_plugin_bwrite; plugin_blseek = my_plugin_blseek; /* * Verify that the plugin is acceptable, and print information about it. */ foreach_alist_index(i, plugin, fd_plugin_list) { Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); } dbg_plugin_add_hook(dump_fd_plugin); dbg_print_plugin_add_hook(dump_fd_plugins); } void unload_fd_plugins(void) { unload_plugins(fd_plugin_list); delete fd_plugin_list; fd_plugin_list = NULL; } int list_fd_plugins(POOL_MEM &msg) { return list_plugins(fd_plugin_list, msg); } /** * Check if a plugin is compatible. Called by the load_plugin function to allow us to verify the plugin. */ static bool is_plugin_compatible(Plugin *plugin) { genpInfo *info = (genpInfo *)plugin->pinfo; Dmsg0(dbglvl, "is_plugin_compatible called\n"); if (debug_level >= 50) { dump_fd_plugin(plugin, stdin); } if (!bstrcmp(info->plugin_magic, FD_PLUGIN_MAGIC)) { Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), plugin->file, FD_PLUGIN_MAGIC, info->plugin_magic); Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", plugin->file, FD_PLUGIN_MAGIC, info->plugin_magic); return false; } if (info->version != FD_PLUGIN_INTERFACE_VERSION) { Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version); Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version); return false; } if (!bstrcasecmp(info->plugin_license, "Bareos AGPLv3") && !bstrcasecmp(info->plugin_license, "AGPLv3")) { Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), plugin->file, info->plugin_license); Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", plugin->file, info->plugin_license); return false; } if (info->size != sizeof(genpInfo)) { Jmsg(NULL, M_ERROR, 0, _("Plugin size incorrect. Plugin=%s wanted=%d got=%d\n"), plugin->file, sizeof(genpInfo), info->size); return false; } return true; } /* * Instantiate a new plugin instance. */ static inline bpContext *instantiate_plugin(JCR *jcr, Plugin *plugin, char instance) { bpContext *ctx; b_plugin_ctx *b_ctx; b_ctx = (b_plugin_ctx *)malloc(sizeof(b_plugin_ctx)); memset(b_ctx, 0, sizeof(b_plugin_ctx)); b_ctx->jcr = jcr; ctx = (bpContext *)malloc(sizeof(bpContext)); ctx->instance = instance; ctx->plugin = plugin; ctx->bContext = (void *)b_ctx; ctx->pContext = NULL; jcr->plugin_ctx_list->append(ctx); if (plug_func(plugin)->newPlugin(ctx) != bRC_OK) { b_ctx->disabled = true; } return ctx; } /** * Create a new instance of each plugin for this Job * * Note, fd_plugin_list can exist but jcr->plugin_ctx_list can be NULL if no plugins were loaded. */ void new_plugins(JCR *jcr) { int i, num; Plugin *plugin; if (!fd_plugin_list) { Dmsg0(dbglvl, "plugin list is NULL\n"); return; } if (jcr->is_job_canceled()) { return; } num = fd_plugin_list->size(); if (num == 0) { Dmsg0(dbglvl, "No plugins loaded\n"); return; } jcr->plugin_ctx_list = New(alist(10, owned_by_alist)); Dmsg2(dbglvl, "Instantiate plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist_index(i, plugin, fd_plugin_list) { /* * Start a new instance of each plugin */ instantiate_plugin(jcr, plugin, 0); } } /** * Free the plugin instances for this Job */ void free_plugins(JCR *jcr) { bpContext *ctx; if (!fd_plugin_list || !jcr->plugin_ctx_list) { return; } Dmsg2(dbglvl, "Free instance dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(ctx, jcr->plugin_ctx_list) { /* * Free the plugin instance */ plug_func(ctx->plugin)->freePlugin(ctx); free(ctx->bContext); /* Free BAREOS private context */ } delete jcr->plugin_ctx_list; jcr->plugin_ctx_list = NULL; } /** * Entry point for opening the file this is a wrapper around the pluginIO entry point in the plugin. */ static int my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) { Plugin *plugin; struct io_pkt io; JCR *jcr = bfd->jcr; Dmsg1(dbglvl, "plugin_bopen flags=%x\n", flags); if (!jcr->plugin_ctx) { return 0; } plugin = (Plugin *)jcr->plugin_ctx->plugin; memset(&io, 0, sizeof(io)); io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_OPEN; io.fname = fname; io.flags = flags; io.mode = mode; plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io); bfd->berrno = io.io_errno; if (io.win32) { errno = b_errno_win32; } else { errno = io.io_errno; bfd->lerror = io.lerror; } Dmsg1(dbglvl, "Return from plugin open status=%d\n", io.status); return io.status; } /** * Entry point for closing the file this is a wrapper around the pluginIO entry point in the plugin. */ static int my_plugin_bclose(BFILE *bfd) { Plugin *plugin; struct io_pkt io; JCR *jcr = bfd->jcr; Dmsg0(dbglvl, "===== plugin_bclose\n"); if (!jcr->plugin_ctx) { return 0; } plugin = (Plugin *)jcr->plugin_ctx->plugin; memset(&io, 0, sizeof(io)); io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_CLOSE; plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io); bfd->berrno = io.io_errno; if (io.win32) { errno = b_errno_win32; } else { errno = io.io_errno; bfd->lerror = io.lerror; } Dmsg1(dbglvl, "plugin_bclose stat=%d\n", io.status); return io.status; } /** * Entry point for reading from the file this is a wrapper around the pluginIO entry point in the plugin. */ static ssize_t my_plugin_bread(BFILE *bfd, void *buf, size_t count) { Plugin *plugin; struct io_pkt io; JCR *jcr = bfd->jcr; Dmsg0(dbglvl, "plugin_bread\n"); if (!jcr->plugin_ctx) { return 0; } plugin = (Plugin *)jcr->plugin_ctx->plugin; memset(&io, 0, sizeof(io)); io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_READ; io.count = count; io.buf = (char *)buf; plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io); bfd->offset = io.offset; bfd->berrno = io.io_errno; if (io.win32) { errno = b_errno_win32; } else { errno = io.io_errno; bfd->lerror = io.lerror; } return (ssize_t)io.status; } /** * Entry point for writing to the file this is a wrapper around the pluginIO entry point in the plugin. */ static ssize_t my_plugin_bwrite(BFILE *bfd, void *buf, size_t count) { Plugin *plugin; struct io_pkt io; JCR *jcr = bfd->jcr; Dmsg0(dbglvl, "plugin_bwrite\n"); if (!jcr->plugin_ctx) { Dmsg0(0, "No plugin context\n"); return 0; } plugin = (Plugin *)jcr->plugin_ctx->plugin; memset(&io, 0, sizeof(io)); io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_WRITE; io.count = count; io.buf = (char *)buf; plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io); bfd->berrno = io.io_errno; if (io.win32) { errno = b_errno_win32; } else { errno = io.io_errno; bfd->lerror = io.lerror; } return (ssize_t)io.status; } /** * Entry point for seeking in the file this is a wrapper around the pluginIO entry point in the plugin. */ static boffset_t my_plugin_blseek(BFILE *bfd, boffset_t offset, int whence) { Plugin *plugin; struct io_pkt io; JCR *jcr = bfd->jcr; Dmsg0(dbglvl, "plugin_bseek\n"); if (!jcr->plugin_ctx) { return 0; } plugin = (Plugin *)jcr->plugin_ctx->plugin; io.pkt_size = sizeof(io); io.pkt_end = sizeof(io); io.func = IO_SEEK; io.offset = offset; io.whence = whence; io.win32 = false; io.lerror = 0; plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io); bfd->berrno = io.io_errno; if (io.win32) { errno = b_errno_win32; } else { errno = io.io_errno; bfd->lerror = io.lerror; } return (boffset_t)io.offset; } /* ============================================================== * * Callbacks from the plugin * * ============================================================== */ static bRC bareosGetValue(bpContext *ctx, bVariable var, void *value) { JCR *jcr = NULL; if (!value) { return bRC_Error; } switch (var) { /* General variables, no need of ctx */ case bVarFDName: *((char **)value) = my_name; break; case bVarWorkingDir: *(void **)value = me->working_directory; break; case bVarExePath: *(char **)value = exepath; break; case bVarVersion: *(char **)value = version; break; case bVarDistName: *(char **)value = dist_name; break; default: if (!ctx) { /* Other variables need context */ return bRC_Error; } jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; if (!jcr) { return bRC_Error; } break; } if (jcr) { switch (var) { case bVarJobId: *((int *)value) = jcr->JobId; Dmsg1(dbglvl, "fd-plugin: return bVarJobId=%d\n", jcr->JobId); break; case bVarLevel: *((int *)value) = jcr->getJobLevel(); Dmsg1(dbglvl, "fd-plugin: return bVarJobLevel=%d\n", jcr->getJobLevel()); break; case bVarType: *((int *)value) = jcr->getJobType(); Dmsg1(dbglvl, "fd-plugin: return bVarJobType=%d\n", jcr->getJobType()); break; case bVarClient: *((char **)value) = jcr->client_name; Dmsg1(dbglvl, "fd-plugin: return bVarClient=%s\n", NPRT(*((char **)value))); break; case bVarJobName: *((char **)value) = jcr->Job; Dmsg1(dbglvl, "fd-plugin: return bVarJobName=%s\n", NPRT(*((char **)value))); break; case bVarPrevJobName: *((char **)value) = jcr->PrevJob; Dmsg1(dbglvl, "fd-plugin: return bVarPrevJobName=%s\n", NPRT(*((char **)value))); break; case bVarJobStatus: *((int *)value) = jcr->JobStatus; Dmsg1(dbglvl, "fd-plugin: return bVarJobStatus=%d\n", jcr->JobStatus); break; case bVarSinceTime: *((int *)value) = (int)jcr->mtime; Dmsg1(dbglvl, "fd-plugin: return bVarSinceTime=%d\n", (int)jcr->mtime); break; case bVarAccurate: *((int *)value) = (int)jcr->accurate; Dmsg1(dbglvl, "fd-plugin: return bVarAccurate=%d\n", (int)jcr->accurate); break; case bVarFileSeen: break; /* a write only variable, ignore read request */ case bVarVssObject: #ifdef HAVE_WIN32 if (g_pVSSClient) { *(void **)value = g_pVSSClient->GetVssObject(); Dmsg1(dbglvl, "fd-plugin: return bVarVssObject=%p\n", *(void **)value); break; } #endif return bRC_Error; case bVarVssDllHandle: #ifdef HAVE_WIN32 if (g_pVSSClient) { *(void **)value = g_pVSSClient->GetVssDllHandle(); Dmsg1(dbglvl, "fd-plugin: return bVarVssDllHandle=%p\n", *(void **)value); break; } #endif return bRC_Error; case bVarWhere: *(char **)value = jcr->where; Dmsg1(dbglvl, "fd-plugin: return bVarWhere=%s\n", NPRT(*((char **)value))); break; case bVarRegexWhere: *(char **)value = jcr->RegexWhere; Dmsg1(dbglvl, "fd-plugin: return bVarRegexWhere=%s\n", NPRT(*((char **)value))); break; case bVarPrefixLinks: *(int *)value = (int)jcr->prefix_links; Dmsg1(dbglvl, "fd-plugin: return bVarPrefixLinks=%d\n", (int)jcr->prefix_links); break; default: break; } } return bRC_OK; } static bRC bareosSetValue(bpContext *ctx, bVariable var, void *value) { JCR *jcr; if (!value || !ctx) { return bRC_Error; } jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; if (!jcr) { return bRC_Error; } switch (var) { case bVarFileSeen: if (!accurate_mark_file_as_seen(jcr, (char *)value)) { return bRC_Error; } break; default: break; } return bRC_OK; } static bRC bareosRegisterEvents(bpContext *ctx, int nr_events, ...) { int i; va_list args; uint32_t event; b_plugin_ctx *b_ctx; if (!ctx) { return bRC_Error; } b_ctx = (b_plugin_ctx *)ctx->bContext; va_start(args, nr_events); for (i = 0; i < nr_events; i++) { event = va_arg(args, uint32_t); Dmsg1(dbglvl, "Plugin wants event=%u\n", event); set_bit(event, b_ctx->events); } va_end(args); return bRC_OK; } static bRC bareosJobMsg(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...) { JCR *jcr; va_list arg_ptr; POOL_MEM buffer(PM_MESSAGE); if (ctx) { jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; } else { jcr = NULL; } va_start(arg_ptr, fmt); buffer.bvsprintf(fmt, arg_ptr); va_end(arg_ptr); Jmsg(jcr, type, mtime, "%s", buffer.c_str()); return bRC_OK; } static bRC bareosDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...) { va_list arg_ptr; POOL_MEM buffer(PM_MESSAGE); va_start(arg_ptr, fmt); buffer.bvsprintf(fmt, arg_ptr); va_end(arg_ptr); d_msg(file, line, level, "%s", buffer.c_str()); return bRC_OK; } static void *bareosMalloc(bpContext *ctx, const char *file, int line, size_t size) { #ifdef SMARTALLOC return sm_malloc(file, line, size); #else return malloc(size); #endif } static void bareosFree(bpContext *ctx, const char *file, int line, void *mem) { #ifdef SMARTALLOC sm_free(file, line, mem); #else free(mem); #endif } static bool is_ctx_good(bpContext *ctx, JCR *&jcr, b_plugin_ctx *&bctx) { if (!ctx) { return false; } bctx = (b_plugin_ctx *)ctx->bContext; if (!bctx) { return false; } jcr = bctx->jcr; if (!jcr) { return false; } return true; } /** * Let the plugin define files/directories to be excluded from the main backup. */ static bRC bareosAddExclude(bpContext *ctx, const char *file) { JCR *jcr; findINCEXE *old; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } if (!file) { return bRC_Error; } /* * Save the include context */ old = get_incexe(jcr); /* * Not right time to add exlude */ if (!old) { return bRC_Error; } if (!bctx->exclude) { bctx->exclude = new_exclude(jcr->ff->fileset); } /* * Set the Exclude context */ set_incexe(jcr, bctx->exclude); add_file_to_fileset(jcr, file, true); /* * Restore the current context */ set_incexe(jcr, old); Dmsg1(100, "Add exclude file=%s\n", file); return bRC_OK; } /** * Let the plugin define files/directories to be excluded from the main backup. */ static bRC bareosAddInclude(bpContext *ctx, const char *file) { JCR *jcr; findINCEXE *old; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } if (!file) { return bRC_Error; } /* * Save the include context */ old = get_incexe(jcr); /* * Not right time to add include */ if (!old) { return bRC_Error; } if (!bctx->include) { bctx->include = old; } set_incexe(jcr, bctx->include); add_file_to_fileset(jcr, file, true); /* * Restore the current context */ set_incexe(jcr, old); Dmsg1(100, "Add include file=%s\n", file); return bRC_OK; } static bRC bareosAddOptions(bpContext *ctx, const char *opts) { JCR *jcr; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } if (!opts) { return bRC_Error; } add_options_to_fileset(jcr, opts); Dmsg1(1000, "Add options=%s\n", opts); return bRC_OK; } static bRC bareosAddRegex(bpContext *ctx, const char *item, int type) { JCR *jcr; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } if (!item) { return bRC_Error; } add_regex_to_fileset(jcr, item, type); Dmsg1(100, "Add regex=%s\n", item); return bRC_OK; } static bRC bareosAddWild(bpContext *ctx, const char *item, int type) { JCR *jcr; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } if (!item) { return bRC_Error; } add_wild_to_fileset(jcr, item, type); Dmsg1(100, "Add wild=%s\n", item); return bRC_OK; } static bRC bareosNewOptions(bpContext *ctx) { JCR *jcr; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } (void)new_options(jcr->ff, jcr->ff->fileset->incexe); return bRC_OK; } static bRC bareosNewInclude(bpContext *ctx) { JCR *jcr; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } (void)new_include(jcr->ff->fileset); return bRC_OK; } static bRC bareosNewPreInclude(bpContext *ctx) { JCR *jcr; b_plugin_ctx *bctx; if (!is_ctx_good(ctx, jcr, bctx)) { return bRC_Error; } bctx->include = new_preinclude(jcr->ff->fileset); new_options(jcr->ff, bctx->include); set_incexe(jcr, bctx->include); return bRC_OK; } /** * Check if a file have to be backuped using Accurate code */ static bRC bareosCheckChanges(bpContext *ctx, struct save_pkt *sp) { JCR *jcr; b_plugin_ctx *bctx; FF_PKT *ff_pkt; bRC ret = bRC_Error; if (!is_ctx_good(ctx, jcr, bctx)) { goto bail_out; } if (!sp) { goto bail_out; } ff_pkt = jcr->ff; /* * Copy fname and link because save_file() zaps them. * This avoids zaping the plugin's strings. */ ff_pkt->type = sp->type; if (!sp->fname) { Jmsg0(jcr, M_FATAL, 0, _("Command plugin: no fname in bareosCheckChanges packet.\n")); goto bail_out; } ff_pkt->fname = sp->fname; ff_pkt->link = sp->link; if (sp->save_time) { ff_pkt->save_time = sp->save_time; ff_pkt->incremental = true; } memcpy(&ff_pkt->statp, &sp->statp, sizeof(ff_pkt->statp)); if (check_changes(jcr, ff_pkt)) { ret = bRC_OK; } else { ret = bRC_Seen; } /* * check_changes() can update delta sequence number, return it to the plugin */ sp->delta_seq = ff_pkt->delta_seq; sp->accurate_found = ff_pkt->accurate_found; bail_out: Dmsg1(100, "checkChanges=%i\n", ret); return ret; } /** * Check if a file would be saved using current Include/Exclude code */ static bRC bareosAcceptFile(bpContext *ctx, struct save_pkt *sp) { JCR *jcr; FF_PKT *ff_pkt; b_plugin_ctx *bctx; bRC ret = bRC_Error; if (!is_ctx_good(ctx, jcr, bctx)) { goto bail_out; } if (!sp) { goto bail_out; } ff_pkt = jcr->ff; ff_pkt->fname = sp->fname; memcpy(&ff_pkt->statp, &sp->statp, sizeof(ff_pkt->statp)); if (accept_file(ff_pkt)) { ret = bRC_OK; } else { ret = bRC_Skip; } bail_out: return ret; } #ifdef TEST_PROGRAM /* Exported variables */ CLIENTRES *me; /* my resource */ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { return 0; } bool accurate_mark_file_as_seen(JCR *jcr, char *fname) { return true; } bool set_cmd_plugin(BFILE *bfd, JCR *jcr) { return true; } int main(int argc, char *argv[]) { char plugin_dir[PATH_MAX]; JCR mjcr1, mjcr2; JCR *jcr1 = &mjcr1; JCR *jcr2 = &mjcr2; my_name_is(argc, argv, "plugtest"); init_msg(NULL, NULL); OSDependentInit(); if (argc != 1) { bstrncpy(plugin_dir, argv[1], sizeof(plugin_dir)); } else { getcwd(plugin_dir, sizeof(plugin_dir)-1); } load_fd_plugins(plugin_dir, NULL); jcr1->JobId = 111; new_plugins(jcr1); jcr2->JobId = 222; new_plugins(jcr2); generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1"); generate_plugin_event(jcr1, bEventJobEnd); generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 2"); free_plugins(jcr1); generate_plugin_event(jcr2, bEventJobEnd); free_plugins(jcr2); unload_fd_plugins(); Dmsg0(dbglvl, "bareos: OK ...\n"); term_msg(); close_memory_pool(); lmgr_cleanup_main(); sm_dump(false); exit(0); } #endif /* TEST_PROGRAM */ bareos-Release-14.2.6/src/filed/fd_plugins.h000066400000000000000000000330471263011562700206240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Application Programming Interface (API) definition for Bareos Plugins * * Kern Sibbald, October 2007 */ #ifndef __FD_PLUGINS_H #define __FD_PLUGINS_H #ifndef _BAREOS_H #ifdef __cplusplus /* Workaround for SGI IRIX 6.5 */ #define _LANGUAGE_C_PLUS_PLUS 1 #endif #define _REENTRANT 1 #define _THREAD_SAFE 1 #define _POSIX_PTHREAD_SEMANTICS 1 #define _FILE_OFFSET_BITS 64 #define _LARGEFILE_SOURCE 1 #define _LARGE_FILES 1 #endif /* ! _BAREOS_H */ #include #include "hostconfig.h" #include "version.h" #include "bc_types.h" #include "fileopts.h" #include "lib/plugins.h" #include #ifdef HAVE_WIN32 #include "vss.h" #endif /* * This packet is used for the restore objects * It is passed to the plugin when restoring * the object. */ struct restore_object_pkt { int32_t pkt_size; /* Size of this packet */ char *object_name; /* Object name */ char *object; /* Restore object data to save */ char *plugin_name; /* Plugin name */ int32_t object_type; /* FT_xx for this file */ int32_t object_len; /* Restore object length */ int32_t object_full_len; /* Restore object uncompressed length */ int32_t object_index; /* Restore object index */ int32_t object_compression; /* Set to compression type */ int32_t stream; /* Attribute stream id */ uint32_t JobId; /* JobId object came from */ int32_t pkt_end; /* End packet sentinel */ }; /* * This packet is used for file save info transfer. */ struct save_pkt { int32_t pkt_size; /* Size of this packet */ char *fname; /* Full path and filename */ char *link; /* Link name if any */ struct stat statp; /* System stat() packet for file */ int32_t type; /* FT_xx for this file */ char flags[FOPTS_BYTES]; /* Bareos internal flags */ bool no_read; /* During the save, the file should not be saved */ bool portable; /* Set if data format is portable */ bool accurate_found; /* Found in accurate list (valid after check_changes()) */ char *cmd; /* Command */ time_t save_time; /* Start of incremental time */ uint32_t delta_seq; /* Delta sequence number */ char *object_name; /* Object name to create */ char *object; /* Restore object data to save */ int32_t object_len; /* Restore object length */ int32_t index; /* Restore object index */ int32_t pkt_end; /* End packet sentinel */ }; /* * This packet is used for file restore info transfer. */ struct restore_pkt { int32_t pkt_size; /* Size of this packet */ int32_t stream; /* Attribute stream id */ int32_t data_stream; /* Id of data stream to follow */ int32_t type; /* File type FT */ int32_t file_index; /* File index */ int32_t LinkFI; /* File index to data if hard link */ uid_t uid; /* Userid */ struct stat statp; /* Decoded stat packet */ const char *attrEx; /* Extended attributes if any */ const char *ofname; /* Output filename */ const char *olname; /* Output link name */ const char *where; /* Where */ const char *RegexWhere; /* Regex where */ int replace; /* Replace flag */ int create_status; /* Status from createFile() */ uint32_t delta_seq; /* Delta sequence number */ int32_t pkt_end; /* End packet sentinel */ }; enum { IO_OPEN = 1, IO_READ = 2, IO_WRITE = 3, IO_CLOSE = 4, IO_SEEK = 5 }; struct io_pkt { int32_t pkt_size; /* Size of this packet */ int32_t func; /* Function code */ int32_t count; /* Read/write count */ int32_t flags; /* Open flags */ mode_t mode; /* Permissions for created files */ char *buf; /* Read/write buffer */ const char *fname; /* Open filename */ int32_t status; /* Return status */ int32_t io_errno; /* Errno code */ int32_t lerror; /* Win32 error code */ int32_t whence; /* Lseek argument */ boffset_t offset; /* Lseek argument */ bool win32; /* Win32 GetLastError returned */ int32_t pkt_end; /* End packet sentinel */ }; struct acl_pkt { int32_t pkt_size; /* Size of this packet */ const char *fname; /* Full path and filename */ uint32_t content_length; /* ACL content length */ char *content; /* ACL content */ int32_t pkt_end; /* End packet sentinel */ }; struct xattr_pkt { int32_t pkt_size; /* Size of this packet */ const char *fname; /* Full path and filename */ uint32_t name_length; /* XATTR name length */ char *name; /* XATTR name */ uint32_t value_length; /* XATTR value length */ char *value; /* XATTR value */ int32_t pkt_end; /* End packet sentinel */ }; /**************************************************************************** * * * Bareos definitions * * * ****************************************************************************/ /* * Bareos Variable Ids */ typedef enum { bVarJobId = 1, bVarFDName = 2, bVarLevel = 3, bVarType = 4, bVarClient = 5, bVarJobName = 6, bVarJobStatus = 7, bVarSinceTime = 8, bVarAccurate = 9, bVarFileSeen = 10, bVarVssObject = 11, bVarVssDllHandle = 12, bVarWorkingDir = 13, bVarWhere = 14, bVarRegexWhere = 15, bVarExePath = 16, bVarVersion = 17, bVarDistName = 18, bVarPrevJobName = 19, bVarPrefixLinks = 20 } bVariable; /* * Events that are passed to plugin */ typedef enum { bEventJobStart = 1, bEventJobEnd = 2, bEventStartBackupJob = 3, bEventEndBackupJob = 4, bEventStartRestoreJob = 5, bEventEndRestoreJob = 6, bEventStartVerifyJob = 7, bEventEndVerifyJob = 8, bEventBackupCommand = 9, bEventRestoreCommand = 10, bEventEstimateCommand = 11, bEventLevel = 12, bEventSince = 13, bEventCancelCommand = 14, /* Executed by another thread */ bEventVssBackupAddComponents = 15, /* Just before bEventVssPrepareSnapshot */ bEventVssRestoreLoadComponentMetadata = 16, bEventVssRestoreSetComponentsSelected = 17, bEventRestoreObject = 18, bEventEndFileSet = 19, bEventPluginCommand = 20, /* Sent during FileSet creation */ bEventVssBeforeCloseRestore = 21, /* Add drives to VSS snapshot * argument: char[27] drivelist * You need to add them without duplicates, * see fd_common.h add_drive() copy_drives() to get help */ bEventVssPrepareSnapshot = 22, bEventOptionPlugin = 23, bEventHandleBackupFile = 24, /* Used with Options Plugin */ bEventComponentInfo = 25, /* Plugin component */ bEventNewPluginOptions = 26 } bEventType; #define FD_NR_EVENTS bEventHandleBackupFile /* keep this updated ! */ typedef struct s_bEvent { uint32_t eventType; } bEvent; typedef struct s_bareosInfo { uint32_t size; uint32_t version; } bInfo; /* * Bareos Core Routines -- not used within a plugin */ #ifdef FILE_DAEMON struct BFILE; /* forward referenced */ struct FF_PKT; void load_fd_plugins(const char *plugin_dir, alist *plugin_names); void unload_fd_plugins(void); int list_fd_plugins(POOL_MEM &msg); void new_plugins(JCR *jcr); void free_plugins(JCR *jcr); void generate_plugin_event(JCR *jcr, bEventType event, void *value = NULL, bool reverse = false); bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start); bool plugin_name_stream(JCR *jcr, char *name); int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace); bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd); bacl_exit_code plugin_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt); bacl_exit_code plugin_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length); bxattr_exit_code plugin_build_xattr_streams(JCR *jcr, struct xattr_data_t *xattr_data, FF_PKT *ff_pkt); bxattr_exit_code plugin_parse_xattr_streams(JCR *jcr, struct xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length); int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level); int plugin_estimate(JCR *jcr, FF_PKT *ff_pkt, bool top_level); bool plugin_check_file(JCR *jcr, char *fname); void plugin_update_ff_pkt(FF_PKT *ff_pkt, struct save_pkt *sp); bRC plugin_option_handle_file(JCR *jcr, FF_PKT *ff_pkt, struct save_pkt *sp); #endif #ifdef __cplusplus extern "C" { #endif /* * Bareos interface version and function pointers -- * i.e. callbacks from the plugin to Bareos */ typedef struct s_bareosFuncs { uint32_t size; uint32_t version; bRC (*registerBareosEvents)(bpContext *ctx, int nr_events, ...); bRC (*getBareosValue)(bpContext *ctx, bVariable var, void *value); bRC (*setBareosValue)(bpContext *ctx, bVariable var, void *value); bRC (*JobMessage)(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); bRC (*DebugMessage)(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); void *(*bareosMalloc)(bpContext *ctx, const char *file, int line, size_t size); void (*bareosFree)(bpContext *ctx, const char *file, int line, void *mem); bRC (*AddExclude)(bpContext *ctx, const char *file); bRC (*AddInclude)(bpContext *ctx, const char *file); bRC (*AddOptions)(bpContext *ctx, const char *opts); bRC (*AddRegex)(bpContext *ctx, const char *item, int type); bRC (*AddWild)(bpContext *ctx, const char *item, int type); bRC (*NewOptions)(bpContext *ctx); bRC (*NewInclude)(bpContext *ctx); bRC (*NewPreInclude)(bpContext *ctx); bRC (*checkChanges)(bpContext *ctx, struct save_pkt *sp); bRC (*AcceptFile)(bpContext *ctx, struct save_pkt *sp); /* Need fname and statp */ } bFuncs; /**************************************************************************** * * * Plugin definitions * * * ****************************************************************************/ typedef enum { pVarName = 1, pVarDescription = 2 } pVariable; #define FD_PLUGIN_MAGIC "*FDPluginData*" #define FD_PLUGIN_INTERFACE_VERSION 9 /* * This is a set of function pointers that Bareos can call * within the plugin. */ typedef struct s_pluginFuncs { uint32_t size; uint32_t version; bRC (*newPlugin)(bpContext *ctx); bRC (*freePlugin)(bpContext *ctx); bRC (*getPluginValue)(bpContext *ctx, pVariable var, void *value); bRC (*setPluginValue)(bpContext *ctx, pVariable var, void *value); bRC (*handlePluginEvent)(bpContext *ctx, bEvent *event, void *value); bRC (*startBackupFile)(bpContext *ctx, struct save_pkt *sp); bRC (*endBackupFile)(bpContext *ctx); bRC (*startRestoreFile)(bpContext *ctx, const char *cmd); bRC (*endRestoreFile)(bpContext *ctx); bRC (*pluginIO)(bpContext *ctx, struct io_pkt *io); bRC (*createFile)(bpContext *ctx, struct restore_pkt *rp); bRC (*setFileAttributes)(bpContext *ctx, struct restore_pkt *rp); bRC (*checkFile)(bpContext *ctx, char *fname); bRC (*getAcl)(bpContext *ctx, struct acl_pkt *ap); bRC (*setAcl)(bpContext *ctx, struct acl_pkt *ap); bRC (*getXattr)(bpContext *ctx, struct xattr_pkt *xp); bRC (*setXattr)(bpContext *ctx, struct xattr_pkt *xp); } pFuncs; #define plug_func(plugin) ((pFuncs *)(plugin->pfuncs)) #define plug_info(plugin) ((genpInfo *)(plugin->pinfo)) #ifdef __cplusplus } #endif #endif /* __FD_PLUGINS_H */ bareos-Release-14.2.6/src/filed/filed.c000066400000000000000000000445721263011562700175550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon * * Kern Sibbald, March MM */ #include "bareos.h" #include "filed.h" #include "lib/mntent_cache.h" /* Imported Functions */ extern void *handle_connection_request(void *dir_sock); extern bool parse_fd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ static bool check_resources(); /* Exported variables */ CLIENTRES *me = NULL; /* Our Global resource */ CONFIG *my_config = NULL; /* Our Global config */ bool no_signals = false; bool backup_only_mode = false; bool restore_only_mode = false; void *start_heap; #define CONFIG_FILE "bareos-fd.conf" /* default config file */ char *configfile = NULL; static bool foreground = false; static workq_t dir_workq; /* queue of work from Director */ static alist *sock_fds; static pthread_t tcp_server_tid; static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bareos-fd [-f -s] [-c config_file] [-d debug_level]\n" " -b backup only mode\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g groupid\n" " -k keep readall capabilities\n" " -m print kaboom output (for debugging)\n" " -r restore only mode\n" " -s no signals (for debugging)\n" " -t test configuration file and exit\n" " -u userid\n" " -v verbose user messages\n" " -? print this message.\n" "\n"), 2000, VERSION, BDATE); exit(1); } /********************************************************************* * * Main Bareos Unix Client Program * */ #if defined(HAVE_WIN32) #define main BareosMain #endif int main (int argc, char *argv[]) { int ch; bool test_config = false; bool keep_readall_caps = false; char *uid = NULL; char *gid = NULL; start_heap = sbrk(0); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "bareos-fd"); init_msg(NULL, NULL); daemon_start_time = time(NULL); while ((ch = getopt(argc, argv, "bc:d:fg:kmrstu:v?")) != -1) { switch (ch) { case 'b': backup_only_mode = true; break; case 'c': /* configuration file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* run in foreground */ foreground = true; break; case 'g': /* set group */ gid = optarg; break; case 'k': keep_readall_caps = true; break; case 'm': /* print kaboom output */ prt_kaboom = true; break; case 'r': restore_only_mode = true; break; case 's': no_signals = true; break; case 't': test_config = true; break; case 'u': /* set userid */ uid = optarg; break; case 'v': /* verbose */ verbose++; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc) { if (configfile != NULL) free(configfile); configfile = bstrdup(*argv); argc--; argv++; } if (argc) { usage(); } if (!uid && keep_readall_caps) { Emsg0(M_ERROR_TERM, 0, _("-k option has no meaning without -u option.\n")); } /* * See if we want to drop privs. */ if (geteuid() == 0) { drop(uid, gid, keep_readall_caps); } tcp_server_tid = pthread_self(); if (!no_signals) { init_signals(terminate_filed); } else { /* This reduces the number of signals facilitating debugging */ watchdog_sleep_time = 120; /* long timeout for debugging */ } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_fd_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Emsg0(M_ERROR, 0, _("Cryptography library initialization failed.\n")); terminate_filed(1); } if (!check_resources()) { Emsg1(M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); terminate_filed(1); } set_working_directory(me->working_directory); #if defined(HAVE_WIN32) if (me->compatible) { Win32SetCompatible(); } else { Win32ClearCompatible(); } #endif if (test_config) { terminate_filed(0); } if (!foreground) { daemon_start(); init_stack_dump(); /* set new pid */ } set_thread_concurrency(me->MaxConcurrentJobs + 10); lmgr_init_thread(); /* initialize the lockmanager stack */ /* Maximum 1 daemon at a time */ create_pid_file(me->pid_directory, "bareos-fd", get_first_port_host_order(me->FDaddrs)); read_state_file(me->working_directory, "bareos-fd", get_first_port_host_order(me->FDaddrs)); load_fd_plugins(me->plugin_directory, me->plugin_names); if (!no_signals) { start_watchdog(); /* start watchdog thread */ if (me->jcr_watchdog_time) { init_jcr_subsystem(me->jcr_watchdog_time); /* start JCR watchdogs etc. */ } } tcp_server_tid = pthread_self(); /* Become server, and handle requests */ IPADDR *p; foreach_dlist(p, me->FDaddrs) { Dmsg1(10, "filed: listening on port %d\n", p->get_port_host_order()); } sock_fds = New(alist(10, not_owned_by_alist)); bnet_thread_server_tcp(me->FDaddrs, me->MaxConcurrentJobs, sock_fds, &dir_workq, me->nokeepalive, handle_connection_request); terminate_filed(0); exit(0); /* should never get here */ } void terminate_filed(int sig) { static bool already_here = false; if (already_here) { bmicrosleep(2, 0); /* yield */ exit(1); /* prevent loops */ } already_here = true; debug_level = 0; /* turn off debug */ stop_watchdog(); bnet_stop_thread_server_tcp(tcp_server_tid); cleanup_bnet_thread_server_tcp(sock_fds, &dir_workq); delete sock_fds; sock_fds = NULL; unload_fd_plugins(); flush_mntent_cache(); write_state_file(me->working_directory, "bareos-fd", get_first_port_host_order(me->FDaddrs)); delete_pid_file(me->pid_directory, "bareos-fd", get_first_port_host_order(me->FDaddrs)); if (configfile != NULL) { free(configfile); } if (debug_level > 0) { print_memory_pool_stats(); } if (my_config) { my_config->free_resources(); free(my_config); my_config = NULL; } term_msg(); cleanup_crypto(); close_memory_pool(); /* release free memory in pool */ lmgr_cleanup_main(); sm_dump(false); /* dump orphaned buffers */ exit(sig); } /* * Make a quick check to see that we have all the * resources needed. */ static bool check_resources() { bool OK = true; DIRRES *director; bool need_tls; LockRes(); me = (CLIENTRES *)GetNextRes(R_CLIENT, NULL); if (!me) { Emsg1(M_FATAL, 0, _("No File daemon resource defined in %s\n" "Without that I don't know who I am :-(\n"), configfile); OK = false; } else { if (GetNextRes(R_CLIENT, (RES *) me) != NULL) { Emsg1(M_FATAL, 0, _("Only one Client resource permitted in %s\n"), configfile); OK = false; } my_name_is(0, NULL, me->hdr.name); if (!me->messages) { me->messages = (MSGSRES *)GetNextRes(R_MSGS, NULL); if (!me->messages) { Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile); OK = false; } } /* tls_require implies tls_enable */ if (me->tls_require) { #ifndef HAVE_TLS Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); OK = false; #else me->tls_enable = true; #endif } need_tls = me->tls_enable || me->tls_authenticate; if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && need_tls) { Emsg1(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for File daemon in %s.\n"), configfile); OK = false; } /* If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (need_tls || me->tls_require)) { /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ me->tls_ctx = new_tls_context(me->tls_ca_certfile, me->tls_ca_certdir, me->tls_crlfile, me->tls_certfile, me->tls_keyfile, NULL, NULL, NULL, me->tls_verify_peer); if (!me->tls_ctx) { Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for File daemon \"%s\" in %s.\n"), me->hdr.name, configfile); OK = false; } set_tls_enable(me->tls_ctx, need_tls); set_tls_require(me->tls_ctx, me->tls_require); } if (me->pki_encrypt || me->pki_sign) { #ifndef HAVE_CRYPTO Jmsg(NULL, M_FATAL, 0, _("PKI encryption/signing enabled but not compiled into Bareos.\n")); OK = false; #endif } /* pki_encrypt implies pki_sign */ if (me->pki_encrypt) { me->pki_sign = true; } if ((me->pki_encrypt || me->pki_sign) && !me->pki_keypair_file) { Emsg2(M_FATAL, 0, _("\"PKI Key Pair\" must be defined for File" " daemon \"%s\" in %s if either \"PKI Sign\" or" " \"PKI Encrypt\" are enabled.\n"), me->hdr.name, configfile); OK = false; } /* If everything is well, attempt to initialize our public/private keys */ if (OK && (me->pki_encrypt || me->pki_sign)) { char *filepath; /* Load our keypair */ me->pki_keypair = crypto_keypair_new(); if (!me->pki_keypair) { Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n")); OK = false; } else { if (!crypto_keypair_load_cert(me->pki_keypair, me->pki_keypair_file)) { Emsg2(M_FATAL, 0, _("Failed to load public certificate for File" " daemon \"%s\" in %s.\n"), me->hdr.name, configfile); OK = false; } if (!crypto_keypair_load_key(me->pki_keypair, me->pki_keypair_file, NULL, NULL)) { Emsg2(M_FATAL, 0, _("Failed to load private key for File" " daemon \"%s\" in %s.\n"), me->hdr.name, configfile); OK = false; } } /* * Trusted Signers. We're always trusted. */ me->pki_signers = New(alist(10, not_owned_by_alist)); if (me->pki_keypair) { me->pki_signers->append(crypto_keypair_dup(me->pki_keypair)); } /* If additional signing public keys have been specified, load them up */ if (me->pki_signing_key_files) { foreach_alist(filepath, me->pki_signing_key_files) { X509_KEYPAIR *keypair; keypair = crypto_keypair_new(); if (!keypair) { Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n")); OK = false; } else { if (crypto_keypair_load_cert(keypair, filepath)) { me->pki_signers->append(keypair); /* Attempt to load a private key, if available */ if (crypto_keypair_has_key(filepath)) { if (!crypto_keypair_load_key(keypair, filepath, NULL, NULL)) { Emsg3(M_FATAL, 0, _("Failed to load private key from file %s for File" " daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile); OK = false; } } } else { Emsg3(M_FATAL, 0, _("Failed to load trusted signer certificate" " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile); OK = false; } } } } /* * Crypto recipients. We're always included as a recipient. * The symmetric session key will be encrypted for each of these readers. */ me->pki_recipients = New(alist(10, not_owned_by_alist)); if (me->pki_keypair) { me->pki_recipients->append(crypto_keypair_dup(me->pki_keypair)); } /* If additional keys have been specified, load them up */ if (me->pki_master_key_files) { foreach_alist(filepath, me->pki_master_key_files) { X509_KEYPAIR *keypair; keypair = crypto_keypair_new(); if (!keypair) { Emsg0(M_FATAL, 0, _("Failed to allocate a new keypair object.\n")); OK = false; } else { if (crypto_keypair_load_cert(keypair, filepath)) { me->pki_recipients->append(keypair); } else { Emsg3(M_FATAL, 0, _("Failed to load master key certificate" " from file %s for File daemon \"%s\" in %s.\n"), filepath, me->hdr.name, configfile); OK = false; } } } } } } /* Verify that a director record exists */ LockRes(); director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); UnlockRes(); if (!director) { Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"), configfile); OK = false; } foreach_res(director, R_DIRECTOR) { /* tls_require implies tls_enable */ if (director->tls_require) { #ifndef HAVE_TLS Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); OK = false; continue; #else director->tls_enable = true; #endif } need_tls = director->tls_enable || director->tls_authenticate; if (!director->tls_certfile && need_tls) { Emsg2(M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } if (!director->tls_keyfile && need_tls) { Emsg2(M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && need_tls && director->tls_verify_peer) { Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s." " At least one CA certificate store is required" " when using \"TLS Verify Peer\".\n"), director->hdr.name, configfile); OK = false; } /* If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (need_tls || director->tls_require)) { /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ director->tls_ctx = new_tls_context(director->tls_ca_certfile, director->tls_ca_certdir, director->tls_crlfile, director->tls_certfile, director->tls_keyfile, NULL, NULL, director->tls_dhfile, director->tls_verify_peer); if (!director->tls_ctx) { Emsg2(M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } set_tls_enable(director->tls_ctx, need_tls); set_tls_require(director->tls_ctx, director->tls_require); } } UnlockRes(); if (OK) { close_msg(NULL); /* close temp message handler */ init_msg(NULL, me->messages); /* open user specified message handler */ } return OK; } bareos-Release-14.2.6/src/filed/filed.h000066400000000000000000000026271263011562700175550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon specific configuration and defines * * Kern Sibbald, Jan MMI */ #define FILE_DAEMON 1 #include "filed_conf.h" #include "lib/breg.h" #include "lib/htable.h" #include "lib/runscript.h" #include "findlib/find.h" #include "fd_plugins.h" #include "ch.h" #include "backup.h" #include "restore.h" #include "protos.h" /* file daemon prototypes */ extern CLIENTRES *me; /* "Global" Client resource */ void terminate_filed(int sig); bareos-Release-14.2.6/src/filed/filed_conf.c000066400000000000000000000520461263011562700205550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main configuration file parser for Bareos File Daemon (Client) * some parts may be split into separate files such as * the schedule configuration (sch_config.c). * * Note, the configuration file parser consists of three parts * * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and * lib/parse_config.h. These files contain the parser code, * some utility routines, and the common store routines * (name, int, string). * * 3. The daemon specific file, which contains the Resource * definitions as well as any specific store routines * for the resource records. * * Kern Sibbald, September MM */ #include "bareos.h" #include "filed.h" /* * Define the first and last resource ID record * types. Note, these should be unique for each * daemon though not a requirement. */ static RES *sres_head[R_LAST - R_FIRST + 1]; static RES **res_head = sres_head; /* * Forward referenced subroutines */ /* * We build the current resource here as we are * scanning the resource configuration definition, * then move it to allocated memory when the resource * scan is complete. */ static URES res_all; static int32_t res_all_size = sizeof(res_all); /* * Definition of records permitted within each * resource with the routine to process the record * information. */ /* * Client or File daemon "Global" resources */ static RES_ITEM cli_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_client.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_client.hdr.desc), 0, 0, NULL }, { "fdport", CFG_TYPE_ADDRESSES_PORT, ITEM(res_client.FDaddrs), 0, CFG_ITEM_DEFAULT, FD_DEFAULT_PORT }, { "fdaddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_client.FDaddrs), 0, CFG_ITEM_DEFAULT, FD_DEFAULT_PORT }, { "fdaddresses", CFG_TYPE_ADDRESSES, ITEM(res_client.FDaddrs), 0, CFG_ITEM_DEFAULT, FD_DEFAULT_PORT }, { "fdsourceaddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_client.FDsrc_addr), 0, CFG_ITEM_DEFAULT, "0" }, { "workingdirectory", CFG_TYPE_DIR, ITEM(res_client.working_directory), 0, CFG_ITEM_DEFAULT, _PATH_BAREOS_WORKINGDIR }, { "piddirectory", CFG_TYPE_DIR, ITEM(res_client.pid_directory), 0, CFG_ITEM_DEFAULT, _PATH_BAREOS_PIDDIR }, { "subsysdirectory", CFG_TYPE_DIR, ITEM(res_client.subsys_directory), CFG_ITEM_DEPRECATED, 0, NULL }, { "plugindirectory", CFG_TYPE_DIR, ITEM(res_client.plugin_directory), 0, 0, NULL }, { "pluginnames", CFG_TYPE_PLUGIN_NAMES, ITEM(res_client.plugin_names), 0, 0, NULL }, { "scriptsdirectory", CFG_TYPE_DIR, ITEM(res_client.scripts_directory), 0, 0, NULL }, { "maximumconcurrentjobs", CFG_TYPE_PINT32, ITEM(res_client.MaxConcurrentJobs), 0, CFG_ITEM_DEFAULT, "20" }, { "messages", CFG_TYPE_RES, ITEM(res_client.messages), R_MSGS, 0, NULL }, { "sdconnecttimeout", CFG_TYPE_TIME, ITEM(res_client.SDConnectTimeout), 0, CFG_ITEM_DEFAULT, "1800" /* 30 minutes */ }, { "heartbeatinterval", CFG_TYPE_TIME, ITEM(res_client.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { "maximumnetworkbuffersize", CFG_TYPE_PINT32, ITEM(res_client.max_network_buffer_size), 0, 0, NULL }, #ifdef DATA_ENCRYPTION { "pkisignatures", CFG_TYPE_BOOL, ITEM(res_client.pki_sign), 0, CFG_ITEM_DEFAULT, "false" }, { "pkiencryption", CFG_TYPE_BOOL, ITEM(res_client.pki_encrypt), 0, CFG_ITEM_DEFAULT, "false" }, { "pkikeypair", CFG_TYPE_DIR, ITEM(res_client.pki_keypair_file), 0, 0, NULL }, { "pkisigner", CFG_TYPE_ALIST_DIR, ITEM(res_client.pki_signing_key_files), 0, 0, NULL }, { "pkimasterkey", CFG_TYPE_ALIST_DIR, ITEM(res_client.pki_master_key_files), 0, 0, NULL }, { "pkicipher", CFG_TYPE_CIPHER, ITEM(res_client.pki_cipher), 0, CFG_ITEM_DEFAULT, "aes128" }, #endif { "tlsauthenticate", CFG_TYPE_BOOL, ITEM(res_client.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(res_client.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(res_client.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(res_client.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(res_client.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(res_client.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(res_client.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(res_client.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(res_client.tls_keyfile), 0, 0, NULL }, { "verid", CFG_TYPE_STR, ITEM(res_client.verid), 0, 0, NULL }, { "compatible", CFG_TYPE_BOOL, ITEM(res_client.compatible), 0, CFG_ITEM_DEFAULT, "true" }, { "maximumbandwidthperjob", CFG_TYPE_SPEED, ITEM(res_client.max_bandwidth_per_job), 0, 0, NULL }, { "allowbandwidthbursting", CFG_TYPE_BOOL, ITEM(res_client.allow_bw_bursting), 0, CFG_ITEM_DEFAULT, "false" }, { "allowedscriptdir", CFG_TYPE_ALIST_DIR, ITEM(res_client.allowed_script_dirs), 0, 0, NULL }, { "allowedjobcommand", CFG_TYPE_ALIST_STR, ITEM(res_client.allowed_job_cmds), 0, 0, NULL }, { "absolutejobtimeout", CFG_TYPE_PINT32, ITEM(res_client.jcr_watchdog_time), 0, 0, NULL }, { "alwaysuselmdb", CFG_TYPE_BOOL, ITEM(res_client.always_use_lmdb), 0, CFG_ITEM_DEFAULT, "false" }, { "lmdbthreshold", CFG_TYPE_PINT32, ITEM(res_client.lmdb_threshold), 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Directors that can use our services */ static RES_ITEM dir_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_dir.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_dir.hdr.desc), 0, 0, NULL }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(res_dir.password), 0, CFG_ITEM_REQUIRED, NULL }, { "address", CFG_TYPE_STR, ITEM(res_dir.address), 0, 0, NULL }, { "monitor", CFG_TYPE_BOOL, ITEM(res_dir.monitor), 0, CFG_ITEM_DEFAULT, "false" }, { "tlsauthenticate", CFG_TYPE_BOOL, ITEM(res_dir.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(res_dir.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(res_dir.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(res_dir.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(res_dir.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(res_dir.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(res_dir.tls_keyfile), 0, 0, NULL }, { "tlsdhfile", CFG_TYPE_DIR, ITEM(res_dir.tls_dhfile), 0, 0, NULL }, { "tlsallowedcn", CFG_TYPE_ALIST_STR, ITEM(res_dir.tls_allowed_cns), 0, 0, NULL }, { "maximumbandwidthperjob", CFG_TYPE_SPEED, ITEM(res_dir.max_bandwidth_per_job), 0, 0, NULL }, { "allowedscriptdir", CFG_TYPE_ALIST_DIR, ITEM(res_dir.allowed_script_dirs), 0, 0, NULL }, { "allowedjobcommand", CFG_TYPE_ALIST_STR, ITEM(res_dir.allowed_job_cmds), 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Message resource */ #include "lib/msg_res.h" /* * This is the master resource definition. * It must have one item for each of the resources. */ static RES_TABLE resources[] = { { "director", dir_items, R_DIRECTOR, sizeof(DIRRES) }, { "filedaemon", cli_items, R_CLIENT, sizeof(CLIENTRES) }, { "client", cli_items, R_CLIENT, sizeof(CLIENTRES) }, /* alias for filedaemon */ { "messages", msgs_items, R_MSGS, sizeof(MSGSRES) }, { NULL, NULL, 0} }; /* * Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { URES *res = (URES *)reshdr; int recurse = 1; if (res == NULL) { sendit(sock, "No record for %d %s\n", type, res_to_str(type)); return; } if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_DIRECTOR: sendit(sock, "Director: name=%s password=%s\n", reshdr->name, res->res_dir.password.value); break; case R_CLIENT: sendit(sock, "Client: name=%s FDport=%d\n", reshdr->name, get_first_port_host_order(res->res_client.FDaddrs)); break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); if (res->res_msgs.mail_cmd) sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); if (res->res_msgs.operator_cmd) sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); break; default: sendit(sock, "Unknown resource type %d\n", type); } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } } /* * Free memory of resource. * NB, we don't need to worry about freeing any references * to other resources as they will be freed when that * resource chain is traversed. Mainly we worry about freeing * allocated strings (names). */ void free_resource(RES *sres, int type) { RES *nres; URES *res = (URES *)sres; if (res == NULL) { return; } /* * Common stuff -- free the resource name */ nres = (RES *)res->res_dir.hdr.next; if (res->res_dir.hdr.name) { free(res->res_dir.hdr.name); } if (res->res_dir.hdr.desc) { free(res->res_dir.hdr.desc); } switch (type) { case R_DIRECTOR: if (res->res_dir.password.value) { free(res->res_dir.password.value); } if (res->res_dir.address) { free(res->res_dir.address); } if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } if (res->res_dir.tls_ca_certfile) { free(res->res_dir.tls_ca_certfile); } if (res->res_dir.tls_ca_certdir) { free(res->res_dir.tls_ca_certdir); } if (res->res_dir.tls_crlfile) { free(res->res_dir.tls_crlfile); } if (res->res_dir.tls_certfile) { free(res->res_dir.tls_certfile); } if (res->res_dir.tls_keyfile) { free(res->res_dir.tls_keyfile); } if (res->res_dir.tls_dhfile) { free(res->res_dir.tls_dhfile); } if (res->res_dir.tls_allowed_cns) { delete res->res_dir.tls_allowed_cns; } if (res->res_dir.allowed_script_dirs) { delete res->res_dir.allowed_script_dirs; } if (res->res_dir.allowed_job_cmds) { delete res->res_dir.allowed_job_cmds; } break; case R_CLIENT: if (res->res_client.working_directory) { free(res->res_client.working_directory); } if (res->res_client.pid_directory) { free(res->res_client.pid_directory); } if (res->res_client.subsys_directory) { free(res->res_client.subsys_directory); } if (res->res_client.scripts_directory) { free(res->res_client.scripts_directory); } if (res->res_client.plugin_directory) { free(res->res_client.plugin_directory); } if (res->res_client.plugin_names) { delete res->res_client.plugin_names; } if (res->res_client.FDaddrs) { free_addresses(res->res_client.FDaddrs); } if (res->res_client.FDsrc_addr) { free_addresses(res->res_client.FDsrc_addr); } if (res->res_client.pki_keypair_file) { free(res->res_client.pki_keypair_file); } if (res->res_client.pki_keypair) { crypto_keypair_free(res->res_client.pki_keypair); } if (res->res_client.pki_signing_key_files) { delete res->res_client.pki_signing_key_files; } if (res->res_client.pki_signers) { X509_KEYPAIR *keypair; foreach_alist(keypair, res->res_client.pki_signers) { crypto_keypair_free(keypair); } delete res->res_client.pki_signers; } if (res->res_client.pki_master_key_files) { delete res->res_client.pki_master_key_files; } if (res->res_client.pki_recipients) { X509_KEYPAIR *keypair; foreach_alist(keypair, res->res_client.pki_recipients) { crypto_keypair_free(keypair); } delete res->res_client.pki_recipients; } if (res->res_client.tls_ctx) { free_tls_context(res->res_client.tls_ctx); } if (res->res_client.tls_ca_certfile) { free(res->res_client.tls_ca_certfile); } if (res->res_client.tls_ca_certdir) { free(res->res_client.tls_ca_certdir); } if (res->res_client.tls_crlfile) { free(res->res_client.tls_crlfile); } if (res->res_client.tls_certfile) { free(res->res_client.tls_certfile); } if (res->res_client.tls_keyfile) { free(res->res_client.tls_keyfile); } if (res->res_client.tls_allowed_cns) { delete res->res_client.tls_allowed_cns; } if (res->res_client.verid) { free(res->res_client.verid); } if (res->res_client.allowed_script_dirs) { delete res->res_client.allowed_script_dirs; } if (res->res_client.allowed_job_cmds) { delete res->res_client.allowed_job_cmds; } break; case R_MSGS: if (res->res_msgs.mail_cmd) { free(res->res_msgs.mail_cmd); } if (res->res_msgs.operator_cmd) { free(res->res_msgs.operator_cmd); } free_msgs_res((MSGSRES *)res); /* free message resource */ res = NULL; break; default: printf(_("Unknown resource type %d\n"), type); } /* Common stuff again -- free the resource, recurse to next one */ if (res) { free(res); } if (nres) { free_resource(nres, type); } } /* * Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * pointers (currently only in the Job resource). */ void save_resource(int type, RES_ITEM *items, int pass) { URES *res; int rindex = type - R_FIRST; int i; int error = 0; /* * Ensure that all required items are present */ for (i = 0; items[i].name; i++) { if (items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"), items[i].name, resources[rindex]); } } } /* * During pass 2, we looked up pointers to all the resources * referrenced in the current resource, , now we * must copy their address from the static record to the allocated * record. */ if (pass == 2) { switch (type) { case R_MSGS: /* * Resources not containing a resource */ break; case R_DIRECTOR: /* * Resources containing another resource */ if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ABORT, 0, _("Cannot find Director resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_dir.tls_allowed_cns = res_all.res_dir.tls_allowed_cns; res->res_dir.allowed_script_dirs = res_all.res_dir.allowed_script_dirs; res->res_dir.allowed_job_cmds = res_all.res_dir.allowed_job_cmds; } break; case R_CLIENT: if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ABORT, 0, _("Cannot find Client resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_client.plugin_names = res_all.res_client.plugin_names; res->res_client.pki_signing_key_files = res_all.res_client.pki_signing_key_files; res->res_client.pki_master_key_files = res_all.res_client.pki_master_key_files; res->res_client.pki_signers = res_all.res_client.pki_signers; res->res_client.pki_recipients = res_all.res_client.pki_recipients; res->res_client.messages = res_all.res_client.messages; res->res_client.tls_allowed_cns = res_all.res_client.tls_allowed_cns; res->res_client.allowed_script_dirs = res_all.res_client.allowed_script_dirs; res->res_client.allowed_job_cmds = res_all.res_client.allowed_job_cmds; } break; default: Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type); error = 1; break; } /* * Note, the resoure name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { free(res_all.res_dir.hdr.name); res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { free(res_all.res_dir.hdr.desc); res_all.res_dir.hdr.desc = NULL; } return; } /* * Common */ if (!error) { res = (URES *)malloc(resources[rindex].size); memcpy(res, &res_all, resources[rindex].size); if (!res_head[rindex]) { res_head[rindex] = (RES *)res; /* store first entry */ } else { RES *next, *last; /* * Add new res to end of chain */ for (last = next = res_head[rindex]; next; next = next->next) { last = next; if (bstrcmp(next->name, res->res_dir.hdr.name)) { Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), resources[rindex].name, res->res_dir.hdr.name); } } last->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), res->res_dir.hdr.name); } } } static struct s_kw CryptoCiphers[] = { { "aes128", CRYPTO_CIPHER_AES_128_CBC }, { "aes192", CRYPTO_CIPHER_AES_192_CBC }, { "aes256", CRYPTO_CIPHER_AES_256_CBC }, { "camellia128", CRYPTO_CIPHER_CAMELLIA_128_CBC }, { "camellia192", CRYPTO_CIPHER_CAMELLIA_192_CBC }, { "camellia256", CRYPTO_CIPHER_CAMELLIA_256_CBC }, { "aes128hmacsha1", CRYPTO_CIPHER_AES_128_CBC_HMAC_SHA1 }, { "aes256hmacsha1", CRYPTO_CIPHER_AES_256_CBC_HMAC_SHA1 }, { "blowfish", CRYPTO_CIPHER_BLOWFISH_CBC }, { NULL, 0 } }; static void store_cipher(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Scan Crypto Ciphers name. */ for (i = 0; CryptoCiphers[i].name; i++) { if (bstrcasecmp(lc->str, CryptoCiphers[i].name)) { *(uint32_t *)(item->value) = CryptoCiphers[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Crypto Cipher option, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * callback function for init_resource * See ../lib/parse_conf.c, function init_resource, for more generic handling. */ static void init_resource_cb(RES_ITEM *item, int pass) { switch (pass) { case 1: switch (item->type) { case CFG_TYPE_CIPHER: for (int i = 0; CryptoCiphers[i].name; i++) { if (bstrcasecmp(item->default_value, CryptoCiphers[i].name)) { *(uint32_t *)(item->value) = CryptoCiphers[i].token; } } break; default: break; } break; default: break; } } /* * callback function for parse_config * See ../lib/parse_conf.c, function parse_config, for more generic handling. */ static void parse_config_cb(LEX *lc, RES_ITEM *item, int index, int pass) { switch (item->type) { case CFG_TYPE_CIPHER: store_cipher(lc, item, index, pass); break; default: break; } } bool parse_fd_config(CONFIG *config, const char *configfile, int exit_code) { config->init(configfile, NULL, NULL, init_resource_cb, parse_config_cb, NULL, exit_code, (void *)&res_all, res_all_size, R_FIRST, R_LAST, resources, res_head); return config->parse_config(); } bareos-Release-14.2.6/src/filed/filed_conf.h000066400000000000000000000132261263011562700205570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon specific configuration * * Kern Sibbald, Sep MM */ /* * Resource codes -- they must be sequential for indexing */ enum { R_DIRECTOR = 1001, R_CLIENT, R_MSGS, R_FIRST = R_DIRECTOR, R_LAST = R_MSGS /* keep this updated */ }; /* * Some resource attributes */ enum { R_NAME = 1020, R_ADDRESS, R_PASSWORD, R_TYPE }; /* Definition of the contents of each Resource */ struct DIRRES { RES hdr; s_password password; /* Director password */ char *address; /* Director address or zero */ bool monitor; /* Have only access to status and .status functions */ bool tls_authenticate; /* Authenticate with TSL */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Server Certificate File */ char *tls_keyfile; /* TLS Server Key File */ char *tls_dhfile; /* TLS Diffie-Hellman Parameters */ alist *tls_allowed_cns; /* TLS Allowed Common Names */ alist *allowed_script_dirs; /* Only allow to run scripts in this directories */ alist *allowed_job_cmds; /* Only allow the following Job commands to be executed */ uint64_t max_bandwidth_per_job; /* Bandwidth limitation (per director) */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; struct CLIENTRES { RES hdr; dlist *FDaddrs; dlist *FDsrc_addr; /* Address to source connections from */ char *working_directory; char *pid_directory; char *subsys_directory; char *plugin_directory; /* Plugin directory */ alist *plugin_names; char *scripts_directory; MSGSRES *messages; /* Daemon message handler */ uint32_t MaxConcurrentJobs; utime_t SDConnectTimeout; /* Timeout in seconds */ utime_t heartbeat_interval; /* Interval to send heartbeats */ uint32_t max_network_buffer_size; /* Max network buf size */ uint32_t jcr_watchdog_time; /* Absolute time after which a Job gets terminated regardless of its progress */ bool compatible; /* Support old protocol keywords */ bool allow_bw_bursting; /* Allow bursting with bandwidth limiting */ bool pki_sign; /* Enable Data Integrity Verification via Digital Signatures */ bool pki_encrypt; /* Enable Data Encryption */ char *pki_keypair_file; /* PKI Key Pair File */ alist *pki_signing_key_files; /* PKI Signing Key Files */ alist *pki_master_key_files; /* PKI Master Key Files */ crypto_cipher_t pki_cipher; /* PKI Cipher to use */ bool tls_authenticate; /* Authenticate with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ bool nokeepalive; /* Don't use SO_KEEPALIVE on sockets */ bool always_use_lmdb; /* Use LMDB for accurate data */ uint32_t lmdb_threshold; /* Switch to using LDMD when number of accurate entries exceeds treshold. */ X509_KEYPAIR *pki_keypair; /* Shared PKI Public/Private Keypair */ alist *pki_signers; /* Shared PKI Trusted Signers */ alist *pki_recipients; /* Shared PKI Recipients */ alist *tls_allowed_cns; /* TLS Allowed Common Names */ alist *allowed_script_dirs; /* Only allow to run scripts in this directories */ alist *allowed_job_cmds; /* Only allow the following Job commands to be executed */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ char *verid; /* Custom Id to print in version command */ uint64_t max_bandwidth_per_job; /* Bandwidth limitation (global) */ }; /* Define the Union of all the above * resource structure definitions. */ union URES { DIRRES res_dir; CLIENTRES res_client; MSGSRES res_msgs; RES hdr; }; bareos-Release-14.2.6/src/filed/fileset.c000066400000000000000000000515711263011562700201220ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon Include Exclude pattern handling. * * Kern Sibbald, October MM * * Extracted from other source files by Marco van Wieringen, September 2012 */ #include "bareos.h" #include "filed.h" #include "ch.h" /* Forward referenced functions */ static int set_options(findFOPTS *fo, const char *opts); extern "C" char *job_code_callback_filed(JCR *jcr, const char* param) { switch (param[0]) { case 'D': if (jcr->director) { return jcr->director->hdr.name; } break; } return NULL; } bool init_fileset(JCR *jcr) { FF_PKT *ff; findFILESET *fileset; if (!jcr->ff) { return false; } ff = jcr->ff; if (ff->fileset) { return false; } fileset = (findFILESET *)malloc(sizeof(findFILESET)); memset(fileset, 0, sizeof(findFILESET)); ff->fileset = fileset; fileset->state = state_none; fileset->include_list.init(1, true); fileset->exclude_list.init(1, true); return true; } static void append_file(JCR *jcr, findINCEXE *incexe, const char *buf, bool is_file) { if (is_file) { /* * Sanity check never append empty file patterns. */ if (strlen(buf) > 0) { incexe->name_list.append(new_dlistString(buf)); } } else if (me->plugin_directory) { generate_plugin_event(jcr, bEventPluginCommand, (void *)buf); incexe->plugin_list.append(new_dlistString(buf)); } else { Jmsg(jcr, M_FATAL, 0, _("Plugin Directory not defined. Cannot use plugin: \"%s\"\n"), buf); } } /** * Add fname to include/exclude fileset list. First check for * | and < and if necessary perform command. */ void add_file_to_fileset(JCR *jcr, const char *fname, bool is_file) { findFILESET *fileset = jcr->ff->fileset; char *p; BPIPE *bpipe; POOLMEM *fn; FILE *ffd; char buf[1000]; int ch; int status; p = (char *)fname; ch = (uint8_t)*p; switch (ch) { case '|': p++; /* skip over | */ fn = get_pool_memory(PM_FNAME); fn = edit_job_codes(jcr, fn, p, "", job_code_callback_filed); bpipe = open_bpipe(fn, 0, "r"); if (!bpipe) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"), p, be.bstrerror()); free_pool_memory(fn); return; } free_pool_memory(fn); while (fgets(buf, sizeof(buf), bpipe->rfd)) { strip_trailing_junk(buf); append_file(jcr, fileset->incexe, buf, is_file); } if ((status = close_bpipe(bpipe)) != 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. status=%d: ERR=%s\n"), p, be.code(status), be.bstrerror(status)); return; } break; case '<': Dmsg1(100, "Doing < of '%s' include on client.\n", p + 1); p++; /* skip over < */ if ((ffd = fopen(p, "rb")) == NULL) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Cannot open FileSet input file: %s. ERR=%s\n"), p, be.bstrerror()); return; } while (fgets(buf, sizeof(buf), ffd)) { strip_trailing_junk(buf); append_file(jcr, fileset->incexe, buf, is_file); } fclose(ffd); break; default: append_file(jcr, fileset->incexe, fname, is_file); break; } } findINCEXE *get_incexe(JCR *jcr) { if (jcr->ff && jcr->ff->fileset) { return jcr->ff->fileset->incexe; } return NULL; } void set_incexe(JCR *jcr, findINCEXE *incexe) { findFILESET *fileset = jcr->ff->fileset; fileset->incexe = incexe; } /** * Add a regex to the current fileset */ int add_regex_to_fileset(JCR *jcr, const char *item, int type) { findFOPTS *current_opts = start_options(jcr->ff); regex_t *preg; int rc; char prbuf[500]; preg = (regex_t *)malloc(sizeof(regex_t)); if (bit_is_set(FO_IGNORECASE, current_opts->flags)) { rc = regcomp(preg, item, REG_EXTENDED|REG_ICASE); } else { rc = regcomp(preg, item, REG_EXTENDED); } if (rc != 0) { regerror(rc, preg, prbuf, sizeof(prbuf)); regfree(preg); free(preg); Jmsg(jcr, M_FATAL, 0, _("REGEX %s compile error. ERR=%s\n"), item, prbuf); return state_error; } if (type == ' ') { current_opts->regex.append(preg); } else if (type == 'D') { current_opts->regexdir.append(preg); } else if (type == 'F') { current_opts->regexfile.append(preg); } else { return state_error; } return state_options; } /** * Add a wild card to the current fileset */ int add_wild_to_fileset(JCR *jcr, const char *item, int type) { findFOPTS *current_opts = start_options(jcr->ff); if (type == ' ') { current_opts->wild.append(bstrdup(item)); } else if (type == 'D') { current_opts->wilddir.append(bstrdup(item)); } else if (type == 'F') { current_opts->wildfile.append(bstrdup(item)); } else if (type == 'B') { current_opts->wildbase.append(bstrdup(item)); } else { return state_error; } return state_options; } /** * Add options to the current fileset */ int add_options_to_fileset(JCR *jcr, const char *item) { findFOPTS *current_opts = start_options(jcr->ff); set_options(current_opts, item); return state_options; } void add_fileset(JCR *jcr, const char *item) { FF_PKT *ff = jcr->ff; findFILESET *fileset = ff->fileset; int code, subcode; int state = fileset->state; findFOPTS *current_opts; /* * Get code, optional subcode, and position item past the dividing space */ Dmsg1(100, "%s\n", item); code = item[0]; if (code != '\0') { ++item; } subcode = ' '; /* A space is always a valid subcode */ if (item[0] != '\0' && item[0] != ' ') { subcode = item[0]; ++item; } if (*item == ' ') { ++item; } /* * Skip all lines we receive after an error */ if (state == state_error) { Dmsg0(100, "State=error return\n"); return; } /** * The switch tests the code for validity. * The subcode is always good if it is a space, otherwise we must confirm. * We set state to state_error first assuming the subcode is invalid, * requiring state to be set in cases below that handle subcodes. */ if (subcode != ' ') { state = state_error; Dmsg0(100, "Set state=error or double code.\n"); } switch (code) { case 'I': (void)new_include(jcr->ff->fileset); break; case 'E': (void)new_exclude(jcr->ff->fileset); break; case 'N': /* Null */ state = state_none; break; case 'F': /* File */ state = state_include; add_file_to_fileset(jcr, item, true); break; case 'P': /* Plugin */ state = state_include; add_file_to_fileset(jcr, item, false); break; case 'R': /* Regex */ state = add_regex_to_fileset(jcr, item, subcode); break; case 'B': current_opts = start_options(ff); current_opts->base.append(bstrdup(item)); state = state_options; break; case 'X': /* Filetype or Drive type */ current_opts = start_options(ff); state = state_options; if (subcode == ' ') { current_opts->fstype.append(bstrdup(item)); } else if (subcode == 'D') { current_opts->drivetype.append(bstrdup(item)); } else { state = state_error; } break; case 'W': /* Wild cards */ state = add_wild_to_fileset(jcr, item, subcode); break; case 'O': /* Options */ state = add_options_to_fileset(jcr, item); break; case 'Z': /* Ignore dir */ state = state_include; fileset->incexe->ignoredir.append(bstrdup(item)); break; case 'D': current_opts = start_options(ff); state = state_options; break; case 'T': current_opts = start_options(ff); state = state_options; break; case 'G': /* Plugin command for this Option block */ current_opts = start_options(ff); current_opts->plugin = bstrdup(item); state = state_options; break; default: Jmsg(jcr, M_FATAL, 0, _("Invalid FileSet command: %s\n"), item); state = state_error; break; } ff->fileset->state = state; } bool term_fileset(JCR *jcr) { findFILESET *fileset; fileset = jcr->ff->fileset; #ifdef HAVE_WIN32 /* * Expand the fileset to include all drive letters when the fileset includes a File = / entry. */ if (!expand_win32_fileset(jcr->ff->fileset)) { return false; } /* * Exclude entries in NotToBackup registry key */ if (!exclude_win32_not_to_backup_registry_entries(jcr, jcr->ff)) { return false; } #endif #ifdef xxx_DEBUG_CODE for (int i = 0; i < fileset->include_list.size(); i++) { dlistString *node; findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); Dmsg0(400, "I\n"); for (int j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); for (int k = 0; k < fo->regex.size(); k++) { Dmsg1(400, "R %s\n", (char *)fo->regex.get(k)); } for (int k = 0; k < fo->regexdir.size(); k++) { Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k)); } for (int k = 0; k < fo->regexfile.size(); k++) { Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k)); } for (int k = 0; k < fo->wild.size(); k++) { Dmsg1(400, "W %s\n", (char *)fo->wild.get(k)); } for (int k = 0; k < fo->wilddir.size(); k++) { Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k)); } for (int k = 0; k < fo->wildfile.size(); k++) { Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k)); } for (int k = 0; k < fo->wildbase.size(); k++) { Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k)); } for (int k = 0; k < fo->base.size(); k++) { Dmsg1(400, "B %s\n", (char *)fo->base.get(k)); } for (int k = 0; k < fo->fstype.size(); k++) { Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k)); } for (int k = 0; k < fo->drivetype.size(); k++) { Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k)); } if (fo->plugin) { Dmsg1(400, "G %s\n", (char *)fo->plugin); } } for (int k = 0; k < incexe->ignoredir.size(); k++) { Dmsg1(400, "Z %s\n", (char *)incexe->ignoredir.get(k)); } foreach_dlist(node, &incexe->name_list) { Dmsg1(400, "F %s\n", node->c_str()); } foreach_dlist(node, &incexe->plugin_list) { Dmsg1(400, "P %s\n", node->c_str()); } } for (int i = 0; i < fileset->exclude_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); Dmsg0(400, "E\n"); for (int j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); for (int k = 0; k < fo->regex.size(); k++) { Dmsg1(400, "R %s\n", (char *)fo->regex.get(k)); } for (int k = 0; k < fo->regexdir.size(); k++) { Dmsg1(400, "RD %s\n", (char *)fo->regexdir.get(k)); } for (int k = 0; k < fo->regexfile.size(); k++) { Dmsg1(400, "RF %s\n", (char *)fo->regexfile.get(k)); } for (int k = 0; k < fo->wild.size(); k++) { Dmsg1(400, "W %s\n", (char *)fo->wild.get(k)); } for (int k = 0; k < fo->wilddir.size(); k++) { Dmsg1(400, "WD %s\n", (char *)fo->wilddir.get(k)); } for (int k = 0; k < fo->wildfile.size(); k++) { Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k)); } for (int k = 0; k < fo->wildbase.size(); k++) { Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k)); } for (int k = 0; kbase.size(); k++) { Dmsg1(400, "B %s\n", (char *)fo->base.get(k)); } for (int k = 0; k < fo->fstype.size(); k++) { Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k)); } for (int k = 0; k < fo->drivetype.size(); k++) { Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k)); } } dlistString *node; foreach_dlist(node, &incexe->name_list) { Dmsg1(400, "F %s\n", node->c_str()); } foreach_dlist(node, &incexe->plugin_list) { Dmsg1(400, "P %s\n", node->c_str()); } } #endif /* * Generate bEventPluginCommand events for each Options Plugin. */ for (int i = 0; i < fileset->include_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); for (int j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); if (fo->plugin) { generate_plugin_event(jcr, bEventPluginCommand, (void *)fo->plugin); } } } return jcr->ff->fileset->state != state_error; } /** * As an optimization, we should do this during * "compile" time in filed/job.c, and keep only a bit mask * and the Verify options. */ static int set_options(findFOPTS *fo, const char *opts) { int j; const char *p; char strip[21]; char size[50]; for (p = opts; *p; p++) { switch (*p) { case 'A': set_bit(FO_ACL, fo->flags); break; case 'a': /* Alway replace */ case '0': /* No option */ break; case 'C': /* Accurate options */ /* * Copy Accurate Options */ for (j = 0; *p && *p != ':'; p++) { fo->AccurateOpts[j] = *p; if (j < (int)sizeof(fo->AccurateOpts) - 1) { j++; } } fo->AccurateOpts[j] = 0; break; case 'c': set_bit(FO_CHKCHANGES, fo->flags); break; case 'd': switch(*(p + 1)) { case '1': fo->shadow_type = check_shadow_local_warn; break; case '2': fo->shadow_type = check_shadow_local_remove; break; case '3': fo->shadow_type = check_shadow_global_warn; break; case '4': fo->shadow_type = check_shadow_global_remove; break; } break; case 'e': set_bit(FO_EXCLUDE, fo->flags); break; case 'f': set_bit(FO_MULTIFS, fo->flags); break; case 'H': /* No hard link handling */ set_bit(FO_NO_HARDLINK, fo->flags); break; case 'h': /* No recursion */ set_bit(FO_NO_RECURSION, fo->flags); break; case 'i': set_bit(FO_IGNORECASE, fo->flags); break; case 'J': /* Basejob options */ /* * Copy BaseJob Options */ for (j = 0; *p && *p != ':'; p++) { fo->BaseJobOpts[j] = *p; if (j < (int)sizeof(fo->BaseJobOpts) - 1) { j++; } } fo->BaseJobOpts[j] = 0; break; case 'K': set_bit(FO_NOATIME, fo->flags); break; case 'k': set_bit(FO_KEEPATIME, fo->flags); break; case 'M': /* MD5 */ set_bit(FO_MD5, fo->flags); break; case 'm': set_bit(FO_MTIMEONLY, fo->flags); break; case 'N': set_bit(FO_HONOR_NODUMP, fo->flags); break; case 'n': set_bit(FO_NOREPLACE, fo->flags); break; case 'P': /* Strip path */ /* * Get integer */ p++; /* skip P */ for (j = 0; *p && *p != ':'; p++) { strip[j] = *p; if (j < (int)sizeof(strip) - 1) { j++; } } strip[j] = 0; fo->strip_path = atoi(strip); set_bit(FO_STRIPPATH, fo->flags); Dmsg2(100, "strip=%s strip_path=%d\n", strip, fo->strip_path); break; case 'p': /* Use portable data format */ set_bit(FO_PORTABLE, fo->flags); break; case 'R': /* Resource forks and Finder Info */ set_bit(FO_HFSPLUS, fo->flags); break; case 'r': /* Read fifo */ set_bit(FO_READFIFO, fo->flags); break; case 'S': switch(*(p + 1)) { case '1': set_bit(FO_SHA1, fo->flags); p++; break; #ifdef HAVE_SHA2 case '2': set_bit(FO_SHA256, fo->flags); p++; break; case '3': set_bit(FO_SHA512, fo->flags); p++; break; #endif default: /* * If 2 or 3 is seen here, SHA2 is not configured, so eat the option, and drop back to SHA-1. */ if (p[1] == '2' || p[1] == '3') { p++; } set_bit(FO_SHA1, fo->flags); break; } break; case 's': set_bit(FO_SPARSE, fo->flags); break; case 'V': /* verify options */ /* * Copy Verify Options */ for (j = 0; *p && *p != ':'; p++) { fo->VerifyOpts[j] = *p; if (j < (int)sizeof(fo->VerifyOpts) - 1) { j++; } } fo->VerifyOpts[j] = 0; break; case 'W': set_bit(FO_ENHANCEDWILD, fo->flags); break; case 'w': set_bit(FO_IF_NEWER, fo->flags); break; case 'x': set_bit(FO_NO_AUTOEXCL, fo->flags); break; case 'X': set_bit(FO_XATTR, fo->flags); break; case 'Z': /* Compression */ p++; /* Skip Z */ if (*p >= '0' && *p <= '9') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_GZIP; fo->Compress_level = *p - '0'; } else if (*p == 'o') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_LZO1X; fo->Compress_level = 1; /* not used with LZO */ } else if (*p == 'f') { p++; if (*p == 'f') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_FZFZ; fo->Compress_level = 1; /* not used with FZFZ */ } else if (*p == '4') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_FZ4L; fo->Compress_level = 1; /* not used with FZ4L */ } else if (*p == 'h') { set_bit(FO_COMPRESS, fo->flags); fo->Compress_algo = COMPRESS_FZ4H; fo->Compress_level = 1; /* not used with FZ4H */ } } break; case 'z': /* Min, max or approx size or size range */ p++; /* Skip z */ for (j = 0; *p && *p != ':'; p++) { size[j] = *p; if (j < (int)sizeof(size) - 1) { j++; } } size[j] = 0; if (!fo->size_match) { fo->size_match = (struct s_sz_matching *)malloc(sizeof(struct s_sz_matching)); } if (!parse_size_match(size, fo->size_match)) { Emsg1(M_ERROR, 0, _("Unparseable size option: %s\n"), size); } break; default: Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p); break; } } return state_options; } bareos-Release-14.2.6/src/filed/heartbeat.c000066400000000000000000000141731263011562700204230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon heartbeat routines * Listens for heartbeats coming from the SD * If configured, sends heartbeats to Dir * * Kern Sibbald, May MMIII */ #include "bareos.h" #include "filed.h" #define WAIT_INTERVAL 5 extern "C" void *sd_heartbeat_thread(void *arg); extern "C" void *dir_heartbeat_thread(void *arg); extern bool no_signals; /* * Listen on the SD socket for heartbeat signals. * Send heartbeats to the Director every HB_TIME * seconds. */ extern "C" void *sd_heartbeat_thread(void *arg) { int32_t n; JCR *jcr = (JCR *)arg; BSOCK *sd, *dir; time_t last_heartbeat = time(NULL); time_t now; pthread_detach(pthread_self()); /* * Get our own local copy */ sd = jcr->store_bsock->clone(); dir = jcr->dir_bsock->clone(); jcr->hb_bsock = sd; jcr->hb_started = true; jcr->hb_dir_bsock = dir; dir->m_suppress_error_msgs = true; sd->m_suppress_error_msgs = true; /* Hang reading the socket to the SD, and every time we get * a heartbeat or we get a wait timeout (5 seconds), we * check to see if we need to send a heartbeat to the * Director. */ while (!sd->is_stop()) { n = bnet_wait_data_intr(sd, WAIT_INTERVAL); if (n < 0 || sd->is_stop()) { break; } if (me->heartbeat_interval) { now = time(NULL); if (now-last_heartbeat >= me->heartbeat_interval) { dir->signal(BNET_HEARTBEAT); if (dir->is_stop()) { break; } last_heartbeat = now; } } if (n == 1) { /* input waiting */ sd->recv(); /* read it -- probably heartbeat from sd */ if (sd->is_stop()) { break; } if (sd->msglen <= 0) { Dmsg1(100, "Got BNET_SIG %d from SD\n", sd->msglen); } else { Dmsg2(100, "Got %d bytes from SD. MSG=%s\n", sd->msglen, sd->msg); } } Dmsg2(200, "wait_intr=%d stop=%d\n", n, is_bnet_stop(sd)); } sd->close(); dir->close(); delete sd; delete dir; jcr->hb_bsock = NULL; jcr->hb_started = false; jcr->hb_dir_bsock = NULL; return NULL; } /* Startup the heartbeat thread -- see above */ void start_heartbeat_monitor(JCR *jcr) { /* * If no signals are set, do not start the heartbeat because * it gives a constant stream of TIMEOUT_SIGNAL signals that * make debugging impossible. */ if (!no_signals) { jcr->hb_bsock = NULL; jcr->hb_started = false; jcr->hb_dir_bsock = NULL; pthread_create(&jcr->heartbeat_id, NULL, sd_heartbeat_thread, (void *)jcr); } } /* Terminate the heartbeat thread. Used for both SD and DIR */ void stop_heartbeat_monitor(JCR *jcr) { int cnt = 0; if (no_signals) { return; } /* Wait max 10 secs for heartbeat thread to start */ while (!jcr->hb_started && cnt++ < 200) { bmicrosleep(0, 50000); /* wait for start */ } if (jcr->hb_started) { jcr->hb_bsock->set_timed_out(); /* set timed_out to terminate read */ jcr->hb_bsock->set_terminated(); /* set to terminate read */ } if (jcr->hb_dir_bsock) { jcr->hb_dir_bsock->set_timed_out(); /* set timed_out to terminate read */ jcr->hb_dir_bsock->set_terminated(); /* set to terminate read */ } if (jcr->hb_started) { Dmsg0(100, "Send kill to heartbeat id\n"); pthread_kill(jcr->heartbeat_id, TIMEOUT_SIGNAL); /* make heartbeat thread go away */ bmicrosleep(0, 50000); } cnt = 0; /* * Wait max 100 secs for heartbeat thread to stop */ while (jcr->hb_started && cnt++ < 200) { pthread_kill(jcr->heartbeat_id, TIMEOUT_SIGNAL); /* make heartbeat thread go away */ bmicrosleep(0, 500000); } if (jcr->hb_bsock) { delete jcr->hb_bsock; jcr->hb_bsock = NULL; } if (jcr->hb_dir_bsock) { delete jcr->hb_dir_bsock; jcr->hb_dir_bsock = NULL; } } /* * Thread for sending heartbeats to the Director when there * is no SD monitoring needed -- e.g. restore and verify Vol * both do their own read() on the SD socket. */ extern "C" void *dir_heartbeat_thread(void *arg) { JCR *jcr = (JCR *)arg; BSOCK *dir; time_t last_heartbeat = time(NULL); pthread_detach(pthread_self()); /* * Get our own local copy */ dir = jcr->dir_bsock->clone(); jcr->hb_bsock = dir; jcr->hb_started = true; dir->m_suppress_error_msgs = true; while (!dir->is_stop()) { time_t now, next; now = time(NULL); next = now - last_heartbeat; if (next >= me->heartbeat_interval) { dir->signal(BNET_HEARTBEAT); if (dir->is_stop()) { break; } last_heartbeat = now; } bmicrosleep(next, 0); } dir->close(); delete dir; jcr->hb_bsock = NULL; jcr->hb_started = false; return NULL; } /* * Same as above but we don't listen to the SD */ void start_dir_heartbeat(JCR *jcr) { if (me->heartbeat_interval) { jcr->dir_bsock->set_locking(); pthread_create(&jcr->heartbeat_id, NULL, dir_heartbeat_thread, (void *)jcr); } } void stop_dir_heartbeat(JCR *jcr) { if (me->heartbeat_interval) { stop_heartbeat_monitor(jcr); } } bareos-Release-14.2.6/src/filed/protos.h000066400000000000000000000071321263011562700200140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by Kern Sibbald, MM */ /* accurate.c */ bool accurate_finish(JCR *jcr); bool accurate_check_file(JCR *jcr, FF_PKT *ff_pkt); bool accurate_mark_file_as_seen(JCR *jcr, char *fname); void accurate_free(JCR *jcr); /* authenticate.c */ bool authenticate_director(JCR *jcr); bool authenticate_storagedaemon(JCR *jcr); bool authenticate_with_storagedaemon(JCR *jcr); /* backup.c */ bool blast_data_to_storage_daemon(JCR *jcr, char *addr); bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream); void strip_path(FF_PKT *ff_pkt); void unstrip_path(FF_PKT *ff_pkt); /* compression.c */ bool adjust_compression_buffers(JCR *jcr); bool adjust_decompression_buffers(JCR *jcr); bool setup_compression_context(b_ctx &bctx); /* crypto.c */ bool crypto_session_start(JCR *jcr); void crypto_session_end(JCR *jcr); bool crypto_session_send(JCR *jcr, BSOCK *sd); bool verify_signature(JCR *jcr, r_ctx &rctx); bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, char *flags, int32_t stream, RESTORE_CIPHER_CTX *cipher_ctx); void deallocate_cipher(r_ctx &rctx); void deallocate_fork_cipher(r_ctx &rctx); bool setup_encryption_context(b_ctx &bctx); bool setup_decryption_context(r_ctx &rctx, RESTORE_CIPHER_CTX &rcctx); bool encrypt_data(b_ctx *bctx, bool *need_more_data); bool decrypt_data(JCR *jcr, char **data, uint32_t *length, RESTORE_CIPHER_CTX *cipher_ctx); /* estimate.c */ int make_estimate(JCR *jcr); /* fileset.c */ bool init_fileset(JCR *jcr); void add_file_to_fileset(JCR *jcr, const char *fname, bool is_file); findINCEXE *get_incexe(JCR *jcr); void set_incexe(JCR *jcr, findINCEXE *incexe); int add_regex_to_fileset(JCR *jcr, const char *item, int type); int add_wild_to_fileset(JCR *jcr, const char *item, int type); int add_options_to_fileset(JCR *jcr, const char *item); void add_fileset(JCR *jcr, const char *item); bool term_fileset(JCR *jcr); /* heartbeat.c */ void start_heartbeat_monitor(JCR *jcr); void stop_heartbeat_monitor(JCR *jcr); void start_dir_heartbeat(JCR *jcr); void stop_dir_heartbeat(JCR *jcr); /* restore.c */ void do_restore(JCR *jcr); void free_session(r_ctx &rctx); int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level); bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length); bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp); /* sd_cmds.c */ void *handle_stored_connection(BSOCK *sd); /* verify.c */ int digest_file(JCR *jcr, FF_PKT *ff_pkt, DIGEST *digest); void do_verify(JCR *jcr); void do_verify_volume(JCR *jcr); bool calculate_and_compare_file_chksum(JCR *jcr, FF_PKT *ff_pkt, const char *fname, const char *chksum); bareos-Release-14.2.6/src/filed/restore.c000066400000000000000000001240531263011562700201460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon restore.c Restorefiles. * * Kern Sibbald, November MM */ #include "bareos.h" #include "filed.h" #include "ch.h" #if defined(HAVE_DARWIN_OS) #include const bool have_darwin_os = true; #else const bool have_darwin_os = false; #endif #if defined(HAVE_CRYPTO) const bool have_crypto = true; #else const bool have_crypto = false; #endif #if defined(HAVE_ACL) const bool have_acl = true; #else const bool have_acl = false; #endif #if defined(HAVE_SHA2) const bool have_sha2 = true; #else const bool have_sha2 = false; #endif #if defined(HAVE_XATTR) const bool have_xattr = true; #else const bool have_xattr = false; #endif /* * Data received from Storage Daemon */ static char rec_header[] = "rechdr %ld %ld %ld %ld %ld"; /* * Forward referenced functions */ #if defined(HAVE_LIBZ) const bool have_libz = true; #else const bool have_libz = false; #endif #if defined(HAVE_LZO) const bool have_lzo = true; #else const bool have_lzo = false; #endif #if defined(HAVE_FASTLZ) const bool have_fastlz = true; #else const bool have_fastlz = false; #endif static void free_signature(r_ctx &rctx); static bool close_previous_stream(JCR *jcr, r_ctx &rctx); int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, uint64_t *addr, char *flags, int32_t stream, RESTORE_CIPHER_CTX *cipher_ctx); /* * Close a bfd check that we are at the expected file offset. * Makes use of some code from set_attributes(). */ static int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize) { char ec1[50], ec2[50]; boffset_t fsize; fsize = blseek(bfd, 0, SEEK_CUR); bclose(bfd); if (fsize > 0 && fsize != osize) { Qmsg3(jcr, M_WARNING, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"), jcr->last_fname, edit_uint64(osize, ec1), edit_uint64(fsize, ec2)); return -1; } return 0; } static inline bool restore_finderinfo(JCR *jcr, POOLMEM *buf, int32_t buflen) { #ifdef HAVE_DARWIN_OS struct attrlist attrList; memset(&attrList, 0, sizeof(attrList)); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.commonattr = ATTR_CMN_FNDRINFO; Dmsg0(130, "Restoring Finder Info\n"); set_bit(FO_HFSPLUS, jcr->ff->flags); if (buflen != 32) { Jmsg(jcr, M_WARNING, 0, _("Invalid length of Finder Info (got %d, not 32)\n"), buflen); return false; } if (setattrlist(jcr->last_fname, &attrList, buf, buflen, 0) != 0) { Jmsg(jcr, M_WARNING, 0, _("Could not set Finder Info on %s\n"), jcr->last_fname); return false; } return true; #else return true; #endif } /* * Cleanup of delayed restore stack with streams for later processing. */ static inline void drop_delayed_data_streams(r_ctx &rctx, bool reuse) { DELAYED_DATA_STREAM *dds; if (!rctx.delayed_streams || rctx.delayed_streams->empty()) { return; } foreach_alist(dds, rctx.delayed_streams) { free(dds->content); } rctx.delayed_streams->destroy(); if (reuse) { rctx.delayed_streams->init(10, owned_by_alist); } } /* * Push a data stream onto the delayed restore stack for later processing. */ static inline void push_delayed_data_stream(r_ctx &rctx, BSOCK *sd) { DELAYED_DATA_STREAM *dds; if (!rctx.delayed_streams) { rctx.delayed_streams = New(alist(10, owned_by_alist)); } dds = (DELAYED_DATA_STREAM *)malloc(sizeof(DELAYED_DATA_STREAM)); dds->stream = rctx.stream; dds->content = (char *)malloc(sd->msglen); memcpy(dds->content, sd->msg, sd->msglen); dds->content_length = sd->msglen; rctx.delayed_streams->append(dds); } /* * Perform a restore of an ACL using the stream received. * This can either be a delayed restore or direct restore. */ static inline bool do_restore_acl(JCR *jcr, int stream, char *content, uint32_t content_length) { bacl_exit_code retval; jcr->acl_data->last_fname = jcr->last_fname; switch (stream) { case STREAM_ACL_PLUGIN: retval = plugin_parse_acl_streams(jcr, jcr->acl_data, stream, content, content_length); break; default: retval = parse_acl_streams(jcr, jcr->acl_data, stream, content, content_length); break; } switch (retval) { case bacl_exit_fatal: return false; case bacl_exit_error: /* * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB * print the error message set by the lower level routine in jcr->errmsg. */ if (jcr->acl_data->u.parse->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } jcr->acl_data->u.parse->nr_errors++; break; case bacl_exit_ok: break; } return true; } /* * Perform a restore of an XATTR using the stream received. * This can either be a delayed restore or direct restore. */ static inline bool do_restore_xattr(JCR *jcr, int stream, char *content, uint32_t content_length) { bxattr_exit_code retval; jcr->xattr_data->last_fname = jcr->last_fname; switch (stream) { case STREAM_XATTR_PLUGIN: retval = plugin_parse_xattr_streams(jcr, jcr->xattr_data, stream, content, content_length); break; default: retval = parse_xattr_streams(jcr, jcr->xattr_data, stream, content, content_length); break; } switch (retval) { case bxattr_exit_fatal: return false; case bxattr_exit_error: /* * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB * print the error message set by the lower level routine in jcr->errmsg. */ if (jcr->xattr_data->u.parse->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) { Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg); } jcr->xattr_data->u.parse->nr_errors++; break; case bxattr_exit_ok: break; } return true; } /* * Restore any data streams that are restored after the file * is fully restored and has its attributes restored. Things * like acls and xattr are restored after we set the file * attributes otherwise we might clear some security flags * by setting the attributes. */ static inline bool pop_delayed_data_streams(JCR *jcr, r_ctx &rctx) { DELAYED_DATA_STREAM *dds; /* * See if there is anything todo. */ if (!rctx.delayed_streams || rctx.delayed_streams->empty()) { return true; } /* * Only process known delayed data streams here. * If you start using more delayed data streams * be sure to add them in this loop and add the * proper calls here. * * Currently we support delayed data stream * processing for the following type of streams: * - *_ACL_* * - *_XATTR_* */ foreach_alist(dds, rctx.delayed_streams) { switch (dds->stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_AIX_TEXT: case STREAM_ACL_DARWIN_ACCESS_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_ACL_HPUX_ACL_ENTRY: case STREAM_ACL_IRIX_DEFAULT_ACL: case STREAM_ACL_IRIX_ACCESS_ACL: case STREAM_ACL_LINUX_DEFAULT_ACL: case STREAM_ACL_LINUX_ACCESS_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: case STREAM_ACL_AFS_TEXT: case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: case STREAM_ACL_HURD_DEFAULT_ACL: case STREAM_ACL_HURD_ACCESS_ACL: if (!do_restore_acl(jcr, dds->stream, dds->content, dds->content_length)) { goto bail_out; } free(dds->content); break; case STREAM_XATTR_PLUGIN: case STREAM_XATTR_HURD: case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: case STREAM_XATTR_SOLARIS_SYS: case STREAM_XATTR_DARWIN: case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: if (!do_restore_xattr(jcr, dds->stream, dds->content, dds->content_length)) { goto bail_out; } free(dds->content); break; default: Jmsg(jcr, M_WARNING, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), dds->stream); break; } } /* * We processed the stack so we can destroy it. */ rctx.delayed_streams->destroy(); /* * (Re)Initialize the stack for a new use. */ rctx.delayed_streams->init(10, owned_by_alist); return true; bail_out: /* * Destroy the content of the stack and (re)initialize it for a new use. */ drop_delayed_data_streams(rctx, true); return false; } /* * Restore the requested files. */ void do_restore(JCR *jcr) { BSOCK *sd; uint32_t VolSessionId, VolSessionTime; int32_t file_index; char ec1[50]; /* Buffer printing huge values */ uint32_t buf_size; /* client buffer size */ int status; int64_t rsrc_len = 0; /* Original length of resource fork */ r_ctx rctx; ATTR *attr; /* ***FIXME*** make configurable */ crypto_digest_t signing_algorithm = have_sha2 ? CRYPTO_DIGEST_SHA256 : CRYPTO_DIGEST_SHA1; /* * The following variables keep track of "known unknowns" */ int non_support_data = 0; int non_support_attr = 0; int non_support_rsrc = 0; int non_support_finfo = 0; int non_support_acl = 0; int non_support_progname = 0; int non_support_crypto = 0; int non_support_xattr = 0; memset(&rctx, 0, sizeof(rctx)); rctx.jcr = jcr; sd = jcr->store_bsock; jcr->setJobStatus(JS_Running); LockRes(); CLIENTRES *client = (CLIENTRES *)GetNextRes(R_CLIENT, NULL); UnlockRes(); if (client) { buf_size = client->max_network_buffer_size; } else { buf_size = 0; /* use default */ } if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) { jcr->setJobStatus(JS_ErrorTerminated); return; } jcr->buf_size = sd->msglen; if (have_libz || have_lzo || have_fastlz) { if (!adjust_decompression_buffers(jcr)) { goto bail_out; } } if (have_crypto) { rctx.cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE); if (have_darwin_os) { rctx.fork_cipher_ctx.buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE); } } /* * Get a record from the Storage daemon. We are guaranteed to * receive records in the following order: * 1. Stream record header * 2. Stream data (one or more of the following in the order given) * a. Attributes (Unix or Win32) * b. Possibly stream encryption session data (e.g., symmetric session key) * c. File data for the file * d. Alternate data stream (e.g. Resource Fork) * e. Finder info * f. ACLs * g. XATTRs * h. Possibly a cryptographic signature * i. Possibly MD5 or SHA1 record * 3. Repeat step 1 * * NOTE: We keep track of two bareos file descriptors: * 1. bfd for file data. * This fd is opened for non empty files when an attribute stream is * encountered and closed when we find the next attribute stream. * 2. fork_bfd for alternate data streams * This fd is opened every time we encounter a new alternate data * stream for the current file. When we find any other stream, we * close it again. * The expected size of the stream, fork_len, should be set when * opening the fd. * 3. Not all the stream data records are required -- e.g. if there * is no fork, there is no alternate data stream, no ACL, ... */ binit(&rctx.bfd); binit(&rctx.forkbfd); attr = rctx.attr = new_attr(jcr); if (have_acl) { jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t)); memset(jcr->acl_data, 0, sizeof(acl_data_t)); jcr->acl_data->u.parse = (acl_parse_data_t *)malloc(sizeof(acl_parse_data_t)); memset(jcr->acl_data->u.parse, 0, sizeof(acl_parse_data_t)); } if (have_xattr) { jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t)); memset(jcr->xattr_data, 0, sizeof(xattr_data_t)); jcr->xattr_data->u.parse = (xattr_parse_data_t *)malloc(sizeof(xattr_parse_data_t)); memset(jcr->xattr_data->u.parse, 0, sizeof(xattr_parse_data_t)); } while (bget_msg(sd) >= 0 && !job_canceled(jcr)) { /* * Remember previous stream type */ rctx.prev_stream = rctx.stream; /* * First we expect a Stream Record Header */ if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index, &rctx.full_stream, &rctx.size) != 5) { Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg); goto bail_out; } /* Strip off new stream high bits */ rctx.stream = rctx.full_stream & STREAMMASK_TYPE; Dmsg5(150, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n", jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream)); /* * Now we expect the Stream Data */ if (bget_msg(sd) < 0) { Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror()); goto bail_out; } if (rctx.size != (uint32_t)sd->msglen) { Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, rctx.size); Dmsg2(50, "Actual data size %d not same as header %d\n", sd->msglen, rctx.size); goto bail_out; } Dmsg3(130, "Got stream: %s len=%d extract=%d\n", stream_to_ascii(rctx.stream), sd->msglen, rctx.extract); /* * If we change streams, close and reset alternate data streams */ if (rctx.prev_stream != rctx.stream) { if (is_bopen(&rctx.forkbfd)) { deallocate_fork_cipher(rctx); bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size); } /* * Use an impossible value and set a proper one below */ rctx.fork_size = -1; rctx.fork_addr = 0; } /* * File Attributes stream */ switch (rctx.stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: /* * if any previous stream open, close it */ if (!close_previous_stream(jcr, rctx)) { goto bail_out; } /* * TODO: manage deleted files */ if (rctx.type == FT_DELETED) { /* deleted file */ continue; } /* * Restore objects should be ignored here -- they are * returned at the beginning of the restore. */ if (IS_FT_OBJECT(rctx.type)) { continue; } /* * Unpack attributes and do sanity check them */ if (!unpack_attributes_record(jcr, rctx.stream, sd->msg, sd->msglen, attr)) { goto bail_out; } Dmsg3(100, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname, attr->attr, attr->attrEx); Dmsg3(100, "=== msglen=%d attrExlen=%d msg=%s\n", sd->msglen, strlen(attr->attrEx), sd->msg); attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI); if (!is_restore_stream_supported(attr->data_stream)) { if (!non_support_data++) { Jmsg(jcr, M_WARNING, 0, _("%s stream not supported on this Client.\n"), stream_to_ascii(attr->data_stream)); } continue; } build_attr_output_fnames(jcr, attr); /* * Try to actually create the file, which returns a status telling * us if we need to extract or not. */ jcr->num_files_examined++; rctx.extract = false; status = CF_CORE; /* By default, let Bareos's core handle it */ if (jcr->is_plugin()) { status = plugin_create_file(jcr, attr, &rctx.bfd, jcr->replace); } if (status == CF_CORE) { status = create_file(jcr, attr, &rctx.bfd, jcr->replace); } jcr->lock(); pm_strcpy(jcr->last_fname, attr->ofname); jcr->last_type = attr->type; jcr->unlock(); Dmsg2(130, "Outfile=%s create_file status=%d\n", attr->ofname, status); switch (status) { case CF_ERROR: break; case CF_SKIP: jcr->JobFiles++; break; case CF_EXTRACT: /* * File created and we expect file data */ rctx.extract = true; /* * FALLTHROUGH */ case CF_CREATED: /* * File created, but there is no content */ rctx.fileAddr = 0; print_ls_output(jcr, attr); if (have_darwin_os) { /* * Only restore the resource fork for regular files */ from_base64(&rsrc_len, attr->attrEx); if (attr->type == FT_REG && rsrc_len > 0) { rctx.extract = true; } /* * Do not count the resource forks as regular files being restored. */ if (rsrc_len == 0) { jcr->JobFiles++; } } else { jcr->JobFiles++; } if (!rctx.extract) { /* * Set attributes now because file will not be extracted */ if (jcr->is_plugin()) { plugin_set_attributes(jcr, attr, &rctx.bfd); } else { set_attributes(jcr, attr, &rctx.bfd); } } break; } break; /* * Data stream */ case STREAM_ENCRYPTED_SESSION_DATA: if (rctx.extract) { crypto_error_t cryptoerr; /* * Is this an unexpected session data entry? */ if (rctx.cs) { Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic session data stream.\n")); rctx.extract = false; bclose(&rctx.bfd); continue; } /* * Do we have any keys at all? */ if (!jcr->crypto.pki_recipients) { Jmsg(jcr, M_ERROR, 0, _("No private decryption keys have been defined to decrypt encrypted backup data.\n")); rctx.extract = false; bclose(&rctx.bfd); break; } if (jcr->crypto.digest) { crypto_digest_free(jcr->crypto.digest); } jcr->crypto.digest = crypto_digest_new(jcr, signing_algorithm); if (!jcr->crypto.digest) { Jmsg0(jcr, M_FATAL, 0, _("Could not create digest.\n")); rctx.extract = false; bclose(&rctx.bfd); break; } /* * Decode and save session keys. */ cryptoerr = crypto_session_decode((uint8_t *)sd->msg, (uint32_t)sd->msglen, jcr->crypto.pki_recipients, &rctx.cs); switch(cryptoerr) { case CRYPTO_ERROR_NONE: /* * Success */ break; case CRYPTO_ERROR_NORECIPIENT: Jmsg(jcr, M_ERROR, 0, _("Missing private key required to decrypt encrypted backup data.\n")); break; case CRYPTO_ERROR_DECRYPTION: Jmsg(jcr, M_ERROR, 0, _("Decrypt of the session key failed.\n")); break; default: /* * Shouldn't happen */ Jmsg1(jcr, M_ERROR, 0, _("An error occurred while decoding encrypted session data stream: %s\n"), crypto_strerror(cryptoerr)); break; } if (cryptoerr != CRYPTO_ERROR_NONE) { rctx.extract = false; bclose(&rctx.bfd); continue; } } break; case STREAM_FILE_DATA: case STREAM_SPARSE_DATA: case STREAM_WIN32_DATA: case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: case STREAM_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: case STREAM_ENCRYPTED_FILE_DATA: case STREAM_ENCRYPTED_WIN32_DATA: case STREAM_ENCRYPTED_FILE_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: if (rctx.extract) { bool process_data = false; /* * Force an expected, consistent stream type here * First see if we need to process the data and * set the flags. */ if (rctx.prev_stream == rctx.stream) { process_data = true; } else { switch (rctx.prev_stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: case STREAM_ENCRYPTED_SESSION_DATA: process_data = true; break; default: break; } } /* * If process_data is set in the test above continue here with the * processing of the data based on the stream type available. */ if (process_data) { clear_all_bits(FO_MAX, rctx.flags); switch (rctx.stream) { case STREAM_SPARSE_DATA: set_bit(FO_SPARSE, rctx.flags); break; case STREAM_SPARSE_GZIP_DATA: case STREAM_SPARSE_COMPRESSED_DATA: set_bit(FO_SPARSE, rctx.flags); set_bit(FO_COMPRESS, rctx.flags); rctx.comp_stream = rctx.stream; break; case STREAM_GZIP_DATA: case STREAM_COMPRESSED_DATA: case STREAM_WIN32_GZIP_DATA: case STREAM_WIN32_COMPRESSED_DATA: set_bit(FO_COMPRESS, rctx.flags); rctx.comp_stream = rctx.stream; break; case STREAM_ENCRYPTED_FILE_GZIP_DATA: case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: if (!rctx.cipher_ctx.cipher) { if (!setup_decryption_context(rctx, rctx.cipher_ctx)) { rctx.extract = false; bclose(&rctx.bfd); continue; } } set_bit(FO_COMPRESS, rctx.flags); set_bit(FO_ENCRYPT, rctx.flags); rctx.comp_stream = rctx.stream; break; case STREAM_ENCRYPTED_FILE_DATA: case STREAM_ENCRYPTED_WIN32_DATA: if (!rctx.cipher_ctx.cipher) { if (!setup_decryption_context(rctx, rctx.cipher_ctx)) { rctx.extract = false; bclose(&rctx.bfd); continue; } } set_bit(FO_ENCRYPT, rctx.flags); break; default: break; } /* * Check for a win32 stream type on a system without the win32 API. * On those we decompose the BackupWrite data. */ if (is_win32_stream(rctx.stream) && !have_win32_api()) { set_portable_backup(&rctx.bfd); /* * "decompose" BackupWrite data */ set_bit(FO_WIN32DECOMP, rctx.flags); } if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr, rctx.flags, rctx.stream, &rctx.cipher_ctx) < 0) { rctx.extract = false; bclose(&rctx.bfd); continue; } } } break; /* * Resource fork stream - only recorded after a file to be restored * Silently ignore if we cannot write - we already reported that */ case STREAM_ENCRYPTED_MACOS_FORK_DATA: case STREAM_MACOS_FORK_DATA: if (have_darwin_os) { clear_all_bits(FO_MAX, rctx.fork_flags); set_bit(FO_HFSPLUS, jcr->ff->flags); if (rctx.stream == STREAM_ENCRYPTED_MACOS_FORK_DATA) { set_bit(FO_ENCRYPT, rctx.fork_flags); if (rctx.extract && !rctx.fork_cipher_ctx.cipher) { if (!setup_decryption_context(rctx, rctx.fork_cipher_ctx)) { rctx.extract = false; bclose(&rctx.bfd); continue; } } } if (rctx.extract) { if (rctx.prev_stream != rctx.stream) { if (bopen_rsrc(&rctx.forkbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) { Jmsg(jcr, M_WARNING, 0, _("Cannot open resource fork for %s.\n"), jcr->last_fname); rctx.extract = false; continue; } rctx.fork_size = rsrc_len; Dmsg0(130, "Restoring resource fork\n"); } if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags, rctx.stream, &rctx.fork_cipher_ctx) < 0) { rctx.extract = false; bclose(&rctx.forkbfd); continue; } } } else { non_support_rsrc++; } break; case STREAM_HFSPLUS_ATTRIBUTES: if (have_darwin_os) { if (!restore_finderinfo(jcr, sd->msg, sd->msglen)) { continue; } } else { non_support_finfo++; } break; case STREAM_UNIX_ACCESS_ACL: case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_AIX_TEXT: case STREAM_ACL_DARWIN_ACCESS_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_ACL_HPUX_ACL_ENTRY: case STREAM_ACL_IRIX_DEFAULT_ACL: case STREAM_ACL_IRIX_ACCESS_ACL: case STREAM_ACL_LINUX_DEFAULT_ACL: case STREAM_ACL_LINUX_ACCESS_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: case STREAM_ACL_AFS_TEXT: case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: case STREAM_ACL_HURD_DEFAULT_ACL: case STREAM_ACL_HURD_ACCESS_ACL: /* * Do not restore ACLs when * a) The current file is not extracted * b) and it is not a directory (they are never "extracted") * c) or the file name is empty */ if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) { break; } if (have_acl) { /* * For anything that is not a directory we delay * the restore of acls till a later stage. */ if (jcr->last_type != FT_DIREND) { push_delayed_data_stream(rctx, sd); } else { if (!do_restore_acl(jcr, rctx.stream, sd->msg, sd->msglen)) { goto bail_out; } } } else { non_support_acl++; } break; case STREAM_XATTR_PLUGIN: case STREAM_XATTR_HURD: case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: case STREAM_XATTR_SOLARIS_SYS: case STREAM_XATTR_DARWIN: case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: /* * Do not restore Extended Attributes when * a) The current file is not extracted * b) and it is not a directory (they are never "extracted") * c) or the file name is empty */ if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) { break; } if (have_xattr) { /* * For anything that is not a directory we delay * the restore of xattr till a later stage. */ if (jcr->last_type != FT_DIREND) { push_delayed_data_stream(rctx, sd); } else { if (!do_restore_xattr(jcr, rctx.stream, sd->msg, sd->msglen)) { goto bail_out; } } } else { non_support_xattr++; } break; case STREAM_XATTR_SOLARIS: /* * Do not restore Extended Attributes when * a) The current file is not extracted * b) and it is not a directory (they are never "extracted") * c) or the file name is empty */ if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) { break; } if (have_xattr) { if (!do_restore_xattr(jcr, rctx.stream, sd->msg, sd->msglen)) { goto bail_out; } } else { non_support_xattr++; } break; case STREAM_SIGNED_DIGEST: /* * Is this an unexpected signature? */ if (rctx.sig) { Jmsg0(jcr, M_ERROR, 0, _("Unexpected cryptographic signature data stream.\n")); free_signature(rctx); continue; } /* * Save signature. */ if (rctx.extract && (rctx.sig = crypto_sign_decode(jcr, (uint8_t *)sd->msg, (uint32_t)sd->msglen)) == NULL) { Jmsg1(jcr, M_ERROR, 0, _("Failed to decode message signature for %s\n"), jcr->last_fname); } break; case STREAM_MD5_DIGEST: case STREAM_SHA1_DIGEST: case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: break; case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: if (!non_support_progname) { Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n"); non_support_progname++; } break; case STREAM_PLUGIN_NAME: if (!close_previous_stream(jcr, rctx)) { goto bail_out; } Dmsg1(50, "restore stream_plugin_name=%s\n", sd->msg); plugin_name_stream(jcr, sd->msg); break; case STREAM_RESTORE_OBJECT: break; /* these are sent by Director */ default: if (!close_previous_stream(jcr, rctx)) { goto bail_out; } Jmsg(jcr, M_WARNING, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), rctx.stream); Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg); break; } /* end switch(stream) */ } /* end while get_msg() */ /* * If output file is still open, it was the last one in the * archive since we just hit an end of file, so close the file. */ if (is_bopen(&rctx.forkbfd)) { bclose_chksize(jcr, &rctx.forkbfd, rctx.fork_size); } if (!close_previous_stream(jcr, rctx)) { goto bail_out; } jcr->setJobStatus(JS_Terminated); goto ok_out; bail_out: jcr->setJobStatus(JS_ErrorTerminated); ok_out: #ifdef HAVE_WIN32 /* * Cleanup the copy thread if we restored any EFS data. */ if (jcr->cp_thread) { win32_cleanup_copy_thread(jcr); } #endif /* * First output the statistics. */ Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); if (have_acl && jcr->acl_data->u.parse->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing restore\n"), jcr->acl_data->u.parse->nr_errors); } if (have_xattr && jcr->xattr_data->u.parse->nr_errors > 0) { Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing restore\n"), jcr->xattr_data->u.parse->nr_errors); } if (non_support_data > 1 || non_support_attr > 1) { Jmsg(jcr, M_WARNING, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"), non_support_data, non_support_attr); } if (non_support_rsrc) { Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc); } if (non_support_finfo) { Jmsg(jcr, M_INFO, 0, _("%d non-supported Finder Info streams ignored.\n"), non_support_finfo); } if (non_support_acl) { Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl); } if (non_support_crypto) { Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_crypto); } if (non_support_xattr) { Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr); } /* * Free Signature & Crypto Data */ free_signature(rctx); free_session(rctx); if (jcr->crypto.digest) { crypto_digest_free(jcr->crypto.digest); jcr->crypto.digest = NULL; } /* * Free file cipher restore context */ if (rctx.cipher_ctx.cipher) { crypto_cipher_free(rctx.cipher_ctx.cipher); rctx.cipher_ctx.cipher = NULL; } if (rctx.cipher_ctx.buf) { free_pool_memory(rctx.cipher_ctx.buf); rctx.cipher_ctx.buf = NULL; } /* * Free alternate stream cipher restore context */ if (rctx.fork_cipher_ctx.cipher) { crypto_cipher_free(rctx.fork_cipher_ctx.cipher); rctx.fork_cipher_ctx.cipher = NULL; } if (rctx.fork_cipher_ctx.buf) { free_pool_memory(rctx.fork_cipher_ctx.buf); rctx.fork_cipher_ctx.buf = NULL; } if (have_acl && jcr->acl_data) { free(jcr->acl_data->u.parse); free(jcr->acl_data); jcr->acl_data = NULL; } if (have_xattr && jcr->xattr_data) { free(jcr->xattr_data->u.parse); free(jcr->xattr_data); jcr->xattr_data = NULL; } /* * Free the delayed stream stack list. */ if (rctx.delayed_streams) { drop_delayed_data_streams(rctx, false); delete rctx.delayed_streams; } cleanup_compression(jcr); bclose(&rctx.forkbfd); bclose(&rctx.bfd); free_attr(rctx.attr); } int do_file_digest(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { Dmsg1(50, "do_file_digest jcr=%p\n", jcr); return (digest_file(jcr, ff_pkt, jcr->crypto.digest)); } bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length) { unser_declare; uint64_t faddr; char ec1[50]; unser_begin(*data, OFFSET_FADDR_SIZE); unser_uint64(faddr); if (*addr != faddr) { *addr = faddr; if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) { berrno be; Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), edit_uint64(*addr, ec1), jcr->last_fname, be.bstrerror(bfd->berrno)); return false; } } *data += OFFSET_FADDR_SIZE; *length -= OFFSET_FADDR_SIZE; return true; } bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp) { if (jcr->crypto.digest) { crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length); } if (win32_decomp) { if (!processWin32BackupAPIBlock(bfd, data, length)) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), jcr->last_fname, be.bstrerror(bfd->berrno)); return false; } #ifdef HAVE_WIN32 } else { if (bfd->encrypted) { if (win32_send_to_copy_thread(jcr, bfd, data, length) != (ssize_t)length) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), jcr->last_fname, be.bstrerror(bfd->berrno)); return false; } } else { if (bwrite(bfd, data, length) != (ssize_t)length) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), jcr->last_fname, be.bstrerror(bfd->berrno)); } } } #else } else if (bwrite(bfd, data, length) != (ssize_t)length) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), jcr->last_fname, be.bstrerror(bfd->berrno)); return false; } #endif return true; } /* * In the context of jcr, write data to bfd. * We write buflen bytes in buf at addr. addr is updated in place. * The flags specify whether to use sparse files or compression. * Return value is the number of bytes written, or -1 on errors. */ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, uint64_t *addr, char *flags, int32_t stream, RESTORE_CIPHER_CTX *cipher_ctx) { char *wbuf; /* write buffer */ uint32_t wsize; /* write size */ uint32_t rsize; /* read size */ char ec1[50]; /* Buffer printing huge values */ rsize = buflen; jcr->ReadBytes += rsize; wsize = rsize; wbuf = buf; if (bit_is_set(FO_ENCRYPT, flags)) { if (!decrypt_data(jcr, &wbuf, &wsize, cipher_ctx)) { goto bail_out; } if (wsize == 0) { return 0; } } if (bit_is_set(FO_SPARSE, flags) || bit_is_set(FO_OFFSETS, flags)) { if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) { goto bail_out; } } if (bit_is_set(FO_COMPRESS, flags)) { if (!decompress_data(jcr, jcr->last_fname, stream, &wbuf, &wsize, false)) { goto bail_out; } } if (!store_data(jcr, bfd, wbuf, wsize, bit_is_set(FO_WIN32DECOMP, flags))) { goto bail_out; } jcr->JobBytes += wsize; *addr += wsize; Dmsg2(130, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); /* * Clean up crypto buffers */ if (bit_is_set(FO_ENCRYPT, flags)) { /* * Move any remaining data to start of buffer */ if (cipher_ctx->buf_len > 0) { Dmsg1(130, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len); memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len], cipher_ctx->buf_len); } /* * The packet was successfully written, reset the length so that the next * packet length may be re-read by unser_crypto_packet_len() */ cipher_ctx->packet_len = 0; } return wsize; bail_out: return -1; } /* * If extracting, close any previous stream */ static bool close_previous_stream(JCR *jcr, r_ctx &rctx) { /* * If extracting, it was from previous stream, so * close the output file and validate the signature. */ if (rctx.extract) { if (rctx.size > 0 && !is_bopen(&rctx.bfd)) { Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should be open\n")); Dmsg2(000, "=== logic error size=%d bopen=%d\n", rctx.size, is_bopen(&rctx.bfd)); } if (rctx.prev_stream != STREAM_ENCRYPTED_SESSION_DATA) { deallocate_cipher(rctx); deallocate_fork_cipher(rctx); } #ifdef HAVE_WIN32 if (jcr->cp_thread) { win32_flush_copy_thread(jcr); } #endif if (jcr->is_plugin()) { plugin_set_attributes(rctx.jcr, rctx.attr, &rctx.bfd); } else { set_attributes(rctx.jcr, rctx.attr, &rctx.bfd); } rctx.extract = false; /* * Now perform the delayed restore of some specific data streams. */ if (!pop_delayed_data_streams(jcr, rctx)) { return false; } /* * Verify the cryptographic signature, if any */ rctx.type = rctx.attr->type; verify_signature(rctx.jcr, rctx); /* * Free Signature */ free_signature(rctx); free_session(rctx); clear_all_bits(FO_MAX, rctx.jcr->ff->flags); Dmsg0(130, "Stop extracting.\n"); } else if (is_bopen(&rctx.bfd)) { Jmsg0(rctx.jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); Dmsg0(000, "=== logic error !open\n"); bclose(&rctx.bfd); } return true; } static void free_signature(r_ctx &rctx) { if (rctx.sig) { crypto_sign_free(rctx.sig); rctx.sig = NULL; } } void free_session(r_ctx &rctx) { if (rctx.cs) { crypto_session_free(rctx.cs); rctx.cs = NULL; } } bareos-Release-14.2.6/src/filed/restore.h000066400000000000000000000056221263011562700201530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __RESTORE_H #define __RESTORE_H struct DELAYED_DATA_STREAM { int32_t stream; /* stream less new bits */ char *content; /* stream data */ uint32_t content_length; /* stream length */ }; struct RESTORE_CIPHER_CTX { CIPHER_CONTEXT *cipher; uint32_t block_size; POOLMEM *buf; /* Pointer to descryption buffer */ int32_t buf_len; /* Count of bytes currently in buf */ int32_t packet_len; /* Total bytes in packet */ }; struct r_ctx { JCR *jcr; int32_t stream; /* stream less new bits */ int32_t prev_stream; /* previous stream */ int32_t full_stream; /* full stream including new bits */ int32_t comp_stream; /* last compressed stream found. needed only to restore encrypted compressed backup */ BFILE bfd; /* File content */ uint64_t fileAddr; /* file write address */ uint32_t size; /* Size of file */ char flags[FOPTS_BYTES]; /* Options for extract_data() */ BFILE forkbfd; /* Alternative data stream */ uint64_t fork_addr; /* Write address for alternative stream */ int64_t fork_size; /* Size of alternate stream */ char fork_flags[FOPTS_BYTES]; /* Options for extract_data() */ int32_t type; /* file type FT_ */ ATTR *attr; /* Pointer to attributes */ bool extract; /* set when extracting */ alist *delayed_streams; /* streams that should be restored as last */ SIGNATURE *sig; /* Cryptographic signature (if any) for file */ CRYPTO_SESSION *cs; /* Cryptographic session data (if any) for file */ RESTORE_CIPHER_CTX cipher_ctx; /* Cryptographic restore context (if any) for file */ RESTORE_CIPHER_CTX fork_cipher_ctx; /* Cryptographic restore context (if any) for alternative stream */ }; #endif bareos-Release-14.2.6/src/filed/sd_cmds.c000066400000000000000000000057471263011562700201070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * This file handles accepting Storage Daemon Commands * * Marco van Wieringen, March 2013 */ #include "bareos.h" #include "filed.h" static int dbglvl = 100; void *handle_stored_connection(BSOCK *sd) { JCR *jcr; char job_name[MAX_NAME_LENGTH]; /* * Do a sanity check on the message received */ if (sd->msglen < 25 || sd->msglen > 256) { Dmsg1(000, "msg); Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), sd->who(), sd->msglen); bmicrosleep(5, 0); /* make user wait 5 seconds */ sd->close(); delete sd; return NULL; } if (sscanf(sd->msg, "Hello Storage calling Start Job %127s", job_name) != 1) { char addr[64]; char *who = bnet_get_peer(sd, addr, sizeof(addr)) ? sd->who() : addr; sd->msg[100] = 0; Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n", sd->who(), sd->msg); Jmsg2(NULL, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"), who, sd->msg); sd->close(); delete sd; return NULL; } if (!(jcr = get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("SD connect failed: Job name not found: %s\n"), job_name); Dmsg1(3, "**** Job \"%s\" not found.\n", job_name); sd->close(); delete sd; return NULL; } Dmsg1(50, "Found Job %s\n", job_name); jcr->store_bsock = sd; jcr->store_bsock->set_jcr(jcr); /* * Authenticate the Storage Daemon. */ if (!authenticate_storagedaemon(jcr)) { Dmsg1(50, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n")); jcr->setJobStatus(JS_ErrorTerminated); } else { Dmsg2(50, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job); } if (!jcr->max_bandwidth) { if (jcr->director->max_bandwidth_per_job) { jcr->max_bandwidth = jcr->director->max_bandwidth_per_job; } else if (me->max_bandwidth_per_job) { jcr->max_bandwidth = me->max_bandwidth_per_job; } } sd->set_bwlimit(jcr->max_bandwidth); if (me->allow_bw_bursting) { sd->set_bwlimit_bursting(); } free_jcr(jcr); return NULL; } bareos-Release-14.2.6/src/filed/status.c000066400000000000000000000422331263011562700200050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon Status routines * * Kern Sibbald, August MMI */ #include "bareos.h" #include "filed.h" #include "lib/status.h" extern void *start_heap; extern bool GetWindowsVersionString(char *buf, int maxsiz); /* Forward referenced functions */ static void list_terminated_jobs(STATUS_PKT *sp); static void list_running_jobs(STATUS_PKT *sp); static void list_status_header(STATUS_PKT *sp); static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp); static const char *level_to_str(int level); /* Static variables */ static char qstatus[] = ".status %s\n"; static char OKqstatus[] = "2000 OK .status\n"; static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n"; #if defined(HAVE_WIN32) static int privs = 0; #endif #ifdef WIN32_VSS #include "vss.h" #define VSS " VSS" extern VSSClient *g_pVSSClient; #else #define VSS "" #endif /* * General status generator */ static void output_status(STATUS_PKT *sp) { list_status_header(sp); list_running_jobs(sp); list_terminated_jobs(sp); } static void list_status_header(STATUS_PKT *sp) { int len; char dt[MAX_TIME_LENGTH]; POOL_MEM msg(PM_MESSAGE); char b1[32], b2[32], b3[32], b4[32], b5[35]; #if defined(HAVE_WIN32) char buf[300]; #endif len = Mmsg(msg, _("%s Version: %s (%s) %s %s %s %s\n"), my_name, VERSION, BDATE, VSS, HOST_OS, DISTNAME, DISTVER); sendit(msg, len, sp); bstrftime_nc(dt, sizeof(dt), daemon_start_time); len = Mmsg(msg, _("Daemon started %s. Jobs: run=%d running=%d.\n"), dt, num_jobs_run, job_count()); sendit(msg, len, sp); #if defined(HAVE_WIN32) if (GetWindowsVersionString(buf, sizeof(buf))) { len = Mmsg(msg, "%s\n", buf); sendit(msg, len, sp); } if (debug_level > 0) { if (!privs) { privs = enable_backup_privileges(NULL, 1); } len = Mmsg(msg, "VSS %s, Priv 0x%x\n", g_pVSSClient ? "enabled" : "disabled", privs); sendit(msg, len, sp); len = Mmsg(msg, "APIs=%sOPT,%sATP,%sLPV,%sCFA,%sCFW,\n", p_OpenProcessToken ? "" : "!", p_AdjustTokenPrivileges ? "" : "!", p_LookupPrivilegeValue ? "" : "!", p_CreateFileA ? "" : "!", p_CreateFileW ? "" : "!"); sendit(msg, len, sp); len = Mmsg(msg, " %sWUL,%sWMKD,%sGFAA,%sGFAW,%sGFAEA,%sGFAEW,%sSFAA,%sSFAW,%sBR,%sBW,%sSPSP,\n", p_wunlink ? "" : "!", p_wmkdir ? "" : "!", p_GetFileAttributesA ? "" : "!", p_GetFileAttributesW ? "" : "!", p_GetFileAttributesExA ? "" : "!", p_GetFileAttributesExW ? "" : "!", p_SetFileAttributesA ? "" : "!", p_SetFileAttributesW ? "" : "!", p_BackupRead ? "" : "!", p_BackupWrite ? "" : "!", p_SetProcessShutdownParameters ? "" : "!"); sendit(msg, len, sp); len = Mmsg(msg, " %sWC2MB,%sMB2WC,%sFFFA,%sFFFW,%sFNFA,%sFNFW,%sSCDA,%sSCDW,\n", p_WideCharToMultiByte ? "" : "!", p_MultiByteToWideChar ? "" : "!", p_FindFirstFileA ? "" : "!", p_FindFirstFileW ? "" : "!", p_FindNextFileA ? "" : "!", p_FindNextFileW ? "" : "!", p_SetCurrentDirectoryA ? "" : "!", p_SetCurrentDirectoryW ? "" : "!"); sendit(msg, len, sp); len = Mmsg(msg, " %sGCDA,%sGCDW,%sGVPNW,%sGVNFVMPW\n", p_GetCurrentDirectoryA ? "" : "!", p_GetCurrentDirectoryW ? "" : "!", p_GetVolumePathNameW ? "" : "!", p_GetVolumeNameForVolumeMountPointW ? "" : "!"); sendit(msg, len, sp); } #endif len = Mmsg(msg, _(" Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"), edit_uint64_with_commas((char *)sbrk(0)-(char *)start_heap, b1), edit_uint64_with_commas(sm_bytes, b2), edit_uint64_with_commas(sm_max_bytes, b3), edit_uint64_with_commas(sm_buffers, b4), edit_uint64_with_commas(sm_max_buffers, b5)); sendit(msg, len, sp); len = Mmsg(msg, _(" Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d " "bwlimit=%skB/s\n"), sizeof(boffset_t), sizeof(size_t), debug_level, get_trace(), edit_uint64_with_commas(me->max_bandwidth_per_job / 1024, b1)); sendit(msg, len, sp); len = list_fd_plugins(msg); if (len > 0) { sendit(msg, len, sp); } } static void list_running_jobs_plain(STATUS_PKT *sp) { JCR *njcr; int len, sec, bps; bool found = false; POOL_MEM msg(PM_MESSAGE); char dt[MAX_TIME_LENGTH], b1[32], b2[32], b3[32], b4[32]; /* * List running jobs */ Dmsg0(1000, "Begin status jcr loop.\n"); len = Mmsg(msg, _("\nRunning Jobs:\n")); sendit(msg, len, sp); const char *vss = ""; #ifdef WIN32_VSS if (g_pVSSClient && g_pVSSClient->IsInitialized()) { vss = "VSS "; } #endif foreach_jcr(njcr) { bstrftime_nc(dt, sizeof(dt), njcr->start_time); if (njcr->JobId == 0) { len = Mmsg(msg, _("Director connected at: %s\n"), dt); } else { len = Mmsg(msg, _("JobId %d Job %s is running.\n"), njcr->JobId, njcr->Job); sendit(msg, len, sp); len = Mmsg(msg, _(" %s%s %s Job started: %s\n"), vss, level_to_str(njcr->getJobLevel()), job_type_to_str(njcr->getJobType()), dt); } sendit(msg, len, sp); if (njcr->JobId == 0) { continue; } sec = time(NULL) - njcr->start_time; if (sec <= 0) { sec = 1; } bps = (int)(njcr->JobBytes / sec); len = Mmsg(msg, _(" Files=%s Bytes=%s Bytes/sec=%s Errors=%d\n" " Bwlimit=%s\n"), edit_uint64_with_commas(njcr->JobFiles, b1), edit_uint64_with_commas(njcr->JobBytes, b2), edit_uint64_with_commas(bps, b3), njcr->JobErrors, edit_uint64_with_commas(njcr->max_bandwidth, b4)); sendit(msg, len, sp); len = Mmsg(msg, _(" Files Examined=%s\n"), edit_uint64_with_commas(njcr->num_files_examined, b1)); sendit(msg, len, sp); if (njcr->JobFiles > 0) { njcr->lock(); len = Mmsg(msg, _(" Processing file: %s\n"), njcr->last_fname); njcr->unlock(); sendit(msg, len, sp); } found = true; if (njcr->store_bsock) { len = Mmsg(msg, " SDReadSeqNo=%" lld " fd=%d\n", njcr->store_bsock->read_seqno, njcr->store_bsock->m_fd); sendit(msg, len, sp); } else { len = Mmsg(msg, _(" SDSocket closed.\n")); sendit(msg, len, sp); } } endeach_jcr(njcr); if (!found) { len = Mmsg(msg, _("No Jobs running.\n")); sendit(msg, len, sp); } len = pm_strcpy(msg, _("====\n")); sendit(msg, len, sp); } static void list_running_jobs_api(STATUS_PKT *sp) { JCR *njcr; int len, sec, bps; POOL_MEM msg(PM_MESSAGE); char dt[MAX_TIME_LENGTH], b1[32], b2[32], b3[32], b4[32]; /* * List running jobs for Bat/Bweb (simple to parse) */ int vss = 0; #ifdef WIN32_VSS if (g_pVSSClient && g_pVSSClient->IsInitialized()) { vss = 1; } #endif foreach_jcr(njcr) { bstrutime(dt, sizeof(dt), njcr->start_time); if (njcr->JobId == 0) { len = Mmsg(msg, "DirectorConnected=%s\n", dt); } else { len = Mmsg(msg, "JobId=%d\n Job=%s\n", njcr->JobId, njcr->Job); sendit(msg, len, sp); len = Mmsg(msg," VSS=%d\n Level=%c\n JobType=%c\n JobStarted=%s\n", vss, njcr->getJobLevel(), njcr->getJobType(), dt); } sendit(msg, len, sp); if (njcr->JobId == 0) { continue; } sec = time(NULL) - njcr->start_time; if (sec <= 0) { sec = 1; } bps = (int)(njcr->JobBytes / sec); len = Mmsg(msg, " Files=%s\n Bytes=%s\n Bytes/sec=%s\n Errors=%d\n" " Bwlimit=%s\n", edit_uint64(njcr->JobFiles, b1), edit_uint64(njcr->JobBytes, b2), edit_uint64(bps, b3), njcr->JobErrors, edit_int64(njcr->max_bandwidth, b4)); sendit(msg, len, sp); len = Mmsg(msg, " Files Examined=%s\n", edit_uint64(njcr->num_files_examined, b1)); sendit(msg, len, sp); if (njcr->JobFiles > 0) { njcr->lock(); len = Mmsg(msg, " Processing file=%s\n", njcr->last_fname); njcr->unlock(); sendit(msg, len, sp); } if (njcr->store_bsock) { len = Mmsg(msg, " SDReadSeqNo=%" lld "\n fd=%d\n", njcr->store_bsock->read_seqno, njcr->store_bsock->m_fd); sendit(msg, len, sp); } else { len = Mmsg(msg, _(" SDSocket=closed\n")); sendit(msg, len, sp); } } endeach_jcr(njcr); } static void list_running_jobs(STATUS_PKT *sp) { if (sp->api) { list_running_jobs_api(sp); } else { list_running_jobs_plain(sp); } } static void list_terminated_jobs(STATUS_PKT *sp) { int len; struct s_last_job *je; POOL_MEM msg(PM_MESSAGE); char level[10], dt[MAX_TIME_LENGTH], b1[30], b2[30]; if (!sp->api) { len = pm_strcpy(msg, _("\nTerminated Jobs:\n")); sendit(msg, len, sp); } if (last_jobs->size() == 0) { if (!sp->api) { len = pm_strcpy(msg, _("====\n")); sendit(msg, len, sp); } return; } lock_last_jobs_list(); if (!sp->api) { len = pm_strcpy(msg, _(" JobId Level Files Bytes Status Finished Name \n")); sendit(msg, len, sp); len = pm_strcpy(msg, _("======================================================================\n")); sendit(msg, len, sp); } foreach_dlist(je, last_jobs) { char *p; char JobName[MAX_NAME_LENGTH]; const char *termstat; bstrftime_nc(dt, sizeof(dt), je->end_time); switch (je->JobType) { case JT_ADMIN: case JT_RESTORE: bstrncpy(level, " ", sizeof(level)); break; default: bstrncpy(level, level_to_str(je->JobLevel), sizeof(level)); level[4] = 0; break; } switch (je->JobStatus) { case JS_Created: termstat = _("Created"); break; case JS_FatalError: case JS_ErrorTerminated: termstat = _("Error"); break; case JS_Differences: termstat = _("Diffs"); break; case JS_Canceled: termstat = _("Cancel"); break; case JS_Terminated: termstat = _("OK"); break; default: termstat = _("Other"); break; } bstrncpy(JobName, je->Job, sizeof(JobName)); /* * There are three periods after the Job name */ for (int i=0; i<3; i++) { if ((p=strrchr(JobName, '.')) != NULL) { *p = 0; } } if (sp->api) { len = Mmsg(msg, _("%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"), je->JobId, level, edit_uint64_with_commas(je->JobFiles, b1), edit_uint64_with_suffix(je->JobBytes, b2), termstat, dt, JobName); } else { len = Mmsg(msg, _("%6d %-6s %8s %10s %-7s %-8s %s\n"), je->JobId, level, edit_uint64_with_commas(je->JobFiles, b1), edit_uint64_with_suffix(je->JobBytes, b2), termstat, dt, JobName); } sendit(msg, len, sp); } unlock_last_jobs_list(); if (!sp->api) { len = pm_strcpy(msg, _("====\n")); sendit(msg, len, sp); } } /* * Send to bsock (Director or Console) */ static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp) { BSOCK *bs = sp->bs; if (bs) { memcpy(bs->msg, msg.c_str(), len+1); bs->msglen = len+1; bs->send(); } else { sp->callback(msg.c_str(), len, sp->context); } } /* * Status command from Director */ bool status_cmd(JCR *jcr) { BSOCK *user = jcr->dir_bsock; STATUS_PKT sp; user->fsend("\n"); sp.bs = user; sp.api = false; /* no API output */ output_status(&sp); user->signal(BNET_EOD); return true; } /* * .status command from Director */ bool qstatus_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOLMEM *cmd; JCR *njcr; s_last_job* job; STATUS_PKT sp; sp.bs = dir; cmd = get_memory(dir->msglen+1); if (sscanf(dir->msg, qstatus, cmd) != 1) { pm_strcpy(&jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg); dir->fsend(_("2900 Bad .status command, missing argument.\n")); dir->signal(BNET_EOD); free_memory(cmd); return false; } unbash_spaces(cmd); if (bstrcmp(cmd, "current")) { dir->fsend(OKqstatus, cmd); foreach_jcr(njcr) { if (njcr->JobId != 0) { dir->fsend(DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors); } } endeach_jcr(njcr); } else if (bstrcmp(cmd, "last")) { dir->fsend(OKqstatus, cmd); if ((last_jobs) && (last_jobs->size() > 0)) { job = (s_last_job*)last_jobs->last(); dir->fsend(DotStatusJob, job->JobId, job->JobStatus, job->Errors); } } else if (bstrcasecmp(cmd, "header")) { sp.api = true; list_status_header(&sp); } else if (bstrcasecmp(cmd, "running")) { sp.api = true; list_running_jobs(&sp); } else if (bstrcasecmp(cmd, "terminated")) { sp.api = true; list_terminated_jobs(&sp); } else { pm_strcpy(&jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad .status command: %s\n"), jcr->errmsg); dir->fsend(_("2900 Bad .status command, wrong argument.\n")); dir->signal(BNET_EOD); free_memory(cmd); return false; } dir->signal(BNET_EOD); free_memory(cmd); return true; } /* * Convert Job Level into a string */ static const char *level_to_str(int level) { const char *str; switch (level) { case L_BASE: str = _("Base"); break; case L_FULL: str = _("Full"); break; case L_INCREMENTAL: str = _("Incremental"); break; case L_DIFFERENTIAL: str = _("Differential"); break; case L_SINCE: str = _("Since"); break; case L_VERIFY_CATALOG: str = _("Verify Catalog"); break; case L_VERIFY_INIT: str = _("Init Catalog"); break; case L_VERIFY_VOLUME_TO_CATALOG: str = _("Volume to Catalog"); break; case L_VERIFY_DISK_TO_CATALOG: str = _("Disk to Catalog"); break; case L_VERIFY_DATA: str = _("Data"); break; case L_NONE: str = " "; break; default: str = _("Unknown Job Level"); break; } return str; } #if defined(HAVE_WIN32) int bareosstat = 0; /* * Put message in Window List Box */ char *bareos_status(char *buf, int buf_len) { JCR *njcr; const char *termstat = _("Bareos Client: Idle"); struct s_last_job *job; int status = 0; /* Idle */ if (!last_jobs) { goto done; } Dmsg0(1000, "Begin bareos_status jcr loop.\n"); foreach_jcr(njcr) { if (njcr->JobId != 0) { status = JS_Running; termstat = _("Bareos Client: Running"); break; } } endeach_jcr(njcr); if (status != 0) { goto done; } if (last_jobs->size() > 0) { job = (struct s_last_job *)last_jobs->last(); status = job->JobStatus; switch (job->JobStatus) { case JS_Canceled: termstat = _("Bareos Client: Last Job Canceled"); break; case JS_ErrorTerminated: case JS_FatalError: termstat = _("Bareos Client: Last Job Failed"); break; default: if (job->Errors) { termstat = _("Bareos Client: Last Job had Warnings"); } break; } } Dmsg0(1000, "End bareos_status jcr loop.\n"); done: bareosstat = status; if (buf) { bstrncpy(buf, termstat, buf_len); } return buf; } #endif /* HAVE_WIN32 */ bareos-Release-14.2.6/src/filed/verify.c000066400000000000000000000344531263011562700177730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon verify.c Verify files. * * Kern Sibbald, October MM */ #include "bareos.h" #include "filed.h" #ifdef HAVE_DARWIN_OS const bool have_darwin_os = true; #else const bool have_darwin_os = false; #endif static int verify_file(JCR *jcr, FF_PKT *ff_pkt, bool); static int read_digest(BFILE *bfd, DIGEST *digest, JCR *jcr); static bool calculate_file_chksum(JCR *jcr, FF_PKT *ff_pkt, DIGEST **digest, int *digest_stream, char **digest_buf, const char **digest_name); /* * Find all the requested files and send attributes * to the Director. * */ void do_verify(JCR *jcr) { jcr->setJobStatus(JS_Running); jcr->buf_size = DEFAULT_NETWORK_BUFFER_SIZE; if ((jcr->big_buf = (char *) malloc(jcr->buf_size)) == NULL) { Jmsg1(jcr, M_ABORT, 0, _("Cannot malloc %d network read buffer\n"), DEFAULT_NETWORK_BUFFER_SIZE); } set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime); Dmsg0(10, "Start find files\n"); /* Subroutine verify_file() is called for each file */ find_files(jcr, (FF_PKT *)jcr->ff, verify_file, NULL); Dmsg0(10, "End find files\n"); if (jcr->big_buf) { free(jcr->big_buf); jcr->big_buf = NULL; } jcr->setJobStatus(JS_Terminated); } /* * Called here by find() for each file. * * Find the file, compute the MD5 or SHA1 and send it back to the Director */ static int verify_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { POOL_MEM attribs(PM_NAME), attribsEx(PM_NAME); int status; BSOCK *dir; if (job_canceled(jcr)) { return 0; } dir = jcr->dir_bsock; jcr->num_files_examined++; /* bump total file count */ switch (ff_pkt->type) { case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(30, "FT_LNKSAVED saving: %s => %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_REGE: Dmsg1(30, "FT_REGE saving: %s\n", ff_pkt->fname); break; case FT_REG: Dmsg1(30, "FT_REG saving: %s\n", ff_pkt->fname); break; case FT_LNK: Dmsg2(30, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ return 1; /* ignored */ case FT_REPARSE: case FT_JUNCTION: case FT_DIREND: Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname); break; case FT_SPEC: Dmsg1(30, "FT_SPEC saving: %s\n", ff_pkt->fname); break; case FT_RAW: Dmsg1(30, "FT_RAW saving: %s\n", ff_pkt->fname); break; case FT_FIFO: Dmsg1(30, "FT_FIFO saving: %s\n", ff_pkt->fname); break; case FT_NOACCESS: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } case FT_NOFOLLOW: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not follow link %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } case FT_NOSTAT: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } case FT_DIRNOCHG: case FT_NOCHG: Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname); return 1; case FT_ISARCH: Jmsg(jcr, M_SKIPPED, 1, _(" Archive file skipped: %s\n"), ff_pkt->fname); return 1; case FT_NORECURSE: Jmsg(jcr, M_SKIPPED, 1, _(" Recursion turned off. Directory skipped: %s\n"), ff_pkt->fname); ff_pkt->type = FT_DIREND; /* directory entry was backed up */ break; case FT_NOFSCHG: Jmsg(jcr, M_SKIPPED, 1, _(" File system change prohibited. Directory skipped: %s\n"), ff_pkt->fname); return 1; case FT_PLUGIN_CONFIG: case FT_RESTORE_FIRST: return 1; /* silently skip */ case FT_NOOPEN: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not open directory %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } default: Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d: %s\n"), ff_pkt->type, ff_pkt->fname); jcr->JobErrors++; return 1; } /* Encode attributes and possibly extend them */ encode_stat(attribs.c_str(), &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, 0); encode_attribsEx(jcr, attribsEx.c_str(), ff_pkt); jcr->lock(); jcr->JobFiles++; /* increment number of files sent */ pm_strcpy(jcr->last_fname, ff_pkt->fname); jcr->unlock(); /* * Send file attributes to Director * File_index * Stream * Verify Options * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK) * For a directory, link is the same as fname, but with trailing * slash. For a linked file, link is the link. */ /* * Send file attributes to Director (note different format than for Storage) */ Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname); if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) { status = dir->fsend("%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs.c_str(), 0, ff_pkt->link, 0); } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION) { /* * Here link is the canonical filename (i.e. with trailing slash) */ status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link, 0, attribs.c_str(), 0, 0); } else { status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs.c_str(), 0, 0); } Dmsg2(20, "filed>dir: attribs len=%d: msg=%s\n", dir->msglen, dir->msg); if (!status) { Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); return 0; } if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && (bit_is_set(FO_MD5, ff_pkt->flags) || bit_is_set(FO_SHA1, ff_pkt->flags) || bit_is_set(FO_SHA256, ff_pkt->flags) || bit_is_set(FO_SHA512, ff_pkt->flags))) { int digest_stream = STREAM_NONE; DIGEST *digest = NULL; char *digest_buf = NULL; const char *digest_name = NULL; if (calculate_file_chksum(jcr, ff_pkt, &digest, &digest_stream, &digest_buf, &digest_name)) { /* * Did digest initialization fail? */ if (digest_stream != STREAM_NONE && digest == NULL) { Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"), stream_to_ascii(digest_stream)); } else if (digest && digest_buf) { Dmsg3(400, "send inx=%d %s=%s\n", jcr->JobFiles, digest_name, digest_buf); dir->fsend("%d %d %s *%s-%d*", jcr->JobFiles, digest_stream, digest_buf, digest_name, jcr->JobFiles); Dmsg3(20, "filed>dir: %s len=%d: msg=%s\n", digest_name, dir->msglen, dir->msg); } } /* * Cleanup. */ if (digest_buf) { free(digest_buf); } if (digest) { crypto_digest_free(digest); } } return 1; } /* * Compute message digest for the file specified by ff_pkt. * In case of errors we need the job control record and file name. */ int digest_file(JCR *jcr, FF_PKT *ff_pkt, DIGEST *digest) { BFILE bfd; binit(&bfd); int noatime = bit_is_set(FO_NOATIME, ff_pkt->flags) ? O_NOATIME : 0; if ((bopen(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0, ff_pkt->statp.st_rdev)) < 0) { ff_pkt->ff_errno = errno; berrno be; be.set_errno(bfd.berrno); Dmsg2(100, "Cannot open %s: ERR=%s\n", ff_pkt->fname, be.bstrerror()); Jmsg(jcr, M_ERROR, 1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); return 1; } read_digest(&bfd, digest, jcr); bclose(&bfd); if (have_darwin_os) { /* * Open resource fork if necessary */ if (bit_is_set(FO_HFSPLUS, ff_pkt->flags) && ff_pkt->hfsinfo.rsrclength > 0) { if (bopen_rsrc(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; Jmsg(jcr, M_ERROR, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); if (is_bopen(&ff_pkt->bfd)) { bclose(&ff_pkt->bfd); } return 1; } read_digest(&bfd, digest, jcr); bclose(&bfd); } if (digest && bit_is_set(FO_HFSPLUS, ff_pkt->flags)) { crypto_digest_update(digest, (uint8_t *)ff_pkt->hfsinfo.fndrinfo, 32); } } return 0; } /* * Read message digest of bfd, updating digest * In case of errors we need the job control record and file name. */ static int read_digest(BFILE *bfd, DIGEST *digest, JCR *jcr) { char buf[DEFAULT_NETWORK_BUFFER_SIZE]; int64_t n; int64_t bufsiz = (int64_t)sizeof(buf); FF_PKT *ff_pkt = (FF_PKT *)jcr->ff; uint64_t fileAddr = 0; /* file address */ Dmsg0(50, "=== read_digest\n"); while ((n=bread(bfd, buf, bufsiz)) > 0) { /* Check for sparse blocks */ if (bit_is_set(FO_SPARSE, ff_pkt->flags)) { bool allZeros = false; if ((n == bufsiz && fileAddr+n < (uint64_t)ff_pkt->statp.st_size) || ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) && (uint64_t)ff_pkt->statp.st_size == 0)) { allZeros = is_buf_zero(buf, bufsiz); } fileAddr += n; /* update file address */ /* Skip any block of all zeros */ if (allZeros) { continue; /* skip block of zeros */ } } crypto_digest_update(digest, (uint8_t *)buf, n); /* Can be used by BaseJobs or with accurate, update only for Verify * jobs */ if (jcr->is_JobType(JT_VERIFY)) { jcr->JobBytes += n; } jcr->ReadBytes += n; } if (n < 0) { berrno be; be.set_errno(bfd->berrno); Dmsg2(100, "Error reading file %s: ERR=%s\n", jcr->last_fname, be.bstrerror()); Jmsg(jcr, M_ERROR, 1, _("Error reading file %s: ERR=%s\n"), jcr->last_fname, be.bstrerror()); jcr->JobErrors++; return -1; } return 0; } /* * Calculate the chksum of a whole file and updates: * - digest * - digest_stream * - digest_buffer * - digest_name * * Returns: true if digest calculation succeeded. * false if digest calculation failed. */ static bool calculate_file_chksum(JCR *jcr, FF_PKT *ff_pkt, DIGEST **digest, int *digest_stream, char **digest_buf, const char **digest_name) { /* * Create our digest context. * If this fails, the digest will be set to NULL and not used. */ if (bit_is_set(FO_MD5 ,ff_pkt->flags)) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); *digest_stream = STREAM_MD5_DIGEST; } else if (bit_is_set(FO_SHA1,ff_pkt->flags)) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1); *digest_stream = STREAM_SHA1_DIGEST; } else if (bit_is_set(FO_SHA256 ,ff_pkt->flags)) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256); *digest_stream = STREAM_SHA256_DIGEST; } else if (bit_is_set(FO_SHA512 ,ff_pkt->flags)) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); *digest_stream = STREAM_SHA512_DIGEST; } /* * compute MD5 or SHA1 hash */ if (*digest) { uint32_t size; char md[CRYPTO_DIGEST_MAX_SIZE]; size = sizeof(md); if (digest_file(jcr, ff_pkt, *digest) != 0) { jcr->JobErrors++; return false; } if (crypto_digest_finalize(*digest, (uint8_t *)md, &size)) { *digest_buf = (char *)malloc(BASE64_SIZE(size)); *digest_name = crypto_digest_name(*digest); bin_to_base64(*digest_buf, BASE64_SIZE(size), md, size, true); } } return true; } /* * Compare a files chksum against a stored chksum. * * Returns: true if chksum matches. * false if chksum is different. */ bool calculate_and_compare_file_chksum(JCR *jcr, FF_PKT *ff_pkt, const char *fname, const char *chksum) { DIGEST *digest = NULL; int digest_stream = STREAM_NONE; char *digest_buf = NULL; const char *digest_name; bool retval = false; if (calculate_file_chksum(jcr, ff_pkt, &digest, &digest_stream, &digest_buf, &digest_name)) { if (digest_stream != STREAM_NONE && digest == NULL) { Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"), stream_to_ascii(digest_stream)); } else if (digest && digest_buf) { if (!bstrcmp(digest_buf, chksum)) { Dmsg4(100, "%s %s chksum diff. Cat: %s File: %s\n", fname, digest_name, chksum, digest_buf); } else { retval = true; } } if (digest_buf) { free(digest_buf); } if (digest) { crypto_digest_free(digest); } } return retval; } bareos-Release-14.2.6/src/filed/verify_vol.c000066400000000000000000000221341263011562700206440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos File Daemon verify-vol.c Verify files on a Volume * versus attributes in Catalog * * Kern Sibbald, July MMII */ #include "bareos.h" #include "filed.h" /* Data received from Storage Daemon */ static char rec_header[] = "rechdr %ld %ld %ld %ld %ld"; /* Forward referenced functions */ /* * Verify attributes of the requested files on the Volume * */ void do_verify_volume(JCR *jcr) { BSOCK *sd, *dir; POOLMEM *fname; /* original file name */ POOLMEM *lname; /* link name */ int32_t stream; uint32_t size; uint32_t VolSessionId, VolSessionTime, file_index; uint32_t record_file_index; char digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; int type, status; sd = jcr->store_bsock; if (!sd) { Jmsg(jcr, M_FATAL, 0, _("Storage command not issued before Verify.\n")); jcr->setJobStatus(JS_FatalError); return; } dir = jcr->dir_bsock; jcr->setJobStatus(JS_Running); LockRes(); CLIENTRES *client = (CLIENTRES *)GetNextRes(R_CLIENT, NULL); UnlockRes(); uint32_t buf_size; if (client) { buf_size = client->max_network_buffer_size; } else { buf_size = 0; /* use default */ } if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) { jcr->setJobStatus(JS_FatalError); return; } jcr->buf_size = sd->msglen; fname = get_pool_memory(PM_FNAME); lname = get_pool_memory(PM_FNAME); /* * Get a record from the Storage daemon */ while (bget_msg(sd) >= 0 && !job_canceled(jcr)) { /* * First we expect a Stream Record Header */ if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index, &stream, &size) != 5) { Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg); goto bail_out; } Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream); /* * Now we expect the Stream Data */ if (bget_msg(sd) < 0) { Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd)); goto bail_out; } if (size != ((uint32_t)sd->msglen)) { Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size); goto bail_out; } Dmsg1(30, "Got stream data, len=%d\n", sd->msglen); /* File Attributes stream */ switch (stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: char *ap, *lp, *fp; Dmsg0(400, "Stream=Unix Attributes.\n"); if ((int)sizeof_pool_memory(fname) < sd->msglen) { fname = realloc_pool_memory(fname, sd->msglen + 1); } if ((int)sizeof_pool_memory(lname) < sd->msglen) { lname = realloc_pool_memory(lname, sd->msglen + 1); } *fname = 0; *lname = 0; /* * An Attributes record consists of: * File_index * Type (FT_types) * Filename * Attributes * Link name (if file linked i.e. FT_LNK) * Extended Attributes (if Win32) */ if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) { Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg); Dmsg0(0, "\nError scanning header\n"); goto bail_out; } Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type); ap = sd->msg; while (*ap++ != ' ') /* skip record file index */ ; while (*ap++ != ' ') /* skip type */ ; /* Save filename and position to attributes */ fp = fname; while (*ap != 0) { *fp++ = *ap++; /* copy filename to fname */ } *fp = *ap++; /* terminate filename & point to attribs */ Dmsg1(200, "Attr=%s\n", ap); /* Skip to Link name */ if (type == FT_LNK || type == FT_LNKSAVED) { lp = ap; while (*lp++ != 0) { ; } pm_strcat(lname, lp); /* "save" link name */ } else { *lname = 0; } jcr->lock(); jcr->JobFiles++; jcr->num_files_examined++; pm_strcpy(jcr->last_fname, fname); /* last file examined */ jcr->unlock(); /* * Send file attributes to Director * File_index * Stream * Verify Options * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK) * For a directory, link is the same as fname, but with trailing * slash. For a linked file, link is the link. */ /* Send file attributes to Director */ Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname); if (type == FT_LNK || type == FT_LNKSAVED) { status = dir->fsend("%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, "pinsug5", fname, 0, ap, 0, lname, 0); /* for a deleted record, we set fileindex=0 */ } else if (type == FT_DELETED) { status = dir->fsend("%d %d %s %s%c%s%c%c", 0, STREAM_UNIX_ATTRIBUTES, "pinsug5", fname, 0, ap, 0, 0); } else { status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, "pinsug5", fname, 0, ap, 0, 0); } Dmsg2(200, "filed>dir: attribs len=%d: msg=%s\n", dir->msglen, dir->msg); if (!status) { Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); goto bail_out; } break; case STREAM_MD5_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_MD5_SIZE, true); Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "filed>dir: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_SHA1_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA1_SIZE, true); Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "filed>dir: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_SHA256_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA256_SIZE, true); Dmsg2(400, "send inx=%d SHA256=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *SHA256-%d*", jcr->JobFiles, STREAM_SHA256_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "filed>dir: SHA256 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_SHA512_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA512_SIZE, true); Dmsg2(400, "send inx=%d SHA512=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *SHA512-%d*", jcr->JobFiles, STREAM_SHA512_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "filed>dir: SHA512 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_RESTORE_OBJECT: jcr->lock(); jcr->JobFiles++; jcr->num_files_examined++; jcr->unlock(); Dmsg2(400, "send inx=%d STREAM_RESTORE_OBJECT-%d\n", jcr->JobFiles, STREAM_RESTORE_OBJECT); dir->fsend("%d %d %s %s%c%c%c", jcr->JobFiles, STREAM_RESTORE_OBJECT, "ReStOrEObJeCt", fname, 0, 0, 0); break; /* Ignore everything else */ default: break; } /* end switch */ } /* end while bnet_get */ jcr->setJobStatus(JS_Terminated); goto ok_out; bail_out: jcr->setJobStatus(JS_ErrorTerminated); ok_out: cleanup_compression(jcr); free_pool_memory(fname); free_pool_memory(lname); Dmsg2(050, "End Verify-Vol. Files=%d Bytes=%" lld "\n", jcr->JobFiles, jcr->JobBytes); } bareos-Release-14.2.6/src/findlib/000077500000000000000000000000001263011562700166365ustar00rootroot00000000000000bareos-Release-14.2.6/src/findlib/Makefile.in000066400000000000000000000077211263011562700207120ustar00rootroot00000000000000# # Find files library Makefile # @MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/findlib DEBUG=@DEBUG@ first_rule: all dummy: # # include files installed when using libtool # INCLUDE_FILES = bfile.h find.h protos.h # LIBBAREOSFIND_SRCS = acl.c attribs.c bfile.c create_file.c \ drivetype.c enable_priv.c find_one.c \ find.c fstype.c hardlink.c match.c mkpath.c \ savecwd.c shadowing.c xattr.c LIBBAREOSFIND_OBJS = $(LIBBAREOSFIND_SRCS:.c=.o) LIBBAREOSFIND_LOBJS = $(LIBBAREOSFIND_SRCS:.c=.lo) LIBBAREOSFIND_LT_RELEASE = @LIBBAREOSFIND_LT_RELEASE@ AFS_CFLAGS = @AFS_CFLAGS@ ACL_LIBS = @ACL_LIBS@ XATTR_LIBS = @XATTR_LIBS@ AFS_LIBS = @AFS_LIBS@ INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .o .lo .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< .c.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile libbareosfind$(DEFAULT_ARCHIVE_TYPE) ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "==== Make of findlib is good ====" @echo " " acl.o: acl.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $(AFS_CFLAGS) $< acl.lo: acl.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $(AFS_CFLAGS) $< libbareosfind.a: $(LIBBAREOSFIND_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOSFIND_OBJS) $(RANLIB) $@ libbareosfind.la: Makefile $(LIBBAREOSFIND_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(LIBBAREOSFIND_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOSFIND_LT_RELEASE) $(ACL_LIBS) $(XATTR_LIBS) $(AFS_LIBS) -lbareos Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-includes: $(MKDIR) $(DESTDIR)/$(includedir)/bareos/findlib for I in $(INCLUDE_FILES); do \ $(INSTALL_DATA) $$I $(DESTDIR)$(includedir)/bareos/findlib/`basename $$I`; \ done libtool-install: all $(MKDIR) $(DESTDIR)$(libdir) $(RMF) $(DESTDIR)$(libdir)/libbareosfind-*.so $(DESTDIR)$(libdir)/libbareosfind.la $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareosfind$(DEFAULT_ARCHIVE_TYPE) $(DESTDIR)$(libdir) install: @LIBTOOL_INSTALL_TARGET@ @INCLUDE_INSTALL_TARGET@ libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) find core a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 realclean: clean @$(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) # Semi-automatic generation of dependencies: # Use gcc -M because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @for src in $(LIBBAREOSFIND_SRCS); do \ $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(AFS_CFLAGS) $(XINC) $(INCLUDES) $$src >> Makefile; \ done @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/findlib/acl.c000066400000000000000000002262621263011562700175530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Functions to handle ACLs for bareos. * * Currently we support the following OSes: * - AIX (pre-5.3 and post 5.3 acls, acl_get and aclx_get interface) * - Darwin * - FreeBSD (POSIX and NFSv4/ZFS acls) * - GNU Hurd * - HPUX * - IRIX * - Linux * - Solaris (POSIX and NFSv4/ZFS acls) * - Tru64 * * Next to OS specific acls we support AFS acls using the pioctl interface. * * We handle two different types of ACLs: access and default ACLS. * On most systems that support default ACLs they only apply to directories. * * On some systems (eg. linux and FreeBSD) we must obtain the two ACLs * independently, while others (eg. Solaris) provide both in one call. * * The Filed saves ACLs in their native format and uses different streams * for all different platforms. Currently we only allow ACLs to be restored * which were saved in the native format of the platform they are extracted * on. Later on we might add conversion functions for mapping from one * platform to an other or allow restores of systems that use the same * native format. * * Its also interesting to see what the exact format of acl text is on * certain platforms and if they use they same encoding we might allow * different platform streams to be decoded on an other similar platform. * * Original written by Preben 'Peppe' Guldberg, December 2004 * Major rewrite by Marco van Wieringen, November 2008 * Major overhaul by Marco van Wieringen, January 2012 * Moved into findlib so it can be used from other programs, May 2012 */ #include "bareos.h" #include "find.h" #if !defined(HAVE_ACL) && !defined(HAVE_AFS_ACL) /** * Entry points when compiled without support for ACLs or on an unsupported platform. */ bacl_exit_code build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { return bacl_exit_fatal; } bacl_exit_code parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { return bacl_exit_fatal; } #else /** * Send an ACL stream to the SD. */ bacl_exit_code send_acl_stream(JCR *jcr, acl_data_t *acl_data, int stream) { BSOCK *sd = jcr->store_bsock; POOLMEM *msgsave; #ifdef FD_NO_SEND_TEST return bacl_exit_ok; #endif /* * Sanity check */ if (acl_data->u.build->content_length <= 0) { return bacl_exit_ok; } /* * Send header */ if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return bacl_exit_fatal; } /* * Send the buffer to the storage deamon */ Dmsg1(400, "Backing up ACL <%s>\n", acl_data->u.build->content); msgsave = sd->msg; sd->msg = acl_data->u.build->content; sd->msglen = acl_data->u.build->content_length + 1; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return bacl_exit_fatal; } jcr->JobBytes += sd->msglen; sd->msg = msgsave; if (!sd->signal(BNET_EOD)) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return bacl_exit_fatal; } Dmsg1(200, "ACL of file: %s successfully backed up!\n", acl_data->last_fname); return bacl_exit_ok; } /* * First the native ACLs. */ #if defined(HAVE_ACL) #if defined(HAVE_AIX_OS) #if defined(HAVE_EXTENDED_ACL) #include #include static bool acl_is_trivial(struct acl *acl) { return (acl_last(acl) != acl->acl_ext ? false : true); } static bool acl_nfs4_is_trivial(nfs4_acl_int_t *acl) { #if 0 return (acl->aclEntryN > 0 ? false : true); #else int i; int count = acl->aclEntryN; nfs4_ace_int_t *ace; for (i = 0; i < count; i++) { ace = &acl->aclEntry[i]; if (!((ace->flags & ACE4_ID_SPECIAL) != 0 && (ace->aceWho.special_whoid == ACE4_WHO_OWNER || ace->aceWho.special_whoid == ACE4_WHO_GROUP || ace->aceWho.special_whoid == ACE4_WHO_EVERYONE) && ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE && ace->aceFlags == 0 && (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY | ACE4_WRITE_DATA | ACE4_ADD_FILE | ACE4_EXECUTE)) == 0)) { return false; } } return true; #endif } /* * Define the supported ACL streams for this OS */ static int os_access_acl_streams[3] = { STREAM_ACL_AIX_TEXT, STREAM_ACL_AIX_AIXC, STREAM_ACL_AIX_NFS4 }; static int os_default_acl_streams[1] = { -1 }; static bacl_exit_code aix_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { mode_t mode; acl_type_t type; size_t aclsize, acltxtsize; bacl_exit_code retval = bacl_exit_error; POOLMEM *aclbuf = get_pool_memory(PM_MESSAGE); /* * First see how big the buffers should be. */ memset(&type, 0, sizeof(acl_type_t)); type.u64 = ACL_ANY; if (aclx_get(acl_data->last_fname, #if defined(GET_ACL_FOR_LINK) GET_ACLINFO_ONLY | GET_ACL_FOR_LINK, #else GET_ACLINFO_ONLY, #endif &type, NULL, &aclsize, &mode) < 0) { berrno be; switch (errno) { case ENOENT: retval = bacl_exit_ok; goto bail_out; case ENOSYS: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_SAVE_NATIVE flag so we skip ACL saves on all other files * on the same filesystem. The BACL_FLAG_SAVE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; retval = bacl_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("aclx_get error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "aclx_get error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Make sure the buffers are big enough. */ aclbuf = check_pool_memory_size(aclbuf, aclsize + 1); /* * Retrieve the ACL info. */ if (aclx_get(acl_data->last_fname, #if defined(GET_ACL_FOR_LINK) GET_ACL_FOR_LINK, #else 0, #endif &type, aclbuf, &aclsize, &mode) < 0) { berrno be; switch (errno) { case ENOENT: retval = bacl_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("aclx_get error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "aclx_get error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); goto bail_out; } } /* * See if the acl is non trivial. */ switch (type.u64) { case ACL_AIXC: if (acl_is_trivial((struct acl *)aclbuf)) { retval = bacl_exit_ok; goto bail_out; } break; case ACL_NFS4: if (acl_nfs4_is_trivial((nfs4_acl_int_t *)aclbuf)) { retval = bacl_exit_ok; goto bail_out; } break; default: Mmsg2(jcr->errmsg, _("Unknown acl type encountered on file \"%s\": %ld\n"), acl_data->last_fname, type.u64); Dmsg2(100, "Unknown acl type encountered on file \"%s\": %ld\n", acl_data->last_fname, type.u64); goto bail_out; } /* * We have a non-trivial acl lets convert it into some ASCII form. */ acltxtsize = sizeof_pool_memory(acl_data->u.build->content); if (aclx_printStr(acl_data->u.build->content, &acltxtsize, aclbuf, aclsize, type, acl_data->last_fname, 0) < 0) { switch (errno) { case ENOSPC: /* * Our buffer is not big enough, acltxtsize should be updated with the value * the aclx_printStr really need. So we increase the buffer and try again. */ acl_data->u.build->content = check_pool_memory_size(acl_data->u.build->content, acltxtsize + 1); if (aclx_printStr(acl_data->u.build->content, &acltxtsize, aclbuf, aclsize, type, acl_data->last_fname, 0) < 0) { Mmsg1(jcr->errmsg, _("Failed to convert acl into text on file \"%s\"\n"), acl_data->last_fname); Dmsg2(100, "Failed to convert acl into text on file \"%s\": %ld\n", acl_data->last_fname, type.u64); goto bail_out; } break; default: Mmsg1(jcr->errmsg, _("Failed to convert acl into text on file \"%s\"\n"), acl_data->last_fname); Dmsg2(100, "Failed to convert acl into text on file \"%s\": %ld\n", acl_data->last_fname, type.u64); goto bail_out; } } acl_data->u.build->content_length = strlen(acl_data->u.build->content) + 1; switch (type.u64) { case ACL_AIXC: retval = send_acl_stream(jcr, acl_data, STREAM_ACL_AIX_AIXC); break; case ACL_NFS4: retval = send_acl_stream(jcr, acl_data, STREAM_ACL_AIX_NFS4); break; } bail_out: free_pool_memory(aclbuf); return retval; } /* * See if a specific type of ACLs are supported on the filesystem * the file is located on. */ static inline bool aix_query_acl_support(JCR *jcr, acl_data_t *acl_data, uint64_t aclType, acl_type_t *pacl_type_info) { unsigned int i; acl_types_list_t acl_type_list; size_t acl_type_list_len = sizeof(acl_types_list_t); memset(&acl_type_list, 0, sizeof(acl_type_list)); if (aclx_gettypes(acl_data->last_fname, &acl_type_list, &acl_type_list_len)) { return false; } for (i = 0; i < acl_type_list.num_entries; i++) { if (acl_type_list.entries[i].u64 == aclType) { memcpy(pacl_type_info, acl_type_list.entries + i, sizeof(acl_type_t)); return true; } } return false; } static bacl_exit_code aix_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { int cnt; acl_type_t type; size_t aclsize; bacl_exit_code retval = bacl_exit_error; POOLMEM *aclbuf = get_pool_memory(PM_MESSAGE); switch (stream) { case STREAM_ACL_AIX_TEXT: /* * Handle the old stream using the old system call for now. */ if (acl_put(acl_data->last_fname, content, 0) != 0) { retval = bacl_exit_error; goto bail_out; } retval = bacl_exit_ok; goto bail_out; case STREAM_ACL_AIX_AIXC: if (!aix_query_acl_support(jcr, acl_data, ACL_AIXC, &type)) { Mmsg1(jcr->errmsg, _("Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl support\n"), acl_data->last_fname); goto bail_out; } break; case STREAM_ACL_AIX_NFS4: if (!aix_query_acl_support(jcr, acl_data, ACL_NFS4, &type)) { Mmsg1(jcr->errmsg, _("Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl support\n"), acl_data->last_fname); goto bail_out; } break; default: goto bail_out; } /* end switch (stream) */ /* * Set the acl buffer to an initial size. For now we set it * to the same size as the ASCII representation. */ aclbuf = check_pool_memory_size(aclbuf, content_length); aclsize = content_length; if (aclx_scanStr(content, aclbuf, &aclsize, type) < 0) { berrno be; switch (errno) { case ENOSPC: /* * The buffer isn't big enough. The man page doesn't say that aclsize * is updated to the needed size as what is done with aclx_printStr. * So for now we try to increase the buffer a maximum of 3 times * and retry the conversion. */ for (cnt = 0; cnt < 3; cnt++) { aclsize = 2 * aclsize; aclbuf = check_pool_memory_size(aclbuf, aclsize); if (aclx_scanStr(content, aclbuf, &aclsize, type) == 0) { break; } /* * See why we failed this time, ENOSPC retry if max retries not met, * otherwise abort. */ switch (errno) { case ENOSPC: if (cnt < 3) { continue; } /* * FALLTHROUGH */ default: Mmsg2(jcr->errmsg, _("aclx_scanStr error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror(errno)); Dmsg2(100, "aclx_scanStr error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); goto bail_out; } } break; default: Mmsg2(jcr->errmsg, _("aclx_scanStr error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "aclx_scanStr error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); } } if (aclx_put(acl_data->last_fname, SET_ACL, type, aclbuf, aclsize, 0) < 0) { berrno be; switch (errno) { case ENOENT: retval = bacl_exit_ok; goto bail_out; case ENOSYS: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; retval = bacl_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("aclx_put error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "aclx_put error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); goto bail_out; } } retval = bacl_exit_ok; bail_out: free_pool_memory(aclbuf); return retval; } #else /* HAVE_EXTENDED_ACL */ #include /* * Define the supported ACL streams for this OS */ static int os_access_acl_streams[1] = { STREAM_ACL_AIX_TEXT }; static int os_default_acl_streams[1] = { -1 }; static bacl_exit_code aix_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { char *acl_text; if ((acl_text = acl_get(acl_data->last_fname)) != NULL) { acl_data->u.build->content_length = pm_strcpy(acl_data->u.build->content, acl_text); actuallyfree(acl_text); return send_acl_stream(jcr, acl_data, STREAM_ACL_AIX_TEXT); } return bacl_exit_error; } static bacl_exit_code aix_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { if (acl_put(acl_data->last_fname, content, 0) != 0) { return bacl_exit_error; } return bacl_exit_ok; } #endif /* HAVE_EXTENDED_ACL */ /* * For this OS setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = aix_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = aix_parse_acl_streams; #elif defined(HAVE_DARWIN_OS) || \ defined(HAVE_FREEBSD_OS) || \ defined(HAVE_IRIX_OS) || \ defined(HAVE_OSF1_OS) || \ defined(HAVE_LINUX_OS) || \ defined(HAVE_HURD_OS) #include #ifdef HAVE_SYS_ACL_H #include #else #error "configure failed to detect availability of sys/acl.h" #endif /* * On IRIX we can get shortened ACLs */ #if defined(HAVE_IRIX_OS) && defined(BACL_WANT_SHORT_ACLS) #define acl_to_text(acl,len) acl_to_short_text((acl), (len)) #endif /* * On Linux we can get numeric and/or shorted ACLs */ #if defined(HAVE_LINUX_OS) #if defined(BACL_WANT_SHORT_ACLS) && defined(BACL_WANT_NUMERIC_IDS) #define BACL_ALTERNATE_TEXT (TEXT_ABBREVIATE|TEXT_NUMERIC_IDS) #elif defined(BACL_WANT_SHORT_ACLS) #define BACL_ALTERNATE_TEXT TEXT_ABBREVIATE #elif defined(BACL_WANT_NUMERIC_IDS) #define BACL_ALTERNATE_TEXT TEXT_NUMERIC_IDS #endif #ifdef BACL_ALTERNATE_TEXT #include #define acl_to_text(acl,len) (acl_to_any_text((acl), NULL, ',', BACL_ALTERNATE_TEXT)) #endif #endif /* * On FreeBSD we can get numeric ACLs */ #if defined(HAVE_FREEBSD_OS) #if defined(BACL_WANT_NUMERIC_IDS) #define BACL_ALTERNATE_TEXT ACL_TEXT_NUMERIC_IDS #endif #ifdef BACL_ALTERNATE_TEXT #define acl_to_text(acl,len) (acl_to_text_np((acl), (len), BACL_ALTERNATE_TEXT)) #endif #endif /* * Some generic functions used by multiple OSes. */ static acl_type_t bac_to_os_acltype(bacl_type acltype) { acl_type_t ostype; switch (acltype) { case BACL_TYPE_ACCESS: ostype = ACL_TYPE_ACCESS; break; case BACL_TYPE_DEFAULT: ostype = ACL_TYPE_DEFAULT; break; #ifdef HAVE_ACL_TYPE_NFS4 /* * FreeBSD has an additional acl type named ACL_TYPE_NFS4. */ case BACL_TYPE_NFS4: ostype = ACL_TYPE_NFS4; break; #endif #ifdef HAVE_ACL_TYPE_DEFAULT_DIR case BACL_TYPE_DEFAULT_DIR: /* * TRU64 has an additional acl type named ACL_TYPE_DEFAULT_DIR. */ ostype = ACL_TYPE_DEFAULT_DIR; break; #endif #ifdef HAVE_ACL_TYPE_EXTENDED case BACL_TYPE_EXTENDED: /* * MacOSX has an additional acl type named ACL_TYPE_EXTENDED. */ ostype = ACL_TYPE_EXTENDED; break; #endif default: /* * This should never happen, as the per OS version function only tries acl * types supported on a certain platform. */ ostype = (acl_type_t)ACL_TYPE_NONE; break; } return ostype; } static int acl_count_entries(acl_t acl) { int count = 0; #if defined(HAVE_FREEBSD_OS) || \ defined(HAVE_LINUX_OS) || \ defined(HAVE_HURD_OS) acl_entry_t ace; int entry_available; entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace); while (entry_available == 1) { count++; entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace); } #elif defined(HAVE_IRIX_OS) count = acl->acl_cnt; #elif defined(HAVE_OSF1_OS) count = acl->acl_num; #elif defined(HAVE_DARWIN_OS) acl_entry_t ace; int entry_available; entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace); while (entry_available == 0) { count++; entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace); } #endif return count; } #if !defined(HAVE_DARWIN_OS) /* * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.) * There is no need to store those acls as we already store the stat bits too. */ static bool acl_is_trivial(acl_t acl) { /* * acl is trivial if it has only the following entries: * "user::", * "group::", * "other::" */ acl_entry_t ace; acl_tag_t tag; #if defined(HAVE_FREEBSD_OS) || \ defined(HAVE_LINUX_OS) || \ defined(HAVE_HURD_OS) int entry_available; entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace); while (entry_available == 1) { /* * Get the tag type of this acl entry. * If we fail to get the tagtype we call the acl non-trivial. */ if (acl_get_tag_type(ace, &tag) < 0) return true; /* * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell. */ if (tag != ACL_USER_OBJ && tag != ACL_GROUP_OBJ && tag != ACL_OTHER) return false; entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace); } return true; #elif defined(HAVE_IRIX_OS) int n; for (n = 0; n < acl->acl_cnt; n++) { ace = &acl->acl_entry[n]; tag = ace->ae_tag; /* * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell. */ if (tag != ACL_USER_OBJ && tag != ACL_GROUP_OBJ && tag != ACL_OTHER_OBJ) return false; } return true; #elif defined(HAVE_OSF1_OS) int count; ace = acl->acl_first; count = acl->acl_num; while (count > 0) { tag = ace->entry->acl_type; /* * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell. */ if (tag != ACL_USER_OBJ && tag != ACL_GROUP_OBJ && tag != ACL_OTHER) return false; /* * On Tru64, perm can also contain non-standard bits such as * PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */ if ((ace->entry->acl_perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE))) return false; ace = ace->next; count--; } return true; #endif } #endif /** * Generic wrapper around acl_get_file call. */ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, acl_data_t *acl_data, bacl_type acltype) { acl_t acl; acl_type_t ostype; char *acl_text; bacl_exit_code retval = bacl_exit_ok; ostype = bac_to_os_acltype(acltype); acl = acl_get_file(acl_data->last_fname, ostype); if (acl) { /** * From observation, IRIX's acl_get_file() seems to return a * non-NULL acl with a count field of -1 when a file has no ACL * defined, while IRIX's acl_to_text() returns NULL when presented * with such an ACL. * * For all other implmentations we check if there are more then * zero entries in the acl returned. */ if (acl_count_entries(acl) <= 0) { goto bail_out; } /* * Make sure this is not just a trivial ACL. */ #if !defined(HAVE_DARWIN_OS) if (acltype == BACL_TYPE_ACCESS && acl_is_trivial(acl)) { /* * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ goto bail_out; } #endif #if defined(HAVE_FREEBSD_OS) && defined(_PC_ACL_NFS4) if (acltype == BACL_TYPE_NFS4) { int trivial; if (acl_is_trivial_np(acl, &trivial) == 0) { if (trivial == 1) { /* * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ goto bail_out; } } } #endif /* * Convert the internal acl representation into a text representation. */ if ((acl_text = acl_to_text(acl, NULL)) != NULL) { acl_data->u.build->content_length = pm_strcpy(acl_data->u.build->content, acl_text); acl_free(acl); acl_free(acl_text); return bacl_exit_ok; } berrno be; Mmsg2(jcr->errmsg, _("acl_to_text error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "acl_to_text error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); retval = bacl_exit_error; goto bail_out; } else { berrno be; /* * Handle errors gracefully. */ switch (errno) { #if defined(BACL_ENOTSUP) case BACL_ENOTSUP: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_SAVE_NATIVE flag so we skip ACL saves on all other files * on the same filesystem. The BACL_FLAG_SAVE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; goto bail_out; #endif case ENOENT: goto bail_out; default: /* Some real error */ Mmsg2(jcr->errmsg, _("acl_get_file error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "acl_get_file error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); retval = bacl_exit_error; goto bail_out; } } bail_out: if (acl) { acl_free(acl); } pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return retval; } /** * Generic wrapper around acl_set_file call. */ static bacl_exit_code generic_set_acl_on_os(JCR *jcr, acl_data_t *acl_data, bacl_type acltype, char *content, uint32_t content_length) { acl_t acl; acl_type_t ostype; /* * If we get empty default ACLs, clear ACLs now */ ostype = bac_to_os_acltype(acltype); if (ostype == ACL_TYPE_DEFAULT && strlen(content) == 0) { if (acl_delete_def_file(acl_data->last_fname) == 0) { return bacl_exit_ok; } berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; #if defined(BACL_ENOTSUP) case BACL_ENOTSUP: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; Mmsg1(jcr->errmsg, _("acl_delete_def_file error on file \"%s\": filesystem doesn't support ACLs\n"), acl_data->last_fname); return bacl_exit_error; #endif default: Mmsg2(jcr->errmsg, _("acl_delete_def_file error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } acl = acl_from_text(content); if (acl == NULL) { berrno be; Mmsg2(jcr->errmsg, _("acl_from_text error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "acl_from_text error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } /** * Only validate POSIX acls the acl_valid interface is only implemented * for checking POSIX acls on most platforms. */ switch (acltype) { case BACL_TYPE_NFS4: /* * Skip acl_valid tests on NFSv4 acls. */ break; default: if (acl_valid(acl) != 0) { berrno be; Mmsg2(jcr->errmsg, _("acl_valid error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "acl_valid error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); acl_free(acl); return bacl_exit_error; } break; } /** * Restore the ACLs, but don't complain about links which really should * not have attributes, and the file it is linked to may not yet be restored. * This is only true for the old acl streams as in the new implementation we * don't save acls of symlinks (which cannot have acls anyhow) */ if (acl_set_file(acl_data->last_fname, ostype, acl) != 0 && acl_data->filetype != FT_LNK) { berrno be; switch (errno) { case ENOENT: acl_free(acl); return bacl_exit_ok; #if defined(BACL_ENOTSUP) case BACL_ENOTSUP: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; Mmsg1(jcr->errmsg, _("acl_set_file error on file \"%s\": filesystem doesn't support ACLs\n"), acl_data->last_fname); Dmsg2(100, "acl_set_file error acl=%s file=%s filesystem doesn't support ACLs\n", content, acl_data->last_fname); acl_free(acl); return bacl_exit_error; #endif default: Mmsg2(jcr->errmsg, _("acl_set_file error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "acl_set_file error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); acl_free(acl); return bacl_exit_error; } } acl_free(acl); return bacl_exit_ok; } /** * OS specific functions for handling different types of acl streams. */ #if defined(HAVE_DARWIN_OS) /** * Define the supported ACL streams for this OS */ static int os_access_acl_streams[1] = { STREAM_ACL_DARWIN_ACCESS_ACL }; static int os_default_acl_streams[1] = { -1 }; static bacl_exit_code darwin_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { #if defined(HAVE_ACL_TYPE_EXTENDED) /** * On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS) * and acl_get_file (name, ACL_TYPE_DEFAULT) * always return NULL / EINVAL. There is no point in making * these two useless calls. The real ACL is retrieved through * acl_get_file (name, ACL_TYPE_EXTENDED). * * Read access ACLs for files, dirs and links */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_EXTENDED) == bacl_exit_fatal) return bacl_exit_fatal; #else /** * Read access ACLs for files, dirs and links */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_ACCESS) == bacl_exit_fatal) return bacl_exit_fatal; #endif if (acl_data->u.build->content_length > 0) { return send_acl_stream(jcr, acl_data, STREAM_ACL_DARWIN_ACCESS_ACL); } return bacl_exit_ok; } static bacl_exit_code darwin_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { #if defined(HAVE_ACL_TYPE_EXTENDED) return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_EXTENDED, content, content_length); #else return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_ACCESS, content, content_length); #endif } /* * For this OS setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = darwin_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = darwin_parse_acl_streams; #elif defined(HAVE_FREEBSD_OS) /* * Define the supported ACL streams for these OSes */ static int os_access_acl_streams[2] = { STREAM_ACL_FREEBSD_ACCESS_ACL, STREAM_ACL_FREEBSD_NFS4_ACL }; static int os_default_acl_streams[1] = { STREAM_ACL_FREEBSD_DEFAULT_ACL }; static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { int acl_enabled = 0; bacl_type acltype = BACL_TYPE_NONE; #if defined(_PC_ACL_NFS4) /* * See if filesystem supports NFS4 acls. */ acl_enabled = pathconf(acl_data->last_fname, _PC_ACL_NFS4); switch (acl_enabled) { case -1: { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "pathconf error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } case 0: break; default: acltype = BACL_TYPE_NFS4; break; } #endif if (acl_enabled == 0) { /* * See if filesystem supports POSIX acls. */ acl_enabled = pathconf(acl_data->last_fname, _PC_ACL_EXTENDED); switch (acl_enabled) { case -1: { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "pathconf error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } case 0: break; default: acltype = BACL_TYPE_ACCESS; break; } } /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_SAVE_NATIVE flag so we skip ACL saves on all other files * on the same filesystem. The BACL_FLAG_SAVE_NATIVE flag gets set again * when we change from one filesystem to an other. */ if (acl_enabled == 0) { acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; } /* * Based on the supported ACLs retrieve and store them. */ switch (acltype) { case BACL_TYPE_NFS4: /* * Read NFS4 ACLs for files, dirs and links */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_NFS4) == bacl_exit_fatal) return bacl_exit_fatal; if (acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, acl_data, STREAM_ACL_FREEBSD_NFS4_ACL) == bacl_exit_fatal) return bacl_exit_fatal; } break; case BACL_TYPE_ACCESS: /* * Read access ACLs for files, dirs and links */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_ACCESS) == bacl_exit_fatal) return bacl_exit_fatal; if (acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, acl_data, STREAM_ACL_FREEBSD_ACCESS_ACL) == bacl_exit_fatal) return bacl_exit_fatal; } /* * Directories can have default ACLs too */ if (acl_data->filetype == FT_DIREND) { if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_DEFAULT) == bacl_exit_fatal) return bacl_exit_fatal; if (acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, acl_data, STREAM_ACL_FREEBSD_DEFAULT_ACL) == bacl_exit_fatal) return bacl_exit_fatal; } } break; default: break; } return bacl_exit_ok; } static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { int acl_enabled = 0; const char *acl_type_name; /* * First make sure the filesystem supports acls. */ switch (stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: acl_enabled = pathconf(acl_data->last_fname, _PC_ACL_EXTENDED); acl_type_name = "POSIX"; break; case STREAM_ACL_FREEBSD_NFS4_ACL: #if defined(_PC_ACL_NFS4) acl_enabled = pathconf(acl_data->last_fname, _PC_ACL_NFS4); #endif acl_type_name = "NFS4"; break; default: acl_type_name = "unknown"; break; } switch (acl_enabled) { case -1: { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } case 0: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; Mmsg2(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without %s acl support\n"), acl_data->last_fname, acl_type_name); return bacl_exit_error; default: break; } /* * Restore the ACLs. */ switch (stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_ACCESS, content, content_length); case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_DEFAULT, content, content_length); case STREAM_ACL_FREEBSD_NFS4_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_NFS4, content, content_length); default: break; } return bacl_exit_error; } /* * For this OSes setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = freebsd_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = freebsd_parse_acl_streams; #elif defined(HAVE_IRIX_OS) || \ defined(HAVE_LINUX_OS) || \ defined(HAVE_HURD_OS) /* * Define the supported ACL streams for these OSes */ #if defined(HAVE_IRIX_OS) static int os_access_acl_streams[1] = { STREAM_ACL_IRIX_ACCESS_ACL }; static int os_default_acl_streams[1] = { STREAM_ACL_IRIX_DEFAULT_ACL }; #elif defined(HAVE_LINUX_OS) static int os_access_acl_streams[1] = { STREAM_ACL_LINUX_ACCESS_ACL }; static int os_default_acl_streams[1] = { STREAM_ACL_LINUX_DEFAULT_ACL }; #elif defined(HAVE_HURD_OS) static int os_access_acl_streams[1] = { STREAM_ACL_HURD_ACCESS_ACL }; static int os_default_acl_streams[1] = { STREAM_ACL_HURD_DEFAULT_ACL }; #endif static bacl_exit_code generic_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { /* * Read access ACLs for files, dirs and links */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_ACCESS) == bacl_exit_fatal) return bacl_exit_fatal; if (acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, acl_data, os_access_acl_streams[0]) == bacl_exit_fatal) return bacl_exit_fatal; } /* * Directories can have default ACLs too */ if (acl_data->filetype == FT_DIREND) { if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_DEFAULT) == bacl_exit_fatal) return bacl_exit_fatal; if (acl_data->u.build->content_length > 0) { if (send_acl_stream(jcr, acl_data, os_default_acl_streams[0]) == bacl_exit_fatal) return bacl_exit_fatal; } } return bacl_exit_ok; } static bacl_exit_code generic_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { unsigned int cnt; switch (stream) { case STREAM_UNIX_ACCESS_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_ACCESS, content, content_length); case STREAM_UNIX_DEFAULT_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_DEFAULT, content, content_length); default: /* * See what type of acl it is. */ for (cnt = 0; cnt < sizeof(os_access_acl_streams) / sizeof(int); cnt++) { if (os_access_acl_streams[cnt] == stream) { return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_ACCESS, content, content_length); } } for (cnt = 0; cnt < sizeof(os_default_acl_streams) / sizeof(int); cnt++) { if (os_default_acl_streams[cnt] == stream) { return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_DEFAULT, content, content_length); } } break; } return bacl_exit_error; } /* * For this OSes setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = generic_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = generic_parse_acl_streams; #elif defined(HAVE_OSF1_OS) /* * Define the supported ACL streams for this OS */ static int os_access_acl_streams[1] = { STREAM_ACL_TRU64_ACCESS_ACL }; static int os_default_acl_streams[2] = { STREAM_ACL_TRU64_DEFAULT_ACL, STREAM_ACL_TRU64_DEFAULT_DIR_ACL }; static bacl_exit_code tru64_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { /* * Read access ACLs for files, dirs and links */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_ACCESS) == bacl_exit_fatal) { return bacl_exit_error; if (acl_data->u.build->content_length > 0) { if (!send_acl_stream(jcr, acl_data, STREAM_ACL_TRU64_ACCESS_ACL)) return bacl_exit_error; } /* * Directories can have default ACLs too */ if (acl_data->filetype == FT_DIREND) { if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_DEFAULT) == bacl_exit_fatal) { return bacl_exit_error; if (acl_data->u.build->content_length > 0) { if (!send_acl_stream(jcr, acl_data, STREAM_ACL_TRU64_DEFAULT_ACL)) return bacl_exit_error; } /** * Tru64 has next to BACL_TYPE_DEFAULT also BACL_TYPE_DEFAULT_DIR acls. * This is an inherited acl for all subdirs. * See http://www.helsinki.fi/atk/unix/dec_manuals/DOC_40D/AQ0R2DTE/DOCU_018.HTM * Section 21.5 Default ACLs */ if (generic_get_acl_from_os(jcr, acl_data, BACL_TYPE_DEFAULT_DIR) == bacl_exit_fatal) { return bacl_exit_error; if (acl_data->u.build->content_length > 0) { if (!send_acl_stream(jcr, acl_data, STREAM_ACL_TRU64_DEFAULT_DIR_ACL)) return bacl_exit_error; } } return bacl_exit_ok; } static bacl_exit_code tru64_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { switch (stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_ACCESS, content, content_length); case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_DEFAULT, content, content_length); case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: return generic_set_acl_on_os(jcr, acl_data, BACL_TYPE_DEFAULT_DIR, content, content_length); } /* * For this OS setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = tru64_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = tru64_parse_acl_streams; #endif #elif defined(HAVE_HPUX_OS) #ifdef HAVE_SYS_ACL_H #include #else #error "configure failed to detect availability of sys/acl.h" #endif #include /* * Define the supported ACL streams for this OS */ static int os_access_acl_streams[1] = { STREAM_ACL_HPUX_ACL_ENTRY }; static int os_default_acl_streams[1] = { -1 }; /* * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.) * There is no need to store those acls as we already store the stat bits too. */ static bool acl_is_trivial(int count, struct acl_entry *entries, struct stat sb) { int n; struct acl_entry ace for (n = 0; n < count; n++) { ace = entries[n]; /* * See if this acl just is the stat mode in acl form. */ if (!((ace.uid == sb.st_uid && ace.gid == ACL_NSGROUP) || (ace.uid == ACL_NSUSER && ace.gid == sb.st_gid) || (ace.uid == ACL_NSUSER && ace.gid == ACL_NSGROUP))) return false; } return true; } /* * OS specific functions for handling different types of acl streams. */ static bacl_exit_code hpux_build_acl_streams(JCR *jcr, acl_data_t *acl_data FF_PKT *ff_pkt) { int n; struct acl_entry acls[NACLENTRIES]; char *acl_text; if ((n = getacl(acl_data->last_fname, 0, acls)) < 0) { berrno be; switch (errno) { #if defined(BACL_ENOTSUP) case BACL_ENOTSUP: /* * Not supported, just pretend there is nothing to see * * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_SAVE_NATIVE flag so we skip ACL saves on all other files * on the same filesystem. The BACL_FLAG_SAVE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; #endif case ENOENT: pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("getacl error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "getacl error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_error; } } if (n == 0) { pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; } if ((n = getacl(acl_data->last_fname, n, acls)) > 0) { if (acl_is_trivial(n, acls, ff_pkt->statp)) { /* * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; } if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) { acl_data->u.build->content_length = pm_strcpy(acl_data->u.build->content, acl_text); actuallyfree(acl_text); return send_acl_stream(jcr, acl_data, STREAM_ACL_HPUX_ACL_ENTRY); } berrno be; Mmsg2(jcr->errmsg, _("acltostr error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "acltostr error acl=%s file=%s ERR=%s\n", acl_data->u.build->content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } return bacl_exit_error; } static bacl_exit_code hpux_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { int n; struct acl_entry acls[NACLENTRIES]; n = strtoacl(content, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); if (n <= 0) { berrno be; Mmsg2(jcr->errmsg, _("strtoacl error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } if (strtoacl(content, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) { berrno be; Mmsg2(jcr->errmsg, _("strtoacl error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } /** * Restore the ACLs, but don't complain about links which really should * not have attributes, and the file it is linked to may not yet be restored. * This is only true for the old acl streams as in the new implementation we * don't save acls of symlinks (which cannot have acls anyhow) */ if (setacl(acl_data->last_fname, n, acls) != 0 && acl_data->filetype != FT_LNK) { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; #if defined(BACL_ENOTSUP) case BACL_ENOTSUP: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; Mmsg1(jcr->errmsg, _("setacl error on file \"%s\": filesystem doesn't support ACLs\n"), acl_data->last_fname); Dmsg2(100, "setacl error acl=%s file=%s filesystem doesn't support ACLs\n", content, acl_data->last_fname); return bacl_exit_error; #endif default: Mmsg2(jcr->errmsg, _("setacl error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "setacl error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } return bacl_exit_ok; } /* * For this OS setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = hpux_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = hpux_parse_acl_streams; #elif defined(HAVE_SUN_OS) #ifdef HAVE_SYS_ACL_H #include #else #error "configure failed to detect availability of sys/acl.h" #endif #if defined(HAVE_EXTENDED_ACL) /** * We define some internals of the Solaris acl libs here as those * are not exposed yet. Probably because they want us to see the * acls as opague data. But as we need to support different platforms * and versions of Solaris we need to expose some data to be able * to determine the type of acl used to stuff it into the correct * data stream. I know this is far from portable, but maybe the * proper interface is exposed later on and we can get ride of * this kludge. Newer versions of Solaris include sys/acl_impl.h * which has implementation details of acls, if thats included we * don't have to define it ourself. */ #if !defined(_SYS_ACL_IMPL_H) typedef enum acl_type { ACLENT_T = 0, ACE_T = 1 } acl_type_t; #endif /** * Two external references to functions in the libsec library function not in current include files. */ extern "C" { int acl_type(acl_t *); char *acl_strerror(int); } /* * Define the supported ACL streams for this OS */ static int os_access_acl_streams[2] = { STREAM_ACL_SOLARIS_ACLENT, STREAM_ACL_SOLARIS_ACE }; static int os_default_acl_streams[1] = { -1 }; /** * As the new libsec interface with acl_totext and acl_fromtext also handles * the old format from acltotext we can use the new functions even * for acls retrieved and stored in the database with older fd versions. If the * new interface is not defined (Solaris 9 and older we fall back to the old code) */ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { int acl_enabled, flags; acl_t *aclp; char *acl_text; bacl_exit_code stream_status = bacl_exit_error; /* * See if filesystem supports acls. */ acl_enabled = pathconf(acl_data->last_fname, _PC_ACL_ENABLED); switch (acl_enabled) { case 0: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_SAVE_NATIVE flag so we skip ACL saves on all other files * on the same filesystem. The BACL_FLAG_SAVE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; case -1: { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "pathconf error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } default: break; } /* * Get ACL info: don't bother allocating space if there is only a trivial ACL. */ if (acl_get(acl_data->last_fname, ACL_NO_TRIVIAL, &aclp) != 0) { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("acl_get error on file \"%s\": ERR=%s\n"), acl_data->last_fname, acl_strerror(errno)); Dmsg2(100, "acl_get error file=%s ERR=%s\n", acl_data->last_fname, acl_strerror(errno)); return bacl_exit_error; } } if (!aclp) { /* * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; } #if defined(ACL_SID_FMT) /* * New format flag added in newer Solaris versions. */ flags = ACL_APPEND_ID | ACL_COMPACT_FMT | ACL_SID_FMT; #else flags = ACL_APPEND_ID | ACL_COMPACT_FMT; #endif /* ACL_SID_FMT */ if ((acl_text = acl_totext(aclp, flags)) != NULL) { acl_data->u.build->content_length = pm_strcpy(acl_data->u.build->content, acl_text); actuallyfree(acl_text); switch (acl_type(aclp)) { case ACLENT_T: stream_status = send_acl_stream(jcr, acl_data, STREAM_ACL_SOLARIS_ACLENT); break; case ACE_T: stream_status = send_acl_stream(jcr, acl_data, STREAM_ACL_SOLARIS_ACE); break; default: break; } acl_free(aclp); } return stream_status; } static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { acl_t *aclp; int acl_enabled, error; switch (stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: /* * First make sure the filesystem supports acls. */ acl_enabled = pathconf(acl_data->last_fname, _PC_ACL_ENABLED); switch (acl_enabled) { case 0: /* * If the filesystem reports it doesn't support ACLs we clear the * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again * when we change from one filesystem to an other. */ acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; Mmsg1(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without acl support\n"), acl_data->last_fname); return bacl_exit_error; case -1: { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("pathconf error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } } default: /* * On a filesystem with ACL support make sure this particular ACL type can be restored. */ switch (stream) { case STREAM_ACL_SOLARIS_ACLENT: /* * An aclent can be restored on filesystems with _ACL_ACLENT_ENABLED or _ACL_ACE_ENABLED support. */ if ((acl_enabled & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED)) == 0) { Mmsg1(jcr->errmsg, _("Trying to restore POSIX acl on file \"%s\" on filesystem without aclent acl support\n"), acl_data->last_fname); return bacl_exit_error; } break; case STREAM_ACL_SOLARIS_ACE: /* * An ace can only be restored on a filesystem with _ACL_ACE_ENABLED support. */ if ((acl_enabled & _ACL_ACE_ENABLED) == 0) { Mmsg1(jcr->errmsg, _("Trying to restore NFSv4 acl on file \"%s\" on filesystem without ace acl support\n"), acl_data->last_fname); return bacl_exit_error; } break; default: /* * Stream id which doesn't describe the type of acl which is encoded. */ break; } break; } if ((error = acl_fromtext(content, &aclp)) != 0) { Mmsg2(jcr->errmsg, _("acl_fromtext error on file \"%s\": ERR=%s\n"), acl_data->last_fname, acl_strerror(error)); Dmsg3(100, "acl_fromtext error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, acl_strerror(error)); return bacl_exit_error; } /* * Validate that the conversion gave us the correct acl type. */ switch (stream) { case STREAM_ACL_SOLARIS_ACLENT: if (acl_type(aclp) != ACLENT_T) { Mmsg1(jcr->errmsg, _("wrong encoding of acl type in acl stream on file \"%s\"\n"), acl_data->last_fname); return bacl_exit_error; } break; case STREAM_ACL_SOLARIS_ACE: if (acl_type(aclp) != ACE_T) { Mmsg1(jcr->errmsg, _("wrong encoding of acl type in acl stream on file \"%s\"\n"), acl_data->last_fname); return bacl_exit_error; } break; default: /* * Stream id which doesn't describe the type of acl which is encoded. */ break; } /** * Restore the ACLs, but don't complain about links which really should * not have attributes, and the file it is linked to may not yet be restored. * This is only true for the old acl streams as in the new implementation we * don't save acls of symlinks (which cannot have acls anyhow) */ if ((error = acl_set(acl_data->last_fname, aclp)) == -1 && acl_data->filetype != FT_LNK) { switch (errno) { case ENOENT: acl_free(aclp); return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("acl_set error on file \"%s\": ERR=%s\n"), acl_data->last_fname, acl_strerror(error)); Dmsg3(100, "acl_set error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, acl_strerror(error)); acl_free(aclp); return bacl_exit_error; } } acl_free(aclp); return bacl_exit_ok; default: return bacl_exit_error; } /* end switch (stream) */ } #else /* HAVE_EXTENDED_ACL */ /* * Define the supported ACL streams for this OS */ static int os_access_acl_streams[1] = { STREAM_ACL_SOLARIS_ACLENT }; static int os_default_acl_streams[1] = { -1 }; /* * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.) * There is no need to store those acls as we already store the stat bits too. */ static bool acl_is_trivial(int count, aclent_t *entries) { int n; aclent_t *ace; for (n = 0; n < count; n++) { ace = &entries[n]; if (!(ace->a_type == USER_OBJ || ace->a_type == GROUP_OBJ || ace->a_type == OTHER_OBJ || ace->a_type == CLASS_OBJ)) return false; } return true; } /* * OS specific functions for handling different types of acl streams. */ static bacl_exit_code solaris_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { int n; aclent_t *acls; char *acl_text; n = acl(acl_data->last_fname, GETACLCNT, 0, NULL); if (n < MIN_ACL_ENTRIES) { return bacl_exit_error; } acls = (aclent_t *)malloc(n * sizeof(aclent_t)); if (acl(acl_data->last_fname, GETACL, n, acls) == n) { if (acl_is_trivial(n, acls)) { /* * The ACLs simply reflect the (already known) standard permissions * So we don't send an ACL stream to the SD. */ free(acls); pm_strcpy(acl_data->u.build->content, ""); acl_data->u.build->content_length = 0; return bacl_exit_ok; } if ((acl_text = acltotext(acls, n)) != NULL) { acl_data->u.build->content_length = pm_strcpy(acl_data->u.build->content, acl_text); actuallyfree(acl_text); free(acls); return send_acl_stream(jcr, acl_data, STREAM_ACL_SOLARIS_ACLENT); } berrno be; Mmsg2(jcr->errmsg, _("acltotext error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "acltotext error acl=%s file=%s ERR=%s\n", acl_data->u.build->content, acl_data->last_fname, be.bstrerror()); } free(acls); return bacl_exit_error; } static bacl_exit_code solaris_parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { int n; aclent_t *acls; acls = aclfromtext(content, &n); if (!acls) { berrno be; Mmsg2(jcr->errmsg, _("aclfromtext error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "aclfromtext error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } /* * Restore the ACLs, but don't complain about links which really should * not have attributes, and the file it is linked to may not yet be restored. */ if (acl(acl_data->last_fname, SETACL, n, acls) == -1 && acl_data->filetype != FT_LNK) { berrno be; switch (errno) { case ENOENT: actuallyfree(acls); return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("acl(SETACL) error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg3(100, "acl(SETACL) error acl=%s file=%s ERR=%s\n", content, acl_data->last_fname, be.bstrerror()); actuallyfree(acls); return bacl_exit_error; } } actuallyfree(acls); return bacl_exit_ok; } #endif /* HAVE_EXTENDED_ACL */ /* * For this OS setup the build and parse function pointer to the OS specific functions. */ static bacl_exit_code (*os_build_acl_streams) (JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) = solaris_build_acl_streams; static bacl_exit_code (*os_parse_acl_streams) (JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) = solaris_parse_acl_streams; #endif /* HAVE_SUN_OS */ #endif /* HAVE_ACL */ #if defined(HAVE_AFS_ACL) #if defined(HAVE_AFS_AFSINT_H) && defined(HAVE_AFS_VENUS_H) #include #include #else #error "configure failed to detect availability of afs/afsint.h and/or afs/venus.h" #endif /** * External references to functions in the libsys library function not in current include files. */ extern "C" { long pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow); } static bacl_exit_code afs_build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { int error; struct ViceIoctl vip; char acl_text[BUFSIZ]; /* * AFS ACLs can only be set on a directory, so no need to try to * request them for anything other then that. */ if (ff_pkt->type != FT_DIREND) { return bacl_exit_ok; } vip.in = NULL; vip.in_size = 0; vip.out = acl_text; vip.out_size = sizeof(acl_text); memset((caddr_t)acl_text, 0, sizeof(acl_text)); if ((error = pioctl(acl_data->last_fname, VIOCGETAL, &vip, 0)) < 0) { berrno be; Mmsg2(jcr->errmsg, _("pioctl VIOCGETAL error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "pioctl VIOCGETAL error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } acl_data->u.build->content_length = pm_strcpy(acl_data->u.build->content, acl_text); return send_acl_stream(jcr, acl_data, STREAM_ACL_AFS_TEXT); } static bacl_exit_code afs_parse_acl_stream(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { int error; struct ViceIoctl vip; vip.in = content; vip.in_size = content_length; vip.out = NULL; vip.out_size = 0; if ((error = pioctl(acl_data->last_fname, VIOCSETAL, &vip, 0)) < 0) { berrno be; Mmsg2(jcr->errmsg, _("pioctl VIOCSETAL error on file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "pioctl VIOCSETAL error file=%s ERR=%s\n", acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } return bacl_exit_ok; } #endif /* HAVE_AFS_ACL */ /** * Entry points when compiled with support for ACLs on a supported platform. */ /** * Read and send an ACL for the last encountered file. */ bacl_exit_code build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt) { /* * See if we are changing from one device to an other. * We save the current device we are scanning and compare * it with the current st_dev in the last stat performed on * the file we are currently storing. */ if (acl_data->current_dev != ff_pkt->statp.st_dev) { /* * Reset the acl save flags. */ acl_data->flags = 0; #if defined(HAVE_AFS_ACL) /* * AFS is a non OS specific filesystem so see if this path is on an AFS filesystem * Set the BACL_FLAG_SAVE_AFS flag if it is. If not set the BACL_FLAG_SAVE_NATIVE flag. */ if (fstype_equals(acl_data->last_fname, "afs")) { acl_data->flags |= BACL_FLAG_SAVE_AFS; } else { acl_data->flags |= BACL_FLAG_SAVE_NATIVE; } #else acl_data->flags |= BACL_FLAG_SAVE_NATIVE; #endif /* * Save that we started scanning a new filesystem. */ acl_data->current_dev = ff_pkt->statp.st_dev; } #if defined(HAVE_AFS_ACL) /* * See if the BACL_FLAG_SAVE_AFS flag is set which lets us know if we should * save AFS ACLs. */ if (acl_data->flags & BACL_FLAG_SAVE_AFS) { return afs_build_acl_streams(jcr, acl_data, ff_pkt); } #endif #if defined(HAVE_ACL) /* * See if the BACL_FLAG_SAVE_NATIVE flag is set which lets us know if we should * save native ACLs. */ if (acl_data->flags & BACL_FLAG_SAVE_NATIVE) { /* * Call the appropriate function. */ if (os_build_acl_streams) { return os_build_acl_streams(jcr, acl_data, ff_pkt); } } else { return bacl_exit_ok; } #endif return bacl_exit_error; } bacl_exit_code parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length) { int ret; struct stat st; unsigned int cnt; /* * See if we are changing from one device to an other. * We save the current device we are restoring to and compare * it with the current st_dev in the last stat performed on * the file we are currently restoring. */ ret = lstat(acl_data->last_fname, &st); switch (ret) { case -1: { berrno be; switch (errno) { case ENOENT: return bacl_exit_ok; default: Mmsg2(jcr->errmsg, _("Unable to stat file \"%s\": ERR=%s\n"), acl_data->last_fname, be.bstrerror()); Dmsg2(100, "Unable to stat file \"%s\": ERR=%s\n", acl_data->last_fname, be.bstrerror()); return bacl_exit_error; } break; } case 0: break; } if (acl_data->current_dev != st.st_dev) { /* * Reset the acl save flags. */ acl_data->flags = 0; #if defined(HAVE_AFS_ACL) /* * AFS is a non OS specific filesystem so see if this path is on an AFS filesystem * Set the BACL_FLAG_RESTORE_AFS flag if it is. If not set the BACL_FLAG_RETORE_NATIVE flag. */ if (fstype_equals(acl_data->last_fname, "afs")) { acl_data->flags |= BACL_FLAG_RESTORE_AFS; } else { acl_data->flags |= BACL_FLAG_RESTORE_NATIVE; } #else acl_data->flags |= BACL_FLAG_RESTORE_NATIVE; #endif /* * Save that we started restoring to a new filesystem. */ acl_data->current_dev = st.st_dev; } switch (stream) { #if defined(HAVE_AFS_ACL) case STREAM_ACL_AFS_TEXT: if (acl_data->flags & BACL_FLAG_RESTORE_AFS) { return afs_parse_acl_stream(jcr, acl_data, stream, content, content_length); } else { /* * Increment error count but don't log an error again for the same filesystem. */ acl_data->u.parse->nr_errors++; return bacl_exit_ok; } #endif #if defined(HAVE_ACL) case STREAM_UNIX_ACCESS_ACL: case STREAM_UNIX_DEFAULT_ACL: /* * Handle legacy ACL streams. */ if ((acl_data->flags & BACL_FLAG_RESTORE_NATIVE) && os_parse_acl_streams) { return os_parse_acl_streams(jcr, acl_data, stream, content, content_length); } else { /* * Increment error count but don't log an error again for the same filesystem. */ acl_data->u.parse->nr_errors++; return bacl_exit_ok; } break; default: if ((acl_data->flags & BACL_FLAG_RESTORE_NATIVE) && os_parse_acl_streams) { /* * Walk the os_access_acl_streams array with the supported Access ACL streams for this OS. */ for (cnt = 0; cnt < sizeof(os_access_acl_streams) / sizeof(int); cnt++) { if (os_access_acl_streams[cnt] == stream) { return os_parse_acl_streams(jcr, acl_data, stream, content, content_length); } } /* * Walk the os_default_acl_streams array with the supported Default ACL streams for this OS. */ for (cnt = 0; cnt < sizeof(os_default_acl_streams) / sizeof(int); cnt++) { if (os_default_acl_streams[cnt] == stream) { return os_parse_acl_streams(jcr, acl_data, stream, content, content_length); } } } else { /* * Increment error count but don't log an error again for the same filesystem. */ acl_data->u.parse->nr_errors++; return bacl_exit_ok; } break; #else default: break; #endif } Qmsg2(jcr, M_WARNING, 0, _("Can't restore ACLs of %s - incompatible acl stream encountered - %d\n"), acl_data->last_fname, stream); return bacl_exit_error; } #endif bareos-Release-14.2.6/src/findlib/acl.h000066400000000000000000000052611263011562700175520ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Properties we use for getting and setting ACLs. */ #ifndef __ACL_H #define __ACL_H /* * * Number of acl errors to report per job. * */ #define ACL_REPORT_ERR_MAX_PER_JOB 25 /* * * Return codes from acl subroutines. * */ typedef enum { bacl_exit_fatal = -1, bacl_exit_error = 0, bacl_exit_ok = 1 } bacl_exit_code; /* For shorter ACL strings when possible, define BACL_WANT_SHORT_ACLS */ /* #define BACL_WANT_SHORT_ACLS */ /* For numeric user/group ids when possible, define BACL_WANT_NUMERIC_IDS */ /* #define BACL_WANT_NUMERIC_IDS */ /* * We support the following types of ACLs */ typedef enum { BACL_TYPE_NONE = 0, BACL_TYPE_ACCESS = 1, BACL_TYPE_DEFAULT = 2, BACL_TYPE_DEFAULT_DIR = 3, BACL_TYPE_EXTENDED = 4, BACL_TYPE_NFS4 = 5 } bacl_type; /* * This value is used as ostype when we encounter an invalid acl type. * The way the code is build this should never happen. */ #if !defined(ACL_TYPE_NONE) #define ACL_TYPE_NONE 0x0 #endif #if defined(HAVE_FREEBSD_OS) || \ defined(HAVE_DARWIN_OS) || \ defined(HAVE_HPUX_OS) || \ defined(HAVE_LINUX_OS) #define BACL_ENOTSUP EOPNOTSUPP #elif defined(HAVE_IRIX_OS) #define BACL_ENOTSUP ENOSYS #endif #define BACL_FLAG_SAVE_NATIVE 0x01 #define BACL_FLAG_SAVE_AFS 0x02 #define BACL_FLAG_RESTORE_NATIVE 0x04 #define BACL_FLAG_RESTORE_AFS 0x08 struct acl_build_data_t { uint32_t nr_errors; uint32_t content_length; POOLMEM *content; }; struct acl_parse_data_t { uint32_t nr_errors; }; /* * Internal tracking data. */ struct acl_data_t { int filetype; POOLMEM *last_fname; uint32_t flags; /* See BACL_FLAG_* */ uint32_t current_dev; union { struct acl_build_data_t *build; struct acl_parse_data_t *parse; } u; }; #endif bareos-Release-14.2.6/src/findlib/attribs.c000066400000000000000000000523541263011562700204630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Encode and decode Extended attributes for Win32 and * other non-Unix systems, or Unix systems with ACLs, ... * * Kern Sibbald, October MMII */ #include "bareos.h" #include "find.h" #include "ch.h" static uid_t my_uid = 1; static gid_t my_gid = 1; static bool uid_set = false; #if defined(HAVE_WIN32) /* Imported Functions */ extern void unix_name_to_win32(POOLMEM **win32_name, const char *name); /* Forward referenced subroutines */ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd); void win_error(JCR *jcr, const char *prefix, POOLMEM *ofile); #endif /* HAVE_WIN32 */ /* * For old systems that don't have lchown() use chown() */ #ifndef HAVE_LCHOWN #define lchown chown #endif /* * For old systems that don't have lchmod() use chmod() */ #ifndef HAVE_LCHMOD #define lchmod chmod #endif /*=============================================================*/ /* */ /* *** A l l S y s t e m s *** */ /* */ /*=============================================================*/ /** * Return the data stream that will be used */ int select_data_stream(FF_PKT *ff_pkt, bool compatible) { int stream; /* This is a plugin special restore object */ if (ff_pkt->type == FT_RESTORE_FIRST) { clear_all_bits(FO_MAX, ff_pkt->flags); return STREAM_FILE_DATA; } /* * Fix all incompatible options */ /** * No sparse option for encrypted data */ if (bit_is_set(FO_ENCRYPT, ff_pkt->flags)) { clear_bit(FO_SPARSE, ff_pkt->flags); } /* * Note, no sparse option for win32_data */ if (!is_portable_backup(&ff_pkt->bfd)) { stream = STREAM_WIN32_DATA; clear_bit(FO_SPARSE, ff_pkt->flags); } else if (bit_is_set(FO_SPARSE, ff_pkt->flags)) { stream = STREAM_SPARSE_DATA; } else { stream = STREAM_FILE_DATA; } if (bit_is_set(FO_OFFSETS, ff_pkt->flags)) { stream = STREAM_SPARSE_DATA; } /* * Encryption is only supported for file data */ if (stream != STREAM_FILE_DATA && stream != STREAM_WIN32_DATA && stream != STREAM_MACOS_FORK_DATA) { clear_bit(FO_ENCRYPT, ff_pkt->flags); } /* * Compression is not supported for Mac fork data */ if (stream == STREAM_MACOS_FORK_DATA) { clear_bit(FO_COMPRESS, ff_pkt->flags); } /* * Handle compression and encryption options */ if (bit_is_set(FO_COMPRESS, ff_pkt->flags)) { if (compatible && ff_pkt->Compress_algo == COMPRESS_GZIP) { switch (stream) { case STREAM_WIN32_DATA: stream = STREAM_WIN32_GZIP_DATA; break; case STREAM_SPARSE_DATA: stream = STREAM_SPARSE_GZIP_DATA; break; case STREAM_FILE_DATA: stream = STREAM_GZIP_DATA; break; default: /** * All stream types that do not support compression should clear out * FO_COMPRESS above, and this code block should be unreachable. */ ASSERT(!bit_is_set(FO_COMPRESS, ff_pkt->flags)); return STREAM_NONE; } } else { switch (stream) { case STREAM_WIN32_DATA: stream = STREAM_WIN32_COMPRESSED_DATA; break; case STREAM_SPARSE_DATA: stream = STREAM_SPARSE_COMPRESSED_DATA; break; case STREAM_FILE_DATA: stream = STREAM_COMPRESSED_DATA; break; default: /* * All stream types that do not support compression should clear out * FO_COMPRESS above, and this code block should be unreachable. */ ASSERT(!bit_is_set(FO_COMPRESS, ff_pkt->flags)); return STREAM_NONE; } } } #ifdef HAVE_CRYPTO if (bit_is_set(FO_ENCRYPT, ff_pkt->flags)) { switch (stream) { case STREAM_WIN32_DATA: stream = STREAM_ENCRYPTED_WIN32_DATA; break; case STREAM_WIN32_GZIP_DATA: stream = STREAM_ENCRYPTED_WIN32_GZIP_DATA; break; case STREAM_WIN32_COMPRESSED_DATA: stream = STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA; break; case STREAM_FILE_DATA: stream = STREAM_ENCRYPTED_FILE_DATA; break; case STREAM_GZIP_DATA: stream = STREAM_ENCRYPTED_FILE_GZIP_DATA; break; case STREAM_COMPRESSED_DATA: stream = STREAM_ENCRYPTED_FILE_COMPRESSED_DATA; break; default: /* * All stream types that do not support encryption should clear out * FO_ENCRYPT above, and this code block should be unreachable. */ ASSERT(!bit_is_set(FO_ENCRYPT, ff_pkt->flags)); return STREAM_NONE; } } #endif return stream; } /* * Restore all file attributes like owner, mode and file times. */ static inline bool restore_file_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { bool ok = true; bool suppress_errors; #if defined(HAVE_FCHOWN) || defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(FUTIMENS) bool file_is_open; /* * Save if we are working on an open file. */ file_is_open = is_bopen(ofd); #endif /* * See if we want to print errors. */ suppress_errors = (debug_level >= 100 || my_uid != 0); /* * Restore owner and group. */ #ifdef HAVE_FCHOWN if (file_is_open) { if (fchown(ofd->fid, attr->statp.st_uid, attr->statp.st_gid) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } } else { #else { #endif if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } } /* * Restore filemode. */ #ifdef HAVE_FCHMOD if (file_is_open) { if (fchmod(ofd->fid, attr->statp.st_mode) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } } else { #else { #endif #if defined(HAVE_WIN32) if (win32_chmod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) < 0 && !suppress_errors) { #else if (lchmod(attr->ofname, attr->statp.st_mode) < 0 && !suppress_errors) { #endif berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } } /* * Reset file times. */ #if defined(HAVE_FUTIMES) if (file_is_open) { struct timeval restore_times[2]; restore_times[0].tv_sec = attr->statp.st_atime; restore_times[0].tv_usec = 0; restore_times[1].tv_sec = attr->statp.st_mtime; restore_times[1].tv_usec = 0; if (futimes(ofd->fid, restore_times) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } } else { #elif defined(HAVE_FUTIMENS) if (file_is_open) { struct timespec restore_times[2]; restore_times[0].tv_sec = attr->statp.st_atime; restore_times[0].tv_nsec = 0; restore_times[1].tv_sec = attr->statp.st_mtime; restore_times[1].tv_nsec = 0; if (futimens(ofd->fid, restore_times) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } } else { #else { #endif #if defined(HAVE_LUTIMES) struct timeval restore_times[2]; restore_times[0].tv_sec = attr->statp.st_atime; restore_times[0].tv_usec = 0; restore_times[1].tv_sec = attr->statp.st_mtime; restore_times[1].tv_usec = 0; if (lutimes(attr->ofname, restore_times) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } #elif defined(HAVE_UTIMES) struct timeval restore_times[2]; restore_times[0].tv_sec = attr->statp.st_atime; restore_times[0].tv_usec = 0; restore_times[1].tv_sec = attr->statp.st_mtime; restore_times[1].tv_usec = 0; if (utimes(attr->ofname, restore_times) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } #else struct utimbuf restore_times; restore_times.actime = attr->statp.st_atime; restore_times.modtime = attr->statp.st_mtime; if (utime(attr->ofname, &restore_times) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } #endif /* HAVE_LUTIMES */ } return ok; } /** * Set file modes, permissions and times * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: true on success * false on failure */ bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { mode_t old_mask; bool ok = true; bool suppress_errors; if (uid_set) { my_uid = getuid(); my_gid = getgid(); uid_set = true; } /* * See if we want to print errors. */ suppress_errors = (debug_level >= 100 || my_uid != 0); #if defined(HAVE_WIN32) if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX && set_win32_attributes(jcr, attr, ofd)) { if (is_bopen(ofd)) { bclose(ofd); } pm_strcpy(attr->ofname, "*none*"); return true; } if (attr->data_stream == STREAM_WIN32_DATA || attr->data_stream == STREAM_WIN32_GZIP_DATA || attr->data_stream == STREAM_WIN32_COMPRESSED_DATA) { if (is_bopen(ofd)) { bclose(ofd); } pm_strcpy(attr->ofname, "*none*"); return true; } /** * If Windows stuff failed, e.g. attempt to restore Unix file to Windows, simply fall * through and we will do it the universal way. */ #endif old_mask = umask(0); if (is_bopen(ofd)) { boffset_t fsize; char ec1[50], ec2[50]; fsize = blseek(ofd, 0, SEEK_END); if (attr->type == FT_REG && fsize > 0 && attr->statp.st_size > 0 && fsize != (boffset_t)attr->statp.st_size) { Jmsg3(jcr, M_ERROR, 0, _("File size of restored file %s not correct. Original %s, restored %s.\n"), attr->ofname, edit_uint64(attr->statp.st_size, ec1), edit_uint64(fsize, ec2)); } } else { struct stat st; char ec1[50], ec2[50]; if (lstat(attr->ofname, &st) == 0) { if (attr->type == FT_REG && st.st_size > 0 && attr->statp.st_size > 0 && st.st_size != attr->statp.st_size) { Jmsg3(jcr, M_ERROR, 0, _("File size of restored file %s not correct. Original %s, restored %s.\n"), attr->ofname, edit_uint64(attr->statp.st_size, ec1), edit_uint64(st.st_size, ec2)); } } } /** * We do not restore sockets, so skip trying to restore their attributes. */ if (attr->type == FT_SPEC && S_ISSOCK(attr->statp.st_mode)) { goto bail_out; } /* ***FIXME**** optimize -- don't do if already correct */ /** * For link, change owner of link using lchown, but don't try to do a chmod as that will update the file behind it. */ if (attr->type == FT_LNK) { /* * Change owner of link, not of real file */ if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } #ifdef HAVE_LCHMOD if (lchmod(attr->ofname, attr->statp.st_mode) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } #endif } else { if (!ofd->cmd_plugin) { ok = restore_file_attributes(jcr, attr, ofd); #ifdef HAVE_CHFLAGS /** * FreeBSD user flags * * Note, this should really be done before the utime() above, * but if the immutable bit is set, it will make the utimes() * fail. */ if (chflags(attr->ofname, attr->statp.st_flags) < 0 && !suppress_errors) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to set file flags %s: ERR=%s\n"), attr->ofname, be.bstrerror()); ok = false; } #endif } } bail_out: if (is_bopen(ofd)) { bclose(ofd); } pm_strcpy(attr->ofname, "*none*"); umask(old_mask); return ok; } #if !defined(HAVE_WIN32) /*=============================================================*/ /* */ /* * * * U n i x * * * * */ /* */ /*=============================================================*/ /** * It is possible to piggyback additional data e.g. ACLs on * the encode_stat() data by returning the extended attributes * here. They must be "self-contained" (i.e. you keep track * of your own length), and they must be in ASCII string * format. Using this feature is not recommended. * The code below shows how to return nothing. See the Win32 * code below for returning something in the attributes. */ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt) { #ifdef HAVE_DARWIN_OS /** * We save the Mac resource fork length so that on a * restore, we can be sure we put back the whole resource. */ char *p; *attribsEx = 0; /* no extended attributes (yet) */ if (jcr->cmd_plugin || ff_pkt->type == FT_DELETED) { return STREAM_UNIX_ATTRIBUTES; } p = attribsEx; if (bit_is_set(FO_HFSPLUS, ff_pkt->flags)) { p += to_base64((uint64_t)(ff_pkt->hfsinfo.rsrclength), p); } *p = 0; #else *attribsEx = 0; /* no extended attributes */ #endif return STREAM_UNIX_ATTRIBUTES; } #else /*=============================================================*/ /* */ /* * * * W i n 3 2 * * * * */ /* */ /*=============================================================*/ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt) { char *p = attribsEx; WIN32_FILE_ATTRIBUTE_DATA atts; ULARGE_INTEGER li; attribsEx[0] = 0; /* no extended attributes */ if (jcr->cmd_plugin || ff_pkt->type == FT_DELETED) { return STREAM_UNIX_ATTRIBUTES; } unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname); if (p_GetFileAttributesExW) { /** * Try unicode version */ POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, ff_pkt->fname); BOOL b=p_GetFileAttributesExW((LPCWSTR)pwszBuf, GetFileExInfoStandard, (LPVOID)&atts); free_pool_memory(pwszBuf); if (!b) { win_error(jcr, "GetFileAttributesExW:", ff_pkt->sys_fname); return STREAM_UNIX_ATTRIBUTES; } } else { if (!p_GetFileAttributesExA) return STREAM_UNIX_ATTRIBUTES; if (!p_GetFileAttributesExA(ff_pkt->sys_fname, GetFileExInfoStandard, (LPVOID)&atts)) { win_error(jcr, "GetFileAttributesExA:", ff_pkt->sys_fname); return STREAM_UNIX_ATTRIBUTES; } } /* * Instead of using the current dwFileAttributes use the * ff_pkt->statp.st_rdev which contains the actual fileattributes we * want to save for this file. */ atts.dwFileAttributes = ff_pkt->statp.st_rdev; p += to_base64((uint64_t)atts.dwFileAttributes, p); *p++ = ' '; /* separate fields with a space */ li.LowPart = atts.ftCreationTime.dwLowDateTime; li.HighPart = atts.ftCreationTime.dwHighDateTime; p += to_base64((uint64_t)li.QuadPart, p); *p++ = ' '; li.LowPart = atts.ftLastAccessTime.dwLowDateTime; li.HighPart = atts.ftLastAccessTime.dwHighDateTime; p += to_base64((uint64_t)li.QuadPart, p); *p++ = ' '; li.LowPart = atts.ftLastWriteTime.dwLowDateTime; li.HighPart = atts.ftLastWriteTime.dwHighDateTime; p += to_base64((uint64_t)li.QuadPart, p); *p++ = ' '; p += to_base64((uint64_t)atts.nFileSizeHigh, p); *p++ = ' '; p += to_base64((uint64_t)atts.nFileSizeLow, p); *p = 0; return STREAM_UNIX_ATTRIBUTES_EX; } /* * Do casting according to unknown type to keep compiler happy */ #ifdef HAVE_TYPEOF #define plug(st, val) st = (typeof st)val #else /* * Use templates to do the casting */ template void plug(T &st, uint64_t val) { st = static_cast(val); } #endif /** * Set Extended File Attributes for Win32 * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: true on success * false on failure */ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { char *p = attr->attrEx; int64_t val; WIN32_FILE_ATTRIBUTE_DATA atts; ULARGE_INTEGER li; /** if we have neither Win ansi nor wchar API, get out */ if (!(p_SetFileAttributesW || p_SetFileAttributesA)) { return false; } if (!p || !*p) { /* we should have attributes */ Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid); if (is_bopen(ofd)) { bclose(ofd); } return false; } else { Dmsg2(100, "Attribs %s = %s\n", attr->ofname, attr->attrEx); } p += from_base64(&val, p); plug(atts.dwFileAttributes, val); p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftCreationTime.dwLowDateTime = li.LowPart; atts.ftCreationTime.dwHighDateTime = li.HighPart; p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastAccessTime.dwLowDateTime = li.LowPart; atts.ftLastAccessTime.dwHighDateTime = li.HighPart; p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastWriteTime.dwLowDateTime = li.LowPart; atts.ftLastWriteTime.dwHighDateTime = li.HighPart; p++; p += from_base64(&val, p); plug(atts.nFileSizeHigh, val); p++; p += from_base64(&val, p); plug(atts.nFileSizeLow, val); /** At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */ if (!is_bopen(ofd)) { Dmsg1(100, "File not open: %s\n", attr->ofname); bopen(ofd, attr->ofname, O_WRONLY | O_BINARY, 0, 0); /* attempt to open the file */ } /* * Restore file attributes and times on the restored file. */ if (!win32_restore_file_attributes(attr->ofname, bget_handle(ofd), &atts)) { win_error(jcr, "win32_restore_file_attributes:", attr->ofname); } if (is_bopen(ofd)) { bclose(ofd); } return true; } void win_error(JCR *jcr, const char *prefix, POOLMEM *win32_ofile) { DWORD lerror = GetLastError(); LPTSTR msg; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, lerror, 0, (LPTSTR)&msg, 0, NULL); Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, win32_ofile, msg); strip_trailing_junk(msg); Jmsg3(jcr, M_ERROR, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg); LocalFree(msg); } void win_error(JCR *jcr, const char *prefix, DWORD lerror) { LPTSTR msg; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, lerror, 0, (LPTSTR)&msg, 0, NULL); strip_trailing_junk(msg); if (jcr) { Jmsg2(jcr, M_ERROR, 0, _("Error in %s: ERR=%s\n"), prefix, msg); } else { MessageBox(NULL, msg, prefix, MB_OK); } LocalFree(msg); } #endif /* HAVE_WIN32 */ bareos-Release-14.2.6/src/findlib/bfile.c000066400000000000000000001100731263011562700200650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos low level File I/O routines. This routine simulates * open(), read(), write(), and close(), but using native routines. * I.e. on Windows, we use Windows APIs. * * Kern Sibbald, April MMIII */ #include "bareos.h" #include "find.h" const int dbglvl = 200; int (*plugin_bopen)(BFILE *bfd, const char *fname, int flags, mode_t mode) = NULL; int (*plugin_bclose)(BFILE *bfd) = NULL; ssize_t (*plugin_bread)(BFILE *bfd, void *buf, size_t count) = NULL; ssize_t (*plugin_bwrite)(BFILE *bfd, void *buf, size_t count) = NULL; boffset_t (*plugin_blseek)(BFILE *bfd, boffset_t offset, int whence) = NULL; #ifdef HAVE_DARWIN_OS #include #endif #if !defined(HAVE_FDATASYNC) #define fdatasync(fd) #endif #ifdef HAVE_WIN32 void pause_msg(const char *file, const char *func, int line, const char *msg) { char buf[1000]; if (msg) { bsnprintf(buf, sizeof(buf), "%s:%s:%d %s", file, func, line, msg); } else { bsnprintf(buf, sizeof(buf), "%s:%s:%d", file, func, line); } MessageBox(NULL, buf, "Pause", MB_OK); } #endif /* =============================================================== * * U N I X AND W I N D O W S * * =============================================================== */ bool is_win32_stream(int stream) { switch (stream) { case STREAM_WIN32_DATA: case STREAM_WIN32_GZIP_DATA: case STREAM_WIN32_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: return true; } return false; } const char *stream_to_ascii(int stream) { static char buf[20]; switch (stream & STREAMMASK_TYPE) { case STREAM_UNIX_ATTRIBUTES: return _("Unix attributes"); case STREAM_FILE_DATA: return _("File data"); case STREAM_MD5_DIGEST: return _("MD5 digest"); case STREAM_GZIP_DATA: return _("GZIP data"); case STREAM_COMPRESSED_DATA: return _("Compressed data"); case STREAM_UNIX_ATTRIBUTES_EX: return _("Extended attributes"); case STREAM_SPARSE_DATA: return _("Sparse data"); case STREAM_SPARSE_GZIP_DATA: return _("GZIP sparse data"); case STREAM_SPARSE_COMPRESSED_DATA: return _("Compressed sparse data"); case STREAM_PROGRAM_NAMES: return _("Program names"); case STREAM_PROGRAM_DATA: return _("Program data"); case STREAM_SHA1_DIGEST: return _("SHA1 digest"); case STREAM_WIN32_DATA: return _("Win32 data"); case STREAM_WIN32_GZIP_DATA: return _("Win32 GZIP data"); case STREAM_WIN32_COMPRESSED_DATA: return _("Win32 compressed data"); case STREAM_MACOS_FORK_DATA: return _("MacOS Fork data"); case STREAM_HFSPLUS_ATTRIBUTES: return _("HFS+ attribs"); case STREAM_UNIX_ACCESS_ACL: return _("Standard Unix ACL attribs"); case STREAM_UNIX_DEFAULT_ACL: return _("Default Unix ACL attribs"); case STREAM_SHA256_DIGEST: return _("SHA256 digest"); case STREAM_SHA512_DIGEST: return _("SHA512 digest"); case STREAM_SIGNED_DIGEST: return _("Signed digest"); case STREAM_ENCRYPTED_FILE_DATA: return _("Encrypted File data"); case STREAM_ENCRYPTED_WIN32_DATA: return _("Encrypted Win32 data"); case STREAM_ENCRYPTED_SESSION_DATA: return _("Encrypted session data"); case STREAM_ENCRYPTED_FILE_GZIP_DATA: return _("Encrypted GZIP data"); case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: return _("Encrypted compressed data"); case STREAM_ENCRYPTED_WIN32_GZIP_DATA: return _("Encrypted Win32 GZIP data"); case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: return _("Encrypted Win32 Compressed data"); case STREAM_ENCRYPTED_MACOS_FORK_DATA: return _("Encrypted MacOS fork data"); case STREAM_ACL_AIX_TEXT: return _("AIX Specific ACL attribs"); case STREAM_ACL_DARWIN_ACCESS_ACL: return _("Darwin Specific ACL attribs"); case STREAM_ACL_FREEBSD_DEFAULT_ACL: return _("FreeBSD Specific Default ACL attribs"); case STREAM_ACL_FREEBSD_ACCESS_ACL: return _("FreeBSD Specific Access ACL attribs"); case STREAM_ACL_HPUX_ACL_ENTRY: return _("HPUX Specific ACL attribs"); case STREAM_ACL_IRIX_DEFAULT_ACL: return _("Irix Specific Default ACL attribs"); case STREAM_ACL_IRIX_ACCESS_ACL: return _("Irix Specific Access ACL attribs"); case STREAM_ACL_LINUX_DEFAULT_ACL: return _("Linux Specific Default ACL attribs"); case STREAM_ACL_LINUX_ACCESS_ACL: return _("Linux Specific Access ACL attribs"); case STREAM_ACL_TRU64_DEFAULT_ACL: return _("TRU64 Specific Default ACL attribs"); case STREAM_ACL_TRU64_ACCESS_ACL: return _("TRU64 Specific Access ACL attribs"); case STREAM_ACL_SOLARIS_ACLENT: return _("Solaris Specific POSIX ACL attribs"); case STREAM_ACL_SOLARIS_ACE: return _("Solaris Specific NFSv4/ZFS ACL attribs"); case STREAM_ACL_AFS_TEXT: return _("AFS Specific ACL attribs"); case STREAM_ACL_AIX_AIXC: return _("AIX Specific POSIX ACL attribs"); case STREAM_ACL_AIX_NFS4: return _("AIX Specific NFSv4 ACL attribs"); case STREAM_ACL_FREEBSD_NFS4_ACL: return _("FreeBSD Specific NFSv4/ZFS ACL attribs"); case STREAM_ACL_HURD_DEFAULT_ACL: return _("GNU Hurd Specific Default ACL attribs"); case STREAM_ACL_HURD_ACCESS_ACL: return _("GNU Hurd Specific Access ACL attribs"); case STREAM_XATTR_HURD: return _("GNU Hurd Specific Extended attribs"); case STREAM_XATTR_IRIX: return _("IRIX Specific Extended attribs"); case STREAM_XATTR_TRU64: return _("TRU64 Specific Extended attribs"); case STREAM_XATTR_AIX: return _("AIX Specific Extended attribs"); case STREAM_XATTR_OPENBSD: return _("OpenBSD Specific Extended attribs"); case STREAM_XATTR_SOLARIS_SYS: return _("Solaris Specific Extensible attribs or System Extended attribs"); case STREAM_XATTR_SOLARIS: return _("Solaris Specific Extended attribs"); case STREAM_XATTR_DARWIN: return _("Darwin Specific Extended attribs"); case STREAM_XATTR_FREEBSD: return _("FreeBSD Specific Extended attribs"); case STREAM_XATTR_LINUX: return _("Linux Specific Extended attribs"); case STREAM_XATTR_NETBSD: return _("NetBSD Specific Extended attribs"); default: sprintf(buf, "%d", stream); return (const char *)buf; } } /** * Convert a 64 bit little endian to a big endian */ static inline void int64_LE2BE(int64_t* pBE, const int64_t v) { /* convert little endian to big endian */ if (htonl(1) != 1L) { /* no work if on little endian machine */ memcpy(pBE, &v, sizeof(int64_t)); } else { int i; uint8_t rv[sizeof(int64_t)]; uint8_t *pv = (uint8_t *) &v; for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(pBE, &rv, sizeof(int64_t)); } } /** * Convert a 32 bit little endian to a big endian */ static inline void int32_LE2BE(int32_t* pBE, const int32_t v) { /* convert little endian to big endian */ if (htonl(1) != 1L) { /* no work if on little endian machine */ memcpy(pBE, &v, sizeof(int32_t)); } else { int i; uint8_t rv[sizeof(int32_t)]; uint8_t *pv = (uint8_t *) &v; for (i = 0; i < 4; i++) { rv[i] = pv[3 - i]; } memcpy(pBE, &rv, sizeof(int32_t)); } } /** * Read a BackupRead block and pull out the file data */ bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize) { /* pByte contains the buffer dwSize the len to be processed. function assumes to be called in successive incremental order over the complete BackupRead stream beginning at pos 0 and ending at the end. */ PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT* pContext = &(bfd->win32DecompContext); bool bContinue = false; int64_t dwDataOffset = 0; int64_t dwDataLen; /* Win32 Stream Header size without name of stream. * = sizeof (WIN32_STREAM_ID)- sizeof(WCHAR*); */ int32_t dwSizeHeader = 20; do { if (pContext->liNextHeader >= dwSize) { dwDataLen = dwSize-dwDataOffset; bContinue = false; /* 1 iteration is enough */ } else { dwDataLen = pContext->liNextHeader-dwDataOffset; bContinue = true; /* multiple iterations may be necessary */ } /* flush */ /* copy block of real DATA */ if (pContext->bIsInData) { if (bwrite(bfd, ((char *)pBuffer)+dwDataOffset, dwDataLen) != (ssize_t)dwDataLen) return false; } if (pContext->liNextHeader < dwSize) {/* is a header in this block ? */ int32_t dwOffsetTarget; int32_t dwOffsetSource; if (pContext->liNextHeader < 0) { /* start of header was before this block, so we * continue with the part in the current block */ dwOffsetTarget = -pContext->liNextHeader; dwOffsetSource = 0; } else { /* start of header is inside of this block */ dwOffsetTarget = 0; dwOffsetSource = pContext->liNextHeader; } int32_t dwHeaderPartLen = dwSizeHeader-dwOffsetTarget; bool bHeaderIsComplete; if (dwHeaderPartLen <= dwSize-dwOffsetSource) { /* header (or rest of header) is completely available in current block */ bHeaderIsComplete = true; } else { /* header will continue in next block */ bHeaderIsComplete = false; dwHeaderPartLen = dwSize-dwOffsetSource; } /* copy the available portion of header to persistent copy */ memcpy(((char *)&pContext->header_stream)+dwOffsetTarget, ((char *)pBuffer)+dwOffsetSource, dwHeaderPartLen); /* recalculate position of next header */ if (bHeaderIsComplete) { /* convert stream name size (32 bit little endian) to machine type */ int32_t dwNameSize; int32_LE2BE (&dwNameSize, pContext->header_stream.dwStreamNameSize); dwDataOffset = dwNameSize+pContext->liNextHeader+dwSizeHeader; /* convert stream size (64 bit little endian) to machine type */ int64_LE2BE (&(pContext->liNextHeader), pContext->header_stream.Size); pContext->liNextHeader += dwDataOffset; pContext->bIsInData = pContext->header_stream.dwStreamId == WIN32_BACKUP_DATA; if (dwDataOffset == dwSize) bContinue = false; } else { /* stop and continue with next block */ bContinue = false; pContext->bIsInData = false; } } } while (bContinue); /* set "NextHeader" relative to the beginning of the next block */ pContext->liNextHeader-= dwSize; return TRUE; } /* =============================================================== * * W I N D O W S * * =============================================================== */ #if defined(HAVE_WIN32) /* Imported Functions */ extern void unix_name_to_win32(POOLMEM **win32_name, const char *name); extern "C" HANDLE get_osfhandle(int fd); void binit(BFILE *bfd) { memset(bfd, 0, sizeof(BFILE)); bfd->fid = -1; bfd->mode = BF_CLOSED; bfd->use_backup_api = have_win32_api(); bfd->cmd_plugin = false; bfd->pvContext = NULL; } /* * Enables using the Backup API (win32_data). * Returns 1 if function worked * Returns 0 if failed (i.e. do not have Backup API on this machine) */ bool set_win32_backup(BFILE *bfd) { /* We enable if possible here */ bfd->use_backup_api = have_win32_api(); return bfd->use_backup_api; } bool set_portable_backup(BFILE *bfd) { bfd->use_backup_api = false; return true; } bool set_cmd_plugin(BFILE *bfd, JCR *jcr) { bfd->cmd_plugin = true; bfd->jcr = jcr; return true; } /* * Return 1 if we are NOT using Win32 BackupWrite() * return 0 if are */ bool is_portable_backup(BFILE *bfd) { return !bfd->use_backup_api; } bool have_win32_api() { return p_BackupRead && p_BackupWrite; } /* * Return true if we support the stream * false if we do not support the stream * * This code is running under Win32, so we do not need #ifdef on MACOS ... */ bool is_restore_stream_supported(int stream) { switch (stream) { /* * Streams known not to be supported */ #ifndef HAVE_LIBZ case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: #endif case STREAM_MACOS_FORK_DATA: case STREAM_HFSPLUS_ATTRIBUTES: case STREAM_ENCRYPTED_MACOS_FORK_DATA: return false; /* * Known streams */ #ifdef HAVE_LIBZ case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: #endif case STREAM_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: case STREAM_WIN32_DATA: case STREAM_UNIX_ATTRIBUTES: case STREAM_FILE_DATA: case STREAM_MD5_DIGEST: case STREAM_UNIX_ATTRIBUTES_EX: case STREAM_SPARSE_DATA: case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: case STREAM_SHA1_DIGEST: #ifdef HAVE_SHA2 case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: #endif #ifdef HAVE_CRYPTO case STREAM_SIGNED_DIGEST: case STREAM_ENCRYPTED_FILE_DATA: case STREAM_ENCRYPTED_FILE_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: #endif /* !HAVE_CRYPTO */ case 0: /* compatibility with old tapes */ return true; } return false; } HANDLE bget_handle(BFILE *bfd) { return (bfd->mode == BF_CLOSED) ? INVALID_HANDLE_VALUE : bfd->fh; } /* * Windows flags for the OpenEncryptedFileRaw functions. */ #ifndef CREATE_FOR_EXPORT #define CREATE_FOR_EXPORT 0 #endif #ifndef CREATE_FOR_IMPORT #define CREATE_FOR_IMPORT 1 #endif #ifndef CREATE_FOR_DIR #define CREATE_FOR_DIR 2 #endif #ifndef OVERWRITE_HIDDEN #define OVERWRITE_HIDDEN 4 #endif static inline int bopen_encrypted(BFILE *bfd, const char *fname, int flags, mode_t mode) { bool is_dir; ULONG ulFlags = 0; POOLMEM *win32_fname; POOLMEM *win32_fname_wchar; if (!p_OpenEncryptedFileRawA && !p_OpenEncryptedFileRawW) { Dmsg0(50, "No p_OpenEncryptedFileRawA and no p_OpenEncryptedFileRawW!!!!!\n"); return 0; } is_dir = S_ISDIR(mode); /* * Convert to Windows path format */ win32_fname = get_pool_memory(PM_FNAME); win32_fname_wchar = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, (char *)fname); if (p_OpenEncryptedFileRawW && p_MultiByteToWideChar) { make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname); } /* * See if we open the file for create or read-write. */ if ((flags & O_CREAT) || (flags & O_WRONLY)) { if (is_dir) { ulFlags |= CREATE_FOR_IMPORT | OVERWRITE_HIDDEN | CREATE_FOR_DIR; } else { ulFlags |= CREATE_FOR_IMPORT | OVERWRITE_HIDDEN; } bfd->mode = BF_WRITE; } else { ulFlags = CREATE_FOR_EXPORT; bfd->mode = BF_READ; } if (p_OpenEncryptedFileRawW && p_MultiByteToWideChar) { /* * Unicode open. */ Dmsg1(100, "OpenEncryptedFileRawW=%s\n", win32_fname); if (p_OpenEncryptedFileRawW((LPCWSTR)win32_fname_wchar, ulFlags, &(bfd->pvContext))) { bfd->mode = BF_CLOSED; } } else { /* * ASCII open. */ Dmsg1(100, "OpenEncryptedFileRawA=%s\n", win32_fname); if (p_OpenEncryptedFileRawA(win32_fname_wchar, ulFlags, &(bfd->pvContext))) { bfd->mode=BF_CLOSED; } } free_pool_memory(win32_fname_wchar); free_pool_memory(win32_fname); bfd->encrypted = true; return bfd->mode == BF_CLOSED ? -1 : 1; } static inline int bopen_nonencrypted(BFILE *bfd, const char *fname, int flags, mode_t mode) { POOLMEM *win32_fname; POOLMEM *win32_fname_wchar; DWORD dwaccess, dwflags, dwshare; /* * Convert to Windows path format */ win32_fname = get_pool_memory(PM_FNAME); win32_fname_wchar = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, (char *)fname); if (bfd->cmd_plugin && plugin_bopen) { int rtnstat; Dmsg1(50, "call plugin_bopen fname=%s\n", fname); rtnstat = plugin_bopen(bfd, fname, flags, mode); Dmsg1(50, "return from plugin_bopen status=%d\n", rtnstat); if (rtnstat >= 0) { if (flags & O_CREAT || flags & O_WRONLY) { /* Open existing for write */ Dmsg1(50, "plugin_open for write OK file=%s.\n", fname); bfd->mode = BF_WRITE; } else { Dmsg1(50, "plugin_open for read OK file=%s.\n", fname); bfd->mode = BF_READ; } } else { bfd->mode = BF_CLOSED; Dmsg1(000, "==== plugin_bopen returned bad status=%d\n", rtnstat); } free_pool_memory(win32_fname_wchar); free_pool_memory(win32_fname); return bfd->mode == BF_CLOSED ? -1 : 1; } Dmsg0(50, "=== NO plugin\n"); if (!(p_CreateFileA || p_CreateFileW)) { Dmsg0(50, "No CreateFileA and no CreateFileW!!!!!\n"); return 0; } if (p_CreateFileW && p_MultiByteToWideChar) { make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname); } if (flags & O_CREAT) { /* Create */ if (bfd->use_backup_api) { dwaccess = GENERIC_WRITE | FILE_ALL_ACCESS | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY; dwflags = FILE_FLAG_BACKUP_SEMANTICS; } else { dwaccess = GENERIC_WRITE; dwflags = 0; } /* * Unicode open for create write */ if (p_CreateFileW && p_MultiByteToWideChar) { Dmsg1(100, "Create CreateFileW=%s\n", win32_fname); bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar, dwaccess, /* Requested access */ 0, /* Shared mode */ NULL, /* SecurityAttributes */ CREATE_ALWAYS, /* CreationDisposition */ dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } else { /* * ASCII open */ Dmsg1(100, "Create CreateFileA=%s\n", win32_fname); bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */ 0, /* Shared mode */ NULL, /* SecurityAttributes */ CREATE_ALWAYS, /* CreationDisposition */ dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } bfd->mode = BF_WRITE; } else if (flags & O_WRONLY) { /* * Open existing for write */ if (bfd->use_backup_api) { dwaccess = GENERIC_WRITE | WRITE_OWNER | WRITE_DAC; if (flags & O_NOFOLLOW) { dwflags = FILE_FLAG_BACKUP_SEMANTICS; } else { dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT; } } else { dwaccess = GENERIC_WRITE; dwflags = 0; } if (p_CreateFileW && p_MultiByteToWideChar) { /* * unicode open for open existing write */ Dmsg1(100, "Write only CreateFileW=%s\n", win32_fname); bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar, dwaccess, /* Requested access */ 0, /* Shared mode */ NULL, /* SecurityAttributes */ OPEN_EXISTING, /* CreationDisposition */ dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } else { /* * ASCII open */ Dmsg1(100, "Write only CreateFileA=%s\n", win32_fname); bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */ 0, /* Shared mode */ NULL, /* SecurityAttributes */ OPEN_EXISTING, /* CreationDisposition */ dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } bfd->mode = BF_WRITE; } else { /* * Open existing for read */ if (bfd->use_backup_api) { dwaccess = GENERIC_READ | READ_CONTROL | ACCESS_SYSTEM_SECURITY; if (flags & O_NOFOLLOW) { dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN; } else { dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OPEN_REPARSE_POINT; } dwshare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; } else { dwaccess = GENERIC_READ; dwflags = 0; dwshare = FILE_SHARE_READ | FILE_SHARE_WRITE; } if (p_CreateFileW && p_MultiByteToWideChar) { /* * Unicode open for open existing read */ Dmsg1(100, "Read CreateFileW=%s\n", win32_fname); bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar, dwaccess, /* Requested access */ dwshare, /* Share modes */ NULL, /* SecurityAttributes */ OPEN_EXISTING, /* CreationDisposition */ dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } else { /* * ASCII open for open existing read */ Dmsg1(100, "Read CreateFileA=%s\n", win32_fname); bfd->fh = p_CreateFileA(win32_fname, dwaccess, /* Requested access */ dwshare, /* Share modes */ NULL, /* SecurityAttributes */ OPEN_EXISTING, /* CreationDisposition */ dwflags, /* Flags and attributes */ NULL); /* TemplateFile */ } bfd->mode = BF_READ; } if (bfd->fh == INVALID_HANDLE_VALUE) { bfd->lerror = GetLastError(); bfd->berrno = b_errno_win32; errno = b_errno_win32; bfd->mode = BF_CLOSED; } bfd->errmsg = NULL; bfd->lpContext = NULL; bfd->win32DecompContext.bIsInData = false; bfd->win32DecompContext.liNextHeader = 0; free_pool_memory(win32_fname_wchar); free_pool_memory(win32_fname); bfd->encrypted = false; return bfd->mode == BF_CLOSED ? -1 : 1; } int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode, dev_t rdev) { Dmsg4(100, "bopen: fname %s, flags %d, mode %d, rdev %u\n", fname, flags, mode, rdev); /* * If the FILE_ATTRIBUTES_DEDUPED_ITEM bit is set this is a deduped file * we let the bopen function know it should open the file without the * FILE_FLAG_OPEN_REPARSE_POINT flag by setting in the O_NOFOLLOW open flag. */ if (rdev & FILE_ATTRIBUTES_DEDUPED_ITEM) { flags |= O_NOFOLLOW; } /* * If the FILE_ATTRIBUTE_ENCRYPTED bit is set this is an file on an EFS filesystem. * For that we need some special handling. */ if (rdev & FILE_ATTRIBUTE_ENCRYPTED) { return bopen_encrypted(bfd, fname, flags, mode); } else { return bopen_nonencrypted(bfd, fname, flags, mode); } } /* * Returns 0 on success * -1 on error */ static inline int bclose_encrypted(BFILE *bfd) { if (bfd->mode == BF_CLOSED) { Dmsg0(50, "=== BFD already closed.\n"); return 0; } if (!p_CloseEncryptedFileRaw) { Dmsg0(50, "No p_CloseEncryptedFileRaw !!!!!\n"); return 0; } p_CloseEncryptedFileRaw(bfd->pvContext); bfd->pvContext = NULL; bfd->mode = BF_CLOSED; return 0; } /* * Returns 0 on success * -1 on error */ static inline int bclose_nonencrypted(BFILE *bfd) { int status = 0; if (bfd->mode == BF_CLOSED) { Dmsg0(50, "=== BFD already closed.\n"); return 0; } if (bfd->cmd_plugin && plugin_bclose) { status = plugin_bclose(bfd); Dmsg0(50, "==== BFD closed!!!\n"); goto all_done; } /* * We need to tell the API to release the buffer it * allocated in lpContext. We do so by calling the * API one more time, but with the Abort bit set. */ if (bfd->use_backup_api && bfd->mode == BF_READ) { BYTE buf[10]; if (bfd->lpContext && !p_BackupRead(bfd->fh, buf, /* buffer */ (DWORD)0, /* bytes to read */ &bfd->rw_bytes, /* bytes read */ 1, /* Abort */ 1, /* ProcessSecurity */ &bfd->lpContext)) { /* Read context */ errno = b_errno_win32; status = -1; } } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) { BYTE buf[10]; if (bfd->lpContext && !p_BackupWrite(bfd->fh, buf, /* buffer */ (DWORD)0, /* bytes to read */ &bfd->rw_bytes, /* bytes written */ 1, /* Abort */ 1, /* ProcessSecurity */ &bfd->lpContext)) { /* Write context */ errno = b_errno_win32; status = -1; } } if (!CloseHandle(bfd->fh)) { status = -1; errno = b_errno_win32; } all_done: if (bfd->errmsg) { free_pool_memory(bfd->errmsg); bfd->errmsg = NULL; } bfd->mode = BF_CLOSED; bfd->lpContext = NULL; bfd->cmd_plugin = false; return status; } /* * Returns 0 on success * -1 on error */ int bclose(BFILE *bfd) { if (bfd->encrypted) { return bclose_encrypted(bfd); } else { return bclose_nonencrypted(bfd); } } /* Returns: bytes read on success * 0 on EOF * -1 on error */ ssize_t bread(BFILE *bfd, void *buf, size_t count) { bfd->rw_bytes = 0; if (bfd->cmd_plugin && plugin_bread) { return plugin_bread(bfd, buf, count); } if (bfd->use_backup_api) { if (!p_BackupRead(bfd->fh, (BYTE *)buf, count, &bfd->rw_bytes, 0, /* no Abort */ 1, /* Process Security */ &bfd->lpContext)) { /* Context */ bfd->lerror = GetLastError(); bfd->berrno = b_errno_win32; errno = b_errno_win32; return -1; } } else { if (!ReadFile(bfd->fh, buf, count, &bfd->rw_bytes, NULL)) { bfd->lerror = GetLastError(); bfd->berrno = b_errno_win32; errno = b_errno_win32; return -1; } } return (ssize_t)bfd->rw_bytes; } ssize_t bwrite(BFILE *bfd, void *buf, size_t count) { bfd->rw_bytes = 0; if (bfd->cmd_plugin && plugin_bwrite) { return plugin_bwrite(bfd, buf, count); } if (bfd->use_backup_api) { if (!p_BackupWrite(bfd->fh, (BYTE *)buf, count, &bfd->rw_bytes, 0, /* No abort */ 1, /* Process Security */ &bfd->lpContext)) { /* Context */ bfd->lerror = GetLastError(); bfd->berrno = b_errno_win32; errno = b_errno_win32; return -1; } } else { if (!WriteFile(bfd->fh, buf, count, &bfd->rw_bytes, NULL)) { bfd->lerror = GetLastError(); bfd->berrno = b_errno_win32; errno = b_errno_win32; return -1; } } return (ssize_t)bfd->rw_bytes; } bool is_bopen(BFILE *bfd) { return bfd->mode != BF_CLOSED; } boffset_t blseek(BFILE *bfd, boffset_t offset, int whence) { LONG offset_low = (LONG)offset; LONG offset_high = (LONG)(offset >> 32); DWORD dwResult; if (bfd->cmd_plugin && plugin_blseek) { return plugin_blseek(bfd, offset, whence); } dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence); if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { return (boffset_t)-1; } return ((boffset_t)offset_high << 32) | dwResult; } #else /* Unix systems */ /* =============================================================== * * U N I X * * =============================================================== */ void binit(BFILE *bfd) { memset(bfd, 0, sizeof(BFILE)); bfd->fid = -1; } bool have_win32_api() { return false; /* no can do */ } /* * Enables using the Backup API (win32_data). * Returns true if function worked * Returns false if failed (i.e. do not have Backup API on this machine) */ bool set_win32_backup(BFILE *bfd) { return false; /* no can do */ } bool set_portable_backup(BFILE *bfd) { return true; /* no problem */ } /* * Return true if we are writing in portable format * return false if not */ bool is_portable_backup(BFILE *bfd) { return true; /* portable by definition */ } bool set_prog(BFILE *bfd, char *prog, JCR *jcr) { return false; } bool set_cmd_plugin(BFILE *bfd, JCR *jcr) { bfd->cmd_plugin = true; bfd->jcr = jcr; return true; } /* * This code is running on a non-Win32 machine */ bool is_restore_stream_supported(int stream) { /* No Win32 backup on this machine */ switch (stream) { #ifndef HAVE_LIBZ case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: #endif #ifndef HAVE_DARWIN_OS case STREAM_MACOS_FORK_DATA: case STREAM_HFSPLUS_ATTRIBUTES: #endif return false; /* Known streams */ #ifdef HAVE_LIBZ case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: #endif case STREAM_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: case STREAM_WIN32_DATA: case STREAM_UNIX_ATTRIBUTES: case STREAM_FILE_DATA: case STREAM_MD5_DIGEST: case STREAM_UNIX_ATTRIBUTES_EX: case STREAM_SPARSE_DATA: case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: case STREAM_SHA1_DIGEST: #ifdef HAVE_SHA2 case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: #endif #ifdef HAVE_CRYPTO case STREAM_SIGNED_DIGEST: case STREAM_ENCRYPTED_FILE_DATA: case STREAM_ENCRYPTED_FILE_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: #endif #ifdef HAVE_DARWIN_OS case STREAM_MACOS_FORK_DATA: case STREAM_HFSPLUS_ATTRIBUTES: #ifdef HAVE_CRYPTO case STREAM_ENCRYPTED_MACOS_FORK_DATA: #endif /* HAVE_CRYPTO */ #endif /* HAVE_DARWIN_OS */ case 0: /* compatibility with old tapes */ return true; } return false; } int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode, dev_t rdev) { Dmsg4(100, "bopen: fname %s, flags %d, mode %d, rdev %u\n", fname, flags, mode, rdev); if (bfd->cmd_plugin && plugin_bopen) { Dmsg1(400, "call plugin_bopen fname=%s\n", fname); bfd->fid = plugin_bopen(bfd, fname, flags, mode); Dmsg1(400, "Plugin bopen stat=%d\n", bfd->fid); return bfd->fid; } /* Normal file open */ Dmsg1(dbglvl, "open file %s\n", fname); /* We use fnctl to set O_NOATIME if requested to avoid open error */ bfd->fid = open(fname, flags & ~O_NOATIME, mode); /* Set O_NOATIME if possible */ if (bfd->fid != -1 && flags & O_NOATIME) { int oldflags = fcntl(bfd->fid, F_GETFL, 0); if (oldflags == -1) { bfd->berrno = errno; close(bfd->fid); bfd->fid = -1; } else { int ret = fcntl(bfd->fid, F_SETFL, oldflags | O_NOATIME); /* EPERM means setting O_NOATIME was not allowed */ if (ret == -1 && errno != EPERM) { bfd->berrno = errno; close(bfd->fid); bfd->fid = -1; } } } bfd->berrno = errno; bfd->m_flags = flags; Dmsg1(400, "Open file %d\n", bfd->fid); errno = bfd->berrno; bfd->win32DecompContext.bIsInData = false; bfd->win32DecompContext.liNextHeader = 0; #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) if (bfd->fid != -1 && flags & O_RDONLY) { int status = posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_WILLNEED); Dmsg2(400, "Did posix_fadvise on %s status=%d\n", fname, status); } #endif return bfd->fid; } #ifdef HAVE_DARWIN_OS /* * Open the resource fork of a file. */ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode) { POOLMEM *rsrc_fname; rsrc_fname = get_pool_memory(PM_FNAME); pm_strcpy(rsrc_fname, fname); pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC); bopen(bfd, rsrc_fname, flags, mode, 0); free_pool_memory(rsrc_fname); return bfd->fid; } #else int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode) { return -1; } #endif int bclose(BFILE *bfd) { int status; if (bfd->fid == -1) { return 0; } Dmsg1(400, "Close file %d\n", bfd->fid); if (bfd->cmd_plugin && plugin_bclose) { status = plugin_bclose(bfd); bfd->fid = -1; bfd->cmd_plugin = false; } else { #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED) if (bfd->m_flags & O_RDONLY) { fdatasync(bfd->fid); /* sync the file */ /* Tell OS we don't need it any more */ posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_DONTNEED); } #endif /* Close normal file */ status = close(bfd->fid); bfd->berrno = errno; bfd->fid = -1; bfd->cmd_plugin = false; } return status; } ssize_t bread(BFILE *bfd, void *buf, size_t count) { ssize_t status; if (bfd->cmd_plugin && plugin_bread) { return plugin_bread(bfd, buf, count); } status = read(bfd->fid, buf, count); bfd->berrno = errno; return status; } ssize_t bwrite(BFILE *bfd, void *buf, size_t count) { ssize_t status; if (bfd->cmd_plugin && plugin_bwrite) { return plugin_bwrite(bfd, buf, count); } status = write(bfd->fid, buf, count); bfd->berrno = errno; return status; } bool is_bopen(BFILE *bfd) { return bfd->fid >= 0; } boffset_t blseek(BFILE *bfd, boffset_t offset, int whence) { boffset_t pos; if (bfd->cmd_plugin && plugin_bwrite) { return plugin_blseek(bfd, offset, whence); } pos = (boffset_t)lseek(bfd->fid, offset, whence); bfd->berrno = errno; return pos; } #endif bareos-Release-14.2.6/src/findlib/bfile.h000066400000000000000000000120261263011562700200710ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos low level File I/O routines. This routine simulates * open(), read(), write(), and close(), but using native routines. * I.e. on Windows, we use Windows APIs. * * Kern Sibbald May MMIII */ #ifndef __BFILE_H #define __BFILE_H /* this should physically correspond to WIN32_STREAM_ID * from winbase.h on Win32. We didn't inlcude cStreamName * as we don't use it and don't need it for a correct struct size. */ #define WIN32_BACKUP_DATA 1 typedef struct _BWIN32_STREAM_ID { int32_t dwStreamId; int32_t dwStreamAttributes; int64_t Size; int32_t dwStreamNameSize; } BWIN32_STREAM_ID, *LPBWIN32_STREAM_ID ; typedef struct _PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT { int64_t liNextHeader; bool bIsInData; BWIN32_STREAM_ID header_stream; } PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT; /* ======================================================= * * W I N D O W S * * ======================================================= */ #if defined(HAVE_WIN32) enum { BF_CLOSED, BF_READ, /* BackupRead */ BF_WRITE /* BackupWrite */ }; /* In bfile.c */ /* Basic Win32 low level I/O file packet */ struct BFILE { bool use_backup_api; /* set if using BackupRead/Write */ bool encrypted; /* set if using ReadEncryptedFileRaw/WriteEncryptedFileRaw */ int mode; /* set if file is open */ HANDLE fh; /* Win32 file handle */ int fid; /* fd if doing Unix style */ LPVOID lpContext; /* BackupRead/Write context */ PVOID pvContext; /* Encryption context */ POOLMEM *errmsg; /* error message buffer */ DWORD rw_bytes; /* Bytes read or written */ DWORD lerror; /* Last error code */ int berrno; /* errno */ boffset_t offset; /* Delta offset */ JCR *jcr; /* jcr for editing job codes */ PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */ int use_backup_decomp; /* set if using BackupRead Stream Decomposition */ bool reparse_point; /* set if reparse point */ bool cmd_plugin; /* set if we have a command plugin */ }; HANDLE bget_handle(BFILE *bfd); #else /* Linux/Unix systems */ /* ======================================================= * * U N I X * * ======================================================= */ /* Basic Unix low level I/O file packet */ struct BFILE { int fid; /* file id on Unix */ int m_flags; /* open flags */ int berrno; /* errno */ int32_t lerror; /* not used - simplies Win32 builds */ boffset_t offset; /* Delta offset */ JCR *jcr; /* jcr for editing job codes */ PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */ int use_backup_decomp; /* set if using BackupRead Stream Decomposition */ bool reparse_point; /* not used in Unix */ bool cmd_plugin; /* set if we have a command plugin */ }; #endif void binit(BFILE *bfd); bool is_bopen(BFILE *bfd); bool set_win32_backup(BFILE *bfd); bool set_portable_backup(BFILE *bfd); bool set_cmd_plugin(BFILE *bfd, JCR *jcr); bool have_win32_api(); bool is_portable_backup(BFILE *bfd); bool is_restore_stream_supported(int stream); bool is_win32_stream(int stream); int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode, dev_t rdev); int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode); int bclose(BFILE *bfd); ssize_t bread(BFILE *bfd, void *buf, size_t count); ssize_t bwrite(BFILE *bfd, void *buf, size_t count); boffset_t blseek(BFILE *bfd, boffset_t offset, int whence); const char *stream_to_ascii(int stream); bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize); #endif /* __BFILE_H */ bareos-Release-14.2.6/src/findlib/create_file.c000066400000000000000000000441061263011562700212510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Create a file, and reset the modes * * Kern Sibbald, November MM */ #include "bareos.h" #include "find.h" #ifndef S_IRWXUGO #define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) #endif #ifndef IS_CTG #define IS_CTG(x) 0 #define O_CTG 0 #endif static int separate_path_and_file(JCR *jcr, char *fname, char *ofile); static int path_already_seen(JCR *jcr, char *path, int pnl); /* * Create the file, or the directory * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: CF_SKIP if file should be skipped * CF_ERROR on error * CF_EXTRACT file created and data to restore * CF_CREATED file created no data to restore * * Note, we create the file here, except for special files, * we do not set the attributes because we want to first * write the file, then when the writing is done, set the * attributes. * * So, we return with the file descriptor open for normal files. */ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) { mode_t new_mode, parent_mode; int flags; uid_t uid; gid_t gid; int pnl; bool exists = false; struct stat mstatp; #ifndef HAVE_WIN32 bool isOnRoot; #endif bfd->reparse_point = false; if (is_win32_stream(attr->data_stream)) { set_win32_backup(bfd); } else { set_portable_backup(bfd); } new_mode = attr->statp.st_mode; Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname); parent_mode = S_IWUSR | S_IXUSR | new_mode; gid = attr->statp.st_gid; uid = attr->statp.st_uid; #ifdef HAVE_WIN32 if (!bfd->use_backup_api) { /* * Eliminate invalid windows filename characters from foreign filenames */ char *ch = (char *)attr->ofname; if (ch[0] != 0 && ch[1] != 0) { ch += 2; while (*ch) { switch (*ch) { case ':': case '<': case '>': case '*': case '?': case '|': *ch = '_'; break; } ch++; } } } #endif Dmsg2(400, "Replace=%c %d\n", (char)replace, replace); if (lstat(attr->ofname, &mstatp) == 0) { exists = true; switch (replace) { case REPLACE_IFNEWER: if (attr->statp.st_mtime <= mstatp.st_mtime) { Qmsg(jcr, M_INFO, 0, _("File skipped. Not newer: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_IFOLDER: if (attr->statp.st_mtime >= mstatp.st_mtime) { Qmsg(jcr, M_INFO, 0, _("File skipped. Not older: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_NEVER: /* * Set attributes if we created this directory */ if (attr->type == FT_DIREND && path_list_lookup(jcr->path_list, attr->ofname)) { break; } Qmsg(jcr, M_INFO, 0, _("File skipped. Already exists: %s\n"), attr->ofname); return CF_SKIP; case REPLACE_ALWAYS: break; } } switch (attr->type) { case FT_RAW: /* Raw device to be written */ case FT_FIFO: /* FIFO to be written to */ case FT_LNKSAVED: /* Hard linked, file already saved */ case FT_LNK: case FT_SPEC: /* Fifo, ... to be backed up */ case FT_REGE: /* Empty file */ case FT_REG: /* Regular file */ /* * Note, we do not delete FT_RAW because these are device files * or FIFOs that should already exist. If we blow it away, * we may blow away a FIFO that is being used to read the * restore data, or we may blow away a partition definition. */ if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) { /* Get rid of old copy */ Dmsg1(400, "unlink %s\n", attr->ofname); if (unlink(attr->ofname) == -1) { berrno be; Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"), attr->ofname, be.bstrerror()); /* Continue despite error */ } } /* * Here we do some preliminary work for all the above * types to create the path to the file if it does * not already exist. Below, we will split to * do the file type specific work */ pnl = separate_path_and_file(jcr, attr->fname, attr->ofname); if (pnl < 0) { return CF_ERROR; } /* * If path length is <= 0 we are making a file in the root * directory. Assume that the directory already exists. */ if (pnl > 0) { char savechr; savechr = attr->ofname[pnl]; attr->ofname[pnl] = 0; /* terminate path */ if (!path_already_seen(jcr, attr->ofname, pnl)) { Dmsg1(400, "Make path %s\n", attr->ofname); /* * If we need to make the directory, ensure that it is with * execute bit set (i.e. parent_mode), and preserve what already * exists. Normally, this should do nothing. */ if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) { Dmsg1(10, "Could not make path. %s\n", attr->ofname); attr->ofname[pnl] = savechr; /* restore full name */ return CF_ERROR; } } attr->ofname[pnl] = savechr; /* restore full name */ } /* * Now we do the specific work for each file type */ switch(attr->type) { case FT_REGE: case FT_REG: Dmsg1(100, "Create=%s\n", attr->ofname); flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /* O_NOFOLLOW; */ if (IS_CTG(attr->statp.st_mode)) { flags |= O_CTG; /* set contiguous bit if needed */ } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); bclose(bfd); } if (bopen(bfd, attr->ofname, flags, 0, attr->statp.st_rdev) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; #ifndef HAVE_WIN32 /* None of these exist in MS Windows */ case FT_RAW: /* Bareos raw device e.g. /dev/sda1 */ case FT_FIFO: /* Bareos fifo to save data */ case FT_SPEC: flags = O_WRONLY | O_BINARY; isOnRoot = bstrcmp(attr->fname, attr->ofname) ? 1 : 0; if (S_ISFIFO(attr->statp.st_mode)) { Dmsg1(400, "Restore fifo: %s\n", attr->ofname); if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } else if (S_ISSOCK(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname); #ifdef S_IFDOOR /* Solaris high speed RPC mechanism */ } else if (S_ISDOOR(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname); #endif #ifdef S_IFPORT /* Solaris event port for handling AIO */ } else if (S_ISPORT(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname); #endif } else if ((S_ISBLK(attr->statp.st_mode) || S_ISCHR(attr->statp.st_mode)) && !exists && isOnRoot) { /* * Fatal: Restoring a device on root-file system, but device node does not exist. * Should not create a dump file. */ Qmsg1(jcr, M_ERROR, 0, _("Device restore on root failed, device %s missing.\n"), attr->fname); return CF_ERROR; } else if (S_ISBLK(attr->statp.st_mode) || S_ISCHR(attr->statp.st_mode)) { Dmsg1(400, "Restoring a device as a file: %s\n", attr->ofname); flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; } else { Dmsg1(400, "Restore node: %s\n", attr->ofname); if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } /* * Here we are going to attempt to restore to a FIFO, which * means that the FIFO must already exist, AND there must * be some process already attempting to read from the * FIFO, so we open it write-only. */ if (attr->type == FT_RAW || attr->type == FT_FIFO) { btimer_t *tid; Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname); /* * Timeout open() in 60 seconds */ if (attr->type == FT_FIFO) { Dmsg0(400, "Set FIFO timer\n"); tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } Dmsg2(400, "open %s flags=0x%x\n", attr->ofname, flags); if ((bopen(bfd, attr->ofname, flags, 0, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror()); stop_thread_timer(tid); return CF_ERROR; } stop_thread_timer(tid); return CF_EXTRACT; } Dmsg1(400, "FT_SPEC %s\n", attr->ofname); return CF_CREATED; case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname); if (link(attr->olname, attr->ofname) != 0) { berrno be; #ifdef HAVE_CHFLAGS struct stat s; /* * If using BSD user flags, maybe has a file flag preventing this. * So attempt to disable, retry link, and reset flags. * Note that BSD securelevel may prevent disabling flag. */ if (stat(attr->olname, &s) == 0 && s.st_flags != 0) { if (chflags(attr->olname, 0) == 0) { if (link(attr->olname, attr->ofname) != 0) { /* * Restore original file flags even when linking failed */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } #endif /* HAVE_CHFLAGS */ Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n", attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; #ifdef HAVE_CHFLAGS } /* * Finally restore original file flags */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } #endif /* HAVE_CHFLAGS */ } return CF_CREATED; #endif /* HAVE_WIN32 */ #ifdef HAVE_WIN32 case FT_LNK: /* * Handle Windows Symlink-Like Reparse Points * - Directory Symlinks * - File Symlinks * - Volume Mount Points * - Junctions */ Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname); if (attr->statp.st_rdev & FILE_ATTRIBUTE_VOLUME_MOUNT_POINT) { /* * We do not restore volume mount points */ Dmsg0(130, "Skipping Volume Mount Point\n"); return CF_SKIP; } if (win32_symlink(attr->olname, attr->ofname, attr->statp.st_rdev) != 0 && errno != EEXIST) { berrno be; Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } return CF_CREATED; #else case FT_LNK: /* * Unix/Linux symlink handling */ Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname); if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) { berrno be; Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } return CF_CREATED; #endif } /* End inner switch */ case FT_REPARSE: case FT_JUNCTION: bfd->reparse_point = true; /* * Fall through wanted */ case FT_DIRBEGIN: case FT_DIREND: Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) { return CF_ERROR; } /* * If we are using the Win32 Backup API, we open the directory so * that the security info will be read and saved. */ if (!is_portable_backup(bfd)) { if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } if (bopen(bfd, attr->ofname, O_WRONLY | O_BINARY, 0, attr->statp.st_rdev) < 0) { berrno be; be.set_errno(bfd->berrno); #ifdef HAVE_WIN32 /* * Check for trying to create a drive, if so, skip */ if (attr->ofname[1] == ':' && IsPathSeparator(attr->ofname[2]) && attr->ofname[3] == '\0') { return CF_SKIP; } #endif Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; } else { return CF_CREATED; } case FT_DELETED: Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type); break; /* * The following should not occur */ case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: case FT_DIRNOCHG: case FT_NOCHG: case FT_ISARCH: case FT_NORECURSE: case FT_NOFSCHG: case FT_NOOPEN: Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type); break; default: Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname); break; } return CF_ERROR; } /* * Returns: > 0 index into path where last path char is. * 0 no path * -1 filename is zero length */ static int separate_path_and_file(JCR *jcr, char *fname, char *ofile) { char *f, *p, *q; int fnl, pnl; /* Separate pathname and filename */ for (q=p=f=ofile; *p; p++) { #ifdef HAVE_WIN32 if (IsPathSeparator(*p)) { f = q; if (IsPathSeparator(p[1])) { p++; } } *q++ = *p; /* copy data */ #else if (IsPathSeparator(*p)) { f = q; /* possible filename */ } q++; #endif } if (IsPathSeparator(*f)) { f++; } *q = 0; /* terminate string */ fnl = q - f; if (fnl == 0) { /* The filename length must not be zero here because we * are dealing with a file (i.e. FT_REGE or FT_REG). */ Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname); return -1; } pnl = f - ofile - 1; return pnl; } /* * Primitive caching of path to prevent recreating a pathname * each time as long as we remain in the same directory. */ static int path_already_seen(JCR *jcr, char *path, int pnl) { if (!jcr->cached_path) { jcr->cached_path = get_pool_memory(PM_FNAME); } if (jcr->cached_pnl == pnl && bstrcmp(path, jcr->cached_path)) { return 1; } pm_strcpy(jcr->cached_path, path); jcr->cached_pnl = pnl; return 0; } bareos-Release-14.2.6/src/findlib/drivetype.c000066400000000000000000000062211263011562700210160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Implement routines to determine drive type (Windows specific). * * Written by Robert Nelson, June 2006 */ #ifndef TEST_PROGRAM #include "bareos.h" #include "find.h" #else /* Set up for testing a stand alone program */ #include #include #include #define SUPPORTEDOSES \ "HAVE_WIN32\n" #define false 0 #define true 1 #define bstrncpy strncpy #define Dmsg0(n,s) fprintf(stderr, s) #define Dmsg1(n,s,a1) fprintf(stderr, s, a1) #define Dmsg2(n,s,a1,a2) fprintf(stderr, s, a1, a2) #endif /* * These functions should be implemented for each OS * * bool drivetype(const char *fname, char *dt, int dtlen); */ #if defined (HAVE_WIN32) /* Windows */ bool drivetype(const char *fname, char *dt, int dtlen) { CHAR rootpath[4]; UINT type; /* * Copy Drive Letter, colon, and backslash to rootpath */ bstrncpy(rootpath, fname, 3); rootpath[3] = '\0'; type = GetDriveType(rootpath); switch (type) { case DRIVE_REMOVABLE: bstrncpy(dt, "removable", dtlen); return true; case DRIVE_FIXED: bstrncpy(dt, "fixed", dtlen); return true; case DRIVE_REMOTE: bstrncpy(dt, "remote", dtlen); return true; case DRIVE_CDROM: bstrncpy(dt, "cdrom", dtlen); return true; case DRIVE_RAMDISK: bstrncpy(dt, "ramdisk", dtlen); return true; case DRIVE_UNKNOWN: case DRIVE_NO_ROOT_DIR: default: return false; } } /* Windows */ #else /* No recognised OS */ bool drivetype(const char *fname, char *dt, int dtlen) { Dmsg0(10, "!!! drivetype() not implemented for this OS. !!!\n"); #ifdef TEST_PROGRAM Dmsg1(10, "Please define one of the following when compiling:\n\n%s\n", SUPPORTEDOSES); exit(EXIT_FAILURE); #endif return false; } #endif #ifdef TEST_PROGRAM int main(int argc, char **argv) { char *p; char dt[1000]; int status = 0; if (argc < 2) { p = (argc < 1) ? "drivetype" : argv[0]; printf("usage:\t%s path ...\n" "\t%s prints the drive type and pathname of the paths.\n", p, p); return EXIT_FAILURE; } while (*++argv) { if (!drivetype(*argv, dt, sizeof(dt))) { status = EXIT_FAILURE; } else { printf("%s\t%s\n", dt, *argv); } } return status; } #endif bareos-Release-14.2.6/src/findlib/enable_priv.c000066400000000000000000000113041263011562700212670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Enable backup privileges for Win32 systems. * * Kern Sibbald, May MMIII */ #include "bareos.h" #include "find.h" #include "jcr.h" /*=============================================================*/ /* */ /* * * * U n i x * * * * */ /* */ /*=============================================================*/ #if !defined(HAVE_WIN32) int enable_backup_privileges(JCR *jcr, int ignore_errors) { return 0; } #endif /*=============================================================*/ /* */ /* * * * W i n 3 2 * * * * */ /* */ /*=============================================================*/ #if defined(HAVE_WIN32) void win_error(JCR *jcr, const char *prefix, DWORD lerror); static int enable_priv(JCR *jcr, HANDLE hToken, const char *name, int ignore_errors) { TOKEN_PRIVILEGES tkp; DWORD lerror; if (!(p_LookupPrivilegeValue && p_AdjustTokenPrivileges)) { return 0; /* not avail on this OS */ } // Get the LUID for the security privilege. if (!p_LookupPrivilegeValue(NULL, name, &tkp.Privileges[0].Luid)) { win_error(jcr, "LookupPrivilegeValue", GetLastError()); return 0; } /* Set the security privilege for this process. */ tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; p_AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); lerror = GetLastError(); if (lerror != ERROR_SUCCESS) { if (!ignore_errors) { char buf[200]; strcpy(buf, _("AdjustTokenPrivileges set ")); bstrncat(buf, name, sizeof(buf)); win_error(jcr, buf, lerror); } return 0; } return 1; } /* * Setup privileges we think we will need. We probably do not need * the SE_SECURITY_NAME, but since nothing seems to be working, * we get it hoping to fix the problems. */ int enable_backup_privileges(JCR *jcr, int ignore_errors) { HANDLE hToken, hProcess; int status = 0; if (!p_OpenProcessToken) { return 0; /* No avail on this OS */ } hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); // Get a token for this process. if (!p_OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { if (!ignore_errors) { win_error(jcr, "OpenProcessToken", GetLastError()); } /* Forge on anyway */ } /* Return a bit map of permissions set. */ if (enable_priv(jcr, hToken, SE_BACKUP_NAME, ignore_errors)) { status |= 1<<1; } if (enable_priv(jcr, hToken, SE_RESTORE_NAME, ignore_errors)) { status |= 1<<2; } if (enable_priv(jcr, hToken, SE_SECURITY_NAME, ignore_errors)) { status |= 1<<0; } if (enable_priv(jcr, hToken, SE_TAKE_OWNERSHIP_NAME, ignore_errors)) { status |= 1<<3; } if (enable_priv(jcr, hToken, SE_ASSIGNPRIMARYTOKEN_NAME, ignore_errors)) { status |= 1<<4; } if (enable_priv(jcr, hToken, SE_SYSTEM_ENVIRONMENT_NAME, ignore_errors)) { status |= 1<<5; } if (enable_priv(jcr, hToken, SE_CREATE_TOKEN_NAME, ignore_errors)) { status |= 1<<6; } if (enable_priv(jcr, hToken, SE_MACHINE_ACCOUNT_NAME, ignore_errors)) { status |= 1<<7; } if (enable_priv(jcr, hToken, SE_TCB_NAME, ignore_errors)) { status |= 1<<8; } if (enable_priv(jcr, hToken, SE_CREATE_PERMANENT_NAME, ignore_errors)) { status |= 1<<10; } if (status) { status |= 1<<9; } CloseHandle(hToken); CloseHandle(hProcess); return status; } #endif /* HAVE_WIN32 */ bareos-Release-14.2.6/src/findlib/find.c000066400000000000000000000425031263011562700177260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main routine for finding files on a file system. * The heart of the work to find the files on the * system is done in find_one.c. Here we have the * higher level control as well as the matching * routines for the new syntax Options resource. * * Kern E. Sibbald, MM */ #include "bareos.h" #include "find.h" static const int dbglvl = 450; int32_t name_max; /* filename max length */ int32_t path_max; /* path name max length */ #ifdef DEBUG #undef bmalloc #define bmalloc(x) sm_malloc(__FILE__, __LINE__, x) #endif static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level); static const int fnmode = 0; /* * Initialize the find files "global" variables */ FF_PKT *init_find_files() { FF_PKT *ff; ff = (FF_PKT *)bmalloc(sizeof(FF_PKT)); memset(ff, 0, sizeof(FF_PKT)); ff->sys_fname = get_pool_memory(PM_FNAME); /* Get system path and filename maximum lengths */ path_max = pathconf(".", _PC_PATH_MAX); if (path_max < 2048) { path_max = 2048; } name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 2048) { name_max = 2048; } path_max++; /* add for EOS */ name_max++; /* add for EOS */ Dmsg1(dbglvl, "init_find_files ff=%p\n", ff); return ff; } /* * Set find_files options. For the moment, we only * provide for full/incremental saves, and setting * of save_time. For additional options, see above */ void set_find_options(FF_PKT *ff, bool incremental, time_t save_time) { Dmsg0(dbglvl, "Enter set_find_options()\n"); ff->incremental = incremental; ff->save_time = save_time; Dmsg0(dbglvl, "Leave set_find_options()\n"); } void set_find_changed_function(FF_PKT *ff, bool check_fct(JCR *jcr, FF_PKT *ff)) { Dmsg0(dbglvl, "Enter set_find_changed_function()\n"); ff->check_fct = check_fct; } /* * Call this subroutine with a callback subroutine as the first * argument and a packet as the second argument, this packet * will be passed back to the callback subroutine as the last * argument. */ int find_files(JCR *jcr, FF_PKT *ff, int file_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level), int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)) { ff->file_save = file_save; ff->plugin_save = plugin_save; /* This is the new way */ findFILESET *fileset = ff->fileset; if (fileset) { int i, j; /* * TODO: We probably need be move the initialization in the fileset loop, * at this place flags options are "concatenated" accross Include {} blocks * (not only Options{} blocks inside a Include{}) */ clear_all_bits(FO_MAX, ff->flags); for (i = 0; i < fileset->include_list.size(); i++) { dlistString *node; findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); fileset->incexe = incexe; /* * Here, we reset some values between two different Include{} */ strcpy(ff->VerifyOpts, "V"); strcpy(ff->AccurateOpts, "Cmcs"); /* mtime+ctime+size by default */ strcpy(ff->BaseJobOpts, "Jspug5"); /* size+perm+user+group+chk */ ff->plugin = NULL; ff->opt_plugin = false; /* * By setting all options, we in effect OR the global options which is what we want. */ for (j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo; fo = (findFOPTS *)incexe->opts_list.get(j); copy_bits(FO_MAX, fo->flags, ff->flags); ff->Compress_algo = fo->Compress_algo; ff->Compress_level = fo->Compress_level; ff->strip_path = fo->strip_path; ff->size_match = fo->size_match; ff->fstypes = fo->fstype; ff->drivetypes = fo->drivetype; if (fo->plugin != NULL) { ff->plugin = fo->plugin; /* TODO: generate a plugin event ? */ ff->opt_plugin = true; } bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts)); /* TODO: Concat or replace? */ if (fo->AccurateOpts[0]) { bstrncpy(ff->AccurateOpts, fo->AccurateOpts, sizeof(ff->AccurateOpts)); } if (fo->BaseJobOpts[0]) { bstrncpy(ff->BaseJobOpts, fo->BaseJobOpts, sizeof(ff->BaseJobOpts)); } } Dmsg4(50, "Verify=<%s> Accurate=<%s> BaseJob=<%s> flags=<%d>\n", ff->VerifyOpts, ff->AccurateOpts, ff->BaseJobOpts, ff->flags); foreach_dlist(node, &incexe->name_list) { char *fname = node->c_str(); Dmsg1(dbglvl, "F %s\n", fname); ff->top_fname = fname; if (find_one_file(jcr, ff, our_callback, ff->top_fname, (dev_t)-1, true) == 0) { return 0; /* error return */ } if (job_canceled(jcr)) { return 0; } } foreach_dlist(node, &incexe->plugin_list) { char *fname = node->c_str(); if (!plugin_save) { Jmsg(jcr, M_FATAL, 0, _("Plugin: \"%s\" not found.\n"), fname); return 0; } Dmsg1(dbglvl, "PluginCommand: %s\n", fname); ff->top_fname = fname; ff->cmd_plugin = true; plugin_save(jcr, ff, true); ff->cmd_plugin = false; if (job_canceled(jcr)) { return 0; } } } } return 1; } /* * Test if the currently selected directory (in ff->fname) is * explicitly in the Include list or explicitly in the Exclude list. */ bool is_in_fileset(FF_PKT *ff) { int i; char *fname; dlistString *node; findINCEXE *incexe; findFILESET *fileset = ff->fileset; if (fileset) { for (i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); foreach_dlist(node, &incexe->name_list) { fname = node->c_str(); Dmsg2(dbglvl, "Inc fname=%s ff->fname=%s\n", fname, ff->fname); if (bstrcmp(fname, ff->fname)) { return true; } } } for (i = 0; i < fileset->exclude_list.size(); i++) { incexe = (findINCEXE *)fileset->exclude_list.get(i); foreach_dlist(node, &incexe->name_list) { fname = node->c_str(); Dmsg2(dbglvl, "Exc fname=%s ff->fname=%s\n", fname, ff->fname); if (bstrcmp(fname, ff->fname)) { return true; } } } } return false; } bool accept_file(FF_PKT *ff) { int i, j, k; int fnm_flags; const char *basename; findFILESET *fileset = ff->fileset; findINCEXE *incexe = fileset->incexe; int (*match_func)(const char *pattern, const char *string, int flags); Dmsg1(dbglvl, "enter accept_file: fname=%s\n", ff->fname); if (bit_is_set(FO_ENHANCEDWILD, ff->flags)) { match_func = fnmatch; if ((basename = last_path_separator(ff->fname)) != NULL) basename++; else basename = ff->fname; } else { match_func = fnmatch; basename = ff->fname; } for (j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo; fo = (findFOPTS *)incexe->opts_list.get(j); copy_bits(FO_MAX, fo->flags, ff->flags); ff->Compress_algo = fo->Compress_algo; ff->Compress_level = fo->Compress_level; ff->fstypes = fo->fstype; ff->drivetypes = fo->drivetype; fnm_flags = bit_is_set(FO_IGNORECASE, ff->flags) ? FNM_CASEFOLD : 0; fnm_flags |= bit_is_set(FO_ENHANCEDWILD, ff->flags) ? FNM_PATHNAME : 0; if (S_ISDIR(ff->statp.st_mode)) { for (k = 0; k < fo->wilddir.size(); k++) { if (match_func((char *)fo->wilddir.get(k), ff->fname, fnmode | fnm_flags) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { Dmsg2(dbglvl, "Exclude wilddir: %s file=%s\n", (char *)fo->wilddir.get(k), ff->fname); return false; /* reject dir */ } return true; /* accept dir */ } } } else { for (k = 0; k < fo->wildfile.size(); k++) { if (match_func((char *)fo->wildfile.get(k), ff->fname, fnmode | fnm_flags) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { Dmsg2(dbglvl, "Exclude wildfile: %s file=%s\n", (char *)fo->wildfile.get(k), ff->fname); return false; /* reject file */ } return true; /* accept file */ } } for (k = 0; k < fo->wildbase.size(); k++) { if (match_func((char *)fo->wildbase.get(k), basename, fnmode | fnm_flags) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { Dmsg2(dbglvl, "Exclude wildbase: %s file=%s\n", (char *)fo->wildbase.get(k), basename); return false; /* reject file */ } return true; /* accept file */ } } } for (k = 0; k < fo->wild.size(); k++) { if (match_func((char *)fo->wild.get(k), ff->fname, fnmode | fnm_flags) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { Dmsg2(dbglvl, "Exclude wild: %s file=%s\n", (char *)fo->wild.get(k), ff->fname); return false; /* reject file */ } return true; /* accept file */ } } if (S_ISDIR(ff->statp.st_mode)) { for (k = 0; k < fo->regexdir.size(); k++) { if (regexec((regex_t *)fo->regexdir.get(k), ff->fname, 0, NULL, 0) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { return false; /* reject file */ } return true; /* accept file */ } } } else { for (k = 0; k < fo->regexfile.size(); k++) { if (regexec((regex_t *)fo->regexfile.get(k), ff->fname, 0, NULL, 0) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { return false; /* reject file */ } return true; /* accept file */ } } } for (k = 0; k < fo->regex.size(); k++) { if (regexec((regex_t *)fo->regex.get(k), ff->fname, 0, NULL, 0) == 0) { if (bit_is_set(FO_EXCLUDE, ff->flags)) { return false; /* reject file */ } return true; /* accept file */ } } /* * If we have an empty Options clause with exclude, then exclude the file */ if (bit_is_set(FO_EXCLUDE, ff->flags) && fo->regex.size() == 0 && fo->wild.size() == 0 && fo->regexdir.size() == 0 && fo->wilddir.size() == 0 && fo->regexfile.size() == 0 && fo->wildfile.size() == 0 && fo->wildbase.size() == 0) { Dmsg1(dbglvl, "Empty options, rejecting: %s\n", ff->fname); return false; /* reject file */ } } /* * Now apply the Exclude { } directive */ for (i = 0; i < fileset->exclude_list.size(); i++) { dlistString *node; findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); for (j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); fnm_flags = bit_is_set(FO_IGNORECASE, fo->flags) ? FNM_CASEFOLD : 0; for (k = 0; k < fo->wild.size(); k++) { if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode | fnm_flags) == 0) { Dmsg1(dbglvl, "Reject wild1: %s\n", ff->fname); return false; /* reject file */ } } } fnm_flags = (incexe->current_opts != NULL && bit_is_set(FO_IGNORECASE, incexe->current_opts->flags)) ? FNM_CASEFOLD : 0; foreach_dlist(node, &incexe->name_list) { char *fname = node->c_str(); if (fnmatch(fname, ff->fname, fnmode|fnm_flags) == 0) { Dmsg1(dbglvl, "Reject wild2: %s\n", ff->fname); return false; /* reject file */ } } } return true; } /* * The code comes here for each file examined. * We filter the files, then call the user's callback if the file is included. */ static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level) { if (top_level) { return ff->file_save(jcr, ff, top_level); /* accept file */ } switch (ff->type) { case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: case FT_NOCHG: case FT_ISARCH: case FT_NORECURSE: case FT_NOFSCHG: case FT_INVALIDFS: case FT_INVALIDDT: case FT_NOOPEN: // return ff->file_save(jcr, ff, top_level); /* These items can be filtered */ case FT_LNKSAVED: case FT_REGE: case FT_REG: case FT_LNK: case FT_DIRBEGIN: case FT_DIREND: case FT_RAW: case FT_FIFO: case FT_SPEC: case FT_DIRNOCHG: case FT_REPARSE: case FT_JUNCTION: if (accept_file(ff)) { return ff->file_save(jcr, ff, top_level); } else { Dmsg1(dbglvl, "Skip file %s\n", ff->fname); return -1; /* ignore this file */ } default: Dmsg1(000, "Unknown FT code %d\n", ff->type); return 0; } } /* * Terminate find_files() and release all allocated memory */ int term_find_files(FF_PKT *ff) { int hard_links; free_pool_memory(ff->sys_fname); if (ff->fname_save) { free_pool_memory(ff->fname_save); } if (ff->link_save) { free_pool_memory(ff->link_save); } if (ff->ignoredir_fname) { free_pool_memory(ff->ignoredir_fname); } hard_links = term_find_one(ff); free(ff); return hard_links; } /** * Allocate a new include/exclude block. */ findINCEXE *allocate_new_incexe(void) { findINCEXE *incexe; incexe = (findINCEXE *)malloc(sizeof(findINCEXE)); memset(incexe, 0, sizeof(findINCEXE)); incexe->opts_list.init(1, true); incexe->name_list.init(); incexe->plugin_list.init(); return incexe; } /** * Define a new Exclude block in the FileSet */ findINCEXE *new_exclude(findFILESET *fileset) { /* * New exclude */ fileset->incexe = allocate_new_incexe(); fileset->exclude_list.append(fileset->incexe); return fileset->incexe; } /** * Define a new Include block in the FileSet */ findINCEXE *new_include(findFILESET *fileset) { /* * New include */ fileset->incexe = allocate_new_incexe(); fileset->include_list.append(fileset->incexe); return fileset->incexe; } /** * Define a new preInclude block in the FileSet. * That is the include is prepended to the other * Includes. This is used for plugin exclusions. */ findINCEXE *new_preinclude(findFILESET *fileset) { /* * New pre-include */ fileset->incexe = allocate_new_incexe(); fileset->include_list.prepend(fileset->incexe); return fileset->incexe; } /* * Create a new exclude block and prepend it to the list of exclude blocks. */ findINCEXE *new_preexclude(findFILESET *fileset) { /* * New pre-exclude */ fileset->incexe = allocate_new_incexe(); fileset->exclude_list.prepend(fileset->incexe); return fileset->incexe; } findFOPTS *start_options(FF_PKT *ff) { int state = ff->fileset->state; findINCEXE *incexe = ff->fileset->incexe; if (state != state_options) { ff->fileset->state = state_options; findFOPTS *fo = (findFOPTS *)malloc(sizeof(findFOPTS)); memset(fo, 0, sizeof(findFOPTS)); fo->regex.init(1, true); fo->regexdir.init(1, true); fo->regexfile.init(1, true); fo->wild.init(1, true); fo->wilddir.init(1, true); fo->wildfile.init(1, true); fo->wildbase.init(1, true); fo->base.init(1, true); fo->fstype.init(1, true); fo->drivetype.init(1, true); incexe->current_opts = fo; incexe->opts_list.append(fo); } return incexe->current_opts; } /* * Used by plugins to define a new options block */ void new_options(FF_PKT *ff, findINCEXE *incexe) { findFOPTS *fo; fo = (findFOPTS *)malloc(sizeof(findFOPTS)); memset(fo, 0, sizeof(findFOPTS)); fo->regex.init(1, true); fo->regexdir.init(1, true); fo->regexfile.init(1, true); fo->wild.init(1, true); fo->wilddir.init(1, true); fo->wildfile.init(1, true); fo->wildbase.init(1, true); fo->base.init(1, true); fo->fstype.init(1, true); fo->drivetype.init(1, true); incexe->current_opts = fo; incexe->opts_list.prepend(fo); ff->fileset->state = state_options; } bareos-Release-14.2.6/src/findlib/find.h000066400000000000000000000235131263011562700177330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * File types as returned by find_files() * * Kern Sibbald MMI */ #ifndef __FIND_H #define __FIND_H #include "jcr.h" #include "fileopts.h" #include "bfile.h" #ifdef HAVE_DIRENT_H #include #define NAMELEN(dirent) (strlen((dirent)->d_name)) #endif #include #if !defined(HAVE_WIN32) || defined(HAVE_MINGW) #include #endif #if !defined(HAVE_UTIMES) && !defined(HAVE_LUTIMES) #if HAVE_UTIME_H #include #else struct utimbuf { long actime; long modtime; }; #endif #endif #define MODE_RALL (S_IRUSR|S_IRGRP|S_IROTH) #include "lib/fnmatch.h" #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif #ifndef HAVE_READDIR_R int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #endif /* * For options FO_xxx values see src/fileopts.h */ enum { state_none, state_options, state_include, state_error }; typedef enum { check_shadow_none, check_shadow_local_warn, check_shadow_local_remove, check_shadow_global_warn, check_shadow_global_remove } b_fileset_shadow_type; typedef enum { size_match_none, size_match_approx, size_match_smaller, size_match_greater, size_match_range } b_sz_match_type; struct s_sz_matching { b_sz_match_type type; uint64_t begin_size; uint64_t end_size; }; struct s_included_file { struct s_included_file *next; char options[FOPTS_BYTES]; /* Backup options */ uint32_t algo; /* Compression algorithm. 4 letters stored as an integer */ int level; /* Compression level */ int len; /* Length of fname */ int pattern; /* Set if wild card pattern */ struct s_sz_matching *size_match; /* Perform size matching ? */ b_fileset_shadow_type shadow_type; /* Perform fileset shadowing check ? */ char VerifyOpts[20]; /* Options for verify */ char fname[1]; }; struct s_excluded_file { struct s_excluded_file *next; int len; char fname[1]; }; #define MAX_OPTS 20 /* * File options structure */ struct findFOPTS { char flags[FOPTS_BYTES]; /* Backup options */ uint32_t Compress_algo; /* Compression algorithm. 4 letters stored as an integer */ int Compress_level; /* Compression level */ int strip_path; /* Strip path count */ struct s_sz_matching *size_match; /* Perform size matching ? */ b_fileset_shadow_type shadow_type; /* Perform fileset shadowing check ? */ char VerifyOpts[MAX_OPTS]; /* Verify options */ char AccurateOpts[MAX_OPTS] ; /* Accurate mode options */ char BaseJobOpts[MAX_OPTS]; /* Basejob mode options */ char *plugin; /* Plugin that handle this section */ alist regex; /* Regex string(s) */ alist regexdir; /* Regex string(s) for directories */ alist regexfile; /* Regex string(s) for files */ alist wild; /* Wild card strings */ alist wilddir; /* Wild card strings for directories */ alist wildfile; /* Wild card strings for files */ alist wildbase; /* Wild card strings for basenames */ alist base; /* List of base names */ alist fstype; /* File system type limitation */ alist drivetype; /* Drive type limitation */ }; /* * This is either an include item or an exclude item */ struct findINCEXE { findFOPTS *current_opts; /* Points to current options structure */ alist opts_list; /* Options list */ dlist name_list; /* Filename list -- holds dlistString */ dlist plugin_list; /* Plugin list -- holds dlistString */ alist ignoredir; /* Ignore directories with this file(s) */ }; /* * FileSet Resource */ struct findFILESET { int state; findINCEXE *incexe; /* Current item */ alist include_list; alist exclude_list; }; /* * OSX resource fork. */ struct HFSPLUS_INFO { unsigned long length; /* Mandatory field */ char fndrinfo[32]; /* Finder Info */ off_t rsrclength; /* Size of resource fork */ }; /* * Structure for keeping track of hard linked files, we * keep an entry for each hardlinked file that we save, * which is the first one found. For all the other files that * are linked to this one, we save only the directory * entry so we can link it. */ struct CurLink { struct hlink link; dev_t dev; /* Device */ ino_t ino; /* Inode with device is unique */ uint32_t FileIndex; /* Bareos FileIndex of this file */ int32_t digest_stream; /* Digest type if needed */ uint32_t digest_len; /* Digest len if needed */ char *digest; /* Checksum of the file if needed */ char name[1]; /* The name */ }; /* * Definition of the find_files packet passed as the * first argument to the find_files callback subroutine. */ struct FF_PKT { char *top_fname; /* Full filename before descending */ char *fname; /* Full filename */ char *link; /* Link if file linked */ char *object_name; /* Object name */ char *object; /* Restore object */ char *plugin; /* Current Options{Plugin=} name */ POOLMEM *sys_fname; /* System filename */ POOLMEM *fname_save; /* Save when stripping path */ POOLMEM *link_save; /* Save when stripping path */ POOLMEM *ignoredir_fname; /* Used to ignore directories */ char *digest; /* Set to file digest when the file is a hardlink */ struct stat statp; /* Stat packet */ uint32_t digest_len; /* Set to the digest len when the file is a hardlink*/ int32_t digest_stream; /* Set to digest type when the file is hardlink */ int32_t FileIndex; /* FileIndex of this file */ int32_t LinkFI; /* FileIndex of main hard linked file */ int32_t delta_seq; /* Delta Sequence number */ int32_t object_index; /* Object index */ int32_t object_len; /* Object length */ int32_t object_compression; /* Type of compression for object */ int type; /* FT_ type from above */ int ff_errno; /* Errno */ BFILE bfd; /* Bareos file descriptor */ time_t save_time; /* Start of incremental time */ bool accurate_found; /* Found in the accurate hash (valid after check_changes()) */ bool dereference; /* Follow links (not implemented) */ bool null_output_device; /* Using null output device */ bool incremental; /* Incremental save */ bool no_read; /* Do not read this file when using Plugin */ char VerifyOpts[MAX_OPTS]; char AccurateOpts[MAX_OPTS]; char BaseJobOpts[MAX_OPTS]; struct s_included_file *included_files_list; struct s_excluded_file *excluded_files_list; struct s_excluded_file *excluded_paths_list; findFILESET *fileset; int (*file_save)(JCR *, FF_PKT *, bool); /* User's callback */ int (*plugin_save)(JCR *, FF_PKT *, bool); /* User's callback */ bool (*check_fct)(JCR *, FF_PKT *); /* Optionnal user fct to check file changes */ /* * Values set by accept_file while processing Options */ char flags[FOPTS_BYTES]; /* Backup options */ uint32_t Compress_algo; /* Compression algorithm. 4 letters stored as an integer */ int Compress_level; /* Compression level */ int strip_path; /* Strip path count */ struct s_sz_matching *size_match; /* Perform size matching ? */ bool cmd_plugin; /* Set if we have a command plugin */ bool opt_plugin; /* Set if we have an option plugin */ alist fstypes; /* Allowed file system types */ alist drivetypes; /* Allowed drive types */ /* * List of all hard linked files found */ htable *linkhash; /* Hard linked files */ struct CurLink *linked; /* Set if this file is hard linked */ /* * Darwin specific things. * To avoid clutter, we always include rsrc_bfd and volhas_attrlist. */ BFILE rsrc_bfd; /* Fd for resource forks */ bool volhas_attrlist; /* Volume supports getattrlist() */ struct HFSPLUS_INFO hfsinfo; /* Finder Info and resource fork size */ }; #include "acl.h" #include "xattr.h" #include "protos.h" #endif /* __FILES_H */ bareos-Release-14.2.6/src/findlib/find_one.c000066400000000000000000000733001263011562700205660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file was derived from GNU TAR source code. Except for a few key * ideas, it has been entirely rewritten for Bareos. * * Kern Sibbald, MM * * Thanks to the TAR programmers. */ #include "bareos.h" #include "find.h" #ifdef HAVE_DARWIN_OS #include #include #include #endif extern int32_t name_max; /* filename max length */ extern int32_t path_max; /* path name max length */ /* * Create a new directory Find File packet, but copy * some of the essential info from the current packet. * However, be careful to zero out the rest of the * packet. */ static inline FF_PKT *new_dir_ff_pkt(FF_PKT *ff_pkt) { FF_PKT *dir_ff_pkt; dir_ff_pkt = (FF_PKT *)bmalloc(sizeof(FF_PKT)); memcpy(dir_ff_pkt, ff_pkt, sizeof(FF_PKT)); dir_ff_pkt->fname = bstrdup(ff_pkt->fname); dir_ff_pkt->link = bstrdup(ff_pkt->link); dir_ff_pkt->sys_fname = get_pool_memory(PM_FNAME); dir_ff_pkt->included_files_list = NULL; dir_ff_pkt->excluded_files_list = NULL; dir_ff_pkt->excluded_paths_list = NULL; dir_ff_pkt->linkhash = NULL; dir_ff_pkt->fname_save = NULL; dir_ff_pkt->link_save = NULL; dir_ff_pkt->ignoredir_fname = NULL; return dir_ff_pkt; } /* * Free the temp directory ff_pkt */ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) { free(dir_ff_pkt->fname); free(dir_ff_pkt->link); free_pool_memory(dir_ff_pkt->sys_fname); if (dir_ff_pkt->fname_save) { free_pool_memory(dir_ff_pkt->fname_save); } if (dir_ff_pkt->link_save) { free_pool_memory(dir_ff_pkt->link_save); } if (dir_ff_pkt->ignoredir_fname) { free_pool_memory(dir_ff_pkt->ignoredir_fname); } free(dir_ff_pkt); } /* * Check to see if we allow the file system type of a file or directory. * If we do not have a list of file system types, we accept anything. */ static int accept_fstype(FF_PKT *ff, void *dummy) { int i; char fs[1000]; bool accept = true; if (ff->fstypes.size()) { accept = false; if (!fstype(ff->fname, fs, sizeof(fs))) { Dmsg1(50, "Cannot determine file system type for \"%s\"\n", ff->fname); } else { for (i = 0; i < ff->fstypes.size(); ++i) { if (bstrcmp(fs, (char *)ff->fstypes.get(i))) { Dmsg2(100, "Accepting fstype %s for \"%s\"\n", fs, ff->fname); accept = true; break; } Dmsg3(200, "fstype %s for \"%s\" does not match %s\n", fs, ff->fname, ff->fstypes.get(i)); } } } return accept; } /* * Check to see if we allow the drive type of a file or directory. * If we do not have a list of drive types, we accept anything. */ static inline int accept_drivetype(FF_PKT *ff, void *dummy) { int i; char dt[100]; bool accept = true; if (ff->drivetypes.size()) { accept = false; if (!drivetype(ff->fname, dt, sizeof(dt))) { Dmsg1(50, "Cannot determine drive type for \"%s\"\n", ff->fname); } else { for (i = 0; i < ff->drivetypes.size(); ++i) { if (bstrcmp(dt, (char *)ff->drivetypes.get(i))) { Dmsg2(100, "Accepting drive type %s for \"%s\"\n", dt, ff->fname); accept = true; break; } Dmsg3(200, "drive type %s for \"%s\" does not match %s\n", dt, ff->fname, ff->drivetypes.get(i)); } } } return accept; } /* * This function determines whether we can use getattrlist() * It's odd, but we have to use the function to determine that... * Also, the man pages talk about things as if they were implemented. * * On Mac OS X, this succesfully differentiates between HFS+ and UFS * volumes, which makes me trust it is OK for others, too. */ static bool volume_has_attrlist(const char *fname) { #ifdef HAVE_DARWIN_OS struct statfs st; struct volinfo_struct { unsigned long length; /* Mandatory field */ vol_capabilities_attr_t info; /* Volume capabilities */ } vol; struct attrlist attrList; memset(&attrList, 0, sizeof(attrList)); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.volattr = ATTR_VOL_INFO | ATTR_VOL_CAPABILITIES; if (statfs(fname, &st) == 0) { /* * We need to check on the mount point */ if (getattrlist(st.f_mntonname, &attrList, &vol, sizeof(vol), FSOPT_NOFOLLOW) == 0 && (vol.info.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_ATTRLIST) && (vol.info.valid[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_ATTRLIST)) { return true; } } #endif return false; } /* * check for BSD nodump flag */ static inline bool no_dump(JCR *jcr, FF_PKT *ff_pkt) { #if defined(HAVE_CHFLAGS) && defined(UF_NODUMP) if (bit_is_set(FO_HONOR_NODUMP, ff_pkt->flags) && (ff_pkt->statp.st_flags & UF_NODUMP) ) { Jmsg(jcr, M_INFO, 1, _(" NODUMP flag set - will not process %s\n"), ff_pkt->fname); return true; /* do not backup this file */ } #endif return false; /* do backup */ } /* * check for sizes */ static inline bool check_size_matching(JCR *jcr, FF_PKT *ff_pkt) { ssize_t begin_size, end_size, difference; /* * See if size matching is turned on. */ if (!ff_pkt->size_match) { return true; } /* * Loose the unsigned bits to keep the compiler from warning * about comparing signed and unsigned. As a size of a file * can only be positive the unsigned is not really to interesting. */ begin_size = ff_pkt->size_match->begin_size; end_size = ff_pkt->size_match->end_size; /* * See what kind of matching should be done. */ switch (ff_pkt->size_match->type) { case size_match_approx: /* * Calculate the fraction this size is of the wanted size. */ if ((ssize_t)ff_pkt->statp.st_size > begin_size) { difference = ff_pkt->statp.st_size - begin_size; } else { difference = begin_size - ff_pkt->statp.st_size; } /* * See if the difference is less then 1% of the total. */ return (difference < (begin_size / 100)); case size_match_smaller: return (ssize_t)ff_pkt->statp.st_size < begin_size; case size_match_greater: return (ssize_t)ff_pkt->statp.st_size > begin_size; case size_match_range: return ((ssize_t)ff_pkt->statp.st_size >= begin_size) && ((ssize_t)ff_pkt->statp.st_size <= end_size); default: return true; } } /* * Check if a file have changed during backup and display an error */ bool has_file_changed(JCR *jcr, FF_PKT *ff_pkt) { struct stat statp; Dmsg1(500, "has_file_changed fname=%s\n",ff_pkt->fname); if (ff_pkt->type != FT_REG) { /* not a regular file */ return false; } if (lstat(ff_pkt->fname, &statp) != 0) { berrno be; Jmsg(jcr, M_WARNING, 0, _("Cannot stat file %s: ERR=%s\n"),ff_pkt->fname,be.bstrerror()); return true; } if (statp.st_mtime != ff_pkt->statp.st_mtime) { Jmsg(jcr, M_ERROR, 0, _("%s: mtime changed during backup.\n"), ff_pkt->fname); Dmsg3(50, "%s mtime (%lld) changed during backup (%lld).\n", ff_pkt->fname, (int64_t)ff_pkt->statp.st_mtime, (int64_t)statp.st_mtime); return true; } if (statp.st_ctime != ff_pkt->statp.st_ctime) { Jmsg(jcr, M_ERROR, 0, _("%s: ctime changed during backup.\n"), ff_pkt->fname); Dmsg3(50, "%s ctime (%lld) changed during backup (%lld).\n", ff_pkt->fname, (int64_t)ff_pkt->statp.st_ctime, (int64_t)statp.st_ctime); return true; } if (statp.st_size != ff_pkt->statp.st_size) { /* TODO: add size change */ Jmsg(jcr, M_ERROR, 0, _("%s: size changed during backup.\n"),ff_pkt->fname); Dmsg3(50, "%s size (%lld) changed during backup (%lld).\n", ff_pkt->fname, (int64_t)ff_pkt->statp.st_size, (int64_t)statp.st_size); return true; } if ((statp.st_blksize != ff_pkt->statp.st_blksize) || (statp.st_blocks != ff_pkt->statp.st_blocks)) { Jmsg(jcr, M_ERROR, 0, _("%s: size changed during backup.\n"),ff_pkt->fname); Dmsg3(50, "%s size (%lld) changed during backup (%lld).\n", ff_pkt->fname, (int64_t)ff_pkt->statp.st_blocks, (int64_t)statp.st_blocks); return true; } return false; } /* * For incremental/diffential or accurate backups, we * determine if the current file has changed. */ bool check_changes(JCR *jcr, FF_PKT *ff_pkt) { /* * In special mode (like accurate backup), the programmer can * choose his comparison function. */ if (ff_pkt->check_fct) { return ff_pkt->check_fct(jcr, ff_pkt); } /* * For normal backups (incr/diff), we use this default behaviour */ if (ff_pkt->incremental && (ff_pkt->statp.st_mtime < ff_pkt->save_time && (bit_is_set(FO_MTIMEONLY, ff_pkt->flags) || ff_pkt->statp.st_ctime < ff_pkt->save_time))) { return false; } return true; } static inline bool have_ignoredir(FF_PKT *ff_pkt) { struct stat sb; char *ignoredir; /* * Ensure that pointers are defined */ if (!ff_pkt->fileset || !ff_pkt->fileset->incexe) { return false; } for (int i = 0; i < ff_pkt->fileset->incexe->ignoredir.size(); i++) { ignoredir = (char *)ff_pkt->fileset->incexe->ignoredir.get(i); if (ignoredir) { if (!ff_pkt->ignoredir_fname) { ff_pkt->ignoredir_fname = get_pool_memory(PM_FNAME); } Mmsg(ff_pkt->ignoredir_fname, "%s/%s", ff_pkt->fname, ignoredir); if (stat(ff_pkt->ignoredir_fname, &sb) == 0) { Dmsg2(100, "Directory '%s' ignored (found %s)\n", ff_pkt->fname, ignoredir); return true; /* Just ignore this directory */ } } } return false; } /* * Restore file times. */ static inline void restore_file_times(FF_PKT *ff_pkt, char *fname) { #if defined(HAVE_LUTIMES) struct timeval restore_times[2]; restore_times[0].tv_sec = ff_pkt->statp.st_atime; restore_times[0].tv_usec = 0; restore_times[1].tv_sec = ff_pkt->statp.st_mtime; restore_times[1].tv_usec = 0; lutimes(fname, restore_times); #elif defined(HAVE_UTIMES) struct timeval restore_times[2]; restore_times[0].tv_sec = ff_pkt->statp.st_atime; restore_times[0].tv_usec = 0; restore_times[1].tv_sec = ff_pkt->statp.st_mtime; restore_times[1].tv_usec = 0; utimes(fname, restore_times); #else struct utimbuf restore_times; restore_times.actime = ff_pkt->statp.st_atime; restore_times.modtime = ff_pkt->statp.st_mtime; utime(fname, &restore_times); #endif } #ifdef HAVE_DARWIN_OS /* * Handling of a HFS+ attributes. */ static inline int process_hfsattributes(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, bool top_level) { /* * TODO: initialise attrList once elsewhere? */ struct attrlist attrList; memset(&attrList, 0, sizeof(attrList)); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.commonattr = ATTR_CMN_FNDRINFO; attrList.fileattr = ATTR_FILE_RSRCLENGTH; if (getattrlist(fname, &attrList, &ff_pkt->hfsinfo, sizeof(ff_pkt->hfsinfo), FSOPT_NOFOLLOW) != 0) { ff_pkt->type = FT_NOSTAT; ff_pkt->ff_errno = errno; return handle_file(jcr, ff_pkt, top_level); } return -1; } #endif /* * Handling of a hardlinked file. */ static inline int process_hardlink(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, bool top_level, bool *done) { int rtn_stat = 0; CurLink *hl; hl = lookup_hardlink(jcr, ff_pkt, ff_pkt->statp.st_ino, ff_pkt->statp.st_dev); if (hl) { /* * If we have already backed up the hard linked file don't do it again */ if (bstrcmp(hl->name, fname)) { Dmsg2(400, "== Name identical skip FI=%d file=%s\n", hl->FileIndex, fname); *done = true; return 1; /* ignore */ } ff_pkt->link = hl->name; ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */ ff_pkt->LinkFI = hl->FileIndex; ff_pkt->linked = NULL; ff_pkt->digest = hl->digest; ff_pkt->digest_stream = hl->digest_stream; ff_pkt->digest_len = hl->digest_len; rtn_stat = handle_file(jcr, ff_pkt, top_level); Dmsg3(400, "FT_LNKSAVED FI=%d LinkFI=%d file=%s\n", ff_pkt->FileIndex, hl->FileIndex, hl->name); *done = true; } else { /* * File not previously dumped. Chain it into our list. */ hl = new_hardlink(jcr, ff_pkt, fname, ff_pkt->statp.st_ino, ff_pkt->statp.st_dev); ff_pkt->linked = hl; /* Mark saved link */ Dmsg2(400, "Added to hash FI=%d file=%s\n", ff_pkt->FileIndex, hl->name); *done = false; } return rtn_stat; } /* * Handling of a regular file. */ static inline int process_regular_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, bool top_level) { int rtn_stat; boffset_t sizeleft; sizeleft = ff_pkt->statp.st_size; /* * Don't bother opening empty, world readable files. Also do not open * files when archive is meant for /dev/null. */ if (ff_pkt->null_output_device || (sizeleft == 0 && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) { ff_pkt->type = FT_REGE; } else { ff_pkt->type = FT_REG; } rtn_stat = handle_file(jcr, ff_pkt, top_level); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } Dmsg3(400, "FT_REG FI=%d linked=%d file=%s\n", ff_pkt->FileIndex, ff_pkt->linked ? 1 : 0, fname); if (bit_is_set(FO_KEEPATIME, ff_pkt->flags)) { restore_file_times(ff_pkt, fname); } return rtn_stat; } /* * Handling of a symlink. */ static inline int process_symlink(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, bool top_level) { int rtn_stat; int size; char *buffer = (char *)alloca(path_max + name_max + 102); size = readlink(fname, buffer, path_max + name_max + 101); if (size < 0) { /* * Could not follow link */ ff_pkt->type = FT_NOFOLLOW; ff_pkt->ff_errno = errno; rtn_stat = handle_file(jcr, ff_pkt, top_level); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; } buffer[size] = 0; ff_pkt->link = buffer; /* point to link */ ff_pkt->type = FT_LNK; /* got a real link */ rtn_stat = handle_file(jcr, ff_pkt, top_level); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; } /* * Handling of a directory. */ static inline int process_directory(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, dev_t parent_device, bool top_level) { int rtn_stat; DIR *directory; struct dirent *entry, *result; char *link; int link_len; int len; int status; dev_t our_device = ff_pkt->statp.st_dev; bool recurse = true; bool volhas_attrlist = ff_pkt->volhas_attrlist; /* Remember this if we recurse */ /* * Ignore this directory and everything below if the file .nobackup * (or what is defined for IgnoreDir in this fileset) exists */ if (have_ignoredir(ff_pkt)) { return 1; /* Just ignore this directory */ } /* * Build a canonical directory name with a trailing slash in link var */ len = strlen(fname); link_len = len + 200; link = (char *)bmalloc(link_len + 2); bstrncpy(link, fname, link_len); /* * Strip all trailing slashes */ while (len >= 1 && IsPathSeparator(link[len - 1])) { len--; } link[len++] = '/'; /* add back one */ link[len] = 0; ff_pkt->link = link; if (!check_changes(jcr, ff_pkt)) { /* * Incremental/Full+Base option, directory entry not changed */ ff_pkt->type = FT_DIRNOCHG; } else { ff_pkt->type = FT_DIRBEGIN; } bool is_win32_mount_point = false; #if defined(HAVE_WIN32) is_win32_mount_point = ff_pkt->statp.st_rdev & FILE_ATTRIBUTE_VOLUME_MOUNT_POINT; if (ff_pkt->statp.st_rdev & FILE_ATTRIBUTE_REPARSE_POINT) { ff_pkt->type = FT_REPARSE; } /* treat win32 mount points (Volume Mount Points) as directories */ if (is_win32_mount_point) { ff_pkt->type = FT_DIRBEGIN; } #endif /* * Note, we return the directory to the calling program (handle_file) * when we first see the directory (FT_DIRBEGIN. * This allows the program to apply matches and make a * choice whether or not to accept it. If it is accepted, we * do not immediately save it, but do so only after everything * in the directory is seen (i.e. the FT_DIREND). */ rtn_stat = handle_file(jcr, ff_pkt, top_level); if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE) { /* ignore or error status */ free(link); return rtn_stat; } /* * Done with DIRBEGIN, next call will be DIREND */ if (ff_pkt->type == FT_DIRBEGIN) { ff_pkt->type = FT_DIREND; } /* * Create a temporary ff packet for this directory * entry, and defer handling the directory until * we have recursed into it. This saves the * directory after all files have been processed, and * during the restore, the directory permissions will * be reset after all the files have been restored. */ Dmsg1(300, "Create temp ff packet for dir: %s\n", ff_pkt->fname); FF_PKT *dir_ff_pkt = new_dir_ff_pkt(ff_pkt); /* * Do not descend into subdirectories (recurse) if the * user has turned it off for this directory. * * If we are crossing file systems, we are either not allowed * to cross, or we may be restricted by a list of permitted * file systems. */ if (!top_level && bit_is_set(FO_NO_RECURSION, ff_pkt->flags)) { ff_pkt->type = FT_NORECURSE; recurse = false; } else if (!top_level && (parent_device != ff_pkt->statp.st_dev || is_win32_mount_point)) { if(!bit_is_set(FO_MULTIFS, ff_pkt->flags)) { ff_pkt->type = FT_NOFSCHG; recurse = false; } else if (!accept_fstype(ff_pkt, NULL)) { ff_pkt->type = FT_INVALIDFS; recurse = false; } else { ff_pkt->volhas_attrlist = volume_has_attrlist(fname); } } /* * If not recursing, just backup dir and return */ if (!recurse) { rtn_stat = handle_file(jcr, ff_pkt, top_level); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } free(link); free_dir_ff_pkt(dir_ff_pkt); ff_pkt->link = ff_pkt->fname; /* reset "link" */ if (bit_is_set(FO_KEEPATIME, ff_pkt->flags)) { restore_file_times(ff_pkt, fname); } return rtn_stat; } ff_pkt->link = ff_pkt->fname; /* reset "link" */ /* * Descend into or "recurse" into the directory to read all the files in it. */ errno = 0; if ((directory = opendir(fname)) == NULL) { ff_pkt->type = FT_NOOPEN; ff_pkt->ff_errno = errno; rtn_stat = handle_file(jcr, ff_pkt, top_level); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } free(link); free_dir_ff_pkt(dir_ff_pkt); return rtn_stat; } /* * Process all files in this directory entry (recursing). * This would possibly run faster if we chdir to the directory * before traversing it. */ rtn_stat = 1; /* * Allocate some extra room so an overflow of the d_name with more then * name_max bytes doesn't kill us right away. We check in the loop if * an overflow has not happened. */ entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100); while (!job_canceled(jcr)) { int name_length; status = readdir_r(directory, entry, &result); if (status != 0 || result == NULL) { // Dmsg2(99, "readdir returned stat=%d result=0x%x\n", // status, (long)result); break; } name_length = (int)NAMELEN(entry); /* * Some filesystems violate against the rules and return filenames * longer then _PC_NAME_MAX. Log the error and continue. */ if ((name_max + 1) <= ((int)sizeof(struct dirent) + name_length)) { Jmsg2(jcr, M_ERROR, 0, _("%s: File name too long [%d]\n"), entry->d_name, name_length); continue; } /* * Skip `.', `..', and excluded file names. */ if (entry->d_name[0] == '\0' || (entry->d_name[0] == '.' && (entry->d_name[1] == '\0' || (entry->d_name[1] == '.' && entry->d_name[2] == '\0')))) { continue; } /* * Make sure there is enough room to store the whole name. */ if (name_length + len >= link_len) { link_len = len + name_length + 1; link = (char *)brealloc(link, link_len + 1); } memcpy(link + len, entry->d_name, name_length); link[len + name_length] = '\0'; if (!file_is_excluded(ff_pkt, link)) { rtn_stat = find_one_file(jcr, ff_pkt, handle_file, link, our_device, false); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } } } closedir(directory); free(link); free(entry); /* * Now that we have recursed through all the files in the * directory, we "save" the directory so that after all * the files are restored, this entry will serve to reset * the directory modes and dates. Temp directory values * were used without this record. */ handle_file(jcr, dir_ff_pkt, top_level); /* handle directory entry */ if (ff_pkt->linked) { ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex; } free_dir_ff_pkt(dir_ff_pkt); if (bit_is_set(FO_KEEPATIME, ff_pkt->flags)) { restore_file_times(ff_pkt, fname); } ff_pkt->volhas_attrlist = volhas_attrlist; /* Restore value in case it changed. */ return rtn_stat; } /* * Handling of a special file. */ static inline int process_special_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, bool top_level) { int rtn_stat; /* * If it is explicitly mentioned (i.e. top_level) and is * a block device, we do a raw backup of it or if it is * a fifo, we simply read it. */ #ifdef HAVE_FREEBSD_OS /* * On FreeBSD, all block devices are character devices, so * to be able to read a raw disk, we need the check for * a character device. * * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/ad0s3 * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/rad0s3 */ if (top_level && (S_ISBLK(ff_pkt->statp.st_mode) || S_ISCHR(ff_pkt->statp.st_mode))) { #else if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) { #endif ff_pkt->type = FT_RAW; /* raw partition */ } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) && bit_is_set(FO_READFIFO, ff_pkt->flags)) { ff_pkt->type = FT_FIFO; } else { /* * The only remaining types are special (character, ...) files */ ff_pkt->type = FT_SPEC; } rtn_stat = handle_file(jcr, ff_pkt, top_level); if (ff_pkt->linked) { ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; } /* * See if we need to perform any processing for a given file. */ static inline int needs_processing(JCR *jcr, FF_PKT *ff_pkt, char *fname) { if (!accept_fstype(ff_pkt, NULL)) { ff_pkt->type = FT_INVALIDFS; if (bit_is_set(FO_KEEPATIME, ff_pkt->flags)) { restore_file_times(ff_pkt, fname); } char fs[100]; if (!fstype(ff_pkt->fname, fs, sizeof(fs))) { bstrncpy(fs, "unknown", sizeof(fs)); } Jmsg(jcr, M_INFO, 0, _("Top level directory \"%s\" has unlisted fstype \"%s\"\n"), fname, fs); return 1; /* Just ignore this error - or the whole backup is cancelled */ } if (!accept_drivetype(ff_pkt, NULL)) { ff_pkt->type = FT_INVALIDDT; if (bit_is_set(FO_KEEPATIME, ff_pkt->flags)) { restore_file_times(ff_pkt, fname); } char dt[100]; if (!drivetype(ff_pkt->fname, dt, sizeof(dt))) { bstrncpy(dt, "unknown", sizeof(dt)); } Jmsg(jcr, M_INFO, 0, _("Top level directory \"%s\" has an unlisted drive type \"%s\"\n"), fname, dt); return 1; /* Just ignore this error - or the whole backup is cancelled */ } ff_pkt->volhas_attrlist = volume_has_attrlist(fname); return 0; } /* * Find a single file. * * handle_file is the callback for handling the file. * p is the filename * parent_device is the device we are currently on * top_level is 1 when not recursing or 0 when descending into a directory. */ int find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(JCR *jcr, FF_PKT *ff, bool top_level), char *fname, dev_t parent_device, bool top_level) { int rtn_stat; bool done = false; ff_pkt->fname = ff_pkt->link = fname; ff_pkt->type = FT_UNSET; if (lstat(fname, &ff_pkt->statp) != 0) { /* * Cannot stat file */ ff_pkt->type = FT_NOSTAT; ff_pkt->ff_errno = errno; return handle_file(jcr, ff_pkt, top_level); } Dmsg1(300, "File ----: %s\n", fname); /* * We check for allowed fstypes and drivetypes at top_level and fstype change (below). */ if (top_level) { if (needs_processing(jcr, ff_pkt, fname) == 1) return 1; } /* * Ignore this entry if no_dump() returns true */ if (no_dump(jcr, ff_pkt)) { Dmsg1(100, "'%s' ignored (NODUMP flag set)\n", ff_pkt->fname); return 1; } switch (ff_pkt->statp.st_mode & S_IFMT) { case S_IFDIR: break; case S_IFREG: if (!check_size_matching(jcr, ff_pkt)) { Dmsg1(100, "'%s' ignored (Size doesn't match\n", ff_pkt->fname); return 1; } /* * Fall Through */ default: /* * If this is an Incremental backup, see if file was modified * since our last "save_time", presumably the last Full save * or Incremental. */ if (!check_changes(jcr, ff_pkt)) { Dmsg1(500, "Non-directory incremental: %s\n", ff_pkt->fname); ff_pkt->type = FT_NOCHG; return handle_file(jcr, ff_pkt, top_level); } break; } #ifdef HAVE_DARWIN_OS if (bit_is_set(FO_HFSPLUS, ff_pkt->flags) && ff_pkt->volhas_attrlist && S_ISREG(ff_pkt->statp.st_mode)) { rtn_stat = process_hfsattributes(jcr, ff_pkt, handle_file, fname, top_level); if (rtn_stat != -1) { return rtn_stat; } } #endif ff_pkt->LinkFI = 0; /* * Handle hard linked files * * Maintain a list of hard linked files already backed up. This * allows us to ensure that the data of each file gets backed * up only once. */ if (!bit_is_set(FO_NO_HARDLINK, ff_pkt->flags) && ff_pkt->statp.st_nlink > 1) { switch (ff_pkt->statp.st_mode & S_IFMT) { case S_IFREG: case S_IFCHR: case S_IFBLK: case S_IFIFO: #ifdef S_IFSOCK case S_IFSOCK: #endif /* * Via the done variable the process_hardlink function returns * if file processing is done. If done is set to false we continue * with the normal processing of the file. */ rtn_stat = process_hardlink(jcr, ff_pkt, handle_file, fname, top_level, &done); if (done) { return rtn_stat; } break; default: ff_pkt->linked = NULL; break; } } else { ff_pkt->linked = NULL; } /* * Based on the type of file call the correct function. * This is not a link to a previously dumped file, so dump it. */ switch (ff_pkt->statp.st_mode & S_IFMT) { case S_IFREG: return process_regular_file(jcr, ff_pkt, handle_file, fname, top_level); #ifdef S_IFLNK case S_IFLNK: return process_symlink(jcr, ff_pkt, handle_file, fname, top_level); #endif case S_IFDIR: return process_directory(jcr, ff_pkt, handle_file, fname, parent_device, top_level); default: return process_special_file(jcr, ff_pkt, handle_file, fname, top_level); } } int term_find_one(FF_PKT *ff) { int count; if (ff->linkhash == NULL) { return 0; } count = ff->linkhash->size(); ff->linkhash->destroy(); free(ff->linkhash); ff->linkhash = NULL; return count; } bareos-Release-14.2.6/src/findlib/fstype.c000066400000000000000000000133561263011562700203240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Implement routines to determine file system types. * * Written by Preben 'Peppe' Guldberg, December MMIV */ #ifndef TEST_PROGRAM #include "bareos.h" #include "find.h" #else /* Set up for testing a stand alone program */ #include #include #include #define SUPPORTEDOSES \ "HAVE_DARWIN_OS\n" \ "HAVE_FREEBSD_OS\n" \ "HAVE_HPUX_OS\n" \ "HAVE_IRIX_OS\n" \ "HAVE_LINUX_OS\n" \ "HAVE_NETBSD_OS\n" \ "HAVE_OPENBSD_OS\n" \ "HAVE_SUN_OS\n" \ "HAVE_OSF1_OS\n" \ "HAVE_WIN32\n" #define false 0 #define true 1 #define bstrncpy strncpy #define bstrcmp(s1, s2) !strcmp(s1, s2) #define Dmsg0(n,s) fprintf(stderr, s) #define Dmsg1(n,s,a1) fprintf(stderr, s, a1) #define Dmsg2(n,s,a1,a2) fprintf(stderr, s, a1, a2) #endif /* * These functions should be implemented for each OS * * bool fstype(const char *fname, char *fs, int fslen); */ #if defined(HAVE_DARWIN_OS) || \ defined(HAVE_FREEBSD_OS) || \ defined(HAVE_OPENBSD_OS) #include #include bool fstype(const char *fname, char *fs, int fslen) { struct statfs st; if (statfs(fname, &st) == 0) { bstrncpy(fs, st.f_fstypename, fslen); return true; } Dmsg1(50, "statfs() failed for \"%s\"\n", fname); return false; } #elif defined(HAVE_NETBSD_OS) #include #include #ifdef HAVE_SYS_STATVFS_H #include #else #define statvfs statfs #endif bool fstype(const char *fname, char *fs, int fslen) { struct statvfs st; if (statvfs(fname, &st) == 0) { bstrncpy(fs, st.f_fstypename, fslen); return true; } Dmsg1(50, "statfs() failed for \"%s\"\n", fname); return false; } #elif defined(HAVE_HPUX_OS) || \ defined(HAVE_IRIX_OS) #include #include bool fstype(const char *fname, char *fs, int fslen) { struct statvfs st; if (statvfs(fname, &st) == 0) { bstrncpy(fs, st.f_basetype, fslen); return true; } Dmsg1(50, "statfs() failed for \"%s\"\n", fname); return false; } #elif defined(HAVE_LINUX_OS) || \ defined(HAVE_OSF1_OS) #include #include "lib/mntent_cache.h" bool fstype(const char *fname, char *fs, int fslen) { struct stat st; mntent_cache_entry_t *mce; if (lstat(fname, &st) == 0) { if ((mce = find_mntent_mapping(st.st_dev)) != NULL) { bstrncpy(fs, mce->fstype, fslen); release_mntent_mapping(mce); return true; } return false; } Dmsg1(50, "lstat() failed for \"%s\"\n", fname); return false; } #elif defined(HAVE_SUN_OS) #include #include bool fstype(const char *fname, char *fs, int fslen) { struct stat st; if (lstat(fname, &st) == 0) { bstrncpy(fs, st.st_fstype, fslen); return true; } Dmsg1(50, "lstat() failed for \"%s\"\n", fname); return false; } #elif defined (HAVE_WIN32) /* Windows */ bool fstype(const char *fname, char *fs, int fslen) { DWORD componentlength; DWORD fsflags; CHAR rootpath[4]; UINT oldmode; BOOL result; /* Copy Drive Letter, colon, and backslash to rootpath */ bstrncpy(rootpath, fname, sizeof(rootpath)); /* We don't want any popups if there isn't any media in the drive */ oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); result = GetVolumeInformation(rootpath, NULL, 0, NULL, &componentlength, &fsflags, fs, fslen); SetErrorMode(oldmode); if (result) { /* Windows returns NTFS, FAT, etc. Make it lowercase to be consistent with other OSes */ lcase(fs); } else { Dmsg2(10, "GetVolumeInformation() failed for \"%s\", Error = %d.\n", rootpath, GetLastError()); } return result != 0; } /* Windows */ #else /* No recognised OS */ bool fstype(const char *fname, char *fs, int fslen) { Dmsg0(10, "!!! fstype() not implemented for this OS. !!!\n"); #ifdef TEST_PROGRAM Dmsg1(10, "Please define one of the following when compiling:\n\n%s\n", SUPPORTEDOSES); exit(EXIT_FAILURE); #endif return false; } #endif /* * Compare function build on top of fstype, OS independent. * * bool fstype_equals(const char *fname, const char *fstypename); */ bool fstype_equals(const char *fname, const char *fstypename) { char fs_typename[128]; if (fstype(fname, fs_typename, sizeof(fs_typename))) { return bstrcmp(fs_typename, fstypename); } return false; } #ifdef TEST_PROGRAM int main(int argc, char **argv) { char *p; char fs[1000]; int status = 0; if (argc < 2) { p = (argc < 1) ? "fstype" : argv[0]; printf("usage:\t%s path ...\n" "\t%s prints the file system type and pathname of the paths.\n", p, p); return EXIT_FAILURE; } while (*++argv) { if (!fstype(*argv, fs, sizeof(fs))) { status = EXIT_FAILURE; } else { printf("%s\t%s\n", fs, *argv); } } return status; } #endif bareos-Release-14.2.6/src/findlib/hardlink.c000066400000000000000000000062371263011562700206060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Hardlinked files handling. The hardlinks are tracked using a htable. * * Written by Marco van Wieringen, May 2014 */ #include "bareos.h" #include "find.h" /* * Lookup a inode/dev in the list of hardlinked files. */ CurLink *lookup_hardlink(JCR *jcr, FF_PKT *ff_pkt, ino_t ino, dev_t dev) { CurLink *hl; uint64_t binary_search_key[2]; if (!ff_pkt->linkhash) { return NULL; } /* * Search link list of hard linked files */ memset(binary_search_key, 0, sizeof(binary_search_key)); binary_search_key[0] = dev; binary_search_key[1] = ino; hl = (CurLink *)ff_pkt->linkhash->lookup((uint8_t *)binary_search_key, sizeof(binary_search_key)); return hl; } CurLink *new_hardlink(JCR *jcr, FF_PKT *ff_pkt, char *fname, ino_t ino, dev_t dev) { int len; CurLink *hl = NULL; uint64_t binary_search_key[2]; uint8_t *new_key; if (!ff_pkt->linkhash) { ff_pkt->linkhash = (htable *)malloc(sizeof(htable)); ff_pkt->linkhash->init(hl, &hl->link, 10000, 480); } len = strlen(fname) + 1; hl = (CurLink *)ff_pkt->linkhash->hash_malloc(sizeof(CurLink) + len); hl->digest = NULL; /* Set later */ hl->digest_stream = 0; /* Set later */ hl->digest_len = 0; /* Set later */ hl->ino = ino; hl->dev = dev; hl->FileIndex = 0; /* Set later */ bstrncpy(hl->name, fname, len); memset(binary_search_key, 0, sizeof(binary_search_key)); binary_search_key[0] = dev; binary_search_key[1] = ino; new_key = (uint8_t *)ff_pkt->linkhash->hash_malloc(sizeof(binary_search_key)); memcpy(new_key, binary_search_key, sizeof(binary_search_key)); ff_pkt->linkhash->insert(new_key, sizeof(binary_search_key), hl); return hl; } /* * When the current file is a hardlink, the backup code can compute * the checksum and store it into the CurLink structure. */ void ff_pkt_set_link_digest(FF_PKT *ff_pkt, int32_t digest_stream, const char *digest, uint32_t len) { if (ff_pkt->linked && !ff_pkt->linked->digest) { /* is a hardlink */ ff_pkt->linked->digest = (char *) ff_pkt->linkhash->hash_malloc(len); memcpy(ff_pkt->linked->digest, digest, len); ff_pkt->linked->digest_len = len; ff_pkt->linked->digest_stream = digest_stream; } } bareos-Release-14.2.6/src/findlib/match.c000066400000000000000000000374361263011562700201130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Old style * * Routines used to keep and match include and exclude * filename/pathname patterns. * * Note, this file is used for the old style include and * excludes, so is deprecated. The new style code is * found in find.c. * This code is still used for lists in testls and bextract. * * Kern E. Sibbald, December MMI */ #include "bareos.h" #include "find.h" #include "ch.h" #include #ifndef FNM_LEADING_DIR #define FNM_LEADING_DIR 0 #endif /* Fold case in fnmatch() on Win32 */ #ifdef HAVE_WIN32 static const int fnmode = FNM_CASEFOLD; #else static const int fnmode = 0; #endif #undef bmalloc #define bmalloc(x) sm_malloc(__FILE__, __LINE__, x) bool match_files(JCR *jcr, FF_PKT *ff, int file_save(JCR *, FF_PKT *ff_pkt, bool)) { ff->file_save = file_save; struct s_included_file *inc = NULL; /* This is the old deprecated way */ while (!job_canceled(jcr) && (inc = get_next_included_file(ff, inc))) { /* Copy options for this file */ bstrncat(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts)); Dmsg1(100, "find_files: file=%s\n", inc->fname); if (!file_is_excluded(ff, inc->fname)) { if (find_one_file(jcr, ff, file_save, inc->fname, (dev_t)-1, 1) ==0) { return false; /* error return */ } } } return true; } /* * Done doing filename matching, release all * resources used. */ void term_include_exclude_files(FF_PKT *ff) { struct s_included_file *inc, *next_inc; struct s_excluded_file *exc, *next_exc; for (inc=ff->included_files_list; inc; ) { next_inc = inc->next; if (inc->size_match) { free(inc->size_match); } free(inc); inc = next_inc; } ff->included_files_list = NULL; for (exc=ff->excluded_files_list; exc; ) { next_exc = exc->next; free(exc); exc = next_exc; } ff->excluded_files_list = NULL; for (exc=ff->excluded_paths_list; exc; ) { next_exc = exc->next; free(exc); exc = next_exc; } ff->excluded_paths_list = NULL; } /* * Add a filename to list of included files */ void add_fname_to_include_list(FF_PKT *ff, int prefixed, const char *fname) { int len, j; struct s_included_file *inc; char *p; const char *rp; char size[50]; len = strlen(fname); inc =(struct s_included_file *)bmalloc(sizeof(struct s_included_file) + len + 1); memset(inc, 0, sizeof(struct s_included_file) + len + 1); inc->VerifyOpts[0] = 'V'; inc->VerifyOpts[1] = ':'; inc->VerifyOpts[2] = 0; /* prefixed = preceded with options */ if (prefixed) { for (rp=fname; *rp && *rp != ' '; rp++) { switch (*rp) { case 'A': set_bit(FO_ACL, inc->options); break; case 'a': /* alway replace */ case '0': /* no option */ break; case 'c': set_bit(FO_CHKCHANGES, inc->options); break; case 'd': switch(*(rp + 1)) { case '1': inc->shadow_type = check_shadow_local_warn; break; case '2': inc->shadow_type = check_shadow_local_remove; break; case '3': inc->shadow_type = check_shadow_global_warn; break; case '4': inc->shadow_type = check_shadow_global_remove; break; } break; case 'e': set_bit(FO_EXCLUDE, inc->options); break; case 'f': set_bit(FO_MULTIFS, inc->options); break; case 'H': /* no hard link handling */ set_bit(FO_NO_HARDLINK, inc->options); break; case 'h': /* no recursion */ set_bit(FO_NO_RECURSION, inc->options); break; case 'i': set_bit(FO_IGNORECASE, inc->options); break; case 'K': set_bit(FO_NOATIME, inc->options); break; case 'k': set_bit(FO_KEEPATIME, inc->options); break; case 'M': /* MD5 */ set_bit(FO_MD5, inc->options); break; case 'm': set_bit(FO_MTIMEONLY, inc->options); break; case 'N': set_bit(FO_HONOR_NODUMP, inc->options); break; case 'n': set_bit(FO_NOREPLACE, inc->options); break; case 'p': /* use portable data format */ set_bit(FO_PORTABLE, inc->options); break; case 'R': /* Resource forks and Finder Info */ set_bit(FO_HFSPLUS, inc->options); break; case 'r': /* read fifo */ set_bit(FO_READFIFO, inc->options); break; case 'S': switch(*(rp + 1)) { case '1': set_bit(FO_SHA1, inc->options); rp++; break; #ifdef HAVE_SHA2 case '2': set_bit(FO_SHA256, inc->options); rp++; break; case '3': set_bit(FO_SHA512, inc->options); rp++; break; #endif default: /* * If 2 or 3 is seen here, SHA2 is not configured, so * eat the option, and drop back to SHA-1. */ if (rp[1] == '2' || rp[1] == '3') { rp++; } set_bit(FO_SHA1, inc->options); break; } break; case 's': set_bit(FO_SPARSE, inc->options); break; case 'V': /* verify options */ /* Copy Verify Options */ for (j = 0; *rp && *rp != ':'; rp++) { inc->VerifyOpts[j] = *rp; if (j < (int)sizeof(inc->VerifyOpts) - 1) { j++; } } inc->VerifyOpts[j] = 0; break; case 'W': set_bit(FO_ENHANCEDWILD, inc->options); break; case 'w': set_bit(FO_IF_NEWER, inc->options); break; case 'x': set_bit(FO_NO_AUTOEXCL, inc->options); break; case 'X': set_bit(FO_XATTR, inc->options); break; case 'Z': /* Compression */ rp++; /* Skip Z */ if (*rp >= '0' && *rp <= '9') { set_bit(FO_COMPRESS, inc->options); inc->algo = COMPRESS_GZIP; inc->level = *rp - '0'; } else if (*rp == 'o') { set_bit(FO_COMPRESS, inc->options); inc->algo = COMPRESS_LZO1X; inc->level = 1; /* Not used with LZO */ } else if (*rp == 'f') { if (rp[1] == 'f') { rp++; /* Skip f */ set_bit(FO_COMPRESS, inc->options); inc->algo = COMPRESS_FZFZ; inc->level = 1; /* Not used with libfzlib */ } else if (rp[1] == '4') { rp++; /* Skip f */ set_bit(FO_COMPRESS, inc->options); inc->algo = COMPRESS_FZ4L; inc->level = 1; /* Not used with libfzlib */ } else if (rp[1] == 'h') { rp++; /* Skip f */ set_bit(FO_COMPRESS, inc->options); inc->algo = COMPRESS_FZ4H; inc->level = 1; /* Not used with libfzlib */ } } Dmsg2(200, "Compression alg=%d level=%d\n", inc->algo, inc->level); break; case 'z': /* Min, Max or Approx size or Size range */ rp++; /* Skip z */ for (j = 0; *rp && *rp != ':'; rp++) { size[j] = *rp; if (j < (int)sizeof(size) - 1) { j++; } } size[j] = 0; if (!inc->size_match) { inc->size_match = (struct s_sz_matching *)bmalloc(sizeof(struct s_sz_matching)); } if (!parse_size_match(size, inc->size_match)) { Emsg1(M_ERROR, 0, _("Unparseable size option: %s\n"), size); } break; default: Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *rp); break; } } /* Skip past space(s) */ for ( ; *rp == ' '; rp++) {} } else { rp = fname; } strcpy(inc->fname, rp); p = inc->fname; len = strlen(p); /* Zap trailing slashes. */ p += len - 1; while (p > inc->fname && IsPathSeparator(*p)) { *p-- = 0; len--; } inc->len = len; /* Check for wild cards */ inc->pattern = 0; for (p=inc->fname; *p; p++) { if (*p == '*' || *p == '[' || *p == '?') { inc->pattern = 1; break; } } #if defined(HAVE_WIN32) /* Convert any \'s into /'s */ for (p=inc->fname; *p; p++) { if (*p == '\\') { *p = '/'; } } #endif inc->next = NULL; /* Chain this one on the end of the list */ if (!ff->included_files_list) { /* First one, so set head */ ff->included_files_list = inc; } else { struct s_included_file *next; /* Walk to end of list */ for (next=ff->included_files_list; next->next; next=next->next) { } next->next = inc; } Dmsg4(100, "add_fname_to_include prefix=%d compres=%d alg= %d fname=%s\n", prefixed, bit_is_set(FO_COMPRESS, inc->options), inc->algo, inc->fname); } /* * We add an exclude name to either the exclude path * list or the exclude filename list. */ void add_fname_to_exclude_list(FF_PKT *ff, const char *fname) { int len; struct s_excluded_file *exc, **list; Dmsg1(20, "Add name to exclude: %s\n", fname); if (first_path_separator(fname) != NULL) { list = &ff->excluded_paths_list; } else { list = &ff->excluded_files_list; } len = strlen(fname); exc = (struct s_excluded_file *)bmalloc(sizeof(struct s_excluded_file) + len + 1); memset(exc, 0, sizeof(struct s_excluded_file) + len + 1); exc->next = *list; exc->len = len; strcpy(exc->fname, fname); #if defined(HAVE_WIN32) /* Convert any \'s into /'s */ for (char *p=exc->fname; *p; p++) { if (*p == '\\') { *p = '/'; } } #endif *list = exc; } /* * Get next included file */ struct s_included_file *get_next_included_file(FF_PKT *ff, struct s_included_file *ainc) { struct s_included_file *inc; if (ainc == NULL) { inc = ff->included_files_list; } else { inc = ainc->next; } /* * copy inc_options for this file into the ff packet */ if (inc) { copy_bits(FO_MAX, inc->options, ff->flags); ff->Compress_algo = inc->algo; ff->Compress_level = inc->level; } return inc; } /* * Walk through the included list to see if this * file is included possibly with wild-cards. */ bool file_is_included(FF_PKT *ff, const char *file) { struct s_included_file *inc = ff->included_files_list; int len; for ( ; inc; inc=inc->next ) { if (inc->pattern) { if (fnmatch(inc->fname, file, fnmode|FNM_LEADING_DIR) == 0) { return true; } continue; } /* * No wild cards. We accept a match to the * end of any component. */ Dmsg2(900, "pat=%s file=%s\n", inc->fname, file); len = strlen(file); if (inc->len == len && bstrcmp(inc->fname, file)) { return true; } if (inc->len < len && IsPathSeparator(file[inc->len]) && bstrncmp(inc->fname, file, inc->len)) { return true; } if (inc->len == 1 && IsPathSeparator(inc->fname[0])) { return true; } } return false; } /* * This is the workhorse of excluded_file(). * Determine if the file is excluded or not. */ static bool file_in_excluded_list(struct s_excluded_file *exc, const char *file) { if (exc == NULL) { Dmsg0(900, "exc is NULL\n"); } for ( ; exc; exc=exc->next ) { if (fnmatch(exc->fname, file, fnmode|FNM_PATHNAME) == 0) { Dmsg2(900, "Match exc pat=%s: file=%s:\n", exc->fname, file); return true; } Dmsg2(900, "No match exc pat=%s: file=%s:\n", exc->fname, file); } return false; } /* * Walk through the excluded lists to see if this * file is excluded, or if it matches a component * of an excluded directory. */ bool file_is_excluded(FF_PKT *ff, const char *file) { const char *p; #if defined(HAVE_WIN32) /* * ***NB*** this removes the drive from the exclude * rule. Why????? */ if (file[1] == ':') { file += 2; } #endif if (file_in_excluded_list(ff->excluded_paths_list, file)) { return true; } /* Try each component */ for (p = file; *p; p++) { /* Match from the beginning of a component only */ if ((p == file || (!IsPathSeparator(*p) && IsPathSeparator(p[-1]))) && file_in_excluded_list(ff->excluded_files_list, p)) { return true; } } return false; } /* * Parse a size matching fileset option. */ bool parse_size_match(const char *size_match_pattern, struct s_sz_matching *size_matching) { bool retval = false; char *private_copy, *bp; /* * Make a private copy of the input string. * As we manipulate the input and size_to_uint64 * eats its input. */ private_copy = bstrdup(size_match_pattern); /* * Empty the matching arguments. */ memset(size_matching, 0, sizeof(struct s_sz_matching)); /* * See if the size is a range e.g. there is a - in the * match pattern. As a size of a file can never be negative * this is a workable solution. */ if ((bp = strchr(private_copy, '-')) != NULL) { *bp++ = '\0'; size_matching->type = size_match_range; if (!size_to_uint64(private_copy, &size_matching->begin_size)) { goto bail_out; } if (!size_to_uint64(bp, &size_matching->end_size)) { goto bail_out; } } else { switch (*private_copy) { case '<': size_matching->type = size_match_smaller; if (!size_to_uint64(private_copy + 1, &size_matching->begin_size)) { goto bail_out; } break; case '>': size_matching->type = size_match_greater; if (!size_to_uint64(private_copy + 1, &size_matching->begin_size)) { goto bail_out; } break; default: size_matching->type = size_match_approx; if (!size_to_uint64(private_copy, &size_matching->begin_size)) { goto bail_out; } break; } } retval = true; bail_out: free(private_copy); return retval; } bareos-Release-14.2.6/src/findlib/mkpath.c000066400000000000000000000210771263011562700202750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, September MMVII * * This is tricky code, especially when writing from scratch. Fortunately, * a non-copyrighted version of mkdir was available to consult. * * ***FIXME*** the mkpath code could be significantly optimized by * walking up the path chain from the bottom until it either gets * to the top or finds an existing directory then walk back down * creating the path components. Currently, it always starts at * the top, which can be rather inefficient for long path names. */ #include "bareos.h" #include "jcr.h" #define dbglvl 50 /* * * For old systems that don't have lchown() use chown() * */ #ifndef HAVE_LCHOWN #define lchown chown #endif /* * * For old systems that don't have lchmod() use chmod() * */ #ifndef HAVE_LCHMOD #define lchmod chmod #endif typedef struct PrivateCurDir { hlink link; char fname[1]; } CurDir; /* * Initialize the path hash table */ htable *path_list_init() { htable *path_list; CurDir *elt = NULL; path_list = (htable *)malloc(sizeof(htable)); /* * Hard to know in advance how many directories will be stored in this hash */ path_list->init(elt, &elt->link, 10000); return path_list; } /* * Add a path to the hash when we create a directory with the replace=NEVER option */ bool path_list_add(htable *path_list, uint32_t len, char *fname) { CurDir *item; if (!path_list) { return false; } /* * We store CurDir, fname in the same chunk */ item = (CurDir *)path_list->hash_malloc(sizeof(CurDir) + len + 1); memset(item, 0, sizeof(CurDir)); memcpy(item->fname, fname, len + 1); path_list->insert(item->fname, item); Dmsg1(dbglvl, "add fname=<%s>\n", fname); return true; } bool path_list_lookup(htable *path_list, char *fname) { int len; bool found = false; char bkp; if (!path_list) { return false; } /* * Strip trailing / */ len = strlen(fname); if (len == 0) { return false; } len--; bkp = fname[len]; if (fname[len] == '/') { /* strip any trailing slash */ fname[len] = 0; } CurDir *temp = (CurDir *)path_list->lookup(fname); if (temp) { found=true; } Dmsg2(dbglvl, "lookup <%s> %s\n", fname, found?"ok":"not ok"); fname[len] = bkp; /* restore last / */ return found; } void free_path_list(htable *path_list) { path_list->destroy(); free(path_list); } static bool makedir(JCR *jcr, char *path, mode_t mode, int *created) { struct stat statp; if (mkdir(path, mode) != 0) { berrno be; *created = false; if (stat(path, &statp) != 0) { Jmsg2(jcr, M_ERROR, 0, _("Cannot create directory %s: ERR=%s\n"), path, be.bstrerror()); return false; } else if (!S_ISDIR(statp.st_mode)) { Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path); return false; } return true; /* directory exists */ } if (jcr->keep_path_list) { /* * When replace = NEVER, we keep track of all directories newly created */ if (!jcr->path_list) { jcr->path_list = path_list_init(); } path_list_add(jcr->path_list, strlen(path), path); } *created = true; return true; } static void set_own_mod(ATTR *attr, char *path, uid_t owner, gid_t group, mode_t mode) { if (lchown(path, owner, group) != 0 && attr->uid == 0 #ifdef AFS && errno != EPERM #endif ) { berrno be; Jmsg2(attr->jcr, M_WARNING, 0, _("Cannot change owner and/or group of %s: ERR=%s\n"), path, be.bstrerror()); } #if defined(HAVE_WIN32) if (win32_chmod(path, mode, 0) != 0 && attr->uid == 0) { #else if (lchmod(path, mode) != 0 && attr->uid == 0) { #endif berrno be; Jmsg2(attr->jcr, M_WARNING, 0, _("Cannot change permissions of %s: ERR=%s\n"), path, be.bstrerror()); } } /* * mode is the mode bits to use in creating a new directory * parent_mode are the parent's modes if we need to create parent directories. * owner and group are to set on any created dirs * keep_dir_modes if set means don't change mode bits if dir exists */ bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode, uid_t owner, gid_t group, bool keep_dir_modes) { struct stat statp; mode_t omask, tmode; char *path = (char *)apath; char *p; int len; bool ok = false; int created; char new_dir[5000]; int ndir = 0; int i = 0; int max_dirs = (int)sizeof(new_dir); JCR *jcr = attr->jcr; if (stat(path, &statp) == 0) { /* Does dir exist? */ if (!S_ISDIR(statp.st_mode)) { Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path); return false; } /* Full path exists */ if (keep_dir_modes) { return true; } set_own_mod(attr, path, owner, group, mode); return true; } omask = umask(0); umask(omask); len = strlen(apath); path = (char *)alloca(len+1); bstrncpy(path, apath, len+1); strip_trailing_slashes(path); /* * Now for one of the complexities. If we are not running as root, * then if the parent_mode does not have wx user perms, or we are * setting the userid or group, and the parent_mode has setuid, setgid, * or sticky bits, we must create the dir with open permissions, then * go back and patch all the dirs up with the correct perms. * Solution, set everything to 0777, then go back and reset them at the * end. */ tmode = 0777; #if defined(HAVE_WIN32) /* * Validate drive letter */ if (path[1] == ':') { char drive[4] = "X:\\"; drive[0] = path[0]; UINT drive_type = GetDriveType(drive); if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) { Jmsg1(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]); goto bail_out; } if (path[2] == '\0') { /* attempt to create a drive */ ok = true; goto bail_out; /* OK, it is already there */ } p = &path[3]; } else { p = path; } #else p = path; #endif /* * Skip leading slash(es) */ while (IsPathSeparator(*p)) { p++; } while ((p = first_path_separator(p))) { char save_p; save_p = *p; *p = 0; if (!makedir(jcr, path, tmode, &created)) { goto bail_out; } if (ndir < max_dirs) { new_dir[ndir++] = created; } *p = save_p; while (IsPathSeparator(*p)) { p++; } } /* * Create final component if not a junction/symlink */ if(attr->type != FT_JUNCTION ){ if (!makedir(jcr, path, tmode, &created)) { goto bail_out; } } if (ndir < max_dirs) { new_dir[ndir++] = created; } if (ndir >= max_dirs) { Jmsg0(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n")); } /* * Now set the proper owner and modes */ #if defined(HAVE_WIN32) /* * Don't propagate the hidden attribute to parent directories */ parent_mode &= ~S_ISVTX; if (path[1] == ':') { p = &path[3]; } else { p = path; } #else p = path; #endif /* * Skip leading slash(es) */ while (IsPathSeparator(*p)) { p++; } while ((p = first_path_separator(p))) { char save_p; save_p = *p; *p = 0; if (i < ndir && new_dir[i++] && !keep_dir_modes) { set_own_mod(attr, path, owner, group, parent_mode); } *p = save_p; while (IsPathSeparator(*p)) { p++; } } /* * Set for final component */ if (i < ndir && new_dir[i++]) { set_own_mod(attr, path, owner, group, mode); } ok = true; bail_out: umask(omask); return ok; } bareos-Release-14.2.6/src/findlib/protos.h000066400000000000000000000132041263011562700203350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Prototypes for findlib directory of Bareos */ /* acl.c */ bacl_exit_code send_acl_stream(JCR *jcr, acl_data_t *acl_data, int stream); bacl_exit_code build_acl_streams(JCR *jcr, acl_data_t *acl_data, FF_PKT *ff_pkt); bacl_exit_code parse_acl_streams(JCR *jcr, acl_data_t *acl_data, int stream, char *content, uint32_t content_length); /* attribs.c */ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt); bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd); int select_data_stream(FF_PKT *ff_pkt, bool compatible); /* create_file.c */ int create_file(JCR *jcr, ATTR *attr, BFILE *ofd, int replace); /* find.c */ FF_PKT *init_find_files(); void set_find_options(FF_PKT *ff, bool incremental, time_t mtime); void set_find_changed_function(FF_PKT *ff, bool check_fct(JCR *jcr, FF_PKT *ff)); int find_files(JCR *jcr, FF_PKT *ff, int file_sub(JCR *, FF_PKT *ff_pkt, bool), int plugin_sub(JCR *, FF_PKT *ff_pkt, bool)); bool match_files(JCR *jcr, FF_PKT *ff, int sub(JCR *, FF_PKT *ff_pkt, bool)); int term_find_files(FF_PKT *ff); bool is_in_fileset(FF_PKT *ff); bool accept_file(FF_PKT *ff); findINCEXE *allocate_new_incexe(void); findINCEXE *new_exclude(findFILESET *fileset); findINCEXE *new_include(findFILESET *fileset); findINCEXE *new_preinclude(findFILESET *fileset); findINCEXE *new_preexclude(findFILESET *fileset); findFOPTS *start_options(FF_PKT *ff); void new_options(FF_PKT *ff, findINCEXE *incexe); /* match.c */ void init_include_exclude_files(FF_PKT *ff); void term_include_exclude_files(FF_PKT *ff); void add_fname_to_include_list(FF_PKT *ff, int prefixed, const char *fname); void add_fname_to_exclude_list(FF_PKT *ff, const char *fname); bool file_is_excluded(FF_PKT *ff, const char *file); bool file_is_included(FF_PKT *ff, const char *file); struct s_included_file *get_next_included_file(FF_PKT *ff, struct s_included_file *inc); bool parse_size_match(const char *size_match_pattern, struct s_sz_matching *size_matching); /* find_one.c */ int find_one_file(JCR *jcr, FF_PKT *ff, int handle_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level), char *p, dev_t parent_device, bool top_level); int term_find_one(FF_PKT *ff); bool has_file_changed(JCR *jcr, FF_PKT *ff_pkt); bool check_changes(JCR *jcr, FF_PKT *ff_pkt); /* get_priv.c */ int enable_backup_privileges(JCR *jcr, int ignore_errors); /* hardlink.c */ CurLink *lookup_hardlink(JCR *jcr, FF_PKT *ff_pkt, ino_t ino, dev_t dev); CurLink *new_hardlink(JCR *jcr, FF_PKT *ff_pkt, char *fname, ino_t ino, dev_t dev); void ff_pkt_set_link_digest(FF_PKT *ff_pkt, int32_t digest_stream, const char *digest, uint32_t len); /* makepath.c */ htable *path_list_init(); bool path_list_lookup(htable *path_list, char *fname); bool path_list_add(htable *path_list, uint32_t len, char *fname); void free_path_list(htable *path_list); bool makepath(ATTR *attr, const char *path, mode_t mode, mode_t parent_mode, uid_t owner, gid_t group, bool keep_dir_modes); /* fstype.c */ bool fstype(const char *fname, char *fs, int fslen); bool fstype_equals(const char *fname, const char *fstypename); /* drivetype.c */ bool drivetype(const char *fname, char *fs, int fslen); /* shadowing.c */ void check_include_list_shadowing(JCR *jcr, findFILESET *fileset); #if defined(HAVE_WIN32) /* win32.c */ bool win32_onefs_is_disabled(findFILESET *fileset); int get_win32_driveletters(findFILESET *fileset, char *szDrives); int get_win32_virtualmountpoints(findFILESET *fileset, dlist **szVmps); bool expand_win32_fileset(findFILESET *fileset); bool exclude_win32_not_to_backup_registry_entries(JCR *jcr, FF_PKT *ff); int win32_send_to_copy_thread(JCR *jcr, BFILE *bfd, char *data, const int32_t length); void win32_flush_copy_thread(JCR *jcr); void win32_cleanup_copy_thread(JCR *jcr); #endif /* xattr.c */ bxattr_exit_code send_xattr_stream(JCR *jcr, xattr_data_t *xattr_data, int stream); void xattr_drop_internal_table(alist *xattr_value_list); uint32_t serialize_xattr_stream(JCR *jcr, xattr_data_t *xattr_data, uint32_t expected_serialize_len, alist *xattr_value_list); bxattr_exit_code unserialize_xattr_stream(JCR *jcr, xattr_data_t *xattr_data, char *content, uint32_t content_length, alist *xattr_value_list); bxattr_exit_code build_xattr_streams(JCR *jcr, struct xattr_data_t *xattr_data, FF_PKT *ff_pkt); bxattr_exit_code parse_xattr_streams(JCR *jcr, struct xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length); /* bfile.c -- see bfile.h */ bareos-Release-14.2.6/src/findlib/savecwd.c000066400000000000000000000060521263011562700204410ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August MMVII */ #include "bareos.h" #include "savecwd.h" /* * Attempt to save the current working directory by various means so that * we can optimize code by doing a cwd and then restore the cwd. */ #ifdef HAVE_FCHDIR static bool fchdir_failed = false; /* set if we get a fchdir failure */ #else static bool fchdir_failed = true; /* set if we get a fchdir failure */ #endif /* * Save current working directory. * Returns: true if OK * false if failed */ bool saveCWD::save(JCR *jcr) { release(); /* clean up */ if (!fchdir_failed) { m_fd = open(".", O_RDONLY); if (m_fd < 0) { berrno be; Jmsg1(jcr, M_ERROR, 0, _("Cannot open current directory: ERR=%s\n"), be.bstrerror()); m_saved = false; return false; } } if (fchdir_failed) { POOLMEM *buf = get_memory(5000); m_cwd = (POOLMEM *)getcwd(buf, sizeof_pool_memory(buf)); if (m_cwd == NULL) { berrno be; Jmsg1(jcr, M_ERROR, 0, _("Cannot get current directory: ERR=%s\n"), be.bstrerror()); free_pool_memory(buf); m_saved = false; return false; } } m_saved = true; return true; } /* * Restore previous working directory. * Returns: true if OK * false if failed */ bool saveCWD::restore(JCR *jcr) { if (!m_saved) { return true; } m_saved = false; if (m_fd >= 0) { if (fchdir(m_fd) != 0) { berrno be; Jmsg1(jcr, M_ERROR, 0, _("Cannot reset current directory: ERR=%s\n"), be.bstrerror()); close(m_fd); m_fd = -1; fchdir_failed = true; chdir("/"); /* punt */ return false; } return true; } if (chdir(m_cwd) < 0) { berrno be; Jmsg1(jcr, M_ERROR, 0, _("Cannot reset current directory: ERR=%s\n"), be.bstrerror()); chdir("/"); free_pool_memory(m_cwd); m_cwd = NULL; return false; } return true; } void saveCWD::release() { if (!m_saved) { return; } m_saved = false; if (m_fd >= 0) { close(m_fd); m_fd = -1; } if (m_cwd) { free_pool_memory(m_cwd); m_cwd = NULL; } } bareos-Release-14.2.6/src/findlib/savecwd.h000066400000000000000000000025761263011562700204550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August MMVII */ #ifndef _SAVECWD_H #define _SAVECWD_H 1 class saveCWD { bool m_saved; /* set if we should do chdir i.e. save_cwd worked */ int m_fd; /* fd of current dir before chdir */ char *m_cwd; /* cwd before chdir if fd fchdir() works */ public: saveCWD() { m_saved=false; m_fd=-1; m_cwd=NULL; }; ~saveCWD() { release(); }; bool save(JCR *jcr); bool restore(JCR *jcr); void release(); bool is_saved() { return m_saved; }; }; #endif /* _SAVECWD_H */ bareos-Release-14.2.6/src/findlib/shadowing.c000066400000000000000000000373121263011562700207730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Detect fileset shadowing e.g. when an include entry pulls in data * which is already being backuped by an other include pattern. Currently * we support both local and global shadowing. Where local shadowing is * when the shadowing occurs within one include block and global when * between multiple include blocks. * * Written by Marco van Wieringen, November 2011 */ #include "bareos.h" #include "find.h" /* * Check if a certain fileset include pattern shadows an other pattern. */ static inline bool check_include_pattern_shadowing(JCR *jcr, const char *pattern1, const char *pattern2, bool recursive) { int len1, len2; bool retval = false; struct stat st1, st2; /* * See if one directory shadows the other or if two * files are hardlinked. */ if (lstat(pattern1, &st1) != 0) { berrno be; Jmsg(jcr, M_WARNING, 0, _("Cannot stat file %s: ERR=%s\n"), pattern1, be.bstrerror()); goto bail_out; } if (lstat(pattern2, &st2) != 0) { berrno be; Jmsg(jcr, M_WARNING, 0, _("Cannot stat file %s: ERR=%s\n"), pattern2, be.bstrerror()); goto bail_out; } if (S_ISDIR(st1.st_mode) && S_ISDIR(st2.st_mode)) { /* * Only check shadowing of directories when recursion is turned on. */ if (recursive ) { len1 = strlen(pattern1); len2 = strlen(pattern2); /* * See if one pattern shadows the other. */ if (((len1 < len2 && pattern1[len1] == '\0' && IsPathSeparator(pattern2[len1])) || (len1 > len2 && IsPathSeparator(pattern1[len2]) && pattern1[len1] == '\0')) && bstrncmp(pattern1, pattern2, MIN(len1, len2))) { /* * If both directories have the same st_dev they shadow * each other e.g. are not on seperate filesystems. */ if (st1.st_dev == st2.st_dev) { retval = true; } } } } else { /* * See if the two files are hardlinked. */ if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) { retval = true; } } bail_out: return retval; } /* * See if recursion is on or off for a specific include block. * We use the data from the default options block. * e.g. the last option block in the include block. */ static inline bool include_block_is_recursive(findINCEXE *incexe) { int i; findFOPTS *fo; bool recursive = true; for (i = 0; i < incexe->opts_list.size(); i++) { fo = (findFOPTS *)incexe->opts_list.get(i); recursive = !bit_is_set(FO_NO_RECURSION, fo->flags); } return recursive; } /* * See if an options block of an include block has any wildcard * or regex settings which are not used for excluding. */ static inline bool include_block_has_patterns(findINCEXE *incexe) { int i; bool has_find_patterns = false; findFOPTS *fo; for (i = 0; i < incexe->opts_list.size(); i++) { fo = (findFOPTS *)incexe->opts_list.get(i); /* * See if this is an exclude block. * e.g. exclude = yes is set then we * should still check for shadowing. */ if (bit_is_set(FO_EXCLUDE, fo->flags)) { continue; } /* * See if the include block has any interesting * wildcard matching options. We consider the following * as making the shadowing match to difficult: * - regex = entries * - regexdir = entries * - wild = entries * - wildir = entries * * For filename shadowing we only check if files are * hardlinked so we don't take into consideration * - regexfile = entries * - wildfile = entries */ if (fo->regex.size() > 0 || fo->regexdir.size() > 0 || fo->wild.size() > 0 || fo->wilddir.size() > 0) { has_find_patterns = true; } } return has_find_patterns; } /* * For this include block lookup the shadow checking type requested. * We use the data from the default options block. * e.g. the last option block in the include block. */ static inline b_fileset_shadow_type include_block_get_shadow_type(findINCEXE *incexe) { int i; findFOPTS *fo; b_fileset_shadow_type shadow_type = check_shadow_none; for (i = 0; i < incexe->opts_list.size(); i++) { fo = (findFOPTS *)incexe->opts_list.get(i); shadow_type = fo->shadow_type; } return shadow_type; } /* * See if there is any local shadowing within an include block. */ static void check_local_fileset_shadowing(JCR *jcr, findINCEXE *incexe, bool remove) { dlistString *str1, *str2, *next; bool recursive; /* * See if this is a recursive include block. */ recursive = include_block_is_recursive(incexe); /* * Loop over all entries in the name_list * and compare them against all next entries * after the one we are currently examining. * This way we only check shadowing only once. */ str1 = (dlistString *)incexe->name_list.first(); while (str1) { str2 = (dlistString *)incexe->name_list.next(str1); while (str1 && str2) { if (check_include_pattern_shadowing(jcr, str1->c_str(), str2->c_str(), recursive)) { /* * See what entry shadows the other, the longest entry * shadow the shorter one. */ if (strlen(str1->c_str()) < strlen(str2->c_str())) { if (remove) { /* * Pattern2 is longer then Pattern1 e.g. the include block patterns * are probably sorted right. This is the easiest case where we just * remove the entry from the list and continue. */ Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s removing it from fileset\n"), str2->c_str(), str1->c_str()); next = (dlistString *)incexe->name_list.next(str2); incexe->name_list.remove(str2); str2 = next; continue; } else { Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s\n"), str2->c_str(), str1->c_str()); } } else { if (remove) { /* * Pattern1 is longer then Pattern2 e.g. the include block patterns * are not sorted right and probably reverse. This is a bit more difficult. * We remove the first pattern from the list and restart the shadow scan. * By setting str1 to NULL we force a rescan as the next method of the dlist * will start at the first entry of the dlist again. */ Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s removing it from fileset\n"), str1->c_str(), str2->c_str()); incexe->name_list.remove(str1); str1 = NULL; continue; } else { Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s\n"), str1->c_str(), str2->c_str()); } } } str2 = (dlistString *)incexe->name_list.next(str2); } str1 = (dlistString *)incexe->name_list.next(str1); } } /* * See if there is any local shadowing within an include block or * any global shadowing between include blocks. */ static inline void check_global_fileset_shadowing(JCR *jcr, findFILESET *fileset, bool remove) { int i, j; bool local_recursive, global_recursive; findINCEXE *current, *compare_against; dlistString *str1, *str2, *next; /* * Walk all the include blocks and see if there * is any shadowing between the different sets. */ for (i = 0; i < fileset->include_list.size(); i++) { current = (findINCEXE *)fileset->include_list.get(i); /* * See if there is any local shadowing. */ check_local_fileset_shadowing(jcr, current, remove); /* * Only check global shadowing against this include block * when it doesn't have any patterns. Testing if a fileset * shadows the other with patterns is next to impossible * without comparing the matching criteria which can be * in so many forms we forget it all together. When you * are smart enough to create include/exclude patterns * we also don't provide you with basic stop gap measures. */ if (include_block_has_patterns(current)) { continue; } /* * Now compare this block against any include block after this one. * We can shortcut as we don't have to start at the beginning of * the list again because we compare all sets against each other * this way anyhow. e.g. we start with set 1 against 2 .. x and * then 2 against 3 .. x (No need to compare 2 against 1 again * as we did that in the first run already. * * See if this is a recursive include block. */ local_recursive = include_block_is_recursive(current); for (j = i + 1; j < fileset->include_list.size(); j++) { compare_against = (findINCEXE *)fileset->include_list.get(j); /* * Only check global shadowing against this include block * when it doesn't have any patterns. */ if (include_block_has_patterns(compare_against)) { continue; } /* * See if both include blocks are recursive. */ global_recursive = (local_recursive && include_block_is_recursive(compare_against)); /* * Walk over the filename list and compare it * against the other entry from the other list. */ str1 = (dlistString *)current->name_list.first(); while (str1) { str2 = (dlistString *)compare_against->name_list.first(); while (str1 && str2) { if (check_include_pattern_shadowing(jcr, str1->c_str(), str2->c_str(), global_recursive)) { /* * See what entry shadows the other, the longest entry * shadow the shorter one. */ if (strlen(str1->c_str()) < strlen(str2->c_str())) { if (remove) { /* * Pattern2 is longer then Pattern1 e.g. the include block patterns * are probably sorted right. This is the easiest case where we just * remove the entry from the list and continue. */ Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s removing it from fileset\n"), str2->c_str(), str1->c_str()); next = (dlistString *)compare_against->name_list.next(str2); compare_against->name_list.remove(str2); str2 = next; continue; } else { Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s\n"), str2->c_str(), str1->c_str()); } } else { if (remove) { /* * Pattern1 is longer then Pattern2 e.g. the include block patterns * are not sorted right and probably reverse. This is a bit more * difficult. We remove the first pattern from the list and restart * the shadow scan. By setting str1 to NULL we force a rescan as the * next method of the dlist will start at the first entry of the * dlist again. */ Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s removing it from fileset\n"), str1->c_str(), str2->c_str()); current->name_list.remove(str1); str1 = NULL; continue; } else { Jmsg(jcr, M_WARNING, 0, _("Fileset include block entry %s shadows %s\n"), str1->c_str(), str2->c_str()); } } } str2 = (dlistString *)compare_against->name_list.next(str2); } str1 = (dlistString *)current->name_list.next(str1); } } } } void check_include_list_shadowing(JCR *jcr, findFILESET *fileset) { int i; findINCEXE *incexe; b_fileset_shadow_type shadow_type; /* * Walk the list of include blocks. */ for (i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); /* * See if the shadow check option is enabled for this * include block. If not just continue with the next include block. */ shadow_type = include_block_get_shadow_type(incexe); switch (shadow_type) { case check_shadow_none: continue; case check_shadow_local_warn: case check_shadow_local_remove: /* * Check only for local shadowing within the same include block. */ check_local_fileset_shadowing(jcr, incexe, shadow_type == check_shadow_local_remove); break; case check_shadow_global_warn: case check_shadow_global_remove: /* * Check global shadowing over more then one include block. * We only need to perform the global check once because we * visit all entries in that scan so return after returning * from the function. */ check_global_fileset_shadowing(jcr, fileset, shadow_type == check_shadow_global_remove); return; } } } bareos-Release-14.2.6/src/findlib/xattr.c000066400000000000000000003740001263011562700201500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2008-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Functions to handle Extended Attributes for bareos. * * Extended Attributes are so OS specific we only restore Extended Attributes if * they were saved using a filed on the same platform. * * Currently we support the following OSes: * - AIX (Extended Attributes) * - Darwin (Extended Attributes) * - FreeBSD (Extended Attributes) * - GNU HURD (Extended Attributes) * - IRIX (Extended Attributes) * - Linux (Extended Attributes) * - NetBSD (Extended Attributes) * - OpenBSD (Extended Attributes) * (As it seems either they never implemented xattr or they are removed * the support as it stated it was in version 3.1 but the current syscall * tabled shows the extattr_ functions are not implemented. So as such we * might eventually support xattr on OpenBSD when they implemented them using * the same interface as FreeBSD and NetBSD. * - Solaris (Extended Attributes and Extensible Attributes) * - Tru64 (Extended Attributes) * * Written by Marco van Wieringen, November 2008 * Major overhaul January 2012 + June 2012 * Moved into findlib so it can be used from other programs, May 2012 */ #include "bareos.h" #include "find.h" #if !defined(HAVE_XATTR) /** * Entry points when compiled without support for XATTRs or on an unsupported platform. */ bxattr_exit_code build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { return bxattr_exit_fatal; } bxattr_exit_code parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { return bxattr_exit_fatal; } #else /** * Send a XATTR stream to the SD. */ bxattr_exit_code send_xattr_stream(JCR *jcr, xattr_data_t *xattr_data, int stream) { BSOCK *sd = jcr->store_bsock; POOLMEM *msgsave; #ifdef FD_NO_SEND_TEST return bxattr_exit_ok; #endif /* * Sanity check */ if (xattr_data->u.build->content_length <= 0) { return bxattr_exit_ok; } /* * Send header */ if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return bxattr_exit_fatal; } /* * Send the buffer to the storage deamon */ Dmsg1(400, "Backing up XATTR <%s>\n", xattr_data->u.build->content); msgsave = sd->msg; sd->msg = xattr_data->u.build->content; sd->msglen = xattr_data->u.build->content_length; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return bxattr_exit_fatal; } jcr->JobBytes += sd->msglen; sd->msg = msgsave; if (!sd->signal(BNET_EOD)) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); return bxattr_exit_fatal; } Dmsg1(200, "XATTR of file: %s successfully backed up!\n", xattr_data->last_fname); return bxattr_exit_ok; } /** * First some generic functions for OSes that use the same xattr encoding scheme. * Currently for all OSes except for Solaris. */ void xattr_drop_internal_table(alist *xattr_value_list) { xattr_t *current_xattr; /* * Walk the list of xattrs and free allocated memory on traversing. */ foreach_alist(current_xattr, xattr_value_list) { /* * See if we can shortcut. */ if (current_xattr == NULL || current_xattr->magic != XATTR_MAGIC) break; free(current_xattr->name); if (current_xattr->value_length > 0) free(current_xattr->value); free(current_xattr); } delete xattr_value_list; } /** * The xattr stream for OSX, FreeBSD, Linux and NetBSD is a serialized stream of bytes * which encodes one or more xattr_t structures. * * The Serialized stream consists of the following elements: * magic - A magic string which makes it easy to detect any binary incompatabilites * name_length - The length of the following xattr name * name - The name of the extended attribute * value_length - The length of the following xattr data * value - The actual content of the extended attribute * * This is repeated 1 or more times. * */ uint32_t serialize_xattr_stream(JCR *jcr, xattr_data_t *xattr_data, uint32_t expected_serialize_len, alist *xattr_value_list) { xattr_t *current_xattr; ser_declare; /* * Make sure the serialized stream fits in the poolmem buffer. * We allocate some more to be sure the stream is gonna fit. */ xattr_data->u.build->content = check_pool_memory_size(xattr_data->u.build->content, expected_serialize_len + 10); ser_begin(xattr_data->u.build->content, expected_serialize_len + 10); /* * Walk the list of xattrs and serialize the data. */ foreach_alist(current_xattr, xattr_value_list) { /* * See if we can shortcut. */ if (current_xattr == NULL || current_xattr->magic != XATTR_MAGIC) break; ser_uint32(current_xattr->magic); ser_uint32(current_xattr->name_length); ser_bytes(current_xattr->name, current_xattr->name_length); ser_uint32(current_xattr->value_length); if (current_xattr->value_length > 0 && current_xattr->value) { ser_bytes(current_xattr->value, current_xattr->value_length); Dmsg3(100, "Backup xattr named %s, value %*s\n", current_xattr->name, current_xattr->value_length, current_xattr->value); } else { Dmsg1(100, "Backup empty xattr named %s\n", current_xattr->name); } } ser_end(xattr_data->u.build->content, expected_serialize_len + 10); xattr_data->u.build->content_length = ser_length(xattr_data->u.build->content); return xattr_data->u.build->content_length; } bxattr_exit_code unserialize_xattr_stream(JCR *jcr, xattr_data_t *xattr_data, char *content, uint32_t content_length, alist *xattr_value_list) { unser_declare; xattr_t *current_xattr; /** * Parse the stream and call restore_xattr_on_file for each extended attribute. * * Start unserializing the data. We keep on looping while we have not * unserialized all bytes in the stream. */ unser_begin(content, content_length); while (unser_length(content) < content_length) { /* * First make sure the magic is present. This way we can easily catch corruption. * Any missing MAGIC is fatal we do NOT try to continue. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); unser_uint32(current_xattr->magic); if (current_xattr->magic != XATTR_MAGIC) { Mmsg1(jcr->errmsg, _("Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n", xattr_data->last_fname); free(current_xattr); return bxattr_exit_error; } /* * Decode the valuepair. First decode the length of the name. */ unser_uint32(current_xattr->name_length); if (current_xattr->name_length == 0) { Mmsg1(jcr->errmsg, _("Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Illegal xattr stream, xattr name length <= 0 on file \"%s\"\n", xattr_data->last_fname); free(current_xattr); return bxattr_exit_error; } /* * Allocate room for the name and decode its content. */ current_xattr->name = (char *)malloc(current_xattr->name_length + 1); unser_bytes(current_xattr->name, current_xattr->name_length); /* * The xattr_name needs to be null terminated. */ current_xattr->name[current_xattr->name_length] = '\0'; /* * Decode the value length. */ unser_uint32(current_xattr->value_length); if (current_xattr->value_length > 0) { /* * Allocate room for the value and decode its content. */ current_xattr->value = (char *)malloc(current_xattr->value_length); unser_bytes(current_xattr->value, current_xattr->value_length); Dmsg3(100, "Restoring xattr named %s, value %*s\n", current_xattr->name, current_xattr->value_length, current_xattr->value); } else { current_xattr->value = NULL; Dmsg1(100, "Restoring empty xattr named %s\n", current_xattr->name); } xattr_value_list->append(current_xattr); } unser_end(content, content_length); return bxattr_exit_ok; } /* * This is a supported OS, See what kind of interface we should use. */ #if defined(HAVE_AIX_OS) #if (!defined(HAVE_LISTEA) && !defined(HAVE_LLISTEA)) || \ (!defined(HAVE_GETEA) && !defined(HAVE_LGETEA)) || \ (!defined(HAVE_SETEA) && !defined(HAVE_LSETEA)) #error "Missing full support for the Extended Attributes (EA) functions." #endif #ifdef HAVE_SYS_EA_H #include #else #error "Missing sys/ea.h header file" #endif /* * Define the supported XATTR streams for this OS */ static int os_default_xattr_streams[1] = { STREAM_XATTR_AIX }; /* * Fallback to the non l-functions when those are not available. */ #if defined(HAVE_GETEA) && !defined(HAVE_LGETEA) #define lgetea getea #endif #if defined(HAVE_SETEA) && !defined(HAVE_LSETEA) #define lsetea setea #endif #if defined(HAVE_LISTEA) && !defined(HAVE_LLISTEA) #define llistea listea #endif static bxattr_exit_code aix_build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { char *bp; bool skip_xattr; char *xattr_list = NULL; int cnt, xattr_count = 0; uint32_t name_length; int32_t xattr_list_len, xattr_value_len; uint32_t expected_serialize_len = 0; xattr_t *current_xattr; alist *xattr_value_list = NULL; bxattr_exit_code retval = bxattr_exit_error; /* * First get the length of the available list with extended attributes. */ xattr_list_len = llistea(xattr_data->last_fname, NULL, 0); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case ENOENT: case EFORMAT: retval = bxattr_exit_ok; goto bail_out; case ENOTSUP: /* * If the filesystem reports it doesn't support XATTRs we clear the * BXATTR_FLAG_SAVE_NATIVE flag so we skip XATTR saves on all other files * on the same filesystem. The BXATTR_FLAG_SAVE_NATIVE flags gets sets again * when we change from one filesystem to an other. */ xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("llistea error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "llistea error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } case 0: retval = bxattr_exit_ok; goto bail_out; default: break; } /* * Allocate room for the extented attribute list. */ xattr_list = (char *)malloc(xattr_list_len + 1); memset(xattr_list, 0, xattr_list_len + 1); /* * Get the actual list of extended attributes names for a file. */ xattr_list_len = llistea(xattr_data->last_fname, xattr_list, xattr_list_len); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case ENOENT: case EFORMAT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("llistea error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "llistea error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } xattr_list[xattr_list_len] = '\0'; /* * Walk the list of extended attributes names and retrieve the data. * We already count the bytes needed for serializing the stream later on. */ for (bp = xattr_list; (bp - xattr_list) + 1 < xattr_list_len; bp = strchr(bp, '\0') + 1) { skip_xattr = false; /* * We want to skip certain xattrs which start with a 0xF8 character on AIX. */ if (*bp == 0xF8) { skip_xattr = true; } name_length = strlen(bp); if (skip_xattr || name_length == 0) { Dmsg1(100, "Skipping xattr named %s\n", bp); continue; } /* * First see how long the value is for the extended attribute. */ xattr_value_len = lgetea(xattr_data->last_fname, bp, NULL, 0); switch (xattr_value_len) { case -1: { berrno be; switch (errno) { case ENOENT: case EFORMAT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("lgetea error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "lgetea error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } /* * Each xattr valuepair starts with a magic so we can parse it easier. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); current_xattr->magic = XATTR_MAGIC; expected_serialize_len += sizeof(current_xattr->magic); /* * Allocate space for storing the name. */ current_xattr->name_length = name_length; current_xattr->name = (char *)malloc(current_xattr->name_length); memcpy(current_xattr->name, bp, current_xattr->name_length); expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; switch (xattr_value_len) { case 0: current_xattr->value = NULL; current_xattr->value_length = 0; expected_serialize_len += sizeof(current_xattr->value_length); break; default: /* * Allocate space for storing the value. */ current_xattr->value = (char *)malloc(xattr_value_len); memset(current_xattr->value, 0, xattr_value_len); xattr_value_len = lgetea(xattr_data->last_fname, bp, current_xattr->value, xattr_value_len); if (xattr_value_len < 0) { berrno be; switch (errno) { case ENOENT: case EFORMAT: retval = bxattr_exit_ok; break; default: Mmsg2(jcr->errmsg, _("lgetea error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "lgetea error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); break; } /* * Default failure path out when retrieval of attr fails. */ free(current_xattr->value); free(current_xattr->name); free(current_xattr); goto bail_out; } /* * Store the actual length of the value. */ current_xattr->value_length = xattr_value_len; expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; break; } if (xattr_value_list == NULL) { xattr_value_list = New(alist(10, not_owned_by_alist)); } xattr_value_list->append(current_xattr); xattr_count++; /* * Protect ourself against things getting out of hand. */ if (expected_serialize_len >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } } free(xattr_list); xattr_list = (char *)NULL; /* * If we found any xattr send them to the SD. */ if (xattr_count > 0) { /* * Serialize the datastream. */ if (serialize_xattr_stream(jcr, xattr_data, expected_serialize_len, xattr_value_list) < expected_serialize_len) { Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Send the datastream to the SD. */ retval = send_xattr_stream(jcr, xattr_data, os_default_xattr_streams[0]); } else { retval = bxattr_exit_ok; } bail_out: if (xattr_list != NULL) { free(xattr_list); } if (xattr_value_list != NULL) { xattr_drop_internal_table(xattr_value_list); } return retval; } static bxattr_exit_code aix_parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { xattr_t *current_xattr; alist *xattr_value_list; bxattr_exit_code retval = bxattr_exit_error; xattr_value_list = New(alist(10, not_owned_by_alist)); if (unserialize_xattr_stream(jcr, xattr_data, content, content_length, xattr_value_list) != bxattr_exit_ok) { goto bail_out; } foreach_alist(current_xattr, xattr_value_list) { if (lsetea(xattr_data->last_fname, current_xattr->name, current_xattr->value, current_xattr->value_length, 0) != 0) { berrno be; switch (errno) { case ENOENT: case EFORMAT: goto bail_out; case ENOTSUP: /* * If the filesystem reports it doesn't support XATTRs we clear * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores * on all other files on the same filesystem. The * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we * change from one filesystem to an other. */ xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; goto bail_out; default: Mmsg2(jcr->errmsg, _("lsetea error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "lsetea error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } } retval = bxattr_exit_ok; bail_out: xattr_drop_internal_table(xattr_value_list); return retval; } /* * Function pointers to the build and parse function to use for these xattrs. */ static bxattr_exit_code (*os_build_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) = aix_build_xattr_streams; static bxattr_exit_code (*os_parse_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) = aix_parse_xattr_streams; #elif defined(HAVE_IRIX_OS) #include /* * Define the supported XATTR streams for this OS */ static int os_default_xattr_streams[1] = { STREAM_XATTR_IRIX }; static const char *xattr_acl_skiplist[1] = { NULL }; static const char *xattr_skiplist[1] = { NULL }; struct xattr_naming_space { const char *name; int flags; }; static xattr_naming_space xattr_naming_spaces[] = { { "user.", ATTR_DONTFOLLOW }, { "root.", ATTR_ROOT | ATTR_DONTFOLLOW }, { NULL, 0 } }; static bxattr_exit_code irix_build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { char dummy[32]; int cnt, length, xattr_count = 0; attrlist_cursor_t cursor; attrlist_t *attrlist; attrlist_ent_t *attrlist_ent; xattr_t *current_xattr; alist *xattr_value_list = NULL; uint32_t expected_serialize_len = 0; bxattr_exit_code retval = bxattr_exit_error; POOLMEM *xattrbuf = get_memory(ATTR_MAX_VALUELEN); for (cnt = 0; xattr_naming_spaces[cnt].name != NULL; cnt++) { memset(&cursor, 0, sizeof(attrlist_cursor_t)); while (1) { if (attr_list(xattr_data->last_fname, xattrbuf, ATTR_MAX_VALUELEN, xattr_naming_spaces[cnt].flags, &cursor) != 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "attr_list error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } attrlist = (attrlist_t *)xattrbuf; /* * Walk the available attributes. */ for (cnt = 0; cnt < attrlist->al_count; cnt++) { attrlist_ent = ATTR_ENTRY(xattrbuf, cnt); /* * First determine if we can retrieve the xattr and how big it really is. */ length = sizeof(dummy); if (attr_get(xattr_data->last_fname, attrlist_ent->a_name, dummy, &length, xattr_naming_spaces[cnt].flags) != 0) { berrno be; switch (errno) { case ENOENT: case ENOATTR: retval = bxattr_exit_ok; goto bail_out; case E2BIG: /* * Size of the xattr is bigger then the 32 bytes dummy which is * likely. As length now contains its actual length we can allocate * a properly size buffer for the real retrieval. */ break; default: Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "attr_list error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Each xattr valuepair starts with a magic so we can parse it easier. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); current_xattr->magic = XATTR_MAGIC; expected_serialize_len += sizeof(current_xattr->magic); /* * Allocate space for storing the name. * We store the name as */ current_xattr->name_length = strlen(xattr_naming_spaces[cnt].name) + strlen(attrlist_ent->a_name) + 1; current_xattr->name = (char *)malloc(current_xattr->name_length); bsnprintf(current_xattr->name, current_xattr->name_length, "%s%s", xattr_naming_spaces[cnt].name, attrlist_ent->a_name); expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; current_xattr->value_length = length; current_xattr->value = (char *)malloc(current_xattr->value_length); /* * Retrieve the actual value of the xattr. */ if (attr_get(xattr_data->last_fname, attrlist_ent->a_name, current_xattr->value, &length, xattr_naming_spaces[cnt].flags) != 0) { berrno be; switch (errno) { case ENOENT: case ENOATTR: retval = bxattr_exit_ok; break; case E2BIG: /* * The buffer for the xattr isn't big enough. the value of * current_xattr->value_length is updated with the actual size * of the xattr. So we free the old buffer and create a new one * and try again. Normally this cannot happen as we size the * buffer using a call to attr_get before but in case of an * race condition it might happen. */ free(current_xattr->value); current_xattr->value = (char *)malloc(length); if (attr_get(xattr_data->last_fname, attrlist_ent->a_name, current_xattr->value, &length, xattr_naming_spaces[cnt].flags) != 0) { switch (errno) { case ENOENT: case ENOATTR: retval = bxattr_exit_ok; break; default: Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror(errno)); Dmsg2(100, "attr_list error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); break; } } else { goto ok_continue; } break; default: Mmsg2(jcr->errmsg, _("attr_list error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "attr_list error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); break; } /* * Default failure path out when retrieval of attr fails. */ free(current_xattr->value); free(current_xattr->name); free(current_xattr); goto bail_out; } ok_continue: current_xattr->value_length = length; expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; if (xattr_value_list == NULL) { xattr_value_list = New(alist(10, not_owned_by_alist)); } xattr_value_list->append(current_xattr); xattr_count++; /* * Protect ourself against things getting out of hand. */ if (expected_serialize_len >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } } /* * See if there are more attributes available for a next run of attr_list. */ if (attrlist->al_more == 0) { break; } } } /* * If we found any xattr send them to the SD. */ if (xattr_count > 0) { /* * Serialize the datastream. */ if (serialize_xattr_stream(jcr, xattr_data, expected_serialize_len, xattr_value_list) < expected_serialize_len) { Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Send the datastream to the SD. */ retval = send_xattr_stream(jcr, xattr_data, os_default_xattr_streams[0]); } else { retval = bxattr_exit_ok; } bail_out: free_pool_memory(xattrbuf); if (xattr_value_list != NULL) { xattr_drop_internal_table(xattr_value_list); } return retval; } static bxattr_exit_code irix_parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { char *bp; int cnt, cmp_size, name_space_index, flags; xattr_t *current_xattr; alist *xattr_value_list; bxattr_exit_code retval = bxattr_exit_error; xattr_value_list = New(alist(10, not_owned_by_alist)); if (unserialize_xattr_stream(jcr, xattr_data, content, content_length, xattr_value_list) != bxattr_exit_ok) { goto bail_out; } foreach_alist(current_xattr, xattr_value_list) { /* * See to what namingspace this xattr belongs to. */ name_space_index = 0; for (cnt = 0; xattr_naming_spaces[cnt].name != NULL; cnt++) { cmp_size = strlen(xattr_naming_spaces[cnt].name); if (bstrncasecmp(current_xattr->name, xattr_naming_spaces[cnt].name, cmp_size)) { name_space_index = cnt; break; } } /* * If we got a xattr that doesn't belong to an valid namespace complain. */ if (name_space_index == 0) { Mmsg2(jcr->errmsg, _("Received illegal xattr named %s on file \"%s\"\n"), current_xattr->name, xattr_data->last_fname); Dmsg2(100, "Received illegal xattr named %s on file \"%s\"\n", current_xattr->name, xattr_data->last_fname); goto bail_out; } /* * Restore the xattr first try to create the attribute from scratch. */ flags = xattr_naming_spaces[name_space_index].flags | ATTR_CREATE; bp = strchr(current_xattr->name, '.'); if (attr_set(xattr_data->last_fname, ++bp, current_xattr->value, current_xattr->value_length, flags) != 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; case EEXIST: /* * The xattr already exists we need to replace it. */ flags = xattr_naming_spaces[name_space_index].flags | ATTR_REPLACE; if (attr_set(xattr_data->last_fname, bp, current_xattr->value, current_xattr->value_length, flags) != 0) { switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("attr_set error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror(errno)); Dmsg2(100, "attr_set error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } break; default: Mmsg2(jcr->errmsg, _("attr_set error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "attr_set error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } } retval = bxattr_exit_ok; bail_out: xattr_drop_internal_table(xattr_value_list); return retval; } /* * Function pointers to the build and parse function to use for these xattrs. */ static bxattr_exit_code (*os_build_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) = irix_build_xattr_streams; static bxattr_exit_code (*os_parse_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) = irix_parse_xattr_streams; #elif defined(HAVE_DARWIN_OS) || \ defined(HAVE_LINUX_OS) || \ defined(HAVE_HURD_OS) #if (!defined(HAVE_LISTXATTR) && !defined(HAVE_LLISTXATTR)) || \ (!defined(HAVE_GETXATTR) && !defined(HAVE_LGETXATTR)) || \ (!defined(HAVE_SETXATTR) && !defined(HAVE_LSETXATTR)) #error "Missing full support for the XATTR functions." #endif #ifdef HAVE_SYS_XATTR_H #include #else #error "Missing sys/xattr.h header file" #endif /* * Define the supported XATTR streams for this OS */ #if defined(HAVE_DARWIN_OS) static int os_default_xattr_streams[1] = { STREAM_XATTR_DARWIN }; static const char *xattr_acl_skiplist[2] = { "com.apple.system.Security", NULL }; static const char *xattr_skiplist[3] = { "com.apple.system.extendedsecurity", "com.apple.ResourceFork", NULL }; #elif defined(HAVE_LINUX_OS) static int os_default_xattr_streams[1] = { STREAM_XATTR_LINUX }; static const char *xattr_acl_skiplist[3] = { "system.posix_acl_access", "system.posix_acl_default", NULL }; static const char *xattr_skiplist[1] = { NULL }; #elif defined(HAVE_HURD_OS) static int os_default_xattr_streams[1] = { STREAM_XATTR_HURD }; static const char *xattr_acl_skiplist[1] = { NULL }; static const char *xattr_skiplist[1] = { NULL }; #endif /* * OSX doesn't have llistxattr, lgetxattr and lsetxattr but has * listxattr, getxattr and setxattr with an extra options argument * which mimics the l variants of the functions when we specify * XATTR_NOFOLLOW as the options value. */ #if defined(HAVE_DARWIN_OS) #define llistxattr(path, list, size) \ listxattr((path), (list), (size), XATTR_NOFOLLOW) #define lgetxattr(path, name, value, size) \ getxattr((path), (name), (value), (size), 0, XATTR_NOFOLLOW) #define lsetxattr(path, name, value, size, flags) \ setxattr((path), (name), (value), (size), (flags), XATTR_NOFOLLOW) #else /* * Fallback to the non l-functions when those are not available. */ #if defined(HAVE_GETXATTR) && !defined(HAVE_LGETXATTR) #define lgetxattr getxattr #endif #if defined(HAVE_SETXATTR) && !defined(HAVE_LSETXATTR) #define lsetxattr setxattr #endif #if defined(HAVE_LISTXATTR) && !defined(HAVE_LLISTXATTR) #define llistxattr listxattr #endif #endif static bxattr_exit_code generic_build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { char *bp; bool skip_xattr; char *xattr_list = NULL; int cnt, xattr_count = 0; uint32_t name_length; int32_t xattr_list_len, xattr_value_len; uint32_t expected_serialize_len = 0; xattr_t *current_xattr; alist *xattr_value_list = NULL; bxattr_exit_code retval = bxattr_exit_error; /* * First get the length of the available list with extended attributes. */ xattr_list_len = llistxattr(xattr_data->last_fname, NULL, 0); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; case BXATTR_ENOTSUP: /* * If the filesystem reports it doesn't support XATTRs we clear * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores * on all other files on the same filesystem. The * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we * change from one filesystem to an other. */ xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "llistxattr error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } case 0: retval = bxattr_exit_ok; goto bail_out; default: break; } /* * Allocate room for the extented attribute list. */ xattr_list = (char *)malloc(xattr_list_len + 1); memset(xattr_list, 0, xattr_list_len + 1); /* * Get the actual list of extended attributes names for a file. */ xattr_list_len = llistxattr(xattr_data->last_fname, xattr_list, xattr_list_len); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "llistxattr error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } xattr_list[xattr_list_len] = '\0'; /* * Walk the list of extended attributes names and retrieve the data. * We already count the bytes needed for serializing the stream later on. */ for (bp = xattr_list; (bp - xattr_list) + 1 < xattr_list_len; bp = strchr(bp, '\0') + 1) { skip_xattr = false; /* * On some OSes you also get the acls in the extented attribute list. * So we check if we are already backing up acls and if we do we * don't store the extended attribute with the same info. */ if (bit_is_set(FO_ACL, ff_pkt->flags)) { for (cnt = 0; xattr_acl_skiplist[cnt] != NULL; cnt++) { if (bstrcmp(bp, xattr_acl_skiplist[cnt])) { skip_xattr = true; break; } } } /* * On some OSes we want to skip certain xattrs which are in the xattr_skiplist array. */ if (!skip_xattr) { for (cnt = 0; xattr_skiplist[cnt] != NULL; cnt++) { if (bstrcmp(bp, xattr_skiplist[cnt])) { skip_xattr = true; break; } } } name_length = strlen(bp); if (skip_xattr || name_length == 0) { Dmsg1(100, "Skipping xattr named %s\n", bp); continue; } /* * First see how long the value is for the extended attribute. */ xattr_value_len = lgetxattr(xattr_data->last_fname, bp, NULL, 0); switch (xattr_value_len) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("lgetxattr error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "lgetxattr error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } /* * Each xattr valuepair starts with a magic so we can parse it easier. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); current_xattr->magic = XATTR_MAGIC; current_xattr->value = NULL; expected_serialize_len += sizeof(current_xattr->magic); /* * Allocate space for storing the name. */ current_xattr->name_length = name_length; current_xattr->name = (char *)malloc(current_xattr->name_length); memcpy(current_xattr->name, bp, current_xattr->name_length); expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; switch (xattr_value_len) { case 0: current_xattr->value = NULL; current_xattr->value_length = 0; expected_serialize_len += sizeof(current_xattr->value_length); break; default: /* * Allocate space for storing the value. */ current_xattr->value = (char *)malloc(xattr_value_len); memset(current_xattr->value, 0, xattr_value_len); xattr_value_len = lgetxattr(xattr_data->last_fname, bp, current_xattr->value, xattr_value_len); if (xattr_value_len < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; break; default: Mmsg2(jcr->errmsg, _("lgetxattr error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "lgetxattr error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); break; } /* * Default failure path out when retrieval of attr fails. */ free(current_xattr->value); free(current_xattr->name); free(current_xattr); goto bail_out; } /* * Store the actual length of the value. */ current_xattr->value_length = xattr_value_len; expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; break; } if (xattr_value_list == NULL) { xattr_value_list = New(alist(10, not_owned_by_alist)); } xattr_value_list->append(current_xattr); xattr_count++; /* * Protect ourself against things getting out of hand. */ if (expected_serialize_len >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } } free(xattr_list); xattr_list = (char *)NULL; /* * If we found any xattr send them to the SD. */ if (xattr_count > 0) { /* * Serialize the datastream. */ if (serialize_xattr_stream(jcr, xattr_data, expected_serialize_len, xattr_value_list) < expected_serialize_len) { Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Send the datastream to the SD. */ retval = send_xattr_stream(jcr, xattr_data, os_default_xattr_streams[0]); } else { retval = bxattr_exit_ok; } bail_out: if (xattr_list != NULL) { free(xattr_list); } if (xattr_value_list != NULL) { xattr_drop_internal_table(xattr_value_list); } return retval; } static bxattr_exit_code generic_parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { xattr_t *current_xattr; alist *xattr_value_list; bxattr_exit_code retval = bxattr_exit_error; xattr_value_list = New(alist(10, not_owned_by_alist)); if (unserialize_xattr_stream(jcr, xattr_data, content, content_length, xattr_value_list) != bxattr_exit_ok) { goto bail_out; } foreach_alist(current_xattr, xattr_value_list) { if (lsetxattr(xattr_data->last_fname, current_xattr->name, current_xattr->value, current_xattr->value_length, 0) != 0) { berrno be; switch (errno) { case ENOENT: goto bail_out; case BXATTR_ENOTSUP: /* * If the filesystem reports it doesn't support XATTRs we clear * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores * on all other files on the same filesystem. The * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we * change from one filesystem to an other. */ xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; goto bail_out; default: Mmsg2(jcr->errmsg, _("lsetxattr error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "lsetxattr error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } } retval = bxattr_exit_ok; bail_out: xattr_drop_internal_table(xattr_value_list); return retval; } /* * Function pointers to the build and parse function to use for these xattrs. */ static bxattr_exit_code (*os_build_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) = generic_build_xattr_streams; static bxattr_exit_code (*os_parse_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) = generic_parse_xattr_streams; #elif defined(HAVE_FREEBSD_OS) || \ defined(HAVE_NETBSD_OS) || \ defined(HAVE_OPENBSD_OS) #if (!defined(HAVE_EXTATTR_GET_LINK) && !defined(HAVE_EXTATTR_GET_FILE)) || \ (!defined(HAVE_EXTATTR_SET_LINK) && !defined(HAVE_EXTATTR_SET_FILE)) || \ (!defined(HAVE_EXTATTR_LIST_LINK) && !defined(HAVE_EXTATTR_LIST_FILE)) || \ !defined(HAVE_EXTATTR_NAMESPACE_TO_STRING) || \ !defined(HAVE_EXTATTR_STRING_TO_NAMESPACE) #error "Missing full support for the extattr functions." #endif #ifdef HAVE_SYS_EXTATTR_H #include #else #error "Missing sys/extattr.h header file" #endif #ifdef HAVE_LIBUTIL_H #include #endif #if !defined(HAVE_EXTATTR_GET_LINK) && defined(HAVE_EXTATTR_GET_FILE) #define extattr_get_link extattr_get_file #endif #if !defined(HAVE_EXTATTR_SET_LINK) && defined(HAVE_EXTATTR_SET_FILE) #define extattr_set_link extattr_set_file #endif #if !defined(HAVE_EXTATTR_LIST_LINK) && defined(HAVE_EXTATTR_LIST_FILE) #define extattr_list_link extattr_list_file #endif #if defined(HAVE_FREEBSD_OS) static int os_default_xattr_streams[1] = { STREAM_XATTR_FREEBSD }; static int os_default_xattr_namespaces[2] = { EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM }; static const char *xattr_acl_skiplist[4] = { "system.posix1e.acl_access", "system.posix1e.acl_default", "system.nfs4.acl", NULL }; static const char *xattr_skiplist[1] = { NULL }; #elif defined(HAVE_NETBSD_OS) static int os_default_xattr_streams[1] = { STREAM_XATTR_NETBSD }; static int os_default_xattr_namespaces[2] = { EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM }; static const char *xattr_acl_skiplist[1] = { NULL }; static const char *xattr_skiplist[1] = { NULL }; #elif defined(HAVE_OPENBSD_OS) static int os_default_xattr_streams[1] = { STREAM_XATTR_OPENBSD }; static int os_default_xattr_namespaces[2] = { EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM }; static const char *xattr_acl_skiplist[1] = { NULL }; static const char *xattr_skiplist[1] = { NULL }; #endif static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { bool skip_xattr; char *xattr_list = NULL; int cnt, index, xattr_count = 0; int32_t xattr_list_len, xattr_value_len; uint32_t expected_serialize_len = 0; unsigned int namespace_index; int attrnamespace; char *current_attrnamespace = NULL; char current_attrname[XATTR_BUFSIZ], current_attrtuple[XATTR_BUFSIZ]; xattr_t *current_xattr; alist *xattr_value_list = NULL; bxattr_exit_code retval = bxattr_exit_error; /* * Loop over all available xattr namespaces. */ for (namespace_index = 0; namespace_index < sizeof(os_default_xattr_namespaces) / sizeof(int); namespace_index++) { attrnamespace = os_default_xattr_namespaces[namespace_index]; /* * First get the length of the available list with extended attributes. * If we get EPERM on system namespace, don't return error. * This is expected for normal users trying to archive the system * namespace on FreeBSD 6.2 and later. On NetBSD 3.1 and later, * they've decided to return EOPNOTSUPP instead. */ xattr_list_len = extattr_list_link(xattr_data->last_fname, attrnamespace, NULL, 0); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; #if defined(EOPNOTSUPP) case EOPNOTSUPP: #endif case EPERM: if (attrnamespace == EXTATTR_NAMESPACE_SYSTEM) { continue; } /* * FALLTHROUGH */ default: Mmsg2(jcr->errmsg, _("extattr_list_link error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "extattr_list_link error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } case 0: continue; default: break; } /* * Allocate room for the extented attribute list. */ xattr_list = (char *)malloc(xattr_list_len + 1); memset(xattr_list, 0, xattr_list_len + 1); /* * Get the actual list of extended attributes names for a file. */ xattr_list_len = extattr_list_link(xattr_data->last_fname, attrnamespace, xattr_list, xattr_list_len); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("extattr_list_link error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "extattr_list_link error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } xattr_list[xattr_list_len] = '\0'; /* * Convert the numeric attrnamespace into a string representation and make * a private copy of that string. The extattr_namespace_to_string functions * returns a strdupped string which we need to free. */ if (extattr_namespace_to_string(attrnamespace, ¤t_attrnamespace) != 0) { Mmsg2(jcr->errmsg, _("Failed to convert %d into namespace on file \"%s\"\n"), attrnamespace, xattr_data->last_fname); Dmsg2(100, "Failed to convert %d into namespace on file \"%s\"\n", attrnamespace, xattr_data->last_fname); goto bail_out; } /* * Walk the list of extended attributes names and retrieve the data. * We already count the bytes needed for serializing the stream later on. */ for (index = 0; index < xattr_list_len; index += xattr_list[index] + 1) { skip_xattr = false; /* * Print the current name into the buffer as its not null terminated * we need to use the length encoded in the string for copying only * the needed bytes. */ cnt = xattr_list[index]; if (cnt > ((int)sizeof(current_attrname) - 1)) { cnt = ((int)sizeof(current_attrname) - 1); } strncpy(current_attrname, xattr_list + (index + 1), cnt); current_attrname[cnt] = '\0'; /* * First make a xattr tuple of the current namespace and the name of * the xattr. e.g. something like user. or system. */ bsnprintf(current_attrtuple, sizeof(current_attrtuple), "%s.%s", current_attrnamespace, current_attrname); /* * On some OSes you also get the acls in the extented attribute list. * So we check if we are already backing up acls and if we do we * don't store the extended attribute with the same info. */ if (bit_is_set(FO_ACL, ff_pkt->flags)) { for (cnt = 0; xattr_acl_skiplist[cnt] != NULL; cnt++) { if (bstrcmp(current_attrtuple, xattr_acl_skiplist[cnt])) { skip_xattr = true; break; } } } /* * On some OSes we want to skip certain xattrs which are in the * xattr_skiplist array. */ if (!skip_xattr) { for (cnt = 0; xattr_skiplist[cnt] != NULL; cnt++) { if (bstrcmp(current_attrtuple, xattr_skiplist[cnt])) { skip_xattr = true; break; } } } if (skip_xattr) { Dmsg1(100, "Skipping xattr named %s\n", current_attrname); continue; } /* * First see how long the value is for the extended attribute. */ xattr_value_len = extattr_get_link(xattr_data->last_fname, attrnamespace, current_attrname, NULL, 0); switch (xattr_value_len) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("extattr_get_link error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "extattr_get_link error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } /* * Each xattr valuepair starts with a magic so we can parse it easier. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); current_xattr->magic = XATTR_MAGIC; current_xattr->value = NULL; expected_serialize_len += sizeof(current_xattr->magic); /* * Allocate space for storing the name. */ current_xattr->name_length = strlen(current_attrtuple); current_xattr->name = (char *)malloc(current_xattr->name_length); memcpy(current_xattr->name, current_attrtuple, current_xattr->name_length); expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; switch (xattr_value_len) { case 0: current_xattr->value = NULL; current_xattr->value_length = 0; expected_serialize_len += sizeof(current_xattr->value_length); break; default: /* * Allocate space for storing the value. */ current_xattr->value = (char *)malloc(xattr_value_len); memset(current_xattr->value, 0, xattr_value_len); xattr_value_len = extattr_get_link(xattr_data->last_fname, attrnamespace, current_attrname, current_xattr->value, xattr_value_len); if (xattr_value_len < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; break; default: Mmsg2(jcr->errmsg, _("extattr_get_link error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "extattr_get_link error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); break; } /* * Default failure path out when retrieval of attr fails. */ free(current_xattr->value); free(current_xattr->name); free(current_xattr); goto bail_out; } /* * Store the actual length of the value. */ current_xattr->value_length = xattr_value_len; expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; break; } if (xattr_value_list == NULL) { xattr_value_list = New(alist(10, not_owned_by_alist)); } xattr_value_list->append(current_xattr); xattr_count++; /* * Protect ourself against things getting out of hand. */ if (expected_serialize_len >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } } /* * Drop the local copy of the current_attrnamespace. */ actuallyfree(current_attrnamespace); current_attrnamespace = NULL; /* * We are done with this xattr list. */ free(xattr_list); xattr_list = (char *)NULL; } /* * If we found any xattr send them to the SD. */ if (xattr_count > 0) { /* * Serialize the datastream. */ if (serialize_xattr_stream(jcr, xattr_data, expected_serialize_len, xattr_value_list) < expected_serialize_len) { Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Send the datastream to the SD. */ retval = send_xattr_stream(jcr, xattr_data, os_default_xattr_streams[0]); } else { retval = bxattr_exit_ok; } bail_out: if (current_attrnamespace != NULL) { actuallyfree(current_attrnamespace); } if (xattr_list != NULL) { free(xattr_list); } if (xattr_value_list != NULL) { xattr_drop_internal_table(xattr_value_list); } return retval; } static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { xattr_t *current_xattr; alist *xattr_value_list; int current_attrnamespace, cnt; char *attrnamespace, *attrname; bxattr_exit_code retval = bxattr_exit_error; xattr_value_list = New(alist(10, not_owned_by_alist)); if (unserialize_xattr_stream(jcr, xattr_data, content, content_length, xattr_value_list) != bxattr_exit_ok) { goto bail_out; } foreach_alist(current_xattr, xattr_value_list) { /* * Try splitting the xattr_name into a namespace and name part. * The splitting character is a . */ attrnamespace = current_xattr->name; if ((attrname = strchr(attrnamespace, '.')) == (char *)NULL) { Mmsg2(jcr->errmsg, _("Failed to split %s into namespace and name part on file \"%s\"\n"), current_xattr->name, xattr_data->last_fname); Dmsg2(100, "Failed to split %s into namespace and name part on file \"%s\"\n", current_xattr->name, xattr_data->last_fname); goto bail_out; } *attrname++ = '\0'; /* * Make sure the attrnamespace makes sense. */ if (extattr_string_to_namespace(attrnamespace, ¤t_attrnamespace) != 0) { Mmsg2(jcr->errmsg, _("Failed to convert %s into namespace on file \"%s\"\n"), attrnamespace, xattr_data->last_fname); Dmsg2(100, "Failed to convert %s into namespace on file \"%s\"\n", attrnamespace, xattr_data->last_fname); goto bail_out; } /* * Try restoring the extended attribute. */ cnt = extattr_set_link(xattr_data->last_fname, current_attrnamespace, attrname, current_xattr->value, current_xattr->value_length); if (cnt < 0 || cnt != (int)current_xattr->value_length) { berrno be; switch (errno) { case ENOENT: goto bail_out; break; default: Mmsg2(jcr->errmsg, _("extattr_set_link error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "extattr_set_link error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; break; } } } retval = bxattr_exit_ok; bail_out: xattr_drop_internal_table(xattr_value_list); return retval; } /* * Function pointers to the build and parse function to use for these xattrs. */ static bxattr_exit_code (*os_build_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) = bsd_build_xattr_streams; static bxattr_exit_code (*os_parse_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) = bsd_parse_xattr_streams; #elif defined(HAVE_OSF1_OS) #if !defined(HAVE_GETPROPLIST) || \ !defined(HAVE_GET_PROPLIST_ENTRY) || \ !defined(HAVE_SIZEOF_PROPLIST_ENTRY) || \ !defined(HAVE_ADD_PROPLIST_ENTRY) || \ !defined(HAVE_SETPROPLIST) #error "Missing full support for the Extended Attributes functions." #endif #ifdef HAVE_SYS_PROPLIST_H #include #else #error "Missing sys/proplist.h header file" #endif /* * Define the supported XATTR streams for this OS */ static int os_default_xattr_streams[1] = { STREAM_XATTR_TRU64 }; static const char *xattr_acl_skiplist[1] = { NULL }; static const char *xattr_skiplist[1] = { NULL }; static bxattr_exit_code tru64_build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { int cnt; char *bp, *xattr_name, *xattr_value; bool skip_xattr; int xattr_count = 0; int32_t *flags, *xattr_value_len; int32_t xattr_list_len, xattrbuf_size, xattrbuf_min_size; uint32_t expected_serialize_len = 0; xattr_t *current_xattr; alist *xattr_value_list = NULL; struct proplistname_args prop_args; bxattr_exit_code retval = bxattr_exit_error; POOLMEM *xattrbuf = get_pool_memory(PM_MESSAGE); xattrbuf_size = sizeof_pool_memory(xattrbuf); xattrbuf_min_size = 0; xattr_list_len = getproplist(xattr_data->last_fname, 1, &prop_args, xattrbuf_size, xattrbuf, &xattrbuf_min_size); /* * See what xattr are available. */ switch (xattr_list_len) { case -1: { berrno be; switch (errno) { case EOPNOTSUPP: /* * If the filesystem reports it doesn't support XATTRs we clear * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores * on all other files on the same filesystem. The * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we * change from one filesystem to an other. */ xattr_data->flags &= ~BXATTR_FLAG_SAVE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("getproplist error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "getproplist error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } case 0: if (xattrbuf_min_size) { /* * The buffer isn't big enough to hold the xattr data, we now have * a minimum buffersize so we resize the buffer and try again. */ xattrbuf = check_pool_memory_size(xattrbuf, xattrbuf_min_size + 1); xattrbuf_size = xattrbuf_min_size + 1; xattr_list_len = getproplist(xattr_data->last_fname, 1, &prop_args, xattrbuf_size, xattrbuf, &xattrbuf_min_size); switch (xattr_list_len) { case -1: { berrno be; switch (errno) { default: Mmsg2(jcr->errmsg, _("getproplist error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "getproplist error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } case 0: /* * This should never happen as we sized the buffer according to the minimumsize * returned by a previous getproplist call. If it does happen things are fishy and * we are better of forgetting this xattr as it seems its list is changing at this * exact moment so we can never make a good backup copy of it. */ retval = bxattr_exit_ok; goto bail_out; default: break; } } else { /* * No xattr on file. */ retval = bxattr_exit_ok; goto bail_out; } break; default: break; } /* * Walk the list of extended attributes names and retrieve the data. * We already count the bytes needed for serializing the stream later on. */ bp = xattrbuf; while (xattrbuf_size > 0) { /* * Call getproplist_entry to initialize name and value * pointers to entries position within buffer. */ xattrbuf_size -= get_proplist_entry(&xattr_name, &flags, &xattr_value_len, &xattr_value, &bp); /* * On some OSes you also get the acls in the extented attribute list. * So we check if we are already backing up acls and if we do we * don't store the extended attribute with the same info. */ if (bit_is_set(FO_ACL, ff_pkt->flags)) { for (cnt = 0; xattr_acl_skiplist[cnt] != NULL; cnt++) { if (bstrcmp(xattr_name, xattr_acl_skiplist[cnt])) { skip_xattr = true; break; } } } /* * On some OSes we want to skip certain xattrs which are in the xattr_skiplist array. */ if (!skip_xattr) { for (cnt = 0; xattr_skiplist[cnt] != NULL; cnt++) { if (bstrcmp(xattr_name, xattr_skiplist[cnt])) { skip_xattr = true; break; } } } if (skip_xattr) { Dmsg1(100, "Skipping xattr named %s\n", xattr_name); continue; } /* * Each xattr valuepair starts with a magic so we can parse it easier. */ current_xattr = (xattr_t *)malloc(sizeof(xattr_t)); current_xattr->magic = XATTR_MAGIC; expected_serialize_len += sizeof(current_xattr->magic); current_xattr->name_length = strlen(xattr_name); current_xattr->name = bstrdup(xattr_name); expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length; current_xattr->value_length = *xattr_value_len; current_xattr->value = (char *)malloc(current_xattr->value_length); memcpy(current_xattr->value, xattr_value, current_xattr->value_length); expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length; if (xattr_value_list == NULL) { xattr_value_list = New(alist(10, not_owned_by_alist)); } xattr_value_list->append(current_xattr); xattr_count++; /* * Protect ourself against things getting out of hand. */ if (expected_serialize_len >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } } /* * If we found any xattr send them to the SD. */ if (xattr_count > 0) { /* * Serialize the datastream. */ if (serialize_xattr_stream(jcr, xattr_data, expected_serialize_len, xattr_value_list) < expected_serialize_len) { Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Send the datastream to the SD. */ retval = send_xattr_stream(jcr, xattr_data, os_default_xattr_streams[0]); } else { retval = bxattr_exit_ok; } bail_out: if (xattr_value_list != NULL) { xattr_drop_internal_table(xattr_value_list); } free_pool_memory(xattrbuf); return retval; } static bxattr_exit_code tru64_parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { char *bp, *xattrbuf = NULL; int32_t xattrbuf_size, cnt; xattr_t *current_xattr; alist *xattr_value_list; bxattr_exit_code retval = bxattr_exit_error; xattr_value_list = New(alist(10, not_owned_by_alist)); if (unserialize_xattr_stream(jcr, xattr_data, content, content_length, xattr_value_list) != bxattr_exit_ok) { goto bail_out; } /* * See how big the propertylist must be. */ xattrbuf_size = 0; foreach_alist(current_xattr, xattr_value_list) { xattrbuf_size += sizeof_proplist_entry(current_xattr->name, current_xattr->value_length); } xattrbuf = (char *)malloc(xattrbuf_size); /* * Add all value pairs to the proplist. */ cnt = 0; bp = xattrbuf; foreach_alist(current_xattr, xattr_value_list) { cnt = add_proplist_entry(current_xattr->name, 0, current_xattr->value_length, current_xattr->value, &bp); } /* * Sanity check. */ if (cnt != xattrbuf_size) { Mmsg1(jcr->errmsg, _("Unable create proper proplist to restore xattrs on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Unable create proper proplist to restore xattrs on file \"%s\"\n", xattr_data->last_fname); goto bail_out; } /* * Restore the list of extended attributes on the file. */ cnt = setproplist(xattr_data->last_fname, 1, xattrbuf_size, xattrbuf); switch (cnt) { case -1: { berrno be; switch (errno) { case EOPNOTSUPP: /* * If the filesystem reports it doesn't support XATTRs we clear * the BXATTR_FLAG_RESTORE_NATIVE flag so we skip XATTR restores * on all other files on the same filesystem. The * BXATTR_FLAG_RESTORE_NATIVE flags gets sets again when we * change from one filesystem to an other. */ xattr_data->flags &= ~BXATTR_FLAG_RESTORE_NATIVE; retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("setproplist error on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "setproplist error file=%s ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } default: break; } retval = bxattr_exit_ok; bail_out: if (xattrbuf) { free(xattrbuf); } xattr_drop_internal_table(xattr_value_list); return retval; } /* * Function pointers to the build and parse function to use for these xattrs. */ static bxattr_exit_code (*os_build_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) = tru64_build_xattr_streams; static bxattr_exit_code (*os_parse_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) = tru64_parse_xattr_streams; #elif defined(HAVE_SUN_OS) /* * Solaris extended attributes were introduced in Solaris 9 * by PSARC 1999/209 * * Solaris extensible attributes were introduced in OpenSolaris * by PSARC 2007/315 Solaris extensible attributes are also * sometimes called extended system attributes. * * man fsattr(5) on Solaris gives a wealth of info. The most * important bits are: * * Attributes are logically supported as files within the file * system. The file system is therefore augmented with an * orthogonal name space of file attributes. Any file (includ- * ing attribute files) can have an arbitrarily deep attribute * tree associated with it. Attribute values are accessed by * file descriptors obtained through a special attribute inter- * face. This logical view of "attributes as files" allows the * leveraging of existing file system interface functionality * to support the construction, deletion, and manipulation of * attributes. * * The special files "." and ".." retain their accustomed * semantics within the attribute hierarchy. The "." attribute * file refers to the current directory and the ".." attribute * file refers to the parent directory. The unnamed directory * at the head of each attribute tree is considered the "child" * of the file it is associated with and the ".." file refers * to the associated file. For any non-directory file with * attributes, the ".." entry in the unnamed directory refers * to a file that is not a directory. * * Conceptually, the attribute model is fully general. Extended * attributes can be any type of file (doors, links, direc- * tories, and so forth) and can even have their own attributes * (fully recursive). As a result, the attributes associated * with a file could be an arbitrarily deep directory hierarchy * where each attribute could have an equally complex attribute * tree associated with it. Not all implementations are able * to, or want to, support the full model. Implementation are * therefore permitted to reject operations that are not sup- * ported. For example, the implementation for the UFS file * system allows only regular files as attributes (for example, * no sub-directories) and rejects attempts to place attributes * on attributes. * * The following list details the operations that are rejected * in the current implementation: * * link Any attempt to create links between * attribute and non-attribute space * is rejected to prevent security- * related or otherwise sensitive * attributes from being exposed, and * therefore manipulable, as regular * files. * * rename Any attempt to rename between * attribute and non-attribute space * is rejected to prevent an already * linked file from being renamed and * thereby circumventing the link res- * triction above. * * mkdir, symlink, mknod Any attempt to create a "non- * regular" file in attribute space is * rejected to reduce the functional- * ity, and therefore exposure and * risk, of the initial implementa- * tion. * * The entire available name space has been allocated to "gen- * eral use" to bring the implementation in line with the NFSv4 * draft standard [NFSv4]. That standard defines "named attri- * butes" (equivalent to Solaris Extended Attributes) with no * naming restrictions. All Sun applications making use of * opaque extended attributes will use the prefix "SUNW". * */ #ifdef HAVE_SYS_ATTR_H #include #endif #ifdef HAVE_ATTR_H #include #endif #ifdef HAVE_SYS_NVPAIR_H #include #endif #ifdef HAVE_SYS_ACL_H #include #endif #if !defined(HAVE_OPENAT) || \ !defined(HAVE_UNLINKAT) || \ !defined(HAVE_FCHOWNAT) || \ !defined(HAVE_FUTIMESAT) #error "Unable to compile code because of missing openat, unlinkat, fchownat or futimesat function" #endif /* * Define the supported XATTR streams for this OS */ #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) static int os_default_xattr_streams[2] = { STREAM_XATTR_SOLARIS, STREAM_XATTR_SOLARIS_SYS }; #else static int os_default_xattr_streams[1] = { STREAM_XATTR_SOLARIS }; #endif /* defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) */ /* * This code creates a temporary cache with entries for each xattr which has * a link count > 1 (which indicates it has one or more hard linked counterpart(s)) */ static inline xattr_link_cache_entry_t *find_xattr_link_cache_entry(xattr_data_t *xattr_data, ino_t inum) { xattr_link_cache_entry_t *ptr; foreach_alist(ptr, xattr_data->u.build->link_cache) { if (ptr && ptr->inum == inum) { return ptr; } } return NULL; } static inline void add_xattr_link_cache_entry(xattr_data_t *xattr_data, ino_t inum, char *target) { xattr_link_cache_entry_t *ptr; ptr = (xattr_link_cache_entry_t *)malloc(sizeof(xattr_link_cache_entry_t)); memset(ptr, 0, sizeof(xattr_link_cache_entry_t)); ptr->inum = inum; ptr->target = bstrdup(target); if (!xattr_data->u.build->link_cache) { xattr_data->u.build->link_cache = New(alist(10, not_owned_by_alist)); } xattr_data->u.build->link_cache->append(ptr); } static inline void drop_xattr_link_cache(xattr_data_t *xattr_data) { xattr_link_cache_entry_t *ptr; /* * Walk the list of xattr link cache entries and free allocated memory on traversing. */ foreach_alist(ptr, xattr_data->u.build->link_cache) { free(ptr->target); free(ptr); } delete xattr_data->u.build->link_cache; xattr_data->u.build->link_cache = NULL; } #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) /* * This function returns true if a non default extended system attribute * list is associated with fd and returns false when an error has occured * or when only extended system attributes other than archive, * av_modified or crtime are set. * * The function returns true for the following cases: * * - any extended system attribute other than the default attributes * ('archive', 'av_modified' and 'crtime') is set * - nvlist has NULL name string * - nvpair has data type of 'nvlist' * - default data type. */ static bool solaris_has_non_transient_extensible_attributes(int fd) { boolean_t value; data_type_t type; nvlist_t *response; nvpair_t *pair; f_attr_t fattr; char *name; bool retval = false; if (fgetattr(fd, XATTR_VIEW_READWRITE, &response) != 0) { return false; } pair = NULL; while ((pair = nvlist_next_nvpair(response, pair)) != NULL) { name = nvpair_name(pair); if (name != NULL) { fattr = name_to_attr(name); } else { retval = true; goto bail_out; } type = nvpair_type(pair); switch (type) { case DATA_TYPE_BOOLEAN_VALUE: if (nvpair_value_boolean_value(pair, &value) != 0) { continue; } if (value && fattr != F_ARCHIVE && fattr != F_AV_MODIFIED) { retval = true; goto bail_out; } break; case DATA_TYPE_UINT64_ARRAY: if (fattr != F_CRTIME) { retval = true; goto bail_out; } break; case DATA_TYPE_NVLIST: default: retval = true; goto bail_out; } } bail_out: if (response != NULL) { nvlist_free(response); } return retval; } #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */ #if defined(HAVE_ACL) && !defined(HAVE_EXTENDED_ACL) /* * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.) * There is no need to store those acls as we already store the stat bits too. */ static bool acl_is_trivial(int count, aclent_t *entries) { int n; aclent_t *ace; for (n = 0; n < count; n++) { ace = &entries[n]; if (!(ace->a_type == USER_OBJ || ace->a_type == GROUP_OBJ || ace->a_type == OTHER_OBJ || ace->a_type == CLASS_OBJ)) return false; } return true; } #endif /* HAVE_ACL && !HAVE_EXTENDED_ACL */ static bxattr_exit_code solaris_save_xattr_acl(JCR *jcr, xattr_data_t *xattr_data, int fd, const char *attrname, char **acl_text) { bxattr_exit_code retval = bxattr_exit_error; #ifdef HAVE_ACL #ifdef HAVE_EXTENDED_ACL int flags; acl_t *aclp = NULL; /* * See if this attribute has an ACL */ if ((fd != -1 && fpathconf(fd, _PC_ACL_ENABLED) > 0) || pathconf(attrname, _PC_ACL_ENABLED) > 0) { /* * See if there is a non trivial acl on the file. */ if ((fd != -1 && facl_get(fd, ACL_NO_TRIVIAL, &aclp) != 0) || acl_get(attrname, ACL_NO_TRIVIAL, &aclp) != 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg3(jcr->errmsg, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"), attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n", attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } if (aclp != NULL) { #if defined(ACL_SID_FMT) /* * New format flag added in newer Solaris versions. */ flags = ACL_APPEND_ID | ACL_COMPACT_FMT | ACL_SID_FMT; #else flags = ACL_APPEND_ID | ACL_COMPACT_FMT; #endif /* ACL_SID_FMT */ *acl_text = acl_totext(aclp, flags); acl_free(aclp); } else { *acl_text = NULL; } } else { *acl_text = NULL; } retval = bxattr_exit_ok; #else /* HAVE_EXTENDED_ACL */ int n; aclent_t *acls = NULL; /* * See if this attribute has an ACL */ if (fd != -1) { n = facl(fd, GETACLCNT, 0, NULL); } else { n = acl(attrname, GETACLCNT, 0, NULL); } if (n >= MIN_ACL_ENTRIES) { acls = (aclent_t *)malloc(n * sizeof(aclent_t)); if ((fd != -1 && facl(fd, GETACL, n, acls) != n) || acl(attrname, GETACL, n, acls) != n) { berrno be; switch (errno) { case ENOENT: free(acls); retval = bxattr_exit_ok; goto bail_out; default: Mmsg3(jcr->errmsg, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"), attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n", attrname, xattr_data->last_fname, be.bstrerror()); free(acls); goto bail_out; } } /* * See if there is a non trivial acl on the file. */ if (!acl_is_trivial(n, acls)) { if ((*acl_text = acltotext(acls, n)) == NULL) { berrno be; Mmsg3(jcr->errmsg, _("Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n"), attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n", attrname, xattr_data->last_fname, be.bstrerror()); free(acls); goto bail_out; } } else { *acl_text = NULL; } free(acls); } else { *acl_text = NULL; } retval = bxattr_exit_ok; #endif /* HAVE_EXTENDED_ACL */ #else /* HAVE_ACL */ retval = bxattr_exit_ok; #endif /* HAVE_ACL */ bail_out: return retval; } /* * Forward declaration for recursive function call. */ static bxattr_exit_code solaris_save_xattrs(JCR *jcr, xattr_data_t *xattr_data, const char *xattr_namespace, const char *attr_parent); /* * Save an extended or extensible attribute. * This is stored as an opaque stream of bytes with the following encoding: * * \0\0\0 * * or for a hardlinked or symlinked attribute * * \0\0\0 * * xattr_name can be a subpath relative to the file the xattr is on. * stat_buffer is the string representation of the stat struct. * acl_string is an acl text when a non trivial acl is set on the xattr. * actual_xattr_data is the content of the xattr file. */ static bxattr_exit_code solaris_save_xattr(JCR *jcr, xattr_data_t *xattr_data, int fd, const char *xattr_namespace, const char *attrname, bool toplevel_hidden_dir, int stream) { int cnt; int attrfd = -1; struct stat st; xattr_link_cache_entry_t *xlce; char target_attrname[PATH_MAX]; char link_source[PATH_MAX]; char *acl_text = NULL; char attribs[XATTR_BUFSIZ]; char buffer[XATTR_BUFSIZ]; bxattr_exit_code retval = bxattr_exit_error; bsnprintf(target_attrname, sizeof(target_attrname), "%s%s", xattr_namespace, attrname); /* * Get the stats of the extended or extensible attribute. */ if (fstatat(fd, attrname, &st, AT_SYMLINK_NOFOLLOW) < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg3(jcr->errmsg, _("Unable to get status on xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Based on the filetype perform the correct action. We support most filetypes here, more * then the actual implementation on Solaris supports so some code may never get executed * due to limitations in the implementation. */ switch (st.st_mode & S_IFMT) { case S_IFIFO: case S_IFCHR: case S_IFBLK: /* * Get any acl on the xattr. */ if (solaris_save_xattr_acl(jcr, xattr_data, attrfd, attrname, &acl_text) != bxattr_exit_ok) goto bail_out; /* * The current implementation of xattr on Solaris doesn't support this, * but if it ever does we are prepared. * Encode the stat struct into an ASCII representation. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); break; case S_IFDIR: /* * Get any acl on the xattr. */ if (solaris_save_xattr_acl(jcr, xattr_data, attrfd, attrname, &acl_text) != bxattr_exit_ok) goto bail_out; /* * See if this is the toplevel_hidden_dir being saved. */ if (toplevel_hidden_dir) { /* * Save the data for later storage when we encounter a real xattr. * We store the data in the xattr_data->u.build->content buffer * and flush that just before sending out the first real xattr. * Encode the stat struct into an ASCII representation and jump * out of the function. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); pm_memcpy(xattr_data->u.build->content, buffer, cnt); xattr_data->u.build->content_length = cnt; goto bail_out; } else { /* * The current implementation of xattr on Solaris doesn't support this, * but if it ever does we are prepared. * Encode the stat struct into an ASCII representation. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); } break; case S_IFREG: /* * If this is a hardlinked file check the inode cache for a hit. */ if (st.st_nlink > 1) { /* * See if the cache already knows this inode number. */ if ((xlce = find_xattr_link_cache_entry(xattr_data, st.st_ino)) != NULL) { /* * Generate a xattr encoding with the reference to the target in there. */ encode_stat(attribs, &st, sizeof(st), st.st_ino, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, xlce->target, 0); pm_memcpy(xattr_data->u.build->content, buffer, cnt); xattr_data->u.build->content_length = cnt; retval = send_xattr_stream(jcr, xattr_data, stream); /* * For a hard linked file we are ready now, no need to recursively * save the attributes. */ goto bail_out; } /* * Store this hard linked file in the cache. * Store the name relative to the top level xattr space. */ add_xattr_link_cache_entry(xattr_data, st.st_ino, target_attrname + 1); } /* * Get any acl on the xattr. */ if (solaris_save_xattr_acl(jcr, xattr_data, attrfd, attrname, &acl_text) != bxattr_exit_ok) { goto bail_out; } /* * Encode the stat struct into an ASCII representation. */ encode_stat(attribs, &st, sizeof(st), 0, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0); /* * Open the extended or extensible attribute file. */ if ((attrfd = openat(fd, attrname, O_RDONLY)) < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg3(jcr->errmsg, _("Unable to open xattr %s on \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } break; case S_IFLNK: /* * The current implementation of xattr on Solaris doesn't support this, but if it * ever does we are prepared. * Encode the stat struct into an ASCII representation. */ if (readlink(attrname, link_source, sizeof(link_source)) < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg3(jcr->errmsg, _("Unable to read symlin %s on \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Generate a xattr encoding with the reference to the target in there. */ encode_stat(attribs, &st, sizeof(st), st.st_ino, stream); cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c", target_attrname, 0, attribs, 0, link_source, 0); pm_memcpy(xattr_data->u.build->content, buffer, cnt); xattr_data->u.build->content_length = cnt; retval = send_xattr_stream(jcr, xattr_data, stream); if (retval == bxattr_exit_ok) { xattr_data->u.build->nr_saved++; } /* * For a soft linked file we are ready now, no need to recursively save the attributes. */ goto bail_out; default: goto bail_out; } /* * See if this is the first real xattr being saved. * If it is save the toplevel_hidden_dir attributes first. * This is easy as its stored already in the * xattr_data->u.build->content buffer. */ if (xattr_data->u.build->nr_saved == 0) { retval = send_xattr_stream(jcr, xattr_data, STREAM_XATTR_SOLARIS); if (retval != bxattr_exit_ok) { goto bail_out; } xattr_data->u.build->nr_saved++; } pm_memcpy(xattr_data->u.build->content, buffer, cnt); xattr_data->u.build->content_length = cnt; /* * Only dump the content of regular files. */ switch (st.st_mode & S_IFMT) { case S_IFREG: if (st.st_size > 0) { /* * Protect ourself against things getting out of hand. */ if (st.st_size >= MAX_XATTR_STREAM) { Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"), xattr_data->last_fname, MAX_XATTR_STREAM); goto bail_out; } while ((cnt = read(attrfd, buffer, sizeof(buffer))) > 0) { xattr_data->u.build->content = check_pool_memory_size(xattr_data->u.build->content, xattr_data->u.build->content_length + cnt); memcpy(xattr_data->u.build->content + xattr_data->u.build->content_length, buffer, cnt); xattr_data->u.build->content_length += cnt; } if (cnt < 0) { Mmsg2(jcr->errmsg, _("Unable to read content of xattr %s on file \"%s\"\n"), target_attrname, xattr_data->last_fname); Dmsg2(100, "read of data from xattr %s on \"%s\" failed\n", target_attrname, xattr_data->last_fname); goto bail_out; } } break; default: break; } /* * We build a new xattr stream send it to the SD. */ retval = send_xattr_stream(jcr, xattr_data, stream); if (retval != bxattr_exit_ok) { goto bail_out; } xattr_data->u.build->nr_saved++; /* * Recursivly call solaris_save_extended_attributes for archiving the attributes * available on this extended attribute. */ retval = solaris_save_xattrs(jcr, xattr_data, xattr_namespace, attrname); /* * The recursive call could change our working dir so change back to the wanted workdir. */ if (fchdir(fd) < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space of file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n", xattr_data->last_fname, fd, be.bstrerror()); goto bail_out; } } bail_out: if (acl_text != NULL) { free(acl_text); } if (attrfd != -1) { close(attrfd); } return retval; } static bxattr_exit_code solaris_save_xattrs(JCR *jcr, xattr_data_t *xattr_data, const char *xattr_namespace, const char *attr_parent) { const char *name; int fd, filefd = -1, attrdirfd = -1; DIR *dirp; struct dirent *dp; char current_xattr_namespace[PATH_MAX]; bxattr_exit_code retval = bxattr_exit_error; /* * Determine what argument to use. Use attr_parent when set * (recursive call) or xattr_data->last_fname for first call. Also save * the current depth of the xattr_space we are in. */ if (attr_parent) { name = attr_parent; if (xattr_namespace) { bsnprintf(current_xattr_namespace, sizeof(current_xattr_namespace), "%s%s/", xattr_namespace, attr_parent); } else { bstrncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace)); } } else { name = xattr_data->last_fname; bstrncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace)); } /* * Open the file on which to save the xattrs read-only. */ if ((filefd = open(name, O_RDONLY | O_NONBLOCK)) < 0) { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("Unable to open file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Open the xattr naming space. */ if ((attrdirfd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) { berrno be; switch (errno) { case EINVAL: /* * Gentile way of the system saying this type of xattr layering is not supported. * Which is not problem we just forget about this this xattr. * But as this is not an error we return a positive return value. */ retval = bxattr_exit_ok; goto bail_out; case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg3(jcr->errmsg, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"), name, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n", name, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * We need to change into the attribute directory to determine if each of the * attributes should be saved. */ if (fchdir(attrdirfd) < 0) { berrno be; Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n", xattr_data->last_fname, attrdirfd, be.bstrerror()); goto bail_out; } /* * Save the data of the toplevel xattr hidden_dir. We save this one before anything * else because the readdir returns "." entry after the extensible attr entry. * And as we want this entry before anything else we better just save its data. */ if (!attr_parent) solaris_save_xattr(jcr, xattr_data, attrdirfd, current_xattr_namespace, ".", true, STREAM_XATTR_SOLARIS); if ((fd = dup(attrdirfd)) == -1 || (dirp = fdopendir(fd)) == (DIR *)NULL) { berrno be; Mmsg2(jcr->errmsg, _("Unable to list the xattr space on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fdopendir xattr space on file \"%s\" using fd %d: ERR=%s\n", xattr_data->last_fname, fd, be.bstrerror()); goto bail_out; } /* * Walk the namespace. */ while ((dp = readdir(dirp)) != NULL) { /* * Skip only the toplevel . dir. */ if (!attr_parent && bstrcmp(dp->d_name, ".")) continue; /* * Skip all .. directories */ if (bstrcmp(dp->d_name, "..")) continue; Dmsg3(400, "processing extended attribute %s%s on file \"%s\"\n", current_xattr_namespace, dp->d_name, xattr_data->last_fname); #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) /* * We are not interested in read-only extensible attributes. */ if (bstrcmp(dp->d_name, VIEW_READONLY)) { Dmsg3(400, "Skipping readonly extensible attributes %s%s on file \"%s\"\n", current_xattr_namespace, dp->d_name, xattr_data->last_fname); continue; } /* * We are only interested in read-write extensible attributes * when they contain non-transient values. */ if (bstrcmp(dp->d_name, VIEW_READWRITE)) { /* * Determine if there are non-transient system attributes at the toplevel. * We need to provide a fd to the open file. */ if (!solaris_has_non_transient_extensible_attributes(filefd)) { Dmsg3(400, "Skipping transient extensible attributes %s%s on file \"%s\"\n", current_xattr_namespace, dp->d_name, xattr_data->last_fname); continue; } /* * Save the xattr. */ solaris_save_xattr(jcr, xattr_data, attrdirfd, current_xattr_namespace, dp->d_name, false, STREAM_XATTR_SOLARIS_SYS); continue; } #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */ /* * Save the xattr. */ solaris_save_xattr(jcr, xattr_data, attrdirfd, current_xattr_namespace, dp->d_name, false, STREAM_XATTR_SOLARIS); } closedir(dirp); retval = bxattr_exit_ok; bail_out: if (attrdirfd != -1) close(attrdirfd); if (filefd != -1) close(filefd); return retval; } #ifdef HAVE_ACL static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, xattr_data_t *xattr_data, int fd, const char *attrname, char *acl_text) { #ifdef HAVE_EXTENDED_ACL int error; acl_t *aclp = NULL; if ((error = acl_fromtext(acl_text, &aclp)) != 0) { Mmsg1(jcr->errmsg, _("Unable to convert acl from text on file \"%s\"\n"), xattr_data->last_fname); return bxattr_exit_error; } if ((fd != -1 && facl_set(fd, aclp) != 0) || acl_set(attrname, aclp) != 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"), attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n", attrname, xattr_data->last_fname, be.bstrerror()); return bxattr_exit_error; } if (aclp) { acl_free(aclp); } return bxattr_exit_ok; #else /* HAVE_EXTENDED_ACL */ int n; aclent_t *acls = NULL; acls = aclfromtext(acl_text, &n); if (!acls) { if ((fd != -1 && facl(fd, SETACL, n, acls) != 0) || acl(attrname, SETACL, n, acls) != 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"), attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n", attrname, xattr_data->last_fname, be.bstrerror()); return bxattr_exit_error; } } if (acls) { free(acls); } return bxattr_exit_ok; #endif /* HAVE_EXTENDED_ACL */ } #endif /* HAVE_ACL */ static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, xattr_data_t *xattr_data, bool is_extensible, char *content, uint32_t content_length) { int fd, filefd = -1, attrdirfd = -1, attrfd = -1; int used_bytes, cnt; char *bp, *target_attrname, *attribs; char *linked_target = NULL; char *acl_text = NULL; char *data = NULL; int32_t inum; struct stat st; struct timeval times[2]; bxattr_exit_code retval = bxattr_exit_error; /* * Parse the xattr stream. First the part that is the same for all xattrs. */ used_bytes = 0; /* * The name of the target xattr has a leading / we are not interested * in that so skip it when decoding the string. We always start a the / * of the xattr space anyway. */ target_attrname = content + 1; if ((bp = strchr(target_attrname, '\0')) == (char *)NULL || (used_bytes = (bp - content)) >= (int32_t)(content_length - 1)) { goto parse_error; } attribs = ++bp; /* * Open the file on which to restore the xattrs read-only. */ if ((filefd = open(xattr_data->last_fname, O_RDONLY | O_NONBLOCK)) < 0) { berrno be; Mmsg2(jcr->errmsg, _("Unable to open file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } /* * Open the xattr naming space and make it the current working dir. */ if ((attrdirfd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) { berrno be; Mmsg2(jcr->errmsg, _("Unable to open xattr space on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "Unable to open xattr space on file \"%s\": ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } if (fchdir(attrdirfd) < 0) { berrno be; Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n", xattr_data->last_fname, attrdirfd, be.bstrerror()); goto bail_out; } /* * Try to open the correct xattr subdir based on the target_attrname given. * e.g. check if its a subdir attrname. Each / in the string makes us go * one level deeper. */ while ((bp = strchr(target_attrname, '/')) != (char *)NULL) { *bp = '\0'; if ((fd = open(target_attrname, O_RDONLY | O_NONBLOCK)) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to open xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } close(filefd); filefd = fd; /* * Open the xattr naming space. */ if ((fd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } close(attrdirfd); attrdirfd = fd; /* * Make the xattr space our current workingdir. */ if (fchdir(attrdirfd) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg4(100, "Unable to fchdir to xattr space %s on file \"%s\" using fd %d: ERR=%s\n", target_attrname, xattr_data->last_fname, attrdirfd, be.bstrerror()); goto bail_out; } target_attrname = ++bp; } /* * Decode the attributes from the stream. */ decode_stat(attribs, &st, sizeof(st), &inum); /* * Decode the next field (acl_text). */ if ((bp = strchr(attribs, '\0')) == (char *)NULL || (used_bytes = (bp - content)) >= (int32_t)(content_length - 1)) { goto parse_error; } acl_text = ++bp; /* * Based on the filetype perform the correct action. We support most filetypes here, more * then the actual implementation on Solaris supports so some code may never get executed * due to limitations in the implementation. */ switch (st.st_mode & S_IFMT) { case S_IFIFO: /* * The current implementation of xattr on Solaris doesn't support this, * but if it ever does we are prepared. */ unlinkat(attrdirfd, target_attrname, 0); if (mkfifo(target_attrname, st.st_mode) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; case S_IFCHR: case S_IFBLK: /* * The current implementation of xattr on Solaris doesn't support this, * but if it ever does we are prepared. */ unlinkat(attrdirfd, target_attrname, 0); if (mknod(target_attrname, st.st_mode, st.st_rdev) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to mknod xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to mknod xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; case S_IFDIR: /* * If its not the hidden_dir create the entry. * The current implementation of xattr on Solaris doesn't support this, * but if it ever does we are prepared. */ if (!bstrcmp(target_attrname, ".")) { unlinkat(attrdirfd, target_attrname, AT_REMOVEDIR); if (mkdir(target_attrname, st.st_mode) < 0) { berrno be; Jmsg3(jcr, M_WARNING, 0, _("Unable to mkdir xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } break; case S_IFREG: /* * See if this is a hard linked file. e.g. inum != 0 */ if (inum != 0) { linked_target = bp; unlinkat(attrdirfd, target_attrname, 0); if (link(linked_target, target_attrname) < 0) { berrno be; Mmsg4(jcr->errmsg, _("Unable to link xattr %s to %s on file \"%s\": ERR=%s\n"), target_attrname, linked_target, xattr_data->last_fname, be.bstrerror()); Dmsg4(100, "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n", target_attrname, linked_target, xattr_data->last_fname, be.bstrerror()); goto bail_out; } /* * Successfully restored xattr. */ retval = bxattr_exit_ok; goto bail_out; } else { if ((bp = strchr(acl_text, '\0')) == (char *)NULL || (used_bytes = (bp - content)) >= (int32_t)content_length) { goto parse_error; } if (used_bytes < (int32_t)(content_length - 1)) data = ++bp; /* * Restore the actual xattr. */ if (!is_extensible) { unlinkat(attrdirfd, target_attrname, 0); } if ((attrfd = openat(attrdirfd, target_attrname, O_RDWR | O_CREAT | O_TRUNC, st.st_mode)) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to open xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Restore the actual data. */ if (st.st_size > 0) { used_bytes = (data - content); cnt = content_length - used_bytes; /* * Do a sanity check, the st.st_size should be the same as the number of bytes * we have available as data of the stream. */ if (cnt != st.st_size) { Mmsg2(jcr->errmsg, _("Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n"), target_attrname, xattr_data->last_fname); Dmsg2(100, "Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n", target_attrname, xattr_data->last_fname); goto bail_out; } while (cnt > 0) { cnt = write(attrfd, data, cnt); if (cnt < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to restore data of xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } used_bytes += cnt; data += cnt; cnt = content_length - used_bytes; } } break; case S_IFLNK: /* * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared. */ linked_target = bp; if (symlink(linked_target, target_attrname) < 0) { berrno be; Mmsg4(jcr->errmsg, _("Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n"), target_attrname, linked_target, xattr_data->last_fname, be.bstrerror()); Dmsg4(100, "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n", target_attrname, linked_target, xattr_data->last_fname, be.bstrerror()); goto bail_out; } /* * Successfully restored xattr. */ retval = bxattr_exit_ok; goto bail_out; default: goto bail_out; } /* * Restore owner and acl for non extensible attributes. */ if (!is_extensible) { if (fchownat(attrdirfd, target_attrname, st.st_uid, st.st_gid, AT_SYMLINK_NOFOLLOW) < 0) { berrno be; switch (errno) { case EINVAL: /* * Gentile way of the system saying this type of xattr layering is not supported. * But as this is not an error we return a positive return value. */ retval = bxattr_exit_ok; break; case ENOENT: retval = bxattr_exit_ok; break; default: Mmsg3(jcr->errmsg, _("Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); } goto bail_out; } } #ifdef HAVE_ACL if (acl_text && *acl_text) if (solaris_restore_xattr_acl(jcr, xattr_data, attrfd, target_attrname, acl_text) != bxattr_exit_ok) goto bail_out; #endif /* HAVE_ACL */ /* * For a non extensible attribute restore access and modification time on the xattr. */ if (!is_extensible) { times[0].tv_sec = st.st_atime; times[0].tv_usec = 0; times[1].tv_sec = st.st_mtime; times[1].tv_usec = 0; if (futimesat(attrdirfd, target_attrname, times) < 0) { berrno be; Mmsg3(jcr->errmsg, _("Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n"), target_attrname, xattr_data->last_fname, be.bstrerror()); Dmsg3(100, "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n", target_attrname, xattr_data->last_fname, be.bstrerror()); goto bail_out; } } /* * Successfully restored xattr. */ retval = bxattr_exit_ok; goto bail_out; parse_error: Mmsg1(jcr->errmsg, _("Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n", xattr_data->last_fname); bail_out: if (attrfd != -1) { close(attrfd); } if (attrdirfd != -1) { close(attrdirfd); } if (filefd != -1) { close(filefd); } return retval; } static bxattr_exit_code solaris_build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { char cwd[PATH_MAX]; bxattr_exit_code retval = bxattr_exit_ok; /* * First see if extended attributes or extensible attributes are present. * If not just pretend things went ok. */ if (pathconf(xattr_data->last_fname, _PC_XATTR_EXISTS) > 0) { xattr_data->u.build->nr_saved = 0; /* * As we change the cwd in the save function save the current cwd * for restore after return from the solaris_save_xattrs function. */ getcwd(cwd, sizeof(cwd)); retval = solaris_save_xattrs(jcr, xattr_data, NULL, NULL); chdir(cwd); if (xattr_data->u.build->link_cache) { drop_xattr_link_cache(xattr_data); } } return retval; } static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { char cwd[PATH_MAX]; bool is_extensible = false; bxattr_exit_code retval = bxattr_exit_error; /* * First make sure we can restore xattr on the filesystem. */ switch (stream) { #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) case STREAM_XATTR_SOLARIS_SYS: if (pathconf(xattr_data->last_fname, _PC_SATTR_ENABLED) <= 0) { Mmsg1(jcr->errmsg, _("Failed to restore extensible attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n", xattr_data->last_fname); goto bail_out; } is_extensible = true; break; #endif case STREAM_XATTR_SOLARIS: if (pathconf(xattr_data->last_fname, _PC_XATTR_ENABLED) <= 0) { Mmsg1(jcr->errmsg, _("Failed to restore extended attributes on file \"%s\"\n"), xattr_data->last_fname); Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n", xattr_data->last_fname); goto bail_out; } break; default: goto bail_out; } /* * As we change the cwd in the restore function save the current cwd * for restore after return from the solaris_restore_xattrs function. */ getcwd(cwd, sizeof(cwd)); retval = solaris_restore_xattrs(jcr, xattr_data, is_extensible, content, content_length); chdir(cwd); bail_out: return retval; } /* * Function pointers to the build and parse function to use for these xattrs. */ static bxattr_exit_code (*os_build_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) = solaris_build_xattr_streams; static bxattr_exit_code (*os_parse_xattr_streams) (JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) = solaris_parse_xattr_streams; #endif /* defined(HAVE_SUN_OS) */ /* * Entry points when compiled with support for XATTRs on a supported platform. */ bxattr_exit_code build_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, FF_PKT *ff_pkt) { /* * See if we are changing from one device to an other. * We save the current device we are scanning and compare * it with the current st_dev in the last stat performed on * the file we are currently storing. */ if (xattr_data->current_dev != ff_pkt->statp.st_dev) { /* * Reset the acl save flags. */ xattr_data->flags = 0; xattr_data->flags |= BXATTR_FLAG_SAVE_NATIVE; /* * Save that we started scanning a new filesystem. */ xattr_data->current_dev = ff_pkt->statp.st_dev; } if ((xattr_data->flags & BXATTR_FLAG_SAVE_NATIVE) && os_parse_xattr_streams) { return os_build_xattr_streams(jcr, xattr_data, ff_pkt); } else { return bxattr_exit_ok; } } bxattr_exit_code parse_xattr_streams(JCR *jcr, xattr_data_t *xattr_data, int stream, char *content, uint32_t content_length) { int ret; struct stat st; unsigned int cnt; bxattr_exit_code retval = bxattr_exit_error; /* * See if we are changing from one device to an other. * We save the current device we are restoring to and compare * it with the current st_dev in the last stat performed on * the file we are currently restoring. */ ret = lstat(xattr_data->last_fname, &st); switch (ret) { case -1: { berrno be; switch (errno) { case ENOENT: retval = bxattr_exit_ok; goto bail_out; default: Mmsg2(jcr->errmsg, _("Unable to stat file \"%s\": ERR=%s\n"), xattr_data->last_fname, be.bstrerror()); Dmsg2(100, "Unable to stat file \"%s\": ERR=%s\n", xattr_data->last_fname, be.bstrerror()); goto bail_out; } break; } case 0: break; } if (xattr_data->current_dev != st.st_dev) { /* * Reset the acl save flags. */ xattr_data->flags = 0; xattr_data->flags |= BXATTR_FLAG_RESTORE_NATIVE; /* * Save that we started restoring to a new filesystem. */ xattr_data->current_dev = st.st_dev; } /* * See if we are still restoring native xattr to this filesystem. */ if ((xattr_data->flags & BXATTR_FLAG_RESTORE_NATIVE) && os_parse_xattr_streams) { /* * See if we can parse this stream, and ifso give it a try. */ for (cnt = 0; cnt < sizeof(os_default_xattr_streams) / sizeof(int); cnt++) { if (os_default_xattr_streams[cnt] == stream) { retval = os_parse_xattr_streams(jcr, xattr_data, stream, content, content_length); goto bail_out; } } } else { /* * Increment error count but don't log an error again for the same filesystem. */ xattr_data->u.parse->nr_errors++; retval = bxattr_exit_ok; goto bail_out; } /* * Issue a warning and discard the message. But pretend the restore was ok. */ Jmsg2(jcr, M_WARNING, 0, _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"), xattr_data->last_fname, stream); bail_out: return retval; } #endif bareos-Release-14.2.6/src/findlib/xattr.h000066400000000000000000000052031263011562700201510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __XATTR_H #define __XATTR_H /* * * Number of xattr errors to report per job. * */ #define XATTR_REPORT_ERR_MAX_PER_JOB 25 /* * * Return codes from xattr subroutines. * */ typedef enum { bxattr_exit_fatal = -1, bxattr_exit_error = 0, bxattr_exit_ok = 1 } bxattr_exit_code; #if defined(HAVE_LINUX_OS) #define BXATTR_ENOTSUP EOPNOTSUPP #elif defined(HAVE_DARWIN_OS) #define BXATTR_ENOTSUP ENOTSUP #elif defined(HAVE_HURD_OS) #define BXATTR_ENOTSUP ENOTSUP #endif /* * Magic used in the magic field of the xattr struct. * This way we can see we encounter a valid xattr struct. */ #define XATTR_MAGIC 0x5C5884 /* * Internal representation of an extended attribute. */ struct xattr_t { uint32_t magic; uint32_t name_length; char *name; uint32_t value_length; char *value; }; /* * Internal representation of an extended attribute hardlinked file. */ struct xattr_link_cache_entry_t { uint32_t inum; char *target; }; #define BXATTR_FLAG_SAVE_NATIVE 0x01 #define BXATTR_FLAG_RESTORE_NATIVE 0x02 struct xattr_build_data_t { uint32_t nr_errors; uint32_t nr_saved; POOLMEM *content; uint32_t content_length; alist *link_cache; }; struct xattr_parse_data_t { uint32_t nr_errors; }; /* * Internal tracking data. */ struct xattr_data_t { POOLMEM *last_fname; uint32_t flags; /* See BXATTR_FLAG_* */ uint32_t current_dev; union { struct xattr_build_data_t *build; struct xattr_parse_data_t *parse; } u; }; /* * Maximum size of the XATTR stream this prevents us from blowing up the filed. */ #define MAX_XATTR_STREAM (1 * 1024 * 1024) /* 1 Mb */ /* * Upperlimit on a xattr internal buffer */ #define XATTR_BUFSIZ 1024 #endif bareos-Release-14.2.6/src/images/000077500000000000000000000000001263011562700164745ustar00rootroot00000000000000bareos-Release-14.2.6/src/images/0p.png000066400000000000000000000003601263011562700175200ustar00rootroot00000000000000PNG  IHDR#LsRGBbKGD pHYs  tIME $-Ŀ|tEXtCommentCreated with GIMPWKIDATHc`49sd #=`l&tIII1HII] c:f1aAx@Q02+XJIENDB`bareos-Release-14.2.6/src/images/16p.png000066400000000000000000000003741263011562700176140ustar00rootroot00000000000000PNG  IHDR#LsRGBbKGD pHYs  tIME  ŝtEXtCommentCreated with GIMPWWIDATHc`4›x1LKb$ %% %%ES1@0Qnj:fX:CdgϞ\l!s( IENDB`bareos-Release-14.2.6/src/images/32p.png000066400000000000000000000004011263011562700176010ustar00rootroot00000000000000PNG  IHDR#LsRGBbKGD pHYs  tIME 'tEXtCommentCreated with GIMPW\IDATHc`4›M̙3(b&&&LKbbRRR RRRTųccX0DfaQEٳgT`$uIENDB`bareos-Release-14.2.6/src/images/48p.png000066400000000000000000000004051263011562700176140ustar00rootroot00000000000000PNG  IHDR#LsRGBbKGD pHYs  tIME ,G) tEXtCommentCreated with GIMPW`IDATHc`49oj+(Ş7_c]`mdOVʈH>hi 4^cc!0Zł?76]9iFN@T:}Tl88' ρ^2ue-k"{RqŒ պu:ݻ', .Z+g`@n Gv6LPzes}=d`P)QZr09r)Dq4f_[zo ;)I"B%# :Xo:˄R뮝6 '\ GtU:6"tg r J?@! 2' ]™.7<:/@"t " ®tYٱȏ:'Jxws ;-hE+KbP x8I? @0p8)ĕk+Д#hM"%G첶D2ֶǭšIENDB`bareos-Release-14.2.6/src/images/R.png000066400000000000000000000021061263011562700174020ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs  ~tIME 7 iIDATxڥ]lSe]׭&S3$&F(A"e b+;cfh"7. !~ě%#f)q8m̪[mn9]onk⛼zy2vn5}@y JgE@:erYI$8E'u@ RTP] |$j| n*ݠƒ1J%WuUKuu5/]O?7!eZ\ (cwWTdѨV._0U$>#`Ռ\;oM6 9+dvUVk=ᡨ,$0'PvԐDQVNٹNtsS'gggp:K5Ԁg~`r4 L/B2GQ5@P!h-niRsZ  1>~pGM?5ݸ MJYacpY}@,սY@j!?bĆGyn ~^=GHV.MzUSgV /yuw?r32ghh~hnX)>9zOly73=5Iۯ"9yG8#ivN`[_Q\2zDbU/$pRfzP)?͟p]F$ˉ/'&h ,=Ձbj6\mۧ]yWt4B j '=_1цKc V}EJԒpYYbpkCXanubxKj2*^W f$w x0xœt$ͳV&7(IU3/x9nӑ/欉>eOlȅ;cw:^qžz ?|^H_%jF\tq.syC^]RFڃ#eeC0 :>F \ib0)%W&^Jkjdo +݄v~$OfSoi@pZ[A^7`%^LnN}U^.saY@ $I )6x{l$ X5B^zbJ}钞1L5o^BLWK0u6<( dq ~ |w%A=+!?`,k"%=9A&6x`+ =l[S kn kRٙwz@qۓ(FjdӼtSWhUMV'ޑc\\4O~!XVU<`P*+ d2w^_W{*I=6@/]&W_e0К'T Sfi1{U#@P`~v8 7yQ= A:MBrDCEWsu;:u>"7EH .& a}fK|e2Y5 &P $nc9X&BS\t<Jg;[Ijb߉;I..0N9+0##Ƀ TV8q͑P~R٤ӾN3^:Ie !Ѐ4?F_K_έ-g\)"FIENDB`bareos-Release-14.2.6/src/images/applications-graphics.png000066400000000000000000000032041263011562700234650ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXWml~fgwoC&j>\,*.&ˆVUPT D@Jmm WԒPH$&8{~ιӂIhgy"RDy]A{gۤ@.[[GÕK.[#J1כ* Ѯ&Ug0OW!K1Vv]]x`h}r2_9>ђ XLjwL˭ IMg`gRtMB77@uXMk7B&iDBѡ[#\cl(s@טA.!Tne s Ѯm3oz۞U}8q~4],.t[h/n"(^ ~VᜋKv<Hk1ٹV?mkqt: 9 WR- Ѯ+c1 N8CTU``<h,}gL]z1g2>4>KkLLm64j9fYk~@4XlmT$d%`;q!ƧƦ$>ql` GO&hVՁy-g4i7=DNMџt |~\\\a=ǠBһE /f+7.}(ޞa"? 1dYQ%xEނL6QPJ|(zzu[4\ qk]BJF@M@b\@[ &LBVTJ)m\===oZSTQZ6 `呻<8\1 T0fZDGnQd*Y1>>}ǿ\-Ys9fgg177UUs:!}g_: ﮩY&A=SSUR.d\>"TU$Iu=lRܸ6_z12)?wüy.^8O\DyB^@@ssϲC---N:ĥ;g%RUT l@``&@'U$!Gt]h㆏uH@m_ů QJNK$0 C4|>ȲBp8ܹSBl拡PF9sa1K_/ᮮ.x/x<800T*9<ϛ$ \ί(J'#@0M`4iqmg*"ݻ_I8R(s2CCCqH3m#L4M08#m pO$5ID|JgϞXb]*CR[gg ]>R.!R=Ͳ규BU(ITtJQ-9Tqcr}/(e%2<\3 '݌Sno mFUHIENDB`bareos-Release-14.2.6/src/images/applications-graphics.svg000066400000000000000000000640151263011562700235070ustar00rootroot00000000000000 image/svg+xml Graphics Category Jakub Steiner graphics category pixel vector editor draw paint http://tango-project.org bareos-Release-14.2.6/src/images/backup.png000066400000000000000000000031631263011562700204520ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs  ~tIME9 5DIDATxڥ]]Usk B;̭AK*~m)O$B2%>}|ďdFLESBQ ! | iPәts^koιs?'ZkziQ0b% ~5bWl xi333#07g|l$.KSK?y@cU81}3p HY瀈y +EvIiW |n0K(/lt9{5MN&}9` @__8)~5}?¦|ua )^oY^(N,xtQ^~nOuގ1F1F-(oW_ {>F8|xeiuf' > C={7` ڜL_>~43r9$2Aa XrW>Hv('* Ux SLQM +Y4υ|>/:((E;&m뻮gťK%f7˘b(7pMD-Z@>'O{vS8Q殛ٷg_}|ayNōw/CreNjQxrS|w;7C[9DZW1 l&v6 icU(+ieyY&>FOy+OЮ`ϵ]iijs?OIENDB`bareos-Release-14.2.6/src/images/bareos_1.png000066400000000000000000000131541263011562700207010ustar00rootroot00000000000000PNG  IHDR9w pHYs.#.#x?v OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F IDATxMLN]Tn5X5AP$uU J!ksڽaR 8pkN'TB U{p-B LJHiUQۃg!3=)<ׄ@K@()!PRB()!x1Q^!'(>5'i*EGBI %%ob 1E.G2鞤wGS'I BI BI %%BI %%BI 7ʜKIŀ^Kl BI BI BI %%BI %%BI %%JJ%%JJ%%DOXQW8G>334O)j{'d,d,riy{TG9O-dU'JD))q/ٛ wP0Ľ2Cj“RJDk)iž4RRqzw0D2PRn(JJ0;~wsLj{Y,T"hQRz-aq}w% Q c>3d;H%1ޣHX\-G>]Q4O.TǔtrGI}w]HTFRnI?PRr0BI BI %%BI %%BI %%JJ%%JJ%%JJ]=JJzOj.{n^MI h"j{g=7/>}PR !Goi|˜\zб]qKK}=:yd,j˟);JJ܋/?iˢ=?纭<-oz$y%Bo8\tq?#OQy J5`SA% 𖡵Q1T"Xjs,wTXT19VA`HuXeoM/5{cFk{c$HWRͿJQ}ݕ|fcn2z{'_U.?Q&RVg΅C6=֜7^Ⱥ`ȏ2CX14Uli%izKr:y^ QL |W=]E35AMTtC=::)W3cwHa༜&{W$٭tC=R^&娚5Q #7Lrذ= Kfr)v\B=z^=IkR?lU2A>=hZXDe98P߮J%>0DaS+!,>KhuK:P_l+X@*vdZCwnͧȥM==i'^|U9aSS~T `a?Z>^ۓPGB֬Y jjOV7:|ԴX)y!MIz!k^5iWdJѰyJDK:ݒڐjS蚌E0;~ŋ6&HVݒڐUy"K]Ѭ^ ({-J\EkY++KoHzY֜U[3ön~7bڌk!KiFAqhue)KL8 Y/{v{S YSh ى`϶V1,)6ZQ)HUmI/dMjFUak{GaȖp7;2hCUYz{!酬ZKXLY=Jjuڞ`bZ̃]_ WOyXwF>7ALO7r*,j!)`KzY<,ta]_t)-jRO Y+aK]rYCII ;+GYq]JF|ߜSRs=J:шrTqb:%e:,^-ˠ6%G׼F1)}9 6dSNI]'l+Zr3%PrXMZ!KIENDB`bareos-Release-14.2.6/src/images/bareos_2.png000066400000000000000000000132271263011562700207030ustar00rootroot00000000000000PNG  IHDR9w 9iCCPPhotoshop ICC profileHǝwTTϽwz0R޻{^Ea`(34!ED"HPĀP$VDT$(1ET,oF֋oZ/K<Qt`)LVF_{ͅ!r_zXp3NY|9,8%K.ϊ,f%f(Aˉ9a >,٩<9SbL!GĈ 3,F0+7T3IlpX"61"H _qW,d ėrIKst.ښAdp&+g]RәY2EE44432PuoJEzg`̉j- -b8o׿M]9La.+-%Mȧg3YះuAxEK i<:ŹPcu*@~(  ]o0 ~y*s7g%9%(3H*@C`-pn VH@ A1 jPA3hA'8΃Kn`Lg` a!2D!H҇ dAP B Byf*z: @]h ~L CUp΅ p%;56< ?" GxG iE>&2 oQEGlQP UFFuzQ7QcYG4G۠t]nB/o'Я1 xb"1I>Lf3bX} *QYvGĩp( &q x)&gsF|7:~@&h!$&B%pH$D.q#xx8F|K!\H$!i.%L";r3EHK-AFCbH$^RSIrdd 3Rx)-))zR#RsiSiT#Wd2Z2n2l2d)EBaQ6S))T UEMSPgeedɆfȞ!4--VJ;N g%K-sɵݖ{'OwO%)P_RRۥEK/+))U<د8䡔TtAiF쨜\|FyZbU)W9.Kw+YUEUOUjꂚZZZCu:C=^\G}VCEO#OE&^WOs^K[+\kV֔vv[]n>z^^u}XROm`m3h01$:fь|:kG23hbabhrT4ߴw3=3Y-s.q_vǂbgբ⃥%߲rJ*֪jAe0JOY6rvvtXLǎl&I']$NϝM.6.\ι"En2nnn[g=,=t٪E2}4\j5loDŽǞ~q=''Z^utv&vvEv >mяN9-{ LOgsΝK?7s>xOL n\x }N}g/]>uɫ,u[dS@u]7ot.<30tKn]p;;SwSyoEVlZIyE,cl%ҽPM*$TI*$TI*$TI*$TI*ca??9JKҕ#bqIt/$TI*$TI*$TI*$TI*$TI*$THR!$THR!$<1ga$ C3DN*])f;[wTM4).qX40tYZ-TlffI*IcoDRTI@tȥI`$i~HETIڠT?g=T@*!IEn{Mp3D;QTОn"3LF:c9<3IG~yW#k^߉%ɤwsC$i SfBzǔ}TyDּ'k?PM*Vc0xh~ m?>>W)] \ڲmi6XI6.xnS/YΪo2ݶ9>l \~n|b2ӑjl;M$LjkNx90EU7A5-q]ljj}QT~*Y{o>D?]6j}J5/ d),;} 4o졓v3n5;XҮ3nto~v4I+>hAwnkY&թ1B11Tl9(_R+uRJuj4 7?(nC5t-paC;zpTW8ʤmv;%!j?WٛŃ F׷^ӽUΕS[xv %vq?}FJW=*$43Ǯz|(Ë"zntP2k|͊)y)<"^SX'/QEն/6ɆFot4bۊZ}$4bByFQBlk^+hpIKn.WPliO/k=9^V t^"[i5J4f=X;̑XC/EuI]-Fc/Ad(`u%I63 '9\'5rfһ9Ρg(T˵uT5;/q }DO(1PMYIe}ml"g<";dNrlrxV5|DU?%}cucO, Zq7եuJQ*@*m#FT>GW(fwfn-Uze5z^ɺ<3uIxs123N+מ<7u ^e2%PSoܡTL.Ou*&Q e9s8UkL?%@)k\ZL t08i3`9Jip~^ִ [*PfBiUrgPuIt(iuquOc.NnKT_s=t<9r?jIe5ʑճ~;XJHf&jV!ΣA4'鼬JCY'sYrZFrGSyY7Su /`Y&l쥻j1LqkL$WӌenX Z_3ǽTqk"c=}b;[}w~g iIe]Ki Nւ!^dច*+JPJn}h7WAHƔtq),vSu@=\(ƖtZZV3VVIx'nQS.hVUꕏ2V.Z3ZSz]{%cJ[}:Fr`*M z%ʁZai^ײ Ia7kсӔkO9® R$ hYxt5K-,lᢕm?DIENDB`bareos-Release-14.2.6/src/images/bareos_3.png000066400000000000000000000035071263011562700207040ustar00rootroot00000000000000PNG  IHDREsRGBfPLTE)((((((()%)&) ')r`6aB.Ip61$S*\tRNSߟ` @0pP2GbKGD!l  pHYs.#.#x?v&IDATxis<S:D_ҤDj=t:ql!Nk-"K )"钤l@P} )C7 ҅&IIIIti|iK*?IIIIIII#},A:TcU2\[ vy`*ZRjwG&4DՅ] )h5SN4Y s54X tjRg@3BOM:L:x5ԖjsW4ӔziYd5+禶jH!} )")")")")")"i/t=Z˪#-K#@ב4lkn%1 ;`'~}=Țt4=WCz>Bk!mRH[DDڵsPҴGkCgZIPsNRT}KUnc]H}F+x& 8|<4bܬdo17oܒ?"e?[ ;obLh]t![EwÄb&mGB>F>KfJgy҅"9a5s}&5vN%D0*y=̟)YS kօAsruAMbI ;VIwѴP|*qHNВheJ@md2Q Ԕ@ɭ- FԲ5=HTD-u.q,k|QQY<K Dh ;noeOztiԮ 6h5봁՟;r^\Ok+(!2sx9_x']]ge-wSP5;E 虬 6'}SX~ʝs2ojXauͦ>^9YΘ'`ZV+zGFS-sO\m5#k_2] Uf%Cq^1zEhSw?/qpN=忄)$t {@W:mD8} GBṶ<\f)1,CiTПZ0hh0'< `$;q;^3kaK)~)9`Tp7:0寳,l 6 %L׆!r.i?ÆаqZͷ Fu^E7\Eْ5k훩ēwȖW)nƜP<{"%Lc7%Uuc6?qR%tEXtdate:create2014-06-11T14:10:27+02:00#y8V%tEXtdate:modify2014-06-11T14:10:27+02:00R$tEXttiff:alphaunassociated(=tEXttiff:document/home/pstorz/git/bareos/src/images/bareos_3.tif H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F IDATxMLN]Tn5X5AP$uU J!ksڽaR 8pkN'TB U{p-B LJHiUQۃg!3=)<ׄ@K@()!PRB()!x1Q^!'(>5'i*EGBI %%ob 1E.G2鞤wGS'I BI BI %%BI %%BI 7ʜKIŀ^Kl BI BI BI %%BI %%BI %%JJ%%JJ%%DOXQW8G>334O)j{'d,d,riy{TG9O-dU'JD))q/ٛ wP0Ľ2Cj“RJDk)iž4RRqzw0D2PRn(JJ0;~wsLj{Y,T"hQRz-aq}w% Q c>3d;H%1ޣHX\-G>]Q4O.TǔtrGI}w]HTFRnI?PRr0BI BI %%BI %%BI %%JJ%%JJ%%JJ]=JJzOj.{n^MI h"j{g=7/>}PR !Goi|˜\zб]qKK}=:yd,j˟);JJ܋/?iˢ=?纭<-oz$y%Bo8\tq?#OQy J5`SA% 𖡵Q1T"Xjs,wTXT19VA`HuXeoM/5{cFk{c$HWRͿJQ}ݕ|fcn2z{'_U.?Q&RVg΅C6=֜7^Ⱥ`ȏ2CX14Uli%izKr:y^ QL |W=]E35AMTtC=::)W3cwHa༜&{W$٭tC=R^&娚5Q #7Lrذ= Kfr)v\B=z^=IkR?lU2A>=hZXDe98P߮J%>0DaS+!,>KhuK:P_l+X@*vdZCwnͧȥM==i'^|U9aSS~T `a?Z>^ۓPGB֬Y jjOV7:|ԴX)y!MIz!k^5iWdJѰyJDK:ݒڐjS蚌E0;~ŋ6&HVݒڐUy"K]Ѭ^ ({-J\EkY++KoHzY֜U[3ön~7bڌk!KiFAqhue)KL8 Y/{v{S YSh ى`϶V1,)6ZQ)HUmI/dMjFUak{GaȖp7;2hCUYz{!酬ZKXLY=Jjuڞ`bZ̃]_ WOyXwF>7ALO7r*,j!)`KzY<,ta]_t)-jRO Y+aK]rYCII ;+GYq]JF|ߜSRs=J:шrTqb:%e:,^-ˠ6%G׼F1)}9 6dSNI]'l+Zr3%PrXMZ!KIENDB`bareos-Release-14.2.6/src/images/bat.svg000066400000000000000000000157631263011562700177770ustar00rootroot00000000000000 image/svg+xmlbareos-Release-14.2.6/src/images/browse.png000066400000000000000000000066201263011562700205070ustar00rootroot00000000000000PNG  IHDR00WsBIT|dtEXtSoftwarewww.inkscape.org< "IDATh{yw_vq0ZjjhT!iQIMڪR, UT)*h.$I\m `|Y]mfvgr.cf{1R^=y+1|_>lpٳgu/^QC񢶀m߼[[4J9ZSBL&9r; !d(TU(Zc! CjQ!$LIZejj qf>ڶ{|1QSTf]kMimFWW|qRb6Q*'O~ѣ_~ᇿ{'ObxO}j33*ʜD*[ne˖-4.svFkƥoy+[X@>X,~&&&={ؽ{mr(b׮]$ 9|$GOIٴC:JŴ'I6W7o Jq yǧ ~* Rᣏ>%,zad}۶뮻(Tx^ae{ߵ,ldܥ8Sc1:U"_?WGO_6`Y.B,^ !Ð|kٻw PJZRD\' C==͎MٱemY,!)EG!M>+Ow{0'VGo56ps-Zd2.LkO?L'="n^ۯfy[됌\Ƕ-e ,!jҿf]kKeoN{{;Td2I*c2y9D@kW*3aȆ x)>&ǶkW"0(RJ+ ׊0Wvx7{ܳ۷fj4'YB8]WBX ]1 &"?z|VrԤCh *A$# ?xkdC^vU) 8+xrq꜉qX d_֏=rώ$j5֮]>4C2g6ҩ8%plm ` a @5R6rb“\.6Jό3t̕+;|qZ ]/ kTGB=g9>[t*]xԡXԂ(/N@)GQ$1Kt矽3LM[-1f. 0@*ñCǺT*yz},z c&.J@kA1 088kΫ8qSHf 0Di^:]?{b ~j3<4"PGœ+t*bbb5}<(ɪ)8eLW}')*|:lܸ!?t::77iԄR_Xx@)s RJ? C]V)-۷[n?o8?|eΌFLʥ+t\ӛdzzRFXرcضM?/"omn$b B  ҤR)2 G& \?@歹]7~ 9{;E )֭l%M8300 /d1\妛n⭷M=c%c!133Ch5N0Y+V ">G͏8|0˗/u]zzzctt^:::=Fצ;(tAB?FK)M" !B Ez"#{,|)%J uó[ݷ2?xv>^<ϣhoo9WXBQ8Vcl]% DQ$<ϣ\ Hat^AX%Ƒ~#,d.S̯tMuCx(PJǙ rwr!X{q Ka Eh{xDxHTh"Aidz[񵋌"d.ps89SO&cYO\nk8ש=/!KC,(]@~Z2S6O%Cd(@>Q]/(@C; y챿\.ֆRe˖.roF4蹂ZDK$$RV<¶lj~5fQü#qXI7o:[' +7!RmOrmYCgY֭[G._~GmAiC` c$Ad۶UT#CH.j׺Il!y3!g^, ;̏r9,J5B 2DEt4zI e$`YHRk2HQ4\ϺFiTq:S ~MڠTcxX?N^'ɐ8u^?IkR"ejՒ"-XP?E@hmm;;;ZFMȊRZ4'Q. McVnV#=B0B`aշSU-P(pzx솝;F4zEbvDXv:F:yb$Zh˚'{NfN>϶I4hJ+q}@N3xtۈ ƀVZ;@ P@Gn^;BtQJ@4>yLc0Mscҙ={X8m1ɉ;_sŹXBX,Lk2?4!A%W4pFui d\۶2Ĺ@}6AiHX^B4,V?H4;yc󿴀b'lBc̒5>l_pcmUvIENDB`bareos-Release-14.2.6/src/images/browse.svg000066400000000000000000001022151263011562700205170ustar00rootroot00000000000000 image/svg+xml Folder Icon Jakub Steiner http://jimmac.musichall.cz folder directory bareos-Release-14.2.6/src/images/cartridge-edit.png000066400000000000000000000014241263011562700220720ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8}OHq?]s1VfK[EKOL HѦKuҠ9u]C3ŨCXdd%|c{{_' image/svg+xml bareos-Release-14.2.6/src/images/cartridge.png000066400000000000000000000012721263011562700211500ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<LIDAT8Kq_ϣZXCxV c;=C ?CWl0?faa9>EfYeyr|z,bFu]'R N?bn*X$adYfvA$^/H;X-җ|K&)JȲ pxx<iaR%>ZA+jXS ;2 hGOjf!NIENDB`bareos-Release-14.2.6/src/images/cartridge.svg000066400000000000000000000204161263011562700211640ustar00rootroot00000000000000 image/svg+xml bareos-Release-14.2.6/src/images/check.png000066400000000000000000000010471263011562700202610ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8;Ha1D ֺ5^QjD:"CTA#jKPP(4ࠓK"oUq0Bht0P ACH4lQDD7ߝAUT(*}Ot (+. FaQk{zqtJq7,NaTUJ}~g\\o$'%lc[Tl_/|nf9AO+GmH7|&w?k>n}57[0AEDsBgKJRi̫eۻW)j!"tF$6C ׾]vD3ma߂`l̊&{a;!, d^J*yu@vr&b";HKbI) kbm<:E[.p]IENDB`bareos-Release-14.2.6/src/images/check.svg000066400000000000000000000060701263011562700202750ustar00rootroot00000000000000 image/svg+xml bareos-Release-14.2.6/src/images/connected.png000066400000000000000000000010431263011562700211420ustar00rootroot00000000000000PNG  IHDR w}YgAMA a pHYs&?tIME:H>IDATxKA &Uh(T(VA%do2RBp~L&5 a|ݕo+KE P`vv,h[^+SG w C%$ C/uB(J/+?ugGIENDB`bareos-Release-14.2.6/src/images/copy.png000066400000000000000000000024731263011562700201620ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATXõ]L[ewoI q&NpхDP+.&J'E2 s.5,0LAV=P]G[JK+P nqFp'>y??I$B L9Ol͟-(9kp0hF뱌I oܜG;662afxFdLRX %ܡ? H#q2Te82f,[p0`.:N1[ X^f 1F-ܨji ܸ aٲ<}^J t (Dq+Fdf"LċGȡȎ;82a+A 0H.݀@2yMrhd^QGнM @t/2= ?H,1yK&B+6F\N 9c6 +A )*7G{̉@DT+, 6FHd*{.T74*TbR,XtzEUȠmts!sQ唃.ݯ˰>`y>^/'g`^3vshG .7wsaؽ^/fߩ6Bϥ-~mTk__sbrVNćԌ08@1~m%[ . $6{B o<ѽVw\Rz0L u5QdQD>v̴@O_~2 D"T*Jh K[9Sy,"džS)⠠ x`X@[^& -Sg L[{` b̄"P`ɹۧu.K)pjx)>+![cG&ؒrdo-- 8b\iF&2,3;3zb<{fO[5XCC=4442e<(6]*2x}.Zl1 %q/'_D Lh>u Ɩ1 f6m8h*>]XGZY Cɑ8 9!\ ϳ7ODIENDB`bareos-Release-14.2.6/src/images/disconnected.png000066400000000000000000000012001263011562700216350ustar00rootroot00000000000000PNG  IHDR w}YgAMA a pHYs&?tIME˛dIDATxkQ?xۓr(j+HZ0/VA^[ |.r ]mgmmKA<.xqjvV(Eg=ْYdg=]aq"m,®XlFrG* /ηjRv$/^bnnΎNlۦdU.c6QMwtG4xi0r0L4l$c"{ ]_bg\(8|bJ4 Jw5cjPjPdF".'>qJOU5;\_OGx- ~F|yQIENDB`bareos-Release-14.2.6/src/images/edit-cut.png000066400000000000000000000014471263011562700207260ustar00rootroot00000000000000PNG  IHDRabKGDC pHYs  tIME 1hAd^IDAT8˅]HQǟsw}lhxUtaIWEd"hiXi}J$ 0m36c6uu_vMaZ? <}rG$d F`Jiym7TDb$[ccqWe#s;R^Au5dr ny % 313sFVG>13_(zx{VZk'LJ[L`ןݍ~s&q\M,˚J)"w]OKiM<כRN<׶cgFc@9-Yr0M+ao>YNdXVQe:RJeYPJiJ^0 }A8NjQ~מq^TL$-aW*b{7)EPph1F+/U,hÕ{e@M' "`l 7 , Ar`{eb23.BD虙l.jR]`5ϝ^ڇ_l4lL[f^pūq3֣gcG1۷ۃ`y\,?IENDB`bareos-Release-14.2.6/src/images/edit-delete.svg000066400000000000000000001525141263011562700214120ustar00rootroot00000000000000 image/svg+xml Delete Jakub Steiner edit delete shredder Novell, Inc. bareos-Release-14.2.6/src/images/edit.png000066400000000000000000000021041263011562700201240ustar00rootroot00000000000000PNG  IHDRw=bKGD pHYs  ~tIME  ^tEXtCommentCreated with The GIMPd%nIDATxڭ_hUwv64nڲ*'1UfmB^5E)F`|Ajq[ͣmĚ6i5*M(IH̽3;gڢ\ff9=?Аu?Ͻ2NWFFFnڎ@\.˿⺎#bQ KOOOl}IY[[ӧ󲼼,""SSS4؍ LOOEPJ!"Z8KT"J0008Ǟ؈/chy#2>>݌Fj!:)1%_p5KKEۥ9NOJsS1V*M!,*>7⵱LvhΟ  -1Q~vF> ! AY 1uD釨.M9y2pn /DJx<{v^Xe"oʧ} 8q9җCLhîݸ7sSw/0ܾu[w03aJsa*)FطW=F;Ci=SH!Ƙ&])qoי_e/d2<Ͳr';=t0P}Y>'&scBD]@kMHqmx^G}OIvvfIPJa)FkfggC`.?rsgFYNl;I[[D"R[{7$6DJE58'DkxhRB)mﰻ&R(@ "cQ28!&پeG "A$h#& j+xs{'[Õd<`XxX L IENDB`bareos-Release-14.2.6/src/images/emblem-system.png000066400000000000000000000077221263011562700217750ustar00rootroot00000000000000PNG  IHDR00WsBIT|dtEXtSoftwarewww.inkscape.org<dIDAThY{tTEݷtА@^& O# ut: Y1B \0 ;{tQpDɃt'!NnUiHbwgs;NݮU}UuBj ;Bh$Jкj}jG_F TOxJ "h m\ 2,)B8=HWV٬4kpS\] XfW t}ZW=;8Fp88,DcCH1HLV88l2W$k IYlEӻ#&GDE5N( Wk}E/9v>E1G s98nNQ24]_PdYJ]wvp\Qk58SҬ/;nH%Jܶ];.j䷊oZFy"~e6 M?!AQ1+3ubਫ,$ \dC4UM!XiՖ0mj_ǺE׵4'jФ ۤ!mOkKhh;Ҝ0P!1kz+?^W۰hiUY4?ϸҖk2> Ȟb Kid[ ȫZrʆslTdjӉXf!Qy{$*р.Y+, +f!(>"MV$r1E#j:|δѪ-)sE=|ۺf/EfMH%!tf+s'E|WO@@Ƭ\[R}" 09Q2FlQl#Ii];1kFfE{Kno3ao޺ejәsRLxo=^II2i|u$eyh]^Ymd"I ,SH1,c25`'+7,v%-M7qf2vCk_)ҳV4N~vOfu934U*=q%+bП4D|E~nQ2ZVd6NO3"uxGZ. ??q<&ǿ[< BP1#R%VUHx0B_f-<:9ܣ봥*wNz[sݷݲd3}H;Ƥ.NwIX#lDMjbxjލ̅ZE}|nj>J;s,޻Uk23RD}tT{AQy@pJaLFdo[@C3iJQW* Ƒ3Mj8aM#\^ ?Di/l^&Fx1PmKp#86(*A4K##^!ƛ ṣ;i ʫdspBO?9wx~~X>1B|>. )J:e )ZTN9۔xiny7ZxC~8ھԴV骼6vm|*ތPϋM!K5"rȨy!Y JpXLdvxnxnl/,J9<Ol1DʅuJg cy` >a _06I"/[C PZj BdT*ۭ\^$䣣'~r 7*yQY92簬#& D_7ݖm}UUUh@6 QdZ[eD 3cAp.FK6.^X_3Soy٬bNq"D@NJ#I5DȄ2A v*/ğ Kgj~Xc;8(:g|fA~6Prz\m(Fl,#^zq4ebHs%-U̙)1(gĸ,B4hHM{aws[oOmEQ 54u04lkOW hF\Њjۇj$c,}m똚wwwUժ܎^upܙjb2[t-ZzCOwӪiQQDcrAQTwy~Uzp ,[ J*YaN&Ǫ*yaǮ]oP<H޵0Š{ߴukU" lgYǽrn )-_ ' gj !FEJ`5knem xcfe7o^PɧvDFbA2czA(m|t=eg̨C?2[FcRSV1#ڍ)=OUŤ'ׅl;gf͕jidI V mv؉/+WߐvS}It:/nBȗ5ギIJz_^zG|06No+=Xi۲I( 6*SD)@,K?~Z9c5_G OyH2I{<3ӢE!!t;*:N}橧0MSG)-7mOqA&#‹*+ٛo^^Ǭ$vGũO=|H)(`|\?DRHBw:=(rwO//+qӣ2!ZC6kEfouwYs*RRFR5VM,8]~H.! ))PH=|-1BH&A y=g@7֍N=ChJ51 2 D6X̺hT`i uu~0v~̸ 0|(ŗD>cqji3534`P=eSHE1u2 |.DB\. :F"|[Lw"Q)YňzjD.x' image/svg+xml Jakub Steiner http://jimmac.musichall.cz Emblem System emblem system library crucial base bareos-Release-14.2.6/src/images/estimate-job.png000066400000000000000000000040011263011562700215600ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXlǿώI1-% kRe EcCm& :FXN@PWcZ4VD ()Ie@B O'Ŏl.M$H}y{{ da.OfBe H 2> KA|Bbs!z} tG @/B}H%& 8C03y'ysMehXRn>Qh(UBƞh%G ~:"W#4Ew>F(>}%zT@3%t (߽FQ CZvVU63%JgFAj}\y"^/cw\q9G z+h|,Ztk;.՚@FC yGB>}K8mۿ{\?81T$<殪9.U ǐ)3M v%XZfѨ#&*ůu ~tY" tin4t<Q;ˤ_j4$/rmɚl9x@/bhFJ_iY4J(UT B`9x nx;+5M@Jyٍk(UX!/,55g:F1jx~if1Ad[PRGeA(ba˛:2aE t++勂W^}z4j$K6OkMji${8U9yU%s]I @>iptPEj_':kzsǗvwkqO¹Ξ\RDslƺ;FיCnQpt{<sgwm[}Է'fUZ~~3..]Xscȴ:=TUsj|TBz0pZ8|Qd?:`P]+`Ycct )]NN.L;ƴoc5zV/BO|}pN@"а|ۚ zGԞg5\u|8n_#. |Δȫ;uVgwy+4k,pʵ;;nX^YyaBy:ԕƙ\~]9i'}FVbBj< Um.ɛo _ut)+kF)͚olvN(^uo)0?C?%˳ϕ?|PFQzߎ+p8$Һ&?ⁿ?lsIHatX @2= ,VL($߭p8B~cǏw PJ  D46dCK3'hYI-|| !Bh10t4`6 Ϧ4(ܮS5?/aJM{B9)-bUzi%PH(4bIENDB`bareos-Release-14.2.6/src/images/estimate-job.svg000066400000000000000000000275631263011562700216150ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Emblem System emblem system library crucial base ? bareos-Release-14.2.6/src/images/extern.png000066400000000000000000000016051263011562700205110ustar00rootroot00000000000000PNG  IHDRw=bKGD pHYs @StIME IDATHOhTWMH6QV iuM)tӥ7EPEZZĈ#Cl馋VA݈FB%D B!I2ɻ{O_B) ;;O1yt\ī ͼ+בm`ND߼*P/ap5p8ر#Mۢ&okGt]#@HLPTf{Ϸtit,5,_ X)OTgӜZEٽndwYu=;Qa1<@ƒ;  %R)]ЁC<5U}jIѰtH? @'Y/pzJ X6iS=}W@Ѽ|K>`\A WeXc1^ X$LU q^ع ˁ|x,cm&FT` :u>xj^`01ep'B/JBPXL` \.dظa\ai:z`sO} 0kq3-L2o |㽣gJc 0]@+/L._`Xaa]haS#&ptﺥ}Fd{``ǘ4ŒfhX3Sb瀮ҾwcLhv'CfVu T1 0 9L䕷gGt#ѻj5iL;ɨDӆ\Ë-q?da FNIENDB`bareos-Release-14.2.6/src/images/f.png000066400000000000000000000025431263011562700174330ustar00rootroot00000000000000PNG  IHDRw=bKGDIDATxڍ[lUE}vϥ^(X(\,FhVL%Q /j"yИ/hLx( +D4 QPZ.=Z=3ˇ[[NVg2̚_R y#s< 4&Tѓ &Tx.Z\c@W]7;z`N Sgߌ3+qw_ħg+Jujc|e{~]#6?LeS*Z!tBhba{]CEˣ@n||`Ը:ɷ.s ǦO`'?V#gyBQqyT_~0)| @)(lXOz0\fFo[.\ {trrT)кj颥@bFJ~fbxSٓ5fc5Ha_cs;uߜ uKG^\uBiiKw"h:^lo~v}{}+;֒jj᷃_bDqgX~KWB_/ (]O# 8ly}h+G%;Uǯ]=,yY̙@1C`#x(x >j+(Ş7_c]`mdOVʈH>hi 4^cc!0Zł?76]9iFN@T:}Tl88' ρ^2ue-k"{RqŒ պu:ݻ', .Z+g`@n Gv6LPzes}=d`P)QZr09r)Dq4f_[zo ;)I"B%# :Xo:˄R뮝6 '\ GtU:6"tg r J?@! 2' ]™.7<:/@"t " ®tYٱȏ:'Jxws ;-hE+KbP x8I? @0p8)ĕk+Д#hM"%G첶D2ֶǭšIENDB`bareos-Release-14.2.6/src/images/folder.png000066400000000000000000000010471263011562700204570ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8;kTQs܌zcbc#`aˁi,-, h#630Er5y>"]>l^̌Q`8.no083c:νE!Hh4^4M뚦i!vesvvv^E˲kBJr$I}D)1L^׶\ s"i1?ȟ<{N*ue~d&mK >A`PTrʲ {ь&(ul _ 1BJjh4jD#/*i/:V?\q6.:68zqgmgejmدG2Ua+1; qac~nUs)_ I ErIENDB`bareos-Release-14.2.6/src/images/folder.svg000066400000000000000000000544241263011562700205010ustar00rootroot00000000000000 image/svg+xml Folder Icon Jakub Steiner http://jimmac.musichall.cz folder directory bareos-Release-14.2.6/src/images/folderbothchecked.png000066400000000000000000000013661263011562700226470ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8ӻkQܙ̺d&FT0j aN!Vjgl+ $`EATķs7jܕĘf3s_U@O{99c(Z?oquR(0F!_,j:ٹi cEq#Dkb`T*u]X|˳G04 DQB۫ju1MǹiOON$Ilչ=Q{k ȮnxDqdՙ'߾aH 2-yʎM !σ.$oўfC~O[˒8Ҟv68!7EeљK*IlB65 j6jڷl!xֶ\e ؐ-7 h6]2#N:zrܝ,LF^|M+IDv#D$ZxA{> O?I%QXCo9NXZfmS:BLdqa1S `ے=AYT>ڻs@Z?ibd́5~[(L8N.~Z~B`H(ZIENDB`bareos-Release-14.2.6/src/images/folderbothchecked.svg000066400000000000000000000574751263011562700226760ustar00rootroot00000000000000 image/svg+xml Folder Icon Jakub Steiner http://jimmac.musichall.cz folder directory bareos-Release-14.2.6/src/images/folderchecked.png000066400000000000000000000013051263011562700217630ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<WIDAT8KTa3 &eQ٢U֢s iSԪ!tg""0 6E Bm$rLͦj!] yx?> 4h NC)R c }m cEq#DkֺP(<_Bຮ0ֈ/TH )%J)c:* `C2π8NA$Iy)G6"k ~j=æ御Ww8PEHH?`:C \lgc@Jd9${xj(u= P- @\ w&/lP/32?'+;&GKRJikHe_Ηo:L`h;Iݹꋱx~*P%F$?V|A<=yȡ҅t(Q$NZ8P01Hm&5j-RVbee0֓)L.cĐ+^>¾9Ĭ4||xѻwMAkZXc0ֲKF#a<꧷ r{j_'VQۮIENDB`bareos-Release-14.2.6/src/images/folderchecked.svg000066400000000000000000000557571263011562700220220ustar00rootroot00000000000000 image/svg+xml Folder Icon Jakub Steiner http://jimmac.musichall.cz folder directory bareos-Release-14.2.6/src/images/folderunchecked.png000066400000000000000000000012641263011562700223320ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<FIDAT8KQ?w^EL(\2*%|*+B?U\jkk'3DP$ BL ݫymЮPp><|Q>pZǛ? J)1cpQ,7OLN4MZcZPUU5800'@J)ozzz^REQD$h1`9ו )%>>@) 9.vhXXgr͌Lθ<} @&5kJ=;7ۛ)1gL;W]ZeRm#:rtr2,gBPM HK)Ѣt4J(Wk岬o1hG6 )%h/Bvuȧ_t5%[:ZZ!q^XJˀ8rHY Fg;Ek|[a6Xl J2ZFF+Uχ9<7P. 5T{wST~brD`~mܛd=9zY[]nk?Nj %8!Dc<`_+1EIENDB`bareos-Release-14.2.6/src/images/folderunchecked.svg000066400000000000000000000561441263011562700223540ustar00rootroot00000000000000 image/svg+xml Folder Icon Jakub Steiner http://jimmac.musichall.cz folder directory bareos-Release-14.2.6/src/images/go-down.png000066400000000000000000000012531263011562700205550ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<=IDAT8MhAߙk`C"I"/*AU*mك١E&MADEt>S8zVO޼)c>. Q51Qw&zgO/Dk00(nCȽ{[a~5鈴@bLQ= &$dY[AOXZloxz.Ҽ6?_h8|E7sJ*hIENDB`bareos-Release-14.2.6/src/images/go-down.svg000066400000000000000000000202201263011562700205630ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Down go lower down arrow pointer > Andreas Nilsson bareos-Release-14.2.6/src/images/go-jump.png000066400000000000000000000027231263011562700205640ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXV[lTU]53iki+TmR@J?L5ĠclJM aL$Ah*3myX>g:<̽0SNv9}{f?7]Hx~1 9QFO5}JC' }jCQe8NtuojU)!5.ٍ*D@.$Kqҩ' /\Xbp>U L`a1<I1Bc~ $ D5esrDg)LŸ QLHEhmkS.^m@ཟ!B^ر2'QZo93`t(m5 ;ŸϋK/x^4GXՁ=kzS*?~h$Ui r͉n0;9r L* <ѣ8k=unkO~GJCZL|aZoQ.G-ߡob? s3 'm\,>HJy#3%'kḻ89Xѯ}64{KC09! 椤%5u RWs% oj%7r"٘</XOҋ\[}Ml_ %*8pg ]aXyљ VaG3!^CC$ɘ{NS# j'>yts@{c{4S}H:dlj Iԁ1g& |@t uodВJX:FDQm _|*a2#mհW$K=[)aӊ+z}$^ICtnq o}; 2ML=P\ Ӝ :U)wK:]U  BXTj&x~r\kAOuQMY2pe`Scy# ToM(Y1N{eT4V`.cc<ޜ|_#,FƜ/B yYO>u2%2,g#ڻK׭C jyS5֝`m\XpS@w\2;Hen;%/Pb )٦,g6[gKo,tP`M5U)HM9}t%2MF-i@CV@dH#miH͵ &! Zh積EOid78D:hfuXb"g"@KF-Q<_m-}mIENDB`bareos-Release-14.2.6/src/images/go-jump.svg000066400000000000000000000176621263011562700206070ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Jump go jump seek arrow pointer bareos-Release-14.2.6/src/images/go-up.png000066400000000000000000000012141263011562700202270ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8OhAƿ73ٍzhLт@*ՊhDbE-rkJIbREOBM*^DPC)*4&Q!|ߛ!5ɛ|fvn<IuL:.O <WLFfG ฼ʼns֖ǖ% Ep74HK: ]"GJ a2Wk =<؎Ql*eh :}6.N_ +XR"K(u@AVqE؟~ԋ+U?cjJZۆ25|I=/b1 lܺ?n%&Fs'0۶К"IENDB`bareos-Release-14.2.6/src/images/go-up.svg000066400000000000000000000200361263011562700202450ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Go Up go higher up arrow pointer > Andreas Nilsson bareos-Release-14.2.6/src/images/graph1.png000066400000000000000000000034751263011562700203750ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXˏ\WUczzgdcv "RĚ$&+vH,Y!V( ‰c;d^\ƜM4DNFL9a0[B6@Hx~2/yg/9{U0ˁS$g/K @fB!/DVT&R# ` !.,":agW9 Yb buHC"ù2DU"ֻV Kfmnk·*y:@Z7 ,gQ {k3u#\h"x,%Ȃ$ ll:nlwX u1f3^rˑ^Lx98Tt@U"J .+8{;m6-z=mSE"!Bg'Ɠ3AUqށ.\U"ZpkF pLg0ƎXaQ.SS3CTS>;?b.*_ki+8nN*|[;-srQwWN?7㓣c1NW4~_xGj5FLfw8w\\UouެyU-|a坏 #YiQ,_rr9J+w-Ͽ9՚\׿jXcB0#5$ 3 QNLů| I% Ff9Wƻx.%:M: т@5!@U*Nq2iEyjSTcGt;A;MCrrQ0|QŠ6괷đ,ι-DPg+AG'5|3:x΋6@ q;Ð`&y c(/*@3PC%gLo":VJNE,ylDppN >?8KaV(G f)KnJihkLRprM81eC}1KY+q0 $*#͎8Ca4khbFXeb:F&V,=q_sʭ^C.>4bAfKOu- X\OHw>|ɱzR@Yz~z+k8RPI ![\Xz4p5F~\Pu8G:GX ߆ /']1B8*EU폟֡I%x]*⴩&P7 /*`Oյ~i+jWzwu_)'>um 'IENDB`bareos-Release-14.2.6/src/images/graph1.svg000066400000000000000000000321641263011562700204050ustar00rootroot00000000000000 image/svg+xml System Monitor 2005-10-10 Andreas Nilsson system monitor performance Jakub Steiner bareos-Release-14.2.6/src/images/help-browser.png000066400000000000000000000015361263011562700216200ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8_Lg<_6ZhVpMQ\草YL],lanfK%,† "4[J@ @QrO~9u]OiO7;75ڛh"f c}l[bܓ#jo=RJ Z^sD{>g葎xשw{nfєBJʵA\&ᙟ?BwnXj~a{ mp ys3\KXz=!lC˟=:'e푆jW( JmCoxew{ RZj)"U戧@4ѫ4eض8gӓ@JI 43At u_`c})y5Vpv *@ @0 ٻˏ HL-b)u`4WDI$X,f7eB͌ù&ÓLBPnftMXK)y黝M< m=!VWWqV+ /07rv042MLmxĿ=Nt^v#e[qm_||W>vaڱsOoo$Ǧ(R 9B5[{_Nudpq ?8~H(~WNeڟ d\u$Pl<@%`@fG Bg{TIENDB`bareos-Release-14.2.6/src/images/help-browser.svg000066400000000000000000000320161263011562700216300ustar00rootroot00000000000000 image/svg+xml Help Browser 2005-11-06 Tuomas Kuosmanen help browser documentation docs man info Jakub Steiner, Andreas Nilsson http://tigert.com bareos-Release-14.2.6/src/images/home.png000066400000000000000000000033651263011562700201410ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs ,tIME $\kH&kxb |bC$*g?'pL$?*S~Ȏe;(kJZC/XX=\_''~͍?"ie"PtK+_OV=L;:T̙HL,/9 -|K?m?(TȹS<5BGSI)̿OʪX}]{!7o-I=!?j/Wh۝|Hפ?SL 6w Kqp oѝ eBY@VEDlOszn [}7Z֔l) Nt`tQ I7줷m˨H4kYZ]$ftM#I$<.#h37DCճ/ nvwc&[ƍ&ݵ{/p3HEµߟӗJ0RmlYY IǎŻ )G^7{WKf ?,+pmM //7Wv>3x̑O}2*ŃiV ,+IY+K#,-WFKW{Bi,=YR`vL(v<‹ODWC$/%7TW٫ t8u짯{piY0qde14/2^ z鞀!y9S̤y.F!Dž䱕eF~jK.zBDq9aLl\cx{eD!3fJ{XrE4rYzNxP SgO>J7hjX/n,]*B͝d3=;Aqsu?y [QkV~_VG_a\<'|Liw2嫞v'!x6^ :U5SyjMSA!Z W.QlP 4MQٹ)fϞ!ÍWE.uM#ǚ%tւ'SFKZ;inHD,]yo\s*YO'_Xlc0~KjBAJU<7`=0w۾ ܈^}lk6rYϯ.J8 l.9MA&j߬Y4-bbJ(<X;5(bIENDB`bareos-Release-14.2.6/src/images/inflag0.png000066400000000000000000000015171263011562700205260ustar00rootroot00000000000000PNG  IHDR gAMA1_IDATx͔oUc;v$YkoVf0:%PiJ8  m6>{koSZY)L*qr(@a+⥙20G?>^&]߸B 7=C$[.c{h҄XJ2'J>V)NU=a.ZJ$ "I!dUYs>*mF6ɠO#xx0DFF"1OU&5HOk.n'.aMH)Z#SM(MWO7eqBu)5(I: H!~%G$IB4y&?6{R02F!? #8IڀQZ^%;Uޝc"o^͠e?Q+E qqWC>s_;'Ҽ0ƅX-qLtMQ;U%S> Zd-KDJ)惶).k`/l|BmbS&n~m޹pN6k /7(x^WMq E~|ˍ;|3ۿK1΁ВK$^iG7J 0_e\է|W3:TfxC\Fd)=!Ɉ7O Cw}ڇ &}r#psxϷwߡρׯv ER4e_F!-52,cv^6AՏc:K=5&(yG0cQ[\ȿ Y|Y( "aJT%,G Fn^_/ '`K,-0|ɽ[3?yx6gNIENDB`bareos-Release-14.2.6/src/images/inflag2.png000066400000000000000000000015331263011562700205260ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs  tIME 4jIDAT8ՕkU~;ЂEI2hp. nō YB:Ѕ]hKB qMJSl0j!65%mqɢIv׳=6==Qukiiino>j$S[k]nwwEf9;;{=|ZF㻍빙gNNNZk]C >J$It+++iFvY]G)jWWW[ITg׆K?:;Yc9g}X?WwgXdg^S## EkX&Yvw?aҴk2ߠ UJ |{񧝏 7nܼVǫ!9%b̗tVHϫ+v~ْ84Bi/JUƤb걄E!RJpGhTȠzǞmm ^! "6Wn q`!̓?(ACtPA!Z+A@(ۧO!" DpTA}QDV!\ tʅB US1AmQ Ap'EU3<| (x*^ `gy=N>Ƹ֕:Di B2 ާ_(DnGQwx_PE! IENDB`bareos-Release-14.2.6/src/images/intern.png000066400000000000000000000020671263011562700205060ustar00rootroot00000000000000PNG  IHDRw=bKGD pHYs )ItIME ]`IDATH[he73;57sф6Xh/(XP "}HTD|KIK E|FL jK}hh6Mfw.LJ So80|s(=~Qϧɍu4s}YgakOehA}j B%j ]h;^8M^&2Y@e'Hbv4]`-{mQKLq$g}_tU A@_=͹m狞xّa|oeNU #jPQjQPYıC6yˍ{P sCu mL@D6l%`1vW#U."9AAJ`$>ٖ9wj{, J!\ @!JPh0D321ƹ/rNQX_ $@}!P[Np.SmF \O?|MFnn\2Kgt%Df9Woxh9SӴwGr{!v 'O Xc!:I^9雚\/TG2 ~4sIL8\y#HQJ* TZ_^8gwRXV@2!}Ɨ%~,1؍ΊenqY,S\(KL6vhCK cw^߿%65L'9 Oo3@1Zי>WFV`qًpO!?dQL;P{VCc@ `jE3~x}RyIENDB`bareos-Release-14.2.6/src/images/joblog.png000066400000000000000000000045011263011562700204560ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATXWyp]iuX%g۱-;q MCJSL MJÔN @\Df0-v9$+I!$8plXeK.K+iwO0fJ)+njyUU9?Xy"RKoi2v7 K6l?Ij9cn7_ؽLkdg]>i q+Q% PJbX8 gٝ yt!9pH̪[xБڹQ(|oO[[l!@gX .ut Ȁot$*J?4P^ۺ*st@Eq-!FZʢ3vRc@EPAE0Sg*uN}ӟ`:&ʺ^TEٲez>;yY%-ȒR1 ݔ5T3:q&>`Z"c+e J)n6K5{ZTM(U|άHn6+3\x}ORaҳOhcJh4x5luO[یK#VxEz61N%T  < z;ڿz'<īgY7WJXj%;:^;Ok2J~;w\ҠBzb ¨eê^Gϗ=mm>꯫Yi'36/ØAƈ覫\Zj- v^A)i t"Ì'))FG8q'jcw9h!u! Z"Br /_{UNy8Zk:wdEre4)0woT,qs.0߰9-\5hp8fӈHK(,4dzFd 'p$"WۯJCGvL?Qyh}c’ckûDL K' BɎKk{3uik,O%X`0p%eVIwH$澟8 \UTY8K3  *NR xr$089HiD}Y]SxEq_ E8 5\0 sĉ}PAkX5E(*p8JPE~`Nu.B-8 vs>nbXq"7< 6 L2Di(Co'|nwL 9[MbҰsS^6Y^D8Co뛰NcB?"LTD8~tH{~ 8B6^iڱ#>7F_ dӳ6bMiUyKtH$NtCzrex"9E-)ςrܫUEM5Icqމ DiU45\,6Ȏm+ڡsrI$dC50* Դ}@w7g O?eY 3 o۵KMkZ6f-P牌QFj\^PsN䐌gESfdpmЋ;yZ\lHVuQ4+, ^FCC>|~\`2P5E/808fWM}3q-#pKkk+r9 %=jTX))*"1~s2 3 0UL|r.'eH"2d4j΀"02,V0z\ 2D E?g&KA&W,nƔolAòa,`|C!8d9988zG,B~Ld)IJiR:` :>:6zN*gA,9yy:B2F $!diFͼ]TEEH=;o +y6sv`gyuQ8 glmKw_V-Uڢf.zFo]JdL{IK:E fucK?IENDB`bareos-Release-14.2.6/src/images/joblog.svg000066400000000000000000000324231263011562700204750ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz Emblem System emblem system library crucial base bareos-Release-14.2.6/src/images/label.png000066400000000000000000000024131263011562700202610ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGDV pHYs )ItIME  >IDATxڭ[he5d4[D))mAb|EX>%}1`+,=IDbmڤbڦRk]ldv.Ň$ x;1gnΙ,T @Lt}D jqˬݡe~v 0 <8U#N7:mcF{Q#Yda @֯Iضy5@(;5or77ƙ8L@ CH2A2;0}^dߑ!zs, .^:Q : 4D)AbXA;iVCpy5$/>ݸXN"%jY':@jq4 Y#εw K[[v&Hb]6}[Ԃ+)JUz&<8B 90S1` $MP@)E cY1&Xh%)JtttT]b~>C__inn&#\k466Sc6׵r3,|v:Vzspp*`Yccch Ðׯ׃_Y` D5RB@r92 qzVСCHQ2*Jeǎ)+3mXlNZEa:`"C(w)aIRc c㇒l:H*$㔃`EьB0~,l\[B4ZI ( =Qd햭ܵUdb81㛞qtJnQ ˜:M L9eupI%Ak)oxd*ޣx}x=:W`l#>)Ǡ1h` īzLIUg^[7J VT. q*BkV졕"$7 C$ ,wL26!ZYʆC?1bLKM=PRի&4--!H>Z+ $ ZWݵG~lKpjl{e+-f81Jc\p`BPȟV ]3]U_@ʚ%vuGw Uſ':\BlͦIENDB`bareos-Release-14.2.6/src/images/mail-message-new.png000066400000000000000000000033201263011562700223330ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<bIDATXŗoT?ݻ뵍w`̏: !@*Bj>Dʟ>XMP QC)>Tj4 >4JBJlw/{gNvzצj{g51wDU N: nQVj |?|?,D!R`2ޥM~ ;·{w`_ٶxl׎<'B$QE0!-~ }}/HoTdJ4CG_6.^3#_ma _'3%CC(`E)߻MbldCϺrv%V00CFBˇW?wo#i)68128,n|4 5mQ-S.hD.?i)K(Y"nDzYTpG$5NĹS\.D ҹ"^y>z*ޒ72Rw:[F|H Nu⸻Am#iP " TRN3Onf,,Z"`-q5)5c@vl}=֟v +Y! mACLws1޼f79~ٛ7 Uhn-.P8D'80fEAgSٹhx':gϞm;&Uk y7owA&7ps8e|I_dd",2bЪ*{r{6?'jI ӷG޹@h> @qf|d`nncLvƢ1vmln_5e 4!Ko?\0 Jꐞ" WqN;s䛎yU<"u ]~ `U?("3@gyPǕ++]Ƣj9UAu)4 A}9ZkecLLNv]a""U`R`&^F"*!OV@mߐo y'IENDB`bareos-Release-14.2.6/src/images/mail-message-new.svg000066400000000000000000000475421263011562700223640ustar00rootroot00000000000000 image/svg+xml Mail New Jakub Steiner Andreas Nilsson, Steven Garrity mail e-mail MUA bareos-Release-14.2.6/src/images/mail-message-pending.png000066400000000000000000000033541263011562700231750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs : :dJtEXtSoftwarewww.inkscape.org<iIDATXŗ}l?繯}m jC2 k ܛ%nlƈ8u[l.!ScƌnLG阙"3le"6/9qEҚ웜9wGT0@𫩌f+**&@ FQ $&pB (z`2ܲgnelFT9癟yתn"eA,a&έ}qOzxXT[`u{3'6pJAsWa4٩ zaOj-.joϓ!Wwiwgz3)Hy4w Glt{W.z5:r8b. D@tqUT!Is C״5ʓC &q 0 *p Q8NGs 5/E*1+/Yp=̀E ZHA*C, pJo۶:7XLA.!Xi\UG)d _nV80Fmi}Ӂ8=N6[ ')p8|z۲n|cF}-Hye#eDD7*h?`O0X`zJ ؾ}{ʹnK\여E:6UI&IRL59˨D}g?+\Hc:9CeCJ(@(Ugۏ rԪ3Gj@$Z17F!pȐ cՄwfk_$^0`t>C"|dghhjFZb11cHRyI-:/Zn>2}=aw'c}4IuLhmBGd:>T4OyJ^CDpTYw/H$H&d2rܥ_l ow?E_H+ ("omTl?u85v1ر 9Jo|/fw2:fόZ,g /\޹^eNݯ`/)h {{z88_xcL@fGp/"ŰH!օb_z`<*z+*Xy6/\*dzIw˧n#H^`;jIjMlN{p=pӣon;s/_5fcg.y mǵs8-~ظG^IJvph8b)9U1X ::JYg0 +iycDpF{0|K;X1e""#I~瓬)8G"d f]|NPėCTi~ óf#n8"l\&s֯#zh[:0`jc"'|#R\. b*Pxp!Bj1( &/f3ďo*_*g'D\ĀJ ɸ_ȮXo ɫѤ$c>28@=<ʢs>Bp虬h! AIENDB`bareos-Release-14.2.6/src/images/mail-message-pending.svg000066400000000000000000000501431263011562700232060ustar00rootroot00000000000000 image/svg+xml Mail New Jakub Steiner Andreas Nilsson, Steven Garrity mail e-mail MUA bareos-Release-14.2.6/src/images/mark.png000066400000000000000000000007041263011562700201350ustar00rootroot00000000000000PNG  IHDRĴl;gAMA a pHYs ?@"tIME -4bKGD#fZ~AIDAT8c`v)?: .=?ƒߧpo=߰ +n<_, &c`<_M'dE3wg:?g8Ʀ[DWzgKGO image/svg+xml Media Floppy Tuomas Kuosmanen http://www.tango-project.org save document store file io floppy media Jakub Steiner bareos-Release-14.2.6/src/images/network-server.png000066400000000000000000000007461263011562700222060ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<xIDAT8?OA qBTގ@Ö, !&V 26j?h$S/ސ?BmGpLӛ^w#H'ɝ1F8Nڍ̜(=;v퉈R D"sDDQt)Fl6{Md33C)v}k"0 :3VT\$`f$If m~l}Z"bѾlFkAfZG rW "P.v>ӝPIENDB`bareos-Release-14.2.6/src/images/network-server.svg000066400000000000000000001212671263011562700222230ustar00rootroot00000000000000 image/svg+xml Server Jakub Steiner http://jimmac.musichall.cz server daemon comupetr lan service provider Garrett LeSage bareos-Release-14.2.6/src/images/new.png000066400000000000000000000015241263011562700177750ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATX՗Na5{q\\0&bXX ѝRHECey{QJ!Iޜ3MN"SsՐn==d 12<S(CfIkR׾TUNK޷’=Oޣqnl4kZS YoK|mu5e<7ɺx&oFh?B~Ql% wIENDB`bareos-Release-14.2.6/src/images/next.png000066400000000000000000000031561263011562700201650ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs ,tIME }IDATxŗl?3{w{>6؁BnD)D")MH$DjM[(*$Jj'D4R,!# E U '`jLsN|{;?{ISuy;y3=?qw7;"oViX)9lwN/Xw7|<@il4aPuV+ q 9nh8B0ebYϮ"z.9~}Jɗ9 D>-o*?5H'kg}eBw{%"*R{D;,H 7LhƷ.j/o322# 4*}VJ>-1@ n&$M+ڶ=lnYWS417M1׭|($*nhz Sд8-U퉟q)wu㿨7Nt0z*c8y`C.͞GݫdUu˱] ^D+z̄xAҶغAܲ 甖 ][fj4+7@aO](li-)xJv)N]U7l@1D2c/դmq|aͽ'=[u|W'wAPÉ 8Ĺwo*|$<?;,bi]#SĢ{O?|UKd]wҜeYxaʭ@oL>%ϗ7[/] H|4\1nY 4X%)47YuӎJN( qWvPZ+ 2CWr&?_~G|@+%&gbL/ 42g2?η_T@cR|A+=(sC3_)c/*VJU|R3B |Ǫ*. 4f2?c=kX)9[ӭSE),󽿼Nъ2HJ+ ɖ1V5}fNvOWvtlCNxLS#9%D?I&yZoS|?1N#G9i֍~T\\18;NxLc0\Xk27âUJwNp5Xf0gm?쫪c&|]uخ3 Ʋݹ"#xQg)^JD]M'z&Ƹ?JੌGp+NJ5a aQ+vݸN1th\LJ̹rQZse\" T9Mv >gZdn>n&υd4XѰUki\ڄe$*"[ ݼa|/D+Nx4#¼i$RҢxLR=4d|~ +Eu:1`V[E>a5@}aߗ]v uH W*e`[ '3">vH~Y2ϭB9DQ臆={XSR,::NI1>I,`]YSMM4 1y`Ż?ū)LOϮ׼tCO3@{=.4W S2^5C`\&K|H$8As''H׻ "U77N,V>V:q,k,'6?F}oY1~ Z{?0L(CF&e-,!4{Z;~m$~CF=5iu?PZlY]/sq 1% cbjC'ݼ-Ӱ;3&SXO!,CPF BBsZ*tȼE lϛ'Ào%Q(/bM$"R-BySt < ] /yƪԳs LŔbK˫#7G<<b~/=/-:C(QNܿ}3i 3Th58 X\3>GelAC'b ER$nPD΋J~ m['Ѡe")(Ȑx5 >c f]KcNzI1N[;|%jJ0("3 t.| J*qQF@7 jH7'@L{RE qAAͷ]lC(N#KQWHoXQG `4QɫgA@?noiқ*/ru)S)+vQŕky8n3cjs@"mDžPt +4X$ |J8aVU;:!z/]&o8=cn*F׃H:381 ^QO`+] 9g=JUmCeS@%`+njǩD9|6ZZ8/95j'zLIdnFڍv9,9=NrG ;Fc9=pOJnX,P(@!F.[! o<<5iEX?7Ǎ: !p5U!4[7*4nI:rsm$Jesp)>|c.2*\"]~M 6tvw䈶"I m2JxLKIõ.|me6Y\Q{ %&6ǝՂ^NEXx]\UPuTA/ rjQCO-H/5z-Wxܯ\u˯Ev2g`§ҩ;P 9 /"mak^2/f_=IENDB`bareos-Release-14.2.6/src/images/package-x-generic.png000066400000000000000000000023661263011562700224630ustar00rootroot00000000000000PNG  IHDR szzsBIT|dtEXtSoftwarewww.inkscape.org<IDATX[lTU9st(*o1`|34\!F_CFjU*I( @D#H*B 3ӹô؁)fb_X9ggd﬽k-ijR8wsn \۴hŧcwY|bV39Μջn.WTv%p]PWB@Y)|L qѥ̀U_ hN 3<=g@nkX"wxﯫ js*K}esHy#ԕƦLf+aNYfo\Nu9@}O_\ozWq7jҞc-PB @5 image/svg+xml Package Jakub Steiner http://jimmac.musichall.cz/ package archive tarball tar bzip gzip zip arj tar jar bareos-Release-14.2.6/src/images/page-next.gif000066400000000000000000000015531263011562700210570ustar00rootroot00000000000000GIF89a$H(M-S3Y8`?hf/d/e,f0b1j8n>s?u$j,q4r>~DoBmJuO{HzN{@@SSUXOOQWVY__`eihkomgihq~煮!,H3H3Hh Sx1 5(TaE Ah!`,!2ₚTɳ';bareos-Release-14.2.6/src/images/page-prev.gif000066400000000000000000000015571263011562700210610ustar00rootroot00000000000000GIF89a$H(M-S3Y8`?hf/d/e,f0b1j8n>s?u$j,q4r>~DoBmJuO{HzN{@@SSUXOOQWVY__`eihkomgihq~煮!,L3H HXK1C.*@cƇ 7BB Zx@T̠ϟ@ ;bareos-Release-14.2.6/src/images/paste.png000066400000000000000000000033211263011562700203150ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<cIDATXíWOW. "RV+DZ}mڴiRM?<>}M|!E4V"bbbQ EPP:;3].q3{Μ}9#qbC{U6k4M{ xA@DFpslKs22я5~nHtLKprZ,p2TUñbYȖ|n{ hxl-0HA‶W b`DFl~`_R Hnw^B88Ck8p  >QnLo8FtfWbDhjj FSN5gua,<|` C!lΒ]SPFR222B+emqbI ci6lLCXQ1 u4ay-|(F|W2 EQI ޽[,D X/M-4BM'pq&2>xEX0pߏT#K(~'1KV$*<4'Rs$χ,nGCC#qֶ}.$@tRp!H Mx;Pq'aIF$ 5Џގ-[ ''h5߿vߋ/BȸnF%,N0fǛDk,bO"pk2֊*htkM6eOKK3$F-IV烐|;!8Ud1'(i.HME Dsoo Lx H[ @KKKłhܘF#YG_| #g-J:04B c3;țGiϴf.2M frr0vx׆I-k>CV>0 fHJܰ\vX,4QgEQ5͉ٹy鐂 эV(+BYGtL͟3%ZBo{n4 ^qXq.9R"B)" ($pA<4m ?W͡) O+1Ϣؐaz(dE[5M[xu LįFoB`#_z0$$7iJpwK\93?|nƎwa[QQ6:u0~;ʜhDƮرeAVD}OZݐ0bA Q .K)B !Pf iky77^-\pvv~d /b=Q#t:.ŕu/mRt0[Mǚta@h4NAZo@@N:aT3' zB4hv[ZZ$h (|LLLD"={p7ۏ)Cˋaا#%j3.K7hRk2hF1u]jkkΟ?414\Ak>yd ɑdpx?A.UtrIENDB`bareos-Release-14.2.6/src/images/prev.png000066400000000000000000000031051263011562700201550ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs ,tIME -xIDATxŗ]hsJeYrq+AEKݦ:8noeDPSLc-{q`̔XJM\oj2NAn>GFi<"}ДҒXeYý[5GܠUvB: 4@ڶfxdߗ>!^UrWշw!*g6Pɍ; 9ȑoѻn`o`~HjT'"PlD:L 6Oop[g84r YΜ5SWީxʈcSaʔhs5S lǾ}[ #̉GO2c^dKy3pa>Qoɔ᮰pi9`;ˑ/|޻n &_ģ'gjCg.S.)L-\rT" NwҶŁ={ Mq}z}h47 p9?NKeLlھB2PhKo=g{a\pmvVPZ-jn)C rCeq}?n%H'Nu$[x%,ˢR&vlX׳r|Ֆ=/L[.4Hd'`'Li`Ycw|NYxn^9{L a24A&m֜q vwXJ5ݥe9 m*WԳ/z^&P<_'w tPrs0 O>KϾj;Yܞ:oA b5 V :eSkL x8 {^@Rg?fmB=@ Њ^s @y⻿:QDoϦK"|XNƊ:. sՊCv[|ɾ Vb*m )GB#dl&?~l,)pbI=P{Fg"_/*4ϧچ%SlyC#_৿=4%657 szW`(ƊQSM~O=#˴m{XeH3柀-͍uSIVu+2q1uY)uxf?r4HJu|F(kWBH>;@֫FȔ!mM6Ŗ{8e|ȧx%EhŔF/d7 `6&wV-?""l]uBHAIwJsR."n+Lz=^%`XlښkB]@SL)}n4\f(!oR=l׬9acdga1;5)jn@IENDB`bareos-Release-14.2.6/src/images/print.png000066400000000000000000000033041263011562700203360ustar00rootroot00000000000000PNG  IHDR szzgAMAܲ{IDATXíWiLTWv!b%R EIVMlihŲF,aQH$d"BYD@@}S6 $ b _Ϲ1/޼{s=yT.;/##.Hӫ%.VGFެMLj/6A+WJۍ|IiZhoGsL ӈ=뗉P 2ǑmXyc8dq[+F:`~!,шKKB%3 -IJ9"g(jGͨ(-1' N t;Tcu`gĎ:6 Hiꀄj lJhjꀯ+25D. pR1qPzahhx! PPPxxxLnڴivmcc+,,Lr\|իWFGG?IݍJ68p`u9r$O&Щ`C&}666s 0ykk(TY{Um VOU;aB*y`---ɓ'x1=z$Z gSىDsqJRwL ;`&H0n޼) [n߿ P8K?jΕK WLvv(d???899رci!&&HIIUEp01ϒCbpubqyxz 233 Bt]QdHOOXzLM yu21 4%+Wؼy+a7oj);c!"bsDy㜫 {KxMOO 5ǏG̹*9]pT[\3gЎi8;wJXwMEɹ~P߷hM }D4C idP?xaKs$N:jd}...s myS1DFНq}\WWc˖-rvE `mm=+97-᫩ 'O%|h6_|͚5fff#‰Rw=eس dQ|ޓ˗&55K֒TY~Ajžu֕ڵkw@vx- ŋմJ[vrI4Eoŕ*"u%<@[[qmVVV-۶m=ZYGG|aBOOOU@N(Ή+Y+h ,(D;ʕ+V^@Yp7" 5򵤘 ",Sre~TJGcIENDB`bareos-Release-14.2.6/src/images/purge.png000066400000000000000000000024341263011562700203270ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs  d_tIME  )EIDATxڥ[lu3ζ{˭ D h1>l[% Fbc)QI)jwkٝٙnZx33?w5@,?`xbhhH.}8s8p/eHƨio[lN#s bi)Qiٹ:U E xRzV`zNYAK|>Fմ=PHE&RǺ_].]7j's~\e=-lHtx !p.C l&bN< p(פ%jU X]GU%z{א̒0ͿO{0,KU]*UY@e 2IENDB`bareos-Release-14.2.6/src/images/restore.png000066400000000000000000000025101263011562700206630ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGDV pHYs )ItIME  +IDATxڵmhesngg縷rDsk"7$ZR>ؚD0aQPۇ"C,&fei褘3QwvA n_}]" HSjJ?ǦQ@T@NW[]&×ޗ\(&=/4཮M*G~܏5C8yzk`[ 䮨8]?~Kãwxe2VB}Hs3@Yi s+tӏWCL$!96.#N.z9wgcHBMV,>K:=+_59ۿ!ʡb)XdQ˖VAzz.cTOTcK#,y 4-БvTUE8VpTF9hvw;c煋-088i!rjv]'OSxyJi cAcc#qX.?C8FuezƦ4`,üռPKMM 7n$_OX,F$3%B%O =˗a U+ٹ(MMMx^|>'#I)_:ihhDu{KG"es4gnFjhʙٵgZ[[inn&4mV8u,Wb.zvTVV200@gg'ů)躞Aqq1mcA~ eL e`w˵>oz-zr( SKq~&^ۑ-IENDB`bareos-Release-14.2.6/src/images/run.png000066400000000000000000000043701263011562700200120ustar00rootroot00000000000000PNG  IHDR szzbKGDIDATxڵypU?wykޒ&$$a1MZZKihu:PYR;.ԙi8UiuԂU bRH򶻜. (#̝=|sIA\'{zot&]8t[w } V'* WBq=g7`׭jMb5A#B,Eڊ&ńOŜŤPO|VZc\H5u'48#kРQ+tlJ5ǷSQ]i_UZRTrcX_ˀ @Ҁ ܐMcwُ܏Z,u3IrH98QO6@jˌ%&LnPd>S{=a9s* = ]C}l3B&GgT)Z:_5 rܶOmfu+4y(-ͷP6>%iEuU]HYP讇]E(6LG[+DԨqڑ/z`bi\< 12j$ ZO[*oEH0LGAd. DZ@ vkiIA vT*@,q|.X@]2zSs8+wh$çb8smD#n3Ig90Ӧa|i( (5wu+ ȒIK0mȒ) CJ3ysKv{1x;{O$~yة "H~>7 46?Or'S[gwy X:1sGSV/!~z1i^kUHDgL^mԿ5&prAbSW7_).j,u73;l$&딺ylb QA[3/|JqR&pl*+u]}-u3/>H_Øs3q? TI{\~HqH&[6$ 4 N*H.xᮽQ2[:z\WRz>T plsJ)ĝNXU p`5}ChIwm'q3JB q!_ӲCN-uWVeEb-EIw['BX`O4FZK<|0 _$Or0M2Gj}*%^f֏m=;˦"X: 68ڗ!  ۑEK<5&X!!{<=Z/2]MWTlHۨ*gv ,'|텣^τ~Oؐ<ޯϣ5h qi^r{cc=|fu^;hBH9և fh&F"sڐ谒w2'kfF=N綆k1%[B'M2q}?k~1+}=Ǜ^)GCpG(y^Uੵ<*ڜ F\S–L+9#[ԐBdQ`,7 l ɇw7}) D&Xn!2vSṼϵsW"]?)Գ!`QnpA'r:!<ŗWH)!nvTgo("-"vYٻxFfLE\X TJ0=u|YIENDB`bareos-Release-14.2.6/src/images/runit.png000066400000000000000000001062661263011562700203560ustar00rootroot00000000000000PNG  IHDR/k*sRGB pHYs  tIME 7$tEXtCommentCreated with GIMPW IDATxwmyU%<>^~*BQPZhw Z("m>R[" F-1Vۡmض,)ʁ}sҾJQ;svX{K^s]/{PӋ z`pv!;Hyh/3|cFoy (N+ 쎦n3[oLv?.ݟ%?:r{{dS`?"bk#ϳ| DQ,ߥ\a@ݷE辄 n ~^BJpa8 {hL݀r)@|gGE[j 74aq7}:5IHoH1x}\鍍)Q V_ts/:B͓PG}2.Hb L c2/)"ã]卨 ~}]|o{ {E?7 ?rTƠ{r7E?Vi,A̧3 F}RUȰWUnNpŘyRN}c"UuR_] $3lhbP]HWtC  (clzJ hòC g9^0ݱgBNuSĴ7ȍ\{Ɲu>~jۧrD}}2B?1ߐӱsw`Zj_3k;e0&(٢7|QR(Fy }C6KE5` z&VIN8!hBG5D&Qcti1l)(RގFP[R1I} hUkaI u\J8vب4)LnBݫA\#R<{sd ~M%pAY/-DKf}SVՄ[00\ +D:s5%a*Og.!!ገP`N栋I^7r{o*:G##`*}$E|V ybI2wi8FUiICH.d(D@pe"ƛ"G\*I);#C=2*,  Xh[BdOINn;3Es1t=-I$K1һW)YK|2 'ѐc-T"۳Isa" MP.LFw ܃h)LG&CaluT -Iw$znQ ؘ)!M`CĠk')9=cgUB'yx0Y} t$8b\ ]eAҙ QO$zUIi=6Albڜ# ܌c眀WQŝE,ڵІ1:f(2&gȔXJ串4>a+S:])>$2p`J6Hz T)tDPKءXӕ5<mb"}5{9MTɗF[_O5h{HmQe1@[ {>-,#yH\s@ЌCCJɞ#H8AL6޾ ڂE*gQo)dFII߼EptUXP+UnH?097+s?sxOw줌n3 1t"+uzTQŠr%>#bK4l )GJ@}7mA}r|Mu7JwKa7K܃*(IOYl{ڂBA P(J"c1(ۧ`G4]4{+f&G2]OeCӑI#))4l{*vLХT&4rՇOELl>+dM1beKg 谠2"{64<ܞ <2˂+]IRgWB6Yp؅ͭU%4,Inqe1.OqqW>Ws%48IMbQt(c$(( 0nk$C(Ś2T:MGB(1yVv$0pB+}|"' O},4Ұ2M S!˼A)z1?Y y3!7 ,:>w8rI}G@.ǰ@ӀK\rOAKPРn@? T.Ry(Fƕgba)tL[spa >\3 Z\6LQj^:$KQ4OP5G^igROB EBdPd򝞔tE]h3Po cPa IsDCnΡ-E86ϲfОɻhK$ތBMgY*Edh#w3TRC)y4~Э2wDlRQڢ%2+8 JD#8)7R_@UNڐIuIQ""7MzTz0*K`Mx dhI1?Uj̄k g`h}v>Āg!t'JN#PM3YB2}>q |P˱0c#yJ1F&Ջ'0=`S(b?Wl,vȩʊҲB/G.FM".;X4iU3#IWBms&I[U"(c@]K Tc$p\ӨPURli4`y#1pHLQXa@$RlF2 !TW!Ya M7^߼^g}_B1s&"\V-%%tX x`i2j{h{lc Th:&CW0gðeE NW6ﱏ(.UE { c>,$, 3Œ$Tr!-EeS6tr +F"/:}Z*1XRcהgC i01pO L!:b(r={A1}Oqe8;7:ˆZȌhfV]$\҆Mag[ l11m2*AϨRi+MX|2 %=KdSa$;:ƿϒfFu<1َ,v$!2/x>><>#T< Y6( Wi@MIHXό|d`^Ia*C"xLYDCn{`tݰ^1 N`{\لI8O f}qH() Qmthdu4/(t.?h^9Y1qO+61]#P{|oq qؑʥaΎuE(]`HFR 4e.QH=Oi}4PTvu08ECWa%d#hpȀә{CI +ԙq{!h3ǒɑ 'Gdht D/'7K;JzC% !|V,=ܳ]tAD]1G!?$bOEdw'Dbr ~<\o4!N`D#8#D85o#lq8{Q!GH %N E1|h%m&&U\O/qlԴ=$h1FBA3j<3CH% .b&\P0*0e$LI96n#Ųg8V(jp"bV pD/-אw aQuuI3>ǴD|$#,rr,0J$uY%6"˅@ }vd0PĂNЄnmyi~Ӯ0 $>|olˀt=ad8kepFa>W5{|hQ'VI $$<!EBE%T*] ccKf%Y#D$}V"UKfgj )WBjJD<'jgSjN?&4bAbEGQU ךUHC ;Eu,]lկj=gCIuz"cZ^0!vI}(* *c,(ꂚaM5!Eaqꕆ,E~PN8CF}B#|CAw-oDw-3©b:~F`.>H($sSm\ϧ(3Pp"cf# Q0f =ƣݚFO,xdݭàK1P !tDZz>%NlF(_e,܈ID2UL!TIVf $,LR\r%pS-Eg^t,S+}7ULQT}A45dK:쎎ќƁ!\`n(-0 1ft8L KXEBEapj+Ѵ[J< <#kQ5$-cyь'љŨH0e*E:hFW/QE Rܵ,SlbI9vr\A(Apnb)܃,LAJ7˛$g Œ"a)Z@HL'MH2m7#>TA2T9O(.L܃DŽ6''<B )ezMYa\A%ol6uCKMH0ի03;f,I3T:gNLQj.2=}C쥡m%@.Fd!zh)LDž6^hY2!^S$ź=GedB2;ee Ak@C yE0^)VڑO`ڝTI<-mfLۍdb]1׸H|^$#N/DD(b$[4XOs8qi$$&Dž@]{Bnxs 녘K椴 %d/mm*)!ob q>ADz#Ɉcn23%`b{רr `B k2k,b8&XR@yI8ȸ?șz2%ňLcK̒zI7hCEΆ)#LBdk醑SJZL Uz; 3!$|NS[ہkNU ) m]ەN&G[ ratFHln'@H|Q֨,P1:N"6;cD<0T@Ėg8֑f()흉KdD'~@cMl^\Tg)7Yੂ*O:ItX' ,t,gD4+_7O_^؋9~^MN9 E Ad^dŖ裨%ہehJإX?2{vTs.VJ1'QӨ0p~=%Ur)$4jۣ-/V40y!Tڡbڴߙ^oQ`ć1d2gꌱgt XYxPLVx\j^O$KD';h*]>f /"1mt :n}Zk̎9(=66"`f4U9iGӵϵCQI5UmCKJؐPIzFwcr3)a&H"6j%.EܴMP?V%;0")Þ=oW/t=)El7},BI,m$ۃ$しL8 0<-U.+*b I MW&WqDž FlE0Rr9 FsV&".YV[0!EzZLиCA6^"' =?RiE%&AIfIkreI9445yt;><3Dr0Ju2  zhjZlKrtrIR~04 ݇)ʩӰFy[te4{1cju&%lT^@Rc3VgV5fDzk5@%Otk:]K{7[~DpT\^ 8lӝf3: @qq#cL.X({3vZͪP$Uщmn-^1b"y\q4.ӂ׶ J t"i!J?$0!MFUld 8ܭ l-pKFl;nt(tPOqO1T3H" ~MC7rTБShУG%=1tXDw]jjfI.b<|ԡHRS & 1;#*1:AvbNcIFveR=9YG<$ן{Y |vr2FspL ghh-QRm[%1Q:j~%r* VC9T^v̀r,7=iI n]CTɈىnLNT(Qo!]Bw|+1g 2E{ : Qlj^Wm\>nǹLɶ)$ I¬7{CHBpZ R1-(H1.4@)Ru#cN jW*=zeOH$Jw{tc2Z^ϫXvٛoKavf< ?0xU>Yv3Z>DT;|t70ć ]-qVBF#Qho& @!PT6l-Jj^%,(#>wSFFu4X"ECZY~[|0wun`vWMK* >I.Hj ]!a1>A<֞$OBg@ 6D^6r ĭqrFF9S%1NjBu]Дp;لW ;\eyMiQ5k)4ET:qR̰vLD y zDHqG%FM^ VAXh%SF-)]XOB0Cpl&DSe'Qr1-MCnϸbiAvz4[y`pńuctP$֑S!WEDi"bEߨNnI6b'$!X]M-g_eQ]^4=Kq =aQ'V9Qы K& odc-a7-fk 3a *2Cb N"Pv~ KR;iIu/gC0~gz]5U2dz;o5$+H_loqCP9IsT,n郕t[jl> Ik N^=Ø15CaT윦cP]q\e{j\K'3iQaTSʎ]8ZXƺZUD`TbjXKHYXC,S\t<a}|ed-sɧElKONi"jQ[}fzYI _Q !#4@UA(%hH-SZ^!Ulu;i2Ylܶ]@ F9$ڔWPlTқZEDsTKh*xZ1z6@jHrֻD1flӈ>iIIQI'CvTك'&B nDPUz®*>#\*!djd5tSXO9r`0jDx3;>mCEP7T7rZ r|bUi4 7n*NNjx+M-:5ƒFdԣzRSS 4q;fSqU +KtƤ  @/J [>ec~5+QJ䡸z|p}%#C$a'v%*c6D&~ng$&%Y*.{MO N)v-hAzpI+ȝW+ ^'GBj\#(C82JVhI '4 ׎ӋcLB:v2E=2hRZY~Ɍj*TRH% DSkP$/<02]AUwZene% &5:j+47$bVa~nQYi!i.z|^A lYkBQd AζpFC$ Y\'/hAƾRje283 ۣы(6XK[E-S =dkͳ$"!r%CΑ*"j'%H8T`֌@lwRvbŎpA{L= XIW#VX0?+tқh1l4Z$&l'}L(i>s le)MNoE5r/lrRu{9h q4[үOzɚ*[L~8s (A&JSl"`12P,YSUk\HatQwķT[fw 8ueRd KL aB@!1[qMv'aGqx8+FgᢎD1h֧$A- E]\dXBA\W"UK~ X2+LY8oz!Q%/ն?9It2J&hDբPům!ٜY7MDgFIG4m%iY =ZU1Qdjaּ?gdZX쮎F=UNH:&&³vETb{ tw 6$'B\D=#R̾S8 Cן2v%̜o600Iz=qW8@ނMZGSk/['a[4TA/]HuJn^QRvM-n 7T6MHayb-D4fѰBUhXZnO+Ck9l1[m=I}(9BQBfKɵdS-gG`U@3 3p(Ⱥ Yx~ +98iFsUlW8s9&ku=aJ ˺ ) 2y [5:a68) z"Lj%4 2Ibw Y{B*rO3]?Lg|}"I 2dwdh"nfdїveP @QnȯZ7(34toq(:9!{сȤZLmNGM'Fr q/wsѺG,{1 c e"tưvęh1U݄PÜZuw-H9\_)1 =h a:)8.dUr& ᣎ(u nXWzS3Z e?w4F<%5'Ӫkjp]`͐'V}uNHz5/B) ]F!_ $gs D}*? v'KDc2䅞fϳY"7^@aP# AN$I+AZ .Q6̥HFnD9n ήcKqPҝŸܲL)CF ,H(؉AYAFK-#" ҞsF8;ꀸ_O,JrW eB{%^*Ud;,`(0DfC^f%'0*Է.L{4X67ĵq50ʽnb"&YLoE a$39Avz"-B)&-@J8ʪPF_,݇mAݎ1$#:+7; s]K7\QJ#54Z~*eZ`kKCMSnC3Z&5&ub&#'b/!:I0>N!H۬7QnY,RTM=.N)Jt3|6|%1bXCtӨM844`Y %bixS|5 Fmh.6h+k9 zϨcwñȌv EPU,z? >zdPbA+ijfm*Sdj*F]OKe %9̪Q/od4*%P7tn(0]̄,u.nˆno&ܟi<1ݺB nqF$ e^,1I~'j'>%`^mΨjHCXbҀQe8ZCbvB&>TЩՋSѻBVy{]T 2LHI)^["iWQ^@ ޠϹuNnD(vj"]{i2vʮ02 L&Ę!I=&)ݢDT}8x֡-cۍ :ZVPls5$e!'@hQ:LTN[g= no HodG$ r,`.3KST:Tb ^ƹhq٤cdC A %\A?pbr-K[IdRD3)A4t\ б'ALBŻb_k 1R1g%?C5؈ :ޓ#N3]{,nIVX{FKP6y bfaK)RU>npj?hWp_wDEB**W+xqZ}&K"PH\B"!j\ xf"jD# jrM.^Дq CAÜ_XY -P]a!dʠ=ЇdB_0H(lQTԖ;'O[{(8e*mfľve9Kju\º)Ou9;[j@` UП'1R$12(JcE㇟1 \{;HtK缼Ga;2&,{#q021MJGM$bc>|l5U#f#pB\ixg !g'vӒ&2БdbbtpT򑿮~Mۑ׻[ y~=DF(p^VP Ĥ \rmY #;Xtli*ۑ KY>y èOF}0G09qL_W\FpzM\DG$kC<ȗ8necI#%cIFSnD&spv1sW>l|Xc=qiHgOQ";O mDn#Tf+B v$L8L fE]3&zMлƮчFE׮[LbOQI&G&'H\5&3+ܸl-tN ڵE/.w SmV :*vO@?8Hp:R\8^ Aɾ[T#Fmgx97ZNWEfnL,0 /'2L 6q oḢ2~zM =3LvU P d"t.q[:§НCTo@'(ހ,Αp!8H.*-c;4-0d($ei-rQzkx;q^ٽwjk5Q[C{jw; X} 0[km9o1ʚu"EJ:-KF N=ľSּe&&U.TyMtȃ( %oAӷA=XfkڃE.~r T>uM:EP 4O~]c2zs a )8LYeT,IJ2rDKQ:CD=/}<]Wa ŕpR&|+oV66؀'<{/6Χ-X9(SmcE4iafć:upB)#U"S-ymIJv_H˜W~ Ϩ'Φ8OÁg> \y&}Rs`1< {)럊Ǵ7{9-4߂O b2\s).H&?c F)acffה;im I$2H##@BFU>wߎQc}+C\\YYl{/\U`ՆpA,o}/xp91iz=LR`~ŏV[#h6:%t'* '޾ x:"dHb) ;>dV T\ӯ?rytM$/U(\Gm&ao8IPqR9b#X;1ǀU`%00ދS;isT5PUcqTۗ\Ta -ȋ"(eϗb2 QyU2nʲZwS`;Q(P,<>5tMů{vBg^1i& uyK1IgRj0&4֥ÏYCJcK,Q21Fūe4f*,9jAw&SĥX_k&ESۊ91S'pk1Ճ[lJ] ?xn`%@|~8`[4% aDgUz.@Uc~\$ -Ұ  $+ch>O; [WX:)Ys/W&.}ٛmBy뺄[*E@^Xr49vfTC0 `RϖZU,BΜ*?p5~cumz8dYwAse ̙7_{ClB'go<8Øpahg#m|^Fa$XQOKYbFFϴ?a:0+YI\Ec_g=ab|Iڛ!yTCU7g'}]&D*m<܍7d#wT;Y\]ri.oU^ t7^q jLR\:y\"1A޿=O Bu. vUje XM0+#뽽I ")HPNh= !C"2;D6xl8dr:&$bE:'aZj8zVP幢x[.!jXY-3أ!:&܎/C݃'4vF3|V58q+_ŮC)yCZBF^~G78o3fƌR2QdTҪ%'sN quKL$ ]B IO2Fj#fcQw'٨?` y¡W@6+7  lb@#B ؔ~F1:i S8񾛇Vp/1n5NϤY~/,f׺E[޸S`[:U.V\K[8ݩ||sP=h(\ylV-9p%d}/MMȝ3IޠM,Arxme3\\dP0m0plHJ0b&9)mks{)q RHfW .N=J`LfbOspeF\ո|]\Y>Ch lbs: Ɏ )aC֑Sx9zcvPndxWBg[S?vzEu$zs mCajXރ|粟ET?}wg_˞x!h=Z] j!)j%`m1Ǩp'`O{6CD2M]K):U}Dp2-DFh)hG5AN;Dݥc> чۍA@z_b)PweZ=mI#Pl7L '&Snngn2׿B#1:\A)9]K?U؞`&1P k tIL*Bi+zލ(vԠ'}82mkkh`~z +^_#7a>% z}tQ G5}L{26A%4YE[cbW^ U&m|YT12Pp͏GNVUմSڏ(<ɛ]8}|MJ*FXL?9ݬ;݄zZJq.b#=?/HO"-沕j9un ưi+fXlG=9I2MwJd_=)ֹܫ~ry̫>kuHr K.Z̫Mث7|/Jh p1 4{Xez;9.}Z•8ۻpw8ڽuwf\}:~o)s|-'ґceEkXfb<`/ˋd }[}4NlP*hN\5S S}T Ǚ;>Wt{X?:ǴX`RZw"&*" yG?EuGn\vOcu*67{0gsGCsLJ[bU}QѴpcGr: ,<fwbLh`[1pR &QDۖԳujn5׾ŪQRuq 9/eY3b钒c}*V+?o|C>h[4l !2l ekhv_łXw?Q,Ϝmڛ>M%H)PYL5bwo8Dٷ "β)NUza;~>-}*lݪny 4cCwjIWdc_uOdqhf1?=[>TVĜ,AHU*lvzԤef߫ S?g|<7nOGL?q]-x*~/όltQEsW̍}ɾ2v4yyOdmo{xJKyp8Bs\{ql}G2ރOęO%ۑ ]mמ5HjXMhbhhR&pN+ g|ܒo lņU8Xו }Au$8&mP4D馸l1qݏ[nc%xk^+nXn%M>>tpt,+an7;fe+%d~` !0.lќ; bzŵU,@ns;LgL%=K6j3'=g>{_piWgqX4*ViC4]%ZNq S|: ?|UѮTag8{5S1[H50˖DsmqMo18oTǘN0k^t6* nG_8 /7!? xj͸/1CkѴn=wHLAm;}Ս/}&ǪҕMn xEGjӕ&&AL8p5p-Q,4ףuG0l&@--cZ)v^"f9PM9WgnWN|ǫ_ŇD3ᯇ$ :dSSc+D"Mst!ugo26|:FpwgO<a+m{!\/! <{[|3y6wb `>o 2i B5zbee.CfBT9r o͜Ή@+$-7°!ɵY'nH _`,o_OH [gą3ɴ9%rڶ/4Tغ}h%1܈y5Ão `9ESu=5j{w5?@,C9\4ߊS8Z{,wq) F&Iӳ- F0I_d|3>4 PQ[x=ͼr*e삠9u[}+ a^Lf LWCLfLZ~#!4Q, >3*O<- 2lǚSk@_e!Slx>~ۀ1/=CA8{^FGY[X`co.^99lc8 6bl/<9dYc)D]N0gATm $}hC?{8aƱWd%9,nUQ _5^;tIG0vo{9/x%®hxv# Cb>EsqaؘXb]{k1h Ja㫾[Пl/|fT i &bӕYK(ud|C^R{͛=8~|YEMsDYR+cS̫cc`]*Z]3K/3vXhэi!Xb{\rݐ`RZ۰xnMw+X/3876)(D]`Rc6M1֨:a׾u"S:s<7d7__b}[^/A-nèVZJk$ #~)`힌OیA\wExsN<nov8X?0H`XmeH%VKp`qXRiCC) y1ӟ~8z/\ wC.~TWԴ$.us]ۅ/J;v ?7Z,wt Jt fCHUccz]Qď~s-=qG٬ϹZ+^<)t#D^{ Kejȓ}@˯kW?j_PU4QЮ 0{/W2Fu>f|ؾ؇'~9Ξ8x//Pw!ci bթҋ1r8w3gZW$T9tx⭃2BkHI2^n,~_2]DXB>^ *!==nix%{?Vnr=~ ?^l/؞רH,&5f5VWfb6b2it69* O viP39ߓLz]/֤~A5o3.|{XZ>"XN/W !G3N@՞X`=_`kQC2lze2TVwb:3:SA*`=nit8VxL8 gEMeӈe]Qqx_qǗ\N `"lƎKѴ9qn j}}Q9_͓Gq|\LЬX_1]Y ue bRX߷Udg`%8e_?hhz WNxFTiTn1OAqNѰ[X9t /xXUȼ{ IDATzw4'bfO?qG?^j+X_1)&طB=AVwc~vӤ_tfNY4y}iz+!$b๖j*0L`/+:X`!>w98Nbi'1a>y)VvBzjuW+{bܦ9fkd]4TDg'XjATe!R& G˹'Q:#, )"[{N^uD~Yys1=lfu!CH5 !a&U}pH즿fcOJsz͔ȼwj`n觍ye|{s^CwwF%4l[ {mC+xSkvƲ>e04'qj~̮"l:7D ^ce}*VVR떴UԳK*rR/2뵻Ab;>h7taѭag;eJ#nz@99l{4H!o];7RǢ=$I9qcfWvnoۣ,}ι[*y#fq+Yq\Q cԉ:NVAY0’nhnGU׻{<~{To{.֭sٿ~ 83S u1*JCIQBwbDDt[eަ"onBGzBEvwvY52|!イK+2FGpM>ĉjG\*'%CcȎ2Eh;6싰p kPh$FwVX[D!ʌ16CT{iHYjuEQVƵNIxJ0y850XT*'S=:=r`)C [[BrU|!pdK$$F] 1.L|#.`Dc:Bf1ϱbGr_DVqD^F eF'ke|lBjHSHSi uAn-Pز'_R )ju } jN(.?o _Ma/rth^=AJJZQ,نhl g=9?" i^#1Z](*]a] cڡ/2k$6MŚ>qWE-W/kC~5:h$_gy뾛=1߹Uae\# is9. cG-E s.(WX닀 FZhu:e !"]@PSTf);DV"HWuQAkJQfI_VbF?E霡Zb),ˑF-"[>QTqE@z GZhˀhʵʁQ(I06=JqF#=.N|%%$ (gzrbePe#ZSOI^wk̔F\$/V˻Loaa>& G]@OԛDr֎@@. FʀQT. (N06CĦ42U;ZllK5qj/IՂ(,O5-`mM7Q l^rB ћ;!<02zn%j[c$\aa#Xd~@t;e@ '\weFiIS;=]G7)<"ˁ~MZFYY iֶwKdsiߜWYGg9|C{Gt-h0h&p}44\z ii'n _cBK:8ˆK l{Ǎ34-v@cF'1Xˀຨ]D3`k|h'0QAHA58:^i`@-pU%N MR7L}$9b9[q_}\v> ;{ q" <~&H Qn-B2 IĔ32Y.҆C:WO)o,9YvQ4om|>$G $CVN L|aC? p)Wy QHåE䣱vG|" ܅2 Q!$zh;e@_cO##8Dh .5)8.r1:V0&ݑ,krKQ./  +jZNJMc㻷UnW/pŠYg`P;-iƨe8c 2 uWCM(ћA{t D2SRU8>`&baE|[-ox| pַ;{{ᗝP@@;k#cO}6+XD*Ctp@w'. d s#C#k\s&Q,2絒dF$D'$Oۘ6l297r\}_f{@.2P4RG$4Vf0`#cH=.ˊ1$E mcA5Dc|zXzD7AkK9tWSpoKLa?$ɬX7֚e!7iZ&=e]+^x>IQ#.^1:>@f3HsxI db".T 8163ZD1§rY[ı認꿗1X3LJLJ$VV#2,5C &U@! ,>x-{ʣ"i<2ϧʑAQ##r6 ߿+}yJv]@T5A#b|STm ![jǀDŐ.*<˯X踇Y ^`sF#~^r9U*e_a}ws6h+HDVHLH@bUlf┳_]SE@pN: -#~@EƠ" N!i% iKu! *)VA@S6'E) &H 7ťu$on,&UQF|+ܭ.B3!> V1`yzQP[-zgĶдD/+T'#=pDp> lV< m I }=MiG,I/;ir(^s;y_NmkY9&. sR̔Mtu`mXii,ߊV nabbQ)%Xe US;|tW\BLQdy#ľR f긴RRKo(&B z&D(.XA)E9acϷ4'dyk Y: : {@@8"0>=Cpd֣HP R_ ]J僒1uO?'?طԴl<4&ZGsCO1(>z.犤_l+3HkX[!lf9>4Gy* F[wIV\A}&f8XBy'o~ /ۮ ﷰ8P6d_%͊$8 ¯}4XGS@q8(1";^\+"8cL]bUvQ;F"m!t@:mO[\3_TEO\M,OsOhvEXNposGvz,ngbV^\ 90x征LlJg{e"\I^pd.cpt>RLD@q$ݨ)>:W$!0`|ƻ(&{hw[<(ID@kUˑw>q;x!js.Mw{,KK>>r5uV`fx#]o]X]w݂xf @G{?H V3 OΙϿ 4Ӕ8G^  'G151oqOO`bfӧZO=e5bP6 /Ks=/w{SQ L+!ZN}ܓs˥aNٵ$@ >baVT}[cn>6HriGǐ-,{:3{7RYܑ~3~)j ZX0N 3 ԋԋw3#?V <#kX:8O㩛>?/k cY @ aMOCɟ=^xzNpJ()6]K-r]+PePa:$Sd)NaQOA^5U*FDsX*);lqw`+3|=m령g@އKӬ/YS e .JAoݴ{Gecc_w}LETPCg*c%Vgf=ǚ2oԾ_cbqDQ`!?ڠ,Q|eDpmc8s囵t|YgY( ˦#Fp7ľR6!.~V?r+n';'I gwc 8TJFXiAݍpgs'_F_2u!H(yEyS͏"8]`A=E1M^BSVhuRD>|Bw|vx!.yVzg(.Cu "t.3-AXbnR+743&>*|vT[4cyc'l}ApV٦L$ ̗Ofo+x `K|kb v1X7āGx`C_CgX_is\B$=JVcCL+'xc{E`S4P|TY+:DT 8Dty42ig$hTv'5D0Xb O#Wa juL>]7͸r<[ަVw] dž 1p3_4O?:Zگ)%cdz00mB߉m9bj<7qh3" vPUHWc_6QE.,-<ut拘叨#\4,W9*ڶh<c2g gAꖗ-T=+I9w>fm>]za )LS=gjX dpnUW\JTWfyPûidhV{)% ]sxMO{"G؋Jj>c$Tx.8RX;_"?X`iUhRx$+}[ϨJ__w3TO9!n,eڄ *ք:^4_!k8:6h6yE-9 Ӟߋً^-X4vYRc=Ϩ \ws1\lHD2vLBTc={7@ H aA',_qKYO6%fɠ^'h$'2/ij1 ~QQx4 8 a!XQCQY|:CK?8J\&|-B~'&#os17( @f3!$IJ*(+D白ȫ# yL]ya@?(~=xb=ؼzq,~a9!{x!UGo}Uv_(k] R^mUT G-r#`'k*md5 0[ĬcSOy<`L?3P@TmhONl/o[9.:k0"wD@,+G;oB.iP@T\W`E0k.|j+#\&[Wy4D3yf.Mnq<` y#y>[@io,\ڎmvPGђ +聣:^7IdV%Klwy(:a=0넒/ RHnH8{ :n= I/rS>h7 <HR[ "MC_(tӬhiI2/]f*"ݫA=n@{򕶮٥<arv^# 4mUOZ*ߟq=pٻ?UZ~[OC2lFDx+|J5Ok N')u 855tBdNr3:Ĺ鍏 ȁ8d>{?s\2K;.݂6@5~mm}-יŹ%|m;tLK5^u-z[Sٓ#\AgFYxՏSZbU [ƹ7⌛?T46}/g "x@< _H/E׽OkWeEW p7ySMj%BФ6U "%䀌UyfoVs0]M&0uCw68皗d΁lHW|? XIA?1dm f⩷߀dIrG9i\_M+;{Ș[ϷbȂ>^G&ׄ[Ǐp#qxD3$R+/E$UuY Sy[2}|,( ;མf.SxHQL;E7?]-?V 2<>\,KHW4a8 .̾Zpҩ~DɁk% Qa!xZlߎ7_ai]=k U5@;4Oz~lh]Naqu9t&'t&t&ct& Xcp _ʰoK ;?\}U"O:3Jd*AZۉ&7O GZΑ``D&Hb_ìwJlJ،։csg)hqùsif4'9V_+F IDATWapoƐȉWgc'VyK#3i>4]jU8>)TPAy͕g_s/tayD W cp [8{=XYbW2kuy鴼t}3{{:_3nMxdfNV32dCY7>}Nl# (<[7EH7'6y*yr-;6QbscNhKlTqBTʮ3׼ߩ5VT*$ B_ S9)Dt< 5s`|\K%xJzrx y7w[#D~ˑ_Ƌq#K8DRTG`]w8f#)tZiިpXSc"Fsϰ V9`v~~+؟A (`hey92k88iFn;(dݘ| *jjZL̢-pxn1skZd1քњqĞ:yZ 힫f3xLK$5$R,ଞh6ٙhYE6_9l9ڢ:>^q Bbff ͒@%Ƞao$G^AYMu_h ՁJ8Ϭ'CƬ\xI6V&FJHĉWK4?U&tbrRh!#xqByDMpT40l 6?np3U&Y\ :)r{Mdkxx?S8r-[?-A]=3]ΎlN# _e 3EUX^O 4bEe8 ><r]cDIfxrrI3k`_΢ ")d"C$5%!C/Bt>DذЀ ^`tj~3iq/FCt416YG 8LU*,VJ#,̒?E fljhL fÃ#3}\4b~oA?B Ty`[DU !(7:n}ld!IcrC\*kLe ˞* Y#qd5ewYURH6`Ҡ5~cFBV@ ^Skn(M!7 x|zIee]] x:Y\@L Bd\0 术 `a ~.B$n2ͷFUb$9>ಋWP~MxGծPaઽܕ?o<hg3e]B^j sk ”yu-d!%-V]4c˝ؘkKh.(:'Y/3k8|3*kzͺtV0"~p5ajSp`IAjaJrХ$B)n5Xed*OԳv{垥0gQ4ŝ6@Na.oV#w)XD@^TˠFl=ZOd{ʦ֠@!PSn%E\<)>&zvLe V!FZ5lɫuJppBjS(.^IwfTO>,uW&s;7U1]<`Du7=ot B٘-ϪWT#zo{AڄV"r@Rx@!"oe@&@9^kU4dv5D2*QbІZ *aD0Y#C&QA,OQ>/㺦 h8+Iv|&J.4Ɉ*Rm`}ްVAQϨ?#@{qy]@ꋭRy=sk\c8uז:z(` F O^FGlyƾ3K`{Ti]c^KZC8[2%Kzq]90v}(dpfӳx$3 =dBtF ^$0[2,@!ŠFZZ27  W1(b:9u S)^-o i Դ7SNry)DR 3ە͑F&4Ylהs5dQ27V*zؿl1%%%յaI\uWJ)l5_-V7S )3oufD2,hZ o$]Vaye), B,gx; 4r@=V+7\=>xKE=܁ə&5R|ѻ ڵ ?0667?29 =IENDB`bareos-Release-14.2.6/src/images/save.png000066400000000000000000000022431263011562700201410ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<5IDATX͏TE{n@FM4DHČL\.M\kXÎč΂htA\ =`PQ` ^` QVR{:ԩz~6>>]vN5ػ」;v<:̗7XSڠkg|p?0x.ory #ӟd}k@E@xp,#˲m00aP|#%"+Օs΃* ,I Iw:琷Ղv+m(r8 㯼IkFؽ{k놮ZVmQg5 ,# /#&|#!Я'aa%% 4M:ólc V_)Fara-р: TIO4/!g iXvj#wPE x:Tx3x$wh6h߱R^DM_ 8ňKvRPZ0}@Ű&WU.2p}Ʉ-Jsf+7QW?תd~')Ü wl 55Y1{X0+WVU!ѐS,-޸Wj'WڣU<_o|w__sl}5ځ?MKFIENDB`bareos-Release-14.2.6/src/images/server.png000066400000000000000000000050721263011562700205140ustar00rootroot00000000000000PNG  IHDR00W pHYs  gAMA|Q cHRMz%u0`:o_F IDATxb?P0@ y 9S@Z00 --hb$6tupR@Cia I AVׯ?3 ?}c;|Z.@C sRATR&" %- )t$f4 ?{ 3{ۏ ?{{ X;aʔ x zmm {f9P3^>o>2| yqB yh~~n.REY iIY }3|(3CQl-6fe`x/tOp (Pcdy GY `bG8y!@<J2耋p`@X2 009x )FKzA Ё|@xD<Q?`hKx1pq1p f"Q @? = 'O>1{X"8/  %%{@DUd/^|ƛJwody`p0112> &"2\r42"@ s(C~go&`e+9Oь   _2|)%ėBDT) d$//q?(qs/''6Xl'F_  1P[OB`B? E$y"# 12| ,03DT&{ËLp(A0c6Eoiz DIV;!&p q> <t܁x2*(&@ Y=1xSk9 +GdD0dA?QCϟDbdt:/o#? "b| F 5 (H|ܐ25@Õ7n\@gٯY99q1Xh2i>>pMoCӧgOaq @ԜXG.5TePP``ee{4GOp׷gϞ_ƶ><|4<@Ԟ5dz&.!L,L :j zj b p o_ |Cv``eO@< {\@|bÆCv6A@'(31iH3ܺ?޾}׮YPG~EAr8x@:}_Nxp??>?`bbf{@CAI1 ;ba><ꠧ.5@w@ S>CChP#7I QѮ'fff@~_6 XH"#5G!sAڟB5B Xp0F2 fb@g`gH|1Q bR AchjԱtʙ9g0mg}kn_{1b*Qn1 ESCWp޺ܰˮ#*0 "`Ś .j*8(LN7ȋYa|1;QcPaOȋjZ/T R=JEUUDo=~>ƫk{Re 4sq*gj R[ZD8\;18a {vM.N pA "J;əku88y蛛IX[c6~-yLРadd*A)J-huRڝ EDQwkb06ǞNalq$kA2kXKG```cctԳ{ v A6n\A#T:64<$YG#cc㎱;Ȇ[cμsa1lZ RY'U0nL[-43yY9r*Vc<9g|[_YGq~R AP Q4iɝǸ"tւu*wPQN>L 'cDA$ ! GVPU<-Xk9޺`mv9s|?_(8V|Z cW?1ØPxux}"J#XSĄNTQ99a .V8gV?cF [ruuPTP4 {GKG#a>?;5'e6]6G[cr15EC (@fB쿫b͚0\y~|G}.Cc |c*bB*k֌\R"Tq2<7?GM\zM2 rȱ֑eYkU{OMOO={מ\qLuqMzxD"7ј/"I?9c̠jwy޽{1i|jZ*QQA E~m/ʉy7F5~4U5?$K=)IENDB`bareos-Release-14.2.6/src/images/status-console.svg000066400000000000000000000630301263011562700222020ustar00rootroot00000000000000 image/svg+xml Terminal 2005-10-15 Andreas Nilsson terminal emulator term command line Jakub Steiner bareos-Release-14.2.6/src/images/status.png000066400000000000000000000016701263011562700205310ustar00rootroot00000000000000PNG  IHDR szzgAMA7tEXtSoftwareAdobe ImageReadyqe<JIDATxb?@bWLeÿ? e#A?,?H_=`q<\ΧZGLDـ5o(dl@s-W gR8TMAFo0 DfDA?!|8H- @a o#`" _Hni`H_$ 4!0 PQ x @X ,9r#B⠿"ـ Dп!x`a Bgkcp^YP("#'6C1 \A X# uuuDʠ9ĂT-hkEQ@آ Oi9PDĂLB BIĤ!55X|JDR r,ǖ4n9rFJH@`mm$Bc: Xc0}P^^5$ d@x61 85  dCurwww Z@>/**'+$E@aS[Y1 image/svg+xml System Monitor 2005-10-10 Andreas Nilsson system monitor performance Jakub Steiner bareos-Release-14.2.6/src/images/system-file-manager.png000066400000000000000000000010341263011562700230510ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8=kQ33;;q? 6ZXX(쵰 )#,m$MXIUwp?f"f_)Ͻ}sI8kHϟ||ɅIQvw;۴gO6ݿ{e`Ξ){Z[; .\|{㋨5}Jkո,W3ђtFe¥w_JVZ-#,1;uR!BZNUk1Z j\A vsrVTrC image/svg+xml File Manager Jakub Steiner http://jimmac.musichall.cz file manager copy move filesystem bareos-Release-14.2.6/src/images/unchecked.png000066400000000000000000000007151263011562700211360ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<_IDAT8K0j#] >Хu>vU"MM0aD4t)%irtp8eٝ.I0i6dYf+BPլx\R.IzNTURz=+</Rf}<ϣnBXz~HT*өMk^Vw맀_x<~EQd{_8\W uJ)("svW1)%|coIENDB`bareos-Release-14.2.6/src/images/unchecked.svg000066400000000000000000000065061263011562700211550ustar00rootroot00000000000000 image/svg+xml bareos-Release-14.2.6/src/images/undo.png000066400000000000000000000033501263011562700201500ustar00rootroot00000000000000PNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<zIDATXW LTWjMii. (* ("0nl#BqAvq (Z Z`hԪZ. ?R)6id23s9G@_B6efR4Xfof>~ޓ%D3ɛ~ җÜ{,|9`ۡ+˯<)vlo`1]#Ŗ$M47YPv7 I$L=)fK9"urIɪIp ,PVlL d {=]Nc] `~6VVpNE>|b#,<*<fs[G8&qP_` ̥ENw-q5&]SM#p~:|/T$o+^^]Z 'Ēu$ c$Em"l t{*TՄQ{,{.OgP ^kLkF*E,#K1z^rϘ i75S`IY4b`W)@U3#A_ӉW;ZӮN6ڱJ4$}TcU:Բ -gmb(X Ԋ-Z/%A+i Ha9@1 ZYGyv9Ec<2O>Lq|ȤO9kJ 0u電e陹ȹE\Wno;nw$@ ,i˞pߡI !< s3Y^!)wHS1ZEBh긛׸ Vˀ+xz붔˄r ]-)p+>oc_Ukhڲ dXtqW+0Xܮ\`N(;p\T]BRbUJfmBu*+-S;QoD)3!D놫UdXΤ8iԚ;o:?mعrMSUX}Փn);<眺Q#J~Xu ❆K` f+gz$gO>,3AY'$yn`$1h Eh* 0/rZTMHܖnrٝlvLOxyӳFVpF Rn<6 ?YU p*ҭDW^H\H NJ1LU8fk wT ֊ٿr &PMMy%ɣ>Ʌ~/(Dq\Ale\ܵlRN>=dQ<}`9qEJ*4βZ#Lt$7k_ 1*Wyk&&FlC&jꖋDҒx%I&Əm_Q$IENDB`bareos-Release-14.2.6/src/images/unmark.png000066400000000000000000000006031263011562700204760ustar00rootroot00000000000000PNG  IHDRĴl;gAMA a pHYs ,tIME -:bKGD#fZ~IDAT8c`ր,n(m  ;u ΢ Cg`HFNJfnR `&n frJO.Qn0HrD7q]/6.?ݻ,` WܲedaooU,`b^qIO ?e`Qf`SE`qu0}#YeR;3C43u4R4>% 6 LCB8t1IENDB`bareos-Release-14.2.6/src/images/up.png000066400000000000000000000030531263011562700176270ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs ,tIMErIDATxŗ]l\G3 IVIH E2B*JHTC*xxHS UD"AV"5 nR<8u$^۱{ wb;UHW3g9g|'oj6>^2 !^!lK:NW @/ >^V\BɌf!5Jĺ_C_)f^i^dz, qqleE X ?u8jnIS V #,Ӣ-A{[׆n #cg-aF~oHSvM6mB:J8.`i996tn]9%$F+Ͽxi< Ÿr=0M$&NXm9Nͷ˦\y"Ae 72{b˕w1<߻&25}~!E{ВWo>ÖgvoG=8J_o (HC|r ޵}՚8X ~~OpV!~kmXՔK"[Soiw2;3aOt}tSS/<{Glލe[ XnòC?{M%F.4ޗwaYv6^s.1 n=i^K(?Ԕv6]?Z89t6c$ը@Cū g^|rMkq_,wõy.n(HV|TIEIw~X-e᭗j} 粐|&@nP*1yXo=MzZ4N.yLN'~rWR7%@Ц-'e5RD% ,B:А1f%?Z"07xd&id1p+p[y>a{ׅ1q!dRDQ1ъqU=?zӯؘN.&7m/R_ZFZ1}Եa3+f@(@nq6dba-B-2c*\h8{r7ݜMײLgA-HGnr\IENDB`bareos-Release-14.2.6/src/images/utilities-terminal.png000066400000000000000000000013331263011562700230260ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<mIDAT8W+2H&j01$MlTF0Dq:M0 h1hcg#  A D;w}SGI!v9gsXkm13Osg>οN b faf>oܸpՂ1 ȀGD`iU|y [_Y43wo鮝@Am𚪁*1,;>7G{3Zxu`ZL)6.6SH<FS?ҶҶXAM aߥ )'矑RB1_JADsCO0u2z ZcAJ 6a.喜3O?#|u['s^7M2MШO1r`@ؑ\v?rRBě!c# U[nr,^71S$B />gϖr)Rn15U1JniJ38̄bEbU%q!!"8^Iugijr_RlycOv4lj Bf2tM{Wm?طyCy tNݙ{s]u/ e@kfu B.DIENDB`bareos-Release-14.2.6/src/images/utilities-terminal.svg000066400000000000000000000513401263011562700230440ustar00rootroot00000000000000 image/svg+xml Terminal 2005-10-15 Andreas Nilsson terminal emulator term command line Jakub Steiner bareos-Release-14.2.6/src/images/view-refresh.png000066400000000000000000000067341263011562700216220ustar00rootroot00000000000000PNG  IHDR00WsBIT|dtEXtSoftwarewww.inkscape.org< nIDAThYipTוνoE-ABqBŃ8q*8cLxPSSrjR3MdbǙx @~=󣻥V%KL̩:^_wĎ"w' $" Ju*KE/~fBOn.&W> 4'0ȭ, Fdo0 X;4lR;Sb:]si;Xthrs՚7_WmaHkYf$m}8|RtgHvrDmZNVdT|)Xf>Ce5ỚKB~0*WZJ14J:/?ׂјfݔ벱yLyZO@ETd%?yC DFzyOAښŋ\JdI)4MYv*_ .-}zÐO7*Ds`}~+nGMS?Zϧjh5Mxg`h^8ד@UC@d$P-u]psv!%pLN(,&~ɺ늃ݻ|~?퍙4 8Z7]le'M h=ͅAat3DL>?edHj!axt#\w5 h}_]Ff13pl\eL@S˖K`L19ND(mAvCA^N9'*c%HPpɢ@tf!fotO]=w 6*hZ6"}/l0ڻH9;$U%> &Ƈ&><cnu?2XB> e,9RRd^ݡrLzZ(G{z;͑(|f..4o/B59W> !+;S~K+?yip5i'Ōw3>xvp@e-Z=oo|𹩂$lw^?\2Fm]/oR7P}M ]'og4ZǖT6jfUr]:,Cr /~֬h]W-NGNzWp3"׼vމmOm=lҺ7,FQe]WSUfi`F&=f(aY)ē) [Iˊ_8?r@{;\p7=l|揬;W] f R5 JATJJ\L~õScX{'y@GSQT\P/[UEeXg{N}|:5p54w> y7$&8 :{% 衾BFUe1t,"3G}"yDztŇ-?Y-G$6!k\c%/Hq ೚P>,}n@O` XUL//ioIENDB`bareos-Release-14.2.6/src/images/view-refresh.svg000066400000000000000000000406771263011562700216410ustar00rootroot00000000000000 image/svg+xml Jakub Steiner http://jimmac.musichall.cz View Refresh reload refresh view bareos-Release-14.2.6/src/images/weather-severe-alert.png000066400000000000000000000014171263011562700232400ustar00rootroot00000000000000PNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8;LSq>x>b|@*$*jdM5Qd$ј12Ƞ&>ߠ -An !#LߗΑIX$,^;:k0ZZZDϛԳO/ml8 (.LIJdtf|`ppWoDc5m'R 2ScgsU3>ahh;:(?º߿5|%>8O\2UU;\N9^Y)P(8k>|`#45PUeל"_`vkj0$Ԕ0x^C{lbѡ#22Y򑣇`pG UQ11r͒GݬضUk&(4]CJUv(B!&"\)63Ae2Mb&".W=_Ξ;^`/8e[Ļn{]*|q,"ujkms󝆛7ݷz<߽[<ؼiڮ̈L&}4ןneR 0 pXٙLg?$uA>ߪVW3EC&/` bz:|]gg9$M\bQP* Q,.o1.IENDB`bareos-Release-14.2.6/src/images/weather-severe-alert.svg000066400000000000000000005231401263011562700232550ustar00rootroot00000000000000 image/svg+xml weather-severe-alert January 2006 Ryan Collier (pseudo) http://www.tango-project.org http://www.pseudocode.org weather applet notify bareos-Release-14.2.6/src/images/zoom.png000066400000000000000000000021131263011562700201630ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs  ~tIME 'IDATxڵKg߷:nU+C/Z zp(e#Q=^R07B=VОDҚ JRHXZugfg^ܩmb?xxx{|ud*ˍX;Ӡ8V*++3'胷o>RJ,u]r,..8r]]ӵ_57u||Bajjj(--Eضi|ϟDჃk lǏljD"TUUǩ& ô`|Ƚ{~<===P(uibbp8L4p8L0$D"B-S ֖r]gllr(xMR ۶q۶޽köm`~~qPJa&mS(E)uxm<[YZZ4M eQ(|u]\mibeaYr-@Jd2dY c/E@>Ų, `ggM"iڷ=hM>!Wlmm-7MoRʭ>~(e_|>333:@UẮ&Xܔ>??g{{i^~yKubBgRʞEcc#z/_,Og=?$/@2DeCO#m@^6$n>'t0/˖˧7MMM)] 8KH1+3NۉD¾kU1 !/Ԏ^7IENDB`bareos-Release-14.2.6/src/include/000077500000000000000000000000001263011562700166525ustar00rootroot00000000000000bareos-Release-14.2.6/src/include/baconfig.h000066400000000000000000000607521263011562700206050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * General header file configurations that apply to * all daemons. System dependent stuff goes here. * */ #ifndef _BACONFIG_H #define _BACONFIG_H 1 /* Bareos common configuration defines */ #undef TRUE #undef FALSE #define TRUE 1 #define FALSE 0 #ifdef HAVE_TLS #define have_tls 1 #else #define have_tls 0 #endif #ifndef ETIME #define ETIME ETIMEDOUT #endif #ifdef HAVE_IOCTL_ULINT_REQUEST #define ioctl_req_t unsigned long int #else #define ioctl_req_t int #endif #define MANUAL_AUTH_URL "http://doc.bareos.org/master/html/bareos-manual-main-reference.html#AuthorizationErrors" #ifdef PROTOTYPES # define __PROTO(p) p #else # define __PROTO(p) () #endif #ifdef DEBUG /* * In DEBUG mode an assert that is triggered generates a segmentation * fault so we can capture the debug info using btraceback. */ #define ASSERT(x) if (!(x)) { \ char *fatal = NULL; \ Emsg1(M_ERROR, 0, _("Failed ASSERT: %s\n"), #x); \ Pmsg1(000, _("Failed ASSERT: %s\n"), #x); \ fatal[0] = 0; } #define ASSERT2(x,y) if (!(x)) { \ assert_msg = y; \ Emsg1(M_ERROR, 0, _("Failed ASSERT: %s\n"), #x); \ Pmsg1(000, _("Failed ASSERT: %s\n"), #x); \ char *fatal = NULL; \ fatal[0] = 0; } #else #define ASSERT(x) #define ASSERT2(x, y) #endif /* * Allow printing of NULL pointers */ #define NPRT(x) (x)?(x):_("*None*") #define NPRTB(x) (x)?(x):"" #if defined(HAVE_WIN32) /* * Reduce compiler warnings from Windows vss code */ #define uuid(x) void InitWinAPIWrapper(); #define OSDependentInit() InitWinAPIWrapper() #define sbrk(x) 0 #define clear_thread_id(x) memset(&(x), 0, sizeof(x)) #if defined(BUILDING_DLL) #define DLL_IMP_EXP _declspec(dllexport) #define CATS_IMP_EXP _declspec(dllexport) #define SD_IMP_EXP _declspec(dllexport) #elif defined(USING_DLL) #define DLL_IMP_EXP _declspec(dllimport) #define CATS_IMP_EXP _declspec(dllimport) #define SD_IMP_EXP _declspec(dllimport) #else #define DLL_IMP_EXP #define CATS_IMP_EXP #define SD_IMP_EXP #endif #else /* HAVE_WIN32 */ #define clear_thread_id(x) x = 0 #define DLL_IMP_EXP #define CATS_IMP_EXP #define SD_IMP_EXP #define OSDependentInit() #endif /* HAVE_WIN32 */ #ifdef ENABLE_NLS #include #include #ifndef _ #define _(s) gettext((s)) #endif /* _ */ #ifndef N_ #define N_(s) (s) #endif /* N_ */ #else /* !ENABLE_NLS */ #undef _ #undef N_ #undef textdomain #undef bindtextdomain #undef setlocale #ifndef _ #define _(s) (s) #endif #ifndef N_ #define N_(s) (s) #endif #ifndef textdomain #define textdomain(d) #endif #ifndef bindtextdomain #define bindtextdomain(p, d) #endif #ifndef setlocale #define setlocale(p, d) #endif #endif /* ENABLE_NLS */ /* Use the following for strings not to be translated */ #define NT_(s) (s) /* Maximum length to edit time/date */ #define MAX_TIME_LENGTH 50 /* Maximum Name length including EOS */ #define MAX_NAME_LENGTH 128 /* Maximum escaped Name lenght including EOS 2*MAX_NAME_LENGTH+1 */ #define MAX_ESCAPE_NAME_LENGTH 257 /* Maximume number of user entered command args */ #define MAX_CMD_ARGS 30 /* All tape operations MUST be a multiple of this */ #define TAPE_BSIZE 1024 /* Maximum length of a hostname */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif /* Default length of passphrases used */ #define DEFAULT_PASSPHRASE_LENGTH 32 #ifdef DEV_BSIZE #define B_DEV_BSIZE DEV_BSIZE #endif #if !defined(B_DEV_BSIZE) & defined(BSIZE) #define B_DEV_BSIZE BSIZE #endif #ifndef B_DEV_BSIZE #define B_DEV_BSIZE 512 #endif /** * Set to time limit for other end to respond to * authentication. Normally 10 minutes is *way* * more than enough. The idea is to keep the Director * from hanging because there is a dead connection on * the other end. */ #define AUTH_TIMEOUT 60 * 10 /* * Default network buffer size */ #define DEFAULT_NETWORK_BUFFER_SIZE (64 * 1024) /** * Tape label types -- stored in catalog */ #define B_BAREOS_LABEL 0 #define B_ANSI_LABEL 1 #define B_IBM_LABEL 2 /** * Actions on purge (bit mask) */ #define ON_PURGE_NONE 0 #define ON_PURGE_TRUNCATE 1 /* Size of File Address stored in STREAM_SPARSE_DATA. Do NOT change! */ #define OFFSET_FADDR_SIZE (sizeof(uint64_t)) /* Size of crypto length stored at head of crypto buffer. Do NOT change! */ #define CRYPTO_LEN_SIZE ((int)sizeof(uint32_t)) /** * This is for dumb compilers/libraries like Solaris. Linux GCC * does it correctly, so it might be worthwhile * to remove the isascii(c) with ifdefs on such * "smart" systems. */ #define B_ISSPACE(c) (isascii((int)(c)) && isspace((int)(c))) #define B_ISALPHA(c) (isascii((int)(c)) && isalpha((int)(c))) #define B_ISUPPER(c) (isascii((int)(c)) && isupper((int)(c))) #define B_ISDIGIT(c) (isascii((int)(c)) && isdigit((int)(c))) /** For multiplying by 10 with shift and addition */ #define B_TIMES10(d) ((d<<3)+(d<<1)) typedef void (HANDLER)(); typedef int (INTHANDLER)(); #ifdef SETPGRP_VOID # define SETPGRP_ARGS(x, y) /* No arguments */ #else # define SETPGRP_ARGS(x, y) (x, y) #endif #ifndef S_ISLNK #define S_ISLNK(m) (((m) & S_IFM) == S_IFLNK) #endif /** Added by KES to deal with Win32 systems */ #ifndef S_ISWIN32 #define S_ISWIN32 020000 #endif #ifndef INADDR_NONE #define INADDR_NONE ((unsigned long) -1) #endif #ifdef TIME_WITH_SYS_TIME #include #include #else #ifdef HAVE_SYS_TIME_H #include #else #include #endif #endif #ifndef O_BINARY #define O_BINARY 0 #endif #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif #ifndef MODE_RW #define MODE_RW 0666 #endif #if defined(HAVE_WIN32) typedef int64_t boffset_t; #define caddr_t char * #else typedef off_t boffset_t; #endif /* These probably should be subroutines */ #define Pw(x) \ do { int errstat; if ((errstat=rwl_writelock(&(x)))) \ e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock lock failure. ERR=%s\n",\ strerror(errstat)); \ } while(0) #define Vw(x) \ do { int errstat; if ((errstat=rwl_writeunlock(&(x)))) \ e_msg(__FILE__, __LINE__, M_ABORT, 0, "Write lock unlock failure. ERR=%s\n",\ strerror(errstat)); \ } while(0) #define LockRes() b_LockRes(__FILE__, __LINE__) #define UnlockRes() b_UnlockRes(__FILE__, __LINE__) #ifdef DEBUG_MEMSET #define memset(a, v, n) b_memset(__FILE__, __LINE__, a, v, n) void b_memset(const char *file, int line, void *mem, int val, size_t num); #endif /** * The digit following Dmsg and Emsg indicates the number of substitutions in * the message string. We need to do this kludge because non-GNU compilers * do not handle varargs #defines. */ /** Debug Messages that are printed */ #ifdef DEBUG #define Dmsg0(lvl, msg) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg) #define Dmsg1(lvl, msg, a1) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1) #define Dmsg2(lvl, msg, a1, a2) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2) #define Dmsg3(lvl, msg, a1, a2, a3) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3) #define Dmsg4(lvl, msg, a1, a2, a3, a4) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4) #define Dmsg5(lvl, msg, a1, a2, a3, a4, a5) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5) #define Dmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6) #define Dmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Dmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) \ if ((lvl)<=debug_level) d_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) #define Dmsg9(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ if ((lvl)<=debug_level) d_msg(__FILE__,__LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) #define Dmsg10(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ if ((lvl)<=debug_level) d_msg(__FILE__,__LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) #define Dmsg11(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ if ((lvl)<=debug_level) d_msg(__FILE__,__LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) #define Dmsg12(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) \ if ((lvl)<=debug_level) d_msg(__FILE__,__LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) #define Dmsg13(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) \ if ((lvl)<=debug_level) d_msg(__FILE__,__LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) #else #define Dmsg0(lvl, msg) #define Dmsg1(lvl, msg, a1) #define Dmsg2(lvl, msg, a1, a2) #define Dmsg3(lvl, msg, a1, a2, a3) #define Dmsg4(lvl, msg, a1, a2, a3, a4) #define Dmsg5(lvl, msg, a1, a2, a3, a4, a5) #define Dmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) #define Dmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Dmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) #define Dmsg11(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) #define Dmsg12(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) #define Dmsg13(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) #endif /* DEBUG */ #ifdef TRACE_FILE #define Tmsg0(lvl, msg) \ t_msg(__FILE__, __LINE__, lvl, msg) #define Tmsg1(lvl, msg, a1) \ t_msg(__FILE__, __LINE__, lvl, msg, a1) #define Tmsg2(lvl, msg, a1, a2) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2) #define Tmsg3(lvl, msg, a1, a2, a3) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3) #define Tmsg4(lvl, msg, a1, a2, a3, a4) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4) #define Tmsg5(lvl, msg, a1, a2, a3, a4, a5) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5) #define Tmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6) #define Tmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Tmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) #define Tmsg9(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) #define Tmsg10(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) #define Tmsg11(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) #define Tmsg12(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) #define Tmsg13(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) \ t_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) #else #define Tmsg0(lvl, msg) #define Tmsg1(lvl, msg, a1) #define Tmsg2(lvl, msg, a1, a2) #define Tmsg3(lvl, msg, a1, a2, a3) #define Tmsg4(lvl, msg, a1, a2, a3, a4) #define Tmsg5(lvl, msg, a1, a2, a3, a4, a5) #define Tmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) #define Tmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Tmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) #define Tmsg9(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) #define Tmsg10(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) #define Tmsg11(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) #define Tmsg12(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) #define Tmsg13(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) #endif /* TRACE_FILE */ /** Messages that are printed (uses p_msg) */ #define Pmsg0(lvl, msg) \ p_msg(__FILE__, __LINE__, lvl, msg) #define Pmsg1(lvl, msg, a1) \ p_msg(__FILE__, __LINE__, lvl, msg, a1) #define Pmsg2(lvl, msg, a1, a2) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2) #define Pmsg3(lvl, msg, a1, a2, a3) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3) #define Pmsg4(lvl, msg, a1, a2, a3, a4) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4) #define Pmsg5(lvl, msg, a1, a2, a3, a4, a5) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5) #define Pmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6) #define Pmsg7(lvl, msg, a1, a2, a3, a4, a5, a6, a7) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Pmsg8(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) #define Pmsg9(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9) #define Pmsg10(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) #define Pmsg11(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) #define Pmsg12(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) #define Pmsg13(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) #define Pmsg14(lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) \ p_msg(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) /** Messages that are printed using fixed size buffers (uses p_msg_fb) */ #define FPmsg0(lvl, msg) \ p_msg_fb(__FILE__, __LINE__, lvl, msg) #define FPmsg1(lvl, msg, a1) \ p_msg_fb(__FILE__, __LINE__, lvl, msg, a1) #define FPmsg2(lvl, msg, a1, a2) \ p_msg_fb(__FILE__, __LINE__, lvl, msg, a1, a2) #define FPmsg3(lvl, msg, a1, a2, a3) \ p_msg_fb(__FILE__, __LINE__, lvl, msg, a1, a2, a3) #define FPmsg4(lvl, msg, a1, a2, a3, a4) \ p_msg_fb(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4) #define FPmsg5(lvl, msg, a1, a2, a3, a4, a5) \ p_msg_fb(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5) #define FPmsg6(lvl, msg, a1, a2, a3, a4, a5, a6) \ p_msg_fb(__FILE__, __LINE__, lvl, msg, a1, a2, a3, a4, a5, a6) /** Daemon Error Messages that are delivered according to the message resource */ #define Emsg0(typ, lvl, msg) \ e_msg(__FILE__, __LINE__, typ, lvl, msg) #define Emsg1(typ, lvl, msg, a1) \ e_msg(__FILE__, __LINE__, typ, lvl, msg, a1) #define Emsg2(typ, lvl, msg, a1, a2) \ e_msg(__FILE__, __LINE__, typ, lvl, msg, a1, a2) #define Emsg3(typ, lvl, msg, a1, a2, a3) \ e_msg(__FILE__, __LINE__, typ, lvl, msg, a1, a2, a3) #define Emsg4(typ, lvl, msg, a1, a2, a3, a4) \ e_msg(__FILE__, __LINE__, typ, lvl, msg, a1, a2, a3, a4) #define Emsg5(typ, lvl, msg, a1, a2, a3, a4, a5) \ e_msg(__FILE__, __LINE__, typ, lvl, msg, a1, a2, a3, a4, a5) #define Emsg6(typ, lvl, msg, a1, a2, a3, a4, a5, a6) \ e_msg(__FILE__, __LINE__, typ, lvl, msg, a1, a2, a3, a4, a5, a6) /** Job Error Messages that are delivered according to the message resource */ #define Jmsg0(jcr, typ, lvl, msg) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg) #define Jmsg1(jcr, typ, lvl, msg, a1) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1) #define Jmsg2(jcr, typ, lvl, msg, a1, a2) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2) #define Jmsg3(jcr, typ, lvl, msg, a1, a2, a3) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3) #define Jmsg4(jcr, typ, lvl, msg, a1, a2, a3, a4) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4) #define Jmsg5(jcr, typ, lvl, msg, a1, a2, a3, a4, a5) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4, a5) #define Jmsg6(jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6) #define Jmsg7(jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6, a7) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6, a7) #define Jmsg8(jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) \ j_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6, a7, a8) /** Queued Job Error Messages that are delivered according to the message resource */ #define Qmsg0(jcr, typ, lvl, msg) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg) #define Qmsg1(jcr, typ, lvl, msg, a1) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1) #define Qmsg2(jcr, typ, lvl, msg, a1, a2) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2) #define Qmsg3(jcr, typ, lvl, msg, a1, a2, a3) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3) #define Qmsg4(jcr, typ, lvl, msg, a1, a2, a3, a4) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4) #define Qmsg5(jcr, typ, lvl, msg, a1, a2, a3, a4, a5) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4, a5) #define Qmsg6(jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6) \ q_msg(__FILE__, __LINE__, jcr, typ, lvl, msg, a1, a2, a3, a4, a5, a6) /** Memory Messages that are edited into a Pool Memory buffer */ #define Mmsg0(buf, msg) \ m_msg(__FILE__, __LINE__, buf, msg) #define Mmsg1(buf, msg, a1) \ m_msg(__FILE__, __LINE__, buf, msg, a1) #define Mmsg2(buf, msg, a1, a2) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2) #define Mmsg3(buf, msg, a1, a2, a3) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3) #define Mmsg4(buf, msg, a1, a2, a3, a4) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4) #define Mmsg5(buf, msg, a1, a2, a3, a4, a5) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4, a5) #define Mmsg6(buf, msg, a1, a2, a3, a4, a5, a6) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4, a5, a6) #define Mmsg7(buf, msg, a1, a2, a3, a4, a5, a6, a7) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4, a5, a6) #define Mmsg8(buf, msg, a1, a2, a3, a4, a5, a6, a7, a8) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4, a5, a6) #define Mmsg11(buf, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) #define Mmsg15(buf, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) \ m_msg(__FILE__, __LINE__, buf, msg, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) class POOL_MEM; /* Edit message into Pool Memory buffer -- no __FILE__ and __LINE__ */ int Mmsg(POOLMEM **msgbuf, const char *fmt, ...); int Mmsg(POOLMEM *&msgbuf, const char *fmt, ...); int Mmsg(POOL_MEM &msgbuf, const char *fmt, ...); class JCR; void d_msg(const char *file, int line, int level, const char *fmt, ...); void p_msg(const char *file, int line, int level, const char *fmt, ...); void p_msg_fb(const char *file, int line, int level, const char *fmt,...); void e_msg(const char *file, int line, int type, int level, const char *fmt, ...); void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt, ...); void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt, ...); int m_msg(const char *file, int line, POOLMEM **msgbuf, const char *fmt, ...); int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...); /** Use our strdup with smartalloc */ #undef strdup #define strdup(buf) bad_call_on_strdup_use_bstrdup(buf) /** Use our fgets which handles interrupts */ #undef fgets #define fgets(x, y, z) bfgets((x), (y), (z)) /** Use our sscanf, which is safer and works with known sizes */ #define sscanf bsscanf #ifdef DEBUG #define bstrdup(str) strcpy((char *)b_malloc(__FILE__,__LINE__, strlen((str))+1), (str)) #else #define bstrdup(str) strcpy((char *)bmalloc(strlen((str))+1),(str)) #endif #ifdef DEBUG #define bmalloc(size) b_malloc(__FILE__, __LINE__, (size)) #endif /** Macro to simplify free/reset pointers */ #define bfree_and_null(a) do{if(a){free(a); (a)=NULL;}} while(0) /** * Replace codes needed in both file routines and non-file routines * Job replace codes -- in "replace" */ #define REPLACE_ALWAYS 'a' #define REPLACE_IFNEWER 'w' #define REPLACE_NEVER 'n' #define REPLACE_IFOLDER 'o' /** This probably should be done on a machine by machine basis, but it works */ /** This is critical for the smartalloc routines to properly align memory */ #define ALIGN_SIZE (sizeof(double)) #define BALIGN(x) (((x) + ALIGN_SIZE - 1) & ~(ALIGN_SIZE -1)) /* ============================================================= * OS Dependent defines * ============================================================= */ #ifndef HAVE_WIN32 #if defined (__digital__) && defined (__unix__) /* Tru64 - it does have fseeko and ftello , but since ftell/fseek are also 64 bit */ /* take this 'shortcut' */ #define fseeko fseek #define ftello ftell #else #ifndef HAVE_FSEEKO /* Bad news. This OS cannot handle 64 bit fseeks and ftells */ #define fseeko fseek #define ftello ftell #endif #endif /* __digital__ && __unix__ */ #endif /* HAVE_WIN32 */ #ifdef HAVE_SUN_OS /* * On Solaris 2.5/2.6/7 and 8, threads are not timesliced by default, * so we need to explictly increase the concurrency level. */ #ifdef USE_THR_SETCONCURRENCY #include #define set_thread_concurrency(x) thr_setconcurrency(x) extern int thr_setconcurrency(int); #define SunOS 1 #else #define set_thread_concurrency(x) #endif #else /* * Not needed on most systems */ #define set_thread_concurrency(x) #endif #ifdef HAVE_DARWIN_OS /* Apparently someone forgot to wrap getdomainname as a C function */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int getdomainname(char *name, int len); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* HAVE_DARWIN_OS */ #define TRACEFILEDIRECTORY working_directory ? working_directory : "c:" #if defined(HAVE_WIN32) /* * Windows */ #define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bareos" #define PathSeparator '\\' inline bool IsPathSeparator(int ch) { return ch == '/' || ch == '\\'; } inline char *first_path_separator(char *path) { return strpbrk(path, "/\\"); } inline const char *first_path_separator(const char *path) { return strpbrk(path, "/\\"); } extern void pause_msg(const char *file, const char *func, int line, const char *msg); #define pause(msg) if (debug_level) pause_msg(__FILE__, __func__, __LINE__, (msg)) #else /* * Unix/Linix */ #define PathSeparator '/' /* Define Winsock functions if we aren't on Windows */ inline int WSA_Init() { return (0); } /* 0 = success */ inline int WSACleanup() { return (0); } /* 0 = success */ inline bool IsPathSeparator(int ch) { return ch == '/'; } inline char *first_path_separator(char *path) { return strchr(path, '/'); } inline const char *first_path_separator(const char *path) { return strchr(path, '/'); } #define pause(msg) #endif /** HP-UX 11 specific workarounds */ #ifdef HAVE_HPUX_OS # undef h_errno extern int h_errno; /** the {get,set}domainname() functions exist in HPUX's libc. * the configure script detects that correctly. * the problem is no system headers declares the prototypes for these functions * this is done below */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int getdomainname(char *name, int namelen); int setdomainname(char *name, int namelen); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* HAVE_HPUX_OS */ #ifdef HAVE_OSF1_OS #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int fchdir(int filedes); long gethostid(void); int getdomainname(char *name, int len); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* HAVE_OSF1_OS */ /** Disabled because it breaks internationalisation... #undef HAVE_SETLOCALE #ifdef HAVE_SETLOCALE #include #else #define setlocale(x, y) ("ANSI_X3.4-1968") #endif #ifdef HAVE_NL_LANGINFO #include #else #define nl_langinfo(x) ("ANSI_X3.4-1968") #endif */ /** Determine endianes */ static inline bool bigendian() { return htonl(1) == 1L; } #ifndef __GNUC__ #define __PRETTY_FUNCTION__ __func__ #endif #ifdef ENTER_LEAVE #define Enter(lvl) Dmsg1(lvl, "Enter: %s\n", __PRETTY_FUNCTION__) #define Leave(lvl) Dmsg1(lvl, "Leave: %s\n", __PRETTY_FUNCTION__) #else #define Enter(lvl) #define Leave(lvl) #endif #endif /* _BACONFIG_H */ bareos-Release-14.2.6/src/include/bareos.h000066400000000000000000000072451263011562700203060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * bareos.h -- main header file to include in all Bareos source * */ #ifndef _BAREOS_H #define _BAREOS_H 1 /* Disable FORTIFY_SOURCE, because bareos uses is own memory * manager */ #ifdef _FORTIFY_SOURCE #undef _FORTIFY_SOURCE #endif #ifdef __cplusplus /* Workaround for SGI IRIX 6.5 */ #define _LANGUAGE_C_PLUS_PLUS 1 #endif #include "hostconfig.h" #define _REENTRANT 1 #define _THREAD_SAFE 1 #define _POSIX_PTHREAD_SEMANTICS 1 /* System includes */ #if HAVE_STDINT_H #ifndef __sgi #include #endif #endif #if HAVE_STDARG_H #include #endif #include #if HAVE_STDLIB_H #include #endif #if HAVE_UNISTD_H # ifdef HAVE_HPUX_OS # undef _INCLUDE_POSIX1C_SOURCE # endif #include #endif #if HAVE_UMEM_H #include #endif #if HAVE_ALLOCA_H #include #endif #if defined(_MSC_VER) #include #include #include #endif #include #include /* O_NOATIME is defined at fcntl.h when supported */ #ifndef O_NOATIME #define O_NOATIME 0 #endif #if defined(_MSC_VER) extern "C" { #include "getopt.h" } #endif #ifdef xxxxx #ifdef HAVE_GETOPT_LONG #include #else #include "lib/getopt.h" #endif #endif #include #include #include #include #ifndef _SPLINT_ #include #endif #if HAVE_LIMITS_H #include #endif #include #include #include #include #include #ifdef HAVE_SYS_BITYPES_H #include #endif #include #ifdef HAVE_SYS_SOCKET_H #include #endif #if defined(HAVE_WIN32) & !defined(HAVE_MINGW) #include #endif #if !defined(HAVE_WIN32) & !defined(HAVE_MINGW) #include #endif #include #if HAVE_SYS_WAIT_H #include #endif #include #include #include #if defined(HAVE_WIN32) #include #endif /* * Local Bareos includes. Be sure to put all the system includes before these. */ #include "version.h" #include "bc_types.h" #if defined(HAVE_WIN32) #include "compat.h" #endif #include "streams.h" #include "filetypes.h" #include "baconfig.h" #include "lib/lib.h" /* * For wx-console compiles, we undo some Bareos defines. * This prevents conflicts between wx-Widgets and Bareos. * In wx-console files that malloc or free() Bareos structures * config/resources and interface to the Bareos libraries, * you must use bmalloc() and bfree(). */ #ifdef HAVE_WXCONSOLE #undef New #undef _ #undef free #undef malloc #endif #if defined(HAVE_WIN32) #include "winapi.h" #include "winhost.h" #else #include "host.h" #endif #ifndef HAVE_ZLIB_H #undef HAVE_LIBZ /* no good without headers */ #endif #endif bareos-Release-14.2.6/src/include/bc_types.h000066400000000000000000000154031263011562700206360ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Define integer types for Bareos * * Integer types. These types should be be used in all * contexts in which the length of an integer stored on * removable media must be known regardless of the * architecture of the platform. * * Bareos types are: * * int8_t, int16_t, int32_t, int64_t * uint8_t, uint16_t, uint32_t, uint64_t * * Also, we define types such as file address lengths. * * Kern Sibbald, March MM */ #ifndef __bc_types_INCLUDED #define __bc_types_INCLUDED #ifdef HAVE_WIN32 typedef UINT64 u_int64_t; typedef UINT64 uint64_t; typedef INT64 int64_t; typedef UINT32 uint32_t; typedef INT64 intmax_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef signed short int16_t; typedef signed char int8_t; typedef int __daddr_t; #if !defined(HAVE_MINGW) typedef long int32_t; typedef float float32_t; typedef double float64_t; #endif #if !defined(_MSC_VER) || (_MSC_VER < 1400) // VC8+ #ifndef _TIME_T_DEFINED #define _TIME_T_DEFINED typedef long time_t; #endif #endif #if __STDC__ && !defined(HAVE_MINGW) typedef _dev_t dev_t; #if !defined(HAVE_WXCONSOLE) typedef __int64 ino_t; #endif #endif typedef UINT32 u_int32_t; typedef unsigned char u_int8_t; typedef unsigned short u_int16_t; #if !defined(HAVE_MINGW) #undef uint32_t #endif #endif /* HAVE_WIN32 */ /* * These are the sizes of the current definitions of database * Ids. In general, FileId_t can be set to uint64_t and it * *should* work. Users have reported back that it does work * for PostgreSQL. For the other types, all places in Bareos * have been converted, but no one has actually tested it. * In principle, the only field that really should need to be * 64 bits is the FileId_t */ typedef uint64_t FileId_t; typedef uint32_t DBId_t; /* general DB id type */ typedef uint32_t JobId_t; typedef char POOLMEM; /* Types */ /* If sys/types.h does not supply intXX_t, supply them ourselves */ /* (or die trying) */ #ifndef HAVE_U_INT typedef unsigned int u_int; #endif #ifndef HAVE_INTXX_T # if (SIZEOF_CHAR == 1) typedef signed char int8_t; # else # error "8 bit int type not found." # endif # if (SIZEOF_SHORT_INT == 2) typedef short int int16_t; # else # error "16 bit int type not found." # endif # if (SIZEOF_INT == 4) typedef int int32_t; # else # error "32 bit int type not found." # endif #endif /* If sys/types.h does not supply u_intXX_t, supply them ourselves */ #ifndef HAVE_U_INTXX_T # ifdef HAVE_UINTXX_T typedef uint8_t u_int8_t; typedef uint16_t u_int16_t; typedef uint32_t u_int32_t; # define HAVE_U_INTXX_T 1 # else # if (SIZEOF_CHAR == 1) typedef unsigned char u_int8_t; # else # error "8 bit int type not found. Required!" # endif # if (SIZEOF_SHORT_INT == 2) typedef unsigned short int u_int16_t; # else # error "16 bit int type not found. Required!" # endif # if (SIZEOF_INT == 4) typedef unsigned int u_int32_t; # else # error "32 bit int type not found. Required!" # endif # endif #endif /* 64-bit types */ #ifndef HAVE_INT64_T # if (SIZEOF_LONG_LONG_INT == 8) typedef long long int int64_t; # define HAVE_INT64_T 1 # else # if (SIZEOF_LONG_INT == 8) typedef long int int64_t; # define HAVE_INT64_T 1 # endif # endif #endif #ifndef HAVE_INTMAX_T # ifdef HAVE_INT64_T typedef int64_t intmax_t; # else # error "64 bit type not found. Required!" # endif #endif #ifndef HAVE_U_INT64_T # if (SIZEOF_LONG_LONG_INT == 8) typedef unsigned long long int u_int64_t; # define HAVE_U_INT64_T 1 # else # if (SIZEOF_LONG_INT == 8) typedef unsigned long int u_int64_t; # define HAVE_U_INT64_T 1 # else # error "64 bit type not found. Required!" # endif # endif #endif #ifndef HAVE_U_INTMAX_T # ifdef HAVE_U_INT64_T typedef u_int64_t u_intmax_t; # else # error "64 bit type not found. Required!" # endif #endif #ifndef HAVE_INTPTR_T #define HAVE_INTPTR_T 1 # if (SIZEOF_INT_P == 4) typedef int32_t intptr_t; # else # if (SIZEOF_INT_P == 8) typedef int64_t intptr_t; # else # error "Can't find sizeof pointer. Required!" # endif # endif #endif #ifndef HAVE_UINTPTR_T #define HAVE_UINTPTR_T 1 # if (SIZEOF_INT_P == 4) typedef uint32_t uintptr_t; # else # if (SIZEOF_INT_P == 8) typedef uint64_t uintptr_t; # else # error "Can't find sizeof pointer. Required!" # endif # endif #endif /* Limits for the above types. */ #undef INT8_MIN #undef INT8_MAX #undef UINT8_MAX #undef INT16_MIN #undef INT16_MAX #undef UINT16_MAX #undef INT32_MIN #undef INT32_MAX #undef UINT32_MAX #define INT8_MIN (-127-1) #define INT8_MAX (127) #define UINT8_MAX (255u) #define INT16_MIN (-32767-1) #define INT16_MAX (32767) #define UINT16_MAX (65535u) #define INT32_MIN (-2147483647-1) #define INT32_MAX (2147483647) #define UINT32_MAX (4294967295u) typedef double float64_t; typedef float float32_t; /* Define the uint versions actually used in Bareos */ #ifndef uint8_t #define uint8_t u_int8_t #define uint16_t u_int16_t #define uint32_t u_int32_t #define uint64_t u_int64_t #define uintmax_t u_intmax_t #endif /* Bareos time -- Unix time with microseconds */ #define btime_t int64_t /* Unix time (time_t) widened to 64 bits */ #define utime_t int64_t #ifndef HAVE_SOCKLEN_T #define socklen_t int #endif #ifdef HAVE_WIN32 #define sockopt_val_t const char * #else #ifdef HAVE_OLD_SOCKOPT #define sockopt_val_t char * #else #define sockopt_val_t void * #endif #endif /* HAVE_WIN32 */ /* * Status codes returned by create_file() * Used in findlib, filed, and plugins */ enum { CF_SKIP = 1, /* skip file (not newer or something) */ CF_ERROR, /* error creating file */ CF_EXTRACT, /* file created, data to extract */ CF_CREATED, /* file created, no data to extract */ CF_CORE /* let bareos core handle the file creation */ }; #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #endif /* __bc_types_INCLUDED */ bareos-Release-14.2.6/src/include/ch.h000066400000000000000000000032061263011562700174160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Compressed stream header struct * * Laurent Papier */ #ifndef __CH_H #define __CH_H 1 /* * Compression algorithm signature. 4 letters as a 32bits integer */ #define COMPRESS_NONE 0x4e4f4e45 /* used for incompressible block */ #define COMPRESS_GZIP 0x475a4950 #define COMPRESS_LZO1X 0x4c5a4f58 #define COMPRESS_FZFZ 0x465A465A #define COMPRESS_FZ4L 0x465A344C #define COMPRESS_FZ4H 0x465A3448 /* * Compression header version */ #define COMP_HEAD_VERSION 0x1 /* Compressed data stream header */ typedef struct { uint32_t magic; /* compression algo used in this compressed data stream */ uint16_t level; /* compression level used */ uint16_t version; /* for futur evolution */ uint32_t size; /* compressed size of the original data */ } comp_stream_header; #endif /* __CH_H */ bareos-Release-14.2.6/src/include/fileopts.h000066400000000000000000000063431263011562700206560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * File types * * Kern Sibbald MMI * * Extracted from findlib/find.h Nov 2010 * Switched to enum Nov 2014, Marco van Wieringen */ #ifndef __BFILEOPTS_H #define __BFILEOPTS_H /* * Options saved in "options" of the include/exclude lists. * They are directly jammed into "flag" of ff packet */ enum { FO_PORTABLE_DATA = 0, /* Data is portable */ FO_MD5 = 1, /* Do MD5 checksum */ FO_COMPRESS = 2, /* Do compression */ FO_NO_RECURSION = 3, /* No recursion in directories */ FO_MULTIFS = 4, /* Multiple file systems */ FO_SPARSE = 5, /* Do sparse file checking */ FO_IF_NEWER = 6, /* Replace if newer */ FO_NOREPLACE = 7, /* Never replace */ FO_READFIFO = 8, /* Read data from fifo */ FO_SHA1 = 9, /* Do SHA1 checksum */ FO_PORTABLE = 10, /* Use portable data format -- no BackupWrite */ FO_MTIMEONLY = 11, /* Use mtime rather than mtime & ctime */ FO_KEEPATIME = 12, /* Reset access time */ FO_EXCLUDE = 13, /* Exclude file */ FO_ACL = 14, /* Backup ACLs */ FO_NO_HARDLINK = 15, /* Don't handle hard links */ FO_IGNORECASE = 16, /* Ignore file name case */ FO_HFSPLUS = 17, /* Resource forks and Finder Info */ FO_WIN32DECOMP = 18, /* Use BackupRead decomposition */ FO_SHA256 = 19, /* Do SHA256 checksum */ FO_SHA512 = 20, /* Do SHA512 checksum */ FO_ENCRYPT = 21, /* Encrypt data stream */ FO_NOATIME = 22, /* Use O_NOATIME to prevent atime change */ FO_ENHANCEDWILD = 23, /* Enhanced wild card processing */ FO_CHKCHANGES = 24, /* Check if file have been modified during backup */ FO_STRIPPATH = 25, /* Check for stripping path */ FO_HONOR_NODUMP = 26, /* Honor NODUMP flag */ FO_XATTR = 27, /* Backup Extended Attributes */ FO_DELTA = 28, /* Delta data -- i.e. all copies returned on restore */ FO_PLUGIN = 29, /* Plugin data stream -- return to plugin on restore */ FO_OFFSETS = 30, /* Keep I/O file offsets */ FO_NO_AUTOEXCL = 31 /* Don't use autoexclude methods */ }; /* * Keep this set to the last entry in the enum. */ #define FO_MAX FO_NO_AUTOEXCL /* * Make sure you have enough bits to store all above bit fields. */ #define FOPTS_BYTES nbytes_for_bits(FO_MAX + 1) #endif /* __BFILEOPTSS_H */ bareos-Release-14.2.6/src/include/filetypes.h000066400000000000000000000075731263011562700210430ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Stream definitions. Split from baconfig.h Nov 2010 * * Kern Sibbald, MM * */ #ifndef __BFILETYPES_H #define __BFILETYPES_H 1 /** * File type (Bareos defined). * NOTE!!! These are saved in the Attributes record on the tape, so * do not change them. If need be, add to them. * * This is stored as 32 bits on the Volume, but only FT_MASK (16) bits are * used for the file type. The upper bits are used to indicate * additional optional fields in the attribute record. */ #define FT_MASK 0xFFFF /* Bits used by FT (type) */ #define FT_LNKSAVED 1 /* hard link to file already saved */ #define FT_REGE 2 /* Regular file but empty */ #define FT_REG 3 /* Regular file */ #define FT_LNK 4 /* Soft Link */ #define FT_DIREND 5 /* Directory at end (saved) */ #define FT_SPEC 6 /* Special file -- chr, blk, fifo, sock */ #define FT_NOACCESS 7 /* Not able to access */ #define FT_NOFOLLOW 8 /* Could not follow link */ #define FT_NOSTAT 9 /* Could not stat file */ #define FT_NOCHG 10 /* Incremental option, file not changed */ #define FT_DIRNOCHG 11 /* Incremental option, directory not changed */ #define FT_ISARCH 12 /* Trying to save archive file */ #define FT_NORECURSE 13 /* No recursion into directory */ #define FT_NOFSCHG 14 /* Different file system, prohibited */ #define FT_NOOPEN 15 /* Could not open directory */ #define FT_RAW 16 /* Raw block device */ #define FT_FIFO 17 /* Raw fifo device */ /** * The DIRBEGIN packet is sent to the FD file processing routine so * that it can filter packets, but otherwise, it is not used * or saved */ #define FT_DIRBEGIN 18 /* Directory at beginning (not saved) */ #define FT_INVALIDFS 19 /* File system not allowed for */ #define FT_INVALIDDT 20 /* Drive type not allowed for */ #define FT_REPARSE 21 /* Win NTFS reparse point */ #define FT_PLUGIN 22 /* Plugin generated filename */ #define FT_DELETED 23 /* Deleted file entry */ #define FT_BASE 24 /* Duplicate base file entry */ #define FT_RESTORE_FIRST 25 /* Restore this "object" first */ #define FT_JUNCTION 26 /* Win32 Junction point */ #define FT_PLUGIN_CONFIG 27 /* Object for Plugin configuration */ #define FT_PLUGIN_CONFIG_FILLED 28 /* Object for Plugin configuration filled by Director */ #define FT_UNSET FT_MASK /* Initial value when not determined yet */ /* Definitions for upper part of type word (see above). */ #define AR_DATA_STREAM (1<<16) /* Data stream id present */ /* Quick way to know if a Filetype is about a plugin "Object" */ #define IS_FT_OBJECT(x) (((x) == FT_RESTORE_FIRST) || ((x) == FT_PLUGIN_CONFIG_FILLED) || ((x) == FT_PLUGIN_CONFIG)) #endif /* __BFILETYPES_H */ bareos-Release-14.2.6/src/include/host.h.in000066400000000000000000000026051263011562700204100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Define Host machine */ #define HOST_OS "@host@@post_host@" #define BAREOS "@BAREOS@" #define DISTNAME "@DISTNAME@" #define DISTVER "@DISTVER@" #define HELPDIR "@htmldir@" #define FD_DEFAULT_PORT "@fd_port@" #define SD_DEFAULT_PORT "@sd_port@" #define DIR_DEFAULT_PORT "@dir_port@" #define NDMP_DEFAULT_PORT "10000" #define OBS_PROJECT "@OBS_PROJECT@" #define OBS_DISTRIBUTION "@OBS_DISTRIBUTION@" #define OBS_ARCH "@OBS_ARCH@" #define OBS_SRCMD5 "@OBS_SRCMD5@" bareos-Release-14.2.6/src/include/hostconfig.h000066400000000000000000000024141263011562700211670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2012-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * hostconfig.h -- wrapper around config.h from autoconf or the windows * config headers so its never included more then once. */ #ifndef _HOSTCONFIG_H #define _HOSTCONFIG_H 1 #if defined(HAVE_WIN32) #if defined(HAVE_MINGW) #include "mingwconfig.h" #else #include "winconfig.h" #endif #else #include "config.h" #endif #endif bareos-Release-14.2.6/src/include/jcr.h000066400000000000000000000755361263011562700176210ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos JCR Structure definition for Daemons and the Library * This definition consists of a "Global" definition common * to all daemons and used by the library routines, and a * daemon specific part that is enabled with #defines. * * Kern Sibbald, Nov MM * */ #ifndef __JCR_H_ #define __JCR_H_ 1 /* * Backup/Verify level code. These are stored in the DB */ #define L_FULL 'F' /* Full backup */ #define L_INCREMENTAL 'I' /* Since last backup */ #define L_DIFFERENTIAL 'D' /* Since last full backup */ #define L_SINCE 'S' #define L_VERIFY_CATALOG 'C' /* Verify from catalog */ #define L_VERIFY_INIT 'V' /* Verify save (init DB) */ #define L_VERIFY_VOLUME_TO_CATALOG 'O' /* Verify Volume to catalog entries */ #define L_VERIFY_DISK_TO_CATALOG 'd' /* Verify Disk attributes to catalog */ #define L_VERIFY_DATA 'A' /* Verify data on volume */ #define L_BASE 'B' /* Base level job */ #define L_NONE ' ' /* None, for Restore and Admin */ #define L_VIRTUAL_FULL 'f' /* Virtual full backup */ /* * Job Types. These are stored in the DB */ #define JT_BACKUP 'B' /* Backup Job */ #define JT_MIGRATED_JOB 'M' /* A previous backup job that was migrated */ #define JT_VERIFY 'V' /* Verify Job */ #define JT_RESTORE 'R' /* Restore Job */ #define JT_CONSOLE 'U' /* console program */ #define JT_SYSTEM 'I' /* internal system "job" */ #define JT_ADMIN 'D' /* admin job */ #define JT_ARCHIVE 'A' /* Archive Job */ #define JT_JOB_COPY 'C' /* Copy of a Job */ #define JT_COPY 'c' /* Copy Job */ #define JT_MIGRATE 'g' /* Migration Job */ #define JT_SCAN 'S' /* Scan Job */ /* * Job Status. Some of these are stored in the DB */ #define JS_Canceled 'A' /* Canceled by user */ #define JS_Blocked 'B' /* Blocked */ #define JS_Created 'C' /* Created but not yet running */ #define JS_Differences 'D' /* Verify differences */ #define JS_ErrorTerminated 'E' /* Job terminated in error */ #define JS_WaitFD 'F' /* Waiting on File daemon */ #define JS_Incomplete 'I' /* Incomplete Job */ #define JS_DataCommitting 'L' /* Committing data (last despool) */ #define JS_WaitMount 'M' /* Waiting for Mount */ #define JS_Running 'R' /* Running */ #define JS_WaitSD 'S' /* Waiting on the Storage daemon */ #define JS_Terminated 'T' /* Terminated normally */ #define JS_Warnings 'W' /* Terminated normally with warnings */ #define JS_AttrDespooling 'a' /* SD despooling attributes */ #define JS_WaitClientRes 'c' /* Waiting for Client resource */ #define JS_WaitMaxJobs 'd' /* Waiting for maximum jobs */ #define JS_Error 'e' /* Non-fatal error */ #define JS_FatalError 'f' /* Fatal error */ #define JS_AttrInserting 'i' /* Doing batch insert file records */ #define JS_WaitJobRes 'j' /* Waiting for job resource */ #define JS_DataDespooling 'l' /* Doing data despooling */ #define JS_WaitMedia 'm' /* Waiting for new media */ #define JS_WaitPriority 'p' /* Waiting for higher priority jobs to finish */ #define JS_WaitDevice 'q' /* Queued waiting for device */ #define JS_WaitStoreRes 's' /* Waiting for storage resource */ #define JS_WaitStartTime 't' /* Waiting for start time */ /* * Protocol types */ enum { PT_NATIVE = 0, PT_NDMP }; /* * Authentication Protocol types */ enum { APT_NATIVE = 0, APT_NDMPV2, APT_NDMPV3, APT_NDMPV4 }; /* * Authentication types */ enum { AT_NONE = 0, AT_CLEAR, AT_MD5, AT_VOID }; /* * Migration selection types */ enum { MT_SMALLEST_VOL = 1, MT_OLDEST_VOL, MT_POOL_OCCUPANCY, MT_POOL_TIME, MT_POOL_UNCOPIED_JOBS, MT_CLIENT, MT_VOLUME, MT_JOB, MT_SQLQUERY }; #define job_terminated_successfully(jcr) \ (jcr->JobStatus == JS_Terminated || \ jcr->JobStatus == JS_Warnings \ ) #define job_canceled(jcr) \ (jcr->JobStatus == JS_Canceled || \ jcr->JobStatus == JS_ErrorTerminated || \ jcr->JobStatus == JS_FatalError \ ) #define job_waiting(jcr) \ (jcr->job_started && \ (jcr->JobStatus == JS_WaitFD || \ jcr->JobStatus == JS_WaitSD || \ jcr->JobStatus == JS_WaitMedia || \ jcr->JobStatus == JS_WaitMount || \ jcr->JobStatus == JS_WaitStoreRes || \ jcr->JobStatus == JS_WaitJobRes || \ jcr->JobStatus == JS_WaitClientRes || \ jcr->JobStatus == JS_WaitMaxJobs || \ jcr->JobStatus == JS_WaitPriority || \ jcr->SDJobStatus == JS_WaitMedia || \ jcr->SDJobStatus == JS_WaitMount || \ jcr->SDJobStatus == JS_WaitDevice || \ jcr->SDJobStatus == JS_WaitMaxJobs)) #define foreach_jcr(jcr) \ for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) ) #define endeach_jcr(jcr) jcr_walk_end(jcr) #define SD_APPEND 1 #define SD_READ 0 /* * Forward referenced structures */ class JCR; class BSOCK; struct FF_PKT; class B_DB; struct ATTR_DBR; struct save_pkt; struct bpContext; #ifdef HAVE_WIN32 struct CP_THREAD_CTX; #endif #ifdef FILE_DAEMON class htable; class B_ACCURATE; struct acl_data_t; struct xattr_data_t; struct CRYPTO_CTX { bool pki_sign; /* Enable PKI Signatures? */ bool pki_encrypt; /* Enable PKI Encryption? */ DIGEST *digest; /* Last file's digest context */ X509_KEYPAIR *pki_keypair; /* Encryption key pair */ alist *pki_signers; /* Trusted Signers */ alist *pki_recipients; /* Trusted Recipients */ CRYPTO_SESSION *pki_session; /* PKE Public Keys + Symmetric Session Keys */ POOLMEM *crypto_buf; /* Encryption/Decryption buffer */ POOLMEM *pki_session_encoded; /* Cached DER-encoded copy of pki_session */ int32_t pki_session_encoded_size; /* Size of DER-encoded pki_session */ }; #endif #ifdef DIRECTOR_DAEMON struct RESOURCES { JOBRES *job; /* Job resource */ JOBRES *verify_job; /* Job resource of verify previous job */ JOBRES *previous_job; /* Job resource of migration previous job */ STORERES *rstore; /* Selected read storage */ STORERES *wstore; /* Selected write storage */ STORERES *pstore; /* Selected paired storage (saved wstore or rstore) */ CLIENTRES *client; /* Client resource */ POOLRES *pool; /* Pool resource = write for migration */ POOLRES *rpool; /* Read pool. Used only in migration */ POOLRES *full_pool; /* Full backup pool resource */ POOLRES *vfull_pool; /* Virtual Full backup pool resource */ POOLRES *inc_pool; /* Incremental backup pool resource */ POOLRES *diff_pool; /* Differential backup pool resource */ POOLRES *next_pool; /* Next Pool used for migration/copy and virtual backup */ FILESETRES *fileset; /* FileSet resource */ CATRES *catalog; /* Catalog resource */ MSGSRES *messages; /* Default message handler */ POOLMEM *pool_source; /* Where pool came from */ POOLMEM *npool_source; /* Where next pool came from */ POOLMEM *rpool_source; /* Where migrate read pool came from */ POOLMEM *rstore_source; /* Where read storage came from */ POOLMEM *wstore_source; /* Where write storage came from */ POOLMEM *catalog_source; /* Where catalog came from */ bool run_pool_override; /* Pool override was given on run cmdline */ bool run_full_pool_override; /* Full pool override was given on run cmdline */ bool run_vfull_pool_override; /* Virtual Full pool override was given on run cmdline */ bool run_inc_pool_override; /* Incremental pool override was given on run cmdline */ bool run_diff_pool_override; /* Differential pool override was given on run cmdline */ bool run_next_pool_override; /* Next pool override was given on run cmdline */ }; #endif struct CMPRS_CTX { POOLMEM *deflate_buffer; /* Buffer used for deflation (compression) */ POOLMEM *inflate_buffer; /* Buffer used for inflation (decompression) */ uint32_t deflate_buffer_size; /* Length of deflation buffer */ uint32_t inflate_buffer_size; /* Length of inflation buffer */ struct { #ifdef HAVE_LIBZ void *pZLIB; /* ZLIB compression session data */ #endif #ifdef HAVE_LZO void *pLZO; /* LZO compression session data */ #endif #ifdef HAVE_FASTLZ void *pZFAST; /* FASTLZ compression session data */ #endif } workset; }; typedef void (JCR_free_HANDLER)(JCR *jcr); /* * Job Control Record (JCR) */ class JCR { private: pthread_mutex_t mutex; /* Jcr mutex */ volatile int32_t _use_count; /* Use count */ int32_t m_JobType; /* Backup, restore, verify ... */ int32_t m_JobLevel; /* Job level */ int32_t m_Protocol; /* Backup Protocol */ bool my_thread_killable; /* Can we kill the thread? */ public: void lock() {P(mutex); }; void unlock() {V(mutex); }; void inc_use_count(void) {lock(); _use_count++; unlock(); }; void dec_use_count(void) {lock(); _use_count--; unlock(); }; int32_t use_count() const { return _use_count; }; void init_mutex(void) {pthread_mutex_init(&mutex, NULL); }; void destroy_mutex(void) {pthread_mutex_destroy(&mutex); }; bool is_job_canceled() { return job_canceled(this); }; bool is_canceled() { return job_canceled(this); }; bool is_terminated_ok() { return job_terminated_successfully(this); }; bool is_incomplete() { return JobStatus == JS_Incomplete; }; bool is_JobLevel(int32_t JobLevel) { return JobLevel == m_JobLevel; }; bool is_JobType(int32_t JobType) { return JobType == m_JobType; }; bool is_JobStatus(int32_t aJobStatus) { return aJobStatus == JobStatus; }; void setJobLevel(int32_t JobLevel) { m_JobLevel = JobLevel; }; void setJobType(int32_t JobType) { m_JobType = JobType; }; void setJobProtocol(int32_t JobProtocol) { m_Protocol = JobProtocol; }; void forceJobStatus(int32_t aJobStatus) { JobStatus = aJobStatus; }; void setJobStarted(); int32_t getJobType() const { return m_JobType; }; int32_t getJobLevel() const { return m_JobLevel; }; int32_t getJobStatus() const { return JobStatus; }; int32_t getJobProtocol() const { return m_Protocol; }; bool no_client_used() const { return (m_JobType == JT_MIGRATE || m_JobType == JT_COPY || m_JobLevel == L_VIRTUAL_FULL); }; bool is_plugin() const { return (cmd_plugin || opt_plugin); }; const char *get_OperationName(); /* in lib/jcr.c */ const char *get_ActionName(bool past = false); /* in lib/jcr.c */ void setJobStatus(int newJobStatus); /* in lib/jcr.c */ bool sendJobStatus(); /* in lib/jcr.c */ bool sendJobStatus(int newJobStatus); /* in lib/jcr.c */ bool JobReads(); /* in lib/jcr.c */ void my_thread_send_signal(int sig); /* in lib/jcr.c */ void set_killable(bool killable); /* in lib/jcr.c */ bool is_killable() const { return my_thread_killable; }; /* * Global part of JCR common to all daemons */ dlink link; /* JCR chain link */ pthread_t my_thread_id; /* Id of thread controlling jcr */ BSOCK *dir_bsock; /* Director bsock or NULL if we are him */ BSOCK *store_bsock; /* Storage connection socket */ BSOCK *file_bsock; /* File daemon connection socket */ JCR_free_HANDLER *daemon_free_jcr; /* Local free routine */ dlist *msg_queue; /* Queued messages */ pthread_mutex_t msg_queue_mutex; /* message queue mutex */ bool dequeuing_msgs; /* Set when dequeuing messages */ alist job_end_push; /* Job end pushed calls */ POOLMEM *VolumeName; /* Volume name desired -- pool_memory */ POOLMEM *errmsg; /* Edited error message */ char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ uint32_t JobId; /* Director's JobId */ uint32_t VolSessionId; uint32_t VolSessionTime; uint32_t JobFiles; /* Number of files written, this job */ uint32_t JobErrors; /* Number of non-fatal errors this job */ uint32_t JobWarnings; /* Number of warning messages */ uint32_t LastRate; /* Last sample bytes/sec */ uint32_t DumpLevel; /* Dump level when doing a NDMP backup */ uint64_t JobBytes; /* Number of bytes processed this job */ uint64_t LastJobBytes; /* Last sample number bytes */ uint64_t ReadBytes; /* Bytes read -- before compression */ FileId_t FileId; /* Last FileId used */ volatile int32_t JobStatus; /* ready, running, blocked, terminated */ int32_t JobPriority; /* Job priority */ time_t sched_time; /* Job schedule time, i.e. when it should start */ time_t initial_sched_time; /* Original sched time before any reschedules are done */ time_t start_time; /* When job actually started */ time_t run_time; /* Used for computing speed */ time_t last_time; /* Last sample time */ time_t end_time; /* Job end time */ time_t wait_time_sum; /* Cumulative wait time since job start */ time_t wait_time; /* Timestamp when job have started to wait */ time_t job_started_time; /* Time when the MaxRunTime start to count */ POOLMEM *client_name; /* Client name */ POOLMEM *JobIds; /* User entered string of JobIds */ POOLMEM *RestoreBootstrap; /* Bootstrap file to restore */ POOLMEM *stime; /* start time for incremental/differential */ char *sd_auth_key; /* SD auth key */ MSGSRES *jcr_msgs; /* Copy of message resource -- actually used */ uint32_t ClientId; /* Client associated with Job */ char *where; /* Prefix to restore files to */ char *RegexWhere; /* File relocation in restore */ alist *where_bregexp; /* BREGEXP alist for path manipulation */ int32_t cached_pnl; /* Cached path length */ POOLMEM *cached_path; /* Cached path */ bool passive_client; /* Client is a passive client e.g. doesn't initiate any network connection */ bool prefix_links; /* Prefix links with Where path */ bool gui; /* Set if gui using console */ bool authenticated; /* Set when client authenticated */ bool cached_attribute; /* Set if attribute is cached */ bool batch_started; /* Set if batch mode started */ bool cmd_plugin; /* Set when processing a command Plugin = */ bool opt_plugin; /* Set when processing an option Plugin = */ bool keep_path_list; /* Keep newly created path in a hash */ bool accurate; /* True if job is accurate */ bool HasBase; /* True if job use base jobs */ bool rerunning; /* Rerunning an incomplete job */ bool job_started; /* Set when the job is actually started */ bool suppress_output; /* Set if this JCR should not output any Jmsgs */ JCR *cjcr; /* Controlling JCR when this is a slave JCR being * controlled by an other JCR used for sending * normal and fatal errors. */ int32_t buf_size; /* Length of buffer */ CMPRS_CTX compress; /* Compression ctx */ #ifdef HAVE_WIN32 CP_THREAD_CTX *cp_thread; /* Copy Thread ctx */ #endif POOLMEM *attr; /* Attribute string from SD */ B_DB *db; /* database pointer */ B_DB *db_batch; /* database pointer for batch and accurate */ uint64_t nb_base_files; /* Number of base files */ uint64_t nb_base_files_used; /* Number of useful files in base */ ATTR_DBR *ar; /* DB attribute record */ guid_list *id_list; /* User/group id to name list */ alist *plugin_ctx_list; /* List of contexts for plugins */ bpContext *plugin_ctx; /* Current plugin context */ save_pkt *plugin_sp; /* Plugin save packet */ POOLMEM *comment; /* Comment for this Job */ int64_t max_bandwidth; /* Bandwidth limit for this Job */ htable *path_list; /* Directory list (used by findlib) */ /* * Daemon specific part of JCR * This should be empty in the library */ #ifdef DIRECTOR_DAEMON /* * Director Daemon specific data part of JCR */ pthread_t SD_msg_chan; /* Message channel thread id */ bool SD_msg_chan_started; /* Message channel thread started */ pthread_cond_t term_wait; /* Wait for job termination */ pthread_cond_t nextrun_ready; /* Wait for job next run to become ready */ workq_ele_t *work_item; /* Work queue item if scheduled */ BSOCK *ua; /* User agent */ RESOURCES res; /* Resources assigned */ alist *rstorage; /* Read storage possibilities */ alist *wstorage; /* Write storage possibilities */ alist *pstorage; /* Paired storage possibilities (saved wstorage or rstorage) */ TREE_ROOT *restore_tree_root; /* Selected files to restore (some protocols need this info) */ BSR *bsr; /* Bootstrap record -- has everything */ char *backup_format; /* Backup format used when doing a NDMP backup */ char *plugin_options; /* User set options for plugin */ uint32_t SDJobFiles; /* Number of files written, this job */ uint64_t SDJobBytes; /* Number of bytes processed this job */ uint32_t SDErrors; /* Number of non-fatal errors */ volatile int32_t SDJobStatus; /* Storage Job Status */ volatile int32_t FDJobStatus; /* File daemon Job Status */ uint32_t ExpectedFiles; /* Expected restore files */ uint32_t MediaId; /* DB record IDs associated with this job */ uint32_t FileIndex; /* Last FileIndex processed */ utime_t MaxRunSchedTime; /* Max run time in seconds from Initial Scheduled time */ POOLMEM *fname; /* Name to put into catalog */ POOLMEM *component_fname; /* Component info file name */ FILE *component_fd; /* Component info file desc */ JOB_DBR jr; /* Job DB record for current job */ JOB_DBR previous_jr; /* Previous job database record */ JCR *mig_jcr; /* JCR for migration/copy job */ char FSCreateTime[MAX_TIME_LENGTH]; /* FileSet CreateTime as returned from DB */ char since[MAX_TIME_LENGTH]; /* Since time */ char PrevJob[MAX_NAME_LENGTH]; /* Previous job name assiciated with since time */ union { JobId_t RestoreJobId; /* Restore id specified by UA */ JobId_t MigrateJobId; /* Migration id specified by UA */ }; POOLMEM *client_uname; /* Client uname */ uint32_t replace; /* Replace option */ int32_t NumVols; /* Number of Volume used in pool */ int32_t reschedule_count; /* Number of times rescheduled */ int32_t FDVersion; /* File daemon version number */ int64_t spool_size; /* Spool size for this job */ volatile bool sd_msg_thread_done; /* Set when Storage message thread done */ bool IgnoreDuplicateJobChecking; /* Set in migration jobs */ bool IgnoreLevelPoolOverides; /* Set if a cmdline pool was specified */ bool spool_data; /* Spool data in SD */ bool acquired_resource_locks; /* Set if resource locks acquired */ bool term_wait_inited; /* Set when cond var inited */ bool nextrun_ready_inited; /* Set when cond var inited */ bool fn_printed; /* Printed filename */ bool needs_sd; /* Set if SD needed by Job */ bool cloned; /* Set if cloned */ bool unlink_bsr; /* Unlink bsr file created */ bool VSS; /* VSS used by FD */ bool Encrypt; /* Encryption used by FD */ bool stats_enabled; /* Keep all job records in a table for long term statistics */ bool no_maxtime; /* Don't check Max*Time for this JCR */ bool keep_sd_auth_key; /* Clear or not the SD auth key after connection*/ bool use_accurate_chksum; /* Use or not checksum option in accurate code */ bool sd_canceled; /* Set if SD canceled */ bool remote_replicate; /* Replicate data to remote SD */ bool RescheduleIncompleteJobs; /* Set if incomplete can be rescheduled */ bool HasQuota; /* Client has quota limits */ #endif /* DIRECTOR_DAEMON */ #ifdef FILE_DAEMON /* * File Daemon specific part of JCR */ uint32_t num_files_examined; /* Files examined this job */ POOLMEM *last_fname; /* Last file saved/verified */ POOLMEM *job_metadata; /* VSS job metadata */ acl_data_t *acl_data; /* ACLs for backup/restore */ xattr_data_t *xattr_data; /* Extended Attributes for backup/restore */ int32_t last_type; /* Type of last file saved/verified */ bool incremental; /* Set if incremental for SINCE */ utime_t mtime; /* Begin time for SINCE */ int listing; /* Job listing in estimate */ long Ticket; /* Ticket */ char *big_buf; /* I/O buffer */ int32_t replace; /* Replace options */ FF_PKT *ff; /* Find Files packet */ char PrevJob[MAX_NAME_LENGTH]; /* Previous job name assiciated with since time */ uint32_t ExpectedFiles; /* Expected restore files */ uint32_t StartFile; uint32_t EndFile; uint32_t StartBlock; uint32_t EndBlock; pthread_t heartbeat_id; /* Id of heartbeat thread */ volatile bool hb_started; /* Heartbeat running */ BSOCK *hb_bsock; /* Duped SD socket */ BSOCK *hb_dir_bsock; /* Duped DIR socket */ alist *RunScripts; /* Commands to run before and after job */ CRYPTO_CTX crypto; /* Crypto ctx */ DIRRES *director; /* Director resource */ bool VSS; /* VSS used by FD */ bool got_metadata; /* Set when found job_metadata */ bool multi_restore; /* Dir can do multiple storage restore */ B_ACCURATE *file_list; /* Previous file list (accurate mode) */ uint64_t base_size; /* Compute space saved with base job */ #endif /* FILE_DAEMON */ #ifdef STORAGE_DAEMON /* * Storage Daemon specific part of JCR */ JCR *next_dev; /* Next JCR attached to device */ JCR *prev_dev; /* Previous JCR attached to device */ char *dir_auth_key; /* Dir auth key */ pthread_cond_t job_start_wait; /* Wait for FD to start Job */ pthread_cond_t job_end_wait; /* Wait for Job to end */ int32_t type; DCR *read_dcr; /* Device context for reading */ DCR *dcr; /* Device context record */ alist *dcrs; /* List of dcrs open */ POOLMEM *job_name; /* Base Job name (not unique) */ POOLMEM *fileset_name; /* FileSet */ POOLMEM *fileset_md5; /* MD5 for FileSet */ POOLMEM *backup_format; /* Backup format used when doing a NDMP backup */ VOL_LIST *VolList; /* List to read */ int32_t NumWriteVolumes; /* Number of volumes written */ int32_t NumReadVolumes; /* Total number of volumes to read */ int32_t CurReadVolume; /* Current read volume number */ int32_t label_errors; /* Count of label errors */ bool session_opened; bool remote_replicate; /* Replicate data to remote SD */ long Ticket; /* Ticket for this job */ bool ignore_label_errors; /* Ignore Volume label errors */ bool spool_attributes; /* Set if spooling attributes */ bool no_attributes; /* Set if no attributes wanted */ int64_t spool_size; /* Spool size for this job */ bool spool_data; /* Set to spool data */ int32_t CurVol; /* Current Volume count */ DIRRES *director; /* Director resource */ alist *plugin_options; /* Specific Plugin Options sent by DIR */ alist *write_store; /* List of write storage devices sent by DIR */ alist *read_store; /* List of read devices sent by DIR */ alist *reserve_msgs; /* Reserve fail messages */ bool acquired_storage; /* Did we acquire our reserved storage already or not */ bool PreferMountedVols; /* Prefer mounted vols rather than new */ bool Resched; /* Job may be rescheduled */ bool insert_jobmedia_records; /* Need to insert job media records */ uint64_t RemainingQuota; /* Available bytes to use as quota */ /* * Parameters for Open Read Session */ READ_CTX *rctx; /* Read context used to keep track of what is processed or not */ BSR *bsr; /* Bootstrap record -- has everything */ bool mount_next_volume; /* Set to cause next volume mount */ uint32_t read_VolSessionId; uint32_t read_VolSessionTime; uint32_t read_StartFile; uint32_t read_EndFile; uint32_t read_StartBlock; uint32_t read_EndBlock; /* * Device wait times */ int32_t min_wait; int32_t max_wait; int32_t max_num_wait; int32_t wait_sec; int32_t rem_wait_sec; int32_t num_wait; #endif /* STORAGE_DAEMON */ }; /* * Setting a NULL in tsd doesn't clear the tsd but instead tells * pthreads not to call the tsd destructor. Consequently, we * define this *invalid* jcr address and stuff it in the tsd * when the jcr is not valid. */ #define INVALID_JCR ((JCR *)(-1)) /* * Structure for all daemons that keeps some summary * info on the last job run. */ struct s_last_job { dlink link; int32_t Errors; /* FD/SD errors */ int32_t JobType; int32_t JobStatus; int32_t JobLevel; uint32_t JobId; uint32_t VolSessionId; uint32_t VolSessionTime; uint32_t JobFiles; uint64_t JobBytes; utime_t start_time; utime_t end_time; char Job[MAX_NAME_LENGTH]; }; extern struct s_last_job last_job; extern DLL_IMP_EXP dlist *last_jobs; /* * The following routines are found in lib/jcr.c */ extern int get_next_jobid_from_list(char **p, uint32_t *JobId); extern bool init_jcr_subsystem(int timeout); extern JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr); extern JCR *get_jcr_by_id(uint32_t JobId); extern JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime); extern JCR *get_jcr_by_partial_name(char *Job); extern JCR *get_jcr_by_full_name(char *Job); extern JCR *get_next_jcr(JCR *jcr); extern void set_jcr_job_status(JCR *jcr, int JobStatus); extern int DLL_IMP_EXP num_jobs_run; #ifdef DEBUG extern void b_free_jcr(const char *file, int line, JCR *jcr); #define free_jcr(jcr) b_free_jcr(__FILE__, __LINE__, (jcr)) #else extern void free_jcr(JCR *jcr); #endif /* * Used to display specific job information after a fatal signal */ typedef void (dbg_jcr_hook_t)(JCR *jcr, FILE *fp); extern void dbg_jcr_add_hook(dbg_jcr_hook_t *fct); #endif /* __JCR_H_ */ bareos-Release-14.2.6/src/include/streams.h000066400000000000000000000316271263011562700205120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Stream definitions. Split from baconfig.h Nov 2010 * * Kern Sibbald, MM * */ #ifndef __BSTREAMS_H #define __BSTREAMS_H 1 /* * Stream bits -- these bits are new as of 24Nov10 */ #define STREAM_BIT_64 (1 << 30) /* 64 bit stream (not yet implemented) */ #define STREAM_BIT_BITS (1 << 29) /* Following bits may be set */ #define STREAM_BIT_PLUGIN (1 << 28) /* Item written by a plugin */ #define STREAM_BIT_DELTA (1 << 27) /* Stream contains delta data */ #define STREAM_BIT_OFFSETS (1 << 26) /* Stream has data offset */ #define STREAM_BIT_PORTABLE_DATA (1 << 25) /* Data is portable */ /* * TYPE represents our current (old) stream types -- e.g. values 0 - 2047 */ #define STREAMBASE_TYPE 0 /* base for types */ #define STREAMBITS_TYPE 11 /* type bit size */ #define STREAMMASK_TYPE (~((~0)<< STREAMBITS_TYPE) << STREAMBASE_TYPE) /* * Note additional base, bits, and masks can be defined for new * ranges or subranges of stream attributes. */ /** * Old, but currently used Stream definitions. Once defined these must NEVER * change as they go on the storage media. * * Note, the following streams are passed from the SD to the DIR * so that they may be put into the catalog (actually only the * stat packet part of the attr record is put in the catalog. * * STREAM_UNIX_ATTRIBUTES * STREAM_UNIX_ATTRIBUTES_EX * STREAM_MD5_DIGEST * STREAM_SHA1_DIGEST * STREAM_SHA256_DIGEST * STREAM_SHA512_DIGEST */ #define STREAM_NONE 0 /* Reserved Non-Stream */ #define STREAM_UNIX_ATTRIBUTES 1 /* Generic Unix attributes */ #define STREAM_FILE_DATA 2 /* Standard uncompressed data */ #define STREAM_MD5_SIGNATURE 3 /* MD5 signature - Deprecated */ #define STREAM_MD5_DIGEST 3 /* MD5 digest for the file */ #define STREAM_GZIP_DATA 4 /* GZip compressed file data - Deprecated */ #define STREAM_UNIX_ATTRIBUTES_EX 5 /* Extended Unix attr for Win32 EX - Deprecated */ #define STREAM_SPARSE_DATA 6 /* Sparse data stream */ #define STREAM_SPARSE_GZIP_DATA 7 /* Sparse gzipped data stream - Deprecated */ #define STREAM_PROGRAM_NAMES 8 /* Program names for program data */ #define STREAM_PROGRAM_DATA 9 /* Data needing program */ #define STREAM_SHA1_SIGNATURE 10 /* SHA1 signature - Deprecated */ #define STREAM_SHA1_DIGEST 10 /* SHA1 digest for the file */ #define STREAM_WIN32_DATA 11 /* Win32 BackupRead data */ #define STREAM_WIN32_GZIP_DATA 12 /* Gzipped Win32 BackupRead data - Deprecated */ #define STREAM_MACOS_FORK_DATA 13 /* Mac resource fork */ #define STREAM_HFSPLUS_ATTRIBUTES 14 /* Mac OS extra attributes */ #define STREAM_UNIX_ACCESS_ACL 15 /* Standard ACL attributes on UNIX - Deprecated */ #define STREAM_UNIX_DEFAULT_ACL 16 /* Default ACL attributes on UNIX - Deprecated */ #define STREAM_SHA256_DIGEST 17 /* SHA-256 digest for the file */ #define STREAM_SHA512_DIGEST 18 /* SHA-512 digest for the file */ #define STREAM_SIGNED_DIGEST 19 /* Signed File Digest, ASN.1, DER Encoded */ #define STREAM_ENCRYPTED_FILE_DATA 20 /* Encrypted, uncompressed data */ #define STREAM_ENCRYPTED_WIN32_DATA 21 /* Encrypted, uncompressed Win32 BackupRead data */ #define STREAM_ENCRYPTED_SESSION_DATA 22 /* Encrypted, Session Data, ASN.1, DER Encoded */ #define STREAM_ENCRYPTED_FILE_GZIP_DATA 23 /* Encrypted, compressed data - Deprecated */ #define STREAM_ENCRYPTED_WIN32_GZIP_DATA 24 /* Encrypted, compressed Win32 BackupRead data - Deprecated */ #define STREAM_ENCRYPTED_MACOS_FORK_DATA 25 /* Encrypted, uncompressed Mac resource fork */ #define STREAM_PLUGIN_NAME 26 /* Plugin "file" string */ #define STREAM_PLUGIN_DATA 27 /* Plugin specific data */ #define STREAM_RESTORE_OBJECT 28 /* Plugin restore object */ /** * Compressed streams. These streams can handle arbitrary compression algorithm data * as an additional header is stored at the beginning of the stream. * See stream_compressed_header definition for more details. */ #define STREAM_COMPRESSED_DATA 29 /* Compressed file data */ #define STREAM_SPARSE_COMPRESSED_DATA 30 /* Sparse compressed data stream */ #define STREAM_WIN32_COMPRESSED_DATA 31 /* Compressed Win32 BackupRead data */ #define STREAM_ENCRYPTED_FILE_COMPRESSED_DATA 32 /* Encrypted, compressed data */ #define STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA 33 /* Encrypted, compressed Win32 BackupRead data */ #define STREAM_NDMP_SEPERATOR 999 /* NDMP seperator between multiple data streams of one job */ /** * The Stream numbers from 1000-1999 are reserved for ACL and extended attribute streams. * Each different platform has its own stream id(s), if a platform supports multiple stream types * it should supply different handlers for each type it supports and this should be called * from the stream dispatch function. Currently in this reserved space we allocate the * different acl streams from 1000 on and the different extended attributes streams from * 1999 down. So the two naming spaces grow towards each other. */ #define STREAM_ACL_AIX_TEXT 1000 /* AIX specific string representation from acl_get */ #define STREAM_ACL_DARWIN_ACCESS_ACL 1001 /* Darwin (OSX) specific acl_t string representation * from acl_to_text (POSIX acl) */ #define STREAM_ACL_FREEBSD_DEFAULT_ACL 1002 /* FreeBSD specific acl_t string representation * from acl_to_text (POSIX acl) for default acls. */ #define STREAM_ACL_FREEBSD_ACCESS_ACL 1003 /* FreeBSD specific acl_t string representation * from acl_to_text (POSIX acl) for access acls. */ #define STREAM_ACL_HPUX_ACL_ENTRY 1004 /* HPUX specific acl_entry string representation * from acltostr (POSIX acl) */ #define STREAM_ACL_IRIX_DEFAULT_ACL 1005 /* IRIX specific acl_t string representation * from acl_to_text (POSIX acl) for default acls. */ #define STREAM_ACL_IRIX_ACCESS_ACL 1006 /* IRIX specific acl_t string representation * from acl_to_text (POSIX acl) for access acls. */ #define STREAM_ACL_LINUX_DEFAULT_ACL 1007 /* Linux specific acl_t string representation * from acl_to_text (POSIX acl) for default acls. */ #define STREAM_ACL_LINUX_ACCESS_ACL 1008 /* Linux specific acl_t string representation * from acl_to_text (POSIX acl) for access acls. */ #define STREAM_ACL_TRU64_DEFAULT_ACL 1009 /* Tru64 specific acl_t string representation * from acl_to_text (POSIX acl) for default acls. */ #define STREAM_ACL_TRU64_DEFAULT_DIR_ACL 1010 /* Tru64 specific acl_t string representation * from acl_to_text (POSIX acl) for default acls. */ #define STREAM_ACL_TRU64_ACCESS_ACL 1011 /* Tru64 specific acl_t string representation * from acl_to_text (POSIX acl) for access acls. */ #define STREAM_ACL_SOLARIS_ACLENT 1012 /* Solaris specific aclent_t string representation * from acltotext or acl_totext (POSIX acl) */ #define STREAM_ACL_SOLARIS_ACE 1013 /* Solaris specific ace_t string representation from * from acl_totext (NFSv4 or ZFS acl) */ #define STREAM_ACL_AFS_TEXT 1014 /* AFS specific string representation from pioctl */ #define STREAM_ACL_AIX_AIXC 1015 /* AIX specific string representation from * aclx_printStr (POSIX acl) */ #define STREAM_ACL_AIX_NFS4 1016 /* AIX specific string representation from * aclx_printStr (NFSv4 acl) */ #define STREAM_ACL_FREEBSD_NFS4_ACL 1017 /* FreeBSD specific acl_t string representation * from acl_to_text (NFSv4 or ZFS acl) */ #define STREAM_ACL_HURD_DEFAULT_ACL 1018 /* GNU HURD specific acl_t string representation * from acl_to_text (POSIX acl) for default acls. */ #define STREAM_ACL_HURD_ACCESS_ACL 1019 /* GNU HURD specific acl_t string representation * from acl_to_text (POSIX acl) for access acls. */ #define STREAM_ACL_PLUGIN 1020 /* Plugin specific acl encoding */ #define STREAM_XATTR_PLUGIN 1988 /* Plugin specific extended attributes */ #define STREAM_XATTR_HURD 1989 /* GNU HURD specific extended attributes */ #define STREAM_XATTR_IRIX 1990 /* IRIX specific extended attributes */ #define STREAM_XATTR_TRU64 1991 /* TRU64 specific extended attributes */ #define STREAM_XATTR_AIX 1992 /* AIX specific extended attributes */ #define STREAM_XATTR_OPENBSD 1993 /* OpenBSD specific extended attributes */ #define STREAM_XATTR_SOLARIS_SYS 1994 /* Solaris specific extensible attributes or * otherwise named extended system attributes. */ #define STREAM_XATTR_SOLARIS 1995 /* Solaris specific extented attributes */ #define STREAM_XATTR_DARWIN 1996 /* Darwin (OSX) specific extended attributes */ #define STREAM_XATTR_FREEBSD 1997 /* FreeBSD specific extended attributes */ #define STREAM_XATTR_LINUX 1998 /* Linux specific extended attributes */ #define STREAM_XATTR_NETBSD 1999 /* NetBSD specific extended attributes */ /* * WARNING!!! do not define more than 2047 of these old types */ #endif /* __BSTREAMS_H */ bareos-Release-14.2.6/src/include/version.h000066400000000000000000000123641263011562700205160ustar00rootroot00000000000000#undef VERSION #define VERSION "14.2.6" #define BDATE "16 Nov 2015" #define LSMDATE "16Nov15" #define PROG_COPYRIGHT "Copyright (C) %d-2012 Free Software Foundation Europe e.V.\n" \ "Copyright (C) 2013-2015 Bareos GmbH & Co. KG\n" #define BYEAR "2015" /* year for copyright messages in progs */ /* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2013 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Shared object library versions */ /* Uncomment to overwrite default value from VERSION */ /* #define LIBBAREOS_LT_RELEASE "14.2.6" */ /* #define LIBBAREOSCFG_LT_RELEASE "14.2.6" */ /* #define LIBBAREOSSQL_LT_RELEASE "14.2.6" */ /* #define LIBBAREOSCATS_LT_RELEASE "14.2.6" */ /* #define LIBBAREOSNDMP_LT_RELEASE "14.2.6" */ /* #define LIBBAREOSLMDB_LT_RELEASE "14.2.6" */ /* #define LIBBAREOSSD_LT_RELEASE "14.2.6" */ /* Debug flags */ #undef DEBUG #define DEBUG 1 #define TRACEBACK 1 #define TRACE_FILE 1 /* If this is set stdout will not be closed on startup */ /* #define DEVELOPER 1 */ /* adjust DEVELOPER_MODE for status command */ #ifdef DEVELOPER #define DEVELOPER_MODE 1 #else #define DEVELOPER_MODE 0 #endif /* * SMCHECK does orphaned buffer checking (memory leaks) * it can always be turned on, but has some minor performance * penalties. */ #ifdef DEVELOPER #define SMCHECK #endif /* * _USE_LOCKMGR does lock/unlock mutex tracking (dead lock) * it can always be turned on, but we advise to use it only * for debug */ #ifndef _USE_LOCKMGR #define _USE_LOCKMGR #endif /* _USE_LOCKMGR */ /* * Enable priority management with the lock manager * * Note, turning this on will cause the Bareos SD to abort if * mutexes are executed out of order, which could lead to a * deadlock. However, note that this is not necessarily a * deadlock, so turn this on only for debugging. */ #define USE_LOCKMGR_PRIORITY /* * Enable thread verification before kill * * Note, this extra check have a high cost when using * dozens of thread, so turn this only for debugging. */ /* #define USE_LOCKMGR_SAFEKILL */ #if !HAVE_LINUX_OS && !HAVE_SUN_OS && !HAVE_DARWIN_OS && !HAVE_FREEBSD_OS #undef _USE_LOCKMGR #endif /* * for fastest speed but you must have a UPS to avoid unwanted shutdowns */ //#define SQLITE3_INIT_QUERY "PRAGMA synchronous = OFF" /* * for more safety, but is 30 times slower than above */ #define SQLITE3_INIT_QUERY "PRAGMA synchronous = NORMAL" /* * This should always be on. It enables data encryption code * providing it is configured. */ #define DATA_ENCRYPTION 1 /* * This uses a Bareos specific bsnprintf rather than the sys lib * version because it is much more secure. It should always be * on. */ #define USE_BSNPRINTF 1 /* Debug flags not normally turned on */ /* #define TRACE_JCR_CHAIN 1 */ /* #define TRACE_RES 1 */ /* #define DEBUG_MEMSET 1 */ /* #define DEBUG_MUTEX 1 */ /* #define DEBUG_BLOCK_CHECKSUM 1 */ /* * Set SMALLOC_SANITY_CHECK to zero to turn off, otherwise * it is the maximum memory malloced before Bareos will * abort. Except for debug situations, this should be zero */ #define SMALLOC_SANITY_CHECK 0 /* 500000000 0.5 GB max */ /* Check if header of tape block is zero before writing */ /* #define DEBUG_BLOCK_ZEROING 1 */ /* #define FULL_DEBUG 1 */ /* normally on for testing only */ /* Turn this on ONLY if you want all Dmsg() to append to the * trace file. Implemented mainly for Win32 ... */ /* #define SEND_DMSG_TO_FILE 1 */ /* The following are turned on for performance testing */ /* * If you turn on the NO_ATTRIBUTES_TEST and rebuild, the SD * will receive the attributes from the FD, will write them * to disk, then when the data is written to tape, it will * read back the attributes, but they will not be sent to * the Director. So this will eliminate: 1. the comm time * to send the attributes to the Director. 2. the time it * takes the Director to put them in the catalog database. */ /* #define NO_ATTRIBUTES_TEST 1 */ /* * If you turn on NO_TAPE_WRITE_TEST and rebuild, the SD * will do all normal actions, but will not write to the * Volume. Note, this means a lot of functions such as * labeling will not work, so you must use it only when * Bareos is going to append to a Volume. This will eliminate * the time it takes to write to the Volume (not the time * it takes to do any positioning). */ /* #define NO_TAPE_WRITE_TEST 1 */ /* * If you turn on FD_NO_SEND_TEST and rebuild, the FD will * not send any attributes or data to the SD. This will * eliminate the comm time sending to the SD. */ /* #define FD_NO_SEND_TEST 1 */ bareos-Release-14.2.6/src/lib/000077500000000000000000000000001263011562700157755ustar00rootroot00000000000000bareos-Release-14.2.6/src/lib/Makefile.in000066400000000000000000000255601263011562700200520ustar00rootroot00000000000000# @MCOMMON@ # Define library versions LIBBAREOS_LT_RELEASE = @LIBBAREOS_LT_RELEASE@ LIBBAREOSCFG_LT_RELEASE = @LIBBAREOSCFG_LT_RELEASE@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/lib CPPFLAGS += @ZLIB_INC@ COMPRESS_CPPFLAGS += @ZLIB_INC@ @LZO_INC@ @FASTLZ_INC@ DEBUG = @DEBUG@ CAM_LIBS = @CAM_LIBS@ CAP_LIBS = @CAP_LIBS@ ZLIB_LIBS = @ZLIB_LIBS@ LZO_LIBS = @LZO_LIBS@ FASTLZ_LIBS = @FASTLZ_LIBS@ first_rule: all dummy: # # include files installed when using libtool # INCLUDE_FILES = ../include/baconfig.h ../include/bareos.h \ ../include/bc_types.h ../include/config.h \ ../include/jcr.h ../include/version.h \ address_conf.h alist.h attr.h base64.h berrno.h \ bits.h bpipe.h breg.h bregex.h bsock.h bsock_sctp.h \ bsock_tcp.h bsock_udt.h bsr.h btime.h btimers.h cbuf.h \ crypto.h crypto_cache.h devlock.h dlist.h fnmatch.h \ guid_to_name.h htable.h ini.h lex.h lib.h lockmgr.h \ md5.h mem_pool.h message.h mntent_cache.h parse_conf.h \ plugins.h protos.h queue.h rblist.h runscript.h rwlock.h \ scsi_crypto.h scsi_lli.h scsi_tapealert.h sellist.h \ serial.h sha1.h smartall.h status.h tls.h tree.h var.h \ waitq.h watchdog.h workq.h # # libbareos # LIBBAREOS_SRCS = address_conf.c alist.c attr.c attribs.c base64.c \ berrno.c bget_msg.c binflate.c bnet_server_tcp.c bnet.c \ bpipe.c breg.c bregex.c bsnprintf.c bsock.c bsock_sctp.c \ bsock_tcp.c bsock_udt.c bsys.c btime.c btimers.c \ cbuf.c compression.c cram-md5.c crypto.c crypto_cache.c \ crypto_gnutls.c crypto_none.c crypto_nss.c crypto_openssl.c \ crypto_wrap.c daemon.c devlock.c dlist.c edit.c fnmatch.c \ guid_to_name.c hmac.c htable.c jcr.c lockmgr.c md5.c \ mem_pool.c message.c mntent_cache.c passphrase.c plugins.c \ poll.c priv.c queue.c rblist.c runscript.c rwlock.c scan.c \ scsi_crypto.c scsi_lli.c scsi_tapealert.c sellist.c serial.c \ sha1.c signal.c smartall.c tls_gnutls.c tls_none.c tls_nss.c \ tls_openssl.c tree.c util.c var.c watchdog.c workq.c LIBBAREOS_OBJS = $(LIBBAREOS_SRCS:.c=.o) LIBBAREOS_LOBJS = $(LIBBAREOS_SRCS:.c=.lo) # # libbareoscfg (config functions) # LIBBAREOSCFG_SRCS = ini.c lex.c parse_bsr.c parse_conf.c res.c LIBBAREOSCFG_OBJS = $(LIBBAREOSCFG_SRCS:.c=.o) LIBBAREOSCFG_LOBJS = $(LIBBAREOSCFG_SRCS:.c=.lo) INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .cc .o .lo .ch .dvi .pdf .tex .view .w .1 .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< .c.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile libbareos$(DEFAULT_ARCHIVE_TYPE) libbareoscfg$(DEFAULT_ARCHIVE_TYPE) @echo "==== Make of lib is good ====" @echo " " crypto_openssl.o: crypto_openssl.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(CXXFLAGS) $< crypto_openssl.lo: crypto_openssl.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(CXXFLAGS) $< tls_openssl.o: tls_openssl.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(CXXFLAGS) $< tls_openssl.lo: tls_openssl.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(CXXFLAGS) $< crypto_gnutls.o: crypto_gnutls.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< crypto_gnutls.lo: crypto_gnutls.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< tls_gnutls.o: tls_gnutls.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< tls_gnutls.lo: tls_gnutls.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< crypto_wrap.o: crypto_wrap.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< crypto_wrap.lo: crypto_wrap.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< passphrase.o: passphrase.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< passphrase.lo: passphrase.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(OPENSSL_INCLUDES) $(GNUTLS_INCLUDES) $(CXXFLAGS) $< compression.o: compression.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(COMPRESS_CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< compression.lo: compression.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(COMPRESS_CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< libbareos.a: $(LIBBAREOS_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOS_OBJS) $(RANLIB) $@ libbareos.la: Makefile $(LIBBAREOS_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -o $@ $(LIBBAREOS_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOS_LT_RELEASE) \ $(WRAPLIBS) $(CAM_LIBS) $(CAP_LIBS) $(ZLIB_LIBS) $(LZO_LIBS) $(FASTLZ_LIBS) $(OPENSSL_LIBS) $(GNUTLS_LIBS) $(LIBS) $(DLLIBS) libbareoscfg.a: $(LIBBAREOSCFG_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOSCFG_OBJS) $(RANLIB) $@ libbareoscfg.la: Makefile $(LIBBAREOSCFG_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -o $@ $(LIBBAREOSCFG_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOSCFG_LT_RELEASE) \ $(LIBS) -lbareos Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status lockmgr_test: Makefile $(RMF) lockmgr.o $(CXX) -D _TEST_IT $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) lockmgr.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ lockmgr.o $(DLIB) -lbareos -lm $(LIBS) rm -f lockmgr.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) lockmgr.c base64_test: Makefile $(RMF) base64.o $(CXX) -DBIN_TEST $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) base64.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ base64.o $(DLIB) -lbareos -lm $(LIBS) rm -f base64.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) base64.c rwlock_test: Makefile $(RMF) rwlock.o $(CXX) -DTEST_RWLOCK $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) rwlock.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ rwlock.o $(DLIB) -lbareos -lm $(LIBS) rm -f rwlock.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) rwlock.c devlock_test: Makefile $(RMF) devlock.o $(CXX) -DTEST_devlock $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) devlock.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ devlock.o $(DLIB) -lbareos -lm $(LIBS) $(RMF) devlock.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) devlock.c htable_test: Makefile $(RMF) htable.o $(CXX) -DTEST_SMALL_HTABLE -DTEST_NON_CHAR -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) htable.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ htable.o $(DLIB) -lbareos -lm $(LIBS) $(RMF) htable.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) htable.c md5sum: Makefile md5.o $(RMF) md5.o $(CXX) -DMD5_SUM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) md5.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ md5.o $(DLIB) -lbareos -lm $(LIBS) $(RMF) md5.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) md5.c bsnprintf: Makefile bsnprintf.o $(RMF) bsnprintf.o $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) bsnprintf.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ bsnprintf.o $(DLIB) -lbareos -lm $(LIBS) $(RMF) bsnprintf.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) bsnprintf.c ini: Makefile ini.o $(RMF) ini.o $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) ini.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ ini.o -lbareoscfg -lbareos $(DLIB) -lm $(LIBS) $(RMF) ini.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) ini.c install-includes: $(MKDIR) $(DESTDIR)/$(includedir)/bareos for I in $(INCLUDE_FILES); do \ $(INSTALL_DATA) $$I $(DESTDIR)$(includedir)/bareos/`basename $$I`; \ done libtool-install: all $(MKDIR) $(DESTDIR)$(libdir) $(RMF) $(DESTDIR)$(libdir)/libbareos-[0-9]*.so $(DESTDIR)$(libdir)/libbareos.la $(RMF) $(DESTDIR)$(libdir)/libbareoscfg-[0-9]*.so $(DESTDIR)$(libdir)/libbareoscfg.la $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareos.la $(DESTDIR)$(libdir) $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareoscfg.la $(DESTDIR)$(libdir) install: @LIBTOOL_INSTALL_TARGET@ @INCLUDE_INSTALL_TARGET@ libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) core a.out *.o *.bak *.tex *.pdf *~ *.intpro *.extpro 1 2 3 @$(RMF) rwlock_test md5sum realclean: clean @$(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) # Semi-automatic generation of dependencies: # Use gcc -M because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @for src in $(LIBBAREOS_SRCS) $(LIBBAREOSCFG_SRCS); do \ $(CXX) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(INCLUDES) $$src >> Makefile; \ done @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/lib/address_conf.c000066400000000000000000000255671263011562700206120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Configuration file parser for IP-Addresse ipv4 and ipv6 * * Written by Meno Abels, June MMIV */ #include "bareos.h" #ifdef HAVE_ARPA_NAMESER_H #include #endif #ifdef HAVE_RESOLV_H //#include #endif IPADDR::IPADDR(const IPADDR &src) : type(src.type) { memcpy(&saddrbuf, &src.saddrbuf, sizeof(saddrbuf)); saddr = &saddrbuf.dontuse; saddr4 = &saddrbuf.dontuse4; #ifdef HAVE_IPV6 saddr6 = &saddrbuf.dontuse6; #endif } IPADDR::IPADDR(int af) : type(R_EMPTY) { #ifdef HAVE_IPV6 if (!(af == AF_INET6 || af == AF_INET)) { Emsg1(M_ERROR_TERM, 0, _("Only ipv4 and ipv6 are supported (%d)\n"), af); } #else if (af != AF_INET) { Emsg1(M_ERROR_TERM, 0, _("Only ipv4 is supported (%d)\n"), af); } #endif memset(&saddrbuf, 0, sizeof(saddrbuf)); saddr = &saddrbuf.dontuse; saddr4 = &saddrbuf.dontuse4; #ifdef HAVE_IPV6 saddr6 = &saddrbuf.dontuse6; #endif saddr->sa_family = af; if (af == AF_INET) { saddr4->sin_port = 0xffff; } #ifdef HAVE_IPV6 else { saddr6->sin6_port = 0xffff; } #endif #ifdef HAVE_SA_LEN #ifdef HAVE_IPV6 saddr->sa_len = (af == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); #else saddr->sa_len = sizeof(sockaddr_in); #endif #endif set_addr_any(); } void IPADDR::set_type(i_type o) { type = o; } IPADDR::i_type IPADDR::get_type() const { return type; } unsigned short IPADDR::get_port_net_order() const { unsigned short port = 0; if (saddr->sa_family == AF_INET) { port = saddr4->sin_port; } #ifdef HAVE_IPV6 else { port = saddr6->sin6_port; } #endif return port; } void IPADDR::set_port_net(unsigned short port) { if (saddr->sa_family == AF_INET) { saddr4->sin_port = port; } #ifdef HAVE_IPV6 else { saddr6->sin6_port = port; } #endif } int IPADDR::get_family() const { return saddr->sa_family; } struct sockaddr *IPADDR::get_sockaddr() { return saddr; } int IPADDR::get_sockaddr_len() { #ifdef HAVE_IPV6 return saddr->sa_family == AF_INET ? sizeof(*saddr4) : sizeof(*saddr6); #else return sizeof(*saddr4); #endif } void IPADDR::copy_addr(IPADDR *src) { if (saddr->sa_family == AF_INET) { saddr4->sin_addr.s_addr = src->saddr4->sin_addr.s_addr; } #ifdef HAVE_IPV6 else { saddr6->sin6_addr = src->saddr6->sin6_addr; } #endif } void IPADDR::set_addr_any() { if (saddr->sa_family == AF_INET) { saddr4->sin_addr.s_addr = INADDR_ANY; } #ifdef HAVE_IPV6 else { saddr6->sin6_addr= in6addr_any; } #endif } void IPADDR::set_addr4(struct in_addr *ip4) { if (saddr->sa_family != AF_INET) { Emsg1(M_ERROR_TERM, 0, _("It was tried to assign a ipv6 address to a ipv4(%d)\n"), saddr->sa_family); } saddr4->sin_addr = *ip4; } #ifdef HAVE_IPV6 void IPADDR::set_addr6(struct in6_addr *ip6) { if (saddr->sa_family != AF_INET6) { Emsg1(M_ERROR_TERM, 0, _("It was tried to assign a ipv4 address to a ipv6(%d)\n"), saddr->sa_family); } saddr6->sin6_addr = *ip6; } #endif const char *IPADDR::get_address(char *outputbuf, int outlen) { outputbuf[0] = '\0'; #ifdef HAVE_INET_NTOP # ifdef HAVE_IPV6 inet_ntop(saddr->sa_family, saddr->sa_family == AF_INET ? (void*)&(saddr4->sin_addr) : (void*)&(saddr6->sin6_addr), outputbuf, outlen); # else inet_ntop(saddr->sa_family, (void*)&(saddr4->sin_addr), outputbuf, outlen); # endif #else bstrncpy(outputbuf, inet_ntoa(saddr4->sin_addr), outlen); #endif return outputbuf; } const char *IPADDR::build_config_str(char *buf, int blen) { char tmp[1024]; bsnprintf(buf, blen, " %s = {\n" " addr = %s\n" " port = %hu\n" " }", get_family() == AF_INET ? "ipv4" : "ipv6", get_address(tmp, sizeof(tmp) - 1), get_port_host_order()); return buf; } const char *IPADDR::build_address_str(char *buf, int blen, bool print_port/*=true*/) { char tmp[1024]; if (print_port) { bsnprintf(buf, blen, "host[%s;%s;%hu] ", get_family() == AF_INET ? "ipv4" : "ipv6", get_address(tmp, sizeof(tmp) - 1), get_port_host_order()); } else { bsnprintf(buf, blen, "host[%s;%s] ", get_family() == AF_INET ? "ipv4" : "ipv6", get_address(tmp, sizeof(tmp) - 1)); } return buf; } const char *build_addresses_str(dlist *addrs, char *buf, int blen, bool print_port/*=true*/) { if (!addrs || addrs->size() == 0) { bstrncpy(buf, "", blen); return buf; } char *work = buf; IPADDR *p; foreach_dlist(p, addrs) { char tmp[1024]; int len = bsnprintf(work, blen, "%s", p->build_address_str(tmp, sizeof(tmp), print_port)); if (len < 0) break; work += len; blen -= len; } return buf; } const char *get_first_address(dlist *addrs, char *outputbuf, int outlen) { return ((IPADDR *)(addrs->first()))->get_address(outputbuf, outlen); } int get_first_port_net_order(dlist *addrs) { if (!addrs) { return 0; } else { return ((IPADDR *)(addrs->first()))->get_port_net_order(); } } int get_first_port_host_order(dlist *addrs) { if (!addrs) { return 0; } else { return ((IPADDR *)(addrs->first()))->get_port_host_order(); } } int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultport, int family, const char *hostname_str, const char *port_str, char *buf, int buflen) { IPADDR *iaddr; IPADDR *jaddr; dlist *hostaddrs; unsigned short port; IPADDR::i_type intype = type; buf[0] = 0; dlist *addrs = (dlist *)(*(out)); if (!addrs) { IPADDR *tmp = 0; addrs = *out = New(dlist(tmp, &tmp->link)); } type = (type == IPADDR::R_SINGLE_PORT || type == IPADDR::R_SINGLE_ADDR) ? IPADDR::R_SINGLE : type; if (type != IPADDR::R_DEFAULT) { IPADDR *def = 0; foreach_dlist(iaddr, addrs) { if (iaddr->get_type() == IPADDR::R_DEFAULT) { def = iaddr; } else if (iaddr->get_type() != type) { bsnprintf(buf, buflen, _("the old style addresses cannot be mixed with new style")); return 0; } } if (def) { addrs->remove(def); delete def; } } if (!port_str || port_str[0] == '\0') { port = defaultport; } else { int pnum = atol(port_str); if (0 < pnum && pnum < 0xffff) { port = htons(pnum); } else { struct servent *s = getservbyname(port_str, "tcp"); if (s) { port = s->s_port; } else { bsnprintf(buf, buflen, _("can't resolve service(%s)"), port_str); return 0; } } } const char *myerrstr; hostaddrs = bnet_host2ipaddrs(hostname_str, family, &myerrstr); if (!hostaddrs) { bsnprintf(buf, buflen, _("can't resolve hostname(%s) %s"), hostname_str, myerrstr); return 0; } if (intype == IPADDR::R_SINGLE_PORT || intype == IPADDR::R_SINGLE_ADDR) { IPADDR *addr; if (addrs->size()) { addr = (IPADDR *)addrs->first(); } else { addr = New(IPADDR(family)); addr->set_type(type); addr->set_port_net(defaultport); addr->set_addr_any(); addrs->append(addr); } if (intype == IPADDR::R_SINGLE_PORT) { addr->set_port_net(port); } if (intype == IPADDR::R_SINGLE_ADDR) { addr->copy_addr((IPADDR *)(hostaddrs->first())); } } else { foreach_dlist(iaddr, hostaddrs) { IPADDR *clone; /* for duplicates */ foreach_dlist(jaddr, addrs) { if (iaddr->get_sockaddr_len() == jaddr->get_sockaddr_len() && !memcmp(iaddr->get_sockaddr(), jaddr->get_sockaddr(), iaddr->get_sockaddr_len())) { goto skip; /* no price */ } } clone = New(IPADDR(*iaddr)); clone->set_type(type); clone->set_port_net(port); addrs->append(clone); skip: continue; } } free_addresses(hostaddrs); return 1; } void init_default_addresses(dlist **out, const char *port) { char buf[1024]; unsigned short sport = str_to_int32(port); if (!add_address(out, IPADDR::R_DEFAULT, htons(sport), AF_INET, 0, 0, buf, sizeof(buf))) { Emsg1(M_ERROR_TERM, 0, _("Can't add default address (%s)\n"), buf); } } void free_addresses(dlist * addrs) { while (!addrs->empty()) { IPADDR *ptr = (IPADDR*)addrs->first(); addrs->remove(ptr); delete ptr; } delete addrs; } int sockaddr_get_port_net_order(const struct sockaddr *client_addr) { if (client_addr->sa_family == AF_INET) { return ((struct sockaddr_in *)client_addr)->sin_port; } #ifdef HAVE_IPV6 else { return ((struct sockaddr_in6 *)client_addr)->sin6_port; } #endif return -1; } int sockaddr_get_port(const struct sockaddr *client_addr) { if (client_addr->sa_family == AF_INET) { return ntohs(((struct sockaddr_in *)client_addr)->sin_port); } #ifdef HAVE_IPV6 else { return ntohs(((struct sockaddr_in6 *)client_addr)->sin6_port); } #endif return -1; } char *sockaddr_to_ascii(const struct sockaddr *sa, char *buf, int len) { #ifdef HAVE_INET_NTOP /* MA Bug 5 the problem was that i mixed up sockaddr and in_addr */ inet_ntop(sa->sa_family, # ifdef HAVE_IPV6 sa->sa_family == AF_INET ? (void*)&(((struct sockaddr_in*)sa)->sin_addr) : (void*)&(((struct sockaddr_in6*)sa)->sin6_addr), # else (void*)&(((struct sockaddr_in*)sa)->sin_addr), # endif /* HAVE_IPV6 */ buf, len); #else bstrncpy(buf, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), len); #endif return buf; } #ifdef HAVE_OLD_SOCKOPT int inet_aton(const char *cp, struct in_addr *inp) { struct in_addr inaddr; if((inaddr.s_addr = inet_addr(cp)) != INADDR_NONE) { inp->s_addr = inaddr.s_addr; return 1; } return 0; } #endif bareos-Release-14.2.6/src/lib/address_conf.h000066400000000000000000000057021263011562700206040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by Meno Abels, June MMIV */ class IPADDR : public SMARTALLOC { public: typedef enum { R_SINGLE, R_SINGLE_PORT, R_SINGLE_ADDR, R_MULTIPLE, R_DEFAULT, R_EMPTY } i_type; IPADDR(int af); IPADDR(const IPADDR & src); private: IPADDR() { /* block this construction */ } i_type type; union { struct sockaddr dontuse; struct sockaddr_in dontuse4; #ifdef HAVE_IPV6 struct sockaddr_in6 dontuse6; #endif } saddrbuf; struct sockaddr *saddr; struct sockaddr_in *saddr4; #ifdef HAVE_IPV6 struct sockaddr_in6 *saddr6; #endif public: void set_type(i_type o); i_type get_type() const; unsigned short get_port_net_order() const; unsigned short get_port_host_order() const { return ntohs(get_port_net_order()); } void set_port_net(unsigned short port); int get_family() const; struct sockaddr *get_sockaddr(); int get_sockaddr_len(); void copy_addr(IPADDR * src); void set_addr_any(); void set_addr4(struct in_addr *ip4); #ifdef HAVE_IPV6 void set_addr6(struct in6_addr *ip6); #endif const char *get_address(char *outputbuf, int outlen); const char *build_config_str(char *buf, int blen); const char *build_address_str(char *buf, int blen, bool print_port=true); /* private */ dlink link; }; void init_default_addresses(dlist ** addr, const char *port); void free_addresses(dlist * addrs); const char *get_first_address(dlist * addrs, char *outputbuf, int outlen); int get_first_port_net_order(dlist * addrs); int get_first_port_host_order(dlist * addrs); int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultport, int family, const char *hostname_str, const char *port_str, char *buf, int buflen); const char *build_addresses_str(dlist *addrs, char *buf, int blen, bool print_port=true); int sockaddr_get_port_net_order(const struct sockaddr *sa); int sockaddr_get_port(const struct sockaddr *sa); char *sockaddr_to_ascii(const struct sockaddr *sa, char *buf, int len); #ifdef WIN32 #undef HAVE_OLD_SOCKOPT #endif #ifdef HAVE_OLD_SOCKOPT int inet_aton(const char *cp, struct in_addr *inp); #endif bareos-Release-14.2.6/src/lib/alist.c000066400000000000000000000102541263011562700172570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS array list routines * * alist is a simple malloc'ed array of pointers. For the moment, * it simply malloc's a bigger array controlled by num_grow. * Default is to realloc the pointer array for each new member. * * Kern Sibbald, June MMIII */ #include "bareos.h" /* * Private grow list function. Used to insure that * at least one more "slot" is available. */ void alist::grow_list() { if (items == NULL) { if (num_grow == 0) { num_grow = 1; /* default if not initialized */ } items = (void **)malloc(num_grow * sizeof(void *)); max_items = num_grow; } else if (num_items == max_items) { max_items += num_grow; items = (void **)realloc(items, max_items * sizeof(void *)); } } void *alist::first() { cur_item = 1; if (num_items == 0) { return NULL; } else { return items[0]; } } void *alist::last() { if (num_items == 0) { return NULL; } else { cur_item = num_items; return items[num_items-1]; } } void *alist::next() { if (cur_item >= num_items) { return NULL; } else { return items[cur_item++]; } } void *alist::prev() { if (cur_item <= 1) { return NULL; } else { return items[--cur_item]; } } /* * prepend an item to the list -- i.e. add to beginning */ void alist::prepend(void *item) { grow_list(); if (num_items == 0) { items[num_items++] = item; return; } for (int i=num_items; i > 0; i--) { items[i] = items[i-1]; } items[0] = item; num_items++; } /* * Append an item to the list */ void alist::append(void *item) { grow_list(); items[num_items++] = item; } /* Remove an item from the list */ void * alist::remove(int index) { void *item; if (index < 0 || index >= num_items) { return NULL; } item = items[index]; num_items--; for (int i=index; i < num_items; i++) { items[i] = items[i+1]; } return item; } /* Get the index item -- we should probably allow real indexing here */ void * alist::get(int index) { if (index < 0 || index >= num_items) { return NULL; } return items[index]; } /* Destroy the list and its contents */ void alist::destroy() { if (items) { if (own_items) { for (int i=0; imylist.init(); printf("Manual allocation/destruction of list:\n"); for (int i=0; i<20; i++) { sprintf(buf, "This is item %d", i); fileset->mylist.append(bstrdup(buf)); } for (int i=0; i< fileset->mylist.size(); i++) { printf("Item %d = %s\n", i, (char *)fileset->mylist[i]); } fileset->mylist.destroy(); free(fileset); printf("Allocation/destruction using new delete\n"); mlist = new alist(10); for (int i=0; i<20; i++) { sprintf(buf, "This is item %d", i); mlist->append(bstrdup(buf)); } for (int i=0; i< mlist->size(); i++) { printf("Item %d = %s\n", i, (char *)mlist->get(i)); } delete mlist; sm_dump(false); /* test program */ } #endif bareos-Release-14.2.6/src/lib/alist.h000066400000000000000000000101171263011562700172620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, June MMIII */ /* * There is a lot of extra casting here to work around the fact * that some compilers (Sun and Visual C++) do not accept * (void *) as an lvalue on the left side of an equal. * * Loop var through each member of list * Loop var through each member of list using an increasing index. * Loop var through each member of list using an decreasing index. */ #ifdef HAVE_TYPEOF #define foreach_alist(var, list) \ for ((var)=(typeof((var)))(list)->first(); (var); (var) = (typeof(var))(list)->next()) #define foreach_alist_index(inx, var, list) \ for ((inx) = 0; ((var) = (typeof((var)))(list)->get((inx))); (inx)++ ) #define foreach_alist_rindex(inx, var, list) \ for ((inx) = ((list)->size() - 1); ((var) = (typeof((var)))(list)->get((inx))); (inx)--) #else #define foreach_alist(var, list) \ for ((*((void **)&(var))=(void*)((list)->first())); \ (var); \ (*((void **)&(var))=(void*)((list)->next()))) #define foreach_alist_index(inx, var, list) \ for ((inx) = 0; ((*((void **)&(var)) = (void*)((list)->get((inx))))); (inx)++) #define foreach_alist_rindex(inx, var, list) \ for ((inx) = ((list)->size() - 1); ((*((void **)&(var)) = (void*)((list)->get((inx))))); (inx)--) #endif /* * Second arg of init */ enum { owned_by_alist = true, not_owned_by_alist = false }; /* * Array list -- much like a simplified STL vector * array of pointers to inserted items */ class alist : public SMARTALLOC { void **items; int num_items; int max_items; int num_grow; int cur_item; bool own_items; void grow_list(void); public: alist(int num = 1, bool own=true); ~alist(); void init(int num = 1, bool own=true); void append(void *item); void prepend(void *item); void *remove(int index); void *get(int index); bool empty() const; void *prev(); void *next(); void *first(); void *last(); void * operator [](int index) const; int current() const { return cur_item; }; int size() const; void destroy(); void grow(int num); /* * Use it as a stack, pushing and poping from the end */ void push(void *item) { append(item); }; void *pop() { return remove(num_items - 1); }; }; /* * Define index operator [] */ inline void * alist::operator [](int index) const { if (index < 0 || index >= num_items) { return NULL; } return items[index]; } inline bool alist::empty() const { /* Check for null pointer */ return this ? num_items == 0 : true; } /* * This allows us to do explicit initialization, * allowing us to mix C++ classes inside malloc'ed * C structures. Define before called in constructor. */ inline void alist::init(int num, bool own) { items = NULL; num_items = 0; max_items = 0; num_grow = num; own_items = own; } /* Constructor */ inline alist::alist(int num, bool own) { init(num, own); } /* Destructor */ inline alist::~alist() { destroy(); } /* Current size of list */ inline int alist::size() const { /* * Check for null pointer, which allows test * on size to succeed even if nothing put in * alist. */ return this ? num_items : 0; } /* How much to grow by each time */ inline void alist::grow(int num) { num_grow = num; } bareos-Release-14.2.6/src/lib/attr.c000066400000000000000000000215021263011562700171130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * attr.c Unpack an Attribute record returned from the tape * * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated) */ #include "bareos.h" #include "jcr.h" #include "lib/breg.h" static const int dbglvl = 150; ATTR *new_attr(JCR *jcr) { ATTR *attr = (ATTR *)malloc(sizeof(ATTR)); memset(attr, 0, sizeof(ATTR)); attr->ofname = get_pool_memory(PM_FNAME); attr->olname = get_pool_memory(PM_FNAME); attr->attrEx = get_pool_memory(PM_FNAME); attr->jcr = jcr; attr->uid = getuid(); return attr; } void free_attr(ATTR *attr) { free_pool_memory(attr->olname); free_pool_memory(attr->ofname); free_pool_memory(attr->attrEx); free(attr); } int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, int32_t reclen, ATTR *attr) { char *p; int object_len; /* * An Attributes record consists of: * File_index * Type (FT_types) * Filename * Attributes * Link name (if file linked i.e. FT_LNK) * Extended attributes (Win32) * plus optional values determined by AR_ flags in upper bits of Type * Data_stream * */ attr->stream = stream; Dmsg1(dbglvl, "Attr: %s\n", rec); if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) { Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec); Dmsg1(dbglvl, "\nError scanning attributes. %s\n", rec); return 0; } Dmsg2(dbglvl, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type); /* * Note AR_DATA_STREAM should never be set since it is encoded * at the end of the attributes. */ if (attr->type & AR_DATA_STREAM) { attr->data_stream = 1; } else { attr->data_stream = 0; } attr->type &= FT_MASK; /* keep only type bits */ p = rec; while (*p++ != ' ') /* skip record file index */ { } while (*p++ != ' ') /* skip type */ { } attr->fname = p; /* set filname position */ while (*p++ != 0) /* skip filename */ { } attr->attr = p; /* set attributes position */ while (*p++ != 0) /* skip attributes */ { } attr->lname = p; /* set link position */ while (*p++ != 0) /* skip link */ { } attr->delta_seq = 0; if (attr->type == FT_RESTORE_FIRST) { /* We have an object, so do a binary copy */ object_len = reclen + rec - p; attr->attrEx = check_pool_memory_size(attr->attrEx, object_len + 1); memcpy(attr->attrEx, p, object_len); /* Add a EOS for those who attempt to print the object */ p = attr->attrEx + object_len; *p = 0; } else { pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */ if (attr->data_stream) { int64_t val; while (*p++ != 0) /* skip extended attributes */ { } from_base64(&val, p); attr->data_stream = (int32_t)val; } else { while (*p++ != 0) /* skip extended attributes */ { } if (p - rec < reclen) { attr->delta_seq = str_to_int32(p); /* delta_seq */ } } } Dmsg8(dbglvl, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s datastr=%d delta_seq=%d\n", attr->file_index, attr->type, attr->fname, attr->attr, attr->lname, attr->attrEx, attr->data_stream, attr->delta_seq); *attr->ofname = 0; *attr->olname = 0; return 1; } #if defined(HAVE_WIN32) static void strip_double_slashes(char *fname) { char *p = fname; while (p && *p) { p = strpbrk(p, "/\\"); if (p != NULL) { if (IsPathSeparator(p[1])) { strcpy(p, p+1); } p++; } } } #endif /* * Build attr->ofname from attr->fname and * attr->olname from attr->olname */ void build_attr_output_fnames(JCR *jcr, ATTR *attr) { /* * Prepend the where directory so that the * files are put where the user wants. * * We do a little jig here to handle Win32 files with * a drive letter -- we simply change the drive * from, for example, c: to c/ for * every filename if a prefix is supplied. * */ if (jcr->where_bregexp) { char *ret; apply_bregexps(attr->fname, jcr->where_bregexp, &ret); pm_strcpy(attr->ofname, ret); if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) { /* Always add prefix to hard links (FT_LNKSAVED) and * on user request to soft links */ if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) { apply_bregexps(attr->lname, jcr->where_bregexp, &ret); pm_strcpy(attr->olname, ret); } else { pm_strcpy(attr->olname, attr->lname); } } } else if (jcr->where[0] == 0) { pm_strcpy(attr->ofname, attr->fname); pm_strcpy(attr->olname, attr->lname); } else { const char *fn; int wherelen = strlen(jcr->where); pm_strcpy(attr->ofname, jcr->where); /* copy prefix */ #if defined(HAVE_WIN32) if (attr->fname[1] == ':') { attr->fname[1] = '/'; /* convert : to / */ } #endif fn = attr->fname; /* take whole name */ /* Ensure where is terminated with a slash */ if (!IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) { pm_strcat(attr->ofname, "/"); } pm_strcat(attr->ofname, fn); /* copy rest of name */ /* * Fixup link name -- if it is an absolute path */ if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) { bool add_link; /* Always add prefix to hard links (FT_LNKSAVED) and * on user request to soft links */ if (IsPathSeparator(attr->lname[0]) && (attr->type == FT_LNKSAVED || jcr->prefix_links)) { pm_strcpy(attr->olname, jcr->where); add_link = true; } else { attr->olname[0] = 0; add_link = false; } fn = attr->lname; /* take whole name */ /* Ensure where is terminated with a slash */ if (add_link && !IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) { pm_strcat(attr->olname, "/"); } pm_strcat(attr->olname, fn); /* copy rest of link */ } } #if defined(HAVE_WIN32) strip_double_slashes(attr->ofname); strip_double_slashes(attr->olname); #endif } extern char *getuser(uid_t uid, char *name, int len); extern char *getgroup(gid_t gid, char *name, int len); /* * Print an ls style message, also send M_RESTORED */ void print_ls_output(JCR *jcr, ATTR *attr) { char buf[5000]; char ec1[30]; char en1[30], en2[30]; char *p, *f; guid_list *guid; if (attr->type == FT_DELETED) { /* TODO: change this to get last seen values */ bsnprintf(buf, sizeof(buf), "---------- - - - - ---------- -------- %s\n", attr->ofname); Dmsg1(dbglvl, "%s", buf); Jmsg(jcr, M_RESTORED, 1, "%s", buf); return; } if (!jcr->id_list) { jcr->id_list = new_guid_list(); } guid = jcr->id_list; p = encode_mode(attr->statp.st_mode, buf); p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink); p += sprintf(p, "%-8.8s %-8.8s", guid->uid_to_name(attr->statp.st_uid, en1, sizeof(en1)), guid->gid_to_name(attr->statp.st_gid, en2, sizeof(en2))); p += sprintf(p, "%12.12s ", edit_int64(attr->statp.st_size, ec1)); p = encode_time(attr->statp.st_ctime, p); *p++ = ' '; *p++ = ' '; for (f=attr->ofname; *f && (p-buf) < (int)sizeof(buf)-10; ) { *p++ = *f++; } if (attr->type == FT_LNK) { *p++ = ' '; *p++ = '-'; *p++ = '>'; *p++ = ' '; /* Copy link name */ for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) { *p++ = *f++; } } *p++ = '\n'; *p = 0; Dmsg1(dbglvl, "%s", buf); Jmsg(jcr, M_RESTORED, 1, "%s", buf); } bareos-Release-14.2.6/src/lib/attr.h000066400000000000000000000040751263011562700171260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * attr.h Definition of attributes packet for unpacking from tape * * Kern Sibbald, June MMIII */ #ifndef __ATTR_H_ #define __ATTR_H_ 1 struct ATTR { int32_t stream; /* attribute stream id */ int32_t data_stream; /* id of data stream to follow */ int32_t type; /* file type FT */ int32_t file_index; /* file index */ int32_t LinkFI; /* file index to data if hard link */ int32_t delta_seq; /* delta sequence numbr */ uid_t uid; /* userid */ struct stat statp; /* decoded stat packet */ POOLMEM *attrEx; /* extended attributes if any */ POOLMEM *ofname; /* output filename */ POOLMEM *olname; /* output link name */ /* * Note the following three variables point into the * current BSOCK record, so they are invalid after * the next socket read! */ char *attr; /* attributes position */ char *fname; /* filename */ char *lname; /* link name if any */ JCR *jcr; /* jcr pointer */ }; #endif /* __ATTR_H_ */ bareos-Release-14.2.6/src/lib/attribs.c000066400000000000000000000165041263011562700176170ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Encode and decode standard Unix attributes * * Kern Sibbald, October MMII */ #include "bareos.h" /** * Encode a stat structure into a base64 character string * All systems must create such a structure. * In addition, we tack on the LinkFI, which is non-zero in * the case of a hard linked file that has no data. This * is a File Index pointing to the link that does have the * data (always the first one encountered in a save). * You may piggyback attributes on this packet by encoding * them in the encode_attribsEx() subroutine, but this is * not recommended. */ void encode_stat(char *buf, struct stat *statp, int stat_size, int32_t LinkFI, int data_stream) { char *p = buf; /* * We read the stat packet so make sure the caller's conception * is the same as ours. They can be different if LARGEFILE is not * the same when compiling this library and the calling program. */ ASSERT(stat_size == (int)sizeof(struct stat)); /** * Encode a stat packet. I should have done this more intelligently * with a length so that it could be easily expanded. */ p += to_base64((int64_t)statp->st_dev, p); *p++ = ' '; /* separate fields with a space */ p += to_base64((int64_t)statp->st_ino, p); *p++ = ' '; p += to_base64((int64_t)statp->st_mode, p); *p++ = ' '; p += to_base64((int64_t)statp->st_nlink, p); *p++ = ' '; p += to_base64((int64_t)statp->st_uid, p); *p++ = ' '; p += to_base64((int64_t)statp->st_gid, p); *p++ = ' '; p += to_base64((int64_t)statp->st_rdev, p); *p++ = ' '; p += to_base64((int64_t)statp->st_size, p); *p++ = ' '; #ifndef HAVE_MINGW p += to_base64((int64_t)statp->st_blksize, p); *p++ = ' '; p += to_base64((int64_t)statp->st_blocks, p); *p++ = ' '; #else p += to_base64((int64_t)0, p); /* output place holder */ *p++ = ' '; p += to_base64((int64_t)0, p); /* output place holder */ *p++ = ' '; #endif p += to_base64((int64_t)statp->st_atime, p); *p++ = ' '; p += to_base64((int64_t)statp->st_mtime, p); *p++ = ' '; p += to_base64((int64_t)statp->st_ctime, p); *p++ = ' '; p += to_base64((int64_t)LinkFI, p); *p++ = ' '; #ifdef HAVE_CHFLAGS /* FreeBSD function */ p += to_base64((int64_t)statp->st_flags, p); /* output st_flags */ #else p += to_base64((int64_t)0, p); /* output place holder */ #endif *p++ = ' '; p += to_base64((int64_t)data_stream, p); *p = 0; return; } /* Do casting according to unknown type to keep compiler happy */ #ifdef HAVE_TYPEOF #define plug(st, val) st = (typeof st)val #else #if !HAVE_GCC & HAVE_SUN_OS /* Sun compiler does not handle templates correctly */ #define plug(st, val) st = val #elif __sgi #define plug(st, val) st = val #else /* Use templates to do the casting */ template void plug(T &st, uint64_t val) { st = static_cast(val); } #endif #endif /** * Decode a stat packet from base64 characters */ int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI) { char *p = buf; int64_t val; /* * We store into the stat packet so make sure the caller's conception * is the same as ours. They can be different if LARGEFILE is not * the same when compiling this library and the calling program. */ ASSERT(stat_size == (int)sizeof(struct stat)); memset(statp, 0, stat_size); p += from_base64(&val, p); plug(statp->st_dev, val); p++; p += from_base64(&val, p); plug(statp->st_ino, val); p++; p += from_base64(&val, p); plug(statp->st_mode, val); p++; p += from_base64(&val, p); plug(statp->st_nlink, val); p++; p += from_base64(&val, p); plug(statp->st_uid, val); p++; p += from_base64(&val, p); plug(statp->st_gid, val); p++; p += from_base64(&val, p); plug(statp->st_rdev, val); p++; p += from_base64(&val, p); plug(statp->st_size, val); p++; #ifndef HAVE_MINGW p += from_base64(&val, p); plug(statp->st_blksize, val); p++; p += from_base64(&val, p); plug(statp->st_blocks, val); p++; #else p += from_base64(&val, p); // plug(statp->st_blksize, val); p++; p += from_base64(&val, p); // plug(statp->st_blocks, val); p++; #endif p += from_base64(&val, p); plug(statp->st_atime, val); p++; p += from_base64(&val, p); plug(statp->st_mtime, val); p++; p += from_base64(&val, p); plug(statp->st_ctime, val); /* Optional FileIndex of hard linked file data */ if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) { p++; p += from_base64(&val, p); *LinkFI = (uint32_t)val; } else { *LinkFI = 0; return 0; } /* FreeBSD user flags */ if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) { p++; p += from_base64(&val, p); #ifdef HAVE_CHFLAGS plug(statp->st_flags, val); } else { statp->st_flags = 0; #endif } /* Look for data stream id */ if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) { p++; p += from_base64(&val, p); } else { val = 0; } return (int)val; } /** * Decode a LinkFI field of encoded stat packet */ int32_t decode_LinkFI(char *buf, struct stat *statp, int stat_size) { char *p = buf; int64_t val; /* * We store into the stat packet so make sure the caller's conception * is the same as ours. They can be different if LARGEFILE is not * the same when compiling this library and the calling program. */ ASSERT(stat_size == (int)sizeof(struct stat)); skip_nonspaces(&p); /* st_dev */ p++; /* skip space */ skip_nonspaces(&p); /* st_ino */ p++; p += from_base64(&val, p); plug(statp->st_mode, val); /* st_mode */ p++; skip_nonspaces(&p); /* st_nlink */ p++; skip_nonspaces(&p); /* st_uid */ p++; skip_nonspaces(&p); /* st_gid */ p++; skip_nonspaces(&p); /* st_rdev */ p++; skip_nonspaces(&p); /* st_size */ p++; skip_nonspaces(&p); /* st_blksize */ p++; skip_nonspaces(&p); /* st_blocks */ p++; skip_nonspaces(&p); /* st_atime */ p++; skip_nonspaces(&p); /* st_mtime */ p++; skip_nonspaces(&p); /* st_ctime */ /* Optional FileIndex of hard linked file data */ if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) { p++; p += from_base64(&val, p); return (int32_t)val; } return 0; } bareos-Release-14.2.6/src/lib/base64.c000066400000000000000000000221301263011562700172230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Generic base 64 input and output routines * * Written by Kern E. Sibbald, March MM. */ #include "bareos.h" #ifdef TEST_MODE #include #endif static uint8_t const base64_digits[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; static int base64_inited = 0; static uint8_t base64_map[256]; /* Initialize the Base 64 conversion routines */ void base64_init(void) { int i; memset(base64_map, 0, sizeof(base64_map)); for (i=0; i<64; i++) base64_map[(uint8_t)base64_digits[i]] = i; base64_inited = 1; } /* Convert a value to base64 characters. * The result is stored in where, which * must be at least 8 characters long. * * Returns the number of characters * stored (not including the EOS). */ int to_base64(int64_t value, char *where) { uint64_t val; int i = 0; int n; /* Handle negative values */ if (value < 0) { where[i++] = '-'; value = -value; } /* Determine output size */ val = value; do { val >>= 6; i++; } while (val); n = i; /* Output characters */ val = value; where[i] = 0; do { where[--i] = base64_digits[val & (uint64_t)0x3F]; val >>= 6; } while (val); return n; } /* * Convert the Base 64 characters in where to * a value. No checking is done on the validity * of the characters!! * * Returns the value. */ int from_base64(int64_t *value, char *where) { uint64_t val = 0; int i, neg; if (!base64_inited) base64_init(); /* Check if it is negative */ i = neg = 0; if (where[i] == '-') { i++; neg = 1; } /* Construct value */ while (where[i] != 0 && where[i] != ' ') { val <<= 6; val += base64_map[(uint8_t)where[i++]]; } *value = neg ? -(int64_t)val : (int64_t)val; return i; } /* * Encode binary data in bin of len bytes into * buf as base64 characters. * * If compatible is true, the bin_to_base64 routine will be compatible * with what the rest of the world uses. * * Returns: the number of characters stored not * including the EOS */ int bin_to_base64(char *buf, int buflen, char *bin, int binlen, bool compatible) { uint32_t reg, save, mask; int rem, i; int j = 0; reg = 0; rem = 0; buflen--; /* allow for storing EOS */ for (i=0; i < binlen; ) { if (rem < 6) { reg <<= 8; if (compatible) { reg |= (uint8_t)bin[i++]; } else { reg |= (int8_t)bin[i++]; } rem += 8; } save = reg; reg >>= (rem - 6); if (j < buflen) { buf[j++] = base64_digits[reg & 0x3F]; } reg = save; rem -= 6; } if (rem && j < buflen) { mask = (1 << rem) - 1; if (compatible) { buf[j++] = base64_digits[(reg & mask) << (6 - rem)]; } else { buf[j++] = base64_digits[reg & mask]; } } buf[j] = 0; return j; } /* * Decode base64 data in bin of len bytes into * buf as binary characters. * * the base64_to_bin routine is compatible with what the rest of the world * uses. * * Returns: the number of characters stored not * including the EOS */ int base64_to_bin(char *dest, int dest_size, char *src, int srclen) { int nprbytes; uint8_t *bufout; uint8_t *bufplain = (uint8_t*) dest; const uint8_t *bufin; if (!base64_inited) base64_init(); if (dest_size < (((srclen + 3) / 4) * 3)) { /* dest buffer too small */ *dest = 0; return 0; } bufin = (const uint8_t *) src; while ((*bufin != ' ') && (srclen != 0)) { bufin++; srclen--; } nprbytes = bufin - (const uint8_t *) src; bufin = (const uint8_t *) src; bufout = (uint8_t *) bufplain; while (nprbytes > 4) { *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4); *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2); *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]); bufin += 4; nprbytes -= 4; } /* BAREOS base64 strings are not always padded with = */ if (nprbytes > 1) { *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4); } if (nprbytes > 2) { *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2); } if (nprbytes > 3) { *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]); } *bufout = 0; return (bufout - (uint8_t *) dest); } #ifdef BIN_TEST int main(int argc, char *argv[]) { int xx = 0; int len; char buf[100]; char junk[100]; int i; #ifdef xxxx for (i=0; i < 1000; i++) { bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true); printf("xx=%s\n", buf); xx++; } #endif junk[0] = 0xFF; for (i=1; i<100; i++) { junk[i] = junk[i-1]-1; } len = bin_to_base64(buf, sizeof(buf), junk, 16, true); printf("len=%d junk=%s\n", len, buf); strcpy(junk, "This is a sample stringa"); len = bin_to_base64(buf, sizeof(buf), junk, strlen(junk), true); buf[len] = 0; base64_to_bin(junk, sizeof(junk), buf, len); printf("buf=<%s>\n", junk); return 0; } #endif #ifdef TEST_MODE static int errfunc(const char *epath, int eernoo) { printf("in errfunc\n"); return 1; } /* * Test the base64 routines by encoding and decoding * lstat() packets. */ int main(int argc, char *argv[]) { char where[500]; int i; glob_t my_glob; char *fname; struct stat statp; struct stat statn; int debug_level = 0; char *p; int32_t j; time_t t = 1028712799; if (argc > 1 && bstrcmp(argv[1], "-v")) debug_level++; base64_init(); my_glob.gl_offs = 0; glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob); for (i=0; my_glob.gl_pathv[i]; i++) { fname = my_glob.gl_pathv[i]; if (lstat(fname, &statp) < 0) { berrno be; printf("Cannot stat %s: %s\n", fname, be.bstrerror(errno)); continue; } encode_stat(where, &statp, sizeof(statp), 0, 0); printf("Encoded stat=%s\n", where); #ifdef xxx p = where; p += to_base64((int64_t)(statp.st_atime), p); *p++ = ' '; p += to_base64((int64_t)t, p); printf("%s %s\n", fname, where); printf("%s %lld\n", "st_dev", (int64_t)statp.st_dev); printf("%s %lld\n", "st_ino", (int64_t)statp.st_ino); printf("%s %lld\n", "st_mode", (int64_t)statp.st_mode); printf("%s %lld\n", "st_nlink", (int64_t)statp.st_nlink); printf("%s %lld\n", "st_uid", (int64_t)statp.st_uid); printf("%s %lld\n", "st_gid", (int64_t)statp.st_gid); printf("%s %lld\n", "st_rdev", (int64_t)statp.st_rdev); printf("%s %lld\n", "st_size", (int64_t)statp.st_size); printf("%s %lld\n", "st_blksize", (int64_t)statp.st_blksize); printf("%s %lld\n", "st_blocks", (int64_t)statp.st_blocks); printf("%s %lld\n", "st_atime", (int64_t)statp.st_atime); printf("%s %lld\n", "st_mtime", (int64_t)statp.st_mtime); printf("%s %lld\n", "st_ctime", (int64_t)statp.st_ctime); #endif if (debug_level) printf("%s: len=%d val=%s\n", fname, strlen(where), where); decode_stat(where, &statn, sizeof(statn), &j); if (statp.st_dev != statn.st_dev || statp.st_ino != statn.st_ino || statp.st_mode != statn.st_mode || statp.st_nlink != statn.st_nlink || statp.st_uid != statn.st_uid || statp.st_gid != statn.st_gid || statp.st_rdev != statn.st_rdev || statp.st_size != statn.st_size || statp.st_blksize != statn.st_blksize || statp.st_blocks != statn.st_blocks || statp.st_atime != statn.st_atime || statp.st_mtime != statn.st_mtime || statp.st_ctime != statn.st_ctime) { printf("%s: %s\n", fname, where); encode_stat(where, &statn, sizeof(statn), 0, 0); printf("%s: %s\n", fname, where); printf("NOT EQAL\n"); } } globfree(&my_glob); printf("%d files examined\n", i); to_base64(UINT32_MAX, where); printf("UINT32_MAX=%s\n", where); return 0; } #endif bareos-Release-14.2.6/src/lib/base64.h000066400000000000000000000021171263011562700172330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Generic base 64 input and output routines * * Written by Kern E. Sibbald, March MM. */ /* Maximum size of len bytes after base64 encoding */ #define BASE64_SIZE(len) ((4 * len + 2) / 3 + 1) // #define BASE64_SIZE(len) (((len + 3 - (len % 3)) / 3) * 4) bareos-Release-14.2.6/src/lib/berrno.c000066400000000000000000000055241263011562700174360ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS errno handler * * berrno is a simplistic errno handler that works for * Unix, Win32, and BAREOS bpipes. * * See berrno.h for how to use berrno. * * Kern Sibbald, July MMIV */ #include "bareos.h" #ifndef HAVE_WIN32 extern const char *get_signal_name(int sig); extern int num_execvp_errors; extern int execvp_errors[]; #endif const char *berrno::bstrerror() { *m_buf = 0; #ifdef HAVE_WIN32 if (m_berrno & b_errno_win32) { format_win32_message(); return (const char *)m_buf; } #else int status = 0; if (m_berrno & b_errno_exit) { status = (m_berrno & ~b_errno_exit); /* remove bit */ if (status == 0) { return _("Child exited normally."); /* this really shouldn't happen */ } else { /* Maybe an execvp failure */ if (status >= 200) { if (status < 200 + num_execvp_errors) { m_berrno = execvp_errors[status - 200]; } else { return _("Unknown error during program execvp"); } } else { Mmsg(m_buf, _("Child exited with code %d"), status); return m_buf; } /* If we drop out here, m_berrno is set to an execvp errno */ } } if (m_berrno & b_errno_signal) { status = (m_berrno & ~b_errno_signal); /* remove bit */ Mmsg(m_buf, _("Child died from signal %d: %s"), status, get_signal_name(status)); return m_buf; } #endif /* Normal errno */ if (b_strerror(m_berrno, m_buf, 1024) < 0) { return _("Invalid errno. No error message possible."); } return m_buf; } void berrno::format_win32_message() { #ifdef HAVE_WIN32 LPVOID msg; FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL); pm_strcpy(&m_buf, (const char *)msg); LocalFree(msg); #endif } #ifdef TEST_PROGRAM int main() { } #endif bareos-Release-14.2.6/src/lib/berrno.h000066400000000000000000000047131263011562700174420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, July MMIV */ /* * Extra bits set to interpret errno value differently from errno */ #ifdef HAVE_WIN32 #define b_errno_win32 (1<<29) /* user reserved bit */ #else #define b_errno_win32 0 /* On Unix/Linix system */ #endif #define b_errno_exit (1<<28) /* child exited, exit code returned */ #define b_errno_signal (1<<27) /* child died, signal code returned */ /* * A more generalized way of handling errno that works with Unix, Windows, * and with BAREOS bpipes. * * It works by picking up errno and creating a memory pool buffer * for editing the message. strerror() does the actual editing, and * it is thread safe. * * If bit 29 in m_berrno is set then it is a Win32 error, and we * must do a GetLastError() to get the error code for formatting. * If bit 29 in m_berrno is not set, then it is a Unix errno. * */ class berrno : public SMARTALLOC { POOLMEM *m_buf; int m_berrno; void format_win32_message(); public: berrno(int pool=PM_EMSG); ~berrno(); const char *bstrerror(); const char *bstrerror(int errnum); void set_errno(int errnum); int code() { return m_berrno & ~(b_errno_exit|b_errno_signal); } int code(int stat) { return stat & ~(b_errno_exit|b_errno_signal); } }; /* Constructor */ inline berrno::berrno(int pool) { m_berrno = errno; m_buf = get_pool_memory(pool); *m_buf = 0; errno = m_berrno; } inline berrno::~berrno() { free_pool_memory(m_buf); } inline const char *berrno::bstrerror(int errnum) { m_berrno = errnum; return berrno::bstrerror(); } inline void berrno::set_errno(int errnum) { m_berrno = errnum; } bareos-Release-14.2.6/src/lib/bget_msg.c000066400000000000000000000060221263011562700177300ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Subroutines to receive network data and handle * network signals for the FD and the SD. * * Kern Sibbald, May MMI previously in src/stored/fdmsg.c */ #include "bareos.h" /* pull in global headers */ static char OK_msg[] = "2000 OK\n"; static char TERM_msg[] = "2999 Terminate\n"; #define msglvl 500 /* * This routine does a bnet_recv(), then if a signal was * sent, it handles it. The return codes are the same as * bne_recv() except the BNET_SIGNAL messages that can * be handled are done so without returning. * * Returns number of bytes read (may return zero) * Returns -1 on signal (BNET_SIGNAL) * Returns -2 on hard end of file (BNET_HARDEOF) * Returns -3 on error (BNET_ERROR) */ int bget_msg(BSOCK *sock) { int n; for ( ;; ) { n = sock->recv(); if (n >= 0) { /* normal return */ return n; } if (is_bnet_stop(sock)) { /* error return */ return n; } /* BNET_SIGNAL (-1) return from bnet_recv() => network signal */ switch (sock->msglen) { case BNET_EOD: /* end of data */ Dmsg0(msglvl, "Got BNET_EOD\n"); return n; case BNET_EOD_POLL: Dmsg0(msglvl, "Got BNET_EOD_POLL\n"); if (sock->is_terminated()) { sock->fsend(TERM_msg); } else { sock->fsend(OK_msg); /* send response */ } return n; /* end of data */ case BNET_TERMINATE: Dmsg0(msglvl, "Got BNET_TERMINATE\n"); sock->set_terminated(); return n; case BNET_POLL: Dmsg0(msglvl, "Got BNET_POLL\n"); if (sock->is_terminated()) { sock->fsend(TERM_msg); } else { sock->fsend(OK_msg); /* send response */ } break; case BNET_HEARTBEAT: case BNET_HB_RESPONSE: break; case BNET_STATUS: /* *****FIXME***** Implement BNET_STATUS */ Dmsg0(msglvl, "Got BNET_STATUS\n"); sock->fsend(_("Status OK\n")); sock->signal(BNET_EOD); break; default: Emsg1(M_ERROR, 0, _("bget_msg: unknown signal %d\n"), sock->msglen); break; } } } bareos-Release-14.2.6/src/lib/binflate.c000066400000000000000000000054231263011562700177310ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS zlib compression wrappers */ #include "bareos.h" #ifdef HAVE_LIBZ #include #endif /* * Deflate or compress and input buffer. You must supply an * output buffer sufficiently long and the length of the * output buffer. Generally, if the output buffer is the * same size as the input buffer, it should work (at least * for text). */ int Zdeflate(char *in, int in_len, char *out, int &out_len) { #ifdef HAVE_LIBZ z_stream strm; int ret; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit(&strm, 9); if (ret != Z_OK) { Dmsg0(200, "deflateInit error\n"); (void)deflateEnd(&strm); return ret; } strm.next_in = (Bytef *)in; strm.avail_in = in_len; Dmsg1(200, "In: %d bytes\n", strm.avail_in); strm.avail_out = out_len; strm.next_out = (Bytef *)out; ret = deflate(&strm, Z_FINISH); out_len = out_len - strm.avail_out; Dmsg1(200, "compressed=%d\n", out_len); (void)deflateEnd(&strm); return ret; #else return 1; #endif } /* * Inflate or uncompress an input buffer. You must supply * and output buffer and an output length sufficiently long * or there will be an error. This uncompresses in one call. */ int Zinflate(char *in, int in_len, char *out, int &out_len) { #ifdef HAVE_LIBZ z_stream strm; int ret; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.next_in = (Bytef *)in; strm.avail_in = in_len; ret = inflateInit(&strm); if (ret != Z_OK) { Dmsg0(200, "inflateInit error\n"); (void)inflateEnd(&strm); return ret; } Dmsg1(200, "In len: %d bytes\n", strm.avail_in); strm.avail_out = out_len; strm.next_out = (Bytef *)out; ret = inflate(&strm, Z_FINISH); out_len -= strm.avail_out; Dmsg1(200, "Uncompressed=%d\n", out_len); (void)inflateEnd(&strm); return ret; #else return 1; #endif } bareos-Release-14.2.6/src/lib/bits.h000066400000000000000000000041121263011562700171050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. Copyright (C) 2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Some elementary bit manipulations * * Kern Sibbald, MM * * NOTE: base 0 */ #ifndef __BITS_H_ #define __BITS_H_ /* * Number of bytes to hold n bits */ #define nbytes_for_bits(n) ((((n) - 1) >> 3) + 1) /* * Test if bit is set */ #define bit_is_set(b, var) (((var)[(b) >> 3] & (1 << ((b) & 0x7))) != 0) /* * Set bit */ #define set_bit(b, var) ((var)[(b) >> 3] |= (1 << ((b) & 0x7))) /* * Clear bit */ #define clear_bit(b, var) ((var)[(b) >> 3] &= ~(1 << ((b) & 0x7))) /* * Clear all bits */ #define clear_all_bits(b, var) memset((var), 0, nbytes_for_bits((b))) /* * Set range of bits */ #define set_bits(f, l, var) { \ int bit; \ for (bit = (f); bit <= (l); bit++) \ set_bit(bit, (var)); \ } /* * Clear range of bits */ #define clear_bits(f, l, var) { \ int bit; \ for (bit = (f); bit <= (l); bit++) \ clear_bit(bit, (var)); \ } /* * Clone all set bits from var1 to var2 */ #define clone_bits(l, var1, var2) { \ int bit; \ for (bit = 0; bit <= (l); bit++) \ if (bit_is_set(bit, (var1))) \ set_bit(bit, (var2)); \ } /* * Copy all bits from var1 to var2 */ #define copy_bits(b, var1, var2) memcpy((var2), (var1), nbytes_for_bits((b))) #endif /* __BITS_H_ */ bareos-Release-14.2.6/src/lib/bmtio.h000066400000000000000000000223441263011562700172650ustar00rootroot00000000000000/*- * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)mtio.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: stable/7/sys/sys/mtio.h 139825 2005-01-07 02:29:27Z imp $ */ #ifndef _SYS_MTIO_H_ #define _SYS_MTIO_H_ #ifndef _KERNEL #include #endif #include /* * Structures and definitions for mag tape io control commands */ /* structure for MTIOCTOP - mag tape op command */ struct mtop { short mt_op; /* operations defined below */ int32_t mt_count; /* how many of them */ }; /* operations */ #define MTWEOF 0 /* write an end-of-file record */ #define MTFSF 1 /* forward space file */ #define MTBSF 2 /* backward space file */ #define MTFSR 3 /* forward space record */ #define MTBSR 4 /* backward space record */ #define MTREW 5 /* rewind */ #define MTOFFL 6 /* rewind and put the drive offline */ #define MTNOP 7 /* no operation, sets status only */ #define MTCACHE 8 /* enable controller cache */ #define MTNOCACHE 9 /* disable controller cache */ #if defined(__FreeBSD__) /* Set block size for device. If device is a variable size dev */ /* a non zero parameter will change the device to a fixed block size */ /* device with block size set to that of the parameter passed in. */ /* Resetting the block size to 0 will restore the device to a variable */ /* block size device. */ #define MTSETBSIZ 10 /* Set density values for device. Sets the value for the opened mode only. */ #define MTSETDNSTY 11 #define MTERASE 12 /* erase to EOM */ #define MTEOD 13 /* Space to EOM */ #define MTCOMP 14 /* select compression mode 0=off, 1=def */ #define MTRETENS 15 /* re-tension tape */ #define MTWSS 16 /* write setmark(s) */ #define MTFSS 17 /* forward space setmark */ #define MTBSS 18 /* backward space setmark */ #define MT_COMP_ENABLE 0xffffffff #define MT_COMP_DISABLED 0xfffffffe #define MT_COMP_UNSUPP 0xfffffffd /* * Values in mt_dsreg that say what the device is doing */ #define MTIO_DSREG_NIL 0 /* Unknown */ #define MTIO_DSREG_REST 1 /* Doing Nothing */ #define MTIO_DSREG_RBSY 2 /* Communicating with tape (but no motion) */ #define MTIO_DSREG_WR 20 /* Writing */ #define MTIO_DSREG_FMK 21 /* Writing Filemarks */ #define MTIO_DSREG_ZER 22 /* Erasing */ #define MTIO_DSREG_RD 30 /* Reading */ #define MTIO_DSREG_FWD 40 /* Spacing Forward */ #define MTIO_DSREG_REV 41 /* Spacing Reverse */ #define MTIO_DSREG_POS 42 /* Hardware Positioning (direction unknown) */ #define MTIO_DSREG_REW 43 /* Rewinding */ #define MTIO_DSREG_TEN 44 /* Retensioning */ #define MTIO_DSREG_UNL 45 /* Unloading */ #define MTIO_DSREG_LD 46 /* Loading */ #endif /* __FreeBSD__ */ /* structure for MTIOCGET - mag tape get status command */ struct mtget { short mt_type; /* type of magtape device */ /* the following two registers are grossly device dependent */ short mt_dsreg; /* ``drive status'' register */ short mt_erreg; /* ``error'' register */ /* end device-dependent registers */ /* * Note that the residual count, while maintained, may be * be nonsense because the size of the residual may (greatly) * exceed 32 K-bytes. Use the MTIOCERRSTAT ioctl to get a * more accurate count. */ short mt_resid; /* residual count */ #if defined (__FreeBSD__) int32_t mt_blksiz; /* presently operating blocksize */ int32_t mt_density; /* presently operating density */ u_int32_t mt_comp; /* presently operating compression */ int32_t mt_blksiz0; /* blocksize for mode 0 */ int32_t mt_blksiz1; /* blocksize for mode 1 */ int32_t mt_blksiz2; /* blocksize for mode 2 */ int32_t mt_blksiz3; /* blocksize for mode 3 */ int32_t mt_density0; /* density for mode 0 */ int32_t mt_density1; /* density for mode 1 */ int32_t mt_density2; /* density for mode 2 */ int32_t mt_density3; /* density for mode 3 */ /* the following are not yet implemented */ u_int32_t mt_comp0; /* compression type for mode 0 */ u_int32_t mt_comp1; /* compression type for mode 1 */ u_int32_t mt_comp2; /* compression type for mode 2 */ u_int32_t mt_comp3; /* compression type for mode 3 */ /* end not yet implemented */ #endif int32_t mt_fileno; /* relative file number of current position */ int32_t mt_blkno; /* relative block number of current position */ }; /* structure for MTIOCERRSTAT - tape get error status command */ /* really only supported for SCSI tapes right now */ struct scsi_tape_errors { /* * These are latched from the last command that had a SCSI * Check Condition noted for these operations. The act * of issuing an MTIOCERRSTAT unlatches and clears them. */ u_int8_t io_sense[32]; /* Last Sense Data For Data I/O */ int32_t io_resid; /* residual count from last Data I/O */ u_int8_t io_cdb[16]; /* Command that Caused the Last Data Sense */ u_int8_t ctl_sense[32]; /* Last Sense Data For Control I/O */ int32_t ctl_resid; /* residual count from last Control I/O */ u_int8_t ctl_cdb[16]; /* Command that Caused the Last Control Sense */ /* * These are the read and write cumulative error counters. * (how to reset cumulative error counters is not yet defined). * (not implemented as yet but space is being reserved for them) */ struct { u_int32_t retries; /* total # retries performed */ u_int32_t corrected; /* total # corrections performed */ u_int32_t processed; /* total # corrections successful */ u_int32_t failures; /* total # corrections/retries failed */ u_int64_t nbytes; /* total # bytes processed */ } wterr, rderr; }; union mterrstat { struct scsi_tape_errors scsi_errstat; char _reserved_padding[256]; }; /* * Constants for mt_type byte. These are the same * for controllers compatible with the types listed. */ #define MT_ISTS 0x01 /* TS-11 */ #define MT_ISHT 0x02 /* TM03 Massbus: TE16, TU45, TU77 */ #define MT_ISTM 0x03 /* TM11/TE10 Unibus */ #define MT_ISMT 0x04 /* TM78/TU78 Massbus */ #define MT_ISUT 0x05 /* SI TU-45 emulation on Unibus */ #define MT_ISCPC 0x06 /* SUN */ #define MT_ISAR 0x07 /* SUN */ #define MT_ISTMSCP 0x08 /* DEC TMSCP protocol (TU81, TK50) */ #define MT_ISCY 0x09 /* CCI Cipher */ #define MT_ISCT 0x0a /* HP 1/4 tape */ #define MT_ISFHP 0x0b /* HP 7980 1/2 tape */ #define MT_ISEXABYTE 0x0c /* Exabyte */ #define MT_ISEXA8200 0x0c /* Exabyte EXB-8200 */ #define MT_ISEXA8500 0x0d /* Exabyte EXB-8500 */ #define MT_ISVIPER1 0x0e /* Archive Viper-150 */ #define MT_ISPYTHON 0x0f /* Archive Python (DAT) */ #define MT_ISHPDAT 0x10 /* HP 35450A DAT drive */ #define MT_ISMFOUR 0x11 /* M4 Data 1/2 9track drive */ #define MT_ISTK50 0x12 /* DEC SCSI TK50 */ #define MT_ISMT02 0x13 /* Emulex MT02 SCSI tape controller */ /* mag tape io control commands */ #define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */ #define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */ /* these two do not appear to be used anywhere */ #define MTIOCIEOT _IO('m', 3) /* ignore EOT error */ #define MTIOCEEOT _IO('m', 4) /* enable EOT error */ /* * When more SCSI-3 SSC (streaming device) devices are out there * that support the full 32 byte type 2 structure, we'll have to * rethink these ioctls to support all the entities they haul into * the picture (64 bit blocks, logical file record numbers, etc..). */ #define MTIOCRDSPOS _IOR('m', 5, u_int32_t) /* get logical blk addr */ #define MTIOCRDHPOS _IOR('m', 6, u_int32_t) /* get hardware blk addr */ #define MTIOCSLOCATE _IOW('m', 5, u_int32_t) /* seek to logical blk addr */ #define MTIOCHLOCATE _IOW('m', 6, u_int32_t) /* seek to hardware blk addr */ #define MTIOCERRSTAT _IOR('m', 7, union mterrstat) /* get tape errors */ /* * Set EOT model- argument is number of filemarks to end a tape with. * Note that not all possible values will be accepted. */ #define MTIOCSETEOTMODEL _IOW('m', 8, u_int32_t) /* Get current EOT model */ #define MTIOCGETEOTMODEL _IOR('m', 8, u_int32_t) #ifndef _KERNEL #define DEFTAPE "/dev/nsa0" #endif #endif /* !_SYS_MTIO_H_ */ bareos-Release-14.2.6/src/lib/bnet.c000066400000000000000000000360271263011562700171010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Network Utility Routines * * by Kern Sibbald * * Adapted and enhanced for BAREOS, originally written * for inclusion in the Apcupsd package */ #include "bareos.h" #include "jcr.h" #include #ifndef INADDR_NONE #define INADDR_NONE -1 #endif #ifndef HAVE_GETADDRINFO static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER; #endif /* * Receive a message from the other end. Each message consists of * two packets. The first is a header that contains the size * of the data that follows in the second packet. * Returns number of bytes read (may return zero) * Returns -1 on signal (BNET_SIGNAL) * Returns -2 on hard end of file (BNET_HARDEOF) * Returns -3 on error (BNET_ERROR) * * Unfortunately, it is a bit complicated because we have these * four return types: * 1. Normal data * 2. Signal including end of data stream * 3. Hard end of file * 4. Error * Using is_bnet_stop() and is_bnet_error() you can figure this all out. */ int32_t bnet_recv(BSOCK * bsock) { return bsock->recv(); } /* * Return 1 if there are errors on this bsock or it is closed, * i.e. stop communicating on this line. */ bool is_bnet_stop(BSOCK * bsock) { return bsock->is_stop(); } /* * Return number of errors on socket */ int is_bnet_error(BSOCK * bsock) { return bsock->is_error(); } /* * Call here after error during closing to suppress error * messages which are due to the other end shutting down too. */ void bnet_suppress_error_messages(BSOCK * bsock, bool flag) { bsock->m_suppress_error_msgs = flag; } /* * Send a message over the network. The send consists of * two network packets. The first is sends a 32 bit integer containing * the length of the data packet which follows. * * Returns: false on failure * true on success */ bool bnet_send(BSOCK *bsock) { return bsock->send(); } /* * Establish a TLS connection -- server side * Returns: true on success * false on failure */ #ifdef HAVE_TLS bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list) { TLS_CONNECTION *tls; JCR *jcr = bsock->jcr(); tls = new_tls_connection(ctx, bsock->m_fd, true); if (!tls) { Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n")); return false; } bsock->tls = tls; /* * Initiate TLS Negotiation */ if (!tls_bsock_accept(bsock)) { Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n")); goto err; } if (verify_list) { if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) { Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed." " Peer certificate did not match a required commonName\n"), bsock->host()); goto err; } } Dmsg0(50, "TLS server negotiation established.\n"); return true; err: free_tls_connection(tls); bsock->tls = NULL; return false; } /* * Establish a TLS connection -- client side * Returns: true on success * false on failure */ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list) { TLS_CONNECTION *tls; JCR *jcr = bsock->jcr(); tls = new_tls_connection(ctx, bsock->m_fd, false); if (!tls) { Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n")); return false; } bsock->tls = tls; /* * Initiate TLS Negotiation */ if (!tls_bsock_connect(bsock)) { goto err; } /* * If there's an Allowed CN verify list, use that to validate the remote * certificate's CN. Otherwise, we use standard host/CN matching. */ if (verify_list) { if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) { Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed." " Peer certificate did not match a required commonName\n"), bsock->host()); goto err; } } else { if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) { Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"), bsock->host()); goto err; } } Dmsg0(50, "TLS client negotiation established.\n"); return true; err: free_tls_connection(tls); bsock->tls = NULL; return false; } #else bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) { Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n")); return false; } bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) { Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n")); return false; } #endif /* HAVE_TLS */ /* * Wait for a specified time for data to appear on * the BSOCK connection. * * Returns: 1 if data available * 0 if timeout * -1 if error */ int bnet_wait_data(BSOCK * bsock, int sec) { return bsock->wait_data(sec); } /* * As above, but returns on interrupt */ int bnet_wait_data_intr(BSOCK * bsock, int sec) { return bsock->wait_data_intr(sec); } #ifndef NETDB_INTERNAL #define NETDB_INTERNAL -1 /* See errno. */ #endif #ifndef NETDB_SUCCESS #define NETDB_SUCCESS 0 /* No problem. */ #endif #ifndef HOST_NOT_FOUND #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */ #endif #ifndef TRY_AGAIN #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */ #endif #ifndef NO_RECOVERY #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */ #endif #ifndef NO_DATA #define NO_DATA 4 /* Valid name, no data record of requested type. */ #endif #if HAVE_GETADDRINFO const char *resolv_host(int family, const char *host, dlist *addr_list) { int res; struct addrinfo hints; struct addrinfo *ai, *rp; IPADDR *addr; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = 0; res = getaddrinfo(host, NULL, &hints, &ai); if (res != 0) { return gai_strerror(res); } for (rp = ai; rp != NULL; rp = rp->ai_next) { switch (rp->ai_addr->sa_family) { case AF_INET: addr = New(IPADDR(rp->ai_addr->sa_family)); addr->set_type(IPADDR::R_MULTIPLE); /* * Some serious casting to get the struct in_addr * * rp->ai_addr == struct sockaddr * as this is AF_INET family we can cast that * to struct_sockaddr_in. Of that we need the * address of the sin_addr member which contains a * struct in_addr */ addr->set_addr4(&(((struct sockaddr_in *)rp->ai_addr)->sin_addr)); break; #ifdef HAVE_IPV6 case AF_INET6: addr = New(IPADDR(rp->ai_addr->sa_family)); addr->set_type(IPADDR::R_MULTIPLE); /* * Some serious casting to get the struct in6_addr * * rp->ai_addr == struct sockaddr * as this is AF_INET6 family we can cast that * to struct_sockaddr_in6. Of that we need the * address of the sin6_addr member which contains a * struct in6_addr */ addr->set_addr6(&(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr)); break; #endif default: continue; } addr_list->append(addr); } freeaddrinfo(ai); return NULL; } #else /* * Get human readable error for gethostbyname() */ static const char *gethost_strerror() { const char *msg; berrno be; switch (h_errno) { case NETDB_INTERNAL: msg = be.bstrerror(); break; case NETDB_SUCCESS: msg = _("No problem."); break; case HOST_NOT_FOUND: msg = _("Authoritative answer for host not found."); break; case TRY_AGAIN: msg = _("Non-authoritative for host not found, or ServerFail."); break; case NO_RECOVERY: msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP."); break; case NO_DATA: msg = _("Valid name, no data record of resquested type."); break; default: msg = _("Unknown error."); } return msg; } static const char *resolv_host(int family, const char *host, dlist *addr_list) { struct hostent *hp; const char *errmsg; char **p; IPADDR *addr; P(ip_mutex); /* gethostbyname() is not thread safe */ #ifdef HAVE_GETHOSTBYNAME2 if ((hp = gethostbyname2(host, family)) == NULL) { #else if ((hp = gethostbyname(host)) == NULL) { #endif /* may be the strerror give not the right result -:( */ errmsg = gethost_strerror(); V(ip_mutex); return errmsg; } else { for (p = hp->h_addr_list; *p != 0; p++) { switch (hp->h_addrtype) { case AF_INET: addr = New(IPADDR(hp->h_addrtype)); addr->set_type(IPADDR::R_MULTIPLE); addr->set_addr4((struct in_addr *)*p); break; #ifdef HAVE_IPV6 case AF_INET6: addr = New(IPADDR(hp->h_addrtype)); addr->set_type(IPADDR::R_MULTIPLE); addr->set_addr6((struct in6_addr *)*p); break; #endif default: continue; } addr_list->append(addr); } V(ip_mutex); } return NULL; } #endif static IPADDR *add_any(int family) { IPADDR *addr = New(IPADDR(family)); addr->set_type(IPADDR::R_MULTIPLE); addr->set_addr_any(); return addr; } /* * i host = 0 mean INADDR_ANY only ipv4 */ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) { struct in_addr inaddr; IPADDR *addr = 0; const char *errmsg; #ifdef HAVE_IPV6 struct in6_addr inaddr6; #endif dlist *addr_list = New(dlist(addr, &addr->link)); if (!host || host[0] == '\0') { if (family != 0) { addr_list->append(add_any(family)); } else { addr_list->append(add_any(AF_INET)); #ifdef HAVE_IPV6 addr_list->append(add_any(AF_INET6)); #endif } } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */ addr = New(IPADDR(AF_INET)); addr->set_type(IPADDR::R_MULTIPLE); addr->set_addr4(&inaddr); addr_list->append(addr); #ifdef HAVE_IPV6 #ifndef HAVE_WIN32 } else if (inet_pton(AF_INET6, host, &inaddr6) == 1) { #else } else if (p_InetPton && p_InetPton(AF_INET6, host, &inaddr6) == 1) { #endif addr = New(IPADDR(AF_INET6)); addr->set_type(IPADDR::R_MULTIPLE); addr->set_addr6(&inaddr6); addr_list->append(addr); #endif } else { if (family != 0) { errmsg = resolv_host(family, host, addr_list); if (errmsg) { *errstr = errmsg; free_addresses(addr_list); return 0; } } else { #ifdef HAVE_IPV6 /* We try to resolv host for ipv6 and ipv4, the connection procedure * will try to reach the host for each protocols. We report only "Host * not found" ipv4 message (no need to have ipv6 and ipv4 messages). */ resolv_host(AF_INET6, host, addr_list); #endif errmsg = resolv_host(AF_INET, host, addr_list); if (addr_list->size() == 0) { *errstr = errmsg; free_addresses(addr_list); return 0; } } } return addr_list; } /* * Return the string for the error that occurred * on the socket. Only the first error is retained. */ const char *bnet_strerror(BSOCK * bsock) { return bsock->bstrerror(); } /* * Format and send a message * Returns: false on error * true on success */ bool bnet_fsend(BSOCK * bs, const char *fmt, ...) { va_list arg_ptr; int maxlen; if (bs->errors || bs->is_terminated()) { return false; } /* This probably won't work, but we vsnprintf, then if we * get a negative length or a length greater than our buffer * (depending on which library is used), the printf was truncated, so * get a bigger buffer and try again. */ for (;;) { maxlen = sizeof_pool_memory(bs->msg) - 1; va_start(arg_ptr, fmt); bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) { break; } bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2); } return bs->send(); } int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) { return bs->get_peer(buf, buflen); } /* * Set the network buffer size, suggested size is in size. * Actual size obtained is returned in bs->msglen * * Returns: 0 on failure * 1 on success */ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw) { return bs->set_buffer_size(size, rw); } /* * Set socket non-blocking * Returns previous socket flag */ int bnet_set_nonblocking(BSOCK *bsock) { return bsock->set_nonblocking(); } /* * Set socket blocking * Returns previous socket flags */ int bnet_set_blocking(BSOCK *bsock) { return bsock->set_blocking(); } /* * Restores socket flags */ void bnet_restore_blocking (BSOCK *bsock, int flags) { bsock->restore_blocking(flags); } /* * Send a network "signal" to the other end * This consists of sending a negative packet length * * Returns: false on failure * true on success */ bool bnet_sig(BSOCK * bs, int signal) { return bs->signal(signal); } /* * Convert a network "signal" code into * human readable ASCII. */ const char *bnet_sig_to_ascii(BSOCK * bs) { static char buf[30]; switch (bs->msglen) { case BNET_EOD: return "BNET_EOD"; /* end of data stream */ case BNET_EOD_POLL: return "BNET_EOD_POLL"; case BNET_STATUS: return "BNET_STATUS"; case BNET_TERMINATE: return "BNET_TERMINATE"; /* terminate connection */ case BNET_POLL: return "BNET_POLL"; case BNET_HEARTBEAT: return "BNET_HEARTBEAT"; case BNET_HB_RESPONSE: return "BNET_HB_RESPONSE"; case BNET_SUB_PROMPT: return "BNET_SUB_PROMPT"; case BNET_TEXT_INPUT: return "BNET_TEXT_INPUT"; default: sprintf(buf, _("Unknown sig %d"), (int)bs->msglen); return buf; } } bareos-Release-14.2.6/src/lib/bnet_server_tcp.c000066400000000000000000000250361263011562700213330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Originally written by Kern Sibbald for inclusion in apcupsd, * but heavily modified for BAREOS */ #include "bareos.h" #include #include #include #include #include #ifdef HAVE_ARPA_NAMESER_H #include #endif #ifdef HAVE_RESOLV_H //#include #endif #ifdef HAVE_POLL_H #include #elif HAVE_SYS_POLL_H #include #endif static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #ifdef HAVE_LIBWRAP #include "tcpd.h" int allow_severity = LOG_NOTICE; int deny_severity = LOG_WARNING; #endif static bool quit = false; struct s_sockfd { int fd; int port; }; /* * Stop the Threaded Network Server if its realy running in a seperate thread. * e.g. set the quit flag and wait for the other thread to exit cleanly. */ void bnet_stop_thread_server_tcp(pthread_t tid) { quit = true; if (!pthread_equal(tid, pthread_self())) { pthread_kill(tid, TIMEOUT_SIGNAL); } } /* * Perform a cleanup for the Threaded Network Server check if there is still * something to do or that the cleanup already took place. */ void cleanup_bnet_thread_server_tcp(alist *sockfds, workq_t *client_wq) { int status; s_sockfd *fd_ptr = NULL; if (!sockfds->empty()) { /* * Cleanup open files and pointers to them */ fd_ptr = (s_sockfd *)sockfds->first(); while (fd_ptr) { close(fd_ptr->fd); fd_ptr = (s_sockfd *)sockfds->next(); } sockfds->destroy(); /* * Stop work queue thread */ if ((status = workq_destroy(client_wq)) != 0) { berrno be; be.set_errno(status); Emsg1(M_FATAL, 0, _("Could not destroy client queue: ERR=%s\n"), be.bstrerror()); } } } /* * Become Threaded Network Server * * This function is able to handle multiple server ips in * ipv4 and ipv6 style. The Addresse are give in a comma * seperated string in bind_addr * * At the moment it is impossible to bind to different ports. */ void bnet_thread_server_tcp(dlist *addr_list, int max_clients, alist *sockfds, workq_t *client_wq, bool nokeepalive, void *handle_client_request(void *bsock)) { int newsockfd, status; socklen_t clilen; struct sockaddr cli_addr; /* client's address */ int tlog, tmax; int value; #ifdef HAVE_LIBWRAP struct request_info request; #endif IPADDR *ipaddr, *next, *to_free; s_sockfd *fd_ptr = NULL; char buf[128]; #ifdef HAVE_POLL nfds_t nfds; int events; struct pollfd *pfds; #endif char allbuf[256 * 10]; /* * Remove any duplicate addresses. */ for (ipaddr = (IPADDR *)addr_list->first(); ipaddr; ipaddr = (IPADDR *)addr_list->next(ipaddr)) { next = (IPADDR *)addr_list->next(ipaddr); while (next) { /* * See if the addresses match. */ if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() && memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(), ipaddr->get_sockaddr_len()) == 0) { to_free = next; next = (IPADDR *)addr_list->next(next); addr_list->remove(to_free); delete to_free; } else { next = (IPADDR *)addr_list->next(next); } } } Dmsg1(100, "Addresses %s\n", build_addresses_str(addr_list, allbuf, sizeof(allbuf))); if (nokeepalive) { value = 0; } else { value = 1; } #ifdef HAVE_POLL nfds = 0; #endif foreach_dlist(ipaddr, addr_list) { /* * Allocate on stack from -- no need to free */ fd_ptr = (s_sockfd *)alloca(sizeof(s_sockfd)); fd_ptr->port = ipaddr->get_port_net_order(); /* * Open a TCP socket */ for (tlog= 60; (fd_ptr->fd=socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0; tlog -= 10) { if (tlog <= 0) { berrno be; char curbuf[256]; Emsg3(M_ABORT, 0, _("Cannot open stream socket. ERR=%s. Current %s All %s\n"), be.bstrerror(), ipaddr->build_address_str(curbuf, sizeof(curbuf)), build_addresses_str(addr_list, allbuf, sizeof(allbuf))); } bmicrosleep(10, 0); } /* * Reuse old sockets */ if (setsockopt(fd_ptr->fd, SOL_SOCKET, SO_REUSEADDR, (sockopt_val_t)&value, sizeof(value)) < 0) { berrno be; Emsg1(M_WARNING, 0, _("Cannot set SO_REUSEADDR on socket: %s\n"), be.bstrerror()); } tmax = 30 * (60 / 5); /* wait 30 minutes max */ for (tlog = 0; bind(fd_ptr->fd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0; tlog -= 5) { berrno be; if (tlog <= 0) { tlog = 2 * 60; /* Complain every 2 minutes */ Emsg2(M_WARNING, 0, _("Cannot bind port %d: ERR=%s: Retrying ...\n"), ntohs(fd_ptr->port), be.bstrerror()); } bmicrosleep(5, 0); if (--tmax <= 0) { Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port), be.bstrerror()); } } listen(fd_ptr->fd, 50); /* tell system we are ready */ sockfds->append(fd_ptr); #ifdef HAVE_POLL nfds++; #endif } /* * Start work queue thread */ if ((status = workq_init(client_wq, max_clients, handle_client_request)) != 0) { berrno be; be.set_errno(status); Emsg1(M_ABORT, 0, _("Could not init client queue: ERR=%s\n"), be.bstrerror()); } #ifdef HAVE_POLL /* * Allocate on stack from -- no need to free */ pfds = (struct pollfd *)alloca(sizeof(struct pollfd) * nfds); memset(pfds, 0, sizeof(struct pollfd) * nfds); nfds = 0; events = POLLIN; #if defined(POLLRDNORM) events |= POLLRDNORM; #endif #if defined(POLLRDBAND) events |= POLLRDBAND; #endif #if defined(POLLPRI) events |= POLLPRI; #endif foreach_alist(fd_ptr, sockfds) { pfds[nfds].fd = fd_ptr->fd; pfds[nfds].events = events; nfds++; } #endif /* * Wait for a connection from the client process. */ while (!quit) { #ifndef HAVE_POLL unsigned int maxfd = 0; fd_set sockset; FD_ZERO(&sockset); foreach_alist(fd_ptr, sockfds) { FD_SET((unsigned)fd_ptr->fd, &sockset); if ((unsigned)fd_ptr->fd > maxfd) { maxfd = fd_ptr->fd; } } errno = 0; if ((status = select(maxfd + 1, &sockset, NULL, NULL, NULL)) < 0) { berrno be; /* capture errno */ if (errno == EINTR) { continue; } Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.bstrerror()); break; } foreach_alist(fd_ptr, sockfds) { if (FD_ISSET(fd_ptr->fd, &sockset)) { #else int cnt; errno = 0; if ((status = poll(pfds, nfds, -1)) < 0) { berrno be; /* capture errno */ if (errno == EINTR) { continue; } Emsg1(M_FATAL, 0, _("Error in poll: %s\n"), be.bstrerror()); break; } cnt = 0; foreach_alist(fd_ptr, sockfds) { if (pfds[cnt++].revents & events) { #endif /* * Got a connection, now accept it. */ do { clilen = sizeof(cli_addr); newsockfd = accept(fd_ptr->fd, &cli_addr, &clilen); } while (newsockfd < 0 && errno == EINTR); if (newsockfd < 0) { continue; } #ifdef HAVE_LIBWRAP P(mutex); /* hosts_access is not thread safe */ request_init(&request, RQ_DAEMON, my_name, RQ_FILE, newsockfd, 0); fromhost(&request); if (!hosts_access(&request)) { V(mutex); Jmsg2(NULL, M_SECURITY, 0, _("Connection from %s:%d refused by hosts.access\n"), sockaddr_to_ascii(&cli_addr, buf, sizeof(buf)), sockaddr_get_port(&cli_addr)); close(newsockfd); continue; } V(mutex); #endif /* * Receive notification when connection dies. */ if (setsockopt(newsockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value, sizeof(value)) < 0) { berrno be; Emsg1(M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), be.bstrerror()); } /* * See who client is. i.e. who connected to us. */ P(mutex); sockaddr_to_ascii(&cli_addr, buf, sizeof(buf)); V(mutex); BSOCK *bs; bs = New(BSOCK_TCP); if (nokeepalive) { bs->clear_keepalive(); } bs->m_fd = newsockfd; bs->set_who(bstrdup("client")); bs->set_host(bstrdup(buf)); bs->set_port(ntohs(fd_ptr->port)); memset(&bs->peer_addr, 0, sizeof(bs->peer_addr)); memcpy(&bs->client_addr, &cli_addr, sizeof(bs->client_addr)); /* * Queue client to be served */ if ((status = workq_add(client_wq, (void *)bs, NULL, 0)) != 0) { berrno be; be.set_errno(status); Jmsg1(NULL, M_ABORT, 0, _("Could not add job to client queue: ERR=%s\n"), be.bstrerror()); } } } } cleanup_bnet_thread_server_tcp(sockfds, client_wq); } bareos-Release-14.2.6/src/lib/bpipe.c000066400000000000000000000311311263011562700172370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * bpipe.c bi-directional pipe * * Kern Sibbald, November MMII */ #include "bareos.h" #include "jcr.h" int execvp_errors[] = { EACCES, ENOEXEC, EFAULT, EINTR, E2BIG, ENAMETOOLONG, ENOMEM, #ifndef HAVE_WIN32 ETXTBSY, #endif ENOENT }; int num_execvp_errors = (int)(sizeof(execvp_errors)/sizeof(int)); #define MAX_ARGV 100 #if !defined(HAVE_WIN32) static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_arg); /* * Run an external program. Optionally wait a specified number * of seconds. Program killed if wait exceeded. We open * a bi-directional pipe so that the user can read from and * write to the program. */ BPIPE *open_bpipe(char *prog, int wait, const char *mode) { char *bargv[MAX_ARGV]; int bargc, i; int readp[2], writep[2]; POOLMEM *tprog; int mode_read, mode_write; BPIPE *bpipe; int save_errno; bpipe = (BPIPE *)malloc(sizeof(BPIPE)); memset(bpipe, 0, sizeof(BPIPE)); mode_read = (mode[0] == 'r'); mode_write = (mode[0] == 'w' || mode[1] == 'w'); /* Build arguments for running program. */ tprog = get_pool_memory(PM_FNAME); pm_strcpy(tprog, prog); build_argc_argv(tprog, &bargc, bargv, MAX_ARGV); #ifdef xxxxxx printf("argc=%d\n", bargc); for (i=0; iworker_pid = fork()) { case -1: /* error */ save_errno = errno; if (mode_write) { close(writep[0]); close(writep[1]); } if (mode_read) { close(readp[0]); close(readp[1]); } free(bpipe); free_pool_memory(tprog); errno = save_errno; return NULL; case 0: /* child */ if (mode_write) { close(writep[1]); dup2(writep[0], 0); /* Dup our write to his stdin */ } if (mode_read) { close(readp[0]); /* Close unused child fds */ dup2(readp[1], 1); /* dup our read to his stdout */ dup2(readp[1], 2); /* and his stderr */ } /* Note, the close log cause problems, see bug #1536 */ /* closelog(); close syslog if open */ #if defined(HAVE_FCNTL_F_CLOSEM) /* * fcntl(fd, F_CLOSEM) needs the lowest filedescriptor to close. */ fcntl(3, F_CLOSEM); #elif defined(HAVE_CLOSEFROM) /* * closefrom needs the lowest filedescriptor to close. */ closefrom(3); #else for (i = 3; i <= 32; i++) { /* close any open file descriptors */ close(i); } #endif execvp(bargv[0], bargv); /* call the program */ /* Convert errno into an exit code for later analysis */ for (i=0; i< num_execvp_errors; i++) { if (execvp_errors[i] == errno) { exit(200 + i); /* exit code => errno */ } } exit(255); /* unknown errno */ default: /* parent */ break; } free_pool_memory(tprog); if (mode_read) { close(readp[1]); /* close unused parent fds */ bpipe->rfd = fdopen(readp[0], "r"); /* open file descriptor */ } if (mode_write) { close(writep[0]); bpipe->wfd = fdopen(writep[1], "w"); } bpipe->worker_stime = time(NULL); bpipe->wait = wait; if (wait > 0) { bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait); } return bpipe; } /* Close the write pipe only */ int close_wpipe(BPIPE *bpipe) { int status = 1; if (bpipe->wfd) { fflush(bpipe->wfd); if (fclose(bpipe->wfd) != 0) { status = 0; } bpipe->wfd = NULL; } return status; } /* * Close both pipes and free resources * * Returns: 0 on success * berrno on failure */ int close_bpipe(BPIPE *bpipe) { int chldstatus = 0; int status = 0; int wait_option; int remaining_wait; pid_t wpid = 0; /* Close pipes */ if (bpipe->rfd) { fclose(bpipe->rfd); bpipe->rfd = NULL; } if (bpipe->wfd) { fclose(bpipe->wfd); bpipe->wfd = NULL; } if (bpipe->wait == 0) { wait_option = 0; /* wait indefinitely */ } else { wait_option = WNOHANG; /* don't hang */ } remaining_wait = bpipe->wait; /* wait for worker child to exit */ for ( ;; ) { Dmsg2(800, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option); do { wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option); } while (wpid == -1 && (errno == EINTR || errno == EAGAIN)); if (wpid == bpipe->worker_pid || wpid == -1) { berrno be; status = errno; Dmsg3(800, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus, wpid==-1?be.bstrerror():"none"); break; } Dmsg3(800, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus, wpid==-1?strerror(errno):"none"); if (remaining_wait > 0) { bmicrosleep(1, 0); /* wait one second */ remaining_wait--; } else { status = ETIME; /* set error status */ wpid = -1; break; /* don't wait any longer */ } } if (wpid > 0) { if (WIFEXITED(chldstatus)) { /* process exit()ed */ status = WEXITSTATUS(chldstatus); if (status != 0) { Dmsg1(800, "Non-zero status %d returned from child.\n", status); status |= b_errno_exit; /* exit status returned */ } Dmsg1(800, "child status=%d\n", status & ~b_errno_exit); } else if (WIFSIGNALED(chldstatus)) { /* process died */ #ifndef HAVE_WIN32 status = WTERMSIG(chldstatus); #else status = 1; /* fake child status */ #endif Dmsg1(800, "Child died from signal %d\n", status); status |= b_errno_signal; /* exit signal returned */ } } if (bpipe->timer_id) { stop_child_timer(bpipe->timer_id); } free(bpipe); Dmsg2(800, "returning status=%d,%d\n", status & ~(b_errno_exit|b_errno_signal), status); return status; } /* * Build argc and argv from a string */ static void build_argc_argv(char *cmd, int *bargc, char *bargv[], int max_argv) { int i; char *p, *q, quote; int argc = 0; argc = 0; for (i=0; iSUCCESS), so we check if the watchdog killed the program. * * Contrary to my normal calling conventions, this program * * Returns: 0 on success * non-zero on error == berrno status */ int run_program(char *prog, int wait, POOLMEM *&results) { BPIPE *bpipe; int stat1, stat2; char *mode; mode = (char *)"r"; bpipe = open_bpipe(prog, wait, mode); if (!bpipe) { return ENOENT; } results[0] = 0; int len = sizeof_pool_memory(results) - 1; fgets(results, len, bpipe->rfd); results[len] = 0; if (feof(bpipe->rfd)) { stat1 = 0; } else { stat1 = ferror(bpipe->rfd); } if (stat1 < 0) { berrno be; Dmsg2(150, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror(errno)); } else if (stat1 != 0) { Dmsg1(150, "Run program fgets stat=%d\n", stat1); if (bpipe->timer_id) { Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed); /* NB: I'm not sure it is really useful for run_program. Without the * following lines run_program would not detect if the program was killed * by the watchdog. */ if (bpipe->timer_id->killed) { stat1 = ETIME; pm_strcpy(results, _("Program killed by BAREOS (timeout)\n")); } } } stat2 = close_bpipe(bpipe); stat1 = stat2 != 0 ? stat2 : stat1; Dmsg1(150, "Run program returning %d\n", stat1); return stat1; } /* * Run an external program. Optionally wait a specified number * of seconds. Program killed if wait exceeded (it is done by the * watchdog, as fgets is a blocking function). * * If the watchdog kills the program, fgets returns, and ferror is set * to 1 (=>SUCCESS), so we check if the watchdog killed the program. * * Return the full output from the program (not only the first line). * * Contrary to my normal calling conventions, this program * * Returns: 0 on success * non-zero on error == berrno status * */ int run_program_full_output(char *prog, int wait, POOLMEM *&results) { BPIPE *bpipe; int stat1, stat2; char *mode; POOLMEM* tmp; char *buf; const int bufsize = 32000; Dsm_check(200); tmp = get_pool_memory(PM_MESSAGE); buf = (char *)malloc(bufsize+1); results[0] = 0; mode = (char *)"r"; bpipe = open_bpipe(prog, wait, mode); if (!bpipe) { stat1 = ENOENT; goto bail_out; } Dsm_check(200); tmp[0] = 0; while (1) { buf[0] = 0; fgets(buf, bufsize, bpipe->rfd); buf[bufsize] = 0; pm_strcat(tmp, buf); if (feof(bpipe->rfd)) { stat1 = 0; Dmsg1(900, "Run program fgets stat=%d\n", stat1); break; } else { stat1 = ferror(bpipe->rfd); } if (stat1 < 0) { berrno be; Dmsg2(200, "Run program fgets stat=%d ERR=%s\n", stat1, be.bstrerror()); break; } else if (stat1 != 0) { Dmsg1(900, "Run program fgets stat=%d\n", stat1); if (bpipe->timer_id && bpipe->timer_id->killed) { Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed); break; } } } /* * We always check whether the timer killed the program. We would see * an eof even when it does so we just have to trust the killed flag * and set the timer values to avoid edge cases where the program ends * just as the timer kills it. */ if (bpipe->timer_id && bpipe->timer_id->killed) { Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed); pm_strcpy(tmp, _("Program killed by BAREOS (timeout)\n")); stat1 = ETIME; } pm_strcpy(results, tmp); Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results); stat2 = close_bpipe(bpipe); stat1 = stat2 != 0 ? stat2 : stat1; Dmsg1(900, "Run program returning %d\n", stat1); bail_out: free_pool_memory(tmp); free(buf); return stat1; } bareos-Release-14.2.6/src/lib/bpipe.h000066400000000000000000000017671263011562700172600ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bi-directional pipe structure */ class BPIPE { public: pid_t worker_pid; time_t worker_stime; int wait; btimer_t *timer_id; FILE *rfd; FILE *wfd; }; bareos-Release-14.2.6/src/lib/breg.c000066400000000000000000000234141263011562700170640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Manipulation routines for BREGEXP list * * Eric Bollengier, March 2007 */ #include "bareos.h" #include "breg.h" #include "mem_pool.h" BREGEXP *new_bregexp(const char *motif) { Dmsg0(500, "bregexp: creating new bregexp object\n"); BREGEXP *self = (BREGEXP *)bmalloc(sizeof(BREGEXP)); memset(self, 0, sizeof(BREGEXP)); if (!self->extract_regexp(motif)) { Dmsg0(100, "bregexp: extract_regexp error\n"); free_bregexp(self); return NULL; } self->result = get_pool_memory(PM_FNAME); self->result[0] = '\0'; return self; } void free_bregexp(BREGEXP *self) { Dmsg0(500, "bregexp: freeing BREGEXP object\n"); if (!self) { return; } if (self->expr) { bfree(self->expr); } if (self->result) { free_pool_memory(self->result); } regfree(&self->preg); bfree(self); } /* Free a bregexps alist */ void free_bregexps(alist *bregexps) { Dmsg0(500, "bregexp: freeing all BREGEXP object\n"); BREGEXP *elt; foreach_alist(elt, bregexps) { free_bregexp(elt); } } /* Apply all regexps to fname */ bool apply_bregexps(const char *fname, alist *bregexps, char **result) { BREGEXP *elt; bool ok=false; char *ret = (char *) fname; foreach_alist(elt, bregexps) { ret = elt->replace(ret); ok = ok || elt->success; } Dmsg2(500, "bregexp: fname=%s ret=%s\n", fname, ret); *result = ret; return ok; } /* return an alist of BREGEXP or return NULL if it's not a * where=!tmp!opt!ig,!temp!opt!i */ alist *get_bregexps(const char *where) { char *p = (char *)where; alist *list = New(alist(10, not_owned_by_alist)); BREGEXP *reg; reg = new_bregexp(p); while(reg) { p = reg->eor; list->append(reg); reg = new_bregexp(p); } if (list->size()) { return list; } else { delete list; return NULL; } } bool BREGEXP::extract_regexp(const char *motif) { if ( !motif ) { return false; } char sep = motif[0]; if (!(sep == '!' || sep == ':' || sep == ';' || sep == '|' || sep == ',' || sep == '&' || sep == '%' || sep == '=' || sep == '~' || sep == '/' || sep == '#' )) { return false; } char *search = (char *) motif + 1; int options = REG_EXTENDED | REG_NEWLINE; bool ok = false; /* extract 1st part */ char *dest = expr = bstrdup(motif); while (*search && !ok) { if (search[0] == '\\' && search[1] == sep) { *dest++ = *++search; /* we skip separator */ } else if (search[0] == '\\' && search[1] == '\\') { *dest++ = *++search; /* we skip the second \ */ } else if (*search == sep) { /* we found end of expression */ *dest++ = '\0'; if (subst) { /* already have found motif */ ok = true; } else { *dest++ = *++search; /* we skip separator */ subst = dest; /* get replaced string */ } } else { *dest++ = *search++; } } *dest = '\0'; /* in case of */ if (!ok || !subst) { /* bad regexp */ return false; } ok = false; /* find options */ while (*search && !ok) { if (*search == 'i') { options |= REG_ICASE; } else if (*search == 'g') { /* recherche multiple*/ } else if (*search == sep) { /* skip separator */ } else { /* end of options */ ok = true; } search++; } int rc = regcomp(&preg, expr, options); if (rc != 0) { char prbuf[500]; regerror(rc, &preg, prbuf, sizeof(prbuf)); Dmsg1(100, "bregexp: compile error: %s\n", prbuf); return false; } eor = search; /* useful to find the next regexp in where */ return true; } /* return regexp->result */ char *BREGEXP::replace(const char *fname) { success = false; /* use this.success to known if it's ok */ int flen = strlen(fname); int rc = regexec(&preg, fname, BREG_NREGS, regs, 0); if (rc == REG_NOMATCH) { Dmsg0(500, "bregexp: regex mismatch\n"); return return_fname(fname, flen); } int len = compute_dest_len(fname, regs); if (len) { result = check_pool_memory_size(result, len); edit_subst(fname, regs); success = true; Dmsg2(500, "bregexp: len = %i, result_len = %i\n", len, strlen(result)); } else { /* error in substitution */ Dmsg0(100, "bregexp: error in substitution\n"); return return_fname(fname, flen); } return result; } char *BREGEXP::return_fname(const char *fname, int len) { result = check_pool_memory_size(result, len+1); strcpy(result,fname); return result; } int BREGEXP::compute_dest_len(const char *fname, regmatch_t pmatch[]) { int len=0; char *p; char *psubst = subst; int no; if (!fname || !pmatch) { return 0; } /* match failed ? */ if (pmatch[0].rm_so < 0) { return 0; } for (p = psubst++; *p ; p = psubst++) { /* match $1 \1 back references */ if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) { no = *psubst++ - '0'; /* we check if the back reference exists */ /* references can not match if we are using (..)? */ if (pmatch[no].rm_so >= 0 && pmatch[no].rm_eo >= 0) { len += pmatch[no].rm_eo - pmatch[no].rm_so; } } else { len++; } } /* $0 is replaced by subst */ len -= pmatch[0].rm_eo - pmatch[0].rm_so; len += strlen(fname) + 1; return len; } char *BREGEXP::edit_subst(const char *fname, regmatch_t pmatch[]) { int i; char *p; char *psubst = subst; int no; int len; /* il faut recopier fname dans dest * on recopie le debut fname -> pmatch->start[0] */ for (i = 0; i < pmatch[0].rm_so ; i++) { result[i] = fname[i]; } /* on recopie le motif de remplacement (avec tous les $x) */ for (p = psubst++; *p ; p = psubst++) { /* match $1 \1 back references */ if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) { no = *psubst++ - '0'; /* have a back reference ? */ if (pmatch[no].rm_so >= 0 && pmatch[no].rm_eo >= 0) { len = pmatch[no].rm_eo - pmatch[no].rm_so; bstrncpy(result + i, fname + pmatch[no].rm_so, len + 1); i += len ; } } else { result[i++] = *p; } } /* we copy what is out of the match */ strcpy(result + i, fname + pmatch[0].rm_eo); return result; } /* escape sep char and \ * dest must be long enough (src*2+1) * return end of the string */ char *bregexp_escape_string(char *dest, const char *src, const char sep) { char *ret = dest; while (*src) { if (*src == sep) { *dest++ = '\\'; } else if (*src == '\\') { *dest++ = '\\'; } *dest++ = *src++; } *dest = '\0'; return ret; } static const char regexp_sep = '!'; static const char *str_strip_prefix = "!%s!!i"; static const char *str_add_prefix = "!^!%s!"; static const char *str_add_suffix = "!([^/])$!$1%s!"; int bregexp_get_build_where_size(char *strip_prefix, char *add_prefix, char *add_suffix) { int str_size = ((strip_prefix?strlen(strip_prefix)+strlen(str_strip_prefix):0) + (add_prefix?strlen(add_prefix)+strlen(str_add_prefix) :0) + (add_suffix?strlen(add_suffix)+strlen(str_add_suffix) :0) ) /* escape + 3*, + \0 */ * 2 + 3 + 1; Dmsg1(200, "bregexp_get_build_where_size = %i\n", str_size); return str_size; } /* build a regexp string with user arguments * Usage : * * int len = bregexp_get_build_where_size(a,b,c) ; * char *dest = (char *) bmalloc (len * sizeof(char)); * bregexp_build_where(dest, len, a, b, c); * bfree(dest); * */ char *bregexp_build_where(char *dest, int str_size, char *strip_prefix, char *add_prefix, char *add_suffix) { int len=0; POOLMEM *str_tmp = get_memory(str_size); *str_tmp = *dest = '\0'; if (strip_prefix) { len += bsnprintf(dest, str_size - len, str_strip_prefix, bregexp_escape_string(str_tmp, strip_prefix, regexp_sep)); } if (add_suffix) { if (len) dest[len++] = ','; len += bsnprintf(dest + len, str_size - len, str_add_suffix, bregexp_escape_string(str_tmp, add_suffix, regexp_sep)); } if (add_prefix) { if (len) dest[len++] = ','; len += bsnprintf(dest + len, str_size - len, str_add_prefix, bregexp_escape_string(str_tmp, add_prefix, regexp_sep)); } free_pool_memory(str_tmp); return dest; } void BREGEXP::debug() { printf("expr=[%s]\n", expr); printf("subst=[%s]\n", subst); printf("result=%s\n", NPRT(result)); } bareos-Release-14.2.6/src/lib/breg.h000066400000000000000000000064121263011562700170700ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS BREGEXP Structure definition for FileDaemon * * Eric Bollengier March 2007 */ #ifndef __BREG_H_ #define __BREG_H_ 1 //#undef HAVE_REGEX_H #ifndef HAVE_REGEX_H #include "bregex.h" #else #include #endif /* Usage: * * #include "lib/breg.h" * * BREGEXP *breg = new_bregexp("!/prod!/test!"); * char *filename = breg->replace("/prod/data.dat"); * or * char *filename = breg->result; * free_bregexp(breg); */ #define BREG_NREGS 11 /* * Structure for BREGEXP ressource */ class BREGEXP { public: POOLMEM *result; /* match result */ bool success; /* match is ok */ char *replace(const char *fname); /* return this.result */ void debug(); /* private */ POOLMEM *expr; /* search epression */ POOLMEM *subst; /* substitution */ regex_t preg; /* regex_t result of regcomp() */ regmatch_t regs[BREG_NREGS]; /* contains match */ char *eor; /* end of regexp in expr */ char *return_fname(const char *fname, int len); /* return fname as result */ char *edit_subst(const char *fname, regmatch_t pmatch[]); int compute_dest_len(const char *fname, regmatch_t pmatch[]); bool extract_regexp(const char *motif); }; /* create new BREGEXP and compile regex_t */ BREGEXP *new_bregexp(const char *motif); /* launch each bregexp on filename */ int run_bregexp(alist *bregexps, const char *fname); /* free BREGEXP (and all POOLMEM) */ void free_bregexp(BREGEXP *script); /* fill an alist with BREGEXP from where */ alist *get_bregexps(const char *where); /* apply every regexps from the alist */ bool apply_bregexps(const char *fname, alist *bregexps, char **result); /* foreach_alist free RUNSCRIPT */ void free_bregexps(alist *bregexps); /* you have to free alist */ /* get regexp size */ int bregexp_get_build_where_size(char *strip_prefix, char *add_prefix, char *add_suffix); /* get a bregexp string from user arguments * you must allocate it with bregexp_get_build_where_size(); */ char *bregexp_build_where(char *dest, int str_size, char *strip_prefix, char *add_prefix, char *add_suffix); /* escape a string to regexp format (sep and \) * dest must be long enough (dest = 2*src + 1) */ char *bregexp_escape_string(char *dest, const char *src, const char sep); #endif /* __BREG_H_ */ bareos-Release-14.2.6/src/lib/bregex.c000066400000000000000000001631011263011562700174170ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* regexpr.c * * Author: Tatu Ylonen * * Copyright (c) 1991 Tatu Ylonen, Espoo, Finland * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies. * This software is provided "as is" without express or implied * warranty. * * Created: Thu Sep 26 17:14:05 1991 ylo * Last modified: Mon Nov 4 17:06:48 1991 ylo * Ported to Think C: 19 Jan 1992 guido@cwi.nl * * This code draws many ideas from the regular expression packages by * Henry Spencer of the University of Toronto and Richard Stallman of * the Free Software Foundation. * * Emacs-specific code and syntax table code is almost directly borrowed * from GNU regexp. * * Bugs fixed and lots of reorganization by Jeffrey C. Ollie, April * 1997 Thanks for bug reports and ideas from Andrew Kuchling, Tim * Peters, Guido van Rossum, Ka-Ping Yee, Sjoerd Mullender, and * probably one or two others that I'm forgetting. * * This file modified to work with BAREOS and C++ by * Kern Sibbald, April 2006 * * This file modified to work with REG_ICASE and BAREOS by * Eric Bollengier April 2007 */ #include "bareos.h" #include "bregex.h" #define set_error(x) bufp->errmsg=((char *)(x)) #define got_error bufp->errmsg!=NULL /* The original code blithely assumed that sizeof(short) == 2. Not * always true. Original instances of "(short)x" were replaced by * SHORT(x), where SHORT is #defined below. */ #define SHORT(x) ((x) & 0x8000 ? (x) - 0x10000 : (x)) /* The stack implementation is taken from an idea by Andrew Kuchling. * It's a doubly linked list of arrays. The advantages of this over a * simple linked list are that the number of mallocs required are * reduced. It also makes it possible to statically allocate enough * space so that small patterns don't ever need to call malloc. * * The advantages over a single array is that is periodically * realloced when more space is needed is that we avoid ever copying * the stack. */ /* item_t is the basic stack element. Defined as a union of * structures so that both registers, failure points, and counters can * be pushed/popped from the stack. There's nothing built into the * item to keep track of whether a certain stack item is a register, a * failure point, or a counter. */ typedef union item_t { struct { int num; int level; unsigned char *start; unsigned char *end; } reg; struct { int count; int level; int phantom; unsigned char *code; unsigned char *text; } fail; struct { int num; int level; int count; } cntr; } item_t; #define B_STACK_PAGE_SIZE 256 #define NUM_REGISTERS 256 /* A 'page' of stack items. */ typedef struct item_page_t { item_t items[B_STACK_PAGE_SIZE]; struct item_page_t *prev; struct item_page_t *next; } item_page_t; typedef struct match_state { /* The number of registers that have been pushed onto the stack * since the last failure point. */ int count; /* Used to control when registers need to be pushed onto the * stack. */ int level; /* The number of failure points on the stack. */ int point; /* Storage for the registers. Each register consists of two * pointers to characters. So register N is represented as * start[N] and end[N]. The pointers must be converted to * offsets from the beginning of the string before returning the * registers to the calling program. */ unsigned char *start[NUM_REGISTERS]; unsigned char *end[NUM_REGISTERS]; /* Keeps track of whether a register has changed recently. */ int changed[NUM_REGISTERS]; /* Structure to encapsulate the stack. */ struct { /* index into the current page. If index == 0 and you need * to pop an item, move to the previous page and set index * = B_STACK_PAGE_SIZE - 1. Otherwise decrement index to * push a page. If index == B_STACK_PAGE_SIZE and you need * to push a page move to the next page and set index = * 0. If there is no new next page, allocate a new page * and link it in. Otherwise, increment index to push a * page. */ int index; item_page_t *current; /* Pointer to the current page. */ item_page_t first; /* First page is statically allocated. */ } stack; } match_state; /* Initialize a state object */ /* #define NEW_STATE(state) \ */ /* memset(&state, 0, (void *)(&state.stack) - (void *)(&state)); \ */ /* state.stack.current = &state.stack.first; \ */ /* state.stack.first.prev = NULL; \ */ /* state.stack.first.next = NULL; \ */ /* state.stack.index = 0; \ */ /* state.level = 1 */ #define NEW_STATE(state, nregs) \ { \ int i; \ for (i = 0; i < nregs; i++) \ { \ state.start[i] = NULL; \ state.end[i] = NULL; \ state.changed[i] = 0; \ } \ state.stack.current = &state.stack.first; \ state.stack.first.prev = NULL; \ state.stack.first.next = NULL; \ state.stack.index = 0; \ state.level = 1; \ state.count = 0; \ state.level = 0; \ state.point = 0; \ } /* Free any memory that might have been malloc'd */ #define FREE_STATE(state) \ while(state.stack.first.next != NULL) \ { \ state.stack.current = state.stack.first.next; \ state.stack.first.next = state.stack.current->next; \ free(state.stack.current); \ } /* Discard the top 'count' stack items. */ #define STACK_DISCARD(stack, count, on_error) \ stack.index -= count; \ while (stack.index < 0) \ { \ if (stack.current->prev == NULL) \ on_error; \ stack.current = stack.current->prev; \ stack.index += B_STACK_PAGE_SIZE; \ } /* Store a pointer to the previous item on the stack. Used to pop an * item off of the stack. */ #define STACK_PREV(stack, top, on_error) \ if (stack.index == 0) \ { \ if (stack.current->prev == NULL) \ on_error; \ stack.current = stack.current->prev; \ stack.index = B_STACK_PAGE_SIZE - 1; \ } \ else \ { \ stack.index--; \ } \ top = &(stack.current->items[stack.index]) /* Store a pointer to the next item on the stack. Used to push an item * on to the stack. */ #define STACK_NEXT(stack, top, on_error) \ if (stack.index == B_STACK_PAGE_SIZE) \ { \ if (stack.current->next == NULL) \ { \ stack.current->next = (item_page_t *)malloc(sizeof(item_page_t)); \ if (stack.current->next == NULL) \ on_error; \ stack.current->next->prev = stack.current; \ stack.current->next->next = NULL; \ } \ stack.current = stack.current->next; \ stack.index = 0; \ } \ top = &(stack.current->items[stack.index++]) /* Store a pointer to the item that is 'count' items back in the * stack. STACK_BACK(stack, top, 1, on_error) is equivalent to * STACK_TOP(stack, top, on_error). */ #define STACK_BACK(stack, top, count, on_error) \ { \ int index; \ item_page_t *current; \ current = stack.current; \ index = stack.index - (count); \ while (index < 0) \ { \ if (current->prev == NULL) \ on_error; \ current = current->prev; \ index += B_STACK_PAGE_SIZE; \ } \ top = &(current->items[index]); \ } /* Store a pointer to the top item on the stack. Execute the * 'on_error' code if there are no items on the stack. */ #define STACK_TOP(stack, top, on_error) \ if (stack.index == 0) \ { \ if (stack.current->prev == NULL) \ on_error; \ top = &(stack.current->prev->items[B_STACK_PAGE_SIZE - 1]); \ } \ else \ { \ top = &(stack.current->items[stack.index - 1]); \ } /* Test to see if the stack is empty */ #define STACK_EMPTY(stack) ((stack.index == 0) && \ (stack.current->prev == NULL)) /* Return the start of register 'reg' */ #define GET_REG_START(state, reg) (state.start[reg]) /* Return the end of register 'reg' */ #define GET_REG_END(state, reg) (state.end[reg]) /* Set the start of register 'reg'. If the state of the register needs * saving, push it on the stack. */ #define SET_REG_START(state, reg, text, on_error) \ if(state.changed[reg] < state.level) \ { \ item_t *item; \ STACK_NEXT(state.stack, item, on_error); \ item->reg.num = reg; \ item->reg.start = state.start[reg]; \ item->reg.end = state.end[reg]; \ item->reg.level = state.changed[reg]; \ state.changed[reg] = state.level; \ state.count++; \ } \ state.start[reg] = text /* Set the end of register 'reg'. If the state of the register needs * saving, push it on the stack. */ #define SET_REG_END(state, reg, text, on_error) \ if(state.changed[reg] < state.level) \ { \ item_t *item; \ STACK_NEXT(state.stack, item, on_error); \ item->reg.num = reg; \ item->reg.start = state.start[reg]; \ item->reg.end = state.end[reg]; \ item->reg.level = state.changed[reg]; \ state.changed[reg] = state.level; \ state.count++; \ } \ state.end[reg] = text #define PUSH_FAILURE(state, xcode, xtext, on_error) \ { \ item_t *item; \ STACK_NEXT(state.stack, item, on_error); \ item->fail.code = xcode; \ item->fail.text = xtext; \ item->fail.count = state.count; \ item->fail.level = state.level; \ item->fail.phantom = 0; \ state.count = 0; \ state.level++; \ state.point++; \ } /* Update the last failure point with a new position in the text. */ #define UPDATE_FAILURE(state, xtext, on_error) \ { \ item_t *item; \ STACK_BACK(state.stack, item, state.count + 1, on_error); \ if (!item->fail.phantom) \ { \ item_t *item2; \ STACK_NEXT(state.stack, item2, on_error); \ item2->fail.code = item->fail.code; \ item2->fail.text = xtext; \ item2->fail.count = state.count; \ item2->fail.level = state.level; \ item2->fail.phantom = 1; \ state.count = 0; \ state.level++; \ state.point++; \ } \ else \ { \ STACK_DISCARD(state.stack, state.count, on_error); \ STACK_TOP(state.stack, item, on_error); \ item->fail.text = xtext; \ state.count = 0; \ state.level++; \ } \ } #define POP_FAILURE(state, xcode, xtext, on_empty, on_error) \ { \ item_t *item; \ do \ { \ while(state.count > 0) \ { \ STACK_PREV(state.stack, item, on_error); \ state.start[item->reg.num] = item->reg.start; \ state.end[item->reg.num] = item->reg.end; \ state.changed[item->reg.num] = item->reg.level; \ state.count--; \ } \ STACK_PREV(state.stack, item, on_empty); \ xcode = item->fail.code; \ xtext = item->fail.text; \ state.count = item->fail.count; \ state.level = item->fail.level; \ state.point--; \ } \ while (item->fail.text == NULL); \ } enum regexp_compiled_ops { /* opcodes for compiled regexp */ Cend, /* end of pattern reached */ Cbol, /* beginning of line */ Ceol, /* end of line */ Cset, /* character set. Followed by 32 bytes of set. */ Cexact, /* followed by a byte to match */ Canychar, /* matches any character except newline */ Cstart_memory, /* set register start addr (followed by reg number) */ Cend_memory, /* set register end addr (followed by reg number) */ Cmatch_memory, /* match a duplicate of reg contents (regnum follows) */ Cjump, /* followed by two bytes (lsb,msb) of displacement. */ Cstar_jump, /* will change to jump/update_failure_jump at runtime */ Cfailure_jump, /* jump to addr on failure */ Cupdate_failure_jump, /* update topmost failure point and jump */ Cdummy_failure_jump, /* push a dummy failure point and jump */ Cbegbuf, /* match at beginning of buffer */ Cendbuf, /* match at end of buffer */ Cwordbeg, /* match at beginning of word */ Cwordend, /* match at end of word */ Cwordbound, /* match if at word boundary */ Cnotwordbound, /* match if not at word boundary */ Csyntaxspec, /* matches syntax code (1 byte follows) */ Cnotsyntaxspec, /* matches if syntax code does not match (1 byte follows) */ Crepeat1 }; enum regexp_syntax_op { /* syntax codes for plain and quoted characters */ Rend, /* special code for end of regexp */ Rnormal, /* normal character */ Ranychar, /* any character except newline */ Rquote, /* the quote character */ Rbol, /* match beginning of line */ Reol, /* match end of line */ Roptional, /* match preceding expression optionally */ Rstar, /* match preceding expr zero or more times */ Rplus, /* match preceding expr one or more times */ Ror, /* match either of alternatives */ Ropenpar, /* opening parenthesis */ Rclosepar, /* closing parenthesis */ Rmemory, /* match memory register */ Rextended_memory, /* \vnn to match registers 10-99 */ Ropenset, /* open set. Internal syntax hard-coded below. */ /* the following are gnu extensions to "normal" regexp syntax */ Rbegbuf, /* beginning of buffer */ Rendbuf, /* end of buffer */ Rwordchar, /* word character */ Rnotwordchar, /* not word character */ Rwordbeg, /* beginning of word */ Rwordend, /* end of word */ Rwordbound, /* word bound */ Rnotwordbound, /* not word bound */ Rnum_ops }; static int re_compile_initialized = 0; static int regexp_syntax = RE_SYNTAX_EGREP; int re_syntax = RE_SYNTAX_EGREP; /* Exported copy of regexp_syntax */ static unsigned char plain_ops[256]; static unsigned char quoted_ops[256]; static unsigned char precedences[Rnum_ops]; static int regexp_context_indep_ops; static int regexp_ansi_sequences; #define NUM_LEVELS 5 /* number of precedence levels in use */ #define MAX_NESTING 100 /* max nesting level of operators */ #define SYNTAX(ch) re_syntax_table[(unsigned char)(ch)] unsigned char re_syntax_table[256]; void re_compile_initialize(void) { int a; static int syntax_table_inited = 0; if (!syntax_table_inited) { syntax_table_inited = 1; memset(re_syntax_table, 0, 256); for (a = 'a'; a <= 'z'; a++) re_syntax_table[a] = Sword; for (a = 'A'; a <= 'Z'; a++) re_syntax_table[a] = Sword; for (a = '0'; a <= '9'; a++) re_syntax_table[a] = Sword | Sdigit | Shexdigit; for (a = '0'; a <= '7'; a++) re_syntax_table[a] |= Soctaldigit; for (a = 'A'; a <= 'F'; a++) re_syntax_table[a] |= Shexdigit; for (a = 'a'; a <= 'f'; a++) re_syntax_table[a] |= Shexdigit; re_syntax_table[(int)'_'] = Sword; for (a = 9; a <= 13; a++) re_syntax_table[a] = Swhitespace; re_syntax_table[(int)' '] = Swhitespace; } re_compile_initialized = 1; for (a = 0; a < 256; a++) { plain_ops[a] = Rnormal; quoted_ops[a] = Rnormal; } for (a = '0'; a <= '9'; a++) quoted_ops[a] = Rmemory; plain_ops[(int)'\134'] = Rquote; if (regexp_syntax & RE_NO_BK_PARENS) { plain_ops[(int)'('] = Ropenpar; plain_ops[(int)')'] = Rclosepar; } else { quoted_ops[(int)'('] = Ropenpar; quoted_ops[(int)')'] = Rclosepar; } if (regexp_syntax & RE_NO_BK_VBAR) { plain_ops[(int)'\174'] = Ror; } else { quoted_ops[(int)'\174'] = Ror; } plain_ops[(int)'*'] = Rstar; if (regexp_syntax & RE_BK_PLUS_QM) { quoted_ops[(int)'+'] = Rplus; quoted_ops[(int)'?'] = Roptional; } else { plain_ops[(int)'+'] = Rplus; plain_ops[(int)'?'] = Roptional; } if (regexp_syntax & RE_NEWLINE_OR) { plain_ops[(int)'\n'] = Ror; } plain_ops[(int)'\133'] = Ropenset; plain_ops[(int)'\136'] = Rbol; plain_ops[(int)'$'] = Reol; plain_ops[(int)'.'] = Ranychar; if (!(regexp_syntax & RE_NO_GNU_EXTENSIONS)) { quoted_ops[(int)'w'] = Rwordchar; quoted_ops[(int)'W'] = Rnotwordchar; quoted_ops[(int)'<'] = Rwordbeg; quoted_ops[(int)'>'] = Rwordend; quoted_ops[(int)'b'] = Rwordbound; quoted_ops[(int)'B'] = Rnotwordbound; quoted_ops[(int)'`'] = Rbegbuf; quoted_ops[(int)'\''] = Rendbuf; } if (regexp_syntax & RE_ANSI_HEX) { quoted_ops[(int)'v'] = Rextended_memory; } for (a = 0; a < Rnum_ops; a++) { precedences[a] = 4; } if (regexp_syntax & RE_TIGHT_VBAR) { precedences[Ror] = 3; precedences[Rbol] = 2; precedences[Reol] = 2; } else { precedences[Ror] = 2; precedences[Rbol] = 3; precedences[Reol] = 3; } precedences[Rclosepar] = 1; precedences[Rend] = 0; regexp_context_indep_ops = (regexp_syntax & RE_CONTEXT_INDEP_OPS) != 0; regexp_ansi_sequences = (regexp_syntax & RE_ANSI_HEX) != 0; } int re_set_syntax(int syntax) { int ret; ret = regexp_syntax; regexp_syntax = syntax; re_syntax = syntax; /* Exported copy */ re_compile_initialize(); return ret; } static int hex_char_to_decimal(int ch) { if (ch >= '0' && ch <= '9') return ch - '0'; if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; return 16; } static void re_compile_fastmap_aux(regex_t * bufp, unsigned char *code, int pos, unsigned char *visited, unsigned char *can_be_null, unsigned char *fastmap) { int a; int b; int syntaxcode; if (visited[pos]) return; /* we have already been here */ visited[pos] = 1; for (;;) { switch (code[pos++]) { case Cend: *can_be_null = 1; return; case Cbol: case Cbegbuf: case Cendbuf: case Cwordbeg: case Cwordend: case Cwordbound: case Cnotwordbound: for (a = 0; a < 256; a++) fastmap[a] = 1; break; case Csyntaxspec: syntaxcode = code[pos++]; for (a = 0; a < 256; a++) if (SYNTAX(a) & syntaxcode) fastmap[a] = 1; return; case Cnotsyntaxspec: syntaxcode = code[pos++]; for (a = 0; a < 256; a++) if (!(SYNTAX(a) & syntaxcode)) fastmap[a] = 1; return; case Ceol: fastmap[(int)'\n'] = 1; if (*can_be_null == 0) *can_be_null = 2; /* can match null, but only at end of buffer */ return; case Cset: for (a = 0; a < 256 / 8; a++) if (code[pos + a] != 0) for (b = 0; b < 8; b++) if (code[pos + a] & (1 << b)) fastmap[(a << 3) + b] = 1; pos += 256 / 8; return; case Cexact: fastmap[(unsigned char)code[pos]] = 1; return; case Canychar: for (a = 0; a < 256; a++) if (a != '\n') fastmap[a] = 1; return; case Cstart_memory: case Cend_memory: pos++; break; case Cmatch_memory: for (a = 0; a < 256; a++) fastmap[a] = 1; *can_be_null = 1; return; case Cjump: case Cdummy_failure_jump: case Cupdate_failure_jump: case Cstar_jump: a = (unsigned char)code[pos++]; a |= (unsigned char)code[pos++] << 8; pos += (int)SHORT(a); if (visited[pos]) { /* argh... the regexp contains empty loops. This is not good, as this may cause a failure stack overflow when matching. Oh well. */ /* this path leads nowhere; pursue other paths. */ return; } visited[pos] = 1; break; case Cfailure_jump: a = (unsigned char)code[pos++]; a |= (unsigned char)code[pos++] << 8; a = pos + (int)SHORT(a); re_compile_fastmap_aux(bufp, code, a, visited, can_be_null, fastmap); break; case Crepeat1: pos += 2; break; default: set_error("Unknown regex opcode: memory corrupted?"); return; } } } static int re_do_compile_fastmap(regex_t * bufp, unsigned char *buffer, int used, int pos, unsigned char *can_be_null, unsigned char *fastmap) { unsigned char small_visited[512], *visited; if (used <= (int)sizeof(small_visited)) visited = small_visited; else { visited = (unsigned char *)malloc(used); if (!visited) return 0; } *can_be_null = 0; memset(fastmap, 0, 256); memset(visited, 0, used); re_compile_fastmap_aux(bufp, buffer, pos, visited, can_be_null, fastmap); if (visited != small_visited) free(visited); return 1; } void re_compile_fastmap(regex_t * bufp) { if (!bufp->fastmap || bufp->fastmap_accurate) return; // assert(bufp->used > 0); if (!re_do_compile_fastmap(bufp, bufp->buffer, bufp->used, 0, &bufp->can_be_null, bufp->fastmap)) return; if (got_error) return; if (bufp->buffer[0] == Cbol) bufp->anchor = 1; /* begline */ else if (bufp->buffer[0] == Cbegbuf) bufp->anchor = 2; /* begbuf */ else bufp->anchor = 0; /* none */ bufp->fastmap_accurate = 1; } /* * star is coded as: * 1: failure_jump 2 * ... code for operand of star * star_jump 1 * 2: ... code after star * * We change the star_jump to update_failure_jump if we can determine * that it is safe to do so; otherwise we change it to an ordinary * jump. * * plus is coded as * * jump 2 * 1: failure_jump 3 * 2: ... code for operand of plus * star_jump 1 * 3: ... code after plus * * For star_jump considerations this is processed identically to star. * */ static int re_optimize_star_jump(regex_t * bufp, unsigned char *code) { unsigned char map[256]; unsigned char can_be_null; unsigned char *p1; unsigned char *p2; unsigned char ch; int a; int b; int num_instructions = 0; a = (unsigned char)*code++; a |= (unsigned char)*code++ << 8; a = (int)SHORT(a); p1 = code + a + 3; /* skip the failure_jump */ /* Check that the jump is within the pattern */ if (p1 < bufp->buffer || bufp->buffer + bufp->used < p1) { set_error("Regex VM jump out of bounds (failure_jump opt)"); return 0; } // assert(p1[-3] == Cfailure_jump); p2 = code; /* p1 points inside loop, p2 points to after loop */ if (!re_do_compile_fastmap(bufp, bufp->buffer, bufp->used, (int)(p2 - bufp->buffer), &can_be_null, map)) goto make_normal_jump; /* If we might introduce a new update point inside the * loop, we can't optimize because then update_jump would * update a wrong failure point. Thus we have to be * quite careful here. */ /* loop until we find something that consumes a character */ for (;;) { num_instructions++; switch (*p1++) { case Cbol: case Ceol: case Cbegbuf: case Cendbuf: case Cwordbeg: case Cwordend: case Cwordbound: case Cnotwordbound: continue; case Cstart_memory: case Cend_memory: p1++; continue; case Cexact: ch = (unsigned char)*p1++; if (map[(int)ch]) goto make_normal_jump; break; case Canychar: for (b = 0; b < 256; b++) if (b != '\n' && map[b]) goto make_normal_jump; break; case Cset: for (b = 0; b < 256; b++) if ((p1[b >> 3] & (1 << (b & 7))) && map[b]) goto make_normal_jump; p1 += 256 / 8; break; default: goto make_normal_jump; } break; } /* now we know that we can't backtrack. */ while (p1 != p2 - 3) { num_instructions++; switch (*p1++) { case Cend: return 0; case Cbol: case Ceol: case Canychar: case Cbegbuf: case Cendbuf: case Cwordbeg: case Cwordend: case Cwordbound: case Cnotwordbound: break; case Cset: p1 += 256 / 8; break; case Cexact: case Cstart_memory: case Cend_memory: case Cmatch_memory: case Csyntaxspec: case Cnotsyntaxspec: p1++; break; case Cjump: case Cstar_jump: case Cfailure_jump: case Cupdate_failure_jump: case Cdummy_failure_jump: goto make_normal_jump; default: return 0; } } /* make_update_jump: */ code -= 3; a += 3; /* jump to after the Cfailure_jump */ code[0] = Cupdate_failure_jump; code[1] = a & 0xff; code[2] = a >> 8; if (num_instructions > 1) return 1; // assert(num_instructions == 1); /* if the only instruction matches a single character, we can do * better */ p1 = code + 3 + a; /* start of sole instruction */ if (*p1 == Cset || *p1 == Cexact || *p1 == Canychar || *p1 == Csyntaxspec || *p1 == Cnotsyntaxspec) code[0] = Crepeat1; return 1; make_normal_jump: code -= 3; *code = Cjump; return 1; } static int re_optimize(regex_t * bufp) { unsigned char *code; code = bufp->buffer; while (1) { switch (*code++) { case Cend: return 1; case Canychar: case Cbol: case Ceol: case Cbegbuf: case Cendbuf: case Cwordbeg: case Cwordend: case Cwordbound: case Cnotwordbound: break; case Cset: code += 256 / 8; break; case Cexact: case Cstart_memory: case Cend_memory: case Cmatch_memory: case Csyntaxspec: case Cnotsyntaxspec: code++; break; case Cstar_jump: if (!re_optimize_star_jump(bufp, code)) { return 0; } /* fall through */ case Cupdate_failure_jump: case Cjump: case Cdummy_failure_jump: case Cfailure_jump: case Crepeat1: code += 2; break; default: return 0; } } } #define NEXTCHAR(var) \ { \ if (pos >= size) \ goto ends_prematurely; \ (var) = regex[pos]; \ pos++; \ } #define ALLOC(amount) \ { \ if (pattern_offset+(amount) > alloc) \ { \ alloc += 256 + (amount); \ pattern = (unsigned char *)realloc(pattern, alloc); \ if (!pattern) \ goto out_of_memory; \ } \ } #define STORE(ch) pattern[pattern_offset++] = (ch) #define CURRENT_LEVEL_START (starts[starts_base + current_level]) #define SET_LEVEL_START starts[starts_base + current_level] = pattern_offset #define PUSH_LEVEL_STARTS \ if (starts_base < (MAX_NESTING-1)*NUM_LEVELS) \ starts_base += NUM_LEVELS; \ else \ goto too_complex \ #define POP_LEVEL_STARTS starts_base -= NUM_LEVELS #define PUT_ADDR(offset,addr) \ { \ int disp = (addr) - (offset) - 2; \ pattern[(offset)] = disp & 0xff; \ pattern[(offset)+1] = (disp>>8) & 0xff; \ } #define INSERT_JUMP(pos,type,addr) \ { \ int a, p = (pos), t = (type), ad = (addr); \ for (a = pattern_offset - 1; a >= p; a--) \ pattern[a + 3] = pattern[a]; \ pattern[p] = t; \ PUT_ADDR(p+1,ad); \ pattern_offset += 3; \ } #define SETBIT(buf,offset,bit) (buf)[(offset)+(bit)/8] |= (1<<((bit) & 7)) #define SET_FIELDS \ { \ bufp->allocated = alloc; \ bufp->buffer = pattern; \ bufp->used = pattern_offset; \ } #define GETHEX(var) \ { \ unsigned char gethex_ch, gethex_value; \ NEXTCHAR(gethex_ch); \ gethex_value = hex_char_to_decimal(gethex_ch); \ if (gethex_value == 16) \ goto hex_error; \ NEXTCHAR(gethex_ch); \ gethex_ch = hex_char_to_decimal(gethex_ch); \ if (gethex_ch == 16) \ goto hex_error; \ (var) = gethex_value * 16 + gethex_ch; \ } #define ANSI_TRANSLATE(ch) \ { \ switch (ch) \ { \ case 'a': \ case 'A': \ { \ ch = 7; /* audible bell */ \ break; \ } \ case 'b': \ case 'B': \ { \ ch = 8; /* backspace */ \ break; \ } \ case 'f': \ case 'F': \ { \ ch = 12; /* form feed */ \ break; \ } \ case 'n': \ case 'N': \ { \ ch = 10; /* line feed */ \ break; \ } \ case 'r': \ case 'R': \ { \ ch = 13; /* carriage return */ \ break; \ } \ case 't': \ case 'T': \ { \ ch = 9; /* tab */ \ break; \ } \ case 'v': \ case 'V': \ { \ ch = 11; /* vertical tab */ \ break; \ } \ case 'x': /* hex code */ \ case 'X': \ { \ GETHEX(ch); \ break; \ } \ default: \ { \ /* other characters passed through */ \ if (translate) \ ch = translate[(unsigned char)ch]; \ break; \ } \ } \ } const char *re_compile_pattern(regex_t * bufp, unsigned char *regex) { int a; int pos; int op; int current_level; int level; int opcode; int pattern_offset = 0, alloc; int starts[NUM_LEVELS * MAX_NESTING]; int starts_base; int future_jumps[MAX_NESTING]; int num_jumps; unsigned char ch = '\0'; unsigned char *pattern; unsigned char *translate; int next_register; int paren_depth; int num_open_registers; int open_registers[RE_NREGS]; int beginning_context; int size = strlen((char *)regex); if (!re_compile_initialized) re_compile_initialize(); bufp->used = 0; bufp->fastmap_accurate = 0; bufp->uses_registers = 1; bufp->num_registers = 1; translate = bufp->translate; pattern = bufp->buffer; alloc = bufp->allocated; if (alloc == 0 || pattern == NULL) { alloc = 256; bufp->buffer = pattern = (unsigned char *)malloc(alloc); if (!pattern) goto out_of_memory; } pattern_offset = 0; starts_base = 0; num_jumps = 0; current_level = 0; SET_LEVEL_START; num_open_registers = 0; next_register = 1; paren_depth = 0; beginning_context = 1; op = -1; /* we use Rend dummy to ensure that pending jumps are updated (due to low priority of Rend) before exiting the loop. */ pos = 0; while (op != Rend) { if (pos >= size) op = Rend; else { NEXTCHAR(ch); if (translate) ch = translate[(unsigned char)ch]; op = plain_ops[(unsigned char)ch]; if (op == Rquote) { NEXTCHAR(ch); op = quoted_ops[(unsigned char)ch]; if (op == Rnormal && regexp_ansi_sequences) ANSI_TRANSLATE(ch); } } level = precedences[op]; /* printf("ch='%c' op=%d level=%d current_level=%d curlevstart=%d\n", ch, op, level, current_level, CURRENT_LEVEL_START); */ if (level > current_level) { for (current_level++; current_level < level; current_level++) SET_LEVEL_START; SET_LEVEL_START; } else if (level < current_level) { current_level = level; for (; num_jumps > 0 && future_jumps[num_jumps - 1] >= CURRENT_LEVEL_START; num_jumps--) PUT_ADDR(future_jumps[num_jumps - 1], pattern_offset); } switch (op) { case Rend: break; case Rnormal: normal_char: opcode = Cexact; store_opcode_and_arg: /* opcode & ch must be set */ SET_LEVEL_START; ALLOC(2); STORE(opcode); STORE(ch); break; case Ranychar: opcode = Canychar; store_opcode: SET_LEVEL_START; ALLOC(1); STORE(opcode); break; case Rquote: set_error("Rquote"); /* NOTREACHED */ break; case Rbol: if (!beginning_context) { if (regexp_context_indep_ops) goto op_error; else goto normal_char; } opcode = Cbol; goto store_opcode; case Reol: if (!((pos >= size) || ((regexp_syntax & RE_NO_BK_VBAR) ? (regex[pos] == '\174') : (pos + 1 < size && regex[pos] == '\134' && regex[pos + 1] == '\174')) || ((regexp_syntax & RE_NO_BK_PARENS) ? (regex[pos] == ')') : (pos + 1 < size && regex[pos] == '\134' && regex[pos + 1] == ')')))) { if (regexp_context_indep_ops) goto op_error; else goto normal_char; } opcode = Ceol; goto store_opcode; /* NOTREACHED */ break; case Roptional: if (beginning_context) { if (regexp_context_indep_ops) goto op_error; else goto normal_char; } if (CURRENT_LEVEL_START == pattern_offset) break; /* ignore empty patterns for ? */ ALLOC(3); INSERT_JUMP(CURRENT_LEVEL_START, Cfailure_jump, pattern_offset + 3); break; case Rstar: case Rplus: if (beginning_context) { if (regexp_context_indep_ops) goto op_error; else goto normal_char; } if (CURRENT_LEVEL_START == pattern_offset) break; /* ignore empty patterns for + and * */ ALLOC(9); INSERT_JUMP(CURRENT_LEVEL_START, Cfailure_jump, pattern_offset + 6); INSERT_JUMP(pattern_offset, Cstar_jump, CURRENT_LEVEL_START); if (op == Rplus) /* jump over initial failure_jump */ INSERT_JUMP(CURRENT_LEVEL_START, Cdummy_failure_jump, CURRENT_LEVEL_START + 6); break; case Ror: ALLOC(6); INSERT_JUMP(CURRENT_LEVEL_START, Cfailure_jump, pattern_offset + 6); if (num_jumps >= MAX_NESTING) goto too_complex; STORE(Cjump); future_jumps[num_jumps++] = pattern_offset; STORE(0); STORE(0); SET_LEVEL_START; break; case Ropenpar: { SET_LEVEL_START; if (next_register < RE_NREGS) { bufp->uses_registers = 1; ALLOC(2); STORE(Cstart_memory); STORE(next_register); open_registers[num_open_registers++] = next_register; bufp->num_registers++; next_register++; } paren_depth++; PUSH_LEVEL_STARTS; current_level = 0; SET_LEVEL_START; break; } case Rclosepar: if (paren_depth <= 0) goto parenthesis_error; POP_LEVEL_STARTS; current_level = precedences[Ropenpar]; paren_depth--; if (paren_depth < num_open_registers) { bufp->uses_registers = 1; ALLOC(2); STORE(Cend_memory); num_open_registers--; STORE(open_registers[num_open_registers]); } break; case Rmemory: if (ch == '0') goto bad_match_register; if (!(ch >= '0' && ch <= '9')) { goto bad_match_register; } bufp->uses_registers = 1; opcode = Cmatch_memory; ch -= '0'; goto store_opcode_and_arg; case Rextended_memory: NEXTCHAR(ch); if (ch < '0' || ch > '9') goto bad_match_register; NEXTCHAR(a); if (a < '0' || a > '9') goto bad_match_register; ch = 10 * (a - '0') + ch - '0'; if (ch == 0 || ch >= RE_NREGS) goto bad_match_register; bufp->uses_registers = 1; opcode = Cmatch_memory; goto store_opcode_and_arg; case Ropenset: { int complement; int prev; int offset; int range; int firstchar; SET_LEVEL_START; ALLOC(1 + 256 / 8); STORE(Cset); offset = pattern_offset; for (a = 0; a < 256 / 8; a++) STORE(0); NEXTCHAR(ch); if (translate) ch = translate[(unsigned char)ch]; if (ch == '\136') { complement = 1; NEXTCHAR(ch); if (translate) ch = translate[(unsigned char)ch]; } else complement = 0; prev = -1; range = 0; firstchar = 1; while (ch != '\135' || firstchar) { firstchar = 0; if (regexp_ansi_sequences && ch == '\134') { NEXTCHAR(ch); ANSI_TRANSLATE(ch); } if (range) { for (a = prev; a <= (int)ch; a++) SETBIT(pattern, offset, a); prev = -1; range = 0; } else if (prev != -1 && ch == '-') range = 1; else { SETBIT(pattern, offset, ch); prev = ch; } NEXTCHAR(ch); if (translate) ch = translate[(unsigned char)ch]; } if (range) SETBIT(pattern, offset, '-'); if (complement) { for (a = 0; a < 256 / 8; a++) pattern[offset + a] ^= 0xff; } break; } case Rbegbuf: { opcode = Cbegbuf; goto store_opcode; } case Rendbuf: { opcode = Cendbuf; goto store_opcode; } case Rwordchar: { opcode = Csyntaxspec; ch = Sword; goto store_opcode_and_arg; } case Rnotwordchar: { opcode = Cnotsyntaxspec; ch = Sword; goto store_opcode_and_arg; } case Rwordbeg: { opcode = Cwordbeg; goto store_opcode; } case Rwordend: { opcode = Cwordend; goto store_opcode; } case Rwordbound: { opcode = Cwordbound; goto store_opcode; } case Rnotwordbound: { opcode = Cnotwordbound; goto store_opcode; } default: { abort(); } } beginning_context = (op == Ropenpar || op == Ror); } if (starts_base != 0) goto parenthesis_error; // assert(num_jumps == 0); ALLOC(1); STORE(Cend); SET_FIELDS; if (!re_optimize(bufp)) return "Optimization error"; return NULL; op_error: SET_FIELDS; return "Badly placed special character"; bad_match_register: SET_FIELDS; return "Bad match register number"; hex_error: SET_FIELDS; return "Bad hexadecimal number"; parenthesis_error: SET_FIELDS; return "Badly placed parenthesis"; out_of_memory: SET_FIELDS; return "Out of memory"; ends_prematurely: SET_FIELDS; return "Regular expression ends prematurely"; too_complex: SET_FIELDS; return "Regular expression too complex"; } #undef CHARAT #undef NEXTCHAR #undef GETHEX #undef ALLOC #undef STORE #undef CURRENT_LEVEL_START #undef SET_LEVEL_START #undef PUSH_LEVEL_STARTS #undef POP_LEVEL_STARTS #undef PUT_ADDR #undef INSERT_JUMP #undef SETBIT #undef SET_FIELDS #define PREFETCH if (text == textend) goto fail #define NEXTCHAR(var) \ PREFETCH; \ var = (unsigned char)*text++; \ if (translate) \ var = translate[var] int regcomp(regex_t * bufp, const char *regex, int cflags) { memset(bufp, 0, sizeof(regex_t)); bufp->cflags = cflags; if (bufp->cflags & REG_ICASE) { char *p, *lcase = bstrdup(regex); for( p = lcase; *p ; p++) { *p = tolower(*p); } re_compile_pattern(bufp, (unsigned char *)lcase); bfree(lcase); } else { re_compile_pattern(bufp, (unsigned char *)regex); } if (got_error) { return -1; } return 0; } void re_registers_to_regmatch(regexp_registers_t old_regs, regmatch_t pmatch[], size_t nmatch) { if (!(nmatch == 0 && pmatch == NULL)) { size_t i = 0; /* * We have to set the last entry to -1 */ nmatch = nmatch - 1; for (i = 0; (i < nmatch) && (old_regs->start[i] > -1) ; i++) { pmatch[i].rm_so = old_regs->start[i]; pmatch[i].rm_eo = old_regs->end[i]; } pmatch[i].rm_eo = pmatch[i].rm_so = -1; } } int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { int status; int len = strlen(string); struct re_registers regs; status = re_search(preg, (unsigned char *)string, len, 0, len, ®s); if (status >= 0) { re_registers_to_regmatch(®s, pmatch, nmatch); } /* * status is the start position in the string base 0 where * the pattern was found or negative if not found. */ return status < 0 ? -1 : 0; } size_t regerror(int errcode, regex_t * preg, char *errbuf, size_t errbuf_size) { bstrncpy(errbuf, preg->errmsg, errbuf_size); return 0; } void regfree(regex_t * preg) { if (preg->lcase) { free_pool_memory(preg->lcase); preg->lcase = NULL; } if (preg->buffer) { free(preg->buffer); preg->buffer = NULL; } } int re_match(regex_t * bufp, unsigned char *string, int size, int pos, regexp_registers_t old_regs) { unsigned char *code; unsigned char *translate; unsigned char *text; unsigned char *textstart; unsigned char *textend; int a; int b; int ch; int reg; int match_end; unsigned char *regstart; unsigned char *regend; int regsize; match_state state; // assert(pos >= 0 && size >= 0); // assert(pos <= size); text = string + pos; textstart = string; textend = string + size; code = bufp->buffer; translate = bufp->translate; NEW_STATE(state, bufp->num_registers); continue_matching: switch (*code++) { case Cend: { match_end = text - textstart; if (old_regs) { old_regs->start[0] = pos; old_regs->end[0] = match_end; if (!bufp->uses_registers) { for (a = 1; a < RE_NREGS; a++) { old_regs->start[a] = -1; old_regs->end[a] = -1; } } else { for (a = 1; a < bufp->num_registers; a++) { if ((GET_REG_START(state, a) == NULL) || (GET_REG_END(state, a) == NULL)) { old_regs->start[a] = -1; old_regs->end[a] = -1; continue; } old_regs->start[a] = GET_REG_START(state, a) - textstart; old_regs->end[a] = GET_REG_END(state, a) - textstart; } for (; a < RE_NREGS; a++) { old_regs->start[a] = -1; old_regs->end[a] = -1; } } } FREE_STATE(state); return match_end - pos; } case Cbol: { if (text == textstart || text[-1] == '\n') goto continue_matching; goto fail; } case Ceol: { if (text == textend || *text == '\n') goto continue_matching; goto fail; } case Cset: { NEXTCHAR(ch); if (code[ch / 8] & (1 << (ch & 7))) { code += 256 / 8; goto continue_matching; } goto fail; } case Cexact: { NEXTCHAR(ch); if (ch != (unsigned char)*code++) goto fail; goto continue_matching; } case Canychar: { NEXTCHAR(ch); if (ch == '\n') goto fail; goto continue_matching; } case Cstart_memory: { reg = *code++; SET_REG_START(state, reg, text, goto error); goto continue_matching; } case Cend_memory: { reg = *code++; SET_REG_END(state, reg, text, goto error); goto continue_matching; } case Cmatch_memory: { reg = *code++; regstart = GET_REG_START(state, reg); regend = GET_REG_END(state, reg); if ((regstart == NULL) || (regend == NULL)) goto fail; /* or should we just match nothing? */ regsize = regend - regstart; if (regsize > (textend - text)) goto fail; if (translate) { for (; regstart < regend; regstart++, text++) if (translate[*regstart] != translate[*text]) goto fail; } else for (; regstart < regend; regstart++, text++) if (*regstart != *text) goto fail; goto continue_matching; } case Cupdate_failure_jump: { UPDATE_FAILURE(state, text, goto error); /* fall to next case */ } /* treat Cstar_jump just like Cjump if it hasn't been optimized */ case Cstar_jump: case Cjump: { a = (unsigned char)*code++; a |= (unsigned char)*code++ << 8; code += (int)SHORT(a); if (code < bufp->buffer || bufp->buffer + bufp->used < code) { set_error("Regex VM jump out of bounds (Cjump)"); FREE_STATE(state); return -2; } goto continue_matching; } case Cdummy_failure_jump: { unsigned char *failuredest; a = (unsigned char)*code++; a |= (unsigned char)*code++ << 8; a = (int)SHORT(a); // assert(*code == Cfailure_jump); b = (unsigned char)code[1]; b |= (unsigned char)code[2] << 8; failuredest = code + (int)SHORT(b) + 3; if (failuredest < bufp->buffer || bufp->buffer + bufp->used < failuredest) { set_error ("Regex VM jump out of bounds (Cdummy_failure_jump failuredest)"); FREE_STATE(state); return -2; } PUSH_FAILURE(state, failuredest, NULL, goto error); code += a; if (code < bufp->buffer || bufp->buffer + bufp->used < code) { set_error("Regex VM jump out of bounds (Cdummy_failure_jump code)"); FREE_STATE(state); return -2; } goto continue_matching; } case Cfailure_jump: { a = (unsigned char)*code++; a |= (unsigned char)*code++ << 8; a = (int)SHORT(a); if (code + a < bufp->buffer || bufp->buffer + bufp->used < code + a) { set_error("Regex VM jump out of bounds (Cfailure_jump)"); FREE_STATE(state); return -2; } PUSH_FAILURE(state, code + a, text, goto error); goto continue_matching; } case Crepeat1: { unsigned char *pinst; a = (unsigned char)*code++; a |= (unsigned char)*code++ << 8; a = (int)SHORT(a); pinst = code + a; if (pinst < bufp->buffer || bufp->buffer + bufp->used < pinst) { set_error("Regex VM jump out of bounds (Crepeat1)"); FREE_STATE(state); return -2; } /* pinst is sole instruction in loop, and it matches a * single character. Since Crepeat1 was originally a * Cupdate_failure_jump, we also know that backtracking * is useless: so long as the single-character * expression matches, it must be used. Also, in the * case of +, we've already matched one character, so + * can't fail: nothing here can cause a failure. */ switch (*pinst++) { case Cset: { if (translate) { while (text < textend) { ch = translate[(unsigned char)*text]; if (pinst[ch / 8] & (1 << (ch & 7))) text++; else break; } } else { while (text < textend) { ch = (unsigned char)*text; if (pinst[ch / 8] & (1 << (ch & 7))) text++; else break; } } break; } case Cexact: { ch = (unsigned char)*pinst; if (translate) { while (text < textend && translate[(unsigned char)*text] == ch) text++; } else { while (text < textend && (unsigned char)*text == ch) text++; } break; } case Canychar: { while (text < textend && (unsigned char)*text != '\n') text++; break; } case Csyntaxspec: { a = (unsigned char)*pinst; if (translate) { while (text < textend && (SYNTAX(translate[*text]) & a)) text++; } else { while (text < textend && (SYNTAX(*text) & a)) text++; } break; } case Cnotsyntaxspec: { a = (unsigned char)*pinst; if (translate) { while (text < textend && !(SYNTAX(translate[*text]) & a)) text++; } else { while (text < textend && !(SYNTAX(*text) & a)) text++; } break; } default: { FREE_STATE(state); set_error("Unknown regex opcode: memory corrupted?"); return -2; /*NOTREACHED*/} } /* due to the funky way + and * are compiled, the top * failure- stack entry at this point is actually a * success entry -- update it & pop it */ UPDATE_FAILURE(state, text, goto error); goto fail; /* i.e., succeed */ } case Cbegbuf: { if (text == textstart) goto continue_matching; goto fail; } case Cendbuf: { if (text == textend) goto continue_matching; goto fail; } case Cwordbeg: { if (text == textend) goto fail; if (!(SYNTAX(*text) & Sword)) goto fail; if (text == textstart) goto continue_matching; if (!(SYNTAX(text[-1]) & Sword)) goto continue_matching; goto fail; } case Cwordend: { if (text == textstart) goto fail; if (!(SYNTAX(text[-1]) & Sword)) goto fail; if (text == textend) goto continue_matching; if (!(SYNTAX(*text) & Sword)) goto continue_matching; goto fail; } case Cwordbound: { /* Note: as in gnu regexp, this also matches at the * beginning and end of buffer. */ if (text == textstart || text == textend) goto continue_matching; if ((SYNTAX(text[-1]) & Sword) ^ (SYNTAX(*text) & Sword)) goto continue_matching; goto fail; } case Cnotwordbound: { /* Note: as in gnu regexp, this never matches at the * beginning and end of buffer. */ if (text == textstart || text == textend) goto fail; if (!((SYNTAX(text[-1]) & Sword) ^ (SYNTAX(*text) & Sword))) goto continue_matching; goto fail; } case Csyntaxspec: { NEXTCHAR(ch); if (!(SYNTAX(ch) & (unsigned char)*code++)) goto fail; goto continue_matching; } case Cnotsyntaxspec: { NEXTCHAR(ch); if (SYNTAX(ch) & (unsigned char)*code++) goto fail; goto continue_matching; } default: { FREE_STATE(state); set_error("Unknown regex opcode: memory corrupted?"); return -2; /*NOTREACHED*/} } #if 0 /* This line is never reached --Guido */ abort(); #endif /* *NOTREACHED */ /* Using "break;" in the above switch statement is equivalent to "goto fail;" */ fail: POP_FAILURE(state, code, text, goto done_matching, goto error); goto continue_matching; done_matching: /* if(translated != NULL) */ /* free(translated); */ FREE_STATE(state); return -1; error: /* if (translated != NULL) */ /* free(translated); */ FREE_STATE(state); return -2; } #undef PREFETCH #undef NEXTCHAR int re_search(regex_t * bufp, unsigned char *str, int size, int pos, int range, regexp_registers_t regs) { unsigned char *fastmap; unsigned char *translate; unsigned char *text; unsigned char *partstart; unsigned char *partend; int dir; int ret; unsigned char anchor; unsigned char *string = str; if (bufp->cflags & REG_ICASE) { /* we must use string in lowercase */ int len = strlen((const char *)str); if (!bufp->lcase) { bufp->lcase = get_pool_memory(PM_FNAME); } bufp->lcase = check_pool_memory_size(bufp->lcase, len+1); unsigned char *dst = (unsigned char *)bufp->lcase; while (*string) { *dst++ = tolower(*string++); } *dst = '\0'; string = (unsigned char *)bufp->lcase; } // assert(size >= 0 && pos >= 0); // assert(pos + range >= 0 && pos + range <= size); /* Bugfix by ylo */ fastmap = bufp->fastmap; translate = bufp->translate; if (fastmap && !bufp->fastmap_accurate) { re_compile_fastmap(bufp); if (got_error) return -2; } anchor = bufp->anchor; if (bufp->can_be_null == 1) /* can_be_null == 2: can match null at eob */ fastmap = NULL; if (range < 0) { dir = -1; range = -range; } else dir = 1; if (anchor == 2) { if (pos != 0) return -1; else range = 0; } for (; range >= 0; range--, pos += dir) { if (fastmap) { if (dir == 1) { /* searching forwards */ text = string + pos; partend = string + size; partstart = text; if (translate) while (text != partend && !fastmap[(unsigned char)translate[(unsigned char)*text]]) text++; else while (text != partend && !fastmap[(unsigned char)*text]) text++; pos += text - partstart; range -= text - partstart; if (pos == size && bufp->can_be_null == 0) return -1; } else { /* searching backwards */ text = string + pos; partstart = string + pos - range; partend = text; if (translate) while (text != partstart && !fastmap[(unsigned char) translate[(unsigned char)*text]]) text--; else while (text != partstart && !fastmap[(unsigned char)*text]) text--; pos -= partend - text; range -= partend - text; } } if (anchor == 1) { /* anchored to begline */ if (pos > 0 && (string[pos - 1] != '\n')) continue; } // assert(pos >= 0 && pos <= size); ret = re_match(bufp, string, size, pos, regs); if (ret >= 0) return pos; if (ret == -2) return -2; } return -1; } /* ** Local Variables: ** mode: c ** c-file-style: "python" ** End: */ bareos-Release-14.2.6/src/lib/bregex.h000066400000000000000000000161321263011562700174250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * regexpr.h * * Author: Tatu Ylonen * * Copyright (c) 1991 Tatu Ylonen, Espoo, Finland * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies. This * software is provided "as is" without express or implied warranty. * * Created: Thu Sep 26 17:15:36 1991 ylo * Last modified: Mon Nov 4 15:49:46 1991 ylo * * Modified to work with C++ for use in BAREOS, * Kern Sibbald April, 2006 */ #ifndef b_REGEXPR_H #define b_REGEXPR_H #ifdef __cplusplus extern "C" { #endif #ifndef REGEXPR_H #define REGEXPR_H /* If we pull in this header, make sure we only get our own library * bregex.c */ #define regex_t b_regex_t #define regmatch_t b_regmatch_t #define re_syntax b_re_syntax #define re_syntax_table b_re_syntax_table #define re_compile_initialize b_re_compile_initialize #define re_set_syntax b_re_set_syntax #define re_compile_pattern b_re_compile_pattern #define re_match b_re_match #define re_search b_re_search #define re_compile_fastmap b_re_compile_fastmap #define re_comp b_re_comp #define re_exec b_re_exec #define regcomp b_regcomp #define regexec b_regexec #define regerror b_regerror #define regfree b_regfree #define RE_NREGS 100 /* number of registers available */ #define regoff_t int typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; #define REG_EXTENDED (1<<1) #define REG_ICASE (1<<2) #define REG_NOSUB (1<<3) #define REG_NEWLINE (1<<4) #define REG_NOTBOL (1<<5) #define REG_NOMATCH -1 struct regex_t { unsigned char *buffer; /* compiled pattern */ int allocated; /* allocated size of compiled pattern */ int used; /* actual length of compiled pattern */ unsigned char *fastmap; /* fastmap[ch] is true if ch can start pattern */ unsigned char *translate; /* translation to apply during compilation/matching */ unsigned char fastmap_accurate; /* true if fastmap is valid */ unsigned char can_be_null; /* true if can match empty string */ unsigned char uses_registers; /* registers are used and need to be initialized */ int num_registers; /* number of registers used */ unsigned char anchor; /* anchor: 0=none 1=begline 2=begbuf */ char *errmsg; int cflags; /* compilation flags */ POOLMEM *lcase; /* used by REG_ICASE */ }; typedef struct re_registers { int start[RE_NREGS]; /* start offset of region */ int end[RE_NREGS]; /* end offset of region */ } *regexp_registers_t; /* bit definitions for syntax */ #define RE_NO_BK_PARENS 1 /* no quoting for parentheses */ #define RE_NO_BK_VBAR 2 /* no quoting for vertical bar */ #define RE_BK_PLUS_QM 4 /* quoting needed for + and ? */ #define RE_TIGHT_VBAR 8 /* | binds tighter than ^ and $ */ #define RE_NEWLINE_OR 16 /* treat newline as or */ #define RE_CONTEXT_INDEP_OPS 32 /* ^$?*+ are special in all contexts */ #define RE_ANSI_HEX 64 /* ansi sequences (\n etc) and \xhh */ #define RE_NO_GNU_EXTENSIONS 128 /* no gnu extensions */ /* definitions for some common regexp styles */ #define RE_SYNTAX_AWK (RE_NO_BK_PARENS|RE_NO_BK_VBAR|RE_CONTEXT_INDEP_OPS) #define RE_SYNTAX_EGREP (RE_SYNTAX_AWK|RE_NEWLINE_OR) #define RE_SYNTAX_GREP (RE_BK_PLUS_QM|RE_NEWLINE_OR) #define RE_SYNTAX_EMACS 0 #define Sword 1 #define Swhitespace 2 #define Sdigit 4 #define Soctaldigit 8 #define Shexdigit 16 /* Rename all exported symbols to avoid conflicts with similarly named symbols in some systems' standard C libraries... */ extern int re_syntax; /* This is the actual syntax mask. It was added so that Python could do * syntax-dependent munging of patterns before compilation. */ extern unsigned char re_syntax_table[256]; void re_compile_initialize(void); int re_set_syntax(int syntax); /* This sets the syntax to use and returns the previous syntax. The * syntax is specified by a bit mask of the above defined bits. */ const char *re_compile_pattern(regex_t *compiled, unsigned char *regex); /* This compiles the regexp (given in regex and length in regex_size). * This returns NULL if the regexp compiled successfully, and an error * message if an error was encountered. The buffer field must be * initialized to a memory area allocated by malloc (or to NULL) before * use, and the allocated field must be set to its length (or 0 if * buffer is NULL). Also, the translate field must be set to point to a * valid translation table, or NULL if it is not used. */ int re_match(regex_t *compiled, unsigned char *string, int size, int pos, regexp_registers_t old_regs); /* This tries to match the regexp against the string. This returns the * length of the matched portion, or -1 if the pattern could not be * matched and -2 if an error (such as failure stack overflow) is * encountered. */ int re_search(regex_t *compiled, unsigned char *string, int size, int startpos, int range, regexp_registers_t regs); /* This searches for a substring matching the regexp. This returns the * first index at which a match is found. range specifies at how many * positions to try matching; positive values indicate searching * forwards, and negative values indicate searching backwards. mstop * specifies the offset beyond which a match must not go. This returns * -1 if no match is found, and -2 if an error (such as failure stack * overflow) is encountered. */ void re_compile_fastmap(regex_t *compiled); /* This computes the fastmap for the regexp. For this to have any effect, * the calling program must have initialized the fastmap field to point * to an array of 256 characters. */ int regcomp(regex_t *preg, const char *regex, int cflags); int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); size_t regerror(int errcode, regex_t *preg, char *errbuf, size_t errbuf_size); void regfree(regex_t *preg); #endif /* REGEXPR_H */ #ifdef __cplusplus } #endif #endif /* !b_REGEXPR_H */ bareos-Release-14.2.6/src/lib/bsnprintf.c000066400000000000000000000636271263011562700201640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Copyright Patrick Powell 1995 * * This code is based on code written by Patrick Powell * (papowell@astart.com) It may be used for any purpose as long * as this notice remains intact on all source code distributions. * * Adapted for BAREOS -- note there were lots of bugs in * the original code: %lld and %s were seriously broken, and * with FP turned off %f seg faulted. * * Kern Sibbald, November MMV */ #include "bareos.h" #include #define FP_OUTPUT 1 /* BAREOS uses floating point */ /* Define the following if you want all the features of * normal printf, but with all the security problems. * For BAREOS we turn this off, and it silently ignores * formats that could pose a security problem. */ #undef SECURITY_PROBLEM #ifdef USE_BSNPRINTF #ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args); static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, const char *value, int flags, int min, int max); static int32_t fmtwstr(char *buffer, int32_t currlen, int32_t maxlen, const wchar_t *value, int flags, int min, int max); static int32_t fmtint(char *buffer, int32_t currlen, int32_t maxlen, int64_t value, int base, int min, int max, int flags); #ifdef FP_OUTPUT # ifdef HAVE_FCVTL # define fcvt fcvtl # endif static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, LDOUBLE fvalue, int min, int max, int flags); #else #define fmtfp(b, c, m, f, min, max, fl) currlen #endif /* * NOTE!!!! do not use this #define with a construct such * as outch(--place);. It just will NOT work, because the * decrement of place is done ONLY if there is room in the * output buffer. */ #define outch(c) {int len=currlen; if (currlen < maxlen) \ { buffer[len] = (c); currlen++; }} /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) #define DP_F_DOT (1 << 7) /* Conversion Flags */ #define DP_C_INT16 1 #define DP_C_INT32 2 #define DP_C_LDOUBLE 3 #define DP_C_INT64 4 #define DP_C_WCHAR 5 /* wide characters */ #define DP_C_SIZE_T 6 #define char_to_int(p) ((p)- '0') #undef MAX #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) /* You might ask why does BAREOS have it's own printf routine? Well, There are two reasons: 1. Here (as opposed to library routines), we define %d and %ld to be 32 bit; %lld and %q to be 64 bit. 2. We disable %n for security reasons. */ int bsnprintf(char *str, int32_t size, const char *fmt, ...) { va_list arg_ptr; int len; va_start(arg_ptr, fmt); len = bvsnprintf(str, size, fmt, arg_ptr); va_end(arg_ptr); return len; } int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) { char ch; int64_t value; char *strvalue; wchar_t *wstrvalue; int min; int max; int state; int flags; int cflags; int32_t currlen; int base; #ifdef FP_OUTPUT LDOUBLE fvalue; #endif state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; ch = *format++; *buffer = 0; while (state != DP_S_DONE) { if ((ch == '\0') || (currlen >= maxlen)) { state = DP_S_DONE; } switch (state) { case DP_S_DEFAULT: if (ch == '%') { state = DP_S_FLAGS; } else { outch(ch); } ch = *format++; break; case DP_S_FLAGS: switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; break; case '+': flags |= DP_F_PLUS; ch = *format++; break; case ' ': flags |= DP_F_SPACE; ch = *format++; break; case '#': flags |= DP_F_NUM; ch = *format++; break; case '0': flags |= DP_F_ZERO; ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { min = 10 * min + char_to_int(ch); ch = *format++; } else if (ch == '*') { min = va_arg(args, int); ch = *format++; state = DP_S_DOT; } else state = DP_S_DOT; break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; flags |= DP_F_DOT; ch = *format++; } else state = DP_S_MOD; break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10 * max + char_to_int(ch); ch = *format++; } else if (ch == '*') { max = va_arg(args, int); ch = *format++; state = DP_S_MOD; } else state = DP_S_MOD; break; case DP_S_MOD: switch (ch) { case 'h': cflags = DP_C_INT16; ch = *format++; break; case 'l': cflags = DP_C_INT32; ch = *format++; if (ch == 's') { cflags = DP_C_WCHAR; } else if (ch == 'l') { /* It's a long long */ cflags = DP_C_INT64; ch = *format++; } break; case 'z': cflags = DP_C_SIZE_T; ch = *format++; break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; break; case 'q': /* same as long long */ cflags = DP_C_INT64; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { case 'd': case 'i': if (cflags == DP_C_INT16) { value = va_arg(args, int32_t); } else if (cflags == DP_C_INT32) { value = va_arg(args, int32_t); } else if (cflags == DP_C_INT64) { value = va_arg(args, int64_t); } else if (cflags == DP_C_SIZE_T) { value = va_arg(args, ssize_t); } else { value = va_arg(args, int); } currlen = fmtint(buffer, currlen, maxlen, value, 10, min, max, flags); break; case 'X': case 'x': case 'o': case 'u': if (ch == 'o') { base = 8; } else if (ch == 'x') { base = 16; } else if (ch == 'X') { base = 16; flags |= DP_F_UP; } else { base = 10; } flags |= DP_F_UNSIGNED; if (cflags == DP_C_INT16) { value = va_arg(args, uint32_t); } else if (cflags == DP_C_INT32) { value = va_arg(args, uint32_t); } else if (cflags == DP_C_INT64) { value = va_arg(args, uint64_t); } else if (cflags == DP_C_SIZE_T) { value = va_arg(args, size_t); } else { value = va_arg(args, unsigned int); } currlen = fmtint(buffer, currlen, maxlen, value, base, min, max, flags); break; case 'f': if (cflags == DP_C_LDOUBLE) { fvalue = va_arg(args, LDOUBLE); } else { fvalue = va_arg(args, double); } currlen = fmtfp(buffer, currlen, maxlen, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) { fvalue = va_arg(args, LDOUBLE); } else { fvalue = va_arg(args, double); } currlen = fmtfp(buffer, currlen, maxlen, fvalue, min, max, flags); break; case 'G': flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) { fvalue = va_arg(args, LDOUBLE); } else { fvalue = va_arg(args, double); } currlen = fmtfp(buffer, currlen, maxlen, fvalue, min, max, flags); break; case 'c': ch = va_arg(args, int); outch(ch); break; case 's': if (cflags != DP_C_WCHAR) { strvalue = va_arg(args, char *); if (!strvalue) { strvalue = (char *)""; } currlen = fmtstr(buffer, currlen, maxlen, strvalue, flags, min, max); } else { /* %ls means to edit wide characters */ wstrvalue = va_arg(args, wchar_t *); if (!wstrvalue) { wstrvalue = (wchar_t *)L""; } currlen = fmtwstr(buffer, currlen, maxlen, wstrvalue, flags, min, max); } break; case 'p': flags |= DP_F_UNSIGNED; if (sizeof(char *) == 4) { value = va_arg(args, uint32_t); } else if (sizeof(char *) == 8) { value = va_arg(args, uint64_t); } else { value = 0; /* we have a problem */ } currlen = fmtint(buffer, currlen, maxlen, value, 16, min, max, flags); break; #ifdef SECURITY_PROBLEM case 'n': if (cflags == DP_C_INT16) { int16_t *num; num = va_arg(args, int16_t *); *num = currlen; } else if (cflags == DP_C_INT32) { int32_t *num; num = va_arg(args, int32_t *); *num = (int32_t)currlen; } else if (cflags == DP_C_INT64) { int64_t *num; num = va_arg(args, int64_t *); *num = (int64_t)currlen; } else { int32_t *num; num = va_arg(args, int32_t *); *num = (int32_t)currlen; } break; #endif case '%': outch(ch); break; case 'w': /* not supported yet, treat as next char */ ch = *format++; break; default: /* Unknown, skip */ break; } ch = *format++; state = DP_S_DEFAULT; flags = cflags = min = 0; max = -1; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } if (currlen < maxlen - 1) { buffer[currlen] = '\0'; } else { buffer[maxlen - 1] = '\0'; } return currlen; } static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, const char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; char ch; if (flags & DP_F_DOT && max < 0) { /* Max not specified */ max = 0; } else if (max < 0) { max = maxlen; } strln = strlen(value); if (strln > max) { strln = max; /* truncate to max */ } padlen = min - strln; if (padlen < 0) { padlen = 0; } if (flags & DP_F_MINUS) { padlen = -padlen; /* Left Justify */ } while (padlen > 0) { outch(' '); --padlen; } while (*value && (cnt < max)) { ch = *value++; outch(ch); ++cnt; } while (padlen < 0) { outch(' '); ++padlen; } return currlen; } static int32_t fmtwstr(char *buffer, int32_t currlen, int32_t maxlen, const wchar_t *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; char ch; if (flags & DP_F_DOT && max < 0) { /* Max not specified */ max = 0; } else if (max < 0) { max = maxlen; } strln = wcslen(value); if (strln > max) { strln = max; /* truncate to max */ } padlen = min - strln; if (padlen < 0) { padlen = 0; } if (flags & DP_F_MINUS) { padlen = -padlen; /* Left Justify */ } while (padlen > 0) { outch(' '); --padlen; } while (*value && (cnt < max)) { ch = (*value++) & 0xff; outch(ch); ++cnt; } while (padlen < 0) { outch(' '); ++padlen; } return currlen; } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static int32_t fmtint(char *buffer, int32_t currlen, int32_t maxlen, int64_t value, int base, int min, int max, int flags) { int signvalue = 0; uint64_t uvalue; char convert[25]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; const char *cvt_string; if (max < 0) { max = 0; } uvalue = value; if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; uvalue = -value; } else if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ signvalue = '+'; } else if (flags & DP_F_SPACE) { signvalue = ' '; } } if (flags & DP_F_UP) { caps = 1; /* Should characters be upper case? */ } cvt_string = caps ? "0123456789ABCDEF" : "0123456789abcdef"; do { convert[place++] = cvt_string[uvalue % (unsigned)base]; uvalue = (uvalue / (unsigned)base); } while (uvalue && (place < (int)sizeof(convert))); if (place == (int)sizeof(convert)) { place--; } convert[place] = 0; zpadlen = max - place; spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); #endif /* Spaces */ while (spadlen > 0) { outch(' '); --spadlen; } /* Sign */ if (signvalue) { outch(signvalue); } /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { outch('0'); --zpadlen; } } /* Output digits backward giving correct order */ while (place > 0) { place--; outch(convert[place]); } /* Left Justified spaces */ while (spadlen < 0) { outch(' '); ++spadlen; } return currlen; } #ifdef FP_OUTPUT static LDOUBLE abs_val(LDOUBLE value) { LDOUBLE result = value; if (value < 0) result = -value; return result; } static LDOUBLE pow10(int exp) { LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result; } static int64_t round(LDOUBLE value) { int64_t intpart; intpart = (int64_t)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; LDOUBLE ufvalue; #ifndef HAVE_FCVT char iconvert[311]; char fconvert[311]; #else char iconvert[311]; char fconvert[311]; char *result; char dummy[10]; int dec_pt, sig; int r_length; extern char *fcvt(double value, int ndigit, int *decpt, int *sign); #endif int fiter; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int64_t intpart; int64_t fracpart; const char *cvt_str; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val(fvalue); if (fvalue < 0) signvalue = '-'; else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; #ifndef HAVE_FCVT intpart = (int64_t)ufvalue; /* * Sorry, we only support 9 digits past the decimal because of our * conversion method */ if (max > 9) max = 9; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ fracpart = round((pow10(max)) * (ufvalue - intpart)); if (fracpart >= pow10(max)) { intpart++; fracpart -= (int64_t)pow10(max); } #ifdef DEBUG_SNPRINTF printf("fmtfp: %g %lld.%lld min=%d max=%d\n", (double)fvalue, intpart, fracpart, min, max); #endif /* Convert integer part */ cvt_str = "0123456789"; do { iconvert[iplace++] = cvt_str[(int)(intpart % 10)]; intpart = (intpart / 10); } while (intpart && (iplace < (int)sizeof(iconvert))); if (iplace == (int)sizeof(fconvert)) { iplace--; } iconvert[iplace] = 0; /* Convert fractional part */ cvt_str = "0123456789"; fiter = max; do { fconvert[fplace++] = cvt_str[fracpart % 10]; fracpart = (fracpart / 10); } while (--fiter); if (fplace == (int)sizeof(fconvert)) { fplace--; } fconvert[fplace] = 0; #else /* use fcvt() */ if (max > 310) { max = 310; } # ifdef HAVE_FCVTL result = fcvtl(ufvalue, max, &dec_pt, &sig); # else result = fcvt(ufvalue, max, &dec_pt, &sig); # endif if (!result) { r_length = 0; dummy[0] = 0; result = dummy; } else { r_length = strlen(result); } /* * Fix broken fcvt implementation returns.. */ if (r_length == 0) { result[0] = '0'; result[1] = '\0'; r_length = 1; } if (r_length < dec_pt) dec_pt = r_length; if (dec_pt <= 0) { iplace = 1; iconvert[0] = '0'; iconvert[1] = '\0'; fplace = 0; while (r_length) { fconvert[fplace++] = result[--r_length]; } while ((dec_pt < 0) && (fplace < max)) { fconvert[fplace++] = '0'; dec_pt++; } } else { int c; iplace = 0; for (c = dec_pt; c; iconvert[iplace++] = result[--c]); iconvert[iplace] = '\0'; result += dec_pt; fplace = 0; for (c = (r_length - dec_pt); c; fconvert[fplace++] = result[--c]); } #endif /* HAVE_FCVT */ /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) { zpadlen = 0; } if (padlen < 0) { padlen = 0; } if (flags & DP_F_MINUS) { padlen = -padlen; /* Left Justifty */ } if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { outch(signvalue); --padlen; signvalue = 0; } while (padlen > 0) { outch('0'); --padlen; } } while (padlen > 0) { outch(' '); --padlen; } if (signvalue) { outch(signvalue); } while (iplace > 0) { iplace--; outch(iconvert[iplace]); } #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { outch('.'); while (fplace > 0) { fplace--; outch(fconvert[fplace]); } } while (zpadlen > 0) { outch('0'); --zpadlen; } while (padlen < 0) { outch(' '); ++padlen; } return currlen; } #endif /* FP_OUTPUT */ #ifdef TEST_PROGRAM #ifndef LONG_STRING #define LONG_STRING 1024 #endif int main(int argc, char *argv[]) { char buf1[LONG_STRING]; char buf2[LONG_STRING]; #ifdef FP_OUTPUT const char *fp_fmt[] = { "%-1.5f", "%1.5f", "%123.9f", "%10.5f", "% 10.5f", "%+22.9f", "%+4.9f", "%01.3f", "%4f", "%3.1f", "%3.2f", "%.0f", "%.1f", NULL }; double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, 4.136, 6442452944.1234, 0, 23365.5 }; #endif const char *int_fmt[] = { "%-1.5d", "%1.5d", "%123.9d", "%5.5d", "%10.5d", "% 10.5d", "%+22.33d", "%01.3d", "%4d", "%-1.5ld", "%1.5ld", "%123.9ld", "%5.5ld", "%10.5ld", "% 10.5ld", "%+22.33ld", "%01.3ld", "%4ld", NULL }; long int_nums[] = { -1, 134, 91340, 341, 0203, 0 }; const char *ll_fmt[] = { "%-1.8lld", "%1.8lld", "%123.9lld", "%5.8lld", "%10.5lld", "% 10.8lld", "%+22.33lld", "%01.3lld", "%4lld", NULL }; int64_t ll_nums[] = { -1976, 789134567890LL, 91340, 34123, 0203, 0 }; const char *s_fmt[] = { "%-1.8s", "%1.8s", "%123.9s", "%5.8s", "%10.5s", "% 10.3s", "%+22.1s", "%01.3s", "%s", "%10s", "%3s", "%3.0s", "%3.s", NULL }; const char *s_nums[] = { "abc", "def", "ghi", "123", "4567", "a", "bb", "ccccccc", NULL}; const char *ls_fmt[] = { "%-1.8ls", "%1.8ls", "%123.9ls", "%5.8ls", "%10.5ls", "% 10.3ls", "%+22.1ls", "%01.3ls", "%ls", "%10ls", "%3ls", "%3.0ls", "%3.ls", NULL }; const wchar_t *ls_nums[] = { L"abc", L"def", L"ghi", L"123", L"4567", L"a", L"bb", L"ccccccc", NULL}; int x, y; int fail = 0; int num = 0; printf("Testing snprintf format codes against system sprintf...\n"); #ifdef FP_OUTPUT for (x = 0; fp_fmt[x] != NULL; x++) for (y = 0; fp_nums[y] != 0; y++) { bsnprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); sprintf(buf2, fp_fmt[x], fp_nums[y]); if (!bstrcmp(buf1, buf2)) { printf ("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", fp_fmt[x], buf1, buf2); fail++; } num++; } #endif for (x = 0; int_fmt[x] != NULL; x++) for (y = 0; int_nums[y] != 0; y++) { int pcount, bcount; bcount = bsnprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); printf("%s\n", buf1); pcount = sprintf(buf2, int_fmt[x], int_nums[y]); if (bcount != pcount) { printf("bsnprintf count %d doesn't match sprintf count %d\n", bcount, pcount); } if (!bstrcmp(buf1, buf2)) { printf ("bsnprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", int_fmt[x], buf1, buf2); fail++; } num++; } for (x = 0; ll_fmt[x] != NULL; x++) { for (y = 0; ll_nums[y] != 0; y++) { int pcount, bcount; bcount = bsnprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]); printf("%s\n", buf1); pcount = sprintf(buf2, ll_fmt[x], ll_nums[y]); if (bcount != pcount) { printf("bsnprintf count %d doesn't match sprintf count %d\n", bcount, pcount); } if (!bstrcmp(buf1, buf2)) { printf ("bsnprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", ll_fmt[x], buf1, buf2); fail++; } num++; } } for (x = 0; s_fmt[x] != NULL; x++) { for (y = 0; s_nums[y] != 0; y++) { int pcount, bcount; bcount = bsnprintf(buf1, sizeof(buf1), s_fmt[x], s_nums[y]); printf("%s\n", buf1); pcount = sprintf(buf2, s_fmt[x], s_nums[y]); if (bcount != pcount) { printf("bsnprintf count %d doesn't match sprintf count %d\n", bcount, pcount); } if (!bstrcmp(buf1, buf2)) { printf ("bsnprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", s_fmt[x], buf1, buf2); fail++; } num++; } } for (x = 0; ls_fmt[x] != NULL; x++) { for (y = 0; ls_nums[y] != 0; y++) { int pcount, bcount; bcount = bsnprintf(buf1, sizeof(buf1), ls_fmt[x], ls_nums[y]); printf("%s\n", buf1); pcount = sprintf(buf2, ls_fmt[x], ls_nums[y]); if (bcount != pcount) { printf("bsnprintf count %d doesn't match sprintf count %d\n", bcount, pcount); } if (!bstrcmp(buf1, buf2)) { printf ("bsnprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", ls_fmt[x], buf1, buf2); fail++; } num++; } } printf("%d tests failed out of %d.\n", fail, num); exit(fail > 0); } #endif /* TEST_PROGRAM */ #endif /* USE_BSNPRINTF */ bareos-Release-14.2.6/src/lib/bsock.c000066400000000000000000000276641263011562700172610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Network Utility Routines * * Kern Sibbald */ #include "bareos.h" #include "jcr.h" BSOCK::BSOCK() { m_fd = -1; m_spool_fd = -1; msg = get_pool_memory(PM_BSOCK); errmsg = get_pool_memory(PM_MESSAGE); m_blocking = true; m_use_keepalive = true; } BSOCK::~BSOCK() { } /* * This is our "class destructor" that ensures that we use * smartalloc rather than the system free(). */ void BSOCK::free_bsock() { destroy(); } void BSOCK::free_tls() { free_tls_connection(this->tls); this->tls = NULL; } /* * Copy the address from the configuration dlist that gets passed in */ void BSOCK::set_source_address(dlist *src_addr_list) { char allbuf[256 * 10]; IPADDR *addr = NULL; Dmsg1(100, "All source addresses %s\n", build_addresses_str(src_addr_list, allbuf, sizeof(allbuf))); /* * Delete the object we already have, if it's allocated */ if (src_addr) { free( src_addr); src_addr = NULL; } if (src_addr_list) { addr = (IPADDR*) src_addr_list->first(); src_addr = New(IPADDR(*addr)); } } /* * Force read/write to use locking */ bool BSOCK::set_locking() { int status; if (m_use_locking) { return true; /* already set */ } if ((status = pthread_mutex_init(&m_mutex, NULL)) != 0) { berrno be; Qmsg(m_jcr, M_FATAL, 0, _("Could not init bsock mutex. ERR=%s\n"), be.bstrerror(status)); return false; } m_use_locking = true; return true; } void BSOCK::clear_locking() { if (!m_use_locking) { return; } m_use_locking = false; pthread_mutex_destroy(&m_mutex); return; } /* * Send a signal */ bool BSOCK::signal(int signal) { msglen = signal; if (signal == BNET_TERMINATE) { m_suppress_error_msgs = true; } return send(); } /* * Despool spooled attributes */ bool BSOCK::despool(void update_attr_spool_size(ssize_t size), ssize_t tsize) { int32_t pktsiz; size_t nbytes; ssize_t last = 0, size = 0; int count = 0; JCR *jcr = get_jcr(); if (lseek(m_spool_fd, 0, SEEK_SET) == -1) { Qmsg(jcr, M_FATAL, 0, _("attr spool I/O error.\n")); return false; } #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) posix_fadvise(m_spool_fd, 0, 0, POSIX_FADV_WILLNEED); #endif while ((nbytes = read(m_spool_fd, (char *)&pktsiz, sizeof(int32_t))) == sizeof(int32_t)) { size += sizeof(int32_t); msglen = ntohl(pktsiz); if (msglen > 0) { if (msglen > (int32_t)sizeof_pool_memory(msg)) { msg = realloc_pool_memory(msg, msglen + 1); } nbytes = read(m_spool_fd, msg, msglen); if (nbytes != (size_t)msglen) { berrno be; Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, msglen); Qmsg1(get_jcr(), M_FATAL, 0, _("read attr spool error. ERR=%s\n"), be.bstrerror()); update_attr_spool_size(tsize - last); return false; } size += nbytes; if ((++count & 0x3F) == 0) { update_attr_spool_size(size - last); last = size; } } send(); if (jcr && job_canceled(jcr)) { return false; } } update_attr_spool_size(tsize - last); return true; } /* * Return the string for the error that occurred * on the socket. Only the first error is retained. */ const char *BSOCK::bstrerror() { berrno be; if (errmsg == NULL) { errmsg = get_pool_memory(PM_MESSAGE); } pm_strcpy(errmsg, be.bstrerror(b_errno)); return errmsg; } /* * Format and send a message * Returns: false on error * true on success */ bool BSOCK::fsend(const char *fmt, ...) { va_list arg_ptr; int maxlen; if (errors || is_terminated()) { return false; } /* This probably won't work, but we vsnprintf, then if we * get a negative length or a length greater than our buffer * (depending on which library is used), the printf was truncated, so * get a bigger buffer and try again. */ for (;;) { maxlen = sizeof_pool_memory(msg) - 1; va_start(arg_ptr, fmt); msglen = bvsnprintf(msg, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (msglen >= 0 && msglen < (maxlen - 5)) { break; } msg = realloc_pool_memory(msg, maxlen + maxlen / 2); } return send(); } void BSOCK::set_killable(bool killable) { if (m_jcr) { m_jcr->set_killable(killable); } } /* Commands sent to Director */ static char hello[] = "Hello %s calling\n"; /* Response from Director */ static char OKhello[] = "1000 OK:"; /* * Authenticate Director */ bool BSOCK::authenticate_with_director(const char *name, const char *password, TLS_CONTEXT *tls_ctx, char *response, int response_len) { int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; char bashed_name[MAX_NAME_LENGTH]; BSOCK *dir = this; /* for readability */ response[0] = 0; /* * Send my name to the Director then do authentication */ bstrncpy(bashed_name, name, sizeof(bashed_name)); bash_spaces(bashed_name); /* * Timeout Hello after 5 mins */ dir->start_timer(60 * 5); dir->fsend(hello, bashed_name); if (get_tls_enable(tls_ctx)) { tls_local_need = get_tls_require(tls_ctx) ? BNET_TLS_REQUIRED : BNET_TLS_OK; } /* * Respond to Dir challenge and then challenge the Dir. */ if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) || !cram_md5_challenge(dir, password, tls_local_need, compatible)) { bsnprintf(response, response_len, _("Director authorization problem at \"%s:%d\"\n"), dir->host(), dir->port()); goto bail_out; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { bsnprintf(response, response_len, _("Authorization problem:" " Remote server at \"%s:%d\" did not advertise required TLS support.\n"), dir->host(), dir->port()); goto bail_out; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { bsnprintf(response, response_len, _("Authorization problem with Director at \"%s:%d\":" " Remote server requires TLS.\n"), dir->host(), dir->port()); goto bail_out; } /* * Is TLS Enabled? */ if (have_tls) { if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { /* * Engage TLS! Full Speed Ahead! */ if (!bnet_tls_client(tls_ctx, dir, NULL)) { bsnprintf(response, response_len, _("TLS negotiation failed with Director at \"%s:%d\"\n"), dir->host(), dir->port()); goto bail_out; } } } Dmsg1(6, ">dird: %s", dir->msg); if (dir->recv() <= 0) { dir->stop_timer(); bsnprintf(response, response_len, _("Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n"), dir->bstrerror(), dir->host(), dir->port()); return false; } dir->stop_timer(); Dmsg1(10, "msg); if (!bstrncmp(dir->msg, OKhello, sizeof(OKhello) - 1)) { bsnprintf(response, response_len, _("Director at \"%s:%d\" rejected Hello command\n"), dir->host(), dir->port()); return false; } else { bsnprintf(response, response_len, "%s", dir->msg); } return true; bail_out: dir->stop_timer(); bsnprintf(response, response_len, _("Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate " "validation error during the TLS handshake.\n" "Please see %s for help.\n"), dir->host(), dir->port(), MANUAL_AUTH_URL); return false; } /* * Try to limit the bandwidth of a network connection */ void BSOCK::control_bwlimit(int bytes) { btime_t now, temp; int64_t usec_sleep; /* * If nothing written or read nothing todo. */ if (bytes == 0) { return; } /* * See if this is the first time we enter here. */ now = get_current_btime(); if (m_last_tick == 0) { m_nb_bytes = bytes; m_last_tick = now; return; } /* * Calculate the number of microseconds since the last check. */ temp = now - m_last_tick; /* * Less than 0.1ms since the last call, see the next time */ if (temp < 100) { m_nb_bytes += bytes; return; } /* * Keep track of how many bytes are written in this timeslice. */ m_nb_bytes += bytes; m_last_tick = now; if (debug_level >= 400) { Dmsg3(400, "control_bwlimit: now = %lld, since = %lld, nb_bytes = %d\n", now, temp, m_nb_bytes); } /* * Take care of clock problems (>10s) */ if (temp > 10000000) { return; } /* * Remove what was authorised to be written in temp usecs. */ m_nb_bytes -= (int64_t)(temp * ((double)m_bwlimit / 1000000.0)); if (m_nb_bytes < 0) { /* * If more was authorized then used but bursting is not enabled * reset the counter as these bytes cannot be used later on when * we are exceeding our bandwidth. */ if (!m_use_bursting) { m_nb_bytes = 0; } return; } /* * What exceed should be converted in sleep time */ usec_sleep = (int64_t)(m_nb_bytes /((double)m_bwlimit / 1000000.0)); if (usec_sleep > 100) { if (debug_level >= 400) { Dmsg1(400, "control_bwlimit: sleeping for %lld usecs\n", usec_sleep); } /* * Sleep the right number of usecs. */ while (1) { bmicrosleep(0, usec_sleep); now = get_current_btime(); /* * See if we slept enough or that bmicrosleep() returned early. */ if ((now - m_last_tick) < usec_sleep) { usec_sleep -= (now - m_last_tick); continue; } else { m_last_tick = now; break; } } /* * Subtract the number of bytes we could have sent during the sleep * time given the bandwidth limit set. We only do this when we are * allowed to burst e.g. use unused bytes from previous timeslices * to get an overall bandwidth limiting which may sometimes be below * the bandwidth and sometimes above it but the average will be near * the set bandwidth. */ if (m_use_bursting) { m_nb_bytes -= (int64_t)(usec_sleep * ((double)m_bwlimit / 1000000.0)); } else { m_nb_bytes = 0; } } } bareos-Release-14.2.6/src/lib/bsock.h000066400000000000000000000246311263011562700172550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Sock Class definition * Note, the old non-class code is in bnet.c, and the * new class code associated with this file is in bsock.c * * Kern Sibbald, May MM * * Zero msglen from other end indicates soft eof (usually * end of some binary data stream, but not end of conversation). * * Negative msglen, is special "signal" (no data follows). * See below for SIGNAL codes. */ #ifndef BRS_BSOCK_H #define BRS_BSOCK_H struct btimer_t; /* forward reference */ class BSOCK; btimer_t *start_bsock_timer(BSOCK *bs, uint32_t wait); void stop_bsock_timer(btimer_t *wid); class BSOCK : public SMARTALLOC { /* * Note, keep this public part before the private otherwise * bat breaks on some systems such as RedHat. */ public: int m_fd; /* Socket file descriptor */ uint64_t read_seqno; /* Read sequence number */ POOLMEM *msg; /* Message pool buffer */ POOLMEM *errmsg; /* Edited error message */ RES *res; /* Resource to which we are connected */ int m_spool_fd; /* Spooling file */ TLS_CONNECTION *tls; /* Associated tls connection */ IPADDR *src_addr; /* IP address to source connections from */ uint32_t in_msg_no; /* Input message number */ uint32_t out_msg_no; /* Output message number */ int32_t msglen; /* Message length */ volatile time_t timer_start; /* Time started read/write */ int b_errno; /* BSOCK errno */ int m_blocking; /* Blocking state (0 = nonblocking, 1 = blocking) */ volatile int errors; /* Incremented for each error on socket */ volatile bool m_suppress_error_msgs; /* Set to suppress error messages */ struct sockaddr client_addr; /* Client's IP address */ struct sockaddr_in peer_addr; /* Peer's IP address */ protected: JCR *m_jcr; /* JCR or NULL for error msgs */ pthread_mutex_t m_mutex; /* For locking if use_locking set */ char *m_who; /* Name of daemon to which we are talking */ char *m_host; /* Host name/IP */ int m_port; /* Desired port */ btimer_t *m_tid; /* Timer id */ boffset_t m_data_end; /* Offset of last valid data written */ int32_t m_FileIndex; /* Last valid attr spool FI */ volatile bool m_timed_out:1; /* Timed out in read/write */ volatile bool m_terminated:1; /* Set when BNET_TERMINATE arrives */ bool m_cloned:1; /* Set if cloned BSOCK */ bool m_spool:1; /* Set for spooling */ bool m_use_locking:1; /* Set to use locking */ bool m_use_bursting:1; /* Set to use bandwidth bursting */ bool m_use_keepalive:1; /* Set to use keepalive on the socket */ int64_t m_bwlimit; /* Set to limit bandwidth */ int64_t m_nb_bytes; /* Bytes sent/recv since the last tick */ btime_t m_last_tick; /* Last tick used by bwlimit */ virtual void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr) = 0; virtual bool open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal) = 0; public: BSOCK(); virtual ~BSOCK(); /* Methods -- in bsock.c */ void free_bsock(); void free_tls(); virtual BSOCK *clone() = 0; virtual bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose) = 0; virtual int32_t recv() = 0; virtual bool send() = 0; virtual int32_t read_nbytes(char *ptr, int32_t nbytes) = 0; virtual int32_t write_nbytes(char *ptr, int32_t nbytes) = 0; virtual void close() = 0; /* close connection and destroy packet */ virtual void destroy() = 0; /* destroy socket packet */ virtual int get_peer(char *buf, socklen_t buflen) = 0; virtual bool set_buffer_size(uint32_t size, int rw) = 0; virtual int set_nonblocking() = 0; virtual int set_blocking() = 0; virtual void restore_blocking(int flags) = 0; virtual int wait_data(int sec, int usec = 0) = 0; virtual int wait_data_intr(int sec, int usec = 0) = 0; bool fsend(const char*, ...); void set_killable(bool killable); bool signal(int signal); const char *bstrerror(); /* last error on socket */ bool despool(void update_attr_spool_size(ssize_t size), ssize_t tsize); bool authenticate_with_director(const char *name, const char *password, TLS_CONTEXT *tls_ctx, char *response, int response_len); bool set_locking(); /* in bsock.c */ void clear_locking(); /* in bsock.c */ void set_source_address(dlist *src_addr_list); void control_bwlimit(int bytes); /* in bsock.c */ /* Inline functions */ void set_jcr(JCR *jcr) { m_jcr = jcr; }; void set_who(char *who) { m_who = who; }; void set_host(char *host) { m_host = host; }; void set_port(int port) { m_port = port; }; char *who() { return m_who; }; char *host() { return m_host; }; int port() { return m_port; }; JCR *jcr() { return m_jcr; }; JCR *get_jcr() { return m_jcr; }; bool is_spooling() { return m_spool; }; bool is_terminated() { return m_terminated; }; bool is_timed_out() { return m_timed_out; }; bool is_stop() { return errors || is_terminated(); } bool is_error() { errno = b_errno; return errors; } void set_data_end(int32_t FileIndex) { if (m_spool != -1 && FileIndex > m_FileIndex) { m_FileIndex = FileIndex - 1; m_data_end = lseek(m_spool_fd, 0, SEEK_CUR); } }; boffset_t get_data_end() { return m_data_end; }; int32_t get_FileIndex() { return m_FileIndex; }; void set_bwlimit(int64_t maxspeed) { m_bwlimit = maxspeed; }; bool use_bwlimit() { return m_bwlimit > 0;}; void set_bwlimit_bursting() { m_use_bursting = true; }; void clear_bwlimit_bursting() { m_use_bursting = false; }; void set_keepalive() { m_use_keepalive = true; }; void clear_keepalive() { m_use_keepalive = false; }; void set_spooling() { m_spool = true; }; void clear_spooling() { m_spool = false; }; void set_timed_out() { m_timed_out = true; }; void clear_timed_out() { m_timed_out = false; }; void set_terminated() { m_terminated = true; }; void start_timer(int sec) { m_tid = start_bsock_timer(this, sec); }; void stop_timer() { stop_bsock_timer(m_tid); }; }; /* * Signal definitions for use in bnet_sig() * Note! These must be negative. There are signals that are generated * by the bsock software not by the OS ... */ enum { BNET_EOD = -1, /* End of data stream, new data may follow */ BNET_EOD_POLL = -2, /* End of data and poll all in one */ BNET_STATUS = -3, /* Send full status */ BNET_TERMINATE = -4, /* Conversation terminated, doing close() */ BNET_POLL = -5, /* Poll request, I'm hanging on a read */ BNET_HEARTBEAT = -6, /* Heartbeat Response requested */ BNET_HB_RESPONSE = -7, /* Only response permited to HB */ BNET_xxxxxxPROMPT = -8, /* No longer used -- Prompt for subcommand */ BNET_BTIME = -9, /* Send UTC btime */ BNET_BREAK = -10, /* Stop current command -- ctl-c */ BNET_START_SELECT = -11, /* Start of a selection list */ BNET_END_SELECT = -12, /* End of a select list */ BNET_INVALID_CMD = -13, /* Invalid command sent */ BNET_CMD_FAILED = -14, /* Command failed */ BNET_CMD_OK = -15, /* Command succeeded */ BNET_CMD_BEGIN = -16, /* Start command execution */ BNET_MSGS_PENDING = -17, /* Messages pending */ BNET_MAIN_PROMPT = -18, /* Server ready and waiting */ BNET_SELECT_INPUT = -19, /* Return selection input */ BNET_WARNING_MSG = -20, /* Warning message */ BNET_ERROR_MSG = -21, /* Error message -- command failed */ BNET_INFO_MSG = -22, /* Info message -- status line */ BNET_RUN_CMD = -23, /* Run command follows */ BNET_YESNO = -24, /* Request yes no response */ BNET_START_RTREE = -25, /* Start restore tree mode */ BNET_END_RTREE = -26, /* End restore tree mode */ BNET_SUB_PROMPT = -27, /* Indicate we are at a subprompt */ BNET_TEXT_INPUT = -28 /* Get text input from user */ }; #define BNET_SETBUF_READ 1 /* Arg for bnet_set_buffer_size */ #define BNET_SETBUF_WRITE 2 /* Arg for bnet_set_buffer_size */ /* * Return status from bnet_recv() * Note, the HARDEOF and ERROR refer to comm status/problems * rather than the BNET_xxx above, which are software signals. */ enum { BNET_SIGNAL = -1, BNET_HARDEOF = -2, BNET_ERROR = -3 }; /* * TLS enabling values. Value is important for comparison, ie: * if (tls_remote_need < BNET_TLS_REQUIRED) { ... } */ enum { BNET_TLS_NONE = 0, /* cannot do TLS */ BNET_TLS_OK = 1, /* can do, but not required on my end */ BNET_TLS_REQUIRED = 2 /* TLS is required */ }; #endif /* BRS_BSOCK_H */ bareos-Release-14.2.6/src/lib/bsock_sctp.c000066400000000000000000000114431263011562700202760ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * SCTP Sockets abstraction. * * Marco van Wieringen, September 2013. */ #include "bareos.h" #include "jcr.h" #include "bsock_sctp.h" BSOCK_SCTP::BSOCK_SCTP() { } BSOCK_SCTP::~BSOCK_SCTP() { destroy(); } BSOCK *BSOCK_SCTP::clone() { BSOCK_SCTP *clone; POOLMEM *o_msg, *o_errmsg; clone = New(BSOCK_SCTP); /* * Copy the data from the original BSOCK but preserve the msg and errmsg buffers. */ o_msg = clone->msg; o_errmsg = clone->errmsg; memcpy((void *)clone, (void *)this, sizeof(BSOCK_SCTP)); clone->msg = o_msg; clone->errmsg = o_errmsg; if (m_who) { clone->set_who(bstrdup(m_who)); } if (m_host) { clone->set_who(bstrdup(m_host)); } if (src_addr) { clone->src_addr = New(IPADDR(*(src_addr))); } m_cloned = true; return (BSOCK *)clone; } /* * Try to connect to host for max_retry_time at retry_time intervals. * Note, you must have called the constructor prior to calling * this routine. */ bool BSOCK_SCTP::connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose) { return false; } /* * Finish initialization of the pocket structure. */ void BSOCK_SCTP::fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr) { } /* * Open a SCTP connection to the server * Returns NULL * Returns BSOCK * pointer on success */ bool BSOCK_SCTP::open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal) { return false; } /* * Send a message over the network. The send consists of * two network packets. The first is sends a 32 bit integer containing * the length of the data packet which follows. * * Returns: false on failure * true on success */ bool BSOCK_SCTP::send() { return false; } /* * Receive a message from the other end. Each message consists of * two packets. The first is a header that contains the size * of the data that follows in the second packet. * Returns number of bytes read (may return zero) * Returns -1 on signal (BNET_SIGNAL) * Returns -2 on hard end of file (BNET_HARDEOF) * Returns -3 on error (BNET_ERROR) * * Unfortunately, it is a bit complicated because we have these * four return types: * 1. Normal data * 2. Signal including end of data stream * 3. Hard end of file * 4. Error * Using is_bnet_stop() and is_bnet_error() you can figure this all out. */ int32_t BSOCK_SCTP::recv() { return -1; } int BSOCK_SCTP::get_peer(char *buf, socklen_t buflen) { return -1; } /* * Set the network buffer size, suggested size is in size. * Actual size obtained is returned in bs->msglen * * Returns: false on failure * true on success */ bool BSOCK_SCTP::set_buffer_size(uint32_t size, int rw) { return false; } /* * Set socket non-blocking * Returns previous socket flag */ int BSOCK_SCTP::set_nonblocking() { return -1; } /* * Set socket blocking * Returns previous socket flags */ int BSOCK_SCTP::set_blocking() { return -1; } /* * Restores socket flags */ void BSOCK_SCTP::restore_blocking (int flags) { } /* * Wait for a specified time for data to appear on * the BSOCK connection. * * Returns: 1 if data available * 0 if timeout * -1 if error */ int BSOCK_SCTP::wait_data(int sec, int usec) { return -1; } /* * As above, but returns on interrupt */ int BSOCK_SCTP::wait_data_intr(int sec, int usec) { return -1; } void BSOCK_SCTP::close() { } void BSOCK_SCTP::destroy() { } /* * Read a nbytes from the network. * It is possible that the total bytes require in several * read requests */ int32_t BSOCK_SCTP::read_nbytes(char *ptr, int32_t nbytes) { return -1; } /* * Write nbytes to the network. * It may require several writes. */ int32_t BSOCK_SCTP::write_nbytes(char *ptr, int32_t nbytes) { return -1; } bareos-Release-14.2.6/src/lib/bsock_sctp.h000066400000000000000000000037721263011562700203110ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef BRS_BSOCK_SCTP_H #define BRS_BSOCK_SCTP_H class BSOCK_SCTP : public BSOCK { private: /* methods -- in bsock_sctp.c */ void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr); bool open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal); public: BSOCK_SCTP(); ~BSOCK_SCTP(); /* methods -- in bsock_sctp.c */ BSOCK *clone(); bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose); int32_t recv(); bool send(); bool fsend(const char*, ...); int32_t read_nbytes(char *ptr, int32_t nbytes); int32_t write_nbytes(char *ptr, int32_t nbytes); bool signal(int signal); void close(); void destroy(); int get_peer(char *buf, socklen_t buflen); bool set_buffer_size(uint32_t size, int rw); int set_nonblocking(); int set_blocking(); void restore_blocking(int flags); int wait_data(int sec, int usec = 0); int wait_data_intr(int sec, int usec = 0); }; #endif /* BRS_BSOCK_SCTP_H */ bareos-Release-14.2.6/src/lib/bsock_tcp.c000066400000000000000000000632641263011562700201230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * TCP Sockets abstraction. * * Kern Sibbald * * Extracted from other source files by Marco van Wieringen, September 2013. */ #include "bareos.h" #include "jcr.h" #include #include #ifndef ENODATA /* not defined on BSD systems */ #define ENODATA EPIPE #endif #ifndef SOL_TCP #define SOL_TCP IPPROTO_TCP #endif #ifdef HAVE_WIN32 #define socketRead(fd, buf, len) ::recv(fd, buf, len, 0) #define socketWrite(fd, buf, len) ::send(fd, buf, len, 0) #define socketClose(fd) ::closesocket(fd) #else #define socketRead(fd, buf, len) ::read(fd, buf, len) #define socketWrite(fd, buf, len) ::write(fd, buf, len) #define socketClose(fd) ::close(fd) #endif BSOCK_TCP::BSOCK_TCP() { } BSOCK_TCP::~BSOCK_TCP() { destroy(); } BSOCK *BSOCK_TCP::clone() { BSOCK_TCP *clone; POOLMEM *o_msg, *o_errmsg; clone = New(BSOCK_TCP); /* * Copy the data from the original BSOCK but preserve the msg and errmsg buffers. */ o_msg = clone->msg; o_errmsg = clone->errmsg; memcpy((void *)clone, (void *)this, sizeof(BSOCK_TCP)); clone->msg = o_msg; clone->errmsg = o_errmsg; if (m_who) { clone->set_who(bstrdup(m_who)); } if (m_host) { clone->set_host(bstrdup(m_host)); } if (src_addr) { clone->src_addr = New(IPADDR(*(src_addr))); } clone->m_cloned = true; return (BSOCK *)clone; } /* * Try to connect to host for max_retry_time at retry_time intervals. * Note, you must have called the constructor prior to calling * this routine. */ bool BSOCK_TCP::connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose) { bool ok = false; int i; int fatal = 0; time_t begin_time = time(NULL); time_t now; btimer_t *tid = NULL; /* * Try to trap out of OS call when time expires */ if (max_retry_time) { tid = start_thread_timer(jcr, pthread_self(), (uint32_t)max_retry_time); } for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal); i -= retry_interval) { berrno be; if (fatal || (jcr && job_canceled(jcr))) { goto bail_out; } Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n", name, host, port, be.bstrerror()); if (i < 0) { i = 60 * 5; /* complain again in 5 minutes */ if (verbose) Qmsg4(jcr, M_WARNING, 0, _( "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n"), name, host, port, be.bstrerror()); } bmicrosleep(retry_interval, 0); now = time(NULL); if (begin_time + max_retry_time <= now) { Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"), name, host, port, be.bstrerror()); goto bail_out; } } ok = true; bail_out: if (tid) { stop_thread_timer(tid); } return ok; } /* * Finish initialization of the pocket structure. */ void BSOCK_TCP::fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr) { Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port); set_who(bstrdup(who)); set_host(bstrdup(host)); set_port(port); memcpy(&client_addr, lclient_addr, sizeof(client_addr)); set_jcr(jcr); } /* * Open a TCP connection to the server * * Returns NULL * Returns BSOCK * pointer on success */ bool BSOCK_TCP::open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal) { int sockfd = -1; dlist *addr_list; IPADDR *ipaddr, *next, *to_free; bool connected = false; int value; const char *errstr; int save_errno = 0; /* * Fill in the structure serv_addr with the address of * the server that we want to connect with. */ if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) { /* * Note errstr is not malloc'ed */ Qmsg2(jcr, M_ERROR, 0, _("bnet_host2ipaddrs() for host \"%s\" failed: ERR=%s\n"), host, errstr); Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n", host, errstr); *fatal = 1; return false; } /* * Remove any duplicate addresses. */ for (ipaddr = (IPADDR *)addr_list->first(); ipaddr; ipaddr = (IPADDR *)addr_list->next(ipaddr)) { next = (IPADDR *)addr_list->next(ipaddr); while (next) { /* * See if the addresses match. */ if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() && memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(), ipaddr->get_sockaddr_len()) == 0) { to_free = next; next = (IPADDR *)addr_list->next(next); addr_list->remove(to_free); delete to_free; } else { next = (IPADDR *)addr_list->next(next); } } } if (m_use_keepalive) { value = 1; } else { value = 0; } foreach_dlist(ipaddr, addr_list) { ipaddr->set_port_net(htons(port)); char allbuf[256 * 10]; char curbuf[256]; Dmsg2(100, "Current %s All %s\n", ipaddr->build_address_str(curbuf, sizeof(curbuf)), build_addresses_str(addr_list, allbuf, sizeof(allbuf))); /* Open a TCP socket */ if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) { berrno be; save_errno = errno; switch (errno) { #ifdef EPFNOSUPPORT case EPFNOSUPPORT: /* * The name lookup of the host returned an address in a protocol family * we don't support. Suppress the error and try the next address. */ break; #endif #ifdef EAFNOSUPPORT case EAFNOSUPPORT: /* * The name lookup of the host returned an address in a address family * we don't support. Suppress the error and try the next address. */ break; #endif default: *fatal = 1; Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"), ipaddr->get_family(), ipaddr->get_port_host_order(), be.bstrerror()); break; } continue; } /* * Bind to the source address if it is set */ if (src_addr) { if (bind(sockfd, src_addr->get_sockaddr(), src_addr->get_sockaddr_len()) < 0) { berrno be; save_errno = errno; *fatal = 1; Pmsg2(000, _("Source address bind error. proto=%d. ERR=%s\n"), src_addr->get_family(), be.bstrerror() ); if (sockfd >= 0) { socketClose(sockfd); sockfd = -1; } continue; } } /* * Keep socket from timing out from inactivity */ if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value, sizeof(value)) < 0) { berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), be.bstrerror()); } #if defined(TCP_KEEPIDLE) if (heart_beat) { int opt = heart_beat; if (setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (sockopt_val_t)&opt, sizeof(opt)) < 0) { berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set TCP_KEEPIDLE on socket: %s\n"), be.bstrerror()); } } #endif /* * Connect to server */ if (::connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) { save_errno = errno; if (sockfd >= 0) { socketClose(sockfd); sockfd = -1; } continue; } *fatal = 0; connected = true; break; } if (!connected) { free_addresses(addr_list); errno = save_errno | b_errno_win32; if (sockfd >= 0) { socketClose(sockfd); sockfd = -1; } return false; } /* * Keep socket from timing out from inactivity * Do this a second time out of paranoia */ if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value, sizeof(value)) < 0) { berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), be.bstrerror()); } fin_init(jcr, sockfd, name, host, port, ipaddr->get_sockaddr()); free_addresses(addr_list); m_fd = sockfd; return true; } /* * Send a message over the network. The send consists of * two network packets. The first is sends a 32 bit integer containing * the length of the data packet which follows. * * Returns: false on failure * true on success */ bool BSOCK_TCP::send() { int32_t rc; int32_t pktsiz; int32_t *hdr; bool ok = true; if (errors) { if (!m_suppress_error_msgs) { Qmsg4(m_jcr, M_ERROR, 0, _("Socket has errors=%d on call to %s:%s:%d\n"), errors, m_who, m_host, m_port); } return false; } if (is_terminated()) { if (!m_suppress_error_msgs) { Qmsg4(m_jcr, M_ERROR, 0, _("Socket is terminated=%d on call to %s:%s:%d\n"), is_terminated(), m_who, m_host, m_port); } return false; } if (msglen > 4000000) { if (!m_suppress_error_msgs) { Qmsg4(m_jcr, M_ERROR, 0, _("Socket has insane msglen=%d on call to %s:%s:%d\n"), msglen, m_who, m_host, m_port); } return false; } if (m_use_locking) { P(m_mutex); } /* * Compute total packet length */ if (msglen <= 0) { pktsiz = sizeof(pktsiz); /* signal, no data */ } else { pktsiz = msglen + sizeof(pktsiz); /* data */ } /* * Store packet length at head of message -- note, we have reserved an int32_t just before msg, * So we can store there */ hdr = (int32_t *)(msg - (int)sizeof(pktsiz)); *hdr = htonl(msglen); /* store signal/length */ out_msg_no++; /* increment message number */ /* * Send data packet */ timer_start = watchdog_time; /* start timer */ clear_timed_out(); /* * Full I/O done in one write */ rc = write_nbytes((char *)hdr, pktsiz); timer_start = 0; /* clear timer */ if (rc != pktsiz) { errors++; if (errno == 0) { b_errno = EIO; } else { b_errno = errno; } if (rc < 0) { if (!m_suppress_error_msgs) { Qmsg5(m_jcr, M_ERROR, 0, _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), msglen, m_who, m_host, m_port, this->bstrerror()); } } else { Qmsg5(m_jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), msglen, m_who, m_host, m_port, rc); } ok = false; } if (m_use_locking) { V(m_mutex); } return ok; } /* * Receive a message from the other end. Each message consists of * two packets. The first is a header that contains the size * of the data that follows in the second packet. * Returns number of bytes read (may return zero) * Returns -1 on signal (BNET_SIGNAL) * Returns -2 on hard end of file (BNET_HARDEOF) * Returns -3 on error (BNET_ERROR) * * Unfortunately, it is a bit complicated because we have these * four return types: * 1. Normal data * 2. Signal including end of data stream * 3. Hard end of file * 4. Error * Using is_bnet_stop() and is_bnet_error() you can figure this all out. */ int32_t BSOCK_TCP::recv() { int32_t nbytes; int32_t pktsiz; msg[0] = 0; msglen = 0; if (errors || is_terminated()) { return BNET_HARDEOF; } if (m_use_locking) { P(m_mutex); } read_seqno++; /* bump sequence number */ timer_start = watchdog_time; /* set start wait time */ clear_timed_out(); /* * Get data size -- in int32_t */ if ((nbytes = read_nbytes((char *)&pktsiz, sizeof(int32_t))) <= 0) { timer_start = 0; /* clear timer */ /* * Probably pipe broken because client died */ if (errno == 0) { b_errno = ENODATA; } else { b_errno = errno; } errors++; nbytes = BNET_HARDEOF; /* assume hard EOF received */ goto get_out; } timer_start = 0; /* clear timer */ if (nbytes != sizeof(int32_t)) { errors++; b_errno = EIO; Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), sizeof(int32_t), nbytes, m_who, m_host, m_port); nbytes = BNET_ERROR; goto get_out; } pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */ if (pktsiz == 0) { /* No data transferred */ timer_start = 0; /* clear timer */ in_msg_no++; msglen = 0; nbytes = 0; /* zero bytes read */ goto get_out; } /* * If signal or packet size too big */ if (pktsiz < 0 || pktsiz > 1000000) { if (pktsiz > 0) { /* if packet too big */ Qmsg3(m_jcr, M_FATAL, 0, _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"), m_who, m_host, m_port); pktsiz = BNET_TERMINATE; /* hang up */ } if (pktsiz == BNET_TERMINATE) { set_terminated(); } timer_start = 0; /* clear timer */ b_errno = ENODATA; msglen = pktsiz; /* signal code */ nbytes = BNET_SIGNAL; /* signal */ goto get_out; } /* * Make sure the buffer is big enough + one byte for EOS */ if (pktsiz >= (int32_t) sizeof_pool_memory(msg)) { msg = realloc_pool_memory(msg, pktsiz + 100); } timer_start = watchdog_time; /* set start wait time */ clear_timed_out(); /* * Now read the actual data */ if ((nbytes = read_nbytes(msg, pktsiz)) <= 0) { timer_start = 0; /* clear timer */ if (errno == 0) { b_errno = ENODATA; } else { b_errno = errno; } errors++; Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), m_who, m_host, m_port, this->bstrerror()); nbytes = BNET_ERROR; goto get_out; } timer_start = 0; /* clear timer */ in_msg_no++; msglen = nbytes; if (nbytes != pktsiz) { b_errno = EIO; errors++; Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), pktsiz, nbytes, m_who, m_host, m_port); nbytes = BNET_ERROR; goto get_out; } /* * Always add a zero by to properly terminate any string that was send to us. * Note, we ensured above that the buffer is at least one byte longer than * the message length. */ msg[nbytes] = 0; /* terminate in case it is a string */ /* * The following uses *lots* of resources so turn it on only for serious debugging. */ Dsm_check(300); get_out: if (m_use_locking) { V(m_mutex); } return nbytes; /* return actual length of message */ } int BSOCK_TCP::get_peer(char *buf, socklen_t buflen) { #if !defined(HAVE_WIN32) if (peer_addr.sin_family == 0) { socklen_t salen = sizeof(peer_addr); int rval = (getpeername)(m_fd, (struct sockaddr *)&peer_addr, &salen); if (rval < 0) return rval; } if (!inet_ntop(peer_addr.sin_family, &peer_addr.sin_addr, buf, buflen)) return -1; return 0; #else return -1; #endif } /* * Set the network buffer size, suggested size is in size. * Actual size obtained is returned in bs->msglen * * Returns: false on failure * true on success */ bool BSOCK_TCP::set_buffer_size(uint32_t size, int rw) { uint32_t dbuf_size, start_size; #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT) int opt; opt = IPTOS_THROUGHPUT; setsockopt(m_fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt)); #endif if (size != 0) { dbuf_size = size; } else { dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE; } start_size = dbuf_size; if ((msg = realloc_pool_memory(msg, dbuf_size + 100)) == NULL) { Qmsg0(get_jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n")); return false; } /* * If user has not set the size, use the OS default -- i.e. do not * try to set it. This allows sys admins to set the size they * want in the OS, and BAREOS will comply. See bug #1493 */ if (size == 0) { msglen = dbuf_size; return true; } if (rw & BNET_SETBUF_READ) { while ((dbuf_size > TAPE_BSIZE) && (setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { berrno be; Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror()); dbuf_size -= TAPE_BSIZE; } Dmsg1(200, "set network buffer size=%d\n", dbuf_size); if (dbuf_size != start_size) { Qmsg1(get_jcr(), M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size); } } if (size != 0) { dbuf_size = size; } else { dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE; } start_size = dbuf_size; if (rw & BNET_SETBUF_WRITE) { while ((dbuf_size > TAPE_BSIZE) && (setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { berrno be; Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror()); dbuf_size -= TAPE_BSIZE; } Dmsg1(900, "set network buffer size=%d\n", dbuf_size); if (dbuf_size != start_size) { Qmsg1(get_jcr(), M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size); } } msglen = dbuf_size; return true; } /* * Set socket non-blocking * * Returns previous socket flag */ int BSOCK_TCP::set_nonblocking() { #ifndef HAVE_WIN32 int oflags; /* * Get current flags */ if ((oflags = fcntl(m_fd, F_GETFL, 0)) < 0) { berrno be; Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.bstrerror()); } /* * Set O_NONBLOCK flag */ if ((fcntl(m_fd, F_SETFL, oflags|O_NONBLOCK)) < 0) { berrno be; Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.bstrerror()); } m_blocking = 0; return oflags; #else int flags; u_long ioctlArg = 1; flags = m_blocking; ioctlsocket(m_fd, FIONBIO, &ioctlArg); m_blocking = 0; return flags; #endif } /* * Set socket blocking * * Returns previous socket flags */ int BSOCK_TCP::set_blocking() { #ifndef HAVE_WIN32 int oflags; /* * Get current flags */ if ((oflags = fcntl(m_fd, F_GETFL, 0)) < 0) { berrno be; Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.bstrerror()); } /* * Set O_NONBLOCK flag */ if ((fcntl(m_fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) { berrno be; Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.bstrerror()); } m_blocking = 1; return oflags; #else int flags; u_long ioctlArg = 0; flags = m_blocking; ioctlsocket(m_fd, FIONBIO, &ioctlArg); m_blocking = 1; return flags; #endif } /* * Restores socket flags */ void BSOCK_TCP::restore_blocking (int flags) { #ifndef HAVE_WIN32 if ((fcntl(m_fd, F_SETFL, flags)) < 0) { berrno be; Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.bstrerror()); } m_blocking = (flags & O_NONBLOCK) ? true : false; #else u_long ioctlArg = flags; ioctlsocket(m_fd, FIONBIO, &ioctlArg); m_blocking = 1; #endif } /* * Wait for a specified time for data to appear on * the BSOCK connection. * * Returns: 1 if data available * 0 if timeout * -1 if error */ int BSOCK_TCP::wait_data(int sec, int usec) { int msec; msec = (sec * 1000) + (usec / 1000); switch (wait_for_readable_fd(m_fd, msec, true)) { case 0: b_errno = 0; return 0; case -1: b_errno = errno; return -1; /* error return */ default: b_errno = 0; return 1; } } /* * As above, but returns on interrupt */ int BSOCK_TCP::wait_data_intr(int sec, int usec) { int msec; msec = (sec * 1000) + (usec / 1000); switch (wait_for_readable_fd(m_fd, msec, false)) { case 0: b_errno = 0; return 0; case -1: b_errno = errno; return -1; /* error return */ default: b_errno = 0; return 1; } } #ifndef SHUT_RDWR #define SHUT_RDWR 2 #endif void BSOCK_TCP::close() { if (!m_cloned) { clear_locking(); } if (!m_cloned) { /* * Shutdown tls cleanly. */ if (tls) { tls_bsock_shutdown(this); free_tls_connection(tls); tls = NULL; } if (is_timed_out()) { shutdown(m_fd, SHUT_RDWR); /* discard any pending I/O */ } socketClose(m_fd); /* normal close */ m_fd = -1; } return; } void BSOCK_TCP::destroy() { if (msg) { free_pool_memory(msg); msg = NULL; } else { ASSERT(1 == 0); /* double close */ } if (errmsg) { free_pool_memory(errmsg); errmsg = NULL; } if (m_who) { free(m_who); m_who = NULL; } if (m_host) { free(m_host); m_host = NULL; } if (src_addr) { free(src_addr); src_addr = NULL; } } /* * Read a nbytes from the network. * It is possible that the total bytes require in several * read requests */ int32_t BSOCK_TCP::read_nbytes(char *ptr, int32_t nbytes) { int32_t nleft, nread; #ifdef HAVE_TLS if (tls) { /* * TLS enabled */ return (tls_bsock_readn(this, ptr, nbytes)); } #endif /* HAVE_TLS */ nleft = nbytes; while (nleft > 0) { errno = 0; nread = socketRead(m_fd, ptr, nleft); if (is_timed_out() || is_terminated()) { return -1; } #ifdef HAVE_WIN32 /* * For Windows, we must simulate Unix errno on a socket error in order to handle errors correctly. */ if (nread == SOCKET_ERROR) { DWORD err = WSAGetLastError(); nread = -1; if (err == WSAEINTR) { errno = EINTR; } else if (err == WSAEWOULDBLOCK) { errno = EAGAIN; } else { errno = EIO; /* some other error */ } } #endif if (nread == -1) { if (errno == EINTR) { continue; } if (errno == EAGAIN) { bmicrosleep(0, 20000); /* try again in 20ms */ continue; } } if (nread <= 0) { return -1; /* error, or EOF */ } nleft -= nread; ptr += nread; if (use_bwlimit()) { control_bwlimit(nread); } } return nbytes - nleft; /* return >= 0 */ } /* * Write nbytes to the network. * It may require several writes. */ int32_t BSOCK_TCP::write_nbytes(char *ptr, int32_t nbytes) { int32_t nleft, nwritten; if (is_spooling()) { nwritten = write(m_spool_fd, ptr, nbytes); if (nwritten != nbytes) { berrno be; b_errno = errno; Qmsg1(jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"), be.bstrerror()); Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes); errno = b_errno; return -1; } return nbytes; } #ifdef HAVE_TLS if (tls) { /* TLS enabled */ return (tls_bsock_writen(this, ptr, nbytes)); } #endif /* HAVE_TLS */ nleft = nbytes; while (nleft > 0) { do { errno = 0; nwritten = socketWrite(m_fd, ptr, nleft); if (is_timed_out() || is_terminated()) { return -1; } #ifdef HAVE_WIN32 /* * For Windows, we must simulate Unix errno on a socket * error in order to handle errors correctly. */ if (nwritten == SOCKET_ERROR) { DWORD err = WSAGetLastError(); nwritten = -1; if (err == WSAEINTR) { errno = EINTR; } else if (err == WSAEWOULDBLOCK) { errno = EAGAIN; } else { errno = EIO; /* some other error */ } } #endif } while (nwritten == -1 && errno == EINTR); /* * If connection is non-blocking, we will get EAGAIN, so * use select()/poll() to keep from consuming all * the CPU and try again. */ if (nwritten == -1 && errno == EAGAIN) { wait_for_writable_fd(m_fd, 1, false); continue; } if (nwritten <= 0) { return -1; /* error */ } nleft -= nwritten; ptr += nwritten; if (use_bwlimit()) { control_bwlimit(nwritten); } } return nbytes - nleft; } bareos-Release-14.2.6/src/lib/bsock_tcp.h000066400000000000000000000037621263011562700201250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef BRS_BSOCK_TCP_H #define BRS_BSOCK_TCP_H class BSOCK_TCP : public BSOCK { private: /* methods -- in bsock_tcp.c */ void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr); bool open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal); public: BSOCK_TCP(); ~BSOCK_TCP(); /* methods -- in bsock_tcp.c */ BSOCK *clone(); bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose); int32_t recv(); bool send(); bool fsend(const char*, ...); int32_t read_nbytes(char *ptr, int32_t nbytes); int32_t write_nbytes(char *ptr, int32_t nbytes); bool signal(int signal); void close(); void destroy(); int get_peer(char *buf, socklen_t buflen); bool set_buffer_size(uint32_t size, int rw); int set_nonblocking(); int set_blocking(); void restore_blocking(int flags); int wait_data(int sec, int usec = 0); int wait_data_intr(int sec, int usec = 0); }; #endif /* BRS_BSOCK_TCP_H */ bareos-Release-14.2.6/src/lib/bsock_udt.c000066400000000000000000000114101263011562700201130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UDT Sockets abstraction. * * Marco van Wieringen, September 2013. */ #include "bareos.h" #include "jcr.h" #include "bsock_udt.h" BSOCK_UDT::BSOCK_UDT() { } BSOCK_UDT::~BSOCK_UDT() { destroy(); } BSOCK *BSOCK_UDT::clone() { BSOCK_UDT *clone; POOLMEM *o_msg, *o_errmsg; clone = New(BSOCK_UDT); /* * Copy the data from the original BSOCK but preserve the msg and errmsg buffers. */ o_msg = clone->msg; o_errmsg = clone->errmsg; memcpy((void *)clone, (void *)this, sizeof(BSOCK_UDT)); clone->msg = o_msg; clone->errmsg = o_errmsg; if (m_who) { clone->set_who(bstrdup(m_who)); } if (m_host) { clone->set_who(bstrdup(m_host)); } if (src_addr) { clone->src_addr = New(IPADDR(*(src_addr))); } m_cloned = true; return (BSOCK *)clone; } /* * Try to connect to host for max_retry_time at retry_time intervals. * Note, you must have called the constructor prior to calling * this routine. */ bool BSOCK_UDT::connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose) { return false; } /* * Finish initialization of the pocket structure. */ void BSOCK_UDT::fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr) { } /* * Open a UDT connection to the server * Returns NULL * Returns BSOCK * pointer on success */ bool BSOCK_UDT::open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal) { return false; } /* * Send a message over the network. The send consists of * two network packets. The first is sends a 32 bit integer containing * the length of the data packet which follows. * * Returns: false on failure * true on success */ bool BSOCK_UDT::send() { return false; } /* * Receive a message from the other end. Each message consists of * two packets. The first is a header that contains the size * of the data that follows in the second packet. * Returns number of bytes read (may return zero) * Returns -1 on signal (BNET_SIGNAL) * Returns -2 on hard end of file (BNET_HARDEOF) * Returns -3 on error (BNET_ERROR) * * Unfortunately, it is a bit complicated because we have these * four return types: * 1. Normal data * 2. Signal including end of data stream * 3. Hard end of file * 4. Error * Using is_bnet_stop() and is_bnet_error() you can figure this all out. */ int32_t BSOCK_UDT::recv() { return -1; } int BSOCK_UDT::get_peer(char *buf, socklen_t buflen) { return -1; } /* * Set the network buffer size, suggested size is in size. * Actual size obtained is returned in bs->msglen * * Returns: false on failure * true on success */ bool BSOCK_UDT::set_buffer_size(uint32_t size, int rw) { return false; } /* * Set socket non-blocking * Returns previous socket flag */ int BSOCK_UDT::set_nonblocking() { return -1; } /* * Set socket blocking * Returns previous socket flags */ int BSOCK_UDT::set_blocking() { return -1; } /* * Restores socket flags */ void BSOCK_UDT::restore_blocking (int flags) { } /* * Wait for a specified time for data to appear on * the BSOCK connection. * * Returns: 1 if data available * 0 if timeout * -1 if error */ int BSOCK_UDT::wait_data(int sec, int usec) { return -1; } /* * As above, but returns on interrupt */ int BSOCK_UDT::wait_data_intr(int sec, int usec) { return -1; } void BSOCK_UDT::close() { } void BSOCK_UDT::destroy() { } /* * Read a nbytes from the network. * It is possible that the total bytes require in several * read requests */ int32_t BSOCK_UDT::read_nbytes(char *ptr, int32_t nbytes) { return -1; } /* * Write nbytes to the network. * It may require several writes. */ int32_t BSOCK_UDT::write_nbytes(char *ptr, int32_t nbytes) { return -1; } bareos-Release-14.2.6/src/lib/bsock_udt.h000066400000000000000000000037621263011562700201330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef BRS_BSOCK_UDT_H #define BRS_BSOCK_UDT_H class BSOCK_UDT : public BSOCK { private: /* methods -- in bsock_udt.c */ void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port, struct sockaddr *lclient_addr); bool open(JCR *jcr, const char *name, char *host, char *service, int port, utime_t heart_beat, int *fatal); public: BSOCK_UDT(); ~BSOCK_UDT(); /* methods -- in bsock_udt.c */ BSOCK *clone(); bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time, utime_t heart_beat, const char *name, char *host, char *service, int port, bool verbose); int32_t recv(); bool send(); bool fsend(const char*, ...); int32_t read_nbytes(char *ptr, int32_t nbytes); int32_t write_nbytes(char *ptr, int32_t nbytes); bool signal(int signal); void close(); void destroy(); int get_peer(char *buf, socklen_t buflen); bool set_buffer_size(uint32_t size, int rw); int set_nonblocking(); int set_blocking(); void restore_blocking(int flags); int wait_data(int sec, int usec = 0); int wait_data_intr(int sec, int usec = 0); }; #endif /* BRS_BSOCK_UDT_H */ bareos-Release-14.2.6/src/lib/bsr.h000066400000000000000000000120211263011562700167300ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BootStrap record definition -- for restoring files. * * Kern Sibbald, June 2002 */ #ifndef __BSR_H #define __BSR_H 1 #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif /* * List of Volume names to be read by Storage daemon. * Formed by Storage daemon from BSR */ struct VOL_LIST { VOL_LIST *next; char VolumeName[MAX_NAME_LENGTH]; char MediaType[MAX_NAME_LENGTH]; char device[MAX_NAME_LENGTH]; /* ***FIXME*** use alist here */ int Slot; uint32_t start_file; }; /* * !!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!! * !!! !!! * !!! All records must have a pointer to !!! * !!! the next item as the first item defined. !!! * !!! !!! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ struct BSR_VOLUME { BSR_VOLUME *next; char VolumeName[MAX_NAME_LENGTH]; char MediaType[MAX_NAME_LENGTH]; char device[MAX_NAME_LENGTH]; /* ***FIXME*** use alist here */ int32_t Slot; /* Slot */ }; struct BSR_CLIENT { BSR_CLIENT *next; char ClientName[MAX_NAME_LENGTH]; }; struct BSR_SESSID { BSR_SESSID *next; uint32_t sessid; uint32_t sessid2; }; struct BSR_SESSTIME { BSR_SESSTIME *next; uint32_t sesstime; bool done; /* local done */ }; struct BSR_VOLFILE { BSR_VOLFILE *next; uint32_t sfile; /* start file */ uint32_t efile; /* end file */ bool done; /* local done */ }; struct BSR_VOLBLOCK { BSR_VOLBLOCK *next; uint32_t sblock; /* start block */ uint32_t eblock; /* end block */ bool done; /* local done */ }; struct BSR_VOLADDR { BSR_VOLADDR *next; uint64_t saddr; /* start address */ uint64_t eaddr; /* end address */ bool done; /* local done */ }; struct BSR_FINDEX { BSR_FINDEX *next; int32_t findex; /* start file index */ int32_t findex2; /* end file index */ bool done; /* local done */ }; struct BSR_JOBID { BSR_JOBID *next; uint32_t JobId; uint32_t JobId2; }; struct BSR_JOBTYPE { BSR_JOBTYPE *next; uint32_t JobType; }; struct BSR_JOBLEVEL { BSR_JOBLEVEL *next; uint32_t JobLevel; }; struct BSR_JOB { BSR_JOB *next; char Job[MAX_NAME_LENGTH]; bool done; /* local done */ }; struct BSR_STREAM { BSR_STREAM *next; int32_t stream; /* stream desired */ }; struct BSR { /* NOTE!!! next must be the first item */ BSR *next; /* pointer to next one */ BSR *prev; /* pointer to previous one */ BSR *root; /* root bsr */ bool reposition; /* set when any bsr is marked done */ bool mount_next_volume; /* set when next volume should be mounted */ bool done; /* set when everything found for this bsr */ bool use_fast_rejection; /* set if fast rejection can be used */ bool use_positioning; /* set if we can position the archive */ bool skip_file; /* skip all records for current file */ BSR_VOLUME *volume; uint32_t count; /* count of files to restore this bsr */ uint32_t found; /* count of restored files this bsr */ BSR_VOLFILE *volfile; BSR_VOLBLOCK *volblock; BSR_VOLADDR *voladdr; BSR_SESSTIME *sesstime; BSR_SESSID *sessid; BSR_JOBID *JobId; BSR_JOB *job; BSR_CLIENT *client; BSR_FINDEX *FileIndex; BSR_JOBTYPE *JobType; BSR_JOBLEVEL *JobLevel; BSR_STREAM *stream; char *fileregex; /* set if restore is filtered on filename */ regex_t *fileregex_re; ATTR *attr; /* scratch space for unpacking */ }; BSR *parse_bsr(JCR *jcr, char *lf); void dump_bsr(BSR *bsr, bool recurse); void free_bsr(BSR *bsr); #endif bareos-Release-14.2.6/src/lib/bsys.c000066400000000000000000000700341263011562700171250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Miscellaneous BAREOS memory and thread safe routines * Generally, these are interfaces to system or standard * library routines. * * BAREOS utility functions are in util.c */ #include "bareos.h" #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t timer = PTHREAD_COND_INITIALIZER; /* * This routine is a somewhat safer unlink in that it * allows you to run a regex on the filename before * excepting it. It also requires the file to be in * the working directory. */ int safer_unlink(const char *pathname, const char *regx) { int rc; regex_t preg1; char prbuf[500]; int rtn; /* Name must start with working directory */ if (strncmp(pathname, working_directory, strlen(working_directory)) != 0) { Pmsg1(000, "Safe_unlink excluded: %s\n", pathname); return EROFS; } /* Compile regex expression */ rc = regcomp(&preg1, regx, REG_EXTENDED); if (rc != 0) { regerror(rc, &preg1, prbuf, sizeof(prbuf)); Pmsg2(000, _("safe_unlink could not compile regex pattern \"%s\" ERR=%s\n"), regx, prbuf); return ENOENT; } /* * Unlink files that match regexes */ if (regexec(&preg1, pathname, 0, NULL, 0) == 0) { Dmsg1(100, "safe_unlink unlinking: %s\n", pathname); rtn = unlink(pathname); } else { Pmsg2(000, "safe_unlink regex failed: regex=%s file=%s\n", regx, pathname); rtn = EROFS; } regfree(&preg1); return rtn; } /* * This routine will sleep (sec, microsec). Note, however, that if a * signal occurs, it will return early. It is up to the caller * to recall this routine if he/she REALLY wants to sleep the * requested time. */ int bmicrosleep(int32_t sec, int32_t usec) { struct timespec timeout; struct timeval tv; struct timezone tz; int status; timeout.tv_sec = sec; timeout.tv_nsec = usec * 1000; #ifdef HAVE_NANOSLEEP status = nanosleep(&timeout, NULL); if (!(status < 0 && errno == ENOSYS)) { return status; } /* * If we reach here it is because nanosleep is not supported by the OS */ #endif /* * Do it the old way */ gettimeofday(&tv, &tz); timeout.tv_nsec += tv.tv_usec * 1000; timeout.tv_sec += tv.tv_sec; while (timeout.tv_nsec >= 1000000000) { timeout.tv_nsec -= 1000000000; timeout.tv_sec++; } Dmsg2(200, "pthread_cond_timedwait sec=%lld usec=%d\n", sec, usec); /* * Note, this unlocks mutex during the sleep */ P(timer_mutex); status = pthread_cond_timedwait(&timer, &timer_mutex, &timeout); V(timer_mutex); return status; } /* * Copy a string inline from one point in the same string * to an other. */ char *bstrinlinecpy(char *dest, const char *src) { int len; /* * Sanity check. We can only inline copy if the src > dest * otherwise the resulting copy will overwrite the end of * the string. */ if (src <= dest) { return NULL; } len = strlen(src); #if HAVE_BCOPY /* * Cannot use strcpy or memcpy as those functions are not * allowed on overlapping data and this is inline replacement * for sure is. So we use bcopy which is allowed on overlapping * data. */ bcopy(src, dest, len + 1); #else /* * Cannot use strcpy or memcpy as those functions are not * allowed on overlapping data and this is inline replacement * for sure is. So we use memmove which is allowed on * overlapping data. */ memmove(dest, src, len + 1); #endif return dest; } /* * Guarantee that the string is properly terminated */ char *bstrncpy(char *dest, const char *src, int maxlen) { strncpy(dest, src, maxlen-1); dest[maxlen-1] = 0; return dest; } /* * Guarantee that the string is properly terminated */ char *bstrncpy(char *dest, POOL_MEM &src, int maxlen) { strncpy(dest, src.c_str(), maxlen-1); dest[maxlen-1] = 0; return dest; } /* * Note: Here the maxlen is the maximum length permitted * stored in dest, while on Unix systems, it is the maximum characters * that may be copied from src. */ char *bstrncat(char *dest, const char *src, int maxlen) { int len = strlen(dest); if (len < maxlen-1) { strncpy(dest+len, src, maxlen-len-1); } dest[maxlen-1] = 0; return dest; } /* * Note: Here the maxlen is the maximum length permitted * stored in dest, while on Unix systems, it is the maximum characters * that may be copied from src. */ char *bstrncat(char *dest, POOL_MEM &src, int maxlen) { int len = strlen(dest); if (len < maxlen-1) { strncpy(dest+len, src.c_str(), maxlen-len-1); } dest[maxlen-1] = 0; return dest; } /* * Allows one or both pointers to be NULL */ bool bstrcmp(const char *s1, const char *s2) { if (s1 == s2) return true; if (s1 == NULL || s2 == NULL) return false; return strcmp(s1, s2) == 0; } bool bstrncmp(const char *s1, const char *s2, int n) { if (s1 == s2) return true; if (s1 == NULL || s2 == NULL) return false; return strncmp(s1, s2, n) == 0; } bool bstrcasecmp(const char *s1, const char *s2) { if (s1 == s2) return true; if (s1 == NULL || s2 == NULL) return false; return strcasecmp(s1, s2) == 0; } bool bstrncasecmp(const char *s1, const char *s2, int n) { if (s1 == s2) return true; if (s1 == NULL || s2 == NULL) return false; return strncasecmp(s1, s2, n) == 0; } /* * Get character length of UTF-8 string * * Valid UTF-8 codes * U-00000000 - U-0000007F: 0xxxxxxx * U-00000080 - U-000007FF: 110xxxxx 10xxxxxx * U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx * U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx * U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ int cstrlen(const char *str) { uint8_t *p = (uint8_t *)str; int len = 0; if (str == NULL) { return 0; } while (*p) { if ((*p & 0xC0) != 0xC0) { p++; len++; continue; } if ((*p & 0xD0) == 0xC0) { p += 2; len++; continue; } if ((*p & 0xF0) == 0xD0) { p += 3; len++; continue; } if ((*p & 0xF8) == 0xF0) { p += 4; len++; continue; } if ((*p & 0xFC) == 0xF8) { p += 5; len++; continue; } if ((*p & 0xFE) == 0xFC) { p += 6; len++; continue; } p++; /* Shouln't get here but must advance */ } return len; } #ifndef bmalloc void *bmalloc(size_t size) { void *buf; #ifdef SMARTALLOC buf = sm_malloc(file, line, size); #else buf = malloc(size); #endif if (buf == NULL) { berrno be; Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror()); } return buf; } #endif void *b_malloc(const char *file, int line, size_t size) { void *buf; #ifdef SMARTALLOC buf = sm_malloc(file, line, size); #else buf = malloc(size); #endif if (buf == NULL) { berrno be; e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror()); } return buf; } void bfree(void *buf) { #ifdef SMARTALLOC sm_free(__FILE__, __LINE__, buf); #else free(buf); #endif } void *brealloc (void *buf, size_t size) { #ifdef SMARTALOC buf = sm_realloc(__FILE__, __LINE__, buf, size); #else buf = realloc(buf, size); #endif if (buf == NULL) { berrno be; Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror()); } return buf; } void *bcalloc(size_t size1, size_t size2) { void *buf; buf = calloc(size1, size2); if (buf == NULL) { berrno be; Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror()); } return buf; } /* Code now in src/lib/bsnprintf.c */ #ifndef USE_BSNPRINTF #define BIG_BUF 5000 /* * Implement snprintf */ int bsnprintf(char *str, int32_t size, const char *fmt, ...) { va_list arg_ptr; int len; va_start(arg_ptr, fmt); len = bvsnprintf(str, size, fmt, arg_ptr); va_end(arg_ptr); return len; } /* * Implement vsnprintf() */ int bvsnprintf(char *str, int32_t size, const char *format, va_list ap) { #ifdef HAVE_VSNPRINTF int len; len = vsnprintf(str, size, format, ap); str[size-1] = 0; return len; #else int len, buflen; char *buf; buflen = size > BIG_BUF ? size : BIG_BUF; buf = get_memory(buflen); len = vsprintf(buf, format, ap); if (len >= buflen) { Emsg0(M_ABORT, 0, _("Buffer overflow.\n")); } memcpy(str, buf, len); str[len] = 0; /* len excludes the null */ free_memory(buf); return len; #endif } #endif /* USE_BSNPRINTF */ #ifndef HAVE_LOCALTIME_R struct tm *localtime_r(const time_t *timep, struct tm *tm) { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct tm *ltm, P(mutex); ltm = localtime(timep); if (ltm) { memcpy(tm, ltm, sizeof(struct tm)); } V(mutex); return ltm ? tm : NULL; } #endif /* HAVE_LOCALTIME_R */ #ifndef HAVE_READDIR_R #ifndef HAVE_WIN32 #include int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct dirent *ndir; int status; P(mutex); errno = 0; ndir = readdir(dirp); status = errno; if (ndir) { memcpy(entry, ndir, sizeof(struct dirent)); strcpy(entry->d_name, ndir->d_name); *result = entry; } else { *result = NULL; } V(mutex); return status; } #endif #endif /* HAVE_READDIR_R */ int b_strerror(int errnum, char *buf, size_t bufsiz) { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int status = 0; const char *msg; P(mutex); msg = strerror(errnum); if (!msg) { msg = _("Bad errno"); status = -1; } bstrncpy(buf, msg, bufsiz); V(mutex); return status; } #ifdef DEBUG_MEMSET /* These routines are not normally turned on */ #undef memset void b_memset(const char *file, int line, void *mem, int val, size_t num) { /* Testing for 2000 byte zero at beginning of Volume block */ if (num > 1900 && num < 3000) { Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line); } memset(mem, val, num); } #endif #if !defined(HAVE_WIN32) static int del_pid_file_ok = FALSE; #endif /* * Create a standard "Unix" pid file. */ void create_pid_file(char *dir, const char *progname, int port) { #if !defined(HAVE_WIN32) int pidfd = -1; int len; int oldpid; char pidbuf[20]; POOLMEM *fname = get_pool_memory(PM_FNAME); struct stat statp; Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port); if (stat(fname, &statp) == 0) { /* File exists, see what we have */ *pidbuf = 0; if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 || read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 || sscanf(pidbuf, "%d", &oldpid) != 1) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, be.bstrerror()); } else { /* * Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and * since they use a deterministic algorithm for assigning PIDs, we can have * pid conflicts with the old PID file after a reboot. * The intent the following code is to check if the oldpid read from the pid * file is the same as the currently executing process's pid, * and if oldpid == getpid(), skip the attempt to * kill(oldpid,0), since the attempt is guaranteed to succeed, * but the success won't actually mean that there is an * another BAREOS process already running. * For more details see bug #797. */ if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) { Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"), progname, oldpid, fname); } } if (pidfd >= 0) { close(pidfd); } /* * He is not alive, so take over file ownership */ unlink(fname); /* remove stale pid file */ } /* * Create new pid file */ if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) { len = sprintf(pidbuf, "%d\n", (int)getpid()); write(pidfd, pidbuf, len); close(pidfd); del_pid_file_ok = TRUE; /* we created it so we can delete it */ } else { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, be.bstrerror()); } free_pool_memory(fname); #endif } /* * Delete the pid file if we created it */ int delete_pid_file(char *dir, const char *progname, int port) { #if !defined(HAVE_WIN32) POOLMEM *fname = get_pool_memory(PM_FNAME); if (!del_pid_file_ok) { free_pool_memory(fname); return 0; } del_pid_file_ok = FALSE; Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port); unlink(fname); free_pool_memory(fname); #endif return 1; } struct s_state_hdr { char id[14]; int32_t version; uint64_t last_jobs_addr; uint64_t reserved[20]; }; static struct s_state_hdr state_hdr = { "Bareos State\n", 4, 0 }; /* * Open and read the state file for the daemon */ void read_state_file(char *dir, const char *progname, int port) { int sfd; ssize_t status; bool ok = false; POOLMEM *fname = get_pool_memory(PM_FNAME); struct s_state_hdr hdr; int hdr_size = sizeof(hdr); Mmsg(&fname, "%s/%s.%d.state", dir, progname, port); /* If file exists, see what we have */ // Dmsg1(10, "O_BINARY=%d\n", O_BINARY); if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) { berrno be; Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n", sfd, sizeof(hdr), be.bstrerror()); goto bail_out; } if ((status = read(sfd, &hdr, hdr_size)) != hdr_size) { berrno be; Dmsg4(010, "Could not read state file. sfd=%d status=%d size=%d: ERR=%s\n", sfd, (int)status, hdr_size, be.bstrerror()); goto bail_out; } if (hdr.version != state_hdr.version) { Dmsg2(010, "Bad hdr version. Wanted %d got %d\n", state_hdr.version, hdr.version); goto bail_out; } hdr.id[13] = 0; if (!bstrcmp(hdr.id, state_hdr.id)) { Dmsg0(000, "State file header id invalid.\n"); goto bail_out; } // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr)); if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) { goto bail_out; } ok = true; bail_out: if (sfd >= 0) { close(sfd); } if (!ok) { unlink(fname); } free_pool_memory(fname); } /* * Write the state file */ static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER; void write_state_file(char *dir, const char *progname, int port) { int sfd; bool ok = false; POOLMEM *fname = get_pool_memory(PM_FNAME); P(state_mutex); /* Only one job at a time can call here */ Mmsg(&fname, "%s/%s.%d.state", dir, progname, port); /* Create new state file */ unlink(fname); if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) { berrno be; Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.bstrerror()); Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.bstrerror()); goto bail_out; } if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) { berrno be; Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror()); goto bail_out; } // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr)); state_hdr.last_jobs_addr = sizeof(state_hdr); state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr); // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]); if (lseek(sfd, 0, SEEK_SET) < 0) { berrno be; Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror()); goto bail_out; } if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) { berrno be; Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror()); goto bail_out; } ok = true; // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr)); bail_out: if (sfd >= 0) { close(sfd); } if (!ok) { unlink(fname); } V(state_mutex); free_pool_memory(fname); } /* BSDI does not have this. This is a *poor* simulation */ #ifndef HAVE_STRTOLL long long int strtoll(const char *ptr, char **endptr, int base) { return (long long int)strtod(ptr, endptr); } #endif /* * BAREOS's implementation of fgets(). The difference is that it handles * being interrupted by a signal (e.g. a SIGCHLD). */ #undef fgetc char *bfgets(char *s, int size, FILE *fd) { char *p = s; int ch; *p = 0; for (int i=0; i < size-1; i++) { do { errno = 0; ch = fgetc(fd); } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN)); if (ch == EOF) { if (i == 0) { return NULL; } else { return s; } } *p++ = ch; *p = 0; if (ch == '\r') { /* Support for Mac/Windows file format */ ch = fgetc(fd); if (ch != '\n') { /* Mac (\r only) */ (void)ungetc(ch, fd); /* Push next character back to fd */ } p[-1] = '\n'; break; } if (ch == '\n') { break; } } return s; } /* * BAREOS's implementation of fgets(). The difference is that it handles * being interrupted by a signal (e.g. a SIGCHLD) and it has a * different calling sequence which implements input lines of * up to a million characters. */ char *bfgets(POOLMEM *&s, FILE *fd) { int ch; int soft_max; int i = 0; s[0] = 0; soft_max = sizeof_pool_memory(s) - 10; for ( ;; ) { do { errno = 0; ch = fgetc(fd); } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN)); if (ch == EOF) { if (i == 0) { return NULL; } else { return s; } } if (i > soft_max) { /* Insanity check */ if (soft_max > 1000000) { return s; } s = check_pool_memory_size(s, soft_max+10000); soft_max = sizeof_pool_memory(s) - 10; } s[i++] = ch; s[i] = 0; if (ch == '\r') { /* Support for Mac/Windows file format */ ch = fgetc(fd); if (ch != '\n') { /* Mac (\r only) */ (void)ungetc(ch, fd); /* Push next character back to fd */ } s[i-1] = '\n'; break; } if (ch == '\n') { break; } } return s; } /* * Make a "unique" filename. It is important that if * called again with the same "what" that the result * will be identical. This allows us to use the file * without saving its name, and re-generate the name * so that it can be deleted. */ void make_unique_filename(POOLMEM **name, int Id, char *what) { Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id); } char *escape_filename(const char *file_path) { if (file_path == NULL || strpbrk(file_path, "\"\\") == NULL) { return NULL; } char *escaped_path = (char *)bmalloc(2 * (strlen(file_path) + 1)); char *cur_char = escaped_path; while (*file_path) { if (*file_path == '\\' || *file_path == '"') { *cur_char++ = '\\'; } *cur_char++ = *file_path++; } *cur_char = '\0'; return escaped_path; } /* * Some Solaris specific support needed for Solaris 10 and lower. */ #if defined(HAVE_SUN_OS) /* * If libc doesn't have addrtosymstr emulate it. * Solaris 11 has addrtosymstr in libc older * Solaris versions don't have this. */ #ifndef HAVE_ADDRTOSYMSTR #include #ifdef _LP64 #define _ELF64 #endif #include static int addrtosymstr(void *pc, char *buffer, int size) { Dl_info info; Sym *sym; if (dladdr1(pc, &info, (void **)&sym, RTLD_DL_SYMENT) == 0) { return (bsnprintf(buffer, size, "[0x%p]", pc)); } if ((info.dli_fname != NULL && info.dli_sname != NULL) && ((uintptr_t)pc - (uintptr_t)info.dli_saddr < sym->st_size)) { return (bsnprintf(buffer, size, "%s'%s+0x%x [0x%p]", info.dli_fname, info.dli_sname, (unsigned long)pc - (unsigned long)info.dli_saddr, pc)); } else { return (bsnprintf(buffer, size, "%s'0x%p [0x%p]", info.dli_fname, (unsigned long)pc - (unsigned long)info.dli_fbase, pc)); } } #endif /* HAVE_ADDRTOSYMSTR */ /* * If libc doesn't have backtrace_symbols emulate it. * Solaris 11 has backtrace_symbols in libc older * Solaris versions don't have this. */ #ifndef HAVE_BACKTRACE_SYMBOLS static char **backtrace_symbols(void *const *array, int size) { int bufferlen, len; char **ret_buffer; char **ret = NULL; char linebuffer[512]; int i; bufferlen = size * sizeof(char *); ret_buffer = (char **)actuallymalloc(bufferlen); if (ret_buffer) { for (i = 0; i < size; i++) { (void) addrtosymstr(array[i], linebuffer, sizeof(linebuffer)); ret_buffer[i] = (char *)actuallymalloc(len = strlen(linebuffer) + 1); strcpy(ret_buffer[i], linebuffer); bufferlen += len; } ret = (char **)actuallymalloc(bufferlen); if (ret) { for (len = i = 0; i < size; i++) { ret[i] = (char *)ret + size * sizeof(char *) + len; (void) strcpy(ret[i], ret_buffer[i]); len += strlen(ret_buffer[i]) + 1; } } } return (ret); } /* * Define that we now know backtrace_symbols() */ #define HAVE_BACKTRACE_SYMBOLS 1 #endif /* HAVE_BACKTRACE_SYMBOLS */ /* * If libc doesn't have backtrace call emulate it using getcontext(3) * Solaris 11 has backtrace in libc older Solaris versions don't have this. */ #ifndef HAVE_BACKTRACE #ifdef HAVE_UCONTEXT_H #include #endif typedef struct backtrace { void **bt_buffer; int bt_maxcount; int bt_actcount; } backtrace_t; static int callback(uintptr_t pc, int signo, void *arg) { backtrace_t *bt = (backtrace_t *)arg; if (bt->bt_actcount >= bt->bt_maxcount) return (-1); bt->bt_buffer[bt->bt_actcount++] = (void *)pc; return (0); } static int backtrace(void **buffer, int count) { backtrace_t bt; ucontext_t u; bt.bt_buffer = buffer; bt.bt_maxcount = count; bt.bt_actcount = 0; if (getcontext(&u) < 0) return (0); (void) walkcontext(&u, callback, &bt); return (bt.bt_actcount); } /* * Define that we now know backtrace() */ #define HAVE_BACKTRACE 1 #endif /* HAVE_BACKTRACE */ #endif /* HAVE_SUN_OS */ /* * Support strack_trace support on platforms that use GCC as compiler. */ #if defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS) && \ defined(HAVE_GCC) #ifdef HAVE_CXXABI_H #include #endif #ifdef HAVE_EXECINFO_H #include #endif void stack_trace() { int status; size_t stack_depth, sz, i; const size_t max_depth = 100; void *stack_addrs[max_depth]; char **stack_strings, *begin, *end, *j, *function, *ret; stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); for (i = 3; i < stack_depth; i++) { sz = 200; /* Just a guess, template names will go much wider */ function = (char *)actuallymalloc(sz); begin = end = 0; /* * Find the parentheses and address offset surrounding the mangled name */ for (j = stack_strings[i]; *j; ++j) { if (*j == '(') { begin = j; } else if (*j == '+') { end = j; } } if (begin && end) { *begin++ = '\0'; *end = '\0'; /* * Found our mangled name, now in [begin, end] */ ret = abi::__cxa_demangle(begin, function, &sz, &status); if (ret) { /* * Return value may be a realloc() of the input */ function = ret; } else { /* * Demangling failed, just pretend it's a C function with no args */ strncpy(function, begin, sz - 3); strcat(function, "()"); function[sz - 1] = '\0'; } Pmsg2(000, " %s:%s\n", stack_strings[i], function); } else { /* didn't find the mangled name, just print the whole line */ Pmsg1(000, " %s\n", stack_strings[i]); } actuallyfree(function); } actuallyfree(stack_strings); /* malloc()ed by backtrace_symbols */ } /* * Support strack_trace support on Solaris when using the SUNPRO_CC compiler. */ #elif defined(HAVE_SUN_OS) && \ !defined(HAVE_NON_WORKING_WALKCONTEXT) && \ defined(HAVE_UCONTEXT_H) && \ defined(HAVE_DEMANGLE_H) && \ defined(HAVE_CPLUS_DEMANGLE) && \ defined(__SUNPRO_CC) #ifdef HAVE_UCONTEXT_H #include #endif #if defined(HAVE_EXECINFO_H) #include #endif #include void stack_trace() { int ret, i; bool demangled_symbol; size_t stack_depth; size_t sz = 200; /* Just a guess, template names will go much wider */ const size_t max_depth = 100; void *stack_addrs[100]; char **stack_strings, *begin, *end, *j, *function; stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); for (i = 1; i < stack_depth; i++) { function = (char *)actuallymalloc(sz); begin = end = 0; /* * Find the single quote and address offset surrounding the mangled name */ for (j = stack_strings[i]; *j; ++j) { if (*j == '\'') { begin = j; } else if (*j == '+') { end = j; } } if (begin && end) { *begin++ = '\0'; *end = '\0'; /* * Found our mangled name, now in [begin, end) */ demangled_symbol = false; while (!demangled_symbol) { ret = cplus_demangle(begin, function, sz); switch (ret) { case DEMANGLE_ENAME: /* * Demangling failed, just pretend it's a C function with no args */ strcat(function, "()"); function[sz - 1] = '\0'; demangled_symbol = true; break; case DEMANGLE_ESPACE: /* * Need more space for demangled function name. */ actuallyfree(function); sz = sz * 2; function = (char *)actuallymalloc(sz); continue; default: demangled_symbol = true; break; } } Pmsg2(000, " %s:%s\n", stack_strings[i], function); } else { /* * Didn't find the mangled name, just print the whole line */ Pmsg1(000, " %s\n", stack_strings[i]); } actuallyfree(function); } actuallyfree(stack_strings); /* malloc()ed by backtrace_symbols */ } #else void stack_trace() { } #endif bareos-Release-14.2.6/src/lib/btime.c000066400000000000000000000272411263011562700172470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS floating point time and date routines -- John Walker * * Later double precision integer time/date routines -- Kern Sibbald * */ /* Concerning times. There are a number of differnt time standards * in BAREOS (fdate_t, ftime_t, time_t (Unix standard), btime_t, and * utime_t). fdate_t and ftime_t are deprecated and should no longer * be used, and in general, Unix time time_t should no longer be used, * it is being phased out. * * Epoch is the base of Unix time in seconds (time_t, ...) * and is 1 Jan 1970 at 0:0 UTC * * The major two times that should be left are: * btime_t (64 bit integer in microseconds base Epoch) * utime_t (64 bit integer in seconds base Epoch) */ #include "bareos.h" #include void blocaltime(const time_t *time, struct tm *tm) { /* ***FIXME**** localtime_r() should be user configurable */ (void)localtime_r(time, tm); } /* * Formatted time for user display: dd-Mon-yyyy hh:mm */ char *bstrftime(char *dt, int maxlen, utime_t utime, const char *fmt) { time_t time = (time_t)utime; struct tm tm; blocaltime(&time, &tm); if (fmt) { strftime(dt, maxlen, fmt, &tm); } else { strftime(dt, maxlen, "%d-%b-%Y %H:%M", &tm); } return dt; } /* * Formatted time for user display: dd-Mon-yyyy hh:mm:ss */ char *bstrftimes(char *dt, int maxlen, utime_t utime) { return bstrftime(dt, maxlen, utime, "%d-%b-%Y %H:%M:%S"); } /* * Formatted time for user display: dd-Mon hh:mm */ char *bstrftime_ny(char *dt, int maxlen, utime_t utime) { return bstrftime(dt, maxlen, utime, "%d-%b %H:%M"); } /* * Formatted time for user display with weekday: weekday dd-Mon hh:mm */ char *bstrftime_wd(char *dt, int maxlen, utime_t utime) { return bstrftime(dt, maxlen, utime, "%a %d-%b-%Y %H:%M"); } /* * Formatted time for user display: dd-Mon-yy hh:mm (no century) */ char *bstrftime_nc(char *dt, int maxlen, utime_t utime) { char *p, *q; /* * NOTE! since the compiler complains about %y, I use %Y and cut the century */ bstrftime(dt, maxlen, utime, "%d-%b-%Y %H:%M"); /* * Overlay the century */ p = dt+7; q = dt+9; while (*q) { *p++ = *q++; } *p = 0; return dt; } /* * Unix time to standard time string yyyy-mm-dd hh:mm:ss */ char *bstrutime(char *dt, int maxlen, utime_t utime) { return bstrftime(dt, maxlen, utime, "%Y-%m-%d %H:%M:%S"); } /* * Convert standard time string yyyy-mm-dd hh:mm:ss to Unix time */ utime_t str_to_utime(const char *str) { struct tm tm; time_t time; /* * Check for bad argument */ if (!str || *str == 0) { return 0; } if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { return 0; } if (tm.tm_mon > 0) { tm.tm_mon--; } else { return 0; } if (tm.tm_year >= 1900) { tm.tm_year -= 1900; } else { return 0; } tm.tm_wday = tm.tm_yday = 0; tm.tm_isdst = -1; time = mktime(&tm); if (time == -1) { time = 0; } return (utime_t)time; } /* * BAREOS's time (btime_t) is an unsigned 64 bit integer that contains * the number of microseconds since Epoch Time (1 Jan 1970) UTC. */ btime_t get_current_btime() { struct timeval tv; if (gettimeofday(&tv, NULL) != 0) { tv.tv_sec = (long)time(NULL); /* fall back to old method */ tv.tv_usec = 0; } return ((btime_t)tv.tv_sec) * 1000000 + (btime_t)tv.tv_usec; } /* * Convert btime to Unix time */ time_t btime_to_unix(btime_t bt) { return (time_t)(bt/1000000); } /* * Convert btime to utime */ utime_t btime_to_utime(btime_t bt) { return (utime_t)(bt/1000000); } /* * Return the week of the month, base 0 (wom) * given tm_mday and tm_wday. Value returned * can be from 0 to 4 => week1, ... week5 */ int tm_wom(int mday, int wday) { int fs; /* first sunday */ int wom; fs = (mday%7) - wday; if (fs <= 0) { fs += 7; } if (mday <= fs) { return 0; } wom = 1 + (mday - fs - 1) / 7; return wom; } /* * Given a Unix date return the week of the year. * The returned value can be 0-53. Officially * the weeks are numbered from 1 to 53 where week1 * is the week in which the first Thursday of the * year occurs (alternatively, the week which contains * the 4th of January). We return 0, if the week of the * year does not fall in the current year. */ int tm_woy(time_t stime) { int woy, fty, tm_yday; time_t time4; struct tm tm; memset(&tm, 0, sizeof(struct tm)); blocaltime(&stime, &tm); tm_yday = tm.tm_yday; tm.tm_mon = 0; tm.tm_mday = 4; tm.tm_isdst = 0; /* 4 Jan is not DST */ time4 = mktime(&tm); blocaltime(&time4, &tm); fty = 1 - tm.tm_wday; if (fty <= 0) { fty += 7; } woy = tm_yday - fty + 4; if (woy < 0) { return 0; } return 1 + woy / 7; } /* * Deprecated. Do not use. */ void get_current_time(struct date_time *dt) { struct tm tm; time_t now; now = time(NULL); (void)gmtime_r(&now, &tm); Dmsg6(200, "m=%d d=%d y=%d h=%d m=%d s=%d\n", tm.tm_mon+1, tm.tm_mday, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec); tm_encode(dt, &tm); #ifdef DEBUG Dmsg2(200, "jday=%f jmin=%f\n", dt->julian_day_number, dt->julian_day_fraction); tm_decode(dt, &tm); Dmsg6(200, "m=%d d=%d y=%d h=%d m=%d s=%d\n", tm.tm_mon+1, tm.tm_mday, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec); #endif } /* date_encode -- Encode civil date as a Julian day number. */ /* Deprecated. Do not use. */ fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day) { /* Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 */ int32_t a, b, m; uint32_t y; ASSERT(month < 13); ASSERT(day > 0 && day < 32); m = month; y = year; if (m <= 2) { y--; m += 12; } /* Determine whether date is in Julian or Gregorian calendar based on canonical date of calendar reform. */ if ((year < 1582) || ((year == 1582) && ((month < 9) || (month == 9 && day < 5)))) { b = 0; } else { a = ((int) (y / 100)); b = 2 - a + (a / 4); } return (((int32_t) (365.25 * (y + 4716))) + ((int) (30.6001 * (m + 1))) + day + b - 1524.5); } /* time_encode -- Encode time from hours, minutes, and seconds into a fraction of a day. */ /* Deprecated. Do not use. */ ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second, float32_t second_fraction) { ASSERT((second_fraction >= 0.0) || (second_fraction < 1.0)); return (ftime_t) (((second + 60L * (minute + 60L * hour)) / 86400.0)) + second_fraction; } /* date_time_encode -- Set day number and fraction from date and time. */ /* Deprecated. Do not use. */ void date_time_encode(struct date_time *dt, uint32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, float32_t second_fraction) { dt->julian_day_number = date_encode(year, month, day); dt->julian_day_fraction = time_encode(hour, minute, second, second_fraction); } /* date_decode -- Decode a Julian day number into civil date. */ /* Deprecated. Do not use. */ void date_decode(fdate_t date, uint32_t *year, uint8_t *month, uint8_t *day) { fdate_t z, f, a, alpha, b, c, d, e; date += 0.5; z = floor(date); f = date - z; if (z < 2299161.0) { a = z; } else { alpha = floor((z - 1867216.25) / 36524.25); a = z + 1 + alpha - floor(alpha / 4); } b = a + 1524; c = floor((b - 122.1) / 365.25); d = floor(365.25 * c); e = floor((b - d) / 30.6001); *day = (uint8_t) (b - d - floor(30.6001 * e) + f); *month = (uint8_t) ((e < 14) ? (e - 1) : (e - 13)); *year = (uint32_t) ((*month > 2) ? (c - 4716) : (c - 4715)); } /* time_decode -- Decode a day fraction into civil time. */ /* Deprecated. Do not use. */ void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute, uint8_t *second, float32_t *second_fraction) { uint32_t ij; ij = (uint32_t) ((time - floor(time)) * 86400.0); *hour = (uint8_t) (ij / 3600L); *minute = (uint8_t) ((ij / 60L) % 60L); *second = (uint8_t) (ij % 60L); if (second_fraction != NULL) { *second_fraction = (float32_t)(time - floor(time)); } } /* date_time_decode -- Decode a Julian day and day fraction into civil date and time. */ /* Deprecated. Do not use. */ void date_time_decode(struct date_time *dt, uint32_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute, uint8_t *second, float32_t *second_fraction) { date_decode(dt->julian_day_number, year, month, day); time_decode(dt->julian_day_fraction, hour, minute, second, second_fraction); } /* tm_encode -- Encode a civil date and time from a tm structure * to a Julian day and day fraction. */ /* Deprecated. Do not use. */ void tm_encode(struct date_time *dt, struct tm *tm) { uint32_t year; uint8_t month, day, hour, minute, second; year = tm->tm_year + 1900; month = tm->tm_mon + 1; day = tm->tm_mday; hour = tm->tm_hour; minute = tm->tm_min; second = tm->tm_sec; dt->julian_day_number = date_encode(year, month, day); dt->julian_day_fraction = time_encode(hour, minute, second, 0.0); } /* tm_decode -- Decode a Julian day and day fraction into civil date and time in tm structure */ /* Deprecated. Do not use. */ void tm_decode(struct date_time *dt, struct tm *tm) { uint32_t year; uint8_t month, day, hour, minute, second; date_decode(dt->julian_day_number, &year, &month, &day); time_decode(dt->julian_day_fraction, &hour, &minute, &second, NULL); tm->tm_year = year - 1900; tm->tm_mon = month - 1; tm->tm_mday = day; tm->tm_hour = hour; tm->tm_min = minute; tm->tm_sec = second; } /* date_time_compare -- Compare two dates and times and return the relationship as follows: -1 dt1 < dt2 0 dt1 = dt2 1 dt1 > dt2 */ /* Deprecated. Do not use. */ int date_time_compare(struct date_time *dt1, struct date_time *dt2) { if (dt1->julian_day_number == dt2->julian_day_number) { if (dt1->julian_day_fraction == dt2->julian_day_fraction) { return 0; } return (dt1->julian_day_fraction < dt2->julian_day_fraction) ? -1 : 1; } return (dt1->julian_day_number - dt2->julian_day_number) ? -1 : 1; } bareos-Release-14.2.6/src/lib/btime.h000066400000000000000000000070771263011562700172610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __btime_INCLUDED #define __btime_INCLUDED /* New btime definition -- use this */ btime_t get_current_btime(void); time_t btime_to_unix(btime_t bt); /* bareos time to epoch time */ utime_t btime_to_utime(btime_t bt); /* bareos time to utime_t */ int tm_wom(int mday, int wday); int tm_woy(time_t stime); void blocaltime(const time_t *time, struct tm *tm); char *bstrutime(char *dt, int maxlen, utime_t tim); char *bstrftime(char *dt, int maxlen, utime_t tim, const char *fmt = NULL); char *bstrftimes(char *dt, int maxlen, utime_t tim); char *bstrftime_ny(char *dt, int maxlen, utime_t tim); char *bstrftime_nc(char *dt, int maxlen, utime_t tim); char *bstrftime_wd(char *dt, int maxlen, utime_t tim); utime_t str_to_utime(const char *str); /* =========================================================== */ /* old code deprecated below. Do not use. */ typedef float64_t fdate_t; /* Date type */ typedef float64_t ftime_t; /* Time type */ struct date_time { fdate_t julian_day_number; /* Julian day number */ ftime_t julian_day_fraction; /* Julian day fraction */ }; /* In arguments and results of the following functions, quantities are expressed as follows. year Year in the Common Era. The canonical date of adoption of the Gregorian calendar (October 5, 1582 in the Julian calendar) is assumed. month Month index with January 0, December 11. day Day number of month, 1 to 31. */ extern fdate_t date_encode(uint32_t year, uint8_t month, uint8_t day); extern ftime_t time_encode(uint8_t hour, uint8_t minute, uint8_t second, float32_t second_fraction); extern void date_time_encode(struct date_time *dt, uint32_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, float32_t second_fraction); extern void date_decode(fdate_t date, uint32_t *year, uint8_t *month, uint8_t *day); extern void time_decode(ftime_t time, uint8_t *hour, uint8_t *minute, uint8_t *second, float32_t *second_fraction); extern void date_time_decode(struct date_time *dt, uint32_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute, uint8_t *second, float32_t *second_fraction); extern int date_time_compare(struct date_time *dt1, struct date_time *dt2); extern void tm_encode(struct date_time *dt, struct tm *tm); extern void tm_decode(struct date_time *dt, struct tm *tm); extern void get_current_time(struct date_time *dt); #endif /* __btime_INCLUDED */ bareos-Release-14.2.6/src/lib/btimers.c000066400000000000000000000147551263011562700176220ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Process and thread timer routines, built on top of watchdogs. * * Nic Bellamy , October 2004. * */ #include "bareos.h" #include "jcr.h" const int dbglvl = 900; /* Forward referenced functions */ static void stop_btimer(btimer_t *wid); static btimer_t *btimer_start_common(uint32_t wait); /* Forward referenced callback functions */ static void callback_child_timer(watchdog_t *self); static void callback_thread_timer(watchdog_t *self); #ifdef xxx static void destructor_thread_timer(watchdog_t *self); static void destructor_child_timer(watchdog_t *self); #endif /* * Start a timer on a child process of pid, kill it after wait seconds. * * Returns: btimer_t *(pointer to btimer_t struct) on success * NULL on failure */ btimer_t *start_child_timer(JCR *jcr, pid_t pid, uint32_t wait) { btimer_t *wid; wid = btimer_start_common(wait); if (wid == NULL) { return NULL; } wid->type = TYPE_CHILD; wid->pid = pid; wid->killed = false; wid->jcr = jcr; wid->wd->callback = callback_child_timer; wid->wd->one_shot = false; wid->wd->interval = wait; register_watchdog(wid->wd); Dmsg3(dbglvl, "Start child timer %p, pid %d for %d secs.\n", wid, pid, wait); return wid; } /* * Stop child timer */ void stop_child_timer(btimer_t *wid) { if (wid == NULL) { Dmsg0(dbglvl, "stop_child_timer called with NULL btimer_id\n"); return; } Dmsg2(dbglvl, "Stop child timer %p pid %d\n", wid, wid->pid); stop_btimer(wid); } #ifdef xxx static void destructor_child_timer(watchdog_t *self) { btimer_t *wid = (btimer_t *)self->data; free(wid->wd); free(wid); } #endif static void callback_child_timer(watchdog_t *self) { btimer_t *wid = (btimer_t *)self->data; if (!wid->killed) { /* First kill attempt; try killing it softly (kill -SONG) first */ wid->killed = true; Dmsg2(dbglvl, "watchdog %p term PID %d\n", self, wid->pid); /* Kill -TERM the specified PID, and reschedule a -KILL for 5 seconds * later. (Warning: this should let dvd-writepart enough time to term * and kill growisofs, which takes 3 seconds, so the interval must not * be less than 5 seconds) */ kill(wid->pid, SIGTERM); self->interval = 5; } else { /* This is the second call - terminate with prejudice. */ Dmsg2(dbglvl, "watchdog %p kill PID %d\n", self, wid->pid); kill(wid->pid, SIGKILL); /* Setting one_shot to true before we leave ensures we don't get * rescheduled. */ self->one_shot = true; } } /* * Start a timer on a thread. kill it after wait seconds. * * Returns: btimer_t *(pointer to btimer_t struct) on success * NULL on failure */ btimer_t *start_thread_timer(JCR *jcr, pthread_t tid, uint32_t wait) { btimer_t *wid; wid = btimer_start_common(wait); if (wid == NULL) { Dmsg1(dbglvl, "start_thread_timer return NULL from common. wait=%d.\n", wait); return NULL; } wid->type = TYPE_PTHREAD; wid->tid = tid; wid->jcr = jcr; wid->wd->callback = callback_thread_timer; wid->wd->one_shot = true; wid->wd->interval = wait; register_watchdog(wid->wd); Dmsg3(dbglvl, "Start thread timer %p tid %p for %d secs.\n", wid, tid, wait); return wid; } /* * Start a timer on a BSOCK. kill it after wait seconds. * * Returns: btimer_t *(pointer to btimer_t struct) on success * NULL on failure */ btimer_t *start_bsock_timer(BSOCK *bsock, uint32_t wait) { btimer_t *wid; if (wait <= 0) { /* wait should be > 0 */ return NULL; } wid = btimer_start_common(wait); if (wid == NULL) { return NULL; } wid->type = TYPE_BSOCK; wid->tid = pthread_self(); wid->bsock = bsock; wid->jcr = bsock->jcr(); wid->wd->callback = callback_thread_timer; wid->wd->one_shot = true; wid->wd->interval = wait; register_watchdog(wid->wd); Dmsg4(dbglvl, "Start bsock timer %p tid=%p for %d secs at %d\n", wid, wid->tid, wait, time(NULL)); return wid; } /* * Stop bsock timer */ void stop_bsock_timer(btimer_t *wid) { if (wid == NULL) { Dmsg0(900, "stop_bsock_timer called with NULL btimer_id\n"); return; } Dmsg3(dbglvl, "Stop bsock timer %p tid=%p at %d.\n", wid, wid->tid, time(NULL)); stop_btimer(wid); } /* * Stop thread timer */ void stop_thread_timer(btimer_t *wid) { if (wid == NULL) { Dmsg0(dbglvl, "stop_thread_timer called with NULL btimer_id\n"); return; } Dmsg2(dbglvl, "Stop thread timer %p tid=%p.\n", wid, wid->tid); stop_btimer(wid); } #ifdef xxx static void destructor_thread_timer(watchdog_t *self) { btimer_t *wid = (btimer_t *)self->data; free(wid->wd); free(wid); } #endif static void callback_thread_timer(watchdog_t *self) { btimer_t *wid = (btimer_t *)self->data; Dmsg4(dbglvl, "thread timer %p kill %s tid=%p at %d.\n", self, wid->type == TYPE_BSOCK ? "bsock" : "thread", wid->tid, time(NULL)); if (wid->jcr) { Dmsg2(dbglvl, "killed jid=%u Job=%s\n", wid->jcr->JobId, wid->jcr->Job); } if (wid->type == TYPE_BSOCK && wid->bsock) { wid->bsock->set_timed_out(); } pthread_kill(wid->tid, TIMEOUT_SIGNAL); } static btimer_t *btimer_start_common(uint32_t wait) { btimer_t *wid = (btimer_t *)malloc(sizeof(btimer_t)); wid->wd = new_watchdog(); if (wid->wd == NULL) { free(wid); return NULL; } wid->wd->data = wid; wid->killed = FALSE; return wid; } /* * Stop btimer */ static void stop_btimer(btimer_t *wid) { if (wid == NULL) { Emsg0(M_ABORT, 0, _("stop_btimer called with NULL btimer_id\n")); } unregister_watchdog(wid->wd); free(wid->wd); free(wid); } bareos-Release-14.2.6/src/lib/btimers.h000066400000000000000000000026161263011562700176200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Process and thread timer routines, built on top of watchdogs. * * Nic Bellamy , October 2003. * */ #ifndef __BTIMERS_H_ #define __BTIMERS_H_ struct btimer_t { watchdog_t *wd; /* Parent watchdog */ int type; bool killed; pid_t pid; /* process id if TYPE_CHILD */ pthread_t tid; /* thread id if TYPE_PTHREAD */ BSOCK *bsock; /* Pointer to BSOCK */ JCR *jcr; /* Pointer to job control record */ }; #endif /* __BTIMERS_H_ */ bareos-Release-14.2.6/src/lib/cbuf.c000066400000000000000000000072041263011562700170630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, August 2013. */ /* * Circular buffer used for producer/consumer problem with pthreads. */ #include "bareos.h" #include "cbuf.h" /* * Initialize a new circular buffer. */ int circbuf::init() { if (pthread_mutex_init(&m_lock, NULL) != 0) { return -1; } if (pthread_cond_init(&m_notfull, NULL) != 0) { pthread_mutex_destroy(&m_lock); return -1; } if (pthread_cond_init(&m_notempty, NULL) != 0) { pthread_cond_destroy(&m_notfull); pthread_mutex_destroy(&m_lock); return -1; } m_next_in = 0; m_next_out = 0; m_size = 0; m_capacity = QSIZE; return 0; } /* * Destroy a circular buffer. */ void circbuf::destroy() { pthread_cond_destroy(&m_notempty); pthread_cond_destroy(&m_notfull); pthread_mutex_destroy(&m_lock); } /* * Enqueue a new item into the circular buffer. */ int circbuf::enqueue(void *data) { if (pthread_mutex_lock(&m_lock) != 0) { return -1; } /* * Wait while the buffer is full. */ while (full()) { pthread_cond_wait(&m_notfull, &m_lock); } m_data[m_next_in++] = data; m_size++; m_next_in %= m_capacity; /* * Let a waiting consumer know there is data. */ pthread_cond_signal(&m_notempty); pthread_mutex_unlock(&m_lock); return 0; } /* * Dequeue an item from the circular buffer. */ void *circbuf::dequeue() { void *data; if (pthread_mutex_lock(&m_lock) != 0) { return NULL; } /* * Wait while there is nothing in the buffer */ while (empty() && !m_flush) { pthread_cond_wait(&m_notempty, &m_lock); } /* * When we are requested to flush and there is no data left return NULL. */ if (empty() && m_flush) { m_flush = false; pthread_mutex_unlock(&m_lock); return NULL; } data = m_data[m_next_out++]; m_size--; m_next_out %= m_capacity; /* * Let a waiting producer know there is room. */ pthread_cond_signal(&m_notfull); pthread_mutex_unlock(&m_lock); return data; } /* * Make sure there is a free next slot available on the circular buffer. * So the next enqueue will not block but we block now until one is available. */ int circbuf::next_slot() { if (pthread_mutex_lock(&m_lock) != 0) { return -1; } /* * Wait while the buffer is full. */ while (full()) { pthread_cond_wait(&m_notfull, &m_lock); } pthread_mutex_unlock(&m_lock); return m_next_in; } /* * Flush the circular buffer. Any waiting consumer will be wakened and will * see we are in flush state. */ int circbuf::flush() { if (pthread_mutex_lock(&m_lock) != 0) { return -1; } m_flush = true; /* * Let a waiting consumer know there will be no more data. */ pthread_cond_signal(&m_notempty); pthread_mutex_unlock(&m_lock); return 0; } bareos-Release-14.2.6/src/lib/cbuf.h000066400000000000000000000034201263011562700170640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, August 2013. */ /* * Circular buffer used for producer/consumer problem with pthread. */ #define QSIZE 10 /* # of pointers in the queue */ class circbuf : public SMARTALLOC { int m_size; int m_next_in; int m_next_out; int m_capacity; bool m_flush; pthread_mutex_t m_lock; /* Lock the structure */ pthread_cond_t m_notfull; /* Full -> not full condition */ pthread_cond_t m_notempty; /* Empty -> not empty condition */ void *m_data[QSIZE]; /* Circular buffer of pointers */ public: circbuf(); ~circbuf(); int init(); void destroy(); int enqueue(void *data); void *dequeue(); int next_slot(); int flush(); bool full() { return m_size == m_capacity; }; bool empty() { return m_size == 0; }; int capacity() const { return m_capacity; }; }; /* * Constructor */ inline circbuf::circbuf() { init(); } /* * Destructor */ inline circbuf::~circbuf() { destroy(); } bareos-Release-14.2.6/src/lib/compression.c000066400000000000000000000667111263011562700205150ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Functions to handle compression/decompression of data. * * Kern Sibbald, November MM * * Extracted from other source files by Marco van Wieringen, May 2013 */ #include "bareos.h" #include "jcr.h" #include "ch.h" #include "streams.h" #if defined(HAVE_LZO) || defined(HAVE_LIBZ) || defined(HAVE_FASTLZ) #ifdef HAVE_LIBZ #include #endif #ifdef HAVE_LZO #include #include #endif #ifdef HAVE_FASTLZ #include #endif #ifdef HAVE_LIBZ #ifndef HAVE_COMPRESS_BOUND #define compressBound(sourceLen) (sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13) #endif /* * Convert ZLIB error code into an ASCII message */ static const char *zlib_strerror(int stat) { if (stat >= 0) { return _("None"); } switch (stat) { case Z_ERRNO: return _("Zlib errno"); case Z_STREAM_ERROR: return _("Zlib stream error"); case Z_DATA_ERROR: return _("Zlib data error"); case Z_MEM_ERROR: return _("Zlib memory error"); case Z_BUF_ERROR: return _("Zlib buffer error"); case Z_VERSION_ERROR: return _("Zlib version error"); default: return _("*none*"); } } #endif static inline void unknown_compression_algorithm(JCR *jcr, uint32_t compression_algorithm) { switch (compression_algorithm) { case COMPRESS_GZIP: Jmsg(jcr, M_FATAL, 0, _("GZIP compression not supported on this platform\n")); break; case COMPRESS_LZO1X: Jmsg(jcr, M_FATAL, 0, _("LZO2 compression not supported on this platform\n")); break; case COMPRESS_FZFZ: Jmsg(jcr, M_FATAL, 0, _("LZFZ compression not supported on this platform\n")); break; case COMPRESS_FZ4L: Jmsg(jcr, M_FATAL, 0, _("LZ4 compression not supported on this platform\n")); break; case COMPRESS_FZ4H: Jmsg(jcr, M_FATAL, 0, _("LZ4HC compression not supported on this platform\n")); break; default: Jmsg(jcr, M_FATAL, 0, _("Unknown compression algorithm specified %d\n"), compression_algorithm); break; } } static inline void non_compatible_compression_algorithm(JCR *jcr, uint32_t compression_algorithm) { switch (compression_algorithm) { case COMPRESS_FZFZ: Jmsg(jcr, M_FATAL, 0, _("Illegal compression algorithm LZFZ for compatible mode\n")); break; case COMPRESS_FZ4L: Jmsg(jcr, M_FATAL, 0, _("Illegal compression algorithm LZ4 for compatible mode\n")); break; case COMPRESS_FZ4H: Jmsg(jcr, M_FATAL, 0, _("Illegal compression algorithm LZ4HC for compatible mode\n")); break; default: break; } } bool setup_compression_buffers(JCR *jcr, bool compatible, uint32_t compression_algorithm, uint32_t *compress_buf_size) { uint32_t wanted_compress_buf_size; switch (compression_algorithm) { case 0: /* * No compression requested. */ break; #ifdef HAVE_LIBZ case COMPRESS_GZIP: { z_stream *pZlibStream; /** * Use compressBound() to get an idea what zlib thinks * what the upper limit is of what it needs to compress * a buffer of x bytes. To that we add 18 bytes and the size * of an compression header. * * This gives a bit extra plus room for the sparse addr if any. * Note, we adjust the read size to be smaller so that the * same output buffer can be used without growing it. * * The zlib compression workset is initialized here to minimize * the "per file" load. The jcr member is only set, if the init * was successful. */ wanted_compress_buf_size = compressBound(jcr->buf_size) + 18 + (int)sizeof(comp_stream_header); if (wanted_compress_buf_size > *compress_buf_size) { *compress_buf_size = wanted_compress_buf_size; } /* * See if this compression algorithm is already setup. */ if (jcr->compress.workset.pZLIB) { return true; } pZlibStream = (z_stream *)malloc(sizeof(z_stream)); memset(pZlibStream, 0, sizeof(z_stream)); pZlibStream->zalloc = Z_NULL; pZlibStream->zfree = Z_NULL; pZlibStream->opaque = Z_NULL; pZlibStream->state = Z_NULL; if (deflateInit(pZlibStream, Z_DEFAULT_COMPRESSION) == Z_OK) { jcr->compress.workset.pZLIB = pZlibStream; } else { Jmsg(jcr, M_FATAL, 0, _("Failed to initialize ZLIB compression\n")); free(pZlibStream); return false; } break; } #endif #ifdef HAVE_LZO case COMPRESS_LZO1X: { lzo_voidp pLzoMem; /** * For LZO1X compression the recommended value is: * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + sizeof(comp_stream_header) * * The LZO compression workset is initialized here to minimize * the "per file" load. The jcr member is only set, if the init * was successful. */ wanted_compress_buf_size = jcr->buf_size + (jcr->buf_size / 16) + 64 + 3 + (int)sizeof(comp_stream_header); if (wanted_compress_buf_size > *compress_buf_size) { *compress_buf_size = wanted_compress_buf_size; } /* * See if this compression algorithm is already setup. */ if (jcr->compress.workset.pLZO) { return true; } pLzoMem = (lzo_voidp) malloc(LZO1X_1_MEM_COMPRESS); memset(pLzoMem, 0, LZO1X_1_MEM_COMPRESS); if (lzo_init() == LZO_E_OK) { jcr->compress.workset.pLZO = pLzoMem; } else { Jmsg(jcr, M_FATAL, 0, _("Failed to initialize LZO compression\n")); free(pLzoMem); return false; } break; } #endif #ifdef HAVE_FASTLZ case COMPRESS_FZFZ: case COMPRESS_FZ4L: case COMPRESS_FZ4H: { int level, zstat; zfast_stream *pZfastStream; if (compatible) { non_compatible_compression_algorithm(jcr, compression_algorithm); return false; } if (compression_algorithm == COMPRESS_FZ4H) { level = Z_BEST_COMPRESSION; } else { level = Z_BEST_SPEED; } /* * For FASTLZ compression the recommended value is: * output_block_size = input_block_size + (input_block_size / 10 + 16 * 2) + sizeof(comp_stream_header) * * The FASTLZ compression workset is initialized here to minimize * the "per file" load. The jcr member is only set, if the init * was successful. */ wanted_compress_buf_size = jcr->buf_size + (jcr->buf_size / 10 + 16 * 2) + (int)sizeof(comp_stream_header); if (wanted_compress_buf_size > *compress_buf_size) { *compress_buf_size = wanted_compress_buf_size; } /* * See if this compression algorithm is already setup. */ if (jcr->compress.workset.pZFAST) { return true; } pZfastStream = (zfast_stream *)malloc(sizeof(zfast_stream)); memset(pZfastStream, 0, sizeof(zfast_stream)); pZfastStream->zalloc = Z_NULL; pZfastStream->zfree = Z_NULL; pZfastStream->opaque = Z_NULL; pZfastStream->state = Z_NULL; if ((zstat = fastlzlibCompressInit(pZfastStream, level)) == Z_OK) { jcr->compress.workset.pZFAST = pZfastStream; } else { Jmsg(jcr, M_FATAL, 0, _("Failed to initialize FASTLZ compression\n")); free(pZfastStream); return false; } break; } #endif default: unknown_compression_algorithm(jcr, compression_algorithm); return false; } return true; } bool setup_decompression_buffers(JCR *jcr, uint32_t *decompress_buf_size) { uint32_t compress_buf_size; /* * Use the same buffer size to decompress all data. */ compress_buf_size = jcr->buf_size; if (compress_buf_size < DEFAULT_NETWORK_BUFFER_SIZE) { compress_buf_size = DEFAULT_NETWORK_BUFFER_SIZE; } *decompress_buf_size = compress_buf_size + 12 + ((compress_buf_size + 999) / 1000) + 100; #ifdef HAVE_LZO if (!jcr->compress.inflate_buffer && lzo_init() != LZO_E_OK) { Jmsg(jcr, M_FATAL, 0, _("LZO init failed\n")); return false; } #endif return true; } #ifdef HAVE_LIBZ static bool compress_with_zlib(JCR *jcr, char *rbuf, uint32_t rsize, unsigned char *cbuf, uint32_t max_compress_len, uint32_t *compress_len) { int zstat; z_stream *pZlibStream; Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, rsize); pZlibStream = (z_stream *)jcr->compress.workset.pZLIB; pZlibStream->next_in = (Bytef *)rbuf; pZlibStream->avail_in = rsize; pZlibStream->next_out = (Bytef *)cbuf; pZlibStream->avail_out = max_compress_len; if ((zstat = deflate(pZlibStream, Z_FINISH)) != Z_STREAM_END) { Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat); jcr->setJobStatus(JS_ErrorTerminated); return false; } *compress_len = pZlibStream->total_out; /* * Reset zlib stream to be able to begin from scratch again */ if ((zstat = deflateReset(pZlibStream)) != Z_OK) { Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat); jcr->setJobStatus(JS_ErrorTerminated); return false; } Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", *compress_len, rsize); return true; } #endif #ifdef HAVE_LZO static bool compress_with_lzo(JCR *jcr, char *rbuf, uint32_t rsize, unsigned char *cbuf, uint32_t max_compress_len, uint32_t *compress_len) { int lzores; lzo_uint len = 0; Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, rsize); lzores = lzo1x_1_compress((const unsigned char *)rbuf, rsize, cbuf, &len, jcr->compress.workset.pLZO); *compress_len = len; if (lzores != LZO_E_OK || *compress_len > max_compress_len) { /* * This should NEVER happen */ Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores); jcr->setJobStatus(JS_ErrorTerminated); return false; } Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", *compress_len, rsize); return true; } #endif #ifdef HAVE_FASTLZ static bool compress_with_fastlz(JCR *jcr, char *rbuf, uint32_t rsize, unsigned char *cbuf, uint32_t max_compress_len, uint32_t *compress_len) { int zstat; zfast_stream *pZfastStream; Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, rsize); pZfastStream = (zfast_stream *)jcr->compress.workset.pZFAST; pZfastStream->next_in = (Bytef *)rbuf; pZfastStream->avail_in = rsize; pZfastStream->next_out = (Bytef *)cbuf; pZfastStream->avail_out = max_compress_len; if ((zstat = fastlzlibCompress(pZfastStream, Z_FINISH)) != Z_STREAM_END) { Jmsg(jcr, M_FATAL, 0, _("Compression fastlzlibCompress error: %d\n"), zstat); jcr->setJobStatus(JS_ErrorTerminated); return false; } *compress_len = pZfastStream->total_out; /* * Reset fastlz stream to be able to begin from scratch again */ if ((zstat = fastlzlibCompressReset(pZfastStream)) != Z_OK) { Jmsg(jcr, M_FATAL, 0, _("Compression fastlzlibCompressReset error: %d\n"), zstat); jcr->setJobStatus(JS_ErrorTerminated); return false; } Dmsg2(400, "FASTLZ compressed len=%d uncompressed len=%d\n", *compress_len, rsize); return true; } #endif bool compress_data(JCR *jcr, uint32_t compression_algorithm, char *rbuf, uint32_t rsize, unsigned char *cbuf, uint32_t max_compress_len, uint32_t *compress_len) { *compress_len = 0; switch (compression_algorithm) { #ifdef HAVE_LIBZ case COMPRESS_GZIP: if (jcr->compress.workset.pZLIB) { if (!compress_with_zlib(jcr, rbuf, rsize, cbuf, max_compress_len, compress_len)) { return false; } } break; #endif #ifdef HAVE_LZO case COMPRESS_LZO1X: if (jcr->compress.workset.pLZO) { if (!compress_with_lzo(jcr, rbuf, rsize, cbuf, max_compress_len, compress_len)) { return false; } } break; #endif #ifdef HAVE_FASTLZ case COMPRESS_FZFZ: case COMPRESS_FZ4L: case COMPRESS_FZ4H: if (jcr->compress.workset.pZFAST) { if (!compress_with_fastlz(jcr, rbuf, rsize, cbuf, max_compress_len, compress_len)) { return false; } } break; #endif default: break; } return true; } #ifdef HAVE_LIBZ static bool decompress_with_zlib(JCR *jcr, const char *last_fname, char **data, uint32_t *length, bool sparse, bool with_header, bool want_data_stream) { char ec1[50]; /* Buffer printing huge values */ uLong compress_len; const unsigned char *cbuf; char *wbuf; int status, real_compress_len; /* * NOTE! We only use uLong and Byte because they are * needed by the zlib routines, they should not otherwise * be used in Bareos. */ if (sparse && want_data_stream) { wbuf = jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE; compress_len = jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE; } else { wbuf = jcr->compress.inflate_buffer; compress_len = jcr->compress.inflate_buffer_size; } /* * See if this is a compressed stream with the new compression header or an old one. */ if (with_header) { cbuf = (const unsigned char*)*data + sizeof(comp_stream_header); real_compress_len = *length - sizeof(comp_stream_header); } else { cbuf = (const unsigned char*)*data; real_compress_len = *length; } Dmsg2(400, "Comp_len=%d msglen=%d\n", compress_len, *length); while ((status = uncompress((Byte *)wbuf, &compress_len, (const Byte *)cbuf, (uLong)real_compress_len)) == Z_BUF_ERROR) { /* * The buffer size is too small, try with a bigger one */ jcr->compress.inflate_buffer_size = jcr->compress.inflate_buffer_size + (jcr->compress.inflate_buffer_size >> 1); jcr->compress.inflate_buffer = check_pool_memory_size(jcr->compress.inflate_buffer, jcr->compress.inflate_buffer_size); if (sparse && want_data_stream) { wbuf = jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE; compress_len = jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE; } else { wbuf = jcr->compress.inflate_buffer; compress_len = jcr->compress.inflate_buffer_size; } Dmsg2(400, "Comp_len=%d msglen=%d\n", compress_len, *length); } if (status != Z_OK) { Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"), last_fname, zlib_strerror(status)); return false; } /* * We return a decompressed data stream with the fileoffset encoded when this was a sparse stream. */ if (sparse && want_data_stream) { memcpy(jcr->compress.inflate_buffer, *data, OFFSET_FADDR_SIZE); } *data = jcr->compress.inflate_buffer; *length = compress_len; Dmsg2(400, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1)); return true; } #endif #ifdef HAVE_LZO static bool decompress_with_lzo(JCR *jcr, const char *last_fname, char **data, uint32_t *length, bool sparse, bool want_data_stream) { char ec1[50]; /* Buffer printing huge values */ lzo_uint compress_len; const unsigned char *cbuf; unsigned char *wbuf; int status, real_compress_len; if (sparse && want_data_stream) { compress_len = jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE; cbuf = (const unsigned char *)*data + OFFSET_FADDR_SIZE + sizeof(comp_stream_header); wbuf = (unsigned char *)jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE; } else { compress_len = jcr->compress.inflate_buffer_size; cbuf = (const unsigned char *)*data + sizeof(comp_stream_header); wbuf = (unsigned char *)jcr->compress.inflate_buffer; } real_compress_len = *length - sizeof(comp_stream_header); Dmsg2(400, "Comp_len=%d msglen=%d\n", compress_len, *length); while ((status = lzo1x_decompress_safe(cbuf, real_compress_len, wbuf, &compress_len, NULL)) == LZO_E_OUTPUT_OVERRUN) { /* * The buffer size is too small, try with a bigger one */ jcr->compress.inflate_buffer_size = jcr->compress.inflate_buffer_size + (jcr->compress.inflate_buffer_size >> 1); jcr->compress.inflate_buffer = check_pool_memory_size(jcr->compress.inflate_buffer, jcr->compress.inflate_buffer_size); if (sparse && want_data_stream) { compress_len = jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE; wbuf = (unsigned char *)jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE; } else { compress_len = jcr->compress.inflate_buffer_size; wbuf = (unsigned char *)jcr->compress.inflate_buffer; } Dmsg2(400, "Comp_len=%d msglen=%d\n", compress_len, *length); } if (status != LZO_E_OK) { Qmsg(jcr, M_ERROR, 0, _("LZO uncompression error on file %s. ERR=%d\n"), last_fname, status); return false; } /* * We return a decompressed data stream with the fileoffset encoded when this was a sparse stream. */ if (sparse && want_data_stream) { memcpy(jcr->compress.inflate_buffer, *data, OFFSET_FADDR_SIZE); } *data = jcr->compress.inflate_buffer; *length = compress_len; Dmsg2(400, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1)); return true; } #endif #ifdef HAVE_FASTLZ static bool decompress_with_fastlz(JCR *jcr, const char *last_fname, char **data, uint32_t *length, uint32_t comp_magic, bool sparse, bool want_data_stream) { int zstat; zfast_stream stream; zfast_stream_compressor compressor = COMPRESSOR_FASTLZ; char ec1[50]; /* Buffer printing huge values */ switch (comp_magic) { case COMPRESS_FZ4L: case COMPRESS_FZ4H: compressor = COMPRESSOR_LZ4; break; } /* * NOTE! We only use uInt and Bytef because they are * needed by the fastlz routines, they should not otherwise * be used in Bareos. */ memset(&stream, 0, sizeof(stream)); stream.next_in = (Bytef *)*data + sizeof(comp_stream_header); stream.avail_in = (uInt)*length - sizeof(comp_stream_header); if (sparse && want_data_stream) { stream.next_out = (Bytef *)jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE; stream.avail_out = (uInt)jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE; } else { stream.next_out = (Bytef *)jcr->compress.inflate_buffer; stream.avail_out = (uInt)jcr->compress.inflate_buffer_size; } Dmsg2(400, "Comp_len=%d msglen=%d\n", stream.avail_in, *length); if ((zstat = fastlzlibDecompressInit(&stream)) != Z_OK) { goto cleanup; } if ((zstat = fastlzlibSetCompressor(&stream, compressor)) != Z_OK) { goto cleanup; } while (1) { zstat = fastlzlibDecompress(&stream); switch (zstat) { case Z_BUF_ERROR: /* * The buffer size is too small, try with a bigger one */ jcr->compress.inflate_buffer_size = jcr->compress.inflate_buffer_size + (jcr->compress.inflate_buffer_size >> 1); jcr->compress.inflate_buffer = check_pool_memory_size(jcr->compress.inflate_buffer, jcr->compress.inflate_buffer_size); if (sparse && want_data_stream) { stream.next_out = (Bytef *)jcr->compress.inflate_buffer + OFFSET_FADDR_SIZE; stream.avail_out = (uInt)jcr->compress.inflate_buffer_size - OFFSET_FADDR_SIZE; } else { stream.next_out = (Bytef *)jcr->compress.inflate_buffer; stream.avail_out = (uInt)jcr->compress.inflate_buffer_size; } continue; case Z_OK: case Z_STREAM_END: break; default: goto cleanup; } break; } /* * We return a decompressed data stream with the fileoffset encoded when this was a sparse stream. */ if (sparse && want_data_stream) { memcpy(jcr->compress.inflate_buffer, *data, OFFSET_FADDR_SIZE); } *data = jcr->compress.inflate_buffer; *length = stream.total_out; Dmsg2(400, "Write uncompressed %d bytes, total before write=%s\n", *length, edit_uint64(jcr->JobBytes, ec1)); fastlzlibDecompressEnd(&stream); return true; cleanup: Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"), last_fname, zlib_strerror(zstat)); fastlzlibDecompressEnd(&stream); return false; } #endif bool decompress_data(JCR *jcr, const char *last_fname, int32_t stream, char **data, uint32_t *length, bool want_data_stream) { Dmsg1(400, "Stream found in decompress_data(): %d\n", stream); switch (stream) { case STREAM_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: { uint32_t comp_magic, comp_len; uint16_t comp_level, comp_version; /* * Read compress header */ unser_declare; unser_begin(*data, sizeof(comp_stream_header)); unser_uint32(comp_magic); unser_uint32(comp_len); unser_uint16(comp_level); unser_uint16(comp_version); unser_end(*data, sizeof(comp_stream_header)); Dmsg4(400, "Compressed data stream found: magic=0x%x, len=%d, level=%d, ver=0x%x\n", comp_magic, comp_len, comp_level, comp_version); /* * Version check */ if (comp_version != COMP_HEAD_VERSION) { Qmsg(jcr, M_ERROR, 0, _("Compressed header version error. version=0x%x\n"), comp_version); return false; } /* * Size check */ if (comp_len + sizeof(comp_stream_header) != *length) { Qmsg(jcr, M_ERROR, 0, _("Compressed header size error. comp_len=%d, msglen=%d\n"), comp_len, *length); return false; } /* * Based on the compression used perform the actual decompression of the data. */ switch (comp_magic) { #ifdef HAVE_LIBZ case COMPRESS_GZIP: switch (stream) { case STREAM_SPARSE_COMPRESSED_DATA: return decompress_with_zlib(jcr, last_fname, data, length, true, true, want_data_stream); default: return decompress_with_zlib(jcr, last_fname, data, length, false, true, want_data_stream); } #endif #ifdef HAVE_LZO case COMPRESS_LZO1X: switch (stream) { case STREAM_SPARSE_COMPRESSED_DATA: return decompress_with_lzo(jcr, last_fname, data, length, true, want_data_stream); default: return decompress_with_lzo(jcr, last_fname, data, length, false, want_data_stream); } #endif #ifdef HAVE_FASTLZ case COMPRESS_FZFZ: case COMPRESS_FZ4L: case COMPRESS_FZ4H: switch (stream) { case STREAM_SPARSE_COMPRESSED_DATA: return decompress_with_fastlz(jcr, last_fname, data, length, comp_magic, true, want_data_stream); default: return decompress_with_fastlz(jcr, last_fname, data, length, comp_magic, false, want_data_stream); } #endif default: Qmsg(jcr, M_ERROR, 0, _("Compression algorithm 0x%x found, but not supported!\n"), comp_magic); return false; } break; } default: #ifdef HAVE_LIBZ switch (stream) { case STREAM_SPARSE_GZIP_DATA: return decompress_with_zlib(jcr, last_fname, data, length, true, false, want_data_stream); default: return decompress_with_zlib(jcr, last_fname, data, length, false, false, want_data_stream); } #else Qmsg(jcr, M_ERROR, 0, _("Compression algorithm GZIP found, but not supported!\n")); return false; #endif } } void cleanup_compression(JCR *jcr) { if (jcr->compress.deflate_buffer) { free_pool_memory(jcr->compress.deflate_buffer); jcr->compress.deflate_buffer = NULL; } if (jcr->compress.inflate_buffer) { free_pool_memory(jcr->compress.inflate_buffer); jcr->compress.inflate_buffer = NULL; } #ifdef HAVE_LIBZ if (jcr->compress.workset.pZLIB) { /* * Free the zlib stream */ deflateEnd((z_stream *)jcr->compress.workset.pZLIB); free(jcr->compress.workset.pZLIB); jcr->compress.workset.pZLIB = NULL; } #endif #ifdef HAVE_LZO if (jcr->compress.workset.pLZO) { free(jcr->compress.workset.pLZO); jcr->compress.workset.pLZO = NULL; } #endif #ifdef HAVE_FASTLZ if (jcr->compress.workset.pZFAST) { free(jcr->compress.workset.pZFAST); jcr->compress.workset.pZFAST = NULL; } #endif } #else bool setup_compression_buffers(JCR *jcr, bool compatible, uint32_t compression_algorithm, uint32_t *compress_buf_size) { return true; } bool setup_decompression_buffers(JCR *jcr, uint32_t *decompress_buf_size) { *decompress_buf_size = 0; return true; } bool compress_data(JCR *jcr, uint32_t compression_algorithm, char *rbuf, uint32_t rsize, unsigned char *cbuf, uint32_t max_compress_len, uint32_t *compress_len) { return true; } bool decompress_data(JCR *jcr, const char *last_fname, int32_t stream, char **data, uint32_t *length, bool want_data_stream) { Qmsg(jcr, M_ERROR, 0, _("Compressed data stream found, but compression not configured!\n")); return false; } void cleanup_compression(JCR *jcr) { } #endif /* defined(HAVE_LZO) || defined(HAVE_LIBZ) || defined(HAVE_FASTLZ) */ bareos-Release-14.2.6/src/lib/cram-md5.c000066400000000000000000000122501263011562700175460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Challenge Response Authentication Method using MD5 (CRAM-MD5) * cram-md5 is based on RFC2104. * * Kern E. Sibbald, May MMI. */ #include "bareos.h" const int dbglvl = 50; /* Authorize other end * Codes that tls_local_need and tls_remote_need can take: * * BNET_TLS_NONE I cannot do tls * BNET_TLS_OK I can do tls, but it is not required on my end * BNET_TLS_REQUIRED tls is required on my end * * Returns: false if authentication failed * true if OK */ bool cram_md5_challenge(BSOCK *bs, const char *password, int tls_local_need, bool compatible) { struct timeval t1; struct timeval t2; struct timezone tz; int i; bool ok; POOL_MEM chal(PM_NAME), host(PM_NAME); uint8_t hmac[20]; gettimeofday(&t1, &tz); for (i=0; i<4; i++) { gettimeofday(&t2, &tz); } srandom((t1.tv_sec & 0xffff) * (t2.tv_usec & 0xff)); host.check_size(MAXHOSTNAMELEN); if (!gethostname(host.c_str(), MAXHOSTNAMELEN)) { pm_strcpy(host, my_name); } /* Send challenge -- no hashing yet */ Mmsg(chal, "<%u.%u@%s>", (uint32_t)random(), (uint32_t)time(NULL), host.c_str()); if (compatible) { Dmsg2(dbglvl, "send: auth cram-md5 %s ssl=%d\n", chal.c_str(), tls_local_need); if (!bs->fsend("auth cram-md5 %s ssl=%d\n", chal.c_str(), tls_local_need)) { Dmsg1(dbglvl, "Bnet send challenge comm error. ERR=%s\n", bs->bstrerror()); return false; } } else { /* Old non-compatible system */ Dmsg2(dbglvl, "send: auth cram-md5 %s ssl=%d\n", chal.c_str(), tls_local_need); if (!bs->fsend("auth cram-md5 %s ssl=%d\n", chal.c_str(), tls_local_need)) { Dmsg1(dbglvl, "Bnet send challenge comm error. ERR=%s\n", bs->bstrerror()); return false; } } /* Read hashed response to challenge */ if (bs->wait_data(180) <= 0 || bs->recv() <= 0) { Dmsg1(dbglvl, "Bnet receive challenge response comm error. ERR=%s\n", bs->bstrerror()); bmicrosleep(5, 0); return false; } /* Attempt to duplicate hash with our password */ hmac_md5((uint8_t *)chal.c_str(), strlen(chal.c_str()), (uint8_t *)password, strlen(password), hmac); bin_to_base64(host.c_str(), MAXHOSTNAMELEN, (char *)hmac, 16, compatible); ok = bstrcmp(bs->msg, host.c_str()); if (ok) { Dmsg1(dbglvl, "Authenticate OK %s\n", host.c_str()); } else { bin_to_base64(host.c_str(), MAXHOSTNAMELEN, (char *)hmac, 16, false); ok = bstrcmp(bs->msg, host.c_str()); if (!ok) { Dmsg2(dbglvl, "Authenticate NOT OK: wanted %s, got %s\n", host.c_str(), bs->msg); } } if (ok) { bs->fsend("1000 OK auth\n"); } else { bs->fsend(_("1999 Authorization failed.\n")); bmicrosleep(5, 0); } return ok; } /* Respond to challenge from other end */ bool cram_md5_respond(BSOCK *bs, const char *password, int *tls_remote_need, bool *compatible) { POOL_MEM chal(PM_NAME); uint8_t hmac[20]; *compatible = false; if (bs->recv() <= 0) { bmicrosleep(5, 0); return false; } Dmsg1(100, "cram-get received: %s", bs->msg); chal.check_size(bs->msglen); if (sscanf(bs->msg, "auth cram-md5c %s ssl=%d", chal.c_str(), tls_remote_need) == 2) { *compatible = true; } else if (sscanf(bs->msg, "auth cram-md5 %s ssl=%d", chal.c_str(), tls_remote_need) != 2) { if (sscanf(bs->msg, "auth cram-md5 %s\n", chal.c_str()) != 1) { Dmsg1(dbglvl, "Cannot scan challenge: %s", bs->msg); bs->fsend(_("1999 Authorization failed.\n")); bmicrosleep(5, 0); return false; } } hmac_md5((uint8_t *)chal.c_str(), strlen(chal.c_str()), (uint8_t *)password, strlen(password), hmac); bs->msglen = bin_to_base64(bs->msg, 50, (char *)hmac, 16, *compatible) + 1; // Dmsg3(100, "get_auth: chal=%s pw=%s hmac=%s\n", chal.c_str(), password, bs->msg); if (!bs->send()) { Dmsg1(dbglvl, "Send challenge failed. ERR=%s\n", bs->bstrerror()); return false; } Dmsg1(99, "sending resp to challenge: %s\n", bs->msg); if (bs->wait_data(180) <= 0 || bs->recv() <= 0) { Dmsg1(dbglvl, "Receive challenge response failed. ERR=%s\n", bs->bstrerror()); bmicrosleep(5, 0); return false; } if (bstrcmp(bs->msg, "1000 OK auth\n")) { return true; } Dmsg1(dbglvl, "Received bad response: %s\n", bs->msg); bmicrosleep(5, 0); return false; } bareos-Release-14.2.6/src/lib/crypto.c000066400000000000000000000124331263011562700174640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto.c Encryption support functions * * Author: Landon Fuller */ #include "bareos.h" /* * BAREOS ASN.1 Syntax * * OID Allocation: * Prefix: iso.org.dod.internet.private.enterprise.bareos.backup(1.3.6.1.4.1.41093.1) * Organization: Bareos GmbH & Co. KG * Contact Name: Marco van Wieringen * Contact E-mail: marco.van.wieringen@bareos.com * * Top Level Allocations - 1 * 1 - Published Allocations * 1.1 - Bareos Encryption * * Bareos Encryption - 1.1.1 * 1 - ASN.1 Modules * 1.1 - BareosCrypto * 2 - ASN.1 Object Identifiers * 2.1 - SignatureData * 2.2 - SignerInfo * 2.3 - CryptoData * 2.4 - RecipientInfo * * BareosCrypto { iso(1) identified-organization(3) usdod(6) * internet(1) private(4) enterprises(1) bareos(41093) * bareos(1) published(1) bareos-encryption(1) * asn1-modules(1) bareos-crypto(1) } * * DEFINITIONS AUTOMATIC TAGS ::= * BEGIN * * SignatureData ::= SEQUENCE { * version Version DEFAULT v0, * signerInfo SignerInfo } * * CryptoData ::= SEQUENCE { * version Version DEFAULT v0, * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, * iv InitializationVector, * recipientInfo RecipientInfo * } * * SignerInfo ::= SET OF SignerInfo * RecipientInfo ::= SET OF RecipientInfo * * Version ::= INTEGER { v0(0) } * * SignerInfo ::= SEQUENCE { * version Version, * subjectKeyIdentifier SubjectKeyIdentifier, * digestAlgorithm DigestAlgorithmIdentifier, * signatureAlgorithm SignatureAlgorithmIdentifier, * signature SignatureValue } * * RecipientInfo ::= SEQUENCE { * version Version * subjectKeyIdentifier SubjectKeyIdentifier * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier * encryptedKey EncryptedKey * } * * SubjectKeyIdentifier ::= OCTET STRING * * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier * * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * InitializationVector ::= OCTET STRING * * SignatureValue ::= OCTET STRING * * EncryptedKey ::= OCTET STRING * * AlgorithmIdentifier ::= OBJECT IDENTIFIER * * END */ /* Shared Code */ /* * Default PEM encryption passphrase callback. * Returns an empty password. */ int crypto_default_pem_callback(char *buf, int size, const void *userdata) { bstrncpy(buf, "", size); return (strlen(buf)); } /* * Returns the ASCII name of the digest type. * Returns: ASCII name of digest type. */ const char *crypto_digest_name(crypto_digest_t type) { switch (type) { case CRYPTO_DIGEST_MD5: return "MD5"; case CRYPTO_DIGEST_SHA1: return "SHA1"; case CRYPTO_DIGEST_SHA256: return "SHA256"; case CRYPTO_DIGEST_SHA512: return "SHA512"; case CRYPTO_DIGEST_NONE: return "None"; default: return "Invalid Digest Type"; } } /* * Given a stream type, returns the associated * crypto_digest_t value. */ crypto_digest_t crypto_digest_stream_type(int stream) { switch (stream) { case STREAM_MD5_DIGEST: return CRYPTO_DIGEST_MD5; case STREAM_SHA1_DIGEST: return CRYPTO_DIGEST_SHA1; case STREAM_SHA256_DIGEST: return CRYPTO_DIGEST_SHA256; case STREAM_SHA512_DIGEST: return CRYPTO_DIGEST_SHA512; default: return CRYPTO_DIGEST_NONE; } } /* * * Given a crypto_error_t value, return the associated * * error string * */ const char *crypto_strerror(crypto_error_t error) { switch (error) { case CRYPTO_ERROR_NONE: return _("No error"); case CRYPTO_ERROR_NOSIGNER: return _("Signer not found"); case CRYPTO_ERROR_NORECIPIENT: return _("Recipient not found"); case CRYPTO_ERROR_INVALID_DIGEST: return _("Unsupported digest algorithm"); case CRYPTO_ERROR_INVALID_CRYPTO: return _("Unsupported encryption algorithm"); case CRYPTO_ERROR_BAD_SIGNATURE: return _("Signature is invalid"); case CRYPTO_ERROR_DECRYPTION: return _("Decryption error"); case CRYPTO_ERROR_INTERNAL: /* This shouldn't happen */ return _("Internal error"); default: return _("Unknown error"); } } bareos-Release-14.2.6/src/lib/crypto.h000066400000000000000000000070761263011562700175000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto.h Encryption support functions * * Author: Landon Fuller */ #ifndef __CRYPTO_H_ #define __CRYPTO_H_ /* Opaque X509 Public/Private Key Pair Structure */ typedef struct X509_Keypair X509_KEYPAIR; /* Opaque Message Digest Structure */ /* Digest is defined (twice) in crypto.c */ typedef struct Digest DIGEST; /* Opaque Message Signature Structure */ typedef struct Signature SIGNATURE; /* Opaque PKI Symmetric Key Data Structure */ typedef struct Crypto_Session CRYPTO_SESSION; /* Opaque Encryption/Decryption Context Structure */ typedef struct Cipher_Context CIPHER_CONTEXT; /* PEM Decryption Passphrase Callback */ typedef int (CRYPTO_PEM_PASSWD_CB) (char *buf, int size, const void *userdata); /* Digest Types */ typedef enum { /* These are stored on disk and MUST NOT change */ CRYPTO_DIGEST_NONE = 0, CRYPTO_DIGEST_MD5 = 1, CRYPTO_DIGEST_SHA1 = 2, CRYPTO_DIGEST_SHA256 = 3, CRYPTO_DIGEST_SHA512 = 4 } crypto_digest_t; /* Cipher Types */ typedef enum { /* These are not stored on disk */ CRYPTO_CIPHER_AES_128_CBC, CRYPTO_CIPHER_AES_192_CBC, CRYPTO_CIPHER_AES_256_CBC, CRYPTO_CIPHER_CAMELLIA_128_CBC, CRYPTO_CIPHER_CAMELLIA_192_CBC, CRYPTO_CIPHER_CAMELLIA_256_CBC, CRYPTO_CIPHER_AES_128_CBC_HMAC_SHA1, CRYPTO_CIPHER_AES_256_CBC_HMAC_SHA1, CRYPTO_CIPHER_BLOWFISH_CBC } crypto_cipher_t; /* Crypto API Errors */ typedef enum { CRYPTO_ERROR_NONE = 0, /* No error */ CRYPTO_ERROR_NOSIGNER = 1, /* Signer not found */ CRYPTO_ERROR_NORECIPIENT = 2, /* Recipient not found */ CRYPTO_ERROR_INVALID_DIGEST = 3, /* Unsupported digest algorithm */ CRYPTO_ERROR_INVALID_CRYPTO = 4, /* Unsupported encryption algorithm */ CRYPTO_ERROR_BAD_SIGNATURE = 5, /* Signature is invalid */ CRYPTO_ERROR_DECRYPTION = 6, /* Decryption error */ CRYPTO_ERROR_INTERNAL = 7 /* Internal Error */ } crypto_error_t; /* Message Digest Sizes */ #define CRYPTO_DIGEST_MD5_SIZE 16 /* 128 bits */ #define CRYPTO_DIGEST_SHA1_SIZE 20 /* 160 bits */ #define CRYPTO_DIGEST_SHA256_SIZE 32 /* 256 bits */ #define CRYPTO_DIGEST_SHA512_SIZE 64 /* 512 bits */ /* Maximum Message Digest Size */ #ifdef HAVE_OPENSSL #define CRYPTO_DIGEST_MAX_SIZE 64 #define CRYPTO_CIPHER_MAX_BLOCK_SIZE 32 #else /* HAVE_OPENSSL */ /* * This must be kept in sync with the available message digest algorithms. * Just in case someone forgets, I've added assertions * to crypto_digest_finalize(). * MD5: 128 bits * SHA-1: 160 bits */ #ifndef HAVE_SHA2 #define CRYPTO_DIGEST_MAX_SIZE CRYPTO_DIGEST_SHA1_SIZE #else #define CRYPTO_DIGEST_MAX_SIZE CRYPTO_DIGEST_SHA512_SIZE #endif /* Dummy Value */ #define CRYPTO_CIPHER_MAX_BLOCK_SIZE 0 #endif /* HAVE_OPENSSL */ #endif /* __CRYPTO_H_ */ bareos-Release-14.2.6/src/lib/crypto_cache.c000066400000000000000000000244441263011562700206140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto_cache.c Encryption key caching functions * * Marco van Wieringen, April 2012 */ #include "bareos.h" #include "crypto_cache.h" static pthread_mutex_t crypto_cache_lock = PTHREAD_MUTEX_INITIALIZER; static dlist *cached_crypto_keys = NULL; static s_crypto_cache_hdr crypto_cache_hdr = { "BAREOS Crypto Cache\n", 1, 0 }; /* * Read the content of the crypto cache from the filesystem. */ void read_crypto_cache(const char *cache_file) { int fd, cnt; ssize_t status; bool ok = false; s_crypto_cache_hdr hdr; int hdr_size = sizeof(hdr); crypto_cache_entry_t *cce = NULL; if ((fd = open(cache_file, O_RDONLY|O_BINARY)) < 0) { berrno be; Dmsg2(010, "Could not open crypto cache file. %s ERR=%s\n", cache_file, be.bstrerror()); goto bail_out; } if ((status = read(fd, &hdr, hdr_size)) != hdr_size) { berrno be; Dmsg4(010, "Could not read crypto cache file. fd=%d status=%d size=%d: ERR=%s\n", fd, (int)status, hdr_size, be.bstrerror()); goto bail_out; } if (hdr.version != crypto_cache_hdr.version) { Dmsg2(010, "Crypto cache bad hdr version. Wanted %d got %d\n", crypto_cache_hdr.version, hdr.version); goto bail_out; } hdr.id[20] = 0; if (!bstrcmp(hdr.id, crypto_cache_hdr.id)) { Dmsg0(000, "Crypto cache file header id invalid.\n"); goto bail_out; } if (!cached_crypto_keys) { cached_crypto_keys = New(dlist(cce, &cce->link)); } /* * Read as many crypto cache entries as available. */ cnt = 0; cce = (crypto_cache_entry_t *)malloc(sizeof(crypto_cache_entry_t)); while (read(fd, cce, sizeof(crypto_cache_entry_t)) == sizeof(crypto_cache_entry_t)) { cnt++; cached_crypto_keys->append(cce); cce = (crypto_cache_entry_t *)malloc(sizeof(crypto_cache_entry_t)); } /* * We always allocate a dangling crypto_cache_entry_t structure in * the way that we malloc before the loop and in the loop. So drop * the last unused entry. */ free(cce); /* * Check if we read the number of entries the header said are in the file. */ if (cnt == hdr.nr_entries) { ok = true; Dmsg2(010, "Crypto cache read %d entries in file %s\n", cnt, cache_file); } else { Dmsg3(000, "Crypto cache read %d entries while %d entries should be in file %s\n", cnt, hdr.nr_entries, cache_file); } bail_out: if (fd >= 0) { close(fd); } if (!ok) { unlink(cache_file); if (cached_crypto_keys) { cached_crypto_keys->destroy(); delete cached_crypto_keys; cached_crypto_keys = NULL; } } } void read_crypto_cache(const char *dir, const char *progname, int port) { POOLMEM *fname = get_pool_memory(PM_FNAME); Mmsg(&fname, "%s/%s.%d.cryptoc", dir, progname, port); read_crypto_cache(fname); free_pool_memory(fname); } /* * Write the content of the crypto cache to the filesystem. */ void write_crypto_cache(const char *cache_file) { int fd; bool ok = false; crypto_cache_entry_t *cce; if (!cached_crypto_keys) { return; } /* * Lock the cache. */ P(crypto_cache_lock); unlink(cache_file); if ((fd = open(cache_file, O_CREAT | O_WRONLY | O_BINARY, 0640)) < 0) { berrno be; Dmsg2(000, "Could not create crypto cache file. %s ERR=%s\n", cache_file, be.bstrerror()); Emsg2(M_ERROR, 0, _("Could not create crypto cache file. %s ERR=%s\n"), cache_file, be.bstrerror()); goto bail_out; } crypto_cache_hdr.nr_entries = cached_crypto_keys->size(); if (write(fd, &crypto_cache_hdr, sizeof(crypto_cache_hdr)) != sizeof(crypto_cache_hdr)) { berrno be; Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror()); goto bail_out; } foreach_dlist(cce, cached_crypto_keys) { if (write(fd, cce, sizeof(crypto_cache_entry_t)) != sizeof(crypto_cache_entry_t)) { berrno be; Dmsg1(000, "Write record error: ERR=%s\n", be.bstrerror()); goto bail_out; } } ok = true; bail_out: if (fd >= 0) { close(fd); } if (!ok) { unlink(cache_file); } V(crypto_cache_lock); } void write_crypto_cache(const char *dir, const char *progname, int port) { POOLMEM *fname = get_pool_memory(PM_FNAME); Mmsg(&fname, "%s/%s.%d.cryptoc", dir, progname, port); write_crypto_cache(fname); free_pool_memory(fname); } /* * Update the internal cache with new data. When the cache gets * modified by a new entry or by expiring old data the return * value gives an indication of that. * Returns: true - cache was updated with new data. * false - cache was not updated with new data. */ bool update_crypto_cache(const char *VolumeName, const char *EncryptionKey) { time_t now; bool found; bool retval = false; crypto_cache_entry_t *cce = NULL; crypto_cache_entry_t *next_cce; /* * Lock the cache. */ P(crypto_cache_lock); /* * See if there are any cached encryption keys. */ if (!cached_crypto_keys) { cached_crypto_keys = New(dlist(cce, &cce->link)); cce = (crypto_cache_entry_t *)malloc(sizeof(crypto_cache_entry_t)); bstrncpy(cce->VolumeName, VolumeName, sizeof(cce->VolumeName)); bstrncpy(cce->EncryptionKey, EncryptionKey, sizeof(cce->EncryptionKey)); cce->added = time(NULL); cached_crypto_keys->append(cce); retval = true; } else { found = false; now = time(NULL); cce = (crypto_cache_entry_t *)cached_crypto_keys->first(); while (cce) { next_cce = (crypto_cache_entry_t *)cached_crypto_keys->next(cce); if (bstrcmp(cce->VolumeName, VolumeName)) { found = true; /* * If the key changed update the cached entry. */ if (!bstrcmp(cce->EncryptionKey, EncryptionKey)) { bstrncpy(cce->EncryptionKey, EncryptionKey, sizeof(cce->EncryptionKey)); retval = true; } cce->added = time(NULL); cce = next_cce; continue; } /* * Validate the entry. * Any entry older the CRYPTO_CACHE_MAX_AGE seconds is removed. */ if ((cce->added + CRYPTO_CACHE_MAX_AGE) < now) { cached_crypto_keys->remove(cce); retval = true; } cce = next_cce; } /* * New entry. */ if (!found) { cce = (crypto_cache_entry_t *)malloc(sizeof(crypto_cache_entry_t)); bstrncpy(cce->VolumeName, VolumeName, sizeof(cce->VolumeName)); bstrncpy(cce->EncryptionKey, EncryptionKey, sizeof(cce->EncryptionKey)); cce->added = time(NULL); cached_crypto_keys->append(cce); retval = true; } } V(crypto_cache_lock); return retval; } /* * Lookup a cache entry for the given VolumeName. * Returns: string dupped encryption key must be freed by caller. */ char *lookup_crypto_cache_entry(const char *VolumeName) { crypto_cache_entry_t *cce; if (!cached_crypto_keys) { return NULL; } /* * Lock the cache. */ P(crypto_cache_lock); foreach_dlist(cce, cached_crypto_keys) { if (bstrcmp(cce->VolumeName, VolumeName)) { V(crypto_cache_lock); return bstrdup(cce->EncryptionKey); } } V(crypto_cache_lock); return NULL; } /* * Dump the content of the crypto cache to a filedescriptor. */ void dump_crypto_cache(int fd) { int len; POOL_MEM msg(PM_MESSAGE); crypto_cache_entry_t *cce; char dt1[MAX_TIME_LENGTH], dt2[MAX_TIME_LENGTH]; unsigned int max_vol_length, max_key_length; if (!cached_crypto_keys) { return; } /* * Lock the cache. */ P(crypto_cache_lock); /* * See how long the biggest volumename and key are. */ max_vol_length = strlen(_("Volumename")); max_key_length = strlen(_("EncryptionKey")); foreach_dlist(cce, cached_crypto_keys) { if (strlen(cce->VolumeName) > max_vol_length) { max_vol_length = strlen(cce->VolumeName); } if (strlen(cce->EncryptionKey) > max_key_length) { max_key_length = strlen(cce->EncryptionKey); } } len = Mmsg(msg, "%-*s %-*s %-20s %-20s\n", max_vol_length, _("Volumename"), max_key_length, _("EncryptionKey"), _("Added"), _("Expires")); write(fd, msg.c_str(), len); foreach_dlist(cce, cached_crypto_keys) { bstrutime(dt1, sizeof(dt1), cce->added); bstrutime(dt2, sizeof(dt2), cce->added + CRYPTO_CACHE_MAX_AGE); len = Mmsg(msg, "%-*s %-*s %-20s %-20s\n", max_vol_length, cce->VolumeName, max_key_length, cce->EncryptionKey, dt1, dt2); write(fd, msg.c_str(), len); } V(crypto_cache_lock); } /* * Reset all entries in the cache to the current time. */ void reset_crypto_cache(void) { time_t now; crypto_cache_entry_t *cce; if (!cached_crypto_keys) { return; } now = time(NULL); /* * Lock the cache. */ P(crypto_cache_lock); foreach_dlist(cce, cached_crypto_keys) { cce->added = now; } V(crypto_cache_lock); } /* * Flush the date from the internal cache. */ void flush_crypto_cache(void) { if (!cached_crypto_keys) { return; } /* * Lock the cache. */ P(crypto_cache_lock); cached_crypto_keys->destroy(); delete cached_crypto_keys; cached_crypto_keys = NULL; V(crypto_cache_lock); } bareos-Release-14.2.6/src/lib/crypto_cache.h000066400000000000000000000033561263011562700206200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, April 2012 */ #ifndef _CRYPTO_CACHE_H #define _CRYPTO_CACHE_H 1 #define CRYPTO_CACHE_MAX_AGE 60 * 60 * 24 * 60 /* 60 Days */ struct s_crypto_cache_hdr { char id[21]; int32_t version; int32_t nr_entries; }; struct crypto_cache_entry_t { dlink link; char VolumeName[MAX_NAME_LENGTH]; char EncryptionKey[MAX_NAME_LENGTH]; utime_t added; }; void read_crypto_cache(const char *dir, const char *progname, int port); void read_crypto_cache(const char *cache_file); void write_crypto_cache(const char *dir, const char *progname, int port); void write_crypto_cache(const char *cache_file); bool update_crypto_cache(const char *VolumeName, const char *EncryptionKey); char *lookup_crypto_cache_entry(const char *VolumeName); void dump_crypto_cache(int fd); void reset_crypto_cache(void); void flush_crypto_cache(void); #endif /* _CRYPTO_CACHE_H */ bareos-Release-14.2.6/src/lib/crypto_gnutls.c000066400000000000000000000135571263011562700210700ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto_gnutls.c Encryption support functions when GNUTLS backend. * * Author: Marco van Wieringen */ #include "bareos.h" #if defined(HAVE_GNUTLS) #include "jcr.h" #include #include #if defined(HAVE_CRYPTO) #include /* Message Digest Structure */ struct Digest { crypto_digest_t type; JCR *jcr; union { SHA1_CTX sha1; MD5_CTX md5; }; }; /* Dummy Signature Structure */ struct Signature { JCR *jcr; }; DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type) { DIGEST *digest; digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; digest->jcr = jcr; switch (type) { case CRYPTO_DIGEST_MD5: MD5_Init(&digest->md5); break; case CRYPTO_DIGEST_SHA1: SHA1Init(&digest->sha1); break; default: Jmsg1(jcr, M_ERROR, 0, _("Unsupported digest type=%d specified\n"), type); free(digest); return NULL; } return (digest); } bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Doesn't return anything ... */ MD5_Update(&digest->md5, (unsigned char *) data, length); return true; case CRYPTO_DIGEST_SHA1: /* Doesn't return anything ... */ SHA1Update(&digest->sha1, (const u_int8_t *) data, (unsigned int)length); return true; default: return false; } } bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Guard against programmer error by either the API client or * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */ assert(*length >= CRYPTO_DIGEST_MD5_SIZE); *length = CRYPTO_DIGEST_MD5_SIZE; /* Doesn't return anything ... */ MD5_Final((unsigned char *)dest, &digest->md5); return true; case CRYPTO_DIGEST_SHA1: /* Guard against programmer error by either the API client or * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */ assert(*length >= CRYPTO_DIGEST_SHA1_SIZE); *length = CRYPTO_DIGEST_SHA1_SIZE; SHA1Final((u_int8_t *) dest, &digest->sha1); return true; default: return false; } return false; } void crypto_digest_free(DIGEST *digest) { free(digest); } SIGNATURE *crypto_sign_new(JCR *jcr) { return NULL; } crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, crypto_digest_t &type, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; } crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; } int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; } int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length) { return false; } SIGNATURE *crypto_sign_decode(JCR *jcr, const uint8_t *sigData, uint32_t length) { return NULL; } void crypto_sign_free(SIGNATURE *sig) { } X509_KEYPAIR *crypto_keypair_new(void) { return NULL; } X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair) { return NULL; } int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file) { return false; } bool crypto_keypair_has_key(const char *file) { return false; } int crypto_keypair_load_key(X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { return false; } void crypto_keypair_free(X509_KEYPAIR *keypair) { } CRYPTO_SESSION *crypto_session_new(crypto_cipher_t cipher, alist *pubkeys) { return NULL; } void crypto_session_free(CRYPTO_SESSION *cs) { } bool crypto_session_encode(CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length) { return false; } crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session) { return CRYPTO_ERROR_INTERNAL; } CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { return NULL; } bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written) { return false; } bool crypto_cipher_finalize(CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written) { return false; } void crypto_cipher_free(CIPHER_CONTEXT *cipher_ctx) { } const char *crypto_digest_name(DIGEST *digest) { return crypto_digest_name(digest->type); } #endif /* HAVE_CRYPTO */ /* Are we initialized? */ static int crypto_initialized = false; int init_crypto(void) { int status; if ((status = gnutls_global_init()) != 0) { Jmsg1(NULL, M_ABORT, 0, _("Unable to init GNUTLS: ERR=%d\n"), status); } crypto_initialized = true; return status; } int cleanup_crypto(void) { /* * Ensure that we've actually been initialized; Doing this here decreases the * complexity of client's termination/cleanup code. */ if (!crypto_initialized) { return 0; } gnutls_global_deinit(); crypto_initialized = false; return 0; } #endif /* HAVE_GNUTLS */ bareos-Release-14.2.6/src/lib/crypto_none.c000066400000000000000000000127261263011562700205100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto_none.c Encryption support functions when no backend. * * Author: Landon Fuller */ #include "bareos.h" #if !defined(HAVE_CRYPTO) #include "jcr.h" #include /* Message Digest Structure */ struct Digest { crypto_digest_t type; JCR *jcr; union { SHA1_CTX sha1; MD5_CTX md5; }; }; /* Dummy Signature Structure */ struct Signature { JCR *jcr; }; DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type) { DIGEST *digest; digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; digest->jcr = jcr; switch (type) { case CRYPTO_DIGEST_MD5: MD5_Init(&digest->md5); break; case CRYPTO_DIGEST_SHA1: SHA1Init(&digest->sha1); break; default: Jmsg1(jcr, M_ERROR, 0, _("Unsupported digest type=%d specified\n"), type); free(digest); return NULL; } return (digest); } bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Doesn't return anything ... */ MD5_Update(&digest->md5, (unsigned char *) data, length); return true; case CRYPTO_DIGEST_SHA1: /* Doesn't return anything ... */ SHA1Update(&digest->sha1, (const u_int8_t *) data, (unsigned int)length); return true; default: return false; } } bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Guard against programmer error by either the API client or * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */ assert(*length >= CRYPTO_DIGEST_MD5_SIZE); *length = CRYPTO_DIGEST_MD5_SIZE; /* Doesn't return anything ... */ MD5_Final((unsigned char *)dest, &digest->md5); return true; case CRYPTO_DIGEST_SHA1: /* Guard against programmer error by either the API client or * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */ assert(*length >= CRYPTO_DIGEST_SHA1_SIZE); *length = CRYPTO_DIGEST_SHA1_SIZE; SHA1Final((u_int8_t *) dest, &digest->sha1); return true; default: return false; } return false; } void crypto_digest_free(DIGEST *digest) { free(digest); } SIGNATURE *crypto_sign_new(JCR *jcr) { return NULL; } crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, crypto_digest_t &type, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; } crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; } int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; } int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length) { return false; } SIGNATURE *crypto_sign_decode(JCR *jcr, const uint8_t *sigData, uint32_t length) { return NULL; } void crypto_sign_free(SIGNATURE *sig) { } X509_KEYPAIR *crypto_keypair_new(void) { return NULL; } X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair) { return NULL; } int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file) { return false; } bool crypto_keypair_has_key(const char *file) { return false; } int crypto_keypair_load_key(X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { return false; } void crypto_keypair_free(X509_KEYPAIR *keypair) { } CRYPTO_SESSION *crypto_session_new(crypto_cipher_t cipher, alist *pubkeys) { return NULL; } void crypto_session_free(CRYPTO_SESSION *cs) { } bool crypto_session_encode(CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length) { return false; } crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session) { return CRYPTO_ERROR_INTERNAL; } CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { return NULL; } bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written) { return false; } bool crypto_cipher_finalize(CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written) { return false; } void crypto_cipher_free(CIPHER_CONTEXT *cipher_ctx) { } const char *crypto_digest_name(DIGEST *digest) { return crypto_digest_name(digest->type); } #endif /* HAVE_CRYPTO */ #if !defined(HAVE_OPENSSL) && \ !defined(HAVE_GNUTLS) && \ !defined(HAVE_NSS) /* * Dummy initialization functions when no crypto framework found. */ int init_crypto(void) { return 0; } int cleanup_crypto(void) { return 0; } #endif /* !HAVE_OPENSSL && !HAVE_GNUTLS && !HAVE_NSS */ bareos-Release-14.2.6/src/lib/crypto_nss.c000066400000000000000000000124531263011562700203510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto_nss.c Encryption support functions when Mozilla NSS backend. * * Author: Marco van Wieringen */ #include "bareos.h" #if defined(HAVE_NSS) #if defined(HAVE_CRYPTO) #include "jcr.h" #include /* Message Digest Structure */ struct Digest { crypto_digest_t type; JCR *jcr; union { SHA1_CTX sha1; MD5_CTX md5; }; }; /* Dummy Signature Structure */ struct Signature { JCR *jcr; }; DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type) { DIGEST *digest; digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; digest->jcr = jcr; switch (type) { case CRYPTO_DIGEST_MD5: MD5_Init(&digest->md5); break; case CRYPTO_DIGEST_SHA1: SHA1Init(&digest->sha1); break; default: Jmsg1(jcr, M_ERROR, 0, _("Unsupported digest type=%d specified\n"), type); free(digest); return NULL; } return (digest); } bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Doesn't return anything ... */ MD5_Update(&digest->md5, (unsigned char *) data, length); return true; case CRYPTO_DIGEST_SHA1: /* Doesn't return anything ... */ SHA1Update(&digest->sha1, (const u_int8_t *) data, (unsigned int)length); return true; default: return false; } } bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Guard against programmer error by either the API client or * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */ assert(*length >= CRYPTO_DIGEST_MD5_SIZE); *length = CRYPTO_DIGEST_MD5_SIZE; /* Doesn't return anything ... */ MD5_Final((unsigned char *)dest, &digest->md5); return true; case CRYPTO_DIGEST_SHA1: /* Guard against programmer error by either the API client or * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */ assert(*length >= CRYPTO_DIGEST_SHA1_SIZE); *length = CRYPTO_DIGEST_SHA1_SIZE; SHA1Final((u_int8_t *) dest, &digest->sha1); return true; default: return false; } return false; } void crypto_digest_free(DIGEST *digest) { free(digest); } SIGNATURE *crypto_sign_new(JCR *jcr) { return NULL; } crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, crypto_digest_t &type, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; } crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; } int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; } int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length) { return false; } SIGNATURE *crypto_sign_decode(JCR *jcr, const uint8_t *sigData, uint32_t length) { return NULL; } void crypto_sign_free(SIGNATURE *sig) { } X509_KEYPAIR *crypto_keypair_new(void) { return NULL; } X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair) { return NULL; } int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file) { return false; } bool crypto_keypair_has_key(const char *file) { return false; } int crypto_keypair_load_key(X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { return false; } void crypto_keypair_free(X509_KEYPAIR *keypair) { } CRYPTO_SESSION *crypto_session_new(crypto_cipher_t cipher, alist *pubkeys) { return NULL; } void crypto_session_free(CRYPTO_SESSION *cs) { } bool crypto_session_encode(CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length) { return false; } crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session) { return CRYPTO_ERROR_INTERNAL; } CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { return NULL; } bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written) { return false; } bool crypto_cipher_finalize(CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written) { return false; } void crypto_cipher_free(CIPHER_CONTEXT *cipher_ctx) { } const char *crypto_digest_name(DIGEST *digest) { return crypto_digest_name(digest->type); } #endif /* HAVE_CRYPTO */ int init_crypto(void) { return 0; } int cleanup_crypto(void) { return 0; } #endif /* HAVE_NSS */ bareos-Release-14.2.6/src/lib/crypto_openssl.c000066400000000000000000001403101263011562700212230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto_openssl.c Encryption support functions when OPENSSL backend. * * Author: Landon Fuller */ #include "bareos.h" #if defined(HAVE_OPENSSL) #include #include #if defined(HAVE_CRYPTO) #include "jcr.h" #include #include #include #include #include #include #include /* * For OpenSSL version 1.x, EVP_PKEY_encrypt no longer exists. It was not an official API. */ #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) #define EVP_PKEY_encrypt EVP_PKEY_encrypt_old #define EVP_PKEY_decrypt EVP_PKEY_decrypt_old #endif /* * Sanity checks. * * Various places in the bareos source code define arrays of size * CRYPTO_DIGEST_MAX_SIZE. Make sure this is large enough for all EVP digest * routines supported by openssl. */ #if (EVP_MAX_MD_SIZE > CRYPTO_DIGEST_MAX_SIZE) #error "EVP_MAX_MD_SIZE > CRYPTO_DIGEST_MAX_SIZE, please update src/lib/crypto.h" #endif #if (EVP_MAX_BLOCK_LENGTH != CRYPTO_CIPHER_MAX_BLOCK_SIZE) #error "EVP_MAX_BLOCK_LENGTH != CRYPTO_CIPHER_MAX_BLOCK_SIZE, please update src/lib/crypto.h" #endif /* ASN.1 Declarations */ #define BAREOS_ASN1_VERSION 0 typedef struct { ASN1_INTEGER *version; ASN1_OCTET_STRING *subjectKeyIdentifier; ASN1_OBJECT *digestAlgorithm; ASN1_OBJECT *signatureAlgorithm; ASN1_OCTET_STRING *signature; } SignerInfo; typedef struct { ASN1_INTEGER *version; ASN1_OCTET_STRING *subjectKeyIdentifier; ASN1_OBJECT *keyEncryptionAlgorithm; ASN1_OCTET_STRING *encryptedKey; } RecipientInfo; ASN1_SEQUENCE(SignerInfo) = { ASN1_SIMPLE(SignerInfo, version, ASN1_INTEGER), ASN1_SIMPLE(SignerInfo, subjectKeyIdentifier, ASN1_OCTET_STRING), ASN1_SIMPLE(SignerInfo, digestAlgorithm, ASN1_OBJECT), ASN1_SIMPLE(SignerInfo, signatureAlgorithm, ASN1_OBJECT), ASN1_SIMPLE(SignerInfo, signature, ASN1_OCTET_STRING) } ASN1_SEQUENCE_END(SignerInfo); ASN1_SEQUENCE(RecipientInfo) = { ASN1_SIMPLE(RecipientInfo, version, ASN1_INTEGER), ASN1_SIMPLE(RecipientInfo, subjectKeyIdentifier, ASN1_OCTET_STRING), ASN1_SIMPLE(RecipientInfo, keyEncryptionAlgorithm, ASN1_OBJECT), ASN1_SIMPLE(RecipientInfo, encryptedKey, ASN1_OCTET_STRING), } ASN1_SEQUENCE_END(RecipientInfo); typedef struct { ASN1_INTEGER *version; STACK_OF(SignerInfo) *signerInfo; } SignatureData; typedef struct { ASN1_INTEGER *version; ASN1_OBJECT *contentEncryptionAlgorithm; ASN1_OCTET_STRING *iv; STACK_OF(RecipientInfo) *recipientInfo; } CryptoData; ASN1_SEQUENCE(SignatureData) = { ASN1_SIMPLE(SignatureData, version, ASN1_INTEGER), ASN1_SET_OF(SignatureData, signerInfo, SignerInfo), } ASN1_SEQUENCE_END(SignatureData); ASN1_SEQUENCE(CryptoData) = { ASN1_SIMPLE(CryptoData, version, ASN1_INTEGER), ASN1_SIMPLE(CryptoData, contentEncryptionAlgorithm, ASN1_OBJECT), ASN1_SIMPLE(CryptoData, iv, ASN1_OCTET_STRING), ASN1_SET_OF(CryptoData, recipientInfo, RecipientInfo) } ASN1_SEQUENCE_END(CryptoData); IMPLEMENT_ASN1_FUNCTIONS(SignerInfo) IMPLEMENT_ASN1_FUNCTIONS(RecipientInfo) IMPLEMENT_ASN1_FUNCTIONS(SignatureData) IMPLEMENT_ASN1_FUNCTIONS(CryptoData) IMPLEMENT_STACK_OF(SignerInfo) IMPLEMENT_STACK_OF(RecipientInfo) /* * SignerInfo and RecipientInfo stack macros, generated by OpenSSL's util/mkstack.pl. */ #define sk_SignerInfo_new(st) SKM_sk_new(SignerInfo, (st)) #define sk_SignerInfo_new_null() SKM_sk_new_null(SignerInfo) #define sk_SignerInfo_free(st) SKM_sk_free(SignerInfo, (st)) #define sk_SignerInfo_num(st) SKM_sk_num(SignerInfo, (st)) #define sk_SignerInfo_value(st, i) SKM_sk_value(SignerInfo, (st), (i)) #define sk_SignerInfo_set(st, i, val) SKM_sk_set(SignerInfo, (st), (i), (val)) #define sk_SignerInfo_zero(st) SKM_sk_zero(SignerInfo, (st)) #define sk_SignerInfo_push(st, val) SKM_sk_push(SignerInfo, (st), (val)) #define sk_SignerInfo_unshift(st, val) SKM_sk_unshift(SignerInfo, (st), (val)) #define sk_SignerInfo_find(st, val) SKM_sk_find(SignerInfo, (st), (val)) #define sk_SignerInfo_delete(st, i) SKM_sk_delete(SignerInfo, (st), (i)) #define sk_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(SignerInfo, (st), (ptr)) #define sk_SignerInfo_insert(st, val, i) SKM_sk_insert(SignerInfo, (st), (val), (i)) #define sk_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SignerInfo, (st), (cmp)) #define sk_SignerInfo_dup(st) SKM_sk_dup(SignerInfo, st) #define sk_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(SignerInfo, (st), (free_func)) #define sk_SignerInfo_shift(st) SKM_sk_shift(SignerInfo, (st)) #define sk_SignerInfo_pop(st) SKM_sk_pop(SignerInfo, (st)) #define sk_SignerInfo_sort(st) SKM_sk_sort(SignerInfo, (st)) #define sk_SignerInfo_is_sorted(st) SKM_sk_is_sorted(SignerInfo, (st)) #define d2i_ASN1_SET_OF_SignerInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ SKM_ASN1_SET_OF_d2i(SignerInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) #define i2d_ASN1_SET_OF_SignerInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \ SKM_ASN1_SET_OF_i2d(SignerInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) #define ASN1_seq_pack_SignerInfo(st, i2d_func, buf, len) \ SKM_ASN1_seq_pack(SignerInfo, (st), (i2d_func), (buf), (len)) #define ASN1_seq_unpack_SignerInfo(buf, len, d2i_func, free_func) \ SKM_ASN1_seq_unpack(SignerInfo, (buf), (len), (d2i_func), (free_func)) #define sk_RecipientInfo_new(st) SKM_sk_new(RecipientInfo, (st)) #define sk_RecipientInfo_new_null() SKM_sk_new_null(RecipientInfo) #define sk_RecipientInfo_free(st) SKM_sk_free(RecipientInfo, (st)) #define sk_RecipientInfo_num(st) SKM_sk_num(RecipientInfo, (st)) #define sk_RecipientInfo_value(st, i) SKM_sk_value(RecipientInfo, (st), (i)) #define sk_RecipientInfo_set(st, i, val) SKM_sk_set(RecipientInfo, (st), (i), (val)) #define sk_RecipientInfo_zero(st) SKM_sk_zero(RecipientInfo, (st)) #define sk_RecipientInfo_push(st, val) SKM_sk_push(RecipientInfo, (st), (val)) #define sk_RecipientInfo_unshift(st, val) SKM_sk_unshift(RecipientInfo, (st), (val)) #define sk_RecipientInfo_find(st, val) SKM_sk_find(RecipientInfo, (st), (val)) #define sk_RecipientInfo_delete(st, i) SKM_sk_delete(RecipientInfo, (st), (i)) #define sk_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(RecipientInfo, (st), (ptr)) #define sk_RecipientInfo_insert(st, val, i) SKM_sk_insert(RecipientInfo, (st), (val), (i)) #define sk_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(RecipientInfo, (st), (cmp)) #define sk_RecipientInfo_dup(st) SKM_sk_dup(RecipientInfo, st) #define sk_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(RecipientInfo, (st), (free_func)) #define sk_RecipientInfo_shift(st) SKM_sk_shift(RecipientInfo, (st)) #define sk_RecipientInfo_pop(st) SKM_sk_pop(RecipientInfo, (st)) #define sk_RecipientInfo_sort(st) SKM_sk_sort(RecipientInfo, (st)) #define sk_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(RecipientInfo, (st)) #define d2i_ASN1_SET_OF_RecipientInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ SKM_ASN1_SET_OF_d2i(RecipientInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) #define i2d_ASN1_SET_OF_RecipientInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \ SKM_ASN1_SET_OF_i2d(RecipientInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) #define ASN1_seq_pack_RecipientInfo(st, i2d_func, buf, len) \ SKM_ASN1_seq_pack(RecipientInfo, (st), (i2d_func), (buf), (len)) #define ASN1_seq_unpack_RecipientInfo(buf, len, d2i_func, free_func) \ SKM_ASN1_seq_unpack(RecipientInfo, (buf), (len), (d2i_func), (free_func)) /* End of util/mkstack.pl block */ /* X509 Public/Private Key Pair Structure */ struct X509_Keypair { ASN1_OCTET_STRING *keyid; EVP_PKEY *pubkey; EVP_PKEY *privkey; }; /* Message Digest Structure */ struct Digest { crypto_digest_t type; JCR *jcr; EVP_MD_CTX ctx; }; /* Message Signature Structure */ struct Signature { SignatureData *sigData; JCR *jcr; }; /* Encryption Session Data */ struct Crypto_Session { CryptoData *cryptoData; /* ASN.1 Structure */ unsigned char *session_key; /* Private symmetric session key */ size_t session_key_len; /* Symmetric session key length */ }; /* Symmetric Cipher Context */ struct Cipher_Context { EVP_CIPHER_CTX ctx; }; /* PEM Password Dispatch Context */ typedef struct PEM_CB_Context { CRYPTO_PEM_PASSWD_CB *pem_callback; const void *pem_userdata; } PEM_CB_CONTEXT; /* * Extract subjectKeyIdentifier from x509 certificate. * Returns: On success, an ASN1_OCTET_STRING that must be freed via M_ASN1_OCTET_STRING_free(). * NULL on failure. */ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) { X509_EXTENSION *ext; const X509V3_EXT_METHOD *method; ASN1_OCTET_STRING *keyid; int i; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) const unsigned char *ext_value_data; #else unsigned char *ext_value_data; #endif /* Find the index to the subjectKeyIdentifier extension */ i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); if (i < 0) { /* Not found */ return NULL; } /* Grab the extension */ ext = X509_get_ext(cert, i); /* Get x509 extension method structure */ if (!(method = X509V3_EXT_get(ext))) { return NULL; } ext_value_data = ext->value->data; #if (OPENSSL_VERSION_NUMBER > 0x00907000L) if (method->it) { /* New style ASN1 */ /* Decode ASN1 item in data */ keyid = (ASN1_OCTET_STRING *) ASN1_item_d2i(NULL, &ext_value_data, ext->value->length, ASN1_ITEM_ptr(method->it)); } else { /* Old style ASN1 */ /* Decode ASN1 item in data */ keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length); } #else keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length); #endif return keyid; } /* * Create a new keypair object. * Returns: A pointer to a X509 KEYPAIR object on success. * NULL on failure. */ X509_KEYPAIR *crypto_keypair_new(void) { X509_KEYPAIR *keypair; /* Allocate our keypair structure */ keypair = (X509_KEYPAIR *)malloc(sizeof(X509_KEYPAIR)); /* Initialize our keypair structure */ keypair->keyid = NULL; keypair->pubkey = NULL; keypair->privkey = NULL; return keypair; } /* * Create a copy of a keypair object. The underlying * EVP objects are not duplicated, as no EVP_PKEY_dup() * API is available. Instead, the reference count is * incremented. */ X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair) { X509_KEYPAIR *newpair; newpair = crypto_keypair_new(); if (!newpair) { /* Allocation failed */ return NULL; } /* Increment the public key ref count */ if (keypair->pubkey) { CRYPTO_add(&(keypair->pubkey->references), 1, CRYPTO_LOCK_EVP_PKEY); newpair->pubkey = keypair->pubkey; } /* Increment the private key ref count */ if (keypair->privkey) { CRYPTO_add(&(keypair->privkey->references), 1, CRYPTO_LOCK_EVP_PKEY); newpair->privkey = keypair->privkey; } /* Duplicate the keyid */ if (keypair->keyid) { newpair->keyid = M_ASN1_OCTET_STRING_dup(keypair->keyid); if (!newpair->keyid) { /* Allocation failed */ crypto_keypair_free(newpair); return NULL; } } return newpair; } /* * Load a public key from a PEM-encoded x509 certificate. * Returns: true on success * false on failure */ int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file) { BIO *bio; X509 *cert; /* Open the file */ if (!(bio = BIO_new_file(file, "r"))) { openssl_post_errors(M_ERROR, _("Unable to open certificate file")); return false; } cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (!cert) { openssl_post_errors(M_ERROR, _("Unable to read certificate from file")); return false; } /* Extract the public key */ if (!(keypair->pubkey = X509_get_pubkey(cert))) { openssl_post_errors(M_ERROR, _("Unable to extract public key from certificate")); goto err; } /* Extract the subjectKeyIdentifier extension field */ if ((keypair->keyid = openssl_cert_keyid(cert)) == NULL) { Jmsg0(NULL, M_ERROR, 0, _("Provided certificate does not include the required subjectKeyIdentifier extension.")); goto err; } /* Validate the public key type (only RSA is supported) */ if (EVP_PKEY_type(keypair->pubkey->type) != EVP_PKEY_RSA) { Jmsg1(NULL, M_ERROR, 0, _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type)); goto err; } X509_free(cert); return true; err: X509_free(cert); if (keypair->pubkey) { EVP_PKEY_free(keypair->pubkey); } return false; } /* Dispatch user PEM encryption callbacks */ static int crypto_pem_callback_dispatch(char *buf, int size, int rwflag, void *userdata) { PEM_CB_CONTEXT *ctx = (PEM_CB_CONTEXT *) userdata; return (ctx->pem_callback(buf, size, ctx->pem_userdata)); } /* * Check a PEM-encoded file * for the existence of a private key. * Returns: true if a private key is found * false otherwise */ bool crypto_keypair_has_key(const char *file) { BIO *bio; char *name = NULL; char *header = NULL; unsigned char *data = NULL; bool retval = false; long len; if (!(bio = BIO_new_file(file, "r"))) { openssl_post_errors(M_ERROR, _("Unable to open private key file")); return false; } while (PEM_read_bio(bio, &name, &header, &data, &len)) { /* We don't care what the data is, just that it's there */ OPENSSL_free(header); OPENSSL_free(data); /* * PEM Header Found, check for a private key * Due to OpenSSL limitations, we must specifically * list supported PEM private key encodings. */ if (bstrcmp(name, PEM_STRING_RSA) || bstrcmp(name, PEM_STRING_DSA) || bstrcmp(name, PEM_STRING_PKCS8) || bstrcmp(name, PEM_STRING_PKCS8INF)) { retval = true; OPENSSL_free(name); break; } else { OPENSSL_free(name); } } /* Free our bio */ BIO_free(bio); /* Post PEM-decoding error messages, if any */ openssl_post_errors(M_ERROR, _("Unable to read private key from file")); return retval; } /* * Load a PEM-encoded private key. * Returns: true on success * false on failure */ int crypto_keypair_load_key(X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { BIO *bio; PEM_CB_CONTEXT ctx; /* Open the file */ if (!(bio = BIO_new_file(file, "r"))) { openssl_post_errors(M_ERROR, _("Unable to open private key file")); return false; } /* Set up PEM encryption callback */ if (pem_callback) { ctx.pem_callback = pem_callback; ctx.pem_userdata = pem_userdata; } else { ctx.pem_callback = crypto_default_pem_callback; ctx.pem_userdata = NULL; } keypair->privkey = PEM_read_bio_PrivateKey(bio, NULL, crypto_pem_callback_dispatch, &ctx); BIO_free(bio); if (!keypair->privkey) { openssl_post_errors(M_ERROR, _("Unable to read private key from file")); return false; } return true; } /* * Free memory associated with a keypair object. */ void crypto_keypair_free(X509_KEYPAIR *keypair) { if (keypair->pubkey) { EVP_PKEY_free(keypair->pubkey); } if (keypair->privkey) { EVP_PKEY_free(keypair->privkey); } if (keypair->keyid) { M_ASN1_OCTET_STRING_free(keypair->keyid); } free(keypair); } /* * Create a new message digest context of the specified type * Returns: A pointer to a DIGEST object on success. * NULL on failure. */ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type) { DIGEST *digest; const EVP_MD *md = NULL; /* Quell invalid uninitialized warnings */ digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; digest->jcr = jcr; Dmsg1(150, "crypto_digest_new jcr=%p\n", jcr); /* Initialize the OpenSSL message digest context */ EVP_MD_CTX_init(&digest->ctx); /* Determine the correct OpenSSL message digest type */ switch (type) { case CRYPTO_DIGEST_MD5: md = EVP_md5(); break; case CRYPTO_DIGEST_SHA1: md = EVP_sha1(); break; #ifdef HAVE_SHA2 case CRYPTO_DIGEST_SHA256: md = EVP_sha256(); break; case CRYPTO_DIGEST_SHA512: md = EVP_sha512(); break; #endif default: Jmsg1(jcr, M_ERROR, 0, _("Unsupported digest type: %d\n"), type); goto err; } /* Initialize the backing OpenSSL context */ if (EVP_DigestInit_ex(&digest->ctx, md, NULL) == 0) { goto err; } return digest; err: /* This should not happen, but never say never ... */ Dmsg0(150, "Digest init failed.\n"); openssl_post_errors(jcr, M_ERROR, _("OpenSSL digest initialization failed")); crypto_digest_free(digest); return NULL; } /* * Hash length bytes of data into the provided digest context. * Returns: true on success * false on failure */ bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) { Dmsg0(150, "digest update failed\n"); openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest update failed")); return false; } else { return true; } } /* * Finalize the data in digest, storing the result in dest and the result size * in length. The result size can be determined with crypto_digest_size(). * * Returns: true on success * false on failure */ bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) { if (!EVP_DigestFinal(&digest->ctx, dest, (unsigned int *)length)) { Dmsg0(150, "digest finalize failed\n"); openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest finalize failed")); return false; } else { return true; } } /* * Free memory associated with a digest object. */ void crypto_digest_free(DIGEST *digest) { EVP_MD_CTX_cleanup(&digest->ctx); free(digest); } /* * Create a new message signature context. * Returns: A pointer to a SIGNATURE object on success. * NULL on failure. */ SIGNATURE *crypto_sign_new(JCR *jcr) { SIGNATURE *sig; sig = (SIGNATURE *)malloc(sizeof(SIGNATURE)); if (!sig) { return NULL; } sig->sigData = SignatureData_new(); sig->jcr = jcr; Dmsg1(150, "crypto_sign_new jcr=%p\n", jcr); if (!sig->sigData) { /* Allocation failed in OpenSSL */ free(sig); return NULL; } /* Set the ASN.1 structure version number */ ASN1_INTEGER_set(sig->sigData->version, BAREOS_ASN1_VERSION); return sig; } /* * For a given public key, find the associated SignatureInfo record * and create a digest context for signature validation * * Returns: CRYPTO_ERROR_NONE on success, with the newly allocated DIGEST in digest. * A crypto_error_t value on failure. */ crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, crypto_digest_t &type, DIGEST **digest) { STACK_OF(SignerInfo) *signers; SignerInfo *si; int i; signers = sig->sigData->signerInfo; for (i = 0; i < sk_SignerInfo_num(signers); i++) { si = sk_SignerInfo_value(signers, i); if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) { /* Get the digest algorithm and allocate a digest context */ Dmsg1(150, "crypto_sign_get_digest jcr=%p\n", sig->jcr); switch (OBJ_obj2nid(si->digestAlgorithm)) { case NID_md5: Dmsg0(100, "sign digest algorithm is MD5\n"); type = CRYPTO_DIGEST_MD5; *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_MD5); break; case NID_sha1: Dmsg0(100, "sign digest algorithm is SHA1\n"); type = CRYPTO_DIGEST_SHA1; *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA1); break; #ifdef HAVE_SHA2 case NID_sha256: Dmsg0(100, "sign digest algorithm is SHA256\n"); type = CRYPTO_DIGEST_SHA256; *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA256); break; case NID_sha512: Dmsg0(100, "sign digest algorithm is SHA512\n"); type = CRYPTO_DIGEST_SHA512; *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA512); break; #endif default: type = CRYPTO_DIGEST_NONE; *digest = NULL; return CRYPTO_ERROR_INVALID_DIGEST; } /* Shouldn't happen */ if (*digest == NULL) { openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL digest_new failed")); return CRYPTO_ERROR_INVALID_DIGEST; } else { return CRYPTO_ERROR_NONE; } } else { openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL sign get digest failed")); } } return CRYPTO_ERROR_NOSIGNER; } /* * For a given signature, public key, and digest, verify the SIGNATURE. * Returns: CRYPTO_ERROR_NONE on success. * A crypto_error_t value on failure. */ crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { STACK_OF(SignerInfo) *signers; SignerInfo *si; int ok, i; unsigned int sigLen; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) const unsigned char *sigData; #else unsigned char *sigData; #endif signers = sig->sigData->signerInfo; /* Find the signer */ for (i = 0; i < sk_SignerInfo_num(signers); i++) { si = sk_SignerInfo_value(signers, i); if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) { /* Extract the signature data */ sigLen = M_ASN1_STRING_length(si->signature); sigData = M_ASN1_STRING_data(si->signature); ok = EVP_VerifyFinal(&digest->ctx, sigData, sigLen, keypair->pubkey); if (ok >= 1) { return CRYPTO_ERROR_NONE; } else if (ok == 0) { openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL digest Verify final failed")); return CRYPTO_ERROR_BAD_SIGNATURE; } else if (ok < 0) { /* Shouldn't happen */ openssl_post_errors(sig->jcr, M_ERROR, _("OpenSSL digest Verify final failed")); return CRYPTO_ERROR_INTERNAL; } } } Jmsg(sig->jcr, M_ERROR, 0, _("No signers found for crypto verify.\n")); /* Signer wasn't found. */ return CRYPTO_ERROR_NOSIGNER; } /* * Add a new signer * Returns: true on success * false on failure */ int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { SignerInfo *si = NULL; unsigned char *buf = NULL; unsigned int len; si = SignerInfo_new(); if (!si) { /* Allocation failed in OpenSSL */ return false; } /* Set the ASN.1 structure version number */ ASN1_INTEGER_set(si->version, BAREOS_ASN1_VERSION); /* Set the digest algorithm identifier */ switch (digest->type) { case CRYPTO_DIGEST_MD5: si->digestAlgorithm = OBJ_nid2obj(NID_md5); break; case CRYPTO_DIGEST_SHA1: si->digestAlgorithm = OBJ_nid2obj(NID_sha1); break; #ifdef HAVE_SHA2 case CRYPTO_DIGEST_SHA256: si->digestAlgorithm = OBJ_nid2obj(NID_sha256); break; case CRYPTO_DIGEST_SHA512: si->digestAlgorithm = OBJ_nid2obj(NID_sha512); break; #endif default: /* This should never happen */ goto err; } /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */ M_ASN1_OCTET_STRING_free(si->subjectKeyIdentifier); si->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid); /* Set our signature algorithm. We currently require RSA */ assert(EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA); /* This is slightly evil. Reach into the MD structure and grab the key type */ si->signatureAlgorithm = OBJ_nid2obj(digest->ctx.digest->pkey_type); /* Finalize/Sign our Digest */ len = EVP_PKEY_size(keypair->privkey); buf = (unsigned char *) malloc(len); if (!EVP_SignFinal(&digest->ctx, buf, &len, keypair->privkey)) { openssl_post_errors(M_ERROR, _("Signature creation failed")); goto err; } /* Add the signature to the SignerInfo structure */ if (!M_ASN1_OCTET_STRING_set(si->signature, buf, len)) { /* Allocation failed in OpenSSL */ goto err; } /* No longer needed */ free(buf); /* Push the new SignerInfo structure onto the stack */ sk_SignerInfo_push(sig->sigData->signerInfo, si); return true; err: if (si) { SignerInfo_free(si); } if (buf) { free(buf); } return false; } /* * Encodes the SignatureData structure. The length argument is used to specify the * size of dest. A length of 0 will cause no data to be written to dest, and the * required length to be written to length. The caller can then allocate sufficient * space for the output. * * Returns: true on success, stores the encoded data in dest, and the size in length. * false on failure. */ int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length) { if (*length == 0) { *length = i2d_SignatureData(sig->sigData, NULL); return true; } *length = i2d_SignatureData(sig->sigData, (unsigned char **)&dest); return true; } /* * Decodes the SignatureData structure. The length argument is used to specify the * size of sigData. * * Returns: SIGNATURE instance on success. * NULL on failure. */ SIGNATURE *crypto_sign_decode(JCR *jcr, const uint8_t *sigData, uint32_t length) { SIGNATURE *sig; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) const unsigned char *p = (const unsigned char *) sigData; #else unsigned char *p = (unsigned char *)sigData; #endif sig = (SIGNATURE *)malloc(sizeof(SIGNATURE)); if (!sig) { return NULL; } sig->jcr = jcr; /* d2i_SignatureData modifies the supplied pointer */ sig->sigData = d2i_SignatureData(NULL, &p, length); if (!sig->sigData) { /* Allocation / Decoding failed in OpenSSL */ openssl_post_errors(jcr, M_ERROR, _("Signature decoding failed")); free(sig); return NULL; } return sig; } /* * Free memory associated with a signature object. */ void crypto_sign_free(SIGNATURE *sig) { SignatureData_free(sig->sigData); free (sig); } /* * Create a new encryption session. * Returns: A pointer to a CRYPTO_SESSION object on success. * NULL on failure. * * Note! BAREOS malloc() fails if out of memory. */ CRYPTO_SESSION *crypto_session_new(crypto_cipher_t cipher, alist *pubkeys) { CRYPTO_SESSION *cs; X509_KEYPAIR *keypair; const EVP_CIPHER *ec; unsigned char *iv; int iv_len; /* Allocate our session description structures */ cs = (CRYPTO_SESSION *)malloc(sizeof(CRYPTO_SESSION)); /* Initialize required fields */ cs->session_key = NULL; /* Allocate a CryptoData structure */ cs->cryptoData = CryptoData_new(); if (!cs->cryptoData) { /* Allocation failed in OpenSSL */ free(cs); return NULL; } /* Set the ASN.1 structure version number */ ASN1_INTEGER_set(cs->cryptoData->version, BAREOS_ASN1_VERSION); /* * Acquire a cipher instance and set the ASN.1 cipher NID */ switch (cipher) { #ifndef OPENSSL_NO_AES case CRYPTO_CIPHER_AES_128_CBC: /* AES 128 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_128_cbc); ec = EVP_aes_128_cbc(); break; #ifndef HAVE_OPENSSL_EXPORT_LIBRARY #ifdef NID_aes_192_cbc case CRYPTO_CIPHER_AES_192_CBC: /* AES 192 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_192_cbc); ec = EVP_aes_192_cbc(); break; #endif #ifdef NID_aes_256_cbc case CRYPTO_CIPHER_AES_256_CBC: /* AES 256 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_256_cbc); ec = EVP_aes_256_cbc(); break; #endif #endif /* HAVE_OPENSSL_EXPORT_LIBRARY */ #endif /* OPENSSL_NO_AES */ #ifndef OPENSSL_NO_CAMELLIA #ifdef NID_camellia_128_cbc case CRYPTO_CIPHER_CAMELLIA_128_CBC: /* Camellia 128 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_camellia_128_cbc); ec = EVP_camellia_128_cbc(); break; #endif #ifndef HAVE_OPENSSL_EXPORT_LIBRARY #ifdef NID_camellia_192_cbc case CRYPTO_CIPHER_CAMELLIA_192_CBC: /* Camellia 192 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_camellia_192_cbc); ec = EVP_camellia_192_cbc(); break; #endif #ifdef NID_camellia_256_cbc case CRYPTO_CIPHER_CAMELLIA_256_CBC: /* Camellia 256 bit CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_camellia_256_cbc); ec = EVP_camellia_256_cbc(); break; #endif #endif /* OPENSSL_NO_CAMELLIA */ #endif /* HAVE_OPENSSL_EXPORT_LIBRARY */ #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) #ifdef NID_aes_128_cbc_hmac_sha1 case CRYPTO_CIPHER_AES_128_CBC_HMAC_SHA1: /* AES 128 bit CBC HMAC SHA1 */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_128_cbc_hmac_sha1); ec = EVP_aes_128_cbc_hmac_sha1(); break; #endif #ifdef NID_aes_256_cbc_hmac_sha1 case CRYPTO_CIPHER_AES_256_CBC_HMAC_SHA1: /* AES 256 bit CBC HMAC SHA1 */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_256_cbc_hmac_sha1); ec = EVP_aes_256_cbc_hmac_sha1(); break; #endif #endif /* !OPENSSL_NO_SHA && !OPENSSL_NO_SHA1 */ case CRYPTO_CIPHER_BLOWFISH_CBC: /* Blowfish CBC */ cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_bf_cbc); ec = EVP_bf_cbc(); break; default: Jmsg0(NULL, M_ERROR, 0, _("Unsupported cipher type specified\n")); crypto_session_free(cs); return NULL; } /* Generate a symmetric session key */ cs->session_key_len = EVP_CIPHER_key_length(ec); cs->session_key = (unsigned char *) malloc(cs->session_key_len); if (RAND_bytes(cs->session_key, cs->session_key_len) <= 0) { /* OpenSSL failure */ crypto_session_free(cs); return NULL; } /* Generate an IV if possible */ if ((iv_len = EVP_CIPHER_iv_length(ec))) { iv = (unsigned char *)malloc(iv_len); /* Generate random IV */ if (RAND_bytes(iv, iv_len) <= 0) { /* OpenSSL failure */ crypto_session_free(cs); free(iv); return NULL; } /* Store it in our ASN.1 structure */ if (!M_ASN1_OCTET_STRING_set(cs->cryptoData->iv, iv, iv_len)) { /* Allocation failed in OpenSSL */ crypto_session_free(cs); free(iv); return NULL; } free(iv); } /* * Create RecipientInfo structures for supplied * public keys. */ foreach_alist(keypair, pubkeys) { RecipientInfo *ri; unsigned char *ekey; int ekey_len; ri = RecipientInfo_new(); if (!ri) { /* Allocation failed in OpenSSL */ crypto_session_free(cs); return NULL; } /* Set the ASN.1 structure version number */ ASN1_INTEGER_set(ri->version, BAREOS_ASN1_VERSION); /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */ M_ASN1_OCTET_STRING_free(ri->subjectKeyIdentifier); ri->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid); /* Set our key encryption algorithm. We currently require RSA */ assert(keypair->pubkey && EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA); ri->keyEncryptionAlgorithm = OBJ_nid2obj(NID_rsaEncryption); /* Encrypt the session key */ ekey = (unsigned char *)malloc(EVP_PKEY_size(keypair->pubkey)); if ((ekey_len = EVP_PKEY_encrypt(ekey, cs->session_key, cs->session_key_len, keypair->pubkey)) <= 0) { /* OpenSSL failure */ RecipientInfo_free(ri); crypto_session_free(cs); free(ekey); return NULL; } /* Store it in our ASN.1 structure */ if (!M_ASN1_OCTET_STRING_set(ri->encryptedKey, ekey, ekey_len)) { /* Allocation failed in OpenSSL */ RecipientInfo_free(ri); crypto_session_free(cs); free(ekey); return NULL; } /* Free the encrypted key buffer */ free(ekey); /* Push the new RecipientInfo structure onto the stack */ sk_RecipientInfo_push(cs->cryptoData->recipientInfo, ri); } return cs; } /* * Encodes the CryptoData structure. The length argument is used to specify the * size of dest. A length of 0 will cause no data to be written to dest, and the * required length to be written to length. The caller can then allocate sufficient * space for the output. * * Returns: true on success, stores the encoded data in dest, and the size in length. * false on failure. */ bool crypto_session_encode(CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length) { if (*length == 0) { *length = i2d_CryptoData(cs->cryptoData, NULL); return true; } *length = i2d_CryptoData(cs->cryptoData, &dest); return true; } /* * Decodes the CryptoData structure. The length argument is * used to specify the size of data. * * Returns: CRYPTO_SESSION instance on success. * NULL on failure. * Returns: CRYPTO_ERROR_NONE and a pointer to a newly allocated CRYPTO_SESSION structure in *session on success. * A crypto_error_t value on failure. */ crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session) { CRYPTO_SESSION *cs; X509_KEYPAIR *keypair; STACK_OF(RecipientInfo) *recipients; crypto_error_t retval = CRYPTO_ERROR_NONE; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) const unsigned char *p = (const unsigned char *)data; #else unsigned char *p = (unsigned char *)data; #endif /* bareos-fd.conf doesn't contains any key */ if (!keypairs) { return CRYPTO_ERROR_NORECIPIENT; } cs = (CRYPTO_SESSION *)malloc(sizeof(CRYPTO_SESSION)); /* Initialize required fields */ cs->session_key = NULL; /* d2i_CryptoData modifies the supplied pointer */ cs->cryptoData = d2i_CryptoData(NULL, &p, length); if (!cs->cryptoData) { /* Allocation / Decoding failed in OpenSSL */ openssl_post_errors(M_ERROR, _("CryptoData decoding failed")); retval = CRYPTO_ERROR_INTERNAL; goto err; } recipients = cs->cryptoData->recipientInfo; /* * Find a matching RecipientInfo structure for a supplied * public key */ foreach_alist(keypair, keypairs) { RecipientInfo *ri; int i; /* Private key available? */ if (keypair->privkey == NULL) { continue; } for (i = 0; i < sk_RecipientInfo_num(recipients); i++) { ri = sk_RecipientInfo_value(recipients, i); /* Match against the subjectKeyIdentifier */ if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, ri->subjectKeyIdentifier) == 0) { /* Match found, extract symmetric encryption session data */ /* RSA is required. */ assert(EVP_PKEY_type(keypair->privkey->type) == EVP_PKEY_RSA); /* If we recieve a RecipientInfo structure that does not use * RSA, return an error */ if (OBJ_obj2nid(ri->keyEncryptionAlgorithm) != NID_rsaEncryption) { retval = CRYPTO_ERROR_INVALID_CRYPTO; goto err; } /* Decrypt the session key */ /* Allocate sufficient space for the largest possible decrypted data */ cs->session_key = (unsigned char *)malloc(EVP_PKEY_size(keypair->privkey)); cs->session_key_len = EVP_PKEY_decrypt(cs->session_key, M_ASN1_STRING_data(ri->encryptedKey), M_ASN1_STRING_length(ri->encryptedKey), keypair->privkey); if (cs->session_key_len <= 0) { openssl_post_errors(M_ERROR, _("Failure decrypting the session key")); retval = CRYPTO_ERROR_DECRYPTION; goto err; } /* Session key successfully extracted, return the CRYPTO_SESSION structure */ *session = cs; return CRYPTO_ERROR_NONE; } } } /* No matching recipient found */ return CRYPTO_ERROR_NORECIPIENT; err: crypto_session_free(cs); return retval; } /* * Free memory associated with a crypto session object. */ void crypto_session_free(CRYPTO_SESSION *cs) { if (cs->cryptoData) { CryptoData_free(cs->cryptoData); } if (cs->session_key){ free(cs->session_key); } free(cs); } /* * Create a new crypto cipher context with the specified session object * Returns: A pointer to a CIPHER_CONTEXT object on success. The cipher block size is returned in blocksize. * NULL on failure. */ CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { CIPHER_CONTEXT *cipher_ctx; const EVP_CIPHER *ec; cipher_ctx = (CIPHER_CONTEXT *)malloc(sizeof(CIPHER_CONTEXT)); /* * Acquire a cipher instance for the given ASN.1 cipher NID */ if ((ec = EVP_get_cipherbyobj(cs->cryptoData->contentEncryptionAlgorithm)) == NULL) { Jmsg1(NULL, M_ERROR, 0, _("Unsupported contentEncryptionAlgorithm: %d\n"), OBJ_obj2nid(cs->cryptoData->contentEncryptionAlgorithm)); free(cipher_ctx); return NULL; } /* Initialize the OpenSSL cipher context */ EVP_CIPHER_CTX_init(&cipher_ctx->ctx); if (encrypt) { /* Initialize for encryption */ if (!EVP_CipherInit_ex(&cipher_ctx->ctx, ec, NULL, NULL, NULL, 1)) { openssl_post_errors(M_ERROR, _("OpenSSL cipher context initialization failed")); goto err; } } else { /* Initialize for decryption */ if (!EVP_CipherInit_ex(&cipher_ctx->ctx, ec, NULL, NULL, NULL, 0)) { openssl_post_errors(M_ERROR, _("OpenSSL cipher context initialization failed")); goto err; } } /* Set the key size */ if (!EVP_CIPHER_CTX_set_key_length(&cipher_ctx->ctx, cs->session_key_len)) { openssl_post_errors(M_ERROR, _("Encryption session provided an invalid symmetric key")); goto err; } /* Validate the IV length */ if (EVP_CIPHER_iv_length(ec) != M_ASN1_STRING_length(cs->cryptoData->iv)) { openssl_post_errors(M_ERROR, _("Encryption session provided an invalid IV")); goto err; } /* Add the key and IV to the cipher context */ if (!EVP_CipherInit_ex(&cipher_ctx->ctx, NULL, NULL, cs->session_key, M_ASN1_STRING_data(cs->cryptoData->iv), -1)) { openssl_post_errors(M_ERROR, _("OpenSSL cipher context key/IV initialization failed")); goto err; } *blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx->ctx); return cipher_ctx; err: crypto_cipher_free(cipher_ctx); return NULL; } /* * Encrypt/Decrypt length bytes of data using the provided cipher context * Returns: true on success, number of bytes output in written * false on failure */ bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written) { if (!EVP_CipherUpdate(&cipher_ctx->ctx, (unsigned char *)dest, (int *)written, (const unsigned char *)data, length)) { /* This really shouldn't fail */ return false; } else { return true; } } /* * Finalize the cipher context, writing any remaining data and necessary padding * to dest, and the size in written. * The result size will either be one block of data or zero. * * Returns: true on success * false on failure */ bool crypto_cipher_finalize(CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written) { if (!EVP_CipherFinal_ex(&cipher_ctx->ctx, (unsigned char *)dest, (int *) written)) { /* This really shouldn't fail */ return false; } else { return true; } } /* * Free memory associated with a cipher context. */ void crypto_cipher_free(CIPHER_CONTEXT *cipher_ctx) { EVP_CIPHER_CTX_cleanup(&cipher_ctx->ctx); free (cipher_ctx); } const char *crypto_digest_name(DIGEST *digest) { return crypto_digest_name(digest->type); } #endif /* HAVE_CRYPTO */ /* * Generic OpenSSL routines used for both TLS and CRYPTO support. */ /* Are we initialized? */ static int crypto_initialized = false; /* * Perform global initialization of OpenSSL * This function is not thread safe. * Returns: 0 on success * errno on failure */ int init_crypto(void) { int status; if ((status = openssl_init_threads()) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("Unable to init OpenSSL threading: ERR=%s\n"), be.bstrerror(status)); } /* Load libssl and libcrypto human-readable error strings */ SSL_load_error_strings(); /* Initialize OpenSSL SSL library */ SSL_library_init(); /* Register OpenSSL ciphers and digests */ OpenSSL_add_all_algorithms(); if (!openssl_seed_prng()) { Jmsg0(NULL, M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n")); } #ifdef HAVE_ENGINE_LOAD_PK11 /* * FIXME: Until https://www.illumos.org/issues/1667 is solved. */ ENGINE_load_pk11(); #else /* * Load all the builtin engines. */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); #endif crypto_initialized = true; return status; } /* * Perform global cleanup of OpenSSL * All cryptographic operations must be completed before calling this function. * This function is not thread safe. * Returns: 0 on success * errno on failure */ int cleanup_crypto(void) { /* * Ensure that we've actually been initialized; Doing this here decreases the * complexity of client's termination/cleanup code. */ if (!crypto_initialized) { return 0; } #ifndef HAVE_SUN_OS /* FIXME: Until https://www.illumos.org/issues/1667 is solved. */ /* * Cleanup the builtin engines. */ ENGINE_cleanup(); #endif if (!openssl_save_prng()) { Jmsg0(NULL, M_ERROR, 0, _("Failed to save OpenSSL PRNG\n")); } openssl_cleanup_threads(); /* Free libssl and libcrypto error strings */ ERR_free_strings(); /* Free all ciphers and digests */ EVP_cleanup(); /* Free memory used by PRNG */ RAND_cleanup(); crypto_initialized = false; return 0; } /* Array of mutexes for use with OpenSSL static locking */ static pthread_mutex_t *mutexes; /* OpenSSL dynamic locking structure */ struct CRYPTO_dynlock_value { pthread_mutex_t mutex; }; /* * ***FIXME*** this is a sort of dummy to avoid having to * change all the existing code to pass either a jcr or * a NULL. Passing a NULL causes the messages to be * printed by the daemon -- not very good :-( */ void openssl_post_errors(int code, const char *errstring) { openssl_post_errors(NULL, code, errstring); } /* * Post all per-thread openssl errors */ void openssl_post_errors(JCR *jcr, int code, const char *errstring) { char buf[512]; unsigned long sslerr; /* Pop errors off of the per-thread queue */ while((sslerr = ERR_get_error()) != 0) { /* Acquire the human readable string */ ERR_error_string_n(sslerr, buf, sizeof(buf)); Dmsg3(50, "jcr=%p %s: ERR=%s\n", jcr, errstring, buf); Qmsg2(jcr, M_ERROR, 0, "%s: ERR=%s\n", errstring, buf); } } /* * Return an OpenSSL thread ID * Returns: thread ID * */ static unsigned long get_openssl_thread_id(void) { #ifdef HAVE_WIN32 return (unsigned long)getpid(); #else /* * Comparison without use of pthread_equal() is mandated by the OpenSSL API * * Note: this creates problems with the new Win32 pthreads * emulation code, which defines pthread_t as a structure. */ return ((unsigned long)pthread_self()); #endif } /* * Allocate a dynamic OpenSSL mutex */ static struct CRYPTO_dynlock_value *openssl_create_dynamic_mutex (const char *file, int line) { struct CRYPTO_dynlock_value *dynlock; int status; dynlock = (struct CRYPTO_dynlock_value *)malloc(sizeof(struct CRYPTO_dynlock_value)); if ((status = pthread_mutex_init(&dynlock->mutex, NULL)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(status)); } return dynlock; } static void openssl_update_dynamic_mutex(int mode, struct CRYPTO_dynlock_value *dynlock, const char *file, int line) { if (mode & CRYPTO_LOCK) { P(dynlock->mutex); } else { V(dynlock->mutex); } } static void openssl_destroy_dynamic_mutex(struct CRYPTO_dynlock_value *dynlock, const char *file, int line) { int status; if ((status = pthread_mutex_destroy(&dynlock->mutex)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("Unable to destroy mutex: ERR=%s\n"), be.bstrerror(status)); } free(dynlock); } /* * (Un)Lock a static OpenSSL mutex */ static void openssl_update_static_mutex (int mode, int i, const char *file, int line) { if (mode & CRYPTO_LOCK) { P(mutexes[i]); } else { V(mutexes[i]); } } /* * Initialize OpenSSL thread support * Returns: 0 on success * errno on failure */ int openssl_init_threads (void) { int i, numlocks; int status; /* Set thread ID callback */ CRYPTO_set_id_callback(get_openssl_thread_id); /* Initialize static locking */ numlocks = CRYPTO_num_locks(); mutexes = (pthread_mutex_t *) malloc(numlocks * sizeof(pthread_mutex_t)); for (i = 0; i < numlocks; i++) { if ((status = pthread_mutex_init(&mutexes[i], NULL)) != 0) { berrno be; Jmsg1(NULL, M_FATAL, 0, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(status)); return status; } } /* Set static locking callback */ CRYPTO_set_locking_callback(openssl_update_static_mutex); /* Initialize dyanmic locking */ CRYPTO_set_dynlock_create_callback(openssl_create_dynamic_mutex); CRYPTO_set_dynlock_lock_callback(openssl_update_dynamic_mutex); CRYPTO_set_dynlock_destroy_callback(openssl_destroy_dynamic_mutex); return 0; } /* * Clean up OpenSSL threading support */ void openssl_cleanup_threads(void) { int i, numlocks; int status; /* Unset thread ID callback */ CRYPTO_set_id_callback(NULL); /* Deallocate static lock mutexes */ numlocks = CRYPTO_num_locks(); for (i = 0; i < numlocks; i++) { if ((status = pthread_mutex_destroy(&mutexes[i])) != 0) { berrno be; switch (status) { case EPERM: /* No need to report errors when we get an EPERM */ break; default: /* We don't halt execution, reporting the error should be sufficient */ Jmsg2(NULL, M_ERROR, 0, _("Unable to destroy mutex: %d ERR=%s\n"), status, be.bstrerror(status)); break; } } } /* Unset static locking callback */ CRYPTO_set_locking_callback(NULL); /* Free static lock array */ free(mutexes); /* Unset dynamic locking callbacks */ CRYPTO_set_dynlock_create_callback(NULL); CRYPTO_set_dynlock_lock_callback(NULL); CRYPTO_set_dynlock_destroy_callback(NULL); } /* * Seed OpenSSL PRNG * Returns: 1 on success * 0 on failure */ int openssl_seed_prng (void) { const char *names[] = { "/dev/urandom", "/dev/random", NULL }; int i; // ***FIXME*** // Win32 Support // Read saved entropy? for (i = 0; names[i]; i++) { if (RAND_load_file(names[i], 1024) != -1) { /* Success */ return 1; } } /* Fail */ return 0; } /* * Save OpenSSL Entropy * Returns: 1 on success * 0 on failure */ int openssl_save_prng (void) { // ***FIXME*** // Implement PRNG state save return 1; } #endif /* HAVE_OPENSSL */ bareos-Release-14.2.6/src/lib/crypto_wrap.c000066400000000000000000000132211263011562700205110ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * crypto_wrap.c Encryption key wrapping support functions * * crypto_wrap.c was based on sample code used in multiple * other projects and has the following copyright: * * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394) * * Copyright (c) 2003-2004, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * Adapted to BAREOS by Marco van Wieringen, March 2012 */ #include "bareos.h" #if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) #ifdef HAVE_OPENSSL #include #endif #ifdef HAVE_GNUTLS #include #include #endif /* * @kek: key encryption key (KEK) * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes * @plain: plaintext key to be wrapped, n * 64 bit * @cipher: wrapped key, (n + 1) * 64 bit */ void aes_wrap(uint8_t *kek, int n, uint8_t *plain, uint8_t *cipher) { uint8_t *a, *r, b[16]; int i, j; #ifdef HAVE_OPENSSL AES_KEY key; #endif #ifdef HAVE_GNUTLS gnutls_cipher_hd_t key; gnutls_datum_t key_data; #endif a = cipher; r = cipher + 8; /* * 1) Initialize variables. */ memset(a, 0xa6, 8); memcpy(r, plain, 8 * n); #ifdef HAVE_OPENSSL AES_set_encrypt_key(kek, 128, &key); #endif #ifdef HAVE_GNUTLS key_data.data = kek; key_data.size = strlen((char *)kek); gnutls_cipher_init(&key, GNUTLS_CIPHER_AES_128_CBC, &key_data, NULL); #endif /* * 2) Calculate intermediate values. * For j = 0 to 5 * For i=1 to n * B = AES(K, A | R[i]) * A = MSB(64, B) ^ t where t = (n*j)+i * R[i] = LSB(64, B) */ for (j = 0; j <= 5; j++) { r = cipher + 8; for (i = 1; i <= n; i++) { memcpy(b, a, 8); memcpy(b + 8, r, 8); #ifdef HAVE_OPENSSL AES_encrypt(b, b, &key); #endif #ifdef HAVE_GNUTLS gnutls_cipher_encrypt(key, b, sizeof(b)); #endif memcpy(a, b, 8); a[7] ^= n * j + i; memcpy(r, b + 8, 8); r += 8; } } /* 3) Output the results. * * These are already in @cipher due to the location of temporary * variables. */ #ifdef HAVE_GNUTLS gnutls_cipher_deinit(key); #endif } /* * @kek: key encryption key (KEK) * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit * @plain: plaintext key, n * 64 bit */ int aes_unwrap(uint8_t *kek, int n, uint8_t *cipher, uint8_t *plain) { uint8_t a[8], *r, b[16]; int i, j; #ifdef HAVE_OPENSSL AES_KEY key; #endif #ifdef HAVE_GNUTLS gnutls_cipher_hd_t key; gnutls_datum_t key_data; #endif /* * 1) Initialize variables. */ memcpy(a, cipher, 8); r = plain; memcpy(r, cipher + 8, 8 * n); #ifdef HAVE_OPENSSL AES_set_decrypt_key(kek, 128, &key); #endif #ifdef HAVE_GNUTLS key_data.data = kek; key_data.size = strlen((char *)kek); gnutls_cipher_init(&key, GNUTLS_CIPHER_AES_128_CBC, &key_data, NULL); #endif /* * 2) Compute intermediate values. * For j = 5 to 0 * For i = n to 1 * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i * A = MSB(64, B) * R[i] = LSB(64, B) */ for (j = 5; j >= 0; j--) { r = plain + (n - 1) * 8; for (i = n; i >= 1; i--) { memcpy(b, a, 8); b[7] ^= n * j + i; memcpy(b + 8, r, 8); #ifdef HAVE_OPENSSL AES_decrypt(b, b, &key); #endif #ifdef HAVE_GNUTLS gnutls_cipher_decrypt(key, b, sizeof(b)); #endif memcpy(a, b, 8); memcpy(r, b + 8, 8); r -= 8; } } /* * 3) Output results. * * These are already in @plain due to the location of temporary * variables. Just verify that the IV matches with the expected value. */ for (i = 0; i < 8; i++) { if (a[i] != 0xa6) { return -1; } } #ifdef HAVE_GNUTLS gnutls_cipher_deinit(key); #endif return 0; } #else /* * @kek: key encryption key (KEK) * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes * @plain: plaintext key to be wrapped, n * 64 bit * @cipher: wrapped key, (n + 1) * 64 bit */ void aes_wrap(uint8_t *kek, int n, uint8_t *plain, uint8_t *cipher) { memcpy(cipher, plain, n * 8); } /* * @kek: key encryption key (KEK) * @n: length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes * @cipher: wrapped key to be unwrapped, (n + 1) * 64 bit * @plain: plaintext key, n * 64 bit */ int aes_unwrap(uint8_t *kek, int n, uint8_t *cipher, uint8_t *plain) { memcpy(cipher, plain, n * 8); return 0; } #endif /* HAVE_OPENSSL || HAVE_GNUTLS */ bareos-Release-14.2.6/src/lib/daemon.c000066400000000000000000000063021263011562700174050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * daemon.c by Kern Sibbald 2000 * * This code is inspired by the Prentice Hall book * "Unix Network Programming" by W. Richard Stevens * and later updated from his book "Advanced Programming * in the UNIX Environment" * * Initialize a daemon process completely detaching us from * any terminal processes. */ #include "bareos.h" extern int debug_level; void daemon_start() { #if !defined(HAVE_WIN32) int i; int fd; pid_t cpid; mode_t oldmask; #ifdef DEVELOPER int low_fd = 2; #else int low_fd = -1; #endif /* * Become a daemon. */ Dmsg0(900, "Enter daemon_start\n"); if ( (cpid = fork() ) < 0) { berrno be; Emsg1(M_ABORT, 0, _("Cannot fork to become daemon: ERR=%s\n"), be.bstrerror()); } else if (cpid > 0) { exit(0); /* parent exits */ } /* Child continues */ setsid(); /* In the PRODUCTION system, we close ALL * file descriptors except stdin, stdout, and stderr. */ if (debug_level > 0) { low_fd = 2; /* don't close debug output */ } #if defined(HAVE_FCNTL_F_CLOSEM) /* * fcntl(fd, F_CLOSEM) needs the lowest filedescriptor * to close. the current code sets the last one to keep * open. So increment it with 1 and use that as argument. */ low_fd++; fcntl(low_fd, F_CLOSEM); #elif defined(HAVE_CLOSEFROM) /* * closefrom needs the lowest filedescriptor to close. * the current code sets the last one to keep open. * So increment it with 1 and use that as argument. */ low_fd++; closefrom(low_fd); #else for (i=sysconf(_SC_OPEN_MAX)-1; i > low_fd; i--) { close(i); } #endif /* Move to root directory. For debug we stay * in current directory so dumps go there. */ #ifndef DEBUG chdir("/"); #endif /* * Avoid creating files 666 but don't override any * more restrictive mask set by the user. */ oldmask = umask(026); oldmask |= 026; umask(oldmask); /* * Make sure we have fd's 0, 1, 2 open * If we don't do this one of our sockets may open * there and if we then use stdout, it could * send total garbage to our socket. * */ fd = open("/dev/null", O_RDONLY, 0644); if (fd > 2) { close(fd); } else { for(i=1; fd + i <= 2; i++) { dup2(fd, fd+i); } } #endif /* HAVE_WIN32 */ Dmsg0(900, "Exit daemon_start\n"); } bareos-Release-14.2.6/src/lib/devlock.c000066400000000000000000000466521263011562700176050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Thread Read/Write locking code. It permits * multiple readers but only one writer. Note, however, * that the writer thread is permitted to make multiple * nested write lock calls. * * Kern Sibbald, January MMI * * This code adapted from "Programming with POSIX Threads", by * David R. Butenhof */ #define _LOCKMGR_COMPLIANT #include "bareos.h" #include "devlock.h" /* * Initialize a read/write lock * * Returns: 0 on success * errno on failure */ devlock *new_devlock() { devlock *lock; lock = (devlock *)malloc(sizeof (devlock)); memset(lock, 0, sizeof(devlock)); return lock; } int devlock::init(int initial_priority) { int status; devlock *rwl = this; rwl->r_active = rwl->w_active = 0; rwl->r_wait = rwl->w_wait = 0; rwl->priority = initial_priority; if ((status = pthread_mutex_init(&rwl->mutex, NULL)) != 0) { return status; } if ((status = pthread_cond_init(&rwl->read, NULL)) != 0) { pthread_mutex_destroy(&rwl->mutex); return status; } if ((status = pthread_cond_init(&rwl->write, NULL)) != 0) { pthread_cond_destroy(&rwl->read); pthread_mutex_destroy(&rwl->mutex); return status; } rwl->valid = DEVLOCK_VALID; return 0; } /* * Destroy a read/write lock * * Returns: 0 on success * errno on failure */ int devlock::destroy() { devlock *rwl = this; int status, status1, status2; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } /* * If any threads are active, report EBUSY */ if (rwl->r_active > 0 || rwl->w_active) { pthread_mutex_unlock(&rwl->mutex); return EBUSY; } /* * If any threads are waiting, report EBUSY */ if (rwl->r_wait > 0 || rwl->w_wait > 0) { pthread_mutex_unlock(&rwl->mutex); return EBUSY; } rwl->valid = 0; if ((status = pthread_mutex_unlock(&rwl->mutex)) != 0) { return status; } status = pthread_mutex_destroy(&rwl->mutex); status1 = pthread_cond_destroy(&rwl->read); status2 = pthread_cond_destroy(&rwl->write); return (status != 0 ? status : (status1 != 0 ? status1 : status2)); } /* * Handle cleanup when the read lock condition variable * wait is released. */ static void devlock_read_release(void *arg) { devlock *rwl = (devlock *)arg; rwl->read_release(); } void devlock::read_release() { r_wait--; pthread_mutex_unlock(&mutex); } /* * Handle cleanup when the write lock condition variable wait * is released. */ static void devlock_write_release(void *arg) { devlock *rwl = (devlock *)arg; rwl->write_release(); } void devlock::write_release() { w_wait--; pthread_mutex_unlock(&mutex); } /* * Lock for read access, wait until locked (or error). */ int devlock::readlock() { devlock *rwl = this; int status; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active) { rwl->r_wait++; /* indicate that we are waiting */ pthread_cleanup_push(devlock_read_release, (void *)rwl); while (rwl->w_active) { status = pthread_cond_wait(&rwl->read, &rwl->mutex); if (status != 0) { break; /* error, bail out */ } } pthread_cleanup_pop(0); rwl->r_wait--; /* we are no longer waiting */ } if (status == 0) { rwl->r_active++; /* we are running */ } pthread_mutex_unlock(&rwl->mutex); return status; } /* * Attempt to lock for read access, don't wait */ int devlock::readtrylock() { devlock *rwl = this; int status, status2; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active) { status = EBUSY; } else { rwl->r_active++; /* we are running */ } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } /* * Unlock read lock */ int devlock::readunlock() { devlock *rwl = this; int status, status2; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } rwl->r_active--; if (rwl->r_active == 0 && rwl->w_wait > 0) { /* if writers waiting */ status = pthread_cond_broadcast(&rwl->write); } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } /* * Lock for write access, wait until locked (or error). * Multiple nested write locking is permitted. */ int devlock::writelock(int areason, bool acan_take) { devlock *rwl = this; int status; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active && pthread_equal(rwl->writer_id, pthread_self())) { rwl->w_active++; pthread_mutex_unlock(&rwl->mutex); return 0; } lmgr_pre_lock(rwl, rwl->priority, __FILE__, __LINE__); if (rwl->w_active || rwl->r_active > 0) { rwl->w_wait++; /* indicate that we are waiting */ pthread_cleanup_push(devlock_write_release, (void *)rwl); while (rwl->w_active || rwl->r_active > 0) { if ((status = pthread_cond_wait(&rwl->write, &rwl->mutex)) != 0) { lmgr_do_unlock(rwl); break; /* error, bail out */ } } pthread_cleanup_pop(0); rwl->w_wait--; /* we are no longer waiting */ } if (status == 0) { rwl->w_active++; /* we are running */ rwl->writer_id = pthread_self(); /* save writer thread's id */ lmgr_post_lock(); } rwl->reason = areason; rwl->can_take = acan_take; pthread_mutex_unlock(&rwl->mutex); return status; } /* * Attempt to lock for write access, don't wait */ int devlock::writetrylock() { devlock *rwl = this; int status, status2; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active && pthread_equal(rwl->writer_id, pthread_self())) { rwl->w_active++; pthread_mutex_unlock(&rwl->mutex); return 0; } if (rwl->w_active || rwl->r_active > 0) { status = EBUSY; } else { rwl->w_active = 1; /* we are running */ rwl->writer_id = pthread_self(); /* save writer thread's id */ lmgr_do_lock(rwl, rwl->priority, __FILE__, __LINE__); } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } /* * Unlock write lock * Start any waiting writers in preference to waiting readers */ int devlock::writeunlock() { devlock *rwl = this; int status, status2; if (rwl->valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active <= 0) { pthread_mutex_unlock(&rwl->mutex); Jmsg0(NULL, M_ABORT, 0, _("writeunlock called too many times.\n")); } rwl->w_active--; if (!pthread_equal(pthread_self(), rwl->writer_id)) { pthread_mutex_unlock(&rwl->mutex); Jmsg0(NULL, M_ABORT, 0, _("writeunlock by non-owner.\n")); } if (rwl->w_active > 0) { status = 0; /* writers still active */ } else { lmgr_do_unlock(rwl); /* No more writers, awaken someone */ if (rwl->r_wait > 0) { /* if readers waiting */ status = pthread_cond_broadcast(&rwl->read); } else if (rwl->w_wait > 0) { status = pthread_cond_broadcast(&rwl->write); } } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } int devlock::take_lock(take_lock_t *hold, int areason) { int status; if (valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&mutex)) != 0) { return status; } hold->reason = reason; hold->prev_reason = prev_reason; hold->writer_id = writer_id; reason = areason; writer_id = pthread_self(); status = pthread_mutex_unlock(&mutex); return status; } int devlock::return_lock(take_lock_t *hold) { int status, status2; if (valid != DEVLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&mutex)) != 0) { return status; } reason = hold->reason; prev_reason = hold->prev_reason; writer_id = hold->writer_id; writer_id = pthread_self(); status2 = pthread_mutex_unlock(&mutex); if (w_active || w_wait) { status = pthread_cond_broadcast(&write); } return (status == 0 ? status2 : status); } #ifdef TEST_RWLOCK #define THREADS 300 #define DATASIZE 15 #define ITERATIONS 1000000 /* * Keep statics for each thread. */ typedef struct thread_tag { int thread_num; pthread_t thread_id; int writes; int reads; int interval; } thread_t; /* * Read/write lock and shared data. */ typedef struct data_tag { brwlock_t lock; int data; int writes; } data_t; static thread_t threads[THREADS]; static data_t data[DATASIZE]; /* * Thread start routine that uses read/write locks. */ void *thread_routine(void *arg) { thread_t *self = (thread_t *)arg; int repeats = 0; int iteration; int element = 0; int status; for (iteration=0; iteration < ITERATIONS; iteration++) { /* * Each "self->interval" iterations, perform an * update operation (write lock instead of read * lock). */ // if ((iteration % self->interval) == 0) { status = writelock(&data[element].lock); if (status != 0) { berrno be; printf("Write lock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } data[element].data = self->thread_num; data[element].writes++; self->writes++; status = writelock(&data[element].lock); if (status != 0) { berrno be; printf("Write lock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } data[element].data = self->thread_num; data[element].writes++; self->writes++; status = writeunlock(&data[element].lock); if (status != 0) { berrno be; printf("Write unlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } status = writeunlock(&data[element].lock); if (status != 0) { berrno be; printf("Write unlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } #ifdef xxx } else { /* * Look at the current data element to see whether * the current thread last updated it. Count the * times to report later. */ status = readlock(&data[element].lock); if (status != 0) { berrno be; printf("Read lock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } self->reads++; if (data[element].data == self->thread_num) repeats++; status = readunlock(&data[element].lock); if (status != 0) { berrno be; printf("Read unlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } } #endif element++; if (element >= DATASIZE) { element = 0; } } if (repeats > 0) { Pmsg2(000, _("Thread %d found unchanged elements %d times\n"), self->thread_num, repeats); } return NULL; } int main (int argc, char *argv[]) { int count; int data_count; int status; unsigned int seed = 1; int thread_writes = 0; int data_writes = 0; #ifdef USE_THR_SETCONCURRENCY /* * On Solaris 2.5,2.6,7 and 8 threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to THREADS. */ thr_setconcurrency (THREADS); #endif /* * Initialize the shared data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data[data_count].data = 0; data[data_count].writes = 0; status = rwl_init(&data[data_count].lock); if (status != 0) { berrno be; printf("Init rwlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } } /* * Create THREADS threads to access shared data. */ for (count = 0; count < THREADS; count++) { threads[count].thread_num = count + 1; threads[count].writes = 0; threads[count].reads = 0; threads[count].interval = rand_r(&seed) % 71; if (threads[count].interval <= 0) { threads[count].interval = 1; } status = pthread_create (&threads[count].thread_id, NULL, thread_routine, (void*)&threads[count]); if (status != 0 || (int)threads[count].thread_id == 0) { berrno be; printf("Create thread failed. ERR=%s\n", be.bstrerror(status)); exit(1); } } /* * Wait for all threads to complete, and collect * statistics. */ for (count = 0; count < THREADS; count++) { status = pthread_join (threads[count].thread_id, NULL); if (status != 0) { berrno be; printf("Join thread failed. ERR=%s\n", be.bstrerror(status)); exit(1); } thread_writes += threads[count].writes; printf (_("%02d: interval %d, writes %d, reads %d\n"), count, threads[count].interval, threads[count].writes, threads[count].reads); } /* * Collect statistics for the data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data_writes += data[data_count].writes; printf (_("data %02d: value %d, %d writes\n"), data_count, data[data_count].data, data[data_count].writes); rwl_destroy (&data[data_count].lock); } printf (_("Total: %d thread writes, %d data writes\n"), thread_writes, data_writes); return 0; } #endif #ifdef TEST_RW_TRY_LOCK /* * brwlock_try_main.c * * Demonstrate use of non-blocking read-write locks. * * Special notes: On older Solaris system, call thr_setconcurrency() * to allow interleaved thread execution, since threads are not * timesliced. */ #include #include "rwlock.h" #include "errors.h" #define THREADS 5 #define ITERATIONS 1000 #define DATASIZE 15 /* * Keep statistics for each thread. */ typedef struct thread_tag { int thread_num; pthread_t thread_id; int r_collisions; int w_collisions; int updates; int interval; } thread_t; /* * Read-write lock and shared data */ typedef struct data_tag { brwlock_t lock; int data; int updates; } data_t; thread_t threads[THREADS]; data_t data[DATASIZE]; /* * Thread start routine that uses read-write locks */ void *thread_routine (void *arg) { thread_t *self = (thread_t*)arg; int iteration; int element; int status; lmgr_init_thread(); element = 0; /* Current data element */ for (iteration = 0; iteration < ITERATIONS; iteration++) { if ((iteration % self->interval) == 0) { status = rwl_writetrylock (&data[element].lock); if (status == EBUSY) self->w_collisions++; else if (status == 0) { data[element].data++; data[element].updates++; self->updates++; rwl_writeunlock (&data[element].lock); } else err_abort (status, _("Try write lock")); } else { status = rwl_readtrylock (&data[element].lock); if (status == EBUSY) self->r_collisions++; else if (status != 0) { err_abort (status, _("Try read lock")); } else { if (data[element].data != data[element].updates) printf ("%d: data[%d] %d != %d\n", self->thread_num, element, data[element].data, data[element].updates); rwl_readunlock (&data[element].lock); } } element++; if (element >= DATASIZE) element = 0; } lmgr_cleanup_thread(); return NULL; } int main (int argc, char *argv[]) { int count, data_count; unsigned int seed = 1; int thread_updates = 0, data_updates = 0; int status; #ifdef USE_THR_SETCONCURRENCY /* * On Solaris 2.5,2.6,7 and 8 threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to THREADS. */ DPRINTF (("Setting concurrency level to %d\n", THREADS)); thr_setconcurrency (THREADS); #endif /* * Initialize the shared data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data[data_count].data = 0; data[data_count].updates = 0; rwl_init(&data[data_count].lock); } /* * Create THREADS threads to access shared data. */ for (count = 0; count < THREADS; count++) { threads[count].thread_num = count; threads[count].r_collisions = 0; threads[count].w_collisions = 0; threads[count].updates = 0; threads[count].interval = rand_r (&seed) % ITERATIONS; status = pthread_create (&threads[count].thread_id, NULL, thread_routine, (void*)&threads[count]); if (status != 0) err_abort (status, _("Create thread")); } /* * Wait for all threads to complete, and collect * statistics. */ for (count = 0; count < THREADS; count++) { status = pthread_join (threads[count].thread_id, NULL); if (status != 0) err_abort (status, _("Join thread")); thread_updates += threads[count].updates; printf (_("%02d: interval %d, updates %d, " "r_collisions %d, w_collisions %d\n"), count, threads[count].interval, threads[count].updates, threads[count].r_collisions, threads[count].w_collisions); } /* * Collect statistics for the data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data_updates += data[data_count].updates; printf (_("data %02d: value %d, %d updates\n"), data_count, data[data_count].data, data[data_count].updates); rwl_destroy (&data[data_count].lock); } return 0; } #endif bareos-Release-14.2.6/src/lib/devlock.h000066400000000000000000000054621263011562700176040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Thread Read/Write locking code. It permits * multiple readers but only one writer. * * Kern Sibbald, January MMI * * This code adapted from "Programming with POSIX Threads", by * David R. Butenhof */ #ifndef __DEVLOCK_H #define __DEVLOCK_H 1 struct take_lock_t { pthread_t writer_id; /* id of writer */ int reason; /* save reason */ int prev_reason; /* previous reason */ }; class devlock { private: pthread_mutex_t mutex; pthread_cond_t read; /* wait for read */ pthread_cond_t write; /* wait for write */ pthread_t writer_id; /* writer's thread id */ int priority; /* used in deadlock detection */ int valid; /* set when valid */ int r_active; /* readers active */ int w_active; /* writers active */ int r_wait; /* readers waiting */ int w_wait; /* writers waiting */ int reason; /* reason for lock */ int prev_reason; /* previous reason */ bool can_take; /* can the lock be taken? */ public: devlock(int reason, bool can_take=false); ~devlock(); int init(int initial_priority); int destroy(); int take_lock(take_lock_t *hold, int reason); int return_lock(take_lock_t *hold); void new_reason(int nreason) { prev_reason = reason; reason = nreason; }; void restore_reason() { reason = prev_reason; prev_reason = 0; }; int writelock(int reason, bool can_take=false); int writetrylock(); int writeunlock(); void write_release(); int readunlock(); int readlock(); int readtrylock(); void read_release(); }; #define DEVLOCK_VALID 0xfadbec #define DEVLOCK_INIIALIZER \ {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, \ PTHREAD_COND_INITIALIZER, DEVOCK_VALID, 0, 0, 0, 0} #endif /* __DEVLOCK_H */ bareos-Release-14.2.6/src/lib/dlist.c000066400000000000000000000313731263011562700172670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS doubly linked list routines. * * dlist is a doubly linked list with the links being in the list data item. * * Kern Sibbald, July MMIII */ #include "bareos.h" /* * Append an item to the list */ void dlist::append(void *item) { set_next(item, NULL); set_prev(item, tail); if (tail) { set_next(tail, item); } tail = item; if (head == NULL) { /* if empty list, */ head = item; /* item is head as well */ } num_items++; } /* * Append an item to the list */ void dlist::prepend(void *item) { set_next(item, head); set_prev(item, NULL); if (head) { set_prev(head, item); } head = item; if (tail == NULL) { /* if empty list, */ tail = item; /* item is tail too */ } num_items++; } void dlist::insert_before(void *item, void *where) { dlink *where_link = get_link(where); set_next(item, where); set_prev(item, where_link->prev); if (where_link->prev) { set_next(where_link->prev, item); } where_link->prev = item; if (head == where) { head = item; } num_items++; } void dlist::insert_after(void *item, void *where) { dlink *where_link = get_link(where); set_next(item, where_link->next); set_prev(item, where); if (where_link->next) { set_prev(where_link->next, item); } where_link->next = item; if (tail == where) { tail = item; } num_items++; } /* * Insert an item in the list, but only if it is unique * otherwise, the item is returned non inserted * * Returns: item if item inserted * other_item if same value already exists (item not inserted) */ void *dlist::binary_insert(void *item, int compare(void *item1, void *item2)) { int comp; int low, high, cur; void *cur_item; if (num_items == 0) { //Dmsg0(000, "Append first.\n"); append(item); return item; } if (num_items == 1) { comp = compare(item, first()); if (comp < 0) { prepend(item); //Dmsg0(000, "Insert before first.\n"); return item; } else if (comp > 0) { insert_after(item, first()); //Dmsg0(000, "Insert after first.\n"); return item; } else { //Dmsg0(000, "Same as first.\n"); return first(); } } /* Check against last item */ comp = compare(item, last()); if (comp > 0) { append(item); //Dmsg0(000, "Appended item.\n"); return item; } else if (comp == 0) { //Dmsg0(000, "Same as last.\n"); return last(); } /* Check against first item */ comp = compare(item, first()); if (comp < 0) { prepend(item); //Dmsg0(000, "Inserted item before.\n"); return item; } else if (comp == 0) { //Dmsg0(000, "Same as first.\n"); return first(); } if (num_items == 2) { insert_after(item, first()); //Dmsg0(000, "Inserted item after.\n"); return item; } low = 1; high = num_items; cur = 1; cur_item = first(); while (low < high) { int nxt; nxt = (low + high) / 2; while (nxt > cur) { cur_item = next(cur_item); cur++; } while (nxt < cur) { cur_item = prev(cur_item); cur--; } //Dmsg1(000, "Compare item to %d\n", cur); comp = compare(item, cur_item); //Dmsg2(000, "Compare item to %d = %d\n", cur, comp); if (comp < 0) { high = cur; //Dmsg2(000, "set high; low=%d high=%d\n", low, high); } else if (comp > 0) { low = cur + 1; //Dmsg2(000, "set low; low=%d high=%d\n", low, high); } else { //Dmsg1(000, "Same as item %d\n", cur); return cur_item; } } if (high == cur) { insert_before(item, cur_item); //Dmsg1(000, "Insert before item %d\n", cur); } else { insert_after(item, cur_item); //Dmsg1(000, "Insert after item %d\n", cur); } return item; } /* * Insert an item in the list, regardless if it is unique * or not. */ void dlist::binary_insert_multiple(void *item, int compare(void *item1, void *item2)) { void *ins_item = binary_insert(item, compare); /* If identical, insert after the one found */ if (ins_item != item) { insert_after(item, ins_item); } } /* * Search for item */ void *dlist::binary_search(void *item, int compare(void *item1, void *item2)) { int comp; int low, high, cur; void *cur_item; if (num_items == 0) { return NULL; } cur_item = first(); if (num_items == 1) { comp = compare(item, cur_item); if (comp == 0) { return cur_item; } else { return NULL; } } low = 1; high = num_items; cur = 1; cur_item = first(); while (low < high) { int nxt; nxt = (low + high) / 2; /* Now get cur pointing to nxt */ while (nxt > cur) { cur_item = next(cur_item); cur++; } while (nxt < cur) { cur_item = prev(cur_item); cur--; } comp = compare(item, cur_item); //Dmsg2(000, "Compare item to %d = %d\n", cur, comp); if (comp < 0) { high = cur; //Dmsg2(000, "set high; low=%d high=%d\n", low, high); } else if (comp > 0) { low = cur + 1; //Dmsg2(000, "set low; low=%d high=%d\n", low, high); } else { return cur_item; } } /* * low == high can only happen if low just * got incremented from cur, and we have * not yet tested cur+1 */ if (low == high) { cur_item = next(cur_item); comp = compare(item, cur_item); if (comp == 0) { return cur_item; } } return NULL; } void dlist::remove(void *item) { void *xitem; dlink *ilink = get_link(item); /* item's link */ if (item == head) { head = ilink->next; if (head) { set_prev(head, NULL); } if (item == tail) { tail = ilink->prev; } } else if (item == tail) { tail = ilink->prev; if (tail) { set_next(tail, NULL); } } else { xitem = ilink->next; set_prev(xitem, ilink->prev); xitem = ilink->prev; set_next(xitem, ilink->next); } num_items--; if (num_items == 0) { head = tail = NULL; } } void *dlist::next(void *item) { if (item == NULL) { return head; } return get_next(item); } void *dlist::prev(void *item) { if (item == NULL) { return tail; } return get_prev(item); } /* Destroy the list contents */ void dlist::destroy() { for (void *n=head; n; ) { void *ni = get_next(n); free(n); n = ni; } num_items = 0; head = tail = NULL; } /* String helpers for dlist usage */ dlistString *new_dlistString(const char *str) { return new_dlistString(str, strlen(str)); } dlistString *new_dlistString(const char *str, int len) { dlistString *node; node = (dlistString *)malloc(sizeof(dlink) + len +1); bstrncpy(node->c_str(), str, len + 1); return node; } #ifdef TEST_PROGRAM struct MYJCR { char *buf; dlink link; }; static int my_compare(void *item1, void *item2) { MYJCR *jcr1, *jcr2; int comp; jcr1 = (MYJCR *)item1; jcr2 = (MYJCR *)item2; comp = strcmp(jcr1->buf, jcr2->buf); //Dmsg3(000, "compare=%d: %s to %s\n", comp, jcr1->buf, jcr2->buf); return comp; } int main() { char buf[30]; dlist *jcr_chain; MYJCR *jcr = NULL; MYJCR *jcr1; MYJCR *save_jcr = NULL; MYJCR *next_jcr; int count; jcr_chain = (dlist *)malloc(sizeof(dlist)); jcr_chain->init(jcr, &jcr->link); printf("Prepend 20 items 0-19\n"); for (int i=0; i<20; i++) { sprintf(buf, "This is dlist item %d", i); jcr = (MYJCR *)malloc(sizeof(MYJCR)); jcr->buf = bstrdup(buf); jcr_chain->prepend(jcr); if (i == 10) { save_jcr = jcr; } } next_jcr = (MYJCR *)jcr_chain->next(save_jcr); printf("11th item=%s\n", next_jcr->buf); jcr1 = (MYJCR *)malloc(sizeof(MYJCR)); jcr1->buf = save_jcr->buf; printf("Remove 10th item\n"); jcr_chain->remove(save_jcr); free(save_jcr); printf("Re-insert 10th item\n"); jcr_chain->insert_before(jcr1, next_jcr); printf("Print remaining list.\n"); foreach_dlist(jcr, jcr_chain) { printf("Dlist item = %s\n", jcr->buf); free(jcr->buf); } jcr_chain->destroy(); free(jcr_chain); /* The following may seem a bit odd, but we create a chaing * of jcr objects. Within a jcr object, there is a buf * that points to a malloced string containing data */ jcr_chain = New(dlist(jcr, &jcr->link)); printf("append 20 items 0-19\n"); for (int i=0; i<20; i++) { sprintf(buf, "This is dlist item %d", i); jcr = (MYJCR *)malloc(sizeof(MYJCR)); jcr->buf = bstrdup(buf); jcr_chain->append(jcr); if (i == 10) { save_jcr = jcr; } } next_jcr = (MYJCR *)jcr_chain->next(save_jcr); printf("11th item=%s\n", next_jcr->buf); jcr = (MYJCR *)malloc(sizeof(MYJCR)); jcr->buf = save_jcr->buf; printf("Remove 10th item\n"); jcr_chain->remove(save_jcr); free(save_jcr); printf("Re-insert 10th item\n"); jcr_chain->insert_before(jcr, next_jcr); printf("Print remaining list.\n"); foreach_dlist (jcr, jcr_chain) { printf("Dlist item = %s\n", jcr->buf); free(jcr->buf); } delete jcr_chain; /* Now do a binary insert for the list */ jcr_chain = New(dlist(jcr, &jcr->link)); #define CNT 26 printf("append %d items\n", CNT*CNT*CNT); strcpy(buf, "ZZZ"); count = 0; for (int i=0; ibuf = bstrdup(buf); jcr1 = (MYJCR *)jcr_chain->binary_insert(jcr, my_compare); if (jcr != jcr1) { Dmsg2(000, "Insert of %s vs %s failed.\n", jcr->buf, jcr1->buf); } buf[1]--; } buf[1] = 'Z'; buf[2]--; } buf[2] = 'Z'; buf[0]--; } jcr = (MYJCR *)malloc(sizeof(MYJCR)); strcpy(buf, "a"); jcr->buf = bstrdup(buf); if (jcr_chain->binary_search(jcr, my_compare)) { printf("One less failed!!!!\n"); } else { printf("One less: OK\n"); } free(jcr->buf); strcpy(buf, "ZZZZZZZZZZZZZZZZ"); jcr->buf = bstrdup(buf); if (jcr_chain->binary_search(jcr, my_compare)) { printf("One greater failed!!!!\n"); } else { printf("One greater: OK\n"); } free(jcr->buf); free(jcr); printf("Find each of %d items in list.\n", count); foreach_dlist (jcr, jcr_chain) { if (!jcr_chain->binary_search(jcr, my_compare)) { printf("Dlist binary_search item not found = %s\n", jcr->buf); } } printf("Free each of %d items in list.\n", count); foreach_dlist (jcr, jcr_chain) { free(jcr->buf); jcr->buf = NULL; } delete jcr_chain; /* Finally, do a test using the dlistString string helper, which * allocates a dlist node and stores the string directly in * it. */ dlist chain; chain.append(new_dlistString("This is a long test line")); #define CNT 26 printf("append %d dlistString items\n", CNT*CNT*CNT); strcpy(buf, "ZZZ"); count = 0; for (int i=0; ic_str()); } printf("destroy dlistString chain\n"); chain.destroy(); sm_dump(false); /* unit test */ } #endif bareos-Release-14.2.6/src/lib/dlist.h000066400000000000000000000114411263011562700172660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Doubly linked list -- dlist * * See the end of the file for the dlistString class which * facilitates storing strings in a dlist. * * Kern Sibbald, MMIV and MMVII */ #define M_ABORT 1 /* In case you want to specifically specify the offset to the link */ #define OFFSET(item, link) (int)((char *)(link) - (char *)(item)) /* * There is a lot of extra casting here to work around the fact * that some compilers (Sun and Visual C++) do not accept * (void *) as an lvalue on the left side of an equal. * * Loop var through each member of list */ #ifdef HAVE_TYPEOF #define foreach_dlist(var, list) \ for((var)=NULL; ((var)=(typeof(var))(list)->next(var)); ) #else #define foreach_dlist(var, list) \ for((var)=NULL; (*((void **)&(var))=(void*)((list)->next(var))); ) #endif struct dlink { void *next; void *prev; }; class dlist : public SMARTALLOC { void *head; void *tail; int16_t loffset; uint32_t num_items; public: dlist(void *item, dlink *link); dlist(void); ~dlist() { destroy(); } void init(void *item, dlink *link); void init(); void prepend(void *item); void append(void *item); void set_prev(void *item, void *prev); void set_next(void *item, void *next); void *get_prev(void *item); void *get_next(void *item); dlink *get_link(void *item); void insert_before(void *item, void *where); void insert_after(void *item, void *where); void *binary_insert(void *item, int compare(void *item1, void *item2)); void *binary_search(void *item, int compare(void *item1, void *item2)); void binary_insert_multiple(void *item, int compare(void *item1, void *item2)); void remove(void *item); bool empty() const; int size() const; void *next(void *item); void *prev(void *item); void destroy(); void *first() const; void *last() const; }; /* * This allows us to do explicit initialization, * allowing us to mix C++ classes inside malloc'ed * C structures. Define before called in constructor. */ inline void dlist::init(void *item, dlink *link) { head = tail = NULL; loffset = (int)((char *)link - (char *)item); if (loffset < 0 || loffset > 5000) { Emsg0(M_ABORT, 0, "Improper dlist initialization.\n"); } num_items = 0; } inline void dlist::init() { head = tail = NULL; loffset = 0; num_items = 0; } /* * Constructor called with the address of a * member of the list (not the list head), and * the address of the link within that member. * If the link is at the beginning of the list member, * then there is no need to specify the link address * since the offset is zero. */ inline dlist::dlist(void *item, dlink *link) { init(item, link); } /* Constructor with link at head of item */ inline dlist::dlist(void) : head(0), tail(0), loffset(0), num_items(0) { } inline void dlist::set_prev(void *item, void *prev) { ((dlink *)(((char *)item)+loffset))->prev = prev; } inline void dlist::set_next(void *item, void *next) { ((dlink *)(((char *)item)+loffset))->next = next; } inline void *dlist::get_prev(void *item) { return ((dlink *)(((char *)item)+loffset))->prev; } inline void *dlist::get_next(void *item) { return ((dlink *)(((char *)item)+loffset))->next; } inline dlink *dlist::get_link(void *item) { return (dlink *)(((char *)item)+loffset); } inline bool dlist::empty() const { return head == NULL; } inline int dlist::size() const { return num_items; } inline void * dlist::first() const { return head; } inline void * dlist::last() const { return tail; } /* * C string helper routines for dlist * The string (char *) is kept in the node * * Kern Sibbald, February 2007 * */ class dlistString { public: char *c_str() { return m_str; }; private: dlink m_link; char m_str[1]; /* !!! Don't put anything after this as this space is used * to hold the string in inline */ }; extern dlistString *new_dlistString(const char *str, int len); extern dlistString *new_dlistString(const char *str); bareos-Release-14.2.6/src/lib/edit.c000066400000000000000000000324511263011562700170730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * edit.c edit string to ascii, and ascii to internal * * Kern Sibbald, December MMII */ #include "bareos.h" #include /* We assume ASCII input and don't worry about overflow */ uint64_t str_to_uint64(const char *str) { const char *p = str; uint64_t value = 0; if (!p) { return 0; } while (B_ISSPACE(*p)) { p++; } if (*p == '+') { p++; } while (B_ISDIGIT(*p)) { value = B_TIMES10(value) + *p - '0'; p++; } return value; } int64_t str_to_int64(const char *str) { const char *p = str; int64_t value; bool negative = false; if (!p) { return 0; } while (B_ISSPACE(*p)) { p++; } if (*p == '+') { p++; } else if (*p == '-') { negative = true; p++; } value = str_to_uint64(p); if (negative) { value = -value; } return value; } /* * Edit an integer number with commas, the supplied buffer * must be at least 27 bytes long. The incoming number * is always widened to 64 bits. */ char *edit_uint64_with_commas(uint64_t val, char *buf) { edit_uint64(val, buf); return add_commas(buf, buf); } /* * Edit an integer into "human-readable" format with four or fewer * significant digits followed by a suffix that indicates the scale * factor. The buf array inherits a 27 byte minimim length * requirement from edit_unit64_with_commas(), although the output * string is limited to eight characters. */ char *edit_uint64_with_suffix(uint64_t val, char *buf) { int commas = 0; char *c, mbuf[50]; const char *suffix[] = { "", "K", "M", "G", "T", "P", "E", "Z", "Y", "FIX ME" }; int suffixes = sizeof(suffix) / sizeof(*suffix); edit_uint64_with_commas(val, mbuf); if ((c = strchr(mbuf, ',')) != NULL) { commas++; *c++ = '.'; while ((c = strchr(c, ',')) != NULL) { commas++; *c++ = '\0'; } mbuf[5] = '\0'; // drop this to get '123.456 TB' rather than '123.4 TB' } if (commas >= suffixes) commas = suffixes - 1; bsnprintf(buf, 27, "%s %s", mbuf, suffix[commas]); return buf; } /* * Edit an integer number, the supplied buffer * must be at least 27 bytes long. The incoming number * is always widened to 64 bits. */ char *edit_uint64(uint64_t val, char *buf) { /* * Replacement for sprintf(buf, "%" llu, val) */ char mbuf[50]; mbuf[sizeof(mbuf)-1] = 0; int i = sizeof(mbuf)-2; /* edit backward */ if (val == 0) { mbuf[i--] = '0'; } else { while (val != 0) { mbuf[i--] = "0123456789"[val%10]; val /= 10; } } bstrncpy(buf, &mbuf[i+1], 27); return buf; } char *edit_int64(int64_t val, char *buf) { /* * Replacement for sprintf(buf, "%" llu, val) */ char mbuf[50]; bool negative = false; mbuf[sizeof(mbuf)-1] = 0; int i = sizeof(mbuf)-2; /* edit backward */ if (val == 0) { mbuf[i--] = '0'; } else { if (val < 0) { negative = true; val = -val; } while (val != 0) { mbuf[i--] = "0123456789"[val%10]; val /= 10; } } if (negative) { mbuf[i--] = '-'; } bstrncpy(buf, &mbuf[i+1], 27); return buf; } /* * Edit an integer number with commas, the supplied buffer * must be at least 27 bytes long. The incoming number * is always widened to 64 bits. */ char *edit_int64_with_commas(int64_t val, char *buf) { edit_int64(val, buf); return add_commas(buf, buf); } /* * Given a string "str", separate the numeric part into * str, and the modifier into mod. */ static bool get_modifier(char *str, char *num, int num_len, char *mod, int mod_len) { int i, len, num_begin, num_end, mod_begin, mod_end; strip_trailing_junk(str); len = strlen(str); for (i=0; i (num_end - num_begin + 1)) { num_len = num_end - num_begin + 1; } if (num_len == 0) { return false; } /* Eat any spaces in front of modifier */ for ( ; i (mod_end - mod_begin + 1)) { mod_len = mod_end - mod_begin + 1; } Dmsg5(900, "str=%s: num_beg=%d num_end=%d mod_beg=%d mod_end=%d\n", str, num_begin, num_end, mod_begin, mod_end); bstrncpy(num, &str[num_begin], num_len); bstrncpy(mod, &str[mod_begin], mod_len); if (!is_a_number(num)) { return false; } bstrncpy(str, &str[mod_end], len); Dmsg2(900, "num=%s mod=%s\n", num, mod); return true; } /* * Convert a string duration to utime_t (64 bit seconds) * Returns false: if error true: if OK, and value stored in value */ bool duration_to_utime(char *str, utime_t *value) { int i, mod_len; double val, total = 0.0; char mod_str[20]; char num_str[50]; /* * The "n" = mins and months appears before minutes so that m maps to months. */ static const char *mod[] = { "n", "seconds", "months", "minutes", "mins", "hours", "days", "weeks", "quarters", "years", (char *)NULL }; static const int32_t mult[] = { 60, 1, 60 * 60 * 24 * 30, 60, 60, 3600, 3600 * 24, 3600 * 24 * 7, 3600 * 24 * 91, 3600 * 24 * 365, 0 }; while (*str) { if (!get_modifier(str, num_str, sizeof(num_str), mod_str, sizeof(mod_str))) { return false; } /* Now find the multiplier corresponding to the modifier */ mod_len = strlen(mod_str); if (mod_len == 0) { i = 1; /* default to seconds */ } else { for (i=0; mod[i]; i++) { if (bstrncasecmp(mod_str, mod[i], mod_len)) { break; } } if (mod[i] == NULL) { return false; } } Dmsg2(900, "str=%s: mult=%d\n", num_str, mult[i]); errno = 0; val = strtod(num_str, NULL); if (errno != 0 || val < 0) { return false; } total += val * mult[i]; } *value = (utime_t)total; return true; } /* * Edit a utime "duration" into ASCII */ char *edit_utime(utime_t val, char *buf, int buf_len) { char mybuf[200]; static const int32_t mult[] = {60*60*24*365, 60*60*24*30, 60*60*24, 60*60, 60}; static const char *mod[] = {"year", "month", "day", "hour", "min"}; int i; uint32_t times; *buf = 0; for (i=0; i<5; i++) { times = (uint32_t)(val / mult[i]); if (times > 0) { val = val - (utime_t)times * mult[i]; bsnprintf(mybuf, sizeof(mybuf), "%d %s%s ", times, mod[i], times>1?"s":""); bstrncat(buf, mybuf, buf_len); } } if (val == 0 && strlen(buf) == 0) { bstrncat(buf, "0 secs", buf_len); } else if (val != 0) { bsnprintf(mybuf, sizeof(mybuf), "%d sec%s", (uint32_t)val, val>1?"s":""); bstrncat(buf, mybuf, buf_len); } return buf; } static bool strunit_to_uint64(char *str, uint64_t *value, const char **mod) { int i, mod_len; double val; char mod_str[20]; char num_str[50]; const int64_t mult[] = {1, /* byte */ 1024, /* kilobyte */ 1000, /* kb kilobyte */ 1048576, /* megabyte */ 1000000, /* mb megabyte */ 1073741824, /* gigabyte */ 1000000000}; /* gb gigabyte */ if (!get_modifier(str, num_str, sizeof(num_str), mod_str, sizeof(mod_str))) { return 0; } /* Now find the multiplier corresponding to the modifier */ mod_len = strlen(mod_str); if (mod_len == 0) { i = 0; /* default with no modifier = 1 */ } else { for (i=0; mod[i]; i++) { if (bstrncasecmp(mod_str, mod[i], mod_len)) { break; } } if (mod[i] == NULL) { return false; } } Dmsg2(900, "str=%s: mult=%d\n", str, mult[i]); errno = 0; val = strtod(num_str, NULL); if (errno != 0 || val < 0) { return false; } *value = (utime_t)(val * mult[i]); return true; } /* * Convert a size in bytes to uint64_t * Returns false: if error true: if OK, and value stored in value */ bool size_to_uint64(char *str, uint64_t *value) { /* first item * not used */ static const char *mod[] = {"*", "k", "kb", "m", "mb", "g", "gb", NULL}; return strunit_to_uint64(str, value, mod); } /* * Convert a speed in bytes/s to uint64_t * Returns false: if error true: if OK, and value stored in value */ bool speed_to_uint64(char *str, uint64_t *value) { /* first item * not used */ static const char *mod[] = {"*", "k/s", "kb/s", "m/s", "mb/s", NULL}; return strunit_to_uint64(str, value, mod); } /* * Check if specified string is a number or not. * Taken from SQLite, cool, thanks. */ bool is_a_number(const char *n) { bool digit_seen = false; if( *n == '-' || *n == '+' ) { n++; } while (B_ISDIGIT(*n)) { digit_seen = true; n++; } if (digit_seen && *n == '.') { n++; while (B_ISDIGIT(*n)) { n++; } } if (digit_seen && (*n == 'e' || *n == 'E') && (B_ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && B_ISDIGIT(n[2])))) { n += 2; /* skip e- or e+ or e digit */ while (B_ISDIGIT(*n)) { n++; } } return digit_seen && *n==0; } /* * Check if specified string is a list of numbers or not */ bool is_a_number_list(const char *n) { bool previous_digit = false; bool digit_seen = false; while (*n) { if (B_ISDIGIT(*n)) { previous_digit=true; digit_seen = true; } else if (*n == ',' && previous_digit) { previous_digit = false; } else { return false; } n++; } return digit_seen && *n==0; } /* * Check if the specified string is an integer */ bool is_an_integer(const char *n) { bool digit_seen = false; while (B_ISDIGIT(*n)) { digit_seen = true; n++; } return digit_seen && *n==0; } /* * Check if BAREOS Resoure Name is valid */ /* * Check if the Volume name has legal characters * If ua is non-NULL send the message */ bool is_name_valid(const char *name, POOLMEM **msg) { int len; const char *p; /* Special characters to accept */ const char *accept = ":.-_ "; /* No name is invalid */ if (!name) { if (msg) { Mmsg(msg, _("Empty name not allowed.\n")); } return false; } /* Restrict the characters permitted in the Volume name */ for (p=name; *p; p++) { if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) { continue; } if (msg) { Mmsg(msg, _("Illegal character \"%c\" in name.\n"), *p); } return false; } len = p - name; if (len >= MAX_NAME_LENGTH) { if (msg) { Mmsg(msg, _("Name too long.\n")); } return false; } if (len == 0) { if (msg) { Mmsg(msg, _("Volume name must be at least one character long.\n")); } return false; } return true; } /* * Add commas to a string, which is presumably * a number. */ char *add_commas(char *val, char *buf) { int len, nc; char *p, *q; int i; if (val != buf) { strcpy(buf, val); } len = strlen(buf); if (len < 1) { len = 1; } nc = (len - 1) / 3; p = buf+len; q = p + nc; *q-- = *p--; for ( ; nc; nc--) { for (i=0; i < 3; i++) { *q-- = *p--; } *q-- = ','; } return buf; } #ifdef TEST_PROGRAM void d_msg(const char*, int, int, const char*, ...) {} int main(int argc, char *argv[]) { char *str[] = {"3", "3n", "3 hours", "3.5 day", "3 week", "3 m", "3 q", "3 years"}; utime_t val; char buf[100]; char outval[100]; for (int i=0; i<8; i++) { strcpy(buf, str[i]); if (!duration_to_utime(buf, &val)) { printf("Error return from duration_to_utime for in=%s\n", str[i]); continue; } edit_utime(val, outval); printf("in=%s val=%" lld " outval=%s\n", str[i], val, outval); } } #endif bareos-Release-14.2.6/src/lib/fnmatch.c000066400000000000000000000265711263011562700175740ustar00rootroot00000000000000/* * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ /* OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert */ /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. */ /* Define SYS to use the system fnmatch() rather than ours */ /* #define SYS 1 */ #include "bareos.h" #ifdef SYS #include #else #include "fnmatch.h" #endif #undef EOS #define EOS '\0' #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) /* Limit of recursion during matching attempts. */ #define FNM_MAX_RECUR 64 #define ISSET(x, y) ((x) & (y)) #define FOLD(c) ((flags & FNM_CASEFOLD) && B_ISUPPER(c) ? tolower(c) : (c)) static int rangematch(const char *, char, int, char **); static int r_fnmatch(const char *, const char *, int, int); #ifdef SYS int xfnmatch(const char *pattern, const char *string, int flags) #else int fnmatch(const char *pattern, const char *string, int flags) #endif { int e; e = r_fnmatch(pattern, string, flags, FNM_MAX_RECUR); if (e == -1) { /* Too much recursion */ e = FNM_NOMATCH; } return (e); } static int r_fnmatch(const char *pattern, const char *string, int flags, int recur) { const char *stringstart; char *newp; char c, test; int e; if (recur-- <= 0) { return (-1); } stringstart = string; for ( ;; ) { switch (c = *pattern++) { case EOS: if (ISSET(flags, FNM_LEADING_DIR) && IsPathSeparator(*string)) return (0); return (*string == EOS ? 0 : FNM_NOMATCH); case '?': if (*string == EOS) return (FNM_NOMATCH); if (IsPathSeparator(*string) && ISSET(flags, FNM_PATHNAME)) return (FNM_NOMATCH); if (*string == '.' && ISSET(flags, FNM_PERIOD) && (string == stringstart || (ISSET(flags, FNM_PATHNAME) && IsPathSeparator(*(string - 1))))) return (FNM_NOMATCH); ++string; break; case '*': c = *pattern; /* Collapse multiple stars. */ while (c == '*') { c = *++pattern; } if (*string == '.' && ISSET(flags, FNM_PERIOD) && (string == stringstart || (ISSET(flags, FNM_PATHNAME) && IsPathSeparator(*(string - 1))))) { return (FNM_NOMATCH); } /* Optimize for pattern with * at end or before /. */ if (c == EOS) { if (ISSET(flags, FNM_PATHNAME)) { return (ISSET(flags, FNM_LEADING_DIR) || strchr(string, '/') == NULL ? 0 : FNM_NOMATCH); } else { return (0); } } else if (IsPathSeparator(c) && ISSET(flags, FNM_PATHNAME)) { if ((string = strchr(string, '/')) == NULL) return (FNM_NOMATCH); break; } /* General case, use recursion. */ while ((test = *string) != EOS) { e = r_fnmatch(pattern, string, flags & ~FNM_PERIOD, recur); if (e != FNM_NOMATCH) { /* can be NOMATCH, -1 or MATCH */ return (e); } if (test == '/' && ISSET(flags, FNM_PATHNAME)) { break; } ++string; } return (FNM_NOMATCH); case '[': if (*string == EOS) return (FNM_NOMATCH); if (IsPathSeparator(*string) && ISSET(flags, FNM_PATHNAME)) return (FNM_NOMATCH); if (*string == '.' && ISSET(flags, FNM_PERIOD) && (string == stringstart || (ISSET(flags, FNM_PATHNAME) && IsPathSeparator(*(string - 1))))) return (FNM_NOMATCH); switch (rangematch(pattern, *string, flags, &newp)) { case RANGE_ERROR: /* not a good range, treat as normal text */ goto normal; case RANGE_MATCH: pattern = newp; break; case RANGE_NOMATCH: return (FNM_NOMATCH); } ++string; break; case '\\': if (!ISSET(flags, FNM_NOESCAPE)) { if ((c = *pattern++) == EOS) { c = '\\'; --pattern; } } /* FALLTHROUGH */ default: normal: if (FOLD(c) != FOLD(*string)) { return (FNM_NOMATCH); } ++string; break; } } /* NOTREACHED */ } static int rangematch(const char *pattern, char test, int flags, char **newp) { int negate, ok; char c, c2; /* * A bracket expression starting with an unquoted circumflex * character produces unspecified results (IEEE 1003.2-1992, * 3.13.2). This implementation treats it like '!', for * consistency with the regular expression syntax. * J.T. Conklin (conklin@ngai.kaleida.com) */ if ((negate = (*pattern == '!' || *pattern == '^'))) ++pattern; test = FOLD(test); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2 */ ok = 0; c = *pattern++; do { if (c == '\\' && !ISSET(flags, FNM_NOESCAPE)) c = *pattern++; if (c == EOS) return (RANGE_ERROR); if (c == '/' && ISSET(flags, FNM_PATHNAME)) return (RANGE_NOMATCH); c = FOLD(c); if (*pattern == '-' && (c2 = *(pattern + 1)) != EOS && c2 != ']') { pattern += 2; if (c2 == '\\' && !ISSET(flags, FNM_NOESCAPE)) c2 = *pattern++; if (c2 == EOS) return (RANGE_ERROR); c2 = FOLD(c2); if (c <= test && test <= c2) ok = 1; } else if (c == test) ok = 1; } while ((c = *pattern++) != ']'); *newp = (char *) pattern; return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); } #ifdef TEST_PROGRAM struct test { const char *pattern; const char *string; const int options; const int result; }; /* * Note, some of these tests were duplicated from a patch file I found * in an email, so I am unsure what the license is. Since this code is * never turned on in any release, it probably doesn't matter at all. * If by some chance someone finds this to be a problem please let * me know. */ static struct test tests[] = { /*1*/ {"x", "x", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"x", "x/y", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"x", "x/y/z", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"*", "x", FNM_PATHNAME | FNM_LEADING_DIR, 0}, /*5*/ {"*", "x/y", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"*", "x/y/z", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"*x", "x", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"*x", "x/y", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"*x", "x/y/z", FNM_PATHNAME | FNM_LEADING_DIR, 0}, /*10*/ {"x*", "x", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"x*", "x/y", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"x*", "x/y/z", FNM_PATHNAME | FNM_LEADING_DIR, 0}, {"a*b/*", "abbb/.x", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH}, {"a*b/*", "abbb/xy", FNM_PATHNAME|FNM_PERIOD, 0}, /*15*/ {"[A-[]", "A", 0, 0}, {"[A-[]", "a", 0, FNM_NOMATCH}, {"[a-{]", "A", 0, FNM_NOMATCH}, {"[a-{]", "a", 0, 0}, {"[A-[]", "A", FNM_CASEFOLD, FNM_NOMATCH}, /*20*/ {"[A-[]", "a", FNM_CASEFOLD, FNM_NOMATCH}, {"[a-{]", "A", FNM_CASEFOLD, 0}, {"[a-{]", "a", FNM_CASEFOLD, 0}, { "*LIB*", "lib", FNM_PERIOD, FNM_NOMATCH }, { "*LIB*", "lib", FNM_CASEFOLD, 0}, /*25*/ { "a[/]b", "a/b", 0, 0}, { "a[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH }, { "[a-z]/[a-z]", "a/b", 0, 0 }, { "a/b", "*", FNM_PATHNAME, FNM_NOMATCH }, { "*", "a/b", FNM_PATHNAME, FNM_NOMATCH }, { "*[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH }, /*30*/ { "\\[/b", "[/b", 0, 0 }, { "?\?/b", "aa/b", 0, 0 }, { "???b", "aa/b", 0, 0 }, { "???b", "aa/b", FNM_PATHNAME, FNM_NOMATCH }, { "?a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, /*35*/ { "a/?b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, { "*a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, { "a/*b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, { "[.]a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, { "a/[.]b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, /*40*/ { "*/?", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, { "?/*", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, { ".*/?", ".a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, { "*/.?", "a/.b", FNM_PATHNAME|FNM_PERIOD, 0 }, { "*/*", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, /*45*/ { "*[.]/b", "a./b", FNM_PATHNAME|FNM_PERIOD, 0 }, { "a?b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, { "a*b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, { "a[.]b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, /*49*/ { "*a*", "a/b", FNM_PATHNAME|FNM_LEADING_DIR, 0 }, { "[/b", "[/b", 0, 0}, #ifdef FULL_TEST /* This test takes a *long* time */ {"a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*", "aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmm" "nnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyy", 0, FNM_NOMATCH}, #endif /* Keep dummy last to avoid compiler warnings */ {"dummy", "dummy", 0, 0} }; #define ntests ((int)(sizeof(tests)/sizeof(struct test))) int main() { bool fail = false; for (int i=0; i after Imatch. */ #define FNM_CASEFOLD 0x10 /* Case insensitive search. */ #define FNM_IGNORECASE FNM_CASEFOLD #define FNM_FILE_NAME FNM_PATHNAME extern "C" int fnmatch(const char *, const char *, int); #endif /* !_FNMATCH_H_ */ bareos-Release-14.2.6/src/lib/generic_res.h000066400000000000000000000046221263011562700204370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January MM * * Extracted from other source files by Marco van Wieringen, June 2013 */ #ifndef _GENERIC_RES_H #define _GENERIC_RES_H 1 #ifndef DIRECTOR_DAEMON /* * Various message destinations. */ static s_mdestination msg_destinations[] = { { MD_SYSLOG, "syslog", false }, { MD_MAIL, "mail", true }, { MD_FILE, "file", true }, { MD_APPEND, "append", true }, { MD_STDOUT, "stdout", false }, { MD_STDERR, "stderr", false }, { MD_DIRECTOR, "director", true }, { MD_OPERATOR, "operator", true }, { MD_CONSOLE, "console", false }, { MD_MAIL_ON_ERROR, "mailonerror", true }, { MD_MAIL_ON_SUCCESS, "mailonsuccess", true }, { MD_CATALOG, "catalog", false }, { 0, NULL } }; /* * Various message types */ static struct s_mtypes msg_types[] = { { "debug", M_DEBUG }, { "abort", M_ABORT }, { "fatal", M_FATAL }, { "error", M_ERROR }, { "warning", M_WARNING }, { "info", M_INFO }, { "saved", M_SAVED }, { "notsaved", M_NOTSAVED }, { "skipped", M_SKIPPED }, { "mount", M_MOUNT }, { "terminate", M_TERM }, { "restored", M_RESTORED }, { "security", M_SECURITY }, { "alert", M_ALERT }, { "volmgmt", M_VOLMGMT }, { "audit", M_AUDIT }, { "all", M_MAX + 1 }, { NULL, 0 } }; #endif /* DIRECTOR_DAEMON */ /* * Tape Label types permitted in Pool records * * tape_label label_code = token */ static s_kw tapelabels[] = { { "bareos", B_BAREOS_LABEL }, { "ansi", B_ANSI_LABEL }, { "ibm", B_IBM_LABEL }, { NULL, 0 } }; #endif /* _GENERIC_RES_H */ bareos-Release-14.2.6/src/lib/guid_to_name.c000066400000000000000000000113361263011562700205770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Kern Sibbald This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by Kern Sibbald, July 2007 to replace idcache.c * * Program to convert uid and gid into names, and cache the results * for preformance reasons. */ #include "bareos.h" #ifndef WIN32 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #endif struct guitem { dlink link; char *name; union { uid_t uid; gid_t gid; }; }; guid_list *new_guid_list() { guid_list *list; guitem *item = NULL; list = (guid_list *)malloc(sizeof(guid_list)); list->uid_list = New(dlist(item, &item->link)); list->gid_list = New(dlist(item, &item->link)); return list; } void free_guid_list(guid_list *list) { guitem *item; foreach_dlist(item, list->uid_list) { free(item->name); } foreach_dlist(item, list->gid_list) { free(item->name); } delete list->uid_list; delete list->gid_list; free(list); } static int uid_compare(void *item1, void *item2) { guitem *i1 = (guitem *)item1; guitem *i2 = (guitem *)item2; if (i1->uid < i2->uid) { return -1; } else if (i1->uid > i2->uid) { return 1; } else { return 0; } } static int gid_compare(void *item1, void *item2) { guitem *i1 = (guitem *)item1; guitem *i2 = (guitem *)item2; if (i1->gid < i2->gid) { return -1; } else if (i1->gid > i2->gid) { return 1; } else { return 0; } } static void get_uidname(uid_t uid, guitem *item) { #ifndef HAVE_WIN32 struct passwd *pwbuf; P(mutex); pwbuf = getpwuid(uid); if (pwbuf != NULL && !bstrcmp(pwbuf->pw_name, "????????")) { item->name = bstrdup(pwbuf->pw_name); } V(mutex); #endif } static void get_gidname(gid_t gid, guitem *item) { #ifndef HAVE_WIN32 struct group *grbuf; P(mutex); grbuf = getgrgid(gid); if (grbuf != NULL && !bstrcmp(grbuf->gr_name, "????????")) { item->name = bstrdup(grbuf->gr_name); } V(mutex); #endif } char *guid_list::uid_to_name(uid_t uid, char *name, int maxlen) { guitem sitem, *item, *fitem; sitem.uid = uid; char buf[50]; item = (guitem *)uid_list->binary_search(&sitem, uid_compare); Dmsg2(900, "uid=%d item=%p\n", uid, item); if (!item) { item = (guitem *)malloc(sizeof(guitem)); item->uid = uid; item->name = NULL; get_uidname(uid, item); if (!item->name) { item->name = bstrdup(edit_int64(uid, buf)); Dmsg2(900, "set uid=%d name=%s\n", uid, item->name); } fitem = (guitem *)uid_list->binary_insert(item, uid_compare); if (fitem != item) { /* item already there this shouldn't happen */ free(item->name); free(item); item = fitem; } } bstrncpy(name, item->name, maxlen); return name; } char *guid_list::gid_to_name(gid_t gid, char *name, int maxlen) { guitem sitem, *item, *fitem; sitem.gid = gid; char buf[50]; item = (guitem *)gid_list->binary_search(&sitem, gid_compare); if (!item) { item = (guitem *)malloc(sizeof(guitem)); item->gid = gid; item->name = NULL; get_gidname(gid, item); if (!item->name) { item->name = bstrdup(edit_int64(gid, buf)); } fitem = (guitem *)gid_list->binary_insert(item, gid_compare); if (fitem != item) { /* item already there this shouldn't happen */ free(item->name); free(item); item = fitem; } } bstrncpy(name, item->name, maxlen); return name; } #ifdef TEST_PROGRAM int main() { int i; guid_list *list; char ed1[50], ed2[50]; list = new_guid_list(); for (i=0; i<1001; i++) { printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)), i, list->gid_to_name(i, ed2, sizeof(ed2))); printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)), i, list->gid_to_name(i, ed2, sizeof(ed2))); } free_guid_list(list); sm_dump(false); /* unit test */ return 0; } #endif bareos-Release-14.2.6/src/lib/guid_to_name.h000066400000000000000000000023201263011562700205750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007 Kern Sibbald This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by Kern Sibbald, July 2007 to replace idcache.c * * Program to convert uid and gid into names, and cache the results * for preformance reasons. */ class guid_list { public: dlist *uid_list; dlist *gid_list; char *uid_to_name(uid_t uid, char *name, int maxlen); char *gid_to_name(gid_t gid, char *name, int maxlen); }; guid_list *new_guid_list(); void free_guid_list(guid_list *list); bareos-Release-14.2.6/src/lib/hmac.c000066400000000000000000000073321263011562700170560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version two of the GNU Lesser General Public License as published by the Free Software Foundation plus additions in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Hashed Message Authentication Code using MD5 (HMAC-MD5) * * hmac_md5 was based on sample code in RFC2104 (thanks guys). * * Adapted to BACULA by Kern E. Sibbald, February MMI. */ #include "bareos.h" #define PAD_LEN 64 /* PAD length */ #define SIG_LEN MD5HashSize /* MD5 digest length */ void hmac_md5( uint8_t* text, /* pointer to data stream */ int text_len, /* length of data stream */ uint8_t* key, /* pointer to authentication key */ int key_len, /* length of authentication key */ uint8_t *hmac) /* returned hmac-md5 */ { MD5_CTX md5c; uint8_t k_ipad[PAD_LEN]; /* inner padding - key XORd with ipad */ uint8_t k_opad[PAD_LEN]; /* outer padding - key XORd with opad */ uint8_t keysig[SIG_LEN]; int i; /* if key is longer than PAD length, reset it to key=MD5(key) */ if (key_len > PAD_LEN) { MD5_CTX md5key; MD5_Init(&md5key); MD5_Update(&md5key, key, key_len); MD5_Final(keysig, &md5key); key = keysig; key_len = SIG_LEN; } /* * the HMAC_MD5 transform looks like: * * MD5(Key XOR opad, MD5(Key XOR ipad, text)) * * where Key is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* Zero pads and store key */ memset(k_ipad, 0, PAD_LEN); memcpy(k_ipad, key, key_len); memcpy(k_opad, k_ipad, PAD_LEN); /* XOR key with ipad and opad values */ for (i=0; inext = mem_block; mem_block = hmem; hmem->mem = mem_block->first; hmem->rem = (char *)hmem + size - hmem->mem; Dmsg3(100, "malloc buf=%p size=%d rem=%d\n", hmem, size, hmem->rem); } /* * This routine frees the whole tree. */ void htable::hash_big_free() { struct h_mem *hmem, *rel; for (hmem=mem_block; hmem; ) { rel = hmem; hmem = hmem->next; Dmsg1(100, "free malloc buf=%p\n", rel); free(rel); } } /* * Normal hash malloc routine that gets a "small" buffer from the big buffer */ char *htable::hash_malloc(int size) { int mb_size; char *buf; int asize = BALIGN(size); if (mem_block->rem < asize) { if (total_size >= (extend_length / 2)) { mb_size = extend_length; } else { mb_size = extend_length / 2; } malloc_big_buf(mb_size); Dmsg1(100, "Created new big buffer of %ld bytes\n", mb_size); } mem_block->rem -= asize; buf = mem_block->mem; mem_block->mem += asize; return buf; } /* * Create hash of key, stored in hash then * create and return the pseudo random bucket index */ void htable::hash_index(char *key) { hash = 0; for (char *p = key; *p; p++) { hash += ((hash << 5) | (hash >> (sizeof(hash) * 8 - 5))) + (uint32_t)*p; } /* * Multiply by large prime number, take top bits, mask for remainder. */ index = ((hash * 1103515249) >> rshift) & mask; Dmsg2(dbglvl, "Leave hash_index hash=0x%llx index=%d\n", hash, index); } void htable::hash_index(uint32_t key) { hash = key; /* * Multiply by large prime number, take top bits, mask for remainder. */ index = ((hash * 1103515249) >> rshift) & mask; Dmsg2(dbglvl, "Leave hash_index hash=0x%llx index=%d\n", hash, index); } void htable::hash_index(uint64_t key) { hash = key; /* * Multiply by large prime number, take top bits, mask for remainder. */ index = ((hash * 1103515249) >> rshift) & mask; Dmsg2(dbglvl, "Leave hash_index hash=0x%llx index=%d\n", hash, index); } void htable::hash_index(uint8_t *key, uint32_t keylen) { hash = 0; for (uint8_t *p = key; keylen--; p++) { hash += ((hash << 5) | (hash >> (sizeof(hash) * 8 - 5))) + (uint32_t)*p; } /* * Multiply by large prime number, take top bits, mask for remainder. */ index = ((hash * 1103515249) >> rshift) & mask; Dmsg2(dbglvl, "Leave hash_index hash=0x%llx index=%d\n", hash, index); } /* * tsize is the estimated number of entries in the hash table */ htable::htable(void *item, void *link, int tsize, int nr_pages) { init(item, link, tsize, nr_pages); } void htable::init(void *item, void *link, int tsize, int nr_pages) { int pwr; int pagesize; int buffer_size; memset(this, 0, sizeof(htable)); if (tsize < 31) { tsize = 31; } tsize >>= 2; for (pwr = 0; tsize; pwr++) { tsize >>= 1; } loffset = (char *)link - (char *)item; mask = ~((~0) << pwr); /* 3 bits => table size = 8 */ rshift = 30 - pwr; /* Start using bits 28, 29, 30 */ buckets = 1 << pwr; /* Hash table size -- power of two */ max_items = buckets * 4; /* Allow average 4 entries per chain */ table = (hlink **)malloc(buckets * sizeof(hlink *)); memset(table, 0, buckets * sizeof(hlink *)); #ifdef HAVE_GETPAGESIZE pagesize = getpagesize(); #else pagesize = B_PAGE_SIZE; #endif if (nr_pages == 0) { buffer_size = MAX_BUF_SIZE; } else { buffer_size = pagesize * nr_pages; if (buffer_size > MAX_BUF_SIZE) { buffer_size = MAX_BUF_SIZE; } else if (buffer_size < MIN_BUF_SIZE) { buffer_size = MIN_BUF_SIZE; } } malloc_big_buf(buffer_size); extend_length = buffer_size; Dmsg1(100, "Allocated big buffer of %ld bytes\n", buffer_size); } uint32_t htable::size() { return num_items; } /* * Take each hash link and walk down the chain of items * that hash there counting them (i.e. the hits), * then report that number. * Obiously, the more hits in a chain, the more time * it takes to reference them. Empty chains are not so * hot either -- as it means unused or wasted space. */ #define MAX_COUNT 20 void htable::stats() { int hits[MAX_COUNT]; int max = 0; int i, j; hlink *p; printf("\n\nNumItems=%d\nTotal buckets=%d\n", num_items, buckets); printf("Hits/bucket: buckets\n"); for (i = 0; i < MAX_COUNT; i++) { hits[i] = 0; } for (i = 0; i < (int)buckets; i++) { p = table[i]; j = 0; while (p) { p = (hlink *)(p->next); j++; } if (j > max) { max = j; } if (j < MAX_COUNT) { hits[j]++; } } for (i = 0; i < MAX_COUNT; i++) { printf("%2d: %d\n",i, hits[i]); } printf("buckets=%d num_items=%d max_items=%d\n", buckets, num_items, max_items); printf("max hits in a bucket = %d\n", max); printf("total bytes malloced = %lld\n", (long long int)total_size); printf("total blocks malloced = %d\n", blocks); } void htable::grow_table() { htable *big; hlink *cur; void *next_item; Dmsg1(100, "Grow called old size = %d\n", buckets); /* * Setup a bigger table. */ big = (htable *)malloc(sizeof(htable)); memcpy(big, this, sizeof(htable)); /* Start with original class data */ big->loffset = loffset; big->mask = mask<<1 | 1; big->rshift = rshift - 1; big->num_items = 0; big->buckets = buckets * 2; big->max_items = big->buckets * 4; /* * Create a bigger hash table. */ big->table = (hlink **)malloc(big->buckets * sizeof(hlink *)); memset(big->table, 0, big->buckets * sizeof(hlink *)); big->walkptr = NULL; big->walk_index = 0; /* * Insert all the items in the new hash table */ Dmsg1(100, "Before copy num_items=%d\n", num_items); /* * We walk through the old smaller tree getting items, * but since we are overwriting the colision links, we must * explicitly save the item->next pointer and walk each * colision chain ourselves. We do use next() for getting * to the next bucket. */ for (void *item=first(); item; ) { cur = (hlink *)((char *)item + loffset); next_item = cur->next; /* Save link overwritten by insert */ switch (cur->key_type) { case KEY_TYPE_CHAR: Dmsg1(100, "Grow insert: %s\n", cur->key.char_key); big->insert(cur->key.char_key, item); break; case KEY_TYPE_UINT32: Dmsg1(100, "Grow insert: %ld\n", cur->key.uint32_key); big->insert(cur->key.uint32_key, item); break; case KEY_TYPE_UINT64: Dmsg1(100, "Grow insert: %lld\n", cur->key.uint64_key); big->insert(cur->key.uint64_key, item); break; case KEY_TYPE_BINARY: big->insert(cur->key.binary_key, cur->key_len, item); break; } if (next_item) { item = (void *)((char *)next_item - loffset); } else { walkptr = NULL; item = next(); } } Dmsg1(100, "After copy new num_items=%d\n", big->num_items); if (num_items != big->num_items) { Dmsg0(000, "****** Big problems num_items mismatch ******\n"); } free(table); memcpy(this, big, sizeof(htable)); /* Move everything across */ free(big); Dmsg0(100, "Exit grow.\n"); } bool htable::insert(char *key, void *item) { hlink *hp; if (lookup(key)) { return false; /* Already exists */ } ASSERT(index < buckets); Dmsg2(dbglvl, "Insert: hash=%p index=%d\n", hash, index); hp = (hlink *)(((char *)item) + loffset); Dmsg4(dbglvl, "Insert hp=%p index=%d item=%p offset=%u\n", hp, index, item, loffset); hp->next = table[index]; hp->hash = hash; hp->key_type = KEY_TYPE_CHAR; hp->key.char_key = key; hp->key_len = 0; table[index] = hp; Dmsg3(dbglvl, "Insert hp->next=%p hp->hash=0x%llx hp->key=%s\n", hp->next, hp->hash, hp->key.char_key); if (++num_items >= max_items) { Dmsg2(dbglvl, "num_items=%d max_items=%d\n", num_items, max_items); grow_table(); } Dmsg3(dbglvl, "Leave insert index=%d num_items=%d key=%s\n", index, num_items, key); return true; } bool htable::insert(uint32_t key, void *item) { hlink *hp; if (lookup(key)) { return false; /* Already exists */ } ASSERT(index < buckets); Dmsg2(dbglvl, "Insert: hash=%p index=%d\n", hash, index); hp = (hlink *)(((char *)item) + loffset); Dmsg4(dbglvl, "Insert hp=%p index=%d item=%p offset=%u\n", hp, index, item, loffset); hp->next = table[index]; hp->hash = hash; hp->key_type = KEY_TYPE_UINT32; hp->key.uint32_key = key; hp->key_len = 0; table[index] = hp; Dmsg3(dbglvl, "Insert hp->next=%p hp->hash=0x%llx hp->key=%ld\n", hp->next, hp->hash, hp->key.uint32_key); if (++num_items >= max_items) { Dmsg2(dbglvl, "num_items=%d max_items=%d\n", num_items, max_items); grow_table(); } Dmsg3(dbglvl, "Leave insert index=%d num_items=%d key=%ld\n", index, num_items, key); return true; } bool htable::insert(uint64_t key, void *item) { hlink *hp; if (lookup(key)) { return false; /* Already exists */ } ASSERT(index < buckets); Dmsg2(dbglvl, "Insert: hash=%p index=%d\n", hash, index); hp = (hlink *)(((char *)item) + loffset); Dmsg4(dbglvl, "Insert hp=%p index=%d item=%p offset=%u\n", hp, index, item, loffset); hp->next = table[index]; hp->hash = hash; hp->key_type = KEY_TYPE_UINT64; hp->key.uint64_key = key; hp->key_len = 0; table[index] = hp; Dmsg3(dbglvl, "Insert hp->next=%p hp->hash=0x%llx hp->key=%lld\n", hp->next, hp->hash, hp->key.uint64_key); if (++num_items >= max_items) { Dmsg2(dbglvl, "num_items=%d max_items=%d\n", num_items, max_items); grow_table(); } Dmsg3(dbglvl, "Leave insert index=%d num_items=%d key=%lld\n", index, num_items, key); return true; } bool htable::insert(uint8_t *key, uint32_t key_len, void *item) { hlink *hp; if (lookup(key, key_len)) { return false; /* Already exists */ } ASSERT(index < buckets); Dmsg2(dbglvl, "Insert: hash=%p index=%d\n", hash, index); hp = (hlink *)(((char *)item) + loffset); Dmsg4(dbglvl, "Insert hp=%p index=%d item=%p offset=%u\n", hp, index, item, loffset); hp->next = table[index]; hp->hash = hash; hp->key_type = KEY_TYPE_BINARY; hp->key.binary_key = key; hp->key_len = key_len; table[index] = hp; Dmsg2(dbglvl, "Insert hp->next=%p hp->hash=0x%llx\n", hp->next, hp->hash); if (++num_items >= max_items) { Dmsg2(dbglvl, "num_items=%d max_items=%d\n", num_items, max_items); grow_table(); } Dmsg2(dbglvl, "Leave insert index=%d num_items=%d\n", index, num_items); return true; } void *htable::lookup(char *key) { hash_index(key); for (hlink *hp = table[index]; hp; hp = (hlink *)hp->next) { ASSERT(hp->key_type == KEY_TYPE_CHAR); if (hash == hp->hash && bstrcmp(key, hp->key.char_key)) { Dmsg1(dbglvl, "lookup return %p\n", ((char *)hp) - loffset); return ((char *)hp) - loffset; } } return NULL; } void *htable::lookup(uint32_t key) { hash_index(key); for (hlink *hp = table[index]; hp; hp = (hlink *)hp->next) { ASSERT(hp->key_type == KEY_TYPE_UINT32); if (hash == hp->hash && key == hp->key.uint32_key) { Dmsg1(dbglvl, "lookup return %p\n", ((char *)hp) - loffset); return ((char *)hp) - loffset; } } return NULL; } void *htable::lookup(uint64_t key) { hash_index(key); for (hlink *hp = table[index]; hp; hp = (hlink *)hp->next) { ASSERT(hp->key_type == KEY_TYPE_UINT64); if (hash == hp->hash && key == hp->key.uint64_key) { Dmsg1(dbglvl, "lookup return %p\n", ((char *)hp) - loffset); return ((char *)hp) - loffset; } } return NULL; } void *htable::lookup(uint8_t *key, uint32_t key_len) { hash_index(key, key_len); for (hlink *hp = table[index]; hp; hp = (hlink *)hp->next) { ASSERT(hp->key_type == KEY_TYPE_BINARY); if (hash == hp->hash && memcmp(key, hp->key.binary_key, hp->key_len) == 0) { Dmsg1(dbglvl, "lookup return %p\n", ((char *)hp) - loffset); return ((char *)hp) - loffset; } } return NULL; } void *htable::next() { Dmsg1(dbglvl, "Enter next: walkptr=%p\n", walkptr); if (walkptr) { walkptr = (hlink *)(walkptr->next); } while (!walkptr && walk_index < buckets) { walkptr = table[walk_index++]; if (walkptr) { Dmsg3(dbglvl, "new walkptr=%p next=%p inx=%d\n", walkptr, walkptr->next, walk_index-1); } } if (walkptr) { Dmsg2(dbglvl, "next: rtn %p walk_index=%d\n", ((char *)walkptr) - loffset, walk_index); return ((char *)walkptr) - loffset; } Dmsg0(dbglvl, "next: return NULL\n"); return NULL; } void *htable::first() { Dmsg0(dbglvl, "Enter first\n"); walkptr = table[0]; /* get first bucket */ walk_index = 1; /* Point to next index */ while (!walkptr && walk_index < buckets) { walkptr = table[walk_index++]; /* go to next bucket */ if (walkptr) { Dmsg3(dbglvl, "first new walkptr=%p next=%p inx=%d\n", walkptr, walkptr->next, walk_index-1); } } if (walkptr) { Dmsg1(dbglvl, "Leave first walkptr=%p\n", walkptr); return ((char *)walkptr) - loffset; } Dmsg0(dbglvl, "Leave first walkptr=NULL\n"); return NULL; } /* Destroy the table and its contents */ void htable::destroy() { hash_big_free(); free(table); table = NULL; garbage_collect_memory(); Dmsg0(100, "Done destroy.\n"); } #ifdef TEST_PROGRAM struct MYJCR { #ifndef TEST_NON_CHAR char *key; #else uint32_t key; #endif hlink link; }; #ifndef TEST_SMALL_HTABLE #define NITEMS 5000000 #else #define NITEMS 5000 #endif int main() { char mkey[30]; htable *jcrtbl; MYJCR *save_jcr = NULL, *item; MYJCR *jcr = NULL; int count = 0; jcrtbl = (htable *)malloc(sizeof(htable)); #ifndef TEST_SMALL_HTABLE jcrtbl->init(jcr, &jcr->link, NITEMS); #else jcrtbl->init(jcr, &jcr->link, NITEMS, 128); #endif Dmsg1(000, "Inserting %d items\n", NITEMS); for (int i=0; ihash_malloc(sizeof(MYJCR)); jcr->key = (char *)jcrtbl->hash_malloc(len); memcpy(jcr->key, mkey, len); #else jcr = (MYJCR *)jcrtbl->hash_malloc(sizeof(MYJCR)); jcr->key = i; #endif Dmsg2(100, "link=%p jcr=%p\n", jcr->link, jcr); jcrtbl->insert(jcr->key, jcr); if (i == 10) { save_jcr = jcr; } } if (!(item = (MYJCR *)jcrtbl->lookup(save_jcr->key))) { printf("Bad news: %s not found.\n", save_jcr->key); } else { #ifndef TEST_NON_CHAR printf("Item 10's key is: %s\n", item->key); #else printf("Item 10's key is: %ld\n", item->key); #endif } jcrtbl->stats(); printf("Walk the hash table:\n"); foreach_htable (jcr, jcrtbl) { #ifndef TEST_NON_CHAR // printf("htable item = %s\n", jcr->key); #ifndef BIG_MALLOC free(jcr->key); #endif #endif count++; } printf("Got %d items -- %s\n", count, count==NITEMS?"OK":"***ERROR***"); printf("Calling destroy\n"); jcrtbl->destroy(); free(jcrtbl); printf("Freed jcrtbl\n"); sm_dump(false); /* unit test */ } #endif bareos-Release-14.2.6/src/lib/htable.h000066400000000000000000000110401263011562700174010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by Kern Sibbald, MMIV */ #ifndef HTABLE_H #define HTABLE_H /* * Hash table class -- htable */ /* * Loop var through each member of table */ #ifdef HAVE_TYPEOF #define foreach_htable(var, tbl) \ for((var)=(typeof(var))((tbl)->first()); \ (var); \ (var)=(typeof(var))((tbl)->next())) #else #define foreach_htable(var, tbl) \ for((*((void **)&(var))=(void *)((tbl)->first())); \ (var); \ (*((void **)&(var))=(void *)((tbl)->next()))) #endif typedef enum { KEY_TYPE_CHAR = 1, KEY_TYPE_UINT32 = 2, KEY_TYPE_UINT64 = 3, KEY_TYPE_BINARY = 4 } key_type_t; union hlink_key { char *char_key; uint32_t uint32_key; uint64_t uint64_key; uint8_t *binary_key; }; struct hlink { void *next; /* Next hash item */ key_type_t key_type; /* Type of key used to hash */ union hlink_key key; /* Key for this item */ uint32_t key_len; /* Length of key for this item */ uint64_t hash; /* Hash for this key */ }; struct h_mem { struct h_mem *next; /* Next buffer */ int32_t rem; /* Remaining bytes in big_buffer */ char *mem; /* Memory pointer */ char first[1]; /* First byte */ }; class htable : public SMARTALLOC { hlink **table; /* Hash table */ int loffset; /* Link offset in item */ hlink *walkptr; /* Table walk pointer */ uint64_t hash; /* Temp storage */ uint64_t total_size; /* Total bytes malloced */ uint32_t extend_length; /* Number of bytes to allocate when extending buffer */ uint32_t walk_index; /* Table walk index */ uint32_t num_items; /* Current number of items */ uint32_t max_items; /* Maximum items before growing */ uint32_t buckets; /* Size of hash table */ uint32_t index; /* Temp storage */ uint32_t mask; /* "Remainder" mask */ uint32_t rshift; /* Amount to shift down */ uint32_t blocks; /* Blocks malloced */ struct h_mem *mem_block; /* Malloc'ed memory block chain */ void malloc_big_buf(int size); /* Get a big buffer */ void hash_index(char *key); /* Produce hash key,index */ void hash_index(uint32_t key); /* Produce hash key,index */ void hash_index(uint64_t key); /* Produce hash key,index */ void hash_index(uint8_t *key, uint32_t key_len); /* Produce hash key,index */ void grow_table(); /* Grow the table */ public: htable(void *item, void *link, int tsize = 31, int nr_pages = 0); ~htable() { destroy(); } void init(void *item, void *link, int tsize = 31, int nr_pages = 0); bool insert(char *key, void *item); bool insert(uint32_t key, void *item); bool insert(uint64_t key, void *item); bool insert(uint8_t *key, uint32_t key_len, void *item); void *lookup(char *key); void *lookup(uint32_t key); void *lookup(uint64_t key); void *lookup(uint8_t *key, uint32_t key_len); void *first(); /* Get first item in table */ void *next(); /* Get next item in table */ void destroy(); void stats(); /* Print stats about the table */ uint32_t size(); /* Return size of table */ char *hash_malloc(int size); /* Malloc bytes for a hash entry */ void hash_big_free(); /* Free all hash allocated big buffers */ }; #endif /* HTABLE_H */ bareos-Release-14.2.6/src/lib/ini.c000066400000000000000000000603501263011562700167240ustar00rootroot00000000000000/* Copyright (C) 2011-2011 Bacula Systems(R) SA Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Handle simple configuration file such as "ini" files. * key1 = val # comment * key2 = val # */ #include "bareos.h" #include "ini.h" #define bfree_and_null_const(a) do{if(a){free((void *)a); (a)=NULL;}} while(0) static int dbglevel = 100; /* * We use this structure to associate a key to the function */ struct ini_store { const char *key; const char *comment; int type; }; static struct ini_store funcs[] = { { "@INT32@", "Integer", INI_CFG_TYPE_INT32 }, { "@PINT32@", "Integer", INI_CFG_TYPE_PINT32 }, { "@INT64@", "Integer", INI_CFG_TYPE_INT64 }, { "@PINT64@", "Positive Integer", INI_CFG_TYPE_PINT64 }, { "@NAME@", "Simple String", INI_CFG_TYPE_NAME }, { "@STR@", "String", INI_CFG_TYPE_STR }, { "@BOOL@", "on/off", INI_CFG_TYPE_BOOL }, { "@ALIST@", "String list", INI_CFG_TYPE_ALIST_STR }, { NULL, NULL, 0 } }; /* * Get handler code from storage type. */ const char *ini_get_store_code(int type) { int i; for (i = 0; funcs[i].key ; i++) { if (funcs[i].type == type) { return funcs[i].key; } } return NULL; } /* * Get storage type from handler name. */ int ini_get_store_type(const char *key) { int i; for (i = 0; funcs[i].key ; i++) { if (!strcmp(funcs[i].key, key)) { return funcs[i].type; } } return 0; } /* ---------------------------------------------------------------- * Handle data type. Import/Export * ---------------------------------------------------------------- */ static bool ini_store_str(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%s", item->val.strval); return true; } if (lex_get_token(lc, T_STRING) == T_ERROR) { return false; } /* * If already allocated, free first */ if (item->found && item->val.strval) { free(item->val.strval); } item->val.strval = bstrdup(lc->str); scan_to_eol(lc); return true; } static bool ini_store_name(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%s", item->val.nameval); return true; } if (lex_get_token(lc, T_NAME) == T_ERROR) { return false; } bstrncpy(item->val.nameval, lc->str, sizeof(item->val.nameval)); scan_to_eol(lc); return true; } static bool ini_store_alist_str(LEX *lc, ConfigFile *inifile, ini_items *item) { alist *list; if (!lc) { /* * TODO, write back the alist to edit buffer */ return true; } if (lex_get_token(lc, T_STRING) == T_ERROR) { return false; } if (item->val.alistval == NULL) { list = New(alist(10, owned_by_alist)); } else { list = item->val.alistval; } Dmsg4(900, "Append %s to alist %p size=%d %s\n", lc->str, list, list->size(), item->name); list->append(bstrdup(lc->str)); item->val.alistval = list; scan_to_eol(lc); return true; } static bool ini_store_int64(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%lld", item->val.int64val); return true; } if (lex_get_token(lc, T_INT64) == T_ERROR) { return false; } item->val.int64val = lc->int64_val; scan_to_eol(lc); return true; } static bool ini_store_pint64(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%lld", item->val.int64val); return true; } if (lex_get_token(lc, T_PINT64) == T_ERROR) { return false; } item->val.int64val = lc->pint64_val; scan_to_eol(lc); return true; } static bool ini_store_pint32(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%d", item->val.int32val); return true; } if (lex_get_token(lc, T_PINT32) == T_ERROR) { return false; } item->val.int32val = lc->pint32_val; scan_to_eol(lc); return true; } static bool ini_store_int32(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%d", item->val.int32val); return true; } if (lex_get_token(lc, T_INT32) == T_ERROR) { return false; } item->val.int32val = lc->int32_val; scan_to_eol(lc); return true; } static bool ini_store_bool(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%s", item->val.boolval?"yes":"no"); return true; } if (lex_get_token(lc, T_NAME) == T_ERROR) { return false; } if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) { item->val.boolval = true; } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) { item->val.boolval = false; } else { /* * YES and NO must not be translated */ scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); return false; } scan_to_eol(lc); return true; } /* * Format a scanner error message */ static void s_err(const char *file, int line, LEX *lc, const char *msg, ...) { va_list ap; int len, maxlen; ConfigFile *ini; POOL_MEM buf(PM_MESSAGE); while (1) { maxlen = buf.size() - 1; va_start(ap, msg); len = bvsnprintf(buf.c_str(), maxlen, msg, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } #ifdef TEST_PROGRAM printf("ERROR: Config file error: %s\n" " : Line %d, col %d of file %s\n%s\n", buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); #endif ini = (ConfigFile *)(lc->caller_ctx); if (ini->jcr) { /* called from core */ Jmsg(ini->jcr, M_ERROR, 0, _("Config file error: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); // } else if (ini->ctx) { /* called from plugin */ // ini->bfuncs->JobMessage(ini->ctx, __FILE__, __LINE__, M_FATAL, 0, // _("Config file error: %s\n" // " : Line %d, col %d of file %s\n%s\n"), // buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); // } else { /* called from ??? */ e_msg(file, line, M_ERROR, 0, _("Config file error: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); } } /* * Format a scanner error message */ static void s_warn(const char *file, int line, LEX *lc, const char *msg, ...) { va_list ap; int len, maxlen; ConfigFile *ini; POOL_MEM buf(PM_MESSAGE); while (1) { maxlen = buf.size() - 1; va_start(ap, msg); len = bvsnprintf(buf.c_str(), maxlen, msg, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } #ifdef TEST_PROGRAM printf("WARNING: Config file warning: %s\n" " : Line %d, col %d of file %s\n%s\n", buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); #endif ini = (ConfigFile *)(lc->caller_ctx); if (ini->jcr) { /* called from core */ Jmsg(ini->jcr, M_WARNING, 0, _("Config file warning: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); // } else if (ini->ctx) { /* called from plugin */ // ini->bfuncs->JobMessage(ini->ctx, __FILE__, __LINE__, M_WARNING, 0, // _("Config file warning: %s\n" // " : Line %d, col %d of file %s\n%s\n"), // buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); // } else { /* called from ??? */ p_msg(file, line, 0, _("Config file warning: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); } } /* * Reset free items */ void ConfigFile::clear_items() { if (!items) { return; } for (int i = 0; items[i].name; i++) { if (items[i].found) { /* * Special members require delete or free */ switch (items[i].type) { case INI_CFG_TYPE_STR: free(items[i].val.strval); items[i].val.strval = NULL; break; case INI_CFG_TYPE_ALIST_STR: delete items[i].val.alistval; items[i].val.alistval = NULL; break; default: break; } items[i].found = false; } } } void ConfigFile::free_items() { if (items_allocated) { for (int i = 0; items[i].name; i++) { bfree_and_null_const(items[i].name); bfree_and_null_const(items[i].comment); } free(items); } items = NULL; items_allocated = false; } /* * Get a particular item from the items list */ int ConfigFile::get_item(const char *name) { if (!items) { return -1; } for (int i = 0; i < MAX_INI_ITEMS && items[i].name; i++) { if (bstrcasecmp(name, items[i].name)) { return i; } } return -1; } /* * Dump a buffer to a file in the working directory * Needed to unserialise() a config */ bool ConfigFile::dump_string(const char *buf, int32_t len) { FILE *fp; bool ret = false; if (!out_fname) { out_fname = get_pool_memory(PM_FNAME); make_unique_filename(&out_fname, (int)(intptr_t)this, (char*)"configfile"); } fp = fopen(out_fname, "wb"); if (!fp) { return ret; } if (fwrite(buf, len, 1, fp) == 1) { ret = true; } fclose(fp); return ret; } /* * Dump the item table format to a text file (used by plugin) */ bool ConfigFile::serialize(const char *fname) { FILE *fp; POOLMEM *tmp; int32_t len; bool ret = false; if (!items) { return ret; } fp = fopen(fname, "w"); if (!fp) { return ret; } tmp = get_pool_memory(PM_MESSAGE); len = serialize(&tmp); if (fwrite(tmp, len, 1, fp) == 1) { ret = true; } free_pool_memory(tmp); fclose(fp); return ret; } /* * Dump the item table format to a text file (used by plugin) */ int ConfigFile::serialize(POOLMEM **buf) { int len; POOLMEM *tmp; if (!items) { **buf = 0; return 0; } len = Mmsg(buf, "# Plugin configuration file\n# Version %d\n", version); tmp = get_pool_memory(PM_MESSAGE); for (int i = 0; items[i].name; i++) { if (items[i].comment) { Mmsg(tmp, "OptPrompt=%s\n", items[i].comment); pm_strcat(buf, tmp); } if (items[i].default_value) { Mmsg(tmp, "OptDefault=%s\n", items[i].default_value); pm_strcat(buf, tmp); } if (items[i].required) { Mmsg(tmp, "OptRequired=yes\n"); pm_strcat(buf, tmp); } /* variable = @INT64@ */ Mmsg(tmp, "%s=%s\n\n", items[i].name, ini_get_store_code(items[i].type)); len = pm_strcat(buf, tmp); } free_pool_memory(tmp); return len ; } /* * Dump the item table content to a text file (used by director) */ int ConfigFile::dump_results(POOLMEM **buf) { int len; POOLMEM *tmp; if (!items) { **buf = 0; return 0; } len = Mmsg(buf, "# Plugin configuration file\n# Version %d\n", version); tmp = get_pool_memory(PM_MESSAGE); for (int i = 0; items[i].name; i++) { if (items[i].found) { switch (items[i].type) { case INI_CFG_TYPE_INT32: ini_store_int32(NULL, this, &items[i]); break; case INI_CFG_TYPE_PINT32: ini_store_pint32(NULL, this, &items[i]); break; case INI_CFG_TYPE_INT64: ini_store_int64(NULL, this, &items[i]); break; case INI_CFG_TYPE_PINT64: ini_store_pint64(NULL, this, &items[i]); break; case INI_CFG_TYPE_NAME: ini_store_name(NULL, this, &items[i]); break; case INI_CFG_TYPE_STR: ini_store_str(NULL, this, &items[i]); break; case INI_CFG_TYPE_BOOL: ini_store_bool(NULL, this, &items[i]); break; case INI_CFG_TYPE_ALIST_STR: ini_store_alist_str(NULL, this, &items[i]); break; default: break; } if (items[i].comment && *items[i].comment) { Mmsg(tmp, "# %s\n", items[i].comment); pm_strcat(buf, tmp); } Mmsg(tmp, "%s=%s\n\n", items[i].name, this->edit); len = pm_strcat(buf, tmp); } } free_pool_memory(tmp); return len ; } /* * Parse a config file used by Plugin/Director */ bool ConfigFile::parse(const char *fname) { int token, i; bool ret = false; if (!items) { return false; } if ((lc = lex_open_file(lc, fname, s_err, s_warn)) == NULL) { berrno be; Emsg2(M_ERROR, 0, _("Cannot open config file %s: %s\n"), fname, be.bstrerror()); return false; } lc->options |= LOPT_NO_EXTERN; lc->caller_ctx = (void *)this; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg1(dbglevel, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { continue; } for (i = 0; items[i].name; i++) { if (bstrcasecmp(items[i].name, lc->str)) { if ((token = lex_get_token(lc, T_EQUALS)) == T_ERROR) { Dmsg1(dbglevel, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); break; } Dmsg1(dbglevel, "calling handler for %s\n", items[i].name); /* * Call item handler */ switch (items[i].type) { case INI_CFG_TYPE_INT32: ret = ini_store_int32(lc, this, &items[i]); break; case INI_CFG_TYPE_PINT32: ret = ini_store_pint32(lc, this, &items[i]); break; case INI_CFG_TYPE_INT64: ret = ini_store_int64(lc, this, &items[i]); break; case INI_CFG_TYPE_PINT64: ret = ini_store_pint64(lc, this, &items[i]); break; case INI_CFG_TYPE_NAME: ret = ini_store_name(lc, this, &items[i]); break; case INI_CFG_TYPE_STR: ret = ini_store_str(lc, this, &items[i]); break; case INI_CFG_TYPE_BOOL: ret = ini_store_bool(lc, this, &items[i]); break; case INI_CFG_TYPE_ALIST_STR: ret = ini_store_alist_str(lc, this, &items[i]); break; default: break; } i = -1; break; } } if (i >= 0) { Dmsg1(dbglevel, "Keyword = %s\n", lc->str); scan_err1(lc, "Keyword %s not found", lc->str); /* * We can raise an error here */ break; } if (!ret) { break; } } for (i = 0; items[i].name; i++) { if (items[i].required && !items[i].found) { scan_err1(lc, "%s required but not found", items[i].name); ret = false; } } lc = lex_close_file(lc); return ret; } /* * Analyse the content of a ini file to build the item list * It uses special syntax for datatype. Used by Director on Restore object * * OptPrompt = "Variable1" * OptRequired * OptDefault = 100 * Variable1 = @PINT32@ * ... */ bool ConfigFile::unserialize(const char *fname) { int token, i, nb = 0; bool ret = false; const char **assign; /* * At this time, we allow only 32 different items */ int s = MAX_INI_ITEMS * sizeof (struct ini_items); items = (struct ini_items *) malloc (s); memset(items, 0, s); items_allocated = true; /* * Parse the file and generate the items structure on the fly */ if ((lc = lex_open_file(lc, fname, s_err, s_warn)) == NULL) { berrno be; Emsg2(M_ERROR, 0, _("Cannot open config file %s: %s\n"), fname, be.bstrerror()); return false; } lc->options |= LOPT_NO_EXTERN; lc->caller_ctx = (void *)this; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg1(dbglevel, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { continue; } ret = false; assign = NULL; if (nb >= MAX_INI_ITEMS) { break; } if (bstrcasecmp("optprompt", lc->str)) { assign = &(items[nb].comment); } else if (bstrcasecmp("optdefault", lc->str)) { assign = &(items[nb].default_value); } else if (bstrcasecmp("optrequired", lc->str)) { items[nb].required = true; /* Don't use argument */ scan_to_eol(lc); continue; } else { items[nb].name = bstrdup(lc->str); } token = lex_get_token(lc, T_ALL); Dmsg1(dbglevel, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); if (token != T_EQUALS) { scan_err1(lc, "expected an equals, got: %s", lc->str); break; } /* * We may allow blank variable */ if (lex_get_token(lc, T_STRING) == T_ERROR) { break; } if (assign) { *assign = bstrdup(lc->str); } else { if ((items[nb].type = ini_get_store_type(lc->str)) == 0) { scan_err1(lc, "expected a data type, got: %s", lc->str); break; } nb++; } scan_to_eol(lc); ret = true; } if (!ret) { for (i = 0; i < nb; i++) { bfree_and_null_const(items[i].name); bfree_and_null_const(items[i].comment); bfree_and_null_const(items[i].default_value); items[i].type = 0; items[i].required = false; } } lc = lex_close_file(lc); return ret; } /* ---------------------------------------------------------------- */ #ifdef TEST_PROGRAM /* make ini * export LD_LIBRARY_PATH=.libs/ * ./.libs/ini */ #include int err=0; int nb=0; void _ok(const char *file, int l, const char *op, int value, const char *label) { nb++; if (!value) { err++; printf("ERR %.45s %s:%i on %s\n", label, file, l, op); } else { printf("OK %.45s\n", label); } } #define ok(x, label) _ok(__FILE__, __LINE__, #x, (x), label) void _nok(const char *file, int l, const char *op, int value, const char *label) { nb++; if (value) { err++; printf("ERR %.45s %s:%i on !%s\n", label, file, l, op); } else { printf("OK %.45s\n", label); } } #define nok(x, label) _nok(__FILE__, __LINE__, #x, (x), label) int report() { printf("Result %i/%i OK\n", nb - err, nb); return err>0; } struct ini_items test_items[] = { /* name type comment req */ { "datastore", INI_CFG_TYPE_NAME, "Target Datastore", 0 }, { "newhost", INI_CFG_TYPE_STR, "New Hostname", 1 }, { "int64val", INI_CFG_TYPE_INT64, "Int64", 1 }, { "list", INI_CFG_TYPE_ALIST_STR, "list", 0 }, { "bool", INI_CFG_TYPE_BOOL, "Bool", 0 }, { "pint64", INI_CFG_TYPE_PINT64, "pint", 0 }, { "int32", INI_CFG_TYPE_INT32, "int 32bit", 0 }, { "plugin.test", INI_CFG_TYPE_STR, "test with .", 0 }, { NULL, NULL, NULL, 0 } }; int main() { FILE *fp; int pos; ConfigFile *ini = new ConfigFile(); POOLMEM *buf = get_pool_memory(PM_BSOCK); nok(ini->register_items(test_items, 5), "Check bad sizeof ini_items"); ok(ini->register_items(test_items, sizeof(struct ini_items)), "Check sizeof ini_items"); if ((fp = fopen("test.cfg", "w")) == NULL) { exit (1); } fprintf(fp, "# this is a comment\ndatastore=datastore1\nnewhost=\"host1\"\n"); fflush(fp); nok(ini->parse("test.cfg"), "Test missing member"); ini->clear_items(); fprintf(fp, "int64val=12 # with a comment\n"); fprintf(fp, "int64val=10 # with a comment\n"); fprintf(fp, "int32=100\n"); fprintf(fp, "bool=yes\n"); fprintf(fp, "plugin.test=parameter\n"); fflush(fp); ok(ini->parse("test.cfg"), "Test with all members"); ok(ini->items[0].found, "Test presence of char[]"); ok(!strcmp(ini->items[0].val.nameval, "datastore1"), "Test char[]"); ok(ini->items[1].found, "Test presence of char*"); ok(!strcmp(ini->items[1].val.strval, "host1"), "Test char*"); ok(ini->items[2].found, "Test presence of int"); ok(ini->items[2].val.int64val == 10, "Test int"); ok(ini->items[4].val.boolval == true, "Test bool"); ok(ini->items[6].val.int32val == 100, "Test int 32"); alist *list = ini->items[3].val.alistval; nok(ini->items[3].found, "Test presence of alist"); fprintf(fp, "list=a\nlist=b\nlist=c\n"); fflush(fp); ini->clear_items(); ok(ini->parse("test.cfg"), "Test with all members"); list = ini->items[3].val.alistval; ok(ini->items[3].found, "Test presence of alist"); ok(list != NULL, "Test list member"); ok(list->size() == 3, "Test list size"); ok(!strcmp((char *)list->get(0), "a"), "Testing alist[0]"); ok(!strcmp((char *)list->get(1), "b"), "Testing alist[1]"); ok(!strcmp((char *)list->get(2), "c"), "Testing alist[2]"); system("cp -f test.cfg test3.cfg"); fprintf(fp, "pouet='10, 11, 12'\n"); fprintf(fp, "pint=-100\n"); fprintf(fp, "int64val=-100\n"); /* TODO: fix negative numbers */ fflush(fp); ini->clear_items(); ok(ini->parse("test.cfg"), "Test with errors"); nok(ini->items[5].found, "Test presence of positive int"); fclose(fp); ini->clear_items(); ini->free_items(); /* Test */ if ((fp = fopen("test2.cfg", "w")) == NULL) { exit (1); } fprintf(fp, "# this is a comment\n" "optprompt=\"Datastore Name\"\n" "datastore=@NAME@\n" "optprompt=\"New Hostname to create\"\n" "newhost=@STR@\n" "optprompt=\"Some 64 integer\"\n" "optrequired=yes\n" "int64val=@INT64@\n" "list=@ALIST@\n" "bool=@BOOL@\n" "pint64=@PINT64@\n" "pouet=@STR@\n" "int32=@INT32@\n" "plugin.test=@STR@\n" ); fclose(fp); ok(ini->unserialize("test2.cfg"), "Test dynamic parse"); ok(ini->serialize("test4.cfg"), "Try to dump the item table in a file"); ok(ini->serialize(&buf) > 0, "Try to dump the item table in a buffer"); ok(ini->parse("test3.cfg"), "Parse test file with dynamic grammar"); ok((pos = ini->get_item("datastore")) == 0, "Check datastore definition"); ok(ini->items[pos].found, "Test presence of char[]"); ok(!strcmp(ini->items[pos].val.nameval, "datastore1"), "Test char[]"); ok(!strcmp(ini->items[pos].comment, "Datastore Name"), "Check comment"); ok(ini->items[pos].required == false, "Check required"); ok((pos = ini->get_item("newhost")) == 1, "Check newhost definition"); ok(ini->items[pos].found, "Test presence of char*"); ok(!strcmp(ini->items[pos].val.strval, "host1"), "Test char*"); ok(ini->items[pos].required == false, "Check required"); ok((pos = ini->get_item("int64val")) == 2, "Check int64val definition"); ok(ini->items[pos].found, "Test presence of int"); ok(ini->items[pos].val.int64val == 10, "Test int"); ok(ini->items[pos].required == true, "Check required"); ok((pos = ini->get_item("bool")) == 4, "Check bool definition"); ok(ini->items[pos].val.boolval == true, "Test bool"); ok(ini->dump_results(&buf), "Test to dump results"); printf("<%s>\n", buf); ini->clear_items(); ini->free_items(); report(); free_pool_memory(buf); exit (0); } #endif bareos-Release-14.2.6/src/lib/ini.h000066400000000000000000000146761263011562700167430ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2011 Bacula Systems(R) SA This program is Free Software; you can modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef INI_H #define INI_H /* * Standard global types with handlers defined in ini.c */ enum { INI_CFG_TYPE_INT32 = 1, /* 32 bits Integer */ INI_CFG_TYPE_PINT32 = 2, /* Positive 32 bits Integer (unsigned) */ INI_CFG_TYPE_INT64 = 3, /* 64 bits Integer */ INI_CFG_TYPE_PINT64 = 4, /* Positive 64 bits Integer (unsigned) */ INI_CFG_TYPE_NAME = 5, /* Name */ INI_CFG_TYPE_STR = 6, /* String */ INI_CFG_TYPE_BOOL = 7, /* Boolean */ INI_CFG_TYPE_ALIST_STR = 8 /* List of strings */ }; /* * Plugin has a internal C structure that describes the configuration: * struct ini_items[] * * The ConfigFile object can generate a text file that describes the C * structure. This text format is saved as RestoreObject in the catalog. * * struct ini_items[] -> register_items() -> serialize() -> RestoreObject R1 * * On the Director side, at the restore time, we can analyse this text to * get the C structure. * * RestoreObject R1 -> write to disk -> unserialize() -> struct ini_items[] * * Once done, we can ask questions to the user at the restore time and fill * the C struct with answers. The Director can send back as a RestoreObject * the result of the questionnaire. * * struct ini_items[] -> UAContext -> dump_result() -> FD as RestoreObject R2 * * On the Plugin side, it can get back the C structure and use it. * RestoreObject R2 -> parse() -> struct ini_items[] */ class ConfigFile; struct ini_items; /* * Used to store result */ typedef union { char *strval; char nameval[MAX_NAME_LENGTH]; int64_t int64val; int32_t int32val; alist *alistval; bool boolval; } item_value; /* * If no items are registred at the scan time, we detect this list from * the file itself */ struct ini_items { const char *name; /* keyword name */ int type; /* type accepted */ const char *comment; /* comment associated, used in prompt */ int required; /* optional required or not */ const char *re_value; /* optional regexp associated */ const char *in_values; /* optional list of values */ const char *default_value; /* optional default value */ bool found; /* if val is set */ item_value val; /* val contains the value */ }; /* * When reading a ini file, we limit the number of items that we can create */ #define MAX_INI_ITEMS 32 /* * Special RestoreObject name used to get user input at restore time */ #define INI_RESTORE_OBJECT_NAME "RestoreOptions" /* * Can be used to set re_value, in_value, default_value, found and val to 0 * G++ looks to allow partial declaration, let see with an other compiler */ #define ITEMS_DEFAULT NULL,NULL,NULL,0,{0} /* * Handle simple configuration file such as "ini" files. * key1 = val # comment * OptPrompt=comment * key2 = val * * For usage example, see ini.c TEST_PROGRAM */ class ConfigFile { private: LEX *lc; /* Lex parser */ bool items_allocated; public: JCR *jcr; /* JCR needed for Jmsg */ int version; /* Internal version check */ int sizeof_ini_items; /* Extra check when using dynamic loading */ struct ini_items *items; /* Structure of the config file */ POOLMEM *out_fname; /* Can be used to dump config to disk */ POOLMEM *edit; /* Can be used to build result file */ ConfigFile() { lc = NULL; jcr = NULL; items = NULL; out_fname = NULL; version = 1; items_allocated = false; edit = get_pool_memory(PM_FNAME); sizeof_ini_items = sizeof(struct ini_items); } ~ConfigFile() { if (lc) { lex_close_file(lc); } if (edit) { free_pool_memory(edit); } if (out_fname) { unlink(out_fname); free_pool_memory(out_fname); } free_items(); } /* * Dump a config string to out_fname */ bool dump_string(const char *buf, int32_t len); /* * JCR needed for Jmsg */ void set_jcr(JCR *ajcr) { jcr = ajcr; } /* * Free malloced items such as char* or alist or items */ void free_items(); /* * Clear items member */ void clear_items(); /* * Dump the item table to a file (used on plugin side) */ bool serialize(const char *fname); /* * Dump the item table format to a buffer (used on plugin side) * returns the length of the buffer, -1 if error */ int serialize(POOLMEM **buf); /* * Dump the item table content to a buffer */ int dump_results(POOLMEM **buf); /* * Get item position in items list (useful when dynamic) */ int get_item(const char *name); /* * Register config file structure, if size doesn't match */ bool register_items(struct ini_items *aitems, int size) { int i; if (sizeof_ini_items == size) { for (i = 0; aitems[i].name ; i++); items = (struct ini_items*) malloc((i+1) * size); /* NULL terminated */ memcpy(items, aitems, (i+1) * size); items_allocated = false; /* we copy only pointers, don't free them */ return true; } return false; } /* * Parse a ini file with a item list previously registred (plugin side) */ bool parse(const char *filename); /* * Create a item list from a ini file (director side) */ bool unserialize(const char *filename); }; /* * Get handler code from storage type. */ const char *ini_get_store_code(int type); /* * Get storage type from handler name. */ int ini_get_store_type(const char *key); #endif bareos-Release-14.2.6/src/lib/jcr.c000066400000000000000000000771121263011562700167270ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Manipulation routines for Job Control Records and * handling of last_jobs_list. * * Kern E. Sibbald, December 2000 * * These routines are thread safe. * * The job list routines were re-written in May 2005 to * eliminate the global lock while traversing the list, and * to use the dlist subroutines. The locking is now done * on the list each time the list is modified or traversed. * That is it is "micro-locked" rather than globally locked. * The result is that there is one lock/unlock for each entry * in the list while traversing it rather than a single lock * at the beginning of a traversal and one at the end. This * incurs slightly more overhead, but effectively eliminates * the possibilty of race conditions. In addition, with the * exception of the global locking of the list during the * re-reading of the config file, no recursion is needed. * */ #include "bareos.h" #include "jcr.h" const int dbglvl = 3400; /* External variables we reference */ /* External referenced functions */ void free_bregexps(alist *bregexps); /* Forward referenced functions */ extern "C" void timeout_handler(int sig); static void jcr_timeout_check(watchdog_t *self); #ifdef TRACE_JCR_CHAIN static void b_lock_jcr_chain(const char *filen, int line); static void b_unlock_jcr_chain(const char *filen, int line); #define lock_jcr_chain() b_lock_jcr_chain(__FILE__, __LINE__); #define unlock_jcr_chain() b_unlock_jcr_chain(__FILE__, __LINE__); #else static void lock_jcr_chain(); static void unlock_jcr_chain(); #endif int num_jobs_run; dlist *last_jobs = NULL; const int max_last_jobs = 10; static dlist *jcrs = NULL; /* JCR chain */ static int watch_dog_timeout = 0; static pthread_mutex_t jcr_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t job_start_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t last_jobs_mutex = PTHREAD_MUTEX_INITIALIZER; #ifdef HAVE_WIN32 static bool tsd_initialized = false; static pthread_key_t jcr_key; /* Pointer to jcr for each thread */ #else #ifdef PTHREAD_ONCE_KEY_NP static pthread_key_t jcr_key = PTHREAD_ONCE_KEY_NP; #else static pthread_key_t jcr_key; /* Pointer to jcr for each thread */ static pthread_once_t key_once = PTHREAD_ONCE_INIT; #endif #endif static char Job_status[] = "Status Job=%s JobStatus=%d\n"; void lock_jobs() { P(job_start_mutex); } void unlock_jobs() { V(job_start_mutex); } void init_last_jobs_list() { JCR *jcr = NULL; struct s_last_job *job_entry = NULL; if (!last_jobs) { last_jobs = New(dlist(job_entry, &job_entry->link)); } if (!jcrs) { jcrs = New(dlist(jcr, &jcr->link)); } } void term_last_jobs_list() { if (last_jobs) { lock_last_jobs_list(); while (!last_jobs->empty()) { void *je = last_jobs->first(); last_jobs->remove(je); free(je); } delete last_jobs; last_jobs = NULL; unlock_last_jobs_list(); } if (jcrs) { delete jcrs; jcrs = NULL; } } bool read_last_jobs_list(int fd, uint64_t addr) { struct s_last_job *je, job; uint32_t num; bool ok = true; Dmsg1(100, "read_last_jobs seek to %d\n", (int)addr); if (addr == 0 || lseek(fd, (boffset_t)addr, SEEK_SET) < 0) { return false; } if (read(fd, &num, sizeof(num)) != sizeof(num)) { return false; } Dmsg1(100, "Read num_items=%d\n", num); if (num > 4 * max_last_jobs) { /* sanity check */ return false; } lock_last_jobs_list(); for ( ; num; num--) { if (read(fd, &job, sizeof(job)) != sizeof(job)) { berrno be; Pmsg1(000, "Read job entry. ERR=%s\n", be.bstrerror()); ok = false; break; } if (job.JobId > 0) { je = (struct s_last_job *)malloc(sizeof(struct s_last_job)); memcpy((char *)je, (char *)&job, sizeof(job)); if (!last_jobs) { init_last_jobs_list(); } last_jobs->append(je); if (last_jobs->size() > max_last_jobs) { je = (struct s_last_job *)last_jobs->first(); last_jobs->remove(je); free(je); } } } unlock_last_jobs_list(); return ok; } uint64_t write_last_jobs_list(int fd, uint64_t addr) { struct s_last_job *je; uint32_t num; ssize_t status; Dmsg1(100, "write_last_jobs seek to %d\n", (int)addr); if (lseek(fd, (boffset_t)addr, SEEK_SET) < 0) { return 0; } if (last_jobs) { lock_last_jobs_list(); /* * First record is number of entires */ num = last_jobs->size(); if (write(fd, &num, sizeof(num)) != sizeof(num)) { berrno be; Pmsg1(000, "Error writing num_items: ERR=%s\n", be.bstrerror()); goto bail_out; } foreach_dlist(je, last_jobs) { if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) { berrno be; Pmsg1(000, "Error writing job: ERR=%s\n", be.bstrerror()); goto bail_out; } } unlock_last_jobs_list(); } /* * Return current address */ status = lseek(fd, 0, SEEK_CUR); if (status < 0) { status = 0; } return status; bail_out: unlock_last_jobs_list(); return 0; } void lock_last_jobs_list() { P(last_jobs_mutex); } void unlock_last_jobs_list() { V(last_jobs_mutex); } /* * Get an ASCII representation of the Operation being performed as an english Noun */ const char *JCR::get_OperationName() { switch(m_JobType) { case JT_BACKUP: return _("Backup"); case JT_VERIFY: return _("Verifying"); case JT_RESTORE: return _("Restoring"); case JT_ARCHIVE: return _("Archiving"); case JT_COPY: return _("Copying"); case JT_MIGRATE: return _("Migration"); case JT_SCAN: return _("Scanning"); default: return _("Unknown operation"); } } /* * Get an ASCII representation of the Action being performed either an english Verb or Adjective */ const char *JCR::get_ActionName(bool past) { switch(m_JobType) { case JT_BACKUP: return _("backup"); case JT_VERIFY: return (past) ? _("verified") : _("verify"); case JT_RESTORE: return (past) ? _("restored") : _("restore"); case JT_ARCHIVE: return (past) ? _("archived") : _("archive"); case JT_COPY: return (past) ? _("copied") : _("copy"); case JT_MIGRATE: return (past) ? _("migrated") : _("migrate"); case JT_SCAN: return (past) ? _("scanned") : _("scan"); default: return _("unknown action"); } } bool JCR::JobReads() { switch (m_JobType) { case JT_VERIFY: case JT_RESTORE: case JT_COPY: case JT_MIGRATE: return true; case JT_BACKUP: if (m_JobLevel == L_VIRTUAL_FULL) { return true; } break; default: break; } return false; } /* * Push a subroutine address into the job end callback stack */ void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx) { jcr->job_end_push.append((void *)job_end_cb); jcr->job_end_push.append(ctx); } /* * Pop each job_end subroutine and call it */ static void job_end_pop(JCR *jcr) { void (*job_end_cb)(JCR *jcr, void *ctx); void *ctx; for (int i=jcr->job_end_push.size()-1; i > 0; ) { ctx = jcr->job_end_push.get(i--); job_end_cb = (void (*)(JCR *,void *))jcr->job_end_push.get(i--); job_end_cb(jcr, ctx); } } /* * Create thread key for thread specific data. */ static void create_jcr_key() { int status; #ifdef PTHREAD_ONCE_KEY_NP status = pthread_key_create_once_np(&jcr_key, NULL); #else status = pthread_key_create(&jcr_key, NULL); #endif if (status != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("pthread key create failed: ERR=%s\n"), be.bstrerror(status)); } } /* * Setup thread key for thread specific data. */ void setup_tsd_key() { #ifdef HAVE_WIN32 P(jcr_lock); if (!tsd_initialized) { create_jcr_key(); tsd_initialized = true; } V(jcr_lock); #else #ifdef PTHREAD_ONCE_KEY_NP create_jcr_key(); #else int status; status = pthread_once(&key_once, create_jcr_key); if (status != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("pthread_once failed. ERR=%s\n"), be.bstrerror(status)); } #endif #endif } /* * Create a Job Control Record and link it into JCR chain * Returns newly allocated JCR * * Note, since each daemon has a different JCR, he passes us the size. */ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr) { JCR *jcr; MQUEUE_ITEM *item = NULL; struct sigaction sigtimer; int status; Dmsg0(dbglvl, "Enter new_jcr\n"); setup_tsd_key(); jcr = (JCR *)malloc(size); memset(jcr, 0, size); jcr->msg_queue = New(dlist(item, &item->link)); if ((status = pthread_mutex_init(&jcr->msg_queue_mutex, NULL)) != 0) { berrno be; Jmsg(NULL, M_ABORT, 0, _("Could not init msg_queue mutex. ERR=%s\n"), be.bstrerror(status)); } jcr->my_thread_id = pthread_self(); jcr->job_end_push.init(1, false); jcr->sched_time = time(NULL); jcr->initial_sched_time = jcr->sched_time; jcr->daemon_free_jcr = daemon_free_jcr; /* plug daemon free routine */ jcr->init_mutex(); jcr->inc_use_count(); jcr->VolumeName = get_pool_memory(PM_FNAME); jcr->VolumeName[0] = 0; jcr->errmsg = get_pool_memory(PM_MESSAGE); jcr->errmsg[0] = 0; jcr->comment = get_pool_memory(PM_FNAME); jcr->comment[0] = 0; /* * Setup some dummy values */ bstrncpy(jcr->Job, "*System*", sizeof(jcr->Job)); jcr->JobId = 0; jcr->setJobType(JT_SYSTEM); /* internal job until defined */ jcr->setJobLevel(L_NONE); jcr->setJobStatus(JS_Created); /* ready to run */ sigtimer.sa_flags = 0; sigtimer.sa_handler = timeout_handler; sigfillset(&sigtimer.sa_mask); sigaction(TIMEOUT_SIGNAL, &sigtimer, NULL); /* * Locking jobs is a global lock that is needed * so that the Director can stop new jobs from being * added to the jcr chain while it processes a new * conf file and does the job_end_push(). */ lock_jobs(); lock_jcr_chain(); if (!jcrs) { jcrs = New(dlist(jcr, &jcr->link)); } jcrs->append(jcr); unlock_jcr_chain(); unlock_jobs(); return jcr; } /* * Remove a JCR from the chain * * NOTE! The chain must be locked prior to calling this routine. */ static void remove_jcr(JCR *jcr) { Dmsg0(dbglvl, "Enter remove_jcr\n"); if (!jcr) { Emsg0(M_ABORT, 0, _("NULL jcr.\n")); } jcrs->remove(jcr); Dmsg0(dbglvl, "Leave remove_jcr\n"); } /* * Free stuff common to all JCRs. N.B. Be careful to include only * generic stuff in the common part of the jcr. */ static void free_common_jcr(JCR *jcr) { /* * Uses jcr lock/unlock */ remove_jcr_from_tsd(jcr); jcr->set_killable(false); jcr->destroy_mutex(); if (jcr->msg_queue) { delete jcr->msg_queue; jcr->msg_queue = NULL; pthread_mutex_destroy(&jcr->msg_queue_mutex); } if (jcr->client_name) { free_pool_memory(jcr->client_name); jcr->client_name = NULL; } if (jcr->attr) { free_pool_memory(jcr->attr); jcr->attr = NULL; } if (jcr->sd_auth_key) { free(jcr->sd_auth_key); jcr->sd_auth_key = NULL; } if (jcr->VolumeName) { free_pool_memory(jcr->VolumeName); jcr->VolumeName = NULL; } if (jcr->dir_bsock) { jcr->dir_bsock->close(); delete jcr->dir_bsock; jcr->dir_bsock = NULL; } if (jcr->errmsg) { free_pool_memory(jcr->errmsg); jcr->errmsg = NULL; } if (jcr->where) { free(jcr->where); jcr->where = NULL; } if (jcr->RegexWhere) { free(jcr->RegexWhere); jcr->RegexWhere = NULL; } if (jcr->where_bregexp) { free_bregexps(jcr->where_bregexp); delete jcr->where_bregexp; jcr->where_bregexp = NULL; } if (jcr->cached_path) { free_pool_memory(jcr->cached_path); jcr->cached_path = NULL; jcr->cached_pnl = 0; } if (jcr->id_list) { free_guid_list(jcr->id_list); jcr->id_list = NULL; } if (jcr->comment) { free_pool_memory(jcr->comment); jcr->comment = NULL; } free(jcr); } /* * Global routine to free a jcr */ #ifdef DEBUG void b_free_jcr(const char *file, int line, JCR *jcr) { struct s_last_job *je; Dmsg3(dbglvl, "Enter free_jcr jid=%u from %s:%d\n", jcr->JobId, file, line); #else void free_jcr(JCR *jcr) { struct s_last_job *je; Dmsg3(dbglvl, "Enter free_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); #endif lock_jcr_chain(); jcr->dec_use_count(); /* decrement use count */ if (jcr->use_count() < 0) { Jmsg2(jcr, M_ERROR, 0, _("JCR use_count=%d JobId=%d\n"), jcr->use_count(), jcr->JobId); } if (jcr->JobId > 0) { Dmsg3(dbglvl, "Dec free_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); } if (jcr->use_count() > 0) { /* if in use */ unlock_jcr_chain(); return; } if (jcr->JobId > 0) { Dmsg3(dbglvl, "remove jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); } remove_jcr(jcr); /* remove Jcr from chain */ unlock_jcr_chain(); dequeue_messages(jcr); job_end_pop(jcr); /* pop and call hooked routines */ Dmsg1(dbglvl, "End job=%d\n", jcr->JobId); /* * Keep some statistics */ switch (jcr->getJobType()) { case JT_BACKUP: case JT_VERIFY: case JT_RESTORE: case JT_MIGRATE: case JT_COPY: case JT_ADMIN: /* * Keep list of last jobs, but not Console where JobId==0 */ if (jcr->JobId > 0) { lock_last_jobs_list(); num_jobs_run++; je = (struct s_last_job *)malloc(sizeof(struct s_last_job)); memset(je, 0, sizeof(struct s_last_job)); /* zero in case unset fields */ je->Errors = jcr->JobErrors; je->JobType = jcr->getJobType(); je->JobId = jcr->JobId; je->VolSessionId = jcr->VolSessionId; je->VolSessionTime = jcr->VolSessionTime; bstrncpy(je->Job, jcr->Job, sizeof(je->Job)); je->JobFiles = jcr->JobFiles; je->JobBytes = jcr->JobBytes; je->JobStatus = jcr->JobStatus; je->JobLevel = jcr->getJobLevel(); je->start_time = jcr->start_time; je->end_time = time(NULL); if (!last_jobs) { init_last_jobs_list(); } last_jobs->append(je); if (last_jobs->size() > max_last_jobs) { je = (struct s_last_job *)last_jobs->first(); last_jobs->remove(je); free(je); } unlock_last_jobs_list(); } break; default: break; } close_msg(jcr); /* close messages for this job */ if (jcr->daemon_free_jcr) { jcr->daemon_free_jcr(jcr); /* call daemon free routine */ } free_common_jcr(jcr); close_msg(NULL); /* flush any daemon messages */ Dmsg0(dbglvl, "Exit free_jcr\n"); } /* * Remove jcr from thread specific data, but * but make sure it is us who are attached. */ void remove_jcr_from_tsd(JCR *jcr) { JCR *tjcr = get_jcr_from_tsd(); if (tjcr == jcr) { set_jcr_in_tsd(INVALID_JCR); } } void JCR::set_killable(bool killable) { JCR *jcr = this; jcr->lock(); jcr->my_thread_killable = killable; if (killable) { jcr->my_thread_id = pthread_self(); } else { memset(&jcr->my_thread_id, 0, sizeof(jcr->my_thread_id)); } jcr->unlock(); } /* * Put this jcr in the thread specifc data * if update_thread_info is true and the jcr is valid, * we update the my_thread_id in the JCR */ void set_jcr_in_tsd(JCR *jcr) { int status; status = pthread_setspecific(jcr_key, (void *)jcr); if (status != 0) { berrno be; Jmsg1(jcr, M_ABORT, 0, _("pthread_setspecific failed: ERR=%s\n"), be.bstrerror(status)); } } void JCR::my_thread_send_signal(int sig) { this->lock(); if (this->is_killable() && !pthread_equal(this->my_thread_id, pthread_self())) { Dmsg1(800, "Send kill to jid=%d\n", this->JobId); pthread_kill(this->my_thread_id, sig); } else if (!this->is_killable()) { Dmsg1(10, "Warning, can't send kill to jid=%d\n", this->JobId); } this->unlock(); } /* * Give me the jcr that is attached to this thread */ JCR *get_jcr_from_tsd() { JCR *jcr = (JCR *)pthread_getspecific(jcr_key); /* * Set any INVALID_JCR to NULL which the rest of BAREOS understands */ if (jcr == INVALID_JCR) { jcr = NULL; } return jcr; } /* * Find which JobId corresponds to the current thread */ uint32_t get_jobid_from_tsd() { JCR *jcr; uint32_t JobId = 0; jcr = get_jcr_from_tsd(); if (jcr) { JobId = (uint32_t)jcr->JobId; } return JobId; } /* * Given a JobId, find the JCR * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_id(uint32_t JobId) { JCR *jcr; foreach_jcr(jcr) { if (jcr->JobId == JobId) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; } /* * Given a thread id, find the JobId * * Returns: JobId on success * 0 on failure */ uint32_t get_jobid_from_tid(pthread_t tid) { JCR *jcr = NULL; bool found = false; foreach_jcr(jcr) { if (pthread_equal(jcr->my_thread_id, tid)) { found = true; break; } } endeach_jcr(jcr); if (found) { return jcr->JobId; } return 0; } /* * Given a SessionId and SessionTime, find the JCR * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime) { JCR *jcr; foreach_jcr(jcr) { if (jcr->VolSessionId == SessionId && jcr->VolSessionTime == SessionTime) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; } /* * Given a Job, find the JCR compares on the number of * characters in Job thus allowing partial matches. * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_partial_name(char *Job) { JCR *jcr; int len; if (!Job) { return NULL; } len = strlen(Job); foreach_jcr(jcr) { if (bstrncmp(Job, jcr->Job, len)) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; } /* * Given a Job, find the JCR requires an exact match of names. * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_full_name(char *Job) { JCR *jcr; if (!Job) { return NULL; } foreach_jcr(jcr) { if (bstrcmp(jcr->Job, Job)) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; } static void update_wait_time(JCR *jcr, int newJobStatus) { bool enter_in_waittime; int oldJobStatus = jcr->JobStatus; switch (newJobStatus) { case JS_WaitFD: case JS_WaitSD: case JS_WaitMedia: case JS_WaitMount: case JS_WaitStoreRes: case JS_WaitJobRes: case JS_WaitClientRes: case JS_WaitMaxJobs: case JS_WaitPriority: enter_in_waittime = true; break; default: enter_in_waittime = false; /* not a Wait situation */ break; } /* * If we were previously waiting and are not any more * we want to update the wait_time variable, which is * the start of waiting. */ switch (oldJobStatus) { case JS_WaitFD: case JS_WaitSD: case JS_WaitMedia: case JS_WaitMount: case JS_WaitStoreRes: case JS_WaitJobRes: case JS_WaitClientRes: case JS_WaitMaxJobs: case JS_WaitPriority: if (!enter_in_waittime) { /* we get out the wait time */ jcr->wait_time_sum += (time(NULL) - jcr->wait_time); jcr->wait_time = 0; } break; default: /* * If wait state is new, we keep current time for watchdog MaxWaitTime */ if (enter_in_waittime) { jcr->wait_time = time(NULL); } break; } } /* * Priority runs from 0 (lowest) to 10 (highest) */ static int get_status_priority(int JobStatus) { int priority = 0; switch (JobStatus) { case JS_Incomplete: priority = 10; break; case JS_ErrorTerminated: case JS_FatalError: case JS_Canceled: priority = 9; break; case JS_Error: priority = 8; break; case JS_Differences: priority = 7; break; } return priority; } /* * Send Job status to Director */ bool JCR::sendJobStatus() { JCR *jcr = this; if (jcr->dir_bsock) { return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus); } return true; } /* * Set and send Job status to Director */ bool JCR::sendJobStatus(int newJobStatus) { JCR *jcr = this; if (!jcr->is_JobStatus(newJobStatus)) { setJobStatus(newJobStatus); if (jcr->dir_bsock) { return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus); } } return true; } void JCR::setJobStarted() { JCR *jcr = this; jcr->job_started = true; jcr->job_started_time = time(NULL); } void JCR::setJobStatus(int newJobStatus) { JCR *jcr = this; int priority, old_priority; int oldJobStatus = jcr->JobStatus; priority = get_status_priority(newJobStatus); old_priority = get_status_priority(oldJobStatus); Dmsg2(800, "set_jcr_job_status(%s, %c)\n", Job, newJobStatus); /* * Update wait_time depending on newJobStatus and oldJobStatus */ update_wait_time(jcr, newJobStatus); /* * For a set of errors, ... keep the current status * so it isn't lost. For all others, set it. */ Dmsg2(800, "OnEntry JobStatus=%c newJobstatus=%c\n", oldJobStatus, newJobStatus); /* * If status priority is > than proposed new status, change it. * If status priority == new priority and both are zero, take the new status. * If it is not zero, then we keep the first non-zero "error" that occurred. */ if (priority > old_priority || ( priority == 0 && old_priority == 0)) { Dmsg4(800, "Set new stat. old: %c,%d new: %c,%d\n", jcr->JobStatus, old_priority, newJobStatus, priority); jcr->JobStatus = newJobStatus; /* replace with new status */ } if (oldJobStatus != jcr->JobStatus) { Dmsg2(800, "leave setJobStatus old=%c new=%c\n", oldJobStatus, newJobStatus); // generate_plugin_event(jcr, bEventStatusChange, NULL); } } #ifdef TRACE_JCR_CHAIN static int lock_count = 0; #endif /* * Lock the chain */ #ifdef TRACE_JCR_CHAIN static void b_lock_jcr_chain(const char *fname, int line) #else static void lock_jcr_chain() #endif { #ifdef TRACE_JCR_CHAIN Dmsg3(dbglvl, "Lock jcr chain %d from %s:%d\n", ++lock_count, fname, line); #endif P(jcr_lock); } /* * Unlock the chain */ #ifdef TRACE_JCR_CHAIN static void b_unlock_jcr_chain(const char *fname, int line) #else static void unlock_jcr_chain() #endif { #ifdef TRACE_JCR_CHAIN Dmsg3(dbglvl, "Unlock jcr chain %d from %s:%d\n", lock_count--, fname, line); #endif V(jcr_lock); } /* * Start walk of jcr chain * The proper way to walk the jcr chain is: * JCR *jcr; * foreach_jcr(jcr) { * ... * } * endeach_jcr(jcr); * * It is possible to leave out the endeach_jcr(jcr), but * in that case, the last jcr referenced must be explicitly * released with: * * free_jcr(jcr); */ JCR *jcr_walk_start() { JCR *jcr; lock_jcr_chain(); jcr = (JCR *)jcrs->first(); if (jcr) { jcr->inc_use_count(); if (jcr->JobId > 0) { Dmsg3(dbglvl, "Inc walk_start jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); } } unlock_jcr_chain(); return jcr; } /* * Get next jcr from chain, and release current one */ JCR *jcr_walk_next(JCR *prev_jcr) { JCR *jcr; lock_jcr_chain(); jcr = (JCR *)jcrs->next(prev_jcr); if (jcr) { jcr->inc_use_count(); if (jcr->JobId > 0) { Dmsg3(dbglvl, "Inc walk_next jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); } } unlock_jcr_chain(); if (prev_jcr) { free_jcr(prev_jcr); } return jcr; } /* * Release last jcr referenced */ void jcr_walk_end(JCR *jcr) { if (jcr) { if (jcr->JobId > 0) { Dmsg3(dbglvl, "Free walk_end jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); } free_jcr(jcr); } } /* * Return number of Jobs */ int job_count() { JCR *jcr; int count = 0; lock_jcr_chain(); for (jcr = (JCR *)jcrs->first(); (jcr = (JCR *)jcrs->next(jcr)); ) { if (jcr->JobId > 0) { count++; } } unlock_jcr_chain(); return count; } /* * Setup to call the timeout check routine every 30 seconds * This routine will check any timers that have been enabled. */ bool init_jcr_subsystem(int timeout) { watchdog_t *wd = new_watchdog(); watch_dog_timeout = timeout; wd->one_shot = false; wd->interval = 30; /* FIXME: should be configurable somewhere, even if only with a #define */ wd->callback = jcr_timeout_check; register_watchdog(wd); return true; } static void jcr_timeout_check(watchdog_t *self) { JCR *jcr; BSOCK *bs; time_t timer_start; Dmsg0(dbglvl, "Start JCR timeout checks\n"); /* Walk through all JCRs checking if any one is * blocked for more than specified max time. */ foreach_jcr(jcr) { Dmsg2(dbglvl, "jcr_timeout_check JobId=%u jcr=0x%x\n", jcr->JobId, jcr); if (jcr->JobId == 0) { continue; } bs = jcr->store_bsock; if (bs) { timer_start = bs->timer_start; if (timer_start && (watchdog_time - timer_start) > watch_dog_timeout) { bs->timer_start = 0; /* turn off timer */ bs->set_timed_out(); Qmsg(jcr, M_ERROR, 0, _( "Watchdog sending kill after %d secs to thread stalled reading Storage daemon.\n"), watchdog_time - timer_start); jcr->my_thread_send_signal(TIMEOUT_SIGNAL); } } bs = jcr->file_bsock; if (bs) { timer_start = bs->timer_start; if (timer_start && (watchdog_time - timer_start) > watch_dog_timeout) { bs->timer_start = 0; /* turn off timer */ bs->set_timed_out(); Qmsg(jcr, M_ERROR, 0, _( "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n"), watchdog_time - timer_start); jcr->my_thread_send_signal(TIMEOUT_SIGNAL); } } bs = jcr->dir_bsock; if (bs) { timer_start = bs->timer_start; if (timer_start && (watchdog_time - timer_start) > watch_dog_timeout) { bs->timer_start = 0; /* turn off timer */ bs->set_timed_out(); Qmsg(jcr, M_ERROR, 0, _( "Watchdog sending kill after %d secs to thread stalled reading Director.\n"), watchdog_time - timer_start); jcr->my_thread_send_signal(TIMEOUT_SIGNAL); } } } endeach_jcr(jcr); Dmsg0(dbglvl, "Finished JCR timeout checks\n"); } /* * Return next JobId from comma separated list * * Returns: * 1 if next JobId returned * 0 if no more JobIds are in list * -1 there is an error */ int get_next_jobid_from_list(char **p, uint32_t *JobId) { const int maxlen = 30; char jobid[maxlen+1]; char *q = *p; jobid[0] = 0; for (int i=0; isize()); for (JCR *jcr = (JCR *)jcrs->first(); jcr ; jcr = (JCR *)jcrs->next(jcr)) { #ifdef HAVE_WIN32 fprintf(fp, "threadid=%p JobId=%d JobStatus=%c jcr=%p name=%s\n", (void *)&jcr->my_thread_id, (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); fprintf(fp, "threadid=%p killable=%d JobId=%d JobStatus=%c " "jcr=%p name=%s\n", (void *)&jcr->my_thread_id, jcr->is_killable(), (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); #else fprintf(fp, "threadid=%p JobId=%d JobStatus=%c jcr=%p name=%s\n", (void *)jcr->my_thread_id, (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); fprintf(fp, "threadid=%p killable=%d JobId=%d JobStatus=%c " "jcr=%p name=%s\n", (void *)jcr->my_thread_id, jcr->is_killable(), (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); #endif fprintf(fp, "\tuse_count=%i\n", jcr->use_count()); fprintf(fp, "\tJobType=%c JobLevel=%c\n", jcr->getJobType(), jcr->getJobLevel()); bstrftime(buf1, sizeof(buf1), jcr->sched_time); bstrftime(buf2, sizeof(buf2), jcr->start_time); bstrftime(buf3, sizeof(buf3), jcr->end_time); bstrftime(buf4, sizeof(buf4), jcr->wait_time); fprintf(fp, "\tsched_time=%s start_time=%s\n\tend_time=%s wait_time=%s\n", buf1, buf2, buf3, buf4); fprintf(fp, "\tdb=%p db_batch=%p batch_started=%i\n", jcr->db, jcr->db_batch, jcr->batch_started); /* * Call all the jcr debug hooks */ for(int i=0; i < dbg_jcr_handler_count; i++) { dbg_jcr_hook_t *hook = dbg_jcr_hooks[i]; hook(jcr, fp); } } } bareos-Release-14.2.6/src/lib/lex.c000066400000000000000000000614531263011562700167420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Lexical scanner for BAREOS configuration file * * Kern Sibbald, 2000 */ #include "bareos.h" #include "lex.h" extern int debug_level; /* Debug level for this source file */ static const int dbglvl = 5000; /* * Scan to "logical" end of line. I.e. end of line, * or semicolon, but stop on T_EOB (same as end of * line except it is not eaten). */ void scan_to_eol(LEX *lc) { int token; Dmsg0(dbglvl, "start scan to eof\n"); while ((token = lex_get_token(lc, T_ALL)) != T_EOL) { if (token == T_EOB) { lex_unget_char(lc); return; } } } /* * Get next token, but skip EOL */ int scan_to_next_not_eol(LEX * lc) { int token; do { token = lex_get_token(lc, T_ALL); } while (token == T_EOL); return token; } /* * Format a scanner error message */ static void s_err(const char *file, int line, LEX *lc, const char *msg, ...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_NAME), more(PM_NAME); while (1) { maxlen = buf.size() - 1; va_start(ap, msg); len = bvsnprintf(buf.c_str(), maxlen, msg, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } if (lc->err_type == 0) { /* M_ERROR_TERM by default */ lc->err_type = M_ERROR_TERM; } if (lc->line_no > lc->begin_line_no) { Mmsg(more, _("Problem probably begins at line %d.\n"), lc->begin_line_no); } else { pm_strcpy(more, ""); } if (lc->line_no > 0) { e_msg(file, line, lc->err_type, 0, _("Config error: %s\n" " : line %d, col %d of file %s\n%s\n%s"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line, more.c_str()); } else { e_msg(file, line, lc->err_type, 0, _("Config error: %s\n"), buf.c_str()); } } /* * Format a scanner warning message */ static void s_warn(const char *file, int line, LEX *lc, const char *msg, ...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_NAME), more(PM_NAME); while (1) { maxlen = buf.size() - 1; va_start(ap, msg); len = bvsnprintf(buf.c_str(), maxlen, msg, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } if (lc->line_no > lc->begin_line_no) { Mmsg(more, _("Problem probably begins at line %d.\n"), lc->begin_line_no); } else { pm_strcpy(more, ""); } if (lc->line_no > 0) { p_msg(file, line, 0, _("Config warning: %s\n" " : line %d, col %d of file %s\n%s\n%s"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line, more.c_str()); } else { p_msg(file, line, 0, _("Config warning: %s\n"), buf.c_str()); } } void lex_set_default_error_handler(LEX *lf) { lf->scan_error = s_err; } void lex_set_default_warning_handler(LEX *lf) { lf->scan_warning = s_warn; } /* * Set err_type used in error_handler * return the old value */ int lex_set_error_handler_error_type(LEX *lf, int err_type) { int old = lf->err_type; lf->err_type = err_type; return old; } /* * Free the current file, and retrieve the contents * of the previous packet if any. */ LEX *lex_close_file(LEX *lf) { LEX *of; if (lf == NULL) { Emsg0(M_ABORT, 0, _("Close of NULL file\n")); } Dmsg1(dbglvl, "Close lex file: %s\n", lf->fname); of = lf->next; if (lf->bpipe) { close_bpipe(lf->bpipe); lf->bpipe = NULL; } else { fclose(lf->fd); } Dmsg1(dbglvl, "Close cfg file %s\n", lf->fname); free(lf->fname); free_memory(lf->line); free_memory(lf->str); lf->line = NULL; if (of) { of->options = lf->options; /* preserve options */ memcpy(lf, of, sizeof(LEX)); Dmsg1(dbglvl, "Restart scan of cfg file %s\n", of->fname); } else { of = lf; lf = NULL; } free(of); return lf; } /* * Open a new configuration file. We push the * state of the current file (lf) so that we * can do includes. This is a bit of a hammer. * Instead of passing back the pointer to the * new packet, I simply replace the contents * of the caller's packet with the new packet, * and link the contents of the old packet into * the next field. * */ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error, LEX_WARNING_HANDLER *scan_warning) { LEX *nf; FILE *fd; BPIPE *bpipe = NULL; char *fname = bstrdup(filename); if (fname[0] == '|') { if ((bpipe = open_bpipe(fname+1, 0, "rb")) == NULL) { free(fname); return NULL; } fd = bpipe->rfd; } else if ((fd = fopen(fname, "rb")) == NULL) { free(fname); return NULL; } Dmsg1(400, "Open config file: %s\n", fname); nf = (LEX *)malloc(sizeof(LEX)); if (lf) { memcpy(nf, lf, sizeof(LEX)); memset(lf, 0, sizeof(LEX)); lf->next = nf; /* if have lf, push it behind new one */ lf->options = nf->options; /* preserve user options */ /* * preserve err_type to prevent bareos exiting on 'reload' * if config is invalid. Fixes bug #877 */ lf->err_type = nf->err_type; } else { lf = nf; /* start new packet */ memset(lf, 0, sizeof(LEX)); lex_set_error_handler_error_type(lf, M_ERROR_TERM); } if (scan_error) { lf->scan_error = scan_error; } else { lex_set_default_error_handler(lf); } if (scan_warning) { lf->scan_warning = scan_warning; } else { lex_set_default_warning_handler(lf); } lf->fd = fd; lf->bpipe = bpipe; lf->fname = fname; lf->line = get_memory(1024); lf->str = get_memory(256); lf->str_max_len = sizeof_pool_memory(lf->str); lf->state = lex_none; lf->ch = L_EOL; Dmsg1(dbglvl, "Return lex=%x\n", lf); return lf; } /* * Get the next character from the input. * Returns the character or * L_EOF if end of file * L_EOL if end of line */ int lex_get_char(LEX *lf) { if (lf->ch == L_EOF) { Emsg0(M_ABORT, 0, _("get_char: called after EOF." " You may have a open double quote without the closing double quote.\n")); } if (lf->ch == L_EOL) { if (bfgets(lf->line, lf->fd) == NULL) { lf->ch = L_EOF; if (lf->next) { lex_close_file(lf); } return lf->ch; } lf->line_no++; lf->col_no = 0; Dmsg2(1000, "fget line=%d %s", lf->line_no, lf->line); } lf->ch = (uint8_t)lf->line[lf->col_no]; if (lf->ch == 0) { lf->ch = L_EOL; } else { lf->col_no++; } Dmsg2(dbglvl, "lex_get_char: %c %d\n", lf->ch, lf->ch); return lf->ch; } void lex_unget_char(LEX *lf) { if (lf->ch == L_EOL) { lf->ch = 0; /* End of line, force read of next one */ } else { lf->col_no--; /* Backup to re-read char */ } } /* * Add a character to the current string */ static void add_str(LEX *lf, int ch) { /* * The default config string is sized to 256 bytes. * If we need longer config strings its increased with 256 bytes each time. */ if ((lf->str_len + 3) >= lf->str_max_len) { lf->str = check_pool_memory_size(lf->str, lf->str_max_len + 256); lf->str_max_len = sizeof_pool_memory(lf->str); } lf->str[lf->str_len++] = ch; lf->str[lf->str_len] = 0; } /* * Begin the string */ static void begin_str(LEX *lf, int ch) { lf->str_len = 0; lf->str[0] = 0; if (ch != 0) { add_str(lf, ch); } lf->begin_line_no = lf->line_no; /* save start string line no */ } #ifdef DEBUG static const char *lex_state_to_str(int state) { switch (state) { case lex_none: return _("none"); case lex_comment: return _("comment"); case lex_number: return _("number"); case lex_ip_addr: return _("ip_addr"); case lex_identifier: return _("identifier"); case lex_string: return _("string"); case lex_quoted_string: return _("quoted_string"); case lex_include: return _("include"); case lex_include_quoted_string: return _("include_quoted_string"); case lex_utf8_bom: return _("UTF-8 Byte Order Mark"); case lex_utf16_le_bom: return _("UTF-16le Byte Order Mark"); default: return "??????"; } } #endif /* * Convert a lex token to a string * used for debug/error printing. */ const char *lex_tok_to_str(int token) { switch(token) { case L_EOF: return "L_EOF"; case L_EOL: return "L_EOL"; case T_NONE: return "T_NONE"; case T_NUMBER: return "T_NUMBER"; case T_IPADDR: return "T_IPADDR"; case T_IDENTIFIER: return "T_IDENTIFIER"; case T_UNQUOTED_STRING: return "T_UNQUOTED_STRING"; case T_QUOTED_STRING: return "T_QUOTED_STRING"; case T_BOB: return "T_BOB"; case T_EOB: return "T_EOB"; case T_EQUALS: return "T_EQUALS"; case T_ERROR: return "T_ERROR"; case T_EOF: return "T_EOF"; case T_COMMA: return "T_COMMA"; case T_EOL: return "T_EOL"; case T_UTF8_BOM: return "T_UTF8_BOM"; case T_UTF16_BOM: return "T_UTF16_BOM"; default: return "??????"; } } static uint32_t scan_pint(LEX *lf, char *str) { int64_t val = 0; if (!is_a_number(str)) { scan_err1(lf, _("expected a positive integer number, got: %s"), str); /* NOT REACHED */ } else { errno = 0; val = str_to_int64(str); if (errno != 0 || val < 0) { scan_err1(lf, _("expected a positive integer number, got: %s"), str); /* NOT REACHED */ } } return (uint32_t)val; } static uint64_t scan_pint64(LEX *lf, char *str) { uint64_t val = 0; if (!is_a_number(str)) { scan_err1(lf, _("expected a positive integer number, got: %s"), str); /* NOT REACHED */ } else { errno = 0; val = str_to_uint64(str); if (errno != 0) { scan_err1(lf, _("expected a positive integer number, got: %s"), str); /* NOT REACHED */ } } return val; } /* * * Get the next token from the input * */ int lex_get_token(LEX *lf, int expect) { int ch; int token = T_NONE; bool esc_next = false; /* Unicode files, especially on Win32, may begin with a "Byte Order Mark" to indicate which transmission format the file is in. The codepoint for this mark is U+FEFF and is represented as the octets EF-BB-BF in UTF-8 and as FF-FE in UTF-16le(little endian) and FE-FF in UTF-16(big endian). We use a distinct state for UTF-8 and UTF-16le, and use bom_bytes_seen to tell which byte we are expecting. */ int bom_bytes_seen = 0; Dmsg0(dbglvl, "enter lex_get_token\n"); while (token == T_NONE) { ch = lex_get_char(lf); switch (lf->state) { case lex_none: Dmsg2(dbglvl, "Lex state lex_none ch=%d,%x\n", ch, ch); if (B_ISSPACE(ch)) break; if (B_ISALPHA(ch)) { if (lf->options & LOPT_NO_IDENT || lf->options & LOPT_STRING) { lf->state = lex_string; } else { lf->state = lex_identifier; } begin_str(lf, ch); break; } if (B_ISDIGIT(ch)) { if (lf->options & LOPT_STRING) { lf->state = lex_string; } else { lf->state = lex_number; } begin_str(lf, ch); break; } Dmsg0(dbglvl, "Enter lex_none switch\n"); switch (ch) { case L_EOF: token = T_EOF; Dmsg0(dbglvl, "got L_EOF set token=T_EOF\n"); break; case '#': lf->state = lex_comment; break; case '{': token = T_BOB; begin_str(lf, ch); break; case '}': token = T_EOB; begin_str(lf, ch); break; case '"': lf->state = lex_quoted_string; begin_str(lf, 0); break; case '=': token = T_EQUALS; begin_str(lf, ch); break; case ',': token = T_COMMA; begin_str(lf, ch); break; case ';': if (expect != T_SKIP_EOL) { token = T_EOL; /* treat ; like EOL */ } break; case L_EOL: Dmsg0(dbglvl, "got L_EOL set token=T_EOL\n"); if (expect != T_SKIP_EOL) { token = T_EOL; } break; case '@': /* In NO_EXTERN mode, @ is part of a string */ if (lf->options & LOPT_NO_EXTERN) { lf->state = lex_string; begin_str(lf, ch); } else { lf->state = lex_include; begin_str(lf, 0); } break; case 0xEF: /* probably a UTF-8 BOM */ case 0xFF: /* probably a UTF-16le BOM */ case 0xFE: /* probably a UTF-16be BOM (error)*/ if (lf->line_no != 1 || lf->col_no != 1) { lf->state = lex_string; begin_str(lf, ch); } else { bom_bytes_seen = 1; if (ch == 0xEF) { lf->state = lex_utf8_bom; } else if (ch == 0xFF) { lf->state = lex_utf16_le_bom; } else { scan_err0(lf, _("This config file appears to be in an " "unsupported Unicode format (UTF-16be). Please resave as UTF-8\n")); return T_ERROR; } } break; default: lf->state = lex_string; begin_str(lf, ch); break; } break; case lex_comment: Dmsg1(dbglvl, "Lex state lex_comment ch=%x\n", ch); if (ch == L_EOL) { lf->state = lex_none; if (expect != T_SKIP_EOL) { token = T_EOL; } } else if (ch == L_EOF) { token = T_ERROR; } break; case lex_number: Dmsg2(dbglvl, "Lex state lex_number ch=%x %c\n", ch, ch); if (ch == L_EOF) { token = T_ERROR; break; } /* Might want to allow trailing specifications here */ if (B_ISDIGIT(ch)) { add_str(lf, ch); break; } /* A valid number can be terminated by the following */ if (B_ISSPACE(ch) || ch == L_EOL || ch == ',' || ch == ';') { token = T_NUMBER; lf->state = lex_none; } else { lf->state = lex_string; } lex_unget_char(lf); break; case lex_ip_addr: if (ch == L_EOF) { token = T_ERROR; break; } Dmsg1(dbglvl, "Lex state lex_ip_addr ch=%x\n", ch); break; case lex_string: Dmsg1(dbglvl, "Lex state lex_string ch=%x\n", ch); if (ch == L_EOF) { token = T_ERROR; break; } if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' || ch == '\r' || ch == ';' || ch == ',' || ch == '#' || (B_ISSPACE(ch)) ) { lex_unget_char(lf); token = T_UNQUOTED_STRING; lf->state = lex_none; break; } add_str(lf, ch); break; case lex_identifier: Dmsg2(dbglvl, "Lex state lex_identifier ch=%x %c\n", ch, ch); if (B_ISALPHA(ch)) { add_str(lf, ch); break; } else if (B_ISSPACE(ch)) { break; } else if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' || ch == '\r' || ch == ';' || ch == ',' || ch == '"' || ch == '#') { lex_unget_char(lf); token = T_IDENTIFIER; lf->state = lex_none; break; } else if (ch == L_EOF) { token = T_ERROR; lf->state = lex_none; begin_str(lf, ch); break; } /* Some non-alpha character => string */ lf->state = lex_string; add_str(lf, ch); break; case lex_quoted_string: Dmsg2(dbglvl, "Lex state lex_quoted_string ch=%x %c\n", ch, ch); if (ch == L_EOF) { token = T_ERROR; break; } if (ch == L_EOL) { esc_next = false; break; } if (esc_next) { add_str(lf, ch); esc_next = false; break; } if (ch == '\\') { esc_next = true; break; } if (ch == '"') { token = T_QUOTED_STRING; /* * Since we may be scanning a quoted list of names, * we get the next character (a comma indicates another * one), then we put it back for rescanning. */ lex_get_char(lf); lex_unget_char(lf); lf->state = lex_none; break; } add_str(lf, ch); break; case lex_include_quoted_string: if (ch == L_EOF) { token = T_ERROR; break; } if (esc_next) { add_str(lf, ch); esc_next = false; break; } if (ch == '\\') { esc_next = true; break; } if (ch == '"') { /* Keep the original LEX so we can print an error if the included file can't be opened. */ LEX* lfori = lf; /* Skip the double quote when restarting parsing */ lex_get_char(lf); lf->state = lex_none; lf = lex_open_file(lf, lf->str, lf->scan_error, lf->scan_warning); if (lf == NULL) { berrno be; scan_err2(lfori, _("Cannot open included config file %s: %s\n"), lfori->str, be.bstrerror()); return T_ERROR; } break; } add_str(lf, ch); break; case lex_include: /* scanning a filename */ if (ch == L_EOF) { token = T_ERROR; break; } if (ch == '"') { lf->state = lex_include_quoted_string; break; } if (B_ISSPACE(ch) || ch == '\n' || ch == L_EOL || ch == '}' || ch == '{' || ch == ';' || ch == ',' || ch == '"' || ch == '#') { /* Keep the original LEX so we can print an error if the included file can't be opened. */ LEX* lfori = lf; lf->state = lex_none; lf = lex_open_file(lf, lf->str, lf->scan_error, lf->scan_warning); if (lf == NULL) { berrno be; scan_err2(lfori, _("Cannot open included config file %s: %s\n"), lfori->str, be.bstrerror()); return T_ERROR; } break; } add_str(lf, ch); break; case lex_utf8_bom: /* we only end up in this state if we have read an 0xEF as the first byte of the file, indicating we are probably reading a UTF-8 file */ if (ch == 0xBB && bom_bytes_seen == 1) { bom_bytes_seen++; } else if (ch == 0xBF && bom_bytes_seen == 2) { token = T_UTF8_BOM; lf->state = lex_none; } else { token = T_ERROR; } break; case lex_utf16_le_bom: /* we only end up in this state if we have read an 0xFF as the first byte of the file -- indicating that we are probably dealing with an Intel based (little endian) UTF-16 file*/ if (ch == 0xFE) { token = T_UTF16_BOM; lf->state = lex_none; } else { token = T_ERROR; } break; } Dmsg4(dbglvl, "ch=%d state=%s token=%s %c\n", ch, lex_state_to_str(lf->state), lex_tok_to_str(token), ch); } Dmsg2(dbglvl, "lex returning: line %d token: %s\n", lf->line_no, lex_tok_to_str(token)); lf->token = token; /* * Here is where we check to see if the user has set certain * expectations (e.g. 32 bit integer). If so, we do type checking * and possible additional scanning (e.g. for range). */ switch (expect) { case T_PINT32: lf->pint32_val = scan_pint(lf, lf->str); lf->pint32_val2 = lf->pint32_val; token = T_PINT32; break; case T_PINT32_RANGE: if (token == T_NUMBER) { lf->pint32_val = scan_pint(lf, lf->str); lf->pint32_val2 = lf->pint32_val; token = T_PINT32; } else { char *p = strchr(lf->str, '-'); if (!p) { scan_err2(lf, _("expected an integer or a range, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; break; } *p++ = 0; /* terminate first half of range */ lf->pint32_val = scan_pint(lf, lf->str); lf->pint32_val2 = scan_pint(lf, p); token = T_PINT32_RANGE; } break; case T_INT32: if (token != T_NUMBER || !is_a_number(lf->str)) { scan_err2(lf, _("expected an integer number, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; break; } errno = 0; lf->int32_val = (int32_t)str_to_int64(lf->str); if (errno != 0) { scan_err2(lf, _("expected an integer number, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; } else { token = T_INT32; } break; case T_INT64: Dmsg2(dbglvl, "int64=:%s: %f\n", lf->str, strtod(lf->str, NULL)); if (token != T_NUMBER || !is_a_number(lf->str)) { scan_err2(lf, _("expected an integer number, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; break; } errno = 0; lf->int64_val = str_to_int64(lf->str); if (errno != 0) { scan_err2(lf, _("expected an integer number, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; } else { token = T_INT64; } break; case T_PINT64_RANGE: if (token == T_NUMBER) { lf->pint64_val = scan_pint64(lf, lf->str); lf->pint64_val2 = lf->pint64_val; token = T_PINT64; } else { char *p = strchr(lf->str, '-'); if (!p) { scan_err2(lf, _("expected an integer or a range, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; break; } *p++ = 0; /* terminate first half of range */ lf->pint64_val = scan_pint64(lf, lf->str); lf->pint64_val2 = scan_pint64(lf, p); token = T_PINT64_RANGE; } break; case T_NAME: if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err2(lf, _("expected a name, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; } else if (lf->str_len > MAX_RES_NAME_LENGTH) { scan_err3(lf, _("name %s length %d too long, max is %d\n"), lf->str, lf->str_len, MAX_RES_NAME_LENGTH); token = T_ERROR; } break; case T_STRING: if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err2(lf, _("expected a string, got %s: %s"), lex_tok_to_str(token), lf->str); token = T_ERROR; } else { token = T_STRING; } break; default: break; /* no expectation given */ } lf->token = token; /* set possible new token */ return token; } bareos-Release-14.2.6/src/lib/lex.h000066400000000000000000000146161263011562700167460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * lex.h * * Lexical scanning of configuration files, used by parsers. * * Kern Sibbald, MM */ #ifndef _LEX_H #define _LEX_H /* Lex get_char() return values */ #define L_EOF (-1) #define L_EOL (-2) /* Internal tokens */ #define T_NONE 100 /* Tokens returned by get_token() */ #define T_EOF 101 #define T_NUMBER 102 #define T_IPADDR 103 #define T_IDENTIFIER 104 #define T_UNQUOTED_STRING 105 #define T_QUOTED_STRING 106 #define T_BOB 108 /* begin block */ #define T_EOB 109 /* end of block */ #define T_EQUALS 110 #define T_COMMA 111 #define T_EOL 112 #define T_ERROR 200 #define T_UTF8_BOM 201 /* File starts with a UTF-8 BOM*/ #define T_UTF16_BOM 202 /* File starts with a UTF-16LE BOM*/ /* * The following will be returned only if * the appropriate expect flag has been set */ #define T_SKIP_EOL 113 /* scan through EOLs */ #define T_PINT32 114 /* positive integer */ #define T_PINT32_RANGE 115 /* positive integer range */ #define T_INT32 116 /* integer */ #define T_INT64 117 /* 64 bit integer */ #define T_NAME 118 /* name max 128 chars */ #define T_STRING 119 /* string */ #define T_PINT64_RANGE 120 /* positive integer range */ #define T_PINT64 121 /* positive integer range */ #define T_ALL 0 /* no expectations */ /* Lexical state */ enum lex_state { lex_none, lex_comment, lex_number, lex_ip_addr, lex_identifier, lex_string, lex_quoted_string, lex_include_quoted_string, lex_include, lex_utf8_bom, /* we are parsing out a utf8 byte order mark */ lex_utf16_le_bom /* we are parsing out a utf-16 (little endian) byte order mark */ }; /* Lex scan options */ #define LOPT_NO_IDENT 0x1 /* No Identifiers -- use string */ #define LOPT_STRING 0x2 /* Force scan for string */ #define LOPT_NO_EXTERN 0x4 /* Don't follow @ command */ class BPIPE; /* forward reference */ /* Lexical context */ typedef struct s_lex_context { struct s_lex_context *next; /* pointer to next lexical context */ int options; /* scan options */ char *fname; /* filename */ FILE *fd; /* file descriptor */ POOLMEM *line; /* input line */ POOLMEM *str; /* string being scanned */ int str_len; /* length of string */ int str_max_len; /* maximum length of string */ int line_no; /* file line number */ int col_no; /* char position on line */ int begin_line_no; /* line no of beginning of string */ enum lex_state state; /* lex_state variable */ int ch; /* last char/L_VAL returned by get_char */ int token; uint32_t pint32_val; uint32_t pint32_val2; int32_t int32_val; int64_t int64_val; uint64_t pint64_val; uint64_t pint64_val2; void (*scan_error)(const char *file, int line, struct s_lex_context *lc, const char *msg, ...); void (*scan_warning)(const char *file, int line, struct s_lex_context *lc, const char *msg, ...); int err_type; /* message level for scan_error (M_..) */ void *caller_ctx; /* caller private data */ BPIPE *bpipe; /* set if we are piping */ } LEX; typedef void (LEX_ERROR_HANDLER)(const char *file, int line, LEX *lc, const char *msg, ...); typedef void (LEX_WARNING_HANDLER)(const char *file, int line, LEX *lc, const char *msg, ...); /* * Lexical scanning errors in parsing conf files */ #define scan_err0(lc, msg) \ lc->scan_error(__FILE__, __LINE__, lc, msg) #define scan_err1(lc, msg, a1) \ lc->scan_error(__FILE__, __LINE__, lc, msg, a1) #define scan_err2(lc, msg, a1, a2) \ lc->scan_error(__FILE__, __LINE__, lc, msg, a1, a2) #define scan_err3(lc, msg, a1, a2, a3) \ lc->scan_error(__FILE__, __LINE__, lc, msg, a1, a2, a3) #define scan_err4(lc, msg, a1, a2, a3, a4) \ lc->scan_error(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4) #define scan_err5(lc, msg, a1, a2, a3, a4, a5) \ lc->scan_error(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5) #define scan_err6(lc, msg, a1, a2, a3, a4, a5, a6) \ lc->scan_error(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5, a6) /* * Lexical scanning warnings in parsing conf files */ #define scan_warn0(lc, msg) \ lc->scan_warning(__FILE__, __LINE__, lc, msg) #define scan_warn1(lc, msg, a1) \ lc->scan_warning(__FILE__, __LINE__, lc, msg, a1) #define scan_warn2(lc, msg, a1, a2) \ lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2) #define scan_warn3(lc, msg, a1, a2, a3) \ lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3) #define scan_warn4(lc, msg, a1, a2, a3, a4) \ lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4) #define scan_warn5(lc, msg, a1, a2, a3, a4, a5) \ lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5) #define scan_warn6(lc, msg, a1, a2, a3, a4, a5, a6) \ lc->scan_warning(__FILE__, __LINE__, lc, msg, a1, a2, a3, a4, a5, a6) void scan_to_eol(LEX *lc); int scan_to_next_not_eol(LEX * lc); #endif /* _LEX_H */ bareos-Release-14.2.6/src/lib/lib.h000066400000000000000000000034231263011562700167160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Library includes for BAREOS lib directory * * This file contains an include for each library file * that we use within Bareos. bareos.h includes this * file and thus picks up everything we need in lib. */ #include "smartall.h" #include "lockmgr.h" #include "alist.h" #include "dlist.h" #include "rblist.h" #include "base64.h" #include "bits.h" #include "btime.h" #include "crypto.h" #include "mem_pool.h" #include "rwlock.h" #include "queue.h" #include "serial.h" #include "message.h" #include "lex.h" #include "parse_conf.h" #include "tls.h" #include "address_conf.h" #include "bsock.h" #include "bsock_tcp.h" #include "bsock_udt.h" #include "workq.h" #ifndef HAVE_FNMATCH #include "fnmatch.h" #endif #include "md5.h" #include "sha1.h" #include "tree.h" #include "watchdog.h" #include "btimers.h" #include "berrno.h" #include "bpipe.h" #include "attr.h" #include "var.h" #include "guid_to_name.h" #include "htable.h" #include "sellist.h" #include "protos.h" bareos-Release-14.2.6/src/lib/lockmgr.c000066400000000000000000000741001263011562700176010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2008-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* How to use mutex with bad order usage detection ------------------------------------------------ Note: see file mutex_list.h for current mutexes with defined priorities. Instead of using: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; P(mutex); .. V(mutex); use: bthread_mutex_t mutex = BTHREAD_MUTEX_PRIORITY(1); P(mutex); ... V(mutex); Mutex that doesn't need this extra check can be declared as pthread_mutex_t. You can use this object on pthread_mutex_lock/unlock/cond_wait/cond_timewait. With dynamic creation, you can use: bthread_mutex_t mutex; pthread_mutex_init(&mutex); bthread_mutex_set_priority(&mutex, 10); pthread_mutex_destroy(&mutex); */ #define _LOCKMGR_COMPLIANT #include "bareos.h" #undef ASSERT #define ASSERT(x) if (!(x)) { \ char *jcr = NULL; \ FPmsg3(000, _("ASSERT failed at %s:%i: %s\n"), __FILE__, __LINE__, #x); \ jcr[0] = 0; } #define ASSERT_p(x,f,l) if (!(x)) { \ char *jcr = NULL; \ FPmsg3(000, _("ASSERT failed at %s:%i: %s \n"), f, l, #x); \ jcr[0] = 0; } /* Inspired from http://www.cs.berkeley.edu/~kamil/teaching/sp03/041403.pdf This lock manager will replace some pthread calls. It can be enabled with _USE_LOCKMGR Some part of the code can't use this manager, for example the rwlock object or the smartalloc lib. To disable LMGR, just add _LOCKMGR_COMPLIANT before the inclusion of "bareos.h" cd build/src/tools g++ -g -c lockmgr.c -I.. -I../lib -D_USE_LOCKMGR -D_TEST_IT g++ -o lockmgr lockmgr.o -lbareos -L../lib/.libs -lssl -lpthread */ /* * pthread_mutex_lock for memory allocator and other * parts that are _LOCKMGR_COMPLIANT */ void lmgr_p(pthread_mutex_t *m) { int errstat; if ((errstat=pthread_mutex_lock(m))) { berrno be; e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"), be.bstrerror(errstat)); } } void lmgr_v(pthread_mutex_t *m) { int errstat; if ((errstat=pthread_mutex_unlock(m))) { berrno be; e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"), be.bstrerror(errstat)); } } #ifdef _USE_LOCKMGR typedef enum { LMGR_WHITE, /* never seen */ LMGR_BLACK, /* no loop */ LMGR_GREY /* seen before */ } lmgr_color_t; /* * Node used by the Lock Manager * If the lock is GRANTED, we have mutex -> proc, else it's a proc -> mutex * relation. * * Note, each mutex can be GRANTED once, and each proc can have only one WANTED * mutex. */ class lmgr_node_t: public SMARTALLOC { public: dlink link; void *node; void *child; lmgr_color_t seen; lmgr_node_t() { child = node = NULL; seen = LMGR_WHITE; } lmgr_node_t(void *n, void *c) { init(n,c); } void init(void *n, void *c) { node = n; child = c; seen = LMGR_WHITE; } void mark_as_seen(lmgr_color_t c) { seen = c; } ~lmgr_node_t() {printf("delete node\n");} }; typedef enum { LMGR_LOCK_EMPTY = 'E', /* unused */ LMGR_LOCK_WANTED = 'W', /* before mutex_lock */ LMGR_LOCK_GRANTED = 'G' /* after mutex_lock */ } lmgr_state_t; /* * Object associated with each mutex per thread */ class lmgr_lock_t: public SMARTALLOC { public: dlink link; void *lock; lmgr_state_t state; int max_priority; int priority; const char *file; int line; lmgr_lock_t() { lock = NULL; state = LMGR_LOCK_EMPTY; priority = max_priority = 0; } lmgr_lock_t(void *l) { lock = l; state = LMGR_LOCK_WANTED; } void set_granted() { state = LMGR_LOCK_GRANTED; } ~lmgr_lock_t() {} }; /* * Get the child list, ret must be already allocated */ static void search_all_node(dlist *g, lmgr_node_t *v, alist *ret) { lmgr_node_t *n; foreach_dlist(n, g) { if (v->child == n->node) { ret->append(n); } } } static bool visite(dlist *g, lmgr_node_t *v) { bool ret=false; lmgr_node_t *n; v->mark_as_seen(LMGR_GREY); alist *d = New(alist(5, false)); /* use alist because own=false */ search_all_node(g, v, d); //foreach_alist(n, d) { // printf("node n=%p c=%p s=%c\n", n->node, n->child, n->seen); //} foreach_alist(n, d) { if (n->seen == LMGR_GREY) { /* already seen this node */ ret = true; goto bail_out; } else if (n->seen == LMGR_WHITE) { if (visite(g, n)) { ret = true; goto bail_out; } } } v->mark_as_seen(LMGR_BLACK); /* no loop detected, node is clean */ bail_out: delete d; return ret; } static bool contains_cycle(dlist *g) { lmgr_node_t *n; foreach_dlist(n, g) { if (n->seen == LMGR_WHITE) { if (visite(g, n)) { return true; } } } return false; } /****************************************************************/ class lmgr_thread_t: public SMARTALLOC { public: dlink link; pthread_mutex_t mutex; pthread_t thread_id; lmgr_lock_t lock_list[LMGR_MAX_LOCK]; int current; int max; int max_priority; lmgr_thread_t() { int status; if ((status = pthread_mutex_init(&mutex, NULL)) != 0) { berrno be; FPmsg1(000, _("pthread key create failed: ERR=%s\n"), be.bstrerror(status)); ASSERT(0); } thread_id = pthread_self(); current = -1; max = 0; max_priority = 0; } void _dump(FILE *fp) { fprintf(fp, "threadid=%p max=%i current=%i\n", (void *)thread_id, max, current); for(int i=0; i<=current; i++) { fprintf(fp, " lock=%p state=%s priority=%i %s:%i\n", lock_list[i].lock, (lock_list[i].state=='W')?"Wanted ":"Granted", lock_list[i].priority, lock_list[i].file, lock_list[i].line); } } void dump(FILE *fp) { lmgr_p(&mutex); { _dump(fp); } lmgr_v(&mutex); } /* * Call before a lock operation (mark mutex as WANTED) */ virtual void pre_P(void *m, int priority, const char *f="*unknown*", int l=0) { int max_prio = max_priority; ASSERT_p(current < LMGR_MAX_LOCK, f, l); ASSERT_p(current >= -1, f, l); lmgr_p(&mutex); { current++; lock_list[current].lock = m; lock_list[current].state = LMGR_LOCK_WANTED; lock_list[current].file = f; lock_list[current].line = l; lock_list[current].priority = priority; lock_list[current].max_priority = MAX(priority, max_priority); max = MAX(current, max); max_priority = MAX(priority, max_priority); } lmgr_v(&mutex); ASSERT_p(!priority || priority >= max_prio, f, l); } /* * Call after the lock operation (mark mutex as GRANTED) */ virtual void post_P() { ASSERT(current >= 0); ASSERT(lock_list[current].state == LMGR_LOCK_WANTED); lock_list[current].state = LMGR_LOCK_GRANTED; } /* Using this function is some sort of bug */ void shift_list(int i) { for(int j=i+1; j<=current; j++) { lock_list[i] = lock_list[j]; } if (current >= 0) { lock_list[current].lock = NULL; lock_list[current].state = LMGR_LOCK_EMPTY; } /* rebuild the priority list */ max_priority = 0; for(int j=0; j< current; j++) { max_priority = MAX(lock_list[j].priority, max_priority); lock_list[j].max_priority = max_priority; } } /* * Remove the mutex from the list */ virtual void do_V(void *m, const char *f="*unknown*", int l=0) { ASSERT_p(current >= 0, f, l); lmgr_p(&mutex); { if (lock_list[current].lock == m) { lock_list[current].lock = NULL; lock_list[current].state = LMGR_LOCK_EMPTY; current--; } else { ASSERT(current > 0); FPmsg3(0, "ERROR: wrong P/V order search lock=%p %s:%i\n", m, f, l); FPmsg4(0, "ERROR: wrong P/V order pos=%i lock=%p %s:%i\n", current, lock_list[current].lock, lock_list[current].file, lock_list[current].line); for (int i=current-1; i >= 0; i--) { /* already seen current */ FPmsg4(0, "ERROR: wrong P/V order pos=%i lock=%p %s:%i\n", i, lock_list[i].lock, lock_list[i].file, lock_list[i].line); if (lock_list[i].lock == m) { FPmsg3(0, "ERROR: FOUND P pos=%i %s:%i\n", i, f, l); shift_list(i); current--; break; } } } /* reset max_priority to the last one */ if (current >= 0) { max_priority = lock_list[current].max_priority; } else { max_priority = 0; } } lmgr_v(&mutex); } virtual ~lmgr_thread_t() {destroy();} void destroy() { pthread_mutex_destroy(&mutex); } } ; class lmgr_dummy_thread_t: public lmgr_thread_t { void do_V(void *m, const char *file, int l) {} void post_P() {} void pre_P(void *m, int priority, const char *file, int l) {} }; /* * LMGR - Lock Manager * * * */ pthread_once_t key_lmgr_once = PTHREAD_ONCE_INIT; static pthread_key_t lmgr_key; /* used to get lgmr_thread_t object */ static dlist *global_mgr = NULL; /* used to store all lgmr_thread_t objects */ static pthread_mutex_t lmgr_global_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_t undertaker; static bool use_undertaker=true; #define lmgr_is_active() (global_mgr != NULL) /* * Add a new lmgr_thread_t object to the global list */ void lmgr_register_thread(lmgr_thread_t *item) { lmgr_p(&lmgr_global_mutex); { global_mgr->prepend(item); } lmgr_v(&lmgr_global_mutex); } /* * Call this function to cleanup specific lock thread data */ void lmgr_unregister_thread(lmgr_thread_t *item) { if (!lmgr_is_active()) { return; } lmgr_p(&lmgr_global_mutex); { global_mgr->remove(item); } lmgr_v(&lmgr_global_mutex); } /* * Search for a deadlock when it's secure to walk across * locks list. (after lmgr_detect_deadlock or a fatal signal) */ bool lmgr_detect_deadlock_unlocked() { bool ret=false; lmgr_node_t *node=NULL; lmgr_lock_t *lock; lmgr_thread_t *item; dlist *g = New(dlist(node, &node->link)); /* First, get a list of all node */ foreach_dlist(item, global_mgr) { for(int i=0; i<=item->current; i++) { node = NULL; lock = &item->lock_list[i]; /* Depending if the lock is granted or not, it's a child or a root * Granted: Mutex -> Thread * Wanted: Thread -> Mutex * * Note: a Mutex can be locked only once, a thread can request only * one mutex. * */ if (lock->state == LMGR_LOCK_GRANTED) { node = New(lmgr_node_t((void*)lock->lock, (void*)item->thread_id)); } else if (lock->state == LMGR_LOCK_WANTED) { node = New(lmgr_node_t((void*)item->thread_id, (void*)lock->lock)); } if (node) { g->append(node); } } } //foreach_dlist(node, g) { // printf("g n=%p c=%p\n", node->node, node->child); //} ret = contains_cycle(g); if (ret) { printf("Found a deadlock !!!!\n"); } delete g; return ret; } /* * Search for a deadlock in during the runtime * It will lock all thread specific lock manager, nothing * can be locked during this check. */ bool lmgr_detect_deadlock() { bool ret=false; if (!lmgr_is_active()) { return ret; } lmgr_p(&lmgr_global_mutex); { lmgr_thread_t *item; foreach_dlist(item, global_mgr) { lmgr_p(&item->mutex); } ret = lmgr_detect_deadlock_unlocked(); foreach_dlist(item, global_mgr) { lmgr_v(&item->mutex); } } lmgr_v(&lmgr_global_mutex); return ret; } /* * !!! WARNING !!! * Use this function is used only after a fatal signal * We don't use locking to display the information */ void dbg_print_lock(FILE *fp) { fprintf(fp, "Attempt to dump locks\n"); if (!lmgr_is_active()) { return ; } lmgr_thread_t *item; foreach_dlist(item, global_mgr) { item->_dump(fp); } } /* * Dump each lmgr_thread_t object */ void lmgr_dump() { lmgr_p(&lmgr_global_mutex); { lmgr_thread_t *item; foreach_dlist(item, global_mgr) { item->dump(stderr); } } lmgr_v(&lmgr_global_mutex); } void cln_hdl(void *a) { lmgr_cleanup_thread(); } void *check_deadlock(void *) { int old; lmgr_init_thread(); pthread_cleanup_push(cln_hdl, NULL); while (!bmicrosleep(30, 0)) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old); if (lmgr_detect_deadlock()) { lmgr_dump(); ASSERT(0); } pthread_setcancelstate(old, NULL); pthread_testcancel(); } pthread_cleanup_pop(1); return NULL; } /* This object is used when LMGR is not initialized */ static lmgr_dummy_thread_t dummy_lmgr; /* * Retrieve the lmgr_thread_t object from the stack */ inline lmgr_thread_t *lmgr_get_thread_info() { if (lmgr_is_active()) { return (lmgr_thread_t *)pthread_getspecific(lmgr_key); } else { return &dummy_lmgr; } } /* * launch once for all threads */ void create_lmgr_key() { int status = pthread_key_create(&lmgr_key, NULL); if (status != 0) { berrno be; FPmsg1(000, _("pthread key create failed: ERR=%s\n"), be.bstrerror(status)); ASSERT(0); } lmgr_thread_t *n=NULL; global_mgr = New(dlist(n, &n->link)); if (use_undertaker) { status = pthread_create(&undertaker, NULL, check_deadlock, NULL); if (status != 0) { berrno be; FPmsg1(000, _("pthread_create failed: ERR=%s\n"), be.bstrerror(status)); ASSERT(0); } } } /* * Each thread have to call this function to put a lmgr_thread_t object * in the stack and be able to call mutex_lock/unlock */ void lmgr_init_thread() { int status = pthread_once(&key_lmgr_once, create_lmgr_key); if (status != 0) { berrno be; FPmsg1(000, _("pthread key create failed: ERR=%s\n"), be.bstrerror(status)); ASSERT(0); } lmgr_thread_t *l = New(lmgr_thread_t()); pthread_setspecific(lmgr_key, l); lmgr_register_thread(l); } /* * Call this function at the end of the thread */ void lmgr_cleanup_thread() { if (!lmgr_is_active()) { return ; } lmgr_thread_t *self = lmgr_get_thread_info(); lmgr_unregister_thread(self); delete(self); } /* * This function should be call at the end of the main thread * Some thread like the watchdog are already present, so the global_mgr * list is never empty. Should carefully clear the memory. */ void lmgr_cleanup_main() { dlist *temp; if (!global_mgr) { return; } if (use_undertaker) { pthread_cancel(undertaker); } lmgr_cleanup_thread(); lmgr_p(&lmgr_global_mutex); { temp = global_mgr; global_mgr = NULL; delete temp; } lmgr_v(&lmgr_global_mutex); } /* * Set the priority of the lmgr mutex object */ void bthread_mutex_set_priority(bthread_mutex_t *m, int prio) { #ifdef USE_LOCKMGR_PRIORITY m->priority = prio; #endif } /* * Replacement for pthread_mutex_init() */ int pthread_mutex_init(bthread_mutex_t *m, const pthread_mutexattr_t *attr) { m->priority = 0; return pthread_mutex_init(&m->mutex, attr); } /* * Replacement for pthread_mutex_destroy() */ int pthread_mutex_destroy(bthread_mutex_t *m) { return pthread_mutex_destroy(&m->mutex); } /* * Replacement for pthread_kill (only with USE_LOCKMGR_SAFEKILL) */ int bthread_kill(pthread_t thread, int sig, const char *file, int line) { bool thread_found_in_process=false; /* We doesn't allow to send signal to ourself */ ASSERT(!pthread_equal(thread, pthread_self())); /* This loop isn't very efficient with dozens of threads but we don't use * signal very much, and this feature is for testing only */ lmgr_p(&lmgr_global_mutex); { lmgr_thread_t *item; foreach_dlist(item, global_mgr) { if (pthread_equal(thread, item->thread_id)) { thread_found_in_process=true; break; } } } lmgr_v(&lmgr_global_mutex); /* Sending a signal to non existing thread can create problem * so, we can stop here. */ ASSERT(thread_found_in_process == true); return pthread_kill(thread, sig); } /* * Replacement for pthread_mutex_lock() * Returns always ok */ int bthread_mutex_lock_p(bthread_mutex_t *m, const char *file, int line) { lmgr_thread_t *self = lmgr_get_thread_info(); self->pre_P(m, m->priority, file, line); lmgr_p(&m->mutex); self->post_P(); return 0; } /* * Replacement for pthread_mutex_unlock() * Returns always ok */ int bthread_mutex_unlock_p(bthread_mutex_t *m, const char *file, int line) { lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m, file, line); lmgr_v(&m->mutex); return 0; } /* * Replacement for pthread_mutex_lock() but with real pthread_mutex_t * Returns always ok */ int bthread_mutex_lock_p(pthread_mutex_t *m, const char *file, int line) { lmgr_thread_t *self = lmgr_get_thread_info(); self->pre_P(m, 0, file, line); lmgr_p(m); self->post_P(); return 0; } /* * Replacement for pthread_mutex_unlock() but with real pthread_mutex_t * Returns always ok */ int bthread_mutex_unlock_p(pthread_mutex_t *m, const char *file, int line) { lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m, file, line); lmgr_v(m); return 0; } /* TODO: check this */ int bthread_cond_wait_p(pthread_cond_t *cond, pthread_mutex_t *m, const char *file, int line) { int ret; lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m, file, line); ret = pthread_cond_wait(cond, m); self->pre_P(m, 0, file, line); self->post_P(); return ret; } /* TODO: check this */ int bthread_cond_timedwait_p(pthread_cond_t *cond, pthread_mutex_t *m, const struct timespec * abstime, const char *file, int line) { int ret; lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m, file, line); ret = pthread_cond_timedwait(cond, m, abstime); self->pre_P(m, 0, file, line); self->post_P(); return ret; } /* TODO: check this */ int bthread_cond_wait_p(pthread_cond_t *cond, bthread_mutex_t *m, const char *file, int line) { int ret; lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m, file, line); ret = pthread_cond_wait(cond, &m->mutex); self->pre_P(m, m->priority, file, line); self->post_P(); return ret; } /* TODO: check this */ int bthread_cond_timedwait_p(pthread_cond_t *cond, bthread_mutex_t *m, const struct timespec * abstime, const char *file, int line) { int ret; lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m, file, line); ret = pthread_cond_timedwait(cond, &m->mutex, abstime); self->pre_P(m, m->priority, file, line); self->post_P(); return ret; } /* Test if this mutex is locked by the current thread * returns: * 0 - unlocked * 1 - locked by the current thread * 2 - locked by an other thread */ int lmgr_mutex_is_locked(void *m) { lmgr_thread_t *self = lmgr_get_thread_info(); for(int i=0; i <= self->current; i++) { if (self->lock_list[i].lock == m) { return 1; /* locked by us */ } } return 0; /* not locked by us */ } /* * Use this function when the caller handle the mutex directly * * lmgr_pre_lock(m, 10); * pthread_mutex_lock(m); * lmgr_post_lock(m); */ void lmgr_pre_lock(void *m, int prio, const char *file, int line) { lmgr_thread_t *self = lmgr_get_thread_info(); self->pre_P(m, prio, file, line); } /* * Use this function when the caller handle the mutex directly */ void lmgr_post_lock() { lmgr_thread_t *self = lmgr_get_thread_info(); self->post_P(); } /* * Do directly pre_P and post_P (used by trylock) */ void lmgr_do_lock(void *m, int prio, const char *file, int line) { lmgr_thread_t *self = lmgr_get_thread_info(); self->pre_P(m, prio, file, line); self->post_P(); } /* * Use this function when the caller handle the mutex directly */ void lmgr_do_unlock(void *m) { lmgr_thread_t *self = lmgr_get_thread_info(); self->do_V(m); } typedef struct { void *(*start_routine)(void*); void *arg; } lmgr_thread_arg_t; extern "C" void *lmgr_thread_launcher(void *x) { void *ret=NULL; lmgr_init_thread(); pthread_cleanup_push(cln_hdl, NULL); lmgr_thread_arg_t arg; lmgr_thread_arg_t *a = (lmgr_thread_arg_t *)x; arg.start_routine = a->start_routine; arg.arg = a->arg; free(a); ret = arg.start_routine(arg.arg); pthread_cleanup_pop(1); return ret; } int lmgr_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) { /* lmgr should be active (lmgr_init_thread() call in main()) */ ASSERT(lmgr_is_active()); /* Will be freed by the child */ lmgr_thread_arg_t *a = (lmgr_thread_arg_t*) malloc(sizeof(lmgr_thread_arg_t)); a->start_routine = start_routine; a->arg = arg; return pthread_create(thread, attr, lmgr_thread_launcher, a); } #else /* _USE_LOCKMGR */ /* * !!! WARNING !!! * Use this function is used only after a fatal signal * We don't use locking to display information */ void dbg_print_lock(FILE *fp) { FPmsg0(000, "lockmgr disabled\n"); } #endif /* _USE_LOCKMGR */ #ifdef _TEST_IT #include "lockmgr.h" #undef P #undef V #define P(x) bthread_mutex_lock_p(&(x), __FILE__, __LINE__) #define V(x) bthread_mutex_unlock_p(&(x), __FILE__, __LINE__) #define pthread_create(a, b, c, d) lmgr_thread_create(a,b,c,d) bthread_mutex_t mutex1 = BTHREAD_MUTEX_NO_PRIORITY; bthread_mutex_t mutex2 = BTHREAD_MUTEX_NO_PRIORITY; bthread_mutex_t mutex3 = BTHREAD_MUTEX_NO_PRIORITY; bthread_mutex_t mutex4 = BTHREAD_MUTEX_NO_PRIORITY; bthread_mutex_t mutex5 = BTHREAD_MUTEX_NO_PRIORITY; bthread_mutex_t mutex6 = BTHREAD_MUTEX_NO_PRIORITY; bthread_mutex_t mutex_p1 = BTHREAD_MUTEX_PRIORITY(1); bthread_mutex_t mutex_p2 = BTHREAD_MUTEX_PRIORITY(2); bthread_mutex_t mutex_p3 = BTHREAD_MUTEX_PRIORITY(3); static const char *my_prog; void *self_lock(void *temp) { P(mutex1); P(mutex1); V(mutex1); return NULL; } void *nolock(void *temp) { P(mutex2); sleep(5); V(mutex2); return NULL; } void *locker(void *temp) { bthread_mutex_t *m = (bthread_mutex_t*) temp; P(*m); V(*m); return NULL; } void *rwlocker(void *temp) { brwlock_t *m = (brwlock_t*) temp; rwl_writelock(m); rwl_writelock(m); rwl_writeunlock(m); rwl_writeunlock(m); return NULL; } void *mix_rwl_mutex(void *temp) { brwlock_t *m = (brwlock_t*) temp; P(mutex1); rwl_writelock(m); rwl_writeunlock(m); V(mutex1); return NULL; } void *th2(void *temp) { P(mutex2); P(mutex1); lmgr_dump(); sleep(10); V(mutex1); V(mutex2); lmgr_dump(); return NULL; } void *th1(void *temp) { P(mutex1); sleep(2); P(mutex2); lmgr_dump(); sleep(10); V(mutex2); V(mutex1); lmgr_dump(); return NULL; } void *thx(void *temp) { int s= 1 + (int) (500.0 * (rand() / (RAND_MAX + 1.0))) + 200; P(mutex1); bmicrosleep(0,s); P(mutex2); bmicrosleep(0,s); V(mutex2); V(mutex1); return NULL; } void *th3(void *a) { while (1) { fprintf(stderr, "undertaker sleep()\n"); sleep(10); lmgr_dump(); if (lmgr_detect_deadlock()) { lmgr_dump(); exit(1); } } return NULL; } void *th_prio(void *a) { char buf[512]; bstrncpy(buf, my_prog, sizeof(buf)); bstrncat(buf, " priority", sizeof(buf)); int ret = system(buf); return (void*) ret; } int err=0; int nb=0; void _ok(const char *file, int l, const char *op, int value, const char *label) { nb++; if (!value) { err++; printf("ERR %.30s %s:%i on %s\n", label, file, l, op); } else { printf("OK %.30s\n", label); } } #define ok(x, label) _ok(__FILE__, __LINE__, #x, (x), label) void _nok(const char *file, int l, const char *op, int value, const char *label) { nb++; if (value) { err++; printf("ERR %.30s %s:%i on !%s\n", label, file, l, op); } else { printf("OK %.30s\n", label); } } #define nok(x, label) _nok(__FILE__, __LINE__, #x, (x), label) int report() { printf("Result %i/%i OK\n", nb - err, nb); return err>0; } /* * TODO: * - Must detect multiple lock * - lock/unlock in wrong order * - deadlock with 2 or 3 threads */ int main(int argc, char **argv) { void *ret=NULL; lmgr_thread_t *self; pthread_t id1, id2, id3, tab[200]; bthread_mutex_t bmutex1; pthread_mutex_t pmutex2; my_prog = argv[0]; use_undertaker = false; lmgr_init_thread(); self = lmgr_get_thread_info(); if (argc == 2) { /* do priority check */ P(mutex_p2); /* not permited */ P(mutex_p1); V(mutex_p1); /* never goes here */ V(mutex_p2); return 0; } pthread_mutex_init(&bmutex1, NULL); bthread_mutex_set_priority(&bmutex1, 10); pthread_mutex_init(&pmutex2, NULL); P(bmutex1); ok(self->max_priority == 10, "Check self max_priority"); P(pmutex2); ok(bmutex1.priority == 10, "Check bmutex_set_priority()"); V(pmutex2); V(bmutex1); ok(self->max_priority == 0, "Check self max_priority"); pthread_create(&id1, NULL, self_lock, NULL); sleep(2); ok(lmgr_detect_deadlock(), "Check self deadlock"); lmgr_v(&mutex1.mutex); /* a bit dirty */ pthread_join(id1, NULL); pthread_create(&id1, NULL, nolock, NULL); sleep(2); nok(lmgr_detect_deadlock(), "Check for nolock"); pthread_join(id1, NULL); P(mutex1); pthread_create(&id1, NULL, locker, &mutex1); pthread_create(&id2, NULL, locker, &mutex1); pthread_create(&id3, NULL, locker, &mutex1); sleep(2); nok(lmgr_detect_deadlock(), "Check for multiple lock"); V(mutex1); pthread_join(id1, NULL); pthread_join(id2, NULL); pthread_join(id3, NULL); brwlock_t wr; rwl_init(&wr); rwl_writelock(&wr); rwl_writelock(&wr); pthread_create(&id1, NULL, rwlocker, &wr); pthread_create(&id2, NULL, rwlocker, &wr); pthread_create(&id3, NULL, rwlocker, &wr); nok(lmgr_detect_deadlock(), "Check for multiple rwlock"); rwl_writeunlock(&wr); nok(lmgr_detect_deadlock(), "Check for simple rwlock"); rwl_writeunlock(&wr); nok(lmgr_detect_deadlock(), "Check for multiple rwlock"); pthread_join(id1, NULL); pthread_join(id2, NULL); pthread_join(id3, NULL); rwl_writelock(&wr); P(mutex1); pthread_create(&id1, NULL, mix_rwl_mutex, &wr); nok(lmgr_detect_deadlock(), "Check for mix rwlock/mutex"); V(mutex1); nok(lmgr_detect_deadlock(), "Check for mix rwlock/mutex"); rwl_writeunlock(&wr); nok(lmgr_detect_deadlock(), "Check for mix rwlock/mutex"); pthread_join(id1, NULL); P(mutex5); P(mutex6); V(mutex5); V(mutex6); nok(lmgr_detect_deadlock(), "Check for wrong order"); for(int j=0; j<200; j++) { pthread_create(&tab[j], NULL, thx, NULL); } for(int j=0; j<200; j++) { pthread_join(tab[j], NULL); if (j%3) { lmgr_detect_deadlock();} } nok(lmgr_detect_deadlock(), "Check 200 lockers"); P(mutex4); P(mutex5); P(mutex6); ok(lmgr_mutex_is_locked(&mutex6) == 1, "Check if mutex is locked"); V(mutex6); ok(lmgr_mutex_is_locked(&mutex6) == 0, "Check if mutex is locked"); V(mutex5); V(mutex4); pthread_create(&id1, NULL, th1, NULL); sleep(1); pthread_create(&id2, NULL, th2, NULL); sleep(1); ok(lmgr_detect_deadlock(), "Check for deadlock"); pthread_create(&id3, NULL, th_prio, NULL); pthread_join(id3, &ret); ok(ret != 0, "Check for priority segfault"); P(mutex_p1); ok(self->max_priority == 1, "Check max_priority 1/4"); P(mutex_p2); ok(self->max_priority == 2, "Check max_priority 2/4"); P(mutex_p3); ok(self->max_priority == 3, "Check max_priority 3/4"); P(mutex6); ok(self->max_priority == 3, "Check max_priority 4/4"); V(mutex6); ok(self->max_priority == 3, "Check max_priority 1/5"); V(mutex_p3); ok(self->max_priority == 2, "Check max_priority 4/5"); V(mutex_p2); ok(self->max_priority == 1, "Check max_priority 4/5"); V(mutex_p1); ok(self->max_priority == 0, "Check max_priority 5/5"); P(mutex_p1); P(mutex_p2); P(mutex_p3); P(mutex6); ok(self->max_priority == 3, "Check max_priority mixed"); V(mutex_p2); ok(self->max_priority == 3, "Check max_priority mixed"); V(mutex_p1); ok(self->max_priority == 3, "Check max_priority mixed"); V(mutex_p3); ok(self->max_priority == 0, "Check max_priority mixed"); V(mutex6); ok(self->max_priority == 0, "Check max_priority mixed"); P(mutex_p1); P(mutex_p2); V(mutex_p1); V(mutex_p2); // lmgr_dump(); // // pthread_create(&id3, NULL, th3, NULL); // // pthread_join(id1, NULL); // pthread_join(id2, NULL); lmgr_cleanup_main(); sm_check(__FILE__, __LINE__, false); return report(); } #endif bareos-Release-14.2.6/src/lib/lockmgr.h000066400000000000000000000162201263011562700176050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2008-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _LOCKMGR_H #define _LOCKMGR_H 1 #include "mutex_list.h" /* Manage mutex with priority in a central place */ /* * P and V op that don't use the lock manager (for memory allocation or on win32) */ void lmgr_p(pthread_mutex_t *m); void lmgr_v(pthread_mutex_t *m); #ifdef _USE_LOCKMGR typedef struct bthread_mutex_t { pthread_mutex_t mutex; int priority; } bthread_mutex_t; /* * We decide that a thread won't lock more than LMGR_MAX_LOCK at the same time */ #define LMGR_MAX_LOCK 32 int bthread_cond_wait_p(pthread_cond_t *cond, bthread_mutex_t *mutex, const char *file="*unknown*", int line=0); int bthread_cond_timedwait_p(pthread_cond_t *cond, bthread_mutex_t *mutex, const struct timespec * abstime, const char *file="*unknown*", int line=0); /* * Same with real pthread_mutex_t */ int bthread_cond_wait_p(pthread_cond_t *cond, pthread_mutex_t *mutex, const char *file="*unknown*", int line=0); int bthread_cond_timedwait_p(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec * abstime, const char *file="*unknown*", int line=0); /* * Replacement of pthread_mutex_lock() but with real pthread_mutex_t */ int bthread_mutex_lock_p(pthread_mutex_t *m, const char *file="*unknown*", int line=0); /* * Replacement for pthread_mutex_unlock() but with real pthread_mutex_t */ int bthread_mutex_unlock_p(pthread_mutex_t *m, const char *file="*unknown*", int line=0); /* * Replacement of pthread_mutex_lock() */ int bthread_mutex_lock_p(bthread_mutex_t *m, const char *file="*unknown*", int line=0); /* * Replacement of pthread_mutex_unlock() */ int bthread_mutex_unlock_p(bthread_mutex_t *m, const char *file="*unknown*", int line=0); /* * Test if this mutex is locked by the current thread * 0 - not locked by the current thread * 1 - locked by the current thread */ int lmgr_mutex_is_locked(void *m); /* * Use them when you want use your lock yourself (ie rwlock) */ /* * Call before requesting the lock */ void lmgr_pre_lock(void *m, int prio=0, const char *file="*unknown*", int line=0); /* * Call after getting it */ void lmgr_post_lock(); /* * Same as pre+post lock */ void lmgr_do_lock(void *m, int prio=0, const char *file="*unknown*", int line=0); /* * Call just before releasing the lock */ void lmgr_do_unlock(void *m); /* * We use C++ mangling to make integration eaysier */ int pthread_mutex_init(bthread_mutex_t *m, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(bthread_mutex_t *m); void bthread_mutex_set_priority(bthread_mutex_t *m, int prio); /* * Each thread have to call this function to put a lmgr_thread_t object * in the stack and be able to call mutex_lock/unlock */ void lmgr_init_thread(); /* * Call this function at the end of the thread */ void lmgr_cleanup_thread(); /* * Call this at the end of the program, it will release the * global lock manager */ void lmgr_cleanup_main(); /* * Dump each lmgr_thread_t object to stdout */ void lmgr_dump(); /* * Search a deadlock */ bool lmgr_detect_deadlock(); /* * Search a deadlock after a fatal signal no lock are granted, so the program must be stopped. */ bool lmgr_detect_deadlock_unlocked(); /* * This function will run your thread with lmgr_init_thread() and lmgr_cleanup_thread(). */ int lmgr_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); /* * Can use SAFEKILL to check if the argument is a valid threadid */ int bthread_kill(pthread_t thread, int sig, const char *file="*unknown*", int line=0); #define BTHREAD_MUTEX_NO_PRIORITY {PTHREAD_MUTEX_INITIALIZER, 0} #define BTHREAD_MUTEX_INITIALIZER BTHREAD_MUTEX_NO_PRIORITY /* * Define USE_LOCKMGR_PRIORITY to detect mutex wrong order */ #ifdef USE_LOCKMGR_PRIORITY #define BTHREAD_MUTEX_PRIORITY(p) { PTHREAD_MUTEX_INITIALIZER, p } #else #define BTHREAD_MUTEX_PRIORITY(p) BTHREAD_MUTEX_NO_PRIORITY #endif #define bthread_mutex_lock(x) bthread_mutex_lock_p(x, __FILE__, __LINE__) #define bthread_mutex_unlock(x) bthread_mutex_unlock_p(x, __FILE__, __LINE__) #define bthread_cond_wait(x,y) bthread_cond_wait_p(x,y, __FILE__, __LINE__) #define bthread_cond_timedwait(x,y,z) bthread_cond_timedwait_p(x,y,z, __FILE__, __LINE__) /* * Define _LOCKMGR_COMPLIANT to use real pthread functions */ #ifdef _LOCKMGR_COMPLIANT #define P(x) lmgr_p(&(x)) #define V(x) lmgr_v(&(x)) #else #define P(x) bthread_mutex_lock_p(&(x), __FILE__, __LINE__) #define V(x) bthread_mutex_unlock_p(&(x), __FILE__, __LINE__) #define pthread_create(a,b,c,d) lmgr_thread_create(a,b,c,d) #define pthread_mutex_lock(x) bthread_mutex_lock(x) #define pthread_mutex_unlock(x) bthread_mutex_unlock(x) #define pthread_cond_wait(x,y) bthread_cond_wait(x,y) #define pthread_cond_timedwait(x,y,z) bthread_cond_timedwait(x,y,z) #ifdef USE_LOCKMGR_SAFEKILL #define pthread_kill(a,b) bthread_kill((a),(b), __FILE__, __LINE__) #endif #endif #else /* _USE_LOCKMGR */ #define lmgr_detect_deadloc() #define lmgr_dump() #define lmgr_init_thread() #define lmgr_cleanup_thread() #define lmgr_pre_lock(m,prio,f,l) #define lmgr_post_lock() #define lmgr_do_lock(m,prio,f,l) #define lmgr_do_unlock(m) #define lmgr_cleanup_main() #define bthread_mutex_set_priority(a,b) #define bthread_mutex_lock(a) pthread_mutex_lock(a) #define bthread_mutex_lock_p(a,f,l) pthread_mutex_lock(a) #define bthread_mutex_unlock(a) pthread_mutex_unlock(a) #define bthread_mutex_unlock_p(a,f,l) pthread_mutex_unlock(a) #define lmgr_cond_wait(a,b) pthread_cond_wait(a,b) #define lmgr_cond_timedwait(a,b,c) pthread_cond_timedwait(a,b,c) #define bthread_mutex_t pthread_mutex_t #define P(x) lmgr_p(&(x)) #define V(x) lmgr_v(&(x)) #define BTHREAD_MUTEX_PRIORITY(p) PTHREAD_MUTEX_INITIALIZER #define BTHREAD_MUTEX_NO_PRIORITY PTHREAD_MUTEX_INITIALIZER #define BTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define lmgr_mutex_is_locked(m) (1) #define bthread_cond_wait_p(w,x,y,z) pthread_cond_wait(w,x) #endif /* _USE_LOCKMGR */ #endif /* _LOCKMGR_H */ bareos-Release-14.2.6/src/lib/md5.c000066400000000000000000000206501263011562700166310ustar00rootroot00000000000000/* * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. * MD5 Message-Digest Algorithm (RFC 1321). * * Homepage: * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 * * Author: * Alexander Peslyak, better known as Solar Designer * * This software was written by Alexander Peslyak in 2001. No copyright is * claimed, and the software is hereby placed in the public domain. * In case this attempt to disclaim copyright and place the software in the * public domain is deemed null and void, then the software is * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the * general public under the following terms: * * Redistribution and use in source and binary forms, with or without * modification, are permitted. * * There's ABSOLUTELY NO WARRANTY, express or implied. * * (This is a heavily cut-down "BSD license".) * * This differs from Colin Plumb's older public domain implementation in that * no exactly 32-bit integer data type is required (any 32-bit or wider * unsigned integer data type will do), there's no compile-time endianness * configuration, and the function prototypes match OpenSSL's. No code from * Colin Plumb's implementation has been reused; this comment merely compares * the properties of the two independent implementations. * * The primary goals of this implementation are portability and ease of use. * It is meant to be fast, but not as fast as possible. Some known * optimizations are not included to reduce source code size and avoid * compile-time configuration. */ #include "bareos.h" #if !defined(HAVE_OPENSSL) || defined(HAVE_WIN32) #include "md5.h" /* * The basic MD5 functions. * * F and G are optimized compared to their RFC 1321 definitions for * architectures that lack an AND-NOT instruction, just like in Colin Plumb's * implementation. */ #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) #define H(x, y, z) (((x) ^ (y)) ^ (z)) #define H2(x, y, z) ((x) ^ ((y) ^ (z))) #define I(x, y, z) ((y) ^ ((x) | ~(z))) /* * The MD5 transformation for all four rounds. */ #define STEP(f, a, b, c, d, x, t, s) \ (a) += f((b), (c), (d)) + (x) + (t); \ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ (a) += (b); /* * SET reads 4 input bytes in little-endian byte order and stores them * in a properly aligned word in host byte order. * * The check for little-endian architectures that tolerate unaligned * memory accesses is just an optimization. Nothing will break if it * doesn't work. */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) #define SET(n) \ (*(MD5_u32plus *)&ptr[(n) * 4]) #define GET(n) \ SET(n) #else #define SET(n) \ (ctx->block[(n)] = \ (MD5_u32plus)ptr[(n) * 4] | \ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) #define GET(n) \ (ctx->block[(n)]) #endif /* * This processes one or more 64-byte data blocks, but does NOT update * the bit counters. There are no alignment requirements. */ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) { const unsigned char *ptr; MD5_u32plus a, b, c, d; MD5_u32plus saved_a, saved_b, saved_c, saved_d; ptr = (const unsigned char *)data; a = ctx->a; b = ctx->b; c = ctx->c; d = ctx->d; do { saved_a = a; saved_b = b; saved_c = c; saved_d = d; /* Round 1 */ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) STEP(F, c, d, a, b, SET(2), 0x242070db, 17) STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) /* Round 2 */ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) STEP(G, d, a, b, c, GET(10), 0x02441453, 9) STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) /* Round 3 */ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) /* Round 4 */ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) a += saved_a; b += saved_b; c += saved_c; d += saved_d; ptr += 64; } while (size -= 64); ctx->a = a; ctx->b = b; ctx->c = c; ctx->d = d; return ptr; } void MD5_Init(MD5_CTX *ctx) { ctx->a = 0x67452301; ctx->b = 0xefcdab89; ctx->c = 0x98badcfe; ctx->d = 0x10325476; ctx->lo = 0; ctx->hi = 0; } void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) { MD5_u32plus saved_lo; unsigned long used, available; saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++; ctx->hi += size >> 29; used = saved_lo & 0x3f; if (used) { available = 64 - used; if (size < available) { memcpy(&ctx->buffer[used], data, size); return; } memcpy(&ctx->buffer[used], data, available); data = (const unsigned char *)data + available; size -= available; body(ctx, ctx->buffer, 64); } if (size >= 64) { data = body(ctx, data, size & ~(unsigned long)0x3f); size &= 0x3f; } memcpy(ctx->buffer, data, size); } void MD5_Final(unsigned char *result, MD5_CTX *ctx) { unsigned long used, available; used = ctx->lo & 0x3f; ctx->buffer[used++] = 0x80; available = 64 - used; if (available < 8) { memset(&ctx->buffer[used], 0, available); body(ctx, ctx->buffer, 64); used = 0; available = 64; } memset(&ctx->buffer[used], 0, available - 8); ctx->lo <<= 3; ctx->buffer[56] = ctx->lo; ctx->buffer[57] = ctx->lo >> 8; ctx->buffer[58] = ctx->lo >> 16; ctx->buffer[59] = ctx->lo >> 24; ctx->buffer[60] = ctx->hi; ctx->buffer[61] = ctx->hi >> 8; ctx->buffer[62] = ctx->hi >> 16; ctx->buffer[63] = ctx->hi >> 24; body(ctx, ctx->buffer, 64); result[0] = ctx->a; result[1] = ctx->a >> 8; result[2] = ctx->a >> 16; result[3] = ctx->a >> 24; result[4] = ctx->b; result[5] = ctx->b >> 8; result[6] = ctx->b >> 16; result[7] = ctx->b >> 24; result[8] = ctx->c; result[9] = ctx->c >> 8; result[10] = ctx->c >> 16; result[11] = ctx->c >> 24; result[12] = ctx->d; result[13] = ctx->d >> 8; result[14] = ctx->d >> 16; result[15] = ctx->d >> 24; memset(ctx, 0, sizeof(*ctx)); } #endif bareos-Release-14.2.6/src/lib/md5.h000066400000000000000000000027231263011562700166370ustar00rootroot00000000000000/* * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. * MD5 Message-Digest Algorithm (RFC 1321). * * Homepage: * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 * * Author: * Alexander Peslyak, better known as Solar Designer * * This software was written by Alexander Peslyak in 2001. No copyright is * claimed, and the software is hereby placed in the public domain. * In case this attempt to disclaim copyright and place the software in the * public domain is deemed null and void, then the software is * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the * general public under the following terms: * * Redistribution and use in source and binary forms, with or without * modification, are permitted. * * There's ABSOLUTELY NO WARRANTY, express or implied. * * See md5.c for more information. */ #ifndef MD5HashSize #define MD5HashSize 16 #endif #if defined(HAVE_OPENSSL) && !defined(HAVE_WIN32) #include #elif !defined(_MD5_H) #define _MD5_H /* Any 32-bit or wider unsigned integer data type will do */ typedef unsigned int MD5_u32plus; typedef struct { MD5_u32plus lo, hi; MD5_u32plus a, b, c, d; unsigned char buffer[64]; MD5_u32plus block[16]; } MD5_CTX; extern void MD5_Init(MD5_CTX *ctx); extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); #endif bareos-Release-14.2.6/src/lib/mem_pool.c000066400000000000000000000436161263011562700177620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS memory pool routines. * * The idea behind these routines is that there will be pools of memory that * are pre-allocated for quick access. The pools will have a fixed memory size * on allocation but if need be, the size can be increased. This is particularly * useful for filename buffers where 256 bytes should be sufficient in 99.99% * of the cases, but when it isn't we want to be able to increase the size. * * A major advantage of the pool memory aside from the speed is that the buffer * carries around its size, so to ensure that there is enough memory, simply call * the check_pool_memory_size() with the desired size and it will adjust only * if necessary. * * Kern E. Sibbald */ #include "bareos.h" #ifdef HAVE_MALLOC_TRIM extern "C" int malloc_trim (size_t pad); #endif struct s_pool_ctl { int32_t size; /* default size */ int32_t max_allocated; /* max allocated */ int32_t max_used; /* max buffers used */ int32_t in_use; /* number in use */ struct abufhead *free_buf; /* pointer to free buffers */ }; /* * Bareos Name length plus extra */ #define NLEN (MAX_NAME_LENGTH + 2) /* * Bareos Record length */ #define RLEN 128 /* #define STRESS_TEST_POOL */ /* * Define default Pool buffer sizes */ #ifndef STRESS_TEST_POOL static struct s_pool_ctl pool_ctl[] = { { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */ { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bareos name */ { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */ { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */ { 1024, 1024, 0, 0, NULL }, /* PM_EMSG error message buffer */ { 4096, 4096, 0, 0, NULL }, /* PM_BSOCK message buffer */ { RLEN, RLEN, 0, 0, NULL } /* PM_RECORD message buffer */ }; #else /* * This is used ONLY when stress testing the code */ static struct s_pool_ctl pool_ctl[] = { { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */ { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bareos name */ { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */ { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */ { 20, 20, 0, 0, NULL }, /* PM_EMSG error message buffer */ { 20, 20, 0, 0, NULL } /* PM_BSOCK message buffer */ { RLEN, RLEN, 0, 0, NULL } /* PM_RECORD message buffer */ }; #endif /* * Memory allocation control structures and storage. */ struct abufhead { int32_t ablen; /* Buffer length in bytes */ int32_t pool; /* pool */ struct abufhead *next; /* pointer to next free buffer */ int32_t bnet_size; /* dummy for bnet_send() */ }; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #ifdef SMARTALLOC #define HEAD_SIZE BALIGN(sizeof(struct abufhead)) /* * Special version of error reporting using a static buffer so we don't use * the normal error reporting which uses dynamic memory e.g. recursivly calls * these routines again leading to deadlocks. */ static void smart_alloc_msg(const char *file, int line, const char *fmt, ...) { char buf[256]; va_list arg_ptr; int len; len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"), my_name, get_basename(file), line); va_start(arg_ptr, fmt); bvsnprintf(buf + len, sizeof(buf) - len, (char *)fmt, arg_ptr); va_end(arg_ptr); dispatch_message(NULL, M_ABORT, 0, buf); char *p = 0; p[0] = 0; /* Generate segmentation violation */ } POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool) { struct abufhead *buf; if (pool > PM_MAX) { smart_alloc_msg(__FILE__, __LINE__, _("MemPool index %d larger than max %d\n"), pool, PM_MAX); return NULL; } P(mutex); if (pool_ctl[pool].free_buf) { buf = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf->next; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); sm_new_owner(fname, lineno, (char *)buf); return (POOLMEM *)((char *)buf + HEAD_SIZE); } if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size + HEAD_SIZE)) == NULL) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size); return NULL; } buf->ablen = pool_ctl[pool].size; buf->pool = pool; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); return (POOLMEM *)((char *)buf + HEAD_SIZE); } /* Get nonpool memory of size requested */ POOLMEM *sm_get_memory(const char *fname, int lineno, int32_t size) { struct abufhead *buf; int pool = 0; if ((buf = (struct abufhead *)sm_malloc(fname, lineno, size + HEAD_SIZE)) == NULL) { smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), size); return NULL; } buf->ablen = size; buf->pool = pool; buf->next = NULL; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } return (POOLMEM *)(((char *)buf) + HEAD_SIZE); } /* Return the size of a memory buffer */ int32_t sm_sizeof_pool_memory(const char *fname, int lineno, POOLMEM *obuf) { char *cp = (char *)obuf; if (obuf == NULL) { smart_alloc_msg(__FILE__, __LINE__, _("obuf is NULL\n")); return 0; } cp -= HEAD_SIZE; return ((struct abufhead *)cp)->ablen; } /* Realloc pool memory buffer */ POOLMEM *sm_realloc_pool_memory(const char *fname, int lineno, POOLMEM *obuf, int32_t size) { char *cp = (char *)obuf; void *buf; int pool; ASSERT(obuf); P(mutex); cp -= HEAD_SIZE; buf = sm_realloc(fname, lineno, cp, size + HEAD_SIZE); if (buf == NULL) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), size); return NULL; } ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; if (size > pool_ctl[pool].max_allocated) { pool_ctl[pool].max_allocated = size; } V(mutex); return (POOLMEM *)(((char *)buf) + HEAD_SIZE); } POOLMEM *sm_check_pool_memory_size(const char *fname, int lineno, POOLMEM *obuf, int32_t size) { ASSERT(obuf); if (size <= sizeof_pool_memory(obuf)) { return obuf; } return realloc_pool_memory(obuf, size); } /* Free a memory buffer */ void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf) { struct abufhead *buf; int pool; ASSERT(obuf); P(mutex); buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); pool = buf->pool; pool_ctl[pool].in_use--; if (pool == 0) { free((char *)buf); /* free nonpooled memory */ } else { /* otherwise link it to the free pool chain */ #ifdef DEBUG struct abufhead *next; /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { if (next == buf) { V(mutex); /* unblock the pool */ ASSERT(next != buf); /* attempt to free twice */ } } #endif buf->next = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf; } V(mutex); } #else /* ========= NO SMARTALLOC ========================================= */ POOLMEM *get_pool_memory(int pool) { struct abufhead *buf; P(mutex); if (pool_ctl[pool].free_buf) { buf = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf->next; V(mutex); return (POOLMEM *)((char *)buf + HEAD_SIZE); } if ((buf=malloc(pool_ctl[pool].size + HEAD_SIZE)) == NULL) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size); return NULL; } buf->ablen = pool_ctl[pool].size; buf->pool = pool; buf->next = NULL; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); return (POOLMEM *)(((char *)buf) + HEAD_SIZE); } /* Get nonpool memory of size requested */ POOLMEM *get_memory(int32_t size) { struct abufhead *buf; int pool = 0; if ((buf=malloc(size + HEAD_SIZE)) == NULL) { smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), size); return NULL; } buf->ablen = size; buf->pool = pool; buf->next = NULL; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } return (POOLMEM *)(((char *)buf) + HEAD_SIZE); } /* Return the size of a memory buffer */ int32_t sizeof_pool_memory(POOLMEM *obuf) { char *cp = (char *)obuf; ASSERT(obuf); cp -= HEAD_SIZE; return ((struct abufhead *)cp)->ablen; } /* Realloc pool memory buffer */ POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size) { char *cp = (char *)obuf; void *buf; int pool; ASSERT(obuf); P(mutex); cp -= HEAD_SIZE; buf = realloc(cp, size + HEAD_SIZE); if (buf == NULL) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), size); return NULL; } ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; if (size > pool_ctl[pool].max_allocated) { pool_ctl[pool].max_allocated = size; } V(mutex); return (POOLMEM *)(((char *)buf) + HEAD_SIZE); } POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size) { ASSERT(obuf); if (size <= sizeof_pool_memory(obuf)) { return obuf; } return realloc_pool_memory(obuf, size); } /* Free a memory buffer */ void free_pool_memory(POOLMEM *obuf) { struct abufhead *buf; int pool; ASSERT(obuf); P(mutex); buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); pool = buf->pool; pool_ctl[pool].in_use--; if (pool == 0) { free((char *)buf); /* free nonpooled memory */ } else { /* otherwise link it to the free pool chain */ #ifdef DEBUG struct abufhead *next; /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { if (next == buf) { V(mutex); ASSERT(next != buf); /* attempt to free twice */ } } #endif buf->next = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf; } V(mutex); } #endif /* SMARTALLOC */ /* * Clean up memory pool periodically * */ static time_t last_garbage_collection = 0; const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */ void garbage_collect_memory_pool() { time_t now; P(mutex); if (last_garbage_collection == 0) { last_garbage_collection = time(NULL); V(mutex); return; } now = time(NULL); if (now >= last_garbage_collection + garbage_interval) { last_garbage_collection = now; V(mutex); garbage_collect_memory(); } else { V(mutex); } } /* Release all freed pooled memory */ void close_memory_pool() { struct abufhead *buf, *next; int count = 0; uint64_t bytes = 0; sm_check(__FILE__, __LINE__, false); P(mutex); for (int i=1; i<=PM_MAX; i++) { buf = pool_ctl[i].free_buf; while (buf) { next = buf->next; count++; bytes += sizeof_pool_memory((char *)buf); free((char *)buf); buf = next; } pool_ctl[i].free_buf = NULL; } V(mutex); if (debug_level >= 1) { print_memory_pool_stats(); } } /* * Garbage collect and trim memory if possible * This should be called after all big memory usages if possible. */ void garbage_collect_memory() { close_memory_pool(); /* release free chain */ #ifdef HAVE_MALLOC_TRIM P(mutex); malloc_trim(8192); V(mutex); #endif } #ifdef DEBUG static const char *pool_name(int pool) { static char buf[30]; static const char *name[] = { "NoPool", "NAME ", "FNAME ", "MSG ", "EMSG ", "BSOCK ", "RECORD" }; if (pool >= 0 && pool <= PM_MAX) { return name[pool]; } sprintf(buf, "%-6d", pool); return buf; } /* * Print staticstics on memory pool usage */ void print_memory_pool_stats() { Pmsg0(-1, "Pool Maxsize Maxused Inuse\n"); for (int i = 0; i <= PM_MAX; i++) { Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated, pool_ctl[i].max_used, pool_ctl[i].in_use); } Pmsg0(-1, "\n"); } #else void print_memory_pool_stats() {} #endif /* DEBUG */ /* * Concatenate a string (str) onto a pool memory buffer pm * Returns: length of concatenated string */ int pm_strcat(POOLMEM **pm, const char *str) { int pmlen = strlen(*pm); int len; if (!str) str = ""; len = strlen(str) + 1; *pm = check_pool_memory_size(*pm, pmlen + len); memcpy(*pm+pmlen, str, len); return pmlen + len - 1; } int pm_strcat(POOLMEM *&pm, const char *str) { int pmlen = strlen(pm); int len; if (!str) str = ""; len = strlen(str) + 1; pm = check_pool_memory_size(pm, pmlen + len); memcpy(pm+pmlen, str, len); return pmlen + len - 1; } int pm_strcat(POOLMEM *&pm, POOL_MEM &str) { int pmlen = strlen(pm); int len = strlen(str.c_str()) + 1; pm = check_pool_memory_size(pm, pmlen + len); memcpy(pm+pmlen, str.c_str(), len); return pmlen + len - 1; } int pm_strcat(POOL_MEM &pm, const char *str) { int pmlen = strlen(pm.c_str()); int len; if (!str) str = ""; len = strlen(str) + 1; pm.check_size(pmlen + len); memcpy(pm.c_str()+pmlen, str, len); return pmlen + len - 1; } /* * Copy a string (str) into a pool memory buffer pm * Returns: length of string copied */ int pm_strcpy(POOLMEM **pm, const char *str) { int len; if (!str) str = ""; len = strlen(str) + 1; *pm = check_pool_memory_size(*pm, len); memcpy(*pm, str, len); return len - 1; } int pm_strcpy(POOLMEM *&pm, const char *str) { int len; if (!str) str = ""; len = strlen(str) + 1; pm = check_pool_memory_size(pm, len); memcpy(pm, str, len); return len - 1; } int pm_strcpy(POOLMEM *&pm, POOL_MEM &str) { int len = strlen(str.c_str()) + 1; pm = check_pool_memory_size(pm, len); memcpy(pm, str.c_str(), len); return len - 1; } int pm_strcpy(POOL_MEM &pm, const char *str) { int len; if (!str) str = ""; len = strlen(str) + 1; pm.check_size(len); memcpy(pm.c_str(), str, len); return len - 1; } /* * Copy data into a pool memory buffer pm * Returns: length of data copied */ int pm_memcpy(POOLMEM **pm, const char *data, int32_t n) { *pm = check_pool_memory_size(*pm, n); memcpy(*pm, data, n); return n; } int pm_memcpy(POOLMEM *&pm, const char *data, int32_t n) { pm = check_pool_memory_size(pm, n); memcpy(pm, data, n); return n; } int pm_memcpy(POOLMEM *&pm, POOL_MEM &data, int32_t n) { pm = check_pool_memory_size(pm, n); memcpy(pm, data.c_str(), n); return n; } int pm_memcpy(POOL_MEM &pm, const char *data, int32_t n) { pm.check_size(n); memcpy(pm.c_str(), data, n); return n; } /* ============== CLASS POOL_MEM ============== */ /* * Return the size of a memory buffer */ int32_t POOL_MEM::max_size() { int32_t size; char *cp = mem; cp -= HEAD_SIZE; size = ((struct abufhead *)cp)->ablen; return size; } void POOL_MEM::realloc_pm(int32_t size) { char *cp = mem; char *buf; int pool; P(mutex); cp -= HEAD_SIZE; buf = (char *)realloc(cp, size + HEAD_SIZE); if (buf == NULL) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("Out of memory requesting %d bytes\n"), size); return; } ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; if (size > pool_ctl[pool].max_allocated) { pool_ctl[pool].max_allocated = size; } mem = buf+HEAD_SIZE; V(mutex); } int POOL_MEM::strcat(const char *str) { int pmlen = strlen(mem); int len; if (!str) str = ""; len = strlen(str) + 1; check_size(pmlen + len); memcpy(mem+pmlen, str, len); return pmlen + len - 1; } int POOL_MEM::strcpy(const char *str) { int len; if (!str) str = ""; len = strlen(str) + 1; check_size(len); memcpy(mem, str, len); return len - 1; } #ifdef HAVE_VA_COPY int POOL_MEM::bvsprintf(const char *fmt, va_list arg_ptr) { int maxlen, len; va_list ap; again: maxlen = max_size() - 1; va_copy(ap, arg_ptr); len = ::bvsnprintf(mem, maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= maxlen) { realloc_pm(maxlen + maxlen / 2); goto again; } return len; } #else /* no va_copy() -- brain damaged version of variable arguments */ int POOL_MEM::bvsprintf(const char *fmt, va_list arg_ptr) { int maxlen, len; realloc_pm(5000); maxlen = max_size() - 1; len = ::bvsnprintf(mem, maxlen, fmt, arg_ptr); if (len < 0 || len >= maxlen) { if (len >= maxlen) { len = -len; } } return len; } #endif bareos-Release-14.2.6/src/lib/mem_pool.h000066400000000000000000000103071263011562700177560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Memory Pool prototypes * * Kern Sibbald, MM */ #ifndef __MEM_POOL_H_ #define __MEM_POOL_H_ #ifdef SMARTALLOC #define get_pool_memory(pool) sm_get_pool_memory(__FILE__, __LINE__, pool) POOLMEM *sm_get_pool_memory(const char *file, int line, int pool); #define get_memory(size) sm_get_memory(__FILE__, __LINE__, size) POOLMEM *sm_get_memory(const char *fname, int line, int32_t size); #define sizeof_pool_memory(buf) sm_sizeof_pool_memory(__FILE__, __LINE__, buf) int32_t sm_sizeof_pool_memory(const char *fname, int line, POOLMEM *buf); #define realloc_pool_memory(buf,size) sm_realloc_pool_memory(__FILE__, __LINE__, buf, size) POOLMEM *sm_realloc_pool_memory(const char *fname, int line, POOLMEM *buf, int32_t size); #define check_pool_memory_size(buf,size) sm_check_pool_memory_size(__FILE__, __LINE__, buf, size) POOLMEM *sm_check_pool_memory_size(const char *fname, int line, POOLMEM *buf, int32_t size); #define free_pool_memory(x) sm_free_pool_memory(__FILE__, __LINE__, x) #define free_memory(x) sm_free_pool_memory(__FILE__, __LINE__, x) void sm_free_pool_memory(const char *fname, int line, POOLMEM *buf); #else POOLMEM *get_pool_memory(int pool); POOLMEM *get_memory(int32_t size); int32_t sizeof_pool_memory(POOLMEM *buf); POOLMEM *realloc_pool_memory(POOLMEM *buf, int32_t size); POOLMEM *check_pool_memory_size(POOLMEM *buf, int32_t size); #define free_memory(x) free_pool_memory(x) void free_pool_memory(POOLMEM *buf); #endif /* * Macro to simplify free/reset pointers */ #define free_and_null_pool_memory(a) do { if (a) { free_pool_memory(a); (a) = NULL;} } while (0) void garbage_collect_memory_pool(); void close_memory_pool(); void print_memory_pool_stats(); void garbage_collect_memory(); enum { PM_NOPOOL = 0, /* Nonpooled memory */ PM_NAME = 1, /* BAREOS name */ PM_FNAME = 2, /* File name buffer */ PM_MESSAGE = 3, /* Daemon message */ PM_EMSG = 4, /* Error message */ PM_BSOCK = 5, /* BSOCK buffer */ PM_RECORD = 6 /* DEV_RECORD buffer */ }; #define PM_MAX PM_RECORD /* Number of types */ class POOL_MEM { char *mem; public: POOL_MEM() { mem = get_pool_memory(PM_NAME); *mem = 0; } POOL_MEM(int pool) { mem = get_pool_memory(pool); *mem = 0; } ~POOL_MEM() { free_pool_memory(mem); mem = NULL; } char *c_str() const { return mem; } POOLMEM *&addr() { return mem; } int size() const { return sizeof_pool_memory(mem); } char *check_size(int32_t size) { mem = check_pool_memory_size(mem, size); return mem; } int32_t max_size(); void realloc_pm(int32_t size); int strcpy(const char *str); int strcat(const char *str); int bvsprintf(const char *fmt, va_list arg_ptr); }; int pm_strcat(POOLMEM **pm, const char *str); int pm_strcat(POOLMEM *&pm, const char *str); int pm_strcat(POOL_MEM &pm, const char *str); int pm_strcat(POOLMEM *&pm, POOL_MEM &str); int pm_strcpy(POOLMEM **pm, const char *str); int pm_strcpy(POOLMEM *&pm, const char *str); int pm_strcpy(POOL_MEM &pm, const char *str); int pm_strcpy(POOLMEM *&pm, POOL_MEM &str); int pm_memcpy(POOLMEM **pm, const char *data, int32_t n); int pm_memcpy(POOLMEM *&pm, const char *data, int32_t n); int pm_memcpy(POOL_MEM &pm, const char *data, int32_t n); int pm_memcpy(POOLMEM *&pm, POOL_MEM &data, int32_t n); #endif bareos-Release-14.2.6/src/lib/message.c000066400000000000000000001410141263011562700175660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS message handling routines * * NOTE: don't use any Jmsg or Qmsg calls within this file, * except in q_msg or j_msg (setup routines), * otherwise you may get into recursive calls if there are * errors, and that can lead to looping or deadlocks. * * Kern Sibbald, April 2000 */ #include "bareos.h" #include "jcr.h" db_log_insert_func p_db_log_insert = NULL; #define FULL_LOCATION 1 /* set for file:line in Debug messages */ /* * This is where we define "Globals" because all the daemons include this file. */ const char *working_directory = NULL; /* working directory path stored here */ const char *assert_msg = (char *)NULL; /* ASSERT2 error message */ int verbose = 0; /* increase User messages */ int debug_level = 0; /* debug level */ bool dbg_timestamp = false; /* print timestamp in debug output */ bool prt_kaboom = false; /* Print kaboom output */ utime_t daemon_start_time = 0; /* Daemon start time */ const char *version = VERSION " (" BDATE ")"; const char *dist_name = DISTNAME " " DISTVER; char my_name[128] = {0}; /* daemon name is stored here */ char host_name[256] = {0}; /* host machine name */ char *exepath = (char *)NULL; char *exename = (char *)NULL; int console_msg_pending = false; char con_fname[500]; /* Console filename */ FILE *con_fd = NULL; /* Console file descriptor */ brwlock_t con_lock; /* Console lock structure */ job_code_callback_t message_job_code_callback = NULL; /* Job code callback. Only used by director. */ /* Forward referenced functions */ /* Imported functions */ void setup_tsd_key(); /* Static storage */ /* Exclude spaces but require .mail at end */ #define MAIL_REGEX "^[^ ]+\\.mail$" /* * Allow only one thread to tweak d->fd at a time */ static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER; static MSGSRES *daemon_msgs; /* global messages */ static char *catalog_db = NULL; /* database type */ static void (*message_callback)(int type, char *msg) = NULL; static FILE *trace_fd = NULL; #if defined(HAVE_WIN32) static bool trace = true; #else static bool trace = false; #endif static bool hangup = false; /* Constants */ const char *host_os = HOST_OS; const char *distname = DISTNAME; const char *distver = DISTVER; /* * Walk back in a string from end looking for a * path separator. * * This routine is passed the start of the string and * the end of the string, it returns either the beginning * of the string or where it found a path separator. */ static const char *bstrrpath(const char *start, const char *end) { while ( end > start ) { end--; if (IsPathSeparator(*end)) { break; } } return end; } /* * Some message class methods */ void MSGSRES::lock() { P(fides_mutex); } void MSGSRES::unlock() { V(fides_mutex); } /* * Wait for not in use variable to be clear */ void MSGSRES::wait_not_in_use() /* leaves fides_mutex set */ { lock(); while (m_in_use || m_closing) { unlock(); bmicrosleep(0, 200); /* wait */ lock(); } } /* * Handle message delivery errors */ static void delivery_error(const char *fmt,...) { va_list ap; int i, len, maxlen; POOLMEM *pool_buf; char dt[MAX_TIME_LENGTH]; int dtlen; pool_buf = get_pool_memory(PM_EMSG); bstrftime_ny(dt, sizeof(dt), time(NULL)); dtlen = strlen(dt); dt[dtlen++] = ' '; dt[dtlen] = 0; i = Mmsg(pool_buf, "%s Message delivery ERROR: ", dt); while (1) { maxlen = sizeof_pool_memory(pool_buf) - i - 1; va_start(ap, fmt); len = bvsnprintf(pool_buf+i, maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen / 2); continue; } break; } fputs(pool_buf, stdout); /* print this here to INSURE that it is printed */ fflush(stdout); syslog(LOG_DAEMON | LOG_ERR, "%s", pool_buf); free_memory(pool_buf); } void register_message_callback(void msg_callback(int type, char *msg)) { message_callback = msg_callback; } /* * Set daemon name. Also, find canonical execution * path. Note, exepath has spare room for tacking on * the exename so that we can reconstruct the full name. * * Note, this routine can get called multiple times * The second time is to put the name as found in the * Resource record. On the second call, generally, * argv is NULL to avoid doing the path code twice. */ void my_name_is(int argc, char *argv[], const char *name) { char *l, *p, *q; char cpath[1024]; int len; if (gethostname(host_name, sizeof(host_name)) != 0) { bstrncpy(host_name, "Hostname unknown", sizeof(host_name)); } bstrncpy(my_name, name, sizeof(my_name)); if (argc>0 && argv && argv[0]) { /* * Strip trailing filename and save exepath */ for (l=p=argv[0]; *p; p++) { if (IsPathSeparator(*p)) { l = p; /* set pos of last slash */ } } if (IsPathSeparator(*l)) { l++; } else { l = argv[0]; #if defined(HAVE_WIN32) /* * On Windows allow c: drive specification */ if (l[1] == ':') { l += 2; } #endif } len = strlen(l) + 1; if (exename) { free(exename); } exename = (char *)malloc(len); strcpy(exename, l); if (exepath) { free(exepath); } exepath = (char *)malloc(strlen(argv[0]) + 1 + len); for (p=argv[0],q=exepath; p < l; ) { *q++ = *p++; } *q = 0; if (strchr(exepath, '.') || !IsPathSeparator(exepath[0])) { if (getcwd(cpath, sizeof(cpath))) { free(exepath); exepath = (char *)malloc(strlen(cpath) + 1 + len); strcpy(exepath, cpath); } } Dmsg2(500, "exepath=%s\nexename=%s\n", exepath, exename); } } void set_db_type(const char *name) { if (catalog_db != NULL) { free(catalog_db); } catalog_db = bstrdup(name); } /* * Initialize message handler for a daemon or a Job * We make a copy of the MSGSRES resource passed, so it belongs * to the job or daemon and thus can be modified. * * NULL for jcr -> initialize global messages for daemon * non-NULL -> initialize jcr using Message resource */ void init_msg(JCR *jcr, MSGSRES *msg, job_code_callback_t job_code_callback) { DEST *d, *dnew, *temp_chain = NULL; int i; if (jcr == NULL && msg == NULL) { init_last_jobs_list(); /* * Setup a daemon key then set invalid jcr * Maybe we should give the daemon a jcr??? */ setup_tsd_key(); set_jcr_in_tsd(INVALID_JCR); } message_job_code_callback = job_code_callback; #if !defined(HAVE_WIN32) /* * Make sure we have fd's 0, 1, 2 open * If we don't do this one of our sockets may open * there and if we then use stdout, it could * send total garbage to our socket. */ int fd; fd = open("/dev/null", O_RDONLY, 0644); if (fd > 2) { close(fd); } else { for(i=1; fd + i <= 2; i++) { dup2(fd, fd+i); } } #endif /* * If msg is NULL, initialize global chain for STDOUT and syslog */ if (msg == NULL) { daemon_msgs = (MSGSRES *)malloc(sizeof(MSGSRES)); memset(daemon_msgs, 0, sizeof(MSGSRES)); for (i=1; i<=M_MAX; i++) { add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL); } Dmsg1(050, "Create daemon global message resource %p\n", daemon_msgs); return; } /* * Walk down the message resource chain duplicating it for the current Job. */ for (d = msg->dest_chain; d; d = d->next) { dnew = (DEST *)malloc(sizeof(DEST)); memcpy(dnew, d, sizeof(DEST)); dnew->next = temp_chain; dnew->fd = NULL; dnew->mail_filename = NULL; if (d->mail_cmd) { dnew->mail_cmd = bstrdup(d->mail_cmd); } if (d->where) { dnew->where = bstrdup(d->where); } temp_chain = dnew; } if (jcr) { jcr->jcr_msgs = (MSGSRES *)malloc(sizeof(MSGSRES)); memset(jcr->jcr_msgs, 0, sizeof(MSGSRES)); jcr->jcr_msgs->dest_chain = temp_chain; memcpy(jcr->jcr_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg)); } else { /* * If we have default values, release them now */ if (daemon_msgs) { free_msgs_res(daemon_msgs); } daemon_msgs = (MSGSRES *)malloc(sizeof(MSGSRES)); memset(daemon_msgs, 0, sizeof(MSGSRES)); daemon_msgs->dest_chain = temp_chain; memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg)); } Dmsg2(250, "Copy message resource %p to %p\n", msg, temp_chain); } /* * Initialize so that the console (User Agent) can receive messages -- stored in a file. */ void init_console_msg(const char *wd) { int fd; bsnprintf(con_fname, sizeof(con_fname), "%s%c%s.conmsg", wd, PathSeparator, my_name); fd = open(con_fname, O_CREAT|O_RDWR|O_BINARY, 0600); if (fd == -1) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not open console message file %s: ERR=%s\n"), con_fname, be.bstrerror()); } if (lseek(fd, 0, SEEK_END) > 0) { console_msg_pending = 1; } close(fd); con_fd = fopen(con_fname, "a+b"); if (!con_fd) { berrno be; Emsg2(M_ERROR, 0, _("Could not open console message file %s: ERR=%s\n"), con_fname, be.bstrerror()); } if (rwl_init(&con_lock) != 0) { berrno be; Emsg1(M_ERROR_TERM, 0, _("Could not get con mutex: ERR=%s\n"), be.bstrerror()); } } /* * Called only during parsing of the config file. * * Add a message destination. I.e. associate a message type with * a destination (code). * * Note, where in the case of dest_code FILE is a filename, * but in the case of MAIL is a space separated list of * email addresses, ... */ void add_msg_dest(MSGSRES *msg, int dest_code, int msg_type, char *where, char *mail_cmd) { DEST *d; /* * First search the existing chain and see if we * can simply add this msg_type to an existing entry. */ for (d = msg->dest_chain; d; d = d->next) { if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) || bstrcmp(where, d->where))) { Dmsg4(850, "Add to existing d=%p msgtype=%d destcode=%d where=%s\n", d, msg_type, dest_code, NPRT(where)); set_bit(msg_type, d->msg_types); set_bit(msg_type, msg->send_msg); /* set msg_type bit in our local */ return; } } /* * Not found, create a new entry */ d = (DEST *)malloc(sizeof(DEST)); memset(d, 0, sizeof(DEST)); d->next = msg->dest_chain; d->dest_code = dest_code; set_bit(msg_type, d->msg_types); /* set type bit in structure */ set_bit(msg_type, msg->send_msg); /* set type bit in our local */ if (where) { d->where = bstrdup(where); } if (mail_cmd) { d->mail_cmd = bstrdup(mail_cmd); } Dmsg5(850, "add new d=%p msgtype=%d destcode=%d where=%s mailcmd=%s\n", d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd)); msg->dest_chain = d; } /* * Called only during parsing of the config file. * * Remove a message destination */ void rem_msg_dest(MSGSRES *msg, int dest_code, int msg_type, char *where) { DEST *d; for (d = msg->dest_chain; d; d = d->next) { Dmsg2(850, "Remove_msg_dest d=%p where=%s\n", d, NPRT(d->where)); if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) && ((where == NULL && d->where == NULL) || bstrcmp(where, d->where))) { Dmsg3(850, "Found for remove d=%p msgtype=%d destcode=%d\n", d, msg_type, dest_code); clear_bit(msg_type, d->msg_types); Dmsg0(850, "Return rem_msg_dest\n"); return; } } } /* * Create a unique filename for the mail command */ static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d) { if (jcr) { Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name, jcr->Job, (int)(intptr_t)d); } else { Mmsg(name, "%s/%s.%s.%d.mail", working_directory, my_name, my_name, (int)(intptr_t)d); } Dmsg1(850, "mailname=%s\n", name); } /* * Open a mail pipe */ static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM *&cmd, DEST *d) { BPIPE *bpipe; if (d->mail_cmd) { cmd = edit_job_codes(jcr, cmd, d->mail_cmd, d->where, message_job_code_callback); } else { Mmsg(cmd, "/usr/lib/sendmail -F BAREOS %s", d->where); } fflush(stdout); if ((bpipe = open_bpipe(cmd, 120, "rw"))) { /* * If we had to use sendmail, add subject */ if (!d->mail_cmd) { fprintf(bpipe->wfd, "Subject: %s\r\n\r\n", _("BAREOS Message")); } } else { berrno be; delivery_error(_("open mail pipe %s failed: ERR=%s\n"), cmd, be.bstrerror()); } return bpipe; } /* * Close the messages for this Messages resource, which means to close * any open files, and dispatch any pending email messages. */ void close_msg(JCR *jcr) { MSGSRES *msgs; DEST *d; BPIPE *bpipe; POOLMEM *cmd, *line; int len, status; Dmsg1(580, "Close_msg jcr=%p\n", jcr); if (jcr == NULL) { /* NULL -> global chain */ msgs = daemon_msgs; } else { msgs = jcr->jcr_msgs; jcr->jcr_msgs = NULL; } if (msgs == NULL) { return; } /* * Wait for item to be not in use, then mark closing */ if (msgs->is_closing()) { return; } msgs->wait_not_in_use(); /* leaves fides_mutex set */ /* * Note get_closing() does not lock because we are already locked */ if (msgs->get_closing()) { msgs->unlock(); return; } msgs->set_closing(); msgs->unlock(); Dmsg1(850, "===Begin close msg resource at %p\n", msgs); cmd = get_pool_memory(PM_MESSAGE); for (d = msgs->dest_chain; d; ) { if (d->fd) { switch (d->dest_code) { case MD_FILE: case MD_APPEND: if (d->fd) { fclose(d->fd); /* close open file descriptor */ d->fd = NULL; } break; case MD_MAIL: case MD_MAIL_ON_ERROR: case MD_MAIL_ON_SUCCESS: Dmsg0(850, "Got MD_MAIL, MD_MAIL_ON_ERROR or MD_MAIL_ON_SUCCESS\n"); if (!d->fd) { break; } switch (d->dest_code) { case MD_MAIL_ON_ERROR: if (jcr) { switch (jcr->JobStatus) { case JS_Terminated: case JS_Warnings: goto rem_temp_file; default: break; } } break; case MD_MAIL_ON_SUCCESS: if (jcr) { switch (jcr->JobStatus) { case JS_Terminated: case JS_Warnings: break; default: goto rem_temp_file; } } break; default: break; } if (!(bpipe=open_mail_pipe(jcr, cmd, d))) { Pmsg0(000, _("open mail pipe failed.\n")); goto rem_temp_file; } Dmsg0(850, "Opened mail pipe\n"); len = d->max_len+10; line = get_memory(len); rewind(d->fd); while (fgets(line, len, d->fd)) { fputs(line, bpipe->wfd); } if (!close_wpipe(bpipe)) { /* close write pipe sending mail */ berrno be; Pmsg1(000, _("close error: ERR=%s\n"), be.bstrerror()); } /* * Since we are closing all messages, before "recursing" * make sure we are not closing the daemon messages, otherwise * kaboom. */ if (msgs != daemon_msgs) { /* * Read what mail prog returned -- should be nothing */ while (fgets(line, len, bpipe->rfd)) { delivery_error(_("Mail prog: %s"), line); } } status = close_bpipe(bpipe); if (status != 0 && msgs != daemon_msgs) { berrno be; be.set_errno(status); Dmsg1(850, "Calling emsg. CMD=%s\n", cmd); delivery_error(_("Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n"), cmd, be.bstrerror()); } free_memory(line); rem_temp_file: /* * Remove temp file */ if (d->fd) { fclose(d->fd); d->fd = NULL; } if (d->mail_filename) { /* * Exclude spaces in mail_filename */ safer_unlink(d->mail_filename, MAIL_REGEX); free_pool_memory(d->mail_filename); d->mail_filename = NULL; } Dmsg0(850, "end mail or mail on error\n"); break; default: break; } d->fd = NULL; } d = d->next; /* point to next buffer */ } free_pool_memory(cmd); Dmsg0(850, "Done walking message chain.\n"); if (jcr) { free_msgs_res(msgs); msgs = NULL; } else { msgs->clear_closing(); } Dmsg0(850, "===End close msg resource\n"); } /* * Free memory associated with Messages resource */ void free_msgs_res(MSGSRES *msgs) { DEST *d, *old; /* * Walk down the message chain releasing allocated buffers */ for (d = msgs->dest_chain; d; ) { if (d->where) { free(d->where); } if (d->mail_cmd) { free(d->mail_cmd); } old = d; /* save pointer to release */ d = d->next; /* point to next buffer */ free(old); /* free the destination item */ } msgs->dest_chain = NULL; free(msgs); /* free the head */ } /* * Terminate the message handler for good. * Release the global destination chain. * * Also, clean up a few other items (cons, exepath). Note, * these really should be done elsewhere. */ void term_msg() { Dmsg0(850, "Enter term_msg\n"); close_msg(NULL); /* close global chain */ free_msgs_res(daemon_msgs); /* free the resources */ daemon_msgs = NULL; if (con_fd) { fflush(con_fd); fclose(con_fd); con_fd = NULL; } if (exepath) { free(exepath); exepath = NULL; } if (exename) { free(exename); exename = NULL; } if (trace_fd) { fclose(trace_fd); trace_fd = NULL; } if (catalog_db) { free(catalog_db); catalog_db = NULL; } term_last_jobs_list(); } static inline bool open_dest_file(JCR *jcr, DEST *d, const char *mode) { d->fd = fopen(d->where, mode); if (!d->fd) { berrno be; delivery_error(_("fopen %s failed: ERR=%s\n"), d->where, be.bstrerror()); return false; } return true; } static struct syslog_facility_name { const char *name; int facility; } syslog_facility_names[] = { { "kern", LOG_KERN }, { "user", LOG_USER }, { "mail", LOG_MAIL }, { "daemon", LOG_DAEMON }, { "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG }, { "lpr", LOG_LPR }, { "news", LOG_NEWS }, { "uucp", LOG_UUCP }, #ifdef LOG_CRON { "cron", LOG_CRON }, #endif #ifdef LOG_AUTHPRIV { "authpriv", LOG_AUTHPRIV }, #endif #ifdef LOG_FTP { "ftp", LOG_FTP }, #endif #ifdef LOG_NTP { "ntp", LOG_NTP }, #endif #ifdef LOG_AUDIT { "audit", LOG_AUDIT }, #endif #ifdef LOG_SECURITY { "security", LOG_SECURITY }, #endif #ifdef LOG_CONSOLE { "console", LOG_CONSOLE }, #endif { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { NULL, -1 } }; static inline bool set_syslog_facility(JCR *jcr, DEST *d) { int i; if (d->where) { for (i = 0; syslog_facility_names[i].name; i++) { if (bstrcasecmp(d->where, syslog_facility_names[i].name)) { d->syslog_facility = syslog_facility_names[i].facility; i = 0; break; } } /* * Make sure we got a match otherwise fallback to LOG_DAEMON */ if (i != 0) { d->syslog_facility = LOG_DAEMON; } } else { d->syslog_facility = LOG_DAEMON; } return true; } /* * Split the output for syslog (it converts \n to ' ' and is * limited to 1024 characters per syslog message */ static inline void send_to_syslog(int mode, const char *msg) { int len; char buf[1024]; const char *p2; const char *p = msg; while (*p && ((p2 = strchr(p, '\n')) != NULL)) { len = MIN((int)sizeof(buf) - 1, p2 - p + 1); /* Add 1 to keep \n */ strncpy(buf, p, len); buf[len] = 0; syslog(mode, "%s", buf); p = p2+1; /* skip \n */ } if (*p != 0) { /* no \n at the end ? */ syslog(mode, "%s", p); } } /* * Handle sending the message to the appropriate place */ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg) { DEST *d; char dt[MAX_TIME_LENGTH]; POOLMEM *mcmd; int len, dtlen; MSGSRES *msgs; BPIPE *bpipe; const char *mode; Dmsg2(850, "Enter dispatch_message type=%d msg=%s", type, msg); /* * Most messages are prefixed by a date and time. If mtime is * zero, then we use the current time. If mtime is 1 (special * kludge), we do not prefix the date and time. Otherwise, * we assume mtime is a utime_t and use it. */ if (mtime == 0) { mtime = time(NULL); } if (mtime == 1) { *dt = 0; dtlen = 0; mtime = time(NULL); /* get time for SQL log */ } else { bstrftime_ny(dt, sizeof(dt), mtime); dtlen = strlen(dt); dt[dtlen++] = ' '; dt[dtlen] = 0; } /* * If the program registered a callback, send it there */ if (message_callback) { message_callback(type, msg); return; } /* * For serious errors make sure message is printed or logged */ if (type == M_ABORT || type == M_ERROR_TERM) { fputs(dt, stdout); fputs(msg, stdout); fflush(stdout); if (type == M_ABORT) { syslog(LOG_DAEMON | LOG_ERR, "%s", msg); } } /* * Now figure out where to send the message */ msgs = NULL; if (!jcr) { jcr = get_jcr_from_tsd(); } if (jcr) { /* * See if we need to suppress the messages. */ if (jcr->suppress_output) { /* * See if this JCR has a controlling JCR and if so redirect * this message to the controlling JCR. */ if (jcr->cjcr) { jcr = jcr->cjcr; } else { /* * Ignore this Job Message. */ return; } } msgs = jcr->jcr_msgs; } if (msgs == NULL) { msgs = daemon_msgs; } /* * If closing this message resource, print and send to syslog, then get out. */ if (msgs->is_closing()) { fputs(dt, stdout); fputs(msg, stdout); fflush(stdout); syslog(LOG_DAEMON | LOG_ERR, "%s", msg); return; } for (d = msgs->dest_chain; d; d = d->next) { if (bit_is_set(type, d->msg_types)) { switch (d->dest_code) { case MD_CATALOG: if (!jcr || !jcr->db) { break; } if (p_db_log_insert) { if (!p_db_log_insert(jcr, mtime, msg)) { delivery_error(_("Msg delivery error: Unable to store data in database.\n")); } } break; case MD_CONSOLE: Dmsg1(850, "CONSOLE for following msg: %s", msg); if (!con_fd) { con_fd = fopen(con_fname, "a+b"); Dmsg0(850, "Console file not open.\n"); } if (con_fd) { Pw(con_lock); /* get write lock on console message file */ errno = 0; if (dtlen) { (void)fwrite(dt, dtlen, 1, con_fd); } len = strlen(msg); if (len > 0) { (void)fwrite(msg, len, 1, con_fd); if (msg[len-1] != '\n') { (void)fwrite("\n", 2, 1, con_fd); } } else { (void)fwrite("\n", 2, 1, con_fd); } fflush(con_fd); console_msg_pending = true; Vw(con_lock); } break; case MD_SYSLOG: Dmsg1(850, "SYSLOG for following msg: %s\n", msg); if (!d->syslog_facility && !set_syslog_facility(jcr, d)) { msgs->clear_in_use(); break; } /* * Dispatch based on our internal message type to a matching syslog one. */ switch (type) { case M_ERROR: case M_ERROR_TERM: send_to_syslog(d->syslog_facility | LOG_ERR, msg); break; case M_ABORT: case M_FATAL: send_to_syslog(d->syslog_facility | LOG_CRIT, msg); break; case M_WARNING: send_to_syslog(d->syslog_facility | LOG_WARNING, msg); break; case M_DEBUG: send_to_syslog(d->syslog_facility | LOG_DEBUG, msg); break; case M_INFO: case M_NOTSAVED: case M_RESTORED: case M_SAVED: case M_SKIPPED: case M_TERM: send_to_syslog(d->syslog_facility | LOG_INFO, msg); break; case M_ALERT: case M_AUDIT: case M_MOUNT: case M_SECURITY: case M_VOLMGMT: send_to_syslog(d->syslog_facility | LOG_NOTICE, msg); break; default: send_to_syslog(d->syslog_facility | LOG_ERR, msg); break; } break; case MD_OPERATOR: Dmsg1(850, "OPERATOR for following msg: %s\n", msg); mcmd = get_pool_memory(PM_MESSAGE); if ((bpipe=open_mail_pipe(jcr, mcmd, d))) { int status; fputs(dt, bpipe->wfd); fputs(msg, bpipe->wfd); /* * Messages to the operator go one at a time */ status = close_bpipe(bpipe); if (status != 0) { berrno be; be.set_errno(status); delivery_error(_("Msg delivery error: Operator mail program terminated in error.\n" "CMD=%s\nERR=%s\n"), mcmd, be.bstrerror()); } } free_pool_memory(mcmd); break; case MD_MAIL: case MD_MAIL_ON_ERROR: case MD_MAIL_ON_SUCCESS: Dmsg1(850, "MAIL for following msg: %s", msg); if (msgs->is_closing()) { break; } msgs->set_in_use(); if (!d->fd) { POOLMEM *name = get_pool_memory(PM_MESSAGE); make_unique_mail_filename(jcr, name, d); d->fd = fopen(name, "w+b"); if (!d->fd) { berrno be; delivery_error(_("Msg delivery error: fopen %s failed: ERR=%s\n"), name, be.bstrerror()); free_pool_memory(name); msgs->clear_in_use(); break; } d->mail_filename = name; } fputs(dt, d->fd); len = strlen(msg) + dtlen; if (len > d->max_len) { d->max_len = len; /* keep max line length */ } fputs(msg, d->fd); msgs->clear_in_use(); break; case MD_APPEND: Dmsg1(850, "APPEND for following msg: %s", msg); mode = "ab"; goto send_to_file; case MD_FILE: Dmsg1(850, "FILE for following msg: %s", msg); mode = "w+b"; send_to_file: if (msgs->is_closing()) { break; } msgs->set_in_use(); if (!d->fd && !open_dest_file(jcr, d, mode)) { msgs->clear_in_use(); break; } fputs(dt, d->fd); fputs(msg, d->fd); /* * On error, we close and reopen to handle log rotation */ if (ferror(d->fd)) { fclose(d->fd); d->fd = NULL; if (open_dest_file(jcr, d, mode)) { fputs(dt, d->fd); fputs(msg, d->fd); } } msgs->clear_in_use(); break; case MD_DIRECTOR: Dmsg1(850, "DIRECTOR for following msg: %s", msg); if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) { jcr->dir_bsock->fsend("Jmsg Job=%s type=%d level=%lld %s", jcr->Job, type, mtime, msg); } else { Dmsg1(800, "no jcr for following msg: %s", msg); } break; case MD_STDOUT: Dmsg1(850, "STDOUT for following msg: %s", msg); if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */ fputs(dt, stdout); fputs(msg, stdout); fflush(stdout); } break; case MD_STDERR: Dmsg1(850, "STDERR for following msg: %s", msg); fputs(dt, stderr); fputs(msg, stderr); fflush(stdout); break; default: break; } } } } /* * This subroutine returns the filename portion of a path. * It is used because some compilers set __FILE__ * to the full path. Try to return base + next higher path. */ const char *get_basename(const char *pathname) { const char *basename; if ((basename = bstrrpath(pathname, pathname+strlen(pathname))) == pathname) { /* empty */ } else if ((basename = bstrrpath(pathname, basename-1)) == pathname) { /* empty */ } else { basename++; } return basename; } /* * Print or write output to trace file */ static void pt_out(char *buf) { /* * Used the "trace on" command in the console to turn on * output to the trace file. "trace off" will close the file. */ if (trace) { if (!trace_fd) { POOL_MEM fn(PM_FNAME); Mmsg(fn, "%s/%s.trace", working_directory ? working_directory : "c:", my_name); trace_fd = fopen(fn.c_str(), "a+b"); } if (trace_fd) { fputs(buf, trace_fd); fflush(trace_fd); return; } else { /* * Some problem, turn off tracing */ trace = false; } } /* * Not tracing */ fputs(buf, stdout); fflush(stdout); } /* * This subroutine prints a debug message if the level number is less than or * equal the debug_level. File and line numbers are included for more detail if * desired, but not currently printed. * * If the level is negative, the details of file and line number are not printed. */ void d_msg(const char *file, int line, int level, const char *fmt,...) { va_list ap; int len, maxlen; utime_t mtime; bool details = true; POOL_MEM buf(PM_EMSG), more(PM_EMSG); if (level < 0) { details = false; level = -level; } if (level <= debug_level) { if (dbg_timestamp) { mtime = time(NULL); bstrftimes(buf.c_str(), buf.size(), mtime); pm_strcat(buf, " "); pt_out(buf.c_str()); } #ifdef FULL_LOCATION if (details) { Mmsg(buf, "%s: %s:%d-%u ", my_name, get_basename(file), line, get_jobid_from_tsd()); } #endif while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } #ifdef FULL_LOCATION if (details) { pt_out(buf.c_str()); } #endif pt_out(more.c_str()); } } /* * Set trace flag on/off. If argument is negative, there is no change */ void set_trace(int trace_flag) { if (trace_flag < 0) { return; } else if (trace_flag > 0) { trace = true; } else { trace = false; } if (!trace && trace_fd) { FILE *ltrace_fd = trace_fd; trace_fd = NULL; bmicrosleep(0, 100000); /* yield to prevent seg faults */ fclose(ltrace_fd); } } void set_hangup(int hangup_value) { if (hangup_value < 0) { return; } else { hangup = hangup_value; } } void set_timestamp(int timestamp_flag) { if (timestamp_flag < 0) { return; } else if (timestamp_flag > 0) { dbg_timestamp = true; } else { dbg_timestamp = false; } } bool get_hangup(void) { return hangup; } bool get_trace(void) { return trace; } bool get_timestamp(void) { return dbg_timestamp; } /* * This subroutine prints a message regardless of the debug level * * If the level is negative, the details of file and line number are not printed. */ void p_msg(const char *file, int line, int level, const char *fmt,...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG), more(PM_EMSG); #ifdef FULL_LOCATION if (level >= 0) { Mmsg(buf, "%s: %s:%d-%u ", my_name, get_basename(file), line, get_jobid_from_tsd()); } #endif while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } #ifdef FULL_LOCATION if (level >= 0) { pt_out(buf.c_str()); } #endif pt_out(more.c_str()); } /* * This subroutine prints a message regardless of the debug level * * If the level is negative, the details of file and line number are not printed. * Special version of p_msg used with fixed buffers. */ void p_msg_fb(const char *file, int line, int level, const char *fmt,...) { char buf[256]; int len = 0; va_list arg_ptr; #ifdef FULL_LOCATION if (level >= 0) { len = bsnprintf(buf, sizeof(buf), "%s: %s:%d-%u ", my_name, get_basename(file), line, get_jobid_from_tsd()); } #endif va_start(arg_ptr, fmt); bvsnprintf(buf + len, sizeof(buf) - len, (char *)fmt, arg_ptr); va_end(arg_ptr); pt_out(buf); } /* * Subroutine writes a debug message to the trace file if the level number is less than * or equal the debug_level. File and line numbers are included for more detail if desired, * but not currently printed. * * If the level is negative, the details of file and line number are not printed. */ void t_msg(const char *file, int line, int level, const char *fmt,...) { va_list ap; int len, maxlen; bool details = true; POOL_MEM buf(PM_EMSG), more(PM_EMSG); if (level < 0) { details = false; level = -level; } if (level <= debug_level) { if (!trace_fd) { POOL_MEM fn(PM_FNAME); Mmsg(fn, "%s/%s.trace", working_directory ? working_directory : "c:", my_name); trace_fd = fopen(fn.c_str(), "a+b"); } #ifdef FULL_LOCATION if (details) { Mmsg(buf, "%s: %s:%d-%u ", my_name, get_basename(file), line, get_jobid_from_tsd()); } #endif while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } if (trace_fd != NULL) { #ifdef FULL_LOCATION if (details) { fputs(buf.c_str(), trace_fd); } #endif fputs(more.c_str(), trace_fd); fflush(trace_fd); } } } /* * print an error message */ void e_msg(const char *file, int line, int type, int level, const char *fmt,...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG), more(PM_EMSG); /* * Check if we have a message destination defined. * We always report M_ABORT and M_ERROR_TERM */ if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) && !bit_is_set(type, daemon_msgs->send_msg))) { return; /* no destination */ } switch (type) { case M_ABORT: Mmsg(buf, _("%s: ABORTING due to ERROR in %s:%d\n"), my_name, get_basename(file), line); break; case M_ERROR_TERM: Mmsg(buf, _("%s: ERROR TERMINATION at %s:%d\n"), my_name, get_basename(file), line); break; case M_FATAL: if (level == -1) /* skip details */ Mmsg(buf, _("%s: Fatal Error because: "), my_name); else Mmsg(buf, _("%s: Fatal Error at %s:%d because:\n"), my_name, get_basename(file), line); break; case M_ERROR: if (level == -1) /* skip details */ Mmsg(buf, _("%s: ERROR: "), my_name); else Mmsg(buf, _("%s: ERROR in %s:%d "), my_name, get_basename(file), line); break; case M_WARNING: Mmsg(buf, _("%s: Warning: "), my_name); break; case M_SECURITY: Mmsg(buf, _("%s: Security violation: "), my_name); break; default: Mmsg(buf, "%s: ", my_name); break; } while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } pm_strcat(buf, more.c_str()); dispatch_message(NULL, type, 0, buf.c_str()); if (type == M_ABORT) { char *p = 0; p[0] = 0; /* generate segmentation violation */ } if (type == M_ERROR_TERM) { exit(1); } } /* * Generate a Job message */ void Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...) { va_list ap; MSGSRES *msgs; int len, maxlen; uint32_t JobId = 0; POOL_MEM buf(PM_EMSG), more(PM_EMSG); Dmsg1(850, "Enter Jmsg type=%d\n", type); /* * Special case for the console, which has a dir_bsock and JobId == 0, * in that case, we send the message directly back to the * dir_bsock. */ if (jcr && jcr->JobId == 0 && jcr->dir_bsock) { BSOCK *dir = jcr->dir_bsock; va_start(ap, fmt); dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg), fmt, ap); va_end(ap); jcr->dir_bsock->send(); return; } /* * The watchdog thread can't use Jmsg directly, we always queued it */ if (is_watchdog()) { while (1) { maxlen = buf.size()- 1; va_start(ap, fmt); len = bvsnprintf(buf.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } Qmsg(jcr, type, mtime, "%s", buf.c_str()); return; } msgs = NULL; if (!jcr) { jcr = get_jcr_from_tsd(); } if (jcr) { /* * Dequeue messages to keep the original order */ if (!jcr->dequeuing_msgs) { /* Avoid recursion */ dequeue_messages(jcr); } msgs = jcr->jcr_msgs; JobId = jcr->JobId; } if (!msgs) { msgs = daemon_msgs; /* if no jcr, we use daemon handler */ } /* * Check if we have a message destination defined. * We always report M_ABORT and M_ERROR_TERM */ if (msgs && (type != M_ABORT && type != M_ERROR_TERM) && !bit_is_set(type, msgs->send_msg)) { return; /* no destination */ } switch (type) { case M_ABORT: Mmsg(buf, _("%s ABORTING due to ERROR\n"), my_name); break; case M_ERROR_TERM: Mmsg(buf, _("%s ERROR TERMINATION\n"), my_name); break; case M_FATAL: Mmsg(buf, _("%s JobId %u: Fatal error: "), my_name, JobId); if (jcr) { jcr->setJobStatus(JS_FatalError); } if (jcr && jcr->JobErrors == 0) { jcr->JobErrors = 1; } break; case M_ERROR: Mmsg(buf, _("%s JobId %u: Error: "), my_name, JobId); if (jcr) { jcr->JobErrors++; } break; case M_WARNING: Mmsg(buf, _("%s JobId %u: Warning: "), my_name, JobId); if (jcr) { jcr->JobWarnings++; } break; case M_SECURITY: Mmsg(buf, _("%s JobId %u: Security violation: "), my_name, JobId); break; default: Mmsg(buf, "%s JobId %u: ", my_name, JobId); break; } while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } pm_strcat(buf, more.c_str()); dispatch_message(jcr, type, mtime, buf.c_str()); if (type == M_ABORT){ char *p = 0; printf("BAREOS forced SEG FAULT to obtain traceback.\n"); syslog(LOG_DAEMON | LOG_ERR, "BAREOS forced SEG FAULT to obtain traceback.\n"); p[0] = 0; /* generate segmentation violation */ } if (type == M_ERROR_TERM) { exit(1); } } /* * If we come here, prefix the message with the file:line-number, * then pass it on to the normal Jmsg routine. */ void j_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG), more(PM_EMSG); Mmsg(buf, "%s:%d ", get_basename(file), line); while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } pm_strcat(buf, more.c_str()); Jmsg(jcr, type, mtime, "%s", buf.c_str()); } /* * Edit a message into a Pool memory buffer, with file:lineno */ int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG), more(PM_EMSG); Mmsg(buf, "%s:%d ", get_basename(file), line); while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } pm_strcpy(*pool_buf, buf.c_str()); len = pm_strcat(*pool_buf, more.c_str()); return len; } int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG), more(PM_EMSG); Mmsg(buf, "%s:%d ", get_basename(file), line); while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } pm_strcpy(pool_buf, buf.c_str()); len = pm_strcat(pool_buf, more.c_str()); return len; } /* * Edit a message into a Pool Memory buffer NO file:lineno * * Returns: string length of what was edited. * -1 when the buffer isn't enough to hold the edited string. */ int Mmsg(POOLMEM **pool_buf, const char *fmt, ...) { int len, maxlen; va_list ap; while (1) { maxlen = sizeof_pool_memory(*pool_buf) - 1; va_start(ap, fmt); len = bvsnprintf(*pool_buf, maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen / 2); continue; } break; } return len; } int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...) { int len, maxlen; va_list ap; while (1) { maxlen = sizeof_pool_memory(pool_buf) - 1; va_start(ap, fmt); len = bvsnprintf(pool_buf, maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen / 2); continue; } break; } return len; } int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...) { int len, maxlen; va_list ap; while (1) { maxlen = pool_buf.max_size() - 1; va_start(ap, fmt); len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { pool_buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } return len; } /* * We queue messages rather than print them directly. This * is generally used in low level routines (msg handler, bnet) * to prevent recursion (i.e. if you are in the middle of * sending a message, it is a bit messy to recursively call * yourself when the bnet packet is not reentrant). */ void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG); MQUEUE_ITEM *item; while (1) { maxlen = buf.size() - 1; va_start(ap, fmt); len = bvsnprintf(buf.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } item = (MQUEUE_ITEM *)malloc(sizeof(MQUEUE_ITEM) + len + 1); item->type = type; item->mtime = time(NULL); strcpy(item->msg, buf.c_str()); if (!jcr) { jcr = get_jcr_from_tsd(); } /* * If no jcr or no queue or dequeuing send to syslog */ if (!jcr || !jcr->msg_queue || jcr->dequeuing_msgs) { syslog(LOG_DAEMON|LOG_ERR, "%s", item->msg); free(item); } else { /* * Queue message for later sending */ P(jcr->msg_queue_mutex); jcr->msg_queue->append(item); V(jcr->msg_queue_mutex); } } /* * Dequeue messages */ void dequeue_messages(JCR *jcr) { MQUEUE_ITEM *item; if (!jcr->msg_queue) { return; } P(jcr->msg_queue_mutex); jcr->dequeuing_msgs = true; foreach_dlist(item, jcr->msg_queue) { Jmsg(jcr, item->type, item->mtime, "%s", item->msg); } /* * Remove messages just sent */ jcr->msg_queue->destroy(); jcr->dequeuing_msgs = false; V(jcr->msg_queue_mutex); } /* * If we come here, prefix the message with the file:line-number, * then pass it on to the normal Qmsg routine. */ void q_msg(const char *file, int line, JCR *jcr, int type, utime_t mtime, const char *fmt,...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_EMSG), more(PM_EMSG); Mmsg(buf, "%s:%d ", get_basename(file), line); while (1) { maxlen = more.size() - 1; va_start(ap, fmt); len = bvsnprintf(more.c_str(), maxlen, fmt, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { more.realloc_pm(maxlen + maxlen / 2); continue; } break; } pm_strcat(buf, more.c_str()); Qmsg(jcr, type, mtime, "%s", buf.c_str()); } bareos-Release-14.2.6/src/lib/message.h000066400000000000000000000132731263011562700176000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Define Message Types for BAREOS * * Kern Sibbald, 2000 */ #include "bits.h" #undef M_DEBUG #undef M_ABORT #undef M_FATAL #undef M_ERROR #undef M_WARNING #undef M_INFO #undef M_MOUNT #undef M_ERROR_TERM #undef M_TERM #undef M_RESTORED #undef M_SECURITY #undef M_ALERT #undef M_VOLMGMT #undef M_AUDIT /* * Most of these message levels are more or less obvious. * They have evolved somewhat during the development of BAREOS, * and here are some of the details of where I am trying to * head (in the process of changing the code) as of 15 June 2002. * * M_ABORT BAREOS immediately aborts and tries to produce a traceback * This is for really serious errors like segmentation fault. * M_ERROR_TERM BAREOS immediately terminates but no dump. This is for * "obvious" serious errors like daemon already running or * cannot open critical file, ... where a dump is not wanted. * M_TERM BAREOS daemon shutting down because of request (SIGTERM). * M_DEBUG Debug Messages * * The remaining apply to Jobs rather than the daemon. * * M_FATAL BAREOS detected a fatal Job error. The Job will be killed, * but BAREOS continues running. * M_ERROR BAREOS detected a Job error. The Job will continue running * but the termination status will be error. * M_WARNING Job warning message. * M_INFO Job information message. * M_SAVED Info on saved file * M_NOTSAVED Info on not saved file * M_RESTORED An ls -l of each restored file. * M_SKIPPED File skipped during backup by option setting * M_SECURITY For security viloations. This is equivalent to FATAL. * M_ALERT For Tape Alert messages. * M_VOLMGMT Volume Management message * M_AUDIT Auditing message * M_MOUNT Mount requests */ enum { /* * Keep M_ABORT=1 for dlist.h */ M_ABORT = 1, M_DEBUG, M_FATAL, M_ERROR, M_WARNING, M_INFO, M_SAVED, M_NOTSAVED, M_SKIPPED, M_MOUNT, M_ERROR_TERM, M_TERM, M_RESTORED, M_SECURITY, M_ALERT, M_VOLMGMT, M_AUDIT }; #define M_MAX M_AUDIT /* keep this updated ! */ #define NR_MSG_TYPES nbytes_for_bits(M_MAX + 1) /* * Define message destination structure */ /* *** FIXME **** where should be extended to handle multiple values */ typedef struct s_dest { struct s_dest *next; int dest_code; /* Destination (one of the MD_ codes) */ int max_len; /* Max mail line length */ FILE *fd; /* File descriptor */ char msg_types[NR_MSG_TYPES]; /* Message type mask */ char *where; /* Filename/program name */ char *mail_cmd; /* Mail command */ int syslog_facility; /* Syslog Facility */ POOLMEM *mail_filename; /* Unique mail filename */ } DEST; /* * Message Destination values for dest field of DEST * * MD_SYSLOG Send msg to syslog * MD_MAIL Email group of messages * MD_FILE Write messages to a file * MD_APPEND Append messages to a file * MD_STDOUT Print messages * MD_STDERR Print messages to stderr * MD_DIRECTOR, Send message to the Director * MD_OPERATOR Email a single message to the operator * MD_CONSOLE Send msg to UserAgent or console * MD_MAIL_ON_ERROR Email messages if job errors * MD_MAIL_ON_SUCCESS Email messages if job succeeds * MD_CATALOG */ enum { MD_SYSLOG = 1, MD_MAIL, MD_FILE, MD_APPEND, MD_STDOUT, MD_STDERR, MD_DIRECTOR, MD_OPERATOR, MD_CONSOLE, MD_MAIL_ON_ERROR, MD_MAIL_ON_SUCCESS, MD_CATALOG }; /* * Queued message item */ struct MQUEUE_ITEM { dlink link; int type; utime_t mtime; char msg[1]; }; extern "C" { typedef char *(*job_code_callback_t)(JCR *, const char *); } void Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...); void Qmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...); bool get_trace(void); const char *get_basename(const char *pathname); typedef bool (*db_log_insert_func)(JCR *jcr, utime_t mtime, char *msg); extern DLL_IMP_EXP db_log_insert_func p_db_log_insert; extern DLL_IMP_EXP int debug_level; extern DLL_IMP_EXP bool dbg_timestamp; /* print timestamp in debug output */ extern DLL_IMP_EXP bool prt_kaboom; /* Print kaboom output */ extern DLL_IMP_EXP int verbose; extern DLL_IMP_EXP char my_name[]; extern DLL_IMP_EXP const char *assert_msg; /* Assert error message */ extern DLL_IMP_EXP const char *working_directory; extern DLL_IMP_EXP utime_t daemon_start_time; extern DLL_IMP_EXP int console_msg_pending; extern DLL_IMP_EXP FILE *con_fd; /* Console file descriptor */ extern DLL_IMP_EXP brwlock_t con_lock; /* Console lock structure */ bareos-Release-14.2.6/src/lib/mntent_cache.c000066400000000000000000000375121263011562700206010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * This code implements a cache with the current mounted filesystems for which * its uses the mostly in kernel mount information and export the different OS * specific interfaces using a generic interface. We use a linked list cache * which is accessed using a binary search on the device id and we keep the * previous cache hit as most of the time we get called quite a lot with most * of the time the same device so keeping the previous cache hit we have a * very optimized code path. * * This interface is implemented for the following OS-es: * * - Linux * - HPUX * - DARWIN (OSX) * - IRIX * - AIX * - OSF1 (Tru64) * - Solaris * * Currently we only use this code for Linux and OSF1 based fstype determination. * For the other OS-es we can use the fstype present in stat structure on those OS-es. * * This code replaces the big switch we used before based on SUPER_MAGIC present in * the statfs(2) structure but which need extra code for each new filesystem added to * the OS and for Linux that tends to be often as it has quite some different filesystems. * This new implementation should eliminate this as we use the Linux /proc/mounts in kernel * data which automatically adds any new filesystem when added to the kernel. */ /* * Marco van Wieringen, August 2009 */ #include "bareos.h" #include "mntent_cache.h" #include #include #include #include #include #if defined(HAVE_GETMNTENT) #if defined(HAVE_LINUX_OS) || \ defined(HAVE_HPUX_OS) || \ defined(HAVE_AIX_OS) #include #elif defined(HAVE_SUN_OS) #include #elif defined(HAVE_HURD_OS) #include #include #endif /* HAVE_GETMNTENT */ #elif defined(HAVE_GETMNTINFO) #if defined(HAVE_OPENBSD_OS) #include #include #elif defined(HAVE_NETBSD_OS) #include #include #else #include #include #include #endif #elif defined(HAVE_AIX_OS) #include #include #elif defined(HAVE_OSF1_OS) #include #endif /* * Protected data by mutex lock. */ static pthread_mutex_t mntent_cache_lock = PTHREAD_MUTEX_INITIALIZER; static mntent_cache_entry_t *previous_cache_hit = NULL; static dlist *mntent_cache_entries = NULL; /* * Last time a rescan of the mountlist took place. */ static time_t last_rescan = 0; static const char *skipped_fs_types[] = { #if defined(HAVE_LINUX_OS) "rootfs", #endif NULL }; /** * Simple comparison function for binary search and insert. */ static int compare_mntent_mapping(void *e1, void *e2) { mntent_cache_entry_t *mce1, *mce2; mce1 = (mntent_cache_entry_t *)e1; mce2 = (mntent_cache_entry_t *)e2; if (mce1->dev == mce2->dev) { return 0; } else { return (mce1->dev < mce2->dev) ? -1 : 1; } } /** * Free the members of the mntent_cache structure not the structure itself. */ static inline void destroy_mntent_cache_entry(mntent_cache_entry_t *mce) { if (mce->mntopts) { free(mce->mntopts); } free(mce->fstype); free(mce->mountpoint); free(mce->special); } /** * Add a new entry to the cache. * This function should be called with a write lock on the mntent_cache. */ static mntent_cache_entry_t *add_mntent_mapping(uint32_t dev, const char *special, const char *mountpoint, const char *fstype, const char *mntopts) { mntent_cache_entry_t *mce; mce = (mntent_cache_entry_t *)malloc(sizeof(mntent_cache_entry_t)); memset(mce, 0, sizeof(mntent_cache_entry_t)); mce->dev = dev; mce->special = bstrdup(special); mce->mountpoint = bstrdup(mountpoint); mce->fstype = bstrdup(fstype); if (mntopts) { mce->mntopts = bstrdup(mntopts); } mntent_cache_entries->binary_insert(mce, compare_mntent_mapping); return mce; } /** * Update an entry in the cache. * This function should be called with a write lock on the mntent_cache. */ static mntent_cache_entry_t *update_mntent_mapping(uint32_t dev, const char *special, const char *mountpoint, const char *fstype, const char *mntopts) { mntent_cache_entry_t lookup, *mce; lookup.dev = dev; mce = (mntent_cache_entry_t *)mntent_cache_entries->binary_search(&lookup, compare_mntent_mapping); if (mce) { /* * See if the info changed. */ if (!bstrcmp(mce->special, special)) { free(mce->special); mce->special = bstrdup(special); } if (!bstrcmp(mce->mountpoint, mountpoint)) { free(mce->mountpoint); mce->mountpoint = bstrdup(mountpoint); } if (!bstrcmp(mce->fstype, fstype)) { free(mce->fstype); mce->fstype = bstrdup(fstype); } if (!bstrcmp(mce->mntopts, mntopts)) { free(mce->mntopts); mce->mntopts = bstrdup(mntopts); } } else { mce = add_mntent_mapping(dev, special, mountpoint, fstype, mntopts); } mce->validated = true; return mce; } static inline bool skip_fstype(const char *fstype) { int i; for (i = 0; skipped_fs_types[i]; i++) { if (bstrcmp(fstype, skipped_fs_types[i])) return true; } return false; } /** * OS specific function to load the different mntents into the cache. * This function should be called with a write lock on the mntent_cache. */ static void refresh_mount_cache(mntent_cache_entry_t *handle_entry(uint32_t dev, const char *special, const char *mountpoint, const char *fstype, const char *mntopts)) { #if defined(HAVE_GETMNTENT) FILE *fp; struct stat st; #if defined(HAVE_LINUX_OS) || \ defined(HAVE_HPUX_OS) || \ defined(HAVE_IRIX_OS) || \ defined(HAVE_AIX_OS) || \ defined(HAVE_HURD_OS) struct mntent *mnt; #if defined(HAVE_LINUX_OS) if ((fp = setmntent("/proc/mounts", "r")) == (FILE *)NULL) { if ((fp = setmntent(_PATH_MOUNTED, "r")) == (FILE *)NULL) { return; } } #elif defined(HAVE_HPUX_OS) if ((fp = fopen(MNT_MNTTAB, "r")) == (FILE *)NULL) { return; } #elif defined(HAVE_IRIX_OS) if ((fp = setmntent(MOUNTED, "r")) == (FILE *)NULL) { return; } #elif defined(HAVE_AIX_OS) if ((fp = setmntent(MNTTAB, "r")) == (FILE *)NULL) { return; } #elif defined(HAVE_HURD_OS) if ((fp = setmntent(_PATH_MNTTAB, "r")) == (FILE *)NULL) { return; } #endif while ((mnt = getmntent(fp)) != (struct mntent *)NULL) { if (skip_fstype(mnt->mnt_type)) { continue; } if (stat(mnt->mnt_dir, &st) < 0) { continue; } handle_entry(st.st_dev, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts); } endmntent(fp); #elif defined(HAVE_SUN_OS) struct mnttab mnt; if ((fp = fopen(MNTTAB, "r")) == (FILE *)NULL) return; while (getmntent(fp, &mnt) == 0) { if (skip_fstype(mnt.mnt_fstype)) { continue; } if (stat(mnt.mnt_mountp, &st) < 0) { continue; } handle_entry(st.st_dev, mnt.mnt_special, mnt.mnt_mountp, mnt.mnt_fstype, mnt.mnt_mntopts); } fclose(fp); #endif /* HAVE_SUN_OS */ #elif defined(HAVE_GETMNTINFO) int cnt; struct stat st; #if defined(HAVE_NETBSD_OS) struct statvfs *mntinfo; #else struct statfs *mntinfo; #endif #if defined(ST_NOWAIT) int flags = ST_NOWAIT; #elif defined(MNT_NOWAIT) int flags = MNT_NOWAIT; #else int flags = 0; #endif if ((cnt = getmntinfo(&mntinfo, flags)) > 0) { while (cnt > 0) { if (!skip_fstype(mntinfo->f_fstypename) && stat(mntinfo->f_mntonname, &st) == 0) { handle_entry(st.st_dev, mntinfo->f_mntfromname, mntinfo->f_mntonname, mntinfo->f_fstypename, NULL); } mntinfo++; cnt--; } } #elif defined(HAVE_AIX_OS) int bufsize; char *entries, *current; struct vmount *vmp; struct stat st; struct vfs_ent *ve; int n_entries, cnt; if (mntctl(MCTL_QUERY, sizeof(bufsize), (struct vmount *)&bufsize) != 0) { return; } entries = malloc(bufsize); if ((n_entries = mntctl(MCTL_QUERY, bufsize, (struct vmount *) entries)) < 0) { free(entries); return; } cnt = 0; current = entries; while (cnt < n_entries) { vmp = (struct vmount *)current; if (skip_fstype(ve->vfsent_name)) { continue; } if (stat(current + vmp->vmt_data[VMT_STUB].vmt_off, &st) < 0) { continue; } ve = getvfsbytype(vmp->vmt_gfstype); if (ve && ve->vfsent_name) { handle_entry(st.st_dev, current + vmp->vmt_data[VMT_OBJECT].vmt_off, current + vmp->vmt_data[VMT_STUB].vmt_off, ve->vfsent_name, current + vmp->vmt_data[VMT_ARGS].vmt_off); } current = current + vmp->vmt_length; cnt++; } free(entries); #elif defined(HAVE_OSF1_OS) struct statfs *entries, *current; struct stat st; int n_entries, cnt; int size; if ((n_entries = getfsstat((struct statfs *)0, 0L, MNT_NOWAIT)) < 0) { return; } size = (n_entries + 1) * sizeof(struct statfs); entries = malloc(size); if ((n_entries = getfsstat(entries, size, MNT_NOWAIT)) < 0) { free(entries); return; } cnt = 0; current = entries; while (cnt < n_entries) { if (skip_fstype(current->f_fstypename)) { continue; } if (stat(current->f_mntonname, &st) < 0) { continue; } handle_entry(st.st_dev, current->f_mntfromname, current->f_mntonname, current->f_fstypename, NULL); current++; cnt++; } free(stats); #endif } /** * Initialize the cache for use. * This function should be called with a write lock on the mntent_cache. */ static inline void initialize_mntent_cache(void) { mntent_cache_entry_t *mce = NULL; mntent_cache_entries = New(dlist(mce, &mce->link)); /** * Refresh the cache. */ refresh_mount_cache(add_mntent_mapping); } /** * Repopulate the cache with new data. * This function should be called with a write lock on the mntent_cache. */ static void repopulate_mntent_cache(void) { mntent_cache_entry_t *mce, *next_mce; /** * Reset validated flag on all entries in the cache. */ foreach_dlist(mce, mntent_cache_entries) { mce->validated = false; } /** * Refresh the cache. */ refresh_mount_cache(update_mntent_mapping); /** * Remove any entry that is not validated in * the previous refresh run. */ mce = (mntent_cache_entry_t *)mntent_cache_entries->first(); while (mce) { next_mce = (mntent_cache_entry_t *)mntent_cache_entries->next(mce); if (!mce->validated) { /** * Invalidate the previous cache hit if we are removing it. */ if (previous_cache_hit == mce) { previous_cache_hit = NULL; } /** * See if this is an outstanding entry. * e.g. when reference_count > 0 set * the entry to destroyed and remove it * from the list. But don't free the data * yet. The put_mntent_mapping function will * handle these dangling entries. */ if (mce->reference_count == 0) { mntent_cache_entries->remove(mce); destroy_mntent_cache_entry(mce); free(mce); } else { mce->destroyed = true; mntent_cache_entries->remove(mce); } } mce = next_mce; } } /** * Flush the current content from the cache. */ void flush_mntent_cache(void) { mntent_cache_entry_t *mce; /** * Lock the cache. */ P(mntent_cache_lock); if (mntent_cache_entries) { previous_cache_hit = NULL; foreach_dlist(mce, mntent_cache_entries) { destroy_mntent_cache_entry(mce); } mntent_cache_entries->destroy(); delete mntent_cache_entries; mntent_cache_entries = NULL; } V(mntent_cache_lock); } /** * Release a mntent mapping reference returned * by a successfull call to find_mntent_mapping. */ void release_mntent_mapping(mntent_cache_entry_t *mce) { /** * Lock the cache. */ P(mntent_cache_lock); mce->reference_count--; /** * See if this entry is a dangling entry. */ if (mce->reference_count == 0 && mce->destroyed) { destroy_mntent_cache_entry(mce); free(mce); } V(mntent_cache_lock); } /** * Find a mapping in the cache. */ mntent_cache_entry_t *find_mntent_mapping(uint32_t dev) { mntent_cache_entry_t lookup, *mce = NULL; time_t now; /** * Lock the cache. */ P(mntent_cache_lock); /** * Shortcut when we get a request for the same device again. */ if (previous_cache_hit && previous_cache_hit->dev == dev) { mce = previous_cache_hit; mce->reference_count++; goto ok_out; } /** * Initialize the cache if that was not done before. */ if (!mntent_cache_entries) { initialize_mntent_cache(); last_rescan = time(NULL); } else { /** * We rescan the mountlist when called when more then * MNTENT_RESCAN_INTERVAL seconds have past since the * last rescan. This way we never work with data older * then MNTENT_RESCAN_INTERVAL seconds. */ now = time(NULL); if ((now - last_rescan) > MNTENT_RESCAN_INTERVAL) { repopulate_mntent_cache(); last_rescan = time(NULL); } } lookup.dev = dev; mce = (mntent_cache_entry_t *)mntent_cache_entries->binary_search(&lookup, compare_mntent_mapping); /** * If we fail to lookup the mountpoint its probably a mountpoint added * after we did our initial scan. Lets rescan the mountlist and try * the lookup again. */ if (!mce) { repopulate_mntent_cache(); mce = (mntent_cache_entry_t *)mntent_cache_entries->binary_search(&lookup, compare_mntent_mapping); } /** * Store the last successfull lookup as the previous_cache_hit. * And increment the reference count. */ if (mce) { previous_cache_hit = mce; mce->reference_count++; } ok_out: V(mntent_cache_lock); return mce; } bareos-Release-14.2.6/src/lib/mntent_cache.h000066400000000000000000000035001263011562700205740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, August 2009 */ #ifndef _MNTENT_CACHE_H #define _MNTENT_CACHE_H 1 /* * Don't use the mountlist data when its older then this amount * of seconds but perform a rescan of the mountlist. */ #define MNTENT_RESCAN_INTERVAL 1800 /* * Initial size of number of hash entries we expect in the cache. * If more are needed the hash table will grow as needed. */ #define NR_MNTENT_CACHE_ENTRIES 256 /* * Number of pages to allocate for the big_buffer used by htable. */ #define NR_MNTENT_HTABLE_PAGES 32 struct mntent_cache_entry_t { dlink link; uint32_t dev; char *special; char *mountpoint; char *fstype; char *mntopts; int reference_count; bool validated; bool destroyed; }; mntent_cache_entry_t *find_mntent_mapping(uint32_t dev); void release_mntent_mapping(mntent_cache_entry_t *mce); void flush_mntent_cache(void); #endif /* _MNTENT_CACHE_H */ bareos-Release-14.2.6/src/lib/msg_res.h000066400000000000000000000045071263011562700176130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January MM * * Extracted from other source files by Marco van Wieringen, April 2014 */ #ifndef _MSGS_RES_H #define _MSGS_RES_H 1 /* * Message resource directives * name config_data_type value code flags default_value */ static RES_ITEM msgs_items[] = { { "Name", CFG_TYPE_NAME, ITEM(res_msgs.hdr.name), 0, 0, NULL }, { "Description", CFG_TYPE_STR, ITEM(res_msgs.hdr.desc), 0, 0, NULL }, { "MailCommand", CFG_TYPE_STR, ITEM(res_msgs.mail_cmd), 0, 0, NULL }, { "OperatorCommand", CFG_TYPE_STR, ITEM(res_msgs.operator_cmd), 0, 0, NULL }, { "Syslog", CFG_TYPE_MSGS, ITEM(res_msgs), MD_SYSLOG, 0, NULL }, { "Mail", CFG_TYPE_MSGS, ITEM(res_msgs), MD_MAIL, 0, NULL }, { "MailOnError", CFG_TYPE_MSGS, ITEM(res_msgs), MD_MAIL_ON_ERROR, 0, NULL }, { "MailOnSuccess", CFG_TYPE_MSGS, ITEM(res_msgs), MD_MAIL_ON_SUCCESS, 0, NULL }, { "File", CFG_TYPE_MSGS, ITEM(res_msgs), MD_FILE, 0, NULL }, { "Append", CFG_TYPE_MSGS, ITEM(res_msgs), MD_APPEND, 0, NULL }, { "Stdout", CFG_TYPE_MSGS, ITEM(res_msgs), MD_STDOUT, 0, NULL }, { "Stderr", CFG_TYPE_MSGS, ITEM(res_msgs), MD_STDERR, 0, NULL }, { "Director", CFG_TYPE_MSGS, ITEM(res_msgs), MD_DIRECTOR, 0, NULL }, { "Console", CFG_TYPE_MSGS, ITEM(res_msgs), MD_CONSOLE, 0, NULL }, { "Operator", CFG_TYPE_MSGS, ITEM(res_msgs), MD_OPERATOR, 0, NULL }, { "Catalog", CFG_TYPE_MSGS, ITEM(res_msgs), MD_CATALOG, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; #endif /* _MSGS_RES_H */ bareos-Release-14.2.6/src/lib/mutex_list.h000066400000000000000000000025651263011562700203530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MUTEX_LIST_H #define MUTEX_LIST_H 1 /* * Use this list to manage lock order and protect the BAREOS from * race conditions and dead locks */ #define PRIO_SD_DEV_ACQUIRE 4 /* dev.acquire_mutex */ #define PRIO_SD_DEV_ACCESS 5 /* dev.m_mutex */ #define PRIO_SD_VOL_LIST 0 /* vol_list_lock */ #define PRIO_SD_READ_VOL_LIST 12 /* read_vol_list */ #define PRIO_SD_DEV_SPOOL 14 /* dev.spool_mutex */ #define PRIO_SD_ACH_ACCESS 16 /* autochanger lock mutex */ #endif bareos-Release-14.2.6/src/lib/parse_bsr.c000066400000000000000000000574061263011562700201350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Parse Bootstrap Records (used for restores) * * Kern Sibbald, June MMII */ #include "bareos.h" #include "jcr.h" #include "bsr.h" typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr); static BSR *store_vol(LEX *lc, BSR *bsr); static BSR *store_mediatype(LEX *lc, BSR *bsr); static BSR *store_device(LEX *lc, BSR *bsr); static BSR *store_client(LEX *lc, BSR *bsr); static BSR *store_job(LEX *lc, BSR *bsr); static BSR *store_jobid(LEX *lc, BSR *bsr); static BSR *store_count(LEX *lc, BSR *bsr); static BSR *store_jobtype(LEX *lc, BSR *bsr); static BSR *store_joblevel(LEX *lc, BSR *bsr); static BSR *store_findex(LEX *lc, BSR *bsr); static BSR *store_sessid(LEX *lc, BSR *bsr); static BSR *store_volfile(LEX *lc, BSR *bsr); static BSR *store_volblock(LEX *lc, BSR *bsr); static BSR *store_voladdr(LEX *lc, BSR *bsr); static BSR *store_sesstime(LEX *lc, BSR *bsr); static BSR *store_include(LEX *lc, BSR *bsr); static BSR *store_exclude(LEX *lc, BSR *bsr); static BSR *store_stream(LEX *lc, BSR *bsr); static BSR *store_slot(LEX *lc, BSR *bsr); static BSR *store_fileregex(LEX *lc, BSR *bsr); static BSR *store_nothing(LEX *lc, BSR *bsr); struct kw_items { const char *name; ITEM_HANDLER *handler; }; /* * List of all keywords permitted in bsr files and their handlers */ struct kw_items items[] = { { "volume", store_vol }, { "mediatype", store_mediatype }, { "client", store_client }, { "job", store_job }, { "jobid", store_jobid }, { "count", store_count }, { "fileindex", store_findex }, { "jobtype", store_jobtype }, { "joblevel", store_joblevel }, { "volsessionid", store_sessid }, { "volsessiontime", store_sesstime }, { "include", store_include }, { "exclude", store_exclude }, { "volfile", store_volfile }, { "volblock", store_volblock }, { "voladdr", store_voladdr }, { "stream", store_stream }, { "slot", store_slot }, { "device", store_device }, { "fileregex", store_fileregex }, { "storage", store_nothing }, { NULL, NULL } }; /* * Create a BSR record */ static BSR *new_bsr() { BSR *bsr = (BSR *)malloc(sizeof(BSR)); memset(bsr, 0, sizeof(BSR)); return bsr; } /* * Format a scanner error message */ static void s_err(const char *file, int line, LEX *lc, const char *msg, ...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_NAME); JCR *jcr = (JCR *)(lc->caller_ctx); while (1) { maxlen = buf.size() - 1; va_start(ap, msg); len = bvsnprintf(buf.c_str(), maxlen, msg, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } if (jcr) { Jmsg(jcr, M_FATAL, 0, _("Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); } else { e_msg(file, line, M_FATAL, 0, _("Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); } } /* * Format a scanner warning message */ static void s_warn(const char *file, int line, LEX *lc, const char *msg, ...) { va_list ap; int len, maxlen; POOL_MEM buf(PM_NAME); JCR *jcr = (JCR *)(lc->caller_ctx); while (1) { maxlen = buf.size() - 1; va_start(ap, msg); len = bvsnprintf(buf.c_str(), maxlen, msg, ap); va_end(ap); if (len < 0 || len >= (maxlen - 5)) { buf.realloc_pm(maxlen + maxlen / 2); continue; } break; } if (jcr) { Jmsg(jcr, M_WARNING, 0, _("Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); } else { p_msg(file, line, 0, _("Bootstrap file warning: %s\n" " : Line %d, col %d of file %s\n%s\n"), buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line); } } static inline bool is_fast_rejection_ok(BSR *bsr) { /* * Although, this can be optimized, for the moment, require * all bsrs to have both sesstime and sessid set before * we do fast rejection. */ for ( ; bsr; bsr=bsr->next) { if (!(bsr->sesstime && bsr->sessid)) { return false; } } return true; } static inline bool is_positioning_ok(BSR *bsr) { /* * Every bsr should have a volfile entry and a volblock entry * or a VolAddr * if we are going to use positioning */ for ( ; bsr; bsr=bsr->next) { if (!((bsr->volfile && bsr->volblock) || bsr->voladdr)) { return false; } } return true; } /* * Parse Bootstrap file */ BSR *parse_bsr(JCR *jcr, char *fname) { LEX *lc = NULL; int token, i; BSR *root_bsr = new_bsr(); BSR *bsr = root_bsr; Dmsg1(300, "Enter parse_bsf %s\n", fname); if ((lc = lex_open_file(lc, fname, s_err, s_warn)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"), fname, be.bstrerror()); } lc->caller_ctx = (void *)jcr; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { continue; } for (i=0; items[i].name; i++) { if (bstrcasecmp(items[i].name, lc->str)) { token = lex_get_token(lc, T_ALL); Dmsg1 (300, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); if (token != T_EQUALS) { scan_err1(lc, "expected an equals, got: %s", lc->str); bsr = NULL; break; } Dmsg1(300, "calling handler for %s\n", items[i].name); /* * Call item handler */ bsr = items[i].handler(lc, bsr); i = -1; break; } } if (i >= 0) { Dmsg1(300, "Keyword = %s\n", lc->str); scan_err1(lc, "Keyword %s not found", lc->str); bsr = NULL; break; } if (!bsr) { break; } } lc = lex_close_file(lc); Dmsg0(300, "Leave parse_bsf()\n"); if (!bsr) { free_bsr(root_bsr); root_bsr = NULL; } if (root_bsr) { root_bsr->use_fast_rejection = is_fast_rejection_ok(root_bsr); root_bsr->use_positioning = is_positioning_ok(root_bsr); } for (bsr=root_bsr; bsr; bsr=bsr->next) { bsr->root = root_bsr; } return root_bsr; } static BSR *store_vol(LEX *lc, BSR *bsr) { int token; BSR_VOLUME *volume; char *p, *n; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } if (bsr->volume) { bsr->next = new_bsr(); bsr->next->prev = bsr; bsr = bsr->next; } /* This may actually be more than one volume separated by a | * If so, separate them. */ for (p=lc->str; p && *p; ) { n = strchr(p, '|'); if (n) { *n++ = 0; } volume = (BSR_VOLUME *)malloc(sizeof(BSR_VOLUME)); memset(volume, 0, sizeof(BSR_VOLUME)); bstrncpy(volume->VolumeName, p, sizeof(volume->VolumeName)); /* * Add it to the end of the volume chain */ if (!bsr->volume) { bsr->volume = volume; } else { BSR_VOLUME *bc = bsr->volume; for ( ;bc->next; bc=bc->next) { } bc->next = volume; } p = n; } return bsr; } /* * Shove the MediaType in each Volume in the current bsr\ */ static BSR *store_mediatype(LEX *lc, BSR *bsr) { int token; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } if (!bsr->volume) { Emsg1(M_ERROR,0, _("MediaType %s in bsr at inappropriate place.\n"), lc->str); return bsr; } BSR_VOLUME *bv; for (bv=bsr->volume; bv; bv=bv->next) { bstrncpy(bv->MediaType, lc->str, sizeof(bv->MediaType)); } return bsr; } static BSR *store_nothing(LEX *lc, BSR *bsr) { int token; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } return bsr; } /* * Shove the Device name in each Volume in the current bsr */ static BSR *store_device(LEX *lc, BSR *bsr) { int token; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } if (!bsr->volume) { Emsg1(M_ERROR,0, _("Device \"%s\" in bsr at inappropriate place.\n"), lc->str); return bsr; } BSR_VOLUME *bv; for (bv=bsr->volume; bv; bv=bv->next) { bstrncpy(bv->device, lc->str, sizeof(bv->device)); } return bsr; } static BSR *store_client(LEX *lc, BSR *bsr) { int token; BSR_CLIENT *client; for (;;) { token = lex_get_token(lc, T_NAME); if (token == T_ERROR) { return NULL; } client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT)); memset(client, 0, sizeof(BSR_CLIENT)); bstrncpy(client->ClientName, lc->str, sizeof(client->ClientName)); /* * Add it to the end of the client chain */ if (!bsr->client) { bsr->client = client; } else { BSR_CLIENT *bc = bsr->client; for ( ;bc->next; bc=bc->next) { } bc->next = client; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_job(LEX *lc, BSR *bsr) { int token; BSR_JOB *job; for (;;) { token = lex_get_token(lc, T_NAME); if (token == T_ERROR) { return NULL; } job = (BSR_JOB *)malloc(sizeof(BSR_JOB)); memset(job, 0, sizeof(BSR_JOB)); bstrncpy(job->Job, lc->str, sizeof(job->Job)); /* * Add it to the end of the client chain */ if (!bsr->job) { bsr->job = job; } else { /* * Add to end of chain */ BSR_JOB *bc = bsr->job; for ( ;bc->next; bc=bc->next) { } bc->next = job; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_findex(LEX *lc, BSR *bsr) { int token; BSR_FINDEX *findex; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX)); memset(findex, 0, sizeof(BSR_FINDEX)); findex->findex = lc->pint32_val; findex->findex2 = lc->pint32_val2; /* * Add it to the end of the chain */ if (!bsr->FileIndex) { bsr->FileIndex = findex; } else { /* * Add to end of chain */ BSR_FINDEX *bs = bsr->FileIndex; for ( ;bs->next; bs=bs->next) { } bs->next = findex; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_jobid(LEX *lc, BSR *bsr) { int token; BSR_JOBID *jobid; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID)); memset(jobid, 0, sizeof(BSR_JOBID)); jobid->JobId = lc->pint32_val; jobid->JobId2 = lc->pint32_val2; /* * Add it to the end of the chain */ if (!bsr->JobId) { bsr->JobId = jobid; } else { /* * Add to end of chain */ BSR_JOBID *bs = bsr->JobId; for ( ;bs->next; bs=bs->next) { } bs->next = jobid; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_count(LEX *lc, BSR *bsr) { int token; token = lex_get_token(lc, T_PINT32); if (token == T_ERROR) { return NULL; } bsr->count = lc->pint32_val; scan_to_eol(lc); return bsr; } static BSR *store_fileregex(LEX *lc, BSR *bsr) { int token; int rc; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } if (bsr->fileregex) free(bsr->fileregex); bsr->fileregex = bstrdup(lc->str); if (bsr->fileregex_re == NULL) bsr->fileregex_re = (regex_t *)bmalloc(sizeof(regex_t)); rc = regcomp(bsr->fileregex_re, bsr->fileregex, REG_EXTENDED|REG_NOSUB); if (rc != 0) { char prbuf[500]; regerror(rc, bsr->fileregex_re, prbuf, sizeof(prbuf)); Emsg2(M_ERROR, 0, _("REGEX '%s' compile error. ERR=%s\n"), bsr->fileregex, prbuf); return NULL; } return bsr; } static BSR *store_jobtype(LEX *lc, BSR *bsr) { /* *****FIXME****** */ Pmsg0(-1, _("JobType not yet implemented\n")); return bsr; } static BSR *store_joblevel(LEX *lc, BSR *bsr) { /* *****FIXME****** */ Pmsg0(-1, _("JobLevel not yet implemented\n")); return bsr; } /* * Routine to handle Volume start/end file */ static BSR *store_volfile(LEX *lc, BSR *bsr) { int token; BSR_VOLFILE *volfile; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE)); memset(volfile, 0, sizeof(BSR_VOLFILE)); volfile->sfile = lc->pint32_val; volfile->efile = lc->pint32_val2; /* * Add it to the end of the chain */ if (!bsr->volfile) { bsr->volfile = volfile; } else { /* * Add to end of chain */ BSR_VOLFILE *bs = bsr->volfile; for ( ;bs->next; bs=bs->next) { } bs->next = volfile; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } /* * Routine to handle Volume start/end Block */ static BSR *store_volblock(LEX *lc, BSR *bsr) { int token; BSR_VOLBLOCK *volblock; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } volblock = (BSR_VOLBLOCK *)malloc(sizeof(BSR_VOLBLOCK)); memset(volblock, 0, sizeof(BSR_VOLBLOCK)); volblock->sblock = lc->pint32_val; volblock->eblock = lc->pint32_val2; /* * Add it to the end of the chain */ if (!bsr->volblock) { bsr->volblock = volblock; } else { /* * Add to end of chain */ BSR_VOLBLOCK *bs = bsr->volblock; for ( ;bs->next; bs=bs->next) { } bs->next = volblock; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } /* * Routine to handle Volume start/end address */ static BSR *store_voladdr(LEX *lc, BSR *bsr) { int token; BSR_VOLADDR *voladdr; for (;;) { token = lex_get_token(lc, T_PINT64_RANGE); if (token == T_ERROR) { return NULL; } voladdr = (BSR_VOLADDR *)malloc(sizeof(BSR_VOLADDR)); memset(voladdr, 0, sizeof(BSR_VOLADDR)); voladdr->saddr = lc->pint64_val; voladdr->eaddr = lc->pint64_val2; /* * Add it to the end of the chain */ if (!bsr->voladdr) { bsr->voladdr = voladdr; } else { /* * Add to end of chain */ BSR_VOLADDR *bs = bsr->voladdr; for ( ;bs->next; bs=bs->next) { } bs->next = voladdr; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_sessid(LEX *lc, BSR *bsr) { int token; BSR_SESSID *sid; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID)); memset(sid, 0, sizeof(BSR_SESSID)); sid->sessid = lc->pint32_val; sid->sessid2 = lc->pint32_val2; /* * Add it to the end of the chain */ if (!bsr->sessid) { bsr->sessid = sid; } else { /* * Add to end of chain */ BSR_SESSID *bs = bsr->sessid; for ( ;bs->next; bs=bs->next) { } bs->next = sid; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_sesstime(LEX *lc, BSR *bsr) { int token; BSR_SESSTIME *stime; for (;;) { token = lex_get_token(lc, T_PINT32); if (token == T_ERROR) { return NULL; } stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME)); memset(stime, 0, sizeof(BSR_SESSTIME)); stime->sesstime = lc->pint32_val; /* * Add it to the end of the chain */ if (!bsr->sesstime) { bsr->sesstime = stime; } else { /* * Add to end of chain */ BSR_SESSTIME *bs = bsr->sesstime; for ( ;bs->next; bs=bs->next) { } bs->next = stime; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_stream(LEX *lc, BSR *bsr) { int token; BSR_STREAM *stream; for (;;) { token = lex_get_token(lc, T_INT32); if (token == T_ERROR) { return NULL; } stream = (BSR_STREAM *)malloc(sizeof(BSR_STREAM)); memset(stream, 0, sizeof(BSR_STREAM)); stream->stream = lc->int32_val; /* * Add it to the end of the chain */ if (!bsr->stream) { bsr->stream = stream; } else { /* * Add to end of chain */ BSR_STREAM *bs = bsr->stream; for ( ;bs->next; bs=bs->next) { } bs->next = stream; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; } static BSR *store_slot(LEX *lc, BSR *bsr) { int token; token = lex_get_token(lc, T_PINT32); if (token == T_ERROR) { return NULL; } if (!bsr->volume) { Emsg1(M_ERROR,0, _("Slot %d in bsr at inappropriate place.\n"), lc->pint32_val); return bsr; } bsr->volume->Slot = lc->pint32_val; scan_to_eol(lc); return bsr; } static BSR *store_include(LEX *lc, BSR *bsr) { scan_to_eol(lc); return bsr; } static BSR *store_exclude(LEX *lc, BSR *bsr) { scan_to_eol(lc); return bsr; } static inline void dump_volfile(BSR_VOLFILE *volfile) { if (volfile) { Pmsg2(-1, _("VolFile : %u-%u\n"), volfile->sfile, volfile->efile); dump_volfile(volfile->next); } } static inline void dump_volblock(BSR_VOLBLOCK *volblock) { if (volblock) { Pmsg2(-1, _("VolBlock : %u-%u\n"), volblock->sblock, volblock->eblock); dump_volblock(volblock->next); } } static inline void dump_voladdr(BSR_VOLADDR *voladdr) { if (voladdr) { Pmsg2(-1, _("VolAddr : %llu-%llu\n"), voladdr->saddr, voladdr->eaddr); dump_voladdr(voladdr->next); } } static inline void dump_findex(BSR_FINDEX *FileIndex) { if (FileIndex) { if (FileIndex->findex == FileIndex->findex2) { Pmsg1(-1, _("FileIndex : %u\n"), FileIndex->findex); } else { Pmsg2(-1, _("FileIndex : %u-%u\n"), FileIndex->findex, FileIndex->findex2); } dump_findex(FileIndex->next); } } static inline void dump_jobid(BSR_JOBID *jobid) { if (jobid) { if (jobid->JobId == jobid->JobId2) { Pmsg1(-1, _("JobId : %u\n"), jobid->JobId); } else { Pmsg2(-1, _("JobId : %u-%u\n"), jobid->JobId, jobid->JobId2); } dump_jobid(jobid->next); } } static inline void dump_sessid(BSR_SESSID *sessid) { if (sessid) { if (sessid->sessid == sessid->sessid2) { Pmsg1(-1, _("SessId : %u\n"), sessid->sessid); } else { Pmsg2(-1, _("SessId : %u-%u\n"), sessid->sessid, sessid->sessid2); } dump_sessid(sessid->next); } } static inline void dump_volume(BSR_VOLUME *volume) { if (volume) { Pmsg1(-1, _("VolumeName : %s\n"), volume->VolumeName); Pmsg1(-1, _(" MediaType : %s\n"), volume->MediaType); Pmsg1(-1, _(" Device : %s\n"), volume->device); Pmsg1(-1, _(" Slot : %d\n"), volume->Slot); dump_volume(volume->next); } } static inline void dump_client(BSR_CLIENT *client) { if (client) { Pmsg1(-1, _("Client : %s\n"), client->ClientName); dump_client(client->next); } } static inline void dump_job(BSR_JOB *job) { if (job) { Pmsg1(-1, _("Job : %s\n"), job->Job); dump_job(job->next); } } static inline void dump_sesstime(BSR_SESSTIME *sesstime) { if (sesstime) { Pmsg1(-1, _("SessTime : %u\n"), sesstime->sesstime); dump_sesstime(sesstime->next); } } void dump_bsr(BSR *bsr, bool recurse) { int save_debug = debug_level; debug_level = 1; if (!bsr) { Pmsg0(-1, _("BSR is NULL\n")); debug_level = save_debug; return; } Pmsg1(-1, _("Next : 0x%x\n"), bsr->next); Pmsg1(-1, _("Root bsr : 0x%x\n"), bsr->root); dump_volume(bsr->volume); dump_sessid(bsr->sessid); dump_sesstime(bsr->sesstime); dump_volfile(bsr->volfile); dump_volblock(bsr->volblock); dump_voladdr(bsr->voladdr); dump_client(bsr->client); dump_jobid(bsr->JobId); dump_job(bsr->job); dump_findex(bsr->FileIndex); if (bsr->count) { Pmsg1(-1, _("count : %u\n"), bsr->count); Pmsg1(-1, _("found : %u\n"), bsr->found); } Pmsg1(-1, _("done : %s\n"), bsr->done?_("yes"):_("no")); Pmsg1(-1, _("positioning : %d\n"), bsr->use_positioning); Pmsg1(-1, _("fast_reject : %d\n"), bsr->use_fast_rejection); if (recurse && bsr->next) { Pmsg0(-1, "\n"); dump_bsr(bsr->next, true); } debug_level = save_debug; } /* * Free bsr resources */ static inline void free_bsr_item(BSR *bsr) { if (bsr) { free_bsr_item(bsr->next); free(bsr); } } /* * Remove a single item from the bsr tree */ static inline void remove_bsr(BSR *bsr) { free_bsr_item((BSR *)bsr->volume); free_bsr_item((BSR *)bsr->client); free_bsr_item((BSR *)bsr->sessid); free_bsr_item((BSR *)bsr->sesstime); free_bsr_item((BSR *)bsr->volfile); free_bsr_item((BSR *)bsr->volblock); free_bsr_item((BSR *)bsr->voladdr); free_bsr_item((BSR *)bsr->JobId); free_bsr_item((BSR *)bsr->job); free_bsr_item((BSR *)bsr->FileIndex); free_bsr_item((BSR *)bsr->JobType); free_bsr_item((BSR *)bsr->JobLevel); if (bsr->fileregex) { bfree(bsr->fileregex); } if (bsr->fileregex_re) { regfree(bsr->fileregex_re); free(bsr->fileregex_re); } if (bsr->attr) { free_attr(bsr->attr); } if (bsr->next) { bsr->next->prev = bsr->prev; } if (bsr->prev) { bsr->prev->next = bsr->next; } free(bsr); } /* * Free all bsrs in chain */ void free_bsr(BSR *bsr) { BSR *next_bsr; if (!bsr) { return; } next_bsr = bsr->next; /* * Remove (free) current bsr */ remove_bsr(bsr); /* * Now get the next one */ free_bsr(next_bsr); } bareos-Release-14.2.6/src/lib/parse_conf.c000066400000000000000000000511731263011562700202670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Master Configuration routines. * * This file contains the common parts of the BAREOS configuration routines. * * Note, the configuration file parser consists of four parts * * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_conf.c and lib/parse_conf.h. * These files contain the parser code, some utility routines, * * 3. The generic resource functions in lib/res.c * Which form the common store routines (name, int, string, time, * int64, size, ...). * * 4. The daemon specific file, which contains the Resource definitions * as well as any specific store routines for the resource records. * * N.B. This is a two pass parser, so if you malloc() a string in a "store" routine, * you must ensure to do it during only one of the two passes, or to free it between. * * Also, note that the resource record is malloced and saved in save_resource() * during pass 1. Anything that you want saved after pass two (e.g. resource pointers) * must explicitly be done in save_resource. Take a look at the Job resource in * src/dird/dird_conf.c to see how it is done. * * Kern Sibbald, January MM */ #include "bareos.h" #if defined(HAVE_WIN32) #include "shlobj.h" #else #define MAX_PATH 1024 #endif /* * Define the Union of all the common resource structure definitions. */ union URES { MSGSRES res_msgs; RES hdr; }; /* Forward referenced subroutines */ static const char *get_default_configdir(); static bool find_config_file(const char *config_file, char *full_path, int max_path); /* Common Resource definitions */ /* * Simply print a message */ static void prtmsg(void *sock, const char *fmt, ...) { va_list arg_ptr; va_start(arg_ptr, fmt); vfprintf(stdout, fmt, arg_ptr); va_end(arg_ptr); } CONFIG *new_config_parser() { CONFIG *config; config = (CONFIG *)malloc(sizeof(CONFIG)); memset(config, 0, sizeof(CONFIG)); return config; } void CONFIG::init(const char *cf, LEX_ERROR_HANDLER *scan_error, LEX_WARNING_HANDLER *scan_warning, INIT_RES_HANDLER *init_res, STORE_RES_HANDLER *store_res, PRINT_RES_HANDLER *print_res, int32_t err_type, void *vres_all, int32_t res_all_size, int32_t r_first, int32_t r_last, RES_TABLE *resources, RES **res_head) { m_cf = cf; m_scan_error = scan_error; m_scan_warning = scan_warning; m_init_res = init_res; m_store_res = store_res; m_print_res = print_res; m_err_type = err_type; m_res_all = vres_all; m_res_all_size = res_all_size; m_r_first = r_first; m_r_last = r_last; m_resources = resources; m_res_head = res_head; } bool CONFIG::parse_config() { LEX *lc = NULL; int token, i, pass; int res_type = 0; enum parse_state state = p_none; RES_ITEM *items = NULL; int level = 0; static bool first = true; int errstat; const char *cf = m_cf; LEX_ERROR_HANDLER *scan_error = m_scan_error; LEX_WARNING_HANDLER *scan_warning = m_scan_warning; int err_type = m_err_type; if (first && (errstat = rwl_init(&m_res_lock)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("Unable to initialize resource lock. ERR=%s\n"), be.bstrerror(errstat)); } first = false; char *full_path = (char *)alloca(MAX_PATH + 1); if (!find_config_file(cf, full_path, MAX_PATH +1)) { Jmsg0(NULL, M_ABORT, 0, _("Config filename too long.\n")); } cf = full_path; /* * Make two passes. The first builds the name symbol table, * and the second picks up the items. */ Dmsg0(900, "Enter parse_config()\n"); for (pass = 1; pass <= 2; pass++) { Dmsg1(900, "parse_config pass %d\n", pass); if ((lc = lex_open_file(lc, cf, scan_error, scan_warning)) == NULL) { berrno be; /* * We must create a lex packet to print the error */ lc = (LEX *)malloc(sizeof(LEX)); memset(lc, 0, sizeof(LEX)); if (scan_error) { lc->scan_error = scan_error; } else { lex_set_default_error_handler(lc); } if (scan_warning) { lc->scan_warning = scan_warning; } else { lex_set_default_warning_handler(lc); } lex_set_error_handler_error_type(lc, err_type) ; scan_err2(lc, _("Cannot open config file \"%s\": %s\n"), cf, be.bstrerror()); free(lc); return 0; } lex_set_error_handler_error_type(lc, err_type) ; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg3(900, "parse state=%d pass=%d got token=%s\n", state, pass, lex_tok_to_str(token)); switch (state) { case p_none: if (token == T_EOL) { break; } else if (token == T_UTF8_BOM) { /* * We can assume the file is UTF-8 as we have seen a UTF-8 BOM */ break; } else if (token == T_UTF16_BOM) { scan_err0(lc, _("Currently we cannot handle UTF-16 source files. " "Please convert the conf file to UTF-8\n")); goto bail_out; } else if (token != T_IDENTIFIER) { scan_err1(lc, _("Expected a Resource name identifier, got: %s"), lc->str); goto bail_out; } for (i = 0; m_resources[i].name; i++) { if (bstrcasecmp(m_resources[i].name, lc->str)) { items = m_resources[i].items; if (!items) { break; } state = p_resource; res_type = m_resources[i].rcode; init_resource(res_type, items, pass); break; } } if (state == p_none) { scan_err1(lc, _("expected resource name, got: %s"), lc->str); goto bail_out; } break; case p_resource: switch (token) { case T_BOB: level++; break; case T_IDENTIFIER: if (level != 1) { scan_err1(lc, _("not in resource definition: %s"), lc->str); goto bail_out; } for (i = 0; items[i].name; i++) { if (bstrcasecmp(items[i].name, lc->str)) { /* * If the CFG_ITEM_NO_EQUALS flag is set we do NOT * scan for = after the keyword */ if (!(items[i].flags & CFG_ITEM_NO_EQUALS)) { token = lex_get_token(lc, T_SKIP_EOL); Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); if (token != T_EQUALS) { scan_err1(lc, _("expected an equals, got: %s"), lc->str); goto bail_out; } } /* * See if we are processing a deprecated keyword if so warn the user about it. */ if (items[i].flags & CFG_ITEM_DEPRECATED) { scan_warn2(lc, _("using deprecated keyword %s on line %d"), items[i].name, lc->line_no); /* * As we only want to warn we continue parsing the config. So no goto bail_out here. */ } Dmsg1(800, "calling handler for %s\n", items[i].name); /* * Call item handler */ if (!store_resource(items[i].type, lc, &items[i], i, pass)) { /* * None of the generic types fired if there is a registered callback call that now. */ if (m_store_res) { m_store_res(lc, &items[i], i, pass); } } i = -1; break; } } if (i >= 0) { Dmsg2(900, "level=%d id=%s\n", level, lc->str); Dmsg1(900, "Keyword = %s\n", lc->str); scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource."), lc->str); goto bail_out; } break; case T_EOB: level--; state = p_none; Dmsg0(900, "T_EOB => define new resource\n"); if (((URES *)m_res_all)->hdr.name == NULL) { scan_err0(lc, _("Name not specified for resource")); goto bail_out; } save_resource(res_type, items, pass); /* save resource */ break; case T_EOL: break; default: scan_err2(lc, _("unexpected token %d %s in resource definition"), token, lex_tok_to_str(token)); goto bail_out; } break; default: scan_err1(lc, _("Unknown parser state %d\n"), state); goto bail_out; } } if (state != p_none) { scan_err0(lc, _("End of conf file reached with unclosed resource.")); goto bail_out; } if (debug_level >= 900 && pass == 2) { int i; for (i = m_r_first; i <= m_r_last; i++) { dump_resource(i, m_res_head[i-m_r_first], prtmsg, NULL, false); } } lc = lex_close_file(lc); } Dmsg0(900, "Leave parse_config()\n"); return 1; bail_out: if (lc) { lc = lex_close_file(lc); } return 0; } const char *get_default_configdir() { #if defined(HAVE_WIN32) HRESULT hr; static char szConfigDir[MAX_PATH + 1] = { 0 }; if (!p_SHGetFolderPath) { bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir)); return szConfigDir; } if (szConfigDir[0] == '\0') { hr = p_SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szConfigDir); if (SUCCEEDED(hr)) { bstrncat(szConfigDir, "\\Bareos", sizeof(szConfigDir)); } else { bstrncpy(szConfigDir, DEFAULT_CONFIGDIR, sizeof(szConfigDir)); } } return szConfigDir; #else return SYSCONFDIR; #endif } /* * Returns false on error * true on OK, with full_path set to where config file should be */ static bool find_config_file(const char *config_file, char *full_path, int max_path) { int dir_length, file_length; const char *config_dir; #if defined(HAVE_SETENV) || defined(HAVE_PUTENV) char *bp; POOL_MEM env_string(PM_NAME); #endif /* * If a full path specified, use it */ file_length = strlen(config_file) + 1; if (first_path_separator(config_file) != NULL) { if (file_length > max_path) { return false; } bstrncpy(full_path, config_file, file_length); #ifdef HAVE_SETENV pm_strcpy(env_string, config_file); bp = (char *)last_path_separator(env_string.c_str()); *bp = '\0'; setenv("BAREOS_CFGDIR", env_string.c_str(), 1); #elif HAVE_PUTENV Mmsg(env_string, "BAREOS_CFGDIR=%s", config_file); bp = (char *)last_path_separator(env_string.c_str()); *bp = '\0'; putenv(bstrdup(env_string.c_str())); #endif return true; } /* * config_file is default file name, now find default dir */ config_dir = get_default_configdir(); dir_length = strlen(config_dir); if ((dir_length + 1 + file_length) > max_path) { return false; } #ifdef HAVE_SETENV pm_strcpy(env_string, config_dir); setenv("BAREOS_CFGDIR", env_string.c_str(), 1); #elif HAVE_PUTENV Mmsg(env_string, "BAREOS_CFGDIR=%s", config_dir); putenv(bstrdup(env_string.c_str())); #endif memcpy(full_path, config_dir, dir_length + 1); if (!IsPathSeparator(full_path[dir_length - 1])) { full_path[dir_length++] = '/'; } memcpy(full_path + dir_length, config_file, file_length); return true; } void CONFIG::free_resources() { for (int i = m_r_first; i<= m_r_last; i++) { free_resource(m_res_head[i-m_r_first], i); m_res_head[i-m_r_first] = NULL; } } RES **CONFIG::save_resources() { int num = m_r_last - m_r_first + 1; RES **res = (RES **)malloc(num*sizeof(RES *)); for (int i = 0; i < num; i++) { res[i] = m_res_head[i]; m_res_head[i] = NULL; } return res; } RES **CONFIG::new_res_head() { int size = (m_r_last - m_r_first + 1) * sizeof(RES *); RES **res = (RES **)malloc(size); memset(res, 0, size); return res; } /* * Initialize the static structure to zeros, then apply all the default values. */ void CONFIG::init_resource(int type, RES_ITEM *items, int pass) { URES *res_all; memset(m_res_all, 0, m_res_all_size); res_all = ((URES *)m_res_all); res_all->hdr.rcode = type; res_all->hdr.refcnt = 1; /* * See what pass of the config parsing this is. */ switch (pass) { case 1: { /* * Set all defaults for types that are filled in pass 1 of the config parser. */ int i; for (i = 0; items[i].name; i++) { Dmsg3(900, "Item=%s def=%s defval=%s\n", items[i].name, (items[i].flags & CFG_ITEM_DEFAULT) ? "yes" : "no", (items[i].default_value) ? items[i].default_value : "None"); /* * Sanity check. * * Items with a default value but without the CFG_ITEM_DEFAULT flag set * are most of the time an indication of a programmers error. */ if (items[i].default_value != NULL && !(items[i].flags & CFG_ITEM_DEFAULT)) { Pmsg1(000, _("Found config item %s which has default value but no CFG_ITEM_DEFAULT flag set\n"), items[i].name); items[i].flags |= CFG_ITEM_DEFAULT; } /* * See if the CFG_ITEM_DEFAULT flag is set and a default value is available. */ if (items[i].flags & CFG_ITEM_DEFAULT && items[i].default_value != NULL) { /* * First try to handle the generic types. */ switch (items[i].type) { case CFG_TYPE_BIT: if (bstrcasecmp(items[i].default_value, "on")) { *(items[i].ui32value) |= items[i].code; } else if (bstrcasecmp(items[i].default_value, "off")) { *(items[i].ui32value) &= ~(items[i].code); } break; case CFG_TYPE_BOOL: if (bstrcasecmp(items[i].default_value, "yes") || bstrcasecmp(items[i].default_value, "true")) { *(items[i].boolvalue) = true; } else if (bstrcasecmp(items[i].default_value, "no") || bstrcasecmp(items[i].default_value, "false")) { *(items[i].boolvalue) = false; } break; case CFG_TYPE_PINT32: case CFG_TYPE_INT32: case CFG_TYPE_SIZE32: *(items[i].ui32value) = str_to_int32(items[i].default_value); break; case CFG_TYPE_INT64: *(items[i].i64value) = str_to_int64(items[i].default_value); break; case CFG_TYPE_SIZE64: *(items[i].ui64value) = str_to_uint64(items[i].default_value); break; case CFG_TYPE_SPEED: *(items[i].ui64value) = str_to_uint64(items[i].default_value); break; case CFG_TYPE_TIME: *(items[i].utimevalue) = str_to_int64(items[i].default_value); break; case CFG_TYPE_STRNAME: case CFG_TYPE_STR: *(items[i].value) = bstrdup(items[i].default_value); break; case CFG_TYPE_DIR: { POOL_MEM pathname(PM_FNAME); pm_strcpy(pathname, items[i].default_value); if (*pathname.c_str() != '|') { int size; /* * Make sure we have enough room */ size = pathname.size() + 1024; pathname.check_size(size); do_shell_expansion(pathname.c_str(), pathname.size()); } *items[i].value = bstrdup(pathname.c_str()); break; } case CFG_TYPE_ADDRESSES: init_default_addresses(items[i].dlistvalue, items[i].default_value); break; default: /* * None of the generic types fired if there is a registered callback call that now. */ if (m_init_res) { m_init_res(&items[i], pass); } break; } if (!m_omit_defaults) { set_bit(i, res_all->hdr.inherit_content); } } /* * If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), m_resources[type - m_r_first]); } } break; } case 2: { /* * Set all defaults for types that are filled in pass 2 of the config parser. */ int i; for (i = 0; items[i].name; i++) { Dmsg3(900, "Item=%s def=%s defval=%s\n", items[i].name, (items[i].flags & CFG_ITEM_DEFAULT) ? "yes" : "no", (items[i].default_value) ? items[i].default_value : "None"); /* * See if the CFG_ITEM_DEFAULT flag is set and a default value is available. */ if (items[i].flags & CFG_ITEM_DEFAULT && items[i].default_value != NULL) { /* * First try to handle the generic types. */ switch (items[i].type) { case CFG_TYPE_ALIST_STR: if (!*items[i].alistvalue) { *(items[i].alistvalue) = New(alist(10, owned_by_alist)); } (*(items[i].alistvalue))->append(bstrdup(items[i].default_value)); break; case CFG_TYPE_ALIST_DIR: { POOL_MEM pathname(PM_FNAME); if (!*items[i].alistvalue) { *(items[i].alistvalue) = New(alist(10, owned_by_alist)); } pm_strcpy(pathname, items[i].default_value); if (*items[i].default_value != '|') { int size; /* * Make sure we have enough room */ size = pathname.size() + 1024; pathname.check_size(size); do_shell_expansion(pathname.c_str(), pathname.size()); } (*(items[i].alistvalue))->append(bstrdup(pathname.c_str())); break; } default: /* * None of the generic types fired if there is a registered callback call that now. */ if (m_init_res) { m_init_res(&items[i], pass); } break; } if (!m_omit_defaults) { set_bit(i, res_all->hdr.inherit_content); } } /* * If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), m_resources[type - m_r_first]); } } break; } default: break; } } bareos-Release-14.2.6/src/lib/parse_conf.h000066400000000000000000000332121263011562700202660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January MM */ struct RES_ITEM; /* Declare forward referenced structure */ class RES; /* Declare forware referenced structure */ /* * Parser state */ enum parse_state { p_none, p_resource }; /* * Password encodings. */ enum password_encoding { p_encoding_clear, p_encoding_md5 }; /* * Used for message destinations. */ struct s_mdestination { int code; const char *destination; bool where; }; /* * Used for message types. */ struct s_mtypes { const char *name; uint32_t token; }; /* * Used for certain KeyWord tables */ struct s_kw { const char *name; uint32_t token; }; /* * Used to store passwords with their encoding. */ struct s_password { enum password_encoding encoding; char *value; }; /* * This is the structure that defines the record types (items) permitted within each * resource. It is used to define the configuration tables. */ struct RES_ITEM { const char *name; /* Resource name i.e. Director, ... */ const int type; union { char **value; /* Where to store the item */ uint32_t *ui32value; int32_t *i32value; uint64_t *ui64value; int64_t *i64value; bool *boolvalue; utime_t *utimevalue; s_password *pwdvalue; RES **resvalue; alist **alistvalue; dlist **dlistvalue; }; int32_t code; /* Item code/additional info */ uint32_t flags; /* Flags: See CFG_ITEM_* */ const char *default_value; /* Default value */ }; /* For storing name_addr items in res_items table */ #define ITEM(x) {(char **)&res_all.x} #define MAX_RES_ITEMS 88 /* maximum resource items per RES */ /* * This is the universal header that is at the beginning of every resource record. */ class RES { public: RES *next; /* Pointer to next resource of this type */ char *name; /* Resource name */ char *desc; /* Resource description */ uint32_t rcode; /* Resource id or type */ int32_t refcnt; /* Reference count for releasing */ char item_present[MAX_RES_ITEMS]; /* Set if item is present in conf file */ char inherit_content[MAX_RES_ITEMS]; /* Set if item has inherited content */ }; /* * Master Resource configuration structure definition * This is the structure that defines the resources that are available to this daemon. */ struct RES_TABLE { const char *name; /* Resource name */ RES_ITEM *items; /* List of resource keywords */ uint32_t rcode; /* Code if needed */ uint32_t size; /* Size of resource */ }; /* * Common Resource definitions */ #define MAX_RES_NAME_LENGTH MAX_NAME_LENGTH - 1 /* maximum resource name length */ /* * Config item flags. */ #define CFG_ITEM_REQUIRED 0x1 /* Item required */ #define CFG_ITEM_DEFAULT 0x2 /* Default supplied */ #define CFG_ITEM_NO_EQUALS 0x4 /* Don't scan = after name */ #define CFG_ITEM_DEPRECATED 0x8 /* Deprecated config option */ #define CFG_ITEM_ALIAS 0x10 /* Item is an alias for an other */ /* * CFG_ITEM_DEFAULT_PLATFORM_SPECIFIC: the value may differ between different * platforms (or configure settings). This information is used for the documentation. */ #define CFG_ITEM_PLATFORM_SPECIFIC 0x20 enum { /* * Standard resource types. handlers in res.c */ CFG_TYPE_STR = 1, /* String */ CFG_TYPE_DIR = 2, /* Directory */ CFG_TYPE_MD5PASSWORD = 3, /* MD5 hashed Password */ CFG_TYPE_CLEARPASSWORD = 4, /* Clear text Password */ CFG_TYPE_AUTOPASSWORD = 5, /* Password stored in clear when needed otherwise hashed */ CFG_TYPE_NAME = 6, /* Name */ CFG_TYPE_STRNAME = 7, /* String Name */ CFG_TYPE_RES = 8, /* Resource */ CFG_TYPE_ALIST_RES = 9, /* List of resources */ CFG_TYPE_ALIST_STR = 10, /* List of strings */ CFG_TYPE_ALIST_DIR = 11, /* List of dirs */ CFG_TYPE_INT32 = 12, /* 32 bits Integer */ CFG_TYPE_PINT32 = 13, /* Positive 32 bits Integer (unsigned) */ CFG_TYPE_MSGS = 14, /* Message resource */ CFG_TYPE_INT64 = 15, /* 64 bits Integer */ CFG_TYPE_BIT = 16, /* Bitfield */ CFG_TYPE_BOOL = 17, /* Boolean */ CFG_TYPE_TIME = 18, /* Time value */ CFG_TYPE_SIZE64 = 19, /* 64 bits file size */ CFG_TYPE_SIZE32 = 20, /* 32 bits file size */ CFG_TYPE_SPEED = 21, /* Speed limit */ CFG_TYPE_DEFS = 22, /* Definition */ CFG_TYPE_LABEL = 23, /* Label */ CFG_TYPE_ADDRESSES = 24, /* List of ip addresses */ CFG_TYPE_ADDRESSES_ADDRESS = 25, /* Ip address */ CFG_TYPE_ADDRESSES_PORT = 26, /* Ip port */ CFG_TYPE_PLUGIN_NAMES = 27, /* Plugin Name(s) */ /* * Director resource types. handlers in dird_conf. */ CFG_TYPE_ACL = 50, /* User Access Control List */ CFG_TYPE_AUDIT = 51, /* Auditing Command List */ CFG_TYPE_AUTHPROTOCOLTYPE = 52, /* Authentication Protocol */ CFG_TYPE_AUTHTYPE = 53, /* Authentication Type */ CFG_TYPE_DEVICE = 54, /* Device resource */ CFG_TYPE_JOBTYPE = 55, /* Type of Job */ CFG_TYPE_PROTOCOLTYPE = 56, /* Protocol */ CFG_TYPE_LEVEL = 57, /* Backup Level */ CFG_TYPE_REPLACE = 58, /* Replace option */ CFG_TYPE_SHRTRUNSCRIPT = 59, /* Short Runscript definition */ CFG_TYPE_RUNSCRIPT = 60, /* Runscript */ CFG_TYPE_RUNSCRIPT_CMD = 61, /* Runscript Command */ CFG_TYPE_RUNSCRIPT_TARGET = 62, /* Runscript Target (Host) */ CFG_TYPE_RUNSCRIPT_BOOL = 63, /* Runscript Boolean */ CFG_TYPE_RUNSCRIPT_WHEN = 64, /* Runscript When expression */ CFG_TYPE_MIGTYPE = 65, /* Migration Type */ CFG_TYPE_INCEXC = 66, /* Include/Exclude item */ CFG_TYPE_RUN = 67, /* Schedule Run Command */ CFG_TYPE_ACTIONONPURGE = 68, /* Action to perform on Purge */ /* * Director fileset options. handlers in dird_conf. */ CFG_TYPE_FNAME = 80, /* Filename */ CFG_TYPE_PLUGINNAME = 81, /* Pluginname */ CFG_TYPE_EXCLUDEDIR = 82, /* Exclude directory */ CFG_TYPE_OPTIONS = 83, /* Options block */ CFG_TYPE_OPTION = 84, /* Option of Options block */ CFG_TYPE_REGEX = 85, /* Regular Expression */ CFG_TYPE_BASE = 86, /* Basejob Expression */ CFG_TYPE_WILD = 87, /* Wildcard Expression */ CFG_TYPE_PLUGIN = 88, /* Plugin definition */ CFG_TYPE_FSTYPE = 89, /* FileSytem match criterium (UNIX)*/ CFG_TYPE_DRIVETYPE = 90, /* DriveType match criterium (Windows) */ CFG_TYPE_META = 91, /* Meta tag */ /* * Storage daemon resource types */ CFG_TYPE_DEVTYPE = 201, /* Device Type */ CFG_TYPE_MAXBLOCKSIZE = 202, /* Maximum Blocksize */ CFG_TYPE_IODIRECTION = 203, /* IO Direction */ CFG_TYPE_CMPRSALGO = 204, /* Compression Algorithm */ /* * File daemon resource types */ CFG_TYPE_CIPHER = 301 /* Encryption Cipher */ }; struct DATATYPE_NAME { const int number; const char *name; const char *description; }; /* * Base Class for all Resource Classes */ class BRSRES { public: RES hdr; /* Methods */ char *name() const; bool print_config(POOL_MEM &buf, bool hide_sensitive_data = false); }; inline char *BRSRES::name() const { return this->hdr.name; } /* * Message Resource */ class MSGSRES : public BRSRES { /* * Members */ public: char *mail_cmd; /* Mail command */ char *operator_cmd; /* Operator command */ DEST *dest_chain; /* chain of destinations */ char send_msg[nbytes_for_bits(M_MAX+1)]; /* Bit array of types */ private: bool m_in_use; /* Set when using to send a message */ bool m_closing; /* Set when closing message resource */ public: /* * Methods */ void clear_in_use() { lock(); m_in_use=false; unlock(); } void set_in_use() { wait_not_in_use(); m_in_use=true; unlock(); } void set_closing() { m_closing=true; } bool get_closing() { return m_closing; } void clear_closing() { lock(); m_closing=false; unlock(); } bool is_closing() { lock(); bool rtn=m_closing; unlock(); return rtn; } void wait_not_in_use(); /* in message.c */ void lock(); /* in message.c */ void unlock(); /* in message.c */ bool print_config(POOL_MEM &buff, bool hide_sensitive_data = false); }; typedef void (INIT_RES_HANDLER)(RES_ITEM *item, int pass); typedef void (STORE_RES_HANDLER)(LEX *lc, RES_ITEM *item, int index, int pass); typedef void (PRINT_RES_HANDLER)(RES_ITEM *items, int i, POOL_MEM &cfg_str, bool hide_sensitive_data); /* * New C++ configuration routines */ class CONFIG { public: /* members */ const char *m_cf; /* Config file */ LEX_ERROR_HANDLER *m_scan_error; /* Error handler if non-null */ LEX_WARNING_HANDLER *m_scan_warning; /* Warning handler if non-null */ INIT_RES_HANDLER *m_init_res; /* Init resource handler for non default types if non-null */ STORE_RES_HANDLER *m_store_res; /* Store resource handler for non default types if non-null */ PRINT_RES_HANDLER *m_print_res; /* Print resource handler for non default types if non-null */ int32_t m_err_type; /* The way to terminate on failure */ void *m_res_all; /* Pointer to res_all buffer */ int32_t m_res_all_size; /* Length of buffer */ bool m_omit_defaults; /* Omit config variables with default values when dumping the config */ int32_t m_r_first; /* First daemon resource type */ int32_t m_r_last; /* Last daemon resource type */ RES_TABLE *m_resources; /* Pointer to table of permitted resources */ RES **m_res_head; /* Pointer to defined resources */ brwlock_t m_res_lock; /* Resource lock */ /* methods */ void init( const char *cf, LEX_ERROR_HANDLER *scan_error, LEX_WARNING_HANDLER *scan_warning, INIT_RES_HANDLER *init_res, STORE_RES_HANDLER *store_res, PRINT_RES_HANDLER *print_res, int32_t err_type, void *vres_all, int32_t res_all_size, int32_t r_first, int32_t r_last, RES_TABLE *resources, RES **res_head); bool parse_config(); void free_resources(); RES **save_resources(); RES **new_res_head(); void init_resource(int type, RES_ITEM *items, int pass); }; CONFIG *new_config_parser(); /* Resource routines */ RES *GetResWithName(int rcode, const char *name); RES *GetNextRes(int rcode, RES *res); void b_LockRes(const char *file, int line); void b_UnlockRes(const char *file, int line); void dump_resource(int type, RES *res, void sendmsg(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data = false); void free_resource(RES *res, int type); void init_resource(int type, RES_ITEM *item); void save_resource(int type, RES_ITEM *item, int pass); bool store_resource(int type, LEX *lc, RES_ITEM *item, int index, int pass); const char *res_to_str(int rcode); bool print_config_schema_json(POOL_MEM &buff); bool print_res_item_schema_json(POOL_MEM &buff, int level, RES_ITEM *item ); /* JSON output helper functions */ void add_json_object_start(POOL_MEM &cfg_str, int level, const char *string); void add_json_object_end(POOL_MEM &cfg_str, int level, const char *string); void add_json_pair_plain(POOL_MEM &cfg_str, int level, const char *string, const char *value); void add_json_pair(POOL_MEM &cfg_str, int level, const char *string, const char *value); void add_json_pair(POOL_MEM &cfg_str, int level, const char *string, int value); /* Loop through each resource of type, returning in var */ #ifdef HAVE_TYPEOF #define foreach_res(var, type) \ for((var)=NULL; ((var)=(typeof(var))GetNextRes((type), (RES *)var));) #else #define foreach_res(var, type) \ for(var=NULL; (*((void **)&(var))=(void *)GetNextRes((type), (RES *)var));) #endif bareos-Release-14.2.6/src/lib/passphrase.c000066400000000000000000000102141263011562700203100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * passphrase.c Generate semi random ASCII passphrases * * Marco van Wieringen, March 2012 */ #include "bareos.h" #if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) #ifdef HAVE_OPENSSL #include #include #endif #ifdef HAVE_GNUTLS #include #include #endif /* * Generate a semi random passphrase using normal ASCII chars * using the openssl rand_bytes() function of the length given * in the length argument. The returned argument should be * freed by the caller. */ char *generate_crypto_passphrase(int length) { #ifdef HAVE_GNUTLS int error; #endif int c; int vc_len, cnt; char *passphrase; unsigned char *rand_bytes; char valid_chars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "!@#$%^&*()-_=+|[]{};:,.<>?/~"; rand_bytes = (unsigned char *)malloc(length); passphrase = (char *)malloc(length); #ifdef HAVE_OPENSSL if (RAND_bytes(rand_bytes, length) != 1) { unsigned long error; error = ERR_get_error(); Emsg1(M_ERROR, 0, _("Failed to get random bytes from RAND_bytes for passphrase: ERR=%s\n"), ERR_lib_error_string(error)); free(rand_bytes); free(passphrase); return NULL; } #endif #ifdef HAVE_GNUTLS error = gnutls_rnd(GNUTLS_RND_RANDOM, rand_bytes, length); if (error != GNUTLS_E_SUCCESS) { Emsg1(M_ERROR, 0, _("Failed to get random bytes from gnutls_rnd for passphrase: ERR=%s\n"), gnutls_strerror(error)); free(rand_bytes); free(passphrase); return NULL; } #endif /* * Convert the random bytes into a readable string. * * This conversion gives reasonable good passphrases with 32 bytes. * Tested was around 300k passphrases without one duplicate. */ vc_len = strlen(valid_chars); for (cnt = 0; cnt < length; cnt++) { c = rand_bytes[cnt] % vc_len; passphrase[cnt] = valid_chars[c]; } free(rand_bytes); return passphrase; } #else /* * Generate a semi random passphrase using normal ASCII chars * using the srand and rand libc functions of the length given * in the length argument. The returned argument should be * freed by the caller. */ char *generate_crypto_passphrase(int length) { char c; int vc_len, cnt; int *rand_bytes; char *passphrase; char valid_chars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "!@#$%^&*()-_=+|[]{};:,.<>?/~"; rand_bytes = (int *)malloc(length * sizeof(int)); passphrase = (char *)malloc(length); srand(time(NULL)); for (cnt = 0; cnt < length; cnt++) { rand_bytes[cnt] = rand(); } /* * Convert the random bytes into a readable string. * Due to the limited randomness of srand and rand this gives * more duplicates then the version using the openssl RAND_bytes * function. If available please use the openssl version. */ vc_len = strlen(valid_chars); for (cnt = 0; cnt < length; cnt++) { c = rand_bytes[cnt] % vc_len; passphrase[cnt] = valid_chars[c]; } free(rand_bytes); return passphrase; } #endif /* HAVE_OPENSSL || HAVE_GNUTLS*/ bareos-Release-14.2.6/src/lib/plugins.c000066400000000000000000000301451263011562700176250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Plugin load/unloader for all BAREOS daemons * * Kern Sibbald, October 2007 */ #include "bareos.h" #if defined(HAVE_DLFCN_H) #include #elif defined(HAVE_SYS_DL_H) #include #elif defined(HAVE_DL_H) #include #else #error "Cannot load dynamic objects into program" #endif #ifdef HAVE_DIRENT_H #include #define NAMELEN(dirent) (strlen((dirent)->d_name)) #endif #ifndef HAVE_READDIR_R int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #endif #ifndef RTLD_NOW #define RTLD_NOW 2 #endif #if !defined(LT_LAZY_OR_NOW) #if defined(RTLD_LAZY) #define LT_LAZY_OR_NOW RTLD_LAZY #else #if defined(DL_LAZY) #define LT_LAZY_OR_NOW DL_LAZY #endif #endif /* !RTLD_LAZY */ #endif #if !defined(LT_LAZY_OR_NOW) #if defined(RTLD_NOW) #define LT_LAZY_OR_NOW RTLD_NOW #else #if defined(DL_NOW) #define LT_LAZY_OR_NOW DL_NOW #endif #endif /* !RTLD_NOW */ #endif #if !defined(LT_LAZY_OR_NOW) #define LT_LAZY_OR_NOW 0 #endif /* !LT_LAZY_OR_NOW */ #if !defined(LT_GLOBAL) #if defined(RTLD_GLOBAL) #define LT_GLOBAL RTLD_GLOBAL #else #if defined(DL_GLOBAL) #define LT_GLOBAL DL_GLOBAL #endif #endif /* !RTLD_GLOBAL */ #endif #include "plugins.h" static const int dbglvl = 50; /* * Create a new plugin "class" entry and enter it in the list of plugins. * Note, this is not the same as an instance of the plugin. */ static Plugin *new_plugin() { Plugin *plugin; plugin = (Plugin *)malloc(sizeof(Plugin)); memset(plugin, 0, sizeof(Plugin)); return plugin; } static void close_plugin(Plugin *plugin) { if (plugin->file) { Dmsg1(50, "Got plugin=%s but not accepted.\n", plugin->file); } if (plugin->unloadPlugin) { plugin->unloadPlugin(); } if (plugin->pHandle) { dlclose(plugin->pHandle); } if (plugin->file) { free(plugin->file); } free(plugin); } /* * Load a specific plugin and check if the plugin had the correct * entry points, the license is compatible and the initialize the plugin. */ static bool load_a_plugin(void *binfo, void *bfuncs, const char *plugin_pathname, const char *plugin_name, const char *type, alist *plugin_list, bool is_plugin_compatible(Plugin *plugin)) { t_loadPlugin loadPlugin; Plugin *plugin = NULL; plugin = new_plugin(); plugin->file = bstrdup(plugin_name); plugin->file_len = strstr(plugin->file, type) - plugin->file; plugin->pHandle = dlopen(plugin_pathname, LT_LAZY_OR_NOW | LT_GLOBAL); if (!plugin->pHandle) { const char *error = dlerror(); Jmsg(NULL, M_ERROR, 0, _("dlopen plugin %s failed: ERR=%s\n"), plugin_pathname, NPRT(error)); Dmsg2(dbglvl, "dlopen plugin %s failed: ERR=%s\n", plugin_pathname, NPRT(error)); close_plugin(plugin); return false; } /* * Get two global entry points */ loadPlugin = (t_loadPlugin)dlsym(plugin->pHandle, "loadPlugin"); if (!loadPlugin) { Jmsg(NULL, M_ERROR, 0, _("Lookup of loadPlugin in plugin %s failed: ERR=%s\n"), plugin_pathname, NPRT(dlerror())); Dmsg2(dbglvl, "Lookup of loadPlugin in plugin %s failed: ERR=%s\n", plugin_pathname, NPRT(dlerror())); close_plugin(plugin); return false; } plugin->unloadPlugin = (t_unloadPlugin)dlsym(plugin->pHandle, "unloadPlugin"); if (!plugin->unloadPlugin) { Jmsg(NULL, M_ERROR, 0, _("Lookup of unloadPlugin in plugin %s failed: ERR=%s\n"), plugin_pathname, NPRT(dlerror())); Dmsg2(dbglvl, "Lookup of unloadPlugin in plugin %s failed: ERR=%s\n", plugin_pathname, NPRT(dlerror())); close_plugin(plugin); return false; } /* * Initialize the plugin */ if (loadPlugin(binfo, bfuncs, &plugin->pinfo, &plugin->pfuncs) != bRC_OK) { close_plugin(plugin); return false; } if (!is_plugin_compatible) { Dmsg0(50, "Plugin compatibility pointer not set.\n"); } else if (!is_plugin_compatible(plugin)) { close_plugin(plugin); return false; } plugin_list->append(plugin); return true; } /* * Load all the plugins in the specified directory. * Or when plugin_names is give it has a list of plugins * to load from the specified directory. */ bool load_plugins(void *binfo, void *bfuncs, alist *plugin_list, const char *plugin_dir, alist *plugin_names, const char *type, bool is_plugin_compatible(Plugin *plugin)) { struct stat statp; bool found = false; POOL_MEM fname(PM_FNAME); bool need_slash = false; int len; Dmsg0(dbglvl, "load_plugins\n"); len = strlen(plugin_dir); if (len > 0) { need_slash = !IsPathSeparator(plugin_dir[len - 1]); } /* * See if we are loading certain plugins only or all plugins of a certain type. */ if (plugin_names && plugin_names->size()) { char *name; POOL_MEM plugin_name(PM_FNAME); foreach_alist(name, plugin_names) { /* * Generate the plugin name e.g. -.so */ Mmsg(plugin_name, "%s%s", name, type); /* * Generate the full pathname to the plugin to load. */ Mmsg(fname, "%s%s%s", plugin_dir, (need_slash) ? "/" : "", plugin_name.c_str()); /* * Make sure the plugin exists and is a regular file. */ if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) { continue; } /* * Try to load the plugin and resolve the wanted symbols. */ if (load_a_plugin(binfo, bfuncs, fname.c_str(), plugin_name.c_str(), type, plugin_list, is_plugin_compatible)) { found = true; } } } else { int name_max, type_len; DIR *dp = NULL; struct dirent *entry = NULL, *result; name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (!(dp = opendir(plugin_dir))) { berrno be; Jmsg(NULL, M_ERROR_TERM, 0, _("Failed to open Plugin directory %s: ERR=%s\n"), plugin_dir, be.bstrerror()); Dmsg2(dbglvl, "Failed to open Plugin directory %s: ERR=%s\n", plugin_dir, be.bstrerror()); goto bail_out; } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); while (1) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { if (!found) { Jmsg(NULL, M_WARNING, 0, _("Failed to find any plugins in %s\n"), plugin_dir); Dmsg1(dbglvl, "Failed to find any plugins in %s\n", plugin_dir); } break; } if (bstrcmp(result->d_name, ".") || bstrcmp(result->d_name, "..")) { continue; } len = strlen(result->d_name); type_len = strlen(type); if (len < type_len + 1 || !bstrcmp(&result->d_name[len - type_len], type)) { Dmsg3(dbglvl, "Rejected plugin: want=%s name=%s len=%d\n", type, result->d_name, len); continue; } Dmsg2(dbglvl, "Found plugin: name=%s len=%d\n", result->d_name, len); pm_strcpy(fname, plugin_dir); if (need_slash) { pm_strcat(fname, "/"); } pm_strcat(fname, result->d_name); /* * Make sure the plugin exists and is a regular file. */ if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) { continue; } /* * Try to load the plugin and resolve the wanted symbols. */ if (load_a_plugin(binfo, bfuncs, fname.c_str(), result->d_name, type, plugin_list, is_plugin_compatible)) { found = true; } } if (entry) { free(entry); } if (dp) { closedir(dp); } } bail_out: return found; } /* * Unload all the loaded plugins */ void unload_plugins(alist *plugin_list) { int i; Plugin *plugin; if (!plugin_list) { return; } foreach_alist_index(i, plugin, plugin_list) { /* * Shut it down and unload it */ plugin->unloadPlugin(); dlclose(plugin->pHandle); if (plugin->file) { free(plugin->file); } free(plugin); } } int list_plugins(alist *plugin_list, POOL_MEM &msg) { int i, len = 0; Plugin *plugin; if (plugin_list->size() > 0) { pm_strcpy(msg, "Plugin Info:\n"); foreach_alist_index(i, plugin, plugin_list) { pm_strcat(msg, " Plugin : "); len = pm_strcat(msg, plugin->file); if (plugin->pinfo) { genpInfo *info = (genpInfo *)plugin->pinfo; pm_strcat(msg, "\n"); pm_strcat(msg, " Description: "); pm_strcat(msg, NPRT(info->plugin_description)); pm_strcat(msg, "\n"); pm_strcat(msg, " Version : "); pm_strcat(msg, NPRT(info->plugin_version)); pm_strcat(msg, ", Date: "); pm_strcat(msg, NPRT(info->plugin_date)); pm_strcat(msg, "\n"); pm_strcat(msg, " Author : "); pm_strcat(msg, NPRT(info->plugin_author)); pm_strcat(msg, "\n"); pm_strcat(msg, " License : "); pm_strcat(msg, NPRT(info->plugin_license)); pm_strcat(msg, "\n"); if (info->plugin_usage) { pm_strcat(msg, " Usage : "); pm_strcat(msg, info->plugin_usage); pm_strcat(msg, "\n"); } pm_strcat(msg, "\n"); } } len = pm_strcat(msg, "\n"); } return len; } /* * Dump plugin information * Each daemon can register a hook that will be called * after a fatal signal. */ #define DBG_MAX_HOOK 10 static dbg_plugin_hook_t *dbg_plugin_hooks[DBG_MAX_HOOK]; static dbg_print_plugin_hook_t *dbg_print_plugin_hook = NULL; static int dbg_plugin_hook_count = 0; void dbg_plugin_add_hook(dbg_plugin_hook_t *fct) { ASSERT(dbg_plugin_hook_count < DBG_MAX_HOOK); dbg_plugin_hooks[dbg_plugin_hook_count++] = fct; } void dbg_print_plugin_add_hook(dbg_print_plugin_hook_t *fct) { dbg_print_plugin_hook = fct; } void dump_plugins(alist *plugin_list, FILE *fp) { int i; Plugin *plugin; fprintf(fp, "Attempt to dump plugins. Hook count=%d\n", dbg_plugin_hook_count); if (!plugin_list) { return; } foreach_alist_index(i, plugin, plugin_list) { for(int i=0; i < dbg_plugin_hook_count; i++) { // dbg_plugin_hook_t *fct = dbg_plugin_hooks[i]; fprintf(fp, "Plugin %p name=\"%s\"\n", plugin, plugin->file); // fct(plugin, fp); } } } /* * Bounce from library to daemon and back to get the proper plugin_list. * As the function is called from the signal context we don't have the * plugin_list as argument and we don't want to expose it as global variable. * If the daemon didn't register a dump plugin function this is a NOP. */ void dbg_print_plugin(FILE *fp) { if (dbg_print_plugin_hook) { dbg_print_plugin_hook(fp); } } bareos-Release-14.2.6/src/lib/plugins.h000066400000000000000000000074541263011562700176410ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Common plugin definitions * * Kern Sibbald, October 2007 */ #ifndef __PLUGINS_H #define __PLUGINS_H /**************************************************************************** * * * Common definitions for all plugins * * * ****************************************************************************/ /* * Universal return codes from all plugin functions */ typedef enum { bRC_OK = 0, /* OK */ bRC_Stop = 1, /* Stop calling other plugins */ bRC_Error = 2, /* Some kind of error */ bRC_More = 3, /* More files to backup */ bRC_Term = 4, /* Unload me */ bRC_Seen = 5, /* Return code from checkFiles */ bRC_Core = 6, /* Let BAREOS core handles this file */ bRC_Skip = 7, /* Skip the proposed file */ bRC_Cancel = 8, /* Job cancelled */ bRC_Max = 9999 /* Max code BAREOS can use */ } bRC; #define LOWEST_PLUGIN_INSTANCE 0 #define HIGHEST_PLUGIN_INSTANCE 127 extern "C" { typedef bRC (*t_loadPlugin)(void *binfo, void *bfuncs, void **pinfo, void **pfuncs); typedef bRC (*t_unloadPlugin)(void); } class Plugin { public: char *file; int32_t file_len; t_unloadPlugin unloadPlugin; void *pinfo; void *pfuncs; void *pHandle; }; /* * Context packet as first argument of all functions */ struct bpContext { uint32_t instance; Plugin *plugin; void *bContext; /* BAREOS private context */ void *pContext; /* Plugin private context */ }; typedef struct gen_pluginInfo { uint32_t size; uint32_t version; const char *plugin_magic; const char *plugin_license; const char *plugin_author; const char *plugin_date; const char *plugin_version; const char *plugin_description; const char *plugin_usage; } genpInfo; /* Functions */ extern bool load_plugins(void *binfo, void *bfuncs, alist *plugin_list, const char *plugin_dir, alist *plugin_names, const char *type, bool is_plugin_compatible(Plugin *plugin)); extern void unload_plugins(alist *plugin_list); extern int list_plugins(alist *plugin_list, POOL_MEM &msg); /* Each daemon can register a debug hook that will be called * after a fatal signal */ typedef void (dbg_plugin_hook_t)(Plugin *plug, FILE *fp); extern void dbg_plugin_add_hook(dbg_plugin_hook_t *fct); typedef void(dbg_print_plugin_hook_t)(FILE *fp); extern void dbg_print_plugin_add_hook(dbg_print_plugin_hook_t *fct); extern void dump_plugins(alist *plugin_list, FILE *fp); #endif /* __PLUGINS_H */ bareos-Release-14.2.6/src/lib/poll.c000066400000000000000000000103401263011562700171050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, May 2012 */ #include "bareos.h" #ifdef HAVE_POLL_H #include #elif HAVE_SYS_POLL_H #include #endif #ifdef HAVE_POLL /* * Returns: 1 if data available * 0 if timeout * -1 if error */ int wait_for_readable_fd(int fd, int msec, bool ignore_interupts) { struct pollfd pfds[1]; int events; events = POLLIN; #if defined(POLLRDNORM) events |= POLLRDNORM; #endif #if defined(POLLRDBAND) events |= POLLRDBAND; #endif #if defined(POLLPRI) events |= POLLPRI; #endif memset(pfds, 0, sizeof(pfds)); pfds[0].fd = fd; pfds[0].events = events; for ( ;; ) { switch(poll(pfds, 1, msec)) { case 0: /* timeout */ return 0; case -1: if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) { continue; } return -1; /* error return */ default: if (pfds[0].revents & events) { return 1; } else { return 0; } } } } /* * Returns: 1 if data available * 0 if timeout * -1 if error */ int wait_for_writable_fd(int fd, int msec, bool ignore_interupts) { struct pollfd pfds[1]; int events; events = POLLOUT; #if defined(POLLWRNORM) events |= POLLWRNORM; #endif #if defined POLLWRBAND events |= POLLWRBAND; #endif memset(pfds, 0, sizeof(pfds)); pfds[0].fd = fd; pfds[0].events = events; for ( ;; ) { switch(poll(pfds, 1, msec)) { case 0: /* timeout */ return 0; case -1: if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) { continue; } return -1; /* error return */ default: if (pfds[0].revents & events) { return 1; } else { return 0; } } } } #else /* * Returns: 1 if data available * 0 if timeout * -1 if error */ int wait_for_readable_fd(int fd, int msec, bool ignore_interupts) { fd_set fdset; struct timeval tv; tv.tv_sec = msec / 1000; tv.tv_usec = (msec % 1000) * 1000; for ( ;; ) { FD_ZERO(&fdset); FD_SET((unsigned)fd, &fdset); switch(select(fd + 1, &fdset, NULL, NULL, &tv)) { case 0: /* timeout */ return 0; case -1: if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) { continue; } return -1; /* error return */ default: return 1; } } } /* * Returns: 1 if data available * 0 if timeout * -1 if error */ int wait_for_writable_fd(int fd, int msec, bool ignore_interupts) { #if defined(HAVE_WIN32) return 1; #else fd_set fdset; struct timeval tv; tv.tv_sec = msec / 1000; tv.tv_usec = (msec % 1000) * 1000; for ( ;; ) { FD_ZERO(&fdset); FD_SET((unsigned)fd, &fdset); switch(select(fd + 1, NULL, &fdset, NULL, &tv)) { case 0: /* timeout */ return 0; case -1: if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) { continue; } return -1; /* error return */ default: return 1; } } #endif /* defined(HAVE_WIN32) */ } #endif /* HAVE_POLL */ bareos-Release-14.2.6/src/lib/priv.c000066400000000000000000000101201263011562700171130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bareos.h" #undef ENABLE_KEEP_READALL_CAPS_SUPPORT #if defined(HAVE_SYS_PRCTL_H) && defined(HAVE_SYS_CAPABILITY_H) && \ defined(HAVE_PRCTL) && defined(HAVE_SETREUID) && defined(HAVE_LIBCAP) #include #include #if defined(PR_SET_KEEPCAPS) #define ENABLE_KEEP_READALL_CAPS_SUPPORT #endif #endif #ifdef HAVE_AIX_OS #ifndef _AIX51 extern "C" int initgroups(const char *,int); #endif #endif /* * Lower privileges by switching to new UID and GID if non-NULL. * If requested, keep readall capabilities after switch. */ void drop(char *uname, char *gname, bool keep_readall_caps) { #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H) struct passwd *passw = NULL; struct group *group = NULL; gid_t gid; uid_t uid; char username[1000]; Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE"); if (!uname && !gname) { return; /* Nothing to do */ } if (uname) { if ((passw = getpwnam(uname)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname, be.bstrerror()); } } else { if ((passw = getpwuid(getuid())) == NULL) { berrno be; Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"), be.bstrerror()); } else { uname = passw->pw_name; } } /* Any OS uname pointer may get overwritten, so save name, uid, and gid */ bstrncpy(username, uname, sizeof(username)); uid = passw->pw_uid; gid = passw->pw_gid; if (gname) { if ((group = getgrnam(gname)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname, be.bstrerror()); } gid = group->gr_gid; } if (initgroups(username, gid)) { berrno be; if (gname) { Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"), gname, username, be.bstrerror()); } else { Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"), username, be.bstrerror()); } } if (gname) { if (setgid(gid)) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname, be.bstrerror()); } } if (keep_readall_caps) { #ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT cap_t caps; if (prctl(PR_SET_KEEPCAPS, 1)) { berrno be; Emsg1(M_ERROR_TERM, 0, _("prctl failed: ERR=%s\n"), be.bstrerror()); } if (setreuid(uid, uid)) { berrno be; Emsg1(M_ERROR_TERM, 0, _("setreuid failed: ERR=%s\n"), be.bstrerror()); } if (!(caps = cap_from_text("cap_dac_read_search=ep"))) { berrno be; Emsg1(M_ERROR_TERM, 0, _("cap_from_text failed: ERR=%s\n"), be.bstrerror()); } if (cap_set_proc(caps) < 0) { berrno be; Emsg1(M_ERROR_TERM, 0, _("cap_set_proc failed: ERR=%s\n"), be.bstrerror()); } cap_free(caps); #else Emsg0(M_ERROR_TERM, 0, _("Keep readall caps not implemented this OS or missing libraries.\n")); #endif } else if (setuid(uid)) { berrno be; Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username); } #endif } bareos-Release-14.2.6/src/lib/protos.h000066400000000000000000000420671263011562700175050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Prototypes for lib directory of BAREOS */ #ifndef __LIBPROTOS_H #define __LIBPROTOS_H class JCR; /* attr.c */ ATTR *new_attr(JCR *jcr); void free_attr(ATTR *attr); int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, int32_t reclen, ATTR *attr); void build_attr_output_fnames(JCR *jcr, ATTR *attr); void print_ls_output(JCR *jcr, ATTR *attr); /* attribs.c */ void encode_stat(char *buf, struct stat *statp, int stat_size, int32_t LinkFI, int data_stream); int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI); int32_t decode_LinkFI(char *buf, struct stat *statp, int stat_size); /* base64.c */ void base64_init(void); int to_base64(int64_t value, char *where); int from_base64(int64_t *value, char *where); int bin_to_base64(char *buf, int buflen, char *bin, int binlen, bool compatible); int base64_to_bin(char *dest, int destlen, char *src, int srclen); /* bget_msg.c */ int bget_msg(BSOCK *sock); /* bnet.c */ int32_t bnet_recv(BSOCK *bsock); bool bnet_send(BSOCK *bsock); bool bnet_fsend(BSOCK *bs, const char *fmt, ...); bool bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw); bool bnet_sig(BSOCK *bs, int sig); bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list); bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list); int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen); BSOCK *dup_bsock(BSOCK *bsock); const char *bnet_strerror(BSOCK *bsock); const char *bnet_sig_to_ascii(BSOCK *bsock); int bnet_wait_data(BSOCK *bsock, int sec); int bnet_wait_data_intr(BSOCK *bsock, int sec); bool is_bnet_stop(BSOCK *bsock); int is_bnet_error(BSOCK *bsock); void bnet_suppress_error_messages(BSOCK *bsock, bool flag); dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr); int bnet_set_blocking(BSOCK *sock); int bnet_set_nonblocking(BSOCK *sock); void bnet_restore_blocking(BSOCK *sock, int flags); int net_connect(int port); BSOCK *bnet_bind(int port); BSOCK *bnet_accept(BSOCK *bsock, char *who); /* bnet_server_tcp.c */ void cleanup_bnet_thread_server_tcp(alist *sockfds, workq_t *client_wq); void bnet_thread_server_tcp(dlist *addr_list, int max_clients, alist *sockfds, workq_t *client_wq, bool nokeepalive, void *handle_client_request(void *bsock)); void bnet_stop_thread_server_tcp(pthread_t tid); /* bpipe.c */ BPIPE *open_bpipe(char *prog, int wait, const char *mode); int close_wpipe(BPIPE *bpipe); int close_bpipe(BPIPE *bpipe); /* bsys.c */ char *bstrinlinecpy(char *dest, const char *src); char *bstrncpy(char *dest, const char *src, int maxlen); char *bstrncpy(char *dest, POOL_MEM &src, int maxlen); char *bstrncat(char *dest, const char *src, int maxlen); char *bstrncat(char *dest, POOL_MEM &src, int maxlen); bool bstrcmp(const char *s1, const char *s2); bool bstrncmp(const char *s1, const char *s2, int n); bool bstrcasecmp(const char *s1, const char *s2); bool bstrncasecmp(const char *s1, const char *s2, int n); int cstrlen(const char *str); void *b_malloc(const char *file, int line, size_t size); #ifndef bmalloc void *bmalloc(size_t size); #endif void bfree(void *buf); void *brealloc(void *buf, size_t size); void *bcalloc(size_t size1, size_t size2); int bsnprintf(char *str, int32_t size, const char *format, ...); int bvsnprintf(char *str, int32_t size, const char *format, va_list ap); int pool_sprintf(char *pool_buf, const char *fmt, ...); void create_pid_file(char *dir, const char *progname, int port); int delete_pid_file(char *dir, const char *progname, int port); void drop(char *uid, char *gid, bool keep_readall_caps); int bmicrosleep(int32_t sec, int32_t usec); char *bfgets(char *s, int size, FILE *fd); char *bfgets(POOLMEM *&s, FILE *fd); void make_unique_filename(POOLMEM **name, int Id, char *what); #ifndef HAVE_STRTOLL long long int strtoll(const char *ptr, char **endptr, int base); #endif void read_state_file(char *dir, const char *progname, int port); int b_strerror(int errnum, char *buf, size_t bufsiz); char *escape_filename(const char *file_path); int Zdeflate(char *in, int in_len, char *out, int &out_len); int Zinflate(char *in, int in_len, char *out, int &out_len); void stack_trace(); int safer_unlink(const char *pathname, const char *regex); /* compression.c */ bool setup_compression_buffers(JCR *jcr, bool compatible, uint32_t compression_algorithm, uint32_t *compress_buf_size); bool setup_decompression_buffers(JCR *jcr, uint32_t *decompress_buf_size); bool compress_data(JCR *jcr, uint32_t compression_algorithm, char *rbuf, uint32_t rsize, unsigned char *cbuf, uint32_t max_compress_len, uint32_t *compress_len); bool decompress_data(JCR *jcr, const char *last_fname, int32_t stream, char **data, uint32_t *length, bool want_data_stream); void cleanup_compression(JCR *jcr); /* cram-md5.c */ bool cram_md5_respond(BSOCK *bs, const char *password, int *tls_remote_need, bool *compatible); bool cram_md5_challenge(BSOCK *bs, const char *password, int tls_local_need, bool compatible); void hmac_md5(uint8_t *text, int text_len, uint8_t *key, int key_len, uint8_t *hmac); /* crypto.c */ int init_crypto(void); int cleanup_crypto(void); DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type); bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length); bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length); void crypto_digest_free(DIGEST *digest); SIGNATURE *crypto_sign_new(JCR *jcr); crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, crypto_digest_t &algorithm, DIGEST **digest); crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest); int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair); int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length); SIGNATURE *crypto_sign_decode(JCR *jcr, const uint8_t *sigData, uint32_t length); void crypto_sign_free(SIGNATURE *sig); CRYPTO_SESSION *crypto_session_new(crypto_cipher_t cipher, alist *pubkeys); void crypto_session_free(CRYPTO_SESSION *cs); bool crypto_session_encode(CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length); crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session); CRYPTO_SESSION *crypto_session_decode(const uint8_t *data, uint32_t length); CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize); bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written); bool crypto_cipher_finalize(CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written); void crypto_cipher_free(CIPHER_CONTEXT *cipher_ctx); X509_KEYPAIR *crypto_keypair_new(void); X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair); int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file); bool crypto_keypair_has_key(const char *file); int crypto_keypair_load_key(X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata); void crypto_keypair_free(X509_KEYPAIR *keypair); int crypto_default_pem_callback(char *buf, int size, const void *userdata); const char *crypto_digest_name(crypto_digest_t type); const char *crypto_digest_name(DIGEST *digest); crypto_digest_t crypto_digest_stream_type(int stream); const char *crypto_strerror(crypto_error_t error); /* crypto_openssl.c */ #ifdef HAVE_OPENSSL void openssl_post_errors(int code, const char *errstring); void openssl_post_errors(JCR *jcr, int code, const char *errstring); int openssl_init_threads(void); void openssl_cleanup_threads(void); int openssl_seed_prng(void); int openssl_save_prng(void); #endif /* HAVE_OPENSSL */ /* crypto_wrap.c */ void aes_wrap(uint8_t *kek, int n, uint8_t *plain, uint8_t *cipher); int aes_unwrap(uint8_t *kek, int n, uint8_t *cipher, uint8_t *plain); /* daemon.c */ void daemon_start(); /* edit.c */ uint64_t str_to_uint64(const char *str); int64_t str_to_int64(const char *str); #define str_to_int32(str)((int32_t)str_to_int64(str)) char *edit_uint64_with_commas(uint64_t val, char *buf); char *edit_uint64_with_suffix(uint64_t val, char *buf); char *add_commas(char *val, char *buf); char *edit_uint64(uint64_t val, char *buf); char *edit_int64(int64_t val, char *buf); char *edit_int64_with_commas(int64_t val, char *buf); bool duration_to_utime(char *str, utime_t *value); bool size_to_uint64(char *str, uint64_t *value); bool speed_to_uint64(char *str, uint64_t *value); char *edit_utime(utime_t val, char *buf, int buf_len); bool is_a_number(const char *num); bool is_a_number_list(const char *n); bool is_an_integer(const char *n); bool is_name_valid(const char *name, POOLMEM **msg); /* jcr.c (most definitions are in src/jcr.h) */ void init_last_jobs_list(); void term_last_jobs_list(); void lock_last_jobs_list(); void unlock_last_jobs_list(); bool read_last_jobs_list(int fd, uint64_t addr); uint64_t write_last_jobs_list(int fd, uint64_t addr); void write_state_file(char *dir, const char *progname, int port); void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx); void lock_jobs(); void unlock_jobs(); JCR *jcr_walk_start(); JCR *jcr_walk_next(JCR *prev_jcr); void jcr_walk_end(JCR *jcr); int job_count(); JCR *get_jcr_from_tsd(); void set_jcr_in_tsd(JCR *jcr); void remove_jcr_from_tsd(JCR *jcr); uint32_t get_jobid_from_tsd(); uint32_t get_jobid_from_tid(pthread_t tid); /* lex.c */ LEX *lex_close_file(LEX *lf); LEX *lex_open_file(LEX *lf, const char *fname, LEX_ERROR_HANDLER *scan_error, LEX_WARNING_HANDLER *scan_warning); int lex_get_char(LEX *lf); void lex_unget_char(LEX *lf); const char *lex_tok_to_str(int token); int lex_get_token(LEX *lf, int expect); void lex_set_default_error_handler(LEX *lf); void lex_set_default_warning_handler(LEX *lf); int lex_set_error_handler_error_type(LEX *lf, int err_type); /* message.c */ void my_name_is(int argc, char *argv[], const char *name); void init_msg(JCR *jcr, MSGSRES *msg, job_code_callback_t job_code_callback = NULL); void term_msg(void); void close_msg(JCR *jcr); void add_msg_dest(MSGSRES *msg, int dest, int type, char *where, char *dest_code); void rem_msg_dest(MSGSRES *msg, int dest, int type, char *where); void Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt, ...); void dispatch_message(JCR *jcr, int type, utime_t mtime, char *buf); void init_console_msg(const char *wd); void free_msgs_res(MSGSRES *msgs); void dequeue_messages(JCR *jcr); void set_trace(int trace_flag); bool get_trace(void); void set_hangup(int hangup_value); bool get_hangup(void); void set_timestamp(int timestamp_flag); bool get_timestamp(void); void set_db_type(const char *name); void register_message_callback(void msg_callback(int type, char *msg)); /* passphrase.c */ char *generate_crypto_passphrase(int length); /* poll.c */ int wait_for_readable_fd(int fd, int sec, bool ignore_interupts); int wait_for_writable_fd(int fd, int sec, bool ignore_interupts); /* pythonlib.c */ int generate_daemon_event(JCR *jcr, const char *event); /* scan.c */ void strip_leading_space(char *str); void strip_trailing_junk(char *str); void strip_trailing_newline(char *str); void strip_trailing_slashes(char *dir); bool skip_spaces(char **msg); bool skip_nonspaces(char **msg); int fstrsch(const char *a, const char *b); char *next_arg(char **s); int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, char **argk, char **argv, int max_args); int parse_args_only(POOLMEM *cmd, POOLMEM **args, int *argc, char **argk, char **argv, int max_args); void split_path_and_filename(const char *fname, POOLMEM **path, int *pnl, POOLMEM **file, int *fnl); int bsscanf(const char *buf, const char *fmt, ...); /* scsi_crypto.c */ bool clear_scsi_encryption_key(int fd, const char *device); bool set_scsi_encryption_key(int fd, const char *device, char *encryption_key); int get_scsi_drive_encryption_status(int fd, const char *device_name, POOLMEM *&status, int indent); int get_scsi_volume_encryption_status(int fd, const char *device_name, POOLMEM *&status, int indent); bool need_scsi_crypto_key(int fd, const char *device_name, bool use_drive_status); bool is_scsi_encryption_enabled(int fd, const char *device_name); /* scsi_lli.c */ bool recv_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len); bool send_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len); bool check_scsi_at_eod(int fd); /* scsi_tapealert.c */ bool get_tapealert_flags(int fd, const char *device_name, uint64_t *flags); /* signal.c */ void init_signals(void terminate(int sig)); void init_stack_dump(void); /* timers.c */ btimer_t *start_child_timer(JCR *jcr, pid_t pid, uint32_t wait); void stop_child_timer(btimer_t *wid); btimer_t *start_thread_timer(JCR *jcr, pthread_t tid, uint32_t wait); void stop_thread_timer(btimer_t *wid); btimer_t *start_bsock_timer(BSOCK *bs, uint32_t wait); void stop_bsock_timer(btimer_t *wid); /* tls.c */ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, const char *crlfile, const char *certfile, const char *keyfile, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata, const char *dhfile, bool verify_peer); void free_tls_context(TLS_CONTEXT *ctx); #ifdef HAVE_TLS bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host); bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list); TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd, bool server); bool tls_bsock_accept(BSOCK *bsock); int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes); int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes); #endif /* HAVE_TLS */ bool tls_bsock_connect(BSOCK *bsock); void tls_bsock_shutdown(BSOCK *bsock); void free_tls_connection(TLS_CONNECTION *tls); bool get_tls_require(TLS_CONTEXT *ctx); void set_tls_require(TLS_CONTEXT *ctx, bool value); bool get_tls_enable(TLS_CONTEXT *ctx); void set_tls_enable(TLS_CONTEXT *ctx, bool value); /* util.c */ void escape_string(char *snew, char *old, int len); bool is_buf_zero(char *buf, int len); void lcase(char *str); void bash_spaces(char *str); void bash_spaces(POOL_MEM &pm); void unbash_spaces(char *str); void unbash_spaces(POOL_MEM &pm); char *encode_time(utime_t time, char *buf); char *encode_mode(mode_t mode, char *buf); int do_shell_expansion(char *name, int name_len); void jobstatus_to_ascii(int JobStatus, char *msg, int maxlen); void jobstatus_to_ascii_gui(int JobStatus, char *msg, int maxlen); int run_program(char *prog, int wait, POOLMEM *&results); int run_program_full_output(char *prog, int wait, POOLMEM *&results); char *action_on_purge_to_string(int aop, POOL_MEM &ret); const char *job_type_to_str(int type); const char *job_status_to_str(int stat); const char *job_level_to_str(int level); const char *volume_status_to_str(const char *status); void make_session_key(char *key, char *seed, int mode); void encode_session_key(char *encode, char *session, char *key, int maxlen); void decode_session_key(char *decode, char *session, char *key, int maxlen); POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to, job_code_callback_t job_code_callback = NULL); void set_working_directory(char *wd); const char *last_path_separator(const char *str); /* watchdog.c */ int start_watchdog(void); int stop_watchdog(void); watchdog_t *new_watchdog(void); bool register_watchdog(watchdog_t *wd); bool unregister_watchdog(watchdog_t *wd); bool is_watchdog(); #endif /* __LIBPROTOS_H */ bareos-Release-14.2.6/src/lib/queue.c000066400000000000000000000066731263011562700173010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Q U E U E Queue Handling Routines Taken from smartall written by John Walker. http://www.fourmilab.ch/smartall/ */ #include "bareos.h" /* General purpose queue */ #ifdef REALLY_NEEDED struct b_queue { struct b_queue *qnext, /* Next item in queue */ *qprev; /* Previous item in queue */ }; #endif /* * To define a queue, use the following * * static BQUEUE xyz = { &xyz, &xyz }; * * Also, note, that the only real requirement is that * the object that is passed to these routines contain * a BQUEUE object as the very first member. The * rest of the structure may be anything. * * NOTE!!!! The casting here is REALLY painful, but this avoids * doing ugly casting every where else in the code. */ /* Queue manipulation functions. */ /* QINSERT -- Insert object at end of queue */ void qinsert(BQUEUE *qhead, BQUEUE *object) { #define qh ((BQUEUE *)qhead) #define obj ((BQUEUE *)object) ASSERT(qh->qprev->qnext == qh); ASSERT(qh->qnext->qprev == qh); obj->qnext = qh; obj->qprev = qh->qprev; qh->qprev = obj; obj->qprev->qnext = obj; #undef qh #undef obj } /* QREMOVE -- Remove next object from the queue given the queue head (or any item). Returns NULL if queue is empty */ BQUEUE *qremove(BQUEUE *qhead) { #define qh ((BQUEUE *)qhead) BQUEUE *object; ASSERT(qh->qprev->qnext == qh); ASSERT(qh->qnext->qprev == qh); if ((object = qh->qnext) == qh) return NULL; qh->qnext = object->qnext; object->qnext->qprev = qh; return object; #undef qh } /* QNEXT -- Return next item from the queue * returns NULL at the end of the queue. * If qitem is NULL, the first item from * the queue is returned. */ BQUEUE *qnext(BQUEUE *qhead, BQUEUE *qitem) { #define qh ((BQUEUE *)qhead) #define qi ((BQUEUE *)qitem) BQUEUE *object; if (qi == NULL) qitem = qhead; ASSERT(qi->qprev->qnext == qi); ASSERT(qi->qnext->qprev == qi); if ((object = qi->qnext) == qh) return NULL; return object; #undef qh #undef qi } /* QDCHAIN -- Dequeue an item from the middle of a queue. Passed the queue item, returns the (now dechained) queue item. */ BQUEUE *qdchain(BQUEUE *qitem) { #define qi ((BQUEUE *)qitem) ASSERT(qi->qprev->qnext == qi); ASSERT(qi->qnext->qprev == qi); return qremove(qi->qprev); #undef qi } bareos-Release-14.2.6/src/lib/queue.h000066400000000000000000000023511263011562700172730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by John Walker MM */ /* * General purpose queue */ struct b_queue { struct b_queue *qnext; /* Next item in queue */ struct b_queue *qprev; /* Previous item in queue */ }; typedef struct b_queue BQUEUE; /* * Queue functions */ void qinsert(BQUEUE *qhead, BQUEUE *object); BQUEUE *qnext(BQUEUE *qhead, BQUEUE *qitem); BQUEUE *qdchain(BQUEUE *qitem); BQUEUE *qremove(BQUEUE *qhead); bareos-Release-14.2.6/src/lib/rblist.c000066400000000000000000000274571263011562700174570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS red-black binary tree routines. * * rblist is a binary tree with the links being in the data item. * * Developped in part from ideas obtained from several online University courses. * * Kern Sibbald, November MMV */ #include "bareos.h" /* * Insert an item in the tree, but only if it is unique * otherwise, the item is returned non inserted * The big trick is keeping the tree balanced after the * insert. We use a parent pointer to make it simpler and * to avoid recursion. * * Returns: item if item inserted * other_item if same value already exists (item not inserted) */ void *rblist::insert(void *item, int compare(void *item1, void *item2)) { void *x, *y; void *last = NULL; /* last leaf if not found */ void *found = NULL; int comp = 0; /* Search */ x = head; while (x && !found) { last = x; comp = compare(item, x); if (comp < 0) { x = left(x); } else if (comp > 0) { x = right(x); } else { found = x; } } if (found) { /* found? */ return found; /* yes, return item found */ } set_left(item, NULL); set_right(item, NULL); set_parent(item, NULL); set_red(item, false); /* Handle empty tree */ if (num_items == 0) { head = item; num_items++; return item; } x = last; /* Not found, so insert it on appropriate side of tree */ if (comp < 0) { set_left(last, item); } else { set_right(last, item); } set_red(last, true); set_parent(item, last); num_items++; /* Now we must walk up the tree balancing it */ x = last; while (x != head && red(parent(x))) { if (parent(x) == left(parent(parent(x)))) { /* Look at the right side of our grandparent */ y = right(parent(parent(x))); if (y && red(y)) { /* our parent must be black */ set_red(parent(x), false); set_red(y, false); set_red(parent(parent(x)), true); x = parent(parent(x)); /* move up to grandpa */ } else { if (x == right(parent(x))) { /* right side of parent? */ x = parent(x); left_rotate(x); } /* make parent black too */ set_red(parent(x), false); set_red(parent(parent(x)), true); right_rotate(parent(parent(x))); } } else { /* Look at left side of our grandparent */ y = left(parent(parent(x))); if (y && red(y)) { set_red(parent(x), false); set_red(y, false); set_red(parent(parent(x)), true); x = parent(parent(x)); /* move up to grandpa */ } else { if (x == left(parent(x))) { x = parent(x); right_rotate(x); } /* make parent black too */ set_red(parent(x), false); set_red(parent(parent(x)), true); left_rotate(parent(parent(x))); } } } /* Make sure the head is always black */ set_red(head, false); return item; } /* * Search for item */ void *rblist::search(void *item, int compare(void *item1, void *item2)) { void *found = NULL; void *x; int comp; x = head; while (x) { comp = compare(item, x); if (comp < 0) { x = left(x); } else if (comp > 0) { x = right(x); } else { found = x; break; } } return found; } /* * Get first item (i.e. lowest value) */ void *rblist::first(void) { void *x; x = head; down = true; while (x) { if (left(x)) { x = left(x); continue; } return x; } /* Tree is empty */ return NULL; } /* * This is a non-recursive btree walk routine that returns * the items one at a time in order. I've never seen a * non-recursive tree walk routine published that returns * one item at a time rather than doing a callback. * * Return the next item in sorted order. We assume first() * was called once before calling this routine. * We always go down as far as we can to the left, then up, and * down one to the right, and again down as far as we can to the * left. etc. * * Returns: pointer to next larger item * NULL when no more items in tree */ void *rblist::next(void *item) { void *x; if (!item) { return first(); } x = item; if ((down && !left(x) && right(x)) || (!down && right(x))) { /* Move down to right one */ down = true; x = right(x); /* Then all the way down left */ while (left(x)) { x = left(x); } return x; } /* We have gone down all we can, so now go up */ for ( ;; ) { /* If at head, we are done */ if (!parent(x)) { return NULL; } /* Move up in tree */ down = false; /* if coming from right, continue up */ if (right(parent(x)) == x) { x = parent(x); continue; } /* Coming from left, go up one -- ie. return parent */ return parent(x); } } /* * Similer to next(), but visits all right nodes when * coming up the tree. */ void *rblist::any(void *item) { void *x; if (!item) { return NULL; } x = item; if ((down && !left(x) && right(x)) || (!down && right(x))) { /* Move down to right one */ down = true; x = right(x); /* Then all the way down left */ while (left(x)) { x = left(x); } return x; } /* We have gone down all we can, so now go up */ for ( ;; ) { /* If at head, we are done */ if (!parent(x)) { return NULL; } down = false; /* Go up one and return parent */ return parent(x); } } /* x is item, y is below and to right, then rotated to below left */ void rblist::left_rotate(void *item) { void *y; void *x; x = item; y = right(x); set_right(x, left(y)); if (left(y)) { set_parent(left(y), x); } set_parent(y, parent(x)); /* if no parent then we have a new head */ if (!parent(x)) { head = y; } else if (x == left(parent(x))) { set_left(parent(x), y); } else { set_right(parent(x), y); } set_left(y, x); set_parent(x, y); } void rblist::right_rotate(void *item) { void *x, *y; y = item; x = left(y); set_left(y, right(x)); if (right(x)) { set_parent(right(x), y); } set_parent(x, parent(y)); /* if no parent then we have a new head */ if (!parent(y)) { head = x; } else if (y == left(parent(y))) { set_left(parent(y), x); } else { set_right(parent(y), x); } set_right(x, y); set_parent(y, x); } void rblist::remove(void *item) { } /* Destroy the tree contents. Not totally working */ void rblist::destroy() { void *x, *y = NULL; x = first(); // printf("head=%p first=%p left=%p right=%p\n", head, x, left(x), right(x)); for ( ; (y=any(x)); ) { /* Prune the last item */ if (parent(x)) { if (x == left(parent(x))) { set_left(parent(x), NULL); } else if (x == right(parent(x))) { set_right(parent(x), NULL); } } if (!left(x) && !right(x)) { if (head == x) { head = NULL; } // if (num_items<30) { // printf("free nitems=%d item=%p left=%p right=%p\n", num_items, x, left(x), right(x)); // } free((void *)x); /* free previous node */ num_items--; } x = y; /* save last node */ } if (x) { if (x == head) { head = NULL; } // printf("free nitems=%d item=%p left=%p right=%p\n", num_items, x, left(x), right(x)); free((void *)x); num_items--; } if (head) { // printf("Free head\n"); free((void *)head); } // printf("free nitems=%d\n", num_items); head = NULL; } #ifdef TEST_PROGRAM struct MYJCR { void link; char *buf; }; static int my_compare(void *item1, void *item2) { MYJCR *jcr1, *jcr2; int comp; jcr1 = (MYJCR *)item1; jcr2 = (MYJCR *)item2; comp = strcmp(jcr1->buf, jcr2->buf); //Dmsg3(000, "compare=%d: %s to %s\n", comp, jcr1->buf, jcr2->buf); return comp; } int main() { char buf[30]; rblist *jcr_chain; MYJCR *jcr = NULL; MYJCR *jcr1; /* Now do a binary insert for the tree */ jcr_chain = New(rblist()); #define CNT 26 printf("append %d items\n", CNT*CNT*CNT); strcpy(buf, "ZZZ"); int count = 0; for (int i=0; ibuf = bstrdup(buf); // printf("buf=%p %s\n", jcr, jcr->buf); jcr1 = (MYJCR *)jcr_chain->insert((void *)jcr, my_compare); if (jcr != jcr1) { Dmsg2(000, "Insert of %s vs %s failed.\n", jcr->buf, jcr1->buf); } buf[1]--; } buf[1] = 'Z'; buf[2]--; } buf[2] = 'Z'; buf[0]--; } printf("%d items appended\n", CNT*CNT*CNT); printf("num_items=%d\n", jcr_chain->size()); jcr = (MYJCR *)malloc(sizeof(MYJCR)); memset(jcr, 0, sizeof(MYJCR)); jcr->buf = bstrdup("a"); if ((jcr1=(MYJCR *)jcr_chain->search((void *)jcr, my_compare))) { printf("One less failed!!!! Got: %s\n", jcr1->buf); } else { printf("One less: OK\n"); } free(jcr->buf); jcr->buf = bstrdup("ZZZZZZZZZZZZZZZZ"); if ((jcr1=(MYJCR *)jcr_chain->search((void *)jcr, my_compare))) { printf("One greater failed!!!! Got:%s\n", jcr1->buf); } else { printf("One greater: OK\n"); } free(jcr->buf); jcr->buf = bstrdup("AAA"); if ((jcr1=(MYJCR *)jcr_chain->search((void *)jcr, my_compare))) { printf("Search for AAA got %s\n", jcr1->buf); } else { printf("Search for AAA not found\n"); } free(jcr->buf); jcr->buf = bstrdup("ZZZ"); if ((jcr1 = (MYJCR *)jcr_chain->search((void *)jcr, my_compare))) { printf("Search for ZZZ got %s\n", jcr1->buf); } else { printf("Search for ZZZ not found\n"); } free(jcr->buf); free(jcr); printf("Find each of %d items in tree.\n", count); for (jcr=(MYJCR *)jcr_chain->first(); jcr; (jcr=(MYJCR *)jcr_chain->next((void *)jcr)) ) { // printf("Got: %s\n", jcr->buf); if (!jcr_chain->search((void *)jcr, my_compare)) { printf("rblist binary_search item not found = %s\n", jcr->buf); } } printf("Free each of %d items in tree.\n", count); for (jcr=(MYJCR *)jcr_chain->first(); jcr; (jcr=(MYJCR *)jcr_chain->next((void *)jcr)) ) { // printf("Free: %p %s\n", jcr, jcr->buf); free(jcr->buf); jcr->buf = NULL; } printf("num_items=%d\n", jcr_chain->size()); delete jcr_chain; sm_dump(true); /* unit test */ } #endif bareos-Release-14.2.6/src/lib/rblist.h000066400000000000000000000100361263011562700174450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * red-black binary tree routines -- rblist.h * * Kern Sibbald, MMV */ #define M_ABORT 1 /* * There is a lot of extra casting here to work around the fact * that some compilers (Sun and Visual C++) do not accept * (bnode *) as an lvalue on the left side of an equal. * * Loop var through each member of list */ #ifdef HAVE_TYPEOF #define foreach_rblist(var, tree) \ for (((var)=(typeof(var))(tree)->first()); (var); ((var)=(typeof(var))(tree)->next(var))) #else #define foreach_rblist(var, tree) \ for ((*((void **)&(var))=(void*)((tree)->first())); (var); (*((void **)&(var))=(void*)((tree)->next(var)))) #endif struct rblink { void *parent; void *left; void *right; bool red; }; class rblist : public SMARTALLOC { void *head; int16_t loffset; uint32_t num_items; bool down; void left_rotate(void *item); void right_rotate(void *item); public: rblist(void *item, rblink *link); rblist(void); ~rblist(void) { destroy(); } void init(void *item, rblink *link); void set_parent(void *item, void *parent); void set_left(void *item, void *left); void set_right(void *item, void *right); void set_red(void *item, bool red); void *parent(const void *item) const; void *left(const void *item) const; void *right(const void *item) const; bool red(const void *item) const; void *insert(void *item, int compare(void *item1, void *item2)); void *search(void *item, int compare(void *item1, void *item2)); void *first(void); void *next(void *item); void *any(void *item); void remove(void *item); bool empty(void) const; int size(void) const; void destroy(void); }; /* * This allows us to do explicit initialization, * allowing us to mix C++ classes inside malloc'ed * C structures. Define before called in constructor. */ inline void rblist::init(void *item, rblink *link) { head = NULL; loffset = (int)((char *)link - (char *)item); if (loffset < 0 || loffset > 5000) { Emsg0(M_ABORT, 0, "Improper rblist initialization.\n"); } num_items = 0; } inline rblist::rblist(void *item, rblink *link) { init(item, link); } /* Constructor with link at head of item */ inline rblist::rblist(void): head(0), loffset(0), num_items(0) { } inline void rblist::set_parent(void *item, void *parent) { ((rblink *)(((char *)item)+loffset))->parent = parent; } inline void rblist::set_left(void *item, void *left) { ((rblink *)(((char *)item)+loffset))->left = left; } inline void rblist::set_right(void *item, void *right) { ((rblink *)(((char *)item)+loffset))->right = right; } inline void rblist::set_red(void *item, bool red) { ((rblink *)(((char *)item)+loffset))->red = red; } inline bool rblist::empty(void) const { return head == NULL; } inline int rblist::size() const { return num_items; } inline void *rblist::parent(const void *item) const { return ((rblink *)(((char *)item)+loffset))->parent; } inline void *rblist::left(const void *item) const { return ((rblink *)(((char *)item)+loffset))->left; } inline void *rblist::right(const void *item) const { return ((rblink *)(((char *)item)+loffset))->right; } inline bool rblist::red(const void *item) const { return ((rblink *)(((char *)item)+loffset))->red; } bareos-Release-14.2.6/src/lib/res.c000066400000000000000000001705671263011562700167520ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file handles most things related to generic resources. * * Kern Sibbald, January MM * Split from parse_conf.c April MMV */ #include "bareos.h" #include "generic_res.h" /* Forward referenced subroutines */ static void scan_types(LEX *lc, MSGSRES *msg, int dest, char *where, char *cmd); static const char *datatype_to_str(int type); extern CONFIG *my_config; /* Our Global config */ /* * Set default indention e.g. 2 spaces. */ #define DEFAULT_INDENT_STRING " " /* * Define the Union of all the common resource structure definitions. */ union URES { MSGSRES res_msgs; RES hdr; }; static int res_locked = 0; /* resource chain lock count -- for debug */ /* #define TRACE_RES */ void b_LockRes(const char *file, int line) { int errstat; #ifdef TRACE_RES Pmsg4(000, "LockRes locked=%d w_active=%d at %s:%d\n", res_locked, my_config->m_res_lock.w_active, file, line); if (res_locked) { Pmsg2(000, "LockRes writerid=%d myid=%d\n", my_config->m_res_lock.writer_id, pthread_self()); } #endif if ((errstat = rwl_writelock(&my_config->m_res_lock)) != 0) { Emsg3(M_ABORT, 0, _("rwl_writelock failure at %s:%d: ERR=%s\n"), file, line, strerror(errstat)); } res_locked++; } void b_UnlockRes(const char *file, int line) { int errstat; if ((errstat = rwl_writeunlock(&my_config->m_res_lock)) != 0) { Emsg3(M_ABORT, 0, _("rwl_writeunlock failure at %s:%d:. ERR=%s\n"), file, line, strerror(errstat)); } res_locked--; #ifdef TRACE_RES Pmsg4(000, "UnLockRes locked=%d wactive=%d at %s:%d\n", res_locked, my_config->m_res_lock.w_active, file, line); #endif } /* * Return resource of type rcode that matches name */ RES *GetResWithName(int rcode, const char *name) { RES *res; int rindex = rcode - my_config->m_r_first; LockRes(); res = my_config->m_res_head[rindex]; while (res) { if (bstrcmp(res->name, name)) { break; } res = res->next; } UnlockRes(); return res; } /* * Return next resource of type rcode. On first * call second arg (res) is NULL, on subsequent * calls, it is called with previous value. */ RES *GetNextRes(int rcode, RES *res) { RES *nres; int rindex = rcode - my_config->m_r_first; if (res == NULL) { nres = my_config->m_res_head[rindex]; } else { nres = res->next; } return nres; } const char *res_to_str(int rcode) { if (rcode < my_config->m_r_first || rcode > my_config->m_r_last) { return _("***UNKNOWN***"); } else { return my_config->m_resources[rcode - my_config->m_r_first].name; } } /* * Store Messages Destination information */ static void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass) { int token; char *cmd; POOLMEM *dest; int dest_len; URES *res_all = (URES *)my_config->m_res_all; Dmsg2(900, "store_msgs pass=%d code=%d\n", pass, item->code); if (pass == 1) { switch (item->code) { case MD_STDOUT: case MD_STDERR: case MD_CONSOLE: case MD_CATALOG: scan_types(lc, (MSGSRES *)(item->value), item->code, NULL, NULL); break; case MD_SYSLOG: { /* syslog */ char *p; int cnt = 0; bool done = false; /* * See if this is an old style syslog definition. * We count the number of = signs in the current config line. */ p = lc->line; while (!done && *p) { switch (*p) { case '=': cnt++; break; case ',': case ';': /* * No need to continue scanning when we encounter a ',' or ';' */ done = true; break; default: break; } p++; } /* * If there is more then one = its the new format e.g. * syslog = facility = filter */ if (cnt > 1) { dest = get_pool_memory(PM_MESSAGE); /* * Pick up a single facility. */ token = lex_get_token(lc, T_NAME); /* scan destination */ pm_strcpy(dest, lc->str); dest_len = lc->str_len; token = lex_get_token(lc, T_SKIP_EOL); scan_types(lc, (MSGSRES *)(item->value), item->code, dest, NULL); free_pool_memory(dest); Dmsg0(900, "done with dest codes\n"); } else { scan_types(lc, (MSGSRES *)(item->value), item->code, NULL, NULL); } break; } case MD_OPERATOR: /* send to operator */ case MD_DIRECTOR: /* send to Director */ case MD_MAIL: /* mail */ case MD_MAIL_ON_ERROR: /* mail if Job errors */ case MD_MAIL_ON_SUCCESS: /* mail if Job succeeds */ if (item->code == MD_OPERATOR) { cmd = res_all->res_msgs.operator_cmd; } else { cmd = res_all->res_msgs.mail_cmd; } dest = get_pool_memory(PM_MESSAGE); dest[0] = 0; dest_len = 0; /* * Pick up comma separated list of destinations. */ for (;;) { token = lex_get_token(lc, T_NAME); /* scan destination */ dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2); if (dest[0] != 0) { pm_strcat(dest, " "); /* separate multiple destinations with space */ dest_len++; } pm_strcat(dest, lc->str); dest_len += lc->str_len; Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest)); token = lex_get_token(lc, T_SKIP_EOL); if (token == T_COMMA) { continue; /* get another destination */ } if (token != T_EQUALS) { scan_err1(lc, _("expected an =, got: %s"), lc->str); return; } break; } Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd)); scan_types(lc, (MSGSRES *)(item->value), item->code, dest, cmd); free_pool_memory(dest); Dmsg0(900, "done with dest codes\n"); break; case MD_FILE: /* file */ case MD_APPEND: /* append */ dest = get_pool_memory(PM_MESSAGE); /* * Pick up a single destination. */ token = lex_get_token(lc, T_NAME); /* scan destination */ pm_strcpy(dest, lc->str); dest_len = lc->str_len; token = lex_get_token(lc, T_SKIP_EOL); Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest)); if (token != T_EQUALS) { scan_err1(lc, _("expected an =, got: %s"), lc->str); return; } scan_types(lc, (MSGSRES *)(item->value), item->code, dest, NULL); free_pool_memory(dest); Dmsg0(900, "done with dest codes\n"); break; default: scan_err1(lc, _("Unknown item code: %d\n"), item->code); return; } } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); Dmsg0(900, "Done store_msgs\n"); } /* * Scan for message types and add them to the message * destination. The basic job here is to connect message types * (WARNING, ERROR, FATAL, INFO, ...) with an appropriate * destination (MAIL, FILE, OPERATOR, ...) */ static void scan_types(LEX *lc, MSGSRES *msg, int dest_code, char *where, char *cmd) { int i; bool found, is_not; int msg_type = 0; char *str; for (;;) { lex_get_token(lc, T_NAME); /* expect at least one type */ found = false; if (lc->str[0] == '!') { is_not = true; str = &lc->str[1]; } else { is_not = false; str = &lc->str[0]; } for (i = 0; msg_types[i].name; i++) { if (bstrcasecmp(str, msg_types[i].name)) { msg_type = msg_types[i].token; found = true; break; } } if (!found) { scan_err1(lc, _("message type: %s not found"), str); return; } if (msg_type == M_MAX + 1) { /* all? */ for (i = 1; i <= M_MAX; i++) { /* yes set all types */ add_msg_dest(msg, dest_code, i, where, cmd); } } else if (is_not) { rem_msg_dest(msg, dest_code, msg_type, where); } else { add_msg_dest(msg, dest_code, msg_type, where, cmd); } if (lc->ch != ',') { break; } Dmsg0(900, "call lex_get_token() to eat comma\n"); lex_get_token(lc, T_ALL); /* eat comma */ } Dmsg0(900, "Done scan_types()\n"); } /* * This routine is ONLY for resource names * Store a name at specified address. */ static void store_name(LEX *lc, RES_ITEM *item, int index, int pass) { POOLMEM *msg = get_pool_memory(PM_EMSG); URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_NAME); if (!is_name_valid(lc->str, &msg)) { scan_err1(lc, "%s\n", msg); return; } free_pool_memory(msg); /* * Store the name both pass 1 and pass 2 */ if (*(item->value)) { scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."), *(item->value), lc->str); return; } *(item->value) = bstrdup(lc->str); scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a name string at specified address * A name string is limited to MAX_RES_NAME_LENGTH */ static void store_strname(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; /* * Store the name */ lex_get_token(lc, T_NAME); if (pass == 1) { /* * If a default was set free it first. */ if (*(item->value)) { free(*(item->value)); } *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a string at specified address */ static void store_str(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_STRING); if (pass == 1) { /* * If a default was set free it first. */ if (*(item->value)) { free(*(item->value)); } *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a directory name at specified address. Note, we do * shell expansion except if the string begins with a vertical * bar (i.e. it will likely be passed to the shell later). */ static void store_dir(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_STRING); if (pass == 1) { /* * If a default was set free it first. */ if (*(item->value)) { free(*(item->value)); } if (lc->str[0] != '|') { do_shell_expansion(lc->str, sizeof_pool_memory(lc->str)); } *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a password at specified address in MD5 coding */ static void store_md5password(LEX *lc, RES_ITEM *item, int index, int pass) { s_password *pwd; URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_STRING); if (pass == 1) { pwd = item->pwdvalue; if (pwd->value) { free(pwd->value); } /* * See if we are parsing an MD5 encoded password already. */ if (bstrncmp(lc->str, "[md5]", 5)) { pwd->encoding = p_encoding_md5; pwd->value = bstrdup(lc->str + 5); } else { unsigned int i, j; MD5_CTX md5c; unsigned char digest[CRYPTO_DIGEST_MD5_SIZE]; char sig[100]; MD5_Init(&md5c); MD5_Update(&md5c, (unsigned char *) (lc->str), lc->str_len); MD5_Final(digest, &md5c); for (i = j = 0; i < sizeof(digest); i++) { sprintf(&sig[j], "%02x", digest[i]); j += 2; } pwd->encoding = p_encoding_md5; pwd->value = bstrdup(sig); } } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a password at specified address in MD5 coding */ static void store_clearpassword(LEX *lc, RES_ITEM *item, int index, int pass) { s_password *pwd; URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_STRING); if (pass == 1) { pwd = item->pwdvalue; if (pwd->value) { free(pwd->value); } pwd->encoding = p_encoding_clear; pwd->value = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a resource at specified address. * If we are in pass 2, do a lookup of the * resource. */ static void store_res(LEX *lc, RES_ITEM *item, int index, int pass) { RES *res; URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(item->code, lc->str); if (res == NULL) { scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"), lc->str, lc->line_no, lc->line); return; } if (*(item->resvalue)) { scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"), item->name, lc->line_no, lc->line); return; } *(item->resvalue) = res; } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a resource pointer in an alist. default_value indicates how many * times this routine can be called -- i.e. how many alists there are. * * If we are in pass 2, do a lookup of the resource. */ static void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass) { RES *res; int i = 0; alist *list; URES *res_all = (URES *)my_config->m_res_all; int count = str_to_int32(item->default_value); if (pass == 2) { if (count == 0) { /* always store in item->value */ i = 0; if (!item->alistvalue[i]) { item->alistvalue[i] = New(alist(10, not_owned_by_alist)); } } else { /* * Find empty place to store this directive */ while ((item->value)[i] != NULL && i++ < count) { } if (i >= count) { scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"), lc->str, count, lc->line_no, lc->line); return; } item->alistvalue[i] = New(alist(10, not_owned_by_alist)); } list = item->alistvalue[i]; for (;;) { lex_get_token(lc, T_NAME); /* scan next item */ res = GetResWithName(item->code, lc->str); if (res == NULL) { scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"), item->name, lc->line_no, lc->line); return; } Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n", res, list, list->size(), i, item->name); list->append(res); if (lc->ch != ',') { /* if no other item follows */ break; /* get out */ } lex_get_token(lc, T_ALL); /* eat comma */ } } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a string in an alist. */ static void store_alist_str(LEX *lc, RES_ITEM *item, int index, int pass) { alist *list; URES *res_all = (URES *)my_config->m_res_all; if (pass == 2) { if (!*(item->value)) { *item->alistvalue = New(alist(10, owned_by_alist)); } list = *item->alistvalue; lex_get_token(lc, T_STRING); /* scan next item */ Dmsg4(900, "Append %s to alist %p size=%d %s\n", lc->str, list, list->size(), item->name); /* * See if we need to drop the default value from the alist. * * We first check to see if the config item has the CFG_ITEM_DEFAULT * flag set and currently has exactly one entry. */ if ((item->flags & CFG_ITEM_DEFAULT) && list->size() == 1) { char *entry; entry = (char *)list->first(); if (bstrcmp(entry, item->default_value)) { list->destroy(); list->init(10, owned_by_alist); } } list->append(bstrdup(lc->str)); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a directory name at specified address in an alist. * Note, we do shell expansion except if the string begins * with a vertical bar (i.e. it will likely be passed to the * shell later). */ static void store_alist_dir(LEX *lc, RES_ITEM *item, int index, int pass) { alist *list; URES *res_all = (URES *)my_config->m_res_all; if (pass == 2) { if (!*item->alistvalue) { *item->alistvalue = New(alist(10, owned_by_alist)); } list = *item->alistvalue; lex_get_token(lc, T_STRING); /* scan next item */ Dmsg4(900, "Append %s to alist %p size=%d %s\n", lc->str, list, list->size(), item->name); if (lc->str[0] != '|') { do_shell_expansion(lc->str, sizeof_pool_memory(lc->str)); } /* * See if we need to drop the default value from the alist. * * We first check to see if the config item has the CFG_ITEM_DEFAULT * flag set and currently has exactly one entry. */ if ((item->flags & CFG_ITEM_DEFAULT) && list->size() == 1) { char *entry; entry = (char *)list->first(); if (bstrcmp(entry, item->default_value)) { list->destroy(); list->init(10, owned_by_alist); } } list->append(bstrdup(lc->str)); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a list of plugin names to load by the daemon on startup. */ static void store_plugin_names(LEX *lc, RES_ITEM *item, int index, int pass) { alist *list; char *p, *plugin_name, *plugin_names; URES *res_all = (URES *)my_config->m_res_all; if (pass == 2) { lex_get_token(lc, T_STRING); /* scan next item */ if (!*item->alistvalue) { *(item->alistvalue) = New(alist(10, owned_by_alist)); } list = *item->alistvalue; plugin_names = bstrdup(lc->str); plugin_name = plugin_names; while (plugin_name) { /* * Split the plugin_names string on ':' */ if ((p = strchr(plugin_name, ':'))) { *p++ = '\0'; } list->append(bstrdup(plugin_name)); plugin_name = p; } free(plugin_names); } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store default values for Resource from xxxDefs * If we are in pass 2, do a lookup of the * resource and store everything not explicitly set * in main resource. * * Note, here item points to the main resource (e.g. Job, not * the jobdefs, which we look up). */ static void store_defs(LEX *lc, RES_ITEM *item, int index, int pass) { RES *res; lex_get_token(lc, T_NAME); if (pass == 2) { Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str); res = GetResWithName(item->code, lc->str); if (res == NULL) { scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"), lc->str, lc->line_no, lc->line); return; } } scan_to_eol(lc); } /* * Store an integer at specified address */ static void store_int32(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_INT32); *(item->i32value) = lc->int32_val; scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a positive integer at specified address */ static void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_PINT32); *(item->ui32value) = lc->pint32_val; scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store an 64 bit integer at specified address */ static void store_int64(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_INT64); *(item->i64value) = lc->int64_val; scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Unit types */ enum unit_type { STORE_SIZE, STORE_SPEED }; /* * Store a size in bytes */ static void store_int_unit(LEX *lc, RES_ITEM *item, int index, int pass, bool size32, enum unit_type type) { int token; uint64_t uvalue; char bsize[500]; URES *res_all = (URES *)my_config->m_res_all; Dmsg0(900, "Enter store_unit\n"); token = lex_get_token(lc, T_SKIP_EOL); errno = 0; switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncpy(bsize, lc->str, sizeof(bsize)); /* save first part */ /* * If terminated by space, scan and get modifier */ while (lc->ch == ' ') { token = lex_get_token(lc, T_ALL); switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncat(bsize, lc->str, sizeof(bsize)); break; } } switch (type) { case STORE_SIZE: if (!size_to_uint64(bsize, &uvalue)) { scan_err1(lc, _("expected a size number, got: %s"), lc->str); return; } break; case STORE_SPEED: if (!speed_to_uint64(bsize, &uvalue)) { scan_err1(lc, _("expected a speed number, got: %s"), lc->str); return; } break; default: scan_err0(lc, _("unknown unit type encountered")); return; } if (size32) { *(item->ui32value) = (uint32_t)uvalue; } else { switch (type) { case STORE_SIZE: *(item->i64value) = uvalue; break; case STORE_SPEED: *(item->ui64value) = uvalue; break; } } break; default: scan_err2(lc, _("expected a %s, got: %s"), (type == STORE_SIZE)?_("size"):_("speed"), lc->str); return; } if (token != T_EOL) { scan_to_eol(lc); } set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); Dmsg0(900, "Leave store_unit\n"); } /* * Store a size in bytes */ static void store_size32(LEX *lc, RES_ITEM *item, int index, int pass) { store_int_unit(lc, item, index, pass, true /* 32 bit */, STORE_SIZE); } /* * Store a size in bytes */ static void store_size64(LEX *lc, RES_ITEM *item, int index, int pass) { store_int_unit(lc, item, index, pass, false /* not 32 bit */, STORE_SIZE); } /* * Store a speed in bytes/s */ static void store_speed(LEX *lc, RES_ITEM *item, int index, int pass) { store_int_unit(lc, item, index, pass, false /* 64 bit */, STORE_SPEED); } /* * Store a time period in seconds */ static void store_time(LEX *lc, RES_ITEM *item, int index, int pass) { int token; utime_t utime; char period[500]; URES *res_all = (URES *)my_config->m_res_all; token = lex_get_token(lc, T_SKIP_EOL); errno = 0; switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncpy(period, lc->str, sizeof(period)); /* get first part */ /* * If terminated by space, scan and get modifier */ while (lc->ch == ' ') { token = lex_get_token(lc, T_ALL); switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncat(period, lc->str, sizeof(period)); break; } } if (!duration_to_utime(period, &utime)) { scan_err1(lc, _("expected a time period, got: %s"), period); return; } *(item->utimevalue) = utime; break; default: scan_err1(lc, _("expected a time period, got: %s"), lc->str); return; } if (token != T_EOL) { scan_to_eol(lc); } set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a yes/no in a bit field */ static void store_bit(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_NAME); if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) { *(item->ui32value) |= item->code; } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) { *(item->ui32value) &= ~(item->code); } else { scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */ return; } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store a bool in a bit field */ static void store_bool(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_NAME); if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) { *item->boolvalue = true; } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) { *(item->boolvalue) = false; } else { scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */ return; } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store Tape Label Type (BAREOS, ANSI, IBM) */ static void store_label(LEX *lc, RES_ITEM *item, int index, int pass) { int i; URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_NAME); /* * Store the label pass 2 so that type is defined */ for (i = 0; tapelabels[i].name; i++) { if (bstrcasecmp(lc->str, tapelabels[i].name)) { *(item->ui32value) = tapelabels[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str); return; } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); } /* * Store network addresses. * * my tests * positiv * = { ip = { addr = 1.2.3.4; port = 1205; } ipv4 = { addr = 1.2.3.4; port = http; } } * = { ip = { * addr = 1.2.3.4; port = 1205; } * ipv4 = { * addr = 1.2.3.4; port = http; } * ipv6 = { * addr = 1.2.3.4; * port = 1205; * } * ip = { * addr = 1.2.3.4 * port = 1205 * } * ip = { * addr = 1.2.3.4 * } * ip = { * addr = 2001:220:222::2 * } * ip = { * addr = bluedot.thun.net * } * } * negativ * = { ip = { } } * = { ipv4 { addr = doof.nowaytoheavenxyz.uhu; } } * = { ipv4 { port = 4711 } } */ static void store_addresses(LEX * lc, RES_ITEM * item, int index, int pass) { int token; int exist; int family = 0; char errmsg[1024]; char port_str[128]; char hostname_str[1024]; enum { EMPTYLINE = 0x0, PORTLINE = 0x1, ADDRLINE = 0x2 } next_line = EMPTYLINE; int port = str_to_int32(item->default_value); token = lex_get_token(lc, T_SKIP_EOL); if (token != T_BOB) { scan_err1(lc, _("Expected a block begin { , got: %s"), lc->str); } token = lex_get_token(lc, T_SKIP_EOL); if (token == T_EOB) { scan_err0(lc, _("Empty addr block is not allowed")); } do { if (!(token == T_UNQUOTED_STRING || token == T_IDENTIFIER)) { scan_err1(lc, _("Expected a string, got: %s"), lc->str); } if (bstrcasecmp("ip", lc->str) || bstrcasecmp("ipv4", lc->str)) { family = AF_INET; #ifdef HAVE_IPV6 } else if (bstrcasecmp("ipv6", lc->str)) { family = AF_INET6; } else { scan_err1(lc, _("Expected a string [ip|ipv4|ipv6], got: %s"), lc->str); } #else } else { scan_err1(lc, _("Expected a string [ip|ipv4], got: %s"), lc->str); } #endif token = lex_get_token(lc, T_SKIP_EOL); if (token != T_EQUALS) { scan_err1(lc, _("Expected a equal =, got: %s"), lc->str); } token = lex_get_token(lc, T_SKIP_EOL); if (token != T_BOB) { scan_err1(lc, _("Expected a block begin { , got: %s"), lc->str); } token = lex_get_token(lc, T_SKIP_EOL); exist = EMPTYLINE; port_str[0] = hostname_str[0] = '\0'; do { if (token != T_IDENTIFIER) { scan_err1(lc, _("Expected a identifier [addr|port], got: %s"), lc->str); } if (bstrcasecmp("port", lc->str)) { next_line = PORTLINE; if (exist & PORTLINE) { scan_err0(lc, _("Only one port per address block")); } exist |= PORTLINE; } else if (bstrcasecmp("addr", lc->str)) { next_line = ADDRLINE; if (exist & ADDRLINE) { scan_err0(lc, _("Only one addr per address block")); } exist |= ADDRLINE; } else { scan_err1(lc, _("Expected a identifier [addr|port], got: %s"), lc->str); } token = lex_get_token(lc, T_SKIP_EOL); if (token != T_EQUALS) { scan_err1(lc, _("Expected a equal =, got: %s"), lc->str); } token = lex_get_token(lc, T_SKIP_EOL); switch (next_line) { case PORTLINE: if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) { scan_err1(lc, _("Expected a number or a string, got: %s"), lc->str); } bstrncpy(port_str, lc->str, sizeof(port_str)); break; case ADDRLINE: if (!(token == T_UNQUOTED_STRING || token == T_IDENTIFIER)) { scan_err1(lc, _("Expected an IP number or a hostname, got: %s"), lc->str); } bstrncpy(hostname_str, lc->str, sizeof(hostname_str)); break; case EMPTYLINE: scan_err0(lc, _("State machine missmatch")); break; } token = lex_get_token(lc, T_SKIP_EOL); } while (token == T_IDENTIFIER); if (token != T_EOB) { scan_err1(lc, _("Expected a end of block }, got: %s"), lc->str); } if (pass == 1 && !add_address(item->dlistvalue, IPADDR::R_MULTIPLE, htons(port), family, hostname_str, port_str, errmsg, sizeof(errmsg))) { scan_err3(lc, _("Can't add hostname(%s) and port(%s) to addrlist (%s)"), hostname_str, port_str, errmsg); } token = scan_to_next_not_eol(lc); } while ((token == T_IDENTIFIER || token == T_UNQUOTED_STRING)); if (token != T_EOB) { scan_err1(lc, _("Expected a end of block }, got: %s"), lc->str); } } static void store_addresses_address(LEX * lc, RES_ITEM * item, int index, int pass) { int token; char errmsg[1024]; int port = str_to_int32(item->default_value); token = lex_get_token(lc, T_SKIP_EOL); if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) { scan_err1(lc, _("Expected an IP number or a hostname, got: %s"), lc->str); } if (pass == 1 && !add_address(item->dlistvalue, IPADDR::R_SINGLE_ADDR, htons(port), AF_INET, lc->str, 0, errmsg, sizeof(errmsg))) { scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errmsg); } } static void store_addresses_port(LEX * lc, RES_ITEM * item, int index, int pass) { int token; char errmsg[1024]; int port = str_to_int32(item->default_value); token = lex_get_token(lc, T_SKIP_EOL); if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) { scan_err1(lc, _("Expected a port number or string, got: %s"), lc->str); } if (pass == 1 && !add_address(item->dlistvalue, IPADDR::R_SINGLE_PORT, htons(port), AF_INET, 0, lc->str, errmsg, sizeof(errmsg))) { scan_err2(lc, _("can't add port (%s) to (%s)"), lc->str, errmsg); } } /* * Generic store resource dispatcher. */ bool store_resource(int type, LEX *lc, RES_ITEM *item, int index, int pass) { switch (type) { case CFG_TYPE_STR: store_str(lc, item, index, pass); break; case CFG_TYPE_DIR: store_dir(lc, item, index, pass); break; case CFG_TYPE_MD5PASSWORD: store_md5password(lc, item, index, pass); break; case CFG_TYPE_CLEARPASSWORD: store_clearpassword(lc, item, index, pass); break; case CFG_TYPE_NAME: store_name(lc, item, index, pass); break; case CFG_TYPE_STRNAME: store_strname(lc, item, index, pass); break; case CFG_TYPE_RES: store_res(lc, item, index, pass); break; case CFG_TYPE_ALIST_RES: store_alist_res(lc, item, index, pass); break; case CFG_TYPE_ALIST_STR: store_alist_str(lc, item, index, pass); break; case CFG_TYPE_ALIST_DIR: store_alist_dir(lc, item, index, pass); break; case CFG_TYPE_INT32: store_int32(lc, item, index, pass); break; case CFG_TYPE_PINT32: store_pint32(lc, item, index, pass); break; case CFG_TYPE_MSGS: store_msgs(lc, item, index, pass); break; case CFG_TYPE_INT64: store_int64(lc, item, index, pass); break; case CFG_TYPE_BIT: store_bit(lc, item, index, pass); break; case CFG_TYPE_BOOL: store_bool(lc, item, index, pass); break; case CFG_TYPE_TIME: store_time(lc, item, index, pass); break; case CFG_TYPE_SIZE64: store_size64(lc, item, index, pass); break; case CFG_TYPE_SIZE32: store_size32(lc, item, index, pass); break; case CFG_TYPE_SPEED: store_speed(lc, item, index, pass); break; case CFG_TYPE_DEFS: store_defs(lc, item, index, pass); break; case CFG_TYPE_LABEL: store_label(lc, item, index, pass); break; case CFG_TYPE_ADDRESSES: store_addresses(lc, item, index, pass); break; case CFG_TYPE_ADDRESSES_ADDRESS: store_addresses_address(lc, item, index, pass); break; case CFG_TYPE_ADDRESSES_PORT: store_addresses_port(lc, item, index, pass); break; case CFG_TYPE_PLUGIN_NAMES: store_plugin_names(lc, item, index, pass); break; default: return false; } return true; } static void indent_config_item(POOL_MEM &cfg_str, int level, const char *config_item) { int i; for (i = 0; i < level; i++) { pm_strcat(cfg_str, DEFAULT_INDENT_STRING); } pm_strcat(cfg_str, config_item); } static inline void print_config_size(RES_ITEM *item, POOL_MEM &cfg_str) { POOL_MEM temp; POOL_MEM volspec; /* vol specification string*/ int64_t bytes = *(item->ui64value); int factor; /* * convert default value string to numeric value */ static const char *modifier[] = { "g", "m", "k", "", NULL }; const int64_t multiplier[] = { 1073741824, /* gibi */ 1048576, /* mebi */ 1024, /* kibi */ 1 /* byte */ }; if (bytes == 0) { pm_strcat(volspec, "0"); } else { for (int t=0; modifier[t]; t++) { Dmsg2(200, " %s bytes: %lld\n", item->name, bytes); factor = bytes / multiplier[t]; bytes = bytes % multiplier[t]; if (factor > 0) { Mmsg(temp, "%d %s ", factor, modifier[t]); pm_strcat(volspec, temp.c_str()); Dmsg1(200, " volspec: %s\n", volspec.c_str()); } if (bytes == 0) { break; } } } Mmsg(temp, "%s = %s\n", item->name, volspec.c_str()); indent_config_item(cfg_str, 1, temp.c_str()); } static inline void print_config_time(RES_ITEM *item, POOL_MEM &cfg_str) { POOL_MEM temp; POOL_MEM timespec; utime_t secs = *(item->utimevalue); int factor; /* * Reverse time formatting: 1 Month, 1 Week, etc. * * convert default value string to numeric value */ static const char *modifier[] = { "years", "months", "weeks", "days", "hours", "minutes", "seconds", NULL }; static const int32_t multiplier[] = { 60 * 60 * 24 * 365, 60 * 60 * 24 * 30, 60 * 60 * 24 * 7, 60 * 60 * 24, 60 * 60, 60, 1, 0 }; if (secs == 0) { pm_strcat(timespec, "0"); } else { for (int t=0; modifier[t]; t++) { factor = secs / multiplier[t]; secs = secs % multiplier[t]; if (factor > 0) { Mmsg(temp, "%d %s ", factor, modifier[t]); pm_strcat(timespec, temp.c_str()); } if (secs == 0) { break; } } } Mmsg(temp, "%s = %s\n", item->name, timespec.c_str()); indent_config_item(cfg_str, 1, temp.c_str()); } bool MSGSRES::print_config(POOL_MEM &buff, bool hide_sensitive_data) { int len; POOLMEM *cmdbuf; POOL_MEM cfg_str; /* configuration as string */ POOL_MEM temp; MSGSRES *msgres; DEST *d; msgres = this; pm_strcat(cfg_str, "Messages {\n"); Mmsg(temp, " %s = \"%s\"\n", "Name", msgres->name()); pm_strcat(cfg_str, temp.c_str()); cmdbuf = get_pool_memory(PM_NAME); if (msgres->mail_cmd) { len = strlen(msgres->mail_cmd); cmdbuf = check_pool_memory_size(cmdbuf, len * 2); escape_string(cmdbuf, msgres->mail_cmd, len); Mmsg(temp, " mailcommand = \"%s\"\n", cmdbuf); pm_strcat(cfg_str, temp.c_str()); } if (msgres->operator_cmd) { len = strlen(msgres->operator_cmd); cmdbuf = check_pool_memory_size(cmdbuf, len * 2); escape_string(cmdbuf, msgres->operator_cmd, len); Mmsg(temp, " operatorcommand = \"%s\"\n", cmdbuf); pm_strcat(cfg_str, temp.c_str()); } free_pool_memory(cmdbuf); for (d = msgres->dest_chain; d; d = d->next) { int nr_set = 0; int nr_unset = 0; POOL_MEM t; /* number of set types */ POOL_MEM u; /* number of unset types */ for (int i = 0; msg_destinations[i].code; i++) { if (msg_destinations[i].code == d->dest_code) { if (msg_destinations[i].where) { Mmsg(temp, " %s = %s = ", msg_destinations[i].destination, d->where); } else { Mmsg(temp, " %s = ", msg_destinations[i].destination); } pm_strcat(cfg_str, temp.c_str()); break; } } for (int j = 0; j < M_MAX - 1; j++) { if bit_is_set(msg_types[j].token, d->msg_types) { nr_set ++; Mmsg(temp, ",%s" , msg_types[j].name); pm_strcat(t, temp.c_str()); } else { Mmsg(temp, ",!%s" , msg_types[j].name); nr_unset++; pm_strcat(u, temp.c_str()); } } if (nr_set > nr_unset) { /* if more is set than is unset */ pm_strcat(cfg_str,"all"); /* all, but not ... */ pm_strcat(cfg_str, u.c_str()); } else { /* only print set types */ pm_strcat(cfg_str, t.c_str() + 1); /* skip first comma */ } pm_strcat(cfg_str, "\n"); } pm_strcat (cfg_str, "}\n\n"); pm_strcat (buff, cfg_str.c_str()); return true; } bool BRSRES::print_config(POOL_MEM &buff, bool hide_sensitive_data) { POOL_MEM cfg_str; POOL_MEM temp; RES_ITEM *items; int i = 0; int rindex; /* * If entry is not used, then there is nothing to print. */ if (this->hdr.rcode < (uint32_t)my_config->m_r_first || this->hdr.refcnt <= 0) { return true; } rindex = this->hdr.rcode - my_config->m_r_first; /* * Make sure the resource class has any items. */ if (!my_config->m_resources[rindex].items) { return true; } memcpy(my_config->m_res_all, this, my_config->m_resources[rindex].size); pm_strcat(cfg_str, res_to_str(this->hdr.rcode)); pm_strcat(cfg_str, " {\n"); items = my_config->m_resources[rindex].items; for (i = 0; items[i].name; i++) { bool print_item = false; /* * If this is an alias for an other config keyword suppress it. */ if ((items[i].flags & CFG_ITEM_ALIAS)) { continue; } if ((items[i].flags & CFG_ITEM_REQUIRED) || !my_config->m_omit_defaults) { /* * Always print required items or if my_config->m_omit_defaults is false */ print_item = true; } else if (items[i].flags & CFG_ITEM_DEFAULT) { /* * See if the item has inherited content from somewhere. * If that is true there is no need to check the whole default setting. */ if (!bit_is_set(i, this->hdr.inherit_content)) { /* * Check for default values. */ switch (items[i].type) { case CFG_TYPE_STR: case CFG_TYPE_DIR: case CFG_TYPE_NAME: case CFG_TYPE_STRNAME: print_item = !bstrcmp(*(items[i].value), items[i].default_value); break; case CFG_TYPE_INT32: print_item = (*(items[i].i32value) != str_to_int32(items[i].default_value)); break; case CFG_TYPE_PINT32: print_item = (*(items[i].ui32value) != (uint32_t)str_to_int32(items[i].default_value)); break; case CFG_TYPE_INT64: print_item = (*(items[i].i64value) != str_to_int64(items[i].default_value)); break; case CFG_TYPE_SPEED: print_item = (*(items[i].ui64value) != (uint64_t)str_to_int64(items[i].default_value)); break; case CFG_TYPE_SIZE64: print_item = (*(items[i].ui64value) != (uint64_t)str_to_int64(items[i].default_value)); break; case CFG_TYPE_SIZE32: print_item = (*(items[i].ui32value) != (uint32_t)str_to_int32(items[i].default_value)); break; case CFG_TYPE_TIME: print_item = (*(items[i].ui64value) != (uint64_t)str_to_int64(items[i].default_value)); break; case CFG_TYPE_BOOL: { bool default_value = bstrcasecmp(items[i].default_value, "true") || bstrcasecmp(items[i].default_value, "yes"); print_item = (*items[i].boolvalue != default_value); break; } default: break; } } } else { /* * See if the item has inherited content from somewhere. * If that is true there is no need to check the whole default setting. */ if (!bit_is_set(i, this->hdr.inherit_content)) { switch (items[i].type) { case CFG_TYPE_STR: case CFG_TYPE_DIR: case CFG_TYPE_NAME: case CFG_TYPE_STRNAME: print_item = *(items[i].value) != NULL; break; case CFG_TYPE_INT32: print_item = (*(items[i].i32value) > 0); break; case CFG_TYPE_PINT32: print_item = (*(items[i].ui32value) > 0); break; case CFG_TYPE_INT64: print_item = (*(items[i].i64value) > 0); break; case CFG_TYPE_SPEED: print_item = (*(items[i].ui64value) > 0); break; case CFG_TYPE_SIZE64: print_item = (*(items[i].ui64value) > 0); break; case CFG_TYPE_SIZE32: print_item = (*(items[i].ui32value) > 0); break; case CFG_TYPE_TIME: print_item = (*(items[i].ui64value) > 0); break; case CFG_TYPE_BOOL: print_item = (*items[i].boolvalue != false); break; default: break; } } } /* * See if the item has inherited content from somewhere. */ if (bit_is_set(i, this->hdr.inherit_content)) { continue; } switch (items[i].type) { case CFG_TYPE_STR: case CFG_TYPE_DIR: case CFG_TYPE_NAME: case CFG_TYPE_STRNAME: if (print_item && *(items[i].value) != NULL) { Dmsg2(200, "%s = \"%s\"\n", items[i].name, *(items[i].value)); Mmsg(temp, "%s = \"%s\"\n", items[i].name, *(items[i].value)); indent_config_item(cfg_str, 1, temp.c_str()); } break; case CFG_TYPE_MD5PASSWORD: case CFG_TYPE_CLEARPASSWORD: case CFG_TYPE_AUTOPASSWORD: if (print_item) { s_password *password; password = items[i].pwdvalue; if (password && password->value != NULL) { if (hide_sensitive_data) { Dmsg1(200, "%s = \"****************\"\n", items[i].name); Mmsg(temp, "%s = \"****************\"\n", items[i].name); } else { switch (password->encoding) { case p_encoding_clear: Dmsg2(200, "%s = \"%s\"\n", items[i].name, password->value); Mmsg(temp, "%s = \"%s\"\n", items[i].name, password->value); break; case p_encoding_md5: Dmsg2(200, "%s = \"[md5]%s\"\n", items[i].name, password->value); Mmsg(temp, "%s = \"[md5]%s\"\n", items[i].name, password->value); break; default: break; } } indent_config_item(cfg_str, 1, temp.c_str()); } } break; case CFG_TYPE_LABEL: for (int j = 0; tapelabels[j].name; j++) { if (*(items[i].ui32value) == tapelabels[j].token) { /* * Supress printing default value. */ if (items[i].flags & CFG_ITEM_DEFAULT) { if (bstrcasecmp(items[i].default_value, tapelabels[j].name)) { break; } } Mmsg(temp, "%s = \"%s\"\n", items[i].name, tapelabels[j].name); indent_config_item(cfg_str, 1, temp.c_str()); break; } } break; case CFG_TYPE_INT32: if (print_item) { Mmsg(temp, "%s = %d\n", items[i].name, *(items[i].i32value)); indent_config_item(cfg_str, 1, temp.c_str()); } break; case CFG_TYPE_PINT32: if (print_item) { Mmsg(temp, "%s = %d\n", items[i].name, *(items[i].ui32value)); indent_config_item(cfg_str, 1, temp.c_str()); } break; case CFG_TYPE_INT64: if (print_item) { Mmsg(temp, "%s = %d\n", items[i].name, *(items[i].i64value)); indent_config_item(cfg_str, 1, temp.c_str()); } break; case CFG_TYPE_SPEED: if (print_item) { Mmsg(temp, "%s = %d\n", items[i].name, *(items[i].ui64value)); indent_config_item(cfg_str, 1, temp.c_str()); } break; case CFG_TYPE_SIZE64: case CFG_TYPE_SIZE32: if (print_item) { print_config_size(&items[i], cfg_str); } break; case CFG_TYPE_TIME: if (print_item) { print_config_time(&items[i], cfg_str); } break; case CFG_TYPE_BOOL: if (print_item) { if (*items[i].boolvalue) { Mmsg(temp, "%s = %s\n", items[i].name, NT_("yes")); } else { Mmsg(temp, "%s = %s\n", items[i].name, NT_("no")); } indent_config_item(cfg_str, 1, temp.c_str()); } break; case CFG_TYPE_ALIST_STR: case CFG_TYPE_ALIST_DIR: case CFG_TYPE_PLUGIN_NAMES: { /* * One line for each member of the list */ char *value; alist* list; list = (alist *) *(items[i].value); if (list != NULL) { foreach_alist(value, list) { /* * If this is the default value skip it. */ if (items[i].flags & CFG_ITEM_DEFAULT) { if (bstrcmp(value, items[i].default_value)) { continue; } } Mmsg(temp, "%s = \"%s\"\n", items[i].name, value); indent_config_item(cfg_str, 1, temp.c_str()); } } break; } case CFG_TYPE_ALIST_RES: { /* * Each member of the list is comma-separated */ int cnt = 0; RES *res; alist* list; POOL_MEM res_names; list = (alist *) *(items[i].value); if (list != NULL) { Mmsg(temp, "%s = ", items[i].name); indent_config_item(cfg_str, 1, temp.c_str()); pm_strcpy(res_names, ""); foreach_alist(res, list) { if (cnt) { Mmsg(temp, ",\"%s\"", res->name); } else { Mmsg(temp, "\"%s\"", res->name); } pm_strcat(res_names, temp.c_str()); cnt++; } pm_strcat(cfg_str, res_names.c_str()); pm_strcat(cfg_str, "\n"); } break; } case CFG_TYPE_RES: { RES *res; res = (RES *)*(items[i].value); if (res != NULL && res->name != NULL) { Mmsg(temp, "%s = \"%s\"\n", items[i].name, res->name); indent_config_item(cfg_str, 1, temp.c_str()); } break; } case CFG_TYPE_BIT: if (*(items[i].ui32value) & items[i].code) { Mmsg(temp, "%s = %s\n", items[i].name, NT_("yes")); } else { Mmsg(temp, "%s = %s\n", items[i].name, NT_("no")); } indent_config_item(cfg_str, 1, temp.c_str()); break; case CFG_TYPE_MSGS: /* * We ignore these items as they are printed in a special way in MSGSRES::print_config() */ break; case CFG_TYPE_ADDRESSES: { dlist *addrs = *items[i].dlistvalue; IPADDR *adr; Mmsg(temp, "%s = {\n", items[i].name); indent_config_item(cfg_str, 1, temp.c_str()); foreach_dlist(adr, addrs) { char tmp[1024]; adr->build_config_str(tmp, sizeof(tmp)); pm_strcat(cfg_str, tmp); pm_strcat(cfg_str, "\n"); } indent_config_item(cfg_str, 1, "}\n"); break; } case CFG_TYPE_ADDRESSES_PORT: /* * Is stored in CFG_TYPE_ADDRESSES and printed there. */ break; case CFG_TYPE_ADDRESSES_ADDRESS: /* * Is stored in CFG_TYPE_ADDRESSES and printed there. */ break; default: /* * This is a non-generic type call back to the daemon to get things printed. */ if (my_config->m_print_res) { my_config->m_print_res(items, i, cfg_str, hide_sensitive_data); } break; } } pm_strcat(cfg_str, "}\n\n"); pm_strcat(buff, cfg_str.c_str()); return true; } static void add_indent(POOL_MEM &cfg_str, int level) { for (int i = 0; i < level; i++) { pm_strcat(cfg_str, DEFAULT_INDENT_STRING); } } void add_json_pair_plain(POOL_MEM &cfg_str, int level, const char *string, const char *value) { POOL_MEM temp; add_indent(cfg_str, level); Mmsg(temp, "\"%s\": %s,\n", string, value); pm_strcat(cfg_str, temp.c_str()); } void add_json_pair(POOL_MEM &cfg_str, int level, const char *string, const char *value) { POOL_MEM temp; Mmsg(temp, "\"%s\"", value); add_json_pair_plain(cfg_str, level, string, temp.c_str()); } void add_json_pair(POOL_MEM &cfg_str, int level, const char *string, int value) { POOL_MEM temp; Mmsg(temp, "%d", value); add_json_pair_plain(cfg_str, level, string, temp.c_str()); } void add_json_object_start(POOL_MEM &cfg_str, int level, const char *string) { add_indent(cfg_str, level); POOL_MEM temp; if (bstrcmp(string, "")) { Mmsg(temp, "{\n"); } else { Mmsg(temp, "\"%s\": {\n", string); } pm_strcat(cfg_str, temp.c_str()); } void add_json_object_end(POOL_MEM &cfg_str, int level, const char *string) { add_indent(cfg_str, level + 1); pm_strcat(cfg_str, "\"\": null\n"); add_indent(cfg_str, level); if (bstrcmp(string, "")) { pm_strcat(cfg_str, "}\n"); } else { pm_strcat(cfg_str, "},\n"); } } /* * prints a resource item schema description in JSON format. * Example output: * * "filesetacl": { * "datatype": "BOOLEAN", * "datatype_number": 51, * "code": int * [ "defaultvalue": "xyz", ] * [ "required": true, ] * [ "alias": true, ] * [ "deprecated": true, ] * [ "equals": true, ] * ... * } */ bool print_res_item_schema_json(POOL_MEM &buff, int level, RES_ITEM *item) { add_json_object_start(buff, level, item->name); add_json_pair(buff, level + 1, "datatype", datatype_to_str(item->type)); add_json_pair(buff, level + 1, "datatype_number", item->type); add_json_pair(buff, level + 1, "code", item->code); if (item->flags & CFG_ITEM_ALIAS) { add_json_pair(buff, level + 1, "alias", "true"); } if (item->flags & CFG_ITEM_DEFAULT) { add_json_pair(buff, level + 1, "default_value", item->default_value); } if (item->flags & CFG_ITEM_PLATFORM_SPECIFIC) { add_json_pair(buff, level + 1, "platform_specific", "true"); } if (item->flags & CFG_ITEM_DEPRECATED) { add_json_pair_plain(buff, level + 1, "deprecated", "true"); } if (item->flags & CFG_ITEM_NO_EQUALS) { add_json_pair_plain(buff, level + 1, "equals", "false"); } else { add_json_pair_plain(buff, level + 1, "equals", "true"); } if (item->flags & CFG_ITEM_REQUIRED) { add_json_pair_plain(buff, level + 1, "required", "true"); } add_json_object_end(buff, level, item->name); return true; } /* * Print configuration file schema in json format */ bool print_config_schema_json(POOL_MEM &buffer) { RES_TABLE *resources = my_config->m_resources; add_json_object_start(buffer, 0, ""); for (int r = 0; resources[r].name; r++) { RES_TABLE resource = my_config->m_resources[r]; add_json_object_start(buffer, 1, resource.name); if (resource.items) { RES_ITEM* items = resource.items; for (int i = 0; items[i].name; i++) { print_res_item_schema_json(buffer, 2, &items[i]); } } add_json_object_end(buffer, 1, resource.name); } add_json_object_end(buffer, 0, ""); return true; } static DATATYPE_NAME datatype_names[] = { /* * Standard resource types. handlers in res.c */ { CFG_TYPE_STR, "STRING", "String" }, { CFG_TYPE_DIR, "DIRECTORY", "directory" }, { CFG_TYPE_MD5PASSWORD, "MD5PASSWORD", "Password in MD5 format" }, { CFG_TYPE_CLEARPASSWORD, "CLEARPASSWORD", "Password as cleartext" }, { CFG_TYPE_AUTOPASSWORD, "AUTOPASSWORD", "Password stored in clear when needed otherwise hashed" }, { CFG_TYPE_NAME, "NAME", "Name" }, { CFG_TYPE_STRNAME, "STRNAME", "String name" }, { CFG_TYPE_RES, "RES", "Resource" }, { CFG_TYPE_ALIST_RES, "RESOURCE_LIST", "Resource list" }, { CFG_TYPE_ALIST_STR, "STRING_LIST", "string list" }, { CFG_TYPE_ALIST_DIR, "DIRECTORY_LIST", "directory list" }, { CFG_TYPE_INT32, "INT32", "Integer 32 bits" }, { CFG_TYPE_PINT32, "PINT32", "Positive 32 bits Integer (unsigned)" }, { CFG_TYPE_MSGS, "MESSAGES", "Message resource" }, { CFG_TYPE_INT64, "INT64", "Integer 64 bits" }, { CFG_TYPE_BIT, "BIT", "Bitfield" }, { CFG_TYPE_BOOL, "BOOLEAN", "boolean" }, { CFG_TYPE_TIME, "TIME", "time" }, { CFG_TYPE_SIZE64, "SIZE64", "64 bits file size" }, { CFG_TYPE_SIZE32, "SIZE32", "32 bits file size" }, { CFG_TYPE_SPEED, "SPEED", "speed" }, { CFG_TYPE_DEFS, "DEFS", "definition" }, { CFG_TYPE_LABEL, "LABEL", "label" }, { CFG_TYPE_ADDRESSES, "ADDRESSES", "ip addresses list" }, { CFG_TYPE_ADDRESSES_ADDRESS, "ADDRESS", "ip address" }, { CFG_TYPE_ADDRESSES_PORT, "PORT", "network port" }, { CFG_TYPE_PLUGIN_NAMES, "PLUGIN_NAMES", "Plugin Name(s)" }, /* * Director resource types. handlers in dird_conf. */ { CFG_TYPE_ACL, "ACL", "User Access Control List" }, { CFG_TYPE_AUDIT, "AUDIT_COMMAND_LIST", "Auditing Command List" }, { CFG_TYPE_AUTHPROTOCOLTYPE, "AUTH_PROTOCOL_TYPE", "Authentication Protocol" }, { CFG_TYPE_AUTHTYPE, "AUTH_TYPE", "Authentication Type" }, { CFG_TYPE_DEVICE, "DEVICE", "Device resource" }, { CFG_TYPE_JOBTYPE, "JOB_TYPE", "Type of Job" }, { CFG_TYPE_PROTOCOLTYPE, "PROTOCOL_TYPE", "Protocol" }, { CFG_TYPE_LEVEL, "BACKUP_LEVEL", "Backup Level" }, { CFG_TYPE_REPLACE, "REPLACE_OPTION", "Replace option" }, { CFG_TYPE_SHRTRUNSCRIPT, "RUNSCRIPT_SHORT", "Short Runscript definition" }, { CFG_TYPE_RUNSCRIPT, "RUNSCRIPT", "Runscript" }, { CFG_TYPE_RUNSCRIPT_CMD, "RUNSCRIPT_COMMAND", "Runscript Command" }, { CFG_TYPE_RUNSCRIPT_TARGET, "RUNSCRIPT_TARGET", "Runscript Target (Host)" }, { CFG_TYPE_RUNSCRIPT_BOOL, "RUNSCRIPT_BOOLEAN", "Runscript Boolean" }, { CFG_TYPE_RUNSCRIPT_WHEN, "RUNSCRIPT_WHEN", "Runscript When expression" }, { CFG_TYPE_MIGTYPE, "MIGRATION_TYPE", "Migration Type" }, { CFG_TYPE_INCEXC, "INCLUDE_EXCLUDE_ITEM", "Include/Exclude item" }, { CFG_TYPE_RUN, "SCHEDULE_RUN_COMMAND", "Schedule Run Command" }, { CFG_TYPE_ACTIONONPURGE, "ACTION_ON_PURGE", "Action to perform on Purge" }, /* * Director fileset options. handlers in dird_conf. */ { CFG_TYPE_FNAME, "FILENAME", "Filename" }, { CFG_TYPE_PLUGINNAME, "PLUGIN_NAME", "Pluginname" }, { CFG_TYPE_EXCLUDEDIR, "EXCLUDE_DIRECTORY", "Exclude directory" }, { CFG_TYPE_OPTIONS, "OPTIONS", "Options block" }, { CFG_TYPE_OPTION, "OPTION", "Option of Options block" }, { CFG_TYPE_REGEX, "REGEX", "Regular Expression" }, { CFG_TYPE_BASE, "BASEJOB", "Basejob Expression" }, { CFG_TYPE_WILD, "WILDCARD", "Wildcard Expression" }, { CFG_TYPE_PLUGIN, "PLUGIN", "Plugin definition" }, { CFG_TYPE_FSTYPE, "FILESYSTEM_TYPE", "FileSytem match criterium (UNIX)" }, { CFG_TYPE_DRIVETYPE, "DRIVE_TYPE", "DriveType match criterium (Windows)" }, { CFG_TYPE_META, "META_TAG", "Meta tag" }, /* * Storage daemon resource types */ { CFG_TYPE_DEVTYPE, "DEVICE_TYPE", "Device Type" }, { CFG_TYPE_MAXBLOCKSIZE, "MAX_BLOCKSIZE", "Maximum Blocksize" }, { CFG_TYPE_IODIRECTION, "IO_DIRECTION", "IO Direction" }, { CFG_TYPE_CMPRSALGO, "COMPRESSION_ALGORITHM", "Compression Algorithm" }, /* * File daemon resource types */ { CFG_TYPE_CIPHER, "ENCRYPTION_CIPHER", "Encryption Cipher" }, { 0, NULL, NULL } }; static const char *datatype_to_str(int type) { for (int i=0; datatype_names[i].name; i++) { if (datatype_names[i].number == type) { return datatype_names[i].name; } } return "unknown"; } bareos-Release-14.2.6/src/lib/runscript.c000066400000000000000000000230641263011562700201770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Manipulation routines for RunScript list * * Eric Bollengier, May 2006 */ #include "bareos.h" #include "jcr.h" #include "runscript.h" /* * This function pointer is set only by the Director (dird.c), * and is not set in the File daemon, because the File * daemon cannot run console commands. */ bool (*console_command)(JCR *jcr, const char *cmd) = NULL; RUNSCRIPT *new_runscript() { Dmsg0(500, "runscript: creating new RUNSCRIPT object\n"); RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT)); memset(cmd, 0, sizeof(RUNSCRIPT)); cmd->reset_default(); return cmd; } void RUNSCRIPT::reset_default(bool free_strings) { if (free_strings && command) { free_pool_memory(command); } if (free_strings && target) { free_pool_memory(target); } target = NULL; command = NULL; on_success = true; on_failure = false; fail_on_error = true; when = SCRIPT_Never; job_code_callback = NULL; } RUNSCRIPT *copy_runscript(RUNSCRIPT *src) { Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n"); RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT)); memcpy(dst, src, sizeof(RUNSCRIPT)); dst->command = NULL; dst->target = NULL; dst->set_command(src->command, src->cmd_type); dst->set_target(src->target); return dst; } void free_runscript(RUNSCRIPT *script) { Dmsg0(500, "runscript: freeing RUNSCRIPT object\n"); if (script->command) { free_pool_memory(script->command); } if (script->target) { free_pool_memory(script->target); } free(script); } static inline bool script_dir_allowed(JCR *jcr, RUNSCRIPT *script, alist *allowed_script_dirs) { char *bp, *allowed_script_dir; bool allowed = false; POOL_MEM script_dir(PM_FNAME); /* * If there is no explicit list of allowed dirs allow any dir. */ if (!allowed_script_dirs) { return true; } /* * Determine the dir the script is in. */ pm_strcpy(script_dir, script->command); if ((bp = strrchr(script_dir.c_str(), '/'))) { *bp = '\0'; } /* * Make sure there are no relative path elements in script dir by which the * user tries to escape the allowed dir checking. For scripts we only allow * absolute paths. */ if (strstr(script_dir.c_str(), "..")) { Dmsg1(200, "script_dir_allowed: relative pathnames not allowed: %s\n", script_dir.c_str()); return false; } /* * Match the path the script is in against the list of allowed script directories. */ foreach_alist(allowed_script_dir, allowed_script_dirs) { if (bstrcasecmp(script_dir.c_str(), allowed_script_dir)) { allowed = true; break; } } Dmsg2(200, "script_dir_allowed: script %s %s allowed by Allowed Script Dir setting", script->command, (allowed) ? "" : "NOT"); return allowed; } int run_scripts(JCR *jcr, alist *runscripts, const char *label, alist *allowed_script_dirs) { RUNSCRIPT *script; bool runit; int when; Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus); if (strstr(label, NT_("Before"))) { when = SCRIPT_Before; } else if (bstrcmp(label, NT_("ClientAfterVSS"))) { when = SCRIPT_AfterVSS; } else { when = SCRIPT_After; } if (runscripts == NULL) { Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n"); return 0; } foreach_alist(script, runscripts) { Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command)); runit = false; if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) { if ((script->on_success && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created)) || (script->on_failure && (job_canceled(jcr) || jcr->JobStatus == JS_Differences))) { Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", script->command, script->on_success, script->on_failure, jcr->JobStatus ); runit = true; } } if ((script->when & SCRIPT_AfterVSS) && (when & SCRIPT_AfterVSS)) { if ((script->on_success && (jcr->JobStatus == JS_Blocked)) || (script->on_failure && job_canceled(jcr))) { Dmsg4(200, "runscript: Run it because SCRIPT_AfterVSS (%s,%i,%i,%c)\n", script->command, script->on_success, script->on_failure, jcr->JobStatus ); runit = true; } } if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) { if ((script->on_success && jcr->is_terminated_ok()) || (script->on_failure && (job_canceled(jcr) || jcr->JobStatus == JS_Differences))) { Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", script->command, script->on_success, script->on_failure, jcr->JobStatus ); runit = true; } } if (!script->is_local()) { runit = false; } /* * We execute it */ if (runit) { if (!script_dir_allowed(jcr, script, allowed_script_dirs)) { Dmsg1(200, "runscript: Not running script %s because its not in one of the allowed scripts dirs\n", script->command); Jmsg(jcr, M_ERROR, 0, _("Runscript: run %s \"%s\" could not execute, " "not in one of the allowed scripts dirs\n"), label, script->command); jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } script->run(jcr, label); } } bail_out: return 1; } bool RUNSCRIPT::is_local() { if (!target || bstrcmp(target, "")) { return true; } else { return false; } } /* set this->command to cmd */ void RUNSCRIPT::set_command(const char *cmd, int acmd_type) { Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd)); if (!cmd) { return; } if (!command) { command = get_pool_memory(PM_FNAME); } pm_strcpy(command, cmd); cmd_type = acmd_type; } /* set this->target to client_name */ void RUNSCRIPT::set_target(const char *client_name) { Dmsg1(500, "runscript: setting target = %s\n", NPRT(client_name)); if (!client_name) { return; } if (!target) { target = get_pool_memory(PM_FNAME); } pm_strcpy(target, client_name); } bool RUNSCRIPT::run(JCR *jcr, const char *name) { Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type); POOLMEM *ecmd = get_pool_memory(PM_FNAME); int status; BPIPE *bpipe; POOL_MEM line(PM_NAME); ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback); Dmsg1(100, "runscript: running '%s'...\n", ecmd); Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd); switch (cmd_type) { case SHELL_CMD: bpipe = open_bpipe(ecmd, 0, "r"); free_pool_memory(ecmd); if (bpipe == NULL) { berrno be; Jmsg(jcr, M_ERROR, 0, _("Runscript: %s could not execute. ERR=%s\n"), name, be.bstrerror()); goto bail_out; } while (fgets(line.c_str(), line.size(), bpipe->rfd)) { strip_trailing_junk(line.c_str()); Jmsg(jcr, M_INFO, 0, _("%s: %s\n"), name, line.c_str()); } status = close_bpipe(bpipe); if (status != 0) { berrno be; Jmsg(jcr, M_ERROR, 0, _("Runscript: %s returned non-zero status=%d. ERR=%s\n"), name, be.code(status), be.bstrerror(status)); goto bail_out; } Dmsg0(100, "runscript OK\n"); break; case CONSOLE_CMD: if (console_command) { /* can we run console command? */ if (!console_command(jcr, ecmd)) { /* yes, do so */ goto bail_out; } } break; } return true; bail_out: /* cancel running job properly */ if (fail_on_error) { jcr->setJobStatus(JS_ErrorTerminated); } Dmsg1(100, "runscript failed. fail_on_error=%d\n", fail_on_error); return false; } void free_runscripts(alist *runscripts) { Dmsg0(500, "runscript: freeing all RUNSCRIPTS object\n"); RUNSCRIPT *elt; foreach_alist(elt, runscripts) { free_runscript(elt); } } void RUNSCRIPT::debug() { Dmsg0(200, "runscript: debug\n"); Dmsg0(200, _(" --> RunScript\n")); Dmsg1(200, _(" --> Command=%s\n"), NPRT(command)); Dmsg1(200, _(" --> Target=%s\n"), NPRT(target)); Dmsg1(200, _(" --> RunOnSuccess=%u\n"), on_success); Dmsg1(200, _(" --> RunOnFailure=%u\n"), on_failure); Dmsg1(200, _(" --> FailJobOnError=%u\n"), fail_on_error); Dmsg1(200, _(" --> RunWhen=%u\n"), when); } void RUNSCRIPT::set_job_code_callback(job_code_callback_t arg_job_code_callback) { this->job_code_callback = arg_job_code_callback; } bareos-Release-14.2.6/src/lib/runscript.h000066400000000000000000000072171263011562700202060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS RUNSCRIPT Structure definition for FileDaemon and Director * * Eric Bollengier May 2006 */ #ifndef __RUNSCRIPT_H_ #define __RUNSCRIPT_H_ 1 #include "protos.h" /* Usage: * * #define USE_RUNSCRIPT * #include "lib/runscript.h" * * RUNSCRIPT *script = new_runscript(); * script->set_command("/bin/sleep 20"); * script->on_failure = true; * script->when = SCRIPT_After; * * script->run("LabelBefore"); // the label must contain "Before" or "After" special keyword * free_runscript(script); */ /* * RUNSCRIPT->when can take following bit values: */ enum { SCRIPT_Never = 0, SCRIPT_After = (1<<0), /* AfterJob */ SCRIPT_Before = (1<<1), /* BeforeJob */ SCRIPT_AfterVSS = (1<<2), /* BeforeJob and After VSS */ SCRIPT_Any = SCRIPT_Before | SCRIPT_After }; enum { SHELL_CMD = '|', CONSOLE_CMD = '@' }; /* * Structure for RunScript ressource */ class RUNSCRIPT { public: POOLMEM *command; /* Command string */ POOLMEM *target; /* Host target */ int when; /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/ int cmd_type; /* Command type -- Shell, Console */ char level; /* Base|Full|Incr...|All (NYI) */ bool short_form; /* Run Script in short form */ bool from_jobdef; /* This RUN script comes from JobDef */ bool on_success; /* Execute command on job success (After) */ bool on_failure; /* Execute command on job failure (After) */ bool fail_on_error; /* Abort job on error (Before) */ job_code_callback_t job_code_callback; /* Optional callback function passed to edit_job_code */ alist *commands; /* Use during parsing */ bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */ bool can_run_at_level(int JobLevel) { return true;}; /* TODO */ void set_command(const char *cmd, int cmd_type = SHELL_CMD); void set_target(const char *client_name); void reset_default(bool free_string = false); bool is_local(); /* True if running on local host */ void debug(); void set_job_code_callback(job_code_callback_t job_code_callback); }; /* create new RUNSCRIPT (set all value to 0) */ RUNSCRIPT *new_runscript(); /* create new RUNSCRIPT from an other */ RUNSCRIPT *copy_runscript(RUNSCRIPT *src); /* launch each script from runscripts*/ int run_scripts(JCR *jcr, alist *runscripts, const char *name, alist *allowed_script_dirs = NULL); /* free RUNSCRIPT (and all POOLMEM) */ void free_runscript(RUNSCRIPT *script); /* foreach_alist free RUNSCRIPT */ void free_runscripts(alist *runscripts); /* you have to free alist */ extern DLL_IMP_EXP bool (*console_command)(JCR *jcr, const char *cmd); #endif /* __RUNSCRIPT_H_ */ bareos-Release-14.2.6/src/lib/rwlock.c000066400000000000000000000442341263011562700174510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Thread Read/Write locking code. It permits * multiple readers but only one writer. Note, however, * that the writer thread is permitted to make multiple * nested write lock calls. * * Kern Sibbald, January MMI * * This code adapted from "Programming with POSIX Threads", by David R. Butenhof */ #define _LOCKMGR_COMPLIANT #include "bareos.h" /* * Initialize a read/write lock * * Returns: 0 on success * errno on failure */ int rwl_init(brwlock_t *rwl, int priority) { int status; rwl->r_active = rwl->w_active = 0; rwl->r_wait = rwl->w_wait = 0; rwl->priority = priority; if ((status = pthread_mutex_init(&rwl->mutex, NULL)) != 0) { return status; } if ((status = pthread_cond_init(&rwl->read, NULL)) != 0) { pthread_mutex_destroy(&rwl->mutex); return status; } if ((status = pthread_cond_init(&rwl->write, NULL)) != 0) { pthread_cond_destroy(&rwl->read); pthread_mutex_destroy(&rwl->mutex); return status; } rwl->valid = RWLOCK_VALID; return 0; } /* * Destroy a read/write lock * * Returns: 0 on success * errno on failure */ int rwl_destroy(brwlock_t *rwl) { int status, status1, status2; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } /* * If any threads are active, report EBUSY */ if (rwl->r_active > 0 || rwl->w_active) { pthread_mutex_unlock(&rwl->mutex); return EBUSY; } /* * If any threads are waiting, report EBUSY */ if (rwl->r_wait > 0 || rwl->w_wait > 0) { pthread_mutex_unlock(&rwl->mutex); return EBUSY; } rwl->valid = 0; if ((status = pthread_mutex_unlock(&rwl->mutex)) != 0) { return status; } status = pthread_mutex_destroy(&rwl->mutex); status1 = pthread_cond_destroy(&rwl->read); status2 = pthread_cond_destroy(&rwl->write); return (status != 0 ? status : (status1 != 0 ? status1 : status2)); } bool rwl_is_init(brwlock_t *rwl) { return (rwl->valid == RWLOCK_VALID); } /* * Handle cleanup when the read lock condition variable * wait is released. */ static void rwl_read_release(void *arg) { brwlock_t *rwl = (brwlock_t *)arg; rwl->r_wait--; pthread_mutex_unlock(&rwl->mutex); } /* * Handle cleanup when the write lock condition variable wait * is released. */ static void rwl_write_release(void *arg) { brwlock_t *rwl = (brwlock_t *)arg; rwl->w_wait--; pthread_mutex_unlock(&rwl->mutex); } /* * Lock for read access, wait until locked (or error). */ int rwl_readlock(brwlock_t *rwl) { int status; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active) { rwl->r_wait++; /* indicate that we are waiting */ pthread_cleanup_push(rwl_read_release, (void *)rwl); while (rwl->w_active) { status = pthread_cond_wait(&rwl->read, &rwl->mutex); if (status != 0) { break; /* error, bail out */ } } pthread_cleanup_pop(0); rwl->r_wait--; /* we are no longer waiting */ } if (status == 0) { rwl->r_active++; /* we are running */ } pthread_mutex_unlock(&rwl->mutex); return status; } /* * Attempt to lock for read access, don't wait */ int rwl_readtrylock(brwlock_t *rwl) { int status, status2; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active) { status = EBUSY; } else { rwl->r_active++; /* we are running */ } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } /* * Unlock read lock */ int rwl_readunlock(brwlock_t *rwl) { int status, status2; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } rwl->r_active--; if (rwl->r_active == 0 && rwl->w_wait > 0) { /* if writers waiting */ status = pthread_cond_broadcast(&rwl->write); } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } /* * Lock for write access, wait until locked (or error). * Multiple nested write locking is permitted. */ int rwl_writelock_p(brwlock_t *rwl, const char *file, int line) { int status; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active && pthread_equal(rwl->writer_id, pthread_self())) { rwl->w_active++; pthread_mutex_unlock(&rwl->mutex); return 0; } lmgr_pre_lock(rwl, rwl->priority, file, line); if (rwl->w_active || rwl->r_active > 0) { rwl->w_wait++; /* indicate that we are waiting */ pthread_cleanup_push(rwl_write_release, (void *)rwl); while (rwl->w_active || rwl->r_active > 0) { if ((status = pthread_cond_wait(&rwl->write, &rwl->mutex)) != 0) { lmgr_do_unlock(rwl); break; /* error, bail out */ } } pthread_cleanup_pop(0); rwl->w_wait--; /* we are no longer waiting */ } if (status == 0) { rwl->w_active++; /* we are running */ rwl->writer_id = pthread_self(); /* save writer thread's id */ lmgr_post_lock(); } pthread_mutex_unlock(&rwl->mutex); return status; } /* * Attempt to lock for write access, don't wait */ int rwl_writetrylock(brwlock_t *rwl) { int status, status2; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active && pthread_equal(rwl->writer_id, pthread_self())) { rwl->w_active++; pthread_mutex_unlock(&rwl->mutex); return 0; } if (rwl->w_active || rwl->r_active > 0) { status = EBUSY; } else { rwl->w_active = 1; /* we are running */ rwl->writer_id = pthread_self(); /* save writer thread's id */ lmgr_do_lock(rwl, rwl->priority, __FILE__, __LINE__); } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } /* * Unlock write lock * Start any waiting writers in preference to waiting readers */ int rwl_writeunlock(brwlock_t *rwl) { int status, status2; if (rwl->valid != RWLOCK_VALID) { return EINVAL; } if ((status = pthread_mutex_lock(&rwl->mutex)) != 0) { return status; } if (rwl->w_active <= 0) { pthread_mutex_unlock(&rwl->mutex); Jmsg0(NULL, M_ABORT, 0, _("rwl_writeunlock called too many times.\n")); } rwl->w_active--; if (!pthread_equal(pthread_self(), rwl->writer_id)) { pthread_mutex_unlock(&rwl->mutex); Jmsg0(NULL, M_ABORT, 0, _("rwl_writeunlock by non-owner.\n")); } if (rwl->w_active > 0) { status = 0; /* writers still active */ } else { lmgr_do_unlock(rwl); /* No more writers, awaken someone */ if (rwl->r_wait > 0) { /* if readers waiting */ status = pthread_cond_broadcast(&rwl->read); } else if (rwl->w_wait > 0) { status = pthread_cond_broadcast(&rwl->write); } } status2 = pthread_mutex_unlock(&rwl->mutex); return (status == 0 ? status2 : status); } #ifdef TEST_RWLOCK #define THREADS 300 #define DATASIZE 15 #define ITERATIONS 1000000 /* * Keep statics for each thread. */ typedef struct thread_tag { int thread_num; pthread_t thread_id; int writes; int reads; int interval; } thread_t; /* * Read/write lock and shared data. */ typedef struct data_tag { brwlock_t lock; int data; int writes; } data_t; static thread_t threads[THREADS]; static data_t data[DATASIZE]; /* * Thread start routine that uses read/write locks. */ void *thread_routine(void *arg) { thread_t *self = (thread_t *)arg; int repeats = 0; int iteration; int element = 0; int status; for (iteration=0; iteration < ITERATIONS; iteration++) { /* * Each "self->interval" iterations, perform an * update operation (write lock instead of read * lock). */ // if ((iteration % self->interval) == 0) { status = rwl_writelock(&data[element].lock); if (status != 0) { berrno be; printf("Write lock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } data[element].data = self->thread_num; data[element].writes++; self->writes++; status = rwl_writelock(&data[element].lock); if (status != 0) { berrno be; printf("Write lock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } data[element].data = self->thread_num; data[element].writes++; self->writes++; status = rwl_writeunlock(&data[element].lock); if (status != 0) { berrno be; printf("Write unlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } status = rwl_writeunlock(&data[element].lock); if (status != 0) { berrno be; printf("Write unlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } #ifdef xxx } else { /* * Look at the current data element to see whether * the current thread last updated it. Count the * times to report later. */ status = rwl_readlock(&data[element].lock); if (status != 0) { berrno be; printf("Read lock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } self->reads++; if (data[element].data == self->thread_num) repeats++; status = rwl_readunlock(&data[element].lock); if (status != 0) { berrno be; printf("Read unlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } } #endif element++; if (element >= DATASIZE) { element = 0; } } if (repeats > 0) { Pmsg2(000, _("Thread %d found unchanged elements %d times\n"), self->thread_num, repeats); } return NULL; } int main (int argc, char *argv[]) { int count; int data_count; int status; unsigned int seed = 1; int thread_writes = 0; int data_writes = 0; #ifdef USE_THR_SETCONCURRENCY /* * On Solaris 2.5,2.6,7 and 8 threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to THREADS. */ thr_setconcurrency (THREADS); #endif /* * Initialize the shared data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data[data_count].data = 0; data[data_count].writes = 0; status = rwl_init(&data[data_count].lock); if (status != 0) { berrno be; printf("Init rwlock failed. ERR=%s\n", be.bstrerror(status)); exit(1); } } /* * Create THREADS threads to access shared data. */ for (count = 0; count < THREADS; count++) { threads[count].thread_num = count + 1; threads[count].writes = 0; threads[count].reads = 0; threads[count].interval = rand_r(&seed) % 71; if (threads[count].interval <= 0) { threads[count].interval = 1; } status = pthread_create (&threads[count].thread_id, NULL, thread_routine, (void*)&threads[count]); if (status != 0 || (int)threads[count].thread_id == 0) { berrno be; printf("Create thread failed. ERR=%s\n", be.bstrerror(status)); exit(1); } } /* * Wait for all threads to complete, and collect * statistics. */ for (count = 0; count < THREADS; count++) { status = pthread_join (threads[count].thread_id, NULL); if (status != 0) { berrno be; printf("Join thread failed. ERR=%s\n", be.bstrerror(status)); exit(1); } thread_writes += threads[count].writes; printf (_("%02d: interval %d, writes %d, reads %d\n"), count, threads[count].interval, threads[count].writes, threads[count].reads); } /* * Collect statistics for the data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data_writes += data[data_count].writes; printf (_("data %02d: value %d, %d writes\n"), data_count, data[data_count].data, data[data_count].writes); rwl_destroy (&data[data_count].lock); } printf (_("Total: %d thread writes, %d data writes\n"), thread_writes, data_writes); return 0; } #endif #ifdef TEST_RW_TRY_LOCK /* * brwlock_try_main.c * * Demonstrate use of non-blocking read-write locks. * * Special notes: On older Solaris system, call thr_setconcurrency() * to allow interleaved thread execution, since threads are not * timesliced. */ #include #include "rwlock.h" #include "errors.h" #define THREADS 5 #define ITERATIONS 1000 #define DATASIZE 15 /* * Keep statistics for each thread. */ typedef struct thread_tag { int thread_num; pthread_t thread_id; int r_collisions; int w_collisions; int updates; int interval; } thread_t; /* * Read-write lock and shared data */ typedef struct data_tag { brwlock_t lock; int data; int updates; } data_t; thread_t threads[THREADS]; data_t data[DATASIZE]; /* * Thread start routine that uses read-write locks */ void *thread_routine (void *arg) { thread_t *self = (thread_t*)arg; int iteration; int element; int status; lmgr_init_thread(); element = 0; /* Current data element */ for (iteration = 0; iteration < ITERATIONS; iteration++) { if ((iteration % self->interval) == 0) { status = rwl_writetrylock (&data[element].lock); if (status == EBUSY) self->w_collisions++; else if (status == 0) { data[element].data++; data[element].updates++; self->updates++; rwl_writeunlock (&data[element].lock); } else err_abort (status, _("Try write lock")); } else { status = rwl_readtrylock (&data[element].lock); if (status == EBUSY) self->r_collisions++; else if (status != 0) { err_abort (status, _("Try read lock")); } else { if (data[element].data != data[element].updates) printf ("%d: data[%d] %d != %d\n", self->thread_num, element, data[element].data, data[element].updates); rwl_readunlock (&data[element].lock); } } element++; if (element >= DATASIZE) element = 0; } lmgr_cleanup_thread(); return NULL; } int main (int argc, char *argv[]) { int count, data_count; unsigned int seed = 1; int thread_updates = 0, data_updates = 0; int status; #ifdef USE_THR_SETCONCURRENCY /* * On Solaris 2.5,2.6,7 and 8 threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to THREADS. */ DPRINTF (("Setting concurrency level to %d\n", THREADS)); thr_setconcurrency (THREADS); #endif /* * Initialize the shared data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data[data_count].data = 0; data[data_count].updates = 0; rwl_init(&data[data_count].lock); } /* * Create THREADS threads to access shared data. */ for (count = 0; count < THREADS; count++) { threads[count].thread_num = count; threads[count].r_collisions = 0; threads[count].w_collisions = 0; threads[count].updates = 0; threads[count].interval = rand_r (&seed) % ITERATIONS; status = pthread_create (&threads[count].thread_id, NULL, thread_routine, (void*)&threads[count]); if (status != 0) err_abort (status, _("Create thread")); } /* * Wait for all threads to complete, and collect * statistics. */ for (count = 0; count < THREADS; count++) { status = pthread_join (threads[count].thread_id, NULL); if (status != 0) err_abort (status, _("Join thread")); thread_updates += threads[count].updates; printf (_("%02d: interval %d, updates %d, " "r_collisions %d, w_collisions %d\n"), count, threads[count].interval, threads[count].updates, threads[count].r_collisions, threads[count].w_collisions); } /* * Collect statistics for the data. */ for (data_count = 0; data_count < DATASIZE; data_count++) { data_updates += data[data_count].updates; printf (_("data %02d: value %d, %d updates\n"), data_count, data[data_count].data, data[data_count].updates); rwl_destroy (&data[data_count].lock); } return 0; } #endif bareos-Release-14.2.6/src/lib/rwlock.h000066400000000000000000000051471263011562700174560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS Thread Read/Write locking code. It permits * multiple readers but only one writer. * * Kern Sibbald, January MMI * * This code adapted from "Programming with POSIX Threads", by David R. Butenhof */ #ifndef __RWLOCK_H #define __RWLOCK_H 1 typedef struct s_rwlock_tag { pthread_mutex_t mutex; pthread_cond_t read; /* wait for read */ pthread_cond_t write; /* wait for write */ pthread_t writer_id; /* writer's thread id */ int priority; /* used in deadlock detection */ int valid; /* set when valid */ int r_active; /* readers active */ int w_active; /* writers active */ int r_wait; /* readers waiting */ int w_wait; /* writers waiting */ } brwlock_t; typedef struct s_rwsteal_tag { pthread_t writer_id; /* writer's thread id */ int state; } brwsteal_t; #define RWLOCK_VALID 0xfacade #define RWL_INIIALIZER \ { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, \ PTHREAD_COND_INITIALIZER, RWLOCK_VALID, 0, 0, 0, 0 } #define rwl_writelock(x) rwl_writelock_p((x), __FILE__, __LINE__) /* * read/write lock prototypes */ extern int rwl_init(brwlock_t *rwl, int priority = 0); extern int rwl_destroy(brwlock_t *rwl); extern bool rwl_is_init(brwlock_t *rwl); extern int rwl_readlock(brwlock_t *rwl); extern int rwl_readtrylock(brwlock_t *rwl); extern int rwl_readunlock(brwlock_t *rwl); extern int rwl_writelock_p(brwlock_t *rwl, const char *file = "*unknown*", int line = 0); extern int rwl_writetrylock(brwlock_t *rwl); extern int rwl_writeunlock(brwlock_t *rwl); #endif /* __RWLOCK_H */ bareos-Release-14.2.6/src/lib/scan.c000066400000000000000000000377421263011562700171020ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * scan.c -- scanning routines for BAREOS * * Kern Sibbald, MM separated from util.c MMIII */ #include "bareos.h" #include "jcr.h" /* * Strip leading space from command line arguments */ void strip_leading_space(char *str) { char *p = str; while (B_ISSPACE(*p)) { p++; } if (p != str) { bstrinlinecpy(str, p); } } /* * Strip any trailing junk from the command */ void strip_trailing_junk(char *cmd) { char *p; /* * Strip trailing junk from command */ p = cmd + strlen(cmd) - 1; while ((p >= cmd) && (*p == '\n' || *p == '\r' || *p == ' ')) { *p-- = 0; } } /* * Strip any trailing newline characters from the string */ void strip_trailing_newline(char *cmd) { char *p; p = cmd + strlen(cmd) - 1; while ((p >= cmd) && (*p == '\n' || *p == '\r')) { *p-- = 0; } } /* * Strip any trailing slashes from a directory path */ void strip_trailing_slashes(char *dir) { char *p; /* * Strip trailing slashes */ p = dir + strlen(dir) - 1; while (p >= dir && IsPathSeparator(*p)) { *p-- = 0; } } /* * Skip spaces * Returns: 0 on failure (EOF) * 1 on success * new address in passed parameter */ bool skip_spaces(char **msg) { char *p = *msg; if (!p) { return false; } while (*p && B_ISSPACE(*p)) { p++; } *msg = p; return *p ? true : false; } /* * Skip nonspaces * Returns: 0 on failure (EOF) * 1 on success * new address in passed parameter */ bool skip_nonspaces(char **msg) { char *p = *msg; if (!p) { return false; } while (*p && !B_ISSPACE(*p)) { p++; } *msg = p; return *p ? true : false; } /* * Folded search for string - case insensitive */ int fstrsch(const char *a, const char *b) /* folded case search */ { const char *s1,*s2; char c1, c2; s1=a; s2=b; while (*s1) { /* do it the fast way */ if ((*s1++ | 0x20) != (*s2++ | 0x20)) return 0; /* failed */ } while (*a) { /* do it over the correct slow way */ if (B_ISUPPER(c1 = *a)) { c1 = tolower((int)c1); } if (B_ISUPPER(c2 = *b)) { c2 = tolower((int)c2); } if (c1 != c2) { return 0; } a++; b++; } return 1; } /* * Return next argument from command line. Note, this * routine is destructive because it stored 0 at the end * of each argument. * Called with pointer to pointer to command line. This * pointer is updated to point to the remainder of the * command line. * * Returns pointer to next argument -- don't store the result * in the pointer you passed as an argument ... * The next argument is terminated by a space unless within * quotes. Double quote characters (unless preceded by a \) are * stripped. * */ char *next_arg(char **s) { char *p, *q, *n; bool in_quote = false; /* skip past spaces to next arg */ for (p=*s; *p && B_ISSPACE(*p); ) { p++; } Dmsg1(900, "Next arg=%s\n", p); for (n = q = p; *p ; ) { if (*p == '\\') { /* slash? */ p++; /* yes, skip it */ if (*p) { *q++ = *p++; } else { *q++ = *p; } continue; } if (*p == '"') { /* start or end of quote */ p++; in_quote = !in_quote; /* change state */ continue; } if (!in_quote && B_ISSPACE(*p)) { /* end of field */ p++; break; } *q++ = *p++; } *q = 0; *s = p; Dmsg2(900, "End arg=%s next=%s\n", n, p); return n; } /* * This routine parses the input command line. * It makes a copy in args, then builds an * argc, argk, argv list where: * * argc = count of arguments * argk[i] = argument keyword (part preceding =) * argv[i] = argument value (part after =) * * example: arg1 arg2=abc arg3= * * argc = c * argk[0] = arg1 * argv[0] = NULL * argk[1] = arg2 * argv[1] = abc * argk[2] = arg3 * argv[2] = */ int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, char **argk, char **argv, int max_args) { char *p; parse_args_only(cmd, args, argc, argk, argv, max_args); /* Separate keyword and value */ for (int i=0; i < *argc; i++) { p = strchr(argk[i], '='); if (p) { *p++ = 0; /* terminate keyword and point to value */ } argv[i] = p; /* save ptr to value or NULL */ } #ifdef xxx_debug for (int i=0; i < *argc; i++) { Pmsg3(000, "Arg %d: kw=%s val=%s\n", i, argk[i], argv[i]?argv[i]:"NULL"); } #endif return 1; } /* * This routine parses the input command line. * It makes a copy in args, then builds an * argc, argk, but no argv (values). * This routine is useful for scanning command lines where the data * is a filename and no keywords are expected. If we scan a filename * for keywords, any = in the filename will be interpreted as the * end of a keyword, and this is not good. * * argc = count of arguments * argk[i] = argument keyword (part preceding =) * argv[i] = NULL * * example: arg1 arg2=abc arg3= * * argc = c * argk[0] = arg1 * argv[0] = NULL * argk[1] = arg2=abc * argv[1] = NULL * argk[2] = arg3 * argv[2] = */ int parse_args_only(POOLMEM *cmd, POOLMEM **args, int *argc, char **argk, char **argv, int max_args) { char *p, *n; pm_strcpy(args, cmd); strip_trailing_junk(*args); p = *args; *argc = 0; /* * Pick up all arguments */ while (*argc < max_args) { n = next_arg(&p); if (*n) { argk[*argc] = n; argv[(*argc)++] = NULL; } else { break; } } return 1; } /* * Given a full filename, split it into its path * and filename parts. They are returned in pool memory * in the arguments provided. */ void split_path_and_filename(const char *fname, POOLMEM **path, int *pnl, POOLMEM **file, int *fnl) { const char *f; int slen; int len = slen = strlen(fname); /* * Find path without the filename. * I.e. everything after the last / is a "filename". * OK, maybe it is a directory name, but we treat it like * a filename. If we don't find a / then the whole name * must be a path name (e.g. c:). */ f = fname + len - 1; /* "strip" any trailing slashes */ while (slen > 1 && IsPathSeparator(*f)) { slen--; f--; } /* Walk back to last slash -- begin of filename */ while (slen > 0 && !IsPathSeparator(*f)) { slen--; f--; } if (IsPathSeparator(*f)) { /* did we find a slash? */ f++; /* yes, point to filename */ } else { /* no, whole thing must be path name */ f = fname; } Dmsg2(200, "after strip len=%d f=%s\n", len, f); *fnl = fname - f + len; if (*fnl > 0) { *file = check_pool_memory_size(*file, *fnl+1); memcpy(*file, f, *fnl); /* copy filename */ } (*file)[*fnl] = 0; *pnl = f - fname; if (*pnl > 0) { *path = check_pool_memory_size(*path, *pnl+1); memcpy(*path, fname, *pnl); } (*path)[*pnl] = 0; Dmsg2(200, "pnl=%d fnl=%d\n", *pnl, *fnl); Dmsg3(200, "split fname=%s path=%s file=%s\n", fname, *path, *file); } /* * Extremely simple sscanf. Handles only %(u,d,ld,qd,qu,lu,lld,llu,c,nns) */ const int BIG = 1000; int bsscanf(const char *buf, const char *fmt, ...) { va_list ap; int count = 0; void *vp; char *cp; int l = 0; int max_len = BIG; uint64_t value; bool error = false; bool negative; va_start(ap, fmt); while (*fmt && !error) { // Dmsg1(000, "fmt=%c\n", *fmt); if (*fmt == '%') { fmt++; // Dmsg1(000, "Got %% nxt=%c\n", *fmt); switch_top: switch (*fmt++) { case 'u': value = 0; while (B_ISDIGIT(*buf)) { value = B_TIMES10(value) + *buf++ - '0'; } vp = (void *)va_arg(ap, void *); // Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp); if (l == 0) { *((int *)vp) = (int)value; } else if (l == 1) { *((uint32_t *)vp) = (uint32_t)value; // Dmsg0(000, "Store 32 bit int\n"); } else { *((uint64_t *)vp) = (uint64_t)value; // Dmsg0(000, "Store 64 bit int\n"); } count++; l = 0; break; case 'd': value = 0; if (*buf == '-') { negative = true; buf++; } else { negative = false; } while (B_ISDIGIT(*buf)) { value = B_TIMES10(value) + *buf++ - '0'; } if (negative) { value = -value; } vp = (void *)va_arg(ap, void *); // Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp); if (l == 0) { *((int *)vp) = (int)value; } else if (l == 1) { *((int32_t *)vp) = (int32_t)value; // Dmsg0(000, "Store 32 bit int\n"); } else { *((int64_t *)vp) = (int64_t)value; // Dmsg0(000, "Store 64 bit int\n"); } count++; l = 0; break; case 'l': // Dmsg0(000, "got l\n"); l = 1; if (*fmt == 'l') { l++; fmt++; } if (*fmt == 'd' || *fmt == 'u') { goto switch_top; } // Dmsg1(000, "fmt=%c !=d,u\n", *fmt); error = true; break; case 'q': l = 2; if (*fmt == 'd' || *fmt == 'u') { goto switch_top; } // Dmsg1(000, "fmt=%c !=d,u\n", *fmt); error = true; break; case 's': // Dmsg1(000, "Store string max_len=%d\n", max_len); cp = (char *)va_arg(ap, char *); while (*buf && !B_ISSPACE(*buf) && max_len-- > 0) { *cp++ = *buf++; } *cp = 0; count++; max_len = BIG; break; case 'c': cp = (char *)va_arg(ap, char *); *cp = *buf++; count++; break; case '%': if (*buf++ != '%') { error = true; } break; default: fmt--; max_len = 0; while (B_ISDIGIT(*fmt)) { max_len = B_TIMES10(max_len) + *fmt++ - '0'; } // Dmsg1(000, "Default max_len=%d\n", max_len); if (*fmt == 's') { goto switch_top; } // Dmsg1(000, "Default c=%c\n", *fmt); error = true; break; /* error: unknown format */ } continue; /* White space eats zero or more whitespace */ } else if (B_ISSPACE(*fmt)) { fmt++; while (B_ISSPACE(*buf)) { buf++; } /* Plain text must match */ } else if (*buf++ != *fmt++) { // Dmsg2(000, "Mismatch buf=%c fmt=%c\n", *--buf, *--fmt); error = true; break; } } va_end(ap); // Dmsg2(000, "Error=%d count=%d\n", error, count); if (error) { count = -1; } return count; } #ifdef TEST_PROGRAM int main(int argc, char *argv[]) { char buf[100]; uint32_t val32; uint64_t val64; uint32_t FirstIndex, LastIndex, StartFile, EndFile, StartBlock, EndBlock; char Job[200]; int cnt; char *helloreq= "Hello *UserAgent* calling\n"; char *hello = "Hello %127s calling\n"; char *catreq = "CatReq Job=NightlySave.2004-06-11_19.11.32 CreateJobMedia FirstIndex=1 LastIndex=114 StartFile=0 EndFile=0 StartBlock=208 EndBlock=2903248"; static char Create_job_media[] = "CatReq Job=%127s CreateJobMedia " "FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u " "StartBlock=%u EndBlock=%u\n"; static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%u" " VolBlocks=%u VolBytes=%" lld " VolMounts=%u VolErrors=%u VolWrites=%u" " MaxVolBytes=%" lld " VolCapacityBytes=%" lld " VolStatus=%20s" " Slot=%d MaxVolJobs=%u MaxVolFiles=%u InChanger=%d" " VolReadTime=%" lld " VolWriteTime=%" lld; char *media = "1000 OK VolName=TestVolume001 VolJobs=0 VolFiles=0 VolBlocks=0 VolBytes=1 VolMounts=0 VolErrors=0 VolWrites=0 MaxVolBytes=0 VolCapacityBytes=0 VolStatus=Append Slot=0 MaxVolJobs=0 MaxVolFiles=0 InChanger=1 VolReadTime=0 VolWriteTime=0"; struct VOLUME_CAT_INFO { /* Media info for the current Volume */ uint32_t VolCatJobs; /* number of jobs on this Volume */ uint32_t VolCatFiles; /* Number of files */ uint32_t VolCatBlocks; /* Number of blocks */ uint64_t VolCatBytes; /* Number of bytes written */ uint32_t VolCatMounts; /* Number of mounts this volume */ uint32_t VolCatErrors; /* Number of errors this volume */ uint32_t VolCatWrites; /* Number of writes this volume */ uint32_t VolCatReads; /* Number of reads this volume */ uint64_t VolCatRBytes; /* Number of bytes read */ uint32_t VolCatRecycles; /* Number of recycles this volume */ int32_t Slot; /* Slot in changer */ bool InChanger; /* Set if vol in current magazine */ uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */ uint32_t VolCatMaxFiles; /* Maximum files to write to volume */ uint64_t VolCatMaxBytes; /* Max bytes to write to volume */ uint64_t VolCatCapacityBytes; /* capacity estimate */ uint64_t VolReadTime; /* time spent reading */ uint64_t VolWriteTime; /* time spent writing this Volume */ uint32_t MinBlocksize; /* Minimum block size */ uint32_t MaxBlocksize; /* Maximum block size */ char VolCatStatus[20]; /* Volume status */ char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */ }; struct VOLUME_CAT_INFO vol; #ifdef xxx bsscanf("Hello_world 123 1234", "%120s %ld %lld", buf, &val32, &val64); printf("%s %d %lld\n", buf, val32, val64); *Job=0; cnt = bsscanf(catreq, Create_job_media, &Job, &FirstIndex, &LastIndex, &StartFile, &EndFile, &StartBlock, &EndBlock); printf("cnt=%d Job=%s\n", cnt, Job); cnt = bsscanf(helloreq, hello, &Job); printf("cnt=%d Agent=%s\n", cnt, Job); #endif cnt = bsscanf(media, OK_media, vol.VolCatName, &vol.VolCatJobs, &vol.VolCatFiles, &vol.VolCatBlocks, &vol.VolCatBytes, &vol.VolCatMounts, &vol.VolCatErrors, &vol.VolCatWrites, &vol.VolCatMaxBytes, &vol.VolCatCapacityBytes, vol.VolCatStatus, &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles, &vol.InChanger, &vol.VolReadTime, &vol.VolWriteTime, &vol.MaxBlocksize, &vol.MinBocksize); printf("cnt=%d Vol=%s\n", cnt, vol.VolCatName); } #endif bareos-Release-14.2.6/src/lib/scsi_crypto.c000066400000000000000000000552271263011562700205150ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Low level SCSI interface for SCSI crypto services * * Marco van Wieringen, March 2012 */ #include "bareos.h" /* Forward referenced functions */ static void indent_status_msg(POOLMEM *&status, const char *msg, int indent); #ifdef HAVE_LOWLEVEL_SCSI_INTERFACE #include "scsi_crypto.h" /* * Store a value as 2 bytes MSB/LSB */ static inline void set_2_byte_value(unsigned char *field, int value) { field[0] = (unsigned char)((value & 0xff00) >> 8); field[1] = (unsigned char)(value & 0x00ff); } /* * Store a value as 4 bytes MSB/LSB */ static inline void set_4_byte_value(unsigned char *field, int value) { field[0] = (unsigned char)((value & 0xff000000) >> 24); field[1] = (unsigned char)((value & 0x00ff0000) >> 16); field[2] = (unsigned char)((value & 0x0000ff00) >> 8); field[3] = (unsigned char)(value & 0x000000ff); } /* * Clear an encryption key used by a tape drive * using a lowlevel SCSI interface. * * The device is send a: * - SPOUT Security Protocol OUT SCSI CDB. (0xB5) * - SPOUT Send Encryption Key Page. (0x10) * * The Send Encryption Key page has the encryption * and decryption set to disabled and the key is empty. */ bool clear_scsi_encryption_key(int fd, const char *device_name) { /* * Create a SPOUT Set Encryption Key CDB and * a SPOUT Clear Encryption Mode Page */ SPP_SCSI_CDB cdb; SPP_PAGE_BUFFER cmd_page; SPP_PAGE_SDE *sps; int cmd_page_len, cdb_len; /* * Put a SPOUT Set Data Encryption page into the start of * the generic cmd_page structure. */ memset(&cmd_page, 0, sizeof(cmd_page)); sps = (SPP_PAGE_SDE *)&cmd_page; set_2_byte_value(sps->pageCode, SPOUT_SET_DATA_ENCRYPTION_PAGE); sps->nexusScope = SPP_NEXUS_SC_ALL_I_T_NEXUS; sps->encryptionMode = SPP_ENCR_MODE_DISABLE; sps->decryptionMode = SPP_DECR_MODE_DISABLE; sps->algorithmIndex = 0x01; sps->kadFormat = SPP_KAD_KEY_FORMAT_NORMAL; set_2_byte_value(sps->keyLength, SPP_KEY_LENGTH); /* * Set the length to the size of the SPP_PAGE_SDE we just filled. */ cmd_page_len = sizeof(SPP_PAGE_SDE); /* * Set the actual size of the cmd_page - 4 into the cmd_page length field * (without the pageCode and pageLength) */ set_2_byte_value(cmd_page.length, cmd_page_len - 4); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_SPOUT_OPCODE; cdb.scp = SPP_SP_PROTOCOL_TDE; set_2_byte_value(cdb.scp_specific, SPOUT_SET_DATA_ENCRYPTION_PAGE); set_4_byte_value(cdb.allocation_length, cmd_page_len); /* * Clear the encryption key. */ return send_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len); } /* * Set an encryption key used by a tape drive * using a lowlevel SCSI interface. * * The device is send a: * - SPOUT Security Protocol OUT SCSI CDB. (0xB5) * - SPOUT Send Encryption Key Page. (0x10) * * The Send Encryption Key page has the encryption * and decryption set to not disabled and the key is filled. */ bool set_scsi_encryption_key(int fd, const char *device_name, char *encryption_key) { /* * Create a SPOUT Set Encryption Key CDB and * a SPOUT Send Encryption Key Page */ SPP_SCSI_CDB cdb; SPP_PAGE_BUFFER cmd_page; SPP_PAGE_SDE *sps; int cmd_page_len, cdb_len; /* * Put a SPOUT Set Data Encryption page into the start of * the generic cmd_page structure. */ memset(&cmd_page, 0, sizeof(cmd_page)); sps = (SPP_PAGE_SDE *)&cmd_page; set_2_byte_value(sps->pageCode, SPOUT_SET_DATA_ENCRYPTION_PAGE); sps->nexusScope = SPP_NEXUS_SC_ALL_I_T_NEXUS; sps->encryptionMode = SPP_ENCR_MODE_ENCRYPT; sps->decryptionMode = SPP_DECR_MODE_MIXED; sps->algorithmIndex = 0x01; sps->kadFormat = SPP_KAD_KEY_FORMAT_NORMAL; set_2_byte_value(sps->keyLength, SPP_KEY_LENGTH); bstrncpy((char *)sps->keyData, encryption_key, SPP_KEY_LENGTH); /* * Set the length to the size of the SPP_PAGE_SDE we just filled. */ cmd_page_len = sizeof(SPP_PAGE_SDE); /* * Set the actual size of the cmd_page - 4 into the cmd_page length field * (without the pageCode and pageLength) */ set_2_byte_value(cmd_page.length, cmd_page_len - 4); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_SPOUT_OPCODE; cdb.scp = SPP_SP_PROTOCOL_TDE; set_2_byte_value(cdb.scp_specific, SPOUT_SET_DATA_ENCRYPTION_PAGE); set_4_byte_value(cdb.allocation_length, cmd_page_len); /* * Set the new encryption key. */ return send_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len); } /* * Request the encryption state of a drive * using a lowlevel SCSI interface. * * The device is send a: * - SPIN Security Protocol IN SCSI CDB. (0xA2) * - SPIN Get Data Encryption Status page. (0x20) * * The return data is interpreted and a status report is build. */ int get_scsi_drive_encryption_status(int fd, const char *device_name, POOLMEM *&status, int indent) { SPP_SCSI_CDB cdb; SPP_PAGE_BUFFER cmd_page; SPP_PAGE_DES *spd; int cmd_page_len, cdb_len; cmd_page_len = sizeof(cmd_page); memset(&cmd_page, 0, cmd_page_len); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_SPIN_OPCODE; cdb.scp = SPP_SP_PROTOCOL_TDE; set_2_byte_value(cdb.scp_specific, SPIN_DATA_ENCR_STATUS_PAGE); set_4_byte_value(cdb.allocation_length, cmd_page_len); /* * Retrieve the drive encryption status. */ if (!recv_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len)) { return 0; } /* * We got a response which should contain a SPP_PAGE_DES. * Create a pointer to the beginning of the generic * cmd_page structure. */ spd = (SPP_PAGE_DES *)&cmd_page; pm_strcpy(status, ""); indent_status_msg(status, _("Drive encryption status:\n"), indent); /* * See what encrption mode is enabled. */ switch (spd->encryptionMode) { case SPP_ENCR_MODE_DISABLE: indent_status_msg(status, _("Encryption Mode: Disabled\n"), indent + 3); break; case SPP_ENCR_MODE_EXTERNAL: indent_status_msg(status, _("Encryption Mode: External\n"), indent + 3); break; case SPP_ENCR_MODE_ENCRYPT: indent_status_msg(status, _("Encryption Mode: Encrypt\n"), indent + 3); break; default: break; } /* * See what decryption mode is enabled. */ switch (spd->decryptionMode) { case SPP_DECR_MODE_DISABLE: indent_status_msg(status, _("Decryption Mode: Disabled\n"), indent + 3); break; case SPP_DECR_MODE_RAW: indent_status_msg(status, _("Decryption Mode: Raw\n"), indent + 3); break; case SPP_DECR_MODE_DECRYPT: indent_status_msg(status, _("Decryption Mode: Decrypt\n"), indent + 3); break; case SPP_DECR_MODE_MIXED: indent_status_msg(status, _("Decryption Mode: Mixed\n"), indent + 3); break; default: break; } /* * See if RDMD is enabled. */ if (spd->RDMD) { indent_status_msg(status, _("Raw Decryption Mode Disabled (RDMD): Enabled\n"), indent + 3); } else { indent_status_msg(status, _("Raw Decryption Mode Disabled (RDMD): Disabled\n"), indent + 3); } /* * See what Check External Encryption Mode Status is set. */ switch (spd->CEEMS) { case SPP_CEEM_NO_ENCR_CHECK: indent_status_msg(status, _("Check External Encryption Mode Status (CEEMS) : No\n"), indent + 3); break; case SPP_CEEM_CHECK_EXTERNAL: indent_status_msg(status, _("Check External Encryption Mode Status (CEEMS) : External\n"), indent + 3); break; case SPP_CEEM_CHECK_ENCR: indent_status_msg(status, _("Check External Encryption Mode Status (CEEMS) : Encrypt\n"), indent + 3); break; default: break; } /* * See if VCELB is enabled. */ if (spd->VCELB) { indent_status_msg(status, _("Volume Contains Encrypted Logical Blocks (VCELB): Enabled\n"), indent + 3); } else { indent_status_msg(status, _("Volume Contains Encrypted Logical Blocks (VCELB): Disabled\n"), indent + 3); } /* * See what is providing the encryption keys. */ switch (spd->parametersControl) { case SPP_PARM_LOG_BLOCK_ENCR_NONE: indent_status_msg(status, _("Logical Block encryption parameters: No report\n"), indent + 3); break; case SPP_PARM_LOG_BLOCK_ENCR_AME: indent_status_msg(status, _("Logical Block encryption parameters: Application Managed\n"), indent + 3); break; case SPP_PARM_LOG_BLOCK_ENCR_DRIVE: indent_status_msg(status, _("Logical Block encryption parameters: Drive Managed\n"), indent + 3); break; case SPP_PARM_LOG_BLOCK_LME_ADC: indent_status_msg(status, _("Logical Block encryption parameters: Library/Key Management Appliance Managed\n"), indent + 3); break; case SPP_PARM_LOG_BLOCK_UNSUP: indent_status_msg(status, _("Logical Block encryption parameters: Unsupported\n"), indent + 3); break; default: break; } /* * Only when both encryption and decryption are disabled skip the KAD Format field. */ if (spd->encryptionMode != SPP_ENCR_MODE_DISABLE && spd->decryptionMode != SPP_DECR_MODE_DISABLE) { switch (spd->kadFormat) { case SPP_KAD_KEY_FORMAT_NORMAL: indent_status_msg(status, _("Key Associated Data (KAD) Descriptor: Normal key\n"), indent + 3); break; case SPP_KAD_KEY_FORMAT_REFERENCE: indent_status_msg(status, _("Key Associated Data (KAD) Descriptor: Vendor-specific reference\n"), indent + 3); break; case SPP_KAD_KEY_FORMAT_WRAPPED: indent_status_msg(status, _("Key Associated Data (KAD) Descriptor: Wrapped public key\n"), indent + 3); break; case SPP_KAD_KEY_FORMAT_ESP_SCSI: indent_status_msg(status, _("Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n"), indent + 3); break; default: break; } } return strlen(status); } /* * Request the encryption state of the next block * using a lowlevel SCSI interface. * * The device is send a: * - SPIN Security Protocol IN SCSI CDB. (0xA2) * - SPIN Get Data Encryption Status page. (0x21) * * The return data is interpreted and a status report is build. */ int get_scsi_volume_encryption_status(int fd, const char *device_name, POOLMEM *&status, int indent) { SPP_SCSI_CDB cdb; SPP_PAGE_BUFFER cmd_page; SPP_PAGE_NBES *spnb; int cmd_page_len, cdb_len; cmd_page_len = sizeof(cmd_page); memset(&cmd_page, 0, cmd_page_len); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_SPIN_OPCODE; cdb.scp = SPP_SP_PROTOCOL_TDE; set_2_byte_value(cdb.scp_specific, SPIN_NEXT_BLOCK_ENCR_STATUS_PAGE); set_4_byte_value(cdb.allocation_length, cmd_page_len); /* * Retrieve the volume encryption status. */ if (!recv_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len)) { return 0; } /* * We got a response which should contain a SPP_PAGE_NBES. * Create a pointer to the beginning of the generic * cmd_page structure. */ spnb = (SPP_PAGE_NBES *)&cmd_page; pm_strcpy(status, ""); indent_status_msg(status, _("Volume encryption status:\n"), indent); switch (spnb->compressionStatus) { case SPP_COMP_STATUS_UNKNOWN: indent_status_msg(status, _("Compression Status: Unknown\n"), indent + 3); break; case SPP_COMP_STATUS_UNAVAIL: indent_status_msg(status, _("Compression Status: Unavailable\n"), indent + 3); break; case SPP_COMP_STATUS_ILLEGAL: indent_status_msg(status, _("Compression Status: Illegal logical block\n"), indent + 3); break; case SPP_COMP_STATUS_UNCOMPRESSED: indent_status_msg(status, _("Compression Status: Compression Disabled\n"), indent + 3); break; case SPP_COMP_STATUS_COMPRESSED: indent_status_msg(status, _("Compression Status: Compression Enabled\n"), indent + 3); break; default: break; } switch (spnb->encryptionStatus) { case SPP_ENCR_STATUS_UNKNOWN: indent_status_msg(status, _("Encryption Status: Unknown\n"), indent + 3); break; case SPP_ENCR_STATUS_UNAVAIL: indent_status_msg(status, _("Encryption Status: Unavailable\n"), indent + 3); break; case SPP_ENCR_STATUS_ILLEGAL: indent_status_msg(status, _("Encryption Status: Illegal logical block\n"), indent + 3); break; case SPP_ENCR_STATUS_NOT_ENCRYPTED: indent_status_msg(status, _("Encryption Status: Encryption Disabled\n"), indent + 3); break; case SPP_ENCR_STATUS_ENCR_ALG_NOT_SUPP: indent_status_msg(status, _("Encryption Status: Encryption Enabled but with non supported algorithm\n"), indent + 3); break; case SPP_ENCR_STATUS_ENCRYPTED: indent_status_msg(status, _("Encryption Status: Encryption Enabled\n"), indent + 3); break; case SPP_ENCR_STATUS_ENCR_NOT_AVAIL: indent_status_msg(status, _("Encryption Status: Encryption Enabled but no valid key available for decryption\n"), indent + 3); break; default: break; } if (spnb->RDMDS) { indent_status_msg(status, _("Raw Decryption Mode Disabled Status (RDMDS): Enabled\n"), indent + 3); } else { indent_status_msg(status, _("Raw Decryption Mode Disabled Status (RDMDS): Disabled\n"), indent + 3); } if (spnb->EMES) { indent_status_msg(status, _("Encryption Mode External Status (EMES): Enabled\n"), indent + 3); } else { indent_status_msg(status, _("Encryption Mode External Status (EMES): Disabled\n"), indent + 3); } /* * Only when the encryption status is set to SPP_ENCR_STATUS_ENCRYPTED we * can use the nextBlockKADFormat otherwise that value is bogus. */ if (spnb->encryptionStatus == SPP_ENCR_STATUS_ENCRYPTED) { switch (spnb->nextBlockKADFormat) { case SPP_KAD_KEY_FORMAT_NORMAL: indent_status_msg(status, _("Next Block Key Associated Data (KAD) Descriptor: Normal key\n"), indent + 3); break; case SPP_KAD_KEY_FORMAT_REFERENCE: indent_status_msg(status, _("Next Block Key Associated Data (KAD) Descriptor: Vendor-specific reference\n"), indent + 3); break; case SPP_KAD_KEY_FORMAT_WRAPPED: indent_status_msg(status, _("Next Block Key Associated Data (KAD) Descriptor: Wrapped public key\n"), indent + 3); break; case SPP_KAD_KEY_FORMAT_ESP_SCSI: indent_status_msg(status, _("Next Block Key Associated Data (KAD) Descriptor: Key using ESP-SCSI\n"), indent + 3); break; default: break; } } return strlen(status); } /* * See if we need a decryption key to read the next block * using a lowlevel SCSI interface. * * The device is send a: * - SPIN Security Protocol IN SCSI CDB. (0xA2) * - SPIN Get Data Encryption Status page. (0x21) */ bool need_scsi_crypto_key(int fd, const char *device_name, bool use_drive_status) { SPP_SCSI_CDB cdb; SPP_PAGE_BUFFER cmd_page; SPP_PAGE_DES *spd; SPP_PAGE_NBES *spnb; int cmd_page_len, cdb_len; cmd_page_len = sizeof(cmd_page); memset(&cmd_page, 0, cmd_page_len); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_SPIN_OPCODE; cdb.scp = SPP_SP_PROTOCOL_TDE; if (use_drive_status) { set_2_byte_value(cdb.scp_specific, SPIN_DATA_ENCR_STATUS_PAGE); } else { set_2_byte_value(cdb.scp_specific, SPIN_NEXT_BLOCK_ENCR_STATUS_PAGE); } set_4_byte_value(cdb.allocation_length, cmd_page_len); /* * Retrieve the volume encryption status. */ if (!recv_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len)) { return false; } if (use_drive_status) { /* * We got a response which should contain a SPP_PAGE_DES. * Create a pointer to the beginning of the generic * cmd_page structure. */ spd = (SPP_PAGE_DES *)&cmd_page; /* * Return the status of the Volume Contains Encrypted Logical Blocks (VCELB) field. */ return (spd->VCELB) ? true : false; } else { /* * We got a response which should contain a SPP_PAGE_NBES. * Create a pointer to the beginning of the generic * cmd_page structure. */ spnb = (SPP_PAGE_NBES *)&cmd_page; /* * If the encryptionStatus is set to encrypted or encrypted but valid key not available * we know we need to load a key to decrypt the data. */ switch (spnb->encryptionStatus) { case SPP_ENCR_STATUS_ENCRYPTED: case SPP_ENCR_STATUS_ENCR_NOT_AVAIL: return true; default: break; } } return false; } /* * See if encryption is enabled on a device using a lowlevel SCSI interface. * * The device is send a: * - SPIN Security Protocol IN SCSI CDB. (0xA2) * - SPIN Get Data Encryption Status page. (0x20) */ bool is_scsi_encryption_enabled(int fd, const char *device_name) { SPP_SCSI_CDB cdb; SPP_PAGE_BUFFER cmd_page; SPP_PAGE_DES *spd; int cmd_page_len, cdb_len; cmd_page_len = sizeof(cmd_page); memset(&cmd_page, 0, cmd_page_len); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_SPIN_OPCODE; cdb.scp = SPP_SP_PROTOCOL_TDE; set_2_byte_value(cdb.scp_specific, SPIN_DATA_ENCR_STATUS_PAGE); set_4_byte_value(cdb.allocation_length, cmd_page_len); /* * Retrieve the drive encryption status. */ if (!recv_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len)) { return false; } /* * We got a response which should contain a SPP_PAGE_DES. * Create a pointer to the beginning of the generic * cmd_page structure. */ spd = (SPP_PAGE_DES *)&cmd_page; /* * When either encryptionMode or decryptionMode are not disabled we return true */ return (spd->encryptionMode != SPP_ENCR_MODE_DISABLE) || (spd->decryptionMode != SPP_DECR_MODE_DISABLE); } #else bool clear_scsi_encryption_key(int fd, const char *device_name) { return false; } bool set_scsi_encryption_key(int fd, const char *device_name, char *encryption_key) { return false; } int get_scsi_drive_encryption_status(int fd, const char *device_name, POOLMEM *&status, int indent) { pm_strcpy(status, ""); indent_status_msg(status, _("Drive encryption status: Unknown\n"), indent); return strlen(status); } int get_scsi_volume_encryption_status(int fd, const char *device_name, POOLMEM *&status, int indent) { pm_strcpy(status, ""); indent_status_msg(status, _("Volume encryption status: Unknown\n"), indent); return strlen(status); } bool need_scsi_crypto_key(int fd, const char *device_name, bool use_drive_status) { return false; } bool get_scsi_encryption_enabled(int fd, const char *device_name) { return false; } #endif /* HAVE_LOWLEVEL_SCSI_INTERFACE */ static void indent_status_msg(POOLMEM *&status, const char *msg, int indent) { int cnt; char indent_level[17]; /* * See if we need to indent the line. */ if (indent > 0) { for (cnt = 0; cnt < indent && cnt < 16; cnt++) { indent_level[cnt] = ' '; } indent_level[cnt] = '\0'; pm_strcat(status, indent_level); } pm_strcat(status, msg); } bareos-Release-14.2.6/src/lib/scsi_crypto.h000066400000000000000000000540241263011562700205140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, March 2012 */ #ifndef _SCSI_CRYPTO_H #define _SCSI_CRYPTO_H 1 /* * Include the SCSI Low Level Interface functions and definitions. */ #include "scsi_lli.h" #define SPP_SP_PROTOCOL_TDE 0x20 #define SPP_KEY_LENGTH 0x20 /* 32 bytes */ #define SPP_DESCRIPTOR_LENGTH 1024 #define SPP_PAGE_DES_LENGTH 24 #define SPP_PAGE_NBES_LENGTH 16 #define SPP_KAD_HEAD_LENGTH 4 #define SPP_PAGE_ALLOCATION 8192 #define SPP_UKAD_LENGTH 0x1e /* * SCSI CDB opcodes */ enum { SCSI_SPIN_OPCODE = 0xa2, SCSI_SPOUT_OPCODE = 0xb5 }; /* * SCSI SPIN pagecodes. */ enum { SPIN_TAPE_DATA_ENCR_IN_SUP_PAGE = 0x00, /* Tape Data Encryption In Support page */ SPIN_TAPE_DATE_ENCR_OUT_SUP_PAGE = 0x01, /* Tape Data Encryption Out Support page */ SPIN_DATA_ENCR_CAP_PAGE = 0x10, /* Data Encryption Capabilities page */ SPIN_SUP_KEY_FORMATS_PAGE = 0x11, /* Supported Key Formats page */ SPIN_DATA_ENCR_MGMT_CAP_PAGE = 0x12, /* Data Encryption Management Capabilities page */ SPIN_DATA_ENCR_STATUS_PAGE = 0x20, /* Data Encryption Status page */ SPIN_NEXT_BLOCK_ENCR_STATUS_PAGE = 0x21, /* Next Block Encryption Status page */ SPIN_RANDOM_NUM_PAGE = 0x30, /* Random Number page */ SPIN_DEV_SVR_KEY_WRAP_PUB_KEY_PAGE = 0x31 /* Device Server Key Wrapping Public Key page */ }; /* * SCSI SPOUT pagecodes. */ enum { SPOUT_SET_DATA_ENCRYPTION_PAGE = 0x10, /* Set Data Encryption page */ SPOUT_SA_ENCAP_PAGE = 0x11 /* SA Encapsulation page */ }; /* * SPP SCSI Control Descriptor Block */ typedef struct { uint8_t opcode; /* Operation Code See SCSI_*_OPCODE */ uint8_t scp; /* Security Protocol */ uint8_t scp_specific[2]; /* Security Protocol Specific, 2 bytes MSB/LSB */ uint8_t res_bits_1[2]; /* Reserved, 2 bytes */ uint8_t allocation_length[4]; /* Allocation Length, 4 bytes, 2 bytes MSB and 2 bytes LSB */ uint8_t res_bits_2; /* Reserved, 1 byte */ uint8_t control_byte; /* Control Byte */ } SPP_SCSI_CDB; /* * Generic SPP Page Buffer */ typedef struct { uint8_t pageCode[2]; uint8_t length[2]; uint8_t buffer[SPP_PAGE_ALLOCATION]; } SPP_PAGE_BUFFER; /* * Nexus Scopes */ enum { SPP_NEXUS_SC_PUBLIC = 0, /* All fields other than the scope field and LOCK bit shall be ignored. The I_T nexus shall use data encryption parameters that are shared by other I_T nexuses. If no I_T nexuses are sharing data encryption parameters, the device server shall use default data encryption parameters. */ SPP_NEXUS_SC_LOCAL = 1, /* The data encryption parameters are unique to the I_T nexus associated with the SECURITY PROTOCOL OUT command and shall not be shared with other I_T nexuses.*/ SPP_NEXUS_SC_ALL_I_T_NEXUS = 2 /* The data encryption parameters shall be shared with all I_T nexuses. */ }; /* * Check External Encryption Mode */ enum { SPP_CEEM_VENDOR_SPECIFIC = 0, /* Vendor specific */ SPP_CEEM_NO_ENCR_CHECK = 1, /* Do not check the encryption mode that was in use when the block was written to the medium.*/ SPP_CEEM_CHECK_EXTERNAL = 2, /* On read and verify commands, check the encryption mode that was in use when the block was written to the medium. Report an error if the block was written in EXTERNAL mode */ SPP_CEEM_CHECK_ENCR = 3 /* On read and verify commands, check the encryption mode that was in use when the block was written to the medium. Report an error if the block was written in ENCRYPT mode */ }; /* * Raw Decryption Mode Control */ enum { SPP_RDMC_DEFAULT = 0, /* The device server shall mark each encrypted block per the default setting for the algorithm */ SPP_RDMC_UNPROTECT = 2, /* The device server shall mark each encrypted block written to the medium in a format specific manner as enabled for raw decryption mode operations. */ SPP_RDMC_PROTECT = 3 /* The device server shall mark each encrypted block written to the medium in a format specific manner as disabled for raw decryption mode operations. */ }; /* * Encryption Modes. */ enum { SPP_ENCR_MODE_DISABLE = 0, /* Data encryption is disabled. */ SPP_ENCR_MODE_EXTERNAL = 1, /* The data associated with the WRITE(6) and WRITE(16) commands has been encrypted by a system that is compatible with the algorithm specified by the ALGORITHM INDEX field. */ SPP_ENCR_MODE_ENCRYPT = 2 /* The device server shall encrypt all data that it receives for a WRITE(6) or WRITE(16) command using the algorithm specified in the ALGORITHM INDEX field and the key specified in the KEY field. */ }; /* * Decryption Modes. */ enum { SPP_DECR_MODE_DISABLE = 0, /* Data decryption is disabled. If the device server encounters an encrypted logical block while reading, it shall not allow access to the data. */ SPP_DECR_MODE_RAW = 1, /* Data decryption is disabled. If the device server encounters an encrypted logical block while reading, it shall pass the encrypted block to the host without decrypting it. The encrypted block may contain data that is not user data. */ SPP_DECR_MODE_DECRYPT = 2, /* The device server shall decrypt all data that is read from the medium when processing a READ(6), READ(16), READ REVERSE(6), READ REVERSE(16), or RECOVER BUFFERED DATA command or verified when processing a VERIFY(6) or VERIFY(16) command. The data shall be decrypted using the algorithm specified in the ALGORITHM INDEX field and the key specified in the KEY field */ SPP_DECR_MODE_MIXED = 3 /* The device server shall decrypt all data that is read from the medium that the device server determines was encrypted when processing a READ(6), READ(16), READ REVERSE(6), READ REVERSE(16), or RECOVER BUFFERED DATA command or verified when processing a VERIFY(6) or VERIFY(16) command. The data shall be decrypted using the algorithm specified in the ALGORITHM INDEX field and the key specified in the KEY field. If the device server encounters unencrypted data when processing a READ(6), READ(16), READ REVERSE(6), READ REVERSE(16), RECOVER BUFFERED DATA, VERIFY(6), or VERIFY(16) command, the data shall be processed without decrypting */ }; /* * Key Format Types. */ enum { SPP_KAD_KEY_FORMAT_NORMAL = 0, /* The KEY field contains the key to be used to encrypt or decrypt data. */ SPP_KAD_KEY_FORMAT_REFERENCE = 1, /* The KEY field contains a vendor-specific key reference. */ SPP_KAD_KEY_FORMAT_WRAPPED = 2, /* The KEY field contains the key wrapped by the device server public key. */ SPP_KAD_KEY_FORMAT_ESP_SCSI = 3 /* The KEY field contains a key that is encrypted using ESP-SCSI. */ }; /* * Key Descriptor Types */ enum { SPP_KAD_KEY_DESC_UKAD = 0, /* Unauthenticated key-associated data */ SPP_KAD_KEY_DESC_AKAD = 1, /* Authenticated key-associated data */ SPP_KAD_KEY_DESC_NONCE = 2, /* Nonce value */ SPP_KAD_KEY_DESC_META = 3 /* Metadata key-associated data */ }; /* * SPOUT Page Set Data Encryption (0x10) */ typedef struct { uint8_t pageCode[2]; /* Page Code, 2 bytes MSB/LSB */ uint8_t length[2]; /* Page Length, 2 bytes MSB/LSB */ #if HAVE_BIG_ENDIAN uint8_t nexusScope:3; /* Scope, See SPP_NEXUS_SC_* */ uint8_t res_bits_1:4; /* Reserved, 4 bits */ uint8_t lock:1; /* Lock bit */ uint8_t CEEM:2; /* Check External Encryption Mode, See SPP_CEEM_* */ uint8_t RDMC:2; /* Raw Decryption Mode Control, See SPP_RDMC_* */ uint8_t SDK:1; /* Supplemental Decryption Key */ uint8_t CKOD:1; /* Clear Key On Demount */ uint8_t CKORP:1; /* Clear Key On Reservation Preempt */ uint8_t CKORL:1; /* Clear Key On Reservation Lost */ #else uint8_t lock:1; /* Lock bit */ uint8_t res_bits_1:4; /* Reserved, 4 bits */ uint8_t nexusScope:3; /* Scope, See SPP_NEXUS_SC_* */ uint8_t CKORL:1; /* Clear Key On Reservation Lost */ uint8_t CKORP:1; /* Clear Key On Reservation Preempt */ uint8_t CKOD:1; /* Clear Key On Demount */ uint8_t SDK:1; /* Supplemental Decryption Key */ uint8_t RDMC:2; /* Raw Decryption Mode Control, See SPP_RDMC_* */ uint8_t CEEM:2; /* Check External Encryption Mode, See SPP_CEEM_* */ #endif uint8_t encryptionMode; /* Encryption Mode, See SPP_ENCR_MODE_* */ uint8_t decryptionMode; /* Decryption Mode, See SPP_DECR_MODE_* */ uint8_t algorithmIndex; /* Algorithm Index */ uint8_t keyFormat; /* Logical Block Encryption Key Format */ uint8_t kadFormat; /* KAD Format, See SPP_KAD_KEY_FORMAT_* */ uint8_t res_bits_2[7]; /* Reserved, 7 bytes */ uint8_t keyLength[2]; /* Logical Block Encryption Key Length, 2 bytes MSB/LSB */ uint8_t keyData[SPP_KEY_LENGTH]; } SPP_PAGE_SDE; enum { SPP_PARM_LOG_BLOCK_ENCR_NONE = 0, /* Logical block encryption parameters control is not reported. */ SPP_PARM_LOG_BLOCK_ENCR_AME = 1, /* Logical Block Encryption Parameters are not exclusively controlled by external data encryption control. */ SPP_PARM_LOG_BLOCK_ENCR_DRIVE = 2, /* Logical block encryption parameters are exclusively controlled by the sequential-access device server. */ SPP_PARM_LOG_BLOCK_LME_ADC = 3, /* Logical block encryption parameters are exclusively controlled by the automation/drive interface device server. */ SPP_PARM_LOG_BLOCK_UNSUP = 4 /* Not supported. */ }; /* * Device Encryption Status Page (0x20) */ typedef struct { uint8_t pageCode[2]; /* Page Code, 2 bytes MSB/LSB */ uint8_t length[2]; /* Page Length, 2 bytes MSB/LSB */ #if HAVE_BIG_ENDIAN uint8_t nexusScope:3; /* Scope, See SPP_NEXUS_SC_* */ uint8_t res_bits_1:2; /* Reserved, 2 bits */ uint8_t keyScope:3; /* Logical Block Encryption Scope */ #else uint8_t keyScope:3; /* Logical Block Encryption Scope */ uint8_t res_bits_1:2; /* Reserved, 2 bits */ uint8_t nexusScope:3; /* Scope, See SPP_NEXUS_SC_* */ #endif uint8_t encryptionMode; /* Encryption Mode, See SPP_ENCR_MODE_* */ uint8_t decryptionMode; /* Decryption Mode, See SPP_DECR_MODE_* */ uint8_t algorithmIndex; /* Algorithm Index */ uint8_t keyInstance[4]; /* Key Instance Counter MSB/LSB */ #if HAVE_BIG_ENDIAN uint8_t res_bits_2:1; /* Reserved, 1 bit */ uint8_t parametersControl:3; /* Logical Block encryption parameters, See SPP_PARM_LOG_BLOCK_* */ uint8_t VCELB:1; /* Volume Contains Encrypted Logical Blocks */ uint8_t CEEMS:2; /* Check External Encryption Mode Status, See SPP_CEEM_* */ uint8_t RDMD:1; /* Raw Decryption Mode Disabled */ #else uint8_t RDMD:1; /* Raw Decryption Mode Disabled */ uint8_t CEEMS:2; /* Check External Encryption Mode Status, See SPP_CEEM_* */ uint8_t VCELB:1; /* Volume Contains Encrypted Logical Blocks */ uint8_t parametersControl:3; /* Logical Block encryption parameters, See SPP_PARM_LOG_BLOCK_* */ uint8_t res_bits_2:1; /* Reserved, 1 bit */ #endif uint8_t kadFormat; /* KAD Format, See SPP_KAD_KEY_FORMAT_* */ uint8_t ASDKCount[2]; /* Available Supplemental Decryption Key MSB/LSB */ uint8_t res_bits_4[8]; /* Reserved, 8 bytes */ } SPP_PAGE_DES; enum { SPP_COMP_STATUS_UNKNOWN = 0, /* The device server is incapable of determining if the logical object referenced by the LOGICAL OBJECT NUMBER field has been compressed. */ SPP_COMP_STATUS_UNAVAIL = 1, /* The device server is capable of determining if the logical object referenced by the LOGICAL OBJECT NUMBER field has been compressed, but is not able to at this time. Possible reasons are: a) the next logical block has not yet been read into the buffer; b) there was an error reading the next logical block; or c) there are no more logical blocks (i.e., end-of-data). */ SPP_COMP_STATUS_ILLEGAL = 2, /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is not a logical block. */ SPP_COMP_STATUS_UNCOMPRESSED = 3, /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is not compressed. */ SPP_COMP_STATUS_COMPRESSED = 4 /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is compressed. */ }; enum { SPP_ENCR_STATUS_UNKNOWN = 0, /* The device server is incapable of determining if the logical object referenced by the LOGICAL OBJECT NUMBER field has been encrypted. */ SPP_ENCR_STATUS_UNAVAIL = 1, /* The device server is capable of determining if the logical object referenced by the LOGICAL OBJECT NUMBER field has been encrypted, but is not able to at this time. Possible reasons are: a) the next logical block has not yet been read into the buffer; b) there was an error reading the next logical block; or c) there are no more logical blocks (i.e., end-of-data). */ SPP_ENCR_STATUS_ILLEGAL = 2, /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is not a logical block. */ SPP_ENCR_STATUS_NOT_ENCRYPTED = 3, /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is not encrypted. */ SPP_ENCR_STATUS_ENCR_ALG_NOT_SUPP = 4, /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is encrypted by an algorithm that is not supported by this device server. The values in the KEY-ASSOCIATED DATA DESCRIPTORS field contain information pertaining to the encrypted block. */ SPP_ENCR_STATUS_ENCRYPTED = 5, /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is encrypted by an algorithm that is supported by this device server. The values in the ALGORITHM INDEX and KEY-ASSOCIATED DATA DESCRIPTORS fields contain information pertaining to the encrypted block. */ SPP_ENCR_STATUS_ENCR_NOT_AVAIL = 6 /* The device server has determined that the logical object referenced by the LOGICAL OBJECT NUMBER field is encrypted by an algorithm that is supported by this device server, but the device server is either not enabled to decrypt or does not have the correct key or nonce value to decrypt the encrypted block. */ }; /* * Next Block Encryption Status Page (0x21) */ typedef struct { uint8_t pageCode[2]; /* Page Code, 2 bytes MSB/LSB */ uint8_t length[2]; /* Page Length, 2 bytes MSB/LSB */ uint8_t log_obj_num[8]; /* Logical Object Number */ #if HAVE_BIG_ENDIAN uint8_t compressionStatus:4; /* Compression Status, See SPP_COMPRESS_STATUS_* */ uint8_t encryptionStatus:4; /* Encryption Status, See SPP_ENCR_STATUS_* */ #else uint8_t encryptionStatus:4; /* Encryption Status, See SPP_ENCR_STATUS_* */ uint8_t compressionStatus:4; /* Compression Status, See SPP_COMPRESS_STATUS_* */ #endif uint8_t algorithmIndex; /* Algorithm Index */ #if HAVE_BIG_ENDIAN uint8_t res_bits_1:6; /* Reserved, 6 bits */ uint8_t EMES:1; /* Encryption Mode External Status */ uint8_t RDMDS:1; /* Raw Decryption Mode Disabled Status */ #else uint8_t RDMDS:1; /* Raw Decryption Mode Disabled Status */ uint8_t EMES:1; /* Encryption Mode External Status */ uint8_t res_bits_1:6; /* Reserved, 6 bits */ #endif uint8_t nextBlockKADFormat; /* Next Block KAD Format, See SPP_KAD_KEY_FORMAT_* */ } SPP_PAGE_NBES; /* * Key Associated Data (KAD) Descriptors */ typedef struct { uint8_t type; /* Key Descriptor Type, See SPP_KAD_KEY_DESC_* */ #if HAVE_BIG_ENDIAN uint8_t res_bits_1:5; /* Reserved, 5 bits */ uint8_t authenticated:3; #else uint8_t authenticated:3; uint8_t res_bits_1:5; /* Reserved, 5 bits */ #endif uint8_t descriptorLength[2]; /* Key Descriptor Length MSB/LSB */ uint8_t descriptor[SPP_DESCRIPTOR_LENGTH]; } SPP_KAD; #endif /* _SCSI_CRYPTO_H */ bareos-Release-14.2.6/src/lib/scsi_lli.c000066400000000000000000000407441263011562700177530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Low level SCSI interface. * * Marco van Wieringen, March 2012 */ #include "bareos.h" /* Forward referenced functions */ #ifdef HAVE_LOWLEVEL_SCSI_INTERFACE #include "scsi_lli.h" #if defined(HAVE_LINUX_OS) #include #include #ifndef SIOC_REQSENSE #define SIOC_REQSENSE _IOR ('C',0x02,SCSI_PAGE_SENSE) #endif /* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int direction) { int rc; sg_io_hdr_t io_hdr; SCSI_PAGE_SENSE sense; bool opened_device = false; bool retval = false; /* * See if we need to open the device_name or if we got an open filedescriptor. */ if (fd == -1) { fd = open(device_name, O_RDWR | O_NONBLOCK | O_BINARY); if (fd < 0) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open %s: ERR=%s\n", device_name, be.bstrerror()); return false; } opened_device = true; } memset(&sense, 0, sizeof(sense)); memset(&io_hdr, 0, sizeof(io_hdr)); io_hdr.interface_id = 'S'; io_hdr.cmd_len = cdb_len; io_hdr.mx_sb_len = sizeof(sense); io_hdr.dxfer_direction = direction; io_hdr.dxfer_len = cmd_page_len; io_hdr.dxferp = (char *)cmd_page; io_hdr.cmdp = (unsigned char *)cdb; io_hdr.sbp = (unsigned char *)&sense; rc = ioctl(fd, SG_IO, &io_hdr); if (rc < 0) { berrno be; Emsg2(M_ERROR, 0, _("Unable to perform SG_IO ioctl on fd %d: ERR=%s\n"), fd, be.bstrerror()); Dmsg2(010, "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n", fd, be.bstrerror()); goto bail_out; } if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) { Emsg3(M_ERROR, 0, _("Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n"), io_hdr.info, io_hdr.masked_status, io_hdr.msg_status); Emsg2(M_ERROR, 0, _(" host status 0x%02x driver status 0x%02x\n"), io_hdr.host_status, io_hdr.driver_status ); Dmsg3(010, "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n", io_hdr.info, io_hdr.masked_status, io_hdr.msg_status); Dmsg2(010, " host status 0x%02x driver status 0x%02x\n", io_hdr.host_status, io_hdr.driver_status ); goto bail_out; } retval = true; bail_out: /* * See if we opened the device in this function, if so close it. */ if (opened_device) { close(fd); } return retval; } /* * Receive a lowlevel SCSI cmd from a SCSI device using the Linux SG_IO ioctl interface. */ bool recv_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, SG_DXFER_FROM_DEV); } /* * Send a lowlevel SCSI cmd to a SCSI device using the Linux SG_IO ioctl interface. */ bool send_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, SG_DXFER_TO_DEV); } /* * Check if the SCSI sense is EOD. */ bool check_scsi_at_eod(int fd) { int rc; SCSI_PAGE_SENSE sense; memset(&sense, 0, sizeof(sense)); rc = ioctl(fd, SIOC_REQSENSE, &sense); if (rc != 0) { return false; } return sense.senseKey == 0x08 && /* BLANK CHECK. */ sense.addSenseCode == 0x00 && /* End of data (Combination of asc and ascq)*/ sense.addSenseCodeQual == 0x05; } #elif defined(HAVE_SUN_OS) #include #ifndef LOBYTE #define LOBYTE(_w) ((_w) & 0xff) #endif /* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int flags) { int rc; struct uscsi_cmd my_cmd; SCSI_PAGE_SENSE sense; bool opened_device = false; bool retval = false; /* * See if we need to open the device_name or if we got an open filedescriptor. */ if (fd == -1) { fd = open(device_name, O_RDWR | O_NONBLOCK | O_BINARY); if (fd < 0) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open %s: ERR=%s\n", device_name, be.bstrerror()); return false; } opened_device = true; } memset(&sense, 0, sizeof(sense)); my_cmd.uscsi_flags = flags; my_cmd.uscsi_timeout = 15; /* Allow 15 seconds for completion */ my_cmd.uscsi_cdb = (char *)cdb; my_cmd.uscsi_cdblen = cdb_len; my_cmd.uscsi_bufaddr = (char *)cmd_page; my_cmd.uscsi_buflen = cmd_page_len; my_cmd.uscsi_rqlen = sizeof(sense); my_cmd.uscsi_rqbuf = (char *)&sense; rc = ioctl(fd, USCSICMD, &my_cmd); if (rc != 0) { berrno be; Emsg2(M_ERROR, 0, _("Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n"), fd, be.bstrerror()); Emsg3(M_ERROR, 0, _("Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n"), LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); Dmsg2(010, "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n", fd, be.bstrerror()); Dmsg3(010, "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n", LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); goto bail_out; } retval = true; bail_out: /* * See if we opened the device in this function, if so close it. */ if (opened_device) { close(fd); } return retval; } /* * Receive a lowlevel SCSI cmd from a SCSI device using the Solaris USCSI ioctl interface. */ bool recv_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, (USCSI_READ | USCSI_SILENT | USCSI_RQENABLE)); } /* * Send a lowlevel SCSI cmd to a SCSI device using the Solaris USCSI ioctl interface. */ bool send_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, (USCSI_WRITE | USCSI_SILENT | USCSI_RQENABLE)); } bool check_scsi_at_eod(int fd) { return false; } #elif defined(HAVE_FREEBSD_OS) #include #include #ifndef SAM_STAT_CHECK_CONDITION #define SAM_STAT_CHECK_CONDITION 0x2 #endif #ifndef SAM_STAT_COMMAND_TERMINATED #define SAM_STAT_COMMAND_TERMINATED 0x22 #endif /* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int direction) { int unitnum, len; union ccb *ccb; char errbuf[128]; char cam_devicename[64]; struct cam_device *cam_dev; SCSI_PAGE_SENSE sense; bool retval = false; /* * See what CAM device to use. */ if (cam_get_device(device_name, cam_devicename, sizeof(cam_devicename), &unitnum) == -1) { berrno be; Emsg2(M_ERROR, 0, _("Failed to find CAM device for %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to find CAM device for %s: ERR=%s\n", device_name, be.bstrerror()); return false; } cam_dev = cam_open_spec_device(cam_devicename, unitnum, O_RDWR, NULL); if (!cam_dev) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open CAM device for %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open CAM device for %s: ERR=%s\n", device_name, be.bstrerror()); return false; } ccb = cam_getccb(cam_dev); if (!ccb) { Emsg1(M_ERROR, 0, _("Failed to allocate new ccb for %s\n"), device_name); Dmsg1(0, "Failed to allocate new ccb for %s\n", device_name); goto bail_out; } /* * Clear out structure, except for header that was filled for us. */ memset(&(&ccb->ccb_h)[1], 0, sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); cam_fill_csio(&ccb->csio, 1, /* retries */ NULL, /* cbfcnp */ direction, /* flags */ MSG_SIMPLE_Q_TAG, /* tagaction */ (u_int8_t *)cmd_page, /* dataptr */ cmd_page_len, /* datalen */ sizeof(sense), /* senselength */ cdb_len, /* cdblength */ 15000 /* timeout (millisecs) */); memcpy(ccb->csio.cdb_io.cdb_bytes, cdb, cdb_len); if (cam_send_ccb(cam_dev, ccb) < 0) { Emsg2(M_ERROR, 0, _("Failed to send ccb to device %s: %s\n"), device_name, cam_error_string(cam_dev, ccb, errbuf, sizeof(errbuf), CAM_ESF_ALL, CAM_EPF_ALL)); Dmsg2(010, "Failed to send ccb to device %s: %s\n", device_name, cam_error_string(cam_dev, ccb, errbuf, sizeof(errbuf), CAM_ESF_ALL, CAM_EPF_ALL)); cam_freeccb(ccb); goto bail_out; } /* * Retrieve the SCSI sense data. */ if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)) { if ((SAM_STAT_CHECK_CONDITION == ccb->csio.scsi_status) || (SAM_STAT_COMMAND_TERMINATED == ccb->csio.scsi_status)) { len = sizeof(sense) - ccb->csio.sense_resid; if (len) { memcpy(&sense, &(ccb->csio.sense_data), len); } } } retval = true; bail_out: /* * Close the CAM device. */ cam_close_device(cam_dev); return retval; } /* * Receive a lowlevel SCSI cmd from a SCSI device using the FreeBSD SCSI CAM interface. */ bool recv_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, CAM_DIR_IN); } /* * Send a lowlevel SCSI cmd to a SCSI device using the FreeBSD SCSI CAM interface. */ bool send_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, CAM_DIR_OUT); } bool check_scsi_at_eod(int fd) { return false; } #elif defined(HAVE_NETBSD_OS) || defined(HAVE_OPENBSD_OS) #if defined(HAVE_NETBSD_OS) #include #else #include #endif #ifndef LOBYTE #define LOBYTE(_w) ((_w) & 0xff) #endif /* * Core interface function to lowlevel SCSI interface. */ static inline bool do_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len, int flags) { int rc; scsireq_t req; SCSI_PAGE_SENSE *sense; bool opened_device = false; bool retval = false; /* * See if we need to open the device_name or if we got an open filedescriptor. */ if (fd == -1) { fd = open(device_name, O_RDWR | O_NONBLOCK| O_BINARY); if (fd < 0) { berrno be; Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"), device_name, be.bstrerror()); Dmsg2(010, "Failed to open %s: ERR=%s\n", device_name, be.bstrerror()); return false; } opened_device = true; } memset(&req, 0, sizeof(req)); memcpy(req.cmd, cdb, cdb_len); req.cmdlen = cdb_len; req.databuf = cmd_page; req.datalen = cmd_page_len; req.timeout = 15000 /* timeout (millisecs) */; req.flags = flags; req.senselen = sizeof(SCSI_PAGE_SENSE); rc = ioctl(fd, SCIOCCOMMAND, &req); if (rc < 0) { berrno be; Emsg2(M_ERROR, 0, _("Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n"), fd, be.bstrerror()); Dmsg2(010, "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n", fd, be.bstrerror()); goto bail_out; } switch (req.retsts) { case SCCMD_OK: retval = true; break; case SCCMD_SENSE: sense = req.sense; Emsg3(M_ERROR, 0, _("Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n"), LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); Dmsg3(010, "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n", LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual); break; case SCCMD_TIMEOUT: Emsg1(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n"), devicename); Dmsg1(010, "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n", devicename); break; case SCCMD_BUSY: Emsg1(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned device is busy\n"), devicename); Dmsg1(010, "SCIOCCOMMAND ioctl on %s returned device is busy\n", devicename); break; case SCCMD_SENSE: break; default: Emsg2(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned unknown status %d\n"), device_name, req.retsts); Dmsg2(010, "SCIOCCOMMAND ioctl on %s returned unknown status %d\n", device_name, req.retsts); break; } bail_out: /* * See if we opened the device in this function, if so close it. */ if (opened_device) { close(fd); } return retval; } /* * Receive a lowlevel SCSI cmd from a SCSI device using the NetBSD/OpenBSD * SCIOCCOMMAND ioctl interface. */ bool recv_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, SCCMD_READ); } /* * Send a lowlevel SCSI cmd to a SCSI device using the NetBSD/OpenBSD * SCIOCCOMMAND ioctl interface. */ bool send_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return do_scsi_cmd_page(fd, device_name, cdb, cdb_len, cmd_page, cmd_page_len, SCCMD_WRITE); } bool check_scsi_at_eod(int fd) { return false; } #endif #else /* * Dummy lowlevel functions when no support for platform. */ bool recv_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return false; } bool send_scsi_cmd_page(int fd, const char *device_name, void *cdb, unsigned int cdb_len, void *cmd_page, unsigned int cmd_page_len) { return false; } bool check_scsi_at_eod(int fd) { return false; } #endif /* HAVE_LOWLEVEL_SCSI_INTERFACE */ bareos-Release-14.2.6/src/lib/scsi_lli.h000066400000000000000000000100751263011562700177520ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, March 2012 */ #ifndef _SCSI_LLI_H #define _SCSI_LLI_H 1 /* * Device Inquiry Response */ typedef struct { #if HAVE_BIG_ENDIAN uint8_t peripheralQualifier:3; uint8_t periphrealDeviceType:5; uint8_t RMB:1; uint8_t res_bits_1:7; #else uint8_t periphrealDeviceType:5; uint8_t peripheralQualifier:3; uint8_t res_bits_1:7; uint8_t RMB:1; #endif uint8_t Version[1]; #if HAVE_BIG_ENDIAN uint8_t obs_bits_1:2; uint8_t NORMACA:1; uint8_t HISUP:1; uint8_t responseDataFormat:4; #else uint8_t responseDataFormat:4; uint8_t HISUP:1; uint8_t NORMACA:1; uint8_t obs_bits_1:2; #endif uint8_t additionalLength[1]; #if HAVE_BIG_ENDIAN uint8_t SCCS:1; uint8_t ACC:1; uint8_t TPGS:2; uint8_t threePC:1; uint8_t res_bits_2:2; uint8_t protect:1; uint8_t obs_bits_2:1; uint8_t ENCSERV:1; uint8_t VS:1; uint8_t MULTIP:1; uint8_t MCHNGR:1; uint8_t obs_bits_3:2; uint8_t ADDR16:1; uint8_t obs_bits_4:2; uint8_t WBUS16:1; uint8_t SYNC:1; uint8_t obs_bits_5:2; uint8_t CMDQUE:1; uint8_t VS2:1; #else uint8_t protect:1; uint8_t res_bits_2:2; uint8_t threePC:1; uint8_t TPGS:2; uint8_t ACC:1; uint8_t SCCS:1; uint8_t ADDR16:1; uint8_t obs_bits_3:2; uint8_t MCHNGR:1; uint8_t MULTIP:1; uint8_t VS:1; uint8_t ENCSERV:1; uint8_t obs_bits_2:1; uint8_t VS2:1; uint8_t CMDQUE:1; uint8_t obs_bits_5:2; uint8_t SYNC:1; uint8_t WBUS16:1; uint8_t obs_bits_4:2; #endif uint8_t vendor[8]; uint8_t productID[16]; uint8_t productRev[4]; uint8_t SN[7]; uint8_t venderUnique[12]; #if HAVE_BIG_ENDIAN uint8_t res_bits_3:4; uint8_t CLOCKING:2; uint8_t QAS:1; uint8_t IUS:1; #else uint8_t IUS:1; uint8_t QAS:1; uint8_t CLOCKING:2; uint8_t res_bits_3:4; #endif uint8_t res_bits_4[1]; uint8_t versionDescriptor[16]; uint8_t res_bits_5[22]; uint8_t copyright[1]; } SCSI_PAGE_INQ; /* * Sense Data Response */ typedef struct { #if HAVE_BIG_ENDIAN uint8_t valid:1; uint8_t responseCode:7; #else uint8_t responseCode:7; uint8_t valid:1; #endif uint8_t res_bits_1; #if HAVE_BIG_ENDIAN uint8_t filemark:1; uint8_t EOM:1; uint8_t ILI:1; uint8_t res_bits_2:1; uint8_t senseKey:4; #else uint8_t senseKey:4; uint8_t res_bits_2:1; uint8_t ILI:1; uint8_t EOM:1; uint8_t filemark:1; #endif uint8_t information[4]; uint8_t addSenseLen; uint8_t cmdSpecificInfo[4]; uint8_t addSenseCode; uint8_t addSenseCodeQual; uint8_t fieldRepUnitCode; #if HAVE_BIG_ENDIAN uint8_t sim:3; /* system information message */ uint8_t bpv:1; /* bit pointer valid */ uint8_t resvd2:2; uint8_t cd:1; /* control/data */ uint8_t SKSV:1; #else uint8_t SKSV:1; uint8_t cd:1; /* control/data */ uint8_t resvd2:2; uint8_t bpv:1; /* bit pointer valid */ uint8_t sim:3; /* system information message */ #endif uint8_t field[2]; /* field pointer */ uint8_t addSenseData[109]; } SCSI_PAGE_SENSE; #endif /* _SCSI_LLI_H */ bareos-Release-14.2.6/src/lib/scsi_tapealert.c000066400000000000000000000065141263011562700211510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Low level SCSI interface for SCSI TapeAlert services. * * Marco van Wieringen, November 2013 */ #include "bareos.h" /* Forward referenced functions */ #ifdef HAVE_LOWLEVEL_SCSI_INTERFACE #include "scsi_tapealert.h" /* * Store a value as 2 bytes MSB/LSB */ static inline void set_2_byte_value(unsigned char *field, int value) { field[0] = (unsigned char)((value & 0xff00) >> 8); field[1] = (unsigned char)(value & 0x00ff); } bool get_tapealert_flags(int fd, const char *device_name, uint64_t *flags) { LOG_SCSI_CDB cdb; TAPEALERT_PAGE_BUFFER cmd_page; int cmd_page_len, cdb_len; int tapealert_length, cnt; *flags = 0; cmd_page_len = sizeof(cmd_page); memset(&cmd_page, 0, cmd_page_len); /* * Fill the SCSI CDB. */ cdb_len = sizeof(cdb); memset(&cdb, 0, cdb_len); cdb.opcode = SCSI_LOG_OPCODE; cdb.pagecode = SCSI_TAPE_ALERT_FLAGS; set_2_byte_value(cdb.allocation_length, cmd_page_len); /* * Retrieve the tapealert status. */ if (!recv_scsi_cmd_page(fd, device_name, (void *)&cdb, cdb_len, (void *)&cmd_page, cmd_page_len)) { return false; } /* * See if we got TapeAlert info back. */ if ((cmd_page.pagecode & 0x3f) != SCSI_TAPE_ALERT_FLAGS) { return false; } tapealert_length = (cmd_page.page_length[0] << 8) + cmd_page.page_length[1]; if (!tapealert_length) { return true; } /* * Walk over all tape alert parameters. */ cnt = 0; while (cnt < tapealert_length) { uint16_t result_index; TAPEALERT_PARAMETER *ta_param; ta_param = (TAPEALERT_PARAMETER *)&cmd_page.log_parameters[cnt]; result_index = (ta_param->parameter_code[0] << 8) + ta_param->parameter_code[1]; if (result_index > 0 && result_index < MAX_TAPE_ALERTS) { /* * See if the TapeAlert is raised. */ if (ta_param->parameter_value) { for (int j = 0; tapealert_mappings[j].alert_msg; j++) { if (result_index == tapealert_mappings[j].flag) { Dmsg2(100, "TapeAlert [%d] set ==> %s\n", result_index, tapealert_mappings[j].alert_msg); set_bit(result_index, (char *)flags); } } } } cnt += ((sizeof(TAPEALERT_PARAMETER) - 1) + ta_param->parameter_length); } return false; } #else bool get_tapealert_flags(int fd, const char *device_name, uint64_t *flags) { *flags = 0; return false; } #endif /* HAVE_LOWLEVEL_SCSI_INTERFACE */ bareos-Release-14.2.6/src/lib/scsi_tapealert.h000066400000000000000000000206001263011562700211460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Marco van Wieringen, November 2013 */ #ifndef SCSI_TAPEALERT_H #define SCSI_TAPEALERT_H 1 /* * Include the SCSI Low Level Interface functions and definitions. */ #include "scsi_lli.h" #define MAX_TAPE_ALERTS 64 /* * SCSI CDB opcodes */ enum { SCSI_LOG_OPCODE = 0x4d }; enum { SCSI_TAPE_ALERT_FLAGS = 0x2e }; /* * SCSI Control Descriptor Block */ typedef struct { uint8_t opcode; /* Operation Code See SCSI_*_OPCODE */ uint8_t res_bits_1[1]; /* Reserved, 1 byte */ uint8_t pagecode; /* Page Code, 1 byte */ uint8_t res_bits_2[2]; /* Reserved, 2 bytes */ uint8_t parameter_pointer[2]; /* Parameter Pointer, 2 bytes, 1 bytes MSB and 1 bytes LSB */ uint8_t allocation_length[2]; /* Allocation Length, 2 bytes, 1 bytes MSB and 1 bytes LSB */ uint8_t control_byte; /* Control Byte */ } LOG_SCSI_CDB; typedef struct { uint8_t pagecode; /* Page Code, 1 byte */ uint8_t res_bits_1[1]; /* Reserved, 1 byte */ uint8_t page_length[2]; /* Page Length, 2 bytes, 1 bytes MSB and 1 bytes LSB */ uint8_t log_parameters[2044]; /* Log parameters (2048 bytes - 4 bytes header) */ } TAPEALERT_PAGE_BUFFER; typedef struct { uint8_t parameter_code[2]; /* Parameter Code, 2 bytes */ #if HAVE_BIG_ENDIAN uint8_t parameter_length; /* Parameter Length, 1 byte */ uint8_t disable_update:1; /* DU: Will be set to 0. The library will always update values reflected by the log parameters. */ uint8_t disable_save:1; /* DS: Will be set to 1. The library does not support saving of log parameters. */ uint8_t target_save_disabled:1; /* TSD: Will be set to 0. The library provides a self-defined method for saving log parameters. */ uint8_t enable_threshold_comparison:1; /* ETC: Will be set to 0. No comparison to threshold values is made. */ uint8_t threshold_met_criteria:2; /* TMC: Will be set to 0. Comparison to threshold values is not supported. */ uint8_t list_parameter_binary:1; /* LBIN: This field is only valid if LP is set to 1. When LBIN is set to 0, the list * parameter is ASCII. When LBIN is set to 1, the list parameter is a binary value. */ uint8_t list_parameter:1; /* LP: This field will be set to 0 for data counters and set to 1 for list parameters */ #else uint8_t list_parameter:1; /* LP: This field will be set to 0 for data counters and set to 1 for list parameters */ uint8_t list_parameter_binary:1; /* LBIN: This field is only valid if LP is set to 1. When LBIN is set to 0, the list * parameter is ASCII. When LBIN is set to 1, the list parameter is a binary value. */ uint8_t threshold_met_criteria:2; /* TMC: Will be set to 0. Comparison to threshold values is not supported. */ uint8_t enable_threshold_comparison:1; /* ETC: Will be set to 0. No comparison to threshold values is made. */ uint8_t target_save_disabled:1; /* TSD: Will be set to 0. The library provides a self-defined method for saving log parameters. */ uint8_t disable_save:1; /* DS: Will be set to 1. The library does not support saving of log parameters. */ uint8_t disable_update:1; /* DU: Will be set to 0. The library will always update values reflected by the log parameters. */ uint8_t parameter_length; /* Parameter Length, 1 byte */ #endif uint8_t parameter_value; /* Parameter Value, n bytes */ } TAPEALERT_PARAMETER; struct tapealert_mapping { uint32_t flag; const char *alert_msg; }; static tapealert_mapping tapealert_mappings[] = { { 0x01, (const char *)"Having problems reading (slowing down)" }, { 0x02, (const char *)"Having problems writing (losing capacity)" }, { 0x03, (const char *)"Uncorrectable read/write error" }, { 0x04, (const char *)"Media Performance Degraded, Data Is At Risk" }, { 0x05, (const char *)"Read Failure" }, { 0x06, (const char *)"Write Failure" }, { 0x07, (const char *)"Media has reached the end of its useful life" }, { 0x08, (const char *)"Cartridge not data grade" }, { 0x09, (const char *)"Cartridge write protected" }, { 0x0A, (const char *)"Initiator is preventing media removal" }, { 0x0B, (const char *)"Cleaning media found instead of data media" }, { 0x0C, (const char *)"Cartridge contains data in an unsupported format" }, { 0x0D, (const char *)"Recoverable mechanical cartridge failure (broken tape?)" }, { 0x0E, (const char *)"Unrecoverable mechanical cartridge failure (broken tape?)" }, { 0x0F, (const char *)"Failure of cartridge memory chip" }, { 0x10, (const char *)"Forced eject of media" }, { 0x11, (const char *)"Read only media loaded" }, { 0x12, (const char *)"Tape directory corrupted on load" }, { 0x13, (const char *)"Media nearing end of life" }, { 0x14, (const char *)"Tape drive neads cleaning NOW" }, { 0x15, (const char *)"Tape drive needs to be cleaned soon" }, { 0x16, (const char *)"Cleaning cartridge used up" }, { 0x17, (const char *)"Invalid cleaning cartidge used" }, { 0x18, (const char *)"Retension requested" }, { 0x19, (const char *)"Dual port interface failed" }, { 0x1A, (const char *)"Cooling fan in drive has failed" }, { 0x1B, (const char *)"Power supply failure in drive" }, { 0x1C, (const char *)"Power consumption outside specified range" }, { 0x1D, (const char *)"Preventative maintenance needed on drive" }, { 0x1E, (const char *)"Hardware A: Tape drive has a problem not read/write related" }, { 0x1F, (const char *)"Hardware B: Tape drive has a problem not read/write related" }, { 0x20, (const char *)"Problem with SCSI interface between tape drive and initiator" }, { 0x21, (const char *)"The current operation has failed. Eject and reload media" }, { 0x22, (const char *)"Attempt to download new firmware failed" }, { 0x23, (const char *)"Drive humidity outside operational range" }, { 0x24, (const char *)"Drive temperature outside operational range" }, { 0x25, (const char *)"Drive voltage outside operational range" }, { 0x26, (const char *)"Failure of drive predicted soon" }, { 0x27, (const char *)"Diagnostics required" }, /* * 0x28 to 0x2E are obsolete, but some vendors still have them listed. */ { 0x28, (const char *)"Loader Hardware A: Changer having problems communicating with tape drive" }, { 0x29, (const char *)"Loader Stray Tape: Stray tape left in drive from prior error" }, { 0x2A, (const char *)"Loader Hardware B: Autoloader mechanism has a fault" }, { 0x2B, (const char *)"Loader Door: Loader door is open, please close it" }, /* * 0x2F to 0x31 are reserved */ { 0x32, (const char *)"Media statistics lost" }, { 0x33, (const char *)"Tape directory invalid at unload (reread all to rebuild)" }, { 0x34, (const char *)"Tape system area write failure" }, { 0x35, (const char *)"Tape system area read failure" }, { 0x36, (const char *)"Start of data not found" }, { 0x37, (const char *)"Media could not be loaded/threaded" }, { 0x38, (const char *)"Unrecoverable unload failed" }, { 0x39, (const char *)"Automation interface failure" }, { 0x3A, (const char *)"Firmware failure" }, /* * 0x3B to 0x40 are reserved */ { 0, NULL } }; #endif /* SCSI_TAPEALERT_H */ bareos-Release-14.2.6/src/lib/sellist.c000066400000000000000000000106131263011562700176210ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January MMXII * * Selection list. A string of integers separated by commas * representing items selected. Ranges of the form nn-mm * are also permitted. */ #include "bareos.h" /* * Returns next item * error if returns -1 and errmsg set * end of items if returns -1 and errmsg NULL */ int64_t sellist::next() { errmsg = NULL; if (beg <= end) { return beg++; } if (e == NULL) { goto bail_out; } /* * As we walk the list, we set EOF in * the end of the next item to ease scanning, * but save and then restore the character. */ for (p=e; p && *p; p=e) { /* Check for list */ e = strchr(p, ','); if (e) { esave = *e; *e++ = 0; } else { esave = 0; } /* Check for range */ h = strchr(p, '-'); /* range? */ if (h == p) { errmsg = _("Negative numbers not permitted.\n"); goto bail_out; } if (h) { hsave = *h; *h++ = 0; if (!is_an_integer(h)) { errmsg = _("Range end is not integer.\n"); goto bail_out; } skip_spaces(&p); if (!is_an_integer(p)) { errmsg = _("Range start is not an integer.\n"); goto bail_out; } beg = str_to_int64(p); end = str_to_int64(h); if (end < beg) { errmsg = _("Range end not bigger than start.\n"); goto bail_out; } } else { hsave = 0; skip_spaces(&p); if (!is_an_integer(p)) { errmsg = _("Input value is not an integer.\n"); goto bail_out; } beg = end = str_to_int64(p); } if (esave) { *(e-1) = esave; } if (hsave) { *(h-1) = hsave; } if (beg <= 0 || end <= 0) { errmsg = _("Selection items must be be greater than zero.\n"); goto bail_out; } if (end > max) { errmsg = _("Selection item too large.\n"); goto bail_out; } if (beg <= end) { return beg++; } } /* End of items */ errmsg = NULL; /* No error */ return -1; bail_out: return -1; /* Error, errmsg set */ } /* * Set selection string and optionally scan it * returns false on error in string * returns true if OK */ bool sellist::set_string(char *string, bool scan=true) { /* * Copy string, because we write into it, * then scan through it once to find any * errors. */ if (str) { free(str); } e = str = bstrdup(string); end = 0; beg = 1; num_items = 0; if (scan) { while (next() >= 0) { num_items++; } if (get_errmsg()) { return false; } e = str; end = 0; beg = 1; } return true; } #ifdef TEST_PROGRAM int main(int argc, char **argv, char **env) { char *msg; sellist sl; int i; if (!argv[1]) { msg = _("No input string given.\n"); goto bail_out; } Dmsg1(000, "argv[1]=%s\n", argv[1]); strip_trailing_junk(argv[1]); sl.set_string(argv[1]); if ((msg = sl.get_errmsg())) { goto bail_out; } while ((i=sl.next()) >= 0) { Dmsg1(000, "%d\n", i); } if ((msg = sl.get_errmsg())) { goto bail_out; } printf("\nPass 2\n"); sl.set_string(argv[1]); while ((i=sl.next()) >= 0) { Dmsg1(000, "%d\n", i); } if ((msg = sl.get_errmsg())) { goto bail_out; } return 0; bail_out: Dmsg1(000, "Error: %s\n", msg); return 1; } #endif /* TEST_PROGRAM */ bareos-Release-14.2.6/src/lib/sellist.h000066400000000000000000000043561263011562700176350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January MMXII * * Selection list. A string of integers separated by commas * representing items selected. Ranges of the form nn-mm * are also permitted. */ /* * Loop var through each member of list */ #define foreach_sellist(var, list) \ for((var)=(list)->first(); (var)>=0; (var)=(list)->next() ) class sellist : public SMARTALLOC { const char *errmsg; char *p, *e, *h; char esave, hsave; int64_t beg, end; int64_t max; int num_items; char *str; public: sellist(); ~sellist(); bool set_string(char *string, bool scan); int64_t first(); int64_t next(); void begin(); /* size() valid only if scan enabled on string */ int size() const { return num_items; }; char *get_list() { return str; }; /* if errmsg == NULL, no error */ const char *get_errmsg() { return errmsg; }; }; /* * Initialize the list structure */ inline sellist::sellist() { num_items = 0; max = 99999; str = NULL; e = NULL; errmsg = NULL; } /* * Destroy the list */ inline sellist::~sellist() { if (str) { free(str); str = NULL; } } /* * Returns first item * error if returns -1 and errmsg set * end of items if returns -1 and errmsg NULL */ inline int64_t sellist::first() { begin(); return next(); } /* * Reset to walk list from beginning */ inline void sellist::begin() { e = str; end = 0; beg = 1; errmsg = NULL; } bareos-Release-14.2.6/src/lib/serial.c000066400000000000000000000172531263011562700174300ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Serialisation Support Functions John Walker */ #include "bareos.h" #include "serial.h" /* NOTE: The following functions should work on any vaguely contemporary platform. Production builds should use optimised macros (void on platforms with network byte order and IEEE floating point format as native. */ /* serial_int16 -- Serialise a signed 16 bit integer. */ void serial_int16(uint8_t * * const ptr, const int16_t v) { int16_t vo = htons(v); memcpy(*ptr, &vo, sizeof vo); *ptr += sizeof vo; } /* serial_uint16 -- Serialise an unsigned 16 bit integer. */ void serial_uint16(uint8_t * * const ptr, const uint16_t v) { uint16_t vo = htons(v); memcpy(*ptr, &vo, sizeof vo); *ptr += sizeof vo; } /* serial_int32 -- Serialise a signed 32 bit integer. */ void serial_int32(uint8_t * * const ptr, const int32_t v) { int32_t vo = htonl(v); memcpy(*ptr, &vo, sizeof vo); *ptr += sizeof vo; } /* serial_uint32 -- Serialise an unsigned 32 bit integer. */ void serial_uint32(uint8_t * * const ptr, const uint32_t v) { uint32_t vo = htonl(v); memcpy(*ptr, &vo, sizeof vo); *ptr += sizeof vo; } /* serial_int64 -- Serialise a signed 64 bit integer. */ void serial_int64(uint8_t * * const ptr, const int64_t v) { if (bigendian()) { memcpy(*ptr, &v, sizeof(int64_t)); } else { int i; uint8_t rv[sizeof(int64_t)]; uint8_t *pv = (uint8_t *) &v; for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(*ptr, &rv, sizeof(int64_t)); } *ptr += sizeof(int64_t); } /* serial_uint64 -- Serialise an unsigned 64 bit integer. */ void serial_uint64(uint8_t * * const ptr, const uint64_t v) { if (bigendian()) { memcpy(*ptr, &v, sizeof(uint64_t)); } else { int i; uint8_t rv[sizeof(uint64_t)]; uint8_t *pv = (uint8_t *) &v; for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(*ptr, &rv, sizeof(uint64_t)); } *ptr += sizeof(uint64_t); } /* serial_btime -- Serialise an btime_t 64 bit integer. */ void serial_btime(uint8_t * * const ptr, const btime_t v) { if (bigendian()) { memcpy(*ptr, &v, sizeof(btime_t)); } else { int i; uint8_t rv[sizeof(btime_t)]; uint8_t *pv = (uint8_t *) &v; for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(*ptr, &rv, sizeof(btime_t)); } *ptr += sizeof(btime_t); } /* serial_float64 -- Serialise a 64 bit IEEE floating point number. This code assumes that the host floating point format is IEEE and that floating point quantities are stored in IEEE format either LSB first or MSB first. More creative host formats will require additional transformations here. */ void serial_float64(uint8_t * * const ptr, const float64_t v) { if (bigendian()) { memcpy(*ptr, &v, sizeof(float64_t)); } else { int i; uint8_t rv[sizeof(float64_t)]; uint8_t *pv = (uint8_t *) &v; for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(*ptr, &rv, sizeof(float64_t)); } *ptr += sizeof(float64_t); } void serial_string(uint8_t * * const ptr, const char * const str) { int i; char *dest = (char *)*ptr; char *src = (char *)str; for (i=0; src[i] != 0; i++) { dest[i] = src[i]; } dest[i++] = 0; /* terminate output string */ *ptr += i; /* update pointer */ // Dmsg2(000, "ser src=%s dest=%s\n", src, dest); } /* unserial_int16 -- Unserialise a signed 16 bit integer. */ int16_t unserial_int16(uint8_t * * const ptr) { int16_t vo; memcpy(&vo, *ptr, sizeof vo); *ptr += sizeof vo; return ntohs(vo); } /* unserial_uint16 -- Unserialise an unsigned 16 bit integer. */ uint16_t unserial_uint16(uint8_t * * const ptr) { uint16_t vo; memcpy(&vo, *ptr, sizeof vo); *ptr += sizeof vo; return ntohs(vo); } /* unserial_int32 -- Unserialise a signed 32 bit integer. */ int32_t unserial_int32(uint8_t * * const ptr) { int32_t vo; memcpy(&vo, *ptr, sizeof vo); *ptr += sizeof vo; return ntohl(vo); } /* unserial_uint32 -- Unserialise an unsigned 32 bit integer. */ uint32_t unserial_uint32(uint8_t * * const ptr) { uint32_t vo; memcpy(&vo, *ptr, sizeof vo); *ptr += sizeof vo; return ntohl(vo); } /* unserial_uint64 -- Unserialise an unsigned 64 bit integer. */ uint64_t unserial_uint64(uint8_t * * const ptr) { uint64_t v; if (bigendian()) { memcpy(&v, *ptr, sizeof(uint64_t)); } else { int i; uint8_t rv[sizeof(uint64_t)]; uint8_t *pv = (uint8_t *) &v; memcpy(&v, *ptr, sizeof(uint64_t)); for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(&v, &rv, sizeof(uint64_t)); } *ptr += sizeof(uint64_t); return v; } /* unserial_btime -- Unserialise a btime_t 64 bit integer. */ btime_t unserial_btime(uint8_t * * const ptr) { btime_t v; if (bigendian()) { memcpy(&v, *ptr, sizeof(btime_t)); } else { int i; uint8_t rv[sizeof(btime_t)]; uint8_t *pv = (uint8_t *) &v; memcpy(&v, *ptr, sizeof(btime_t)); for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(&v, &rv, sizeof(btime_t)); } *ptr += sizeof(btime_t); return v; } /* unserial_float64 -- Unserialise a 64 bit IEEE floating point number. This code assumes that the host floating point format is IEEE and that floating point quantities are stored in IEEE format either LSB first or MSB first. More creative host formats will require additional transformations here. */ float64_t unserial_float64(uint8_t * * const ptr) { float64_t v; if (bigendian()) { memcpy(&v, *ptr, sizeof(float64_t)); } else { int i; uint8_t rv[sizeof(float64_t)]; uint8_t *pv = (uint8_t *) &v; memcpy(&v, *ptr, sizeof(float64_t)); for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; } memcpy(&v, &rv, sizeof(float64_t)); } *ptr += sizeof(float64_t); return v; } void unserial_string(uint8_t * * const ptr, char * const str, int max) { int i; char *src = (char*)(*ptr); char *dest = str; for (i=0; i 100% Public Domain Test Vectors (from FIPS PUB 180-1) "abc" A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 A million repetitions of "a" 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ #include "bareos.h" #if !defined(HAVE_OPENSSL) || defined(HAVE_WIN32) /* #define LITTLE_ENDIAN * This should be #define'd if true. */ #if __LITTLE_ENDIAN__ #define LITTLE_ENDIAN #endif /* #define SHA1HANDSOFF * Copies data before messing with it. */ #include "sha1.h" void SHA1Transform(u_int32_t state[5], const u_int8_t buffer[64]); #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ #ifdef LITTLE_ENDIAN #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ |(rol(block->l[i],8)&0x00FF00FF)) #else #define blk0(i) block->l[i] #endif #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); /* Hash a single 512-bit block. This is the core of the algorithm. */ void SHA1Transform(u_int32_t state[5], const u_int8_t buffer[64]) { u_int32_t a, b, c, d, e; typedef union { u_int8_t c[64]; u_int32_t l[16]; } CHAR64LONG16; CHAR64LONG16* block; #ifdef SHA1HANDSOFF static u_int8_t workspace[64]; block = (CHAR64LONG16*)workspace; memcpy(block, buffer, 64); #else block = (CHAR64LONG16*)buffer; #endif /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; } /* SHA1Init - Initialize new context */ void SHA1Init(SHA1_CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = context->count[1] = 0; } /* Run your data through this. */ void SHA1Update(SHA1_CTX* context, const u_int8_t* data, unsigned int len) { unsigned int i, j; j = (context->count[0] >> 3) & 63; if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; context->count[1] += (len >> 29); if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); SHA1Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { SHA1Transform(context->state, &data[i]); } j = 0; } else i = 0; memcpy(&context->buffer[j], &data[i], len - i); } /* Add padding and return the message digest. */ void SHA1Final(u_int8_t digest[20], SHA1_CTX* context) { u_int32_t i, j; u_int8_t finalcount[8]; for (i = 0; i < 8; i++) { finalcount[i] = (u_int8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1Update(context, (u_int8_t *)"\200", 1); while ((context->count[0] & 504) != 448) { SHA1Update(context, (u_int8_t *)"\0", 1); } SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < 20; i++) { digest[i] = (u_int8_t) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ i = j = 0; memset(context->buffer, 0, 64); memset(context->state, 0, 20); memset(context->count, 0, 8); memset(&finalcount, 0, 8); #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ SHA1Transform(context->state, context->buffer); #endif } #endif /* !defined(HAVE_OPENSSL) || defined(HAVE_WIN32) */ bareos-Release-14.2.6/src/lib/sha1.h000066400000000000000000000013441263011562700170040ustar00rootroot00000000000000/* $OpenBSD: sha1.h,v 1.5 2007/09/10 22:19:42 henric Exp $ */ /* * SHA-1 in C * By Steve Reid * 100% Public Domain */ #if defined(HAVE_OPENSSL) && !defined(HAVE_WIN32) #include #elif !defined(_SHA1_H_) #define _SHA1_H_ #define SHA1_BLOCK_LENGTH 64 #define SHA1_DIGEST_LENGTH 20 typedef struct { u_int32_t state[5]; u_int32_t count[2]; unsigned char buffer[SHA1_BLOCK_LENGTH]; } SHA1_CTX; void SHA1Init(SHA1_CTX * context); void SHA1Transform(u_int32_t state[5], const unsigned char buffer[SHA1_BLOCK_LENGTH]); void SHA1Update(SHA1_CTX *context, const unsigned char *data, unsigned int len); void SHA1Final(unsigned char digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context); #endif /* _SHA1_H_ */ bareos-Release-14.2.6/src/lib/signal.c000066400000000000000000000321151263011562700174200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Signal handlers for BAREOS daemons * * Kern Sibbald, April 2000 * * Note, we probably should do a core dump for the serious * signals such as SIGBUS, SIGPFE, ... * Also, for SIGHUP and SIGUSR1, we should re-read the * configuration file. However, since this is a "general" * routine, we leave it to the individual daemons to * tweak their signals after calling this routine. */ #ifndef HAVE_WIN32 #include "bareos.h" #ifndef _NSIG #define BA_NSIG 100 #else #define BA_NSIG _NSIG #endif extern char my_name[]; extern char *exepath; extern char *exename; extern bool prt_kaboom; static const char *sig_names[BA_NSIG + 1]; typedef void (SIG_HANDLER)(int sig); static SIG_HANDLER *exit_handler; /* main process id */ static pid_t main_pid = 0; const char *get_signal_name(int sig) { if (sig < 0 || sig > BA_NSIG || !sig_names[sig]) { return _("Invalid signal number"); } else { return sig_names[sig]; } } /* defined in jcr.c */ extern void dbg_print_jcr(FILE *fp); /* defined in plugins.c */ extern void dbg_print_plugin(FILE *fp); /* defined in lockmgr.c */ extern void dbg_print_lock(FILE *fp); /* * !!! WARNING !!! * * This function should be used ONLY after a violent signal. We walk through the * JCR chain without locking, BAREOS should not be running. */ static void dbg_print_bareos() { char buf[512]; snprintf(buf, sizeof(buf), "%s/%s.%d.bactrace", working_directory, my_name, (int)getpid()); FILE *fp = fopen(buf, "a+") ; if (!fp) { fp = stderr; } fprintf(stderr, "Dumping: %s\n", buf); /* Print also B_DB and RWLOCK structure * Can add more info about JCR with dbg_jcr_add_hook() */ dbg_print_lock(fp); dbg_print_jcr(fp); dbg_print_plugin(fp); if (fp != stderr) { #define direct_print #ifdef direct_print if (prt_kaboom) { rewind(fp); printf("\n\n ==== bactrace output ====\n\n"); while (fgets(buf, (int)sizeof(buf), fp) != NULL) { printf("%s", buf); } printf(" ==== End baktrace output ====\n\n"); } #else if (prt_kaboom) { char buf1[512]; printf("\n\n ==== bactrace output ====\n\n"); snprintf(buf1, sizeof(buf1), "/bin/cat %s", buf); system(buf1); printf(" ==== End baktrace output ====\n\n"); } #endif fclose(fp); } } /* * Handle signals here */ extern "C" void signal_handler(int sig) { static int already_dead = 0; int chld_status = -1; /* * If we come back more than once, get out fast! */ if (already_dead) { exit(1); } Dmsg2(900, "sig=%d %s\n", sig, sig_names[sig]); /* * Ignore certain signals -- SIGUSR2 used to interrupt threads */ if (sig == SIGCHLD || sig == SIGUSR2) { return; } already_dead++; /* * Don't use Emsg here as it may lock and thus block us */ if (sig == SIGTERM) { syslog(LOG_DAEMON | LOG_ERR, "Shutting down BAREOS service: %s ...\n", my_name); } else { fprintf(stderr, _("BAREOS interrupted by signal %d: %s\n"), sig, get_signal_name(sig)); syslog(LOG_DAEMON | LOG_ERR, _("BAREOS interrupted by signal %d: %s\n"), sig, get_signal_name(sig)); } #ifdef TRACEBACK if (sig != SIGTERM) { struct sigaction sigdefault; static char *argv[5]; static char pid_buf[20]; static char btpath[400]; char buf[400]; pid_t pid; int exelen = strlen(exepath); fprintf(stderr, _("Kaboom! %s, %s got signal %d - %s. Attempting traceback.\n"), exename, my_name, sig, get_signal_name(sig)); fprintf(stderr, _("Kaboom! exepath=%s\n"), exepath); if (exelen + 12 > (int)sizeof(btpath)) { bstrncpy(btpath, "btraceback", sizeof(btpath)); } else { bstrncpy(btpath, exepath, sizeof(btpath)); if (IsPathSeparator(btpath[exelen-1])) { btpath[exelen-1] = 0; } bstrncat(btpath, "/btraceback", sizeof(btpath)); } if (!IsPathSeparator(exepath[exelen - 1])) { strcat(exepath, "/"); } strcat(exepath, exename); if (!working_directory) { working_directory = buf; *buf = 0; } if (*working_directory == 0) { strcpy((char *)working_directory, "/tmp/"); } if (chdir(working_directory) != 0) { /* dump in working directory */ berrno be; Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory, be.bstrerror()); strcpy((char *)working_directory, "/tmp/"); } unlink("./core"); /* get rid of any old core file */ #ifdef DEVELOPER /* When DEVELOPER not set, this is done below */ /* * Print information about the current state into working/.bactrace */ dbg_print_bareos(); #endif sprintf(pid_buf, "%d", (int)main_pid); Dmsg1(300, "Working=%s\n", working_directory); Dmsg1(300, "btpath=%s\n", btpath); Dmsg1(300, "exepath=%s\n", exepath); switch (pid = fork()) { case -1: /* error */ fprintf(stderr, _("Fork error: ERR=%s\n"), strerror(errno)); break; case 0: /* child */ argv[0] = btpath; /* path to btraceback */ argv[1] = exepath; /* path to exe */ argv[2] = pid_buf; argv[3] = (char *)working_directory; argv[4] = (char *)NULL; fprintf(stderr, _("Calling: %s %s %s %s\n"), btpath, exepath, pid_buf, working_directory); if (execv(btpath, argv) != 0) { berrno be; printf(_("execv: %s failed: ERR=%s\n"), btpath, be.bstrerror()); } exit(-1); default: /* parent */ break; } /* * Parent continue here, waiting for child */ sigdefault.sa_flags = 0; sigdefault.sa_handler = SIG_DFL; sigfillset(&sigdefault.sa_mask); sigaction(sig, &sigdefault, NULL); if (pid > 0) { Dmsg0(500, "Doing waitpid\n"); waitpid(pid, &chld_status, 0); /* wait for child to produce dump */ Dmsg0(500, "Done waitpid\n"); } else { Dmsg0(500, "Doing sleep\n"); bmicrosleep(30, 0); } if (WEXITSTATUS(chld_status) == 0) { fprintf(stderr, _("It looks like the traceback worked...\n")); } else { fprintf(stderr, _("The btraceback call returned %d\n"), WEXITSTATUS(chld_status)); } /* * If we want it printed, do so */ #ifdef direct_print if (prt_kaboom) { FILE *fd; snprintf(buf, sizeof(buf), "%s/bareos.%s.traceback", working_directory, pid_buf); fd = fopen(buf, "r"); if (fd != NULL) { printf("\n\n ==== Traceback output ====\n\n"); while (fgets(buf, (int)sizeof(buf), fd) != NULL) { printf("%s", buf); } fclose(fd); printf(" ==== End traceback output ====\n\n"); } } #else if (prt_kaboom) { snprintf(buf, sizeof(buf), "/bin/cat %s/bareos.%s.traceback", working_directory, pid_buf); fprintf(stderr, "\n\n ==== Traceback output ====\n\n"); system(buf); fprintf(stderr, " ==== End traceback output ====\n\n"); } #endif #ifndef DEVELOPER /* When DEVELOPER set, this is done above */ /* * Print information about the current state into working/.bactrace */ dbg_print_bareos(); #endif } #endif exit_handler(sig); Dmsg0(500, "Done exit_handler\n"); } /* * Init stack dump by saving main process id -- needed by debugger to attach to this program. */ void init_stack_dump(void) { main_pid = getpid(); /* save main thread's pid */ } /* * Initialize signals */ void init_signals(void terminate(int sig)) { struct sigaction sighandle; struct sigaction sigignore; struct sigaction sigdefault; #ifdef _sys_nsig int i; exit_handler = terminate; if (BA_NSIG < _sys_nsig) { Emsg2(M_ABORT, 0, _("BA_NSIG too small (%d) should be (%d)\n"), BA_NSIG, _sys_nsig); } for (i = 0; i < _sys_nsig; i++) { sig_names[i] = _sys_siglist[i]; } #else exit_handler = terminate; sig_names[0] = _("UNKNOWN SIGNAL"); sig_names[SIGHUP] = _("Hangup"); sig_names[SIGINT] = _("Interrupt"); sig_names[SIGQUIT] = _("Quit"); sig_names[SIGILL] = _("Illegal instruction"); sig_names[SIGTRAP] = _("Trace/Breakpoint trap"); sig_names[SIGABRT] = _("Abort"); #ifdef SIGEMT sig_names[SIGEMT] = _("EMT instruction (Emulation Trap)"); #endif #ifdef SIGIOT sig_names[SIGIOT] = _("IOT trap"); #endif sig_names[SIGBUS] = _("BUS error"); sig_names[SIGFPE] = _("Floating-point exception"); sig_names[SIGKILL] = _("Kill, unblockable"); sig_names[SIGUSR1] = _("User-defined signal 1"); sig_names[SIGSEGV] = _("Segmentation violation"); sig_names[SIGUSR2] = _("User-defined signal 2"); sig_names[SIGPIPE] = _("Broken pipe"); sig_names[SIGALRM] = _("Alarm clock"); sig_names[SIGTERM] = _("Termination"); #ifdef SIGSTKFLT sig_names[SIGSTKFLT] = _("Stack fault"); #endif sig_names[SIGCHLD] = _("Child status has changed"); sig_names[SIGCONT] = _("Continue"); sig_names[SIGSTOP] = _("Stop, unblockable"); sig_names[SIGTSTP] = _("Keyboard stop"); sig_names[SIGTTIN] = _("Background read from tty"); sig_names[SIGTTOU] = _("Background write to tty"); sig_names[SIGURG] = _("Urgent condition on socket"); sig_names[SIGXCPU] = _("CPU limit exceeded"); sig_names[SIGXFSZ] = _("File size limit exceeded"); sig_names[SIGVTALRM] = _("Virtual alarm clock"); sig_names[SIGPROF] = _("Profiling alarm clock"); sig_names[SIGWINCH] = _("Window size change"); sig_names[SIGIO] = _("I/O now possible"); #ifdef SIGPWR sig_names[SIGPWR] = _("Power failure restart"); #endif #ifdef SIGWAITING sig_names[SIGWAITING] = _("No runnable lwp"); #endif #ifdef SIGLWP sig_names[SIGLWP] = _("SIGLWP special signal used by thread library"); #endif #ifdef SIGFREEZE sig_names[SIGFREEZE] = _("Checkpoint Freeze"); #endif #ifdef SIGTHAW sig_names[SIGTHAW] = _("Checkpoint Thaw"); #endif #ifdef SIGCANCEL sig_names[SIGCANCEL] = _("Thread Cancellation"); #endif #ifdef SIGLOST sig_names[SIGLOST] = _("Resource Lost (e.g. record-lock lost)"); #endif #endif /* * Now setup signal handlers */ sighandle.sa_flags = 0; sighandle.sa_handler = signal_handler; sigfillset(&sighandle.sa_mask); sigignore.sa_flags = 0; sigignore.sa_handler = SIG_IGN; sigfillset(&sigignore.sa_mask); sigdefault.sa_flags = 0; sigdefault.sa_handler = SIG_DFL; sigfillset(&sigdefault.sa_mask); sigaction(SIGPIPE, &sigignore, NULL); sigaction(SIGCHLD, &sighandle, NULL); sigaction(SIGCONT, &sigignore, NULL); sigaction(SIGPROF, &sigignore, NULL); sigaction(SIGWINCH, &sigignore, NULL); sigaction(SIGIO, &sighandle, NULL); sigaction(SIGINT, &sigdefault, NULL); sigaction(SIGXCPU, &sigdefault, NULL); sigaction(SIGXFSZ, &sigdefault, NULL); sigaction(SIGHUP, &sigignore, NULL); sigaction(SIGQUIT, &sighandle, NULL); sigaction(SIGILL, &sighandle, NULL); sigaction(SIGTRAP, &sighandle, NULL); sigaction(SIGABRT, &sighandle, NULL); #ifdef SIGEMT sigaction(SIGEMT, &sighandle, NULL); #endif #ifdef SIGIOT sigaction(SIGIOT, &sighandle, NULL); #endif sigaction(SIGBUS, &sighandle, NULL); sigaction(SIGFPE, &sighandle, NULL); sigaction(SIGUSR1, &sighandle, NULL); sigaction(SIGSEGV, &sighandle, NULL); sigaction(SIGUSR2, &sighandle, NULL); sigaction(SIGALRM, &sighandle, NULL); sigaction(SIGTERM, &sighandle, NULL); #ifdef SIGSTKFLT sigaction(SIGSTKFLT, &sighandle, NULL); #endif sigaction(SIGTSTP, &sigdefault, NULL); sigaction(SIGTTIN, &sighandle, NULL); sigaction(SIGTTOU, &sighandle, NULL); sigaction(SIGURG, &sighandle, NULL); sigaction(SIGVTALRM, &sighandle, NULL); #ifdef SIGPWR sigaction(SIGPWR, &sighandle, NULL); #endif #ifdef SIGWAITING sigaction(SIGWAITING,&sighandle, NULL); #endif #ifdef SIGLWP sigaction(SIGLWP, &sighandle, NULL); #endif #ifdef SIGFREEZE sigaction(SIGFREEZE, &sighandle, NULL); #endif #ifdef SIGTHAW sigaction(SIGTHAW, &sighandle, NULL); #endif #ifdef SIGCANCEL sigaction(SIGCANCEL, &sighandle, NULL); #endif #ifdef SIGLOST sigaction(SIGLOST, &sighandle, NULL); #endif } #endif bareos-Release-14.2.6/src/lib/smartall.c000066400000000000000000000422561263011562700177710ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* S M A R T A L L O C Smart Memory Allocator Evolved over several years, starting with the initial SMARTALLOC code for AutoSketch in 1986, guided by the Blind Watchbreaker, John Walker. Isolated in this general-purpose form in September of 1989. Updated with be more POSIX compliant and to include Web-friendly HTML documentation in October of 1998 by the same culprit. For additional information and the current version visit the Web page: http://www.fourmilab.ch/smartall/ */ #define _LOCKMGR_COMPLIANT #include "bareos.h" /* * Use the real routines here */ #undef realloc #undef calloc #undef malloc #undef free uint64_t sm_max_bytes = 0; uint64_t sm_bytes = 0; uint32_t sm_max_buffers = 0; uint32_t sm_buffers = 0; #ifdef SMARTALLOC static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; extern char my_name[]; /* Daemon name */ #define EOS '\0' /* End of string sentinel */ #define sm_min(a, b) ((a) < (b) ? (a) : (b)) /* * Queue data structures */ /* * Memory allocation control structures and storage. */ struct abufhead { struct b_queue abq; /* Links on allocated queue */ uint32_t ablen; /* Buffer length in bytes */ const char *abfname; /* File name pointer */ uint32_t ablineno; /* Line number of allocation */ bool abin_use; /* set when malloced and cleared when free */ }; /* * Allocated buffer queue */ static struct b_queue abqueue = { &abqueue, &abqueue }; static bool bufimode = false; /* Buffers not tracked when True */ #define HEAD_SIZE BALIGN(sizeof(struct abufhead)) /* * SMALLOC -- Allocate buffer, enqueing on the orphaned buffer tracking list. */ /* * Special version of error reporting using a static buffer so we don't use * the normal error reporting which uses dynamic memory e.g. recursivly calls * these routines again leading to deadlocks. */ static void smart_alloc_msg(const char *file, int line, const char *fmt, ...) { char buf[256]; va_list arg_ptr; int len; len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"), my_name, get_basename(file), line); va_start(arg_ptr, fmt); bvsnprintf(buf + len, sizeof(buf) - len, (char *)fmt, arg_ptr); va_end(arg_ptr); dispatch_message(NULL, M_ABORT, 0, buf); char *p = 0; p[0] = 0; /* Generate segmentation violation */ } static void *smalloc(const char *fname, int lineno, unsigned int nbytes) { char *buf; /* * Note: Unix MALLOC actually permits a zero length to be * passed and allocates a valid block with zero user bytes. * Such a block can later be expanded with realloc(). We * disallow this based on the belief that it's better to make * a special case and allocate one byte in the rare case this * is desired than to miss all the erroneous occurrences where * buffer length calculation code results in a zero. */ ASSERT(nbytes > 0); nbytes += HEAD_SIZE + 1; if ((buf = (char *)malloc(nbytes)) != NULL) { struct abufhead *head = (struct abufhead *)buf; P(mutex); /* * Enqueue buffer on allocated list */ qinsert(&abqueue, (struct b_queue *) buf); head->ablen = nbytes; head->abfname = bufimode ? NULL : fname; head->ablineno = (uint32_t)lineno; head->abin_use = true; /* * Emplace end-clobber detector at end of buffer */ buf[nbytes - 1] = (uint8_t)((((intptr_t) buf) & 0xFF) ^ 0xC5); /* * Increment to user data start */ buf += HEAD_SIZE; if (++sm_buffers > sm_max_buffers) { sm_max_buffers = sm_buffers; } sm_bytes += nbytes; if (sm_bytes > sm_max_bytes) { sm_max_bytes = sm_bytes; } V(mutex); } else { smart_alloc_msg(__FILE__, __LINE__, _("Out of memory\n")); } #if SMALLOC_SANITY_CHECK > 0 if (sm_bytes > SMALLOC_SANITY_CHECK) { smart_alloc_msg(__FILE__, __LINE__, _("Too much memory used.")); } #endif return (void *)buf; } /* SM_NEW_OWNER -- Update the File and line number for a buffer This is to accomodate mem_pool. */ void sm_new_owner(const char *fname, int lineno, char *buf) { buf -= HEAD_SIZE; /* Decrement to header */ ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname; ((struct abufhead *)buf)->ablineno = (uint32_t) lineno; ((struct abufhead *)buf)->abin_use = true; return; } /* SM_FREE -- Update free pool availability. FREE is never called except through this interface or by actuallyfree(). free(x) is defined to generate a call to this routine. */ void sm_free(const char *file, int line, void *fp) { char *cp = (char *) fp; struct b_queue *qp; uint32_t lineno = line; if (cp == NULL) { smart_alloc_msg(__FILE__, __LINE__, _("Attempt to free NULL called from %s:%d\n"), file, lineno); } cp -= HEAD_SIZE; qp = (struct b_queue *)cp; struct abufhead *head = (struct abufhead *)cp; P(mutex); if (!head->abin_use) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("double free from %s:%d\n"), file, lineno); } head->abin_use = false; /* The following assertions will catch virtually every release of an address which isn't an allocated buffer. */ if (qp->qnext->qprev != qp) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("qp->qnext->qprev != qp called from %s:%d\n"), file, lineno); } if (qp->qprev->qnext != qp) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("qp->qprev->qnext != qp called from %s:%d\n"), file, lineno); } /* The following assertion detects storing off the end of the allocated space in the buffer by comparing the end of buffer checksum with the address of the buffer. */ if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) { V(mutex); smart_alloc_msg(__FILE__, __LINE__, _("Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n"), head->ablen, fp, get_basename(head->abfname), head->ablineno, file, line); } if (sm_buffers > 0) { sm_buffers--; sm_bytes -= head->ablen; } qdchain(qp); V(mutex); /* Now we wipe the contents of the just-released buffer with "designer garbage" (Duff Kurland's phrase) of alternating bits. This is intended to ruin the day for any miscreant who attempts to access data through a pointer into storage that's been previously released. Modified, kes May, 2007 to not zap the header. This allows us to check the in_use bit and detect doubly freed buffers. */ memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE)); free(cp); } /* SM_MALLOC -- Allocate buffer. NULL is returned if no memory was available. */ void *sm_malloc(const char *fname, int lineno, unsigned int nbytes) { void *buf; if ((buf = smalloc(fname, lineno, nbytes)) != NULL) { /* To catch sloppy code that assumes buffers obtained from malloc() are zeroed, we preset the buffer contents to "designer garbage" consisting of alternating bits. */ memset(buf, 0x55, (int) nbytes); } else { smart_alloc_msg(__FILE__, __LINE__, _("Out of memory\n")); } return buf; } /* SM_CALLOC -- Allocate an array and clear it to zero. */ void *sm_calloc(const char *fname, int lineno, unsigned int nelem, unsigned int elsize) { void *buf; if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) { memset(buf, 0, (int) (nelem * elsize)); } else { smart_alloc_msg(__FILE__, __LINE__, _("Out of memory\n")); } return buf; } /* SM_REALLOC -- Adjust the size of a previously allocated buffer. Note that the trick of "resurrecting" a previously freed buffer with realloc() is NOT supported by this function. Further, because of the need to maintain our control storage, SM_REALLOC must always allocate a new block and copy the data in the old block. This may result in programs which make heavy use of realloc() running much slower than normally. */ void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size) { unsigned osize; void *buf; char *cp = (char *) ptr; if (size <= 0) { e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size); } /* If the old block pointer is NULL, treat realloc() as a malloc(). SVID is silent on this, but many C libraries permit this. */ if (ptr == NULL) { return sm_malloc(fname, lineno, size); } /* If the old and new sizes are the same, be a nice guy and just return the buffer passed in. */ cp -= HEAD_SIZE; struct abufhead *head = (struct abufhead *)cp; osize = head->ablen - (HEAD_SIZE + 1); if (size == osize) { return ptr; } /* Sizes differ. Allocate a new buffer of the requested size. If we can't obtain such a buffer, act as defined in SVID: return NULL from realloc() and leave the buffer in PTR intact. */ // sm_buffers--; // sm_bytes -= head->ablen; if ((buf = smalloc(fname, lineno, size)) != NULL) { memcpy(buf, ptr, (int)sm_min(size, osize)); /* If the new buffer is larger than the old, fill the balance of it with "designer garbage". */ if (size > osize) { memset(((char *) buf) + osize, 0x55, (int) (size - osize)); } /* All done. Free and dechain the original buffer. */ sm_free(fname, lineno, ptr); } return buf; } /* ACTUALLYMALLOC -- Call the system malloc() function to obtain storage which will eventually be released by system or library routines not compiled using SMARTALLOC. */ void *actuallymalloc(unsigned int size) { return malloc(size); } /* ACTUALLYCALLOC -- Call the system calloc() function to obtain storage which will eventually be released by system or library routines not compiled using SMARTALLOC. */ void *actuallycalloc(unsigned int nelem, unsigned int elsize) { return calloc(nelem, elsize); } /* ACTUALLYREALLOC -- Call the system realloc() function to obtain storage which will eventually be released by system or library routines not compiled using SMARTALLOC. */ void *actuallyrealloc(void *ptr, unsigned int size) { return realloc(ptr, size); } /* ACTUALLYFREE -- Interface to system free() function to release buffers allocated by low-level routines. */ void actuallyfree(void *cp) { free(cp); } /* SM_DUMP -- Print orphaned buffers (and dump them if BUFDUMP is * True). */ void sm_dump(bool bufdump, bool in_use) { struct abufhead *ap; P(mutex); ap = (struct abufhead *)abqueue.qnext; while (ap != (struct abufhead *) &abqueue) { if ((ap == NULL) || (ap->abq.qnext->qprev != (struct b_queue *) ap) || (ap->abq.qprev->qnext != (struct b_queue *) ap)) { FPmsg1(0, _("\nOrphaned buffers exist. Dump terminated following\n" " discovery of bad links in chain of orphaned buffers.\n" " Buffer address with bad links: %p\n"), ap); break; } if (ap->abfname != NULL) { char errmsg[500]; uint32_t memsize = ap->ablen - (HEAD_SIZE + 1); char *cp = ((char *)ap) + HEAD_SIZE; FPmsg6(0, "%s buffer: %s %d bytes at %p from %s:%d\n", in_use ? "In use" : "Orphaned", my_name, memsize, cp, get_basename(ap->abfname), ap->ablineno); if (bufdump) { char buf[20]; unsigned llen = 0; errmsg[0] = EOS; while (memsize) { if (llen >= 16) { bstrncat(errmsg, "\n", sizeof(errmsg)); llen = 0; FPmsg1(0, "%s", errmsg); errmsg[0] = EOS; } bsnprintf(buf, sizeof(buf), " %02X", (*cp++) & 0xFF); bstrncat(errmsg, buf, sizeof(errmsg)); llen++; memsize--; } FPmsg1(0, "%s\n", errmsg); } } ap = (struct abufhead *) ap->abq.qnext; } V(mutex); } #undef sm_check /* SM_CHECK -- Check the buffers and dump if any damage exists. */ void sm_check(const char *fname, int lineno, bool bufdump) { if (!sm_check_rtn(fname, lineno, bufdump)) { smart_alloc_msg(__FILE__, __LINE__, _("Damaged buffer found. Called from %s:%d\n"), get_basename(fname), (uint32_t)lineno); } } #undef sm_check_rtn /* SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */ int sm_check_rtn(const char *fname, int lineno, bool bufdump) { struct abufhead *ap; int bad, badbuf = 0; P(mutex); ap = (struct abufhead *) abqueue.qnext; while (ap != (struct abufhead *)&abqueue) { bad = 0; if (ap != NULL) { if (ap->abq.qnext->qprev != (struct b_queue *)ap) { bad = 0x1; } if (ap->abq.qprev->qnext != (struct b_queue *)ap) { bad |= 0x2; } if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] != ((((intptr_t) ap) & 0xFF) ^ 0xC5)) { bad |= 0x4; } } else { bad = 0x8; } badbuf |= bad; if (bad) { FPmsg2(0, _("\nDamaged buffers found at %s:%d\n"), get_basename(fname), (uint32_t)lineno); if (bad & 0x1) { FPmsg0(0, _(" discovery of bad prev link.\n")); } if (bad & 0x2) { FPmsg0(0, _(" discovery of bad next link.\n")); } if (bad & 0x4) { FPmsg0(0, _(" discovery of data overrun.\n")); } if (bad & 0x8) { FPmsg0(0, _(" NULL pointer.\n")); } if (!ap) { goto get_out; } FPmsg1(0, _(" Buffer address: %p\n"), ap); if (ap->abfname != NULL) { uint32_t memsize = ap->ablen - (HEAD_SIZE + 1); char errmsg[80]; FPmsg4(0, _("Damaged buffer: %6u bytes allocated at line %d of %s %s\n"), memsize, ap->ablineno, my_name, get_basename(ap->abfname)); if (bufdump) { unsigned llen = 0; char *cp = ((char *) ap) + HEAD_SIZE; errmsg[0] = EOS; while (memsize) { if (llen >= 16) { strcat(errmsg, "\n"); llen = 0; FPmsg1(0, "%s", errmsg); errmsg[0] = EOS; } if (*cp < 0x20) { sprintf(errmsg + strlen(errmsg), " %02X", (*cp++) & 0xFF); } else { sprintf(errmsg + strlen(errmsg), " %c ", (*cp++) & 0xFF); } llen++; memsize--; } FPmsg1(0, "%s\n", errmsg); } } } ap = (struct abufhead *)ap->abq.qnext; } get_out: V(mutex); return badbuf ? 0 : 1; } /* SM_STATIC -- Orphaned buffer detection can be disabled (for such items as buffers allocated during initialisation) by calling sm_static(1). Normal orphaned buffer detection can be re-enabled with sm_static(0). Note that all the other safeguards still apply to buffers allocated when sm_static(1) mode is in effect. */ void sm_static(bool mode) { bufimode = mode; } /* * Here we overload C++'s global new and delete operators * so that the memory is allocated through smartalloc. */ #ifdef xxx void * operator new(size_t size) { return sm_malloc(__FILE__, __LINE__, size); } void operator delete(void *buf) { sm_free(__FILE__, __LINE__, buf); } #endif #endif /* SMARTALLOC */ bareos-Release-14.2.6/src/lib/smartall.h000066400000000000000000000112331263011562700177650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Definitions for the smart memory allocator */ #ifndef SMARTALLOC_H #define SMARTALLOC_H extern uint64_t DLL_IMP_EXP sm_max_bytes; extern uint64_t DLL_IMP_EXP sm_bytes; extern uint32_t DLL_IMP_EXP sm_max_buffers; extern uint32_t DLL_IMP_EXP sm_buffers; #ifdef SMARTALLOC #undef SMARTALLOC #define SMARTALLOC SMARTALLOC extern void *sm_malloc(const char *fname, int lineno, unsigned int nbytes), *sm_calloc(const char *fname, int lineno, unsigned int nelem, unsigned int elsize), *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size), *actuallymalloc(unsigned int size), *actuallycalloc(unsigned int nelem, unsigned int elsize), *actuallyrealloc(void *ptr, unsigned int size); extern void sm_free(const char *fname, int lineno, void *fp); extern void actuallyfree(void *cp), sm_dump(bool bufdump, bool in_use=false), sm_static(int mode); extern void sm_new_owner(const char *fname, int lineno, char *buf); #ifdef SMCHECK #define Dsm_check(lvl) if ((lvl)<=debug_level) sm_check(__FILE__, __LINE__, true) extern void sm_check(const char *fname, int lineno, bool bufdump); extern int sm_check_rtn(const char *fname, int lineno, bool bufdump); #else #define Dsm_check(lvl) #define sm_check(f, l, fl) #define sm_check_rtn(f, l, fl) 1 #endif /* Redefine standard memory allocator calls to use our routines instead. */ #define free(x) sm_free(__FILE__, __LINE__, (x)) #define cfree(x) sm_free(__FILE__, __LINE__, (x)) #define malloc(x) sm_malloc(__FILE__, __LINE__, (x)) #define calloc(n,e) sm_calloc(__FILE__, __LINE__, (n), (e)) #define realloc(p,x) sm_realloc(__FILE__, __LINE__, (p), (x)) #else /* If SMARTALLOC is disabled, define its special calls to default to the standard routines. */ #define actuallyfree(x) free(x) #define actuallymalloc(x) malloc(x) #define actuallycalloc(x,y) calloc(x,y) #define actuallyrealloc(x,y) realloc(x,y) #define sm_dump(x) #define sm_static(x) #define sm_new_owner(a, b, c) #define sm_malloc(f, l, n) malloc(n) #define sm_free(f, l, n) free(n) #define sm_check(f, l, fl) #define sm_check_rtn(f, l, fl) 1 extern void *b_malloc(); #define malloc(x) b_malloc(__FILE__, __LINE__, (x)) #endif #ifdef SMARTALLOC #define New(type) new(__FILE__, __LINE__) type /* We do memset(0) because it's not possible to memset a class when * using subclass with virtual functions */ class SMARTALLOC { public: void *operator new(size_t s, const char *fname, int line) { size_t size = s > sizeof(int) ? (unsigned int)s : sizeof(int); void *p = sm_malloc(fname, line, size); memset(p, 0, size); return p; } void *operator new[](size_t s, const char *fname, int line) { size_t size = s > sizeof(int) ? (unsigned int)s : sizeof(int); void *p = sm_malloc(fname, line, size); memset(p, 0, size); return p; } void operator delete(void *ptr) { free(ptr); } void operator delete[](void *ptr, size_t /*i*/) { free(ptr); } void operator delete(void *ptr, const char * /*fname*/, int /*line*/) { free(ptr); } void operator delete[](void *ptr, size_t /*i*/, const char * /*fname*/, int /*line*/) { free(ptr); } private: void *operator new(size_t s) throw() { (void)s; return 0; } void *operator new[](size_t s) throw() { (void)s; return 0; } }; #else #define New(type) new type class SMARTALLOC { public: void *operator new(size_t s) { void *p = malloc(s); memset(p, 0, s); return p; } void *operator new[](size_t s) { void *p = malloc(s); memset(p, 0, s); return p; } void operator delete(void *ptr) { free(ptr); } void operator delete[](void *ptr, size_t i) { free(ptr); } }; #endif /* SMARTALLOC */ #endif /* !SMARTALLOC_H */ bareos-Release-14.2.6/src/lib/status.h000066400000000000000000000030641263011562700174740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2008-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Status packet definition that is used in both the SD and FD. It * permits Win32 to call output_status() and get the output back * at the callback address line by line, and for Linux code, * the output can be sent directly to a BSOCK. * * Kern Sibbald, March MMVII */ #ifndef __STATUS_H_ #define __STATUS_H_ /* * Packet to send to output_status() */ class STATUS_PKT { public: BSOCK *bs; /* used on Unix machines */ void *context; /* Win32 */ void (*callback)(const char *msg, int len, void *context); /* Win32 */ bool api; /* set if we want API output */ /* Methods */ STATUS_PKT() { memset(this, 0, sizeof(STATUS_PKT)); }; ~STATUS_PKT() { }; }; #endif bareos-Release-14.2.6/src/lib/tcpd.h000066400000000000000000000212451263011562700171040ustar00rootroot00000000000000 /* * @(#) tcpd.h 1.5 96/03/19 16:22:24 * * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. */ #ifdef __cplusplus extern "C" { #endif /* Structure to describe one communications endpoint. */ #define STRING_LENGTH 128 /* hosts, users, processes */ struct host_info { char name[STRING_LENGTH]; /* access via eval_hostname(host) */ char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */ struct sockaddr_in *sin; /* socket address or 0 */ struct t_unitdata *unit; /* TLI transport address or 0 */ struct request_info *request; /* for shared information */ }; /* Structure to describe what we know about a service request. */ struct request_info { int fd; /* socket handle */ char user[STRING_LENGTH]; /* access via eval_user(request) */ char daemon[STRING_LENGTH]; /* access via eval_daemon(request) */ char pid[10]; /* access via eval_pid(request) */ struct host_info client[1]; /* client endpoint info */ struct host_info server[1]; /* server endpoint info */ void (*sink) (); /* datagram sink function or 0 */ void (*hostname) (); /* address to printable hostname */ void (*hostaddr) (); /* address to printable address */ void (*cleanup) (); /* cleanup function or 0 */ struct netconfig *config; /* netdir handle */ }; /* Common string operations. Less clutter should be more readable. */ #define STRN_CPY(d,s,l) { strncpy((d),(s),(l)); (d)[(l)-1] = 0; } #define STRN_EQ(x,y,l) (strncasecmp((x),(y),(l)) == 0) #define STRN_NE(x,y,l) (strncasecmp((x),(y),(l)) != 0) #define STR_EQ(x,y) (strcasecmp((x),(y)) == 0) #define STR_NE(x,y) (strcasecmp((x),(y)) != 0) /* * Initially, all above strings have the empty value. Information that * cannot be determined at runtime is set to "unknown", so that we can * distinguish between `unavailable' and `not yet looked up'. A hostname * that we do not believe in is set to "paranoid". */ #define STRING_UNKNOWN "unknown" /* lookup failed */ #define STRING_PARANOID "paranoid" /* hostname conflict */ extern char unknown[]; extern char paranoid[]; #define HOSTNAME_KNOWN(s) (STR_NE((s),unknown) && STR_NE((s),paranoid)) #define NOT_INADDR(s) (s[strspn(s,"01234567890./")] != 0) /* Global functions. */ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT) extern void fromhost(); /* get/validate client host info */ #else #define fromhost sock_host /* no TLI support needed */ #endif extern int hosts_access(struct request_info *); /* access control */ extern void shell_cmd(); /* execute shell command */ extern char *percent_x(); /* do % expansion */ extern void rfc931(); /* client name from RFC 931 daemon */ extern void clean_exit(); /* clean up and exit */ extern void refuse(); /* clean up and exit */ extern char *xgets(); /* fgets() on steroids */ extern char *split_at(); /* strchr() and split */ extern unsigned long dot_quad_addr(); /* restricted inet_addr() */ /* Global variables. */ extern int allow_severity; /* for connection logging */ extern int deny_severity; /* for connection logging */ extern char *hosts_allow_table; /* for verification mode redirection */ extern char *hosts_deny_table; /* for verification mode redirection */ extern int hosts_access_verbose; /* for verbose matching mode */ extern int rfc931_timeout; /* user lookup timeout */ extern int resident; /* > 0 if resident process */ /* * Routines for controlled initialization and update of request structure * attributes. Each attribute has its own key. */ #ifdef __STDC__ extern struct request_info *request_init(struct request_info *,...); extern struct request_info *request_set(struct request_info *,...); #else extern struct request_info *request_init(); /* initialize request */ extern struct request_info *request_set(); /* update request structure */ #endif #define RQ_FILE 1 /* file descriptor */ #define RQ_DAEMON 2 /* server process (argv[0]) */ #define RQ_USER 3 /* client user name */ #define RQ_CLIENT_NAME 4 /* client host name */ #define RQ_CLIENT_ADDR 5 /* client host address */ #define RQ_CLIENT_SIN 6 /* client endpoint (internal) */ #define RQ_SERVER_NAME 7 /* server host name */ #define RQ_SERVER_ADDR 8 /* server host address */ #define RQ_SERVER_SIN 9 /* server endpoint (internal) */ /* * Routines for delayed evaluation of request attributes. Each attribute * type has its own access method. The trivial ones are implemented by * macros. The other ones are wrappers around the transport-specific host * name, address, and client user lookup methods. The request_info and * host_info structures serve as caches for the lookup results. */ extern char *eval_user(); /* client user */ extern char *eval_hostname(); /* printable hostname */ extern char *eval_hostaddr(); /* printable host address */ extern char *eval_hostinfo(); /* host name or address */ extern char *eval_client(struct request_info *); /* whatever is available */ extern char *eval_server(); /* whatever is available */ #define eval_daemon(r) ((r)->daemon) /* daemon process name */ #define eval_pid(r) ((r)->pid) /* process id */ /* Socket-specific methods, including DNS hostname lookups. */ extern void sock_host(struct request_info *); extern void sock_hostname(); /* translate address to hostname */ extern void sock_hostaddr(); /* address to printable address */ #define sock_methods(r) \ { (r)->hostname = sock_hostname; (r)->hostaddr = sock_hostaddr; } /* The System V Transport-Level Interface (TLI) interface. */ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT) extern void tli_host(); /* look up endpoint addresses etc. */ #endif /* * Problem reporting interface. Additional file/line context is reported * when available. The jump buffer (tcpd_buf) is not declared here, or * everyone would have to include . */ #ifdef __STDC__ extern void tcpd_warn(char *, ...); /* report problem and proceed */ extern void tcpd_jump(char *, ...); /* report problem and jump */ #else extern void tcpd_warn(); extern void tcpd_jump(); #endif struct tcpd_context { char *file; /* current file */ int line; /* current line */ }; extern struct tcpd_context tcpd_context; /* * While processing access control rules, error conditions are handled by * jumping back into the hosts_access() routine. This is cleaner than * checking the return value of each and every silly little function. The * (-1) returns are here because zero is already taken by longjmp(). */ #define AC_PERMIT 1 /* permit access */ #define AC_DENY (-1) /* deny_access */ #define AC_ERROR AC_DENY /* XXX */ /* * In verification mode an option function should just say what it would do, * instead of really doing it. An option function that would not return * should clear the dry_run flag to inform the caller of this unusual * behavior. */ extern void process_options(); /* execute options */ extern int dry_run; /* verification flag */ /* Bug workarounds. */ #ifdef INET_ADDR_BUG /* inet_addr() returns struct */ #define inet_addr fix_inet_addr extern long fix_inet_addr(); #endif #ifdef BROKEN_FGETS /* partial reads from sockets */ #define fgets fix_fgets extern char *fix_fgets(); #endif #ifdef RECVFROM_BUG /* no address family info */ #define recvfrom fix_recvfrom extern int fix_recvfrom(); #endif #ifdef GETPEERNAME_BUG /* claims success with UDP */ #define getpeername fix_getpeername extern int fix_getpeername(); #endif #ifdef SOLARIS_24_GETHOSTBYNAME_BUG /* lists addresses as aliases */ #define gethostbyname fix_gethostbyname extern struct hostent *fix_gethostbyname(); #endif #ifdef USE_STRSEP /* libc calls strtok() */ #define strtok fix_strtok extern char *fix_strtok(); #endif #ifdef LIBC_CALLS_STRTOK /* libc calls strtok() */ #define strtok my_strtok extern char *my_strtok(); #endif #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/lib/tls.h000066400000000000000000000023051263011562700167500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version two of the GNU Lesser General Public License as published by the Free Software Foundation plus additions in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * tls.h TLS support functions * * Author: Landon Fuller */ #ifndef __TLS_H_ #define __TLS_H_ /* * Opaque TLS Context Structure. * New TLS Connections are manufactured from this context. */ typedef struct TLS_Context TLS_CONTEXT; /* Opaque TLS Connection Structure */ typedef struct TLS_Connection TLS_CONNECTION; #endif /* __TLS_H_ */ bareos-Release-14.2.6/src/lib/tls_gnutls.c000066400000000000000000000443751263011562700203540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * tls_gnutls.c TLS support functions when using GNUTLS backend. * * Author: Marco van Wieringen */ #include "bareos.h" #include #if defined(HAVE_TLS) && defined(HAVE_GNUTLS) #include #include #define TLS_DEFAULT_CIPHERS "NONE:+VERS-TLS1.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL" #define DH_BITS 1024 /* TLS Context Structure */ struct TLS_Context { gnutls_dh_params dh_params; gnutls_certificate_client_credentials gnutls_cred; CRYPTO_PEM_PASSWD_CB *pem_callback; const void *pem_userdata; unsigned char *dhdata; bool verify_peer; bool tls_enable; bool tls_require; }; struct TLS_Connection { TLS_Context *ctx; gnutls_session_t gnutls_state; }; static inline bool load_dhfile_data(TLS_CONTEXT *ctx, const char *dhfile) { FILE *fp; int error; size_t size; struct stat st; gnutls_datum_t dhparms; /* * Load the content of the file into memory. */ if (stat(dhfile, &st) < 0) { return false; } if ((fp = fopen(dhfile, "r")) == (FILE *)NULL) { return false; } /* * Allocate a memory buffer to hold the DH data. */ ctx->dhdata = (unsigned char *)malloc(st.st_size + 1); size = fread(ctx->dhdata, sizeof(ctx->dhdata), 1, fp); fclose(fp); dhparms.data = ctx->dhdata; dhparms.size = size; error = gnutls_dh_params_import_pkcs3(ctx->dh_params, &dhparms, GNUTLS_X509_FMT_PEM); if (error != GNUTLS_E_SUCCESS) { return false; } return true; } /* * Create a new TLS_CONTEXT instance. * Returns: Pointer to TLS_CONTEXT instance on success * NULL on failure; */ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, const char *crlfile, const char *certfile, const char *keyfile, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata, const char *dhfile, bool verify_peer) { int error; TLS_CONTEXT *ctx; ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT)); memset(ctx, 0, sizeof(TLS_CONTEXT)); ctx->pem_callback = pem_callback; ctx->pem_userdata = pem_userdata; ctx->verify_peer = verify_peer; error = gnutls_certificate_allocate_credentials(&ctx->gnutls_cred); if (error != GNUTLS_E_SUCCESS) { Jmsg1(NULL, M_ERROR, 0, _("Failed to create a new GNUTLS certificate credential: ERR=%s\n"), gnutls_strerror(error)); free(ctx); return NULL; } /* * GNUTLS supports only a certfile not a certdir. */ if (ca_certdir && !ca_certfile) { Jmsg0(NULL, M_ERROR, 0, _("GNUTLS doesn't support certdir use certfile instead\n")); goto bail_out; } /* * Try to load the trust file, first in PEM format and if that fails in DER format. */ if (ca_certfile) { error = gnutls_certificate_set_x509_trust_file(ctx->gnutls_cred, ca_certfile, GNUTLS_X509_FMT_PEM); if (error < GNUTLS_E_SUCCESS) { error = gnutls_certificate_set_x509_trust_file(ctx->gnutls_cred, ca_certfile, GNUTLS_X509_FMT_DER); if (error < GNUTLS_E_SUCCESS) { Jmsg1(NULL, M_ERROR, 0, _("Error loading CA certificates from %s\n"), ca_certfile); goto bail_out; } } } else if (verify_peer) { /* * At least one CA is required for peer verification */ Jmsg0(NULL, M_ERROR, 0, _("Certificate file must be specified as a verification store\n")); goto bail_out; } /* * Try to load the revocation list file, first in PEM format and if that fails in DER format. */ if (crlfile) { error = gnutls_certificate_set_x509_crl_file(ctx->gnutls_cred, crlfile, GNUTLS_X509_FMT_PEM); if (error < GNUTLS_E_SUCCESS) { error = gnutls_certificate_set_x509_crl_file(ctx->gnutls_cred, crlfile, GNUTLS_X509_FMT_DER); if (error < GNUTLS_E_SUCCESS) { Jmsg1(NULL, M_ERROR, 0, _("Error loading certificate revocation list from %s\n"), crlfile); goto bail_out; } } } /* * Try to load the certificate and the keyfile, first in PEM format and if that fails in DER format. */ if (certfile && keyfile) { error = gnutls_certificate_set_x509_key_file(ctx->gnutls_cred, certfile, keyfile, GNUTLS_X509_FMT_PEM); if (error != GNUTLS_E_SUCCESS) { error = gnutls_certificate_set_x509_key_file(ctx->gnutls_cred, certfile, keyfile, GNUTLS_X509_FMT_DER); if (error != GNUTLS_E_SUCCESS) { Jmsg2(NULL, M_ERROR, 0, _("Error loading key from %s or certificate from %s\n"), keyfile, certfile); goto bail_out; } } } error = gnutls_dh_params_init(&ctx->dh_params); if (error != GNUTLS_E_SUCCESS) { goto bail_out; } if (dhfile) { if (!load_dhfile_data(ctx, dhfile)) { Jmsg1(NULL, M_ERROR, 0, _("Failed to load DH file %s\n"), dhfile); goto bail_out; } } else { error = gnutls_dh_params_generate2(ctx->dh_params, DH_BITS); if (error != GNUTLS_E_SUCCESS) { Jmsg0(NULL, M_ERROR, 0, _("Failed to generate new DH parameters\n")); goto bail_out; } } /* * Link the dh params and the credentials. */ gnutls_certificate_set_dh_params(ctx->gnutls_cred, ctx->dh_params); return ctx; bail_out: free_tls_context(ctx); return NULL; } void free_tls_context(TLS_CONTEXT *ctx) { gnutls_certificate_free_credentials(ctx->gnutls_cred); if (ctx->dhdata) { free(ctx->dhdata); } free(ctx); } bool get_tls_require(TLS_CONTEXT *ctx) { return (ctx) ? ctx->tls_require : false; } void set_tls_require(TLS_CONTEXT *ctx, bool value) { if (ctx) { ctx->tls_require = value; } } bool get_tls_enable(TLS_CONTEXT *ctx) { return (ctx) ? ctx->tls_enable : false; } void set_tls_enable(TLS_CONTEXT *ctx, bool value) { if (ctx) { ctx->tls_enable = value; } } /* * Certs are not automatically verified during the handshake. */ static inline bool tls_cert_verify(TLS_CONNECTION *tls) { unsigned int status = 0; int error; time_t now = time(NULL); time_t peertime; error = gnutls_certificate_verify_peers2(tls->gnutls_state, &status); if (error != GNUTLS_E_SUCCESS) { Jmsg1(NULL, M_ERROR, 0, _("gnutls_certificate_verify_peers2 failed: ERR=%s\n"), gnutls_strerror(error)); return false; } if (status) { Jmsg1(NULL, M_ERROR, 0, _("peer certificate untrusted or revoked (0x%x)\n"), status); return false; } peertime = gnutls_certificate_expiration_time_peers(tls->gnutls_state); if (peertime == -1) { Jmsg0(NULL, M_ERROR, 0, _("gnutls_certificate_expiration_time_peers failed\n")); return false; } if (peertime < now) { Jmsg0(NULL, M_ERROR, 0, _("peer certificate is expired\n")); return false; } peertime = gnutls_certificate_activation_time_peers(tls->gnutls_state); if (peertime == -1) { Jmsg0(NULL, M_ERROR, 0, _("gnutls_certificate_activation_time_peers failed\n")); return false; } if (peertime > now) { Jmsg0(NULL, M_ERROR, 0, _("peer certificate not yet active\n")); return false; } return true; } /* * Verifies a list of common names against the certificate commonName attribute. * * Returns: true on success * false on failure */ bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list) { char *cn; int error, cnt; unsigned int list_size; size_t cn_length; char cannonicalname[256]; bool auth_success = false; gnutls_x509_crt_t cert; const gnutls_datum_t *peer_cert_list; /* * See if we verify the peer certificate. */ if (!tls->ctx->verify_peer) { return true; } peer_cert_list = gnutls_certificate_get_peers(tls->gnutls_state, &list_size); if (!peer_cert_list) { return false; } error = gnutls_x509_crt_init(&cert); if (error != GNUTLS_E_SUCCESS) { return false; } gnutls_x509_crt_import(cert, peer_cert_list, GNUTLS_X509_FMT_DER); if (error != GNUTLS_E_SUCCESS) { gnutls_x509_crt_deinit(cert); return false; } /* * See what CN's are available. */ error = 0; for (cnt = 0; error >= 0; cnt++) { cn_length = sizeof(cannonicalname); error = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, cnt, 0, cannonicalname, &cn_length); if (error < 0) { break; } /* * NULL terminate data. */ cannonicalname[255] = '\0'; /* * Try all the CNs in the list */ foreach_alist(cn, verify_list) { if (bstrcasecmp(cn, cannonicalname)) { auth_success = true; break; } } if (auth_success) { break; } } gnutls_x509_crt_deinit(cert); return auth_success; } /* * Verifies a peer's hostname against the subjectAltName and commonName attributes. * * Returns: true on success * false on failure */ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host) { int error; unsigned int list_size; gnutls_x509_crt_t cert; const gnutls_datum_t *peer_cert_list; /* * See if we verify the peer certificate. */ if (!tls->ctx->verify_peer) { return true; } peer_cert_list = gnutls_certificate_get_peers(tls->gnutls_state, &list_size); if (!peer_cert_list) { return false; } error = gnutls_x509_crt_init(&cert); if (error != GNUTLS_E_SUCCESS) { return false; } error = gnutls_x509_crt_import(cert, peer_cert_list, GNUTLS_X509_FMT_DER); if (error != GNUTLS_E_SUCCESS) { gnutls_x509_crt_deinit(cert); return false; } if (!gnutls_x509_crt_check_hostname(cert, host)) { gnutls_x509_crt_deinit(cert); return false; } gnutls_x509_crt_deinit(cert); return true; } /* * Create a new TLS_CONNECTION instance. * * Returns: Pointer to TLS_CONNECTION instance on success * NULL on failure; */ TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd, bool server) { TLS_CONNECTION *tls; int error; /* * Allocate our new tls connection */ tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION)); memset(tls, 0, sizeof(TLS_CONNECTION)); /* * Link the TLS context and the TLS session. */ tls->ctx = ctx; if (server) { error = gnutls_init(&tls->gnutls_state, GNUTLS_SERVER); } else { error = gnutls_init(&tls->gnutls_state, GNUTLS_CLIENT); } if (error != GNUTLS_E_SUCCESS) { Jmsg1(NULL, M_ERROR, 0, _("Failed to create a new GNUTLS session: ERR=%s\n"), gnutls_strerror(error)); goto bail_out; } /* * Set the default ciphers to use for the TLS connection. */ gnutls_priority_set_direct(tls->gnutls_state, TLS_DEFAULT_CIPHERS, NULL); /* * Link the credentials and the session. */ gnutls_credentials_set(tls->gnutls_state, GNUTLS_CRD_CERTIFICATE, ctx->gnutls_cred); /* * Link the TLS session and the filedescriptor of the socket used. * gnutls_transport_set_ptr may cause problems on some platforms, * therefore the replacement gnutls_transport_set_int is used, * when available (since GnuTLS >= 3.1.9) */ #ifdef HAVE_GNUTLS_TRANSPORT_SET_INT gnutls_transport_set_int(tls->gnutls_state, fd); #else gnutls_transport_set_ptr(tls->gnutls_state, (gnutls_transport_ptr_t)fd); #endif /* * Server specific settings. */ if (server) { /* * See if we require the other party to have a certificate too. */ if (ctx->tls_require) { gnutls_certificate_server_set_request(tls->gnutls_state, GNUTLS_CERT_REQUIRE); } else { gnutls_certificate_server_set_request(tls->gnutls_state, GNUTLS_CERT_REQUEST); } gnutls_dh_set_prime_bits(tls->gnutls_state, DH_BITS); } return tls; bail_out: free(tls); return NULL; } void free_tls_connection(TLS_CONNECTION *tls) { gnutls_deinit(tls->gnutls_state); free(tls); } static inline bool gnutls_bsock_session_start(BSOCK *bsock, bool server) { int flags, error; bool status = true; bool done = false; unsigned int list_size; TLS_CONNECTION *tls = bsock->tls; const gnutls_datum_t *peer_cert_list; /* Ensure that socket is non-blocking */ flags = bsock->set_nonblocking(); /* start timer */ bsock->timer_start = watchdog_time; bsock->clear_timed_out(); bsock->set_killable(false); while (!done) { error = gnutls_handshake(tls->gnutls_state); switch (error) { case GNUTLS_E_SUCCESS: status = true; done = true; break; case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: if (gnutls_record_get_direction(tls->gnutls_state) == 1) { wait_for_writable_fd(bsock->m_fd, 10000, false); } else { wait_for_readable_fd(bsock->m_fd, 10000, false); } status = true; continue; default: status = false; goto cleanup; } if (bsock->is_timed_out()) { goto cleanup; } /* * See if we need to verify the peer. */ peer_cert_list = gnutls_certificate_get_peers(tls->gnutls_state, &list_size); if (!peer_cert_list && !tls->ctx->tls_require) { goto cleanup; } if (tls->ctx->verify_peer) { if (!tls_cert_verify(tls)) { status = false; goto cleanup; } } } cleanup: /* Restore saved flags */ bsock->restore_blocking(flags); /* Clear timer */ bsock->timer_start = 0; bsock->set_killable(true); return status; } /* * Initiates a TLS connection with the server. * Returns: true on success * false on failure */ bool tls_bsock_connect(BSOCK *bsock) { return gnutls_bsock_session_start(bsock, false); } /* * Listens for a TLS connection from a client. * Returns: true on success * false on failure */ bool tls_bsock_accept(BSOCK *bsock) { return gnutls_bsock_session_start(bsock, true); } void tls_bsock_shutdown(BSOCK *bsock) { TLS_CONNECTION *tls = bsock->tls; gnutls_bye(tls->gnutls_state, GNUTLS_SHUT_WR); } /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */ static inline int gnutls_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write) { TLS_CONNECTION *tls = bsock->tls; int error; int flags; int nleft = 0; int nwritten = 0; /* Ensure that socket is non-blocking */ flags = bsock->set_nonblocking(); /* start timer */ bsock->timer_start = watchdog_time; bsock->clear_timed_out(); bsock->set_killable(false); nleft = nbytes; while (nleft > 0) { if (write) { nwritten = gnutls_record_send(tls->gnutls_state, ptr, nleft); } else { nwritten = gnutls_record_recv(tls->gnutls_state, ptr, nleft); } /* Handle errors */ if (nwritten > 0) { nleft -= nwritten; if (nleft) { ptr += nwritten; } } else { switch (nwritten) { case GNUTLS_E_REHANDSHAKE: /* * TLS renegotiation requested. */ error = gnutls_handshake(tls->gnutls_state); if (error != GNUTLS_E_SUCCESS) { goto cleanup; } break; case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: if (gnutls_record_get_direction(tls->gnutls_state) == 1) { wait_for_writable_fd(bsock->m_fd, 10000, false); } else { wait_for_readable_fd(bsock->m_fd, 10000, false); } break; default: goto cleanup; } } /* Everything done? */ if (nleft == 0) { goto cleanup; } /* Timeout/Termination, let's take what we can get */ if (bsock->is_timed_out() || bsock->is_terminated()) { goto cleanup; } } cleanup: /* Restore saved flags */ bsock->restore_blocking(flags); /* Clear timer */ bsock->timer_start = 0; bsock->set_killable(true); return nbytes - nleft; } int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) { return gnutls_bsock_readwrite(bsock, ptr, nbytes, true); } int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) { return gnutls_bsock_readwrite(bsock, ptr, nbytes, false); } #endif /* HAVE_TLS && HAVE_GNUTLS */ bareos-Release-14.2.6/src/lib/tls_none.c000066400000000000000000000037401263011562700177660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * tls_none.c TLS support functions when no backend. * * Author: Landon Fuller */ #include "bareos.h" #include #ifndef HAVE_TLS /* Dummy routines */ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, const char *crlfile, const char *certfile, const char *keyfile, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata, const char *dhfile, bool verify_peer) { return NULL; } void free_tls_context(TLS_CONTEXT *ctx) { } bool get_tls_require(TLS_CONTEXT *ctx) { return false; } void set_tls_require(TLS_CONTEXT *ctx, bool value) { } bool get_tls_enable(TLS_CONTEXT *ctx) { return false; } void set_tls_enable(TLS_CONTEXT *ctx, bool value) { } TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd, bool server) { return NULL; } void free_tls_connection(TLS_CONNECTION *tls) { } void tls_bsock_shutdown(BSOCK *bsock) { } #endif /* HAVE_TLS */ bareos-Release-14.2.6/src/lib/tls_nss.c000066400000000000000000000070161263011562700176320ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * tls.c TLS support functions when using Mozilla NSS backend. * * Author: Marco van Wieringen */ #include "bareos.h" #include #if defined(HAVE_TLS) && defined(HAVE_NSS) /* TLS Context Structure */ struct TLS_Context { bool tls_enable; bool tls_require; }; struct TLS_Connection { }; /* * Create a new TLS_CONTEXT instance. * Returns: Pointer to TLS_CONTEXT instance on success * NULL on failure; */ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, const char *crlfile, const char *certfile, const char *keyfile, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata, const char *dhfile, bool verify_peer) { return NULL; } void free_tls_context(TLS_CONTEXT *ctx) { } bool get_tls_require(TLS_CONTEXT *ctx) { return (ctx) ? ctx->tls_require : false; } void set_tls_require(TLS_CONTEXT *ctx, bool value) { if (ctx) { ctx->tls_require = value; } } bool get_tls_enable(TLS_CONTEXT *ctx) { return (ctx) ? ctx->tls_enable : false; } void set_tls_enable(TLS_CONTEXT *ctx, bool value) { if (ctx) { ctx->tls_enable = value; } } /* * Verifies a list of common names against the certificate commonName attribute. * * Returns: true on success * false on failure */ bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list) { return true; } /* * Verifies a peer's hostname against the subjectAltName and commonName attributes. * * Returns: true on success * false on failure */ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host) { return true; } /* * Create a new TLS_CONNECTION instance. * * Returns: Pointer to TLS_CONNECTION instance on success * NULL on failure; */ TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd, bool server) { return NULL; } void free_tls_connection(TLS_CONNECTION *tls) { } /* * Initiates a TLS connection with the server. * Returns: true on success * false on failure */ bool tls_bsock_connect(BSOCK *bsock) { return false; } /* * Listens for a TLS connection from a client. * Returns: true on success * false on failure */ bool tls_bsock_accept(BSOCK *bsock) { return false; } void tls_bsock_shutdown(BSOCK *bsock) { } int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) { return -1; } int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) { return -1; } #endif /* HAVE_TLS && HAVE_NSS */ bareos-Release-14.2.6/src/lib/tls_openssl.c000066400000000000000000000636451263011562700205240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2010 Free Software Foundation Europe e.V. Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * tls_openssl.c TLS support functions when using OPENSSL backend. * * Author: Landon Fuller */ #include "bareos.h" #include #if defined(HAVE_TLS) && defined(HAVE_OPENSSL) #include #include #include #include #include /* * No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */ #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH" #define MAX_CRLS 16 /* * TLS Context Structures */ struct TLS_Context { SSL_CTX *openssl; CRYPTO_PEM_PASSWD_CB *pem_callback; const void *pem_userdata; bool verify_peer; bool tls_enable; bool tls_require; }; struct TLS_Connection { TLS_Context *ctx; SSL *openssl; }; #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) struct TLS_CRL_Reload_Context { time_t mtime; char *crl_file_name; X509_CRL *crls[MAX_CRLS]; }; /* * Automatic Certificate Revocation List reload logic. */ static int crl_reloader_new(X509_LOOKUP *ctx) { TLS_CRL_Reload_Context *data; data = (TLS_CRL_Reload_Context *)malloc(sizeof(TLS_CRL_Reload_Context)); memset(data, 0, sizeof(TLS_CRL_Reload_Context)); ctx->method_data = (char *)data; return 1; } static void crl_reloader_free(X509_LOOKUP *ctx) { int cnt; TLS_CRL_Reload_Context *data; if (ctx->method_data) { data = (TLS_CRL_Reload_Context *)ctx->method_data; if (data->crl_file_name) { free(data->crl_file_name); } for (cnt = 0; cnt < MAX_CRLS; cnt++) { if (data->crls[cnt]) { X509_CRL_free(data->crls[cnt]); } } free(data); ctx->method_data = NULL; } } /* * Load the new content from a Certificate Revocation List (CRL). */ static int crl_reloader_reload_file(X509_LOOKUP *ctx) { int cnt, ok = 0; struct stat st; BIO *in = NULL; TLS_CRL_Reload_Context *data; data = (TLS_CRL_Reload_Context *)ctx->method_data; if (!data->crl_file_name) { goto bail_out; } if (stat(data->crl_file_name, &st) != 0) { goto bail_out; } in = BIO_new_file(data->crl_file_name, "r"); if (!in) { goto bail_out; } /* * Load a maximum of MAX_CRLS Certificate Revocation Lists. */ data->mtime = st.st_mtime; for (cnt = 0; cnt < MAX_CRLS; cnt++) { X509_CRL *crl; if ((crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL)) == NULL) { if (cnt == 0) { /* * We try to read multiple times only the first is fatal. */ goto bail_out; } else { break; } } if (data->crls[cnt]) { X509_CRL_free(data->crls[cnt]); } data->crls[cnt] = crl; } /* * Clear the other slots. */ while (++cnt < MAX_CRLS) { if (data->crls[cnt]) { X509_CRL_free(data->crls[cnt]); data->crls[cnt] = NULL; } } ok = 1; bail_out: if (in) { BIO_free(in); } return ok; } /* * See if the data in the Certificate Revocation List (CRL) is newer then we loaded before. */ static int crl_reloader_reload_if_newer(X509_LOOKUP *ctx) { int ok = 0; TLS_CRL_Reload_Context *data; struct stat st; data = (TLS_CRL_Reload_Context *)ctx->method_data; if (!data->crl_file_name) { return ok; } if (stat(data->crl_file_name, &st) != 0) { return ok; } if (st.st_mtime > data->mtime) { ok = crl_reloader_reload_file(ctx); if (!ok) { goto bail_out; } } ok = 1; bail_out: return ok; } /* * Load the data from a Certificate Revocation List (CRL) into memory. */ static int crl_reloader_file_load(X509_LOOKUP *ctx, const char *argp) { int ok = 0; TLS_CRL_Reload_Context *data; data = (TLS_CRL_Reload_Context *)ctx->method_data; if (data->crl_file_name) { free(data->crl_file_name); } data->crl_file_name = bstrdup(argp); ok = crl_reloader_reload_file(ctx); if (!ok) { goto bail_out; } ok = 1; bail_out: return ok; } static int crl_reloader_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret) { int ok = 0; switch (cmd) { case X509_L_FILE_LOAD: ok = crl_reloader_file_load(ctx, argp); break; default: break; } return ok; } /* * Check if a CRL entry is expired. */ static int crl_entry_expired(X509_CRL *crl) { int lastUpdate, nextUpdate; if (!crl) { return 0; } lastUpdate = X509_cmp_current_time(X509_CRL_get_lastUpdate(crl)); nextUpdate = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); if (lastUpdate < 0 && nextUpdate > 0) { return 0; } return 1; } /* * Retrieve a CRL entry by Subject. */ static int crl_reloader_get_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret) { int cnt, ok = 0; TLS_CRL_Reload_Context *data = NULL; if (type != X509_LU_CRL) { return ok; } data = (TLS_CRL_Reload_Context *)ctx->method_data; if (!data->crls[0]) { return ok; } ret->type = 0; ret->data.crl = NULL; for (cnt = 0; cnt < MAX_CRLS; cnt++) { if (crl_entry_expired(data->crls[cnt]) && !crl_reloader_reload_if_newer(ctx)) { goto bail_out; } if (X509_NAME_cmp(data->crls[cnt]->crl->issuer, name)) { continue; } ret->type = type; ret->data.crl = data->crls[cnt]; ok = 1; break; } return ok; bail_out: return ok; } static int load_new_crl_file(X509_LOOKUP *lu, const char *fname) { int ok = 0; if (!fname) { return ok; } ok = X509_LOOKUP_ctrl(lu, X509_L_FILE_LOAD, fname, 0, NULL); return ok; } static X509_LOOKUP_METHOD x509_crl_reloader = { "CRL file reloader", crl_reloader_new, /* new */ crl_reloader_free, /* free */ NULL, /* init */ NULL, /* shutdown */ crl_reloader_ctrl, /* ctrl */ crl_reloader_get_by_subject, /* get_by_subject */ NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL /* get_by_alias */ }; static X509_LOOKUP_METHOD *X509_LOOKUP_crl_reloader(void) { return (&x509_crl_reloader); } #endif /* (OPENSSL_VERSION_NUMBER > 0x00907000L) */ /* * OpenSSL certificate verification callback. * OpenSSL has already performed internal certificate verification. * We just report any errors that occured. */ static int openssl_verify_peer(int ok, X509_STORE_CTX *store) { if (!ok) { X509 *cert = X509_STORE_CTX_get_current_cert(store); int depth = X509_STORE_CTX_get_error_depth(store); int err = X509_STORE_CTX_get_error(store); char issuer[256]; char subject[256]; X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 256); X509_NAME_oneline(X509_get_subject_name(cert), subject, 256); Jmsg5(NULL, M_ERROR, 0, _("Error with certificate at depth: %d, issuer = %s," " subject = %s, ERR=%d:%s\n"), depth, issuer, subject, err, X509_verify_cert_error_string(err)); } return ok; } /* * Dispatch user PEM encryption callbacks */ static int tls_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata) { TLS_CONTEXT *ctx = (TLS_CONTEXT *)userdata; return (ctx->pem_callback(buf, size, ctx->pem_userdata)); } /* * Create a new TLS_CONTEXT instance. * * Returns: Pointer to TLS_CONTEXT instance on success * NULL on failure; */ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir, const char *crlfile, const char *certfile, const char *keyfile, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata, const char *dhfile, bool verify_peer) { TLS_CONTEXT *ctx; BIO *bio; DH *dh; ctx = (TLS_CONTEXT *)malloc(sizeof(TLS_CONTEXT)); /* * Allocate our OpenSSL Context * We allow tls 1.2. 1.1 and 1.0 */ #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) ctx->openssl = SSL_CTX_new(TLS_method()); #else ctx->openssl = SSL_CTX_new(SSLv23_method()); #endif if (!ctx->openssl) { openssl_post_errors(M_FATAL, _("Error initializing SSL context")); goto err; } /* * Enable all Bug Workarounds */ SSL_CTX_set_options(ctx->openssl, SSL_OP_ALL); #if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* * Disallow broken sslv2 and sslv3. */ SSL_CTX_set_options(ctx->openssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); #endif /* * Set up pem encryption callback */ if (pem_callback) { ctx->pem_callback = pem_callback; ctx->pem_userdata = pem_userdata; } else { ctx->pem_callback = crypto_default_pem_callback; ctx->pem_userdata = NULL; } ctx->verify_peer = verify_peer; SSL_CTX_set_default_passwd_cb(ctx->openssl, tls_pem_callback_dispatch); SSL_CTX_set_default_passwd_cb_userdata(ctx->openssl, (void *) ctx); /* * Set certificate verification paths. This requires that at least one value be non-NULL */ if (ca_certfile || ca_certdir) { if (!SSL_CTX_load_verify_locations(ctx->openssl, ca_certfile, ca_certdir)) { openssl_post_errors(M_FATAL, _("Error loading certificate verification stores")); goto err; } } else if (verify_peer) { /* At least one CA is required for peer verification */ Jmsg0(NULL, M_ERROR, 0, _("Either a certificate file or a directory must be" " specified as a verification store\n")); goto err; } #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) /* * Set certificate revocation list. */ if (crlfile) { X509_STORE *store; X509_LOOKUP *lookup; store = SSL_CTX_get_cert_store(ctx->openssl); if (!store) { openssl_post_errors(M_FATAL, _("Error loading revocation list file")); goto err; } lookup = X509_STORE_add_lookup(store, X509_LOOKUP_crl_reloader()); if (!lookup) { openssl_post_errors(M_FATAL, _("Error loading revocation list file")); goto err; } if (!load_new_crl_file(lookup, (char *)crlfile)) { openssl_post_errors(M_FATAL, _("Error loading revocation list file")); goto err; } X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } #endif /* * Load our certificate file, if available. This file may also contain a * private key, though this usage is somewhat unusual. */ if (certfile) { if (!SSL_CTX_use_certificate_chain_file(ctx->openssl, certfile)) { openssl_post_errors(M_FATAL, _("Error loading certificate file")); goto err; } } /* * Load our private key. */ if (keyfile) { if (!SSL_CTX_use_PrivateKey_file(ctx->openssl, keyfile, SSL_FILETYPE_PEM)) { openssl_post_errors(M_FATAL, _("Error loading private key")); goto err; } } /* * Load Diffie-Hellman Parameters. */ if (dhfile) { if (!(bio = BIO_new_file(dhfile, "r"))) { openssl_post_errors(M_FATAL, _("Unable to open DH parameters file")); goto err; } dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); if (!dh) { openssl_post_errors(M_FATAL, _("Unable to load DH parameters from specified file")); goto err; } if (!SSL_CTX_set_tmp_dh(ctx->openssl, dh)) { openssl_post_errors(M_FATAL, _("Failed to set TLS Diffie-Hellman parameters")); DH_free(dh); goto err; } /* * Enable Single-Use DH for Ephemeral Keying */ SSL_CTX_set_options(ctx->openssl, SSL_OP_SINGLE_DH_USE); } if (SSL_CTX_set_cipher_list(ctx->openssl, TLS_DEFAULT_CIPHERS) != 1) { Jmsg0(NULL, M_ERROR, 0, _("Error setting cipher list, no valid ciphers available\n")); goto err; } /* * Verify Peer Certificate */ if (verify_peer) { /* * SSL_VERIFY_FAIL_IF_NO_PEER_CERT has no effect in client mode */ SSL_CTX_set_verify(ctx->openssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, openssl_verify_peer); } else { SSL_CTX_set_verify(ctx->openssl, SSL_VERIFY_NONE, NULL); } return ctx; err: /* * Clean up after ourselves */ if (ctx->openssl) { SSL_CTX_free(ctx->openssl); } free(ctx); return NULL; } /* * Free TLS_CONTEXT instance */ void free_tls_context(TLS_CONTEXT *ctx) { SSL_CTX_free(ctx->openssl); free(ctx); } bool get_tls_require(TLS_CONTEXT *ctx) { return (ctx) ? ctx->tls_require : false; } void set_tls_require(TLS_CONTEXT *ctx, bool value) { if (ctx) { ctx->tls_require = value; } } bool get_tls_enable(TLS_CONTEXT *ctx) { return (ctx) ? ctx->tls_enable : false; } void set_tls_enable(TLS_CONTEXT *ctx, bool value) { if (ctx) { ctx->tls_enable = value; } } /* * Verifies a list of common names against the certificate commonName attribute. * * Returns: true on success * false on failure */ bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list) { SSL *ssl = tls->openssl; X509 *cert; X509_NAME *subject; bool auth_success = false; char data[256]; /* * See if we verify the peer certificate. */ if (!tls->ctx->verify_peer) { return true; } /* * Check if peer provided a certificate */ if (!(cert = SSL_get_peer_certificate(ssl))) { Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n")); return false; } if ((subject = X509_get_subject_name(cert)) != NULL) { if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) { char *cn; data[255] = 0; /* NULL terminate data */ /* * Try all the CNs in the list */ foreach_alist(cn, verify_list) { if (bstrcasecmp(data, cn)) { auth_success = true; } } } } X509_free(cert); return auth_success; } /* * Verifies a peer's hostname against the subjectAltName and commonName attributes. * * Returns: true on success * false on failure */ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host) { int i, j; int extensions; int cnLastPos = -1; X509 *cert; X509_NAME *subject; X509_NAME_ENTRY *neCN; ASN1_STRING *asn1CN; SSL *ssl = tls->openssl; bool auth_success = false; /* * See if we verify the peer certificate. */ if (!tls->ctx->verify_peer) { return true; } /* * Check if peer provided a certificate */ if (!(cert = SSL_get_peer_certificate(ssl))) { Qmsg1(jcr, M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host); return false; } /* * Check subjectAltName extensions first */ if ((extensions = X509_get_ext_count(cert)) > 0) { for (i = 0; i < extensions; i++) { X509_EXTENSION *ext; const char *extname; ext = X509_get_ext(cert, i); extname = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); if (bstrcmp(extname, "subjectAltName")) { #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) const X509V3_EXT_METHOD *method; #else X509V3_EXT_METHOD *method; #endif STACK_OF(CONF_VALUE) *val; CONF_VALUE *nval; void *extstr = NULL; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) const unsigned char *ext_value_data; #else unsigned char *ext_value_data; #endif /* * Get x509 extension method structure */ if (!(method = X509V3_EXT_get(ext))) { break; } ext_value_data = ext->value->data; #if (OPENSSL_VERSION_NUMBER > 0x00907000L) if (method->it) { /* * New style ASN1 * Decode ASN1 item in data */ extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length, ASN1_ITEM_ptr(method->it)); } else { /* * Old style ASN1 * Decode ASN1 item in data */ extstr = method->d2i(NULL, &ext_value_data, ext->value->length); } #else extstr = method->d2i(NULL, &ext_value_data, ext->value->length); #endif /* * Iterate through to find the dNSName field(s) */ val = method->i2v(method, extstr, NULL); /* * dNSName shortname is "DNS" */ for (j = 0; j < sk_CONF_VALUE_num(val); j++) { nval = sk_CONF_VALUE_value(val, j); if (bstrcmp(nval->name, "DNS")) { if (bstrcasecmp(nval->value, host)) { auth_success = true; goto success; } } } } } } /* * Try verifying against the subject name */ if (!auth_success) { if ((subject = X509_get_subject_name(cert)) != NULL) { /* * Loop through all CNs */ for (;;) { cnLastPos = X509_NAME_get_index_by_NID(subject, NID_commonName, cnLastPos); if (cnLastPos == -1) { break; } neCN = X509_NAME_get_entry(subject, cnLastPos); asn1CN = X509_NAME_ENTRY_get_data(neCN); if (bstrcasecmp((const char*)asn1CN->data, host)) { auth_success = true; break; } } } } success: X509_free(cert); return auth_success; } /* * Create a new TLS_CONNECTION instance. * * Returns: Pointer to TLS_CONNECTION instance on success * NULL on failure; */ TLS_CONNECTION *new_tls_connection(TLS_CONTEXT *ctx, int fd, bool server) { BIO *bio; /* * Create a new BIO and assign the fd. * The caller will remain responsible for closing the associated fd */ bio = BIO_new(BIO_s_socket()); if (!bio) { /* Not likely, but never say never */ openssl_post_errors(M_FATAL, _("Error creating file descriptor-based BIO")); return NULL; /* Nothing allocated, nothing to clean up */ } BIO_set_fd(bio, fd, BIO_NOCLOSE); /* Allocate our new tls connection */ TLS_CONNECTION *tls = (TLS_CONNECTION *)malloc(sizeof(TLS_CONNECTION)); /* Link the TLS context and the TLS session. */ tls->ctx = ctx; /* Create the SSL object and attach the socket BIO */ if ((tls->openssl = SSL_new(ctx->openssl)) == NULL) { /* Not likely, but never say never */ openssl_post_errors(M_FATAL, _("Error creating new SSL object")); goto err; } SSL_set_bio(tls->openssl, bio, bio); /* Non-blocking partial writes */ SSL_set_mode(tls->openssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); return tls; err: /* Clean up */ BIO_free(bio); SSL_free(tls->openssl); free(tls); return NULL; } /* * Free TLS_CONNECTION instance */ void free_tls_connection(TLS_CONNECTION *tls) { SSL_free(tls->openssl); free(tls); } /* Does all the manual labor for tls_bsock_accept() and tls_bsock_connect() */ static inline bool openssl_bsock_session_start(BSOCK *bsock, bool server) { TLS_CONNECTION *tls = bsock->tls; int err; int flags; bool status = true; /* Ensure that socket is non-blocking */ flags = bsock->set_nonblocking(); /* start timer */ bsock->timer_start = watchdog_time; bsock->clear_timed_out(); bsock->set_killable(false); for (;;) { if (server) { err = SSL_accept(tls->openssl); } else { err = SSL_connect(tls->openssl); } /* Handle errors */ switch (SSL_get_error(tls->openssl, err)) { case SSL_ERROR_NONE: status = true; goto cleanup; case SSL_ERROR_ZERO_RETURN: /* TLS connection was cleanly shut down */ openssl_post_errors(bsock->get_jcr(), M_FATAL, _("Connect failure")); status = false; goto cleanup; case SSL_ERROR_WANT_READ: wait_for_readable_fd(bsock->m_fd, 10000, false); break; case SSL_ERROR_WANT_WRITE: wait_for_writable_fd(bsock->m_fd, 10000, false); break; default: /* Socket Error Occurred */ openssl_post_errors(bsock->get_jcr(), M_FATAL, _("Connect failure")); status = false; goto cleanup; } if (bsock->is_timed_out()) { goto cleanup; } } cleanup: /* Restore saved flags */ bsock->restore_blocking(flags); /* Clear timer */ bsock->timer_start = 0; bsock->set_killable(true); return status; } /* * Initiates a TLS connection with the server. * Returns: true on success * false on failure */ bool tls_bsock_connect(BSOCK *bsock) { return openssl_bsock_session_start(bsock, false); } /* * Listens for a TLS connection from a client. * Returns: true on success * false on failure */ bool tls_bsock_accept(BSOCK *bsock) { return openssl_bsock_session_start(bsock, true); } /* * Shutdown TLS_CONNECTION instance */ void tls_bsock_shutdown(BSOCK *bsock) { /* * SSL_shutdown must be called twice to fully complete the process - * The first time to initiate the shutdown handshake, and the second to * receive the peer's reply. * * In addition, if the underlying socket is blocking, SSL_shutdown() * will not return until the current stage of the shutdown process has * completed or an error has occured. By setting the socket blocking * we can avoid the ugly for()/switch()/select() loop. */ int err; btimer_t *tid; /* Set socket blocking for shutdown */ bsock->set_blocking(); tid = start_bsock_timer(bsock, 60 * 2); err = SSL_shutdown(bsock->tls->openssl); stop_bsock_timer(tid); if (err == 0) { /* Complete shutdown */ tid = start_bsock_timer(bsock, 60 * 2); err = SSL_shutdown(bsock->tls->openssl); stop_bsock_timer(tid); } switch (SSL_get_error(bsock->tls->openssl, err)) { case SSL_ERROR_NONE: break; case SSL_ERROR_ZERO_RETURN: /* TLS connection was shut down on us via a TLS protocol-level closure */ openssl_post_errors(bsock->get_jcr(), M_ERROR, _("TLS shutdown failure.")); break; default: /* Socket Error Occurred */ openssl_post_errors(bsock->get_jcr(), M_ERROR, _("TLS shutdown failure.")); break; } } /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */ static inline int openssl_bsock_readwrite(BSOCK *bsock, char *ptr, int nbytes, bool write) { TLS_CONNECTION *tls = bsock->tls; int flags; int nleft = 0; int nwritten = 0; /* Ensure that socket is non-blocking */ flags = bsock->set_nonblocking(); /* start timer */ bsock->timer_start = watchdog_time; bsock->clear_timed_out(); bsock->set_killable(false); nleft = nbytes; while (nleft > 0) { if (write) { nwritten = SSL_write(tls->openssl, ptr, nleft); } else { nwritten = SSL_read(tls->openssl, ptr, nleft); } /* Handle errors */ switch (SSL_get_error(tls->openssl, nwritten)) { case SSL_ERROR_NONE: nleft -= nwritten; if (nleft) { ptr += nwritten; } break; case SSL_ERROR_SYSCALL: if (nwritten == -1) { if (errno == EINTR) { continue; } if (errno == EAGAIN) { bmicrosleep(0, 20000); /* try again in 20 ms */ continue; } } openssl_post_errors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure.")); goto cleanup; case SSL_ERROR_WANT_READ: wait_for_readable_fd(bsock->m_fd, 10000, false); break; case SSL_ERROR_WANT_WRITE: wait_for_writable_fd(bsock->m_fd, 10000, false); break; case SSL_ERROR_ZERO_RETURN: /* TLS connection was cleanly shut down */ /* Fall through wanted */ default: /* Socket Error Occured */ openssl_post_errors(bsock->get_jcr(), M_FATAL, _("TLS read/write failure.")); goto cleanup; } /* Everything done? */ if (nleft == 0) { goto cleanup; } /* Timeout/Termination, let's take what we can get */ if (bsock->is_timed_out() || bsock->is_terminated()) { goto cleanup; } } cleanup: /* Restore saved flags */ bsock->restore_blocking(flags); /* Clear timer */ bsock->timer_start = 0; bsock->set_killable(true); return nbytes - nleft; } int tls_bsock_writen(BSOCK *bsock, char *ptr, int32_t nbytes) { return openssl_bsock_readwrite(bsock, ptr, nbytes, true); } int tls_bsock_readn(BSOCK *bsock, char *ptr, int32_t nbytes) { return openssl_bsock_readwrite(bsock, ptr, nbytes, false); } #endif /* HAVE_TLS && HAVE_OPENSSL */ bareos-Release-14.2.6/src/lib/tree.c000066400000000000000000000407541263011562700171120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Directory tree build/traverse routines * * Kern Sibbald, June MMII */ #include "bareos.h" #define B_PAGE_SIZE 4096 #define MAX_PAGES 2400 #define MAX_BUF_SIZE (MAX_PAGES * B_PAGE_SIZE) /* approx 10MB */ /* Forward referenced subroutines */ static TREE_NODE *search_and_insert_tree_node(char *fname, int type, TREE_ROOT *root, TREE_NODE *parent); static char *tree_alloc(TREE_ROOT *root, int size); /* * NOTE !!!!! we turn off Debug messages for performance reasons. */ #undef Dmsg0 #undef Dmsg1 #undef Dmsg2 #undef Dmsg3 #define Dmsg0(n,f) #define Dmsg1(n,f,a1) #define Dmsg2(n,f,a1,a2) #define Dmsg3(n,f,a1,a2,a3) /* * This subroutine gets a big buffer. */ static void malloc_buf(TREE_ROOT *root, int size) { struct s_mem *mem; mem = (struct s_mem *)malloc(size); root->total_size += size; root->blocks++; mem->next = root->mem; root->mem = mem; mem->mem = mem->first; mem->rem = (char *)mem + size - mem->mem; Dmsg2(200, "malloc buf size=%d rem=%d\n", size, mem->rem); } /* * Note, we allocate a big buffer in the tree root * from which we allocate nodes. This runs more * than 100 times as fast as directly using malloc() * for each of the nodes. */ TREE_ROOT *new_tree(int count) { TREE_ROOT *root; uint32_t size; if (count < 1000) { /* minimum tree size */ count = 1000; } root = (TREE_ROOT *)malloc(sizeof(TREE_ROOT)); memset(root, 0, sizeof(TREE_ROOT)); /* * Assume filename + node = 40 characters average length */ size = count * (BALIGN(sizeof(TREE_NODE)) + 40); if (count > 1000000 || size > (MAX_BUF_SIZE / 2)) { size = MAX_BUF_SIZE; } Dmsg2(400, "count=%d size=%d\n", count, size); malloc_buf(root, size); root->cached_path_len = -1; root->cached_path = get_pool_memory(PM_FNAME); root->type = TN_ROOT; root->fname = ""; HL_ENTRY* entry = NULL; root->hardlinks.init(entry, &entry->link, 0, 1); return root; } /* * Create a new tree node. */ static TREE_NODE *new_tree_node(TREE_ROOT *root) { TREE_NODE *node; int size = sizeof(TREE_NODE); node = (TREE_NODE *)tree_alloc(root, size); memset(node, 0, size); node->delta_seq = -1; return node; } /* * This routine can be called to release the previously allocated tree node. */ static void free_tree_node(TREE_ROOT *root) { int asize = BALIGN(sizeof(TREE_NODE)); root->mem->rem += asize; root->mem->mem -= asize; } void tree_remove_node(TREE_ROOT *root, TREE_NODE *node) { int asize = BALIGN(sizeof(TREE_NODE)); node->parent->child.remove(node); if ((root->mem->mem - asize) == (char *)node) { free_tree_node(root); } else { Dmsg0(0, "Can't release tree node\n"); } } /* * Allocate bytes for filename in tree structure. * Keep the pointers properly aligned by allocating * sizes that are aligned. */ static char *tree_alloc(TREE_ROOT *root, int size) { char *buf; int asize = BALIGN(size); if (root->mem->rem < asize) { uint32_t mb_size; if (root->total_size >= (MAX_BUF_SIZE / 2)) { mb_size = MAX_BUF_SIZE; } else { mb_size = MAX_BUF_SIZE / 2; } malloc_buf(root, mb_size); } root->mem->rem -= asize; buf = root->mem->mem; root->mem->mem += asize; return buf; } /* * This routine frees the whole tree */ void free_tree(TREE_ROOT *root) { struct s_mem *mem, *rel; uint32_t freed_blocks = 0; root->hardlinks.destroy(); for (mem=root->mem; mem; ) { rel = mem; mem = mem->next; free(rel); freed_blocks++; } if (root->cached_path) { free_pool_memory(root->cached_path); root->cached_path = NULL; } Dmsg3(100, "Total size=%u blocks=%u freed_blocks=%u\n", root->total_size, root->blocks, freed_blocks); free(root); garbage_collect_memory(); return; } /* * Add Delta part for this node */ void tree_add_delta_part(TREE_ROOT *root, TREE_NODE *node, JobId_t JobId, int32_t FileIndex) { struct delta_list *elt = (struct delta_list *) tree_alloc(root, sizeof(struct delta_list)); elt->next = node->delta_list; elt->JobId = JobId; elt->FileIndex = FileIndex; node->delta_list = elt; } /* * Insert a node in the tree. This is the main subroutine called when building a tree. */ TREE_NODE *insert_tree_node(char *path, char *fname, int type, TREE_ROOT *root, TREE_NODE *parent) { char *p, *q; int path_len = strlen(path); TREE_NODE *node; Dmsg1(100, "insert_tree_node: %s\n", path); /* * If trailing slash on path, strip it */ if (path_len > 0) { q = path + path_len - 1; if (IsPathSeparator(*q)) { *q = 0; /* strip trailing slash */ } else { q = NULL; /* no trailing slash */ } } else { q = NULL; /* no trailing slash */ } /* * If no filename, strip last component of path as "filename" */ if (*fname == 0) { p = (char *)last_path_separator(path); /* separate path and filename */ if (p) { fname = p + 1; /* set new filename */ *p = '\0'; /* terminate new path */ } } else { p = NULL; } if (*fname) { if (!parent) { /* if no parent, we need to make one */ Dmsg1(100, "make_tree_path for %s\n", path); path_len = strlen(path); /* get new length */ if (path_len == root->cached_path_len && bstrcmp(path, root->cached_path)) { parent = root->cached_parent; } else { root->cached_path_len = path_len; pm_strcpy(&root->cached_path, path); parent = make_tree_path(path, root); root->cached_parent = parent; } Dmsg1(100, "parent=%s\n", parent->fname); } } else { fname = path; if (!parent) { parent = (TREE_NODE *)root; type = TN_DIR_NLS; } Dmsg1(100, "No / found: %s\n", path); } node = search_and_insert_tree_node(fname, 0, root, parent); if (q) { /* if trailing slash on entry */ *q = '/'; /* restore it */ } if (p) { /* if slash in path trashed */ *p = '/'; /* restore full path */ } return node; } /* * Ensure that all appropriate nodes for a full path exist in the tree. */ TREE_NODE *make_tree_path(char *path, TREE_ROOT *root) { TREE_NODE *parent, *node; char *fname, *p; int type = TN_NEWDIR; Dmsg1(100, "make_tree_path: %s\n", path); if (*path == 0) { Dmsg0(100, "make_tree_path: parent=*root*\n"); return (TREE_NODE *)root; } /* * Get last dir component of path */ p = (char *)last_path_separator(path); if (p) { fname = p + 1; *p = 0; /* terminate path */ parent = make_tree_path(path, root); *p = '/'; /* restore full name */ } else { fname = path; parent = (TREE_NODE *)root; type = TN_DIR_NLS; } node = search_and_insert_tree_node(fname, type, root, parent); return node; } static int node_compare(void *item1, void *item2) { TREE_NODE *tn1 = (TREE_NODE *)item1; TREE_NODE *tn2 = (TREE_NODE *)item2; if (tn1->fname[0] > tn2->fname[0]) { return 1; } else if (tn1->fname[0] < tn2->fname[0]) { return -1; } return strcmp(tn1->fname, tn2->fname); } /* * See if the fname already exists. If not insert a new node for it. */ static TREE_NODE *search_and_insert_tree_node(char *fname, int type, TREE_ROOT *root, TREE_NODE *parent) { TREE_NODE *node, *found_node; node = new_tree_node(root); node->fname = fname; found_node = (TREE_NODE *)parent->child.insert(node, node_compare); if (found_node != node) { /* already in list */ free_tree_node(root); /* free node allocated above */ found_node->inserted = false; return found_node; } /* * It was not found, but is now inserted */ node->fname_len = strlen(fname); node->fname = tree_alloc(root, node->fname_len + 1); strcpy(node->fname, fname); node->parent = parent; node->type = type; /* * Maintain a linear chain of nodes */ if (!root->first) { root->first = node; root->last = node; } else { root->last->next = node; root->last = node; } node->inserted = true; /* inserted into tree */ return node; } static void tree_getpath_item(TREE_NODE *node, POOLMEM **path) { if (!node) { return; } tree_getpath_item(node->parent, path); /* * Fixup for Win32. If we have a Win32 directory and * there is only a / in the buffer, remove it since * win32 names don't generally start with / */ if (node->type == TN_DIR_NLS && IsPathSeparator((*path[0])) && (*path)[1] == '\0') { pm_strcpy(path, ""); } pm_strcat(path, node->fname); /* * Add a slash for all directories unless we are at the root, * also add a slash to a soft linked file if it has children * i.e. it is linked to a directory. */ if ((node->type != TN_FILE && !(IsPathSeparator((*path)[0]) && (*path)[1] == '\0')) || (node->soft_link && tree_node_has_child(node))) { pm_strcat(path, "/"); } } POOLMEM *tree_getpath(TREE_NODE *node) { POOLMEM *path; if (!node) { return NULL; } /* * Allocate a new empty path. */ path = get_pool_memory(PM_NAME); pm_strcpy(path, ""); /* * Fill the path with the full path. */ tree_getpath_item(node, &path); return path; } /* * Change to specified directory */ TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node) { if (path[0] == '.' && path[1] == '\0') { return node; } /* * Handle relative path */ if (path[0] == '.' && path[1] == '.' && (IsPathSeparator(path[2]) || path[2] == '\0')) { TREE_NODE *parent = node->parent ? node->parent : node; if (path[2] == 0) { return parent; } else { return tree_cwd(path+3, root, parent); } } if (IsPathSeparator(path[0])) { Dmsg0(100, "Doing absolute lookup.\n"); return tree_relcwd(path+1, root, (TREE_NODE *)root); } Dmsg0(100, "Doing relative lookup.\n"); return tree_relcwd(path, root, node); } /* * Do a relative cwd -- i.e. relative to current node rather than root node */ TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node) { char *p; int len; TREE_NODE *cd; char save_char; int match; if (*path == 0) { return node; } /* * Check the current segment only */ if ((p = first_path_separator(path)) != NULL) { len = p - path; } else { len = strlen(path); } Dmsg2(100, "tree_relcwd: len=%d path=%s\n", len, path); foreach_child(cd, node) { Dmsg1(100, "tree_relcwd: test cd=%s\n", cd->fname); if (cd->fname[0] == path[0] && len == (int)strlen(cd->fname) && bstrncmp(cd->fname, path, len)) { break; } /* * fnmatch has no len in call so we truncate the string */ save_char = path[len]; path[len] = 0; match = fnmatch(path, cd->fname, 0) == 0; path[len] = save_char; if (match) { break; } } if (!cd || (cd->type == TN_FILE && !tree_node_has_child(cd))) { return NULL; } if (!p) { Dmsg0(100, "tree_relcwd: no more to lookup. found.\n"); return cd; } Dmsg2(100, "recurse tree_relcwd with path=%s, cd=%s\n", p+1, cd->fname); /* * Check the next segment if any */ return tree_relcwd(p+1, root, cd); } #ifdef BUILD_TEST_PROGRAM void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent); static uint32_t FileIndex = 0; /* * Simple test program for tree routines */ int main(int argc, char *argv[]) { TREE_ROOT *root; TREE_NODE *node; char buf[MAXPATHLEN]; root = new_tree(); root->fname = tree_alloc(root, 1); *root->fname = 0; root->fname_len = 0; FillDirectoryTree("/home/user/bareos", root, NULL); for (node = first_tree_node(root); node; node=next_tree_node(node)) { tree_getpath(node, buf, sizeof(buf)); Dmsg2(100, "%d: %s\n", node->FileIndex, buf); } node = (TREE_NODE *)root; Pmsg0(000, "doing cd /home/user/bareos/techlogs\n"); node = tree_cwd("/home/user/bareos/techlogs", root, node); if (node) { tree_getpath(node, buf, sizeof(buf)); Dmsg2(100, "findex=%d: cwd=%s\n", node->FileIndex, buf); } Pmsg0(000, "doing cd /home/user/bareos/src/testprogs\n"); node = tree_cwd("/home/user/bareos/src/testprogs", root, node); if (node) { tree_getpath(node, buf, sizeof(buf)); Dmsg2(100, "findex=%d: cwd=%s\n", node->FileIndex, buf); } else { Dmsg0(100, "testprogs not found.\n"); } free_tree((TREE_NODE *)root); return 0; } void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent) { TREE_NODE *newparent = NULL; TREE_NODE *node; struct stat statbuf; DIR *dp; struct dirent *dir; char pathbuf[MAXPATHLEN]; char file[MAXPATHLEN]; int type; int i; Dmsg1(100, "FillDirectoryTree: %s\n", path); dp = opendir(path); if (!dp) { return; } while ((dir = readdir(dp))) { if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) { continue; } bstrncpy(file, dir->d_name, sizeof(file)); snprintf(pathbuf, MAXPATHLEN-1, "%s/%s", path, file); if (lstat(pathbuf, &statbuf) < 0) { berrno be; printf("lstat() failed. ERR=%s\n", be.bstrerror(errno)); continue; } // printf("got file=%s, pathbuf=%s\n", file, pathbuf); type = TN_FILE; if (S_ISLNK(statbuf.st_mode)) type = TN_FILE; /* link */ else if (S_ISREG(statbuf.st_mode)) type = TN_FILE; else if (S_ISDIR(statbuf.st_mode)) { type = TN_DIR; } else if (S_ISCHR(statbuf.st_mode)) type = TN_FILE; /* char dev */ else if (S_ISBLK(statbuf.st_mode)) type = TN_FILE; /* block dev */ else if (S_ISFIFO(statbuf.st_mode)) type = TN_FILE; /* fifo */ else if (S_ISSOCK(statbuf.st_mode)) type = TN_FILE; /* sock */ else { type = TN_FILE; printf("Unknown file type: 0x%x\n", statbuf.st_mode); } Dmsg2(100, "Doing: %d %s\n", type, pathbuf); node = new_tree_node(root); node->FileIndex = ++FileIndex; parent = insert_tree_node(pathbuf, node, root, parent); if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) { Dmsg2(100, "calling fill. pathbuf=%s, file=%s\n", pathbuf, file); FillDirectoryTree(pathbuf, root, node); } } closedir(dp); } #ifndef MAXPATHLEN #define MAXPATHLEN 2000 #endif void print_tree(char *path, TREE_NODE *tree) { char buf[MAXPATHLEN]; char *termchr; if (!tree) { return; } switch (tree->type) { case TN_DIR_NLS: case TN_DIR: case TN_NEWDIR: termchr = "/"; break; case TN_ROOT: case TN_FILE: default: termchr = ""; break; } Pmsg3(-1, "%s/%s%s\n", path, tree->fname, termchr); switch (tree->type) { case TN_FILE: case TN_NEWDIR: case TN_DIR: case TN_DIR_NLS: bsnprintf(buf, sizeof(buf), "%s/%s", path, tree->fname); print_tree(buf, first_child(tree)); break; case TN_ROOT: print_tree(path, first_child(tree)); break; default: Pmsg1(000, "Unknown node type %d\n", tree->type); } print_tree(path, tree->sibling_); return; } #endif bareos-Release-14.2.6/src/lib/tree.h000066400000000000000000000132471263011562700171140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Directory tree build/traverse routines * * Kern Sibbald, June MMII */ #include "htable.h" struct s_mem { struct s_mem *next; /* next buffer */ int rem; /* remaining bytes */ char *mem; /* memory pointer */ char first[1]; /* first byte */ }; #define USE_DLIST #define foreach_child(var, list) \ for((var)=NULL; (*((TREE_NODE **)&(var))=(TREE_NODE*)(list->child.next(var))); ) #define tree_node_has_child(node) \ ((node)->child.size() > 0) #define first_child(node) \ ((TREE_NODE *)(node->child.first()) struct delta_list { struct delta_list *next; JobId_t JobId; int32_t FileIndex; }; /* * Keep this node as small as possible because * there is one for each file. */ struct s_tree_node { /* KEEP sibling as the first member to avoid having to * do initialization of child */ rblink sibling; rblist child; char *fname; /* file name */ int32_t FileIndex; /* file index */ uint32_t JobId; /* JobId */ int32_t delta_seq; /* current delta sequence */ uint16_t fname_len; /* filename length */ unsigned int type:8; /* node type */ unsigned int extract:1; /* extract item */ unsigned int extract_dir:1; /* extract dir entry only */ unsigned int hard_link:1; /* set if have hard link */ unsigned int soft_link:1; /* set if is soft link */ unsigned int inserted:1; /* set when node newly inserted */ unsigned int loaded:1; /* set when the dir is in the tree */ struct s_tree_node *parent; struct s_tree_node *next; /* next hash of FileIndex */ struct delta_list *delta_list; /* delta parts for this node */ }; typedef struct s_tree_node TREE_NODE; struct s_tree_root { /* KEEP sibling as the first member to avoid having to * do initialization of child */ rblink sibling; rblist child; const char *fname; /* file name */ int32_t FileIndex; /* file index */ uint32_t JobId; /* JobId */ int32_t delta_seq; /* current delta sequence */ uint16_t fname_len; /* filename length */ unsigned int type:8; /* node type */ unsigned int extract:1; /* extract item */ unsigned int extract_dir:1; /* extract dir entry only */ unsigned int have_link:1; /* set if have hard link */ unsigned int inserted:1; /* set when newly inserted */ unsigned int loaded:1; /* set when the dir is in the tree */ struct s_tree_node *parent; struct s_tree_node *next; /* next hash of FileIndex */ struct delta_list *delta_list; /* delta parts for this node */ /* The above ^^^ must be identical to a TREE_NODE structure */ struct s_tree_node *first; /* first entry in the tree */ struct s_tree_node *last; /* last entry in tree */ struct s_mem *mem; /* tree memory */ uint32_t total_size; /* total bytes allocated */ uint32_t blocks; /* total mallocs */ int cached_path_len; /* length of cached path */ char *cached_path; /* cached current path */ TREE_NODE *cached_parent; /* cached parent for above path */ htable hardlinks; /* references to first occurence of hardlinks */ }; typedef struct s_tree_root TREE_ROOT; /* hardlink hashtable entry */ struct s_hl_entry { uint64_t key; hlink link; TREE_NODE *node; }; typedef struct s_hl_entry HL_ENTRY; /* type values */ #define TN_ROOT 1 /* root node */ #define TN_NEWDIR 2 /* created directory to fill path */ #define TN_DIR 3 /* directory entry */ #define TN_DIR_NLS 4 /* directory -- no leading slash -- win32 */ #define TN_FILE 5 /* file entry */ /* External interface */ TREE_ROOT *new_tree(int count); TREE_NODE *insert_tree_node(char *path, char *fname, int type, TREE_ROOT *root, TREE_NODE *parent); TREE_NODE *make_tree_path(char *path, TREE_ROOT *root); TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node); TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node); void tree_add_delta_part(TREE_ROOT *root, TREE_NODE *node, JobId_t JobId, int32_t FileIndex); void free_tree(TREE_ROOT *root); POOLMEM *tree_getpath(TREE_NODE *node); void tree_remove_node(TREE_ROOT *root, TREE_NODE *node); /* * Use the following for traversing the whole tree. It will be * traversed in the order the entries were inserted into the * tree. */ #define first_tree_node(r) (r)->first #define next_tree_node(n) (n)->next bareos-Release-14.2.6/src/lib/util.c000066400000000000000000000535041263011562700171250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * util.c miscellaneous utility subroutines for BAREOS * * Kern Sibbald, MM */ #include "bareos.h" #include "jcr.h" /* * Various BAREOS Utility subroutines * */ /* * Escape special characters in bareos configuration strings * needed for dumping config strings */ void escape_string(char *snew, char *old, int len) { char *n, *o; n = snew; o = old; while (len--) { switch (*o) { case '\'': *n++ = '\''; *n++ = '\''; o++; break; case 0: *n++ = '\\'; *n++ = 0; o++; break; case '(': case ')': case '<': case '>': case '"': *n++ = '\\'; *n++ = *o++; break; default: *n++ = *o++; break; } } *n = 0; } /* Return true of buffer has all zero bytes */ bool is_buf_zero(char *buf, int len) { uint64_t *ip; char *p; int i, len64, done, rem; if (buf[0] != 0) { return false; } ip = (uint64_t *)buf; /* Optimize by checking uint64_t for zero */ len64 = len / sizeof(uint64_t); for (i=0; i < len64; i++) { if (ip[i] != 0) { return false; } } done = len64 * sizeof(uint64_t); /* bytes already checked */ p = buf + done; rem = len - done; for (i = 0; i < rem; i++) { if (p[i] != 0) { return false; } } return true; } /* Convert a string in place to lower case */ void lcase(char *str) { while (*str) { if (B_ISUPPER(*str)) { *str = tolower((int)(*str)); } str++; } } /* Convert spaces to non-space character. * This makes scanf of fields containing spaces easier. */ void bash_spaces(char *str) { while (*str) { if (*str == ' ') *str = 0x1; str++; } } /* Convert spaces to non-space character. * This makes scanf of fields containing spaces easier. */ void bash_spaces(POOL_MEM &pm) { char *str = pm.c_str(); while (*str) { if (*str == ' ') *str = 0x1; str++; } } /* Convert non-space characters (0x1) back into spaces */ void unbash_spaces(char *str) { while (*str) { if (*str == 0x1) *str = ' '; str++; } } /* Convert non-space characters (0x1) back into spaces */ void unbash_spaces(POOL_MEM &pm) { char *str = pm.c_str(); while (*str) { if (*str == 0x1) *str = ' '; str++; } } char *encode_time(utime_t utime, char *buf) { struct tm tm; int n = 0; time_t time = utime; #if defined(HAVE_WIN32) /* * Avoid a seg fault in Microsoft's CRT localtime_r(), * which incorrectly references a NULL returned from gmtime() if * time is negative before or after the timezone adjustment. */ struct tm *gtm; if ((gtm = gmtime(&time)) == NULL) { return buf; } if (gtm->tm_year == 1970 && gtm->tm_mon == 1 && gtm->tm_mday < 3) { return buf; } #endif blocaltime(&time, &tm); n = sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); return buf+n; } /* * Convert a JobStatus code into a human readable form */ void jobstatus_to_ascii(int JobStatus, char *msg, int maxlen) { const char *jobstat; char buf[100]; switch (JobStatus) { case JS_Created: jobstat = _("Created"); break; case JS_Running: jobstat = _("Running"); break; case JS_Blocked: jobstat = _("Blocked"); break; case JS_Terminated: jobstat = _("OK"); break; case JS_Incomplete: jobstat = _("Error: incomplete job"); break; case JS_FatalError: jobstat = _("Fatal Error"); break; case JS_ErrorTerminated: jobstat = _("Error"); break; case JS_Error: jobstat = _("Non-fatal error"); break; case JS_Warnings: jobstat = _("OK -- with warnings"); break; case JS_Canceled: jobstat = _("Canceled"); break; case JS_Differences: jobstat = _("Verify differences"); break; case JS_WaitFD: jobstat = _("Waiting on FD"); break; case JS_WaitSD: jobstat = _("Wait on SD"); break; case JS_WaitMedia: jobstat = _("Wait for new Volume"); break; case JS_WaitMount: jobstat = _("Waiting for mount"); break; case JS_WaitStoreRes: jobstat = _("Waiting for Storage resource"); break; case JS_WaitJobRes: jobstat = _("Waiting for Job resource"); break; case JS_WaitClientRes: jobstat = _("Waiting for Client resource"); break; case JS_WaitMaxJobs: jobstat = _("Waiting on Max Jobs"); break; case JS_WaitStartTime: jobstat = _("Waiting for Start Time"); break; case JS_WaitPriority: jobstat = _("Waiting on Priority"); break; case JS_DataCommitting: jobstat = _("SD committing Data"); break; case JS_DataDespooling: jobstat = _("SD despooling Data"); break; case JS_AttrDespooling: jobstat = _("SD despooling Attributes"); break; case JS_AttrInserting: jobstat = _("Dir inserting Attributes"); break; default: if (JobStatus == 0) { buf[0] = 0; } else { bsnprintf(buf, sizeof(buf), _("Unknown Job termination status=%d"), JobStatus); } jobstat = buf; break; } bstrncpy(msg, jobstat, maxlen); } /* * Convert a JobStatus code into a human readable form - gui version */ void jobstatus_to_ascii_gui(int JobStatus, char *msg, int maxlen) { const char *cnv = NULL; switch (JobStatus) { case JS_Terminated: cnv = _("Completed successfully"); break; case JS_Warnings: cnv = _("Completed with warnings"); break; case JS_ErrorTerminated: cnv = _("Terminated with errors"); break; case JS_FatalError: cnv = _("Fatal error"); break; case JS_Created: cnv = _("Created, not yet running"); break; case JS_Canceled: cnv = _("Canceled by user"); break; case JS_Differences: cnv = _("Verify found differences"); break; case JS_WaitFD: cnv = _("Waiting for File daemon"); break; case JS_WaitSD: cnv = _("Waiting for Storage daemon"); break; case JS_WaitPriority: cnv = _("Waiting for higher priority jobs"); break; case JS_AttrInserting: cnv = _("Batch inserting file records"); break; }; if (cnv) { bstrncpy(msg, cnv, maxlen); } else { jobstatus_to_ascii(JobStatus, msg, maxlen); } } /* * Convert Job Termination Status into a string */ const char *job_status_to_str(int stat) { const char *str; switch (stat) { case JS_Terminated: str = _("OK"); break; case JS_Warnings: str = _("OK -- with warnings"); break; case JS_ErrorTerminated: case JS_Error: str = _("Error"); break; case JS_FatalError: str = _("Fatal Error"); break; case JS_Canceled: str = _("Canceled"); break; case JS_Differences: str = _("Differences"); break; default: str = _("Unknown term code"); break; } return str; } /* * Convert Job Type into a string */ const char *job_type_to_str(int type) { const char *str = NULL; switch (type) { case JT_BACKUP: str = _("Backup"); break; case JT_MIGRATED_JOB: str = _("Migrated Job"); break; case JT_VERIFY: str = _("Verify"); break; case JT_RESTORE: str = _("Restore"); break; case JT_CONSOLE: str = _("Console"); break; case JT_SYSTEM: str = _("System or Console"); break; case JT_ADMIN: str = _("Admin"); break; case JT_ARCHIVE: str = _("Archive"); break; case JT_JOB_COPY: str = _("Job Copy"); break; case JT_COPY: str = _("Copy"); break; case JT_MIGRATE: str = _("Migrate"); break; case JT_SCAN: str = _("Scan"); break; } if (!str) { str = _("Unknown Type"); } return str; } /* Convert ActionOnPurge to string (Truncate, Erase, Destroy) */ char *action_on_purge_to_string(int aop, POOL_MEM &ret) { if (aop & ON_PURGE_TRUNCATE) { pm_strcpy(ret, _("Truncate")); } if (!aop) { pm_strcpy(ret, _("None")); } return ret.c_str(); } /* * Convert Job Level into a string */ const char *job_level_to_str(int level) { const char *str; switch (level) { case L_BASE: str = _("Base"); break; case L_FULL: str = _("Full"); break; case L_INCREMENTAL: str = _("Incremental"); break; case L_DIFFERENTIAL: str = _("Differential"); break; case L_SINCE: str = _("Since"); break; case L_VERIFY_CATALOG: str = _("Verify Catalog"); break; case L_VERIFY_INIT: str = _("Verify Init Catalog"); break; case L_VERIFY_VOLUME_TO_CATALOG: str = _("Verify Volume to Catalog"); break; case L_VERIFY_DISK_TO_CATALOG: str = _("Verify Disk to Catalog"); break; case L_VERIFY_DATA: str = _("Verify Data"); break; case L_VIRTUAL_FULL: str = _("Virtual Full"); break; case L_NONE: str = " "; break; default: str = _("Unknown Job Level"); break; } return str; } const char *volume_status_to_str(const char *status) { int pos; const char *vs[] = { NT_("Append"), _("Append"), NT_("Archive"), _("Archive"), NT_("Disabled"), _("Disabled"), NT_("Full"), _("Full"), NT_("Used"), _("Used"), NT_("Cleaning"), _("Cleaning"), NT_("Purged"), _("Purged"), NT_("Recycle"), _("Recycle"), NT_("Read-Only"), _("Read-Only"), NT_("Error"), _("Error"), NULL, NULL}; if (status) { for (pos = 0 ; vs[pos] ; pos += 2) { if (bstrcmp(vs[pos], status)) { return vs[pos+1]; } } } return _("Invalid volume status"); } /*********************************************************************** * Encode the mode bits into a 10 character string like LS does ***********************************************************************/ char *encode_mode(mode_t mode, char *buf) { char *cp = buf; *cp++ = S_ISDIR(mode) ? 'd' : S_ISBLK(mode) ? 'b' : S_ISCHR(mode) ? 'c' : S_ISLNK(mode) ? 'l' : S_ISFIFO(mode) ? 'f' : S_ISSOCK(mode) ? 's' : '-'; *cp++ = mode & S_IRUSR ? 'r' : '-'; *cp++ = mode & S_IWUSR ? 'w' : '-'; *cp++ = (mode & S_ISUID ? (mode & S_IXUSR ? 's' : 'S') : (mode & S_IXUSR ? 'x' : '-')); *cp++ = mode & S_IRGRP ? 'r' : '-'; *cp++ = mode & S_IWGRP ? 'w' : '-'; *cp++ = (mode & S_ISGID ? (mode & S_IXGRP ? 's' : 'S') : (mode & S_IXGRP ? 'x' : '-')); *cp++ = mode & S_IROTH ? 'r' : '-'; *cp++ = mode & S_IWOTH ? 'w' : '-'; *cp++ = (mode & S_ISVTX ? (mode & S_IXOTH ? 't' : 'T') : (mode & S_IXOTH ? 'x' : '-')); *cp = '\0'; return cp; } #if defined(HAVE_WIN32) int do_shell_expansion(char *name, int name_len) { char *src = bstrdup(name); ExpandEnvironmentStrings(src, name, name_len); free(src); return 1; } #else int do_shell_expansion(char *name, int name_len) { static char meta[] = "~\\$[]*?`'<>\""; bool found = false; int len, i, status; POOLMEM *cmd, *line; BPIPE *bpipe; const char *shellcmd; /* Check if any meta characters are present */ len = strlen(meta); for (i = 0; i < len; i++) { if (strchr(name, meta[i])) { found = true; break; } } if (found) { cmd = get_pool_memory(PM_FNAME); line = get_pool_memory(PM_FNAME); /* look for shell */ if ((shellcmd = getenv("SHELL")) == NULL) { shellcmd = "/bin/sh"; } pm_strcpy(&cmd, shellcmd); pm_strcat(&cmd, " -c \"echo "); pm_strcat(&cmd, name); pm_strcat(&cmd, "\""); Dmsg1(400, "Send: %s\n", cmd); if ((bpipe = open_bpipe(cmd, 0, "r"))) { bfgets(line, bpipe->rfd); strip_trailing_junk(line); status = close_bpipe(bpipe); Dmsg2(400, "status=%d got: %s\n", status, line); } else { status = 1; /* error */ } free_pool_memory(cmd); free_pool_memory(line); if (status == 0) { bstrncpy(name, line, name_len); } } return 1; } #endif /* MAKESESSIONKEY -- Generate session key with optional start key. If mode is TRUE, the key will be translated to a string, otherwise it is returned as 16 binary bytes. from SpeakFreely by John Walker */ void make_session_key(char *key, char *seed, int mode) { int j, k; MD5_CTX md5c; unsigned char md5key[16], md5key1[16]; char s[1024]; #define ss sizeof(s) s[0] = 0; if (seed != NULL) { bstrncat(s, seed, sizeof(s)); } /* The following creates a seed for the session key generator based on a collection of volatile and environment-specific information unlikely to be vulnerable (as a whole) to an exhaustive search attack. If one of these items isn't available on your machine, replace it with something equivalent or, if you like, just delete it. */ #if defined(HAVE_WIN32) { LARGE_INTEGER li; DWORD length; FILETIME ft; bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)GetCurrentProcessId()); (void)getcwd(s + strlen(s), 256); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)GetTickCount()); QueryPerformanceCounter(&li); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)li.LowPart); GetSystemTimeAsFileTime(&ft); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)ft.dwLowDateTime); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)ft.dwHighDateTime); length = 256; GetComputerName(s + strlen(s), &length); length = 256; GetUserName(s + strlen(s), &length); } #else bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)getpid()); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)getppid()); (void)getcwd(s + strlen(s), 256); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)clock()); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)time(NULL)); #if defined(Solaris) sysinfo(SI_HW_SERIAL,s + strlen(s), 12); #endif #if defined(HAVE_GETHOSTID) bsnprintf(s + strlen(s), ss, "%lu", (uint32_t) gethostid()); #endif gethostname(s + strlen(s), 256); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)getuid()); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)getgid()); #endif MD5_Init(&md5c); MD5_Update(&md5c, (uint8_t *)s, strlen(s)); MD5_Final(md5key, &md5c); bsnprintf(s + strlen(s), ss, "%lu", (uint32_t)((time(NULL) + 65121) ^ 0x375F)); MD5_Init(&md5c); MD5_Update(&md5c, (uint8_t *)s, strlen(s)); MD5_Final(md5key1, &md5c); #define nextrand (md5key[j] ^ md5key1[j]) if (mode) { for (j = k = 0; j < 16; j++) { unsigned char rb = nextrand; #define Rad16(x) ((x) + 'A') key[k++] = Rad16((rb >> 4) & 0xF); key[k++] = Rad16(rb & 0xF); #undef Rad16 if (j & 1) { key[k++] = '-'; } } key[--k] = 0; } else { for (j = 0; j < 16; j++) { key[j] = nextrand; } } } #undef nextrand void encode_session_key(char *encode, char *session, char *key, int maxlen) { int i; for (i = 0; (i < maxlen - 1) && session[i]; i++) { if (session[i] == '-') { encode[i] = '-'; } else { encode[i] = ((session[i] - 'A' + key[i]) & 0xF) + 'A'; } } encode[i] = 0; Dmsg3(000, "Session=%s key=%s encode=%s\n", session, key, encode); } void decode_session_key(char *decode, char *session, char *key, int maxlen) { int i, x; for (i = 0; (i < maxlen - 1) && session[i]; i++) { if (session[i] == '-') { decode[i] = '-'; } else { x = (session[i] - 'A' - key[i]) & 0xF; if (x < 0) { x += 16; } decode[i] = x + 'A'; } } decode[i] = 0; Dmsg3(000, "Session=%s key=%s decode=%s\n", session, key, decode); } /* * Edit job codes into main command line * %% = % * %B = Job Bytes in human readable format * %F = Job Files * %P = Pid of daemon * %b = Job Bytes * %c = Client's name * %d = Director's name * %e = Job Exit code * %i = JobId * %j = Unique Job id * %l = job level * %n = Unadorned Job name * %s = Since time * %t = Job type (Backup, ...) * %r = Recipients * %v = Volume name(s) * * omsg = edited output message * imsg = input string containing edit codes (%x) * to = recipients list */ POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to, job_code_callback_t callback) { char *p, *q; const char *str; char add[50]; char name[MAX_NAME_LENGTH]; int i; *omsg = 0; Dmsg1(200, "edit_job_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'B': /* Job Bytes in human readable format */ str = edit_uint64_with_suffix(jcr->JobBytes, add); break; case 'F': /* Job Files */ str = edit_uint64(jcr->JobFiles, add); break; case 'P': bsnprintf(add, sizeof(add), "%lu", (uint32_t)getpid()); str = add; break; case 'b': /* Job Bytes */ str = edit_uint64(jcr->JobBytes, add); break; case 'c': if (jcr) { str = jcr->client_name; } else { str = _("*none*"); } break; case 'd': str = my_name; /* Director's name */ break; case 'e': if (jcr) { str = job_status_to_str(jcr->JobStatus); } else { str = _("*none*"); } break; case 'i': if (jcr) { bsnprintf(add, sizeof(add), "%d", jcr->JobId); str = add; } else { str = _("*none*"); } break; case 'j': /* Job name */ if (jcr) { str = jcr->Job; } else { str = _("*none*"); } break; case 'l': if (jcr) { str = job_level_to_str(jcr->getJobLevel()); } else { str = _("*none*"); } break; case 'n': if (jcr) { bstrncpy(name, jcr->Job, sizeof(name)); /* * There are three periods after the Job name */ for (i = 0; i < 3; i++) { if ((q=strrchr(name, '.')) != NULL) { *q = 0; } } str = name; } else { str = _("*none*"); } break; case 'r': str = to; break; case 's': /* Since time */ if (jcr && jcr->stime) { str = jcr->stime; } else { str = _("*none*"); } break; case 't': if (jcr) { str = job_type_to_str(jcr->getJobType()); } else { str = _("*none*"); } break; case 'v': if (jcr) { if (jcr->VolumeName) { str = jcr->VolumeName; } else { str = _("*none*"); } } else { str = _("*none*"); } break; default: str = NULL; if (callback != NULL) { str = callback(jcr, p); } if (!str) { add[0] = '%'; add[1] = *p; add[2] = 0; str = add; } break; } } else { add[0] = *p; add[1] = 0; str = add; } Dmsg1(1200, "add_str %s\n", str); pm_strcat(&omsg, str); Dmsg1(1200, "omsg=%s\n", omsg); } return omsg; } void set_working_directory(char *wd) { struct stat stat_buf; if (wd == NULL) { Emsg0(M_ERROR_TERM, 0, _("Working directory not defined. Cannot continue.\n")); } if (stat(wd, &stat_buf) != 0) { Emsg1(M_ERROR_TERM, 0, _("Working Directory: \"%s\" not found. Cannot continue.\n"), wd); } if (!S_ISDIR(stat_buf.st_mode)) { Emsg1(M_ERROR_TERM, 0, _("Working Directory: \"%s\" is not a directory. Cannot continue.\n"), wd); } working_directory = wd; /* set global */ } const char *last_path_separator(const char *str) { if (*str != '\0') { for (const char *p = &str[strlen(str) - 1]; p >= str; p--) { if (IsPathSeparator(*p)) { return p; } } } return NULL; } bareos-Release-14.2.6/src/lib/var.c000066400000000000000000002361621263011562700167430ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * OSSP var - Variable Expansion * Copyright (c) 2001-2002 Ralf S. Engelschall * Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/) * Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) * * This file is part of OSSP var, a variable expansion * library which can be found at http://www.ossp.org/pkg/lib/var/. * * Permission to use, copy, modify, and distribute this software for * any purpose with or without fee is hereby granted, provided that * the above copyright notice and this permission notice appear in all * copies. * * For disclaimer see below. */ /* * Adapted by Kern Sibbald to BACULA June 2003 */ #include "bareos.h" #if defined(HAVE_PCREPOSIX) # include #elif defined(HAVE_WIN32) # include "bregex.h" #else # include #endif #include "var.h" /* support for OSSP ex based exception throwing */ #ifdef WITH_EX #include "ex.h" #define VAR_RC(rv) \ ( (rv) != VAR_OK && (ex_catching && !ex_shielding) \ ? (ex_throw(var_id, NULL, (rv)), (rv)) : (rv) ) #else #define VAR_RC(rv) (rv) #endif /* WITH_EX */ #ifndef EOS #define EOS '\0' #endif /* ** ** ==== INTERNAL DATA STRUCTURES ==== ** */ typedef char char_class_t[256]; /* 256 == 2 ^ sizeof(unsigned char)*8 */ /* the external context structure */ struct var_st { var_syntax_t syntax; char_class_t syntax_nameclass; var_cb_value_t cb_value_fct; void *cb_value_ctx; var_cb_operation_t cb_operation_fct; void *cb_operation_ctx; }; /* the internal expansion context structure */ struct var_parse_st { struct var_parse_st *lower; int force_expand; int rel_lookup_flag; int rel_lookup_cnt; int index_this; }; typedef struct var_parse_st var_parse_t; /* the default syntax configuration */ static const var_syntax_t var_syntax_default = { '\\', /* escape */ '$', /* delim_init */ '{', /* delim_open */ '}', /* delim_close */ '[', /* index_open */ ']', /* index_close */ '#', /* index_mark */ "a-zA-Z0-9_" /* name_chars */ }; /* ** ** ==== FORMATTING FUNCTIONS ==== ** */ /* minimal output-independent vprintf(3) variant which supports %{c,s,d,%} only */ static int var_mvxprintf( int (*output)(void *ctx, const char *buffer, int bufsize), void *ctx, const char *format, va_list ap) { /* sufficient integer buffer: x log_10(2) + safety */ char ibuf[((sizeof(int)*8)/3)+10]; const char *cp; char c; int d; int n; int bytes; if (format == NULL) return -1; bytes = 0; while (*format != '\0') { if (*format == '%') { c = *(format+1); if (c == '%') { /* expand "%%" */ cp = &c; n = sizeof(char); } else if (c == 'c') { /* expand "%c" */ c = (char)va_arg(ap, int); cp = &c; n = sizeof(char); } else if (c == 's') { /* expand "%s" */ if ((cp = (char *)va_arg(ap, char *)) == NULL) cp = "(null)"; n = strlen(cp); } else if (c == 'd') { /* expand "%d" */ d = (int)va_arg(ap, int); bsnprintf(ibuf, sizeof(ibuf), "%d", d); /* explicitly secure */ cp = ibuf; n = strlen(cp); } else { /* any other "%X" */ cp = (char *)format; n = 2; } format += 2; } else { /* plain text */ cp = (char *)format; if ((format = strchr(cp, '%')) == NULL) format = strchr(cp, '\0'); n = format - cp; } /* perform output operation */ if (output != NULL) if ((n = output(ctx, cp, n)) == -1) break; bytes += n; } return bytes; } /* output callback function context for var_mvsnprintf() */ typedef struct { char *bufptr; int buflen; } var_mvsnprintf_cb_t; /* output callback function for var_mvsnprintf() */ static int var_mvsnprintf_cb( void *_ctx, const char *buffer, int bufsize) { var_mvsnprintf_cb_t *ctx = (var_mvsnprintf_cb_t *)_ctx; if (bufsize > ctx->buflen) return -1; memcpy(ctx->bufptr, buffer, bufsize); ctx->bufptr += bufsize; ctx->buflen -= bufsize; return bufsize; } /* minimal vsnprintf(3) variant which supports %{c,s,d} only */ static int var_mvsnprintf( char *buffer, int bufsize, const char *format, va_list ap) { int n; var_mvsnprintf_cb_t ctx; if (format == NULL) return -1; if (buffer != NULL && bufsize == 0) return -1; if (buffer == NULL) /* just determine output length */ n = var_mvxprintf(NULL, NULL, format, ap); else { /* perform real output */ ctx.bufptr = buffer; ctx.buflen = bufsize; n = var_mvxprintf(var_mvsnprintf_cb, &ctx, format, ap); if (n != -1 && ctx.buflen == 0) n = -1; if (n != -1) *(ctx.bufptr) = '\0'; } return n; } /* ** ** ==== PARSE CONTEXT FUNCTIONS ==== ** */ static var_parse_t * var_parse_push( var_parse_t *lower, var_parse_t *upper) { if (upper == NULL) return NULL; memcpy(upper, lower, sizeof(var_parse_t)); upper->lower = lower; return upper; } static var_parse_t * var_parse_pop( var_parse_t *upper) { if (upper == NULL) return NULL; return upper->lower; } /* ** ** ==== TOKEN BUFFER FUNCTIONS ==== ** */ #define TOKENBUF_INITIAL_BUFSIZE 64 typedef struct { const char *begin; const char *end; int buffer_size; } tokenbuf_t; static void tokenbuf_init( tokenbuf_t *buf) { buf->begin = NULL; buf->end = NULL; buf->buffer_size = 0; return; } static int tokenbuf_isundef( tokenbuf_t *buf) { if (buf->begin == NULL && buf->end == NULL) return 1; return 0; } static int tokenbuf_isempty( tokenbuf_t *buf) { if (buf->begin == buf->end) return 1; return 0; } static void tokenbuf_set( tokenbuf_t *buf, const char *begin, const char *end, int buffer_size) { buf->begin = begin; buf->end = end; buf->buffer_size = buffer_size; return; } static void tokenbuf_move( tokenbuf_t *src, tokenbuf_t *dst) { dst->begin = src->begin; dst->end = src->end; dst->buffer_size = src->buffer_size; tokenbuf_init(src); return; } static int tokenbuf_assign( tokenbuf_t *buf, const char *data, int len) { char *p; if ((p = (char *)malloc(len + 1)) == NULL) return 0; memcpy(p, data, len); buf->begin = p; buf->end = p + len; buf->buffer_size = len + 1; *((char *)(buf->end)) = EOS; return 1; } static int tokenbuf_append( tokenbuf_t *output, const char *data, int len) { char *new_buffer; int new_size; char *tmp; /* Is the tokenbuffer initialized at all? If not, allocate a standard-sized buffer to begin with. */ if (output->begin == NULL) { if ((output->begin = output->end = (const char *)malloc(TOKENBUF_INITIAL_BUFSIZE)) == NULL) return 0; output->buffer_size = TOKENBUF_INITIAL_BUFSIZE; } /* does the token contain text, but no buffer has been allocated yet? */ if (output->buffer_size == 0) { /* check whether data borders to output. If, we can append simly by increasing the end pointer. */ if (output->end == data) { output->end += len; return 1; } /* ok, so copy the contents of output into an allocated buffer so that we can append that way. */ if ((tmp = (char *)malloc(output->end - output->begin + len + 1)) == NULL) return 0; memcpy(tmp, output->begin, output->end - output->begin); output->buffer_size = output->end - output->begin; output->begin = tmp; output->end = tmp + output->buffer_size; output->buffer_size += len + 1; } /* does the token fit into the current buffer? If not, realloc a larger buffer that fits. */ if ((output->buffer_size - (output->end - output->begin)) <= len) { new_size = output->buffer_size; do { new_size *= 2; } while ((new_size - (output->end - output->begin)) <= len); if ((new_buffer = (char *)realloc((char *)output->begin, new_size)) == NULL) return 0; output->end = new_buffer + (output->end - output->begin); output->begin = new_buffer; output->buffer_size = new_size; } /* append the data at the end of the current buffer. */ if (len > 0) memcpy((char *)output->end, data, len); output->end += len; *((char *)output->end) = EOS; return 1; } static int tokenbuf_merge( tokenbuf_t *output, tokenbuf_t *input) { return tokenbuf_append(output, input->begin, input->end - input->begin); } static void tokenbuf_free( tokenbuf_t *buf) { if (buf->begin != NULL && buf->buffer_size > 0) free((char *)buf->begin); buf->begin = buf->end = NULL; buf->buffer_size = 0; return; } /* ** ** ==== CHARACTER CLASS EXPANSION ==== ** */ static void expand_range(char a, char b, char_class_t chrclass) { do { chrclass[(int)a] = 1; } while (++a <= b); return; } static var_rc_t expand_character_class(const char *desc, char_class_t chrclass) { int i; /* clear the class array. */ for (i = 0; i < 256; ++i) chrclass[i] = 0; /* walk through class description and set appropriate entries in array */ while (*desc != EOS) { if (desc[1] == '-' && desc[2] != EOS) { if (desc[0] > desc[2]) return VAR_ERR_INCORRECT_CLASS_SPEC; expand_range(desc[0], desc[2], chrclass); desc += 3; } else { chrclass[(int) *desc] = 1; desc++; } } return VAR_OK; } /* ** ** ==== ESCAPE SEQUENCE EXPANSION FUNCTIONS ==== ** */ static int expand_isoct( int c) { if (c >= '0' && c <= '7') return 1; else return 0; } static var_rc_t expand_octal( const char **src, char **dst, const char *end) { int c; if (end - *src < 3) return VAR_ERR_INCOMPLETE_OCTAL; if ( !expand_isoct(**src) || !expand_isoct((*src)[1]) || !expand_isoct((*src)[2])) return VAR_ERR_INVALID_OCTAL; c = **src - '0'; if (c > 3) return VAR_ERR_OCTAL_TOO_LARGE; c *= 8; (*src)++; c += **src - '0'; c *= 8; (*src)++; c += **src - '0'; **dst = (char) c; (*dst)++; return VAR_OK; } static int expand_ishex( int c) { if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) return 1; else return 0; } static var_rc_t expand_simple_hex( const char **src, char **dst, const char *end) { int c = 0; if (end - *src < 2) return VAR_ERR_INCOMPLETE_HEX; if ( !expand_ishex(**src) || !expand_ishex((*src)[1])) return VAR_ERR_INVALID_HEX; if (**src >= '0' && **src <= '9') c = **src - '0'; else if (**src >= 'a' && **src <= 'f') c = **src - 'a' + 10; else if (**src >= 'A' && **src <= 'F') c = **src - 'A' + 10; c = c << 4; (*src)++; if (**src >= '0' && **src <= '9') c += **src - '0'; else if (**src >= 'a' && **src <= 'f') c += **src - 'a' + 10; else if (**src >= 'A' && **src <= 'F') c += **src - 'A' + 10; **dst = (char)c; (*dst)++; return VAR_OK; } static var_rc_t expand_grouped_hex( const char **src, char **dst, const char *end) { var_rc_t rc; while (*src < end && **src != '}') { if ((rc = expand_simple_hex(src, dst, end)) != VAR_OK) return rc; (*src)++; } if (*src == end) return VAR_ERR_INCOMPLETE_GROUPED_HEX; return VAR_OK; } static var_rc_t expand_hex( const char **src, char **dst, const char *end) { if (*src == end) return VAR_ERR_INCOMPLETE_HEX; if (**src == '{') { (*src)++; return expand_grouped_hex(src, dst, end); } else return expand_simple_hex(src, dst, end); } /* ** ** ==== RECURSIVE-DESCEND VARIABLE EXPANSION PARSER ==== ** */ /* forward declarations */ static int parse_variable(var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result); static int parse_numexp (var_t *var, var_parse_t *ctx, const char *begin, const char *end, int *result, int *failed); static int parse_name (var_t *var, var_parse_t *ctx, const char *begin, const char *end); /* parse pattern text */ static int parse_pattern( var_t *var, var_parse_t *ctx, const char *begin, const char *end) { const char *p; /* parse until '/' */ for (p = begin; p != end && *p != '/'; p++) { if (*p == var->syntax.escape) { if (p + 1 == end) return VAR_ERR_INCOMPLETE_QUOTED_PAIR; p++; } } return (p - begin); } /* parse substitution text */ static int parse_substext( var_t *var, var_parse_t *ctx, const char *begin, const char *end) { const char *p; /* parse until delim_init or '/' */ for (p = begin; p != end && *p != var->syntax.delim_init && *p != '/'; p++) { if (*p == var->syntax.escape) { if (p + 1 == end) return VAR_ERR_INCOMPLETE_QUOTED_PAIR; p++; } } return (p - begin); } /* parse expression text */ static int parse_exptext( var_t *var, var_parse_t *ctx, const char *begin, const char *end) { const char *p; /* parse until delim_init or delim_close or ':' */ for (p = begin; p != end && *p != var->syntax.delim_init && *p != var->syntax.delim_close && *p != ':'; p++) { if (*p == var->syntax.escape) { if (p + 1 == end) return VAR_ERR_INCOMPLETE_QUOTED_PAIR; p++; } } return (p - begin); } /* parse opertion argument text */ static int parse_opargtext( var_t *var, var_parse_t *ctx, const char *begin, const char *end) { const char *p; /* parse until delim_init or ')' */ for (p = begin; p != end && *p != var->syntax.delim_init && *p != ')'; p++) { if (*p == var->syntax.escape) { if (p + 1 == end) return VAR_ERR_INCOMPLETE_QUOTED_PAIR; p++; } } return (p - begin); } static int parse_opargtext_or_variable( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result) { const char *p; tokenbuf_t tmp; int rc; tokenbuf_init(result); tokenbuf_init(&tmp); p = begin; if (p == end) return 0; do { rc = parse_opargtext(var, ctx, p, end); if (rc < 0) goto error_return; if (rc > 0) { if (!tokenbuf_append(result, p, rc)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } p += rc; } rc = parse_variable(var, ctx, p, end, &tmp); if (rc < 0) goto error_return; if (rc > 0) { p += rc; if (!tokenbuf_merge(result, &tmp)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } } tokenbuf_free(&tmp); /* KES 11/9/2003 */ } while (rc > 0); tokenbuf_free(&tmp); return (p - begin); error_return: tokenbuf_free(&tmp); tokenbuf_free(result); return rc; } /* parse expression or variable */ static int parse_exptext_or_variable( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result) { const char *p = begin; tokenbuf_t tmp; int rc; tokenbuf_init(result); tokenbuf_init(&tmp); if (begin == end) return 0; do { /* try to parse expression text */ rc = parse_exptext(var, ctx, p, end); if (rc < 0) goto error_return; if (rc > 0) { if (!tokenbuf_append(result, p, rc)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } p += rc; } /* try to parse variable construct */ rc = parse_variable(var, ctx, p, end, &tmp); if (rc < 0) goto error_return; if (rc > 0) { p += rc; if (!tokenbuf_merge(result, &tmp)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } } tokenbuf_free(&tmp); /* KES 11/9/2003 */ } while (rc > 0); tokenbuf_free(&tmp); return (p - begin); error_return: tokenbuf_free(&tmp); tokenbuf_free(result); return rc; } /* parse substitution text or variable */ static int parse_substext_or_variable( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result) { const char *p = begin; tokenbuf_t tmp; int rc; tokenbuf_init(result); tokenbuf_init(&tmp); if (begin == end) return 0; do { /* try to parse substitution text */ rc = parse_substext(var, ctx, p, end); if (rc < 0) goto error_return; if (rc > 0) { if (!tokenbuf_append(result, p, rc)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } p += rc; } /* try to parse substitution text */ rc = parse_variable(var, ctx, p, end, &tmp); if (rc < 0) goto error_return; if (rc > 0) { p += rc; if (!tokenbuf_merge(result, &tmp)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } } tokenbuf_free(&tmp); /* KES 11/9/2003 */ } while (rc > 0); tokenbuf_free(&tmp); return (p - begin); error_return: tokenbuf_free(&tmp); tokenbuf_free(result); return rc; } /* parse class description */ static int parse_class_description( var_t *var, var_parse_t *ctx, tokenbuf_t *src, tokenbuf_t *dst) { unsigned char c, d; const char *p; p = src->begin; while (p != src->end) { if ((src->end - p) >= 3 && p[1] == '-') { if (*p > p[2]) return VAR_ERR_INCORRECT_TRANSPOSE_CLASS_SPEC; for (c = *p, d = p[2]; c <= d; ++c) { if (!tokenbuf_append(dst, (char *)&c, 1)) return VAR_ERR_OUT_OF_MEMORY; } p += 3; } else { if (!tokenbuf_append(dst, p, 1)) return VAR_ERR_OUT_OF_MEMORY; p++; } } return VAR_OK; } /* parse regex replace part */ static int parse_regex_replace( var_t *var, var_parse_t *ctx, const char *data, tokenbuf_t *orig, regmatch_t *pmatch, tokenbuf_t *expanded) { const char *p; int i; p = orig->begin; tokenbuf_init(expanded); while (p != orig->end) { if (*p == '\\') { if (orig->end - p <= 1) { tokenbuf_free(expanded); return VAR_ERR_INCOMPLETE_QUOTED_PAIR; } p++; if (*p == '\\') { if (!tokenbuf_append(expanded, p, 1)) { tokenbuf_free(expanded); return VAR_ERR_OUT_OF_MEMORY; } p++; continue; } if (!isdigit((int)*p)) { tokenbuf_free(expanded); return VAR_ERR_UNKNOWN_QUOTED_PAIR_IN_REPLACE; } i = (*p - '0'); p++; if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1) { tokenbuf_free(expanded); return VAR_ERR_SUBMATCH_OUT_OF_RANGE; } if (!tokenbuf_append(expanded, data + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so)) { tokenbuf_free(expanded); return VAR_ERR_OUT_OF_MEMORY; } } else { if (!tokenbuf_append(expanded, p, 1)) { tokenbuf_free(expanded); return VAR_ERR_OUT_OF_MEMORY; } p++; } } return VAR_OK; } /* operation: transpose */ static int op_transpose( var_t *var, var_parse_t *ctx, tokenbuf_t *data, tokenbuf_t *search, tokenbuf_t *replace) { tokenbuf_t srcclass, dstclass; const char *p; int rc; int i; tokenbuf_init(&srcclass); tokenbuf_init(&dstclass); if ((rc = parse_class_description(var, ctx, search, &srcclass)) != VAR_OK) goto error_return; if ((rc = parse_class_description(var, ctx, replace, &dstclass)) != VAR_OK) goto error_return; if (srcclass.begin == srcclass.end) { rc = VAR_ERR_EMPTY_TRANSPOSE_CLASS; goto error_return; } if ((srcclass.end - srcclass.begin) != (dstclass.end - dstclass.begin)) { rc = VAR_ERR_TRANSPOSE_CLASSES_MISMATCH; goto error_return; } if (data->buffer_size == 0) { tokenbuf_t tmp; if (!tokenbuf_assign(&tmp, data->begin, data->end - data->begin)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } tokenbuf_move(&tmp, data); } for (p = data->begin; p != data->end; ++p) { for (i = 0; i <= (srcclass.end - srcclass.begin); ++i) { if (*p == srcclass.begin[i]) { *((char *)p) = dstclass.begin[i]; break; } } } tokenbuf_free(&srcclass); tokenbuf_free(&dstclass); return VAR_OK; error_return: tokenbuf_free(search); tokenbuf_free(replace); tokenbuf_free(&srcclass); tokenbuf_free(&dstclass); return rc; } /* operation: search & replace */ static int op_search_and_replace( var_t *var, var_parse_t *ctx, tokenbuf_t *data, tokenbuf_t *search, tokenbuf_t *replace, tokenbuf_t *flags) { tokenbuf_t tmp; const char *p; int case_insensitive = 0; int multiline = 0; int global = 0; int no_regex = 0; bool rc; if (search->begin == search->end) return VAR_ERR_EMPTY_SEARCH_STRING; for (p = flags->begin; p != flags->end; p++) { switch (tolower(*p)) { case 'm': multiline = 1; break; case 'i': case_insensitive = 1; break; case 'g': global = 1; break; case 't': no_regex = 1; break; default: return VAR_ERR_UNKNOWN_REPLACE_FLAG; } } if (no_regex) { /* plain text pattern based operation */ tokenbuf_init(&tmp); for (p = data->begin; p != data->end;) { if (case_insensitive) rc = bstrncasecmp(p, search->begin, search->end - search->begin); else rc = bstrncmp(p, search->begin, search->end - search->begin); if (!rc) { /* not matched, copy character */ if (!tokenbuf_append(&tmp, p, 1)) { tokenbuf_free(&tmp); return VAR_ERR_OUT_OF_MEMORY; } p++; } else { /* matched, copy replacement string */ tokenbuf_merge(&tmp, replace); p += (search->end - search->begin); if (!global) { /* append remaining text */ if (!tokenbuf_append(&tmp, p, data->end - p)) { tokenbuf_free(&tmp); return VAR_ERR_OUT_OF_MEMORY; } break; } } } tokenbuf_free(data); tokenbuf_move(&tmp, data); } else { /* regular expression pattern based operation */ tokenbuf_t mydata; tokenbuf_t myreplace; regex_t preg; regmatch_t pmatch[10]; int regexec_flag; /* copy pattern and data to own buffer to make sure they are EOS-terminated */ if (!tokenbuf_assign(&tmp, search->begin, search->end - search->begin)) return VAR_ERR_OUT_OF_MEMORY; if (!tokenbuf_assign(&mydata, data->begin, data->end - data->begin)) { tokenbuf_free(&tmp); return VAR_ERR_OUT_OF_MEMORY; } /* compile the pattern. */ rc = regcomp(&preg, tmp.begin, ( REG_EXTENDED | (multiline ? REG_NEWLINE : 0) | (case_insensitive ? REG_ICASE : 0))); tokenbuf_free(&tmp); if (rc != 0) { tokenbuf_free(&mydata); return VAR_ERR_INVALID_REGEX_IN_REPLACE; } /* match the pattern and create the result string in the tmp buffer */ tokenbuf_append(&tmp, "", 0); for (p = mydata.begin; p < mydata.end; ) { if (p == mydata.begin || p[-1] == '\n') regexec_flag = 0; else regexec_flag = REG_NOTBOL; rc = regexec(&preg, p, sizeof(pmatch) / sizeof(regmatch_t), pmatch, regexec_flag); if (rc != 0) { /* no (more) matching */ tokenbuf_append(&tmp, p, mydata.end - p); break; } else if (multiline && (p + pmatch[0].rm_so) == mydata.end && (pmatch[0].rm_eo - pmatch[0].rm_so) == 0) { /* special case: found empty pattern (usually /^/ or /$/ only) in multi-line at end of data (after the last newline) */ tokenbuf_append(&tmp, p, mydata.end - p); break; } else { /* append prolog string */ if (!tokenbuf_append(&tmp, p, pmatch[0].rm_so)) { regfree(&preg); tokenbuf_free(&tmp); tokenbuf_free(&mydata); return VAR_ERR_OUT_OF_MEMORY; } /* create replace string */ rc = parse_regex_replace(var, ctx, p, replace, pmatch, &myreplace); if (rc != VAR_OK) { regfree(&preg); tokenbuf_free(&tmp); tokenbuf_free(&mydata); return rc; } /* append replace string */ if (!tokenbuf_merge(&tmp, &myreplace)) { regfree(&preg); tokenbuf_free(&tmp); tokenbuf_free(&mydata); tokenbuf_free(&myreplace); return VAR_ERR_OUT_OF_MEMORY; } tokenbuf_free(&myreplace); /* skip now processed data */ p += pmatch[0].rm_eo; /* if pattern matched an empty part (think about anchor-only regular expressions like /^/ or /$/) we skip the next character to make sure we do not enter an infinitive loop in matching */ if ((pmatch[0].rm_eo - pmatch[0].rm_so) == 0) { if (p >= mydata.end) break; if (!tokenbuf_append(&tmp, p, 1)) { regfree(&preg); tokenbuf_free(&tmp); tokenbuf_free(&mydata); return VAR_ERR_OUT_OF_MEMORY; } p++; } /* append prolog string and stop processing if we do not perform the search & replace globally */ if (!global) { if (!tokenbuf_append(&tmp, p, mydata.end - p)) { regfree(&preg); tokenbuf_free(&tmp); tokenbuf_free(&mydata); return VAR_ERR_OUT_OF_MEMORY; } break; } } } regfree(&preg); tokenbuf_free(data); tokenbuf_move(&tmp, data); tokenbuf_free(&mydata); } return VAR_OK; } /* operation: offset substring */ static int op_offset( var_t *var, var_parse_t *ctx, tokenbuf_t *data, int num1, int num2, int isrange) { tokenbuf_t res; const char *p; /* determine begin of result string */ if ((data->end - data->begin) < num1) return VAR_ERR_OFFSET_OUT_OF_BOUNDS; p = data->begin + num1; /* if num2 is zero, we copy the rest from there. */ if (num2 == 0) { if (!tokenbuf_assign(&res, p, data->end - p)) return VAR_ERR_OUT_OF_MEMORY; } else { /* ok, then use num2. */ if (isrange) { if ((p + num2) > data->end) return VAR_ERR_RANGE_OUT_OF_BOUNDS; if (!tokenbuf_assign(&res, p, num2)) return VAR_ERR_OUT_OF_MEMORY; } else { if (num2 < num1) return VAR_ERR_OFFSET_LOGIC; if ((data->begin + num2) > data->end) return VAR_ERR_RANGE_OUT_OF_BOUNDS; if (!tokenbuf_assign(&res, p, num2 - num1 + 1)) return VAR_ERR_OUT_OF_MEMORY; } } tokenbuf_free(data); tokenbuf_move(&res, data); return VAR_OK; } /* operation: padding */ static int op_padding( var_t *var, var_parse_t *ctx, tokenbuf_t *data, int width, tokenbuf_t *fill, char position) { tokenbuf_t result; int i; if (fill->begin == fill->end) return VAR_ERR_EMPTY_PADDING_FILL_STRING; tokenbuf_init(&result); if (position == 'l') { /* left padding */ i = width - (data->end - data->begin); if (i > 0) { i = i / (fill->end - fill->begin); while (i > 0) { if (!tokenbuf_append(data, fill->begin, fill->end - fill->begin)) return VAR_ERR_OUT_OF_MEMORY; i--; } i = (width - (data->end - data->begin)) % (fill->end - fill->begin); if (!tokenbuf_append(data, fill->begin, i)) return VAR_ERR_OUT_OF_MEMORY; } } else if (position == 'r') { /* right padding */ i = width - (data->end - data->begin); if (i > 0) { i = i / (fill->end - fill->begin); while (i > 0) { if (!tokenbuf_merge(&result, fill)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } i--; } i = (width - (data->end - data->begin)) % (fill->end - fill->begin); if (!tokenbuf_append(&result, fill->begin, i)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } if (!tokenbuf_merge(&result, data)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } /* move string from temporary buffer to data buffer */ tokenbuf_free(data); tokenbuf_move(&result, data); } } else if (position == 'c') { /* centered padding */ i = (width - (data->end - data->begin)) / 2; if (i > 0) { /* create the prefix */ i = i / (fill->end - fill->begin); while (i > 0) { if (!tokenbuf_merge(&result, fill)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } i--; } i = ((width - (data->end - data->begin)) / 2) % (fill->end - fill->begin); if (!tokenbuf_append(&result, fill->begin, i)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } /* append the actual data string */ if (!tokenbuf_merge(&result, data)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } /* append the suffix */ i = width - (result.end - result.begin); i = i / (fill->end - fill->begin); while (i > 0) { if (!tokenbuf_merge(&result, fill)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } i--; } i = width - (result.end - result.begin); if (!tokenbuf_append(&result, fill->begin, i)) { tokenbuf_free(&result); return VAR_ERR_OUT_OF_MEMORY; } /* move string from temporary buffer to data buffer */ tokenbuf_free(data); tokenbuf_move(&result, data); } } return VAR_OK; } /* parse an integer number ("123") */ static int parse_integer( var_t *var, var_parse_t *ctx, const char *begin, const char *end, int *result) { const char *p; int num; p = begin; num = 0; while (isdigit(*p) && p != end) { num *= 10; num += (*p - '0'); p++; } if (result != NULL) *result = num; return (p - begin); } /* parse an operation (":x...") */ static int parse_operation( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *data) { const char *p; tokenbuf_t tmptokbuf; tokenbuf_t search, replace, flags; tokenbuf_t number1, number2; int num1, num2; int isrange; int rc; char *ptr; /* initialization */ tokenbuf_init(&tmptokbuf); tokenbuf_init(&search); tokenbuf_init(&replace); tokenbuf_init(&flags); tokenbuf_init(&number1); tokenbuf_init(&number2); p = begin; if (p == end) return 0; /* dispatch through the first operation character */ switch (tolower(*p)) { case 'l': { /* turn value to lowercase. */ if (data->begin != NULL) { /* if the buffer does not live in an allocated buffer, we have to copy it before modifying the contents. */ if (data->buffer_size == 0) { if (!tokenbuf_assign(data, data->begin, data->end - data->begin)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } } /* convert value */ for (ptr = (char *)data->begin; ptr != data->end; ptr++) *ptr = (char)tolower((int)(*ptr)); } p++; break; } case 'u': { /* turn value to uppercase. */ if (data->begin != NULL) { /* if the buffer does not live in an allocated buffer, we have to copy it before modifying the contents. */ if (data->buffer_size == 0) { if (!tokenbuf_assign(data, data->begin, data->end - data->begin)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } } /* convert value */ for (ptr = (char *)data->begin; ptr != data->end; ptr++) *ptr = (char)toupper((int)(*ptr)); } p++; break; } case 'o': { /* cut out substring of value. */ p++; rc = parse_integer(var, ctx, p, end, &num1); if (rc == 0) { rc = VAR_ERR_MISSING_START_OFFSET; goto error_return; } else if (rc < 0) goto error_return; p += rc; if (*p == ',') { isrange = 0; p++; } else if (*p == '-') { isrange = 1; p++; } else { rc = VAR_ERR_INVALID_OFFSET_DELIMITER; goto error_return; } rc = parse_integer(var, ctx, p, end, &num2); p += rc; if (data->begin != NULL) { rc = op_offset(var, ctx, data, num1, num2, isrange); if (rc < 0) goto error_return; } break; } case '#': { /* determine length of the value */ if (data->begin != NULL) { char buf[((sizeof(int)*8)/3)+10]; /* sufficient size: <#bits> x log_10(2) + safety */ sprintf(buf, "%d", (int)(data->end - data->begin)); tokenbuf_free(data); if (!tokenbuf_assign(data, buf, strlen(buf))) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } } p++; break; } case '-': { /* substitute parameter if data is empty */ p++; rc = parse_exptext_or_variable(var, ctx, p, end, &tmptokbuf); if (rc < 0) goto error_return; if (rc == 0) { rc = VAR_ERR_MISSING_PARAMETER_IN_COMMAND; goto error_return; } p += rc; if (tokenbuf_isundef(data)) tokenbuf_move(&tmptokbuf, data); else if (tokenbuf_isempty(data)) { tokenbuf_free(data); tokenbuf_move(&tmptokbuf, data); } break; } case '*': { /* substitute empty string if data is not empty, parameter otherwise. */ p++; rc = parse_exptext_or_variable(var, ctx, p, end, &tmptokbuf); if (rc < 0) goto error_return; if (rc == 0) { rc = VAR_ERR_MISSING_PARAMETER_IN_COMMAND; goto error_return; } p += rc; if (data->begin != NULL) { if (data->begin == data->end) { tokenbuf_free(data); tokenbuf_move(&tmptokbuf, data); } else { tokenbuf_free(data); data->begin = data->end = ""; data->buffer_size = 0; } } break; } case '+': { /* substitute parameter if data is not empty. */ p++; rc = parse_exptext_or_variable(var, ctx, p, end, &tmptokbuf); if (rc < 0) goto error_return; if (rc == 0) { rc = VAR_ERR_MISSING_PARAMETER_IN_COMMAND; goto error_return; } p += rc; if (data->begin != NULL && data->begin != data->end) { tokenbuf_free(data); tokenbuf_move(&tmptokbuf, data); } break; } case 's': { /* search and replace. */ p++; if (*p != '/') return VAR_ERR_MALFORMATTED_REPLACE; p++; rc = parse_pattern(var, ctx, p, end); if (rc < 0) goto error_return; tokenbuf_set(&search, p, p + rc, 0); p += rc; if (*p != '/') { rc = VAR_ERR_MALFORMATTED_REPLACE; goto error_return; } p++; rc = parse_substext_or_variable(var, ctx, p, end, &replace); if (rc < 0) goto error_return; p += rc; if (*p != '/') { rc = VAR_ERR_MALFORMATTED_REPLACE; goto error_return; } p++; rc = parse_exptext(var, ctx, p, end); if (rc < 0) goto error_return; tokenbuf_set(&flags, p, p + rc, 0); p += rc; if (data->begin != NULL) { rc = op_search_and_replace(var, ctx, data, &search, &replace, &flags); if (rc < 0) goto error_return; } break; } case 'y': { /* transpose characters from class A to class B. */ p++; if (*p != '/') return VAR_ERR_MALFORMATTED_TRANSPOSE; p++; rc = parse_substext_or_variable(var, ctx, p, end, &search); if (rc < 0) goto error_return; p += rc; if (*p != '/') { rc = VAR_ERR_MALFORMATTED_TRANSPOSE; goto error_return; } p++; rc = parse_substext_or_variable(var, ctx, p, end, &replace); if (rc < 0) goto error_return; p += rc; if (*p != '/') { rc = VAR_ERR_MALFORMATTED_TRANSPOSE; goto error_return; } else p++; if (data->begin) { rc = op_transpose(var, ctx, data, &search, &replace); if (rc < 0) goto error_return; } break; } case 'p': { /* padding. */ p++; if (*p != '/') return VAR_ERR_MALFORMATTED_PADDING; p++; rc = parse_integer(var, ctx, p, end, &num1); if (rc == 0) { rc = VAR_ERR_MISSING_PADDING_WIDTH; goto error_return; } p += rc; if (*p != '/') { rc = VAR_ERR_MALFORMATTED_PADDING; goto error_return; } p++; rc = parse_substext_or_variable(var, ctx, p, end, &replace); if (rc < 0) goto error_return; p += rc; if (*p != '/') { rc = VAR_ERR_MALFORMATTED_PADDING; goto error_return; } p++; if (*p != 'l' && *p != 'c' && *p != 'r') { rc = VAR_ERR_MALFORMATTED_PADDING; goto error_return; } p++; if (data->begin) { rc = op_padding(var, ctx, data, num1, &replace, p[-1]); if (rc < 0) goto error_return; } break; } case '%': { /* operation callback function */ const char *op_ptr; int op_len; const char *arg_ptr; int arg_len; const char *val_ptr; int val_len; const char *out_ptr; int out_len; int out_size; tokenbuf_t args; p++; rc = parse_name(var, ctx, p, end); if (rc < 0) goto error_return; op_ptr = p; op_len = rc; p += rc; if (*p == '(') { p++; tokenbuf_init(&args); rc = parse_opargtext_or_variable(var, ctx, p, end, &args); if (rc < 0) goto error_return; p += rc; arg_ptr = args.begin; arg_len = args.end - args.begin; if (*p != ')') { rc = VAR_ERR_MALFORMED_OPERATION_ARGUMENTS; goto error_return; } p++; } else { arg_ptr = NULL; arg_len = 0; } val_ptr = data->begin; val_len = data->end - data->begin; if (data->begin != NULL && var->cb_operation_fct != NULL) { /* call operation callback function */ rc = (*var->cb_operation_fct)(var, var->cb_operation_ctx, op_ptr, op_len, arg_ptr, arg_len, val_ptr, val_len, &out_ptr, &out_len, &out_size); if (rc < 0) { if (arg_ptr != NULL) free((void *)arg_ptr); goto error_return; } tokenbuf_free(data); tokenbuf_set(data, out_ptr, out_ptr+out_len, out_size); } if (arg_ptr != NULL) free((void *)arg_ptr); break; } default: return VAR_ERR_UNKNOWN_COMMAND_CHAR; } /* return successfully */ tokenbuf_free(&tmptokbuf); tokenbuf_free(&search); tokenbuf_free(&replace); tokenbuf_free(&flags); tokenbuf_free(&number1); tokenbuf_free(&number2); return (p - begin); /* return with an error */ error_return: tokenbuf_free(data); tokenbuf_free(&tmptokbuf); tokenbuf_free(&search); tokenbuf_free(&replace); tokenbuf_free(&flags); tokenbuf_free(&number1); tokenbuf_free(&number2); return rc; } /* parse numerical expression operand */ static int parse_numexp_operand( var_t *var, var_parse_t *ctx, const char *begin, const char *end, int *result, int *failed) { const char *p; tokenbuf_t tmp; int rc; var_parse_t myctx; /* initialization */ p = begin; tokenbuf_init(&tmp); if (p == end) return VAR_ERR_INCOMPLETE_INDEX_SPEC; /* parse opening numerical expression */ if (*p == '(') { /* parse inner numerical expression */ rc = parse_numexp(var, ctx, ++p, end, result, failed); if (rc < 0) return rc; p += rc; if (p == end) return VAR_ERR_INCOMPLETE_INDEX_SPEC; /* parse closing parenthesis */ if (*p != ')') return VAR_ERR_UNCLOSED_BRACKET_IN_INDEX; p++; } /* parse contained variable */ else if (*p == var->syntax.delim_init) { /* parse variable with forced expansion */ ctx = var_parse_push(ctx, &myctx); ctx->force_expand = 1; rc = parse_variable(var, ctx, p, end, &tmp); ctx = var_parse_pop(ctx); if (rc == VAR_ERR_UNDEFINED_VARIABLE) { *failed = 1; /* parse variable without forced expansion */ ctx = var_parse_push(ctx, &myctx); ctx->force_expand = 0; rc = parse_variable(var, ctx, p, end, &tmp); ctx = var_parse_pop(ctx); if (rc < 0) return rc; p += rc; *result = 0; tokenbuf_free(&tmp); /* KES 11/9/2003 */ } else if (rc < 0) { return rc; } else { p += rc; /* parse remaining numerical expression */ rc = parse_numexp(var, ctx, tmp.begin, tmp.end, result, failed); tokenbuf_free(&tmp); if (rc < 0) return rc; } } /* parse relative index mark ("#") */ else if ( var->syntax.index_mark != EOS && *p == var->syntax.index_mark) { p++; *result = ctx->index_this; if (ctx->rel_lookup_flag) ctx->rel_lookup_cnt++; } /* parse plain integer number */ else if (isdigit(*p)) { rc = parse_integer(var, ctx, p, end, result); p += rc; } /* parse signed positive integer number */ else if (*p == '+') { if ((end - p) > 1 && isdigit(p[1])) { p++; rc = parse_integer(var, ctx, p, end, result); p += rc; } else return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC; } /* parse signed negative integer number */ else if (*p == '-') { if (end - p > 1 && isdigit(p[1])) { p++; rc = parse_integer(var, ctx, p, end, result); *result = -(*result); p += rc; } else return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC; } /* else we failed to parse anything reasonable */ else return VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC; return (p - begin); } /* parse numerical expression ("x+y") */ static int parse_numexp( var_t *var, var_parse_t *ctx, const char *begin, const char *end, int *result, int *failed) { const char *p; char op; int right; int rc; /* initialization */ p = begin; if (p == end) return VAR_ERR_INCOMPLETE_INDEX_SPEC; /* parse left numerical operand */ rc = parse_numexp_operand(var, ctx, p, end, result, failed); if (rc < 0) return rc; p += rc; /* parse numerical operator */ while (p != end) { if (*p == '+' || *p == '-') { op = *p++; /* recursively parse right operand (light binding) */ rc = parse_numexp(var, ctx, p, end, &right, failed); if (rc < 0) return rc; p += rc; if (op == '+') *result = (*result + right); else *result = (*result - right); } else if (*p == '*' || *p == '/' || *p == '%') { op = *p++; /* recursively parse right operand (string binding) */ rc = parse_numexp_operand(var, ctx, p, end, &right, failed); if (rc < 0) return rc; p += rc; if (op == '*') *result = (*result * right); else if (op == '/') { if (right == 0) { if (*failed) *result = 0; else return VAR_ERR_DIVISION_BY_ZERO_IN_INDEX; } else *result = (*result / right); } else if (op == '%') { if (right == 0) { if (*failed) *result = 0; else return VAR_ERR_DIVISION_BY_ZERO_IN_INDEX; } else *result = (*result % right); } } else break; } /* return amount of parsed input */ return (p - begin); } /* parse variable name ("abc") */ static int parse_name( var_t *var, var_parse_t *ctx, const char *begin, const char *end) { const char *p; /* parse as long as name class characters are found */ for (p = begin; p != end && var->syntax_nameclass[(int)(*p)]; p++) ; return (p - begin); } /* lookup a variable value through the callback function */ static int lookup_value( var_t *var, var_parse_t *ctx, const char *var_ptr, int var_len, int var_inc, int var_idx, const char **val_ptr, int *val_len, int *val_size) { char buf[1]; int rc; /* pass through to original callback */ rc = (*var->cb_value_fct)(var, var->cb_value_ctx, var_ptr, var_len, var_inc, var_idx, val_ptr, val_len, val_size); /* convert undefined variable into empty variable if relative lookups are counted. This is the case inside an active loop construct if no limits are given. There the parse_input() has to proceed until all variables have undefined values. This trick here allows it to determine this case. */ if (ctx->rel_lookup_flag && rc == VAR_ERR_UNDEFINED_VARIABLE) { ctx->rel_lookup_cnt--; buf[0] = EOS; *val_ptr = bstrdup(buf); *val_len = 0; *val_size = 0; return VAR_OK; } return rc; } /* parse complex variable construct ("${name...}") */ static int parse_variable_complex( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result) { const char *p; const char *data; int len, buffer_size; int failed = 0; int rc; int idx = 0; int inc; tokenbuf_t name; tokenbuf_t tmp; /* initializations */ p = begin; tokenbuf_init(&name); tokenbuf_init(&tmp); tokenbuf_init(result); /* parse open delimiter */ if (p == end || *p != var->syntax.delim_open) return 0; p++; if (p == end) return VAR_ERR_INCOMPLETE_VARIABLE_SPEC; /* parse name of variable to expand. The name may consist of an arbitrary number of variable name character and contained variable constructs. */ do { /* parse a variable name */ rc = parse_name(var, ctx, p, end); if (rc < 0) goto error_return; if (rc > 0) { if (!tokenbuf_append(&name, p, rc)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } p += rc; } /* parse an (embedded) variable */ rc = parse_variable(var, ctx, p, end, &tmp); if (rc < 0) goto error_return; if (rc > 0) { if (!tokenbuf_merge(&name, &tmp)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } p += rc; } tokenbuf_free(&tmp); /* KES 11/9/2003 */ } while (rc > 0); /* we must have the complete expanded variable name now, so make sure we really do. */ if (name.begin == name.end) { if (ctx->force_expand) { rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC; goto error_return; } else { /* If no force_expand is requested, we have to back-off. We're not sure whether our approach here is 100% correct, because it _could_ have side-effects according to Peter Simons, but as far as we know and tried it, it is correct. But be warned -- RSE */ tokenbuf_set(result, begin - 1, p, 0); goto goahead; } } /* parse an optional index specification */ if ( var->syntax.index_open != EOS && *p == var->syntax.index_open) { p++; rc = parse_numexp(var, ctx, p, end, &idx, &failed); if (rc < 0) goto error_return; if (rc == 0) { rc = VAR_ERR_INCOMPLETE_INDEX_SPEC; goto error_return; } p += rc; if (p == end) { rc = VAR_ERR_INCOMPLETE_INDEX_SPEC; goto error_return; } if (*p != var->syntax.index_close) { rc = VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC; goto error_return; } p++; } /* parse end of variable construct or start of post-operations */ if (p == end || (*p != var->syntax.delim_close && *p != ':' && *p != '+')) { rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC; goto error_return; } if ((inc = (*p++ == '+'))) { p++; /* skip the + */ } /* lookup the variable value now */ if (failed) { tokenbuf_set(result, begin - 1, p, 0); } else { rc = lookup_value(var, ctx, name.begin, name.end-name.begin, inc, idx, &data, &len, &buffer_size); if (rc == VAR_ERR_UNDEFINED_VARIABLE) { tokenbuf_init(result); /* delayed handling of undefined variable */ } else if (rc < 0) { goto error_return; } else { /* the preliminary result is the raw value of the variable. This may be modified by the operations that may follow. */ tokenbuf_set(result, data, data + len, buffer_size); } } /* parse optional post-operations */ goahead: if (p[-1] == ':') { tokenbuf_free(&tmp); tokenbuf_init(&tmp); p--; while (p != end && *p == ':') { p++; if (!failed) rc = parse_operation(var, ctx, p, end, result); else rc = parse_operation(var, ctx, p, end, &tmp); if (rc < 0) goto error_return; p += rc; if (failed) result->end += rc; } if (p == end || *p != var->syntax.delim_close) { rc = VAR_ERR_INCOMPLETE_VARIABLE_SPEC; goto error_return; } p++; if (failed) result->end++; } else if (p[-1] == '+') { p++; } /* lazy handling of undefined variable */ if (!failed && tokenbuf_isundef(result)) { if (ctx->force_expand) { rc = VAR_ERR_UNDEFINED_VARIABLE; goto error_return; } else { tokenbuf_set(result, begin - 1, p, 0); } } /* return successfully */ tokenbuf_free(&name); tokenbuf_free(&tmp); return (p - begin); /* return with an error */ error_return: tokenbuf_free(&name); tokenbuf_free(&tmp); tokenbuf_free(result); return rc; } /* parse variable construct ("$name" or "${name...}") */ static int parse_variable( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *result) { const char *p; const char *data; int len, buffer_size; int rc, rc2; int inc; /* initialization */ p = begin; tokenbuf_init(result); /* parse init delimiter */ if (p == end || *p != var->syntax.delim_init) return 0; p++; if (p == end) return VAR_ERR_INCOMPLETE_VARIABLE_SPEC; /* parse a simple variable name. (if this fails, we're try to parse a complex variable construct) */ rc = parse_name(var, ctx, p, end); if (rc < 0) return rc; if (rc > 0) { inc = (p[rc] == '+'); rc2 = lookup_value(var, ctx, p, rc, inc, 0, &data, &len, &buffer_size); if (rc2 == VAR_ERR_UNDEFINED_VARIABLE && !ctx->force_expand) { tokenbuf_set(result, begin, begin + 1 + rc, 0); return (1 + rc); } if (rc2 < 0) return rc2; tokenbuf_set(result, data, data + len, buffer_size); return (1 + rc); } /* parse a complex variable construct (else case) */ rc = parse_variable_complex(var, ctx, p, end, result); if (rc > 0) rc++; return rc; } /* parse loop construct limits ("[...]{b,s,e}") */ static var_rc_t parse_looplimits( var_t *var, var_parse_t *ctx, const char *begin, const char *end, int *start, int *step, int *stop, int *open_stop) { const char *p; int rc; int failed; /* initialization */ p = begin; /* we are happy if nothing is to left to parse */ if (p == end) return VAR_OK; /* parse start delimiter */ if (*p != var->syntax.delim_open) return VAR_OK; p++; /* parse loop start value */ failed = 0; rc = parse_numexp(var, ctx, p, end, start, &failed); if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC) *start = 0; /* use default */ else if (rc < 0) return (var_rc_t)rc; else p += rc; if (failed) return VAR_ERR_UNDEFINED_VARIABLE; /* parse separator */ if (*p != ',') return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS; p++; /* parse loop step value */ failed = 0; rc = parse_numexp(var, ctx, p, end, step, &failed); if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC) *step = 1; /* use default */ else if (rc < 0) return (var_rc_t)rc; else p += rc; if (failed) return VAR_ERR_UNDEFINED_VARIABLE; /* parse separator */ if (*p != ',') { /* if not found, parse end delimiter */ if (*p != var->syntax.delim_close) return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS; p++; /* shift step value to stop value */ *stop = *step; *step = 1; /* determine whether loop end is open */ if (rc > 0) *open_stop = 0; else *open_stop = 1; return (var_rc_t)(p - begin); } p++; /* parse loop stop value */ failed = 0; rc = parse_numexp(var, ctx, p, end, stop, &failed); if (rc == VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC) { *stop = 0; /* use default */ *open_stop = 1; } else if (rc < 0) return (var_rc_t)rc; else { *open_stop = 0; p += rc; } if (failed) return VAR_ERR_UNDEFINED_VARIABLE; /* parse end delimiter */ if (*p != var->syntax.delim_close) return VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS; p++; /* return amount of parsed input */ return (var_rc_t)(p - begin); } /* parse plain text */ static int parse_text( var_t *var, var_parse_t *ctx, const char *begin, const char *end) { const char *p; /* parse until delim_init (variable construct) or index_open (loop construct) is found */ for (p = begin; p != end; p++) { if (*p == var->syntax.escape) { p++; /* skip next character */ if (p == end) return VAR_ERR_INCOMPLETE_QUOTED_PAIR; } else if (*p == var->syntax.delim_init) break; else if ( var->syntax.index_open != EOS && ( *p == var->syntax.index_open || *p == var->syntax.index_close)) break; } return (p - begin); } /* expand input in general */ static var_rc_t parse_input( var_t *var, var_parse_t *ctx, const char *begin, const char *end, tokenbuf_t *output, int recursion_level) { const char *p; int rc, rc2; tokenbuf_t result; int start, step, stop, open_stop; int i; int output_backup; int rel_lookup_cnt; int loop_limit_length; var_parse_t myctx; /* initialization */ p = begin; do { /* try to parse a loop construct */ if ( p != end && var->syntax.index_open != EOS && *p == var->syntax.index_open) { p++; /* loop preparation */ loop_limit_length = -1; rel_lookup_cnt = ctx->rel_lookup_cnt; open_stop = 1; rc = 0; start = 0; step = 1; stop = 0; output_backup = 0; /* iterate over loop construct, either as long as there is (still) nothing known about the limit, or there is an open (=unknown) limit stop and there are still defined variables or there is a stop limit known and it is still not reached */ re_loop: for (i = start; ( ( open_stop && ( loop_limit_length < 0 || rel_lookup_cnt > ctx->rel_lookup_cnt)) || ( !open_stop && i <= stop) ); i += step) { /* remember current output end for restoring */ output_backup = (output->end - output->begin); /* open temporary context for recursion */ ctx = var_parse_push(ctx, &myctx); ctx->force_expand = 1; ctx->rel_lookup_flag = 1; ctx->index_this = i; /* recursive parse input through ourself */ rc = parse_input(var, ctx, p, end, output, recursion_level+1); /* retrieve info and close temporary context */ rel_lookup_cnt = ctx->rel_lookup_cnt; ctx = var_parse_pop(ctx); /* error handling */ if (rc < 0) goto error_return; /* make sure the loop construct is closed */ if (p[rc] != var->syntax.index_close) { rc = VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT; goto error_return; } /* try to parse loop construct limit specification */ if (loop_limit_length < 0) { rc2 = parse_looplimits(var, ctx, p+rc+1, end, &start, &step, &stop, &open_stop); if (rc2 < 0) goto error_return; else if (rc2 == 0) loop_limit_length = 0; else if (rc2 > 0) { loop_limit_length = rc2; /* restart loop from scratch */ output->end = (output->begin + output_backup); goto re_loop; } } } /* if stop value is open, restore to the output end because the last iteration was just to determine the loop termination and its result has to be discarded */ if (open_stop) output->end = (output->begin + output_backup); /* skip parsed loop construct */ p += rc; p++; p += loop_limit_length; continue; } /* try to parse plain text */ rc = parse_text(var, ctx, p, end); if (rc > 0) { if (!tokenbuf_append(output, p, rc)) { rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } p += rc; continue; } else if (rc < 0) goto error_return; /* try to parse a variable construct */ tokenbuf_init(&result); rc = parse_variable(var, ctx, p, end, &result); if (rc > 0) { if (!tokenbuf_merge(output, &result)) { tokenbuf_free(&result); rc = VAR_ERR_OUT_OF_MEMORY; goto error_return; } tokenbuf_free(&result); p += rc; continue; } tokenbuf_free(&result); if (rc < 0) goto error_return; } while (p != end && rc > 0); /* We do not know whether this really could happen, but because we are paranoid, report an error at the outer most parsing level if there is still any input. Because this would mean that we are no longer able to parse the remaining input as a loop construct, a text or a variable construct. This would be very strange, but could perhaps happen in case of configuration errors!?... */ if (recursion_level == 0 && p != end) { rc = VAR_ERR_INPUT_ISNT_TEXT_NOR_VARIABLE; goto error_return; } /* return amount of parsed text */ return (var_rc_t)(p - begin); /* return with an error where as a special case the output begin is set to the input begin and the output end to the last input parsing position. */ error_return: tokenbuf_free(output); tokenbuf_set(output, begin, p, 0); return (var_rc_t)rc; } /* ** ** ==== APPLICATION PROGRAMMING INTERFACE (API) ==== ** */ /* create variable expansion context */ var_rc_t var_create( var_t **pvar) { var_t *var; if (pvar == NULL) return VAR_RC(VAR_ERR_INVALID_ARGUMENT); if ((var = (var_t *)malloc(sizeof(var_t))) == NULL) return VAR_RC(VAR_ERR_OUT_OF_MEMORY); memset(var, 0, sizeof(var_t)); var_config(var, VAR_CONFIG_SYNTAX, &var_syntax_default); *pvar = var; return VAR_OK; } /* destroy variable expansion context */ var_rc_t var_destroy( var_t *var) { if (var == NULL) return VAR_RC(VAR_ERR_INVALID_ARGUMENT); free(var); return VAR_OK; } /* configure variable expansion context */ var_rc_t var_config( var_t *var, var_config_t mode, ...) { va_list ap; var_rc_t rc = VAR_OK; if (var == NULL) { return VAR_RC(VAR_ERR_INVALID_ARGUMENT); } va_start(ap, mode); switch (mode) { case VAR_CONFIG_SYNTAX: { var_syntax_t *s; s = (var_syntax_t *)va_arg(ap, void *); if (s == NULL) { rc = VAR_ERR_INVALID_ARGUMENT; goto bail_out; } var->syntax.escape = s->escape; var->syntax.delim_init = s->delim_init; var->syntax.delim_open = s->delim_open; var->syntax.delim_close = s->delim_close; var->syntax.index_open = s->index_open; var->syntax.index_close = s->index_close; var->syntax.index_mark = s->index_mark; var->syntax.name_chars = NULL; /* unused internally */ if ((rc = expand_character_class(s->name_chars, var->syntax_nameclass)) != VAR_OK) { goto bail_out; } if (var->syntax_nameclass[(int)var->syntax.delim_init] || var->syntax_nameclass[(int)var->syntax.delim_open] || var->syntax_nameclass[(int)var->syntax.delim_close] || var->syntax_nameclass[(int)var->syntax.escape]) { rc = VAR_ERR_INVALID_CONFIGURATION; goto bail_out; } break; } case VAR_CONFIG_CB_VALUE: { var_cb_value_t fct; void *ctx; fct = (var_cb_value_t)va_arg(ap, void *); ctx = (void *)va_arg(ap, void *); var->cb_value_fct = fct; var->cb_value_ctx = ctx; break; } case VAR_CONFIG_CB_OPERATION: { var_cb_operation_t fct; void *ctx; fct = (var_cb_operation_t)va_arg(ap, void *); ctx = (void *)va_arg(ap, void *); var->cb_operation_fct = fct; var->cb_operation_ctx = ctx; break; } default: rc = VAR_ERR_INVALID_ARGUMENT; goto bail_out; } bail_out: va_end(ap); return VAR_RC(rc); } /* perform unescape operation on a buffer */ var_rc_t var_unescape( var_t *var, const char *src, int srclen, char *dst, int dstlen, int all) { const char *end; var_rc_t rc; if (var == NULL || src == NULL || dst == NULL) return VAR_RC(VAR_ERR_INVALID_ARGUMENT); end = src + srclen; while (src < end) { if (*src == '\\') { if (++src == end) return VAR_RC(VAR_ERR_INCOMPLETE_NAMED_CHARACTER); switch (*src) { case '\\': if (!all) { *dst++ = '\\'; } *dst++ = '\\'; break; case 'n': *dst++ = '\n'; break; case 't': *dst++ = '\t'; break; case 'r': *dst++ = '\r'; break; case 'x': ++src; if ((rc = expand_hex(&src, &dst, end)) != VAR_OK) return VAR_RC(rc); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ( end - src >= 3 && isdigit((int)src[1]) && isdigit((int)src[2])) { if ((rc = expand_octal(&src, &dst, end)) != 0) return VAR_RC(rc); break; } default: if (!all) { *dst++ = '\\'; } *dst++ = *src; } ++src; } else *dst++ = *src++; } *dst = EOS; return VAR_OK; } /* perform expand operation on a buffer */ var_rc_t var_expand( var_t *var, const char *src_ptr, int src_len, char **dst_ptr, int *dst_len, int force_expand) { var_parse_t ctx; tokenbuf_t output; var_rc_t rc; /* argument sanity checks */ if (var == NULL || src_ptr == NULL || src_len == 0 || dst_ptr == NULL) return VAR_RC(VAR_ERR_INVALID_ARGUMENT); /* prepare internal expansion context */ ctx.lower = NULL; ctx.force_expand = force_expand; ctx.rel_lookup_flag = 0; ctx.rel_lookup_cnt = 0; ctx.index_this = 0; /* start the parsing */ tokenbuf_init(&output); rc = parse_input(var, &ctx, src_ptr, src_ptr+src_len, &output, 0); /* post-processing */ if (rc >= 0) { /* always EOS-terminate output for convinience reasons but do not count the EOS-terminator in the length */ if (!tokenbuf_append(&output, "\0", 1)) { tokenbuf_free(&output); return VAR_RC(VAR_ERR_OUT_OF_MEMORY); } output.end--; /* provide result */ *dst_ptr = (char *)output.begin; if (dst_len != NULL) *dst_len = (output.end - output.begin); rc = VAR_OK; } else { /* provide result */ if (dst_len != NULL) *dst_len = (output.end - output.begin); } return VAR_RC(rc); } /* format and expand a string */ var_rc_t var_formatv( var_t *var, char **dst_ptr, int force_expand, const char *fmt, va_list ap) { var_rc_t rc; char *cpBuf; int nBuf = 5000; /* argument sanity checks */ if (var == NULL || dst_ptr == NULL || fmt == NULL) return VAR_RC(VAR_ERR_INVALID_ARGUMENT); /* perform formatting */ if ((cpBuf = (char *)malloc(nBuf+1)) == NULL) return VAR_RC(VAR_ERR_OUT_OF_MEMORY); nBuf = var_mvsnprintf(cpBuf, nBuf+1, fmt, ap); if (nBuf == -1) { free(cpBuf); return VAR_RC(VAR_ERR_FORMATTING_FAILURE); } /* perform expansion */ if ((rc = var_expand(var, cpBuf, nBuf, dst_ptr, NULL, force_expand)) != VAR_OK) { free(cpBuf); return VAR_RC(rc); } /* cleanup */ free(cpBuf); return VAR_OK; } /* format and expand a string */ var_rc_t var_format( var_t *var, char **dst_ptr, int force_expand, const char *fmt, ...) { var_rc_t rc; va_list ap; /* argument sanity checks */ if (var == NULL || dst_ptr == NULL || fmt == NULL) return VAR_RC(VAR_ERR_INVALID_ARGUMENT); va_start(ap, fmt); rc = var_formatv(var, dst_ptr, force_expand, fmt, ap); va_end(ap); return VAR_RC(rc); } /* var_rc_t to string mapping table */ static const char *var_errors[] = { _("everything ok"), /* VAR_OK = 0 */ _("incomplete named character"), /* VAR_ERR_INCOMPLETE_NAMED_CHARACTER */ _("incomplete hexadecimal value"), /* VAR_ERR_INCOMPLETE_HEX */ _("invalid hexadecimal value"), /* VAR_ERR_INVALID_HEX */ _("octal value too large"), /* VAR_ERR_OCTAL_TOO_LARGE */ _("invalid octal value"), /* VAR_ERR_INVALID_OCTAL */ _("incomplete octal value"), /* VAR_ERR_INCOMPLETE_OCTAL */ _("incomplete grouped hexadecimal value"), /* VAR_ERR_INCOMPLETE_GROUPED_HEX */ _("incorrect character class specification"), /* VAR_ERR_INCORRECT_CLASS_SPEC */ _("invalid expansion configuration"), /* VAR_ERR_INVALID_CONFIGURATION */ _("out of memory"), /* VAR_ERR_OUT_OF_MEMORY */ _("incomplete variable specification"), /* VAR_ERR_INCOMPLETE_VARIABLE_SPEC */ _("undefined variable"), /* VAR_ERR_UNDEFINED_VARIABLE */ _("input is neither text nor variable"), /* VAR_ERR_INPUT_ISNT_TEXT_NOR_VARIABLE */ _("unknown command character in variable"), /* VAR_ERR_UNKNOWN_COMMAND_CHAR */ _("malformatted search and replace operation"), /* VAR_ERR_MALFORMATTED_REPLACE */ _("unknown flag in search and replace operation"), /* VAR_ERR_UNKNOWN_REPLACE_FLAG */ _("invalid regex in search and replace operation"), /* VAR_ERR_INVALID_REGEX_IN_REPLACE */ _("missing parameter in command"), /* VAR_ERR_MISSING_PARAMETER_IN_COMMAND */ _("empty search string in search and replace operation"), /* VAR_ERR_EMPTY_SEARCH_STRING */ _("start offset missing in cut operation"), /* VAR_ERR_MISSING_START_OFFSET */ _("offsets in cut operation delimited by unknown character"), /* VAR_ERR_INVALID_OFFSET_DELIMITER */ _("range out of bounds in cut operation"), /* VAR_ERR_RANGE_OUT_OF_BOUNDS */ _("offset out of bounds in cut operation"), /* VAR_ERR_OFFSET_OUT_OF_BOUNDS */ _("logic error in cut operation"), /* VAR_ERR_OFFSET_LOGIC */ _("malformatted transpose operation"), /* VAR_ERR_MALFORMATTED_TRANSPOSE */ _("source and target class mismatch in transpose operation"), /* VAR_ERR_TRANSPOSE_CLASSES_MISMATCH */ _("empty character class in transpose operation"), /* VAR_ERR_EMPTY_TRANSPOSE_CLASS */ _("incorrect character class in transpose operation"), /* VAR_ERR_INCORRECT_TRANSPOSE_CLASS_SPEC */ _("malformatted padding operation"), /* VAR_ERR_MALFORMATTED_PADDING */ _("width parameter missing in padding operation"), /* VAR_ERR_MISSING_PADDING_WIDTH */ _("fill string missing in padding operation"), /* VAR_ERR_EMPTY_PADDING_FILL_STRING */ _("unknown quoted pair in search and replace operation"), /* VAR_ERR_UNKNOWN_QUOTED_PAIR_IN_REPLACE */ _("sub-matching reference out of range"), /* VAR_ERR_SUBMATCH_OUT_OF_RANGE */ _("invalid argument"), /* VAR_ERR_INVALID_ARGUMENT */ _("incomplete quoted pair"), /* VAR_ERR_INCOMPLETE_QUOTED_PAIR */ _("lookup function does not support variable arrays"), /* VAR_ERR_ARRAY_LOOKUPS_ARE_UNSUPPORTED */ _("index of array variable contains an invalid character"), /* VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC */ _("index of array variable is incomplete"), /* VAR_ERR_INCOMPLETE_INDEX_SPEC */ _("bracket expression in array variable's index not closed"), /* VAR_ERR_UNCLOSED_BRACKET_IN_INDEX */ _("division by zero error in index specification"), /* VAR_ERR_DIVISION_BY_ZERO_IN_INDEX */ _("unterminated loop construct"), /* VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT */ _("invalid character in loop limits"), /* VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS */ _("malformed operation argument list"), /* VAR_ERR_MALFORMED_OPERATION_ARGUMENTS */ _("undefined operation"), /* VAR_ERR_UNDEFINED_OPERATION */ _("formatting failure") /* VAR_ERR_FORMATTING_FAILURE */ }; /* translate a return code into its corresponding descriptive text */ const char *var_strerror(var_t *var, var_rc_t rc) { const char *str; rc = (var_rc_t)(0 - rc); if (rc < 0 || rc >= (int)sizeof(var_errors) / (int)sizeof(char *)) { str = _("unknown error"); } else { str = (char *)var_errors[rc]; } return str; } bareos-Release-14.2.6/src/lib/var.h000066400000000000000000000130541263011562700167410ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * OSSP var - Variable Expansion * Copyright (c) 2001-2002 Ralf S. Engelschall * Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/) * Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) * * This file is part of OSSP var, a variable expansion * library which can be found at http://www.ossp.org/pkg/lib/var/. * * Permission to use, copy, modify, and distribute this software for * any purpose with or without fee is hereby granted, provided that * the above copyright notice and this permission notice appear in all * copies. * * For disclaimer see below. */ /* * Modified for use with BACULA by Kern Sibbald, June 2003 */ #ifndef __VAR_H__ #define __VAR_H__ /* Error codes */ typedef enum { VAR_ERR_CALLBACK = -64, VAR_ERR_FORMATTING_FAILURE = -45, VAR_ERR_UNDEFINED_OPERATION = -44, VAR_ERR_MALFORMED_OPERATION_ARGUMENTS = -43, VAR_ERR_INVALID_CHAR_IN_LOOP_LIMITS = -42, VAR_ERR_UNTERMINATED_LOOP_CONSTRUCT = -41, VAR_ERR_DIVISION_BY_ZERO_IN_INDEX = -40, VAR_ERR_UNCLOSED_BRACKET_IN_INDEX = -39, VAR_ERR_INCOMPLETE_INDEX_SPEC = -37, VAR_ERR_INVALID_CHAR_IN_INDEX_SPEC = -36, VAR_ERR_ARRAY_LOOKUPS_ARE_UNSUPPORTED = -35, VAR_ERR_INCOMPLETE_QUOTED_PAIR = -34, VAR_ERR_INVALID_ARGUMENT = -34, VAR_ERR_SUBMATCH_OUT_OF_RANGE = -33, VAR_ERR_UNKNOWN_QUOTED_PAIR_IN_REPLACE = -32, VAR_ERR_EMPTY_PADDING_FILL_STRING = -31, VAR_ERR_MISSING_PADDING_WIDTH = -30, VAR_ERR_MALFORMATTED_PADDING = -29, VAR_ERR_INCORRECT_TRANSPOSE_CLASS_SPEC = -28, VAR_ERR_EMPTY_TRANSPOSE_CLASS = -27, VAR_ERR_TRANSPOSE_CLASSES_MISMATCH = -26, VAR_ERR_MALFORMATTED_TRANSPOSE = -25, VAR_ERR_OFFSET_LOGIC = -24, VAR_ERR_OFFSET_OUT_OF_BOUNDS = -23, VAR_ERR_RANGE_OUT_OF_BOUNDS = -22, VAR_ERR_INVALID_OFFSET_DELIMITER = -21, VAR_ERR_MISSING_START_OFFSET = -20, VAR_ERR_EMPTY_SEARCH_STRING = -19, VAR_ERR_MISSING_PARAMETER_IN_COMMAND = -18, VAR_ERR_INVALID_REGEX_IN_REPLACE = -17, VAR_ERR_UNKNOWN_REPLACE_FLAG = -16, VAR_ERR_MALFORMATTED_REPLACE = -15, VAR_ERR_UNKNOWN_COMMAND_CHAR = -14, VAR_ERR_INPUT_ISNT_TEXT_NOR_VARIABLE = -13, VAR_ERR_UNDEFINED_VARIABLE = -12, VAR_ERR_INCOMPLETE_VARIABLE_SPEC = -11, VAR_ERR_OUT_OF_MEMORY = -10, VAR_ERR_INVALID_CONFIGURATION = -9, VAR_ERR_INCORRECT_CLASS_SPEC = -8, VAR_ERR_INCOMPLETE_GROUPED_HEX = -7, VAR_ERR_INCOMPLETE_OCTAL = -6, VAR_ERR_INVALID_OCTAL = -5, VAR_ERR_OCTAL_TOO_LARGE = -4, VAR_ERR_INVALID_HEX = -3, VAR_ERR_INCOMPLETE_HEX = -2, VAR_ERR_INCOMPLETE_NAMED_CHARACTER = -1, VAR_OK = 0 } var_rc_t; struct var_st; typedef struct var_st var_t; typedef enum { VAR_CONFIG_SYNTAX, VAR_CONFIG_CB_VALUE, VAR_CONFIG_CB_OPERATION } var_config_t; typedef struct { char escape; /* default: '\' */ char delim_init; /* default: '$' */ char delim_open; /* default: '{' */ char delim_close; /* default: '}' */ char index_open; /* default: '[' */ char index_close; /* default: ']' */ char index_mark; /* default: '#' */ const char *name_chars; /* default: "a-zA-Z0-9_" */ } var_syntax_t; typedef var_rc_t (*var_cb_value_t)( var_t *var, void *ctx, const char *var_ptr, int var_len, int var_inc, int var_idx, const char **val_ptr, int *val_len, int *val_size ); typedef var_rc_t (*var_cb_operation_t)( var_t *var, void *ctx, const char *op_ptr, int op_len, const char *arg_ptr, int arg_len, const char *val_ptr, int val_len, const char **out_ptr, int *out_len, int *out_size ); var_rc_t var_create (var_t **var); var_rc_t var_destroy (var_t *var); var_rc_t var_config (var_t *var, var_config_t mode, ...); var_rc_t var_unescape (var_t *var, const char *src_ptr, int src_len, char *dst_ptr, int dst_len, int all); var_rc_t var_expand (var_t *var, const char *src_ptr, int src_len, char **dst_ptr, int *dst_len, int force_expand); var_rc_t var_formatv (var_t *var, char **dst_ptr, int force_expand, const char *fmt, va_list ap); var_rc_t var_format (var_t *var, char **dst_ptr, int force_expand, const char *fmt, ...); const char *var_strerror (var_t *var, var_rc_t rc); #endif /* __VAR_H__ */ bareos-Release-14.2.6/src/lib/waitq.h000066400000000000000000000037041263011562700172770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS wait queue routines. Permits waiting for something * to be done. I.e. for operator to mount new volume. * * Kern Sibbald, March MMI * * This code inspired from "Programming with POSIX Threads", by * David R. Butenhof */ #ifndef __WAITQ_H #define __WAITQ_H 1 /* * Structure to keep track of wait queue request */ typedef struct waitq_ele_tag { struct waitq_ele_tag *next; int done_flag; /* predicate for wait */ pthread_cont_t done; /* wait for completion */ void *msg; /* message to be passed */ } waitq_ele_t; /* * Structure describing a wait queue */ typedef struct workq_tag { pthread_mutex_t mutex; /* queue access control */ pthread_cond_t wait_req; /* wait for OK */ int num_msgs; /* number of waiters */ waitq_ele_t *first; /* wait queue first item */ waitq_ele_t *last; /* wait queue last item */ } workq_t; extern int waitq_init(waitq_t *wq); extern int waitq_destroy(waitq_t *wq); extern int waitq_add(waitq_t *wq, void *msg); #endif /* __WAITQ_H */ bareos-Release-14.2.6/src/lib/watchdog.c000066400000000000000000000212351263011562700177440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS thread watchdog routine. General routine that * allows setting a watchdog timer with a callback that is * called when the timer goes off. * * Kern Sibbald, January MMII */ #include "bareos.h" #include "jcr.h" /* Exported globals */ utime_t watchdog_time = 0; /* this has granularity of SLEEP_TIME */ utime_t watchdog_sleep_time = 60; /* examine things every 60 seconds */ /* Locals */ static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t timer = PTHREAD_COND_INITIALIZER; /* Forward referenced functions */ extern "C" void *watchdog_thread(void *arg); static void wd_lock(); static void wd_unlock(); /* Static globals */ static bool quit = false; static bool wd_is_init = false; static brwlock_t lock; /* watchdog lock */ static pthread_t wd_tid; static dlist *wd_queue; static dlist *wd_inactive; /* * Returns: 0 if the current thread is NOT the watchdog * 1 if the current thread is the watchdog */ bool is_watchdog() { if (wd_is_init && pthread_equal(pthread_self(), wd_tid)) { return true; } else { return false; } } /* * Start watchdog thread * * Returns: 0 on success * errno on failure */ int start_watchdog(void) { int status; watchdog_t *dummy = NULL; int errstat; if (wd_is_init) { return 0; } Dmsg0(800, "Initialising NicB-hacked watchdog thread\n"); watchdog_time = time(NULL); if ((errstat=rwl_init(&lock)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("Unable to initialize watchdog lock. ERR=%s\n"), be.bstrerror(errstat)); } wd_queue = New(dlist(dummy, &dummy->link)); wd_inactive = New(dlist(dummy, &dummy->link)); wd_is_init = true; if ((status = pthread_create(&wd_tid, NULL, watchdog_thread, NULL)) != 0) { return status; } return 0; } /* * Wake watchdog timer thread so that it walks the * queue and adjusts its wait time (or exits). */ static void ping_watchdog() { P(timer_mutex); pthread_cond_signal(&timer); V(timer_mutex); bmicrosleep(0, 100); } /* * Terminate the watchdog thread * * Returns: 0 on success * errno on failure */ int stop_watchdog(void) { int status; watchdog_t *p; if (!wd_is_init) { return 0; } quit = true; /* notify watchdog thread to stop */ ping_watchdog(); status = pthread_join(wd_tid, NULL); while (!wd_queue->empty()) { void *item = wd_queue->first(); wd_queue->remove(item); p = (watchdog_t *)item; if (p->destructor != NULL) { p->destructor(p); } free(p); } delete wd_queue; wd_queue = NULL; while (!wd_inactive->empty()) { void *item = wd_inactive->first(); wd_inactive->remove(item); p = (watchdog_t *)item; if (p->destructor != NULL) { p->destructor(p); } free(p); } delete wd_inactive; wd_inactive = NULL; rwl_destroy(&lock); wd_is_init = false; return status; } watchdog_t *new_watchdog(void) { watchdog_t *wd = (watchdog_t *)malloc(sizeof(watchdog_t)); if (!wd_is_init) { start_watchdog(); } if (wd == NULL) { return NULL; } wd->one_shot = true; wd->interval = 0; wd->callback = NULL; wd->destructor = NULL; wd->data = NULL; return wd; } bool register_watchdog(watchdog_t *wd) { if (!wd_is_init) { Jmsg0(NULL, M_ABORT, 0, _("BUG! register_watchdog called before start_watchdog\n")); } if (wd->callback == NULL) { Jmsg1(NULL, M_ABORT, 0, _("BUG! Watchdog %p has NULL callback\n"), wd); } if (wd->interval == 0) { Jmsg1(NULL, M_ABORT, 0, _("BUG! Watchdog %p has zero interval\n"), wd); } wd_lock(); wd->next_fire = watchdog_time + wd->interval; wd_queue->append(wd); Dmsg3(800, "Registered watchdog %p, interval %d%s\n", wd, wd->interval, wd->one_shot ? " one shot" : ""); wd_unlock(); ping_watchdog(); return false; } bool unregister_watchdog(watchdog_t *wd) { watchdog_t *p; bool ok = false; if (!wd_is_init) { Jmsg0(NULL, M_ABORT, 0, _("BUG! unregister_watchdog_unlocked called before start_watchdog\n")); } wd_lock(); foreach_dlist(p, wd_queue) { if (wd == p) { wd_queue->remove(wd); Dmsg1(800, "Unregistered watchdog %p\n", wd); ok = true; goto get_out; } } foreach_dlist(p, wd_inactive) { if (wd == p) { wd_inactive->remove(wd); Dmsg1(800, "Unregistered inactive watchdog %p\n", wd); ok = true; goto get_out; } } Dmsg1(800, "Failed to unregister watchdog %p\n", wd); get_out: wd_unlock(); ping_watchdog(); return ok; } /* * This is the thread that walks the watchdog queue * and when a queue item fires, the callback is * invoked. If it is a one shot, the queue item * is moved to the inactive queue. */ extern "C" void *watchdog_thread(void *arg) { struct timespec timeout; struct timeval tv; struct timezone tz; utime_t next_time; set_jcr_in_tsd(INVALID_JCR); Dmsg0(800, "NicB-reworked watchdog thread entered\n"); while (!quit) { watchdog_t *p; /* * * NOTE. lock_jcr_chain removed, but the message below * was left until we are sure there are no deadlocks. * * We lock the jcr chain here because a good number of the * callback routines lock the jcr chain. We need to lock * it here *before* the watchdog lock because the SD message * thread first locks the jcr chain, then when closing the * job locks the watchdog chain. If the two threads do not * lock in the same order, we get a deadlock -- each holds * the other's needed lock. */ wd_lock(); walk_list: watchdog_time = time(NULL); next_time = watchdog_time + watchdog_sleep_time; foreach_dlist(p, wd_queue) { if (p->next_fire <= watchdog_time) { /* Run the callback */ Dmsg2(3400, "Watchdog callback p=0x%p fire=%d\n", p, p->next_fire); p->callback(p); /* Reschedule (or move to inactive list if it's a one-shot timer) */ if (p->one_shot) { wd_queue->remove(p); wd_inactive->append(p); goto walk_list; } else { p->next_fire = watchdog_time + p->interval; } } if (p->next_fire <= next_time) { next_time = p->next_fire; } } wd_unlock(); /* * Wait sleep time or until someone wakes us */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + next_time - time(NULL); while (timeout.tv_nsec >= 1000000000) { timeout.tv_nsec -= 1000000000; timeout.tv_sec++; } Dmsg1(1900, "pthread_cond_timedwait %d\n", timeout.tv_sec - tv.tv_sec); /* Note, this unlocks mutex during the sleep */ P(timer_mutex); pthread_cond_timedwait(&timer, &timer_mutex, &timeout); V(timer_mutex); } Dmsg0(800, "NicB-reworked watchdog thread exited\n"); return NULL; } /* * Watchdog lock, this can be called multiple times by the same * thread without blocking, but must be unlocked the number of * times it was locked. */ static void wd_lock() { int errstat; if ((errstat=rwl_writelock(&lock)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("rwl_writelock failure. ERR=%s\n"), be.bstrerror(errstat)); } } /* * Unlock the watchdog. This can be called multiple times by the * same thread up to the number of times that thread called * wd_ lock()/ */ static void wd_unlock() { int errstat; if ((errstat=rwl_writeunlock(&lock)) != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("rwl_writeunlock failure. ERR=%s\n"), be.bstrerror(errstat)); } } bareos-Release-14.2.6/src/lib/watchdog.h000066400000000000000000000030361263011562700177500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Watchdog timer routines * * Kern Sibbald, December MMII */ enum { TYPE_CHILD = 1, TYPE_PTHREAD, TYPE_BSOCK }; #define TIMEOUT_SIGNAL SIGUSR2 struct s_watchdog_t { bool one_shot; utime_t interval; void (*callback)(struct s_watchdog_t *wd); void (*destructor)(struct s_watchdog_t *wd); void *data; /* Private data below - don't touch outside of watchdog.c */ dlink link; utime_t next_fire; }; typedef struct s_watchdog_t watchdog_t; /* Exported globals */ extern utime_t DLL_IMP_EXP watchdog_time; /* this has granularity of SLEEP_TIME */ extern utime_t DLL_IMP_EXP watchdog_sleep_time; /* examine things every 60 seconds */ bareos-Release-14.2.6/src/lib/workq.c000066400000000000000000000241701263011562700173100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS work queue routines. Permits passing work to * multiple threads. * * Kern Sibbald, January MMI * * This code adapted from "Programming with POSIX Threads", by David R. Butenhof * * Example: * * static workq_t job_wq; define work queue * * Initialize queue * if ((stat = workq_init(&job_wq, max_workers, job_thread)) != 0) { * berrno be; * Emsg1(M_ABORT, 0, "Could not init job work queue: ERR=%s\n", be.bstrerror(errno)); * } * * Add an item to the queue * if ((stat = workq_add(&job_wq, (void *)jcr)) != 0) { * berrno be; * Emsg1(M_ABORT, 0, "Could not add job to work queue: ERR=%s\n", be.bstrerror(errno)); * } * * Terminate the queue * workq_destroy(workq_t *wq); */ #include "bareos.h" #include "jcr.h" /* Forward referenced functions */ extern "C" void *workq_server(void *arg); /* * Initialize a work queue * * Returns: 0 on success * errno on failure */ int workq_init(workq_t *wq, int threads, void *(*engine)(void *arg)) { int status; if ((status = pthread_attr_init(&wq->attr)) != 0) { return status; } if ((status = pthread_attr_setdetachstate(&wq->attr, PTHREAD_CREATE_DETACHED)) != 0) { pthread_attr_destroy(&wq->attr); return status; } if ((status = pthread_mutex_init(&wq->mutex, NULL)) != 0) { pthread_attr_destroy(&wq->attr); return status; } if ((status = pthread_cond_init(&wq->work, NULL)) != 0) { pthread_mutex_destroy(&wq->mutex); pthread_attr_destroy(&wq->attr); return status; } wq->quit = 0; wq->first = wq->last = NULL; wq->max_workers = threads; /* max threads to create */ wq->num_workers = 0; /* no threads yet */ wq->idle_workers = 0; /* no idle threads */ wq->engine = engine; /* routine to run */ wq->valid = WORKQ_VALID; return 0; } /* * Destroy a work queue * * Returns: 0 on success * errno on failure */ int workq_destroy(workq_t *wq) { int status, status1, status2; if (wq->valid != WORKQ_VALID) { return EINVAL; } P(wq->mutex); wq->valid = 0; /* prevent any more operations */ /* * If any threads are active, wake them */ if (wq->num_workers > 0) { wq->quit = 1; if (wq->idle_workers) { if ((status = pthread_cond_broadcast(&wq->work)) != 0) { V(wq->mutex); return status; } } while (wq->num_workers > 0) { if ((status = pthread_cond_wait(&wq->work, &wq->mutex)) != 0) { V(wq->mutex); return status; } } } V(wq->mutex); status = pthread_mutex_destroy(&wq->mutex); status1 = pthread_cond_destroy(&wq->work); status2 = pthread_attr_destroy(&wq->attr); return (status != 0 ? status : (status1 != 0 ? status1 : status2)); } /* * Add work to a queue * wq is a queue that was created with workq_init * element is a user unique item that will be passed to the * processing routine * work_item will get internal work queue item -- if it is not NULL * priority if non-zero will cause the item to be placed on the * head of the list instead of the tail. */ int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority) { int status = 0; workq_ele_t *item; pthread_t id; Dmsg0(1400, "workq_add\n"); if (wq->valid != WORKQ_VALID) { return EINVAL; } if ((item = (workq_ele_t *)malloc(sizeof(workq_ele_t))) == NULL) { return ENOMEM; } item->data = element; item->next = NULL; P(wq->mutex); Dmsg0(1400, "add item to queue\n"); if (priority) { /* Add to head of queue */ if (wq->first == NULL) { wq->first = item; wq->last = item; } else { item->next = wq->first; wq->first = item; } } else { /* Add to end of queue */ if (wq->first == NULL) { wq->first = item; } else { wq->last->next = item; } wq->last = item; } /* if any threads are idle, wake one */ if (wq->idle_workers > 0) { Dmsg0(1400, "Signal worker\n"); if ((status = pthread_cond_broadcast(&wq->work)) != 0) { V(wq->mutex); return status; } } else if (wq->num_workers < wq->max_workers) { Dmsg0(1400, "Create worker thread\n"); /* No idle threads so create a new one */ set_thread_concurrency(wq->max_workers + 1); if ((status = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) { V(wq->mutex); return status; } wq->num_workers++; } V(wq->mutex); Dmsg0(1400, "Return workq_add\n"); /* Return work_item if requested */ if (work_item) { *work_item = item; } return status; } /* * Remove work from a queue * wq is a queue that was created with workq_init * work_item is an element of work * * Note, it is "removed" by immediately calling a processing routine. * if you want to cancel it, you need to provide some external means * of doing so. */ int workq_remove(workq_t *wq, workq_ele_t *work_item) { int status, found = 0; pthread_t id; workq_ele_t *item, *prev; Dmsg0(1400, "workq_remove\n"); if (wq->valid != WORKQ_VALID) { return EINVAL; } P(wq->mutex); for (prev=item=wq->first; item; item=item->next) { if (item == work_item) { found = 1; break; } prev = item; } if (!found) { return EINVAL; } /* Move item to be first on list */ if (wq->first != work_item) { prev->next = work_item->next; if (wq->last == work_item) { wq->last = prev; } work_item->next = wq->first; wq->first = work_item; } /* if any threads are idle, wake one */ if (wq->idle_workers > 0) { Dmsg0(1400, "Signal worker\n"); if ((status = pthread_cond_broadcast(&wq->work)) != 0) { V(wq->mutex); return status; } } else { Dmsg0(1400, "Create worker thread\n"); /* No idle threads so create a new one */ set_thread_concurrency(wq->max_workers + 1); if ((status = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) { V(wq->mutex); return status; } wq->num_workers++; } V(wq->mutex); Dmsg0(1400, "Return workq_remove\n"); return status; } /* * This is the worker thread that serves the work queue. * In due course, it will call the user's engine. */ extern "C" void *workq_server(void *arg) { struct timespec timeout; workq_t *wq = (workq_t *)arg; workq_ele_t *we; int status, timedout; Dmsg0(1400, "Start workq_server\n"); P(wq->mutex); set_jcr_in_tsd(INVALID_JCR); for (;;) { struct timeval tv; struct timezone tz; Dmsg0(1400, "Top of for loop\n"); timedout = 0; Dmsg0(1400, "gettimeofday()\n"); gettimeofday(&tv, &tz); timeout.tv_nsec = 0; timeout.tv_sec = tv.tv_sec + 2; while (wq->first == NULL && !wq->quit) { /* * Wait 2 seconds, then if no more work, exit */ Dmsg0(1400, "pthread_cond_timedwait()\n"); #ifdef xxxxxxxxxxxxxxxx_was_HAVE_CYGWIN /* CYGWIN dies with a page fault the second * time that pthread_cond_timedwait() is called * so fake it out. */ P(wq->mutex); status = ETIMEDOUT; #else status = pthread_cond_timedwait(&wq->work, &wq->mutex, &timeout); #endif Dmsg1(1400, "timedwait=%d\n", status); if (status == ETIMEDOUT) { timedout = 1; break; } else if (status != 0) { /* This shouldn't happen */ Dmsg0(1400, "This shouldn't happen\n"); wq->num_workers--; V(wq->mutex); return NULL; } } we = wq->first; if (we != NULL) { wq->first = we->next; if (wq->last == we) { wq->last = NULL; } V(wq->mutex); /* Call user's routine here */ Dmsg0(1400, "Calling user engine.\n"); wq->engine(we->data); Dmsg0(1400, "Back from user engine.\n"); free(we); /* release work entry */ Dmsg0(1400, "relock mutex\n"); P(wq->mutex); Dmsg0(1400, "Done lock mutex\n"); } /* * If no more work request, and we are asked to quit, then do it */ if (wq->first == NULL && wq->quit) { wq->num_workers--; if (wq->num_workers == 0) { Dmsg0(1400, "Wake up destroy routine\n"); /* Wake up destroy routine if he is waiting */ pthread_cond_broadcast(&wq->work); } Dmsg0(1400, "Unlock mutex\n"); V(wq->mutex); Dmsg0(1400, "Return from workq_server\n"); return NULL; } Dmsg0(1400, "Check for work request\n"); /* * If no more work requests, and we waited long enough, quit */ Dmsg1(1400, "wq->first==NULL = %d\n", wq->first==NULL); Dmsg1(1400, "timedout=%d\n", timedout); if (wq->first == NULL && timedout) { Dmsg0(1400, "break big loop\n"); wq->num_workers--; break; } Dmsg0(1400, "Loop again\n"); } /* end of big for loop */ Dmsg0(1400, "unlock mutex\n"); V(wq->mutex); Dmsg0(1400, "End workq_server\n"); return NULL; } bareos-Release-14.2.6/src/lib/workq.h000066400000000000000000000045051263011562700173150ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * BAREOS work queue routines. Permits passing work to * multiple threads. * * Kern Sibbald, January MMI * * This code adapted from "Programming with POSIX Threads", by David R. Butenhof */ #ifndef __WORKQ_H #define __WORKQ_H 1 /* * Structure to keep track of work queue request */ typedef struct workq_ele_tag { struct workq_ele_tag *next; void *data; } workq_ele_t; /* * Structure describing a work queue */ typedef struct workq_tag { pthread_mutex_t mutex; /* queue access control */ pthread_cond_t work; /* wait for work */ pthread_attr_t attr; /* create detached threads */ workq_ele_t *first, *last; /* work queue */ int valid; /* queue initialized */ int quit; /* workq should quit */ int max_workers; /* max threads */ int num_workers; /* current threads */ int idle_workers; /* idle threads */ void *(*engine)(void *arg); /* user engine */ } workq_t; #define WORKQ_VALID 0xdec1992 extern int workq_init( workq_t *wq, int threads, /* maximum threads */ void *(*engine)(void *) /* engine routine */ ); extern int workq_destroy(workq_t *wq); extern int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority); extern int workq_remove(workq_t *wq, workq_ele_t *work_item); #endif /* __WORKQ_H */ bareos-Release-14.2.6/src/lmdb/000077500000000000000000000000001263011562700161455ustar00rootroot00000000000000bareos-Release-14.2.6/src/lmdb/COPYRIGHT000066400000000000000000000013131263011562700174360ustar00rootroot00000000000000Copyright 2011-2014 Howard Chu, Symas Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted only as authorized by the OpenLDAP Public License. A copy of this license is available in the file LICENSE in the top-level directory of the distribution or, alternatively, at . OpenLDAP is a registered trademark of the OpenLDAP Foundation. Individual files and/or contributed packages may be copyright by other parties and/or subject to additional restrictions. This work also contains materials derived from public sources. Additional information about OpenLDAP can be obtained at . bareos-Release-14.2.6/src/lmdb/LICENSE000066400000000000000000000042461263011562700171600ustar00rootroot00000000000000The OpenLDAP Public License Version 2.8, 17 August 2003 Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source form must retain copyright statements and notices, 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and 3. Redistributions must contain a verbatim copy of this document. The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED 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 OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE 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 names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. OpenLDAP is a registered trademark of the OpenLDAP Foundation. Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. bareos-Release-14.2.6/src/lmdb/Makefile.in000066400000000000000000000070421263011562700202150ustar00rootroot00000000000000# @MCOMMON@ LIBTOOL_TAG = CC # Define library versions LIBBAREOSLMDB_LT_RELEASE = @LIBBAREOSLMDB_LT_RELEASE@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/lmdb DEBUG = @DEBUG@ first_rule: all dummy: # # include files installed when using libtool # INCLUDE_FILES = lmdb.h midl.h # # libbareoslmdb # LIBBAREOSLMDB_SRCS = mdb.c midl.c LIBBAREOSLMDB_OBJS = $(LIBBAREOSLMDB_SRCS:.c=.o) LIBBAREOSLMDB_LOBJS = $(LIBBAREOSLMDB_SRCS:.c=.lo) INCLUDES += -I. -I$(srcdir) -I$(basedir) -I$(basedir)/include CPPFLAGS += -D__USE_XOPEN2K8 .SUFFIXES: .c .cc .o .lo .ch .dvi .pdf .tex .view .w .1 .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CC) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CFLAGS) $< .c.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CC) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CFLAGS) $< .cc.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< .cc.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile libbareoslmdb$(DEFAULT_ARCHIVE_TYPE) @echo "==== Make of lib is good ====" @echo " " libbareoslmdb.a: $(LIBBAREOSLMDB_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOSLMDB_OBJS) $(RANLIB) $@ libbareoslmdb.la: Makefile $(LIBBAREOSLMDB_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CC) $(DEFS) $(DEBUG) $(LDFLAGS) -o $@ $(LIBBAREOSLMDB_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOSLMDB_LT_RELEASE) $(LIBS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-includes: $(MKDIR) $(DESTDIR)/$(includedir)/bareos/lmdb for I in $(INCLUDE_FILES); do \ $(INSTALL_DATA) $$I $(DESTDIR)$(includedir)/bareos/lmdb/`basename $$I`; \ done libtool-install: all $(MKDIR) $(DESTDIR)$(libdir) $(RMF) $(DESTDIR)$(libdir)/libbareoslmdb-*.so $(DESTDIR)$(libdir)/libbareoslmdb.la $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareoslmdb.la $(DESTDIR)$(libdir) install: @LIBTOOL_INSTALL_TARGET@ @INCLUDE_INSTALL_TARGET@ libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) core a.out *.o *.bak *.tex *.pdf *~ *.intpro *.extpro 1 2 3 realclean: clean @$(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) # Semi-automatic generation of dependencies: # # Use cc -M because X11 `makedepend' doesn't work on all systems # # and it also includes system headers. # # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @for src in $(LIBBAREOSLMDB_SRCS) ; do \ $(CC) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CPPFLAGS) $(XINC) $(INCLUDES) $$src >> Makefile; \ done @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ======= Something went wrong with make depend. ======="; \ fi # ----------------------------------------------------------------------- # # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/lmdb/lmdb.h000066400000000000000000002164241263011562700172450ustar00rootroot00000000000000/** @file lmdb.h * @brief Lightning memory-mapped database library * * @mainpage Lightning Memory-Mapped Database Manager (LMDB) * * @section intro_sec Introduction * LMDB is a Btree-based database management library modeled loosely on the * BerkeleyDB API, but much simplified. The entire database is exposed * in a memory map, and all data fetches return data directly * from the mapped memory, so no malloc's or memcpy's occur during * data fetches. As such, the library is extremely simple because it * requires no page caching layer of its own, and it is extremely high * performance and memory-efficient. It is also fully transactional with * full ACID semantics, and when the memory map is read-only, the * database integrity cannot be corrupted by stray pointer writes from * application code. * * The library is fully thread-aware and supports concurrent read/write * access from multiple processes and threads. Data pages use a copy-on- * write strategy so no active data pages are ever overwritten, which * also provides resistance to corruption and eliminates the need of any * special recovery procedures after a system crash. Writes are fully * serialized; only one write transaction may be active at a time, which * guarantees that writers can never deadlock. The database structure is * multi-versioned so readers run with no locks; writers cannot block * readers, and readers don't block writers. * * Unlike other well-known database mechanisms which use either write-ahead * transaction logs or append-only data writes, LMDB requires no maintenance * during operation. Both write-ahead loggers and append-only databases * require periodic checkpointing and/or compaction of their log or database * files otherwise they grow without bound. LMDB tracks free pages within * the database and re-uses them for new write operations, so the database * size does not grow without bound in normal use. * * The memory map can be used as a read-only or read-write map. It is * read-only by default as this provides total immunity to corruption. * Using read-write mode offers much higher write performance, but adds * the possibility for stray application writes thru pointers to silently * corrupt the database. Of course if your application code is known to * be bug-free (...) then this is not an issue. * * @section caveats_sec Caveats * Troubleshooting the lock file, plus semaphores on BSD systems: * * - A broken lockfile can cause sync issues. * Stale reader transactions left behind by an aborted program * cause further writes to grow the database quickly, and * stale locks can block further operation. * * Fix: Check for stale readers periodically, using the * #mdb_reader_check function or the \ref mdb_stat_1 "mdb_stat" tool. * Stale writers will be cleared automatically on most systems: * - Windows - automatic * - BSD, systems using SysV semaphores - automatic * - Linux, systems using POSIX mutexes with Robust option - automatic * Otherwise just make all programs using the database close it; * the lockfile is always reset on first open of the environment. * * - On BSD systems or others configured with MDB_USE_SYSV_SEM or * MDB_USE_POSIX_SEM, * startup can fail due to semaphores owned by another userid. * * Fix: Open and close the database as the user which owns the * semaphores (likely last user) or as root, while no other * process is using the database. * * Restrictions/caveats (in addition to those listed for some functions): * * - Only the database owner should normally use the database on * BSD systems or when otherwise configured with MDB_USE_POSIX_SEM. * Multiple users can cause startup to fail later, as noted above. * * - There is normally no pure read-only mode, since readers need write * access to locks and lock file. Exceptions: On read-only filesystems * or with the #MDB_NOLOCK flag described under #mdb_env_open(). * * - By default, in versions before 0.9.10, unused portions of the data * file might receive garbage data from memory freed by other code. * (This does not happen when using the #MDB_WRITEMAP flag.) As of * 0.9.10 the default behavior is to initialize such memory before * writing to the data file. Since there may be a slight performance * cost due to this initialization, applications may disable it using * the #MDB_NOMEMINIT flag. Applications handling sensitive data * which must not be written should not use this flag. This flag is * irrelevant when using #MDB_WRITEMAP. * * - A thread can only use one transaction at a time, plus any child * transactions. Each transaction belongs to one thread. See below. * The #MDB_NOTLS flag changes this for read-only transactions. * * - Use an MDB_env* in the process which opened it, without fork()ing. * * - Do not have open an LMDB database twice in the same process at * the same time. Not even from a plain open() call - close()ing it * breaks flock() advisory locking. * * - Avoid long-lived transactions. Read transactions prevent * reuse of pages freed by newer write transactions, thus the * database can grow quickly. Write transactions prevent * other write transactions, since writes are serialized. * * - Avoid suspending a process with active transactions. These * would then be "long-lived" as above. Also read transactions * suspended when writers commit could sometimes see wrong data. * * ...when several processes can use a database concurrently: * * - Avoid aborting a process with an active transaction. * The transaction becomes "long-lived" as above until a check * for stale readers is performed or the lockfile is reset, * since the process may not remove it from the lockfile. * * This does not apply to write transactions if the system clears * stale writers, see above. * * - If you do that anyway, do a periodic check for stale readers. Or * close the environment once in a while, so the lockfile can get reset. * * - Do not use LMDB databases on remote filesystems, even between * processes on the same host. This breaks flock() on some OSes, * possibly memory map sync, and certainly sync between programs * on different hosts. * * - Opening a database can fail if another process is opening or * closing it at exactly the same time. * * @author Howard Chu, Symas Corporation. * * @copyright Copyright 2011-2015 Howard Chu, Symas Corp. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . * * @par Derived From: * This code is derived from btree.c written by Martin Hedenfalk. * * Copyright (c) 2009, 2010 Martin Hedenfalk * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _LMDB_H_ #define _LMDB_H_ #include #ifdef __cplusplus extern "C" { #endif /** Unix permissions for creating files, or dummy definition for Windows */ #ifdef _MSC_VER typedef int mdb_mode_t; #else typedef mode_t mdb_mode_t; #endif /** An abstraction for a file handle. * On POSIX systems file handles are small integers. On Windows * they're opaque pointers. */ #ifdef _WIN32 typedef void *mdb_filehandle_t; #else typedef int mdb_filehandle_t; #endif /** @defgroup mdb LMDB API * @{ * @brief OpenLDAP Lightning Memory-Mapped Database Manager */ /** @defgroup Version Version Macros * @{ */ /** Library major version */ #define MDB_VERSION_MAJOR 0 /** Library minor version */ #define MDB_VERSION_MINOR 9 /** Library patch version */ #define MDB_VERSION_PATCH 16 /** Combine args a,b,c into a single integer for easy version comparisons */ #define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c)) /** The full library version as a single integer */ #define MDB_VERSION_FULL \ MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH) /** The release date of this library version */ #define MDB_VERSION_DATE "August 14, 2015" /** A stringifier for the version info */ #define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")" /** A helper for the stringifier macro */ #define MDB_VERFOO(a,b,c,d) MDB_VERSTR(a,b,c,d) /** The full library version as a C string */ #define MDB_VERSION_STRING \ MDB_VERFOO(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH,MDB_VERSION_DATE) /** @} */ /** @brief Opaque structure for a database environment. * * A DB environment supports multiple databases, all residing in the same * shared-memory map. */ typedef struct MDB_env MDB_env; /** @brief Opaque structure for a transaction handle. * * All database operations require a transaction handle. Transactions may be * read-only or read-write. */ typedef struct MDB_txn MDB_txn; /** @brief A handle for an individual database in the DB environment. */ typedef unsigned int MDB_dbi; /** @brief Opaque structure for navigating through a database */ typedef struct MDB_cursor MDB_cursor; /** @brief Generic structure used for passing keys and data in and out * of the database. * * Values returned from the database are valid only until a subsequent * update operation, or the end of the transaction. Do not modify or * free them, they commonly point into the database itself. * * Key sizes must be between 1 and #mdb_env_get_maxkeysize() inclusive. * The same applies to data sizes in databases with the #MDB_DUPSORT flag. * Other data items can in theory be from 0 to 0xffffffff bytes long. */ typedef struct MDB_val { size_t mv_size; /**< size of the data item */ void *mv_data; /**< address of the data item */ } MDB_val; /** @brief A callback function used to compare two keys in a database */ typedef int (MDB_cmp_func)(const MDB_val *a, const MDB_val *b); /** @brief A callback function used to relocate a position-dependent data item * in a fixed-address database. * * The \b newptr gives the item's desired address in * the memory map, and \b oldptr gives its previous address. The item's actual * data resides at the address in \b item. This callback is expected to walk * through the fields of the record in \b item and modify any * values based at the \b oldptr address to be relative to the \b newptr address. * @param[in,out] item The item that is to be relocated. * @param[in] oldptr The previous address. * @param[in] newptr The new address to relocate to. * @param[in] relctx An application-provided context, set by #mdb_set_relctx(). * @todo This feature is currently unimplemented. */ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *relctx); /** @defgroup mdb_env Environment Flags * @{ */ /** mmap at a fixed address (experimental) */ #define MDB_FIXEDMAP 0x01 /** no environment directory */ #define MDB_NOSUBDIR 0x4000 /** don't fsync after commit */ #define MDB_NOSYNC 0x10000 /** read only */ #define MDB_RDONLY 0x20000 /** don't fsync metapage after commit */ #define MDB_NOMETASYNC 0x40000 /** use writable mmap */ #define MDB_WRITEMAP 0x80000 /** use asynchronous msync when #MDB_WRITEMAP is used */ #define MDB_MAPASYNC 0x100000 /** tie reader locktable slots to #MDB_txn objects instead of to threads */ #define MDB_NOTLS 0x200000 /** don't do any locking, caller must manage their own locks */ #define MDB_NOLOCK 0x400000 /** don't do readahead (no effect on Windows) */ #define MDB_NORDAHEAD 0x800000 /** don't initialize malloc'd memory before writing to datafile */ #define MDB_NOMEMINIT 0x1000000 /** @} */ /** @defgroup mdb_dbi_open Database Flags * @{ */ /** use reverse string keys */ #define MDB_REVERSEKEY 0x02 /** use sorted duplicates */ #define MDB_DUPSORT 0x04 /** numeric keys in native byte order: either unsigned int or size_t. * The keys must all be of the same size. */ #define MDB_INTEGERKEY 0x08 /** with #MDB_DUPSORT, sorted dup items have fixed size */ #define MDB_DUPFIXED 0x10 /** with #MDB_DUPSORT, dups are #MDB_INTEGERKEY-style integers */ #define MDB_INTEGERDUP 0x20 /** with #MDB_DUPSORT, use reverse string dups */ #define MDB_REVERSEDUP 0x40 /** create DB if not already existing */ #define MDB_CREATE 0x40000 /** @} */ /** @defgroup mdb_put Write Flags * @{ */ /** For put: Don't write if the key already exists. */ #define MDB_NOOVERWRITE 0x10 /** Only for #MDB_DUPSORT
* For put: don't write if the key and data pair already exist.
* For mdb_cursor_del: remove all duplicate data items. */ #define MDB_NODUPDATA 0x20 /** For mdb_cursor_put: overwrite the current key/data pair */ #define MDB_CURRENT 0x40 /** For put: Just reserve space for data, don't copy it. Return a * pointer to the reserved space. */ #define MDB_RESERVE 0x10000 /** Data is being appended, don't split full pages. */ #define MDB_APPEND 0x20000 /** Duplicate data is being appended, don't split full pages. */ #define MDB_APPENDDUP 0x40000 /** Store multiple data items in one call. Only for #MDB_DUPFIXED. */ #define MDB_MULTIPLE 0x80000 /* @} */ /** @defgroup mdb_copy Copy Flags * @{ */ /** Compacting copy: Omit free space from copy, and renumber all * pages sequentially. */ #define MDB_CP_COMPACT 0x01 /* @} */ /** @brief Cursor Get operations. * * This is the set of all operations for retrieving data * using a cursor. */ typedef enum MDB_cursor_op { MDB_FIRST, /**< Position at first key/data item */ MDB_FIRST_DUP, /**< Position at first data item of current key. Only for #MDB_DUPSORT */ MDB_GET_BOTH, /**< Position at key/data pair. Only for #MDB_DUPSORT */ MDB_GET_BOTH_RANGE, /**< position at key, nearest data. Only for #MDB_DUPSORT */ MDB_GET_CURRENT, /**< Return key/data at current cursor position */ MDB_GET_MULTIPLE, /**< Return key and up to a page of duplicate data items from current cursor position. Move cursor to prepare for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */ MDB_LAST, /**< Position at last key/data item */ MDB_LAST_DUP, /**< Position at last data item of current key. Only for #MDB_DUPSORT */ MDB_NEXT, /**< Position at next data item */ MDB_NEXT_DUP, /**< Position at next data item of current key. Only for #MDB_DUPSORT */ MDB_NEXT_MULTIPLE, /**< Return key and up to a page of duplicate data items from next cursor position. Move cursor to prepare for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */ MDB_NEXT_NODUP, /**< Position at first data item of next key */ MDB_PREV, /**< Position at previous data item */ MDB_PREV_DUP, /**< Position at previous data item of current key. Only for #MDB_DUPSORT */ MDB_PREV_NODUP, /**< Position at last data item of previous key */ MDB_SET, /**< Position at specified key */ MDB_SET_KEY, /**< Position at specified key, return key + data */ MDB_SET_RANGE /**< Position at first key greater than or equal to specified key. */ } MDB_cursor_op; /** @defgroup errors Return Codes * * BerkeleyDB uses -30800 to -30999, we'll go under them * @{ */ /** Successful result */ #define MDB_SUCCESS 0 /** key/data pair already exists */ #define MDB_KEYEXIST (-30799) /** key/data pair not found (EOF) */ #define MDB_NOTFOUND (-30798) /** Requested page not found - this usually indicates corruption */ #define MDB_PAGE_NOTFOUND (-30797) /** Located page was wrong type */ #define MDB_CORRUPTED (-30796) /** Update of meta page failed or environment had fatal error */ #define MDB_PANIC (-30795) /** Environment version mismatch */ #define MDB_VERSION_MISMATCH (-30794) /** File is not a valid LMDB file */ #define MDB_INVALID (-30793) /** Environment mapsize reached */ #define MDB_MAP_FULL (-30792) /** Environment maxdbs reached */ #define MDB_DBS_FULL (-30791) /** Environment maxreaders reached */ #define MDB_READERS_FULL (-30790) /** Too many TLS keys in use - Windows only */ #define MDB_TLS_FULL (-30789) /** Txn has too many dirty pages */ #define MDB_TXN_FULL (-30788) /** Cursor stack too deep - internal error */ #define MDB_CURSOR_FULL (-30787) /** Page has not enough space - internal error */ #define MDB_PAGE_FULL (-30786) /** Database contents grew beyond environment mapsize */ #define MDB_MAP_RESIZED (-30785) /** Operation and DB incompatible, or DB type changed. This can mean: *
    *
  • The operation expects an #MDB_DUPSORT / #MDB_DUPFIXED database. *
  • Opening a named DB when the unnamed DB has #MDB_DUPSORT / #MDB_INTEGERKEY. *
  • Accessing a data record as a database, or vice versa. *
  • The database was dropped and recreated with different flags. *
*/ #define MDB_INCOMPATIBLE (-30784) /** Invalid reuse of reader locktable slot */ #define MDB_BAD_RSLOT (-30783) /** Transaction must abort, has a child, or is invalid */ #define MDB_BAD_TXN (-30782) /** Unsupported size of key/DB name/data, or wrong DUPFIXED size */ #define MDB_BAD_VALSIZE (-30781) /** The specified DBI was changed unexpectedly */ #define MDB_BAD_DBI (-30780) /** The last defined error code */ #define MDB_LAST_ERRCODE MDB_BAD_DBI /** @} */ /** @brief Statistics for a database in the environment */ typedef struct MDB_stat { unsigned int ms_psize; /**< Size of a database page. This is currently the same for all databases. */ unsigned int ms_depth; /**< Depth (height) of the B-tree */ size_t ms_branch_pages; /**< Number of internal (non-leaf) pages */ size_t ms_leaf_pages; /**< Number of leaf pages */ size_t ms_overflow_pages; /**< Number of overflow pages */ size_t ms_entries; /**< Number of data items */ } MDB_stat; /** @brief Information about the environment */ typedef struct MDB_envinfo { void *me_mapaddr; /**< Address of map, if fixed */ size_t me_mapsize; /**< Size of the data memory map */ size_t me_last_pgno; /**< ID of the last used page */ size_t me_last_txnid; /**< ID of the last committed transaction */ unsigned int me_maxreaders; /**< max reader slots in the environment */ unsigned int me_numreaders; /**< max reader slots used in the environment */ } MDB_envinfo; /** @brief Return the LMDB library version information. * * @param[out] major if non-NULL, the library major version number is copied here * @param[out] minor if non-NULL, the library minor version number is copied here * @param[out] patch if non-NULL, the library patch version number is copied here * @retval "version string" The library version as a string */ char *mdb_version(int *major, int *minor, int *patch); /** @brief Return a string describing a given error code. * * This function is a superset of the ANSI C X3.159-1989 (ANSI C) strerror(3) * function. If the error code is greater than or equal to 0, then the string * returned by the system function strerror(3) is returned. If the error code * is less than 0, an error string corresponding to the LMDB library error is * returned. See @ref errors for a list of LMDB-specific error codes. * @param[in] err The error code * @retval "error message" The description of the error */ char *mdb_strerror(int err); /** @brief Create an LMDB environment handle. * * This function allocates memory for a #MDB_env structure. To release * the allocated memory and discard the handle, call #mdb_env_close(). * Before the handle may be used, it must be opened using #mdb_env_open(). * Various other options may also need to be set before opening the handle, * e.g. #mdb_env_set_mapsize(), #mdb_env_set_maxreaders(), #mdb_env_set_maxdbs(), * depending on usage requirements. * @param[out] env The address where the new handle will be stored * @return A non-zero error value on failure and 0 on success. */ int mdb_env_create(MDB_env **env); /** @brief Open an environment handle. * * If this function fails, #mdb_env_close() must be called to discard the #MDB_env handle. * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] path The directory in which the database files reside. This * directory must already exist and be writable. * @param[in] flags Special options for this environment. This parameter * must be set to 0 or by bitwise OR'ing together one or more of the * values described here. * Flags set by mdb_env_set_flags() are also used. *
    *
  • #MDB_FIXEDMAP * use a fixed address for the mmap region. This flag must be specified * when creating the environment, and is stored persistently in the environment. * If successful, the memory map will always reside at the same virtual address * and pointers used to reference data items in the database will be constant * across multiple invocations. This option may not always work, depending on * how the operating system has allocated memory to shared libraries and other uses. * The feature is highly experimental. *
  • #MDB_NOSUBDIR * By default, LMDB creates its environment in a directory whose * pathname is given in \b path, and creates its data and lock files * under that directory. With this option, \b path is used as-is for * the database main data file. The database lock file is the \b path * with "-lock" appended. *
  • #MDB_RDONLY * Open the environment in read-only mode. No write operations will be * allowed. LMDB will still modify the lock file - except on read-only * filesystems, where LMDB does not use locks. *
  • #MDB_WRITEMAP * Use a writeable memory map unless MDB_RDONLY is set. This is faster * and uses fewer mallocs, but loses protection from application bugs * like wild pointer writes and other bad updates into the database. * Incompatible with nested transactions. * Do not mix processes with and without MDB_WRITEMAP on the same * environment. This can defeat durability (#mdb_env_sync etc). *
  • #MDB_NOMETASYNC * Flush system buffers to disk only once per transaction, omit the * metadata flush. Defer that until the system flushes files to disk, * or next non-MDB_RDONLY commit or #mdb_env_sync(). This optimization * maintains database integrity, but a system crash may undo the last * committed transaction. I.e. it preserves the ACI (atomicity, * consistency, isolation) but not D (durability) database property. * This flag may be changed at any time using #mdb_env_set_flags(). *
  • #MDB_NOSYNC * Don't flush system buffers to disk when committing a transaction. * This optimization means a system crash can corrupt the database or * lose the last transactions if buffers are not yet flushed to disk. * The risk is governed by how often the system flushes dirty buffers * to disk and how often #mdb_env_sync() is called. However, if the * filesystem preserves write order and the #MDB_WRITEMAP flag is not * used, transactions exhibit ACI (atomicity, consistency, isolation) * properties and only lose D (durability). I.e. database integrity * is maintained, but a system crash may undo the final transactions. * Note that (#MDB_NOSYNC | #MDB_WRITEMAP) leaves the system with no * hint for when to write transactions to disk, unless #mdb_env_sync() * is called. (#MDB_MAPASYNC | #MDB_WRITEMAP) may be preferable. * This flag may be changed at any time using #mdb_env_set_flags(). *
  • #MDB_MAPASYNC * When using #MDB_WRITEMAP, use asynchronous flushes to disk. * As with #MDB_NOSYNC, a system crash can then corrupt the * database or lose the last transactions. Calling #mdb_env_sync() * ensures on-disk database integrity until next commit. * This flag may be changed at any time using #mdb_env_set_flags(). *
  • #MDB_NOTLS * Don't use Thread-Local Storage. Tie reader locktable slots to * #MDB_txn objects instead of to threads. I.e. #mdb_txn_reset() keeps * the slot reseved for the #MDB_txn object. A thread may use parallel * read-only transactions. A read-only transaction may span threads if * the user synchronizes its use. Applications that multiplex many * user threads over individual OS threads need this option. Such an * application must also serialize the write transactions in an OS * thread, since LMDB's write locking is unaware of the user threads. *
  • #MDB_NOLOCK * Don't do any locking. If concurrent access is anticipated, the * caller must manage all concurrency itself. For proper operation * the caller must enforce single-writer semantics, and must ensure * that no readers are using old transactions while a writer is * active. The simplest approach is to use an exclusive lock so that * no readers may be active at all when a writer begins. *
  • #MDB_NORDAHEAD * Turn off readahead. Most operating systems perform readahead on * read requests by default. This option turns it off if the OS * supports it. Turning it off may help random read performance * when the DB is larger than RAM and system RAM is full. * The option is not implemented on Windows. *
  • #MDB_NOMEMINIT * Don't initialize malloc'd memory before writing to unused spaces * in the data file. By default, memory for pages written to the data * file is obtained using malloc. While these pages may be reused in * subsequent transactions, freshly malloc'd pages will be initialized * to zeroes before use. This avoids persisting leftover data from other * code (that used the heap and subsequently freed the memory) into the * data file. Note that many other system libraries may allocate * and free memory from the heap for arbitrary uses. E.g., stdio may * use the heap for file I/O buffers. This initialization step has a * modest performance cost so some applications may want to disable * it using this flag. This option can be a problem for applications * which handle sensitive data like passwords, and it makes memory * checkers like Valgrind noisy. This flag is not needed with #MDB_WRITEMAP, * which writes directly to the mmap instead of using malloc for pages. The * initialization is also skipped if #MDB_RESERVE is used; the * caller is expected to overwrite all of the memory that was * reserved in that case. * This flag may be changed at any time using #mdb_env_set_flags(). *
* @param[in] mode The UNIX permissions to set on created files and semaphores. * This parameter is ignored on Windows. * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_VERSION_MISMATCH - the version of the LMDB library doesn't match the * version that created the database environment. *
  • #MDB_INVALID - the environment file headers are corrupted. *
  • ENOENT - the directory specified by the path parameter doesn't exist. *
  • EACCES - the user didn't have permission to access the environment files. *
  • EAGAIN - the environment was locked by another process. *
*/ int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode); /** @brief Copy an LMDB environment to the specified path. * * This function may be used to make a backup of an existing environment. * No lockfile is created, since it gets recreated at need. * @note This call can trigger significant file size growth if run in * parallel with write transactions, because it employs a read-only * transaction. See long-lived transactions under @ref caveats_sec. * @param[in] env An environment handle returned by #mdb_env_create(). It * must have already been opened successfully. * @param[in] path The directory in which the copy will reside. This * directory must already exist and be writable but must otherwise be * empty. * @return A non-zero error value on failure and 0 on success. */ int mdb_env_copy(MDB_env *env, const char *path); /** @brief Copy an LMDB environment to the specified file descriptor. * * This function may be used to make a backup of an existing environment. * No lockfile is created, since it gets recreated at need. * @note This call can trigger significant file size growth if run in * parallel with write transactions, because it employs a read-only * transaction. See long-lived transactions under @ref caveats_sec. * @param[in] env An environment handle returned by #mdb_env_create(). It * must have already been opened successfully. * @param[in] fd The filedescriptor to write the copy to. It must * have already been opened for Write access. * @return A non-zero error value on failure and 0 on success. */ int mdb_env_copyfd(MDB_env *env, mdb_filehandle_t fd); /** @brief Copy an LMDB environment to the specified path, with options. * * This function may be used to make a backup of an existing environment. * No lockfile is created, since it gets recreated at need. * @note This call can trigger significant file size growth if run in * parallel with write transactions, because it employs a read-only * transaction. See long-lived transactions under @ref caveats_sec. * @param[in] env An environment handle returned by #mdb_env_create(). It * must have already been opened successfully. * @param[in] path The directory in which the copy will reside. This * directory must already exist and be writable but must otherwise be * empty. * @param[in] flags Special options for this operation. This parameter * must be set to 0 or by bitwise OR'ing together one or more of the * values described here. *
    *
  • #MDB_CP_COMPACT - Perform compaction while copying: omit free * pages and sequentially renumber all pages in output. This option * consumes more CPU and runs more slowly than the default. *
* @return A non-zero error value on failure and 0 on success. */ int mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags); /** @brief Copy an LMDB environment to the specified file descriptor, * with options. * * This function may be used to make a backup of an existing environment. * No lockfile is created, since it gets recreated at need. See * #mdb_env_copy2() for further details. * @note This call can trigger significant file size growth if run in * parallel with write transactions, because it employs a read-only * transaction. See long-lived transactions under @ref caveats_sec. * @param[in] env An environment handle returned by #mdb_env_create(). It * must have already been opened successfully. * @param[in] fd The filedescriptor to write the copy to. It must * have already been opened for Write access. * @param[in] flags Special options for this operation. * See #mdb_env_copy2() for options. * @return A non-zero error value on failure and 0 on success. */ int mdb_env_copyfd2(MDB_env *env, mdb_filehandle_t fd, unsigned int flags); /** @brief Return statistics about the LMDB environment. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] stat The address of an #MDB_stat structure * where the statistics will be copied */ int mdb_env_stat(MDB_env *env, MDB_stat *stat); /** @brief Return information about the LMDB environment. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] stat The address of an #MDB_envinfo structure * where the information will be copied */ int mdb_env_info(MDB_env *env, MDB_envinfo *stat); /** @brief Flush the data buffers to disk. * * Data is always written to disk when #mdb_txn_commit() is called, * but the operating system may keep it buffered. LMDB always flushes * the OS buffers upon commit as well, unless the environment was * opened with #MDB_NOSYNC or in part #MDB_NOMETASYNC. This call is * not valid if the environment was opened with #MDB_RDONLY. * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] force If non-zero, force a synchronous flush. Otherwise * if the environment has the #MDB_NOSYNC flag set the flushes * will be omitted, and with #MDB_MAPASYNC they will be asynchronous. * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EACCES - the environment is read-only. *
  • EINVAL - an invalid parameter was specified. *
  • EIO - an error occurred during synchronization. *
*/ int mdb_env_sync(MDB_env *env, int force); /** @brief Close the environment and release the memory map. * * Only a single thread may call this function. All transactions, databases, * and cursors must already be closed before calling this function. Attempts to * use any such handles after calling this function will cause a SIGSEGV. * The environment handle will be freed and must not be used again after this call. * @param[in] env An environment handle returned by #mdb_env_create() */ void mdb_env_close(MDB_env *env); /** @brief Set environment flags. * * This may be used to set some flags in addition to those from * #mdb_env_open(), or to unset these flags. If several threads * change the flags at the same time, the result is undefined. * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] flags The flags to change, bitwise OR'ed together * @param[in] onoff A non-zero value sets the flags, zero clears them. * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_env_set_flags(MDB_env *env, unsigned int flags, int onoff); /** @brief Get environment flags. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] flags The address of an integer to store the flags * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_env_get_flags(MDB_env *env, unsigned int *flags); /** @brief Return the path that was used in #mdb_env_open(). * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] path Address of a string pointer to contain the path. This * is the actual string in the environment, not a copy. It should not be * altered in any way. * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_env_get_path(MDB_env *env, const char **path); /** @brief Return the filedescriptor for the given environment. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] fd Address of a mdb_filehandle_t to contain the descriptor. * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *fd); /** @brief Set the size of the memory map to use for this environment. * * The size should be a multiple of the OS page size. The default is * 10485760 bytes. The size of the memory map is also the maximum size * of the database. The value should be chosen as large as possible, * to accommodate future growth of the database. * This function should be called after #mdb_env_create() and before #mdb_env_open(). * It may be called at later times if no transactions are active in * this process. Note that the library does not check for this condition, * the caller must ensure it explicitly. * * The new size takes effect immediately for the current process but * will not be persisted to any others until a write transaction has been * committed by the current process. Also, only mapsize increases are * persisted into the environment. * * If the mapsize is increased by another process, and data has grown * beyond the range of the current mapsize, #mdb_txn_begin() will * return #MDB_MAP_RESIZED. This function may be called with a size * of zero to adopt the new size. * * Any attempt to set a size smaller than the space already consumed * by the environment will be silently changed to the current size of the used space. * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] size The size in bytes * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified, or the environment has * an active write transaction. *
*/ int mdb_env_set_mapsize(MDB_env *env, size_t size); /** @brief Set the maximum number of threads/reader slots for the environment. * * This defines the number of slots in the lock table that is used to track readers in the * the environment. The default is 126. * Starting a read-only transaction normally ties a lock table slot to the * current thread until the environment closes or the thread exits. If * MDB_NOTLS is in use, #mdb_txn_begin() instead ties the slot to the * MDB_txn object until it or the #MDB_env object is destroyed. * This function may only be called after #mdb_env_create() and before #mdb_env_open(). * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] readers The maximum number of reader lock table slots * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified, or the environment is already open. *
*/ int mdb_env_set_maxreaders(MDB_env *env, unsigned int readers); /** @brief Get the maximum number of threads/reader slots for the environment. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] readers Address of an integer to store the number of readers * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_env_get_maxreaders(MDB_env *env, unsigned int *readers); /** @brief Set the maximum number of named databases for the environment. * * This function is only needed if multiple databases will be used in the * environment. Simpler applications that use the environment as a single * unnamed database can ignore this option. * This function may only be called after #mdb_env_create() and before #mdb_env_open(). * * Currently a moderate number of slots are cheap but a huge number gets * expensive: 7-120 words per transaction, and every #mdb_dbi_open() * does a linear search of the opened slots. * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] dbs The maximum number of databases * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified, or the environment is already open. *
*/ int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs); /** @brief Get the maximum size of keys and #MDB_DUPSORT data we can write. * * Depends on the compile-time constant #MDB_MAXKEYSIZE. Default 511. * See @ref MDB_val. * @param[in] env An environment handle returned by #mdb_env_create() * @return The maximum size of a key we can write */ int mdb_env_get_maxkeysize(MDB_env *env); /** @brief Set application information associated with the #MDB_env. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] ctx An arbitrary pointer for whatever the application needs. * @return A non-zero error value on failure and 0 on success. */ int mdb_env_set_userctx(MDB_env *env, void *ctx); /** @brief Get the application information associated with the #MDB_env. * * @param[in] env An environment handle returned by #mdb_env_create() * @return The pointer set by #mdb_env_set_userctx(). */ void *mdb_env_get_userctx(MDB_env *env); /** @brief A callback function for most LMDB assert() failures, * called before printing the message and aborting. * * @param[in] env An environment handle returned by #mdb_env_create(). * @param[in] msg The assertion message, not including newline. */ typedef void MDB_assert_func(MDB_env *env, const char *msg); /** Set or reset the assert() callback of the environment. * Disabled if liblmdb is buillt with NDEBUG. * @note This hack should become obsolete as lmdb's error handling matures. * @param[in] env An environment handle returned by #mdb_env_create(). * @param[in] func An #MDB_assert_func function, or 0. * @return A non-zero error value on failure and 0 on success. */ int mdb_env_set_assert(MDB_env *env, MDB_assert_func *func); /** @brief Create a transaction for use with the environment. * * The transaction handle may be discarded using #mdb_txn_abort() or #mdb_txn_commit(). * @note A transaction and its cursors must only be used by a single * thread, and a thread may only have a single transaction at a time. * If #MDB_NOTLS is in use, this does not apply to read-only transactions. * @note Cursors may not span transactions. * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] parent If this parameter is non-NULL, the new transaction * will be a nested transaction, with the transaction indicated by \b parent * as its parent. Transactions may be nested to any level. A parent * transaction and its cursors may not issue any other operations than * mdb_txn_commit and mdb_txn_abort while it has active child transactions. * @param[in] flags Special options for this transaction. This parameter * must be set to 0 or by bitwise OR'ing together one or more of the * values described here. *
    *
  • #MDB_RDONLY * This transaction will not perform any write operations. *
  • #MDB_NOSYNC * Don't flush system buffers to disk when committing this transaction. *
  • #MDB_NOMETASYNC * Flush system buffers but omit metadata flush when committing this transaction. *
* @param[out] txn Address where the new #MDB_txn handle will be stored * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_PANIC - a fatal error occurred earlier and the environment * must be shut down. *
  • #MDB_MAP_RESIZED - another process wrote data beyond this MDB_env's * mapsize and this environment's map must be resized as well. * See #mdb_env_set_mapsize(). *
  • #MDB_READERS_FULL - a read-only transaction was requested and * the reader lock table is full. See #mdb_env_set_maxreaders(). *
  • ENOMEM - out of memory. *
*/ int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn); /** @brief Returns the transaction's #MDB_env * * @param[in] txn A transaction handle returned by #mdb_txn_begin() */ MDB_env *mdb_txn_env(MDB_txn *txn); /** @brief Return the transaction's ID. * * This returns the identifier associated with this transaction. For a * read-only transaction, this corresponds to the snapshot being read; * concurrent readers will frequently have the same transaction ID. * * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @return A transaction ID, valid if input is an active transaction. */ size_t mdb_txn_id(MDB_txn *txn); /** @brief Commit all the operations of a transaction into the database. * * The transaction handle is freed. It and its cursors must not be used * again after this call, except with #mdb_cursor_renew(). * @note Earlier documentation incorrectly said all cursors would be freed. * Only write-transactions free cursors. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
  • ENOSPC - no more disk space. *
  • EIO - a low-level I/O error occurred while writing. *
  • ENOMEM - out of memory. *
*/ int mdb_txn_commit(MDB_txn *txn); /** @brief Abandon all the operations of the transaction instead of saving them. * * The transaction handle is freed. It and its cursors must not be used * again after this call, except with #mdb_cursor_renew(). * @note Earlier documentation incorrectly said all cursors would be freed. * Only write-transactions free cursors. * @param[in] txn A transaction handle returned by #mdb_txn_begin() */ void mdb_txn_abort(MDB_txn *txn); /** @brief Reset a read-only transaction. * * Abort the transaction like #mdb_txn_abort(), but keep the transaction * handle. #mdb_txn_renew() may reuse the handle. This saves allocation * overhead if the process will start a new read-only transaction soon, * and also locking overhead if #MDB_NOTLS is in use. The reader table * lock is released, but the table slot stays tied to its thread or * #MDB_txn. Use mdb_txn_abort() to discard a reset handle, and to free * its lock table slot if MDB_NOTLS is in use. * Cursors opened within the transaction must not be used * again after this call, except with #mdb_cursor_renew(). * Reader locks generally don't interfere with writers, but they keep old * versions of database pages allocated. Thus they prevent the old pages * from being reused when writers commit new data, and so under heavy load * the database size may grow much more rapidly than otherwise. * @param[in] txn A transaction handle returned by #mdb_txn_begin() */ void mdb_txn_reset(MDB_txn *txn); /** @brief Renew a read-only transaction. * * This acquires a new reader lock for a transaction handle that had been * released by #mdb_txn_reset(). It must be called before a reset transaction * may be used again. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_PANIC - a fatal error occurred earlier and the environment * must be shut down. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_txn_renew(MDB_txn *txn); /** Compat with version <= 0.9.4, avoid clash with libmdb from MDB Tools project */ #define mdb_open(txn,name,flags,dbi) mdb_dbi_open(txn,name,flags,dbi) /** Compat with version <= 0.9.4, avoid clash with libmdb from MDB Tools project */ #define mdb_close(env,dbi) mdb_dbi_close(env,dbi) /** @brief Open a database in the environment. * * A database handle denotes the name and parameters of a database, * independently of whether such a database exists. * The database handle may be discarded by calling #mdb_dbi_close(). * The old database handle is returned if the database was already open. * The handle may only be closed once. * * The database handle will be private to the current transaction until * the transaction is successfully committed. If the transaction is * aborted the handle will be closed automatically. * After a successful commit the handle will reside in the shared * environment, and may be used by other transactions. * * This function must not be called from multiple concurrent * transactions in the same process. A transaction that uses * this function must finish (either commit or abort) before * any other transaction in the process may use this function. * * To use named databases (with name != NULL), #mdb_env_set_maxdbs() * must be called before opening the environment. Database names are * keys in the unnamed database, and may be read but not written. * * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] name The name of the database to open. If only a single * database is needed in the environment, this value may be NULL. * @param[in] flags Special options for this database. This parameter * must be set to 0 or by bitwise OR'ing together one or more of the * values described here. *
    *
  • #MDB_REVERSEKEY * Keys are strings to be compared in reverse order, from the end * of the strings to the beginning. By default, Keys are treated as strings and * compared from beginning to end. *
  • #MDB_DUPSORT * Duplicate keys may be used in the database. (Or, from another perspective, * keys may have multiple data items, stored in sorted order.) By default * keys must be unique and may have only a single data item. *
  • #MDB_INTEGERKEY * Keys are binary integers in native byte order, either unsigned int * or size_t, and will be sorted as such. * The keys must all be of the same size. *
  • #MDB_DUPFIXED * This flag may only be used in combination with #MDB_DUPSORT. This option * tells the library that the data items for this database are all the same * size, which allows further optimizations in storage and retrieval. When * all data items are the same size, the #MDB_GET_MULTIPLE and #MDB_NEXT_MULTIPLE * cursor operations may be used to retrieve multiple items at once. *
  • #MDB_INTEGERDUP * This option specifies that duplicate data items are binary integers, * similar to #MDB_INTEGERKEY keys. *
  • #MDB_REVERSEDUP * This option specifies that duplicate data items should be compared as * strings in reverse order. *
  • #MDB_CREATE * Create the named database if it doesn't exist. This option is not * allowed in a read-only transaction or a read-only environment. *
* @param[out] dbi Address where the new #MDB_dbi handle will be stored * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_NOTFOUND - the specified database doesn't exist in the environment * and #MDB_CREATE was not specified. *
  • #MDB_DBS_FULL - too many databases have been opened. See #mdb_env_set_maxdbs(). *
*/ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi); /** @brief Retrieve statistics for a database. * * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[out] stat The address of an #MDB_stat structure * where the statistics will be copied * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat); /** @brief Retrieve the DB flags for a database handle. * * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[out] flags Address where the flags will be returned. * @return A non-zero error value on failure and 0 on success. */ int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags); /** @brief Close a database handle. Normally unnecessary. Use with care: * * This call is not mutex protected. Handles should only be closed by * a single thread, and only if no other threads are going to reference * the database handle or one of its cursors any further. Do not close * a handle if an existing transaction has modified its database. * Doing so can cause misbehavior from database corruption to errors * like MDB_BAD_VALSIZE (since the DB name is gone). * * Closing a database handle is not necessary, but lets #mdb_dbi_open() * reuse the handle value. Usually it's better to set a bigger * #mdb_env_set_maxdbs(), unless that value would be large. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] dbi A database handle returned by #mdb_dbi_open() */ void mdb_dbi_close(MDB_env *env, MDB_dbi dbi); /** @brief Empty or delete+close a database. * * See #mdb_dbi_close() for restrictions about closing the DB handle. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] del 0 to empty the DB, 1 to delete it from the * environment and close the DB handle. * @return A non-zero error value on failure and 0 on success. */ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del); /** @brief Set a custom key comparison function for a database. * * The comparison function is called whenever it is necessary to compare a * key specified by the application with a key currently stored in the database. * If no comparison function is specified, and no special key flags were specified * with #mdb_dbi_open(), the keys are compared lexically, with shorter keys collating * before longer keys. * @warning This function must be called before any data access functions are used, * otherwise data corruption may occur. The same comparison function must be used by every * program accessing the database, every time the database is used. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] cmp A #MDB_cmp_func function * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp); /** @brief Set a custom data comparison function for a #MDB_DUPSORT database. * * This comparison function is called whenever it is necessary to compare a data * item specified by the application with a data item currently stored in the database. * This function only takes effect if the database was opened with the #MDB_DUPSORT * flag. * If no comparison function is specified, and no special key flags were specified * with #mdb_dbi_open(), the data items are compared lexically, with shorter items collating * before longer items. * @warning This function must be called before any data access functions are used, * otherwise data corruption may occur. The same comparison function must be used by every * program accessing the database, every time the database is used. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] cmp A #MDB_cmp_func function * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp); /** @brief Set a relocation function for a #MDB_FIXEDMAP database. * * @todo The relocation function is called whenever it is necessary to move the data * of an item to a different position in the database (e.g. through tree * balancing operations, shifts as a result of adds or deletes, etc.). It is * intended to allow address/position-dependent data items to be stored in * a database in an environment opened with the #MDB_FIXEDMAP option. * Currently the relocation feature is unimplemented and setting * this function has no effect. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] rel A #MDB_rel_func function * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel); /** @brief Set a context pointer for a #MDB_FIXEDMAP database's relocation function. * * See #mdb_set_relfunc and #MDB_rel_func for more details. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] ctx An arbitrary pointer for whatever the application needs. * It will be passed to the callback function set by #mdb_set_relfunc * as its \b relctx parameter whenever the callback is invoked. * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx); /** @brief Get items from a database. * * This function retrieves key/data pairs from the database. The address * and length of the data associated with the specified \b key are returned * in the structure to which \b data refers. * If the database supports duplicate keys (#MDB_DUPSORT) then the * first data item for the key will be returned. Retrieval of other * items requires the use of #mdb_cursor_get(). * * @note The memory pointed to by the returned values is owned by the * database. The caller need not dispose of the memory, and may not * modify it in any way. For values returned in a read-only transaction * any modification attempts will cause a SIGSEGV. * @note Values returned from the database are valid only until a * subsequent update operation, or the end of the transaction. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] key The key to search for in the database * @param[out] data The data corresponding to the key * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_NOTFOUND - the key was not in the database. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data); /** @brief Store items into a database. * * This function stores key/data pairs in the database. The default behavior * is to enter the new key/data pair, replacing any previously existing key * if duplicates are disallowed, or adding a duplicate data item if * duplicates are allowed (#MDB_DUPSORT). * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] key The key to store in the database * @param[in,out] data The data to store * @param[in] flags Special options for this operation. This parameter * must be set to 0 or by bitwise OR'ing together one or more of the * values described here. *
    *
  • #MDB_NODUPDATA - enter the new key/data pair only if it does not * already appear in the database. This flag may only be specified * if the database was opened with #MDB_DUPSORT. The function will * return #MDB_KEYEXIST if the key/data pair already appears in the * database. *
  • #MDB_NOOVERWRITE - enter the new key/data pair only if the key * does not already appear in the database. The function will return * #MDB_KEYEXIST if the key already appears in the database, even if * the database supports duplicates (#MDB_DUPSORT). The \b data * parameter will be set to point to the existing item. *
  • #MDB_RESERVE - reserve space for data of the given size, but * don't copy the given data. Instead, return a pointer to the * reserved space, which the caller can fill in later - before * the next update operation or the transaction ends. This saves * an extra memcpy if the data is being generated later. * LMDB does nothing else with this memory, the caller is expected * to modify all of the space requested. This flag must not be * specified if the database was opened with #MDB_DUPSORT. *
  • #MDB_APPEND - append the given key/data pair to the end of the * database. This option allows fast bulk loading when keys are * already known to be in the correct order. Loading unsorted keys * with this flag will cause a #MDB_KEYEXIST error. *
  • #MDB_APPENDDUP - as above, but for sorted dup data. *
* @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_MAP_FULL - the database is full, see #mdb_env_set_mapsize(). *
  • #MDB_TXN_FULL - the transaction has too many dirty pages. *
  • EACCES - an attempt was made to write in a read-only transaction. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags); /** @brief Delete items from a database. * * This function removes key/data pairs from the database. * If the database does not support sorted duplicate data items * (#MDB_DUPSORT) the data parameter is ignored. * If the database supports sorted duplicates and the data parameter * is NULL, all of the duplicate data items for the key will be * deleted. Otherwise, if the data parameter is non-NULL * only the matching data item will be deleted. * This function will return #MDB_NOTFOUND if the specified key/data * pair is not in the database. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] key The key to delete from the database * @param[in] data The data to delete * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EACCES - an attempt was made to write in a read-only transaction. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data); /** @brief Create a cursor handle. * * A cursor is associated with a specific transaction and database. * A cursor cannot be used when its database handle is closed. Nor * when its transaction has ended, except with #mdb_cursor_renew(). * It can be discarded with #mdb_cursor_close(). * A cursor in a write-transaction can be closed before its transaction * ends, and will otherwise be closed when its transaction ends. * A cursor in a read-only transaction must be closed explicitly, before * or after its transaction ends. It can be reused with * #mdb_cursor_renew() before finally closing it. * @note Earlier documentation said that cursors in every transaction * were closed when the transaction committed or aborted. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[out] cursor Address where the new #MDB_cursor handle will be stored * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor); /** @brief Close a cursor handle. * * The cursor handle will be freed and must not be used again after this call. * Its transaction must still be live if it is a write-transaction. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() */ void mdb_cursor_close(MDB_cursor *cursor); /** @brief Renew a cursor handle. * * A cursor is associated with a specific transaction and database. * Cursors that are only used in read-only * transactions may be re-used, to avoid unnecessary malloc/free overhead. * The cursor may be associated with a new read-only transaction, and * referencing the same database handle as it was created with. * This may be done whether the previous transaction is live or dead. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_cursor_renew(MDB_txn *txn, MDB_cursor *cursor); /** @brief Return the cursor's transaction handle. * * @param[in] cursor A cursor handle returned by #mdb_cursor_open() */ MDB_txn *mdb_cursor_txn(MDB_cursor *cursor); /** @brief Return the cursor's database handle. * * @param[in] cursor A cursor handle returned by #mdb_cursor_open() */ MDB_dbi mdb_cursor_dbi(MDB_cursor *cursor); /** @brief Retrieve by cursor. * * This function retrieves key/data pairs from the database. The address and length * of the key are returned in the object to which \b key refers (except for the * case of the #MDB_SET option, in which the \b key object is unchanged), and * the address and length of the data are returned in the object to which \b data * refers. * See #mdb_get() for restrictions on using the output values. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @param[in,out] key The key for a retrieved item * @param[in,out] data The data of a retrieved item * @param[in] op A cursor operation #MDB_cursor_op * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_NOTFOUND - no matching key found. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op); /** @brief Store by cursor. * * This function stores key/data pairs into the database. * The cursor is positioned at the new item, or on failure usually near it. * @note Earlier documentation incorrectly said errors would leave the * state of the cursor unchanged. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @param[in] key The key operated on. * @param[in] data The data operated on. * @param[in] flags Options for this operation. This parameter * must be set to 0 or one of the values described here. *
    *
  • #MDB_CURRENT - replace the item at the current cursor position. * The \b key parameter must still be provided, and must match it. * If using sorted duplicates (#MDB_DUPSORT) the data item must still * sort into the same place. This is intended to be used when the * new data is the same size as the old. Otherwise it will simply * perform a delete of the old record followed by an insert. *
  • #MDB_NODUPDATA - enter the new key/data pair only if it does not * already appear in the database. This flag may only be specified * if the database was opened with #MDB_DUPSORT. The function will * return #MDB_KEYEXIST if the key/data pair already appears in the * database. *
  • #MDB_NOOVERWRITE - enter the new key/data pair only if the key * does not already appear in the database. The function will return * #MDB_KEYEXIST if the key already appears in the database, even if * the database supports duplicates (#MDB_DUPSORT). *
  • #MDB_RESERVE - reserve space for data of the given size, but * don't copy the given data. Instead, return a pointer to the * reserved space, which the caller can fill in later. This saves * an extra memcpy if the data is being generated later. This flag * must not be specified if the database was opened with #MDB_DUPSORT. *
  • #MDB_APPEND - append the given key/data pair to the end of the * database. No key comparisons are performed. This option allows * fast bulk loading when keys are already known to be in the * correct order. Loading unsorted keys with this flag will cause * a #MDB_KEYEXIST error. *
  • #MDB_APPENDDUP - as above, but for sorted dup data. *
  • #MDB_MULTIPLE - store multiple contiguous data elements in a * single request. This flag may only be specified if the database * was opened with #MDB_DUPFIXED. The \b data argument must be an * array of two MDB_vals. The mv_size of the first MDB_val must be * the size of a single data element. The mv_data of the first MDB_val * must point to the beginning of the array of contiguous data elements. * The mv_size of the second MDB_val must be the count of the number * of data elements to store. On return this field will be set to * the count of the number of elements actually written. The mv_data * of the second MDB_val is unused. *
* @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • #MDB_MAP_FULL - the database is full, see #mdb_env_set_mapsize(). *
  • #MDB_TXN_FULL - the transaction has too many dirty pages. *
  • EACCES - an attempt was made to write in a read-only transaction. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags); /** @brief Delete current key/data pair * * This function deletes the key/data pair to which the cursor refers. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @param[in] flags Options for this operation. This parameter * must be set to 0 or one of the values described here. *
    *
  • #MDB_NODUPDATA - delete all of the data items for the current key. * This flag may only be specified if the database was opened with #MDB_DUPSORT. *
* @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EACCES - an attempt was made to write in a read-only transaction. *
  • EINVAL - an invalid parameter was specified. *
*/ int mdb_cursor_del(MDB_cursor *cursor, unsigned int flags); /** @brief Return count of duplicates for current key. * * This call is only valid on databases that support sorted duplicate * data items #MDB_DUPSORT. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @param[out] countp Address where the count will be stored * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    *
  • EINVAL - cursor is not initialized, or an invalid parameter was specified. *
*/ int mdb_cursor_count(MDB_cursor *cursor, size_t *countp); /** @brief Compare two data items according to a particular database. * * This returns a comparison as if the two data items were keys in the * specified database. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] a The first item to compare * @param[in] b The second item to compare * @return < 0 if a < b, 0 if a == b, > 0 if a > b */ int mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b); /** @brief Compare two data items according to a particular database. * * This returns a comparison as if the two items were data items of * the specified database. The database must have the #MDB_DUPSORT flag. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() * @param[in] a The first item to compare * @param[in] b The second item to compare * @return < 0 if a < b, 0 if a == b, > 0 if a > b */ int mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b); /** @brief A callback function used to print a message from the library. * * @param[in] msg The string to be printed. * @param[in] ctx An arbitrary context pointer for the callback. * @return < 0 on failure, >= 0 on success. */ typedef int (MDB_msg_func)(const char *msg, void *ctx); /** @brief Dump the entries in the reader lock table. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] func A #MDB_msg_func function * @param[in] ctx Anything the message function needs * @return < 0 on failure, >= 0 on success. */ int mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx); /** @brief Check for stale entries in the reader lock table. * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] dead Number of stale slots that were cleared * @return 0 on success, non-zero on failure. */ int mdb_reader_check(MDB_env *env, int *dead); /** @} */ #ifdef __cplusplus } #endif /** @page tools LMDB Command Line Tools The following describes the command line tools that are available for LMDB. \li \ref mdb_copy_1 \li \ref mdb_dump_1 \li \ref mdb_load_1 \li \ref mdb_stat_1 */ #endif /* _LMDB_H_ */ bareos-Release-14.2.6/src/lmdb/mdb.c000066400000000000000000010362701263011562700170640ustar00rootroot00000000000000/** @file mdb.c * @brief Lightning memory-mapped database library * * A Btree-based database management library modeled loosely on the * BerkeleyDB API, but much simplified. */ /* * Copyright 2011-2015 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . * * This code is derived from btree.c written by Martin Hedenfalk. * * Copyright (c) 2009, 2010 Martin Hedenfalk * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #ifdef _WIN32 #include #include /** getpid() returns int; MinGW defines pid_t but MinGW64 typedefs it * as int64 which is wrong. MSVC doesn't define it at all, so just * don't use it. */ #define MDB_PID_T int #define MDB_THR_T DWORD #include #include #ifdef __GNUC__ # include #else # define LITTLE_ENDIAN 1234 # define BIG_ENDIAN 4321 # define BYTE_ORDER LITTLE_ENDIAN # ifndef SSIZE_MAX # define SSIZE_MAX INT_MAX # endif #endif #else #include #include #define MDB_PID_T pid_t #define MDB_THR_T pthread_t #include #include #include #ifdef HAVE_SYS_FILE_H #include #endif #include #endif #if defined(__mips) && defined(__linux) /* MIPS has cache coherency issues, requires explicit cache control */ #include extern int cacheflush(char *addr, int nbytes, int cache); #define CACHEFLUSH(addr, bytes, cache) cacheflush(addr, bytes, cache) #else #define CACHEFLUSH(addr, bytes, cache) #endif #if defined(__linux) && !defined(MDB_FDATASYNC_WORKS) /** fdatasync is broken on ext3/ext4fs on older kernels, see * description in #mdb_env_open2 comments. You can safely * define MDB_FDATASYNC_WORKS if this code will only be run * on kernels 3.6 and newer. */ #define BROKEN_FDATASYNC #endif #include #include #include #include #include #include #include #include #ifdef _MSC_VER #include typedef SSIZE_T ssize_t; #else #include #endif #if defined(__sun) || defined(ANDROID) /* Most platforms have posix_memalign, older may only have memalign */ #define HAVE_MEMALIGN 1 #include #endif #if !(defined(BYTE_ORDER) || defined(__BYTE_ORDER)) #include #include /* defines BYTE_ORDER on HPUX and Solaris */ #endif #if defined(__APPLE__) || defined (BSD) # if !(defined(MDB_USE_POSIX_MUTEX) || defined(MDB_USE_POSIX_SEM)) # define MDB_USE_SYSV_SEM 1 # endif # define MDB_FDATASYNC fsync #elif defined(ANDROID) # define MDB_FDATASYNC fsync #endif #ifndef _WIN32 #include #ifdef MDB_USE_POSIX_SEM # define MDB_USE_HASH 1 #include #elif defined(MDB_USE_SYSV_SEM) #include #include #ifdef _SEM_SEMUN_UNDEFINED union semun { int val; struct semid_ds *buf; unsigned short *array; }; #endif /* _SEM_SEMUN_UNDEFINED */ #else #define MDB_USE_POSIX_MUTEX 1 #endif /* MDB_USE_POSIX_SEM */ #endif /* !_WIN32 */ #if defined(_WIN32) + defined(MDB_USE_POSIX_SEM) + defined(MDB_USE_SYSV_SEM) \ + defined(MDB_USE_POSIX_MUTEX) != 1 # error "Ambiguous shared-lock implementation" #endif #if defined(__SUNPRO_C) #include "mbarrier.h" #endif #ifdef USE_VALGRIND #include #define VGMEMP_CREATE(h,r,z) VALGRIND_CREATE_MEMPOOL(h,r,z) #define VGMEMP_ALLOC(h,a,s) VALGRIND_MEMPOOL_ALLOC(h,a,s) #define VGMEMP_FREE(h,a) VALGRIND_MEMPOOL_FREE(h,a) #define VGMEMP_DESTROY(h) VALGRIND_DESTROY_MEMPOOL(h) #define VGMEMP_DEFINED(a,s) VALGRIND_MAKE_MEM_DEFINED(a,s) #else #define VGMEMP_CREATE(h,r,z) #define VGMEMP_ALLOC(h,a,s) #define VGMEMP_FREE(h,a) #define VGMEMP_DESTROY(h) #define VGMEMP_DEFINED(a,s) #endif #ifndef BYTE_ORDER # if (defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)) /* Solaris just defines one or the other */ # define LITTLE_ENDIAN 1234 # define BIG_ENDIAN 4321 # ifdef _LITTLE_ENDIAN # define BYTE_ORDER LITTLE_ENDIAN # else # define BYTE_ORDER BIG_ENDIAN # endif # else # define BYTE_ORDER __BYTE_ORDER # endif #endif #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN __LITTLE_ENDIAN #endif #ifndef BIG_ENDIAN #define BIG_ENDIAN __BIG_ENDIAN #endif #if defined(__i386) || defined(__x86_64) || defined(_M_IX86) #define MISALIGNED_OK 1 #endif #include "lmdb.h" #include "midl.h" #if (BYTE_ORDER == LITTLE_ENDIAN) == (BYTE_ORDER == BIG_ENDIAN) # error "Unknown or unsupported endianness (BYTE_ORDER)" #elif (-6 & 5) || CHAR_BIT != 8 || UINT_MAX < 0xffffffff || ULONG_MAX % 0xFFFF # error "Two's complement, reasonably sized integer types, please" #endif #ifdef __GNUC__ /** Put infrequently used env functions in separate section */ # ifdef __APPLE__ # define ESECT __attribute__ ((section("__TEXT,text_env"))) # else # define ESECT __attribute__ ((section("text_env"))) # endif #else #define ESECT #endif /** @defgroup internal LMDB Internals * @{ */ /** @defgroup compat Compatibility Macros * A bunch of macros to minimize the amount of platform-specific ifdefs * needed throughout the rest of the code. When the features this library * needs are similar enough to POSIX to be hidden in a one-or-two line * replacement, this macro approach is used. * @{ */ /** Features under development */ #ifndef MDB_DEVEL #define MDB_DEVEL 0 #endif /** Wrapper around __func__, which is a C99 feature */ #if __STDC_VERSION__ >= 199901L # define mdb_func_ __func__ #elif __GNUC__ >= 2 || _MSC_VER >= 1300 # define mdb_func_ __FUNCTION__ #else /* If a debug message says (), update the #if statements above */ # define mdb_func_ "" #endif /* Internal error codes, not exposed outside liblmdb */ #define MDB_NO_ROOT (MDB_LAST_ERRCODE + 10) #ifdef _WIN32 #define MDB_OWNERDEAD ((int) WAIT_ABANDONED) #elif defined MDB_USE_SYSV_SEM #define MDB_OWNERDEAD (MDB_LAST_ERRCODE + 11) #elif defined(MDB_USE_POSIX_MUTEX) && defined(EOWNERDEAD) && defined(PTHREAD_MUTEX_ROBUST) #define MDB_OWNERDEAD EOWNERDEAD /**< #LOCK_MUTEX0() result if dead owner */ #endif #ifdef MDB_OWNERDEAD #define MDB_ROBUST_SUPPORTED 1 #endif #ifdef _WIN32 #define MDB_USE_HASH 1 #define MDB_PIDLOCK 0 #define THREAD_RET DWORD #define pthread_t HANDLE #define pthread_mutex_t HANDLE #define pthread_cond_t HANDLE typedef HANDLE mdb_mutex_t, mdb_mutexref_t; #define pthread_key_t DWORD #define pthread_self() GetCurrentThreadId() #define pthread_key_create(x,y) \ ((*(x) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? ErrCode() : 0) #define pthread_key_delete(x) TlsFree(x) #define pthread_getspecific(x) TlsGetValue(x) #define pthread_setspecific(x,y) (TlsSetValue(x,y) ? 0 : ErrCode()) #define pthread_mutex_unlock(x) ReleaseMutex(*x) #define pthread_mutex_lock(x) WaitForSingleObject(*x, INFINITE) #define pthread_cond_signal(x) SetEvent(*x) #define pthread_cond_wait(cond,mutex) do{SignalObjectAndWait(*mutex, *cond, INFINITE, FALSE); WaitForSingleObject(*mutex, INFINITE);}while(0) #define THREAD_CREATE(thr,start,arg) thr=CreateThread(NULL,0,start,arg,0,NULL) #define THREAD_FINISH(thr) WaitForSingleObject(thr, INFINITE) #define LOCK_MUTEX0(mutex) WaitForSingleObject(mutex, INFINITE) #define UNLOCK_MUTEX(mutex) ReleaseMutex(mutex) #define mdb_mutex_consistent(mutex) 0 #define getpid() GetCurrentProcessId() #define MDB_FDATASYNC(fd) (!FlushFileBuffers(fd)) #define MDB_MSYNC(addr,len,flags) (!FlushViewOfFile(addr,len)) #define ErrCode() GetLastError() #define GET_PAGESIZE(x) {SYSTEM_INFO si; GetSystemInfo(&si); (x) = si.dwPageSize;} #define close(fd) (CloseHandle(fd) ? 0 : -1) #define munmap(ptr,len) UnmapViewOfFile(ptr) #ifdef PROCESS_QUERY_LIMITED_INFORMATION #define MDB_PROCESS_QUERY_LIMITED_INFORMATION PROCESS_QUERY_LIMITED_INFORMATION #else #define MDB_PROCESS_QUERY_LIMITED_INFORMATION 0x1000 #endif #define Z "I" #else #define THREAD_RET void * #define THREAD_CREATE(thr,start,arg) pthread_create(&thr,NULL,start,arg) #define THREAD_FINISH(thr) pthread_join(thr,NULL) #define Z "z" /**< printf format modifier for size_t */ /** For MDB_LOCK_FORMAT: True if readers take a pid lock in the lockfile */ #define MDB_PIDLOCK 1 #ifdef MDB_USE_POSIX_SEM typedef sem_t *mdb_mutex_t, *mdb_mutexref_t; #define LOCK_MUTEX0(mutex) mdb_sem_wait(mutex) #define UNLOCK_MUTEX(mutex) sem_post(mutex) static int mdb_sem_wait(sem_t *sem) { int rc; while ((rc = sem_wait(sem)) && (rc = errno) == EINTR) ; return rc; } #elif defined MDB_USE_SYSV_SEM typedef struct mdb_mutex { int semid; int semnum; int *locked; } mdb_mutex_t[1], *mdb_mutexref_t; #define LOCK_MUTEX0(mutex) mdb_sem_wait(mutex) #define UNLOCK_MUTEX(mutex) do { \ struct sembuf sb = { 0, 1, SEM_UNDO }; \ sb.sem_num = (mutex)->semnum; \ *(mutex)->locked = 0; \ semop((mutex)->semid, &sb, 1); \ } while(0) static int mdb_sem_wait(mdb_mutexref_t sem) { int rc, *locked = sem->locked; struct sembuf sb = { 0, -1, SEM_UNDO }; sb.sem_num = sem->semnum; do { if (!semop(sem->semid, &sb, 1)) { rc = *locked ? MDB_OWNERDEAD : MDB_SUCCESS; *locked = 1; break; } } while ((rc = errno) == EINTR); return rc; } #define mdb_mutex_consistent(mutex) 0 #else /* MDB_USE_POSIX_MUTEX: */ /** Shared mutex/semaphore as it is stored (mdb_mutex_t), and as * local variables keep it (mdb_mutexref_t). * * An mdb_mutex_t can be assigned to an mdb_mutexref_t. They can * be the same, or an array[size 1] and a pointer. * @{ */ typedef pthread_mutex_t mdb_mutex_t[1], *mdb_mutexref_t; /* @} */ /** Lock the reader or writer mutex. * Returns 0 or a code to give #mdb_mutex_failed(), as in #LOCK_MUTEX(). */ #define LOCK_MUTEX0(mutex) pthread_mutex_lock(mutex) /** Unlock the reader or writer mutex. */ #define UNLOCK_MUTEX(mutex) pthread_mutex_unlock(mutex) /** Mark mutex-protected data as repaired, after death of previous owner. */ #define mdb_mutex_consistent(mutex) pthread_mutex_consistent(mutex) #endif /* MDB_USE_POSIX_SEM || MDB_USE_SYSV_SEM */ /** Get the error code for the last failed system function. */ #define ErrCode() errno /** An abstraction for a file handle. * On POSIX systems file handles are small integers. On Windows * they're opaque pointers. */ #define HANDLE int /** A value for an invalid file handle. * Mainly used to initialize file variables and signify that they are * unused. */ #define INVALID_HANDLE_VALUE (-1) /** Get the size of a memory page for the system. * This is the basic size that the platform's memory manager uses, and is * fundamental to the use of memory-mapped files. */ #define GET_PAGESIZE(x) ((x) = sysconf(_SC_PAGE_SIZE)) #endif #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) #define MNAME_LEN 32 #elif defined(MDB_USE_SYSV_SEM) #define MNAME_LEN (sizeof(int)) #else #define MNAME_LEN (sizeof(pthread_mutex_t)) #endif #ifdef MDB_USE_SYSV_SEM #define SYSV_SEM_FLAG 1 /**< SysV sems in lockfile format */ #else #define SYSV_SEM_FLAG 0 #endif /** @} */ #ifdef MDB_ROBUST_SUPPORTED /** Lock mutex, handle any error, set rc = result. * Return 0 on success, nonzero (not rc) on error. */ #define LOCK_MUTEX(rc, env, mutex) \ (((rc) = LOCK_MUTEX0(mutex)) && \ ((rc) = mdb_mutex_failed(env, mutex, rc))) static int mdb_mutex_failed(MDB_env *env, mdb_mutexref_t mutex, int rc); #else #define LOCK_MUTEX(rc, env, mutex) ((rc) = LOCK_MUTEX0(mutex)) #define mdb_mutex_failed(env, mutex, rc) (rc) #endif #ifndef _WIN32 /** A flag for opening a file and requesting synchronous data writes. * This is only used when writing a meta page. It's not strictly needed; * we could just do a normal write and then immediately perform a flush. * But if this flag is available it saves us an extra system call. * * @note If O_DSYNC is undefined but exists in /usr/include, * preferably set some compiler flag to get the definition. * Otherwise compile with the less efficient -DMDB_DSYNC=O_SYNC. */ #ifndef MDB_DSYNC # define MDB_DSYNC O_DSYNC #endif #endif /** Function for flushing the data of a file. Define this to fsync * if fdatasync() is not supported. */ #ifndef MDB_FDATASYNC # define MDB_FDATASYNC fdatasync #endif #ifndef MDB_MSYNC # define MDB_MSYNC(addr,len,flags) msync(addr,len,flags) #endif #ifndef MS_SYNC #define MS_SYNC 1 #endif #ifndef MS_ASYNC #define MS_ASYNC 0 #endif /** A page number in the database. * Note that 64 bit page numbers are overkill, since pages themselves * already represent 12-13 bits of addressable memory, and the OS will * always limit applications to a maximum of 63 bits of address space. * * @note In the #MDB_node structure, we only store 48 bits of this value, * which thus limits us to only 60 bits of addressable data. */ typedef MDB_ID pgno_t; /** A transaction ID. * See struct MDB_txn.mt_txnid for details. */ typedef MDB_ID txnid_t; /** @defgroup debug Debug Macros * @{ */ #ifndef MDB_DEBUG /** Enable debug output. Needs variable argument macros (a C99 feature). * Set this to 1 for copious tracing. Set to 2 to add dumps of all IDLs * read from and written to the database (used for free space management). */ #define MDB_DEBUG 0 #endif #if MDB_DEBUG static int mdb_debug; static txnid_t mdb_debug_start; /** Print a debug message with printf formatting. * Requires double parenthesis around 2 or more args. */ # define DPRINTF(args) ((void) ((mdb_debug) && DPRINTF0 args)) # define DPRINTF0(fmt, ...) \ fprintf(stderr, "%s:%d " fmt "\n", mdb_func_, __LINE__, __VA_ARGS__) #else # define DPRINTF(args) ((void) 0) #endif /** Print a debug string. * The string is printed literally, with no format processing. */ #define DPUTS(arg) DPRINTF(("%s", arg)) /** Debuging output value of a cursor DBI: Negative in a sub-cursor. */ #define DDBI(mc) \ (((mc)->mc_flags & C_SUB) ? -(int)(mc)->mc_dbi : (int)(mc)->mc_dbi) /** @} */ /** @brief The maximum size of a database page. * * It is 32k or 64k, since value-PAGEBASE must fit in * #MDB_page.%mp_upper. * * LMDB will use database pages < OS pages if needed. * That causes more I/O in write transactions: The OS must * know (read) the whole page before writing a partial page. * * Note that we don't currently support Huge pages. On Linux, * regular data files cannot use Huge pages, and in general * Huge pages aren't actually pageable. We rely on the OS * demand-pager to read our data and page it out when memory * pressure from other processes is high. So until OSs have * actual paging support for Huge pages, they're not viable. */ #define MAX_PAGESIZE (PAGEBASE ? 0x10000 : 0x8000) /** The minimum number of keys required in a database page. * Setting this to a larger value will place a smaller bound on the * maximum size of a data item. Data items larger than this size will * be pushed into overflow pages instead of being stored directly in * the B-tree node. This value used to default to 4. With a page size * of 4096 bytes that meant that any item larger than 1024 bytes would * go into an overflow page. That also meant that on average 2-3KB of * each overflow page was wasted space. The value cannot be lower than * 2 because then there would no longer be a tree structure. With this * value, items larger than 2KB will go into overflow pages, and on * average only 1KB will be wasted. */ #define MDB_MINKEYS 2 /** A stamp that identifies a file as an LMDB file. * There's nothing special about this value other than that it is easily * recognizable, and it will reflect any byte order mismatches. */ #define MDB_MAGIC 0xBEEFC0DE /** The version number for a database's datafile format. */ #define MDB_DATA_VERSION ((MDB_DEVEL) ? 999 : 1) /** The version number for a database's lockfile format. */ #define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 1) /** @brief The max size of a key we can write, or 0 for computed max. * * This macro should normally be left alone or set to 0. * Note that a database with big keys or dupsort data cannot be * reliably modified by a liblmdb which uses a smaller max. * The default is 511 for backwards compat, or 0 when #MDB_DEVEL. * * Other values are allowed, for backwards compat. However: * A value bigger than the computed max can break if you do not * know what you are doing, and liblmdb <= 0.9.10 can break when * modifying a DB with keys/dupsort data bigger than its max. * * Data items in an #MDB_DUPSORT database are also limited to * this size, since they're actually keys of a sub-DB. Keys and * #MDB_DUPSORT data items must fit on a node in a regular page. */ #ifndef MDB_MAXKEYSIZE #define MDB_MAXKEYSIZE ((MDB_DEVEL) ? 0 : 511) #endif /** The maximum size of a key we can write to the environment. */ #if MDB_MAXKEYSIZE #define ENV_MAXKEY(env) (MDB_MAXKEYSIZE) #else #define ENV_MAXKEY(env) ((env)->me_maxkey) #endif /** @brief The maximum size of a data item. * * We only store a 32 bit value for node sizes. */ #define MAXDATASIZE 0xffffffffUL #if MDB_DEBUG /** Key size which fits in a #DKBUF. * @ingroup debug */ #define DKBUF_MAXKEYSIZE ((MDB_MAXKEYSIZE) > 0 ? (MDB_MAXKEYSIZE) : 511) /** A key buffer. * @ingroup debug * This is used for printing a hex dump of a key's contents. */ #define DKBUF char kbuf[DKBUF_MAXKEYSIZE*2+1] /** Display a key in hex. * @ingroup debug * Invoke a function to display a key in hex. */ #define DKEY(x) mdb_dkey(x, kbuf) #else #define DKBUF #define DKEY(x) 0 #endif /** An invalid page number. * Mainly used to denote an empty tree. */ #define P_INVALID (~(pgno_t)0) /** Test if the flags \b f are set in a flag word \b w. */ #define F_ISSET(w, f) (((w) & (f)) == (f)) /** Round \b n up to an even number. */ #define EVEN(n) (((n) + 1U) & -2) /* sign-extending -2 to match n+1U */ /** Used for offsets within a single page. * Since memory pages are typically 4 or 8KB in size, 12-13 bits, * this is plenty. */ typedef uint16_t indx_t; /** Default size of memory map. * This is certainly too small for any actual applications. Apps should always set * the size explicitly using #mdb_env_set_mapsize(). */ #define DEFAULT_MAPSIZE 1048576 /** @defgroup readers Reader Lock Table * Readers don't acquire any locks for their data access. Instead, they * simply record their transaction ID in the reader table. The reader * mutex is needed just to find an empty slot in the reader table. The * slot's address is saved in thread-specific data so that subsequent read * transactions started by the same thread need no further locking to proceed. * * If #MDB_NOTLS is set, the slot address is not saved in thread-specific data. * * No reader table is used if the database is on a read-only filesystem, or * if #MDB_NOLOCK is set. * * Since the database uses multi-version concurrency control, readers don't * actually need any locking. This table is used to keep track of which * readers are using data from which old transactions, so that we'll know * when a particular old transaction is no longer in use. Old transactions * that have discarded any data pages can then have those pages reclaimed * for use by a later write transaction. * * The lock table is constructed such that reader slots are aligned with the * processor's cache line size. Any slot is only ever used by one thread. * This alignment guarantees that there will be no contention or cache * thrashing as threads update their own slot info, and also eliminates * any need for locking when accessing a slot. * * A writer thread will scan every slot in the table to determine the oldest * outstanding reader transaction. Any freed pages older than this will be * reclaimed by the writer. The writer doesn't use any locks when scanning * this table. This means that there's no guarantee that the writer will * see the most up-to-date reader info, but that's not required for correct * operation - all we need is to know the upper bound on the oldest reader, * we don't care at all about the newest reader. So the only consequence of * reading stale information here is that old pages might hang around a * while longer before being reclaimed. That's actually good anyway, because * the longer we delay reclaiming old pages, the more likely it is that a * string of contiguous pages can be found after coalescing old pages from * many old transactions together. * @{ */ /** Number of slots in the reader table. * This value was chosen somewhat arbitrarily. 126 readers plus a * couple mutexes fit exactly into 8KB on my development machine. * Applications should set the table size using #mdb_env_set_maxreaders(). */ #define DEFAULT_READERS 126 /** The size of a CPU cache line in bytes. We want our lock structures * aligned to this size to avoid false cache line sharing in the * lock table. * This value works for most CPUs. For Itanium this should be 128. */ #ifndef CACHELINE #define CACHELINE 64 #endif /** The information we store in a single slot of the reader table. * In addition to a transaction ID, we also record the process and * thread ID that owns a slot, so that we can detect stale information, * e.g. threads or processes that went away without cleaning up. * @note We currently don't check for stale records. We simply re-init * the table when we know that we're the only process opening the * lock file. */ typedef struct MDB_rxbody { /** Current Transaction ID when this transaction began, or (txnid_t)-1. * Multiple readers that start at the same time will probably have the * same ID here. Again, it's not important to exclude them from * anything; all we need to know is which version of the DB they * started from so we can avoid overwriting any data used in that * particular version. */ volatile txnid_t mrb_txnid; /** The process ID of the process owning this reader txn. */ volatile MDB_PID_T mrb_pid; /** The thread ID of the thread owning this txn. */ volatile MDB_THR_T mrb_tid; } MDB_rxbody; /** The actual reader record, with cacheline padding. */ typedef struct MDB_reader { union { MDB_rxbody mrx; /** shorthand for mrb_txnid */ #define mr_txnid mru.mrx.mrb_txnid #define mr_pid mru.mrx.mrb_pid #define mr_tid mru.mrx.mrb_tid /** cache line alignment */ char pad[(sizeof(MDB_rxbody)+CACHELINE-1) & ~(CACHELINE-1)]; } mru; } MDB_reader; /** The header for the reader table. * The table resides in a memory-mapped file. (This is a different file * than is used for the main database.) * * For POSIX the actual mutexes reside in the shared memory of this * mapped file. On Windows, mutexes are named objects allocated by the * kernel; we store the mutex names in this mapped file so that other * processes can grab them. This same approach is also used on * MacOSX/Darwin (using named semaphores) since MacOSX doesn't support * process-shared POSIX mutexes. For these cases where a named object * is used, the object name is derived from a 64 bit FNV hash of the * environment pathname. As such, naming collisions are extremely * unlikely. If a collision occurs, the results are unpredictable. */ typedef struct MDB_txbody { /** Stamp identifying this as an LMDB file. It must be set * to #MDB_MAGIC. */ uint32_t mtb_magic; /** Format of this lock file. Must be set to #MDB_LOCK_FORMAT. */ uint32_t mtb_format; #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) char mtb_rmname[MNAME_LEN]; #elif defined(MDB_USE_SYSV_SEM) int mtb_semid; int mtb_rlocked; #else /** Mutex protecting access to this table. * This is the reader table lock used with LOCK_MUTEX(). */ mdb_mutex_t mtb_rmutex; #endif /** The ID of the last transaction committed to the database. * This is recorded here only for convenience; the value can always * be determined by reading the main database meta pages. */ volatile txnid_t mtb_txnid; /** The number of slots that have been used in the reader table. * This always records the maximum count, it is not decremented * when readers release their slots. */ volatile unsigned mtb_numreaders; } MDB_txbody; /** The actual reader table definition. */ typedef struct MDB_txninfo { union { MDB_txbody mtb; #define mti_magic mt1.mtb.mtb_magic #define mti_format mt1.mtb.mtb_format #define mti_rmutex mt1.mtb.mtb_rmutex #define mti_rmname mt1.mtb.mtb_rmname #define mti_txnid mt1.mtb.mtb_txnid #define mti_numreaders mt1.mtb.mtb_numreaders #ifdef MDB_USE_SYSV_SEM #define mti_semid mt1.mtb.mtb_semid #define mti_rlocked mt1.mtb.mtb_rlocked #endif char pad[(sizeof(MDB_txbody)+CACHELINE-1) & ~(CACHELINE-1)]; } mt1; union { #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) char mt2_wmname[MNAME_LEN]; #define mti_wmname mt2.mt2_wmname #elif defined MDB_USE_SYSV_SEM int mt2_wlocked; #define mti_wlocked mt2.mt2_wlocked #else mdb_mutex_t mt2_wmutex; #define mti_wmutex mt2.mt2_wmutex #endif char pad[(MNAME_LEN+CACHELINE-1) & ~(CACHELINE-1)]; } mt2; MDB_reader mti_readers[1]; } MDB_txninfo; /** Lockfile format signature: version, features and field layout */ #define MDB_LOCK_FORMAT \ ((uint32_t) \ ((MDB_LOCK_VERSION) \ /* Flags which describe functionality */ \ + (SYSV_SEM_FLAG << 18) \ + (((MDB_PIDLOCK) != 0) << 16))) /** @} */ /** Common header for all page types. * Overflow records occupy a number of contiguous pages with no * headers on any page after the first. */ typedef struct MDB_page { #define mp_pgno mp_p.p_pgno #define mp_next mp_p.p_next union { pgno_t p_pgno; /**< page number */ struct MDB_page *p_next; /**< for in-memory list of freed pages */ } mp_p; uint16_t mp_pad; /** @defgroup mdb_page Page Flags * @ingroup internal * Flags for the page headers. * @{ */ #define P_BRANCH 0x01 /**< branch page */ #define P_LEAF 0x02 /**< leaf page */ #define P_OVERFLOW 0x04 /**< overflow page */ #define P_META 0x08 /**< meta page */ #define P_DIRTY 0x10 /**< dirty page, also set for #P_SUBP pages */ #define P_LEAF2 0x20 /**< for #MDB_DUPFIXED records */ #define P_SUBP 0x40 /**< for #MDB_DUPSORT sub-pages */ #define P_LOOSE 0x4000 /**< page was dirtied then freed, can be reused */ #define P_KEEP 0x8000 /**< leave this page alone during spill */ /** @} */ uint16_t mp_flags; /**< @ref mdb_page */ #define mp_lower mp_pb.pb.pb_lower #define mp_upper mp_pb.pb.pb_upper #define mp_pages mp_pb.pb_pages union { struct { indx_t pb_lower; /**< lower bound of free space */ indx_t pb_upper; /**< upper bound of free space */ } pb; uint32_t pb_pages; /**< number of overflow pages */ } mp_pb; indx_t mp_ptrs[1]; /**< dynamic size */ } MDB_page; /** Size of the page header, excluding dynamic data at the end */ #define PAGEHDRSZ ((unsigned) offsetof(MDB_page, mp_ptrs)) /** Address of first usable data byte in a page, after the header */ #define METADATA(p) ((void *)((char *)(p) + PAGEHDRSZ)) /** ITS#7713, change PAGEBASE to handle 65536 byte pages */ #define PAGEBASE ((MDB_DEVEL) ? PAGEHDRSZ : 0) /** Number of nodes on a page */ #define NUMKEYS(p) (((p)->mp_lower - (PAGEHDRSZ-PAGEBASE)) >> 1) /** The amount of space remaining in the page */ #define SIZELEFT(p) (indx_t)((p)->mp_upper - (p)->mp_lower) /** The percentage of space used in the page, in tenths of a percent. */ #define PAGEFILL(env, p) (1000L * ((env)->me_psize - PAGEHDRSZ - SIZELEFT(p)) / \ ((env)->me_psize - PAGEHDRSZ)) /** The minimum page fill factor, in tenths of a percent. * Pages emptier than this are candidates for merging. */ #define FILL_THRESHOLD 250 /** Test if a page is a leaf page */ #define IS_LEAF(p) F_ISSET((p)->mp_flags, P_LEAF) /** Test if a page is a LEAF2 page */ #define IS_LEAF2(p) F_ISSET((p)->mp_flags, P_LEAF2) /** Test if a page is a branch page */ #define IS_BRANCH(p) F_ISSET((p)->mp_flags, P_BRANCH) /** Test if a page is an overflow page */ #define IS_OVERFLOW(p) F_ISSET((p)->mp_flags, P_OVERFLOW) /** Test if a page is a sub page */ #define IS_SUBP(p) F_ISSET((p)->mp_flags, P_SUBP) /** The number of overflow pages needed to store the given size. */ #define OVPAGES(size, psize) ((PAGEHDRSZ-1 + (size)) / (psize) + 1) /** Link in #MDB_txn.%mt_loose_pgs list */ #define NEXT_LOOSE_PAGE(p) (*(MDB_page **)((p) + 2)) /** Header for a single key/data pair within a page. * Used in pages of type #P_BRANCH and #P_LEAF without #P_LEAF2. * We guarantee 2-byte alignment for 'MDB_node's. */ typedef struct MDB_node { /** lo and hi are used for data size on leaf nodes and for * child pgno on branch nodes. On 64 bit platforms, flags * is also used for pgno. (Branch nodes have no flags). * They are in host byte order in case that lets some * accesses be optimized into a 32-bit word access. */ #if BYTE_ORDER == LITTLE_ENDIAN unsigned short mn_lo, mn_hi; /**< part of data size or pgno */ #else unsigned short mn_hi, mn_lo; #endif /** @defgroup mdb_node Node Flags * @ingroup internal * Flags for node headers. * @{ */ #define F_BIGDATA 0x01 /**< data put on overflow page */ #define F_SUBDATA 0x02 /**< data is a sub-database */ #define F_DUPDATA 0x04 /**< data has duplicates */ /** valid flags for #mdb_node_add() */ #define NODE_ADD_FLAGS (F_DUPDATA|F_SUBDATA|MDB_RESERVE|MDB_APPEND) /** @} */ unsigned short mn_flags; /**< @ref mdb_node */ unsigned short mn_ksize; /**< key size */ char mn_data[1]; /**< key and data are appended here */ } MDB_node; /** Size of the node header, excluding dynamic data at the end */ #define NODESIZE offsetof(MDB_node, mn_data) /** Bit position of top word in page number, for shifting mn_flags */ #define PGNO_TOPWORD ((pgno_t)-1 > 0xffffffffu ? 32 : 0) /** Size of a node in a branch page with a given key. * This is just the node header plus the key, there is no data. */ #define INDXSIZE(k) (NODESIZE + ((k) == NULL ? 0 : (k)->mv_size)) /** Size of a node in a leaf page with a given key and data. * This is node header plus key plus data size. */ #define LEAFSIZE(k, d) (NODESIZE + (k)->mv_size + (d)->mv_size) /** Address of node \b i in page \b p */ #define NODEPTR(p, i) ((MDB_node *)((char *)(p) + (p)->mp_ptrs[i] + PAGEBASE)) /** Address of the key for the node */ #define NODEKEY(node) (void *)((node)->mn_data) /** Address of the data for a node */ #define NODEDATA(node) (void *)((char *)(node)->mn_data + (node)->mn_ksize) /** Get the page number pointed to by a branch node */ #define NODEPGNO(node) \ ((node)->mn_lo | ((pgno_t) (node)->mn_hi << 16) | \ (PGNO_TOPWORD ? ((pgno_t) (node)->mn_flags << PGNO_TOPWORD) : 0)) /** Set the page number in a branch node */ #define SETPGNO(node,pgno) do { \ (node)->mn_lo = (pgno) & 0xffff; (node)->mn_hi = (pgno) >> 16; \ if (PGNO_TOPWORD) (node)->mn_flags = (pgno) >> PGNO_TOPWORD; } while(0) /** Get the size of the data in a leaf node */ #define NODEDSZ(node) ((node)->mn_lo | ((unsigned)(node)->mn_hi << 16)) /** Set the size of the data for a leaf node */ #define SETDSZ(node,size) do { \ (node)->mn_lo = (size) & 0xffff; (node)->mn_hi = (size) >> 16;} while(0) /** The size of a key in a node */ #define NODEKSZ(node) ((node)->mn_ksize) /** Copy a page number from src to dst */ #ifdef MISALIGNED_OK #define COPY_PGNO(dst,src) dst = src #else #if SIZE_MAX > 4294967295UL #define COPY_PGNO(dst,src) do { \ unsigned short *s, *d; \ s = (unsigned short *)&(src); \ d = (unsigned short *)&(dst); \ *d++ = *s++; \ *d++ = *s++; \ *d++ = *s++; \ *d = *s; \ } while (0) #else #define COPY_PGNO(dst,src) do { \ unsigned short *s, *d; \ s = (unsigned short *)&(src); \ d = (unsigned short *)&(dst); \ *d++ = *s++; \ *d = *s; \ } while (0) #endif #endif /** The address of a key in a LEAF2 page. * LEAF2 pages are used for #MDB_DUPFIXED sorted-duplicate sub-DBs. * There are no node headers, keys are stored contiguously. */ #define LEAF2KEY(p, i, ks) ((char *)(p) + PAGEHDRSZ + ((i)*(ks))) /** Set the \b node's key into \b keyptr, if requested. */ #define MDB_GET_KEY(node, keyptr) { if ((keyptr) != NULL) { \ (keyptr)->mv_size = NODEKSZ(node); (keyptr)->mv_data = NODEKEY(node); } } /** Set the \b node's key into \b key. */ #define MDB_GET_KEY2(node, key) { key.mv_size = NODEKSZ(node); key.mv_data = NODEKEY(node); } /** Information about a single database in the environment. */ typedef struct MDB_db { uint32_t md_pad; /**< also ksize for LEAF2 pages */ uint16_t md_flags; /**< @ref mdb_dbi_open */ uint16_t md_depth; /**< depth of this tree */ pgno_t md_branch_pages; /**< number of internal pages */ pgno_t md_leaf_pages; /**< number of leaf pages */ pgno_t md_overflow_pages; /**< number of overflow pages */ size_t md_entries; /**< number of data items */ pgno_t md_root; /**< the root page of this tree */ } MDB_db; /** mdb_dbi_open flags */ #define MDB_VALID 0x8000 /**< DB handle is valid, for me_dbflags */ #define PERSISTENT_FLAGS (0xffff & ~(MDB_VALID)) #define VALID_FLAGS (MDB_REVERSEKEY|MDB_DUPSORT|MDB_INTEGERKEY|MDB_DUPFIXED|\ MDB_INTEGERDUP|MDB_REVERSEDUP|MDB_CREATE) /** Handle for the DB used to track free pages. */ #define FREE_DBI 0 /** Handle for the default DB. */ #define MAIN_DBI 1 /** Number of DBs in metapage (free and main) - also hardcoded elsewhere */ #define CORE_DBS 2 /** Number of meta pages - also hardcoded elsewhere */ #define NUM_METAS 2 /** Meta page content. * A meta page is the start point for accessing a database snapshot. * Pages 0-1 are meta pages. Transaction N writes meta page #(N % 2). */ typedef struct MDB_meta { /** Stamp identifying this as an LMDB file. It must be set * to #MDB_MAGIC. */ uint32_t mm_magic; /** Version number of this file. Must be set to #MDB_DATA_VERSION. */ uint32_t mm_version; void *mm_address; /**< address for fixed mapping */ size_t mm_mapsize; /**< size of mmap region */ MDB_db mm_dbs[CORE_DBS]; /**< first is free space, 2nd is main db */ /** The size of pages used in this DB */ #define mm_psize mm_dbs[FREE_DBI].md_pad /** Any persistent environment flags. @ref mdb_env */ #define mm_flags mm_dbs[FREE_DBI].md_flags pgno_t mm_last_pg; /**< last used page in file */ volatile txnid_t mm_txnid; /**< txnid that committed this page */ } MDB_meta; /** Buffer for a stack-allocated meta page. * The members define size and alignment, and silence type * aliasing warnings. They are not used directly; that could * mean incorrectly using several union members in parallel. */ typedef union MDB_metabuf { MDB_page mb_page; struct { char mm_pad[PAGEHDRSZ]; MDB_meta mm_meta; } mb_metabuf; } MDB_metabuf; /** Auxiliary DB info. * The information here is mostly static/read-only. There is * only a single copy of this record in the environment. */ typedef struct MDB_dbx { MDB_val md_name; /**< name of the database */ MDB_cmp_func *md_cmp; /**< function for comparing keys */ MDB_cmp_func *md_dcmp; /**< function for comparing data items */ MDB_rel_func *md_rel; /**< user relocate function */ void *md_relctx; /**< user-provided context for md_rel */ } MDB_dbx; /** A database transaction. * Every operation requires a transaction handle. */ struct MDB_txn { MDB_txn *mt_parent; /**< parent of a nested txn */ /** Nested txn under this txn, set together with flag #MDB_TXN_HAS_CHILD */ MDB_txn *mt_child; pgno_t mt_next_pgno; /**< next unallocated page */ /** The ID of this transaction. IDs are integers incrementing from 1. * Only committed write transactions increment the ID. If a transaction * aborts, the ID may be re-used by the next writer. */ txnid_t mt_txnid; MDB_env *mt_env; /**< the DB environment */ /** The list of pages that became unused during this transaction. */ MDB_IDL mt_free_pgs; /** The list of loose pages that became unused and may be reused * in this transaction, linked through #NEXT_LOOSE_PAGE(page). */ MDB_page *mt_loose_pgs; /* #Number of loose pages (#mt_loose_pgs) */ int mt_loose_count; /** The sorted list of dirty pages we temporarily wrote to disk * because the dirty list was full. page numbers in here are * shifted left by 1, deleted slots have the LSB set. */ MDB_IDL mt_spill_pgs; union { /** For write txns: Modified pages. Sorted when not MDB_WRITEMAP. */ MDB_ID2L dirty_list; /** For read txns: This thread/txn's reader table slot, or NULL. */ MDB_reader *reader; } mt_u; /** Array of records for each DB known in the environment. */ MDB_dbx *mt_dbxs; /** Array of MDB_db records for each known DB */ MDB_db *mt_dbs; /** Array of sequence numbers for each DB handle */ unsigned int *mt_dbiseqs; /** @defgroup mt_dbflag Transaction DB Flags * @ingroup internal * @{ */ #define DB_DIRTY 0x01 /**< DB was modified or is DUPSORT data */ #define DB_STALE 0x02 /**< Named-DB record is older than txnID */ #define DB_NEW 0x04 /**< Named-DB handle opened in this txn */ #define DB_VALID 0x08 /**< DB handle is valid, see also #MDB_VALID */ #define DB_USRVALID 0x10 /**< As #DB_VALID, but not set for #FREE_DBI */ /** @} */ /** In write txns, array of cursors for each DB */ MDB_cursor **mt_cursors; /** Array of flags for each DB */ unsigned char *mt_dbflags; /** Number of DB records in use, or 0 when the txn is finished. * This number only ever increments until the txn finishes; we * don't decrement it when individual DB handles are closed. */ MDB_dbi mt_numdbs; /** @defgroup mdb_txn Transaction Flags * @ingroup internal * @{ */ /** #mdb_txn_begin() flags */ #define MDB_TXN_BEGIN_FLAGS (MDB_NOMETASYNC|MDB_NOSYNC|MDB_RDONLY) #define MDB_TXN_NOMETASYNC MDB_NOMETASYNC /**< don't sync meta for this txn on commit */ #define MDB_TXN_NOSYNC MDB_NOSYNC /**< don't sync this txn on commit */ #define MDB_TXN_RDONLY MDB_RDONLY /**< read-only transaction */ /* internal txn flags */ #define MDB_TXN_WRITEMAP MDB_WRITEMAP /**< copy of #MDB_env flag in writers */ #define MDB_TXN_FINISHED 0x01 /**< txn is finished or never began */ #define MDB_TXN_ERROR 0x02 /**< txn is unusable after an error */ #define MDB_TXN_DIRTY 0x04 /**< must write, even if dirty list is empty */ #define MDB_TXN_SPILLS 0x08 /**< txn or a parent has spilled pages */ #define MDB_TXN_HAS_CHILD 0x10 /**< txn has an #MDB_txn.%mt_child */ /** most operations on the txn are currently illegal */ #define MDB_TXN_BLOCKED (MDB_TXN_FINISHED|MDB_TXN_ERROR|MDB_TXN_HAS_CHILD) /** @} */ unsigned int mt_flags; /**< @ref mdb_txn */ /** #dirty_list room: Array size - \#dirty pages visible to this txn. * Includes ancestor txns' dirty pages not hidden by other txns' * dirty/spilled pages. Thus commit(nested txn) has room to merge * dirty_list into mt_parent after freeing hidden mt_parent pages. */ unsigned int mt_dirty_room; }; /** Enough space for 2^32 nodes with minimum of 2 keys per node. I.e., plenty. * At 4 keys per node, enough for 2^64 nodes, so there's probably no need to * raise this on a 64 bit machine. */ #define CURSOR_STACK 32 struct MDB_xcursor; /** Cursors are used for all DB operations. * A cursor holds a path of (page pointer, key index) from the DB * root to a position in the DB, plus other state. #MDB_DUPSORT * cursors include an xcursor to the current data item. Write txns * track their cursors and keep them up to date when data moves. * Exception: An xcursor's pointer to a #P_SUBP page can be stale. * (A node with #F_DUPDATA but no #F_SUBDATA contains a subpage). */ struct MDB_cursor { /** Next cursor on this DB in this txn */ MDB_cursor *mc_next; /** Backup of the original cursor if this cursor is a shadow */ MDB_cursor *mc_backup; /** Context used for databases with #MDB_DUPSORT, otherwise NULL */ struct MDB_xcursor *mc_xcursor; /** The transaction that owns this cursor */ MDB_txn *mc_txn; /** The database handle this cursor operates on */ MDB_dbi mc_dbi; /** The database record for this cursor */ MDB_db *mc_db; /** The database auxiliary record for this cursor */ MDB_dbx *mc_dbx; /** The @ref mt_dbflag for this database */ unsigned char *mc_dbflag; unsigned short mc_snum; /**< number of pushed pages */ unsigned short mc_top; /**< index of top page, normally mc_snum-1 */ /** @defgroup mdb_cursor Cursor Flags * @ingroup internal * Cursor state flags. * @{ */ #define C_INITIALIZED 0x01 /**< cursor has been initialized and is valid */ #define C_EOF 0x02 /**< No more data */ #define C_SUB 0x04 /**< Cursor is a sub-cursor */ #define C_DEL 0x08 /**< last op was a cursor_del */ #define C_SPLITTING 0x20 /**< Cursor is in page_split */ #define C_UNTRACK 0x40 /**< Un-track cursor when closing */ /** @} */ unsigned int mc_flags; /**< @ref mdb_cursor */ MDB_page *mc_pg[CURSOR_STACK]; /**< stack of pushed pages */ indx_t mc_ki[CURSOR_STACK]; /**< stack of page indices */ }; /** Context for sorted-dup records. * We could have gone to a fully recursive design, with arbitrarily * deep nesting of sub-databases. But for now we only handle these * levels - main DB, optional sub-DB, sorted-duplicate DB. */ typedef struct MDB_xcursor { /** A sub-cursor for traversing the Dup DB */ MDB_cursor mx_cursor; /** The database record for this Dup DB */ MDB_db mx_db; /** The auxiliary DB record for this Dup DB */ MDB_dbx mx_dbx; /** The @ref mt_dbflag for this Dup DB */ unsigned char mx_dbflag; } MDB_xcursor; /** State of FreeDB old pages, stored in the MDB_env */ typedef struct MDB_pgstate { pgno_t *mf_pghead; /**< Reclaimed freeDB pages, or NULL before use */ txnid_t mf_pglast; /**< ID of last used record, or 0 if !mf_pghead */ } MDB_pgstate; /** The database environment. */ struct MDB_env { HANDLE me_fd; /**< The main data file */ HANDLE me_lfd; /**< The lock file */ HANDLE me_mfd; /**< just for writing the meta pages */ /** Failed to update the meta page. Probably an I/O error. */ #define MDB_FATAL_ERROR 0x80000000U /** Some fields are initialized. */ #define MDB_ENV_ACTIVE 0x20000000U /** me_txkey is set */ #define MDB_ENV_TXKEY 0x10000000U /** fdatasync is unreliable */ #define MDB_FSYNCONLY 0x08000000U uint32_t me_flags; /**< @ref mdb_env */ unsigned int me_psize; /**< DB page size, inited from me_os_psize */ unsigned int me_os_psize; /**< OS page size, from #GET_PAGESIZE */ unsigned int me_maxreaders; /**< size of the reader table */ /** Max #MDB_txninfo.%mti_numreaders of interest to #mdb_env_close() */ volatile int me_close_readers; MDB_dbi me_numdbs; /**< number of DBs opened */ MDB_dbi me_maxdbs; /**< size of the DB table */ MDB_PID_T me_pid; /**< process ID of this env */ char *me_path; /**< path to the DB files */ char *me_map; /**< the memory map of the data file */ MDB_txninfo *me_txns; /**< the memory map of the lock file or NULL */ MDB_meta *me_metas[NUM_METAS]; /**< pointers to the two meta pages */ void *me_pbuf; /**< scratch area for DUPSORT put() */ MDB_txn *me_txn; /**< current write transaction */ MDB_txn *me_txn0; /**< prealloc'd write transaction */ size_t me_mapsize; /**< size of the data memory map */ off_t me_size; /**< current file size */ pgno_t me_maxpg; /**< me_mapsize / me_psize */ MDB_dbx *me_dbxs; /**< array of static DB info */ uint16_t *me_dbflags; /**< array of flags from MDB_db.md_flags */ unsigned int *me_dbiseqs; /**< array of dbi sequence numbers */ pthread_key_t me_txkey; /**< thread-key for readers */ txnid_t me_pgoldest; /**< ID of oldest reader last time we looked */ MDB_pgstate me_pgstate; /**< state of old pages from freeDB */ # define me_pglast me_pgstate.mf_pglast # define me_pghead me_pgstate.mf_pghead MDB_page *me_dpages; /**< list of malloc'd blocks for re-use */ /** IDL of pages that became unused in a write txn */ MDB_IDL me_free_pgs; /** ID2L of pages written during a write txn. Length MDB_IDL_UM_SIZE. */ MDB_ID2L me_dirty_list; /** Max number of freelist items that can fit in a single overflow page */ int me_maxfree_1pg; /** Max size of a node on a page */ unsigned int me_nodemax; #if !(MDB_MAXKEYSIZE) unsigned int me_maxkey; /**< max size of a key */ #endif int me_live_reader; /**< have liveness lock in reader table */ #ifdef _WIN32 int me_pidquery; /**< Used in OpenProcess */ #endif #ifdef MDB_USE_POSIX_MUTEX /* Posix mutexes reside in shared mem */ # define me_rmutex me_txns->mti_rmutex /**< Shared reader lock */ # define me_wmutex me_txns->mti_wmutex /**< Shared writer lock */ #else mdb_mutex_t me_rmutex; mdb_mutex_t me_wmutex; #endif void *me_userctx; /**< User-settable context */ MDB_assert_func *me_assert_func; /**< Callback for assertion failures */ }; /** Nested transaction */ typedef struct MDB_ntxn { MDB_txn mnt_txn; /**< the transaction */ MDB_pgstate mnt_pgstate; /**< parent transaction's saved freestate */ } MDB_ntxn; /** max number of pages to commit in one writev() call */ #define MDB_COMMIT_PAGES 64 #if defined(IOV_MAX) && IOV_MAX < MDB_COMMIT_PAGES #undef MDB_COMMIT_PAGES #define MDB_COMMIT_PAGES IOV_MAX #endif /** max bytes to write in one call */ #define MAX_WRITE (0x80000000U >> (sizeof(ssize_t) == 4)) /** Check \b txn and \b dbi arguments to a function */ #define TXN_DBI_EXIST(txn, dbi, validity) \ ((txn) && (dbi)<(txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & (validity))) /** Check for misused \b dbi handles */ #define TXN_DBI_CHANGED(txn, dbi) \ ((txn)->mt_dbiseqs[dbi] != (txn)->mt_env->me_dbiseqs[dbi]) static int mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp); static int mdb_page_new(MDB_cursor *mc, uint32_t flags, int num, MDB_page **mp); static int mdb_page_touch(MDB_cursor *mc); #define MDB_END_NAMES {"committed", "empty-commit", "abort", "reset", \ "reset-tmp", "fail-begin", "fail-beginchild"} enum { /* mdb_txn_end operation number, for logging */ MDB_END_COMMITTED, MDB_END_EMPTY_COMMIT, MDB_END_ABORT, MDB_END_RESET, MDB_END_RESET_TMP, MDB_END_FAIL_BEGIN, MDB_END_FAIL_BEGINCHILD }; #define MDB_END_OPMASK 0x0F /**< mask for #mdb_txn_end() operation number */ #define MDB_END_UPDATE 0x10 /**< update env state (DBIs) */ #define MDB_END_FREE 0x20 /**< free txn unless it is #MDB_env.%me_txn0 */ #define MDB_END_SLOT MDB_NOTLS /**< release any reader slot if #MDB_NOTLS */ static void mdb_txn_end(MDB_txn *txn, unsigned mode); static int mdb_page_get(MDB_txn *txn, pgno_t pgno, MDB_page **mp, int *lvl); static int mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int modify); #define MDB_PS_MODIFY 1 #define MDB_PS_ROOTONLY 2 #define MDB_PS_FIRST 4 #define MDB_PS_LAST 8 static int mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags); static int mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst); #define MDB_SPLIT_REPLACE MDB_APPENDDUP /**< newkey is not new */ static int mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno, unsigned int nflags); static int mdb_env_read_header(MDB_env *env, MDB_meta *meta); static MDB_meta *mdb_env_pick_meta(const MDB_env *env); static int mdb_env_write_meta(MDB_txn *txn); #ifdef MDB_USE_POSIX_MUTEX /* Drop unused excl arg */ # define mdb_env_close0(env, excl) mdb_env_close1(env) #endif static void mdb_env_close0(MDB_env *env, int excl); static MDB_node *mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp); static int mdb_node_add(MDB_cursor *mc, indx_t indx, MDB_val *key, MDB_val *data, pgno_t pgno, unsigned int flags); static void mdb_node_del(MDB_cursor *mc, int ksize); static void mdb_node_shrink(MDB_page *mp, indx_t indx); static int mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst); static int mdb_node_read(MDB_txn *txn, MDB_node *leaf, MDB_val *data); static size_t mdb_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data); static size_t mdb_branch_size(MDB_env *env, MDB_val *key); static int mdb_rebalance(MDB_cursor *mc); static int mdb_update_key(MDB_cursor *mc, MDB_val *key); static void mdb_cursor_pop(MDB_cursor *mc); static int mdb_cursor_push(MDB_cursor *mc, MDB_page *mp); static int mdb_cursor_del0(MDB_cursor *mc); static int mdb_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned flags); static int mdb_cursor_sibling(MDB_cursor *mc, int move_right); static int mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op); static int mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op); static int mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op, int *exactp); static int mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data); static int mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data); static void mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx); static void mdb_xcursor_init0(MDB_cursor *mc); static void mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node); static void mdb_xcursor_init2(MDB_cursor *mc, MDB_xcursor *src_mx, int force); static int mdb_drop0(MDB_cursor *mc, int subs); static void mdb_default_cmp(MDB_txn *txn, MDB_dbi dbi); static int mdb_reader_check0(MDB_env *env, int rlocked, int *dead); /** @cond */ static MDB_cmp_func mdb_cmp_memn, mdb_cmp_memnr, mdb_cmp_int, mdb_cmp_cint, mdb_cmp_long; /** @endcond */ /** Compare two items pointing at size_t's of unknown alignment. */ #ifdef MISALIGNED_OK # define mdb_cmp_clong mdb_cmp_long #else # define mdb_cmp_clong mdb_cmp_cint #endif #ifdef _WIN32 static SECURITY_DESCRIPTOR mdb_null_sd; static SECURITY_ATTRIBUTES mdb_all_sa; static int mdb_sec_inited; #endif /** Return the library version info. */ char * ESECT mdb_version(int *major, int *minor, int *patch) { if (major) *major = MDB_VERSION_MAJOR; if (minor) *minor = MDB_VERSION_MINOR; if (patch) *patch = MDB_VERSION_PATCH; return MDB_VERSION_STRING; } /** Table of descriptions for LMDB @ref errors */ static char *const mdb_errstr[] = { "MDB_KEYEXIST: Key/data pair already exists", "MDB_NOTFOUND: No matching key/data pair found", "MDB_PAGE_NOTFOUND: Requested page not found", "MDB_CORRUPTED: Located page was wrong type", "MDB_PANIC: Update of meta page failed or environment had fatal error", "MDB_VERSION_MISMATCH: Database environment version mismatch", "MDB_INVALID: File is not an LMDB file", "MDB_MAP_FULL: Environment mapsize limit reached", "MDB_DBS_FULL: Environment maxdbs limit reached", "MDB_READERS_FULL: Environment maxreaders limit reached", "MDB_TLS_FULL: Thread-local storage keys full - too many environments open", "MDB_TXN_FULL: Transaction has too many dirty pages - transaction too big", "MDB_CURSOR_FULL: Internal error - cursor stack limit reached", "MDB_PAGE_FULL: Internal error - page has no more space", "MDB_MAP_RESIZED: Database contents grew beyond environment mapsize", "MDB_INCOMPATIBLE: Operation and DB incompatible, or DB flags changed", "MDB_BAD_RSLOT: Invalid reuse of reader locktable slot", "MDB_BAD_TXN: Transaction must abort, has a child, or is invalid", "MDB_BAD_VALSIZE: Unsupported size of key/DB name/data, or wrong DUPFIXED size", "MDB_BAD_DBI: The specified DBI handle was closed/changed unexpectedly", }; char * mdb_strerror(int err) { #ifdef _WIN32 /** HACK: pad 4KB on stack over the buf. Return system msgs in buf. * This works as long as no function between the call to mdb_strerror * and the actual use of the message uses more than 4K of stack. */ char pad[4096]; char buf[1024], *ptr = buf; #endif int i; if (!err) return ("Successful return: 0"); if (err >= MDB_KEYEXIST && err <= MDB_LAST_ERRCODE) { i = err - MDB_KEYEXIST; return mdb_errstr[i]; } #ifdef _WIN32 /* These are the C-runtime error codes we use. The comment indicates * their numeric value, and the Win32 error they would correspond to * if the error actually came from a Win32 API. A major mess, we should * have used LMDB-specific error codes for everything. */ switch(err) { case ENOENT: /* 2, FILE_NOT_FOUND */ case EIO: /* 5, ACCESS_DENIED */ case ENOMEM: /* 12, INVALID_ACCESS */ case EACCES: /* 13, INVALID_DATA */ case EBUSY: /* 16, CURRENT_DIRECTORY */ case EINVAL: /* 22, BAD_COMMAND */ case ENOSPC: /* 28, OUT_OF_PAPER */ return strerror(err); default: ; } buf[0] = 0; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, ptr, sizeof(buf), (va_list *)pad); return ptr; #else return strerror(err); #endif } /** assert(3) variant in cursor context */ #define mdb_cassert(mc, expr) mdb_assert0((mc)->mc_txn->mt_env, expr, #expr) /** assert(3) variant in transaction context */ #define mdb_tassert(txn, expr) mdb_assert0((txn)->mt_env, expr, #expr) /** assert(3) variant in environment context */ #define mdb_eassert(env, expr) mdb_assert0(env, expr, #expr) #ifndef NDEBUG # define mdb_assert0(env, expr, expr_txt) ((expr) ? (void)0 : \ mdb_assert_fail(env, expr_txt, mdb_func_, __FILE__, __LINE__)) static void ESECT mdb_assert_fail(MDB_env *env, const char *expr_txt, const char *func, const char *file, int line) { char buf[400]; sprintf(buf, "%.100s:%d: Assertion '%.200s' failed in %.40s()", file, line, expr_txt, func); if (env->me_assert_func) env->me_assert_func(env, buf); fprintf(stderr, "%s\n", buf); abort(); } #else # define mdb_assert0(env, expr, expr_txt) ((void) 0) #endif /* NDEBUG */ #if MDB_DEBUG /** Return the page number of \b mp which may be sub-page, for debug output */ static pgno_t mdb_dbg_pgno(MDB_page *mp) { pgno_t ret; COPY_PGNO(ret, mp->mp_pgno); return ret; } /** Display a key in hexadecimal and return the address of the result. * @param[in] key the key to display * @param[in] buf the buffer to write into. Should always be #DKBUF. * @return The key in hexadecimal form. */ char * mdb_dkey(MDB_val *key, char *buf) { char *ptr = buf; unsigned char *c = key->mv_data; unsigned int i; if (!key) return ""; if (key->mv_size > DKBUF_MAXKEYSIZE) return "MDB_MAXKEYSIZE"; /* may want to make this a dynamic check: if the key is mostly * printable characters, print it as-is instead of converting to hex. */ #if 1 buf[0] = '\0'; for (i=0; imv_size; i++) ptr += sprintf(ptr, "%02x", *c++); #else sprintf(buf, "%.*s", key->mv_size, key->mv_data); #endif return buf; } static const char * mdb_leafnode_type(MDB_node *n) { static char *const tp[2][2] = {{"", ": DB"}, {": sub-page", ": sub-DB"}}; return F_ISSET(n->mn_flags, F_BIGDATA) ? ": overflow page" : tp[F_ISSET(n->mn_flags, F_DUPDATA)][F_ISSET(n->mn_flags, F_SUBDATA)]; } /** Display all the keys in the page. */ void mdb_page_list(MDB_page *mp) { pgno_t pgno = mdb_dbg_pgno(mp); const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : ""; MDB_node *node; unsigned int i, nkeys, nsize, total = 0; MDB_val key; DKBUF; switch (mp->mp_flags & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) { case P_BRANCH: type = "Branch page"; break; case P_LEAF: type = "Leaf page"; break; case P_LEAF|P_SUBP: type = "Sub-page"; break; case P_LEAF|P_LEAF2: type = "LEAF2 page"; break; case P_LEAF|P_LEAF2|P_SUBP: type = "LEAF2 sub-page"; break; case P_OVERFLOW: fprintf(stderr, "Overflow page %"Z"u pages %u%s\n", pgno, mp->mp_pages, state); return; case P_META: fprintf(stderr, "Meta-page %"Z"u txnid %"Z"u\n", pgno, ((MDB_meta *)METADATA(mp))->mm_txnid); return; default: fprintf(stderr, "Bad page %"Z"u flags 0x%u\n", pgno, mp->mp_flags); return; } nkeys = NUMKEYS(mp); fprintf(stderr, "%s %"Z"u numkeys %d%s\n", type, pgno, nkeys, state); for (i=0; imp_pad; key.mv_data = LEAF2KEY(mp, i, nsize); total += nsize; fprintf(stderr, "key %d: nsize %d, %s\n", i, nsize, DKEY(&key)); continue; } node = NODEPTR(mp, i); key.mv_size = node->mn_ksize; key.mv_data = node->mn_data; nsize = NODESIZE + key.mv_size; if (IS_BRANCH(mp)) { fprintf(stderr, "key %d: page %"Z"u, %s\n", i, NODEPGNO(node), DKEY(&key)); total += nsize; } else { if (F_ISSET(node->mn_flags, F_BIGDATA)) nsize += sizeof(pgno_t); else nsize += NODEDSZ(node); total += nsize; nsize += sizeof(indx_t); fprintf(stderr, "key %d: nsize %d, %s%s\n", i, nsize, DKEY(&key), mdb_leafnode_type(node)); } total = EVEN(total); } fprintf(stderr, "Total: header %d + contents %d + unused %d\n", IS_LEAF2(mp) ? PAGEHDRSZ : PAGEBASE + mp->mp_lower, total, SIZELEFT(mp)); } void mdb_cursor_chk(MDB_cursor *mc) { unsigned int i; MDB_node *node; MDB_page *mp; if (!mc->mc_snum && !(mc->mc_flags & C_INITIALIZED)) return; for (i=0; imc_top; i++) { mp = mc->mc_pg[i]; node = NODEPTR(mp, mc->mc_ki[i]); if (NODEPGNO(node) != mc->mc_pg[i+1]->mp_pgno) printf("oops!\n"); } if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i])) printf("ack!\n"); } #endif #if (MDB_DEBUG) > 2 /** Count all the pages in each DB and in the freelist * and make sure it matches the actual number of pages * being used. * All named DBs must be open for a correct count. */ static void mdb_audit(MDB_txn *txn) { MDB_cursor mc; MDB_val key, data; MDB_ID freecount, count; MDB_dbi i; int rc; freecount = 0; mdb_cursor_init(&mc, txn, FREE_DBI, NULL); while ((rc = mdb_cursor_get(&mc, &key, &data, MDB_NEXT)) == 0) freecount += *(MDB_ID *)data.mv_data; mdb_tassert(txn, rc == MDB_NOTFOUND); count = 0; for (i = 0; imt_numdbs; i++) { MDB_xcursor mx; if (!(txn->mt_dbflags[i] & DB_VALID)) continue; mdb_cursor_init(&mc, txn, i, &mx); if (txn->mt_dbs[i].md_root == P_INVALID) continue; count += txn->mt_dbs[i].md_branch_pages + txn->mt_dbs[i].md_leaf_pages + txn->mt_dbs[i].md_overflow_pages; if (txn->mt_dbs[i].md_flags & MDB_DUPSORT) { rc = mdb_page_search(&mc, NULL, MDB_PS_FIRST); for (; rc == MDB_SUCCESS; rc = mdb_cursor_sibling(&mc, 1)) { unsigned j; MDB_page *mp; mp = mc.mc_pg[mc.mc_top]; for (j=0; jmn_flags & F_SUBDATA) { MDB_db db; memcpy(&db, NODEDATA(leaf), sizeof(db)); count += db.md_branch_pages + db.md_leaf_pages + db.md_overflow_pages; } } } mdb_tassert(txn, rc == MDB_NOTFOUND); } } if (freecount + count + NUM_METAS != txn->mt_next_pgno) { fprintf(stderr, "audit: %lu freecount: %lu count: %lu total: %lu next_pgno: %lu\n", txn->mt_txnid, freecount, count+NUM_METAS, freecount+count+NUM_METAS, txn->mt_next_pgno); } } #endif int mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b) { return txn->mt_dbxs[dbi].md_cmp(a, b); } int mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b) { MDB_cmp_func *dcmp = txn->mt_dbxs[dbi].md_dcmp; #if UINT_MAX < SIZE_MAX if (dcmp == mdb_cmp_int && a->mv_size == sizeof(size_t)) dcmp = mdb_cmp_clong; #endif return dcmp(a, b); } /** Allocate memory for a page. * Re-use old malloc'd pages first for singletons, otherwise just malloc. */ static MDB_page * mdb_page_malloc(MDB_txn *txn, unsigned num) { MDB_env *env = txn->mt_env; MDB_page *ret = env->me_dpages; size_t psize = env->me_psize, sz = psize, off; /* For ! #MDB_NOMEMINIT, psize counts how much to init. * For a single page alloc, we init everything after the page header. * For multi-page, we init the final page; if the caller needed that * many pages they will be filling in at least up to the last page. */ if (num == 1) { if (ret) { VGMEMP_ALLOC(env, ret, sz); VGMEMP_DEFINED(ret, sizeof(ret->mp_next)); env->me_dpages = ret->mp_next; return ret; } psize -= off = PAGEHDRSZ; } else { sz *= num; off = sz - psize; } if ((ret = malloc(sz)) != NULL) { VGMEMP_ALLOC(env, ret, sz); if (!(env->me_flags & MDB_NOMEMINIT)) { memset((char *)ret + off, 0, psize); ret->mp_pad = 0; } } else { txn->mt_flags |= MDB_TXN_ERROR; } return ret; } /** Free a single page. * Saves single pages to a list, for future reuse. * (This is not used for multi-page overflow pages.) */ static void mdb_page_free(MDB_env *env, MDB_page *mp) { mp->mp_next = env->me_dpages; VGMEMP_FREE(env, mp); env->me_dpages = mp; } /** Free a dirty page */ static void mdb_dpage_free(MDB_env *env, MDB_page *dp) { if (!IS_OVERFLOW(dp) || dp->mp_pages == 1) { mdb_page_free(env, dp); } else { /* large pages just get freed directly */ VGMEMP_FREE(env, dp); free(dp); } } /** Return all dirty pages to dpage list */ static void mdb_dlist_free(MDB_txn *txn) { MDB_env *env = txn->mt_env; MDB_ID2L dl = txn->mt_u.dirty_list; unsigned i, n = dl[0].mid; for (i = 1; i <= n; i++) { mdb_dpage_free(env, dl[i].mptr); } dl[0].mid = 0; } /** Loosen or free a single page. * Saves single pages to a list for future reuse * in this same txn. It has been pulled from the freeDB * and already resides on the dirty list, but has been * deleted. Use these pages first before pulling again * from the freeDB. * * If the page wasn't dirtied in this txn, just add it * to this txn's free list. */ static int mdb_page_loose(MDB_cursor *mc, MDB_page *mp) { int loose = 0; pgno_t pgno = mp->mp_pgno; MDB_txn *txn = mc->mc_txn; if ((mp->mp_flags & P_DIRTY) && mc->mc_dbi != FREE_DBI) { if (txn->mt_parent) { MDB_ID2 *dl = txn->mt_u.dirty_list; /* If txn has a parent, make sure the page is in our * dirty list. */ if (dl[0].mid) { unsigned x = mdb_mid2l_search(dl, pgno); if (x <= dl[0].mid && dl[x].mid == pgno) { if (mp != dl[x].mptr) { /* bad cursor? */ mc->mc_flags &= ~(C_INITIALIZED|C_EOF); txn->mt_flags |= MDB_TXN_ERROR; return MDB_CORRUPTED; } /* ok, it's ours */ loose = 1; } } } else { /* no parent txn, so it's just ours */ loose = 1; } } if (loose) { DPRINTF(("loosen db %d page %"Z"u", DDBI(mc), mp->mp_pgno)); NEXT_LOOSE_PAGE(mp) = txn->mt_loose_pgs; txn->mt_loose_pgs = mp; txn->mt_loose_count++; mp->mp_flags |= P_LOOSE; } else { int rc = mdb_midl_append(&txn->mt_free_pgs, pgno); if (rc) return rc; } return MDB_SUCCESS; } /** Set or clear P_KEEP in dirty, non-overflow, non-sub pages watched by txn. * @param[in] mc A cursor handle for the current operation. * @param[in] pflags Flags of the pages to update: * P_DIRTY to set P_KEEP, P_DIRTY|P_KEEP to clear it. * @param[in] all No shortcuts. Needed except after a full #mdb_page_flush(). * @return 0 on success, non-zero on failure. */ static int mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all) { enum { Mask = P_SUBP|P_DIRTY|P_LOOSE|P_KEEP }; MDB_txn *txn = mc->mc_txn; MDB_cursor *m3; MDB_xcursor *mx; MDB_page *dp, *mp; MDB_node *leaf; unsigned i, j; int rc = MDB_SUCCESS, level; /* Mark pages seen by cursors */ if (mc->mc_flags & C_UNTRACK) mc = NULL; /* will find mc in mt_cursors */ for (i = txn->mt_numdbs;; mc = txn->mt_cursors[--i]) { for (; mc; mc=mc->mc_next) { if (!(mc->mc_flags & C_INITIALIZED)) continue; for (m3 = mc;; m3 = &mx->mx_cursor) { mp = NULL; for (j=0; jmc_snum; j++) { mp = m3->mc_pg[j]; if ((mp->mp_flags & Mask) == pflags) mp->mp_flags ^= P_KEEP; } mx = m3->mc_xcursor; /* Proceed to mx if it is at a sub-database */ if (! (mx && (mx->mx_cursor.mc_flags & C_INITIALIZED))) break; if (! (mp && (mp->mp_flags & P_LEAF))) break; leaf = NODEPTR(mp, m3->mc_ki[j-1]); if (!(leaf->mn_flags & F_SUBDATA)) break; } } if (i == 0) break; } if (all) { /* Mark dirty root pages */ for (i=0; imt_numdbs; i++) { if (txn->mt_dbflags[i] & DB_DIRTY) { pgno_t pgno = txn->mt_dbs[i].md_root; if (pgno == P_INVALID) continue; if ((rc = mdb_page_get(txn, pgno, &dp, &level)) != MDB_SUCCESS) break; if ((dp->mp_flags & Mask) == pflags && level <= 1) dp->mp_flags ^= P_KEEP; } } } return rc; } static int mdb_page_flush(MDB_txn *txn, int keep); /** Spill pages from the dirty list back to disk. * This is intended to prevent running into #MDB_TXN_FULL situations, * but note that they may still occur in a few cases: * 1) our estimate of the txn size could be too small. Currently this * seems unlikely, except with a large number of #MDB_MULTIPLE items. * 2) child txns may run out of space if their parents dirtied a * lot of pages and never spilled them. TODO: we probably should do * a preemptive spill during #mdb_txn_begin() of a child txn, if * the parent's dirty_room is below a given threshold. * * Otherwise, if not using nested txns, it is expected that apps will * not run into #MDB_TXN_FULL any more. The pages are flushed to disk * the same way as for a txn commit, e.g. their P_DIRTY flag is cleared. * If the txn never references them again, they can be left alone. * If the txn only reads them, they can be used without any fuss. * If the txn writes them again, they can be dirtied immediately without * going thru all of the work of #mdb_page_touch(). Such references are * handled by #mdb_page_unspill(). * * Also note, we never spill DB root pages, nor pages of active cursors, * because we'll need these back again soon anyway. And in nested txns, * we can't spill a page in a child txn if it was already spilled in a * parent txn. That would alter the parent txns' data even though * the child hasn't committed yet, and we'd have no way to undo it if * the child aborted. * * @param[in] m0 cursor A cursor handle identifying the transaction and * database for which we are checking space. * @param[in] key For a put operation, the key being stored. * @param[in] data For a put operation, the data being stored. * @return 0 on success, non-zero on failure. */ static int mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data) { MDB_txn *txn = m0->mc_txn; MDB_page *dp; MDB_ID2L dl = txn->mt_u.dirty_list; unsigned int i, j, need; int rc; if (m0->mc_flags & C_SUB) return MDB_SUCCESS; /* Estimate how much space this op will take */ i = m0->mc_db->md_depth; /* Named DBs also dirty the main DB */ if (m0->mc_dbi >= CORE_DBS) i += txn->mt_dbs[MAIN_DBI].md_depth; /* For puts, roughly factor in the key+data size */ if (key) i += (LEAFSIZE(key, data) + txn->mt_env->me_psize) / txn->mt_env->me_psize; i += i; /* double it for good measure */ need = i; if (txn->mt_dirty_room > i) return MDB_SUCCESS; if (!txn->mt_spill_pgs) { txn->mt_spill_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX); if (!txn->mt_spill_pgs) return ENOMEM; } else { /* purge deleted slots */ MDB_IDL sl = txn->mt_spill_pgs; unsigned int num = sl[0]; j=0; for (i=1; i<=num; i++) { if (!(sl[i] & 1)) sl[++j] = sl[i]; } sl[0] = j; } /* Preserve pages which may soon be dirtied again */ if ((rc = mdb_pages_xkeep(m0, P_DIRTY, 1)) != MDB_SUCCESS) goto done; /* Less aggressive spill - we originally spilled the entire dirty list, * with a few exceptions for cursor pages and DB root pages. But this * turns out to be a lot of wasted effort because in a large txn many * of those pages will need to be used again. So now we spill only 1/8th * of the dirty pages. Testing revealed this to be a good tradeoff, * better than 1/2, 1/4, or 1/10. */ if (need < MDB_IDL_UM_MAX / 8) need = MDB_IDL_UM_MAX / 8; /* Save the page IDs of all the pages we're flushing */ /* flush from the tail forward, this saves a lot of shifting later on. */ for (i=dl[0].mid; i && need; i--) { MDB_ID pn = dl[i].mid << 1; dp = dl[i].mptr; if (dp->mp_flags & (P_LOOSE|P_KEEP)) continue; /* Can't spill twice, make sure it's not already in a parent's * spill list. */ if (txn->mt_parent) { MDB_txn *tx2; for (tx2 = txn->mt_parent; tx2; tx2 = tx2->mt_parent) { if (tx2->mt_spill_pgs) { j = mdb_midl_search(tx2->mt_spill_pgs, pn); if (j <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[j] == pn) { dp->mp_flags |= P_KEEP; break; } } } if (tx2) continue; } if ((rc = mdb_midl_append(&txn->mt_spill_pgs, pn))) goto done; need--; } mdb_midl_sort(txn->mt_spill_pgs); /* Flush the spilled part of dirty list */ if ((rc = mdb_page_flush(txn, i)) != MDB_SUCCESS) goto done; /* Reset any dirty pages we kept that page_flush didn't see */ rc = mdb_pages_xkeep(m0, P_DIRTY|P_KEEP, i); done: txn->mt_flags |= rc ? MDB_TXN_ERROR : MDB_TXN_SPILLS; return rc; } /** Find oldest txnid still referenced. Expects txn->mt_txnid > 0. */ static txnid_t mdb_find_oldest(MDB_txn *txn) { int i; txnid_t mr, oldest = txn->mt_txnid - 1; if (txn->mt_env->me_txns) { MDB_reader *r = txn->mt_env->me_txns->mti_readers; for (i = txn->mt_env->me_txns->mti_numreaders; --i >= 0; ) { if (r[i].mr_pid) { mr = r[i].mr_txnid; if (oldest > mr) oldest = mr; } } } return oldest; } /** Add a page to the txn's dirty list */ static void mdb_page_dirty(MDB_txn *txn, MDB_page *mp) { MDB_ID2 mid; int rc, (*insert)(MDB_ID2L, MDB_ID2 *); if (txn->mt_flags & MDB_TXN_WRITEMAP) { insert = mdb_mid2l_append; } else { insert = mdb_mid2l_insert; } mid.mid = mp->mp_pgno; mid.mptr = mp; rc = insert(txn->mt_u.dirty_list, &mid); mdb_tassert(txn, rc == 0); txn->mt_dirty_room--; } /** Allocate page numbers and memory for writing. Maintain me_pglast, * me_pghead and mt_next_pgno. * * If there are free pages available from older transactions, they * are re-used first. Otherwise allocate a new page at mt_next_pgno. * Do not modify the freedB, just merge freeDB records into me_pghead[] * and move me_pglast to say which records were consumed. Only this * function can create me_pghead and move me_pglast/mt_next_pgno. * @param[in] mc cursor A cursor handle identifying the transaction and * database for which we are allocating. * @param[in] num the number of pages to allocate. * @param[out] mp Address of the allocated page(s). Requests for multiple pages * will always be satisfied by a single contiguous chunk of memory. * @return 0 on success, non-zero on failure. */ static int mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp) { #ifdef MDB_PARANOID /* Seems like we can ignore this now */ /* Get at most more freeDB records once me_pghead * has enough pages. If not enough, use new pages from the map. * If and mc is updating the freeDB, only get new * records if me_pghead is empty. Then the freelist cannot play * catch-up with itself by growing while trying to save it. */ enum { Paranoid = 1, Max_retries = 500 }; #else enum { Paranoid = 0, Max_retries = INT_MAX /*infinite*/ }; #endif int rc, retry = num * 60; MDB_txn *txn = mc->mc_txn; MDB_env *env = txn->mt_env; pgno_t pgno, *mop = env->me_pghead; unsigned i, j, mop_len = mop ? mop[0] : 0, n2 = num-1; MDB_page *np; txnid_t oldest = 0, last; MDB_cursor_op op; MDB_cursor m2; int found_old = 0; /* If there are any loose pages, just use them */ if (num == 1 && txn->mt_loose_pgs) { np = txn->mt_loose_pgs; txn->mt_loose_pgs = NEXT_LOOSE_PAGE(np); txn->mt_loose_count--; DPRINTF(("db %d use loose page %"Z"u", DDBI(mc), np->mp_pgno)); *mp = np; return MDB_SUCCESS; } *mp = NULL; /* If our dirty list is already full, we can't do anything */ if (txn->mt_dirty_room == 0) { rc = MDB_TXN_FULL; goto fail; } for (op = MDB_FIRST;; op = MDB_NEXT) { MDB_val key, data; MDB_node *leaf; pgno_t *idl; /* Seek a big enough contiguous page range. Prefer * pages at the tail, just truncating the list. */ if (mop_len > n2) { i = mop_len; do { pgno = mop[i]; if (mop[i-n2] == pgno+n2) goto search_done; } while (--i > n2); if (--retry < 0) break; } if (op == MDB_FIRST) { /* 1st iteration */ /* Prepare to fetch more and coalesce */ last = env->me_pglast; oldest = env->me_pgoldest; mdb_cursor_init(&m2, txn, FREE_DBI, NULL); if (last) { op = MDB_SET_RANGE; key.mv_data = &last; /* will look up last+1 */ key.mv_size = sizeof(last); } if (Paranoid && mc->mc_dbi == FREE_DBI) retry = -1; } if (Paranoid && retry < 0 && mop_len) break; last++; /* Do not fetch more if the record will be too recent */ if (oldest <= last) { if (!found_old) { oldest = mdb_find_oldest(txn); env->me_pgoldest = oldest; found_old = 1; } if (oldest <= last) break; } rc = mdb_cursor_get(&m2, &key, NULL, op); if (rc) { if (rc == MDB_NOTFOUND) break; goto fail; } last = *(txnid_t*)key.mv_data; if (oldest <= last) { if (!found_old) { oldest = mdb_find_oldest(txn); env->me_pgoldest = oldest; found_old = 1; } if (oldest <= last) break; } np = m2.mc_pg[m2.mc_top]; leaf = NODEPTR(np, m2.mc_ki[m2.mc_top]); if ((rc = mdb_node_read(txn, leaf, &data)) != MDB_SUCCESS) return rc; idl = (MDB_ID *) data.mv_data; i = idl[0]; if (!mop) { if (!(env->me_pghead = mop = mdb_midl_alloc(i))) { rc = ENOMEM; goto fail; } } else { if ((rc = mdb_midl_need(&env->me_pghead, i)) != 0) goto fail; mop = env->me_pghead; } env->me_pglast = last; #if (MDB_DEBUG) > 1 DPRINTF(("IDL read txn %"Z"u root %"Z"u num %u", last, txn->mt_dbs[FREE_DBI].md_root, i)); for (j = i; j; j--) DPRINTF(("IDL %"Z"u", idl[j])); #endif /* Merge in descending sorted order */ mdb_midl_xmerge(mop, idl); mop_len = mop[0]; } /* Use new pages from the map when nothing suitable in the freeDB */ i = 0; pgno = txn->mt_next_pgno; if (pgno + num >= env->me_maxpg) { DPUTS("DB size maxed out"); rc = MDB_MAP_FULL; goto fail; } search_done: if (env->me_flags & MDB_WRITEMAP) { np = (MDB_page *)(env->me_map + env->me_psize * pgno); } else { if (!(np = mdb_page_malloc(txn, num))) { rc = ENOMEM; goto fail; } } if (i) { mop[0] = mop_len -= num; /* Move any stragglers down */ for (j = i-num; j < mop_len; ) mop[++j] = mop[++i]; } else { txn->mt_next_pgno = pgno + num; } np->mp_pgno = pgno; mdb_page_dirty(txn, np); *mp = np; return MDB_SUCCESS; fail: txn->mt_flags |= MDB_TXN_ERROR; return rc; } /** Copy the used portions of a non-overflow page. * @param[in] dst page to copy into * @param[in] src page to copy from * @param[in] psize size of a page */ static void mdb_page_copy(MDB_page *dst, MDB_page *src, unsigned int psize) { enum { Align = sizeof(pgno_t) }; indx_t upper = src->mp_upper, lower = src->mp_lower, unused = upper-lower; /* If page isn't full, just copy the used portion. Adjust * alignment so memcpy may copy words instead of bytes. */ if ((unused &= -Align) && !IS_LEAF2(src)) { upper = (upper + PAGEBASE) & -Align; memcpy(dst, src, (lower + PAGEBASE + (Align-1)) & -Align); memcpy((pgno_t *)((char *)dst+upper), (pgno_t *)((char *)src+upper), psize - upper); } else { memcpy(dst, src, psize - unused); } } /** Pull a page off the txn's spill list, if present. * If a page being referenced was spilled to disk in this txn, bring * it back and make it dirty/writable again. * @param[in] txn the transaction handle. * @param[in] mp the page being referenced. It must not be dirty. * @param[out] ret the writable page, if any. ret is unchanged if * mp wasn't spilled. */ static int mdb_page_unspill(MDB_txn *txn, MDB_page *mp, MDB_page **ret) { MDB_env *env = txn->mt_env; const MDB_txn *tx2; unsigned x; pgno_t pgno = mp->mp_pgno, pn = pgno << 1; for (tx2 = txn; tx2; tx2=tx2->mt_parent) { if (!tx2->mt_spill_pgs) continue; x = mdb_midl_search(tx2->mt_spill_pgs, pn); if (x <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[x] == pn) { MDB_page *np; int num; if (txn->mt_dirty_room == 0) return MDB_TXN_FULL; if (IS_OVERFLOW(mp)) num = mp->mp_pages; else num = 1; if (env->me_flags & MDB_WRITEMAP) { np = mp; } else { np = mdb_page_malloc(txn, num); if (!np) return ENOMEM; if (num > 1) memcpy(np, mp, num * env->me_psize); else mdb_page_copy(np, mp, env->me_psize); } if (tx2 == txn) { /* If in current txn, this page is no longer spilled. * If it happens to be the last page, truncate the spill list. * Otherwise mark it as deleted by setting the LSB. */ if (x == txn->mt_spill_pgs[0]) txn->mt_spill_pgs[0]--; else txn->mt_spill_pgs[x] |= 1; } /* otherwise, if belonging to a parent txn, the * page remains spilled until child commits */ mdb_page_dirty(txn, np); np->mp_flags |= P_DIRTY; *ret = np; break; } } return MDB_SUCCESS; } /** Touch a page: make it dirty and re-insert into tree with updated pgno. * @param[in] mc cursor pointing to the page to be touched * @return 0 on success, non-zero on failure. */ static int mdb_page_touch(MDB_cursor *mc) { MDB_page *mp = mc->mc_pg[mc->mc_top], *np; MDB_txn *txn = mc->mc_txn; MDB_cursor *m2, *m3; pgno_t pgno; int rc; if (!F_ISSET(mp->mp_flags, P_DIRTY)) { if (txn->mt_flags & MDB_TXN_SPILLS) { np = NULL; rc = mdb_page_unspill(txn, mp, &np); if (rc) goto fail; if (np) goto done; } if ((rc = mdb_midl_need(&txn->mt_free_pgs, 1)) || (rc = mdb_page_alloc(mc, 1, &np))) goto fail; pgno = np->mp_pgno; DPRINTF(("touched db %d page %"Z"u -> %"Z"u", DDBI(mc), mp->mp_pgno, pgno)); mdb_cassert(mc, mp->mp_pgno != pgno); mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno); /* Update the parent page, if any, to point to the new page */ if (mc->mc_top) { MDB_page *parent = mc->mc_pg[mc->mc_top-1]; MDB_node *node = NODEPTR(parent, mc->mc_ki[mc->mc_top-1]); SETPGNO(node, pgno); } else { mc->mc_db->md_root = pgno; } } else if (txn->mt_parent && !IS_SUBP(mp)) { MDB_ID2 mid, *dl = txn->mt_u.dirty_list; pgno = mp->mp_pgno; /* If txn has a parent, make sure the page is in our * dirty list. */ if (dl[0].mid) { unsigned x = mdb_mid2l_search(dl, pgno); if (x <= dl[0].mid && dl[x].mid == pgno) { if (mp != dl[x].mptr) { /* bad cursor? */ mc->mc_flags &= ~(C_INITIALIZED|C_EOF); txn->mt_flags |= MDB_TXN_ERROR; return MDB_CORRUPTED; } return 0; } } mdb_cassert(mc, dl[0].mid < MDB_IDL_UM_MAX); /* No - copy it */ np = mdb_page_malloc(txn, 1); if (!np) return ENOMEM; mid.mid = pgno; mid.mptr = np; rc = mdb_mid2l_insert(dl, &mid); mdb_cassert(mc, rc == 0); } else { return 0; } mdb_page_copy(np, mp, txn->mt_env->me_psize); np->mp_pgno = pgno; np->mp_flags |= P_DIRTY; done: /* Adjust cursors pointing to mp */ mc->mc_pg[mc->mc_top] = np; m2 = txn->mt_cursors[mc->mc_dbi]; if (mc->mc_flags & C_SUB) { for (; m2; m2=m2->mc_next) { m3 = &m2->mc_xcursor->mx_cursor; if (m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[mc->mc_top] == mp) m3->mc_pg[mc->mc_top] = np; } } else { for (; m2; m2=m2->mc_next) { if (m2->mc_snum < mc->mc_snum) continue; if (m2->mc_pg[mc->mc_top] == mp) { m2->mc_pg[mc->mc_top] = np; if ((mc->mc_db->md_flags & MDB_DUPSORT) && IS_LEAF(np) && m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top]) { MDB_node *leaf = NODEPTR(np, mc->mc_ki[mc->mc_top]); if (!(leaf->mn_flags & F_SUBDATA)) m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); } } } } return 0; fail: txn->mt_flags |= MDB_TXN_ERROR; return rc; } int mdb_env_sync(MDB_env *env, int force) { int rc = 0; if (env->me_flags & MDB_RDONLY) return EACCES; if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) { if (env->me_flags & MDB_WRITEMAP) { int flags = ((env->me_flags & MDB_MAPASYNC) && !force) ? MS_ASYNC : MS_SYNC; if (MDB_MSYNC(env->me_map, env->me_mapsize, flags)) rc = ErrCode(); #ifdef _WIN32 else if (flags == MS_SYNC && MDB_FDATASYNC(env->me_fd)) rc = ErrCode(); #endif } else { #ifdef BROKEN_FDATASYNC if (env->me_flags & MDB_FSYNCONLY) { if (fsync(env->me_fd)) rc = ErrCode(); } else #endif if (MDB_FDATASYNC(env->me_fd)) rc = ErrCode(); } } return rc; } /** Back up parent txn's cursors, then grab the originals for tracking */ static int mdb_cursor_shadow(MDB_txn *src, MDB_txn *dst) { MDB_cursor *mc, *bk; MDB_xcursor *mx; size_t size; int i; for (i = src->mt_numdbs; --i >= 0; ) { if ((mc = src->mt_cursors[i]) != NULL) { size = sizeof(MDB_cursor); if (mc->mc_xcursor) size += sizeof(MDB_xcursor); for (; mc; mc = bk->mc_next) { bk = malloc(size); if (!bk) return ENOMEM; *bk = *mc; mc->mc_backup = bk; mc->mc_db = &dst->mt_dbs[i]; /* Kill pointers into src - and dst to reduce abuse: The * user may not use mc until dst ends. Otherwise we'd... */ mc->mc_txn = NULL; /* ...set this to dst */ mc->mc_dbflag = NULL; /* ...and &dst->mt_dbflags[i] */ if ((mx = mc->mc_xcursor) != NULL) { *(MDB_xcursor *)(bk+1) = *mx; mx->mx_cursor.mc_txn = NULL; /* ...and dst. */ } mc->mc_next = dst->mt_cursors[i]; dst->mt_cursors[i] = mc; } } } return MDB_SUCCESS; } /** Close this write txn's cursors, give parent txn's cursors back to parent. * @param[in] txn the transaction handle. * @param[in] merge true to keep changes to parent cursors, false to revert. * @return 0 on success, non-zero on failure. */ static void mdb_cursors_close(MDB_txn *txn, unsigned merge) { MDB_cursor **cursors = txn->mt_cursors, *mc, *next, *bk; MDB_xcursor *mx; int i; for (i = txn->mt_numdbs; --i >= 0; ) { for (mc = cursors[i]; mc; mc = next) { next = mc->mc_next; if ((bk = mc->mc_backup) != NULL) { if (merge) { /* Commit changes to parent txn */ mc->mc_next = bk->mc_next; mc->mc_backup = bk->mc_backup; mc->mc_txn = bk->mc_txn; mc->mc_db = bk->mc_db; mc->mc_dbflag = bk->mc_dbflag; if ((mx = mc->mc_xcursor) != NULL) mx->mx_cursor.mc_txn = bk->mc_txn; } else { /* Abort nested txn */ *mc = *bk; if ((mx = mc->mc_xcursor) != NULL) *mx = *(MDB_xcursor *)(bk+1); } mc = bk; } /* Only malloced cursors are permanently tracked. */ free(mc); } cursors[i] = NULL; } } #if !(MDB_PIDLOCK) /* Currently the same as defined(_WIN32) */ enum Pidlock_op { Pidset, Pidcheck }; #else enum Pidlock_op { Pidset = F_SETLK, Pidcheck = F_GETLK }; #endif /** Set or check a pid lock. Set returns 0 on success. * Check returns 0 if the process is certainly dead, nonzero if it may * be alive (the lock exists or an error happened so we do not know). * * On Windows Pidset is a no-op, we merely check for the existence * of the process with the given pid. On POSIX we use a single byte * lock on the lockfile, set at an offset equal to the pid. */ static int mdb_reader_pid(MDB_env *env, enum Pidlock_op op, MDB_PID_T pid) { #if !(MDB_PIDLOCK) /* Currently the same as defined(_WIN32) */ int ret = 0; HANDLE h; if (op == Pidcheck) { h = OpenProcess(env->me_pidquery, FALSE, pid); /* No documented "no such process" code, but other program use this: */ if (!h) return ErrCode() != ERROR_INVALID_PARAMETER; /* A process exists until all handles to it close. Has it exited? */ ret = WaitForSingleObject(h, 0) != 0; CloseHandle(h); } return ret; #else for (;;) { int rc; struct flock lock_info; memset(&lock_info, 0, sizeof(lock_info)); lock_info.l_type = F_WRLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = pid; lock_info.l_len = 1; if ((rc = fcntl(env->me_lfd, op, &lock_info)) == 0) { if (op == F_GETLK && lock_info.l_type != F_UNLCK) rc = -1; } else if ((rc = ErrCode()) == EINTR) { continue; } return rc; } #endif } /** Common code for #mdb_txn_begin() and #mdb_txn_renew(). * @param[in] txn the transaction handle to initialize * @return 0 on success, non-zero on failure. */ static int mdb_txn_renew0(MDB_txn *txn) { MDB_env *env = txn->mt_env; MDB_txninfo *ti = env->me_txns; MDB_meta *meta; unsigned int i, nr, flags = txn->mt_flags; uint16_t x; int rc, new_notls = 0; if ((flags &= MDB_TXN_RDONLY) != 0) { if (!ti) { meta = mdb_env_pick_meta(env); txn->mt_txnid = meta->mm_txnid; txn->mt_u.reader = NULL; } else { MDB_reader *r = (env->me_flags & MDB_NOTLS) ? txn->mt_u.reader : pthread_getspecific(env->me_txkey); if (r) { if (r->mr_pid != env->me_pid || r->mr_txnid != (txnid_t)-1) return MDB_BAD_RSLOT; } else { MDB_PID_T pid = env->me_pid; MDB_THR_T tid = pthread_self(); mdb_mutexref_t rmutex = env->me_rmutex; if (!env->me_live_reader) { rc = mdb_reader_pid(env, Pidset, pid); if (rc) return rc; env->me_live_reader = 1; } if (LOCK_MUTEX(rc, env, rmutex)) return rc; nr = ti->mti_numreaders; for (i=0; imti_readers[i].mr_pid == 0) break; if (i == env->me_maxreaders) { UNLOCK_MUTEX(rmutex); return MDB_READERS_FULL; } r = &ti->mti_readers[i]; /* Claim the reader slot, carefully since other code * uses the reader table un-mutexed: First reset the * slot, next publish it in mti_numreaders. After * that, it is safe for mdb_env_close() to touch it. * When it will be closed, we can finally claim it. */ r->mr_pid = 0; r->mr_txnid = (txnid_t)-1; r->mr_tid = tid; if (i == nr) ti->mti_numreaders = ++nr; env->me_close_readers = nr; r->mr_pid = pid; UNLOCK_MUTEX(rmutex); new_notls = (env->me_flags & MDB_NOTLS); if (!new_notls && (rc=pthread_setspecific(env->me_txkey, r))) { r->mr_pid = 0; return rc; } } do /* LY: Retry on a race, ITS#7970. */ r->mr_txnid = ti->mti_txnid; while(r->mr_txnid != ti->mti_txnid); txn->mt_txnid = r->mr_txnid; txn->mt_u.reader = r; meta = env->me_metas[txn->mt_txnid & 1]; } } else { /* Not yet touching txn == env->me_txn0, it may be active */ if (ti) { if (LOCK_MUTEX(rc, env, env->me_wmutex)) return rc; txn->mt_txnid = ti->mti_txnid; meta = env->me_metas[txn->mt_txnid & 1]; } else { meta = mdb_env_pick_meta(env); txn->mt_txnid = meta->mm_txnid; } txn->mt_txnid++; #if MDB_DEBUG if (txn->mt_txnid == mdb_debug_start) mdb_debug = 1; #endif txn->mt_child = NULL; txn->mt_loose_pgs = NULL; txn->mt_loose_count = 0; txn->mt_dirty_room = MDB_IDL_UM_MAX; txn->mt_u.dirty_list = env->me_dirty_list; txn->mt_u.dirty_list[0].mid = 0; txn->mt_free_pgs = env->me_free_pgs; txn->mt_free_pgs[0] = 0; txn->mt_spill_pgs = NULL; env->me_txn = txn; memcpy(txn->mt_dbiseqs, env->me_dbiseqs, env->me_maxdbs * sizeof(unsigned int)); } /* Copy the DB info and flags */ memcpy(txn->mt_dbs, meta->mm_dbs, CORE_DBS * sizeof(MDB_db)); /* Moved to here to avoid a data race in read TXNs */ txn->mt_next_pgno = meta->mm_last_pg+1; txn->mt_flags = flags; /* Setup db info */ txn->mt_numdbs = env->me_numdbs; for (i=CORE_DBS; imt_numdbs; i++) { x = env->me_dbflags[i]; txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS; txn->mt_dbflags[i] = (x & MDB_VALID) ? DB_VALID|DB_USRVALID|DB_STALE : 0; } txn->mt_dbflags[MAIN_DBI] = DB_VALID|DB_USRVALID; txn->mt_dbflags[FREE_DBI] = DB_VALID; if (env->me_flags & MDB_FATAL_ERROR) { DPUTS("environment had fatal error, must shutdown!"); rc = MDB_PANIC; } else if (env->me_maxpg < txn->mt_next_pgno) { rc = MDB_MAP_RESIZED; } else { return MDB_SUCCESS; } mdb_txn_end(txn, new_notls /*0 or MDB_END_SLOT*/ | MDB_END_FAIL_BEGIN); return rc; } int mdb_txn_renew(MDB_txn *txn) { int rc; if (!txn || !F_ISSET(txn->mt_flags, MDB_TXN_RDONLY|MDB_TXN_FINISHED)) return EINVAL; rc = mdb_txn_renew0(txn); if (rc == MDB_SUCCESS) { DPRINTF(("renew txn %"Z"u%c %p on mdbenv %p, root page %"Z"u", txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w', (void *)txn, (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root)); } return rc; } int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret) { MDB_txn *txn; MDB_ntxn *ntxn; int rc, size, tsize; flags &= MDB_TXN_BEGIN_FLAGS; flags |= env->me_flags & MDB_WRITEMAP; if (env->me_flags & MDB_RDONLY & ~flags) /* write txn in RDONLY env */ return EACCES; if (parent) { /* Nested transactions: Max 1 child, write txns only, no writemap */ flags |= parent->mt_flags; if (flags & (MDB_RDONLY|MDB_WRITEMAP|MDB_TXN_BLOCKED)) { return (parent->mt_flags & MDB_TXN_RDONLY) ? EINVAL : MDB_BAD_TXN; } /* Child txns save MDB_pgstate and use own copy of cursors */ size = env->me_maxdbs * (sizeof(MDB_db)+sizeof(MDB_cursor *)+1); size += tsize = sizeof(MDB_ntxn); } else if (flags & MDB_RDONLY) { size = env->me_maxdbs * (sizeof(MDB_db)+1); size += tsize = sizeof(MDB_txn); } else { /* Reuse preallocated write txn. However, do not touch it until * mdb_txn_renew0() succeeds, since it currently may be active. */ txn = env->me_txn0; goto renew; } if ((txn = calloc(1, size)) == NULL) { DPRINTF(("calloc: %s", strerror(errno))); return ENOMEM; } txn->mt_dbxs = env->me_dbxs; /* static */ txn->mt_dbs = (MDB_db *) ((char *)txn + tsize); txn->mt_dbflags = (unsigned char *)txn + size - env->me_maxdbs; txn->mt_flags = flags; txn->mt_env = env; if (parent) { unsigned int i; txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs); txn->mt_dbiseqs = parent->mt_dbiseqs; txn->mt_u.dirty_list = malloc(sizeof(MDB_ID2)*MDB_IDL_UM_SIZE); if (!txn->mt_u.dirty_list || !(txn->mt_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX))) { free(txn->mt_u.dirty_list); free(txn); return ENOMEM; } txn->mt_txnid = parent->mt_txnid; txn->mt_dirty_room = parent->mt_dirty_room; txn->mt_u.dirty_list[0].mid = 0; txn->mt_spill_pgs = NULL; txn->mt_next_pgno = parent->mt_next_pgno; parent->mt_flags |= MDB_TXN_HAS_CHILD; parent->mt_child = txn; txn->mt_parent = parent; txn->mt_numdbs = parent->mt_numdbs; memcpy(txn->mt_dbs, parent->mt_dbs, txn->mt_numdbs * sizeof(MDB_db)); /* Copy parent's mt_dbflags, but clear DB_NEW */ for (i=0; imt_numdbs; i++) txn->mt_dbflags[i] = parent->mt_dbflags[i] & ~DB_NEW; rc = 0; ntxn = (MDB_ntxn *)txn; ntxn->mnt_pgstate = env->me_pgstate; /* save parent me_pghead & co */ if (env->me_pghead) { size = MDB_IDL_SIZEOF(env->me_pghead); env->me_pghead = mdb_midl_alloc(env->me_pghead[0]); if (env->me_pghead) memcpy(env->me_pghead, ntxn->mnt_pgstate.mf_pghead, size); else rc = ENOMEM; } if (!rc) rc = mdb_cursor_shadow(parent, txn); if (rc) mdb_txn_end(txn, MDB_END_FAIL_BEGINCHILD); } else { /* MDB_RDONLY */ txn->mt_dbiseqs = env->me_dbiseqs; renew: rc = mdb_txn_renew0(txn); } if (rc) { if (txn != env->me_txn0) free(txn); } else { txn->mt_flags |= flags; /* could not change txn=me_txn0 earlier */ *ret = txn; DPRINTF(("begin txn %"Z"u%c %p on mdbenv %p, root page %"Z"u", txn->mt_txnid, (flags & MDB_RDONLY) ? 'r' : 'w', (void *) txn, (void *) env, txn->mt_dbs[MAIN_DBI].md_root)); } return rc; } MDB_env * mdb_txn_env(MDB_txn *txn) { if(!txn) return NULL; return txn->mt_env; } size_t mdb_txn_id(MDB_txn *txn) { if(!txn) return 0; return txn->mt_txnid; } /** Export or close DBI handles opened in this txn. */ static void mdb_dbis_update(MDB_txn *txn, int keep) { int i; MDB_dbi n = txn->mt_numdbs; MDB_env *env = txn->mt_env; unsigned char *tdbflags = txn->mt_dbflags; for (i = n; --i >= CORE_DBS;) { if (tdbflags[i] & DB_NEW) { if (keep) { env->me_dbflags[i] = txn->mt_dbs[i].md_flags | MDB_VALID; } else { char *ptr = env->me_dbxs[i].md_name.mv_data; if (ptr) { env->me_dbxs[i].md_name.mv_data = NULL; env->me_dbxs[i].md_name.mv_size = 0; env->me_dbflags[i] = 0; env->me_dbiseqs[i]++; free(ptr); } } } } if (keep && env->me_numdbs < n) env->me_numdbs = n; } /** End a transaction, except successful commit of a nested transaction. * May be called twice for readonly txns: First reset it, then abort. * @param[in] txn the transaction handle to end * @param[in] mode why and how to end the transaction */ static void mdb_txn_end(MDB_txn *txn, unsigned mode) { MDB_env *env = txn->mt_env; #if MDB_DEBUG static const char *const names[] = MDB_END_NAMES; #endif /* Export or close DBI handles opened in this txn */ mdb_dbis_update(txn, mode & MDB_END_UPDATE); DPRINTF(("%s txn %"Z"u%c %p on mdbenv %p, root page %"Z"u", names[mode & MDB_END_OPMASK], txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w', (void *) txn, (void *)env, txn->mt_dbs[MAIN_DBI].md_root)); if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) { if (txn->mt_u.reader) { txn->mt_u.reader->mr_txnid = (txnid_t)-1; if (!(env->me_flags & MDB_NOTLS)) { txn->mt_u.reader = NULL; /* txn does not own reader */ } else if (mode & MDB_END_SLOT) { txn->mt_u.reader->mr_pid = 0; txn->mt_u.reader = NULL; } /* else txn owns the slot until it does MDB_END_SLOT */ } txn->mt_numdbs = 0; /* prevent further DBI activity */ txn->mt_flags |= MDB_TXN_FINISHED; } else if (!F_ISSET(txn->mt_flags, MDB_TXN_FINISHED)) { pgno_t *pghead = env->me_pghead; if (!(mode & MDB_END_UPDATE)) /* !(already closed cursors) */ mdb_cursors_close(txn, 0); if (!(env->me_flags & MDB_WRITEMAP)) { mdb_dlist_free(txn); } txn->mt_numdbs = 0; txn->mt_flags = MDB_TXN_FINISHED; if (!txn->mt_parent) { mdb_midl_shrink(&txn->mt_free_pgs); env->me_free_pgs = txn->mt_free_pgs; /* me_pgstate: */ env->me_pghead = NULL; env->me_pglast = 0; env->me_txn = NULL; mode = 0; /* txn == env->me_txn0, do not free() it */ /* The writer mutex was locked in mdb_txn_begin. */ if (env->me_txns) UNLOCK_MUTEX(env->me_wmutex); } else { txn->mt_parent->mt_child = NULL; txn->mt_parent->mt_flags &= ~MDB_TXN_HAS_CHILD; env->me_pgstate = ((MDB_ntxn *)txn)->mnt_pgstate; mdb_midl_free(txn->mt_free_pgs); mdb_midl_free(txn->mt_spill_pgs); free(txn->mt_u.dirty_list); } mdb_midl_free(pghead); } if (mode & MDB_END_FREE) free(txn); } void mdb_txn_reset(MDB_txn *txn) { if (txn == NULL) return; /* This call is only valid for read-only txns */ if (!(txn->mt_flags & MDB_TXN_RDONLY)) return; mdb_txn_end(txn, MDB_END_RESET); } void mdb_txn_abort(MDB_txn *txn) { if (txn == NULL) return; if (txn->mt_child) mdb_txn_abort(txn->mt_child); mdb_txn_end(txn, MDB_END_ABORT|MDB_END_SLOT|MDB_END_FREE); } /** Save the freelist as of this transaction to the freeDB. * This changes the freelist. Keep trying until it stabilizes. */ static int mdb_freelist_save(MDB_txn *txn) { /* env->me_pghead[] can grow and shrink during this call. * env->me_pglast and txn->mt_free_pgs[] can only grow. * Page numbers cannot disappear from txn->mt_free_pgs[]. */ MDB_cursor mc; MDB_env *env = txn->mt_env; int rc, maxfree_1pg = env->me_maxfree_1pg, more = 1; txnid_t pglast = 0, head_id = 0; pgno_t freecnt = 0, *free_pgs, *mop; ssize_t head_room = 0, total_room = 0, mop_len, clean_limit; mdb_cursor_init(&mc, txn, FREE_DBI, NULL); if (env->me_pghead) { /* Make sure first page of freeDB is touched and on freelist */ rc = mdb_page_search(&mc, NULL, MDB_PS_FIRST|MDB_PS_MODIFY); if (rc && rc != MDB_NOTFOUND) return rc; } if (!env->me_pghead && txn->mt_loose_pgs) { /* Put loose page numbers in mt_free_pgs, since * we may be unable to return them to me_pghead. */ MDB_page *mp = txn->mt_loose_pgs; if ((rc = mdb_midl_need(&txn->mt_free_pgs, txn->mt_loose_count)) != 0) return rc; for (; mp; mp = NEXT_LOOSE_PAGE(mp)) mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno); txn->mt_loose_pgs = NULL; txn->mt_loose_count = 0; } /* MDB_RESERVE cancels meminit in ovpage malloc (when no WRITEMAP) */ clean_limit = (env->me_flags & (MDB_NOMEMINIT|MDB_WRITEMAP)) ? SSIZE_MAX : maxfree_1pg; for (;;) { /* Come back here after each Put() in case freelist changed */ MDB_val key, data; pgno_t *pgs; ssize_t j; /* If using records from freeDB which we have not yet * deleted, delete them and any we reserved for me_pghead. */ while (pglast < env->me_pglast) { rc = mdb_cursor_first(&mc, &key, NULL); if (rc) return rc; pglast = head_id = *(txnid_t *)key.mv_data; total_room = head_room = 0; mdb_tassert(txn, pglast <= env->me_pglast); rc = mdb_cursor_del(&mc, 0); if (rc) return rc; } /* Save the IDL of pages freed by this txn, to a single record */ if (freecnt < txn->mt_free_pgs[0]) { if (!freecnt) { /* Make sure last page of freeDB is touched and on freelist */ rc = mdb_page_search(&mc, NULL, MDB_PS_LAST|MDB_PS_MODIFY); if (rc && rc != MDB_NOTFOUND) return rc; } free_pgs = txn->mt_free_pgs; /* Write to last page of freeDB */ key.mv_size = sizeof(txn->mt_txnid); key.mv_data = &txn->mt_txnid; do { freecnt = free_pgs[0]; data.mv_size = MDB_IDL_SIZEOF(free_pgs); rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE); if (rc) return rc; /* Retry if mt_free_pgs[] grew during the Put() */ free_pgs = txn->mt_free_pgs; } while (freecnt < free_pgs[0]); mdb_midl_sort(free_pgs); memcpy(data.mv_data, free_pgs, data.mv_size); #if (MDB_DEBUG) > 1 { unsigned int i = free_pgs[0]; DPRINTF(("IDL write txn %"Z"u root %"Z"u num %u", txn->mt_txnid, txn->mt_dbs[FREE_DBI].md_root, i)); for (; i; i--) DPRINTF(("IDL %"Z"u", free_pgs[i])); } #endif continue; } mop = env->me_pghead; mop_len = (mop ? mop[0] : 0) + txn->mt_loose_count; /* Reserve records for me_pghead[]. Split it if multi-page, * to avoid searching freeDB for a page range. Use keys in * range [1,me_pglast]: Smaller than txnid of oldest reader. */ if (total_room >= mop_len) { if (total_room == mop_len || --more < 0) break; } else if (head_room >= maxfree_1pg && head_id > 1) { /* Keep current record (overflow page), add a new one */ head_id--; head_room = 0; } /* (Re)write {key = head_id, IDL length = head_room} */ total_room -= head_room; head_room = mop_len - total_room; if (head_room > maxfree_1pg && head_id > 1) { /* Overflow multi-page for part of me_pghead */ head_room /= head_id; /* amortize page sizes */ head_room += maxfree_1pg - head_room % (maxfree_1pg + 1); } else if (head_room < 0) { /* Rare case, not bothering to delete this record */ head_room = 0; } key.mv_size = sizeof(head_id); key.mv_data = &head_id; data.mv_size = (head_room + 1) * sizeof(pgno_t); rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE); if (rc) return rc; /* IDL is initially empty, zero out at least the length */ pgs = (pgno_t *)data.mv_data; j = head_room > clean_limit ? head_room : 0; do { pgs[j] = 0; } while (--j >= 0); total_room += head_room; } /* Return loose page numbers to me_pghead, though usually none are * left at this point. The pages themselves remain in dirty_list. */ if (txn->mt_loose_pgs) { MDB_page *mp = txn->mt_loose_pgs; unsigned count = txn->mt_loose_count; MDB_IDL loose; /* Room for loose pages + temp IDL with same */ if ((rc = mdb_midl_need(&env->me_pghead, 2*count+1)) != 0) return rc; mop = env->me_pghead; loose = mop + MDB_IDL_ALLOCLEN(mop) - count; for (count = 0; mp; mp = NEXT_LOOSE_PAGE(mp)) loose[ ++count ] = mp->mp_pgno; loose[0] = count; mdb_midl_sort(loose); mdb_midl_xmerge(mop, loose); txn->mt_loose_pgs = NULL; txn->mt_loose_count = 0; mop_len = mop[0]; } /* Fill in the reserved me_pghead records */ rc = MDB_SUCCESS; if (mop_len) { MDB_val key, data; mop += mop_len; rc = mdb_cursor_first(&mc, &key, &data); for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) { txnid_t id = *(txnid_t *)key.mv_data; ssize_t len = (ssize_t)(data.mv_size / sizeof(MDB_ID)) - 1; MDB_ID save; mdb_tassert(txn, len >= 0 && id <= env->me_pglast); key.mv_data = &id; if (len > mop_len) { len = mop_len; data.mv_size = (len + 1) * sizeof(MDB_ID); } data.mv_data = mop -= len; save = mop[0]; mop[0] = len; rc = mdb_cursor_put(&mc, &key, &data, MDB_CURRENT); mop[0] = save; if (rc || !(mop_len -= len)) break; } } return rc; } /** Flush (some) dirty pages to the map, after clearing their dirty flag. * @param[in] txn the transaction that's being committed * @param[in] keep number of initial pages in dirty_list to keep dirty. * @return 0 on success, non-zero on failure. */ static int mdb_page_flush(MDB_txn *txn, int keep) { MDB_env *env = txn->mt_env; MDB_ID2L dl = txn->mt_u.dirty_list; unsigned psize = env->me_psize, j; int i, pagecount = dl[0].mid, rc; size_t size = 0, pos = 0; pgno_t pgno = 0; MDB_page *dp = NULL; #ifdef _WIN32 OVERLAPPED ov; #else struct iovec iov[MDB_COMMIT_PAGES]; ssize_t wpos = 0, wsize = 0, wres; size_t next_pos = 1; /* impossible pos, so pos != next_pos */ int n = 0; #endif j = i = keep; if (env->me_flags & MDB_WRITEMAP) { /* Clear dirty flags */ while (++i <= pagecount) { dp = dl[i].mptr; /* Don't flush this page yet */ if (dp->mp_flags & (P_LOOSE|P_KEEP)) { dp->mp_flags &= ~P_KEEP; dl[++j] = dl[i]; continue; } dp->mp_flags &= ~P_DIRTY; } goto done; } /* Write the pages */ for (;;) { if (++i <= pagecount) { dp = dl[i].mptr; /* Don't flush this page yet */ if (dp->mp_flags & (P_LOOSE|P_KEEP)) { dp->mp_flags &= ~P_KEEP; dl[i].mid = 0; continue; } pgno = dl[i].mid; /* clear dirty flag */ dp->mp_flags &= ~P_DIRTY; pos = pgno * psize; size = psize; if (IS_OVERFLOW(dp)) size *= dp->mp_pages; } #ifdef _WIN32 else break; /* Windows actually supports scatter/gather I/O, but only on * unbuffered file handles. Since we're relying on the OS page * cache for all our data, that's self-defeating. So we just * write pages one at a time. We use the ov structure to set * the write offset, to at least save the overhead of a Seek * system call. */ DPRINTF(("committing page %"Z"u", pgno)); memset(&ov, 0, sizeof(ov)); ov.Offset = pos & 0xffffffff; ov.OffsetHigh = pos >> 16 >> 16; if (!WriteFile(env->me_fd, dp, size, NULL, &ov)) { rc = ErrCode(); DPRINTF(("WriteFile: %d", rc)); return rc; } #else /* Write up to MDB_COMMIT_PAGES dirty pages at a time. */ if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) { if (n) { retry_write: /* Write previous page(s) */ #ifdef MDB_USE_PWRITEV wres = pwritev(env->me_fd, iov, n, wpos); #else if (n == 1) { wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos); } else { retry_seek: if (lseek(env->me_fd, wpos, SEEK_SET) == -1) { rc = ErrCode(); if (rc == EINTR) goto retry_seek; DPRINTF(("lseek: %s", strerror(rc))); return rc; } wres = writev(env->me_fd, iov, n); } #endif if (wres != wsize) { if (wres < 0) { rc = ErrCode(); if (rc == EINTR) goto retry_write; DPRINTF(("Write error: %s", strerror(rc))); } else { rc = EIO; /* TODO: Use which error code? */ DPUTS("short write, filesystem full?"); } return rc; } n = 0; } if (i > pagecount) break; wpos = pos; wsize = 0; } DPRINTF(("committing page %"Z"u", pgno)); next_pos = pos + size; iov[n].iov_len = size; iov[n].iov_base = (char *)dp; wsize += size; n++; #endif /* _WIN32 */ } /* MIPS has cache coherency issues, this is a no-op everywhere else * Note: for any size >= on-chip cache size, entire on-chip cache is * flushed. */ CACHEFLUSH(env->me_map, txn->mt_next_pgno * env->me_psize, DCACHE); for (i = keep; ++i <= pagecount; ) { dp = dl[i].mptr; /* This is a page we skipped above */ if (!dl[i].mid) { dl[++j] = dl[i]; dl[j].mid = dp->mp_pgno; continue; } mdb_dpage_free(env, dp); } done: i--; txn->mt_dirty_room += i - j; dl[0].mid = j; return MDB_SUCCESS; } int mdb_txn_commit(MDB_txn *txn) { int rc; unsigned int i, end_mode; MDB_env *env; if (txn == NULL) return EINVAL; /* mdb_txn_end() mode for a commit which writes nothing */ end_mode = MDB_END_EMPTY_COMMIT|MDB_END_UPDATE|MDB_END_SLOT|MDB_END_FREE; if (txn->mt_child) { rc = mdb_txn_commit(txn->mt_child); if (rc) goto fail; } env = txn->mt_env; if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) { goto done; } if (txn->mt_flags & (MDB_TXN_FINISHED|MDB_TXN_ERROR)) { DPUTS("txn has failed/finished, can't commit"); if (txn->mt_parent) txn->mt_parent->mt_flags |= MDB_TXN_ERROR; rc = MDB_BAD_TXN; goto fail; } if (txn->mt_parent) { MDB_txn *parent = txn->mt_parent; MDB_page **lp; MDB_ID2L dst, src; MDB_IDL pspill; unsigned x, y, len, ps_len; /* Append our free list to parent's */ rc = mdb_midl_append_list(&parent->mt_free_pgs, txn->mt_free_pgs); if (rc) goto fail; mdb_midl_free(txn->mt_free_pgs); /* Failures after this must either undo the changes * to the parent or set MDB_TXN_ERROR in the parent. */ parent->mt_next_pgno = txn->mt_next_pgno; parent->mt_flags = txn->mt_flags; /* Merge our cursors into parent's and close them */ mdb_cursors_close(txn, 1); /* Update parent's DB table. */ memcpy(parent->mt_dbs, txn->mt_dbs, txn->mt_numdbs * sizeof(MDB_db)); parent->mt_numdbs = txn->mt_numdbs; parent->mt_dbflags[FREE_DBI] = txn->mt_dbflags[FREE_DBI]; parent->mt_dbflags[MAIN_DBI] = txn->mt_dbflags[MAIN_DBI]; for (i=CORE_DBS; imt_numdbs; i++) { /* preserve parent's DB_NEW status */ x = parent->mt_dbflags[i] & DB_NEW; parent->mt_dbflags[i] = txn->mt_dbflags[i] | x; } dst = parent->mt_u.dirty_list; src = txn->mt_u.dirty_list; /* Remove anything in our dirty list from parent's spill list */ if ((pspill = parent->mt_spill_pgs) && (ps_len = pspill[0])) { x = y = ps_len; pspill[0] = (pgno_t)-1; /* Mark our dirty pages as deleted in parent spill list */ for (i=0, len=src[0].mid; ++i <= len; ) { MDB_ID pn = src[i].mid << 1; while (pn > pspill[x]) x--; if (pn == pspill[x]) { pspill[x] = 1; y = --x; } } /* Squash deleted pagenums if we deleted any */ for (x=y; ++x <= ps_len; ) if (!(pspill[x] & 1)) pspill[++y] = pspill[x]; pspill[0] = y; } /* Find len = length of merging our dirty list with parent's */ x = dst[0].mid; dst[0].mid = 0; /* simplify loops */ if (parent->mt_parent) { len = x + src[0].mid; y = mdb_mid2l_search(src, dst[x].mid + 1) - 1; for (i = x; y && i; y--) { pgno_t yp = src[y].mid; while (yp < dst[i].mid) i--; if (yp == dst[i].mid) { i--; len--; } } } else { /* Simplify the above for single-ancestor case */ len = MDB_IDL_UM_MAX - txn->mt_dirty_room; } /* Merge our dirty list with parent's */ y = src[0].mid; for (i = len; y; dst[i--] = src[y--]) { pgno_t yp = src[y].mid; while (yp < dst[x].mid) dst[i--] = dst[x--]; if (yp == dst[x].mid) free(dst[x--].mptr); } mdb_tassert(txn, i == x); dst[0].mid = len; free(txn->mt_u.dirty_list); parent->mt_dirty_room = txn->mt_dirty_room; if (txn->mt_spill_pgs) { if (parent->mt_spill_pgs) { /* TODO: Prevent failure here, so parent does not fail */ rc = mdb_midl_append_list(&parent->mt_spill_pgs, txn->mt_spill_pgs); if (rc) parent->mt_flags |= MDB_TXN_ERROR; mdb_midl_free(txn->mt_spill_pgs); mdb_midl_sort(parent->mt_spill_pgs); } else { parent->mt_spill_pgs = txn->mt_spill_pgs; } } /* Append our loose page list to parent's */ for (lp = &parent->mt_loose_pgs; *lp; lp = &NEXT_LOOSE_PAGE(lp)) ; *lp = txn->mt_loose_pgs; parent->mt_loose_count += txn->mt_loose_count; parent->mt_child = NULL; mdb_midl_free(((MDB_ntxn *)txn)->mnt_pgstate.mf_pghead); free(txn); return rc; } if (txn != env->me_txn) { DPUTS("attempt to commit unknown transaction"); rc = EINVAL; goto fail; } mdb_cursors_close(txn, 0); if (!txn->mt_u.dirty_list[0].mid && !(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS))) goto done; DPRINTF(("committing txn %"Z"u %p on mdbenv %p, root page %"Z"u", txn->mt_txnid, (void*)txn, (void*)env, txn->mt_dbs[MAIN_DBI].md_root)); /* Update DB root pointers */ if (txn->mt_numdbs > CORE_DBS) { MDB_cursor mc; MDB_dbi i; MDB_val data; data.mv_size = sizeof(MDB_db); mdb_cursor_init(&mc, txn, MAIN_DBI, NULL); for (i = CORE_DBS; i < txn->mt_numdbs; i++) { if (txn->mt_dbflags[i] & DB_DIRTY) { if (TXN_DBI_CHANGED(txn, i)) { rc = MDB_BAD_DBI; goto fail; } data.mv_data = &txn->mt_dbs[i]; rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data, F_SUBDATA); if (rc) goto fail; } } } rc = mdb_freelist_save(txn); if (rc) goto fail; mdb_midl_free(env->me_pghead); env->me_pghead = NULL; mdb_midl_shrink(&txn->mt_free_pgs); #if (MDB_DEBUG) > 2 mdb_audit(txn); #endif if ((rc = mdb_page_flush(txn, 0))) goto fail; if (!F_ISSET(txn->mt_flags, MDB_TXN_NOSYNC) && (rc = mdb_env_sync(env, 0))) goto fail; if ((rc = mdb_env_write_meta(txn))) goto fail; end_mode = MDB_END_COMMITTED|MDB_END_UPDATE; done: mdb_txn_end(txn, end_mode); return MDB_SUCCESS; fail: mdb_txn_abort(txn); return rc; } /** Read the environment parameters of a DB environment before * mapping it into memory. * @param[in] env the environment handle * @param[out] meta address of where to store the meta information * @return 0 on success, non-zero on failure. */ static int ESECT mdb_env_read_header(MDB_env *env, MDB_meta *meta) { MDB_metabuf pbuf; MDB_page *p; MDB_meta *m; int i, rc, off; enum { Size = sizeof(pbuf) }; /* We don't know the page size yet, so use a minimum value. * Read both meta pages so we can use the latest one. */ for (i=off=0; imm_psize) { #ifdef _WIN32 DWORD len; OVERLAPPED ov; memset(&ov, 0, sizeof(ov)); ov.Offset = off; rc = ReadFile(env->me_fd, &pbuf, Size, &len, &ov) ? (int)len : -1; if (rc == -1 && ErrCode() == ERROR_HANDLE_EOF) rc = 0; #else rc = pread(env->me_fd, &pbuf, Size, off); #endif if (rc != Size) { if (rc == 0 && off == 0) return ENOENT; rc = rc < 0 ? (int) ErrCode() : MDB_INVALID; DPRINTF(("read: %s", mdb_strerror(rc))); return rc; } p = (MDB_page *)&pbuf; if (!F_ISSET(p->mp_flags, P_META)) { DPRINTF(("page %"Z"u not a meta page", p->mp_pgno)); return MDB_INVALID; } m = METADATA(p); if (m->mm_magic != MDB_MAGIC) { DPUTS("meta has invalid magic"); return MDB_INVALID; } if (m->mm_version != MDB_DATA_VERSION) { DPRINTF(("database is version %u, expected version %u", m->mm_version, MDB_DATA_VERSION)); return MDB_VERSION_MISMATCH; } if (off == 0 || m->mm_txnid > meta->mm_txnid) *meta = *m; } return 0; } /** Fill in most of the zeroed #MDB_meta for an empty database environment */ static void ESECT mdb_env_init_meta0(MDB_env *env, MDB_meta *meta) { meta->mm_magic = MDB_MAGIC; meta->mm_version = MDB_DATA_VERSION; meta->mm_mapsize = env->me_mapsize; meta->mm_psize = env->me_psize; meta->mm_last_pg = NUM_METAS-1; meta->mm_flags = env->me_flags & 0xffff; meta->mm_flags |= MDB_INTEGERKEY; /* this is mm_dbs[FREE_DBI].md_flags */ meta->mm_dbs[FREE_DBI].md_root = P_INVALID; meta->mm_dbs[MAIN_DBI].md_root = P_INVALID; } /** Write the environment parameters of a freshly created DB environment. * @param[in] env the environment handle * @param[in] meta the #MDB_meta to write * @return 0 on success, non-zero on failure. */ static int ESECT mdb_env_init_meta(MDB_env *env, MDB_meta *meta) { MDB_page *p, *q; int rc; unsigned int psize; #ifdef _WIN32 DWORD len; OVERLAPPED ov; memset(&ov, 0, sizeof(ov)); #define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \ ov.Offset = pos; \ rc = WriteFile(fd, ptr, size, &len, &ov); } while(0) #else int len; #define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \ len = pwrite(fd, ptr, size, pos); \ if (len == -1 && ErrCode() == EINTR) continue; \ rc = (len >= 0); break; } while(1) #endif DPUTS("writing new meta page"); psize = env->me_psize; p = calloc(NUM_METAS, psize); if (!p) return ENOMEM; p->mp_pgno = 0; p->mp_flags = P_META; *(MDB_meta *)METADATA(p) = *meta; q = (MDB_page *)((char *)p + psize); q->mp_pgno = 1; q->mp_flags = P_META; *(MDB_meta *)METADATA(q) = *meta; DO_PWRITE(rc, env->me_fd, p, psize * NUM_METAS, len, 0); if (!rc) rc = ErrCode(); else if ((unsigned) len == psize * NUM_METAS) rc = MDB_SUCCESS; else rc = ENOSPC; free(p); return rc; } /** Update the environment info to commit a transaction. * @param[in] txn the transaction that's being committed * @return 0 on success, non-zero on failure. */ static int mdb_env_write_meta(MDB_txn *txn) { MDB_env *env; MDB_meta meta, metab, *mp; unsigned flags; size_t mapsize; off_t off; int rc, len, toggle; char *ptr; HANDLE mfd; #ifdef _WIN32 OVERLAPPED ov; #else int r2; #endif toggle = txn->mt_txnid & 1; DPRINTF(("writing meta page %d for root page %"Z"u", toggle, txn->mt_dbs[MAIN_DBI].md_root)); env = txn->mt_env; flags = txn->mt_flags & env->me_flags; mp = env->me_metas[toggle]; mapsize = env->me_metas[toggle ^ 1]->mm_mapsize; /* Persist any increases of mapsize config */ if (mapsize < env->me_mapsize) mapsize = env->me_mapsize; if (flags & MDB_WRITEMAP) { mp->mm_mapsize = mapsize; mp->mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI]; mp->mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI]; mp->mm_last_pg = txn->mt_next_pgno - 1; #if defined(__SUNPRO_C) __machine_rw_barrier(); #elif defined(__GNUC__) #if (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) && /* TODO: portability */ \ !(defined(__i386__) || defined(__x86_64__)) /* LY: issue a memory barrier, if not x86. ITS#7969 */ __sync_synchronize(); #endif #endif mp->mm_txnid = txn->mt_txnid; if (!(flags & (MDB_NOMETASYNC|MDB_NOSYNC))) { unsigned meta_size = env->me_psize; rc = (env->me_flags & MDB_MAPASYNC) ? MS_ASYNC : MS_SYNC; ptr = (char *)mp - PAGEHDRSZ; #ifndef _WIN32 /* POSIX msync() requires ptr = start of OS page */ r2 = (ptr - env->me_map) & (env->me_os_psize - 1); ptr -= r2; meta_size += r2; #endif if (MDB_MSYNC(ptr, meta_size, rc)) { rc = ErrCode(); goto fail; } } goto done; } metab.mm_txnid = mp->mm_txnid; metab.mm_last_pg = mp->mm_last_pg; meta.mm_mapsize = mapsize; meta.mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI]; meta.mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI]; meta.mm_last_pg = txn->mt_next_pgno - 1; meta.mm_txnid = txn->mt_txnid; off = offsetof(MDB_meta, mm_mapsize); ptr = (char *)&meta + off; len = sizeof(MDB_meta) - off; off += (char *)mp - env->me_map; /* Write to the SYNC fd */ mfd = (flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ? env->me_fd : env->me_mfd; #ifdef _WIN32 { memset(&ov, 0, sizeof(ov)); ov.Offset = off; if (!WriteFile(mfd, ptr, len, (DWORD *)&rc, &ov)) rc = -1; } #else retry_write: rc = pwrite(mfd, ptr, len, off); #endif if (rc != len) { rc = rc < 0 ? ErrCode() : EIO; #ifndef _WIN32 if (rc == EINTR) goto retry_write; #endif DPUTS("write failed, disk error?"); /* On a failure, the pagecache still contains the new data. * Write some old data back, to prevent it from being used. * Use the non-SYNC fd; we know it will fail anyway. */ meta.mm_last_pg = metab.mm_last_pg; meta.mm_txnid = metab.mm_txnid; #ifdef _WIN32 memset(&ov, 0, sizeof(ov)); ov.Offset = off; WriteFile(env->me_fd, ptr, len, NULL, &ov); #else r2 = pwrite(env->me_fd, ptr, len, off); (void)r2; /* Silence warnings. We don't care about pwrite's return value */ #endif fail: env->me_flags |= MDB_FATAL_ERROR; return rc; } /* MIPS has cache coherency issues, this is a no-op everywhere else */ CACHEFLUSH(env->me_map + off, len, DCACHE); done: /* Memory ordering issues are irrelevant; since the entire writer * is wrapped by wmutex, all of these changes will become visible * after the wmutex is unlocked. Since the DB is multi-version, * readers will get consistent data regardless of how fresh or * how stale their view of these values is. */ if (env->me_txns) env->me_txns->mti_txnid = txn->mt_txnid; return MDB_SUCCESS; } /** Check both meta pages to see which one is newer. * @param[in] env the environment handle * @return newest #MDB_meta. */ static MDB_meta * mdb_env_pick_meta(const MDB_env *env) { MDB_meta *const *metas = env->me_metas; return metas[ metas[0]->mm_txnid < metas[1]->mm_txnid ]; } int ESECT mdb_env_create(MDB_env **env) { MDB_env *e; e = calloc(1, sizeof(MDB_env)); if (!e) return ENOMEM; e->me_maxreaders = DEFAULT_READERS; e->me_maxdbs = e->me_numdbs = CORE_DBS; e->me_fd = INVALID_HANDLE_VALUE; e->me_lfd = INVALID_HANDLE_VALUE; e->me_mfd = INVALID_HANDLE_VALUE; #ifdef MDB_USE_POSIX_SEM e->me_rmutex = SEM_FAILED; e->me_wmutex = SEM_FAILED; #elif defined MDB_USE_SYSV_SEM e->me_rmutex->semid = -1; e->me_wmutex->semid = -1; #endif e->me_pid = getpid(); GET_PAGESIZE(e->me_os_psize); VGMEMP_CREATE(e,0,0); *env = e; return MDB_SUCCESS; } static int ESECT mdb_env_map(MDB_env *env, void *addr) { MDB_page *p; unsigned int flags = env->me_flags; #ifdef _WIN32 int rc; HANDLE mh; LONG sizelo, sizehi; size_t msize; if (flags & MDB_RDONLY) { /* Don't set explicit map size, use whatever exists */ msize = 0; sizelo = 0; sizehi = 0; } else { msize = env->me_mapsize; sizelo = msize & 0xffffffff; sizehi = msize >> 16 >> 16; /* only needed on Win64 */ /* Windows won't create mappings for zero length files. * and won't map more than the file size. * Just set the maxsize right now. */ if (SetFilePointer(env->me_fd, sizelo, &sizehi, 0) != (DWORD)sizelo || !SetEndOfFile(env->me_fd) || SetFilePointer(env->me_fd, 0, NULL, 0) != 0) return ErrCode(); } mh = CreateFileMapping(env->me_fd, NULL, flags & MDB_WRITEMAP ? PAGE_READWRITE : PAGE_READONLY, sizehi, sizelo, NULL); if (!mh) return ErrCode(); env->me_map = MapViewOfFileEx(mh, flags & MDB_WRITEMAP ? FILE_MAP_WRITE : FILE_MAP_READ, 0, 0, msize, addr); rc = env->me_map ? 0 : ErrCode(); CloseHandle(mh); if (rc) return rc; #else int prot = PROT_READ; if (flags & MDB_WRITEMAP) { prot |= PROT_WRITE; if (ftruncate(env->me_fd, env->me_mapsize) < 0) return ErrCode(); } env->me_map = mmap(addr, env->me_mapsize, prot, MAP_SHARED, env->me_fd, 0); if (env->me_map == MAP_FAILED) { env->me_map = NULL; return ErrCode(); } if (flags & MDB_NORDAHEAD) { /* Turn off readahead. It's harmful when the DB is larger than RAM. */ #ifdef MADV_RANDOM madvise(env->me_map, env->me_mapsize, MADV_RANDOM); #else #ifdef POSIX_MADV_RANDOM posix_madvise(env->me_map, env->me_mapsize, POSIX_MADV_RANDOM); #endif /* POSIX_MADV_RANDOM */ #endif /* MADV_RANDOM */ } #endif /* _WIN32 */ /* Can happen because the address argument to mmap() is just a * hint. mmap() can pick another, e.g. if the range is in use. * The MAP_FIXED flag would prevent that, but then mmap could * instead unmap existing pages to make room for the new map. */ if (addr && env->me_map != addr) return EBUSY; /* TODO: Make a new MDB_* error code? */ p = (MDB_page *)env->me_map; env->me_metas[0] = METADATA(p); env->me_metas[1] = (MDB_meta *)((char *)env->me_metas[0] + env->me_psize); return MDB_SUCCESS; } int ESECT mdb_env_set_mapsize(MDB_env *env, size_t size) { /* If env is already open, caller is responsible for making * sure there are no active txns. */ if (env->me_map) { int rc; MDB_meta *meta; void *old; if (env->me_txn) return EINVAL; meta = mdb_env_pick_meta(env); if (!size) size = meta->mm_mapsize; { /* Silently round up to minimum if the size is too small */ size_t minsize = (meta->mm_last_pg + 1) * env->me_psize; if (size < minsize) size = minsize; } munmap(env->me_map, env->me_mapsize); env->me_mapsize = size; old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL; rc = mdb_env_map(env, old); if (rc) return rc; } env->me_mapsize = size; if (env->me_psize) env->me_maxpg = env->me_mapsize / env->me_psize; return MDB_SUCCESS; } int ESECT mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs) { if (env->me_map) return EINVAL; env->me_maxdbs = dbs + CORE_DBS; return MDB_SUCCESS; } int ESECT mdb_env_set_maxreaders(MDB_env *env, unsigned int readers) { if (env->me_map || readers < 1) return EINVAL; env->me_maxreaders = readers; return MDB_SUCCESS; } int ESECT mdb_env_get_maxreaders(MDB_env *env, unsigned int *readers) { if (!env || !readers) return EINVAL; *readers = env->me_maxreaders; return MDB_SUCCESS; } static int ESECT mdb_fsize(HANDLE fd, size_t *size) { #ifdef _WIN32 LARGE_INTEGER fsize; if (!GetFileSizeEx(fd, &fsize)) return ErrCode(); *size = fsize.QuadPart; #else struct stat st; if (fstat(fd, &st)) return ErrCode(); *size = st.st_size; #endif return MDB_SUCCESS; } #ifdef BROKEN_FDATASYNC #include #include #endif /** Further setup required for opening an LMDB environment */ static int ESECT mdb_env_open2(MDB_env *env) { unsigned int flags = env->me_flags; int i, newenv = 0, rc; MDB_meta meta; #ifdef _WIN32 /* See if we should use QueryLimited */ rc = GetVersion(); if ((rc & 0xff) > 5) env->me_pidquery = MDB_PROCESS_QUERY_LIMITED_INFORMATION; else env->me_pidquery = PROCESS_QUERY_INFORMATION; #endif /* _WIN32 */ #ifdef BROKEN_FDATASYNC /* ext3/ext4 fdatasync is broken on some older Linux kernels. * https://lkml.org/lkml/2012/9/3/83 * Kernels after 3.6-rc6 are known good. * https://lkml.org/lkml/2012/9/10/556 * See if the DB is on ext3/ext4, then check for new enough kernel * Kernels 2.6.32.60, 2.6.34.15, 3.2.30, and 3.5.4 are also known * to be patched. */ { struct statfs st; fstatfs(env->me_fd, &st); while (st.f_type == 0xEF53) { struct utsname uts; int i; uname(&uts); if (uts.release[0] < '3') { if (!strncmp(uts.release, "2.6.32.", 7)) { i = atoi(uts.release+7); if (i >= 60) break; /* 2.6.32.60 and newer is OK */ } else if (!strncmp(uts.release, "2.6.34.", 7)) { i = atoi(uts.release+7); if (i >= 15) break; /* 2.6.34.15 and newer is OK */ } } else if (uts.release[0] == '3') { i = atoi(uts.release+2); if (i > 5) break; /* 3.6 and newer is OK */ if (i == 5) { i = atoi(uts.release+4); if (i >= 4) break; /* 3.5.4 and newer is OK */ } else if (i == 2) { i = atoi(uts.release+4); if (i >= 30) break; /* 3.2.30 and newer is OK */ } } else { /* 4.x and newer is OK */ break; } env->me_flags |= MDB_FSYNCONLY; break; } } #endif if ((i = mdb_env_read_header(env, &meta)) != 0) { if (i != ENOENT) return i; DPUTS("new mdbenv"); newenv = 1; env->me_psize = env->me_os_psize; if (env->me_psize > MAX_PAGESIZE) env->me_psize = MAX_PAGESIZE; memset(&meta, 0, sizeof(meta)); mdb_env_init_meta0(env, &meta); meta.mm_mapsize = DEFAULT_MAPSIZE; } else { env->me_psize = meta.mm_psize; } /* Was a mapsize configured? */ if (!env->me_mapsize) { env->me_mapsize = meta.mm_mapsize; } { /* Make sure mapsize >= committed data size. Even when using * mm_mapsize, which could be broken in old files (ITS#7789). */ size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize; if (env->me_mapsize < minsize) env->me_mapsize = minsize; } meta.mm_mapsize = env->me_mapsize; if (newenv && !(flags & MDB_FIXEDMAP)) { /* mdb_env_map() may grow the datafile. Write the metapages * first, so the file will be valid if initialization fails. * Except with FIXEDMAP, since we do not yet know mm_address. * We could fill in mm_address later, but then a different * program might end up doing that - one with a memory layout * and map address which does not suit the main program. */ rc = mdb_env_init_meta(env, &meta); if (rc) return rc; newenv = 0; } rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta.mm_address : NULL); if (rc) return rc; if (newenv) { if (flags & MDB_FIXEDMAP) meta.mm_address = env->me_map; i = mdb_env_init_meta(env, &meta); if (i != MDB_SUCCESS) { return i; } } env->me_maxfree_1pg = (env->me_psize - PAGEHDRSZ) / sizeof(pgno_t) - 1; env->me_nodemax = (((env->me_psize - PAGEHDRSZ) / MDB_MINKEYS) & -2) - sizeof(indx_t); #if !(MDB_MAXKEYSIZE) env->me_maxkey = env->me_nodemax - (NODESIZE + sizeof(MDB_db)); #endif env->me_maxpg = env->me_mapsize / env->me_psize; #if MDB_DEBUG { MDB_meta *meta = mdb_env_pick_meta(env); MDB_db *db = &meta->mm_dbs[MAIN_DBI]; DPRINTF(("opened database version %u, pagesize %u", meta->mm_version, env->me_psize)); DPRINTF(("using meta page %d", (int) (meta->mm_txnid & 1))); DPRINTF(("depth: %u", db->md_depth)); DPRINTF(("entries: %"Z"u", db->md_entries)); DPRINTF(("branch pages: %"Z"u", db->md_branch_pages)); DPRINTF(("leaf pages: %"Z"u", db->md_leaf_pages)); DPRINTF(("overflow pages: %"Z"u", db->md_overflow_pages)); DPRINTF(("root: %"Z"u", db->md_root)); } #endif return MDB_SUCCESS; } /** Release a reader thread's slot in the reader lock table. * This function is called automatically when a thread exits. * @param[in] ptr This points to the slot in the reader lock table. */ static void mdb_env_reader_dest(void *ptr) { MDB_reader *reader = ptr; reader->mr_pid = 0; } #ifdef _WIN32 /** Junk for arranging thread-specific callbacks on Windows. This is * necessarily platform and compiler-specific. Windows supports up * to 1088 keys. Let's assume nobody opens more than 64 environments * in a single process, for now. They can override this if needed. */ #ifndef MAX_TLS_KEYS #define MAX_TLS_KEYS 64 #endif static pthread_key_t mdb_tls_keys[MAX_TLS_KEYS]; static int mdb_tls_nkeys; static void NTAPI mdb_tls_callback(PVOID module, DWORD reason, PVOID ptr) { int i; switch(reason) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: for (i=0; ime_txns->mti_txnid = meta->mm_txnid; #ifdef _WIN32 { OVERLAPPED ov; /* First acquire a shared lock. The Unlock will * then release the existing exclusive lock. */ memset(&ov, 0, sizeof(ov)); if (!LockFileEx(env->me_lfd, 0, 0, 1, 0, &ov)) { rc = ErrCode(); } else { UnlockFile(env->me_lfd, 0, 0, 1, 0); *excl = 0; } } #else { struct flock lock_info; /* The shared lock replaces the existing lock */ memset((void *)&lock_info, 0, sizeof(lock_info)); lock_info.l_type = F_RDLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = 0; lock_info.l_len = 1; while ((rc = fcntl(env->me_lfd, F_SETLK, &lock_info)) && (rc = ErrCode()) == EINTR) ; *excl = rc ? -1 : 0; /* error may mean we lost the lock */ } #endif return rc; } /** Try to get exclusive lock, otherwise shared. * Maintain *excl = -1: no/unknown lock, 0: shared, 1: exclusive. */ static int ESECT mdb_env_excl_lock(MDB_env *env, int *excl) { int rc = 0; #ifdef _WIN32 if (LockFile(env->me_lfd, 0, 0, 1, 0)) { *excl = 1; } else { OVERLAPPED ov; memset(&ov, 0, sizeof(ov)); if (LockFileEx(env->me_lfd, 0, 0, 1, 0, &ov)) { *excl = 0; } else { rc = ErrCode(); } } #else struct flock lock_info; memset((void *)&lock_info, 0, sizeof(lock_info)); lock_info.l_type = F_WRLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = 0; lock_info.l_len = 1; while ((rc = fcntl(env->me_lfd, F_SETLK, &lock_info)) && (rc = ErrCode()) == EINTR) ; if (!rc) { *excl = 1; } else # ifndef MDB_USE_POSIX_MUTEX if (*excl < 0) /* always true when MDB_USE_POSIX_MUTEX */ # endif { lock_info.l_type = F_RDLCK; while ((rc = fcntl(env->me_lfd, F_SETLKW, &lock_info)) && (rc = ErrCode()) == EINTR) ; if (rc == 0) *excl = 0; } #endif return rc; } #ifdef MDB_USE_HASH /* * hash_64 - 64 bit Fowler/Noll/Vo-0 FNV-1a hash code * * @(#) $Revision: 5.1 $ * @(#) $Id: hash_64a.c,v 5.1 2009/06/30 09:01:38 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64a.c,v $ * * http://www.isthe.com/chongo/tech/comp/fnv/index.html * *** * * Please do not copyright this code. This code is in the public domain. * * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * By: * chongo /\oo/\ * http://www.isthe.com/chongo/ * * Share and Enjoy! :-) */ typedef unsigned long long mdb_hash_t; #define MDB_HASH_INIT ((mdb_hash_t)0xcbf29ce484222325ULL) /** perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer * @param[in] val value to hash * @param[in] hval initial value for hash * @return 64 bit hash * * NOTE: To use the recommended 64 bit FNV-1a hash, use MDB_HASH_INIT as the * hval arg on the first call. */ static mdb_hash_t mdb_hash_val(MDB_val *val, mdb_hash_t hval) { unsigned char *s = (unsigned char *)val->mv_data; /* unsigned string */ unsigned char *end = s + val->mv_size; /* * FNV-1a hash each octet of the string */ while (s < end) { /* xor the bottom with the current octet */ hval ^= (mdb_hash_t)*s++; /* multiply by the 64 bit FNV magic prime mod 2^64 */ hval += (hval << 1) + (hval << 4) + (hval << 5) + (hval << 7) + (hval << 8) + (hval << 40); } /* return our new hash value */ return hval; } /** Hash the string and output the encoded hash. * This uses modified RFC1924 Ascii85 encoding to accommodate systems with * very short name limits. We don't care about the encoding being reversible, * we just want to preserve as many bits of the input as possible in a * small printable string. * @param[in] str string to hash * @param[out] encbuf an array of 11 chars to hold the hash */ static const char mdb_a85[]= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"; static void ESECT mdb_pack85(unsigned long l, char *out) { int i; for (i=0; i<5; i++) { *out++ = mdb_a85[l % 85]; l /= 85; } } static void ESECT mdb_hash_enc(MDB_val *val, char *encbuf) { mdb_hash_t h = mdb_hash_val(val, MDB_HASH_INIT); mdb_pack85(h, encbuf); mdb_pack85(h>>32, encbuf+5); encbuf[10] = '\0'; } #endif /** Open and/or initialize the lock region for the environment. * @param[in] env The LMDB environment. * @param[in] lpath The pathname of the file used for the lock region. * @param[in] mode The Unix permissions for the file, if we create it. * @param[in,out] excl In -1, out lock type: -1 none, 0 shared, 1 exclusive * @return 0 on success, non-zero on failure. */ static int ESECT mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) { #ifdef _WIN32 # define MDB_ERRCODE_ROFS ERROR_WRITE_PROTECT #else # define MDB_ERRCODE_ROFS EROFS #ifdef O_CLOEXEC /* Linux: Open file and set FD_CLOEXEC atomically */ # define MDB_CLOEXEC O_CLOEXEC #else int fdflags; # define MDB_CLOEXEC 0 #endif #endif #ifdef MDB_USE_SYSV_SEM int semid; union semun semu; #endif int rc; off_t size, rsize; #ifdef _WIN32 env->me_lfd = CreateFileA(lpath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); #else env->me_lfd = open(lpath, O_RDWR|O_CREAT|MDB_CLOEXEC, mode); #endif if (env->me_lfd == INVALID_HANDLE_VALUE) { rc = ErrCode(); if (rc == MDB_ERRCODE_ROFS && (env->me_flags & MDB_RDONLY)) { return MDB_SUCCESS; } goto fail_errno; } #if ! ((MDB_CLOEXEC) || defined(_WIN32)) /* Lose record locks when exec*() */ if ((fdflags = fcntl(env->me_lfd, F_GETFD) | FD_CLOEXEC) >= 0) fcntl(env->me_lfd, F_SETFD, fdflags); #endif if (!(env->me_flags & MDB_NOTLS)) { rc = pthread_key_create(&env->me_txkey, mdb_env_reader_dest); if (rc) goto fail; env->me_flags |= MDB_ENV_TXKEY; #ifdef _WIN32 /* Windows TLS callbacks need help finding their TLS info. */ if (mdb_tls_nkeys >= MAX_TLS_KEYS) { rc = MDB_TLS_FULL; goto fail; } mdb_tls_keys[mdb_tls_nkeys++] = env->me_txkey; #endif } /* Try to get exclusive lock. If we succeed, then * nobody is using the lock region and we should initialize it. */ if ((rc = mdb_env_excl_lock(env, excl))) goto fail; #ifdef _WIN32 size = GetFileSize(env->me_lfd, NULL); #else size = lseek(env->me_lfd, 0, SEEK_END); if (size == -1) goto fail_errno; #endif rsize = (env->me_maxreaders-1) * sizeof(MDB_reader) + sizeof(MDB_txninfo); if (size < rsize && *excl > 0) { #ifdef _WIN32 if (SetFilePointer(env->me_lfd, rsize, NULL, FILE_BEGIN) != (DWORD)rsize || !SetEndOfFile(env->me_lfd)) goto fail_errno; #else if (ftruncate(env->me_lfd, rsize) != 0) goto fail_errno; #endif } else { rsize = size; size = rsize - sizeof(MDB_txninfo); env->me_maxreaders = size/sizeof(MDB_reader) + 1; } { #ifdef _WIN32 HANDLE mh; mh = CreateFileMapping(env->me_lfd, NULL, PAGE_READWRITE, 0, 0, NULL); if (!mh) goto fail_errno; env->me_txns = MapViewOfFileEx(mh, FILE_MAP_WRITE, 0, 0, rsize, NULL); CloseHandle(mh); if (!env->me_txns) goto fail_errno; #else void *m = mmap(NULL, rsize, PROT_READ|PROT_WRITE, MAP_SHARED, env->me_lfd, 0); if (m == MAP_FAILED) goto fail_errno; env->me_txns = m; #endif } if (*excl > 0) { #ifdef _WIN32 BY_HANDLE_FILE_INFORMATION stbuf; struct { DWORD volume; DWORD nhigh; DWORD nlow; } idbuf; MDB_val val; char encbuf[11]; if (!mdb_sec_inited) { InitializeSecurityDescriptor(&mdb_null_sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&mdb_null_sd, TRUE, 0, FALSE); mdb_all_sa.nLength = sizeof(SECURITY_ATTRIBUTES); mdb_all_sa.bInheritHandle = FALSE; mdb_all_sa.lpSecurityDescriptor = &mdb_null_sd; mdb_sec_inited = 1; } if (!GetFileInformationByHandle(env->me_lfd, &stbuf)) goto fail_errno; idbuf.volume = stbuf.dwVolumeSerialNumber; idbuf.nhigh = stbuf.nFileIndexHigh; idbuf.nlow = stbuf.nFileIndexLow; val.mv_data = &idbuf; val.mv_size = sizeof(idbuf); mdb_hash_enc(&val, encbuf); sprintf(env->me_txns->mti_rmname, "Global\\MDBr%s", encbuf); sprintf(env->me_txns->mti_wmname, "Global\\MDBw%s", encbuf); env->me_rmutex = CreateMutexA(&mdb_all_sa, FALSE, env->me_txns->mti_rmname); if (!env->me_rmutex) goto fail_errno; env->me_wmutex = CreateMutexA(&mdb_all_sa, FALSE, env->me_txns->mti_wmname); if (!env->me_wmutex) goto fail_errno; #elif defined(MDB_USE_POSIX_SEM) struct stat stbuf; struct { dev_t dev; ino_t ino; } idbuf; MDB_val val; char encbuf[11]; #if defined(__NetBSD__) #define MDB_SHORT_SEMNAMES 1 /* limited to 14 chars */ #endif if (fstat(env->me_lfd, &stbuf)) goto fail_errno; idbuf.dev = stbuf.st_dev; idbuf.ino = stbuf.st_ino; val.mv_data = &idbuf; val.mv_size = sizeof(idbuf); mdb_hash_enc(&val, encbuf); #ifdef MDB_SHORT_SEMNAMES encbuf[9] = '\0'; /* drop name from 15 chars to 14 chars */ #endif sprintf(env->me_txns->mti_rmname, "/MDBr%s", encbuf); sprintf(env->me_txns->mti_wmname, "/MDBw%s", encbuf); /* Clean up after a previous run, if needed: Try to * remove both semaphores before doing anything else. */ sem_unlink(env->me_txns->mti_rmname); sem_unlink(env->me_txns->mti_wmname); env->me_rmutex = sem_open(env->me_txns->mti_rmname, O_CREAT|O_EXCL, mode, 1); if (env->me_rmutex == SEM_FAILED) goto fail_errno; env->me_wmutex = sem_open(env->me_txns->mti_wmname, O_CREAT|O_EXCL, mode, 1); if (env->me_wmutex == SEM_FAILED) goto fail_errno; #elif defined(MDB_USE_SYSV_SEM) unsigned short vals[2] = {1, 1}; key_t key = ftok(lpath, 'M'); if (key == -1) goto fail_errno; semid = semget(key, 2, (mode & 0777) | IPC_CREAT); if (semid < 0) goto fail_errno; semu.array = vals; if (semctl(semid, 0, SETALL, semu) < 0) goto fail_errno; env->me_txns->mti_semid = semid; #else /* MDB_USE_POSIX_MUTEX: */ pthread_mutexattr_t mattr; if ((rc = pthread_mutexattr_init(&mattr)) || (rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED)) #ifdef MDB_ROBUST_SUPPORTED || (rc = pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST)) #endif || (rc = pthread_mutex_init(env->me_txns->mti_rmutex, &mattr)) || (rc = pthread_mutex_init(env->me_txns->mti_wmutex, &mattr))) goto fail; pthread_mutexattr_destroy(&mattr); #endif /* _WIN32 || ... */ env->me_txns->mti_magic = MDB_MAGIC; env->me_txns->mti_format = MDB_LOCK_FORMAT; env->me_txns->mti_txnid = 0; env->me_txns->mti_numreaders = 0; } else { #ifdef MDB_USE_SYSV_SEM struct semid_ds buf; #endif if (env->me_txns->mti_magic != MDB_MAGIC) { DPUTS("lock region has invalid magic"); rc = MDB_INVALID; goto fail; } if (env->me_txns->mti_format != MDB_LOCK_FORMAT) { DPRINTF(("lock region has format+version 0x%x, expected 0x%x", env->me_txns->mti_format, MDB_LOCK_FORMAT)); rc = MDB_VERSION_MISMATCH; goto fail; } rc = ErrCode(); if (rc && rc != EACCES && rc != EAGAIN) { goto fail; } #ifdef _WIN32 env->me_rmutex = OpenMutexA(SYNCHRONIZE, FALSE, env->me_txns->mti_rmname); if (!env->me_rmutex) goto fail_errno; env->me_wmutex = OpenMutexA(SYNCHRONIZE, FALSE, env->me_txns->mti_wmname); if (!env->me_wmutex) goto fail_errno; #elif defined(MDB_USE_POSIX_SEM) env->me_rmutex = sem_open(env->me_txns->mti_rmname, 0); if (env->me_rmutex == SEM_FAILED) goto fail_errno; env->me_wmutex = sem_open(env->me_txns->mti_wmname, 0); if (env->me_wmutex == SEM_FAILED) goto fail_errno; #elif defined(MDB_USE_SYSV_SEM) semid = env->me_txns->mti_semid; semu.buf = &buf; /* check for read access */ if (semctl(semid, 0, IPC_STAT, semu) < 0) goto fail_errno; /* check for write access */ if (semctl(semid, 0, IPC_SET, semu) < 0) goto fail_errno; #endif } #ifdef MDB_USE_SYSV_SEM env->me_rmutex->semid = semid; env->me_wmutex->semid = semid; env->me_rmutex->semnum = 0; env->me_wmutex->semnum = 1; env->me_rmutex->locked = &env->me_txns->mti_rlocked; env->me_wmutex->locked = &env->me_txns->mti_wlocked; #endif return MDB_SUCCESS; fail_errno: rc = ErrCode(); fail: return rc; } /** The name of the lock file in the DB environment */ #define LOCKNAME "/lock.mdb" /** The name of the data file in the DB environment */ #define DATANAME "/data.mdb" /** The suffix of the lock file when no subdir is used */ #define LOCKSUFF "-lock" /** Only a subset of the @ref mdb_env flags can be changed * at runtime. Changing other flags requires closing the * environment and re-opening it with the new flags. */ #define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC|MDB_NOMEMINIT) #define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY| \ MDB_WRITEMAP|MDB_NOTLS|MDB_NOLOCK|MDB_NORDAHEAD) #if VALID_FLAGS & PERSISTENT_FLAGS & (CHANGEABLE|CHANGELESS) # error "Persistent DB flags & env flags overlap, but both go in mm_flags" #endif int ESECT mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode) { int oflags, rc, len, excl = -1; char *lpath, *dpath; if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS))) return EINVAL; len = strlen(path); if (flags & MDB_NOSUBDIR) { rc = len + sizeof(LOCKSUFF) + len + 1; } else { rc = len + sizeof(LOCKNAME) + len + sizeof(DATANAME); } lpath = malloc(rc); if (!lpath) return ENOMEM; if (flags & MDB_NOSUBDIR) { dpath = lpath + len + sizeof(LOCKSUFF); sprintf(lpath, "%s" LOCKSUFF, path); strcpy(dpath, path); } else { dpath = lpath + len + sizeof(LOCKNAME); sprintf(lpath, "%s" LOCKNAME, path); sprintf(dpath, "%s" DATANAME, path); } rc = MDB_SUCCESS; flags |= env->me_flags; if (flags & MDB_RDONLY) { /* silently ignore WRITEMAP when we're only getting read access */ flags &= ~MDB_WRITEMAP; } else { if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) && (env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2))))) rc = ENOMEM; } env->me_flags = flags |= MDB_ENV_ACTIVE; if (rc) goto leave; env->me_path = strdup(path); env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDB_dbx)); env->me_dbflags = calloc(env->me_maxdbs, sizeof(uint16_t)); env->me_dbiseqs = calloc(env->me_maxdbs, sizeof(unsigned int)); if (!(env->me_dbxs && env->me_path && env->me_dbflags && env->me_dbiseqs)) { rc = ENOMEM; goto leave; } env->me_dbxs[FREE_DBI].md_cmp = mdb_cmp_long; /* aligned MDB_INTEGERKEY */ /* For RDONLY, get lockfile after we know datafile exists */ if (!(flags & (MDB_RDONLY|MDB_NOLOCK))) { rc = mdb_env_setup_locks(env, lpath, mode, &excl); if (rc) goto leave; } #ifdef _WIN32 if (F_ISSET(flags, MDB_RDONLY)) { oflags = GENERIC_READ; len = OPEN_EXISTING; } else { oflags = GENERIC_READ|GENERIC_WRITE; len = OPEN_ALWAYS; } mode = FILE_ATTRIBUTE_NORMAL; env->me_fd = CreateFileA(dpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len, mode, NULL); #else if (F_ISSET(flags, MDB_RDONLY)) oflags = O_RDONLY; else oflags = O_RDWR | O_CREAT; env->me_fd = open(dpath, oflags, mode); #endif if (env->me_fd == INVALID_HANDLE_VALUE) { rc = ErrCode(); goto leave; } if ((flags & (MDB_RDONLY|MDB_NOLOCK)) == MDB_RDONLY) { rc = mdb_env_setup_locks(env, lpath, mode, &excl); if (rc) goto leave; } if ((rc = mdb_env_open2(env)) == MDB_SUCCESS) { if (flags & (MDB_RDONLY|MDB_WRITEMAP)) { env->me_mfd = env->me_fd; } else { /* Synchronous fd for meta writes. Needed even with * MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset. */ #ifdef _WIN32 len = OPEN_EXISTING; env->me_mfd = CreateFileA(dpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len, mode | FILE_FLAG_WRITE_THROUGH, NULL); #else oflags &= ~O_CREAT; env->me_mfd = open(dpath, oflags | MDB_DSYNC, mode); #endif if (env->me_mfd == INVALID_HANDLE_VALUE) { rc = ErrCode(); goto leave; } } DPRINTF(("opened dbenv %p", (void *) env)); if (excl > 0) { rc = mdb_env_share_locks(env, &excl); if (rc) goto leave; } if (!(flags & MDB_RDONLY)) { MDB_txn *txn; int tsize = sizeof(MDB_txn), size = tsize + env->me_maxdbs * (sizeof(MDB_db)+sizeof(MDB_cursor *)+sizeof(unsigned int)+1); if ((env->me_pbuf = calloc(1, env->me_psize)) && (txn = calloc(1, size))) { txn->mt_dbs = (MDB_db *)((char *)txn + tsize); txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs); txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs); txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs); txn->mt_env = env; txn->mt_dbxs = env->me_dbxs; txn->mt_flags = MDB_TXN_FINISHED; env->me_txn0 = txn; } else { rc = ENOMEM; } } } leave: if (rc) { mdb_env_close0(env, excl); } free(lpath); return rc; } /** Destroy resources from mdb_env_open(), clear our readers & DBIs */ static void ESECT mdb_env_close0(MDB_env *env, int excl) { int i; if (!(env->me_flags & MDB_ENV_ACTIVE)) return; /* Doing this here since me_dbxs may not exist during mdb_env_close */ if (env->me_dbxs) { for (i = env->me_maxdbs; --i >= CORE_DBS; ) free(env->me_dbxs[i].md_name.mv_data); free(env->me_dbxs); } free(env->me_pbuf); free(env->me_dbiseqs); free(env->me_dbflags); free(env->me_path); free(env->me_dirty_list); free(env->me_txn0); mdb_midl_free(env->me_free_pgs); if (env->me_flags & MDB_ENV_TXKEY) { pthread_key_delete(env->me_txkey); #ifdef _WIN32 /* Delete our key from the global list */ for (i=0; ime_txkey) { mdb_tls_keys[i] = mdb_tls_keys[mdb_tls_nkeys-1]; mdb_tls_nkeys--; break; } #endif } if (env->me_map) { munmap(env->me_map, env->me_mapsize); } if (env->me_mfd != env->me_fd && env->me_mfd != INVALID_HANDLE_VALUE) (void) close(env->me_mfd); if (env->me_fd != INVALID_HANDLE_VALUE) (void) close(env->me_fd); if (env->me_txns) { MDB_PID_T pid = env->me_pid; /* Clearing readers is done in this function because * me_txkey with its destructor must be disabled first. * * We skip the the reader mutex, so we touch only * data owned by this process (me_close_readers and * our readers), and clear each reader atomically. */ for (i = env->me_close_readers; --i >= 0; ) if (env->me_txns->mti_readers[i].mr_pid == pid) env->me_txns->mti_readers[i].mr_pid = 0; #ifdef _WIN32 if (env->me_rmutex) { CloseHandle(env->me_rmutex); if (env->me_wmutex) CloseHandle(env->me_wmutex); } /* Windows automatically destroys the mutexes when * the last handle closes. */ #elif defined(MDB_USE_POSIX_SEM) if (env->me_rmutex != SEM_FAILED) { sem_close(env->me_rmutex); if (env->me_wmutex != SEM_FAILED) sem_close(env->me_wmutex); /* If we have the filelock: If we are the * only remaining user, clean up semaphores. */ if (excl == 0) mdb_env_excl_lock(env, &excl); if (excl > 0) { sem_unlink(env->me_txns->mti_rmname); sem_unlink(env->me_txns->mti_wmname); } } #elif defined(MDB_USE_SYSV_SEM) if (env->me_rmutex->semid != -1) { /* If we have the filelock: If we are the * only remaining user, clean up semaphores. */ if (excl == 0) mdb_env_excl_lock(env, &excl); if (excl > 0) semctl(env->me_rmutex->semid, 0, IPC_RMID); } #endif munmap((void *)env->me_txns, (env->me_maxreaders-1)*sizeof(MDB_reader)+sizeof(MDB_txninfo)); } if (env->me_lfd != INVALID_HANDLE_VALUE) { #ifdef _WIN32 if (excl >= 0) { /* Unlock the lockfile. Windows would have unlocked it * after closing anyway, but not necessarily at once. */ UnlockFile(env->me_lfd, 0, 0, 1, 0); } #endif (void) close(env->me_lfd); } env->me_flags &= ~(MDB_ENV_ACTIVE|MDB_ENV_TXKEY); } void ESECT mdb_env_close(MDB_env *env) { MDB_page *dp; if (env == NULL) return; VGMEMP_DESTROY(env); while ((dp = env->me_dpages) != NULL) { VGMEMP_DEFINED(&dp->mp_next, sizeof(dp->mp_next)); env->me_dpages = dp->mp_next; free(dp); } mdb_env_close0(env, 0); free(env); } /** Compare two items pointing at aligned size_t's */ static int mdb_cmp_long(const MDB_val *a, const MDB_val *b) { return (*(size_t *)a->mv_data < *(size_t *)b->mv_data) ? -1 : *(size_t *)a->mv_data > *(size_t *)b->mv_data; } /** Compare two items pointing at aligned unsigned int's. * * This is also set as #MDB_INTEGERDUP|#MDB_DUPFIXED's #MDB_dbx.%md_dcmp, * but #mdb_cmp_clong() is called instead if the data type is size_t. */ static int mdb_cmp_int(const MDB_val *a, const MDB_val *b) { return (*(unsigned int *)a->mv_data < *(unsigned int *)b->mv_data) ? -1 : *(unsigned int *)a->mv_data > *(unsigned int *)b->mv_data; } /** Compare two items pointing at unsigned ints of unknown alignment. * Nodes and keys are guaranteed to be 2-byte aligned. */ static int mdb_cmp_cint(const MDB_val *a, const MDB_val *b) { #if BYTE_ORDER == LITTLE_ENDIAN unsigned short *u, *c; int x; u = (unsigned short *) ((char *) a->mv_data + a->mv_size); c = (unsigned short *) ((char *) b->mv_data + a->mv_size); do { x = *--u - *--c; } while(!x && u > (unsigned short *)a->mv_data); return x; #else unsigned short *u, *c, *end; int x; end = (unsigned short *) ((char *) a->mv_data + a->mv_size); u = (unsigned short *)a->mv_data; c = (unsigned short *)b->mv_data; do { x = *u++ - *c++; } while(!x && u < end); return x; #endif } /** Compare two items lexically */ static int mdb_cmp_memn(const MDB_val *a, const MDB_val *b) { int diff; ssize_t len_diff; unsigned int len; len = a->mv_size; len_diff = (ssize_t) a->mv_size - (ssize_t) b->mv_size; if (len_diff > 0) { len = b->mv_size; len_diff = 1; } diff = memcmp(a->mv_data, b->mv_data, len); return diff ? diff : len_diff<0 ? -1 : len_diff; } /** Compare two items in reverse byte order */ static int mdb_cmp_memnr(const MDB_val *a, const MDB_val *b) { const unsigned char *p1, *p2, *p1_lim; ssize_t len_diff; int diff; p1_lim = (const unsigned char *)a->mv_data; p1 = (const unsigned char *)a->mv_data + a->mv_size; p2 = (const unsigned char *)b->mv_data + b->mv_size; len_diff = (ssize_t) a->mv_size - (ssize_t) b->mv_size; if (len_diff > 0) { p1_lim += len_diff; len_diff = 1; } while (p1 > p1_lim) { diff = *--p1 - *--p2; if (diff) return diff; } return len_diff<0 ? -1 : len_diff; } /** Search for key within a page, using binary search. * Returns the smallest entry larger or equal to the key. * If exactp is non-null, stores whether the found entry was an exact match * in *exactp (1 or 0). * Updates the cursor index with the index of the found entry. * If no entry larger or equal to the key is found, returns NULL. */ static MDB_node * mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp) { unsigned int i = 0, nkeys; int low, high; int rc = 0; MDB_page *mp = mc->mc_pg[mc->mc_top]; MDB_node *node = NULL; MDB_val nodekey; MDB_cmp_func *cmp; DKBUF; nkeys = NUMKEYS(mp); DPRINTF(("searching %u keys in %s %spage %"Z"u", nkeys, IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "", mdb_dbg_pgno(mp))); low = IS_LEAF(mp) ? 0 : 1; high = nkeys - 1; cmp = mc->mc_dbx->md_cmp; /* Branch pages have no data, so if using integer keys, * alignment is guaranteed. Use faster mdb_cmp_int. */ if (cmp == mdb_cmp_cint && IS_BRANCH(mp)) { if (NODEPTR(mp, 1)->mn_ksize == sizeof(size_t)) cmp = mdb_cmp_long; else cmp = mdb_cmp_int; } if (IS_LEAF2(mp)) { nodekey.mv_size = mc->mc_db->md_pad; node = NODEPTR(mp, 0); /* fake */ while (low <= high) { i = (low + high) >> 1; nodekey.mv_data = LEAF2KEY(mp, i, nodekey.mv_size); rc = cmp(key, &nodekey); DPRINTF(("found leaf index %u [%s], rc = %i", i, DKEY(&nodekey), rc)); if (rc == 0) break; if (rc > 0) low = i + 1; else high = i - 1; } } else { while (low <= high) { i = (low + high) >> 1; node = NODEPTR(mp, i); nodekey.mv_size = NODEKSZ(node); nodekey.mv_data = NODEKEY(node); rc = cmp(key, &nodekey); #if MDB_DEBUG if (IS_LEAF(mp)) DPRINTF(("found leaf index %u [%s], rc = %i", i, DKEY(&nodekey), rc)); else DPRINTF(("found branch index %u [%s -> %"Z"u], rc = %i", i, DKEY(&nodekey), NODEPGNO(node), rc)); #endif if (rc == 0) break; if (rc > 0) low = i + 1; else high = i - 1; } } if (rc > 0) { /* Found entry is less than the key. */ i++; /* Skip to get the smallest entry larger than key. */ if (!IS_LEAF2(mp)) node = NODEPTR(mp, i); } if (exactp) *exactp = (rc == 0 && nkeys > 0); /* store the key index */ mc->mc_ki[mc->mc_top] = i; if (i >= nkeys) /* There is no entry larger or equal to the key. */ return NULL; /* nodeptr is fake for LEAF2 */ return node; } #if 0 static void mdb_cursor_adjust(MDB_cursor *mc, func) { MDB_cursor *m2; for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) { if (m2->mc_pg[m2->mc_top] == mc->mc_pg[mc->mc_top]) { func(mc, m2); } } } #endif /** Pop a page off the top of the cursor's stack. */ static void mdb_cursor_pop(MDB_cursor *mc) { if (mc->mc_snum) { DPRINTF(("popping page %"Z"u off db %d cursor %p", mc->mc_pg[mc->mc_top]->mp_pgno, DDBI(mc), (void *) mc)); mc->mc_snum--; if (mc->mc_snum) mc->mc_top--; } } /** Push a page onto the top of the cursor's stack. */ static int mdb_cursor_push(MDB_cursor *mc, MDB_page *mp) { DPRINTF(("pushing page %"Z"u on db %d cursor %p", mp->mp_pgno, DDBI(mc), (void *) mc)); if (mc->mc_snum >= CURSOR_STACK) { mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return MDB_CURSOR_FULL; } mc->mc_top = mc->mc_snum++; mc->mc_pg[mc->mc_top] = mp; mc->mc_ki[mc->mc_top] = 0; return MDB_SUCCESS; } /** Find the address of the page corresponding to a given page number. * @param[in] txn the transaction for this access. * @param[in] pgno the page number for the page to retrieve. * @param[out] ret address of a pointer where the page's address will be stored. * @param[out] lvl dirty_list inheritance level of found page. 1=current txn, 0=mapped page. * @return 0 on success, non-zero on failure. */ static int mdb_page_get(MDB_txn *txn, pgno_t pgno, MDB_page **ret, int *lvl) { MDB_env *env = txn->mt_env; MDB_page *p = NULL; int level; if (! (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_WRITEMAP))) { MDB_txn *tx2 = txn; level = 1; do { MDB_ID2L dl = tx2->mt_u.dirty_list; unsigned x; /* Spilled pages were dirtied in this txn and flushed * because the dirty list got full. Bring this page * back in from the map (but don't unspill it here, * leave that unless page_touch happens again). */ if (tx2->mt_spill_pgs) { MDB_ID pn = pgno << 1; x = mdb_midl_search(tx2->mt_spill_pgs, pn); if (x <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[x] == pn) { p = (MDB_page *)(env->me_map + env->me_psize * pgno); goto done; } } if (dl[0].mid) { unsigned x = mdb_mid2l_search(dl, pgno); if (x <= dl[0].mid && dl[x].mid == pgno) { p = dl[x].mptr; goto done; } } level++; } while ((tx2 = tx2->mt_parent) != NULL); } if (pgno < txn->mt_next_pgno) { level = 0; p = (MDB_page *)(env->me_map + env->me_psize * pgno); } else { DPRINTF(("page %"Z"u not found", pgno)); txn->mt_flags |= MDB_TXN_ERROR; return MDB_PAGE_NOTFOUND; } done: *ret = p; if (lvl) *lvl = level; return MDB_SUCCESS; } /** Finish #mdb_page_search() / #mdb_page_search_lowest(). * The cursor is at the root page, set up the rest of it. */ static int mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) { MDB_page *mp = mc->mc_pg[mc->mc_top]; int rc; DKBUF; while (IS_BRANCH(mp)) { MDB_node *node; indx_t i; DPRINTF(("branch page %"Z"u has %u keys", mp->mp_pgno, NUMKEYS(mp))); mdb_cassert(mc, NUMKEYS(mp) > 1); DPRINTF(("found index 0 to page %"Z"u", NODEPGNO(NODEPTR(mp, 0)))); if (flags & (MDB_PS_FIRST|MDB_PS_LAST)) { i = 0; if (flags & MDB_PS_LAST) i = NUMKEYS(mp) - 1; } else { int exact; node = mdb_node_search(mc, key, &exact); if (node == NULL) i = NUMKEYS(mp) - 1; else { i = mc->mc_ki[mc->mc_top]; if (!exact) { mdb_cassert(mc, i > 0); i--; } } DPRINTF(("following index %u for key [%s]", i, DKEY(key))); } mdb_cassert(mc, i < NUMKEYS(mp)); node = NODEPTR(mp, i); if ((rc = mdb_page_get(mc->mc_txn, NODEPGNO(node), &mp, NULL)) != 0) return rc; mc->mc_ki[mc->mc_top] = i; if ((rc = mdb_cursor_push(mc, mp))) return rc; if (flags & MDB_PS_MODIFY) { if ((rc = mdb_page_touch(mc)) != 0) return rc; mp = mc->mc_pg[mc->mc_top]; } } if (!IS_LEAF(mp)) { DPRINTF(("internal error, index points to a %02X page!?", mp->mp_flags)); mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return MDB_CORRUPTED; } DPRINTF(("found leaf page %"Z"u for key [%s]", mp->mp_pgno, key ? DKEY(key) : "null")); mc->mc_flags |= C_INITIALIZED; mc->mc_flags &= ~C_EOF; return MDB_SUCCESS; } /** Search for the lowest key under the current branch page. * This just bypasses a NUMKEYS check in the current page * before calling mdb_page_search_root(), because the callers * are all in situations where the current page is known to * be underfilled. */ static int mdb_page_search_lowest(MDB_cursor *mc) { MDB_page *mp = mc->mc_pg[mc->mc_top]; MDB_node *node = NODEPTR(mp, 0); int rc; if ((rc = mdb_page_get(mc->mc_txn, NODEPGNO(node), &mp, NULL)) != 0) return rc; mc->mc_ki[mc->mc_top] = 0; if ((rc = mdb_cursor_push(mc, mp))) return rc; return mdb_page_search_root(mc, NULL, MDB_PS_FIRST); } /** Search for the page a given key should be in. * Push it and its parent pages on the cursor stack. * @param[in,out] mc the cursor for this operation. * @param[in] key the key to search for, or NULL for first/last page. * @param[in] flags If MDB_PS_MODIFY is set, visited pages in the DB * are touched (updated with new page numbers). * If MDB_PS_FIRST or MDB_PS_LAST is set, find first or last leaf. * This is used by #mdb_cursor_first() and #mdb_cursor_last(). * If MDB_PS_ROOTONLY set, just fetch root node, no further lookups. * @return 0 on success, non-zero on failure. */ static int mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags) { int rc; pgno_t root; /* Make sure the txn is still viable, then find the root from * the txn's db table and set it as the root of the cursor's stack. */ if (mc->mc_txn->mt_flags & MDB_TXN_BLOCKED) { DPUTS("transaction may not be used now"); return MDB_BAD_TXN; } else { /* Make sure we're using an up-to-date root */ if (*mc->mc_dbflag & DB_STALE) { MDB_cursor mc2; if (TXN_DBI_CHANGED(mc->mc_txn, mc->mc_dbi)) return MDB_BAD_DBI; mdb_cursor_init(&mc2, mc->mc_txn, MAIN_DBI, NULL); rc = mdb_page_search(&mc2, &mc->mc_dbx->md_name, 0); if (rc) return rc; { MDB_val data; int exact = 0; uint16_t flags; MDB_node *leaf = mdb_node_search(&mc2, &mc->mc_dbx->md_name, &exact); if (!exact) return MDB_NOTFOUND; if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) return MDB_INCOMPATIBLE; /* not a named DB */ rc = mdb_node_read(mc->mc_txn, leaf, &data); if (rc) return rc; memcpy(&flags, ((char *) data.mv_data + offsetof(MDB_db, md_flags)), sizeof(uint16_t)); /* The txn may not know this DBI, or another process may * have dropped and recreated the DB with other flags. */ if ((mc->mc_db->md_flags & PERSISTENT_FLAGS) != flags) return MDB_INCOMPATIBLE; memcpy(mc->mc_db, data.mv_data, sizeof(MDB_db)); } *mc->mc_dbflag &= ~DB_STALE; } root = mc->mc_db->md_root; if (root == P_INVALID) { /* Tree is empty. */ DPUTS("tree is empty"); return MDB_NOTFOUND; } } mdb_cassert(mc, root > 1); if (!mc->mc_pg[0] || mc->mc_pg[0]->mp_pgno != root) if ((rc = mdb_page_get(mc->mc_txn, root, &mc->mc_pg[0], NULL)) != 0) return rc; mc->mc_snum = 1; mc->mc_top = 0; DPRINTF(("db %d root page %"Z"u has flags 0x%X", DDBI(mc), root, mc->mc_pg[0]->mp_flags)); if (flags & MDB_PS_MODIFY) { if ((rc = mdb_page_touch(mc))) return rc; } if (flags & MDB_PS_ROOTONLY) return MDB_SUCCESS; return mdb_page_search_root(mc, key, flags); } static int mdb_ovpage_free(MDB_cursor *mc, MDB_page *mp) { MDB_txn *txn = mc->mc_txn; pgno_t pg = mp->mp_pgno; unsigned x = 0, ovpages = mp->mp_pages; MDB_env *env = txn->mt_env; MDB_IDL sl = txn->mt_spill_pgs; MDB_ID pn = pg << 1; int rc; DPRINTF(("free ov page %"Z"u (%d)", pg, ovpages)); /* If the page is dirty or on the spill list we just acquired it, * so we should give it back to our current free list, if any. * Otherwise put it onto the list of pages we freed in this txn. * * Won't create me_pghead: me_pglast must be inited along with it. * Unsupported in nested txns: They would need to hide the page * range in ancestor txns' dirty and spilled lists. */ if (env->me_pghead && !txn->mt_parent && ((mp->mp_flags & P_DIRTY) || (sl && (x = mdb_midl_search(sl, pn)) <= sl[0] && sl[x] == pn))) { unsigned i, j; pgno_t *mop; MDB_ID2 *dl, ix, iy; rc = mdb_midl_need(&env->me_pghead, ovpages); if (rc) return rc; if (!(mp->mp_flags & P_DIRTY)) { /* This page is no longer spilled */ if (x == sl[0]) sl[0]--; else sl[x] |= 1; goto release; } /* Remove from dirty list */ dl = txn->mt_u.dirty_list; x = dl[0].mid--; for (ix = dl[x]; ix.mptr != mp; ix = iy) { if (x > 1) { x--; iy = dl[x]; dl[x] = ix; } else { mdb_cassert(mc, x > 1); j = ++(dl[0].mid); dl[j] = ix; /* Unsorted. OK when MDB_TXN_ERROR. */ txn->mt_flags |= MDB_TXN_ERROR; return MDB_CORRUPTED; } } if (!(env->me_flags & MDB_WRITEMAP)) mdb_dpage_free(env, mp); release: /* Insert in me_pghead */ mop = env->me_pghead; j = mop[0] + ovpages; for (i = mop[0]; i && mop[i] < pg; i--) mop[j--] = mop[i]; while (j>i) mop[j--] = pg++; mop[0] += ovpages; } else { rc = mdb_midl_append_range(&txn->mt_free_pgs, pg, ovpages); if (rc) return rc; } mc->mc_db->md_overflow_pages -= ovpages; return 0; } /** Return the data associated with a given node. * @param[in] txn The transaction for this operation. * @param[in] leaf The node being read. * @param[out] data Updated to point to the node's data. * @return 0 on success, non-zero on failure. */ static int mdb_node_read(MDB_txn *txn, MDB_node *leaf, MDB_val *data) { MDB_page *omp; /* overflow page */ pgno_t pgno; int rc; if (!F_ISSET(leaf->mn_flags, F_BIGDATA)) { data->mv_size = NODEDSZ(leaf); data->mv_data = NODEDATA(leaf); return MDB_SUCCESS; } /* Read overflow data. */ data->mv_size = NODEDSZ(leaf); memcpy(&pgno, NODEDATA(leaf), sizeof(pgno)); if ((rc = mdb_page_get(txn, pgno, &omp, NULL)) != 0) { DPRINTF(("read overflow page %"Z"u failed", pgno)); return rc; } data->mv_data = METADATA(omp); return MDB_SUCCESS; } int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data) { MDB_cursor mc; MDB_xcursor mx; int exact = 0; DKBUF; DPRINTF(("===> get db %u key [%s]", dbi, DKEY(key))); if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; if (txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; mdb_cursor_init(&mc, txn, dbi, &mx); return mdb_cursor_set(&mc, key, data, MDB_SET, &exact); } /** Find a sibling for a page. * Replaces the page at the top of the cursor's stack with the * specified sibling, if one exists. * @param[in] mc The cursor for this operation. * @param[in] move_right Non-zero if the right sibling is requested, * otherwise the left sibling. * @return 0 on success, non-zero on failure. */ static int mdb_cursor_sibling(MDB_cursor *mc, int move_right) { int rc; MDB_node *indx; MDB_page *mp; if (mc->mc_snum < 2) { return MDB_NOTFOUND; /* root has no siblings */ } mdb_cursor_pop(mc); DPRINTF(("parent page is page %"Z"u, index %u", mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top])); if (move_right ? (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mc->mc_pg[mc->mc_top])) : (mc->mc_ki[mc->mc_top] == 0)) { DPRINTF(("no more keys left, moving to %s sibling", move_right ? "right" : "left")); if ((rc = mdb_cursor_sibling(mc, move_right)) != MDB_SUCCESS) { /* undo cursor_pop before returning */ mc->mc_top++; mc->mc_snum++; return rc; } } else { if (move_right) mc->mc_ki[mc->mc_top]++; else mc->mc_ki[mc->mc_top]--; DPRINTF(("just moving to %s index key %u", move_right ? "right" : "left", mc->mc_ki[mc->mc_top])); } mdb_cassert(mc, IS_BRANCH(mc->mc_pg[mc->mc_top])); indx = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if ((rc = mdb_page_get(mc->mc_txn, NODEPGNO(indx), &mp, NULL)) != 0) { /* mc will be inconsistent if caller does mc_snum++ as above */ mc->mc_flags &= ~(C_INITIALIZED|C_EOF); return rc; } mdb_cursor_push(mc, mp); if (!move_right) mc->mc_ki[mc->mc_top] = NUMKEYS(mp)-1; return MDB_SUCCESS; } /** Move the cursor to the next data item. */ static int mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) { MDB_page *mp; MDB_node *leaf; int rc; if (mc->mc_flags & C_EOF) { return MDB_NOTFOUND; } mdb_cassert(mc, mc->mc_flags & C_INITIALIZED); mp = mc->mc_pg[mc->mc_top]; if (mc->mc_db->md_flags & MDB_DUPSORT) { leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (op == MDB_NEXT || op == MDB_NEXT_DUP) { rc = mdb_cursor_next(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_NEXT); if (op != MDB_NEXT || rc != MDB_NOTFOUND) { if (rc == MDB_SUCCESS) MDB_GET_KEY(leaf, key); return rc; } } } else { mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if (op == MDB_NEXT_DUP) return MDB_NOTFOUND; } } DPRINTF(("cursor_next: top page is %"Z"u in cursor %p", mdb_dbg_pgno(mp), (void *) mc)); if (mc->mc_flags & C_DEL) goto skip; if (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mp)) { DPUTS("=====> move to next sibling page"); if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS) { mc->mc_flags |= C_EOF; return rc; } mp = mc->mc_pg[mc->mc_top]; DPRINTF(("next page is %"Z"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top])); } else mc->mc_ki[mc->mc_top]++; skip: DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u", mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top])); if (IS_LEAF2(mp)) { key->mv_size = mc->mc_db->md_pad; key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size); return MDB_SUCCESS; } mdb_cassert(mc, IS_LEAF(mp)); leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdb_xcursor_init1(mc, leaf); } if (data) { if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { rc = mdb_cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL); if (rc != MDB_SUCCESS) return rc; } } MDB_GET_KEY(leaf, key); return MDB_SUCCESS; } /** Move the cursor to the previous data item. */ static int mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) { MDB_page *mp; MDB_node *leaf; int rc; mdb_cassert(mc, mc->mc_flags & C_INITIALIZED); mp = mc->mc_pg[mc->mc_top]; if (mc->mc_db->md_flags & MDB_DUPSORT) { leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (op == MDB_PREV || op == MDB_PREV_DUP) { rc = mdb_cursor_prev(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_PREV); if (op != MDB_PREV || rc != MDB_NOTFOUND) { if (rc == MDB_SUCCESS) { MDB_GET_KEY(leaf, key); mc->mc_flags &= ~C_EOF; } return rc; } } } else { mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if (op == MDB_PREV_DUP) return MDB_NOTFOUND; } } DPRINTF(("cursor_prev: top page is %"Z"u in cursor %p", mdb_dbg_pgno(mp), (void *) mc)); if (mc->mc_ki[mc->mc_top] == 0) { DPUTS("=====> move to prev sibling page"); if ((rc = mdb_cursor_sibling(mc, 0)) != MDB_SUCCESS) { return rc; } mp = mc->mc_pg[mc->mc_top]; mc->mc_ki[mc->mc_top] = NUMKEYS(mp) - 1; DPRINTF(("prev page is %"Z"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top])); } else mc->mc_ki[mc->mc_top]--; mc->mc_flags &= ~C_EOF; DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u", mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top])); if (IS_LEAF2(mp)) { key->mv_size = mc->mc_db->md_pad; key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size); return MDB_SUCCESS; } mdb_cassert(mc, IS_LEAF(mp)); leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdb_xcursor_init1(mc, leaf); } if (data) { if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { rc = mdb_cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL); if (rc != MDB_SUCCESS) return rc; } } MDB_GET_KEY(leaf, key); return MDB_SUCCESS; } /** Set the cursor on a specific data item. */ static int mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op, int *exactp) { int rc; MDB_page *mp; MDB_node *leaf = NULL; DKBUF; if (key->mv_size == 0) return MDB_BAD_VALSIZE; if (mc->mc_xcursor) mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); /* See if we're already on the right page */ if (mc->mc_flags & C_INITIALIZED) { MDB_val nodekey; mp = mc->mc_pg[mc->mc_top]; if (!NUMKEYS(mp)) { mc->mc_ki[mc->mc_top] = 0; return MDB_NOTFOUND; } if (mp->mp_flags & P_LEAF2) { nodekey.mv_size = mc->mc_db->md_pad; nodekey.mv_data = LEAF2KEY(mp, 0, nodekey.mv_size); } else { leaf = NODEPTR(mp, 0); MDB_GET_KEY2(leaf, nodekey); } rc = mc->mc_dbx->md_cmp(key, &nodekey); if (rc == 0) { /* Probably happens rarely, but first node on the page * was the one we wanted. */ mc->mc_ki[mc->mc_top] = 0; if (exactp) *exactp = 1; goto set1; } if (rc > 0) { unsigned int i; unsigned int nkeys = NUMKEYS(mp); if (nkeys > 1) { if (mp->mp_flags & P_LEAF2) { nodekey.mv_data = LEAF2KEY(mp, nkeys-1, nodekey.mv_size); } else { leaf = NODEPTR(mp, nkeys-1); MDB_GET_KEY2(leaf, nodekey); } rc = mc->mc_dbx->md_cmp(key, &nodekey); if (rc == 0) { /* last node was the one we wanted */ mc->mc_ki[mc->mc_top] = nkeys-1; if (exactp) *exactp = 1; goto set1; } if (rc < 0) { if (mc->mc_ki[mc->mc_top] < NUMKEYS(mp)) { /* This is definitely the right page, skip search_page */ if (mp->mp_flags & P_LEAF2) { nodekey.mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], nodekey.mv_size); } else { leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); MDB_GET_KEY2(leaf, nodekey); } rc = mc->mc_dbx->md_cmp(key, &nodekey); if (rc == 0) { /* current node was the one we wanted */ if (exactp) *exactp = 1; goto set1; } } rc = 0; goto set2; } } /* If any parents have right-sibs, search. * Otherwise, there's nothing further. */ for (i=0; imc_top; i++) if (mc->mc_ki[i] < NUMKEYS(mc->mc_pg[i])-1) break; if (i == mc->mc_top) { /* There are no other pages */ mc->mc_ki[mc->mc_top] = nkeys; return MDB_NOTFOUND; } } if (!mc->mc_top) { /* There are no other pages */ mc->mc_ki[mc->mc_top] = 0; if (op == MDB_SET_RANGE && !exactp) { rc = 0; goto set1; } else return MDB_NOTFOUND; } } rc = mdb_page_search(mc, key, 0); if (rc != MDB_SUCCESS) return rc; mp = mc->mc_pg[mc->mc_top]; mdb_cassert(mc, IS_LEAF(mp)); set2: leaf = mdb_node_search(mc, key, exactp); if (exactp != NULL && !*exactp) { /* MDB_SET specified and not an exact match. */ return MDB_NOTFOUND; } if (leaf == NULL) { DPUTS("===> inexact leaf not found, goto sibling"); if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS) { mc->mc_flags |= C_EOF; return rc; /* no entries matched */ } mp = mc->mc_pg[mc->mc_top]; mdb_cassert(mc, IS_LEAF(mp)); leaf = NODEPTR(mp, 0); } set1: mc->mc_flags |= C_INITIALIZED; mc->mc_flags &= ~C_EOF; if (IS_LEAF2(mp)) { if (op == MDB_SET_RANGE || op == MDB_SET_KEY) { key->mv_size = mc->mc_db->md_pad; key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size); } return MDB_SUCCESS; } if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdb_xcursor_init1(mc, leaf); } if (data) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (op == MDB_SET || op == MDB_SET_KEY || op == MDB_SET_RANGE) { rc = mdb_cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL); } else { int ex2, *ex2p; if (op == MDB_GET_BOTH) { ex2p = &ex2; ex2 = 0; } else { ex2p = NULL; } rc = mdb_cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_SET_RANGE, ex2p); if (rc != MDB_SUCCESS) return rc; } } else if (op == MDB_GET_BOTH || op == MDB_GET_BOTH_RANGE) { MDB_val olddata; MDB_cmp_func *dcmp; if ((rc = mdb_node_read(mc->mc_txn, leaf, &olddata)) != MDB_SUCCESS) return rc; dcmp = mc->mc_dbx->md_dcmp; #if UINT_MAX < SIZE_MAX if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t)) dcmp = mdb_cmp_clong; #endif rc = dcmp(data, &olddata); if (rc) { if (op == MDB_GET_BOTH || rc > 0) return MDB_NOTFOUND; rc = 0; *data = olddata; } } else { if (mc->mc_xcursor) mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; } } /* The key already matches in all other cases */ if (op == MDB_SET_RANGE || op == MDB_SET_KEY) MDB_GET_KEY(leaf, key); DPRINTF(("==> cursor placed on key [%s]", DKEY(key))); return rc; } /** Move the cursor to the first item in the database. */ static int mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data) { int rc; MDB_node *leaf; if (mc->mc_xcursor) mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) { rc = mdb_page_search(mc, NULL, MDB_PS_FIRST); if (rc != MDB_SUCCESS) return rc; } mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top])); leaf = NODEPTR(mc->mc_pg[mc->mc_top], 0); mc->mc_flags |= C_INITIALIZED; mc->mc_flags &= ~C_EOF; mc->mc_ki[mc->mc_top] = 0; if (IS_LEAF2(mc->mc_pg[mc->mc_top])) { key->mv_size = mc->mc_db->md_pad; key->mv_data = LEAF2KEY(mc->mc_pg[mc->mc_top], 0, key->mv_size); return MDB_SUCCESS; } if (data) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdb_xcursor_init1(mc, leaf); rc = mdb_cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL); if (rc) return rc; } else { if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; } } MDB_GET_KEY(leaf, key); return MDB_SUCCESS; } /** Move the cursor to the last item in the database. */ static int mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data) { int rc; MDB_node *leaf; if (mc->mc_xcursor) mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if (!(mc->mc_flags & C_EOF)) { if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) { rc = mdb_page_search(mc, NULL, MDB_PS_LAST); if (rc != MDB_SUCCESS) return rc; } mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top])); } mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]) - 1; mc->mc_flags |= C_INITIALIZED|C_EOF; leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (IS_LEAF2(mc->mc_pg[mc->mc_top])) { key->mv_size = mc->mc_db->md_pad; key->mv_data = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], key->mv_size); return MDB_SUCCESS; } if (data) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdb_xcursor_init1(mc, leaf); rc = mdb_cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL); if (rc) return rc; } else { if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; } } MDB_GET_KEY(leaf, key); return MDB_SUCCESS; } int mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) { int rc; int exact = 0; int (*mfunc)(MDB_cursor *mc, MDB_val *key, MDB_val *data); if (mc == NULL) return EINVAL; if (mc->mc_txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; switch (op) { case MDB_GET_CURRENT: if (!(mc->mc_flags & C_INITIALIZED)) { rc = EINVAL; } else { MDB_page *mp = mc->mc_pg[mc->mc_top]; int nkeys = NUMKEYS(mp); if (!nkeys || mc->mc_ki[mc->mc_top] >= nkeys) { mc->mc_ki[mc->mc_top] = nkeys; rc = MDB_NOTFOUND; break; } rc = MDB_SUCCESS; if (IS_LEAF2(mp)) { key->mv_size = mc->mc_db->md_pad; key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size); } else { MDB_node *leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); MDB_GET_KEY(leaf, key); if (data) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (mc->mc_flags & C_DEL) mdb_xcursor_init1(mc, leaf); rc = mdb_cursor_get(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_GET_CURRENT); } else { rc = mdb_node_read(mc->mc_txn, leaf, data); } } } } break; case MDB_GET_BOTH: case MDB_GET_BOTH_RANGE: if (data == NULL) { rc = EINVAL; break; } if (mc->mc_xcursor == NULL) { rc = MDB_INCOMPATIBLE; break; } /* FALLTHRU */ case MDB_SET: case MDB_SET_KEY: case MDB_SET_RANGE: if (key == NULL) { rc = EINVAL; } else { rc = mdb_cursor_set(mc, key, data, op, op == MDB_SET_RANGE ? NULL : &exact); } break; case MDB_GET_MULTIPLE: if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) { rc = EINVAL; break; } if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) { rc = MDB_INCOMPATIBLE; break; } rc = MDB_SUCCESS; if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) || (mc->mc_xcursor->mx_cursor.mc_flags & C_EOF)) break; goto fetchm; case MDB_NEXT_MULTIPLE: if (data == NULL) { rc = EINVAL; break; } if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) { rc = MDB_INCOMPATIBLE; break; } if (!(mc->mc_flags & C_INITIALIZED)) rc = mdb_cursor_first(mc, key, data); else rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP); if (rc == MDB_SUCCESS) { if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { MDB_cursor *mx; fetchm: mx = &mc->mc_xcursor->mx_cursor; data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) * mx->mc_db->md_pad; data->mv_data = METADATA(mx->mc_pg[mx->mc_top]); mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1; } else { rc = MDB_NOTFOUND; } } break; case MDB_NEXT: case MDB_NEXT_DUP: case MDB_NEXT_NODUP: if (!(mc->mc_flags & C_INITIALIZED)) rc = mdb_cursor_first(mc, key, data); else rc = mdb_cursor_next(mc, key, data, op); break; case MDB_PREV: case MDB_PREV_DUP: case MDB_PREV_NODUP: if (!(mc->mc_flags & C_INITIALIZED)) { rc = mdb_cursor_last(mc, key, data); if (rc) break; mc->mc_flags |= C_INITIALIZED; mc->mc_ki[mc->mc_top]++; } rc = mdb_cursor_prev(mc, key, data, op); break; case MDB_FIRST: rc = mdb_cursor_first(mc, key, data); break; case MDB_FIRST_DUP: mfunc = mdb_cursor_first; mmove: if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) { rc = EINVAL; break; } if (mc->mc_xcursor == NULL) { rc = MDB_INCOMPATIBLE; break; } { MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { MDB_GET_KEY(leaf, key); rc = mdb_node_read(mc->mc_txn, leaf, data); break; } } if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { rc = EINVAL; break; } rc = mfunc(&mc->mc_xcursor->mx_cursor, data, NULL); break; case MDB_LAST: rc = mdb_cursor_last(mc, key, data); break; case MDB_LAST_DUP: mfunc = mdb_cursor_last; goto mmove; default: DPRINTF(("unhandled/unimplemented cursor operation %u", op)); rc = EINVAL; break; } if (mc->mc_flags & C_DEL) mc->mc_flags ^= C_DEL; return rc; } /** Touch all the pages in the cursor stack. Set mc_top. * Makes sure all the pages are writable, before attempting a write operation. * @param[in] mc The cursor to operate on. */ static int mdb_cursor_touch(MDB_cursor *mc) { int rc = MDB_SUCCESS; if (mc->mc_dbi >= CORE_DBS && !(*mc->mc_dbflag & DB_DIRTY)) { MDB_cursor mc2; MDB_xcursor mcx; if (TXN_DBI_CHANGED(mc->mc_txn, mc->mc_dbi)) return MDB_BAD_DBI; mdb_cursor_init(&mc2, mc->mc_txn, MAIN_DBI, &mcx); rc = mdb_page_search(&mc2, &mc->mc_dbx->md_name, MDB_PS_MODIFY); if (rc) return rc; *mc->mc_dbflag |= DB_DIRTY; } mc->mc_top = 0; if (mc->mc_snum) { do { rc = mdb_page_touch(mc); } while (!rc && ++(mc->mc_top) < mc->mc_snum); mc->mc_top = mc->mc_snum-1; } return rc; } /** Do not spill pages to disk if txn is getting full, may fail instead */ #define MDB_NOSPILL 0x8000 int mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data, unsigned int flags) { MDB_env *env; MDB_node *leaf = NULL; MDB_page *fp, *mp, *sub_root = NULL; uint16_t fp_flags; MDB_val xdata, *rdata, dkey, olddata; MDB_db dummy; int do_sub = 0, insert_key, insert_data; unsigned int mcount = 0, dcount = 0, nospill; size_t nsize; int rc, rc2; unsigned int nflags; DKBUF; if (mc == NULL || key == NULL) return EINVAL; env = mc->mc_txn->mt_env; /* Check this first so counter will always be zero on any * early failures. */ if (flags & MDB_MULTIPLE) { dcount = data[1].mv_size; data[1].mv_size = 0; if (!F_ISSET(mc->mc_db->md_flags, MDB_DUPFIXED)) return MDB_INCOMPATIBLE; } nospill = flags & MDB_NOSPILL; flags &= ~MDB_NOSPILL; if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED)) return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN; if (key->mv_size-1 >= ENV_MAXKEY(env)) return MDB_BAD_VALSIZE; #if SIZE_MAX > MAXDATASIZE if (data->mv_size > ((mc->mc_db->md_flags & MDB_DUPSORT) ? ENV_MAXKEY(env) : MAXDATASIZE)) return MDB_BAD_VALSIZE; #else if ((mc->mc_db->md_flags & MDB_DUPSORT) && data->mv_size > ENV_MAXKEY(env)) return MDB_BAD_VALSIZE; #endif DPRINTF(("==> put db %d key [%s], size %"Z"u, data size %"Z"u", DDBI(mc), DKEY(key), key ? key->mv_size : 0, data->mv_size)); dkey.mv_size = 0; if (flags == MDB_CURRENT) { if (!(mc->mc_flags & C_INITIALIZED)) return EINVAL; rc = MDB_SUCCESS; } else if (mc->mc_db->md_root == P_INVALID) { /* new database, cursor has nothing to point to */ mc->mc_snum = 0; mc->mc_top = 0; mc->mc_flags &= ~C_INITIALIZED; rc = MDB_NO_ROOT; } else { int exact = 0; MDB_val d2; if (flags & MDB_APPEND) { MDB_val k2; rc = mdb_cursor_last(mc, &k2, &d2); if (rc == 0) { rc = mc->mc_dbx->md_cmp(key, &k2); if (rc > 0) { rc = MDB_NOTFOUND; mc->mc_ki[mc->mc_top]++; } else { /* new key is <= last key */ rc = MDB_KEYEXIST; } } } else { rc = mdb_cursor_set(mc, key, &d2, MDB_SET, &exact); } if ((flags & MDB_NOOVERWRITE) && rc == 0) { DPRINTF(("duplicate key [%s]", DKEY(key))); *data = d2; return MDB_KEYEXIST; } if (rc && rc != MDB_NOTFOUND) return rc; } if (mc->mc_flags & C_DEL) mc->mc_flags ^= C_DEL; /* Cursor is positioned, check for room in the dirty list */ if (!nospill) { if (flags & MDB_MULTIPLE) { rdata = &xdata; xdata.mv_size = data->mv_size * dcount; } else { rdata = data; } if ((rc2 = mdb_page_spill(mc, key, rdata))) return rc2; } if (rc == MDB_NO_ROOT) { MDB_page *np; /* new database, write a root leaf page */ DPUTS("allocating new root leaf page"); if ((rc2 = mdb_page_new(mc, P_LEAF, 1, &np))) { return rc2; } mdb_cursor_push(mc, np); mc->mc_db->md_root = np->mp_pgno; mc->mc_db->md_depth++; *mc->mc_dbflag |= DB_DIRTY; if ((mc->mc_db->md_flags & (MDB_DUPSORT|MDB_DUPFIXED)) == MDB_DUPFIXED) np->mp_flags |= P_LEAF2; mc->mc_flags |= C_INITIALIZED; } else { /* make sure all cursor pages are writable */ rc2 = mdb_cursor_touch(mc); if (rc2) return rc2; } insert_key = insert_data = rc; if (insert_key) { /* The key does not exist */ DPRINTF(("inserting key at index %i", mc->mc_ki[mc->mc_top])); if ((mc->mc_db->md_flags & MDB_DUPSORT) && LEAFSIZE(key, data) > env->me_nodemax) { /* Too big for a node, insert in sub-DB. Set up an empty * "old sub-page" for prep_subDB to expand to a full page. */ fp_flags = P_LEAF|P_DIRTY; fp = env->me_pbuf; fp->mp_pad = data->mv_size; /* used if MDB_DUPFIXED */ fp->mp_lower = fp->mp_upper = (PAGEHDRSZ-PAGEBASE); olddata.mv_size = PAGEHDRSZ; goto prep_subDB; } } else { /* there's only a key anyway, so this is a no-op */ if (IS_LEAF2(mc->mc_pg[mc->mc_top])) { char *ptr; unsigned int ksize = mc->mc_db->md_pad; if (key->mv_size != ksize) return MDB_BAD_VALSIZE; ptr = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], ksize); memcpy(ptr, key->mv_data, ksize); fix_parent: /* if overwriting slot 0 of leaf, need to * update branch key if there is a parent page */ if (mc->mc_top && !mc->mc_ki[mc->mc_top]) { unsigned short top = mc->mc_top; mc->mc_top--; /* slot 0 is always an empty key, find real slot */ while (mc->mc_top && !mc->mc_ki[mc->mc_top]) mc->mc_top--; if (mc->mc_ki[mc->mc_top]) rc2 = mdb_update_key(mc, key); else rc2 = MDB_SUCCESS; mc->mc_top = top; if (rc2) return rc2; } return MDB_SUCCESS; } more: leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); olddata.mv_size = NODEDSZ(leaf); olddata.mv_data = NODEDATA(leaf); /* DB has dups? */ if (F_ISSET(mc->mc_db->md_flags, MDB_DUPSORT)) { /* Prepare (sub-)page/sub-DB to accept the new item, * if needed. fp: old sub-page or a header faking * it. mp: new (sub-)page. offset: growth in page * size. xdata: node data with new page or DB. */ unsigned i, offset = 0; mp = fp = xdata.mv_data = env->me_pbuf; mp->mp_pgno = mc->mc_pg[mc->mc_top]->mp_pgno; /* Was a single item before, must convert now */ if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { MDB_cmp_func *dcmp; /* Just overwrite the current item */ if (flags == MDB_CURRENT) goto current; dcmp = mc->mc_dbx->md_dcmp; #if UINT_MAX < SIZE_MAX if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t)) dcmp = mdb_cmp_clong; #endif /* does data match? */ if (!dcmp(data, &olddata)) { if (flags & MDB_NODUPDATA) return MDB_KEYEXIST; /* overwrite it */ goto current; } /* Back up original data item */ dkey.mv_size = olddata.mv_size; dkey.mv_data = memcpy(fp+1, olddata.mv_data, olddata.mv_size); /* Make sub-page header for the dup items, with dummy body */ fp->mp_flags = P_LEAF|P_DIRTY|P_SUBP; fp->mp_lower = (PAGEHDRSZ-PAGEBASE); xdata.mv_size = PAGEHDRSZ + dkey.mv_size + data->mv_size; if (mc->mc_db->md_flags & MDB_DUPFIXED) { fp->mp_flags |= P_LEAF2; fp->mp_pad = data->mv_size; xdata.mv_size += 2 * data->mv_size; /* leave space for 2 more */ } else { xdata.mv_size += 2 * (sizeof(indx_t) + NODESIZE) + (dkey.mv_size & 1) + (data->mv_size & 1); } fp->mp_upper = xdata.mv_size - PAGEBASE; olddata.mv_size = xdata.mv_size; /* pretend olddata is fp */ } else if (leaf->mn_flags & F_SUBDATA) { /* Data is on sub-DB, just store it */ flags |= F_DUPDATA|F_SUBDATA; goto put_sub; } else { /* Data is on sub-page */ fp = olddata.mv_data; switch (flags) { default: if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) { offset = EVEN(NODESIZE + sizeof(indx_t) + data->mv_size); break; } offset = fp->mp_pad; if (SIZELEFT(fp) < offset) { offset *= 4; /* space for 4 more */ break; } /* FALLTHRU: Big enough MDB_DUPFIXED sub-page */ case MDB_CURRENT: fp->mp_flags |= P_DIRTY; COPY_PGNO(fp->mp_pgno, mp->mp_pgno); mc->mc_xcursor->mx_cursor.mc_pg[0] = fp; flags |= F_DUPDATA; goto put_sub; } xdata.mv_size = olddata.mv_size + offset; } fp_flags = fp->mp_flags; if (NODESIZE + NODEKSZ(leaf) + xdata.mv_size > env->me_nodemax) { /* Too big for a sub-page, convert to sub-DB */ fp_flags &= ~P_SUBP; prep_subDB: if (mc->mc_db->md_flags & MDB_DUPFIXED) { fp_flags |= P_LEAF2; dummy.md_pad = fp->mp_pad; dummy.md_flags = MDB_DUPFIXED; if (mc->mc_db->md_flags & MDB_INTEGERDUP) dummy.md_flags |= MDB_INTEGERKEY; } else { dummy.md_pad = 0; dummy.md_flags = 0; } dummy.md_depth = 1; dummy.md_branch_pages = 0; dummy.md_leaf_pages = 1; dummy.md_overflow_pages = 0; dummy.md_entries = NUMKEYS(fp); xdata.mv_size = sizeof(MDB_db); xdata.mv_data = &dummy; if ((rc = mdb_page_alloc(mc, 1, &mp))) return rc; offset = env->me_psize - olddata.mv_size; flags |= F_DUPDATA|F_SUBDATA; dummy.md_root = mp->mp_pgno; sub_root = mp; } if (mp != fp) { mp->mp_flags = fp_flags | P_DIRTY; mp->mp_pad = fp->mp_pad; mp->mp_lower = fp->mp_lower; mp->mp_upper = fp->mp_upper + offset; if (fp_flags & P_LEAF2) { memcpy(METADATA(mp), METADATA(fp), NUMKEYS(fp) * fp->mp_pad); } else { memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE, olddata.mv_size - fp->mp_upper - PAGEBASE); for (i=0; imp_ptrs[i] = fp->mp_ptrs[i] + offset; } } rdata = &xdata; flags |= F_DUPDATA; do_sub = 1; if (!insert_key) mdb_node_del(mc, 0); goto new_sub; } current: /* LMDB passes F_SUBDATA in 'flags' to write a DB record */ if ((leaf->mn_flags ^ flags) & F_SUBDATA) return MDB_INCOMPATIBLE; /* overflow page overwrites need special handling */ if (F_ISSET(leaf->mn_flags, F_BIGDATA)) { MDB_page *omp; pgno_t pg; int level, ovpages, dpages = OVPAGES(data->mv_size, env->me_psize); memcpy(&pg, olddata.mv_data, sizeof(pg)); if ((rc2 = mdb_page_get(mc->mc_txn, pg, &omp, &level)) != 0) return rc2; ovpages = omp->mp_pages; /* Is the ov page large enough? */ if (ovpages >= dpages) { if (!(omp->mp_flags & P_DIRTY) && (level || (env->me_flags & MDB_WRITEMAP))) { rc = mdb_page_unspill(mc->mc_txn, omp, &omp); if (rc) return rc; level = 0; /* dirty in this txn or clean */ } /* Is it dirty? */ if (omp->mp_flags & P_DIRTY) { /* yes, overwrite it. Note in this case we don't * bother to try shrinking the page if the new data * is smaller than the overflow threshold. */ if (level > 1) { /* It is writable only in a parent txn */ size_t sz = (size_t) env->me_psize * ovpages, off; MDB_page *np = mdb_page_malloc(mc->mc_txn, ovpages); MDB_ID2 id2; if (!np) return ENOMEM; id2.mid = pg; id2.mptr = np; rc2 = mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2); mdb_cassert(mc, rc2 == 0); if (!(flags & MDB_RESERVE)) { /* Copy end of page, adjusting alignment so * compiler may copy words instead of bytes. */ off = (PAGEHDRSZ + data->mv_size) & -sizeof(size_t); memcpy((size_t *)((char *)np + off), (size_t *)((char *)omp + off), sz - off); sz = PAGEHDRSZ; } memcpy(np, omp, sz); /* Copy beginning of page */ omp = np; } SETDSZ(leaf, data->mv_size); if (F_ISSET(flags, MDB_RESERVE)) data->mv_data = METADATA(omp); else memcpy(METADATA(omp), data->mv_data, data->mv_size); return MDB_SUCCESS; } } if ((rc2 = mdb_ovpage_free(mc, omp)) != MDB_SUCCESS) return rc2; } else if (data->mv_size == olddata.mv_size) { /* same size, just replace it. Note that we could * also reuse this node if the new data is smaller, * but instead we opt to shrink the node in that case. */ if (F_ISSET(flags, MDB_RESERVE)) data->mv_data = olddata.mv_data; else if (!(mc->mc_flags & C_SUB)) memcpy(olddata.mv_data, data->mv_data, data->mv_size); else { memcpy(NODEKEY(leaf), key->mv_data, key->mv_size); goto fix_parent; } return MDB_SUCCESS; } mdb_node_del(mc, 0); } rdata = data; new_sub: nflags = flags & NODE_ADD_FLAGS; nsize = IS_LEAF2(mc->mc_pg[mc->mc_top]) ? key->mv_size : mdb_leaf_size(env, key, rdata); if (SIZELEFT(mc->mc_pg[mc->mc_top]) < nsize) { if (( flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA ) nflags &= ~MDB_APPEND; /* sub-page may need room to grow */ if (!insert_key) nflags |= MDB_SPLIT_REPLACE; rc = mdb_page_split(mc, key, rdata, P_INVALID, nflags); } else { /* There is room already in this leaf page. */ rc = mdb_node_add(mc, mc->mc_ki[mc->mc_top], key, rdata, 0, nflags); if (rc == 0 && insert_key) { /* Adjust other cursors pointing to mp */ MDB_cursor *m2, *m3; MDB_dbi dbi = mc->mc_dbi; unsigned i = mc->mc_top; MDB_page *mp = mc->mc_pg[i]; for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (mc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[i] == mp && m3->mc_ki[i] >= mc->mc_ki[i]) { m3->mc_ki[i]++; } } } } if (rc == MDB_SUCCESS) { /* Now store the actual data in the child DB. Note that we're * storing the user data in the keys field, so there are strict * size limits on dupdata. The actual data fields of the child * DB are all zero size. */ if (do_sub) { int xflags, new_dupdata; size_t ecount; put_sub: xdata.mv_size = 0; xdata.mv_data = ""; leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (flags & MDB_CURRENT) { xflags = MDB_CURRENT|MDB_NOSPILL; } else { mdb_xcursor_init1(mc, leaf); xflags = (flags & MDB_NODUPDATA) ? MDB_NOOVERWRITE|MDB_NOSPILL : MDB_NOSPILL; } if (sub_root) mc->mc_xcursor->mx_cursor.mc_pg[0] = sub_root; new_dupdata = (int)dkey.mv_size; /* converted, write the original data first */ if (dkey.mv_size) { rc = mdb_cursor_put(&mc->mc_xcursor->mx_cursor, &dkey, &xdata, xflags); if (rc) goto bad_sub; /* we've done our job */ dkey.mv_size = 0; } if (!(leaf->mn_flags & F_SUBDATA) || sub_root) { /* Adjust other cursors pointing to mp */ MDB_cursor *m2; MDB_xcursor *mx = mc->mc_xcursor; unsigned i = mc->mc_top; MDB_page *mp = mc->mc_pg[i]; for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) { if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; if (!(m2->mc_flags & C_INITIALIZED)) continue; if (m2->mc_pg[i] == mp) { if (m2->mc_ki[i] == mc->mc_ki[i]) { mdb_xcursor_init2(m2, mx, new_dupdata); } else if (!insert_key) { MDB_node *n2 = NODEPTR(mp, m2->mc_ki[i]); if (!(n2->mn_flags & F_SUBDATA)) m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); } } } } ecount = mc->mc_xcursor->mx_db.md_entries; if (flags & MDB_APPENDDUP) xflags |= MDB_APPEND; rc = mdb_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags); if (flags & F_SUBDATA) { void *db = NODEDATA(leaf); memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDB_db)); } insert_data = mc->mc_xcursor->mx_db.md_entries - ecount; } /* Increment count unless we just replaced an existing item. */ if (insert_data) mc->mc_db->md_entries++; if (insert_key) { /* Invalidate txn if we created an empty sub-DB */ if (rc) goto bad_sub; /* If we succeeded and the key didn't exist before, * make sure the cursor is marked valid. */ mc->mc_flags |= C_INITIALIZED; } if (flags & MDB_MULTIPLE) { if (!rc) { mcount++; /* let caller know how many succeeded, if any */ data[1].mv_size = mcount; if (mcount < dcount) { data[0].mv_data = (char *)data[0].mv_data + data[0].mv_size; insert_key = insert_data = 0; goto more; } } } return rc; bad_sub: if (rc == MDB_KEYEXIST) /* should not happen, we deleted that item */ rc = MDB_CORRUPTED; } mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return rc; } int mdb_cursor_del(MDB_cursor *mc, unsigned int flags) { MDB_node *leaf; MDB_page *mp; int rc; if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED)) return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN; if (!(mc->mc_flags & C_INITIALIZED)) return EINVAL; if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top])) return MDB_NOTFOUND; if (!(flags & MDB_NOSPILL) && (rc = mdb_page_spill(mc, NULL, NULL))) return rc; rc = mdb_cursor_touch(mc); if (rc) return rc; mp = mc->mc_pg[mc->mc_top]; if (IS_LEAF2(mp)) goto del_key; leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (flags & MDB_NODUPDATA) { /* mdb_cursor_del0() will subtract the final entry */ mc->mc_db->md_entries -= mc->mc_xcursor->mx_db.md_entries - 1; } else { if (!F_ISSET(leaf->mn_flags, F_SUBDATA)) { mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); } rc = mdb_cursor_del(&mc->mc_xcursor->mx_cursor, MDB_NOSPILL); if (rc) return rc; /* If sub-DB still has entries, we're done */ if (mc->mc_xcursor->mx_db.md_entries) { if (leaf->mn_flags & F_SUBDATA) { /* update subDB info */ void *db = NODEDATA(leaf); memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDB_db)); } else { MDB_cursor *m2; /* shrink fake page */ mdb_node_shrink(mp, mc->mc_ki[mc->mc_top]); leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); /* fix other sub-DB cursors pointed at fake pages on this page */ for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) { if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; if (!(m2->mc_flags & C_INITIALIZED)) continue; if (m2->mc_pg[mc->mc_top] == mp) { if (m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top]) { m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); } else { MDB_node *n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); if (!(n2->mn_flags & F_SUBDATA)) m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); } } } } mc->mc_db->md_entries--; mc->mc_flags |= C_DEL; return rc; } /* otherwise fall thru and delete the sub-DB */ } if (leaf->mn_flags & F_SUBDATA) { /* add all the child DB's pages to the free list */ rc = mdb_drop0(&mc->mc_xcursor->mx_cursor, 0); if (rc) goto fail; } } /* LMDB passes F_SUBDATA in 'flags' to delete a DB record */ else if ((leaf->mn_flags ^ flags) & F_SUBDATA) { rc = MDB_INCOMPATIBLE; goto fail; } /* add overflow pages to free list */ if (F_ISSET(leaf->mn_flags, F_BIGDATA)) { MDB_page *omp; pgno_t pg; memcpy(&pg, NODEDATA(leaf), sizeof(pg)); if ((rc = mdb_page_get(mc->mc_txn, pg, &omp, NULL)) || (rc = mdb_ovpage_free(mc, omp))) goto fail; } del_key: return mdb_cursor_del0(mc); fail: mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return rc; } /** Allocate and initialize new pages for a database. * @param[in] mc a cursor on the database being added to. * @param[in] flags flags defining what type of page is being allocated. * @param[in] num the number of pages to allocate. This is usually 1, * unless allocating overflow pages for a large record. * @param[out] mp Address of a page, or NULL on failure. * @return 0 on success, non-zero on failure. */ static int mdb_page_new(MDB_cursor *mc, uint32_t flags, int num, MDB_page **mp) { MDB_page *np; int rc; if ((rc = mdb_page_alloc(mc, num, &np))) return rc; DPRINTF(("allocated new mpage %"Z"u, page size %u", np->mp_pgno, mc->mc_txn->mt_env->me_psize)); np->mp_flags = flags | P_DIRTY; np->mp_lower = (PAGEHDRSZ-PAGEBASE); np->mp_upper = mc->mc_txn->mt_env->me_psize - PAGEBASE; if (IS_BRANCH(np)) mc->mc_db->md_branch_pages++; else if (IS_LEAF(np)) mc->mc_db->md_leaf_pages++; else if (IS_OVERFLOW(np)) { mc->mc_db->md_overflow_pages += num; np->mp_pages = num; } *mp = np; return 0; } /** Calculate the size of a leaf node. * The size depends on the environment's page size; if a data item * is too large it will be put onto an overflow page and the node * size will only include the key and not the data. Sizes are always * rounded up to an even number of bytes, to guarantee 2-byte alignment * of the #MDB_node headers. * @param[in] env The environment handle. * @param[in] key The key for the node. * @param[in] data The data for the node. * @return The number of bytes needed to store the node. */ static size_t mdb_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data) { size_t sz; sz = LEAFSIZE(key, data); if (sz > env->me_nodemax) { /* put on overflow page */ sz -= data->mv_size - sizeof(pgno_t); } return EVEN(sz + sizeof(indx_t)); } /** Calculate the size of a branch node. * The size should depend on the environment's page size but since * we currently don't support spilling large keys onto overflow * pages, it's simply the size of the #MDB_node header plus the * size of the key. Sizes are always rounded up to an even number * of bytes, to guarantee 2-byte alignment of the #MDB_node headers. * @param[in] env The environment handle. * @param[in] key The key for the node. * @return The number of bytes needed to store the node. */ static size_t mdb_branch_size(MDB_env *env, MDB_val *key) { size_t sz; sz = INDXSIZE(key); if (sz > env->me_nodemax) { /* put on overflow page */ /* not implemented */ /* sz -= key->size - sizeof(pgno_t); */ } return sz + sizeof(indx_t); } /** Add a node to the page pointed to by the cursor. * @param[in] mc The cursor for this operation. * @param[in] indx The index on the page where the new node should be added. * @param[in] key The key for the new node. * @param[in] data The data for the new node, if any. * @param[in] pgno The page number, if adding a branch node. * @param[in] flags Flags for the node. * @return 0 on success, non-zero on failure. Possible errors are: *
    *
  • ENOMEM - failed to allocate overflow pages for the node. *
  • MDB_PAGE_FULL - there is insufficient room in the page. This error * should never happen since all callers already calculate the * page's free space before calling this function. *
*/ static int mdb_node_add(MDB_cursor *mc, indx_t indx, MDB_val *key, MDB_val *data, pgno_t pgno, unsigned int flags) { unsigned int i; size_t node_size = NODESIZE; ssize_t room; indx_t ofs; MDB_node *node; MDB_page *mp = mc->mc_pg[mc->mc_top]; MDB_page *ofp = NULL; /* overflow page */ void *ndata; DKBUF; mdb_cassert(mc, mp->mp_upper >= mp->mp_lower); DPRINTF(("add to %s %spage %"Z"u index %i, data size %"Z"u key size %"Z"u [%s]", IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "", mdb_dbg_pgno(mp), indx, data ? data->mv_size : 0, key ? key->mv_size : 0, key ? DKEY(key) : "null")); if (IS_LEAF2(mp)) { /* Move higher keys up one slot. */ int ksize = mc->mc_db->md_pad, dif; char *ptr = LEAF2KEY(mp, indx, ksize); dif = NUMKEYS(mp) - indx; if (dif > 0) memmove(ptr+ksize, ptr, dif*ksize); /* insert new key */ memcpy(ptr, key->mv_data, ksize); /* Just using these for counting */ mp->mp_lower += sizeof(indx_t); mp->mp_upper -= ksize - sizeof(indx_t); return MDB_SUCCESS; } room = (ssize_t)SIZELEFT(mp) - (ssize_t)sizeof(indx_t); if (key != NULL) node_size += key->mv_size; if (IS_LEAF(mp)) { mdb_cassert(mc, key && data); if (F_ISSET(flags, F_BIGDATA)) { /* Data already on overflow page. */ node_size += sizeof(pgno_t); } else if (node_size + data->mv_size > mc->mc_txn->mt_env->me_nodemax) { int ovpages = OVPAGES(data->mv_size, mc->mc_txn->mt_env->me_psize); int rc; /* Put data on overflow page. */ DPRINTF(("data size is %"Z"u, node would be %"Z"u, put data on overflow page", data->mv_size, node_size+data->mv_size)); node_size = EVEN(node_size + sizeof(pgno_t)); if ((ssize_t)node_size > room) goto full; if ((rc = mdb_page_new(mc, P_OVERFLOW, ovpages, &ofp))) return rc; DPRINTF(("allocated overflow page %"Z"u", ofp->mp_pgno)); flags |= F_BIGDATA; goto update; } else { node_size += data->mv_size; } } node_size = EVEN(node_size); if ((ssize_t)node_size > room) goto full; update: /* Move higher pointers up one slot. */ for (i = NUMKEYS(mp); i > indx; i--) mp->mp_ptrs[i] = mp->mp_ptrs[i - 1]; /* Adjust free space offsets. */ ofs = mp->mp_upper - node_size; mdb_cassert(mc, ofs >= mp->mp_lower + sizeof(indx_t)); mp->mp_ptrs[indx] = ofs; mp->mp_upper = ofs; mp->mp_lower += sizeof(indx_t); /* Write the node data. */ node = NODEPTR(mp, indx); node->mn_ksize = (key == NULL) ? 0 : key->mv_size; node->mn_flags = flags; if (IS_LEAF(mp)) SETDSZ(node,data->mv_size); else SETPGNO(node,pgno); if (key) memcpy(NODEKEY(node), key->mv_data, key->mv_size); if (IS_LEAF(mp)) { ndata = NODEDATA(node); if (ofp == NULL) { if (F_ISSET(flags, F_BIGDATA)) memcpy(ndata, data->mv_data, sizeof(pgno_t)); else if (F_ISSET(flags, MDB_RESERVE)) data->mv_data = ndata; else memcpy(ndata, data->mv_data, data->mv_size); } else { memcpy(ndata, &ofp->mp_pgno, sizeof(pgno_t)); ndata = METADATA(ofp); if (F_ISSET(flags, MDB_RESERVE)) data->mv_data = ndata; else memcpy(ndata, data->mv_data, data->mv_size); } } return MDB_SUCCESS; full: DPRINTF(("not enough room in page %"Z"u, got %u ptrs", mdb_dbg_pgno(mp), NUMKEYS(mp))); DPRINTF(("upper-lower = %u - %u = %"Z"d", mp->mp_upper,mp->mp_lower,room)); DPRINTF(("node size = %"Z"u", node_size)); mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return MDB_PAGE_FULL; } /** Delete the specified node from a page. * @param[in] mc Cursor pointing to the node to delete. * @param[in] ksize The size of a node. Only used if the page is * part of a #MDB_DUPFIXED database. */ static void mdb_node_del(MDB_cursor *mc, int ksize) { MDB_page *mp = mc->mc_pg[mc->mc_top]; indx_t indx = mc->mc_ki[mc->mc_top]; unsigned int sz; indx_t i, j, numkeys, ptr; MDB_node *node; char *base; DPRINTF(("delete node %u on %s page %"Z"u", indx, IS_LEAF(mp) ? "leaf" : "branch", mdb_dbg_pgno(mp))); numkeys = NUMKEYS(mp); mdb_cassert(mc, indx < numkeys); if (IS_LEAF2(mp)) { int x = numkeys - 1 - indx; base = LEAF2KEY(mp, indx, ksize); if (x) memmove(base, base + ksize, x * ksize); mp->mp_lower -= sizeof(indx_t); mp->mp_upper += ksize - sizeof(indx_t); return; } node = NODEPTR(mp, indx); sz = NODESIZE + node->mn_ksize; if (IS_LEAF(mp)) { if (F_ISSET(node->mn_flags, F_BIGDATA)) sz += sizeof(pgno_t); else sz += NODEDSZ(node); } sz = EVEN(sz); ptr = mp->mp_ptrs[indx]; for (i = j = 0; i < numkeys; i++) { if (i != indx) { mp->mp_ptrs[j] = mp->mp_ptrs[i]; if (mp->mp_ptrs[i] < ptr) mp->mp_ptrs[j] += sz; j++; } } base = (char *)mp + mp->mp_upper + PAGEBASE; memmove(base + sz, base, ptr - mp->mp_upper); mp->mp_lower -= sizeof(indx_t); mp->mp_upper += sz; } /** Compact the main page after deleting a node on a subpage. * @param[in] mp The main page to operate on. * @param[in] indx The index of the subpage on the main page. */ static void mdb_node_shrink(MDB_page *mp, indx_t indx) { MDB_node *node; MDB_page *sp, *xp; char *base; indx_t delta, nsize, len, ptr; int i; node = NODEPTR(mp, indx); sp = (MDB_page *)NODEDATA(node); delta = SIZELEFT(sp); nsize = NODEDSZ(node) - delta; /* Prepare to shift upward, set len = length(subpage part to shift) */ if (IS_LEAF2(sp)) { len = nsize; if (nsize & 1) return; /* do not make the node uneven-sized */ } else { xp = (MDB_page *)((char *)sp + delta); /* destination subpage */ for (i = NUMKEYS(sp); --i >= 0; ) xp->mp_ptrs[i] = sp->mp_ptrs[i] - delta; len = PAGEHDRSZ; } sp->mp_upper = sp->mp_lower; COPY_PGNO(sp->mp_pgno, mp->mp_pgno); SETDSZ(node, nsize); /* Shift upward */ base = (char *)mp + mp->mp_upper + PAGEBASE; memmove(base + delta, base, (char *)sp + len - base); ptr = mp->mp_ptrs[indx]; for (i = NUMKEYS(mp); --i >= 0; ) { if (mp->mp_ptrs[i] <= ptr) mp->mp_ptrs[i] += delta; } mp->mp_upper += delta; } /** Initial setup of a sorted-dups cursor. * Sorted duplicates are implemented as a sub-database for the given key. * The duplicate data items are actually keys of the sub-database. * Operations on the duplicate data items are performed using a sub-cursor * initialized when the sub-database is first accessed. This function does * the preliminary setup of the sub-cursor, filling in the fields that * depend only on the parent DB. * @param[in] mc The main cursor whose sorted-dups cursor is to be initialized. */ static void mdb_xcursor_init0(MDB_cursor *mc) { MDB_xcursor *mx = mc->mc_xcursor; mx->mx_cursor.mc_xcursor = NULL; mx->mx_cursor.mc_txn = mc->mc_txn; mx->mx_cursor.mc_db = &mx->mx_db; mx->mx_cursor.mc_dbx = &mx->mx_dbx; mx->mx_cursor.mc_dbi = mc->mc_dbi; mx->mx_cursor.mc_dbflag = &mx->mx_dbflag; mx->mx_cursor.mc_snum = 0; mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_flags = C_SUB; mx->mx_dbx.md_name.mv_size = 0; mx->mx_dbx.md_name.mv_data = NULL; mx->mx_dbx.md_cmp = mc->mc_dbx->md_dcmp; mx->mx_dbx.md_dcmp = NULL; mx->mx_dbx.md_rel = mc->mc_dbx->md_rel; } /** Final setup of a sorted-dups cursor. * Sets up the fields that depend on the data from the main cursor. * @param[in] mc The main cursor whose sorted-dups cursor is to be initialized. * @param[in] node The data containing the #MDB_db record for the * sorted-dup database. */ static void mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node) { MDB_xcursor *mx = mc->mc_xcursor; if (node->mn_flags & F_SUBDATA) { memcpy(&mx->mx_db, NODEDATA(node), sizeof(MDB_db)); mx->mx_cursor.mc_pg[0] = 0; mx->mx_cursor.mc_snum = 0; mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_flags = C_SUB; } else { MDB_page *fp = NODEDATA(node); mx->mx_db.md_pad = 0; mx->mx_db.md_flags = 0; mx->mx_db.md_depth = 1; mx->mx_db.md_branch_pages = 0; mx->mx_db.md_leaf_pages = 1; mx->mx_db.md_overflow_pages = 0; mx->mx_db.md_entries = NUMKEYS(fp); COPY_PGNO(mx->mx_db.md_root, fp->mp_pgno); mx->mx_cursor.mc_snum = 1; mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_flags = C_INITIALIZED|C_SUB; mx->mx_cursor.mc_pg[0] = fp; mx->mx_cursor.mc_ki[0] = 0; if (mc->mc_db->md_flags & MDB_DUPFIXED) { mx->mx_db.md_flags = MDB_DUPFIXED; mx->mx_db.md_pad = fp->mp_pad; if (mc->mc_db->md_flags & MDB_INTEGERDUP) mx->mx_db.md_flags |= MDB_INTEGERKEY; } } DPRINTF(("Sub-db -%u root page %"Z"u", mx->mx_cursor.mc_dbi, mx->mx_db.md_root)); mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */ #if UINT_MAX < SIZE_MAX if (mx->mx_dbx.md_cmp == mdb_cmp_int && mx->mx_db.md_pad == sizeof(size_t)) mx->mx_dbx.md_cmp = mdb_cmp_clong; #endif } /** Fixup a sorted-dups cursor due to underlying update. * Sets up some fields that depend on the data from the main cursor. * Almost the same as init1, but skips initialization steps if the * xcursor had already been used. * @param[in] mc The main cursor whose sorted-dups cursor is to be fixed up. * @param[in] src_mx The xcursor of an up-to-date cursor. * @param[in] new_dupdata True if converting from a non-#F_DUPDATA item. */ static void mdb_xcursor_init2(MDB_cursor *mc, MDB_xcursor *src_mx, int new_dupdata) { MDB_xcursor *mx = mc->mc_xcursor; if (new_dupdata) { mx->mx_cursor.mc_snum = 1; mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_flags |= C_INITIALIZED; mx->mx_cursor.mc_ki[0] = 0; mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */ #if UINT_MAX < SIZE_MAX mx->mx_dbx.md_cmp = src_mx->mx_dbx.md_cmp; #endif } else if (!(mx->mx_cursor.mc_flags & C_INITIALIZED)) { return; } mx->mx_db = src_mx->mx_db; mx->mx_cursor.mc_pg[0] = src_mx->mx_cursor.mc_pg[0]; DPRINTF(("Sub-db -%u root page %"Z"u", mx->mx_cursor.mc_dbi, mx->mx_db.md_root)); } /** Initialize a cursor for a given transaction and database. */ static void mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx) { mc->mc_next = NULL; mc->mc_backup = NULL; mc->mc_dbi = dbi; mc->mc_txn = txn; mc->mc_db = &txn->mt_dbs[dbi]; mc->mc_dbx = &txn->mt_dbxs[dbi]; mc->mc_dbflag = &txn->mt_dbflags[dbi]; mc->mc_snum = 0; mc->mc_top = 0; mc->mc_pg[0] = 0; mc->mc_ki[0] = 0; mc->mc_flags = 0; if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) { mdb_tassert(txn, mx != NULL); mc->mc_xcursor = mx; mdb_xcursor_init0(mc); } else { mc->mc_xcursor = NULL; } if (*mc->mc_dbflag & DB_STALE) { mdb_page_search(mc, NULL, MDB_PS_ROOTONLY); } } int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret) { MDB_cursor *mc; size_t size = sizeof(MDB_cursor); if (!ret || !TXN_DBI_EXIST(txn, dbi, DB_VALID)) return EINVAL; if (txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; if (dbi == FREE_DBI && !F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) return EINVAL; if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) size += sizeof(MDB_xcursor); if ((mc = malloc(size)) != NULL) { mdb_cursor_init(mc, txn, dbi, (MDB_xcursor *)(mc + 1)); if (txn->mt_cursors) { mc->mc_next = txn->mt_cursors[dbi]; txn->mt_cursors[dbi] = mc; mc->mc_flags |= C_UNTRACK; } } else { return ENOMEM; } *ret = mc; return MDB_SUCCESS; } int mdb_cursor_renew(MDB_txn *txn, MDB_cursor *mc) { if (!mc || !TXN_DBI_EXIST(txn, mc->mc_dbi, DB_VALID)) return EINVAL; if ((mc->mc_flags & C_UNTRACK) || txn->mt_cursors) return EINVAL; if (txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; mdb_cursor_init(mc, txn, mc->mc_dbi, mc->mc_xcursor); return MDB_SUCCESS; } /* Return the count of duplicate data items for the current key */ int mdb_cursor_count(MDB_cursor *mc, size_t *countp) { MDB_node *leaf; if (mc == NULL || countp == NULL) return EINVAL; if (mc->mc_xcursor == NULL) return MDB_INCOMPATIBLE; if (mc->mc_txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; if (!(mc->mc_flags & C_INITIALIZED)) return EINVAL; if (!mc->mc_snum || (mc->mc_flags & C_EOF)) return MDB_NOTFOUND; leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { *countp = 1; } else { if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) return EINVAL; *countp = mc->mc_xcursor->mx_db.md_entries; } return MDB_SUCCESS; } void mdb_cursor_close(MDB_cursor *mc) { if (mc && !mc->mc_backup) { /* remove from txn, if tracked */ if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) { MDB_cursor **prev = &mc->mc_txn->mt_cursors[mc->mc_dbi]; while (*prev && *prev != mc) prev = &(*prev)->mc_next; if (*prev == mc) *prev = mc->mc_next; } free(mc); } } MDB_txn * mdb_cursor_txn(MDB_cursor *mc) { if (!mc) return NULL; return mc->mc_txn; } MDB_dbi mdb_cursor_dbi(MDB_cursor *mc) { return mc->mc_dbi; } /** Replace the key for a branch node with a new key. * @param[in] mc Cursor pointing to the node to operate on. * @param[in] key The new key to use. * @return 0 on success, non-zero on failure. */ static int mdb_update_key(MDB_cursor *mc, MDB_val *key) { MDB_page *mp; MDB_node *node; char *base; size_t len; int delta, ksize, oksize; indx_t ptr, i, numkeys, indx; DKBUF; indx = mc->mc_ki[mc->mc_top]; mp = mc->mc_pg[mc->mc_top]; node = NODEPTR(mp, indx); ptr = mp->mp_ptrs[indx]; #if MDB_DEBUG { MDB_val k2; char kbuf2[DKBUF_MAXKEYSIZE*2+1]; k2.mv_data = NODEKEY(node); k2.mv_size = node->mn_ksize; DPRINTF(("update key %u (ofs %u) [%s] to [%s] on page %"Z"u", indx, ptr, mdb_dkey(&k2, kbuf2), DKEY(key), mp->mp_pgno)); } #endif /* Sizes must be 2-byte aligned. */ ksize = EVEN(key->mv_size); oksize = EVEN(node->mn_ksize); delta = ksize - oksize; /* Shift node contents if EVEN(key length) changed. */ if (delta) { if (delta > 0 && SIZELEFT(mp) < delta) { pgno_t pgno; /* not enough space left, do a delete and split */ DPRINTF(("Not enough room, delta = %d, splitting...", delta)); pgno = NODEPGNO(node); mdb_node_del(mc, 0); return mdb_page_split(mc, key, NULL, pgno, MDB_SPLIT_REPLACE); } numkeys = NUMKEYS(mp); for (i = 0; i < numkeys; i++) { if (mp->mp_ptrs[i] <= ptr) mp->mp_ptrs[i] -= delta; } base = (char *)mp + mp->mp_upper + PAGEBASE; len = ptr - mp->mp_upper + NODESIZE; memmove(base - delta, base, len); mp->mp_upper -= delta; node = NODEPTR(mp, indx); } /* But even if no shift was needed, update ksize */ if (node->mn_ksize != key->mv_size) node->mn_ksize = key->mv_size; if (key->mv_size) memcpy(NODEKEY(node), key->mv_data, key->mv_size); return MDB_SUCCESS; } static void mdb_cursor_copy(const MDB_cursor *csrc, MDB_cursor *cdst); /** Move a node from csrc to cdst. */ static int mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst) { MDB_node *srcnode; MDB_val key, data; pgno_t srcpg; MDB_cursor mn; int rc; unsigned short flags; DKBUF; /* Mark src and dst as dirty. */ if ((rc = mdb_page_touch(csrc)) || (rc = mdb_page_touch(cdst))) return rc; if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { key.mv_size = csrc->mc_db->md_pad; key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], csrc->mc_ki[csrc->mc_top], key.mv_size); data.mv_size = 0; data.mv_data = NULL; srcpg = 0; flags = 0; } else { srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], csrc->mc_ki[csrc->mc_top]); mdb_cassert(csrc, !((size_t)srcnode & 1)); srcpg = NODEPGNO(srcnode); flags = srcnode->mn_flags; if (csrc->mc_ki[csrc->mc_top] == 0 && IS_BRANCH(csrc->mc_pg[csrc->mc_top])) { unsigned int snum = csrc->mc_snum; MDB_node *s2; /* must find the lowest key below src */ rc = mdb_page_search_lowest(csrc); if (rc) return rc; if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { key.mv_size = csrc->mc_db->md_pad; key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size); } else { s2 = NODEPTR(csrc->mc_pg[csrc->mc_top], 0); key.mv_size = NODEKSZ(s2); key.mv_data = NODEKEY(s2); } csrc->mc_snum = snum--; csrc->mc_top = snum; } else { key.mv_size = NODEKSZ(srcnode); key.mv_data = NODEKEY(srcnode); } data.mv_size = NODEDSZ(srcnode); data.mv_data = NODEDATA(srcnode); } if (IS_BRANCH(cdst->mc_pg[cdst->mc_top]) && cdst->mc_ki[cdst->mc_top] == 0) { unsigned int snum = cdst->mc_snum; MDB_node *s2; MDB_val bkey; /* must find the lowest key below dst */ mdb_cursor_copy(cdst, &mn); rc = mdb_page_search_lowest(&mn); if (rc) return rc; if (IS_LEAF2(mn.mc_pg[mn.mc_top])) { bkey.mv_size = mn.mc_db->md_pad; bkey.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, bkey.mv_size); } else { s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0); bkey.mv_size = NODEKSZ(s2); bkey.mv_data = NODEKEY(s2); } mn.mc_snum = snum--; mn.mc_top = snum; mn.mc_ki[snum] = 0; rc = mdb_update_key(&mn, &bkey); if (rc) return rc; } DPRINTF(("moving %s node %u [%s] on page %"Z"u to node %u on page %"Z"u", IS_LEAF(csrc->mc_pg[csrc->mc_top]) ? "leaf" : "branch", csrc->mc_ki[csrc->mc_top], DKEY(&key), csrc->mc_pg[csrc->mc_top]->mp_pgno, cdst->mc_ki[cdst->mc_top], cdst->mc_pg[cdst->mc_top]->mp_pgno)); /* Add the node to the destination page. */ rc = mdb_node_add(cdst, cdst->mc_ki[cdst->mc_top], &key, &data, srcpg, flags); if (rc != MDB_SUCCESS) return rc; /* Delete the node from the source page. */ mdb_node_del(csrc, key.mv_size); { /* Adjust other cursors pointing to mp */ MDB_cursor *m2, *m3; MDB_dbi dbi = csrc->mc_dbi; MDB_page *mp; mp = cdst->mc_pg[csrc->mc_top]; for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (csrc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3 == cdst) continue; if (m3->mc_pg[csrc->mc_top] == mp && m3->mc_ki[csrc->mc_top] >= cdst->mc_ki[csrc->mc_top]) { m3->mc_ki[csrc->mc_top]++; } } mp = csrc->mc_pg[csrc->mc_top]; for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (csrc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3 == csrc) continue; if (m3->mc_pg[csrc->mc_top] == mp && m3->mc_ki[csrc->mc_top] == csrc->mc_ki[csrc->mc_top]) { m3->mc_pg[csrc->mc_top] = cdst->mc_pg[cdst->mc_top]; m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top]; } } } /* Update the parent separators. */ if (csrc->mc_ki[csrc->mc_top] == 0) { if (csrc->mc_ki[csrc->mc_top-1] != 0) { if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size); } else { srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], 0); key.mv_size = NODEKSZ(srcnode); key.mv_data = NODEKEY(srcnode); } DPRINTF(("update separator for source page %"Z"u to [%s]", csrc->mc_pg[csrc->mc_top]->mp_pgno, DKEY(&key))); mdb_cursor_copy(csrc, &mn); mn.mc_snum--; mn.mc_top--; if ((rc = mdb_update_key(&mn, &key)) != MDB_SUCCESS) return rc; } if (IS_BRANCH(csrc->mc_pg[csrc->mc_top])) { MDB_val nullkey; indx_t ix = csrc->mc_ki[csrc->mc_top]; nullkey.mv_size = 0; csrc->mc_ki[csrc->mc_top] = 0; rc = mdb_update_key(csrc, &nullkey); csrc->mc_ki[csrc->mc_top] = ix; mdb_cassert(csrc, rc == MDB_SUCCESS); } } if (cdst->mc_ki[cdst->mc_top] == 0) { if (cdst->mc_ki[cdst->mc_top-1] != 0) { if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { key.mv_data = LEAF2KEY(cdst->mc_pg[cdst->mc_top], 0, key.mv_size); } else { srcnode = NODEPTR(cdst->mc_pg[cdst->mc_top], 0); key.mv_size = NODEKSZ(srcnode); key.mv_data = NODEKEY(srcnode); } DPRINTF(("update separator for destination page %"Z"u to [%s]", cdst->mc_pg[cdst->mc_top]->mp_pgno, DKEY(&key))); mdb_cursor_copy(cdst, &mn); mn.mc_snum--; mn.mc_top--; if ((rc = mdb_update_key(&mn, &key)) != MDB_SUCCESS) return rc; } if (IS_BRANCH(cdst->mc_pg[cdst->mc_top])) { MDB_val nullkey; indx_t ix = cdst->mc_ki[cdst->mc_top]; nullkey.mv_size = 0; cdst->mc_ki[cdst->mc_top] = 0; rc = mdb_update_key(cdst, &nullkey); cdst->mc_ki[cdst->mc_top] = ix; mdb_cassert(cdst, rc == MDB_SUCCESS); } } return MDB_SUCCESS; } /** Merge one page into another. * The nodes from the page pointed to by \b csrc will * be copied to the page pointed to by \b cdst and then * the \b csrc page will be freed. * @param[in] csrc Cursor pointing to the source page. * @param[in] cdst Cursor pointing to the destination page. * @return 0 on success, non-zero on failure. */ static int mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) { MDB_page *psrc, *pdst; MDB_node *srcnode; MDB_val key, data; unsigned nkeys; int rc; indx_t i, j; psrc = csrc->mc_pg[csrc->mc_top]; pdst = cdst->mc_pg[cdst->mc_top]; DPRINTF(("merging page %"Z"u into %"Z"u", psrc->mp_pgno, pdst->mp_pgno)); mdb_cassert(csrc, csrc->mc_snum > 1); /* can't merge root page */ mdb_cassert(csrc, cdst->mc_snum > 1); /* Mark dst as dirty. */ if ((rc = mdb_page_touch(cdst))) return rc; /* Move all nodes from src to dst. */ j = nkeys = NUMKEYS(pdst); if (IS_LEAF2(psrc)) { key.mv_size = csrc->mc_db->md_pad; key.mv_data = METADATA(psrc); for (i = 0; i < NUMKEYS(psrc); i++, j++) { rc = mdb_node_add(cdst, j, &key, NULL, 0, 0); if (rc != MDB_SUCCESS) return rc; key.mv_data = (char *)key.mv_data + key.mv_size; } } else { for (i = 0; i < NUMKEYS(psrc); i++, j++) { srcnode = NODEPTR(psrc, i); if (i == 0 && IS_BRANCH(psrc)) { MDB_cursor mn; MDB_node *s2; mdb_cursor_copy(csrc, &mn); /* must find the lowest key below src */ rc = mdb_page_search_lowest(&mn); if (rc) return rc; if (IS_LEAF2(mn.mc_pg[mn.mc_top])) { key.mv_size = mn.mc_db->md_pad; key.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, key.mv_size); } else { s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0); key.mv_size = NODEKSZ(s2); key.mv_data = NODEKEY(s2); } } else { key.mv_size = srcnode->mn_ksize; key.mv_data = NODEKEY(srcnode); } data.mv_size = NODEDSZ(srcnode); data.mv_data = NODEDATA(srcnode); rc = mdb_node_add(cdst, j, &key, &data, NODEPGNO(srcnode), srcnode->mn_flags); if (rc != MDB_SUCCESS) return rc; } } DPRINTF(("dst page %"Z"u now has %u keys (%.1f%% filled)", pdst->mp_pgno, NUMKEYS(pdst), (float)PAGEFILL(cdst->mc_txn->mt_env, pdst) / 10)); /* Unlink the src page from parent and add to free list. */ csrc->mc_top--; mdb_node_del(csrc, 0); if (csrc->mc_ki[csrc->mc_top] == 0) { key.mv_size = 0; rc = mdb_update_key(csrc, &key); if (rc) { csrc->mc_top++; return rc; } } csrc->mc_top++; psrc = csrc->mc_pg[csrc->mc_top]; /* If not operating on FreeDB, allow this page to be reused * in this txn. Otherwise just add to free list. */ rc = mdb_page_loose(csrc, psrc); if (rc) return rc; if (IS_LEAF(psrc)) csrc->mc_db->md_leaf_pages--; else csrc->mc_db->md_branch_pages--; { /* Adjust other cursors pointing to mp */ MDB_cursor *m2, *m3; MDB_dbi dbi = csrc->mc_dbi; for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (csrc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3 == csrc) continue; if (m3->mc_snum < csrc->mc_snum) continue; if (m3->mc_pg[csrc->mc_top] == psrc) { m3->mc_pg[csrc->mc_top] = pdst; m3->mc_ki[csrc->mc_top] += nkeys; } } } { unsigned int snum = cdst->mc_snum; uint16_t depth = cdst->mc_db->md_depth; mdb_cursor_pop(cdst); rc = mdb_rebalance(cdst); /* Did the tree height change? */ if (depth != cdst->mc_db->md_depth) snum += cdst->mc_db->md_depth - depth; cdst->mc_snum = snum; cdst->mc_top = snum-1; } return rc; } /** Copy the contents of a cursor. * @param[in] csrc The cursor to copy from. * @param[out] cdst The cursor to copy to. */ static void mdb_cursor_copy(const MDB_cursor *csrc, MDB_cursor *cdst) { unsigned int i; cdst->mc_txn = csrc->mc_txn; cdst->mc_dbi = csrc->mc_dbi; cdst->mc_db = csrc->mc_db; cdst->mc_dbx = csrc->mc_dbx; cdst->mc_snum = csrc->mc_snum; cdst->mc_top = csrc->mc_top; cdst->mc_flags = csrc->mc_flags; for (i=0; imc_snum; i++) { cdst->mc_pg[i] = csrc->mc_pg[i]; cdst->mc_ki[i] = csrc->mc_ki[i]; } } /** Rebalance the tree after a delete operation. * @param[in] mc Cursor pointing to the page where rebalancing * should begin. * @return 0 on success, non-zero on failure. */ static int mdb_rebalance(MDB_cursor *mc) { MDB_node *node; int rc; unsigned int ptop, minkeys, thresh; MDB_cursor mn; indx_t oldki; if (IS_BRANCH(mc->mc_pg[mc->mc_top])) { minkeys = 1; thresh = 1; } else { minkeys = 2; thresh = FILL_THRESHOLD; } minkeys = 1 + (IS_BRANCH(mc->mc_pg[mc->mc_top])); DPRINTF(("rebalancing %s page %"Z"u (has %u keys, %.1f%% full)", IS_LEAF(mc->mc_pg[mc->mc_top]) ? "leaf" : "branch", mdb_dbg_pgno(mc->mc_pg[mc->mc_top]), NUMKEYS(mc->mc_pg[mc->mc_top]), (float)PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) / 10)); if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= thresh && NUMKEYS(mc->mc_pg[mc->mc_top]) >= minkeys) { DPRINTF(("no need to rebalance page %"Z"u, above fill threshold", mdb_dbg_pgno(mc->mc_pg[mc->mc_top]))); return MDB_SUCCESS; } if (mc->mc_snum < 2) { MDB_page *mp = mc->mc_pg[0]; if (IS_SUBP(mp)) { DPUTS("Can't rebalance a subpage, ignoring"); return MDB_SUCCESS; } if (NUMKEYS(mp) == 0) { DPUTS("tree is completely empty"); mc->mc_db->md_root = P_INVALID; mc->mc_db->md_depth = 0; mc->mc_db->md_leaf_pages = 0; rc = mdb_midl_append(&mc->mc_txn->mt_free_pgs, mp->mp_pgno); if (rc) return rc; /* Adjust cursors pointing to mp */ mc->mc_snum = 0; mc->mc_top = 0; mc->mc_flags &= ~C_INITIALIZED; { MDB_cursor *m2, *m3; MDB_dbi dbi = mc->mc_dbi; for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (mc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[0] == mp) { m3->mc_snum = 0; m3->mc_top = 0; m3->mc_flags &= ~C_INITIALIZED; } } } } else if (IS_BRANCH(mp) && NUMKEYS(mp) == 1) { int i; DPUTS("collapsing root page!"); rc = mdb_midl_append(&mc->mc_txn->mt_free_pgs, mp->mp_pgno); if (rc) return rc; mc->mc_db->md_root = NODEPGNO(NODEPTR(mp, 0)); rc = mdb_page_get(mc->mc_txn,mc->mc_db->md_root,&mc->mc_pg[0],NULL); if (rc) return rc; mc->mc_db->md_depth--; mc->mc_db->md_branch_pages--; mc->mc_ki[0] = mc->mc_ki[1]; for (i = 1; imc_db->md_depth; i++) { mc->mc_pg[i] = mc->mc_pg[i+1]; mc->mc_ki[i] = mc->mc_ki[i+1]; } { /* Adjust other cursors pointing to mp */ MDB_cursor *m2, *m3; MDB_dbi dbi = mc->mc_dbi; for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (mc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[0] == mp) { for (i=0; imc_snum; i++) { m3->mc_pg[i] = m3->mc_pg[i+1]; m3->mc_ki[i] = m3->mc_ki[i+1]; } m3->mc_snum--; m3->mc_top--; } } } } else DPUTS("root page doesn't need rebalancing"); return MDB_SUCCESS; } /* The parent (branch page) must have at least 2 pointers, * otherwise the tree is invalid. */ ptop = mc->mc_top-1; mdb_cassert(mc, NUMKEYS(mc->mc_pg[ptop]) > 1); /* Leaf page fill factor is below the threshold. * Try to move keys from left or right neighbor, or * merge with a neighbor page. */ /* Find neighbors. */ mdb_cursor_copy(mc, &mn); mn.mc_xcursor = NULL; oldki = mc->mc_ki[mc->mc_top]; if (mc->mc_ki[ptop] == 0) { /* We're the leftmost leaf in our parent. */ DPUTS("reading right neighbor"); mn.mc_ki[ptop]++; node = NODEPTR(mc->mc_pg[ptop], mn.mc_ki[ptop]); rc = mdb_page_get(mc->mc_txn,NODEPGNO(node),&mn.mc_pg[mn.mc_top],NULL); if (rc) return rc; mn.mc_ki[mn.mc_top] = 0; mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]); } else { /* There is at least one neighbor to the left. */ DPUTS("reading left neighbor"); mn.mc_ki[ptop]--; node = NODEPTR(mc->mc_pg[ptop], mn.mc_ki[ptop]); rc = mdb_page_get(mc->mc_txn,NODEPGNO(node),&mn.mc_pg[mn.mc_top],NULL); if (rc) return rc; mn.mc_ki[mn.mc_top] = NUMKEYS(mn.mc_pg[mn.mc_top]) - 1; mc->mc_ki[mc->mc_top] = 0; } DPRINTF(("found neighbor page %"Z"u (%u keys, %.1f%% full)", mn.mc_pg[mn.mc_top]->mp_pgno, NUMKEYS(mn.mc_pg[mn.mc_top]), (float)PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) / 10)); /* If the neighbor page is above threshold and has enough keys, * move one key from it. Otherwise we should try to merge them. * (A branch page must never have less than 2 keys.) */ minkeys = 1 + (IS_BRANCH(mn.mc_pg[mn.mc_top])); if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= thresh && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) { rc = mdb_node_move(&mn, mc); if (mc->mc_ki[mc->mc_top-1]) { oldki++; } } else { if (mc->mc_ki[ptop] == 0) { rc = mdb_page_merge(&mn, mc); } else { MDB_cursor dummy; oldki += NUMKEYS(mn.mc_pg[mn.mc_top]); mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1; /* We want mdb_rebalance to find mn when doing fixups */ if (mc->mc_flags & C_SUB) { dummy.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; mc->mc_txn->mt_cursors[mc->mc_dbi] = &dummy; dummy.mc_xcursor = (MDB_xcursor *)&mn; } else { mn.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; mc->mc_txn->mt_cursors[mc->mc_dbi] = &mn; } rc = mdb_page_merge(mc, &mn); if (mc->mc_flags & C_SUB) mc->mc_txn->mt_cursors[mc->mc_dbi] = dummy.mc_next; else mc->mc_txn->mt_cursors[mc->mc_dbi] = mn.mc_next; mdb_cursor_copy(&mn, mc); } mc->mc_flags &= ~C_EOF; } mc->mc_ki[mc->mc_top] = oldki; return rc; } /** Complete a delete operation started by #mdb_cursor_del(). */ static int mdb_cursor_del0(MDB_cursor *mc) { int rc; MDB_page *mp; indx_t ki; unsigned int nkeys; MDB_cursor *m2, *m3; MDB_dbi dbi = mc->mc_dbi; ki = mc->mc_ki[mc->mc_top]; mp = mc->mc_pg[mc->mc_top]; mdb_node_del(mc, mc->mc_db->md_pad); mc->mc_db->md_entries--; { /* Adjust other cursors pointing to mp */ for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { m3 = (mc->mc_flags & C_SUB) ? &m2->mc_xcursor->mx_cursor : m2; if (! (m2->mc_flags & m3->mc_flags & C_INITIALIZED)) continue; if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[mc->mc_top] == mp) { if (m3->mc_ki[mc->mc_top] >= ki) { m3->mc_flags |= C_DEL; if (m3->mc_ki[mc->mc_top] > ki) m3->mc_ki[mc->mc_top]--; else if (mc->mc_db->md_flags & MDB_DUPSORT) m3->mc_xcursor->mx_cursor.mc_flags |= C_EOF; } } } } rc = mdb_rebalance(mc); if (rc == MDB_SUCCESS) { /* DB is totally empty now, just bail out. * Other cursors adjustments were already done * by mdb_rebalance and aren't needed here. */ if (!mc->mc_snum) return rc; mp = mc->mc_pg[mc->mc_top]; nkeys = NUMKEYS(mp); /* Adjust other cursors pointing to mp */ for (m2 = mc->mc_txn->mt_cursors[dbi]; !rc && m2; m2=m2->mc_next) { m3 = (mc->mc_flags & C_SUB) ? &m2->mc_xcursor->mx_cursor : m2; if (! (m2->mc_flags & m3->mc_flags & C_INITIALIZED)) continue; if (m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[mc->mc_top] == mp) { /* if m3 points past last node in page, find next sibling */ if (m3->mc_ki[mc->mc_top] >= nkeys) { rc = mdb_cursor_sibling(m3, 1); if (rc == MDB_NOTFOUND) { m3->mc_flags |= C_EOF; rc = MDB_SUCCESS; } } } } mc->mc_flags |= C_DEL; } if (rc) mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return rc; } int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data) { if (!key || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED)) return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN; if (!F_ISSET(txn->mt_dbs[dbi].md_flags, MDB_DUPSORT)) { /* must ignore any data */ data = NULL; } return mdb_del0(txn, dbi, key, data, 0); } static int mdb_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned flags) { MDB_cursor mc; MDB_xcursor mx; MDB_cursor_op op; MDB_val rdata, *xdata; int rc, exact = 0; DKBUF; DPRINTF(("====> delete db %u key [%s]", dbi, DKEY(key))); mdb_cursor_init(&mc, txn, dbi, &mx); if (data) { op = MDB_GET_BOTH; rdata = *data; xdata = &rdata; } else { op = MDB_SET; xdata = NULL; flags |= MDB_NODUPDATA; } rc = mdb_cursor_set(&mc, key, xdata, op, &exact); if (rc == 0) { /* let mdb_page_split know about this cursor if needed: * delete will trigger a rebalance; if it needs to move * a node from one page to another, it will have to * update the parent's separator key(s). If the new sepkey * is larger than the current one, the parent page may * run out of space, triggering a split. We need this * cursor to be consistent until the end of the rebalance. */ mc.mc_flags |= C_UNTRACK; mc.mc_next = txn->mt_cursors[dbi]; txn->mt_cursors[dbi] = &mc; rc = mdb_cursor_del(&mc, flags); txn->mt_cursors[dbi] = mc.mc_next; } return rc; } /** Split a page and insert a new node. * @param[in,out] mc Cursor pointing to the page and desired insertion index. * The cursor will be updated to point to the actual page and index where * the node got inserted after the split. * @param[in] newkey The key for the newly inserted node. * @param[in] newdata The data for the newly inserted node. * @param[in] newpgno The page number, if the new node is a branch node. * @param[in] nflags The #NODE_ADD_FLAGS for the new node. * @return 0 on success, non-zero on failure. */ static int mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno, unsigned int nflags) { unsigned int flags; int rc = MDB_SUCCESS, new_root = 0, did_split = 0; indx_t newindx; pgno_t pgno = 0; int i, j, split_indx, nkeys, pmax; MDB_env *env = mc->mc_txn->mt_env; MDB_node *node; MDB_val sepkey, rkey, xdata, *rdata = &xdata; MDB_page *copy = NULL; MDB_page *mp, *rp, *pp; int ptop; MDB_cursor mn; DKBUF; mp = mc->mc_pg[mc->mc_top]; newindx = mc->mc_ki[mc->mc_top]; nkeys = NUMKEYS(mp); DPRINTF(("-----> splitting %s page %"Z"u and adding [%s] at index %i/%i", IS_LEAF(mp) ? "leaf" : "branch", mp->mp_pgno, DKEY(newkey), mc->mc_ki[mc->mc_top], nkeys)); /* Create a right sibling. */ if ((rc = mdb_page_new(mc, mp->mp_flags, 1, &rp))) return rc; rp->mp_pad = mp->mp_pad; DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno)); if (mc->mc_snum < 2) { if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp))) goto done; /* shift current top to make room for new parent */ mc->mc_pg[1] = mc->mc_pg[0]; mc->mc_ki[1] = mc->mc_ki[0]; mc->mc_pg[0] = pp; mc->mc_ki[0] = 0; mc->mc_db->md_root = pp->mp_pgno; DPRINTF(("root split! new root = %"Z"u", pp->mp_pgno)); new_root = mc->mc_db->md_depth++; /* Add left (implicit) pointer. */ if ((rc = mdb_node_add(mc, 0, NULL, NULL, mp->mp_pgno, 0)) != MDB_SUCCESS) { /* undo the pre-push */ mc->mc_pg[0] = mc->mc_pg[1]; mc->mc_ki[0] = mc->mc_ki[1]; mc->mc_db->md_root = mp->mp_pgno; mc->mc_db->md_depth--; goto done; } mc->mc_snum = 2; mc->mc_top = 1; ptop = 0; } else { ptop = mc->mc_top-1; DPRINTF(("parent branch page is %"Z"u", mc->mc_pg[ptop]->mp_pgno)); } mc->mc_flags |= C_SPLITTING; mdb_cursor_copy(mc, &mn); mn.mc_pg[mn.mc_top] = rp; mn.mc_ki[ptop] = mc->mc_ki[ptop]+1; if (nflags & MDB_APPEND) { mn.mc_ki[mn.mc_top] = 0; sepkey = *newkey; split_indx = newindx; nkeys = 0; } else { split_indx = (nkeys+1) / 2; if (IS_LEAF2(rp)) { char *split, *ins; int x; unsigned int lsize, rsize, ksize; /* Move half of the keys to the right sibling */ x = mc->mc_ki[mc->mc_top] - split_indx; ksize = mc->mc_db->md_pad; split = LEAF2KEY(mp, split_indx, ksize); rsize = (nkeys - split_indx) * ksize; lsize = (nkeys - split_indx) * sizeof(indx_t); mp->mp_lower -= lsize; rp->mp_lower += lsize; mp->mp_upper += rsize - lsize; rp->mp_upper -= rsize - lsize; sepkey.mv_size = ksize; if (newindx == split_indx) { sepkey.mv_data = newkey->mv_data; } else { sepkey.mv_data = split; } if (x<0) { ins = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], ksize); memcpy(rp->mp_ptrs, split, rsize); sepkey.mv_data = rp->mp_ptrs; memmove(ins+ksize, ins, (split_indx - mc->mc_ki[mc->mc_top]) * ksize); memcpy(ins, newkey->mv_data, ksize); mp->mp_lower += sizeof(indx_t); mp->mp_upper -= ksize - sizeof(indx_t); } else { if (x) memcpy(rp->mp_ptrs, split, x * ksize); ins = LEAF2KEY(rp, x, ksize); memcpy(ins, newkey->mv_data, ksize); memcpy(ins+ksize, split + x * ksize, rsize - x * ksize); rp->mp_lower += sizeof(indx_t); rp->mp_upper -= ksize - sizeof(indx_t); mc->mc_ki[mc->mc_top] = x; mc->mc_pg[mc->mc_top] = rp; } } else { int psize, nsize, k; /* Maximum free space in an empty page */ pmax = env->me_psize - PAGEHDRSZ; if (IS_LEAF(mp)) nsize = mdb_leaf_size(env, newkey, newdata); else nsize = mdb_branch_size(env, newkey); nsize = EVEN(nsize); /* grab a page to hold a temporary copy */ copy = mdb_page_malloc(mc->mc_txn, 1); if (copy == NULL) { rc = ENOMEM; goto done; } copy->mp_pgno = mp->mp_pgno; copy->mp_flags = mp->mp_flags; copy->mp_lower = (PAGEHDRSZ-PAGEBASE); copy->mp_upper = env->me_psize - PAGEBASE; /* prepare to insert */ for (i=0, j=0; imp_ptrs[j++] = 0; } copy->mp_ptrs[j++] = mp->mp_ptrs[i]; } /* When items are relatively large the split point needs * to be checked, because being off-by-one will make the * difference between success or failure in mdb_node_add. * * It's also relevant if a page happens to be laid out * such that one half of its nodes are all "small" and * the other half of its nodes are "large." If the new * item is also "large" and falls on the half with * "large" nodes, it also may not fit. * * As a final tweak, if the new item goes on the last * spot on the page (and thus, onto the new page), bias * the split so the new page is emptier than the old page. * This yields better packing during sequential inserts. */ if (nkeys < 20 || nsize > pmax/16 || newindx >= nkeys) { /* Find split point */ psize = 0; if (newindx <= split_indx || newindx >= nkeys) { i = 0; j = 1; k = newindx >= nkeys ? nkeys : split_indx+1+IS_LEAF(mp); } else { i = nkeys; j = -1; k = split_indx-1; } for (; i!=k; i+=j) { if (i == newindx) { psize += nsize; node = NULL; } else { node = (MDB_node *)((char *)mp + copy->mp_ptrs[i] + PAGEBASE); psize += NODESIZE + NODEKSZ(node) + sizeof(indx_t); if (IS_LEAF(mp)) { if (F_ISSET(node->mn_flags, F_BIGDATA)) psize += sizeof(pgno_t); else psize += NODEDSZ(node); } psize = EVEN(psize); } if (psize > pmax || i == k-j) { split_indx = i + (j<0); break; } } } if (split_indx == newindx) { sepkey.mv_size = newkey->mv_size; sepkey.mv_data = newkey->mv_data; } else { node = (MDB_node *)((char *)mp + copy->mp_ptrs[split_indx] + PAGEBASE); sepkey.mv_size = node->mn_ksize; sepkey.mv_data = NODEKEY(node); } } } DPRINTF(("separator is %d [%s]", split_indx, DKEY(&sepkey))); /* Copy separator key to the parent. */ if (SIZELEFT(mn.mc_pg[ptop]) < mdb_branch_size(env, &sepkey)) { mn.mc_snum--; mn.mc_top--; did_split = 1; rc = mdb_page_split(&mn, &sepkey, NULL, rp->mp_pgno, 0); if (rc) goto done; /* root split? */ if (mn.mc_snum == mc->mc_snum) { mc->mc_pg[mc->mc_snum] = mc->mc_pg[mc->mc_top]; mc->mc_ki[mc->mc_snum] = mc->mc_ki[mc->mc_top]; mc->mc_pg[mc->mc_top] = mc->mc_pg[ptop]; mc->mc_ki[mc->mc_top] = mc->mc_ki[ptop]; mc->mc_snum++; mc->mc_top++; ptop++; } /* Right page might now have changed parent. * Check if left page also changed parent. */ if (mn.mc_pg[ptop] != mc->mc_pg[ptop] && mc->mc_ki[ptop] >= NUMKEYS(mc->mc_pg[ptop])) { for (i=0; imc_pg[i] = mn.mc_pg[i]; mc->mc_ki[i] = mn.mc_ki[i]; } mc->mc_pg[ptop] = mn.mc_pg[ptop]; if (mn.mc_ki[ptop]) { mc->mc_ki[ptop] = mn.mc_ki[ptop] - 1; } else { /* find right page's left sibling */ mc->mc_ki[ptop] = mn.mc_ki[ptop]; mdb_cursor_sibling(mc, 0); } } } else { mn.mc_top--; rc = mdb_node_add(&mn, mn.mc_ki[ptop], &sepkey, NULL, rp->mp_pgno, 0); mn.mc_top++; } mc->mc_flags ^= C_SPLITTING; if (rc != MDB_SUCCESS) { goto done; } if (nflags & MDB_APPEND) { mc->mc_pg[mc->mc_top] = rp; mc->mc_ki[mc->mc_top] = 0; rc = mdb_node_add(mc, 0, newkey, newdata, newpgno, nflags); if (rc) goto done; for (i=0; imc_top; i++) mc->mc_ki[i] = mn.mc_ki[i]; } else if (!IS_LEAF2(mp)) { /* Move nodes */ mc->mc_pg[mc->mc_top] = rp; i = split_indx; j = 0; do { if (i == newindx) { rkey.mv_data = newkey->mv_data; rkey.mv_size = newkey->mv_size; if (IS_LEAF(mp)) { rdata = newdata; } else pgno = newpgno; flags = nflags; /* Update index for the new key. */ mc->mc_ki[mc->mc_top] = j; } else { node = (MDB_node *)((char *)mp + copy->mp_ptrs[i] + PAGEBASE); rkey.mv_data = NODEKEY(node); rkey.mv_size = node->mn_ksize; if (IS_LEAF(mp)) { xdata.mv_data = NODEDATA(node); xdata.mv_size = NODEDSZ(node); rdata = &xdata; } else pgno = NODEPGNO(node); flags = node->mn_flags; } if (!IS_LEAF(mp) && j == 0) { /* First branch index doesn't need key data. */ rkey.mv_size = 0; } rc = mdb_node_add(mc, j, &rkey, rdata, pgno, flags); if (rc) goto done; if (i == nkeys) { i = 0; j = 0; mc->mc_pg[mc->mc_top] = copy; } else { i++; j++; } } while (i != split_indx); nkeys = NUMKEYS(copy); for (i=0; imp_ptrs[i] = copy->mp_ptrs[i]; mp->mp_lower = copy->mp_lower; mp->mp_upper = copy->mp_upper; memcpy(NODEPTR(mp, nkeys-1), NODEPTR(copy, nkeys-1), env->me_psize - copy->mp_upper - PAGEBASE); /* reset back to original page */ if (newindx < split_indx) { mc->mc_pg[mc->mc_top] = mp; if (nflags & MDB_RESERVE) { node = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (!(node->mn_flags & F_BIGDATA)) newdata->mv_data = NODEDATA(node); } } else { mc->mc_pg[mc->mc_top] = rp; mc->mc_ki[ptop]++; /* Make sure mc_ki is still valid. */ if (mn.mc_pg[ptop] != mc->mc_pg[ptop] && mc->mc_ki[ptop] >= NUMKEYS(mc->mc_pg[ptop])) { for (i=0; i<=ptop; i++) { mc->mc_pg[i] = mn.mc_pg[i]; mc->mc_ki[i] = mn.mc_ki[i]; } } } } { /* Adjust other cursors pointing to mp */ MDB_cursor *m2, *m3; MDB_dbi dbi = mc->mc_dbi; int fixup = NUMKEYS(mp); for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (mc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; if (m3 == mc) continue; if (!(m2->mc_flags & m3->mc_flags & C_INITIALIZED)) continue; if (m3->mc_flags & C_SPLITTING) continue; if (new_root) { int k; /* root split */ for (k=new_root; k>=0; k--) { m3->mc_ki[k+1] = m3->mc_ki[k]; m3->mc_pg[k+1] = m3->mc_pg[k]; } if (m3->mc_ki[0] >= split_indx) { m3->mc_ki[0] = 1; } else { m3->mc_ki[0] = 0; } m3->mc_pg[0] = mc->mc_pg[0]; m3->mc_snum++; m3->mc_top++; } if (m3->mc_top >= mc->mc_top && m3->mc_pg[mc->mc_top] == mp) { if (m3->mc_ki[mc->mc_top] >= newindx && !(nflags & MDB_SPLIT_REPLACE)) m3->mc_ki[mc->mc_top]++; if (m3->mc_ki[mc->mc_top] >= fixup) { m3->mc_pg[mc->mc_top] = rp; m3->mc_ki[mc->mc_top] -= fixup; m3->mc_ki[ptop] = mn.mc_ki[ptop]; } } else if (!did_split && m3->mc_top >= ptop && m3->mc_pg[ptop] == mc->mc_pg[ptop] && m3->mc_ki[ptop] >= mc->mc_ki[ptop]) { m3->mc_ki[ptop]++; } } } DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp))); done: if (copy) /* tmp page */ mdb_page_free(env, copy); if (rc) mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return rc; } int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags) { MDB_cursor mc; MDB_xcursor mx; if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; if (flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP)) return EINVAL; if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED)) return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN; mdb_cursor_init(&mc, txn, dbi, &mx); return mdb_cursor_put(&mc, key, data, flags); } #ifndef MDB_WBUF #define MDB_WBUF (1024*1024) #endif /** State needed for a compacting copy. */ typedef struct mdb_copy { pthread_mutex_t mc_mutex; pthread_cond_t mc_cond; char *mc_wbuf[2]; char *mc_over[2]; MDB_env *mc_env; MDB_txn *mc_txn; int mc_wlen[2]; int mc_olen[2]; pgno_t mc_next_pgno; HANDLE mc_fd; int mc_status; volatile int mc_new; int mc_toggle; } mdb_copy; /** Dedicated writer thread for compacting copy. */ static THREAD_RET ESECT mdb_env_copythr(void *arg) { mdb_copy *my = arg; char *ptr; int toggle = 0, wsize, rc; #ifdef _WIN32 DWORD len; #define DO_WRITE(rc, fd, ptr, w2, len) rc = WriteFile(fd, ptr, w2, &len, NULL) #else int len; #define DO_WRITE(rc, fd, ptr, w2, len) len = write(fd, ptr, w2); rc = (len >= 0) #endif pthread_mutex_lock(&my->mc_mutex); my->mc_new = 0; pthread_cond_signal(&my->mc_cond); for(;;) { while (!my->mc_new) pthread_cond_wait(&my->mc_cond, &my->mc_mutex); if (my->mc_new < 0) { my->mc_new = 0; break; } my->mc_new = 0; wsize = my->mc_wlen[toggle]; ptr = my->mc_wbuf[toggle]; again: while (wsize > 0) { DO_WRITE(rc, my->mc_fd, ptr, wsize, len); if (!rc) { rc = ErrCode(); break; } else if (len > 0) { rc = MDB_SUCCESS; ptr += len; wsize -= len; continue; } else { rc = EIO; break; } } if (rc) { my->mc_status = rc; break; } /* If there's an overflow page tail, write it too */ if (my->mc_olen[toggle]) { wsize = my->mc_olen[toggle]; ptr = my->mc_over[toggle]; my->mc_olen[toggle] = 0; goto again; } my->mc_wlen[toggle] = 0; toggle ^= 1; pthread_cond_signal(&my->mc_cond); } pthread_cond_signal(&my->mc_cond); pthread_mutex_unlock(&my->mc_mutex); return (THREAD_RET)0; #undef DO_WRITE } /** Tell the writer thread there's a buffer ready to write */ static int ESECT mdb_env_cthr_toggle(mdb_copy *my, int st) { int toggle = my->mc_toggle ^ 1; pthread_mutex_lock(&my->mc_mutex); if (my->mc_status) { pthread_mutex_unlock(&my->mc_mutex); return my->mc_status; } while (my->mc_new == 1) pthread_cond_wait(&my->mc_cond, &my->mc_mutex); my->mc_new = st; my->mc_toggle = toggle; pthread_cond_signal(&my->mc_cond); pthread_mutex_unlock(&my->mc_mutex); return 0; } /** Depth-first tree traversal for compacting copy. */ static int ESECT mdb_env_cwalk(mdb_copy *my, pgno_t *pg, int flags) { MDB_cursor mc; MDB_txn *txn = my->mc_txn; MDB_node *ni; MDB_page *mo, *mp, *leaf; char *buf, *ptr; int rc, toggle; unsigned int i; /* Empty DB, nothing to do */ if (*pg == P_INVALID) return MDB_SUCCESS; mc.mc_snum = 1; mc.mc_top = 0; mc.mc_txn = txn; rc = mdb_page_get(my->mc_txn, *pg, &mc.mc_pg[0], NULL); if (rc) return rc; rc = mdb_page_search_root(&mc, NULL, MDB_PS_FIRST); if (rc) return rc; /* Make cursor pages writable */ buf = ptr = malloc(my->mc_env->me_psize * mc.mc_snum); if (buf == NULL) return ENOMEM; for (i=0; imc_env->me_psize); mc.mc_pg[i] = (MDB_page *)ptr; ptr += my->mc_env->me_psize; } /* This is writable space for a leaf page. Usually not needed. */ leaf = (MDB_page *)ptr; toggle = my->mc_toggle; while (mc.mc_snum > 0) { unsigned n; mp = mc.mc_pg[mc.mc_top]; n = NUMKEYS(mp); if (IS_LEAF(mp)) { if (!IS_LEAF2(mp) && !(flags & F_DUPDATA)) { for (i=0; imn_flags & F_BIGDATA) { MDB_page *omp; pgno_t pg; /* Need writable leaf */ if (mp != leaf) { mc.mc_pg[mc.mc_top] = leaf; mdb_page_copy(leaf, mp, my->mc_env->me_psize); mp = leaf; ni = NODEPTR(mp, i); } memcpy(&pg, NODEDATA(ni), sizeof(pg)); rc = mdb_page_get(txn, pg, &omp, NULL); if (rc) goto done; if (my->mc_wlen[toggle] >= MDB_WBUF) { rc = mdb_env_cthr_toggle(my, 1); if (rc) goto done; toggle = my->mc_toggle; } mo = (MDB_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]); memcpy(mo, omp, my->mc_env->me_psize); mo->mp_pgno = my->mc_next_pgno; my->mc_next_pgno += omp->mp_pages; my->mc_wlen[toggle] += my->mc_env->me_psize; if (omp->mp_pages > 1) { my->mc_olen[toggle] = my->mc_env->me_psize * (omp->mp_pages - 1); my->mc_over[toggle] = (char *)omp + my->mc_env->me_psize; rc = mdb_env_cthr_toggle(my, 1); if (rc) goto done; toggle = my->mc_toggle; } memcpy(NODEDATA(ni), &mo->mp_pgno, sizeof(pgno_t)); } else if (ni->mn_flags & F_SUBDATA) { MDB_db db; /* Need writable leaf */ if (mp != leaf) { mc.mc_pg[mc.mc_top] = leaf; mdb_page_copy(leaf, mp, my->mc_env->me_psize); mp = leaf; ni = NODEPTR(mp, i); } memcpy(&db, NODEDATA(ni), sizeof(db)); my->mc_toggle = toggle; rc = mdb_env_cwalk(my, &db.md_root, ni->mn_flags & F_DUPDATA); if (rc) goto done; toggle = my->mc_toggle; memcpy(NODEDATA(ni), &db, sizeof(db)); } } } } else { mc.mc_ki[mc.mc_top]++; if (mc.mc_ki[mc.mc_top] < n) { pgno_t pg; again: ni = NODEPTR(mp, mc.mc_ki[mc.mc_top]); pg = NODEPGNO(ni); rc = mdb_page_get(txn, pg, &mp, NULL); if (rc) goto done; mc.mc_top++; mc.mc_snum++; mc.mc_ki[mc.mc_top] = 0; if (IS_BRANCH(mp)) { /* Whenever we advance to a sibling branch page, * we must proceed all the way down to its first leaf. */ mdb_page_copy(mc.mc_pg[mc.mc_top], mp, my->mc_env->me_psize); goto again; } else mc.mc_pg[mc.mc_top] = mp; continue; } } if (my->mc_wlen[toggle] >= MDB_WBUF) { rc = mdb_env_cthr_toggle(my, 1); if (rc) goto done; toggle = my->mc_toggle; } mo = (MDB_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]); mdb_page_copy(mo, mp, my->mc_env->me_psize); mo->mp_pgno = my->mc_next_pgno++; my->mc_wlen[toggle] += my->mc_env->me_psize; if (mc.mc_top) { /* Update parent if there is one */ ni = NODEPTR(mc.mc_pg[mc.mc_top-1], mc.mc_ki[mc.mc_top-1]); SETPGNO(ni, mo->mp_pgno); mdb_cursor_pop(&mc); } else { /* Otherwise we're done */ *pg = mo->mp_pgno; break; } } done: free(buf); return rc; } /** Copy environment with compaction. */ static int ESECT mdb_env_copyfd1(MDB_env *env, HANDLE fd) { MDB_meta *mm; MDB_page *mp; mdb_copy my; MDB_txn *txn = NULL; pthread_t thr; int rc; #ifdef _WIN32 my.mc_mutex = CreateMutex(NULL, FALSE, NULL); my.mc_cond = CreateEvent(NULL, FALSE, FALSE, NULL); my.mc_wbuf[0] = _aligned_malloc(MDB_WBUF*2, env->me_os_psize); if (my.mc_wbuf[0] == NULL) return errno; #else pthread_mutex_init(&my.mc_mutex, NULL); pthread_cond_init(&my.mc_cond, NULL); #ifdef HAVE_MEMALIGN my.mc_wbuf[0] = memalign(env->me_os_psize, MDB_WBUF*2); if (my.mc_wbuf[0] == NULL) return errno; #else rc = posix_memalign((void **)&my.mc_wbuf[0], env->me_os_psize, MDB_WBUF*2); if (rc) return rc; #endif #endif memset(my.mc_wbuf[0], 0, MDB_WBUF*2); my.mc_wbuf[1] = my.mc_wbuf[0] + MDB_WBUF; my.mc_wlen[0] = 0; my.mc_wlen[1] = 0; my.mc_olen[0] = 0; my.mc_olen[1] = 0; my.mc_next_pgno = NUM_METAS; my.mc_status = 0; my.mc_new = 1; my.mc_toggle = 0; my.mc_env = env; my.mc_fd = fd; THREAD_CREATE(thr, mdb_env_copythr, &my); rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (rc) return rc; mp = (MDB_page *)my.mc_wbuf[0]; memset(mp, 0, NUM_METAS * env->me_psize); mp->mp_pgno = 0; mp->mp_flags = P_META; mm = (MDB_meta *)METADATA(mp); mdb_env_init_meta0(env, mm); mm->mm_address = env->me_metas[0]->mm_address; mp = (MDB_page *)(my.mc_wbuf[0] + env->me_psize); mp->mp_pgno = 1; mp->mp_flags = P_META; *(MDB_meta *)METADATA(mp) = *mm; mm = (MDB_meta *)METADATA(mp); /* Count the number of free pages, subtract from lastpg to find * number of active pages */ { MDB_ID freecount = 0; MDB_cursor mc; MDB_val key, data; mdb_cursor_init(&mc, txn, FREE_DBI, NULL); while ((rc = mdb_cursor_get(&mc, &key, &data, MDB_NEXT)) == 0) freecount += *(MDB_ID *)data.mv_data; freecount += txn->mt_dbs[FREE_DBI].md_branch_pages + txn->mt_dbs[FREE_DBI].md_leaf_pages + txn->mt_dbs[FREE_DBI].md_overflow_pages; /* Set metapage 1 */ mm->mm_last_pg = txn->mt_next_pgno - freecount - 1; mm->mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI]; if (mm->mm_last_pg > NUM_METAS-1) { mm->mm_dbs[MAIN_DBI].md_root = mm->mm_last_pg; mm->mm_txnid = 1; } else { mm->mm_dbs[MAIN_DBI].md_root = P_INVALID; } } my.mc_wlen[0] = env->me_psize * NUM_METAS; my.mc_txn = txn; pthread_mutex_lock(&my.mc_mutex); while(my.mc_new) pthread_cond_wait(&my.mc_cond, &my.mc_mutex); pthread_mutex_unlock(&my.mc_mutex); rc = mdb_env_cwalk(&my, &txn->mt_dbs[MAIN_DBI].md_root, 0); if (rc == MDB_SUCCESS && my.mc_wlen[my.mc_toggle]) rc = mdb_env_cthr_toggle(&my, 1); mdb_env_cthr_toggle(&my, -1); pthread_mutex_lock(&my.mc_mutex); while(my.mc_new) pthread_cond_wait(&my.mc_cond, &my.mc_mutex); pthread_mutex_unlock(&my.mc_mutex); THREAD_FINISH(thr); mdb_txn_abort(txn); #ifdef _WIN32 CloseHandle(my.mc_cond); CloseHandle(my.mc_mutex); _aligned_free(my.mc_wbuf[0]); #else pthread_cond_destroy(&my.mc_cond); pthread_mutex_destroy(&my.mc_mutex); free(my.mc_wbuf[0]); #endif return rc; } /** Copy environment as-is. */ static int ESECT mdb_env_copyfd0(MDB_env *env, HANDLE fd) { MDB_txn *txn = NULL; mdb_mutexref_t wmutex = NULL; int rc; size_t wsize; char *ptr; #ifdef _WIN32 DWORD len, w2; #define DO_WRITE(rc, fd, ptr, w2, len) rc = WriteFile(fd, ptr, w2, &len, NULL) #else ssize_t len; size_t w2; #define DO_WRITE(rc, fd, ptr, w2, len) len = write(fd, ptr, w2); rc = (len >= 0) #endif /* Do the lock/unlock of the reader mutex before starting the * write txn. Otherwise other read txns could block writers. */ rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (rc) return rc; if (env->me_txns) { /* We must start the actual read txn after blocking writers */ mdb_txn_end(txn, MDB_END_RESET_TMP); /* Temporarily block writers until we snapshot the meta pages */ wmutex = env->me_wmutex; if (LOCK_MUTEX(rc, env, wmutex)) goto leave; rc = mdb_txn_renew0(txn); if (rc) { UNLOCK_MUTEX(wmutex); goto leave; } } wsize = env->me_psize * NUM_METAS; ptr = env->me_map; w2 = wsize; while (w2 > 0) { DO_WRITE(rc, fd, ptr, w2, len); if (!rc) { rc = ErrCode(); break; } else if (len > 0) { rc = MDB_SUCCESS; ptr += len; w2 -= len; continue; } else { /* Non-blocking or async handles are not supported */ rc = EIO; break; } } if (wmutex) UNLOCK_MUTEX(wmutex); if (rc) goto leave; w2 = txn->mt_next_pgno * env->me_psize; { size_t fsize = 0; if ((rc = mdb_fsize(env->me_fd, &fsize))) goto leave; if (w2 > fsize) w2 = fsize; } wsize = w2 - wsize; while (wsize > 0) { if (wsize > MAX_WRITE) w2 = MAX_WRITE; else w2 = wsize; DO_WRITE(rc, fd, ptr, w2, len); if (!rc) { rc = ErrCode(); break; } else if (len > 0) { rc = MDB_SUCCESS; ptr += len; wsize -= len; continue; } else { rc = EIO; break; } } leave: mdb_txn_abort(txn); return rc; } int ESECT mdb_env_copyfd2(MDB_env *env, HANDLE fd, unsigned int flags) { if (flags & MDB_CP_COMPACT) return mdb_env_copyfd1(env, fd); else return mdb_env_copyfd0(env, fd); } int ESECT mdb_env_copyfd(MDB_env *env, HANDLE fd) { return mdb_env_copyfd2(env, fd, 0); } int ESECT mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags) { int rc, len; char *lpath; HANDLE newfd = INVALID_HANDLE_VALUE; if (env->me_flags & MDB_NOSUBDIR) { lpath = (char *)path; } else { len = strlen(path); len += sizeof(DATANAME); lpath = malloc(len); if (!lpath) return ENOMEM; sprintf(lpath, "%s" DATANAME, path); } /* The destination path must exist, but the destination file must not. * We don't want the OS to cache the writes, since the source data is * already in the OS cache. */ #ifdef _WIN32 newfd = CreateFileA(lpath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL); #else newfd = open(lpath, O_WRONLY|O_CREAT|O_EXCL, 0666); #endif if (newfd == INVALID_HANDLE_VALUE) { rc = ErrCode(); goto leave; } if (env->me_psize >= env->me_os_psize) { #ifdef O_DIRECT /* Set O_DIRECT if the file system supports it */ if ((rc = fcntl(newfd, F_GETFL)) != -1) (void) fcntl(newfd, F_SETFL, rc | O_DIRECT); #endif #ifdef F_NOCACHE /* __APPLE__ */ rc = fcntl(newfd, F_NOCACHE, 1); if (rc) { rc = ErrCode(); goto leave; } #endif } rc = mdb_env_copyfd2(env, newfd, flags); leave: if (!(env->me_flags & MDB_NOSUBDIR)) free(lpath); if (newfd != INVALID_HANDLE_VALUE) if (close(newfd) < 0 && rc == MDB_SUCCESS) rc = ErrCode(); return rc; } int ESECT mdb_env_copy(MDB_env *env, const char *path) { return mdb_env_copy2(env, path, 0); } int ESECT mdb_env_set_flags(MDB_env *env, unsigned int flag, int onoff) { if (flag & ~CHANGEABLE) return EINVAL; if (onoff) env->me_flags |= flag; else env->me_flags &= ~flag; return MDB_SUCCESS; } int ESECT mdb_env_get_flags(MDB_env *env, unsigned int *arg) { if (!env || !arg) return EINVAL; *arg = env->me_flags & (CHANGEABLE|CHANGELESS); return MDB_SUCCESS; } int ESECT mdb_env_set_userctx(MDB_env *env, void *ctx) { if (!env) return EINVAL; env->me_userctx = ctx; return MDB_SUCCESS; } void * ESECT mdb_env_get_userctx(MDB_env *env) { return env ? env->me_userctx : NULL; } int ESECT mdb_env_set_assert(MDB_env *env, MDB_assert_func *func) { if (!env) return EINVAL; #ifndef NDEBUG env->me_assert_func = func; #endif return MDB_SUCCESS; } int ESECT mdb_env_get_path(MDB_env *env, const char **arg) { if (!env || !arg) return EINVAL; *arg = env->me_path; return MDB_SUCCESS; } int ESECT mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *arg) { if (!env || !arg) return EINVAL; *arg = env->me_fd; return MDB_SUCCESS; } /** Common code for #mdb_stat() and #mdb_env_stat(). * @param[in] env the environment to operate in. * @param[in] db the #MDB_db record containing the stats to return. * @param[out] arg the address of an #MDB_stat structure to receive the stats. * @return 0, this function always succeeds. */ static int ESECT mdb_stat0(MDB_env *env, MDB_db *db, MDB_stat *arg) { arg->ms_psize = env->me_psize; arg->ms_depth = db->md_depth; arg->ms_branch_pages = db->md_branch_pages; arg->ms_leaf_pages = db->md_leaf_pages; arg->ms_overflow_pages = db->md_overflow_pages; arg->ms_entries = db->md_entries; return MDB_SUCCESS; } int ESECT mdb_env_stat(MDB_env *env, MDB_stat *arg) { MDB_meta *meta; if (env == NULL || arg == NULL) return EINVAL; meta = mdb_env_pick_meta(env); return mdb_stat0(env, &meta->mm_dbs[MAIN_DBI], arg); } int ESECT mdb_env_info(MDB_env *env, MDB_envinfo *arg) { MDB_meta *meta; if (env == NULL || arg == NULL) return EINVAL; meta = mdb_env_pick_meta(env); arg->me_mapaddr = meta->mm_address; arg->me_last_pgno = meta->mm_last_pg; arg->me_last_txnid = meta->mm_txnid; arg->me_mapsize = env->me_mapsize; arg->me_maxreaders = env->me_maxreaders; arg->me_numreaders = env->me_txns ? env->me_txns->mti_numreaders : 0; return MDB_SUCCESS; } /** Set the default comparison functions for a database. * Called immediately after a database is opened to set the defaults. * The user can then override them with #mdb_set_compare() or * #mdb_set_dupsort(). * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] dbi A database handle returned by #mdb_dbi_open() */ static void mdb_default_cmp(MDB_txn *txn, MDB_dbi dbi) { uint16_t f = txn->mt_dbs[dbi].md_flags; txn->mt_dbxs[dbi].md_cmp = (f & MDB_REVERSEKEY) ? mdb_cmp_memnr : (f & MDB_INTEGERKEY) ? mdb_cmp_cint : mdb_cmp_memn; txn->mt_dbxs[dbi].md_dcmp = !(f & MDB_DUPSORT) ? 0 : ((f & MDB_INTEGERDUP) ? ((f & MDB_DUPFIXED) ? mdb_cmp_int : mdb_cmp_cint) : ((f & MDB_REVERSEDUP) ? mdb_cmp_memnr : mdb_cmp_memn)); } int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi) { MDB_val key, data; MDB_dbi i; MDB_cursor mc; MDB_db dummy; int rc, dbflag, exact; unsigned int unused = 0, seq; size_t len; if (flags & ~VALID_FLAGS) return EINVAL; if (txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; /* main DB? */ if (!name) { *dbi = MAIN_DBI; if (flags & PERSISTENT_FLAGS) { uint16_t f2 = flags & PERSISTENT_FLAGS; /* make sure flag changes get committed */ if ((txn->mt_dbs[MAIN_DBI].md_flags | f2) != txn->mt_dbs[MAIN_DBI].md_flags) { txn->mt_dbs[MAIN_DBI].md_flags |= f2; txn->mt_flags |= MDB_TXN_DIRTY; } } mdb_default_cmp(txn, MAIN_DBI); return MDB_SUCCESS; } if (txn->mt_dbxs[MAIN_DBI].md_cmp == NULL) { mdb_default_cmp(txn, MAIN_DBI); } /* Is the DB already open? */ len = strlen(name); for (i=CORE_DBS; imt_numdbs; i++) { if (!txn->mt_dbxs[i].md_name.mv_size) { /* Remember this free slot */ if (!unused) unused = i; continue; } if (len == txn->mt_dbxs[i].md_name.mv_size && !strncmp(name, txn->mt_dbxs[i].md_name.mv_data, len)) { *dbi = i; return MDB_SUCCESS; } } /* If no free slot and max hit, fail */ if (!unused && txn->mt_numdbs >= txn->mt_env->me_maxdbs) return MDB_DBS_FULL; /* Cannot mix named databases with some mainDB flags */ if (txn->mt_dbs[MAIN_DBI].md_flags & (MDB_DUPSORT|MDB_INTEGERKEY)) return (flags & MDB_CREATE) ? MDB_INCOMPATIBLE : MDB_NOTFOUND; /* Find the DB info */ dbflag = DB_NEW|DB_VALID|DB_USRVALID; exact = 0; key.mv_size = len; key.mv_data = (void *)name; mdb_cursor_init(&mc, txn, MAIN_DBI, NULL); rc = mdb_cursor_set(&mc, &key, &data, MDB_SET, &exact); if (rc == MDB_SUCCESS) { /* make sure this is actually a DB */ MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) return MDB_INCOMPATIBLE; } else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) { /* Create if requested */ data.mv_size = sizeof(MDB_db); data.mv_data = &dummy; memset(&dummy, 0, sizeof(dummy)); dummy.md_root = P_INVALID; dummy.md_flags = flags & PERSISTENT_FLAGS; rc = mdb_cursor_put(&mc, &key, &data, F_SUBDATA); dbflag |= DB_DIRTY; } /* OK, got info, add to table */ if (rc == MDB_SUCCESS) { unsigned int slot = unused ? unused : txn->mt_numdbs; txn->mt_dbxs[slot].md_name.mv_data = strdup(name); txn->mt_dbxs[slot].md_name.mv_size = len; txn->mt_dbxs[slot].md_rel = NULL; txn->mt_dbflags[slot] = dbflag; /* txn-> and env-> are the same in read txns, use * tmp variable to avoid undefined assignment */ seq = ++txn->mt_env->me_dbiseqs[slot]; txn->mt_dbiseqs[slot] = seq; memcpy(&txn->mt_dbs[slot], data.mv_data, sizeof(MDB_db)); *dbi = slot; mdb_default_cmp(txn, slot); if (!unused) { txn->mt_numdbs++; } } return rc; } int ESECT mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *arg) { if (!arg || !TXN_DBI_EXIST(txn, dbi, DB_VALID)) return EINVAL; if (txn->mt_flags & MDB_TXN_BLOCKED) return MDB_BAD_TXN; if (txn->mt_dbflags[dbi] & DB_STALE) { MDB_cursor mc; MDB_xcursor mx; /* Stale, must read the DB's root. cursor_init does it for us. */ mdb_cursor_init(&mc, txn, dbi, &mx); } return mdb_stat0(txn->mt_env, &txn->mt_dbs[dbi], arg); } void mdb_dbi_close(MDB_env *env, MDB_dbi dbi) { char *ptr; if (dbi < CORE_DBS || dbi >= env->me_maxdbs) return; ptr = env->me_dbxs[dbi].md_name.mv_data; /* If there was no name, this was already closed */ if (ptr) { env->me_dbxs[dbi].md_name.mv_data = NULL; env->me_dbxs[dbi].md_name.mv_size = 0; env->me_dbflags[dbi] = 0; env->me_dbiseqs[dbi]++; free(ptr); } } int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags) { /* We could return the flags for the FREE_DBI too but what's the point? */ if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; *flags = txn->mt_dbs[dbi].md_flags & PERSISTENT_FLAGS; return MDB_SUCCESS; } /** Add all the DB's pages to the free list. * @param[in] mc Cursor on the DB to free. * @param[in] subs non-Zero to check for sub-DBs in this DB. * @return 0 on success, non-zero on failure. */ static int mdb_drop0(MDB_cursor *mc, int subs) { int rc; rc = mdb_page_search(mc, NULL, MDB_PS_FIRST); if (rc == MDB_SUCCESS) { MDB_txn *txn = mc->mc_txn; MDB_node *ni; MDB_cursor mx; unsigned int i; /* DUPSORT sub-DBs have no ovpages/DBs. Omit scanning leaves. * This also avoids any P_LEAF2 pages, which have no nodes. */ if (mc->mc_flags & C_SUB) mdb_cursor_pop(mc); mdb_cursor_copy(mc, &mx); while (mc->mc_snum > 0) { MDB_page *mp = mc->mc_pg[mc->mc_top]; unsigned n = NUMKEYS(mp); if (IS_LEAF(mp)) { for (i=0; imn_flags & F_BIGDATA) { MDB_page *omp; pgno_t pg; memcpy(&pg, NODEDATA(ni), sizeof(pg)); rc = mdb_page_get(txn, pg, &omp, NULL); if (rc != 0) goto done; mdb_cassert(mc, IS_OVERFLOW(omp)); rc = mdb_midl_append_range(&txn->mt_free_pgs, pg, omp->mp_pages); if (rc) goto done; } else if (subs && (ni->mn_flags & F_SUBDATA)) { mdb_xcursor_init1(mc, ni); rc = mdb_drop0(&mc->mc_xcursor->mx_cursor, 0); if (rc) goto done; } } } else { if ((rc = mdb_midl_need(&txn->mt_free_pgs, n)) != 0) goto done; for (i=0; imt_free_pgs, pg); } } if (!mc->mc_top) break; mc->mc_ki[mc->mc_top] = i; rc = mdb_cursor_sibling(mc, 1); if (rc) { if (rc != MDB_NOTFOUND) goto done; /* no more siblings, go back to beginning * of previous level. */ mdb_cursor_pop(mc); mc->mc_ki[0] = 0; for (i=1; imc_snum; i++) { mc->mc_ki[i] = 0; mc->mc_pg[i] = mx.mc_pg[i]; } } } /* free it */ rc = mdb_midl_append(&txn->mt_free_pgs, mc->mc_db->md_root); done: if (rc) txn->mt_flags |= MDB_TXN_ERROR; } else if (rc == MDB_NOTFOUND) { rc = MDB_SUCCESS; } return rc; } int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del) { MDB_cursor *mc, *m2; int rc; if ((unsigned)del > 1 || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) return EACCES; if (TXN_DBI_CHANGED(txn, dbi)) return MDB_BAD_DBI; rc = mdb_cursor_open(txn, dbi, &mc); if (rc) return rc; rc = mdb_drop0(mc, mc->mc_db->md_flags & MDB_DUPSORT); /* Invalidate the dropped DB's cursors */ for (m2 = txn->mt_cursors[dbi]; m2; m2 = m2->mc_next) m2->mc_flags &= ~(C_INITIALIZED|C_EOF); if (rc) goto leave; /* Can't delete the main DB */ if (del && dbi >= CORE_DBS) { rc = mdb_del0(txn, MAIN_DBI, &mc->mc_dbx->md_name, NULL, F_SUBDATA); if (!rc) { txn->mt_dbflags[dbi] = DB_STALE; mdb_dbi_close(txn->mt_env, dbi); } else { txn->mt_flags |= MDB_TXN_ERROR; } } else { /* reset the DB record, mark it dirty */ txn->mt_dbflags[dbi] |= DB_DIRTY; txn->mt_dbs[dbi].md_depth = 0; txn->mt_dbs[dbi].md_branch_pages = 0; txn->mt_dbs[dbi].md_leaf_pages = 0; txn->mt_dbs[dbi].md_overflow_pages = 0; txn->mt_dbs[dbi].md_entries = 0; txn->mt_dbs[dbi].md_root = P_INVALID; txn->mt_flags |= MDB_TXN_DIRTY; } leave: mdb_cursor_close(mc); return rc; } int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp) { if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; txn->mt_dbxs[dbi].md_cmp = cmp; return MDB_SUCCESS; } int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp) { if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; txn->mt_dbxs[dbi].md_dcmp = cmp; return MDB_SUCCESS; } int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel) { if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; txn->mt_dbxs[dbi].md_rel = rel; return MDB_SUCCESS; } int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx) { if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; txn->mt_dbxs[dbi].md_relctx = ctx; return MDB_SUCCESS; } int ESECT mdb_env_get_maxkeysize(MDB_env *env) { return ENV_MAXKEY(env); } int ESECT mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx) { unsigned int i, rdrs; MDB_reader *mr; char buf[64]; int rc = 0, first = 1; if (!env || !func) return -1; if (!env->me_txns) { return func("(no reader locks)\n", ctx); } rdrs = env->me_txns->mti_numreaders; mr = env->me_txns->mti_readers; for (i=0; i> 1; cursor = base + pivot + 1; val = pid - ids[cursor]; if( val < 0 ) { n = pivot; } else if ( val > 0 ) { base = cursor; n -= pivot + 1; } else { /* found, so it's a duplicate */ return -1; } } if( val > 0 ) { ++cursor; } ids[0]++; for (n = ids[0]; n > cursor; n--) ids[n] = ids[n-1]; ids[n] = pid; return 0; } int ESECT mdb_reader_check(MDB_env *env, int *dead) { if (!env) return EINVAL; if (dead) *dead = 0; return env->me_txns ? mdb_reader_check0(env, 0, dead) : MDB_SUCCESS; } /** As #mdb_reader_check(). rlocked = . */ static int ESECT mdb_reader_check0(MDB_env *env, int rlocked, int *dead) { mdb_mutexref_t rmutex = rlocked ? NULL : env->me_rmutex; unsigned int i, j, rdrs; MDB_reader *mr; MDB_PID_T *pids, pid; int rc = MDB_SUCCESS, count = 0; rdrs = env->me_txns->mti_numreaders; pids = malloc((rdrs+1) * sizeof(MDB_PID_T)); if (!pids) return ENOMEM; pids[0] = 0; mr = env->me_txns->mti_readers; for (i=0; ime_pid) { if (mdb_pid_insert(pids, pid) == 0) { if (!mdb_reader_pid(env, Pidcheck, pid)) { /* Stale reader found */ j = i; if (rmutex) { if ((rc = LOCK_MUTEX0(rmutex)) != 0) { if ((rc = mdb_mutex_failed(env, rmutex, rc))) break; rdrs = 0; /* the above checked all readers */ } else { /* Recheck, a new process may have reused pid */ if (mdb_reader_pid(env, Pidcheck, pid)) j = rdrs; } } for (; jme_rmutex); if (!rlocked) { /* Keep mti_txnid updated, otherwise next writer can * overwrite data which latest meta page refers to. */ meta = mdb_env_pick_meta(env); env->me_txns->mti_txnid = meta->mm_txnid; /* env is hosed if the dead thread was ours */ if (env->me_txn) { env->me_flags |= MDB_FATAL_ERROR; env->me_txn = NULL; rc = MDB_PANIC; } } DPRINTF(("%cmutex owner died, %s", (rlocked ? 'r' : 'w'), (rc ? "this process' env is hosed" : "recovering"))); rc2 = mdb_reader_check0(env, rlocked, NULL); if (rc2 == 0) rc2 = mdb_mutex_consistent(mutex); if (rc || (rc = rc2)) { DPRINTF(("LOCK_MUTEX recovery failed, %s", mdb_strerror(rc))); UNLOCK_MUTEX(mutex); } } else { #ifdef _WIN32 rc = ErrCode(); #endif DPRINTF(("LOCK_MUTEX failed, %s", mdb_strerror(rc))); } return rc; } #endif /* MDB_ROBUST_SUPPORTED */ /** @} */ bareos-Release-14.2.6/src/lmdb/midl.c000066400000000000000000000146041263011562700172430ustar00rootroot00000000000000/** @file midl.c * @brief ldap bdb back-end ID List functions */ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * * Copyright 2000-2015 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ #include #include #include #include #include #include "midl.h" /** @defgroup internal LMDB Internals * @{ */ /** @defgroup idls ID List Management * @{ */ #define CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) ) unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id ) { /* * binary search of id in ids * if found, returns position of id * if not found, returns first position greater than id */ unsigned base = 0; unsigned cursor = 1; int val = 0; unsigned n = ids[0]; while( 0 < n ) { unsigned pivot = n >> 1; cursor = base + pivot + 1; val = CMP( ids[cursor], id ); if( val < 0 ) { n = pivot; } else if ( val > 0 ) { base = cursor; n -= pivot + 1; } else { return cursor; } } if( val > 0 ) { ++cursor; } return cursor; } #if 0 /* superseded by append/sort */ int mdb_midl_insert( MDB_IDL ids, MDB_ID id ) { unsigned x, i; x = mdb_midl_search( ids, id ); assert( x > 0 ); if( x < 1 ) { /* internal error */ return -2; } if ( x <= ids[0] && ids[x] == id ) { /* duplicate */ assert(0); return -1; } if ( ++ids[0] >= MDB_IDL_DB_MAX ) { /* no room */ --ids[0]; return -2; } else { /* insert id */ for (i=ids[0]; i>x; i--) ids[i] = ids[i-1]; ids[x] = id; } return 0; } #endif MDB_IDL mdb_midl_alloc(int num) { MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID)); if (ids) { *ids++ = num; *ids = 0; } return ids; } void mdb_midl_free(MDB_IDL ids) { if (ids) free(ids-1); } void mdb_midl_shrink( MDB_IDL *idp ) { MDB_IDL ids = *idp; if (*(--ids) > MDB_IDL_UM_MAX && (ids = realloc(ids, (MDB_IDL_UM_MAX+1) * sizeof(MDB_ID)))) { *ids++ = MDB_IDL_UM_MAX; *idp = ids; } } static int mdb_midl_grow( MDB_IDL *idp, int num ) { MDB_IDL idn = *idp-1; /* grow it */ idn = realloc(idn, (*idn + num + 2) * sizeof(MDB_ID)); if (!idn) return ENOMEM; *idn++ += num; *idp = idn; return 0; } int mdb_midl_need( MDB_IDL *idp, unsigned num ) { MDB_IDL ids = *idp; num += ids[0]; if (num > ids[-1]) { num = (num + num/4 + (256 + 2)) & -256; if (!(ids = realloc(ids-1, num * sizeof(MDB_ID)))) return ENOMEM; *ids++ = num - 2; *idp = ids; } return 0; } int mdb_midl_append( MDB_IDL *idp, MDB_ID id ) { MDB_IDL ids = *idp; /* Too big? */ if (ids[0] >= ids[-1]) { if (mdb_midl_grow(idp, MDB_IDL_UM_MAX)) return ENOMEM; ids = *idp; } ids[0]++; ids[ids[0]] = id; return 0; } int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app ) { MDB_IDL ids = *idp; /* Too big? */ if (ids[0] + app[0] >= ids[-1]) { if (mdb_midl_grow(idp, app[0])) return ENOMEM; ids = *idp; } memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID)); ids[0] += app[0]; return 0; } int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n ) { MDB_ID *ids = *idp, len = ids[0]; /* Too big? */ if (len + n > ids[-1]) { if (mdb_midl_grow(idp, n | MDB_IDL_UM_MAX)) return ENOMEM; ids = *idp; } ids[0] = len + n; ids += len; while (n) ids[n--] = id++; return 0; } void mdb_midl_xmerge( MDB_IDL idl, MDB_IDL merge ) { MDB_ID old_id, merge_id, i = merge[0], j = idl[0], k = i+j, total = k; idl[0] = (MDB_ID)-1; /* delimiter for idl scan below */ old_id = idl[j]; while (i) { merge_id = merge[i--]; for (; old_id < merge_id; old_id = idl[--j]) idl[k--] = old_id; idl[k--] = merge_id; } idl[0] = total; } /* Quicksort + Insertion sort for small arrays */ #define SMALL 8 #define MIDL_SWAP(a,b) { itmp=(a); (a)=(b); (b)=itmp; } void mdb_midl_sort( MDB_IDL ids ) { /* Max possible depth of int-indexed tree * 2 items/level */ int istack[sizeof(int)*CHAR_BIT * 2]; int i,j,k,l,ir,jstack; MDB_ID a, itmp; ir = (int)ids[0]; l = 1; jstack = 0; for(;;) { if (ir - l < SMALL) { /* Insertion sort */ for (j=l+1;j<=ir;j++) { a = ids[j]; for (i=j-1;i>=1;i--) { if (ids[i] >= a) break; ids[i+1] = ids[i]; } ids[i+1] = a; } if (jstack == 0) break; ir = istack[jstack--]; l = istack[jstack--]; } else { k = (l + ir) >> 1; /* Choose median of left, center, right */ MIDL_SWAP(ids[k], ids[l+1]); if (ids[l] < ids[ir]) { MIDL_SWAP(ids[l], ids[ir]); } if (ids[l+1] < ids[ir]) { MIDL_SWAP(ids[l+1], ids[ir]); } if (ids[l] < ids[l+1]) { MIDL_SWAP(ids[l], ids[l+1]); } i = l+1; j = ir; a = ids[l+1]; for(;;) { do i++; while(ids[i] > a); do j--; while(ids[j] < a); if (j < i) break; MIDL_SWAP(ids[i],ids[j]); } ids[l+1] = ids[j]; ids[j] = a; jstack += 2; if (ir-i+1 >= j-l) { istack[jstack] = ir; istack[jstack-1] = i; ir = j-1; } else { istack[jstack] = j-1; istack[jstack-1] = l; l = i; } } } } unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id ) { /* * binary search of id in ids * if found, returns position of id * if not found, returns first position greater than id */ unsigned base = 0; unsigned cursor = 1; int val = 0; unsigned n = (unsigned)ids[0].mid; while( 0 < n ) { unsigned pivot = n >> 1; cursor = base + pivot + 1; val = CMP( id, ids[cursor].mid ); if( val < 0 ) { n = pivot; } else if ( val > 0 ) { base = cursor; n -= pivot + 1; } else { return cursor; } } if( val > 0 ) { ++cursor; } return cursor; } int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id ) { unsigned x, i; x = mdb_mid2l_search( ids, id->mid ); if( x < 1 ) { /* internal error */ return -2; } if ( x <= ids[0].mid && ids[x].mid == id->mid ) { /* duplicate */ return -1; } if ( ids[0].mid >= MDB_IDL_UM_MAX ) { /* too big */ return -2; } else { /* insert id */ ids[0].mid++; for (i=(unsigned)ids[0].mid; i>x; i--) ids[i] = ids[i-1]; ids[x] = *id; } return 0; } int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id ) { /* Too big? */ if (ids[0].mid >= MDB_IDL_UM_MAX) { return -2; } ids[0].mid++; ids[ids[0].mid] = *id; return 0; } /** @} */ /** @} */ bareos-Release-14.2.6/src/lmdb/midl.h000066400000000000000000000130271263011562700172460ustar00rootroot00000000000000/** @file midl.h * @brief LMDB ID List header file. * * This file was originally part of back-bdb but has been * modified for use in libmdb. Most of the macros defined * in this file are unused, just left over from the original. * * This file is only used internally in libmdb and its definitions * are not exposed publicly. */ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * * Copyright 2000-2015 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ #ifndef _MDB_MIDL_H_ #define _MDB_MIDL_H_ #include #ifdef __cplusplus extern "C" { #endif /** @defgroup internal LMDB Internals * @{ */ /** @defgroup idls ID List Management * @{ */ /** A generic unsigned ID number. These were entryIDs in back-bdb. * Preferably it should have the same size as a pointer. */ typedef size_t MDB_ID; /** An IDL is an ID List, a sorted array of IDs. The first * element of the array is a counter for how many actual * IDs are in the list. In the original back-bdb code, IDLs are * sorted in ascending order. For libmdb IDLs are sorted in * descending order. */ typedef MDB_ID *MDB_IDL; /* IDL sizes - likely should be even bigger * limiting factors: sizeof(ID), thread stack size */ #define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */ #define MDB_IDL_DB_SIZE (1< Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @for src in $(LIBBAREOSNDMP_SRCS) ; do \ $(CC) -S -M -MT `basename $$src .c`$(DEFAULT_OBJECT_TYPE) $(CFLAGS) $(XINC) $(INCLUDES) $$src >> Makefile; \ done @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ======= Something went wrong with make depend. ======="; \ fi # ----------------------------------------------------------------------- # # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/ndmp/md5.h000066400000000000000000000042371263011562700170310ustar00rootroot00000000000000/* MD5.H - header file for MD5C.C */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ /* PROTOTYPES should be set to one if and only if the compiler supports function argument prototyping. The following makes PROTOTYPES default to 0 if it has not already been defined with C compiler flags. */ #ifndef PROTOTYPES #define PROTOTYPES 1 #endif #define MD5_LEN 16 /* POINTER defines a generic pointer type */ typedef unsigned char *POINTER; /* UINT2 defines a two byte word */ typedef unsigned short int UINT2; #ifdef i386 /* UINT4 defines a four byte word */ typedef unsigned long int UINT4; #else /* UINT4 defines a four byte word */ typedef unsigned int UINT4; #endif /* PROTO_LIST is defined depending on how PROTOTYPES is defined above. If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it returns an empty list. */ #if PROTOTYPES #define PROTO_LIST(list) list #else #define PROTO_LIST(list) () #endif /* MD5 context. */ typedef struct MD5Context { UINT4 state[4]; /* state (ABCD) */ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } MD5_CTX; void MD5Init PROTO_LIST ((MD5_CTX *)); void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int)); void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); bareos-Release-14.2.6/src/ndmp/md5c.c000066400000000000000000000242431263011562700171660ustar00rootroot00000000000000/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ #include "md5.h" /* Constants for MD5Transform routine. */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); static void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int)); static void Decode PROTO_LIST ((UINT4 *, unsigned char *, unsigned int)); static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (context) MD5_CTX *context; /* context */ { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ void MD5Update (context, input, inputLen) MD5_CTX *context; /* context */ unsigned char *input; /* input block */ unsigned int inputLen; /* length of input block */ { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ index = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) context->count[1]++; context->count[1] += ((UINT4)inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if (inputLen >= partLen) { MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform (context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) MD5Transform (context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ void MD5Final (digest, context) unsigned char digest[16]; /* message digest */ MD5_CTX *context; /* context */ { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ Encode (bits, context->count, 8); /* Pad out to 56 mod 64. */ index = (unsigned int)((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); MD5Update (context, PADDING, padLen); /* Append length (before padding) */ MD5Update (context, bits, 8); /* Store state in digest */ Encode (digest, context->state, 16); /* Zeroize sensitive information. */ MD5_memset ((POINTER)context, 0, sizeof (*context)); } /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform (state, block) UINT4 state[4]; unsigned char block[64]; { UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode (x, block, 64); /* Round 1 */ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ MD5_memset ((POINTER)x, 0, sizeof (x)); } /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ static void Encode (output, input, len) unsigned char *output; UINT4 *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); } } /* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ static void Decode (output, input, len) UINT4 *output; unsigned char *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); } /* Note: Replace "for loop" with standard memcpy if possible. */ static void MD5_memcpy (output, input, len) POINTER output; POINTER input; unsigned int len; { unsigned int i; for (i = 0; i < len; i++) output[i] = input[i]; } /* Note: Replace "for loop" with standard memset if possible. */ static void MD5_memset (output, value, len) POINTER output; int value; unsigned int len; { unsigned int i; for (i = 0; i < len; i++) ((char *)output)[i] = (char)value; } bareos-Release-14.2.6/src/ndmp/ndma_comm_dispatch.c000066400000000000000000002370701263011562700221530ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * Think of ndma_dispatch_request() as a parser (like yacc(1) input). * This parses (audits) the sequence of requests. If the requests * conform to the "grammar", semantic actions are taken. * * This is, admittedly, a huge source file. The idea * is to have all audits and associated errors here. This * makes review, study, comparing to the specification, and * discussion easier because we don't get balled up in * the implementation of semantics. Further, with the hope * of wide-scale deployment, revisions of this source file * can readily be integrated into derivative works without * disturbing other portions. */ #include "ndmagents.h" extern struct ndm_dispatch_version_table ndma_dispatch_version_table[]; static int connect_open_common (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, int protocol_version); int ndma_dispatch_request (struct ndm_session *sess, struct ndmp_xa_buf *arg_xa, struct ndmconn *ref_conn) { struct ndm_dispatch_request_table *drt; struct ndmp_xa_buf * xa = arg_xa; struct ndmp_xa_buf xl_xa; struct reqrep_xlate * rrxl = 0; unsigned protocol_version = ref_conn->protocol_version; unsigned msg = xa->request.header.message; int rc; NDMOS_MACRO_ZEROFILL (&xa->reply); xa->reply.protocol_version = xa->request.protocol_version; xa->reply.flags |= NDMNMB_FLAG_NO_FREE; xa->reply.header.sequence = 0; /* filled-in by xmit logic */ xa->reply.header.time_stamp = 0; /* filled-in by xmit logic */ xa->reply.header.message_type = NDMP0_MESSAGE_REPLY; xa->reply.header.message = xa->request.header.message; xa->reply.header.reply_sequence = xa->request.header.sequence; xa->reply.header.error = NDMP0_NO_ERR; /* assume no error */ ndmnmb_set_reply_error_raw (&xa->reply, NDMP0_NO_ERR); switch ((int)msg & 0xFFFFFF00) { case 0x0500: /* notify */ case 0x0600: /* log */ case 0x0700: /* file history */ xa->reply.flags |= NDMNMB_FLAG_NO_SEND; break; } /* sanity check */ if (xa->request.protocol_version != protocol_version) { xa->reply.header.error = NDMP0_UNDEFINED_ERR; return 0; } /* * If the session is not open and the message * is anything other than CONNECT_OPEN, the client * has implicitly agreed to the protocol_version * offered by NOTIFY_CONNECTED (ref ndmconn_accept()). * Effectively perform CONNECT_OPEN for that * protocol_version. */ if (!sess->conn_open && msg != NDMP0_CONNECT_OPEN) { connect_open_common (sess, xa, ref_conn, ref_conn->protocol_version); } /* * Give the OS/implementation specific module a chance * to intercept the request. Some requests are only implemented * by the module. Some requests are reimplemented by the module * when the standard implementation is inadequate to the app. */ rc = ndmos_dispatch_request (sess, xa, ref_conn); if (rc >= 0) { return rc; /* request intercepted */ } /* * See if there is a standard, protocol_version specific * dispatch function for the request. */ drt = ndma_drt_lookup (ndma_dispatch_version_table, protocol_version, msg); if (drt) { goto have_drt; } /* * Typical case.... * Find the protocol_version specific translation * functions for this request/reply. The request * is translated from its native version, NDMPvX, * into NDMPv9. The NDMPv9 form is dispatched. * The resulting reply is translated back to * the native version */ rrxl = reqrep_xlate_lookup_version (reqrep_xlate_version_table, protocol_version); /* find the protocol_version translation table */ if (!rrxl) { /* can't do it */ xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; return 0; } /* find the interface's translation table entry */ rrxl = ndmp_reqrep_by_vx (rrxl, msg); if (!rrxl) { /* can't do it */ xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; return 0; } /* find the NDMPv9 dispatch table entry */ drt = ndma_drt_lookup (ndma_dispatch_version_table, NDMP9VER, rrxl->v9_message); if (!drt) { /* can't do it */ xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; return 0; } have_drt: /* * Permission checks, always. */ if (!sess->conn_open && !(drt->flags & NDM_DRT_FLAG_OK_NOT_CONNECTED)) { xa->reply.header.error = NDMP0_PERMISSION_ERR; return 0; } if (!sess->conn_authorized && !(drt->flags & NDM_DRT_FLAG_OK_NOT_AUTHORIZED)) { xa->reply.header.error = NDMP0_NOT_AUTHORIZED_ERR; return 0; } /* * If there is a translation afoot, translate the request now. */ if (rrxl) { NDMOS_MACRO_ZEROFILL (&xl_xa); xa = &xl_xa; xa->request.header = arg_xa->request.header; xa->request.header.message = rrxl->v9_message; xa->request.protocol_version = NDMP9VER; xa->reply.header = arg_xa->reply.header; xa->reply.flags = arg_xa->reply.flags; xa->reply.protocol_version = NDMP9VER; rc = (*rrxl->request_xto9)( (void*)&arg_xa->request.body, (void*)&xa->request.body); if (rc < 0) { /* unrecoverable translation error */ xa = arg_xa; xa->reply.header.error = NDMP0_UNDEFINED_ERR; return 0; } /* NB: rc>0 means that there were tolerated xlate errors */ /* allow reply to be freed */ xa->reply.flags &= ~NDMNMB_FLAG_NO_FREE; } rc = (*drt->dispatch_request)(sess, xa, ref_conn); /* free up any memory allocated as part of the xto9 request */ if (rrxl) (*rrxl->free_request_xto9)((void*)&xa->request.body); if (rc < 0) { /* unrecoverable dispatch error */ if (rrxl) { ndmnmb_free (&xa->reply); /* clean up partials */ xa = arg_xa; } xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; return 0; } if (rrxl) { rc = (*rrxl->reply_9tox)( (void*)&xa->reply.body, (void*)&arg_xa->reply.body); /* free up any memory allocated as part of the 9tox reply */ if (rrxl) (*rrxl->free_reply_9tox)((void*)&arg_xa->reply.body); ndmnmb_free (&xa->reply); /* clean up */ xa = arg_xa; if (rc < 0) { /* unrecoverable translation error */ xa->reply.header.error = NDMP0_UNDEFINED_ERR; return 0; } /* NB: rc>0 means that there were tolerated xlate errors */ } return 0; } int ndma_dispatch_raise_error (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_error error, char *errstr) { int protocol_version = ref_conn->protocol_version; ndmp0_message msg = xa->request.header.message; if (errstr) { ndmalogf (sess, 0, 2, "op=%s err=%s why=%s", ndmp_message_to_str (protocol_version, msg), ndmp9_error_to_str (error), errstr); } sess->error_raised = 1; ndmnmb_set_reply_error (&xa->reply, error); return 1; } /* * Access paths to ndma_dispatch_request() **************************************************************** */ /* incomming requests on a ndmconn connection */ int ndma_dispatch_conn (struct ndm_session *sess, struct ndmconn *conn) { struct ndmp_xa_buf xa; int rc; NDMOS_MACRO_ZEROFILL (&xa); rc = ndmconn_recv_nmb (conn, &xa.request); if (rc) { ndmnmb_free (&xa.request); return rc; } ndma_dispatch_request (sess, &xa, conn); ndmnmb_free (&xa.request); if (! (xa.reply.flags & NDMNMB_FLAG_NO_SEND)) { rc = ndmconn_send_nmb (conn, &xa.reply); if (rc) return rc; } ndmnmb_free (&xa.reply); return 0; } void ndma_dispatch_ctrl_unexpected (struct ndmconn *conn, struct ndmp_msg_buf *nmb) { int protocol_version = conn->protocol_version; struct ndm_session * sess = conn->context; struct ndmp_xa_buf xa; if (nmb->header.message_type != NDMP0_MESSAGE_REQUEST) { ndmalogf (sess, conn->chan.name, 1, "Unexpected message -- probably reply " "w/ wrong reply_sequence"); #if 0 /* causes crash, needs investigation */ ndmnmb_snoop (&sess->param.log, "WTF", 5, nmb, conn->chan.name); #endif ndmnmb_free (nmb); return; } NDMOS_MACRO_ZEROFILL (&xa); xa.request = *nmb; ndmalogf (sess, conn->chan.name, 4, "Async request %s", ndmp_message_to_str (protocol_version, xa.request.header.message)); ndma_dispatch_request (sess, &xa, conn); if (! (xa.reply.flags & NDMNMB_FLAG_NO_SEND)) { ndmconn_send_nmb (conn, &xa.reply); } ndmnmb_free (&xa.reply); } int ndma_call_no_tattle (struct ndmconn *conn, struct ndmp_xa_buf *arg_xa) { struct ndmp_xa_buf * xa = arg_xa; struct ndmp_xa_buf xl_xa; struct reqrep_xlate * rrxl = 0; unsigned protocol_version = conn->protocol_version; unsigned msg = xa->request.header.message; int rc; if (xa->request.protocol_version == NDMP9VER) { /* * Typical case.... * Find the protocol_version specific translation * functions for this request/reply. The request * is translated to its native version, NDMPvX, * from NDMPv9. The NDMPvX form is transmitted. * The resulting reply is translated back to NDMPv9. * NDMPvX is determined by the connection. */ rrxl = reqrep_xlate_lookup_version (reqrep_xlate_version_table, protocol_version); /* find the protocol_version translation table */ if (!rrxl) { /* can't do it */ xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; rc = NDMCONN_CALL_STATUS_HDR_ERROR; conn->last_header_error = xa->reply.header.error; return rc; } /* find the interface's translation table entry */ rrxl = ndmp_reqrep_by_v9 (rrxl, msg); if (!rrxl) { /* can't do it */ xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; rc = NDMCONN_CALL_STATUS_HDR_ERROR; conn->last_header_error = xa->reply.header.error; return rc; } NDMOS_MACRO_ZEROFILL (&xl_xa); xa = &xl_xa; xa->request.header = arg_xa->request.header; xa->request.header.message = rrxl->vx_message; xa->request.protocol_version = protocol_version; rc = (*rrxl->request_9tox)( (void*)&arg_xa->request.body, (void*)&xa->request.body); if (rc < 0) { /* unrecoverable translation error */ ndmnmb_free (&xa->request); /* clean up partials */ xa = arg_xa; xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; rc = NDMCONN_CALL_STATUS_HDR_ERROR; conn->last_header_error = xa->reply.header.error; return rc; } /* NB: rc>0 means that there were tolerated xlate errors */ } if (conn->conn_type == NDMCONN_TYPE_RESIDENT) { struct ndm_session *sess = conn->context; conn->last_message = xa->request.header.message; conn->last_call_status = NDMCONN_CALL_STATUS_BOTCH; conn->last_header_error = -1; /* invalid */ conn->last_reply_error = -1; /* invalid */ xa->request.header.sequence = conn->next_sequence++; ndmconn_snoop_nmb (conn, &xa->request, "Send"); rc = ndma_dispatch_request (sess, xa, conn); xa->reply.header.sequence = conn->next_sequence++; if (! (xa->reply.flags & NDMNMB_FLAG_NO_SEND)) ndmconn_snoop_nmb (conn, &xa->reply, "Recv"); if (rc) { /* keep it */ } else if (xa->reply.header.error != NDMP0_NO_ERR) { rc = NDMCONN_CALL_STATUS_HDR_ERROR; conn->last_header_error = xa->reply.header.error; } else { conn->last_header_error = NDMP9_NO_ERR; conn->last_reply_error = ndmnmb_get_reply_error (&xa->reply); if (conn->last_reply_error == NDMP9_NO_ERR) { rc = NDMCONN_CALL_STATUS_OK; } else { rc = NDMCONN_CALL_STATUS_REPLY_ERROR; } } } else { rc = ndmconn_call (conn, xa); if (rc == 0) { if ((conn->time_limit > 0) && (conn->received_time > conn->sent_time)) { int delta; delta = conn->received_time - conn->sent_time; if (delta > conn->time_limit) rc = NDMCONN_CALL_STATUS_REPLY_LATE; } } } if (rrxl) { int xrc; xrc = (*rrxl->reply_xto9)( (void*)&xa->reply.body, (void*)&arg_xa->reply.body); ndmnmb_free (&xa->request); /* clean up */ ndmnmb_free (&xa->reply); /* clean up */ arg_xa->reply.header = xa->reply.header; arg_xa->reply.flags = xa->reply.flags; arg_xa->reply.protocol_version = NDMP9VER; xa = arg_xa; if (xrc < 0) { /* unrecoverable translation error */ xa->reply.header.error = NDMP0_UNDEFINED_ERR; rc = NDMCONN_CALL_STATUS_HDR_ERROR; conn->last_header_error = xa->reply.header.error; return rc; } /* NB: rc>0 means that there were tolerated xlate errors */ } return rc; } int ndma_call (struct ndmconn *conn, struct ndmp_xa_buf *xa) { int rc; rc = ndma_call_no_tattle (conn, xa); if (rc) { ndma_tattle (conn, xa, rc); } return rc; } int ndma_send_to_control (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *from_conn) { struct ndmconn * conn = sess->plumb.control; int rc; if (conn->conn_type == NDMCONN_TYPE_RESIDENT && from_conn) { /* * Control and sending agent are * resident. Substitute the sending * agents "connection" so that logs * look right and right protocol_version * is used. */ conn = from_conn; } rc = ndma_call_no_tattle (conn, xa); if (rc) { ndma_tattle (conn, xa, rc); } return rc; } int ndma_tattle (struct ndmconn *conn, struct ndmp_xa_buf *xa, int rc) { struct ndm_session *sess = conn->context; int protocol_version = conn->protocol_version; unsigned msg = xa->request.header.message; char * tag = conn->chan.name; char * msgname = ndmp_message_to_str (protocol_version, msg); unsigned err; switch (rc) { case 0: ndmalogf (sess, tag, 2, " ?OK %s", msgname); break; case 1: /* no error in header, error in reply */ err = ndmnmb_get_reply_error_raw (&xa->reply); ndmalogf (sess, tag, 2, " ERR %s %s", msgname, ndmp_error_to_str (protocol_version, err)); break; case 2: /* no error in header or in reply, response late */ ndmalogf (sess, tag, 2, " REPLY LATE %s, took %d seconds", msgname, (conn->received_time - conn->sent_time)); break; case -2: /* error in header, no reply body */ err = xa->reply.header.error; ndmalogf (sess, tag, 2, " ERR-AGENT %s %s", msgname, ndmp_error_to_str (protocol_version, err)); break; default: ndmalogf (sess, tag, 2, " ERR-CONN %s %s", msgname, ndmconn_get_err_msg (conn)); break; } return 0; } /* * NDMPx_CONNECT Interfaces **************************************************************** */ /* * NDMP[0234]_CONNECT_OPEN */ int ndmp_sxa_connect_open (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { NDMS_WITH(ndmp0_connect_open) if (sess->conn_open) { if (request->protocol_version != ref_conn->protocol_version) { NDMADR_RAISE_ILLEGAL_ARGS("too late to change version"); } } else { switch (request->protocol_version) { #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: #endif /* !NDMOS_OPTION_NO_NDMP4 */ connect_open_common (sess, xa, ref_conn, request->protocol_version); break; default: NDMADR_RAISE_ILLEGAL_ARGS("unsupport protocol version"); break; } } NDMS_ENDWITH return 0; } static int connect_open_common (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, int protocol_version) { #ifndef NDMOS_OPTION_NO_DATA_AGENT if (sess->data_acb) sess->data_acb->protocol_version = protocol_version; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (sess->tape_acb) sess->tape_acb->protocol_version = protocol_version; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT if (sess->robot_acb) sess->robot_acb->protocol_version = protocol_version; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ ref_conn->protocol_version = protocol_version; sess->conn_open = 1; return 0; } /* * NDMP[234]_CONNECT_CLIENT_AUTH */ int ndmp_sxa_connect_client_auth (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_auth_type auth_type; char * name = 0; char * proof = 0; NDMS_WITH(ndmp9_connect_client_auth) auth_type = request->auth_data.auth_type; switch (auth_type) { default: NDMADR_RAISE_ILLEGAL_ARGS ("auth_type"); case NDMP9_AUTH_TEXT: { ndmp9_auth_text * p; p = &request->auth_data.ndmp9_auth_data_u.auth_text; name = p->auth_id; proof = p->auth_password; if (!ndmos_ok_name_password (sess, name, proof)) { NDMADR_RAISE(NDMP9_NOT_AUTHORIZED_ERR, "password not OK"); } } break; case NDMP9_AUTH_MD5: { ndmp9_auth_md5 * p; p = &request->auth_data.ndmp9_auth_data_u.auth_md5; name = p->auth_id; proof = p->auth_digest; if (!sess->md5_challenge_valid) { NDMADR_RAISE(NDMP9_NOT_AUTHORIZED_ERR, "no challenge"); } if (!ndmos_ok_name_md5_digest (sess, name, proof)) { NDMADR_RAISE(NDMP9_NOT_AUTHORIZED_ERR, "digest not OK"); } } break; } sess->conn_authorized = 1; return 0; NDMS_ENDWITH } /* * NDMP[023]_CONNECT_CLOSE */ int ndmp_sxa_connect_close (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { xa->reply.flags |= NDMNMB_FLAG_NO_SEND; /* ??? */ /* TODO: shutdown everything */ sess->connect_status = 0; ndmchan_set_eof (&ref_conn->chan); return 0; } /* * NDMP[23]_CONNECT_SERVER_AUTH */ int ndmp_sxa_connect_server_auth (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { return NDMADR_UNIMPLEMENTED_MESSAGE; } /* * NDMPx_CONFIG Interfaces **************************************************************** */ /* * NDMP[234]_CONFIG_GET_HOST_INFO * NDMP[34]_CONFIG_GET_SERVER_INFO * NDMP2_CONFIG_GET_MOVER_TYPE * NDMP[34]_CONFIG_GET_CONNECTION_TYPE * NDMP[34]_CONFIG_GET_BUTYPE_INFO * NDMP[34]_CONFIG_GET_FS_INFO * NDMP[34]_CONFIG_GET_TAPE_INFO * NDMP[34]_CONFIG_GET_SCSI_INFO */ int ndmp_sxa_config_get_info (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { NDMS_WITH_VOID_REQUEST(ndmp9_config_get_info) ndmos_sync_config_info (sess); if (!sess->config_info) { return NDMP9_NO_MEM_ERR; } if (sess->config_info->conntypes == 0) { /* OS left it for us to do */ #ifndef NDMOS_OPTION_NO_DATA_AGENT #ifndef NDMOS_OPTION_NO_TAPE_AGENT sess->config_info->conntypes |= NDMP9_CONFIG_CONNTYPE_LOCAL; sess->config_info->conntypes |= NDMP9_CONFIG_CONNTYPE_TCP; #else /* !NDMOS_OPTION_NO_TAPE_AGENT */ sess->config_info->conntypes |= NDMP9_CONFIG_CONNTYPE_TCP; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #else /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT sess->config_info->conntypes |= NDMP9_CONFIG_CONNTYPE_TCP; #else /* !NDMOS_OPTION_NO_TAPE_AGENT */ #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ } if (sess->config_info->authtypes == 0) { /* OS left it for us to do */ sess->config_info->authtypes |= NDMP9_CONFIG_AUTHTYPE_TEXT; sess->config_info->authtypes |= NDMP9_CONFIG_AUTHTYPE_MD5; } memcpy (&reply->config_info, sess->config_info, sizeof(ndmp9_config_info)); return 0; NDMS_ENDWITH } #ifndef NDMOS_OPTION_NO_NDMP2 /* * NDMP2_CONFIG_GET_BUTYPE_ATTR */ int ndmp2_sxa_config_get_butype_attr (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_config_info * ci = sess->config_info; ndmp9_butype_info * bu = 0; unsigned int i; assert (xa->request.protocol_version == NDMP2VER); NDMS_WITH(ndmp2_config_get_butype_attr) ndmos_sync_config_info (sess); if (!sess->config_info) { return NDMP9_NO_MEM_ERR; } for (i = 0; i < ci->butype_info.butype_info_len; i++) { bu = &ci->butype_info.butype_info_val[i]; if (strcmp (request->name, bu->butype_name) == 0) { break; } } if (i >= ci->butype_info.butype_info_len) { NDMADR_RAISE_ILLEGAL_ARGS("butype"); } reply->attrs = bu->v2attr.value; return 0; NDMS_ENDWITH } #endif /* !NDMOS_OPTION_NO_NDMP2 */ /* * NDMP[234]_CONFIG_GET_AUTH_ATTR * * Credits to Rajiv of NetApp for helping with MD5 stuff. */ int ndmp_sxa_config_get_auth_attr (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { NDMS_WITH(ndmp9_config_get_auth_attr) switch (request->auth_type) { default: NDMADR_RAISE_ILLEGAL_ARGS ("auth_type"); case NDMP9_AUTH_NONE: break; case NDMP9_AUTH_TEXT: break; case NDMP9_AUTH_MD5: ndmos_get_md5_challenge (sess); NDMOS_API_BCOPY (sess->md5_challenge, reply->server_attr.ndmp9_auth_attr_u.challenge, 64); break; } reply->server_attr.auth_type = request->auth_type; return 0; NDMS_ENDWITH } #ifndef NDMOS_OPTION_NO_ROBOT_AGENT /* Surrounds SCSI intfs */ /* * NDMPx_SCSI Interfaces **************************************************************** * * If these are implemented, they should already have been * intercepted by ndmos_dispatch_request(). There is absolutely * no way to implement this generically, nor is there merit to * a generic "layer". * * Still, just in case, they are implemented here. */ static ndmp9_error scsi_open_ok (struct ndm_session *sess); static ndmp9_error scsi_op_ok (struct ndm_session *sess); /* * NDMP[234]_SCSI_OPEN */ int ndmp_sxa_scsi_open (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; if (!sess->robot_acb) { NDMADR_RAISE(NDMP9_DEVICE_OPENED_ERR, "No Robot Agent"); } NDMS_WITH(ndmp9_scsi_open) error = scsi_open_ok (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!scsi_open_ok"); } error = ndmos_scsi_open (sess, request->device); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "scsi_open"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_SCSI_CLOSE */ int ndmp_sxa_scsi_close (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; NDMS_WITH_VOID_REQUEST(ndmp9_scsi_close) error = scsi_op_ok (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!scsi_op_ok"); } error = ndmos_scsi_close (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "scsi_close"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_SCSI_GET_STATE */ int ndmp_sxa_scsi_get_state (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_robot_agent *ra = sess->robot_acb; NDMS_WITH_VOID_REQUEST(ndmp9_scsi_get_state) ndmos_scsi_sync_state (sess); *reply = ra->scsi_state; return 0; NDMS_ENDWITH } /* * NDMP[23]_SCSI_SET_TARGET */ int ndmp_sxa_scsi_set_target (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; NDMS_WITH(ndmp9_scsi_set_target) error = scsi_op_ok (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!scsi_op_ok"); } error = ndmos_scsi_set_target (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "scsi_set_target"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_SCSI_RESET_DEVICE */ int ndmp_sxa_scsi_reset_device (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; NDMS_WITH_VOID_REQUEST(ndmp9_scsi_reset_device) error = scsi_op_ok (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!scsi_op_ok"); } error = ndmos_scsi_reset_device (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "scsi_reset_device"); } return 0; NDMS_ENDWITH } /* * NDMP[23]_SCSI_RESET_BUS */ int ndmp_sxa_scsi_reset_bus (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; NDMS_WITH_VOID_REQUEST(ndmp9_scsi_reset_bus) error = scsi_op_ok (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!scsi_op_ok"); } error = ndmos_scsi_reset_bus (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "scsi_reset_bus"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_SCSI_EXECUTE_CDB */ int ndmp_sxa_scsi_execute_cdb (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; NDMS_WITH(ndmp9_scsi_execute_cdb) error = scsi_op_ok (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!scsi_op_ok"); } error = ndmos_scsi_execute_cdb (sess, request, reply); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "scsi_execute_cdb"); } return 0; NDMS_ENDWITH } /* * NDMPx_SCSI helper routines */ static ndmp9_error scsi_open_ok (struct ndm_session *sess) { struct ndm_robot_agent * ra = sess->robot_acb; ndmos_scsi_sync_state(sess); if (ra->scsi_state.error != NDMP9_DEV_NOT_OPEN_ERR) return NDMP9_DEVICE_OPENED_ERR; #ifndef NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN #ifndef NDMOS_OPTION_NO_TAPE_AGENT ndmos_tape_sync_state(sess); if (sess->tape_acb->tape_state.error != NDMP9_DEV_NOT_OPEN_ERR) return NDMP9_DEVICE_OPENED_ERR; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #endif /* NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN */ return NDMP9_NO_ERR; } static ndmp9_error scsi_op_ok (struct ndm_session *sess) { struct ndm_robot_agent * ra = sess->robot_acb; ndmos_scsi_sync_state(sess); if (ra->scsi_state.error != NDMP9_NO_ERR) return NDMP9_DEV_NOT_OPEN_ERR; return NDMP9_NO_ERR; } #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ /* Surrounds SCSI intfs */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* Surrounds TAPE intfs */ /* * NDMPx_TAPE Interfaces **************************************************************** */ static ndmp9_error tape_open_ok (struct ndm_session *sess, int will_write); static ndmp9_error tape_op_ok (struct ndm_session *sess, int will_write); /* * NDMP[234]_TAPE_OPEN */ int ndmp_sxa_tape_open (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; int will_write; if (!sess->tape_acb) { NDMADR_RAISE(NDMP9_DEVICE_OPENED_ERR, "No Tape Agent"); } NDMS_WITH(ndmp9_tape_open) switch (request->mode) { default: NDMADR_RAISE_ILLEGAL_ARGS("tape_mode"); case NDMP9_TAPE_READ_MODE: will_write = 0; break; case NDMP9_TAPE_RDWR_MODE: case NDMP9_TAPE_RAW_MODE: will_write = 1; break; } error = tape_open_ok (sess, will_write); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!tape_open_ok"); } error = ndmos_tape_open (sess, request->device, will_write); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "tape_open"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_TAPE_CLOSE */ int ndmp_sxa_tape_close (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; NDMS_WITH_VOID_REQUEST(ndmp9_tape_close) error = tape_op_ok (sess, 0); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!tape_op_ok"); } error = ndmos_tape_close (sess); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "tape_close"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_TAPE_GET_STATE */ int ndmp_sxa_tape_get_state (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; NDMS_WITH_VOID_REQUEST(ndmp9_tape_get_state) ndmos_tape_sync_state(sess); *reply = ta->tape_state; return 0; NDMS_ENDWITH } /* * NDMP[234]_TAPE_MTIO */ int ndmp_sxa_tape_mtio (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; ndmp9_tape_mtio_op tape_op; int will_write = 0; uint32_t resid = 0; NDMS_WITH(ndmp9_tape_mtio) switch (request->tape_op) { default: NDMADR_RAISE_ILLEGAL_ARGS("tape_op"); case NDMP9_MTIO_EOF: will_write = 1; tape_op = NDMP9_MTIO_EOF; break; case NDMP9_MTIO_FSF: case NDMP9_MTIO_BSF: case NDMP9_MTIO_FSR: case NDMP9_MTIO_BSR: case NDMP9_MTIO_REW: case NDMP9_MTIO_OFF: tape_op = request->tape_op; break; } error = tape_op_ok (sess, will_write); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!tape_op_ok"); } error = ndmos_tape_mtio (sess, tape_op, request->count, &resid); reply->error = error; reply->resid_count = resid; return 0; NDMS_ENDWITH } /* * NDMP[234]_TAPE_WRITE */ int ndmp_sxa_tape_write (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; uint32_t done_count = 0; NDMS_WITH(ndmp9_tape_write) if (request->data_out.data_out_len == 0) { /* * NDMPv4 clarification -- a tape read or write with * a count==0 is a no-op. This is undoubtedly influenced * by the SCSI Sequential Access specification which * says much the same thing. * * NDMPv[23] MAY return NDMP_NO_ERR or * NDMP_ILLEGAL_ARGS_ERR. */ reply->error = NDMP9_NO_ERR; reply->count = 0; return 0; } if (!NDMOS_MACRO_OK_TAPE_REC_LEN(request->data_out.data_out_len)) { NDMADR_RAISE_ILLEGAL_ARGS("!ok_tape_rec_len"); } error = tape_op_ok (sess, 1); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!tape_op_ok"); } error = ndmos_tape_write (sess, request->data_out.data_out_val, request->data_out.data_out_len, &done_count); reply->error = error; reply->count = done_count; return 0; NDMS_ENDWITH } /* * NDMP[234]_TAPE_READ */ int ndmp_sxa_tape_read (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; ndmp9_error error; uint32_t done_count = 0; /* * We are about to read data into a tape buffer so make sure * we have it available. We delay allocating buffers to the * moment we first need them. */ if (!ta->tape_buffer) { ta->tape_buffer = NDMOS_API_MALLOC (NDMOS_CONST_TAPE_REC_MAX); if (!ta->tape_buffer) { NDMADR_RAISE(NDMP9_NO_MEM_ERR, "Allocating tape buffer"); } } NDMS_WITH(ndmp9_tape_read) if (request->count == 0) { /* * NDMPv4 clarification -- a tape read or write with * a count==0 is a no-op. This is undoubtedly influenced * by the SCSI Sequential Access specification which * says much the same thing. * * NDMPv[23] MAY return NDMP_NO_ERR or * NDMP_ILLEGAL_ARGS_ERR. */ reply->error = NDMP9_NO_ERR; reply->data_in.data_in_val = ta->tape_buffer; reply->data_in.data_in_len = 0; return 0; } if (!NDMOS_MACRO_OK_TAPE_REC_LEN(request->count)) { NDMADR_RAISE_ILLEGAL_ARGS("!ok_tape_rec_len"); } error = tape_op_ok (sess, 0); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!tape_op_ok"); } error = ndmos_tape_read (sess, ta->tape_buffer, request->count, &done_count); reply->error = error; reply->data_in.data_in_val = ta->tape_buffer; reply->data_in.data_in_len = done_count; return 0; NDMS_ENDWITH } /* * NDMP[234]_TAPE_EXECUTE_CDB * * If this is implemented, it should already have been * intercepted by ndmos_dispatch_request(). * There is absolutely no way to implement this generically, * nor is there merit to a generic "layer". * Still, just in case, it is implemented here. */ int ndmp_sxa_tape_execute_cdb (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { NDMS_WITH(ndmp9_tape_execute_cdb) return NDMADR_UNIMPLEMENTED_MESSAGE; NDMS_ENDWITH } /* * NDMPx_TAPE helper routines */ static ndmp9_error tape_open_ok (struct ndm_session *sess, int will_write) { struct ndm_tape_agent * ta = sess->tape_acb; ndmos_tape_sync_state(sess); if (ta->tape_state.state != NDMP9_TAPE_STATE_IDLE) return NDMP9_DEVICE_OPENED_ERR; #ifndef NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN #ifndef NDMOS_OPTION_NO_ROBOT_AGENT ndmos_scsi_sync_state(sess); if (sess->robot_acb && sess->robot_acb->scsi_state.error != NDMP9_DEV_NOT_OPEN_ERR) return NDMP9_DEVICE_OPENED_ERR; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ #endif /* NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN */ return NDMP9_NO_ERR; } /* * Tape operation is only OK if it is open and the MOVER * hasn't got a hold of it. We can't allow tape operations * to interfere with the MOVER. */ static ndmp9_error tape_op_ok (struct ndm_session *sess, int will_write) { struct ndm_tape_agent * ta = sess->tape_acb; ndmos_tape_sync_state(sess); switch (ta->tape_state.state) { case NDMP9_TAPE_STATE_IDLE: return NDMP9_DEV_NOT_OPEN_ERR; case NDMP9_TAPE_STATE_OPEN: if (will_write && !NDMTA_TAPE_IS_WRITABLE(ta)) return NDMP9_PERMISSION_ERR; break; case NDMP9_TAPE_STATE_MOVER: return NDMP9_ILLEGAL_STATE_ERR; } return NDMP9_NO_ERR; } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* Surrounds TAPE intfs */ #ifndef NDMOS_OPTION_NO_DATA_AGENT /* Surrounds DATA intfs */ /* * NDMPx_DATA Interfaces **************************************************************** */ static int data_ok_bu_type (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, char *bu_type); static int data_can_connect_and_start (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr *data_addr, ndmp9_mover_mode mover_mode); static int data_can_connect (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr *data_addr); static int data_can_start (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_mover_mode mover_mode); static int data_connect (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr *data_addr); static ndmp9_error data_copy_environment (struct ndm_session *sess, ndmp9_pval *env, unsigned n_env); static ndmp9_error data_copy_nlist (struct ndm_session *sess, ndmp9_name *nlist, unsigned n_nlist); /* * NDMP[234]_DATA_GET_STATE */ int ndmp_sxa_data_get_state (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_data_agent * da = sess->data_acb; if (!da) { NDMADR_RAISE(NDMP9_CONNECT_ERR, "No Data Agent"); } NDMS_WITH_VOID_REQUEST(ndmp9_data_get_state) *reply = da->data_state; return 0; NDMS_ENDWITH } /* * NDMP[234]_DATA_START_BACKUP */ int ndmp_sxa_data_start_backup (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { int rc; ndmp9_error error; if (!sess->data_acb) { NDMADR_RAISE(NDMP9_CONNECT_ERR, "No Data Agent"); } NDMS_WITH(ndmp9_data_start_backup) rc = data_ok_bu_type (sess, xa, ref_conn, request->bu_type); if (rc) { return rc; } if (request->addr.addr_type != NDMP9_ADDR_AS_CONNECTED) { rc = data_can_connect_and_start (sess, xa, ref_conn, &request->addr, NDMP9_MOVER_MODE_READ); } else { rc = data_can_start (sess, xa, ref_conn, NDMP9_MOVER_MODE_READ); } if (rc) { return rc; /* already tattled */ } strncpy (sess->data_acb->bu_type, request->bu_type, sizeof(sess->data_acb->bu_type) - 1); sess->data_acb->bu_type[sizeof(sess->data_acb->bu_type) - 1] = '\0'; error = data_copy_environment (sess, request->env.env_val, request->env.env_len); if (error != NDMP9_NO_ERR) { ndmda_belay (sess); NDMADR_RAISE(error, "copy-env"); } if (request->addr.addr_type != NDMP9_ADDR_AS_CONNECTED) { rc = data_connect (sess, xa, ref_conn, &request->addr); if (rc) { ndmda_belay (sess); return rc; /* already tattled */ } } error = ndmda_data_start_backup (sess); if (error != NDMP9_NO_ERR) { /* TODO: undo everything */ ndmda_belay (sess); NDMADR_RAISE(error, "start_backup"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_DATA_START_RECOVER */ int ndmp_sxa_data_start_recover (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; int rc; if (!sess->data_acb) { NDMADR_RAISE(NDMP9_CONNECT_ERR, "No Data Agent"); } NDMS_WITH(ndmp9_data_start_recover) rc = data_ok_bu_type (sess, xa, ref_conn, request->bu_type); if (rc) { return rc; } if (request->addr.addr_type != NDMP9_ADDR_AS_CONNECTED) { rc = data_can_connect_and_start (sess, xa, ref_conn, &request->addr, NDMP9_MOVER_MODE_WRITE); } else { rc = data_can_start (sess, xa, ref_conn, NDMP9_MOVER_MODE_WRITE); } if (rc) { return rc; /* already tattled */ } strncpy (sess->data_acb->bu_type, request->bu_type, sizeof(sess->data_acb->bu_type) - 1); sess->data_acb->bu_type[sizeof(sess->data_acb->bu_type) - 1] = '\0'; error = data_copy_environment (sess, request->env.env_val, request->env.env_len); if (error != NDMP9_NO_ERR) { ndmda_belay (sess); NDMADR_RAISE(error, "copy-env"); } error = data_copy_nlist (sess, request->nlist.nlist_val, request->nlist.nlist_len); if (error != NDMP9_NO_ERR) { ndmda_belay (sess); NDMADR_RAISE(error, "copy-nlist"); } if (request->addr.addr_type != NDMP9_ADDR_AS_CONNECTED) { rc = data_connect (sess, xa, ref_conn, &request->addr); if (rc) { ndmda_belay (sess); return rc; /* already tattled */ } } error = ndmda_data_start_recover (sess); if (error != NDMP9_NO_ERR) { /* TODO: undo everything */ ndmda_belay (sess); NDMADR_RAISE(error, "start_recover"); } return 0; NDMS_ENDWITH } /* * NDMP[234]_DATA_ABORT */ int ndmp_sxa_data_abort (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_data_agent * da = sess->data_acb; if (!sess->data_acb) { return 0; } NDMS_WITH_VOID_REQUEST(ndmp9_data_abort) if (da->data_state.state != NDMP9_DATA_STATE_ACTIVE) NDMADR_RAISE_ILLEGAL_STATE("data_state !ACTIVE"); ndmda_data_abort (sess); return 0; NDMS_ENDWITH } /* * NDMP[234]_DATA_GET_ENV */ int ndmp_sxa_data_get_env (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_data_agent * da = sess->data_acb; ndmp9_pval * env; NDMS_WITH_VOID_REQUEST(ndmp9_data_get_env) if (da->data_state.state == NDMP9_DATA_STATE_IDLE) { NDMADR_RAISE_ILLEGAL_STATE("data_state IDLE"); } if (da->data_state.operation != NDMP9_DATA_OP_BACKUP) { NDMADR_RAISE_ILLEGAL_STATE("data_op !BACKUP"); } ndmda_sync_environment (sess); ndmalogf (sess, ref_conn->chan.name, 6, "n_env=%d", da->env_tab.n_env); env = ndma_enumerate_env_list(&da->env_tab); if (!env) { NDMADR_RAISE(NDMP9_NO_MEM_ERR, "Allocating enumerate buffer"); } reply->env.env_len = da->env_tab.n_env; reply->env.env_val = env; #if 0 xa->reply.flags &= ~NDMNMB_FLAG_NO_FREE; /* free env after xmit */ #endif return 0; NDMS_ENDWITH } /* * NDMP[234]_DATA_STOP */ int ndmp_sxa_data_stop (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_data_agent * da = sess->data_acb; NDMS_WITH_VOID_REQUEST(ndmp9_data_stop) if (da->data_state.state != NDMP9_DATA_STATE_HALTED) { NDMADR_RAISE_ILLEGAL_STATE("data_state !HALTED"); } ndmda_data_stop (sess); return 0; NDMS_ENDWITH } /* * NDMP[234]_DATA_START_RECOVER_FILEHIST * This is a Traakan extension to NDMPv2 and NDMPv3 * Adopted for NDMPv4 */ int ndmp_sxa_data_start_recover_filehist (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { ndmp9_error error; int rc; if (!sess->data_acb) { NDMADR_RAISE(NDMP9_CONNECT_ERR, "No Data Agent"); } NDMS_WITH(ndmp9_data_start_recover) rc = data_ok_bu_type (sess, xa, ref_conn, request->bu_type); if (rc) { return rc; } if (request->addr.addr_type != NDMP9_ADDR_AS_CONNECTED) { rc = data_can_connect_and_start (sess, xa, ref_conn, &request->addr, NDMP9_MOVER_MODE_WRITE); } else { rc = data_can_start (sess, xa, ref_conn, NDMP9_MOVER_MODE_WRITE); } if (rc) { return rc; /* already tattled */ } strncpy (sess->data_acb->bu_type, request->bu_type, sizeof(sess->data_acb->bu_type) - 1); sess->data_acb->bu_type[sizeof(sess->data_acb->bu_type) - 1] = '\0'; error = data_copy_environment (sess, request->env.env_val, request->env.env_len); if (error != NDMP9_NO_ERR) { ndmda_belay (sess); NDMADR_RAISE(error, "copy-env"); } error = data_copy_nlist (sess, request->nlist.nlist_val, request->nlist.nlist_len); if (error != NDMP9_NO_ERR) { ndmda_belay (sess); NDMADR_RAISE(error, "copy-nlist"); } if (request->addr.addr_type != NDMP9_ADDR_AS_CONNECTED) { rc = data_connect (sess, xa, ref_conn, &request->addr); if (rc) { ndmda_belay (sess); return rc; /* already tattled */ } } error = ndmda_data_start_recover_fh (sess); if (error != NDMP9_NO_ERR) { /* TODO: undo everything */ ndmda_belay (sess); NDMADR_RAISE(error, "start_recover_filehist"); } return 0; NDMS_ENDWITH } #ifndef NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 /* Surrounds NDMPv[34] DATA intfs */ /* * NDMP[34]_DATA_CONNECT */ int ndmp_sxa_data_connect (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { if (!sess->data_acb) { NDMADR_RAISE(NDMP9_CONNECT_ERR, "No Data Agent"); } NDMS_WITH(ndmp9_data_connect) return data_connect (sess, xa, ref_conn, &request->addr); NDMS_ENDWITH } #ifdef notyet static int data_listen_common34 (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr_type addr_type); /* * NDMP[34]_DATA_LISTEN */ int ndmadr_data_listen (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_data_agent * da = sess->data_acb; int rc; switch (xa->request.protocol_version) { default: return NDMADR_UNIMPLEMENTED_VERSION; /* should never happen */ #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: /* not part of NDMPv2 */ return NDMADR_UNSPECIFIED_MESSAGE; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMS_WITH(ndmp3_data_listen) ndmp9_addr_type addr_type; /* Check args, map along the way */ switch (request->addr_type) { default: addr_type = -1; break; case NDMP3_ADDR_LOCAL: addr_type = NDMP9_ADDR_LOCAL; break; case NDMP3_ADDR_TCP: addr_type = NDMP9_ADDR_TCP; break; } rc = data_listen_common34 (sess, xa, ref_conn, addr_type); if (rc) return rc; /* something went wrong */ ndmp_9to3_addr (&da->data_state.data_connection_addr, &reply->data_connection_addr); /* reply->error already set to NDMPx_NO_ERROR */ NDMS_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMS_WITH(ndmp4_data_listen) ndmp9_addr_type addr_type; /* Check args, map along the way */ switch (request->addr_type) { default: addr_type = -1; break; case NDMP4_ADDR_LOCAL: addr_type = NDMP9_ADDR_LOCAL; break; case NDMP4_ADDR_TCP: addr_type = NDMP9_ADDR_TCP; break; } rc = data_listen_common34 (sess, xa, ref_conn, addr_type); if (rc) return rc; /* something went wrong */ ndmp_9to4_addr (&da->data_state.data_connection_addr, &reply->data_connection_addr); /* reply->error already set to NDMPx_NO_ERROR */ NDMS_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } /* this same intf is expected in v4, so _common() now */ static int data_listen_common34 (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr_type addr_type) { struct ndm_data_agent * da = sess->data_acb; #ifndef NDMOS_OPTION_NO_TAPE_AGENT struct ndm_tape_agent * ta = sess->tape_acb; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ ndmp9_error error; char reason[100]; /* Check args */ switch (addr_type) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_addr_type"); case NDMP9_ADDR_LOCAL: #ifdef NDMOS_OPTION_NO_TAPE_AGENT NDMADR_RAISE_ILLEGAL_ARGS("data LOCAL w/o local TAPE agent"); #endif /* NDMOS_OPTION_NO_TAPE_AGENT */ break; case NDMP9_ADDR_TCP: break; } /* Check states -- this should cover everything */ if (da->data_state.state != NDMP9_DATA_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("data_state !IDLE"); #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (ta->mover_state.state != NDMP9_MOVER_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE"); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* * Check image stream state -- should already be reflected * in the mover and data states. This extra check gives * us an extra measure of robustness and sanity * check on the implementation. */ error = ndmis_audit_data_listen (sess, addr_type, reason); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, reason); error = ndmis_data_listen (sess, addr_type, &da->data_state.data_connection_addr, reason); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, reason); error = ndmda_data_listen(sess); if (error != NDMP9_NO_ERR) { /* TODO: belay ndmis_data_listen() */ NDMADR_RAISE(error, "!data_listen"); } return 0; } #endif /* notyet */ #endif /* !NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 Surrounds NDMPv[34] DATA intfs */ /* * NDMPx_DATA helper routines */ static int data_ok_bu_type (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, char *bu_type) { ndmp9_config_info * ci; ndmp9_butype_info * bu; unsigned int i; ndmos_sync_config_info (sess); if (!sess->config_info) { NDMADR_RAISE(NDMP9_NO_MEM_ERR, "Allocating memory for config data"); } ci = sess->config_info; for (i = 0; i < ci->butype_info.butype_info_len; i++) { bu = &ci->butype_info.butype_info_val[i]; if (strcmp (bu_type, bu->butype_name) == 0) { return 0; } } NDMADR_RAISE_ILLEGAL_ARGS ("bu_type"); } /* * Data can only start if the mover is ready. * Just mode and state checks. */ static int data_can_connect_and_start (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr *data_addr, ndmp9_mover_mode mover_mode) { int rc; /* Check args */ switch (mover_mode) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_mode"); case NDMP9_MOVER_MODE_READ: /* aka BACKUP */ case NDMP9_MOVER_MODE_WRITE: /* aka RECOVER */ break; } rc = data_can_connect (sess, xa, ref_conn, data_addr); if (rc) return rc; #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (data_addr->addr_type == NDMP9_ADDR_LOCAL) { struct ndm_tape_agent * ta = sess->tape_acb; ndmp9_mover_get_state_reply * ms = &ta->mover_state; if (ms->mode != mover_mode) NDMADR_RAISE_ILLEGAL_STATE("mover_mode mismatch"); } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ return 0; } static int data_can_connect (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr *data_addr) { struct ndm_data_agent * da = sess->data_acb; #ifndef NDMOS_OPTION_NO_TAPE_AGENT struct ndm_tape_agent * ta = sess->tape_acb; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ ndmp9_error error; char reason[100]; /* Check args */ switch (data_addr->addr_type) { default: NDMADR_RAISE_ILLEGAL_ARGS("addr_type"); case NDMP9_ADDR_LOCAL: #ifdef NDMOS_OPTION_NO_TAPE_AGENT NDMADR_RAISE_ILLEGAL_ARGS("mover LOCAL w/o local DATA agent"); #endif /* NDMOS_OPTION_NO_TAPE_AGENT */ break; case NDMP9_ADDR_TCP: break; } /* Check states -- this should cover everything */ if (da->data_state.state != NDMP9_DATA_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("data_state !IDLE"); #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (data_addr->addr_type == NDMP9_ADDR_LOCAL) { ndmp9_mover_get_state_reply *ms = &ta->mover_state; if (ms->state != NDMP9_MOVER_STATE_LISTEN) NDMADR_RAISE_ILLEGAL_STATE("mover_state !LISTEN"); if (ms->data_connection_addr.addr_type != NDMP9_ADDR_LOCAL) NDMADR_RAISE_ILLEGAL_STATE("mover_addr !LOCAL"); } else { if (ta->mover_state.state != NDMP9_MOVER_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE"); } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* * Check image stream state -- should already be reflected * in the mover and data states. This extra check gives * us an extra measure of robustness and sanity * check on the implementation. */ error = ndmis_audit_data_connect (sess, data_addr->addr_type, reason); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, reason); return 0; } static int data_can_start (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_mover_mode mover_mode) { struct ndm_data_agent * da = sess->data_acb; ndmp9_data_get_state_reply *ds = &da->data_state; #ifndef NDMOS_OPTION_NO_TAPE_AGENT struct ndm_tape_agent * ta = sess->tape_acb; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* Check args */ switch (mover_mode) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_mode"); case NDMP9_MOVER_MODE_READ: /* aka BACKUP */ case NDMP9_MOVER_MODE_WRITE: /* aka RECOVER */ break; } /* Check states -- this should cover everything */ if (da->data_state.state != NDMP9_DATA_STATE_CONNECTED) NDMADR_RAISE_ILLEGAL_STATE("data_state !CONNECTED"); #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (ds->data_connection_addr.addr_type == NDMP9_ADDR_LOCAL) { ndmp9_mover_get_state_reply *ms = &ta->mover_state; if (ms->state != NDMP9_MOVER_STATE_ACTIVE) NDMADR_RAISE_ILLEGAL_STATE("mover_state !ACTIVE"); if (ms->data_connection_addr.addr_type != NDMP9_ADDR_LOCAL) NDMADR_RAISE_ILLEGAL_STATE("mover_addr !LOCAL"); if (ms->mode != mover_mode) NDMADR_RAISE_ILLEGAL_STATE("mover_mode mismatch"); } else { if (ta->mover_state.state != NDMP9_MOVER_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE"); } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ return 0; } /* * For NDMPv2, called from ndmadr_data_start_{backup,recover,recover_filhist}() * For NDMPv[34], called from ndmp_sxa_data_connect() */ static int data_connect (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_addr *data_addr) { struct ndm_data_agent * da = sess->data_acb; int rc; ndmp9_error error; char reason[100]; if (!sess->data_acb) { NDMADR_RAISE(NDMP9_CONNECT_ERR, "No Data Agent"); } rc = data_can_connect (sess, xa, ref_conn, data_addr); if (rc) return rc; /* * Audits done, connect already */ error = ndmis_data_connect (sess, data_addr, reason); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, reason); da->data_state.data_connection_addr = *data_addr; /* alt: da->....data_connection_addr = sess->...peer_addr */ error = ndmda_data_connect (sess); if (error != NDMP9_NO_ERR) { /* TODO: belay ndmis_data_connect() */ NDMADR_RAISE(error, "!data_connect"); } da->data_state.data_connection_addr = *data_addr; return 0; } static ndmp9_error data_copy_environment (struct ndm_session *sess, ndmp9_pval *env, unsigned n_env) { int rc; if (n_env > NDM_MAX_ENV) return NDMP9_ILLEGAL_ARGS_ERR; rc = ndmda_copy_environment (sess, env, n_env); if (rc != 0) return NDMP9_NO_MEM_ERR; return NDMP9_NO_ERR; } static ndmp9_error data_copy_nlist (struct ndm_session *sess, ndmp9_name *nlist, unsigned n_nlist) { int rc; if (n_nlist >= NDM_MAX_NLIST) return NDMP9_ILLEGAL_ARGS_ERR; rc = ndmda_copy_nlist (sess, nlist, n_nlist); if (rc != 0) return NDMP9_NO_MEM_ERR; return NDMP9_NO_ERR; } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ /* Surrounds DATA intfs */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* Surrounds MOVER intfs */ /* * NDMPx_MOVER Interfaces **************************************************************** */ static ndmp9_error mover_can_proceed (struct ndm_session *sess, int will_write); /* * NDMP[234]_MOVER_GET_STATE */ int ndmp_sxa_mover_get_state (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; NDMS_WITH_VOID_REQUEST(ndmp9_mover_get_state) ndmta_mover_sync_state(sess); *reply = ta->mover_state; return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_LISTEN */ int ndmp_sxa_mover_listen (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { #ifndef NDMOS_OPTION_NO_DATA_AGENT struct ndm_data_agent * da = sess->data_acb; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ struct ndm_tape_agent * ta = sess->tape_acb; ndmp9_error error; int will_write; char reason[100]; NDMS_WITH(ndmp9_mover_listen) ndmalogf (sess, 0, 6, "mover_listen_common() addr_type=%s mode=%s", ndmp9_addr_type_to_str (request->addr_type), ndmp9_mover_mode_to_str (request->mode)); /* Check args */ switch (request->mode) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_mode"); case NDMP9_MOVER_MODE_READ: will_write = 1; break; case NDMP9_MOVER_MODE_WRITE: will_write = 0; break; } switch (request->addr_type) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_addr_type"); case NDMP9_ADDR_LOCAL: #ifdef NDMOS_OPTION_NO_DATA_AGENT NDMADR_RAISE_ILLEGAL_ARGS("mover LOCAL w/o local DATA agent"); #endif /* NDMOS_OPTION_NO_DATA_AGENT */ break; case NDMP9_ADDR_TCP: break; } /* Check states -- this should cover everything */ if (ta->mover_state.state != NDMP9_MOVER_STATE_IDLE) { NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE"); } #ifndef NDMOS_OPTION_NO_DATA_AGENT if (da && da->data_state.state != NDMP9_DATA_STATE_IDLE) { NDMADR_RAISE_ILLEGAL_STATE("data_state !IDLE"); } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ /* Check that the tape is ready to go */ error = mover_can_proceed (sess, will_write); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!mover_can_proceed"); } /* * Check image stream state -- should already be reflected * in the mover and data states. This extra check gives * us an extra measure of robustness and sanity * check on the implementation. */ error = ndmis_audit_tape_listen (sess, request->addr_type, reason); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, reason); } error = ndmis_tape_listen (sess, request->addr_type, &ta->mover_state.data_connection_addr, reason); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, reason); } error = ndmta_mover_listen(sess, request->mode); if (error != NDMP9_NO_ERR) { /* TODO: belay ndmis_tape_listen() */ NDMADR_RAISE(error, "!mover_listen"); } reply->data_connection_addr = ta->mover_state.data_connection_addr; return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_CONTINUE */ int ndmp_sxa_mover_continue (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; ndmp9_error error; int will_write; NDMS_WITH_VOID_REQUEST(ndmp9_mover_continue) if (ta->mover_state.state != NDMP9_MOVER_STATE_PAUSED) { NDMADR_RAISE_ILLEGAL_STATE("mover_state !PAUSED"); } will_write = ta->mover_state.mode == NDMP9_MOVER_MODE_READ; error = mover_can_proceed (sess, will_write); if (error != NDMP9_NO_ERR) { NDMADR_RAISE(error, "!mover_can_proceed"); } ndmta_mover_continue (sess); return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_ABORT */ int ndmp_sxa_mover_abort (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; NDMS_WITH_VOID_REQUEST(ndmp9_mover_abort) if (ta->mover_state.state != NDMP9_MOVER_STATE_LISTEN && ta->mover_state.state != NDMP9_MOVER_STATE_ACTIVE && ta->mover_state.state != NDMP9_MOVER_STATE_PAUSED) { NDMADR_RAISE_ILLEGAL_STATE("mover_state"); } ndmta_mover_abort (sess); return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_STOP */ int ndmp_sxa_mover_stop (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; NDMS_WITH_VOID_REQUEST(ndmp9_mover_stop) if (ta->mover_state.state != NDMP9_MOVER_STATE_HALTED) { NDMADR_RAISE_ILLEGAL_STATE("mover_state !HALTED"); } ndmta_mover_stop (sess); return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_SET_WINDOW */ int ndmp_sxa_mover_set_window (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; struct ndmp9_mover_get_state_reply *ms = &ta->mover_state; uint64_t max_len; uint64_t end_win; NDMS_WITH(ndmp9_mover_set_window) ndmta_mover_sync_state (sess); if (ref_conn->protocol_version < NDMP4VER) { /* * NDMP[23] require the Mover be in LISTEN state. * Unclear sequence for MOVER_CONNECT. */ if (ms->state != NDMP9_MOVER_STATE_LISTEN && ms->state != NDMP9_MOVER_STATE_PAUSED) { NDMADR_RAISE_ILLEGAL_STATE("mover_state !LISTEN/PAUSED"); } } else { /* * NDMP4 require the Mover be in IDLE state. * This always preceeds both MOVER_LISTEN or * MOVER_CONNECT. */ if (ms->state != NDMP9_MOVER_STATE_IDLE && ms->state != NDMP9_MOVER_STATE_PAUSED) { NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE/PAUSED"); } } if (request->offset % ms->record_size != 0) { NDMADR_RAISE_ILLEGAL_ARGS("off !record_size"); } /* TODO: NDMPv4 subtle semantic changes here */ /* If a maximum length window is required following a mover transition * to the PAUSED state, a window length of all ones (binary) minus the * current window offset MUST be specified." (NDMPv4 RFC, Section * 3.6.2.2) -- we allow length = NDMP_LENGTH_INFINITY too */ if (request->length != NDMP_LENGTH_INFINITY && request->length + request->offset != NDMP_LENGTH_INFINITY) { if (request->length % ms->record_size != 0) { NDMADR_RAISE_ILLEGAL_ARGS("len !record_size"); } #if 0 /* Too pedantic. Sometimes needed (like for testing) */ if (request->length == 0) { NDMADR_RAISE_ILLEGAL_ARGS("length 0"); } #endif max_len = NDMP_LENGTH_INFINITY - request->offset; max_len -= max_len % ms->record_size; if (request->length > max_len) { /* learn math fella */ NDMADR_RAISE_ILLEGAL_ARGS("length too long"); } end_win = request->offset + request->length; } else { end_win = NDMP_LENGTH_INFINITY; } ms->window_offset = request->offset; /* record_num should probably be one less than this value, but the spec * says to divide, so we divide */ ms->record_num = request->offset / ms->record_size; ms->window_length = request->length; ta->mover_window_end = end_win; ta->mover_window_first_blockno = ta->tape_state.blockno.value; return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_READ */ int ndmp_sxa_mover_read (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; struct ndmp9_mover_get_state_reply *ms = &ta->mover_state; NDMS_WITH(ndmp9_mover_read) ndmta_mover_sync_state (sess); if (ms->state != NDMP9_MOVER_STATE_ACTIVE) { NDMADR_RAISE_ILLEGAL_STATE("mover_state !ACTIVE"); } if (ms->bytes_left_to_read > 0) { NDMADR_RAISE_ILLEGAL_STATE("byte_left_to_read"); } if (ms->data_connection_addr.addr_type != NDMP9_ADDR_TCP) { NDMADR_RAISE_ILLEGAL_STATE("mover_addr !TCP"); } if (ms->mode != NDMP9_MOVER_MODE_WRITE) { NDMADR_RAISE_ILLEGAL_STATE("mover_mode !WRITE"); } ndmta_mover_read (sess, request->offset, request->length); return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_CLOSE */ int ndmp_sxa_mover_close (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; NDMS_WITH_VOID_REQUEST(ndmp9_mover_close) { if (ta->mover_state.state == NDMP9_MOVER_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE"); } ndmta_mover_close (sess); return 0; NDMS_ENDWITH } /* * NDMP[234]_MOVER_SET_RECORD_SIZE */ int ndmp_sxa_mover_set_record_size (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_tape_agent * ta = sess->tape_acb; struct ndmp9_mover_get_state_reply *ms = &ta->mover_state; NDMS_WITH(ndmp9_mover_set_record_size) ndmta_mover_sync_state (sess); if (ms->state != NDMP9_MOVER_STATE_IDLE && ms->state != NDMP9_MOVER_STATE_PAUSED) NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE/PAUSED"); if (!NDMOS_MACRO_OK_TAPE_REC_LEN(request->record_size)) NDMADR_RAISE_ILLEGAL_ARGS("!ok_tape_rec_len"); ta->mover_state.record_size = request->record_size; return 0; NDMS_ENDWITH } #ifndef NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 /* Surrounds NDMPv[34] MOVER intfs */ /* * NDMP[34]_MOVER_CONNECT */ int ndmp_sxa_mover_connect (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { #ifndef NDMOS_OPTION_NO_DATA_AGENT struct ndm_data_agent * da = sess->data_acb; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ struct ndm_tape_agent * ta = sess->tape_acb; ndmp9_error error; int will_write; char reason[100]; NDMS_WITH(ndmp9_mover_connect) /* Check args */ switch (request->mode) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_mode"); case NDMP9_MOVER_MODE_READ: will_write = 1; break; case NDMP9_MOVER_MODE_WRITE: will_write = 0; break; } switch (request->addr.addr_type) { default: NDMADR_RAISE_ILLEGAL_ARGS("mover_addr_type"); case NDMP9_ADDR_LOCAL: #ifdef NDMOS_OPTION_NO_DATA_AGENT NDMADR_RAISE_ILLEGAL_ARGS("mover LOCAL w/o local DATA agent"); #endif /* NDMOS_OPTION_NO_DATA_AGENT */ break; case NDMP9_ADDR_TCP: break; } /* Check states -- this should cover everything */ if (ta->mover_state.state != NDMP9_MOVER_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("mover_state !IDLE"); #ifndef NDMOS_OPTION_NO_DATA_AGENT if (request->addr.addr_type == NDMP9_ADDR_LOCAL) { ndmp9_data_get_state_reply *ds = &da->data_state; if (ds->state != NDMP9_DATA_STATE_LISTEN) NDMADR_RAISE_ILLEGAL_STATE("data_state !LISTEN"); if (ds->data_connection_addr.addr_type != NDMP9_ADDR_LOCAL) NDMADR_RAISE_ILLEGAL_STATE("data_addr !LOCAL"); } else { if (da->data_state.state != NDMP9_DATA_STATE_IDLE) NDMADR_RAISE_ILLEGAL_STATE("data_state !IDLE"); } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ /* Check that the tape is ready to go */ error = mover_can_proceed (sess, will_write); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, "!mover_can_proceed"); /* * Check image stream state -- should already be reflected * in the mover and data states. This extra check gives * us an extra measure of robustness and sanity * check on the implementation. */ error = ndmis_audit_tape_connect (sess, request->addr.addr_type, reason); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, reason); error = ndmis_tape_connect (sess, &request->addr, reason); if (error != NDMP9_NO_ERR) NDMADR_RAISE(error, reason); ta->mover_state.data_connection_addr = request->addr; /* alt: ta->....data_connection_addr = sess->...peer_addr */ error = ndmta_mover_connect (sess, request->mode); if (error != NDMP9_NO_ERR) { /* TODO: belay ndmis_tape_connect() */ NDMADR_RAISE(error, "!mover_connect"); } return 0; NDMS_ENDWITH } #endif /* !NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 Surrounds NDMPv[34] MOVER intfs */ /* * NDMPx_MOVER helper routines */ /* * MOVER can only proceed from IDLE->LISTEN or PAUSED->ACTIVE * if the tape drive is ready. */ static ndmp9_error mover_can_proceed (struct ndm_session *sess, int will_write) { struct ndm_tape_agent * ta = sess->tape_acb; ndmos_tape_sync_state(sess); if (ta->tape_state.state != NDMP9_TAPE_STATE_OPEN) return NDMP9_DEV_NOT_OPEN_ERR; if (will_write && !NDMTA_TAPE_IS_WRITABLE(ta)) return NDMP9_PERMISSION_ERR; return NDMP9_NO_ERR; } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* Surrounds MOVER intfs */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds NOTIFY intfs */ /* * NDMPx_NOTIFY Interfaces **************************************************************** */ /* * NDMP[234]_NOTIFY_DATA_HALTED */ int ndmp_sxa_notify_data_halted (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent *ca = sess->control_acb; NDMS_WITH_NO_REPLY(ndmp9_notify_data_halted) xa->reply.flags |= NDMNMB_FLAG_NO_SEND; ca->pending_notify_data_halted++; return 0; NDMS_ENDWITH } /* * NDMP[234]_NOTIFY_CONNECTED */ int ndmp_sxa_notify_connected (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { NDMS_WITH_NO_REPLY(ndmp9_notify_connected) xa->reply.flags |= NDMNMB_FLAG_NO_SEND; /* Just ignore? */ return 0; NDMS_ENDWITH } /* * NDMP[234]_NOTIFY_MOVER_HALTED */ int ndmp_sxa_notify_mover_halted (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent * ca = sess->control_acb; NDMS_WITH_NO_REPLY(ndmp9_notify_mover_halted) xa->reply.flags |= NDMNMB_FLAG_NO_SEND; ca->pending_notify_mover_halted++; return 0; NDMS_ENDWITH } /* * NDMP[234]_NOTIFY_MOVER_PAUSED */ int ndmp_sxa_notify_mover_paused (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent * ca = sess->control_acb; NDMS_WITH_NO_REPLY(ndmp9_notify_mover_paused) xa->reply.flags |= NDMNMB_FLAG_NO_SEND; ca->pending_notify_mover_paused++; ca->last_notify_mover_paused.reason = request->reason; ca->last_notify_mover_paused.seek_position = request->seek_position; return 0; NDMS_ENDWITH } /* * NDMP[234]_NOTIFY_DATA_READ */ int ndmp_sxa_notify_data_read (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent * ca = sess->control_acb; NDMS_WITH_NO_REPLY(ndmp9_notify_data_read) xa->reply.flags |= NDMNMB_FLAG_NO_SEND; ca->pending_notify_data_read++; ca->last_notify_data_read.offset = request->offset; ca->last_notify_data_read.length = request->length; return 0; NDMS_ENDWITH } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds NOTIFY intfs */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds LOG intfs */ /* * NDMPx_LOG Interfaces **************************************************************** */ /* * NDMP[234]_LOG_FILE */ int ndmp_sxa_log_file (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent *ca = sess->control_acb; char prefix[32]; char * tag; int lev = 0; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp9_log_file) switch (request->recovery_status) { case NDMP9_RECOVERY_SUCCESSFUL: tag = "OK"; lev = 1; break; case NDMP9_RECOVERY_FAILED_PERMISSION: tag = "Bad Permission"; break; case NDMP9_RECOVERY_FAILED_NOT_FOUND: tag = "Not found"; break; case NDMP9_RECOVERY_FAILED_NO_DIRECTORY: tag = "No directory"; break; case NDMP9_RECOVERY_FAILED_OUT_OF_MEMORY: tag = "Out of mem"; break; case NDMP9_RECOVERY_FAILED_IO_ERROR: tag = "I/O error"; break; case NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR: tag = "General error"; break; default: tag = "n"; break; } /* count the notification and whether it is good news or not */ ca->recover_log_file_count++; if (lev == 1) { ca->recover_log_file_ok++; } else { ca->recover_log_file_error++; } snprintf (prefix, sizeof(prefix), "%cLF", ref_conn->chan.name[1]); ndmalogf (sess, prefix, lev, "%s: %s", tag, request->name); NDMS_ENDWITH return 0; } #ifndef NDMOS_OPTION_NO_NDMP2 /* * NDMP2_LOG_LOG */ int ndmp2_sxa_log_log (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { char prefix[32]; char * tag; char * bp; int lev; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp2_log_log) tag = "n"; lev = 1; snprintf (prefix, sizeof(prefix), "%cLM%s", ref_conn->chan.name[1], tag); bp = strrchr(request->entry, '\n'); if (bp) { *bp = '\0'; } ndmalogf (sess, prefix, lev, "LOG_LOG: '%s'", request->entry); NDMS_ENDWITH return 0; } /* * NDMP2_LOG_DEBUG */ int ndmp2_sxa_log_debug (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { char prefix[32]; char * tag; char * bp; int lev; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp2_log_debug) tag = "d"; lev = 2; snprintf (prefix, sizeof(prefix), "%cLM%s", ref_conn->chan.name[1], tag); bp = strrchr(request->message, '\n'); if (bp) { *bp = '\0'; } ndmalogf (sess, prefix, lev, "LOG_DEBUG: '%s'", request->message); NDMS_ENDWITH return 0; } #endif /* !NDMOS_OPTION_NO_NDMP2 */ /* * NDMP[34]_LOG_MESSAGE */ int ndmp_sxa_log_message (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { char prefix[32]; char * tag; char * bp; int lev; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp9_log_message) switch (request->log_type) { case NDMP9_LOG_NORMAL: tag = "n"; lev = 1; break; case NDMP9_LOG_DEBUG: tag = "d"; lev = 2; break; case NDMP9_LOG_ERROR: tag = "e"; lev = 0; break; case NDMP9_LOG_WARNING: tag = "w"; lev = 0; break; default: tag = "?"; lev = 0; break; } snprintf (prefix, sizeof(prefix), "%cLM%s", ref_conn->chan.name[1], tag); bp = strrchr(request->entry, '\n'); if (bp) { *bp = '\0'; } ndmalogf (sess, prefix, lev, "LOG_MESSAGE: '%s'", request->entry); NDMS_ENDWITH return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds LOG intfs */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds FH intfs */ /* * NDMPx_FH Interfaces **************************************************************** */ /* * NDMP2_FH_ADD_UNIX_PATH * NDMP[34]_FH_ADD_FILE */ int ndmp_sxa_fh_add_file (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent *ca = sess->control_acb; struct ndmlog * ixlog = &ca->job.index_log; int tagc = ref_conn->chan.name[1]; unsigned int i; ndmp9_file * file; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp9_fh_add_file) for (i = 0; i < request->files.files_len; i++) { file = &request->files.files_val[i]; ndmfhdb_add_file (ixlog, tagc, file->unix_path, &file->fstat); } NDMS_ENDWITH return 0; } /* * NDMP2_FH_ADD_UNIX_DIR * NDMP[34]_FH_ADD_DIR */ int ndmp_sxa_fh_add_dir (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent *ca = sess->control_acb; struct ndmlog * ixlog = &ca->job.index_log; int tagc = ref_conn->chan.name[1]; char * raw_name; unsigned int i; ndmp9_dir * dir; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp9_fh_add_dir) for (i = 0; i < request->dirs.dirs_len; i++) { dir = &request->dirs.dirs_val[i]; raw_name = dir->unix_name; switch (ca->job.n_dir_entry) { case 0: if (strcmp (raw_name, ".") == 0) { /* goodness */ ndmfhdb_add_dirnode_root (ixlog, tagc, dir->node); ca->job.root_node = dir->node; } else { /* ungoodness */ ndmalogf (sess, 0, 0, "WARNING: First add_dir " "entry is non-conforming"); } break; case 1: if (strcmp (raw_name, "..") == 0 && dir->parent == dir->node && dir->node == ca->job.root_node) { /* goodness */ } else { /* ungoodness */ /* NetApp is non-conforming */ /* ndmalogf (sess, 0, 0, "WARNING: Second add_dir " "entry is non-conforming"); */ } break; default: break; } ndmfhdb_add_dir (ixlog, tagc, dir->unix_name, dir->parent, dir->node); ca->job.n_dir_entry++; } NDMS_ENDWITH return 0; } /* * NDMP2_FH_ADD_UNIX_NODE * NDMP[34]_FH_ADD_NODE */ int ndmp_sxa_fh_add_node (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_control_agent *ca = sess->control_acb; struct ndmlog * ixlog = &ca->job.index_log; int tagc = ref_conn->chan.name[1]; unsigned int i; ndmp9_node * node; xa->reply.flags |= NDMNMB_FLAG_NO_SEND; NDMS_WITH_NO_REPLY(ndmp9_fh_add_node) for (i = 0; i < request->nodes.nodes_len; i++) { node = &request->nodes.nodes_val[i]; ndmfhdb_add_node (ixlog, tagc, node->fstat.node.value, &node->fstat); } NDMS_ENDWITH return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds FH intfs */ /* * Common helper interfaces **************************************************************** * These do complicated state checks which are called from * several of the interfaces above. */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* * Shortcut for DATA->MOVER READ requests when NDMP9_ADDR_LOCAL * (local MOVER). This is implemented here because of the * state (sanity) checks. This should track the * NDMP9_MOVER_READ stanza in ndma_dispatch_request(). */ int ndmta_local_mover_read (struct ndm_session *sess, uint64_t offset, uint64_t length) { struct ndm_tape_agent * ta = sess->tape_acb; struct ndmp9_mover_get_state_reply *ms = &ta->mover_state; char * errstr = 0; if (ms->state != NDMP9_MOVER_STATE_ACTIVE && ms->state != NDMP9_MOVER_STATE_LISTEN) { errstr = "mover_state !ACTIVE"; goto senderr; } if (ms->bytes_left_to_read > 0) { errstr = "byte_left_to_read"; goto senderr; } if (ms->data_connection_addr.addr_type != NDMP9_ADDR_LOCAL) { errstr = "mover_addr !LOCAL"; goto senderr; } if (ms->mode != NDMP9_MOVER_MODE_WRITE) { errstr = "mover_mode !WRITE"; goto senderr; } ms->seek_position = offset; ms->bytes_left_to_read = length; ta->mover_want_pos = offset; return 0; senderr: if (errstr) { ndmalogf (sess, 0, 2, "local_read error why=%s", errstr); } return -1; } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* * Dispatch Version Table and Dispatch Request Tables (DVT/DRT) **************************************************************** */ struct ndm_dispatch_request_table * ndma_drt_lookup (struct ndm_dispatch_version_table *dvt, unsigned protocol_version, unsigned message) { struct ndm_dispatch_request_table * drt; for (; dvt->protocol_version >= 0; dvt++) { if (dvt->protocol_version == (int)protocol_version) break; } if (dvt->protocol_version < 0) return 0; for (drt = dvt->dispatch_request_table; drt->message; drt++) { if (drt->message == message) return drt; } return 0; } struct ndm_dispatch_request_table ndma_dispatch_request_table_v0[] = { { NDMP0_CONNECT_OPEN, NDM_DRT_FLAG_OK_NOT_CONNECTED+NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_connect_open, }, { NDMP0_CONNECT_CLOSE, NDM_DRT_FLAG_OK_NOT_CONNECTED+NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_connect_close, }, #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds NOTIFY intfs */ { NDMP0_NOTIFY_CONNECTED, 0, ndmp_sxa_notify_connected, }, #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds NOTIFY intfs */ {0} }; #ifndef NDMOS_OPTION_NO_NDMP2 struct ndm_dispatch_request_table ndma_dispatch_request_table_v2[] = { { NDMP2_CONFIG_GET_BUTYPE_ATTR, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp2_sxa_config_get_butype_attr }, { NDMP2_LOG_LOG, 0, ndmp2_sxa_log_log }, { NDMP2_LOG_DEBUG, 0, ndmp2_sxa_log_debug }, {0} }; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 struct ndm_dispatch_request_table ndma_dispatch_request_table_v3[] = { {0} }; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 struct ndm_dispatch_request_table ndma_dispatch_request_table_v4[] = { {0} }; #endif /* !NDMOS_OPTION_NO_NDMP4 */ struct ndm_dispatch_request_table ndma_dispatch_request_table_v9[] = { { NDMP9_CONNECT_OPEN, NDM_DRT_FLAG_OK_NOT_CONNECTED+NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_connect_open }, { NDMP9_CONNECT_CLIENT_AUTH, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_connect_client_auth }, { NDMP9_CONNECT_CLOSE, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_connect_close }, { NDMP9_CONNECT_SERVER_AUTH, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_connect_server_auth }, { NDMP9_CONFIG_GET_HOST_INFO, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, { NDMP9_CONFIG_GET_CONNECTION_TYPE, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, { NDMP9_CONFIG_GET_AUTH_ATTR, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_auth_attr }, { NDMP9_CONFIG_GET_BUTYPE_INFO, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, { NDMP9_CONFIG_GET_FS_INFO, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, { NDMP9_CONFIG_GET_TAPE_INFO, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, { NDMP9_CONFIG_GET_SCSI_INFO, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, { NDMP9_CONFIG_GET_SERVER_INFO, NDM_DRT_FLAG_OK_NOT_AUTHORIZED, ndmp_sxa_config_get_info }, #ifndef NDMOS_OPTION_NO_ROBOT_AGENT /* Surrounds SCSI intfs */ { NDMP9_SCSI_OPEN, 0, ndmp_sxa_scsi_open }, { NDMP9_SCSI_CLOSE, 0, ndmp_sxa_scsi_close }, { NDMP9_SCSI_GET_STATE, 0, ndmp_sxa_scsi_get_state }, { NDMP9_SCSI_SET_TARGET, 0, ndmp_sxa_scsi_set_target }, { NDMP9_SCSI_RESET_DEVICE, 0, ndmp_sxa_scsi_reset_device }, { NDMP9_SCSI_RESET_BUS, 0, ndmp_sxa_scsi_reset_bus }, { NDMP9_SCSI_EXECUTE_CDB, 0, ndmp_sxa_scsi_execute_cdb }, #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ /* Surrounds SCSI intfs */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* Surrounds TAPE intfs */ { NDMP9_TAPE_OPEN, 0, ndmp_sxa_tape_open }, { NDMP9_TAPE_CLOSE, 0, ndmp_sxa_tape_close }, { NDMP9_TAPE_GET_STATE, 0, ndmp_sxa_tape_get_state }, { NDMP9_TAPE_MTIO, 0, ndmp_sxa_tape_mtio }, { NDMP9_TAPE_WRITE, 0, ndmp_sxa_tape_write }, { NDMP9_TAPE_READ, 0, ndmp_sxa_tape_read }, { NDMP9_TAPE_EXECUTE_CDB, 0, ndmp_sxa_tape_execute_cdb }, #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* Surrounds TAPE intfs */ #ifndef NDMOS_OPTION_NO_DATA_AGENT /* Surrounds DATA intfs */ { NDMP9_DATA_GET_STATE, 0, ndmp_sxa_data_get_state }, { NDMP9_DATA_START_BACKUP, 0, ndmp_sxa_data_start_backup }, { NDMP9_DATA_START_RECOVER, 0, ndmp_sxa_data_start_recover }, { NDMP9_DATA_ABORT, 0, ndmp_sxa_data_abort }, { NDMP9_DATA_GET_ENV, 0, ndmp_sxa_data_get_env }, { NDMP9_DATA_STOP, 0, ndmp_sxa_data_stop }, #ifndef NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 /* Surrounds NDMPv[34] DATA intfs */ #ifdef notyet { NDMP9_DATA_LISTEN, 0, ndmp_sxa_data_listen }, #endif /* notyet */ { NDMP9_DATA_CONNECT, 0, ndmp_sxa_data_connect }, #endif /* NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 Surrounds NDMPv[34] DATA intfs */ { NDMP9_DATA_START_RECOVER_FILEHIST, 0, ndmp_sxa_data_start_recover_filehist }, #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ /* Surrounds DATA intfs */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds NOTIFY intfs */ { NDMP9_NOTIFY_DATA_HALTED, 0, ndmp_sxa_notify_data_halted }, { NDMP9_NOTIFY_CONNECTED, 0, ndmp_sxa_notify_connected }, { NDMP9_NOTIFY_MOVER_HALTED, 0, ndmp_sxa_notify_mover_halted }, { NDMP9_NOTIFY_MOVER_PAUSED, 0, ndmp_sxa_notify_mover_paused }, { NDMP9_NOTIFY_DATA_READ, 0, ndmp_sxa_notify_data_read }, #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds NOTIFY intfs */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds LOG intfs */ { NDMP9_LOG_FILE, 0, ndmp_sxa_log_file }, { NDMP9_LOG_MESSAGE, 0, ndmp_sxa_log_message }, #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds LOG intfs */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Surrounds FH intfs */ { NDMP9_FH_ADD_FILE, 0, ndmp_sxa_fh_add_file }, { NDMP9_FH_ADD_DIR, 0, ndmp_sxa_fh_add_dir }, { NDMP9_FH_ADD_NODE, 0, ndmp_sxa_fh_add_node }, #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ /* Surrounds FH intfs */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* Surrounds MOVER intfs */ { NDMP9_MOVER_GET_STATE, 0, ndmp_sxa_mover_get_state }, { NDMP9_MOVER_LISTEN, 0, ndmp_sxa_mover_listen }, { NDMP9_MOVER_CONTINUE, 0, ndmp_sxa_mover_continue }, { NDMP9_MOVER_ABORT, 0, ndmp_sxa_mover_abort }, { NDMP9_MOVER_STOP, 0, ndmp_sxa_mover_stop }, { NDMP9_MOVER_SET_WINDOW, 0, ndmp_sxa_mover_set_window }, { NDMP9_MOVER_READ, 0, ndmp_sxa_mover_read }, { NDMP9_MOVER_CLOSE, 0, ndmp_sxa_mover_close }, { NDMP9_MOVER_SET_RECORD_SIZE, 0, ndmp_sxa_mover_set_record_size }, { NDMP9_MOVER_CONNECT, 0, ndmp_sxa_mover_connect }, #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* Surrounds MOVER intfs */ {0} }; struct ndm_dispatch_version_table ndma_dispatch_version_table[] = { { 0, ndma_dispatch_request_table_v0 }, #ifndef NDMOS_OPTION_NO_NDMP2 { NDMP2VER, ndma_dispatch_request_table_v2 }, #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 { NDMP3VER, ndma_dispatch_request_table_v3 }, #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 { NDMP4VER, ndma_dispatch_request_table_v4 }, #endif /* !NDMOS_OPTION_NO_NDMP4 */ { NDMP9VER, ndma_dispatch_request_table_v9 }, { -1 } }; bareos-Release-14.2.6/src/ndmp/ndma_comm_job.c000066400000000000000000000152461263011562700211250ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT #define RETERR if (errcnt++ >= errskip) return errcnt; #define ERROR(S) { if (errbuf) strcpy(errbuf, (S)); RETERR } /* * To just check a job: * rc = ndma_job_audit (job, 0, 0); * if (rc) { "error" } * * To display everything wrong with a job: * i = n_err = 0; * do { * n_err = ndma_job_audit (job, errbuf, i); * if (n_err) display (errbuf); * i++; * } while (i < n_err); * * if (n_err) { "error" } */ int ndma_job_audit (struct ndm_job_param *job, char *errbuf, int errskip) { int errcnt = 0; char * audit_what; switch (job->operation) { default: ERROR ("invalid operatiton") return -1; case NDM_JOB_OP_BACKUP: audit_what = "DfbBmM"; break; case NDM_JOB_OP_EXTRACT: audit_what = "DfbBmM"; break; case NDM_JOB_OP_TOC: audit_what = "DfbBmM"; break; case NDM_JOB_OP_QUERY_AGENTS: audit_what = ""; break; case NDM_JOB_OP_INIT_LABELS: audit_what = "TfmM"; break; case NDM_JOB_OP_LIST_LABELS: audit_what = "TfM"; break; case NDM_JOB_OP_REMEDY_ROBOT: audit_what = ""; break; case NDM_JOB_OP_TEST_TAPE: audit_what = "TfM"; break; case NDM_JOB_OP_TEST_MOVER: audit_what = "TfbM"; break; case NDM_JOB_OP_TEST_DATA: audit_what = "DB"; break; case NDM_JOB_OP_REWIND_TAPE: audit_what = "Tf"; break; case NDM_JOB_OP_EJECT_TAPE: audit_what = "Tf"; break; case NDM_JOB_OP_MOVE_TAPE: audit_what = "Rr@"; break; case NDM_JOB_OP_IMPORT_TAPE: audit_what = "Rr@"; break; case NDM_JOB_OP_EXPORT_TAPE: audit_what = "Rr@"; break; case NDM_JOB_OP_LOAD_TAPE: audit_what = "Rr@"; break; case NDM_JOB_OP_UNLOAD_TAPE: audit_what = "Rr"; break; case NDM_JOB_OP_INIT_ELEM_STATUS: audit_what = "Rr"; break; } while (*audit_what) switch (*audit_what++) { case 'D': /* DATA agent provided */ if (job->data_agent.conn_type == NDMCONN_TYPE_NONE) ERROR("missing DATA agent") break; case 'T': /* TAPE agent provided (use DATA if given) */ if (job->data_agent.conn_type == NDMCONN_TYPE_NONE && job->tape_agent.conn_type == NDMCONN_TYPE_NONE) ERROR("missing TAPE or DATA agent") break; case 'R': /* ROBOT agent provided (use TAPE or DATA if given) */ if (job->data_agent.conn_type == NDMCONN_TYPE_NONE && job->tape_agent.conn_type == NDMCONN_TYPE_NONE && job->robot_agent.conn_type == NDMCONN_TYPE_NONE) ERROR("missing ROBOT, TAPE or DATA agent") break; case 'B': /* Backup type */ if (!job->bu_type) ERROR("missing bu_type") break; case 'b': /* block (record) size */ if (!job->record_size) ERROR("missing record size") break; case 'f': /* tape file */ if (!job->tape_device) ERROR("missing tape device") break; case 'm': /* media entry/ies */ if (job->media_tab.n_media < 1) ERROR("missing media entry") break; case 'M': /* ? */ errcnt += ndma_job_media_audit (job, errbuf, errskip-errcnt); break; case 'r': /* robot file/device name */ if (!job->have_robot) ERROR ("missing robot SCSI address"); break; case '@': /* from and/or to address */ if (job->operation == NDM_JOB_OP_MOVE_TAPE || job->operation == NDM_JOB_OP_EXPORT_TAPE || job->operation == NDM_JOB_OP_LOAD_TAPE) { if (!job->from_addr_given) ERROR ("missing 'from' slot address"); } if (job->operation == NDM_JOB_OP_MOVE_TAPE || job->operation == NDM_JOB_OP_IMPORT_TAPE) { if (!job->to_addr_given) ERROR ("missing 'to' slot address"); } break; default: ERROR ("INTERNAL BOTCH") return -2; } if (job->robot_agent.conn_type != NDMCONN_TYPE_NONE && !job->have_robot && job->operation != NDM_JOB_OP_QUERY_AGENTS) { ERROR ("robot agent, but no robot") } return errcnt; } int ndma_job_media_audit (struct ndm_job_param *job, char *errbuf, int errskip) { struct ndm_media_table *mtab = &job->media_tab; int n_media = mtab->n_media; struct ndmmedia * me; struct ndmmedia * me2; int errcnt = 0; if (job->have_robot) { for (me = mtab->head; me; me = me->next) { if (!me->valid_slot) { if (errbuf) { sprintf (errbuf, "media #%d missing slot address", me->index); } RETERR continue; } for (me2 = me->next; me2; me2 = me2->next) { if (! me2->valid_slot) continue; if (me->slot_addr == me2->slot_addr) { if (errbuf) { sprintf (errbuf, "media #%d dup slot addr w/ #%d", me->index, me2->index); } RETERR } } } } else { if (n_media > 1) { ERROR ("no robot, too many media") } for (me = mtab->head; me; me = me->next) { if (me->valid_slot) { if (errbuf) { sprintf (errbuf, "media #%d slot address, but no robot", me->index); } RETERR } } } if (job->operation == NDM_JOB_OP_INIT_LABELS) { for (me = mtab->head; me; me = me->next) { if (! me->valid_label) { if (errbuf) { sprintf (errbuf, "media #%d missing label", me->index); } RETERR } } } return 0; } void ndma_job_auto_adjust (struct ndm_job_param *job) { struct ndmmedia * me; if (job->media_tab.n_media == 0 && !job->have_robot && job->operation != NDM_JOB_OP_INIT_LABELS) { /* synthesize one media table entry */ me = ndma_store_media (&job->media_tab, 0); if (me) { /* As this is a fake media entry set valid_slot to 0 */ me->valid_slot = 0; } } } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_comm_session.c000066400000000000000000000305711263011562700220340ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndma_client_session (struct ndm_session *sess, struct ndm_job_param *job, int swap_connect) { int rc; rc = ndma_job_audit (job, 0, 0); if (rc) return -1; /* * Old behaviour enable all agents. */ sess->control_agent_enabled = 1; sess->data_agent_enabled = 1; sess->tape_agent_enabled = 1; sess->robot_agent_enabled = 1; /* * Old behaviour enable session snooping */ sess->conn_snooping = 1; /* * Old behaviour enable media info dumping. */ sess->dump_media_info = 1; rc = ndma_session_initialize (sess); if (rc) return rc; memcpy (&sess->control_acb->job, job, sizeof(struct ndm_job_param )); sess->control_acb->swap_connect = swap_connect; rc = ndma_session_commission (sess); if (rc) return rc; rc = ndmca_connect_control_agent (sess); if (rc) return rc; /* already tattled */ sess->conn_open = 1; sess->conn_authorized = 1; rc = ndmca_control_agent (sess); ndma_session_decommission (sess); ndma_session_destroy (sess); return rc; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS int ndma_server_session (struct ndm_session *sess, int control_sock) { struct ndmconn * conn; int rc; struct sockaddr sa; socklen_t len; /* * Old behaviour enable all agents. */ sess->control_agent_enabled = 1; sess->data_agent_enabled = 1; sess->tape_agent_enabled = 1; sess->robot_agent_enabled = 1; /* * Old behaviour enable session snooping */ sess->conn_snooping = 1; /* * Old behaviour enable media info dumping. */ sess->dump_media_info = 1; rc = ndma_session_initialize (sess); if (rc) return rc; rc = ndma_session_commission (sess); if (rc) return rc; len = sizeof sa; rc = getpeername (control_sock, &sa, &len); if (rc < 0) { perror ("getpeername"); } else { char ip_addr[100]; ndmalogf (sess, 0, 2, "Connection accepted from %s", inet_ntop ( AF_INET, &(((struct sockaddr_in *)&sa)->sin_addr), ip_addr, sizeof(ip_addr))); } len = sizeof sa; rc = getsockname (control_sock, &sa, &len); if (rc < 0) { perror ("getsockname"); } else { char ip_addr[100]; ndmalogf (sess, 0, 2, "Connection accepted to %s", inet_ntop( AF_INET, &((struct sockaddr_in *)&sa)->sin_addr, ip_addr, sizeof(ip_addr))); } conn = ndmconn_initialize (0, "#C"); if (!conn) { ndmalogf (sess, 0, 0, "can't init connection"); close (control_sock); return -1; } ndmos_condition_control_socket (sess, control_sock); if (sess->conn_snooping) { ndmconn_set_snoop (conn, &sess->param->log, sess->param->log_level); } ndmconn_accept (conn, control_sock); conn->call = ndma_call; conn->context = sess; sess->plumb.control = conn; while (!conn->chan.eof) { ndma_session_quantum (sess, 1000); } #if 0 { char ip_addr[100]; ndmalogf (sess, 0, 2, "Connection close %s", inet_ntop( AF_INET, &((struct sockaddr_in *)&sa)->sin_addr, ip_addr, sizeof(ip_addr))); } #endif ndmconn_destruct (conn); ndma_session_decommission (sess); ndma_session_destroy (sess); return 0; } int ndma_daemon_session (struct ndm_session *sess, int port) { int listen_sock; int conn_sock, rc; socklen_t len; struct sockaddr sa; listen_sock = socket (AF_INET, SOCK_STREAM, 0); if (listen_sock < 0) { perror ("socket"); return 1; } ndmos_condition_listen_socket (sess, listen_sock); NDMOS_MACRO_SET_SOCKADDR(&sa, 0, port); if (bind (listen_sock, &sa, sizeof sa) < 0) { perror ("bind"); close(listen_sock); return 2; } if (listen (listen_sock, 1) < 0) { perror ("listen"); close(listen_sock); return 3; } for (;;) { len = sizeof sa; conn_sock = accept (listen_sock, &sa, &len); if (conn_sock < 0) { perror ("accept"); close(listen_sock); return 4; } rc = fork(); if (rc < 0) { perror ("fork"); close(listen_sock); close(conn_sock); return 5; } if (rc == 0) { close (listen_sock); ndma_server_session (sess, conn_sock); exit (0); } close (conn_sock); } return 0; } #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */ int ndma_session_distribute_quantum (struct ndm_session *sess) { int total_did_something = 0; int did_something; do { did_something = 0; if (sess->plumb.image_stream) did_something |= ndmis_quantum (sess); #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (sess->tape_acb && sess->tape_acb->mover_state.state != NDMP9_MOVER_STATE_IDLE) did_something |= ndmta_quantum (sess); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT if (sess->data_acb && sess->data_acb->data_state.state != NDMP9_DATA_STATE_IDLE) did_something |= ndmda_quantum (sess); #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ total_did_something |= did_something; } while (did_something); return total_did_something; } int ndma_session_quantum (struct ndm_session *sess, int max_delay_secs) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmconn * conn; struct ndmconn * conntab[5]; int n_conntab; struct ndmchan * chtab[16]; int n_chtab; int i; int max_delay_usec = max_delay_secs * 1000; /* * Gather distinct connections */ n_conntab = 0; if ((conn = sess->plumb.control)) conntab[n_conntab++] = conn; if ( (conn = sess->plumb.data) && conn != sess->plumb.control) conntab[n_conntab++] = conn; if ( (conn = sess->plumb.tape) && conn != sess->plumb.data && conn != sess->plumb.control) conntab[n_conntab++] = conn; if ( (conn = sess->plumb.robot) && conn != sess->plumb.tape && conn != sess->plumb.data && conn != sess->plumb.control) conntab[n_conntab++] = conn; /* * Add connections to channel table */ n_chtab = 0; for (i = 0; i < n_conntab; i++) { conn = conntab[i]; chtab[n_chtab++] = &conn->chan; } #ifndef NDMOS_OPTION_NO_DATA_AGENT /* * Add DATA AGENT channels to table if active (!IDLE) */ if (sess->data_acb && sess->data_acb->data_state.state != NDMP9_DATA_STATE_IDLE) { chtab[n_chtab++] = &sess->data_acb->formatter_image; chtab[n_chtab++] = &sess->data_acb->formatter_error; chtab[n_chtab++] = &sess->data_acb->formatter_wrap; } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ /* * Add image stream to channel table */ if (is && is->remote.connect_status == NDMIS_CONN_LISTEN) { chtab[n_chtab++] = &is->remote.listen_chan; } if (is) { chtab[n_chtab++] = &is->chan; } /* * Let TAPE and DATA AGENTS get a bit of work done. * This fills channel buffers as much as possible prior to blocking. */ if (ndma_session_distribute_quantum (sess)) max_delay_usec = 0; #if 0 #ifndef NDMOS_OPTION_NO_DATA_AGENT /* bogus */ if (sess->data_acb && sess->data_acb->data_state.state == NDMP9_DATA_STATE_ACTIVE && sess->data_acb->data_state.data_connection_addr.addr_type == NDMP9_ADDR_LOCAL) { /* * There is no remote connection to cue forward * progress between local DATA/MOVER. * So, sniff all the connections, and immediately * attempt the next tape record. */ max_delay_usec = 0; } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #endif /* * Block awaiting ready I/O. Many channel buffers * will have actual I/O (read/write) performed. */ ndmchan_quantum (chtab, n_chtab, max_delay_usec); /* * Tattle for debug */ if (sess->param->log_level > 7) { for (i = 0; i < n_chtab; i++) { struct ndmchan * ch = chtab[i]; char buf[80]; ndmchan_pp (ch, buf); ndmalogf (sess, 0, 7, "ch %s", buf); } } /* * Let TAPE and DATA AGENTS get a bit more work done. * This will mostly digest whatever data just arrived. */ ndma_session_distribute_quantum (sess); /* * Dispatch any pending activity on the control connections */ for (i = 0; i < n_conntab; i++) { conn = conntab[i]; if (conn->chan.ready) { conn->chan.ready = 0; ndma_dispatch_conn (sess, conn); } } return 0; } int ndma_session_initialize (struct ndm_session *sess) { #ifndef NDMOS_OPTION_NO_CONTROL_AGENT if (sess->control_agent_enabled && ndmca_initialize (sess)) return -1; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT if (sess->data_agent_enabled && ndmda_initialize (sess)) return -1; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (sess->tape_agent_enabled && ndmta_initialize (sess)) return -1; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT if (sess->robot_agent_enabled && ndmra_initialize (sess)) return -1; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ return 0; } int ndma_session_commission (struct ndm_session *sess) { #ifndef NDMOS_OPTION_NO_CONTROL_AGENT if (sess->control_agent_enabled && ndmca_commission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT if (sess->data_agent_enabled && ndmda_commission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (sess->tape_agent_enabled && ndmta_commission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT if (sess->robot_agent_enabled && ndmra_commission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ return 0; } int ndma_session_decommission (struct ndm_session *sess) { #ifndef NDMOS_OPTION_NO_CONTROL_AGENT if (sess->control_agent_enabled && ndmca_decommission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT if (sess->data_agent_enabled && ndmda_decommission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (sess->tape_agent_enabled && ndmta_decommission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT if (sess->robot_agent_enabled && ndmra_decommission (sess)) return -1; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ return 0; } int ndma_session_destroy (struct ndm_session *sess) { if (sess->config_info) { NDMOS_API_FREE (sess->config_info); sess->config_info = NULL; } ndmis_destroy (sess); if (sess->plumb.control) { ndmconn_destruct (sess->plumb.control); sess->plumb.control = NULL; } if (sess->plumb.data) { ndmconn_destruct (sess->plumb.data); sess->plumb.data = NULL; } if (sess->plumb.tape) { ndmconn_destruct (sess->plumb.tape); sess->plumb.tape = NULL; } if (sess->plumb.robot) { ndmconn_destruct (sess->plumb.robot); sess->plumb.robot = NULL; } #ifndef NDMOS_OPTION_NO_CONTROL_AGENT if (sess->control_agent_enabled && ndmca_destroy (sess)) return -1; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT if (sess->data_agent_enabled && ndmda_destroy (sess)) return -1; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (sess->tape_agent_enabled && ndmta_destroy (sess)) return -1; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT if (sess->robot_agent_enabled && ndmra_destroy (sess)) return -1; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ return 0; } bareos-Release-14.2.6/src/ndmp/ndma_comm_subr.c000066400000000000000000000050661263011562700213250ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" void ndmalogf (struct ndm_session *sess, char *tag, int level, char *fmt, ...) { va_list ap; if (sess->param->log_level < level) return; if (!tag) tag = sess->param->log_tag; if (!tag) tag = "???"; va_start (ap, fmt); ndmlogfv (&sess->param->log, tag, level, fmt, ap); va_end (ap); } void ndmalogfv (struct ndm_session *sess, char *tag, int level, char *fmt, va_list ap) { if (sess->param->log_level < level) return; if (!tag) tag = sess->param->log_tag; if (!tag) tag = "???"; ndmlogfv (&sess->param->log, tag, level, fmt, ap); } #if 0 #ifndef NDMOS_OPTION_NO_NDMP2 char * ndma_log_dbg_tag (ndmp2_debug_level lev) { switch (lev) { case NDMP2_DBG_USER_INFO: return "ui"; case NDMP2_DBG_USER_SUMMARY: return "us"; case NDMP2_DBG_USER_DETAIL: return "ud"; case NDMP2_DBG_DIAG_INFO: return "di"; case NDMP2_DBG_DIAG_SUMMARY: return "ds"; case NDMP2_DBG_DIAG_DETAIL: return "dd"; case NDMP2_DBG_PROG_INFO: return "pi"; case NDMP2_DBG_PROG_SUMMARY: return "ps"; case NDMP2_DBG_PROG_DETAIL: return "pd"; default: return "??"; } } #endif /* !NDMOS_OPTION_NO_NDMP2 */ #endif bareos-Release-14.2.6/src/ndmp/ndma_control.c000066400000000000000000000106541263011562700210160ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * * CONTROL agent entry point. */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* Initialize -- Set data structure to know value, ignore current value */ int ndmca_initialize (struct ndm_session *sess) { sess->control_acb = NDMOS_API_MALLOC (sizeof(struct ndm_control_agent)); if (!sess->control_acb) { return -1; } NDMOS_MACRO_ZEROFILL (sess->control_acb); return 0; } /* Commission -- Get agent ready. Entire session has been initialize()d */ int ndmca_commission (struct ndm_session *sess) { return 0; } /* Decommission -- Discard agent */ int ndmca_decommission (struct ndm_session *sess) { return 0; } /* Decommission -- Discard agent */ int ndmca_destroy (struct ndm_session *sess) { if (!sess->control_acb) { return 0; } ndmca_destroy_media_table(&sess->control_acb->job.media_tab); ndmca_destroy_media_table(&sess->control_acb->job.result_media_tab); if (sess->control_acb->job.tape_target) { NDMOS_API_FREE (sess->control_acb->job.tape_target); } if (sess->control_acb->job.robot_target) { NDMOS_API_FREE (sess->control_acb->job.robot_target); } if (sess->control_acb->smc_cb) { NDMOS_API_FREE (sess->control_acb->smc_cb); } NDMOS_API_FREE (sess->control_acb); sess->control_acb = NULL; return 0; } int ndmca_control_agent (struct ndm_session *sess) { struct ndm_job_param * job = &sess->control_acb->job; int rc = -1; switch (job->operation) { default: ndmalogf (sess, 0, 0, "Job operation invalid"); break; case NDM_JOB_OP_INIT_LABELS: rc = ndmca_op_init_labels (sess); break; case NDM_JOB_OP_LIST_LABELS: rc = ndmca_op_list_labels (sess); break; case NDM_JOB_OP_BACKUP: rc = ndmca_op_create_backup (sess); break; case NDM_JOB_OP_EXTRACT: rc = ndmca_op_recover_files (sess); break; case NDM_JOB_OP_TOC: rc = ndmca_op_recover_fh (sess); break; case NDM_JOB_OP_REMEDY_ROBOT: rc = ndmca_op_robot_remedy (sess); break; case NDM_JOB_OP_QUERY_AGENTS: rc = ndmca_op_query (sess); break; case NDM_JOB_OP_TEST_TAPE: #ifndef NDMOS_OPTION_NO_TEST_AGENTS rc = ndmca_op_test_tape (sess); #endif break; case NDM_JOB_OP_TEST_MOVER: #ifndef NDMOS_OPTION_NO_TEST_AGENTS rc = ndmca_op_test_mover (sess); #endif break; case NDM_JOB_OP_TEST_DATA: #ifndef NDMOS_OPTION_NO_TEST_AGENTS rc = ndmca_op_test_data (sess); #endif break; case NDM_JOB_OP_REWIND_TAPE: rc = ndmca_op_rewind_tape (sess); break; case NDM_JOB_OP_EJECT_TAPE: rc = ndmca_op_eject_tape (sess); break; case NDM_JOB_OP_MOVE_TAPE: rc = ndmca_op_move_tape (sess); break; case NDM_JOB_OP_LOAD_TAPE: rc = ndmca_op_load_tape (sess); break; case NDM_JOB_OP_UNLOAD_TAPE: rc = ndmca_op_unload_tape (sess); break; case NDM_JOB_OP_IMPORT_TAPE: rc = ndmca_op_import_tape (sess); break; case NDM_JOB_OP_EXPORT_TAPE: rc = ndmca_op_export_tape (sess); break; case NDM_JOB_OP_INIT_ELEM_STATUS: rc = ndmca_op_init_elem_status (sess); break; } return rc; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_cops_backreco.c000066400000000000000000000604261263011562700221350ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_monitor_backup_tape_tcp (struct ndm_session *sess); int ndmca_monitor_recover_tape_tcp (struct ndm_session *sess); int ndmca_monitor_shutdown_tape_tcp (struct ndm_session *sess); int ndmca_op_create_backup (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ca->tape_mode = NDMP9_TAPE_RDWR_MODE; ca->mover_mode = NDMP9_MOVER_MODE_READ; ca->is_label_op = 0; rc = ndmca_backreco_startup (sess); if (rc) return rc; rc = ndmca_data_start_backup (sess); if (rc == 0) { rc = ndmca_monitor_startup (sess); if (rc == 0) { rc = ndmca_monitor_backup (sess); } } if (rc == 0) rc = ndmca_monitor_shutdown (sess); else ndmca_monitor_shutdown (sess); ndmca_media_tattle (sess); return rc; } int ndmca_op_recover_files (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ca->tape_mode = NDMP9_TAPE_READ_MODE; ca->mover_mode = NDMP9_MOVER_MODE_WRITE; ca->is_label_op = 0; rc = ndmca_backreco_startup (sess); if (rc) return rc; rc = ndmca_data_start_recover (sess); if (rc == 0) { rc = ndmca_monitor_startup (sess); if (rc == 0) { rc = ndmca_monitor_recover (sess); } } if (rc == 0) rc = ndmca_monitor_shutdown (sess); else ndmca_monitor_shutdown (sess); if (rc == 0) { if (ca->recover_log_file_count > 0) { struct ndm_control_agent *ca = sess->control_acb; int n_nlist = ca->job.nlist_tab.n_nlist; ndmalogf (sess, 0, 0, "LOG_FILE messages: %d OK, %d ERROR, total %d of %d", ca->recover_log_file_ok, ca->recover_log_file_error, ca->recover_log_file_count, n_nlist); if (ca->recover_log_file_ok < n_nlist) { rc = 1; } } else { ndmalogf (sess, 0, 1, "DATA did not report any LOG_FILE messages"); } } if(!ca->job.tape_tcp) ndmca_media_tattle (sess); return rc; } int ndmca_op_recover_fh (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ca->tape_mode = NDMP9_TAPE_READ_MODE; ca->mover_mode = NDMP9_MOVER_MODE_WRITE; ca->is_label_op = 0; rc = ndmca_backreco_startup (sess); if (rc) return rc; rc = ndmca_data_start_recover_filehist (sess); if (rc == 0) { rc = ndmca_monitor_startup (sess); if (rc == 0) { rc = ndmca_monitor_recover (sess); } } if (rc == 0) rc = ndmca_monitor_shutdown (sess); else ndmca_monitor_shutdown (sess); ndmca_media_tattle (sess); return rc; } char *ndmca_data_est(struct ndm_control_agent *ca) { char *estb; static char estb_buf[64]; estb = 0; if (ca->data_state.est_bytes_remain.valid && (ca->data_state.est_bytes_remain.value >= 1024)) { snprintf(estb_buf, sizeof (estb_buf), " left %lldKB", ca->data_state.est_bytes_remain.value/1024LL); estb = estb_buf; } return estb; } int ndmca_monitor_backup (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int count; ndmp9_data_state ds; ndmp9_mover_state ms; char *estb; if (ca->job.tape_tcp) { return ndmca_monitor_backup_tape_tcp(sess); } ndmalogf (sess, 0, 3, "Monitoring backup"); for (count = 0; count < 10; count++) { ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10); if (ndmca_monitor_get_states(sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; ms = ca->mover_state.state; estb = ndmca_data_est(ca); ndmalogf (sess, 0, 1, "DATA: bytes %lldKB%s MOVER: written %lldKB record %d", ca->data_state.bytes_processed/1024LL, estb ? estb : "", ca->mover_state.bytes_moved/1024LL, ca->mover_state.record_num); ca->job.bytes_written = ca->data_state.bytes_processed; if (ds == NDMP9_DATA_STATE_ACTIVE && ms == NDMP9_MOVER_STATE_ACTIVE) { count = 0; continue; } /* * Check MOVER for needed tape change during DATA_FLOW_TO_TAPE. * Have to do this before checking DATA. Even if DATA halted, * MOVER may be holding unwritten data. Have to perform * the tape change. */ if (ms == NDMP9_MOVER_STATE_PAUSED) { ndmp9_mover_pause_reason pr; pr = ca->mover_state.pause_reason; if (!ca->pending_notify_mover_paused) { /* count=count */ continue; /* wait for notice */ } ca->pending_notify_mover_paused = 0; ndmalogf (sess, 0, 3, "Mover paused, reason=%s", ndmp9_mover_pause_reason_to_str (pr)); /* backups are different then recoverys... When * we reach the end of a window, we signal EOW * except in V2 where we signal EOF. EOM occurs * at EOT (or EOF does). * This is based on reading comments in the email * archives... */ if ((pr == NDMP9_MOVER_PAUSE_EOM) || (pr == NDMP9_MOVER_PAUSE_EOW)) { if (ndmca_monitor_load_next(sess) == 0) { /* count=count */ continue; /* Happy */ } /* Something went wrong with tape change. */ } else if ((sess->plumb.tape->protocol_version <= 2) && pr == NDMP9_MOVER_PAUSE_EOF) { if (ndmca_monitor_load_next(sess) == 0) { /* count=count */ continue; /* Happy */ } /* Something went wrong with tape change. */ } else { /* All other pause reasons * are critically bogus. */ } ndmalogf (sess, 0, 0, "Operation paused w/o remedy, cancelling"); ndmca_mover_abort (sess); return -1; } /* * If DATA has halted, the show is over. */ if (ds == NDMP9_DATA_STATE_HALTED) { if (ms != NDMP9_MOVER_STATE_HALTED) { ndmalogf (sess, 0, 3, "DATA halted, MOVER active"); /* * MOVER still occupied. It might be a * heartbeat away from asking for another * tape. Give it a chance. */ continue; } ndmalogf (sess, 0, 2, "Operation done, cleaning up"); ndmca_monitor_get_post_backup_env (sess); return 0; } #if 1 if (ms == NDMP9_MOVER_STATE_HALTED) { if (ds == NDMP9_DATA_STATE_ACTIVE) { ndmalogf (sess, 0, 3, "MOVER halted, DATA active"); /* * DATA still occupied. */ continue; } } #endif if (ms != NDMP9_MOVER_STATE_ACTIVE && count == 0) { /* Not active. Not paused. Something wrong */ ndmalogf (sess, 0, 0, "Operation in unreasonable state, cancelling"); return -1; } } ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling"); return -1; } int ndmca_monitor_backup_tape_tcp (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int count; ndmp9_data_state ds; char *estb; ndmalogf (sess, 0, 3, "Monitoring backup"); for (count = 0; count < 10; count++) { ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10); if (ndmca_monitor_get_states(sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; estb = ndmca_data_est(ca); ndmalogf (sess, 0, 1, "DATA: bytes %lldKB%s", ca->data_state.bytes_processed/1024LL, estb ? estb : ""); ca->job.bytes_written = ca->data_state.bytes_processed; if (ds == NDMP9_DATA_STATE_ACTIVE) { count = 0; continue; } /* * If DATA has halted, the show is over. */ if (ds == NDMP9_DATA_STATE_HALTED) { ndmalogf (sess, 0, 2, "Operation done, cleaning up"); ndmca_monitor_get_post_backup_env (sess); return 0; } } ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling"); return -1; } int ndmca_monitor_get_post_backup_env (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndmlog * ixlog = &ca->job.index_log; struct ndm_env_entry * entry; int rc; rc = ndmca_data_get_env (sess); if (rc && ca->data_state.error == NDMP9_ILLEGAL_STATE_ERR) { ndmalogf (sess, 0, 2, "fetch post backup env failed"); return 0; } if (rc) { ndmalogf (sess, 0, 0, "fetch post backup env failed"); return -1; } /* * Only print the data when a deliver function was defined. */ if (ixlog->deliver) { for (entry = ca->job.result_env_tab.head; entry; entry = entry->next) { ndmlogf (ixlog, "DE", 0, "%s=%s", entry->pval.name, entry->pval.value); } } return 0; } int ndmca_monitor_recover (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int count, rc; ndmp9_data_state ds; ndmp9_mover_state ms; char *estb; int last_state_print = 0; if (ca->job.tape_tcp) { return (ndmca_monitor_recover_tape_tcp(sess)); } ndmalogf (sess, 0, 3, "Monitoring recover"); for (count = 0; count < 10; count++) { if (ca->pending_notify_data_read) { ca->pending_notify_data_read = 0; rc = ndmca_mover_read (sess, ca->last_notify_data_read.offset, ca->last_notify_data_read.length); if (rc) { ndmalogf (sess, 0, 0, "data-read failed"); return -1; } if (count < 5) continue; } ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10); if (ndmca_monitor_get_states(sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; ms = ca->mover_state.state; estb = ndmca_data_est(ca); if ((ds != NDMP9_DATA_STATE_ACTIVE) || (ms != NDMP9_MOVER_STATE_ACTIVE) || ((time(0) - last_state_print) >= 5)) { ndmalogf (sess, 0, 1, "DATA: bytes %lldKB%s MOVER: read %lldKB record %d", ca->data_state.bytes_processed/1024LL, estb ? estb : "", ca->mover_state.bytes_moved/1024LL, ca->mover_state.record_num); last_state_print = time(0); } ca->job.bytes_read = ca->data_state.bytes_processed; if (ds == NDMP9_DATA_STATE_ACTIVE && ms == NDMP9_MOVER_STATE_ACTIVE) { count = 0; continue; } /* * Check MOVER for needed tape change during DATA_FLOW_TO_TAPE. * Have to do this before checking DATA. Even if DATA halted, * MOVER may be holding unwritten data. Have to perform * the tape change. */ if (ms == NDMP9_MOVER_STATE_PAUSED) { ndmp9_mover_pause_reason pr; pr = ca->mover_state.pause_reason; if (!ca->pending_notify_mover_paused) { /* count=count */ continue; /* wait for notice */ } ca->pending_notify_mover_paused = 0; ndmalogf (sess, 0, 3, "Mover paused, reason=%s", ndmp9_mover_pause_reason_to_str (pr)); if (((pr == NDMP9_MOVER_PAUSE_EOF) || (pr == NDMP9_MOVER_PAUSE_SEEK)) && (ca->cur_media_ix == ca->job.media_tab.n_media)) { /* * Last tape consumed by tape agent. * The DATA agent may be just shy * of done, but there is no way for * us to tell. So, close the * image stream from the TAPE * agent side, thus indicating * EOF to the DATA agent. */ ndmalogf (sess, 0, 2, "End of tapes"); ndmca_mover_close (sess); /* count=count */ continue; } if (pr == NDMP9_MOVER_PAUSE_EOM || pr == NDMP9_MOVER_PAUSE_EOF) { if (ndmca_monitor_load_next(sess) == 0) { /* count=count */ continue; /* Happy */ } /* Something went wrong with tape change. */ } else if (pr == NDMP9_MOVER_PAUSE_SEEK) { if (ndmca_monitor_seek_tape(sess) == 0) { /* count=count */ continue; /* Happy */ } /* Something went wrong with tape change. */ } else { /* All other pause reasons * are critically bogus. */ } ndmalogf (sess, 0, 0, "Operation paused w/o remedy, cancelling"); ndmca_mover_abort (sess); return -1; } /* * If DATA has halted, the show is over. */ if (ds == NDMP9_DATA_STATE_HALTED) { if (ms != NDMP9_MOVER_STATE_HALTED) { ndmalogf (sess, 0, 3, "DATA halted, MOVER active"); /* * MOVER still occupied. It might * figure it out. Then again, it might * be awaiting a MOVER_READ. The NDMP * design does not provide a state * for awaiting MOVER_READ, so we have * to guess. */ if (count > 0) { ndmca_mover_close(sess); } continue; } ndmalogf (sess, 0, 2, "Operation done, cleaning up"); return 0; } if (ms != NDMP9_MOVER_STATE_ACTIVE && count == 0) { /* Not active. Not paused. Something wrong */ ndmalogf (sess, 0, 0, "Operation in unreasonable state, cancelling"); return -1; } } ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling"); return -1; } int ndmca_monitor_recover_tape_tcp (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int count; ndmp9_data_state ds; char *estb; int last_state_print = 0; ndmalogf (sess, 0, 3, "Monitoring recover"); for (count = 0; count < 10; count++) { ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10); if (ndmca_monitor_get_states(sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; estb = ndmca_data_est(ca); if ((ds != NDMP9_DATA_STATE_ACTIVE) || ((time(0) - last_state_print) >= 5)) { ndmalogf (sess, 0, 1, "DATA: bytes %lldKB%s MOVER: read %lldKB record %d", ca->data_state.bytes_processed/1024LL, estb ? estb : "", ca->mover_state.bytes_moved/1024LL, ca->mover_state.record_num); last_state_print = time(0); } ca->job.bytes_read = ca->data_state.bytes_processed; if (ds == NDMP9_DATA_STATE_ACTIVE) { count = 0; continue; } /* * If DATA has halted, the show is over. */ if (ds == NDMP9_DATA_STATE_HALTED) { ndmalogf (sess, 0, 2, "Operation done, cleaning up"); ndmca_monitor_get_post_backup_env (sess); return 0; } } ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling"); return -1; } int ndmca_backreco_startup (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc = 0; if (!ca->job.tape_tcp) rc = ndmca_op_robot_startup (sess, 1); if (rc) return rc; rc = ndmca_connect_data_agent(sess); if (rc) { ndmconn_destruct (sess->plumb.data); sess->plumb.data = NULL; return rc; } if (ca->job.tape_tcp) { return 0; } rc = ndmca_connect_tape_agent(sess); if (rc) { ndmconn_destruct (sess->plumb.tape); sess->plumb.tape = NULL; return rc; } rc = ndmca_mover_set_record_size (sess); if (rc) return rc; rc = ndmca_media_load_first (sess); if (rc) return rc; ndmca_media_calculate_offsets (sess); if (sess->control_acb->swap_connect && (sess->plumb.tape->protocol_version >= 3)) { if (sess->plumb.tape->protocol_version < 4) { rc = ndmca_data_listen (sess); if (rc) return rc; rc = ndmca_media_set_window_current (sess); if (rc) return rc; } else { rc = ndmca_media_set_window_current (sess); if (rc) return rc; rc = ndmca_data_listen (sess); if (rc) return rc; } } else { if (sess->plumb.tape->protocol_version < 4) { rc = ndmca_mover_listen (sess); if (rc) return rc; rc = ndmca_media_set_window_current (sess); if (rc) return rc; } else { rc = ndmca_media_set_window_current (sess); if (rc) return rc; rc = ndmca_mover_listen (sess); if (rc) return rc; } } return 0; } int ndmca_monitor_startup (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; ndmp9_data_state ds; ndmp9_mover_state ms; int count; ndmalogf (sess, 0, 3, "Waiting for operation to start"); if (ca->job.tape_tcp) return 0; for (count = 0; count < 10; count++) { if (ndmca_monitor_get_states (sess) < 0) break; ds = ca->data_state.state; if (!ca->job.tape_tcp) ms = ca->mover_state.state; else ms = NDMP9_MOVER_STATE_ACTIVE; if (ds == NDMP9_DATA_STATE_ACTIVE && ms == NDMP9_MOVER_STATE_ACTIVE) { ndmalogf (sess, 0, 1, "Operation started"); return 0; } if (ds == NDMP9_DATA_STATE_HALTED && ms == NDMP9_MOVER_STATE_HALTED) { /* operation finished immediately */ return 0; } if (ds != NDMP9_DATA_STATE_IDLE && ms != NDMP9_MOVER_STATE_IDLE && ms != NDMP9_MOVER_STATE_LISTEN) { ndmalogf (sess, 0, 1, "Operation started in unusual fashion"); return 0; } ndmca_mon_wait_for_something (sess, 2); } ndmalogf (sess, 0, 0, "Operation failed to start"); return -1; } /* * Just make sure things get finished */ int ndmca_monitor_shutdown (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; ndmp9_data_state ds; ndmp9_data_halt_reason dhr; ndmp9_mover_state ms; ndmp9_mover_halt_reason mhr; int count; int finish; if (ca->job.tape_tcp) { return ndmca_monitor_shutdown_tape_tcp(sess); } ndmalogf (sess, 0, 3, "Waiting for operation to halt"); for (count = 0; count < 10; count++) { ndmca_mon_wait_for_something (sess, 2); if (ndmca_monitor_get_states (sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; ms = ca->mover_state.state; if (ds == NDMP9_DATA_STATE_HALTED && ms == NDMP9_MOVER_STATE_HALTED) { dhr = ca->data_state.halt_reason; mhr = ca->mover_state.halt_reason; break; } if (count > 2) { if (ds != NDMP9_DATA_STATE_HALTED) ndmca_data_abort(sess); if (ms != NDMP9_MOVER_STATE_HALTED) ndmca_mover_abort(sess); } } if (ca->tape_state.error == NDMP9_NO_ERR) { ndmca_monitor_unload_last_tape (sess); } if (count >= 10) { ndmalogf (sess, 0, 0, "Operation did not halt, something wrong"); } ndmalogf (sess, 0, 2, "Operation halted, stopping"); ds = ca->data_state.state; ms = ca->mover_state.state; dhr = ca->data_state.halt_reason; mhr = ca->mover_state.halt_reason; if ((ds == NDMP9_DATA_STATE_HALTED) && (ms == NDMP9_MOVER_STATE_HALTED)) { if ((dhr == NDMP9_DATA_HALT_SUCCESSFUL) && (mhr == NDMP9_MOVER_HALT_CONNECT_CLOSED)) { /* Successful operation */ ndmalogf (sess, 0, 0, "Operation ended OKAY"); finish = 0; } else { /* Questionable success */ ndmalogf (sess, 0, 0, "Operation ended questionably"); finish = 1; } } else { ndmalogf (sess, 0, 0, "Operation ended in failure"); finish = -1; } ndmca_data_stop (sess); ndmca_mover_stop (sess); for (count = 0; count < 10; count++) { if (ndmca_monitor_get_states(sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; ms = ca->mover_state.state; if (ds == NDMP9_DATA_STATE_IDLE && ms == NDMP9_MOVER_STATE_IDLE) { break; } } if (count >= 10) { ndmalogf (sess, 0, 0, "Operation did not stop, something wrong"); return -1; } return finish; } int ndmca_monitor_shutdown_tape_tcp (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; ndmp9_data_state ds; ndmp9_data_halt_reason dhr; int count; int finish; ndmalogf (sess, 0, 3, "Waiting for operation to halt"); for (count = 0; count < 10; count++) { ndmca_mon_wait_for_something (sess, 2); if (ndmca_monitor_get_states (sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; if (ds == NDMP9_DATA_STATE_HALTED) { dhr = ca->data_state.halt_reason; break; } if (count > 2) { if (ds != NDMP9_DATA_STATE_HALTED) ndmca_data_abort(sess); } } if (count >= 10) { ndmalogf (sess, 0, 0, "Operation did not halt, something wrong"); } ndmalogf (sess, 0, 2, "Operation halted, stopping"); ds = ca->data_state.state; dhr = ca->data_state.halt_reason; if (ds == NDMP9_DATA_STATE_HALTED) { if (dhr == NDMP9_DATA_HALT_SUCCESSFUL) { /* Successful operation */ ndmalogf (sess, 0, 0, "Operation ended OKAY"); finish = 0; } else { /* Questionable success */ ndmalogf (sess, 0, 0, "Operation ended questionably"); finish = 1; } } else { ndmalogf (sess, 0, 0, "Operation ended in failure"); finish = -1; } ndmca_data_stop (sess); for (count = 0; count < 10; count++) { if (ndmca_monitor_get_states(sess) < 0) break; #if 0 if (count > 2) ndmca_mon_show_states(sess); #endif ds = ca->data_state.state; if (ds == NDMP9_DATA_STATE_IDLE) { break; } } if (count >= 10) { ndmalogf (sess, 0, 0, "Operation did not stop, something wrong"); return -1; } return finish; } int ndmca_monitor_get_states (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc = 0; if (ndmca_data_get_state (sess) < 0) rc = -1; if (!ca->job.tape_tcp) { if (ndmca_mover_get_state (sess) < 0) rc = -1; ndmca_tape_get_state_no_tattle (sess); } return rc; } int ndmca_monitor_load_next (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ndmalogf (sess, 0, 1, "Operation requires next tape"); ndmca_media_capture_mover_window (sess); ndmca_media_calculate_offsets (sess); if (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) { if (ca->mover_state.pause_reason != NDMP9_MOVER_PAUSE_EOM) ndmca_media_write_filemarks (sess); else ndmalogf (sess, 0, 1, "At EOM, not writing filemarks"); } rc = ndmca_media_unload_current(sess); if (rc) return rc; rc = ndmca_media_load_next(sess); if (rc) return rc; rc = ndmca_media_set_window_current (sess); if (rc) return rc; rc = ndmca_mover_continue(sess); if (rc) return rc; ndmalogf (sess, 0, 1, "Operation resuming"); return 0; } /* VERY VERY HARD */ int ndmca_monitor_seek_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; uint64_t pos; pos = ca->last_notify_mover_paused.seek_position; ndmalogf (sess, 0, 1, "Operation requires a different tape"); /* ndmca_media_capture_mover_window (sess); // !!! */ ndmca_media_calculate_offsets (sess); rc = ndmca_media_unload_current(sess); if (rc) return rc; rc = ndmca_media_load_seek (sess, pos); if (rc) return rc; rc = ndmca_media_set_window_current (sess); if (rc) return rc; rc = ndmca_mover_continue(sess); if (rc) return rc; ndmalogf (sess, 0, 1, "Operation resuming"); return 0; } int ndmca_monitor_unload_last_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; if (!ca->media_is_loaded) return 0; ndmca_media_capture_mover_window (sess); ndmca_media_calculate_offsets (sess); if (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) { ndmca_media_write_filemarks (sess); } rc = ndmca_media_unload_current(sess); if (rc) return rc; return 0; } int ndmca_mon_wait_for_something (struct ndm_session *sess, int max_delay_secs) { struct ndm_control_agent *ca = sess->control_acb; int delta, notices; int time_ref = time(0) + max_delay_secs; ndmalogf (sess, 0, 5, "mon_wait_for_something() entered"); for (;;) { delta = time_ref - time(0); if (delta <= 0) break; notices = 0; if (ca->pending_notify_data_read) { /* leave visible */ notices++; } if (ca->pending_notify_data_halted) { /* just used to "wake up" */ ca->pending_notify_data_halted = 0; notices++; } if (ca->pending_notify_mover_paused) { /* leave visible */ notices++; } if (ca->pending_notify_mover_halted) { /* just used to "wake up" */ ca->pending_notify_mover_halted = 0; notices++; } ndma_session_quantum (sess, notices ? 0 : delta); if (notices) break; } ndmalogf (sess, 0, 5, "mon_wait_for_something() happened, resid=%d", delta); return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_cops_labels.c000066400000000000000000000101541263011562700216170ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_op_init_labels (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndm_media_table *mtab = &job->media_tab; int n_media = mtab->n_media; struct ndmmedia * me; int rc, errors; ca->tape_mode = NDMP9_TAPE_RDWR_MODE; ca->is_label_op = 1; if (n_media <= 0) { ndmalogf (sess, 0, 0, "No media entries in table"); return -1; } errors = 0; for (me = mtab->head; me; me = me->next) { if (me->valid_label) continue; ndmalogf (sess, 0, 0, "media #%d missing a label", me->index); errors++; } if (errors) return -1; rc = ndmca_op_robot_startup (sess, 1); if (rc) return rc; /* already tattled */ rc = ndmca_connect_tape_agent (sess); if (rc) { ndmconn_destruct (sess->plumb.tape); sess->plumb.tape = NULL; return rc; /* already tattled */ } for (me = mtab->head; me; me = me->next) { ca->cur_media_ix = me->index; rc = ndmca_media_load_current (sess); if (rc) { /* already tattled */ continue; } rc = ndmca_media_write_label (sess, 'm', me->label); if (rc) { ndmalogf (sess, 0, 0, "failed label write"); } ndmca_media_write_filemarks (sess); ndmca_media_unload_current (sess); } return rc; } int ndmca_op_list_labels (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndm_media_table *mtab = &job->media_tab; int n_media; char labbuf[NDMMEDIA_LABEL_MAX]; char buf[200]; struct ndmmedia * me; int rc; ca->tape_mode = NDMP9_TAPE_READ_MODE; ca->is_label_op = 1; rc = ndmca_op_robot_startup (sess, 0); if (rc) return rc; /* already tattled */ if (job->media_tab.n_media == 0) { if (job->have_robot) { rc = ndmca_robot_synthesize_media (sess); if (rc) return rc; /* already tattled */ } else { /* * No fixup. Should be done by now. * See ndma_job_auto_adjust() */ } } if ((rc = ndmca_connect_tape_agent (sess)) != 0) { ndmconn_destruct (sess->plumb.tape); sess->plumb.tape = NULL; return rc; /* already tattled */ } n_media = mtab->n_media; for (me = mtab->head; me; me = me->next) { ca->cur_media_ix = me->index; rc = ndmca_media_load_current (sess); if (rc) { /* already tattled */ continue; } rc = ndmca_media_read_label (sess, labbuf); if (rc == 'm' || rc == 'V') { strcpy (me->label, labbuf); me->valid_label = 1; ndmmedia_to_str (me, buf); ndmalogf (sess, "ME", 0, "%s", buf); } else { ndmalogf (sess, 0, 0, "failed label read"); } ndmca_media_unload_current (sess); } return rc; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_cops_query.c000066400000000000000000000560141263011562700215270ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_op_query (struct ndm_session *sess) { ndmca_opq_data(sess); ndmca_opq_tape(sess); ndmca_opq_robot(sess); return 0; } int ndmca_opq_data (struct ndm_session *sess) { struct ndm_job_param * job = &sess->control_acb->job; int rc; if (job->data_agent.conn_type == NDMCONN_TYPE_NONE) return 0; rc = ndmca_connect_data_agent (sess); if (rc) { ndmconn_destruct (sess->plumb.data); sess->plumb.data = NULL; return rc; /* already tattled */ } ndmalogqr (sess, ""); ndmalogqr (sess, "Data Agent %s NDMPv%d", job->data_agent.host, sess->plumb.data->protocol_version); ndmca_opq_host_info (sess, sess->plumb.data); ndmca_opq_get_mover_type (sess, sess->plumb.data); ndmca_opq_get_butype_attr (sess, sess->plumb.data); #ifndef NDMOS_OPTION_NO_NDMP3 if (sess->plumb.data->protocol_version == NDMP3VER) { ndmca_opq_get_fs_info (sess, sess->plumb.data); } #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 if (sess->plumb.data->protocol_version == NDMP4VER) { ndmca_opq_get_fs_info (sess, sess->plumb.data); } #endif /* !NDMOS_OPTION_NO_NDMP4 */ return 0; } int ndmca_opq_tape (struct ndm_session *sess) { struct ndm_job_param * job = &sess->control_acb->job; int rc; if (job->tape_agent.conn_type == NDMCONN_TYPE_NONE) return 0; rc = ndmca_connect_tape_agent (sess); if (rc) { ndmconn_destruct (sess->plumb.tape); sess->plumb.data = NULL; return rc; /* already tattled */ } ndmalogqr (sess, ""); ndmalogqr (sess, "Tape Agent %s NDMPv%d", job->tape_agent.host, sess->plumb.tape->protocol_version); if (sess->plumb.tape != sess->plumb.data) { /* don't be boring */ ndmca_opq_host_info (sess, sess->plumb.tape); ndmca_opq_get_mover_type (sess, sess->plumb.tape); } #ifndef NDMOS_OPTION_NO_NDMP3 if (sess->plumb.tape->protocol_version == NDMP3VER) { ndmca_opq_get_tape_info (sess, sess->plumb.tape); } #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 if (sess->plumb.tape->protocol_version == NDMP4VER) { ndmca_opq_get_tape_info (sess, sess->plumb.tape); } #endif /* !NDMOS_OPTION_NO_NDMP4 */ return 0; } int ndmca_opq_robot (struct ndm_session *sess) { struct ndm_job_param * job = &sess->control_acb->job; int rc; if (job->robot_agent.conn_type == NDMCONN_TYPE_NONE && !job->have_robot) return 0; rc = ndmca_connect_robot_agent (sess); if (rc) return rc; /* already tattled */ ndmalogqr (sess, ""); ndmalogqr (sess, "Robot Agent %s NDMPv%d", job->robot_agent.host, sess->plumb.robot->protocol_version); if (sess->plumb.robot != sess->plumb.data && sess->plumb.robot != sess->plumb.tape) { /* don't be boring */ ndmca_opq_host_info (sess, sess->plumb.robot); } #ifndef NDMOS_OPTION_NO_NDMP3 if (sess->plumb.robot->protocol_version == NDMP3VER) { ndmca_opq_get_scsi_info (sess, sess->plumb.robot); } #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 if (sess->plumb.robot->protocol_version == NDMP4VER) { ndmca_opq_get_scsi_info (sess, sess->plumb.robot); } #endif /* !NDMOS_OPTION_NO_NDMP4 */ if (job->have_robot) { if (ndmca_robot_prep_target(sess)) { ndmalogqr (sess, " robot init failed"); return -1; } ndmca_robot_query (sess); } return 0; } int ndmca_opq_host_info (struct ndm_session *sess, struct ndmconn *conn) { int rc; int cnt; int out; unsigned int i; char buf[100]; switch (conn->protocol_version) { default: ndmalogqr (sess, " Host info NDMPv???? %d", conn->protocol_version); ndmalogqr (sess, " INTERNAL ERROR, CHECK BUILD"); break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH_VOID_REQUEST(ndmp2_config_get_host_info, NDMP2VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_host_info failed"); return rc; } ndmalogqr (sess, " Host info"); ndmalogqr (sess, " hostname %s", reply->hostname); ndmalogqr (sess, " os_type %s", reply->os_type); ndmalogqr (sess, " os_vers %s", reply->os_vers); ndmalogqr (sess, " hostid %s", reply->hostid); *buf = 0; out = 0; cnt = sizeof(buf) - 1; for (i = 0; i < reply->auth_type.auth_type_len; i++) { ndmp2_auth_type atyp; atyp = reply->auth_type.auth_type_val[i]; if (out) rc = snprintf(buf + out, cnt, " %s", ndmp2_auth_type_to_str (atyp)); else rc = snprintf(buf + out, cnt, "%s", ndmp2_auth_type_to_str (atyp)); out += rc; cnt -= rc; } buf[sizeof(buf) - 1] = '\0'; ndmalogqr (sess, " auths (%d) %s", reply->auth_type.auth_type_len, buf); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH_VOID_REQUEST(ndmp3_config_get_host_info, NDMP3VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_host_info failed"); return rc; } ndmalogqr (sess, " Host info"); ndmalogqr (sess, " hostname %s", reply->hostname); ndmalogqr (sess, " os_type %s", reply->os_type); ndmalogqr (sess, " os_vers %s", reply->os_vers); ndmalogqr (sess, " hostid %s", reply->hostid); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH NDMC_WITH_VOID_REQUEST(ndmp3_config_get_server_info, NDMP3VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_server_info failed"); return rc; } ndmalogqr (sess, " Server info"); ndmalogqr (sess, " vendor %s", reply->vendor_name); ndmalogqr (sess, " product %s", reply->product_name); ndmalogqr (sess, " revision %s", reply->revision_number); *buf = 0; out = 0; cnt = sizeof(buf) - 1; for (i = 0; i < reply->auth_type.auth_type_len; i++) { ndmp3_auth_type atyp; atyp = reply->auth_type.auth_type_val[i]; if (out) rc = snprintf(buf + out, cnt, " %s", ndmp3_auth_type_to_str (atyp)); else rc = snprintf(buf + out, cnt, "%s", ndmp3_auth_type_to_str (atyp)); out += rc; cnt -= rc; } buf[sizeof(buf) - 1] = '\0'; ndmalogqr (sess, " auths (%d) %s", reply->auth_type.auth_type_len, buf); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH_VOID_REQUEST(ndmp4_config_get_host_info, NDMP4VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_host_info failed"); return rc; } ndmalogqr (sess, " Host info"); ndmalogqr (sess, " hostname %s", reply->hostname); ndmalogqr (sess, " os_type %s", reply->os_type); ndmalogqr (sess, " os_vers %s", reply->os_vers); ndmalogqr (sess, " hostid %s", reply->hostid); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH NDMC_WITH_VOID_REQUEST(ndmp4_config_get_server_info, NDMP4VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_server_info failed"); return rc; } ndmalogqr (sess, " Server info"); ndmalogqr (sess, " vendor %s", reply->vendor_name); ndmalogqr (sess, " product %s", reply->product_name); ndmalogqr (sess, " revision %s", reply->revision_number); *buf = 0; out = 0; cnt = sizeof(buf) - 1; for (i = 0; i < reply->auth_type.auth_type_len; i++) { ndmp4_auth_type atyp; atyp = reply->auth_type.auth_type_val[i]; if (out) rc = snprintf(buf + out, cnt, " %s", ndmp4_auth_type_to_str (atyp)); else rc = snprintf(buf + out, cnt, "%s", ndmp4_auth_type_to_str (atyp)); out += rc; cnt -= rc; } buf[sizeof(buf) - 1] = '\0'; ndmalogqr (sess, " auths (%d) %s", reply->auth_type.auth_type_len, buf); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } int ndmca_opq_get_mover_type (struct ndm_session *sess, struct ndmconn *conn) { int rc; int cnt; int out; unsigned int i; char buf[100]; switch (conn->protocol_version) { default: /* already tattled in ndmca_opq_host_info() */ break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH_VOID_REQUEST(ndmp2_config_get_mover_type, NDMP2VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_mover_info failed"); return rc; } ndmalogqr (sess, " Mover types"); *buf = 0; out = 0; cnt = sizeof(buf) - 1; for (i = 0; i < reply->methods.methods_len; i++) { ndmp2_mover_addr_type val; val = reply->methods.methods_val[i]; if (out) rc = snprintf(buf + out, cnt, " %s", ndmp2_mover_addr_type_to_str (val)); else rc = snprintf(buf + out, cnt, "%s", ndmp2_mover_addr_type_to_str (val)); out += rc; cnt -= rc; } ndmalogqr (sess, " methods (%d) %s", reply->methods.methods_len, buf); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH_VOID_REQUEST(ndmp3_config_get_connection_type, NDMP3VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_connection_type failed"); return rc; } ndmalogqr (sess, " Connection types"); *buf = 0; out = 0; cnt = sizeof(buf) - 1; for (i = 0; i < reply->addr_types.addr_types_len; i++) { ndmp3_addr_type val; val = reply->addr_types.addr_types_val[i]; if (out) rc = snprintf(buf + out, cnt, " %s", ndmp3_addr_type_to_str (val)); else rc = snprintf(buf + out, cnt, "%s", ndmp3_addr_type_to_str (val)); out += rc; cnt -= rc; } ndmalogqr (sess, " addr_types (%d) %s", reply->addr_types.addr_types_len, buf); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH_VOID_REQUEST(ndmp4_config_get_connection_type, NDMP4VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, "get_connection_type failed"); return rc; } ndmalogqr (sess, " Connection types"); *buf = 0; out = 0; cnt = sizeof(buf) - 1; for (i = 0; i < reply->addr_types.addr_types_len; i++) { ndmp4_addr_type val; val = reply->addr_types.addr_types_val[i]; if (out) rc = snprintf(buf + out, cnt, " %s", ndmp4_addr_type_to_str (val)); else rc = snprintf(buf + out, cnt, "%s", ndmp4_addr_type_to_str (val)); out += rc; cnt -= rc; } ndmalogqr (sess, " addr_types (%d) %s", reply->addr_types.addr_types_len, buf); ndmalogqr (sess, ""); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } int ndmca_opq_get_butype_attr (struct ndm_session *sess, struct ndmconn *conn) { int rc; switch (conn->protocol_version) { default: /* already tattled in ndmca_opq_host_info() */ break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_config_get_butype_attr, NDMP2VER) request->name = sess->control_acb->job.bu_type; rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_butype_attr '%s' failed", sess->control_acb->job.bu_type); return rc; } ndmalogqr (sess, " Backup type attributes of %s format", sess->control_acb->job.bu_type); ndmalogqr (sess, " backup-filelist %s", (reply->attrs&NDMP2_NO_BACKUP_FILELIST) ? "no":"yes"); ndmalogqr (sess, " backup-fhinfo %s", (reply->attrs&NDMP2_NO_BACKUP_FHINFO) ? "no":"yes"); ndmalogqr (sess, " recover-filelist %s", (reply->attrs&NDMP2_NO_RECOVER_FILELIST) ? "no":"yes"); ndmalogqr (sess, " recover-fhinfo %s", (reply->attrs&NDMP2_NO_RECOVER_FHINFO) ? "no":"yes"); ndmalogqr (sess, " recover-inc-only %s", (reply->attrs&NDMP2_NO_RECOVER_INC_ONLY) ? "no":"yes"); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH_VOID_REQUEST(ndmp3_config_get_butype_info, NDMP3VER) unsigned int i, j; rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_butype_info failed"); return rc; } for (i = 0; i < reply->butype_info.butype_info_len; i++) { ndmp3_butype_info * buti; buti = &reply->butype_info.butype_info_val[i]; ndmalogqr (sess, " Backup type info of %s format", buti->butype_name); ndmalogqr (sess, " attrs 0x%lx", buti->attrs); ndmalogqr (sess, " backup-file-history %s", (buti->attrs&NDMP3_BUTYPE_BACKUP_FILE_HISTORY) ? "yes":"no"); ndmalogqr (sess, " backup-filelist %s", (buti->attrs&NDMP3_BUTYPE_BACKUP_FILELIST) ? "yes":"no"); ndmalogqr (sess, " recover-filelist %s", (buti->attrs&NDMP3_BUTYPE_RECOVER_FILELIST) ? "yes":"no"); ndmalogqr (sess, " backup-direct %s", (buti->attrs&NDMP3_BUTYPE_BACKUP_DIRECT) ? "yes":"no"); ndmalogqr (sess, " recover-direct %s", (buti->attrs&NDMP3_BUTYPE_RECOVER_DIRECT) ? "yes":"no"); ndmalogqr (sess, " backup-incremental %s", (buti->attrs&NDMP3_BUTYPE_BACKUP_INCREMENTAL) ? "yes":"no"); ndmalogqr (sess, " recover-incremental %s", (buti->attrs&NDMP3_BUTYPE_RECOVER_INCREMENTAL) ? "yes":"no"); ndmalogqr (sess, " backup-utf8 %s", (buti->attrs&NDMP3_BUTYPE_BACKUP_UTF8) ? "yes":"no"); ndmalogqr (sess, " recover-utf8 %s", (buti->attrs&NDMP3_BUTYPE_RECOVER_UTF8) ? "yes":"no"); ndmalogqr (sess, " recover-file-history %s", (buti->attrs&NDMP3_BUTYPE_RECOVER_FILE_HISTORY) ? "yes":"no"); for (j = 0; j < buti->default_env.default_env_len; j++) { ndmalogqr (sess, " set %s=%s", buti->default_env.default_env_val[j].name, buti->default_env.default_env_val[j].value); } if (j == 0) ndmalogqr (sess, " empty default env"); ndmalogqr (sess, ""); } if (i == 0) ndmalogqr (sess, " Empty backup type info"); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH_VOID_REQUEST(ndmp4_config_get_butype_info, NDMP4VER) unsigned int i, j; rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_butype_info failed"); return rc; } for (i = 0; i < reply->butype_info.butype_info_len; i++) { ndmp4_butype_info * buti; buti = &reply->butype_info.butype_info_val[i]; ndmalogqr (sess, " Backup type info of %s format", buti->butype_name); ndmalogqr (sess, " attrs 0x%lx", buti->attrs); for (j = 0; j < buti->default_env.default_env_len; j++) { ndmalogqr (sess, " set %s=%s", buti->default_env.default_env_val[j].name, buti->default_env.default_env_val[j].value); } if (j == 0) ndmalogqr (sess, " empty default env"); ndmalogqr (sess, ""); } if (i == 0) ndmalogqr (sess, " Empty backup type info"); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } #ifndef NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 int ndmca_opq_get_fs_info (struct ndm_session *sess, struct ndmconn *conn) { int rc; switch (conn->protocol_version) { default: /* already tattled in ndmca_opq_host_info() */ break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: break; /* why are we here? */ #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH_VOID_REQUEST(ndmp3_config_get_fs_info, NDMP3VER) unsigned int i, j; rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_fs_info failed"); return rc; } for (i = 0; i < reply->fs_info.fs_info_len; i++) { ndmp3_fs_info * fsi; fsi = &reply->fs_info.fs_info_val[i]; ndmalogqr (sess, " File system %s", fsi->fs_logical_device); ndmalogqr (sess, " physdev %s", fsi->fs_physical_device); ndmalogqr (sess, " invalid 0x%lx", fsi->invalid); if (fsi->invalid & NDMP3_FS_INFO_TOTAL_SIZE_INVALID) ndmalogqr (sess, " TOTAL_SIZE_INVALID"); if (fsi->invalid & NDMP3_FS_INFO_USED_SIZE_INVALID) ndmalogqr (sess, " USED_SIZE_INVALID"); if (fsi->invalid & NDMP3_FS_INFO_AVAIL_SIZE_INVALID) ndmalogqr (sess, " AVAIL_SIZE_INVALID"); if (fsi->invalid & NDMP3_FS_INFO_TOTAL_INODES_INVALID) ndmalogqr (sess, " TOTAL_INODES_INVALID"); if (fsi->invalid & NDMP3_FS_INFO_USED_INODES_INVALID) ndmalogqr (sess, " USED_INODES_INVALID"); ndmalogqr (sess, " type %s", fsi->fs_type); ndmalogqr (sess, " status %s", fsi->fs_status); ndmalogqr (sess, " space %lld total, %lld used, %lld avail", fsi->total_size, fsi->used_size, fsi->avail_size); ndmalogqr (sess, " inodes %lld total, %lld used", fsi->total_inodes, fsi->used_inodes); for (j = 0; j < fsi->fs_env.fs_env_len; j++) { ndmalogqr (sess, " set %s=%s", fsi->fs_env.fs_env_val[j].name, fsi->fs_env.fs_env_val[j].value); } if (j == 0) ndmalogqr (sess, " empty default env"); ndmalogqr (sess, ""); } if (i == 0) ndmalogqr (sess, " Empty fs info"); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH_VOID_REQUEST(ndmp4_config_get_fs_info, NDMP4VER) unsigned int i, j; rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_fs_info failed"); return rc; } for (i = 0; i < reply->fs_info.fs_info_len; i++) { ndmp4_fs_info * fsi; fsi = &reply->fs_info.fs_info_val[i]; ndmalogqr (sess, " File system %s", fsi->fs_logical_device); ndmalogqr (sess, " physdev %s", fsi->fs_physical_device); ndmalogqr (sess, " unsupported 0x%lx", fsi->unsupported); if (fsi->unsupported & NDMP4_FS_INFO_TOTAL_SIZE_UNS) ndmalogqr (sess, " TOTAL_SIZE_UNS"); if (fsi->unsupported & NDMP4_FS_INFO_USED_SIZE_UNS) ndmalogqr (sess, " USED_SIZE_UNS"); if (fsi->unsupported & NDMP4_FS_INFO_AVAIL_SIZE_UNS) ndmalogqr (sess, " AVAIL_SIZE_UNS"); if (fsi->unsupported & NDMP4_FS_INFO_TOTAL_INODES_UNS) ndmalogqr (sess, " TOTAL_INODES_UNS"); if (fsi->unsupported & NDMP4_FS_INFO_USED_INODES_UNS) ndmalogqr (sess, " USED_INODES_UNS"); ndmalogqr (sess, " type %s", fsi->fs_type); ndmalogqr (sess, " status %s", fsi->fs_status); ndmalogqr (sess, " space %lld total, %lld used, %lld avail", fsi->total_size, fsi->used_size, fsi->avail_size); ndmalogqr (sess, " inodes %lld total, %lld used", fsi->total_inodes, fsi->used_inodes); for (j = 0; j < fsi->fs_env.fs_env_len; j++) { ndmalogqr (sess, " set %s=%s", fsi->fs_env.fs_env_val[j].name, fsi->fs_env.fs_env_val[j].value); } if (j == 0) ndmalogqr (sess, " empty default env"); ndmalogqr (sess, ""); } if (i == 0) ndmalogqr (sess, " Empty fs info"); NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } int ndmca_opq_show_device_info (struct ndm_session *sess, ndmp9_device_info *info, unsigned n_info, char *what) { unsigned int i, j, k; for (i = 0; i < n_info; i++) { ndmalogqr (sess, " %s %s", what, info[i].model); for (j = 0; j < info[i].caplist.caplist_len; j++) { ndmp9_device_capability *dc; uint32_t attr; dc = &info[i].caplist.caplist_val[j]; ndmalogqr (sess, " device %s", dc->device); if (!strcmp(what, "tape")) { #ifndef NDMOS_OPTION_NO_NDMP3 if (sess->plumb.tape->protocol_version == 3) { attr = dc->v3attr.value; ndmalogqr (sess, " attr 0x%lx", attr); if (attr & NDMP3_TAPE_ATTR_REWIND) ndmalogqr (sess, " REWIND"); if (attr & NDMP3_TAPE_ATTR_UNLOAD) ndmalogqr (sess, " UNLOAD"); } #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 if (sess->plumb.tape->protocol_version == 4) { attr = dc->v4attr.value; ndmalogqr (sess, " attr 0x%lx", attr); if (attr & NDMP4_TAPE_ATTR_REWIND) ndmalogqr (sess, " REWIND"); if (attr & NDMP4_TAPE_ATTR_UNLOAD) ndmalogqr (sess, " UNLOAD"); } #endif /* !NDMOS_OPTION_NO_NDMP4 */ } for (k = 0; k < dc->capability.capability_len; k++) { ndmalogqr (sess, " set %s=%s", dc->capability.capability_val[k].name, dc->capability.capability_val[k].value); } if (k == 0) ndmalogqr (sess, " empty capabilities"); } if (j == 0) ndmalogqr (sess, " empty caplist"); ndmalogqr (sess, ""); } if (i == 0) ndmalogqr (sess, " Empty %s info", what); return 0; } int ndmca_opq_get_tape_info (struct ndm_session *sess, struct ndmconn *conn) { int rc; NDMC_WITH_VOID_REQUEST(ndmp9_config_get_tape_info, NDMP9VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_tape_info failed"); return rc; } ndmca_opq_show_device_info (sess, reply->config_info.tape_info.tape_info_val, reply->config_info.tape_info.tape_info_len, "tape"); NDMC_FREE_REPLY(); return 0; NDMC_ENDWITH } int ndmca_opq_get_scsi_info (struct ndm_session *sess, struct ndmconn *conn) { int rc; NDMC_WITH_VOID_REQUEST(ndmp9_config_get_scsi_info, NDMP9VER) rc = NDMC_CALL(conn); if (rc) { ndmalogqr (sess, " get_scsi_info failed"); return rc; } ndmca_opq_show_device_info (sess, reply->config_info.scsi_info.scsi_info_val, reply->config_info.scsi_info.scsi_info_len, "scsi"); NDMC_FREE_REPLY(); return 0; NDMC_ENDWITH } #endif /* !NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 */ void ndmalogqr (struct ndm_session *sess, char *fmt, ...) { va_list ap; va_start (ap, fmt); ndmalogfv (sess, "QR", 0, fmt, ap); va_end (ap); } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_cops_robot.c000066400000000000000000000244161263011562700215100ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_op_robot_remedy (struct ndm_session *sess) { struct ndm_job_param * job = &sess->control_acb->job; int rc; if (!job->have_robot) return 0; rc = ndmca_connect_robot_agent (sess); if (rc) return rc; /* already tattled */ rc = ndmca_robot_prep_target (sess); if (rc) return rc; /* already tattled */ rc = ndmca_robot_check_ready (sess); if (rc) { /* already tattled */ ndmalogf (sess, 0, 0, "Robot is not ready, trying to remedy"); rc = ndmca_robot_remedy_ready (sess); if (rc) { ndmalogf (sess, 0, 0, "Robot remedy failed"); return -1; } } return 0; } int ndmca_op_robot_startup (struct ndm_session *sess, int verify_media_flag) { struct ndm_job_param * job = &sess->control_acb->job; int rc; if (!job->have_robot) return 0; rc = ndmca_connect_robot_agent (sess); if (rc) return rc; /* already tattled */ rc = ndmca_robot_prep_target (sess); if (rc) return rc; /* already tattled */ rc = ndmca_robot_check_ready (sess); if (rc) { /* already tattled */ if (!job->auto_remedy) { ndmalogf (sess, 0, 0, "Robot is not ready, failing"); return -1; } ndmalogf (sess, 0, 0, "Robot is not ready, trying to remedy"); rc = ndmca_robot_remedy_ready (sess); if (rc) { ndmalogf (sess, 0, 0, "Robot remedy failed"); return -1; } } if (verify_media_flag) { rc = ndmca_media_verify (sess); if (rc) return rc; /* already tattled */ } return 0; } /* * ndmca_op_rewind_tape() and ndmca_op_eject_tape() really * belong somewhere else. Here because they are close * to the other "tape handling" operations. */ int ndmca_op_rewind_tape (struct ndm_session *sess) { return ndmca_op_mtio (sess, NDMP9_MTIO_REW); } int ndmca_op_eject_tape (struct ndm_session *sess) { return ndmca_op_mtio (sess, NDMP9_MTIO_OFF); } int ndmca_op_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op mtio_op) { struct ndm_control_agent *ca = sess->control_acb; int rc; ca->tape_mode = NDMP9_TAPE_READ_MODE; ca->is_label_op = 1; rc = ndmca_connect_tape_agent (sess); if (rc) { ndmconn_destruct (sess->plumb.tape); return rc; /* already tattled */ } rc = ndmca_media_open_tape (sess); if (rc) return rc; /* already tattled */ if (mtio_op == NDMP9_MTIO_OFF) { /* best-effort rewind */ ndmca_media_mtio_tape (sess, NDMP9_MTIO_REW, 1, 0); } rc = ndmca_media_mtio_tape (sess, mtio_op, 1, 0); if (rc) { /* best-effort close */ ndmca_media_close_tape (sess); return rc; /* already tattled */ } rc = ndmca_media_close_tape (sess); if (rc) return rc; /* already tattled */ return 0; } int ndmca_op_move_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; int src_addr = job->from_addr; int dst_addr = job->to_addr; int rc; /* repeat audits */ if (!job->to_addr_given || !job->from_addr_given) { ndmalogf (sess, 0, 0, "Missing to/from addr"); return -1; } rc = ndmca_robot_startup (sess); if (rc) return rc; /* already tattled -- NOT */ rc = ndmca_robot_obtain_info (sess); if (rc) return rc; /* already tattled -- NOT */ rc = ndmca_robot_move (sess, src_addr, dst_addr); if (rc) return rc; /* already tattled */ return 0; } int ndmca_op_import_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct smc_ctrl_block * smc = ca->smc_cb; int src_addr; int dst_addr = job->to_addr; int rc; /* repeat audits */ if (!job->to_addr_given) { ndmalogf (sess, 0, 0, "Missing to-addr"); return -1; } rc = ndmca_robot_startup (sess); if (rc) return rc; /* already tattled -- NOT */ rc = ndmca_robot_obtain_info (sess); if (rc) return rc; /* already tattled -- NOT */ if (smc->elem_aa.iee_count < 1) { ndmalogf (sess, 0, 0, "robot has no import/export; try move"); return -1; } src_addr = smc->elem_aa.iee_addr; rc = ndmca_robot_move (sess, src_addr, dst_addr); if (rc) return rc; /* already tattled */ return 0; } int ndmca_op_export_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct smc_ctrl_block * smc = ca->smc_cb; int src_addr = job->from_addr; int dst_addr; int rc; /* repeat audits */ if (!job->from_addr_given) { ndmalogf (sess, 0, 0, "Missing from-addr"); return -1; } rc = ndmca_robot_startup (sess); if (rc) return rc; /* already tattled -- NOT */ rc = ndmca_robot_obtain_info (sess); if (rc) return rc; /* already tattled -- NOT */ if (smc->elem_aa.iee_count < 1) { ndmalogf (sess, 0, 0, "robot has no import/export; try move"); return -1; } dst_addr = smc->elem_aa.iee_addr; rc = ndmca_robot_move (sess, src_addr, dst_addr); if (rc) return rc; /* already tattled */ return 0; } int ndmca_op_load_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct smc_ctrl_block * smc = ca->smc_cb; int src_addr = job->from_addr; int dst_addr; int rc; /* repeat audits */ if (!job->from_addr_given) { ndmalogf (sess, 0, 0, "Missing from-addr"); return -1; } rc = ndmca_robot_startup (sess); if (rc) return rc; /* already tattled -- NOT */ rc = ndmca_robot_obtain_info (sess); if (rc) return rc; /* already tattled -- NOT */ if (job->drive_addr_given) { dst_addr = job->drive_addr; } else if (smc->elem_aa.dte_count > 0) { dst_addr = smc->elem_aa.dte_addr; } else { ndmalogf (sess, 0, 0, "robot has no tape drives? try move"); return -1; } /* * Calculation for dst_addr repeated in ndmca_robot_load(). * We just did it to be sure it would succeed */ rc = ndmca_robot_load (sess, src_addr); if (rc) return rc; /* already tattled */ return 0; } int ndmca_op_unload_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct smc_ctrl_block * smc = ca->smc_cb; int src_addr = job->from_addr; int dst_addr; int rc; /* repeat audits */ rc = ndmca_robot_startup (sess); if (rc) return rc; /* already tattled -- NOT */ rc = ndmca_robot_obtain_info (sess); if (rc) return rc; /* already tattled -- NOT */ if (job->drive_addr_given) { src_addr = job->drive_addr; } else if (smc->elem_aa.dte_count > 0) { src_addr = smc->elem_aa.dte_addr; } else { ndmalogf (sess, 0, 0, "robot has no tape drives? try move"); return -1; } /* * Calculation for src_addr repeated in ndmca_robot_unload(). * We just did it to be sure it would succeed */ if (job->tape_device) { /* best effort */ rc = ndmca_op_mtio (sess, job->use_eject ? NDMP9_MTIO_OFF : NDMP9_MTIO_REW); if (rc) return rc; /* already tattled -- NOT */ } if (job->to_addr_given) { dst_addr = job->to_addr; } else { struct smc_element_descriptor * edp; struct smc_element_descriptor * edp2; char prefix[60]; /* * Try to automatically determine where to * put the tape, if there is one in the drive. * This is pretty much a rip-off of remedy_robot(). * The difference is here we believe the user * that something should happen. Otherwise, * the user would have used REMEDY_ROBOT. */ edp = ndmca_robot_find_element (sess, src_addr); if (!edp) { ndmalogf (sess, 0, 1, "no such slot @%d, trying unload anyway", src_addr); dst_addr = 0; /* g'luck! */ goto unload_anyway; } if (!edp->Full) { ndmalogf (sess, 0, 1, "drive @%d empty, trying unload anyway", src_addr); dst_addr = 0; /* g'luck! */ goto unload_anyway; } snprintf (prefix, sizeof(prefix), "drive @%d full", edp->element_address); if (!edp->SValid) { ndmalogf (sess, 0, 1, "%s, no SValid info, you must specify to-addr", prefix); return -1; } dst_addr = edp->src_se_addr; sprintf (NDMOS_API_STREND(prefix), ", src @%d", edp->src_se_addr); edp2 = ndmca_robot_find_element (sess, dst_addr); if (!edp2) { ndmalogf (sess, 0, 1, "%s, no such addr, trying unload anyway", prefix); goto unload_anyway; } if (edp2->element_type_code != SMC_ELEM_TYPE_SE) { ndmalogf (sess, 0, 1, "%s, not slot, trying unload anyway", prefix); goto unload_anyway; } if (edp2->Full) { ndmalogf (sess, 0, 1, "%s, slot Full, trying unload anyway", prefix); goto unload_anyway; } } unload_anyway: rc = ndmca_robot_unload (sess, dst_addr); if (rc) return rc; /* already tattled */ return 0; } int ndmca_op_init_elem_status (struct ndm_session *sess) { int rc; /* repeat audits */ rc = ndmca_robot_startup (sess); if (rc) return rc; /* already tattled -- NOT */ /* best-effort */ rc = ndmca_robot_obtain_info (sess); rc = ndmca_robot_init_elem_status (sess); if (rc) return rc; /* already tattled */ rc = ndmca_robot_query (sess); if (rc) return rc; /* already tattled -- WAY WAY tattled */ return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_ctrl_calls.c000066400000000000000000000336731263011562700214660ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* * DATA Agent calls **************************************************************** */ int ndmca_data_get_state (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; struct ndmp9_data_get_state_reply *state = &ca->data_state; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_data_get_state, NDMP9VER) rc = NDMC_CALL(conn); if (rc) { NDMOS_MACRO_ZEROFILL (state); ca->data_state.state = -1; } else { *state = *reply; } NDMC_ENDWITH return rc; } int ndmca_data_listen (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; int rc; NDMC_WITH(ndmp9_data_listen, NDMP9VER) if (sess->plumb.tape == sess->plumb.data) { request->addr_type = NDMP9_ADDR_LOCAL; } else { request->addr_type = NDMP9_ADDR_TCP; } rc = NDMC_CALL(conn); if (rc) return rc; if (request->addr_type != reply->data_connection_addr.addr_type) { ndmalogf (sess, 0, 0, "DATA_LISTEN addr_type mismatch"); return -1; } ca->data_addr = reply->data_connection_addr; NDMC_ENDWITH return 0; } int ndmca_data_connect (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; int rc; ndmp9_addr addr; if (ca->job.tape_tcp) { char *host; char *port; struct sockaddr_in sin; host = ca->job.tape_tcp; port = strchr(ca->job.tape_tcp, ':'); if (!port) { return 1; } *port++ = '\0'; rc = ndmhost_lookup(host, &sin); addr.addr_type = NDMP9_ADDR_TCP; addr.ndmp9_addr_u.tcp_addr.ip_addr = ntohl(sin.sin_addr.s_addr); addr.ndmp9_addr_u.tcp_addr.port = atoi(port); } else { addr = ca->mover_addr; } NDMC_WITH(ndmp9_data_connect, NDMP9VER) request->addr = addr; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_data_start_backup (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; unsigned n_env; ndmp9_pval * env; ndmp9_addr addr; int rc; if (conn->protocol_version > 2) { if (ca->swap_connect) { if ( (rc = ndmca_mover_connect (sess)) != 0) { return rc; } } else { if ( (rc = ndmca_data_connect (sess)) != 0) { return rc; } } addr.addr_type = NDMP9_ADDR_AS_CONNECTED; } else { addr = ca->mover_addr; } env = ndma_enumerate_env_list(&ca->job.env_tab); if (!env) { ndmalogf (sess, 0, 0, "Failed allocating enumerate buffer"); return -1; } n_env = ca->job.env_tab.n_env; NDMC_WITH(ndmp9_data_start_backup, NDMP9VER) request->addr = addr; request->bu_type = ca->job.bu_type; request->env.env_len = n_env; request->env.env_val = env; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_data_start_recover (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; unsigned n_env; ndmp9_pval * env; unsigned n_nlist; ndmp9_name * nlist; ndmp9_addr addr; int rc; if (conn->protocol_version > 2) { if (ca->swap_connect) { if ( (rc = ndmca_mover_connect (sess)) != 0) { return rc; } } else { if ( (rc = ndmca_data_connect (sess)) != 0) { return rc; } } addr.addr_type = NDMP9_ADDR_AS_CONNECTED; } else { addr = ca->mover_addr; } env = ndma_enumerate_env_list(&ca->job.env_tab); if (!env) { ndmalogf (sess, 0, 0, "Failed allocating enumerate buffer"); return -1; } n_env = ca->job.env_tab.n_env; nlist = ndma_enumerate_nlist(&ca->job.nlist_tab); n_nlist = ca->job.nlist_tab.n_nlist; NDMC_WITH(ndmp9_data_start_recover, NDMP9VER) request->addr = addr; request->bu_type = ca->job.bu_type; request->env.env_len = n_env; request->env.env_val = env; request->nlist.nlist_len = n_nlist; request->nlist.nlist_val = nlist; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_data_start_recover_filehist (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; unsigned n_env; ndmp9_pval * env; unsigned n_nlist; ndmp9_name * nlist; ndmp9_addr addr; int rc; if (conn->protocol_version > 2) { if (ca->swap_connect) { if ( (rc = ndmca_mover_connect (sess)) != 0) { return rc; } } else { if ( (rc = ndmca_data_connect (sess)) != 0) { return rc; } } addr.addr_type = NDMP9_ADDR_AS_CONNECTED; } else { addr = ca->mover_addr; } env = ndma_enumerate_env_list(&ca->job.env_tab); if (!env) { ndmalogf (sess, 0, 0, "Failed allocating enumerate buffer"); return -1; } n_env = ca->job.env_tab.n_env; nlist = ndma_enumerate_nlist(&ca->job.nlist_tab); n_nlist = ca->job.nlist_tab.n_nlist; NDMC_WITH(ndmp9_data_start_recover_filehist, NDMP9VER) request->addr = addr; request->bu_type = ca->job.bu_type; request->env.env_len = n_env; request->env.env_val = env; request->nlist.nlist_len = n_nlist; request->nlist.nlist_val = nlist; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_data_abort (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_data_abort, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_data_get_env (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; int rc; unsigned int i; NDMC_WITH_VOID_REQUEST(ndmp9_data_get_env, NDMP9VER) rc = NDMC_CALL(conn); if (rc) return rc; for (i = 0; i < reply->env.env_len; i++) { ndma_store_env_list (&ca->job.result_env_tab, &reply->env.env_val[i]); } NDMC_FREE_REPLY(); NDMC_ENDWITH return rc; } int ndmca_data_stop (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.data; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_data_stop, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } /* * TAPE Agent calls -- TAPE **************************************************************** */ int ndmca_tape_open (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; NDMC_WITH (ndmp9_tape_open, NDMP9VER) request->device = ca->job.tape_device; request->mode = ca->tape_mode; rc = NDMC_CALL(conn); ca->tape_state.error = reply->error; NDMC_ENDWITH return rc; } int ndmca_tape_close (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_tape_close, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_tape_get_state (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; struct ndmp9_tape_get_state_reply *state = &ca->tape_state; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER) rc = NDMC_CALL(conn); if (rc) { NDMOS_MACRO_ZEROFILL (state); /* tape_state.state = -1; */ state->error = reply->error; } else { *state = *reply; } NDMC_ENDWITH return rc; } int ndmca_tape_get_state_no_tattle (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; struct ndmp9_tape_get_state_reply *state = &ca->tape_state; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER) rc = ndma_call_no_tattle (conn, xa); if (rc) { NDMOS_MACRO_ZEROFILL (state); /* tape_state.state = -1; */ } else { *state = *reply; } if (rc < 0 || (reply->error != NDMP9_DEV_NOT_OPEN_ERR && reply->error != NDMP9_NO_ERR)) ndma_tattle (sess->plumb.tape, xa, rc); NDMC_ENDWITH return rc; } int ndmca_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH(ndmp9_tape_mtio, NDMP9VER) request->tape_op = op; request->count = count; rc = NDMC_CALL(conn); if (!rc) { if (resid) { *resid = reply->resid_count; } else if (reply->resid_count != 0) { return -1; } } NDMC_ENDWITH return rc; } int ndmca_tape_write (struct ndm_session *sess, char *buf, unsigned count) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH(ndmp9_tape_write, NDMP9VER) request->data_out.data_out_len = count; request->data_out.data_out_val = buf; rc = NDMC_CALL(conn); if (rc == 0) { if (reply->count != count) rc = -1; } NDMC_ENDWITH return rc; } int ndmca_tape_read (struct ndm_session *sess, char *buf, unsigned count) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH(ndmp9_tape_read, NDMP9VER) request->count = count; rc = NDMC_CALL(conn); if (rc == 0) { if (reply->data_in.data_in_len == count) { bcopy (reply->data_in.data_in_val, buf, count); } else { rc = -1; } } NDMC_FREE_REPLY(); NDMC_ENDWITH return rc; } int ndmca_tape_read_partial (struct ndm_session *sess, char *buf, unsigned count, int *read_count) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH(ndmp9_tape_read, NDMP9VER) request->count = count; rc = NDMC_CALL(conn); if (rc == 0) { *read_count = reply->data_in.data_in_len; bcopy (reply->data_in.data_in_val, buf, *read_count); } else { rc = reply->error; } NDMC_FREE_REPLY(); NDMC_ENDWITH return rc; } /* * TAPE Agent calls -- MOVER **************************************************************** */ int ndmca_mover_get_state (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; struct ndmp9_mover_get_state_reply *state = &ca->mover_state; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_mover_get_state, NDMP9VER) rc = NDMC_CALL(conn); if (rc) { NDMOS_MACRO_ZEROFILL (state); ca->mover_state.state = -1; } else { *state = *reply; } NDMC_ENDWITH return rc; } int ndmca_mover_listen (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; NDMC_WITH(ndmp9_mover_listen, NDMP9VER) request->mode = ca->mover_mode; if (sess->plumb.tape == sess->plumb.data) { request->addr_type = NDMP9_ADDR_LOCAL; } else { request->addr_type = NDMP9_ADDR_TCP; } rc = NDMC_CALL(conn); if (rc) return rc; if (request->addr_type != reply->data_connection_addr.addr_type) { ndmalogf (sess, 0, 0, "MOVER_LISTEN addr_type mismatch"); return -1; } ca->mover_addr = reply->data_connection_addr; NDMC_ENDWITH return 0; } int ndmca_mover_connect (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; NDMC_WITH(ndmp9_mover_connect, NDMP9VER) request->mode = ca->mover_mode; request->addr = ca->data_addr; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_continue (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_mover_continue, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_abort (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_mover_abort, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_stop (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_mover_stop, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_set_window (struct ndm_session *sess, uint64_t offset, uint64_t length) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH(ndmp9_mover_set_window, NDMP9VER) request->offset = offset; request->length = length; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_read (struct ndm_session *sess, uint64_t offset, uint64_t length) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH(ndmp9_mover_read, NDMP9VER) request->offset = offset; request->length = length; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_close (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; int rc; NDMC_WITH_VOID_REQUEST(ndmp9_mover_close, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmca_mover_set_record_size (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; NDMC_WITH(ndmp9_mover_set_record_size, NDMP9VER) request->record_size = ca->job.record_size; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_ctrl_conn.c000066400000000000000000000110641263011562700213130ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_connect_xxx_agent ( struct ndm_session *sess, struct ndmconn **connp, char *prefix, struct ndmagent *agent) { struct ndmconn * conn = *connp; char * err; int rc; if (conn) return 0; /* already connected */ if (agent->conn_type == NDMCONN_TYPE_NONE) { ndmalogf (sess, 0, 0, "agent %s not give", prefix+1); return -1; } conn = ndmconn_initialize (0, prefix); if (!conn) { ndmalogf (sess, prefix, 0, "can't init connection"); return -1; } if (sess->control_acb->job.time_limit > 0) conn->time_limit = sess->control_acb->job.time_limit; if (sess->conn_snooping) { ndmconn_set_snoop (conn, &sess->param->log, sess->param->log_level); } conn->call = ndma_call; conn->context = sess; conn->unexpected = ndma_dispatch_ctrl_unexpected; rc = ndmconn_connect_agent (conn, agent); if (rc) { err = "Can't connect"; goto error_out; } rc = ndmconn_auth_agent (conn, agent); if (rc) { err = "Can't auth (bad pw?)"; goto error_out; } *connp = conn; return 0; error_out: ndmalogf (sess, prefix, 0, "err %s", ndmconn_get_err_msg (conn)); //ndmconn_destruct (conn); *connp = conn; return -1; } int ndmca_connect_data_agent (struct ndm_session *sess) { int rc; rc = ndmca_connect_xxx_agent (sess, &sess->plumb.data, "#D", &sess->control_acb->job.data_agent); if (rc == 0) { if (sess->plumb.data->conn_type == NDMCONN_TYPE_RESIDENT) { sess->data_acb->protocol_version = sess->plumb.data->protocol_version; } } return rc; } int ndmca_connect_tape_agent (struct ndm_session *sess) { int rc; if (sess->control_acb->job.tape_agent.conn_type == NDMCONN_TYPE_NONE) { rc = ndmca_connect_data_agent (sess); if (rc) { ndmconn_destruct (sess->plumb.data); sess->plumb.data = NULL; return rc; } sess->plumb.tape = sess->plumb.data; rc = 0; } else { rc = ndmca_connect_xxx_agent (sess, &sess->plumb.tape, "#T", &sess->control_acb->job.tape_agent); ndmalogf (sess, 0, 7, "ndmca_connect_tape_agent: %d %p", rc, sess->plumb.tape); } if (rc == 0) { if (sess->plumb.tape->conn_type == NDMCONN_TYPE_RESIDENT) { sess->tape_acb->protocol_version = sess->plumb.tape->protocol_version; } } return rc; } int ndmca_connect_robot_agent (struct ndm_session *sess) { int rc; if (sess->control_acb->job.robot_agent.conn_type == NDMCONN_TYPE_NONE) { rc = ndmca_connect_tape_agent (sess); if (rc) return rc; sess->plumb.robot = sess->plumb.tape; rc = 0; } else { rc = ndmca_connect_xxx_agent (sess, &sess->plumb.robot, "#R", &sess->control_acb->job.robot_agent); } if (rc == 0) { if (sess->plumb.robot->conn_type == NDMCONN_TYPE_RESIDENT) { sess->robot_acb->protocol_version = sess->plumb.robot->protocol_version; } } return rc; } int ndmca_connect_control_agent (struct ndm_session *sess) { struct ndmagent control_agent; int rc; ndmagent_from_str (&control_agent, "."); /* resident */ rc = ndmca_connect_xxx_agent (sess, &sess->plumb.control, "#C.", &control_agent); return rc; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_ctrl_media.c000066400000000000000000000340141263011562700214350ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_media_load_first (struct ndm_session *sess) { sess->control_acb->cur_media_ix = 1; return ndmca_media_load_current (sess); } /* * TODO: It would be nice that if a media entry has a problem * during load_current() to just skip over it and proceed * to the next one. It will be really annoying to have a * long running backup terminate because of a write-protect * or label-check error when there are perfectly good * tapes available. */ int ndmca_media_load_next (struct ndm_session *sess) { int n_media = sess->control_acb->job.media_tab.n_media; if (sess->control_acb->cur_media_ix >= n_media) { ndmalogf (sess, 0, 0, "Out of tapes"); return -1; } sess->control_acb->cur_media_ix++; return ndmca_media_load_current (sess); } int ndmca_media_unload_last (struct ndm_session *sess) { return ndmca_media_unload_current(sess); } int ndmca_media_change (struct ndm_session *sess) { int rc; rc = ndmca_media_unload_current(sess); if (rc) return rc; rc = ndmca_media_load_next (sess); if (rc) return rc; return 0; } int ndmca_media_load_seek (struct ndm_session *sess, uint64_t pos) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; int n_media = job->media_tab.n_media; struct ndmmedia * me; for (me = job->media_tab.head; me; me = me->next) { if (me->begin_offset <= pos && pos < me->end_offset) break; } if (!me || me->index > n_media) { ndmalogf (sess, 0, 0, "Seek to unspecified media"); return -1; } ca->cur_media_ix = me->index; return ndmca_media_load_current (sess); } int ndmca_media_load_current (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; int rc; unsigned count; for (me = job->media_tab.head; me; me = me->next) { if (me->index == ca->cur_media_ix) break; } if (!me) { return -1; } if (job->have_robot) { rc = ndmca_robot_load (sess, me->slot_addr); if (rc) return rc; } me->media_used = 1; rc = ndmca_media_open_tape (sess); /* * TODO: it would be nice to discriminate this and * set flags accordingly. For example, * indicate a write-protect tape. */ if (rc) { me->media_open_error = 1; /* if use_eject, this won't work */ if (job->have_robot) { /* best-effort unload the robot */ ndmca_robot_unload (sess, me->slot_addr); } return rc; } ca->media_is_loaded = 1; rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_REW, 1, 0); if (rc) { me->media_io_error = 1; goto close_and_unload; } if (ca->is_label_op) { if (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) me->media_written = 1; /* most likely */ return 0; /* ready to go */ } if (me->valid_label) { rc = ndmca_media_check_label (sess, 'm', me->label); if (rc) { if (rc == -1) { me->label_io_error = 1; } else if (rc == -2) { me->label_read = 1; me->label_mismatch = 1; } goto close_and_unload; } me->label_read = 1; rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_REW, 1, 0); if (rc) { me->media_io_error = 1; } } if (!me->valid_filemark) { /* synthetic */ me->valid_filemark = 1; if (me->valid_label) me->file_mark_offset = 1; else me->file_mark_offset = 0; } count = me->file_mark_offset; if (count > 0) { rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_FSF, count, 0); if (rc) { me->fmark_error = 1; ndmca_media_mtio_tape (sess, NDMP9_MTIO_REW, 1, 0); goto close_and_unload; } } if (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) me->media_written = 1; /* most likely */ return 0; close_and_unload: me->media_io_error = 1; ndmca_media_unload_best_effort (sess); return rc; } int ndmca_media_unload_current (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; int rc; if (!ca->media_is_loaded) return 0; rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; if (ca->job.use_eject) { rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_OFF, 1, 0); if (rc) return rc; } rc = ndmca_media_close_tape (sess); if (rc) return rc; for (me = job->media_tab.head; me; me = me->next) { if (me->index == ca->cur_media_ix) break; } if (me && job->have_robot) { rc = ndmca_robot_unload (sess, me->slot_addr); if (rc) return rc; } ca->media_is_loaded = 0; return 0; } int ndmca_media_unload_best_effort (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; int errors = 0; int rc; if (!ca->media_is_loaded) return 0; rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_REW, 1, 0); if (rc) errors++; if (ca->job.use_eject) { rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_OFF, 1, 0); if (rc) errors++; } rc = ndmca_media_close_tape (sess); if (rc) errors++; if (job->have_robot) { for (me = job->media_tab.head; me; me = me->next) { if (me->index == ca->cur_media_ix) break; } if (me) { rc = ndmca_robot_unload (sess, me->slot_addr); if (rc) errors++; } else { errors++; } } ca->media_is_loaded = 0; return errors ? -1 : 0; } int ndmca_media_open_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; unsigned int t; ndmalogf (sess, 0, 1, "Opening tape drive %s %s", ca->job.tape_device, (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) ? "read/write" : "read-only"); rc = -1; for (t = 0; t <= ca->job.tape_timeout; t += 10) { if (t > 0) { ndmalogf (sess, 0, 1, "Pausing ten seconds before retry (%d/%d)", t, ca->job.tape_timeout); sleep (10); } rc = ndmca_tape_open(sess); if (rc == 0) break; } if (rc) { /* should interpret the error */ ndmalogf (sess, 0, 0, "failed open tape drive %s %s", ca->job.tape_device, (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) ? "read/write" : "read-only"); } return rc; } int ndmca_media_close_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ndmalogf (sess, 0, 2, "Closing tape drive %s", ca->job.tape_device); rc = ndmca_tape_close (sess); return 0; } int ndmca_media_mtio_tape (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { int rc; if (op == NDMP9_MTIO_REW) { ndmalogf (sess, 0, 1, "Commanding tape drive to rewind"); } else if (op == NDMP9_MTIO_OFF) { ndmalogf (sess, 0, 1, "Commanding tape drive to eject (go offline)"); } else { ndmalogf (sess, 0, 2, "Commanding tape drive to %s %d times", ndmp9_tape_mtio_op_to_str (op), count); } rc = ndmca_tape_mtio (sess, op, count, resid); return rc; } int ndmca_media_write_filemarks (struct ndm_session *sess) { int rc; rc = ndmca_media_mtio_tape (sess, NDMP9_MTIO_EOF, 2, 0); return rc; } /* * Returns: 'm' for tape (media) label * 'V' for volume label * '?' for unknown content * -1 for some kind of error */ int ndmca_media_read_label (struct ndm_session *sess, char labbuf[]) { char tape_read_buf[512]; int rc; char * p; char * q; ndmalogf (sess, 0, 2, "Reading label"); *labbuf = 0; rc = ndmca_tape_read (sess, tape_read_buf, 512); if (rc == 0) { p = tape_read_buf; if (strncmp (p, "##ndmjob -m ", 12) == 0) { p += 12; rc = 'm'; } else if (strncmp (p, "##ndmjob -V ", 12) == 0) { p += 12; rc = 'V'; } else { rc = '?'; p = 0; } if (p) { q = labbuf; while (*p && *p != '\n' && q < &labbuf[NDMMEDIA_LABEL_MAX-1]) { *q++ = *p++; } *q = 0; } } else { rc = -1; } return rc; } /* * type is either 'm' or 'V', see above */ int ndmca_media_write_label (struct ndm_session *sess, int type, char labbuf[]) { int rc; char buf[512]; char * p; ndmalogf (sess, 0, 1, "Writing tape label '%s' type=%c", labbuf, type); for (p = buf; p < &buf[512]; p++) *p = '#'; for (p = buf+63; p < &buf[512]; p += 64) *p = '\n'; snprintf (buf, sizeof(buf), "##ndmjob -%c %s", type, labbuf); for (p = buf; *p; p++) continue; *p++ = '\n'; rc = ndmca_tape_write (sess, buf, 512); return rc; } /* * type is either 'm' or 'V', see above */ int ndmca_media_check_label (struct ndm_session *sess, int type, char labbuf[]) { int rc; char mylabbuf[NDMMEDIA_LABEL_MAX]; ndmalogf (sess, 0, 1, "Checking tape label, expect '%s'", labbuf); rc = ndmca_media_read_label (sess, mylabbuf); if (rc < 0) { ndmalogf (sess, 0, 0, "Label read error"); return -1; } if (rc != type || strcmp (labbuf, mylabbuf) != 0) { ndmalogf (sess, 0, 0, "Label mismatch, expected -%c'%s', got -%c'%s'", type, labbuf, rc, mylabbuf); return -2; } return 0; } int ndmca_media_verify (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; int rc; if (job->have_robot) return 0; /* not much we can do in advance */ rc = ndmca_robot_verify_media (sess); if (rc == 0) return rc; ndmca_media_tattle (sess); return -1; } int ndmca_media_tattle (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; int line, nline; if (!sess->dump_media_info) { return 0; } for (me = job->media_tab.head; me; me = me->next) { char buf[80]; nline = ndmmedia_pp (me, 0, buf); ndmalogf (sess, 0, 1, "media #%d %s", me->index, buf); for (line = 1; line < nline; line++) { nline = ndmmedia_pp (me, line, buf); ndmalogf (sess, 0, 2, " %s", buf); } } return 0; } /* * Determine the current byte offset in the current * tape file. */ uint64_t ndmca_media_capture_tape_offset (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; int rc; uint64_t off; rc = ndmca_tape_get_state(sess); if (rc) return NDMP_LENGTH_INFINITY; /* invalid? */ if (!ca->tape_state.blockno.valid) return NDMP_LENGTH_INFINITY; /* invalid? */ off = ca->tape_state.blockno.value; off *= job->record_size; return off; } int ndmca_media_capture_mover_window (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndmlog * ixlog = &ca->job.index_log; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; ndmp9_mover_state ms = ca->mover_state.state; ndmp9_mover_pause_reason pr = ca->mover_state.pause_reason; char buf[100]; uint64_t wlen; for (me = job->media_tab.head; me; me = me->next) { if (me->index == ca->cur_media_ix) break; } if (!me) { return -1; } if (ms == NDMP9_MOVER_STATE_PAUSED) { if (pr == NDMP9_MOVER_PAUSE_SEEK) { /* end-of-window */ } else if (pr == NDMP9_MOVER_PAUSE_EOM) { me->media_eom = 1; /* tape full */ } else if (pr == NDMP9_MOVER_PAUSE_EOF) { me->media_eof = 1; } else if (pr == NDMP9_MOVER_PAUSE_MEDIA_ERROR) { me->media_io_error = 1; } else { /* what */ } } else if (ms == NDMP9_MOVER_STATE_HALTED) { /* if tape_mode == READ, this may not actually be the window */ /* TODO: should STATE_LISTEN be considered? */ } else { ndmalogf (sess, 0, 1, "Warning: capturing offset w/o quiescent mover"); } wlen = ca->mover_state.record_num; wlen *= job->record_size; wlen -= job->last_w_offset; /* want the size of this image */ me->valid_n_bytes = 1; me->nb_determined = 1; me->n_bytes = wlen; /* * Only print the data when a deliver function was defined. */ if (ixlog->deliver) { ndmmedia_pp (me, 0, buf); ndmlogf (ixlog, "CM", 0, "%02d %s", ca->cur_media_ix, buf); } return 0; } int ndmca_media_calculate_windows (struct ndm_session *sess) { return 0; } int ndmca_media_calculate_offsets (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; uint64_t offset = 0; for (me = job->media_tab.head; me; me = me->next) { me->begin_offset = offset; if (me->valid_n_bytes) { offset += me->n_bytes; me->end_offset = offset; } else { me->n_bytes = NDMP_LENGTH_INFINITY; me->end_offset = NDMP_LENGTH_INFINITY; /* offset unchanged */ } } return 0; } int ndmca_media_set_window_current (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndm_job_param * job = &ca->job; struct ndmmedia * me; int rc; for (me = job->media_tab.head; me; me = me->next) { if (me->index == ca->cur_media_ix) break; } if (!me) { return -1; } rc = ndmca_mover_set_window (sess, me->begin_offset, me->n_bytes); if (rc == 0) job->last_w_offset = me->begin_offset; return rc; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_ctrl_robot.c000066400000000000000000000265311263011562700215100ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int ndmca_robot_issue_scsi_req (struct smc_ctrl_block *smc) { struct ndmconn * conn = (struct ndmconn *) smc->app_data; struct smc_scsi_req * sr = &smc->scsi_req; int rc; rc = ndmscsi_execute (conn, (struct ndmscsi_request *) sr, 0); return rc; } int ndmca_robot_prep_target (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; int rc; NDMOS_MACRO_ZEROFILL (smc); smc->app_data = sess->plumb.robot; smc->issue_scsi_req = ndmca_robot_issue_scsi_req; /* * We are about to start using a Robot Target so allocate it. * Only do this when not allocated yet. */ if (!sess->control_acb->job.robot_target) { sess->control_acb->job.robot_target = NDMOS_API_MALLOC (sizeof(struct ndmscsi_target)); if (!sess->control_acb->job.robot_target) { ndmalogf (sess, 0, 0, "Failed allocating robot target"); return -1; } NDMOS_MACRO_ZEROFILL (sess->control_acb->job.robot_target); } rc = ndmscsi_use (sess->plumb.robot, sess->control_acb->job.robot_target); if (rc) return rc; return 0; } int ndmca_robot_obtain_info (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; int rc; rc = smc_inquire (smc); if (rc) return rc; rc = smc_get_elem_aa (smc); if (rc) return rc; rc = smc_read_elem_status (smc); if (rc) return rc; return 0; } int ndmca_robot_init_elem_status (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; int rc; ndmalogf (sess, 0, 1, "Commanding robot to initialize element status (take inventory)"); rc = smc_init_elem_status (smc); if (rc) { ndmalogf (sess, 0, 0, "init-elem-status failed"); return rc; } return 0; } int ndmca_robot_startup (struct ndm_session *sess) { int rc; if (!sess->control_acb->job.have_robot) return -1; /* Huh? why were we called */ if (!sess->control_acb->smc_cb) { sess->control_acb->smc_cb = NDMOS_API_MALLOC (sizeof(struct smc_ctrl_block)); NDMOS_MACRO_ZEROFILL (sess->control_acb->smc_cb); } rc = ndmca_connect_robot_agent(sess); if (rc) return rc; rc = ndmca_robot_prep_target(sess); if (rc) return rc; return 0; } int ndmca_robot_move (struct ndm_session *sess, int src_addr, int dst_addr) { struct ndm_control_agent *ca = sess->control_acb; struct smc_ctrl_block * smc = ca->smc_cb; int rc; unsigned int t; ndmalogf (sess, 0, 2, "robot moving @%d to @%d", src_addr, dst_addr); rc = -1; for (t = 0; t <= ca->job.robot_timeout; t += 10) { if (t > 0) { ndmalogf (sess, 0, 2, "Pausing ten seconds before retry (%d/%d)", t, ca->job.robot_timeout); sleep (10); } rc = smc_move (smc, src_addr, dst_addr, 0, smc->elem_aa.mte_addr); if (rc == 0) break; } if (rc == 0) { ndmalogf (sess, 0, 2, "robot move OK @%d to @%d", src_addr, dst_addr); } else { ndmalogf (sess, 0, 2, "robot move BAD @%d to @%d", src_addr, dst_addr); } return rc; } int ndmca_robot_load (struct ndm_session *sess, int slot_addr) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; unsigned dte_addr = smc->elem_aa.dte_addr; int rc; if (sess->control_acb->job.drive_addr_given) dte_addr = sess->control_acb->job.drive_addr; ndmalogf (sess, 0, 1, "Commanding robot to load slot @%d into drive @%d", slot_addr, dte_addr); rc = ndmca_robot_move (sess, slot_addr, dte_addr); return rc; } int ndmca_robot_unload (struct ndm_session *sess, int slot_addr) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; int dte_addr = smc->elem_aa.dte_addr; int rc; if (sess->control_acb->job.drive_addr_given) dte_addr = sess->control_acb->job.drive_addr; /* tricky part -- some (most?) robots need the drive to eject */ ndmalogf (sess, 0, 1, "Commanding robot to unload drive @%d to slot @%d", dte_addr, slot_addr); rc = ndmca_robot_move (sess, dte_addr, slot_addr); return rc; } struct smc_element_descriptor * ndmca_robot_find_element (struct ndm_session *sess, int element_address) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; unsigned int i; struct smc_element_descriptor * edp; for (i = 0; i < smc->n_elem_desc; i++) { edp = &smc->elem_desc[i]; if (edp->element_address == element_address) return edp; } return 0; } int ndmca_robot_check_ready (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; unsigned first_dte_addr; unsigned n_dte_addr; int rc; unsigned int i; int errcnt = 0; struct smc_element_descriptor * edp; rc = ndmca_robot_obtain_info (sess); if (rc) return rc; if (sess->control_acb->job.remedy_all) { first_dte_addr = smc->elem_aa.dte_addr; n_dte_addr = smc->elem_aa.dte_count; } else { n_dte_addr = 1; if (sess->control_acb->job.drive_addr_given) { first_dte_addr = sess->control_acb->job.drive_addr; } else { first_dte_addr = smc->elem_aa.dte_addr; } } for (i = 0; i < n_dte_addr; i++) { edp = ndmca_robot_find_element (sess, first_dte_addr+i); if (!edp->Full) continue; ndmalogf (sess, 0, 1, "tape drive @%d not empty", edp->element_address); errcnt++; } return errcnt; } int ndmca_robot_remedy_ready (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; int rc; unsigned int i; int errcnt; struct smc_element_descriptor * edp; struct smc_element_descriptor * edp2; unsigned first_dte_addr; unsigned n_dte_addr; char prefix[60]; errcnt = 0; rc = ndmca_robot_obtain_info (sess); if (rc) return rc; if (sess->control_acb->job.remedy_all) { first_dte_addr = smc->elem_aa.dte_addr; n_dte_addr = smc->elem_aa.dte_count; } else { n_dte_addr = 1; if (sess->control_acb->job.drive_addr_given) { first_dte_addr = sess->control_acb->job.drive_addr; } else { first_dte_addr = smc->elem_aa.dte_addr; } } for (i = 0; i < n_dte_addr; i++) { edp = ndmca_robot_find_element (sess, first_dte_addr+i); if (!edp->Full) continue; snprintf (prefix, sizeof(prefix), "drive @%d not empty", edp->element_address); if (!edp->SValid) { ndmalogf (sess, 0, 1, "%s, invalid source", prefix); errcnt++; continue; } sprintf (NDMOS_API_STREND(prefix), ", src @%d", edp->src_se_addr); edp2 = ndmca_robot_find_element (sess, edp->src_se_addr); if (edp2->element_type_code != SMC_ELEM_TYPE_SE) { ndmalogf (sess, 0, 1, "%s, not slot", prefix); errcnt++; continue; } if (edp2->Full) { ndmalogf (sess, 0, 1, "%s, but slot Full", prefix); errcnt++; continue; } rc = ndmca_robot_move (sess, edp->element_address, edp->src_se_addr); if (rc) { ndmalogf (sess, 0, 1, "%s, move failed", prefix); errcnt++; continue; } } return errcnt; } /* * ndmca_robot_query() incrementally obtains info so that we * can print progress. */ int ndmca_robot_query (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; int rc; unsigned int i; char buf[111]; char lnbuf[30]; int lineno, nline = 1; ndmalogqr (sess, " Type"); rc = smc_inquire (smc); if (rc) { ndmalogqr (sess, " ERROR smc_inquire(): %s", smc->errmsg); } else { ndmalogqr (sess, " '%s'", smc->ident); } ndmalogqr (sess, " Elements"); rc = smc_get_elem_aa (smc); if (rc) { ndmalogqr (sess, " ERROR smc_get_elem_aa(): %s", smc->errmsg); } else { strcpy (lnbuf, " "); for (lineno = 0, nline = 1; lineno < nline; lineno++) { rc = smc_pp_element_address_assignments (&smc->elem_aa, lineno, buf); if (rc < 0) { strcpy (buf, "PP-ERROR"); } nline = rc; ndmalogqr (sess, "%s %s", lnbuf, buf); } } ndmalogqr (sess, " Status"); rc = smc_read_elem_status (smc); if (rc) { ndmalogqr (sess, " ERROR smc_read_elem_status(): %s", smc->errmsg); } else { ndmalogqr (sess, " E# Addr Type Status"); ndmalogqr (sess, " -- ---- ---- ---------------------"); for (i = 0; i < smc->n_elem_desc; i++) { struct smc_element_descriptor * edp; edp = &smc->elem_desc[i]; for (lineno = 0, nline = 1; lineno < nline; lineno++) { rc = smc_pp_element_descriptor (edp, lineno, buf); if (lineno == 0) snprintf (lnbuf, sizeof(lnbuf), " %2d ", i+1); else snprintf (lnbuf, sizeof(lnbuf), " "); if (rc < 0) { strcpy (buf, "PP-ERROR"); } nline = rc; ndmalogqr (sess, "%s %s", lnbuf, buf); } } } return 0; } int ndmca_robot_verify_media (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; struct ndm_media_table *mtab = &sess->control_acb->job.media_tab; int rc; struct ndmmedia * me; struct smc_element_descriptor *edp; unsigned int i; int errcnt = 0; rc = ndmca_robot_obtain_info (sess); if (rc) return rc; for (me = mtab->head; me; me = me->next) { if (! me->valid_slot) { me->slot_missing = 1; errcnt++; continue; /* what now */ } for (i = 0; i < smc->n_elem_desc; i++) { edp = &smc->elem_desc[i]; if (edp->element_type_code != SMC_ELEM_TYPE_SE) continue; if (edp->element_address != me->slot_addr) continue; if (!edp->Full) { me->slot_empty = 1; errcnt++; } else { me->slot_empty = 0; } break; } if (i >= smc->n_elem_desc) { me->slot_bad = 1; errcnt++; } } return errcnt; } /* * For NDM_JOB_OP_LIST_LABELS, fill in media_tab based on non-empty slots. * Note: this might REALLY nerf on a cleaning cartridge. */ int ndmca_robot_synthesize_media (struct ndm_session *sess) { struct smc_ctrl_block * smc = sess->control_acb->smc_cb; struct ndm_media_table *mtab = &sess->control_acb->job.media_tab; int rc; struct smc_element_descriptor *edp; unsigned int i; rc = ndmca_robot_obtain_info (sess); if (rc) return rc; for (i = 0; i < smc->n_elem_desc; i++) { edp = &smc->elem_desc[i]; if (edp->element_type_code != SMC_ELEM_TYPE_SE) continue; if (!edp->Full) continue; ndma_store_media (mtab, edp->element_address); } return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_ctst_data.c000066400000000000000000000261671263011562700213120ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * ******************************************************************** * * NDMP Elements of a test-data session * * +-----+ ########### * | Job |----># CONTROL # * +-----+ # Agent # * # # * ########### * | # * +----------------+ # * | control connection # CONTROL * V # impersonates * ############ # TAPE side of * # DATA # # image stream * # Agent # # * +-----+ # +------+ # image # * |FILES|====|butype|===================# * +-----+ # +------+ # stream * ############ * * ******************************************************************** * */ #include "ndmagents.h" #if !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) extern int ndmca_td_wrapper (struct ndm_session *sess, int (*func)(struct ndm_session *sess)); extern int ndmca_op_test_data (struct ndm_session *sess); extern int ndmca_td_idle (struct ndm_session *sess); extern int ndmca_td_listen (struct ndm_session *sess); extern int ndmca_td_listen_subr (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type); extern int ndmca_test_check_data_state (struct ndm_session *sess, ndmp9_data_state expected, int reason); extern int ndmca_test_data_get_state (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_data_abort (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_data_stop (struct ndm_session *sess, ndmp9_error expect_err); int ndmca_op_test_data (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; struct ndmconn * conn; int (*save_call) (struct ndmconn *conn, struct ndmp_xa_buf *xa); int rc; rc = ndmca_connect_data_agent(sess); if (rc) { ndmconn_destruct (sess->plumb.data); sess->plumb.data = NULL; return rc; } conn = sess->plumb.data; save_call = conn->call; conn->call = ndma_call_no_tattle; /* perform query to find out about TCP and LOCAL support */ rc = ndmca_test_query_conn_types (sess, conn); if (rc) return rc; rc = ndmca_td_wrapper (sess, ndmca_td_idle); if (sess->plumb.data->protocol_version >= 3) { // version 3 and later adds LISTEN rc = ndmca_td_wrapper (sess, ndmca_td_listen); } ndmca_test_done_series (sess, "test-data"); ca = sess->control_acb; if (ca->has_tcp_addr && ca->has_local_addr) { ndmalogf (sess, "TEST", 0, "LOCAL and TCP addressing tested."); } else if (ca->has_tcp_addr) { ndmalogf (sess, "TEST", 0, "TCP addressing ONLY tested."); } else if (ca->has_local_addr) { ndmalogf (sess, "TEST", 0, "LOCAL addressing ONLY tested."); } else { ndmalogf (sess, "TEST", 0, "Neither TCP or LOCAL addressing tested."); } return 0; } int ndmca_td_wrapper (struct ndm_session *sess, int (*func)(struct ndm_session *sess)) { int rc; rc = (*func)(sess); if (rc != 0) { ndmalogf (sess, "Test", 1, "Failure"); } ndmca_test_done_phase (sess); /* clean up mess */ ndmca_test_log_note (sess, 2, "Cleaning up..."); rc = 0; return rc; } int ndmca_td_idle (struct ndm_session *sess) { int rc; ndmca_test_phase (sess, "D-IDLE", "Data IDLE State Series"); rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); if (rc) return rc; rc = ndmca_test_data_abort (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_data_stop (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; return 0; /* pass */ } #define NDMTEST_CALL(CONN) ndmca_test_call(CONN, xa, expect_err); int ndmca_test_data_listen (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type) { struct ndmconn * conn = sess->plumb.data; struct ndm_control_agent *ca = sess->control_acb; int rc; /* close previous test if there is one */ ndmca_test_close (sess); switch (conn->protocol_version) { default: return -1234; #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_data_listen, NDMP3VER) request->addr_type = addr_type; rc = NDMTEST_CALL(conn); if (rc) return rc; if (expect_err == NDMP9_NO_ERR && request->addr_type != reply->data_connection_addr.addr_type) { /* TODO: use proper test format */ ndmalogf (sess, "Test", 1, "DATA_LISTEN addr_type mismatch"); return -1; } ndmp_3to9_addr (&reply->data_connection_addr, &ca->data_addr); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_data_listen, NDMP4VER) request->addr_type = addr_type; rc = NDMTEST_CALL(conn); if (rc) return rc; if (expect_err == NDMP9_NO_ERR && request->addr_type != reply->connect_addr.addr_type) { /* TODO: use proper test format */ ndmalogf (sess, "Test", 1, "DATA_LISTEN addr_type mismatch"); return -1; } ndmp_4to9_addr (&reply->connect_addr, &ca->data_addr); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } int ndmca_td_listen (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ndmca_test_phase (sess, "D-LISTEN", "Data LISTEN State Series"); rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); if (rc) return rc; if (ca->has_tcp_addr) { rc = ndmca_td_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_TCP); if (rc) return rc; } if (ca->has_local_addr) { rc = ndmca_td_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_LOCAL); if (rc) return rc; } ndmca_test_done_phase (sess); /* * Bogus arguments */ ndmca_test_phase (sess, "D-LISTEN/bogus-args", "Data LISTEN State Series w/ bogus args"); rc = ndmca_test_data_listen (sess, NDMP9_ILLEGAL_ARGS_ERR, 123); if (rc) return rc; ndmca_test_done_phase (sess); return 0; /* pass */ } int ndmca_td_listen_subr (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type) { int rc; rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); if (rc) return rc; rc = ndmca_test_data_listen (sess, expect_err, addr_type); if (rc) return rc; if (expect_err != NDMP9_NO_ERR) return 0; /* got expected error */ rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_LISTEN, 0); if (rc) return rc; rc = ndmca_test_data_listen (sess, NDMP9_ILLEGAL_STATE_ERR, addr_type); if (rc) return rc; rc = ndmca_test_data_stop (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_data_abort (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_HALTED, NDMP9_DATA_HALT_ABORTED); if (rc) return rc; rc = ndmca_test_data_stop (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); if (rc) return rc; return 0; } int ndmca_test_check_data_state (struct ndm_session *sess, ndmp9_data_state expected, int reason) { struct ndm_control_agent * ca = sess->control_acb; ndmp9_data_get_state_reply * ds = &ca->data_state; int rc; char * what; char errbuf[100]; char tmpbuf[256]; /* close previous test if there is one */ ndmca_test_close (sess); /* open new test */ ndmca_test_open (sess, "data check", ndmp9_data_state_to_str (expected)); strcpy (errbuf, "???"); what = "get_state"; rc = ndmca_data_get_state (sess); if (rc) goto fail; what = "state self-consistent"; /* make sure the sensed state is self consistent */ switch (ds->state) { case NDMP9_DATA_STATE_IDLE: case NDMP9_DATA_STATE_ACTIVE: case NDMP9_DATA_STATE_LISTEN: case NDMP9_DATA_STATE_CONNECTED: if (ds->halt_reason != NDMP9_DATA_HALT_NA) { strcpy (errbuf, "reason != NA"); goto fail; } break; case NDMP9_DATA_STATE_HALTED: break; default: strcpy (errbuf, "bogus state"); goto fail; } what = "state"; if (ds->state != expected) { snprintf (errbuf, sizeof(errbuf), "expected %s got %s", ndmp9_data_state_to_str (expected), ndmp9_data_state_to_str (ds->state)); goto fail; } what = "reason"; switch (ds->state) { case NDMP9_DATA_STATE_HALTED: if (ds->halt_reason != (ndmp9_data_halt_reason)reason) { snprintf (errbuf, sizeof(errbuf), "expected %s got %s", ndmp9_data_halt_reason_to_str (reason), ndmp9_data_halt_reason_to_str (ds->halt_reason)); goto fail; } break; default: break; } /* test passed */ ndmca_test_close (sess); return 0; fail: /* test failed */ snprintf(tmpbuf, sizeof(tmpbuf), "%s: %s", what, errbuf); ndmca_test_fail(sess, tmpbuf); ndmca_test_close (sess); return -1; } int ndmca_test_data_get_state (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.data; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_data_get_state (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_data_abort (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.data; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_data_abort (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_data_stop (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.data; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_data_stop (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } #endif /* !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) */ bareos-Release-14.2.6/src/ndmp/ndma_ctst_mover.c000066400000000000000000000512111263011562700215150ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * ***************************************************************** * * NDMP Elements of a test-mover session * * +-----+ ########### * | Job |----># CONTROL # * +-----+ # Agent # * # # * ########### * # | | * #=============# | +---------------------+ * # | | * CONTROL # control | connections | * impersonates # V V * DATA side of # ############ +-------+ ######### * image stream # # TAPE # | | # ROBOT # * # # Agent # | ROBOT |<-># Agent # * # image # +------+ # |+-----+| # # * #==============|mover |=====|DRIVE|| # # * stream # +------+ # |+-----+| # # * ############ +-------+ ######### * **************************************************************** * */ #include "ndmagents.h" #if !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) extern int ndmca_tm_wrapper (struct ndm_session *sess, int (*func)(struct ndm_session *sess)); extern int ndmca_op_test_mover (struct ndm_session *sess); extern int ndmca_tm_idle (struct ndm_session *sess); extern int ndmca_tm_listen (struct ndm_session *sess); extern int ndmca_tm_listen_subr (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type, ndmp9_mover_mode mode); extern int ndmca_test_check_mover_state (struct ndm_session *sess, ndmp9_mover_state expected, int reason); extern int ndmca_test_mover_get_state (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_mover_listen (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type, ndmp9_mover_mode mode); extern int ndmca_test_mover_continue (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_mover_abort (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_mover_stop (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_mover_set_window (struct ndm_session *sess, ndmp9_error expect_err, uint64_t offset, uint64_t length); extern int ndmca_test_mover_read (struct ndm_session *sess, ndmp9_error expect_err, uint64_t offset, uint64_t length); extern int ndmca_test_mover_close (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_mover_set_record_size (struct ndm_session *sess, ndmp9_error expect_err); struct series { unsigned n_rec; unsigned recsize; }; struct series tm_series[] = { { 1, 512 }, { 100, 1024 }, { 1, 512 }, { 100, 139 }, { 1, 512 }, { 99, 10240 }, { 1, 512 }, { 3, 32768 }, { 1, 512 }, { 0 } }; int ndmca_op_test_mover (struct ndm_session *sess) { struct ndmconn * conn; int (*save_call) (struct ndmconn *conn, struct ndmp_xa_buf *xa); int rc; struct ndm_control_agent *ca = sess->control_acb; if (sess->control_acb->job.data_agent.conn_type != NDMCONN_TYPE_NONE) { /* * Sometimes needed to aid resident tape agent test */ rc = ndmca_connect_data_agent (sess); if (rc) { ndmconn_destruct (sess->plumb.data); sess->plumb.data = NULL; return rc; } } rc = ndmca_test_load_tape (sess); if (rc) return rc; conn = sess->plumb.tape; save_call = conn->call; conn->call = ndma_call_no_tattle; /* perform query to find out about TCP and LOCAL support */ rc = ndmca_test_query_conn_types (sess, conn); if (rc) return rc; rc = ndmca_tm_wrapper (sess, ndmca_tm_idle); rc = ndmca_tm_wrapper (sess, ndmca_tm_listen); ndmca_test_unload_tape (sess); ndmca_test_done_series (sess, "test-mover"); ca = sess->control_acb; if (ca->has_tcp_addr && ca->has_local_addr) { ndmalogf (sess, "TEST", 0, "LOCAL and TCP addressing tested."); } else if (ca->has_tcp_addr) { ndmalogf (sess, "TEST", 0, "TCP addressing ONLY tested."); } else if (ca->has_local_addr) { ndmalogf (sess, "TEST", 0, "LOCAL addressing ONLY tested."); } else { ndmalogf (sess, "TEST", 0, "Neither TCP or LOCAL addressing tested."); } return 0; } int ndmca_tm_wrapper (struct ndm_session *sess, int (*func)(struct ndm_session *sess)) { int rc; rc = (*func)(sess); if (rc != 0) { ndmalogf (sess, "Test", 1, "Failure"); } ndmca_test_done_phase (sess); /* clean up mess */ ndmca_test_log_note (sess, 2, "Cleaning up..."); ndmca_tape_open (sess); /* Open the tape, OK if already opened */ ndmca_tape_mtio (sess, NDMP9_MTIO_REW, 1, 0); rc = ndmca_tape_close (sess); /* close, collective error */ if (rc != 0) { ndmca_test_log_note (sess, 0, "Cleaning up failed, quiting"); } else { ndmca_test_log_note (sess, 2, "Cleaning up done"); } return rc; } int ndmca_tm_idle (struct ndm_session *sess) { int rc; ndmca_test_phase (sess, "M-IDLE", "Mover IDLE State Series"); rc = ndmca_test_check_mover_state (sess, NDMP9_MOVER_STATE_IDLE, 0); if (rc) return rc; rc = ndmca_test_mover_continue (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_mover_abort (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_mover_stop (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_mover_close (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_mover_set_window (sess, NDMP9_NO_ERR, 0, 0); if (rc) return rc; rc = ndmca_test_mover_set_record_size (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; /* pass */ } extern int ndmca_test_tape_open (struct ndm_session *sess, ndmp9_error expect_err, char *device, int mode); extern int ndmca_test_tape_close (struct ndm_session *sess, ndmp9_error expect_err); int ndmca_tm_listen (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ndmca_test_phase (sess, "M-LISTEN", "Mover LISTEN State Series"); rc = ndmca_test_check_mover_state (sess, NDMP9_MOVER_STATE_IDLE, 0); if (rc) return rc; rc = ndmca_test_mover_set_record_size (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_mover_set_window (sess, NDMP9_NO_ERR, 0, 0); if (rc) return rc; ndmca_test_done_phase (sess); /* * Bogus arguments */ ndmca_test_phase (sess, "M-LISTEN/bogus-args", "Mover LISTEN State Series w/ bogus args"); if (ca->has_local_addr) { rc = ndmca_test_mover_listen (sess, NDMP9_ILLEGAL_ARGS_ERR, NDMP9_ADDR_LOCAL, 123); if (rc) return rc; } rc = ndmca_test_mover_listen (sess, NDMP9_ILLEGAL_ARGS_ERR, 123, NDMP9_MOVER_MODE_READ); if (rc) return rc; ndmca_test_done_phase (sess); /* * Tape drive not open */ ndmca_test_phase (sess, "M-LISTEN/not-open", "Mover LISTEN State Series w/o tape open"); if (ca->has_local_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_DEV_NOT_OPEN_ERR, NDMP9_ADDR_LOCAL, NDMP9_MOVER_MODE_READ); if (rc) return rc; } if (ca->has_tcp_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_DEV_NOT_OPEN_ERR, NDMP9_ADDR_TCP, NDMP9_MOVER_MODE_READ); if (rc) return rc; } if (ca->has_local_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_DEV_NOT_OPEN_ERR, NDMP9_ADDR_LOCAL, NDMP9_MOVER_MODE_WRITE); if (rc) return rc; } if (ca->has_tcp_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_DEV_NOT_OPEN_ERR, NDMP9_ADDR_TCP, NDMP9_MOVER_MODE_WRITE); if (rc) return rc; } ndmca_test_done_phase (sess); /* * Tape drive open for READ */ ndmca_test_phase (sess, "M-LISTEN/tape-ro", "Mover LISTEN State Series w/ tape r/o"); rc = ndmca_test_tape_open(sess, NDMP9_NO_ERR, 0, NDMP9_TAPE_READ_MODE); if (rc) return rc; if (ca->has_local_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_PERMISSION_ERR, NDMP9_ADDR_LOCAL, NDMP9_MOVER_MODE_READ); if (rc) return rc; } if (ca->has_tcp_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_PERMISSION_ERR, NDMP9_ADDR_TCP, NDMP9_MOVER_MODE_READ); if (rc) return rc; } if (ca->has_local_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_LOCAL, NDMP9_MOVER_MODE_WRITE); if (rc) return rc; } if (ca->has_tcp_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_TCP, NDMP9_MOVER_MODE_WRITE); if (rc) return rc; } rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; ndmca_test_done_phase (sess); /* * Tape drive open for WRITE */ ndmca_test_phase (sess, "M-LISTEN/tape-rw", "Mover LISTEN State Series w/ tape r/w"); rc = ndmca_test_tape_open(sess, NDMP9_NO_ERR, 0, NDMP9_TAPE_RDWR_MODE); if (rc) return rc; if (ca->has_local_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_LOCAL, NDMP9_MOVER_MODE_READ); if (rc) return rc; } if (ca->has_tcp_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_TCP, NDMP9_MOVER_MODE_READ); if (rc) return rc; } if (ca->has_local_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_LOCAL, NDMP9_MOVER_MODE_WRITE); if (rc) return rc; } if (ca->has_tcp_addr) { rc = ndmca_tm_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_TCP, NDMP9_MOVER_MODE_WRITE); if (rc) return rc; } rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; #if 0 ndmca_test_done_phase (sess); #else // done by the wrapper... #endif /* * TODO: NDMP9_MOVER_MODE_DATA */ /* * Good enough */ #if 0 ndmca_test_phase (sess, "M-LISTEN", "Mover LISTEN State Series"); #endif return 0; /* pass */ } int ndmca_tm_listen_subr (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type, ndmp9_mover_mode mode) { int rc; rc = ndmca_test_check_mover_state (sess, NDMP9_MOVER_STATE_IDLE, 0); if (rc) return rc; rc = ndmca_test_mover_listen (sess, expect_err, addr_type, mode); if (rc) return rc; if (expect_err != NDMP9_NO_ERR) return 0; /* got expected error */ rc = ndmca_test_check_mover_state (sess, NDMP9_MOVER_STATE_LISTEN, 0); if (rc) return rc; rc = ndmca_test_mover_listen (sess, NDMP9_ILLEGAL_STATE_ERR, addr_type, mode); if (rc) return rc; rc = ndmca_test_mover_continue (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; #if 0 /* let it slide for Veritas 3.2 for the moment... Oct 23, 2002 */ #else rc = ndmca_test_mover_stop (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; #endif #if 0 /* ??? */ rc = ndmca_test_mover_close (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; #endif /* setting the window size in LISTEN mode is not legal in * version 4 and is required to work in earlier versions */ if (sess->plumb.tape->protocol_version < 4) { rc = ndmca_test_mover_set_window (sess, NDMP9_NO_ERR, 0, 0); if (rc) return rc; } else { rc = ndmca_test_mover_set_window (sess, NDMP9_ILLEGAL_STATE_ERR, 0, 0); if (rc) return rc; } rc = ndmca_test_mover_set_record_size (sess, NDMP9_ILLEGAL_STATE_ERR); if (rc) return rc; rc = ndmca_test_mover_abort (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_check_mover_state (sess, NDMP9_MOVER_STATE_HALTED, NDMP9_MOVER_HALT_ABORTED); if (rc) return rc; rc = ndmca_test_mover_stop (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_check_mover_state (sess, NDMP9_MOVER_STATE_IDLE, 0); if (rc) return rc; return 0; } int ndmca_test_check_mover_state (struct ndm_session *sess, ndmp9_mover_state expected, int reason) { struct ndm_control_agent * ca = sess->control_acb; ndmp9_mover_get_state_reply * ms = &ca->mover_state; int rc; char * what; char errbuf[100]; char tmpbuf[256]; /* close previous test if there is one */ ndmca_test_close (sess); /* open new test */ ndmca_test_open (sess, "mover check", ndmp9_mover_state_to_str (expected)); strcpy (errbuf, "???"); what = "get_state"; rc = ndmca_mover_get_state (sess); if (rc) goto fail; what = "state self-consistent"; /* make sure the sensed state is self consistent */ switch (ms->state) { case NDMP9_MOVER_STATE_IDLE: case NDMP9_MOVER_STATE_LISTEN: case NDMP9_MOVER_STATE_ACTIVE: if (ms->pause_reason != NDMP9_MOVER_PAUSE_NA || ms->halt_reason != NDMP9_MOVER_HALT_NA) { strcpy (errbuf, "reason(s) != NA"); goto fail; } break; case NDMP9_MOVER_STATE_PAUSED: if (ms->halt_reason != NDMP9_MOVER_HALT_NA) { strcpy (errbuf, "halt_reason != NA"); goto fail; } break; case NDMP9_MOVER_STATE_HALTED: if (ms->pause_reason != NDMP9_MOVER_PAUSE_NA) { strcpy (errbuf, "pause_reason != NA"); goto fail; } break; default: strcpy (errbuf, "bogus state"); goto fail; } what = "state"; if (ms->state != expected) { snprintf (errbuf, sizeof(errbuf), "expected %s got %s", ndmp9_mover_state_to_str (expected), ndmp9_mover_state_to_str (ms->state)); goto fail; } what = "reason"; switch (ms->state) { case NDMP9_MOVER_STATE_PAUSED: if (ms->pause_reason != (ndmp9_mover_pause_reason)reason) { snprintf (errbuf, sizeof(errbuf), "expected %s got %s", ndmp9_mover_pause_reason_to_str (reason), ndmp9_mover_pause_reason_to_str (ms->pause_reason)); goto fail; } break; case NDMP9_MOVER_STATE_HALTED: if (ms->halt_reason != (ndmp9_mover_halt_reason)reason) { snprintf (errbuf, sizeof(errbuf), "expected %s got %s", ndmp9_mover_halt_reason_to_str (reason), ndmp9_mover_halt_reason_to_str (ms->halt_reason)); goto fail; } break; default: break; } /* test passed */ ndmca_test_close (sess); return 0; fail: /* test failed */ snprintf(tmpbuf, sizeof(tmpbuf), "%s: %s", what, errbuf); ndmca_test_fail(sess, tmpbuf); ndmca_test_close (sess); return -1; } #define NDMTEST_CALL(CONN) ndmca_test_call(CONN, xa, expect_err); int ndmca_test_mover_get_state (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_get_state (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_listen (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_addr_type addr_type, ndmp9_mover_mode mode) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; /* close previous test if there is one */ ndmca_test_close (sess); switch (conn->protocol_version) { default: return -1234; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_mover_listen, NDMP2VER) request->mode = mode; request->addr_type = addr_type; rc = NDMTEST_CALL(conn); if (rc) return rc; if (expect_err == NDMP9_NO_ERR && request->addr_type != reply->mover.addr_type) { /* TODO: use proper test format */ ndmalogf (sess, "Test", 1, "MOVER_LISTEN addr_type mismatch"); return -1; } ndmp_2to9_mover_addr (&reply->mover, &ca->mover_addr); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_mover_listen, NDMP3VER) request->mode = mode; request->addr_type = addr_type; rc = NDMTEST_CALL(conn); if (rc) return rc; if (expect_err == NDMP9_NO_ERR && request->addr_type != reply->data_connection_addr.addr_type) { /* TODO: use proper test format */ ndmalogf (sess, "Test", 1, "MOVER_LISTEN addr_type mismatch"); return -1; } ndmp_3to9_addr (&reply->data_connection_addr, &ca->mover_addr); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_mover_listen, NDMP4VER) request->mode = mode; request->addr_type = addr_type; rc = NDMTEST_CALL(conn); if (rc) return rc; if (expect_err == NDMP9_NO_ERR && request->addr_type != reply->connect_addr.addr_type) { /* TODO: use proper test format */ ndmalogf (sess, "Test", 1, "MOVER_LISTEN addr_type mismatch"); return -1; } ndmp_4to9_addr (&reply->connect_addr, &ca->mover_addr); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } int ndmca_test_mover_continue (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_continue (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_abort (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_abort (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_stop (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_stop (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_set_window (struct ndm_session *sess, ndmp9_error expect_err, uint64_t offset, uint64_t length) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_set_window (sess, offset, length); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_read (struct ndm_session *sess, ndmp9_error expect_err, uint64_t offset, uint64_t length) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_read (sess, offset, length); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_close (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_mover_close (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_mover_set_record_size (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; /* close previous test if there is one */ ndmca_test_close (sess); switch (conn->protocol_version) { default: return -1234; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_mover_set_record_size, NDMP2VER) request->len = ca->job.record_size; rc = NDMTEST_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_mover_set_record_size, NDMP3VER) request->len = ca->job.record_size; rc = NDMTEST_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_mover_set_record_size, NDMP4VER) request->len = ca->job.record_size; rc = NDMTEST_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return rc; } #endif /* !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) */ bareos-Release-14.2.6/src/ndmp/ndma_ctst_subr.c000066400000000000000000000320711263011562700213430ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #if !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) int ndmca_test_query_conn_types (struct ndm_session *sess, struct ndmconn *ref_conn) { struct ndmconn *conn = ref_conn; struct ndm_control_agent *ca = sess->control_acb; int rc; unsigned int i; switch (conn->protocol_version) { default: return -1234; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH_VOID_REQUEST(ndmp2_config_get_mover_type, NDMP2VER) rc = NDMC_CALL(conn); if (rc) { ndmalogf (sess, "Test", 1, "GET_MOVER_TYPE failed"); return rc; } for (i = 0; i < reply->methods.methods_len; i++) { switch(reply->methods.methods_val[i]) { case NDMP2_ADDR_LOCAL: ca->has_local_addr = 1; break; case NDMP2_ADDR_TCP: ca->has_tcp_addr = 1; break; default: break; } } NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH_VOID_REQUEST(ndmp3_config_get_connection_type, NDMP3VER) rc = NDMC_CALL(conn); if (rc) { ndmalogf (sess, "Test", 1, "GET_CONNECTION_TYPE failed"); return rc; } for (i = 0; i < reply->addr_types.addr_types_len; i++) { switch(reply->addr_types.addr_types_val[i]) { case NDMP3_ADDR_LOCAL: ca->has_local_addr = 1; break; case NDMP3_ADDR_TCP: ca->has_tcp_addr = 1; break; default: break; } } NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH_VOID_REQUEST(ndmp4_config_get_connection_type, NDMP4VER) rc = NDMC_CALL(conn); if (rc) { ndmalogf (sess, "Test", 1, "GET_CONNECTION_TYPE failed"); return rc; } for (i = 0; i < reply->addr_types.addr_types_len; i++) { switch(reply->addr_types.addr_types_val[i]) { case NDMP4_ADDR_LOCAL: ca->has_local_addr = 1; break; case NDMP4_ADDR_TCP: ca->has_tcp_addr = 1; break; default: break; } } NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return 0; } int ndmca_test_load_tape (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; int rc; ca->tape_mode = NDMP9_TAPE_READ_MODE; ca->is_label_op = 1; rc = ndmca_op_robot_startup (sess, 1); if (rc) return rc; rc = ndmca_connect_tape_agent(sess); if (rc) { ndmconn_destruct (sess->plumb.tape); sess->plumb.tape = NULL; return rc; /* already tattled */ } rc = ndmca_media_load_first (sess); if (rc) return rc; ndmca_tape_close (sess); return 0; } int ndmca_test_unload_tape (struct ndm_session *sess) { ndmca_tape_open (sess); ndmca_media_unload_current(sess); return 0; } int ndmca_test_check_expect_errs (struct ndmconn *conn, int rc, ndmp9_error expect_errs[]) { struct ndm_session *sess = conn->context; int protocol_version = conn->protocol_version; struct ndmp_xa_buf *xa = &conn->call_xa_buf; unsigned msg = xa->request.header.message; char * msgname = ndmp_message_to_str (protocol_version, msg); ndmp9_error reply_error = conn->last_reply_error; int i; /* make sure we have a 'test' active */ ndmca_test_open (sess, msgname, ndmp9_error_to_str (expect_errs[0])); if (rc >= 0) { /* Call succeeded. Body valid */ rc = 1; for (i = 0; (int)expect_errs[i] >= 0; i++) { if (reply_error == expect_errs[i]) { rc = 0; break; } } if (rc) { if (reply_error != NDMP9_NO_ERR && expect_errs[0] != NDMP9_NO_ERR) { /* both are errors, don't be picky */ rc = 2; } else { /* intolerable mismatch */ } } else { /* Worked as expected */ } } if (rc != 0) { char tmpbuf[128]; for (i = 0; (int)expect_errs[i] >= 0; i++) { ndmalogf (sess, "Test", 1, "%s #%d -- .... %s %s", sess->control_acb->test_phase, sess->control_acb->test_step, (i==0) ? "expected" : "or", ndmp9_error_to_str (expect_errs[i])); } snprintf(tmpbuf, sizeof(tmpbuf), "got %s (error expected)", ndmp9_error_to_str (reply_error)); if (rc == 2) ndmca_test_warn (sess, tmpbuf); else ndmca_test_fail (sess, tmpbuf); ndma_tattle (conn, xa, rc); if (rc == 2) rc = 0; } return rc; } int ndmca_test_check_expect (struct ndmconn *conn, int rc, ndmp9_error expect_err) { ndmp9_error errs[2]; errs[0] = expect_err; errs[1] = -1; return ndmca_test_check_expect_errs (conn, rc, errs); } int ndmca_test_check_expect_no_err (struct ndmconn *conn, int rc) { return ndmca_test_check_expect (conn, rc, NDMP9_NO_ERR); } int ndmca_test_check_expect_illegal_state (struct ndmconn *conn, int rc) { return ndmca_test_check_expect (conn, rc, NDMP9_ILLEGAL_STATE_ERR); } int ndmca_test_check_expect_illegal_args (struct ndmconn *conn, int rc) { return ndmca_test_check_expect (conn, rc, NDMP9_ILLEGAL_ARGS_ERR); } int ndmca_test_call (struct ndmconn *conn, struct ndmp_xa_buf *xa, ndmp9_error expect_err) { struct ndm_session *sess = conn->context; int protocol_version = conn->protocol_version; unsigned msg = xa->request.header.message; char * msgname = ndmp_message_to_str (protocol_version, msg); unsigned reply_error; int rc; /* close previous test if there is one */ ndmca_test_close (sess); /* open new 'test' */ ndmca_test_open (sess, msgname, ndmp9_error_to_str (expect_err)); rc = ndma_call_no_tattle (conn, xa); reply_error = ndmnmb_get_reply_error (&xa->reply); if (rc >= 0) { /* Call succeeded. Body valid */ if (reply_error == expect_err) { /* Worked exactly as expected */ rc = 0; } else if (reply_error != NDMP9_NO_ERR && expect_err != NDMP9_NO_ERR) { /* both are errors, don't be picky about the codes */ rc = 2; } else { /* intolerable mismatch */ rc = 1; } } if (rc != 0) { char tmpbuf[128]; snprintf(tmpbuf, sizeof(tmpbuf), "got %s (call)", ndmp9_error_to_str (reply_error)); if (rc == 2) ndmca_test_warn (sess, tmpbuf); else ndmca_test_fail (sess, tmpbuf); ndma_tattle (conn, xa, rc); if (rc == 2) rc = 0; } return rc; } /* * start or open a test if not already opened */ void ndmca_test_open (struct ndm_session *sess, char *test_name, char *sub_test_name) { static char test_name_buf[512]; if (sess->control_acb->active_test == 0) { /* record name */ if (sub_test_name) snprintf(test_name_buf, sizeof(test_name_buf), "%s/%s", test_name, sub_test_name); else strcpy(test_name_buf, test_name); sess->control_acb->active_test = test_name_buf; /* make sure flags are cleared */ sess->control_acb->active_test_failed = (char *)0; sess->control_acb->active_test_warned = (char *)0; } } void ndmca_test_warn (struct ndm_session *sess, char *warn_msg) { static char warn_msg_buf[512]; ndmca_test_open (sess, "UNKNOWN WARN", 0); strcpy(warn_msg_buf, warn_msg); sess->control_acb->active_test_warned = warn_msg_buf; } void ndmca_test_fail (struct ndm_session *sess, char *fail_msg) { static char fail_msg_buf[512]; ndmca_test_open (sess, "UNKNOWN FAIL", 0); strcpy(fail_msg_buf, fail_msg); sess->control_acb->active_test_failed = fail_msg_buf; } /* * close or end a test if not already closed */ void ndmca_test_close (struct ndm_session *sess) { if (sess->control_acb->active_test != 0) { /* count test */ sess->control_acb->n_step_tests++; /* display results */ if (sess->control_acb->active_test_failed) { ndmalogf (sess, "Test", 1, "%s #%d -- Failed %s %s", sess->control_acb->test_phase, sess->control_acb->test_step, sess->control_acb->active_test, sess->control_acb->active_test_failed); sess->control_acb->n_step_fail++; exit(1); } else if (sess->control_acb->active_test_warned) { ndmalogf (sess, "Test", 1, "%s #%d -- Almost %s %s", sess->control_acb->test_phase, sess->control_acb->test_step, sess->control_acb->active_test, sess->control_acb->active_test_warned); sess->control_acb->n_step_warn++; exit(1); } else { ndmalogf (sess, "Test", 2, "%s #%d -- Passed %s", sess->control_acb->test_phase, sess->control_acb->test_step, sess->control_acb->active_test); sess->control_acb->n_step_pass++; } /* clear flags */ sess->control_acb->active_test = (char *)0; sess->control_acb->active_test_failed = (char *)0; sess->control_acb->active_test_warned = (char *)0; /* advance test count */ sess->control_acb->test_step++; } } /* * start a test phase (part of a series) */ void ndmca_test_phase (struct ndm_session *sess, char *test_phase, char *desc) { ndmalogf (sess, "TEST", 0, "Test %s -- %s", test_phase, desc); sess->control_acb->test_phase = test_phase; sess->control_acb->test_step = 1; sess->control_acb->n_step_pass = 0; sess->control_acb->n_step_fail = 0; sess->control_acb->n_step_warn = 0; sess->control_acb->n_step_tests = 0; } void ndmca_test_log_step (struct ndm_session *sess, int level, char *msg) { int had_active = (sess->control_acb->active_test != 0); ndmalogf (sess, "Test", level, "%s #%d -- %s", sess->control_acb->test_phase, sess->control_acb->test_step, msg); /* in case we have a open test -- close it */ ndmca_test_close (sess); /* advance test count if we didn't have an active test */ if (!had_active) sess->control_acb->test_step++; } void ndmca_test_log_note (struct ndm_session *sess, int level, char *msg) { ndmalogf (sess, "Test", level, "%s #%d %s", sess->control_acb->test_phase, sess->control_acb->test_step, msg); } /* * finish a test phase (part of a series) */ void ndmca_test_done_phase (struct ndm_session *sess) { struct ndm_control_agent *ca = sess->control_acb; char * status; int had_active = (sess->control_acb->active_test != 0); /* close previous test if there is one */ ndmca_test_close (sess); if (ca->n_step_fail) status = "Failed"; else if (ca->n_step_warn) status = "Almost"; else if (ca->n_step_pass > 0) status = "Passed"; else status = "Whiffed"; ndmalogf (sess, "TEST", 0, "Test %s %s -- pass=%d warn=%d fail=%d (total %d)", ca->test_phase, status, ca->n_step_pass, ca->n_step_warn, ca->n_step_fail, ca->n_step_tests); ca->total_n_step_pass += ca->n_step_pass; ca->total_n_step_warn += ca->n_step_warn; ca->total_n_step_fail += ca->n_step_fail; ca->total_n_step_tests += ca->n_step_tests; /* advance test count if we didn't have an active test so * clean up phases have a new test count */ if (!had_active) sess->control_acb->test_step++; } /* * finish a test series (which may include test phases) */ void ndmca_test_done_series (struct ndm_session *sess, char *series_name) { struct ndm_control_agent *ca = sess->control_acb; char * status; /* close previous test if there is one */ ndmca_test_close (sess); if (ca->total_n_step_fail) status = "Failed"; else if (ca->total_n_step_warn) status = "Almost"; else status = "Passed"; ndmalogf (sess, "TEST", 0, "FINAL %s %s -- pass=%d warn=%d fail=%d (total %d)", series_name, status, ca->total_n_step_pass, ca->total_n_step_warn, ca->total_n_step_fail, ca->total_n_step_tests); } void ndmca_test_fill_data (char *buf, int bufsize, int recno, int fileno) { char * src; char * srcend; char * dst = buf; char * dstend = buf+bufsize; uint16_t sequence = 0; struct { uint16_t fileno; uint16_t sequence; uint32_t recno; } x; x.fileno = fileno; x.recno = recno; srcend = (char *) &x; srcend += sizeof x; while (dst < dstend) { x.sequence = sequence++; src = (char *) &x; while (src < srcend && dst < dstend) *dst++ = *src++; } } #endif /* !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) */ bareos-Release-14.2.6/src/ndmp/ndma_ctst_tape.c000066400000000000000000000754161263011562700213330ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * ***************************************************************** * * NDMP Elements of a test-tape session * * +-----+ ########### * | Job |----># CONTROL # * +-----+ # Agent # * # # * ########### * | | * | +---------------------+ * control | connections | * V V * ############ +-------+ ######### * # TAPE # | | # ROBOT # * # Agent # | ROBOT |<-># Agent # * # # |+-----+| # # * # ======|DRIVE|| # # * # # |+-----+| # # * ############ +-------+ ######### * **************************************************************** */ #include "ndmagents.h" #if !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) extern int ndmca_tt_wrapper (struct ndm_session *sess, int (*func)(struct ndm_session *sess)); extern int ndmca_op_test_tape (struct ndm_session *sess); extern int ndmca_tt_openclose (struct ndm_session *sess); extern int ndmca_tt_basic_getstate (struct ndm_session *sess); extern int ndmca_tt_basic_write (struct ndm_session *sess); extern int ndmca_tt_basic_read (struct ndm_session *sess); extern int ndmca_tt_basic_write_and_read (struct ndm_session *sess); extern int ndmca_tt_write (struct ndm_session *sess); extern int ndmca_tt_read (struct ndm_session *sess); extern int ndmca_tt_mtio (struct ndm_session *sess); extern int ndmca_tt_check_fileno_recno (struct ndm_session *sess, char *what, uint32_t file_num, uint32_t blockno, char *note); extern int ndmca_test_tape_open (struct ndm_session *sess, ndmp9_error expect_err, char *device, int mode); extern int ndmca_test_tape_close (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_tape_get_state (struct ndm_session *sess, ndmp9_error expect_err); extern int ndmca_test_tape_mtio (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid); extern int ndmca_check_tape_mtio (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_tape_mtio_op op, uint32_t count, uint32_t resid); extern int ndmca_test_tape_write (struct ndm_session *sess, ndmp9_error expect_err, char *buf, unsigned count); extern int ndmca_test_tape_read (struct ndm_session *sess, ndmp9_error expect_err, char *buf, unsigned count); extern int ndmca_test_tape_read_2cnt (struct ndm_session *sess, ndmp9_error expect_err, char *buf, unsigned count, unsigned true_count); struct series { unsigned n_rec; unsigned recsize; }; struct series tt_series[] = { { 1, 512 }, { 100, 1024 }, { 1, 512 }, { 100, 139 }, { 1, 512 }, { 99, 10240 }, { 1, 512 }, { 3, 32768 }, { 1, 512 }, { 0 } }; int ndmca_op_test_tape (struct ndm_session *sess) { struct ndmconn * conn; int (*save_call) (struct ndmconn *conn, struct ndmp_xa_buf *xa); int rc; rc = ndmca_test_load_tape (sess); if (rc) return rc; conn = sess->plumb.tape; save_call = conn->call; conn->call = ndma_call_no_tattle; if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_openclose); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_getstate); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_write); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_read); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_write_and_read); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_write); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_read); if (rc == 0) rc = ndmca_tt_wrapper (sess, ndmca_tt_mtio); ndmca_test_unload_tape (sess); ndmca_test_done_series (sess, "test-tape"); conn->call = save_call; return 0; } int ndmca_tt_wrapper (struct ndm_session *sess, int (*func)(struct ndm_session *sess)) { int rc; rc = (*func)(sess); if (rc != 0) { ndmalogf (sess, "Test", 1, "Failure"); } ndmca_test_done_phase (sess); /* clean up mess */ ndmca_test_log_note (sess, 2, "Cleaning up..."); ndmca_tape_open (sess); /* Open the tape, OK if already opened */ ndmca_tape_mtio (sess, NDMP9_MTIO_REW, 1, 0); rc = ndmca_tape_close (sess); /* close, collective error */ if (rc != 0) { ndmca_test_log_note (sess, 0, "Cleaning up failed, quiting"); } else { ndmca_test_log_note (sess, 2, "Cleaning up done"); } return rc; } int ndmca_tt_openclose (struct ndm_session *sess) { int rc; ndmca_test_phase (sess, "T-OC", "Tape Open/Close"); rc = ndmca_test_tape_close (sess, NDMP9_DEV_NOT_OPEN_ERR); if (rc) return rc; rc = ndmca_test_tape_open (sess, NDMP9_NO_DEVICE_ERR, "bogus", NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_open (sess, NDMP9_ILLEGAL_ARGS_ERR, 0, 123); if (rc) return rc; rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_tape_open (sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; rc = ndmca_test_tape_open (sess, NDMP9_DEVICE_OPENED_ERR, 0, NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; /* pass */ } int ndmca_tt_basic_getstate (struct ndm_session *sess) { int rc; ndmca_test_phase (sess, "T-BGS", "Tape Get State Basics"); rc = ndmca_test_tape_get_state (sess, NDMP9_DEV_NOT_OPEN_ERR); if (rc) return rc; rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_get_state (sess, NDMP9_NO_ERR); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; /* pass */ } /* * Precedes tt_basic_read() so that we can make a "known" tape. */ int ndmca_tt_basic_write (struct ndm_session *sess) { int rc, ix; char buf[1024]; ndmp9_error expect_errs[5]; ndmca_test_phase (sess, "T-BW", "Tape Write Basics"); rc = ndmca_test_tape_write (sess, NDMP9_DEV_NOT_OPEN_ERR, buf, 1024); if (rc) return rc; /* * Write w/ read-only open mode */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_write (sess, NDMP9_PERMISSION_ERR, buf, 1024); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * Write w/ bogus lengths */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; /* OPEN Question: what does len==0 mean? */ /* write/len=0 MUST be NDMP[234]_NO_ERR or NDMP[234]_ILLEGAL_ARGS */ /* write/len=0 MUST be NDMP4_NO_ERR */ ix = 0; if (sess->plumb.tape->protocol_version < 5) { expect_errs[ix++] = NDMP9_ILLEGAL_ARGS_ERR; } expect_errs[ix++] = NDMP9_NO_ERR; expect_errs[ix++] = -1; rc = ndmca_tape_write (sess, buf, 0); rc = ndmca_test_check_expect_errs (sess->plumb.tape, rc, expect_errs); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * TODO: bogus length */ /* * Write works */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; rc = ndmca_test_tape_write (sess, NDMP9_NO_ERR, buf, 1024); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_EOF, 1, 0); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; /* pass */ } /* * Assumes tt_basic_write() passed. Uses resulting tape. */ int ndmca_tt_basic_read (struct ndm_session *sess) { int rc, ix; char buf[2048]; ndmp9_error expect_errs[5]; ndmca_test_phase (sess, "T-BR", "Tape Read Basics"); rc = ndmca_test_tape_read (sess, NDMP9_DEV_NOT_OPEN_ERR, buf, 1024); if (rc) return rc; /* * Read w/ bogus lengths -- mode=READ_MODE */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; /* read/len=0 MUST be NDMP[23]_NO_ERR or NDMP[23]_ILLEGAL_ARGS */ /* read/len=0 MUST be NDMP4_NO_ERR */ ix = 0; if (sess->plumb.tape->protocol_version < 4) { expect_errs[ix++] = NDMP9_ILLEGAL_ARGS_ERR; } expect_errs[ix++] = NDMP9_NO_ERR; expect_errs[ix++] = -1; rc = ndmca_tape_read (sess, buf, 0); rc = ndmca_test_check_expect_errs (sess->plumb.tape, rc, expect_errs); if (rc) return rc; rc = ndmca_test_tape_read(sess,NDMP9_ILLEGAL_ARGS_ERR,buf,0x80000000); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * Read works -- mode=WRITE_MODE (just to mix it up) */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; rc = ndmca_test_tape_read (sess, NDMP9_NO_ERR, buf, 1024); if (rc) return rc; rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * Read works w/ oversize -- mode=READ_MODE (just to mix it up) */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_read_2cnt (sess, NDMP9_NO_ERR, buf, 2048, 1024); if (rc) return rc; rc = ndmca_test_tape_read_2cnt (sess, NDMP9_EOF_ERR, buf, 2048, 1024); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * Read works w/ undersize -- mode=READ_MODE (just to mix it up) */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_read_2cnt (sess, NDMP9_NO_ERR, buf, 512, 512); if (rc) return rc; rc = ndmca_test_tape_read_2cnt (sess, NDMP9_EOF_ERR, buf, 512, 512); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; /* pass */ } #define CHECK_FILENO_RECNO(WHAT,FILENO,RECNO) { \ what = WHAT; \ rc = ndmca_tt_check_fileno_recno (sess, \ WHAT, FILENO, RECNO, note); \ if (rc) return -1; \ } /* * Assumes tt_basic_read() and tt_basic_write() have been done verifying * READ and WRITE operations work... */ int ndmca_tt_basic_write_and_read (struct ndm_session *sess) { int rc, i, f, pass; char buf[64*1024]; char *p; ndmca_test_phase (sess, "T-BWR", "Tape Write and Read Basics"); /* * check EOF and EOM by rewinding and putting on 1 EOF mark */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSR, 100, 100); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSF, 100, 100); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_EOF, 1, 0); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSF, 100, 99); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSF, 100, 99); if (rc) return rc; /* we are at EOM */ if (sess->plumb.tape->protocol_version < 4) { rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, sizeof(buf)); if (rc) return rc; /* check it again */ rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024); if (rc) return rc; } else { rc = ndmca_test_tape_read (sess, NDMP9_EOM_ERR, buf, sizeof(buf)); if (rc) return rc; /* check it again */ rc = ndmca_test_tape_read (sess, NDMP9_EOM_ERR, buf, 1024); if (rc) return rc; } /* rewind and place 1 record in tape -- no EOF marker by seeking */ rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_write (sess, NDMP9_NO_ERR, buf, 512); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSR, 100, 99); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSR, 100, 99); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSR, 100, 100); if (rc) return rc; rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSF, 100, 100); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * perform tape label type processing with positioning ops */ for(pass = 0; pass < 2; pass++) { /* * open the tape and write 1 record and close it */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; for(p = buf, i = 0; i < 1024; i++, p++) *p = ((i - 4) & 0xff); rc = ndmca_test_tape_write (sess, NDMP9_NO_ERR, buf, 1024); if (rc) return rc; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_EOF, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; /* * open the tape and read it */ rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; if (pass == 1) rc = ndmca_test_tape_read_2cnt (sess, NDMP9_NO_ERR, buf, sizeof(buf), 1024); else rc = ndmca_test_tape_read (sess, NDMP9_NO_ERR, buf, 1024); if (rc) return rc; for(p = buf, f = i = 0; f < 64 && i < 1024; i++, p++) if (*p != ((i - 4) & 0xff)) { char tmp[80]; snprintf (tmp, sizeof(tmp), "%d: 0x%x => 0x%x", i, ((i - 4) & 0xff), *p); ndmalogf (sess, "DATA", 6, tmp); f++; } if (f > 0) { ndmca_test_fail (sess, "Failed compare"); return -1; } rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024); if (rc) return rc; /* check EOM */ if (sess->plumb.tape->protocol_version < 4) { rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024); if (rc) return rc; } else { /* skip over filemark */ rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, 1, 0); /* read EOM */ rc = ndmca_test_tape_read (sess, NDMP9_EOM_ERR, buf, 1024); if (rc) return rc; } rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; } return 0; /* pass */ } /* * Precedes tt_read() so that we can make a "known" tape. */ int ndmca_tt_write (struct ndm_session *sess) { int rc; unsigned n_rec; unsigned recsize; unsigned fileno, recno; char * what; char note[128]; char buf[64*1024]; ndmca_test_phase (sess, "T-WRITE", "Tape Write Series"); rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE); if (rc) return rc; for (fileno = 0; tt_series[fileno].n_rec > 0; fileno++) { n_rec = tt_series[fileno].n_rec; recsize = tt_series[fileno].recsize; snprintf (note, sizeof(note), "Write tape file %d", fileno+1); ndmca_test_open (sess, note, 0); snprintf (note, sizeof(note), "file #%d, %d records, %d bytes/rec", fileno+1, n_rec, recsize); ndmca_test_log_note (sess, 2, note); for (recno = 0; recno < n_rec; recno++) { ndmca_test_fill_data (buf, recsize, recno, fileno); what = "write"; rc = ndmca_tape_write (sess, buf, recsize); if (rc) goto fail; CHECK_FILENO_RECNO ("write", fileno, recno+1); } what = "write filemark"; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_EOF, 1, 0); if (rc) goto fail; CHECK_FILENO_RECNO ("wfm", fileno+1, 0); /* no test calls so the file operation is the test */ snprintf (buf, sizeof(buf), "Passed tape write %s", note); ndmca_test_log_step (sess, 2, buf); } rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; fail: snprintf (buf, sizeof(buf), "Failed %s recno=%d; %s", what, recno, note); ndmca_test_fail (sess, buf); return -1; } /* * Assumes tt_write() passed */ int ndmca_tt_read (struct ndm_session *sess) { int rc; unsigned n_rec; unsigned recsize; unsigned fileno, recno; char * what; char note[128]; char pbuf[64*1024]; char buf[64*1024]; ndmca_test_phase (sess, "T-READ", "Tape Read Series"); rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; for (fileno = 0; tt_series[fileno].n_rec > 0; fileno++) { n_rec = tt_series[fileno].n_rec; recsize = tt_series[fileno].recsize; snprintf (note, sizeof(note), "Read tape file %d", fileno+1); ndmca_test_open (sess, note, 0); snprintf (note, sizeof(note), "file #%d, %d records, %d bytes/rec", fileno+1, n_rec, recsize); ndmca_test_log_note (sess, 2, note); for (recno = 0; recno < n_rec; recno++) { ndmca_test_fill_data (pbuf, recsize, recno, fileno); what = "read"; rc = ndmca_tape_read (sess, buf, recsize); if (rc) goto fail; CHECK_FILENO_RECNO ("read", fileno, recno+1); what = "compare"; #if 0 if (bcmp (buf, pbuf, recsize) != 0) goto fail; #else if (bcmp (buf, pbuf, recsize) != 0) { unsigned char *expect_p = (unsigned char *)pbuf; unsigned char *got_p = (unsigned char *)buf; unsigned int i, f; for(f = i = 0; f < 64 && i < recsize; i++, expect_p++, got_p++) { if (*expect_p != *got_p) { char tmp[80]; snprintf (tmp, sizeof(tmp), "%d: 0x%x => 0x%x", i, *expect_p, *got_p); ndmalogf (sess, "DATA", 6, tmp); f++; } } goto fail; } #endif } what = "eof read"; rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, recsize); if (rc) goto fail; if (sess->plumb.tape->protocol_version > 3) { CHECK_FILENO_RECNO ("eof", fileno, -1); what = "skip filemark"; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, 1, 0); if (rc) goto fail; CHECK_FILENO_RECNO ("skip", fileno+1, 0); } else { CHECK_FILENO_RECNO ("eof", fileno+1, 0); } snprintf (buf, sizeof(buf), "Passed tape read %s", note); ndmca_test_log_step (sess, 2, buf); } rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; fail: snprintf (buf, sizeof(buf), "Failed %s recno=%d; %s", what, recno, note); ndmca_test_fail (sess, buf); return -1; } /* * Assumes tt_write() passed */ int ndmca_tt_mtio (struct ndm_session *sess) { int rc; unsigned n_rec; unsigned recsize; unsigned fileno, recno; uint32_t count, resid; char * what; char note[128]; char pbuf[64*1024]; char buf[64*1024]; ndmca_test_phase (sess, "T-MTIO", "Tape MTIO"); rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE); if (rc) return rc; rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0); if (rc) return rc; for (fileno = 0; tt_series[fileno].n_rec > 0; fileno++) { n_rec = tt_series[fileno].n_rec; recsize = tt_series[fileno].recsize; snprintf (note, sizeof(note), "Seek around tape file %d", fileno+1); ndmca_test_open (sess, note, 0); snprintf (note, sizeof(note), "file #%d, %d records, %d bytes/rec", fileno+1, n_rec, recsize); ndmca_test_log_note (sess, 2, note); what = "rew"; count = 1; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_REW, count, &resid); if (rc) goto fail; what = "rew resid"; if (resid != 0) goto fail; CHECK_FILENO_RECNO ("rew", 0, 0); what = "fsf(n)"; count = fileno; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, count, &resid); if (rc) goto fail; what = "fsf(n) resid"; if (resid != 0) goto fail; CHECK_FILENO_RECNO ("fsf", fileno, 0); what = "fsr(1m)"; count = 1000000; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSR, count, &resid); if (rc) goto fail; what = "fsr(1m) resid"; if (n_rec + resid != count) goto fail; if (sess->plumb.tape->protocol_version < 4) { CHECK_FILENO_RECNO ("fsr(1m)", fileno + 1, 0); what = "bsf 1 after fsr(1m)"; count = 1; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_BSF, count, 0); if (rc) goto fail; CHECK_FILENO_RECNO (what, fileno, -1); recno = n_rec; } else { /* EOT side of EOF marker */ recno = n_rec; CHECK_FILENO_RECNO ("fsr(1m)", fileno, recno); } what = "bsr(1m)"; count = 1000000; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_BSR, count, &resid); if (rc) goto fail; what = "bsr(1m) resid"; if (n_rec + resid != count) goto fail; if ((fileno > 0) && (sess->plumb.tape->protocol_version < 4)) { /* at BOT side of EOF marker (not BOT) */ CHECK_FILENO_RECNO ("bsr(1m)", fileno - 1, -1); what = "fsf 1 after bsr(1m)"; count = 1; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, count, 0); if (rc) goto fail; } recno = 0; CHECK_FILENO_RECNO ("bsr(1m)", fileno, recno); what = "fsr(0)"; count = 0; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSR, count, &resid); if (rc) goto fail; what = "fsr(0) resid"; if (resid != 0) goto fail; recno = 0; CHECK_FILENO_RECNO ("fsr(0)", fileno, recno); what = "fsr(x)"; count = n_rec / 2; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSR, count, &resid); if (rc) goto fail; what = "fsr(x) resid"; if (resid != 0) goto fail; recno = n_rec / 2; CHECK_FILENO_RECNO ("fsr(x)", fileno, recno); what = "fsr(x) read"; rc = ndmca_tape_read (sess, buf, recsize); if (rc) goto fail; what = "fsr(x) compare"; ndmca_test_fill_data (pbuf, recsize, recno, fileno); if (bcmp (buf, pbuf, recsize) != 0) goto fail; recno++; /* caused by tape_read */ if (recno > 1) { what = "bsr(2)"; count = 2; rc = ndmca_tape_mtio (sess, NDMP9_MTIO_BSR, count, &resid); if (rc) goto fail; what = "bsr(2) resid"; if (resid != 0) goto fail; recno -= count; CHECK_FILENO_RECNO ("bsr(2)", fileno, recno); what = "bsr(2) read"; rc = ndmca_tape_read (sess, buf, recsize); if (rc) goto fail; what = "bsr(2) compare"; ndmca_test_fill_data (pbuf, recsize, recno, fileno); if (bcmp (buf, pbuf, recsize) != 0) goto fail; } snprintf (buf, sizeof(buf), "Passed %s", note); ndmca_test_log_step (sess, 2, buf); } rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR); if (rc) return rc; return 0; fail: snprintf (buf, sizeof(buf), "Failed %s: %s", what, note); ndmca_test_fail (sess, buf); return -1; } /* * Check the tape_state accurately reflects position */ int ndmca_tt_check_fileno_recno (struct ndm_session *sess, char *what, uint32_t file_num, uint32_t blockno, char *note) { struct ndm_control_agent *ca = sess->control_acb; struct ndmp9_tape_get_state_reply *ts = 0; char buf[100]; int rc; char * oper; oper ="get_state"; rc = ndmca_tape_get_state (sess); if (rc) goto fail; ts = &ca->tape_state; oper = "check file_num"; if (ts->file_num.value != file_num) goto fail; oper = "check blockno"; if ((ts->blockno.value != blockno) && (ts->blockno.value != NDMP9_INVALID_U_LONG)) goto fail; return 0; fail: snprintf (buf, sizeof(buf), "Failed %s while testing %s", oper, what); ndmca_test_log_note (sess, 1, buf); if (ts) { snprintf (buf, sizeof(buf), " expect file_num=%ld got file_num=%ld", (long)file_num, (long)ts->file_num.value); ndmca_test_log_note (sess, 1, buf); snprintf (buf, sizeof(buf), " expect blockno=%ld got blockno=%ld", (long)blockno, (long)ts->blockno.value); ndmca_test_log_note (sess, 1, buf); } snprintf (buf, sizeof(buf), " note: %s", note); ndmca_test_fail (sess, buf); return -1; } #define NDMTEST_CALL(CONN) ndmca_test_call(CONN, xa, expect_err); int ndmca_test_tape_open (struct ndm_session *sess, ndmp9_error expect_err, char *device, int mode) { struct ndmconn * conn = sess->plumb.tape; struct ndm_control_agent *ca = sess->control_acb; int rc; /* close previous test if there is one */ ndmca_test_close (sess); switch (conn->protocol_version) { default: return -1234; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH (ndmp2_tape_open, NDMP2VER) if (device) request->device.name = device; else request->device.name = ca->job.tape_device; if (mode != -1) request->mode = mode; else request->mode = ca->tape_mode; rc = NDMTEST_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH (ndmp3_tape_open, NDMP3VER) if (device) request->device = device; else request->device = ca->job.tape_device; if (mode != -1) request->mode = mode; else request->mode = ca->tape_mode; rc = NDMTEST_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH (ndmp4_tape_open, NDMP4VER) if (device) request->device = device; else request->device = ca->job.tape_device; if (mode != -1) request->mode = mode; else request->mode = ca->tape_mode; rc = NDMTEST_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return rc; } int ndmca_test_tape_close (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_tape_close (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_tape_get_state (struct ndm_session *sess, ndmp9_error expect_err) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_tape_get_state (sess); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_tape_mtio (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_tape_mtio (sess, op, count, resid); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_check_tape_mtio (struct ndm_session *sess, ndmp9_error expect_err, ndmp9_tape_mtio_op op, uint32_t count, uint32_t resid) { struct ndmconn * conn = sess->plumb.tape; uint32_t got_resid; int rc; /* close previous test if there is one */ ndmca_test_close (sess); got_resid = ~resid; rc = ndmca_tape_mtio (sess, op, count, &got_resid); rc = ndmca_test_check_expect (conn, rc, expect_err); if (rc) return rc; if (resid != got_resid) { char tmp[128]; snprintf (tmp, sizeof(tmp), "Residual incorrect, got %lu expected %lu", got_resid, resid); ndmca_test_fail (sess, tmp); return -1; } return rc; } int ndmca_test_tape_write (struct ndm_session *sess, ndmp9_error expect_err, char *buf, unsigned count) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_tape_write (sess, buf, count); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_tape_read (struct ndm_session *sess, ndmp9_error expect_err, char *buf, unsigned count) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); rc = ndmca_tape_read (sess, buf, count); rc = ndmca_test_check_expect (conn, rc, expect_err); return rc; } int ndmca_test_tape_read_2cnt (struct ndm_session *sess, ndmp9_error expect_err, char *buf, unsigned count, unsigned true_count) { struct ndmconn * conn = sess->plumb.tape; int rc; /* close previous test if there is one */ ndmca_test_close (sess); switch (conn->protocol_version) { default: return -1234; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_tape_read, NDMP2VER) request->count = count; rc = NDMTEST_CALL(conn); if (rc == 0 && expect_err == NDMP9_NO_ERR) { if (reply->data_in.data_in_len == true_count) { bcopy (reply->data_in.data_in_val, buf, true_count); } else { rc = -1; } } NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_tape_read, NDMP3VER) request->count = count; rc = NDMTEST_CALL(conn); if (rc == 0 && expect_err == NDMP9_NO_ERR) { if (reply->data_in.data_in_len == true_count) { bcopy (reply->data_in.data_in_val, buf, true_count); } else { rc = -1; } } NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_tape_read, NDMP4VER) request->count = count; rc = NDMTEST_CALL(conn); if (rc == 0 && expect_err == NDMP9_NO_ERR) { if (reply->data_in.data_in_len == true_count) { bcopy (reply->data_in.data_in_val, buf, true_count); } else { rc = -1; } } NDMC_FREE_REPLY(); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return rc; } #endif /* !defined(NDMOS_OPTION_NO_CONTROL_AGENT) && !defined(NDMOS_OPTION_NO_TEST_AGENTS) */ bareos-Release-14.2.6/src/ndmp/ndma_data.c000066400000000000000000000525371263011562700202550ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #include "wraplib.h" #ifndef NDMOS_OPTION_NO_DATA_AGENT /* * Initialization and Cleanup **************************************************************** */ /* Initialize -- Set data structure to know value, ignore current value */ int ndmda_initialize (struct ndm_session *sess) { sess->data_acb = NDMOS_API_MALLOC (sizeof(struct ndm_data_agent)); if (!sess->data_acb) return -1; NDMOS_MACRO_ZEROFILL (sess->data_acb); sess->data_acb->data_state.state = NDMP9_DATA_STATE_IDLE; ndmchan_initialize (&sess->data_acb->formatter_error, "dfp-error"); ndmchan_initialize (&sess->data_acb->formatter_wrap, "dfp-wrap"); ndmchan_initialize (&sess->data_acb->formatter_image, "dfp-image"); ndmda_fh_initialize (sess); return 0; } /* Commission -- Get agent ready. Entire session has been initialize()d */ int ndmda_commission (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; da->data_state.state = NDMP9_DATA_STATE_IDLE; ndmda_fh_commission (sess); return 0; } /* Decommission -- Discard agent */ int ndmda_decommission (struct ndm_session *sess) { ndmis_data_close (sess); ndmda_purge_environment (sess); ndmda_purge_nlist (sess); ndmda_fh_decommission (sess); NDMOS_API_BZERO (sess->data_acb->bu_type,sizeof sess->data_acb->bu_type); ndmda_commission (sess); return 0; } /* Destroy -- destroy agent */ int ndmda_destroy (struct ndm_session *sess) { if (!sess->data_acb) { return 0; } if (sess->data_acb->fmt_image_buf) { NDMOS_API_FREE (sess->data_acb->fmt_image_buf); } if (sess->data_acb->fmt_error_buf) { NDMOS_API_FREE (sess->data_acb->fmt_error_buf); } if (sess->data_acb->fmt_wrap_buf) { NDMOS_API_FREE (sess->data_acb->fmt_wrap_buf); } ndmda_fh_destroy (sess); NDMOS_API_FREE (sess->data_acb); sess->data_acb = NULL; return 0; } /* Belay -- Cancel partially issued activation/start */ int ndmda_belay (struct ndm_session *sess) { ndmda_fh_belay (sess); return ndmda_decommission (sess); } /* * Semantic actions -- called from ndma_dispatch() **************************************************************** */ static int add_env (struct ndm_env_table *envtab, char *cmd) { char buf[1024]; struct ndm_env_entry * entry; for (entry = envtab->head; entry; entry = entry->next) { snprintf (buf, sizeof(buf) - 1, "%s=%s", entry->pval.name, entry->pval.value); buf[sizeof(buf) - 1] = '\0'; ndmda_add_to_cmd (cmd, "-E"); ndmda_add_to_cmd (cmd, buf); } return 0; } static int add_nlist (struct ndm_nlist_table *nlisttab, char *cmd) { char buf[32]; struct ndm_nlist_entry * entry; for (entry = nlisttab->head; entry; entry = entry->next) { ndmda_add_to_cmd (cmd, entry->name.original_path); if (entry->name.fh_info.valid == NDMP9_VALIDITY_VALID) { snprintf (buf, sizeof(buf), "@%llu", entry->name.fh_info.value); ndmda_add_to_cmd (cmd, buf); } else { ndmda_add_to_cmd (cmd, "@-"); } ndmda_add_to_cmd (cmd, entry->name.destination_path); } return 0; } ndmp9_error ndmda_data_start_backup (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndmp9_error error = NDMP9_NO_ERR; char cmd[NDMDA_MAX_CMD]; strcpy (cmd, "wrap_"); strcat (cmd, da->bu_type); if (sess->param->log_level > 0) { char tmpbuf[40]; snprintf(tmpbuf, sizeof(tmpbuf), "-d%d", sess->param->log_level); ndmda_add_to_cmd (cmd, tmpbuf); } ndmda_add_to_cmd (cmd, "-c"); ndmda_add_to_cmd (cmd, "-I#3"); add_env (&da->env_tab, cmd); ndma_send_logmsg (sess, NDMP9_LOG_DEBUG, sess->plumb.data, "CMD: %s", cmd); if (ndmda_pipe_fork_exec (sess, cmd, 1) < 0) { return NDMP9_UNDEFINED_ERR; } ndmis_data_start (sess, NDMCHAN_MODE_WRITE); da->data_state.state = NDMP9_DATA_STATE_ACTIVE; da->data_state.operation = NDMP9_DATA_OP_BACKUP; return error; } ndmp9_error ndmda_data_start_recover (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndmp9_error error = NDMP9_NO_ERR; char cmd[NDMDA_MAX_CMD]; strcpy (cmd, "wrap_"); strcat (cmd, da->bu_type); if (sess->param->log_level > 0) { char tmpbuf[40]; snprintf(tmpbuf, sizeof(tmpbuf), "-d%d", sess->param->log_level); ndmda_add_to_cmd (cmd, tmpbuf); } ndmda_add_to_cmd (cmd, "-x"); ndmda_add_to_cmd (cmd, "-I#3"); add_env (&da->env_tab, cmd); add_nlist (&da->nlist_tab, cmd); ndma_send_logmsg (sess, NDMP9_LOG_DEBUG, sess->plumb.data, "CMD: %s", cmd); if (ndmda_pipe_fork_exec (sess, cmd, 0) < 0) { return NDMP9_UNDEFINED_ERR; } ndmis_data_start (sess, NDMCHAN_MODE_READ); da->data_state.state = NDMP9_DATA_STATE_ACTIVE; da->data_state.operation = NDMP9_DATA_OP_RECOVER; return error; } ndmp9_error ndmda_data_start_recover_fh (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndmp9_error error = NDMP9_NO_ERR; char cmd[NDMDA_MAX_CMD]; strcpy (cmd, "wrap_"); strcat (cmd, da->bu_type); ndmda_add_to_cmd (cmd, "-t"); ndmda_add_to_cmd (cmd, "-I#3"); add_env (&da->env_tab, cmd); add_nlist (&da->nlist_tab, cmd); ndma_send_logmsg (sess, NDMP9_LOG_DEBUG, sess->plumb.data, "CMD: %s", cmd); if (ndmda_pipe_fork_exec (sess, cmd, 0) < 0) { return NDMP9_UNDEFINED_ERR; } ndmis_data_start (sess, NDMCHAN_MODE_READ); da->data_state.state = NDMP9_DATA_STATE_ACTIVE; da->data_state.operation = NDMP9_DATA_OP_RECOVER_FILEHIST; return error; } void ndmda_sync_state (struct ndm_session *sess) { /* no-op, always accurate */ } void ndmda_data_abort (struct ndm_session *sess) { ndmda_data_halt (sess, NDMP9_DATA_HALT_ABORTED); } void ndmda_sync_environment (struct ndm_session *sess) { /* no-op, always accurate */ } ndmp9_error ndmda_data_listen (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; da->data_state.state = NDMP9_DATA_STATE_LISTEN; da->data_state.halt_reason = NDMP9_DATA_HALT_NA; return NDMP9_NO_ERR; } ndmp9_error ndmda_data_connect (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; da->data_state.state = NDMP9_DATA_STATE_CONNECTED; da->data_state.halt_reason = NDMP9_DATA_HALT_NA; return NDMP9_NO_ERR; } void ndmda_data_halt (struct ndm_session *sess, ndmp9_data_halt_reason reason) { struct ndm_data_agent * da = sess->data_acb; da->data_state.state = NDMP9_DATA_STATE_HALTED; da->data_state.halt_reason = reason; da->data_notify_pending = 1; ndmda_fh_flush (sess); ndmis_data_close (sess); ndmchan_cleanup (&da->formatter_image); ndmchan_cleanup (&da->formatter_error); ndmchan_cleanup (&da->formatter_wrap); /* this needs to be better */ if (da->formatter_pid) { sleep (1); /* give gtar a chance to stop by itself */ kill (da->formatter_pid, SIGTERM); } } void ndmda_data_stop (struct ndm_session *sess) { ndmda_decommission (sess); } /* * Quantum -- get a bit of work done **************************************************************** */ int ndmda_quantum (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; int did_something = 0; /* did nothing */ switch (da->data_state.state) { default: ndmalogf (sess, 0, 0, "BOTCH data state"); return -1; case NDMP9_DATA_STATE_IDLE: case NDMP9_DATA_STATE_HALTED: case NDMP9_DATA_STATE_CONNECTED: break; case NDMP9_DATA_STATE_LISTEN: switch (sess->plumb.image_stream->data_ep.connect_status) { case NDMIS_CONN_LISTEN: /* no connection yet */ break; case NDMIS_CONN_ACCEPTED: /* we're in business */ /* drum roll please... */ da->data_state.state = NDMP9_DATA_STATE_CONNECTED; /* tah-dah */ did_something++; /* did something */ break; case NDMIS_CONN_BOTCHED: /* accept() went south */ default: /* ain't suppose to happen */ ndmda_data_halt (sess, NDMP9_DATA_HALT_CONNECT_ERROR); did_something++; /* did something */ break; } break; case NDMP9_DATA_STATE_ACTIVE: did_something |= ndmda_quantum_stderr (sess); did_something |= ndmda_quantum_wrap (sess); did_something |= ndmda_quantum_image (sess); break; } ndmda_send_notice (sess); return did_something; } int ndmda_quantum_stderr (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmchan * ch = &da->formatter_error; int did_something = 0; char * p; char * data; char * pend; unsigned n_ready; again: n_ready = ndmchan_n_ready (ch); if (n_ready == 0) return did_something; data = p = &ch->data[ch->beg_ix]; pend = p + n_ready; while (p < pend && *p != '\n') p++; if (p < pend && *p == '\n') { *p++ = 0; ndma_send_logmsg (sess, NDMP9_LOG_NORMAL, sess->plumb.data, "%s", data); ch->beg_ix += p - data; did_something++; goto again; } if (!ch->eof) return did_something; /* content w/o newline, and EOF */ /* p == pend */ if (ch->end_ix >= ch->data_size) { if (data != ch->data) { ndmchan_compress (ch); goto again; } /* that's one huge message */ p--; /* lose last byte */ } ch->data[ch->end_ix++] = '\n'; did_something++; goto again; } int ndmda_quantum_wrap (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmchan * ch = &da->formatter_wrap; int did_something = 0; char * p; char * data; char * pend; unsigned n_ready; int is_recover = 0; switch (da->data_state.operation) { default: assert (0); break; case NDMP9_DATA_OP_BACKUP: break; case NDMP9_DATA_OP_RECOVER: case NDMP9_DATA_OP_RECOVER_FILEHIST: is_recover = 1; break; } again: n_ready = ndmchan_n_ready (ch); if (n_ready == 0) { if (ch->eof && is_recover) { ndmda_data_halt (sess, NDMP9_DATA_HALT_SUCCESSFUL); } return did_something; } data = p = &ch->data[ch->beg_ix]; pend = p + n_ready; while (p < pend && *p != '\n') p++; if (p < pend && *p == '\n') { *p++ = 0; ndmda_wrap_in (sess, data); ch->beg_ix += p - data; did_something++; goto again; } if (!ch->eof) return did_something; /* content w/o newline, and EOF */ /* p == pend */ if (ch->end_ix >= ch->data_size) { if (data != ch->data) { ndmchan_compress (ch); goto again; } /* that's one huge message */ p--; /* lose last byte */ } ch->data[ch->end_ix++] = '\n'; did_something++; goto again; } int ndmda_quantum_image (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmchan * from_chan; struct ndmchan * to_chan; unsigned n_ready, n_avail, n_copy; int is_backup = 0; switch (da->data_state.operation) { default: assert (0); from_chan = 0; to_chan = 0; break; case NDMP9_DATA_OP_BACKUP: from_chan = &da->formatter_image; to_chan = &sess->plumb.image_stream->chan; is_backup = 1; break; case NDMP9_DATA_OP_RECOVER: case NDMP9_DATA_OP_RECOVER_FILEHIST: from_chan = &sess->plumb.image_stream->chan; to_chan = &da->formatter_image; break; } again: n_copy = n_ready = ndmchan_n_ready (from_chan); if (n_ready == 0) { if (from_chan->eof) { to_chan->eof = 1; if (ndmchan_n_ready (to_chan) == 0) { if (is_backup) { ndmda_data_halt (sess, NDMP9_DATA_HALT_SUCCESSFUL); } } } return 0; /* data blocked */ } n_avail = ndmchan_n_avail (to_chan); if (n_copy > n_avail) n_copy = n_avail; if (da->enable_hist) { if (n_copy > da->pass_resid) n_copy = da->pass_resid; } if (n_copy > 0) { bcopy (&from_chan->data[from_chan->beg_ix], &to_chan->data[to_chan->end_ix], n_copy); from_chan->beg_ix += n_copy; to_chan->end_ix += n_copy; da->data_state.bytes_processed += n_copy; da->pass_resid -= n_copy; goto again; /* do as much as possible */ } return 0; } /* * Process WRAP messages from the formatter. Called from * ndmda_quantum_wrap(). The formatter sends one line text * messages via the WRAP pipe (fd=3 on formatter). * The WRAP message contain log messages, file history, * status updates, etc, etc, etc. * * Here the messages are parsed and directed to the * right NDMP interface toward the Control Agent. */ void ndmp9_fstat_from_wrap_fstat (ndmp9_file_stat *fstat9, struct wrap_fstat *fstatw); int ndmda_wrap_in (struct ndm_session *sess, char *wrap_line) { struct wrap_msg_buf _wmsg, *wmsg = &_wmsg; int rc; ndmp9_file_stat fstat9; NDMOS_MACRO_ZEROFILL (wmsg); rc = wrap_parse_msg (wrap_line, wmsg); if (rc != 0) { ndmalogf (sess, 0, 2, "Malformed wrap: %s", wrap_line); return -1; } switch (wmsg->msg_type) { case WRAP_MSGTYPE_LOG_MESSAGE: ndmalogf (sess, "WRAP", 2, "%s", wmsg->body.log_message.message); ndma_send_logmsg (sess, NDMP9_LOG_NORMAL, sess->plumb.data, "WRAP: %s", wmsg->body.log_message.message); break; case WRAP_MSGTYPE_ADD_FILE: ndmp9_fstat_from_wrap_fstat (&fstat9, &wmsg->body.add_file.fstat); fstat9.fh_info.valid = NDMP9_VALIDITY_VALID; fstat9.fh_info.value = wmsg->body.add_file.fhinfo; ndmda_fh_add_file (sess, &fstat9, wmsg->body.add_file.path); break; case WRAP_MSGTYPE_ADD_DIRENT: ndmda_fh_add_dir (sess, wmsg->body.add_dirent.dir_fileno, wmsg->body.add_dirent.name, wmsg->body.add_dirent.fileno); break; case WRAP_MSGTYPE_ADD_NODE: ndmp9_fstat_from_wrap_fstat (&fstat9, &wmsg->body.add_node.fstat); fstat9.fh_info.valid = NDMP9_VALIDITY_VALID; fstat9.fh_info.value = wmsg->body.add_node.fhinfo; ndmda_fh_add_node (sess, &fstat9); break; case WRAP_MSGTYPE_DATA_READ: ndmda_send_data_read (sess, wmsg->body.data_read.offset, wmsg->body.data_read.length); break; case WRAP_MSGTYPE_ADD_ENV: case WRAP_MSGTYPE_DATA_STATS: case WRAP_MSGTYPE_RECOVERY_RESULT: ndmalogf (sess, 0, 2, "Unimplemented wrap: %s", wrap_line); break; } return 0; } void ndmp9_fstat_from_wrap_fstat (ndmp9_file_stat *fstat9, struct wrap_fstat *fstatw) { NDMOS_MACRO_ZEROFILL (fstat9); switch (fstatw->ftype) { default: case WRAP_FTYPE_INVALID:fstat9->ftype = NDMP9_FILE_OTHER; break; case WRAP_FTYPE_DIR: fstat9->ftype = NDMP9_FILE_DIR; break; case WRAP_FTYPE_FIFO: fstat9->ftype = NDMP9_FILE_FIFO; break; case WRAP_FTYPE_CSPEC: fstat9->ftype = NDMP9_FILE_CSPEC; break; case WRAP_FTYPE_BSPEC: fstat9->ftype = NDMP9_FILE_BSPEC; break; case WRAP_FTYPE_REG: fstat9->ftype = NDMP9_FILE_REG; break; case WRAP_FTYPE_SLINK: fstat9->ftype = NDMP9_FILE_SLINK; break; case WRAP_FTYPE_SOCK: fstat9->ftype = NDMP9_FILE_SOCK; break; case WRAP_FTYPE_REGISTRY:fstat9->ftype = NDMP9_FILE_REGISTRY; break; case WRAP_FTYPE_OTHER: fstat9->ftype = NDMP9_FILE_OTHER; break; } if (fstatw->valid & WRAP_FSTAT_VALID_FTYPE) { } if (fstatw->valid & WRAP_FSTAT_VALID_MODE) { fstat9->mode.valid = NDMP9_VALIDITY_VALID; fstat9->mode.value = fstatw->mode; } if (fstatw->valid & WRAP_FSTAT_VALID_SIZE) { fstat9->size.valid = NDMP9_VALIDITY_VALID; fstat9->size.value = fstatw->size; } if (fstatw->valid & WRAP_FSTAT_VALID_LINKS) { fstat9->links.valid = NDMP9_VALIDITY_VALID; fstat9->links.value = fstatw->size; } if (fstatw->valid & WRAP_FSTAT_VALID_UID) { fstat9->uid.valid = NDMP9_VALIDITY_VALID; fstat9->uid.value = fstatw->uid; } if (fstatw->valid & WRAP_FSTAT_VALID_GID) { fstat9->gid.valid = NDMP9_VALIDITY_VALID; fstat9->gid.value = fstatw->gid; } if (fstatw->valid & WRAP_FSTAT_VALID_ATIME) { fstat9->atime.valid = NDMP9_VALIDITY_VALID; fstat9->atime.value = fstatw->atime; } if (fstatw->valid & WRAP_FSTAT_VALID_MTIME) { fstat9->mtime.valid = NDMP9_VALIDITY_VALID; fstat9->mtime.value = fstatw->mtime; } if (fstatw->valid & WRAP_FSTAT_VALID_CTIME) { fstat9->ctime.valid = NDMP9_VALIDITY_VALID; fstat9->ctime.value = fstatw->ctime; } if (fstatw->valid & WRAP_FSTAT_VALID_FILENO) { fstat9->node.valid = NDMP9_VALIDITY_VALID; fstat9->node.value = fstatw->fileno; } } /* * Send LOG and NOTIFY messages **************************************************************** */ #if 0 void ndmda_send_logmsg (struct ndm_session *sess, char *fmt, ...) { struct ndmconn * conn = sess->plumb.control; char buf[4096]; va_list ap; va_start (ap, fmt); vsnprintf (buf, sizeof(buf), fmt, ap); va_end (ap); // we don't handle our own messages so don't send them.... if (conn->conn_type == NDMCONN_TYPE_RESIDENT) { ndmalogf(sess, 0, 2, "RESIDENT AGENT LOGMSG: %s", buf); return; } ndma_send_logmsg (sess, buf, conn); } #endif void ndmda_send_notice (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; if (!da->data_notify_pending) return; da->data_notify_pending = 0; switch (da->data_state.state) { case NDMP9_DATA_STATE_HALTED: ndma_notify_data_halted (sess); break; default: /* Hmm. Why are we here. Race? */ break; } } void ndmda_send_data_read (struct ndm_session *sess, uint64_t offset, uint64_t length) { struct ndm_data_agent * da = sess->data_acb; ndmp9_addr_type addr_type; addr_type = da->data_state.data_connection_addr.addr_type; #if 0 da->reco_read_offset = offset; da->reco_read_length = length; #endif if (NDMP9_ADDR_LOCAL == addr_type) { #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (ndmta_local_mover_read (sess, offset, length) != 0) { ndma_send_logmsg (sess, NDMP9_LOG_ERROR, sess->plumb.data, "local_mover_read failed"); ndmda_data_halt (sess, NDMP9_DATA_HALT_INTERNAL_ERROR); } #else /* !NDMOS_OPTION_NO_TAPE_AGENT */ ndma_send_logmsg (sess, NDMP9_LOG_ERROR, sess->plumb.data, "local_mover_read not configured"); ndmda_data_halt (sess, NDMP9_DATA_HALT_INTERNAL_ERROR); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ return; } switch (addr_type) { case NDMP9_ADDR_TCP: ndma_notify_data_read (sess, offset, length); break; default: ndma_send_logmsg (sess, NDMP9_LOG_ERROR, sess->plumb.data, "bogus mover.addr_type"); ndmda_data_halt (sess, NDMP9_DATA_HALT_INTERNAL_ERROR); break; } } /* * Misc -- env[] and nlist[] subroutines, etc **************************************************************** */ int ndmda_copy_environment (struct ndm_session *sess, ndmp9_pval *env, unsigned n_env) { struct ndm_data_agent * da = sess->data_acb; unsigned int i; for (i = 0; i < n_env; i++) { if (!ndma_store_env_list (&da->env_tab, &env[i])) goto fail; } return 0; fail: ndma_destroy_env_list (&da->env_tab); return -1; } struct ndmp9_pval * ndmda_find_env (struct ndm_session *sess, char *name) { struct ndm_data_agent * da = sess->data_acb; struct ndm_env_entry * entry; for (entry = da->env_tab.head; entry; entry = entry->next) { if (strcmp (entry->pval.name, name) == 0) return &entry->pval; } return 0; } int ndmda_interpret_boolean_value (char *value_str, int default_value) { if (strcasecmp (value_str, "y") == 0 || strcasecmp (value_str, "yes") == 0 || strcasecmp (value_str, "t") == 0 || strcasecmp (value_str, "true") == 0 || strcasecmp (value_str, "1") == 0) return 1; if (strcasecmp (value_str, "n") == 0 || strcasecmp (value_str, "no") == 0 || strcasecmp (value_str, "f") == 0 || strcasecmp (value_str, "false") == 0 || strcasecmp (value_str, "0") == 0) return 0; return default_value; } void ndmda_purge_environment (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndma_destroy_env_list(&da->env_tab); } int ndmda_copy_nlist (struct ndm_session *sess, ndmp9_name *nlist, unsigned n_nlist) { struct ndm_data_agent * da = sess->data_acb; unsigned int i; for (i = 0; i < n_nlist; i++) { if (!ndma_store_nlist(&da->nlist_tab, &nlist[i])) { return -1; /* no mem */ } } /* TODO: sort */ return 0; } void ndmda_purge_nlist (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndma_destroy_nlist(&da->nlist_tab); } int ndmda_count_invalid_fh_info (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndm_nlist_entry * entry; int count; count = 0; for (entry = da->nlist_tab.head; entry; entry = entry->next) { if (entry->name.fh_info.valid != NDMP9_VALIDITY_VALID) { count++; } } return count; } int ndmda_count_invalid_fh_info_pending (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndm_nlist_entry * entry; int count; count = 0; for (entry = da->nlist_tab.head; entry; entry = entry->next) { if (entry->result_err == NDMP9_UNDEFINED_ERR && entry->name.fh_info.valid != NDMP9_VALIDITY_VALID) { count++; } } return count; } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_data_fh.c000066400000000000000000000125511263011562700207220ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_DATA_AGENT /* * Initialization and Cleanup **************************************************************** */ /* Initialize -- Set data structure to know value, ignore current value */ int ndmda_fh_initialize (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmfhheap * fhh = &da->fhh; ndmfhh_initialize (fhh); return 0; } /* Commission -- Get agent ready. Entire session has been initialize()d */ int ndmda_fh_commission (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmfhheap * fhh = &da->fhh; da->fhh_buf = NDMOS_API_MALLOC (NDMDA_N_FHH_BUF); if (!da->fhh_buf) return -1; ndmfhh_commission (fhh, da->fhh_buf, sizeof *da->fhh_buf); return 0; } /* Decommission -- Discard agent */ int ndmda_fh_decommission (struct ndm_session *sess) { return 0; } /* Destroy -- Destroy agent */ int ndmda_fh_destroy (struct ndm_session *sess) { if (sess->data_acb->fhh_buf) { NDMOS_API_FREE (sess->data_acb->fhh_buf); sess->data_acb->fhh_buf = NULL; } return 0; } /* Belay -- Cancel partially issued activation/start */ int ndmda_fh_belay (struct ndm_session *sess) { return 0; } /* * Semantic actions -- called from ndmda_XXX() butype formatters **************************************************************** */ void ndmda_fh_add_file (struct ndm_session *sess, ndmp9_file_stat *filestat, char *name) { struct ndm_data_agent * da = sess->data_acb; int nlen = strlen (name) + 1; ndmp9_file * file9; int rc; rc = ndmda_fh_prepare (sess, NDMP9VER, NDMP9_FH_ADD_FILE, sizeof (ndmp9_file), 1, nlen); if (rc != NDMFHH_RET_OK) return; file9 = ndmfhh_add_entry (&da->fhh); file9->fstat = *filestat; file9->unix_path = ndmfhh_save_item (&da->fhh, name, nlen); } void ndmda_fh_add_dir (struct ndm_session *sess, uint64_t dir_fileno, char *name, uint64_t fileno) { struct ndm_data_agent * da = sess->data_acb; int nlen = strlen (name) + 1; ndmp9_dir * dir9; int rc; rc = ndmda_fh_prepare (sess, NDMP9VER, NDMP9_FH_ADD_DIR, sizeof (ndmp9_dir), 1, nlen); if (rc != NDMFHH_RET_OK) return; dir9 = ndmfhh_add_entry (&da->fhh); dir9->unix_name = ndmfhh_save_item (&da->fhh, name, nlen); dir9->parent = dir_fileno; dir9->node = fileno; } void ndmda_fh_add_node (struct ndm_session *sess, ndmp9_file_stat *filestat) { struct ndm_data_agent * da = sess->data_acb; ndmp9_node * node9; int rc; rc = ndmda_fh_prepare (sess, NDMP9VER, NDMP9_FH_ADD_NODE, sizeof (ndmp9_node), 1, 0); if (rc != NDMFHH_RET_OK) return; node9 = ndmfhh_add_entry (&da->fhh); node9->fstat = *filestat; } /* * Helpers -- prepare/flush **************************************************************** */ int ndmda_fh_prepare (struct ndm_session *sess, int vers, int msg, int entry_size, unsigned n_item, unsigned total_size_of_items) { struct ndm_data_agent * da = sess->data_acb; struct ndmfhheap * fhh = &da->fhh; int fhtype = (vers<<16) + msg; int rc; rc = ndmfhh_prepare (fhh, fhtype, entry_size, n_item, total_size_of_items); if (rc == NDMFHH_RET_OK) return NDMFHH_RET_OK; ndmda_fh_flush (sess); rc = ndmfhh_prepare (fhh, fhtype, entry_size, n_item, total_size_of_items); return rc; } void ndmda_fh_flush (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmfhheap * fhh = &da->fhh; int rc; int fhtype; void * table; unsigned n_entry; rc = ndmfhh_get_table (fhh, &fhtype, &table, &n_entry); if (rc == NDMFHH_RET_OK && n_entry > 0) { struct ndmp_xa_buf xa; struct ndmfhh_generic_table *request; request = (void *) &xa.request.body; NDMOS_MACRO_ZEROFILL (&xa); xa.request.protocol_version = fhtype >> 16; xa.request.header.message = fhtype & 0xFFFF; request->table_len = n_entry; request->table_val = table; ndma_send_to_control (sess, &xa, sess->plumb.data); } ndmfhh_reset (fhh); } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_data_pfe.c000066400000000000000000000115671263011562700211050ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_DATA_AGENT int ndmda_pipe_fork_exec (struct ndm_session *sess, char *cmd, int is_backup) { struct ndm_data_agent * da = sess->data_acb; struct ndmchan * ch; int errpipe[2]; int datpipe[2]; int wrppipe[2]; int nullfd; int rc = -1; ndmalogf (sess, 0, 2, "Starting %s", cmd); nullfd = open ("/dev/null", 2); if (nullfd < 0) { return rc; } rc = pipe (errpipe); if (rc < 0) { close (nullfd); return rc; } rc = pipe (datpipe); if (rc < 0) { close (nullfd); close (errpipe[0]); close (errpipe[1]); return rc; } rc = pipe (wrppipe); if (rc < 0) { close (nullfd); close (errpipe[0]); close (errpipe[1]); close (datpipe[0]); close (datpipe[1]); return rc; } rc = fork(); if (rc < 0) { close (nullfd); close (errpipe[0]); close (errpipe[1]); close (datpipe[0]); close (datpipe[1]); close (wrppipe[0]); close (wrppipe[1]); return rc; } if (rc == 0) { /* child */ dup2 (errpipe[1], 2); dup2 (wrppipe[1], 3); close (errpipe[0]); close (wrppipe[0]); if (is_backup) { dup2 (nullfd, 0); dup2 (datpipe[1], 1); close (datpipe[0]); } else { dup2 (datpipe[0], 0); dup2 (nullfd, 1); close (datpipe[1]); } /* * 0 -- formatter stdin * 1 -- formatter stdout * 2 -- formatter stderr * 3 -- formatter wrap chan (wraplib.c) */ for (rc = 4; rc < 100; rc++) { close(rc); } execl ("/bin/sh", "sh", "-c", cmd, NULL); fprintf (stderr, "EXEC FAILED %s\n", cmd); exit(127); } /* parent */ close (nullfd); ch = &da->formatter_error; ndmchan_initialize (ch, "dfp-error"); da->fmt_error_buf = NDMOS_API_MALLOC (NDMDA_N_FMT_ERROR_BUF); if (!da->fmt_error_buf) return -1; ndmchan_setbuf (ch, da->fmt_error_buf, NDMDA_N_FMT_ERROR_BUF); close (errpipe[1]); ndmos_condition_pipe_fd (sess, errpipe[0]); ndmchan_start_read (ch, errpipe[0]); ch = &da->formatter_wrap; ndmchan_initialize (ch, "dfp-wrap"); da->fmt_wrap_buf = NDMOS_API_MALLOC (NDMDA_N_FMT_WRAP_BUF); if (!da->fmt_wrap_buf) return -1; ndmchan_setbuf (ch, da->fmt_wrap_buf, NDMDA_N_FMT_WRAP_BUF); close (wrppipe[1]); ndmos_condition_pipe_fd (sess, wrppipe[0]); ndmchan_start_read (ch, wrppipe[0]); ch = &da->formatter_image; ndmchan_initialize (ch, "dfp-image"); da->fmt_image_buf = NDMOS_API_MALLOC (NDMDA_N_FMT_IMAGE_BUF); if (!da->fmt_image_buf) return -1; ndmchan_setbuf (ch, da->fmt_image_buf, NDMDA_N_FMT_IMAGE_BUF); if (is_backup) { ndmalogf (sess, 0, 2, "backup..."); close (datpipe[1]); ndmos_condition_pipe_fd (sess, datpipe[0]); ndmchan_start_read (ch, datpipe[0]); } else { ndmalogf (sess, 0, 2, "recover..."); close (datpipe[0]); ndmos_condition_pipe_fd (sess, datpipe[1]); ndmchan_start_write (ch, datpipe[1]); } da->formatter_pid = rc; return rc; /* PID */ } int ndmda_add_to_cmd_with_escapes (char *cmd, char *word, char *special) { char * cmd_lim = &cmd[NDMDA_MAX_CMD-3]; char * p; int c; p = cmd; while (*p) p++; if (p != cmd) *p++ = ' '; while ((c = *word++) != 0) { if (p >= cmd_lim) return -1; /* overflow */ if (c == '\\' || strchr (special, c)) *p++ = '\\'; *p++ = c; } *p = 0; return 0; } int ndmda_add_to_cmd (char *cmd, char *word) { return ndmda_add_to_cmd_with_escapes (cmd, word, " \t`'\"*?[]$"); } int ndmda_add_to_cmd_allow_file_wildcards (char *cmd, char *word) { return ndmda_add_to_cmd_with_escapes (cmd, word, " \t`'\"$"); } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_image_stream.c000066400000000000000000000661331263011562700217760ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * * * ndmis_connect_status transitions * * Event relative to ------ before ------ ------ after ------- * "mine" end point MINE PEER REMO MINE PEER REMO * ==================================================================== * LISTEN/LOCAL IDLE IDLE IDLE LISTEN IDLE EXCLUDE * LISTEN/TCP IDLE IDLE IDLE LISTEN REMOTE LISTEN * * CONNECT/LOCAL IDLE LISTEN EXCLUDE CONN'ED ACC'ED EXCLUDE * CONNECT/TCP IDLE IDLE IDLE CONN'ED REMOTE CONN'ED * * tcp_accept() LISTEN REMOTE LISTEN ACC'ED REMOTE ACC'ED * */ #if 0 DATA TAPE END ========== LOCAL ============ END POINT POINT REMOTE #endif #include "ndmagents.h" int ndmis_reinit_remote (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndm_tape_agent * ta = sess->tape_acb; NDMOS_MACRO_ZEROFILL (&is->remote); ndmchan_initialize (&is->remote.listen_chan, "image-stream-listen"); ndmchan_initialize (&is->remote.sanity_chan, "image-stream-sanity"); ndmchan_initialize (&is->chan, "image-stream"); if (!is->buf) { is->buflen = ta->mover_state.record_size; is->buf = NDMOS_API_MALLOC (is->buflen); if (!is->buf) { return -1; } NDMOS_MACRO_ZEROFILL_SIZE (is->buf, is->buflen); } ndmchan_setbuf (&is->chan, is->buf, is->buflen); return 0; } /* * Initialization and Cleanup **************************************************************** */ /* Initialize -- Set data structure to know value, ignore current value */ int ndmis_initialize (struct ndm_session *sess) { sess->plumb.image_stream = NDMOS_API_MALLOC (sizeof(struct ndm_image_stream)); if (!sess->plumb.image_stream) return -1; NDMOS_MACRO_ZEROFILL (sess->plumb.image_stream); NDMOS_MACRO_ZEROFILL (&sess->plumb.image_stream->chan); ndmis_reinit_remote (sess); sess->plumb.image_stream->data_ep.name = "DATA"; sess->plumb.image_stream->tape_ep.name = "TAPE"; return 0; } /* Commission -- Get agent ready. Entire session has been initialize()d */ int ndmis_commission (struct ndm_session *sess) { return 0; } /* Decommission -- Discard agent */ int ndmis_decommission (struct ndm_session *sess) { return 0; } /* Destroy -- Destroy agent */ int ndmis_destroy (struct ndm_session *sess) { if (!sess->plumb.image_stream) { return 0; } if (sess->plumb.image_stream->buf) { NDMOS_API_FREE (sess->plumb.image_stream->buf); } NDMOS_API_FREE (sess->plumb.image_stream); sess->plumb.image_stream = NULL; return 0; } /* Belay -- Cancel partially issued activation/start */ int ndmis_belay (struct ndm_session *sess) { return 0; } /* * Semantic actions -- called from ndma_dispatch() **************************************************************** */ ndmp9_error ndmis_audit_data_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason) { struct ndm_image_stream *is; struct ndmis_end_point *mine_ep; struct ndmis_end_point *peer_ep; /* * We are about to start using an Image Stream so allocate it. * Only do this when not allocated yet. */ if (!sess->plumb.image_stream) { if (ndmis_initialize (sess)) { return NDMP9_NO_MEM_ERR; } } is = sess->plumb.image_stream; mine_ep = &is->data_ep; peer_ep = &is->tape_ep; return ndmis_audit_ep_listen (sess, addr_type, reason, mine_ep, peer_ep); } ndmp9_error ndmis_audit_tape_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason) { struct ndm_image_stream *is; struct ndmis_end_point *mine_ep; struct ndmis_end_point *peer_ep; /* * We are about to start using an Image Stream so allocate it. * Only do this when not allocated yet. */ if (!sess->plumb.image_stream) { if (ndmis_initialize (sess)) { return NDMP9_NO_MEM_ERR; } } is = sess->plumb.image_stream; mine_ep = &is->tape_ep; peer_ep = &is->data_ep; return ndmis_audit_ep_listen (sess, addr_type, reason, mine_ep, peer_ep); } ndmp9_error ndmis_audit_data_connect (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason) { struct ndm_image_stream *is; struct ndmis_end_point *mine_ep; struct ndmis_end_point *peer_ep; /* * We are about to start using an Image Stream so allocate it. * Only do this when not allocated yet. */ if (!sess->plumb.image_stream) { if (ndmis_initialize (sess)) { return NDMP9_NO_MEM_ERR; } } is = sess->plumb.image_stream; mine_ep = &is->data_ep; peer_ep = &is->tape_ep; return ndmis_audit_ep_listen (sess, addr_type, reason, mine_ep, peer_ep); } ndmp9_error ndmis_audit_tape_connect (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason) { struct ndm_image_stream *is; struct ndmis_end_point *mine_ep; struct ndmis_end_point *peer_ep; /* * We are about to start using an Image Stream so allocate it. * Only do this when not allocated yet. */ if (!sess->plumb.image_stream) { if (ndmis_initialize (sess)) { return NDMP9_NO_MEM_ERR; } } is = sess->plumb.image_stream; mine_ep = &is->tape_ep; peer_ep = &is->data_ep; return ndmis_audit_ep_listen (sess, addr_type, reason, mine_ep, peer_ep); } ndmp9_error ndmis_data_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, ndmp9_addr *ret_addr, char *reason) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep = &is->data_ep; struct ndmis_end_point *peer_ep = &is->tape_ep; return ndmis_ep_listen (sess, addr_type, ret_addr, reason, mine_ep, peer_ep); } ndmp9_error ndmis_tape_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, ndmp9_addr *ret_addr, char *reason) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep = &is->tape_ep; struct ndmis_end_point *peer_ep = &is->data_ep; return ndmis_ep_listen (sess, addr_type, ret_addr, reason, mine_ep, peer_ep); } ndmp9_error ndmis_data_connect (struct ndm_session *sess, ndmp9_addr *addr, char *reason) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep = &is->data_ep; struct ndmis_end_point *peer_ep = &is->tape_ep; ndmp9_error error; error = ndmis_ep_connect (sess, addr, reason, mine_ep, peer_ep); #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (error == NDMP9_NO_ERR) { if (peer_ep->connect_status == NDMIS_CONN_ACCEPTED && peer_ep->addr_type == NDMP9_ADDR_LOCAL) { ndmta_quantum (sess); } } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ return error; } ndmp9_error ndmis_tape_connect (struct ndm_session *sess, ndmp9_addr *addr, char *reason) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep = &is->tape_ep; struct ndmis_end_point *peer_ep = &is->data_ep; return ndmis_ep_connect (sess, addr, reason, mine_ep, peer_ep); } int ndmis_ep_start (struct ndm_session *sess, int chan_mode, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { struct ndm_image_stream *is = sess->plumb.image_stream; if (mine_ep->connect_status != NDMIS_CONN_CONNECTED && mine_ep->connect_status != NDMIS_CONN_ACCEPTED) { return -1; } if (mine_ep->transfer_mode != NDMCHAN_MODE_IDLE) { return -2; } if (mine_ep->addr_type == NDMP9_ADDR_LOCAL) { ndmchan_start_resident (&is->chan); if (chan_mode == NDMCHAN_MODE_WRITE) { peer_ep->transfer_mode = NDMCHAN_MODE_READ; } else { peer_ep->transfer_mode = NDMCHAN_MODE_WRITE; } } else if (chan_mode == NDMCHAN_MODE_WRITE) { ndmchan_pending_to_write (&is->chan); } else if (chan_mode == NDMCHAN_MODE_READ) { ndmchan_pending_to_read (&is->chan); } else { return -3; } mine_ep->transfer_mode = chan_mode; return 0; } int ndmis_data_start (struct ndm_session *sess, int chan_mode) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep = &is->data_ep; struct ndmis_end_point *peer_ep = &is->tape_ep; return ndmis_ep_start (sess, chan_mode, mine_ep, peer_ep); } int ndmis_tape_start (struct ndm_session *sess, int chan_mode) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep = &is->tape_ep; struct ndmis_end_point *peer_ep = &is->data_ep; return ndmis_ep_start (sess, chan_mode, mine_ep, peer_ep); } int ndmis_data_close (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; if (is) { return ndmis_ep_close (sess, &is->data_ep, &is->tape_ep); } else { return 0; } } int ndmis_tape_close (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; if (is) { return ndmis_ep_close (sess, &is->tape_ep, &is->data_ep); } else { return 0; } } /* * Quantum -- get a bit of work done **************************************************************** */ int ndmis_quantum (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; struct ndmis_end_point *mine_ep; int rc; if (is->remote.connect_status != NDMIS_CONN_LISTEN) return 0; /* did nothing */ if (!is->remote.listen_chan.ready) return 0; /* did nothing */ /* now this is going to get hard */ if (is->data_ep.connect_status == NDMIS_CONN_LISTEN) { mine_ep = &is->data_ep; /* assert (is->tape_ep.connect_status == NDMIS_CONN_REMOTE); */ } else if (is->tape_ep.connect_status == NDMIS_CONN_LISTEN) { mine_ep = &is->tape_ep; /* assert (is->data_ep.connect_status == NDMIS_CONN_REMOTE); */ } else { assert(0); return -1; } rc = ndmis_tcp_accept (sess); if (rc == 0) { mine_ep->connect_status = NDMIS_CONN_ACCEPTED; is->remote.connect_status = NDMIS_CONN_ACCEPTED; } else { mine_ep->connect_status = NDMIS_CONN_BOTCHED; is->remote.connect_status = NDMIS_CONN_BOTCHED; } return 1; /* did something */ } /* * ndmis_end_point oriented helper routines **************************************************************** */ ndmp9_error ndmis_audit_ep_listen ( struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { ndmp9_error error = NDMP9_NO_ERR; char * reason_end; sprintf (reason, "IS %s_LISTEN: ", mine_ep->name); reason_end = reason; while (*reason_end) reason_end++; if (mine_ep->connect_status != NDMIS_CONN_IDLE) { sprintf (reason_end, "%s not idle", mine_ep->name); error = NDMP9_ILLEGAL_STATE_ERR; goto out; } if (peer_ep->connect_status != NDMIS_CONN_IDLE) { sprintf (reason_end, "%s not idle", peer_ep->name); error = NDMP9_ILLEGAL_STATE_ERR; goto out; } switch (addr_type) { case NDMP9_ADDR_LOCAL: break; case NDMP9_ADDR_TCP: break; default: strcpy (reason_end, "unknown addr_type"); error = NDMP9_ILLEGAL_ARGS_ERR; goto out; } out: if (error == NDMP9_NO_ERR) strcpy (reason_end, "OK"); else ndmalogf (sess, 0, 2, "listen %s messy mcs=%d pcs=%d", mine_ep->name, mine_ep->connect_status, peer_ep->connect_status); return error; } ndmp9_error ndmis_audit_ep_connect ( struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { ndmp9_error error = NDMP9_NO_ERR; char * reason_end; sprintf (reason, "IS %s_CONNECT: ", mine_ep->name); reason_end = reason; while (*reason_end) reason_end++; if (mine_ep->connect_status != NDMIS_CONN_IDLE) { sprintf (reason_end, "%s not idle", mine_ep->name); error = NDMP9_ILLEGAL_STATE_ERR; goto out; } switch (addr_type) { case NDMP9_ADDR_LOCAL: if (peer_ep->connect_status != NDMIS_CONN_LISTEN) { sprintf (reason_end, "LOCAL %s not LISTEN", peer_ep->name); error = NDMP9_ILLEGAL_STATE_ERR; goto out; } if (peer_ep->addr_type != NDMP9_ADDR_LOCAL) { sprintf (reason_end, "LOCAL %s not LOCAL", peer_ep->name); error = NDMP9_ILLEGAL_STATE_ERR; goto out; } break; case NDMP9_ADDR_TCP: if (peer_ep->connect_status != NDMIS_CONN_IDLE) { sprintf (reason_end, "LOCAL %s not IDLE", peer_ep->name); error = NDMP9_ILLEGAL_STATE_ERR; goto out; } break; default: strcpy (reason_end, "unknown addr_type"); error = NDMP9_ILLEGAL_ARGS_ERR; goto out; } out: if (error == NDMP9_NO_ERR) strcpy (reason_end, "OK"); return error; } ndmp9_error ndmis_ep_listen ( struct ndm_session *sess, ndmp9_addr_type addr_type, ndmp9_addr *ret_addr, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { struct ndm_image_stream *is = sess->plumb.image_stream; char * reason_end; ndmp9_error error; error = ndmis_audit_ep_listen (sess, addr_type, reason, mine_ep, peer_ep); if (error != NDMP9_NO_ERR) return error; reason_end = reason; while (*reason_end && *reason_end != ':') reason_end++; *reason_end++ = ':'; *reason_end++ = ' '; *reason_end = 0; NDMOS_MACRO_ZEROFILL (ret_addr); ret_addr->addr_type = addr_type; switch (addr_type) { case NDMP9_ADDR_LOCAL: mine_ep->addr_type = NDMP9_ADDR_LOCAL; mine_ep->connect_status = NDMIS_CONN_LISTEN; is->remote.connect_status = NDMIS_CONN_EXCLUDE; break; case NDMP9_ADDR_TCP: if (ndmis_tcp_listen (sess, ret_addr) != 0) { strcpy (reason_end, "TCP listen() failed"); error = NDMP9_CONNECT_ERR; goto out; } mine_ep->addr_type = NDMP9_ADDR_TCP; mine_ep->connect_status = NDMIS_CONN_LISTEN; peer_ep->connect_status = NDMIS_CONN_REMOTE; break; default: reason = "unknown addr_type (bad)"; error = NDMP9_ILLEGAL_ARGS_ERR; goto out; } out: if (error == NDMP9_NO_ERR) strcpy (reason_end, "OK"); return error; } ndmp9_error ndmis_ep_connect ( struct ndm_session *sess, ndmp9_addr *addr, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { struct ndm_image_stream *is = sess->plumb.image_stream; ndmp9_addr_type addr_type = addr->addr_type; char * reason_end; ndmp9_error error; error = ndmis_audit_ep_connect (sess, addr_type, reason, mine_ep, peer_ep); if (error != NDMP9_NO_ERR) return error; reason_end = reason; while (*reason_end && *reason_end != ':') reason_end++; *reason_end++ = ':'; *reason_end++ = ' '; *reason_end = 0; switch (addr_type) { case NDMP9_ADDR_LOCAL: mine_ep->addr_type = NDMP9_ADDR_LOCAL; mine_ep->connect_status = NDMIS_CONN_CONNECTED; peer_ep->connect_status = NDMIS_CONN_ACCEPTED; is->remote.connect_status = NDMIS_CONN_EXCLUDE; break; case NDMP9_ADDR_TCP: if (ndmis_tcp_connect (sess, addr) != 0) { strcpy (reason_end, "TCP connect() failed"); error = NDMP9_CONNECT_ERR; goto out; } mine_ep->addr_type = NDMP9_ADDR_TCP; mine_ep->connect_status = NDMIS_CONN_CONNECTED; peer_ep->connect_status = NDMIS_CONN_REMOTE; break; default: reason = "unknown addr_type (bad)"; error = NDMP9_ILLEGAL_ARGS_ERR; goto out; } out: return error; } int ndmis_ep_close (struct ndm_session *sess, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { struct ndm_image_stream *is = sess->plumb.image_stream; char * save_name = mine_ep->name; switch (mine_ep->connect_status) { case NDMIS_CONN_IDLE: return 0; case NDMIS_CONN_BOTCHED: case NDMIS_CONN_REMOTE: case NDMIS_CONN_EXCLUDE: goto messy; case NDMIS_CONN_LISTEN: switch (mine_ep->addr_type) { default: goto messy; case NDMP9_ADDR_LOCAL: ndmis_reinit_remote (sess); if (peer_ep->connect_status != NDMIS_CONN_IDLE) goto messy; break; case NDMP9_ADDR_TCP: ndmis_tcp_close (sess); if (peer_ep->connect_status != NDMIS_CONN_REMOTE) goto messy; peer_ep->connect_status = NDMIS_CONN_IDLE; break; } break; case NDMIS_CONN_ACCEPTED: switch (mine_ep->addr_type) { default: goto messy; case NDMP9_ADDR_LOCAL: if (peer_ep->connect_status != NDMIS_CONN_CONNECTED) goto messy; peer_ep->connect_status = NDMIS_CONN_DISCONNECTED; is->chan.eof = 1; if (mine_ep->transfer_mode == NDMCHAN_MODE_READ) is->chan.error = 1; /* EPIPE */ break; case NDMP9_ADDR_TCP: ndmis_tcp_close (sess); if (peer_ep->connect_status != NDMIS_CONN_REMOTE) goto messy; peer_ep->connect_status = NDMIS_CONN_IDLE; break; } break; case NDMIS_CONN_CONNECTED: switch (mine_ep->addr_type) { default: goto messy; case NDMP9_ADDR_LOCAL: if (peer_ep->connect_status != NDMIS_CONN_ACCEPTED) goto messy; peer_ep->connect_status = NDMIS_CONN_DISCONNECTED; is->chan.eof = 1; if (mine_ep->transfer_mode == NDMCHAN_MODE_READ) is->chan.error = 1; /* EPIPE */ break; case NDMP9_ADDR_TCP: ndmis_tcp_close (sess); if (peer_ep->connect_status != NDMIS_CONN_REMOTE) goto messy; peer_ep->connect_status = NDMIS_CONN_IDLE; break; } break; case NDMIS_CONN_DISCONNECTED: /* peer close()d first */ ndmis_reinit_remote (sess); break; case NDMIS_CONN_CLOSED: goto messy; } NDMOS_MACRO_ZEROFILL (mine_ep); mine_ep->name = save_name; return 0; messy: ndmalogf (sess, 0, 2, "close %s messy mcs=%d pcs=%d", mine_ep->name, mine_ep->connect_status, peer_ep->connect_status); NDMOS_MACRO_ZEROFILL (mine_ep); mine_ep->name = save_name; return -1; } #if 0 ndmp9_error ndmis_ep_could_start ( struct ndm_session *sess, int want_transfer_mode, /* NDMCHAN_MODE_{IDLE|READ|WRITE} */ char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep) { ndmp9_error error = NDMP9_NO_ERR; char * reason_end; sprintf (reason, "IS %s_START: ", mine_ep->name); reason_end = reason; while (*reason_end) reason_end++; if (want_transfer_mode == NDMCHAN_MODE_IDLE) want_transfer_mode = mine_ep->transfer_mode; switch (want_transfer_mode) { case NDMCHAN_MODE_IDLE: /* can't check much */ break; case NDMCHAN_MODE_READ: /* what to check? */ break; case NDMCHAN_MODE_WRITE: /* what to check? */ break; default: strcpy (reason_end, "unknown chan_mode"); error = NDMP9_ILLEGAL_ARGS_ERR; goto out; } out: if (error == NDMP9_NO_ERR) strcpy (reason_end, "OK"); return error; } #endif /* 0 */ /* * ADDR_TCP helper routines **************************************************************** */ /* * ndmis_tcp_listen() * * The tricky part of listen()ing is determining the IP * address to offer, which ultimately will be used by * the other (peer) side for connect()ing. * * We can't just bind() with INADDR_ANY (0's) because * that results in a local socket with INADDR_ANY, and * any inbound connection to the right port will be * accept()ed by the networking system. That doesn't * help us here, though, because we have to have a * real IP address to offer. INADDR_ANY ain't sufficient. * * There is also the issue of systems with multiple * network connections. We of course would like to * use the network data link that is most advantageous * on both sides. This may vary from job run to job * run, and so any method of specifying just one * is IP address ain't sufficient. * * The approach here uses the existing control connections, * which normally precede the image stream connection, * as cues for which IP address to use. So, for example, * if a TAPE or DATA host has four network connections, * the CONTROL agent can coax them to use a specific one * of the four by connecting to the IP address of the * network wanted for the image stream. * * If the clever rules don't work out, the fallback is to * look up the host name. Right now we use ndmhost_lookup() * of sess->local_info.host_name because both must work * before things would progress to this point. */ int ndmis_tcp_listen (struct ndm_session *sess, struct ndmp9_addr *listen_addr) { struct ndm_image_stream *is = sess->plumb.image_stream; ndmp9_tcp_addr * tcp_addr = &listen_addr->ndmp9_addr_u.tcp_addr; struct ndmconn * conn; struct sockaddr c_sa; struct sockaddr l_sa; struct sockaddr_in * sin; socklen_t len; int listen_sock = -1; char * what = "???"; /* * Get the IP address thru which the CONTROL agent connected * to this session. The CONTROL agent may influence the * network used for the image-stream on multi-homed hosts * simply by connecting to the prefered IP address. */ what = "determine-conn"; conn = sess->plumb.control; if (!conn || conn->conn_type != NDMCONN_TYPE_REMOTE) { /* * If CONTROL is resident, try the other * control connections in hopes of finding * a clue about what IP address to offer. */ conn = sess->plumb.data; if (!conn || conn->conn_type != NDMCONN_TYPE_REMOTE) { conn = sess->plumb.tape; if (!conn || conn->conn_type != NDMCONN_TYPE_REMOTE) { conn = 0; } } } if (conn) { /* * We found a connection to use for determining * what IP address to offer. */ len = sizeof c_sa; if (getsockname (ndmconn_fileno(conn), &c_sa, &len) < 0) { /* we'll try the fallback rules */ conn = 0; } } if (!conn) { /* * For whatever reason, we can't determine a good * IP address from the connections. Try the boring * fallback rules. */ ndmos_sync_config_info (sess); sin = (struct sockaddr_in *) &c_sa; what = "ndmhost_lookup"; if (ndmhost_lookup (sess->config_info->hostname, sin) != 0) goto fail; } /* c_sa is a sockaddr_in for the IP address to use */ what = "socket"; listen_sock = socket (AF_INET, SOCK_STREAM, 0); if (listen_sock < 0) goto fail; /* could bind() to more restrictive addr based on c_sa */ NDMOS_MACRO_SET_SOCKADDR(&l_sa, 0, 0); what = "bind"; if (bind (listen_sock, &l_sa, sizeof l_sa) < 0) goto fail; what = "listen"; if (listen (listen_sock, 1) < 0) goto fail; ndmos_condition_listen_socket (sess, listen_sock); /* Get the port */ what = "getsockname-listen"; len = sizeof l_sa; if (getsockname (listen_sock, &l_sa, &len) < 0) goto fail; /* * Fill in the return address */ listen_addr->addr_type = NDMP9_ADDR_TCP; tcp_addr = &listen_addr->ndmp9_addr_u.tcp_addr; /* IP addr from CONTROL connection, or where ever c_sa came from */ sin = (struct sockaddr_in *) &c_sa; tcp_addr->ip_addr = ntohl (sin->sin_addr.s_addr); /* port from the bind() and getsockname() above */ sin = (struct sockaddr_in *) &l_sa; tcp_addr->port = ntohs (sin->sin_port); /* * Start the listen channel */ ndmchan_start_listen (&is->remote.listen_chan, listen_sock); is->remote.connect_status = NDMIS_CONN_LISTEN; is->remote.listen_addr = *listen_addr; return 0; fail: ndmalogf (sess, 0, 2, "ndmis_tcp_listen(): %s failed", what); if (listen_sock >= 0) close (listen_sock); return -1; } int ndmis_tcp_accept (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; char * what = "???"; ndmp9_tcp_addr * tcp_addr; struct sockaddr sa; struct sockaddr_in * sin = (struct sockaddr_in *) &sa; socklen_t len; int accept_sock = -1; what = "remote-conn-stat"; if (is->remote.connect_status != NDMIS_CONN_LISTEN) goto fail; what = "remote-list-ready"; if (!is->remote.listen_chan.ready) goto fail; what = "accept"; len = sizeof sa; accept_sock = accept (is->remote.listen_chan.fd, &sa, &len); ndmchan_cleanup (&is->remote.listen_chan); if (accept_sock < 0) { is->remote.connect_status = NDMIS_CONN_BOTCHED; goto fail; } /* write what we know, ndmis...addrs() will update if possible */ is->remote.peer_addr.addr_type = NDMP9_ADDR_TCP; tcp_addr = &is->remote.peer_addr.ndmp9_addr_u.tcp_addr; tcp_addr->ip_addr = ntohl (sin->sin_addr.s_addr); tcp_addr->port = ntohs (sin->sin_port); ndmis_tcp_green_light (sess, accept_sock, NDMIS_CONN_ACCEPTED); return 0; fail: ndmalogf (sess, 0, 2, "ndmis_tcp_accept(): %s failed", what); return -1; } int ndmis_tcp_connect (struct ndm_session *sess, struct ndmp9_addr *connect_addr) { struct ndm_image_stream *is = sess->plumb.image_stream; ndmp9_tcp_addr * tcp_addr=&connect_addr->ndmp9_addr_u.tcp_addr; char * what = "???"; struct sockaddr sa; int connect_sock; NDMOS_MACRO_SET_SOCKADDR (&sa, tcp_addr->ip_addr, tcp_addr->port); what = "socket"; connect_sock = socket (AF_INET, SOCK_STREAM, 0); if (connect_sock < 0) goto fail; what = "connect"; if (connect (connect_sock, &sa, sizeof sa) < 0) goto fail; /* write what we know, ndmis...addrs() will update if possible */ is->remote.peer_addr = *connect_addr; ndmis_tcp_green_light (sess, connect_sock, NDMIS_CONN_CONNECTED); return 0; fail: ndmalogf (sess, 0, 2, "ndmis_tcp_connect(): %s failed", what); if (connect_sock >= 0) close (connect_sock); return -1; } int ndmis_tcp_green_light (struct ndm_session *sess, int sock, ndmis_connect_status new_status) { struct ndm_image_stream *is = sess->plumb.image_stream; ndmos_condition_image_stream_socket (sess, sock); ndmchan_start_pending (&is->chan, sock); is->remote.connect_status = new_status; ndmis_tcp_get_local_and_peer_addrs (sess); return 0; } int ndmis_tcp_close (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; switch (is->remote.connect_status) { case NDMIS_CONN_LISTEN: ndmchan_cleanup (&is->remote.listen_chan); break; case NDMIS_CONN_CONNECTED: case NDMIS_CONN_ACCEPTED: ndmchan_cleanup (&is->chan); break; default: break; } ndmis_reinit_remote (sess); return 0; } int ndmis_tcp_get_local_and_peer_addrs (struct ndm_session *sess) { struct ndm_image_stream *is = sess->plumb.image_stream; char * what = "???"; struct sockaddr sa; struct sockaddr_in * sin = (struct sockaddr_in *) &sa; ndmp9_tcp_addr * tcp_addr; socklen_t len; int rc = 0; len = sizeof sa; what = "getpeername"; if (getpeername (is->chan.fd, &sa, &len) < 0) { /* this is best effort */ ndmalogf (sess, 0, 2, "ndmis_tcp..._addrs(): %s failed", what); rc = -1; } else { is->remote.peer_addr.addr_type = NDMP9_ADDR_TCP; tcp_addr = &is->remote.peer_addr.ndmp9_addr_u.tcp_addr; tcp_addr->ip_addr = ntohl (sin->sin_addr.s_addr); tcp_addr->port = ntohs (sin->sin_port); } len = sizeof sa; what = "getsockname"; if (getsockname (is->chan.fd, &sa, &len) < 0) { /* this is best effort */ ndmalogf (sess, 0, 2, "ndmis_tcp..._addrs(): %s failed", what); rc = -1; } else { is->remote.local_addr.addr_type = NDMP9_ADDR_TCP; tcp_addr = &is->remote.peer_addr.ndmp9_addr_u.tcp_addr; tcp_addr->ip_addr = ntohl (sin->sin_addr.s_addr); tcp_addr->port = ntohs (sin->sin_port); } return rc; } bareos-Release-14.2.6/src/ndmp/ndma_listmgmt.c000066400000000000000000000226671263011562700212050ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" /* * Env list mgmt. * * Return a chunk of memory with all entries from the envlist as * one big enumeration useable for rpc to use as return value. * We allacate the memory and keep the pointer in the table handle * which gets freed on destroy of the table. */ ndmp9_pval * ndma_enumerate_env_list (struct ndm_env_table *envtab) { int i; struct ndm_env_entry * entry; /* * See if we need to allocate memory or can reuse the memory * already allocated in an earlier call. */ if (!envtab->enumerate) { envtab->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_pval) * envtab->n_env); envtab->enumerate_length = envtab->n_env; } else if (envtab->enumerate_length != envtab->n_env) { NDMOS_API_FREE (envtab->enumerate); envtab->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_pval) * envtab->n_env); envtab->enumerate_length = envtab->n_env; } if (!envtab->enumerate) { return NULL; } NDMOS_API_BZERO (envtab->enumerate, sizeof(ndmp9_pval) * envtab->n_env); i = 0; for (entry = envtab->head; entry; entry = entry->next) { memcpy (&envtab->enumerate[i], &entry->pval, sizeof(ndmp9_pval)); i++; } return envtab->enumerate; } /* * Add a new entry to an environment list table. * Return entry if caller want to modify it. */ struct ndm_env_entry * ndma_store_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv) { struct ndm_env_entry * entry; if (envtab->n_env >= NDM_MAX_ENV) return NULL; entry = NDMOS_API_MALLOC (sizeof(struct ndm_env_entry)); if (!entry) return NULL; entry->pval.name = NDMOS_API_STRDUP (pv->name); if (!entry->pval.name) { NDMOS_API_FREE (entry); return NULL; } entry->pval.value = NDMOS_API_STRDUP (pv->value); if (!entry->pval.value) { NDMOS_API_FREE (entry->pval.name); NDMOS_API_FREE (entry); return NULL; } entry->next = NULL; if (envtab->tail) { envtab->tail->next = entry; envtab->tail = entry; } else { envtab->head = entry; envtab->tail = entry; } envtab->n_env++; return entry; } /* * Update an entry in an environment list table. * If it doesn't exist add a new entry. * Return entry if caller want to modify it. */ struct ndm_env_entry * ndma_update_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv) { struct ndm_env_entry * entry; for (entry = envtab->head; entry; entry = entry->next) { if (strcmp(entry->pval.name, pv->name) == 0) { NDMOS_API_FREE (entry->pval.value); entry->pval.value = NDMOS_API_STRDUP (pv->value); return entry; } } return ndma_store_env_list (envtab, pv); } /* * Destroy an environment list table including any * enumerate buffers allocated for it. */ void ndma_destroy_env_list (struct ndm_env_table *envtab) { struct ndm_env_entry * entry; struct ndm_env_entry * next; for (entry = envtab->head; entry; entry = next) { if (entry->pval.name) NDMOS_API_FREE (entry->pval.name); if (entry->pval.value) NDMOS_API_FREE (entry->pval.value); next = entry->next; NDMOS_API_FREE (entry); } if (envtab->enumerate) { NDMOS_API_FREE (envtab->enumerate); envtab->enumerate = NULL; envtab->enumerate_length = 0; } envtab->head = NULL; envtab->tail = NULL; envtab->n_env = 0; } /* * Nlist mgmt. * * Return a chunk of memory with all entries from the nlist as * one big enumeration useable for rpc to use as return value. * We allacate the memory and keep the pointer in the table handle * which gets freed on destroy of the table. */ ndmp9_name * ndma_enumerate_nlist (struct ndm_nlist_table *nlist) { int i; struct ndm_nlist_entry * entry; /* * See if we need to allocate memory or can reuse the memory * already allocated in an earlier call. */ if (!nlist->enumerate) { nlist->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_name) * nlist->n_nlist); nlist->enumerate_length = nlist->n_nlist; } else if (nlist->enumerate_length != nlist->n_nlist) { NDMOS_API_FREE (nlist->enumerate); nlist->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_name) * nlist->n_nlist); nlist->enumerate_length = nlist->n_nlist; } if (!nlist->enumerate) { return NULL; } NDMOS_API_BZERO (nlist->enumerate, sizeof(ndmp9_name) * nlist->n_nlist); i = 0; for (entry = nlist->head; entry; entry = entry->next) { memcpy (&nlist->enumerate[i], &entry->name, sizeof(ndmp9_name)); i++; } return nlist->enumerate; } /* * Add a new entry to a nlist list table. * Return entry if caller want to modify it. */ struct ndm_nlist_entry * ndma_store_nlist (struct ndm_nlist_table *nlist, ndmp9_name *nl) { struct ndm_nlist_entry * entry; if (nlist->n_nlist >= NDM_MAX_NLIST) return NULL; entry = NDMOS_API_MALLOC (sizeof(struct ndm_nlist_entry)); if (!entry) return NULL; NDMOS_MACRO_ZEROFILL (entry); entry->name.original_path = NDMOS_API_STRDUP (nl->original_path); if (!entry->name.original_path) goto bail_out; entry->name.destination_path = NDMOS_API_STRDUP (nl->destination_path); if (!entry->name.destination_path) goto bail_out; entry->name.name = NDMOS_API_STRDUP (nl->name); if (!entry->name.name) goto bail_out; entry->name.other_name = NDMOS_API_STRDUP (nl->other_name); if (!entry->name.other_name) goto bail_out; entry->name.node = nl->node; entry->name.fh_info = nl->fh_info; entry->result_err = NDMP9_UNDEFINED_ERR; entry->result_count = 0; entry->next = NULL; if (nlist->tail) { nlist->tail->next = entry; nlist->tail = entry; } else { nlist->head = entry; nlist->tail = entry; } nlist->n_nlist++; return entry; bail_out: if (entry->name.other_name) NDMOS_API_FREE (entry->name.other_name); if (entry->name.name) NDMOS_API_FREE (entry->name.name); if (entry->name.destination_path) NDMOS_API_FREE (entry->name.destination_path); if (entry->name.original_path) NDMOS_API_FREE (entry->name.original_path); NDMOS_API_FREE (entry); return NULL; } /* * Destroy a nlist list table including any * enumerate buffers allocated for it. */ void ndma_destroy_nlist (struct ndm_nlist_table *nlist) { struct ndm_nlist_entry * entry; struct ndm_nlist_entry * next; for (entry = nlist->head; entry; entry = next) { if (entry->name.original_path) NDMOS_API_FREE (entry->name.original_path); if (entry->name.destination_path) NDMOS_API_FREE (entry->name.destination_path); next = entry->next; NDMOS_API_FREE (entry); } if (nlist->enumerate) { NDMOS_API_FREE (nlist->enumerate); nlist->enumerate = NULL; nlist->enumerate_length = 0; } nlist->head = NULL; nlist->tail = NULL; nlist->n_nlist = 0; } /* * Media list mgmt. * * Create a new media entry and add it to the Media Table. * Return entry if caller want to modify it. */ struct ndmmedia * ndma_store_media (struct ndm_media_table *mtab, uint16_t element_address) { struct ndmmedia * me; if (mtab->n_media >= NDM_MAX_MEDIA) return NULL; me = NDMOS_API_MALLOC (sizeof(struct ndmmedia)); if (!me) { return NULL; } NDMOS_MACRO_ZEROFILL (me); me->valid_slot = 1; me->slot_addr = element_address; me->index = mtab->n_media + 1; me->next = NULL; if (mtab->tail) { mtab->tail->next = me; mtab->tail = me; } else { mtab->head = me; mtab->tail = me; } mtab->n_media++; return me; } /* * Clone an existing media entry and add it to the Media Table. * Return entry if caller want to modify it. */ struct ndmmedia * ndma_clone_media_entry (struct ndm_media_table *mtab, struct ndmmedia *to_clone) { struct ndmmedia * me; if (mtab->n_media >= NDM_MAX_MEDIA) return NULL; me = NDMOS_API_MALLOC (sizeof(struct ndmmedia)); if (!me) { return NULL; } memcpy (me, to_clone, sizeof(struct ndmmedia)); me->index = mtab->n_media + 1; me->next = NULL; if (mtab->tail) { mtab->tail->next = me; mtab->tail = me; } else { mtab->head = me; mtab->tail = me; } mtab->n_media++; return me; } /* * Destroy a Media Table. */ void ndmca_destroy_media_table (struct ndm_media_table *mtab) { struct ndmmedia * me, *next; for (me = mtab->head; me; me = next) { next = me->next; NDMOS_API_FREE (me); } mtab->head = NULL; mtab->tail = NULL; mtab->n_media = 0; } bareos-Release-14.2.6/src/ndmp/ndma_noti_calls.c000066400000000000000000000132121263011562700214560ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_DATA_AGENT /* * DATA Agent originated calls **************************************************************** */ int ndma_notify_data_halted (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.control; struct ndm_data_agent * da = sess->data_acb; assert (da->data_state.state == NDMP9_DATA_STATE_HALTED); assert (da->data_state.halt_reason != NDMP9_DATA_HALT_NA); NDMC_WITH_NO_REPLY(ndmp9_notify_data_halted, NDMP9VER) request->reason = da->data_state.halt_reason; ndma_send_to_control (sess, xa, sess->plumb.data); NDMC_ENDWITH return 0; } int ndma_notify_data_read (struct ndm_session *sess, uint64_t offset, uint64_t length) { struct ndmconn * conn = sess->plumb.control; NDMC_WITH_NO_REPLY(ndmp9_notify_data_read, NDMP9VER) request->offset = offset; request->length = length; ndma_send_to_control (sess, xa, sess->plumb.data); NDMC_ENDWITH return 0; } #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT int ndma_notify_mover_halted (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.control; struct ndm_tape_agent * ta = sess->tape_acb; assert (ta->mover_state.state == NDMP9_MOVER_STATE_HALTED); assert (ta->mover_state.halt_reason != NDMP9_MOVER_HALT_NA); NDMC_WITH_NO_REPLY(ndmp9_notify_mover_halted, NDMP9VER) request->reason = ta->mover_state.halt_reason; ndma_send_to_control (sess, xa, sess->plumb.tape); NDMC_ENDWITH return 0; } int ndma_notify_mover_paused (struct ndm_session *sess) { struct ndmconn * conn = sess->plumb.control; struct ndm_tape_agent * ta = sess->tape_acb; assert (ta->mover_state.state == NDMP9_MOVER_STATE_PAUSED); assert (ta->mover_state.pause_reason != NDMP9_MOVER_PAUSE_NA); NDMC_WITH_NO_REPLY(ndmp9_notify_mover_paused, NDMP9VER) request->reason = ta->mover_state.pause_reason; request->seek_position = ta->mover_want_pos; ndma_send_to_control (sess, xa, sess->plumb.tape); NDMC_ENDWITH return 0; } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS void ndma_send_logmsg (struct ndm_session *sess, ndmp9_log_type ltype, struct ndmconn *from_conn, char *fmt, ...) { struct ndmconn * conn = from_conn; char buf[4096]; va_list ap; va_start (ap, fmt); vsnprintf (buf, sizeof(buf), fmt, ap); va_end (ap); if (!from_conn) return; switch (from_conn->protocol_version) { #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: switch (ltype) { default: case NDMP9_LOG_NORMAL: case NDMP9_LOG_ERROR: case NDMP9_LOG_WARNING: NDMC_WITH_NO_REPLY(ndmp2_log_log, NDMP2VER) request->entry = buf; ndma_send_to_control (sess, xa, from_conn); NDMC_ENDWITH break; case NDMP9_LOG_DEBUG: NDMC_WITH_NO_REPLY(ndmp2_log_debug, NDMP2VER) request->level = NDMP2_DBG_USER_INFO; request->message = buf; ndma_send_to_control (sess, xa, from_conn); NDMC_ENDWITH break; } break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH_NO_REPLY(ndmp3_log_message, NDMP3VER) switch (ltype) { default: case NDMP9_LOG_NORMAL: request->log_type = NDMP3_LOG_NORMAL; break; case NDMP9_LOG_DEBUG: request->log_type = NDMP3_LOG_DEBUG; break; case NDMP9_LOG_ERROR: request->log_type = NDMP3_LOG_ERROR; break; case NDMP9_LOG_WARNING: request->log_type = NDMP3_LOG_WARNING; break; } request->message_id = time(0); request->entry = buf; ndma_send_to_control (sess, xa, from_conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH_POST(ndmp4_log_message, NDMP4VER) switch (ltype) { default: case NDMP9_LOG_NORMAL: request->log_type = NDMP4_LOG_NORMAL; break; case NDMP9_LOG_DEBUG: request->log_type = NDMP4_LOG_DEBUG; break; case NDMP9_LOG_ERROR: request->log_type = NDMP4_LOG_ERROR; break; case NDMP9_LOG_WARNING: request->log_type = NDMP4_LOG_WARNING; break; } request->message_id = time(0); request->entry = buf; ndma_send_to_control (sess, xa, from_conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: /* BOGUS */ break; } } #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */ bareos-Release-14.2.6/src/ndmp/ndma_robot.c000066400000000000000000000051421263011562700204570ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_ROBOT_AGENT /* * Initialization and Cleanup **************************************************************** */ /* Initialize -- Set data structure to know value, ignore current value */ int ndmra_initialize (struct ndm_session *sess) { sess->robot_acb = NDMOS_API_MALLOC (sizeof(struct ndm_robot_agent)); if (!sess->robot_acb) return -1; NDMOS_MACRO_ZEROFILL (sess->robot_acb); sess->robot_acb->scsi_state.error = NDMP9_DEV_NOT_OPEN_ERR; return 0; } /* Commission -- Get agent ready. Entire session has been initialize()d */ int ndmra_commission (struct ndm_session *sess) { return 0; } /* Decommission -- Discard agent */ int ndmra_decommission (struct ndm_session *sess) { return 0; } /* Destroy -- Destroy agent */ int ndmra_destroy (struct ndm_session *sess) { if (!sess->robot_acb) { return 0; } #ifdef NDMOS_OPTION_ROBOT_SIMULATOR if (sess->robot_acb->sim_dir) { NDMOS_API_FREE (sess->robot_acb->sim_dir); } #endif NDMOS_API_FREE (sess->robot_acb); sess->robot_acb = NULL; return 0; } /* * Semantic actions are all handled directly by ndmos_scsi_* */ #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_robot_simulator.c000066400000000000000000000103651263011562700225610ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_ROBOT_AGENT #ifdef NDMOS_OPTION_ROBOT_SIMULATOR #include "scsiconst.h" #define ROBOT_CONTROLLER 0 #define ROBOT_ID 7 #define ROBOT_LUN 1 /* * interface */ void ndmos_scsi_register_callbacks (struct ndm_session *sess, struct ndm_robot_simulator_callbacks *callbacks) { /* * Only allow one register. */ if (!sess->nrsc) { sess->nrsc = NDMOS_API_MALLOC (sizeof(struct ndm_robot_simulator_callbacks)); if (sess->nrsc) { memcpy (sess->nrsc, callbacks, sizeof(struct ndm_robot_simulator_callbacks)); } } } void ndmos_scsi_unregister_callbacks (struct ndm_session *sess) { if (sess->nrsc) { NDMOS_API_FREE (sess->nrsc); sess->nrsc = NULL; } } int ndmos_scsi_initialize (struct ndm_session *sess) { struct ndm_robot_agent * ra = sess->robot_acb; NDMOS_MACRO_ZEROFILL (&ra->scsi_state); ra->scsi_state.error = NDMP9_DEV_NOT_OPEN_ERR; ra->scsi_state.target_controller = ROBOT_CONTROLLER; ra->scsi_state.target_id = ROBOT_ID; ra->scsi_state.target_lun = ROBOT_LUN; return 0; } void ndmos_scsi_sync_state (struct ndm_session *sess) { } ndmp9_error ndmos_scsi_open (struct ndm_session *sess, char *name) { ndmp9_error err; if (!name || strlen(name) > NDMOS_CONST_PATH_MAX - 1) return NDMP9_NO_DEVICE_ERR; if (sess->nrsc && sess->nrsc->scsi_open) { err = sess->nrsc->scsi_open(sess, name); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } ndmp9_error ndmos_scsi_close (struct ndm_session *sess) { ndmp9_error err; if (sess->nrsc && sess->nrsc->scsi_close) { err = sess->nrsc->scsi_close(sess); if (err != NDMP9_NO_ERR) return err; } ndmos_scsi_initialize(sess); return NDMP9_NO_ERR; } /* deprecated */ ndmp9_error ndmos_scsi_set_target (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_reset_device (struct ndm_session *sess) { ndmp9_error err; struct ndm_robot_agent * ra = sess->robot_acb; if (sess->nrsc && sess->nrsc->scsi_reset) { err = sess->nrsc->scsi_reset(sess); if (err != NDMP9_NO_ERR) return err; } return ra->scsi_state.error; } /* deprecated */ ndmp9_error ndmos_scsi_reset_bus (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { ndmp9_error err; struct ndm_robot_agent * ra = sess->robot_acb; if (ra->scsi_state.error != NDMP9_NO_ERR) return ra->scsi_state.error; if (request->cdb.cdb_len < 1) return NDMP9_ILLEGAL_ARGS_ERR; if (sess->nrsc && sess->nrsc->scsi_execute_cdb) { err = sess->nrsc->scsi_execute_cdb(sess, request, reply); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_tape.c000066400000000000000000000404571263011562700202730ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* * Initialization and Cleanup **************************************************************** */ /* Initialize -- Set data structure to know value, ignore current value */ int ndmta_initialize (struct ndm_session *sess) { int rc; sess->tape_acb = NDMOS_API_MALLOC (sizeof(struct ndm_tape_agent)); if (!sess->tape_acb) return -1; NDMOS_MACRO_ZEROFILL (sess->tape_acb); ndmta_commission (sess); rc = ndmos_tape_initialize (sess); if (rc) return rc; return 0; } /* Commission -- Get agent ready. Entire session has been initialize()d */ int ndmta_commission (struct ndm_session *sess) { ndmta_init_mover_state (sess); return 0; } /* Decommission -- Discard agent */ int ndmta_decommission (struct ndm_session *sess) { if (!sess->tape_acb) return 0; ndmis_tape_close (sess); return 0; } /* Destroy -- Destroy agent */ int ndmta_destroy (struct ndm_session *sess) { if (!sess->tape_acb) return 0; if (sess->tape_acb->tape_buffer) { NDMOS_API_FREE (sess->tape_acb->tape_buffer); } #ifdef NDMOS_OPTION_TAPE_SIMULATOR if (sess->tape_acb->drive_name) { NDMOS_API_FREE (sess->tape_acb->drive_name); } #endif NDMOS_API_FREE (sess->tape_acb); sess->tape_acb = NULL; return 0; } /* helper for mover state */ int ndmta_init_mover_state (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; NDMOS_MACRO_ZEROFILL (&ta->mover_state); ta->mover_state.state = NDMP9_MOVER_STATE_IDLE; ta->mover_state.window_offset = 0; ta->mover_state.record_num = 0; /* this should probably be -1, but spec says 0 */ ta->mover_state.record_size = 20*512; /* traditional tar default */ ta->mover_state.window_length = NDMP_LENGTH_INFINITY; ta->mover_window_end = NDMP_LENGTH_INFINITY; ta->mover_want_pos = 0; ta->tb_blockno = -1; return 0; } /* * Semantic actions -- called from ndma_dispatch() **************************************************************** */ void ndmta_mover_sync_state (struct ndm_session *sess) { ndmos_tape_sync_state (sess); } ndmp9_error ndmta_mover_listen (struct ndm_session *sess, ndmp9_mover_mode mover_mode) { struct ndm_tape_agent * ta = sess->tape_acb; ta->mover_state.mode = mover_mode; ta->mover_state.state = NDMP9_MOVER_STATE_LISTEN; ta->mover_state.halt_reason = NDMP9_MOVER_HALT_NA; ta->mover_state.pause_reason = NDMP9_MOVER_PAUSE_NA; return NDMP9_NO_ERR; } ndmp9_error ndmta_mover_connect (struct ndm_session *sess, ndmp9_mover_mode mover_mode) { struct ndm_tape_agent * ta = sess->tape_acb; ta->mover_state.mode = mover_mode; ndmta_mover_start_active (sess); return NDMP9_NO_ERR; } void ndmta_mover_halt (struct ndm_session *sess, ndmp9_mover_halt_reason reason) { struct ndm_tape_agent * ta = sess->tape_acb; ta->mover_state.state = NDMP9_MOVER_STATE_HALTED; ta->mover_state.halt_reason = reason; ta->mover_state.pause_reason = NDMP9_MOVER_PAUSE_NA; ta->pending_change_after_drain = 0; ta->mover_notify_pending = 1; ndmis_tape_close (sess); } void ndmta_mover_pause (struct ndm_session *sess, ndmp9_mover_pause_reason reason) { struct ndm_tape_agent * ta = sess->tape_acb; ta->mover_state.state = NDMP9_MOVER_STATE_PAUSED; ta->mover_state.halt_reason = NDMP9_MOVER_HALT_NA; ta->mover_state.pause_reason = reason; ta->pending_change_after_drain = 0; ta->mover_notify_pending = 1; } void ndmta_mover_pending (struct ndm_session *sess, ndmp9_mover_state pending_state, ndmp9_mover_halt_reason halt_reason, ndmp9_mover_pause_reason pause_reason) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->pending_change_after_drain) { /* internal botch */ } ta->pending_mover_state = pending_state; ta->pending_mover_halt_reason = halt_reason; ta->pending_mover_pause_reason = pause_reason; ta->pending_change_after_drain = 1; } void ndmta_mover_apply_pending (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (!ta->pending_change_after_drain) { /* internal botch */ } ta->mover_state.state = ta->pending_mover_state; ta->mover_state.halt_reason = ta->pending_mover_halt_reason; ta->mover_state.pause_reason = ta->pending_mover_pause_reason; ta->pending_change_after_drain = 0; ta->mover_notify_pending = 1; } void ndmta_mover_halt_pending (struct ndm_session *sess, ndmp9_mover_halt_reason halt_reason) { ndmta_mover_pending (sess, NDMP9_MOVER_STATE_HALTED, halt_reason, NDMP9_MOVER_PAUSE_NA); } void ndmta_mover_pause_pending (struct ndm_session *sess, ndmp9_mover_pause_reason pause_reason) { ndmta_mover_pending (sess, NDMP9_MOVER_STATE_PAUSED, NDMP9_MOVER_HALT_NA, pause_reason); } void ndmta_mover_active (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; ta->mover_state.state = NDMP9_MOVER_STATE_ACTIVE; ta->mover_state.halt_reason = NDMP9_MOVER_HALT_NA; ta->mover_state.pause_reason = NDMP9_MOVER_PAUSE_NA; ta->tb_blockno = -1; /* always mistrust after activating */ } void ndmta_mover_start_active (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; ndmalogf (sess, 0, 6, "mover going active"); ndma_send_logmsg(sess, NDMP9_LOG_DEBUG, sess->plumb.control, "mover going active"); switch (ta->mover_state.mode) { case NDMP9_MOVER_MODE_READ: ndmis_tape_start (sess, NDMCHAN_MODE_READ); ndmta_mover_active (sess); break; case NDMP9_MOVER_MODE_WRITE: ndmis_tape_start (sess, NDMCHAN_MODE_WRITE); ndmta_mover_active (sess); break; default: ndmalogf (sess, 0, 0, "BOTCH mover listen, unknown mode"); break; } } void ndmta_mover_stop (struct ndm_session *sess) { ndmta_init_mover_state (sess); } void ndmta_mover_abort (struct ndm_session *sess) { ndmta_mover_halt (sess, NDMP9_MOVER_HALT_ABORTED); } void ndmta_mover_continue (struct ndm_session *sess) { ndmta_mover_active (sess); } void ndmta_mover_close (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->mover_state.state != NDMP9_MOVER_STATE_HALTED) ndmta_mover_halt (sess, NDMP9_MOVER_HALT_CONNECT_CLOSED); } void ndmta_mover_read (struct ndm_session *sess, uint64_t offset, uint64_t length) { struct ndm_tape_agent * ta = sess->tape_acb; ta->mover_state.seek_position = offset; ta->mover_state.bytes_left_to_read = length; ta->mover_want_pos = offset; } /* * Quantum -- get a bit of work done **************************************************************** */ int ndmta_quantum (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; int rc = 0; /* did nothing */ switch (ta->mover_state.state) { default: ndmalogf (sess, 0, 0, "BOTCH mover state"); return -1; case NDMP9_MOVER_STATE_IDLE: case NDMP9_MOVER_STATE_PAUSED: case NDMP9_MOVER_STATE_HALTED: break; case NDMP9_MOVER_STATE_LISTEN: switch (sess->plumb.image_stream->tape_ep.connect_status) { case NDMIS_CONN_LISTEN: /* no connection yet */ break; case NDMIS_CONN_ACCEPTED: /* we're in business */ ndmta_mover_start_active (sess); rc = 1; /* did something */ break; case NDMIS_CONN_BOTCHED: /* accept() went south */ default: /* ain't suppose to happen */ ndmta_mover_halt(sess,NDMP9_MOVER_HALT_CONNECT_ERROR); break; } break; case NDMP9_MOVER_STATE_ACTIVE: switch (ta->mover_state.mode) { case NDMP9_MOVER_MODE_READ: rc = ndmta_read_quantum (sess); break; case NDMP9_MOVER_MODE_WRITE: rc = ndmta_write_quantum (sess); break; default: ndmalogf (sess, 0, 0, "BOTCH mover active, unknown mode"); return -1; } break; } ndmta_mover_send_notice (sess); return rc; } int ndmta_read_quantum (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; struct ndmchan * ch = &sess->plumb.image_stream->chan; uint32_t count = ta->mover_state.record_size; int did_something = 0; unsigned n_ready; char * data; uint32_t done_count; ndmp9_error error; again: n_ready = ndmchan_n_ready (ch); if (ch->eof) { if (n_ready == 0) { /* done */ if (ch->saved_errno) ndmta_mover_halt (sess, NDMP9_MOVER_HALT_CONNECT_ERROR); else ndmta_mover_halt (sess, NDMP9_MOVER_HALT_CONNECT_CLOSED); did_something++; return did_something; } if (n_ready < count) { int n_pad = count - n_ready; int n_avail; while (n_pad > 0) { n_avail = ndmchan_n_avail (ch); if (n_avail == 0) { /* Uh-oh */ } data = &ch->data[ch->end_ix]; if (n_avail > n_pad) n_avail = n_pad; bzero (data, n_avail); ch->end_ix += n_avail; n_pad -= n_avail; } n_ready = ndmchan_n_ready (ch); } } if (n_ready < count) { return did_something; /* blocked */ } if (ta->mover_want_pos >= ta->mover_window_end) { ndmta_mover_pause (sess, NDMP9_MOVER_PAUSE_SEEK); did_something++; return did_something; } data = &ch->data[ch->beg_ix]; done_count = 0; error = ndmos_tape_write (sess, data, count, &done_count); switch (error) { case NDMP9_NO_ERR: if (done_count != count) { /* This ain't suppose to happen */ } ta->mover_state.bytes_moved += count; /* note this is calculated before mover_want_pos is incremented, since * record_num is the *last* block processed */ ta->mover_state.record_num = ta->mover_want_pos / ta->mover_state.record_size; ta->mover_want_pos += count; ch->beg_ix += count; did_something++; goto again; /* write as much to tape as possible */ case NDMP9_EOM_ERR: ndmta_mover_pause (sess, NDMP9_MOVER_PAUSE_EOM); did_something++; break; default: ndmta_mover_halt (sess, NDMP9_MOVER_HALT_MEDIA_ERROR); did_something++; break; } return did_something; } int ndmta_write_quantum (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; struct ndmchan * ch = &sess->plumb.image_stream->chan; uint32_t count = ta->mover_state.record_size; int did_something = 0; uint64_t max_read; uint64_t want_window_off; uint32_t block_size; uint32_t want_blockno; uint32_t cur_blockno; unsigned n_avail, n_read, record_off; char * data; uint32_t done_count = 0; ndmp9_error error; again: n_read = n_avail = ndmchan_n_avail_record (ch, count); if (n_avail < count) { /* allow to drain */ return did_something; } if (ta->pending_change_after_drain) { if (ndmchan_n_ready (ch) > 0) { /* allow to drain */ } else { ndmta_mover_apply_pending (sess); did_something++; } return did_something; } if (n_read > ta->mover_state.bytes_left_to_read) n_read = ta->mover_state.bytes_left_to_read; if (n_read < count) { /* Active, but paused awaiting MOVER_READ request */ return did_something; /* mover blocked */ } if (ta->mover_want_pos < ta->mover_state.window_offset || ta->mover_want_pos >= ta->mover_window_end) { ndmta_mover_pause_pending (sess, NDMP9_MOVER_PAUSE_SEEK); goto again; } max_read = ta->mover_window_end - ta->mover_want_pos; if (n_read > max_read) n_read = max_read; want_window_off = ta->mover_want_pos - ta->mover_state.window_offset; /* make an estimate of the block size - the tape agent's block size, or * if it's in variable block size mode, the mover's record size: "When * in variable block mode, as indicated by a tape block_size value of * zero, the mover record size defines the actual block size used by * the tape subsystem." (NDMPv4 RFC, Section 3.6.2.1) */ block_size = ta->tape_state.block_size.value; if (!block_size) block_size = ta->mover_state.record_size; want_blockno = ta->mover_window_first_blockno + want_window_off / block_size; if (ta->tb_blockno != want_blockno) { uint32_t xsr_count, xsr_resid; ndmos_tape_sync_state(sess); cur_blockno = ta->tape_state.blockno.value; if (cur_blockno < want_blockno) { xsr_count = want_blockno - cur_blockno; error = ndmos_tape_mtio (sess, NDMP9_MTIO_FSR, xsr_count, &xsr_resid); if (error == NDMP9_EOF_ERR) { ndmta_mover_pause_pending (sess, NDMP9_MOVER_PAUSE_EOF); goto again; } if (error != NDMP9_NO_ERR) { ndmta_mover_halt_pending (sess, NDMP9_MOVER_HALT_MEDIA_ERROR); goto again; } if (xsr_resid > 0) { ndmta_mover_pause_pending (sess, NDMP9_MOVER_PAUSE_EOF); goto again; } } else if (cur_blockno > want_blockno) { xsr_count = cur_blockno - want_blockno; error = ndmos_tape_mtio (sess, NDMP9_MTIO_BSR, xsr_count, &xsr_resid); if (error != NDMP9_NO_ERR || xsr_resid > 0) { ndmta_mover_halt_pending (sess, NDMP9_MOVER_HALT_MEDIA_ERROR); goto again; } } else { /* in position */ } /* * We are about to read data into a tape buffer so make sure * we have it available. We delay allocating buffers to the * moment we first need them. */ if (!ta->tape_buffer) { ta->tape_buffer = NDMOS_API_MALLOC (NDMOS_CONST_TAPE_REC_MAX); if (!ta->tape_buffer) { ndmta_mover_pause_pending (sess, NDMP9_MOVER_HALT_NA); goto again; } } data = ta->tape_buffer; done_count = 0; error = ndmos_tape_read (sess, data, count, &done_count); did_something++; if (error == NDMP9_EOF_ERR) { ndmta_mover_pause_pending (sess, NDMP9_MOVER_PAUSE_EOF); goto again; } /* N.B. - handling of done_count = 0 here is hacked to support * non-blocking writes to a socket in amndmjob */ if (error != NDMP9_NO_ERR) { ndmta_mover_halt_pending (sess, NDMP9_MOVER_HALT_MEDIA_ERROR); goto again; } if (done_count == 0) { return did_something - 1; } if (done_count != count) { goto again; } ta->tb_blockno = want_blockno; /* re-calcluate this, since record_size may be > block_size, in which * case the record_num may not change for each block read from tape */ ta->mover_state.record_num = ta->mover_want_pos / ta->mover_state.record_size; } record_off = ta->mover_want_pos % ta->mover_state.record_size; n_avail = ta->mover_state.record_size - record_off; if (n_read > n_avail) n_read = n_avail; if (n_read != done_count) { printf("lost %lu bytes %lu %u\n", done_count - n_read, done_count, n_read); n_read = done_count; } /* * We are about to read data into a tape buffer so make sure * we have it available. We delay allocating buffers to the * moment we first need them. */ if (!ta->tape_buffer) { ta->tape_buffer = NDMOS_API_MALLOC (NDMOS_CONST_TAPE_REC_MAX); if (!ta->tape_buffer) { ndmta_mover_pause_pending (sess, NDMP9_MOVER_HALT_NA); goto again; } } data = &ta->tape_buffer[record_off]; bcopy (data, ch->data + ch->end_ix, n_read); ch->end_ix += n_read; ta->mover_state.bytes_moved += n_read; ta->mover_want_pos += n_read; ta->mover_state.bytes_left_to_read -= n_read; did_something++; goto again; /* do as much as possible */ } void ndmta_mover_send_notice (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (!ta->mover_notify_pending) return; ta->mover_notify_pending = 0; switch (ta->mover_state.state) { case NDMP9_MOVER_STATE_HALTED: ndma_notify_mover_halted (sess); break; case NDMP9_MOVER_STATE_PAUSED: ndma_notify_mover_paused (sess); break; default: /* Hmm. Why are we here. Race? */ break; } } #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ bareos-Release-14.2.6/src/ndmp/ndma_tape_simulator.c000066400000000000000000000152401263011562700223620ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef NDMOS_OPTION_NO_TAPE_AGENT #ifdef NDMOS_OPTION_TAPE_SIMULATOR void ndmos_tape_register_callbacks (struct ndm_session *sess, struct ndm_tape_simulator_callbacks *callbacks) { /* * Only allow one register. */ if (!sess->ntsc) { sess->ntsc = NDMOS_API_MALLOC (sizeof(struct ndm_tape_simulator_callbacks)); memcpy(sess->ntsc, callbacks, sizeof(struct ndm_tape_simulator_callbacks)); } } void ndmos_tape_unregister_callbacks (struct ndm_session *sess) { if (!sess->ntsc) { NDMOS_API_FREE (sess->ntsc); sess->ntsc = NULL; } } int ndmos_tape_initialize (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; ta->tape_fd = -1; NDMOS_MACRO_ZEROFILL (&ta->tape_state); ta->tape_state.error = NDMP9_DEV_NOT_OPEN_ERR; ta->tape_state.state = NDMP9_TAPE_STATE_IDLE; return 0; } ndmp9_error ndmos_tape_open (struct ndm_session *sess, char *drive_name, int will_write) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd >= 0) { ndma_send_logmsg(sess, NDMP9_LOG_ERROR, sess->plumb.control, "device simulator is already open"); return NDMP9_DEVICE_OPENED_ERR; } if (sess->ntsc && sess->ntsc->tape_open) { err = sess->ntsc->tape_open(sess, drive_name, will_write); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } ndmp9_error ndmos_tape_close (struct ndm_session *sess) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (sess->ntsc && sess->ntsc->tape_close) { err = sess->ntsc->tape_close(sess); if (err != NDMP9_NO_ERR) return err; } ndmos_tape_initialize (sess); return NDMP9_NO_ERR; } void ndmos_tape_sync_state (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd < 0) { ta->tape_state.error = NDMP9_DEV_NOT_OPEN_ERR; ta->tape_state.state = NDMP9_TAPE_STATE_IDLE; ta->tape_state.file_num.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.soft_errors.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.block_size.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.blockno.valid = NDMP9_VALIDITY_INVALID; } else { ta->tape_state.error = NDMP9_NO_ERR; if (ta->mover_state.state == NDMP9_MOVER_STATE_ACTIVE) ta->tape_state.state = NDMP9_TAPE_STATE_MOVER; else ta->tape_state.state = NDMP9_TAPE_STATE_OPEN; ta->tape_state.file_num.valid = NDMP9_VALIDITY_VALID; ta->tape_state.soft_errors.valid = NDMP9_VALIDITY_VALID; ta->tape_state.block_size.valid = NDMP9_VALIDITY_VALID; ta->tape_state.blockno.valid = NDMP9_VALIDITY_VALID; } return; } ndmp9_error ndmos_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; *resid = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } /* audit for valid op and for tape mode */ switch (op) { case NDMP9_MTIO_FSF: break; case NDMP9_MTIO_BSF: break; case NDMP9_MTIO_FSR: break; case NDMP9_MTIO_BSR: break; case NDMP9_MTIO_REW: break; case NDMP9_MTIO_OFF: break; case NDMP9_MTIO_EOF: break; default: return NDMP9_ILLEGAL_ARGS_ERR; } if (sess->ntsc && sess->ntsc->tape_mtio) { err = sess->ntsc->tape_mtio(sess, op, count, resid); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } ndmp9_error ndmos_tape_write (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } if (count == 0) { /* * NDMPv4 clarification -- a tape read or write with * a count==0 is a no-op. This is undoubtedly influenced * by the SCSI Sequential Access specification which * says much the same thing. */ *done_count = 0; return NDMP9_NO_ERR; } if (sess->ntsc && sess->ntsc->tape_write) { err = sess->ntsc->tape_write(sess, buf, count, done_count); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } ndmp9_error ndmos_tape_wfm (struct ndm_session *sess) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; ta->weof_on_close = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } if (sess->ntsc && sess->ntsc->tape_wfm) { err = sess->ntsc->tape_wfm(sess); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } ndmp9_error ndmos_tape_read (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (count == 0) { /* * NDMPv4 clarification -- a tape read or write with * a count==0 is a no-op. This is undoubtedly influenced * by the SCSI Sequential Access specification which * says much the same thing. */ *done_count = 0; return NDMP9_NO_ERR; } if (sess->ntsc && sess->ntsc->tape_read) { err = sess->ntsc->tape_read(sess, buf, count, done_count); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; } #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ bareos-Release-14.2.6/src/ndmp/ndmagents.h000066400000000000000000001361101263011562700203200ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * ******************************************************************** * * NDMP Elements of a backup/restore session * * +-----+ ########### * | Job |----># CONTROL # +----------------+ * +-----+ # Agent #<---->|FILE/MEDIA INDEX| * # # +----------------+ * ########### * | | | * +----------------+ | +---------------------+ * | control | connections | * V V V * ############ ############ +-------+ ######### * # DATA # # TAPE # | | # ROBOT # * # Agent # # Agent # | ROBOT |<-># Agent # * +-----+ # +------+ # image # +------+ # |+-----+| # # * |FILES|====|butype|============|mover |=====|DRIVE|| # # * +-----+ # +------+ # stream # +------+ # |+-----+| # # * ############ ############ +-------+ ######### * * ******************************************************************** * * NDMAGENTS components overview * * * "job" -> ndma_client_session() ndma_server_session() * | | * /-------------/ Q * | v * | +------------------------------------+ +-----------+ * | /->| SESSION QUANTUM |----->| disp conn | * | | +------------------------------------+ \ +-----------+ * | Q Q Q Q Q Q | v | * | | | | | | | | +----------+ | * | /-----|----+--|----+----|----+--|----+---|----| dispatch | | * | | | | | | | | | | | | | | request | | * | v | v v v v v v v v v | +----------+ | * | +-------+ +----+ +------+ +----+ +-----+ | ^ | * +>|CONTROL| |DATA| |IMAGE | |TAPE| |ROBOT| | | | * | | | |->|STREAM|<-| | | | | | | * | | | *====* *====* | | | | | ndmconn_recv() * | ndmca | ndmda| |ndmis | ndmta| |ndmra| | | | * +-------+ +----+ +------+ +----+ +-----+ | |resi | * | | | | | | | +------+ | * \-----|-+----|----+-------+-------------->| call | | * | | | +------+ | * formatter| |image_stream | |remo | * v v | v v * +---------+<---ndmchan_poll()----/ +---------+ * | ndmchan |<---------------------------| ndmconn | * +---------+ +---------+ * non-blocking I/O XDR wrapper * * -----> caller/callee * --Q--> quantum (CPU scheduling) * ====== image stream shared data structures * ******************************************************************** */ #include "ndmp/ndmlib.h" #ifdef __cplusplus extern "C" { #endif /* * VERSION AND RELEASE CONSTANTS -- KEEPER ONLY **************************************************************** * * Revision constants for the source code. These may only be * changed by the keeper of these sources. Contact ndmp-tech@ndmp.org * for a pointer to the latest sources and the current keeper. * * The Version increases every time there is a significant * design change. Significant means new functionality, * reorganization of key data structures, etc. The Release * increases every time the keeper releases an update to * the current version, such as bug fixes or integration * of new contributions. * * There are provisions for a free-form string for revisions * of the O/S specific portions (NDMOS_CONST_NDMOS_REVISION) * and for local revisions (NDMOS_CONST_NDMJOBLIB_REVISION) * which reflect in-house change levels. */ #define NDMJOBLIB_VERSION 1 #define NDMJOBLIB_RELEASE 2 struct ndm_session; /* forward decl */ /* * NDM_ENV_TABLE and NDM_NLIST_TABLE **************************************************************** * Used by DATA and CONTROL agents */ #ifndef NDM_MAX_ENV #define NDM_MAX_ENV 1024 #endif struct ndm_env_entry { ndmp9_pval pval; struct ndm_env_entry * next; }; struct ndm_env_table { int32_t n_env; ndmp9_pval * enumerate; int32_t enumerate_length; struct ndm_env_entry * head; struct ndm_env_entry * tail; }; /* ndma_listmgt.c */ extern ndmp9_pval * ndma_enumerate_env_list (struct ndm_env_table *envtab); extern struct ndm_env_entry * ndma_store_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv); extern struct ndm_env_entry * ndma_update_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv); extern void ndma_destroy_env_list (struct ndm_env_table *envtab); #ifndef NDM_MAX_NLIST #define NDM_MAX_NLIST 10240 #endif struct ndm_nlist_entry { ndmp9_name name; ndmp9_error result_err; unsigned result_count; struct ndm_nlist_entry * next; }; struct ndm_nlist_table { int32_t n_nlist; ndmp9_name * enumerate; int32_t enumerate_length; struct ndm_nlist_entry * head; struct ndm_nlist_entry * tail; }; /* ndma_listmgt.c */ extern ndmp9_name * ndma_enumerate_nlist (struct ndm_nlist_table *nlist); extern struct ndm_nlist_entry * ndma_store_nlist (struct ndm_nlist_table *nlist, ndmp9_name *nl); extern void ndma_destroy_nlist (struct ndm_nlist_table *nlist); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT /* * CONTROL AGENT **************************************************************** */ #include "ndmp/smc.h" /* SCSI Media Changer */ #ifndef NDM_MAX_MEDIA #define NDM_MAX_MEDIA 40 #endif struct ndm_media_table { int32_t n_media; struct ndmmedia *head; struct ndmmedia *tail; }; /* ndma_listmgt.c */ extern struct ndmmedia * ndma_store_media (struct ndm_media_table *mtab, uint16_t element_address); extern struct ndmmedia * ndma_clone_media_entry (struct ndm_media_table *mtab, struct ndmmedia *to_clone); extern void ndmca_destroy_media_table (struct ndm_media_table *mtab); #define NDM_JOB_OP_BACKUP (0x100 | 'c') #define NDM_JOB_OP_EXTRACT (0x100 | 'x') #define NDM_JOB_OP_TOC (0x100 | 't') #define NDM_JOB_OP_QUERY_AGENTS (0x100 | 'q') #define NDM_JOB_OP_INIT_LABELS (0x100 | 'I') #define NDM_JOB_OP_LIST_LABELS (0x100 | 'L') #define NDM_JOB_OP_REMEDY_ROBOT (0x100 | 'Z') /* test operations */ #define NDM_JOB_OP_TEST_TAPE (0x200 | 'T') #define NDM_JOB_OP_TEST_MOVER (0x200 | 'M') #define NDM_JOB_OP_TEST_DATA (0x200 | 'D') /* tape handling operations */ #define NDM_JOB_OP_REWIND_TAPE (0x300 | 'r') #define NDM_JOB_OP_EJECT_TAPE (0x300 | 'j') #define NDM_JOB_OP_MOVE_TAPE (0x300 | 'm') #define NDM_JOB_OP_LOAD_TAPE (0x300 | 'l') #define NDM_JOB_OP_UNLOAD_TAPE (0x300 | 'u') #define NDM_JOB_OP_IMPORT_TAPE (0x300 | 'i') #define NDM_JOB_OP_EXPORT_TAPE (0x300 | 'e') #define NDM_JOB_OP_INIT_ELEM_STATUS (0x300 | 'I') /* daemon operations */ #define NDM_JOB_OP_DAEMON 'd' struct ndm_job_param { int32_t operation; /* NDM_JOB_OP_... */ int32_t time_limit; /* command timeout, 0 is off */ struct ndmagent data_agent; /* DATA AGENT host/pw */ char * bu_type; /* e.g. "tar" */ int32_t bu_level; /* e.g. 0..9 for dump */ struct ndm_env_table env_tab; /* for BACKUP+RECOVER ops */ struct ndm_nlist_table nlist_tab; /* for RECOVER ops */ struct ndm_env_table result_env_tab; /* after BACKUP */ struct ndmlog index_log; /* to log NDMP_FH_ADD_... */ struct ndmagent tape_agent; /* TAPE AGENT host/pw */ char * tape_device; /* eg "/dev/rmt0" */ unsigned tape_timeout; /* secs total to retry open */ unsigned record_size; /* in bytes, 10k typical */ uint64_t last_w_offset; /* last window offset sent */ struct ndmscsi_target * tape_target; /* unused for now */ char * tape_tcp; /* tcp direct */ NDM_FLAG_DECL(use_eject) /* eject upon close (unload) */ struct ndmagent robot_agent; /* ROBOT AGENT host/pw */ struct ndmscsi_target * robot_target; /* SCSI coord of robot */ unsigned robot_timeout; /* secs total to retry move */ NDM_FLAG_DECL(have_robot) /* yes, we have robot, today */ NDM_FLAG_DECL(auto_remedy) /* if drive loaded, unload */ NDM_FLAG_DECL(remedy_all) /* OP_REMEDY, all drives */ NDM_FLAG_DECL(drive_addr_given) NDM_FLAG_DECL(from_addr_given) NDM_FLAG_DECL(to_addr_given) unsigned drive_addr; /* 0->first, !0->elem addr */ unsigned from_addr; /* for MOVE and EXPORT */ unsigned to_addr; /* for MOVE and IMPORT */ /* use move for many I/E */ struct ndm_media_table media_tab; /* media to use, params */ struct ndm_media_table result_media_tab; /* results after job */ uint32_t n_file_entry; uint32_t n_dir_entry; uint32_t n_node_entry; uint64_t root_node; uint64_t bytes_written; uint64_t bytes_read; }; /* ndma_job.c */ extern int ndma_job_audit (struct ndm_job_param *job, char *errbuf, int errskip); extern int ndma_job_media_audit (struct ndm_job_param *job, char *errbuf, int errskip); extern void ndma_job_auto_adjust (struct ndm_job_param *job); struct ndm_control_agent { /* The JOB, see immediately above */ struct ndm_job_param job; NDM_FLAG_DECL(swap_connect) NDM_FLAG_DECL(has_tcp_addr) NDM_FLAG_DECL(has_local_addr) /* DATA agent */ ndmp9_data_operation data_op; ndmp9_data_get_state_reply data_state; NDM_FLAG_DECL(pending_notify_data_read) NDM_FLAG_DECL(pending_notify_data_halted) ndmp9_notify_data_read_request last_notify_data_read; ndmp9_addr data_addr; int32_t recover_log_file_count; int32_t recover_log_file_ok; int32_t recover_log_file_error; /* Image stream */ ndmp9_addr mover_addr; ndmp9_mover_mode mover_mode; /* TAPE Agent */ ndmp9_mover_get_state_reply mover_state; NDM_FLAG_DECL(pending_notify_mover_paused) NDM_FLAG_DECL(pending_notify_mover_halted) ndmp9_notify_mover_paused_request last_notify_mover_paused; ndmp9_tape_open_mode tape_mode; ndmp9_tape_get_state_reply tape_state; /* Media management, media_table inside of job */ int32_t cur_media_ix; /* references struct ndmmedia index field */ NDM_FLAG_DECL(media_is_loaded) NDM_FLAG_DECL(is_label_op) /* ROBOT Agent */ struct smc_ctrl_block * smc_cb; unsigned drive_addr; #ifndef NDMOS_OPTION_NO_TEST_AGENTS /* when testing */ char * active_test; /* name of test or 0 if no test */ char * active_test_failed; /* active test failed */ char * active_test_warned; /* active test warned */ char * test_phase; /* name of sub-series test phase */ int32_t test_step; /* test sequence number */ int32_t n_step_pass; /* per phase test stats */ int32_t n_step_fail; int32_t n_step_warn; int32_t n_step_tests; int32_t total_n_step_pass; /* total test stats */ int32_t total_n_step_fail; int32_t total_n_step_warn; int32_t total_n_step_tests; #endif #ifdef NDMOS_MACRO_CONTROL_AGENT_ADDITIONS NDMOS_MACRO_CONTROL_AGENT_ADDITIONS #endif /* NDMOS_MACRO_CONTROL_AGENT_ADDITIONS */ }; /* ndma_control.c */ extern int ndmca_initialize (struct ndm_session *sess); extern int ndmca_commission (struct ndm_session *sess); extern int ndmca_decommission (struct ndm_session *sess); extern int ndmca_destroy (struct ndm_session *sess); extern int ndmca_control_agent (struct ndm_session *sess); /* ndma_cops_backreco.c */ extern int ndmca_op_create_backup (struct ndm_session *sess); extern int ndmca_op_recover_files (struct ndm_session *sess); extern int ndmca_op_recover_fh (struct ndm_session *sess); extern int ndmca_monitor_backup (struct ndm_session *sess); extern int ndmca_monitor_get_post_backup_env (struct ndm_session *sess); extern int ndmca_monitor_recover (struct ndm_session *sess); extern int ndmca_backreco_startup (struct ndm_session *sess); extern int ndmca_monitor_startup (struct ndm_session *sess); extern int ndmca_monitor_shutdown (struct ndm_session *sess); extern int ndmca_monitor_get_states (struct ndm_session *sess); extern int ndmca_monitor_load_next (struct ndm_session *sess); extern int ndmca_monitor_seek_tape (struct ndm_session *sess); extern int ndmca_monitor_unload_last_tape (struct ndm_session *sess); extern int ndmca_mon_wait_for_something (struct ndm_session *sess, int32_t max_delay_secs); /* ndma_cops_labels.c */ extern int ndmca_op_init_labels (struct ndm_session *sess); extern int ndmca_op_list_labels (struct ndm_session *sess); /* ndma_cops_query.c */ extern int ndmca_op_query (struct ndm_session *sess); extern int ndmca_opq_data (struct ndm_session *sess); extern int ndmca_opq_tape (struct ndm_session *sess); extern int ndmca_opq_robot (struct ndm_session *sess); extern int ndmca_opq_host_info (struct ndm_session *sess, struct ndmconn *conn); extern int ndmca_opq_get_mover_type (struct ndm_session *sess, struct ndmconn *conn); extern int ndmca_opq_get_butype_attr (struct ndm_session *sess, struct ndmconn *conn); extern int ndmca_opq_get_fs_info (struct ndm_session *sess, struct ndmconn *conn); extern int ndmca_opq_get_tape_info (struct ndm_session *sess, struct ndmconn *conn); extern int ndmca_opq_get_scsi_info (struct ndm_session *sess, struct ndmconn *conn); extern void ndmalogqr (struct ndm_session *sess, char *fmt, ...); /* ndma_cops_robot.c */ extern int ndmca_op_robot_remedy (struct ndm_session *sess); extern int ndmca_op_robot_startup (struct ndm_session *sess, int32_t verify_media_flag); extern int ndmca_op_init_elem_status (struct ndm_session *sess); extern int ndmca_op_rewind_tape (struct ndm_session *sess); extern int ndmca_op_eject_tape (struct ndm_session *sess); extern int ndmca_op_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op mtio_op); extern int ndmca_op_move_tape (struct ndm_session *sess); extern int ndmca_op_import_tape (struct ndm_session *sess); extern int ndmca_op_export_tape (struct ndm_session *sess); extern int ndmca_op_load_tape (struct ndm_session *sess); extern int ndmca_op_unload_tape (struct ndm_session *sess); /* ndma_ctrl_calls.c */ extern int ndmca_data_get_state (struct ndm_session *sess); extern int ndmca_data_connect (struct ndm_session *sess); extern int ndmca_data_listen (struct ndm_session *sess); extern int ndmca_data_start_backup (struct ndm_session *sess); extern int ndmca_data_start_recover (struct ndm_session *sess); extern int ndmca_data_start_recover_filehist (struct ndm_session *sess); extern int ndmca_data_abort (struct ndm_session *sess); extern int ndmca_data_get_env (struct ndm_session *sess); extern int ndmca_data_stop (struct ndm_session *sess); extern int ndmca_tape_open (struct ndm_session *sess); extern int ndmca_tape_close (struct ndm_session *sess); extern int ndmca_tape_get_state (struct ndm_session *sess); extern int ndmca_tape_get_state_no_tattle (struct ndm_session *sess); extern int ndmca_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid); extern int ndmca_tape_write (struct ndm_session *sess, char *buf, unsigned count); extern int ndmca_tape_read (struct ndm_session *sess, char *buf, unsigned count); extern int ndmca_mover_get_state (struct ndm_session *sess); extern int ndmca_mover_listen (struct ndm_session *sess); extern int ndmca_mover_connect (struct ndm_session *sess); extern int ndmca_mover_continue (struct ndm_session *sess); extern int ndmca_mover_abort (struct ndm_session *sess); extern int ndmca_mover_stop (struct ndm_session *sess); extern int ndmca_mover_set_window (struct ndm_session *sess, uint64_t offset, uint64_t length); extern int ndmca_mover_read (struct ndm_session *sess, uint64_t offset, uint64_t length); extern int ndmca_mover_close (struct ndm_session *sess); extern int ndmca_mover_set_record_size (struct ndm_session *sess); /* ndma_ctrl_media.c */ extern int ndmca_media_load_first (struct ndm_session *sess); extern int ndmca_media_load_next (struct ndm_session *sess); extern int ndmca_media_unload_last (struct ndm_session *sess); extern int ndmca_media_change (struct ndm_session *sess); extern int ndmca_media_load_seek (struct ndm_session *sess, uint64_t pos); extern int ndmca_media_load_current (struct ndm_session *sess); extern int ndmca_media_unload_current (struct ndm_session *sess); extern int ndmca_media_unload_best_effort (struct ndm_session *sess); extern int ndmca_media_open_tape (struct ndm_session *sess); extern int ndmca_media_close_tape (struct ndm_session *sess); extern int ndmca_media_mtio_tape (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid); extern int ndmca_media_write_filemarks (struct ndm_session *sess); extern int ndmca_media_read_label (struct ndm_session *sess, char labbuf[]); extern int ndmca_media_write_label (struct ndm_session *sess, int32_t type, char labbuf[]); extern int ndmca_media_check_label (struct ndm_session *sess, int32_t type, char labbuf[]); extern int ndmca_media_verify (struct ndm_session *sess); extern int ndmca_media_tattle (struct ndm_session *sess); extern uint64_t ndmca_media_capture_tape_offset (struct ndm_session *sess); extern int ndmca_media_capture_mover_window (struct ndm_session *sess); extern int ndmca_media_calculate_windows (struct ndm_session *sess); extern int ndmca_media_calculate_offsets (struct ndm_session *sess); extern int ndmca_media_set_window_current (struct ndm_session *sess); /* ndma_ctrl_robot.c */ extern int ndmca_robot_issue_scsi_req (struct smc_ctrl_block *smc); extern int ndmca_robot_prep_target (struct ndm_session *sess); extern int ndmca_robot_obtain_info (struct ndm_session *sess); extern int ndmca_robot_init_elem_status (struct ndm_session *sess); extern int ndmca_robot_startup (struct ndm_session *sess); extern int ndmca_robot_move (struct ndm_session *sess, int32_t src_addr, int32_t dst_addr); extern int ndmca_robot_load (struct ndm_session *sess, int32_t slot_addr); extern int ndmca_robot_unload (struct ndm_session *sess, int32_t slot_addr); extern struct smc_element_descriptor * ndmca_robot_find_element (struct ndm_session *sess, int32_t element_address); extern int ndmca_robot_check_ready (struct ndm_session *sess); extern int ndmca_robot_remedy_ready (struct ndm_session *sess); extern int ndmca_robot_query (struct ndm_session *sess); extern int ndmca_robot_verify_media (struct ndm_session *sess); extern int ndmca_robot_synthesize_media (struct ndm_session *sess); /* ndma_ctrl_conn.c */ extern int ndmca_connect_xxx_agent (struct ndm_session *sess, struct ndmconn **connp, char *prefix, struct ndmagent *agent); extern int ndmca_connect_data_agent (struct ndm_session *sess); extern int ndmca_connect_tape_agent (struct ndm_session *sess); extern int ndmca_connect_robot_agent (struct ndm_session *sess); extern int ndmca_connect_control_agent (struct ndm_session *sess); /* ndma_ctst_tape.c */ extern int ndmca_op_test_tape (struct ndm_session *sess); /* ndma_ctst_mover.c */ extern int ndmca_op_test_mover (struct ndm_session *sess); /* ndma_ctst_data.c */ extern int ndmca_op_test_data (struct ndm_session *sess); /* ndma_ctst_subr.c */ extern int ndmca_test_query_conn_types (struct ndm_session *sess, struct ndmconn *ref_conn); extern int ndmca_test_load_tape (struct ndm_session *sess); extern int ndmca_test_unload_tape (struct ndm_session *sess); extern int ndmca_test_call (struct ndmconn *conn, struct ndmp_xa_buf *xa, ndmp9_error expect_err); extern int ndmca_test_check_expect_errs (struct ndmconn *conn, int32_t rc, ndmp9_error expect_errs[]); extern int ndmca_test_check_expect (struct ndmconn *conn, int32_t rc, ndmp9_error expect_err); extern int ndmca_test_check_expect_no_err (struct ndmconn *conn, int32_t rc); extern int ndmca_test_check_expect_illegal_state (struct ndmconn *conn, int32_t rc); extern int ndmca_test_check_expect_illegal_args (struct ndmconn *conn, int32_t rc); extern void ndmca_test_phase (struct ndm_session *sess, char *test_phase, char *desc); extern void ndmca_test_log_step (struct ndm_session *sess, int32_t level, char *msg); extern void ndmca_test_log_note (struct ndm_session *sess, int32_t level, char *msg); extern void ndmca_test_done_phase (struct ndm_session *sess); extern void ndmca_test_done_series (struct ndm_session *sess, char *series_name); extern void ndmca_test_open (struct ndm_session *sess, char *test_name, char *sub_test_name); extern void ndmca_test_warn (struct ndm_session *sess, char *warn_msg); extern void ndmca_test_fail (struct ndm_session *sess, char *fail_msg); extern void ndmca_test_close (struct ndm_session *sess); extern void ndmca_test_fill_data (char *buf, int32_t bufsize, int32_t recno, int32_t fileno); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT /* * DATA AGENT **************************************************************** * * NDMP Elements of Data Agent (backup) * * +-----------+stderr * | bu_type |--------formatter_err---------NDMP_LOG-------> to CONTROL * | formatter | * | process |========formatter_data=+=====================> to image stream * +-----------+stdout | * +-------+ * | snoop |--NDMP_FH_ADD_x--> to CONTROL * +-------+ * **************************************************************** * * NDMP Elements of Data Agent (recover) * * +-----------+stderr * | bu_type |--------formatter_err---------NDMP_LOG-------> to CONTROL * | formatter | +--------+ * | process |<=======fmt_data=| direct |==================< from image str * +-----------+stdin | |-NOTIFY_DATA_READ-> to CONTROL * | snoop | * +--------+ * **************************************************************** * * NDMP Elements of Data Agent (recover filehist) * * +--------+ * | direct |==================< from image str * | |-NOTIFY_DATA_READ-> to CONTROL * | snoop |--NDMP_FH_ADD_x---> to CONTROL * +--------+ * **************************************************************** */ #ifndef NDMDA_N_FMT_IMAGE_BUF #define NDMDA_N_FMT_IMAGE_BUF (8*1024) #endif #ifndef NDMDA_N_FHH_BUF #define NDMDA_N_FHH_BUF (8*1024) #endif #ifndef NDMDA_N_FMT_ERROR_BUF #define NDMDA_N_FMT_ERROR_BUF (8*1024) #endif #ifndef NDMDA_N_FMT_WRAP_BUF #define NDMDA_N_FMT_WRAP_BUF (4*1024) #endif #ifndef NDMDA_MAX_CMD #define NDMDA_MAX_CMD (4*1024) #endif #ifndef NDMOS_OPTION_NO_GTAR_BUTYPE extern int ndmda_butype_gtar_config_get_attrs (struct ndm_session *sess, uint32_t *attrs_p, int32_t protocol_version); extern int ndmda_butype_gtar_config_get_default_env ( struct ndm_session *sess, ndmp9_pval **env_p, int32_t *n_env_p, int32_t protocol_version); extern int ndmda_butype_gtar_attach (struct ndm_session *sess); #endif #ifndef NDMOS_OPTION_NO_DUMP_BUTYPE extern int ndmda_butype_dump_config_get_attrs (struct ndm_session *sess, uint32_t *attrs_p, int32_t protocol_version); extern int ndmda_butype_dump_config_get_default_env ( struct ndm_session *sess, ndmp9_pval **env_p, int32_t *n_env_p, int32_t protocol_version); extern int ndmda_butype_dump_attach (struct ndm_session *sess); #endif struct ndm_data_recovery_interval { ndmp9_u_quad offset; ndmp9_u_quad length; }; enum ndm_data_recovery_access_method { NDMDA_RECO_ACCESS_SEQUENTIAL = 1, NDMDA_RECO_ACCESS_DIRECT, NDMDA_RECO_ACCESS_SEMI_DIRECT, NDMDA_RECO_ACCESS_SEMI_DIRECT_PENDING }; enum ndm_data_recovery_state { NDMDA_RECO_STATE_START = 1, NDMDA_RECO_STATE_PASS_THRU, NDMDA_RECO_STATE_CHOOSE_NLENT, NDMDA_RECO_STATE_ACQUIRE, NDMDA_RECO_STATE_DISPOSE, NDMDA_RECO_STATE_FINISH_NLENT, NDMDA_RECO_STATE_ALL_DONE }; enum ndm_data_recovery_acquire_mode { NDMDA_RECO_ACQUIRE_EVERYTHING = 1, NDMDA_RECO_ACQUIRE_SEARCHING, NDMDA_RECO_ACQUIRE_MATCHING }; enum ndm_data_recovery_disposition { NDMDA_RECO_DISPOSITION_PASS = 1, NDMDA_RECO_DISPOSITION_DISCARD }; struct ndm_data_agent { int32_t protocol_version; char bu_type[32]; struct ndm_env_table env_tab; struct ndm_nlist_table nlist_tab; NDM_FLAG_DECL(enable_hist) uint64_t pass_resid; ndmp9_data_get_state_reply data_state; int32_t data_notify_pending; struct ndmchan formatter_image; /* stdin/out */ struct ndmchan formatter_error; /* stderr */ struct ndmchan formatter_wrap; /* fd=3 */ int32_t formatter_pid; char * fmt_image_buf; char * fmt_error_buf; char * fmt_wrap_buf; struct ndmfhheap fhh; uint32_t * fhh_buf; #ifdef NDMOS_MACRO_DATA_AGENT_ADDITIONS NDMOS_MACRO_DATA_AGENT_ADDITIONS #endif /* NDMOS_MACRO_DATA_AGENT_ADDITIONS */ }; /* ndma_data.c */ extern int ndmda_initialize (struct ndm_session *sess); extern int ndmda_commission (struct ndm_session *sess); extern int ndmda_decommission (struct ndm_session *sess); extern int ndmda_destroy (struct ndm_session *sess); extern int ndmda_belay (struct ndm_session *sess); extern ndmp9_error ndmda_data_start_backup (struct ndm_session *sess); extern ndmp9_error ndmda_data_start_recover (struct ndm_session *sess); extern ndmp9_error ndmda_data_start_recover_fh (struct ndm_session *sess); extern void ndmda_sync_state (struct ndm_session *sess); extern ndmp9_error ndmda_data_listen (struct ndm_session *sess); extern ndmp9_error ndmda_data_connect (struct ndm_session *sess); extern void ndmda_data_abort (struct ndm_session *sess); extern void ndmda_sync_environment (struct ndm_session *sess); extern void ndmda_data_halt (struct ndm_session *sess, ndmp9_data_halt_reason reason); extern void ndmda_data_stop (struct ndm_session *sess); extern int ndmda_quantum (struct ndm_session *sess); extern int ndmda_quantum_image (struct ndm_session *sess); extern int ndmda_quantum_stderr (struct ndm_session *sess); extern int ndmda_quantum_wrap (struct ndm_session *sess); extern int ndmda_wrap_in (struct ndm_session *sess, char *wrap_line); extern void ndmda_send_logmsg (struct ndm_session *sess, char *fmt, ...); extern void ndmda_send_notice (struct ndm_session *sess); extern void ndmda_send_data_read (struct ndm_session *sess, uint64_t offset, uint64_t length); extern int ndmda_copy_environment (struct ndm_session *sess, ndmp9_pval *env, unsigned n_env); extern struct ndmp9_pval *ndmda_find_env (struct ndm_session *sess, char *name); extern int ndmda_interpret_boolean_value (char *value_str, int32_t default_value); extern void ndmda_purge_environment (struct ndm_session *sess); extern int ndmda_copy_nlist (struct ndm_session *sess, ndmp9_name *nlist, unsigned n_nlist); extern void ndmda_purge_nlist (struct ndm_session *sess); extern int ndmda_count_invalid_fh_info (struct ndm_session *sess); extern int ndmda_count_invalid_fh_info_pending (struct ndm_session *sess); /* in ndma_data_recover.c */ extern int ndmda_quantum_recover_common (struct ndm_session *sess); extern int ndmda_reco_state_start (struct ndm_session *sess); extern int ndmda_reco_pass_thru (struct ndm_session *sess); extern int ndmda_reco_state_pass_thru (struct ndm_session *sess); extern int ndmda_reco_state_choose_nlent (struct ndm_session *sess); extern int ndmda_reco_state_acquire (struct ndm_session *sess); extern int ndmda_reco_state_dispose (struct ndm_session *sess); extern int ndmda_reco_state_finish_nlent (struct ndm_session *sess); extern int ndmda_reco_state_all_done (struct ndm_session *sess); extern int ndmda_reco_assess_channels (struct ndm_session *sess); extern int ndmda_reco_assess_intervals (struct ndm_session *sess); extern int ndmda_reco_align_to_wanted (struct ndm_session *sess); extern int ndmda_reco_obtain_wanted (struct ndm_session *sess); extern int ndmda_reco_send_data_read (struct ndm_session *sess, uint64_t offset, uint64_t length); extern int ndmda_reco_internal_error (struct ndm_session *sess, char *why); /* ndma_data_fh.c */ extern int ndmda_fh_initialize (struct ndm_session *sess); extern int ndmda_fh_commission (struct ndm_session *sess); extern int ndmda_fh_decommission (struct ndm_session *sess); extern int ndmda_fh_destroy (struct ndm_session *sess); extern int ndmda_fh_belay (struct ndm_session *sess); extern void ndmda_fh_add_file (struct ndm_session *sess, ndmp9_file_stat *filestat, char *name); extern void ndmda_fh_add_dir (struct ndm_session *sess, uint64_t dir_fileno, char *name, uint64_t fileno); extern void ndmda_fh_add_node (struct ndm_session *sess, ndmp9_file_stat *filestat); extern int ndmda_fh_prepare (struct ndm_session *sess, int vers, int msg, int entry_size, unsigned n_item, unsigned total_size_of_items); extern void ndmda_fh_flush (struct ndm_session *sess); /* ndma_data_pfe.c (pipe-fork-exec) */ extern int ndmda_pipe_fork_exec (struct ndm_session *sess, char *cmd, int is_backup); extern int ndmda_add_to_cmd_with_escapes (char *cmd, char *word, char *special); extern int ndmda_add_to_cmd (char *cmd, char *word); extern int ndmda_add_to_cmd_allow_file_wildcards (char *cmd, char *word); #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT /* * TAPE AGENT **************************************************************** */ struct ndm_tape_agent { int protocol_version; /* TAPE */ ndmp9_tape_get_state_reply tape_state; /* MOVER */ ndmp9_mover_get_state_reply mover_state; uint32_t mover_window_first_blockno; uint64_t mover_window_end; uint64_t mover_want_pos; int mover_notify_pending; int pending_change_after_drain; ndmp9_mover_state pending_mover_state; ndmp9_mover_halt_reason pending_mover_halt_reason; ndmp9_mover_pause_reason pending_mover_pause_reason; char *tape_buffer; uint32_t tb_blockno; #ifdef NDMOS_MACRO_TAPE_AGENT_ADDITIONS NDMOS_MACRO_TAPE_AGENT_ADDITIONS #endif /* NDMOS_MACRO_DATA_AGENT_ADDITIONS */ }; #define NDMTA_TAPE_IS_WRITABLE(TA) \ ( (TA)->tape_state.open_mode == NDMP9_TAPE_RDWR_MODE \ || (TA)->tape_state.open_mode == NDMP9_TAPE_RAW_MODE) extern int ndmta_initialize (struct ndm_session *sess); extern int ndmta_commission (struct ndm_session *sess); extern int ndmta_decommission (struct ndm_session *sess); extern int ndmta_destroy (struct ndm_session *sess); extern int ndmta_init_mover_state (struct ndm_session *sess); extern void ndmta_mover_sync_state (struct ndm_session *sess); ndmp9_error ndmta_mover_listen (struct ndm_session *sess, ndmp9_mover_mode mover_mode); ndmp9_error ndmta_mover_connect (struct ndm_session *sess, ndmp9_mover_mode mover_mode); extern void ndmta_mover_halt (struct ndm_session *sess, ndmp9_mover_halt_reason reason); extern void ndmta_mover_pause (struct ndm_session *sess, ndmp9_mover_pause_reason reason); extern void ndmta_mover_active (struct ndm_session *sess); extern void ndmta_mover_start_active (struct ndm_session *sess); extern void ndmta_mover_stop (struct ndm_session *sess); extern void ndmta_mover_abort (struct ndm_session *sess); extern void ndmta_mover_continue (struct ndm_session *sess); extern void ndmta_mover_close (struct ndm_session *sess); extern void ndmta_mover_read (struct ndm_session *sess, uint64_t offset, uint64_t length); extern int ndmta_quantum (struct ndm_session *sess); extern int ndmta_read_quantum (struct ndm_session *sess); extern int ndmta_write_quantum (struct ndm_session *sess); extern void ndmta_mover_send_notice (struct ndm_session *sess); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT /* * ROBOT AGENT **************************************************************** */ struct ndm_robot_agent { int protocol_version; ndmp9_scsi_get_state_reply scsi_state; #ifdef NDMOS_MACRO_ROBOT_AGENT_ADDITIONS NDMOS_MACRO_ROBOT_AGENT_ADDITIONS #endif /* NDMOS_MACRO_ROBOT_AGENT_ADDITIONS */ }; extern int ndmra_initialize (struct ndm_session *sess); extern int ndmra_commission (struct ndm_session *sess); extern int ndmra_decommission (struct ndm_session *sess); extern int ndmra_destroy (struct ndm_session *sess); /* all semantic operations are done directly to the ndmos_scsi layer */ #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ /* * IMAGE STREAM **************************************************************** */ enum ndmis_connect_status { NDMIS_CONN_IDLE = 0, NDMIS_CONN_LISTEN, NDMIS_CONN_ACCEPTED, NDMIS_CONN_CONNECTED, NDMIS_CONN_DISCONNECTED, NDMIS_CONN_CLOSED, NDMIS_CONN_BOTCHED, NDMIS_CONN_REMOTE, NDMIS_CONN_EXCLUDE }; typedef enum ndmis_connect_status ndmis_connect_status; struct ndmis_end_point { char * name; ndmis_connect_status connect_status; int transfer_mode; ndmp9_addr_type addr_type; }; struct ndmis_remote { ndmis_connect_status connect_status; int transfer_mode; ndmp9_addr local_addr; ndmp9_addr peer_addr; ndmp9_addr listen_addr; struct ndmchan listen_chan; struct ndmchan sanity_chan; }; struct ndm_image_stream { struct ndmis_end_point data_ep; struct ndmis_end_point tape_ep; struct ndmis_remote remote; /* transfer stuff */ int transfer_mode; struct ndmchan chan; char * buf; int buflen; }; extern int ndmis_initialize (struct ndm_session *sess); extern int ndmis_commission (struct ndm_session *sess); extern int ndmis_decommission (struct ndm_session *sess); extern int ndmis_destroy (struct ndm_session *sess); extern int ndmis_belay (struct ndm_session *sess); extern int ndmis_quantum (struct ndm_session *sess); extern ndmp9_error ndmis_data_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, ndmp9_addr *ret_addr, char *reason); extern ndmp9_error ndmis_tape_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, ndmp9_addr *ret_addr, char *reason); extern ndmp9_error ndmis_data_connect (struct ndm_session *sess, ndmp9_addr *addr, char *reason); extern ndmp9_error ndmis_tape_connect (struct ndm_session *sess, ndmp9_addr *addr, char *reason); extern int ndmis_data_start (struct ndm_session *sess, int chan_mode); extern int ndmis_tape_start (struct ndm_session *sess, int chan_mode); extern int ndmis_data_close (struct ndm_session *sess); extern int ndmis_tape_close (struct ndm_session *sess); extern ndmp9_error ndmis_audit_data_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason); extern ndmp9_error ndmis_audit_tape_listen (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason); extern ndmp9_error ndmis_audit_data_connect (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason); extern ndmp9_error ndmis_audit_tape_connect (struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason); extern ndmp9_error ndmis_audit_ep_listen ( struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep); extern ndmp9_error ndmis_audit_ep_connect ( struct ndm_session *sess, ndmp9_addr_type addr_type, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep); extern ndmp9_error ndmis_ep_listen ( struct ndm_session *sess, ndmp9_addr_type addr_type, ndmp9_addr *ret_addr, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep); extern ndmp9_error ndmis_ep_connect ( struct ndm_session *sess, ndmp9_addr *addr, char *reason, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep); extern int ndmis_ep_close ( struct ndm_session *sess, struct ndmis_end_point *mine_ep, struct ndmis_end_point *peer_ep); extern int ndmis_tcp_listen (struct ndm_session *sess, struct ndmp9_addr *listen_addr); extern int ndmis_tcp_accept (struct ndm_session *sess); extern int ndmis_tcp_connect (struct ndm_session *sess, struct ndmp9_addr *connect_addr); extern int ndmis_tcp_close (struct ndm_session *sess); extern int ndmis_tcp_get_local_and_peer_addrs ( struct ndm_session *sess); extern int ndmis_tcp_green_light (struct ndm_session *sess, int sock, ndmis_connect_status new_status); /* * PLUMBING **************************************************************** */ struct ndm_plumbing { struct ndmconn * control; struct ndmconn * data; struct ndmconn * tape; struct ndmconn * robot; struct ndm_image_stream * image_stream; }; /* * SESSION **************************************************************** */ struct ndm_session_param { struct ndmlog log; char * log_tag; int log_level; char * config_file_name; }; struct ndm_session { #ifndef NDMOS_OPTION_NO_CONTROL_AGENT struct ndm_control_agent *control_acb; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT struct ndm_data_agent *data_acb; #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT struct ndm_tape_agent *tape_acb; struct ndm_tape_simulator_callbacks *ntsc; #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT struct ndm_robot_agent *robot_acb; struct ndm_robot_simulator_callbacks *nrsc; #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ struct ndm_auth_callbacks *nac; struct ndm_plumbing plumb; struct ndm_session_param *param; /* scratch pad stuff */ ndmp9_config_info *config_info; char md5_challenge[64]; /* CONNECT_AUTH MD5 */ NDM_FLAG_DECL(conn_open) NDM_FLAG_DECL(conn_authorized) NDM_FLAG_DECL(conn_snooping) NDM_FLAG_DECL(md5_challenge_valid) NDM_FLAG_DECL(control_agent_enabled) NDM_FLAG_DECL(data_agent_enabled) NDM_FLAG_DECL(tape_agent_enabled) NDM_FLAG_DECL(robot_agent_enabled) NDM_FLAG_DECL(dump_media_info) NDM_FLAG_DECL(error_raised) int connect_status; /* Void pointer to session specific data the calling process wants to associate */ void * session_handle; #ifdef NDMOS_MACRO_SESSION_ADDITIONS NDMOS_MACRO_SESSION_ADDITIONS #endif /* NDMOS_MACRO_SESSION_ADDITIONS */ }; /* ndma_session.c */ extern int ndma_client_session (struct ndm_session *sess, struct ndm_job_param *job, int swap_connect); extern int ndma_server_session (struct ndm_session *sess, int control_sock); extern int ndma_daemon_session (struct ndm_session *sess, int port); extern int ndma_session_quantum (struct ndm_session *sess, int max_delay_secs); extern int ndma_session_initialize (struct ndm_session *sess); extern int ndma_session_commission (struct ndm_session *sess); extern int ndma_session_decommission (struct ndm_session *sess); extern int ndma_session_destroy (struct ndm_session *sess); /* ndma_comm_subr.c */ extern void ndmalogf (struct ndm_session *sess, char *tag, int level, char *fmt, ...); extern void ndmalogfv (struct ndm_session *sess, char *tag, int level, char *fmt, va_list ap); /* * Dispatch Version/Reqeust Tables (DVT, DRT) **************************************************************** */ struct ndm_dispatch_request_table { uint16_t message; uint16_t flags; int (*dispatch_request) ( /* "dr" for short */ struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn); }; struct ndm_dispatch_version_table { int protocol_version; struct ndm_dispatch_request_table * dispatch_request_table; }; #define NDM_DRT_FLAG_OK_NOT_CONNECTED 0x0001 #define NDM_DRT_FLAG_OK_NOT_AUTHORIZED 0x0002 /* ndma_comm_dispatch.c */ extern int ndma_dispatch_request (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn); extern int ndma_dispatch_raise_error (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn, ndmp9_error error, char *errstr); extern int ndma_dispatch_conn (struct ndm_session *sess, struct ndmconn *conn); extern void ndma_dispatch_ctrl_unexpected (struct ndmconn *conn, struct ndmp_msg_buf *nmb); extern int ndmta_local_mover_read (struct ndm_session *sess, uint64_t offset, uint64_t length); extern int ndma_call_no_tattle (struct ndmconn *conn, struct ndmp_xa_buf *xa); extern int ndma_call (struct ndmconn *conn, struct ndmp_xa_buf *xa); extern int ndma_send_to_control (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *from_conn); extern int ndma_tattle (struct ndmconn *conn, struct ndmp_xa_buf *xa, int rc); extern struct ndm_dispatch_request_table * ndma_drt_lookup (struct ndm_dispatch_version_table *dvt, unsigned protocol_version, unsigned message); #define NDMADR_RAISE(ERROR,ERRSTR) \ return ndma_dispatch_raise_error (sess, xa, ref_conn, ERROR, ERRSTR) #define NDMADR_RAISE_ILLEGAL_ARGS(ERRSTR) \ NDMADR_RAISE(NDMP9_ILLEGAL_ARGS_ERR, ERRSTR) #define NDMADR_RAISE_ILLEGAL_STATE(ERRSTR) \ NDMADR_RAISE(NDMP9_ILLEGAL_STATE_ERR, ERRSTR) #define NDMADR_UNIMPLEMENTED_MESSAGE (-1) /* aka "TODO" */ #define NDMADR_UNSPECIFIED_MESSAGE (-123) /* no such per specs */ #define NDMADR_UNIMPLEMENTED_VERSION (-1234) /* implementation error */ /* * Operating System Specific **************************************************************** * Must be implemented in ndmos_xxx.c */ /* from ndma_dispatch_request() in ndma_dispatch.c */ extern int ndmos_dispatch_request (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn); /* from ndmadr_connect_client_auth() in ndma_dispatch.c */ struct ndm_auth_callbacks { int (*validate_password)(struct ndm_session *sess, char *name, char *pass); int (*validate_md5)(struct ndm_session *sess, char *name, char digest[16]); }; extern void ndmos_auth_register_callbacks (struct ndm_session *sess, struct ndm_auth_callbacks *callbacks); extern void ndmos_auth_unregister_callbacks (struct ndm_session *sess); extern int ndmos_ok_name_password (struct ndm_session *sess, char *name, char *pass); extern int ndmos_get_md5_challenge (struct ndm_session *sess); extern int ndmos_ok_name_md5_digest (struct ndm_session *sess, char *name, char digest[16]); /* from ndmadr_config_get_{host,server}_info() in ndma_dispatch.c */ extern void ndmos_sync_config_info (struct ndm_session *sess); /* from ndma_image_stream.c and ndma_ctrl_conn.c and others */ extern void ndmos_condition_pipe_fd (struct ndm_session *sess, int fd); extern void ndmos_condition_listen_socket ( struct ndm_session *sess, int sock); extern void ndmos_condition_control_socket ( struct ndm_session *sess, int sock); extern void ndmos_condition_image_stream_socket ( struct ndm_session *sess, int sock); #ifndef NDMOS_OPTION_NO_TAPE_AGENT struct ndm_tape_simulator_callbacks { ndmp9_error (*tape_open)(struct ndm_session *sess, char *drive_name, int will_write); ndmp9_error (*tape_close)(struct ndm_session *sess); ndmp9_error (*tape_mtio)(struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid); ndmp9_error (*tape_write)(struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count); ndmp9_error (*tape_wfm)(struct ndm_session *sess); ndmp9_error (*tape_read)(struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count); }; extern void ndmos_tape_register_callbacks (struct ndm_session *sess, struct ndm_tape_simulator_callbacks *callbacks); extern void ndmos_tape_unregister_callbacks (struct ndm_session *sess); extern int ndmos_tape_initialize (struct ndm_session *sess); extern ndmp9_error ndmos_tape_open (struct ndm_session *sess, char *drive_name, int will_write); extern ndmp9_error ndmos_tape_close (struct ndm_session *sess); extern void ndmos_tape_sync_state (struct ndm_session *sess); extern ndmp9_error ndmos_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid); extern ndmp9_error ndmos_tape_write (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count); extern ndmp9_error ndmos_tape_wfm (struct ndm_session *sess); extern ndmp9_error ndmos_tape_read (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count); extern ndmp9_error ndmos_tape_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT struct ndm_robot_simulator_callbacks { ndmp9_error (*scsi_open)(struct ndm_session *sess, char *name); ndmp9_error (*scsi_close)(struct ndm_session *sess); ndmp9_error (*scsi_reset)(struct ndm_session *sess); ndmp9_error (*scsi_execute_cdb)(struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply); }; extern void ndmos_scsi_register_callbacks (struct ndm_session *sess, struct ndm_robot_simulator_callbacks *callbacks); extern void ndmos_scsi_unregister_callbacks (struct ndm_session *sess); extern int ndmos_scsi_initialize (struct ndm_session *sess); extern void ndmos_scsi_sync_state (struct ndm_session *sess); extern void ndmos_scsi_sync_config_info (struct ndm_session *sess); extern ndmp9_error ndmos_scsi_open (struct ndm_session *sess, char *name); extern ndmp9_error ndmos_scsi_close (struct ndm_session *sess); extern ndmp9_error ndmos_scsi_set_target (struct ndm_session *sess); extern ndmp9_error ndmos_scsi_reset_device (struct ndm_session *sess); extern ndmp9_error ndmos_scsi_reset_bus (struct ndm_session *sess); extern ndmp9_error ndmos_scsi_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply); #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ /* ndma_noti_calls.c */ #ifndef NDMOS_OPTION_NO_DATA_AGENT extern int ndma_notify_data_halted (struct ndm_session *sess); extern int ndma_notify_data_read (struct ndm_session *sess, uint64_t offset, uint64_t length); #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT extern int ndma_notify_mover_halted (struct ndm_session *sess); extern int ndma_notify_mover_paused (struct ndm_session *sess); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS extern void ndma_send_logmsg (struct ndm_session *sess, ndmp9_log_type ltype, struct ndmconn *from_conn, char *fmt, ...); #ifdef __cplusplus } #endif #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */ bareos-Release-14.2.6/src/ndmp/ndmjob.conf000066400000000000000000000066451263011562700203200ustar00rootroot00000000000000 [password] password ndmp ndmp [butype tar] v2attr 0xFFFF v3attr 0x1234 v4attr 0x4321 default_env EXCLUDE *.o default_env HIST p [butype dump] v3attr 0x1234 v4attr 0x4321 default_env UPDATE n default_env HIST d [butype simple] v3attr 0x1234 v4attr 0x4321 default_env NAME VALUE default_env NAME VALUE [butype test] v3attr 0x1234 v4attr 0x4321 default_env HIST y,n,f,d [tape tape1] device /dev/rsa1 v3attr 0x1234 v4attr 0x4321 capability NAME VALUE capability NAME VALUE [tape tape1] device /dev/rnsa1 v3attr 0x801234 v4attr 0x804321 capability NAME VALUE capability NAME VALUE [scsi scsi1] device /dev/pass2 v3attr 0x0 v4attr 0x4 capability NAME VALUE [fs /test] fs_status Online fs_physical_device /dev/wd0a fs_type ufs fs_env NAME VALUE fs_env NAME VALUE [--local-tape] -T traakan-200,ndmp,ndmp -f FakeTape [--faketape] -T. -f FakeTape [--std-excl] # standard EXCLUDES -- These patterns are very common. -e *.core -e BUILD*/*.o -e home/*/.netscape/cache # LOG/INDEX short hands [--log+index] -L ndmjob.log -I ndmjob.ind [--just-log] -L ndmjob.log -I- [--log-no-index] -L ndmjob.log [--dbg] -L dbg.log -I dbg.ind -d7 [--v] -v -Llog -I- -d6 [--Tntap4] -T netapp-4/4,root,netapp -f nrst0l [--Rntap4] -R netapp-4/4,root,netapp -r mc0 -o tape-timeout=60 -o use-eject -o robot-timeout=60 [--Twsi1] -T wsi-1,ndmp,ndmp -f /dev/rbt0 [--Rwsi1] -R wsi-1,ndmp,ndmp -r /dev/rbl0 -o tape-timeout=60 -o use-eject -o robot-timeout=60 [--Temc-104] -T emc-104,ndmp,ndmp -f c0t2l0 [--Remc-104] -R emc-104,ndmp,ndmp -r c0t1l0 -o tape-timeout=60 -o use-eject -o robot-timeout=60 [--Dbluearc-2] -D bluearc-2,ndmp,ndmp -B dump -C /export [--Tbluearc-2] -T bluearc-2,ndmp,ndmp -f /dev/mt_d0l1f [--Rbluearc-2] -R bluearc-2,ndmp,ndmp -r /dev/mc_d0l0 -o tape-timeout=60 -o use-eject -o robot-timeout=60 [--Dagile-100] -D agile-100,root,agile -B dump -b 16 -C /vol1 [--Iagile-100] -Iagile.index [--Tagile-100] -T agile-100,root,agile -f NRNU0l [--Tspectra2] -T spectra-2,root,hello -f Tape1_0 [--Tspectra2v4] -T spectra-2/4,root,hello -f Tape1_0 [--Tspectra2v3] -T spectra-2/3,root,hello -f Tape1_0 [--Tspectra2v2] -T spectra-2/2,root,hello -f Tape1_0 [--Rspectra2] -R spectra-2,root,hello -r Library0_0 [--Tcv2] -T commvault-2/v -f B:0:1:1:1:1:0:1:1:1:1:1 [--Tcv2v3] -T commvault-2/3v -f B:0:1:1:1:1:0:1:1:1:1:1 [--Dmira1] -D mirapoint-1,administrator,admin -E FILESYSTEM=/usr/store [--Tmira1] -T mirapoint-1,administrator,admin -f /dev/nrst0 [--Rmira1] -R mirapoint-1,administrator,admin -r /dev/ch0 [--Rquan] -R quantum-10,root,ndmp -r spt0 [--Tquan] -T quantum-11,root,ndmp -f /dev/nst0 [--Demc] -D emc1-102,webadm,f -E FILESYSTEM=/Drive1 [--Dnei] -D netengine-1,test,nei2001! -E FILESYSTEM=/test [--Dneiv2] -D netengine-1/2,test,nei2001! -E FILESYSTEM=/test [--Dneiv3] -D netengine-1/3,test,nei2001! -E FILESYSTEM=/test [--Dneiv4] -D netengine-1/4,test,nei2001! -E FILESYSTEM=/test [--Daspx51] -D auspex-51,root,auspex -E FILESYSTEM=/ibmdata -E LEVEL=0 -B dump [--Taspx51] -T auspex-51,root,auspex -f /dev/raxmt/fsp0c3t1 [--Raspx51] -R auspex-51,root,auspex -r fsp0,3,0,0 [--Dblue] -D synaxia-1,ndmp,jupiter -E FILESYSTEM=/nfsroot/Commvault [--Tblue] -T synaxia-1,ndmp,jupiter -f /dev/mt_d0l1f [--Tbluev4] -T synaxia-1,ndmp,jupiter -f /dev/mt_d0l1v4 [--Rblue] -R synaxia-1,ndmp,jupiter -r /dev/mc_d0l0 bareos-Release-14.2.6/src/ndmp/ndmjob.h000066400000000000000000000131031263011562700176050ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" #ifndef GLOBAL #define GLOBAL extern #endif GLOBAL char * progname; GLOBAL struct ndm_session the_session; GLOBAL struct ndm_session_param the_param; GLOBAL int the_mode; GLOBAL int d_debug; GLOBAL char * L_log_file; GLOBAL int n_noop; GLOBAL int v_verbose; GLOBAL int o_no_time_stamps; GLOBAL char * o_config_file; GLOBAL char * o_tape_tcp; GLOBAL char * o_load_files_file; GLOBAL FILE * log_fp; extern void error_byebye (char *fmt, ...); extern struct ndmp_enum_str_table mode_long_name_table[]; extern int process_args (int argc, char *argv[]); extern int handle_long_option (char *str); extern void set_job_mode (int mode); extern void usage (void); extern void help (void); extern void ndmjob_version_info (void); extern void dump_settings (void); extern int copy_args_expanding_macros (int argc, char *argv[], char *av[], int max_ac); extern int lookup_and_snarf (char *av[], char *name); extern int snarf_macro (char *av[], char *val); extern void ndmjob_log_deliver(struct ndmlog *log, char *tag, int lev, char *msg); extern void ndmjob_log (int level, char *fmt, ...); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT #define MAX_EXCLUDE_PATTERN 100 #define MAX_FILE_ARG NDM_MAX_NLIST GLOBAL char * B_bu_type; GLOBAL int b_bsize; GLOBAL char * C_chdir; GLOBAL struct ndmagent D_data_agent; GLOBAL struct ndm_env_table E_environment; GLOBAL char * e_exclude_pattern[MAX_EXCLUDE_PATTERN]; GLOBAL int n_e_exclude_pattern; GLOBAL char * f_tape_device; GLOBAL char * I_index_file; /* output */ GLOBAL char * J_index_file; /* input */ GLOBAL struct ndm_media_table m_media; GLOBAL struct ndmagent R_robot_agent; GLOBAL struct ndmscsi_target * r_robot_target; GLOBAL struct ndmagent T_tape_agent; GLOBAL char * U_user; GLOBAL int o_time_limit; GLOBAL int o_swap_connect; GLOBAL int o_use_eject; GLOBAL int o_tape_addr; GLOBAL int o_from_addr; GLOBAL int o_to_addr; GLOBAL struct ndmscsi_target * o_tape_scsi; GLOBAL int o_tape_timeout; GLOBAL int o_robot_timeout; GLOBAL char * o_rules; GLOBAL off_t o_tape_limit; GLOBAL int p_ndmp_port; GLOBAL char * file_arg[MAX_FILE_ARG]; GLOBAL char * file_arg_new[MAX_FILE_ARG]; GLOBAL int n_file_arg; /* The ji_ variables are set according to the -J input index */ GLOBAL struct ndm_media_table ji_media; GLOBAL struct ndm_env_table ji_environment; GLOBAL ndmp9_name nlist[MAX_FILE_ARG]; /* parallels file_arg[] */ GLOBAL FILE * index_fp; GLOBAL struct ndm_job_param the_job; #define AGENT_GIVEN(AGENT) (AGENT.conn_type != NDMCONN_TYPE_NONE) #define ROBOT_GIVEN() (r_robot_target) extern void ndmjob_ixlog_deliver(struct ndmlog *log, char *tag, int lev, char *msg); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ extern void ndmjob_register_callbacks (struct ndm_session *sess, struct ndmlog *ixlog); extern void ndmjob_unregister_callbacks (struct ndm_session *sess, struct ndmlog *ixlog); extern int ndmjobfhdb_add_file (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat); extern int ndmjobfhdb_add_dir (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node); extern int ndmjobfhdb_add_node (struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat); extern int ndmjobfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT extern int start_index_file (void); extern int sort_index_file (void); extern int build_job (void); extern int args_to_job (void); extern int args_to_job_backup_env (void); extern int args_to_job_recover_env (void); extern int args_to_job_recover_nlist (void); extern int jndex_doit (void); extern int jndex_tattle (void); extern int jndex_merge_media (void); extern int jndex_audit_not_found (void); extern int jndex_merge_environment (void); extern int jndex_fetch_post_backup_data_env (FILE *fp); extern int jndex_fetch_post_backup_media (FILE *fp); extern int apply_rules (struct ndm_job_param *job, char *rules); extern int help_rules (void); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndmjob_args.c000066400000000000000000000631431263011562700206250ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmjob.h" char *help_text[] = { "ndmjob -v -- print version and configuration info", "ndmjob OPTIONS ... FILES ...", " FILES can be FILEPATH or NEWFILEPATH=OLDFILEPATH with", " '=' quoted by backslash.", "Modes (exactly one required)", #ifndef NDMOS_OPTION_NO_CONTROL_AGENT " -c -- create a backup", " -t -- list contents on a backup", " -x -- extract from a backup", " -l -- list media labels", " -q -- query agent(s)", " -Z -- clean up zee mess (put robot right)", " -o init-labels -- init media labels", #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS " -o daemon -- launch session for incomming connections", " -o tape-size=SIZE -- specify the length, in bytes of the simulated tape", #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT " -o rewind -- rewind tape in drive, need -T and -f", " -o eject -- eject tape in drive, need -T and -f", " -o move -- cmd ROBOT to move tape, need -o from/to-addr", " -o import=ELEMADDR -- cmd ROBOT to import tape from door to slot", " -o export=ELEMADDR -- cmd ROBOT to export tape from slot to door", " -o load=ELEMADDR -- cmd ROBOT to load tape from slot to drive", " -o unload[=ELEMADDR]-- cmd ROBOT to unload tape, sometimes auto", " -o init-elem-status -- cmd ROBOT to rescan tape slots", #ifndef NDMOS_OPTION_NO_TEST_AGENTS " -o test-tape -- test TAPE agent NDMP_TAPE functions", " -o test-mover -- test TAPE agent NDMP_MOVER functions", " -o test-data -- test DATA agent NDMP_DATA functions", #endif /* NDMOS_OPTION_NO_TEST_AGENTS */ " -o time-limit=N", " -- check for reply within specified seconds (default 360)", " -o swap-connect -- perform DATA LISTEN & MOVER CONNECT", #if 0 " -p -- pass DATA->DATA (ndmpcopy)", " -P -- pass TAPE->TAPE", " -o c-partial -- partial backup", " -o c-full -- full backup", " -o x-restore -- extract restoring", #endif #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ "General and Logging parameters", " --MACRO -- expand MACRO from ndmjob-args file", " -d N -- set debug level to N (default 0, max 9)", " -L FILE -- set log file (default stderr, includes debug)", " -n -- no-op, just show how args were handled", " -v -- verbose, same messages as -d1 to standard out", " -S -- Perform DATA listen and MOVER CONNECT", " -p PORT -- NDMP port to listen on (for -o daemon)", " -o no-time-stamps -- log w/o time stamps, makes diff(1)s easier", " -o config-file=PATH", " -- set config file ($NDMJOB_CONFIG, /usr/local/etc/ndmjob.conf)", #ifndef NDMOS_OPTION_NO_CONTROL_AGENT "CONTROL of DATA agent parameters", " -D AGENT -- data agent (see AGENT below)", " -B TYPE -- set backup format (default tar)", " -C DIR -- change directory on data agent before operation", " -e PATN -- exclude files matching pattern", " -E NAME=VAL -- add to data agent environment", " -F FILE -- add FILE arg (used to not confuse arg processing)", " -o load-files=PATHNAME", " -- load FILES from the specified PATHANME", " -o import=ELEMADDR -- cmd ROBOT to import tape from door to slot", " -I FILE -- set output index file, enable FILEHIST (default to log)", " -J FILE -- set input index file (default none)", " -U USER -- user rights to use on data agent", " -o rules=RULES -- apply RULES to job (see RULES below)", "CONTROL of TAPE agent parameters", " -T AGENT -- tape agent if different than -D (see AGENT below)", " -b N -- block size in 512-byte records (default 20)", " -f TAPE -- tape drive device name", " -o tape-timeout=SECONDS", " -- how long to retry opening drive (await tape)", " -o use-eject=N", " -- use eject when unloading tapes (default 0)", " -o tape-tcp=hostname:port -- send the data directly to that tcp port.", " -o D-agent-fd= -- file descriptor to read the -D agent.", "CONTROL of ROBOT agent parameters", " -R AGENT -- robot agent if different than -T (see AGENT below)", " -m MEDIA -- add entry to media table (see below)", " -o tape-addr=ELEMADDR", " -- robot element address of drive (default first)", " -o tape-scsi=SCSI", " -- tape drive SCSI target (see below)", " -o robot-timeout=SECONDS", " -- how long to retry moving tapes (await robot)", " -r SCSI -- tape robot target (see below)", "", "Definitions:", " AGENT HOST[:PORT][/FLAGS][,USERNAME,PASSWORD]", " FLAGS [234][ntm] 2->v2 3->v3 4->v4 n->AUTH_NONE t->TEXT m->MD5", " AGENT . (resident)", " SCSI DEVICE[,[CNUM,]SID[,LUN]]", " MEDIA [TAPE-LABEL][+SKIP-FILEMARKS][@ELEMADDR][/WINDOW-SIZE]", "", "RULES:", #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ 0 }; int process_args (int argc, char *argv[]) { int c; char options[100]; char ** pp; char * p; char * op; char * av[1000]; int ac = 0; progname = argv[0]; if (argc == 2 && strcmp (argv[1], "-help") == 0) { help(); exit(0); } if (argc == 2 && strcmp (argv[1], "-v") == 0) { ndmjob_version_info (); exit(0); } if (argc < 2) usage(); o_config_file = "./ndmjob.conf"; if ((p = getenv ("NDMJOB_CONF")) != 0) { o_config_file = p; } op = options; for (pp = help_text; *pp; pp++) { p = *pp; if (strncmp (p, " -", 3) != 0) continue; if (p[3] == 'o') continue; /* don't include o: repeatedly */ *op++ = p[3]; if (p[5] != ' ') *op++ = ':'; } *op++ = 'o'; /* include o: once */ *op++ = ':'; *op = 0; ac = copy_args_expanding_macros (argc, argv, av, 1000); while ((c = getopt (ac, av, options)) != EOF) { switch (c) { case 'o': handle_long_option (optarg); break; #ifndef NDMOS_OPTION_NO_CONTROL_AGENT case 'c': /* -c -- create a backup */ set_job_mode (NDM_JOB_OP_BACKUP); break; case 't': /* -t -- list contents on a backup */ set_job_mode (NDM_JOB_OP_TOC); break; case 'x': /* -x -- extract from a backup */ set_job_mode (NDM_JOB_OP_EXTRACT); break; case 'l': /* -l -- list media labels */ set_job_mode (NDM_JOB_OP_LIST_LABELS); break; case 'q': /* -q -- query agent(s) */ set_job_mode (NDM_JOB_OP_QUERY_AGENTS); break; case 'Z': /* -Z -- clean up zee mess */ set_job_mode (NDM_JOB_OP_REMEDY_ROBOT); break; case 'B': /* -B TYPE -- set backup format (default tar) */ if (B_bu_type) { error_byebye ("more than one of -B"); } B_bu_type = optarg; break; case 'b': /* -b N -- block size in 512-byte records (20) */ { long b = strtol(optarg, NULL, 10); if (b < 1 || b > 200 || (!b && EINVAL == errno)) { error_byebye ("bad -b option"); } b_bsize = (int) b; break; } case 'p': /* -p N -- port number for daemon mode (10000) */ { long p = strtol(optarg, NULL, 10); if (p < 1 || p > 65535 || (!p && EINVAL == errno)) { error_byebye ("bad -p option"); } p_ndmp_port = (int) p; break; } case 'C': /* -C DIR -- change directory on data agent */ #if 0 /* allow second to override first. make recover easier */ if (C_chdir) { error_byebye ("more than one of -C"); } #endif C_chdir = optarg; break; case 'D': /* -D AGENT -- data agent (see below) */ if (AGENT_GIVEN(D_data_agent)) { error_byebye ("more than one of -D"); } if (ndmagent_from_str (&D_data_agent, optarg)) { error_byebye ("bad -D argument"); } break; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ case 'd': /* -d N -- set debug level to N */ d_debug = atoi(optarg); break; #ifndef NDMOS_OPTION_NO_CONTROL_AGENT case 'E': /* -E NAME=VAL -- add to data agent environment */ if (E_environment.n_env >= NDM_MAX_ENV) { error_byebye ("too many of -E"); } { char * p; ndmp9_pval pv; p = optarg; pv.name = p; while (*p && *p != '=') p++; if (*p != '=') { error_byebye ("missing value in -E"); } *p++ = 0; pv.value = p; ndma_store_env_list (&E_environment, &pv); } break; case 'e': /* -e PATN -- exclude files matching pattern */ if (n_e_exclude_pattern >= MAX_EXCLUDE_PATTERN) { error_byebye ("too many of -e"); } e_exclude_pattern[n_e_exclude_pattern++] = optarg; break; case 'F': /* -F FILE -- add to list of files */ if (n_file_arg >= MAX_FILE_ARG) { error_byebye ("too many FILE args"); } if (strchr(optarg, '=')) { char *p = strchr(optarg, '='); *p++ = 0; file_arg[n_file_arg] = p; file_arg_new[n_file_arg] = optarg; n_file_arg++; } else { file_arg[n_file_arg] = optarg; file_arg_new[n_file_arg] = 0; n_file_arg++; } break; case 'f': /* -f TAPE -- tape drive device name */ if (f_tape_device) { error_byebye ("more than one of -f"); } f_tape_device = optarg; break; case 'I': /* -I FILE -- output index, enab FILEHIST */ if (I_index_file) { error_byebye ("more than one of -I"); } I_index_file = optarg; break; case 'J': /* -J FILE -- input index */ if (J_index_file) { error_byebye ("more than one of -J"); } J_index_file = optarg; break; case 'L': /* -L FILE -- set log file (def stderr, incl. dbg) */ if (L_log_file) { error_byebye ("more than one of -L"); } L_log_file = optarg; if (d_debug < 2) d_debug = 2; break; case 'm': /* -m MEDIA -- add entry to media table (see below) */ if (m_media.n_media >= NDM_MAX_MEDIA) { error_byebye ("too many of -m"); } { struct ndmmedia me; if (ndmmedia_from_str (&me, optarg)) { error_byebye ("bad -m argument: %s", optarg); } ndma_clone_media_entry (&m_media, &me); } break; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ case 'n': /* -n -- no-op, show how args were handled */ n_noop++; break; #ifndef NDMOS_OPTION_NO_CONTROL_AGENT case 'R': /* -R AGENT -- robot agent if different than -T */ if (AGENT_GIVEN(R_robot_agent)) { error_byebye ("more than one of -R"); } if (ndmagent_from_str (&R_robot_agent, optarg)) { error_byebye ("bad -R argument"); } break; case 'r': /* -r SCSI -- tape robot target (see below) */ if (ROBOT_GIVEN()) { error_byebye ("more than one of -r"); } r_robot_target = NDMOS_API_MALLOC (sizeof(struct ndmscsi_target)); if (!r_robot_target) { error_byebye ("No memory for robot target"); } if (ndmscsi_target_from_str (r_robot_target, optarg)) { error_byebye ("bad -r argument"); } break; case 'T': /* -T AGENT -- tape agent if different than -D */ if (AGENT_GIVEN(T_tape_agent)) { error_byebye ("more than one of -T"); } if (ndmagent_from_str (&T_tape_agent, optarg)) { error_byebye ("bad -T argument"); } break; case 'U': /* -U USER -- user rights to use on data agent */ if (U_user) { error_byebye ("more than one of -U"); } U_user = optarg; break; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ case 'v': /* -v -- verbose */ v_verbose++; break; default: usage(); break; } } if (n_noop && d_debug > 1) { int i; for (i = 0; i < ac; i++) { printf (" av[%d] = '%s'\n", i, av[i]); } } if (!the_mode) { #ifndef NDMOS_OPTION_NO_CONTROL_AGENT printf ("must specify one of -[ctxlqZ] or other mode\n"); #else /* !NDMOS_OPTION_NO_CONTROL_AGENT */ printf ("must specify -o daemon\n"); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ usage(); } #ifndef NDMOS_OPTION_NO_CONTROL_AGENT for (c = optind; c < ac; c++) { if (n_file_arg >= MAX_FILE_ARG) { error_byebye ("too many file args"); } if (strchr(av[c], '=')) { char *p = strchr(av[c], '='); *p++ = 0; file_arg[n_file_arg] = p; file_arg_new[n_file_arg] = av[c]; } else { file_arg[n_file_arg] = av[c]; file_arg_new[n_file_arg] = 0; } n_file_arg++; } if (o_load_files_file) { char buf[2048]; FILE *fp; static struct load_file_entry { struct load_file_entry *next; char name[1]; } *load_files_list = 0; /* clean up old load_files_list */ while (load_files_list) { struct load_file_entry *p; p = load_files_list; load_files_list = p->next; p->next = 0; free(p); } fp = fopen(o_load_files_file, "r"); if (!fp) { perror (o_load_files_file); error_byebye ("can't open load_files file %s", o_load_files_file); /* no return */ } while (fgets (buf, sizeof buf, fp) != NULL) { char *bp = buf, *p, *ep; int len, slen; struct load_file_entry *lfe; bp = buf; while (*bp && isspace(*bp)) bp++; ep = bp; while (*ep && (*ep != '\n') && (*ep != '\r')) ep++; *ep = 0; if (bp >= ep) continue; if (n_file_arg >= MAX_FILE_ARG) { error_byebye ("too many FILE args"); } /* allocate memory */ slen = (ep-bp)+2; len = sizeof(struct load_file_entry)+(ep-bp)+1; lfe = malloc(len); if (lfe == 0) { error_byebye ("can't allocate entry for load_files file line %s", bp); /* no return */ } lfe->next = 0; /* see if we have destination */ if ((p = strchr(bp, '=')) != 0) { int plen; char ch = *p; *p = 0; /* double conversion -- assume the strings shrink */ plen = (p-bp); ndmcstr_to_str(p, &lfe->name[plen+2], slen-plen-2); ndmcstr_to_str(bp, lfe->name, plen+1); file_arg[n_file_arg] = &lfe->name[plen+2]; file_arg_new[n_file_arg] = lfe->name; *p = ch; } else { /* simple conversion copy */ ndmcstr_to_str(bp, lfe->name, slen-1); file_arg[n_file_arg] = lfe->name; file_arg_new[n_file_arg] = 0; } n_file_arg++; /* link into list */ lfe->next = load_files_list; load_files_list = lfe; } fclose (fp); } /* end of load_files option */ if (!B_bu_type) B_bu_type = "tar"; /* * A quirk of the NDMP protocol is that the robot * should be accessed over a different connection * than the TAPE agent. (See the Workflow document). */ if (ROBOT_GIVEN()) { if (!AGENT_GIVEN(R_robot_agent)) { if (AGENT_GIVEN(T_tape_agent)) R_robot_agent = T_tape_agent; else R_robot_agent = D_data_agent; if (!AGENT_GIVEN(R_robot_agent)) { error_byebye ("-r given, can't determine -R"); } } } else if (AGENT_GIVEN(R_robot_agent)) { if (the_mode != NDM_JOB_OP_QUERY_AGENTS) { error_byebye ("-R but no -r"); } } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ return 0; } struct ndmp_enum_str_table mode_long_name_table[] = { #ifndef NDMOS_OPTION_NO_CONTROL_AGENT { "init-labels", NDM_JOB_OP_INIT_LABELS }, #ifndef NDMOS_OPTION_NO_TEST_AGENTS { "test-tape", NDM_JOB_OP_TEST_TAPE }, { "test-mover", NDM_JOB_OP_TEST_MOVER }, { "test-data", NDM_JOB_OP_TEST_DATA }, #endif /* NDMOS_OPTION_NO_TEST_AGENTS */ { "eject", NDM_JOB_OP_EJECT_TAPE }, { "rewind", NDM_JOB_OP_REWIND_TAPE }, { "move", NDM_JOB_OP_MOVE_TAPE }, { "import", NDM_JOB_OP_IMPORT_TAPE }, { "export", NDM_JOB_OP_EXPORT_TAPE }, { "load", NDM_JOB_OP_LOAD_TAPE }, { "unload", NDM_JOB_OP_UNLOAD_TAPE }, { "init-elem-status", NDM_JOB_OP_INIT_ELEM_STATUS }, { "-c", NDM_JOB_OP_BACKUP }, { "-t", NDM_JOB_OP_TOC }, { "-x", NDM_JOB_OP_EXTRACT }, { "-l", NDM_JOB_OP_LIST_LABELS }, { "-q", NDM_JOB_OP_QUERY_AGENTS }, { "-Z", NDM_JOB_OP_REMEDY_ROBOT }, #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS { "daemon", NDM_JOB_OP_DAEMON }, #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */ { 0 } }; int handle_long_option (char *str) { char * name; char * value; int mode; name = str; for (value = str; *value; value++) if (*value == '=') break; if (*value) *value++ = 0; else value = 0; if (ndmp_enum_from_str (&mode, name, mode_long_name_table)) { set_job_mode (mode); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT if (value) { switch (mode) { default: /* value part ignored */ break; case NDM_JOB_OP_LOAD_TAPE: case NDM_JOB_OP_EXPORT_TAPE: o_from_addr = atoi(value); break; case NDM_JOB_OP_UNLOAD_TAPE: case NDM_JOB_OP_IMPORT_TAPE: o_to_addr = atoi(value); break; } } } else if (strcmp (name, "swap-connect") == 0) { /* value part ignored */ o_swap_connect++; } else if (strcmp (name, "time-limit") == 0) { if (!value) { o_time_limit = 5*60; } else { o_time_limit = atoi(value); } } else if (strcmp (name, "use-eject") == 0) { if (!value) { o_use_eject = 1; } else { o_use_eject = atoi(value); } } else if (strcmp (name, "tape-addr") == 0 && value) { o_tape_addr = atoi(value); } else if (strcmp (name, "from-addr") == 0 && value) { o_from_addr = atoi(value); } else if (strcmp (name, "to-addr") == 0 && value) { o_to_addr = atoi(value); } else if (strcmp (name, "tape-timeout") == 0 && value) { o_tape_timeout = atoi(value); } else if (strcmp (name, "robot-timeout") == 0 && value) { o_robot_timeout = atoi(value); } else if (strcmp (name, "tape-scsi") == 0 && value) { o_tape_scsi = NDMOS_API_MALLOC (sizeof(struct ndmscsi_target)); if (!o_tape_scsi) { error_byebye ("No memory for tape-scsi target"); } if (ndmscsi_target_from_str (o_tape_scsi, value)) { error_byebye ("bad -otape-scsi argument"); } } else if (strcmp (name, "rules") == 0 && value) { if (!value) error_byebye ("missing RULES in -o rules"); o_rules = value; } else if (strcmp (name, "load-files") == 0 && value) { o_load_files_file = value; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ } else if (strcmp (name, "no-time-stamps") == 0) { /* value part ignored */ o_no_time_stamps++; } else if (strcmp (name, "config-file") == 0 && value) { o_config_file = value; } else if (strcmp (name, "tape-tcp") == 0 && value) { o_tape_tcp = value; } else if (strcmp (name, "D-agent-fd") == 0 && value) { char d_agent[1025]; int fd = atoi(value); int size; if (AGENT_GIVEN(D_data_agent)) { error_byebye ("more than one of -D or -D-agent-fd"); } size = read(fd, d_agent, 1024); d_agent[size] = '\0'; if (size > 0 && d_agent[size-1] == '\n') d_agent[size-1] = '\0'; close(fd); if (ndmagent_from_str (&D_data_agent, d_agent)) { error_byebye ("bad -D-agent-fd argument"); } } else if (strcmp (name, "tape-limit") == 0) { if (!value) { error_byebye ("tape-limit argument is required"); } else { o_tape_limit = atoi(value); } } else { if (value) value[-1] = '='; error_byebye ("unknown/bad long option -o%s", str); } if (value) value[-1] = '='; return 0; } void set_job_mode (int mode) { if (the_mode) { printf ("more than one -[ctxlqZ] or other mode"); usage(); } the_mode = mode; } void usage (void) { error_byebye ("bad usage, use -help"); } void help (void) { char * p; char ** pp; for (pp = help_text; *pp; pp++) { p = *pp; printf ("%s\n", p); } #ifndef NDMOS_OPTION_NO_CONTROL_AGENT help_rules(); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ } void ndmjob_version_info (void) { char vbuf[100]; char abuf[100]; char obuf[5]; *vbuf = 0; #ifndef NDMOS_OPTION_NO_NDMP2 strcat (vbuf, " NDMPv2"); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 strcat (vbuf, " NDMPv3"); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 strcat (vbuf, " NDMPv4"); #endif /* !NDMOS_OPTION_NO_NDMP4 */ *abuf = 0; #ifndef NDMOS_OPTION_NO_CONTROL_AGENT strcat (abuf, " CONTROL"); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ #ifndef NDMOS_OPTION_NO_DATA_AGENT strcat (abuf, " DATA"); #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifndef NDMOS_OPTION_NO_TAPE_AGENT strcat (abuf, " TAPE"); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #ifndef NDMOS_OPTION_NO_ROBOT_AGENT strcat (abuf, " ROBOT"); #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ obuf[0] = (char)(NDMOS_ID >> 24); obuf[1] = (char)(NDMOS_ID >> 16); obuf[2] = (char)(NDMOS_ID >> 8); obuf[3] = (char)(NDMOS_ID >> 0); obuf[4] = 0; printf ("%s (%s)\n", NDMOS_CONST_PRODUCT_NAME, NDMOS_CONST_VENDOR_NAME); printf (" Rev %s LIB:%d.%d/%s OS:%s (%s)\n", NDMOS_CONST_PRODUCT_REVISION, NDMJOBLIB_VERSION, NDMJOBLIB_RELEASE, NDMOS_CONST_NDMJOBLIB_REVISION, NDMOS_CONST_NDMOS_REVISION, obuf); printf (" Agents: %s\n", abuf); printf (" Protocols:%s\n", vbuf); } void dump_settings (void) { int i; char buf[100]; struct ndmmedia * me; struct ndm_env_entry * env; *buf = 0; /* shuts up -Wall */ i = 0; /* shuts up -Wall */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT switch (the_mode) { case 'x': printf ("mode = x (extract)\n"); break; case 'c': printf ("mode = c (create)\n"); break; case 't': printf ("mode = t (table-of-contents)\n"); break; case 'q': printf ("mode = q (query-agents)\n"); break; default: printf ("mode = %c (unknown)\n", the_mode); break; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ if (v_verbose) printf ("verbose %d\n", v_verbose); else printf ("not verbose\n"); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT printf ("blocksize = %d (%dkb, %db)\n", b_bsize, b_bsize/2, b_bsize*512); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ if (d_debug) printf ("debug %d\n", d_debug); else printf ("no debug\n"); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT printf ("Data agent %s\n", D_data_agent.host); if (AGENT_GIVEN(T_tape_agent)) printf ("Tape agent %s\n", T_tape_agent.host); else printf ("Tape agent same as data agent\n"); printf ("tape device %s\n", f_tape_device); printf ("tape format %s\n", B_bu_type); if (C_chdir) printf ("Chdir %s\n", C_chdir); else printf ("Chdir / (default)\n"); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ if (L_log_file) printf ("Log to file %s\n", L_log_file); else printf ("Log to stderr (default)\n"); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT if (I_index_file) { if (strcmp (I_index_file, "-") == 0) { printf ("Index to log, enable FILEHIST\n"); } else { printf ("Index to file %s, enable FILEHIST\n", I_index_file); } } else { printf ("Index off (default), no FILEHIST\n"); } printf ("%d media entries\n", m_media.n_media); for (me = m_media.head; me; me = me->next) { ndmmedia_to_str (me, buf); printf (" %2d: %s\n", i, buf); } printf ("%d excludes\n", n_e_exclude_pattern); for (i = 0; i < n_e_exclude_pattern; i++) { printf (" %2d: %s\n", i, e_exclude_pattern[i]); } printf ("%d environment values\n", E_environment.n_env); for (env = E_environment.head; env; env = env->next) { printf (" %2d: %s=%s\n", i, env->pval.name, env->pval.value); } printf ("%d files\n", n_file_arg); for (i = 0; i < n_file_arg; i++) { printf (" %2d: @%-8lld %s\n", i, nlist[i].fh_info.valid ? nlist[i].fh_info.value : NDMP9_INVALID_U_QUAD, file_arg[i]); } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ return; } int copy_args_expanding_macros (int argc, char *argv[], char *av[], int max_ac) { int i, ac = 0, rc; char * arg; char * p; char env_name[50]; /* expand macros */ for (i = 0; i < argc; i++) { arg = argv[i]; if (strncmp (arg, "--", 2) != 0 || arg[2] == 0) { av[ac++] = arg; continue; } snprintf (env_name, sizeof(env_name), "NDMJOB_%s", arg+2); if ((p = getenv (env_name)) != 0) { ac += snarf_macro (&av[ac], p); continue; } rc = lookup_and_snarf (&av[ac], arg+2); if (rc < 0) { error_byebye ("bad arg macro --%s", arg+2); } ac += rc; } av[ac] = 0; return ac; } int lookup_and_snarf (char *av[], char *name) { FILE * fp; char buf[512]; char * argfile; int ac = 0; int found = 0; argfile = o_config_file; assert (argfile); fp = fopen (argfile, "r"); if (!fp) { perror (argfile); error_byebye ("can't open config file %s", argfile); } while (ndmstz_getstanza (fp, buf, sizeof buf) >= 0) { if (buf[0] == '-' && buf[1] == '-' && strcmp (buf+2, name) == 0) { found = 1; break; } } if (found) { while (ndmstz_getline (fp, buf, sizeof buf) >= 0) { if (*buf == 0) continue; ac += snarf_macro (&av[ac], buf); } } fclose (fp); if (!found) return -1; return ac; } int snarf_macro (char *av[], char *val) { char * p; int ac = 0; char * tmp_av[100]; int tmp_ac = 0; p = NDMOS_API_STRDUP (val); if (!p) { error_byebye ("bad strdup macro"); } for (;;) { while (isspace((int)*p)) p++; if (*p == 0) break; tmp_av[tmp_ac++] = p; while (*p && !isspace((int)*p)) p++; if (*p) *p++ = 0; } ac = copy_args_expanding_macros (tmp_ac, tmp_av, av, 100); return ac; } bareos-Release-14.2.6/src/ndmp/ndmjob_fhdb.c000066400000000000000000000055701263011562700205740ustar00rootroot00000000000000/* * Copyright (c) 2001,2002 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: FileIndex database handling functions. * Implemented as callbacks from the generic framework. * Original code extracted from ndml_fhdb.c * */ #include "ndmlib.h" int ndmjobfhdb_add_file (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat) { char prefix[8]; char statbuf[100]; char namebuf[NDMOS_CONST_PATH_MAX]; strcpy (prefix, "DHf"); prefix[0] = tagc; ndm_fstat_to_str (fstat, statbuf); ndmcstr_from_str (raw_name, namebuf, sizeof namebuf); ndmlogf (ixlog, prefix, 0, "%s UNIX %s", namebuf, statbuf); return 0; } int ndmjobfhdb_add_dir (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node) { char prefix[8]; char namebuf[NDMOS_CONST_PATH_MAX]; strcpy (prefix, "DHd"); prefix[0] = tagc; ndmcstr_from_str (raw_name, namebuf, sizeof namebuf); ndmlogf (ixlog, prefix, 0, "%llu %s UNIX %llu", dir_node, namebuf, node); return 0; } int ndmjobfhdb_add_node (struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat) { char prefix[8]; char statbuf[100]; strcpy (prefix, "DHn"); prefix[0] = tagc; ndm_fstat_to_str (fstat, statbuf); ndmlogf (ixlog, prefix, 0, "%llu UNIX %s", node, statbuf); return 0; } int ndmjobfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node) { char prefix[8]; strcpy (prefix, "DHr"); prefix[0] = tagc; ndmlogf (ixlog, prefix, 0, "%llu", root_node); return 0; } bareos-Release-14.2.6/src/ndmp/ndmjob_job.c000066400000000000000000000314031263011562700204350ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmjob.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int build_job (void) { struct ndm_job_param * job = &the_job; int i, rc, n_err; char errbuf[100]; NDMOS_MACRO_ZEROFILL (job); args_to_job (); ndma_job_auto_adjust (job); if (o_rules) apply_rules (job, o_rules); i = n_err = 0; do { rc = ndma_job_audit (job, errbuf, i); if (rc > n_err || rc < 0) { ndmjob_log (0, "error: %s", errbuf); } n_err = rc; } while (i++ < n_err); if (n_err) { error_byebye ("can't proceed"); /* no return */ } return 0; } int args_to_job (void) { struct ndm_job_param * job = &the_job; int i; switch (the_mode) { case NDM_JOB_OP_QUERY_AGENTS: case NDM_JOB_OP_INIT_LABELS: case NDM_JOB_OP_LIST_LABELS: case NDM_JOB_OP_REMEDY_ROBOT: case NDM_JOB_OP_TEST_TAPE: case NDM_JOB_OP_TEST_MOVER: case NDM_JOB_OP_TEST_DATA: case NDM_JOB_OP_REWIND_TAPE: case NDM_JOB_OP_EJECT_TAPE: case NDM_JOB_OP_MOVE_TAPE: case NDM_JOB_OP_IMPORT_TAPE: case NDM_JOB_OP_EXPORT_TAPE: case NDM_JOB_OP_LOAD_TAPE: case NDM_JOB_OP_UNLOAD_TAPE: case NDM_JOB_OP_INIT_ELEM_STATUS: break; case NDM_JOB_OP_BACKUP: args_to_job_backup_env(); break; case NDM_JOB_OP_TOC: args_to_job_recover_env(); args_to_job_recover_nlist(); if (J_index_file) { jndex_doit(); jndex_merge_environment(); } break; case NDM_JOB_OP_EXTRACT: args_to_job_recover_env(); args_to_job_recover_nlist(); jndex_doit(); jndex_merge_environment(); break; case 'D': /* -o daemon */ return 0; default: printf ("mode -%c not implemented yet\n", the_mode); break; } job->operation = the_mode; /* DATA agent */ job->data_agent = D_data_agent; job->bu_type = B_bu_type; job->env_tab = E_environment; if (the_mode == NDM_JOB_OP_EXTRACT || the_mode == NDM_JOB_OP_TOC) { for (i = 0; i < n_file_arg; i++) { ndma_store_nlist (&job->nlist_tab, &nlist[i]); } job->nlist_tab.n_nlist = n_file_arg; } job->index_log.deliver = ndmjob_ixlog_deliver; /* TAPE agent */ job->tape_agent = T_tape_agent; job->tape_device = f_tape_device; job->record_size = b_bsize * 512; job->tape_timeout = o_tape_timeout; job->use_eject = o_use_eject; job->tape_target = o_tape_scsi; job->tape_tcp = o_tape_tcp; /* ROBOT agent */ job->robot_agent = R_robot_agent; job->robot_target = r_robot_target; job->robot_timeout = o_robot_timeout; if (o_tape_addr >= 0) { job->drive_addr = o_tape_addr; job->drive_addr_given = 1; } if (o_from_addr >= 0) { job->from_addr = o_from_addr; job->from_addr_given = 1; } if (o_to_addr >= 0) { job->to_addr = o_to_addr; job->to_addr_given = 1; } if (ROBOT_GIVEN()) job->have_robot = 1; /* media */ job->media_tab = m_media; return 0; } int args_to_job_backup_env (void) { ndmp9_pval pv; int i; if (C_chdir) { pv.name = "FILESYSTEM"; pv.value = C_chdir; ndma_store_env_list (&E_environment, &pv); } pv.name = "HIST"; pv.value = I_index_file ? "y" : "n"; ndma_store_env_list (&E_environment, &pv); pv.name = "TYPE"; pv.value = B_bu_type; ndma_store_env_list (&E_environment, &pv); if (U_user) { pv.name = "USER"; pv.value = U_user; ndma_store_env_list (&E_environment, &pv); } for (i = 0; (i < n_e_exclude_pattern); i++) { pv.name = "EXCLUDE"; pv.value = e_exclude_pattern[i]; ndma_store_env_list (&E_environment, &pv); } for (i = 0; (i < n_file_arg); i++) { pv.name = "FILES"; pv.value = file_arg[i]; ndma_store_env_list (&E_environment, &pv); } if (o_rules) { pv.name = "RULES"; pv.value = o_rules; ndma_store_env_list (&E_environment, &pv); } return E_environment.n_env; } int args_to_job_recover_env (void) { ndmp9_pval pv; int i; if (C_chdir) { pv.name = "PREFIX"; pv.value = C_chdir; ndma_store_env_list (&E_environment, &pv); } pv.name = "HIST"; pv.value = I_index_file ? "y" : "n"; ndma_store_env_list (&E_environment, &pv); pv.name = "TYPE"; pv.value = B_bu_type; ndma_store_env_list (&E_environment, &pv); if (U_user) { pv.name = "USER"; pv.value = U_user; ndma_store_env_list (&E_environment, &pv); } for (i = 0; i < n_e_exclude_pattern; i++) { pv.name = "EXCLUDE"; pv.value = e_exclude_pattern[i]; ndma_store_env_list (&E_environment, &pv); } if (o_rules) { pv.name = "RULES"; pv.value = o_rules; ndma_store_env_list (&E_environment, &pv); } /* file_arg[]s are done in nlist[] */ jndex_merge_environment (); return E_environment.n_env; } void normalize_name (char *name) { char * p = name; while (*p) { if (*p == '/' && p[1] == '/') { strcpy (p, p+1); continue; } if (p[0] == '/' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) { strcpy (p, p+2); continue; } p++; } } int args_to_job_recover_nlist (void) { int not_found = 0; int i, prefix_len, len; char * dest; if (C_chdir) { prefix_len = strlen (C_chdir) + 2; } else { prefix_len = 0; } for (i = 0; (i < n_file_arg) && (i < NDM_MAX_NLIST); i++) { if (file_arg_new[i]) { len = strlen (file_arg_new[i]) + prefix_len + 1; dest = NDMOS_API_MALLOC (len); *dest = 0; if (C_chdir) { strcpy (dest, C_chdir); } if (file_arg_new[i][0] != '/') { strcat (dest, "/"); } strcat (dest, file_arg_new[i]); normalize_name (file_arg_new[i]); normalize_name (file_arg[i]); normalize_name (dest); nlist[i].original_path = file_arg[i]; nlist[i].destination_path = dest; nlist[i].name = ""; nlist[i].other_name = ""; nlist[i].node = NDMP_INVALID_U_QUAD; } else { len = strlen (file_arg[i]) + prefix_len + 1; dest = NDMOS_API_MALLOC (len); *dest = 0; if (C_chdir) { strcpy (dest, C_chdir); } if (file_arg[i][0] != '/') { strcat (dest, "/"); } strcat (dest, file_arg[i]); normalize_name (file_arg[i]); normalize_name (dest); nlist[i].original_path = file_arg[i]; nlist[i].destination_path = dest; nlist[i].name = ""; nlist[i].other_name = ""; nlist[i].node = NDMP_INVALID_U_QUAD; } } return not_found; /* should ALWAYS be 0 */ } /* * Index files are sequentially searched. They can be VERY big. * There is a credible effort for efficiency here. * Probably lots and lots and lots of room for improvement. */ FILE * jndex_open (void); int jndex_doit (void) { FILE * fp; int rc; fp = jndex_open(); if (!fp) { /* error messages already given */ return -1; } ndmjob_log (1, "Processing input index (-J%s)", J_index_file); if (n_file_arg > 0) { rc = ndmfhdb_add_fh_info_to_nlist (fp, nlist, n_file_arg); if (rc < 0) { /* toast one way or another */ } } jndex_fetch_post_backup_data_env(fp); jndex_fetch_post_backup_media(fp); jndex_tattle(); if (jndex_audit_not_found ()) { ndmjob_log (1, "Warning: Missing index entries, valid file name(s)?"); } jndex_merge_media (); fclose(fp); return 0; } FILE * jndex_open (void) { char buf[256]; FILE * fp; if (!J_index_file) { /* Hmmm. */ ndmjob_log (1, "Warning: No -J input index?"); return 0; } ndmjob_log (1, "Reading input index (-I%s)", J_index_file); fp = fopen(J_index_file, "r"); if (!fp) { perror (J_index_file); error_byebye ("Can not open -J%s input index", J_index_file); /* no return */ } if (fgets (buf, sizeof buf, fp) == NULL) { fclose (fp); error_byebye ("Failed read 1st line of -J%s", J_index_file); /* no return */ } if (strcmp (buf, "##ndmjob -I\n") != 0) { fclose (fp); error_byebye ("Bad 1st line in -J%s", J_index_file); /* no return */ } if (fgets (buf, sizeof buf, fp) == NULL) { fclose (fp); error_byebye ("Failed read 2nd line of -J%s", J_index_file); /* no return */ } if (strcmp (buf, "##ndmjob -J\n") != 0) { fclose (fp); error_byebye ("Bad 2nd line in -J%s", J_index_file); /* no return */ } ndmjob_log (2, "Opened index (-J%s)", J_index_file); return fp; } int jndex_tattle (void) { char buf[100]; struct ndmmedia * me; struct ndm_env_entry * nev; int i; for (me = ji_media.head; me; me = me->next) { ndmmedia_to_str (me, buf); ndmjob_log (3, "ji me[%d] %s", i, buf); } for (nev = ji_environment.head; nev; nev = nev->next) { ndmjob_log (3, "ji env[%d] %s=%s", i, nev->pval.name, nev->pval.value); } for (i = 0; (i < n_file_arg) && (i < NDM_MAX_NLIST); i++) { if (nlist[i].fh_info.valid) { ndmjob_log (3, "ji fil[%d] fi=%lld %s", i, nlist[i].fh_info.value, file_arg[i]); } else { ndmjob_log (3, "ji fil[%d] not-found %s", i, file_arg[i]); } } return 0; } int jndex_merge_media (void) { struct ndmmedia * me; struct ndmmedia * jme; int i; for (jme = ji_media.head; jme; jme = jme->next) { if (! jme->valid_label) continue; /* can't match it up */ for (me = m_media.head; me; me = me->next) { if (! me->valid_label) continue; /* can't match it up */ if (strcmp (jme->label, me->label) != 0) continue; if (!jme->valid_slot && me->valid_slot) { jme->slot_addr = me->slot_addr; jme->valid_slot = 1; } } } ndmca_destroy_media_table (&m_media); m_media = ji_media; ndmjob_log (3, "After merging input -J index with -m entries"); i = 0; for (me = m_media.head; me; me = me->next) { char buf[40]; ndmmedia_to_str (me, buf); ndmjob_log (3, "%d: -m %s", i + 1, buf); i++; } return 0; } int jndex_audit_not_found (void) { int i; int not_found = 0; for (i = 0; (i < n_file_arg) && (i < NDM_MAX_NLIST); i++) { if (!nlist[i].fh_info.valid) { ndmjob_log (0, "No index entry for %s", file_arg[i]); not_found++; } } return not_found; } int jndex_merge_environment (void) { struct ndm_env_entry * entry; for (entry = ji_environment.head; entry; entry = entry->next) { if (strcmp(entry->pval.name, "FILESYSTEM") != 0 && strcmp(entry->pval.name, "PREFIX") != 0 && strcmp(entry->pval.name, "HIST") != 0 && strcmp(entry->pval.name, "TYPE") != 0) { ndma_store_env_list (&E_environment, &entry->pval); } } return 0; } int jndex_fetch_post_backup_data_env (FILE *fp) { int rc; char buf[512]; char * p; char * q; ndmp9_pval pv; rc = ndmbstf_first (fp, "DE ", buf, sizeof buf); if (rc <= 0) { return rc; /* error or not found */ } /* DE HIST=Yes */ while (buf[0] == 'D' && buf[1] == 'E' && buf[2] == ' ') { if (ji_environment.n_env >= NDM_MAX_ENV) { goto overflow; } p = &buf[2]; while (*p == ' ') p++; if (!strchr (p, '=')) { goto malformed; } q = strchr (p, '='); if (!q) { goto malformed; } *q++ = 0; pv.name = p; pv.value = q; ndma_store_env_list (&ji_environment, &pv); rc = ndmbstf_getline (fp, buf, sizeof buf); if (rc <= 0) { break; } continue; malformed: ndmjob_log (1, "Malformed in -J%s: %s", J_index_file, buf); continue; overflow: ndmjob_log (1, "Overflow in -J%s: %s", J_index_file, buf); } return 0; } int jndex_fetch_post_backup_media (FILE *fp) { int rc; char buf[512]; struct ndmmedia me; rc = ndmbstf_first (fp, "CM ", buf, sizeof buf); if (rc <= 0) { return rc; /* error or not found */ } /* CM 01 T103/10850K */ while (buf[0] == 'C' && buf[1] == 'M' && buf[2] == ' ') { if (ji_media.n_media >= NDM_MAX_MEDIA) { goto overflow; } if (ndmmedia_from_str (&me, &buf[6])) { goto malformed; } ndma_clone_media_entry (&ji_media, &me); rc = ndmbstf_getline (fp, buf, sizeof buf); if (rc <= 0) { break; } continue; malformed: ndmjob_log (1, "Malformed in -J%s: %s", J_index_file, buf); continue; overflow: ndmjob_log (1, "Overflow in -J%s: %s", J_index_file, buf); } return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndmjob_main.c000066400000000000000000000063741263011562700206200ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #define GLOBAL #include "ndmjob.h" int exit_program (void) { ndma_destroy_env_list (&E_environment); ndma_destroy_env_list (&ji_environment); ndmjob_unregister_callbacks (&the_session, &the_param.log); exit (0); } int main (int ac, char *av[]) { int rc; NDMOS_MACRO_ZEROFILL (&E_environment); NDMOS_MACRO_ZEROFILL (&ji_environment); NDMOS_MACRO_ZEROFILL (&m_media); NDMOS_MACRO_ZEROFILL (&ji_media); NDMOS_MACRO_ZEROFILL (&the_session); d_debug = -1; /* ready the_param early so logging works during process_args() */ NDMOS_MACRO_ZEROFILL (&the_param); the_param.log.deliver = ndmjob_log_deliver; the_param.log_level = 0; the_param.log_tag = "SESS"; #ifndef NDMOS_OPTION_NO_CONTROL_AGENT b_bsize = 20; index_fp = stderr; o_tape_addr = -1; o_from_addr = -1; o_to_addr = -1; p_ndmp_port = NDMPPORT; #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ log_fp = stderr; process_args (ac, av); if (the_param.log_level < d_debug) the_param.log_level = d_debug; if (the_param.log_level < v_verbose) the_param.log_level = v_verbose; the_param.config_file_name = o_config_file; if (the_mode == NDM_JOB_OP_DAEMON) { the_session.param = &the_param; if (n_noop) { dump_settings (); exit_program (); } ndma_daemon_session (&the_session, p_ndmp_port); exit_program (); } ndmjob_register_callbacks (&the_session, &the_param.log); #ifndef NDMOS_OPTION_NO_CONTROL_AGENT build_job(); /* might not return */ the_session.param = &the_param; if (n_noop) { dump_settings (); exit_program (); } start_index_file (); rc = ndma_client_session (&the_session, &the_job, (o_swap_connect != 0)); sort_index_file (); if (rc == 0) ndmjob_log (1, "Operation complete"); else ndmjob_log (1, "Operation complete but had problems."); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ exit_program (); } bareos-Release-14.2.6/src/ndmp/ndmjob_main_util.c000066400000000000000000000076131263011562700216520ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmjob.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT int start_index_file (void) { if (I_index_file && strcmp (I_index_file, "-") != 0) { FILE * ifp; if (atoi(I_index_file) != 0) { ndmjob_log (1, "Writing index (-I%s)", I_index_file); ifp = fdopen(atoi(I_index_file), "w"); } else { ndmjob_log (1, "Writing index (-I%s)", I_index_file); ifp = fopen (I_index_file, "w"); } if (!ifp) { error_byebye ("can't open -I logfile"); } index_fp = ifp; fprintf (ifp, "##ndmjob -I\n"); } else { index_fp = stderr; } return 0; } int sort_index_file (void) { if (I_index_file && strcmp (I_index_file, "-") != 0 && atoi(I_index_file) == 0) { char cmd[512]; fprintf (index_fp, "##ndmjob -J\n"); /* sorts to 2nd line */ fclose (index_fp); index_fp = stderr; /* in case anything else happens */ snprintf (cmd, sizeof(cmd), "LC_ALL=C sort %s -o %s\n", I_index_file, I_index_file); ndmjob_log (3, "sort command: %s", cmd); ndmjob_log (1, "sorting index"); if (system (cmd) < 0) error_byebye ("sort index failed"); ndmjob_log (1, "sort index done"); } return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ void error_byebye (char *fmt, ...) { va_list ap; char buf[4096]; va_start (ap, fmt); vsnprintf (buf, sizeof(buf), fmt, ap); va_end (ap); ndmjob_log (0, "FATAL: %s", buf); fprintf (stderr, "%s: %s\n", progname, buf); exit(1); } void ndmjob_log_deliver (struct ndmlog *log, char *tag, int lev, char *msg) { char tagbuf[32]; if (the_mode == 'D') { char buf[32]; snprintf (buf, sizeof(buf), "%s(%d)", tag, (int)getpid()); snprintf (tagbuf, sizeof(tagbuf), "%-11s", buf); } else { snprintf (tagbuf, sizeof(tagbuf), "%-4s", tag); } if (d_debug >= lev) { if (!o_no_time_stamps) { fprintf (log_fp, "%s %s %s\n", tagbuf, ndmlog_time_stamp(), msg); } else { fprintf (log_fp, "%s t[x] %s\n", tagbuf, msg); } fflush (log_fp); } if (v_verbose >= lev) { printf ("%s\n", msg); fflush (stdout); } } #ifndef NDMOS_OPTION_NO_CONTROL_AGENT void ndmjob_ixlog_deliver (struct ndmlog *log, char *tag, int lev, char *msg) { fprintf (index_fp, "%s %s\n", tag, msg); fflush (index_fp); /* this doesn't change the run time */ } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ void ndmjob_log (int lev, char *fmt, ...) { va_list ap; char buf[4096]; va_start (ap, fmt); vsnprintf (buf, sizeof(buf), fmt, ap); va_end (ap); ndmjob_log_deliver (&the_param.log, the_param.log_tag, lev, buf); } bareos-Release-14.2.6/src/ndmp/ndmjob_rules.c000066400000000000000000000040411263011562700210130ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmjob.h" #ifndef NDMOS_OPTION_NO_CONTROL_AGENT #include "ndmjr_none.h" int apply_rules (struct ndm_job_param *job, char *rules) { char reason[100]; int rc = 0; strcpy (reason, "(no reason given)"); if (NDMJR_NONE_RECOGNIZE(rules)) { rc = ndmjr_none_apply (job, reason); goto out; } error_byebye ("unknown rules: %s", rules); out: if (rc != 0) { error_byebye ("rules %s failed: %s", rules, reason); } return 0; } int help_rules () { printf (" %-8s -- %s\n", NDMJR_NONE_HELP_LINE_NAME, NDMJR_NONE_HELP_LINE_1); return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndmjob_simulator.c000066400000000000000000001211541263011562700217050ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: Tape/Robot and Authentication Simulation for testing purposes. * Implemented as callbacks from the generic framework. * Original code extracted from ndma_tape_simulator.c and * ndma_robot_simulator.c * */ #include "ndmjob.h" #ifdef NDMOS_OPTION_TAPE_SIMULATOR #ifdef NDMOS_OPTION_GAP_SIMULATOR struct simu_gap { uint32_t magic; uint32_t rectype; uint32_t prev_size; uint32_t size; }; #define SIMU_GAP_MAGIC 0x0BEEFEE0 #define SIMU_GAP_RT_(a,b,c,d) ((a<<0)+(b<<8)+(c<<16)+(d<<24)) #define SIMU_GAP_RT_BOT SIMU_GAP_RT_('B','O','T','_') #define SIMU_GAP_RT_DATA SIMU_GAP_RT_('D','A','T','A') #define SIMU_GAP_RT_FILE SIMU_GAP_RT_('F','I','L','E') #define SIMU_GAP_RT_EOT SIMU_GAP_RT_('E','O','T','_') /* send logical EOM with a bit less than 2 32k blocks left (due to SIMU_GAPs) */ #define TAPE_SIM_LOGICAL_EOM 32768*2 /* we sneak a peek at this global variable - probably not the best way, but * it works */ extern off_t o_tape_limit; static int simu_back_one (struct ndm_session *sess, int over_file_mark) { struct ndm_tape_agent * ta = sess->tape_acb; struct simu_gap gap; off_t cur_pos; off_t new_pos; int rc; cur_pos = lseek (ta->tape_fd, (off_t)0, 1); rc = read (ta->tape_fd, &gap, sizeof gap); if (rc != sizeof gap || gap.magic != SIMU_GAP_MAGIC) goto bail_out; new_pos = cur_pos; new_pos -= sizeof gap + gap.prev_size; ta->sent_leom = 0; /* * This is the new position. We need to update simu_prev_gap. */ lseek (ta->tape_fd, new_pos, 0); rc = read (ta->tape_fd, &gap, sizeof gap); if (rc != sizeof gap || gap.magic != SIMU_GAP_MAGIC) goto bail_out; switch (gap.rectype) { case SIMU_GAP_RT_BOT: /* can't actually back up to this, but update stuff */ ta->tape_state.file_num.value = 0; ta->tape_state.blockno.value = 0; /* cur_pos is now just right */ return 0; /* can't back up */ case SIMU_GAP_RT_EOT: /* this just isn't suppose to happen */ goto bail_out; case SIMU_GAP_RT_DATA: /* this is always OK */ if (ta->tape_state.blockno.value > 0) ta->tape_state.blockno.value--; lseek (ta->tape_fd, new_pos, 0); return SIMU_GAP_RT_DATA; case SIMU_GAP_RT_FILE: ta->tape_state.blockno.value = 0; if (!over_file_mark) { lseek (ta->tape_fd, cur_pos, 0); return 0; } if (ta->tape_state.file_num.value > 0) ta->tape_state.file_num.value--; lseek (ta->tape_fd, new_pos, 0); return SIMU_GAP_RT_FILE; default: /* this just isn't suppose to happen */ goto bail_out; } bail_out: lseek (ta->tape_fd, cur_pos, 0); return -1; } static int simu_forw_one (struct ndm_session *sess, int over_file_mark) { struct ndm_tape_agent * ta = sess->tape_acb; struct simu_gap gap; off_t cur_pos; off_t new_pos; int rc; cur_pos = lseek (ta->tape_fd, (off_t)0, 1); rc = read (ta->tape_fd, &gap, sizeof gap); if (rc != sizeof gap || gap.magic != SIMU_GAP_MAGIC) goto bail_out; ta->sent_leom = 0; new_pos = cur_pos; new_pos += gap.size + sizeof gap; switch (gap.rectype) { case SIMU_GAP_RT_BOT: /* this just isn't suppose to happen */ goto bail_out; case SIMU_GAP_RT_EOT: lseek (ta->tape_fd, cur_pos, 0); return 0; /* can't go forward */ case SIMU_GAP_RT_DATA: /* this is always OK */ ta->tape_state.blockno.value++; lseek (ta->tape_fd, new_pos, 0); return SIMU_GAP_RT_DATA; case SIMU_GAP_RT_FILE: if (!over_file_mark) { lseek (ta->tape_fd, cur_pos, 0); return 0; } ta->tape_state.blockno.value = 0; ta->tape_state.file_num.value++; /* cur_pos is just right */ return SIMU_GAP_RT_FILE; default: /* this just isn't suppose to happen */ goto bail_out; } bail_out: lseek (ta->tape_fd, cur_pos, 0); return -1; } static int simu_flush_weof (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->weof_on_close) { /* best effort */ ndmos_tape_wfm (sess); } return 0; } static int touch_tape_lockfile(char *drive_name) { char lockfile_name[NDMOS_CONST_PATH_MAX]; int fd; snprintf (lockfile_name, sizeof(lockfile_name), "%s.lck", drive_name); if ((fd = open(lockfile_name, O_CREAT|O_EXCL, 0666)) < 0) { return -1; } close(fd); return 0; } static void unlink_tape_lockfile(char *drive_name) { char lockfile_name[NDMOS_CONST_PATH_MAX]; snprintf (lockfile_name, sizeof(lockfile_name), "%s.lck", drive_name); unlink(lockfile_name); } static ndmp9_error ndmjob_tape_open (struct ndm_session *sess, char *drive_name, int will_write) { struct ndm_tape_agent * ta = sess->tape_acb; struct simu_gap gap; struct stat st; int read_only, omode; int rc, fd; char pos_symlink_name[NDMOS_CONST_PATH_MAX]; char pos_buf[32]; off_t pos = -1; if (stat (drive_name, &st) < 0) { return NDMP9_NO_DEVICE_ERR; } read_only = (st.st_mode & 0222) == 0; if (!will_write) { omode = 0; } else { if (read_only) return NDMP9_WRITE_PROTECT_ERR; omode = 2; /* ndmp_write means read/write */ } if (touch_tape_lockfile(drive_name) < 0) return NDMP9_DEVICE_BUSY_ERR; fd = open (drive_name, omode); if (fd < 0) { return NDMP9_PERMISSION_ERR; } snprintf (pos_symlink_name, sizeof(pos_symlink_name), "%s.pos", drive_name); if (st.st_size == 0) { remove (pos_symlink_name); if (will_write) { gap.magic = SIMU_GAP_MAGIC; gap.rectype = SIMU_GAP_RT_BOT; gap.size = 0; gap.prev_size = 0; if (write (fd, &gap, sizeof gap) < (int)sizeof gap) { close(fd); return NDMP9_IO_ERR; } gap.rectype = SIMU_GAP_RT_EOT; if (write (fd, &gap, sizeof gap) < (int)sizeof gap) { close(fd); return NDMP9_IO_ERR; } lseek (fd, (off_t)0, 0); } else { goto skip_header_check; } } rc = read (fd, &gap, sizeof gap); if (rc != sizeof gap) { close (fd); return NDMP9_NO_TAPE_LOADED_ERR; } #if 1 if (gap.magic != SIMU_GAP_MAGIC) { close (fd); return NDMP9_IO_ERR; } #else if (gap.magic != SIMU_GAP_MAGIC || gap.rectype != SIMU_GAP_RT_BOT || gap.size != 0) { close (fd); return NDMP9_IO_ERR; } #endif rc = readlink (pos_symlink_name, pos_buf, sizeof pos_buf); if (rc > 0) { pos_buf[rc] = 0; pos = strtol (pos_buf, 0, 0); lseek (fd, pos, 0); rc = read (fd, &gap, sizeof gap); if (rc == sizeof gap && gap.magic == SIMU_GAP_MAGIC) { } else { pos = sizeof gap; } lseek (fd, pos, 0); } skip_header_check: ta->tape_fd = fd; if (ta->drive_name) { NDMOS_API_FREE (ta->drive_name); } ta->drive_name = NDMOS_API_STRDUP (drive_name); bzero (&ta->tape_state, sizeof ta->tape_state); ta->tape_state.error = NDMP9_NO_ERR; ta->tape_state.state = NDMP9_TAPE_STATE_OPEN; ta->tape_state.open_mode = will_write ? NDMP9_TAPE_RDWR_MODE : NDMP9_TAPE_READ_MODE; ta->tape_state.file_num.valid = NDMP9_VALIDITY_VALID; ta->tape_state.soft_errors.valid = NDMP9_VALIDITY_VALID; ta->tape_state.block_size.valid = NDMP9_VALIDITY_VALID; ta->tape_state.blockno.valid = NDMP9_VALIDITY_VALID; ta->tape_state.total_space.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.space_remain.valid = NDMP9_VALIDITY_INVALID; ta->sent_leom = 0; if (o_tape_limit) { ta->tape_state.total_space.valid = NDMP9_VALIDITY_VALID; ta->tape_state.total_space.value = o_tape_limit; ta->tape_state.space_remain.valid = NDMP9_VALIDITY_VALID; ta->tape_state.space_remain.value = o_tape_limit - st.st_size; } return NDMP9_NO_ERR; } static ndmp9_error ndmjob_tape_close (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; off_t cur_pos; /* TODO this is not called on an EOF from the DMA, so the lockfile * will remain, although the spec says the tape service should be * automatically closed */ if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } simu_flush_weof(sess); #if 0 uint32_t resid; ndmos_tape_mtio (sess, NDMP9_MTIO_REW, 1, &resid); #endif cur_pos = lseek (ta->tape_fd, (off_t)0, 1); if (cur_pos != -1) { char pos_symlink_name[NDMOS_CONST_PATH_MAX]; char pos_buf[32]; snprintf (pos_symlink_name, sizeof(pos_symlink_name), "%s.pos", ta->drive_name); snprintf (pos_buf, sizeof(pos_buf), "%ld", (long) cur_pos); if (symlink (pos_buf, pos_symlink_name) < 0) { ; /* ignore error during close */ } } close (ta->tape_fd); ta->tape_fd = -1; unlink_tape_lockfile(ta->drive_name); ndmos_tape_initialize (sess); return NDMP9_NO_ERR; } static ndmp9_error ndmjob_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { struct ndm_tape_agent * ta = sess->tape_acb; int rc; *resid = count; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } /* audit for valid op and for tape mode */ switch (op) { case NDMP9_MTIO_FSF: while (*resid > 0) { simu_flush_weof(sess); rc = simu_forw_one (sess, 1); if (rc < 0) return NDMP9_IO_ERR; if (rc == 0) break; if (rc == SIMU_GAP_RT_FILE) *resid -= 1; } break; case NDMP9_MTIO_BSF: while (*resid > 0) { simu_flush_weof(sess); rc = simu_back_one (sess, 1); if (rc < 0) return NDMP9_IO_ERR; if (rc == 0) break; if (rc == SIMU_GAP_RT_FILE) *resid -= 1; } break; case NDMP9_MTIO_FSR: while (*resid > 0) { simu_flush_weof(sess); rc = simu_forw_one (sess, 0); if (rc < 0) return NDMP9_IO_ERR; if (rc == 0) break; *resid -= 1; } break; case NDMP9_MTIO_BSR: while (*resid > 0) { simu_flush_weof(sess); rc = simu_back_one (sess, 0); if (rc < 0) return NDMP9_IO_ERR; if (rc == 0) break; *resid -= 1; } break; case NDMP9_MTIO_REW: simu_flush_weof(sess); *resid = 0; ta->tape_state.file_num.value = 0; ta->tape_state.blockno.value = 0; lseek (ta->tape_fd, (off_t)(sizeof (struct simu_gap)), 0); break; case NDMP9_MTIO_OFF: simu_flush_weof(sess); /* Hmmm. */ break; case NDMP9_MTIO_EOF: /* should be "WFM" write-file-mark */ if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } while (*resid > 0) { ndmp9_error err; err = ndmos_tape_wfm (sess); if (err != NDMP9_NO_ERR) return err; *resid -= 1; } break; default: return NDMP9_ILLEGAL_ARGS_ERR; } return NDMP9_NO_ERR; } static ndmp9_error ndmjob_tape_write (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { struct ndm_tape_agent * ta = sess->tape_acb; int rc; struct simu_gap gap; off_t cur_pos; ndmp9_error err; uint32_t prev_size; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } cur_pos = lseek (ta->tape_fd, (off_t)0, 1); if (o_tape_limit) { /* if cur_pos is past LEOM, but we haven't sent NDMP9_EOM_ERR yet, * then do so now */ if (!ta->sent_leom && cur_pos > o_tape_limit - TAPE_SIM_LOGICAL_EOM) { ta->sent_leom = 1; return NDMP9_EOM_ERR; } /* if this write will put us over PEOM, then send NDMP9_IO_ERR */ if ((off_t)(cur_pos + sizeof gap + count) > o_tape_limit) { return NDMP9_IO_ERR; } } rc = read (ta->tape_fd, &gap, sizeof gap); if (rc != sizeof gap || gap.magic != SIMU_GAP_MAGIC) { lseek (ta->tape_fd, cur_pos, 0); return NDMP9_IO_ERR; } prev_size = gap.prev_size; gap.magic = SIMU_GAP_MAGIC; gap.rectype = SIMU_GAP_RT_DATA; gap.prev_size = prev_size; gap.size = count; lseek (ta->tape_fd, cur_pos, 0); if (write (ta->tape_fd, &gap, sizeof gap) == sizeof gap && (uint32_t)write (ta->tape_fd, buf, count) == count) { cur_pos += count + sizeof gap; prev_size = count; ta->tape_state.blockno.value++; *done_count = count; err = NDMP9_NO_ERR; } else { err = NDMP9_IO_ERR; } if (ftruncate (ta->tape_fd, cur_pos) < 0) return NDMP9_IO_ERR; lseek (ta->tape_fd, cur_pos, 0); gap.rectype = SIMU_GAP_RT_EOT; gap.size = 0; gap.prev_size = prev_size; if (write (ta->tape_fd, &gap, sizeof gap) < (int)sizeof gap) return NDMP9_IO_ERR; lseek (ta->tape_fd, cur_pos, 0); if (o_tape_limit) { ta->tape_state.space_remain.value = o_tape_limit - cur_pos; } ta->weof_on_close = 1; return err; } static ndmp9_error ndmjob_tape_wfm (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; int rc; struct simu_gap gap; off_t cur_pos; ndmp9_error err; uint32_t prev_size; ta->weof_on_close = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } cur_pos = lseek (ta->tape_fd, (off_t)0, 1); if (o_tape_limit) { /* note: filemarks *never* trigger NDMP9_EOM_ERR */ /* if this write will put us over PEOM, then send NDMP9_IO_ERR */ if ((off_t)(cur_pos + sizeof gap) > o_tape_limit) { return NDMP9_IO_ERR; } } rc = read (ta->tape_fd, &gap, sizeof gap); if (rc != sizeof gap || gap.magic != SIMU_GAP_MAGIC) { lseek (ta->tape_fd, cur_pos, 0); return NDMP9_IO_ERR; } prev_size = gap.prev_size; gap.magic = SIMU_GAP_MAGIC; gap.rectype = SIMU_GAP_RT_FILE; gap.prev_size = prev_size; gap.size = 0; lseek (ta->tape_fd, cur_pos, 0); if (write (ta->tape_fd, &gap, sizeof gap) == sizeof gap) { cur_pos += sizeof gap; prev_size = 0; ta->tape_state.file_num.value++; ta->tape_state.blockno.value = 0; err = NDMP9_NO_ERR; } else { err = NDMP9_IO_ERR; } if (ftruncate (ta->tape_fd, cur_pos) < 0) return NDMP9_IO_ERR; lseek (ta->tape_fd, cur_pos, 0); gap.rectype = SIMU_GAP_RT_EOT; gap.size = 0; gap.prev_size = prev_size; if (write (ta->tape_fd, &gap, sizeof gap) < (int)sizeof gap) return NDMP9_IO_ERR; lseek (ta->tape_fd, cur_pos, 0); if (o_tape_limit) { ta->tape_state.space_remain.value = o_tape_limit - cur_pos; } return err; } static ndmp9_error ndmjob_tape_read (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { struct ndm_tape_agent * ta = sess->tape_acb; int rc; struct simu_gap gap; off_t cur_pos; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } cur_pos = lseek (ta->tape_fd, (off_t)0, 1); rc = read (ta->tape_fd, &gap, sizeof gap); if (rc != sizeof gap || gap.magic != SIMU_GAP_MAGIC) { lseek (ta->tape_fd, cur_pos, 0); return NDMP9_IO_ERR; } if (gap.rectype == SIMU_GAP_RT_DATA) { unsigned nb; nb = count; if (nb > gap.size) nb = gap.size; rc = read (ta->tape_fd, buf, nb); if (rc != (int)nb) { lseek (ta->tape_fd, cur_pos, 0); return NDMP9_IO_ERR; } if (gap.size != nb) { cur_pos += sizeof gap + gap.size; lseek (ta->tape_fd, cur_pos, 0); } ta->tape_state.blockno.value++; *done_count = nb; } else { /* all other record types are interpretted as EOF */ lseek (ta->tape_fd, cur_pos, 0); *done_count = 0; return NDMP9_EOF_ERR; } return NDMP9_NO_ERR; } #else static int simu_flush_weof (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->weof_on_close) { /* best effort */ ndmos_tape_wfm (sess); } return 0; } static ndmp9_error ndmjob_tape_open (struct ndm_session *sess, char *drive_name, int will_write) { struct ndm_tape_agent * ta = sess->tape_acb; struct stat st; int read_only, omode; int fd; if (stat (drive_name, &st) < 0) { return NDMP9_NO_DEVICE_ERR; } read_only = (st.st_mode & 0222) == 0; if (!will_write) { omode = 0; } else { if (read_only) return NDMP9_WRITE_PROTECT_ERR; omode = 2; /* ndmp_write means read/write */ } fd = open (drive_name, omode); if (fd < 0) { return NDMP9_PERMISSION_ERR; } if (st.st_size == 0) { if (will_write) { lseek (fd, (off_t)0, 0); } else { goto skip_header_check; } } skip_header_check: ta->tape_fd = fd; if (ta->drive_name) { NDMOS_API_FREE (ta->drive_name); } ta->drive_name = NDMOS_API_STRDUP (drive_name); bzero (&ta->tape_state, sizeof ta->tape_state); ta->tape_state.error = NDMP9_NO_ERR; ta->tape_state.state = NDMP9_TAPE_STATE_OPEN; ta->tape_state.open_mode = will_write ? NDMP9_TAPE_RDWR_MODE : NDMP9_TAPE_READ_MODE; ta->tape_state.file_num.valid = NDMP9_VALIDITY_VALID; ta->tape_state.soft_errors.valid = NDMP9_VALIDITY_VALID; ta->tape_state.block_size.valid = NDMP9_VALIDITY_VALID; ta->tape_state.blockno.valid = NDMP9_VALIDITY_VALID; ta->tape_state.total_space.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.space_remain.valid = NDMP9_VALIDITY_INVALID; return NDMP9_NO_ERR; } static ndmp9_error ndmjob_tape_close (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } simu_flush_weof(sess); #if 0 uint32_t resid; ndmos_tape_mtio (sess, NDMP9_MTIO_REW, 1, &resid); #endif close (ta->tape_fd); ta->tape_fd = -1; ndmos_tape_initialize (sess); return NDMP9_NO_ERR; } static ndmp9_error ndmjob_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { struct ndm_tape_agent * ta = sess->tape_acb; int rc; *resid = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } /* audit for valid op and for tape mode */ switch (op) { case NDMP9_MTIO_FSF: return NDMP9_NO_ERR; case NDMP9_MTIO_BSF: return NDMP9_NO_ERR; case NDMP9_MTIO_FSR: return NDMP9_NO_ERR; case NDMP9_MTIO_BSR: return NDMP9_NO_ERR; case NDMP9_MTIO_REW: simu_flush_weof(sess); *resid = 0; ta->tape_state.file_num.value = 0; ta->tape_state.blockno.value = 0; lseek (ta->tape_fd, (off_t)0, 0); ndmalogf(sess, 0, 7, "NDMP9_MTIO_REW"); break; case NDMP9_MTIO_OFF: return NDMP9_NO_ERR; case NDMP9_MTIO_EOF: /* should be "WFM" write-file-mark */ return NDMP9_NO_ERR; default: return NDMP9_ILLEGAL_ARGS_ERR; } return NDMP9_NO_ERR; } static ndmp9_error ndmjob_tape_write (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { struct ndm_tape_agent * ta = sess->tape_acb; off_t cur_pos; ndmp9_error err; uint32_t prev_size; int rc; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } cur_pos = lseek (ta->tape_fd, (off_t)0, 1); lseek (ta->tape_fd, cur_pos, 0); if ((uint32_t)write (ta->tape_fd, buf, count) == count) { cur_pos += count; prev_size = count; ta->tape_state.blockno.value++; *done_count = count; err = NDMP9_NO_ERR; } else { ndmalogf(sess, 0, 7, "write not %d", count); err = NDMP9_IO_ERR; } /* error ignored for pipe file descriptor */ rc = ftruncate (ta->tape_fd, cur_pos); lseek (ta->tape_fd, cur_pos, 0); ta->weof_on_close = 1; return err; } static ndmp9_error ndmjob_tape_wfm (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; off_t cur_pos; ndmp9_error err; int rc; ta->weof_on_close = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } cur_pos = lseek (ta->tape_fd, (off_t)0, 1); lseek (ta->tape_fd, cur_pos, 0); err = NDMP9_NO_ERR; /* error ignored for pipe file descriptor */ rc = ftruncate (ta->tape_fd, cur_pos); lseek (ta->tape_fd, cur_pos, 0); return err; } static ndmp9_error ndmjob_tape_read (struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { struct ndm_tape_agent * ta = sess->tape_acb; size_t rc, nb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } nb = count; rc = read(ta->tape_fd, buf, nb); if (rc < 0) { return NDMP9_IO_ERR; } ta->tape_state.blockno.value++; *done_count = rc; if (rc == 0) { return NDMP9_EOF_ERR; } return NDMP9_NO_ERR; } #endif /* NDMOS_OPTION_GAP_SIMULATOR */ #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ #ifdef NDMOS_OPTION_ROBOT_SIMULATOR #include "scsiconst.h" /* * Robot state management **************************************************************** */ /* xxx_FIRST must be in order! */ #define IE_FIRST 0 #define IE_COUNT 2 #define MTE_FIRST 16 #define MTE_COUNT 1 #define DTE_FIRST 128 #define DTE_COUNT 2 #define STORAGE_FIRST 1024 #define STORAGE_COUNT 10 #if (IE_FIRST+IE_COUNT > MTE_FIRST) \ || (MTE_FIRST+MTE_COUNT > DTE_FIRST) \ || (DTE_FIRST+MTE_COUNT > STORAGE_FIRST) #error element addresses overlap or are in the wrong order #endif #define IS_IE_ADDR(a) ((a) >= IE_FIRST && (a) < IE_FIRST+IE_COUNT) #define IS_MTE_ADDR(a) ((a) >= MTE_FIRST && (a) < MTE_FIRST+MTE_COUNT) #define IS_DTE_ADDR(a) ((a) >= DTE_FIRST && (a) < DTE_FIRST+DTE_COUNT) #define IS_STORAGE_ADDR(a) ((a) >= STORAGE_FIRST && (a) < STORAGE_FIRST+STORAGE_COUNT) struct element_state { int full; int medium_type; int source_element; char pvoltag[32]; char avoltag[32]; }; struct robot_state { struct element_state mte[MTE_COUNT]; struct element_state storage[STORAGE_COUNT]; struct element_state ie[IE_COUNT]; struct element_state dte[DTE_COUNT]; }; static void robot_state_init(struct robot_state *rs) { int i; /* invent some nice data, with some nice voltags and whatnot */ NDMOS_API_BZERO(rs, sizeof(*rs)); /* (nothing to do for MTEs) */ for (i = 0; i < STORAGE_COUNT; i++) { struct element_state *es = &rs->storage[i]; es->full = 1; es->medium_type = 1; /* data */ es->source_element = 0; snprintf(es->pvoltag, sizeof(es->pvoltag), "PTAG%02XXX ", i); snprintf(es->avoltag, sizeof(es->avoltag), "ATAG%02XXX ", i); } /* (i/e are all empty) */ /* (dte's are all empty) */ } static void robot_state_load(struct ndm_session *sess, struct robot_state *rs) { int fd; char filename[NDMOS_CONST_PATH_MAX]; /* N.B. writing a struct to disk like this isn't portable, but this * is test code, so it's OK for now. */ snprintf(filename, sizeof filename, "%s/state", sess->robot_acb->sim_dir); fd = open(filename, O_RDONLY, 0666); if (fd < 0) { robot_state_init(rs); return; } if (read(fd, (void *)rs, sizeof(*rs)) < sizeof(*rs)) { robot_state_init(rs); close(fd); return; } close(fd); } static int robot_state_save(struct ndm_session *sess, struct robot_state *rs) { int fd; char filename[NDMOS_CONST_PATH_MAX]; /* N.B. writing a struct to disk like this isn't portable, but this * is test code, so it's OK for now. */ snprintf(filename, sizeof filename, "%s/state", sess->robot_acb->sim_dir); fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0666); if (fd < 0) return -1; if (write(fd, (void *)rs, sizeof(*rs)) < sizeof(*rs)) { close(fd); return -1; } close(fd); return 0; } static int robot_state_move(struct ndm_session *sess, struct robot_state *rs, int src, int dest) { char src_filename[NDMOS_CONST_PATH_MAX]; struct element_state *src_elt; char dest_filename[NDMOS_CONST_PATH_MAX]; struct element_state *dest_elt; struct stat st; char pos[NDMOS_CONST_PATH_MAX]; /* TODO: audit that the tape device is not using this volume right now */ ndmalogf(sess, 0, 3, "moving medium from %d to %d", src, dest); if (IS_IE_ADDR(src)) { src_elt = &rs->ie[src - IE_FIRST]; snprintf(src_filename, sizeof(src_filename), "%s/ie%d", sess->robot_acb->sim_dir, src - IE_FIRST); } else if (IS_DTE_ADDR(src)) { src_elt = &rs->dte[src - DTE_FIRST]; snprintf(src_filename, sizeof(src_filename), "%s/drive%d", sess->robot_acb->sim_dir, src - DTE_FIRST); } else if (IS_STORAGE_ADDR(src)) { src_elt = &rs->storage[src - STORAGE_FIRST]; snprintf(src_filename, sizeof(src_filename), "%s/slot%d", sess->robot_acb->sim_dir, src - STORAGE_FIRST); } else { ndmalogf(sess, 0, 3, "invalid src address %d", src); return -1; } if (IS_IE_ADDR(dest)) { dest_elt = &rs->ie[dest - IE_FIRST]; snprintf(dest_filename, sizeof(dest_filename), "%s/ie%d", sess->robot_acb->sim_dir, dest - IE_FIRST); } else if (IS_DTE_ADDR(dest)) { dest_elt = &rs->dte[dest - DTE_FIRST]; snprintf(dest_filename, sizeof(dest_filename), "%s/drive%d", sess->robot_acb->sim_dir, dest - DTE_FIRST); } else if (IS_STORAGE_ADDR(dest)) { dest_elt = &rs->storage[dest - STORAGE_FIRST]; snprintf(dest_filename, sizeof(dest_filename), "%s/slot%d", sess->robot_acb->sim_dir, dest - STORAGE_FIRST); } else { ndmalogf(sess, 0, 3, "invalid dst address %d", src); return -1; } if (!src_elt->full) { ndmalogf(sess, 0, 3, "src not full"); return -1; } if (dest_elt->full) { ndmalogf(sess, 0, 3, "dest full"); return -1; } /* OK, enough checking, let's do it */ /* delete the destination, if it exists */ if (stat (dest_filename, &st) >= 0) { ndmalogf(sess, 0, 3, "unlink %s", dest_filename); if (unlink(dest_filename) < 0) { ndmalogf(sess, 0, 0, "error unlinking: %s", strerror(errno)); return -1; } } /* and move the source if it exists */ if (stat (src_filename, &st) >= 0) { ndmalogf(sess, 0, 3, "move %s to %s", src_filename, dest_filename); if (rename(src_filename, dest_filename) < 0) { ndmalogf(sess, 0, 0, "error renaming: %s", strerror(errno)); return -1; } } else { /* otherwise touch the destination file */ ndmalogf(sess, 0, 3, "touch %s", dest_filename); int fd = open(dest_filename, O_CREAT | O_WRONLY, 0666); if (fd < 0) { ndmalogf(sess, 0, 0, "error touching: %s", strerror(errno)); return -1; } close(fd); } /* blow away any tape-drive .pos files */ snprintf(pos, sizeof(pos), "%s.pos", src_filename); unlink(pos); /* ignore errors */ snprintf(pos, sizeof(pos), "%s.pos", dest_filename); unlink(pos); /* ignore errors */ /* update state */ *dest_elt = *src_elt; ndmalogf(sess, 0, 3, "setting dest's source_element to %d", src); dest_elt->source_element = src; src_elt->full = 0; ndmalogf(sess, 0, 3, "move successful"); return 0; } /* * SCSI commands **************************************************************** */ /* * Utilities */ static ndmp9_error scsi_fail_with_sense_code(struct ndm_session *sess, ndmp9_execute_cdb_reply *reply, int status, int sense_key, int asq) { unsigned char ext_sense[] = { 0x72, /* current errors */ sense_key & SCSI_SENSE_SENSE_KEY_MASK, (asq >> 8) & 0xff, (asq ) & 0xff, 0, 0, 0, 0 }; ndmalogf(sess, 0, 3, "sending failure; status=0x%02x sense_key=0x%02x asq=0x%04x", status, sense_key, asq); reply->status = status; reply->ext_sense.ext_sense_len = sizeof(ext_sense); reply->ext_sense.ext_sense_val = NDMOS_API_MALLOC(sizeof(ext_sense)); if (!reply->ext_sense.ext_sense_val) return NDMP9_NO_MEM_ERR; NDMOS_API_BCOPY(ext_sense, reply->ext_sense.ext_sense_val, sizeof(ext_sense)); return NDMP9_NO_ERR; } /* * Command implementations */ static ndmp9_error execute_cdb_test_unit_ready (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { if (request->cdb.cdb_len != 6) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); /* yep, we're ready! */ return NDMP9_NO_ERR; } static ndmp9_error execute_cdb_inquiry (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { unsigned char *cdb = (unsigned char *)request->cdb.cdb_val; char *response; int response_len; char *p; /* N.B.: only page code 0 is supported */ if (request->cdb.cdb_len != 6 || request->data_dir != NDMP9_SCSI_DATA_DIR_IN || cdb[1] & 0x01 || cdb[2] != 0 || request->datain_len < 96 || ((cdb[3] << 8) + cdb[4]) < 96) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); response_len = 96; p = response = NDMOS_API_MALLOC(response_len); if (!response) return NDMP9_NO_MEM_ERR; NDMOS_API_BZERO(response, response_len); *(p++) = 0x08; /* media changer */ *(p++) = 0; /* RMB=0 */ *(p++) = 6; /* VERSION=SPC-4 */ *(p++) = 2; /* !NORMACA, !HISUP, RESPONSE DATA FORMAT = 2 */ *(p++) = 92; /* remaining bytes */ *(p++) = 0; /* lots of flags, all 0 */ *(p++) = 0; /* lots of flags, all 0 */ *(p++) = 0; /* lots of flags, all 0 */ NDMOS_API_BCOPY("NDMJOB ", p, 8); p += 8; NDMOS_API_BCOPY("FakeRobot ", p, 16); p += 16; NDMOS_API_BCOPY("1.0 ", p, 4); p += 4; /* remainder is zero */ reply->datain.datain_len = response_len; reply->datain.datain_val = response; return NDMP9_NO_ERR; } static ndmp9_error execute_cdb_mode_sense_6 (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { unsigned char *cdb = (unsigned char *)request->cdb.cdb_val; int page, subpage; char *response; int response_len; char *p; if (request->cdb.cdb_len != 6 || request->data_dir != NDMP9_SCSI_DATA_DIR_IN) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); page = cdb[2] & 0x3f; subpage = cdb[3]; switch ((page << 8) + subpage) { case 0x1D00: /* Element Address Assignment */ if (request->datain_len < 20 || cdb[4] < 20) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); response_len = 24; p = response = NDMOS_API_MALLOC(response_len); if (!response) return NDMP9_NO_MEM_ERR; NDMOS_API_BZERO(response, response_len); *(p++) = response_len; *(p++) = 0; /* reserved medium type */ *(p++) = 0; /* reserved device-specific parameter */ *(p++) = 0; /* block descriptor length (DBD = 0 above)*/ *(p++) = 0x1D; /* page code */ *(p++) = 18; /* remaining bytes */ *(p++) = (MTE_FIRST >> 8) & 0xff; *(p++) = MTE_FIRST & 0xff; *(p++) = (MTE_COUNT >> 8) & 0xff; *(p++) = MTE_COUNT & 0xff; *(p++) = (STORAGE_FIRST >> 8) & 0xff; *(p++) = STORAGE_FIRST & 0xff; *(p++) = (STORAGE_COUNT >> 8) & 0xff; *(p++) = STORAGE_COUNT & 0xff; *(p++) = (IE_FIRST >> 8) & 0xff; *(p++) = IE_FIRST & 0xff; *(p++) = (IE_COUNT >> 8) & 0xff; *(p++) = IE_COUNT & 0xff; *(p++) = (DTE_FIRST >> 8) & 0xff; *(p++) = DTE_FIRST & 0xff; *(p++) = (DTE_COUNT >> 8) & 0xff; *(p++) = DTE_COUNT & 0xff; /* remainder is zero */ break; default: return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); } reply->datain.datain_len = response_len; reply->datain.datain_val = response; return NDMP9_NO_ERR; } static ndmp9_error execute_cdb_read_element_status (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { unsigned char *cdb = (unsigned char *)request->cdb.cdb_val; struct robot_state rs; int min_addr, max_elts; char *response; int response_len; int required_len; int num_elts = IE_COUNT + MTE_COUNT + DTE_COUNT + STORAGE_COUNT; char *p; if (request->cdb.cdb_len != 12 || request->data_dir != NDMP9_SCSI_DATA_DIR_IN) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); min_addr = (cdb[2] << 8) + cdb[3]; max_elts = (cdb[4] << 8) + cdb[5]; response_len = (cdb[7] << 16) + (cdb[8] << 8) + cdb[9]; if (response_len < 8) { return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); } /* this is bogus, but we don't allow "partial" status requests */ if (min_addr > IE_FIRST || max_elts < num_elts) { return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); } robot_state_load(sess, &rs); robot_state_save(sess, &rs); /* calculate the total space required */ required_len = 8; /* element status data header */ if (MTE_COUNT) { required_len += 8; /* element status page header */ required_len += 12 * MTE_COUNT; /* element status descriptor w/o tags */ } if (STORAGE_COUNT) { required_len += 8; /* element status page header */ required_len += 84 * STORAGE_COUNT; /* element status descriptor w/ tags */ } if (IE_COUNT) { required_len += 8; /* element status page header */ required_len += 84 * IE_COUNT; /* element status descriptor w/ tags */ } if (DTE_COUNT) { required_len += 8; /* element status page header */ required_len += 84 * DTE_COUNT; /* element status descriptor w/ tags */ } p = response = NDMOS_API_MALLOC(response_len); if (!response) return NDMP9_NO_MEM_ERR; NDMOS_API_BZERO(response, response_len); /* write the element status data header */ *(p++) = IE_FIRST >> 8; /* first element address */ *(p++) = IE_FIRST & 0xff; *(p++) = num_elts >> 8; /* number of elements */ *(p++) = num_elts & 0xff; *(p++) = 0; /* reserved */ *(p++) = (required_len-8) >> 16; /* remaining byte count of report */ *(p++) = ((required_len-8) >> 8) & 0xff; *(p++) = (required_len-8) & 0xff; /* only fill in the rest if we have space */ if (required_len <= response_len) { int i; struct { int first, count, have_voltags, eltype; int empty_flags, full_flags; struct element_state *es; } page[4] = { { IE_FIRST, IE_COUNT, 1, 3, 0x38, 0x39, &rs.ie[0] }, { MTE_FIRST, MTE_COUNT, 0, 1, 0x00, 0x01, &rs.mte[0] }, { DTE_FIRST, DTE_COUNT, 1, 4, 0x08, 0x81, &rs.dte[0] }, { STORAGE_FIRST, STORAGE_COUNT, 1, 2, 0x08, 0x09, &rs.storage[0] }, }; for (i = 0; i < 4; i++) { int descr_size = page[i].have_voltags? 84 : 12; int totalsize = descr_size * page[i].count; int j; if (page[i].count == 0) continue; /* write the page header */ *(p++) = page[i].eltype; *(p++) = page[i].have_voltags? 0xc0 : 0; *(p++) = 0; *(p++) = descr_size; *(p++) = 0; /* reserved */ *(p++) = totalsize >> 16; *(p++) = (totalsize >> 8) & 0xff; *(p++) = totalsize & 0xff; /* and write each descriptor */ for (j = 0; j < page[i].count; j++) { int elt_addr = page[i].first + j; int src_elt = page[i].es[j].source_element; unsigned char byte9 = page[i].es[j].medium_type; if (src_elt!= 0) byte9 |= 0x80; /* SVALID */ *(p++) = elt_addr >> 8; *(p++) = elt_addr & 0xff; *(p++) = page[i].es[j].full? page[i].full_flags : page[i].empty_flags; *(p++) = 0; *(p++) = 0; *(p++) = 0; *(p++) = 0; *(p++) = 0; *(p++) = 0; *(p++) = byte9; *(p++) = src_elt >> 8; *(p++) = src_elt & 0xff; if (page[i].have_voltags) { int k; if (page[i].es[j].full) { for (k = 0; k < 32; k++) { if (!page[i].es[j].pvoltag[k]) break; p[k] = page[i].es[j].pvoltag[k]; } for (k = 0; k < 32; k++) { if (!page[i].es[j].avoltag[k]) break; p[k+36] = page[i].es[j].avoltag[k]; } } else { for (k = 0; k < 32; k++) { p[k] = p[k+36] = ' '; } } p += 72; } } } } reply->datain.datain_len = response_len; reply->datain.datain_val = response; return NDMP9_NO_ERR; } static ndmp9_error execute_cdb_move_medium (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { unsigned char *cdb = (unsigned char *)request->cdb.cdb_val; struct robot_state rs; int mte, src, dest; if (request->cdb.cdb_len != 12) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_FIELD_IN_CDB); mte = (cdb[2] << 8) + cdb[3]; src = (cdb[4] << 8) + cdb[5]; dest = (cdb[6] << 8) + cdb[7]; if (!IS_MTE_ADDR(mte)) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_ELEMENT_ADDRESS); robot_state_load(sess, &rs); if (robot_state_move(sess, &rs, src, dest) < 0) return scsi_fail_with_sense_code(sess, reply, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_KEY_ILLEGAL_REQUEST, ASQ_INVALID_ELEMENT_ADDRESS); robot_state_save(sess, &rs); return NDMP9_NO_ERR; } static struct { unsigned char cdb_byte; ndmp9_error (* execute_cdb)( struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply); } cdb_executors[] = { { SCSI_CMD_TEST_UNIT_READY, execute_cdb_test_unit_ready }, { SCSI_CMD_INQUIRY, execute_cdb_inquiry }, { SCSI_CMD_MODE_SENSE_6, execute_cdb_mode_sense_6 }, { SCSI_CMD_READ_ELEMENT_STATUS, execute_cdb_read_element_status }, { SCSI_CMD_MOVE_MEDIUM, execute_cdb_move_medium }, { 0, 0 }, }; static ndmp9_error ndmjob_scsi_open (struct ndm_session *sess, char *name) { struct stat st; struct ndm_robot_agent * ra = sess->robot_acb; if (!name || strlen(name) > sizeof(ra->sim_dir)-1) return NDMP9_NO_DEVICE_ERR; /* check that it's a directory */ if (stat (name, &st) < 0) return NDMP9_NO_DEVICE_ERR; if (!S_ISDIR(st.st_mode)) return NDMP9_NO_DEVICE_ERR; ra->sim_dir = NDMOS_API_STRDUP (name); ra->scsi_state.error = NDMP9_NO_ERR; return NDMP9_NO_ERR; } static ndmp9_error ndmjob_scsi_close (struct ndm_session *sess) { return NDMP9_NO_ERR; } static ndmp9_error ndmjob_scsi_reset (struct ndm_session *sess) { return NDMP9_NO_ERR; } static ndmp9_error ndmjob_scsi_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { char cdb_byte; int i; cdb_byte = request->cdb.cdb_val[0]; for (i = 0; cdb_executors[i].execute_cdb; i++) { if (cdb_executors[i].cdb_byte == cdb_byte) return cdb_executors[i].execute_cdb(sess, request, reply); } return NDMP9_ILLEGAL_ARGS_ERR; } #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ static int ndmjob_validate_password (struct ndm_session *sess, char *name, char *pass) { if (strcmp (name, "ndmp") != 0) return 0; if (strcmp (pass, "ndmp") != 0) return 0; return 1; /* OK */ } static int ndmjob_validate_md5 (struct ndm_session *sess, char *name, char digest[16]) { if (strcmp (name, "ndmp") != 0) return 0; if (!ndmmd5_ok_digest (sess->md5_challenge, "ndmp", digest)) return 0; return 1; /* OK */ } void ndmjob_register_callbacks (struct ndm_session *sess, struct ndmlog *ixlog) { #ifdef NDMOS_OPTION_TAPE_SIMULATOR struct ndm_tape_simulator_callbacks tape_callbacks; #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ #ifdef NDMOS_OPTION_ROBOT_SIMULATOR struct ndm_robot_simulator_callbacks robot_callbacks; #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ struct ndm_auth_callbacks auth_callbacks; struct ndm_fhdb_callbacks fhdb_callbacks; #ifdef NDMOS_OPTION_TAPE_SIMULATOR tape_callbacks.tape_open = ndmjob_tape_open; tape_callbacks.tape_close = ndmjob_tape_close; tape_callbacks.tape_mtio = ndmjob_tape_mtio; tape_callbacks.tape_write = ndmjob_tape_write; tape_callbacks.tape_wfm = ndmjob_tape_wfm; tape_callbacks.tape_read = ndmjob_tape_read; ndmos_tape_register_callbacks (sess, &tape_callbacks); #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ #ifdef NDMOS_OPTION_ROBOT_SIMULATOR robot_callbacks.scsi_open = ndmjob_scsi_open; robot_callbacks.scsi_close = ndmjob_scsi_close; robot_callbacks.scsi_reset = ndmjob_scsi_reset; robot_callbacks.scsi_execute_cdb = ndmjob_scsi_execute_cdb; ndmos_scsi_register_callbacks (sess, &robot_callbacks); #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ auth_callbacks.validate_password = ndmjob_validate_password; auth_callbacks.validate_md5 = ndmjob_validate_md5; ndmos_auth_register_callbacks (sess, &auth_callbacks); fhdb_callbacks.add_file = ndmjobfhdb_add_file; fhdb_callbacks.add_dir = ndmjobfhdb_add_dir; fhdb_callbacks.add_node = ndmjobfhdb_add_node; fhdb_callbacks.add_dirnode_root = ndmjobfhdb_add_dirnode_root; ndmfhdb_register_callbacks (ixlog, &fhdb_callbacks); } void ndmjob_unregister_callbacks (struct ndm_session *sess, struct ndmlog *ixlog) { ndmfhdb_unregister_callbacks (ixlog); ndmos_auth_unregister_callbacks (sess); #ifdef NDMOS_OPTION_ROBOT_SIMULATOR ndmos_scsi_unregister_callbacks (sess); #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ #ifdef NDMOS_OPTION_TAPE_SIMULATOR ndmos_auth_unregister_callbacks (sess); #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ } bareos-Release-14.2.6/src/ndmp/ndmjr_none.c000066400000000000000000000032471263011562700204700ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmagents.h" /* struct ndm_job_param */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT #include "ndmjr_none.h" int ndmjr_none_apply (struct ndm_job_param *job, char *reason) { return 0; } #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndmjr_none.h000066400000000000000000000034061263011562700204720ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_CONTROL_AGENT #define NDMJR_NONE_RECOGNIZE(RULES) \ (strcmp (RULES, "none") == 0) #define NDMJR_NONE_HELP_LINE_NAME \ "none" #define NDMJR_NONE_HELP_LINE_1 \ "no additional rules (default)" extern int ndmjr_none_apply (struct ndm_job_param *job, char *reason); #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */ bareos-Release-14.2.6/src/ndmp/ndml_agent.c000066400000000000000000000141161263011562700204440ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * Handle representation of an NDMP agent. * * This provides for a common text for specifying * an agent host, connection authentication, and * protocol version. The text specification may * originate on the command line, in a config file, * or elsewhere. * * A text string representation has the form: * * AGENT ::= HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]] * AGENT ::= . * FLAGS ::= [23][ntm] * * The internal representation is a struct ndmagent. */ #include "ndmlib.h" /* On some solaris distributions INADDR_NONE is not defined, * so define it here.. */ #ifndef INADDR_NONE #define INADDR_NONE ((in_addr_t)-1) #endif int ndmagent_from_str (struct ndmagent *agent, char *str) { int have_vers = 0; int have_auth = 0; int rc; char * acct; char * port; char * flags; NDMOS_MACRO_ZEROFILL (agent); if ((acct = strchr (str, ',')) != 0) *acct++ = 0; /* stomp */ if ((port = strchr (str, ':')) != 0) *port++ = 0; /* stomp */ if (port) { flags = strchr (port, '/'); } else { flags = strchr (str, '/'); } if (flags) *flags++ = 0; /* stomp */ /* * HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]] * ^ ^ ^ ^ * str------+ | | | * port-----------+ | | * flags-----------------+ | * acct--------------------------+ * * The delimiters have been stomped (*p=0). * If a portion is missing, the respective pointer is NULL (p==0) * We restore the delimiters (p[-1]=x) as we proceed. */ strncpy (agent->host, str, NDMAGENT_HOST_MAX-1); if (port) { agent->port = atoi(port); port[-1] = ':'; /* restore */ } else { agent->port = NDMPPORT; } if (flags) { char * p; for (p = flags; *p; p++) { switch (*p) { #ifndef NDMOS_OPTION_NO_NDMP2 case '2': agent->protocol_version = 2; have_vers++; break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case '3': agent->protocol_version = 3; have_vers++; break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case '4': agent->protocol_version = 4; have_vers++; break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ case 'n': /* NDMP_AUTH_NONE */ case 't': /* NDMP_AUTH_TEXT */ case 'm': /* NDMP_AUTH_MD5 */ case 'v': /* void (don't auth) */ agent->auth_type = *p; have_auth++; break; default: rc = -1; goto error_out; } } if (have_auth > 1 || have_vers > 1) { rc = -2; goto error_out; } flags[-1] = '/'; /* restore */ } if (acct) { char * pass; if ((pass = strchr (acct, ',')) != 0) *pass++ = 0; strncpy (agent->account, acct, NDMAGENT_ACCOUNT_MAX-1); if (pass) { strncpy (agent->password, pass, NDMAGENT_PASSWORD_MAX-1); pass[-1] = ','; } acct[-1] = ','; /* restore */ if (!have_auth) { agent->auth_type = 't'; /* NDMP_AUTH_TEXT */ } } if (strcmp (agent->host, ".") == 0) { agent->conn_type = NDMCONN_TYPE_RESIDENT; strcpy (agent->host, "(resident)"); } else { agent->conn_type = NDMCONN_TYPE_REMOTE; } return 0; error_out: if (acct) acct[-1] = ','; /* restore */ if (port) port[-1] = ':'; /* restore */ if (flags) flags[-1] = '/'; /* restore */ return rc; } #ifdef NDMOS_OPTION_USE_GETHOSTBYNAME int ndmhost_lookup (char *hostname, struct sockaddr_in *sin) { struct hostent * he; in_addr_t addr; NDMOS_MACRO_ZEROFILL (sin); #ifdef NDMOS_OPTION_HAVE_SIN_LEN sin->sin_len = sizeof *sin; #endif sin->sin_family = AF_INET; addr = inet_addr (hostname); if (addr != INADDR_NONE) { bcopy (&addr, &sin->sin_addr, 4); } else { he = gethostbyname (hostname); if (!he) return -1; bcopy (he->h_addr, &sin->sin_addr, 4); } return 0; } #endif #ifdef NDMOS_OPTION_USE_GETADDRINFO int ndmhost_lookup (char *hostname, struct sockaddr_in *sin) { int res; struct addrinfo hints; struct addrinfo * ai; in_addr_t addr; NDMOS_MACRO_ZEROFILL (sin); #ifdef NDMOS_OPTION_HAVE_SIN_LEN sin->sin_len = sizeof *sin; #endif sin->sin_family = AF_INET; addr = inet_addr (hostname); if (addr != INADDR_NONE) { bcopy (&addr, &sin->sin_addr, 4); } else { memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = 0; res = getaddrinfo (hostname, NULL, &hints, &ai); if (res != 0) { return 1; } bcopy (&(((struct sockaddr_in *)ai->ai_addr)->sin_addr), &sin->sin_addr, 4); freeaddrinfo(ai); } return 0; } #endif int ndmagent_to_sockaddr_in (struct ndmagent *agent, struct sockaddr_in *sin) { int rc; rc = ndmhost_lookup (agent->host, sin); /* inits sin */ if (rc) return rc; sin->sin_port = htons (agent->port); return 0; } bareos-Release-14.2.6/src/ndmp/ndml_bstf.c000066400000000000000000000230541263011562700203050ustar00rootroot00000000000000/* * Copyright 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * Binary Search Text File (BSTF) * * Use conventional binary search method on a sorted text * file. The file MUST be sorted in ascending, lexicographic * order. This is the default order of sort(1). */ #include "ndmlib.h" #ifdef SELF_TEST int n_seek, n_align, n_line, n_getc; #endif #define MIN_DELTA 2048 /* * ndmbstf_first() * ndmbstf_first_with_bounds() * * Returns: * <0 Error * -1 EOF * -2 Malformed line/file * -3 fseek() to determine file size failed * -4 fseek() to hop failed * =0 First line found in buf[], does not match key * >0 Length of first matching line in buf[] */ int ndmbstf_first ( FILE *fp, /* the file to search */ char *key, /* what we're looking for */ char *buf, /* returned line */ unsigned max_buf) /* maximum lenght of buf (sizeof (buf)) */ { return ndmbstf_first_with_bounds (fp, key, buf, max_buf, 0, 0); } int ndmbstf_first_with_bounds ( FILE *fp, /* the file to search */ char *key, /* what we're looking for */ char *buf, /* returned line */ unsigned max_buf, /* maximum lenght of buf (sizeof (buf)) */ off_t lower_bound, /* offset, to skip headers, usually 0 */ off_t upper_bound) /* 0->don't know, >0 limit */ { off_t off; off_t lower, upper; /* bounds */ off_t delta; int rc, buf_len; if (upper_bound == 0) { off_t end_off; /* * Determine the file size using fseek()/ftell() */ fseeko (fp, 0, SEEK_END); end_off = ftello (fp); if (end_off == -1) return -3; upper_bound = end_off; } /* * Set lower and upper bounds of the binary search */ lower = lower_bound; upper = upper_bound; for (;;) { /* * Determine the delta (distance) between the current * lower and upper bounds. If delta is small, it is more * efficient to do a linear search than to continue * seeking. This is because stdio will pre-read * portions no matter what and fseek()ing will discard * the pre-read portions. MIN_DELTA is the approximation * of the stdio pre-read size. Better to just * linearly process the pre-read portion in the * hopes that our answer is already sitting in the * stdio buffer. */ delta = upper - lower; if (delta <= MIN_DELTA) break; /* * Seek to the first line after the midpoint * between the lower and upper bounds. */ off = lower + delta / 2; rc = ndmbstf_seek_and_align (fp, &off); if (rc < 0) { if (rc == EOF) { /* * Alignment found a very long line without * a \n at the end of the file. All we * can do now is try a linear search * from the current lower bound. */ } return -4; /* fseek() for hop failed */ } /* * Read the next line up into buf[]. */ buf_len = ndmbstf_getline (fp, buf, max_buf); if (buf_len <= 0) { /* * EOF, or malformed line. All we can do now * is try a linear search from the current * lower bound. */ break; } /* * This is the crucial point. * * buf[] contains a line just read. * off points the the line we just read. * key[] is what we're looking for. * * Is the objective line (what we're trying to find) * somewhere between lower..off or between off..upper. */ rc = ndmbstf_compare (key, buf); if (rc > 0) { /* key>buf. Objective somewhere in off..upper */ lower = off; } else { /* * key<=buf. Objective somewhere in lower..off * Notice that if key==buf, there still might * be a line ==key before the one we just * read. There might be hundreds of such * lines. The objective is the FIRST line * greater than or equal to the key. * This might be it. It might not. * So, keep searching. */ upper = off; } } /* * Do an unbounded linear search begining at the * lower bound. */ off = lower; rc = ndmbstf_seek_and_align (fp, &off); if (rc < 0) { if (rc == EOF) { /* * Alignment found a very long line without * a \n at the end of the file. All we * can do is give up. */ return -2; } return -4; /* fseek() for hop failed */ } /* * Read the next line up into buf[]. */ for (;;) { buf_len = ndmbstf_getline (fp, buf, max_buf); if (buf_len <= 0) { if (buf_len == EOF) break; /* at end of file */ return -2; } rc = ndmbstf_compare (key, buf); if (rc == 0) { /* match */ return buf_len; } if (rc < 0) return 0; /* have line but it doesn't match */ } return EOF; } int ndmbstf_next ( FILE *fp, /* the file to search */ char *key, /* what we're looking for */ char *buf, /* returned line */ unsigned max_buf) /* maximum lenght of buf (sizeof (buf)) */ { int rc, buf_len; /* * Read the next line up into buf[]. */ buf_len = ndmbstf_getline (fp, buf, max_buf); if (buf_len <= 0) { if (buf_len == EOF) return EOF; /* at end of file */ return -2; /* malformed line */ } rc = ndmbstf_compare (key, buf); if (rc == 0) { /* match */ return buf_len; } else { return 0; /* have line but it doesn't match */ } } /* * ndmbstr_getline() * * Returns: * <0 Error * -1 EOF * -2 Malformed line * >=0 Length of buf */ int ndmbstf_getline (FILE *fp, char *buf, unsigned max_buf) { char * p = buf; char * p_end = buf + max_buf - 2; int c; while ((c = getc(fp)) != EOF) { #ifdef SELF_TEST n_getc++; #endif if (c == '\n') break; if (p < p_end) *p++ = c; } *p = 0; if (c == EOF) { if (p > buf) return -2; /* malformed line */ return EOF; } #ifdef SELF_TEST n_line++; #endif return p - buf; } int ndmbstf_seek_and_align (FILE *fp, off_t *off) { int c; if (fseeko (fp, *off, SEEK_SET) == -1) { return -2; } #ifdef SELF_TEST n_seek++; #endif /* * There is a slim chance that we're at the * true begining of a line. Too slim. * Scan forward discarding the trailing * portion of the line we just fseek()ed * to, and leave the stdio stream positioned * for the subsequent line. Notice * we keep off upated so that it reflects * the seek position of the stdio stream. */ while ((c = getc(fp)) != EOF) { *off += 1; #ifdef SELF_TEST n_align++; #endif if (c == '\n') break; } if (c == EOF) { /* at end of file */ return EOF; } return 0; } /* * ndmbstf_compare() * * Given a key[] and a buf[], return whether or not they match. * This effectively is strncmp (key, buf, strlen(key)). * Because of the cost of the call to strlen(), we implement * it ndmbstf_compare() here with the exact semantics. * * Return values are: * <0 No match, key[] less than buf[] * =0 Match, the key[] is a prefix for buf[] * >0 No match, key[] greater than buf[] */ int ndmbstf_compare (char *key, char *buf) { char * p = key; char * q = buf; while (*p != 0 && *p == *q) { p++; q++; } if (*p == 0) return 0; /* entire key matched */ else return *p - *q; } /* * ndmbstf_match() * * A simple wrapper around ndmbstf_compare() with an * easy-to-use return value.. * * Returns: * !0 match * =0 no match */ int ndmbstf_match (char *key, char *buf) { return ndmbstf_compare (key, buf) == 0; } #ifdef SELF_TEST int main (int ac, char *av[]) { int i; FILE * fp; int verbose = 1; int total_n_match = 0; int total_n_no_match = 0; int total_n_error = 0; i = 1; if (i < ac && strcmp (av[i], "-q") == 0) { i++; verbose = 0; } if (ac < i+2) { printf ("usage: %s [-q] FILE KEY ...\n", av[0]); return 1; } fp = fopen (av[i], "r"); if (!fp) { perror (av[i]); return 2; } for (i++; i < ac; i++) { char buf[512]; char * key = av[i]; int n_match = 0; int rc; rc = ndmbstf_first (fp, key, buf, sizeof buf); if (rc < 0) { printf ("Key '%s' err=%d\n", key, rc); total_n_error++; continue; } if (rc == 0) { printf ("Key '%s' no matches\n", key); total_n_no_match++; continue; } if (verbose) printf ("Key '%s'\n", key); for (; rc > 0; rc = ndmbstf_next (fp, key, buf, sizeof buf)) { n_match++; if (verbose) printf (" %2d: '%s'\n", n_match, buf); } total_n_match += n_match; } fclose (fp); printf ("n_match=%d n_miss=%d n_error=%d\n", total_n_match, total_n_no_match, total_n_error); printf ("n_seek=%d n_align=%d n_line=%d\n", n_seek, n_align, n_line); return 0; } #endif /* SELF_TEST */ bareos-Release-14.2.6/src/ndmp/ndml_chan.c000066400000000000000000000320241263011562700202550ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" /* * Initialize a channel. Make sure it won't be confused for active. */ void ndmchan_initialize (struct ndmchan *ch, char *name) { NDMOS_MACRO_ZEROFILL (ch); ch->name = name ? name : "???"; ch->fd = -1; ch->mode = NDMCHAN_MODE_IDLE; } /* * Set the data buffer */ int ndmchan_setbuf (struct ndmchan *ch, char *data, unsigned data_size) { ch->data = data; ch->data_size = data_size; ch->beg_ix = 0; ch->end_ix = 0; return 0; } /* * Interfaces for starting a channel in various modes. */ int ndmchan_start_mode (struct ndmchan *ch, int fd, int chan_mode) { ch->fd = fd; ch->mode = chan_mode; return 0; } int ndmchan_start_read (struct ndmchan *ch, int fd) { return ndmchan_start_mode (ch, fd, NDMCHAN_MODE_READ); } int ndmchan_start_write (struct ndmchan *ch, int fd) { return ndmchan_start_mode (ch, fd, NDMCHAN_MODE_WRITE); } int ndmchan_start_readchk (struct ndmchan *ch, int fd) { return ndmchan_start_mode (ch, fd, NDMCHAN_MODE_READCHK); } int ndmchan_start_listen (struct ndmchan *ch, int fd) { return ndmchan_start_mode (ch, fd, NDMCHAN_MODE_LISTEN); } int ndmchan_start_resident (struct ndmchan *ch) { return ndmchan_start_mode (ch, -1, NDMCHAN_MODE_RESIDENT); } int ndmchan_start_pending (struct ndmchan *ch, int fd) { return ndmchan_start_mode (ch, fd, NDMCHAN_MODE_PENDING); } /* * Change a PENDING channel to an active (READ/WRITE) channel */ int ndmchan_pending_to_mode (struct ndmchan *ch, int chan_mode) { ch->mode = chan_mode; return 0; } int ndmchan_pending_to_read (struct ndmchan *ch) { return ndmchan_pending_to_mode (ch, NDMCHAN_MODE_READ); } int ndmchan_pending_to_write (struct ndmchan *ch) { return ndmchan_pending_to_mode (ch, NDMCHAN_MODE_WRITE); } /* * Interfaces for stopping (close()ing) a channel. * This is a bit of a hodge-podge. Could probably be cleaner. */ void ndmchan_set_eof (struct ndmchan *ch) { ch->eof = 1; } void ndmchan_close_set_errno (struct ndmchan *ch, int err_no) { ch->eof = 1; if (ch->fd >= 0) { close (ch->fd); ch->fd = -1; } ch->mode = NDMCHAN_MODE_CLOSED; ch->saved_errno = err_no; ch->beg_ix = ch->end_ix = 0; } void ndmchan_close (struct ndmchan *ch) { ndmchan_close_set_errno (ch, 0); } void ndmchan_abort (struct ndmchan *ch) { ndmchan_close_set_errno (ch, ch->saved_errno == 0 ? EINTR : ch->saved_errno); } void ndmchan_close_as_is (struct ndmchan *ch) { ndmchan_close_set_errno (ch, ch->saved_errno); } void ndmchan_cleanup (struct ndmchan *ch) { if (ch->mode != NDMCHAN_MODE_IDLE) { ndmchan_close_as_is (ch); } } /* * CPU Quantum for a set of channels. There are three * phases: * 1) Identify the channels to check for ready to do I/O. * For example, a READ channel with no buffer space * need not be checked. * 2) Call the OS dependent function that performs the * actual select()/poll()/whatever. * 3) Based on the results, perform actual read()/write(). * EOF and errors are detected. * * This is constructed so that applications which can not use * ndmchan_quantum() directly have access to the helper functions * ndmchan_pre_poll() and ndmchan_post_poll(). */ int ndmchan_quantum (struct ndmchan *chtab[], unsigned n_chtab, int milli_timo) { int rc; ndmchan_pre_poll (chtab, n_chtab); rc = ndmos_chan_poll (chtab, n_chtab, milli_timo); if (rc <= 0) return rc; rc = ndmchan_post_poll (chtab, n_chtab); return rc; } int ndmchan_pre_poll (struct ndmchan *chtab[], unsigned n_chtab) { struct ndmchan * ch; unsigned int i, n_check; n_check = 0; for (i = 0; i < n_chtab; i++) { ch = chtab[i]; ch->ready = 0; ch->check = 0; if (ch->error) continue; switch (ch->mode) { default: case NDMCHAN_MODE_IDLE: case NDMCHAN_MODE_PENDING: case NDMCHAN_MODE_RESIDENT: case NDMCHAN_MODE_CLOSED: continue; case NDMCHAN_MODE_LISTEN: case NDMCHAN_MODE_READCHK: break; case NDMCHAN_MODE_READ: if (ch->eof) continue; if (ndmchan_n_avail (ch) == 0) continue; break; case NDMCHAN_MODE_WRITE: if (ndmchan_n_ready (ch) == 0) continue; break; } ch->check = 1; n_check++; } return n_check; } int ndmchan_post_poll (struct ndmchan *chtab[], unsigned n_chtab) { struct ndmchan * ch; unsigned int i; int rc, len, n_ready; n_ready = 0; for (i = 0; i < n_chtab; i++) { ch = chtab[i]; if (!ch->ready) continue; switch (ch->mode) { case NDMCHAN_MODE_READ: len = ndmchan_n_avail (ch); if (len <= 0) continue; n_ready++; rc = read (ch->fd, &ch->data[ch->end_ix], len); if (rc < 0) { if (errno != NDMOS_CONST_EWOULDBLOCK) { ch->error = ch->eof = 1; ch->saved_errno = errno; if (!ch->saved_errno) ch->saved_errno = -1; } else { /* no bytes read */ } } else if (rc == 0) { ch->eof = 1; ch->error = 0; ch->saved_errno = 0; } else { ch->end_ix += rc; } break; case NDMCHAN_MODE_WRITE: len = ndmchan_n_ready (ch); if (len <= 0) continue; n_ready++; rc = write (ch->fd, &ch->data[ch->beg_ix], len); if (rc < 0) { if (errno != NDMOS_CONST_EWOULDBLOCK) { ch->eof = 1; ch->error = 1; ch->saved_errno = errno; if (!ch->saved_errno) ch->saved_errno = -1; } else { /* no bytes written */ /* EWOULDBLOCK but ready? */ } } else if (rc == 0) { /* NDMOS_CONST_EWOULDBLOCK? */ ch->eof = 1; ch->error = 1; ch->saved_errno = 0; } else { ch->beg_ix += rc; } break; } } return n_ready; } /* * Channel data buffer space manipulation. */ void ndmchan_compress (struct ndmchan *ch) { unsigned len = ch->end_ix - ch->beg_ix; if (ch->beg_ix > 0 && len > 0) { bcopy (&ch->data[ch->beg_ix], ch->data, len); } else { if (len > ch->data_size) len = 0; } ch->beg_ix = 0; ch->end_ix = len; } int ndmchan_n_avail (struct ndmchan *ch) { if (ch->end_ix == ch->beg_ix) ch->end_ix = ch->beg_ix = 0; if (ch->end_ix >= ch->data_size) { ndmchan_compress (ch); } return ch->data_size - ch->end_ix; } int ndmchan_n_avail_record (struct ndmchan *ch, uint32_t size) { if (ch->end_ix == ch->beg_ix) ch->end_ix = ch->beg_ix = 0; if (ch->end_ix >= ch->data_size - size) { ndmchan_compress (ch); } return ch->data_size - ch->end_ix; } int ndmchan_n_avail_total (struct ndmchan *ch) { if (ch->end_ix == ch->beg_ix) ch->end_ix = ch->beg_ix = 0; if (ch->end_ix >= ch->data_size) { ndmchan_compress (ch); } return ch->data_size - ch->end_ix + ch->beg_ix; } int ndmchan_n_ready (struct ndmchan *ch) { return ch->end_ix - ch->beg_ix; } /* * Interfaces for interpreting channel state, obtaining pointers, lengths */ enum ndmchan_read_interpretation ndmchan_read_interpret (struct ndmchan *ch, char **data_p, unsigned *n_ready_p) { unsigned n_ready; n_ready = *n_ready_p = ndmchan_n_ready (ch); *data_p = &ch->data[ch->beg_ix]; if (ch->error) { if (n_ready == 0) { return NDMCHAN_RI_DONE_ERROR; } else { return NDMCHAN_RI_DRAIN_ERROR; } } if (ch->eof) { if (n_ready == 0) { return NDMCHAN_RI_DONE_EOF; } else { return NDMCHAN_RI_DRAIN_EOF; } } if (n_ready == 0) { return NDMCHAN_RI_EMPTY; } if (n_ready == ch->data_size) { return NDMCHAN_RI_READY_FULL; } return NDMCHAN_RI_READY; } enum ndmchan_write_interpretation ndmchan_write_interpret (struct ndmchan *ch, char **data_p, unsigned *n_avail_p) { unsigned n_avail; n_avail = *n_avail_p = ndmchan_n_avail (ch); *data_p = &ch->data[ch->end_ix]; if (ch->error) { /* We don't use WI_DRAIN_ERROR. If it's kaput, it's kaput */ return NDMCHAN_WI_DONE_ERROR; } if (ch->eof) { if (n_avail == ch->data_size) { return NDMCHAN_WI_DONE_EOF; } else { return NDMCHAN_WI_DRAIN_EOF; } } if (n_avail == 0) { return NDMCHAN_WI_FULL; } if (n_avail == ch->data_size) { return NDMCHAN_WI_AVAIL_EMPTY; } return NDMCHAN_WI_AVAIL; } /* * Pretty printer */ void ndmchan_pp (struct ndmchan *ch, char *buf) { int show_ra = 0; char * bp = buf; char * p; sprintf (bp, "name=%s", ch->name); while (*bp) bp++; switch (ch->mode) { case NDMCHAN_MODE_IDLE: p = "idle"; break; case NDMCHAN_MODE_RESIDENT: p = "resident"; show_ra = 1; break; case NDMCHAN_MODE_READ: p = "read"; show_ra = 1; break; case NDMCHAN_MODE_WRITE: p = "write"; show_ra = 1; break; case NDMCHAN_MODE_READCHK: p = "readchk"; break; case NDMCHAN_MODE_LISTEN: p = "listen"; break; case NDMCHAN_MODE_PENDING: p = "pending"; break; case NDMCHAN_MODE_CLOSED: p = "closed"; break; default: p = "mode=???"; break; } sprintf (bp, " %s ", p); while (*bp) bp++; if (show_ra) { sprintf (bp, "ready=%d avail=%d ", ndmchan_n_ready(ch), ndmchan_n_avail(ch)); while (*bp) bp++; } if (ch->ready) strcat (bp, "-rdy"); if (ch->check) strcat (bp, "-chk"); if (ch->eof) strcat (bp, "-eof"); if (ch->error) strcat (bp, "-err"); } #ifdef NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL /* * Here because it is almost always used */ int ndmos_chan_poll (struct ndmchan *chtab[], unsigned n_chtab, int milli_timo) { struct ndmchan * ch; fd_set rfds, wfds; int nfd = 0, rc; unsigned i; struct timeval timo; FD_ZERO(&rfds); FD_ZERO(&wfds); timo.tv_sec = milli_timo / 1000; timo.tv_usec = (milli_timo % 1000) * 1000; for (i = 0; i < n_chtab; i++) { ch = chtab[i]; if (!ch->check) continue; switch (ch->mode) { case NDMCHAN_MODE_LISTEN: case NDMCHAN_MODE_READCHK: case NDMCHAN_MODE_READ: FD_SET (ch->fd, &rfds); break; case NDMCHAN_MODE_WRITE: FD_SET (ch->fd, &wfds); break; } if (nfd < ch->fd+1) nfd = ch->fd+1; } rc = select (nfd, &rfds, &wfds, (void*)0, &timo); if (rc <= 0) return rc; for (i = 0; i < n_chtab; i++) { ch = chtab[i]; if (!ch->check) continue; switch (ch->mode) { case NDMCHAN_MODE_LISTEN: case NDMCHAN_MODE_READCHK: case NDMCHAN_MODE_READ: if (FD_ISSET (ch->fd, &rfds)) ch->ready = 1; break; case NDMCHAN_MODE_WRITE: if (FD_ISSET (ch->fd, &wfds)) ch->ready = 1; break; } } return rc; } #endif /* NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL */ #ifdef NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL /* * Here because it is common, and because poll(2) is * INFINITELY SUPERIOR to select(2). */ #ifdef HAVE_POLL_H #include #elif HAVE_SYS_POLL_H #include #endif int ndmos_chan_poll (struct ndmchan *chtab[], unsigned n_chtab, int milli_timo) { struct ndmchan * ch; struct pollfd * pfdtab; int n_pfdtab; int rc, i; /* * See how many filedescriptors we need to check. */ n_pfdtab = 0; for (i = 0; i < n_chtab; i++) { if (!chtab[i]->check) continue; n_pfdtab++; } pfdtab = (struct pollfd *) NDMOS_API_MALLOC (sizeof(struct pollfd) * n_pfdtab); if (!pfdtab) return -1; NDMOS_API_BZERO (pfdtab, sizeof(struct pollfd) * n_pfdtab); n_pfdtab = 0; for (i = 0; i < n_chtab; i++) { ch = chtab[i]; if (!ch->check) continue; switch (ch->mode) { case NDMCHAN_MODE_LISTEN: case NDMCHAN_MODE_READCHK: case NDMCHAN_MODE_READ: pfdtab[n_pfdtab].fd = ch->fd; pfdtab[n_pfdtab].events = POLLIN; break; case NDMCHAN_MODE_WRITE: pfdtab[n_pfdtab].fd = ch->fd; pfdtab[n_pfdtab].events = POLLOUT; break; } n_pfdtab++; } rc = poll (pfdtab, n_pfdtab, milli_timo); if (rc <= 0) { NDMOS_API_FREE (pfdtab); return rc; } n_pfdtab = 0; for (i = 0; i < n_chtab; i++) { ch = chtab[i]; if (!ch->check) continue; switch (ch->mode) { case NDMCHAN_MODE_LISTEN: case NDMCHAN_MODE_READCHK: case NDMCHAN_MODE_READ: if (pfdtab[n_pfdtab].revents & POLLIN) ch->ready = 1; break; case NDMCHAN_MODE_WRITE: if (pfdtab[n_pfdtab].revents & POLLOUT) ch->ready = 1; break; } n_pfdtab++; } NDMOS_API_FREE (pfdtab); return rc; } #endif /* NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL */ bareos-Release-14.2.6/src/ndmp/ndml_config.c000066400000000000000000000336141263011562700206170ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" #define CFG_BUF_SIZE 512 #define CFG_MAX_SV 32 /* control block */ struct cfg_cb { FILE * fp; ndmp9_config_info * config_info; char buf[CFG_BUF_SIZE]; char * sv[CFG_MAX_SV]; int sc; int n_error; }; static int cfg_butype (struct cfg_cb *cb); static int cfg_fs (struct cfg_cb *cb); static int cfg_tape (struct cfg_cb *cb); static int cfg_scsi (struct cfg_cb *cb); static int cfg_device (struct cfg_cb *cb, u_int *n_device, ndmp9_device_info **pp); static int cfg_add_env (struct cfg_cb *cb, u_int *n_env, ndmp9_pval **pp, char *name, char *value); int ndmcfg_load (char *filename, ndmp9_config_info *config_info) { FILE * fp; int rc; fp = fopen (filename, "r"); if (!fp) return -1; rc = ndmcfg_loadfp (fp, config_info); fclose (fp); return rc; } int ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info) { struct cfg_cb _cb, *cb = &_cb; int rc; NDMOS_MACRO_ZEROFILL (cb); cb->fp = fp; cb->config_info = config_info; for (;;) { rc = ndmstz_getstanza (cb->fp, cb->buf, sizeof cb->buf); if (rc == EOF) { break; } cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV); if (cb->sc < 1) { continue; } if (strcmp (cb->sv[0], "butype") == 0 && cb->sc == 2) { cfg_butype (cb); continue; } if (strcmp (cb->sv[0], "fs") == 0 && cb->sc == 2) { cfg_fs (cb); continue; } if (strcmp (cb->sv[0], "tape") == 0 && cb->sc == 2) { cfg_tape (cb); continue; } if (strcmp (cb->sv[0], "scsi") == 0 && cb->sc == 2) { cfg_scsi (cb); continue; } /* * Unrecognized stanzas are deemed for other purposes * and tolerated. */ } return cb->n_error; } /* * [butype BUTYPE] * v2attr 0xATTR * v3attr 0xATTR * v4attr 0xATTR * default_env NAME VALUE */ static int cfg_butype (struct cfg_cb *cb) { ndmp9_config_info * cfg = cb->config_info; ndmp9_butype_info * ent = cfg->butype_info.butype_info_val; int n_ent = cfg->butype_info.butype_info_len; int i, rc; if (!ent) n_ent = 0; ent = NDMOS_MACRO_NEWN(ndmp9_butype_info, n_ent+1); if (!ent) { cb->n_error++; return -1; } for (i = 0; i < n_ent; i++) { ent[i] = cfg->butype_info.butype_info_val[i]; } if (cfg->butype_info.butype_info_val) { NDMOS_API_FREE (cfg->butype_info.butype_info_val); } cfg->butype_info.butype_info_val = ent; cfg->butype_info.butype_info_len = n_ent+1; ent += n_ent; NDMOS_MACRO_ZEROFILL (ent); ent->butype_name = NDMOS_API_STRDUP (cb->sv[1]); for (;;) { rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE); if (rc < 0) break; cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV); if (cb->sc < 1) { continue; } if (strcmp (cb->sv[0], "v2attr") == 0 && cb->sc == 2) { ent->v2attr.valid = NDMP9_VALIDITY_VALID; ent->v2attr.value = strtol (cb->sv[1], 0, 0); continue; } if (strcmp (cb->sv[0], "v3attr") == 0 && cb->sc == 2) { ent->v3attr.valid = NDMP9_VALIDITY_VALID; ent->v3attr.value = strtol (cb->sv[1], 0, 0); continue; } if (strcmp (cb->sv[0], "v4attr") == 0 && cb->sc == 2) { ent->v4attr.valid = NDMP9_VALIDITY_VALID; ent->v4attr.value = strtol (cb->sv[1], 0, 0); continue; } if (strcmp (cb->sv[0], "default_env") == 0 && cb->sc == 3) { cfg_add_env (cb, &ent->default_env.default_env_len, &ent->default_env.default_env_val, cb->sv[1], cb->sv[2]); continue; } /* * Unrecognized lines are deemed version differences * and tolerated. */ } return 0; } /* * [fs MOUNTPOINT] * fs_type TYPE * fs_physical_device DEVICEPATH * fs_status "COMMENT" * fs_env NAME VALUE */ static int cfg_fs (struct cfg_cb *cb) { ndmp9_config_info * cfg = cb->config_info; ndmp9_fs_info * ent = cfg->fs_info.fs_info_val; int n_ent = cfg->fs_info.fs_info_len; int i, rc; if (!ent) n_ent = 0; ent = NDMOS_MACRO_NEWN(ndmp9_fs_info, n_ent+1); if (!ent) { cb->n_error++; return -1; } for (i = 0; i < n_ent; i++) { ent[i] = cfg->fs_info.fs_info_val[i]; } if (cfg->fs_info.fs_info_val) { NDMOS_API_FREE (cfg->fs_info.fs_info_val); } cfg->fs_info.fs_info_val = ent; cfg->fs_info.fs_info_len = n_ent+1; ent += n_ent; NDMOS_MACRO_ZEROFILL (ent); ent->fs_logical_device = NDMOS_API_STRDUP (cb->sv[1]); for (;;) { rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE); if (rc < 0) break; cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV); if (cb->sc < 1) { continue; } if (strcmp (cb->sv[0], "fs_type") == 0 && cb->sc == 2) { ent->fs_type = NDMOS_API_STRDUP (cb->sv[1]); continue; } if (strcmp (cb->sv[0], "fs_physical_device") == 0 && cb->sc == 2) { ent->fs_physical_device = NDMOS_API_STRDUP (cb->sv[1]); continue; } if (strcmp (cb->sv[0], "fs_status") == 0 && cb->sc == 2) { ent->fs_status = NDMOS_API_STRDUP (cb->sv[1]); continue; } if (strcmp (cb->sv[0], "fs_env") == 0 && cb->sc == 3) { cfg_add_env (cb, &ent->fs_env.fs_env_len, &ent->fs_env.fs_env_val, cb->sv[1], cb->sv[2]); continue; } /* * Unrecognized lines are deemed version differences * and tolerated. */ } return 0; } static int cfg_tape (struct cfg_cb *cb) { ndmp9_config_info * cfg = cb->config_info; return cfg_device (cb, &cfg->tape_info.tape_info_len, &cfg->tape_info.tape_info_val); } static int cfg_scsi (struct cfg_cb *cb) { ndmp9_config_info * cfg = cb->config_info; return cfg_device (cb, &cfg->scsi_info.scsi_info_len, &cfg->scsi_info.scsi_info_val); } /* * [tape IDENT] or [scsi IDENT] * device DEVICEPATH * v3attr 0xATTR * v4attr 0xATTR * capability NAME VALUE */ static int cfg_device (struct cfg_cb *cb, u_int *n_device, ndmp9_device_info **pp) { ndmp9_device_info * ent = *pp; ndmp9_device_capability *dcap; int rc; unsigned int i, n_ent = *n_device; if (!ent) n_ent = 0; for (i = 0; i < n_ent; i++) { if (strcmp(ent[i].model, (*pp)[i].model) == 0) { ent += i; goto got_model; } } ent = NDMOS_MACRO_NEWN(ndmp9_device_info, n_ent+1); if (!ent) { cb->n_error++; return -1; } for (i = 0; i < n_ent; i++) { ent[i] = (*pp)[i]; } if (*pp) { NDMOS_API_FREE (*pp); } *pp = ent; *n_device = n_ent+1; ent += n_ent; NDMOS_MACRO_ZEROFILL (ent); ent->model = NDMOS_API_STRDUP (cb->sv[1]); got_model: dcap = NDMOS_MACRO_NEWN (ndmp9_device_capability, ent->caplist.caplist_len+1); if (!dcap) { cb->n_error++; return -1; } for (i = 0; i < ent->caplist.caplist_len; i++) { dcap[i] = ent->caplist.caplist_val[i]; } if (ent->caplist.caplist_val) { NDMOS_API_FREE (ent->caplist.caplist_val); } ent->caplist.caplist_val = dcap; dcap += ent->caplist.caplist_len++; NDMOS_MACRO_ZEROFILL (dcap); for (;;) { rc = ndmstz_getline (cb->fp, cb->buf, CFG_BUF_SIZE); if (rc < 0) break; cb->sc = ndmstz_parse (cb->buf, cb->sv, CFG_MAX_SV); if (cb->sc < 1) { continue; } if (strcmp (cb->sv[0], "device") == 0 && cb->sc == 2) { dcap->device = NDMOS_API_STRDUP (cb->sv[1]); continue; } if (strcmp (cb->sv[0], "v3attr") == 0 && cb->sc == 2) { dcap->v3attr.valid = NDMP9_VALIDITY_VALID; dcap->v3attr.value = strtol (cb->sv[1], 0, 0); continue; } if (strcmp (cb->sv[0], "v4attr") == 0 && cb->sc == 2) { dcap->v4attr.valid = NDMP9_VALIDITY_VALID; dcap->v4attr.value = strtol (cb->sv[1], 0, 0); continue; } if (strcmp (cb->sv[0], "capability") == 0 && cb->sc == 3) { cfg_add_env (cb, &dcap->capability.capability_len, &dcap->capability.capability_val, cb->sv[1], cb->sv[2]); continue; } /* * Unrecognized lines are deemed version differences * and tolerated. */ } return 0; } static int cfg_add_env (struct cfg_cb *cb, u_int *n_env, ndmp9_pval **pp, char *name, char *value) { ndmp9_pval * ent = *pp; int n_ent = *n_env; int i; if (!ent) n_ent = 0; ent = NDMOS_MACRO_NEWN(ndmp9_pval, n_ent+1); if (!ent) { cb->n_error++; return -1; } for (i = 0; i < n_ent; i++) { ent[i] = (*pp)[i]; } if (*pp) { NDMOS_API_FREE (*pp); } *pp = ent; *n_env = n_ent+1; ent += n_ent; NDMOS_MACRO_ZEROFILL (ent); ent->name = NDMOS_API_STRDUP (name); ent->value = NDMOS_API_STRDUP (value); return 0; } #ifdef SELF_TEST int main (int argc, char *argv[]) { ndmp9_config_info config_info; int rc, i, j, k; if (argc != 2) { printf ("usage: %s FILE\n", argv[0]); return 1; } NDMOS_MACRO_ZEROFILL (&config_info); rc = ndmcfg_load (argv[1], &config_info); printf ("%d errors\n", rc); for (i = 0; i < config_info.butype_info.butype_info_len; i++) { ndmp9_butype_info * bu; bu = &config_info.butype_info.butype_info_val[i]; printf ("butype[%d] name='%s'\n", i, bu->butype_name); if (bu->v2attr.valid) { printf (" v2attr 0x%x\n", bu->v2attr.value); } else { printf (" v2attr -invalid-\n"); } if (bu->v3attr.valid) { printf (" v3attr 0x%x\n", bu->v3attr.value); } else { printf (" v3attr -invalid-\n"); } if (bu->v4attr.valid) { printf (" v4attr 0x%x\n", bu->v4attr.value); } else { printf (" v4attr -invalid-\n"); } for (j = 0; j < bu->default_env.default_env_len; j++) { ndmp9_pval * env; env = &bu->default_env.default_env_val[j]; printf (" default_env[%d] '%s'='%s'\n", j, env->name, env->value); } } for (i = 0; i < config_info.fs_info.fs_info_len; i++) { ndmp9_fs_info * fs; fs = &config_info.fs_info.fs_info_val[i]; printf ("fs[%d] fs_logical_device='%s'\n", i, fs->fs_logical_device); if (fs->fs_physical_device) { printf (" fs_physical_device '%s'\n", fs->fs_physical_device); } else { printf (" fs_physical_device -null-\n"); } if (fs->fs_type) { printf (" fs_type '%s'\n", fs->fs_type); } else { printf (" fs_type -null-\n"); } if (fs->fs_status) { printf (" fs_status '%s'\n", fs->fs_status); } else { printf (" fs_status -null-\n"); } if (fs->total_size.valid) { printf (" total_size %llu\n", fs->total_size.value); } else { printf (" total_size -invalid-\n"); } if (fs->used_size.valid) { printf (" used_size %llu\n", fs->used_size.value); } else { printf (" used_size -invalid-\n"); } if (fs->avail_size.valid) { printf (" avail_size %llu\n", fs->avail_size.value); } else { printf (" avail_size -invalid-\n"); } if (fs->total_inodes.valid) { printf (" total_inodes %llu\n", fs->total_inodes.value); } else { printf (" total_inodes -invalid-\n"); } if (fs->used_inodes.valid) { printf (" used_inodes %llu\n", fs->used_inodes.value); } else { printf (" used_inodes -invalid-\n"); } for (j = 0; j < fs->fs_env.fs_env_len; j++) { ndmp9_pval * env; env = &fs->fs_env.fs_env_val[j]; printf (" fs_env[%d] '%s'='%s'\n", j, env->name, env->value); } } for (i = 0; i < config_info.tape_info.tape_info_len; i++) { ndmp9_device_info * dev; dev = &config_info.tape_info.tape_info_val[i]; printf ("tape[%d] model='%s'\n", i, dev->model); for (j = 0; j < dev->caplist.caplist_len; j++) { struct ndmp9_device_capability *dcap; dcap = &dev->caplist.caplist_val[j]; printf (" capability %d\n", j); if (dcap->device) { printf (" device '%s'\n", dcap->device); } else { printf (" device -null-\n"); } if (dcap->v3attr.valid) { printf (" v3attr 0x%x\n", dcap->v3attr.value); } else { printf (" v3attr -invalid-\n"); } if (dcap->v4attr.valid) { printf (" v4attr 0x%x\n", dcap->v4attr.value); } else { printf (" v4attr -invalid-\n"); } k = 0; for (; k < dcap->capability.capability_len; k++) { ndmp9_pval *env; env = &dcap->capability.capability_val[k]; printf (" capability[%d] '%s'='%s'\n", k, env->name, env->value); } } } for (i = 0; i < config_info.scsi_info.scsi_info_len; i++) { ndmp9_device_info * dev; dev = &config_info.scsi_info.scsi_info_val[i]; printf ("scsi[%d] model='%s'\n", i, dev->model); for (j = 0; j < dev->caplist.caplist_len; j++) { struct ndmp9_device_capability *dcap; dcap = &dev->caplist.caplist_val[j]; printf (" capability %d\n", j); if (dcap->device) { printf (" device '%s'\n", dcap->device); } else { printf (" device -null-\n"); } if (dcap->v3attr.valid) { printf (" v3attr 0x%x\n", dcap->v3attr.value); } else { printf (" v3attr -invalid-\n"); } if (dcap->v4attr.valid) { printf (" v4attr 0x%x\n", dcap->v4attr.value); } else { printf (" v4attr -invalid-\n"); } k = 0; for (; k < dcap->capability.capability_len; k++) { ndmp9_pval *env; env = &dcap->capability.capability_val[k]; printf (" capability[%d] '%s'='%s'\n", k, env->name, env->value); } } } return 0; } #endif /* SELF_TEST */ bareos-Release-14.2.6/src/ndmp/ndml_conn.c000066400000000000000000000607451263011562700203140ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" #ifndef NDMOS_OPTION_NO_NDMP4 #define MAX_PROTOCOL_VERSION NDMP4VER #else /* !NDMOS_OPTION_NO_NDMP4 */ #ifndef NDMOS_OPTION_NO_NDMP3 #define MAX_PROTOCOL_VERSION NDMP3VER #else /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP2 #define MAX_PROTOCOL_VERSION NDMP2VER #else /* !NDMOS_OPTION_NO_NDMP2 */ #define MAX_PROTOCOL_VERSION 0 #endif /* !NDMOS_OPTION_NO_NDM2 */ #endif /* !NDMOS_OPTION_NO_NDMP3 */ #endif /* !NDMOS_OPTION_NO_NDMP4 */ /* * INITIALIZE AND DESTRUCT **************************************************************** * * Initialize an ndmconn. This pretty much amounts to * initializing the underlying ndmchan and stuffing * the function pointers. */ struct ndmconn * ndmconn_initialize (struct ndmconn *aconn, char *name) { struct ndmconn * conn = aconn; if (!conn) { conn = NDMOS_MACRO_NEW(struct ndmconn); if (!conn) return 0; } NDMOS_MACRO_ZEROFILL (conn); if (!name) name = "#?"; /* default */ ndmchan_initialize (&conn->chan, name); conn->was_allocated = aconn == 0; conn->next_sequence = 1; xdrrec_create (&conn->xdrs, 0, 0, (void*) conn, (void*)ndmconn_readit, (void*)ndmconn_writeit); conn->unexpected = ndmconn_unexpected; conn->call = ndmconn_call; conn->time_limit = 0; return conn; } /* * Get rid of an ndmconn. */ void ndmconn_destruct (struct ndmconn *conn) { if (conn->chan.fd >= 0) { close (conn->chan.fd); conn->chan.fd = -1; } if (conn->xdrs.x_ops) { xdr_destroy (&conn->xdrs); conn->xdrs.x_ops = NULL; } if (conn->was_allocated) { NDMOS_API_FREE (conn); conn = 0; } } /* * ESTABLISH CONNECTION **************************************************************** * * The following four routines establish the TCP/IP connection * between agents. * * ndmconn_connect_agent() * make a connection per an ndmagent, uses ..._host_port() * ndmconn_connect_host_port () * make a connection per a hostname and port, uses ..._sockaddr_in() * ndmconn_connect_sockaddr_in() * make a connection per sockaddr_in, performs NDMP_CONNECT_ * sequences, but no authentication * ndmconn_accept() * make a connection (receive it really) from a file descriptor * already accept()ed. */ int ndmconn_connect_agent (struct ndmconn *conn, struct ndmagent *agent) { if (agent->conn_type == NDMCONN_TYPE_RESIDENT) { conn->conn_type = NDMCONN_TYPE_RESIDENT; conn->protocol_version = agent->protocol_version; if (conn->protocol_version == 0) { /* Let's negotiate......MAX */ conn->protocol_version = MAX_PROTOCOL_VERSION; } ndmchan_start_resident (&conn->chan); return 0; } if (agent->port == 0) agent->port = NDMPPORT; return ndmconn_connect_host_port (conn, agent->host, agent->port, agent->protocol_version); } int ndmconn_connect_host_port (struct ndmconn *conn, char * hostname, int port, unsigned want_protocol_version) { struct sockaddr_in sin; char * err = "???"; if (conn->chan.fd >= 0) { err = "already-connected"; return ndmconn_set_err_msg (conn, err); } if (ndmhost_lookup (hostname, &sin) != 0) { err = "bad-host-name"; return ndmconn_set_err_msg (conn, err); } if (port == 0) port = NDMPPORT; sin.sin_port = htons(port); return ndmconn_connect_sockaddr_in (conn, &sin, want_protocol_version); } int ndmconn_connect_sockaddr_in (struct ndmconn *conn, struct sockaddr_in *sin, unsigned want_protocol_version) { int fd = -1; int rc; char * err = "???"; unsigned max_protocol_version = MAX_PROTOCOL_VERSION; if (conn->chan.fd >= 0) { err = "already-connected"; return ndmconn_set_err_msg (conn, err); } fd = socket (AF_INET, SOCK_STREAM, 0); if (fd < 0) { err = NDMOS_API_MALLOC (1024); if (err) snprintf(err, 1023, "open a socket failed: %s", strerror(errno)); goto error_out; } /* reserved port? */ if (connect (fd, (struct sockaddr *)sin, sizeof *sin) < 0) { err = NDMOS_API_MALLOC (1024); if (err) snprintf(err, 1023, "connect failed: %s", strerror(errno)); goto error_out; } ndmchan_start_readchk (&conn->chan, fd); conn->conn_type = NDMCONN_TYPE_REMOTE; /* * Await the NDMP_NOTIFY_CONNECTED request (no reply) * Don't get confused that this client-side is awaiting * a "request" from the server. */ NDMC_WITH_NO_REPLY(ndmp0_notify_connected,0) rc = ndmconn_recv_nmb(conn, &xa->request); if (rc != 0) { err = "recv-notify-connected"; goto error_out; } if (xa->request.header.message_type != NDMP0_MESSAGE_REQUEST || xa->request.header.message != NDMP0_NOTIFY_CONNECTED) { err = "msg-not-notify-connected"; goto error_out; } if (request->reason != NDMP0_CONNECTED) { err = "notify-connected-not-connected"; goto error_out; } if (max_protocol_version > request->protocol_version) { max_protocol_version = request->protocol_version; } NDMC_ENDWITH if (want_protocol_version == 0) { want_protocol_version = max_protocol_version; } else if (want_protocol_version > max_protocol_version) { err = "connect-want/max-version-mismatch"; goto error_out; } /* * Send the OPEN request */ NDMC_WITH(ndmp0_connect_open,0) request->protocol_version = want_protocol_version; rc = NDMC_CALL(conn); if (rc) { err = "connect-open-failed"; goto error_out; } NDMC_ENDWITH /* GOOD! */ conn->protocol_version = want_protocol_version; return 0; error_out: if (fd >= 0) { close (fd); fd = -1; } conn->chan.fd = -1; conn->chan.mode = NDMCHAN_MODE_IDLE; conn->conn_type = NDMCONN_TYPE_NONE; return ndmconn_set_err_msg (conn, err); } int ndmconn_try_open (struct ndmconn *conn, unsigned protocol_version) { int rc; /* * Send the OPEN request */ NDMC_WITH(ndmp0_connect_open,0) request->protocol_version = protocol_version; rc = NDMC_CALL(conn); if (rc) { ndmconn_set_err_msg (conn, "connect-open-failed"); } NDMC_ENDWITH return rc; } int ndmconn_accept (struct ndmconn *conn, int sock) { char * err = "???"; if (conn->chan.fd >= 0) { err = "already-connected"; return ndmconn_set_err_msg (conn, err); } ndmchan_start_readchk (&conn->chan, sock); conn->conn_type = NDMCONN_TYPE_REMOTE; /* * Send the NDMP_NOTIFY_CONNECTED message, no reply * The connect()er is waiting for it. */ NDMC_WITH_NO_REPLY(ndmp0_notify_connected,0) request->reason = NDMP0_CONNECTED; request->protocol_version = MAX_PROTOCOL_VERSION; request->text_reason = "Hello"; NDMC_SEND(conn); NDMC_ENDWITH /* assume connection is running in offered protocol_version */ conn->protocol_version = MAX_PROTOCOL_VERSION; return 0; } /* * TERMINATE CONNECTION **************************************************************** * * These two routines are about terminating a connection. * They are incomplete. */ /* hangup */ int ndmconn_abort (struct ndmconn *conn) { return 0; } /* orderly close */ int ndmconn_close (struct ndmconn *conn) { return 0; } /* * Return the underlying fd of the ndmconn. * This is no longer used since the ndmchan stuff was done. */ int ndmconn_fileno (struct ndmconn *conn) { return conn->chan.fd; } /* * AUTHENTICATION * * The following three routines do the NDMP_CONNECT_AUTH sequences. */ int ndmconn_auth_agent (struct ndmconn *conn, struct ndmagent *agent) { int rc; if (conn->conn_type == NDMCONN_TYPE_RESIDENT) return 0; switch (agent->auth_type) { case 'n': /* NDMP_AUTH_NONE */ rc = ndmconn_auth_none (conn); break; case 't': /* NDMP_AUTH_TEXT */ rc = ndmconn_auth_text (conn, agent->account, agent->password); break; case 'm': /* NDMP_AUTH_MD5 */ rc = ndmconn_auth_md5 (conn, agent->account, agent->password); break; case 'v': /* void (don't auth) */ rc = 0; break; default: ndmconn_set_err_msg (conn, "connect-auth-unknown"); rc = -1; break; } return rc; } int ndmconn_auth_none (struct ndmconn *conn) { int rc; switch (conn->protocol_version) { default: ndmconn_set_err_msg (conn, "connect-auth-none-vers-botch"); return -1; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_connect_client_auth, NDMP2VER) request->auth_data.auth_type = NDMP2_AUTH_NONE; rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_connect_client_auth, NDMP3VER) request->auth_data.auth_type = NDMP3_AUTH_NONE; rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_connect_client_auth, NDMP4VER) request->auth_data.auth_type = NDMP4_AUTH_NONE; rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } if (rc) { ndmconn_set_err_msg (conn, "connect-auth-none-failed"); return -1; } return 0; } int ndmconn_auth_text (struct ndmconn *conn, char *id, char *pw) { int rc; switch (conn->protocol_version) { default: ndmconn_set_err_msg (conn, "connect-auth-text-vers-botch"); return -1; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_connect_client_auth, NDMP2VER) struct ndmp2_auth_text *at; request->auth_data.auth_type = NDMP2_AUTH_TEXT; at = &request->auth_data.ndmp2_auth_data_u.auth_text; at->auth_id = id; at->auth_password = pw; rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_connect_client_auth, NDMP3VER) struct ndmp3_auth_text *at; request->auth_data.auth_type = NDMP3_AUTH_TEXT; at = &request->auth_data.ndmp3_auth_data_u.auth_text; at->auth_id = id; at->auth_password = pw; rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_connect_client_auth, NDMP4VER) struct ndmp4_auth_text *at; request->auth_data.auth_type = NDMP4_AUTH_TEXT; at = &request->auth_data.ndmp4_auth_data_u.auth_text; at->auth_id = id; at->auth_password = pw; rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } if (rc) { ndmconn_set_err_msg (conn, "connect-auth-text-failed"); return -1; } return 0; } int ndmconn_auth_md5 (struct ndmconn *conn, char *id, char *pw) { int rc; char challenge[NDMP_MD5_CHALLENGE_LENGTH]; char digest[NDMP_MD5_DIGEST_LENGTH]; switch (conn->protocol_version) { default: ndmconn_set_err_msg (conn, "connect-auth-md5-vers-botch"); return -1; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_config_get_auth_attr, NDMP2VER) request->auth_type = NDMP2_AUTH_MD5; rc = NDMC_CALL(conn); if (rc == 0) { if (reply->server_attr.auth_type != NDMP2_AUTH_MD5) { ndmconn_set_err_msg (conn, "connect-auth-md5-attr-type-botch"); return -1; } NDMOS_API_BCOPY ( reply->server_attr.ndmp2_auth_attr_u.challenge, challenge, sizeof challenge); } NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_config_get_auth_attr, NDMP3VER) request->auth_type = NDMP3_AUTH_MD5; rc = NDMC_CALL(conn); if (rc == 0) { if (reply->server_attr.auth_type != NDMP3_AUTH_MD5) { ndmconn_set_err_msg (conn, "connect-auth-md5-attr-type-botch"); return -1; } NDMOS_API_BCOPY ( reply->server_attr.ndmp3_auth_attr_u.challenge, challenge, sizeof challenge); } NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_config_get_auth_attr, NDMP4VER) request->auth_type = NDMP4_AUTH_MD5; rc = NDMC_CALL(conn); if (rc == 0) { if (reply->server_attr.auth_type != NDMP4_AUTH_MD5) { ndmconn_set_err_msg (conn, "connect-auth-md5-attr-type-botch"); return -1; } NDMOS_API_BCOPY ( reply->server_attr.ndmp4_auth_attr_u.challenge, challenge, sizeof challenge); } NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } if (rc) { ndmconn_set_err_msg (conn, "connect-auth-md5-attr-failed"); return -1; } ndmmd5_digest (challenge, pw, digest); switch (conn->protocol_version) { default: ndmconn_set_err_msg (conn, "connect-auth-text-vers-botch"); return -1; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: NDMC_WITH(ndmp2_connect_client_auth, NDMP2VER) struct ndmp2_auth_md5 *am; request->auth_data.auth_type = NDMP2_AUTH_MD5; am = &request->auth_data.ndmp2_auth_data_u.auth_md5; am->auth_id = id; NDMOS_API_BCOPY (digest, am->auth_digest, sizeof digest); rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: NDMC_WITH(ndmp3_connect_client_auth, NDMP3VER) struct ndmp3_auth_md5 *am; request->auth_data.auth_type = NDMP3_AUTH_MD5; am = &request->auth_data.ndmp3_auth_data_u.auth_md5; am->auth_id = id; NDMOS_API_BCOPY (digest, am->auth_digest, sizeof digest); rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: NDMC_WITH(ndmp4_connect_client_auth, NDMP4VER) struct ndmp4_auth_md5 *am; request->auth_data.auth_type = NDMP4_AUTH_MD5; am = &request->auth_data.ndmp4_auth_data_u.auth_md5; am->auth_id = id; NDMOS_API_BCOPY (digest, am->auth_digest, sizeof digest); rc = NDMC_CALL(conn); NDMC_ENDWITH break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } if (rc) { ndmconn_set_err_msg (conn, "connect-auth-md5-failed"); return -1; } return 0; } /* * CALL (REQUEST/REPLY), SEND, and RECEIVE **************************************************************** */ int ndmconn_call (struct ndmconn *conn, struct ndmp_xa_buf *xa) { unsigned protocol_version = conn->protocol_version; unsigned msg = xa->request.header.message; int rc; struct ndmp_xdr_message_table * xmte; conn->last_message = msg; conn->last_call_status = NDMCONN_CALL_STATUS_BOTCH; conn->last_header_error = -1; /* invalid */ conn->last_reply_error = -1; /* invalid */ if (protocol_version != xa->request.protocol_version) { ndmconn_set_err_msg (conn, "protocol-version-mismatch"); return NDMCONN_CALL_STATUS_BOTCH; } xmte = ndmp_xmt_lookup (protocol_version, msg); if (!xmte) { ndmconn_set_err_msg (conn, "no-xdr-found"); return NDMCONN_CALL_STATUS_BOTCH; } xa->request.header.message_type = NDMP0_MESSAGE_REQUEST; if (!xmte->xdr_reply) { /* no reply expected, just a send (eg NOTIFY) */ return ndmconn_send_nmb (conn, &xa->request); } rc = ndmconn_exchange_nmb (conn, &xa->request, &xa->reply); if (rc) { ndmconn_set_err_msg (conn, "exchange-failed"); return NDMCONN_CALL_STATUS_BOTCH; } if (xa->reply.header.message != msg) { ndmconn_set_err_msg (conn, "msg-mismatch"); return NDMCONN_CALL_STATUS_BOTCH; } /* TODO: this should be converted ndmp_xto9_error(....) */ conn->last_header_error = xa->reply.header.error; if (xa->reply.header.error) { conn->last_call_status = NDMCONN_CALL_STATUS_HDR_ERROR; ndmconn_set_err_msg (conn, "reply-error-hdr"); return NDMCONN_CALL_STATUS_HDR_ERROR; } conn->last_reply_error = ndmnmb_get_reply_error (&xa->reply); if (conn->last_reply_error != NDMP9_NO_ERR) { conn->last_call_status = NDMCONN_CALL_STATUS_REPLY_ERROR; ndmconn_set_err_msg (conn, "reply-error"); return NDMCONN_CALL_STATUS_REPLY_ERROR; } return NDMCONN_CALL_STATUS_OK; } int ndmconn_exchange_nmb (struct ndmconn *conn, struct ndmp_msg_buf *request_nmb, struct ndmp_msg_buf *reply_nmb) { int rc; if ((rc = ndmconn_send_nmb (conn, request_nmb)) != 0) return rc; conn->received_time = 0; conn->sent_time = time(0); for (;;) { if ((rc = ndmconn_recv_nmb (conn, reply_nmb)) != 0) return rc; if (reply_nmb->header.message_type == NDMP0_MESSAGE_REPLY && reply_nmb->header.reply_sequence == request_nmb->header.sequence) { conn->received_time = time(0); return 0; } (*conn->unexpected)(conn, reply_nmb); } } int ndmconn_send_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb) { return ndmconn_xdr_nmb (conn, nmb, XDR_ENCODE); } int ndmconn_recv_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb) { NDMOS_MACRO_ZEROFILL (nmb); nmb->protocol_version = conn->protocol_version; return ndmconn_xdr_nmb (conn, nmb, XDR_DECODE); } void ndmconn_free_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb) { ndmnmb_free (nmb); } int ndmconn_xdr_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb, enum xdr_op x_op) { xdrproc_t xdr_body = 0; assert (conn->conn_type == NDMCONN_TYPE_REMOTE); if (conn->chan.fd < 0) { return ndmconn_set_err_msg (conn, "not-open"); } conn->xdrs.x_op = x_op; if (x_op == XDR_ENCODE) { xdr_body = ndmnmb_find_xdrproc (nmb); if (nmb->header.error == NDMP0_NO_ERR && !xdr_body) { return ndmconn_set_err_msg (conn, "unknown-body"); } nmb->header.sequence = conn->next_sequence++; nmb->header.time_stamp = time(0); ndmconn_snoop_nmb (conn, nmb, "Send"); } if (x_op == XDR_DECODE) { if (!xdrrec_skiprecord (&conn->xdrs)) { return ndmconn_set_err_msg (conn, "xdr-get-next"); } } if (!xdr_ndmp0_header (&conn->xdrs, &nmb->header)) { ndmconn_abort (conn); if (x_op == XDR_DECODE && conn->chan.eof && !conn->chan.error) { return ndmconn_set_err_msg (conn, "EOF"); } else { return ndmconn_set_err_msg (conn, "xdr-hdr"); } } if (x_op == XDR_DECODE) { xdr_body = ndmnmb_find_xdrproc (nmb); if (nmb->header.error == NDMP0_NO_ERR && !xdr_body) { return ndmconn_set_err_msg (conn, "unknown-body"); } } if (nmb->header.error == NDMP0_NO_ERR) { if (!(*xdr_body) (&conn->xdrs, &nmb->body)) { ndmconn_abort (conn); return ndmconn_set_err_msg (conn, "xdr-body"); } } if (x_op == XDR_ENCODE) { if (!xdrrec_endofrecord(&conn->xdrs, 1)) { ndmconn_abort (conn); return ndmconn_set_err_msg (conn, "xdr-send"); } } if (x_op == XDR_DECODE) { ndmconn_snoop_nmb (conn, nmb, "Recv"); } return 0; } /* * XDR READ/WRITE CALLBACKS **************************************************************** * * ndmconn_readit() and ndmconn_writeit() are the XDR callbacks * used by xdrrec_create(). They are fundamentally wrappers * around read() and write(), and have very similar parameters. * See the xdr(3) manual page (or try "man xdrrec_create"). * * ndmconn_readit() tracks the XDR record marks, and never * reads across a record boundary. This keeps select() an * indicator of when there is a (single) request pending. * Otherwise, we have to check buffers internal to XDR * as well as the file descriptor (via select) to determine * if a request is pending. */ int ndmconn_readit (void *a_conn, char *buf, int len) { struct ndmconn *conn = (struct ndmconn *)a_conn; int rc, i, c; /* could impose timeout here */ if (conn->chan.fd < 0 || conn->chan.eof) return -1; ndmconn_snoop (conn, 8, "frag_resid=%d fhb_off=%d", conn->frag_resid, conn->fhb_off); if (conn->frag_resid == 0) { i = 0; while (i < 4) { c = 4 - i; rc = ndmconn_sys_read (conn, (void *)(conn->frag_hdr_buf+i), c); if (rc <= 0) { return rc; } i += rc; } conn->frag_resid = conn->frag_hdr_buf[0] << 24; conn->frag_resid |= conn->frag_hdr_buf[1] << 16; conn->frag_resid |= conn->frag_hdr_buf[2] << 8; conn->frag_resid |= conn->frag_hdr_buf[3]; conn->frag_resid &= 0xFFFFFF; conn->fhb_off = 0; } if (conn->fhb_off < 4) { i = 0; while (conn->fhb_off < 4 && len > 0) { buf[i++] = conn->frag_hdr_buf[conn->fhb_off++]; len--; } return i; } if ((unsigned int)len > conn->frag_resid) len = (unsigned int)conn->frag_resid; rc = ndmconn_sys_read (conn, buf, len); if (rc > 0) { conn->frag_resid -= rc; } return rc; } int ndmconn_writeit (void *a_conn, char *buf, int len) { struct ndmconn *conn = (struct ndmconn *)a_conn; /* could impose timeout here */ if (conn->chan.fd < 0) return -1; return ndmconn_sys_write (conn, buf, len); } /* * ndmconn_sys_read() and ndmconn_sys_write() are simply * wrappers around read() and write(). They implement * the low-level snooping. */ int ndmconn_sys_read (struct ndmconn *conn, char *buf, unsigned len) { int rc; ndmconn_snoop (conn, 9, "reading %d ...", len); rc = read (conn->chan.fd, buf, len); ndmconn_snoop (conn, 8, "read=%d len=%d", rc, len); if (rc <= 0) { conn->chan.eof = 1; if (rc < 0) conn->chan.error = 1; } else { ndmconn_hex_dump (conn, buf, rc); } return rc; } int ndmconn_sys_write (struct ndmconn *conn, char *buf, unsigned len) { int rc; ndmconn_snoop (conn, 9, "writing %d ...", len); ndmconn_hex_dump (conn, buf, len); rc = write (conn->chan.fd, buf, len); ndmconn_snoop (conn, 8, "write=%d len=%d", rc, len); if (rc !=(int)len) { conn->chan.eof = 1; conn->chan.error = 1; } return rc; } /* * UNEXPECTED **************************************************************** * * The default unexpected() handler for a connection. It is * called when ndmconn_exchange_nmb() receives something * other than the reply for which it is waiting. * This default routine silently dumps the message. */ void ndmconn_unexpected (struct ndmconn *conn, struct ndmp_msg_buf *nmb) { xdrproc_t xdr_body = ndmnmb_find_xdrproc (nmb); if (xdr_body) { xdr_free (xdr_body, (void*) &nmb->body); } } /* * SNOOP **************************************************************** * * The ndmconn snoop stuff. The cool part. This pretty prints * NDMP messages as they go flying by this end-point. */ int ndmconn_set_snoop (struct ndmconn *conn, struct ndmlog *log, int level) { conn->snoop_log = log; conn->snoop_level = level; return 0; } void ndmconn_clear_snoop (struct ndmconn *conn) { conn->snoop_log = 0; conn->snoop_level = 0; } void ndmconn_snoop_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb, char *whence) { if (!conn->snoop_log) { return; } ndmnmb_snoop (conn->snoop_log, conn->chan.name, conn->snoop_level, nmb, whence); } void ndmconn_snoop (struct ndmconn *conn, int level, char *fmt, ...) { va_list ap; if (conn->snoop_log && conn->snoop_level >= level) { va_start (ap, fmt); ndmlogfv (conn->snoop_log, conn->chan.name, level, fmt, ap); va_end (ap); } } /* used by ndmconn_sys_read() and ndmconn_sys_write() to show low-level */ void ndmconn_hex_dump (struct ndmconn *conn, char *buf, unsigned len) { struct ndmlog * log = conn->snoop_log; char * tag = conn->chan.name; char linebuf[16*3+3]; char * p = linebuf; int b; unsigned i; if (log && conn->snoop_level > 8) { for (i = 0; i < len; i++) { b = buf[i] & 0xFF; sprintf (p, " %02x", b); while (*p) p++; if ((i&0xF) == 0xF) { ndmlogf (log,tag,9,"%s",linebuf+1); p = linebuf; } } if (p > linebuf) { ndmlogf (log,tag,9,"%s",linebuf+1); } } } /* * ERRORS **************************************************************** * * Possible errors for ndmconn are not enumerated. * Instead, errors are indicated by a -1 return, and * a simple string error message is available for details. * Appologies for the english-centric design, but it * is quick and easy, and better than using printf(). */ int ndmconn_set_err_msg (struct ndmconn *conn, char *err_msg) { conn->last_err_msg = err_msg; ndmconn_snoop (conn, 4, "ERR=%s", err_msg); return -1; } char * ndmconn_get_err_msg (struct ndmconn *conn) { if (!conn->last_err_msg) return "-no-error-"; else return conn->last_err_msg; } bareos-Release-14.2.6/src/ndmp/ndml_cstr.c000066400000000000000000000064471263011562700203310ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * Convert strings to/from a canonical strings (CSTR). * * The main reason for this is to eliminate spaces * in strings thus making multiple strings easily * delimited by white space. * * Canonical strings use the HTTP convention of * percent sign followed by two hex digits (%xx). * Characters outside the printable ASCII range, * space, and percent sign are so converted. * * Both interfaces return the length of the resulting * string, -1 if there is an overflow, or -2 * there is a conversion error. */ #include "ndmlib.h" static char ndmcstr_to_hex[] = "0123456789ABCDEF"; extern int ndmcstr_from_hex (int c); int ndmcstr_from_str (char *src, char *dst, unsigned dst_max) { unsigned char * p = (unsigned char *)src; unsigned char * q = (unsigned char *)dst; unsigned char * q_end = q + dst_max - 1; int c; while ((c = *p++) != 0) { if (c <= ' ' || c > 0x7E || c == NDMCSTR_WARN) { if (q+3 > q_end) return -1; *q++ = NDMCSTR_WARN; *q++ = ndmcstr_to_hex[(c>>4)&0xF]; *q++ = ndmcstr_to_hex[c&0xF]; } else { if (q+1 > q_end) return -1; *q++ = c; } } *q = 0; return q - (unsigned char *)dst; } int ndmcstr_to_str (char *src, char *dst, unsigned dst_max) { unsigned char * p = (unsigned char *)src; unsigned char * q = (unsigned char *)dst; unsigned char * q_end = q + dst_max - 1; int c, c1, c2; while ((c = *p++) != 0) { if (q+1 > q_end) return -1; if (c != NDMCSTR_WARN) { *q++ = c; continue; } c1 = ndmcstr_from_hex (p[0]); c2 = ndmcstr_from_hex (p[1]); if (c1 < 0 || c2 < 0) { /* busted conversion */ return -2; } c = (c1<<4) + c2; *q++ = c; p += 2; } *q = 0; return q - (unsigned char *)dst; } int ndmcstr_from_hex (int c) { if ('0' <= c && c <= '9') return c - '0'; if ('a' <= c && c <= 'f') return (c - 'a') + 10; if ('A' <= c && c <= 'F') return (c - 'A') + 10; return -1; } bareos-Release-14.2.6/src/ndmp/ndml_fhdb.c000066400000000000000000000246571263011562700202640ustar00rootroot00000000000000/* * Copyright (c) 2001,2002 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" void ndmfhdb_register_callbacks (struct ndmlog *ixlog, struct ndm_fhdb_callbacks *callbacks) { /* * Only allow one register. */ if (!ixlog->nfc) { ixlog->nfc = NDMOS_API_MALLOC (sizeof(struct ndm_fhdb_callbacks)); if (ixlog->nfc) { memcpy (ixlog->nfc, callbacks, sizeof(struct ndm_fhdb_callbacks)); } } } void ndmfhdb_unregister_callbacks (struct ndmlog *ixlog) { if (ixlog->nfc) { NDMOS_API_FREE (ixlog->nfc); ixlog->nfc = NULL; } } int ndmfhdb_add_file (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat) { if (ixlog->nfc && ixlog->nfc->add_file) { return ixlog->nfc->add_file (ixlog, tagc, raw_name, fstat); } else { return 0; } } int ndmfhdb_add_dir (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node) { if (ixlog->nfc && ixlog->nfc->add_dir) { return ixlog->nfc->add_dir (ixlog, tagc, raw_name, dir_node, node); } else { return 0; } } int ndmfhdb_add_node (struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat) { if (ixlog->nfc && ixlog->nfc->add_node) { return ixlog->nfc->add_node (ixlog, tagc, node, fstat); } else { return 0; } } int ndmfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node) { if (ixlog->nfc && ixlog->nfc->add_dirnode_root) { return ixlog->nfc->add_dirnode_root (ixlog, tagc, root_node); } else { return 0; } } int ndmfhdb_add_fh_info_to_nlist (FILE *fp, ndmp9_name *nlist, int n_nlist) { struct ndmfhdb _fhcb, *fhcb = &_fhcb; int i, rc, n_found; ndmp9_file_stat fstat; rc = ndmfhdb_open (fp, fhcb); if (rc != 0) { return -31; } n_found = 0; for (i = 0; i < n_nlist; i++) { char * name = nlist[i].original_path; rc = ndmfhdb_lookup (fhcb, name, &fstat); if (rc > 0) { nlist[i].fh_info = fstat.fh_info; if (fstat.fh_info.valid) { n_found++; } } } return n_found; } int ndmfhdb_open (FILE *fp, struct ndmfhdb *fhcb) { int rc; NDMOS_MACRO_ZEROFILL (fhcb); fhcb->fp = fp; rc = ndmfhdb_dirnode_root (fhcb); if (rc > 0) { fhcb->use_dir_node = 1; return 0; } rc = ndmfhdb_file_root (fhcb); if (rc > 0) { fhcb->use_dir_node = 0; return 0; } return -1; } int ndmfhdb_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat) { if (fhcb->use_dir_node) { return ndmfhdb_dirnode_lookup (fhcb, path, fstat); } else { return ndmfhdb_file_lookup (fhcb, path, fstat); } } int ndmfhdb_dirnode_root (struct ndmfhdb *fhcb) { int rc, off; char * p; char key[256]; char linebuf[2048]; snprintf (key, sizeof(key), "DHr "); p = NDMOS_API_STREND(key); off = p - key; rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf); if (rc <= 0) { return rc; /* error or not found */ } fhcb->root_node = NDMOS_API_STRTOLL (linebuf+off, &p, 0); if (*p != 0) { return -10; } return 1; } int ndmfhdb_dirnode_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat) { int rc; char * p; char * q; char component[256+128]; uint64_t dir_node; uint64_t node; /* classic path name reduction */ node = dir_node = fhcb->root_node; p = path; for (;;) { if (*p == '/') { p++; continue; } if (*p == 0) { break; } q = component; while (*p != 0 && *p != '/') { *q++ = *p++; } *q = 0; dir_node = node; rc = ndmfhdb_dir_lookup (fhcb, dir_node, component, &node); if (rc <= 0) return rc; /* error or not found */ } rc = ndmfhdb_node_lookup (fhcb, node, fstat); return rc; } int ndmfhdb_dir_lookup (struct ndmfhdb *fhcb, uint64_t dir_node, char *name, uint64_t *node_p) { int rc, off; char * p; char key[256+128]; char linebuf[2048]; snprintf (key, sizeof(key), "DHd %llu ", dir_node); p = NDMOS_API_STREND(key); ndmcstr_from_str (name, p, sizeof key - (p-key) - 10); strcat (p, " UNIX "); p = NDMOS_API_STREND(key); off = p - key; rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf); if (rc <= 0) { return rc; /* error or not found */ } *node_p = NDMOS_API_STRTOLL (linebuf+off, &p, 0); if (*p != 0) { return -10; } return 1; } int ndmfhdb_node_lookup (struct ndmfhdb *fhcb, uint64_t node, ndmp9_file_stat *fstat) { int rc, off; char * p; char key[128]; char linebuf[2048]; snprintf (key, sizeof(key), "DHn %llu UNIX ", node); p = NDMOS_API_STREND(key); off = p - key; rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf); if (rc <= 0) { return rc; /* error or not found */ } rc = ndm_fstat_from_str (fstat, linebuf + off); if (rc < 0) { return rc; } return 1; } int ndmfhdb_file_root (struct ndmfhdb *fhcb) { int rc; ndmp9_file_stat fstat; rc = ndmfhdb_file_lookup (fhcb, "/", &fstat); if (rc > 0) { if (fstat.node.valid) fhcb->root_node = fstat.node.value; } return rc; } int ndmfhdb_file_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat) { int rc, off; char * p; char key[2048]; char linebuf[2048]; snprintf (key, sizeof(key), "DHf "); p = NDMOS_API_STREND(key); ndmcstr_from_str (path, p, sizeof key - (p-key) - 10); strcat (p, " UNIX "); p = NDMOS_API_STREND(key); off = p - key; rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf); if (rc <= 0) { return rc; /* error or not found */ } rc = ndm_fstat_from_str (fstat, linebuf + off); if (rc < 0) { return rc; } return 1; } /* * Same codes as wraplib.[ch] wrap_parse_fstat_subr() * and wrap_send_fstat_subr(). */ char * ndm_fstat_to_str (ndmp9_file_stat *fstat, char *buf) { char * p = buf; *p++ = 'f'; switch (fstat->ftype) { case NDMP9_FILE_DIR: *p++ = 'd'; break; case NDMP9_FILE_FIFO: *p++ = 'p'; break; case NDMP9_FILE_CSPEC: *p++ = 'c'; break; case NDMP9_FILE_BSPEC: *p++ = 'b'; break; case NDMP9_FILE_REG: *p++ = '-'; break; case NDMP9_FILE_SLINK: *p++ = 'l'; break; case NDMP9_FILE_SOCK: *p++ = 's'; break; case NDMP9_FILE_REGISTRY: *p++ = 'R'; break; case NDMP9_FILE_OTHER: *p++ = 'o'; break; default: *p++ = '?'; break; } if (fstat->mode.valid) { sprintf (p, " m%04lo", fstat->mode.value & 07777); } while (*p) p++; if (fstat->uid.valid) { sprintf (p, " u%ld", fstat->uid.value); } while (*p) p++; if (fstat->gid.valid) { sprintf (p, " g%ld", fstat->gid.value); } while (*p) p++; if (fstat->ftype == NDMP9_FILE_REG || fstat->ftype == NDMP9_FILE_SLINK) { if (fstat->size.valid) { sprintf (p, " s%llu", fstat->size.value); } } else { /* ignore size on other file types */ } while (*p) p++; /* tar -t can not recover atime/ctime */ /* they are also not particularly interesting in the index */ if (fstat->mtime.valid) { sprintf (p, " tm%lu", fstat->mtime.value); } while (*p) p++; if (fstat->fh_info.valid) { sprintf (p, " @%lld", fstat->fh_info.value); } while (*p) p++; return buf; } int ndm_fstat_from_str (ndmp9_file_stat *fstat, char *buf) { char * scan = buf; ndmp9_validity * valid_p; NDMOS_MACRO_ZEROFILL (fstat); while (*scan) { char * p = scan + 1; switch (*scan) { case ' ': scan++; continue; case '@': /* fh_info */ fstat->fh_info.value = NDMOS_API_STRTOLL (p, &scan, 0); valid_p = &fstat->fh_info.valid; break; case 's': /* size */ fstat->size.value = NDMOS_API_STRTOLL (p, &scan, 0); valid_p = &fstat->size.valid; break; case 'i': /* fileno (inum) */ fstat->node.value = NDMOS_API_STRTOLL (p, &scan, 0); valid_p = &fstat->node.valid; break; case 'm': /* mode low twelve bits */ fstat->mode.value = strtol (p, &scan, 8); valid_p = &fstat->mode.valid; break; case 'l': /* link count */ fstat->links.value = strtol (p, &scan, 0); valid_p = &fstat->links.valid; break; case 'u': /* uid */ fstat->uid.value = strtol (p, &scan, 0); valid_p = &fstat->uid.valid; break; case 'g': /* gid */ fstat->gid.value = strtol (p, &scan, 0); valid_p = &fstat->gid.valid; break; case 't': /* one of the times */ p = scan+2; switch (scan[1]) { case 'm': /* mtime */ fstat->mtime.value = strtol (p, &scan, 0); valid_p = &fstat->mtime.valid; break; case 'a': /* atime */ fstat->atime.value = strtol (p, &scan, 0); valid_p = &fstat->atime.valid; break; case 'c': /* ctime */ fstat->ctime.value = strtol (p, &scan, 0); valid_p = &fstat->ctime.valid; break; default: return -13; } break; case 'f': /* ftype (file type) */ switch (scan[1]) { case 'd': fstat->ftype = NDMP9_FILE_DIR; break; case 'p': fstat->ftype = NDMP9_FILE_FIFO; break; case 'c': fstat->ftype = NDMP9_FILE_CSPEC; break; case 'b': fstat->ftype = NDMP9_FILE_BSPEC; break; case '-': fstat->ftype = NDMP9_FILE_REG; break; case 'l': fstat->ftype = NDMP9_FILE_SLINK; break; case 's': fstat->ftype = NDMP9_FILE_SOCK; break; case 'R': fstat->ftype = NDMP9_FILE_REGISTRY; break; case 'o': fstat->ftype = NDMP9_FILE_OTHER; break; default: fstat->ftype = NDMP9_FILE_OTHER; return -15; } scan += 2; valid_p = 0; break; default: return -13; } if (*scan != ' ' && *scan != 0) return -11; if (valid_p) *valid_p = NDMP9_VALIDITY_VALID; } return 0; } bareos-Release-14.2.6/src/ndmp/ndml_fhh.c000066400000000000000000000107401263011562700201120ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * The heap is managed like this: * * +----------------+ * table ------> | entry | <----- heap_top * | ------- | * | entry | * | ------- | * | entry | * | ------- | * allo_ent ---> | ..... | * | | | * V | | * ~ ~ * ~ ~ * ^ | | * | | | * allo_item---> | .... | * | ------- | * | item | * | ------- | * | item | * | ------- | * | item | * +----------------+ <----- heap_end * * n_entry = allo_ent - table; */ #include "ndmlib.h" int ndmfhh_initialize (struct ndmfhheap *fhh) { NDMOS_MACRO_ZEROFILL (fhh); return NDMFHH_RET_OK; } int ndmfhh_commission (struct ndmfhheap *fhh, void *heap, unsigned size) { fhh->heap_base = heap; fhh->heap_size = size; fhh->heap_end = (char*)heap + size; /* Align everything */ fhh->heap_top = (void*) (((long)heap + (NDMOS_CONST_ALIGN-1)) &~ (NDMOS_CONST_ALIGN-1)); fhh->heap_bot = (void*) ((long)((char*)heap+size) &~ (NDMOS_CONST_ALIGN-1)); ndmfhh_reset (fhh); return NDMFHH_RET_OK; } #define SLOP 32 int ndmfhh_prepare (struct ndmfhheap *fhh, int fhtype, int entry_size, unsigned n_item, unsigned total_size_of_items) { void * pe; void * pi; unsigned items_need; if (fhh->heap_base == 0) return NDMFHH_RET_NO_HEAP; if (fhh->allo_entry == fhh->heap_top) { fhh->fhtype = fhtype; fhh->entry_size = entry_size; } else { if (fhh->fhtype != fhtype) return NDMFHH_RET_TYPE_CHANGE; if (fhh->entry_size != entry_size) return NDMFHH_RET_ENTRY_SIZE_MISMATCH; } items_need = total_size_of_items + n_item * NDMOS_CONST_ALIGN + SLOP; pe = (char*)fhh->allo_entry + fhh->entry_size; pi = (char*)fhh->allo_item - items_need; if (pe >= pi) return NDMFHH_RET_OVERFLOW; /* it'll fit! */ return NDMFHH_RET_OK; } void * ndmfhh_add_entry (struct ndmfhheap *fhh) { void * p; p = fhh->allo_entry; if ((char*)fhh->allo_entry + fhh->entry_size < (char*)fhh->allo_item) { fhh->allo_entry = (char *)p + fhh->entry_size; return p; } else { return 0; } } void * ndmfhh_add_item (struct ndmfhheap *fhh, unsigned size) { void * p; size += (NDMOS_CONST_ALIGN-1); size &= ~(NDMOS_CONST_ALIGN-1); p = (char*)fhh->allo_item - size; if (p > fhh->allo_entry) { fhh->allo_item = p; return p; } else { return 0; } } void * ndmfhh_save_item (struct ndmfhheap *fhh, void *item, unsigned size) { void * p; p = ndmfhh_add_item (fhh, size); if (p) { NDMOS_API_BCOPY (item, p, size); } return p; } int ndmfhh_reset (struct ndmfhheap *fhh) { fhh->allo_entry = fhh->heap_top; fhh->allo_item = fhh->heap_bot; return NDMFHH_RET_OK; } int ndmfhh_get_table (struct ndmfhheap *fhh, int *fhtype_p, void **table_p, unsigned *n_entry_p) { unsigned n; *fhtype_p = fhh->fhtype; *table_p = fhh->heap_top; n = (char*)fhh->allo_entry - (char*)fhh->heap_top; if (n > 0) n /= fhh->entry_size; *n_entry_p = n; return NDMFHH_RET_OK; } bareos-Release-14.2.6/src/ndmp/ndml_log.c000066400000000000000000000047161263011562700201340ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" static struct timeval start_time; char * ndmlog_time_stamp (void) { static char buf[40]; struct timeval now; uint32_t elapsed; int ms, sec, min, hour; if (!start_time.tv_sec) { gettimeofday (&start_time, (void*)0); } gettimeofday (&now, (void*)0); now.tv_sec -= start_time.tv_sec; now.tv_usec -= start_time.tv_usec; elapsed = now.tv_sec * 1000 + now.tv_usec / 1000; ms = elapsed % 1000; elapsed /= 1000; sec = elapsed % 60; elapsed /= 60; min = elapsed % 60; elapsed /= 60; hour = elapsed; snprintf (buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms); return buf; } void ndmlogf (struct ndmlog *log, char *tag, int level, char *fmt, ...) { va_list ap; char buf[2048]; va_start (ap, fmt); vsnprintf (buf, sizeof(buf), fmt, ap); va_end (ap); (*log->deliver)(log, tag, level, buf); } void ndmlogfv (struct ndmlog *log, char *tag, int level, char *fmt, va_list ap) { char buf[2048]; vsnprintf (buf, sizeof(buf), fmt, ap); (*log->deliver)(log, tag, level, buf); } bareos-Release-14.2.6/src/ndmp/ndml_md5.c000066400000000000000000000116321263011562700200330ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * * MD5 authentication support **************************************************************** * Both sides share a secret in the form of a clear-text * password. One side generates a challenge (64-bytes) * and conveys it to the other. The other side then * uses the challenge, the clear-text password, and * the NDMP rules for MD5, and generates a digest. * The digest is returned as proof that both sides * share the same secret clear-text password. * * The NDMP rules for MD5 are implemented in ndmmd5_digest(). * It amounts to positioning the clear-text password and challenge * into a "message" buffer, then applying the MD5 algorithm. * * ndmmd5_generate_challenge() generates a challenge[] * using conventional random number routines. * * ndmmd5_ok_digest() takes a locally known challenge[] * and clear-text password, a remotely generated * digest[], and determines if everything is correct. * * Using MD5 prevents clear-text passwords from being conveyed * over the network. However, it compels both sides to maintain * clear-text passwords in a secure fashion, which is difficult * to say the least. Because the NDMP MD5 rules must be followed * to digest() the password, it's impractical to consider * an external authentication authority. * * Credits to Rajiv of NetApp for helping with MD5 stuff. */ #include "ndmlib.h" #include "md5.h" int ndmmd5_generate_challenge (char challenge[NDMP_MD5_CHALLENGE_LENGTH]) { int i; NDMOS_MACRO_SRAND(); for (i = 0; i < NDMP_MD5_CHALLENGE_LENGTH; i++) { challenge[i] = NDMOS_MACRO_RAND() >> (i&7); } return 0; } int ndmmd5_ok_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH], char *clear_text_password, char digest[NDMP_MD5_DIGEST_LENGTH]) { char my_digest[16]; int i; ndmmd5_digest (challenge, clear_text_password, my_digest); for (i = 0; i < NDMP_MD5_DIGEST_LENGTH; i++) if (digest[i] != my_digest[i]) return 0; /* Invalid */ return 1; /* OK */ } int ndmmd5_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH], char *clear_text_password, char digest[NDMP_MD5_DIGEST_LENGTH]) { int pwlength = strlen (clear_text_password); struct MD5Context mdContext; unsigned char message[128]; /* * The spec describes the construction of the 128 byte * "message" (probably MD5-speak). It is described as: * * PASSWORD PADDING CHALLENGE PADDING PASSWORD * * Each PADDING is defined as zeros of length 64 minus pwlen. * * A pwlen of over 32 would result in not all fields * fitting. This begs a question of the order elements * are inserted into the message[]. You get a different * message[] if you insert the PASSWORD(s) before * the CHALLENGE than you get the other way around. * * A pwlen of over 64 would result in PADDING of negative * length, which could cause crash boom bang. * * The resolution of this vaguery implemented here is to * only use the first 32 bytes of the password. All * fields fit. Order dependencies are avoided. * * Final resolution is pending. */ if (pwlength > 32) pwlength = 32; /* * Compose the 128-byte buffer according to NDMP rules */ NDMOS_API_BZERO (message, sizeof message); NDMOS_API_BCOPY (clear_text_password, &message[0], pwlength); NDMOS_API_BCOPY (clear_text_password, &message[128 - pwlength], pwlength); NDMOS_API_BCOPY (challenge, &message[64 - pwlength], 64); /* * Grind it up, ala MD5 */ MD5Init(&mdContext); MD5Update(&mdContext, message, 128); MD5Final((unsigned char *)digest, &mdContext); /* * ding! done */ return 0; } bareos-Release-14.2.6/src/ndmp/ndml_media.c000066400000000000000000000127751263011562700204360ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" /* * Media Entry (medent) * * [LABEL][+FILEMARKS][/NBYTES][@SLOT] * * LABEL is simple text and must be first. * * +FILEMARKS, /NBYTES, and @SLOT may occur in any order. * * FILEMARKS is a small decimal number and indicates * how many filemarks to skip when using the media. * 0 means begining of tape. If no +FILEMARKS is given, * 1 is used if LABEL is given, 0 otherwise. * * NBYTES indicates the maximum amount of data on the * media. This is a decimal number optionally followed * by a scale character (k, m, g). * * SLOT is the slot address in the tape robot. It is * the element address, not relative to the first * slot in the robot. */ int ndmmedia_from_str (struct ndmmedia *me, char *str) { char * p; char * q; int c; NDMOS_MACRO_ZEROFILL (me); p = str; q = me->label; for (; *p; p++) { c = *p; if (c == '+' || c == '@' || c == '/') break; if (q < &me->label[NDMMEDIA_LABEL_MAX]) *q++ = c; } *q = 0; if (q > me->label) me->valid_label = 1; while (*p) { c = *p; switch (c) { default: return -1; /* what is this? */ case '@': if (me->valid_slot) return -2; me->slot_addr = strtol (p+1, &p, 0); me->valid_slot = 1; break; case '+': if (me->valid_filemark) return -3; me->file_mark_offset = strtol (p+1, &p, 0); me->valid_filemark = 1; break; case '/': if (me->valid_n_bytes) return -4; me->n_bytes = ndmmedia_strtoll (p+1, &p, 0); me->valid_n_bytes = 1; break; } } return 0; } int ndmmedia_to_str (struct ndmmedia *me, char *str) { char * q = str; *q = 0; if (me->valid_label) { strcpy (q, me->label); while (*q) q++; } if (me->valid_filemark) { sprintf (q, "+%d", me->file_mark_offset); while (*q) q++; } if (me->valid_n_bytes) { if (me->n_bytes == 0) sprintf (q, "/0"); else if (me->n_bytes % (1024*1024*1024) == 0) sprintf (q, "/%lldG", me->n_bytes/(1024*1024*1024)); else if (me->n_bytes % (1024*1024) == 0) sprintf (q, "/%lldM", me->n_bytes/(1024*1024)); else if (me->n_bytes % (1024) == 0) sprintf (q, "/%lldK", me->n_bytes/(1024)); else sprintf (q, "/%lld", me->n_bytes); while (*q) q++; } if (me->valid_slot) { sprintf (q, "@%d", me->slot_addr); while (*q) q++; } return 0; } static char *flag_yes_or_no (int f) { return (f) ? "Y" : "N"; } int ndmmedia_pp (struct ndmmedia *me, int lineno, char *buf) { switch (lineno) { case 0: ndmmedia_to_str (me, buf); break; case 1: sprintf (buf, "valid label=%s filemark=%s n_bytes=%s slot=%s", flag_yes_or_no (me->valid_label), flag_yes_or_no (me->valid_filemark), flag_yes_or_no (me->valid_n_bytes), flag_yes_or_no (me->valid_slot)); break; case 2: sprintf (buf, "media used=%s written=%s eof=%s eom=%s io_error=%s", flag_yes_or_no (me->media_used), flag_yes_or_no (me->media_written), flag_yes_or_no (me->media_eof), flag_yes_or_no (me->media_eom), flag_yes_or_no (me->media_io_error)); break; case 3: sprintf (buf, "label read=%s written=%s io_error=%s mismatch=%s", flag_yes_or_no (me->label_read), flag_yes_or_no (me->label_written), flag_yes_or_no (me->label_io_error), flag_yes_or_no (me->label_mismatch)); break; case 4: sprintf (buf, "fm_error=%s nb_determined=%s nb_aligned=%s", flag_yes_or_no (me->fmark_error), flag_yes_or_no (me->nb_determined), flag_yes_or_no (me->nb_aligned)); break; case 5: sprintf (buf, "slot empty=%s bad=%s missing=%s", flag_yes_or_no (me->slot_empty), flag_yes_or_no (me->slot_bad), flag_yes_or_no (me->slot_missing)); break; default: strcpy (buf, "<>"); break; } return 6; } int64_t ndmmedia_strtoll (char *str, char **tailp, int defbase) { int64_t val = 0; int c; for (;;) { c = *str; if (c < '0' || '9' < c) break; val *= 10; val += c - '0'; str++; } switch (c) { default: break; case 'k': case 'K': val *= 1024LL; str++; break; case 'm': case 'M': val *= 1024*1024LL; str++; break; case 'g': case 'G': val *= 1024*1024*1024LL; str++; break; } if (tailp) *tailp = str; return val; } bareos-Release-14.2.6/src/ndmp/ndml_nmb.c000066400000000000000000000136571263011562700201330ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" xdrproc_t ndmnmb_find_xdrproc (struct ndmp_msg_buf *nmb) { struct ndmp_xdr_message_table * xmte; xmte = ndmp_xmt_lookup (nmb->protocol_version, nmb->header.message); if (!xmte) { return 0; } if (nmb->header.message_type == NDMP0_MESSAGE_REQUEST) { return (xdrproc_t) xmte->xdr_request; } if (nmb->header.message_type == NDMP0_MESSAGE_REPLY) { return (xdrproc_t) xmte->xdr_reply; } return 0; } void ndmnmb_free (struct ndmp_msg_buf *nmb) { xdrproc_t xdr_body = ndmnmb_find_xdrproc (nmb); if (nmb->flags & NDMNMB_FLAG_NO_FREE) return; if (xdr_body) { xdr_free (xdr_body, (void*) &nmb->body); } } void ndmnmb_snoop ( struct ndmlog *log, char *tag, int level, struct ndmp_msg_buf *nmb, char *whence) { int rc, nl, i; char buf[2048]; int (*ndmpp)(); int level5 = 5; int level6 = 6; if (level < 6 && nmb->protocol_version == 4) { ndmp4_header *header = (ndmp4_header *)&nmb->header; if ((header->message_code == NDMP4_NOTIFY_DATA_HALTED && header->error_code == NDMP4_DATA_HALT_SUCCESSFUL) || (header->message_code == NDMP4_NOTIFY_MOVER_HALTED && header->error_code == NDMP4_MOVER_HALT_CONNECT_CLOSED)) { level = 6; level5 = 0; level6 = 0; } } if (!log || level < 5) { return; } rc = ndmp_pp_header (nmb->protocol_version, &nmb->header, buf); #if 0 ndmlogf (log, tag, level5, "%s %s", buf, whence); #else { char combo[3]; if (*whence == 'R') { combo[0] = '>'; combo[1] = buf[0]; } else { combo[0] = buf[0]; combo[1] = '>'; } combo[2] = 0; ndmlogf (log, tag, level5, "%s %s", combo, buf+2); } #endif if (level < 6) { return; } if (rc <= 0) { /* no body */ return; } if (nmb->header.message_type == NDMP0_MESSAGE_REQUEST) { ndmpp = ndmp_pp_request; } else if (nmb->header.message_type == NDMP0_MESSAGE_REPLY) { ndmpp = ndmp_pp_reply; } else { return; /* should not happen */ } nl = 1; for (i = 0; i < nl; i++) { nl = (*ndmpp)(nmb->protocol_version, nmb->header.message, &nmb->body, i, buf); if (nl == 0) break; /* no printable body (void) */ ndmlogf (log, tag, level6, " %s", buf); } } unsigned ndmnmb_get_reply_error_raw (struct ndmp_msg_buf *nmb) { unsigned protocol_version = nmb->protocol_version; unsigned msg = nmb->header.message; unsigned raw_error; if (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(protocol_version, msg)) { raw_error = nmb->body.unf3_error.error; } else { raw_error = nmb->body.error; } return raw_error; } ndmp9_error ndmnmb_get_reply_error (struct ndmp_msg_buf *nmb) { unsigned protocol_version = nmb->protocol_version; unsigned raw_error = ndmnmb_get_reply_error_raw (nmb); ndmp9_error error; switch (protocol_version) { default: /* best effort */ error = (ndmp9_error) raw_error; break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: { ndmp2_error error2 = raw_error; ndmp_2to9_error (&error2, &error); } break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: { ndmp3_error error3 = raw_error; ndmp_3to9_error (&error3, &error); } break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: { ndmp4_error error4 = raw_error; ndmp_4to9_error (&error4, &error); } break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return error; } int ndmnmb_set_reply_error_raw (struct ndmp_msg_buf *nmb, unsigned raw_error) { unsigned protocol_version = nmb->protocol_version; unsigned msg = nmb->header.message; if (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(protocol_version, msg)) { nmb->body.unf3_error.error = raw_error; } else { nmb->body.error = raw_error; } return 0; } int ndmnmb_set_reply_error (struct ndmp_msg_buf *nmb, ndmp9_error error) { unsigned protocol_version = nmb->protocol_version; unsigned raw_error; switch (protocol_version) { default: /* best effort */ raw_error = (unsigned) error; break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: { ndmp2_error error2; ndmp_9to2_error (&error, &error2); raw_error = (unsigned) error2; } break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: { ndmp3_error error3; ndmp_9to3_error (&error, &error3); raw_error = (unsigned) error3; } break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: { ndmp4_error error4; ndmp_9to4_error (&error, &error4); raw_error = (unsigned) error4; } break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ } return ndmnmb_set_reply_error_raw (nmb, raw_error); } bareos-Release-14.2.6/src/ndmp/ndml_scsi.c000066400000000000000000000141231263011562700203050ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" /* * NAME[,[CNUM,]SID[,LUN] * * The foregoing pattern is ambiguous. Here's the disambiguating rules: * 1) If just a name is given, controller, sid, and lun are all * set to invalid (-1) * 2) If one number comes after the device name (,sid) it is the * SID; controller is set to -1, lun is set to 0 * 3) If two numbers come after the device name (,sid,lun), they are * the SID and LUN; controller is set to -1 * 4) Three numbers after the device name are all three number fields. */ int ndmscsi_target_from_str (struct ndmscsi_target *targ, char *str) { char * p; int n1, n2, n3; NDMOS_MACRO_ZEROFILL (targ); p = strchr (str, ','); if (p) { *p++ = 0; } if (strlen (str) >= NDMOS_CONST_PATH_MAX) { if (p) p[-1] = ','; return -2; } strcpy (targ->dev_name, str); if (!p) { targ->controller = -1; targ->sid = -1; targ->lun = -1; return 0; } p[-1] = ','; if (*p < '0' || '9' < *p) { return -3; } n1 = strtol (p, &p, 0); if (*p != 0 && *p != ',') { return -4; } if (*p == 0) { targ->controller = -1; targ->sid = n1; targ->lun = 0; return 0; } p++; if (*p < '0' || '9' < *p) { return -5; } n2 = strtol (p, &p, 0); if (*p == 0) { /* SID,LUN */ targ->controller = -1; targ->sid = n1; targ->lun = n2; } else { if (*p != ',') { return -6; } p++; if (*p < '0' || '9' < *p) { return -7; } n3 = strtol (p, &p, 0); if (*p != 0) { return -8; } targ->controller = n1; targ->sid = n2; targ->lun = n3; } return 0; } int ndmscsi_open (struct ndmconn *conn, char *dev_name) { int rc; NDMC_WITH(ndmp9_scsi_open, NDMP9VER) request->device = dev_name; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmscsi_close (struct ndmconn *conn) { int rc; NDMC_WITH_VOID_REQUEST(ndmp9_scsi_close, NDMP9VER) rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmscsi_get_state (struct ndmconn *conn, struct ndmscsi_target *targ) { int rc; NDMOS_MACRO_ZEROFILL (targ); NDMC_WITH_VOID_REQUEST(ndmp9_scsi_get_state, NDMP9VER) rc = NDMC_CALL(conn); targ->controller = reply->target_controller; targ->sid = reply->target_id; targ->lun = reply->target_lun; NDMC_ENDWITH return rc; } int ndmscsi_set_target (struct ndmconn *conn, struct ndmscsi_target *targ) { int rc; NDMC_WITH(ndmp9_scsi_set_target, NDMP9VER) request->device = targ->dev_name; request->target_controller = targ->controller; request->target_id = targ->sid; request->target_lun = targ->lun; rc = NDMC_CALL(conn); NDMC_ENDWITH return rc; } int ndmscsi_use (struct ndmconn *conn, struct ndmscsi_target *targ) { int rc; #if 0 rc = ndmscsi_close (conn); /* error ignored */ #endif rc = ndmscsi_open (conn, targ->dev_name); if (rc) return rc; if (targ->controller != -1 || targ->sid != -1 || targ->lun != -1) { #ifndef NDMOS_OPTION_NO_NDMP4 if (conn->protocol_version == NDMP4VER) { return -1; /* can't set target */ } #endif /* !NDMOS_OPTION_NO_NDMP4 */ rc = ndmscsi_set_target (conn, targ); if (rc) { ndmscsi_close (conn); /* best effort */ return rc; } } return 0; } int ndmscsi_execute (struct ndmconn *conn, struct ndmscsi_request *req, struct ndmscsi_target *targ) { int rc; if (targ) { rc = ndmscsi_use (conn, targ); if (rc) return rc; } NDMC_WITH(ndmp9_scsi_execute_cdb, NDMP9VER) request->cdb.cdb_len = req->n_cmd; request->cdb.cdb_val = (char*)req->cmd; switch (req->data_dir) { case NDMSCSI_DD_NONE: request->data_dir = NDMP9_SCSI_DATA_DIR_NONE; break; case NDMSCSI_DD_IN: request->data_dir = NDMP9_SCSI_DATA_DIR_IN; request->datain_len = req->n_data_avail; break; case NDMSCSI_DD_OUT: request->data_dir = NDMP9_SCSI_DATA_DIR_OUT; request->dataout.dataout_len = req->n_data_avail; request->dataout.dataout_val = (char*)req->data; break; } request->timeout = 300000; /* five minutes */ rc = NDMC_CALL (conn); if (rc) { req->completion_status = NDMSCSI_CS_FAIL; return rc; } req->status_byte = reply->status; req->n_data_done = 0; req->n_sense_data = 0; rc = reply->ext_sense.ext_sense_len; if (rc > 0) { if (rc > NDMSCSI_MAX_SENSE_DATA) rc = NDMSCSI_MAX_SENSE_DATA; req->n_sense_data = rc; NDMOS_API_BCOPY (reply->ext_sense.ext_sense_val, req->sense_data, rc); } switch (req->data_dir) { case NDMSCSI_DD_IN: req->n_data_done = reply->datain.datain_len; if (req->n_data_done > 0) { NDMOS_API_BCOPY (reply->datain.datain_val, req->data, req->n_data_done); } break; case NDMSCSI_DD_OUT: req->n_data_done = reply->dataout_len; break; } req->completion_status = NDMSCSI_CS_GOOD; NDMC_FREE_REPLY(); NDMC_ENDWITH return 0; } bareos-Release-14.2.6/src/ndmp/ndml_stzf.c000066400000000000000000000102641263011562700203340ustar00rootroot00000000000000/* * Copyright 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * Stanza files look about like this: * [stanza name line] * stanza body lines * * These are used for config files. */ #include "ndmlib.h" int ndmstz_getline (FILE *fp, char *buf, int n_buf) { int c; char * p; again: c = getc (fp); if (c == EOF) return EOF; if (c == '[') { /* end-of-stanza */ ungetc (c, fp); return -2; } if (c == '#') { /* comment */ while ((c = getc(fp)) != EOF && c != '\n') continue; goto again; } ungetc (c, fp); p = buf; while ((c = getc(fp)) != EOF && c != '\n') { if (p < &buf[n_buf-1]) *p++ = c; } *p = 0; return p - buf; } int ndmstz_getstanza (FILE *fp, char *buf, int n_buf) { int c; char * p; again: c = getc (fp); if (c == EOF) return EOF; if (c == '\n') goto again; /* blank line */ if (c != '[') { /* not a stanza header, eat line */ while ((c = getc(fp)) != EOF && c != '\n') continue; goto again; } p = buf; while ((c = getc(fp)) != EOF && c != '\n' && c != ']') { if (p < &buf[n_buf-1]) *p++ = c; } *p = 0; if (c == ']') { /* eat rest of line */ while ((c = getc(fp)) != EOF && c != '\n') continue; } /* fp is left pointing to begining of first line */ return p - buf; } int ndmstz_parse (char *buf, char *argv[], int max_argv) { char * p = buf; char * q = buf; int inword = 0; int inquote = 0; int argc = 0; int c; while ((c = *p++) != 0) { if (inquote) { if (c == inquote) { inquote = 0; } else { *q++ = c; } continue; } if (isspace(c)) { if (inword) { *q++ = 0; inword = 0; } continue; } if (!inword) { if (argc > max_argv-1) break; argv[argc++] = q; inword = 1; } if (c == '"' || c == '\'') { inquote = c; continue; } *q++ = c; } if (inword) *q++ = 0; argv[argc] = 0; return argc; } #ifdef SELF_TEST int main (int ac, char *av[]) { int i, found, argc; FILE * fp; char buf[512]; char * argv[100]; if (ac < 2) { printf ("bad usage\n"); return 1; } fp = fopen (av[1], "r"); if (!fp) { perror (av[1]); return 2; } if (ac == 2) { while (ndmstz_getstanza (fp, buf, sizeof buf) >= 0) printf ("%s\n", buf); } else { for (i = 2; i < ac; i++) { rewind (fp); found = 0; while (ndmstz_getstanza (fp, buf, sizeof buf) >= 0) { if (strcmp (av[i], buf) == 0) { found = 1; break; } } if (!found) { printf ("Search for '%s' failed\n", av[i]); continue; } printf ("'%s'\n", buf); printf ("========================================\n"); while (ndmstz_getline (fp, buf, sizeof buf) >= 0) { printf ("= %s", buf); argc = ndmstz_parse (buf, argv, 100); printf (" [%d]\n", argc); } printf ("========================================\n"); } } fclose (fp); return 0; } #endif /* SELF_TEST */ bareos-Release-14.2.6/src/ndmp/ndml_util.c000066400000000000000000000030231263011562700203160ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmlib.h" char * ndml_strend (char *s) { while (*s) s++; return s; } bareos-Release-14.2.6/src/ndmp/ndmlib.h000066400000000000000000000633251263011562700176140ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000,2002 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef _NDMLIB_H_ #define _NDMLIB_H_ #include "ndmos.h" #include "ndmprotocol.h" #include "ndmp_msg_buf.h" #include "ndmp_translate.h" /* Probably unnecessary, yet prudent. Compilers/debuggers sometimes goof. */ #ifndef NDM_FLAG_DECL #define NDM_FLAG_DECL(XXX) unsigned XXX : 1; #endif /* !NDM_FLAG_DECL */ #ifdef __cplusplus extern "C" { #endif /* boring forward reference stuff */ struct ndmagent; /* * NDMLOG **************************************************************** * * ndmlog is a simple abstraction for log messages. * Each log entry has: * - a tag, which is a short string indicating origin or purpose * - a level between 0-9, the higher the value the greater the detail * - a message * The application will typically direct log messages to a file. * Yet, logging directly to a FILE tends to be restrictive. Hence * this abstraction. * * The time stamp is relative to the start time, and has millisecond * granularity. */ struct ndmlog { void (*deliver)(struct ndmlog *log, char *tag, int lev, char *msg); void * ctx; struct ndm_fhdb_callbacks *nfc; }; extern char * ndmlog_time_stamp (void); extern void ndmlogf (struct ndmlog *log, char *tag, int level, char *fmt, ...); extern void ndmlogfv (struct ndmlog *log, char *tag, int level, char *fmt, va_list ap); /* * NDMNMB -- NDMP Message Buffer **************************************************************** * * The ndmnmb routines are trivial aids for handling * NMB (NDMP Messsage Buffer). ndmp_msg_buf is defined in * ndmp_msg_buf.h, and pretty much amounts to a huge * union of all NDMP request and reply types. */ extern xdrproc_t ndmnmb_find_xdrproc (struct ndmp_msg_buf *nmb); extern void ndmnmb_free (struct ndmp_msg_buf *nmb); extern void ndmnmb_snoop (struct ndmlog *log, char *tag, int level, struct ndmp_msg_buf *nmb, char *whence); extern unsigned ndmnmb_get_reply_error_raw (struct ndmp_msg_buf *nmb); extern ndmp9_error ndmnmb_get_reply_error (struct ndmp_msg_buf *nmb); extern int ndmnmb_set_reply_error_raw (struct ndmp_msg_buf *nmb, unsigned raw_error); extern int ndmnmb_set_reply_error (struct ndmp_msg_buf *nmb, ndmp9_error error); /* * NDMCHAN -- Async I/O channel **************************************************************** * * ndmchan is a wrapper around I/O channels, and is used * to juggle (manage) multiple I/O activities at one time. * The data buffer is used linearly. beg_ix and end_ix * bracket the valid data. When the end of the buffer is reached, * the remaining valid data is moved to the begining. */ struct ndmchan { char * name; /* short name, helps debugging */ char mode; /* NDMCHAN_MODE_... (see below) */ NDM_FLAG_DECL(check) /* Want select()/poll() to check */ NDM_FLAG_DECL(ready) /* select()/poll() indicates ready */ NDM_FLAG_DECL(eof) /* eof pending upon n_ready()==0 */ NDM_FLAG_DECL(error) /* error (channel shutdown) */ int fd; /* der eff dee */ int saved_errno; /* errno captured if ->error occurs */ unsigned beg_ix; /* relative to ->data */ unsigned end_ix; /* relative to ->data */ char * data; /* data buffer (READ/WRITE/RESIDENT) */ unsigned data_size; /* size of data buffer */ }; #define NDMCHAN_MODE_IDLE 0 /* not doing anything */ #define NDMCHAN_MODE_RESIDENT 1 /* resident, within this process */ #define NDMCHAN_MODE_READ 2 /* read from ->fd into ->data */ #define NDMCHAN_MODE_WRITE 3 /* write to ->fd from ->data */ #define NDMCHAN_MODE_READCHK 4 /* check ->fd readable, no ->data */ #define NDMCHAN_MODE_LISTEN 5 /* ->fd listen()ing */ #define NDMCHAN_MODE_PENDING 6 /* ->fd and ->data ready */ #define NDMCHAN_MODE_CLOSED 7 /* ->fd closed */ enum ndmchan_read_interpretation { NDMCHAN_RI_EMPTY = 10, /* no data, might be more coming */ NDMCHAN_RI_READY, /* data ready */ NDMCHAN_RI_READY_FULL, /* data ready, no more until consumed */ NDMCHAN_RI_DRAIN_EOF, /* data ready, DONE_EOF after consumed */ NDMCHAN_RI_DRAIN_ERROR, /* data ready, DONE_ERROR after consumed */ NDMCHAN_RI_DONE_EOF, /* no data, no more coming, normal EOF */ NDMCHAN_RI_DONE_ERROR, /* no data, no more coming, something wrong */ NDMCHAN_RI_FAULT /* crazy request */ }; enum ndmchan_write_interpretation { NDMCHAN_WI_FULL = 30, /* no buffer, no more until some sent */ NDMCHAN_WI_AVAIL, /* buffer ready, sending in progress */ NDMCHAN_WI_AVAIL_EMPTY, /* buffer ready, done sending */ NDMCHAN_WI_DRAIN_EOF, /* no more buffer, DONE_EOF after sent */ NDMCHAN_WI_DRAIN_ERROR, /* no more buffer, DONE_ERROR after sent */ NDMCHAN_WI_DONE_EOF, /* no more buffer, done sending, normal EOF */ NDMCHAN_WI_DONE_ERROR, /* no more buffer, done sending, went wrong */ NDMCHAN_WI_FAULT /* crazy request */ }; extern void ndmchan_initialize (struct ndmchan *ch, char *name); extern int ndmchan_setbuf (struct ndmchan *ch, char *data, unsigned data_size); extern int ndmchan_start_mode (struct ndmchan *ch, int fd, int chan_mode); extern int ndmchan_start_read (struct ndmchan *ch, int fd); extern int ndmchan_start_write (struct ndmchan *ch, int fd); extern int ndmchan_start_readchk (struct ndmchan *ch, int fd); extern int ndmchan_start_listen (struct ndmchan *ch, int fd); extern int ndmchan_start_resident (struct ndmchan *ch); extern int ndmchan_start_pending (struct ndmchan *ch, int fd); extern int ndmchan_pending_to_mode (struct ndmchan *ch, int chan_mode); extern int ndmchan_pending_to_read (struct ndmchan *ch); extern int ndmchan_pending_to_write (struct ndmchan *ch); extern void ndmchan_set_eof (struct ndmchan *ch); extern void ndmchan_close_set_errno (struct ndmchan *ch, int err_no); extern void ndmchan_close (struct ndmchan *ch); extern void ndmchan_abort (struct ndmchan *ch); extern void ndmchan_close_as_is (struct ndmchan *ch); extern void ndmchan_cleanup (struct ndmchan *ch); extern int ndmchan_quantum (struct ndmchan *chtab[], unsigned n_chtab, int milli_timo); extern int ndmchan_pre_poll (struct ndmchan *chtab[], unsigned n_chtab); extern int ndmchan_post_poll (struct ndmchan *chtab[], unsigned n_chtab); extern void ndmchan_compress (struct ndmchan *ch); extern int ndmchan_n_avail (struct ndmchan *ch); extern int ndmchan_n_avail_record (struct ndmchan *ch, uint32_t size); extern int ndmchan_n_avail_total (struct ndmchan *ch); extern int ndmchan_n_ready (struct ndmchan *ch); extern enum ndmchan_read_interpretation ndmchan_read_interpret (struct ndmchan *ch, char **data_p, unsigned *n_ready_p); extern enum ndmchan_write_interpretation ndmchan_write_interpret (struct ndmchan *ch, char **data_p, unsigned *n_avail_p); extern void ndmchan_pp (struct ndmchan *ch, char *buf); extern int ndmos_chan_poll (struct ndmchan *chtab[], unsigned n_chtab, int milli_timo); /* * NDMCONN -- Bidirectional control connections **************************************************************** */ #define NDMCONN_TYPE_NONE 0 #define NDMCONN_TYPE_RESIDENT 1 #define NDMCONN_TYPE_REMOTE 2 #define NDMCONN_CALL_STATUS_HDR_ERROR (-2) #define NDMCONN_CALL_STATUS_BOTCH (-1) #define NDMCONN_CALL_STATUS_OK 0 #define NDMCONN_CALL_STATUS_REPLY_ERROR 1 #define NDMCONN_CALL_STATUS_REPLY_LATE 2 struct ndmconn { struct sockaddr sa; struct ndmchan chan; char conn_type; char protocol_version; char was_allocated; void * context; XDR xdrs; unsigned char frag_hdr_buf[4]; /* see ndmconn_readit() */ unsigned fhb_off; uint32_t frag_resid; uint32_t next_sequence; void (*unexpected)(struct ndmconn *conn, struct ndmp_msg_buf *nmb); int snoop_level; struct ndmlog * snoop_log; char * last_err_msg; int (*call) (struct ndmconn *conn, struct ndmp_xa_buf *xa); struct ndmp_xa_buf call_xa_buf; int last_message; int last_call_status; ndmp9_error last_header_error; ndmp9_error last_reply_error; long sent_time; long received_time; long time_limit; }; extern struct ndmconn * ndmconn_initialize (struct ndmconn *aconn, char *name); extern void ndmconn_destruct (struct ndmconn *conn); extern int ndmconn_connect_agent (struct ndmconn *conn, struct ndmagent *agent); extern int ndmconn_connect_host_port (struct ndmconn *conn, char * hostname, int port, unsigned want_protocol_version); extern int ndmconn_connect_sockaddr_in (struct ndmconn *conn, struct sockaddr_in *sin, unsigned want_protocol_version); extern int ndmconn_try_open (struct ndmconn *conn, unsigned protocol_version); extern int ndmconn_accept (struct ndmconn *conn, int sock); extern int ndmconn_abort (struct ndmconn *conn); extern int ndmconn_close (struct ndmconn *conn); extern int ndmconn_fileno (struct ndmconn *conn); extern int ndmconn_auth_agent (struct ndmconn *conn, struct ndmagent *agent); extern int ndmconn_auth_none (struct ndmconn *conn); extern int ndmconn_auth_text (struct ndmconn *conn, char *id, char *pw); extern int ndmconn_auth_md5 (struct ndmconn *conn, char *id, char *pw); extern int ndmconn_call (struct ndmconn *conn, struct ndmp_xa_buf *xa); extern int ndmconn_exchange_nmb (struct ndmconn *conn, struct ndmp_msg_buf *request_nmb, struct ndmp_msg_buf *reply_nmb); extern int ndmconn_send_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb); extern int ndmconn_recv_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb); extern void ndmconn_free_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb); extern int ndmconn_xdr_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb, enum xdr_op x_op); extern int ndmconn_readit (void *a_conn, char *buf, int len); extern int ndmconn_writeit (void *a_conn, char *buf, int len); extern int ndmconn_sys_read (struct ndmconn *conn, char *buf, unsigned len); extern int ndmconn_sys_write (struct ndmconn *conn, char *buf, unsigned len); extern void ndmconn_unexpected (struct ndmconn *conn, struct ndmp_msg_buf *nmb); extern int ndmconn_set_snoop (struct ndmconn *conn, struct ndmlog *log, int level); extern void ndmconn_clear_snoop (struct ndmconn *conn); extern void ndmconn_snoop_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb, char *whence); extern void ndmconn_snoop (struct ndmconn *conn, int level, char *fmt, ...); extern void ndmconn_hex_dump (struct ndmconn *conn, char *buf, unsigned len); extern int ndmconn_set_err_msg (struct ndmconn *conn, char *err_msg); extern char * ndmconn_get_err_msg (struct ndmconn *conn); /* * NDMC_WITH() AND FRIENDS **************************************************************** * * Macro NDMC_WITH() and friends. These are patterned after * the Pascal "with" construct. These macros take care of * the tedious, error prone, mind-numbing, and distracting * code required to perform NDMP RPCs. These greatly * facilitate the clarity of the main body of code. * Code sequences look something like: * * NDMC_WITH(ndmp_config_get_butype_attr) * request->xxx = yyy; * ... * rc = NDMC_CALL(ndmconn); * if (rc == 0) { * reply->xxx ... * .... * } * NDMC_FREE_REPLY() * NDMC_ENDWITH * * The NDMC macros are for client-side (caller) sequences. * The NDMS macros are for server-side (callee) sequences. * * These macros are very dependent on ndmp_msg_buf.h and ndmp_ammend.h * * Implementation note: initialization of *request and *reply * are separate from their declarations. They used to be * initialized declarators. The separation made gcc -Wall happy. */ #define NDMC_WITH(TYPE,VERS) \ { \ struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ TYPE##_request * request; \ TYPE##_reply * reply; \ request = &xa->request.body.TYPE##_request_body; \ reply = &xa->reply.body.TYPE##_reply_body; \ NDMOS_MACRO_ZEROFILL (xa); \ xa->request.protocol_version = VERS; \ xa->request.header.message = (ndmp0_message) MT_##TYPE; \ { #define NDMC_WITH_VOID_REQUEST(TYPE,VERS) \ { \ struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ TYPE##_reply * reply; \ reply = &xa->reply.body.TYPE##_reply_body; \ NDMOS_MACRO_ZEROFILL (xa); \ xa->request.protocol_version = VERS; \ xa->request.header.message = (ndmp0_message) MT_##TYPE; \ { #define NDMC_WITH_NO_REPLY(TYPE,VERS) \ { \ struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ TYPE##_request * request; \ request = &xa->request.body.TYPE##_request_body; \ NDMOS_MACRO_ZEROFILL (xa); \ xa->request.protocol_version = VERS; \ xa->request.header.message = (ndmp0_message) MT_##TYPE; \ { #ifndef NDMOS_OPTION_NO_NDMP4 #define NDMC_WITH_POST(TYPE,VERS) \ { \ struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ TYPE##_post * request; \ request = &xa->request.body.TYPE##_post_body; \ NDMOS_MACRO_ZEROFILL (xa); \ xa->request.protocol_version = VERS; \ xa->request.header.message = (ndmp0_message) MT_##TYPE; \ { #endif /* !NDMOS_OPTION_NO_NDMP4 */ #define NDMC_ENDWITH \ } } #define NDMC_CALL(CONN) (*(CONN)->call)(CONN, xa); #define NDMC_SEND(CONN) (*(CONN)->call)(CONN, xa); #define NDMC_FREE_REPLY() ndmconn_free_nmb ((void*)0, &xa->reply) #define NDMS_WITH(TYPE) \ { \ TYPE##_request * request; \ TYPE##_reply * reply; \ request = &xa->request.body.TYPE##_request_body; \ reply = &xa->reply.body.TYPE##_reply_body; \ { #define NDMS_WITH_VOID_REQUEST(TYPE) \ { \ TYPE##_reply * reply; \ reply = &xa->reply.body.TYPE##_reply_body; \ { #define NDMS_WITH_NO_REPLY(TYPE) \ { \ TYPE##_request * request; \ request = &xa->request.body.TYPE##_request_body; \ { #ifndef NDMOS_OPTION_NO_NDMP4 #define NDMS_WITH_POST(TYPE) \ { \ TYPE##_post * request; \ request = &xa->request.body.TYPE##_post_body; \ { #endif /* !NDMOS_OPTION_NO_NDMP4 */ #define NDMS_ENDWITH \ } } /* * NDMAGENT -- "Address" of agent **************************************************************** * * A struct ndmagent contains the information necessary * to establish a connection with an NDMP agent (server). * An agent can be remote (NDMCONN_TYPE_REMOTE) or resident * (...._RESIDENT). * TODO: MD5 */ #define NDMAGENT_HOST_MAX 63 #define NDMAGENT_ACCOUNT_MAX 15 #define NDMAGENT_PASSWORD_MAX 32 struct ndmagent { char conn_type; /* NDMCONN_TYPE_... (see above) */ char protocol_version; /* 0->best, 2->v2 3->v3 */ char host[NDMAGENT_HOST_MAX+1]; /* name */ int port; /* 0->default (NDMPPORT) */ char account[NDMAGENT_ACCOUNT_MAX+1]; /* clear text */ char password[NDMAGENT_PASSWORD_MAX+1]; /* clear text */ #if 0 ndmp_auth_type auth_type; #else int auth_type; #endif }; extern int ndmagent_from_str (struct ndmagent *agent, char *str); extern int ndmhost_lookup (char *hostname, struct sockaddr_in *sin); extern int ndmagent_to_sockaddr_in (struct ndmagent *agent, struct sockaddr_in *sin); /* * NDMSCSI -- "Address" of SCSI device **************************************************************** */ struct ndmscsi_target { char dev_name[NDMOS_CONST_PATH_MAX]; int controller; int sid; int lun; }; #define NDMSCSI_MAX_SENSE_DATA 127 struct ndmscsi_request { unsigned char completion_status; unsigned char status_byte; unsigned char data_dir; unsigned char n_cmd; unsigned char cmd[12]; unsigned char * data; unsigned n_data_avail; unsigned n_data_done; uint32_t _pad; unsigned char n_sense_data; unsigned char sense_data[NDMSCSI_MAX_SENSE_DATA]; }; #define NDMSCSI_CS_GOOD 0 #define NDMSCSI_CS_FAIL 1 /* more? */ #define NDMSCSI_DD_NONE 0 #define NDMSCSI_DD_IN 1 /* adapter->app */ #define NDMSCSI_DD_OUT 2 /* app->adapter */ extern int ndmscsi_target_from_str (struct ndmscsi_target *targ, char *str); extern int ndmscsi_open (struct ndmconn *conn, char *dev_name); extern int ndmscsi_close (struct ndmconn *conn); extern int ndmscsi_get_state (struct ndmconn *conn, struct ndmscsi_target *targ); extern int ndmscsi_set_target (struct ndmconn *conn, struct ndmscsi_target *targ); extern int ndmscsi_use (struct ndmconn *conn, struct ndmscsi_target *targ); extern int ndmscsi_execute (struct ndmconn *conn, struct ndmscsi_request *req, struct ndmscsi_target *targ); /* * NDMMEDIA -- media (tape) labels, position, and status **************************************************************** */ #define NDMMEDIA_LABEL_MAX 31 struct ndmmedia { NDM_FLAG_DECL(valid_label) /* ->label[] valid */ NDM_FLAG_DECL(valid_filemark) /* ->file_mark_skip valid */ NDM_FLAG_DECL(valid_n_bytes) /* ->n_bytes valid */ NDM_FLAG_DECL(valid_slot) /* ->slot_addr valid */ /* results flags */ NDM_FLAG_DECL(media_used) /* was used (loaded) */ NDM_FLAG_DECL(media_written) /* media was written */ NDM_FLAG_DECL(media_eof) /* reached EOF of tape file */ NDM_FLAG_DECL(media_eom) /* reached EOM (tape full) */ NDM_FLAG_DECL(media_open_error) /* open-time error (write-protect?) */ NDM_FLAG_DECL(media_io_error) /* media error */ NDM_FLAG_DECL(label_read) /* ->label[] read fm media */ NDM_FLAG_DECL(label_written) /* ->label[] written to media */ NDM_FLAG_DECL(label_io_error) /* error label read/write */ NDM_FLAG_DECL(label_mismatch) /* label wasn't as expected */ NDM_FLAG_DECL(fmark_error) /* error skipping file marks */ NDM_FLAG_DECL(nb_determined) /* true ->n_bytes determined */ NDM_FLAG_DECL(nb_aligned) /* ->n_bytes aligned per rec_size */ NDM_FLAG_DECL(slot_empty) /* slot empty per robot */ NDM_FLAG_DECL(slot_bad) /* ->slot_addr invalid */ NDM_FLAG_DECL(slot_missing) /* !->valid_slot */ /* all fields are specified/actual depending on context */ char label[NDMMEDIA_LABEL_MAX+1]; unsigned file_mark_offset; uint64_t n_bytes; unsigned slot_addr; /* scratch pad */ uint64_t begin_offset, end_offset; int index; struct ndmmedia *next; }; extern int ndmmedia_from_str (struct ndmmedia *me, char *str); extern int ndmmedia_to_str (struct ndmmedia *me, char *str); extern int ndmmedia_pp (struct ndmmedia *me, int lineno, char *buf); extern int64_t ndmmedia_strtoll (char *str, char **tailp, int defbase); /* * NDMFHH -- file history (FH) heap **************************************************************** * * As DATA accumulates individual File History (FH) entries they * are saved into a heap buffer. When the heap is full it is flushed * from DATA to CONTROL using NDMP?_FH_ADD_.... requests/posts. */ struct ndmfhheap { int fhtype; int entry_size; void * table; void * allo_entry; void * allo_item; void * heap_base; void * heap_end; unsigned heap_size; void * heap_top; void * heap_bot; }; struct ndmfhh_generic_table { u_int table_len; void * table_val; }; #define NDMFHH_RET_OK (0) #define NDMFHH_RET_OVERFLOW (-1) #define NDMFHH_RET_TYPE_CHANGE (-2) #define NDMFHH_RET_NO_HEAP (-3) #define NDMFHH_RET_ENTRY_SIZE_MISMATCH (-4) extern int ndmfhh_initialize (struct ndmfhheap *fhh); extern int ndmfhh_commission (struct ndmfhheap *fhh, void *heap, unsigned size); extern int ndmfhh_prepare (struct ndmfhheap *fhh, int fhtype, int entry_size, unsigned n_item, unsigned total_size_of_items); extern void * ndmfhh_add_entry (struct ndmfhheap *fhh); extern void * ndmfhh_add_item (struct ndmfhheap *fhh, unsigned size); extern void * ndmfhh_save_item (struct ndmfhheap *fhh, void *item, unsigned size); extern int ndmfhh_reset (struct ndmfhheap *fhh); extern int ndmfhh_get_table (struct ndmfhheap *fhh, int *fhtype_p, void **table_p, unsigned *n_entry_p); /* * NDMCSTR -- canonical strings **************************************************************** * Convert strings to/from HTTP-like canonical strings (%xx). * Example "a b%c" --> "a%20b%25c" */ #define NDMCSTR_WARN '%' extern int ndmcstr_from_str (char *src, char *dst, unsigned dst_max); extern int ndmcstr_to_str (char *src, char *dst, unsigned dst_max); extern int ndmcstr_from_hex (int c); /* * NDMMD5 -- MD5 helpers **************************************************************** * This is a wrapper around the MD5 functions. ndml_md5.c * is the only thing that needs to #include md5.h. * The NDMP rules for converting a clear-text password * into an MD5 digest are implemented here. */ #define NDMP_MD5_CHALLENGE_LENGTH 64 #define NDMP_MD5_DIGEST_LENGTH 16 #define NDMP_MD5_MESSAGE_LENGTH 128 #define NDMP_MD5_MAX_PASSWORD_LENGTH 32 extern int ndmmd5_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH], char *clear_text_password, char digest[NDMP_MD5_DIGEST_LENGTH]); extern int ndmmd5_generate_challenge ( char challenge[NDMP_MD5_CHALLENGE_LENGTH]); extern int ndmmd5_ok_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH], char *clear_text_password, char digest[NDMP_MD5_DIGEST_LENGTH]); /* * NDMBSTF -- Binary Search Text File **************************************************************** * Use conventional binary search method on a sorted text * file. The file MUST be sorted in ascending, lexicographic * order. This is the default order of sort(1). */ extern int ndmbstf_first (FILE *fp, char *key, char *buf, unsigned max_buf); extern int ndmbstf_next (FILE *fp, char *key, char *buf, unsigned max_buf); extern int ndmbstf_first_with_bounds (FILE *fp, char *key, char *buf, unsigned max_buf, off_t lower_bound, off_t upper_bound); extern int ndmbstf_getline (FILE *fp, char *buf, unsigned max_buf); extern int ndmbstf_seek_and_align (FILE *fp, off_t *off); extern int ndmbstf_match (char *key, char *buf); extern int ndmbstf_compare (char *key, char *buf); /* * NDMSTZF -- Stanza File **************************************************************** * * Stanza files look about like this: * [stanza name line] * stanza body lines * * These are used for config files. */ extern int ndmstz_getline (FILE *fp, char *buf, int n_buf); extern int ndmstz_getstanza (FILE *fp, char *buf, int n_buf); extern int ndmstz_parse (char *buf, char *argv[], int max_argv); /* * NDMCFG -- Config File **************************************************************** * * Config files are stanza files (see above) which describe * backup types, tape and scsi devices, etc. * See ndml_config.c for details and stanza formats. */ extern int ndmcfg_load (char *filename, ndmp9_config_info *config_info); extern int ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info); /* * NDMFHDB -- File History Database * * The File History is generated by the DATA and sent to the CONTROL * using NDMP?_FH_ADD_... requests/posts. During backup the CONTROL * writes the File History info to a text file as it arrives. Upon * completion of the backup the text file should be sorted (UNIX * sort(1) command). For recovery the file history index is searched * using binary search (see NDMBSTF above). The fh_info, a 64-bit * cookie used by DATA to identify the region of the backup image * containing the corresponding object, is retreived from the index. */ struct ndmfhdb { FILE * fp; int use_dir_node; uint64_t root_node; }; struct ndm_fhdb_callbacks { int (*add_file) (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat); int (*add_dir) (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node); int (*add_node) (struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat); int (*add_dirnode_root) (struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node); }; extern void ndmfhdb_register_callbacks (struct ndmlog *ixlog, struct ndm_fhdb_callbacks *callbacks); extern void ndmfhdb_unregister_callbacks (struct ndmlog *ixlog); extern int ndmfhdb_add_file (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_file_stat *fstat); extern int ndmfhdb_add_dir (struct ndmlog *ixlog, int tagc, char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node); extern int ndmfhdb_add_node (struct ndmlog *ixlog, int tagc, ndmp9_u_quad node, ndmp9_file_stat *fstat); extern int ndmfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc, ndmp9_u_quad root_node); extern int ndmfhdb_add_fh_info_to_nlist (FILE *fp, ndmp9_name *nlist, int n_nlist); extern int ndmfhdb_open (FILE *fp, struct ndmfhdb *fhcb); extern int ndmfhdb_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat); extern int ndmfhdb_dirnode_root (struct ndmfhdb *fhcb); extern int ndmfhdb_dirnode_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat); extern int ndmfhdb_dir_lookup (struct ndmfhdb *fhcb, uint64_t dir_node, char *name, uint64_t *node_p); extern int ndmfhdb_node_lookup (struct ndmfhdb *fhcb, uint64_t node, ndmp9_file_stat *fstat); extern int ndmfhdb_file_root (struct ndmfhdb *fhcb); extern int ndmfhdb_file_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat); extern char * ndm_fstat_to_str (ndmp9_file_stat *fstat, char *buf); extern int ndm_fstat_from_str (ndmp9_file_stat *fstat, char *buf); #ifdef __cplusplus } #endif #endif /* _NDMLIB_H_ */ bareos-Release-14.2.6/src/ndmp/ndmos.c000066400000000000000000000033101263011562700174460ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * #include the right O/S specific C file. */ #include "ndmagents.h" #if NDMOS_ID == NDMOS_ID_FREEBSD #include "ndmos_freebsd.c" #endif #if NDMOS_ID == NDMOS_ID_SOLARIS #include "ndmos_solaris.c" #endif #if NDMOS_ID == NDMOS_ID_LINUX #include "ndmos_linux.c" #endif bareos-Release-14.2.6/src/ndmp/ndmos.h000066400000000000000000000424571263011562700174720ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * * This is the #include file for the Operating System * (O/S) specific portion of the NDMJOBLIB library. * By O/S we mean the programming environment including * compilers, header files, as well the host O/S APIs. * O/S specific is clear and concise, so that's how we refer * to the hosting environment. * * This file, ndmos.h, essentially #include's the right * ndmos_xxx.h for the hosting environment. The companion * source C files, ndmos_xxx*.c, are similarly selected by * ndmos.c. * * The strategy for separating the O/S specific and O/S * generic portions of NDMJOBLIB has four key points: * * 1) Isolate O/S specific portions in separate * files which can be developed, contributed, * and maintained independently of the overall * source base. * * 2) NEVER NEVER #ifdef based on O/S or programming * environment in the O/S generic portions. These * make collective maintenance and integration * too difficult. * * 3) Use O/S specific #define macros (NDMOS_...) * and C functions (ndmos_...) as wrappers around * the portions that vary between environments * and applications. * * 4) Use generic, objective-oriented #ifdef's to isolate * and omit functionality which may not be wanted in * all applications. * * There are templates in ndmos_xxx.h and ndmos_xxx.c * to get started on a new O/S specific portion. * Send contributions to the current keeper of NDMJOB. * Contact ndmp-tech@ndmp.org for details. * * >>> DO NOT MODIFY THIS FILE OR ANY GENERIC <<< * >>> PORTION OF NDMJOBLIB FOR THE SAKE OF A <<< * >>> HOSTING ENVIRONMENT OR APPLICATION. <<< * * If you discover additional isolation requirements, * raise the issue on ndmp-tech@ndmp.org. Propose new * #define NDMOS_ macros to address them. Then, submit * the proposal with required changes to the current * keeper of NDMJOB. Changes to the generic portion which * use #ifdef's based on anything other than NDMOS_ * macros will be summarily rejected. * * There are four sections of this file: * 1) Establish identities for various O/S platforms * 2) Try to auto-recognize the environment * 3) #include the right O/S specific ndmos_xxx.h * 4) Establish default #define-itions for macros * left undefined */ #ifndef _NDMOS_H #define _NDMOS_H /* * Silence compiler for known warnings. */ #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wformat" #pragma GCC diagnostic ignored "-Wenum-compare" #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 460 #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #endif #endif #if defined(__SUNPRO_C) #pragma error_messages (off, E_ENUM_TYPE_MISMATCH_OP, E_ENUM_TYPE_MISMATCH_ARG, E_STATEMENT_NOT_REACHED ) #endif /* * Operating system idents */ #define NDMOS_IDENT(A,B,C,D) (((A)<<24)+((B)<<16)+((C)<<8)+(D)) #define NDMOS_ID_FREEBSD NDMOS_IDENT('F','B','s','d') #define NDMOS_ID_SOLARIS NDMOS_IDENT('S','o','l','a') #define NDMOS_ID_LINUX NDMOS_IDENT('L','n','u','x') #define NDMOS_ID_IRIX NDMOS_IDENT('I','R','I','X') #define NDMOS_ID_HPUX NDMOS_IDENT('H','P','U','X') #define NDMOS_ID_ULTRIX NDMOS_IDENT('U','l','t','r') #define NDMOS_ID_TRU64 NDMOS_IDENT('T','R','U',64) #define NDMOS_ID_AIX NDMOS_IDENT('A','I','X',0) /* * Only explicitly include config.h when we are doing standalone * compiling of the lib when included from Bareos there is no need * to re-include config.h as that config file is not protected against * multiple including. So we just test to see if bareos.h is not * already included as that leaves a nice fingerprint. */ #ifndef _BAREOS_H #include "config.h" #endif /* * If NDMOS_ID isn't set, try to autorecognize the OS based * on standard CPP symbols. */ #ifndef NDMOS_ID #ifdef HAVE_FREEBSD_OS #define NDMOS_ID NDMOS_ID_FREEBSD #endif #ifdef HAVE_SUN_OS #define NDMOS_ID NDMOS_ID_SOLARIS #endif #ifdef HAVE_LINUX_OS #define NDMOS_ID NDMOS_ID_LINUX #endif #endif /* !NDMOS_ID */ /* * Do we got it? */ #ifndef NDMOS_ID @@@@ You need to use -DNDMOS_ID=NDMOS_ID_xxxx #endif /* * Based on NDMOS_ID, #include the right O/S specific header file */ #if NDMOS_ID == NDMOS_ID_FREEBSD #include "ndmos_freebsd.h" #endif #if NDMOS_ID == NDMOS_ID_SOLARIS #include "ndmos_solaris.h" #endif #if NDMOS_ID == NDMOS_ID_LINUX #include "ndmos_linux.h" #endif /* * From here down, pre-processor symbols are #define'd to defaults * if not already #define'd in the O/S specific header file. * * Application Program Interfaces (APIs). The macros give the * O/S specific header a chance to use casts or different functions. * * NDMOS_API_BCOPY -- memory copy * NDMOS_API_BZERO -- zero-fill memory * NDMOS_API_MALLOC -- memory allocator, no initialization * NDMOS_API_FREE -- memory deallocator * NDMOS_API_STRTOLL -- convert strings to long long * NDMOS_API_STRDUP -- malloc() and strcpy() * NDMOS_API_STREND -- return pointer to end of string * * Important constants that sometimes vary between O/S's. * * NDMOS_CONST_ALIGN -- alignment for memory allocation * NDMOS_CONST_EWOULDBLOCK -- errno when async I/O would stall * NDMOS_CONST_TAPE_REC_MAX -- maximum tape record length * NDMOS_CONST_TAPE_REC_MIN -- minimum tape record length * NDMOS_CONST_PATH_MAX -- maximum path name length * NDMOS_CONST_NDMJOBLIB_REVISION -- String for in-house change level * Convention "0" if no changes * from released source. If changes, * the initials of local keeper with * sequence number or date code. * NDMOS_CONST_VENDOR_NAME -- String for server_info_reply.vendor_name * NDMOS_CONST_PRODUCT_NAME -- String for server_info_reply.product_name * NDMOS_CONST_PRODUCT_REVISION -- String for product change level * By "product" we mean the program * enclosing this NDMJOBLIB library. * NDMOS_CONST_NDMOS_REVISION -- String for ndmos_xxx change level * * Macros for certain small operations which can vary. * * NDMOS_MACRO_NEW -- allocate a data structure, wrapper * around NDMOS_API_MALLOC() with casts * NDMOS_MACRO_NEWN -- allocate a vector of data structs * NDMOS_MACRO_ZEROFILL -- zero-fill data structure, wrapper * around NDMOS_API_BZERO() * NDMOS_MACRO_ZEROFILL_SIZE -- zero-fill data structure, wrapper * around NDMOS_API_BZERO() * NDMOS_MACRO_SRAND -- wrapper around srand(3), for MD5 * NDMOS_MACRO_RAND -- wrapper around rand(3), for MD5 * NDMOS_MACRO_OK_TAPE_REC_LEN -- Uses NDMOS_CONST_TAPE_REC_MIN/MAX * NDMOS_MACRO_SET_SOCKADDR -- Sets struct sockaddr_in with * respect to NDMOS_OPTION_HAVE_SIN_LEN * * The NDMOS_MACRO_xxx_ADDITIONS macros allow additional O/S * specific members to key structures in ndmagents.h * * NDMOS_MACRO_CONTROL_AGENT_ADDITIONS -- struct ndm_control_agent * NDMOS_MACRO_DATA_AGENT_ADDITIONS -- struct ndm_data_agent * NDMOS_MACRO_ROBOT_AGENT_ADDITIONS -- struct ndm_robot_agent * NDMOS_MACRO_SESSION_ADDITIONS -- struct ndm_session * NDMOS_MACRO_TAPE_AGENT_ADDITIONS -- struct ndm_tape_agent * * All NDMOS_OPTION_... parameters are either #define'd or #undef'ed. * They are solely interpretted in #ifdef's and #ifndef's, and the * value of the definition means nothing. These _OPTIONS_'s can be set * on the command line (-D) in the Makefile, or in the O/S specific * header file. * * NDMOS_OPTION_NO_NDMP2 -- omit NDMPv2 support * NDMOS_OPTION_NO_NDMP3 -- omit NDMPv3 support * NDMOS_OPTION_NO_NDMP4 -- omit NDMPv4 support * * NDMOS_OPTION_NO_CONTROL_AGENT -- omit CONTROL agent features * NDMOS_OPTION_NO_DATA_AGENT -- omit DATA agent features * NDMOS_OPTION_NO_ROBOT_AGENT -- omit ROBOT agent features * NDMOS_OPTION_NO_TAPE_AGENT -- omit TAPE agent features * NDMOS_OPTION_NO_TEST_AGENTS -- omit any agent test features * For some purposes, an all-in-one is overkill, or perhaps * impractical. Everything is carefully constructed so * that certain agents can be omitted without disturbing * the rest. The two most obvious uses are to either * keep or omit just the CONTROL agent. * * NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN * The NDMP specification says that both TAPE and SCSI can not * be open at the same time. Then the workflow docs suggest * a separate process for the ROBOT agent to get around the * restriction. #define'ing this breaks the spec and allows * both to be open. * * NDMOS_OPTION_HAVE_SIN_LEN * In preparation for IPv6, some O/Ss use a sin_len field to * indicate the length of the address. This _OPTION_ affects * the standard NDMOS_MACRO_SET_SOCKADDR. * * NDMOS_OPTION_TAPE_SIMULATOR * Early in bring-up on a new system, it's a little easier to * get started by using the tape simulator. It represents * an idealized MTIO-type tape subsystem, and uses a disk * file to represent the tape. As the real O/S specific tape * subsystem interface is implemented (ndmos_tape_...()), the * tape simulator serves as a reference for correct implementation. * * NDMOS_OPTION_ROBOT_SIMULATOR * Similarly, for testing multi-tape operations, it's easier to * get started by using the robot simulator. It represents a simple * robot with ten slots and two drives. It operates on a directory, * and uses rename() to load and unload tapes. It operates in concert * with the tape simulator. The robot name is a directory, and it * creates drives named 'drive0', 'drive1', etc. in that directory * * NDMOS_OPTION_GAP_SIMULATOR * Implement the spinnaker GAP simulator in the tape simulator. * When you want a clean tape stream in the tape simulator disable * this option and the output should only contain the info from * the data agent no fancy Begin Of Tape (BOT) simulation etc. * * NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL -- use common select() code * NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL -- use common poll() code * These two _OPTION_'s choose common code to implement * ndmos_chan_poll(). The select() and poll() functions are * fairly common and consistent among various O/S's to detect * ready I/O. Only one can be defined. If the common code * doesn't work out, don't define either _OPTION_ and implement * ndmos_chan_poll() in the O/S specific C source file. * * NDMOS_OPTION_USE_GETHOSTBYNAME -- use gethostbyname() code * NDMOS_OPTION_USE_GETADDRINFO -- use getaddrinfo() code * These two _OPTION_'s choose common code to implement * the lookup of a host. getaddrinfo() is the new interface * and gethostbyname() is deprecated by POSIX so should only * be used when there is no support for getaddrinfo() */ #if HAVE_POLL #define NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL 1 #else #define NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL 1 #endif #if HAVE_GETADDRINFO #define NDMOS_OPTION_USE_GETADDRINFO 1 #else #define NDMOS_OPTION_USE_GETHOSTBYNAME 1 #endif #define NDMOS_OPTION_TAPE_SIMULATOR 1 #define NDMOS_OPTION_ROBOT_SIMULATOR 1 /* #define NDMOS_OPTION_GAP_SIMULATOR 1 */ /* * Constants */ #ifndef NDMOS_CONST_ALIGN #define NDMOS_CONST_ALIGN sizeof(uint64_t) #endif /* !NDMOS_CONST_ALIGN */ #ifndef NDMOS_CONST_TAPE_REC_MIN #define NDMOS_CONST_TAPE_REC_MIN 1 #endif /* !NDMOS_CONST_TAPE_REC_MIN */ #ifndef NDMOS_CONST_TAPE_REC_MAX #define NDMOS_CONST_TAPE_REC_MAX (1024*1024) #endif /* !NDMOS_CONST_TAPE_REC_MAX */ #ifndef NDMOS_CONST_PATH_MAX #define NDMOS_CONST_PATH_MAX (1024) #endif /* !NDMOS_CONST_PATH_MAX */ #ifndef NDMOS_CONST_EWOULDBLOCK #ifdef EWOULDBLOCK #define NDMOS_CONST_EWOULDBLOCK EWOULDBLOCK #else /* EWOULDBLOCK */ #define NDMOS_CONST_EWOULDBLOCK EAGAIN #endif /* EWOULDBLOCK */ #endif /* !NDMOS_CONST_EWOULDBLOCK */ #ifndef NDMOS_CONST_NDMJOBLIB_REVISION #define NDMOS_CONST_NDMJOBLIB_REVISION "1.4a" #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */ #ifndef NDMOS_CONST_VENDOR_NAME #define NDMOS_CONST_VENDOR_NAME "PublicDomain" #endif /* !NDMOS_CONST_VENDOR_NAME */ #ifndef NDMOS_CONST_PRODUCT_NAME #define NDMOS_CONST_PRODUCT_NAME "NDMJOB" #endif /* !NDMOS_CONST_PRODUCT_NAME */ #ifndef NDMOS_CONST_PRODUCT_REVISION #define NDMOS_CONST_PRODUCT_REVISION "1.4a" #endif /* !NDMOS_CONST_PRODUCT_REVISION */ #ifndef NDMOS_CONST_NDMOS_REVISION #define NDMOS_CONST_NDMOS_REVISION "0" #endif /* !NDMOS_CONST_NDMOS_REVISION */ /* * Application Program Interfaces (APIs) */ #ifndef NDMOS_API_BZERO #define NDMOS_API_BZERO(P,N) (void)bzero((void*)(P),(N)) #endif /* !NDMOS_API_BZERO */ #ifndef NDMOS_API_BCOPY #define NDMOS_API_BCOPY(S,D,N) (void)bcopy((void*)(S),(void*)(D),(N)) #endif /* !NDMOS_API_BCOPY */ #ifndef NDMOS_API_MALLOC #define NDMOS_API_MALLOC(N) malloc(N) #endif /* !NDMOS_API_MALLOC */ #ifndef NDMOS_API_FREE #define NDMOS_API_FREE(P) free((void*)(P)) #endif /* !NDMOS_API_FREE */ #ifndef NDMOS_API_STRTOLL #define NDMOS_API_STRTOLL(P,PP,BASE) strtoll(P,PP,BASE) #endif /* !NDMOS_API_STRTOLL */ #ifndef NDMOS_API_STRDUP #define NDMOS_API_STRDUP(S) strdup(S) #endif /* !NDMOS_API_STRDUP */ #ifndef NDMOS_API_STREND #ifdef __cplusplus extern "C" { #endif extern char *ndml_strend(char *s); /* ndml_util.c */ #ifdef __cplusplus } #endif #define NDMOS_API_STREND(S) ndml_strend(S) #endif /* !NDMOS_API_STREND */ /* * Macros */ #ifndef NDMOS_MACRO_NEW #define NDMOS_MACRO_NEW(T) ((T *) NDMOS_API_MALLOC(sizeof (T))) #endif /* !NDMOS_MACRO_NEW */ #ifndef NDMOS_MACRO_NEWN #define NDMOS_MACRO_NEWN(T,N) ((T *) NDMOS_API_MALLOC(sizeof (T) * (N))) #endif /* !NDMOS_MACRO_NEWN */ #ifndef NDMOS_MACRO_FREE #define NDMOS_MACRO_FREE(T) free(T) #endif #ifndef NDMOS_MACRO_ZEROFILL #define NDMOS_MACRO_ZEROFILL(P) NDMOS_API_BZERO(P,sizeof *(P)) #endif /* !NDMOS_MACRO_ZEROFILL */ #ifndef NDMOS_MACRO_ZEROFILL_SIZE #define NDMOS_MACRO_ZEROFILL_SIZE(P, N) NDMOS_API_BZERO(P, N) #endif /* !NDMOS_MACRO_ZEROFILL_SIZE */ #ifndef NDMOS_MACRO_SRAND #define NDMOS_MACRO_SRAND() srand(time(0)) #endif /* !NDMOS_MACRO_SRAND */ #ifndef NDMOS_MACRO_RAND #define NDMOS_MACRO_RAND() rand() #endif /* !NDMOS_MACRO_RAND */ #ifndef NDMOS_MACRO_OK_TAPE_REC_LEN #define NDMOS_MACRO_OK_TAPE_REC_LEN(LEN) \ (NDMOS_CONST_TAPE_REC_MIN <= (LEN) \ && (LEN) <= NDMOS_CONST_TAPE_REC_MAX) #endif /* !NDMOS_MACRO_OK_TAPE_REC_LEN */ #ifndef NDMOS_MACRO_SET_SOCKADDR #ifdef NDMOS_OPTION_HAVE_SIN_LEN #define NDMOS_MACRO_SET_SOCKADDR(SA,INADDR,PORT) \ ( NDMOS_MACRO_ZEROFILL (SA), \ ((struct sockaddr_in *)(SA))->sin_len = sizeof *(SA), \ ((struct sockaddr_in *)(SA))->sin_family = AF_INET, \ ((struct sockaddr_in *)(SA))->sin_addr.s_addr = htonl(INADDR), \ ((struct sockaddr_in *)(SA))->sin_port = htons(PORT)) #else /* NDMOS_OPTION_HAVE_SIN_LEN */ #define NDMOS_MACRO_SET_SOCKADDR(SA,INADDR,PORT) \ ( NDMOS_MACRO_ZEROFILL (SA), \ ((struct sockaddr_in *)(SA))->sin_family = AF_INET, \ ((struct sockaddr_in *)(SA))->sin_addr.s_addr = htonl(INADDR), \ ((struct sockaddr_in *)(SA))->sin_port = htons(PORT)) #endif /* NDMOS_OPTION_HAVE_SIN_LEN */ #endif /* !NDMOS_MACRO_SET_SOCKADDR */ /* * Composite effects */ #ifdef NDMOS_OPTION_NO_DATA_AGENT #ifdef NDMOS_OPTION_NO_TAPE_AGENT #ifdef NDMOS_OPTION_NO_ROBOT_AGENT #define NDMOS_EFFECT_NO_SERVER_AGENTS #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #endif /* !NDMOS_OPTION_NO_DATA_AGENT */ #ifdef NDMOS_OPTION_NO_NDMP3 #ifdef NDMOS_OPTION_NO_NDMP4 #define NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 #endif /* !NDMOS_OPTION_NO_NDMP3 */ #endif /* !NDMOS_OPTION_NO_NDMP4 */ /* check for a conflict: robot sim requires tape sim */ #ifdef NDMOS_OPTION_ROBOT_SIMULATOR #ifndef NDMOS_OPTION_TAPE_SIMULATOR #error robot simulator requires the tape simulator #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ #ifdef NDMOS_COMMON_SCSI_INTERFACE #error robot simulator and ndmos scsi interface are incompatible #endif #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ /* * simulator fields */ #ifdef NDMOS_OPTION_TAPE_SIMULATOR #define NDMOS_MACRO_TAPE_AGENT_ADDITIONS \ int32_t tape_fd; \ char * drive_name; \ int32_t weof_on_close; \ int32_t sent_leom; #endif /* NDMOS_OPTION_TAPE_SIMULATOR */ #ifdef NDMOS_OPTION_ROBOT_SIMULATOR #undef NDMOS_MACRO_ROBOT_AGENT_ADDITIONS #define NDMOS_MACRO_ROBOT_AGENT_ADDITIONS \ char * sim_dir; #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ #endif /* _NDMOS_H */ bareos-Release-14.2.6/src/ndmp/ndmos_common.c000066400000000000000000000335201263011562700210240ustar00rootroot00000000000000/* * Copyright (c) 1998,2001 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This contains code fragments common between the * O/S (Operating System) portions of NDMJOBLIB. * * This file is #include'd by the O/S specific ndmos_*.c * file, and fragments are selected by #ifdef's. * * There are four major portions: * 1) Misc support routines: password check, local info, etc * 2) Non-blocking I/O support routines * 3) Tape interfacs ndmos_tape_xxx() * 4) OS Specific NDMP request dispatcher which intercepts * requests implemented here, such as SCSI operations * and system configuration queries. */ /* * CONFIG SUPPORT **************************************************************** */ #ifdef NDMOS_COMMON_SYNC_CONFIG_INFO /* * Get local info. Supports NDMPx_CONFIG_GET_HOST_INFO, * NDMP3_CONFIG_GET_SERVER_INFO, and NDMPx_CONFIG_GET_SCSI_INFO. */ void ndmos_sync_config_info (struct ndm_session *sess) { static struct utsname unam; static char osbuf[100]; static char idbuf[30]; static char revbuf[100]; char obuf[5]; if (!sess->config_info) { sess->config_info = (ndmp9_config_info *)NDMOS_API_MALLOC (sizeof (ndmp9_config_info)); if (!sess->config_info) return; } if (sess->config_info->hostname) { /* already set */ return; } obuf[0] = (char)(NDMOS_ID >> 24); obuf[1] = (char)(NDMOS_ID >> 16); obuf[2] = (char)(NDMOS_ID >> 8); obuf[3] = (char)(NDMOS_ID >> 0); obuf[4] = 0; uname (&unam); snprintf (idbuf, sizeof(idbuf), "%lu", gethostid()); /* * give CONTROL via NDMPv2 a chance to recognize this * implementation (no ndmp2_config_get_server). */ snprintf (osbuf, sizeof(osbuf), "%s (running %s from %s)", unam.sysname, NDMOS_CONST_PRODUCT_NAME, NDMOS_CONST_VENDOR_NAME); sess->config_info->hostname = unam.nodename; sess->config_info->os_type = osbuf; sess->config_info->os_vers = unam.release; sess->config_info->hostid = idbuf; sess->config_info->vendor_name = (char *)NDMOS_CONST_VENDOR_NAME; sess->config_info->product_name = (char *)NDMOS_CONST_PRODUCT_NAME; snprintf (revbuf, sizeof(revbuf), "%s LIB:%d.%d/%s OS:%s (%s)", NDMOS_CONST_PRODUCT_REVISION, NDMJOBLIB_VERSION, NDMJOBLIB_RELEASE, NDMOS_CONST_NDMJOBLIB_REVISION, NDMOS_CONST_NDMOS_REVISION, obuf); sess->config_info->revision_number = revbuf; /* best effort; note that this loads scsi and tape config */ if (sess->param->config_file_name) ndmcfg_load (sess->param->config_file_name, sess->config_info); } #endif /* NDMOS_COMMON_SYNC_CONFIG_INFO */ /* * AUTHENTICATION SUPPORT **************************************************************** */ void ndmos_auth_register_callbacks (struct ndm_session *sess, struct ndm_auth_callbacks *callbacks) { /* * Only allow one register. */ if (!sess->nac) { sess->nac = (struct ndm_auth_callbacks *) NDMOS_API_MALLOC (sizeof(struct ndm_auth_callbacks)); if (sess->nac) { memcpy (sess->nac, callbacks, sizeof(struct ndm_auth_callbacks)); } } } void ndmos_auth_unregister_callbacks (struct ndm_session *sess) { if (sess->nac) { NDMOS_API_FREE (sess->nac); sess->nac = NULL; } } #ifdef NDMOS_COMMON_OK_NAME_PASSWORD /* * Determine whether the clear-text account name and password * are valid. Supports NDMPx_CONNECT_CLIENT_AUTH requests. */ int ndmos_ok_name_password (struct ndm_session *sess, char *name, char *pass) { if (sess->nac && sess->nac->validate_password) { return sess->nac->validate_password(sess, name, pass); } return 0; /* NOT OK */ } #endif /* NDMOS_COMMON_OK_NAME_PASSWORD */ #ifdef NDMOS_COMMON_MD5 /* * MD5 authentication support * * See ndml_md5.c */ int ndmos_get_md5_challenge (struct ndm_session *sess) { ndmmd5_generate_challenge (sess->md5_challenge); sess->md5_challenge_valid = 1; return 0; } int ndmos_ok_name_md5_digest (struct ndm_session *sess, char *name, char digest[16]) { if (sess->nac && sess->nac->validate_md5) { return sess->nac->validate_md5(sess, name, digest); } return 0; /* NOT OK */ } #endif /* NDMOS_COMMON_MD5 */ #ifdef NDMOS_COMMON_NONBLOCKING_IO_SUPPORT /* * NON-BLOCKING I/O SUPPORT **************************************************************** * As support non-blocking I/O for NDMCHAN, condition different * types of file descriptors to not block. */ void ndmos_condition_listen_socket (struct ndm_session *sess, int sock) { int flag; flag = 1; setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, sizeof flag); } void ndmos_condition_control_socket (struct ndm_session *sess, int sock) { /* nothing */ } void ndmos_condition_image_stream_socket (struct ndm_session *sess, int sock) { fcntl (sock, F_SETFL, O_NONBLOCK); signal (SIGPIPE, SIG_IGN); } void ndmos_condition_pipe_fd (struct ndm_session *sess, int fd) { fcntl (fd, F_SETFL, O_NONBLOCK); signal (SIGPIPE, SIG_IGN); } #endif /* NDMOS_COMMON_NONBLOCKING_IO_SUPPORT */ #ifdef NDMOS_COMMON_TAPE_INTERFACE #ifndef NDMOS_OPTION_NO_TAPE_AGENT #ifndef NDMOS_OPTION_TAPE_SIMULATOR /* * TAPE INTERFACE **************************************************************** * These interface to the O/S specific tape drivers and subsystem. * They must result in functionality equivalent to the reference * tape simulator. The NDMP TAPE model is demanding, and it is * often necessary to workaround the native device driver(s) * to achieve NDMP TAPE model conformance. * * It's easy to test this ndmos_tape_xxx() implementation * using the ndmjob(1) command in test-tape conformance mode. * The tape simulator passes this test. To test this implementation, * rebuild ndmjob, then use this command: * * ndmjob -o test-tape -T. -f /dev/whatever * * These ndmos_tape_xxx() interfaces must maintain the tape state * (sess->tape_agent.tape_state). In particular, the position * information (file_num and blockno) must be accurate at all * times. A typical workaround is to maintain these here rather * than relying on the native device drivers. Another workaround * is to implement NDMP MTIO operations using repeated native MTIO * operations with count=1, then interpret the results and errors * to maintain accurate position and residual information. * * Workarounds in this implementation (please keep this updated): * */ int ndmos_tape_initialize (struct ndm_session *sess) { return -1; } void ndmos_tape_sync_state (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; ta->tape_state.error = NDMP9_DEV_NOT_OPEN_ERR; } ndmp9_error ndmos_tape_open (struct ndm_session *sess, char *name, int will_write) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_tape_close (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_tape_write (struct ndm_session *sess, char *data, uint32_t count, uint32_t * done_count) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_tape_read (struct ndm_session *sess, char *data, uint32_t count, uint32_t * done_count) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_tape_mtio (struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t * done_count) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_tape_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { return NDMP9_NOT_SUPPORTED_ERR; } #endif /* !NDMOS_OPTION_TAPE_SIMULATOR */ #else /* !NDMOS_OPTION_NO_TAPE_AGENT */ /* tape interfaces implemented in ndma_tape_simulator.c */ #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ #endif /* NDMOS_COMMON_TAPE_INTERFACE */ #ifdef NDMOS_COMMON_ROBOT_INTERFACE #ifndef NDMOS_OPTION_NO_ROBOT_AGENT #ifndef NDMOS_OPTION_ROBOT_SIMULATOR /* ndmos_robot_* functions here */ #endif /* !NDMOS_OPTION_ROBOT_SIMULATOR */ #else /* !NDMOS_OPTION_NO_ROBOT_AGENT */ /* robot interfaces implemented in ndma_robot_simulator.c */ #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */ #endif /* NDMOS_COMMON_ROBOT_INTERFACE */ #ifdef NDMOS_COMMON_SCSI_INTERFACE #ifndef NDMOS_OPTION_NO_ROBOT_AGENT /* Surrounds all SCSI intfs */ #ifndef NDMOS_OPTION_ROBOT_SIMULATOR /* * SCSI INTERFACE **************************************************************** */ int ndmos_scsi_initialize (struct ndm_session *sess) { return -1; } void ndmos_scsi_sync_state (struct ndm_session *sess) { sess->robot_acb->scsi_state.error = NDMP9_DEV_NOT_OPEN_ERR; } ndmp9_error ndmos_scsi_open (struct ndm_session *sess, char *name) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_close (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } /* deprecated */ ndmp9_error ndmos_scsi_set_target (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_reset_device (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } /* deprecated */ ndmp9_error ndmos_scsi_reset_bus (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { return NDMP9_NOT_SUPPORTED_ERR; } #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ #endif /* NDMOS_OPTION_NO_ROBOT_AGENT Surrounds all SCSI intfs */ #endif /* NDMOS_COMMON_SCSI_INTERFACE */ #ifdef NDMOS_COMMON_DISPATCH_REQUEST /* * ndmos_dispatch_request() -- O/S Specific Agent Dispatch Request (ADR) **************************************************************** * Some NDMP requests can only be handled as O/S specific portions, * and are implemented here. * * The more generic NDMP requests may be re-implemented here rather * than modifying the main body of code. Extensions to the NDMP protocol * may also be implemented here. Neither is ever a good idea beyond * experimentation. The structures in ndmagents.h provide for O/S * specific extensions. Such extensions are #define'd in the ndmos_xxx.h. * * The return value from ndmos_dispatch_request() tells the main * dispatcher, ndma_dispatch_request(), whether or not the request * was intercepted. ndmos_dispatch_request() is called after basic * reply setup is done (message headers and buffers), but before * the request is interpretted. */ #ifndef I_HAVE_DISPATCH_REQUEST /* * If we're not intercepting, keep it simple */ int ndmos_dispatch_request (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { return -1; /* not intercepted */ } #else /* !I_HAVE_DISPATCH_REQUEST */ /* * The following fragment is here for reference. * If the O/S module intercepts requests, copy * all this into the module source file and * #undef NDMOS_COMMON_DISPATCH_REQUEST. */ extern struct ndm_dispatch_version_table ndmos_dispatch_version_table[]; int ndmos_dispatch_request (struct ndm_session *sess, struct ndmp_xa_buf *xa, struct ndmconn *ref_conn) { struct ndm_dispatch_request_table *drt; unsigned protocol_version = ref_conn->protocol_version; unsigned msg = xa->request.header.message; int rc; drt = ndma_drt_lookup (ndmos_dispatch_version_table, protocol_version, msg); if (!drt) { return -1; /* not intercepted */ } /* * Replicate the ndma_dispatch_request() permission checks */ if (!sess->conn_open && !(drt->flags & NDM_DRT_FLAG_OK_NOT_CONNECTED)) { xa->reply.header.error = NDMP0_PERMISSION_ERR; return 0; } if (!sess->conn_authorized && !(drt->flags & NDM_DRT_FLAG_OK_NOT_AUTHORIZED)) { xa->reply.header.error = NDMP9_NOT_AUTHORIZED_ERR; return 0; } rc = (*drt->dispatch_request)(sess, xa, ref_conn); if (rc < 0) { xa->reply.header.error = NDMP0_NOT_SUPPORTED_ERR; } return 0; } /* * Dispatch Version Table and Dispatch Request Tables (DVT/DRT) **************************************************************** */ struct ndm_dispatch_request_table ndmos_dispatch_request_table_v0[] = { {0} }; #ifndef NDMOS_OPTION_NO_NDMP2 struct ndm_dispatch_request_table ndmos_dispatch_request_table_v2[] = { {0} }; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 struct ndm_dispatch_request_table ndmos_dispatch_request_table_v3[] = { {0} }; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 struct ndm_dispatch_request_table ndmos_dispatch_request_table_v4[] = { {0} }; #endif /* !NDMOS_OPTION_NO_NDMP4 */ struct ndm_dispatch_version_table ndmos_dispatch_version_table[] = { { 0, ndmos_dispatch_request_table_v0 }, #ifndef NDMOS_OPTION_NO_NDMP2 { NDMP2VER, ndmos_dispatch_request_table_v2 }, #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 { NDMP3VER, ndmos_dispatch_request_table_v3 }, #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP4 { NDMP4VER, ndmos_dispatch_request_table_v4 }, #endif /* !NDMOS_OPTION_NO_NDMP4 */ { -1 } }; #endif /* !I_HAVE_DISPATCH_REQUEST */ #endif /* NDMOS_COMMON_DISPATCH_REQUEST */ bareos-Release-14.2.6/src/ndmp/ndmos_freebsd.c000066400000000000000000000173731263011562700211560ustar00rootroot00000000000000/* * Copyright (c) 1998,2001 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This contains the O/S (Operating System) specific * portions of NDMJOBLIB for the FreeBSD platform. * * This file is #include'd by ndmos.c when * selected by #ifdef's of NDMOS_ID. * * There are four major portions: * 1) Misc support routines: password check, local info, etc * 2) Non-blocking I/O support routines * 3) Tape interfacs ndmos_tape_xxx() * 4) OS Specific NDMP request dispatcher which intercepts * requests implemented here, such as SCSI operations * and system configuration queries. */ /* * #include "ndmagents.h" already done in ndmos.c * Additional #include's, not needed in ndmos_freebsd.h, yet needed here. */ #include #include #include /* * Select common code fragments from ndmos_common.c */ #define NDMOS_COMMON_SYNC_CONFIG_INFO /* from config file (ndmjob.conf) */ #define NDMOS_COMMON_OK_NAME_PASSWORD #define NDMOS_COMMON_MD5 #define NDMOS_COMMON_NONBLOCKING_IO_SUPPORT #define NDMOS_COMMON_TAPE_INTERFACE /* uses tape simulator */ #define NDMOS_COMMON_SCSI_INTERFACE /* use scsi simulator */ #define NDMOS_COMMON_DISPATCH_REQUEST /* no-op */ #include "ndmos_common.c" #ifdef NDMOS_COMMON_SCSI_INTERFACE #ifndef NDMOS_OPTION_NO_ROBOT_AGENT /* Surrounds all SCSI intfs */ #ifndef NDMOS_OPTION_ROBOT_SIMULATOR /* * SCSI INTERFACE **************************************************************** */ int ndmos_scsi_initialize (struct ndm_session *sess) { sess->robot_acb->camdev = 0; return 0; } void ndmos_scsi_sync_state (struct ndm_session *sess) { struct ndm_robot_agent * robot = sess->robot_acb; struct cam_device * camdev = robot->camdev; ndmp9_scsi_get_state_reply * state = &robot->scsi_state; if (robot->camdev) { state->error = NDMP9_NO_ERR; state->target_controller = camdev->path_id; state->target_id = camdev->target_id; state->target_lun = camdev->target_lun; } else { state->error = NDMP9_DEV_NOT_OPEN_ERR; state->target_controller = -1; state->target_id = -1; state->target_lun = -1; } } ndmp9_error ndmos_scsi_open (struct ndm_session *sess, char *name) { struct ndm_robot_agent * robot = sess->robot_acb; struct cam_device * camdev = robot->camdev; /* redundant test */ if (camdev) { return NDMP9_DEVICE_OPENED_ERR; } camdev = cam_open_pass(name, 2, 0); if (!camdev) { /* could sniff errno */ switch (errno) { default: case ENOENT: return NDMP9_NO_DEVICE_ERR; case EACCES: case EPERM: return NDMP9_PERMISSION_ERR; case EBUSY: return NDMP9_DEVICE_BUSY_ERR; } } robot->camdev = camdev; ndmos_scsi_sync_state (sess); return NDMP9_NO_ERR; } ndmp9_error ndmos_scsi_close (struct ndm_session *sess) { struct ndm_robot_agent * robot = sess->robot_acb; struct cam_device * camdev = robot->camdev; /* redundant test */ if (!camdev) { return NDMP9_DEV_NOT_OPEN_ERR; } robot->camdev = 0; ndmos_scsi_sync_state (sess); cam_close_device (camdev); return NDMP9_NO_ERR; } /* deprecated */ ndmp9_error ndmos_scsi_set_target (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_reset_device (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } /* deprecated */ ndmp9_error ndmos_scsi_reset_bus (struct ndm_session *sess) { return NDMP9_NOT_SUPPORTED_ERR; } ndmp9_error ndmos_scsi_execute_cdb (struct ndm_session *sess, ndmp9_execute_cdb_request *request, ndmp9_execute_cdb_reply *reply) { struct ndm_robot_agent *robot = sess->robot_acb; struct cam_device * camdev = robot->camdev; union ccb * ccb; u_int32_t flags; u_int8_t * data_ptr = 0; u_int8_t * data_in_ptr = 0; u_int32_t data_len = 0; u_int32_t data_done; int rc; NDMOS_MACRO_ZEROFILL (reply); reply->error = NDMP9_IO_ERR; /* pessimistic */ ccb = cam_getccb(camdev); if (!ccb) { reply->error = NDMP9_NO_MEM_ERR; return reply->error; } switch (request->data_dir) { case NDMP9_SCSI_DATA_DIR_NONE: flags = CAM_DIR_NONE; break; case NDMP9_SCSI_DATA_DIR_IN: if (data_len > 1024*1024) { reply->error = NDMP9_ILLEGAL_ARGS_ERR; goto out; } data_len = request->datain_len; data_in_ptr = (u_int8_t *)malloc (data_len); if (!data_in_ptr) { reply->error = NDMP9_NO_MEM_ERR; goto out; } data_ptr = data_in_ptr; flags = CAM_DIR_IN; break; case NDMP9_SCSI_DATA_DIR_OUT: data_len = request->dataout.dataout_len; data_ptr = (u_int8_t *)request->dataout.dataout_val; flags = CAM_DIR_OUT; break; default: return NDMP9_ILLEGAL_ARGS_ERR; break; } bcopy(request->cdb.cdb_val, &ccb->csio.cdb_io.cdb_bytes, request->cdb.cdb_len); cam_fill_csio(&ccb->csio, /*retries*/ 1, /*cbfcnp*/ NULL, /*flags*/ flags, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*data_ptr*/ data_ptr, /*dxfer_len*/ data_len, /*sense_len*/ SSD_FULL_SIZE, /*cdb_len*/ request->cdb.cdb_len, /*timeout*/ request->timeout); rc = cam_send_ccb (camdev, ccb); if (rc != 0) { reply->error = NDMP9_IO_ERR; goto out; } switch (ccb->csio.ccb_h.status & CAM_STATUS_MASK) { case CAM_REQ_CMP: /* completed */ reply->error = NDMP9_NO_ERR; break; case CAM_SEL_TIMEOUT: case CAM_CMD_TIMEOUT: reply->error = NDMP9_TIMEOUT_ERR; break; case CAM_SCSI_STATUS_ERROR: if (ccb->csio.ccb_h.status & CAM_AUTOSNS_VALID) { int n_sense; n_sense = ccb->csio.sense_len - ccb->csio.sense_resid; reply->ext_sense.ext_sense_val = (char *)malloc (n_sense); if (reply->ext_sense.ext_sense_val) { bcopy (&ccb->csio.sense_data, reply->ext_sense.ext_sense_val, n_sense); reply->ext_sense.ext_sense_len = n_sense; } } reply->error = NDMP9_NO_ERR; break; default: reply->error = NDMP9_IO_ERR; break; } out: if (reply->error == NDMP9_NO_ERR) { reply->status = ccb->csio.scsi_status; data_done = data_len - ccb->csio.resid; switch (request->data_dir) { case NDMP9_SCSI_DATA_DIR_NONE: break; case NDMP9_SCSI_DATA_DIR_IN: reply->datain.datain_val = (char *)data_in_ptr; reply->datain.datain_len = data_len; break; case NDMP9_SCSI_DATA_DIR_OUT: reply->dataout_len = data_len; break; default: break; } } else { if (data_in_ptr) { free (data_in_ptr); data_in_ptr = 0; } } cam_freeccb (ccb); return reply->error; } #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */ #endif /* NDMOS_OPTION_NO_ROBOT_AGENT Surrounds all SCSI intfs */ #endif /* NDMOS_COMMON_SCSI_INTERFACE */ bareos-Release-14.2.6/src/ndmp/ndmos_freebsd.h000066400000000000000000000062141263011562700211530ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This establishes the environment and options * for the FreeBSD platform. This, combined with * the O/S generic ndmos.h, are the foundation * for NDMJOBLIB. * * This file is #include'd by ndmos.h when * selected by #ifdef's of NDMOS_ID. * * Refer to ndmos.h for explanations of the * macros thar are or can be #define'd here. */ #define NDMOS_ID_FREEBSD NDMOS_IDENT('F','B','s','d') #ifndef NDMOS_ID #ifdef __FreeBSD__ #define NDMOS_ID NDMOS_ID_FREEBSD #endif /* __FreeBSD__ */ #endif /* !NDMOS_ID */ #if NDMOS_ID == NDMOS_ID_FREEBSD /* probably redundant */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NDMOS_OPTION_HAVE_SIN_LEN #define NDMOS_API_STRTOLL(P,PP,BASE) strtoq(P,PP,BASE) /* * #ifndef'ed so they can be set from the Makefile command line */ #ifndef NDMOS_CONST_NDMJOBLIB_REVISION #define NDMOS_CONST_NDMJOBLIB_REVISION "0" #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */ #ifndef NDMOS_CONST_VENDOR_NAME #define NDMOS_CONST_VENDOR_NAME "PublicDomain" #endif /* !NDMOS_CONST_VENDOR_NAME */ #ifndef NDMOS_CONST_PRODUCT_NAME #define NDMOS_CONST_PRODUCT_NAME "NDMJOB" #endif /* !NDMOS_CONST_PRODUCT_NAME */ #ifndef NDMOS_CONST_PRODUCT_REVISION #define NDMOS_CONST_PRODUCT_REVISION "0.0" #endif /* !NDMOS_CONST_PRODUCT_REVISION */ #define NDMOS_CONST_NDMOS_REVISION "FreeBSD-04xx" #define NDMOS_MACRO_ROBOT_AGENT_ADDITIONS \ struct cam_device * camdev; #endif /* NDMOS_ID == NDMOS_ID_FREEBSD */ bareos-Release-14.2.6/src/ndmp/ndmos_linux.c000066400000000000000000000050141263011562700206700ustar00rootroot00000000000000/* * Copyright (c) 1998,2001 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This contains the O/S (Operating System) specific * portions of NDMJOBLIB for the Linux platform. * * This file is #include'd by ndmos.c when * selected by #ifdef's of NDMOS_ID. * * There are four major portions: * 1) Misc support routines: password check, local info, etc * 2) Non-blocking I/O support routines * 3) Tape interfacs ndmos_tape_xxx() * 4) OS Specific NDMP request dispatcher which intercepts * requests implemented here, such as SCSI operations * and system configuration queries. */ /* * #include "ndmagents.h" already done in ndmos.c * Additional #include's, not needed in ndmos_linux.h, yet needed here. */ #include /* * Select common code fragments from ndmos_common.c */ #define NDMOS_COMMON_SYNC_CONFIG_INFO /* from config file (ndmjob.conf) */ #define NDMOS_COMMON_OK_NAME_PASSWORD #define NDMOS_COMMON_MD5 #define NDMOS_COMMON_NONBLOCKING_IO_SUPPORT #define NDMOS_COMMON_TAPE_INTERFACE /* uses tape simulator */ #define NDMOS_COMMON_SCSI_INTERFACE /* stub-out */ #define NDMOS_COMMON_DISPATCH_REQUEST /* no-op */ #include "ndmos_common.c" bareos-Release-14.2.6/src/ndmp/ndmos_linux.h000066400000000000000000000061361263011562700207030ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This establishes the environment and options * for the FreeBSD platform. This, combined with * the O/S generic ndmos.h, are the foundation * for NDMJOBLIB. * * This file is #include'd by ndmos.h when * selected by #ifdef's of NDMOS_ID. * * Refer to ndmos.h for explanations of the * macros thar are or can be #define'd here. */ #define NDMOS_ID_LINUX NDMOS_IDENT('L','n','u','x') #ifndef NDMOS_ID #ifdef __linux__ #define NDMOS_ID NDMOS_ID_LINUX #endif /* __linux__ */ #endif /* !NDMOS_ID */ #if NDMOS_ID == NDMOS_ID_LINUX /* probably redundant */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef NDMOS_OPTION_HAVE_SIN_LEN #define NDMOS_API_STRTOLL(P,PP,BASE) strtoq(P,PP,BASE) /* * #ifndef'ed so they can be set from the Makefile command line */ #ifndef NDMOS_CONST_NDMJOBLIB_REVISION #define NDMOS_CONST_NDMJOBLIB_REVISION "0" #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */ #ifndef NDMOS_CONST_VENDOR_NAME #define NDMOS_CONST_VENDOR_NAME "PublicDomain" #endif /* !NDMOS_CONST_VENDOR_NAME */ #ifndef NDMOS_CONST_PRODUCT_NAME #define NDMOS_CONST_PRODUCT_NAME "NDMJOB" #endif /* !NDMOS_CONST_PRODUCT_NAME */ #ifndef NDMOS_CONST_PRODUCT_REVISION #define NDMOS_CONST_PRODUCT_REVISION "0.0" #endif /* !NDMOS_CONST_PRODUCT_REVISION */ #define NDMOS_CONST_NDMOS_REVISION "Linux-xxxx" #endif /* NDMOS_ID == NDMOS_ID_FREEBSD */ bareos-Release-14.2.6/src/ndmp/ndmos_solaris.c000066400000000000000000000050141263011562700212050ustar00rootroot00000000000000/* * Copyright (c) 1998,2001 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This contains the O/S (Operating System) specific * portions of NDMJOBLIB for the Solaris platform. * * This file is #include'd by ndmos.c when * selected by #ifdef's of NDMOS_ID. * * There are four major portions: * 1) Misc support routines: password check, local info, etc * 2) Non-blocking I/O support routines * 3) Tape interfacs ndmos_tape_xxx() * 4) OS Specific NDMP request dispatcher which intercepts * requests implemented here, such as SCSI operations * and system configuration queries. */ /* * #include "ndmagents.h" already done in ndmos.c * Additional #include's, not needed in ndmos_xxx.h, yet needed here. */ #include /* * Select common code fragments from ndmos_common.c */ #define NDMOS_COMMON_SYNC_CONFIG_INFO /* from config file (ndmjob.conf) */ #define NDMOS_COMMON_OK_NAME_PASSWORD #define NDMOS_COMMON_MD5 #define NDMOS_COMMON_NONBLOCKING_IO_SUPPORT #define NDMOS_COMMON_TAPE_INTERFACE /* uses tape simulator */ #define NDMOS_COMMON_SCSI_INTERFACE /* stub-out */ #define NDMOS_COMMON_DISPATCH_REQUEST /* no-op */ #include "ndmos_common.c" bareos-Release-14.2.6/src/ndmp/ndmos_solaris.h000066400000000000000000000062021263011562700212120ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This establishes the environment and options * for the Solaris platform. This, combined with * the O/S generic ndmos.h, are the foundation * for NDMJOBLIB. * * This file is #include'd by ndmos.h when * selected by #ifdef's of NDMOS_ID. * * Refer to ndmos.h for explanations of the * macros thar are or can be #define'd here. */ #define NDMOS_ID_SOLARIS NDMOS_IDENT('S','o','l','a') #ifndef NDMOS_ID #ifdef __sun__ #define NDMOS_ID NDMOS_ID_SOLARIS #endif /* __sun__ */ #endif /* !NDMOS_ID */ #if NDMOS_ID == NDMOS_ID_SOLARIS /* probably redundant */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef INADDR_NONE #define INADDR_NONE ((in_addr_t)-1) #endif #undef NDMOS_OPTION_HAVE_SIN_LEN #define NDMOS_API_STRTOLL(P,PP,BASE) strtoll(P,PP,BASE) /* * #ifndef'ed so they can be set from the Makefile command line */ #ifndef NDMOS_CONST_NDMJOBLIB_REVISION #define NDMOS_CONST_NDMJOBLIB_REVISION "0" #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */ #ifndef NDMOS_CONST_VENDOR_NAME #define NDMOS_CONST_VENDOR_NAME "PublicDomain" #endif /* !NDMOS_CONST_VENDOR_NAME */ #ifndef NDMOS_CONST_PRODUCT_NAME #define NDMOS_CONST_PRODUCT_NAME "NDMJOB" #endif /* !NDMOS_CONST_PRODUCT_NAME */ #ifndef NDMOS_CONST_PRODUCT_REVISION #define NDMOS_CONST_PRODUCT_REVISION "0.0" #endif /* !NDMOS_CONST_PRODUCT_REVISION */ #define NDMOS_CONST_NDMOS_REVISION "Solaris-0002xx" #endif /* NDMOS_ID == NDMOS_ID_SOLARIS */ bareos-Release-14.2.6/src/ndmp/ndmp0.x000066400000000000000000000124151263011562700173770ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * NDMPv0, represented here, is a ficticious version * used to negotiate NDMP protocol version for the * remainder of the session. Early, as a connection is * being set up, the version of the protocol is unknown. * The first messages exchanged negotiate the protocol * version, and such messages are in the NDMP format. * This is different than other protocols, such as ONC RPC * which negotiate version by lower layers before the * objective protocol becomes involved. During the * negotiation, we deem the connection to be in "v0" mode. * This NDMPv0 protocol specification is the subset of * the NDMP protocol(s) required for the negotiation, * and necessarily must remain immutable for all time. */ /* * Copyright (c) 1997 Network Appliance. All Rights Reserved. * * Network Appliance makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. * */ %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 %#pragma GCC diagnostic ignored "-Wunused-variable" %#endif const NDMPPORT = 10000; enum ndmp0_error { NDMP0_NO_ERR, /* No error */ NDMP0_NOT_SUPPORTED_ERR, /* Call is not supported */ NDMP0_DEVICE_BUSY_ERR, /* The device is in use */ NDMP0_DEVICE_OPENED_ERR, /* Another tape or scsi device * is already open */ NDMP0_NOT_AUTHORIZED_ERR, /* connection has not been authorized*/ NDMP0_PERMISSION_ERR, /* some sort of permission problem */ NDMP0_DEV_NOT_OPEN_ERR, /* SCSI device is not open */ NDMP0_IO_ERR, /* I/O error */ NDMP0_TIMEOUT_ERR, /* command timed out */ NDMP0_ILLEGAL_ARGS_ERR, /* illegal arguments in request */ NDMP0_NO_TAPE_LOADED_ERR, /* Cannot open because there is no tape loaded */ NDMP0_WRITE_PROTECT_ERR, /* tape cannot be open for write */ NDMP0_EOF_ERR, /* Command encountered EOF */ NDMP0_EOM_ERR, /* Command encountered EOM */ NDMP0_FILE_NOT_FOUND_ERR, /* File not found during restore */ NDMP0_BAD_FILE_ERR, /* The file descriptor is invalid */ NDMP0_NO_DEVICE_ERR, /* The device is not at that target */ NDMP0_NO_BUS_ERR, /* Invalid controller */ NDMP0_XDR_DECODE_ERR, /* Can't decode the request argument */ NDMP0_ILLEGAL_STATE_ERR, /* Call can't be done at this state */ NDMP0_UNDEFINED_ERR, /* Undefined Error */ NDMP0_XDR_ENCODE_ERR, /* Can't encode the reply argument */ NDMP0_NO_MEM_ERR /* no memory */ }; enum ndmp0_header_message_type { NDMP0_MESSAGE_REQUEST, NDMP0_MESSAGE_REPLY }; enum ndmp0_message { NDMP0_CONNECT_OPEN = 0x900, /* CONNECT INTERFACE */ NDMP0_CONNECT_CLOSE = 0x902, NDMP0_NOTIFY_CONNECTED = 0x502 }; struct ndmp0_header { uint32_t sequence; /* monotonically increasing */ uint32_t time_stamp; /* time stamp of message */ ndmp0_header_message_type message_type; /* what type of message */ ndmp0_message message; /* message number */ uint32_t reply_sequence; /* reply is in response to */ ndmp0_error error; /* communications errors */ }; /**********************/ /* CONNECT INTERFACE */ /**********************/ /* NDMP0_CONNECT_OPEN */ struct ndmp0_connect_open_request { uint16_t protocol_version; /* the version of protocol supported */ }; struct ndmp0_connect_open_reply { ndmp0_error error; }; /* NDMP0_CONNECT_CLOSE */ /* no request arguments */ /* no reply arguments */ /****************************/ /* NOTIFY INTERFACE */ /****************************/ /* NDMP0_NOTIFY_CONNECTED */ enum ndmp0_connect_reason { NDMP0_CONNECTED, /* Connect sucessfully */ NDMP0_SHUTDOWN, /* Connection shutdown */ NDMP0_REFUSED /* reach the maximum number of connections */ }; struct ndmp0_notify_connected_request { ndmp0_connect_reason reason; uint16_t protocol_version; string text_reason<>; }; bareos-Release-14.2.6/src/ndmp/ndmp0_enum_strs.c000066400000000000000000000122101263011562700214420ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" extern struct ndmp_enum_str_table ndmp0_error_table[]; extern char * ndmp0_error_to_str (ndmp0_error val); extern int ndmp0_error_from_str (ndmp0_error *valp, char *str); char * ndmp0_error_to_str (ndmp0_error val) { return ndmp_enum_to_str ((int)val, ndmp0_error_table); } int ndmp0_error_from_str (ndmp0_error *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp0_error_table); } struct ndmp_enum_str_table ndmp0_error_table[] = { { "NDMP0_NO_ERR", NDMP0_NO_ERR, }, { "NDMP0_NOT_SUPPORTED_ERR", NDMP0_NOT_SUPPORTED_ERR, }, { "NDMP0_DEVICE_BUSY_ERR", NDMP0_DEVICE_BUSY_ERR, }, { "NDMP0_DEVICE_OPENED_ERR", NDMP0_DEVICE_OPENED_ERR, }, { "NDMP0_NOT_AUTHORIZED_ERR", NDMP0_NOT_AUTHORIZED_ERR, }, { "NDMP0_PERMISSION_ERR", NDMP0_PERMISSION_ERR, }, { "NDMP0_DEV_NOT_OPEN_ERR", NDMP0_DEV_NOT_OPEN_ERR, }, { "NDMP0_IO_ERR", NDMP0_IO_ERR, }, { "NDMP0_TIMEOUT_ERR", NDMP0_TIMEOUT_ERR, }, { "NDMP0_ILLEGAL_ARGS_ERR", NDMP0_ILLEGAL_ARGS_ERR, }, { "NDMP0_NO_TAPE_LOADED_ERR", NDMP0_NO_TAPE_LOADED_ERR, }, { "NDMP0_WRITE_PROTECT_ERR", NDMP0_WRITE_PROTECT_ERR, }, { "NDMP0_EOF_ERR", NDMP0_EOF_ERR, }, { "NDMP0_EOM_ERR", NDMP0_EOM_ERR, }, { "NDMP0_FILE_NOT_FOUND_ERR", NDMP0_FILE_NOT_FOUND_ERR, }, { "NDMP0_BAD_FILE_ERR", NDMP0_BAD_FILE_ERR, }, { "NDMP0_NO_DEVICE_ERR", NDMP0_NO_DEVICE_ERR, }, { "NDMP0_NO_BUS_ERR", NDMP0_NO_BUS_ERR, }, { "NDMP0_XDR_DECODE_ERR", NDMP0_XDR_DECODE_ERR, }, { "NDMP0_ILLEGAL_STATE_ERR", NDMP0_ILLEGAL_STATE_ERR, }, { "NDMP0_UNDEFINED_ERR", NDMP0_UNDEFINED_ERR, }, { "NDMP0_XDR_ENCODE_ERR", NDMP0_XDR_ENCODE_ERR, }, { "NDMP0_NO_MEM_ERR", NDMP0_NO_MEM_ERR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp0_header_message_type_table[]; extern char * ndmp0_header_message_type_to_str (ndmp0_header_message_type val); extern int ndmp0_header_message_type_from_str (ndmp0_header_message_type *valp, char *str); char * ndmp0_header_message_type_to_str (ndmp0_header_message_type val) { return ndmp_enum_to_str ((int)val, ndmp0_header_message_type_table); } int ndmp0_header_message_type_from_str (ndmp0_header_message_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp0_header_message_type_table); } struct ndmp_enum_str_table ndmp0_header_message_type_table[] = { { "NDMP0_MESSAGE_REQUEST", NDMP0_MESSAGE_REQUEST, }, { "NDMP0_MESSAGE_REPLY", NDMP0_MESSAGE_REPLY, }, { 0 } }; extern struct ndmp_enum_str_table ndmp0_message_table[]; extern char * ndmp0_message_to_str (ndmp0_message val); extern int ndmp0_message_from_str (ndmp0_message *valp, char *str); char * ndmp0_message_to_str (ndmp0_message val) { return ndmp_enum_to_str ((int)val, ndmp0_message_table); } int ndmp0_message_from_str (ndmp0_message *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp0_message_table); } struct ndmp_enum_str_table ndmp0_message_table[] = { { "NDMP0_CONNECT_OPEN", NDMP0_CONNECT_OPEN, }, { "NDMP0_CONNECT_CLOSE", NDMP0_CONNECT_CLOSE, }, { "NDMP0_NOTIFY_CONNECTED", NDMP0_NOTIFY_CONNECTED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp0_connect_reason_table[]; extern char * ndmp0_connect_reason_to_str (ndmp0_connect_reason val); extern int ndmp0_connect_reason_from_str (ndmp0_connect_reason *valp, char *str); char * ndmp0_connect_reason_to_str (ndmp0_connect_reason val) { return ndmp_enum_to_str ((int)val, ndmp0_connect_reason_table); } int ndmp0_connect_reason_from_str (ndmp0_connect_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp0_connect_reason_table); } struct ndmp_enum_str_table ndmp0_connect_reason_table[] = { { "NDMP0_CONNECTED", NDMP0_CONNECTED, }, { "NDMP0_SHUTDOWN", NDMP0_SHUTDOWN, }, { "NDMP0_REFUSED", NDMP0_REFUSED, }, { 0 } }; bareos-Release-14.2.6/src/ndmp/ndmp0_enum_strs.h000066400000000000000000000043521263011562700214570ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ extern struct ndmp_enum_str_table ndmp0_error_table[]; extern char * ndmp0_error_to_str (ndmp0_error val); extern int ndmp0_error_from_str (ndmp0_error *valp, char *str); extern struct ndmp_enum_str_table ndmp0_header_message_type_table[]; extern char * ndmp0_header_message_type_to_str (ndmp0_header_message_type val); extern int ndmp0_header_message_type_from_str (ndmp0_header_message_type *valp, char *str); extern struct ndmp_enum_str_table ndmp0_message_table[]; extern char * ndmp0_message_to_str (ndmp0_message val); extern int ndmp0_message_from_str (ndmp0_message *valp, char *str); extern struct ndmp_enum_str_table ndmp0_connect_reason_table[]; extern char * ndmp0_connect_reason_to_str (ndmp0_connect_reason val); extern int ndmp0_connect_reason_from_str (ndmp0_connect_reason *valp, char *str); bareos-Release-14.2.6/src/ndmp/ndmp0_pp.c000066400000000000000000000063611263011562700200540ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" int ndmp0_pp_header (void *data, char *buf) { ndmp0_header * mh = (ndmp0_header *) data; if (mh->message_type == NDMP0_MESSAGE_REQUEST) { sprintf (buf, "C %s %lu", ndmp0_message_to_str (mh->message), mh->sequence); } else if (mh->message_type == NDMP0_MESSAGE_REPLY) { sprintf (buf, "R %s %lu (%lu)", ndmp0_message_to_str (mh->message), mh->reply_sequence, mh->sequence); if (mh->error != NDMP0_NO_ERR) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp0_error_to_str (mh->error)); return 0; /* no body */ } } else { strcpy (buf, "??? INVALID MESSAGE TYPE"); return -1; /* no body */ } return 1; /* body */ } int ndmp0_pp_request (ndmp0_message msg, void *data, int lineno, char *buf) { switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP0_CONNECT_OPEN: NDMP_PP_WITH(ndmp0_connect_open_request) sprintf (buf, "version=%d", p->protocol_version); NDMP_PP_ENDWITH break; case NDMP0_CONNECT_CLOSE: *buf = 0; /* no body */ return 0; case NDMP0_NOTIFY_CONNECTED: NDMP_PP_WITH(ndmp0_notify_connected_request) sprintf (buf, "reason=%s protocol_version=%d text_reason='%s'", ndmp0_connect_reason_to_str(p->reason), p->protocol_version, p->text_reason); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } int ndmp0_pp_reply (ndmp0_message msg, void *data, int lineno, char *buf) { switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP0_CONNECT_OPEN: NDMP_PP_WITH(ndmp0_error) sprintf (buf, "error=%s", ndmp0_error_to_str(*p)); NDMP_PP_ENDWITH break; case NDMP0_NOTIFY_CONNECTED: strcpy (buf, "<>"); break; } return 1; /* one line in buf */ } bareos-Release-14.2.6/src/ndmp/ndmp0_xmt.c000066400000000000000000000040151263011562700202370ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" #include "ndmprotocol.h" #define xdr_ndmp0_connect_close_request xdr_void #define xdr_ndmp0_connect_close_reply xdr_void #define xdr_ndmp0_notify_connected_reply 0 struct ndmp_xdr_message_table ndmp0_xdr_message_table[] = { { NDMP0_CONNECT_OPEN, xdr_ndmp0_connect_open_request, xdr_ndmp0_connect_open_reply, }, { NDMP0_CONNECT_CLOSE, xdr_ndmp0_connect_close_request, xdr_ndmp0_connect_close_reply, }, { NDMP0_NOTIFY_CONNECTED, xdr_ndmp0_notify_connected_request, xdr_ndmp0_notify_connected_reply, }, {0} }; bareos-Release-14.2.6/src/ndmp/ndmp2.x000066400000000000000000000461541263011562700174100ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ /* * Copyright (c) 1997 Network Appliance. All Rights Reserved. * * Network Appliance makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. * */ %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 %#pragma GCC diagnostic ignored "-Wunused-variable" %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 470 %#pragma GCC diagnostic ignored "-Wunprototyped-calls" %#endif %#endif %#ifndef NDMOS_OPTION_NO_NDMP2 const NDMP2VER = 2; const NDMP2PORT = 10000; %#define ndmp2_u_quad uint64_t %extern bool_t xdr_ndmp2_u_quad(); struct _ndmp2_u_quad { uint32_t high; uint32_t low; }; struct ndmp2_pval { string name<>; string value<>; }; struct ndmp2_scsi_device { string name<>; }; struct ndmp2_tape_device { string name<>; }; enum ndmp2_error { NDMP2_NO_ERR, /* No error */ NDMP2_NOT_SUPPORTED_ERR, /* Call is not supported */ NDMP2_DEVICE_BUSY_ERR, /* The device is in use */ NDMP2_DEVICE_OPENED_ERR, /* Another tape or scsi device * is already open */ NDMP2_NOT_AUTHORIZED_ERR, /* connection has not been authorized*/ NDMP2_PERMISSION_ERR, /* some sort of permission problem */ NDMP2_DEV_NOT_OPEN_ERR, /* SCSI device is not open */ NDMP2_IO_ERR, /* I/O error */ NDMP2_TIMEOUT_ERR, /* command timed out */ NDMP2_ILLEGAL_ARGS_ERR, /* illegal arguments in request */ NDMP2_NO_TAPE_LOADED_ERR, /* Cannot open because there is no tape loaded */ NDMP2_WRITE_PROTECT_ERR, /* tape cannot be open for write */ NDMP2_EOF_ERR, /* Command encountered EOF */ NDMP2_EOM_ERR, /* Command encountered EOM */ NDMP2_FILE_NOT_FOUND_ERR, /* File not found during restore */ NDMP2_BAD_FILE_ERR, /* The file descriptor is invalid */ NDMP2_NO_DEVICE_ERR, /* The device is not at that target */ NDMP2_NO_BUS_ERR, /* Invalid controller */ NDMP2_XDR_DECODE_ERR, /* Can't decode the request argument */ NDMP2_ILLEGAL_STATE_ERR, /* Call can't be done at this state */ NDMP2_UNDEFINED_ERR, /* Undefined Error */ NDMP2_XDR_ENCODE_ERR, /* Can't encode the reply argument */ NDMP2_NO_MEM_ERR /* no memory */ }; enum ndmp2_header_message_type { NDMP2_MESSAGE_REQUEST, NDMP2_MESSAGE_REPLY }; enum ndmp2_message { NDMP2_CONNECT_OPEN = 0x900, /* CONNECT INTERFACE */ NDMP2_CONNECT_CLIENT_AUTH, NDMP2_CONNECT_CLOSE, NDMP2_CONNECT_SERVER_AUTH, NDMP2_CONFIG_GET_HOST_INFO = 0x100, /* CONFIG INTERFACE */ NDMP2_CONFIG_GET_BUTYPE_ATTR, NDMP2_CONFIG_GET_MOVER_TYPE, NDMP2_CONFIG_GET_AUTH_ATTR, NDMP2_SCSI_OPEN = 0x200, /* SCSI INTERFACE */ NDMP2_SCSI_CLOSE, NDMP2_SCSI_GET_STATE, NDMP2_SCSI_SET_TARGET, NDMP2_SCSI_RESET_DEVICE, NDMP2_SCSI_RESET_BUS, NDMP2_SCSI_EXECUTE_CDB, NDMP2_TAPE_OPEN = 0x300, /* TAPE INTERFACE */ NDMP2_TAPE_CLOSE, NDMP2_TAPE_GET_STATE, NDMP2_TAPE_MTIO, NDMP2_TAPE_WRITE, NDMP2_TAPE_READ, NDMP2_TAPE_RESVD1, NDMP2_TAPE_EXECUTE_CDB, NDMP2_DATA_GET_STATE = 0x400, /* DATA INTERFACE */ NDMP2_DATA_START_BACKUP, NDMP2_DATA_START_RECOVER, NDMP2_DATA_ABORT, NDMP2_DATA_GET_ENV, NDMP2_DATA_RESVD1, NDMP2_DATA_RESVD2, NDMP2_DATA_STOP, NDMP2_DATA_START_RECOVER_FILEHIST = 0x40b, /* same as V3.1 */ NDMP2_NOTIFY_RESVD1 = 0x500, /* NOTIFY INTERFACE */ NDMP2_NOTIFY_DATA_HALTED, NDMP2_NOTIFY_CONNECTED, NDMP2_NOTIFY_MOVER_HALTED, NDMP2_NOTIFY_MOVER_PAUSED, NDMP2_NOTIFY_DATA_READ, NDMP2_LOG_LOG = 0x600, /* LOGGING INTERFACE */ NDMP2_LOG_DEBUG, NDMP2_LOG_FILE, NDMP2_FH_ADD_UNIX_PATH = 0x700, /* FILE HISTORY INTERFACE */ NDMP2_FH_ADD_UNIX_DIR, NDMP2_FH_ADD_UNIX_NODE, NDMP2_MOVER_GET_STATE = 0xa00, /* MOVER INTERFACE */ NDMP2_MOVER_LISTEN, NDMP2_MOVER_CONTINUE, NDMP2_MOVER_ABORT, NDMP2_MOVER_STOP, NDMP2_MOVER_SET_WINDOW, NDMP2_MOVER_READ, NDMP2_MOVER_CLOSE, NDMP2_MOVER_SET_RECORD_SIZE, NDMP2_RESERVED = 0xff00 /* Reserved for prototyping */ }; struct ndmp2_header { uint32_t sequence; /* monotonically increasing */ uint32_t time_stamp; /* time stamp of message */ ndmp2_header_message_type message_type; /* what type of message */ ndmp2_message message; /* message number */ uint32_t reply_sequence; /* reply is in response to */ ndmp2_error error; /* communications errors */ }; /**********************/ /* CONNECT INTERFACE */ /**********************/ /* NDMP2_CONNECT_OPEN */ struct ndmp2_connect_open_request { uint16_t protocol_version; /* the version of protocol supported */ }; struct ndmp2_connect_open_reply { ndmp2_error error; }; /* NDMP2_CONNECT_CLIENT_AUTH */ enum ndmp2_auth_type { NDMP2_AUTH_NONE, /* no password is required */ NDMP2_AUTH_TEXT, /* the clear text password */ NDMP2_AUTH_MD5 /* md5 */ }; struct ndmp2_auth_text { string auth_id<>; string auth_password<>; }; struct ndmp2_auth_md5 { string auth_id<>; opaque auth_digest[16]; }; union ndmp2_auth_data switch (enum ndmp2_auth_type auth_type) { case NDMP2_AUTH_NONE: void; case NDMP2_AUTH_TEXT: ndmp2_auth_text auth_text; case NDMP2_AUTH_MD5: ndmp2_auth_md5 auth_md5; }; struct ndmp2_connect_client_auth_request { ndmp2_auth_data auth_data; }; struct ndmp2_connect_client_auth_reply { ndmp2_error error; }; /* NDMP2_CONNECT_CLOSE */ /* no request arguments */ /* no reply arguments */ /* NDMP2_CONNECT_SERVER_AUTH */ union ndmp2_auth_attr switch (enum ndmp2_auth_type auth_type) { case NDMP2_AUTH_NONE: void; case NDMP2_AUTH_TEXT: void; case NDMP2_AUTH_MD5: opaque challenge[64]; }; struct ndmp2_connect_server_auth_request { ndmp2_auth_attr client_attr; }; struct ndmp2_connect_server_auth_reply { ndmp2_error error; ndmp2_auth_data auth_result; }; /********************/ /* CONFIG INTERFACE */ /********************/ /* NDMP2_CONFIG_GET_HOST_INFO */ /* no request arguments */ struct ndmp2_config_get_host_info_reply { ndmp2_error error; string hostname<>; /* host name */ string os_type<>; /* The O/S type (e.g. SOLARIS) */ string os_vers<>; /* The O/S version (e.g. 2.5) */ string hostid<>; ndmp2_auth_type auth_type<>; }; /* NDMP2_CONFIG_GET_BUTYPE_ATTR */ const NDMP2_NO_BACKUP_FILELIST = 0x0001; const NDMP2_NO_BACKUP_FHINFO = 0x0002; const NDMP2_NO_RECOVER_FILELIST = 0x0004; const NDMP2_NO_RECOVER_FHINFO = 0x0008; const NDMP2_NO_RECOVER_RESVD = 0x0010; const NDMP2_NO_RECOVER_INC_ONLY = 0x0020; struct ndmp2_config_get_butype_attr_request { string name<>; /* backup type name */ }; struct ndmp2_config_get_butype_attr_reply { ndmp2_error error; uint32_t attrs; }; /* NDMP2_CONFIG_GET_MOVER_TYPE */ /* no request arguments */ enum ndmp2_mover_addr_type { NDMP2_ADDR_LOCAL, NDMP2_ADDR_TCP }; struct ndmp2_config_get_mover_type_reply { ndmp2_error error; ndmp2_mover_addr_type methods<>; }; /* NDMP2_CONFIG_GET_AUTH_ATTR */ struct ndmp2_config_get_auth_attr_request { ndmp2_auth_type auth_type; }; struct ndmp2_config_get_auth_attr_reply { ndmp2_error error; ndmp2_auth_attr server_attr; }; /******************/ /* SCSI INTERFACE */ /******************/ /* NDMP2_SCSI_OPEN */ struct ndmp2_scsi_open_request { ndmp2_scsi_device device; }; struct ndmp2_scsi_open_reply { ndmp2_error error; }; /* NDMP2_SCSI_CLOSE */ /* no request arguments */ struct ndmp2_scsi_close_reply { ndmp2_error error; }; /* NDMP2_SCSI_GET_STATE */ /* no request arguments */ struct ndmp2_scsi_get_state_reply { ndmp2_error error; short target_controller; short target_id; short target_lun; }; /* NDMP2_SCSI_SET_TARGET */ struct ndmp2_scsi_set_target_request { ndmp2_scsi_device device; uint16_t target_controller; uint16_t target_id; uint16_t target_lun; }; struct ndmp2_scsi_set_target_reply { ndmp2_error error; }; /* NDMP2_SCSI_RESET_DEVICE */ /* no request arguments */ struct ndmp2_scsi_reset_device_reply { ndmp2_error error; }; /* NDMP2_SCSI_RESET_BUS */ /* no request arguments */ struct ndmp2_scsi_reset_bus_reply { ndmp2_error error; }; /* NDMP2_SCSI_EXECUTE_CDB */ const NDMP2_SCSI_DATA_IN = 0x00000001; /* Expect data from SCSI device */ const NDMP2_SCSI_DATA_OUT = 0x00000002; /* Transfer data to SCSI device */ struct ndmp2_execute_cdb_request { uint32_t flags; uint32_t timeout; uint32_t datain_len; /* Set for expected datain */ opaque cdb<>; opaque dataout<>; }; struct ndmp2_execute_cdb_reply { ndmp2_error error; u_char status; /* SCSI status bytes */ uint32_t dataout_len; opaque datain<>; /* SCSI datain */ opaque ext_sense<>; /* Extended sense data */ }; typedef ndmp2_execute_cdb_request ndmp2_scsi_execute_cdb_request; typedef ndmp2_execute_cdb_reply ndmp2_scsi_execute_cdb_reply; /******************/ /* TAPE INTERFACE */ /******************/ /* NDMP2_TAPE_OPEN */ enum ndmp2_tape_open_mode { NDMP2_TAPE_READ_MODE, NDMP2_TAPE_WRITE_MODE }; struct ndmp2_tape_open_request { ndmp2_tape_device device; ndmp2_tape_open_mode mode; }; struct ndmp2_tape_open_reply { ndmp2_error error; }; /* NDMP2_TAPE_CLOSE */ /* no request arguments */ struct ndmp2_tape_close_reply { ndmp2_error error; }; /* NDMP2_TAPE_GET_STATE */ /* no request arguments */ const NDMP2_TAPE_NOREWIND = 0x0008; /* non-rewind device */ const NDMP2_TAPE_WR_PROT = 0x0010; /* write-protected */ const NDMP2_TAPE_ERROR = 0x0020; /* media error */ const NDMP2_TAPE_UNLOAD = 0x0040; /* tape will be unloaded when * the device is closed */ struct ndmp2_tape_get_state_reply { ndmp2_error error; uint32_t flags; uint32_t file_num; uint32_t soft_errors; uint32_t block_size; uint32_t blockno; ndmp2_u_quad total_space; ndmp2_u_quad space_remain; }; /* NDMP2_TAPE_MTIO */ enum ndmp2_tape_mtio_op { NDMP2_MTIO_FSF, NDMP2_MTIO_BSF, NDMP2_MTIO_FSR, NDMP2_MTIO_BSR, NDMP2_MTIO_REW, NDMP2_MTIO_EOF, NDMP2_MTIO_OFF }; struct ndmp2_tape_mtio_request { ndmp2_tape_mtio_op tape_op; uint32_t count; }; struct ndmp2_tape_mtio_reply { ndmp2_error error; uint32_t resid_count; }; /* NDMP2_TAPE_WRITE */ struct ndmp2_tape_write_request { opaque data_out<>; }; struct ndmp2_tape_write_reply { ndmp2_error error; uint32_t count; }; /* NDMP2_TAPE_READ */ struct ndmp2_tape_read_request { uint32_t count; }; struct ndmp2_tape_read_reply { ndmp2_error error; opaque data_in<>; }; /* NDMP2_TAPE_EXECUTE_CDB */ typedef ndmp2_execute_cdb_request ndmp2_tape_execute_cdb_request; typedef ndmp2_execute_cdb_reply ndmp2_tape_execute_cdb_reply; /********************************/ /* MOVER INTERFACE */ /********************************/ /* NDMP2_MOVER_GET_STATE */ enum ndmp2_mover_state { NDMP2_MOVER_STATE_IDLE, NDMP2_MOVER_STATE_LISTEN, NDMP2_MOVER_STATE_ACTIVE, NDMP2_MOVER_STATE_PAUSED, NDMP2_MOVER_STATE_HALTED }; enum ndmp2_mover_pause_reason { NDMP2_MOVER_PAUSE_NA, NDMP2_MOVER_PAUSE_EOM, NDMP2_MOVER_PAUSE_EOF, NDMP2_MOVER_PAUSE_SEEK, NDMP2_MOVER_PAUSE_MEDIA_ERROR }; enum ndmp2_mover_halt_reason { NDMP2_MOVER_HALT_NA, NDMP2_MOVER_HALT_CONNECT_CLOSED, NDMP2_MOVER_HALT_ABORTED, NDMP2_MOVER_HALT_INTERNAL_ERROR, NDMP2_MOVER_HALT_CONNECT_ERROR }; /* no request arguments */ struct ndmp2_mover_get_state_reply { ndmp2_error error; ndmp2_mover_state state; ndmp2_mover_pause_reason pause_reason; ndmp2_mover_halt_reason halt_reason; uint32_t record_size; uint32_t record_num; ndmp2_u_quad data_written; ndmp2_u_quad seek_position; ndmp2_u_quad bytes_left_to_read; ndmp2_u_quad window_offset; ndmp2_u_quad window_length; }; /* NDMP2_MOVER_LISTEN */ enum ndmp2_mover_mode { NDMP2_MOVER_MODE_READ, /* read from data conn; write to tape */ NDMP2_MOVER_MODE_WRITE, /* write to data conn; read from tape */ NDMP2_MOVER_MODE_DATA /* write to data conn; read from data conn */ }; struct ndmp2_mover_tcp_addr { uint32_t ip_addr; uint16_t port; }; union ndmp2_mover_addr switch (ndmp2_mover_addr_type addr_type) { case NDMP2_ADDR_LOCAL: void; case NDMP2_ADDR_TCP: ndmp2_mover_tcp_addr addr; }; struct ndmp2_mover_listen_request { ndmp2_mover_mode mode; ndmp2_mover_addr_type addr_type; }; struct ndmp2_mover_listen_reply { ndmp2_error error; ndmp2_mover_addr mover; }; /* NDMP2_MOVER_SET_RECORD_SIZE */ struct ndmp2_mover_set_record_size_request { uint32_t len; }; struct ndmp2_mover_set_record_size_reply { ndmp2_error error; }; /* NDMP2_MOVER_SET_WINDOW */ struct ndmp2_mover_set_window_request { ndmp2_u_quad offset; ndmp2_u_quad length; }; struct ndmp2_mover_set_window_reply { ndmp2_error error; }; /* NDMP2_MOVER_CONTINUE */ /* no request arguments */ struct ndmp2_mover_continue_reply { ndmp2_error error; }; /* NDMP2_MOVER_ABORT */ /* no request arguments */ struct ndmp2_mover_abort_reply { ndmp2_error error; }; /* NDMP2_MOVER_STOP */ /* no request arguments */ struct ndmp2_mover_stop_reply { ndmp2_error error; }; /* NDMP2_MOVER_READ */ struct ndmp2_mover_read_request { ndmp2_u_quad offset; ndmp2_u_quad length; }; struct ndmp2_mover_read_reply { ndmp2_error error; }; /* NDMP2_MOVER_CLOSE */ /* no request arguments */ struct ndmp2_mover_close_reply { ndmp2_error error; }; /****************************/ /* DATA INTERFACE */ /****************************/ /* NDMP2_DATA_GET_STATE */ /* no request arguments */ enum ndmp2_data_operation { NDMP2_DATA_OP_NOACTION, NDMP2_DATA_OP_BACKUP, NDMP2_DATA_OP_RESTORE, NDMP2_DATA_OP_RESTORE_FILEHIST }; enum ndmp2_data_state { NDMP2_DATA_STATE_IDLE, NDMP2_DATA_STATE_ACTIVE, NDMP2_DATA_STATE_HALTED }; enum ndmp2_data_halt_reason { NDMP2_DATA_HALT_NA, NDMP2_DATA_HALT_SUCCESSFUL, NDMP2_DATA_HALT_ABORTED, NDMP2_DATA_HALT_INTERNAL_ERROR, NDMP2_DATA_HALT_CONNECT_ERROR }; struct ndmp2_data_get_state_reply { ndmp2_error error; ndmp2_data_operation operation; ndmp2_data_state state; ndmp2_data_halt_reason halt_reason; ndmp2_u_quad bytes_processed; ndmp2_u_quad est_bytes_remain; uint32_t est_time_remain; ndmp2_mover_addr mover; ndmp2_u_quad read_offset; ndmp2_u_quad read_length; }; /* NDMP2_DATA_START_BACKUP */ struct ndmp2_data_start_backup_request { ndmp2_mover_addr mover; /* mover to receive data */ string bu_type<>; /* backup method to use */ ndmp2_pval env<>; /* Parameters that may modify backup */ }; struct ndmp2_data_start_backup_reply { ndmp2_error error; }; /* NDMP2_DATA_START_RECOVER */ struct ndmp2_name { string name<>; string dest<>; uint16_t ssid; ndmp2_u_quad fh_info; }; struct ndmp2_data_start_recover_request { ndmp2_mover_addr mover; ndmp2_pval env<>; ndmp2_name nlist<>; string bu_type<>; }; struct ndmp2_data_start_recover_reply { ndmp2_error error; }; /* NDMP2_DATA_START_RECOVER_FILEHIST */ typedef ndmp2_data_start_recover_request ndmp2_data_start_recover_filehist_request; typedef ndmp2_data_start_recover_reply ndmp2_data_start_recover_filehist_reply; /* NDMP2_DATA_ABORT */ /* no request arguments */ struct ndmp2_data_abort_reply { ndmp2_error error; }; /* NDMP2_DATA_STOP */ /* no request arguments */ struct ndmp2_data_stop_reply { ndmp2_error error; }; /* NDMP2_DATA_GET_ENV */ /* no request arguments */ struct ndmp2_data_get_env_reply { ndmp2_error error; ndmp2_pval env<>; }; /****************************/ /* NOTIFY INTERFACE */ /****************************/ /* NDMP2_NOTIFY_DATA_HALTED */ struct ndmp2_notify_data_halted_request { ndmp2_data_halt_reason reason; string text_reason<>; }; /* No reply */ /* NDMP2_NOTIFY_CONNECTED */ enum ndmp2_connect_reason { NDMP2_CONNECTED, /* Connect sucessfully */ NDMP2_SHUTDOWN, /* Connection shutdown */ NDMP2_REFUSED /* reach the maximum number of connections */ }; struct ndmp2_notify_connected_request { ndmp2_connect_reason reason; uint16_t protocol_version; string text_reason<>; }; /* NDMP2_NOTIFY_MOVER_PAUSED */ struct ndmp2_notify_mover_paused_request { ndmp2_mover_pause_reason reason; ndmp2_u_quad seek_position; }; /* No reply */ /* NDMP2_NOTIFY_MOVER_HALTED */ struct ndmp2_notify_mover_halted_request { ndmp2_mover_halt_reason reason; string text_reason<>; }; /* No reply */ /* NDMP2_NOTIFY_DATA_READ */ struct ndmp2_notify_data_read_request { ndmp2_u_quad offset; ndmp2_u_quad length; }; /* No reply */ /********************************/ /* LOG INTERFACE */ /********************************/ /* NDMP2_LOG_LOG */ struct ndmp2_log_log_request { string entry<>; }; /* No reply */ /* NDMP2_LOG_DEBUG */ enum ndmp2_debug_level { NDMP2_DBG_USER_INFO, NDMP2_DBG_USER_SUMMARY, NDMP2_DBG_USER_DETAIL, NDMP2_DBG_DIAG_INFO, NDMP2_DBG_DIAG_SUMMARY, NDMP2_DBG_DIAG_DETAIL, NDMP2_DBG_PROG_INFO, NDMP2_DBG_PROG_SUMMARY, NDMP2_DBG_PROG_DETAIL }; struct ndmp2_log_debug_request { ndmp2_debug_level level; string message<>; }; /* No reply */ /* NDMP2_LOG_FILE */ struct ndmp2_log_file_request { string name<>; uint16_t ssid; ndmp2_error error; }; /* No reply */ /********************************/ /* File History INTERFACE */ /********************************/ /* NDMP2_FH_ADD_UNIX_PATH */ typedef string ndmp2_unix_path<>; enum ndmp2_unix_file_type { NDMP2_FILE_DIR, NDMP2_FILE_FIFO, NDMP2_FILE_CSPEC, NDMP2_FILE_BSPEC, NDMP2_FILE_REG, NDMP2_FILE_SLINK, NDMP2_FILE_SOCK }; struct ndmp2_unix_file_stat { ndmp2_unix_file_type ftype; uint32_t mtime; uint32_t atime; uint32_t ctime; uint32_t uid; uint32_t gid; uint32_t mode; ndmp2_u_quad size; ndmp2_u_quad fh_info; }; struct ndmp2_fh_unix_path { ndmp2_unix_path name; ndmp2_unix_file_stat fstat; }; struct ndmp2_fh_add_unix_path_request { ndmp2_fh_unix_path paths<>; }; /* No reply */ /* NDMP2_FH_ADD_UNIX_DIR */ struct ndmp2_fh_unix_dir { ndmp2_unix_path name; uint32_t node; uint32_t parent; }; struct ndmp2_fh_add_unix_dir_request { ndmp2_fh_unix_dir dirs<>; }; /* No reply */ struct ndmp2_fh_unix_node { ndmp2_unix_file_stat fstat; uint32_t node; }; struct ndmp2_fh_add_unix_node_request { ndmp2_fh_unix_node nodes<>; }; /* No reply */ /**************************************************************** * * End of file : ndmp.x * ****************************************************************/ %#endif /* !NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp2_enum_strs.c000066400000000000000000000437661263011562700214700ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP2 extern struct ndmp_enum_str_table ndmp2_error_table[]; extern char * ndmp2_error_to_str (ndmp2_error val); extern int ndmp2_error_from_str (ndmp2_error *valp, char * str); char * ndmp2_error_to_str (ndmp2_error val) { return ndmp_enum_to_str ((int)val, ndmp2_error_table); } int ndmp2_error_from_str (ndmp2_error *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_error_table); } struct ndmp_enum_str_table ndmp2_error_table[] = { { "NDMP2_NO_ERR", NDMP2_NO_ERR }, { "NDMP2_NOT_SUPPORTED_ERR", NDMP2_NOT_SUPPORTED_ERR }, { "NDMP2_DEVICE_BUSY_ERR", NDMP2_DEVICE_BUSY_ERR }, { "NDMP2_DEVICE_OPENED_ERR", NDMP2_DEVICE_OPENED_ERR }, { "NDMP2_NOT_AUTHORIZED_ERR", NDMP2_NOT_AUTHORIZED_ERR }, { "NDMP2_PERMISSION_ERR", NDMP2_PERMISSION_ERR }, { "NDMP2_DEV_NOT_OPEN_ERR", NDMP2_DEV_NOT_OPEN_ERR }, { "NDMP2_IO_ERR", NDMP2_IO_ERR }, { "NDMP2_TIMEOUT_ERR", NDMP2_TIMEOUT_ERR }, { "NDMP2_ILLEGAL_ARGS_ERR", NDMP2_ILLEGAL_ARGS_ERR }, { "NDMP2_NO_TAPE_LOADED_ERR", NDMP2_NO_TAPE_LOADED_ERR }, { "NDMP2_WRITE_PROTECT_ERR", NDMP2_WRITE_PROTECT_ERR }, { "NDMP2_EOF_ERR", NDMP2_EOF_ERR }, { "NDMP2_EOM_ERR", NDMP2_EOM_ERR }, { "NDMP2_FILE_NOT_FOUND_ERR", NDMP2_FILE_NOT_FOUND_ERR }, { "NDMP2_BAD_FILE_ERR", NDMP2_BAD_FILE_ERR }, { "NDMP2_NO_DEVICE_ERR", NDMP2_NO_DEVICE_ERR }, { "NDMP2_NO_BUS_ERR", NDMP2_NO_BUS_ERR }, { "NDMP2_XDR_DECODE_ERR", NDMP2_XDR_DECODE_ERR }, { "NDMP2_ILLEGAL_STATE_ERR", NDMP2_ILLEGAL_STATE_ERR }, { "NDMP2_UNDEFINED_ERR", NDMP2_UNDEFINED_ERR }, { "NDMP2_XDR_ENCODE_ERR", NDMP2_XDR_ENCODE_ERR }, { "NDMP2_NO_MEM_ERR", NDMP2_NO_MEM_ERR }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_header_message_type_table[]; extern char * ndmp2_header_message_type_to_str (ndmp2_header_message_type val); extern int ndmp2_header_message_type_from_str (ndmp2_header_message_type *valp, char * str); char * ndmp2_header_message_type_to_str (ndmp2_header_message_type val) { return ndmp_enum_to_str ((int)val, ndmp2_header_message_type_table); } int ndmp2_header_message_type_from_str (ndmp2_header_message_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_header_message_type_table); } struct ndmp_enum_str_table ndmp2_header_message_type_table[] = { { "NDMP2_MESSAGE_REQUEST", NDMP2_MESSAGE_REQUEST }, { "NDMP2_MESSAGE_REPLY", NDMP2_MESSAGE_REPLY }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_message_table[]; extern char * ndmp2_message_to_str (ndmp2_message val); extern int ndmp2_message_from_str (ndmp2_message *valp, char * str); char * ndmp2_message_to_str (ndmp2_message val) { return ndmp_enum_to_str ((int)val, ndmp2_message_table); } int ndmp2_message_from_str (ndmp2_message *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_message_table); } struct ndmp_enum_str_table ndmp2_message_table[] = { { "NDMP2_CONNECT_OPEN", NDMP2_CONNECT_OPEN }, { "NDMP2_CONNECT_CLIENT_AUTH", NDMP2_CONNECT_CLIENT_AUTH }, { "NDMP2_CONNECT_CLOSE", NDMP2_CONNECT_CLOSE }, { "NDMP2_CONNECT_SERVER_AUTH", NDMP2_CONNECT_SERVER_AUTH }, { "NDMP2_CONFIG_GET_HOST_INFO", NDMP2_CONFIG_GET_HOST_INFO }, { "NDMP2_CONFIG_GET_BUTYPE_ATTR", NDMP2_CONFIG_GET_BUTYPE_ATTR }, { "NDMP2_CONFIG_GET_MOVER_TYPE", NDMP2_CONFIG_GET_MOVER_TYPE }, { "NDMP2_CONFIG_GET_AUTH_ATTR", NDMP2_CONFIG_GET_AUTH_ATTR }, { "NDMP2_SCSI_OPEN", NDMP2_SCSI_OPEN }, { "NDMP2_SCSI_CLOSE", NDMP2_SCSI_CLOSE }, { "NDMP2_SCSI_GET_STATE", NDMP2_SCSI_GET_STATE }, { "NDMP2_SCSI_SET_TARGET", NDMP2_SCSI_SET_TARGET }, { "NDMP2_SCSI_RESET_DEVICE", NDMP2_SCSI_RESET_DEVICE }, { "NDMP2_SCSI_RESET_BUS", NDMP2_SCSI_RESET_BUS }, { "NDMP2_SCSI_EXECUTE_CDB", NDMP2_SCSI_EXECUTE_CDB }, { "NDMP2_TAPE_OPEN", NDMP2_TAPE_OPEN }, { "NDMP2_TAPE_CLOSE", NDMP2_TAPE_CLOSE }, { "NDMP2_TAPE_GET_STATE", NDMP2_TAPE_GET_STATE }, { "NDMP2_TAPE_MTIO", NDMP2_TAPE_MTIO }, { "NDMP2_TAPE_WRITE", NDMP2_TAPE_WRITE }, { "NDMP2_TAPE_READ", NDMP2_TAPE_READ }, { "NDMP2_TAPE_RESVD1", NDMP2_TAPE_RESVD1 }, { "NDMP2_TAPE_EXECUTE_CDB", NDMP2_TAPE_EXECUTE_CDB }, { "NDMP2_DATA_GET_STATE", NDMP2_DATA_GET_STATE }, { "NDMP2_DATA_START_BACKUP", NDMP2_DATA_START_BACKUP }, { "NDMP2_DATA_START_RECOVER", NDMP2_DATA_START_RECOVER }, { "NDMP2_DATA_ABORT", NDMP2_DATA_ABORT }, { "NDMP2_DATA_GET_ENV", NDMP2_DATA_GET_ENV }, { "NDMP2_DATA_RESVD1", NDMP2_DATA_RESVD1 }, { "NDMP2_DATA_RESVD2", NDMP2_DATA_RESVD2 }, { "NDMP2_DATA_STOP", NDMP2_DATA_STOP }, { "NDMP2_DATA_START_RECOVER_FILEHIST", NDMP2_DATA_START_RECOVER_FILEHIST }, { "NDMP2_NOTIFY_RESVD1", NDMP2_NOTIFY_RESVD1 }, { "NDMP2_NOTIFY_DATA_HALTED", NDMP2_NOTIFY_DATA_HALTED }, { "NDMP2_NOTIFY_CONNECTED", NDMP2_NOTIFY_CONNECTED }, { "NDMP2_NOTIFY_MOVER_HALTED", NDMP2_NOTIFY_MOVER_HALTED }, { "NDMP2_NOTIFY_MOVER_PAUSED", NDMP2_NOTIFY_MOVER_PAUSED }, { "NDMP2_NOTIFY_DATA_READ", NDMP2_NOTIFY_DATA_READ }, { "NDMP2_LOG_LOG", NDMP2_LOG_LOG }, { "NDMP2_LOG_DEBUG", NDMP2_LOG_DEBUG }, { "NDMP2_LOG_FILE", NDMP2_LOG_FILE }, { "NDMP2_FH_ADD_UNIX_PATH", NDMP2_FH_ADD_UNIX_PATH }, { "NDMP2_FH_ADD_UNIX_DIR", NDMP2_FH_ADD_UNIX_DIR }, { "NDMP2_FH_ADD_UNIX_NODE", NDMP2_FH_ADD_UNIX_NODE }, { "NDMP2_MOVER_GET_STATE", NDMP2_MOVER_GET_STATE }, { "NDMP2_MOVER_LISTEN", NDMP2_MOVER_LISTEN }, { "NDMP2_MOVER_CONTINUE", NDMP2_MOVER_CONTINUE }, { "NDMP2_MOVER_ABORT", NDMP2_MOVER_ABORT }, { "NDMP2_MOVER_STOP", NDMP2_MOVER_STOP }, { "NDMP2_MOVER_SET_WINDOW", NDMP2_MOVER_SET_WINDOW }, { "NDMP2_MOVER_READ", NDMP2_MOVER_READ }, { "NDMP2_MOVER_CLOSE", NDMP2_MOVER_CLOSE }, { "NDMP2_MOVER_SET_RECORD_SIZE", NDMP2_MOVER_SET_RECORD_SIZE }, { "NDMP2_RESERVED", NDMP2_RESERVED }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_auth_type_table[]; extern char * ndmp2_auth_type_to_str (ndmp2_auth_type val); extern int ndmp2_auth_type_from_str (ndmp2_auth_type *valp, char * str); char * ndmp2_auth_type_to_str (ndmp2_auth_type val) { return ndmp_enum_to_str ((int)val, ndmp2_auth_type_table); } int ndmp2_auth_type_from_str (ndmp2_auth_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_auth_type_table); } struct ndmp_enum_str_table ndmp2_auth_type_table[] = { { "NDMP2_AUTH_NONE", NDMP2_AUTH_NONE }, { "NDMP2_AUTH_TEXT", NDMP2_AUTH_TEXT }, { "NDMP2_AUTH_MD5", NDMP2_AUTH_MD5 }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_mover_addr_type_table[]; extern char * ndmp2_mover_addr_type_to_str (ndmp2_mover_addr_type val); extern int ndmp2_mover_addr_type_from_str (ndmp2_mover_addr_type *valp, char * str); char * ndmp2_mover_addr_type_to_str (ndmp2_mover_addr_type val) { return ndmp_enum_to_str ((int)val, ndmp2_mover_addr_type_table); } int ndmp2_mover_addr_type_from_str (ndmp2_mover_addr_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_mover_addr_type_table); } struct ndmp_enum_str_table ndmp2_mover_addr_type_table[] = { { "NDMP2_ADDR_LOCAL", NDMP2_ADDR_LOCAL }, { "NDMP2_ADDR_TCP", NDMP2_ADDR_TCP }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_tape_open_mode_table[]; extern char * ndmp2_tape_open_mode_to_str (ndmp2_tape_open_mode val); extern int ndmp2_tape_open_mode_from_str (ndmp2_tape_open_mode *valp, char * str); char * ndmp2_tape_open_mode_to_str (ndmp2_tape_open_mode val) { return ndmp_enum_to_str ((int)val, ndmp2_tape_open_mode_table); } int ndmp2_tape_open_mode_from_str (ndmp2_tape_open_mode *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_tape_open_mode_table); } struct ndmp_enum_str_table ndmp2_tape_open_mode_table[] = { { "NDMP2_TAPE_READ_MODE", NDMP2_TAPE_READ_MODE }, { "NDMP2_TAPE_WRITE_MODE", NDMP2_TAPE_WRITE_MODE }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_tape_mtio_op_table[]; extern char * ndmp2_tape_mtio_op_to_str (ndmp2_tape_mtio_op val); extern int ndmp2_tape_mtio_op_from_str (ndmp2_tape_mtio_op *valp, char * str); char * ndmp2_tape_mtio_op_to_str (ndmp2_tape_mtio_op val) { return ndmp_enum_to_str ((int)val, ndmp2_tape_mtio_op_table); } int ndmp2_tape_mtio_op_from_str (ndmp2_tape_mtio_op *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_tape_mtio_op_table); } struct ndmp_enum_str_table ndmp2_tape_mtio_op_table[] = { { "NDMP2_MTIO_FSF", NDMP2_MTIO_FSF }, { "NDMP2_MTIO_BSF", NDMP2_MTIO_BSF }, { "NDMP2_MTIO_FSR", NDMP2_MTIO_FSR }, { "NDMP2_MTIO_BSR", NDMP2_MTIO_BSR }, { "NDMP2_MTIO_REW", NDMP2_MTIO_REW }, { "NDMP2_MTIO_EOF", NDMP2_MTIO_EOF }, { "NDMP2_MTIO_OFF", NDMP2_MTIO_OFF }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_mover_state_table[]; extern char * ndmp2_mover_state_to_str (ndmp2_mover_state val); extern int ndmp2_mover_state_from_str (ndmp2_mover_state *valp, char * str); char * ndmp2_mover_state_to_str (ndmp2_mover_state val) { return ndmp_enum_to_str ((int)val, ndmp2_mover_state_table); } int ndmp2_mover_state_from_str (ndmp2_mover_state *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_mover_state_table); } struct ndmp_enum_str_table ndmp2_mover_state_table[] = { { "NDMP2_MOVER_STATE_IDLE", NDMP2_MOVER_STATE_IDLE }, { "NDMP2_MOVER_STATE_LISTEN", NDMP2_MOVER_STATE_LISTEN }, { "NDMP2_MOVER_STATE_ACTIVE", NDMP2_MOVER_STATE_ACTIVE }, { "NDMP2_MOVER_STATE_PAUSED", NDMP2_MOVER_STATE_PAUSED }, { "NDMP2_MOVER_STATE_HALTED", NDMP2_MOVER_STATE_HALTED }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_mover_pause_reason_table[]; extern char * ndmp2_mover_pause_reason_to_str (ndmp2_mover_pause_reason val); extern int ndmp2_mover_pause_reason_from_str (ndmp2_mover_pause_reason *valp, char * str); char * ndmp2_mover_pause_reason_to_str (ndmp2_mover_pause_reason val) { return ndmp_enum_to_str ((int)val, ndmp2_mover_pause_reason_table); } int ndmp2_mover_pause_reason_from_str (ndmp2_mover_pause_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_mover_pause_reason_table); } struct ndmp_enum_str_table ndmp2_mover_pause_reason_table[] = { { "NDMP2_MOVER_PAUSE_NA", NDMP2_MOVER_PAUSE_NA }, { "NDMP2_MOVER_PAUSE_EOM", NDMP2_MOVER_PAUSE_EOM }, { "NDMP2_MOVER_PAUSE_EOF", NDMP2_MOVER_PAUSE_EOF }, { "NDMP2_MOVER_PAUSE_SEEK", NDMP2_MOVER_PAUSE_SEEK }, { "NDMP2_MOVER_PAUSE_MEDIA_ERROR", NDMP2_MOVER_PAUSE_MEDIA_ERROR }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_mover_halt_reason_table[]; extern char * ndmp2_mover_halt_reason_to_str (ndmp2_mover_halt_reason val); extern int ndmp2_mover_halt_reason_from_str (ndmp2_mover_halt_reason *valp, char * str); char * ndmp2_mover_halt_reason_to_str (ndmp2_mover_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp2_mover_halt_reason_table); } int ndmp2_mover_halt_reason_from_str (ndmp2_mover_halt_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_mover_halt_reason_table); } struct ndmp_enum_str_table ndmp2_mover_halt_reason_table[] = { { "NDMP2_MOVER_HALT_NA", NDMP2_MOVER_HALT_NA }, { "NDMP2_MOVER_HALT_CONNECT_CLOSED", NDMP2_MOVER_HALT_CONNECT_CLOSED }, { "NDMP2_MOVER_HALT_ABORTED", NDMP2_MOVER_HALT_ABORTED }, { "NDMP2_MOVER_HALT_INTERNAL_ERROR", NDMP2_MOVER_HALT_INTERNAL_ERROR }, { "NDMP2_MOVER_HALT_CONNECT_ERROR", NDMP2_MOVER_HALT_CONNECT_ERROR }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_mover_mode_table[]; extern char * ndmp2_mover_mode_to_str (ndmp2_mover_mode val); extern int ndmp2_mover_mode_from_str (ndmp2_mover_mode *valp, char * str); char * ndmp2_mover_mode_to_str (ndmp2_mover_mode val) { return ndmp_enum_to_str ((int)val, ndmp2_mover_mode_table); } int ndmp2_mover_mode_from_str (ndmp2_mover_mode *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_mover_mode_table); } struct ndmp_enum_str_table ndmp2_mover_mode_table[] = { { "NDMP2_MOVER_MODE_READ", NDMP2_MOVER_MODE_READ }, { "NDMP2_MOVER_MODE_WRITE", NDMP2_MOVER_MODE_WRITE }, { "NDMP2_MOVER_MODE_DATA", NDMP2_MOVER_MODE_DATA }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_data_operation_table[]; extern char * ndmp2_data_operation_to_str (ndmp2_data_operation val); extern int ndmp2_data_operation_from_str (ndmp2_data_operation *valp, char * str); char * ndmp2_data_operation_to_str (ndmp2_data_operation val) { return ndmp_enum_to_str ((int)val, ndmp2_data_operation_table); } int ndmp2_data_operation_from_str (ndmp2_data_operation *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_data_operation_table); } struct ndmp_enum_str_table ndmp2_data_operation_table[] = { { "NDMP2_DATA_OP_NOACTION", NDMP2_DATA_OP_NOACTION }, { "NDMP2_DATA_OP_BACKUP", NDMP2_DATA_OP_BACKUP }, { "NDMP2_DATA_OP_RESTORE", NDMP2_DATA_OP_RESTORE }, { "NDMP2_DATA_OP_RESTORE_FILEHIST", NDMP2_DATA_OP_RESTORE_FILEHIST }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_data_state_table[]; extern char * ndmp2_data_state_to_str (ndmp2_data_state val); extern int ndmp2_data_state_from_str (ndmp2_data_state *valp, char * str); char * ndmp2_data_state_to_str (ndmp2_data_state val) { return ndmp_enum_to_str ((int)val, ndmp2_data_state_table); } int ndmp2_data_state_from_str (ndmp2_data_state *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_data_state_table); } struct ndmp_enum_str_table ndmp2_data_state_table[] = { { "NDMP2_DATA_STATE_IDLE", NDMP2_DATA_STATE_IDLE }, { "NDMP2_DATA_STATE_ACTIVE", NDMP2_DATA_STATE_ACTIVE }, { "NDMP2_DATA_STATE_HALTED", NDMP2_DATA_STATE_HALTED }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_data_halt_reason_table[]; extern char * ndmp2_data_halt_reason_to_str (ndmp2_data_halt_reason val); extern int ndmp2_data_halt_reason_from_str (ndmp2_data_halt_reason *valp, char * str); char * ndmp2_data_halt_reason_to_str (ndmp2_data_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp2_data_halt_reason_table); } int ndmp2_data_halt_reason_from_str (ndmp2_data_halt_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_data_halt_reason_table); } struct ndmp_enum_str_table ndmp2_data_halt_reason_table[] = { { "NDMP2_DATA_HALT_NA", NDMP2_DATA_HALT_NA }, { "NDMP2_DATA_HALT_SUCCESSFUL", NDMP2_DATA_HALT_SUCCESSFUL }, { "NDMP2_DATA_HALT_ABORTED", NDMP2_DATA_HALT_ABORTED }, { "NDMP2_DATA_HALT_INTERNAL_ERROR", NDMP2_DATA_HALT_INTERNAL_ERROR }, { "NDMP2_DATA_HALT_CONNECT_ERROR", NDMP2_DATA_HALT_CONNECT_ERROR }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_connect_reason_table[]; extern char * ndmp2_connect_reason_to_str (ndmp2_connect_reason val); extern int ndmp2_connect_reason_from_str (ndmp2_connect_reason *valp, char * str); char * ndmp2_connect_reason_to_str (ndmp2_connect_reason val) { return ndmp_enum_to_str ((int)val, ndmp2_connect_reason_table); } int ndmp2_connect_reason_from_str (ndmp2_connect_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_connect_reason_table); } struct ndmp_enum_str_table ndmp2_connect_reason_table[] = { { "NDMP2_CONNECTED", NDMP2_CONNECTED }, { "NDMP2_SHUTDOWN", NDMP2_SHUTDOWN }, { "NDMP2_REFUSED", NDMP2_REFUSED }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_debug_level_table[]; extern char * ndmp2_debug_level_to_str (ndmp2_debug_level val); extern int ndmp2_debug_level_from_str (ndmp2_debug_level *valp, char * str); char * ndmp2_debug_level_to_str (ndmp2_debug_level val) { return ndmp_enum_to_str ((int)val, ndmp2_debug_level_table); } int ndmp2_debug_level_from_str (ndmp2_debug_level *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_debug_level_table); } struct ndmp_enum_str_table ndmp2_debug_level_table[] = { { "NDMP2_DBG_USER_INFO", NDMP2_DBG_USER_INFO }, { "NDMP2_DBG_USER_SUMMARY", NDMP2_DBG_USER_SUMMARY }, { "NDMP2_DBG_USER_DETAIL", NDMP2_DBG_USER_DETAIL }, { "NDMP2_DBG_DIAG_INFO", NDMP2_DBG_DIAG_INFO }, { "NDMP2_DBG_DIAG_SUMMARY", NDMP2_DBG_DIAG_SUMMARY }, { "NDMP2_DBG_DIAG_DETAIL", NDMP2_DBG_DIAG_DETAIL }, { "NDMP2_DBG_PROG_INFO", NDMP2_DBG_PROG_INFO }, { "NDMP2_DBG_PROG_SUMMARY", NDMP2_DBG_PROG_SUMMARY }, { "NDMP2_DBG_PROG_DETAIL", NDMP2_DBG_PROG_DETAIL }, { 0 } }; extern struct ndmp_enum_str_table ndmp2_unix_file_type_table[]; extern char * ndmp2_unix_file_type_to_str (ndmp2_unix_file_type val); extern int ndmp2_unix_file_type_from_str (ndmp2_unix_file_type *valp, char * str); char * ndmp2_unix_file_type_to_str (ndmp2_unix_file_type val) { return ndmp_enum_to_str ((int)val, ndmp2_unix_file_type_table); } int ndmp2_unix_file_type_from_str (ndmp2_unix_file_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp2_unix_file_type_table); } struct ndmp_enum_str_table ndmp2_unix_file_type_table[] = { { "NDMP2_FILE_DIR", NDMP2_FILE_DIR }, { "NDMP2_FILE_FIFO", NDMP2_FILE_FIFO }, { "NDMP2_FILE_CSPEC", NDMP2_FILE_CSPEC }, { "NDMP2_FILE_BSPEC", NDMP2_FILE_BSPEC }, { "NDMP2_FILE_REG", NDMP2_FILE_REG }, { "NDMP2_FILE_SLINK", NDMP2_FILE_SLINK }, { "NDMP2_FILE_SOCK", NDMP2_FILE_SOCK }, { 0 } }; #endif /* !NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp2_enum_strs.h000066400000000000000000000120621263011562700214560ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_NDMP2 extern struct ndmp_enum_str_table ndmp2_error_table[]; extern char * ndmp2_error_to_str (ndmp2_error val); extern int ndmp2_error_from_str (ndmp2_error *valp, char * str); extern struct ndmp_enum_str_table ndmp2_header_message_type_table[]; extern char * ndmp2_header_message_type_to_str (ndmp2_header_message_type val); extern int ndmp2_header_message_type_from_str (ndmp2_header_message_type *valp, char * str); extern struct ndmp_enum_str_table ndmp2_message_table[]; extern char * ndmp2_message_to_str (ndmp2_message val); extern int ndmp2_message_from_str (ndmp2_message *valp, char * str); extern struct ndmp_enum_str_table ndmp2_auth_type_table[]; extern char * ndmp2_auth_type_to_str (ndmp2_auth_type val); extern int ndmp2_auth_type_from_str (ndmp2_auth_type *valp, char * str); extern struct ndmp_enum_str_table ndmp2_mover_addr_type_table[]; extern char * ndmp2_mover_addr_type_to_str (ndmp2_mover_addr_type val); extern int ndmp2_mover_addr_type_from_str (ndmp2_mover_addr_type *valp, char * str); extern struct ndmp_enum_str_table ndmp2_tape_open_mode_table[]; extern char * ndmp2_tape_open_mode_to_str (ndmp2_tape_open_mode val); extern int ndmp2_tape_open_mode_from_str (ndmp2_tape_open_mode *valp, char * str); extern struct ndmp_enum_str_table ndmp2_tape_mtio_op_table[]; extern char * ndmp2_tape_mtio_op_to_str (ndmp2_tape_mtio_op val); extern int ndmp2_tape_mtio_op_from_str (ndmp2_tape_mtio_op *valp, char * str); extern struct ndmp_enum_str_table ndmp2_mover_state_table[]; extern char * ndmp2_mover_state_to_str (ndmp2_mover_state val); extern int ndmp2_mover_state_from_str (ndmp2_mover_state *valp, char * str); extern struct ndmp_enum_str_table ndmp2_mover_pause_reason_table[]; extern char * ndmp2_mover_pause_reason_to_str (ndmp2_mover_pause_reason val); extern int ndmp2_mover_pause_reason_from_str (ndmp2_mover_pause_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp2_mover_halt_reason_table[]; extern char * ndmp2_mover_halt_reason_to_str (ndmp2_mover_halt_reason val); extern int ndmp2_mover_halt_reason_from_str (ndmp2_mover_halt_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp2_mover_mode_table[]; extern char * ndmp2_mover_mode_to_str (ndmp2_mover_mode val); extern int ndmp2_mover_mode_from_str (ndmp2_mover_mode *valp, char * str); extern struct ndmp_enum_str_table ndmp2_data_operation_table[]; extern char * ndmp2_data_operation_to_str (ndmp2_data_operation val); extern int ndmp2_data_operation_from_str (ndmp2_data_operation *valp, char * str); extern struct ndmp_enum_str_table ndmp2_data_state_table[]; extern char * ndmp2_data_state_to_str (ndmp2_data_state val); extern int ndmp2_data_state_from_str (ndmp2_data_state *valp, char * str); extern struct ndmp_enum_str_table ndmp2_data_halt_reason_table[]; extern char * ndmp2_data_halt_reason_to_str (ndmp2_data_halt_reason val); extern int ndmp2_data_halt_reason_from_str (ndmp2_data_halt_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp2_connect_reason_table[]; extern char * ndmp2_connect_reason_to_str (ndmp2_connect_reason val); extern int ndmp2_connect_reason_from_str (ndmp2_connect_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp2_debug_level_table[]; extern char * ndmp2_debug_level_to_str (ndmp2_debug_level val); extern int ndmp2_debug_level_from_str (ndmp2_debug_level *valp, char * str); extern struct ndmp_enum_str_table ndmp2_unix_file_type_table[]; extern char * ndmp2_unix_file_type_to_str (ndmp2_unix_file_type val); extern int ndmp2_unix_file_type_from_str (ndmp2_unix_file_type *valp, char * str); #endif /* !NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp2_pp.c000066400000000000000000000452731263011562700200630ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP2 int ndmp2_pp_header (void *data, char *buf) { ndmp2_header * mh = (ndmp2_header *) data; if (mh->message_type == NDMP2_MESSAGE_REQUEST) { sprintf (buf, "C %s %lu", ndmp2_message_to_str (mh->message), mh->sequence); } else if (mh->message_type == NDMP2_MESSAGE_REPLY) { sprintf (buf, "R %s %lu (%lu)", ndmp2_message_to_str (mh->message), mh->reply_sequence, mh->sequence); if (mh->error != NDMP2_NO_ERR) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp2_error_to_str (mh->error)); return 0; /* no body */ } } else { strcpy (buf, "??? INVALID MESSAGE TYPE"); return -1; /* no body */ } return 1; /* body */ } int ndmp2_pp_mover_addr (char *buf, ndmp2_mover_addr *ma) { sprintf (buf, "%s", ndmp2_mover_addr_type_to_str (ma->addr_type)); if (ma->addr_type == NDMP2_ADDR_TCP) { sprintf (NDMOS_API_STREND(buf), "(%lx,%d)", ma->ndmp2_mover_addr_u.addr.ip_addr, ma->ndmp2_mover_addr_u.addr.port); } return 0; } int ndmp2_pp_request (ndmp2_message msg, void *data, int lineno, char *buf) { int i; unsigned int j; switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP2_CONNECT_OPEN: NDMP_PP_WITH(ndmp2_connect_open_request) sprintf (buf, "version=%d", p->protocol_version); NDMP_PP_ENDWITH break; case NDMP2_CONNECT_CLIENT_AUTH: NDMP_PP_WITH(ndmp2_connect_client_auth_request) sprintf (buf, "auth_type=%s", ndmp2_auth_type_to_str (p->auth_data.auth_type)); switch (p->auth_data.auth_type) { case NDMP2_AUTH_NONE: break; case NDMP2_AUTH_TEXT: sprintf (NDMOS_API_STREND(buf), " auth_id=%s", p->auth_data.ndmp2_auth_data_u.auth_text.auth_id); break; case NDMP2_AUTH_MD5: sprintf (NDMOS_API_STREND(buf), " auth_id=%s", p->auth_data.ndmp2_auth_data_u.auth_md5.auth_id); break; default: sprintf (NDMOS_API_STREND(buf), " ????"); break; } NDMP_PP_ENDWITH break; case NDMP2_CONNECT_CLOSE: case NDMP2_CONFIG_GET_HOST_INFO: case NDMP2_CONFIG_GET_MOVER_TYPE: case NDMP2_SCSI_CLOSE: case NDMP2_SCSI_GET_STATE: case NDMP2_SCSI_RESET_DEVICE: case NDMP2_SCSI_RESET_BUS: case NDMP2_TAPE_GET_STATE: case NDMP2_TAPE_CLOSE: case NDMP2_MOVER_GET_STATE: case NDMP2_MOVER_CONTINUE: case NDMP2_MOVER_ABORT: case NDMP2_MOVER_STOP: case NDMP2_MOVER_CLOSE: case NDMP2_DATA_GET_STATE: case NDMP2_DATA_ABORT: case NDMP2_DATA_STOP: case NDMP2_DATA_GET_ENV: *buf = 0; /* no body */ return 0; case NDMP2_CONNECT_SERVER_AUTH: strcpy (buf, "<>"); break; case NDMP2_CONFIG_GET_BUTYPE_ATTR: NDMP_PP_WITH(ndmp2_config_get_butype_attr_request) sprintf (buf, "bu_type='%s'", p->name); NDMP_PP_ENDWITH break; case NDMP2_CONFIG_GET_AUTH_ATTR: NDMP_PP_WITH(ndmp2_config_get_auth_attr_request) sprintf (buf, "auth_type=%s", ndmp2_auth_type_to_str (p->auth_type)); NDMP_PP_ENDWITH break; case NDMP2_SCSI_OPEN: NDMP_PP_WITH(ndmp2_scsi_open_request) sprintf (buf, "device='%s'", p->device.name); NDMP_PP_ENDWITH break; case NDMP2_SCSI_SET_TARGET: NDMP_PP_WITH(ndmp2_scsi_set_target_request) sprintf (buf, "device='%s' cont=%d sid=%d lun=%d", p->device.name, p->target_controller, p->target_id, p->target_lun); NDMP_PP_ENDWITH break; case NDMP2_SCSI_EXECUTE_CDB: case NDMP2_TAPE_EXECUTE_CDB: NDMP_PP_WITH(ndmp2_execute_cdb_request) switch (lineno) { case 0: sprintf (buf, "flags=0x%lx timeout=%ld datain_len=%ld", p->flags, p->timeout, p->datain_len); break; case 1: sprintf (buf, "cmd[%d]={", p->cdb.cdb_len); for (j = 0; j < p->cdb.cdb_len; j++) { sprintf (NDMOS_API_STREND(buf), " %02x", p->cdb.cdb_val[j]&0xFF); } strcat (buf, " }"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP2_TAPE_OPEN: NDMP_PP_WITH(ndmp2_tape_open_request) sprintf (buf, "device='%s' mode=%s", p->device.name, ndmp2_tape_open_mode_to_str (p->mode)); NDMP_PP_ENDWITH break; case NDMP2_TAPE_MTIO: NDMP_PP_WITH(ndmp2_tape_mtio_request) sprintf (buf, "op=%s count=%ld", ndmp2_tape_mtio_op_to_str(p->tape_op), p->count); NDMP_PP_ENDWITH break; case NDMP2_TAPE_WRITE: NDMP_PP_WITH(ndmp2_tape_write_request) sprintf (buf, "data_out_len=%d", p->data_out.data_out_len); NDMP_PP_ENDWITH break; case NDMP2_TAPE_READ: NDMP_PP_WITH(ndmp2_tape_read_request) sprintf (buf, "count=%ld", p->count); NDMP_PP_ENDWITH break; case NDMP2_DATA_START_BACKUP: NDMP_PP_WITH(ndmp2_data_start_backup_request) if (lineno == 0) { sprintf (buf, "bu_type='%s' n_env=%d mover=", p->bu_type, p->env.env_len); ndmp2_pp_mover_addr (NDMOS_API_STREND(buf), &p->mover); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "env[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { strcpy (buf, "--INVALID--"); } } return 1 + p->env.env_len; NDMP_PP_ENDWITH break; case NDMP2_DATA_START_RECOVER: case NDMP2_DATA_START_RECOVER_FILEHIST: NDMP_PP_WITH(ndmp2_data_start_recover_request) if (lineno == 0) { sprintf (buf, "bu_type='%s' n_env=%d n_nlist=%d mover=", p->bu_type, p->env.env_len, p->nlist.nlist_len); ndmp2_pp_mover_addr (NDMOS_API_STREND(buf), &p->mover); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "env[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { i -= p->env.env_len; if (0 <= i && (unsigned)i < p->nlist.nlist_len) { sprintf (buf, "nl[%d] name='%s' fhi=%lld dest='%s'", i, p->nlist.nlist_val[i].name, p->nlist.nlist_val[i].fh_info, p->nlist.nlist_val[i].dest); } else { strcpy (buf, "--INVALID--"); } } } return 1 + p->env.env_len + p->nlist.nlist_len; NDMP_PP_ENDWITH break; case NDMP2_NOTIFY_DATA_HALTED: NDMP_PP_WITH(ndmp2_notify_data_halted_request) sprintf (buf, "reason=%s text_reason='%s'", ndmp2_data_halt_reason_to_str(p->reason), p->text_reason); NDMP_PP_ENDWITH break; case NDMP2_NOTIFY_CONNECTED: NDMP_PP_WITH(ndmp2_notify_connected_request) sprintf (buf, "reason=%s protocol_version=%d text_reason='%s'", ndmp2_connect_reason_to_str(p->reason), p->protocol_version, p->text_reason); NDMP_PP_ENDWITH break; case NDMP2_NOTIFY_MOVER_HALTED: NDMP_PP_WITH(ndmp2_notify_mover_halted_request) sprintf (buf, "reason=%s text_reason='%s'", ndmp2_mover_halt_reason_to_str(p->reason), p->text_reason); NDMP_PP_ENDWITH break; case NDMP2_NOTIFY_MOVER_PAUSED: NDMP_PP_WITH(ndmp2_notify_mover_paused_request) sprintf (buf, "reason=%s seek_position=%lld", ndmp2_mover_pause_reason_to_str(p->reason), p->seek_position); NDMP_PP_ENDWITH break; case NDMP2_NOTIFY_DATA_READ: NDMP_PP_WITH(ndmp2_notify_data_read_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP2_LOG_LOG: NDMP_PP_WITH(ndmp2_log_log_request) sprintf (buf, "entry='%s'", p->entry); NDMP_PP_ENDWITH break; case NDMP2_LOG_DEBUG: NDMP_PP_WITH(ndmp2_log_debug_request) sprintf (buf, "level=%s message='%s'", ndmp2_debug_level_to_str(p->level), p->message); NDMP_PP_ENDWITH break; case NDMP2_LOG_FILE: NDMP_PP_WITH(ndmp2_log_file_request) sprintf (buf, "file=%s error=%s", p->name, ndmp2_error_to_str(p->error)); NDMP_PP_ENDWITH break; case NDMP2_FH_ADD_UNIX_PATH: NDMP_PP_WITH(ndmp2_fh_add_unix_path_request) if (lineno == 0) { sprintf (buf, "n_paths=%d", p->paths.paths_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->paths.paths_len) { struct ndmp2_fh_unix_path *pa; pa = &p->paths.paths_val[i]; sprintf (buf, "[%d] %-15s %7llu %s [%lld]", i, ndmp2_unix_file_type_to_str(pa->fstat.ftype), pa->fstat.size, pa->name, pa->fstat.fh_info); } else { strcpy (buf, "--INVALID--"); } } return 1 + p->paths.paths_len; NDMP_PP_ENDWITH break; case NDMP2_FH_ADD_UNIX_DIR: NDMP_PP_WITH(ndmp2_fh_add_unix_dir_request) if (lineno == 0) { sprintf (buf, "n_dirs=%d", p->dirs.dirs_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->dirs.dirs_len) { struct ndmp2_fh_unix_dir *de; de = &p->dirs.dirs_val[i]; sprintf (buf, "[%d] %lu %lu %s", i, de->node, de->parent, de->name); } else { strcpy (buf, "--INVALID--"); } } return 1 + p->dirs.dirs_len; NDMP_PP_ENDWITH break; case NDMP2_FH_ADD_UNIX_NODE: NDMP_PP_WITH(ndmp2_fh_add_unix_node_request) if (lineno == 0) { sprintf (buf, "n_nodes=%d", p->nodes.nodes_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->nodes.nodes_len) { struct ndmp2_fh_unix_node *nd; nd = &p->nodes.nodes_val[i]; sprintf (buf, "[%d] %-15s %7llu %lu [%lld]", i, ndmp2_unix_file_type_to_str(nd->fstat.ftype), nd->fstat.size, nd->node, nd->fstat.fh_info); } else { strcpy (buf, "--INVALID--"); } } return 1 + p->nodes.nodes_len; NDMP_PP_ENDWITH break; case NDMP2_MOVER_LISTEN: NDMP_PP_WITH(ndmp2_mover_listen_request) sprintf (buf, "mode=%s addr_type=%s", ndmp2_mover_mode_to_str (p->mode), ndmp2_mover_addr_type_to_str (p->addr_type)); NDMP_PP_ENDWITH break; case NDMP2_MOVER_SET_WINDOW: NDMP_PP_WITH(ndmp2_mover_set_window_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP2_MOVER_READ: NDMP_PP_WITH(ndmp2_mover_read_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP2_MOVER_SET_RECORD_SIZE: NDMP_PP_WITH(ndmp2_mover_set_record_size_request) sprintf (buf, "len=%lu", p->len); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } int ndmp2_pp_reply (ndmp2_message msg, void *data, int lineno, char *buf) { int i; unsigned int j; switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP2_CONNECT_OPEN: case NDMP2_CONNECT_CLIENT_AUTH: case NDMP2_SCSI_OPEN: case NDMP2_SCSI_CLOSE: case NDMP2_SCSI_SET_TARGET: case NDMP2_SCSI_RESET_DEVICE: case NDMP2_SCSI_RESET_BUS: case NDMP2_TAPE_OPEN: case NDMP2_TAPE_CLOSE: case NDMP2_MOVER_CONTINUE: case NDMP2_MOVER_ABORT: case NDMP2_MOVER_STOP: case NDMP2_MOVER_READ: case NDMP2_MOVER_SET_WINDOW: case NDMP2_MOVER_CLOSE: case NDMP2_MOVER_SET_RECORD_SIZE: case NDMP2_DATA_START_BACKUP: case NDMP2_DATA_START_RECOVER: case NDMP2_DATA_START_RECOVER_FILEHIST: case NDMP2_DATA_ABORT: case NDMP2_DATA_STOP: NDMP_PP_WITH(ndmp2_error) sprintf (buf, "error=%s", ndmp2_error_to_str(*p)); NDMP_PP_ENDWITH break; case NDMP2_CONNECT_CLOSE: *buf = 0; return 0; case NDMP2_CONNECT_SERVER_AUTH: strcpy (buf, "<>"); break; case NDMP2_CONFIG_GET_HOST_INFO: NDMP_PP_WITH(ndmp2_config_get_host_info_reply) switch (lineno) { case 0: sprintf (buf, "error=%s hostname=%s", ndmp2_error_to_str(p->error), p->hostname); break; case 1: sprintf (buf, "os_type=%s os_vers=%s hostid=%s", p->os_type, p->os_vers, p->hostid); break; case 2: sprintf (buf, "auth_type[%d]={", p->auth_type.auth_type_len); for (j = 0; j < p->auth_type.auth_type_len; j++) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp2_auth_type_to_str( p->auth_type.auth_type_val[j])); } strcat (buf, " }"); break; default: strcpy (buf, "--INVALID--"); break; } return 3; NDMP_PP_ENDWITH break; case NDMP2_CONFIG_GET_BUTYPE_ATTR: NDMP_PP_WITH(ndmp2_config_get_butype_attr_reply) sprintf (buf, "error=%s attrs=0x%lx", ndmp2_error_to_str(p->error), p->attrs); NDMP_PP_ENDWITH break; case NDMP2_CONFIG_GET_MOVER_TYPE: NDMP_PP_WITH(ndmp2_config_get_mover_type_reply) sprintf (buf, "error=%s methods[%d]={", ndmp2_error_to_str(p->error), p->methods.methods_len); for (j = 0; j < p->methods.methods_len; j++) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp2_mover_addr_type_to_str(p->methods.methods_val[j])); } strcat (buf, " }"); NDMP_PP_ENDWITH break; case NDMP2_CONFIG_GET_AUTH_ATTR: strcpy (buf, "<>"); break; case NDMP2_SCSI_GET_STATE: NDMP_PP_WITH(ndmp2_scsi_get_state_reply) sprintf (buf, "error=%s cont=%d sid=%d lun=%d", ndmp2_error_to_str(p->error), p->target_controller, p->target_id, p->target_lun); NDMP_PP_ENDWITH break; case NDMP2_SCSI_EXECUTE_CDB: case NDMP2_TAPE_EXECUTE_CDB: NDMP_PP_WITH(ndmp2_execute_cdb_reply) switch (lineno) { case 0: sprintf (buf, "error=%s status=%02x dataout_len=%ld datain_len=%d", ndmp2_error_to_str(p->error), p->status, p->dataout_len, p->datain.datain_len); break; case 1: sprintf (buf, "sense[%d]={", p->ext_sense.ext_sense_len); for (j = 0; j < p->ext_sense.ext_sense_len; j++) { sprintf (NDMOS_API_STREND(buf), " %02x", p->ext_sense.ext_sense_val[j]&0xFF); } strcat (buf, " }"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP2_TAPE_GET_STATE: NDMP_PP_WITH(ndmp2_tape_get_state_reply) switch (lineno) { case 0: sprintf (buf, "error=%s flags=0x%lx file_num=%ld", ndmp2_error_to_str(p->error), p->flags, p->file_num); break; case 1: sprintf (buf, "soft_errors=%lu block_size=%lu blockno=%lu", p->soft_errors, p->block_size, p->blockno); break; case 2: sprintf (buf, "total_space=%lld space_remain=%lld", p->total_space, p->space_remain); break; default: strcpy (buf, "--INVALID--"); break; } return 3; NDMP_PP_ENDWITH break; case NDMP2_TAPE_MTIO: NDMP_PP_WITH(ndmp2_tape_mtio_reply) sprintf (buf, "error=%s resid_count=%ld", ndmp2_error_to_str(p->error), p->resid_count); NDMP_PP_ENDWITH break; case NDMP2_TAPE_WRITE: NDMP_PP_WITH(ndmp2_tape_write_reply) sprintf (buf, "error=%s count=%ld", ndmp2_error_to_str(p->error), p->count); NDMP_PP_ENDWITH break; case NDMP2_TAPE_READ: NDMP_PP_WITH(ndmp2_tape_read_reply) sprintf (buf, "error=%s data_in_len=%d", ndmp2_error_to_str(p->error), p->data_in.data_in_len); NDMP_PP_ENDWITH break; case NDMP2_DATA_GET_STATE: NDMP_PP_WITH(ndmp2_data_get_state_reply) switch (lineno) { case 0: sprintf (buf, "error=%s op=%s", ndmp2_error_to_str(p->error), ndmp2_data_operation_to_str(p->operation)); break; case 1: sprintf (buf, "state=%s", ndmp2_data_state_to_str(p->state)); break; case 2: sprintf (buf, "halt_reason=%s", ndmp2_data_halt_reason_to_str(p->halt_reason)); break; case 3: sprintf (buf, "bytes_processed=%lld est_bytes_remain=%lld", p->bytes_processed, p->est_bytes_remain); break; case 4: sprintf (buf, "est_time_remain=%ld mover=", p->est_time_remain); ndmp2_pp_mover_addr (NDMOS_API_STREND(buf), &p->mover); break; case 5: sprintf (buf, "read_offset=%lld read_length=%lld", p->read_offset, p->read_length); break; default: strcpy (buf, "--INVALID--"); break; } return 6; NDMP_PP_ENDWITH break; case NDMP2_DATA_GET_ENV: NDMP_PP_WITH(ndmp2_data_get_env_reply) if (lineno == 0) { sprintf (buf, "error=%s n_env=%d", ndmp2_error_to_str(p->error), p->env.env_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { strcpy (buf, "--INVALID--"); } } return p->env.env_len + 1; NDMP_PP_ENDWITH break; case NDMP2_NOTIFY_DATA_HALTED: case NDMP2_NOTIFY_CONNECTED: case NDMP2_NOTIFY_MOVER_HALTED: case NDMP2_NOTIFY_MOVER_PAUSED: case NDMP2_NOTIFY_DATA_READ: case NDMP2_LOG_LOG: case NDMP2_LOG_DEBUG: case NDMP2_LOG_FILE: case NDMP2_FH_ADD_UNIX_PATH: case NDMP2_FH_ADD_UNIX_DIR: case NDMP2_FH_ADD_UNIX_NODE: strcpy (buf, "<>"); break; case NDMP2_MOVER_GET_STATE: NDMP_PP_WITH(ndmp2_mover_get_state_reply) switch (lineno) { case 0: sprintf (buf, "error=%s state=%s", ndmp2_error_to_str(p->error), ndmp2_mover_state_to_str(p->state)); break; case 1: sprintf (buf, "pause_reason=%s", ndmp2_mover_pause_reason_to_str(p->pause_reason)); break; case 2: sprintf (buf, "halt_reason=%s", ndmp2_mover_halt_reason_to_str(p->halt_reason)); break; case 3: sprintf (buf,"record_size=%lu record_num=%lu data_written=%lld", p->record_size, p->record_num, p->data_written); break; case 4: sprintf (buf, "seek=%lld to_read=%lld win_off=%lld win_len=%lld", p->seek_position, p->bytes_left_to_read, p->window_offset, p->window_length); break; default: strcpy (buf, "--INVALID--"); break; } return 5; NDMP_PP_ENDWITH break; case NDMP2_MOVER_LISTEN: NDMP_PP_WITH(ndmp2_mover_listen_reply) sprintf (buf, "error=%s mover=", ndmp2_error_to_str(p->error)); ndmp2_pp_mover_addr (NDMOS_API_STREND(buf), &p->mover); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } #endif /* NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp2_translate.c000066400000000000000000002054051263011562700214340ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #include "ndmp_msg_buf.h" #include "ndmp_translate.h" #ifndef NDMOS_OPTION_NO_NDMP2 /* * Pervasive Types **************************************************************** */ /* * ndmp_error */ struct enum_conversion ndmp_29_error[] = { { NDMP2_UNDEFINED_ERR, NDMP9_UNDEFINED_ERR }, /* default */ { NDMP2_NO_ERR, NDMP9_NO_ERR }, { NDMP2_NOT_SUPPORTED_ERR, NDMP9_NOT_SUPPORTED_ERR }, { NDMP2_DEVICE_BUSY_ERR, NDMP9_DEVICE_BUSY_ERR }, { NDMP2_DEVICE_OPENED_ERR, NDMP9_DEVICE_OPENED_ERR }, { NDMP2_NOT_AUTHORIZED_ERR, NDMP9_NOT_AUTHORIZED_ERR }, { NDMP2_PERMISSION_ERR, NDMP9_PERMISSION_ERR }, { NDMP2_DEV_NOT_OPEN_ERR, NDMP9_DEV_NOT_OPEN_ERR }, { NDMP2_IO_ERR, NDMP9_IO_ERR }, { NDMP2_TIMEOUT_ERR, NDMP9_TIMEOUT_ERR }, { NDMP2_ILLEGAL_ARGS_ERR, NDMP9_ILLEGAL_ARGS_ERR }, { NDMP2_NO_TAPE_LOADED_ERR, NDMP9_NO_TAPE_LOADED_ERR }, { NDMP2_WRITE_PROTECT_ERR, NDMP9_WRITE_PROTECT_ERR }, { NDMP2_EOF_ERR, NDMP9_EOF_ERR }, { NDMP2_EOM_ERR, NDMP9_EOM_ERR }, { NDMP2_FILE_NOT_FOUND_ERR, NDMP9_FILE_NOT_FOUND_ERR }, { NDMP2_BAD_FILE_ERR, NDMP9_BAD_FILE_ERR }, { NDMP2_NO_DEVICE_ERR, NDMP9_NO_DEVICE_ERR }, { NDMP2_NO_BUS_ERR, NDMP9_NO_BUS_ERR }, { NDMP2_XDR_DECODE_ERR, NDMP9_XDR_DECODE_ERR }, { NDMP2_ILLEGAL_STATE_ERR, NDMP9_ILLEGAL_STATE_ERR }, { NDMP2_UNDEFINED_ERR, NDMP9_UNDEFINED_ERR }, { NDMP2_XDR_ENCODE_ERR, NDMP9_XDR_ENCODE_ERR }, { NDMP2_NO_MEM_ERR, NDMP9_NO_MEM_ERR }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_error ( ndmp2_error *error2, ndmp9_error *error9) { *error9 = convert_enum_to_9 (ndmp_29_error, *error2); return 0; } int ndmp_9to2_error ( ndmp9_error *error9, ndmp2_error *error2) { *error2 = convert_enum_from_9 (ndmp_29_error, *error9); return 0; } /* * ndmp_pval **************************************************************** */ int ndmp_2to9_pval ( ndmp2_pval *pval2, ndmp9_pval *pval9) { CNVT_STRDUP_TO_9(pval2, pval9, name); CNVT_STRDUP_TO_9(pval2, pval9, value); return 0; } int ndmp_9to2_pval ( ndmp9_pval *pval9, ndmp2_pval *pval2) { CNVT_STRDUP_FROM_9(pval2, pval9, name); CNVT_STRDUP_FROM_9(pval2, pval9, value); return 0; } int ndmp_2to9_pval_vec ( ndmp2_pval *pval2, ndmp9_pval *pval9, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_2to9_pval (&pval2[i], &pval9[i]); return 0; } int ndmp_9to2_pval_vec ( ndmp9_pval *pval9, ndmp2_pval *pval2, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_9to2_pval (&pval9[i], &pval2[i]); return 0; } int ndmp_2to9_pval_vec_dup ( ndmp2_pval *pval2, ndmp9_pval **pval9_p, unsigned n_pval) { *pval9_p = NDMOS_MACRO_NEWN (ndmp9_pval, n_pval); if (!*pval9_p) return -1; return ndmp_2to9_pval_vec (pval2, *pval9_p, n_pval); } int ndmp_9to2_pval_vec_dup ( ndmp9_pval *pval9, ndmp2_pval **pval2_p, unsigned n_pval) { *pval2_p = NDMOS_MACRO_NEWN (ndmp2_pval, n_pval); if (!*pval2_p) return -1; return ndmp_9to2_pval_vec (pval9, *pval2_p, n_pval); } /* * ndmp[_mover]_addr */ struct enum_conversion ndmp_29_mover_addr_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL }, /* default */ { NDMP2_ADDR_LOCAL, NDMP9_ADDR_LOCAL }, { NDMP2_ADDR_TCP, NDMP9_ADDR_TCP }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_mover_addr ( ndmp2_mover_addr *addr2, ndmp9_addr *addr9) { switch (addr2->addr_type) { case NDMP2_ADDR_LOCAL: addr9->addr_type = NDMP9_ADDR_LOCAL; break; case NDMP2_ADDR_TCP: addr9->addr_type = NDMP9_ADDR_TCP; addr9->ndmp9_addr_u.tcp_addr.ip_addr = addr2->ndmp2_mover_addr_u.addr.ip_addr; addr9->ndmp9_addr_u.tcp_addr.port = addr2->ndmp2_mover_addr_u.addr.port; break; default: NDMOS_MACRO_ZEROFILL (addr9); addr9->addr_type = -1; return -1; } return 0; } int ndmp_9to2_mover_addr ( ndmp9_addr *addr9, ndmp2_mover_addr *addr2) { switch (addr9->addr_type) { case NDMP9_ADDR_LOCAL: addr2->addr_type = NDMP2_ADDR_LOCAL; break; case NDMP9_ADDR_TCP: addr2->addr_type = NDMP2_ADDR_TCP; addr2->ndmp2_mover_addr_u.addr.ip_addr = addr9->ndmp9_addr_u.tcp_addr.ip_addr; addr2->ndmp2_mover_addr_u.addr.port = addr9->ndmp9_addr_u.tcp_addr.port; break; default: NDMOS_MACRO_ZEROFILL (addr2); addr2->addr_type = -1; return -1; } return 0; } /* * CONNECT INTERFACES **************************************************************** */ struct enum_conversion ndmp_29_auth_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL }, /* default */ { NDMP2_AUTH_NONE, NDMP9_AUTH_NONE }, { NDMP2_AUTH_TEXT, NDMP9_AUTH_TEXT }, { NDMP2_AUTH_MD5, NDMP9_AUTH_MD5 }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_auth_data ( ndmp2_auth_data *auth_data2, ndmp9_auth_data *auth_data9) { int n_error = 0; int rc; ndmp2_auth_text *text2; ndmp9_auth_text *text9; ndmp2_auth_md5 *md52; ndmp9_auth_md5 *md59; switch (auth_data2->auth_type) { case NDMP2_AUTH_NONE: auth_data9->auth_type = NDMP9_AUTH_NONE; break; case NDMP2_AUTH_TEXT: auth_data9->auth_type = NDMP9_AUTH_TEXT; text2 = &auth_data2->ndmp2_auth_data_u.auth_text; text9 = &auth_data9->ndmp9_auth_data_u.auth_text; rc = CNVT_STRDUP_TO_9(text2, text9, auth_id); if (rc) { return rc; /* no mem */ } rc = CNVT_STRDUP_TO_9(text2, text9, auth_password); if (rc) { NDMOS_API_FREE (text9->auth_id); text9->auth_id = 0; return rc; /* no mem */ } break; case NDMP2_AUTH_MD5: auth_data9->auth_type = NDMP9_AUTH_MD5; md52 = &auth_data2->ndmp2_auth_data_u.auth_md5; md59 = &auth_data9->ndmp9_auth_data_u.auth_md5; rc = CNVT_STRDUP_TO_9(md52, md59, auth_id); if (rc) { return rc; /* no mem */ } NDMOS_API_BCOPY (md52->auth_digest, md59->auth_digest, 16); break; default: auth_data9->auth_type = auth_data2->auth_type; NDMOS_MACRO_ZEROFILL (&auth_data9->ndmp9_auth_data_u); n_error++; break; } return n_error; } int ndmp_9to2_auth_data ( ndmp9_auth_data *auth_data9, ndmp2_auth_data *auth_data2) { int n_error = 0; int rc; ndmp9_auth_text *text9; ndmp2_auth_text *text2; ndmp9_auth_md5 *md59; ndmp2_auth_md5 *md52; switch (auth_data9->auth_type) { case NDMP9_AUTH_NONE: auth_data2->auth_type = NDMP2_AUTH_NONE; break; case NDMP9_AUTH_TEXT: auth_data2->auth_type = NDMP2_AUTH_TEXT; text9 = &auth_data9->ndmp9_auth_data_u.auth_text; text2 = &auth_data2->ndmp2_auth_data_u.auth_text; rc = CNVT_STRDUP_FROM_9(text2, text9, auth_id); if (rc) { return rc; /* no mem */ } rc = CNVT_STRDUP_FROM_9(text2, text9, auth_password); if (rc) { NDMOS_API_FREE (text9->auth_id); text2->auth_id = 0; return rc; /* no mem */ } break; case NDMP9_AUTH_MD5: auth_data2->auth_type = NDMP2_AUTH_MD5; md59 = &auth_data9->ndmp9_auth_data_u.auth_md5; md52 = &auth_data2->ndmp2_auth_data_u.auth_md5; rc = CNVT_STRDUP_FROM_9(md52, md59, auth_id); if (rc) { return rc; /* no mem */ } NDMOS_API_BCOPY (md59->auth_digest, md52->auth_digest, 16); break; default: auth_data2->auth_type = auth_data9->auth_type; NDMOS_MACRO_ZEROFILL (&auth_data2->ndmp2_auth_data_u); n_error++; break; } return n_error; } int ndmp_2to9_auth_attr ( ndmp2_auth_attr *auth_attr2, ndmp9_auth_attr *auth_attr9) { int n_error = 0; switch (auth_attr2->auth_type) { case NDMP2_AUTH_NONE: auth_attr9->auth_type = NDMP9_AUTH_NONE; break; case NDMP2_AUTH_TEXT: auth_attr9->auth_type = NDMP9_AUTH_TEXT; break; case NDMP2_AUTH_MD5: auth_attr9->auth_type = NDMP9_AUTH_MD5; NDMOS_API_BCOPY (auth_attr2->ndmp2_auth_attr_u.challenge, auth_attr9->ndmp9_auth_attr_u.challenge, 64); break; default: auth_attr9->auth_type = auth_attr2->auth_type; NDMOS_MACRO_ZEROFILL (&auth_attr9->ndmp9_auth_attr_u); n_error++; break; } return n_error; } int ndmp_9to2_auth_attr ( ndmp9_auth_attr *auth_attr9, ndmp2_auth_attr *auth_attr2) { int n_error = 0; switch (auth_attr9->auth_type) { case NDMP9_AUTH_NONE: auth_attr2->auth_type = NDMP2_AUTH_NONE; break; case NDMP9_AUTH_TEXT: auth_attr2->auth_type = NDMP2_AUTH_TEXT; break; case NDMP9_AUTH_MD5: auth_attr2->auth_type = NDMP2_AUTH_MD5; NDMOS_API_BCOPY (auth_attr9->ndmp9_auth_attr_u.challenge, auth_attr2->ndmp2_auth_attr_u.challenge, 64); break; default: auth_attr2->auth_type = auth_attr9->auth_type; NDMOS_MACRO_ZEROFILL (&auth_attr2->ndmp2_auth_attr_u); n_error++; break; } return n_error; } /* * ndmp_connect_open * just error reply */ int ndmp_2to9_connect_open_request ( ndmp2_connect_open_request *request2, ndmp9_connect_open_request *request9) { CNVT_TO_9 (request2, request9, protocol_version); return 0; } int ndmp_9to2_connect_open_request ( ndmp9_connect_open_request *request9, ndmp2_connect_open_request *request2) { CNVT_FROM_9 (request2, request9, protocol_version); return 0; } /* * ndmp_connect_client_auth * just error reply */ int ndmp_2to9_connect_client_auth_request ( ndmp2_connect_client_auth_request *request2, ndmp9_connect_client_auth_request *request9) { int rc; rc = ndmp_2to9_auth_data (&request2->auth_data, &request9->auth_data); return rc; } int ndmp_9to2_connect_client_auth_request ( ndmp9_connect_client_auth_request *request9, ndmp2_connect_client_auth_request *request2) { int rc; rc = ndmp_9to2_auth_data (&request9->auth_data, &request2->auth_data); return rc; } /* * ndmp_connect_close * no arg request, **NO REPLY** */ /* * ndmp_connect_server_auth */ /* TBD */ int ndmp_2to9_connect_server_auth_request ( ndmp2_connect_server_auth_request *request2, ndmp9_connect_server_auth_request *request9) { return -1; } int ndmp_9to2_connect_server_auth_request ( ndmp9_connect_server_auth_request *request9, ndmp2_connect_server_auth_request *request2) { return -1; } /* * CONFIG INTERFACES **************************************************************** */ /* * ndmp_config_get_host_info * no args request */ int ndmp_2to9_config_get_host_info_reply ( ndmp2_config_get_host_info_reply *reply2, ndmp9_config_get_host_info_reply *reply9) { unsigned int i, n_error = 0; CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_STRDUP_TO_9x (reply2, reply9, hostname, config_info.hostname); CNVT_STRDUP_TO_9x (reply2, reply9, os_type, config_info.os_type); CNVT_STRDUP_TO_9x (reply2, reply9, os_vers, config_info.os_vers); CNVT_STRDUP_TO_9x (reply2, reply9, hostid, config_info.hostid); reply9->config_info.authtypes = 0; for (i = 0; i < reply2->auth_type.auth_type_len; i++) { switch (reply2->auth_type.auth_type_val[i]) { case NDMP2_AUTH_NONE: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_NONE; break; case NDMP2_AUTH_TEXT: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_TEXT; break; case NDMP2_AUTH_MD5: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_MD5; break; default: n_error++; /* ignore */ break; } } return n_error; } int ndmp_9to2_config_get_host_info_reply ( ndmp9_config_get_host_info_reply *reply9, ndmp2_config_get_host_info_reply *reply2) { int i = 0; CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_STRDUP_FROM_9x (reply2, reply9, hostname, config_info.hostname); CNVT_STRDUP_FROM_9x (reply2, reply9, os_type, config_info.os_type); CNVT_STRDUP_FROM_9x (reply2, reply9, os_vers, config_info.os_vers); CNVT_STRDUP_FROM_9x (reply2, reply9, hostid, config_info.hostid); reply2->auth_type.auth_type_val = NDMOS_MACRO_NEWN(ndmp2_auth_type, 3); if (!reply2->auth_type.auth_type_val) { return -1; } i = 0; if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_NONE) { reply2->auth_type.auth_type_val[i++] = NDMP2_AUTH_NONE; } if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_TEXT) { reply2->auth_type.auth_type_val[i++] = NDMP2_AUTH_TEXT; } if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_MD5) { reply2->auth_type.auth_type_val[i++] = NDMP2_AUTH_MD5; } reply2->auth_type.auth_type_len = i; return 0; } /* * ndmp_config_get_butype_attr * ndmp2_config_get_butype_attr handled * as version specific dispatch function * in ndma_comm_dispatch.c */ /* * ndmp_config_get_mover_type * no args request */ int ndmp_2to9_config_get_mover_type_reply ( ndmp2_config_get_mover_type_reply *reply2, ndmp9_config_get_connection_type_reply *reply9) { int n_error = 0; unsigned int i; CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); for (i = 0; i < reply2->methods.methods_len; i++) { switch (reply2->methods.methods_val[i]) { case NDMP2_ADDR_LOCAL: reply9->config_info.conntypes |= NDMP9_CONFIG_CONNTYPE_LOCAL; break; case NDMP2_ADDR_TCP: reply9->config_info.conntypes |= NDMP9_CONFIG_CONNTYPE_TCP; break; default: n_error++; /* ignore */ break; } } return n_error; } int ndmp_9to2_config_get_mover_type_reply ( ndmp9_config_get_connection_type_reply *reply9, ndmp2_config_get_mover_type_reply *reply2) { int i = 0; CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); reply2->methods.methods_val = NDMOS_MACRO_NEWN(ndmp2_mover_addr_type, 3); if (!reply2->methods.methods_val) { return -1; /* no mem */ } i = 0; if (reply9->config_info.conntypes & NDMP9_CONFIG_CONNTYPE_LOCAL) { reply2->methods.methods_val[i++] = NDMP2_ADDR_LOCAL; } if (reply9->config_info.conntypes & NDMP9_CONFIG_CONNTYPE_TCP) { reply2->methods.methods_val[i++] = NDMP2_ADDR_TCP; } reply2->methods.methods_len = i; return 0; } /* * ndmp_config_get_auth_attr */ int ndmp_2to9_config_get_auth_attr_request ( struct ndmp2_config_get_auth_attr_request *request2, struct ndmp9_config_get_auth_attr_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request2, request9, auth_type, ndmp_29_auth_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, auth_type); n_error++; } return n_error; } int ndmp_9to2_config_get_auth_attr_request ( struct ndmp9_config_get_auth_attr_request *request9, struct ndmp2_config_get_auth_attr_request *request2) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request2, request9, auth_type, ndmp_29_auth_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, auth_type); n_error++; } return n_error; } int ndmp_2to9_config_get_auth_attr_reply ( struct ndmp2_config_get_auth_attr_reply *reply2, struct ndmp9_config_get_auth_attr_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); n_error += ndmp_2to9_auth_attr (&reply2->server_attr, &reply9->server_attr); return n_error; } int ndmp_9to2_config_get_auth_attr_reply ( struct ndmp9_config_get_auth_attr_reply *reply9, struct ndmp2_config_get_auth_attr_reply *reply2) { int n_error = 0; CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); n_error += ndmp_9to2_auth_attr (&reply9->server_attr, &reply2->server_attr); return n_error; } /* * SCSI INTERFACES **************************************************************** */ /* * ndmp_scsi_open * just error reply */ int ndmp_2to9_scsi_open_request ( ndmp2_scsi_open_request *request2, ndmp9_scsi_open_request *request9) { request9->device = NDMOS_API_STRDUP (request2->device.name); if (!request9->device) { return -1; /* no memory */ } return 0; } int ndmp_9to2_scsi_open_request ( ndmp9_scsi_open_request *request9, ndmp2_scsi_open_request *request2) { request2->device.name = NDMOS_API_STRDUP (request9->device); if (!request2->device.name) { return -1; /* no memory */ } return 0; } /* * ndmp_scsi_close * no args request, just error reply */ /* * ndmp_scsi_get_state * no args request */ int ndmp_2to9_scsi_get_state_reply ( ndmp2_scsi_get_state_reply *reply2, ndmp9_scsi_get_state_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_TO_9 (reply2, reply9, target_controller); CNVT_TO_9 (reply2, reply9, target_id); CNVT_TO_9 (reply2, reply9, target_lun); return 0; } int ndmp_9to2_scsi_get_state_reply ( ndmp9_scsi_get_state_reply *reply9, ndmp2_scsi_get_state_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_FROM_9 (reply2, reply9, target_controller); CNVT_FROM_9 (reply2, reply9, target_id); CNVT_FROM_9 (reply2, reply9, target_lun); return 0; } /* * ndmp_scsi_set_target -- deprecated * just error reply */ int ndmp_2to9_scsi_set_target_request ( ndmp2_scsi_set_target_request *request2, ndmp9_scsi_set_target_request *request9) { request9->device = NDMOS_API_STRDUP (request2->device.name); if (!request9->device) { return -1; /* no memory */ } CNVT_TO_9 (request2, request9, target_controller); CNVT_TO_9 (request2, request9, target_id); CNVT_TO_9 (request2, request9, target_lun); return 0; } int ndmp_9to2_scsi_set_target_request ( ndmp9_scsi_set_target_request *request9, ndmp2_scsi_set_target_request *request2) { request2->device.name = NDMOS_API_STRDUP (request9->device); if (!request2->device.name) { return -1; /* no memory */ } CNVT_FROM_9 (request2, request9, target_controller); CNVT_FROM_9 (request2, request9, target_id); CNVT_FROM_9 (request2, request9, target_lun); return 0; } /* * ndmp_scsi_reset_device * no args request, just error reply */ /* * ndmp_scsi_reset_bus -- deprecated * no args request, just error reply */ /* * ndmp_tape_execute_cdb * ndmp_scsi_execute_cdb */ int ndmp_2to9_execute_cdb_request ( ndmp2_execute_cdb_request *request2, ndmp9_execute_cdb_request *request9) { int n_error = 0; uint32_t len; char * p; switch (request2->flags) { case 0: request9->data_dir = NDMP9_SCSI_DATA_DIR_NONE; break; case NDMP2_SCSI_DATA_IN: request9->data_dir = NDMP9_SCSI_DATA_DIR_IN; break; case NDMP2_SCSI_DATA_OUT: request9->data_dir = NDMP9_SCSI_DATA_DIR_IN; break; default: /* deemed insolvable */ n_error++; return -1; } CNVT_TO_9 (request2, request9, timeout); CNVT_TO_9 (request2, request9, datain_len); len = request2->dataout.dataout_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request2->dataout.dataout_val, p, len); } else { len = 0; p = 0; } request9->dataout.dataout_len = len; request9->dataout.dataout_val = p; len = request2->cdb.cdb_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (request9->dataout.dataout_val) { NDMOS_API_FREE (request9->dataout.dataout_val); request9->dataout.dataout_len = 0; request9->dataout.dataout_val = 0; } return -1; } NDMOS_API_BCOPY (request2->cdb.cdb_val, p, len); } else { len = 0; p = 0; } request9->cdb.cdb_len = len; request9->cdb.cdb_val = p; return 0; } int ndmp_9to2_execute_cdb_request ( ndmp9_execute_cdb_request *request9, ndmp2_execute_cdb_request *request2) { int n_error = 0; uint32_t len; char * p; switch (request9->data_dir) { case NDMP9_SCSI_DATA_DIR_NONE: request2->flags = 0; break; case NDMP9_SCSI_DATA_DIR_IN: request2->flags = NDMP2_SCSI_DATA_IN; break; case NDMP9_SCSI_DATA_DIR_OUT: request2->flags = NDMP2_SCSI_DATA_OUT; break; default: /* deemed insolvable */ n_error++; return -1; } CNVT_FROM_9 (request2, request9, timeout); CNVT_FROM_9 (request2, request9, datain_len); len = request9->dataout.dataout_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request9->dataout.dataout_val, p, len); } else { len = 0; p = 0; } request2->dataout.dataout_len = len; request2->dataout.dataout_val = p; len = request9->cdb.cdb_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (request2->dataout.dataout_val) { NDMOS_API_FREE (request2->dataout.dataout_val); request2->dataout.dataout_len = 0; request2->dataout.dataout_val = 0; } return -1; } NDMOS_API_BCOPY (request9->cdb.cdb_val, p, len); } else { len = 0; p = 0; } request2->cdb.cdb_len = len; request2->cdb.cdb_val = p; return 0; } int ndmp_2to9_execute_cdb_reply ( ndmp2_execute_cdb_reply *reply2, ndmp9_execute_cdb_reply *reply9) { uint32_t len; char * p; CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_TO_9 (reply2, reply9, status); CNVT_TO_9 (reply2, reply9, dataout_len); len = reply2->datain.datain_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply2->datain.datain_val, p, len); } else { len = 0; p = 0; } reply9->datain.datain_len = len; reply9->datain.datain_val = p; len = reply2->ext_sense.ext_sense_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (reply9->datain.datain_val) { NDMOS_API_FREE (reply9->datain.datain_val); reply9->datain.datain_len = 0; reply9->datain.datain_val = 0; } return -1; } NDMOS_API_BCOPY (reply2->ext_sense.ext_sense_val, p, len); } else { len = 0; p = 0; } reply9->ext_sense.ext_sense_len = len; reply9->ext_sense.ext_sense_val = p; return 0; } int ndmp_9to2_execute_cdb_reply ( ndmp9_execute_cdb_reply *reply9, ndmp2_execute_cdb_reply *reply2) { uint32_t len; char * p; CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_FROM_9 (reply2, reply9, status); CNVT_FROM_9 (reply2, reply9, dataout_len); len = reply9->datain.datain_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply9->datain.datain_val, p, len); } else { len = 0; p = 0; } reply2->datain.datain_len = len; reply2->datain.datain_val = p; len = reply9->ext_sense.ext_sense_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (reply2->datain.datain_val) { NDMOS_API_FREE (reply9->datain.datain_val); reply2->datain.datain_len = 0; reply2->datain.datain_val = 0; } return -1; } NDMOS_API_BCOPY (reply9->ext_sense.ext_sense_val, p, len); } else { len = 0; p = 0; } reply2->ext_sense.ext_sense_len = len; reply2->ext_sense.ext_sense_val = p; return 0; } /* * TAPE INTERFACES **************************************************************** */ /* * ndmp_tape_open_request * just error reply */ struct enum_conversion ndmp_29_tape_open_mode[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_TAPE_READ_MODE, NDMP9_TAPE_READ_MODE }, { NDMP2_TAPE_WRITE_MODE, NDMP9_TAPE_RDWR_MODE }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_tape_open_request ( ndmp2_tape_open_request *request2, ndmp9_tape_open_request *request9) { int n_error = 0; int rc; /* * Mode codes are compatible between versions. * We let untranslated values through to * facilitate testing illegal values. */ rc = convert_enum_to_9 (ndmp_29_tape_open_mode, request2->mode); if (rc == NDMP_INVALID_GENERAL) { n_error++; request9->mode = request2->mode; } else { request9->mode = rc; } request9->device = NDMOS_API_STRDUP (request2->device.name); if (!request9->device) { return -1; /* no memory */ } return n_error; } int ndmp_9to2_tape_open_request ( ndmp9_tape_open_request *request9, ndmp2_tape_open_request *request2) { int n_error = 0; int rc; rc = convert_enum_from_9 (ndmp_29_tape_open_mode, request9->mode); if (rc == NDMP_INVALID_GENERAL) { n_error++; request2->mode = request9->mode; } else { request2->mode = rc; } request2->device.name = NDMOS_API_STRDUP (request9->device); if (!request2->device.name) { return -1; /* no memory */ } return n_error; } /* * ndmp_tape_close * no arg request, just error reply */ /* * ndmp_tape_get_state_reply * no arg request */ int ndmp_2to9_tape_get_state_reply ( ndmp2_tape_get_state_reply *reply2, ndmp9_tape_get_state_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_TO_9 (reply2, reply9, flags); CNVT_VUL_TO_9 (reply2, reply9, file_num); CNVT_VUL_TO_9 (reply2, reply9, soft_errors); CNVT_VUL_TO_9 (reply2, reply9, block_size); CNVT_VUL_TO_9 (reply2, reply9, blockno); CNVT_VUQ_TO_9 (reply2, reply9, total_space); CNVT_VUQ_TO_9 (reply2, reply9, space_remain); return 0; } int ndmp_9to2_tape_get_state_reply ( ndmp9_tape_get_state_reply *reply9, ndmp2_tape_get_state_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_FROM_9 (reply2, reply9, flags); CNVT_VUL_FROM_9 (reply2, reply9, file_num); CNVT_VUL_FROM_9 (reply2, reply9, soft_errors); CNVT_VUL_FROM_9 (reply2, reply9, block_size); CNVT_VUL_FROM_9 (reply2, reply9, blockno); CNVT_VUQ_FROM_9 (reply2, reply9, total_space); CNVT_VUQ_FROM_9 (reply2, reply9, space_remain); return 0; } /* * ndmp_tape_mtio_request */ struct enum_conversion ndmp_29_tape_mtio_op[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_MTIO_FSF, NDMP9_MTIO_FSF }, { NDMP2_MTIO_BSF, NDMP9_MTIO_BSF }, { NDMP2_MTIO_FSR, NDMP9_MTIO_FSR }, { NDMP2_MTIO_BSR, NDMP9_MTIO_BSR }, { NDMP2_MTIO_REW, NDMP9_MTIO_REW }, { NDMP2_MTIO_EOF, NDMP9_MTIO_EOF }, { NDMP2_MTIO_OFF, NDMP9_MTIO_OFF }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_tape_mtio_request ( ndmp2_tape_mtio_request *request2, ndmp9_tape_mtio_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request2, request9, tape_op, ndmp_29_tape_mtio_op); if (rc == NDMP_INVALID_GENERAL) { n_error++; CNVT_TO_9(request2, request9, tape_op); } CNVT_TO_9(request2, request9, count); return n_error; } int ndmp_9to2_tape_mtio_request ( ndmp9_tape_mtio_request *request9, ndmp2_tape_mtio_request *request2) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request2, request9, tape_op, ndmp_29_tape_mtio_op); if (rc == NDMP_INVALID_GENERAL) { n_error++; CNVT_FROM_9(request2, request9, tape_op); } CNVT_FROM_9(request2, request9, count); return n_error; } int ndmp_2to9_tape_mtio_reply ( ndmp2_tape_mtio_reply *reply2, ndmp9_tape_mtio_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_TO_9 (reply2, reply9, resid_count); return 0; } int ndmp_9to2_tape_mtio_reply ( ndmp9_tape_mtio_reply *reply9, ndmp2_tape_mtio_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_FROM_9 (reply2, reply9, resid_count); return 0; } /* * ndmp_tape_write */ int ndmp_2to9_tape_write_request ( ndmp2_tape_write_request *request2, ndmp9_tape_write_request *request9) { uint32_t len; char * p; len = request2->data_out.data_out_len; p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request2->data_out.data_out_val, p, len); request9->data_out.data_out_val = p; request9->data_out.data_out_len = len; return 0; } int ndmp_9to2_tape_write_request ( ndmp9_tape_write_request *request9, ndmp2_tape_write_request *request2) { uint32_t len; char * p; len = request9->data_out.data_out_len; p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request9->data_out.data_out_val, p, len); request2->data_out.data_out_val = p; request2->data_out.data_out_len = len; return 0; } int ndmp_2to9_tape_write_reply ( ndmp2_tape_write_reply *reply2, ndmp9_tape_write_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_TO_9 (reply2, reply9, count); return 0; } int ndmp_9to2_tape_write_reply ( ndmp9_tape_write_reply *reply9, ndmp2_tape_write_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_FROM_9 (reply2, reply9, count); return 0; } /* * ndmp_tape_read */ int ndmp_2to9_tape_read_request ( ndmp2_tape_read_request *request2, ndmp9_tape_read_request *request9) { CNVT_TO_9 (request2, request9, count); return 0; } int ndmp_9to2_tape_read_request ( ndmp9_tape_read_request *request9, ndmp2_tape_read_request *request2) { CNVT_FROM_9 (request2, request9, count); return 0; } int ndmp_2to9_tape_read_reply ( ndmp2_tape_read_reply *reply2, ndmp9_tape_read_reply *reply9) { uint32_t len; char * p; CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); len = reply2->data_in.data_in_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply2->data_in.data_in_val, p, len); } else { p = 0; len = 0; } reply9->data_in.data_in_len = len; reply9->data_in.data_in_val = p; return 0; } int ndmp_9to2_tape_read_reply ( ndmp9_tape_read_reply *reply9, ndmp2_tape_read_reply *reply2) { uint32_t len; char * p; CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); len = reply9->data_in.data_in_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply9->data_in.data_in_val, p, len); } else { p = 0; len = 0; } reply2->data_in.data_in_len = len; reply2->data_in.data_in_val = p; return 0; } /* * ndmp_tape_execute_cdb * see SCSI INTERFACES above */ /* * MOVER INTERFACES **************************************************************** */ /* * ndmp_mover_get_state * no args request */ struct enum_conversion ndmp_29_mover_mode[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_MOVER_MODE_READ, NDMP9_MOVER_MODE_READ }, { NDMP2_MOVER_MODE_WRITE, NDMP9_MOVER_MODE_WRITE }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_29_mover_state[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_MOVER_STATE_IDLE, NDMP9_MOVER_STATE_IDLE }, { NDMP2_MOVER_STATE_LISTEN, NDMP9_MOVER_STATE_LISTEN }, { NDMP2_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_ACTIVE }, { NDMP2_MOVER_STATE_PAUSED, NDMP9_MOVER_STATE_PAUSED }, { NDMP2_MOVER_STATE_HALTED, NDMP9_MOVER_STATE_HALTED }, /* alias */ { NDMP2_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_STANDBY }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_29_mover_pause_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_MOVER_PAUSE_NA, NDMP9_MOVER_PAUSE_NA }, { NDMP2_MOVER_PAUSE_EOM, NDMP9_MOVER_PAUSE_EOM }, { NDMP2_MOVER_PAUSE_EOF, NDMP9_MOVER_PAUSE_EOF }, { NDMP2_MOVER_PAUSE_SEEK, NDMP9_MOVER_PAUSE_SEEK }, { NDMP2_MOVER_PAUSE_MEDIA_ERROR, NDMP9_MOVER_PAUSE_MEDIA_ERROR }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_29_mover_halt_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_MOVER_HALT_NA, NDMP9_MOVER_HALT_NA }, { NDMP2_MOVER_HALT_CONNECT_CLOSED, NDMP9_MOVER_HALT_CONNECT_CLOSED }, { NDMP2_MOVER_HALT_ABORTED, NDMP9_MOVER_HALT_ABORTED }, { NDMP2_MOVER_HALT_INTERNAL_ERROR, NDMP9_MOVER_HALT_INTERNAL_ERROR }, { NDMP2_MOVER_HALT_CONNECT_ERROR, NDMP9_MOVER_HALT_CONNECT_ERROR }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_mover_get_state_reply ( ndmp2_mover_get_state_reply *reply2, ndmp9_mover_get_state_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_E_TO_9 (reply2, reply9, state, ndmp_29_mover_state); CNVT_E_TO_9 (reply2, reply9, pause_reason, ndmp_29_mover_pause_reason); CNVT_E_TO_9 (reply2, reply9, halt_reason, ndmp_29_mover_halt_reason); CNVT_TO_9 (reply2, reply9, record_size); CNVT_TO_9 (reply2, reply9, record_num); CNVT_TO_9x (reply2, reply9, data_written, bytes_moved); CNVT_TO_9 (reply2, reply9, seek_position); CNVT_TO_9 (reply2, reply9, bytes_left_to_read); CNVT_TO_9 (reply2, reply9, window_offset); CNVT_TO_9 (reply2, reply9, window_length); return 0; } int ndmp_9to2_mover_get_state_reply ( ndmp9_mover_get_state_reply *reply9, ndmp2_mover_get_state_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_E_FROM_9 (reply2, reply9, state, ndmp_29_mover_state); CNVT_E_FROM_9 (reply2, reply9, pause_reason, ndmp_29_mover_pause_reason); CNVT_E_FROM_9 (reply2, reply9, halt_reason, ndmp_29_mover_halt_reason); CNVT_FROM_9 (reply2, reply9, record_size); CNVT_FROM_9 (reply2, reply9, record_num); CNVT_FROM_9x (reply2, reply9, data_written, bytes_moved); CNVT_FROM_9 (reply2, reply9, seek_position); CNVT_FROM_9 (reply2, reply9, bytes_left_to_read); CNVT_FROM_9 (reply2, reply9, window_offset); CNVT_FROM_9 (reply2, reply9, window_length); return 0; } /* * ndmp_mover_listen */ int ndmp_2to9_mover_listen_request ( ndmp2_mover_listen_request *request2, ndmp9_mover_listen_request *request9) { int rc; rc = CNVT_E_TO_9 (request2, request9, mode, ndmp_29_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, mode); } rc = CNVT_E_TO_9 (request2, request9, addr_type, ndmp_29_mover_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, addr_type); } return 0; } int ndmp_9to2_mover_listen_request ( ndmp9_mover_listen_request *request9, ndmp2_mover_listen_request *request2) { int rc; rc = CNVT_E_FROM_9 (request2, request9, mode, ndmp_29_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, mode); } rc = CNVT_E_FROM_9 (request2, request9, addr_type, ndmp_29_mover_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, addr_type); } return 0; } int ndmp_2to9_mover_listen_reply ( ndmp2_mover_listen_reply *reply2, ndmp9_mover_listen_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); n_error += ndmp_2to9_mover_addr (&reply2->mover, &reply9->data_connection_addr); return n_error; } int ndmp_9to2_mover_listen_reply ( ndmp9_mover_listen_reply *reply9, ndmp2_mover_listen_reply *reply2) { int n_error = 0; CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); n_error += ndmp_9to2_mover_addr (&reply9->data_connection_addr, &reply2->mover); return n_error; } /* * ndmp_mover_continue * no args request, just error reply */ /* * ndmp_mover_abort * no args request, just error reply */ /* * ndmp_mover_stop * no args request, just error reply */ /* * ndmp_mover_set_window * just error reply */ int ndmp_2to9_mover_set_window_request ( ndmp2_mover_set_window_request *request2, ndmp9_mover_set_window_request *request9) { CNVT_TO_9 (request2, request9, offset); CNVT_TO_9 (request2, request9, length); return 0; } int ndmp_9to2_mover_set_window_request ( ndmp9_mover_set_window_request *request9, ndmp2_mover_set_window_request *request2) { CNVT_FROM_9 (request2, request9, offset); CNVT_FROM_9 (request2, request9, length); return 0; } /* * ndmp_mover_read * just error reply */ int ndmp_2to9_mover_read_request ( ndmp2_mover_read_request *request2, ndmp9_mover_read_request *request9) { CNVT_TO_9 (request2, request9, offset); CNVT_TO_9 (request2, request9, length); return 0; } int ndmp_9to2_mover_read_request ( ndmp9_mover_read_request *request9, ndmp2_mover_read_request *request2) { CNVT_FROM_9 (request2, request9, offset); CNVT_FROM_9 (request2, request9, length); return 0; } /* * ndmp_mover_close * no args request, just error reply */ /* * ndmp_mover_set_record_size * just error reply */ int ndmp_2to9_mover_set_record_size_request ( ndmp2_mover_set_record_size_request *request2, ndmp9_mover_set_record_size_request *request9) { CNVT_TO_9x (request2, request9, len, record_size); return 0; } int ndmp_9to2_mover_set_record_size_request ( ndmp9_mover_set_record_size_request *request9, ndmp2_mover_set_record_size_request *request2) { CNVT_FROM_9x (request2, request9, len, record_size); return 0; } /* * DATA INTERFACES **************************************************************** */ /* * ndmp_name **************************************************************** */ int ndmp_2to9_name ( ndmp2_name *name2, ndmp9_name *name9) { name9->original_path = NDMOS_API_STRDUP(name2->name); name9->destination_path = NDMOS_API_STRDUP(name2->dest); if (name2->fh_info != NDMP_INVALID_U_QUAD) { name9->fh_info.valid = NDMP9_VALIDITY_VALID; name9->fh_info.value = name2->fh_info; } else { name9->fh_info.valid = NDMP9_VALIDITY_INVALID; name9->fh_info.value = NDMP_INVALID_U_QUAD; } return 0; } int ndmp_9to2_name ( ndmp9_name *name9, ndmp2_name *name2) { name2->name = NDMOS_API_STRDUP(name9->original_path); name2->dest = NDMOS_API_STRDUP(name9->destination_path); if (name9->fh_info.valid == NDMP9_VALIDITY_VALID) { name2->fh_info = name9->fh_info.value; } else { name2->fh_info = NDMP_INVALID_U_QUAD; } name2->ssid = 0; return 0; } int ndmp_2to9_name_vec ( ndmp2_name *name2, ndmp9_name *name9, unsigned n_name) { unsigned int i; for (i = 0; i < n_name; i++) ndmp_2to9_name (&name2[i], &name9[i]); return 0; } int ndmp_9to2_name_vec ( ndmp9_name *name9, ndmp2_name *name2, unsigned n_name) { unsigned int i; for (i = 0; i < n_name; i++) ndmp_9to2_name (&name9[i], &name2[i]); return 0; } int ndmp_2to9_name_vec_dup ( ndmp2_name *name2, ndmp9_name **name9_p, unsigned n_name) { *name9_p = NDMOS_MACRO_NEWN (ndmp9_name, n_name); if (!*name9_p) return -1; return ndmp_2to9_name_vec (name2, *name9_p, n_name); } int ndmp_9to2_name_vec_dup ( ndmp9_name *name9, ndmp2_name **name2_p, unsigned n_name) { *name2_p = NDMOS_MACRO_NEWN (ndmp2_name, n_name); if (!*name2_p) return -1; return ndmp_9to2_name_vec (name9, *name2_p, n_name); } /* * ndmp_data_get_state * no args request */ struct enum_conversion ndmp_29_data_operation[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_DATA_OP_NOACTION, NDMP9_DATA_OP_NOACTION }, { NDMP2_DATA_OP_BACKUP, NDMP9_DATA_OP_BACKUP }, { NDMP2_DATA_OP_RESTORE, NDMP9_DATA_OP_RECOVER }, { NDMP2_DATA_OP_RESTORE_FILEHIST, NDMP9_DATA_OP_RECOVER_FILEHIST }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_29_data_state[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_DATA_STATE_IDLE, NDMP9_DATA_STATE_IDLE }, { NDMP2_DATA_STATE_ACTIVE, NDMP9_DATA_STATE_ACTIVE }, { NDMP2_DATA_STATE_HALTED, NDMP9_DATA_STATE_HALTED }, /* aliases */ { NDMP2_DATA_STATE_ACTIVE, NDMP9_DATA_STATE_CONNECTED }, { NDMP2_DATA_STATE_ACTIVE, NDMP9_DATA_STATE_LISTEN }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_29_data_halt_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_DATA_HALT_NA, NDMP9_DATA_HALT_NA }, { NDMP2_DATA_HALT_SUCCESSFUL, NDMP9_DATA_HALT_SUCCESSFUL }, { NDMP2_DATA_HALT_ABORTED, NDMP9_DATA_HALT_ABORTED }, { NDMP2_DATA_HALT_INTERNAL_ERROR, NDMP9_DATA_HALT_INTERNAL_ERROR }, { NDMP2_DATA_HALT_CONNECT_ERROR, NDMP9_DATA_HALT_CONNECT_ERROR }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_data_get_state_reply ( ndmp2_data_get_state_reply *reply2, ndmp9_data_get_state_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); CNVT_E_TO_9 (reply2, reply9, operation, ndmp_29_data_operation); CNVT_E_TO_9 (reply2, reply9, state, ndmp_29_data_state); CNVT_E_TO_9 (reply2, reply9, halt_reason, ndmp_29_data_halt_reason); CNVT_TO_9 (reply2, reply9, bytes_processed); CNVT_VUQ_TO_9 (reply2, reply9, est_bytes_remain); CNVT_VUL_TO_9 (reply2, reply9, est_time_remain); ndmp_2to9_mover_addr (&reply2->mover, &reply9->data_connection_addr); CNVT_TO_9 (reply2, reply9, read_offset); CNVT_TO_9 (reply2, reply9, read_length); return 0; } int ndmp_9to2_data_get_state_reply ( ndmp9_data_get_state_reply *reply9, ndmp2_data_get_state_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); CNVT_E_FROM_9 (reply2, reply9, operation, ndmp_29_data_operation); CNVT_E_FROM_9 (reply2, reply9, state, ndmp_29_data_state); CNVT_E_FROM_9 (reply2, reply9, halt_reason, ndmp_29_data_halt_reason); CNVT_FROM_9 (reply2, reply9, bytes_processed); CNVT_VUQ_FROM_9 (reply2, reply9, est_bytes_remain); CNVT_VUL_FROM_9 (reply2, reply9, est_time_remain); ndmp_9to2_mover_addr (&reply9->data_connection_addr, &reply2->mover); CNVT_FROM_9 (reply2, reply9, read_offset); CNVT_FROM_9 (reply2, reply9, read_length); return 0; } /* * ndmp_data_start_backup * just error reply */ int ndmp_2to9_data_start_backup_request ( ndmp2_data_start_backup_request *request2, ndmp9_data_start_backup_request *request9) { int n_error = 0; CNVT_STRDUP_TO_9 (request2, request9, bu_type); ndmp_2to9_pval_vec_dup (request2->env.env_val, &request9->env.env_val, request2->env.env_len); request9->env.env_len = request2->env.env_len; n_error += ndmp_2to9_mover_addr (&request2->mover, &request9->addr); return n_error; } int ndmp_9to2_data_start_backup_request ( ndmp9_data_start_backup_request *request9, ndmp2_data_start_backup_request *request2) { int n_error = 0; CNVT_STRDUP_FROM_9 (request2, request9, bu_type); ndmp_9to2_pval_vec_dup (request9->env.env_val, &request2->env.env_val, request9->env.env_len); request2->env.env_len = request9->env.env_len; n_error += ndmp_9to2_mover_addr (&request9->addr, &request2->mover); return n_error; } /* * ndmp_data_start_recover * ndmp_data_start_recover_filehist * just error reply */ int ndmp_2to9_data_start_recover_request ( ndmp2_data_start_recover_request *request2, ndmp9_data_start_recover_request *request9) { int n_error = 0; CNVT_STRDUP_TO_9 (request2, request9, bu_type); ndmp_2to9_pval_vec_dup (request2->env.env_val, &request9->env.env_val, request2->env.env_len); request9->env.env_len = request2->env.env_len; ndmp_2to9_name_vec_dup (request2->nlist.nlist_val, &request9->nlist.nlist_val, request2->nlist.nlist_len); request9->nlist.nlist_len = request2->nlist.nlist_len; n_error += ndmp_2to9_mover_addr (&request2->mover, &request9->addr); return n_error; } int ndmp_9to2_data_start_recover_request ( ndmp9_data_start_recover_request *request9, ndmp2_data_start_recover_request *request2) { int n_error = 0; CNVT_STRDUP_FROM_9 (request2, request9, bu_type); ndmp_9to2_pval_vec_dup (request9->env.env_val, &request2->env.env_val, request9->env.env_len); request2->env.env_len = request9->env.env_len; ndmp_9to2_name_vec_dup (request9->nlist.nlist_val, &request2->nlist.nlist_val, request9->nlist.nlist_len); request2->nlist.nlist_len = request9->nlist.nlist_len; n_error += ndmp_9to2_mover_addr (&request9->addr, &request2->mover); return n_error; } /* * ndmp_data_abort * no args request, just error reply */ /* * ndmp_data_get_env * no args request */ int ndmp_2to9_data_get_env_reply ( ndmp2_data_get_env_reply *reply2, ndmp9_data_get_env_reply *reply9) { CNVT_E_TO_9 (reply2, reply9, error, ndmp_29_error); ndmp_2to9_pval_vec_dup (reply2->env.env_val, &reply9->env.env_val, reply2->env.env_len); reply9->env.env_len = reply2->env.env_len; return 0; } int ndmp_9to2_data_get_env_reply ( ndmp9_data_get_env_reply *reply9, ndmp2_data_get_env_reply *reply2) { CNVT_E_FROM_9 (reply2, reply9, error, ndmp_29_error); ndmp_9to2_pval_vec_dup (reply9->env.env_val, &reply2->env.env_val, reply9->env.env_len); reply2->env.env_len = reply9->env.env_len; return 0; } /* * ndmp_data_stop * no args request, just error reply */ /* * NOTIFY INTERFACES **************************************************************** */ /* * ndmp_notify_data_halted * just error reply */ int ndmp_2to9_notify_data_halted_request ( ndmp2_notify_data_halted_request *request2, ndmp9_notify_data_halted_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request2, request9, reason, ndmp_29_data_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, reason); n_error++; } return n_error; } int ndmp_9to2_notify_data_halted_request ( ndmp9_notify_data_halted_request *request9, ndmp2_notify_data_halted_request *request2) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request2, request9, reason, ndmp_29_data_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, reason); n_error++; } request2->text_reason = NDMOS_API_STRDUP("whatever"); return n_error; } /* * ndmp_notify_connected * just error reply */ /* NDMP2_NOTIFY_CONNECTED */ struct enum_conversion ndmp_29_connect_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_CONNECTED, NDMP9_CONNECTED }, { NDMP2_SHUTDOWN, NDMP9_SHUTDOWN }, { NDMP2_REFUSED, NDMP9_REFUSED }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_notify_connected_request ( ndmp2_notify_connected_request *request2, ndmp9_notify_connected_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request2, request9, reason, ndmp_29_connect_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, reason); n_error++; } CNVT_TO_9 (request2, request9, protocol_version); CNVT_STRDUP_TO_9 (request2, request9, text_reason); return n_error; } int ndmp_9to2_notify_connected_request ( ndmp9_notify_connected_request *request9, ndmp2_notify_connected_request *request2) { int n_error = 0; int rc; rc = CNVT_E_FROM_9(request2, request9, reason, ndmp_29_connect_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, reason); n_error++; } CNVT_FROM_9 (request2, request9, protocol_version); CNVT_STRDUP_FROM_9 (request2, request9, text_reason); return n_error; } /* * ndmp_notify_mover_halted * just error reply */ int ndmp_2to9_notify_mover_halted_request ( ndmp2_notify_mover_halted_request *request2, ndmp9_notify_mover_halted_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request2, request9, reason, ndmp_29_mover_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, reason); n_error++; } return n_error; } int ndmp_9to2_notify_mover_halted_request ( ndmp9_notify_mover_halted_request *request9, ndmp2_notify_mover_halted_request *request2) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request2, request9, reason, ndmp_29_mover_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, reason); n_error++; } request2->text_reason = NDMOS_API_STRDUP ("Whatever"); return n_error; } /* * ndmp_notify_mover_paused * just error reply */ int ndmp_2to9_notify_mover_paused_request ( ndmp2_notify_mover_paused_request *request2, ndmp9_notify_mover_paused_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request2, request9, reason, ndmp_29_mover_pause_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request2, request9, reason); n_error++; } CNVT_TO_9 (request2, request9, seek_position); return n_error; } int ndmp_9to2_notify_mover_paused_request ( ndmp9_notify_mover_paused_request *request9, ndmp2_notify_mover_paused_request *request2) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request2, request9, reason, ndmp_29_mover_pause_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request2, request9, reason); n_error++; } CNVT_FROM_9 (request2, request9, seek_position); return n_error; } /* * ndmp_notify_data_read * just error reply */ int ndmp_2to9_notify_data_read_request ( ndmp2_notify_data_read_request *request2, ndmp9_notify_data_read_request *request9) { CNVT_TO_9 (request2, request9, offset); CNVT_TO_9 (request2, request9, length); return 0; } int ndmp_9to2_notify_data_read_request ( ndmp9_notify_data_read_request *request9, ndmp2_notify_data_read_request *request2) { CNVT_FROM_9 (request2, request9, offset); CNVT_FROM_9 (request2, request9, length); return 0; } /* * LOG INTERFACES **************************************************************** */ /* * ndmp2_log_log and ndmp2_log_debug are not handled * by the ndmp9 translater. Like ndmp2_config_get_butype_attr, * these NDMP2 log interfaces do not pair well with the * ndmp[349] interfaces. So they are handled directly * rather than by translation. */ struct enum_conversion ndmp_29_recovery_status[] = { { NDMP2_UNDEFINED_ERR, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR }, /* default */ { NDMP2_NO_ERR, NDMP9_RECOVERY_SUCCESSFUL }, { NDMP2_PERMISSION_ERR, NDMP9_RECOVERY_FAILED_PERMISSION }, { NDMP2_FILE_NOT_FOUND_ERR, NDMP9_RECOVERY_FAILED_NOT_FOUND }, { NDMP2_BAD_FILE_ERR, NDMP9_RECOVERY_FAILED_NO_DIRECTORY }, { NDMP2_NO_MEM_ERR, NDMP9_RECOVERY_FAILED_OUT_OF_MEMORY }, { NDMP2_IO_ERR, NDMP9_RECOVERY_FAILED_IO_ERROR }, { NDMP2_UNDEFINED_ERR, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_log_file_request ( ndmp2_log_file_request *request2, ndmp9_log_file_request *request9) { request9->recovery_status = convert_enum_to_9 (ndmp_29_recovery_status, request2->error); CNVT_STRDUP_TO_9 (request2, request9, name); return 0; } int ndmp_9to2_log_file_request ( ndmp9_log_file_request *request9, ndmp2_log_file_request *request2) { request2->error = convert_enum_from_9 (ndmp_29_recovery_status, request9->recovery_status); CNVT_STRDUP_FROM_9 (request2, request9, name); return 0; } /* * FILE HISTORY INTERFACES **************************************************************** */ /* * ndmp[_unix]_file_stat */ struct enum_conversion ndmp_29_file_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP2_FILE_DIR, NDMP9_FILE_DIR }, { NDMP2_FILE_FIFO, NDMP9_FILE_FIFO }, { NDMP2_FILE_CSPEC, NDMP9_FILE_CSPEC }, { NDMP2_FILE_BSPEC, NDMP9_FILE_BSPEC }, { NDMP2_FILE_REG, NDMP9_FILE_REG }, { NDMP2_FILE_SLINK, NDMP9_FILE_SLINK }, { NDMP2_FILE_SOCK, NDMP9_FILE_SOCK }, END_ENUM_CONVERSION_TABLE }; int ndmp_2to9_unix_file_stat ( ndmp2_unix_file_stat *fstat2, ndmp9_file_stat *fstat9) { CNVT_E_TO_9 (fstat2, fstat9, ftype, ndmp_29_file_type); CNVT_VUL_TO_9 (fstat2, fstat9, mtime); CNVT_VUL_TO_9 (fstat2, fstat9, atime); CNVT_VUL_TO_9 (fstat2, fstat9, ctime); CNVT_VUL_TO_9 (fstat2, fstat9, uid); CNVT_VUL_TO_9 (fstat2, fstat9, gid); CNVT_VUL_TO_9 (fstat2, fstat9, mode); CNVT_VUQ_TO_9 (fstat2, fstat9, size); CNVT_VUQ_TO_9 (fstat2, fstat9, fh_info); return 0; } int ndmp_9to2_unix_file_stat ( ndmp9_file_stat *fstat9, ndmp2_unix_file_stat *fstat2) { CNVT_E_FROM_9 (fstat2, fstat9, ftype, ndmp_29_file_type); CNVT_VUL_FROM_9 (fstat2, fstat9, mtime); CNVT_VUL_FROM_9 (fstat2, fstat9, atime); CNVT_VUL_FROM_9 (fstat2, fstat9, ctime); CNVT_VUL_FROM_9 (fstat2, fstat9, uid); CNVT_VUL_FROM_9 (fstat2, fstat9, gid); CNVT_VUL_FROM_9 (fstat2, fstat9, mode); CNVT_VUQ_FROM_9 (fstat2, fstat9, size); CNVT_VUQ_FROM_9 (fstat2, fstat9, fh_info); /* node ignored */ return 0; } /* * ndmp_fh_add_unix_path_request */ int ndmp_2to9_fh_add_unix_path_request ( ndmp2_fh_add_unix_path_request *request2, ndmp9_fh_add_file_request *request9) { int n_ent = request2->paths.paths_len; int i; ndmp9_file * table; table = NDMOS_MACRO_NEWN(ndmp9_file, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp2_fh_unix_path * ent2 = &request2->paths.paths_val[i]; ndmp9_file * ent9 = &table[i]; CNVT_STRDUP_TO_9x (ent2, ent9, name, unix_path); ndmp_2to9_unix_file_stat (&ent2->fstat, &ent9->fstat); } request9->files.files_len = n_ent; request9->files.files_val = table; return 0; } int ndmp_9to2_fh_add_unix_path_request ( ndmp9_fh_add_file_request *request9, ndmp2_fh_add_unix_path_request *request2) { int n_ent = request9->files.files_len; int i; ndmp2_fh_unix_path * table; table = NDMOS_MACRO_NEWN(ndmp2_fh_unix_path, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp2_fh_unix_path * ent2 = &table[i]; ndmp9_file * ent9 = &request9->files.files_val[i]; CNVT_STRDUP_FROM_9x (ent2, ent9, name, unix_path); ndmp_9to2_unix_file_stat (&ent9->fstat, &ent2->fstat); } request2->paths.paths_len = n_ent; request2->paths.paths_val = table; return 0; } /* * ndmp_fh_add_unix_dir */ int ndmp_2to9_fh_add_unix_dir_request ( ndmp2_fh_add_unix_dir_request *request2, ndmp9_fh_add_dir_request *request9) { int n_ent = request2->dirs.dirs_len; int i; ndmp9_dir * table; table = NDMOS_MACRO_NEWN(ndmp9_dir, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp2_fh_unix_dir * ent2 = &request2->dirs.dirs_val[i]; ndmp9_dir * ent9 = &table[i]; CNVT_STRDUP_TO_9x (ent2, ent9, name, unix_name); CNVT_TO_9 (ent2, ent9, node); CNVT_TO_9 (ent2, ent9, parent); } request9->dirs.dirs_len = n_ent; request9->dirs.dirs_val = table; return 0; } int ndmp_2to9_fh_add_unix_dir_free_request (ndmp9_fh_add_dir_request *request9) { int i; if (request9) { if(request9->dirs.dirs_val) { int n_ent = request9->dirs.dirs_len; for (i = 0; i < n_ent; i++) { ndmp9_dir *ent9 = &request9->dirs.dirs_val[i]; if (ent9->unix_name) NDMOS_API_FREE(ent9->unix_name); ent9->unix_name = 0; } NDMOS_API_FREE(request9->dirs.dirs_val); } request9->dirs.dirs_val = 0; } return 0; } int ndmp_9to2_fh_add_unix_dir_request ( ndmp9_fh_add_dir_request *request9, ndmp2_fh_add_unix_dir_request *request2) { int n_ent = request9->dirs.dirs_len; int i; ndmp2_fh_unix_dir * table; table = NDMOS_MACRO_NEWN(ndmp2_fh_unix_dir, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_dir * ent9 = &request9->dirs.dirs_val[i]; ndmp2_fh_unix_dir * ent2 = &table[i]; CNVT_STRDUP_FROM_9x (ent2, ent9, name, unix_name); CNVT_FROM_9 (ent2, ent9, node); CNVT_FROM_9 (ent2, ent9, parent); } request2->dirs.dirs_len = n_ent; request2->dirs.dirs_val = table; return 0; } int ndmp_9to2_fh_add_unix_dir_free_request (ndmp2_fh_add_unix_dir_request *request2) { int i; if (request2) { if(request2->dirs.dirs_val) { int n_ent = request2->dirs.dirs_len; for (i = 0; i < n_ent; i++) { ndmp2_fh_unix_dir *ent2 = &request2->dirs.dirs_val[i]; if (ent2->name) NDMOS_API_FREE(ent2->name); ent2->name = 0; } NDMOS_API_FREE(request2->dirs.dirs_val); } request2->dirs.dirs_val = 0; } return 0; } /* * ndmp_fh_add_unix_node */ int ndmp_2to9_fh_add_unix_node_request ( ndmp2_fh_add_unix_node_request *request2, ndmp9_fh_add_node_request *request9) { int n_ent = request2->nodes.nodes_len; int i; ndmp9_node * table; table = NDMOS_MACRO_NEWN(ndmp9_node, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp2_fh_unix_node * ent2 = &request2->nodes.nodes_val[i]; ndmp9_node * ent9 = &table[i]; ndmp_2to9_unix_file_stat (&ent2->fstat, &ent9->fstat); ent9->fstat.node.valid = NDMP9_VALIDITY_VALID; ent9->fstat.node.value = ent2->node; } request9->nodes.nodes_len = n_ent; request9->nodes.nodes_val = table; return 0; } int ndmp_2to9_fh_add_unix_node_free_request (ndmp9_fh_add_node_request *request9) { if (request9) { if(request9->nodes.nodes_val) { NDMOS_API_FREE(request9->nodes.nodes_val); } request9->nodes.nodes_val = 0; } return 0; } int ndmp_9to2_fh_add_unix_node_request ( ndmp9_fh_add_node_request *request9, ndmp2_fh_add_unix_node_request *request2) { int n_ent = request9->nodes.nodes_len; int i; ndmp2_fh_unix_node * table; table = NDMOS_MACRO_NEWN(ndmp2_fh_unix_node, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_node * ent9 = &request9->nodes.nodes_val[i]; ndmp2_fh_unix_node * ent2 = &table[i]; ndmp_9to2_unix_file_stat (&ent9->fstat, &ent2->fstat); ent2->node = ent9->fstat.node.value; } request2->nodes.nodes_len = n_ent; request2->nodes.nodes_val = table; return 0; } int ndmp_9to2_fh_add_unix_node_free_request (ndmp2_fh_add_unix_node_request *request2) { if (request2) { if(request2->nodes.nodes_val) { NDMOS_API_FREE(request2->nodes.nodes_val); } request2->nodes.nodes_val = 0; } return 0; } /* * request/reply translation */ #define NO_ARG_REQUEST \ ndmp_xtox_no_arguments, ndmp_xtox_no_arguments #define JUST_ERROR_REPLY \ ndmp_2to9_error, ndmp_9to2_error #define NO_ARG_REQUEST_JUST_ERROR_REPLY \ NO_ARG_REQUEST, JUST_ERROR_REPLY #define NO_MEMUSED_REQUEST \ ndmp_xtox_no_memused, ndmp_xtox_no_memused #define NO_MEMUSED_REPLY \ ndmp_xtox_no_memused, ndmp_xtox_no_memused #define NO_MEMUSED \ ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused struct reqrep_xlate ndmp2_reqrep_xlate_table[] = { { NDMP2_CONNECT_OPEN, NDMP9_CONNECT_OPEN, ndmp_2to9_connect_open_request, ndmp_9to2_connect_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_CONNECT_CLIENT_AUTH, NDMP9_CONNECT_CLIENT_AUTH, ndmp_2to9_connect_client_auth_request, ndmp_9to2_connect_client_auth_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_CONNECT_CLOSE, NDMP9_CONNECT_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, /* actually no reply */ NO_MEMUSED /* no memory free routines written yet */ }, #ifdef notyet { NDMP2_CONNECT_SERVER_AUTH, NDMP9_CONNECT_SERVER_AUTH, ndmp_2to9_connect_server_auth_request, ndmp_9to2_connect_server_auth_request, ndmp_2to9_connect_server_auth_reply, ndmp_9to2_connect_server_auth_reply, NO_MEMUSED /* no memory free routines written yet */ }, #endif /* notyet */ { NDMP2_CONFIG_GET_HOST_INFO, NDMP9_CONFIG_GET_HOST_INFO, NO_ARG_REQUEST, ndmp_2to9_config_get_host_info_reply, ndmp_9to2_config_get_host_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, /* * ndmp2_config_get_butype_attr handled * as version specific dispatch function * in ndma_comm_dispatch.c */ { NDMP2_CONFIG_GET_MOVER_TYPE, NDMP9_CONFIG_GET_CONNECTION_TYPE, NO_ARG_REQUEST, ndmp_2to9_config_get_mover_type_reply, ndmp_9to2_config_get_mover_type_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_CONFIG_GET_AUTH_ATTR, NDMP9_CONFIG_GET_AUTH_ATTR, ndmp_2to9_config_get_auth_attr_request, ndmp_9to2_config_get_auth_attr_request, ndmp_2to9_config_get_auth_attr_reply, ndmp_9to2_config_get_auth_attr_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_OPEN, NDMP9_SCSI_OPEN, ndmp_2to9_scsi_open_request, ndmp_9to2_scsi_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_CLOSE, NDMP9_SCSI_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_GET_STATE, NDMP9_SCSI_GET_STATE, NO_ARG_REQUEST, ndmp_2to9_scsi_get_state_reply, ndmp_9to2_scsi_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_SET_TARGET, NDMP9_SCSI_SET_TARGET, ndmp_2to9_scsi_set_target_request, ndmp_9to2_scsi_set_target_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_RESET_DEVICE, NDMP9_SCSI_RESET_DEVICE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_RESET_BUS, NDMP9_SCSI_RESET_BUS, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_SCSI_EXECUTE_CDB, NDMP9_SCSI_EXECUTE_CDB, ndmp_2to9_execute_cdb_request, ndmp_9to2_execute_cdb_request, ndmp_2to9_execute_cdb_reply, ndmp_9to2_execute_cdb_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_OPEN, NDMP9_TAPE_OPEN, ndmp_2to9_tape_open_request, ndmp_9to2_tape_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_CLOSE, NDMP9_TAPE_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_GET_STATE, NDMP9_TAPE_GET_STATE, NO_ARG_REQUEST, ndmp_2to9_tape_get_state_reply, ndmp_9to2_tape_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_MTIO, NDMP9_TAPE_MTIO, ndmp_2to9_tape_mtio_request, ndmp_9to2_tape_mtio_request, ndmp_2to9_tape_mtio_reply, ndmp_9to2_tape_mtio_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_WRITE, NDMP9_TAPE_WRITE, ndmp_2to9_tape_write_request, ndmp_9to2_tape_write_request, ndmp_2to9_tape_write_reply, ndmp_9to2_tape_write_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_READ, NDMP9_TAPE_READ, ndmp_2to9_tape_read_request, ndmp_9to2_tape_read_request, ndmp_2to9_tape_read_reply, ndmp_9to2_tape_read_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_TAPE_EXECUTE_CDB, NDMP9_TAPE_EXECUTE_CDB, ndmp_2to9_execute_cdb_request, ndmp_9to2_execute_cdb_request, ndmp_2to9_execute_cdb_reply, ndmp_9to2_execute_cdb_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_GET_STATE, NDMP9_DATA_GET_STATE, NO_ARG_REQUEST, ndmp_2to9_data_get_state_reply, ndmp_9to2_data_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_START_BACKUP, NDMP9_DATA_START_BACKUP, ndmp_2to9_data_start_backup_request, ndmp_9to2_data_start_backup_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_START_RECOVER, NDMP9_DATA_START_RECOVER, ndmp_2to9_data_start_recover_request, ndmp_9to2_data_start_recover_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_ABORT, NDMP9_DATA_ABORT, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_GET_ENV, NDMP9_DATA_GET_ENV, NO_ARG_REQUEST, ndmp_2to9_data_get_env_reply, ndmp_9to2_data_get_env_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_STOP, NDMP9_DATA_STOP, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_DATA_START_RECOVER_FILEHIST, NDMP9_DATA_START_RECOVER_FILEHIST, ndmp_2to9_data_start_recover_request, ndmp_9to2_data_start_recover_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_NOTIFY_DATA_HALTED, NDMP9_NOTIFY_DATA_HALTED, ndmp_2to9_notify_data_halted_request, ndmp_9to2_notify_data_halted_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_NOTIFY_CONNECTED, NDMP9_NOTIFY_CONNECTED, ndmp_2to9_notify_connected_request, ndmp_9to2_notify_connected_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_NOTIFY_MOVER_HALTED, NDMP9_NOTIFY_MOVER_HALTED, ndmp_2to9_notify_mover_halted_request, ndmp_9to2_notify_mover_halted_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_NOTIFY_MOVER_PAUSED, NDMP9_NOTIFY_MOVER_PAUSED, ndmp_2to9_notify_mover_paused_request, ndmp_9to2_notify_mover_paused_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_NOTIFY_DATA_READ, NDMP9_NOTIFY_DATA_READ, ndmp_2to9_notify_data_read_request, ndmp_9to2_notify_data_read_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_LOG_FILE, NDMP9_LOG_FILE, ndmp_2to9_log_file_request, ndmp_9to2_log_file_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, #if 0 { NDMP2_LOG_MESSAGE, NDMP9_LOG_MESSAGE, ndmp_2to9_log_message_request, ndmp_9to2_log_message_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, #endif { NDMP2_FH_ADD_UNIX_PATH, NDMP9_FH_ADD_FILE, ndmp_2to9_fh_add_unix_path_request, ndmp_9to2_fh_add_unix_path_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_FH_ADD_UNIX_DIR, NDMP9_FH_ADD_DIR, ndmp_2to9_fh_add_unix_dir_request, ndmp_9to2_fh_add_unix_dir_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_2to9_fh_add_unix_dir_free_request, ndmp_9to2_fh_add_unix_dir_free_request, NO_MEMUSED_REPLY }, { NDMP2_FH_ADD_UNIX_NODE, NDMP9_FH_ADD_NODE, ndmp_2to9_fh_add_unix_node_request, ndmp_9to2_fh_add_unix_node_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_2to9_fh_add_unix_node_free_request, ndmp_9to2_fh_add_unix_node_free_request, NO_MEMUSED_REPLY }, { NDMP2_MOVER_GET_STATE, NDMP9_MOVER_GET_STATE, NO_ARG_REQUEST, ndmp_2to9_mover_get_state_reply, ndmp_9to2_mover_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_LISTEN, NDMP9_MOVER_LISTEN, ndmp_2to9_mover_listen_request, ndmp_9to2_mover_listen_request, ndmp_2to9_mover_listen_reply, ndmp_9to2_mover_listen_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_SET_RECORD_SIZE, NDMP9_MOVER_SET_RECORD_SIZE, ndmp_2to9_mover_set_record_size_request, ndmp_9to2_mover_set_record_size_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_SET_WINDOW, NDMP9_MOVER_SET_WINDOW, ndmp_2to9_mover_set_window_request, ndmp_9to2_mover_set_window_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_CONTINUE, NDMP9_MOVER_CONTINUE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_ABORT, NDMP9_MOVER_ABORT, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_STOP, NDMP9_MOVER_STOP, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_READ, NDMP9_MOVER_READ, ndmp_2to9_mover_read_request, ndmp_9to2_mover_read_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP2_MOVER_CLOSE, NDMP9_MOVER_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { 0 }, }; #endif /* !NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp2_translate.h000066400000000000000000000070401263011562700214340ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_NDMP2 #ifdef __cplusplus extern "C" { #endif extern int ndmp_2to9_error ( ndmp2_error *error2, ndmp9_error *error9); extern int ndmp_9to2_error ( ndmp9_error *error9, ndmp2_error *error2); extern int ndmp_2to9_data_get_state_reply ( ndmp2_data_get_state_reply *reply2, ndmp9_data_get_state_reply *reply9); extern int ndmp_9to2_data_get_state_reply ( ndmp9_data_get_state_reply *reply9, ndmp2_data_get_state_reply *reply2); extern int ndmp_2to9_tape_get_state_reply ( ndmp2_tape_get_state_reply *reply2, ndmp9_tape_get_state_reply *reply9); extern int ndmp_9to2_tape_get_state_reply ( ndmp9_tape_get_state_reply *reply9, ndmp2_tape_get_state_reply *reply2); extern int ndmp_2to9_mover_get_state_reply ( ndmp2_mover_get_state_reply *reply2, ndmp9_mover_get_state_reply *reply9); extern int ndmp_9to2_mover_get_state_reply ( ndmp9_mover_get_state_reply *reply9, ndmp2_mover_get_state_reply *reply2); extern int ndmp_2to9_mover_addr ( ndmp2_mover_addr *addr2, ndmp9_addr *addr9); extern int ndmp_9to2_mover_addr ( ndmp9_addr *addr9, ndmp2_mover_addr *addr2); extern int ndmp_2to9_unix_file_stat ( ndmp2_unix_file_stat *fstat2, ndmp9_file_stat *fstat9); extern int ndmp_9to2_unix_file_stat ( ndmp9_file_stat *fstat9, ndmp2_unix_file_stat *fstat2); extern int ndmp_2to9_pval ( ndmp2_pval *pval2, ndmp9_pval *pval9); extern int ndmp_9to2_pval ( ndmp9_pval *pval9, ndmp2_pval *pval2); extern int ndmp_2to9_pval_vec ( ndmp2_pval *pval2, ndmp9_pval *pval9, unsigned n_pval); extern int ndmp_9to2_pval_vec ( ndmp9_pval *pval9, ndmp2_pval *pval2, unsigned n_pval); extern int ndmp_2to9_name ( ndmp2_name *name2, ndmp9_name *name9); extern int ndmp_9to2_name ( ndmp9_name *name9, ndmp2_name *name2); extern int ndmp_2to9_name_vec ( ndmp2_name *name2, ndmp9_name *name9, unsigned n_name); extern int ndmp_9to2_name_vec ( ndmp9_name *name9, ndmp2_name *name2, unsigned n_name); extern struct reqrep_xlate ndmp2_reqrep_xlate_table[]; #ifdef __cplusplus } #endif #endif /* !NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp2_xmt.c000066400000000000000000000221211263011562700202370ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP2 #define xdr_ndmp2_connect_close_request xdr_void #define xdr_ndmp2_connect_close_reply xdr_void #define xdr_ndmp2_config_get_host_info_request xdr_void #define xdr_ndmp2_config_get_mover_type_request xdr_void #define xdr_ndmp2_scsi_close_request xdr_void #define xdr_ndmp2_scsi_get_state_request xdr_void #define xdr_ndmp2_scsi_reset_device_request xdr_void #define xdr_ndmp2_scsi_reset_bus_request xdr_void #define xdr_ndmp2_tape_close_request xdr_void #define xdr_ndmp2_tape_get_state_request xdr_void #define xdr_ndmp2_data_get_state_request xdr_void #define xdr_ndmp2_data_abort_request xdr_void #define xdr_ndmp2_data_get_env_request xdr_void #define xdr_ndmp2_data_stop_request xdr_void #define xdr_ndmp2_notify_data_halted_reply 0 #define xdr_ndmp2_notify_connected_reply 0 #define xdr_ndmp2_notify_mover_halted_reply 0 #define xdr_ndmp2_notify_mover_paused_reply 0 #define xdr_ndmp2_notify_data_read_reply 0 #define xdr_ndmp2_log_log_reply 0 #define xdr_ndmp2_log_debug_reply 0 #define xdr_ndmp2_log_file_reply 0 #define xdr_ndmp2_fh_add_unix_path_reply 0 #define xdr_ndmp2_fh_add_unix_dir_reply 0 #define xdr_ndmp2_fh_add_unix_node_reply 0 #define xdr_ndmp2_mover_get_state_request xdr_void #define xdr_ndmp2_mover_continue_request xdr_void #define xdr_ndmp2_mover_abort_request xdr_void #define xdr_ndmp2_mover_stop_request xdr_void #define xdr_ndmp2_mover_close_request xdr_void struct ndmp_xdr_message_table ndmp2_xdr_message_table[] = { { NDMP2_CONNECT_OPEN, xdr_ndmp2_connect_open_request, xdr_ndmp2_connect_open_reply, }, { NDMP2_CONNECT_CLIENT_AUTH, xdr_ndmp2_connect_client_auth_request, xdr_ndmp2_connect_client_auth_reply, }, { NDMP2_CONNECT_CLOSE, xdr_ndmp2_connect_close_request, xdr_ndmp2_connect_close_reply, }, { NDMP2_CONNECT_SERVER_AUTH, xdr_ndmp2_connect_server_auth_request, xdr_ndmp2_connect_server_auth_reply, }, { NDMP2_CONFIG_GET_HOST_INFO, xdr_ndmp2_config_get_host_info_request, xdr_ndmp2_config_get_host_info_reply, }, { NDMP2_CONFIG_GET_BUTYPE_ATTR, xdr_ndmp2_config_get_butype_attr_request, xdr_ndmp2_config_get_butype_attr_reply, }, { NDMP2_CONFIG_GET_MOVER_TYPE, xdr_ndmp2_config_get_mover_type_request, xdr_ndmp2_config_get_mover_type_reply, }, { NDMP2_CONFIG_GET_AUTH_ATTR, xdr_ndmp2_config_get_auth_attr_request, xdr_ndmp2_config_get_auth_attr_reply, }, { NDMP2_SCSI_OPEN, xdr_ndmp2_scsi_open_request, xdr_ndmp2_scsi_open_reply, }, { NDMP2_SCSI_CLOSE, xdr_ndmp2_scsi_close_request, xdr_ndmp2_scsi_close_reply, }, { NDMP2_SCSI_GET_STATE, xdr_ndmp2_scsi_get_state_request, xdr_ndmp2_scsi_get_state_reply, }, { NDMP2_SCSI_SET_TARGET, xdr_ndmp2_scsi_set_target_request, xdr_ndmp2_scsi_set_target_reply, }, { NDMP2_SCSI_RESET_DEVICE, xdr_ndmp2_scsi_reset_device_request, xdr_ndmp2_scsi_reset_device_reply, }, { NDMP2_SCSI_RESET_BUS, xdr_ndmp2_scsi_reset_bus_request, xdr_ndmp2_scsi_reset_bus_reply, }, { NDMP2_SCSI_EXECUTE_CDB, xdr_ndmp2_scsi_execute_cdb_request, xdr_ndmp2_scsi_execute_cdb_reply, }, { NDMP2_TAPE_OPEN, xdr_ndmp2_tape_open_request, xdr_ndmp2_tape_open_reply, }, { NDMP2_TAPE_CLOSE, xdr_ndmp2_tape_close_request, xdr_ndmp2_tape_close_reply, }, { NDMP2_TAPE_GET_STATE, xdr_ndmp2_tape_get_state_request, xdr_ndmp2_tape_get_state_reply, }, { NDMP2_TAPE_MTIO, xdr_ndmp2_tape_mtio_request, xdr_ndmp2_tape_mtio_reply, }, { NDMP2_TAPE_WRITE, xdr_ndmp2_tape_write_request, xdr_ndmp2_tape_write_reply, }, { NDMP2_TAPE_READ, xdr_ndmp2_tape_read_request, xdr_ndmp2_tape_read_reply, }, { NDMP2_TAPE_EXECUTE_CDB, xdr_ndmp2_tape_execute_cdb_request, xdr_ndmp2_tape_execute_cdb_reply, }, { NDMP2_DATA_GET_STATE, xdr_ndmp2_data_get_state_request, xdr_ndmp2_data_get_state_reply, }, { NDMP2_DATA_START_BACKUP, xdr_ndmp2_data_start_backup_request, xdr_ndmp2_data_start_backup_reply, }, { NDMP2_DATA_START_RECOVER, xdr_ndmp2_data_start_recover_request, xdr_ndmp2_data_start_recover_reply, }, { NDMP2_DATA_ABORT, xdr_ndmp2_data_abort_request, xdr_ndmp2_data_abort_reply, }, { NDMP2_DATA_GET_ENV, xdr_ndmp2_data_get_env_request, xdr_ndmp2_data_get_env_reply, }, { NDMP2_DATA_STOP, xdr_ndmp2_data_stop_request, xdr_ndmp2_data_stop_reply, }, { NDMP2_DATA_START_RECOVER_FILEHIST, xdr_ndmp2_data_start_recover_filehist_request, xdr_ndmp2_data_start_recover_filehist_reply, }, { NDMP2_NOTIFY_DATA_HALTED, xdr_ndmp2_notify_data_halted_request, xdr_ndmp2_notify_data_halted_reply, }, { NDMP2_NOTIFY_CONNECTED, xdr_ndmp2_notify_connected_request, xdr_ndmp2_notify_connected_reply, }, { NDMP2_NOTIFY_MOVER_HALTED, xdr_ndmp2_notify_mover_halted_request, xdr_ndmp2_notify_mover_halted_reply, }, { NDMP2_NOTIFY_MOVER_PAUSED, xdr_ndmp2_notify_mover_paused_request, xdr_ndmp2_notify_mover_paused_reply, }, { NDMP2_NOTIFY_DATA_READ, xdr_ndmp2_notify_data_read_request, xdr_ndmp2_notify_data_read_reply, }, { NDMP2_LOG_LOG, xdr_ndmp2_log_log_request, xdr_ndmp2_log_log_reply, }, { NDMP2_LOG_DEBUG, xdr_ndmp2_log_debug_request, xdr_ndmp2_log_debug_reply, }, { NDMP2_LOG_FILE, xdr_ndmp2_log_file_request, xdr_ndmp2_log_file_reply, }, { NDMP2_FH_ADD_UNIX_PATH, xdr_ndmp2_fh_add_unix_path_request, xdr_ndmp2_fh_add_unix_path_reply, }, { NDMP2_FH_ADD_UNIX_DIR, xdr_ndmp2_fh_add_unix_dir_request, xdr_ndmp2_fh_add_unix_dir_reply, }, { NDMP2_FH_ADD_UNIX_NODE, xdr_ndmp2_fh_add_unix_node_request, xdr_ndmp2_fh_add_unix_node_reply, }, { NDMP2_MOVER_GET_STATE, xdr_ndmp2_mover_get_state_request, xdr_ndmp2_mover_get_state_reply, }, { NDMP2_MOVER_LISTEN, xdr_ndmp2_mover_listen_request, xdr_ndmp2_mover_listen_reply, }, { NDMP2_MOVER_CONTINUE, xdr_ndmp2_mover_continue_request, xdr_ndmp2_mover_continue_reply, }, { NDMP2_MOVER_ABORT, xdr_ndmp2_mover_abort_request, xdr_ndmp2_mover_abort_reply, }, { NDMP2_MOVER_STOP, xdr_ndmp2_mover_stop_request, xdr_ndmp2_mover_stop_reply, }, { NDMP2_MOVER_SET_WINDOW, xdr_ndmp2_mover_set_window_request, xdr_ndmp2_mover_set_window_reply, }, { NDMP2_MOVER_READ, xdr_ndmp2_mover_read_request, xdr_ndmp2_mover_read_reply, }, { NDMP2_MOVER_CLOSE, xdr_ndmp2_mover_close_request, xdr_ndmp2_mover_close_reply, }, { NDMP2_MOVER_SET_RECORD_SIZE, xdr_ndmp2_mover_set_record_size_request, xdr_ndmp2_mover_set_record_size_reply, }, {0} }; /* * XDR unsigned long integers * same as xdr_long - open coded to save a proc call! */ bool_t xdr_ndmp2_u_quad(xdrs, objp) register XDR *xdrs; ndmp2_u_quad *objp; { uint32_t hi, lo; switch (xdrs->x_op) { case XDR_DECODE: #if defined(_LP64) if (XDR_GETINT32(xdrs, (int32_t *)&hi) && XDR_GETINT32(xdrs, (int32_t *)&lo)) { #else if (XDR_GETLONG(xdrs, (long *)&hi) && XDR_GETLONG(xdrs, (long *)&lo)) { #endif *objp = ((uint64_t)hi << 32) | (lo & 0xffffffff); return TRUE; } break; case XDR_ENCODE: hi = *objp >> 32; lo = *objp & 0xffffffff; #if defined(_LP64) return XDR_PUTINT32(xdrs, (int32_t *)&hi) && XDR_PUTINT32(xdrs, (int32_t *)&lo); #else return XDR_PUTLONG(xdrs, (long *)&hi) && XDR_PUTLONG(xdrs, (long *)&lo); #endif case XDR_FREE: return (TRUE); } return (FALSE); } #endif /* !NDMOS_OPTION_NO_NDMP2 */ bareos-Release-14.2.6/src/ndmp/ndmp3.x000066400000000000000000000566511263011562700174140ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ /* * ndmp3.x * * Description : NDMP protocol rpcgen file. * * Copyright (c) 1999 Intelliguard Software, Network Appliance. * All Rights Reserved. * * $Id: ndmp.x,v 1.11 1998/05/26 03:52:12 tim Exp $ */ %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 %#pragma GCC diagnostic ignored "-Wunused-variable" %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 470 %#pragma GCC diagnostic ignored "-Wunprototyped-calls" %#endif %#endif %#ifndef NDMOS_OPTION_NO_NDMP3 const NDMP3VER = 3; const NDMP3PORT = 10000; %#define ndmp3_u_quad uint64_t %extern bool_t xdr_ndmp3_u_quad(); struct _ndmp3_u_quad { uint32_t high; uint32_t low; }; struct ndmp3_pval { string name<>; string value<>; }; enum ndmp3_error { NDMP3_NO_ERR, /* No error */ NDMP3_NOT_SUPPORTED_ERR, /* Call is not supported */ NDMP3_DEVICE_BUSY_ERR, /* The device is in use */ NDMP3_DEVICE_OPENED_ERR, /* Another tape or scsi device * is already open */ NDMP3_NOT_AUTHORIZED_ERR, /* connection has not been authorized*/ NDMP3_PERMISSION_ERR, /* some sort of permission problem */ NDMP3_DEV_NOT_OPEN_ERR, /* SCSI device is not open */ NDMP3_IO_ERR, /* I/O error */ NDMP3_TIMEOUT_ERR, /* command timed out */ NDMP3_ILLEGAL_ARGS_ERR, /* illegal arguments in request */ NDMP3_NO_TAPE_LOADED_ERR, /* Cannot open because there is * no tape loaded */ NDMP3_WRITE_PROTECT_ERR, /* tape cannot be open for write */ NDMP3_EOF_ERR, /* Command encountered EOF */ NDMP3_EOM_ERR, /* Command encountered EOM */ NDMP3_FILE_NOT_FOUND_ERR, /* File not found during restore */ NDMP3_BAD_FILE_ERR, /* The file descriptor is invalid */ NDMP3_NO_DEVICE_ERR, /* The device is not at that target */ NDMP3_NO_BUS_ERR, /* Invalid controller */ NDMP3_XDR_DECODE_ERR, /* Can't decode the request argument */ NDMP3_ILLEGAL_STATE_ERR, /* Call can't be done at this state */ NDMP3_UNDEFINED_ERR, /* Undefined Error */ NDMP3_XDR_ENCODE_ERR, /* Can't encode the reply argument */ NDMP3_NO_MEM_ERR, /* no memory */ NDMP3_CONNECT_ERR /* Error connecting to another * NDMP server */ }; enum ndmp3_header_message_type { NDMP3_MESSAGE_REQUEST, NDMP3_MESSAGE_REPLY }; enum ndmp3_message { NDMP3_CONNECT_OPEN = 0x900, /* CONNECT INTERFACE */ NDMP3_CONNECT_CLIENT_AUTH = 0x901, NDMP3_CONNECT_CLOSE = 0x902, NDMP3_CONNECT_SERVER_AUTH = 0x903, NDMP3_CONFIG_GET_HOST_INFO = 0x100, /* CONFIG INTERFACE */ NDMP3_CONFIG_GET_CONNECTION_TYPE = 0x102, /* NDMP2_CONFIG_GET_MOVER_TYPE on v2*/ NDMP3_CONFIG_GET_AUTH_ATTR = 0x103, NDMP3_CONFIG_GET_BUTYPE_INFO = 0x104, /* new from v3 */ NDMP3_CONFIG_GET_FS_INFO = 0x105, /* new from v3 */ NDMP3_CONFIG_GET_TAPE_INFO = 0x106, /* new from v3 */ NDMP3_CONFIG_GET_SCSI_INFO = 0x107, /* new from v3 */ NDMP3_CONFIG_GET_SERVER_INFO =0x108, /* new from v3 */ NDMP3_SCSI_OPEN = 0x200, /* SCSI INTERFACE */ NDMP3_SCSI_CLOSE = 0x201, NDMP3_SCSI_GET_STATE = 0x202, NDMP3_SCSI_SET_TARGET = 0x203, NDMP3_SCSI_RESET_DEVICE = 0x204, NDMP3_SCSI_RESET_BUS = 0x205, NDMP3_SCSI_EXECUTE_CDB = 0x206, NDMP3_TAPE_OPEN = 0x300, /* TAPE INTERFACE */ NDMP3_TAPE_CLOSE = 0x301, NDMP3_TAPE_GET_STATE = 0x302, NDMP3_TAPE_MTIO = 0x303, NDMP3_TAPE_WRITE = 0x304, NDMP3_TAPE_READ = 0x305, NDMP3_TAPE_EXECUTE_CDB = 0x307, NDMP3_DATA_GET_STATE = 0x400, /* DATA INTERFACE */ NDMP3_DATA_START_BACKUP = 0x401, NDMP3_DATA_START_RECOVER = 0x402, NDMP3_DATA_ABORT = 0x403, NDMP3_DATA_GET_ENV = 0x404, NDMP3_DATA_STOP = 0x407, NDMP3_DATA_LISTEN = 0x409, /* new from V3 */ NDMP3_DATA_CONNECT = 0x40a, /* new from V3 */ NDMP3_DATA_START_RECOVER_FILEHIST = 0x40b, /* same as V3.1 */ NDMP3_NOTIFY_DATA_HALTED =0x501,/* NOTIFY INTERFACE */ NDMP3_NOTIFY_CONNECTED = 0x502, NDMP3_NOTIFY_MOVER_HALTED = 0x503, NDMP3_NOTIFY_MOVER_PAUSED = 0x504, NDMP3_NOTIFY_DATA_READ =0x505, NDMP3_LOG_FILE = 0x602, /* LOGGING INTERFACE */ NDMP3_LOG_MESSAGE = 0x603, /* new from v3 */ NDMP3_FH_ADD_FILE = 0x703, /* FILE HISTORY INTERFACE */ NDMP3_FH_ADD_DIR = 0x704, NDMP3_FH_ADD_NODE = 0x705, NDMP3_MOVER_GET_STATE = 0xa00, /* MOVER INTERFACE */ NDMP3_MOVER_LISTEN = 0xa01, NDMP3_MOVER_CONTINUE = 0xa02, NDMP3_MOVER_ABORT = 0xa03, NDMP3_MOVER_STOP = 0xa04, NDMP3_MOVER_SET_WINDOW = 0xa05, NDMP3_MOVER_READ = 0xa06, NDMP3_MOVER_CLOSE =0xa07, NDMP3_MOVER_SET_RECORD_SIZE =0xa08, NDMP3_MOVER_CONNECT =0xa09, /* new from V3 */ NDMP3_VENDORS_BASE = 0xf000, /* Reserved for the vendor * specific usage * from 0xf000 to 0xfeff */ NDMP3_RESERVED_BASE = 0xff00 /* Reserved for prototyping * from 0xff00 to 0xffff */ }; struct ndmp3_header { uint32_t sequence; /* monotonically increasing */ uint32_t time_stamp; /* time stamp of message */ ndmp3_header_message_type message_type; /* what type of message */ ndmp3_message message; /* message number */ uint32_t reply_sequence; /* reply is in response to */ ndmp3_error error; /* communications errors */ }; /**********************/ /* CONNECT INTERFACE */ /**********************/ /* NDMP3_CONNECT_OPEN */ struct ndmp3_connect_open_request { uint16_t protocol_version; /* the version of protocol supported */ }; struct ndmp3_connect_open_reply { ndmp3_error error; }; /* NDMP3_CONNECT_CLIENT_AUTH */ enum ndmp3_auth_type { NDMP3_AUTH_NONE, /* no password is required */ NDMP3_AUTH_TEXT, /* the clear text password */ NDMP3_AUTH_MD5 /* md5 */ }; struct ndmp3_auth_text { string auth_id<>; string auth_password<>; }; struct ndmp3_auth_md5 { string auth_id<>; opaque auth_digest[16]; }; union ndmp3_auth_data switch (enum ndmp3_auth_type auth_type) { case NDMP3_AUTH_NONE: void; case NDMP3_AUTH_TEXT: struct ndmp3_auth_text auth_text; case NDMP3_AUTH_MD5: struct ndmp3_auth_md5 auth_md5; }; struct ndmp3_connect_client_auth_request { ndmp3_auth_data auth_data; }; struct ndmp3_connect_client_auth_reply { ndmp3_error error; }; /* NDMP3_CONNECT_CLOSE */ /* no request arguments */ /* no reply arguments */ /* NDMP3_CONNECT_SERVER_AUTH */ union ndmp3_auth_attr switch (enum ndmp3_auth_type auth_type) { case NDMP3_AUTH_NONE: void; case NDMP3_AUTH_TEXT: void; case NDMP3_AUTH_MD5: opaque challenge[64]; }; struct ndmp3_connect_server_auth_request { ndmp3_auth_attr client_attr; }; struct ndmp3_connect_server_auth_reply { ndmp3_error error; ndmp3_auth_data server_result; }; /********************/ /* CONFIG INTERFACE */ /********************/ /* NDMP3_CONFIG_GET_HOST_INFO */ /* no request arguments */ struct ndmp3_config_get_host_info_reply { ndmp3_error error; string hostname<>; /* host name */ string os_type<>; /* The O/S type (e.g. SOLARIS) */ string os_vers<>; /* The O/S version (e.g. 2.5) */ string hostid<>; }; enum ndmp3_addr_type { NDMP3_ADDR_LOCAL, NDMP3_ADDR_TCP, NDMP3_ADDR_FC, NDMP3_ADDR_IPC }; /* NDMP3_CONFIG_GET_CONNECTION_TYPE */ /* no request arguments */ struct ndmp3_config_get_connection_type_reply { ndmp3_error error; ndmp3_addr_type addr_types<>; }; /* NDMP3_CONFIG_GET_AUTH_ATTR */ struct ndmp3_config_get_auth_attr_request { ndmp3_auth_type auth_type; }; struct ndmp3_config_get_auth_attr_reply { ndmp3_error error; ndmp3_auth_attr server_attr; }; /* NDMP3_CONFIG_GET_SERVER_INFO */ /* no requset arguments */ struct ndmp3_config_get_server_info_reply { ndmp3_error error; string vendor_name<>; string product_name<>; string revision_number<>; ndmp3_auth_type auth_type<>; }; /* backup type attributes */ const NDMP3_BUTYPE_BACKUP_FILE_HISTORY = 0x0001; const NDMP3_BUTYPE_BACKUP_FILELIST = 0x0002; const NDMP3_BUTYPE_RECOVER_FILELIST = 0x0004; const NDMP3_BUTYPE_BACKUP_DIRECT = 0x0008; const NDMP3_BUTYPE_RECOVER_DIRECT = 0x0010; const NDMP3_BUTYPE_BACKUP_INCREMENTAL = 0x0020; const NDMP3_BUTYPE_RECOVER_INCREMENTAL = 0x0040; const NDMP3_BUTYPE_BACKUP_UTF8 = 0x0080; const NDMP3_BUTYPE_RECOVER_UTF8 = 0x0100; const NDMP3_BUTYPE_RECOVER_FILE_HISTORY = 0x0200; struct ndmp3_butype_info { string butype_name<>; ndmp3_pval default_env<>; uint32_t attrs; }; /* NDMP3_CONFIG_GET_BUTYPE_INFO */ /* no request arguments */ struct ndmp3_config_get_butype_info_reply { ndmp3_error error; ndmp3_butype_info butype_info<>; }; /* invalid bit */ const NDMP3_FS_INFO_TOTAL_SIZE_INVALID = 0x00000001; const NDMP3_FS_INFO_USED_SIZE_INVALID = 0x00000002; const NDMP3_FS_INFO_AVAIL_SIZE_INVALID = 0x00000004; const NDMP3_FS_INFO_TOTAL_INODES_INVALID = 0x00000008; const NDMP3_FS_INFO_USED_INODES_INVALID = 0x00000010; struct ndmp3_fs_info { uint32_t invalid; string fs_type<>; string fs_logical_device<>; string fs_physical_device<>; ndmp3_u_quad total_size; ndmp3_u_quad used_size; ndmp3_u_quad avail_size; ndmp3_u_quad total_inodes; ndmp3_u_quad used_inodes; ndmp3_pval fs_env<>; string fs_status<>; }; /* NDMP3_CONFIG_GET_FS_INFO */ /* no request arguments */ struct ndmp3_config_get_fs_info_reply { ndmp3_error error; ndmp3_fs_info fs_info<>; }; /* NDMP3_CONFIG_GET_TAPE_INFO */ /* no request arguments */ /* tape attributes */ const NDMP3_TAPE_ATTR_REWIND = 0x00000001; const NDMP3_TAPE_ATTR_UNLOAD = 0x00000002; struct ndmp3_device_capability { string device<>; uint32_t attr; ndmp3_pval capability<>; }; struct ndmp3_device_info { string model<>; ndmp3_device_capability caplist<>; }; struct ndmp3_config_get_tape_info_reply { ndmp3_error error; ndmp3_device_info tape_info<>; }; /* NDMP3_CONFIG_GET_SCSI_INFO */ /* jukebox attributes */ struct ndmp3_config_get_scsi_info_reply { ndmp3_error error; ndmp3_device_info scsi_info<>; }; /******************/ /* SCSI INTERFACE */ /******************/ /* NDMP3_SCSI_OPEN */ struct ndmp3_scsi_open_request { string device<>; }; struct ndmp3_scsi_open_reply { ndmp3_error error; }; /* NDMP3_SCSI_CLOSE */ /* no request arguments */ struct ndmp3_scsi_close_reply { ndmp3_error error; }; /* NDMP3_SCSI_GET_STATE */ /* no request arguments */ struct ndmp3_scsi_get_state_reply { ndmp3_error error; short target_controller; short target_id; short target_lun; }; /* NDMP3_SCSI_SET_TARGET */ struct ndmp3_scsi_set_target_request { string device<>; uint16_t target_controller; uint16_t target_id; uint16_t target_lun; }; struct ndmp3_scsi_set_target_reply { ndmp3_error error; }; /* NDMP3_SCSI_RESET_DEVICE */ /* no request arguments */ struct ndmp3_scsi_reset_device_reply { ndmp3_error error; }; /* NDMP3_SCSI_RESET_BUS */ /* no request arguments */ struct ndmp3_scsi_reset_bus_reply { ndmp3_error error; }; /* NDMP3_SCSI_EXECUTE_CDB */ const NDMP3_SCSI_DATA_IN = 0x00000001; /* Expect data from SCSI device */ const NDMP3_SCSI_DATA_OUT = 0x00000002; /* Transfer data to SCSI device */ struct ndmp3_execute_cdb_request { uint32_t flags; uint32_t timeout; uint32_t datain_len; /* Set for expected datain */ opaque cdb<>; opaque dataout<>; }; struct ndmp3_execute_cdb_reply { ndmp3_error error; u_char status; /* SCSI status bytes */ uint32_t dataout_len; opaque datain<>; /* SCSI datain */ opaque ext_sense<>; /* Extended sense data */ }; typedef ndmp3_execute_cdb_request ndmp3_scsi_execute_cdb_request; typedef ndmp3_execute_cdb_reply ndmp3_scsi_execute_cdb_reply; /******************/ /* TAPE INTERFACE */ /******************/ /* NDMP3_TAPE_OPEN */ enum ndmp3_tape_open_mode { NDMP3_TAPE_READ_MODE, NDMP3_TAPE_RDWR_MODE }; struct ndmp3_tape_open_request { string device<>; ndmp3_tape_open_mode mode; }; struct ndmp3_tape_open_reply { ndmp3_error error; }; /* NDMP3_TAPE_CLOSE */ /* no request arguments */ struct ndmp3_tape_close_reply { ndmp3_error error; }; /*NDMP3_TAPE_GET_STATE */ /* no request arguments */ const NDMP3_TAPE_STATE_NOREWIND = 0x0008; /* non-rewind device */ const NDMP3_TAPE_STATE_WR_PROT = 0x0010; /* write-protected */ const NDMP3_TAPE_STATE_ERROR = 0x0020; /* media error */ const NDMP3_TAPE_STATE_UNLOAD = 0x0040; /* tape will be unloaded when * the device is closed */ /* invalid bit */ const NDMP3_TAPE_STATE_FILE_NUM_INVALID = 0x00000001; const NDMP3_TAPE_STATE_SOFT_ERRORS_INVALID = 0x00000002; const NDMP3_TAPE_STATE_BLOCK_SIZE_INVALID = 0x00000004; const NDMP3_TAPE_STATE_BLOCKNO_INVALID = 0x00000008; const NDMP3_TAPE_STATE_TOTAL_SPACE_INVALID = 0x00000010; const NDMP3_TAPE_STATE_SPACE_REMAIN_INVALID = 0x00000020; const NDMP3_TAPE_STATE_PARTITION_INVALID = 0x00000040; struct ndmp3_tape_get_state_reply { uint32_t invalid; ndmp3_error error; uint32_t flags; uint32_t file_num; uint32_t soft_errors; uint32_t block_size; uint32_t blockno; ndmp3_u_quad total_space; ndmp3_u_quad space_remain; uint32_t partition; }; /* NDMP3_TAPE_MTIO */ enum ndmp3_tape_mtio_op { NDMP3_MTIO_FSF, NDMP3_MTIO_BSF, NDMP3_MTIO_FSR, NDMP3_MTIO_BSR, NDMP3_MTIO_REW, NDMP3_MTIO_EOF, NDMP3_MTIO_OFF }; struct ndmp3_tape_mtio_request { ndmp3_tape_mtio_op tape_op; uint32_t count; }; struct ndmp3_tape_mtio_reply { ndmp3_error error; uint32_t resid_count; }; /* NDMP3_TAPE_WRITE */ struct ndmp3_tape_write_request { opaque data_out<>; }; struct ndmp3_tape_write_reply { ndmp3_error error; uint32_t count; }; /* NDMP3_TAPE_READ */ struct ndmp3_tape_read_request { uint32_t count; }; struct ndmp3_tape_read_reply { ndmp3_error error; opaque data_in<>; }; /* NDMP3_TAPE_EXECUTE_CDB */ typedef ndmp3_execute_cdb_request ndmp3_tape_execute_cdb_request; typedef ndmp3_execute_cdb_reply ndmp3_tape_execute_cdb_reply; /********************************/ /* MOVER INTERFACE */ /********************************/ /* NDMP3_MOVER_GET_STATE */ enum ndmp3_mover_state { NDMP3_MOVER_STATE_IDLE, NDMP3_MOVER_STATE_LISTEN, NDMP3_MOVER_STATE_ACTIVE, NDMP3_MOVER_STATE_PAUSED, NDMP3_MOVER_STATE_HALTED }; enum ndmp3_mover_pause_reason { NDMP3_MOVER_PAUSE_NA, NDMP3_MOVER_PAUSE_EOM, NDMP3_MOVER_PAUSE_EOF, NDMP3_MOVER_PAUSE_SEEK, NDMP3_MOVER_PAUSE_MEDIA_ERROR, NDMP3_MOVER_PAUSE_EOW }; enum ndmp3_mover_halt_reason { NDMP3_MOVER_HALT_NA, NDMP3_MOVER_HALT_CONNECT_CLOSED, NDMP3_MOVER_HALT_ABORTED, NDMP3_MOVER_HALT_INTERNAL_ERROR, NDMP3_MOVER_HALT_CONNECT_ERROR }; /* mover address */ enum ndmp3_mover_mode { NDMP3_MOVER_MODE_READ, /* read from data connection; write to tape */ NDMP3_MOVER_MODE_WRITE /* write to data connection; read from tape */ }; struct ndmp3_tcp_addr { uint32_t ip_addr; uint16_t port; }; struct ndmp3_fc_addr { uint32_t loop_id; }; struct ndmp3_ipc_addr { opaque comm_data<>; }; union ndmp3_addr switch (ndmp3_addr_type addr_type) { case NDMP3_ADDR_LOCAL: void; case NDMP3_ADDR_TCP: ndmp3_tcp_addr tcp_addr; case NDMP3_ADDR_FC: ndmp3_fc_addr fc_addr; case NDMP3_ADDR_IPC: ndmp3_ipc_addr ipc_addr; }; /* no request arguments */ struct ndmp3_mover_get_state_reply { ndmp3_error error; ndmp3_mover_state state; ndmp3_mover_pause_reason pause_reason; ndmp3_mover_halt_reason halt_reason; uint32_t record_size; uint32_t record_num; ndmp3_u_quad data_written; ndmp3_u_quad seek_position; ndmp3_u_quad bytes_left_to_read; ndmp3_u_quad window_offset; ndmp3_u_quad window_length; ndmp3_addr data_connection_addr; }; /* NDMP3_MOVER_LISTEN */ struct ndmp3_mover_listen_request { ndmp3_mover_mode mode; ndmp3_addr_type addr_type; }; struct ndmp3_mover_listen_reply { ndmp3_error error; ndmp3_addr data_connection_addr; }; /* NDMP3_MOVER_CONNECT */ struct ndmp3_mover_connect_request { ndmp3_mover_mode mode; ndmp3_addr addr; }; struct ndmp3_mover_connect_reply { ndmp3_error error; }; /* NDMP3_MOVER_SET_RECORD_SIZE */ struct ndmp3_mover_set_record_size_request { uint32_t len; }; struct ndmp3_mover_set_record_size_reply { ndmp3_error error; }; /* NDMP3_MOVER_SET_WINDOW */ struct ndmp3_mover_set_window_request { ndmp3_u_quad offset; ndmp3_u_quad length; }; struct ndmp3_mover_set_window_reply { ndmp3_error error; }; /* NDMP3_MOVER_CONTINUE */ /* no request arguments */ struct ndmp3_mover_continue_reply { ndmp3_error error; }; /* NDMP3_MOVER_ABORT */ /* no request arguments */ struct ndmp3_mover_abort_reply { ndmp3_error error; }; /* NDMP3_MOVER_STOP */ /* no request arguments */ struct ndmp3_mover_stop_reply { ndmp3_error error; }; /* NDMP3_MOVER_READ */ struct ndmp3_mover_read_request { ndmp3_u_quad offset; ndmp3_u_quad length; }; struct ndmp3_mover_read_reply { ndmp3_error error; }; /* NDMP3_MOVER_CLOSE */ /* no request arguments */ struct ndmp3_mover_close_reply { ndmp3_error error; }; /********************************/ /* DATA INTERFACE */ /********************************/ /* NDMP3_DATA_GET_STATE */ /* no request arguments */ enum ndmp3_data_operation { NDMP3_DATA_OP_NOACTION, NDMP3_DATA_OP_BACKUP, NDMP3_DATA_OP_RESTORE, NDMP3_DATA_OP_RESTORE_FILEHIST }; enum ndmp3_data_state { NDMP3_DATA_STATE_IDLE, NDMP3_DATA_STATE_ACTIVE, NDMP3_DATA_STATE_HALTED, NDMP3_DATA_STATE_LISTEN, NDMP3_DATA_STATE_CONNECTED }; enum ndmp3_data_halt_reason { NDMP3_DATA_HALT_NA, NDMP3_DATA_HALT_SUCCESSFUL, NDMP3_DATA_HALT_ABORTED, NDMP3_DATA_HALT_INTERNAL_ERROR, NDMP3_DATA_HALT_CONNECT_ERROR }; /* invalid bit */ const NDMP3_DATA_STATE_EST_BYTES_REMAIN_INVALID = 0x00000001; const NDMP3_DATA_STATE_EST_TIME_REMAIN_INVALID = 0x00000002; struct ndmp3_data_get_state_reply { uint32_t invalid; ndmp3_error error; ndmp3_data_operation operation; ndmp3_data_state state; ndmp3_data_halt_reason halt_reason; ndmp3_u_quad bytes_processed; ndmp3_u_quad est_bytes_remain; uint32_t est_time_remain; ndmp3_addr data_connection_addr; ndmp3_u_quad read_offset; ndmp3_u_quad read_length; }; /* NDMP3_DATA_START_BACKUP */ struct ndmp3_data_start_backup_request { string bu_type<>; /* backup method to use */ ndmp3_pval env<>; /* Parameters that may modify backup */ }; struct ndmp3_data_start_backup_reply { ndmp3_error error; }; /* NDMP3_DATA_START_RECOVER */ struct ndmp3_name { string original_path<>; string destination_dir<>; string new_name<>; /* Direct access restore only */ string other_name<>; /* Direct access restore only */ ndmp3_u_quad node; /* Direct access restore only */ ndmp3_u_quad fh_info; /* Direct access restore only */ }; struct ndmp3_data_start_recover_request { ndmp3_pval env<>; ndmp3_name nlist<>; string bu_type<>; }; struct ndmp3_data_start_recover_reply { ndmp3_error error; }; /* NDMP3_DATA_START_RECOVER_FILEHIST */ typedef ndmp3_data_start_recover_request ndmp3_data_start_recover_filehist_request; typedef ndmp3_data_start_recover_reply ndmp3_data_start_recover_filehist_reply; /* NDMP3_DATA_ABORT */ /* no request arguments */ struct ndmp3_data_abort_reply { ndmp3_error error; }; /* NDMP3_DATA_STOP */ /* no request arguments */ struct ndmp3_data_stop_reply { ndmp3_error error; }; /* NDMP3_DATA_GET_ENV */ /* no request arguments */ struct ndmp3_data_get_env_reply { ndmp3_error error; ndmp3_pval env<>; }; /* NDMP3_DATA_LISTEN */ struct ndmp3_data_listen_request { ndmp3_addr_type addr_type; }; struct ndmp3_data_listen_reply { ndmp3_error error; ndmp3_addr data_connection_addr; }; /* NDMP3_DATA_CONNECT */ struct ndmp3_data_connect_request { ndmp3_addr addr; }; struct ndmp3_data_connect_reply { ndmp3_error error; }; /****************************************/ /* NOTIFY INTERFACE */ /****************************************/ /* NDMP3_NOTIFY_DATA_HALTED */ struct ndmp3_notify_data_halted_request { ndmp3_data_halt_reason reason; string text_reason<>; }; /* NDMP3_NOTIFY_CONNECTED */ enum ndmp3_connect_reason { NDMP3_CONNECTED, /* Connect sucessfully */ NDMP3_SHUTDOWN, /* Connection shutdown */ NDMP3_REFUSED /* reach the maximum number of connections */ }; struct ndmp3_notify_connected_request { ndmp3_connect_reason reason; uint16_t protocol_version; string text_reason<>; }; /* NDMP3_NOTIFY_MOVER_PAUSED */ struct ndmp3_notify_mover_paused_request { ndmp3_mover_pause_reason reason; ndmp3_u_quad seek_position; }; /* No reply */ /* NDMP3_NOTIFY_MOVER_HALTED */ struct ndmp3_notify_mover_halted_request { ndmp3_mover_halt_reason reason; string text_reason<>; }; /* No reply */ /* NDMP3_NOTIFY_DATA_READ */ struct ndmp3_notify_data_read_request { ndmp3_u_quad offset; ndmp3_u_quad length; }; /* No reply */ /********************************/ /* LOG INTERFACE */ /********************************/ /* NDMP3_LOG_MESSAGE */ enum ndmp3_log_type { NDMP3_LOG_NORMAL, NDMP3_LOG_DEBUG, NDMP3_LOG_ERROR, NDMP3_LOG_WARNING }; struct ndmp3_log_message_request { ndmp3_log_type log_type; uint32_t message_id; string entry<>; }; /* No reply */ /* NDMP3_LOG_FILE */ struct ndmp3_log_file_request { string name<>; ndmp3_error error; }; /* No reply */ /*****************************/ /* File History INTERFACE */ /*****************************/ /* NDMP3_FH_ADD_FILE */ enum ndmp3_fs_type { NDMP3_FS_UNIX, /* UNIX */ NDMP3_FS_NT, /* NT */ NDMP3_FS_OTHER }; typedef string ndmp3_path<>; struct ndmp3_nt_path { ndmp3_path nt_path; ndmp3_path dos_path; }; union ndmp3_file_name switch (ndmp3_fs_type fs_type) { case NDMP3_FS_UNIX: ndmp3_path unix_name; case NDMP3_FS_NT: ndmp3_nt_path nt_name; default: ndmp3_path other_name; }; enum ndmp3_file_type { NDMP3_FILE_DIR, NDMP3_FILE_FIFO, NDMP3_FILE_CSPEC, NDMP3_FILE_BSPEC, NDMP3_FILE_REG, NDMP3_FILE_SLINK, NDMP3_FILE_SOCK, NDMP3_FILE_REGISTRY, NDMP3_FILE_OTHER }; /* invalid bit */ const NDMP3_FILE_STAT_ATIME_INVALID = 0x00000001; const NDMP3_FILE_STAT_CTIME_INVALID = 0x00000002; const NDMP3_FILE_STAT_GROUP_INVALID = 0x00000004; struct ndmp3_file_stat { uint32_t invalid; ndmp3_fs_type fs_type; ndmp3_file_type ftype; uint32_t mtime; uint32_t atime; uint32_t ctime; uint32_t owner; /* uid for UNIX, owner for NT */ uint32_t group; /* gid for UNIX, NA for NT */ uint32_t fattr; /* mode for UNIX, fattr for NT */ ndmp3_u_quad size; uint32_t links; }; /* one file could have both UNIX and NT name and attributes */ struct ndmp3_file { ndmp3_file_name names<>; ndmp3_file_stat stats<>; ndmp3_u_quad node; /* used for the direct access */ ndmp3_u_quad fh_info;/* used for the direct access */ }; struct ndmp3_fh_add_file_request { ndmp3_file files<>; }; /* No reply */ /* NDMP3_FH_ADD_DIR */ struct ndmp3_dir { ndmp3_file_name names<>; ndmp3_u_quad node; ndmp3_u_quad parent; }; struct ndmp3_fh_add_dir_request { ndmp3_dir dirs<>; }; /* No reply */ /* NDMP3_FH_ADD_NODE */ struct ndmp3_node { ndmp3_file_stat stats<>; ndmp3_u_quad node; ndmp3_u_quad fh_info; }; struct ndmp3_fh_add_node_request { ndmp3_node nodes<>; }; /* No reply */ %#endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp3_enum_strs.c000066400000000000000000000455171263011562700214650ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP3 extern struct ndmp_enum_str_table ndmp3_error_table[]; extern char * ndmp3_error_to_str (ndmp3_error val); extern int ndmp3_error_from_str (ndmp3_error *valp, char *str); char * ndmp3_error_to_str (ndmp3_error val) { return ndmp_enum_to_str ((int)val, ndmp3_error_table); } int ndmp3_error_from_str (ndmp3_error *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_error_table); } struct ndmp_enum_str_table ndmp3_error_table[] = { { "NDMP3_NO_ERR", NDMP3_NO_ERR, }, { "NDMP3_NOT_SUPPORTED_ERR", NDMP3_NOT_SUPPORTED_ERR, }, { "NDMP3_DEVICE_BUSY_ERR", NDMP3_DEVICE_BUSY_ERR, }, { "NDMP3_DEVICE_OPENED_ERR", NDMP3_DEVICE_OPENED_ERR, }, { "NDMP3_NOT_AUTHORIZED_ERR", NDMP3_NOT_AUTHORIZED_ERR, }, { "NDMP3_PERMISSION_ERR", NDMP3_PERMISSION_ERR, }, { "NDMP3_DEV_NOT_OPEN_ERR", NDMP3_DEV_NOT_OPEN_ERR, }, { "NDMP3_IO_ERR", NDMP3_IO_ERR, }, { "NDMP3_TIMEOUT_ERR", NDMP3_TIMEOUT_ERR, }, { "NDMP3_ILLEGAL_ARGS_ERR", NDMP3_ILLEGAL_ARGS_ERR, }, { "NDMP3_NO_TAPE_LOADED_ERR", NDMP3_NO_TAPE_LOADED_ERR, }, { "NDMP3_WRITE_PROTECT_ERR", NDMP3_WRITE_PROTECT_ERR, }, { "NDMP3_EOF_ERR", NDMP3_EOF_ERR, }, { "NDMP3_EOM_ERR", NDMP3_EOM_ERR, }, { "NDMP3_FILE_NOT_FOUND_ERR", NDMP3_FILE_NOT_FOUND_ERR, }, { "NDMP3_BAD_FILE_ERR", NDMP3_BAD_FILE_ERR, }, { "NDMP3_NO_DEVICE_ERR", NDMP3_NO_DEVICE_ERR, }, { "NDMP3_NO_BUS_ERR", NDMP3_NO_BUS_ERR, }, { "NDMP3_XDR_DECODE_ERR", NDMP3_XDR_DECODE_ERR, }, { "NDMP3_ILLEGAL_STATE_ERR", NDMP3_ILLEGAL_STATE_ERR, }, { "NDMP3_UNDEFINED_ERR", NDMP3_UNDEFINED_ERR, }, { "NDMP3_XDR_ENCODE_ERR", NDMP3_XDR_ENCODE_ERR, }, { "NDMP3_NO_MEM_ERR", NDMP3_NO_MEM_ERR, }, { "NDMP3_CONNECT_ERR", NDMP3_CONNECT_ERR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_header_message_type_table[]; extern char * ndmp3_header_message_type_to_str (ndmp3_header_message_type val); extern int ndmp3_header_message_type_from_str (ndmp3_header_message_type *valp, char *str); char * ndmp3_header_message_type_to_str (ndmp3_header_message_type val) { return ndmp_enum_to_str ((int)val, ndmp3_header_message_type_table); } int ndmp3_header_message_type_from_str (ndmp3_header_message_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_header_message_type_table); } struct ndmp_enum_str_table ndmp3_header_message_type_table[] = { { "NDMP3_MESSAGE_REQUEST", NDMP3_MESSAGE_REQUEST, }, { "NDMP3_MESSAGE_REPLY", NDMP3_MESSAGE_REPLY, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_message_table[]; extern char * ndmp3_message_to_str (ndmp3_message val); extern int ndmp3_message_from_str (ndmp3_message *valp, char *str); char * ndmp3_message_to_str (ndmp3_message val) { return ndmp_enum_to_str ((int)val, ndmp3_message_table); } int ndmp3_message_from_str (ndmp3_message *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_message_table); } struct ndmp_enum_str_table ndmp3_message_table[] = { { "NDMP3_CONNECT_OPEN", NDMP3_CONNECT_OPEN, }, { "NDMP3_CONNECT_CLIENT_AUTH", NDMP3_CONNECT_CLIENT_AUTH, }, { "NDMP3_CONNECT_CLOSE", NDMP3_CONNECT_CLOSE, }, { "NDMP3_CONNECT_SERVER_AUTH", NDMP3_CONNECT_SERVER_AUTH, }, { "NDMP3_CONFIG_GET_HOST_INFO", NDMP3_CONFIG_GET_HOST_INFO, }, { "NDMP3_CONFIG_GET_CONNECTION_TYPE", NDMP3_CONFIG_GET_CONNECTION_TYPE, }, { "NDMP3_CONFIG_GET_AUTH_ATTR", NDMP3_CONFIG_GET_AUTH_ATTR, }, { "NDMP3_CONFIG_GET_BUTYPE_INFO", NDMP3_CONFIG_GET_BUTYPE_INFO, }, { "NDMP3_CONFIG_GET_FS_INFO", NDMP3_CONFIG_GET_FS_INFO, }, { "NDMP3_CONFIG_GET_TAPE_INFO", NDMP3_CONFIG_GET_TAPE_INFO, }, { "NDMP3_CONFIG_GET_SCSI_INFO", NDMP3_CONFIG_GET_SCSI_INFO, }, { "NDMP3_CONFIG_GET_SERVER_INFO",NDMP3_CONFIG_GET_SERVER_INFO, }, { "NDMP3_SCSI_OPEN", NDMP3_SCSI_OPEN, }, { "NDMP3_SCSI_CLOSE", NDMP3_SCSI_CLOSE, }, { "NDMP3_SCSI_GET_STATE", NDMP3_SCSI_GET_STATE, }, { "NDMP3_SCSI_SET_TARGET", NDMP3_SCSI_SET_TARGET, }, { "NDMP3_SCSI_RESET_DEVICE", NDMP3_SCSI_RESET_DEVICE, }, { "NDMP3_SCSI_RESET_BUS", NDMP3_SCSI_RESET_BUS, }, { "NDMP3_SCSI_EXECUTE_CDB", NDMP3_SCSI_EXECUTE_CDB, }, { "NDMP3_TAPE_OPEN", NDMP3_TAPE_OPEN, }, { "NDMP3_TAPE_CLOSE", NDMP3_TAPE_CLOSE, }, { "NDMP3_TAPE_GET_STATE", NDMP3_TAPE_GET_STATE, }, { "NDMP3_TAPE_MTIO", NDMP3_TAPE_MTIO, }, { "NDMP3_TAPE_WRITE", NDMP3_TAPE_WRITE, }, { "NDMP3_TAPE_READ", NDMP3_TAPE_READ, }, { "NDMP3_TAPE_EXECUTE_CDB", NDMP3_TAPE_EXECUTE_CDB, }, { "NDMP3_DATA_GET_STATE", NDMP3_DATA_GET_STATE, }, { "NDMP3_DATA_START_BACKUP", NDMP3_DATA_START_BACKUP, }, { "NDMP3_DATA_START_RECOVER", NDMP3_DATA_START_RECOVER, }, { "NDMP3_DATA_START_RECOVER_FILEHIST", NDMP3_DATA_START_RECOVER_FILEHIST, }, { "NDMP3_DATA_ABORT", NDMP3_DATA_ABORT, }, { "NDMP3_DATA_GET_ENV", NDMP3_DATA_GET_ENV, }, { "NDMP3_DATA_STOP", NDMP3_DATA_STOP, }, { "NDMP3_DATA_LISTEN", NDMP3_DATA_LISTEN, }, { "NDMP3_DATA_CONNECT", NDMP3_DATA_CONNECT, }, { "NDMP3_NOTIFY_DATA_HALTED", NDMP3_NOTIFY_DATA_HALTED, }, { "NDMP3_NOTIFY_CONNECTED", NDMP3_NOTIFY_CONNECTED, }, { "NDMP3_NOTIFY_MOVER_HALTED", NDMP3_NOTIFY_MOVER_HALTED, }, { "NDMP3_NOTIFY_MOVER_PAUSED", NDMP3_NOTIFY_MOVER_PAUSED, }, { "NDMP3_NOTIFY_DATA_READ", NDMP3_NOTIFY_DATA_READ, }, { "NDMP3_LOG_FILE", NDMP3_LOG_FILE, }, { "NDMP3_LOG_MESSAGE", NDMP3_LOG_MESSAGE, }, { "NDMP3_FH_ADD_FILE", NDMP3_FH_ADD_FILE, }, { "NDMP3_FH_ADD_DIR", NDMP3_FH_ADD_DIR, }, { "NDMP3_FH_ADD_NODE", NDMP3_FH_ADD_NODE, }, { "NDMP3_MOVER_GET_STATE", NDMP3_MOVER_GET_STATE, }, { "NDMP3_MOVER_LISTEN", NDMP3_MOVER_LISTEN, }, { "NDMP3_MOVER_CONTINUE", NDMP3_MOVER_CONTINUE, }, { "NDMP3_MOVER_ABORT", NDMP3_MOVER_ABORT, }, { "NDMP3_MOVER_STOP", NDMP3_MOVER_STOP, }, { "NDMP3_MOVER_SET_WINDOW", NDMP3_MOVER_SET_WINDOW, }, { "NDMP3_MOVER_READ", NDMP3_MOVER_READ, }, { "NDMP3_MOVER_CLOSE", NDMP3_MOVER_CLOSE, }, { "NDMP3_MOVER_SET_RECORD_SIZE", NDMP3_MOVER_SET_RECORD_SIZE, }, { "NDMP3_MOVER_CONNECT", NDMP3_MOVER_CONNECT, }, { "NDMP3_VENDORS_BASE", NDMP3_VENDORS_BASE, }, { "NDMP3_RESERVED_BASE", NDMP3_RESERVED_BASE, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_auth_type_table[]; extern char * ndmp3_auth_type_to_str (ndmp3_auth_type val); extern int ndmp3_auth_type_from_str (ndmp3_auth_type *valp, char *str); char * ndmp3_auth_type_to_str (ndmp3_auth_type val) { return ndmp_enum_to_str ((int)val, ndmp3_auth_type_table); } int ndmp3_auth_type_from_str (ndmp3_auth_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_auth_type_table); } struct ndmp_enum_str_table ndmp3_auth_type_table[] = { { "NDMP3_AUTH_NONE", NDMP3_AUTH_NONE, }, { "NDMP3_AUTH_TEXT", NDMP3_AUTH_TEXT, }, { "NDMP3_AUTH_MD5", NDMP3_AUTH_MD5, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_addr_type_table[]; extern char * ndmp3_addr_type_to_str (ndmp3_addr_type val); extern int ndmp3_addr_type_from_str (ndmp3_addr_type *valp, char *str); char * ndmp3_addr_type_to_str (ndmp3_addr_type val) { return ndmp_enum_to_str ((int)val, ndmp3_addr_type_table); } int ndmp3_addr_type_from_str (ndmp3_addr_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_addr_type_table); } struct ndmp_enum_str_table ndmp3_addr_type_table[] = { { "NDMP3_ADDR_LOCAL", NDMP3_ADDR_LOCAL, }, { "NDMP3_ADDR_TCP", NDMP3_ADDR_TCP, }, { "NDMP3_ADDR_FC", NDMP3_ADDR_FC, }, { "NDMP3_ADDR_IPC", NDMP3_ADDR_IPC, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_tape_open_mode_table[]; extern char * ndmp3_tape_open_mode_to_str (ndmp3_tape_open_mode val); extern int ndmp3_tape_open_mode_from_str (ndmp3_tape_open_mode *valp, char *str); char * ndmp3_tape_open_mode_to_str (ndmp3_tape_open_mode val) { return ndmp_enum_to_str ((int)val, ndmp3_tape_open_mode_table); } int ndmp3_tape_open_mode_from_str (ndmp3_tape_open_mode *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_tape_open_mode_table); } struct ndmp_enum_str_table ndmp3_tape_open_mode_table[] = { { "NDMP3_TAPE_READ_MODE", NDMP3_TAPE_READ_MODE, }, { "NDMP3_TAPE_RDWR_MODE", NDMP3_TAPE_RDWR_MODE, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_tape_mtio_op_table[]; extern char * ndmp3_tape_mtio_op_to_str (ndmp3_tape_mtio_op val); extern int ndmp3_tape_mtio_op_from_str (ndmp3_tape_mtio_op *valp, char *str); char * ndmp3_tape_mtio_op_to_str (ndmp3_tape_mtio_op val) { return ndmp_enum_to_str ((int)val, ndmp3_tape_mtio_op_table); } int ndmp3_tape_mtio_op_from_str (ndmp3_tape_mtio_op *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_tape_mtio_op_table); } struct ndmp_enum_str_table ndmp3_tape_mtio_op_table[] = { { "NDMP3_MTIO_FSF", NDMP3_MTIO_FSF, }, { "NDMP3_MTIO_BSF", NDMP3_MTIO_BSF, }, { "NDMP3_MTIO_FSR", NDMP3_MTIO_FSR, }, { "NDMP3_MTIO_BSR", NDMP3_MTIO_BSR, }, { "NDMP3_MTIO_REW", NDMP3_MTIO_REW, }, { "NDMP3_MTIO_EOF", NDMP3_MTIO_EOF, }, { "NDMP3_MTIO_OFF", NDMP3_MTIO_OFF, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_mover_state_table[]; extern char * ndmp3_mover_state_to_str (ndmp3_mover_state val); extern int ndmp3_mover_state_from_str (ndmp3_mover_state *valp, char *str); char * ndmp3_mover_state_to_str (ndmp3_mover_state val) { return ndmp_enum_to_str ((int)val, ndmp3_mover_state_table); } int ndmp3_mover_state_from_str (ndmp3_mover_state *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_mover_state_table); } struct ndmp_enum_str_table ndmp3_mover_state_table[] = { { "NDMP3_MOVER_STATE_IDLE", NDMP3_MOVER_STATE_IDLE, }, { "NDMP3_MOVER_STATE_LISTEN", NDMP3_MOVER_STATE_LISTEN, }, { "NDMP3_MOVER_STATE_ACTIVE", NDMP3_MOVER_STATE_ACTIVE, }, { "NDMP3_MOVER_STATE_PAUSED", NDMP3_MOVER_STATE_PAUSED, }, { "NDMP3_MOVER_STATE_HALTED", NDMP3_MOVER_STATE_HALTED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_mover_pause_reason_table[]; extern char * ndmp3_mover_pause_reason_to_str (ndmp3_mover_pause_reason val); extern int ndmp3_mover_pause_reason_from_str (ndmp3_mover_pause_reason *valp, char *str); char * ndmp3_mover_pause_reason_to_str (ndmp3_mover_pause_reason val) { return ndmp_enum_to_str ((int)val, ndmp3_mover_pause_reason_table); } int ndmp3_mover_pause_reason_from_str (ndmp3_mover_pause_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_mover_pause_reason_table); } struct ndmp_enum_str_table ndmp3_mover_pause_reason_table[] = { { "NDMP3_MOVER_PAUSE_NA", NDMP3_MOVER_PAUSE_NA, }, { "NDMP3_MOVER_PAUSE_EOM", NDMP3_MOVER_PAUSE_EOM, }, { "NDMP3_MOVER_PAUSE_EOF", NDMP3_MOVER_PAUSE_EOF, }, { "NDMP3_MOVER_PAUSE_SEEK", NDMP3_MOVER_PAUSE_SEEK, }, { "NDMP3_MOVER_PAUSE_MEDIA_ERROR", NDMP3_MOVER_PAUSE_MEDIA_ERROR, }, { "NDMP3_MOVER_PAUSE_EOW", NDMP3_MOVER_PAUSE_EOW, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_mover_halt_reason_table[]; extern char * ndmp3_mover_halt_reason_to_str (ndmp3_mover_halt_reason val); extern int ndmp3_mover_halt_reason_from_str (ndmp3_mover_halt_reason *valp, char *str); char * ndmp3_mover_halt_reason_to_str (ndmp3_mover_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp3_mover_halt_reason_table); } int ndmp3_mover_halt_reason_from_str (ndmp3_mover_halt_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_mover_halt_reason_table); } struct ndmp_enum_str_table ndmp3_mover_halt_reason_table[] = { { "NDMP3_MOVER_HALT_NA", NDMP3_MOVER_HALT_NA, }, { "NDMP3_MOVER_HALT_CONNECT_CLOSED", NDMP3_MOVER_HALT_CONNECT_CLOSED, }, { "NDMP3_MOVER_HALT_ABORTED", NDMP3_MOVER_HALT_ABORTED, }, { "NDMP3_MOVER_HALT_INTERNAL_ERROR", NDMP3_MOVER_HALT_INTERNAL_ERROR, }, { "NDMP3_MOVER_HALT_CONNECT_ERROR", NDMP3_MOVER_HALT_CONNECT_ERROR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_mover_mode_table[]; extern char * ndmp3_mover_mode_to_str (ndmp3_mover_mode val); extern int ndmp3_mover_mode_from_str (ndmp3_mover_mode *valp, char *str); char * ndmp3_mover_mode_to_str (ndmp3_mover_mode val) { return ndmp_enum_to_str ((int)val, ndmp3_mover_mode_table); } int ndmp3_mover_mode_from_str (ndmp3_mover_mode *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_mover_mode_table); } struct ndmp_enum_str_table ndmp3_mover_mode_table[] = { { "NDMP3_MOVER_MODE_READ", NDMP3_MOVER_MODE_READ, }, { "NDMP3_MOVER_MODE_WRITE", NDMP3_MOVER_MODE_WRITE, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_data_operation_table[]; extern char * ndmp3_data_operation_to_str (ndmp3_data_operation val); extern int ndmp3_data_operation_from_str (ndmp3_data_operation *valp, char *str); char * ndmp3_data_operation_to_str (ndmp3_data_operation val) { return ndmp_enum_to_str ((int)val, ndmp3_data_operation_table); } int ndmp3_data_operation_from_str (ndmp3_data_operation *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_data_operation_table); } struct ndmp_enum_str_table ndmp3_data_operation_table[] = { { "NDMP3_DATA_OP_NOACTION", NDMP3_DATA_OP_NOACTION, }, { "NDMP3_DATA_OP_BACKUP", NDMP3_DATA_OP_BACKUP, }, { "NDMP3_DATA_OP_RESTORE", NDMP3_DATA_OP_RESTORE, }, { "NDMP3_DATA_OP_RESTORE_FILEHIST", NDMP3_DATA_OP_RESTORE_FILEHIST, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_data_state_table[]; extern char * ndmp3_data_state_to_str (ndmp3_data_state val); extern int ndmp3_data_state_from_str (ndmp3_data_state *valp, char *str); char * ndmp3_data_state_to_str (ndmp3_data_state val) { return ndmp_enum_to_str ((int)val, ndmp3_data_state_table); } int ndmp3_data_state_from_str (ndmp3_data_state *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_data_state_table); } struct ndmp_enum_str_table ndmp3_data_state_table[] = { { "NDMP3_DATA_STATE_IDLE", NDMP3_DATA_STATE_IDLE, }, { "NDMP3_DATA_STATE_ACTIVE", NDMP3_DATA_STATE_ACTIVE, }, { "NDMP3_DATA_STATE_HALTED", NDMP3_DATA_STATE_HALTED, }, { "NDMP3_DATA_STATE_LISTEN", NDMP3_DATA_STATE_LISTEN, }, { "NDMP3_DATA_STATE_CONNECTED", NDMP3_DATA_STATE_CONNECTED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_data_halt_reason_table[]; extern char * ndmp3_data_halt_reason_to_str (ndmp3_data_halt_reason val); extern int ndmp3_data_halt_reason_from_str (ndmp3_data_halt_reason *valp, char *str); char * ndmp3_data_halt_reason_to_str (ndmp3_data_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp3_data_halt_reason_table); } int ndmp3_data_halt_reason_from_str (ndmp3_data_halt_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_data_halt_reason_table); } struct ndmp_enum_str_table ndmp3_data_halt_reason_table[] = { { "NDMP3_DATA_HALT_NA", NDMP3_DATA_HALT_NA, }, { "NDMP3_DATA_HALT_SUCCESSFUL", NDMP3_DATA_HALT_SUCCESSFUL, }, { "NDMP3_DATA_HALT_ABORTED", NDMP3_DATA_HALT_ABORTED, }, { "NDMP3_DATA_HALT_INTERNAL_ERROR", NDMP3_DATA_HALT_INTERNAL_ERROR, }, { "NDMP3_DATA_HALT_CONNECT_ERROR", NDMP3_DATA_HALT_CONNECT_ERROR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_connect_reason_table[]; extern char * ndmp3_connect_reason_to_str (ndmp3_connect_reason val); extern int ndmp3_connect_reason_from_str (ndmp3_connect_reason *valp, char *str); char * ndmp3_connect_reason_to_str (ndmp3_connect_reason val) { return ndmp_enum_to_str ((int)val, ndmp3_connect_reason_table); } int ndmp3_connect_reason_from_str (ndmp3_connect_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_connect_reason_table); } struct ndmp_enum_str_table ndmp3_connect_reason_table[] = { { "NDMP3_CONNECTED", NDMP3_CONNECTED, }, { "NDMP3_SHUTDOWN", NDMP3_SHUTDOWN, }, { "NDMP3_REFUSED", NDMP3_REFUSED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_log_type_table[]; extern char * ndmp3_log_type_to_str (ndmp3_log_type val); extern int ndmp3_log_type_from_str (ndmp3_log_type *valp, char *str); char * ndmp3_log_type_to_str (ndmp3_log_type val) { return ndmp_enum_to_str ((int)val, ndmp3_log_type_table); } int ndmp3_log_type_from_str (ndmp3_log_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_log_type_table); } struct ndmp_enum_str_table ndmp3_log_type_table[] = { { "NDMP3_LOG_NORMAL", NDMP3_LOG_NORMAL, }, { "NDMP3_LOG_DEBUG", NDMP3_LOG_DEBUG, }, { "NDMP3_LOG_ERROR", NDMP3_LOG_ERROR, }, { "NDMP3_LOG_WARNING", NDMP3_LOG_WARNING, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_fs_type_table[]; extern char * ndmp3_fs_type_to_str (ndmp3_fs_type val); extern int ndmp3_fs_type_from_str (ndmp3_fs_type *valp, char *str); char * ndmp3_fs_type_to_str (ndmp3_fs_type val) { return ndmp_enum_to_str ((int)val, ndmp3_fs_type_table); } int ndmp3_fs_type_from_str (ndmp3_fs_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_fs_type_table); } struct ndmp_enum_str_table ndmp3_fs_type_table[] = { { "NDMP3_FS_UNIX", NDMP3_FS_UNIX, }, { "NDMP3_FS_NT", NDMP3_FS_NT, }, { "NDMP3_FS_OTHER", NDMP3_FS_OTHER, }, { 0 } }; extern struct ndmp_enum_str_table ndmp3_file_type_table[]; extern char * ndmp3_file_type_to_str (ndmp3_file_type val); extern int ndmp3_file_type_from_str (ndmp3_file_type *valp, char *str); char * ndmp3_file_type_to_str (ndmp3_file_type val) { return ndmp_enum_to_str ((int)val, ndmp3_file_type_table); } int ndmp3_file_type_from_str (ndmp3_file_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp3_file_type_table); } struct ndmp_enum_str_table ndmp3_file_type_table[] = { { "NDMP3_FILE_DIR", NDMP3_FILE_DIR, }, { "NDMP3_FILE_FIFO", NDMP3_FILE_FIFO, }, { "NDMP3_FILE_CSPEC", NDMP3_FILE_CSPEC, }, { "NDMP3_FILE_BSPEC", NDMP3_FILE_BSPEC, }, { "NDMP3_FILE_REG", NDMP3_FILE_REG, }, { "NDMP3_FILE_SLINK", NDMP3_FILE_SLINK, }, { "NDMP3_FILE_SOCK", NDMP3_FILE_SOCK, }, { "NDMP3_FILE_REGISTRY", NDMP3_FILE_REGISTRY, }, { "NDMP3_FILE_OTHER", NDMP3_FILE_OTHER, }, { 0 } }; #endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp3_enum_strs.h000066400000000000000000000122111263011562700214530ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_NDMP3 extern struct ndmp_enum_str_table ndmp3_error_table[]; extern char * ndmp3_error_to_str (ndmp3_error val); extern int ndmp3_error_from_str (ndmp3_error *valp, char *str); extern struct ndmp_enum_str_table ndmp3_header_message_type_table[]; extern char * ndmp3_header_message_type_to_str (ndmp3_header_message_type val); extern int ndmp3_header_message_type_from_str (ndmp3_header_message_type *valp, char *str); extern struct ndmp_enum_str_table ndmp3_message_table[]; extern char * ndmp3_message_to_str (ndmp3_message val); extern int ndmp3_message_from_str (ndmp3_message *valp, char *str); extern struct ndmp_enum_str_table ndmp3_auth_type_table[]; extern char * ndmp3_auth_type_to_str (ndmp3_auth_type val); extern int ndmp3_auth_type_from_str (ndmp3_auth_type *valp, char *str); extern struct ndmp_enum_str_table ndmp3_addr_type_table[]; extern char * ndmp3_addr_type_to_str (ndmp3_addr_type val); extern int ndmp3_addr_type_from_str (ndmp3_addr_type *valp, char *str); extern struct ndmp_enum_str_table ndmp3_tape_open_mode_table[]; extern char * ndmp3_tape_open_mode_to_str (ndmp3_tape_open_mode val); extern int ndmp3_tape_open_mode_from_str (ndmp3_tape_open_mode *valp, char *str); extern struct ndmp_enum_str_table ndmp3_tape_mtio_op_table[]; extern char * ndmp3_tape_mtio_op_to_str (ndmp3_tape_mtio_op val); extern int ndmp3_tape_mtio_op_from_str (ndmp3_tape_mtio_op *valp, char *str); extern struct ndmp_enum_str_table ndmp3_mover_state_table[]; extern char * ndmp3_mover_state_to_str (ndmp3_mover_state val); extern int ndmp3_mover_state_from_str (ndmp3_mover_state *valp, char *str); extern struct ndmp_enum_str_table ndmp3_mover_pause_reason_table[]; extern char * ndmp3_mover_pause_reason_to_str (ndmp3_mover_pause_reason val); extern int ndmp3_mover_pause_reason_from_str (ndmp3_mover_pause_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp3_mover_halt_reason_table[]; extern char * ndmp3_mover_halt_reason_to_str (ndmp3_mover_halt_reason val); extern int ndmp3_mover_halt_reason_from_str (ndmp3_mover_halt_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp3_mover_mode_table[]; extern char * ndmp3_mover_mode_to_str (ndmp3_mover_mode val); extern int ndmp3_mover_mode_from_str (ndmp3_mover_mode *valp, char *str); extern struct ndmp_enum_str_table ndmp3_data_operation_table[]; extern char * ndmp3_data_operation_to_str (ndmp3_data_operation val); extern int ndmp3_data_operation_from_str (ndmp3_data_operation *valp, char *str); extern struct ndmp_enum_str_table ndmp3_data_state_table[]; extern char * ndmp3_data_state_to_str (ndmp3_data_state val); extern int ndmp3_data_state_from_str (ndmp3_data_state *valp, char *str); extern struct ndmp_enum_str_table ndmp3_data_halt_reason_table[]; extern char * ndmp3_data_halt_reason_to_str (ndmp3_data_halt_reason val); extern int ndmp3_data_halt_reason_from_str (ndmp3_data_halt_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp3_connect_reason_table[]; extern char * ndmp3_connect_reason_to_str (ndmp3_connect_reason val); extern int ndmp3_connect_reason_from_str (ndmp3_connect_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp3_log_type_table[]; extern char * ndmp3_log_type_to_str (ndmp3_log_type val); extern int ndmp3_log_type_from_str (ndmp3_log_type *valp, char *str); extern struct ndmp_enum_str_table ndmp3_fs_type_table[]; extern char * ndmp3_fs_type_to_str (ndmp3_fs_type val); extern int ndmp3_fs_type_from_str (ndmp3_fs_type *valp, char *str); extern struct ndmp_enum_str_table ndmp3_file_type_table[]; extern char * ndmp3_file_type_to_str (ndmp3_file_type val); extern int ndmp3_file_type_from_str (ndmp3_file_type *valp, char *str); #endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp3_pp.c000066400000000000000000000563321263011562700200620ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP3 int ndmp3_pp_header (void *data, char *buf) { ndmp3_header * mh = (ndmp3_header *) data; if (mh->message_type == NDMP3_MESSAGE_REQUEST) { sprintf (buf, "C %s %lu", ndmp3_message_to_str (mh->message), mh->sequence); } else if (mh->message_type == NDMP3_MESSAGE_REPLY) { sprintf (buf, "R %s %lu (%lu)", ndmp3_message_to_str (mh->message), mh->reply_sequence, mh->sequence); if (mh->error != NDMP3_NO_ERR) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp3_error_to_str (mh->error)); return 0; /* no body */ } } else { strcpy (buf, "??? INVALID MESSAGE TYPE"); return -1; /* no body */ } return 1; /* body */ } int ndmp3_pp_addr (char *buf, ndmp3_addr *ma) { sprintf (buf, "%s", ndmp3_addr_type_to_str (ma->addr_type)); if (ma->addr_type == NDMP3_ADDR_TCP) { sprintf (NDMOS_API_STREND(buf), "(%lx,%d)", ma->ndmp3_addr_u.tcp_addr.ip_addr, ma->ndmp3_addr_u.tcp_addr.port); } return 0; } int ndmp3_pp_request (ndmp3_message msg, void *data, int lineno, char *buf) { int i; unsigned int j; switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP3_CONNECT_OPEN: NDMP_PP_WITH(ndmp3_connect_open_request) sprintf (buf, "version=%d", p->protocol_version); NDMP_PP_ENDWITH break; case NDMP3_CONNECT_CLIENT_AUTH: NDMP_PP_WITH(ndmp3_connect_client_auth_request) sprintf (buf, "auth_type=%s", ndmp3_auth_type_to_str (p->auth_data.auth_type)); sprintf (buf, "auth_type=%s", ndmp3_auth_type_to_str (p->auth_data.auth_type)); switch (p->auth_data.auth_type) { case NDMP3_AUTH_NONE: break; case NDMP3_AUTH_TEXT: sprintf (NDMOS_API_STREND(buf), " auth_id=%s", p->auth_data.ndmp3_auth_data_u.auth_text.auth_id); break; case NDMP3_AUTH_MD5: sprintf (NDMOS_API_STREND(buf), " auth_id=%s", p->auth_data.ndmp3_auth_data_u.auth_md5.auth_id); break; default: sprintf (NDMOS_API_STREND(buf), " ????"); break; } NDMP_PP_ENDWITH break; case NDMP3_CONNECT_CLOSE: case NDMP3_CONFIG_GET_HOST_INFO: case NDMP3_CONFIG_GET_CONNECTION_TYPE: case NDMP3_CONFIG_GET_SERVER_INFO: case NDMP3_CONFIG_GET_BUTYPE_INFO: case NDMP3_CONFIG_GET_FS_INFO: case NDMP3_CONFIG_GET_TAPE_INFO: case NDMP3_CONFIG_GET_SCSI_INFO: case NDMP3_SCSI_CLOSE: case NDMP3_SCSI_GET_STATE: case NDMP3_SCSI_RESET_DEVICE: case NDMP3_SCSI_RESET_BUS: case NDMP3_TAPE_GET_STATE: case NDMP3_TAPE_CLOSE: case NDMP3_MOVER_GET_STATE: case NDMP3_MOVER_CONTINUE: case NDMP3_MOVER_ABORT: case NDMP3_MOVER_STOP: case NDMP3_MOVER_CLOSE: case NDMP3_DATA_GET_STATE: case NDMP3_DATA_ABORT: case NDMP3_DATA_STOP: case NDMP3_DATA_GET_ENV: *buf = 0; /* no body */ return 0; case NDMP3_CONNECT_SERVER_AUTH: strcpy (buf, "<>"); break; case NDMP3_CONFIG_GET_AUTH_ATTR: NDMP_PP_WITH(ndmp3_config_get_auth_attr_request) sprintf (buf, "auth_type=%s", ndmp3_auth_type_to_str (p->auth_type)); NDMP_PP_ENDWITH break; case NDMP3_SCSI_OPEN: NDMP_PP_WITH(ndmp3_scsi_open_request) sprintf (buf, "device='%s'", p->device); NDMP_PP_ENDWITH break; case NDMP3_SCSI_SET_TARGET: NDMP_PP_WITH(ndmp3_scsi_set_target_request) sprintf (buf, "device='%s' cont=%d sid=%d lun=%d", p->device, p->target_controller, p->target_id, p->target_lun); NDMP_PP_ENDWITH break; case NDMP3_SCSI_EXECUTE_CDB: case NDMP3_TAPE_EXECUTE_CDB: NDMP_PP_WITH(ndmp3_execute_cdb_request) switch (lineno) { case 0: sprintf (buf, "flags=0x%lx timeout=%ld datain_len=%ld", p->flags, p->timeout, p->datain_len); break; case 1: sprintf (buf, "cmd[%d]={", p->cdb.cdb_len); for (j = 0; j < p->cdb.cdb_len; j++) { sprintf (NDMOS_API_STREND(buf), " %02x", p->cdb.cdb_val[j]&0xFF); } strcat (buf, " }"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP3_TAPE_OPEN: NDMP_PP_WITH(ndmp3_tape_open_request) sprintf (buf, "device='%s' mode=%s", p->device, ndmp3_tape_open_mode_to_str (p->mode)); NDMP_PP_ENDWITH break; case NDMP3_TAPE_MTIO: NDMP_PP_WITH(ndmp3_tape_mtio_request) sprintf (buf, "op=%s count=%ld", ndmp3_tape_mtio_op_to_str(p->tape_op), p->count); NDMP_PP_ENDWITH break; case NDMP3_TAPE_WRITE: NDMP_PP_WITH(ndmp3_tape_write_request) sprintf (buf, "data_out_len=%d", p->data_out.data_out_len); NDMP_PP_ENDWITH break; case NDMP3_TAPE_READ: NDMP_PP_WITH(ndmp3_tape_read_request) sprintf (buf, "count=%ld", p->count); NDMP_PP_ENDWITH break; case NDMP3_DATA_START_BACKUP: NDMP_PP_WITH(ndmp3_data_start_backup_request) if (lineno == 0) { sprintf (buf, "bu_type='%s' n_env=%d", p->bu_type, p->env.env_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "env[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { strcpy (buf, "--INVALID--"); } } return 1 + p->env.env_len; NDMP_PP_ENDWITH break; case NDMP3_DATA_START_RECOVER: case NDMP3_DATA_START_RECOVER_FILEHIST: NDMP_PP_WITH(ndmp3_data_start_recover_request) if (lineno == 0) { sprintf (buf, "bu_type='%s' n_env=%d n_nlist=%d", p->bu_type, p->env.env_len, p->nlist.nlist_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "env[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { i -= p->env.env_len; if (0 <= i && (unsigned)i < p->nlist.nlist_len*4) { ndmp3_name *nm = &p->nlist.nlist_val[i/4]; switch (i%4) { case 0: sprintf (buf, "nl[%d] original_path='%s'", i/4, nm->original_path); break; case 1: sprintf (buf, "..... destination_dir='%s'", nm->destination_dir); break; case 2: sprintf (buf, "..... new_name='%s' other='%s'", nm->new_name, nm->other_name); break; case 3: sprintf (buf, "..... node=%lld fh_info=%lld", nm->node, nm->fh_info); break; } } else { strcpy (buf, "--INVALID--"); } } } return 1 + p->env.env_len + p->nlist.nlist_len*4; NDMP_PP_ENDWITH break; case NDMP3_DATA_LISTEN: NDMP_PP_WITH(ndmp3_data_listen_request) sprintf (buf, "addr_type=%s", ndmp3_addr_type_to_str (p->addr_type)); NDMP_PP_ENDWITH break; case NDMP3_DATA_CONNECT: NDMP_PP_WITH(ndmp3_data_connect_request) sprintf (buf, "addr="); ndmp3_pp_addr (NDMOS_API_STREND(buf), &p->addr); NDMP_PP_ENDWITH break; case NDMP3_NOTIFY_DATA_HALTED: NDMP_PP_WITH(ndmp3_notify_data_halted_request) sprintf (buf, "reason=%s text_reason='%s'", ndmp3_data_halt_reason_to_str(p->reason), p->text_reason); NDMP_PP_ENDWITH break; case NDMP3_NOTIFY_CONNECTED: NDMP_PP_WITH(ndmp3_notify_connected_request) sprintf (buf, "reason=%s protocol_version=%d text_reason='%s'", ndmp3_connect_reason_to_str(p->reason), p->protocol_version, p->text_reason); NDMP_PP_ENDWITH break; case NDMP3_NOTIFY_MOVER_HALTED: NDMP_PP_WITH(ndmp3_notify_mover_halted_request) sprintf (buf, "reason=%s text_reason='%s'", ndmp3_mover_halt_reason_to_str(p->reason), p->text_reason); NDMP_PP_ENDWITH break; case NDMP3_NOTIFY_MOVER_PAUSED: NDMP_PP_WITH(ndmp3_notify_mover_paused_request) sprintf (buf, "reason=%s seek_position=%lld", ndmp3_mover_pause_reason_to_str(p->reason), p->seek_position); NDMP_PP_ENDWITH break; case NDMP3_NOTIFY_DATA_READ: NDMP_PP_WITH(ndmp3_notify_data_read_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP3_LOG_FILE: NDMP_PP_WITH(ndmp3_log_file_request) sprintf (buf, "file=%s error=%s", p->name, ndmp3_error_to_str(p->error)); NDMP_PP_ENDWITH break; case NDMP3_LOG_MESSAGE: NDMP_PP_WITH(ndmp3_log_message_request) sprintf (buf, "log_type=%s id=%lu message='%s'", ndmp3_log_type_to_str(p->log_type), p->message_id, p->entry); NDMP_PP_ENDWITH break; case NDMP3_FH_ADD_FILE: NDMP_PP_WITH(ndmp3_fh_add_file_request) int n_line = 0, n_names = 0, n_stats = 0; unsigned int n_normal = 0; n_line++; for (j = 0; j < p->files.files_len; j++) { int nn, ns; nn = p->files.files_val[j].names.names_len; ns = p->files.files_val[j].stats.stats_len; n_line += 1 + nn + ns; if (nn == 1 && ns == 1) n_normal++; n_names += nn; n_stats += ns; } if (n_normal == p->files.files_len) { /* could do something more efficient here */ } if (lineno == 0) { sprintf (buf, "n_files=%d total n_names=%d n_stats=%d", p->files.files_len, n_names, n_stats); return n_line; } lineno--; for (j = 0; j < p->files.files_len; j++) { ndmp3_file * file = &p->files.files_val[j]; unsigned int k; if (lineno == 0) { sprintf (buf, "[%d] n_names=%d n_stats=%d node=%lld fhinfo=%lld", j, file->names.names_len, file->stats.stats_len, file->node, file->fh_info); return n_line; } lineno--; for (k = 0; k < file->names.names_len; k++, lineno--) { ndmp3_file_name *filename; if (lineno != 0) continue; filename = &file->names.names_val[k]; sprintf (buf, " name[%d] fs_type=%s", k, ndmp3_fs_type_to_str (filename->fs_type)); switch (filename->fs_type) { default: sprintf (NDMOS_API_STREND(buf), " other=%s", filename->ndmp3_file_name_u.other_name); break; case NDMP3_FS_UNIX: sprintf (NDMOS_API_STREND(buf), " unix=%s", filename->ndmp3_file_name_u.unix_name); break; case NDMP3_FS_NT: sprintf (NDMOS_API_STREND(buf)," nt=%s dos=%s", filename->ndmp3_file_name_u.nt_name.nt_path, filename->ndmp3_file_name_u.nt_name.dos_path); break; } return n_line; } for (k = 0; k < file->stats.stats_len; k++, lineno--) { ndmp3_file_stat *filestat; if (lineno != 0) continue; filestat = &file->stats.stats_val[k]; sprintf (buf, " stat[%ud] fs_type=%s ftype=%s size=%lld", k, ndmp3_fs_type_to_str (filestat->fs_type), ndmp3_file_type_to_str (filestat->ftype), filestat->size); return n_line; } } sprintf (buf, " YIKES n_line=%d lineno=%d", n_line, lineno); return -1; NDMP_PP_ENDWITH break; case NDMP3_FH_ADD_DIR: NDMP_PP_WITH(ndmp3_fh_add_dir_request) int n_line = 0, n_names = 0; unsigned int n_normal = 0; n_line++; for (j = 0; j < p->dirs.dirs_len; j++) { int nn; nn = p->dirs.dirs_val[j].names.names_len; n_line += 1 + nn; if (nn == 1) n_normal++; n_names += nn; } if (n_normal == p->dirs.dirs_len) { /* could do something more efficient here */ } if (lineno == 0) { sprintf (buf, "n_dirs=%d total n_names=%d", p->dirs.dirs_len, n_names); return n_line; } lineno--; for (j = 0; j < p->dirs.dirs_len; j++) { ndmp3_dir * dir = &p->dirs.dirs_val[j]; unsigned int k; if (lineno == 0) { sprintf (buf, "[%ud] n_names=%d node=%lld parent=%lld", j, dir->names.names_len, dir->node, dir->parent); return n_line; } lineno--; for (k = 0; k < dir->names.names_len; k++, lineno--) { ndmp3_file_name *filename; if (lineno != 0) continue; filename = &dir->names.names_val[k]; sprintf (buf, " name[%ud] fs_type=%s", k, ndmp3_fs_type_to_str (filename->fs_type)); switch (filename->fs_type) { default: sprintf (NDMOS_API_STREND(buf), " other=%s", filename->ndmp3_file_name_u.other_name); break; case NDMP3_FS_UNIX: sprintf (NDMOS_API_STREND(buf), " unix=%s", filename->ndmp3_file_name_u.unix_name); break; case NDMP3_FS_NT: sprintf (NDMOS_API_STREND(buf)," nt=%s dos=%s", filename->ndmp3_file_name_u.nt_name.nt_path, filename->ndmp3_file_name_u.nt_name.dos_path); break; } return n_line; } } sprintf (buf, " YIKES n_line=%d lineno=%d", n_line, lineno); return -1; NDMP_PP_ENDWITH break; case NDMP3_FH_ADD_NODE: NDMP_PP_WITH(ndmp3_fh_add_node_request) int n_line = 0, n_stats = 0; unsigned int n_normal = 0; n_line++; for (j = 0; j < p->nodes.nodes_len; j++) { int ns; ns = p->nodes.nodes_val[j].stats.stats_len; n_line += 1 + ns; if (ns == 1) n_normal++; n_stats += ns; } if (n_normal == p->nodes.nodes_len) { /* could do something more efficient here */ } if (lineno == 0) { sprintf (buf, "n_nodes=%d total n_stats=%d", p->nodes.nodes_len, n_stats); return n_line; } lineno--; for (j = 0; j < p->nodes.nodes_len; j++) { ndmp3_node * node = &p->nodes.nodes_val[j]; unsigned int k; if (lineno == 0) { sprintf (buf, "[%ud] n_stats=%d node=%lld fhinfo=%lld", j, node->stats.stats_len, node->node, node->fh_info); return n_line; } lineno--; for (k = 0; k < node->stats.stats_len; k++, lineno--) { ndmp3_file_stat *filestat; if (lineno != 0) continue; filestat = &node->stats.stats_val[k]; sprintf (buf, " stat[%ud] fs_type=%s ftype=%s size=%lld", k, ndmp3_fs_type_to_str (filestat->fs_type), ndmp3_file_type_to_str (filestat->ftype), filestat->size); return n_line; } } sprintf (buf, " YIKES n_line=%d lineno=%d", n_line, lineno); return -1; NDMP_PP_ENDWITH break; case NDMP3_MOVER_LISTEN: NDMP_PP_WITH(ndmp3_mover_listen_request) sprintf (buf, "mode=%s addr_type=%s", ndmp3_mover_mode_to_str (p->mode), ndmp3_addr_type_to_str (p->addr_type)); NDMP_PP_ENDWITH break; case NDMP3_MOVER_SET_WINDOW: NDMP_PP_WITH(ndmp3_mover_set_window_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP3_MOVER_READ: NDMP_PP_WITH(ndmp3_mover_read_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP3_MOVER_SET_RECORD_SIZE: NDMP_PP_WITH(ndmp3_mover_set_record_size_request) sprintf (buf, "len=%lu", p->len); NDMP_PP_ENDWITH break; case NDMP3_MOVER_CONNECT: NDMP_PP_WITH(ndmp3_mover_connect_request) sprintf (buf, "mode=%s addr=", ndmp3_mover_mode_to_str (p->mode)); ndmp3_pp_addr (NDMOS_API_STREND(buf), &p->addr); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } int ndmp3_pp_reply (ndmp3_message msg, void *data, int lineno, char *buf) { int i; unsigned int j; switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP3_CONNECT_OPEN: case NDMP3_CONNECT_CLIENT_AUTH: case NDMP3_SCSI_OPEN: case NDMP3_SCSI_CLOSE: case NDMP3_SCSI_SET_TARGET: case NDMP3_SCSI_RESET_DEVICE: case NDMP3_SCSI_RESET_BUS: case NDMP3_TAPE_OPEN: case NDMP3_TAPE_CLOSE: case NDMP3_MOVER_CONTINUE: case NDMP3_MOVER_ABORT: case NDMP3_MOVER_STOP: case NDMP3_MOVER_READ: case NDMP3_MOVER_SET_WINDOW: case NDMP3_MOVER_CLOSE: case NDMP3_MOVER_SET_RECORD_SIZE: case NDMP3_MOVER_CONNECT: case NDMP3_DATA_START_BACKUP: case NDMP3_DATA_START_RECOVER: case NDMP3_DATA_START_RECOVER_FILEHIST: case NDMP3_DATA_ABORT: case NDMP3_DATA_STOP: case NDMP3_DATA_CONNECT: NDMP_PP_WITH(ndmp3_error) sprintf (buf, "error=%s", ndmp3_error_to_str(*p)); NDMP_PP_ENDWITH break; case NDMP3_CONFIG_GET_CONNECTION_TYPE: NDMP_PP_WITH(ndmp3_config_get_connection_type_reply) sprintf (buf, "error=%s addr_types[%d]={", ndmp3_error_to_str(p->error), p->addr_types.addr_types_len); for (j = 0; j < p->addr_types.addr_types_len; j++) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp3_addr_type_to_str(p->addr_types.addr_types_val[j])); } strcat (buf, " }"); NDMP_PP_ENDWITH break; case NDMP3_CONFIG_GET_SERVER_INFO: case NDMP3_CONFIG_GET_BUTYPE_INFO: case NDMP3_CONFIG_GET_FS_INFO: case NDMP3_CONFIG_GET_TAPE_INFO: case NDMP3_CONFIG_GET_SCSI_INFO: strcpy (buf, "<>"); break; case NDMP3_CONNECT_CLOSE: *buf = 0; return 0; case NDMP3_CONNECT_SERVER_AUTH: strcpy (buf, "<>"); break; case NDMP3_CONFIG_GET_HOST_INFO: NDMP_PP_WITH(ndmp3_config_get_host_info_reply) switch (lineno) { case 0: sprintf (buf, "error=%s hostname=%s", ndmp3_error_to_str(p->error), p->hostname); break; case 1: sprintf (buf, "os_type=%s os_vers=%s hostid=%s", p->os_type, p->os_vers, p->hostid); break; default: strcpy (buf, "--INVALID--"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP3_CONFIG_GET_AUTH_ATTR: strcpy (buf, "<>"); break; case NDMP3_SCSI_GET_STATE: NDMP_PP_WITH(ndmp3_scsi_get_state_reply) sprintf (buf, "error=%s cont=%d sid=%d lun=%d", ndmp3_error_to_str(p->error), p->target_controller, p->target_id, p->target_lun); NDMP_PP_ENDWITH break; case NDMP3_SCSI_EXECUTE_CDB: case NDMP3_TAPE_EXECUTE_CDB: NDMP_PP_WITH(ndmp3_execute_cdb_reply) switch (lineno) { case 0: sprintf (buf, "error=%s status=%02x dataout_len=%ld datain_len=%d", ndmp3_error_to_str(p->error), p->status, p->dataout_len, p->datain.datain_len); break; case 1: sprintf (buf, "sense[%d]={", p->ext_sense.ext_sense_len); for (j = 0; j < p->ext_sense.ext_sense_len; j++) { sprintf (NDMOS_API_STREND(buf), " %02x", p->ext_sense.ext_sense_val[j]&0xFF); } strcat (buf, " }"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP3_TAPE_GET_STATE: NDMP_PP_WITH(ndmp3_tape_get_state_reply) switch (lineno) { case 0: sprintf (buf, "invalid=%lx error=%s flags=0x%lx file_num=%ld", p->invalid, ndmp3_error_to_str(p->error), p->flags, p->file_num); break; case 1: sprintf (buf, "soft_errors=%lu block_size=%lu blockno=%lu", p->soft_errors, p->block_size, p->blockno); break; case 2: sprintf (buf, "total_space=%lld space_remain=%lld partition=%lu", p->total_space, p->space_remain, p->partition); break; default: strcpy (buf, "--INVALID--"); break; } return 3; NDMP_PP_ENDWITH break; case NDMP3_TAPE_MTIO: NDMP_PP_WITH(ndmp3_tape_mtio_reply) sprintf (buf, "error=%s resid_count=%ld", ndmp3_error_to_str(p->error), p->resid_count); NDMP_PP_ENDWITH break; case NDMP3_TAPE_WRITE: NDMP_PP_WITH(ndmp3_tape_write_reply) sprintf (buf, "error=%s count=%ld", ndmp3_error_to_str(p->error), p->count); NDMP_PP_ENDWITH break; case NDMP3_TAPE_READ: NDMP_PP_WITH(ndmp3_tape_read_reply) sprintf (buf, "error=%s data_in_len=%d", ndmp3_error_to_str(p->error), p->data_in.data_in_len); NDMP_PP_ENDWITH break; case NDMP3_DATA_GET_STATE: NDMP_PP_WITH(ndmp3_data_get_state_reply) switch (lineno) { case 0: sprintf (buf, "invalid=%lx error=%s op=%s", p->invalid, ndmp3_error_to_str(p->error), ndmp3_data_operation_to_str(p->operation)); break; case 1: sprintf (buf, "state=%s", ndmp3_data_state_to_str(p->state)); break; case 2: sprintf (buf, "halt_reason=%s", ndmp3_data_halt_reason_to_str(p->halt_reason)); break; case 3: sprintf (buf, "bytes_processed=%lld est_bytes_remain=%lld", p->bytes_processed, p->est_bytes_remain); break; case 4: sprintf (buf, "est_time_remain=%ld data_conn_addr=", p->est_time_remain); ndmp3_pp_addr (NDMOS_API_STREND(buf), &p->data_connection_addr); break; case 5: sprintf (buf, "read_offset=%lld read_length=%lld", p->read_offset, p->read_length); break; default: strcpy (buf, "--INVALID--"); break; } return 6; NDMP_PP_ENDWITH break; case NDMP3_DATA_GET_ENV: NDMP_PP_WITH(ndmp3_data_get_env_reply) if (lineno == 0) { sprintf (buf, "error=%s n_env=%d", ndmp3_error_to_str(p->error), p->env.env_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { strcpy (buf, "--INVALID--"); } } return p->env.env_len + 1; NDMP_PP_ENDWITH break; case NDMP3_NOTIFY_DATA_HALTED: case NDMP3_NOTIFY_CONNECTED: case NDMP3_NOTIFY_MOVER_HALTED: case NDMP3_NOTIFY_MOVER_PAUSED: case NDMP3_NOTIFY_DATA_READ: case NDMP3_LOG_FILE: case NDMP3_LOG_MESSAGE: case NDMP3_FH_ADD_FILE: case NDMP3_FH_ADD_DIR: case NDMP3_FH_ADD_NODE: strcpy (buf, "<>"); break; case NDMP3_MOVER_GET_STATE: NDMP_PP_WITH(ndmp3_mover_get_state_reply) switch (lineno) { case 0: sprintf (buf, "error=%s state=%s", ndmp3_error_to_str(p->error), ndmp3_mover_state_to_str(p->state)); break; case 1: sprintf (buf, "pause_reason=%s", ndmp3_mover_pause_reason_to_str(p->pause_reason)); break; case 2: sprintf (buf, "halt_reason=%s", ndmp3_mover_halt_reason_to_str(p->halt_reason)); break; case 3: sprintf (buf,"record_size=%lu record_num=%lu data_written=%lld", p->record_size, p->record_num, p->data_written); break; case 4: sprintf (buf, "seek=%lld to_read=%lld win_off=%lld win_len=%lld", p->seek_position, p->bytes_left_to_read, p->window_offset, p->window_length); break; case 5: sprintf (buf, "data_conn_addr="); ndmp3_pp_addr (NDMOS_API_STREND(buf), &p->data_connection_addr); break; default: strcpy (buf, "--INVALID--"); break; } return 6; NDMP_PP_ENDWITH break; case NDMP3_DATA_LISTEN: NDMP_PP_WITH(ndmp3_data_listen_reply) sprintf (buf, "error=%s mover_conn_addr=", ndmp3_error_to_str(p->error)); ndmp3_pp_addr (NDMOS_API_STREND(buf), &p->data_connection_addr); NDMP_PP_ENDWITH break; case NDMP3_MOVER_LISTEN: NDMP_PP_WITH(ndmp3_mover_listen_reply) sprintf (buf, "error=%s data_conn_addr=", ndmp3_error_to_str(p->error)); ndmp3_pp_addr (NDMOS_API_STREND(buf), &p->data_connection_addr); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } #endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp3_translate.c000066400000000000000000002600741263011562700214400ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #include "ndmp_msg_buf.h" #include "ndmp_translate.h" #ifndef NDMOS_OPTION_NO_NDMP3 /* * Pervasive Types **************************************************************** */ /* * ndmp_error **************************************************************** */ struct enum_conversion ndmp_39_error[] = { { NDMP3_UNDEFINED_ERR, NDMP9_UNDEFINED_ERR }, /* default */ { NDMP3_NO_ERR, NDMP9_NO_ERR }, { NDMP3_NOT_SUPPORTED_ERR, NDMP9_NOT_SUPPORTED_ERR }, { NDMP3_DEVICE_BUSY_ERR, NDMP9_DEVICE_BUSY_ERR }, { NDMP3_DEVICE_OPENED_ERR, NDMP9_DEVICE_OPENED_ERR }, { NDMP3_NOT_AUTHORIZED_ERR, NDMP9_NOT_AUTHORIZED_ERR }, { NDMP3_PERMISSION_ERR, NDMP9_PERMISSION_ERR }, { NDMP3_DEV_NOT_OPEN_ERR, NDMP9_DEV_NOT_OPEN_ERR }, { NDMP3_IO_ERR, NDMP9_IO_ERR }, { NDMP3_TIMEOUT_ERR, NDMP9_TIMEOUT_ERR }, { NDMP3_ILLEGAL_ARGS_ERR, NDMP9_ILLEGAL_ARGS_ERR }, { NDMP3_NO_TAPE_LOADED_ERR, NDMP9_NO_TAPE_LOADED_ERR }, { NDMP3_WRITE_PROTECT_ERR, NDMP9_WRITE_PROTECT_ERR }, { NDMP3_EOF_ERR, NDMP9_EOF_ERR }, { NDMP3_EOM_ERR, NDMP9_EOM_ERR }, { NDMP3_FILE_NOT_FOUND_ERR, NDMP9_FILE_NOT_FOUND_ERR }, { NDMP3_BAD_FILE_ERR, NDMP9_BAD_FILE_ERR }, { NDMP3_NO_DEVICE_ERR, NDMP9_NO_DEVICE_ERR }, { NDMP3_NO_BUS_ERR, NDMP9_NO_BUS_ERR }, { NDMP3_XDR_DECODE_ERR, NDMP9_XDR_DECODE_ERR }, { NDMP3_ILLEGAL_STATE_ERR, NDMP9_ILLEGAL_STATE_ERR }, { NDMP3_UNDEFINED_ERR, NDMP9_UNDEFINED_ERR }, { NDMP3_XDR_ENCODE_ERR, NDMP9_XDR_ENCODE_ERR }, { NDMP3_NO_MEM_ERR, NDMP9_NO_MEM_ERR }, { NDMP3_CONNECT_ERR, NDMP9_CONNECT_ERR }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_3to9_error ( ndmp3_error *error3, ndmp9_error *error9) { *error9 = convert_enum_to_9 (ndmp_39_error, *error3); return 0; } extern int ndmp_9to3_error ( ndmp9_error *error9, ndmp3_error *error3) { *error3 = convert_enum_from_9 (ndmp_39_error, *error9); return 0; } /* * ndmp_pval **************************************************************** */ int ndmp_3to9_pval ( ndmp3_pval *pval3, ndmp9_pval *pval9) { CNVT_STRDUP_TO_9(pval3, pval9, name); CNVT_STRDUP_TO_9(pval3, pval9, value); return 0; } int ndmp_9to3_pval ( ndmp9_pval *pval9, ndmp3_pval *pval3) { CNVT_STRDUP_FROM_9(pval3, pval9, name); CNVT_STRDUP_FROM_9(pval3, pval9, value); return 0; } int ndmp_3to9_pval_vec ( ndmp3_pval *pval3, ndmp9_pval *pval9, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_3to9_pval (&pval3[i], &pval9[i]); return 0; } int ndmp_9to3_pval_vec ( ndmp9_pval *pval9, ndmp3_pval *pval3, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_9to3_pval (&pval9[i], &pval3[i]); return 0; } int ndmp_3to9_pval_vec_dup ( ndmp3_pval *pval3, ndmp9_pval **pval9_p, unsigned n_pval) { *pval9_p = NDMOS_MACRO_NEWN (ndmp9_pval, n_pval); if (!*pval9_p) return -1; return ndmp_3to9_pval_vec (pval3, *pval9_p, n_pval); } int ndmp_9to3_pval_vec_dup ( ndmp9_pval *pval9, ndmp3_pval **pval3_p, unsigned n_pval) { *pval3_p = NDMOS_MACRO_NEWN (ndmp3_pval, n_pval); if (!*pval3_p) return -1; return ndmp_9to3_pval_vec (pval9, *pval3_p, n_pval); } /* * ndmp_addr **************************************************************** */ struct enum_conversion ndmp_39_addr_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL }, /* default */ { NDMP3_ADDR_LOCAL, NDMP9_ADDR_LOCAL }, { NDMP3_ADDR_TCP, NDMP9_ADDR_TCP }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_3to9_addr ( ndmp3_addr *addr3, ndmp9_addr *addr9) { switch (addr3->addr_type) { case NDMP3_ADDR_LOCAL: addr9->addr_type = NDMP9_ADDR_LOCAL; break; case NDMP3_ADDR_TCP: addr9->addr_type = NDMP9_ADDR_TCP; addr9->ndmp9_addr_u.tcp_addr.ip_addr = addr3->ndmp3_addr_u.tcp_addr.ip_addr; addr9->ndmp9_addr_u.tcp_addr.port = addr3->ndmp3_addr_u.tcp_addr.port; break; default: NDMOS_MACRO_ZEROFILL (addr9); addr9->addr_type = -1; return -1; } return 0; } extern int ndmp_9to3_addr ( ndmp9_addr *addr9, ndmp3_addr *addr3) { switch (addr9->addr_type) { case NDMP9_ADDR_LOCAL: addr3->addr_type = NDMP3_ADDR_LOCAL; break; case NDMP9_ADDR_TCP: addr3->addr_type = NDMP3_ADDR_TCP; addr3->ndmp3_addr_u.tcp_addr.ip_addr = addr9->ndmp9_addr_u.tcp_addr.ip_addr; addr3->ndmp3_addr_u.tcp_addr.port = addr9->ndmp9_addr_u.tcp_addr.port; break; default: NDMOS_MACRO_ZEROFILL (addr3); addr3->addr_type = -1; return -1; } return 0; } /* * CONNECT INTERFACES **************************************************************** */ struct enum_conversion ndmp_39_auth_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL }, /* default */ { NDMP3_AUTH_NONE, NDMP9_AUTH_NONE }, { NDMP3_AUTH_TEXT, NDMP9_AUTH_TEXT }, { NDMP3_AUTH_MD5, NDMP9_AUTH_MD5 }, END_ENUM_CONVERSION_TABLE }; int ndmp_3to9_auth_data ( ndmp3_auth_data *auth_data3, ndmp9_auth_data *auth_data9) { int n_error = 0; int rc; ndmp3_auth_text *text3; ndmp9_auth_text *text9; ndmp3_auth_md5 *md53; ndmp9_auth_md5 *md59; switch (auth_data3->auth_type) { case NDMP3_AUTH_NONE: auth_data9->auth_type = NDMP9_AUTH_NONE; break; case NDMP3_AUTH_TEXT: auth_data9->auth_type = NDMP9_AUTH_TEXT; text3 = &auth_data3->ndmp3_auth_data_u.auth_text; text9 = &auth_data9->ndmp9_auth_data_u.auth_text; rc = CNVT_STRDUP_TO_9(text3, text9, auth_id); if (rc) { return rc; /* no mem */ } rc = CNVT_STRDUP_TO_9(text3, text9, auth_password); if (rc) { NDMOS_API_FREE (text9->auth_id); text9->auth_id = 0; return rc; /* no mem */ } break; case NDMP3_AUTH_MD5: auth_data9->auth_type = NDMP9_AUTH_MD5; md53 = &auth_data3->ndmp3_auth_data_u.auth_md5; md59 = &auth_data9->ndmp9_auth_data_u.auth_md5; rc = CNVT_STRDUP_TO_9(md53, md59, auth_id); if (rc) { return rc; /* no mem */ } NDMOS_API_BCOPY (md53->auth_digest, md59->auth_digest, 16); break; default: auth_data9->auth_type = auth_data3->auth_type; NDMOS_MACRO_ZEROFILL (&auth_data9->ndmp9_auth_data_u); n_error++; break; } return n_error; } int ndmp_9to3_auth_data ( ndmp9_auth_data *auth_data9, ndmp3_auth_data *auth_data3) { int n_error = 0; int rc; ndmp9_auth_text *text9; ndmp3_auth_text *text3; ndmp9_auth_md5 *md59; ndmp3_auth_md5 *md53; switch (auth_data9->auth_type) { case NDMP9_AUTH_NONE: auth_data3->auth_type = NDMP3_AUTH_NONE; break; case NDMP9_AUTH_TEXT: auth_data3->auth_type = NDMP3_AUTH_TEXT; text9 = &auth_data9->ndmp9_auth_data_u.auth_text; text3 = &auth_data3->ndmp3_auth_data_u.auth_text; rc = CNVT_STRDUP_FROM_9(text3, text9, auth_id); if (rc) { return rc; /* no mem */ } rc = CNVT_STRDUP_FROM_9(text3, text9, auth_password); if (rc) { NDMOS_API_FREE (text9->auth_id); text3->auth_id = 0; return rc; /* no mem */ } break; case NDMP9_AUTH_MD5: auth_data3->auth_type = NDMP3_AUTH_MD5; md59 = &auth_data9->ndmp9_auth_data_u.auth_md5; md53 = &auth_data3->ndmp3_auth_data_u.auth_md5; rc = CNVT_STRDUP_FROM_9(md53, md59, auth_id); if (rc) { return rc; /* no mem */ } NDMOS_API_BCOPY (md59->auth_digest, md53->auth_digest, 16); break; default: auth_data3->auth_type = auth_data9->auth_type; NDMOS_MACRO_ZEROFILL (&auth_data3->ndmp3_auth_data_u); n_error++; break; } return n_error; } int ndmp_3to9_auth_attr ( ndmp3_auth_attr *auth_attr3, ndmp9_auth_attr *auth_attr9) { int n_error = 0; switch (auth_attr3->auth_type) { case NDMP3_AUTH_NONE: auth_attr9->auth_type = NDMP9_AUTH_NONE; break; case NDMP3_AUTH_TEXT: auth_attr9->auth_type = NDMP9_AUTH_TEXT; break; case NDMP3_AUTH_MD5: auth_attr9->auth_type = NDMP9_AUTH_MD5; NDMOS_API_BCOPY (auth_attr3->ndmp3_auth_attr_u.challenge, auth_attr9->ndmp9_auth_attr_u.challenge, 64); break; default: auth_attr9->auth_type = auth_attr3->auth_type; NDMOS_MACRO_ZEROFILL (&auth_attr9->ndmp9_auth_attr_u); n_error++; break; } return n_error; } int ndmp_9to3_auth_attr ( ndmp9_auth_attr *auth_attr9, ndmp3_auth_attr *auth_attr3) { int n_error = 0; switch (auth_attr9->auth_type) { case NDMP9_AUTH_NONE: auth_attr3->auth_type = NDMP3_AUTH_NONE; break; case NDMP9_AUTH_TEXT: auth_attr3->auth_type = NDMP3_AUTH_TEXT; break; case NDMP9_AUTH_MD5: auth_attr3->auth_type = NDMP3_AUTH_MD5; NDMOS_API_BCOPY (auth_attr9->ndmp9_auth_attr_u.challenge, auth_attr3->ndmp3_auth_attr_u.challenge, 64); break; default: auth_attr3->auth_type = auth_attr9->auth_type; NDMOS_MACRO_ZEROFILL (&auth_attr3->ndmp3_auth_attr_u); n_error++; break; } return n_error; } /* * ndmp_connect_open * just error reply */ int ndmp_3to9_connect_open_request ( ndmp3_connect_open_request *request3, ndmp9_connect_open_request *request9) { CNVT_TO_9 (request3, request9, protocol_version); return 0; } int ndmp_9to3_connect_open_request ( ndmp9_connect_open_request *request9, ndmp3_connect_open_request *request3) { CNVT_FROM_9 (request3, request9, protocol_version); return 0; } /* * ndmp_connect_client_auth * just error reply */ int ndmp_3to9_connect_client_auth_request ( ndmp3_connect_client_auth_request *request3, ndmp9_connect_client_auth_request *request9) { int rc; rc = ndmp_3to9_auth_data (&request3->auth_data, &request9->auth_data); return rc; } int ndmp_9to3_connect_client_auth_request ( ndmp9_connect_client_auth_request *request9, ndmp3_connect_client_auth_request *request3) { int rc; rc = ndmp_9to3_auth_data (&request9->auth_data, &request3->auth_data); return rc; } /* * ndmp_connect_close * no arg request, **NO REPLY** */ /* * ndmp_connect_server_auth */ /* TBD */ int ndmp_3to9_connect_server_auth_request ( ndmp3_connect_server_auth_request *request3, ndmp9_connect_server_auth_request *request9) { return -1; } int ndmp_9to3_connect_server_auth_request ( ndmp9_connect_server_auth_request *request9, ndmp3_connect_server_auth_request *request3) { return -1; } /* * CONFIG INTERFACES **************************************************************** */ int ndmp_3to9_device_info_vec_dup ( ndmp3_device_info *devinf3, ndmp9_device_info **devinf9_p, int n_devinf) { ndmp9_device_info * devinf9; int i; unsigned int j; devinf9 = *devinf9_p = NDMOS_MACRO_NEWN(ndmp9_device_info, n_devinf); if (!devinf9) { return -1; /* no mem */ } for (i = 0; i < n_devinf; i++) { ndmp3_device_info * di3 = &devinf3[i]; ndmp9_device_info * di9 = &devinf9[i]; NDMOS_MACRO_ZEROFILL (di9); CNVT_STRDUP_TO_9 (di3, di9, model); di9->caplist.caplist_val = NDMOS_MACRO_NEWN (ndmp9_device_capability, di3->caplist.caplist_len); if (!di9->caplist.caplist_val) { return -1; } for (j = 0; j < di3->caplist.caplist_len; j++) { ndmp3_device_capability * cap3; ndmp9_device_capability * cap9; cap3 = &di3->caplist.caplist_val[j]; cap9 = &di9->caplist.caplist_val[j]; NDMOS_MACRO_ZEROFILL (cap9); cap9->v3attr.valid = NDMP9_VALIDITY_VALID; cap9->v3attr.value = cap3->attr; CNVT_STRDUP_TO_9 (cap3, cap9, device); ndmp_3to9_pval_vec_dup ( cap3->capability.capability_val, &cap9->capability.capability_val, cap3->capability.capability_len); cap9->capability.capability_len = cap3->capability.capability_len; } di9->caplist.caplist_len = j; } return 0; } int ndmp_9to3_device_info_vec_dup ( ndmp9_device_info *devinf9, ndmp3_device_info **devinf3_p, int n_devinf) { ndmp3_device_info * devinf3; int i; unsigned int j; devinf3 = *devinf3_p = NDMOS_MACRO_NEWN(ndmp3_device_info, n_devinf); if (!devinf3) { return -1; /* no mem */ } for (i = 0; i < n_devinf; i++) { ndmp9_device_info * di9 = &devinf9[i]; ndmp3_device_info * di3 = &devinf3[i]; NDMOS_MACRO_ZEROFILL (di3); CNVT_STRDUP_FROM_9 (di3, di9, model); di3->caplist.caplist_val = NDMOS_MACRO_NEWN (ndmp3_device_capability, di9->caplist.caplist_len); if (!di3->caplist.caplist_val) { return -1; } for (j = 0; j < di9->caplist.caplist_len; j++) { ndmp9_device_capability * cap9; ndmp3_device_capability * cap3; cap9 = &di9->caplist.caplist_val[j]; cap3 = &di3->caplist.caplist_val[j]; NDMOS_MACRO_ZEROFILL (cap3); CNVT_STRDUP_FROM_9 (cap3, cap9, device); ndmp_9to3_pval_vec_dup ( cap9->capability.capability_val, &cap3->capability.capability_val, cap9->capability.capability_len); cap3->capability.capability_len = cap9->capability.capability_len; } di3->caplist.caplist_len = j; } return 0; } /* * ndmp_config_get_host_info * no args request */ int ndmp_3to9_config_get_host_info_reply ( ndmp3_config_get_host_info_reply *reply3, ndmp9_config_get_host_info_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_STRDUP_TO_9x (reply3, reply9, hostname, config_info.hostname); CNVT_STRDUP_TO_9x (reply3, reply9, os_type, config_info.os_type); CNVT_STRDUP_TO_9x (reply3, reply9, os_vers, config_info.os_vers); CNVT_STRDUP_TO_9x (reply3, reply9, hostid, config_info.hostid); return n_error; } int ndmp_9to3_config_get_host_info_reply ( ndmp9_config_get_host_info_reply *reply9, ndmp3_config_get_host_info_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_STRDUP_FROM_9x (reply3, reply9, hostname, config_info.hostname); CNVT_STRDUP_FROM_9x (reply3, reply9, os_type, config_info.os_type); CNVT_STRDUP_FROM_9x (reply3, reply9, os_vers, config_info.os_vers); CNVT_STRDUP_FROM_9x (reply3, reply9, hostid, config_info.hostid); return 0; } /* * ndmp_config_get_connection_type * no args request */ int ndmp_3to9_config_get_connection_type_reply ( ndmp3_config_get_connection_type_reply *reply3, ndmp9_config_get_connection_type_reply *reply9) { int n_error = 0; unsigned int i; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); for (i = 0; i < reply3->addr_types.addr_types_len; i++) { switch (reply3->addr_types.addr_types_val[i]) { case NDMP3_ADDR_LOCAL: reply9->config_info.conntypes |= NDMP9_CONFIG_CONNTYPE_LOCAL; break; case NDMP3_ADDR_TCP: reply9->config_info.conntypes |= NDMP9_CONFIG_CONNTYPE_TCP; break; default: n_error++; /* ignore */ break; } } return n_error; } int ndmp_9to3_config_get_connection_type_reply ( ndmp9_config_get_connection_type_reply *reply9, ndmp3_config_get_connection_type_reply *reply3) { int i = 0; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); reply3->addr_types.addr_types_val = NDMOS_MACRO_NEWN(ndmp3_addr_type, 3); if (!reply3->addr_types.addr_types_val) { return -1; /* no mem */ } i = 0; if (reply9->config_info.conntypes & NDMP9_CONFIG_CONNTYPE_LOCAL) { reply3->addr_types.addr_types_val[i++] = NDMP3_ADDR_LOCAL; } if (reply9->config_info.conntypes & NDMP9_CONFIG_CONNTYPE_TCP) { reply3->addr_types.addr_types_val[i++] = NDMP3_ADDR_TCP; } reply3->addr_types.addr_types_len = i; return 0; } /* * ndmp_config_get_auth_attr */ int ndmp_3to9_config_get_auth_attr_request ( struct ndmp3_config_get_auth_attr_request *request3, struct ndmp9_config_get_auth_attr_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request3, request9, auth_type, ndmp_39_auth_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, auth_type); n_error++; } return n_error; } int ndmp_9to3_config_get_auth_attr_request ( struct ndmp9_config_get_auth_attr_request *request9, struct ndmp3_config_get_auth_attr_request *request3) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request3, request9, auth_type, ndmp_39_auth_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, auth_type); n_error++; } return n_error; } int ndmp_3to9_config_get_auth_attr_reply ( struct ndmp3_config_get_auth_attr_reply *reply3, struct ndmp9_config_get_auth_attr_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); n_error += ndmp_3to9_auth_attr (&reply3->server_attr, &reply9->server_attr); return n_error; } int ndmp_9to3_config_get_auth_attr_reply ( struct ndmp9_config_get_auth_attr_reply *reply9, struct ndmp3_config_get_auth_attr_reply *reply3) { int n_error = 0; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); n_error += ndmp_9to3_auth_attr (&reply9->server_attr, &reply3->server_attr); return n_error; } /* * ndmp_config_get_butype_info * no args request */ int ndmp_3to9_config_get_butype_info_reply ( ndmp3_config_get_butype_info_reply *reply3, ndmp9_config_get_butype_info_reply *reply9) { int n; int i; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); n = reply3->butype_info.butype_info_len; if (n == 0) { reply9->config_info.butype_info.butype_info_len = 0; reply9->config_info.butype_info.butype_info_val = 0; return 0; } reply9->config_info.butype_info.butype_info_val = NDMOS_MACRO_NEWN (ndmp9_butype_info, n); for (i = 0; i < n; i++) { ndmp9_butype_info * bu9; ndmp3_butype_info * bu3; bu3 = &reply3->butype_info.butype_info_val[i]; bu9 = &reply9->config_info.butype_info.butype_info_val[i]; NDMOS_MACRO_ZEROFILL (bu9); CNVT_STRDUP_TO_9 (bu3, bu9, butype_name); ndmp_3to9_pval_vec_dup (bu3->default_env.default_env_val, &bu9->default_env.default_env_val, bu3->default_env.default_env_len); bu9->default_env.default_env_len = bu3->default_env.default_env_len; bu9->v3attr.valid = NDMP9_VALIDITY_VALID; bu9->v3attr.value = bu3->attrs; } reply9->config_info.butype_info.butype_info_len = n; return 0; } int ndmp_9to3_config_get_butype_info_reply ( ndmp9_config_get_butype_info_reply *reply9, ndmp3_config_get_butype_info_reply *reply3) { int n; int i; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); n = reply9->config_info.butype_info.butype_info_len; if (n == 0) { reply3->butype_info.butype_info_len = 0; reply3->butype_info.butype_info_val = 0; return 0; } reply3->butype_info.butype_info_val = NDMOS_MACRO_NEWN (ndmp3_butype_info, n); for (i = 0; i < n; i++) { ndmp3_butype_info * bu3; ndmp9_butype_info * bu9; bu9 = &reply9->config_info.butype_info.butype_info_val[i]; bu3 = &reply3->butype_info.butype_info_val[i]; NDMOS_MACRO_ZEROFILL (bu3); CNVT_STRDUP_FROM_9 (bu3, bu9, butype_name); ndmp_9to3_pval_vec_dup (bu9->default_env.default_env_val, &bu3->default_env.default_env_val, bu9->default_env.default_env_len); bu3->default_env.default_env_len = bu9->default_env.default_env_len; bu3->attrs = bu9->v3attr.value; } reply3->butype_info.butype_info_len = n; return 0; } /* * ndmp_config_get_fs_info * no args request */ int ndmp_3to9_config_get_fs_info_reply ( ndmp3_config_get_fs_info_reply *reply3, ndmp9_config_get_fs_info_reply *reply9) { int n; int i; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); n = reply3->fs_info.fs_info_len; if (n == 0) { reply9->config_info.fs_info.fs_info_len = 0; reply9->config_info.fs_info.fs_info_val = 0; return 0; } reply9->config_info.fs_info.fs_info_val = NDMOS_MACRO_NEWN (ndmp9_fs_info, n); for (i = 0; i < n; i++) { ndmp3_fs_info * fs3; ndmp9_fs_info * fs9; fs3 = &reply3->fs_info.fs_info_val[i]; fs9 = &reply9->config_info.fs_info.fs_info_val[i]; NDMOS_MACRO_ZEROFILL (fs9); CNVT_STRDUP_TO_9 (fs3, fs9, fs_type); CNVT_STRDUP_TO_9 (fs3, fs9, fs_logical_device); CNVT_STRDUP_TO_9 (fs3, fs9, fs_physical_device); CNVT_STRDUP_TO_9 (fs3, fs9, fs_status); ndmp_3to9_pval_vec_dup (fs3->fs_env.fs_env_val, &fs9->fs_env.fs_env_val, fs3->fs_env.fs_env_len); fs9->fs_env.fs_env_len = fs3->fs_env.fs_env_len; } reply9->config_info.fs_info.fs_info_len = n; return 0; } int ndmp_9to3_config_get_fs_info_reply ( ndmp9_config_get_fs_info_reply *reply9, ndmp3_config_get_fs_info_reply *reply3) { int n; int i; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); n = reply9->config_info.fs_info.fs_info_len; if (n == 0) { reply3->fs_info.fs_info_len = 0; reply3->fs_info.fs_info_val = 0; return 0; } reply3->fs_info.fs_info_val = NDMOS_MACRO_NEWN (ndmp3_fs_info, n); for (i = 0; i < n; i++) { ndmp9_fs_info * fs9; ndmp3_fs_info * fs3; fs9 = &reply9->config_info.fs_info.fs_info_val[i]; fs3 = &reply3->fs_info.fs_info_val[i]; NDMOS_MACRO_ZEROFILL (fs3); CNVT_STRDUP_FROM_9 (fs3, fs9, fs_type); CNVT_STRDUP_FROM_9 (fs3, fs9, fs_logical_device); CNVT_STRDUP_FROM_9 (fs3, fs9, fs_physical_device); CNVT_STRDUP_FROM_9 (fs3, fs9, fs_status); ndmp_9to3_pval_vec_dup (fs9->fs_env.fs_env_val, &fs3->fs_env.fs_env_val, fs9->fs_env.fs_env_len); fs3->fs_env.fs_env_len = fs9->fs_env.fs_env_len; } reply3->fs_info.fs_info_len = n; return 0; } /* * ndmp_config_get_tape_info * no args request */ int ndmp_3to9_config_get_tape_info_reply ( ndmp3_config_get_tape_info_reply *reply3, ndmp9_config_get_tape_info_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); ndmp_3to9_device_info_vec_dup ( reply3->tape_info.tape_info_val, &reply9->config_info.tape_info.tape_info_val, reply3->tape_info.tape_info_len); reply9->config_info.tape_info.tape_info_len = reply3->tape_info.tape_info_len; return 0; } int ndmp_9to3_config_get_tape_info_reply ( ndmp9_config_get_tape_info_reply *reply9, ndmp3_config_get_tape_info_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); ndmp_9to3_device_info_vec_dup ( reply9->config_info.tape_info.tape_info_val, &reply3->tape_info.tape_info_val, reply9->config_info.tape_info.tape_info_len); reply3->tape_info.tape_info_len = reply9->config_info.tape_info.tape_info_len; return 0; } /* * ndmp_config_get_scsi_info * no args request */ int ndmp_3to9_config_get_scsi_info_reply ( ndmp3_config_get_scsi_info_reply *reply3, ndmp9_config_get_scsi_info_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); ndmp_3to9_device_info_vec_dup ( reply3->scsi_info.scsi_info_val, &reply9->config_info.scsi_info.scsi_info_val, reply3->scsi_info.scsi_info_len); reply9->config_info.scsi_info.scsi_info_len = reply3->scsi_info.scsi_info_len; return 0; } int ndmp_9to3_config_get_scsi_info_reply ( ndmp9_config_get_scsi_info_reply *reply9, ndmp3_config_get_scsi_info_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); ndmp_9to3_device_info_vec_dup ( reply9->config_info.scsi_info.scsi_info_val, &reply3->scsi_info.scsi_info_val, reply9->config_info.scsi_info.scsi_info_len); reply3->scsi_info.scsi_info_len = reply9->config_info.scsi_info.scsi_info_len; return 0; } /* * ndmp_config_get_server_info * no args request */ int ndmp_3to9_config_get_server_info_reply ( ndmp3_config_get_server_info_reply *reply3, ndmp9_config_get_server_info_reply *reply9) { unsigned int i, n_error = 0; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_STRDUP_TO_9x (reply3, reply9, vendor_name, config_info.vendor_name); CNVT_STRDUP_TO_9x (reply3, reply9, product_name, config_info.product_name); CNVT_STRDUP_TO_9x (reply3, reply9, revision_number, config_info.revision_number); reply9->config_info.authtypes = 0; for (i = 0; i < reply3->auth_type.auth_type_len; i++) { switch (reply3->auth_type.auth_type_val[i]) { case NDMP3_AUTH_NONE: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_NONE; break; case NDMP3_AUTH_TEXT: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_TEXT; break; case NDMP3_AUTH_MD5: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_MD5; break; default: n_error++; /* ignore */ break; } } return n_error; } int ndmp_9to3_config_get_server_info_reply ( ndmp9_config_get_server_info_reply *reply9, ndmp3_config_get_server_info_reply *reply3) { int i = 0; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_STRDUP_FROM_9x (reply3, reply9, vendor_name, config_info.vendor_name); CNVT_STRDUP_FROM_9x (reply3, reply9, product_name, config_info.product_name); CNVT_STRDUP_FROM_9x (reply3, reply9, revision_number, config_info.revision_number); reply3->auth_type.auth_type_val = NDMOS_MACRO_NEWN(ndmp3_auth_type, 3); if (!reply3->auth_type.auth_type_val) { return -1; } i = 0; if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_NONE) { reply3->auth_type.auth_type_val[i++] = NDMP3_AUTH_NONE; } if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_TEXT) { reply3->auth_type.auth_type_val[i++] = NDMP3_AUTH_TEXT; } if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_MD5) { reply3->auth_type.auth_type_val[i++] = NDMP3_AUTH_MD5; } reply3->auth_type.auth_type_len = i; return 0; } /* * SCSI INTERFACES **************************************************************** */ /* * ndmp_scsi_open * just error reply */ int ndmp_3to9_scsi_open_request ( ndmp3_scsi_open_request *request3, ndmp9_scsi_open_request *request9) { request9->device = NDMOS_API_STRDUP (request3->device); if (!request9->device) { return -1; /* no memory */ } return 0; } int ndmp_9to3_scsi_open_request ( ndmp9_scsi_open_request *request9, ndmp3_scsi_open_request *request3) { request3->device = NDMOS_API_STRDUP (request9->device); if (!request3->device) { return -1; /* no memory */ } return 0; } /* * ndmp_scsi_close * no args request, just error reply */ /* * ndmp_scsi_get_state * no args request */ int ndmp_3to9_scsi_get_state_reply ( ndmp3_scsi_get_state_reply *reply3, ndmp9_scsi_get_state_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_TO_9 (reply3, reply9, target_controller); CNVT_TO_9 (reply3, reply9, target_id); CNVT_TO_9 (reply3, reply9, target_lun); return 0; } int ndmp_9to3_scsi_get_state_reply ( ndmp9_scsi_get_state_reply *reply9, ndmp3_scsi_get_state_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_FROM_9 (reply3, reply9, target_controller); CNVT_FROM_9 (reply3, reply9, target_id); CNVT_FROM_9 (reply3, reply9, target_lun); return 0; } /* * ndmp_scsi_set_target -- deprecated * just error reply */ int ndmp_3to9_scsi_set_target_request ( ndmp3_scsi_set_target_request *request3, ndmp9_scsi_set_target_request *request9) { request9->device = NDMOS_API_STRDUP (request3->device); if (!request9->device) { return -1; /* no memory */ } CNVT_TO_9 (request3, request9, target_controller); CNVT_TO_9 (request3, request9, target_id); CNVT_TO_9 (request3, request9, target_lun); return 0; } int ndmp_9to3_scsi_set_target_request ( ndmp9_scsi_set_target_request *request9, ndmp3_scsi_set_target_request *request3) { request3->device = NDMOS_API_STRDUP (request9->device); if (!request3->device) { return -1; /* no memory */ } CNVT_FROM_9 (request3, request9, target_controller); CNVT_FROM_9 (request3, request9, target_id); CNVT_FROM_9 (request3, request9, target_lun); return 0; } /* * ndmp_scsi_reset_device * no args request, just error reply */ /* * ndmp_scsi_reset_bus -- deprecated * no args request, just error reply */ /* * ndmp_tape_execute_cdb * ndmp_scsi_execute_cdb */ int ndmp_3to9_execute_cdb_request ( ndmp3_execute_cdb_request *request3, ndmp9_execute_cdb_request *request9) { int n_error = 0; uint32_t len; char * p; switch (request3->flags) { case 0: request9->data_dir = NDMP9_SCSI_DATA_DIR_NONE; break; case NDMP3_SCSI_DATA_IN: request9->data_dir = NDMP9_SCSI_DATA_DIR_IN; break; case NDMP3_SCSI_DATA_OUT: request9->data_dir = NDMP9_SCSI_DATA_DIR_IN; break; default: /* deemed insolvable */ n_error++; return -1; } CNVT_TO_9 (request3, request9, timeout); CNVT_TO_9 (request3, request9, datain_len); len = request3->dataout.dataout_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request3->dataout.dataout_val, p, len); } else { len = 0; p = 0; } request9->dataout.dataout_len = len; request9->dataout.dataout_val = p; len = request3->cdb.cdb_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (request9->dataout.dataout_val) { NDMOS_API_FREE (request9->dataout.dataout_val); request9->dataout.dataout_len = 0; request9->dataout.dataout_val = 0; } return -1; } NDMOS_API_BCOPY (request3->cdb.cdb_val, p, len); } else { len = 0; p = 0; } request9->cdb.cdb_len = len; request9->cdb.cdb_val = p; return 0; } int ndmp_9to3_execute_cdb_request ( ndmp9_execute_cdb_request *request9, ndmp3_execute_cdb_request *request3) { int n_error = 0; uint32_t len; char * p; switch (request9->data_dir) { case NDMP9_SCSI_DATA_DIR_NONE: request3->flags = 0; break; case NDMP9_SCSI_DATA_DIR_IN: request3->flags = NDMP3_SCSI_DATA_IN; break; case NDMP9_SCSI_DATA_DIR_OUT: request3->flags = NDMP3_SCSI_DATA_OUT; break; default: /* deemed insolvable */ n_error++; return -1; } CNVT_FROM_9 (request3, request9, timeout); CNVT_FROM_9 (request3, request9, datain_len); len = request9->dataout.dataout_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request9->dataout.dataout_val, p, len); } else { len = 0; p = 0; } request3->dataout.dataout_len = len; request3->dataout.dataout_val = p; len = request9->cdb.cdb_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (request3->dataout.dataout_val) { NDMOS_API_FREE (request3->dataout.dataout_val); request3->dataout.dataout_len = 0; request3->dataout.dataout_val = 0; } return -1; } NDMOS_API_BCOPY (request9->cdb.cdb_val, p, len); } else { len = 0; p = 0; } request3->cdb.cdb_len = len; request3->cdb.cdb_val = p; return 0; } int ndmp_3to9_execute_cdb_reply ( ndmp3_execute_cdb_reply *reply3, ndmp9_execute_cdb_reply *reply9) { uint32_t len; char * p; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_TO_9 (reply3, reply9, status); CNVT_TO_9 (reply3, reply9, dataout_len); len = reply3->datain.datain_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply3->datain.datain_val, p, len); } else { len = 0; p = 0; } reply9->datain.datain_len = len; reply9->datain.datain_val = p; len = reply3->ext_sense.ext_sense_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (reply9->datain.datain_val) { NDMOS_API_FREE (reply9->datain.datain_val); reply9->datain.datain_len = 0; reply9->datain.datain_val = 0; } return -1; } NDMOS_API_BCOPY (reply3->ext_sense.ext_sense_val, p, len); } else { len = 0; p = 0; } reply9->ext_sense.ext_sense_len = len; reply9->ext_sense.ext_sense_val = p; return 0; } int ndmp_9to3_execute_cdb_reply ( ndmp9_execute_cdb_reply *reply9, ndmp3_execute_cdb_reply *reply3) { uint32_t len; char * p; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_FROM_9 (reply3, reply9, status); CNVT_FROM_9 (reply3, reply9, dataout_len); len = reply9->datain.datain_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply9->datain.datain_val, p, len); } else { len = 0; p = 0; } reply3->datain.datain_len = len; reply3->datain.datain_val = p; len = reply9->ext_sense.ext_sense_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (reply3->datain.datain_val) { NDMOS_API_FREE (reply9->datain.datain_val); reply3->datain.datain_len = 0; reply3->datain.datain_val = 0; } return -1; } NDMOS_API_BCOPY (reply9->ext_sense.ext_sense_val, p, len); } else { len = 0; p = 0; } reply3->ext_sense.ext_sense_len = len; reply3->ext_sense.ext_sense_val = p; return 0; } /* * TAPE INTERFACES **************************************************************** */ /* * ndmp_tape_open_request * just error reply */ struct enum_conversion ndmp_39_tape_open_mode[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_TAPE_READ_MODE, NDMP9_TAPE_READ_MODE }, { NDMP3_TAPE_RDWR_MODE, NDMP9_TAPE_RDWR_MODE }, END_ENUM_CONVERSION_TABLE }; int ndmp_3to9_tape_open_request ( ndmp3_tape_open_request *request3, ndmp9_tape_open_request *request9) { int n_error = 0; int rc; /* * Mode codes are compatible between versions. * We let untranslated values through to * facilitate testing illegal values. */ rc = convert_enum_to_9 (ndmp_39_tape_open_mode, request3->mode); if (rc == NDMP_INVALID_GENERAL) { n_error++; request9->mode = request3->mode; } else { request9->mode = rc; } request9->device = NDMOS_API_STRDUP (request3->device); if (!request9->device) { return -1; /* no memory */ } return n_error; } int ndmp_9to3_tape_open_request ( ndmp9_tape_open_request *request9, ndmp3_tape_open_request *request3) { int n_error = 0; int rc; rc = convert_enum_from_9 (ndmp_39_tape_open_mode, request9->mode); if (rc == NDMP_INVALID_GENERAL) { n_error++; request3->mode = request9->mode; } else { request3->mode = rc; } request3->device = NDMOS_API_STRDUP (request9->device); if (!request3->device) { return -1; /* no memory */ } return n_error; } /* * ndmp_tape_get_state_reply * no arg request */ extern int ndmp_3to9_tape_get_state_reply ( ndmp3_tape_get_state_reply *reply3, ndmp9_tape_get_state_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_TO_9 (reply3, reply9, flags); CNVT_VUL_TO_9 (reply3, reply9, file_num); CNVT_VUL_TO_9 (reply3, reply9, soft_errors); CNVT_VUL_TO_9 (reply3, reply9, block_size); CNVT_VUL_TO_9 (reply3, reply9, blockno); CNVT_VUQ_TO_9 (reply3, reply9, total_space); CNVT_VUQ_TO_9 (reply3, reply9, space_remain); #if 0 CNVT_VUL_TO_9 (reply3, reply9, partition); #endif if (reply3->invalid & NDMP3_TAPE_STATE_FILE_NUM_INVALID) CNVT_IUL_TO_9 (reply9, file_num); if (reply3->invalid & NDMP3_TAPE_STATE_SOFT_ERRORS_INVALID) CNVT_IUL_TO_9 (reply9, soft_errors); if (reply3->invalid & NDMP3_TAPE_STATE_BLOCK_SIZE_INVALID) CNVT_IUL_TO_9 (reply9, block_size); if (reply3->invalid & NDMP3_TAPE_STATE_BLOCKNO_INVALID) CNVT_IUL_TO_9 (reply9, blockno); if (reply3->invalid & NDMP3_TAPE_STATE_TOTAL_SPACE_INVALID) CNVT_IUQ_TO_9 (reply9, total_space); if (reply3->invalid & NDMP3_TAPE_STATE_SPACE_REMAIN_INVALID) CNVT_IUQ_TO_9 (reply9, space_remain); #if 0 if (reply3->invalid & NDMP3_TAPE_STATE_PARTITION_INVALID) CNVT_IUL_TO_9 (reply9, partition); #endif return 0; } extern int ndmp_9to3_tape_get_state_reply ( ndmp9_tape_get_state_reply *reply9, ndmp3_tape_get_state_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_FROM_9 (reply3, reply9, flags); CNVT_VUL_FROM_9 (reply3, reply9, file_num); CNVT_VUL_FROM_9 (reply3, reply9, soft_errors); CNVT_VUL_FROM_9 (reply3, reply9, block_size); CNVT_VUL_FROM_9 (reply3, reply9, blockno); CNVT_VUQ_FROM_9 (reply3, reply9, total_space); CNVT_VUQ_FROM_9 (reply3, reply9, space_remain); #if 0 CNVT_VUL_FROM_9 (reply3, reply9, partition); #endif reply3->invalid = 0; if (!reply9->file_num.valid) reply3->invalid |= NDMP3_TAPE_STATE_FILE_NUM_INVALID; if (!reply9->soft_errors.valid) reply3->invalid |= NDMP3_TAPE_STATE_SOFT_ERRORS_INVALID; if (!reply9->block_size.valid) reply3->invalid |= NDMP3_TAPE_STATE_BLOCK_SIZE_INVALID; if (!reply9->blockno.valid) reply3->invalid |= NDMP3_TAPE_STATE_BLOCKNO_INVALID; if (!reply9->total_space.valid) reply3->invalid |= NDMP3_TAPE_STATE_TOTAL_SPACE_INVALID; if (!reply9->space_remain.valid) reply3->invalid |= NDMP3_TAPE_STATE_SPACE_REMAIN_INVALID; #if 0 if (!reply9->partition.valid) reply3->invalid |= NDMP3_TAPE_STATE_PARTITION_INVALID; #else reply3->invalid |= NDMP3_TAPE_STATE_PARTITION_INVALID; #endif return 0; } /* * ndmp_tape_mtio_request */ struct enum_conversion ndmp_39_tape_mtio_op[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_MTIO_FSF, NDMP9_MTIO_FSF }, { NDMP3_MTIO_BSF, NDMP9_MTIO_BSF }, { NDMP3_MTIO_FSR, NDMP9_MTIO_FSR }, { NDMP3_MTIO_BSR, NDMP9_MTIO_BSR }, { NDMP3_MTIO_REW, NDMP9_MTIO_REW }, { NDMP3_MTIO_EOF, NDMP9_MTIO_EOF }, { NDMP3_MTIO_OFF, NDMP9_MTIO_OFF }, END_ENUM_CONVERSION_TABLE }; int ndmp_3to9_tape_mtio_request ( ndmp3_tape_mtio_request *request3, ndmp9_tape_mtio_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request3, request9, tape_op, ndmp_39_tape_mtio_op); if (rc == NDMP_INVALID_GENERAL) { n_error++; CNVT_TO_9(request3, request9, tape_op); } CNVT_TO_9(request3, request9, count); return n_error; } int ndmp_9to3_tape_mtio_request ( ndmp9_tape_mtio_request *request9, ndmp3_tape_mtio_request *request3) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request3, request9, tape_op, ndmp_39_tape_mtio_op); if (rc == NDMP_INVALID_GENERAL) { n_error++; CNVT_FROM_9(request3, request9, tape_op); } CNVT_FROM_9(request3, request9, count); return n_error; } int ndmp_3to9_tape_mtio_reply ( ndmp3_tape_mtio_reply *reply3, ndmp9_tape_mtio_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_TO_9 (reply3, reply9, resid_count); return 0; } int ndmp_9to3_tape_mtio_reply ( ndmp9_tape_mtio_reply *reply9, ndmp3_tape_mtio_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_FROM_9 (reply3, reply9, resid_count); return 0; } /* * ndmp_tape_write */ int ndmp_3to9_tape_write_request ( ndmp3_tape_write_request *request3, ndmp9_tape_write_request *request9) { uint32_t len; char * p; len = request3->data_out.data_out_len; p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request3->data_out.data_out_val, p, len); request9->data_out.data_out_val = p; request9->data_out.data_out_len = len; return 0; } int ndmp_9to3_tape_write_request ( ndmp9_tape_write_request *request9, ndmp3_tape_write_request *request3) { uint32_t len; char * p; len = request9->data_out.data_out_len; p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request9->data_out.data_out_val, p, len); request3->data_out.data_out_val = p; request3->data_out.data_out_len = len; return 0; } int ndmp_3to9_tape_write_reply ( ndmp3_tape_write_reply *reply3, ndmp9_tape_write_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_TO_9 (reply3, reply9, count); return 0; } int ndmp_9to3_tape_write_reply ( ndmp9_tape_write_reply *reply9, ndmp3_tape_write_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_FROM_9 (reply3, reply9, count); return 0; } /* * ndmp_tape_read */ int ndmp_3to9_tape_read_request ( ndmp3_tape_read_request *request3, ndmp9_tape_read_request *request9) { CNVT_TO_9 (request3, request9, count); return 0; } int ndmp_9to3_tape_read_request ( ndmp9_tape_read_request *request9, ndmp3_tape_read_request *request3) { CNVT_FROM_9 (request3, request9, count); return 0; } int ndmp_3to9_tape_read_reply ( ndmp3_tape_read_reply *reply3, ndmp9_tape_read_reply *reply9) { uint32_t len; char * p; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); len = reply3->data_in.data_in_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply3->data_in.data_in_val, p, len); } else { p = 0; len = 0; } reply9->data_in.data_in_len = len; reply9->data_in.data_in_val = p; return 0; } int ndmp_9to3_tape_read_reply ( ndmp9_tape_read_reply *reply9, ndmp3_tape_read_reply *reply3) { uint32_t len; char * p; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); len = reply9->data_in.data_in_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply9->data_in.data_in_val, p, len); } else { p = 0; len = 0; } reply3->data_in.data_in_len = len; reply3->data_in.data_in_val = p; return 0; } /* * ndmp_tape_execute_cdb * see SCSI INTERFACES above */ /* * MOVER INTERFACES **************************************************************** */ /* * ndmp_mover_get_state * no args request */ struct enum_conversion ndmp_39_mover_mode[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_MOVER_MODE_READ, NDMP9_MOVER_MODE_READ }, { NDMP3_MOVER_MODE_WRITE, NDMP9_MOVER_MODE_WRITE }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_39_mover_state[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_MOVER_STATE_IDLE, NDMP9_MOVER_STATE_IDLE }, { NDMP3_MOVER_STATE_LISTEN, NDMP9_MOVER_STATE_LISTEN }, { NDMP3_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_ACTIVE }, { NDMP3_MOVER_STATE_PAUSED, NDMP9_MOVER_STATE_PAUSED }, { NDMP3_MOVER_STATE_HALTED, NDMP9_MOVER_STATE_HALTED }, /* alias */ { NDMP3_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_STANDBY }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_39_mover_pause_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_MOVER_PAUSE_NA, NDMP9_MOVER_PAUSE_NA }, { NDMP3_MOVER_PAUSE_EOM, NDMP9_MOVER_PAUSE_EOM }, { NDMP3_MOVER_PAUSE_EOF, NDMP9_MOVER_PAUSE_EOF }, { NDMP3_MOVER_PAUSE_SEEK, NDMP9_MOVER_PAUSE_SEEK }, { NDMP3_MOVER_PAUSE_MEDIA_ERROR, NDMP9_MOVER_PAUSE_MEDIA_ERROR }, { NDMP3_MOVER_PAUSE_EOW, NDMP9_MOVER_PAUSE_EOW }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_39_mover_halt_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_MOVER_HALT_NA, NDMP9_MOVER_HALT_NA }, { NDMP3_MOVER_HALT_CONNECT_CLOSED, NDMP9_MOVER_HALT_CONNECT_CLOSED }, { NDMP3_MOVER_HALT_ABORTED, NDMP9_MOVER_HALT_ABORTED }, { NDMP3_MOVER_HALT_INTERNAL_ERROR, NDMP9_MOVER_HALT_INTERNAL_ERROR }, { NDMP3_MOVER_HALT_CONNECT_ERROR, NDMP9_MOVER_HALT_CONNECT_ERROR }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_3to9_mover_get_state_reply ( ndmp3_mover_get_state_reply *reply3, ndmp9_mover_get_state_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_E_TO_9 (reply3, reply9, state, ndmp_39_mover_state); CNVT_E_TO_9 (reply3, reply9, pause_reason, ndmp_39_mover_pause_reason); CNVT_E_TO_9 (reply3, reply9, halt_reason, ndmp_39_mover_halt_reason); CNVT_TO_9 (reply3, reply9, record_size); CNVT_TO_9 (reply3, reply9, record_num); CNVT_TO_9x (reply3, reply9, data_written, bytes_moved); CNVT_TO_9 (reply3, reply9, seek_position); CNVT_TO_9 (reply3, reply9, bytes_left_to_read); CNVT_TO_9 (reply3, reply9, window_offset); CNVT_TO_9 (reply3, reply9, window_length); ndmp_3to9_addr (&reply3->data_connection_addr, &reply9->data_connection_addr); return 0; } extern int ndmp_9to3_mover_get_state_reply ( ndmp9_mover_get_state_reply *reply9, ndmp3_mover_get_state_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_E_FROM_9 (reply3, reply9, state, ndmp_39_mover_state); CNVT_E_FROM_9 (reply3, reply9, pause_reason, ndmp_39_mover_pause_reason); CNVT_E_FROM_9 (reply3, reply9, halt_reason, ndmp_39_mover_halt_reason); CNVT_FROM_9 (reply3, reply9, record_size); CNVT_FROM_9 (reply3, reply9, record_num); CNVT_FROM_9x (reply3, reply9, data_written, bytes_moved); CNVT_FROM_9 (reply3, reply9, seek_position); CNVT_FROM_9 (reply3, reply9, bytes_left_to_read); CNVT_FROM_9 (reply3, reply9, window_offset); CNVT_FROM_9 (reply3, reply9, window_length); ndmp_9to3_addr (&reply9->data_connection_addr, &reply3->data_connection_addr); return 0; } /* * ndmp_mover_listen */ int ndmp_3to9_mover_listen_request ( ndmp3_mover_listen_request *request3, ndmp9_mover_listen_request *request9) { int rc; rc = CNVT_E_TO_9 (request3, request9, mode, ndmp_39_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, mode); } rc = CNVT_E_TO_9 (request3, request9, addr_type, ndmp_39_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, addr_type); } return 0; } int ndmp_9to3_mover_listen_request ( ndmp9_mover_listen_request *request9, ndmp3_mover_listen_request *request3) { int rc; rc = CNVT_E_FROM_9 (request3, request9, mode, ndmp_39_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, mode); } rc = CNVT_E_FROM_9 (request3, request9, addr_type, ndmp_39_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, addr_type); } return 0; } int ndmp_3to9_mover_listen_reply ( ndmp3_mover_listen_reply *reply3, ndmp9_mover_listen_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); n_error += ndmp_3to9_addr (&reply3->data_connection_addr, &reply9->data_connection_addr); return n_error; } int ndmp_9to3_mover_listen_reply ( ndmp9_mover_listen_reply *reply9, ndmp3_mover_listen_reply *reply3) { int n_error = 0; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); n_error += ndmp_9to3_addr (&reply9->data_connection_addr, &reply3->data_connection_addr); return n_error; } /* * ndmp_mover_connect * just error reply */ int ndmp_3to9_mover_connect_request ( ndmp3_mover_connect_request *request3, ndmp9_mover_connect_request *request9) { int rc; rc = CNVT_E_TO_9 (request3, request9, mode, ndmp_39_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, mode); } return ndmp_3to9_addr (&request3->addr, &request9->addr); } int ndmp_9to3_mover_connect_request ( ndmp9_mover_connect_request *request9, ndmp3_mover_connect_request *request3) { int rc; rc = CNVT_E_FROM_9 (request3, request9, mode, ndmp_39_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, mode); } return ndmp_9to3_addr (&request9->addr, &request3->addr); } /* * ndmp_mover_continue * no arg request, just error reply */ /* * ndmp_mover_abort * no args request, just error reply */ /* * ndmp_mover_stop * no args request, just error reply */ /* * ndmp_mover_set_window * just error reply */ int ndmp_3to9_mover_set_window_request ( ndmp3_mover_set_window_request *request3, ndmp9_mover_set_window_request *request9) { CNVT_TO_9 (request3, request9, offset); CNVT_TO_9 (request3, request9, length); return 0; } int ndmp_9to3_mover_set_window_request ( ndmp9_mover_set_window_request *request9, ndmp3_mover_set_window_request *request3) { CNVT_FROM_9 (request3, request9, offset); CNVT_FROM_9 (request3, request9, length); return 0; } /* * ndmp_mover_read * just error reply */ int ndmp_3to9_mover_read_request ( ndmp3_mover_read_request *request3, ndmp9_mover_read_request *request9) { CNVT_TO_9 (request3, request9, offset); CNVT_TO_9 (request3, request9, length); return 0; } int ndmp_9to3_mover_read_request ( ndmp9_mover_read_request *request9, ndmp3_mover_read_request *request3) { CNVT_FROM_9 (request3, request9, offset); CNVT_FROM_9 (request3, request9, length); return 0; } /* * ndmp_mover_close * no args request, just error reply */ /* * ndmp_mover_set_record_size * just error reply */ int ndmp_3to9_mover_set_record_size_request ( ndmp3_mover_set_record_size_request *request3, ndmp9_mover_set_record_size_request *request9) { CNVT_TO_9x (request3, request9, len, record_size); return 0; } int ndmp_9to3_mover_set_record_size_request ( ndmp9_mover_set_record_size_request *request9, ndmp3_mover_set_record_size_request *request3) { CNVT_FROM_9x (request3, request9, len, record_size); return 0; } /* * DATA INTERFACES **************************************************************** */ int ndmp_3to9_name ( ndmp3_name *name3, ndmp9_name *name9) { char buf[1024]; int cnt; cnt = sizeof(buf) - 1; name9->original_path = NDMOS_API_STRDUP(name3->original_path); if (name3->new_name && *name3->new_name && *name3->destination_dir) { snprintf (buf, cnt, "%s/%s", name3->destination_dir, name3->new_name); } else if (name3->new_name && *name3->new_name) { snprintf (buf, cnt, "/%s", name3->new_name); } else { strncpy (buf, name3->destination_dir, cnt); } buf[cnt] = '\0'; name9->destination_path = NDMOS_API_STRDUP(buf); /* per the following email's on the NDMP tech mailing on * Apr. 10 & 11 2000 and Feb. 21, 2001 with matching * references in the V3.1.3 specification: * * V2 and V4 are close in behavior but V3 does the following: * * If new_name is not NULL then the destination path is * destination_path = destination_dir PLUS new_name * otherwise * destination_path = destination_dir PLUS original_path * and original_path is missing the trailing component. */ if (name3->new_name && *name3->new_name) { if (*name3->original_path) { snprintf (buf, cnt, "%s/%s", name3->original_path, name3->new_name); } else { strncpy (buf, name3->new_name, cnt); } buf[cnt] = '\0'; name9->original_path = NDMOS_API_STRDUP(buf); } else { name9->original_path = NDMOS_API_STRDUP(name3->original_path); } if (name3->new_name && *name3->new_name) { if (*name3->destination_dir) { snprintf (buf, cnt, "%s/%s", name3->destination_dir, name3->new_name); } else { strncpy (buf, name3->new_name, cnt); } buf[cnt] = '\0'; name9->original_path = NDMOS_API_STRDUP(buf); } else { if (*name3->destination_dir) { snprintf (buf, cnt, "%s/%s", name3->destination_dir, name3->original_path); } else { strncpy (buf, name3->original_path, cnt); } buf[cnt] = '\0'; } name9->destination_path = NDMOS_API_STRDUP(buf); name9->other_name = NDMOS_API_STRDUP (name3->other_name); name9->node = name3->node; if (name3->fh_info != NDMP_INVALID_U_QUAD) { name9->fh_info.valid = NDMP9_VALIDITY_VALID; name9->fh_info.value = name3->fh_info; } else { name9->fh_info.valid = NDMP9_VALIDITY_INVALID; name9->fh_info.value = NDMP_INVALID_U_QUAD; } return 0; } int ndmp_9to3_name ( ndmp9_name *name9, ndmp3_name *name3) { char buf[1024]; int olen, dlen, offset; /* see comment in ndmp_3to9_name() above */ if (!strcmp(name9->original_path,".")) { // special case name3->original_path = NDMOS_API_STRDUP(name9->original_path); name3->destination_dir = NDMOS_API_STRDUP(name9->destination_path); name3->new_name = NDMOS_API_STRDUP(""); } else { olen = strlen(name9->original_path); dlen = strlen(name9->destination_path); offset = dlen - olen; if ((olen < dlen) && (!strcmp(name9->original_path, &name9->destination_path[offset]))) { /* original path part of destination path */ name3->original_path = NDMOS_API_STRDUP(name9->original_path); *buf = 0; strncat(buf, name9->destination_path, offset); name3->destination_dir = NDMOS_API_STRDUP(buf); name3->new_name = NDMOS_API_STRDUP(""); } else { name3->original_path = NDMOS_API_STRDUP(name9->original_path); name3->destination_dir = NDMOS_API_STRDUP(""); name3->new_name = NDMOS_API_STRDUP(name9->destination_path); } } name3->other_name = NDMOS_API_STRDUP (name9->other_name); name3->node = name9->node; if (name9->fh_info.valid == NDMP9_VALIDITY_VALID) { name3->fh_info = name9->fh_info.value; } else { name3->fh_info = NDMP_INVALID_U_QUAD; } return 0; } int ndmp_3to9_name_vec ( ndmp3_name *name3, ndmp9_name *name9, unsigned n_name) { unsigned int i; for (i = 0; i < n_name; i++) ndmp_3to9_name (&name3[i], &name9[i]); return 0; } int ndmp_9to3_name_vec ( ndmp9_name *name9, ndmp3_name *name3, unsigned n_name) { unsigned int i; for (i = 0; i < n_name; i++) ndmp_9to3_name (&name9[i], &name3[i]); return 0; } int ndmp_3to9_name_vec_dup ( ndmp3_name *name3, ndmp9_name **name9_p, unsigned n_name) { *name9_p = NDMOS_MACRO_NEWN (ndmp9_name, n_name); if (!*name9_p) return -1; return ndmp_3to9_name_vec (name3, *name9_p, n_name); } int ndmp_9to3_name_vec_dup ( ndmp9_name *name9, ndmp3_name **name3_p, unsigned n_name) { *name3_p = NDMOS_MACRO_NEWN (ndmp3_name, n_name); if (!*name3_p) return -1; return ndmp_9to3_name_vec (name9, *name3_p, n_name); } /* * ndmp_data_get_state * no args request */ struct enum_conversion ndmp_39_data_operation[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_DATA_OP_NOACTION, NDMP9_DATA_OP_NOACTION }, { NDMP3_DATA_OP_BACKUP, NDMP9_DATA_OP_BACKUP }, { NDMP3_DATA_OP_RESTORE, NDMP9_DATA_OP_RECOVER }, { NDMP3_DATA_OP_RESTORE_FILEHIST, NDMP9_DATA_OP_RECOVER_FILEHIST }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_39_data_state[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_DATA_STATE_IDLE, NDMP9_DATA_STATE_IDLE }, { NDMP3_DATA_STATE_ACTIVE, NDMP9_DATA_STATE_ACTIVE }, { NDMP3_DATA_STATE_HALTED, NDMP9_DATA_STATE_HALTED }, { NDMP3_DATA_STATE_CONNECTED, NDMP9_DATA_STATE_CONNECTED }, { NDMP3_DATA_STATE_LISTEN, NDMP9_DATA_STATE_LISTEN }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_39_data_halt_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_DATA_HALT_NA, NDMP9_DATA_HALT_NA }, { NDMP3_DATA_HALT_SUCCESSFUL, NDMP9_DATA_HALT_SUCCESSFUL }, { NDMP3_DATA_HALT_ABORTED, NDMP9_DATA_HALT_ABORTED }, { NDMP3_DATA_HALT_INTERNAL_ERROR, NDMP9_DATA_HALT_INTERNAL_ERROR }, { NDMP3_DATA_HALT_CONNECT_ERROR, NDMP9_DATA_HALT_CONNECT_ERROR }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_3to9_data_get_state_reply ( ndmp3_data_get_state_reply *reply3, ndmp9_data_get_state_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); CNVT_E_TO_9 (reply3, reply9, operation, ndmp_39_data_operation); CNVT_E_TO_9 (reply3, reply9, state, ndmp_39_data_state); CNVT_E_TO_9 (reply3, reply9, halt_reason, ndmp_39_data_halt_reason); CNVT_TO_9 (reply3, reply9, bytes_processed); CNVT_VUQ_TO_9 (reply3, reply9, est_bytes_remain); CNVT_VUL_TO_9 (reply3, reply9, est_time_remain); ndmp_3to9_addr (&reply3->data_connection_addr, &reply9->data_connection_addr); CNVT_TO_9 (reply3, reply9, read_offset); CNVT_TO_9 (reply3, reply9, read_length); return 0; } extern int ndmp_9to3_data_get_state_reply ( ndmp9_data_get_state_reply *reply9, ndmp3_data_get_state_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); CNVT_E_FROM_9 (reply3, reply9, operation, ndmp_39_data_operation); CNVT_E_FROM_9 (reply3, reply9, state, ndmp_39_data_state); CNVT_E_FROM_9 (reply3, reply9, halt_reason, ndmp_39_data_halt_reason); CNVT_FROM_9 (reply3, reply9, bytes_processed); CNVT_VUQ_FROM_9 (reply3, reply9, est_bytes_remain); CNVT_VUL_FROM_9 (reply3, reply9, est_time_remain); ndmp_9to3_addr (&reply9->data_connection_addr, &reply3->data_connection_addr); CNVT_FROM_9 (reply3, reply9, read_offset); CNVT_FROM_9 (reply3, reply9, read_length); return 0; } /* * ndmp_data_start_backup * just error reply */ int ndmp_3to9_data_start_backup_request ( ndmp3_data_start_backup_request *request3, ndmp9_data_start_backup_request *request9) { int n_error = 0; CNVT_STRDUP_TO_9 (request3, request9, bu_type); ndmp_3to9_pval_vec_dup (request3->env.env_val, &request9->env.env_val, request3->env.env_len); request9->env.env_len = request3->env.env_len; request9->addr.addr_type = NDMP9_ADDR_AS_CONNECTED; return n_error; } int ndmp_9to3_data_start_backup_request ( ndmp9_data_start_backup_request *request9, ndmp3_data_start_backup_request *request3) { int n_error = 0; CNVT_STRDUP_FROM_9 (request3, request9, bu_type); ndmp_9to3_pval_vec_dup (request9->env.env_val, &request3->env.env_val, request9->env.env_len); request3->env.env_len = request9->env.env_len; return n_error; } /* * ndmp_data_start_recover * ndmp_data_start_recover_filehist * just error reply */ int ndmp_3to9_data_start_recover_request ( ndmp3_data_start_recover_request *request3, ndmp9_data_start_recover_request *request9) { int n_error = 0; CNVT_STRDUP_TO_9 (request3, request9, bu_type); ndmp_3to9_pval_vec_dup (request3->env.env_val, &request9->env.env_val, request3->env.env_len); request9->env.env_len = request3->env.env_len; ndmp_3to9_name_vec_dup (request3->nlist.nlist_val, &request9->nlist.nlist_val, request3->nlist.nlist_len); request9->nlist.nlist_len = request3->nlist.nlist_len; request9->addr.addr_type = NDMP9_ADDR_AS_CONNECTED; return n_error; } int ndmp_9to3_data_start_recover_request ( ndmp9_data_start_recover_request *request9, ndmp3_data_start_recover_request *request3) { int n_error = 0; CNVT_STRDUP_FROM_9 (request3, request9, bu_type); ndmp_9to3_pval_vec_dup (request9->env.env_val, &request3->env.env_val, request9->env.env_len); request3->env.env_len = request9->env.env_len; ndmp_9to3_name_vec_dup (request9->nlist.nlist_val, &request3->nlist.nlist_val, request9->nlist.nlist_len); request3->nlist.nlist_len = request9->nlist.nlist_len; return n_error; } /* * ndmp_data_abort * no args request, just error reply */ /* * ndmp_data_get_env * no args request */ int ndmp_3to9_data_get_env_reply ( ndmp3_data_get_env_reply *reply3, ndmp9_data_get_env_reply *reply9) { CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); ndmp_3to9_pval_vec_dup (reply3->env.env_val, &reply9->env.env_val, reply3->env.env_len); reply9->env.env_len = reply3->env.env_len; return 0; } int ndmp_9to3_data_get_env_reply ( ndmp9_data_get_env_reply *reply9, ndmp3_data_get_env_reply *reply3) { CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); ndmp_9to3_pval_vec_dup (reply9->env.env_val, &reply3->env.env_val, reply9->env.env_len); reply3->env.env_len = reply9->env.env_len; return 0; } /* * ndmp_data_stop * no args request, just error reply */ /* * ndmp_data_listen */ int ndmp_3to9_data_listen_request ( ndmp3_data_listen_request *request3, ndmp9_data_listen_request *request9) { int rc; rc = CNVT_E_TO_9 (request3, request9, addr_type, ndmp_39_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, addr_type); } return 0; } int ndmp_9to3_data_listen_request ( ndmp9_data_listen_request *request9, ndmp3_data_listen_request *request3) { int rc; rc = CNVT_E_FROM_9 (request3, request9, addr_type, ndmp_39_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, addr_type); } return 0; } int ndmp_3to9_data_listen_reply ( ndmp3_data_listen_reply *reply3, ndmp9_data_listen_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply3, reply9, error, ndmp_39_error); n_error += ndmp_3to9_addr (&reply3->data_connection_addr, &reply9->data_connection_addr); return n_error; } int ndmp_9to3_data_listen_reply ( ndmp9_data_listen_reply *reply9, ndmp3_data_listen_reply *reply3) { int n_error = 0; CNVT_E_FROM_9 (reply3, reply9, error, ndmp_39_error); n_error += ndmp_9to3_addr (&reply9->data_connection_addr, &reply3->data_connection_addr); return n_error; } /* * ndmp_data_connect * just error reply */ int ndmp_3to9_data_connect_request ( ndmp3_data_connect_request *request3, ndmp9_data_connect_request *request9) { return ndmp_3to9_addr (&request3->addr, &request9->addr); } int ndmp_9to3_data_connect_request ( ndmp9_data_connect_request *request9, ndmp3_data_connect_request *request3) { return ndmp_9to3_addr (&request9->addr, &request3->addr); } /* * NOTIFY INTERFACES **************************************************************** */ /* * ndmp_notify_data_halted * just error reply */ int ndmp_3to9_notify_data_halted_request ( ndmp3_notify_data_halted_request *request3, ndmp9_notify_data_halted_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request3, request9, reason, ndmp_39_data_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, reason); n_error++; } return n_error; } int ndmp_9to3_notify_data_halted_request ( ndmp9_notify_data_halted_request *request9, ndmp3_notify_data_halted_request *request3) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request3, request9, reason, ndmp_39_data_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, reason); n_error++; } request3->text_reason = NDMOS_API_STRDUP("whatever"); return n_error; } /* * ndmp_notify_connected * just error reply */ /* NDMP3_NOTIFY_CONNECTED */ struct enum_conversion ndmp_39_connect_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_CONNECTED, NDMP9_CONNECTED }, { NDMP3_SHUTDOWN, NDMP9_SHUTDOWN }, { NDMP3_REFUSED, NDMP9_REFUSED }, END_ENUM_CONVERSION_TABLE }; int ndmp_3to9_notify_connected_request ( ndmp3_notify_connected_request *request3, ndmp9_notify_connected_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request3, request9, reason, ndmp_39_connect_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, reason); n_error++; } CNVT_TO_9 (request3, request9, protocol_version); CNVT_STRDUP_TO_9 (request3, request9, text_reason); return n_error; } int ndmp_9to3_notify_connected_request ( ndmp9_notify_connected_request *request9, ndmp3_notify_connected_request *request3) { int n_error = 0; int rc; rc = CNVT_E_FROM_9(request3, request9, reason, ndmp_39_connect_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, reason); n_error++; } CNVT_FROM_9 (request3, request9, protocol_version); CNVT_STRDUP_FROM_9 (request3, request9, text_reason); return n_error; } /* * ndmp_notify_mover_halted * just error reply */ int ndmp_3to9_notify_mover_halted_request ( ndmp3_notify_mover_halted_request *request3, ndmp9_notify_mover_halted_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request3, request9, reason, ndmp_39_mover_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, reason); n_error++; } return n_error; } int ndmp_9to3_notify_mover_halted_request ( ndmp9_notify_mover_halted_request *request9, ndmp3_notify_mover_halted_request *request3) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request3, request9, reason, ndmp_39_mover_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, reason); n_error++; } request3->text_reason = NDMOS_API_STRDUP ("Whatever"); return n_error; } /* * ndmp_notify_mover_paused * just error reply */ int ndmp_3to9_notify_mover_paused_request ( ndmp3_notify_mover_paused_request *request3, ndmp9_notify_mover_paused_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request3, request9, reason, ndmp_39_mover_pause_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request3, request9, reason); n_error++; } CNVT_TO_9 (request3, request9, seek_position); return n_error; } int ndmp_9to3_notify_mover_paused_request ( ndmp9_notify_mover_paused_request *request9, ndmp3_notify_mover_paused_request *request3) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request3, request9, reason, ndmp_39_mover_pause_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request3, request9, reason); n_error++; } CNVT_FROM_9 (request3, request9, seek_position); return n_error; } /* * ndmp_notify_data_read * just error reply */ int ndmp_3to9_notify_data_read_request ( ndmp3_notify_data_read_request *request3, ndmp9_notify_data_read_request *request9) { CNVT_TO_9 (request3, request9, offset); CNVT_TO_9 (request3, request9, length); return 0; } int ndmp_9to3_notify_data_read_request ( ndmp9_notify_data_read_request *request9, ndmp3_notify_data_read_request *request3) { CNVT_FROM_9 (request3, request9, offset); CNVT_FROM_9 (request3, request9, length); return 0; } /* * LOGGING INTERFACES **************************************************************** */ struct enum_conversion ndmp_39_recovery_status[] = { { NDMP3_UNDEFINED_ERR, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR }, /* default */ { NDMP3_NO_ERR, NDMP9_RECOVERY_SUCCESSFUL }, { NDMP3_PERMISSION_ERR, NDMP9_RECOVERY_FAILED_PERMISSION }, { NDMP3_FILE_NOT_FOUND_ERR, NDMP9_RECOVERY_FAILED_NOT_FOUND }, { NDMP3_BAD_FILE_ERR, NDMP9_RECOVERY_FAILED_NO_DIRECTORY }, { NDMP3_NO_MEM_ERR, NDMP9_RECOVERY_FAILED_OUT_OF_MEMORY }, { NDMP3_IO_ERR, NDMP9_RECOVERY_FAILED_IO_ERROR }, { NDMP3_UNDEFINED_ERR, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR }, END_ENUM_CONVERSION_TABLE }; int ndmp_3to9_log_file_request ( ndmp3_log_file_request *request3, ndmp9_log_file_request *request9) { request9->recovery_status = convert_enum_to_9 (ndmp_39_recovery_status, request3->error); CNVT_STRDUP_TO_9 (request3, request9, name); return 0; } int ndmp_9to3_log_file_request ( ndmp9_log_file_request *request9, ndmp3_log_file_request *request3) { request3->error = convert_enum_from_9 (ndmp_39_recovery_status, request9->recovery_status); CNVT_STRDUP_FROM_9 (request3, request9, name); return 0; } /* * ndmp_log_type */ struct enum_conversion ndmp_39_log_type[] = { { NDMP3_LOG_NORMAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_LOG_NORMAL, NDMP9_LOG_NORMAL }, { NDMP3_LOG_DEBUG, NDMP9_LOG_DEBUG }, { NDMP3_LOG_ERROR, NDMP9_LOG_ERROR }, { NDMP3_LOG_WARNING, NDMP9_LOG_WARNING }, END_ENUM_CONVERSION_TABLE }; int ndmp_3to9_log_message_request ( ndmp3_log_message_request *request3, ndmp9_log_message_request *request9) { CNVT_E_TO_9 (request3, request9, log_type, ndmp_39_log_type); CNVT_TO_9 (request3, request9, message_id); CNVT_STRDUP_TO_9 (request3, request9, entry); request9->associated_message_sequence.valid = NDMP9_VALIDITY_INVALID; request9->associated_message_sequence.value = NDMP9_INVALID_U_LONG; return 0; } int ndmp_9to3_log_message_request ( ndmp9_log_message_request *request9, ndmp3_log_message_request *request3) { CNVT_E_FROM_9 (request3, request9, log_type, ndmp_39_log_type); CNVT_FROM_9 (request3, request9, message_id); CNVT_STRDUP_TO_9 (request3, request9, entry); return 0; } /* * FILE HISTORY INTERFACES **************************************************************** */ /* * ndmp[_unix]_file_stat */ struct enum_conversion ndmp_39_file_type[] = { { NDMP3_FILE_OTHER, NDMP_INVALID_GENERAL, }, /* default */ { NDMP3_FILE_DIR, NDMP9_FILE_DIR }, { NDMP3_FILE_FIFO, NDMP9_FILE_FIFO }, { NDMP3_FILE_CSPEC, NDMP9_FILE_CSPEC }, { NDMP3_FILE_BSPEC, NDMP9_FILE_BSPEC }, { NDMP3_FILE_REG, NDMP9_FILE_REG }, { NDMP3_FILE_SLINK, NDMP9_FILE_SLINK }, { NDMP3_FILE_SOCK, NDMP9_FILE_SOCK }, { NDMP3_FILE_REGISTRY, NDMP9_FILE_REGISTRY }, { NDMP3_FILE_OTHER, NDMP9_FILE_OTHER }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_3to9_file_stat ( ndmp3_file_stat *fstat3, ndmp9_file_stat *fstat9, ndmp9_u_quad node, ndmp9_u_quad fh_info) { CNVT_E_TO_9 (fstat3, fstat9, ftype, ndmp_39_file_type); CNVT_VUL_TO_9 (fstat3, fstat9, mtime); CNVT_VUL_TO_9 (fstat3, fstat9, atime); CNVT_VUL_TO_9 (fstat3, fstat9, ctime); CNVT_VUL_TO_9x (fstat3, fstat9, owner, uid); CNVT_VUL_TO_9x (fstat3, fstat9, group, gid); CNVT_VUL_TO_9x (fstat3, fstat9, fattr, mode); CNVT_VUQ_TO_9 (fstat3, fstat9, size); CNVT_VUL_TO_9 (fstat3, fstat9, links); convert_valid_u_quad_to_9 (&node, &fstat9->node); convert_valid_u_quad_to_9 (&fh_info, &fstat9->fh_info); if (fstat3->invalid & NDMP3_FILE_STAT_ATIME_INVALID) CNVT_IUL_TO_9 (fstat9, atime); if (fstat3->invalid & NDMP3_FILE_STAT_CTIME_INVALID) CNVT_IUL_TO_9 (fstat9, ctime); if (fstat3->invalid & NDMP3_FILE_STAT_GROUP_INVALID) CNVT_IUL_TO_9 (fstat9, gid); return 0; } extern int ndmp_9to3_file_stat ( ndmp9_file_stat *fstat9, ndmp3_file_stat *fstat3) { CNVT_E_FROM_9 (fstat3, fstat9, ftype, ndmp_39_file_type); fstat3->fs_type = NDMP3_FS_UNIX; CNVT_VUL_FROM_9 (fstat3, fstat9, mtime); CNVT_VUL_FROM_9 (fstat3, fstat9, atime); CNVT_VUL_FROM_9 (fstat3, fstat9, ctime); CNVT_VUL_FROM_9x (fstat3, fstat9, owner, uid); CNVT_VUL_FROM_9x (fstat3, fstat9, group, gid); CNVT_VUL_FROM_9x (fstat3, fstat9, fattr, mode); CNVT_VUQ_FROM_9 (fstat3, fstat9, size); CNVT_VUL_FROM_9 (fstat3, fstat9, links); fstat3->invalid = 0; if (!fstat9->atime.valid) fstat3->invalid |= NDMP3_FILE_STAT_ATIME_INVALID; if (!fstat9->ctime.valid) fstat3->invalid |= NDMP3_FILE_STAT_CTIME_INVALID; if (!fstat9->gid.valid) fstat3->invalid |= NDMP3_FILE_STAT_GROUP_INVALID; /* fh_info ignored */ /* node ignored */ return 0; } /* * ndmp_fh_add_file_request */ int ndmp_3to9_fh_add_file_request ( ndmp3_fh_add_file_request *request3, ndmp9_fh_add_file_request *request9) { int n_ent = request3->files.files_len; unsigned int j; int i; ndmp9_file * table; table = NDMOS_MACRO_NEWN(ndmp9_file, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp3_file * ent3 = &request3->files.files_val[i]; ndmp3_file_name * file_name; ndmp3_file_stat * file_stat = 0; ndmp3_file_stat _file_stat; char * filename; ndmp9_file * ent9 = &table[i]; filename = "no-unix-name"; for (j = 0; j < ent3->names.names_len; j++) { file_name = &ent3->names.names_val[j]; if (file_name->fs_type == NDMP3_FS_UNIX) { filename = file_name->ndmp3_file_name_u.unix_name; break; } } for (j = 0; j < ent3->stats.stats_len; j++) { file_stat = &ent3->stats.stats_val[j]; if (file_stat->fs_type == NDMP3_FS_UNIX) { break; } } if (j >= ent3->stats.stats_len) { file_stat = &_file_stat; NDMOS_MACRO_ZEROFILL (file_stat); } ent9->unix_path = NDMOS_API_STRDUP(filename); ndmp_3to9_file_stat (file_stat, &ent9->fstat, ent3->node, ent3->fh_info); } request9->files.files_len = n_ent; request9->files.files_val = table; return 0; } int ndmp_9to3_fh_add_file_request ( ndmp9_fh_add_file_request *request9, ndmp3_fh_add_file_request *request3) { int n_ent = request9->files.files_len; int i; ndmp3_file * table; table = NDMOS_MACRO_NEWN(ndmp3_file, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_file * ent9 = &request9->files.files_val[i]; ndmp3_file * ent3 = &table[i]; ent3->names.names_val = NDMOS_MACRO_NEW(ndmp3_file_name); ent3->names.names_len = 1; ent3->stats.stats_val = NDMOS_MACRO_NEW(ndmp3_file_stat); ent3->stats.stats_len = 1; ent3->names.names_val[0].fs_type = NDMP3_FS_UNIX; ent3->names.names_val[0].ndmp3_file_name_u.unix_name = NDMOS_API_STRDUP(ent9->unix_path); ndmp_9to3_file_stat (&ent9->fstat, &ent3->stats.stats_val[0]); ent3->node = ent9->fstat.node.value; ent3->fh_info = ent9->fstat.fh_info.value; } request3->files.files_len = n_ent; request3->files.files_val = table; return 0; } /* * ndmp_fh_add_unix_dir */ int ndmp_3to9_fh_add_dir_request ( ndmp3_fh_add_dir_request *request3, ndmp9_fh_add_dir_request *request9) { int n_ent = request3->dirs.dirs_len; int i; unsigned int j; ndmp9_dir * table; table = NDMOS_MACRO_NEWN(ndmp9_dir, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp3_dir * ent3 = &request3->dirs.dirs_val[i]; ndmp3_file_name * file_name; char * filename; ndmp9_dir * ent9 = &table[i]; filename = "no-unix-name"; for (j = 0; j < ent3->names.names_len; j++) { file_name = &ent3->names.names_val[j]; if (file_name->fs_type == NDMP3_FS_UNIX) { filename = file_name->ndmp3_file_name_u.unix_name; break; } } ent9->unix_name = NDMOS_API_STRDUP(filename); ent9->node = ent3->node; ent9->parent = ent3->parent; } request9->dirs.dirs_len = n_ent; request9->dirs.dirs_val = table; return 0; } int ndmp_3to9_fh_add_dir_free_request (ndmp9_fh_add_dir_request *request9) { int i; if (request9) { if(request9->dirs.dirs_val) { int n_ent = request9->dirs.dirs_len; for (i = 0; i < n_ent; i++) { ndmp9_dir *ent9 = &request9->dirs.dirs_val[i]; if (ent9->unix_name) NDMOS_API_FREE(ent9->unix_name); ent9->unix_name = 0; } NDMOS_API_FREE(request9->dirs.dirs_val); } request9->dirs.dirs_val = 0; } return 0; } int ndmp_9to3_fh_add_dir_request ( ndmp9_fh_add_dir_request *request9, ndmp3_fh_add_dir_request *request3) { int n_ent = request9->dirs.dirs_len; int i; ndmp3_dir * table; table = NDMOS_MACRO_NEWN(ndmp3_dir, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_dir * ent9 = &request9->dirs.dirs_val[i]; ndmp3_dir * ent3 = &table[i]; ent3->names.names_val = NDMOS_MACRO_NEW(ndmp3_file_name); ent3->names.names_len = 1; ent3->names.names_val[0].fs_type = NDMP3_FS_UNIX; ent3->names.names_val[0].ndmp3_file_name_u.unix_name = NDMOS_API_STRDUP(ent9->unix_name); ent3->node = ent9->node; ent3->parent = ent9->parent; } request3->dirs.dirs_len = n_ent; request3->dirs.dirs_val = table; return 0; } int ndmp_9to3_fh_add_dir_free_request (ndmp3_fh_add_dir_request *request3) { int i; if (request3) { if(request3->dirs.dirs_val) { int n_ent = request3->dirs.dirs_len; for (i = 0; i < n_ent; i++) { ndmp3_dir *ent3 = &request3->dirs.dirs_val[i]; if (ent3->names.names_val) { if (ent3->names.names_val[0].ndmp3_file_name_u.unix_name) NDMOS_API_FREE(ent3->names.names_val[0].ndmp3_file_name_u.unix_name); ent3->names.names_val[0].ndmp3_file_name_u.unix_name = 0; NDMOS_API_FREE(ent3->names.names_val); } ent3->names.names_val = 0; } NDMOS_API_FREE(request3->dirs.dirs_val); } request3->dirs.dirs_val = 0; } return 0; } /* * ndmp_fh_add_node_request */ int ndmp_3to9_fh_add_node_request ( ndmp3_fh_add_node_request *request3, ndmp9_fh_add_node_request *request9) { int n_ent = request3->nodes.nodes_len; int i; unsigned int j; ndmp9_node * table; table = NDMOS_MACRO_NEWN(ndmp9_node, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp3_node * ent3 = &request3->nodes.nodes_val[i]; ndmp3_file_stat * file_stat = 0; ndmp3_file_stat _file_stat; ndmp9_node * ent9 = &table[i]; for (j = 0; j < ent3->stats.stats_len; j++) { file_stat = &ent3->stats.stats_val[j]; if (file_stat->fs_type == NDMP3_FS_UNIX) { break; } } if (j >= ent3->stats.stats_len) { file_stat = &_file_stat; NDMOS_MACRO_ZEROFILL (file_stat); } ndmp_3to9_file_stat (file_stat, &ent9->fstat, ent3->node, ent3->fh_info); } request9->nodes.nodes_len = n_ent; request9->nodes.nodes_val = table; return 0; } int ndmp_3to9_fh_add_node_free_request (ndmp9_fh_add_node_request *request9) { if (request9) { if(request9->nodes.nodes_val) { NDMOS_API_FREE(request9->nodes.nodes_val); } request9->nodes.nodes_val = 0; } return 0; } int ndmp_9to3_fh_add_node_request ( ndmp9_fh_add_node_request *request9, ndmp3_fh_add_node_request *request3) { int n_ent = request9->nodes.nodes_len; int i; ndmp3_node * table; table = NDMOS_MACRO_NEWN(ndmp3_node, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_node * ent9 = &request9->nodes.nodes_val[i]; ndmp3_node * ent3 = &table[i]; ent3->stats.stats_val = NDMOS_MACRO_NEW(ndmp3_file_stat); ent3->stats.stats_len = 1; ndmp_9to3_file_stat (&ent9->fstat, &ent3->stats.stats_val[0]); ent3->node = ent9->fstat.node.value; ent3->fh_info = ent9->fstat.fh_info.value; } request3->nodes.nodes_len = n_ent; request3->nodes.nodes_val = table; return 0; } int ndmp_9to3_fh_add_node_free_request (ndmp3_fh_add_node_request *request3) { if (request3) { if(request3->nodes.nodes_val) { NDMOS_API_FREE(request3->nodes.nodes_val); } request3->nodes.nodes_val = 0; } return 0; } /* * request/reply translation */ #define NO_ARG_REQUEST \ ndmp_xtox_no_arguments, ndmp_xtox_no_arguments #define JUST_ERROR_REPLY \ ndmp_3to9_error, ndmp_9to3_error #define NO_ARG_REQUEST_JUST_ERROR_REPLY \ NO_ARG_REQUEST, JUST_ERROR_REPLY #define NO_MEMUSED_REQUEST \ ndmp_xtox_no_memused, ndmp_xtox_no_memused #define NO_MEMUSED_REPLY \ ndmp_xtox_no_memused, ndmp_xtox_no_memused #define NO_MEMUSED \ ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused struct reqrep_xlate ndmp3_reqrep_xlate_table[] = { { NDMP3_CONNECT_OPEN, NDMP9_CONNECT_OPEN, ndmp_3to9_connect_open_request, ndmp_9to3_connect_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONNECT_CLIENT_AUTH, NDMP9_CONNECT_CLIENT_AUTH, ndmp_3to9_connect_client_auth_request, ndmp_9to3_connect_client_auth_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONNECT_CLOSE, NDMP9_CONNECT_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, /* actually no reply */ NO_MEMUSED /* no memory free routines written yet */ }, #ifdef notyet { NDMP3_CONNECT_SERVER_AUTH, NDMP9_CONNECT_SERVER_AUTH, ndmp_3to9_connect_server_auth_request, ndmp_9to3_connect_server_auth_request, ndmp_3to9_connect_server_auth_reply, ndmp_9to3_connect_server_auth_reply, NO_MEMUSED /* no memory free routines written yet */ }, #endif /* notyet */ { NDMP3_CONFIG_GET_HOST_INFO, NDMP9_CONFIG_GET_HOST_INFO, NO_ARG_REQUEST, ndmp_3to9_config_get_host_info_reply, ndmp_9to3_config_get_host_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_CONNECTION_TYPE, NDMP9_CONFIG_GET_CONNECTION_TYPE, NO_ARG_REQUEST, ndmp_3to9_config_get_connection_type_reply, ndmp_9to3_config_get_connection_type_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_AUTH_ATTR, NDMP9_CONFIG_GET_AUTH_ATTR, ndmp_3to9_config_get_auth_attr_request, ndmp_9to3_config_get_auth_attr_request, ndmp_3to9_config_get_auth_attr_reply, ndmp_9to3_config_get_auth_attr_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_BUTYPE_INFO, NDMP9_CONFIG_GET_BUTYPE_INFO, NO_ARG_REQUEST, ndmp_3to9_config_get_butype_info_reply, ndmp_9to3_config_get_butype_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_FS_INFO, NDMP9_CONFIG_GET_FS_INFO, NO_ARG_REQUEST, ndmp_3to9_config_get_fs_info_reply, ndmp_9to3_config_get_fs_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_TAPE_INFO, NDMP9_CONFIG_GET_TAPE_INFO, NO_ARG_REQUEST, ndmp_3to9_config_get_tape_info_reply, ndmp_9to3_config_get_tape_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_SCSI_INFO, NDMP9_CONFIG_GET_SCSI_INFO, NO_ARG_REQUEST, ndmp_3to9_config_get_scsi_info_reply, ndmp_9to3_config_get_scsi_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_CONFIG_GET_SERVER_INFO, NDMP9_CONFIG_GET_SERVER_INFO, NO_ARG_REQUEST, ndmp_3to9_config_get_server_info_reply, ndmp_9to3_config_get_server_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_OPEN, NDMP9_SCSI_OPEN, ndmp_3to9_scsi_open_request, ndmp_9to3_scsi_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_CLOSE, NDMP9_SCSI_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_GET_STATE, NDMP9_SCSI_GET_STATE, NO_ARG_REQUEST, ndmp_3to9_scsi_get_state_reply, ndmp_9to3_scsi_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_SET_TARGET, NDMP9_SCSI_SET_TARGET, ndmp_3to9_scsi_set_target_request, ndmp_9to3_scsi_set_target_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_RESET_DEVICE, NDMP9_SCSI_RESET_DEVICE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_RESET_BUS, NDMP9_SCSI_RESET_BUS, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_SCSI_EXECUTE_CDB, NDMP9_SCSI_EXECUTE_CDB, ndmp_3to9_execute_cdb_request, ndmp_9to3_execute_cdb_request, ndmp_3to9_execute_cdb_reply, ndmp_9to3_execute_cdb_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_OPEN, NDMP9_TAPE_OPEN, ndmp_3to9_tape_open_request, ndmp_9to3_tape_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_CLOSE, NDMP9_TAPE_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_GET_STATE, NDMP9_TAPE_GET_STATE, NO_ARG_REQUEST, ndmp_3to9_tape_get_state_reply, ndmp_9to3_tape_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_MTIO, NDMP9_TAPE_MTIO, ndmp_3to9_tape_mtio_request, ndmp_9to3_tape_mtio_request, ndmp_3to9_tape_mtio_reply, ndmp_9to3_tape_mtio_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_WRITE, NDMP9_TAPE_WRITE, ndmp_3to9_tape_write_request, ndmp_9to3_tape_write_request, ndmp_3to9_tape_write_reply, ndmp_9to3_tape_write_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_READ, NDMP9_TAPE_READ, ndmp_3to9_tape_read_request, ndmp_9to3_tape_read_request, ndmp_3to9_tape_read_reply, ndmp_9to3_tape_read_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_TAPE_EXECUTE_CDB, NDMP9_TAPE_EXECUTE_CDB, ndmp_3to9_execute_cdb_request, ndmp_9to3_execute_cdb_request, ndmp_3to9_execute_cdb_reply, ndmp_9to3_execute_cdb_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_GET_STATE, NDMP9_DATA_GET_STATE, NO_ARG_REQUEST, ndmp_3to9_data_get_state_reply, ndmp_9to3_data_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_START_BACKUP, NDMP9_DATA_START_BACKUP, ndmp_3to9_data_start_backup_request, ndmp_9to3_data_start_backup_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_START_RECOVER, NDMP9_DATA_START_RECOVER, ndmp_3to9_data_start_recover_request, ndmp_9to3_data_start_recover_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_ABORT, NDMP9_DATA_ABORT, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_GET_ENV, NDMP9_DATA_GET_ENV, NO_ARG_REQUEST, ndmp_3to9_data_get_env_reply, ndmp_9to3_data_get_env_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_STOP, NDMP9_DATA_STOP, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_LISTEN, NDMP9_DATA_LISTEN, ndmp_3to9_data_listen_request, ndmp_9to3_data_listen_request, ndmp_3to9_data_listen_reply, ndmp_9to3_data_listen_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_CONNECT, NDMP9_DATA_CONNECT, ndmp_3to9_data_connect_request, ndmp_9to3_data_connect_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_DATA_START_RECOVER_FILEHIST, NDMP9_DATA_START_RECOVER_FILEHIST, ndmp_3to9_data_start_recover_request, ndmp_9to3_data_start_recover_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_NOTIFY_DATA_HALTED, NDMP9_NOTIFY_DATA_HALTED, ndmp_3to9_notify_data_halted_request, ndmp_9to3_notify_data_halted_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_NOTIFY_CONNECTED, NDMP9_NOTIFY_CONNECTED, ndmp_3to9_notify_connected_request, ndmp_9to3_notify_connected_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_NOTIFY_MOVER_HALTED, NDMP9_NOTIFY_MOVER_HALTED, ndmp_3to9_notify_mover_halted_request, ndmp_9to3_notify_mover_halted_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_NOTIFY_MOVER_PAUSED, NDMP9_NOTIFY_MOVER_PAUSED, ndmp_3to9_notify_mover_paused_request, ndmp_9to3_notify_mover_paused_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_NOTIFY_DATA_READ, NDMP9_NOTIFY_DATA_READ, ndmp_3to9_notify_data_read_request, ndmp_9to3_notify_data_read_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_LOG_FILE, NDMP9_LOG_FILE, ndmp_3to9_log_file_request, ndmp_9to3_log_file_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_LOG_MESSAGE, NDMP9_LOG_MESSAGE, ndmp_3to9_log_message_request, ndmp_9to3_log_message_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_FH_ADD_FILE, NDMP9_FH_ADD_FILE, ndmp_3to9_fh_add_file_request, ndmp_9to3_fh_add_file_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_FH_ADD_DIR, NDMP9_FH_ADD_DIR, ndmp_3to9_fh_add_dir_request, ndmp_9to3_fh_add_dir_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_3to9_fh_add_dir_free_request, ndmp_9to3_fh_add_dir_free_request, NO_MEMUSED_REPLY }, { NDMP3_FH_ADD_NODE, NDMP9_FH_ADD_NODE, ndmp_3to9_fh_add_node_request, ndmp_9to3_fh_add_node_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_3to9_fh_add_node_free_request, ndmp_9to3_fh_add_node_free_request, NO_MEMUSED_REPLY }, { NDMP3_MOVER_GET_STATE, NDMP9_MOVER_GET_STATE, NO_ARG_REQUEST, ndmp_3to9_mover_get_state_reply, ndmp_9to3_mover_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_LISTEN, NDMP9_MOVER_LISTEN, ndmp_3to9_mover_listen_request, ndmp_9to3_mover_listen_request, ndmp_3to9_mover_listen_reply, ndmp_9to3_mover_listen_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_CONNECT, NDMP9_MOVER_CONNECT, ndmp_3to9_mover_connect_request, ndmp_9to3_mover_connect_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_CONTINUE, NDMP9_MOVER_CONTINUE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_ABORT, NDMP9_MOVER_ABORT, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_STOP, NDMP9_MOVER_STOP, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_SET_WINDOW, NDMP9_MOVER_SET_WINDOW, ndmp_3to9_mover_set_window_request, ndmp_9to3_mover_set_window_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_READ, NDMP9_MOVER_READ, ndmp_3to9_mover_read_request, ndmp_9to3_mover_read_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_CLOSE, NDMP9_MOVER_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP3_MOVER_SET_RECORD_SIZE, NDMP9_MOVER_SET_RECORD_SIZE, ndmp_3to9_mover_set_record_size_request, ndmp_9to3_mover_set_record_size_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, /* ndmp_mover_connnect TBD */ { 0 }, }; #endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp3_translate.h000066400000000000000000000070451263011562700214420ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_NDMP3 #ifdef __cplusplus extern "C" { #endif extern int ndmp_3to9_error ( ndmp3_error *error3, ndmp9_error *error9); extern int ndmp_9to3_error ( ndmp9_error *error9, ndmp3_error *error3); extern int ndmp_3to9_data_get_state_reply ( ndmp3_data_get_state_reply *reply3, ndmp9_data_get_state_reply *reply9); extern int ndmp_9to3_data_get_state_reply ( ndmp9_data_get_state_reply *reply9, ndmp3_data_get_state_reply *reply3); extern int ndmp_3to9_tape_get_state_reply ( ndmp3_tape_get_state_reply *reply3, ndmp9_tape_get_state_reply *reply9); extern int ndmp_9to3_tape_get_state_reply ( ndmp9_tape_get_state_reply *reply9, ndmp3_tape_get_state_reply *reply3); extern int ndmp_3to9_mover_get_state_reply ( ndmp3_mover_get_state_reply *reply3, ndmp9_mover_get_state_reply *reply9); extern int ndmp_9to3_mover_get_state_reply ( ndmp9_mover_get_state_reply *reply9, ndmp3_mover_get_state_reply *reply3); extern int ndmp_3to9_addr ( ndmp3_addr *addr3, ndmp9_addr *addr9); extern int ndmp_9to3_addr ( ndmp9_addr *addr9, ndmp3_addr *addr3); extern int ndmp_3to9_file_stat ( ndmp3_file_stat *fstat3, ndmp9_file_stat *fstat9, ndmp9_u_quad node, ndmp9_u_quad fh_info); extern int ndmp_9to3_file_stat ( ndmp9_file_stat *fstat9, ndmp3_file_stat *fstat3); extern int ndmp_3to9_pval ( ndmp3_pval *pval3, ndmp9_pval *pval9); extern int ndmp_9to3_pval ( ndmp9_pval *pval9, ndmp3_pval *pval3); extern int ndmp_3to9_pval_vec ( ndmp3_pval *pval3, ndmp9_pval *pval9, unsigned n_pval); extern int ndmp_9to3_pval_vec ( ndmp9_pval *pval9, ndmp3_pval *pval3, unsigned n_pval); extern int ndmp_3to9_name ( ndmp3_name *name3, ndmp9_name *name9); extern int ndmp_9to3_name ( ndmp9_name *name9, ndmp3_name *name3); extern int ndmp_3to9_name_vec ( ndmp3_name *name3, ndmp9_name *name9, unsigned n_name); extern int ndmp_9to3_name_vec ( ndmp9_name *name9, ndmp3_name *name3, unsigned n_name); extern struct reqrep_xlate ndmp3_reqrep_xlate_table[]; #ifdef __cplusplus } #endif #endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp3_xmt.c000066400000000000000000000240041263011562700202420ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP3 #define xdr_ndmp3_connect_close_request xdr_void #define xdr_ndmp3_connect_close_reply xdr_void #define xdr_ndmp3_config_get_host_info_request xdr_void #define xdr_ndmp3_config_get_connection_type_request xdr_void #define xdr_ndmp3_config_get_butype_info_request xdr_void #define xdr_ndmp3_config_get_fs_info_request xdr_void #define xdr_ndmp3_config_get_tape_info_request xdr_void #define xdr_ndmp3_config_get_scsi_info_request xdr_void #define xdr_ndmp3_config_get_server_info_request xdr_void #define xdr_ndmp3_scsi_close_request xdr_void #define xdr_ndmp3_scsi_get_state_request xdr_void #define xdr_ndmp3_scsi_reset_device_request xdr_void #define xdr_ndmp3_scsi_reset_bus_request xdr_void #define xdr_ndmp3_tape_close_request xdr_void #define xdr_ndmp3_tape_get_state_request xdr_void #define xdr_ndmp3_data_get_state_request xdr_void #define xdr_ndmp3_data_abort_request xdr_void #define xdr_ndmp3_data_get_env_request xdr_void #define xdr_ndmp3_data_stop_request xdr_void #define xdr_ndmp3_notify_data_halted_reply 0 #define xdr_ndmp3_notify_connected_reply 0 #define xdr_ndmp3_notify_mover_halted_reply 0 #define xdr_ndmp3_notify_mover_paused_reply 0 #define xdr_ndmp3_notify_data_read_reply 0 #define xdr_ndmp3_log_message_reply 0 #define xdr_ndmp3_log_file_reply 0 #define xdr_ndmp3_fh_add_file_reply 0 #define xdr_ndmp3_fh_add_dir_reply 0 #define xdr_ndmp3_fh_add_node_reply 0 #define xdr_ndmp3_mover_get_state_request xdr_void #define xdr_ndmp3_mover_continue_request xdr_void #define xdr_ndmp3_mover_abort_request xdr_void #define xdr_ndmp3_mover_stop_request xdr_void #define xdr_ndmp3_mover_close_request xdr_void struct ndmp_xdr_message_table ndmp3_xdr_message_table[] = { { NDMP3_CONNECT_OPEN, xdr_ndmp3_connect_open_request, xdr_ndmp3_connect_open_reply, }, { NDMP3_CONNECT_CLIENT_AUTH, xdr_ndmp3_connect_client_auth_request, xdr_ndmp3_connect_client_auth_reply, }, { NDMP3_CONNECT_CLOSE, xdr_ndmp3_connect_close_request, xdr_ndmp3_connect_close_reply, }, { NDMP3_CONNECT_SERVER_AUTH, xdr_ndmp3_connect_server_auth_request, xdr_ndmp3_connect_server_auth_reply, }, { NDMP3_CONFIG_GET_HOST_INFO, xdr_ndmp3_config_get_host_info_request, xdr_ndmp3_config_get_host_info_reply, }, { NDMP3_CONFIG_GET_CONNECTION_TYPE, xdr_ndmp3_config_get_connection_type_request, xdr_ndmp3_config_get_connection_type_reply, }, { NDMP3_CONFIG_GET_AUTH_ATTR, xdr_ndmp3_config_get_auth_attr_request, xdr_ndmp3_config_get_auth_attr_reply, }, { NDMP3_CONFIG_GET_BUTYPE_INFO, xdr_ndmp3_config_get_butype_info_request, xdr_ndmp3_config_get_butype_info_reply, }, { NDMP3_CONFIG_GET_FS_INFO, xdr_ndmp3_config_get_fs_info_request, xdr_ndmp3_config_get_fs_info_reply, }, { NDMP3_CONFIG_GET_TAPE_INFO, xdr_ndmp3_config_get_tape_info_request, xdr_ndmp3_config_get_tape_info_reply, }, { NDMP3_CONFIG_GET_SCSI_INFO, xdr_ndmp3_config_get_scsi_info_request, xdr_ndmp3_config_get_scsi_info_reply, }, { NDMP3_CONFIG_GET_SERVER_INFO, xdr_ndmp3_config_get_server_info_request, xdr_ndmp3_config_get_server_info_reply, }, { NDMP3_SCSI_OPEN, xdr_ndmp3_scsi_open_request, xdr_ndmp3_scsi_open_reply, }, { NDMP3_SCSI_CLOSE, xdr_ndmp3_scsi_close_request, xdr_ndmp3_scsi_close_reply, }, { NDMP3_SCSI_GET_STATE, xdr_ndmp3_scsi_get_state_request, xdr_ndmp3_scsi_get_state_reply, }, { NDMP3_SCSI_SET_TARGET, xdr_ndmp3_scsi_set_target_request, xdr_ndmp3_scsi_set_target_reply, }, { NDMP3_SCSI_RESET_DEVICE, xdr_ndmp3_scsi_reset_device_request, xdr_ndmp3_scsi_reset_device_reply, }, { NDMP3_SCSI_RESET_BUS, xdr_ndmp3_scsi_reset_bus_request, xdr_ndmp3_scsi_reset_bus_reply, }, { NDMP3_SCSI_EXECUTE_CDB, xdr_ndmp3_scsi_execute_cdb_request, xdr_ndmp3_scsi_execute_cdb_reply, }, { NDMP3_TAPE_OPEN, xdr_ndmp3_tape_open_request, xdr_ndmp3_tape_open_reply, }, { NDMP3_TAPE_CLOSE, xdr_ndmp3_tape_close_request, xdr_ndmp3_tape_close_reply, }, { NDMP3_TAPE_GET_STATE, xdr_ndmp3_tape_get_state_request, xdr_ndmp3_tape_get_state_reply, }, { NDMP3_TAPE_MTIO, xdr_ndmp3_tape_mtio_request, xdr_ndmp3_tape_mtio_reply, }, { NDMP3_TAPE_WRITE, xdr_ndmp3_tape_write_request, xdr_ndmp3_tape_write_reply, }, { NDMP3_TAPE_READ, xdr_ndmp3_tape_read_request, xdr_ndmp3_tape_read_reply, }, { NDMP3_TAPE_EXECUTE_CDB, xdr_ndmp3_tape_execute_cdb_request, xdr_ndmp3_tape_execute_cdb_reply, }, { NDMP3_DATA_GET_STATE, xdr_ndmp3_data_get_state_request, xdr_ndmp3_data_get_state_reply, }, { NDMP3_DATA_START_BACKUP, xdr_ndmp3_data_start_backup_request, xdr_ndmp3_data_start_backup_reply, }, { NDMP3_DATA_START_RECOVER, xdr_ndmp3_data_start_recover_request, xdr_ndmp3_data_start_recover_reply, }, { NDMP3_DATA_START_RECOVER_FILEHIST, xdr_ndmp3_data_start_recover_filehist_request, xdr_ndmp3_data_start_recover_filehist_reply, }, { NDMP3_DATA_ABORT, xdr_ndmp3_data_abort_request, xdr_ndmp3_data_abort_reply, }, { NDMP3_DATA_GET_ENV, xdr_ndmp3_data_get_env_request, xdr_ndmp3_data_get_env_reply, }, { NDMP3_DATA_STOP, xdr_ndmp3_data_stop_request, xdr_ndmp3_data_stop_reply, }, { NDMP3_DATA_LISTEN, xdr_ndmp3_data_listen_request, xdr_ndmp3_data_listen_reply, }, { NDMP3_DATA_CONNECT, xdr_ndmp3_data_connect_request, xdr_ndmp3_data_connect_reply, }, { NDMP3_NOTIFY_DATA_HALTED, xdr_ndmp3_notify_data_halted_request, xdr_ndmp3_notify_data_halted_reply, }, { NDMP3_NOTIFY_CONNECTED, xdr_ndmp3_notify_connected_request, xdr_ndmp3_notify_connected_reply, }, { NDMP3_NOTIFY_MOVER_HALTED, xdr_ndmp3_notify_mover_halted_request, xdr_ndmp3_notify_mover_halted_reply, }, { NDMP3_NOTIFY_MOVER_PAUSED, xdr_ndmp3_notify_mover_paused_request, xdr_ndmp3_notify_mover_paused_reply, }, { NDMP3_NOTIFY_DATA_READ, xdr_ndmp3_notify_data_read_request, xdr_ndmp3_notify_data_read_reply, }, { NDMP3_LOG_FILE, xdr_ndmp3_log_file_request, xdr_ndmp3_log_file_reply, }, { NDMP3_LOG_MESSAGE, xdr_ndmp3_log_message_request, xdr_ndmp3_log_message_reply, }, { NDMP3_FH_ADD_FILE, xdr_ndmp3_fh_add_file_request, xdr_ndmp3_fh_add_file_reply, }, { NDMP3_FH_ADD_DIR, xdr_ndmp3_fh_add_dir_request, xdr_ndmp3_fh_add_dir_reply, }, { NDMP3_FH_ADD_NODE, xdr_ndmp3_fh_add_node_request, xdr_ndmp3_fh_add_node_reply, }, { NDMP3_MOVER_GET_STATE, xdr_ndmp3_mover_get_state_request, xdr_ndmp3_mover_get_state_reply, }, { NDMP3_MOVER_LISTEN, xdr_ndmp3_mover_listen_request, xdr_ndmp3_mover_listen_reply, }, { NDMP3_MOVER_CONTINUE, xdr_ndmp3_mover_continue_request, xdr_ndmp3_mover_continue_reply, }, { NDMP3_MOVER_ABORT, xdr_ndmp3_mover_abort_request, xdr_ndmp3_mover_abort_reply, }, { NDMP3_MOVER_STOP, xdr_ndmp3_mover_stop_request, xdr_ndmp3_mover_stop_reply, }, { NDMP3_MOVER_SET_WINDOW, xdr_ndmp3_mover_set_window_request, xdr_ndmp3_mover_set_window_reply, }, { NDMP3_MOVER_READ, xdr_ndmp3_mover_read_request, xdr_ndmp3_mover_read_reply, }, { NDMP3_MOVER_CLOSE, xdr_ndmp3_mover_close_request, xdr_ndmp3_mover_close_reply, }, { NDMP3_MOVER_SET_RECORD_SIZE, xdr_ndmp3_mover_set_record_size_request, xdr_ndmp3_mover_set_record_size_reply, }, { NDMP3_MOVER_CONNECT, xdr_ndmp3_mover_connect_request, xdr_ndmp3_mover_connect_reply, }, {0} }; /* * XDR unsigned long integers * same as xdr_long - open coded to save a proc call! */ bool_t xdr_ndmp3_u_quad(xdrs, objp) register XDR *xdrs; ndmp3_u_quad *objp; { uint32_t hi, lo; switch (xdrs->x_op) { case XDR_DECODE: #if defined(_LP64) if (XDR_GETINT32(xdrs, (int32_t *)&hi) && XDR_GETINT32(xdrs, (int32_t *)&lo)) { #else if (XDR_GETLONG(xdrs, (long *)&hi) && XDR_GETLONG(xdrs, (long *)&lo)) { #endif *objp = ((uint64_t)hi << 32) | (lo & 0xffffffff); return TRUE; } break; case XDR_ENCODE: hi = *objp >> 32; lo = *objp & 0xffffffff; #if defined(_LP64) return XDR_PUTINT32(xdrs, (int32_t *)&hi) && XDR_PUTINT32(xdrs, (int32_t *)&lo); #else return XDR_PUTLONG(xdrs, (long *)&hi) && XDR_PUTLONG(xdrs, (long *)&lo); #endif case XDR_FREE: return (TRUE); } return (FALSE); } #endif /* !NDMOS_OPTION_NO_NDMP3 */ bareos-Release-14.2.6/src/ndmp/ndmp4.x000066400000000000000000000475241263011562700174140ustar00rootroot00000000000000/* * Copyright (c) 2000,2001 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ /* * ndmp4.x * * Description : NDMP protocol rpcgen file. * * Copyright (c) 1999 Intelliguard Software, Network Appliance. * All Rights Reserved. * * $Id: ndmp.x,v 1.11 1998/05/26 03:52:12 tim Exp $ */ %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 %#pragma GCC diagnostic ignored "-Wunused-variable" %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 470 %#pragma GCC diagnostic ignored "-Wunprototyped-calls" %#endif %#endif %#ifndef NDMOS_OPTION_NO_NDMP4 const NDMP4VER = 4; const NDMP4PORT = 10000; %#define ndmp4_u_quad uint64_t %extern bool_t xdr_ndmp4_u_quad(); struct _ndmp4_u_quad { uint32_t high; uint32_t low; }; enum ndmp4_header_message_type { NDMP4_MESSAGE_REQUEST, NDMP4_MESSAGE_REPLY }; const NDMP4_MESSAGE_POST = NDMP4_MESSAGE_REQUEST; /* Note: because of extensibility, this is */ /* Not a complete list of errors. */ enum ndmp4_error { NDMP4_NO_ERR = 0, NDMP4_NOT_SUPPORTED_ERR = 1, NDMP4_DEVICE_BUSY_ERR = 2, NDMP4_DEVICE_OPENED_ERR = 3, NDMP4_NOT_AUTHORIZED_ERR = 4, NDMP4_PERMISSION_ERR = 5, NDMP4_DEV_NOT_OPEN_ERR = 6, NDMP4_IO_ERR = 7, NDMP4_TIMEOUT_ERR = 8, NDMP4_ILLEGAL_ARGS_ERR = 9, NDMP4_NO_TAPE_LOADED_ERR = 10, NDMP4_WRITE_PROTECT_ERR = 11, NDMP4_EOF_ERR = 12, NDMP4_EOM_ERR = 13, NDMP4_FILE_NOT_FOUND_ERR = 14, NDMP4_BAD_FILE_ERR = 15, NDMP4_NO_DEVICE_ERR = 16, NDMP4_NO_BUS_ERR = 17, NDMP4_XDR_DECODE_ERR = 18, NDMP4_ILLEGAL_STATE_ERR = 19, NDMP4_UNDEFINED_ERR = 20, NDMP4_XDR_ENCODE_ERR = 21, NDMP4_NO_MEM_ERR = 22, NDMP4_CONNECT_ERR = 23, NDMP4_SEQUENCE_NUM_ERR = 24, NDMP4_READ_IN_PROGRESS_ERR = 25, NDMP4_PRECONDITION_ERR = 26, NDMP4_CLASS_NOT_SUPPORTED = 27, NDMP4_VERSION_NOT_SUPPORTED = 28, NDMP4_EXT_DUPL_CLASSES = 29, NDMP4_EXT_DN_ILLEGAL = 30 }; /* Note: Because of extensibility, this */ /* is not a complete list of messages */ enum ndmp4_message { /* CONNECT INTERFACE */ NDMP4_CONNECT_OPEN = 0x900, NDMP4_CONNECT_CLIENT_AUTH = 0x901, NDMP4_CONNECT_CLOSE = 0x902, NDMP4_CONNECT_SERVER_AUTH = 0x903, /* CONFIG INTERFACE */ NDMP4_CONFIG_GET_HOST_INFO = 0x100, NDMP4_CONFIG_GET_CONNECTION_TYPE = 0x102, NDMP4_CONFIG_GET_AUTH_ATTR = 0x103, NDMP4_CONFIG_GET_BUTYPE_INFO = 0x104, NDMP4_CONFIG_GET_FS_INFO = 0x105, NDMP4_CONFIG_GET_TAPE_INFO = 0x106, NDMP4_CONFIG_GET_SCSI_INFO = 0x107, NDMP4_CONFIG_GET_SERVER_INFO = 0x108, NDMP4_CONFIG_SET_EXT_LIST = 0x109, NDMP4_CONFIG_GET_EXT_LIST = 0x10A, /* SCSI INTERFACE */ NDMP4_SCSI_OPEN = 0x200, NDMP4_SCSI_CLOSE = 0x201, NDMP4_SCSI_GET_STATE = 0x202, NDMP4_SCSI_RESET_DEVICE = 0x204, NDMP4_SCSI_EXECUTE_CDB = 0x206, /* TAPE INTERFACE */ NDMP4_TAPE_OPEN = 0x300, NDMP4_TAPE_CLOSE = 0x301, NDMP4_TAPE_GET_STATE = 0x302, NDMP4_TAPE_MTIO = 0x303, NDMP4_TAPE_WRITE = 0x304, NDMP4_TAPE_READ = 0x305, NDMP4_TAPE_EXECUTE_CDB = 0x307, /* DATA INTERFACE */ NDMP4_DATA_GET_STATE = 0x400, NDMP4_DATA_START_BACKUP = 0x401, NDMP4_DATA_START_RECOVER = 0x402, NDMP4_DATA_ABORT = 0x403, NDMP4_DATA_GET_ENV = 0x404, NDMP4_DATA_STOP = 0x407, NDMP4_DATA_LISTEN = 0x409, NDMP4_DATA_CONNECT = 0x40A, NDMP4_DATA_START_RECOVER_FILEHIST = 0x40B, /* NOTIFY INTERFACE */ NDMP4_NOTIFY_DATA_HALTED = 0x501, NDMP4_NOTIFY_CONNECTION_STATUS = 0x502, NDMP4_NOTIFY_MOVER_HALTED = 0x503, NDMP4_NOTIFY_MOVER_PAUSED = 0x504, NDMP4_NOTIFY_DATA_READ = 0x505, /* LOGGING INTERFACE */ NDMP4_LOG_FILE = 0x602, NDMP4_LOG_MESSAGE = 0x603, /* FILE HISTORY INTERFACE */ NDMP4_FH_ADD_FILE = 0x703, NDMP4_FH_ADD_DIR = 0x704, NDMP4_FH_ADD_NODE = 0x705, /* MOVER INTERFACE */ NDMP4_MOVER_GET_STATE = 0xA00, NDMP4_MOVER_LISTEN = 0xA01, NDMP4_MOVER_CONTINUE = 0xA02, NDMP4_MOVER_ABORT = 0xA03, NDMP4_MOVER_STOP = 0xA04, NDMP4_MOVER_SET_WINDOW = 0xA05, NDMP4_MOVER_READ = 0xA06, NDMP4_MOVER_CLOSE = 0xA07, NDMP4_MOVER_SET_RECORD_SIZE = 0xA08, NDMP4_MOVER_CONNECT = 0xA09, /* EXTENSIBILITY */ /* Reserved for Standard extensions */ NDMP4_EXT_STANDARD_BASE = 0x10000, /* Reserved for Proprietary extensions */ NDMP4_EXT_PROPRIETARY_BASE = 0x20000000 }; struct ndmp4_header { uint32_t sequence; uint32_t time_stamp; ndmp4_header_message_type message_type; ndmp4_message message_code; uint32_t reply_sequence; ndmp4_error error_code; }; struct ndmp4_pval { string name<>; string value<>; }; /* Connect messages */ struct ndmp4_connect_open_request { uint16_t protocol_version; }; struct ndmp4_connect_open_reply { ndmp4_error error; }; enum ndmp4_auth_type { NDMP4_AUTH_NONE=0, NDMP4_AUTH_TEXT=1, NDMP4_AUTH_MD5=2 }; struct ndmp4_auth_text { string auth_id<>; string auth_password<>; }; struct ndmp4_auth_md5 { string auth_id<>; opaque auth_digest[16]; }; union ndmp4_auth_data switch (enum ndmp4_auth_type auth_type) { case NDMP4_AUTH_NONE: void; case NDMP4_AUTH_TEXT: struct ndmp4_auth_text auth_text; case NDMP4_AUTH_MD5: struct ndmp4_auth_md5 auth_md5; }; union ndmp4_auth_attr switch (enum ndmp4_auth_type auth_type) { case NDMP4_AUTH_NONE: void; case NDMP4_AUTH_TEXT: void; case NDMP4_AUTH_MD5: opaque challenge[64]; }; struct ndmp4_connect_client_auth_request { ndmp4_auth_data auth_data; }; struct ndmp4_connect_client_auth_reply { ndmp4_error error; }; struct ndmp4_connect_server_auth_request { ndmp4_auth_attr client_attr; }; struct ndmp4_connect_server_auth_reply { ndmp4_error error; ndmp4_auth_data server_result; }; struct ndmp4_config_get_host_info_reply { ndmp4_error error; string hostname<>; string os_type<>; string os_vers<>; string hostid<>; }; struct ndmp4_config_get_server_info_reply { ndmp4_error error; string vendor_name<>; string product_name<>; string revision_number<>; ndmp4_auth_type auth_type<>; }; enum ndmp4_addr_type { NDMP4_ADDR_LOCAL=0, NDMP4_ADDR_TCP=1, NDMP4_ADDR_RESERVED=2, NDMP4_ADDR_IPC=3 }; struct ndmp4_config_get_connection_type_reply { ndmp4_error error; ndmp4_addr_type addr_types<>; }; struct ndmp4_config_get_auth_attr_request { ndmp4_auth_type auth_type; }; struct ndmp4_config_get_auth_attr_reply { ndmp4_error error; ndmp4_auth_attr server_attr; }; const NDMP4_BUTYPE_BACKUP_FILELIST = 0x0002; const NDMP4_BUTYPE_RECOVER_FILELIST = 0x0004; const NDMP4_BUTYPE_BACKUP_DIRECT = 0x0008; const NDMP4_BUTYPE_RECOVER_DIRECT = 0x0010; const NDMP4_BUTYPE_BACKUP_INCREMENTAL = 0x0020; const NDMP4_BUTYPE_RECOVER_INCREMENTAL = 0x0040; const NDMP4_BUTYPE_BACKUP_UTF8 = 0x0080; const NDMP4_BUTYPE_RECOVER_UTF8 = 0x0100; const NDMP4_BUTYPE_BACKUP_FH_FILE = 0x0200; const NDMP4_BUTYPE_BACKUP_FH_DIR = 0x0400; const NDMP4_BUTYPE_RECOVER_FILEHIST = 0x0800; const NDMP4_BUTYPE_RECOVER_FH_FILE = 0x1000; const NDMP4_BUTYPE_RECOVER_FH_DIR = 0x2000; struct ndmp4_butype_info { string butype_name<>; ndmp4_pval default_env<>; uint32_t attrs; }; struct ndmp4_config_get_butype_info_reply { ndmp4_error error; ndmp4_butype_info butype_info<>; }; const NDMP4_FS_INFO_TOTAL_SIZE_UNS = 0x00000001; const NDMP4_FS_INFO_USED_SIZE_UNS = 0x00000002; const NDMP4_FS_INFO_AVAIL_SIZE_UNS = 0x00000004; const NDMP4_FS_INFO_TOTAL_INODES_UNS = 0x00000008; const NDMP4_FS_INFO_USED_INODES_UNS = 0x00000010; struct ndmp4_fs_info { uint32_t unsupported; string fs_type<>; string fs_logical_device<>; string fs_physical_device<>; ndmp4_u_quad total_size; ndmp4_u_quad used_size; ndmp4_u_quad avail_size; ndmp4_u_quad total_inodes; ndmp4_u_quad used_inodes; ndmp4_pval fs_env<>; string fs_status<>; }; struct ndmp4_config_get_fs_info_reply { ndmp4_error error; ndmp4_fs_info fs_info<>; }; const NDMP4_TAPE_ATTR_REWIND = 0x00000001; const NDMP4_TAPE_ATTR_UNLOAD = 0x00000002; const NDMP4_TAPE_ATTR_RAW = 0x00000004; struct ndmp4_device_capability { string device<>; uint32_t attr; ndmp4_pval capability<>; }; struct ndmp4_device_info { string model<>; ndmp4_device_capability caplist<>; }; struct ndmp4_config_get_tape_info_reply { ndmp4_error error; ndmp4_device_info tape_info<>; }; struct ndmp4_config_get_scsi_info_reply { ndmp4_error error; ndmp4_device_info scsi_info<>; }; struct ndmp4_class_list { uint16_t class_id; uint16_t class_version<>; }; struct ndmp4_class_version { uint16_t class_id; uint16_t class_version; }; struct ndmp4_config_get_ext_list_reply { ndmp4_error error; ndmp4_class_list class_list<>; }; struct ndmp4_config_set_ext_list_request { ndmp4_error error; ndmp4_class_list ndmp4_accepted_ext<>; }; struct ndmp4_config_set_ext_list_reply { ndmp4_error error; }; struct ndmp4_scsi_open_request { string device<>; }; struct ndmp4_scsi_open_reply { ndmp4_error error; }; struct ndmp4_scsi_close_reply { ndmp4_error error; }; struct ndmp4_scsi_get_state_reply { ndmp4_error error; short target_controller; short target_id; short target_lun; }; struct ndmp4_scsi_reset_device_reply { ndmp4_error error; }; const NDMP4_SCSI_DATA_IN = 0x00000001; const NDMP4_SCSI_DATA_OUT = 0x00000002; struct ndmp4_execute_cdb_request { uint32_t flags; uint32_t timeout; uint32_t datain_len; opaque cdb<>; opaque dataout<>; }; struct ndmp4_execute_cdb_reply { ndmp4_error error; u_char status; uint32_t dataout_len; opaque datain<>; opaque ext_sense<>; }; typedef ndmp4_execute_cdb_request ndmp4_scsi_execute_cdb_request; typedef ndmp4_execute_cdb_reply ndmp4_scsi_execute_cdb_reply; enum ndmp4_tape_open_mode { NDMP4_TAPE_READ_MODE = 0, NDMP4_TAPE_RDWR_MODE = 1, NDMP4_TAPE_RAW_MODE = 2 }; struct ndmp4_tape_open_request { string device<>; ndmp4_tape_open_mode mode; }; struct ndmp4_tape_open_reply { ndmp4_error error; }; struct ndmp4_tape_close_reply { ndmp4_error error; }; /* flags */ const NDMP4_TAPE_STATE_NOREWIND = 0x0008; /* non-rewind device */ const NDMP4_TAPE_STATE_WR_PROT = 0x0010; /* write-protected */ const NDMP4_TAPE_STATE_ERROR = 0x0020; /* media error */ const NDMP4_TAPE_STATE_UNLOAD = 0x0040; /* tape unloaded upon close */ /* unsupported bits */ const NDMP4_TAPE_STATE_FILE_NUM_UNS = 0x00000001; const NDMP4_TAPE_STATE_SOFT_ERRORS_UNS = 0x00000002; const NDMP4_TAPE_STATE_BLOCK_SIZE_UNS = 0x00000004; const NDMP4_TAPE_STATE_BLOCKNO_UNS = 0x00000008; const NDMP4_TAPE_STATE_TOTAL_SPACE_UNS = 0x00000010; const NDMP4_TAPE_STATE_SPACE_REMAIN_UNS = 0x00000020; struct ndmp4_tape_get_state_reply { uint32_t unsupported; ndmp4_error error; uint32_t flags; uint32_t file_num; uint32_t soft_errors; uint32_t block_size; uint32_t blockno; ndmp4_u_quad total_space; ndmp4_u_quad space_remain; }; enum ndmp4_tape_mtio_op { NDMP4_MTIO_FSF=0, NDMP4_MTIO_BSF=1, NDMP4_MTIO_FSR=2, NDMP4_MTIO_BSR=3, NDMP4_MTIO_REW=4, NDMP4_MTIO_EOF=5, NDMP4_MTIO_OFF=6, NDMP4_MTIO_TUR=7 }; struct ndmp4_tape_mtio_request { ndmp4_tape_mtio_op tape_op; uint32_t count; }; struct ndmp4_tape_mtio_reply { ndmp4_error error; uint32_t resid_count; }; struct ndmp4_tape_write_request { opaque data_out<>; }; struct ndmp4_tape_write_reply { ndmp4_error error; uint32_t count; }; struct ndmp4_tape_read_request { uint32_t count; }; struct ndmp4_tape_read_reply { ndmp4_error error; opaque data_in<>; }; typedef ndmp4_scsi_execute_cdb_request ndmp4_tape_execute_cdb_request; typedef ndmp4_scsi_execute_cdb_reply ndmp4_tape_execute_cdb_reply; enum ndmp4_data_operation { NDMP4_DATA_OP_NOACTION = 0, NDMP4_DATA_OP_BACKUP = 1, NDMP4_DATA_OP_RECOVER = 2, NDMP4_DATA_OP_RECOVER_FILEHIST = 3 }; enum ndmp4_data_state { NDMP4_DATA_STATE_IDLE=0, NDMP4_DATA_STATE_ACTIVE=1, NDMP4_DATA_STATE_HALTED=2, NDMP4_DATA_STATE_LISTEN=3, NDMP4_DATA_STATE_CONNECTED=4 }; enum ndmp4_data_halt_reason { NDMP4_DATA_HALT_NA=0, NDMP4_DATA_HALT_SUCCESSFUL=1, NDMP4_DATA_HALT_ABORTED=2, NDMP4_DATA_HALT_INTERNAL_ERROR=3, NDMP4_DATA_HALT_CONNECT_ERROR=4 }; /* ndmp4_addr */ struct ndmp4_tcp_addr { uint32_t ip_addr; uint16_t port; ndmp4_pval addr_env<>; }; struct ndmp4_ipc_addr { opaque comm_data<>; }; union ndmp4_addr switch (ndmp4_addr_type addr_type) { case NDMP4_ADDR_LOCAL: void; case NDMP4_ADDR_TCP: ndmp4_tcp_addr tcp_addr<>; case NDMP4_ADDR_IPC: ndmp4_ipc_addr ipc_addr; }; /* unsupported bitmask bits */ const NDMP4_DATA_STATE_EST_BYTES_REMAIN_UNS = 0x00000001; const NDMP4_DATA_STATE_EST_TIME_REMAIN_UNS = 0x00000002; struct ndmp4_data_get_state_reply { uint32_t unsupported; ndmp4_error error; ndmp4_data_operation operation; ndmp4_data_state state; ndmp4_data_halt_reason halt_reason; ndmp4_u_quad bytes_processed; ndmp4_u_quad est_bytes_remain; uint32_t est_time_remain; ndmp4_addr data_connection_addr; ndmp4_u_quad read_offset; ndmp4_u_quad read_length; }; struct ndmp4_data_listen_request { ndmp4_addr_type addr_type; }; struct ndmp4_data_listen_reply { ndmp4_error error; ndmp4_addr connect_addr; }; struct ndmp4_data_connect_request { ndmp4_addr addr; }; struct ndmp4_data_connect_reply { ndmp4_error error; }; struct ndmp4_data_start_backup_request { string butype_name<>; ndmp4_pval env<>; }; struct ndmp4_data_start_backup_reply { ndmp4_error error; }; struct ndmp4_name { string original_path<>; string destination_path<>; string name<>; string other_name<>; ndmp4_u_quad node; ndmp4_u_quad fh_info; }; struct ndmp4_data_start_recover_request { ndmp4_pval env<>; ndmp4_name nlist<>; string butype_name<>; }; struct ndmp4_data_start_recover_reply { ndmp4_error error; }; struct ndmp4_data_start_recover_filehist_request { ndmp4_pval env<>; ndmp4_name nlist<>; string butype_name<>; }; struct ndmp4_data_start_recover_filehist_reply { ndmp4_error error; }; struct ndmp4_data_abort_reply { ndmp4_error error; }; struct ndmp4_data_stop_reply { ndmp4_error error; }; struct ndmp4_data_get_env_reply { ndmp4_error error; ndmp4_pval env<>; }; enum ndmp4_mover_mode { NDMP4_MOVER_MODE_READ = 0, NDMP4_MOVER_MODE_WRITE = 1, NDMP4_MOVER_MODE_NOACTION = 2 }; enum ndmp4_mover_state { NDMP4_MOVER_STATE_IDLE, NDMP4_MOVER_STATE_LISTEN, NDMP4_MOVER_STATE_ACTIVE, NDMP4_MOVER_STATE_PAUSED, NDMP4_MOVER_STATE_HALTED }; enum ndmp4_mover_pause_reason { NDMP4_MOVER_PAUSE_NA = 0, NDMP4_MOVER_PAUSE_EOM = 1, NDMP4_MOVER_PAUSE_EOF = 2, NDMP4_MOVER_PAUSE_SEEK = 3, /* NDMPv4 does not have MOVER_PAUSE_MEDIA_ERROR = 4 */ NDMP4_MOVER_PAUSE_EOW = 5 }; enum ndmp4_mover_halt_reason { NDMP4_MOVER_HALT_NA, NDMP4_MOVER_HALT_CONNECT_CLOSED, NDMP4_MOVER_HALT_ABORTED, NDMP4_MOVER_HALT_INTERNAL_ERROR, NDMP4_MOVER_HALT_CONNECT_ERROR, NDMP4_MOVER_HALT_MEDIA_ERROR }; struct ndmp4_mover_set_record_size_request { uint32_t len; }; struct ndmp4_mover_set_record_size_reply { ndmp4_error error; }; struct ndmp4_mover_set_window_request { ndmp4_u_quad offset; ndmp4_u_quad length; }; struct ndmp4_mover_set_window_reply { ndmp4_error error; }; struct ndmp4_mover_connect_request { ndmp4_mover_mode mode; ndmp4_addr addr; }; struct ndmp4_mover_connect_reply { ndmp4_error error; }; struct ndmp4_mover_listen_request { ndmp4_mover_mode mode; ndmp4_addr_type addr_type; }; struct ndmp4_mover_listen_reply { ndmp4_error error; ndmp4_addr connect_addr; }; struct ndmp4_mover_read_request { ndmp4_u_quad offset; ndmp4_u_quad length; }; struct ndmp4_mover_read_reply { ndmp4_error error; }; struct ndmp4_mover_get_state_reply { ndmp4_error error; ndmp4_mover_mode mode; ndmp4_mover_state state; ndmp4_mover_pause_reason pause_reason; ndmp4_mover_halt_reason halt_reason; uint32_t record_size; uint32_t record_num; ndmp4_u_quad bytes_moved; ndmp4_u_quad seek_position; ndmp4_u_quad bytes_left_to_read; ndmp4_u_quad window_offset; ndmp4_u_quad window_length; ndmp4_addr data_connection_addr; }; struct ndmp4_mover_continue_reply { ndmp4_error error; }; struct ndmp4_mover_close_reply { ndmp4_error error; }; struct ndmp4_mover_abort_reply { ndmp4_error error; }; struct ndmp4_mover_stop_reply { ndmp4_error error; }; struct ndmp4_notify_data_halted_post { ndmp4_data_halt_reason reason; }; enum ndmp4_connection_status_reason { NDMP4_CONNECTED=0, NDMP4_SHUTDOWN=1, NDMP4_REFUSED=2 }; struct ndmp4_notify_connection_status_post { ndmp4_connection_status_reason reason; uint16_t protocol_version; string text_reason<>; }; struct ndmp4_notify_mover_halted_post { ndmp4_mover_halt_reason reason; }; struct ndmp4_notify_mover_paused_post { ndmp4_mover_pause_reason reason; ndmp4_u_quad seek_position; }; struct ndmp4_notify_data_read_post { ndmp4_u_quad offset; ndmp4_u_quad length; }; enum ndmp4_has_associated_message { NDMP4_NO_ASSOCIATED_MESSAGE = 0, NDMP4_HAS_ASSOCIATED_MESSAGE = 1 }; enum ndmp4_log_type { NDMP4_LOG_NORMAL = 0, NDMP4_LOG_DEBUG = 1, NDMP4_LOG_ERROR = 2, NDMP4_LOG_WARNING = 3 }; struct ndmp4_log_message_post { ndmp4_log_type log_type; uint32_t message_id; string entry<>; ndmp4_has_associated_message associated_message_valid; uint32_t associated_message_sequence; }; enum ndmp4_recovery_status { NDMP4_RECOVERY_SUCCESSFUL = 0, NDMP4_RECOVERY_FAILED_PERMISSION = 1, NDMP4_RECOVERY_FAILED_NOT_FOUND = 2, NDMP4_RECOVERY_FAILED_NO_DIRECTORY = 3, NDMP4_RECOVERY_FAILED_OUT_OF_MEMORY = 4, NDMP4_RECOVERY_FAILED_IO_ERROR = 5, NDMP4_RECOVERY_FAILED_UNDEFINED_ERROR = 6 }; struct ndmp4_log_file_post { string name<>; ndmp4_recovery_status recovery_status; }; enum ndmp4_fs_type { NDMP4_FS_UNIX=0, NDMP4_FS_NT=1, NDMP4_FS_OTHER=2 }; typedef string ndmp4_path<>; struct ndmp4_nt_path { ndmp4_path nt_path; ndmp4_path dos_path; }; union ndmp4_file_name switch (ndmp4_fs_type fs_type) { case NDMP4_FS_UNIX: ndmp4_path unix_name; case NDMP4_FS_NT: ndmp4_nt_path nt_name; default: ndmp4_path other_name; }; /* file type */ enum ndmp4_file_type { NDMP4_FILE_DIR=0, NDMP4_FILE_FIFO=1, NDMP4_FILE_CSPEC=2, NDMP4_FILE_BSPEC=3, NDMP4_FILE_REG=4, NDMP4_FILE_SLINK=5, NDMP4_FILE_SOCK=6, NDMP4_FILE_REGISTRY=7, NDMP4_FILE_OTHER=8 }; /* file stat */ /* unsupported bitmask */ const NDMP4_FILE_STAT_ATIME_UNS = 0x00000001; const NDMP4_FILE_STAT_CTIME_UNS = 0x00000002; const NDMP4_FILE_STAT_GROUP_UNS = 0x00000004; struct ndmp4_file_stat { uint32_t unsupported; ndmp4_fs_type fs_type; ndmp4_file_type ftype; uint32_t mtime; uint32_t atime; uint32_t ctime; uint32_t owner; uint32_t group; uint32_t fattr; ndmp4_u_quad size; uint32_t links; }; struct ndmp4_file { ndmp4_file_name names<>; ndmp4_file_stat stats<>; ndmp4_u_quad node; ndmp4_u_quad fh_info; }; struct ndmp4_fh_add_file_post { ndmp4_file files<>; }; struct ndmp4_dir { ndmp4_file_name names<>; ndmp4_u_quad node; ndmp4_u_quad parent; }; struct ndmp4_fh_add_dir_post { ndmp4_dir dirs<>; }; struct ndmp4_node { ndmp4_file_stat stats<>; ndmp4_u_quad node; ndmp4_u_quad fh_info; }; struct ndmp4_fh_add_node_post { ndmp4_node nodes<>; }; %#endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp4_enum_strs.c000066400000000000000000000502461263011562700214610ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP4 extern struct ndmp_enum_str_table ndmp4_error_table[]; extern char * ndmp4_error_to_str (ndmp4_error val); extern int ndmp4_error_from_str (ndmp4_error *valp, char *str); char * ndmp4_error_to_str (ndmp4_error val) { return ndmp_enum_to_str ((int)val, ndmp4_error_table); } int ndmp4_error_from_str (ndmp4_error *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_error_table); } struct ndmp_enum_str_table ndmp4_error_table[] = { { "NDMP4_NO_ERR", NDMP4_NO_ERR, }, { "NDMP4_NOT_SUPPORTED_ERR", NDMP4_NOT_SUPPORTED_ERR, }, { "NDMP4_DEVICE_BUSY_ERR", NDMP4_DEVICE_BUSY_ERR, }, { "NDMP4_DEVICE_OPENED_ERR", NDMP4_DEVICE_OPENED_ERR, }, { "NDMP4_NOT_AUTHORIZED_ERR", NDMP4_NOT_AUTHORIZED_ERR, }, { "NDMP4_PERMISSION_ERR", NDMP4_PERMISSION_ERR, }, { "NDMP4_DEV_NOT_OPEN_ERR", NDMP4_DEV_NOT_OPEN_ERR, }, { "NDMP4_IO_ERR", NDMP4_IO_ERR, }, { "NDMP4_TIMEOUT_ERR", NDMP4_TIMEOUT_ERR, }, { "NDMP4_ILLEGAL_ARGS_ERR", NDMP4_ILLEGAL_ARGS_ERR, }, { "NDMP4_NO_TAPE_LOADED_ERR", NDMP4_NO_TAPE_LOADED_ERR, }, { "NDMP4_WRITE_PROTECT_ERR", NDMP4_WRITE_PROTECT_ERR, }, { "NDMP4_EOF_ERR", NDMP4_EOF_ERR, }, { "NDMP4_EOM_ERR", NDMP4_EOM_ERR, }, { "NDMP4_FILE_NOT_FOUND_ERR", NDMP4_FILE_NOT_FOUND_ERR, }, { "NDMP4_BAD_FILE_ERR", NDMP4_BAD_FILE_ERR, }, { "NDMP4_NO_DEVICE_ERR", NDMP4_NO_DEVICE_ERR, }, { "NDMP4_NO_BUS_ERR", NDMP4_NO_BUS_ERR, }, { "NDMP4_XDR_DECODE_ERR", NDMP4_XDR_DECODE_ERR, }, { "NDMP4_ILLEGAL_STATE_ERR", NDMP4_ILLEGAL_STATE_ERR, }, { "NDMP4_UNDEFINED_ERR", NDMP4_UNDEFINED_ERR, }, { "NDMP4_XDR_ENCODE_ERR", NDMP4_XDR_ENCODE_ERR, }, { "NDMP4_NO_MEM_ERR", NDMP4_NO_MEM_ERR, }, { "NDMP4_CONNECT_ERR", NDMP4_CONNECT_ERR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_header_message_type_table[]; extern char * ndmp4_header_message_type_to_str (ndmp4_header_message_type val); extern int ndmp4_header_message_type_from_str (ndmp4_header_message_type *valp, char *str); char * ndmp4_header_message_type_to_str (ndmp4_header_message_type val) { return ndmp_enum_to_str ((int)val, ndmp4_header_message_type_table); } int ndmp4_header_message_type_from_str (ndmp4_header_message_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_header_message_type_table); } struct ndmp_enum_str_table ndmp4_header_message_type_table[] = { { "NDMP4_MESSAGE_REQUEST", NDMP4_MESSAGE_REQUEST, }, { "NDMP4_MESSAGE_REPLY", NDMP4_MESSAGE_REPLY, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_message_table[]; extern char * ndmp4_message_to_str (ndmp4_message val); extern int ndmp4_message_from_str (ndmp4_message *valp, char *str); char * ndmp4_message_to_str (ndmp4_message val) { return ndmp_enum_to_str ((int)val, ndmp4_message_table); } int ndmp4_message_from_str (ndmp4_message *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_message_table); } struct ndmp_enum_str_table ndmp4_message_table[] = { { "NDMP4_CONNECT_OPEN", NDMP4_CONNECT_OPEN, }, { "NDMP4_CONNECT_CLIENT_AUTH", NDMP4_CONNECT_CLIENT_AUTH, }, { "NDMP4_CONNECT_CLOSE", NDMP4_CONNECT_CLOSE, }, { "NDMP4_CONNECT_SERVER_AUTH", NDMP4_CONNECT_SERVER_AUTH, }, { "NDMP4_CONFIG_GET_HOST_INFO", NDMP4_CONFIG_GET_HOST_INFO, }, { "NDMP4_CONFIG_GET_CONNECTION_TYPE", NDMP4_CONFIG_GET_CONNECTION_TYPE, }, { "NDMP4_CONFIG_GET_AUTH_ATTR", NDMP4_CONFIG_GET_AUTH_ATTR, }, { "NDMP4_CONFIG_GET_BUTYPE_INFO", NDMP4_CONFIG_GET_BUTYPE_INFO, }, { "NDMP4_CONFIG_GET_FS_INFO", NDMP4_CONFIG_GET_FS_INFO, }, { "NDMP4_CONFIG_GET_TAPE_INFO", NDMP4_CONFIG_GET_TAPE_INFO, }, { "NDMP4_CONFIG_GET_SCSI_INFO", NDMP4_CONFIG_GET_SCSI_INFO, }, { "NDMP4_CONFIG_GET_SERVER_INFO",NDMP4_CONFIG_GET_SERVER_INFO, }, { "NDMP4_SCSI_OPEN", NDMP4_SCSI_OPEN, }, { "NDMP4_SCSI_CLOSE", NDMP4_SCSI_CLOSE, }, { "NDMP4_SCSI_GET_STATE", NDMP4_SCSI_GET_STATE, }, /* { "NDMP4_SCSI_SET_TARGET", NDMP4_SCSI_SET_TARGET, }, */ { "NDMP4_SCSI_RESET_DEVICE", NDMP4_SCSI_RESET_DEVICE, }, /* { "NDMP4_SCSI_RESET_BUS", NDMP4_SCSI_RESET_BUS, }, */ { "NDMP4_SCSI_EXECUTE_CDB", NDMP4_SCSI_EXECUTE_CDB, }, { "NDMP4_TAPE_OPEN", NDMP4_TAPE_OPEN, }, { "NDMP4_TAPE_CLOSE", NDMP4_TAPE_CLOSE, }, { "NDMP4_TAPE_GET_STATE", NDMP4_TAPE_GET_STATE, }, { "NDMP4_TAPE_MTIO", NDMP4_TAPE_MTIO, }, { "NDMP4_TAPE_WRITE", NDMP4_TAPE_WRITE, }, { "NDMP4_TAPE_READ", NDMP4_TAPE_READ, }, { "NDMP4_TAPE_EXECUTE_CDB", NDMP4_TAPE_EXECUTE_CDB, }, { "NDMP4_DATA_GET_STATE", NDMP4_DATA_GET_STATE, }, { "NDMP4_DATA_START_BACKUP", NDMP4_DATA_START_BACKUP, }, { "NDMP4_DATA_START_RECOVER", NDMP4_DATA_START_RECOVER, }, { "NDMP4_DATA_START_RECOVER_FILEHIST", NDMP4_DATA_START_RECOVER_FILEHIST, }, { "NDMP4_DATA_ABORT", NDMP4_DATA_ABORT, }, { "NDMP4_DATA_GET_ENV", NDMP4_DATA_GET_ENV, }, { "NDMP4_DATA_STOP", NDMP4_DATA_STOP, }, { "NDMP4_DATA_LISTEN", NDMP4_DATA_LISTEN, }, { "NDMP4_DATA_CONNECT", NDMP4_DATA_CONNECT, }, { "NDMP4_NOTIFY_DATA_HALTED", NDMP4_NOTIFY_DATA_HALTED, }, { "NDMP4_NOTIFY_CONNECTION_STATUS", NDMP4_NOTIFY_CONNECTION_STATUS, }, { "NDMP4_NOTIFY_MOVER_HALTED", NDMP4_NOTIFY_MOVER_HALTED, }, { "NDMP4_NOTIFY_MOVER_PAUSED", NDMP4_NOTIFY_MOVER_PAUSED, }, { "NDMP4_NOTIFY_DATA_READ", NDMP4_NOTIFY_DATA_READ, }, { "NDMP4_LOG_FILE", NDMP4_LOG_FILE, }, { "NDMP4_LOG_MESSAGE", NDMP4_LOG_MESSAGE, }, { "NDMP4_FH_ADD_FILE", NDMP4_FH_ADD_FILE, }, { "NDMP4_FH_ADD_DIR", NDMP4_FH_ADD_DIR, }, { "NDMP4_FH_ADD_NODE", NDMP4_FH_ADD_NODE, }, { "NDMP4_MOVER_GET_STATE", NDMP4_MOVER_GET_STATE, }, { "NDMP4_MOVER_LISTEN", NDMP4_MOVER_LISTEN, }, { "NDMP4_MOVER_CONTINUE", NDMP4_MOVER_CONTINUE, }, { "NDMP4_MOVER_ABORT", NDMP4_MOVER_ABORT, }, { "NDMP4_MOVER_STOP", NDMP4_MOVER_STOP, }, { "NDMP4_MOVER_SET_WINDOW", NDMP4_MOVER_SET_WINDOW, }, { "NDMP4_MOVER_READ", NDMP4_MOVER_READ, }, { "NDMP4_MOVER_CLOSE", NDMP4_MOVER_CLOSE, }, { "NDMP4_MOVER_SET_RECORD_SIZE", NDMP4_MOVER_SET_RECORD_SIZE, }, { "NDMP4_MOVER_CONNECT", NDMP4_MOVER_CONNECT, }, /* { "NDMP4_VENDORS_BASE", NDMP4_VENDORS_BASE, }, */ /* { "NDMP4_RESERVED_BASE", NDMP4_RESERVED_BASE, }, */ { 0 } }; extern struct ndmp_enum_str_table ndmp4_auth_type_table[]; extern char * ndmp4_auth_type_to_str (ndmp4_auth_type val); extern int ndmp4_auth_type_from_str (ndmp4_auth_type *valp, char *str); char * ndmp4_auth_type_to_str (ndmp4_auth_type val) { return ndmp_enum_to_str ((int)val, ndmp4_auth_type_table); } int ndmp4_auth_type_from_str (ndmp4_auth_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_auth_type_table); } struct ndmp_enum_str_table ndmp4_auth_type_table[] = { { "NDMP4_AUTH_NONE", NDMP4_AUTH_NONE, }, { "NDMP4_AUTH_TEXT", NDMP4_AUTH_TEXT, }, { "NDMP4_AUTH_MD5", NDMP4_AUTH_MD5, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_addr_type_table[]; extern char * ndmp4_addr_type_to_str (ndmp4_addr_type val); extern int ndmp4_addr_type_from_str (ndmp4_addr_type *valp, char *str); char * ndmp4_addr_type_to_str (ndmp4_addr_type val) { return ndmp_enum_to_str ((int)val, ndmp4_addr_type_table); } int ndmp4_addr_type_from_str (ndmp4_addr_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_addr_type_table); } struct ndmp_enum_str_table ndmp4_addr_type_table[] = { { "NDMP4_ADDR_LOCAL", NDMP4_ADDR_LOCAL, }, { "NDMP4_ADDR_TCP", NDMP4_ADDR_TCP, }, { "NDMP4_ADDR_RESERVED", NDMP4_ADDR_RESERVED, }, { "NDMP4_ADDR_IPC", NDMP4_ADDR_IPC, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_tape_open_mode_table[]; extern char * ndmp4_tape_open_mode_to_str (ndmp4_tape_open_mode val); extern int ndmp4_tape_open_mode_from_str (ndmp4_tape_open_mode *valp, char *str); char * ndmp4_tape_open_mode_to_str (ndmp4_tape_open_mode val) { return ndmp_enum_to_str ((int)val, ndmp4_tape_open_mode_table); } int ndmp4_tape_open_mode_from_str (ndmp4_tape_open_mode *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_tape_open_mode_table); } struct ndmp_enum_str_table ndmp4_tape_open_mode_table[] = { { "NDMP4_TAPE_READ_MODE", NDMP4_TAPE_READ_MODE, }, { "NDMP4_TAPE_RDWR_MODE", NDMP4_TAPE_RDWR_MODE, }, { "NDMP4_TAPE_RAW_MODE", NDMP4_TAPE_RAW_MODE, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_tape_mtio_op_table[]; extern char * ndmp4_tape_mtio_op_to_str (ndmp4_tape_mtio_op val); extern int ndmp4_tape_mtio_op_from_str (ndmp4_tape_mtio_op *valp, char *str); char * ndmp4_tape_mtio_op_to_str (ndmp4_tape_mtio_op val) { return ndmp_enum_to_str ((int)val, ndmp4_tape_mtio_op_table); } int ndmp4_tape_mtio_op_from_str (ndmp4_tape_mtio_op *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_tape_mtio_op_table); } struct ndmp_enum_str_table ndmp4_tape_mtio_op_table[] = { { "NDMP4_MTIO_FSF", NDMP4_MTIO_FSF, }, { "NDMP4_MTIO_BSF", NDMP4_MTIO_BSF, }, { "NDMP4_MTIO_FSR", NDMP4_MTIO_FSR, }, { "NDMP4_MTIO_BSR", NDMP4_MTIO_BSR, }, { "NDMP4_MTIO_REW", NDMP4_MTIO_REW, }, { "NDMP4_MTIO_EOF", NDMP4_MTIO_EOF, }, { "NDMP4_MTIO_OFF", NDMP4_MTIO_OFF, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_mover_state_table[]; extern char * ndmp4_mover_state_to_str (ndmp4_mover_state val); extern int ndmp4_mover_state_from_str (ndmp4_mover_state *valp, char *str); char * ndmp4_mover_state_to_str (ndmp4_mover_state val) { return ndmp_enum_to_str ((int)val, ndmp4_mover_state_table); } int ndmp4_mover_state_from_str (ndmp4_mover_state *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_mover_state_table); } struct ndmp_enum_str_table ndmp4_mover_state_table[] = { { "NDMP4_MOVER_STATE_IDLE", NDMP4_MOVER_STATE_IDLE, }, { "NDMP4_MOVER_STATE_LISTEN", NDMP4_MOVER_STATE_LISTEN, }, { "NDMP4_MOVER_STATE_ACTIVE", NDMP4_MOVER_STATE_ACTIVE, }, { "NDMP4_MOVER_STATE_PAUSED", NDMP4_MOVER_STATE_PAUSED, }, { "NDMP4_MOVER_STATE_HALTED", NDMP4_MOVER_STATE_HALTED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_mover_pause_reason_table[]; extern char * ndmp4_mover_pause_reason_to_str (ndmp4_mover_pause_reason val); extern int ndmp4_mover_pause_reason_from_str (ndmp4_mover_pause_reason *valp, char *str); char * ndmp4_mover_pause_reason_to_str (ndmp4_mover_pause_reason val) { return ndmp_enum_to_str ((int)val, ndmp4_mover_pause_reason_table); } int ndmp4_mover_pause_reason_from_str (ndmp4_mover_pause_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_mover_pause_reason_table); } struct ndmp_enum_str_table ndmp4_mover_pause_reason_table[] = { { "NDMP4_MOVER_PAUSE_NA", NDMP4_MOVER_PAUSE_NA, }, { "NDMP4_MOVER_PAUSE_EOM", NDMP4_MOVER_PAUSE_EOM, }, { "NDMP4_MOVER_PAUSE_EOF", NDMP4_MOVER_PAUSE_EOF, }, { "NDMP4_MOVER_PAUSE_SEEK", NDMP4_MOVER_PAUSE_SEEK, }, { "NDMP4_MOVER_PAUSE_EOW", NDMP4_MOVER_PAUSE_EOW, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_mover_halt_reason_table[]; extern char * ndmp4_mover_halt_reason_to_str (ndmp4_mover_halt_reason val); extern int ndmp4_mover_halt_reason_from_str (ndmp4_mover_halt_reason *valp, char *str); char * ndmp4_mover_halt_reason_to_str (ndmp4_mover_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp4_mover_halt_reason_table); } int ndmp4_mover_halt_reason_from_str (ndmp4_mover_halt_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_mover_halt_reason_table); } struct ndmp_enum_str_table ndmp4_mover_halt_reason_table[] = { { "NDMP4_MOVER_HALT_NA", NDMP4_MOVER_HALT_NA, }, { "NDMP4_MOVER_HALT_CONNECT_CLOSED", NDMP4_MOVER_HALT_CONNECT_CLOSED, }, { "NDMP4_MOVER_HALT_ABORTED", NDMP4_MOVER_HALT_ABORTED, }, { "NDMP4_MOVER_HALT_INTERNAL_ERROR", NDMP4_MOVER_HALT_INTERNAL_ERROR, }, { "NDMP4_MOVER_HALT_CONNECT_ERROR", NDMP4_MOVER_HALT_CONNECT_ERROR, }, { "NDMP4_MOVER_HALT_MEDIA_ERROR", NDMP4_MOVER_HALT_MEDIA_ERROR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_mover_mode_table[]; extern char * ndmp4_mover_mode_to_str (ndmp4_mover_mode val); extern int ndmp4_mover_mode_from_str (ndmp4_mover_mode *valp, char *str); char * ndmp4_mover_mode_to_str (ndmp4_mover_mode val) { return ndmp_enum_to_str ((int)val, ndmp4_mover_mode_table); } int ndmp4_mover_mode_from_str (ndmp4_mover_mode *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_mover_mode_table); } struct ndmp_enum_str_table ndmp4_mover_mode_table[] = { { "NDMP4_MOVER_MODE_READ", NDMP4_MOVER_MODE_READ, }, { "NDMP4_MOVER_MODE_WRITE", NDMP4_MOVER_MODE_WRITE, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_data_operation_table[]; extern char * ndmp4_data_operation_to_str (ndmp4_data_operation val); extern int ndmp4_data_operation_from_str (ndmp4_data_operation *valp, char *str); char * ndmp4_data_operation_to_str (ndmp4_data_operation val) { return ndmp_enum_to_str ((int)val, ndmp4_data_operation_table); } int ndmp4_data_operation_from_str (ndmp4_data_operation *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_data_operation_table); } struct ndmp_enum_str_table ndmp4_data_operation_table[] = { { "NDMP4_DATA_OP_NOACTION", NDMP4_DATA_OP_NOACTION, }, { "NDMP4_DATA_OP_BACKUP", NDMP4_DATA_OP_BACKUP, }, { "NDMP4_DATA_OP_RECOVER", NDMP4_DATA_OP_RECOVER, }, { "NDMP4_DATA_OP_RECOVER_FILEHIST", NDMP4_DATA_OP_RECOVER_FILEHIST, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_data_state_table[]; extern char * ndmp4_data_state_to_str (ndmp4_data_state val); extern int ndmp4_data_state_from_str (ndmp4_data_state *valp, char *str); char * ndmp4_data_state_to_str (ndmp4_data_state val) { return ndmp_enum_to_str ((int)val, ndmp4_data_state_table); } int ndmp4_data_state_from_str (ndmp4_data_state *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_data_state_table); } struct ndmp_enum_str_table ndmp4_data_state_table[] = { { "NDMP4_DATA_STATE_IDLE", NDMP4_DATA_STATE_IDLE, }, { "NDMP4_DATA_STATE_ACTIVE", NDMP4_DATA_STATE_ACTIVE, }, { "NDMP4_DATA_STATE_HALTED", NDMP4_DATA_STATE_HALTED, }, { "NDMP4_DATA_STATE_LISTEN", NDMP4_DATA_STATE_LISTEN, }, { "NDMP4_DATA_STATE_CONNECTED", NDMP4_DATA_STATE_CONNECTED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_data_halt_reason_table[]; extern char * ndmp4_data_halt_reason_to_str (ndmp4_data_halt_reason val); extern int ndmp4_data_halt_reason_from_str (ndmp4_data_halt_reason *valp, char *str); char * ndmp4_data_halt_reason_to_str (ndmp4_data_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp4_data_halt_reason_table); } int ndmp4_data_halt_reason_from_str (ndmp4_data_halt_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_data_halt_reason_table); } struct ndmp_enum_str_table ndmp4_data_halt_reason_table[] = { { "NDMP4_DATA_HALT_NA", NDMP4_DATA_HALT_NA, }, { "NDMP4_DATA_HALT_SUCCESSFUL", NDMP4_DATA_HALT_SUCCESSFUL, }, { "NDMP4_DATA_HALT_ABORTED", NDMP4_DATA_HALT_ABORTED, }, { "NDMP4_DATA_HALT_INTERNAL_ERROR", NDMP4_DATA_HALT_INTERNAL_ERROR, }, { "NDMP4_DATA_HALT_CONNECT_ERROR", NDMP4_DATA_HALT_CONNECT_ERROR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_connection_status_reason_table[]; extern char * ndmp4_connection_status_reason_to_str (ndmp4_connection_status_reason val); extern int ndmp4_connection_status_reason_from_str (ndmp4_connection_status_reason *valp, char *str); char * ndmp4_connection_status_reason_to_str (ndmp4_connection_status_reason val) { return ndmp_enum_to_str ((int)val, ndmp4_connection_status_reason_table); } int ndmp4_connection_status_reason_from_str (ndmp4_connection_status_reason *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_connection_status_reason_table); } struct ndmp_enum_str_table ndmp4_connection_status_reason_table[] = { { "NDMP4_CONNECTED", NDMP4_CONNECTED, }, { "NDMP4_SHUTDOWN", NDMP4_SHUTDOWN, }, { "NDMP4_REFUSED", NDMP4_REFUSED, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_log_type_table[]; extern char * ndmp4_log_type_to_str (ndmp4_log_type val); extern int ndmp4_log_type_from_str (ndmp4_log_type *valp, char *str); char * ndmp4_log_type_to_str (ndmp4_log_type val) { return ndmp_enum_to_str ((int)val, ndmp4_log_type_table); } int ndmp4_log_type_from_str (ndmp4_log_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_log_type_table); } struct ndmp_enum_str_table ndmp4_log_type_table[] = { { "NDMP4_LOG_NORMAL", NDMP4_LOG_NORMAL, }, { "NDMP4_LOG_DEBUG", NDMP4_LOG_DEBUG, }, { "NDMP4_LOG_ERROR", NDMP4_LOG_ERROR, }, { "NDMP4_LOG_WARNING", NDMP4_LOG_WARNING, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_fs_type_table[]; extern char * ndmp4_fs_type_to_str (ndmp4_fs_type val); extern int ndmp4_fs_type_from_str (ndmp4_fs_type *valp, char *str); char * ndmp4_fs_type_to_str (ndmp4_fs_type val) { return ndmp_enum_to_str ((int)val, ndmp4_fs_type_table); } int ndmp4_fs_type_from_str (ndmp4_fs_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_fs_type_table); } struct ndmp_enum_str_table ndmp4_fs_type_table[] = { { "NDMP4_FS_UNIX", NDMP4_FS_UNIX, }, { "NDMP4_FS_NT", NDMP4_FS_NT, }, { "NDMP4_FS_OTHER", NDMP4_FS_OTHER, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_file_type_table[]; extern char * ndmp4_file_type_to_str (ndmp4_file_type val); extern int ndmp4_file_type_from_str (ndmp4_file_type *valp, char *str); char * ndmp4_file_type_to_str (ndmp4_file_type val) { return ndmp_enum_to_str ((int)val, ndmp4_file_type_table); } int ndmp4_file_type_from_str (ndmp4_file_type *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_file_type_table); } struct ndmp_enum_str_table ndmp4_file_type_table[] = { { "NDMP4_FILE_DIR", NDMP4_FILE_DIR, }, { "NDMP4_FILE_FIFO", NDMP4_FILE_FIFO, }, { "NDMP4_FILE_CSPEC", NDMP4_FILE_CSPEC, }, { "NDMP4_FILE_BSPEC", NDMP4_FILE_BSPEC, }, { "NDMP4_FILE_REG", NDMP4_FILE_REG, }, { "NDMP4_FILE_SLINK", NDMP4_FILE_SLINK, }, { "NDMP4_FILE_SOCK", NDMP4_FILE_SOCK, }, { "NDMP4_FILE_REGISTRY", NDMP4_FILE_REGISTRY, }, { "NDMP4_FILE_OTHER", NDMP4_FILE_OTHER, }, { 0 } }; extern struct ndmp_enum_str_table ndmp4_recovery_status_table[]; extern char * ndmp4_recovery_status_to_str (ndmp4_recovery_status val); extern int ndmp4_recovery_status_from_str (ndmp4_recovery_status *valp, char *str); char * ndmp4_recovery_status_to_str (ndmp4_recovery_status val) { return ndmp_enum_to_str ((int)val, ndmp4_recovery_status_table); } int ndmp4_recovery_status_from_str (ndmp4_recovery_status *valp, char *str) { return ndmp_enum_from_str ((int*)valp, str, ndmp4_recovery_status_table); } struct ndmp_enum_str_table ndmp4_recovery_status_table[] = { { "NDMP4_RECOVERY_SUCCESSFUL", NDMP4_RECOVERY_SUCCESSFUL, }, { "NDMP4_RECOVERY_FAILED_PERMISSION", NDMP4_RECOVERY_FAILED_PERMISSION, }, { "NDMP4_RECOVERY_FAILED_NOT_FOUND", NDMP4_RECOVERY_FAILED_NOT_FOUND, }, { "NDMP4_RECOVERY_FAILED_NO_DIRECTORY", NDMP4_RECOVERY_FAILED_NO_DIRECTORY, }, { "NDMP4_RECOVERY_FAILED_OUT_OF_MEMORY", NDMP4_RECOVERY_FAILED_OUT_OF_MEMORY, }, { "NDMP4_RECOVERY_FAILED_IO_ERROR", NDMP4_RECOVERY_FAILED_IO_ERROR, }, { "NDMP4_RECOVERY_FAILED_UNDEFINED_ERROR", NDMP4_RECOVERY_FAILED_UNDEFINED_ERROR, }, { 0 } }; #endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp4_enum_strs.h000066400000000000000000000126331263011562700214640ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_NDMP4 extern struct ndmp_enum_str_table ndmp4_error_table[]; extern char * ndmp4_error_to_str (ndmp4_error val); extern int ndmp4_error_from_str (ndmp4_error *valp, char *str); extern struct ndmp_enum_str_table ndmp4_header_message_type_table[]; extern char * ndmp4_header_message_type_to_str (ndmp4_header_message_type val); extern int ndmp4_header_message_type_from_str (ndmp4_header_message_type *valp, char *str); extern struct ndmp_enum_str_table ndmp4_message_table[]; extern char * ndmp4_message_to_str (ndmp4_message val); extern int ndmp4_message_from_str (ndmp4_message *valp, char *str); extern struct ndmp_enum_str_table ndmp4_auth_type_table[]; extern char * ndmp4_auth_type_to_str (ndmp4_auth_type val); extern int ndmp4_auth_type_from_str (ndmp4_auth_type *valp, char *str); extern struct ndmp_enum_str_table ndmp4_addr_type_table[]; extern char * ndmp4_addr_type_to_str (ndmp4_addr_type val); extern int ndmp4_addr_type_from_str (ndmp4_addr_type *valp, char *str); extern struct ndmp_enum_str_table ndmp4_tape_open_mode_table[]; extern char * ndmp4_tape_open_mode_to_str (ndmp4_tape_open_mode val); extern int ndmp4_tape_open_mode_from_str (ndmp4_tape_open_mode *valp, char *str); extern struct ndmp_enum_str_table ndmp4_tape_mtio_op_table[]; extern char * ndmp4_tape_mtio_op_to_str (ndmp4_tape_mtio_op val); extern int ndmp4_tape_mtio_op_from_str (ndmp4_tape_mtio_op *valp, char *str); extern struct ndmp_enum_str_table ndmp4_mover_state_table[]; extern char * ndmp4_mover_state_to_str (ndmp4_mover_state val); extern int ndmp4_mover_state_from_str (ndmp4_mover_state *valp, char *str); extern struct ndmp_enum_str_table ndmp4_mover_pause_reason_table[]; extern char * ndmp4_mover_pause_reason_to_str (ndmp4_mover_pause_reason val); extern int ndmp4_mover_pause_reason_from_str (ndmp4_mover_pause_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp4_mover_halt_reason_table[]; extern char * ndmp4_mover_halt_reason_to_str (ndmp4_mover_halt_reason val); extern int ndmp4_mover_halt_reason_from_str (ndmp4_mover_halt_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp4_mover_mode_table[]; extern char * ndmp4_mover_mode_to_str (ndmp4_mover_mode val); extern int ndmp4_mover_mode_from_str (ndmp4_mover_mode *valp, char *str); extern struct ndmp_enum_str_table ndmp4_data_operation_table[]; extern char * ndmp4_data_operation_to_str (ndmp4_data_operation val); extern int ndmp4_data_operation_from_str (ndmp4_data_operation *valp, char *str); extern struct ndmp_enum_str_table ndmp4_data_state_table[]; extern char * ndmp4_data_state_to_str (ndmp4_data_state val); extern int ndmp4_data_state_from_str (ndmp4_data_state *valp, char *str); extern struct ndmp_enum_str_table ndmp4_data_halt_reason_table[]; extern char * ndmp4_data_halt_reason_to_str (ndmp4_data_halt_reason val); extern int ndmp4_data_halt_reason_from_str (ndmp4_data_halt_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp4_connection_status_reason_table[]; extern char * ndmp4_connection_status_reason_to_str (ndmp4_connection_status_reason val); extern int ndmp4_connection_status_reason_from_str (ndmp4_connection_status_reason *valp, char *str); extern struct ndmp_enum_str_table ndmp4_log_type_table[]; extern char * ndmp4_log_type_to_str (ndmp4_log_type val); extern int ndmp4_log_type_from_str (ndmp4_log_type *valp, char *str); extern struct ndmp_enum_str_table ndmp4_fs_type_table[]; extern char * ndmp4_fs_type_to_str (ndmp4_fs_type val); extern int ndmp4_fs_type_from_str (ndmp4_fs_type *valp, char *str); extern struct ndmp_enum_str_table ndmp4_file_type_table[]; extern char * ndmp4_file_type_to_str (ndmp4_file_type val); extern int ndmp4_file_type_from_str (ndmp4_file_type *valp, char *str); extern struct ndmp_enum_str_table ndmp4_recovery_status_table[]; extern char * ndmp4_recovery_status_to_str (ndmp4_recovery_status val); extern int ndmp4_recovery_status_from_str (ndmp4_recovery_status *valp, char *str); #endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp4_pp.c000066400000000000000000000562711263011562700200650ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP4 int ndmp4_pp_header (void *data, char *buf) { ndmp4_header * mh = (ndmp4_header *) data; if (mh->message_type == NDMP4_MESSAGE_REQUEST) { sprintf (buf, "C %s %lu", ndmp4_message_to_str (mh->message_code), mh->sequence); } else if (mh->message_type == NDMP4_MESSAGE_REPLY) { sprintf (buf, "R %s %lu (%lu)", ndmp4_message_to_str (mh->message_code), mh->reply_sequence, mh->sequence); if (mh->error_code != NDMP4_NO_ERR) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp4_error_to_str (mh->error_code)); return 0; /* no body */ } } else { strcpy (buf, "??? INVALID MESSAGE TYPE"); return -1; /* no body */ } return 1; /* body */ } int ndmp4_pp_addr (char *buf, ndmp4_addr *ma) { unsigned int i, j; ndmp4_tcp_addr * tcp; sprintf (buf, "%s", ndmp4_addr_type_to_str (ma->addr_type)); if (ma->addr_type == NDMP4_ADDR_TCP) { for (i = 0; i < ma->ndmp4_addr_u.tcp_addr.tcp_addr_len; i++) { tcp = &ma->ndmp4_addr_u.tcp_addr.tcp_addr_val[i]; sprintf (NDMOS_API_STREND(buf), " #%d(%lx,%d", i, tcp->ip_addr, tcp->port); for (j = 0; j < tcp->addr_env.addr_env_len; j++) { sprintf (NDMOS_API_STREND(buf), ",%s=%s", tcp->addr_env.addr_env_val[j].name, tcp->addr_env.addr_env_val[j].value); } sprintf (NDMOS_API_STREND(buf), ")"); } } return 0; } int ndmp4_pp_request (ndmp4_message msg, void *data, int lineno, char *buf) { int i; unsigned int j; switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP4_CONNECT_OPEN: NDMP_PP_WITH(ndmp4_connect_open_request) sprintf (buf, "version=%d", p->protocol_version); NDMP_PP_ENDWITH break; case NDMP4_CONNECT_CLIENT_AUTH: NDMP_PP_WITH(ndmp4_connect_client_auth_request) sprintf (buf, "auth_type=%s", ndmp4_auth_type_to_str (p->auth_data.auth_type)); sprintf (buf, "auth_type=%s", ndmp4_auth_type_to_str (p->auth_data.auth_type)); switch (p->auth_data.auth_type) { case NDMP4_AUTH_NONE: break; case NDMP4_AUTH_TEXT: sprintf (NDMOS_API_STREND(buf), " auth_id=%s", p->auth_data.ndmp4_auth_data_u.auth_text.auth_id); break; case NDMP4_AUTH_MD5: sprintf (NDMOS_API_STREND(buf), " auth_id=%s", p->auth_data.ndmp4_auth_data_u.auth_md5.auth_id); break; default: sprintf (NDMOS_API_STREND(buf), " ????"); break; } NDMP_PP_ENDWITH break; case NDMP4_CONNECT_CLOSE: case NDMP4_CONFIG_GET_HOST_INFO: case NDMP4_CONFIG_GET_CONNECTION_TYPE: case NDMP4_CONFIG_GET_SERVER_INFO: case NDMP4_CONFIG_GET_TAPE_INFO: case NDMP4_CONFIG_GET_SCSI_INFO: case NDMP4_SCSI_CLOSE: case NDMP4_SCSI_GET_STATE: case NDMP4_SCSI_RESET_DEVICE: /* case NDMP4_SCSI_RESET_BUS: */ case NDMP4_TAPE_GET_STATE: case NDMP4_TAPE_CLOSE: case NDMP4_MOVER_GET_STATE: case NDMP4_MOVER_CONTINUE: case NDMP4_MOVER_ABORT: case NDMP4_MOVER_STOP: case NDMP4_MOVER_CLOSE: case NDMP4_DATA_GET_STATE: case NDMP4_DATA_ABORT: case NDMP4_DATA_STOP: case NDMP4_DATA_GET_ENV: *buf = 0; /* no body */ return 0; case NDMP4_CONNECT_SERVER_AUTH: strcpy (buf, "<>"); break; case NDMP4_CONFIG_GET_AUTH_ATTR: NDMP_PP_WITH(ndmp4_config_get_auth_attr_request) sprintf (buf, "auth_type=%s", ndmp4_auth_type_to_str (p->auth_type)); NDMP_PP_ENDWITH break; case NDMP4_SCSI_OPEN: NDMP_PP_WITH(ndmp4_scsi_open_request) sprintf (buf, "device='%s'", p->device); NDMP_PP_ENDWITH break; /*** deprecated case NDMP4_SCSI_SET_TARGET: NDMP_PP_WITH(ndmp4_scsi_set_target_request) sprintf (buf, "device='%s' cont=%d sid=%d lun=%d", p->device, p->target_controller, p->target_id, p->target_lun); NDMP_PP_ENDWITH break; ***/ case NDMP4_SCSI_EXECUTE_CDB: case NDMP4_TAPE_EXECUTE_CDB: NDMP_PP_WITH(ndmp4_execute_cdb_request) switch (lineno) { case 0: sprintf (buf, "flags=0x%lx timeout=%ld datain_len=%ld", p->flags, p->timeout, p->datain_len); break; case 1: sprintf (buf, "cmd[%d]={", p->cdb.cdb_len); for (j = 0; j < p->cdb.cdb_len; j++) { sprintf (NDMOS_API_STREND(buf), " %02x", p->cdb.cdb_val[j]&0xFF); } strcat (buf, " }"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP4_TAPE_OPEN: NDMP_PP_WITH(ndmp4_tape_open_request) sprintf (buf, "device='%s' mode=%s", p->device, ndmp4_tape_open_mode_to_str (p->mode)); NDMP_PP_ENDWITH break; case NDMP4_TAPE_MTIO: NDMP_PP_WITH(ndmp4_tape_mtio_request) sprintf (buf, "op=%s count=%ld", ndmp4_tape_mtio_op_to_str(p->tape_op), p->count); NDMP_PP_ENDWITH break; case NDMP4_TAPE_WRITE: NDMP_PP_WITH(ndmp4_tape_write_request) sprintf (buf, "data_out_len=%d", p->data_out.data_out_len); NDMP_PP_ENDWITH break; case NDMP4_TAPE_READ: NDMP_PP_WITH(ndmp4_tape_read_request) sprintf (buf, "count=%ld", p->count); NDMP_PP_ENDWITH break; case NDMP4_DATA_START_BACKUP: NDMP_PP_WITH(ndmp4_data_start_backup_request) if (lineno == 0) { sprintf (buf, "butype_name='%s' n_env=%d", p->butype_name, p->env.env_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "env[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { strcpy (buf, "--INVALID--"); } } return 1 + p->env.env_len; NDMP_PP_ENDWITH break; case NDMP4_DATA_START_RECOVER: case NDMP4_DATA_START_RECOVER_FILEHIST: NDMP_PP_WITH(ndmp4_data_start_recover_request) if (lineno == 0) { sprintf (buf, "butype_name='%s' n_env=%d n_nlist=%d", p->butype_name, p->env.env_len, p->nlist.nlist_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "env[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { i -= p->env.env_len; if (0 <= i && (unsigned)i < p->nlist.nlist_len*4) { ndmp4_name *nm = &p->nlist.nlist_val[i/4]; switch (i%4) { case 0: sprintf (buf, "nl[%d] original_path='%s'", i/4, nm->original_path); break; case 1: sprintf (buf, "..... destination_path='%s'", nm->destination_path); break; case 2: sprintf (buf, "..... name='%s' other='%s'", nm->name, nm->other_name); break; case 3: sprintf (buf, "..... node=%lld fh_info=%lld", nm->node, nm->fh_info); break; } } else { strcpy (buf, "--INVALID--"); } } } return 1 + p->env.env_len + p->nlist.nlist_len*4; NDMP_PP_ENDWITH break; case NDMP4_DATA_LISTEN: NDMP_PP_WITH(ndmp4_data_listen_request) sprintf (buf, "addr_type=%s", ndmp4_addr_type_to_str (p->addr_type)); NDMP_PP_ENDWITH break; case NDMP4_DATA_CONNECT: NDMP_PP_WITH(ndmp4_data_connect_request) sprintf (buf, "addr="); ndmp4_pp_addr (NDMOS_API_STREND(buf), &p->addr); NDMP_PP_ENDWITH break; case NDMP4_NOTIFY_DATA_HALTED: NDMP_PP_WITH(ndmp4_notify_data_halted_post) sprintf (buf, "reason=%s", ndmp4_data_halt_reason_to_str(p->reason)); NDMP_PP_ENDWITH break; case NDMP4_NOTIFY_CONNECTION_STATUS: NDMP_PP_WITH(ndmp4_notify_connection_status_post) sprintf (buf, "reason=%s protocol_version=%d text_reason='%s'", ndmp4_connection_status_reason_to_str(p->reason), p->protocol_version, p->text_reason); NDMP_PP_ENDWITH break; case NDMP4_NOTIFY_MOVER_HALTED: NDMP_PP_WITH(ndmp4_notify_mover_halted_post) sprintf (buf, "reason=%s", ndmp4_mover_halt_reason_to_str(p->reason)); NDMP_PP_ENDWITH break; case NDMP4_NOTIFY_MOVER_PAUSED: NDMP_PP_WITH(ndmp4_notify_mover_paused_post) sprintf (buf, "reason=%s seek_position=%lld", ndmp4_mover_pause_reason_to_str(p->reason), p->seek_position); NDMP_PP_ENDWITH break; case NDMP4_NOTIFY_DATA_READ: NDMP_PP_WITH(ndmp4_notify_data_read_post) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP4_LOG_FILE: NDMP_PP_WITH(ndmp4_log_file_post) sprintf (buf, "file=%s recovery_status=%s", p->name, ndmp4_recovery_status_to_str(p->recovery_status)); NDMP_PP_ENDWITH break; case NDMP4_LOG_MESSAGE: NDMP_PP_WITH(ndmp4_log_message_post) sprintf (buf, "log_type=%s id=%lu message='%s'", ndmp4_log_type_to_str(p->log_type), p->message_id, p->entry); NDMP_PP_ENDWITH break; case NDMP4_FH_ADD_FILE: NDMP_PP_WITH(ndmp4_fh_add_file_post) int n_line = 0, n_names = 0, n_stats = 0; unsigned int n_normal = 0; n_line++; for (j = 0; j < p->files.files_len; j++) { int nn, ns; nn = p->files.files_val[j].names.names_len; ns = p->files.files_val[j].stats.stats_len; n_line += 1 + nn + ns; if (nn == 1 && ns == 1) n_normal++; n_names += nn; n_stats += ns; } if (n_normal == p->files.files_len) { /* could do something more efficient here */ } if (lineno == 0) { sprintf (buf, "n_files=%d total n_names=%d n_stats=%d", p->files.files_len, n_names, n_stats); return n_line; } lineno--; for (j = 0; j < p->files.files_len; j++) { ndmp4_file * file = &p->files.files_val[j]; unsigned int k; if (lineno == 0) { sprintf (buf, "[%ud] n_names=%d n_stats=%d node=%lld fhinfo=%lld", j, file->names.names_len, file->stats.stats_len, file->node, file->fh_info); return n_line; } lineno--; for (k = 0; k < file->names.names_len; k++, lineno--) { ndmp4_file_name *filename; if (lineno != 0) continue; filename = &file->names.names_val[k]; sprintf (buf, " name[%ud] fs_type=%s", k, ndmp4_fs_type_to_str (filename->fs_type)); switch (filename->fs_type) { default: sprintf (NDMOS_API_STREND(buf), " other=%s", filename->ndmp4_file_name_u.other_name); break; case NDMP4_FS_UNIX: sprintf (NDMOS_API_STREND(buf), " unix=%s", filename->ndmp4_file_name_u.unix_name); break; case NDMP4_FS_NT: sprintf (NDMOS_API_STREND(buf)," nt=%s dos=%s", filename->ndmp4_file_name_u.nt_name.nt_path, filename->ndmp4_file_name_u.nt_name.dos_path); break; } return n_line; } for (k = 0; k < file->stats.stats_len; k++, lineno--) { ndmp4_file_stat *filestat; if (lineno != 0) continue; filestat = &file->stats.stats_val[k]; sprintf (buf, " stat[%d] fs_type=%s ftype=%s size=%lld", k, ndmp4_fs_type_to_str (filestat->fs_type), ndmp4_file_type_to_str (filestat->ftype), filestat->size); return n_line; } } sprintf (buf, " YIKES n_line=%d lineno=%d", n_line, lineno); return -1; NDMP_PP_ENDWITH break; case NDMP4_FH_ADD_DIR: NDMP_PP_WITH(ndmp4_fh_add_dir_post) int n_line = 0, n_names = 0; unsigned int n_normal = 0; n_line++; for (j = 0; j < p->dirs.dirs_len; j++) { int nn; nn = p->dirs.dirs_val[j].names.names_len; n_line += 1 + nn; if (nn == 1) n_normal++; n_names += nn; } if (n_normal == p->dirs.dirs_len) { /* could do something more efficient here */ } if (lineno == 0) { sprintf (buf, "n_dirs=%d total n_names=%d", p->dirs.dirs_len, n_names); return n_line; } lineno--; for (j = 0; j < p->dirs.dirs_len; j++) { ndmp4_dir * dir = &p->dirs.dirs_val[j]; unsigned int k; if (lineno == 0) { sprintf (buf, "[%ud] n_names=%d node=%lld parent=%lld", j, dir->names.names_len, dir->node, dir->parent); return n_line; } lineno--; for (k = 0; k < dir->names.names_len; k++, lineno--) { ndmp4_file_name *filename; if (lineno != 0) continue; filename = &dir->names.names_val[k]; sprintf (buf, " name[%d] fs_type=%s", k, ndmp4_fs_type_to_str (filename->fs_type)); switch (filename->fs_type) { default: sprintf (NDMOS_API_STREND(buf), " other=%s", filename->ndmp4_file_name_u.other_name); break; case NDMP4_FS_UNIX: sprintf (NDMOS_API_STREND(buf), " unix=%s", filename->ndmp4_file_name_u.unix_name); break; case NDMP4_FS_NT: sprintf (NDMOS_API_STREND(buf)," nt=%s dos=%s", filename->ndmp4_file_name_u.nt_name.nt_path, filename->ndmp4_file_name_u.nt_name.dos_path); break; } return n_line; } } sprintf (buf, " YIKES n_line=%d lineno=%d", n_line, lineno); return -1; NDMP_PP_ENDWITH break; case NDMP4_FH_ADD_NODE: NDMP_PP_WITH(ndmp4_fh_add_node_post) int n_line = 0, n_stats = 0; unsigned int n_normal = 0; n_line++; for (j = 0; j < p->nodes.nodes_len; j++) { int ns; ns = p->nodes.nodes_val[j].stats.stats_len; n_line += 1 + ns; if (ns == 1) n_normal++; n_stats += ns; } if (n_normal == p->nodes.nodes_len) { /* could do something more efficient here */ } if (lineno == 0) { sprintf (buf, "n_nodes=%d total n_stats=%d", p->nodes.nodes_len, n_stats); return n_line; } lineno--; for (j = 0; j < p->nodes.nodes_len; j++) { ndmp4_node * node = &p->nodes.nodes_val[j]; unsigned int k; if (lineno == 0) { sprintf (buf, "[%ud] n_stats=%d node=%lld fhinfo=%lld", j, node->stats.stats_len, node->node, node->fh_info); return n_line; } lineno--; for (k = 0; k < node->stats.stats_len; k++, lineno--) { ndmp4_file_stat *filestat; if (lineno != 0) continue; filestat = &node->stats.stats_val[k]; sprintf (buf, " stat[%ud] fs_type=%s ftype=%s size=%lld", k, ndmp4_fs_type_to_str (filestat->fs_type), ndmp4_file_type_to_str (filestat->ftype), filestat->size); return n_line; } } sprintf (buf, " YIKES n_line=%d lineno=%d", n_line, lineno); return -1; NDMP_PP_ENDWITH break; case NDMP4_MOVER_LISTEN: NDMP_PP_WITH(ndmp4_mover_listen_request) sprintf (buf, "mode=%s addr_type=%s", ndmp4_mover_mode_to_str (p->mode), ndmp4_addr_type_to_str (p->addr_type)); NDMP_PP_ENDWITH break; case NDMP4_MOVER_SET_WINDOW: NDMP_PP_WITH(ndmp4_mover_set_window_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP4_MOVER_READ: NDMP_PP_WITH(ndmp4_mover_read_request) sprintf (buf, "offset=%lld length=%lld", p->offset, p->length); NDMP_PP_ENDWITH break; case NDMP4_MOVER_SET_RECORD_SIZE: NDMP_PP_WITH(ndmp4_mover_set_record_size_request) sprintf (buf, "len=%lu", p->len); NDMP_PP_ENDWITH break; case NDMP4_MOVER_CONNECT: NDMP_PP_WITH(ndmp4_mover_connect_request) sprintf (buf, "mode=%s addr=", ndmp4_mover_mode_to_str (p->mode)); ndmp4_pp_addr (NDMOS_API_STREND(buf), &p->addr); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } int ndmp4_pp_reply (ndmp4_message msg, void *data, int lineno, char *buf) { int i; unsigned int j; switch (msg) { default: strcpy (buf, "<>"); return -1; case NDMP4_CONNECT_OPEN: case NDMP4_CONNECT_CLIENT_AUTH: case NDMP4_SCSI_OPEN: case NDMP4_SCSI_CLOSE: /* case NDMP4_SCSI_SET_TARGET: */ case NDMP4_SCSI_RESET_DEVICE: /* case NDMP4_SCSI_RESET_BUS: */ case NDMP4_TAPE_OPEN: case NDMP4_TAPE_CLOSE: case NDMP4_MOVER_CONTINUE: case NDMP4_MOVER_ABORT: case NDMP4_MOVER_STOP: case NDMP4_MOVER_READ: case NDMP4_MOVER_SET_WINDOW: case NDMP4_MOVER_CLOSE: case NDMP4_MOVER_SET_RECORD_SIZE: case NDMP4_MOVER_CONNECT: case NDMP4_DATA_START_BACKUP: case NDMP4_DATA_START_RECOVER: case NDMP4_DATA_START_RECOVER_FILEHIST: case NDMP4_DATA_ABORT: case NDMP4_DATA_STOP: case NDMP4_DATA_CONNECT: NDMP_PP_WITH(ndmp4_error) sprintf (buf, "error=%s", ndmp4_error_to_str(*p)); NDMP_PP_ENDWITH break; case NDMP4_CONNECT_CLOSE: *buf = 0; return 0; case NDMP4_CONNECT_SERVER_AUTH: strcpy (buf, "<>"); break; case NDMP4_CONFIG_GET_HOST_INFO: NDMP_PP_WITH(ndmp4_config_get_host_info_reply) switch (lineno) { case 0: sprintf (buf, "error=%s hostname=%s", ndmp4_error_to_str(p->error), p->hostname); break; case 1: sprintf (buf, "os_type=%s os_vers=%s hostid=%s", p->os_type, p->os_vers, p->hostid); break; default: strcpy (buf, "--INVALID--"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP4_CONFIG_GET_CONNECTION_TYPE: NDMP_PP_WITH(ndmp4_config_get_connection_type_reply) sprintf (buf, "error=%s addr_types[%d]={", ndmp4_error_to_str(p->error), p->addr_types.addr_types_len); for (j = 0; j < p->addr_types.addr_types_len; j++) { sprintf (NDMOS_API_STREND(buf), " %s", ndmp4_addr_type_to_str(p->addr_types.addr_types_val[j])); } strcat (buf, " }"); NDMP_PP_ENDWITH break; case NDMP4_CONFIG_GET_SERVER_INFO: case NDMP4_CONFIG_GET_TAPE_INFO: case NDMP4_CONFIG_GET_SCSI_INFO: strcpy (buf, "<>"); break; case NDMP4_CONFIG_GET_AUTH_ATTR: strcpy (buf, "<>"); break; case NDMP4_SCSI_GET_STATE: NDMP_PP_WITH(ndmp4_scsi_get_state_reply) sprintf (buf, "error=%s cont=%d sid=%d lun=%d", ndmp4_error_to_str(p->error), p->target_controller, p->target_id, p->target_lun); NDMP_PP_ENDWITH break; case NDMP4_SCSI_EXECUTE_CDB: case NDMP4_TAPE_EXECUTE_CDB: NDMP_PP_WITH(ndmp4_execute_cdb_reply) switch (lineno) { case 0: sprintf (buf, "error=%s status=%02x dataout_len=%ld datain_len=%d", ndmp4_error_to_str(p->error), p->status, p->dataout_len, p->datain.datain_len); break; case 1: sprintf (buf, "sense[%d]={", p->ext_sense.ext_sense_len); for (j = 0; j < p->ext_sense.ext_sense_len; j++) { sprintf (NDMOS_API_STREND(buf), " %02x", p->ext_sense.ext_sense_val[j]&0xFF); } strcat (buf, " }"); break; } return 2; NDMP_PP_ENDWITH break; case NDMP4_TAPE_GET_STATE: NDMP_PP_WITH(ndmp4_tape_get_state_reply) switch (lineno) { case 0: sprintf (buf, "unsupp=%lx error=%s flags=0x%lx file_num=%ld", p->unsupported, ndmp4_error_to_str(p->error), p->flags, p->file_num); break; case 1: sprintf (buf, "soft_errors=%lu block_size=%lu blockno=%lu", p->soft_errors, p->block_size, p->blockno); break; case 2: sprintf (buf, "total_space=%lld space_remain=%lld", p->total_space, p->space_remain); break; default: strcpy (buf, "--INVALID--"); break; } return 3; NDMP_PP_ENDWITH break; case NDMP4_TAPE_MTIO: NDMP_PP_WITH(ndmp4_tape_mtio_reply) sprintf (buf, "error=%s resid_count=%ld", ndmp4_error_to_str(p->error), p->resid_count); NDMP_PP_ENDWITH break; case NDMP4_TAPE_WRITE: NDMP_PP_WITH(ndmp4_tape_write_reply) sprintf (buf, "error=%s count=%ld", ndmp4_error_to_str(p->error), p->count); NDMP_PP_ENDWITH break; case NDMP4_TAPE_READ: NDMP_PP_WITH(ndmp4_tape_read_reply) sprintf (buf, "error=%s data_in_len=%d", ndmp4_error_to_str(p->error), p->data_in.data_in_len); NDMP_PP_ENDWITH break; case NDMP4_DATA_GET_STATE: NDMP_PP_WITH(ndmp4_data_get_state_reply) switch (lineno) { case 0: sprintf (buf, "unsupp=%lx error=%s op=%s", p->unsupported, ndmp4_error_to_str(p->error), ndmp4_data_operation_to_str(p->operation)); break; case 1: sprintf (buf, "state=%s", ndmp4_data_state_to_str(p->state)); break; case 2: sprintf (buf, "halt_reason=%s", ndmp4_data_halt_reason_to_str(p->halt_reason)); break; case 3: sprintf (buf, "bytes_processed=%lld est_bytes_remain=%lld", p->bytes_processed, p->est_bytes_remain); break; case 4: sprintf (buf, "est_time_remain=%ld data_conn_addr=", p->est_time_remain); ndmp4_pp_addr (NDMOS_API_STREND(buf), &p->data_connection_addr); break; case 5: sprintf (buf, "read_offset=%lld read_length=%lld", p->read_offset, p->read_length); break; default: strcpy (buf, "--INVALID--"); break; } return 6; NDMP_PP_ENDWITH break; case NDMP4_DATA_GET_ENV: NDMP_PP_WITH(ndmp4_data_get_env_reply) if (lineno == 0) { sprintf (buf, "error=%s n_env=%d", ndmp4_error_to_str(p->error), p->env.env_len); } else { i = lineno - 1; if (0 <= i && (unsigned)i < p->env.env_len) { sprintf (buf, "[%d] name='%s' value='%s'", i, p->env.env_val[i].name, p->env.env_val[i].value); } else { strcpy (buf, "--INVALID--"); } } return p->env.env_len + 1; NDMP_PP_ENDWITH break; case NDMP4_NOTIFY_DATA_HALTED: case NDMP4_NOTIFY_CONNECTION_STATUS: case NDMP4_NOTIFY_MOVER_HALTED: case NDMP4_NOTIFY_MOVER_PAUSED: case NDMP4_NOTIFY_DATA_READ: case NDMP4_LOG_FILE: case NDMP4_LOG_MESSAGE: case NDMP4_FH_ADD_FILE: case NDMP4_FH_ADD_DIR: case NDMP4_FH_ADD_NODE: strcpy (buf, "<>"); break; case NDMP4_MOVER_GET_STATE: NDMP_PP_WITH(ndmp4_mover_get_state_reply) switch (lineno) { case 0: sprintf (buf, "error=%s state=%s", ndmp4_error_to_str(p->error), ndmp4_mover_state_to_str(p->state)); break; case 1: sprintf (buf, "pause_reason=%s", ndmp4_mover_pause_reason_to_str(p->pause_reason)); break; case 2: sprintf (buf, "halt_reason=%s", ndmp4_mover_halt_reason_to_str(p->halt_reason)); break; case 3: sprintf (buf,"record_size=%lu record_num=%lu bytes_moved=%lld", p->record_size, p->record_num, p->bytes_moved); break; case 4: sprintf (buf, "seek=%lld to_read=%lld win_off=%lld win_len=%lld", p->seek_position, p->bytes_left_to_read, p->window_offset, p->window_length); break; case 5: sprintf (buf, "data_conn_addr="); ndmp4_pp_addr (NDMOS_API_STREND(buf), &p->data_connection_addr); break; default: strcpy (buf, "--INVALID--"); break; } return 6; NDMP_PP_ENDWITH break; case NDMP4_MOVER_LISTEN: NDMP_PP_WITH(ndmp4_mover_listen_reply) sprintf (buf, "error=%s data_conn_addr=", ndmp4_error_to_str(p->error)); ndmp4_pp_addr (NDMOS_API_STREND(buf), &p->connect_addr); NDMP_PP_ENDWITH break; } return 1; /* one line in buf */ } #endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp4_translate.c000066400000000000000000002563021263011562700214400ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #include "ndmp_msg_buf.h" #include "ndmp_translate.h" #ifndef NDMOS_OPTION_NO_NDMP4 /* * Pervasive Types **************************************************************** */ /* * ndmp_error **************************************************************** */ struct enum_conversion ndmp_49_error[] = { { NDMP4_UNDEFINED_ERR, NDMP9_UNDEFINED_ERR }, /* default */ { NDMP4_NO_ERR, NDMP9_NO_ERR }, { NDMP4_NOT_SUPPORTED_ERR, NDMP9_NOT_SUPPORTED_ERR }, { NDMP4_DEVICE_BUSY_ERR, NDMP9_DEVICE_BUSY_ERR }, { NDMP4_DEVICE_OPENED_ERR, NDMP9_DEVICE_OPENED_ERR }, { NDMP4_NOT_AUTHORIZED_ERR, NDMP9_NOT_AUTHORIZED_ERR }, { NDMP4_PERMISSION_ERR, NDMP9_PERMISSION_ERR }, { NDMP4_DEV_NOT_OPEN_ERR, NDMP9_DEV_NOT_OPEN_ERR }, { NDMP4_IO_ERR, NDMP9_IO_ERR }, { NDMP4_TIMEOUT_ERR, NDMP9_TIMEOUT_ERR }, { NDMP4_ILLEGAL_ARGS_ERR, NDMP9_ILLEGAL_ARGS_ERR }, { NDMP4_NO_TAPE_LOADED_ERR, NDMP9_NO_TAPE_LOADED_ERR }, { NDMP4_WRITE_PROTECT_ERR, NDMP9_WRITE_PROTECT_ERR }, { NDMP4_EOF_ERR, NDMP9_EOF_ERR }, { NDMP4_EOM_ERR, NDMP9_EOM_ERR }, { NDMP4_FILE_NOT_FOUND_ERR, NDMP9_FILE_NOT_FOUND_ERR }, { NDMP4_BAD_FILE_ERR, NDMP9_BAD_FILE_ERR }, { NDMP4_NO_DEVICE_ERR, NDMP9_NO_DEVICE_ERR }, { NDMP4_NO_BUS_ERR, NDMP9_NO_BUS_ERR }, { NDMP4_XDR_DECODE_ERR, NDMP9_XDR_DECODE_ERR }, { NDMP4_ILLEGAL_STATE_ERR, NDMP9_ILLEGAL_STATE_ERR }, { NDMP4_UNDEFINED_ERR, NDMP9_UNDEFINED_ERR }, { NDMP4_XDR_ENCODE_ERR, NDMP9_XDR_ENCODE_ERR }, { NDMP4_NO_MEM_ERR, NDMP9_NO_MEM_ERR }, { NDMP4_CONNECT_ERR, NDMP9_CONNECT_ERR }, { NDMP4_SEQUENCE_NUM_ERR, NDMP9_SEQUENCE_NUM_ERR }, { NDMP4_READ_IN_PROGRESS_ERR, NDMP9_READ_IN_PROGRESS_ERR }, { NDMP4_PRECONDITION_ERR, NDMP9_PRECONDITION_ERR }, { NDMP4_CLASS_NOT_SUPPORTED, NDMP9_CLASS_NOT_SUPPORTED }, { NDMP4_VERSION_NOT_SUPPORTED, NDMP9_VERSION_NOT_SUPPORTED }, { NDMP4_EXT_DUPL_CLASSES, NDMP9_EXT_DUPL_CLASSES }, { NDMP4_EXT_DN_ILLEGAL, NDMP9_EXT_DN_ILLEGAL }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_4to9_error ( ndmp4_error *error4, ndmp9_error *error9) { *error9 = convert_enum_to_9 (ndmp_49_error, *error4); return 0; } extern int ndmp_9to4_error ( ndmp9_error *error9, ndmp4_error *error4) { *error4 = convert_enum_from_9 (ndmp_49_error, *error9); return 0; } /* * ndmp_pval **************************************************************** */ int ndmp_4to9_pval ( ndmp4_pval *pval4, ndmp9_pval *pval9) { CNVT_STRDUP_TO_9(pval4, pval9, name); CNVT_STRDUP_TO_9(pval4, pval9, value); return 0; } int ndmp_9to4_pval ( ndmp9_pval *pval9, ndmp4_pval *pval4) { CNVT_STRDUP_FROM_9(pval4, pval9, name); CNVT_STRDUP_FROM_9(pval4, pval9, value); return 0; } int ndmp_4to9_pval_vec ( ndmp4_pval *pval4, ndmp9_pval *pval9, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_4to9_pval (&pval4[i], &pval9[i]); return 0; } int ndmp_9to4_pval_vec ( ndmp9_pval *pval9, ndmp4_pval *pval4, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_9to4_pval (&pval9[i], &pval4[i]); return 0; } int ndmp_4to9_pval_vec_dup ( ndmp4_pval *pval4, ndmp9_pval **pval9_p, unsigned n_pval) { *pval9_p = NDMOS_MACRO_NEWN (ndmp9_pval, n_pval); if (!*pval9_p) return -1; return ndmp_4to9_pval_vec (pval4, *pval9_p, n_pval); } int ndmp_9to4_pval_vec_dup ( ndmp9_pval *pval9, ndmp4_pval **pval4_p, unsigned n_pval) { *pval4_p = NDMOS_MACRO_NEWN (ndmp4_pval, n_pval); if (!*pval4_p) return -1; return ndmp_9to4_pval_vec (pval9, *pval4_p, n_pval); } int ndmp_4to9_pval_free( ndmp9_pval *pval9) { CNVT_FREE(pval9, name); CNVT_FREE(pval9, value); return 0; } int ndmp_4to9_pval_vec_free ( ndmp9_pval *pval9, unsigned n_pval) { unsigned int i; for (i = 0; i < n_pval; i++) ndmp_4to9_pval_free(&pval9[i]); NDMOS_MACRO_FREE(pval9); return 0; } /* * ndmp_addr **************************************************************** */ struct enum_conversion ndmp_49_addr_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL }, /* default */ { NDMP4_ADDR_LOCAL, NDMP9_ADDR_LOCAL }, { NDMP4_ADDR_TCP, NDMP9_ADDR_TCP }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_4to9_addr ( ndmp4_addr *addr4, ndmp9_addr *addr9) { switch (addr4->addr_type) { case NDMP4_ADDR_LOCAL: addr9->addr_type = NDMP9_ADDR_LOCAL; break; case NDMP4_ADDR_TCP: addr9->addr_type = NDMP9_ADDR_TCP; if (addr4->ndmp4_addr_u.tcp_addr.tcp_addr_len < 1) return -1; addr9->ndmp9_addr_u.tcp_addr.ip_addr = addr4->ndmp4_addr_u.tcp_addr.tcp_addr_val[0].ip_addr; addr9->ndmp9_addr_u.tcp_addr.port = addr4->ndmp4_addr_u.tcp_addr.tcp_addr_val[0].port; break; default: NDMOS_MACRO_ZEROFILL (addr9); addr9->addr_type = -1; return -1; } return 0; } extern int ndmp_9to4_addr ( ndmp9_addr *addr9, ndmp4_addr *addr4) { ndmp4_tcp_addr * tcp; switch (addr9->addr_type) { case NDMP9_ADDR_LOCAL: addr4->addr_type = NDMP4_ADDR_LOCAL; break; case NDMP9_ADDR_TCP: addr4->addr_type = NDMP4_ADDR_TCP; tcp = NDMOS_MACRO_NEWN(ndmp4_tcp_addr, 1); NDMOS_MACRO_ZEROFILL (tcp); tcp[0].ip_addr = addr9->ndmp9_addr_u.tcp_addr.ip_addr; tcp[0].port = addr9->ndmp9_addr_u.tcp_addr.port; addr4->ndmp4_addr_u.tcp_addr.tcp_addr_val = tcp; addr4->ndmp4_addr_u.tcp_addr.tcp_addr_len = 1; break; default: NDMOS_MACRO_ZEROFILL (addr4); addr4->addr_type = -1; return -1; } return 0; } int ndmp_9to4_addr_free ( ndmp4_addr *addr4) { if (addr4->addr_type == NDMP4_ADDR_TCP) { NDMOS_MACRO_FREE(addr4->ndmp4_addr_u.tcp_addr.tcp_addr_val); } return 0; } /* * CONNECT INTERFACES **************************************************************** */ struct enum_conversion ndmp_49_auth_type[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL }, /* default */ { NDMP4_AUTH_NONE, NDMP9_AUTH_NONE }, { NDMP4_AUTH_TEXT, NDMP9_AUTH_TEXT }, { NDMP4_AUTH_MD5, NDMP9_AUTH_MD5 }, END_ENUM_CONVERSION_TABLE }; int ndmp_4to9_auth_data ( ndmp4_auth_data *auth_data4, ndmp9_auth_data *auth_data9) { int n_error = 0; int rc; ndmp4_auth_text *text4; ndmp9_auth_text *text9; ndmp4_auth_md5 *md54; ndmp9_auth_md5 *md59; switch (auth_data4->auth_type) { case NDMP4_AUTH_NONE: auth_data9->auth_type = NDMP9_AUTH_NONE; break; case NDMP4_AUTH_TEXT: auth_data9->auth_type = NDMP9_AUTH_TEXT; text4 = &auth_data4->ndmp4_auth_data_u.auth_text; text9 = &auth_data9->ndmp9_auth_data_u.auth_text; rc = CNVT_STRDUP_TO_9(text4, text9, auth_id); if (rc) { return rc; /* no mem */ } rc = CNVT_STRDUP_TO_9(text4, text9, auth_password); if (rc) { NDMOS_API_FREE (text9->auth_id); text9->auth_id = 0; return rc; /* no mem */ } break; case NDMP4_AUTH_MD5: auth_data9->auth_type = NDMP9_AUTH_MD5; md54 = &auth_data4->ndmp4_auth_data_u.auth_md5; md59 = &auth_data9->ndmp9_auth_data_u.auth_md5; rc = CNVT_STRDUP_TO_9(md54, md59, auth_id); if (rc) { return rc; /* no mem */ } NDMOS_API_BCOPY (md54->auth_digest, md59->auth_digest, 16); break; default: auth_data9->auth_type = auth_data4->auth_type; NDMOS_MACRO_ZEROFILL (&auth_data9->ndmp9_auth_data_u); n_error++; break; } return n_error; } int ndmp_9to4_auth_data ( ndmp9_auth_data *auth_data9, ndmp4_auth_data *auth_data4) { int n_error = 0; int rc; ndmp9_auth_text *text9; ndmp4_auth_text *text4; ndmp9_auth_md5 *md59; ndmp4_auth_md5 *md54; switch (auth_data9->auth_type) { case NDMP9_AUTH_NONE: auth_data4->auth_type = NDMP4_AUTH_NONE; break; case NDMP9_AUTH_TEXT: auth_data4->auth_type = NDMP4_AUTH_TEXT; text9 = &auth_data9->ndmp9_auth_data_u.auth_text; text4 = &auth_data4->ndmp4_auth_data_u.auth_text; rc = CNVT_STRDUP_FROM_9(text4, text9, auth_id); if (rc) { return rc; /* no mem */ } rc = CNVT_STRDUP_FROM_9(text4, text9, auth_password); if (rc) { NDMOS_API_FREE (text9->auth_id); text4->auth_id = 0; return rc; /* no mem */ } break; case NDMP9_AUTH_MD5: auth_data4->auth_type = NDMP4_AUTH_MD5; md59 = &auth_data9->ndmp9_auth_data_u.auth_md5; md54 = &auth_data4->ndmp4_auth_data_u.auth_md5; rc = CNVT_STRDUP_FROM_9(md54, md59, auth_id); if (rc) { return rc; /* no mem */ } NDMOS_API_BCOPY (md59->auth_digest, md54->auth_digest, 16); break; default: auth_data4->auth_type = auth_data9->auth_type; NDMOS_MACRO_ZEROFILL (&auth_data4->ndmp4_auth_data_u); n_error++; break; } return n_error; } int ndmp_4to9_auth_attr ( ndmp4_auth_attr *auth_attr4, ndmp9_auth_attr *auth_attr9) { int n_error = 0; switch (auth_attr4->auth_type) { case NDMP4_AUTH_NONE: auth_attr9->auth_type = NDMP9_AUTH_NONE; break; case NDMP4_AUTH_TEXT: auth_attr9->auth_type = NDMP9_AUTH_TEXT; break; case NDMP4_AUTH_MD5: auth_attr9->auth_type = NDMP9_AUTH_MD5; NDMOS_API_BCOPY (auth_attr4->ndmp4_auth_attr_u.challenge, auth_attr9->ndmp9_auth_attr_u.challenge, 64); break; default: auth_attr9->auth_type = auth_attr4->auth_type; NDMOS_MACRO_ZEROFILL (&auth_attr9->ndmp9_auth_attr_u); n_error++; break; } return n_error; } int ndmp_9to4_auth_attr ( ndmp9_auth_attr *auth_attr9, ndmp4_auth_attr *auth_attr4) { int n_error = 0; switch (auth_attr9->auth_type) { case NDMP9_AUTH_NONE: auth_attr4->auth_type = NDMP4_AUTH_NONE; break; case NDMP9_AUTH_TEXT: auth_attr4->auth_type = NDMP4_AUTH_TEXT; break; case NDMP9_AUTH_MD5: auth_attr4->auth_type = NDMP4_AUTH_MD5; NDMOS_API_BCOPY (auth_attr9->ndmp9_auth_attr_u.challenge, auth_attr4->ndmp4_auth_attr_u.challenge, 64); break; default: auth_attr4->auth_type = auth_attr9->auth_type; NDMOS_MACRO_ZEROFILL (&auth_attr4->ndmp4_auth_attr_u); n_error++; break; } return n_error; } /* * ndmp_connect_open * just error reply */ int ndmp_4to9_connect_open_request ( ndmp4_connect_open_request *request4, ndmp9_connect_open_request *request9) { CNVT_TO_9 (request4, request9, protocol_version); return 0; } int ndmp_9to4_connect_open_request ( ndmp9_connect_open_request *request9, ndmp4_connect_open_request *request4) { CNVT_FROM_9 (request4, request9, protocol_version); return 0; } /* * ndmp_connect_client_auth * just error reply */ int ndmp_4to9_connect_client_auth_request ( ndmp4_connect_client_auth_request *request4, ndmp9_connect_client_auth_request *request9) { int rc; rc = ndmp_4to9_auth_data (&request4->auth_data, &request9->auth_data); return rc; } int ndmp_9to4_connect_client_auth_request ( ndmp9_connect_client_auth_request *request9, ndmp4_connect_client_auth_request *request4) { int rc; rc = ndmp_9to4_auth_data (&request9->auth_data, &request4->auth_data); return rc; } /* * ndmp_connect_close * no arg request, **NO REPLY** */ /* * ndmp_connect_server_auth */ /* TBD */ int ndmp_4to9_connect_server_auth_request ( ndmp4_connect_server_auth_request *request4, ndmp9_connect_server_auth_request *request9) { return -1; } int ndmp_9to4_connect_server_auth_request ( ndmp9_connect_server_auth_request *request9, ndmp4_connect_server_auth_request *request4) { return -1; } /* * CONFIG INTERFACES **************************************************************** */ /* * ndmp_config_get_host_info * no args request */ int ndmp_4to9_config_get_host_info_reply ( ndmp4_config_get_host_info_reply *reply4, ndmp9_config_get_host_info_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_STRDUP_TO_9x (reply4, reply9, hostname, config_info.hostname); CNVT_STRDUP_TO_9x (reply4, reply9, os_type, config_info.os_type); CNVT_STRDUP_TO_9x (reply4, reply9, os_vers, config_info.os_vers); CNVT_STRDUP_TO_9x (reply4, reply9, hostid, config_info.hostid); return n_error; } int ndmp_9to4_config_get_host_info_reply ( ndmp9_config_get_host_info_reply *reply9, ndmp4_config_get_host_info_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_STRDUP_FROM_9x (reply4, reply9, hostname, config_info.hostname); CNVT_STRDUP_FROM_9x (reply4, reply9, os_type, config_info.os_type); CNVT_STRDUP_FROM_9x (reply4, reply9, os_vers, config_info.os_vers); CNVT_STRDUP_FROM_9x (reply4, reply9, hostid, config_info.hostid); return 0; } /* * ndmp_config_get_connection_type * no args request */ int ndmp_4to9_config_get_connection_type_reply ( ndmp4_config_get_connection_type_reply *reply4, ndmp9_config_get_connection_type_reply *reply9) { int n_error = 0; unsigned int i; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); for (i = 0; i < reply4->addr_types.addr_types_len; i++) { switch (reply4->addr_types.addr_types_val[i]) { case NDMP4_ADDR_LOCAL: reply9->config_info.conntypes |= NDMP9_CONFIG_CONNTYPE_LOCAL; break; case NDMP4_ADDR_TCP: reply9->config_info.conntypes |= NDMP9_CONFIG_CONNTYPE_TCP; break; default: n_error++; /* ignore */ break; } } return n_error; } int ndmp_9to4_config_get_connection_type_reply ( ndmp9_config_get_connection_type_reply *reply9, ndmp4_config_get_connection_type_reply *reply4) { int i = 0; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); reply4->addr_types.addr_types_val = NDMOS_MACRO_NEWN(ndmp4_addr_type, 3); if (!reply4->addr_types.addr_types_val) { return -1; /* no mem */ } i = 0; if (reply9->config_info.conntypes & NDMP9_CONFIG_CONNTYPE_LOCAL) { reply4->addr_types.addr_types_val[i++] = NDMP4_ADDR_LOCAL; } if (reply9->config_info.conntypes & NDMP9_CONFIG_CONNTYPE_TCP) { reply4->addr_types.addr_types_val[i++] = NDMP4_ADDR_TCP; } reply4->addr_types.addr_types_len = i; return 0; } /* * ndmp_config_get_auth_attr */ int ndmp_4to9_config_get_auth_attr_request ( struct ndmp4_config_get_auth_attr_request *request4, struct ndmp9_config_get_auth_attr_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request4, request9, auth_type, ndmp_49_auth_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, auth_type); n_error++; } return n_error; } int ndmp_9to4_config_get_auth_attr_request ( struct ndmp9_config_get_auth_attr_request *request9, struct ndmp4_config_get_auth_attr_request *request4) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request4, request9, auth_type, ndmp_49_auth_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, auth_type); n_error++; } return n_error; } int ndmp_4to9_config_get_auth_attr_reply ( struct ndmp4_config_get_auth_attr_reply *reply4, struct ndmp9_config_get_auth_attr_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); n_error += ndmp_4to9_auth_attr (&reply4->server_attr, &reply9->server_attr); return n_error; } int ndmp_9to4_config_get_auth_attr_reply ( struct ndmp9_config_get_auth_attr_reply *reply9, struct ndmp4_config_get_auth_attr_reply *reply4) { int n_error = 0; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); n_error += ndmp_9to4_auth_attr (&reply9->server_attr, &reply4->server_attr); return n_error; } /* * ndmp_config_get_server_info * no args request */ int ndmp_4to9_config_get_server_info_reply ( ndmp4_config_get_server_info_reply *reply4, ndmp9_config_get_server_info_reply *reply9) { unsigned int i, n_error = 0; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_STRDUP_TO_9x (reply4, reply9, vendor_name, config_info.vendor_name); CNVT_STRDUP_TO_9x (reply4, reply9, product_name, config_info.product_name); CNVT_STRDUP_TO_9x (reply4, reply9, revision_number, config_info.revision_number); reply9->config_info.authtypes = 0; for (i = 0; i < reply4->auth_type.auth_type_len; i++) { switch (reply4->auth_type.auth_type_val[i]) { case NDMP4_AUTH_NONE: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_NONE; break; case NDMP4_AUTH_TEXT: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_TEXT; break; case NDMP4_AUTH_MD5: reply9->config_info.authtypes |= NDMP9_CONFIG_AUTHTYPE_MD5; break; default: n_error++; /* ignore */ break; } } return n_error; } int ndmp_9to4_config_get_server_info_reply ( ndmp9_config_get_server_info_reply *reply9, ndmp4_config_get_server_info_reply *reply4) { int i = 0; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_STRDUP_FROM_9x (reply4, reply9, vendor_name, config_info.vendor_name); CNVT_STRDUP_FROM_9x (reply4, reply9, product_name, config_info.product_name); CNVT_STRDUP_FROM_9x (reply4, reply9, revision_number, config_info.revision_number); reply4->auth_type.auth_type_val = NDMOS_MACRO_NEWN(ndmp4_auth_type, 3); if (!reply4->auth_type.auth_type_val) { return -1; } i = 0; if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_NONE) { reply4->auth_type.auth_type_val[i++] = NDMP4_AUTH_NONE; } if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_TEXT) { reply4->auth_type.auth_type_val[i++] = NDMP4_AUTH_TEXT; } if (reply9->config_info.authtypes & NDMP9_CONFIG_AUTHTYPE_MD5) { reply4->auth_type.auth_type_val[i++] = NDMP4_AUTH_MD5; } reply4->auth_type.auth_type_len = i; return 0; } /* * ndmp_config_get_butype_info * no args request */ int ndmp_4to9_config_get_butype_info_reply ( ndmp4_config_get_butype_info_reply *reply4, ndmp9_config_get_butype_info_reply *reply9) { int n; int i; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); n = reply4->butype_info.butype_info_len; if (n == 0) { reply9->config_info.butype_info.butype_info_len = 0; reply9->config_info.butype_info.butype_info_val = 0; return 0; } reply9->config_info.butype_info.butype_info_val = NDMOS_MACRO_NEWN (ndmp9_butype_info, n); for (i = 0; i < n; i++) { ndmp9_butype_info * bu9; ndmp4_butype_info * bu4; bu4 = &reply4->butype_info.butype_info_val[i]; bu9 = &reply9->config_info.butype_info.butype_info_val[i]; NDMOS_MACRO_ZEROFILL (bu9); CNVT_STRDUP_TO_9 (bu4, bu9, butype_name); ndmp_4to9_pval_vec_dup (bu4->default_env.default_env_val, &bu9->default_env.default_env_val, bu4->default_env.default_env_len); bu9->default_env.default_env_len = bu4->default_env.default_env_len; bu9->v4attr.valid = NDMP9_VALIDITY_VALID; bu9->v4attr.value = bu4->attrs; } reply9->config_info.butype_info.butype_info_len = n; return 0; } int ndmp_9to4_config_get_butype_info_reply ( ndmp9_config_get_butype_info_reply *reply9, ndmp4_config_get_butype_info_reply *reply4) { int n; int i; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); n = reply9->config_info.butype_info.butype_info_len; if (n == 0) { reply4->butype_info.butype_info_len = 0; reply4->butype_info.butype_info_val = 0; return 0; } reply4->butype_info.butype_info_val = NDMOS_MACRO_NEWN (ndmp4_butype_info, n); for (i = 0; i < n; i++) { ndmp4_butype_info * bu4; ndmp9_butype_info * bu9; bu9 = &reply9->config_info.butype_info.butype_info_val[i]; bu4 = &reply4->butype_info.butype_info_val[i]; NDMOS_MACRO_ZEROFILL (bu4); CNVT_STRDUP_FROM_9 (bu4, bu9, butype_name); ndmp_9to4_pval_vec_dup (bu9->default_env.default_env_val, &bu4->default_env.default_env_val, bu9->default_env.default_env_len); bu4->default_env.default_env_len = bu9->default_env.default_env_len; bu4->attrs = bu9->v4attr.value; } reply4->butype_info.butype_info_len = n; return 0; } /* * ndmp_config_get_fs_info * no args request */ int ndmp_4to9_config_get_fs_info_reply ( ndmp4_config_get_fs_info_reply *reply4, ndmp9_config_get_fs_info_reply *reply9) { int n; int i; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); n = reply4->fs_info.fs_info_len; if (n == 0) { reply9->config_info.fs_info.fs_info_len = 0; reply9->config_info.fs_info.fs_info_val = 0; return 0; } reply9->config_info.fs_info.fs_info_val = NDMOS_MACRO_NEWN (ndmp9_fs_info, n); for (i = 0; i < n; i++) { ndmp4_fs_info * fs4; ndmp9_fs_info * fs9; fs4 = &reply4->fs_info.fs_info_val[i]; fs9 = &reply9->config_info.fs_info.fs_info_val[i]; NDMOS_MACRO_ZEROFILL (fs9); CNVT_STRDUP_TO_9 (fs4, fs9, fs_type); CNVT_STRDUP_TO_9 (fs4, fs9, fs_logical_device); CNVT_STRDUP_TO_9 (fs4, fs9, fs_physical_device); CNVT_STRDUP_TO_9 (fs4, fs9, fs_status); ndmp_4to9_pval_vec_dup (fs4->fs_env.fs_env_val, &fs9->fs_env.fs_env_val, fs4->fs_env.fs_env_len); fs9->fs_env.fs_env_len = fs4->fs_env.fs_env_len; } reply9->config_info.fs_info.fs_info_len = n; return 0; } int ndmp_9to4_config_get_fs_info_reply ( ndmp9_config_get_fs_info_reply *reply9, ndmp4_config_get_fs_info_reply *reply4) { int n; int i; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); n = reply9->config_info.fs_info.fs_info_len; if (n == 0) { reply4->fs_info.fs_info_len = 0; reply4->fs_info.fs_info_val = 0; return 0; } reply4->fs_info.fs_info_val = NDMOS_MACRO_NEWN (ndmp4_fs_info, n); for (i = 0; i < n; i++) { ndmp9_fs_info * fs9; ndmp4_fs_info * fs4; fs9 = &reply9->config_info.fs_info.fs_info_val[i]; fs4 = &reply4->fs_info.fs_info_val[i]; NDMOS_MACRO_ZEROFILL (fs4); CNVT_STRDUP_FROM_9 (fs4, fs9, fs_type); CNVT_STRDUP_FROM_9 (fs4, fs9, fs_logical_device); CNVT_STRDUP_FROM_9 (fs4, fs9, fs_physical_device); CNVT_STRDUP_FROM_9 (fs4, fs9, fs_status); ndmp_9to4_pval_vec_dup (fs9->fs_env.fs_env_val, &fs4->fs_env.fs_env_val, fs9->fs_env.fs_env_len); fs4->fs_env.fs_env_len = fs9->fs_env.fs_env_len; } reply4->fs_info.fs_info_len = n; return 0; } /* * ndmp_config_get_tape_info * no args request */ /* * ndmp_config_get_scsi_info * no args request */ int ndmp_4to9_device_info_vec_dup ( ndmp4_device_info *devinf4, ndmp9_device_info **devinf9_p, int n_devinf) { ndmp9_device_info * devinf9; int i; unsigned int j; devinf9 = *devinf9_p = NDMOS_MACRO_NEWN(ndmp9_device_info, n_devinf); if (!devinf9) { return -1; /* no mem */ } for (i = 0; i < n_devinf; i++) { ndmp4_device_info * di4 = &devinf4[i]; ndmp9_device_info * di9 = &devinf9[i]; NDMOS_MACRO_ZEROFILL (di9); CNVT_STRDUP_TO_9 (di4, di9, model); di9->caplist.caplist_val = NDMOS_MACRO_NEWN (ndmp9_device_capability, di4->caplist.caplist_len); if (!di9->caplist.caplist_val) { return -1; } for (j = 0; j < di4->caplist.caplist_len; j++) { ndmp4_device_capability * cap4; ndmp9_device_capability * cap9; cap4 = &di4->caplist.caplist_val[j]; cap9 = &di9->caplist.caplist_val[j]; NDMOS_MACRO_ZEROFILL (cap9); cap9->v4attr.valid = NDMP9_VALIDITY_VALID; cap9->v4attr.value = cap4->attr; CNVT_STRDUP_TO_9 (cap4, cap9, device); ndmp_4to9_pval_vec_dup ( cap4->capability.capability_val, &cap9->capability.capability_val, cap4->capability.capability_len); cap9->capability.capability_len = cap4->capability.capability_len; } di9->caplist.caplist_len = j; } return 0; } int ndmp_9to4_device_info_vec_dup ( ndmp9_device_info *devinf9, ndmp4_device_info **devinf4_p, int n_devinf) { ndmp4_device_info * devinf4; int i; unsigned int j; devinf4 = *devinf4_p = NDMOS_MACRO_NEWN(ndmp4_device_info, n_devinf); if (!devinf4) { return -1; /* no mem */ } for (i = 0; i < n_devinf; i++) { ndmp9_device_info * di9 = &devinf9[i]; ndmp4_device_info * di4 = &devinf4[i]; NDMOS_MACRO_ZEROFILL (di4); CNVT_STRDUP_FROM_9 (di4, di9, model); di4->caplist.caplist_val = NDMOS_MACRO_NEWN (ndmp4_device_capability, di9->caplist.caplist_len); if (!di4->caplist.caplist_val) { return -1; } for (j = 0; j < di9->caplist.caplist_len; j++) { ndmp9_device_capability * cap9; ndmp4_device_capability * cap4; cap9 = &di9->caplist.caplist_val[j]; cap4 = &di4->caplist.caplist_val[j]; NDMOS_MACRO_ZEROFILL (cap4); CNVT_STRDUP_FROM_9 (cap4, cap9, device); ndmp_9to4_pval_vec_dup ( cap9->capability.capability_val, &cap4->capability.capability_val, cap9->capability.capability_len); cap4->capability.capability_len = cap9->capability.capability_len; } di4->caplist.caplist_len = j; } return 0; } int ndmp_4to9_config_get_tape_info_reply ( ndmp4_config_get_tape_info_reply *reply4, ndmp9_config_get_tape_info_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); ndmp_4to9_device_info_vec_dup ( reply4->tape_info.tape_info_val, &reply9->config_info.tape_info.tape_info_val, reply4->tape_info.tape_info_len); reply9->config_info.tape_info.tape_info_len = reply4->tape_info.tape_info_len; return 0; } int ndmp_9to4_config_get_tape_info_reply ( ndmp9_config_get_tape_info_reply *reply9, ndmp4_config_get_tape_info_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); ndmp_9to4_device_info_vec_dup ( reply9->config_info.tape_info.tape_info_val, &reply4->tape_info.tape_info_val, reply9->config_info.tape_info.tape_info_len); reply4->tape_info.tape_info_len = reply9->config_info.tape_info.tape_info_len; return 0; } int ndmp_4to9_config_get_scsi_info_reply ( ndmp4_config_get_scsi_info_reply *reply4, ndmp9_config_get_scsi_info_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); ndmp_4to9_device_info_vec_dup ( reply4->scsi_info.scsi_info_val, &reply9->config_info.scsi_info.scsi_info_val, reply4->scsi_info.scsi_info_len); reply9->config_info.scsi_info.scsi_info_len = reply4->scsi_info.scsi_info_len; return 0; } int ndmp_9to4_config_get_scsi_info_reply ( ndmp9_config_get_scsi_info_reply *reply9, ndmp4_config_get_scsi_info_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); ndmp_9to4_device_info_vec_dup ( reply9->config_info.scsi_info.scsi_info_val, &reply4->scsi_info.scsi_info_val, reply9->config_info.scsi_info.scsi_info_len); reply4->scsi_info.scsi_info_len = reply9->config_info.scsi_info.scsi_info_len; return 0; } /* * SCSI INTERFACES **************************************************************** */ /* * ndmp_scsi_open * just error reply */ int ndmp_4to9_scsi_open_request ( ndmp4_scsi_open_request *request4, ndmp9_scsi_open_request *request9) { request9->device = NDMOS_API_STRDUP (request4->device); if (!request9->device) { return -1; /* no memory */ } return 0; } int ndmp_9to4_scsi_open_request ( ndmp9_scsi_open_request *request9, ndmp4_scsi_open_request *request4) { request4->device = NDMOS_API_STRDUP (request9->device); if (!request4->device) { return -1; /* no memory */ } return 0; } /* * ndmp_scsi_close * no args request, just error reply */ /* * ndmp_scsi_get_state * no args request */ int ndmp_4to9_scsi_get_state_reply ( ndmp4_scsi_get_state_reply *reply4, ndmp9_scsi_get_state_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_TO_9 (reply4, reply9, target_controller); CNVT_TO_9 (reply4, reply9, target_id); CNVT_TO_9 (reply4, reply9, target_lun); return 0; } int ndmp_9to4_scsi_get_state_reply ( ndmp9_scsi_get_state_reply *reply9, ndmp4_scsi_get_state_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_FROM_9 (reply4, reply9, target_controller); CNVT_FROM_9 (reply4, reply9, target_id); CNVT_FROM_9 (reply4, reply9, target_lun); return 0; } /* * ndmp_scsi_set_target -- deprecated * just error reply */ /* * ndmp_scsi_reset_device * no args request, just error reply */ /* * ndmp_scsi_reset_bus -- deprecated * no args request, just error reply */ /* * ndmp_tape_execute_cdb * ndmp_scsi_execute_cdb */ int ndmp_4to9_execute_cdb_request ( ndmp4_execute_cdb_request *request4, ndmp9_execute_cdb_request *request9) { int n_error = 0; uint32_t len; char * p; switch (request4->flags) { case 0: request9->data_dir = NDMP9_SCSI_DATA_DIR_NONE; break; case NDMP4_SCSI_DATA_IN: request9->data_dir = NDMP9_SCSI_DATA_DIR_IN; break; case NDMP4_SCSI_DATA_OUT: request9->data_dir = NDMP9_SCSI_DATA_DIR_IN; break; default: /* deemed insolvable */ n_error++; return -1; } CNVT_TO_9 (request4, request9, timeout); CNVT_TO_9 (request4, request9, datain_len); len = request4->dataout.dataout_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request4->dataout.dataout_val, p, len); } else { len = 0; p = 0; } request9->dataout.dataout_len = len; request9->dataout.dataout_val = p; len = request4->cdb.cdb_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (request9->dataout.dataout_val) { NDMOS_API_FREE (request9->dataout.dataout_val); request9->dataout.dataout_len = 0; request9->dataout.dataout_val = 0; } return -1; } NDMOS_API_BCOPY (request4->cdb.cdb_val, p, len); } else { len = 0; p = 0; } request9->cdb.cdb_len = len; request9->cdb.cdb_val = p; return 0; } int ndmp_9to4_execute_cdb_request ( ndmp9_execute_cdb_request *request9, ndmp4_execute_cdb_request *request4) { int n_error = 0; uint32_t len; char * p; switch (request9->data_dir) { case NDMP9_SCSI_DATA_DIR_NONE: request4->flags = 0; break; case NDMP9_SCSI_DATA_DIR_IN: request4->flags = NDMP4_SCSI_DATA_IN; break; case NDMP9_SCSI_DATA_DIR_OUT: request4->flags = NDMP4_SCSI_DATA_OUT; break; default: /* deemed insolvable */ n_error++; return -1; } CNVT_FROM_9 (request4, request9, timeout); CNVT_FROM_9 (request4, request9, datain_len); len = request9->dataout.dataout_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request9->dataout.dataout_val, p, len); } else { len = 0; p = 0; } request4->dataout.dataout_len = len; request4->dataout.dataout_val = p; len = request9->cdb.cdb_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (request4->dataout.dataout_val) { NDMOS_API_FREE (request4->dataout.dataout_val); request4->dataout.dataout_len = 0; request4->dataout.dataout_val = 0; } return -1; } NDMOS_API_BCOPY (request9->cdb.cdb_val, p, len); } else { len = 0; p = 0; } request4->cdb.cdb_len = len; request4->cdb.cdb_val = p; return 0; } int ndmp_4to9_execute_cdb_reply ( ndmp4_execute_cdb_reply *reply4, ndmp9_execute_cdb_reply *reply9) { uint32_t len; char * p; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_TO_9 (reply4, reply9, status); CNVT_TO_9 (reply4, reply9, dataout_len); len = reply4->datain.datain_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply4->datain.datain_val, p, len); } else { len = 0; p = 0; } reply9->datain.datain_len = len; reply9->datain.datain_val = p; len = reply4->ext_sense.ext_sense_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (reply9->datain.datain_val) { NDMOS_API_FREE (reply9->datain.datain_val); reply9->datain.datain_len = 0; reply9->datain.datain_val = 0; } return -1; } NDMOS_API_BCOPY (reply4->ext_sense.ext_sense_val, p, len); } else { len = 0; p = 0; } reply9->ext_sense.ext_sense_len = len; reply9->ext_sense.ext_sense_val = p; return 0; } int ndmp_9to4_execute_cdb_reply ( ndmp9_execute_cdb_reply *reply9, ndmp4_execute_cdb_reply *reply4) { uint32_t len; char * p; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_FROM_9 (reply4, reply9, status); CNVT_FROM_9 (reply4, reply9, dataout_len); len = reply9->datain.datain_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply9->datain.datain_val, p, len); } else { len = 0; p = 0; } reply4->datain.datain_len = len; reply4->datain.datain_val = p; len = reply9->ext_sense.ext_sense_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { if (reply4->datain.datain_val) { NDMOS_API_FREE (reply9->datain.datain_val); reply4->datain.datain_len = 0; reply4->datain.datain_val = 0; } return -1; } NDMOS_API_BCOPY (reply9->ext_sense.ext_sense_val, p, len); } else { len = 0; p = 0; } reply4->ext_sense.ext_sense_len = len; reply4->ext_sense.ext_sense_val = p; return 0; } /* * TAPE INTERFACES **************************************************************** */ /* * ndmp_tape_open_request */ struct enum_conversion ndmp_49_tape_open_mode[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_TAPE_READ_MODE, NDMP9_TAPE_READ_MODE }, { NDMP4_TAPE_RDWR_MODE, NDMP9_TAPE_RDWR_MODE }, END_ENUM_CONVERSION_TABLE }; int ndmp_4to9_tape_open_request ( ndmp4_tape_open_request *request4, ndmp9_tape_open_request *request9) { int n_error = 0; int rc; /* * Mode codes are compatible between versions. * We let untranslated values through to * facilitate testing illegal values. */ rc = convert_enum_to_9 (ndmp_49_tape_open_mode, request4->mode); if (rc == NDMP_INVALID_GENERAL) { n_error++; request9->mode = request4->mode; } else { request9->mode = rc; } request9->device = NDMOS_API_STRDUP (request4->device); if (!request9->device) { return -1; /* no memory */ } return n_error; } int ndmp_4to9_tape_open_free_request ( ndmp9_tape_open_request *request9) { NDMOS_API_FREE(request9->device); request9->device = NULL; return 0; } int ndmp_9to4_tape_open_request ( ndmp9_tape_open_request *request9, ndmp4_tape_open_request *request4) { int n_error = 0; int rc; rc = convert_enum_from_9 (ndmp_49_tape_open_mode, request9->mode); if (rc == NDMP_INVALID_GENERAL) { n_error++; request4->mode = request9->mode; } else { request4->mode = rc; } request4->device = NDMOS_API_STRDUP (request9->device); if (!request4->device) { return -1; /* no memory */ } return n_error; } /* * ndmp_tape_get_state_reply **************************************************************** */ extern int ndmp_4to9_tape_get_state_reply ( ndmp4_tape_get_state_reply *reply4, ndmp9_tape_get_state_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_TO_9 (reply4, reply9, flags); CNVT_VUL_TO_9 (reply4, reply9, file_num); CNVT_VUL_TO_9 (reply4, reply9, soft_errors); CNVT_VUL_TO_9 (reply4, reply9, block_size); CNVT_VUL_TO_9 (reply4, reply9, blockno); CNVT_VUQ_TO_9 (reply4, reply9, total_space); CNVT_VUQ_TO_9 (reply4, reply9, space_remain); #if 0 CNVT_VUL_TO_9 (reply4, reply9, partition); #endif if (reply4->unsupported & NDMP4_TAPE_STATE_FILE_NUM_UNS) CNVT_IUL_TO_9 (reply9, file_num); if (reply4->unsupported & NDMP4_TAPE_STATE_SOFT_ERRORS_UNS) CNVT_IUL_TO_9 (reply9, soft_errors); if (reply4->unsupported & NDMP4_TAPE_STATE_BLOCK_SIZE_UNS) CNVT_IUL_TO_9 (reply9, block_size); if (reply4->unsupported & NDMP4_TAPE_STATE_BLOCKNO_UNS) CNVT_IUL_TO_9 (reply9, blockno); if (reply4->unsupported & NDMP4_TAPE_STATE_TOTAL_SPACE_UNS) CNVT_IUQ_TO_9 (reply9, total_space); if (reply4->unsupported & NDMP4_TAPE_STATE_SPACE_REMAIN_UNS) CNVT_IUQ_TO_9 (reply9, space_remain); #if 0 if (reply4->unsupported & NDMP4_TAPE_STATE_PARTITION_UNS) CNVT_IUL_TO_9 (reply9, partition); #endif return 0; } extern int ndmp_9to4_tape_get_state_reply ( ndmp9_tape_get_state_reply *reply9, ndmp4_tape_get_state_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_FROM_9 (reply4, reply9, flags); CNVT_VUL_FROM_9 (reply4, reply9, file_num); CNVT_VUL_FROM_9 (reply4, reply9, soft_errors); CNVT_VUL_FROM_9 (reply4, reply9, block_size); CNVT_VUL_FROM_9 (reply4, reply9, blockno); CNVT_VUQ_FROM_9 (reply4, reply9, total_space); CNVT_VUQ_FROM_9 (reply4, reply9, space_remain); #if 0 CNVT_VUL_FROM_9 (reply4, reply9, partition); #endif reply4->unsupported = 0; if (!reply9->file_num.valid) reply4->unsupported |= NDMP4_TAPE_STATE_FILE_NUM_UNS; if (!reply9->soft_errors.valid) reply4->unsupported |= NDMP4_TAPE_STATE_SOFT_ERRORS_UNS; if (!reply9->block_size.valid) reply4->unsupported |= NDMP4_TAPE_STATE_BLOCK_SIZE_UNS; if (!reply9->blockno.valid) reply4->unsupported |= NDMP4_TAPE_STATE_BLOCKNO_UNS; if (!reply9->total_space.valid) reply4->unsupported |= NDMP4_TAPE_STATE_TOTAL_SPACE_UNS; if (!reply9->space_remain.valid) reply4->unsupported |= NDMP4_TAPE_STATE_SPACE_REMAIN_UNS; #if 0 if (!reply9->partition.valid) reply4->unsupported |= NDMP4_TAPE_STATE_PARTITION_UNS; #endif return 0; } /* * ndmp_tape_mtio_request */ struct enum_conversion ndmp_49_tape_mtio_op[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_MTIO_FSF, NDMP9_MTIO_FSF }, { NDMP4_MTIO_BSF, NDMP9_MTIO_BSF }, { NDMP4_MTIO_FSR, NDMP9_MTIO_FSR }, { NDMP4_MTIO_BSR, NDMP9_MTIO_BSR }, { NDMP4_MTIO_REW, NDMP9_MTIO_REW }, { NDMP4_MTIO_EOF, NDMP9_MTIO_EOF }, { NDMP4_MTIO_OFF, NDMP9_MTIO_OFF }, END_ENUM_CONVERSION_TABLE }; int ndmp_4to9_tape_mtio_request ( ndmp4_tape_mtio_request *request4, ndmp9_tape_mtio_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request4, request9, tape_op, ndmp_49_tape_mtio_op); if (rc == NDMP_INVALID_GENERAL) { n_error++; CNVT_TO_9(request4, request9, tape_op); } CNVT_TO_9(request4, request9, count); return n_error; } int ndmp_9to4_tape_mtio_request ( ndmp9_tape_mtio_request *request9, ndmp4_tape_mtio_request *request4) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request4, request9, tape_op, ndmp_49_tape_mtio_op); if (rc == NDMP_INVALID_GENERAL) { n_error++; CNVT_FROM_9(request4, request9, tape_op); } CNVT_FROM_9(request4, request9, count); return n_error; } int ndmp_4to9_tape_mtio_reply ( ndmp4_tape_mtio_reply *reply4, ndmp9_tape_mtio_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_TO_9 (reply4, reply9, resid_count); return 0; } int ndmp_9to4_tape_mtio_reply ( ndmp9_tape_mtio_reply *reply9, ndmp4_tape_mtio_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_FROM_9 (reply4, reply9, resid_count); return 0; } /* * ndmp_tape_write */ int ndmp_4to9_tape_write_request ( ndmp4_tape_write_request *request4, ndmp9_tape_write_request *request9) { uint32_t len; char * p; len = request4->data_out.data_out_len; p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request4->data_out.data_out_val, p, len); request9->data_out.data_out_val = p; request9->data_out.data_out_len = len; return 0; } int ndmp_9to4_tape_write_request ( ndmp9_tape_write_request *request9, ndmp4_tape_write_request *request4) { uint32_t len; char * p; len = request9->data_out.data_out_len; p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (request9->data_out.data_out_val, p, len); request4->data_out.data_out_val = p; request4->data_out.data_out_len = len; return 0; } int ndmp_4to9_tape_write_reply ( ndmp4_tape_write_reply *reply4, ndmp9_tape_write_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_TO_9 (reply4, reply9, count); return 0; } int ndmp_9to4_tape_write_reply ( ndmp9_tape_write_reply *reply9, ndmp4_tape_write_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_FROM_9 (reply4, reply9, count); return 0; } /* * ndmp_tape_read */ int ndmp_4to9_tape_read_request ( ndmp4_tape_read_request *request4, ndmp9_tape_read_request *request9) { CNVT_TO_9 (request4, request9, count); return 0; } int ndmp_9to4_tape_read_request ( ndmp9_tape_read_request *request9, ndmp4_tape_read_request *request4) { CNVT_FROM_9 (request4, request9, count); return 0; } int ndmp_4to9_tape_read_reply ( ndmp4_tape_read_reply *reply4, ndmp9_tape_read_reply *reply9) { uint32_t len; char * p; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); len = reply4->data_in.data_in_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply4->data_in.data_in_val, p, len); } else { p = 0; len = 0; } reply9->data_in.data_in_len = len; reply9->data_in.data_in_val = p; return 0; } int ndmp_9to4_tape_read_reply ( ndmp9_tape_read_reply *reply9, ndmp4_tape_read_reply *reply4) { uint32_t len; char * p; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); len = reply9->data_in.data_in_len; if (len > 0) { p = NDMOS_API_MALLOC (len); if (!p) { return -1; } NDMOS_API_BCOPY (reply9->data_in.data_in_val, p, len); } else { p = 0; len = 0; } reply4->data_in.data_in_len = len; reply4->data_in.data_in_val = p; return 0; } /* * MOVER INTERFACES **************************************************************** */ /* * ndmp_mover_get_state * no args request */ struct enum_conversion ndmp_49_mover_mode[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_MOVER_MODE_READ, NDMP9_MOVER_MODE_READ }, { NDMP4_MOVER_MODE_WRITE, NDMP9_MOVER_MODE_WRITE }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_49_mover_state[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_MOVER_STATE_IDLE, NDMP9_MOVER_STATE_IDLE }, { NDMP4_MOVER_STATE_LISTEN, NDMP9_MOVER_STATE_LISTEN }, { NDMP4_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_ACTIVE }, { NDMP4_MOVER_STATE_PAUSED, NDMP9_MOVER_STATE_PAUSED }, { NDMP4_MOVER_STATE_HALTED, NDMP9_MOVER_STATE_HALTED }, /* alias */ { NDMP4_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_STANDBY }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_49_mover_pause_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_MOVER_PAUSE_NA, NDMP9_MOVER_PAUSE_NA }, { NDMP4_MOVER_PAUSE_EOM, NDMP9_MOVER_PAUSE_EOM }, { NDMP4_MOVER_PAUSE_EOF, NDMP9_MOVER_PAUSE_EOF }, { NDMP4_MOVER_PAUSE_SEEK, NDMP9_MOVER_PAUSE_SEEK }, /* no NDMP4_MOVER_PAUSE_MEDIA_ERROR, so use EOF */ { NDMP4_MOVER_PAUSE_EOF, NDMP9_MOVER_PAUSE_MEDIA_ERROR }, { NDMP4_MOVER_PAUSE_EOW, NDMP9_MOVER_PAUSE_EOW }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_49_mover_halt_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_MOVER_HALT_NA, NDMP9_MOVER_HALT_NA }, { NDMP4_MOVER_HALT_CONNECT_CLOSED, NDMP9_MOVER_HALT_CONNECT_CLOSED }, { NDMP4_MOVER_HALT_ABORTED, NDMP9_MOVER_HALT_ABORTED }, { NDMP4_MOVER_HALT_INTERNAL_ERROR, NDMP9_MOVER_HALT_INTERNAL_ERROR }, { NDMP4_MOVER_HALT_CONNECT_ERROR, NDMP9_MOVER_HALT_CONNECT_ERROR }, { NDMP4_MOVER_HALT_MEDIA_ERROR, NDMP9_MOVER_HALT_MEDIA_ERROR }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_4to9_mover_get_state_reply ( ndmp4_mover_get_state_reply *reply4, ndmp9_mover_get_state_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_E_TO_9 (reply4, reply9, state, ndmp_49_mover_state); CNVT_E_TO_9 (reply4, reply9, pause_reason, ndmp_49_mover_pause_reason); CNVT_E_TO_9 (reply4, reply9, halt_reason, ndmp_49_mover_halt_reason); CNVT_TO_9 (reply4, reply9, record_size); CNVT_TO_9 (reply4, reply9, record_num); CNVT_TO_9 (reply4, reply9, bytes_moved); CNVT_TO_9 (reply4, reply9, seek_position); CNVT_TO_9 (reply4, reply9, bytes_left_to_read); CNVT_TO_9 (reply4, reply9, window_offset); CNVT_TO_9 (reply4, reply9, window_length); ndmp_4to9_addr (&reply4->data_connection_addr, &reply9->data_connection_addr); return 0; } extern int ndmp_9to4_mover_get_state_reply ( ndmp9_mover_get_state_reply *reply9, ndmp4_mover_get_state_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_E_FROM_9 (reply4, reply9, state, ndmp_49_mover_state); CNVT_E_FROM_9 (reply4, reply9, pause_reason, ndmp_49_mover_pause_reason); CNVT_E_FROM_9 (reply4, reply9, halt_reason, ndmp_49_mover_halt_reason); CNVT_FROM_9 (reply4, reply9, record_size); CNVT_FROM_9 (reply4, reply9, record_num); CNVT_FROM_9 (reply4, reply9, bytes_moved); CNVT_FROM_9 (reply4, reply9, seek_position); CNVT_FROM_9 (reply4, reply9, bytes_left_to_read); CNVT_FROM_9 (reply4, reply9, window_offset); CNVT_FROM_9 (reply4, reply9, window_length); ndmp_9to4_addr (&reply9->data_connection_addr, &reply4->data_connection_addr); return 0; } int ndmp_9to4_mover_get_state_free_reply( ndmp4_mover_get_state_reply *reply4) { // ndmp_9to4_addr_free(&reply4->data_connection_addr); return 0; } /* * ndmp_mover_listen */ int ndmp_4to9_mover_listen_request ( ndmp4_mover_listen_request *request4, ndmp9_mover_listen_request *request9) { int rc; rc = CNVT_E_TO_9 (request4, request9, mode, ndmp_49_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, mode); } rc = CNVT_E_TO_9 (request4, request9, addr_type, ndmp_49_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, addr_type); } return 0; } int ndmp_9to4_mover_listen_request ( ndmp9_mover_listen_request *request9, ndmp4_mover_listen_request *request4) { int rc; rc = CNVT_E_FROM_9 (request4, request9, mode, ndmp_49_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, mode); } rc = CNVT_E_FROM_9 (request4, request9, addr_type, ndmp_49_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, addr_type); } return 0; } int ndmp_4to9_mover_listen_reply ( ndmp4_mover_listen_reply *reply4, ndmp9_mover_listen_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); n_error += ndmp_4to9_addr (&reply4->connect_addr, &reply9->data_connection_addr); return n_error; } int ndmp_9to4_mover_listen_reply ( ndmp9_mover_listen_reply *reply9, ndmp4_mover_listen_reply *reply4) { int n_error = 0; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); n_error += ndmp_9to4_addr (&reply9->data_connection_addr, &reply4->connect_addr); return n_error; } /* * ndmp_mover_connect * just error reply */ int ndmp_4to9_mover_connect_request ( ndmp4_mover_connect_request *request4, ndmp9_mover_connect_request *request9) { int rc; rc = CNVT_E_TO_9 (request4, request9, mode, ndmp_49_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, mode); } return ndmp_4to9_addr (&request4->addr, &request9->addr); } int ndmp_9to4_mover_connect_request ( ndmp9_mover_connect_request *request9, ndmp4_mover_connect_request *request4) { int rc; rc = CNVT_E_FROM_9 (request4, request9, mode, ndmp_49_mover_mode); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, mode); } return ndmp_9to4_addr (&request9->addr, &request4->addr); } /* * ndmp_mover_set_record_size * just error reply */ int ndmp_4to9_mover_set_record_size_request ( ndmp4_mover_set_record_size_request *request4, ndmp9_mover_set_record_size_request *request9) { CNVT_TO_9x (request4, request9, len, record_size); return 0; } int ndmp_9to4_mover_set_record_size_request ( ndmp9_mover_set_record_size_request *request9, ndmp4_mover_set_record_size_request *request4) { CNVT_FROM_9x (request4, request9, len, record_size); return 0; } /* * ndmp_mover_set_window * just error reply */ int ndmp_4to9_mover_set_window_request ( ndmp4_mover_set_window_request *request4, ndmp9_mover_set_window_request *request9) { CNVT_TO_9 (request4, request9, offset); CNVT_TO_9 (request4, request9, length); return 0; } int ndmp_9to4_mover_set_window_request ( ndmp9_mover_set_window_request *request9, ndmp4_mover_set_window_request *request4) { CNVT_FROM_9 (request4, request9, offset); CNVT_FROM_9 (request4, request9, length); return 0; } /* * ndmp_mover_continue * no args request, just error reply */ /* * ndmp_mover_abort * no args request, just error reply */ /* * ndmp_mover_stop * no args request, just error reply */ /* * ndmp_mover_read * just error reply */ int ndmp_4to9_mover_read_request ( ndmp4_mover_read_request *request4, ndmp9_mover_read_request *request9) { CNVT_TO_9 (request4, request9, offset); CNVT_TO_9 (request4, request9, length); return 0; } int ndmp_9to4_mover_read_request ( ndmp9_mover_read_request *request9, ndmp4_mover_read_request *request4) { CNVT_FROM_9 (request4, request9, offset); CNVT_FROM_9 (request4, request9, length); return 0; } /* * ndmp_mover_close * no args request, just error reply */ /* * DATA INTERFACES */ /* * ndmp_name **************************************************************** */ int ndmp_4to9_name ( ndmp4_name *name4, ndmp9_name *name9) { name9->original_path = NDMOS_API_STRDUP(name4->original_path); name9->destination_path = NDMOS_API_STRDUP(name4->destination_path); name9->name = NDMOS_API_STRDUP(name4->name); name9->other_name = NDMOS_API_STRDUP(name4->other_name); name9->node = name4->node; if (name4->fh_info != NDMP_INVALID_U_QUAD) { name9->fh_info.valid = NDMP9_VALIDITY_VALID; name9->fh_info.value = name4->fh_info; } else { name9->fh_info.valid = NDMP9_VALIDITY_INVALID; name9->fh_info.value = NDMP_INVALID_U_QUAD; } return 0; } int ndmp_9to4_name ( ndmp9_name *name9, ndmp4_name *name4) { name4->original_path = NDMOS_API_STRDUP(name9->original_path); name4->destination_path = NDMOS_API_STRDUP(name9->destination_path); name4->name = NDMOS_API_STRDUP(name9->name); name4->other_name = NDMOS_API_STRDUP(name9->other_name); name4->node = name9->node; if (name9->fh_info.valid == NDMP9_VALIDITY_VALID) { name4->fh_info = name9->fh_info.value; } else { name4->fh_info = NDMP_INVALID_U_QUAD; } return 0; } int ndmp_4to9_name_vec ( ndmp4_name *name4, ndmp9_name *name9, unsigned n_name) { unsigned int i; for (i = 0; i < n_name; i++) ndmp_4to9_name (&name4[i], &name9[i]); return 0; } int ndmp_9to4_name_vec ( ndmp9_name *name9, ndmp4_name *name4, unsigned n_name) { unsigned int i; for (i = 0; i < n_name; i++) ndmp_9to4_name (&name9[i], &name4[i]); return 0; } int ndmp_4to9_name_vec_dup ( ndmp4_name *name4, ndmp9_name **name9_p, unsigned n_name) { *name9_p = NDMOS_MACRO_NEWN (ndmp9_name, n_name); if (!*name9_p) return -1; return ndmp_4to9_name_vec (name4, *name9_p, n_name); } int ndmp_9to4_name_vec_dup ( ndmp9_name *name9, ndmp4_name **name4_p, unsigned n_name) { *name4_p = NDMOS_MACRO_NEWN (ndmp4_name, n_name); if (!*name4_p) return -1; return ndmp_9to4_name_vec (name9, *name4_p, n_name); } /* * ndmp_data_get_state_reply **************************************************************** */ struct enum_conversion ndmp_49_data_operation[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_DATA_OP_NOACTION, NDMP9_DATA_OP_NOACTION }, { NDMP4_DATA_OP_BACKUP, NDMP9_DATA_OP_BACKUP }, { NDMP4_DATA_OP_RECOVER, NDMP9_DATA_OP_RECOVER }, { NDMP4_DATA_OP_RECOVER_FILEHIST, NDMP9_DATA_OP_RECOVER_FILEHIST }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_49_data_state[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_DATA_STATE_IDLE, NDMP9_DATA_STATE_IDLE }, { NDMP4_DATA_STATE_ACTIVE, NDMP9_DATA_STATE_ACTIVE }, { NDMP4_DATA_STATE_HALTED, NDMP9_DATA_STATE_HALTED }, { NDMP4_DATA_STATE_CONNECTED, NDMP9_DATA_STATE_CONNECTED }, { NDMP4_DATA_STATE_LISTEN, NDMP9_DATA_STATE_LISTEN }, END_ENUM_CONVERSION_TABLE }; struct enum_conversion ndmp_49_data_halt_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_DATA_HALT_NA, NDMP9_DATA_HALT_NA }, { NDMP4_DATA_HALT_SUCCESSFUL, NDMP9_DATA_HALT_SUCCESSFUL }, { NDMP4_DATA_HALT_ABORTED, NDMP9_DATA_HALT_ABORTED }, { NDMP4_DATA_HALT_INTERNAL_ERROR, NDMP9_DATA_HALT_INTERNAL_ERROR }, { NDMP4_DATA_HALT_CONNECT_ERROR, NDMP9_DATA_HALT_CONNECT_ERROR }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_4to9_data_get_state_reply ( ndmp4_data_get_state_reply *reply4, ndmp9_data_get_state_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); CNVT_E_TO_9 (reply4, reply9, operation, ndmp_49_data_operation); CNVT_E_TO_9 (reply4, reply9, state, ndmp_49_data_state); CNVT_E_TO_9 (reply4, reply9, halt_reason, ndmp_49_data_halt_reason); CNVT_TO_9 (reply4, reply9, bytes_processed); CNVT_VUQ_TO_9 (reply4, reply9, est_bytes_remain); CNVT_VUL_TO_9 (reply4, reply9, est_time_remain); ndmp_4to9_addr (&reply4->data_connection_addr, &reply9->data_connection_addr); CNVT_TO_9 (reply4, reply9, read_offset); CNVT_TO_9 (reply4, reply9, read_length); return 0; } extern int ndmp_9to4_data_get_state_reply ( ndmp9_data_get_state_reply *reply9, ndmp4_data_get_state_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); CNVT_E_FROM_9 (reply4, reply9, operation, ndmp_49_data_operation); CNVT_E_FROM_9 (reply4, reply9, state, ndmp_49_data_state); CNVT_E_FROM_9 (reply4, reply9, halt_reason, ndmp_49_data_halt_reason); CNVT_FROM_9 (reply4, reply9, bytes_processed); CNVT_VUQ_FROM_9 (reply4, reply9, est_bytes_remain); CNVT_VUL_FROM_9 (reply4, reply9, est_time_remain); ndmp_9to4_addr (&reply9->data_connection_addr, &reply4->data_connection_addr); CNVT_FROM_9 (reply4, reply9, read_offset); CNVT_FROM_9 (reply4, reply9, read_length); return 0; } /* * ndmp_data_start_backup * just error reply */ int ndmp_4to9_data_start_backup_request ( ndmp4_data_start_backup_request *request4, ndmp9_data_start_backup_request *request9) { int n_error = 0; CNVT_STRDUP_TO_9x (request4, request9, butype_name, bu_type); ndmp_4to9_pval_vec_dup (request4->env.env_val, &request9->env.env_val, request4->env.env_len); request9->env.env_len = request4->env.env_len; request9->addr.addr_type = NDMP9_ADDR_AS_CONNECTED; return n_error; } int ndmp_9to4_data_start_backup_request ( ndmp9_data_start_backup_request *request9, ndmp4_data_start_backup_request *request4) { int n_error = 0; CNVT_STRDUP_FROM_9x (request4, request9, butype_name, bu_type); ndmp_9to4_pval_vec_dup (request9->env.env_val, &request4->env.env_val, request9->env.env_len); request4->env.env_len = request9->env.env_len; return n_error; } /* * ndmp_data_start_recover * ndmp_data_start_recover_filehist * just error reply */ int ndmp_4to9_data_start_recover_request ( ndmp4_data_start_recover_request *request4, ndmp9_data_start_recover_request *request9) { int n_error = 0; CNVT_STRDUP_TO_9x (request4, request9, butype_name, bu_type); ndmp_4to9_pval_vec_dup (request4->env.env_val, &request9->env.env_val, request4->env.env_len); request9->env.env_len = request4->env.env_len; ndmp_4to9_name_vec_dup (request4->nlist.nlist_val, &request9->nlist.nlist_val, request4->nlist.nlist_len); request9->nlist.nlist_len = request4->nlist.nlist_len; request9->addr.addr_type = NDMP9_ADDR_AS_CONNECTED; return n_error; } int ndmp_9to4_data_start_recover_request ( ndmp9_data_start_recover_request *request9, ndmp4_data_start_recover_request *request4) { int n_error = 0; CNVT_STRDUP_FROM_9x (request4, request9, butype_name, bu_type); ndmp_9to4_pval_vec_dup (request9->env.env_val, &request4->env.env_val, request9->env.env_len); request4->env.env_len = request9->env.env_len; ndmp_9to4_name_vec_dup (request9->nlist.nlist_val, &request4->nlist.nlist_val, request9->nlist.nlist_len); request4->nlist.nlist_len = request9->nlist.nlist_len; return n_error; } /* * ndmp_data_abort * no args request, just error reply */ /* * ndmp_data_get_env * no args request */ int ndmp_4to9_data_get_env_reply ( ndmp4_data_get_env_reply *reply4, ndmp9_data_get_env_reply *reply9) { CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); ndmp_4to9_pval_vec_dup (reply4->env.env_val, &reply9->env.env_val, reply4->env.env_len); reply9->env.env_len = reply4->env.env_len; return 0; } int ndmp_4to9_data_get_env_free_reply ( ndmp9_data_get_env_reply *reply9) { ndmp_4to9_pval_vec_free(reply9->env.env_val, reply9->env.env_len); return 0; } int ndmp_9to4_data_get_env_reply ( ndmp9_data_get_env_reply *reply9, ndmp4_data_get_env_reply *reply4) { CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); ndmp_9to4_pval_vec_dup (reply9->env.env_val, &reply4->env.env_val, reply9->env.env_len); reply4->env.env_len = reply9->env.env_len; return 0; } /* * ndmp_data_stop * no args request, just error reply */ /* * ndmp_data_listen */ int ndmp_4to9_data_listen_request ( ndmp4_data_listen_request *request4, ndmp9_data_listen_request *request9) { int rc; rc = CNVT_E_TO_9 (request4, request9, addr_type, ndmp_49_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, addr_type); } return 0; } int ndmp_9to4_data_listen_request ( ndmp9_data_listen_request *request9, ndmp4_data_listen_request *request4) { int rc; rc = CNVT_E_FROM_9 (request4, request9, addr_type, ndmp_49_addr_type); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, addr_type); } return 0; } int ndmp_4to9_data_listen_reply ( ndmp4_data_listen_reply *reply4, ndmp9_data_listen_reply *reply9) { int n_error = 0; CNVT_E_TO_9 (reply4, reply9, error, ndmp_49_error); n_error += ndmp_4to9_addr (&reply4->connect_addr, &reply9->data_connection_addr); return n_error; } int ndmp_9to4_data_listen_reply ( ndmp9_data_listen_reply *reply9, ndmp4_data_listen_reply *reply4) { int n_error = 0; CNVT_E_FROM_9 (reply4, reply9, error, ndmp_49_error); n_error += ndmp_9to4_addr (&reply9->data_connection_addr, &reply4->connect_addr); return n_error; } /* * ndmp_data_connect * just error reply */ int ndmp_4to9_data_connect_request ( ndmp4_data_connect_request *request4, ndmp9_data_connect_request *request9) { return ndmp_4to9_addr (&request4->addr, &request9->addr); } int ndmp_9to4_data_connect_request ( ndmp9_data_connect_request *request9, ndmp4_data_connect_request *request4) { return ndmp_9to4_addr (&request9->addr, &request4->addr); } /* * NOTIFY INTERFACES **************************************************************** */ /* * ndmp_notify_data_halted * just error reply */ int ndmp_4to9_notify_data_halted_request ( ndmp4_notify_data_halted_post *request4, ndmp9_notify_data_halted_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request4, request9, reason, ndmp_49_data_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, reason); n_error++; } return n_error; } int ndmp_9to4_notify_data_halted_request ( ndmp9_notify_data_halted_request *request9, ndmp4_notify_data_halted_post *request4) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request4, request9, reason, ndmp_49_data_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, reason); n_error++; } return n_error; } /* * ndmp_notify_connected * just error reply */ /* NDMP4_NOTIFY_CONNECTED */ struct enum_conversion ndmp_49_connect_reason[] = { { NDMP_INVALID_GENERAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_CONNECTED, NDMP9_CONNECTED }, { NDMP4_SHUTDOWN, NDMP9_SHUTDOWN }, { NDMP4_REFUSED, NDMP9_REFUSED }, END_ENUM_CONVERSION_TABLE }; int ndmp_4to9_notify_connection_status_request ( ndmp4_notify_connection_status_post *request4, ndmp9_notify_connected_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request4, request9, reason, ndmp_49_connect_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, reason); n_error++; } CNVT_TO_9 (request4, request9, protocol_version); CNVT_STRDUP_TO_9 (request4, request9, text_reason); return n_error; } int ndmp_9to4_notify_connection_status_request ( ndmp9_notify_connected_request *request9, ndmp4_notify_connection_status_post *request4) { int n_error = 0; int rc; rc = CNVT_E_FROM_9(request4, request9, reason, ndmp_49_connect_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, reason); n_error++; } CNVT_FROM_9 (request4, request9, protocol_version); CNVT_STRDUP_FROM_9 (request4, request9, text_reason); return n_error; } /* * ndmp_notify_mover_halted * just error reply */ int ndmp_4to9_notify_mover_halted_request ( ndmp4_notify_mover_halted_post *request4, ndmp9_notify_mover_halted_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request4, request9, reason, ndmp_49_mover_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, reason); n_error++; } return n_error; } int ndmp_9to4_notify_mover_halted_request ( ndmp9_notify_mover_halted_request *request9, ndmp4_notify_mover_halted_post *request4) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request4, request9, reason, ndmp_49_mover_halt_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, reason); n_error++; } return n_error; } /* * ndmp_notify_mover_paused * just error reply */ int ndmp_4to9_notify_mover_paused_request ( ndmp4_notify_mover_paused_post *request4, ndmp9_notify_mover_paused_request *request9) { int n_error = 0; int rc; rc = CNVT_E_TO_9 (request4, request9, reason, ndmp_49_mover_pause_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_TO_9 (request4, request9, reason); n_error++; } CNVT_TO_9 (request4, request9, seek_position); return n_error; } int ndmp_9to4_notify_mover_paused_request ( ndmp9_notify_mover_paused_request *request9, ndmp4_notify_mover_paused_post *request4) { int n_error = 0; int rc; rc = CNVT_E_FROM_9 (request4, request9, reason, ndmp_49_mover_pause_reason); if (rc == NDMP_INVALID_GENERAL) { CNVT_FROM_9 (request4, request9, reason); n_error++; } CNVT_FROM_9 (request4, request9, seek_position); return n_error; } /* * ndmp_notify_data_read * just error reply */ int ndmp_4to9_notify_data_read_request ( ndmp4_notify_data_read_post *request4, ndmp9_notify_data_read_request *request9) { CNVT_TO_9 (request4, request9, offset); CNVT_TO_9 (request4, request9, length); return 0; } int ndmp_9to4_notify_data_read_request ( ndmp9_notify_data_read_request *request9, ndmp4_notify_data_read_post *request4) { CNVT_FROM_9 (request4, request9, offset); CNVT_FROM_9 (request4, request9, length); return 0; } /* * LOGGING INTERFACES **************************************************************** */ struct enum_conversion ndmp_49_recovery_status[] = { { NDMP4_RECOVERY_FAILED_UNDEFINED_ERROR, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR }, /* default */ { NDMP4_RECOVERY_SUCCESSFUL, NDMP9_RECOVERY_SUCCESSFUL }, { NDMP4_RECOVERY_FAILED_PERMISSION, NDMP9_RECOVERY_FAILED_PERMISSION }, { NDMP4_RECOVERY_FAILED_NOT_FOUND, NDMP9_RECOVERY_FAILED_NOT_FOUND }, { NDMP4_RECOVERY_FAILED_NO_DIRECTORY, NDMP9_RECOVERY_FAILED_NO_DIRECTORY }, { NDMP4_RECOVERY_FAILED_OUT_OF_MEMORY, NDMP9_RECOVERY_FAILED_OUT_OF_MEMORY }, { NDMP4_RECOVERY_FAILED_IO_ERROR, NDMP9_RECOVERY_FAILED_IO_ERROR }, { NDMP4_RECOVERY_FAILED_UNDEFINED_ERROR, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR }, END_ENUM_CONVERSION_TABLE }; int ndmp_4to9_log_file_request ( ndmp4_log_file_post *request4, ndmp9_log_file_request *request9) { CNVT_E_TO_9 (request4, request9, recovery_status, ndmp_49_recovery_status); CNVT_STRDUP_TO_9 (request4, request9, name); return 0; } int ndmp_9to4_log_file_request ( ndmp9_log_file_request *request9, ndmp4_log_file_post *request4) { CNVT_E_FROM_9 (request4, request9, recovery_status, ndmp_49_recovery_status); CNVT_STRDUP_FROM_9 (request4, request9, name); return 0; } /* * ndmp_log_type */ struct enum_conversion ndmp_49_log_type[] = { { NDMP4_LOG_NORMAL, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_LOG_NORMAL, NDMP9_LOG_NORMAL }, { NDMP4_LOG_DEBUG, NDMP9_LOG_DEBUG }, { NDMP4_LOG_ERROR, NDMP9_LOG_ERROR }, { NDMP4_LOG_WARNING, NDMP9_LOG_WARNING }, END_ENUM_CONVERSION_TABLE }; int ndmp_4to9_log_message_request ( ndmp4_log_message_post *request4, ndmp9_log_message_request *request9) { CNVT_E_TO_9 (request4, request9, log_type, ndmp_49_log_type); CNVT_TO_9 (request4, request9, message_id); CNVT_STRDUP_TO_9 (request4, request9, entry); switch (request4->associated_message_valid) { case NDMP4_HAS_ASSOCIATED_MESSAGE: request9->associated_message_sequence.valid = NDMP9_VALIDITY_VALID; break; default: case NDMP4_NO_ASSOCIATED_MESSAGE: request9->associated_message_sequence.valid = NDMP9_VALIDITY_INVALID; break; } request9->associated_message_sequence.value = request4->associated_message_sequence; return 0; } int ndmp_4to9_log_message_free_request ( ndmp9_log_message_request *request9) { CNVT_FREE(request9, entry); return 0; } int ndmp_9to4_log_message_request ( ndmp9_log_message_request *request9, ndmp4_log_message_post *request4) { CNVT_E_FROM_9 (request4, request9, log_type, ndmp_49_log_type); CNVT_FROM_9 (request4, request9, message_id); CNVT_STRDUP_TO_9 (request4, request9, entry); switch (request9->associated_message_sequence.valid) { case NDMP9_VALIDITY_VALID: request4->associated_message_valid = NDMP4_HAS_ASSOCIATED_MESSAGE; break; default: request4->associated_message_valid = NDMP4_NO_ASSOCIATED_MESSAGE; break; } request4->associated_message_sequence = request9->associated_message_sequence.value; return 0; } /* * FILE HISTORY INTERFACES **************************************************************** */ /* * ndmp[_unix]_file_stat */ struct enum_conversion ndmp_49_file_type[] = { { NDMP4_FILE_OTHER, NDMP_INVALID_GENERAL, }, /* default */ { NDMP4_FILE_DIR, NDMP9_FILE_DIR }, { NDMP4_FILE_FIFO, NDMP9_FILE_FIFO }, { NDMP4_FILE_CSPEC, NDMP9_FILE_CSPEC }, { NDMP4_FILE_BSPEC, NDMP9_FILE_BSPEC }, { NDMP4_FILE_REG, NDMP9_FILE_REG }, { NDMP4_FILE_SLINK, NDMP9_FILE_SLINK }, { NDMP4_FILE_SOCK, NDMP9_FILE_SOCK }, { NDMP4_FILE_REGISTRY, NDMP9_FILE_REGISTRY }, { NDMP4_FILE_OTHER, NDMP9_FILE_OTHER }, END_ENUM_CONVERSION_TABLE }; extern int ndmp_4to9_file_stat ( ndmp4_file_stat *fstat4, ndmp9_file_stat *fstat9, ndmp9_u_quad node, ndmp9_u_quad fh_info) { CNVT_E_TO_9 (fstat4, fstat9, ftype, ndmp_49_file_type); CNVT_VUL_TO_9 (fstat4, fstat9, mtime); CNVT_VUL_TO_9 (fstat4, fstat9, atime); CNVT_VUL_TO_9 (fstat4, fstat9, ctime); CNVT_VUL_TO_9x (fstat4, fstat9, owner, uid); CNVT_VUL_TO_9x (fstat4, fstat9, group, gid); CNVT_VUL_TO_9x (fstat4, fstat9, fattr, mode); CNVT_VUQ_TO_9 (fstat4, fstat9, size); CNVT_VUL_TO_9 (fstat4, fstat9, links); convert_valid_u_quad_to_9 (&node, &fstat9->node); convert_valid_u_quad_to_9 (&fh_info, &fstat9->fh_info); if (fstat4->unsupported & NDMP4_FILE_STAT_ATIME_UNS) CNVT_IUL_TO_9 (fstat9, atime); if (fstat4->unsupported & NDMP4_FILE_STAT_CTIME_UNS) CNVT_IUL_TO_9 (fstat9, ctime); if (fstat4->unsupported & NDMP4_FILE_STAT_GROUP_UNS) CNVT_IUL_TO_9 (fstat9, gid); return 0; } extern int ndmp_9to4_file_stat ( ndmp9_file_stat *fstat9, ndmp4_file_stat *fstat4) { CNVT_E_FROM_9 (fstat4, fstat9, ftype, ndmp_49_file_type); fstat4->fs_type = NDMP4_FS_UNIX; CNVT_VUL_FROM_9 (fstat4, fstat9, mtime); CNVT_VUL_FROM_9 (fstat4, fstat9, atime); CNVT_VUL_FROM_9 (fstat4, fstat9, ctime); CNVT_VUL_FROM_9x (fstat4, fstat9, owner, uid); CNVT_VUL_FROM_9x (fstat4, fstat9, group, gid); CNVT_VUL_FROM_9x (fstat4, fstat9, fattr, mode); CNVT_VUQ_FROM_9 (fstat4, fstat9, size); CNVT_VUL_FROM_9 (fstat4, fstat9, links); fstat4->unsupported = 0; if (!fstat9->atime.valid) fstat4->unsupported |= NDMP4_FILE_STAT_ATIME_UNS; if (!fstat9->ctime.valid) fstat4->unsupported |= NDMP4_FILE_STAT_CTIME_UNS; if (!fstat9->gid.valid) fstat4->unsupported |= NDMP4_FILE_STAT_GROUP_UNS; /* fh_info ignored */ /* node ignored */ return 0; } /* * ndmp_fh_add_file_request */ int ndmp_4to9_fh_add_file_request ( ndmp4_fh_add_file_post *request4, ndmp9_fh_add_file_request *request9) { int n_ent = request4->files.files_len; int i; unsigned int j; ndmp9_file * table; table = NDMOS_MACRO_NEWN(ndmp9_file, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp4_file * ent4 = &request4->files.files_val[i]; ndmp4_file_name * file_name; ndmp4_file_stat * file_stat = 0; ndmp4_file_stat _file_stat; char * filename; ndmp9_file * ent9 = &table[i]; filename = "no-unix-name"; for (j = 0; j < ent4->names.names_len; j++) { file_name = &ent4->names.names_val[j]; if (file_name->fs_type == NDMP4_FS_UNIX) { filename = file_name->ndmp4_file_name_u.unix_name; break; } } for (j = 0; j < ent4->stats.stats_len; j++) { file_stat = &ent4->stats.stats_val[j]; if (file_stat->fs_type == NDMP4_FS_UNIX) { break; } } if (j >= ent4->stats.stats_len) { file_stat = &_file_stat; NDMOS_MACRO_ZEROFILL (file_stat); } ent9->unix_path = NDMOS_API_STRDUP(filename); ndmp_4to9_file_stat (file_stat, &ent9->fstat, ent4->node, ent4->fh_info); } request9->files.files_len = n_ent; request9->files.files_val = table; return 0; } int ndmp_4to9_fh_add_file_free_request ( ndmp9_fh_add_file_request *request9) { int i; for (i = 0; i < request9->files.files_len; i++) { NDMOS_API_FREE(request9->files.files_val[i].unix_path); } NDMOS_MACRO_FREE(request9->files.files_val); return 0; } int ndmp_9to4_fh_add_file_request ( ndmp9_fh_add_file_request *request9, ndmp4_fh_add_file_post *request4) { int n_ent = request9->files.files_len; int i; ndmp4_file * table; table = NDMOS_MACRO_NEWN(ndmp4_file, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_file * ent9 = &request9->files.files_val[i]; ndmp4_file * ent4 = &table[i]; ent4->names.names_val = NDMOS_MACRO_NEW(ndmp4_file_name); ent4->names.names_len = 1; ent4->stats.stats_val = NDMOS_MACRO_NEW(ndmp4_file_stat); ent4->stats.stats_len = 1; ent4->names.names_val[0].fs_type = NDMP4_FS_UNIX; ent4->names.names_val[0].ndmp4_file_name_u.unix_name = NDMOS_API_STRDUP(ent9->unix_path); ndmp_9to4_file_stat (&ent9->fstat, &ent4->stats.stats_val[0]); ent4->node = ent9->fstat.node.value; ent4->fh_info = ent9->fstat.fh_info.value; } request4->files.files_len = n_ent; request4->files.files_val = table; return 0; } /* * ndmp_fh_add_unix_dir */ int ndmp_4to9_fh_add_dir_request ( ndmp4_fh_add_dir_post *request4, ndmp9_fh_add_dir_request *request9) { int n_ent = request4->dirs.dirs_len; int i; unsigned int j; ndmp9_dir * table; table = NDMOS_MACRO_NEWN(ndmp9_dir, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp4_dir * ent4 = &request4->dirs.dirs_val[i]; ndmp4_file_name * file_name; char * filename; ndmp9_dir * ent9 = &table[i]; filename = "no-unix-name"; for (j = 0; j < ent4->names.names_len; j++) { file_name = &ent4->names.names_val[j]; if (file_name->fs_type == NDMP4_FS_UNIX) { filename = file_name->ndmp4_file_name_u.unix_name; break; } } ent9->unix_name = NDMOS_API_STRDUP(filename); ent9->node = ent4->node; ent9->parent = ent4->parent; } request9->dirs.dirs_len = n_ent; request9->dirs.dirs_val = table; return 0; } int ndmp_4to9_fh_add_dir_free_request (ndmp9_fh_add_dir_request *request9) { int i; if (request9) { if(request9->dirs.dirs_val) { int n_ent = request9->dirs.dirs_len; for (i = 0; i < n_ent; i++) { ndmp9_dir *ent9 = &request9->dirs.dirs_val[i]; if (ent9->unix_name) NDMOS_API_FREE(ent9->unix_name); ent9->unix_name = 0; } NDMOS_API_FREE(request9->dirs.dirs_val); } request9->dirs.dirs_val = 0; } return 0; } int ndmp_9to4_fh_add_dir_request ( ndmp9_fh_add_dir_request *request9, ndmp4_fh_add_dir_post *request4) { int n_ent = request9->dirs.dirs_len; int i; ndmp4_dir * table; table = NDMOS_MACRO_NEWN(ndmp4_dir, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_dir * ent9 = &request9->dirs.dirs_val[i]; ndmp4_dir * ent4 = &table[i]; ent4->names.names_val = NDMOS_MACRO_NEW(ndmp4_file_name); ent4->names.names_len = 1; ent4->names.names_val[0].fs_type = NDMP4_FS_UNIX; ent4->names.names_val[0].ndmp4_file_name_u.unix_name = NDMOS_API_STRDUP(ent9->unix_name); ent4->node = ent9->node; ent4->parent = ent9->parent; } request4->dirs.dirs_len = n_ent; request4->dirs.dirs_val = table; return 0; } int ndmp_9to4_fh_add_dir_free_request (ndmp4_fh_add_dir_post *request4) { int i; if (request4) { if(request4->dirs.dirs_val) { int n_ent = request4->dirs.dirs_len; for (i = 0; i < n_ent; i++) { ndmp4_dir *ent4 = &request4->dirs.dirs_val[i]; if (ent4->names.names_val) { if (ent4->names.names_val[0].ndmp4_file_name_u.unix_name) NDMOS_API_FREE(ent4->names.names_val[0].ndmp4_file_name_u.unix_name); ent4->names.names_val[0].ndmp4_file_name_u.unix_name = 0; NDMOS_API_FREE(ent4->names.names_val); } ent4->names.names_val = 0; } NDMOS_API_FREE(request4->dirs.dirs_val); } request4->dirs.dirs_val = 0; } return 0; } /* * ndmp_fh_add_node_request */ int ndmp_4to9_fh_add_node_request ( ndmp4_fh_add_node_post *request4, ndmp9_fh_add_node_request *request9) { int n_ent = request4->nodes.nodes_len; int i; unsigned int j; ndmp9_node * table; table = NDMOS_MACRO_NEWN(ndmp9_node, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp4_node * ent4 = &request4->nodes.nodes_val[i]; ndmp4_file_stat * file_stat = 0; ndmp4_file_stat _file_stat; ndmp9_node * ent9 = &table[i]; for (j = 0; j < ent4->stats.stats_len; j++) { file_stat = &ent4->stats.stats_val[j]; if (file_stat->fs_type == NDMP4_FS_UNIX) { break; } } if (j >= ent4->stats.stats_len) { file_stat = &_file_stat; NDMOS_MACRO_ZEROFILL (file_stat); } ndmp_4to9_file_stat (file_stat, &ent9->fstat, ent4->node, ent4->fh_info); } request9->nodes.nodes_len = n_ent; request9->nodes.nodes_val = table; return 0; } int ndmp_4to9_fh_add_node_free_request (ndmp9_fh_add_node_request *request9) { if (request9) { if(request9->nodes.nodes_val) { NDMOS_API_FREE(request9->nodes.nodes_val); } request9->nodes.nodes_val = 0; } return 0; } int ndmp_9to4_fh_add_node_request ( ndmp9_fh_add_node_request *request9, ndmp4_fh_add_node_post *request4) { int n_ent = request9->nodes.nodes_len; int i; ndmp4_node * table; table = NDMOS_MACRO_NEWN(ndmp4_node, n_ent); if (!table) return -1; NDMOS_API_BZERO (table, sizeof *table * n_ent); for (i = 0; i < n_ent; i++) { ndmp9_node * ent9 = &request9->nodes.nodes_val[i]; ndmp4_node * ent4 = &table[i]; ent4->stats.stats_val = NDMOS_MACRO_NEW(ndmp4_file_stat); ent4->stats.stats_len = 1; ndmp_9to4_file_stat (&ent9->fstat, &ent4->stats.stats_val[0]); ent4->node = ent9->fstat.node.value; ent4->fh_info = ent9->fstat.fh_info.value; } request4->nodes.nodes_len = n_ent; request4->nodes.nodes_val = table; return 0; } int ndmp_9to4_fh_add_node_free_request (ndmp4_fh_add_node_post *request4) { if (request4) { if(request4->nodes.nodes_val) { NDMOS_API_FREE(request4->nodes.nodes_val); } request4->nodes.nodes_val = 0; } return 0; } /* * request/reply translation */ #define NO_ARG_REQUEST \ ndmp_xtox_no_arguments, ndmp_xtox_no_arguments #define JUST_ERROR_REPLY \ ndmp_4to9_error, ndmp_9to4_error #define NO_ARG_REQUEST_JUST_ERROR_REPLY \ NO_ARG_REQUEST, JUST_ERROR_REPLY #define NO_MEMUSED_REQUEST \ ndmp_xtox_no_memused, ndmp_xtox_no_memused #define NO_MEMUSED_REPLY \ ndmp_xtox_no_memused, ndmp_xtox_no_memused #define NO_MEMUSED \ ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused struct reqrep_xlate ndmp4_reqrep_xlate_table[] = { { NDMP4_CONNECT_OPEN, NDMP9_CONNECT_OPEN, ndmp_4to9_connect_open_request, ndmp_9to4_connect_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONNECT_CLIENT_AUTH, NDMP9_CONNECT_CLIENT_AUTH, ndmp_4to9_connect_client_auth_request, ndmp_9to4_connect_client_auth_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONNECT_CLOSE, NDMP9_CONNECT_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, /* actually no reply */ NO_MEMUSED /* no memory free routines written yet */ }, #ifdef notyet { NDMP4_CONNECT_SERVER_AUTH, NDMP9_CONNECT_SERVER_AUTH, ndmp_4to9_connect_server_auth_request, ndmp_9to4_connect_server_auth_request, ndmp_4to9_connect_server_auth_reply, ndmp_9to4_connect_server_auth_reply, NO_MEMUSED /* no memory free routines written yet */ }, #endif /* notyet */ { NDMP4_CONFIG_GET_HOST_INFO, NDMP9_CONFIG_GET_HOST_INFO, NO_ARG_REQUEST, ndmp_4to9_config_get_host_info_reply, ndmp_9to4_config_get_host_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_CONNECTION_TYPE, NDMP9_CONFIG_GET_CONNECTION_TYPE, NO_ARG_REQUEST, ndmp_4to9_config_get_connection_type_reply, ndmp_9to4_config_get_connection_type_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_AUTH_ATTR, NDMP9_CONFIG_GET_AUTH_ATTR, ndmp_4to9_config_get_auth_attr_request, ndmp_9to4_config_get_auth_attr_request, ndmp_4to9_config_get_auth_attr_reply, ndmp_9to4_config_get_auth_attr_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_SERVER_INFO, NDMP9_CONFIG_GET_SERVER_INFO, NO_ARG_REQUEST, ndmp_4to9_config_get_server_info_reply, ndmp_9to4_config_get_server_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_BUTYPE_INFO, NDMP9_CONFIG_GET_BUTYPE_INFO, NO_ARG_REQUEST, ndmp_4to9_config_get_butype_info_reply, ndmp_9to4_config_get_butype_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_FS_INFO, NDMP9_CONFIG_GET_FS_INFO, NO_ARG_REQUEST, ndmp_4to9_config_get_fs_info_reply, ndmp_9to4_config_get_fs_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_TAPE_INFO, NDMP9_CONFIG_GET_TAPE_INFO, NO_ARG_REQUEST, ndmp_4to9_config_get_tape_info_reply, ndmp_9to4_config_get_tape_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_CONFIG_GET_SCSI_INFO, NDMP9_CONFIG_GET_SCSI_INFO, NO_ARG_REQUEST, ndmp_4to9_config_get_scsi_info_reply, ndmp_9to4_config_get_scsi_info_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_SCSI_OPEN, NDMP9_SCSI_OPEN, ndmp_4to9_scsi_open_request, ndmp_9to4_scsi_open_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_SCSI_CLOSE, NDMP9_SCSI_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_SCSI_GET_STATE, NDMP9_SCSI_GET_STATE, NO_ARG_REQUEST, ndmp_4to9_scsi_get_state_reply, ndmp_9to4_scsi_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_SCSI_RESET_DEVICE, NDMP9_SCSI_RESET_DEVICE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_SCSI_EXECUTE_CDB, NDMP9_SCSI_EXECUTE_CDB, ndmp_4to9_execute_cdb_request, ndmp_9to4_execute_cdb_request, ndmp_4to9_execute_cdb_reply, ndmp_9to4_execute_cdb_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_TAPE_OPEN, NDMP9_TAPE_OPEN, ndmp_4to9_tape_open_request, ndmp_9to4_tape_open_request, JUST_ERROR_REPLY, ndmp_4to9_tape_open_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused }, { NDMP4_TAPE_CLOSE, NDMP9_TAPE_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_TAPE_GET_STATE, NDMP9_TAPE_GET_STATE, NO_ARG_REQUEST, ndmp_4to9_tape_get_state_reply, ndmp_9to4_tape_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_TAPE_MTIO, NDMP9_TAPE_MTIO, ndmp_4to9_tape_mtio_request, ndmp_9to4_tape_mtio_request, ndmp_4to9_tape_mtio_reply, ndmp_9to4_tape_mtio_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_TAPE_WRITE, NDMP9_TAPE_WRITE, ndmp_4to9_tape_write_request, ndmp_9to4_tape_write_request, ndmp_4to9_tape_write_reply, ndmp_9to4_tape_write_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_TAPE_READ, NDMP9_TAPE_READ, ndmp_4to9_tape_read_request, ndmp_9to4_tape_read_request, ndmp_4to9_tape_read_reply, ndmp_9to4_tape_read_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_TAPE_EXECUTE_CDB, NDMP9_TAPE_EXECUTE_CDB, ndmp_4to9_execute_cdb_request, ndmp_9to4_execute_cdb_request, ndmp_4to9_execute_cdb_reply, ndmp_9to4_execute_cdb_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_GET_STATE, NDMP9_DATA_GET_STATE, NO_ARG_REQUEST, ndmp_4to9_data_get_state_reply, ndmp_9to4_data_get_state_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_START_BACKUP, NDMP9_DATA_START_BACKUP, ndmp_4to9_data_start_backup_request, ndmp_9to4_data_start_backup_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_START_RECOVER, NDMP9_DATA_START_RECOVER, ndmp_4to9_data_start_recover_request, ndmp_9to4_data_start_recover_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_ABORT, NDMP9_DATA_ABORT, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_GET_ENV, NDMP9_DATA_GET_ENV, NO_ARG_REQUEST, ndmp_4to9_data_get_env_reply, ndmp_9to4_data_get_env_reply, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_4to9_data_get_env_free_reply, ndmp_xtox_no_memused }, { NDMP4_DATA_STOP, NDMP9_DATA_STOP, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_LISTEN, NDMP9_DATA_LISTEN, ndmp_4to9_data_listen_request, ndmp_9to4_data_listen_request, ndmp_4to9_data_listen_reply, ndmp_9to4_data_listen_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_CONNECT, NDMP9_DATA_CONNECT, ndmp_4to9_data_connect_request, ndmp_9to4_data_connect_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_DATA_START_RECOVER_FILEHIST, NDMP9_DATA_START_RECOVER_FILEHIST, ndmp_4to9_data_start_recover_request, ndmp_9to4_data_start_recover_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_NOTIFY_DATA_HALTED, NDMP9_NOTIFY_DATA_HALTED, ndmp_4to9_notify_data_halted_request, ndmp_9to4_notify_data_halted_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_NOTIFY_CONNECTION_STATUS, NDMP9_NOTIFY_CONNECTED, ndmp_4to9_notify_connection_status_request, ndmp_9to4_notify_connection_status_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_NOTIFY_MOVER_HALTED, NDMP9_NOTIFY_MOVER_HALTED, ndmp_4to9_notify_mover_halted_request, ndmp_9to4_notify_mover_halted_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_NOTIFY_MOVER_PAUSED, NDMP9_NOTIFY_MOVER_PAUSED, ndmp_4to9_notify_mover_paused_request, ndmp_9to4_notify_mover_paused_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_NOTIFY_DATA_READ, NDMP9_NOTIFY_DATA_READ, ndmp_4to9_notify_data_read_request, ndmp_9to4_notify_data_read_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_LOG_FILE, NDMP9_LOG_FILE, ndmp_4to9_log_file_request, ndmp_9to4_log_file_request, JUST_ERROR_REPLY, /* no reply actually */ NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_LOG_MESSAGE, NDMP9_LOG_MESSAGE, ndmp_4to9_log_message_request, ndmp_9to4_log_message_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_4to9_log_message_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused }, { NDMP4_FH_ADD_FILE, NDMP9_FH_ADD_FILE, ndmp_4to9_fh_add_file_request, ndmp_9to4_fh_add_file_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_4to9_fh_add_file_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused }, { NDMP4_FH_ADD_DIR, NDMP9_FH_ADD_DIR, ndmp_4to9_fh_add_dir_request, ndmp_9to4_fh_add_dir_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_4to9_fh_add_dir_free_request, ndmp_9to4_fh_add_dir_free_request, NO_MEMUSED_REPLY }, { NDMP4_FH_ADD_NODE, NDMP9_FH_ADD_NODE, ndmp_4to9_fh_add_node_request, ndmp_9to4_fh_add_node_request, JUST_ERROR_REPLY, /* no reply actually */ ndmp_4to9_fh_add_node_free_request, ndmp_9to4_fh_add_node_free_request, NO_MEMUSED_REPLY }, { NDMP4_MOVER_GET_STATE, NDMP9_MOVER_GET_STATE, NO_ARG_REQUEST, ndmp_4to9_mover_get_state_reply, ndmp_9to4_mover_get_state_reply, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_9to4_mover_get_state_free_reply }, { NDMP4_MOVER_LISTEN, NDMP9_MOVER_LISTEN, ndmp_4to9_mover_listen_request, ndmp_9to4_mover_listen_request, ndmp_4to9_mover_listen_reply, ndmp_9to4_mover_listen_reply, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_CONNECT, NDMP9_MOVER_CONNECT, ndmp_4to9_mover_connect_request, ndmp_9to4_mover_connect_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_SET_RECORD_SIZE, NDMP9_MOVER_SET_RECORD_SIZE, ndmp_4to9_mover_set_record_size_request, ndmp_9to4_mover_set_record_size_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_SET_WINDOW, NDMP9_MOVER_SET_WINDOW, ndmp_4to9_mover_set_window_request, ndmp_9to4_mover_set_window_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_CONTINUE, NDMP9_MOVER_CONTINUE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_ABORT, NDMP9_MOVER_ABORT, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_STOP, NDMP9_MOVER_STOP, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_READ, NDMP9_MOVER_READ, ndmp_4to9_mover_read_request, ndmp_9to4_mover_read_request, JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { NDMP4_MOVER_CLOSE, NDMP9_MOVER_CLOSE, NO_ARG_REQUEST_JUST_ERROR_REPLY, NO_MEMUSED /* no memory free routines written yet */ }, { 0 }, }; #endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp4_translate.h000066400000000000000000000070451263011562700214430ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifndef NDMOS_OPTION_NO_NDMP4 #ifdef __cplusplus extern "C" { #endif extern int ndmp_4to9_error ( ndmp4_error *error4, ndmp9_error *error9); extern int ndmp_9to4_error ( ndmp9_error *error9, ndmp4_error *error4); extern int ndmp_4to9_data_get_state_reply ( ndmp4_data_get_state_reply *reply4, ndmp9_data_get_state_reply *reply9); extern int ndmp_9to4_data_get_state_reply ( ndmp9_data_get_state_reply *reply9, ndmp4_data_get_state_reply *reply4); extern int ndmp_4to9_tape_get_state_reply ( ndmp4_tape_get_state_reply *reply4, ndmp9_tape_get_state_reply *reply9); extern int ndmp_9to4_tape_get_state_reply ( ndmp9_tape_get_state_reply *reply9, ndmp4_tape_get_state_reply *reply4); extern int ndmp_4to9_mover_get_state_reply ( ndmp4_mover_get_state_reply *reply4, ndmp9_mover_get_state_reply *reply9); extern int ndmp_9to4_mover_get_state_reply ( ndmp9_mover_get_state_reply *reply9, ndmp4_mover_get_state_reply *reply4); extern int ndmp_4to9_addr ( ndmp4_addr *addr4, ndmp9_addr *addr9); extern int ndmp_9to4_addr ( ndmp9_addr *addr9, ndmp4_addr *addr4); extern int ndmp_4to9_file_stat ( ndmp4_file_stat *fstat4, ndmp9_file_stat *fstat9, ndmp9_u_quad node, ndmp9_u_quad fh_info); extern int ndmp_9to4_file_stat ( ndmp9_file_stat *fstat9, ndmp4_file_stat *fstat4); extern int ndmp_4to9_pval ( ndmp4_pval *pval4, ndmp9_pval *pval9); extern int ndmp_9to4_pval ( ndmp9_pval *pval9, ndmp4_pval *pval4); extern int ndmp_4to9_pval_vec ( ndmp4_pval *pval4, ndmp9_pval *pval9, unsigned n_pval); extern int ndmp_9to4_pval_vec ( ndmp9_pval *pval9, ndmp4_pval *pval4, unsigned n_pval); extern int ndmp_4to9_name ( ndmp4_name *name4, ndmp9_name *name9); extern int ndmp_9to4_name ( ndmp9_name *name9, ndmp4_name *name4); extern int ndmp_4to9_name_vec ( ndmp4_name *name4, ndmp9_name *name9, unsigned n_name); extern int ndmp_9to4_name_vec ( ndmp9_name *name9, ndmp4_name *name4, unsigned n_name); extern struct reqrep_xlate ndmp4_reqrep_xlate_table[]; #ifdef __cplusplus } #endif #endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp4_xmt.c000066400000000000000000000221171263011562700202460ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" #include "ndmprotocol.h" #ifndef NDMOS_OPTION_NO_NDMP4 #define xdr_ndmp4_connect_close_request xdr_void #define xdr_ndmp4_connect_close_reply xdr_void #define xdr_ndmp4_config_get_host_info_request xdr_void #define xdr_ndmp4_config_get_connection_type_request xdr_void #define xdr_ndmp4_config_get_butype_info_request xdr_void #define xdr_ndmp4_config_get_fs_info_request xdr_void #define xdr_ndmp4_config_get_tape_info_request xdr_void #define xdr_ndmp4_config_get_scsi_info_request xdr_void #define xdr_ndmp4_config_get_server_info_request xdr_void #define xdr_ndmp4_scsi_close_request xdr_void #define xdr_ndmp4_scsi_get_state_request xdr_void #define xdr_ndmp4_scsi_reset_device_request xdr_void #define xdr_ndmp4_scsi_reset_bus_request xdr_void #define xdr_ndmp4_tape_close_request xdr_void #define xdr_ndmp4_tape_get_state_request xdr_void #define xdr_ndmp4_data_get_state_request xdr_void #define xdr_ndmp4_data_abort_request xdr_void #define xdr_ndmp4_data_get_env_request xdr_void #define xdr_ndmp4_data_stop_request xdr_void #define xdr_ndmp4_mover_get_state_request xdr_void #define xdr_ndmp4_mover_continue_request xdr_void #define xdr_ndmp4_mover_abort_request xdr_void #define xdr_ndmp4_mover_stop_request xdr_void #define xdr_ndmp4_mover_close_request xdr_void struct ndmp_xdr_message_table ndmp4_xdr_message_table[] = { { NDMP4_CONNECT_OPEN, xdr_ndmp4_connect_open_request, xdr_ndmp4_connect_open_reply, }, { NDMP4_CONNECT_CLIENT_AUTH, xdr_ndmp4_connect_client_auth_request, xdr_ndmp4_connect_client_auth_reply, }, { NDMP4_CONNECT_CLOSE, xdr_ndmp4_connect_close_request, xdr_ndmp4_connect_close_reply, }, { NDMP4_CONNECT_SERVER_AUTH, xdr_ndmp4_connect_server_auth_request, xdr_ndmp4_connect_server_auth_reply, }, { NDMP4_CONFIG_GET_HOST_INFO, xdr_ndmp4_config_get_host_info_request, xdr_ndmp4_config_get_host_info_reply, }, { NDMP4_CONFIG_GET_CONNECTION_TYPE, xdr_ndmp4_config_get_connection_type_request, xdr_ndmp4_config_get_connection_type_reply, }, { NDMP4_CONFIG_GET_AUTH_ATTR, xdr_ndmp4_config_get_auth_attr_request, xdr_ndmp4_config_get_auth_attr_reply, }, { NDMP4_CONFIG_GET_BUTYPE_INFO, xdr_ndmp4_config_get_butype_info_request, xdr_ndmp4_config_get_butype_info_reply, }, { NDMP4_CONFIG_GET_FS_INFO, xdr_ndmp4_config_get_fs_info_request, xdr_ndmp4_config_get_fs_info_reply, }, { NDMP4_CONFIG_GET_TAPE_INFO, xdr_ndmp4_config_get_tape_info_request, xdr_ndmp4_config_get_tape_info_reply, }, { NDMP4_CONFIG_GET_SCSI_INFO, xdr_ndmp4_config_get_scsi_info_request, xdr_ndmp4_config_get_scsi_info_reply, }, { NDMP4_CONFIG_GET_SERVER_INFO, xdr_ndmp4_config_get_server_info_request, xdr_ndmp4_config_get_server_info_reply, }, { NDMP4_SCSI_OPEN, xdr_ndmp4_scsi_open_request, xdr_ndmp4_scsi_open_reply, }, { NDMP4_SCSI_CLOSE, xdr_ndmp4_scsi_close_request, xdr_ndmp4_scsi_close_reply, }, { NDMP4_SCSI_GET_STATE, xdr_ndmp4_scsi_get_state_request, xdr_ndmp4_scsi_get_state_reply, }, { NDMP4_SCSI_RESET_DEVICE, xdr_ndmp4_scsi_reset_device_request, xdr_ndmp4_scsi_reset_device_reply, }, { NDMP4_SCSI_EXECUTE_CDB, xdr_ndmp4_scsi_execute_cdb_request, xdr_ndmp4_scsi_execute_cdb_reply, }, { NDMP4_TAPE_OPEN, xdr_ndmp4_tape_open_request, xdr_ndmp4_tape_open_reply, }, { NDMP4_TAPE_CLOSE, xdr_ndmp4_tape_close_request, xdr_ndmp4_tape_close_reply, }, { NDMP4_TAPE_GET_STATE, xdr_ndmp4_tape_get_state_request, xdr_ndmp4_tape_get_state_reply, }, { NDMP4_TAPE_MTIO, xdr_ndmp4_tape_mtio_request, xdr_ndmp4_tape_mtio_reply, }, { NDMP4_TAPE_WRITE, xdr_ndmp4_tape_write_request, xdr_ndmp4_tape_write_reply, }, { NDMP4_TAPE_READ, xdr_ndmp4_tape_read_request, xdr_ndmp4_tape_read_reply, }, { NDMP4_TAPE_EXECUTE_CDB, xdr_ndmp4_tape_execute_cdb_request, xdr_ndmp4_tape_execute_cdb_reply, }, { NDMP4_DATA_GET_STATE, xdr_ndmp4_data_get_state_request, xdr_ndmp4_data_get_state_reply, }, { NDMP4_DATA_START_BACKUP, xdr_ndmp4_data_start_backup_request, xdr_ndmp4_data_start_backup_reply, }, { NDMP4_DATA_START_RECOVER, xdr_ndmp4_data_start_recover_request, xdr_ndmp4_data_start_recover_reply, }, { NDMP4_DATA_START_RECOVER_FILEHIST, xdr_ndmp4_data_start_recover_filehist_request, xdr_ndmp4_data_start_recover_filehist_reply, }, { NDMP4_DATA_ABORT, xdr_ndmp4_data_abort_request, xdr_ndmp4_data_abort_reply, }, { NDMP4_DATA_GET_ENV, xdr_ndmp4_data_get_env_request, xdr_ndmp4_data_get_env_reply, }, { NDMP4_DATA_STOP, xdr_ndmp4_data_stop_request, xdr_ndmp4_data_stop_reply, }, { NDMP4_DATA_LISTEN, xdr_ndmp4_data_listen_request, xdr_ndmp4_data_listen_reply, }, { NDMP4_DATA_CONNECT, xdr_ndmp4_data_connect_request, xdr_ndmp4_data_connect_reply, }, { NDMP4_NOTIFY_DATA_HALTED, xdr_ndmp4_notify_data_halted_post, 0 }, { NDMP4_NOTIFY_CONNECTION_STATUS, xdr_ndmp4_notify_connection_status_post, 0 }, { NDMP4_NOTIFY_MOVER_HALTED, xdr_ndmp4_notify_mover_halted_post, 0 }, { NDMP4_NOTIFY_MOVER_PAUSED, xdr_ndmp4_notify_mover_paused_post, 0 }, { NDMP4_NOTIFY_DATA_READ, xdr_ndmp4_notify_data_read_post, 0 }, { NDMP4_LOG_FILE, xdr_ndmp4_log_file_post, 0 }, { NDMP4_LOG_MESSAGE, xdr_ndmp4_log_message_post, 0 }, { NDMP4_FH_ADD_FILE, xdr_ndmp4_fh_add_file_post, 0 }, { NDMP4_FH_ADD_DIR, xdr_ndmp4_fh_add_dir_post, 0 }, { NDMP4_FH_ADD_NODE, xdr_ndmp4_fh_add_node_post, 0 }, { NDMP4_MOVER_GET_STATE, xdr_ndmp4_mover_get_state_request, xdr_ndmp4_mover_get_state_reply, }, { NDMP4_MOVER_LISTEN, xdr_ndmp4_mover_listen_request, xdr_ndmp4_mover_listen_reply, }, { NDMP4_MOVER_CONTINUE, xdr_ndmp4_mover_continue_request, xdr_ndmp4_mover_continue_reply, }, { NDMP4_MOVER_ABORT, xdr_ndmp4_mover_abort_request, xdr_ndmp4_mover_abort_reply, }, { NDMP4_MOVER_STOP, xdr_ndmp4_mover_stop_request, xdr_ndmp4_mover_stop_reply, }, { NDMP4_MOVER_SET_WINDOW, xdr_ndmp4_mover_set_window_request, xdr_ndmp4_mover_set_window_reply, }, { NDMP4_MOVER_READ, xdr_ndmp4_mover_read_request, xdr_ndmp4_mover_read_reply, }, { NDMP4_MOVER_CLOSE, xdr_ndmp4_mover_close_request, xdr_ndmp4_mover_close_reply, }, { NDMP4_MOVER_SET_RECORD_SIZE, xdr_ndmp4_mover_set_record_size_request, xdr_ndmp4_mover_set_record_size_reply, }, { NDMP4_MOVER_CONNECT, xdr_ndmp4_mover_connect_request, xdr_ndmp4_mover_connect_reply, }, {0} }; /* * XDR unsigned long integers * same as xdr_long - open coded to save a proc call! */ bool_t xdr_ndmp4_u_quad(xdrs, objp) register XDR *xdrs; ndmp4_u_quad *objp; { uint32_t hi, lo; switch (xdrs->x_op) { case XDR_DECODE: #if defined(_LP64) if (XDR_GETINT32(xdrs, (int32_t *)&hi) && XDR_GETINT32(xdrs, (int32_t *)&lo)) { #else if (XDR_GETLONG(xdrs, (long *)&hi) && XDR_GETLONG(xdrs, (long *)&lo)) { #endif *objp = ((uint64_t)hi << 32) | (lo & 0xffffffff); return TRUE; } break; case XDR_ENCODE: hi = *objp >> 32; lo = *objp & 0xffffffff; #if defined(_LP64) return XDR_PUTINT32(xdrs, (int32_t *)&hi) && XDR_PUTINT32(xdrs, (int32_t *)&lo); #else return XDR_PUTLONG(xdrs, (long *)&hi) && XDR_PUTLONG(xdrs, (long *)&lo); #endif case XDR_FREE: return (TRUE); } return (FALSE); } #endif /* !NDMOS_OPTION_NO_NDMP4 */ bareos-Release-14.2.6/src/ndmp/ndmp9.x000066400000000000000000000677601263011562700174250ustar00rootroot00000000000000/* * Copyright (c) 2000,2001 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * NDMPv9, represented here, is a ficticious version * used internally and never over-the-wire. This * isolates higher-level routines from variations * between NDMP protocol version. At this time, * NDMPv2, NDMPv3 and NDMPv4 are deployed. NDMPv9 tends * to be bits and pieces of all supported protocol versions * mashed together. * * While we want the higher-level routines isolated, * for clarity we still want them to use data structures * and construct that resemble NDMP. Higher-level routines * manipulate NDMPv9 data structures. Mid-level routines * translate between NDMPv9 and the over-the-wire version * in use. Low-level routines do the over-the-wire functions. * * The approach of using the latest version internally * and retrofiting earlier versions was rejected for * two reasons. First, it means a tear-up of higher-level * functions as new versions are deployed. Second, * it makes building with selected version impossible. * No matter what approach is taken, there will be * some sort of retrofit between versions. NDMPv9 * is simply the internal version, and all bona-fide * versions are retrofitted. v9 was chosen because * it is unlikely the NDMP version will reach 9 * within the useful life of the NDMP architecture. * * NDMPv9 could be implemented in a hand-crafted header (.h) * file, yet we continue to use the ONC RPC (.x) description * for convenvience. It's easy to cut-n-paste from the other * NDMP.x files. It's important that ndmp9_xdr.c never be * generated nor compiled. */ /* * (from ndmp3.x) * ndmp.x * * Description : NDMP protocol rpcgen file. * * Copyright (c) 1999 Intelliguard Software, Network Appliance. * All Rights Reserved. */ /* * (from ndmp2.x) * Copyright (c) 1997 Network Appliance. All Rights Reserved. * * Network Appliance makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 %#pragma GCC diagnostic ignored "-Wunused-variable" %#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 470 %#pragma GCC diagnostic ignored "-Wunprototyped-calls" %#endif %#endif const NDMP9VER = 9; /* * General types **************************************************************** */ /* * Error codes */ enum ndmp9_error { NDMP9_NO_ERR, /* No error */ NDMP9_NOT_SUPPORTED_ERR, /* Call is not supported */ NDMP9_DEVICE_BUSY_ERR, /* The device is in use */ NDMP9_DEVICE_OPENED_ERR, /* Another tape or scsi device * is already open */ NDMP9_NOT_AUTHORIZED_ERR, /* connection has not been authorized*/ NDMP9_PERMISSION_ERR, /* some sort of permission problem */ NDMP9_DEV_NOT_OPEN_ERR, /* SCSI device is not open */ NDMP9_IO_ERR, /* I/O error */ NDMP9_TIMEOUT_ERR, /* command timed out */ NDMP9_ILLEGAL_ARGS_ERR, /* illegal arguments in request */ NDMP9_NO_TAPE_LOADED_ERR, /* Cannot open because there is no tape loaded */ NDMP9_WRITE_PROTECT_ERR, /* tape cannot be open for write */ NDMP9_EOF_ERR, /* Command encountered EOF */ NDMP9_EOM_ERR, /* Command encountered EOM */ NDMP9_FILE_NOT_FOUND_ERR, /* File not found during recover */ NDMP9_BAD_FILE_ERR, /* The file descriptor is invalid */ NDMP9_NO_DEVICE_ERR, /* The device is not at that target */ NDMP9_NO_BUS_ERR, /* Invalid controller */ NDMP9_XDR_DECODE_ERR, /* Can't decode the request argument */ NDMP9_ILLEGAL_STATE_ERR, /* Call can't be done at this state */ NDMP9_UNDEFINED_ERR, /* Undefined Error */ NDMP9_XDR_ENCODE_ERR, /* Can't encode the reply argument */ NDMP9_NO_MEM_ERR, /* no memory */ NDMP9_CONNECT_ERR, /* Error connecting to another * NDMP server */ NDMP9_SEQUENCE_NUM_ERR, NDMP9_READ_IN_PROGRESS_ERR = 25, NDMP9_PRECONDITION_ERR = 26, NDMP9_CLASS_NOT_SUPPORTED = 27, NDMP9_VERSION_NOT_SUPPORTED = 28, NDMP9_EXT_DUPL_CLASSES = 29, NDMP9_EXT_DN_ILLEGAL = 30 }; /* * Message codes */ enum ndmp9_message { NDMP9_CONNECT_OPEN = 0x900, /* CONNECT INTERFACE */ NDMP9_CONNECT_CLIENT_AUTH = 0x901, NDMP9_CONNECT_CLOSE = 0x902, NDMP9_CONNECT_SERVER_AUTH = 0x903, NDMP9_CONFIG_GET_HOST_INFO = 0x100, /* CONFIG INTERFACE */ NDMP9_CONFIG_GET_CONNECTION_TYPE = 0x102, /* NDMP2_CONFIG_GET_MOVER_TYPE on v2*/ NDMP9_CONFIG_GET_AUTH_ATTR = 0x103, NDMP9_CONFIG_GET_BUTYPE_INFO = 0x104, /* NDMPv3 and forward */ NDMP9_CONFIG_GET_FS_INFO = 0x105, /* NDMPv3 and forward */ NDMP9_CONFIG_GET_TAPE_INFO = 0x106, /* NDMPv3 and forward */ NDMP9_CONFIG_GET_SCSI_INFO = 0x107, /* NDMPv3 and forward */ NDMP9_CONFIG_GET_SERVER_INFO =0x108, /* NDMPv3 and forward */ NDMP9_SCSI_OPEN = 0x200, /* SCSI INTERFACE */ NDMP9_SCSI_CLOSE = 0x201, NDMP9_SCSI_GET_STATE = 0x202, NDMP9_SCSI_SET_TARGET = 0x203, NDMP9_SCSI_RESET_DEVICE = 0x204, NDMP9_SCSI_RESET_BUS = 0x205, NDMP9_SCSI_EXECUTE_CDB = 0x206, NDMP9_TAPE_OPEN = 0x300, /* TAPE INTERFACE */ NDMP9_TAPE_CLOSE = 0x301, NDMP9_TAPE_GET_STATE = 0x302, NDMP9_TAPE_MTIO = 0x303, NDMP9_TAPE_WRITE = 0x304, NDMP9_TAPE_READ = 0x305, NDMP9_TAPE_EXECUTE_CDB = 0x307, NDMP9_DATA_GET_STATE = 0x400, /* DATA INTERFACE */ NDMP9_DATA_START_BACKUP = 0x401, NDMP9_DATA_START_RECOVER = 0x402, NDMP9_DATA_ABORT = 0x403, NDMP9_DATA_GET_ENV = 0x404, NDMP9_DATA_STOP = 0x407, NDMP9_DATA_LISTEN = 0x409, NDMP9_DATA_CONNECT = 0x40a, NDMP9_DATA_START_RECOVER_FILEHIST = 0x40b, NDMP9_NOTIFY_DATA_HALTED =0x501,/* NOTIFY INTERFACE */ NDMP9_NOTIFY_CONNECTED = 0x502, NDMP9_NOTIFY_MOVER_HALTED = 0x503, NDMP9_NOTIFY_MOVER_PAUSED = 0x504, NDMP9_NOTIFY_DATA_READ =0x505, NDMP9_LOG_FILE = 0x602, /* LOGGING INTERFACE */ NDMP9_LOG_MESSAGE = 0x603, NDMP9_FH_ADD_FILE = 0x703, /* FILE HISTORY INTERFACE */ NDMP9_FH_ADD_DIR = 0x704, NDMP9_FH_ADD_NODE = 0x705, NDMP9_MOVER_GET_STATE = 0xa00, /* MOVER INTERFACE */ NDMP9_MOVER_LISTEN = 0xa01, NDMP9_MOVER_CONTINUE = 0xa02, NDMP9_MOVER_ABORT = 0xa03, NDMP9_MOVER_STOP = 0xa04, NDMP9_MOVER_SET_WINDOW = 0xa05, NDMP9_MOVER_READ = 0xa06, NDMP9_MOVER_CLOSE =0xa07, NDMP9_MOVER_SET_RECORD_SIZE =0xa08, NDMP9_MOVER_CONNECT =0xa09 }; /* * Common message bodies */ %extern bool_t xdr_ndmp9_no_arguments(); %#define ndmp9_no_arguments int struct ndmp9_just_error_reply { ndmp9_error error; }; /* * 64-bit integers */ %extern bool_t xdr_ndmp9_u_quad(); %#define ndmp9_u_quad uint64_t /* * Valid values. Sometimes we have values, and sometimes we don't. */ enum ndmp9_validity { NDMP9_VALIDITY_INVALID = 0, NDMP9_VALIDITY_VALID, NDMP9_VALIDITY_MAYBE_INVALID, NDMP9_VALIDITY_MAYBE_VALID }; %#define NDMP9_INVALID_U_LONG 0xFFFFFFFFul struct ndmp9_valid_u_long { ndmp9_validity valid; uint32_t value; }; %#define NDMP9_INVALID_U_QUAD 0xFFFFFFFFFFFFFFFFull struct ndmp9_valid_u_quad { ndmp9_validity valid; ndmp9_u_quad value; }; /* * Property values. A simple name/value pair. Used in lots of places. */ struct ndmp9_pval { string name<>; string value<>; }; /* * Authorization data. Three authorization types each * with their particular values. Authorization is done * in three steps: * 1) Client determines which types of authorization are available * on the server. * 2) Client may get parameters (challenge) from server. * 3) Client requests authorization based on a shared * secret (password) with parameters (challenge) applied. */ enum ndmp9_auth_type { NDMP9_AUTH_NONE, /* no password is required */ NDMP9_AUTH_TEXT, /* the clear text password */ NDMP9_AUTH_MD5 /* md5 */ }; union ndmp9_auth_attr switch (enum ndmp9_auth_type auth_type) { case NDMP9_AUTH_NONE: void; case NDMP9_AUTH_TEXT: void; case NDMP9_AUTH_MD5: opaque challenge[64]; }; struct ndmp9_auth_text { string auth_id<>; /* account/user name */ string auth_password<>; /* clear-text password */ }; struct ndmp9_auth_md5 { string auth_id<>; /* account/user name */ opaque auth_digest[16]; /* MD5 "hashed" password */ }; union ndmp9_auth_data switch (enum ndmp9_auth_type auth_type) { case NDMP9_AUTH_NONE: void; case NDMP9_AUTH_TEXT: struct ndmp9_auth_text auth_text; case NDMP9_AUTH_MD5: struct ndmp9_auth_md5 auth_md5; }; /* * The data connection (data stream, image stream, big ol' pipe) * has two endpoints, Once side instigates the connection (connects), * the other side receives the connection (listen/accept). * Appears in DATA and MOVER interfaces. */ enum ndmp9_addr_type { NDMP9_ADDR_LOCAL, NDMP9_ADDR_TCP, /* IPC and FC addr types contemplated but never deployed */ NDMP9_ADDR_AS_CONNECTED = 0x1000 }; struct ndmp9_tcp_addr { uint32_t ip_addr; uint16_t port; }; union ndmp9_addr switch (ndmp9_addr_type addr_type) { case NDMP9_ADDR_LOCAL: case NDMP9_ADDR_AS_CONNECTED: void; case NDMP9_ADDR_TCP: ndmp9_tcp_addr tcp_addr; }; /* * CONNECT INTERFACE **************************************************************** * * The CONNECT INTERFACE is used to condition and authorize * the control connection from the CONTROL Agent (DMA, Client) * to the DATA, TAPE, or SCSI Agent (DSP, Servers). * * Most of this is addressed by NDMP0 (zero), which is a companion * ficticious version. The NDMP0 features must never change to * support protocol version negotiation. Once the version is * negotiated, subsequent negotiations and authorization can * take place. */ /* NDMP9_CONNECT_OPEN -- must never change, negotiate protocol version */ struct ndmp9_connect_open_request { uint16_t protocol_version; /* the version of protocol supported */ }; typedef ndmp9_just_error_reply ndmp9_connect_open_reply; /* NDMP9_CONNECT_CLIENT_AUTH -- authorize client */ struct ndmp9_connect_client_auth_request { ndmp9_auth_data auth_data; }; typedef ndmp9_just_error_reply ndmp9_connect_client_auth_reply; /* NDMP9_CONNECT_CLOSE -- must never change, terminate control connection */ typedef ndmp9_no_arguments ndmp9_connect_close_request; typedef ndmp9_no_arguments ndmp9_connect_close_reply; /* NDMP9_CONNECT_SERVER_AUTH -- once client is authorized, ask server to * prove itself -- nobody is using this */ struct ndmp9_connect_server_auth_request { ndmp9_auth_attr client_attr; }; struct ndmp9_connect_server_auth_reply { ndmp9_error error; ndmp9_auth_data server_result; }; /* * CONFIG INTERFACE **************************************************************** * * The CONFIG interfaces allow the CONTROL Agent (DMA, client) to * obtain resource and other information from the DATA/TAPE/SCSI * Agent (DSP, server). * * For NDMPv9, the whole show is lumped into a single data structure. * The specific CONFIG interfaces, which vary between versions, * pick-n-choose the info needed. */ struct ndmp9_butype_info { string butype_name<>; ndmp9_valid_u_long v2attr; ndmp9_valid_u_long v3attr; ndmp9_valid_u_long v4attr; ndmp9_pval default_env<>; }; struct ndmp9_fs_info { string fs_type<>; string fs_logical_device<>; string fs_physical_device<>; ndmp9_valid_u_quad total_size; ndmp9_valid_u_quad used_size; ndmp9_valid_u_quad avail_size; ndmp9_valid_u_quad total_inodes; ndmp9_valid_u_quad used_inodes; ndmp9_pval fs_env<>; string fs_status<>; }; struct ndmp9_device_capability { string device<>; ndmp9_valid_u_long v3attr; ndmp9_valid_u_long v4attr; ndmp9_pval capability<>; }; struct ndmp9_device_info { string model<>; ndmp9_device_capability caplist<>; }; const NDMP9_CONFIG_CONNTYPE_LOCAL = 0x0001; const NDMP9_CONFIG_CONNTYPE_TCP = 0x0002; const NDMP9_CONFIG_AUTHTYPE_NONE = 0x0001; const NDMP9_CONFIG_AUTHTYPE_TEXT = 0x0002; const NDMP9_CONFIG_AUTHTYPE_MD5 = 0x0004; struct ndmp9_config_info { ndmp9_error error; /* ndmp[23]_config_get_host_info_reply */ string hostname<>; /* host name */ string os_type<>; /* The O/S type (e.g. SOLARIS) */ string os_vers<>; /* The O/S version (e.g. 2.5) */ string hostid<>; /* ndmp[34]_config_get_server_info_reply */ string vendor_name<>; string product_name<>; string revision_number<>; /* ndmp2_config_get_host_info */ /* ndmp[34]_config_get_server_info */ uint32_t authtypes; /* ndmp2_config_get_mover_type */ /* ndmp[34]_config_get_connection_type */ uint32_t conntypes; /* ndmp2_config_get_butype_attr */ /* ndmp[34]_config_get_butype_info */ ndmp9_butype_info butype_info<>; /* ndmp[34]_config_get_fs_info */ ndmp9_fs_info fs_info<>; /* ndmp[34]_config_get_tape_info */ ndmp9_device_info tape_info<>; /* ndmp[34]_config_get_scsi_info */ ndmp9_device_info scsi_info<>; }; /* NDMP9_CONFIG_GET_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_info_request; struct ndmp9_config_get_info_reply { ndmp9_error error; ndmp9_config_info config_info; }; /* NDMP9_CONFIG_GET_HOST_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_host_info_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_host_info_reply; /* NDMP9_CONFIG_GET_CONNECTION_TYPE */ typedef ndmp9_no_arguments ndmp9_config_get_connection_type_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_connection_type_reply; /* NDMP9_CONFIG_GET_SERVER_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_server_info_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_server_info_reply; /* NDMP9_CONFIG_GET_BUTYPE_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_butype_info_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_butype_info_reply; /* NDMP9_CONFIG_GET_FS_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_fs_info_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_fs_info_reply; /* NDMP9_CONFIG_GET_TAPE_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_tape_info_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_tape_info_reply; /* NDMP9_CONFIG_GET_SCSI_INFO */ typedef ndmp9_no_arguments ndmp9_config_get_scsi_info_request; typedef ndmp9_config_get_info_reply ndmp9_config_get_scsi_info_reply; /* NDMP9_CONFIG_GET_AUTH_ATTR */ struct ndmp9_config_get_auth_attr_request { ndmp9_auth_type auth_type; }; struct ndmp9_config_get_auth_attr_reply { ndmp9_error error; ndmp9_auth_attr server_attr; }; /* * SCSI INTERFACE **************************************************************** * * A SCSI pass-thru service. The CONTROL Agent (DMA, Client) * manipulates a SCSI Media Changer through this interface. * It may be used for other purposes. */ /* NDMP9_SCSI_OPEN */ struct ndmp9_scsi_open_request { string device<>; }; typedef ndmp9_just_error_reply ndmp9_scsi_open_reply; /* NDMP9_SCSI_CLOSE */ typedef ndmp9_no_arguments ndmp9_scsi_close_request; typedef ndmp9_just_error_reply ndmp9_scsi_close_reply; /* NDMP9_SCSI_GET_STATE */ typedef ndmp9_no_arguments ndmp9_scsi_get_state_request; struct ndmp9_scsi_get_state_reply { ndmp9_error error; short target_controller; short target_id; short target_lun; }; /* NDMP9_SCSI_SET_TARGET -- deleted for NDMPv4 */ struct ndmp9_scsi_set_target_request { string device<>; uint16_t target_controller; uint16_t target_id; uint16_t target_lun; }; typedef ndmp9_just_error_reply ndmp9_scsi_set_target_reply; /* NDMP9_SCSI_RESET_DEVICE */ typedef ndmp9_no_arguments ndmp9_scsi_reset_device_request; typedef ndmp9_just_error_reply ndmp9_scsi_reset_device_reply; /* NDMP9_SCSI_RESET_BUS -- deleted for NDMPv4 */ typedef ndmp9_no_arguments ndmp9_scsi_reset_bus_request; typedef ndmp9_just_error_reply ndmp9_scsi_reset_bus_reply; /* NDMP9_SCSI_EXECUTE_CDB */ enum ndmp9_scsi_data_dir { NDMP9_SCSI_DATA_DIR_NONE = 0, NDMP9_SCSI_DATA_DIR_IN = 1, /* Expect data from SCSI device */ NDMP9_SCSI_DATA_DIR_OUT = 2 /* Transfer data to SCSI device */ }; struct ndmp9_execute_cdb_request { ndmp9_scsi_data_dir data_dir; uint32_t timeout; uint32_t datain_len; /* Set for expected datain */ opaque cdb<>; opaque dataout<>; }; struct ndmp9_execute_cdb_reply { ndmp9_error error; u_char status; /* SCSI status bytes */ uint32_t dataout_len; opaque datain<>; /* SCSI datain */ opaque ext_sense<>; /* Extended sense data */ }; typedef ndmp9_execute_cdb_request ndmp9_scsi_execute_cdb_request; typedef ndmp9_execute_cdb_reply ndmp9_scsi_execute_cdb_reply; /******************/ /* TAPE INTERFACE */ /******************/ /* NDMP9_TAPE_OPEN */ enum ndmp9_tape_open_mode { NDMP9_TAPE_READ_MODE, NDMP9_TAPE_RDWR_MODE, NDMP9_TAPE_RAW_MODE /* new for NDMPv4 */ }; enum ndmp9_tape_state { NDMP9_TAPE_STATE_IDLE, /* not doing anything */ NDMP9_TAPE_STATE_OPEN, /* open, tape operations OK */ NDMP9_TAPE_STATE_MOVER /* mover active, tape ops locked out */ /* ie read, write, mtio, close, cdb */ }; struct ndmp9_tape_open_request { string device<>; ndmp9_tape_open_mode mode; }; typedef ndmp9_just_error_reply ndmp9_tape_open_reply; /* NDMP9_TAPE_CLOSE */ typedef ndmp9_no_arguments ndmp9_tape_close_request; typedef ndmp9_just_error_reply ndmp9_tape_close_reply; /* NDMP9_TAPE_GET_STATE */ const NDMP9_TAPE_STATE_NOREWIND = 0x0008; /* non-rewind device */ const NDMP9_TAPE_STATE_WR_PROT = 0x0010; /* write-protected */ const NDMP9_TAPE_STATE_ERROR = 0x0020; /* media error */ const NDMP9_TAPE_STATE_UNLOAD = 0x0040; /* tape will be unloaded when * the device is closed */ typedef ndmp9_no_arguments ndmp9_tape_get_state_request; struct ndmp9_tape_get_state_reply { ndmp9_error error; uint32_t flags; /* compatible NDMP[2349] */ ndmp9_tape_state state; ndmp9_tape_open_mode open_mode; ndmp9_valid_u_long file_num; ndmp9_valid_u_long soft_errors; ndmp9_valid_u_long block_size; ndmp9_valid_u_long blockno; ndmp9_valid_u_quad total_space; ndmp9_valid_u_quad space_remain; ndmp9_valid_u_long partition; }; /* NDMP9_TAPE_MTIO */ enum ndmp9_tape_mtio_op { NDMP9_MTIO_FSF, NDMP9_MTIO_BSF, NDMP9_MTIO_FSR, NDMP9_MTIO_BSR, NDMP9_MTIO_REW, NDMP9_MTIO_EOF, NDMP9_MTIO_OFF }; struct ndmp9_tape_mtio_request { ndmp9_tape_mtio_op tape_op; uint32_t count; }; struct ndmp9_tape_mtio_reply { ndmp9_error error; uint32_t resid_count; }; /* NDMP9_TAPE_WRITE */ struct ndmp9_tape_write_request { opaque data_out<>; }; struct ndmp9_tape_write_reply { ndmp9_error error; uint32_t count; }; /* NDMP9_TAPE_READ */ struct ndmp9_tape_read_request { uint32_t count; }; struct ndmp9_tape_read_reply { ndmp9_error error; opaque data_in<>; }; /* NDMP9_TAPE_EXECUTE_CDB */ typedef ndmp9_execute_cdb_request ndmp9_tape_execute_cdb_request; typedef ndmp9_execute_cdb_reply ndmp9_tape_execute_cdb_reply; /********************************/ /* MOVER INTERFACE */ /********************************/ enum ndmp9_mover_state { NDMP9_MOVER_STATE_IDLE, NDMP9_MOVER_STATE_LISTEN, NDMP9_MOVER_STATE_ACTIVE, NDMP9_MOVER_STATE_PAUSED, NDMP9_MOVER_STATE_HALTED, NDMP9_MOVER_STATE_STANDBY /* awaiting mover_read_request */ }; enum ndmp9_mover_mode { NDMP9_MOVER_MODE_READ, /* read from data conn; write to tape */ NDMP9_MOVER_MODE_WRITE /* write to data conn; read from tape */ }; enum ndmp9_mover_pause_reason { NDMP9_MOVER_PAUSE_NA, NDMP9_MOVER_PAUSE_EOM, NDMP9_MOVER_PAUSE_EOF, NDMP9_MOVER_PAUSE_SEEK, NDMP9_MOVER_PAUSE_MEDIA_ERROR, NDMP9_MOVER_PAUSE_EOW }; enum ndmp9_mover_halt_reason { NDMP9_MOVER_HALT_NA, NDMP9_MOVER_HALT_CONNECT_CLOSED, NDMP9_MOVER_HALT_ABORTED, NDMP9_MOVER_HALT_INTERNAL_ERROR, NDMP9_MOVER_HALT_CONNECT_ERROR, NDMP9_MOVER_HALT_MEDIA_ERROR }; /* NDMP9_MOVER_GET_STATE */ typedef ndmp9_no_arguments ndmp9_mover_get_state_request; struct ndmp9_mover_get_state_reply { ndmp9_error error; ndmp9_mover_state state; ndmp9_mover_mode mode; ndmp9_mover_pause_reason pause_reason; ndmp9_mover_halt_reason halt_reason; uint32_t record_size; uint32_t record_num; ndmp9_u_quad bytes_moved; ndmp9_u_quad seek_position; ndmp9_u_quad bytes_left_to_read; ndmp9_u_quad window_offset; ndmp9_u_quad window_length; ndmp9_addr data_connection_addr; }; /* NDMP9_MOVER_LISTEN */ struct ndmp9_mover_listen_request { ndmp9_mover_mode mode; ndmp9_addr_type addr_type; }; struct ndmp9_mover_listen_reply { ndmp9_error error; ndmp9_addr data_connection_addr; }; /* NDMP9_MOVER_CONNECT */ struct ndmp9_mover_connect_request { ndmp9_mover_mode mode; ndmp9_addr addr; }; typedef ndmp9_just_error_reply ndmp9_mover_connect_reply; /* NDMP9_MOVER_SET_RECORD_SIZE */ struct ndmp9_mover_set_record_size_request { uint32_t record_size; }; typedef ndmp9_just_error_reply ndmp9_mover_set_record_size_reply; /* NDMP9_MOVER_SET_WINDOW */ struct ndmp9_mover_set_window_request { ndmp9_u_quad offset; ndmp9_u_quad length; }; typedef ndmp9_just_error_reply ndmp9_mover_set_window_reply; /* NDMP9_MOVER_CONTINUE */ typedef ndmp9_no_arguments ndmp9_mover_continue_request; typedef ndmp9_just_error_reply ndmp9_mover_continue_reply; /* NDMP9_MOVER_ABORT */ typedef ndmp9_no_arguments ndmp9_mover_abort_request; typedef ndmp9_just_error_reply ndmp9_mover_abort_reply; /* NDMP9_MOVER_STOP */ typedef ndmp9_no_arguments ndmp9_mover_stop_request; typedef ndmp9_just_error_reply ndmp9_mover_stop_reply; /* NDMP9_MOVER_READ */ struct ndmp9_mover_read_request { ndmp9_u_quad offset; ndmp9_u_quad length; }; typedef ndmp9_just_error_reply ndmp9_mover_read_reply; /* NDMP9_MOVER_CLOSE */ typedef ndmp9_no_arguments ndmp9_mover_close_request; typedef ndmp9_just_error_reply ndmp9_mover_close_reply; /****************************/ /* DATA INTERFACE */ /****************************/ enum ndmp9_data_operation { NDMP9_DATA_OP_NOACTION, NDMP9_DATA_OP_BACKUP, NDMP9_DATA_OP_RECOVER, NDMP9_DATA_OP_RECOVER_FILEHIST }; enum ndmp9_data_state { NDMP9_DATA_STATE_IDLE, NDMP9_DATA_STATE_ACTIVE, NDMP9_DATA_STATE_HALTED, NDMP9_DATA_STATE_LISTEN, NDMP9_DATA_STATE_CONNECTED }; enum ndmp9_data_halt_reason { NDMP9_DATA_HALT_NA, NDMP9_DATA_HALT_SUCCESSFUL, NDMP9_DATA_HALT_ABORTED, NDMP9_DATA_HALT_INTERNAL_ERROR, NDMP9_DATA_HALT_CONNECT_ERROR }; /* NDMP9_DATA_START_BACKUP */ typedef ndmp9_no_arguments ndmp9_data_get_state_request; struct ndmp9_data_get_state_reply { ndmp9_error error; ndmp9_data_operation operation; ndmp9_data_state state; ndmp9_data_halt_reason halt_reason; ndmp9_u_quad bytes_processed; ndmp9_valid_u_quad est_bytes_remain; ndmp9_valid_u_long est_time_remain; ndmp9_addr data_connection_addr; ndmp9_u_quad read_offset; ndmp9_u_quad read_length; }; struct ndmp9_name { string original_path<>; /* relative to backup root */ string destination_path<>; /* nt_destination_path<> */ string name<>; string other_name<>; ndmp9_u_quad node; ndmp9_valid_u_quad fh_info; }; /* NDMP9_DATA_START_BACKUP */ struct ndmp9_data_start_backup_request { string bu_type<>; /* backup method to use */ ndmp9_pval env<>; /* Parameters that may modify backup */ ndmp9_addr addr; }; typedef ndmp9_just_error_reply ndmp9_data_start_backup_reply; /* NDMP9_DATA_START_RECOVER */ struct ndmp9_data_start_recover_request { ndmp9_pval env<>; ndmp9_name nlist<>; string bu_type<>; ndmp9_addr addr; }; typedef ndmp9_just_error_reply ndmp9_data_start_recover_reply; /* NDMP9_DATA_START_RECOVER_FILEHIST */ typedef ndmp9_data_start_recover_request ndmp9_data_start_recover_filehist_request; typedef ndmp9_data_start_recover_reply ndmp9_data_start_recover_filehist_reply; /* NDMP9_DATA_ABORT */ typedef ndmp9_no_arguments ndmp9_data_abort_request; typedef ndmp9_just_error_reply ndmp9_data_abort_reply; /* NDMP9_DATA_STOP */ typedef ndmp9_no_arguments ndmp9_data_stop_request; typedef ndmp9_just_error_reply ndmp9_data_stop_reply; /* NDMP9_DATA_GET_ENV */ typedef ndmp9_no_arguments ndmp9_data_get_env_request; struct ndmp9_data_get_env_reply { ndmp9_error error; ndmp9_pval env<>; }; /* NDMP9_DATA_LISTEN */ struct ndmp9_data_listen_request { ndmp9_addr_type addr_type; }; struct ndmp9_data_listen_reply { ndmp9_error error; ndmp9_addr data_connection_addr; }; /* NDMP9_DATA_CONNECT */ struct ndmp9_data_connect_request { ndmp9_addr addr; }; typedef ndmp9_just_error_reply ndmp9_data_connect_reply; /****************************/ /* NOTIFY INTERFACE */ /****************************/ /* NDMP9_NOTIFY_DATA_HALTED */ struct ndmp9_notify_data_halted_request { ndmp9_data_halt_reason reason; }; enum ndmp9_connect_reason { NDMP9_CONNECTED, /* Connect sucessfully */ NDMP9_SHUTDOWN, /* Connection shutdown */ NDMP9_REFUSED /* reach the maximum number of connections */ }; /* NDMP9_NOTIFY_CONNECTED */ struct ndmp9_notify_connected_request { ndmp9_connect_reason reason; uint16_t protocol_version; string text_reason<>; }; /* NDMP9_NOTIFY_MOVER_HALTED */ struct ndmp9_notify_mover_halted_request { ndmp9_mover_halt_reason reason; }; /* NDMP9_NOTIFY_MOVER_PAUSED */ struct ndmp9_notify_mover_paused_request { ndmp9_mover_pause_reason reason; ndmp9_u_quad seek_position; }; /* NDMP9_NOTIFY_DATA_READ */ struct ndmp9_notify_data_read_request { ndmp9_u_quad offset; ndmp9_u_quad length; }; /********************************/ /* LOG INTERFACE */ /********************************/ /* NDMP9_LOG_MESSAGE */ enum ndmp9_log_type { NDMP9_LOG_NORMAL, NDMP9_LOG_DEBUG, NDMP9_LOG_ERROR, NDMP9_LOG_WARNING }; struct ndmp9_log_message_request { ndmp9_log_type log_type; uint32_t message_id; string entry<>; ndmp9_valid_u_long associated_message_sequence; }; /* No reply */ enum ndmp9_recovery_status { NDMP9_RECOVERY_SUCCESSFUL = 0, NDMP9_RECOVERY_FAILED_PERMISSION = 1, NDMP9_RECOVERY_FAILED_NOT_FOUND = 2, NDMP9_RECOVERY_FAILED_NO_DIRECTORY = 3, NDMP9_RECOVERY_FAILED_OUT_OF_MEMORY = 4, NDMP9_RECOVERY_FAILED_IO_ERROR = 5, NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR = 6 }; /* NDMP9_LOG_FILE */ struct ndmp9_log_file_request { string name<>; ndmp9_recovery_status recovery_status; }; /* No reply */ /* * FILE HISTORY INTERFACES **************************************************************** */ enum ndmp9_file_type { NDMP9_FILE_DIR, NDMP9_FILE_FIFO, NDMP9_FILE_CSPEC, NDMP9_FILE_BSPEC, NDMP9_FILE_REG, NDMP9_FILE_SLINK, NDMP9_FILE_SOCK, NDMP9_FILE_REGISTRY, NDMP9_FILE_OTHER }; struct ndmp9_file_stat { ndmp9_file_type ftype; ndmp9_valid_u_long mtime; ndmp9_valid_u_long atime; ndmp9_valid_u_long ctime; ndmp9_valid_u_long uid; ndmp9_valid_u_long gid; ndmp9_valid_u_long mode; ndmp9_valid_u_quad size; ndmp9_valid_u_long links; /* * Add NT attributes here as ndmp9_valid_.... */ ndmp9_valid_u_quad node; /* id on disk at backup time */ ndmp9_valid_u_quad fh_info; /* id on tape at backup time */ }; /* * ndmp_fh_add_file * no reply */ struct ndmp9_file { string unix_path<>; /* nt_path<> here */ /* dos_path<> here */ ndmp9_file_stat fstat; }; struct ndmp9_fh_add_file_request { ndmp9_file files<>; }; /* * ndmp_fh_add_dir * no reply */ struct ndmp9_dir { string unix_name<>; /* nt_name<> here */ /* dos_name<> here */ ndmp9_u_quad node; ndmp9_u_quad parent; }; struct ndmp9_fh_add_dir_request { ndmp9_dir dirs<>; }; /* * ndmp_fh_add_node * no reply */ struct ndmp9_node { ndmp9_file_stat fstat; }; struct ndmp9_fh_add_node_request { ndmp9_node nodes<>; }; /* No reply */ bareos-Release-14.2.6/src/ndmp/ndmp9_enum_strs.c000066400000000000000000000306411263011562700214630ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" extern struct ndmp_enum_str_table ndmp9_error_table[]; extern char * ndmp9_error_to_str (ndmp9_error val); extern int ndmp9_error_from_str (ndmp9_error *valp, char * str); char * ndmp9_error_to_str (ndmp9_error val) { return ndmp_enum_to_str ((int)val, ndmp9_error_table); } int ndmp9_error_from_str (ndmp9_error *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_error_table); } struct ndmp_enum_str_table ndmp9_error_table[] = { { "NDMP9_NO_ERR", NDMP9_NO_ERR }, { "NDMP9_NOT_SUPPORTED_ERR", NDMP9_NOT_SUPPORTED_ERR }, { "NDMP9_DEVICE_BUSY_ERR", NDMP9_DEVICE_BUSY_ERR }, { "NDMP9_DEVICE_OPENED_ERR", NDMP9_DEVICE_OPENED_ERR }, { "NDMP9_NOT_AUTHORIZED_ERR", NDMP9_NOT_AUTHORIZED_ERR }, { "NDMP9_PERMISSION_ERR", NDMP9_PERMISSION_ERR }, { "NDMP9_DEV_NOT_OPEN_ERR", NDMP9_DEV_NOT_OPEN_ERR }, { "NDMP9_IO_ERR", NDMP9_IO_ERR }, { "NDMP9_TIMEOUT_ERR", NDMP9_TIMEOUT_ERR }, { "NDMP9_ILLEGAL_ARGS_ERR", NDMP9_ILLEGAL_ARGS_ERR }, { "NDMP9_NO_TAPE_LOADED_ERR", NDMP9_NO_TAPE_LOADED_ERR }, { "NDMP9_WRITE_PROTECT_ERR", NDMP9_WRITE_PROTECT_ERR }, { "NDMP9_EOF_ERR", NDMP9_EOF_ERR }, { "NDMP9_EOM_ERR", NDMP9_EOM_ERR }, { "NDMP9_FILE_NOT_FOUND_ERR", NDMP9_FILE_NOT_FOUND_ERR }, { "NDMP9_BAD_FILE_ERR", NDMP9_BAD_FILE_ERR }, { "NDMP9_NO_DEVICE_ERR", NDMP9_NO_DEVICE_ERR }, { "NDMP9_NO_BUS_ERR", NDMP9_NO_BUS_ERR }, { "NDMP9_XDR_DECODE_ERR", NDMP9_XDR_DECODE_ERR }, { "NDMP9_ILLEGAL_STATE_ERR", NDMP9_ILLEGAL_STATE_ERR }, { "NDMP9_UNDEFINED_ERR", NDMP9_UNDEFINED_ERR }, { "NDMP9_XDR_ENCODE_ERR", NDMP9_XDR_ENCODE_ERR }, { "NDMP9_NO_MEM_ERR", NDMP9_NO_MEM_ERR }, { "NDMP9_CONNECT_ERR", NDMP9_CONNECT_ERR, }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_auth_type_table[]; extern char * ndmp9_auth_type_to_str (ndmp9_auth_type val); extern int ndmp9_auth_type_from_str (ndmp9_auth_type *valp, char * str); char * ndmp9_auth_type_to_str (ndmp9_auth_type val) { return ndmp_enum_to_str ((int)val, ndmp9_auth_type_table); } int ndmp9_auth_type_from_str (ndmp9_auth_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_auth_type_table); } struct ndmp_enum_str_table ndmp9_auth_type_table[] = { { "NDMP9_AUTH_NONE", NDMP9_AUTH_NONE }, { "NDMP9_AUTH_TEXT", NDMP9_AUTH_TEXT }, { "NDMP9_AUTH_MD5", NDMP9_AUTH_MD5 }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_addr_type_table[]; extern char * ndmp9_addr_type_to_str (ndmp9_addr_type val); extern int ndmp9_addr_type_from_str (ndmp9_addr_type *valp, char * str); char * ndmp9_addr_type_to_str (ndmp9_addr_type val) { return ndmp_enum_to_str ((int)val, ndmp9_addr_type_table); } int ndmp9_addr_type_from_str (ndmp9_addr_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_addr_type_table); } struct ndmp_enum_str_table ndmp9_addr_type_table[] = { { "NDMP9_ADDR_LOCAL", NDMP9_ADDR_LOCAL }, { "NDMP9_ADDR_TCP", NDMP9_ADDR_TCP }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_tape_open_mode_table[]; extern char * ndmp9_tape_open_mode_to_str (ndmp9_tape_open_mode val); extern int ndmp9_tape_open_mode_from_str (ndmp9_tape_open_mode *valp, char * str); char * ndmp9_tape_open_mode_to_str (ndmp9_tape_open_mode val) { return ndmp_enum_to_str ((int)val, ndmp9_tape_open_mode_table); } int ndmp9_tape_open_mode_from_str (ndmp9_tape_open_mode *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_tape_open_mode_table); } struct ndmp_enum_str_table ndmp9_tape_open_mode_table[] = { { "NDMP9_TAPE_READ_MODE", NDMP9_TAPE_READ_MODE }, { "NDMP9_TAPE_RDWR_MODE", NDMP9_TAPE_RDWR_MODE }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_tape_mtio_op_table[]; extern char * ndmp9_tape_mtio_op_to_str (ndmp9_tape_mtio_op val); extern int ndmp9_tape_mtio_op_from_str (ndmp9_tape_mtio_op *valp, char * str); char * ndmp9_tape_mtio_op_to_str (ndmp9_tape_mtio_op val) { return ndmp_enum_to_str ((int)val, ndmp9_tape_mtio_op_table); } int ndmp9_tape_mtio_op_from_str (ndmp9_tape_mtio_op *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_tape_mtio_op_table); } struct ndmp_enum_str_table ndmp9_tape_mtio_op_table[] = { { "NDMP9_MTIO_FSF", NDMP9_MTIO_FSF }, { "NDMP9_MTIO_BSF", NDMP9_MTIO_BSF }, { "NDMP9_MTIO_FSR", NDMP9_MTIO_FSR }, { "NDMP9_MTIO_BSR", NDMP9_MTIO_BSR }, { "NDMP9_MTIO_REW", NDMP9_MTIO_REW }, { "NDMP9_MTIO_EOF", NDMP9_MTIO_EOF }, { "NDMP9_MTIO_OFF", NDMP9_MTIO_OFF }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_mover_state_table[]; extern char * ndmp9_mover_state_to_str (ndmp9_mover_state val); extern int ndmp9_mover_state_from_str (ndmp9_mover_state *valp, char * str); char * ndmp9_mover_state_to_str (ndmp9_mover_state val) { return ndmp_enum_to_str ((int)val, ndmp9_mover_state_table); } int ndmp9_mover_state_from_str (ndmp9_mover_state *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_mover_state_table); } struct ndmp_enum_str_table ndmp9_mover_state_table[] = { { "NDMP9_MOVER_STATE_IDLE", NDMP9_MOVER_STATE_IDLE }, { "NDMP9_MOVER_STATE_LISTEN", NDMP9_MOVER_STATE_LISTEN }, { "NDMP9_MOVER_STATE_ACTIVE", NDMP9_MOVER_STATE_ACTIVE }, { "NDMP9_MOVER_STATE_PAUSED", NDMP9_MOVER_STATE_PAUSED }, { "NDMP9_MOVER_STATE_HALTED", NDMP9_MOVER_STATE_HALTED }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_mover_pause_reason_table[]; extern char * ndmp9_mover_pause_reason_to_str (ndmp9_mover_pause_reason val); extern int ndmp9_mover_pause_reason_from_str (ndmp9_mover_pause_reason *valp, char * str); char * ndmp9_mover_pause_reason_to_str (ndmp9_mover_pause_reason val) { return ndmp_enum_to_str ((int)val, ndmp9_mover_pause_reason_table); } int ndmp9_mover_pause_reason_from_str (ndmp9_mover_pause_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_mover_pause_reason_table); } struct ndmp_enum_str_table ndmp9_mover_pause_reason_table[] = { { "NDMP9_MOVER_PAUSE_NA", NDMP9_MOVER_PAUSE_NA }, { "NDMP9_MOVER_PAUSE_EOM", NDMP9_MOVER_PAUSE_EOM }, { "NDMP9_MOVER_PAUSE_EOF", NDMP9_MOVER_PAUSE_EOF }, { "NDMP9_MOVER_PAUSE_SEEK", NDMP9_MOVER_PAUSE_SEEK }, { "NDMP9_MOVER_PAUSE_MEDIA_ERROR", NDMP9_MOVER_PAUSE_MEDIA_ERROR }, { "NDMP9_MOVER_PAUSE_EOW", NDMP9_MOVER_PAUSE_EOW }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_mover_halt_reason_table[]; extern char * ndmp9_mover_halt_reason_to_str (ndmp9_mover_halt_reason val); extern int ndmp9_mover_halt_reason_from_str (ndmp9_mover_halt_reason *valp, char * str); char * ndmp9_mover_halt_reason_to_str (ndmp9_mover_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp9_mover_halt_reason_table); } int ndmp9_mover_halt_reason_from_str (ndmp9_mover_halt_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_mover_halt_reason_table); } struct ndmp_enum_str_table ndmp9_mover_halt_reason_table[] = { { "NDMP9_MOVER_HALT_NA", NDMP9_MOVER_HALT_NA }, { "NDMP9_MOVER_HALT_CONNECT_CLOSED", NDMP9_MOVER_HALT_CONNECT_CLOSED }, { "NDMP9_MOVER_HALT_ABORTED", NDMP9_MOVER_HALT_ABORTED }, { "NDMP9_MOVER_HALT_INTERNAL_ERROR", NDMP9_MOVER_HALT_INTERNAL_ERROR }, { "NDMP9_MOVER_HALT_CONNECT_ERROR", NDMP9_MOVER_HALT_CONNECT_ERROR }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_mover_mode_table[]; extern char * ndmp9_mover_mode_to_str (ndmp9_mover_mode val); extern int ndmp9_mover_mode_from_str (ndmp9_mover_mode *valp, char * str); char * ndmp9_mover_mode_to_str (ndmp9_mover_mode val) { return ndmp_enum_to_str ((int)val, ndmp9_mover_mode_table); } int ndmp9_mover_mode_from_str (ndmp9_mover_mode *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_mover_mode_table); } struct ndmp_enum_str_table ndmp9_mover_mode_table[] = { { "NDMP9_MOVER_MODE_READ", NDMP9_MOVER_MODE_READ }, { "NDMP9_MOVER_MODE_WRITE", NDMP9_MOVER_MODE_WRITE }, #if 0 { "NDMP9_MOVER_MODE_DATA", NDMP9_MOVER_MODE_DATA }, #endif { 0 } }; extern struct ndmp_enum_str_table ndmp9_data_operation_table[]; extern char * ndmp9_data_operation_to_str (ndmp9_data_operation val); extern int ndmp9_data_operation_from_str (ndmp9_data_operation *valp, char * str); char * ndmp9_data_operation_to_str (ndmp9_data_operation val) { return ndmp_enum_to_str ((int)val, ndmp9_data_operation_table); } int ndmp9_data_operation_from_str (ndmp9_data_operation *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_data_operation_table); } struct ndmp_enum_str_table ndmp9_data_operation_table[] = { { "NDMP9_DATA_OP_NOACTION", NDMP9_DATA_OP_NOACTION }, { "NDMP9_DATA_OP_BACKUP", NDMP9_DATA_OP_BACKUP }, { "NDMP9_DATA_OP_RECOVER", NDMP9_DATA_OP_RECOVER }, { "NDMP9_DATA_OP_RECOVER_FILEHIST", NDMP9_DATA_OP_RECOVER_FILEHIST }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_data_state_table[]; extern char * ndmp9_data_state_to_str (ndmp9_data_state val); extern int ndmp9_data_state_from_str (ndmp9_data_state *valp, char * str); char * ndmp9_data_state_to_str (ndmp9_data_state val) { return ndmp_enum_to_str ((int)val, ndmp9_data_state_table); } int ndmp9_data_state_from_str (ndmp9_data_state *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_data_state_table); } struct ndmp_enum_str_table ndmp9_data_state_table[] = { { "NDMP9_DATA_STATE_IDLE", NDMP9_DATA_STATE_IDLE }, { "NDMP9_DATA_STATE_ACTIVE", NDMP9_DATA_STATE_ACTIVE }, { "NDMP9_DATA_STATE_HALTED", NDMP9_DATA_STATE_HALTED }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_data_halt_reason_table[]; extern char * ndmp9_data_halt_reason_to_str (ndmp9_data_halt_reason val); extern int ndmp9_data_halt_reason_from_str (ndmp9_data_halt_reason *valp, char * str); char * ndmp9_data_halt_reason_to_str (ndmp9_data_halt_reason val) { return ndmp_enum_to_str ((int)val, ndmp9_data_halt_reason_table); } int ndmp9_data_halt_reason_from_str (ndmp9_data_halt_reason *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_data_halt_reason_table); } struct ndmp_enum_str_table ndmp9_data_halt_reason_table[] = { { "NDMP9_DATA_HALT_NA", NDMP9_DATA_HALT_NA }, { "NDMP9_DATA_HALT_SUCCESSFUL", NDMP9_DATA_HALT_SUCCESSFUL }, { "NDMP9_DATA_HALT_ABORTED", NDMP9_DATA_HALT_ABORTED }, { "NDMP9_DATA_HALT_INTERNAL_ERROR", NDMP9_DATA_HALT_INTERNAL_ERROR }, { "NDMP9_DATA_HALT_CONNECT_ERROR", NDMP9_DATA_HALT_CONNECT_ERROR }, { 0 } }; extern struct ndmp_enum_str_table ndmp9_file_type_table[]; extern char * ndmp9_file_type_to_str (ndmp9_file_type val); extern int ndmp9_file_type_from_str (ndmp9_file_type *valp, char * str); char * ndmp9_file_type_to_str (ndmp9_file_type val) { return ndmp_enum_to_str ((int)val, ndmp9_file_type_table); } int ndmp9_file_type_from_str (ndmp9_file_type *valp, char * str) { return ndmp_enum_from_str ((int*)valp, str, ndmp9_file_type_table); } struct ndmp_enum_str_table ndmp9_file_type_table[] = { { "NDMP9_FILE_DIR", NDMP9_FILE_DIR }, { "NDMP9_FILE_FIFO", NDMP9_FILE_FIFO }, { "NDMP9_FILE_CSPEC", NDMP9_FILE_CSPEC }, { "NDMP9_FILE_BSPEC", NDMP9_FILE_BSPEC }, { "NDMP9_FILE_REG", NDMP9_FILE_REG }, { "NDMP9_FILE_SLINK", NDMP9_FILE_SLINK }, { "NDMP9_FILE_SOCK", NDMP9_FILE_SOCK }, { "NDMP9_FILE_REGISTRY", NDMP9_FILE_REGISTRY }, { "NDMP9_FILE_OTHER", NDMP9_FILE_OTHER }, { 0 } }; bareos-Release-14.2.6/src/ndmp/ndmp9_enum_strs.h000066400000000000000000000101371263011562700214660ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ extern struct ndmp_enum_str_table ndmp9_error_table[]; extern char * ndmp9_error_to_str (ndmp9_error val); extern int ndmp9_error_from_str (ndmp9_error *valp, char * str); extern struct ndmp_enum_str_table ndmp9_auth_type_table[]; extern char * ndmp9_auth_type_to_str (ndmp9_auth_type val); extern int ndmp9_auth_type_from_str (ndmp9_auth_type *valp, char * str); extern struct ndmp_enum_str_table ndmp9_addr_type_table[]; extern char * ndmp9_addr_type_to_str (ndmp9_addr_type val); extern int ndmp9_addr_type_from_str (ndmp9_addr_type *valp, char * str); extern struct ndmp_enum_str_table ndmp9_tape_open_mode_table[]; extern char * ndmp9_tape_open_mode_to_str (ndmp9_tape_open_mode val); extern int ndmp9_tape_open_mode_from_str (ndmp9_tape_open_mode *valp, char * str); extern struct ndmp_enum_str_table ndmp9_tape_mtio_op_table[]; extern char * ndmp9_tape_mtio_op_to_str (ndmp9_tape_mtio_op val); extern int ndmp9_tape_mtio_op_from_str (ndmp9_tape_mtio_op *valp, char * str); extern struct ndmp_enum_str_table ndmp9_mover_state_table[]; extern char * ndmp9_mover_state_to_str (ndmp9_mover_state val); extern int ndmp9_mover_state_from_str (ndmp9_mover_state *valp, char * str); extern struct ndmp_enum_str_table ndmp9_mover_pause_reason_table[]; extern char * ndmp9_mover_pause_reason_to_str (ndmp9_mover_pause_reason val); extern int ndmp9_mover_pause_reason_from_str (ndmp9_mover_pause_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp9_mover_halt_reason_table[]; extern char * ndmp9_mover_halt_reason_to_str (ndmp9_mover_halt_reason val); extern int ndmp9_mover_halt_reason_from_str (ndmp9_mover_halt_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp9_mover_mode_table[]; extern char * ndmp9_mover_mode_to_str (ndmp9_mover_mode val); extern int ndmp9_mover_mode_from_str (ndmp9_mover_mode *valp, char * str); extern struct ndmp_enum_str_table ndmp9_data_operation_table[]; extern char * ndmp9_data_operation_to_str (ndmp9_data_operation val); extern int ndmp9_data_operation_from_str (ndmp9_data_operation *valp, char * str); extern struct ndmp_enum_str_table ndmp9_data_state_table[]; extern char * ndmp9_data_state_to_str (ndmp9_data_state val); extern int ndmp9_data_state_from_str (ndmp9_data_state *valp, char * str); extern struct ndmp_enum_str_table ndmp9_data_halt_reason_table[]; extern char * ndmp9_data_halt_reason_to_str (ndmp9_data_halt_reason val); extern int ndmp9_data_halt_reason_from_str (ndmp9_data_halt_reason *valp, char * str); extern struct ndmp_enum_str_table ndmp9_file_type_table[]; extern char * ndmp9_file_type_to_str (ndmp9_file_type val); extern int ndmp9_file_type_from_str (ndmp9_file_type *valp, char * str); bareos-Release-14.2.6/src/ndmp/ndmp9_xmt.c000066400000000000000000000176531263011562700202640ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" #include "ndmprotocol.h" struct ndmp_xdr_message_table ndmp9_xdr_message_table[] = { { NDMP9_CONNECT_OPEN, xdr_ndmp9_connect_open_request, xdr_ndmp9_connect_open_reply, }, { NDMP9_CONNECT_CLIENT_AUTH, xdr_ndmp9_connect_client_auth_request, xdr_ndmp9_connect_client_auth_reply, }, { NDMP9_CONNECT_CLOSE, xdr_ndmp9_connect_close_request, xdr_ndmp9_connect_close_reply, }, { NDMP9_CONNECT_SERVER_AUTH, xdr_ndmp9_connect_server_auth_request, xdr_ndmp9_connect_server_auth_reply, }, { NDMP9_CONFIG_GET_HOST_INFO, xdr_ndmp9_config_get_host_info_request, xdr_ndmp9_config_get_host_info_reply, }, { NDMP9_CONFIG_GET_CONNECTION_TYPE, xdr_ndmp9_config_get_connection_type_request, xdr_ndmp9_config_get_connection_type_reply, }, { NDMP9_CONFIG_GET_AUTH_ATTR, xdr_ndmp9_config_get_auth_attr_request, xdr_ndmp9_config_get_auth_attr_reply, }, { NDMP9_CONFIG_GET_BUTYPE_INFO, xdr_ndmp9_config_get_butype_info_request, xdr_ndmp9_config_get_butype_info_reply, }, { NDMP9_CONFIG_GET_FS_INFO, xdr_ndmp9_config_get_fs_info_request, xdr_ndmp9_config_get_fs_info_reply, }, { NDMP9_CONFIG_GET_TAPE_INFO, xdr_ndmp9_config_get_tape_info_request, xdr_ndmp9_config_get_tape_info_reply, }, { NDMP9_CONFIG_GET_SCSI_INFO, xdr_ndmp9_config_get_scsi_info_request, xdr_ndmp9_config_get_scsi_info_reply, }, { NDMP9_CONFIG_GET_SERVER_INFO, xdr_ndmp9_config_get_server_info_request, xdr_ndmp9_config_get_server_info_reply, }, { NDMP9_SCSI_OPEN, xdr_ndmp9_scsi_open_request, xdr_ndmp9_scsi_open_reply, }, { NDMP9_SCSI_CLOSE, xdr_ndmp9_scsi_close_request, xdr_ndmp9_scsi_close_reply, }, { NDMP9_SCSI_GET_STATE, xdr_ndmp9_scsi_get_state_request, xdr_ndmp9_scsi_get_state_reply, }, { NDMP9_SCSI_RESET_DEVICE, xdr_ndmp9_scsi_reset_device_request, xdr_ndmp9_scsi_reset_device_reply, }, { NDMP9_SCSI_EXECUTE_CDB, xdr_ndmp9_scsi_execute_cdb_request, xdr_ndmp9_scsi_execute_cdb_reply, }, { NDMP9_TAPE_OPEN, xdr_ndmp9_tape_open_request, xdr_ndmp9_tape_open_reply, }, { NDMP9_TAPE_CLOSE, xdr_ndmp9_tape_close_request, xdr_ndmp9_tape_close_reply, }, { NDMP9_TAPE_GET_STATE, xdr_ndmp9_tape_get_state_request, xdr_ndmp9_tape_get_state_reply, }, { NDMP9_TAPE_MTIO, xdr_ndmp9_tape_mtio_request, xdr_ndmp9_tape_mtio_reply, }, { NDMP9_TAPE_WRITE, xdr_ndmp9_tape_write_request, xdr_ndmp9_tape_write_reply, }, { NDMP9_TAPE_READ, xdr_ndmp9_tape_read_request, xdr_ndmp9_tape_read_reply, }, { NDMP9_TAPE_EXECUTE_CDB, xdr_ndmp9_tape_execute_cdb_request, xdr_ndmp9_tape_execute_cdb_reply, }, { NDMP9_DATA_GET_STATE, xdr_ndmp9_data_get_state_request, xdr_ndmp9_data_get_state_reply, }, { NDMP9_DATA_START_BACKUP, xdr_ndmp9_data_start_backup_request, xdr_ndmp9_data_start_backup_reply, }, { NDMP9_DATA_START_RECOVER, xdr_ndmp9_data_start_recover_request, xdr_ndmp9_data_start_recover_reply, }, { NDMP9_DATA_START_RECOVER_FILEHIST, xdr_ndmp9_data_start_recover_filehist_request, xdr_ndmp9_data_start_recover_filehist_reply, }, { NDMP9_DATA_ABORT, xdr_ndmp9_data_abort_request, xdr_ndmp9_data_abort_reply, }, { NDMP9_DATA_GET_ENV, xdr_ndmp9_data_get_env_request, xdr_ndmp9_data_get_env_reply, }, { NDMP9_DATA_STOP, xdr_ndmp9_data_stop_request, xdr_ndmp9_data_stop_reply, }, { NDMP9_DATA_LISTEN, xdr_ndmp9_data_listen_request, xdr_ndmp9_data_listen_reply, }, { NDMP9_DATA_CONNECT, xdr_ndmp9_data_connect_request, xdr_ndmp9_data_connect_reply, }, { NDMP9_NOTIFY_DATA_HALTED, xdr_ndmp9_notify_data_halted_request, 0 }, { NDMP9_NOTIFY_CONNECTED, xdr_ndmp9_notify_connected_request, 0 }, { NDMP9_NOTIFY_MOVER_HALTED, xdr_ndmp9_notify_mover_halted_request, 0 }, { NDMP9_NOTIFY_MOVER_PAUSED, xdr_ndmp9_notify_mover_paused_request, 0 }, { NDMP9_NOTIFY_DATA_READ, xdr_ndmp9_notify_data_read_request, 0 }, { NDMP9_LOG_FILE, xdr_ndmp9_log_file_request, 0 }, { NDMP9_LOG_MESSAGE, xdr_ndmp9_log_message_request, 0 }, { NDMP9_FH_ADD_FILE, xdr_ndmp9_fh_add_file_request, 0 }, { NDMP9_FH_ADD_DIR, xdr_ndmp9_fh_add_dir_request, 0 }, { NDMP9_FH_ADD_NODE, xdr_ndmp9_fh_add_node_request, 0 }, { NDMP9_MOVER_GET_STATE, xdr_ndmp9_mover_get_state_request, xdr_ndmp9_mover_get_state_reply, }, { NDMP9_MOVER_LISTEN, xdr_ndmp9_mover_listen_request, xdr_ndmp9_mover_listen_reply, }, { NDMP9_MOVER_CONTINUE, xdr_ndmp9_mover_continue_request, xdr_ndmp9_mover_continue_reply, }, { NDMP9_MOVER_ABORT, xdr_ndmp9_mover_abort_request, xdr_ndmp9_mover_abort_reply, }, { NDMP9_MOVER_STOP, xdr_ndmp9_mover_stop_request, xdr_ndmp9_mover_stop_reply, }, { NDMP9_MOVER_SET_WINDOW, xdr_ndmp9_mover_set_window_request, xdr_ndmp9_mover_set_window_reply, }, { NDMP9_MOVER_READ, xdr_ndmp9_mover_read_request, xdr_ndmp9_mover_read_reply, }, { NDMP9_MOVER_CLOSE, xdr_ndmp9_mover_close_request, xdr_ndmp9_mover_close_reply, }, { NDMP9_MOVER_SET_RECORD_SIZE, xdr_ndmp9_mover_set_record_size_request, xdr_ndmp9_mover_set_record_size_reply, }, { NDMP9_MOVER_CONNECT, xdr_ndmp9_mover_connect_request, xdr_ndmp9_mover_connect_reply, }, {0} }; /* * XDR unsigned long integers * same as xdr_long - open coded to save a proc call! */ bool_t xdr_ndmp9_u_quad(xdrs, objp) register XDR *xdrs; ndmp9_u_quad *objp; { uint32_t hi, lo; switch (xdrs->x_op) { case XDR_DECODE: #if defined(_LP64) if (XDR_GETINT32(xdrs, (int32_t *)&hi) && XDR_GETINT32(xdrs, (int32_t *)&lo)) { #else if (XDR_GETLONG(xdrs, (long *)&hi) && XDR_GETLONG(xdrs, (long *)&lo)) { #endif *objp = ((uint64_t)hi << 32) | (lo & 0xffffffff); return TRUE; } break; case XDR_ENCODE: hi = *objp >> 32; lo = *objp & 0xffffffff; #if defined(_LP64) return XDR_PUTINT32(xdrs, (int32_t *)&hi) && XDR_PUTINT32(xdrs, (int32_t *)&lo); #else return XDR_PUTLONG(xdrs, (long *)&hi) && XDR_PUTLONG(xdrs, (long *)&lo); #endif case XDR_FREE: return (TRUE); } return (FALSE); } bool_t xdr_ndmp9_no_arguments(xdrs, objp) register XDR *xdrs; ndmp9_u_quad *objp; { return TRUE; } bareos-Release-14.2.6/src/ndmp/ndmp_ammend.h000066400000000000000000000052551263011562700206240ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ /* * All invalid values are all 1s */ #define NDMP_INVALID_U_SHORT (0xFFFFu) #define NDMP_INVALID_U_LONG (0xFFFFFFFFul) #define NDMP_INVALID_U_QUAD (0xFFFFFFFFFFFFFFFFull) #define NDMP_INVALID_GENERAL (-1) #define NDMP_LENGTH_INFINITY (~0ULL) #define NDMP_TAPE_INVALID_FILE_NUM NDMP_INVALID_U_LONG #define NDMP_TAPE_INVALID_SOFT_ERRORS NDMP_INVALID_U_LONG #define NDMP_TAPE_INVALID_BLOCK_SIZE NDMP_INVALID_U_LONG #define NDMP_TAPE_INVALID_BLOCKNO NDMP_INVALID_U_LONG #define NDMP_TAPE_INVALID_TOTAL_SPACE NDMP_INVALID_U_QUAD #define NDMP_TAPE_INVALID_SPACE_REMAIN NDMP_INVALID_U_QUAD #define NDMP_TAPE_INVALID_PARTITION NDMP_INVALID_U_LONG #define NDMP_DATA_INVALID_EST_BYTES_REMAIN NDMP_INVALID_U_QUAD #define NDMP_DATA_INVALID_EST_TIME_REMAIN NDMP_INVALID_U_QUAD #define NDMP_FILE_STAT_INVALID_MTIME NDMP_INVALID_U_LONG #define NDMP_FILE_STAT_INVALID_ATIME NDMP_INVALID_U_LONG #define NDMP_FILE_STAT_INVALID_CTIME NDMP_INVALID_U_LONG #define NDMP_FILE_STAT_INVALID_UID NDMP_INVALID_U_LONG #define NDMP_FILE_STAT_INVALID_GID NDMP_INVALID_U_LONG #define NDMP_FILE_STAT_INVALID_LINKS NDMP_INVALID_U_LONG #define NDMP_FILE_STAT_INVALID_NODE NDMP_INVALID_U_QUAD #define NDMP_FILE_STAT_INVALID_SIZE 0 #define NDMP_FH_INVALID_FH_INFO NDMP_INVALID_U_QUAD bareos-Release-14.2.6/src/ndmp/ndmp_msg_buf.h000066400000000000000000001045321263011562700210030ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifdef __cplusplus extern "C" { #endif #define NDMNMB_FLAG_NO_FREE 1 #define NDMNMB_FLAG_NO_SEND 2 /* * Most replies are regular in that 'error' is the * first field. This affords certain efficiencies * and conveniences in the implementation. * NDMPv3 introduced replies that broke this regularity. * This is used to work around such replies * in areas that otherwise take advantage * of the convenient regularity. */ struct ndmp3_unfortunate_error { uint32_t invalid_probably; ndmp9_error error; }; /* * NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(vers,msg) */ #ifdef NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 #define NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(vers,msg) 0 #else /* NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 */ #ifndef NDMOS_OPTION_NO_NDMP3 #define NDMNMB_IS_UNFORTUNATE_REPLY_TYPE_V3(vers,msg) \ ((vers) == NDMP3VER \ && ((msg) == NDMP3_TAPE_GET_STATE \ || (msg) == NDMP3_DATA_GET_STATE)) #else /* !NDMOS_OPTION_NO_NDMP3 */ #define NDMNMB_IS_UNFORTUNATE_REPLY_TYPE_V3(vers,msg) 0 #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 #define NDMNMB_IS_UNFORTUNATE_REPLY_TYPE_V4(vers,msg) \ ((vers) == NDMP4VER \ && ((msg) == NDMP4_TAPE_GET_STATE \ || (msg) == NDMP4_DATA_GET_STATE)) #else /* !NDMOS_OPTION_NO_NDMP4 */ #define NDMNMB_IS_UNFORTUNATE_REPLY_TYPE_V4(vers,msg) 0 #endif /* !NDMOS_OPTION_NO_NDMP4 */ #define NDMNMB_IS_UNFORTUNATE_REPLY_TYPE(vers,msg) \ (NDMNMB_IS_UNFORTUNATE_REPLY_TYPE_V3(vers,msg) \ || NDMNMB_IS_UNFORTUNATE_REPLY_TYPE_V4(vers,msg)) #endif /* NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4 */ /* 92 bytes, checked 970930 */ struct ndmp_msg_buf { ndmp0_header header; unsigned char protocol_version; unsigned char flags; unsigned char _pad[2]; union { ndmp0_connect_open_request ndmp0_connect_open_request_body; ndmp0_connect_open_reply ndmp0_connect_open_reply_body; ndmp0_notify_connected_request ndmp0_notify_connected_request_body; #ifndef NDMOS_OPTION_NO_NDMP2 ndmp2_error ndmp2_error_reply; ndmp2_connect_open_request ndmp2_connect_open_request_body; ndmp2_connect_open_reply ndmp2_connect_open_reply_body; ndmp2_connect_client_auth_request ndmp2_connect_client_auth_request_body; ndmp2_connect_client_auth_reply ndmp2_connect_client_auth_reply_body; ndmp2_connect_server_auth_request ndmp2_connect_server_auth_request_body; ndmp2_connect_server_auth_reply ndmp2_connect_server_auth_reply_body; ndmp2_config_get_host_info_reply ndmp2_config_get_host_info_reply_body; ndmp2_config_get_butype_attr_request ndmp2_config_get_butype_attr_request_body; ndmp2_config_get_butype_attr_reply ndmp2_config_get_butype_attr_reply_body; ndmp2_config_get_mover_type_reply ndmp2_config_get_mover_type_reply_body; ndmp2_config_get_auth_attr_request ndmp2_config_get_auth_attr_request_body; ndmp2_config_get_auth_attr_reply ndmp2_config_get_auth_attr_reply_body; ndmp2_scsi_open_request ndmp2_scsi_open_request_body; ndmp2_scsi_open_reply ndmp2_scsi_open_reply_body; ndmp2_scsi_close_reply ndmp2_scsi_close_reply_body; ndmp2_scsi_get_state_reply ndmp2_scsi_get_state_reply_body; ndmp2_scsi_set_target_request ndmp2_scsi_set_target_request_body; ndmp2_scsi_set_target_reply ndmp2_scsi_set_target_reply_body; ndmp2_scsi_reset_device_reply ndmp2_scsi_reset_device_reply_body; ndmp2_scsi_reset_bus_reply ndmp2_scsi_reset_bus_reply_body; ndmp2_scsi_execute_cdb_request ndmp2_scsi_execute_cdb_request_body; ndmp2_scsi_execute_cdb_reply ndmp2_scsi_execute_cdb_reply_body; ndmp2_tape_open_request ndmp2_tape_open_request_body; ndmp2_tape_open_reply ndmp2_tape_open_reply_body; ndmp2_tape_close_reply ndmp2_tape_close_reply_body; ndmp2_tape_get_state_reply ndmp2_tape_get_state_reply_body; ndmp2_tape_mtio_request ndmp2_tape_mtio_request_body; ndmp2_tape_mtio_reply ndmp2_tape_mtio_reply_body; ndmp2_tape_write_request ndmp2_tape_write_request_body; ndmp2_tape_write_reply ndmp2_tape_write_reply_body; ndmp2_tape_read_request ndmp2_tape_read_request_body; ndmp2_tape_read_reply ndmp2_tape_read_reply_body; ndmp2_tape_execute_cdb_request ndmp2_tape_execute_cdb_request_body; ndmp2_tape_execute_cdb_reply ndmp2_tape_execute_cdb_reply_body; ndmp2_data_get_state_reply ndmp2_data_get_state_reply_body; ndmp2_data_start_backup_request ndmp2_data_start_backup_request_body; ndmp2_data_start_backup_reply ndmp2_data_start_backup_reply_body; ndmp2_data_start_recover_request ndmp2_data_start_recover_request_body; ndmp2_data_start_recover_reply ndmp2_data_start_recover_reply_body; ndmp2_data_abort_reply ndmp2_data_abort_reply_body; ndmp2_data_get_env_reply ndmp2_data_get_env_reply_body; ndmp2_data_stop_reply ndmp2_data_stop_reply_body; ndmp2_data_start_recover_filehist_request ndmp2_data_start_recover_filehist_request_body; ndmp2_data_start_recover_filehist_reply ndmp2_data_start_recover_filehist_reply_body; ndmp2_notify_data_halted_request ndmp2_notify_data_halted_request_body; ndmp2_notify_connected_request ndmp2_notify_connected_request_body; ndmp2_notify_mover_halted_request ndmp2_notify_mover_halted_request_body; ndmp2_notify_mover_paused_request ndmp2_notify_mover_paused_request_body; ndmp2_notify_data_read_request ndmp2_notify_data_read_request_body; ndmp2_log_log_request ndmp2_log_log_request_body; ndmp2_log_debug_request ndmp2_log_debug_request_body; ndmp2_log_file_request ndmp2_log_file_request_body; ndmp2_fh_add_unix_path_request ndmp2_fh_add_unix_path_request_body; ndmp2_fh_add_unix_dir_request ndmp2_fh_add_unix_dir_request_body; ndmp2_fh_add_unix_node_request ndmp2_fh_add_unix_node_request_body; ndmp2_mover_get_state_reply ndmp2_mover_get_state_reply_body; ndmp2_mover_listen_request ndmp2_mover_listen_request_body; ndmp2_mover_listen_reply ndmp2_mover_listen_reply_body; ndmp2_mover_continue_reply ndmp2_mover_continue_reply_body; ndmp2_mover_abort_reply ndmp2_mover_abort_reply_body; ndmp2_mover_stop_reply ndmp2_mover_stop_reply_body; ndmp2_mover_set_window_request ndmp2_mover_set_window_request_body; ndmp2_mover_set_window_reply ndmp2_mover_set_window_reply_body; ndmp2_mover_read_request ndmp2_mover_read_request_body; ndmp2_mover_read_reply ndmp2_mover_read_reply_body; ndmp2_mover_close_reply ndmp2_mover_close_reply_body; ndmp2_mover_set_record_size_request ndmp2_mover_set_record_size_request_body; ndmp2_mover_set_record_size_reply ndmp2_mover_set_record_size_reply_body; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 ndmp3_error ndmp3_error_reply; ndmp3_connect_open_request ndmp3_connect_open_request_body; ndmp3_connect_open_reply ndmp3_connect_open_reply_body; ndmp3_connect_client_auth_request ndmp3_connect_client_auth_request_body; ndmp3_connect_client_auth_reply ndmp3_connect_client_auth_reply_body; ndmp3_connect_server_auth_request ndmp3_connect_server_auth_request_body; ndmp3_connect_server_auth_reply ndmp3_connect_server_auth_reply_body; ndmp3_config_get_host_info_reply ndmp3_config_get_host_info_reply_body; ndmp3_config_get_connection_type_reply ndmp3_config_get_connection_type_reply_body; ndmp3_config_get_auth_attr_request ndmp3_config_get_auth_attr_request_body; ndmp3_config_get_auth_attr_reply ndmp3_config_get_auth_attr_reply_body; ndmp3_config_get_butype_info_reply ndmp3_config_get_butype_info_reply_body; ndmp3_config_get_fs_info_reply ndmp3_config_get_fs_info_reply_body; ndmp3_config_get_tape_info_reply ndmp3_config_get_tape_info_reply_body; ndmp3_config_get_scsi_info_reply ndmp3_config_get_scsi_info_reply_body; ndmp3_config_get_server_info_reply ndmp3_config_get_server_info_reply_body; ndmp3_scsi_open_request ndmp3_scsi_open_request_body; ndmp3_scsi_open_reply ndmp3_scsi_open_reply_body; ndmp3_scsi_close_reply ndmp3_scsi_close_reply_body; ndmp3_scsi_get_state_reply ndmp3_scsi_get_state_reply_body; ndmp3_scsi_set_target_request ndmp3_scsi_set_target_request_body; ndmp3_scsi_set_target_reply ndmp3_scsi_set_target_reply_body; ndmp3_scsi_reset_device_reply ndmp3_scsi_reset_device_reply_body; ndmp3_scsi_reset_bus_reply ndmp3_scsi_reset_bus_reply_body; ndmp3_scsi_execute_cdb_request ndmp3_scsi_execute_cdb_request_body; ndmp3_scsi_execute_cdb_reply ndmp3_scsi_execute_cdb_reply_body; ndmp3_tape_open_request ndmp3_tape_open_request_body; ndmp3_tape_open_reply ndmp3_tape_open_reply_body; ndmp3_tape_close_reply ndmp3_tape_close_reply_body; ndmp3_tape_get_state_reply ndmp3_tape_get_state_reply_body; ndmp3_tape_mtio_request ndmp3_tape_mtio_request_body; ndmp3_tape_mtio_reply ndmp3_tape_mtio_reply_body; ndmp3_tape_write_request ndmp3_tape_write_request_body; ndmp3_tape_write_reply ndmp3_tape_write_reply_body; ndmp3_tape_read_request ndmp3_tape_read_request_body; ndmp3_tape_read_reply ndmp3_tape_read_reply_body; ndmp3_tape_execute_cdb_request ndmp3_tape_execute_cdb_request_body; ndmp3_tape_execute_cdb_reply ndmp3_tape_execute_cdb_reply_body; ndmp3_data_get_state_reply ndmp3_data_get_state_reply_body; ndmp3_data_start_backup_request ndmp3_data_start_backup_request_body; ndmp3_data_start_backup_reply ndmp3_data_start_backup_reply_body; ndmp3_data_start_recover_request ndmp3_data_start_recover_request_body; ndmp3_data_start_recover_reply ndmp3_data_start_recover_reply_body; ndmp3_data_abort_reply ndmp3_data_abort_reply_body; ndmp3_data_get_env_reply ndmp3_data_get_env_reply_body; ndmp3_data_stop_reply ndmp3_data_stop_reply_body; ndmp3_data_start_recover_filehist_request ndmp3_data_start_recover_filehist_request_body; ndmp3_data_start_recover_filehist_reply ndmp3_data_start_recover_filehist_reply_body; ndmp3_data_listen_request ndmp3_data_listen_request_body; ndmp3_data_listen_reply ndmp3_data_listen_reply_body; ndmp3_data_connect_request ndmp3_data_connect_request_body; ndmp3_data_connect_reply ndmp3_data_connect_reply_body; ndmp3_notify_data_halted_request ndmp3_notify_data_halted_request_body; ndmp3_notify_connected_request ndmp3_notify_connected_request_body; ndmp3_notify_mover_halted_request ndmp3_notify_mover_halted_request_body; ndmp3_notify_mover_paused_request ndmp3_notify_mover_paused_request_body; ndmp3_notify_data_read_request ndmp3_notify_data_read_request_body; ndmp3_log_file_request ndmp3_log_file_request_body; ndmp3_log_message_request ndmp3_log_message_request_body; ndmp3_fh_add_file_request ndmp3_fh_add_file_request_body; ndmp3_fh_add_dir_request ndmp3_fh_add_dir_request_body; ndmp3_fh_add_node_request ndmp3_fh_add_node_request_body; ndmp3_mover_get_state_reply ndmp3_mover_get_state_reply_body; ndmp3_mover_listen_request ndmp3_mover_listen_request_body; ndmp3_mover_listen_reply ndmp3_mover_listen_reply_body; ndmp3_mover_continue_reply ndmp3_mover_continue_reply_body; ndmp3_mover_abort_reply ndmp3_mover_abort_reply_body; ndmp3_mover_stop_reply ndmp3_mover_stop_reply_body; ndmp3_mover_set_window_request ndmp3_mover_set_window_request_body; ndmp3_mover_set_window_reply ndmp3_mover_set_window_reply_body; ndmp3_mover_read_request ndmp3_mover_read_request_body; ndmp3_mover_read_reply ndmp3_mover_read_reply_body; ndmp3_mover_close_reply ndmp3_mover_close_reply_body; ndmp3_mover_set_record_size_request ndmp3_mover_set_record_size_request_body; ndmp3_mover_set_record_size_reply ndmp3_mover_set_record_size_reply_body; ndmp3_mover_connect_request ndmp3_mover_connect_request_body; ndmp3_mover_connect_reply ndmp3_mover_connect_reply_body; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 ndmp4_error ndmp4_error_reply; ndmp4_connect_open_request ndmp4_connect_open_request_body; ndmp4_connect_open_reply ndmp4_connect_open_reply_body; ndmp4_connect_client_auth_request ndmp4_connect_client_auth_request_body; ndmp4_connect_client_auth_reply ndmp4_connect_client_auth_reply_body; ndmp4_connect_server_auth_request ndmp4_connect_server_auth_request_body; ndmp4_connect_server_auth_reply ndmp4_connect_server_auth_reply_body; ndmp4_config_get_host_info_reply ndmp4_config_get_host_info_reply_body; ndmp4_config_get_connection_type_reply ndmp4_config_get_connection_type_reply_body; ndmp4_config_get_auth_attr_request ndmp4_config_get_auth_attr_request_body; ndmp4_config_get_auth_attr_reply ndmp4_config_get_auth_attr_reply_body; ndmp4_config_get_butype_info_reply ndmp4_config_get_butype_info_reply_body; ndmp4_config_get_fs_info_reply ndmp4_config_get_fs_info_reply_body; ndmp4_config_get_tape_info_reply ndmp4_config_get_tape_info_reply_body; ndmp4_config_get_scsi_info_reply ndmp4_config_get_scsi_info_reply_body; ndmp4_config_get_server_info_reply ndmp4_config_get_server_info_reply_body; ndmp4_scsi_open_request ndmp4_scsi_open_request_body; ndmp4_scsi_open_reply ndmp4_scsi_open_reply_body; ndmp4_scsi_close_reply ndmp4_scsi_close_reply_body; ndmp4_scsi_get_state_reply ndmp4_scsi_get_state_reply_body; ndmp4_scsi_reset_device_reply ndmp4_scsi_reset_device_reply_body; ndmp4_scsi_execute_cdb_request ndmp4_scsi_execute_cdb_request_body; ndmp4_scsi_execute_cdb_reply ndmp4_scsi_execute_cdb_reply_body; ndmp4_tape_open_request ndmp4_tape_open_request_body; ndmp4_tape_open_reply ndmp4_tape_open_reply_body; ndmp4_tape_close_reply ndmp4_tape_close_reply_body; ndmp4_tape_get_state_reply ndmp4_tape_get_state_reply_body; ndmp4_tape_mtio_request ndmp4_tape_mtio_request_body; ndmp4_tape_mtio_reply ndmp4_tape_mtio_reply_body; ndmp4_tape_write_request ndmp4_tape_write_request_body; ndmp4_tape_write_reply ndmp4_tape_write_reply_body; ndmp4_tape_read_request ndmp4_tape_read_request_body; ndmp4_tape_read_reply ndmp4_tape_read_reply_body; ndmp4_tape_execute_cdb_request ndmp4_tape_execute_cdb_request_body; ndmp4_tape_execute_cdb_reply ndmp4_tape_execute_cdb_reply_body; ndmp4_data_get_state_reply ndmp4_data_get_state_reply_body; ndmp4_data_start_backup_request ndmp4_data_start_backup_request_body; ndmp4_data_start_backup_reply ndmp4_data_start_backup_reply_body; ndmp4_data_start_recover_request ndmp4_data_start_recover_request_body; ndmp4_data_start_recover_reply ndmp4_data_start_recover_reply_body; ndmp4_data_abort_reply ndmp4_data_abort_reply_body; ndmp4_data_get_env_reply ndmp4_data_get_env_reply_body; ndmp4_data_stop_reply ndmp4_data_stop_reply_body; ndmp4_data_start_recover_filehist_request ndmp4_data_start_recover_filehist_request_body; ndmp4_data_start_recover_filehist_reply ndmp4_data_start_recover_filehist_reply_body; ndmp4_data_listen_request ndmp4_data_listen_request_body; ndmp4_data_listen_reply ndmp4_data_listen_reply_body; ndmp4_data_connect_request ndmp4_data_connect_request_body; ndmp4_data_connect_reply ndmp4_data_connect_reply_body; ndmp4_notify_data_halted_post ndmp4_notify_data_halted_post_body; ndmp4_notify_connection_status_post ndmp4_notify_connection_status_post_body; ndmp4_notify_mover_halted_post ndmp4_notify_mover_halted_post_body; ndmp4_notify_mover_paused_post ndmp4_notify_mover_paused_post_body; ndmp4_notify_data_read_post ndmp4_notify_data_read_post_body; ndmp4_log_file_post ndmp4_log_file_post_body; ndmp4_log_message_post ndmp4_log_message_post_body; ndmp4_fh_add_file_post ndmp4_fh_add_file_post_body; ndmp4_fh_add_dir_post ndmp4_fh_add_dir_post_body; ndmp4_fh_add_node_post ndmp4_fh_add_node_post_body; ndmp4_mover_get_state_reply ndmp4_mover_get_state_reply_body; ndmp4_mover_listen_request ndmp4_mover_listen_request_body; ndmp4_mover_listen_reply ndmp4_mover_listen_reply_body; ndmp4_mover_continue_reply ndmp4_mover_continue_reply_body; ndmp4_mover_abort_reply ndmp4_mover_abort_reply_body; ndmp4_mover_stop_reply ndmp4_mover_stop_reply_body; ndmp4_mover_set_window_request ndmp4_mover_set_window_request_body; ndmp4_mover_set_window_reply ndmp4_mover_set_window_reply_body; ndmp4_mover_read_request ndmp4_mover_read_request_body; ndmp4_mover_read_reply ndmp4_mover_read_reply_body; ndmp4_mover_close_reply ndmp4_mover_close_reply_body; ndmp4_mover_set_record_size_request ndmp4_mover_set_record_size_request_body; ndmp4_mover_set_record_size_reply ndmp4_mover_set_record_size_reply_body; ndmp4_mover_connect_request ndmp4_mover_connect_request_body; ndmp4_mover_connect_reply ndmp4_mover_connect_reply_body; #endif /* !NDMOS_OPTION_NO_NDMP4 */ ndmp0_error error; struct ndmp3_unfortunate_error unf3_error; ndmp9_error ndmp9_error_reply; ndmp9_connect_open_request ndmp9_connect_open_request_body; ndmp9_connect_open_reply ndmp9_connect_open_reply_body; ndmp9_connect_client_auth_request ndmp9_connect_client_auth_request_body; ndmp9_connect_client_auth_reply ndmp9_connect_client_auth_reply_body; ndmp9_connect_server_auth_request ndmp9_connect_server_auth_request_body; ndmp9_connect_server_auth_reply ndmp9_connect_server_auth_reply_body; ndmp9_config_get_host_info_reply ndmp9_config_get_host_info_reply_body; ndmp9_config_get_server_info_reply ndmp9_config_get_server_info_reply_body; ndmp9_config_get_butype_info_reply ndmp9_config_get_butype_info_reply_body; ndmp9_config_get_fs_info_reply ndmp9_config_get_fs_info_reply_body; ndmp9_config_get_tape_info_reply ndmp9_config_get_tape_info_reply_body; ndmp9_config_get_scsi_info_reply ndmp9_config_get_scsi_info_reply_body; ndmp9_config_get_info_reply ndmp9_config_get_info_reply_body; ndmp9_config_get_auth_attr_request ndmp9_config_get_auth_attr_request_body; ndmp9_config_get_auth_attr_reply ndmp9_config_get_auth_attr_reply_body; ndmp9_scsi_open_request ndmp9_scsi_open_request_body; ndmp9_scsi_open_reply ndmp9_scsi_open_reply_body; ndmp9_scsi_close_reply ndmp9_scsi_close_reply_body; ndmp9_scsi_get_state_reply ndmp9_scsi_get_state_reply_body; ndmp9_scsi_set_target_request ndmp9_scsi_set_target_request_body; ndmp9_scsi_set_target_reply ndmp9_scsi_set_target_reply_body; ndmp9_scsi_reset_device_reply ndmp9_scsi_reset_device_reply_body; ndmp9_scsi_reset_bus_reply ndmp9_scsi_reset_bus_reply_body; ndmp9_scsi_execute_cdb_request ndmp9_scsi_execute_cdb_request_body; ndmp9_scsi_execute_cdb_reply ndmp9_scsi_execute_cdb_reply_body; ndmp9_tape_open_request ndmp9_tape_open_request_body; ndmp9_tape_open_reply ndmp9_tape_open_reply_body; ndmp9_tape_close_reply ndmp9_tape_close_reply_body; ndmp9_tape_get_state_reply ndmp9_tape_get_state_reply_body; ndmp9_tape_mtio_request ndmp9_tape_mtio_request_body; ndmp9_tape_mtio_reply ndmp9_tape_mtio_reply_body; ndmp9_tape_write_request ndmp9_tape_write_request_body; ndmp9_tape_write_reply ndmp9_tape_write_reply_body; ndmp9_tape_read_request ndmp9_tape_read_request_body; ndmp9_tape_read_reply ndmp9_tape_read_reply_body; ndmp9_tape_execute_cdb_request ndmp9_tape_execute_cdb_request_body; ndmp9_tape_execute_cdb_reply ndmp9_tape_execute_cdb_reply_body; ndmp9_data_get_state_reply ndmp9_data_get_state_reply_body; ndmp9_data_start_backup_request ndmp9_data_start_backup_request_body; ndmp9_data_start_backup_reply ndmp9_data_start_backup_reply_body; ndmp9_data_start_recover_request ndmp9_data_start_recover_request_body; ndmp9_data_start_recover_reply ndmp9_data_start_recover_reply_body; ndmp9_data_abort_reply ndmp9_data_abort_reply_body; ndmp9_data_get_env_reply ndmp9_data_get_env_reply_body; ndmp9_data_stop_reply ndmp9_data_stop_reply_body; ndmp9_data_start_recover_filehist_request ndmp9_data_start_recover_filehist_request_body; ndmp9_data_start_recover_filehist_reply ndmp9_data_start_recover_filehist_reply_body; ndmp9_data_listen_request ndmp9_data_listen_request_body; ndmp9_data_listen_reply ndmp9_data_listen_reply_body; ndmp9_data_connect_request ndmp9_data_connect_request_body; ndmp9_data_connect_reply ndmp9_data_connect_reply_body; ndmp9_notify_data_halted_request ndmp9_notify_data_halted_request_body; ndmp9_notify_connected_request ndmp9_notify_connected_request_body; ndmp9_notify_mover_halted_request ndmp9_notify_mover_halted_request_body; ndmp9_notify_mover_paused_request ndmp9_notify_mover_paused_request_body; ndmp9_notify_data_read_request ndmp9_notify_data_read_request_body; ndmp9_log_file_request ndmp9_log_file_request_body; ndmp9_log_message_request ndmp9_log_message_request_body; ndmp9_fh_add_file_request ndmp9_fh_add_file_request_body; ndmp9_fh_add_dir_request ndmp9_fh_add_dir_request_body; ndmp9_fh_add_node_request ndmp9_fh_add_node_request_body; ndmp9_mover_get_state_reply ndmp9_mover_get_state_reply_body; ndmp9_mover_listen_request ndmp9_mover_listen_request_body; ndmp9_mover_listen_reply ndmp9_mover_listen_reply_body; ndmp9_mover_continue_reply ndmp9_mover_continue_reply_body; ndmp9_mover_abort_reply ndmp9_mover_abort_reply_body; ndmp9_mover_stop_reply ndmp9_mover_stop_reply_body; ndmp9_mover_set_window_request ndmp9_mover_set_window_request_body; ndmp9_mover_set_window_reply ndmp9_mover_set_window_reply_body; ndmp9_mover_read_request ndmp9_mover_read_request_body; ndmp9_mover_read_reply ndmp9_mover_read_reply_body; ndmp9_mover_close_reply ndmp9_mover_close_reply_body; ndmp9_mover_set_record_size_request ndmp9_mover_set_record_size_request_body; ndmp9_mover_set_record_size_reply ndmp9_mover_set_record_size_reply_body; ndmp9_mover_connect_request ndmp9_mover_connect_request_body; ndmp9_mover_connect_reply ndmp9_mover_connect_reply_body; } body; }; struct ndmp_xa_buf { struct ndmp_msg_buf request; struct ndmp_msg_buf reply; }; #define MT_ndmp0_connect_open NDMP0_CONNECT_OPEN #define MT_ndmp0_connect_close NDMP0_CONNECT_CLOSE #define MT_ndmp0_notify_connected NDMP0_NOTIFY_CONNECTED #ifndef NDMOS_OPTION_NO_NDMP2 #define MT_ndmp2_connect_open NDMP2_CONNECT_OPEN #define MT_ndmp2_connect_client_auth NDMP2_CONNECT_CLIENT_AUTH #define MT_ndmp2_connect_close NDMP2_CONNECT_CLOSE #define MT_ndmp2_connect_server_auth NDMP2_CONNECT_SERVER_AUTH #define MT_ndmp2_config_get_host_info NDMP2_CONFIG_GET_HOST_INFO #define MT_ndmp2_config_get_butype_attr NDMP2_CONFIG_GET_BUTYPE_ATTR #define MT_ndmp2_config_get_mover_type NDMP2_CONFIG_GET_MOVER_TYPE #define MT_ndmp2_config_get_auth_attr NDMP2_CONFIG_GET_AUTH_ATTR #define MT_ndmp2_scsi_open NDMP2_SCSI_OPEN #define MT_ndmp2_scsi_close NDMP2_SCSI_CLOSE #define MT_ndmp2_scsi_get_state NDMP2_SCSI_GET_STATE #define MT_ndmp2_scsi_set_target NDMP2_SCSI_SET_TARGET #define MT_ndmp2_scsi_reset_device NDMP2_SCSI_RESET_DEVICE #define MT_ndmp2_scsi_reset_bus NDMP2_SCSI_RESET_BUS #define MT_ndmp2_scsi_execute_cdb NDMP2_SCSI_EXECUTE_CDB #define MT_ndmp2_tape_open NDMP2_TAPE_OPEN #define MT_ndmp2_tape_close NDMP2_TAPE_CLOSE #define MT_ndmp2_tape_get_state NDMP2_TAPE_GET_STATE #define MT_ndmp2_tape_mtio NDMP2_TAPE_MTIO #define MT_ndmp2_tape_write NDMP2_TAPE_WRITE #define MT_ndmp2_tape_read NDMP2_TAPE_READ #define MT_ndmp2_tape_execute_cdb NDMP2_TAPE_EXECUTE_CDB #define MT_ndmp2_data_get_state NDMP2_DATA_GET_STATE #define MT_ndmp2_data_start_backup NDMP2_DATA_START_BACKUP #define MT_ndmp2_data_start_recover NDMP2_DATA_START_RECOVER #define MT_ndmp2_data_abort NDMP2_DATA_ABORT #define MT_ndmp2_data_get_env NDMP2_DATA_GET_ENV #define MT_ndmp2_data_stop NDMP2_DATA_STOP #define MT_ndmp2_data_start_recover_filehist NDMP2_DATA_START_RECOVER_FILEHIST #define MT_ndmp2_notify_data_halted NDMP2_NOTIFY_DATA_HALTED #define MT_ndmp2_notify_connected NDMP2_NOTIFY_CONNECTED #define MT_ndmp2_notify_mover_halted NDMP2_NOTIFY_MOVER_HALTED #define MT_ndmp2_notify_mover_paused NDMP2_NOTIFY_MOVER_PAUSED #define MT_ndmp2_notify_data_read NDMP2_NOTIFY_DATA_READ #define MT_ndmp2_log_log NDMP2_LOG_LOG #define MT_ndmp2_log_debug NDMP2_LOG_DEBUG #define MT_ndmp2_log_file NDMP2_LOG_FILE #define MT_ndmp2_fh_add_unix_path NDMP2_FH_ADD_UNIX_PATH #define MT_ndmp2_fh_add_unix_dir NDMP2_FH_ADD_UNIX_DIR #define MT_ndmp2_fh_add_unix_node NDMP2_FH_ADD_UNIX_NODE #define MT_ndmp2_mover_get_state NDMP2_MOVER_GET_STATE #define MT_ndmp2_mover_listen NDMP2_MOVER_LISTEN #define MT_ndmp2_mover_continue NDMP2_MOVER_CONTINUE #define MT_ndmp2_mover_abort NDMP2_MOVER_ABORT #define MT_ndmp2_mover_stop NDMP2_MOVER_STOP #define MT_ndmp2_mover_set_window NDMP2_MOVER_SET_WINDOW #define MT_ndmp2_mover_read NDMP2_MOVER_READ #define MT_ndmp2_mover_close NDMP2_MOVER_CLOSE #define MT_ndmp2_mover_set_record_size NDMP2_MOVER_SET_RECORD_SIZE #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 #define MT_ndmp3_connect_open NDMP3_CONNECT_OPEN #define MT_ndmp3_connect_client_auth NDMP3_CONNECT_CLIENT_AUTH #define MT_ndmp3_connect_close NDMP3_CONNECT_CLOSE #define MT_ndmp3_connect_server_auth NDMP3_CONNECT_SERVER_AUTH #define MT_ndmp3_config_get_host_info NDMP3_CONFIG_GET_HOST_INFO #define MT_ndmp3_config_get_connection_type NDMP3_CONFIG_GET_CONNECTION_TYPE #define MT_ndmp3_config_get_auth_attr NDMP3_CONFIG_GET_AUTH_ATTR #define MT_ndmp3_config_get_butype_info NDMP3_CONFIG_GET_BUTYPE_INFO #define MT_ndmp3_config_get_fs_info NDMP3_CONFIG_GET_FS_INFO #define MT_ndmp3_config_get_tape_info NDMP3_CONFIG_GET_TAPE_INFO #define MT_ndmp3_config_get_scsi_info NDMP3_CONFIG_GET_SCSI_INFO #define MT_ndmp3_config_get_server_info NDMP3_CONFIG_GET_SERVER_INFO #define MT_ndmp3_scsi_open NDMP3_SCSI_OPEN #define MT_ndmp3_scsi_close NDMP3_SCSI_CLOSE #define MT_ndmp3_scsi_get_state NDMP3_SCSI_GET_STATE #define MT_ndmp3_scsi_set_target NDMP3_SCSI_SET_TARGET #define MT_ndmp3_scsi_reset_device NDMP3_SCSI_RESET_DEVICE #define MT_ndmp3_scsi_reset_bus NDMP3_SCSI_RESET_BUS #define MT_ndmp3_scsi_execute_cdb NDMP3_SCSI_EXECUTE_CDB #define MT_ndmp3_tape_open NDMP3_TAPE_OPEN #define MT_ndmp3_tape_close NDMP3_TAPE_CLOSE #define MT_ndmp3_tape_get_state NDMP3_TAPE_GET_STATE #define MT_ndmp3_tape_mtio NDMP3_TAPE_MTIO #define MT_ndmp3_tape_write NDMP3_TAPE_WRITE #define MT_ndmp3_tape_read NDMP3_TAPE_READ #define MT_ndmp3_tape_execute_cdb NDMP3_TAPE_EXECUTE_CDB #define MT_ndmp3_data_get_state NDMP3_DATA_GET_STATE #define MT_ndmp3_data_start_backup NDMP3_DATA_START_BACKUP #define MT_ndmp3_data_start_recover NDMP3_DATA_START_RECOVER #define MT_ndmp3_data_start_recover_filehist NDMP3_DATA_START_RECOVER_FILEHIST #define MT_ndmp3_data_abort NDMP3_DATA_ABORT #define MT_ndmp3_data_get_env NDMP3_DATA_GET_ENV #define MT_ndmp3_data_stop NDMP3_DATA_STOP #define MT_ndmp3_data_listen NDMP3_DATA_LISTEN #define MT_ndmp3_data_connect NDMP3_DATA_CONNECT #define MT_ndmp3_notify_data_halted NDMP3_NOTIFY_DATA_HALTED #define MT_ndmp3_notify_connected NDMP3_NOTIFY_CONNECTED #define MT_ndmp3_notify_mover_halted NDMP3_NOTIFY_MOVER_HALTED #define MT_ndmp3_notify_mover_paused NDMP3_NOTIFY_MOVER_PAUSED #define MT_ndmp3_notify_data_read NDMP3_NOTIFY_DATA_READ #define MT_ndmp3_log_file NDMP3_LOG_FILE #define MT_ndmp3_log_message NDMP3_LOG_MESSAGE #define MT_ndmp3_fh_add_file NDMP3_FH_ADD_FILE #define MT_ndmp3_fh_add_dir NDMP3_FH_ADD_DIR #define MT_ndmp3_fh_add_node NDMP3_FH_ADD_NODE #define MT_ndmp3_mover_get_state NDMP3_MOVER_GET_STATE #define MT_ndmp3_mover_listen NDMP3_MOVER_LISTEN #define MT_ndmp3_mover_continue NDMP3_MOVER_CONTINUE #define MT_ndmp3_mover_abort NDMP3_MOVER_ABORT #define MT_ndmp3_mover_stop NDMP3_MOVER_STOP #define MT_ndmp3_mover_set_window NDMP3_MOVER_SET_WINDOW #define MT_ndmp3_mover_read NDMP3_MOVER_READ #define MT_ndmp3_mover_close NDMP3_MOVER_CLOSE #define MT_ndmp3_mover_set_record_size NDMP3_MOVER_SET_RECORD_SIZE #define MT_ndmp3_mover_connect NDMP3_MOVER_CONNECT #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 #define MT_ndmp4_connect_open NDMP4_CONNECT_OPEN #define MT_ndmp4_connect_client_auth NDMP4_CONNECT_CLIENT_AUTH #define MT_ndmp4_connect_close NDMP4_CONNECT_CLOSE #define MT_ndmp4_connect_server_auth NDMP4_CONNECT_SERVER_AUTH #define MT_ndmp4_config_get_host_info NDMP4_CONFIG_GET_HOST_INFO #define MT_ndmp4_config_get_connection_type NDMP4_CONFIG_GET_CONNECTION_TYPE #define MT_ndmp4_config_get_auth_attr NDMP4_CONFIG_GET_AUTH_ATTR #define MT_ndmp4_config_get_butype_info NDMP4_CONFIG_GET_BUTYPE_INFO #define MT_ndmp4_config_get_fs_info NDMP4_CONFIG_GET_FS_INFO #define MT_ndmp4_config_get_tape_info NDMP4_CONFIG_GET_TAPE_INFO #define MT_ndmp4_config_get_scsi_info NDMP4_CONFIG_GET_SCSI_INFO #define MT_ndmp4_config_get_server_info NDMP4_CONFIG_GET_SERVER_INFO #define MT_ndmp4_scsi_open NDMP4_SCSI_OPEN #define MT_ndmp4_scsi_close NDMP4_SCSI_CLOSE #define MT_ndmp4_scsi_get_state NDMP4_SCSI_GET_STATE #define MT_ndmp4_scsi_reset_device NDMP4_SCSI_RESET_DEVICE #define MT_ndmp4_scsi_execute_cdb NDMP4_SCSI_EXECUTE_CDB #define MT_ndmp4_tape_open NDMP4_TAPE_OPEN #define MT_ndmp4_tape_close NDMP4_TAPE_CLOSE #define MT_ndmp4_tape_get_state NDMP4_TAPE_GET_STATE #define MT_ndmp4_tape_mtio NDMP4_TAPE_MTIO #define MT_ndmp4_tape_write NDMP4_TAPE_WRITE #define MT_ndmp4_tape_read NDMP4_TAPE_READ #define MT_ndmp4_tape_execute_cdb NDMP4_TAPE_EXECUTE_CDB #define MT_ndmp4_data_get_state NDMP4_DATA_GET_STATE #define MT_ndmp4_data_start_backup NDMP4_DATA_START_BACKUP #define MT_ndmp4_data_start_recover NDMP4_DATA_START_RECOVER #define MT_ndmp4_data_start_recover_filehist NDMP4_DATA_START_RECOVER_FILEHIST #define MT_ndmp4_data_abort NDMP4_DATA_ABORT #define MT_ndmp4_data_get_env NDMP4_DATA_GET_ENV #define MT_ndmp4_data_stop NDMP4_DATA_STOP #define MT_ndmp4_data_listen NDMP4_DATA_LISTEN #define MT_ndmp4_data_connect NDMP4_DATA_CONNECT #define MT_ndmp4_notify_data_halted NDMP4_NOTIFY_DATA_HALTED #define MT_ndmp4_notify_connection_status NDMP4_NOTIFY_CONNECTION_STATUS #define MT_ndmp4_notify_mover_halted NDMP4_NOTIFY_MOVER_HALTED #define MT_ndmp4_notify_mover_paused NDMP4_NOTIFY_MOVER_PAUSED #define MT_ndmp4_notify_data_read NDMP4_NOTIFY_DATA_READ #define MT_ndmp4_log_file NDMP4_LOG_FILE #define MT_ndmp4_log_message NDMP4_LOG_MESSAGE #define MT_ndmp4_fh_add_file NDMP4_FH_ADD_FILE #define MT_ndmp4_fh_add_dir NDMP4_FH_ADD_DIR #define MT_ndmp4_fh_add_node NDMP4_FH_ADD_NODE #define MT_ndmp4_mover_get_state NDMP4_MOVER_GET_STATE #define MT_ndmp4_mover_listen NDMP4_MOVER_LISTEN #define MT_ndmp4_mover_continue NDMP4_MOVER_CONTINUE #define MT_ndmp4_mover_abort NDMP4_MOVER_ABORT #define MT_ndmp4_mover_stop NDMP4_MOVER_STOP #define MT_ndmp4_mover_set_window NDMP4_MOVER_SET_WINDOW #define MT_ndmp4_mover_read NDMP4_MOVER_READ #define MT_ndmp4_mover_close NDMP4_MOVER_CLOSE #define MT_ndmp4_mover_set_record_size NDMP4_MOVER_SET_RECORD_SIZE #define MT_ndmp4_mover_connect NDMP4_MOVER_CONNECT #endif /* !NDMOS_OPTION_NO_NDMP4 */ #define MT_ndmp9_connect_open NDMP9_CONNECT_OPEN #define MT_ndmp9_connect_client_auth NDMP9_CONNECT_CLIENT_AUTH #define MT_ndmp9_connect_close NDMP9_CONNECT_CLOSE #define MT_ndmp9_connect_server_auth NDMP9_CONNECT_SERVER_AUTH #define MT_ndmp9_config_get_host_info NDMP9_CONFIG_GET_HOST_INFO #define MT_ndmp9_config_get_connection_type NDMP9_CONFIG_GET_CONNECTION_TYPE #define MT_ndmp9_config_get_auth_attr NDMP9_CONFIG_GET_AUTH_ATTR #define MT_ndmp9_config_get_butype_info NDMP9_CONFIG_GET_BUTYPE_INFO #define MT_ndmp9_config_get_fs_info NDMP9_CONFIG_GET_FS_INFO #define MT_ndmp9_config_get_tape_info NDMP9_CONFIG_GET_TAPE_INFO #define MT_ndmp9_config_get_scsi_info NDMP9_CONFIG_GET_SCSI_INFO #define MT_ndmp9_config_get_server_info NDMP9_CONFIG_GET_SERVER_INFO #define MT_ndmp9_scsi_open NDMP9_SCSI_OPEN #define MT_ndmp9_scsi_close NDMP9_SCSI_CLOSE #define MT_ndmp9_scsi_get_state NDMP9_SCSI_GET_STATE #define MT_ndmp9_scsi_set_target NDMP9_SCSI_SET_TARGET #define MT_ndmp9_scsi_reset_device NDMP9_SCSI_RESET_DEVICE #define MT_ndmp9_scsi_reset_bus NDMP9_SCSI_RESET_BUS #define MT_ndmp9_scsi_execute_cdb NDMP9_SCSI_EXECUTE_CDB #define MT_ndmp9_tape_open NDMP9_TAPE_OPEN #define MT_ndmp9_tape_close NDMP9_TAPE_CLOSE #define MT_ndmp9_tape_get_state NDMP9_TAPE_GET_STATE #define MT_ndmp9_tape_mtio NDMP9_TAPE_MTIO #define MT_ndmp9_tape_write NDMP9_TAPE_WRITE #define MT_ndmp9_tape_read NDMP9_TAPE_READ #define MT_ndmp9_tape_execute_cdb NDMP9_TAPE_EXECUTE_CDB #define MT_ndmp9_data_get_state NDMP9_DATA_GET_STATE #define MT_ndmp9_data_start_backup NDMP9_DATA_START_BACKUP #define MT_ndmp9_data_start_recover NDMP9_DATA_START_RECOVER #define MT_ndmp9_data_start_recover_filehist NDMP9_DATA_START_RECOVER_FILEHIST #define MT_ndmp9_data_abort NDMP9_DATA_ABORT #define MT_ndmp9_data_get_env NDMP9_DATA_GET_ENV #define MT_ndmp9_data_stop NDMP9_DATA_STOP #define MT_ndmp9_data_listen NDMP9_DATA_LISTEN #define MT_ndmp9_data_connect NDMP9_DATA_CONNECT #define MT_ndmp9_notify_data_halted NDMP9_NOTIFY_DATA_HALTED #define MT_ndmp9_notify_connected NDMP9_NOTIFY_CONNECTED #define MT_ndmp9_notify_mover_halted NDMP9_NOTIFY_MOVER_HALTED #define MT_ndmp9_notify_mover_paused NDMP9_NOTIFY_MOVER_PAUSED #define MT_ndmp9_notify_data_read NDMP9_NOTIFY_DATA_READ #define MT_ndmp9_log_file NDMP9_LOG_FILE #define MT_ndmp9_log_message NDMP9_LOG_MESSAGE #define MT_ndmp9_fh_add_file NDMP9_FH_ADD_FILE #define MT_ndmp9_fh_add_dir NDMP9_FH_ADD_DIR #define MT_ndmp9_fh_add_node NDMP9_FH_ADD_NODE #define MT_ndmp9_mover_get_state NDMP9_MOVER_GET_STATE #define MT_ndmp9_mover_listen NDMP9_MOVER_LISTEN #define MT_ndmp9_mover_continue NDMP9_MOVER_CONTINUE #define MT_ndmp9_mover_abort NDMP9_MOVER_ABORT #define MT_ndmp9_mover_stop NDMP9_MOVER_STOP #define MT_ndmp9_mover_set_window NDMP9_MOVER_SET_WINDOW #define MT_ndmp9_mover_read NDMP9_MOVER_READ #define MT_ndmp9_mover_close NDMP9_MOVER_CLOSE #define MT_ndmp9_mover_set_record_size NDMP9_MOVER_SET_RECORD_SIZE #define MT_ndmp9_mover_connect NDMP9_MOVER_CONNECT #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/ndmp/ndmp_translate.c000066400000000000000000000117341263011562700213520ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* rpc/rpc.h */ #include "ndmprotocol.h" #include "ndmp_msg_buf.h" #include "ndmp_translate.h" /* * enum_conversion tables **************************************************************** * Used to make enum conversion convenient and dense. * The first row is the default case in both directions, * and is skipped while attempting precise conversion. * The search stops with the first match. */ int /* ndmp9_.... */ convert_enum_to_9 (struct enum_conversion *ectab, int enum_x) { struct enum_conversion * ec = &ectab[1]; for (; !IS_END_ENUM_CONVERSION_TABLE(ec); ec++) { if (ec->enum_x == enum_x) return ec->enum_9; } return ectab[0].enum_9; } int /* ndmpx_.... */ convert_enum_from_9 (struct enum_conversion *ectab, int enum_9) { struct enum_conversion * ec = &ectab[1]; for (; !IS_END_ENUM_CONVERSION_TABLE(ec); ec++) { if (ec->enum_9 == enum_9) return ec->enum_x; } return ectab[0].enum_x; } int convert_valid_u_long_to_9 (uint32_t *valx, ndmp9_valid_u_long *val9) { val9->value = *valx; if (*valx == NDMP_INVALID_U_LONG) val9->valid = NDMP9_VALIDITY_INVALID; else val9->valid = NDMP9_VALIDITY_VALID; return 0; } int convert_valid_u_long_from_9 (uint32_t *valx, ndmp9_valid_u_long *val9) { if (!val9->valid) *valx = NDMP_INVALID_U_LONG; else *valx = val9->value; return 0; } int convert_invalid_u_long_9 (struct ndmp9_valid_u_long *val9) { val9->value = NDMP_INVALID_U_LONG; val9->valid = NDMP9_VALIDITY_INVALID; return 0; } int convert_valid_u_quad_to_9 (ndmp9_u_quad *valx, ndmp9_valid_u_quad *val9) { val9->value = *valx; if (*valx == NDMP_INVALID_U_QUAD) val9->valid = NDMP9_VALIDITY_INVALID; else val9->valid = NDMP9_VALIDITY_VALID; return 0; } int convert_valid_u_quad_from_9 (ndmp9_u_quad *valx, ndmp9_valid_u_quad *val9) { if (!val9->valid) *valx = NDMP_INVALID_U_QUAD; else *valx = val9->value; return 0; } int convert_invalid_u_quad_9 (struct ndmp9_valid_u_quad *val9) { val9->value = NDMP_INVALID_U_QUAD; val9->valid = NDMP9_VALIDITY_INVALID; return 0; } int convert_strdup (char *src, char **dstp) { if (src == 0) { *dstp = 0; return 0; } *dstp = NDMOS_API_STRDUP (src); if (!*dstp) return -1; return 0; } /* * request/reply translation tables **************************************************************** */ struct reqrep_xlate_version_table reqrep_xlate_version_table[] = { #ifndef NDMOS_OPTION_NO_NDMP2 { NDMP2VER, ndmp2_reqrep_xlate_table }, #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 { NDMP3VER, ndmp3_reqrep_xlate_table }, #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 { NDMP4VER, ndmp4_reqrep_xlate_table }, #endif /* !NDMOS_OPTION_NO_NDMP4 */ { 0 } }; struct reqrep_xlate * reqrep_xlate_lookup_version ( struct reqrep_xlate_version_table *rrvt, unsigned protocol_version) { for (; rrvt->protocol_version > 0; rrvt++) { if (rrvt->protocol_version == (int)protocol_version) { return rrvt->reqrep_xlate_table; } } return 0; } struct reqrep_xlate * ndmp_reqrep_by_v9 (struct reqrep_xlate *table, ndmp9_message v9_message) { struct reqrep_xlate * rrx = table; for (; rrx->v9_message; rrx++) if (rrx->v9_message == v9_message) return rrx; return 0; } struct reqrep_xlate * ndmp_reqrep_by_vx (struct reqrep_xlate *table, int vx_message) { struct reqrep_xlate * rrx = table; for (; rrx->v9_message; rrx++) if (rrx->vx_message == vx_message) return rrx; return 0; } int ndmp_xtox_no_arguments (void *vxbody, void *vybody) { return 0; } int ndmp_xtox_no_memused (void *vxbody) { return 0; } bareos-Release-14.2.6/src/ndmp/ndmp_translate.h000066400000000000000000000151161263011562700213550ustar00rootroot00000000000000/* * Copyright (c) 2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifdef __cplusplus extern "C" { #endif /* * conversion macros **************************************************************** * These make things a bit more readable and less error prone. * They also foster consistency. */ /* straight assignments */ #define CNVT_TO_9(PX, P9, MEMBER) ((P9)->MEMBER = (PX)->MEMBER) #define CNVT_FROM_9(PX, P9, MEMBER) ((PX)->MEMBER = (P9)->MEMBER) #define CNVT_TO_9x(PX, P9, MEMBERX, MEMBER9) ((P9)->MEMBER9 = (PX)->MEMBERX) #define CNVT_FROM_9x(PX, P9, MEMBERX, MEMBER9) ((PX)->MEMBERX = (P9)->MEMBER9) /* enum conversion */ #define CNVT_E_TO_9(PX, P9, MEMBER, ENUM_CONVERSION_TABLE) \ ((P9)->MEMBER = convert_enum_to_9 (ENUM_CONVERSION_TABLE, (PX)->MEMBER)) #define CNVT_E_FROM_9(PX, P9, MEMBER, ENUM_CONVERSION_TABLE) \ ((PX)->MEMBER = convert_enum_from_9 (ENUM_CONVERSION_TABLE, (P9)->MEMBER)) #define CNVT_VUL_TO_9(PX, P9, MEMBER) \ convert_valid_u_long_to_9 (&(PX)->MEMBER, &(P9)->MEMBER) #define CNVT_VUL_FROM_9(PX, P9, MEMBER) \ convert_valid_u_long_from_9 (&(PX)->MEMBER, &(P9)->MEMBER) #define CNVT_VUL_TO_9x(PX, P9, MEMBERX, MEMBER9) \ convert_valid_u_long_to_9 (&(PX)->MEMBERX, &(P9)->MEMBER9) #define CNVT_VUL_FROM_9x(PX, P9, MEMBERX, MEMBER9) \ convert_valid_u_long_from_9 (&(PX)->MEMBERX, &(P9)->MEMBER9) #define CNVT_IUL_TO_9(P9, MEMBER) \ convert_invalid_u_long_9 (&(P9)->MEMBER) #define CNVT_VUQ_TO_9(PX, P9, MEMBER) \ convert_valid_u_quad_to_9 (&(PX)->MEMBER, &(P9)->MEMBER) #define CNVT_VUQ_FROM_9(PX, P9, MEMBER) \ convert_valid_u_quad_from_9 (&(PX)->MEMBER, &(P9)->MEMBER) #define CNVT_VUQ_TO_9x(PX, P9, MEMBERX, MEMBER9) \ convert_valid_u_quad_to_9 (&(PX)->MEMBERX, &(P9)->MEMBER9) #define CNVT_VUQ_FROM_9x(PX, P9, MEMBERX, MEMBER9) \ convert_valid_u_quad_from_9 (&(PX)->MEMBERX, &(P9)->MEMBER9) #define CNVT_IUQ_TO_9(P9, MEMBER) \ convert_invalid_u_quad_9 (&(P9)->MEMBER) #define CNVT_STRDUP_TO_9(PX, P9, MEMBER) \ convert_strdup ((PX)->MEMBER, &(P9)->MEMBER) #define CNVT_STRDUP_FROM_9(PX, P9, MEMBER) \ convert_strdup ((P9)->MEMBER, &(PX)->MEMBER) #define CNVT_STRDUP_TO_9x(PX, P9, MEMBERX, MEMBER9) \ convert_strdup ((PX)->MEMBERX, &(P9)->MEMBER9) #define CNVT_STRDUP_FROM_9x(PX, P9, MEMBERX, MEMBER9) \ convert_strdup ((P9)->MEMBER9, &(PX)->MEMBERX) #define CNVT_FREE(PX, MEMBERX) \ { NDMOS_API_FREE((PX)->MEMBERX) ; (PX)->MEMBERX = NULL; }; /* * enum_conversion tables **************************************************************** * Used to make enum conversion convenient and dense. * The first row is the default case in both directions, * and is skipped while attempting precise conversion. * The search stops with the first match. */ struct enum_conversion { int enum_x; int enum_9; }; #define END_ENUM_CONVERSION_TABLE { -1, -1 } #define IS_END_ENUM_CONVERSION_TABLE(EC) \ ((EC)->enum_x == -1 && (EC)->enum_9 == -1) extern int /* ndmp9_.... */ convert_enum_to_9 (struct enum_conversion *ectab, int enum_x); extern int /* ndmpx_.... */ convert_enum_from_9 (struct enum_conversion *ectab, int enum_9); extern int convert_valid_u_long_to_9 (uint32_t *valx, ndmp9_valid_u_long *val9); extern int convert_valid_u_long_from_9 (uint32_t *valx, ndmp9_valid_u_long *val9); extern int convert_invalid_u_long_9 (struct ndmp9_valid_u_long *val9); extern int convert_valid_u_quad_to_9 (ndmp9_u_quad *valx, ndmp9_valid_u_quad *val9); extern int convert_valid_u_quad_from_9 (ndmp9_u_quad *valx, ndmp9_valid_u_quad *val9); extern int convert_invalid_u_quad_9 (struct ndmp9_valid_u_quad *val9); extern int convert_strdup (char *src, char **dstp); /* * request/reply translation tables **************************************************************** */ struct reqrep_xlate { int vx_message; ndmp9_message v9_message; int (*request_xto9) (/* void *vxbody, void *v9body */); int (*request_9tox) (/* void *v9body, void *vxbody */); int (*reply_xto9) (/* void *vxbody, void *v9body */); int (*reply_9tox) (/* void *v9body, void *vxbody */); int (*free_request_xto9) (/* void *v9body */); int (*free_request_9tox) (/* void *vxbody */); int (*free_reply_xto9) (/* void *v9body */); int (*free_reply_9tox) (/* void *vxbody */); }; struct reqrep_xlate_version_table { int protocol_version; struct reqrep_xlate * reqrep_xlate_table; }; extern struct reqrep_xlate_version_table reqrep_xlate_version_table[]; extern struct reqrep_xlate *reqrep_xlate_lookup_version ( struct reqrep_xlate_version_table *rrvt, unsigned protocol_version); extern struct reqrep_xlate *ndmp_reqrep_by_v9 (struct reqrep_xlate *table, ndmp9_message v9_message); extern struct reqrep_xlate *ndmp_reqrep_by_vx (struct reqrep_xlate *table, int vx_message); extern int ndmp_xtox_no_arguments (void *vxbody, void *vybody); extern int ndmp_xtox_no_memused (void *vxbody); /* * PROTOCOL VERSIONS **************************************************************** * */ #ifndef NDMOS_OPTION_NO_NDMP2 #include "ndmp2_translate.h" #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 #include "ndmp3_translate.h" #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 #include "ndmp4_translate.h" #endif /* !NDMOS_OPTION_NO_NDMP4 */ #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/ndmp/ndmprotocol.c000066400000000000000000000146071263011562700207010ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * Miscellaneous C functions to support protocol versions. * See ndmprotocol.h for explanation. */ #include "ndmos.h" #include "ndmprotocol.h" /* * XDR MESSAGE TABLES **************************************************************** */ struct ndmp_xdr_message_table * ndmp_xmt_lookup (int protocol_version, int msg) { struct ndmp_xdr_message_table * table; struct ndmp_xdr_message_table * ent; switch (protocol_version) { case 0: table = ndmp0_xdr_message_table; break; #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: table = ndmp2_xdr_message_table; break; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: table = ndmp3_xdr_message_table; break; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: table = ndmp4_xdr_message_table; break; #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: return 0; } for (ent = table; ent->msg; ent++) { if (ent->msg == msg) { return ent; } } return 0; } /* * ENUM STRING TABLES **************************************************************** */ char * ndmp_enum_to_str (int val, struct ndmp_enum_str_table *table) { static char vbuf[8][32]; static int vbix; char * vbp; for (; table->name; table++) if (table->value == val) return table->name; vbp = vbuf[vbix&7]; vbix++; sprintf (vbp, "?0x%x?", val); return vbp; } int ndmp_enum_from_str (int *valp, char *str, struct ndmp_enum_str_table *table) { for (; table->name; table++) { if (strcmp(table->name, str) == 0) { *valp = table->value; return 1; } } return 0; } /* * MULTI-VERSION ENUM TO STRING CONVERTERS **************************************************************** */ char * ndmp_message_to_str (int protocol_version, int msg) { static char yikes_buf[40]; /* non-reentrant */ switch (protocol_version) { case 0: return ndmp0_message_to_str (msg); #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: return ndmp2_message_to_str (msg); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: return ndmp3_message_to_str (msg); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: return ndmp4_message_to_str (msg); #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: /* should never happen, if so should be rare */ sprintf (yikes_buf, "v%dmsg0x%04x", protocol_version, msg); return yikes_buf; } } char * ndmp_error_to_str (int protocol_version, int err) { static char yikes_buf[40]; /* non-reentrant */ switch (protocol_version) { case 0: return ndmp0_error_to_str (err); case 9: return ndmp9_error_to_str (err); #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: return ndmp2_error_to_str (err); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: return ndmp3_error_to_str (err); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: return ndmp4_error_to_str (err); #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: /* should never happen, if so should be rare */ sprintf (yikes_buf, "v%derr%d", protocol_version, err); return yikes_buf; } } /* * PRETTY PRINTERS **************************************************************** */ int ndmp_pp_header (int vers, void *data, char *buf) { switch (vers) { case 0: return ndmp0_pp_header (data, buf); #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: return ndmp2_pp_header (data, buf); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: return ndmp3_pp_header (data, buf); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: return ndmp4_pp_header (data, buf); #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: sprintf (buf, "V%d? ", vers); return ndmp0_pp_header (data, NDMOS_API_STREND(buf)); } } int ndmp_pp_request (int vers, int msg, void *data, int lineno, char *buf) { switch (vers) { case 0: return ndmp0_pp_request (msg, data, lineno, buf); #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: return ndmp2_pp_request (msg, data, lineno, buf); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: return ndmp3_pp_request (msg, data, lineno, buf); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: return ndmp4_pp_request (msg, data, lineno, buf); #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: sprintf (buf, "<>", vers); return -1; } } int ndmp_pp_reply (int vers, int msg, void *data, int lineno, char *buf) { switch (vers) { case 0: return ndmp0_pp_reply (msg, data, lineno, buf); #ifndef NDMOS_OPTION_NO_NDMP2 case NDMP2VER: return ndmp2_pp_reply (msg, data, lineno, buf); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 case NDMP3VER: return ndmp3_pp_reply (msg, data, lineno, buf); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 case NDMP4VER: return ndmp4_pp_reply (msg, data, lineno, buf); #endif /* !NDMOS_OPTION_NO_NDMP4 */ default: sprintf (buf, "<>", vers); return -1; } } bareos-Release-14.2.6/src/ndmp/ndmprotocol.h000066400000000000000000000211361263011562700207010ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * This is the key #include file for the NDMP protocol * layer of NDMJOBLIB. * * There are multiple version of NDMP. This gathers them together. * Under control of #ifdef NDMOS_OPTION_NO_NDMPx specific versions * may be omitted. At this time, NDMPv2 and NDMPv3 are deployed. * NDMPv1 was defined but not widely deployed, and deemed irrelavent. * NDMPv4 is under consideration. * * NDMP is defined using RPC protocol specification * files (.x files). NDMP does not really use the RPC * layer, but it does use the RPC XDR (External Data * Representation) layer. * * The original NDMP .x files are cosmetically transformed for * NDMJOBLIB. The original NDMPv2 and NDMPv3 .x files use names * like ndmp_name and ndmp_config_get_host_info_reply. These * changed between versions even though they have the same name. * Data structures which didn't change, like ndmp_pval, caused * compile-time agony. For example, xdr_ndmp_pval() would be * multiply defined at ld(1)-time. The first approach considered * and rejected to resolve this was to make a unified, all * versions .x file. It was rejected because it becomes difficult, * even impractical, to integrate new versions and to omit old ones. * The approach taken was to transform the names to reflect protocol * version. This same approach was adopted by NFS for NFSv3 and * NFSv4. Now there is an ndmp2_pval and an ndmp3_pval, and the * compiler is happy. When it's defined, there will be an ndmp4_pval. * * There are two pseudo-versions of the protocol here: NDMPv0 * and NDMPv9. These are used for internal convenience. These * are also defined using .x files because it's easy to * cut-n-paste from the official .x files. Neither NDMPv0 * nor NDMPv9 may be omitted. * * NDMPv0 is the NDMP protocol subset used before the protocol * version negotiation is complete. This subset of the protocol * must necessarily remain immutable and constant for all time. * NDMPv0 is the over-the-wire protocol until the version is * negotiated. * * NDMPv9 is an internal representation of the protocol and * isolates higher layers of NDMJOB from most variations between * protocol version. NDMPv9 makes it a little easier to add * new versions and omit older ones. NDMPv9 is never used * over-the-wire, and therefor there are no XDR routines. * * There are three primary elements of this layer: * * 1) Header files which define each version of the protocol. * These are generated from files (.x files) by rpcgen(1). * * 2) XDR routines which convert to/from the over-the-wire * protocol and internal data structures. These are * also generated by rpcgen(1). There are also * tables of XDR routines. * * 3) Support for pretty-printing the protocol data structures. * Maybe someday rpcgen(1) will generate these, too. */ /* * PROTOCOL VERSIONS **************************************************************** * */ #include "ndmp0.h" #ifndef NDMOS_OPTION_NO_NDMP2 #include "ndmp2.h" #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 #include "ndmp3.h" #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 #include "ndmp4.h" #endif /* !NDMOS_OPTION_NO_NDMP4 */ #include "ndmp9.h" /* * Protocol ammendments. These are important constants * omitted from the spec and .x files. */ #include "ndmp_ammend.h" #ifdef __cplusplus extern "C" { #endif /* * XDR MESSAGE TABLES **************************************************************** * * Table for binding a ndmp_message to appropriate XDR routines. */ struct ndmp_xdr_message_table { int msg; int (*xdr_request)(); int (*xdr_reply)(); }; extern struct ndmp_xdr_message_table ndmp0_xdr_message_table[]; #ifndef NDMOS_OPTION_NO_NDMP2 extern struct ndmp_xdr_message_table ndmp2_xdr_message_table[]; #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 extern struct ndmp_xdr_message_table ndmp3_xdr_message_table[]; #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 extern struct ndmp_xdr_message_table ndmp4_xdr_message_table[]; #endif /* !NDMOS_OPTION_NO_NDMP4 */ /* Note: no ndmp9 XDRs */ extern struct ndmp_xdr_message_table * ndmp_xmt_lookup (int protocol_version, int msg); /* * ENUM STRING TABLES **************************************************************** */ struct ndmp_enum_str_table { char * name; int value; }; extern char * ndmp_enum_to_str (int val, struct ndmp_enum_str_table *table); extern int ndmp_enum_from_str (int *valp, char *str, struct ndmp_enum_str_table *table); #include "ndmp0_enum_strs.h" #ifndef NDMOS_OPTION_NO_NDMP2 #include "ndmp2_enum_strs.h" #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 #include "ndmp3_enum_strs.h" #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 #include "ndmp4_enum_strs.h" #endif /* !NDMOS_OPTION_NO_NDMP4 */ #include "ndmp9_enum_strs.h" /* * MULTI-VERSION ENUM TO STRING CONVERTERS **************************************************************** */ extern char * ndmp_message_to_str (int protocol_version, int msg); extern char * ndmp_error_to_str (int protocol_version, int msg); /* * PRETTY PRINTERS **************************************************************** * * The ndmp[v]_pp_... (pretty printer) routines are debugging aids. * They pretty much implement an NDMP snooping package. * * All routines return -1 for an error. Otherwise, they * return the number of lines required to print the entire * data structure. A return of 0 indicates a void data * structure. lineno parameter begins at 0. * * Line number 0 is usually usable as a summary. * Three levels of increasing detail are easy: * 1) Just ndmp_pp_header() * 2) ndmp_pp_header() and ndmp_pp_{request|reply} w/ lineno=0 * 3) ndmp_pp_header() and ndmp_pp_{request|reply} all lines */ extern int ndmp_pp_header (int vers, void *data, char *buf); extern int ndmp_pp_request (int vers, int msg, void *data, int lineno, char *buf); extern int ndmp_pp_reply (int vers, int msg, void *data, int lineno, char *buf); extern int ndmp0_pp_header (void *data, char *buf); extern int ndmp0_pp_request (ndmp0_message msg, void *data, int lineno, char *buf); extern int ndmp0_pp_reply (ndmp0_message msg, void *data, int lineno, char *buf); #ifndef NDMOS_OPTION_NO_NDMP2 extern int ndmp2_pp_header (void *data, char *buf); extern int ndmp2_pp_request (ndmp2_message msg, void *data, int lineno, char *buf); extern int ndmp2_pp_reply (ndmp2_message msg, void *data, int lineno, char *buf); #endif /* !NDMOS_OPTION_NO_NDMP2 */ #ifndef NDMOS_OPTION_NO_NDMP3 extern int ndmp3_pp_header (void *data, char *buf); extern int ndmp3_pp_request (ndmp3_message msg, void *data, int lineno, char *buf); extern int ndmp3_pp_reply (ndmp3_message msg, void *data, int lineno, char *buf); #endif /* !NDMOS_OPTION_NO_NDMP3 */ #ifndef NDMOS_OPTION_NO_NDMP4 extern int ndmp4_pp_header (void *data, char *buf); extern int ndmp4_pp_request (ndmp4_message msg, void *data, int lineno, char *buf); extern int ndmp4_pp_reply (ndmp4_message msg, void *data, int lineno, char *buf); #endif /* !NDMOS_OPTION_NO_NDMP4 */ #define NDMP_PP_AS(T) ((T *)data) #define NDMP_PP_WITH(T) { T * p = ((T *)data); #define NDMP_PP_ENDWITH } #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/ndmp/scsiconst.h000066400000000000000000000710561263011562700203570ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ /* * WORKING X3T9.2 * DRAFT Project 375D */ /* Table D.2 - SCSI-2 Operation Codes ============================================================================= D - DIRECT ACCESS DEVICE Device column key .T - SEQUENTIAL ACCESS DEVICE M = Mandatory . L - PRINTER DEVICE O = Optional . P - PROCESSOR DEVICE V = Vendor-specific . .W - WRITE ONCE READ MULTIPLE DEVICE R = Reserved . . R - READ ONLY (CD-ROM) DEVICE . . S - SCANNER DEVICE . . .O - OPTICAL MEMORY DEVICE . . . M - MEDIA CHANGER DEVICE . . . C - COMMUNICATION DEVICE . . . . DTLPWRSOMC */ /*OP DTLPWRSOMC */ #define SCSI_CMD_TEST_UNIT_READY 0x00 /* MMMMMMMMMM */ #define SCSI_CMD_REWIND 0x01 /* _M________ */ #define SCSI_CMD_REZERO_UNIT 0x01 /* O_V_OO_OO_ */ #define SCSI_CMD_REQUEST_SENSE 0x03 /* MMMMMMMMMM */ #define SCSI_CMD_FORMAT 0x04 /* __O_______ */ #define SCSI_CMD_FORMAT_UNIT 0x04 /* M______O__ */ #define SCSI_CMD_READ_BLOCK_LIMITS 0x05 /* VMVVVV__V_ */ #define SCSI_CMD_INITIALIZE_ELEMENT_STATUS 0x07 /* ________O_ */ #define SCSI_CMD_REASSIGN_BLOCKS 0x07 /* OVV_O__OV_ */ #define SCSI_CMD_GET_MESSAGE_6 0x08 /* _________M */ #define SCSI_CMD_READ_6 0x08 /* OMV_OO_OV_ */ #define SCSI_CMD_RECEIVE 0x08 /* ___O______ */ #define SCSI_CMD_PRINT 0x0A /* __M_______ */ #define SCSI_CMD_SEND_MESSAGE_6 0x0A /* _________M */ #define SCSI_CMD_SEND_6 0x0A /* ___M______ */ #define SCSI_CMD_WRITE_6 0x0A /* OM__O__OV_ */ #define SCSI_CMD_SEEK_6 0x0B /* O___OO_OV_ */ #define SCSI_CMD_SLEW_AND_PRINT 0x0B /* __O_______ */ #define SCSI_CMD_READ_REVERSE 0x0F /* VOVVVV__V_ */ #define SCSI_CMD_SYNCHRONIZE_BUFFER 0x10 /* __O_O_____ */ #define SCSI_CMD_WRITE_FILEMARKS 0x10 /* VM_VVV____ */ #define SCSI_CMD_SPACE 0x11 /* VMVVVV____ */ #define SCSI_CMD_INQUIRY 0x12 /* MMMMMMMMMM */ #define SCSI_CMD_VERIFY_6 0x13 /* VOVVVV____ */ #define SCSI_CMD_RECOVER_BUFFERED_DATA 0x14 /* VOOVVV____ */ #define SCSI_CMD_MODE_SELECT_6 0x15 /* OMO_OOOOOO */ #define SCSI_CMD_RESERVE 0x16 /* M___MM_MO_ */ #define SCSI_CMD_RESERVE_UNIT 0x16 /* _MM___M___ */ #define SCSI_CMD_RELEASE 0x17 /* M___MM_MO_ */ #define SCSI_CMD_RELEASE_UNIT 0x17 /* _MM___M___ */ #define SCSI_CMD_COPY 0x18 /* OOOOOOOO__ */ #define SCSI_CMD_ERASE 0x19 /* VMVVVV____ */ #define SCSI_CMD_MODE_SENSE_6 0x1A /* OMO_OOOOOO */ #define SCSI_CMD_LOAD_UNLOAD 0x1B /* _O________ */ #define SCSI_CMD_SCAN 0x1B /* ______O___ */ #define SCSI_CMD_STOP_PRINT 0x1B /* __O_______ */ #define SCSI_CMD_STOP_START_UNIT 0x1B /* O___OO_O__ */ #define SCSI_CMD_RECEIVE_DIAGNOSTIC_RESULTS 0x1C /* OOOOOOOOOO */ #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D /* MMMMMMMMMM */ #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E /* OO__OO_OO_ */ #define SCSI_CMD_SET_WINDOW 0x24 /* V___VVM___ */ #define SCSI_CMD_GET_WINDOW 0x25 /* ______O___ */ #define SCSI_CMD_READ_CAPACITY 0x25 /* M___M__M__ */ #define SCSI_CMD_READ_CD_ROM_CAPACITY 0x25 /* _____M____ */ #define SCSI_CMD_GET_MESSAGE_10 0x28 /* _________O */ #define SCSI_CMD_READ_10 0x28 /* M___MMMM__ */ #define SCSI_CMD_READ_GENERATION 0x29 /* V___VV_O__ */ #define SCSI_CMD_SEND_MESSAGE_10 0x2A /* _________O */ #define SCSI_CMD_SEND_10 0x2A /* ______O___ */ #define SCSI_CMD_WRITE_10 0x2A /* O___M__M__ */ #define SCSI_CMD_LOCATE 0x2B /* _O________ */ #define SCSI_CMD_POSITION_TO_ELEMENT 0x2B /* ________O_ */ #define SCSI_CMD_SEEK_10 0x2B /* O___OO_O__ */ #define SCSI_CMD_ERASE_10 0x2C /* V______O__ */ #define SCSI_CMD_READ_UPDATED_BLOCK 0x2D /* V___O__O__ */ #define SCSI_CMD_WRITE_AND_VERIFY_10 0x2E /* O___O__O__ */ #define SCSI_CMD_VERIFY_10 0x2F /* O___OO_O__ */ #define SCSI_CMD_SEARCH_DATA_HIGH_10 0x30 /* O___OO_O__ */ #define SCSI_CMD_OBJECT_POSITION 0x31 /* ______O___ */ #define SCSI_CMD_SEARCH_DATA_EQUAL_10 0x31 /* O___OO_O__ */ #define SCSI_CMD_SEARCH_DATA_LOW_10 0x32 /* O___OO_O__ */ #define SCSI_CMD_SET_LIMITS_10 0x33 /* O___OO_O__ */ #define SCSI_CMD_GET_DATA_BUFFER_STATUS 0x34 /* ______O___ */ #define SCSI_CMD_PRE_FETCH 0x34 /* O___OO_O__ */ #define SCSI_CMD_READ_POSITION 0x34 /* _O________ */ #define SCSI_CMD_SYNCHRONIZE_CACHE 0x35 /* O___OO_O__ */ #define SCSI_CMD_LOCK_UNLOCK_CACHE 0x36 /* O___OO_O__ */ #define SCSI_CMD_READ_DEFECT_DATA_10 0x37 /* O______O__ */ #define SCSI_CMD_MEDIUM_SCAN 0x38 /* ____O__O__ */ #define SCSI_CMD_COMPARE 0x39 /* OOOOOOOO__ */ #define SCSI_CMD_COPY_AND_VERIFY 0x3A /* OOOOOOOO__ */ #define SCSI_CMD_WRITE_BUFFER 0x3B /* OOOOOOOOOO */ #define SCSI_CMD_READ_BUFFER 0x3C /* OOOOOOOOOO */ #define SCSI_CMD_UPDATE_BLOCK 0x3D /* ____O__O__ */ #define SCSI_CMD_READ_LONG 0x3E /* O___OO_O__ */ #define SCSI_CMD_WRITE_LONG 0x3F /* O___O__O__ */ #define SCSI_CMD_CHANGE_DEFINITION 0x40 /* OOOOOOOOOO */ #define SCSI_CMD_WRITE_SAME 0x41 /* O_________ */ #define SCSI_CMD_READ_SUB_CHANNEL 0x42 /* _____O____ */ #define SCSI_CMD_READ_TOC 0x43 /* _____O____ */ #define SCSI_CMD_READ_HEADER 0x44 /* _____O____ */ #define SCSI_CMD_PLAY_AUDIO_10 0x45 /* _____O____ */ #define SCSI_CMD_PLAY_AUDIO_MSF 0x47 /* _____O____ */ #define SCSI_CMD_PLAY_AUDIO_TRACK_INDEX 0x48 /* _____O____ */ #define SCSI_CMD_PLAY_TRACK_RELATIVE_10 0x49 /* _____O____ */ #define SCSI_CMD_PAUSE_RESUME 0x4B /* _____O____ */ #define SCSI_CMD_LOG_SELECT 0x4C /* OOOOOOOOOO */ #define SCSI_CMD_LOG_SENSE 0x4D /* OOOOOOOOOO */ #define SCSI_CMD_MODE_SELECT_10 0x55 /* OOO_OOOOOO */ #define SCSI_CMD_MODE_SENSE_10 0x5A /* OOO_OOOOOO */ #define SCSI_CMD_MOVE_MEDIUM 0xA5 /* ________M_ */ #define SCSI_CMD_PLAY_AUDIO_12 0xA5 /* _____O____ */ #define SCSI_CMD_EXCHANGE_MEDIUM 0xA6 /* ________O_ */ #define SCSI_CMD_GET_MESSAGE_12 0xA8 /* _________O */ #define SCSI_CMD_READ_12 0xA8 /* ____OO_O__ */ #define SCSI_CMD_PLAY_TRACK_RELATIVE_12 0xA9 /* _____O____ */ #define SCSI_CMD_SEND_MESSAGE_12 0xAA /* _________O */ #define SCSI_CMD_WRITE_12 0xAA /* ____O__O__ */ #define SCSI_CMD_ERASE_12 0xAC /* _______O__ */ #define SCSI_CMD_WRITE_AND_VERIFY_12 0xAE /* ____O__O__ */ #define SCSI_CMD_VERIFY_12 0xAF /* ____OO_O__ */ #define SCSI_CMD_SEARCH_DATA_HIGH_12 0xB0 /* ____OO_O__ */ #define SCSI_CMD_SEARCH_DATA_EQUAL_12 0xB1 /* ____OO_O__ */ #define SCSI_CMD_SEARCH_DATA_LOW_12 0xB2 /* ____OO_O__ */ #define SCSI_CMD_SET_LIMITS_12 0xB3 /* ____OO_O__ */ #define SCSI_CMD_REQUEST_VOLUME_ELEMENT_ADDRESS 0xB5 /* ________O_ */ #define SCSI_CMD_SEND_VOLUME_TAG 0xB6 /* ________O_ */ #define SCSI_CMD_READ_DEFECT_DATA_12 0xB7 /* _______O__ */ #define SCSI_CMD_READ_ELEMENT_STATUS 0xB8 /* ________O_ */ /* * Table 26 - Status byte * +========-========-========-========-========-========-========-========+ * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |=================+============================================+========| * | Reserved | Status byte code |Reserved| * +=======================================================================+ * * * Table 27 - Status byte code * +==================================-==============================+ * | Bits of status byte | Status | * |----------------------------------| | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | * |-----+---+---+---+---+---+---+----+------------------------------| * | R | R | 0 | 0 | 0 | 0 | 0 | R | GOOD | * | R | R | 0 | 0 | 0 | 0 | 1 | R | CHECK CONDITION | * | R | R | 0 | 0 | 0 | 1 | 0 | R | CONDITION MET | * | R | R | 0 | 0 | 1 | 0 | 0 | R | BUSY | * | R | R | 0 | 1 | 0 | 0 | 0 | R | INTERMEDIATE | * | R | R | 0 | 1 | 0 | 1 | 0 | R | INTERMEDIATE-CONDITION MET | * | R | R | 0 | 1 | 1 | 0 | 0 | R | RESERVATION CONFLICT | * | R | R | 1 | 0 | 0 | 0 | 1 | R | COMMAND TERMINATED | * | R | R | 1 | 0 | 1 | 0 | 0 | R | QUEUE FULL | * |----------------------------------| | * | All other codes | Reserved | * |-----------------------------------------------------------------| * | Key: R = Reserved bit | * +=================================================================+ * * A definition of the status byte codes is given below. * * 7.3.1 GOOD: This status indicates that the target has successfully * completed the command. * * 7.3.2 CHECK CONDITION: This status indicates that a contingent allegiance * condition has occurred (see 7.6). * * 7.3.3 CONDITION MET: This status or INTERMEDIATE-CONDITION MET is * returned whenever the requested operation is satisfied (see the SEARCH * DATA and PREFETCH commands). * * 7.3.4 BUSY: This status indicates that the target is busy. This status * shall be returned whenever a target is unable to accept a command from an * otherwise acceptable initiator (i.e. no reservation conflicts). The * recommended initiator recovery action is to issue the command again at a * later time. * * 7.3.5 INTERMEDIATE: This status or INTERMEDIATE-CONDITION MET shall be * returned for every successfully completed command in a series of linked * commands (except the last command), unless the command is terminated with * CHECK CONDITION, RESERVATION CONFLICT, or COMMAND TERMINATED status. If * INTERMEDIATE or INTERMEDIATE-CONDITION MET status is not returned, the * series of linked commands is terminated and the I/O process is ended. * * 7.3.6 INTERMEDIATE-CONDITION MET: This status is the combination of the * CONDITION MET and INTERMEDIATE statuses. * * 7.3.7 RESERVATION CONFLICT: This status shall be returned whenever an * initiator attempts to access a logical unit or an extent within a logical * unit that is reserved with a conflicting reservation type for another SCSI * device (see the RESERVE and RESERVE UNIT commands). The recommended * initiator recovery action is to issue the command again at a later time. * * 7.3.8 COMMAND TERMINATED: This status shall be returned whenever the * target terminates the current I/O process after receiving a TERMINATE I/O * PROCESS message (see 6.6.22). This status also indicates that a * contingent allegiance condition has occurred (see 7.6). * * 7.3.9 QUEUE FULL: This status shall be implemented if tagged queuing is * implemented. This status is returned when a SIMPLE QUEUE TAG, ORDERED * QUEUE TAG, or HEAD OF QUEUE TAG message is received and the command queue * is full. The I/O process is not placed in the command queue. */ /* Standard SCSI status byte values. */ #define SCSI_STATUS_MASK 0x3E #define SCSI_STATUS_BYTE_CODE(X) ((X)&SCSI_STATUS_MASK) #define SCSI_STATUS_GOOD 0x00 #define SCSI_STATUS_CHECK_CONDITION 0x02 #define SCSI_STATUS_CONDITION_MET 0x04 #define SCSI_STATUS_BUSY 0x08 #define SCSI_STATUS_INTERMEDIATE_GOOD 0x10 #define SCSI_STATUS_INTERMEDIATE_MET 0x14 #define SCSI_STATUS_RESERVATION_CONFLICT 0x18 #define SCSI_STATUS_COMMAND_TERMINATED 0x22 #define SCSI_STATUS_QUEUE_FULL 0x28 #define SCSI_SENSE_VALID_BIT 0x80 #define SCSI_SENSE_FILEMARK_BIT 0x80 #define SCSI_SENSE_EOM_BIT 0x40 #define SCSI_SENSE_ILI_BIT 0x20 #define SCSI_SENSE_SENSE_KEY_MASK 0x0F /* 8.2.14.3 Sense key and sense code definitions */ #define SCSI_SENSE_KEY_NO_SENSE 0x0 #define SCSI_SENSE_KEY_RECOVERED_ERROR 0x1 #define SCSI_SENSE_KEY_NOT_READY 0x2 #define SCSI_SENSE_KEY_MEDIUM_ERROR 0x3 #define SCSI_SENSE_KEY_HARDWARE_ERROR 0x4 #define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x5 #define SCSI_SENSE_KEY_UNIT_ATTENTION 0x6 #define SCSI_SENSE_KEY_DATA_PROTECT 0x7 #define SCSI_SENSE_KEY_BLANK_CHECK 0x8 #define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x9 #define SCSI_SENSE_KEY_COPY_ABORTED 0xA #define SCSI_SENSE_KEY_ABORTED_COMMAND 0xB #define SCSI_SENSE_KEY_EQUAL 0xC #define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0xD #define SCSI_SENSE_KEY_MISCOMPARE 0xE #define SCSI_SENSE_KEY_RESERVED 0xF /* ================================================================ D - DIRECT ACCESS DEVICE .T - SEQUENTIAL ACCESS DEVICE . L - PRINTER DEVICE . P - PROCESSOR DEVICE . .W - WRITE ONCE READ MULTIPLE DEVICE . . R - READ ONLY (CD-ROM) DEVICE . . S - SCANNER DEVICE . . .O - OPTICAL MEMORY DEVICE . . . M - MEDIA CHANGER DEVICE . . . C - COMMUNICATION DEVICE . . . . DTLPWRSOMC */ #ifndef _ASQ #define _ASQ(ASC,ASCQ) (((ASC)<<8)|(ASCQ)) #endif #define ASQ_NO_ADDITIONAL_SENSE_INFORMATION _ASQ(0x00,0x00) /* DTLPWRSOMC */ #define ASQ_FILEMARK_DETECTED _ASQ(0x00,0x01) /* _T________ */ #define ASQ_END_OF_PARTITION_OR_MEDIUM_DETECTED _ASQ(0x00,0x02) /* _T____S___ */ #define ASQ_SETMARK_DETECTED _ASQ(0x00,0x03) /* _T________ */ #define ASQ_BEGINNING_OF_PARTITION_OR_MEDIUM_DETECTED _ASQ(0x00,0x04) /* _T____S___ */ #define ASQ_END_OF_DATA_DETECTED _ASQ(0x00,0x05) /* _T____S___ */ #define ASQ_IO_PROCESS_TERMINATED _ASQ(0x00,0x06) /* DTLPWRSOMC */ #define ASQ_AUDIO_PLAY_OPERATION_IN_PROGRESS _ASQ(0x00,0x11) /* R_________ */ #define ASQ_AUDIO_PLAY_OPERATION_PAUSED _ASQ(0x00,0x12) /* R_________ */ #define ASQ_AUDIO_PLAY_OPERATION_SUCCESSFULLY_COMPLETED _ASQ(0x00,0x13) /* R_________ */ #define ASQ_AUDIO_PLAY_OPERATION_STOPPED_DUE_TO_ERROR _ASQ(0x00,0x14) /* R_________ */ #define ASQ_NO_CURRENT_AUDIO_STATUS_TO_RETURN _ASQ(0x00,0x15) /* R_________ */ #define ASQ_NO_INDEX_OR_SECTOR_SIGNAL _ASQ(0x01,0x00) /* DW__O_____ */ #define ASQ_NO_SEEK_COMPLETE _ASQ(0x02,0x00) /* DWR_OM____ */ #define ASQ_PERIPHERAL_DEVICE_WRITE_FAULT _ASQ(0x03,0x00) /* DTL_W_SO__ */ #define ASQ_NO_WRITE_CURRENT _ASQ(0x03,0x01) /* _T________ */ #define ASQ_EXCESSIVE_WRITE_ERRORS _ASQ(0x03,0x02) /* _T________ */ #define ASQ_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE _ASQ(0x04,0x00) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_IS_IN_PROCESS_OF_BECOMING_READY \ _ASQ(0x04,0x01) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_NOT_READY_INITIALIZING_REQUIRED \ _ASQ(0x04,0x02) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_NOT_READY_MANUAL_INTERVENTION_REQUIRED \ _ASQ(0x04,0x03) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS _ASQ(0x04,0x04) /* DTL____O__ */ #define ASQ_LOGICAL_UNIT_DOES_NOT_RESPOND_TO_SELECTION _ASQ(0x05,0x00) /* DTL_WRSOMC */ #define ASQ_NO_REFERENCE_POSITION_FOUND _ASQ(0x06,0x00) /* DWR_OM__NO */ #define ASQ_MULTIPLE_PERIPHERAL_DEVICES_SELECTED _ASQ(0x07,0x00) /* DTL_WRSOM_ */ #define ASQ_LOGICAL_UNIT_COMMUNICATION_FAILURE _ASQ(0x08,0x00) /* DTL_WRSOMC */ #define ASQ_LOGICAL_UNIT_COMMUNICATION_TIME_OUT _ASQ(0x08,0x01) /* DTL_WRSOMC */ #define ASQ_LOGICAL_UNIT_COMMUNICATION_PARITY_ERROR _ASQ(0x08,0x02) /* DTL_WRSOMC */ #define ASQ_TRACK_FOLLOWING_ERROR _ASQ(0x09,0x00) /* DT__WR_O__ */ #define ASQ_TRACKING_SERVO_FAILURE _ASQ(0x09,0x01) /* ____WR_O__ */ #define ASQ_FOCUS_SERVO_FAILURE _ASQ(0x09,0x02) /* ____WR_O__ */ #define ASQ_SPINDLE_SERVO_FAILURE _ASQ(0x09,0x03) /* ____WR_O__ */ #define ASQ_ERROR_LOG_OVERFLOW _ASQ(0x0A,0x00) /* DTLPWRSOMC */ #define ASQ_WRITE_ERROR _ASQ(0x0C,0x00) /* ___T_____S */ #define ASQ_WRITE_ERROR_RECOVERED_WITH_AUTO_REALLOCATION \ _ASQ(0x0C,0x01) /* D___W__O__ */ #define ASQ_WRITE_ERROR_AUTO_REALLOCATION_FAILED _ASQ(0x0C,0x02) /* D___W__O__ */ #define ASQ_ID_CRC_OR_ECC_ERROR _ASQ(0x10,0x00) /* D___W__O__ */ #define ASQ_UNRECOVERED_READ_ERROR _ASQ(0x11,0x00) /* DT__WRSO__ */ #define ASQ_READ_RETRIES_EXHAUSTED _ASQ(0x11,0x01) /* DT__W_SO__ */ #define ASQ_ERROR_TOO_LONG_TO_CORRECT _ASQ(0x11,0x02) /* DT__W_SO__ */ #define ASQ_MULTIPLE_READ_ERRORS _ASQ(0x11,0x03) /* DT__W_SO__ */ #define ASQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED \ _ASQ(0x11,0x04) /* D___W__O__ */ #define ASQ_L_EC_UNCORRECTABLE_ERROR _ASQ(0x11,0x05) /* ____WR_O__ */ #define ASQ_CIRC_UNRECOVERED_ERROR _ASQ(0x11,0x06) /* ____WR_O__ */ #define ASQ_DATA_RESYNCHRONIZATION_ERROR _ASQ(0x11,0x07) /* ____W__O__ */ #define ASQ_INCOMPLETE_BLOCK_READ _ASQ(0x11,0x08) /* _T________ */ #define ASQ_NO_GAP_FOUND _ASQ(0x11,0x09) /* _T________ */ #define ASQ_MISCORRECTED_ERROR _ASQ(0x11,0x0A) /* DT_____O__ */ #define ASQ_UNRECOVERED_READ_ERROR_RECOMMEND_REASSIGNMENT \ _ASQ(0x11,0x0B) /* D___W__O__ */ #define ASQ_UNRECOVERED_READ_ERROR_RECOMMEND_REWRITE_THE_DATA \ _ASQ(0x11,0x0C) /* D___W__O__ */ #define ASQ_ADDRESS_MARK_NOT_FOUND_FOR_ID_FIELD _ASQ(0x12,0x00) /* D___W__O__ */ #define ASQ_ADDRESS_MARK_NOT_FOUND_FOR_DATA_FIELD _ASQ(0x13,0x00) /* D___W__O__ */ #define ASQ_RECORDED_ENTITY_NOT_FOUND _ASQ(0x14,0x00) /* DTL_WRSO__ */ #define ASQ_RECORD_NOT_FOUND _ASQ(0x14,0x01) /* DT__WR_O__ */ #define ASQ_FILEMARK_OR_SETMARK_NOT_FOUND _ASQ(0x14,0x02) /* _T________ */ #define ASQ_END_OF_DATA_NOT_FOUND _ASQ(0x14,0x03) /* _T________ */ #define ASQ_BLOCK_SEQUENCE_ERROR _ASQ(0x14,0x04) /* _T________ */ #define ASQ_RANDOM_POSITIONING_ERROR _ASQ(0x15,0x00) /* DTL_WRSOM_ */ #define ASQ_MECHANICAL_POSITIONING_ERROR _ASQ(0x15,0x01) /* DTL_WRSOM_ */ #define ASQ_POSITIONING_ERROR_DETECTED_BY_READ_OF_MEDIUM \ _ASQ(0x15,0x02) /* DT__WR_O__ */ #define ASQ_DATA_SYNCHRONIZATION_MARK_ERROR _ASQ(0x16,0x00) /* DW_____O__ */ #define ASQ_RECOVERED_DATA_WITH_NO_ERROR_CORRECTION_APPLIED \ _ASQ(0x17,0x00) /* DT__WRSO__ */ #define ASQ_RECOVERED_DATA_WITH_RETRIES _ASQ(0x17,0x01) /* DT__WRSO__ */ #define ASQ_RECOVERED_DATA_WITH_POSITIVE_HEAD_OFFSET _ASQ(0x17,0x02) /* DT__WR_O__ */ #define ASQ_RECOVERED_DATA_WITH_NEGATIVE_HEAD_OFFSET _ASQ(0x17,0x03) /* DT__WR_O__ */ #define ASQ_RECOVERED_DATA_WITH_RETRIES_ANDOR_CIRC_APPLIED \ _ASQ(0x17,0x04) /* ____WR_O__ */ #define ASQ_RECOVERED_DATA_USING_PREVIOUS_SECTOR_ID _ASQ(0x17,0x05) /* D___WR_O__ */ #define ASQ_RECOVERED_DATA_WITHOUT_ECC_DATA_AUTO_REALLOCATED \ _ASQ(0x17,0x06) /* D___W__O__ */ #define ASQ_RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REASSIGNMENT \ _ASQ(0x17,0x07) /* D___W__O__ */ #define ASQ_RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REWRITE \ _ASQ(0x17,0x08) /* D___W__O__ */ #define ASQ_RECOVERED_DATA_WITH_ERROR_CORRECTION_APPLIED \ _ASQ(0x18,0x00) /* DT__WR_O__ */ #define ASQ_RECOVERED_DATA_WITH_ERROR_CORRECTION_AND_RETRIES_APPLIED \ _ASQ(0x18,0x01) /* D___WR_O__ */ #define ASQ_RECOVERED_DATA_DATA_AUTO_REALLOCATED _ASQ(0x18,0x02) /* D___WR_O__ */ #define ASQ_RECOVERED_DATA_WITH_CIRC _ASQ(0x18,0x03) /* _____R____ */ #define ASQ_RECOVERED_DATA_WITH_LEC _ASQ(0x18,0x04) /* _____R____ */ #define ASQ_RECOVERED_DATA_RECOMMEND_REASSIGNMENT _ASQ(0x18,0x05) /* D___WR_O__ */ #define ASQ_RECOVERED_DATA_RECOMMEND_REWRITE _ASQ(0x18,0x06) /* D___WR_O__ */ #define ASQ_DEFECT_LIST_ERROR _ASQ(0x19,0x00) /* D______O__ */ #define ASQ_DEFECT_LIST_NOT_AVAILABLE _ASQ(0x19,0x01) /* D______O__ */ #define ASQ_DEFECT_LIST_ERROR_IN_PRIMARY_LIST _ASQ(0x19,0x02) /* D______O__ */ #define ASQ_DEFECT_LIST_ERROR_IN_GROWN_LIST _ASQ(0x19,0x03) /* D______O__ */ #define ASQ_PARAMETER_LIST_LENGTH_ERROR _ASQ(0x1A,0x00) /* DTLPWRSOMC */ #define ASQ_SYNCHRONOUS_DATA_TRANSFER_ERROR _ASQ(0x1B,0x00) /* DTLPWRSOMC */ #define ASQ_DEFECT_LIST_NOT_FOUND _ASQ(0x1C,0x00) /* D______O__ */ #define ASQ_PRIMARY_DEFECT_LIST_NOT_FOUND _ASQ(0x1C,0x01) /* D______O__ */ #define ASQ_GROWN_DEFECT_LIST_NOT_FOUND _ASQ(0x1C,0x02) /* D______O__ */ #define ASQ_MISCOMPARE_DURING_VERIFY_OPERATION _ASQ(0x1D,0x00) /* D___W__O__ */ #define ASQ_RECOVERED_ID_WITH_ECC _ASQ(0x1E,0x00) /* D___W__O__ */ #define ASQ_INVALID_COMMAND_OPERATION_CODE _ASQ(0x20,0x00) /* DTLPWRSOMC */ #define ASQ_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE _ASQ(0x21,0x00) /* DT__WR_OM_ */ #define ASQ_INVALID_ELEMENT_ADDRESS _ASQ(0x21,0x01) /* ________M_ */ #define ASQ_ILLEGAL_FUNCTION _ASQ(0x22,0x00) /* D_________ */ #define ASQ_INVALID_FIELD_IN_CDB _ASQ(0x24,0x00) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_NOT_SUPPORTED _ASQ(0x25,0x00) /* DTLPWRSOMC */ #define ASQ_INVALID_FIELD_IN_PARAMETER_LIST _ASQ(0x26,0x00) /* DTLPWRSOMC */ #define ASQ_PARAMETER_NOT_SUPPORTED _ASQ(0x26,0x01) /* DTLPWRSOMC */ #define ASQ_PARAMETER_VALUE_INVALID _ASQ(0x26,0x02) /* DTLPWRSOMC */ #define ASQ_THRESHOLD_PARAMETERS_NOT_SUPPORTED _ASQ(0x26,0x03) /* DTLPWRSOMC */ #define ASQ_WRITE_PROTECTED _ASQ(0x27,0x00) /* DT__W__O__ */ #define ASQ_NOT_READY_TO_READY_TRANSITION _ASQ(0x28,0x00) /* DTLPWRSOMC */ #define ASQ_MEDIUM_MAY_HAVE_CHANGED _ASQ(0x28,0x00) /* DTLPWRSOMC */ #define ASQ_IMPORT_OR_EXPORT_ELEMENT_ACCESSED _ASQ(0x28,0x01) /* ________M_ */ #define ASQ_POWER_ON_OR_RESET_OR_BUS_DEVICE_RESET_OCCURRED \ _ASQ(0x29,0x00) /* DTLPWRSOMC */ #define ASQ_PARAMETERS_CHANGED _ASQ(0x2A,0x00) /* DTL_WRSOMC */ #define ASQ_MODE_PARAMETERS_CHANGED _ASQ(0x2A,0x01) /* DTL_WRSOMC */ #define ASQ_LOG_PARAMETERS_CHANGED _ASQ(0x2A,0x02) /* DTL_WRSOMC */ #define ASQ_COPY_CANNOT_EXECUTE_SINCE_HOST_CANNOT_DISCONNECT \ _ASQ(0x2B,0x00) /* DTLPWRSO_C */ #define ASQ_COMMAND_SEQUENCE_ERROR _ASQ(0x2C,0x00) /* DTLPWRSOMC */ #define ASQ_TOO_MANY_WINDOWS_SPECIFIED _ASQ(0x2C,0x01) /* ______S___ */ #define ASQ_INVALID_COMBINATION_OF_WINDOWS_SPECIFIED _ASQ(0x2C,0x02) /* ______S___ */ #define ASQ_OVERWRITE_ERROR_ON_UPDATE_IN_PLACE _ASQ(0x2D,0x00) /* _T________ */ #define ASQ_COMMANDS_CLEARED_BY_ANOTHER_INITIATOR _ASQ(0x2F,0x00) /* DTLPWRSOMC */ #define ASQ_INCOMPATIBLE_MEDIUM_INSTALLED _ASQ(0x30,0x00) /* DT__WR_OM_ */ #define ASQ_CANNOT_READ_MEDIUM_UNKNOWN_FORMAT _ASQ(0x30,0x01) /* DT__WR_O__ */ #define ASQ_CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT _ASQ(0x30,0x02) /* DT__WR_O__ */ #define ASQ_CLEANING_CARTRIDGE_INSTALLED _ASQ(0x30,0x03) /* DT________ */ #define ASQ_MEDIUM_FORMAT_CORRUPTED _ASQ(0x31,0x00) /* DT__W__O__ */ #define ASQ_FORMAT_COMMAND_FAILED _ASQ(0x31,0x01) /* D_L____O__ */ #define ASQ_NO_DEFECT_SPARE_LOCATION_AVAILABLE _ASQ(0x32,0x00) /* D___W__O__ */ #define ASQ_DEFECT_LIST_UPDATE_FAILURE _ASQ(0x32,0x01) /* D___W__O__ */ #define ASQ_TAPE_LENGTH_ERROR _ASQ(0x33,0x00) /* _T________ */ #define ASQ_RIBBON_OR_INK_OR_TONER_FAILURE _ASQ(0x36,0x00) /* __L_______ */ #define ASQ_ROUNDED_PARAMETER _ASQ(0x37,0x00) /* DTL_WRSOMC */ #define ASQ_SAVING_PARAMETERS_NOT_SUPPORTED _ASQ(0x39,0x00) /* DTL_WRSOMC */ #define ASQ_MEDIUM_NOT_PRESENT _ASQ(0x3A,0x00) /* DTL_WRSOM_ */ #define ASQ_SEQUENTIAL_POSITIONING_ERROR _ASQ(0x3B,0x00) /* _TL_______ */ #define ASQ_TAPE_POSITION_ERROR_AT_BEGINNING_OF_MEDIUM _ASQ(0x3B,0x01) /* _T________ */ #define ASQ_TAPE_POSITION_ERROR_AT_END_OF_MEDIUM _ASQ(0x3B,0x02) /* _T________ */ #define ASQ_TAPE_OR_ELECTRONIC_VERTICAL_FORMS_UNIT_NOT_READY \ _ASQ(0x3B,0x03) /* __L_______ */ #define ASQ_SLEW_FAILURE _ASQ(0x3B,0x04) /* __L_______ */ #define ASQ_PAPER_JAM _ASQ(0x3B,0x05) /* __L_______ */ #define ASQ_FAILED_TO_SENSE_TOP_OF_FORM _ASQ(0x3B,0x06) /* __L_______ */ #define ASQ_FAILED_TO_SENSE_BOTTOM_OF_FORM _ASQ(0x3B,0x07) /* __L_______ */ #define ASQ_REPOSITION_ERROR _ASQ(0x3B,0x08) /* _T________ */ #define ASQ_READ_PAST_END_OF_MEDIUM _ASQ(0x3B,0x09) /* ______S___ */ #define ASQ_READ_PAST_BEGINNING_OF_MEDIUM _ASQ(0x3B,0x0A) /* ______S___ */ #define ASQ_POSITION_PAST_END_OF_MEDIUM _ASQ(0x3B,0x0B) /* ______S___ */ #define ASQ_POSITION_PAST_BEGINNING_OF_MEDIUM _ASQ(0x3B,0x0C) /* ______S___ */ #define ASQ_MEDIUM_DESTINATION_ELEMENT_FULL _ASQ(0x3B,0x0D) /* ________M_ */ #define ASQ_MEDIUM_SOURCE_ELEMENT_EMPTY _ASQ(0x3B,0x0E) /* ________M_ */ #define ASQ_INVALID_BITS_IN_IDENTIFY_MESSAGE _ASQ(0x3D,0x00) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_HAS_NOT_SELF_CONFIGURED_YET _ASQ(0x3E,0x00) /* DTLPWRSOMC */ #define ASQ_TARGET_OPERATING_CONDITIONS_HAVE_CHANGED _ASQ(0x3F,0x00) /* DTLPWRSOMC */ #define ASQ_MICROCODE_HAS_BEEN_CHANGED _ASQ(0x3F,0x01) /* DTLPWRSOMC */ #define ASQ_CHANGED_OPERATING_DEFINITION _ASQ(0x3F,0x02) /* DTLPWRSOMC */ #define ASQ_INQUIRY_DATA_HAS_CHANGED _ASQ(0x3F,0x03) /* DTLPWRSOMC */ #define ASQ_RAM_FAILURE _ASQ(0x40,0x00) /* D_________ */ #define ASQ_DIAGNOSTIC_FAILURE_ON_COMPONENT_00 _ASQ(0x40,0x00) /* DTLPWRSOMC */ #define ASQ_DATA_PATH_FAILURE _ASQ(0x41,0x00) /* D_________ */ #define ASQ_POWER_ON_OR_SELF_TEST_FAILURE _ASQ(0x42,0x00) /* D_________ */ #define ASQ_MESSAGE_ERROR _ASQ(0x43,0x00) /* DTLPWRSOMC */ #define ASQ_INTERNAL_TARGET_FAILURE _ASQ(0x44,0x00) /* DTLPWRSOMC */ #define ASQ_SELECT_OR_RESELECT_FAILURE _ASQ(0x45,0x00) /* DTLPWRSOMC */ #define ASQ_UNSUCCESSFUL_SOFT_RESET _ASQ(0x46,0x00) /* DTLPWRSOMC */ #define ASQ_SCSI_PARITY_ERROR _ASQ(0x47,0x00) /* DTLPWRSOMC */ #define ASQ_INITIATOR_DETECTED_ERROR_MESSAGE_RECEIVED _ASQ(0x48,0x00) /* DTLPWRSOMC */ #define ASQ_INVALID_MESSAGE_ERROR _ASQ(0x49,0x00) /* DTLPWRSOMC */ #define ASQ_COMMAND_PHASE_ERROR _ASQ(0x4A,0x00) /* DTLPWRSOMC */ #define ASQ_DATA_PHASE_ERROR _ASQ(0x4B,0x00) /* DTLPWRSOMC */ #define ASQ_LOGICAL_UNIT_FAILED_SELF_CONFIGURATION _ASQ(0x4C,0x00) /* DTLPWRSOMC */ #define ASQ_OVERLAPPED_COMMANDS_ATTEMPTED _ASQ(0x4E,0x00) /* DTLPWRSOMC */ #define ASQ_WRITE_APPEND_ERROR _ASQ(0x50,0x00) /* _T________ */ #define ASQ_WRITE_APPEND_POSITION_ERROR _ASQ(0x50,0x01) /* _T________ */ #define ASQ_POSITION_ERROR_RELATED_TO_TIMING _ASQ(0x50,0x02) /* _T________ */ #define ASQ_ERASE_FAILURE _ASQ(0x51,0x00) /* _T_____O__ */ #define ASQ_CARTRIDGE_FAULT _ASQ(0x52,0x00) /* _T________ */ #define ASQ_MEDIA_LOAD_OR_EJECT_FAILED _ASQ(0x53,0x00) /* DTL_WRSOM_ */ #define ASQ_UNLOAD_TAPE_FAILURE _ASQ(0x53,0x01) /* _T________ */ #define ASQ_MEDIUM_REMOVAL_PREVENTED _ASQ(0x53,0x02) /* DT__WR_OM_ */ #define ASQ_SCSI_TO_HOST_SYSTEM_INTERFACE_FAILURE _ASQ(0x54,0x00) /* ___P______ */ #define ASQ_SYSTEM_RESOURCE_FAILURE _ASQ(0x55,0x00) /* ___P______ */ #define ASQ_UNABLE_TO_RECOVER_TABLE_OF_CONTENTS _ASQ(0x57,0x00) /* _______R__ */ #define ASQ_GENERATION_DOES_NOT_EXIST _ASQ(0x58,0x00) /* __O_______ */ #define ASQ_UPDATED_BLOCK_READ _ASQ(0x59,0x00) /* __O_______ */ #define ASQ_OPERATOR_REQUEST_OR_STATE_CHANGE_INPUT _ASQ(0x5A,0x00) /* DTLPWRSOM_ */ #define ASQ_OPERATOR_MEDIUM_REMOVAL_REQUEST _ASQ(0x5A,0x01) /* DT__WR_OM_ */ #define ASQ_OPERATOR_SELECTED_WRITE_PROTECT _ASQ(0x5A,0x02) /* DT__W__O__ */ #define ASQ_OPERATOR_SELECTED_WRITE_PERMIT _ASQ(0x5A,0x03) /* DT__W__O__ */ #define ASQ_LOG_EXCEPTION _ASQ(0x5B,0x00) /* DTLPWRSOM_ */ #define ASQ_THRESHOLD_CONDITION_MET _ASQ(0x5B,0x01) /* DTLPWRSOM_ */ #define ASQ_LOG_COUNTER_AT_MAXIMUM _ASQ(0x5B,0x02) /* DTLPWRSOM_ */ #define ASQ_LOG_LIST_CODES_EXHAUSTED _ASQ(0x5B,0x03) /* DTLPWRSOM_ */ #define ASQ_RPL_STATUS_CHANGE _ASQ(0x5C,0x00) /* D___O_____ */ #define ASQ_SPINDLES_SYNCHRONIZED _ASQ(0x5C,0x01) /* D___O_____ */ #define ASQ_SPINDLES_NOT_SYNCHRONIZED _ASQ(0x5C,0x02) /* D___O_____ */ #define ASQ_LAMP_FAILURE _ASQ(0x60,0x00) /* ______S___ */ #define ASQ_VIDEO_ACQUISITION_ERROR _ASQ(0x61,0x00) /* ______S___ */ #define ASQ_UNABLE_TO_ACQUIRE_VIDEO _ASQ(0x61,0x01) /* ______S___ */ #define ASQ_OUT_OF_FOCUS _ASQ(0x61,0x02) /* ______S___ */ #define ASQ_SCAN_HEAD_POSITIONING_ERROR _ASQ(0x62,0x00) /* ______S___ */ #define ASQ_END_OF_USER_AREA_ENCOUNTERED_ON_THIS_TRACK _ASQ(0x63,0x00) /* _____R____ */ #define ASQ_ILLEGAL_MODE_FOR_THIS_TRACK _ASQ(0x64,0x00) /* _____R____ */ bareos-Release-14.2.6/src/ndmp/smc.h000066400000000000000000000124321263011562700171220ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifdef __cplusplus extern "C" { #endif #define SMC_MAX_SENSE_DATA 127 /* carefully layed out so that 16-byte/line hex dumps look nice */ struct smc_scsi_req { unsigned char completion_status; unsigned char status_byte; unsigned char data_dir; unsigned char n_cmd; unsigned char cmd[12]; unsigned char * data; unsigned n_data_avail; unsigned n_data_done; uint32_t _pad; unsigned char n_sense_data; unsigned char sense_data[SMC_MAX_SENSE_DATA]; }; #define SMCSR_CS_GOOD 0 #define SMCSR_CS_FAIL 1 /* more? */ #define SMCSR_DD_NONE 0 #define SMCSR_DD_IN 1 /* adapter->app */ #define SMCSR_DD_OUT 2 /* app->adapter */ struct smc_volume_tag { unsigned char volume_id[32]; uint16_t volume_seq; }; struct smc_element_address_assignment { unsigned mte_addr; /* media transport element */ unsigned mte_count; unsigned se_addr; /* storage element */ unsigned se_count; unsigned iee_addr; /* import/export element */ unsigned iee_count; unsigned dte_addr; /* data transfer element */ unsigned dte_count; }; #define SMC_ELEM_TYPE_ALL 0 #define SMC_ELEM_TYPE_MTE 1 #define SMC_ELEM_TYPE_SE 2 #define SMC_ELEM_TYPE_IEE 3 #define SMC_ELEM_TYPE_DTE 4 struct smc_element_descriptor { unsigned char element_type_code; uint16_t element_address; /* Flags, use SCSI spec names for convenience */ unsigned PVolTag : 1; /* MSID primary vol tag info present */ unsigned AVolTag : 1; /* MSID alternate vol tag present */ unsigned InEnab : 1; /* --I- supports import */ unsigned ExEnab : 1; /* --I- supports export */ unsigned Access : 1; /* -SID access by a MTE allowed */ unsigned Except : 1; /* MSID element in abnormal state */ unsigned ImpExp : 1; /* --I- placed by operator */ unsigned Full : 1; /* MSID contains a unit of media */ unsigned Not_bus : 1; /* ---D if ID_valid, not same bus */ unsigned ID_valid: 1; /* ---D scsi_sid valid */ unsigned LU_valid: 1; /* ---D scsi_lun valid */ unsigned SValid : 1; /* MSID src_se_addr and Invert valid */ unsigned Invert : 1; /* MSID inverted by MOVE/EXCHANGE */ unsigned char asc; /* Additional sense code */ unsigned char ascq; /* Additional sense code qualifier */ uint16_t src_se_addr; /* if Svalid, last *STORAGE* element */ unsigned char scsi_sid; /* if ID_valid, SID of drive */ unsigned char scsi_lun; /* if LU_valid, LUN of drive */ struct smc_volume_tag primary_vol_tag; /* if PVolTag */ struct smc_volume_tag alternate_vol_tag;/* if AVolTag */ }; #ifndef SMC_MAX_ELEMENT #define SMC_MAX_ELEMENT 80 #endif struct smc_ctrl_block { unsigned char ident[32]; unsigned char valid_elem_aa; unsigned char valid_elem_desc; struct smc_element_address_assignment elem_aa; struct smc_element_descriptor elem_desc[SMC_MAX_ELEMENT]; unsigned n_elem_desc; struct smc_scsi_req scsi_req; int (*issue_scsi_req)(struct smc_ctrl_block *smc); void * app_data; int dont_ask_for_voltags; char errmsg[64]; }; extern int smc_inquire (struct smc_ctrl_block *smc); extern int smc_test_unit_ready (struct smc_ctrl_block *smc); extern int smc_get_elem_aa (struct smc_ctrl_block *smc); extern int smc_init_elem_status (struct smc_ctrl_block *smc); extern int smc_read_elem_status (struct smc_ctrl_block *smc); extern int smc_move (struct smc_ctrl_block *smc, unsigned from_addr, unsigned to_addr, int invert, unsigned chs_addr); extern int smc_position (struct smc_ctrl_block *smc, unsigned to_addr, int invert); extern int smc_handy_move_to_drive (struct smc_ctrl_block *smc, unsigned from_se_ix); extern int smc_handy_move_from_drive (struct smc_ctrl_block *smc, unsigned to_se_ix); extern char * smc_elem_type_code_to_str(int code); extern int smc_pp_element_address_assignments ( struct smc_element_address_assignment *eaa, int lineno, char *buf); extern int smc_pp_element_descriptor (struct smc_element_descriptor *edp, int lineno, char *ret_buf); #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/ndmp/smc_api.c000066400000000000000000000325601263011562700177520ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "smc_priv.h" #include "scsiconst.h" int smc_scsi_xa (struct smc_ctrl_block *smc) { int try = 0; int rc; int sense_key; unsigned char * sense_data = smc->scsi_req.sense_data; for (try = 0; try < 2; try++) { rc = (*smc->issue_scsi_req)(smc); if (rc || smc->scsi_req.completion_status != SMCSR_CS_GOOD) { strcpy (smc->errmsg, "SCSI request failed"); if (rc == 0) rc = -1; continue; /* retry */ } switch (SCSI_STATUS_BYTE_CODE(smc->scsi_req.status_byte)) { case SCSI_STATUS_GOOD: return 0; case SCSI_STATUS_CHECK_CONDITION: /* sense data processed below */ break; default: strcpy (smc->errmsg, "SCSI unexpected status"); return -1; } sense_key = sense_data[2] & SCSI_SENSE_SENSE_KEY_MASK; if (sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION) { int valid; int asc, ascq, asq, cmd; long info; valid = sense_data[0] & SCSI_SENSE_VALID_BIT; info = SMC_GET4(&sense_data[3]); asc = sense_data[12]; ascq = sense_data[13]; asq = _ASQ(asc,ascq); cmd = smc->scsi_req.cmd[0]; sprintf (smc->errmsg, "SCSI attn s0=%x asq=%x,%x cmd=%x info=%lx", sense_data[0], asc, ascq, cmd, info); rc = 1; } else { strcpy (smc->errmsg, "SCSI check condition"); rc = 1; break; /* don't retry, investigate */ } } if (!rc) rc = -1; return rc; } #define SINQ_MEDIA_CHANGER 0x08 int smc_inquire (struct smc_ctrl_block *smc) { struct smc_scsi_req * sr = &smc->scsi_req; unsigned char data[128]; int rc; int i; bzero (sr, sizeof *sr); bzero (data, sizeof data); sr->n_cmd = 6; sr->cmd[0] = SCSI_CMD_INQUIRY; sr->cmd[4] = sizeof data; /* allocation length */ sr->data = data; sr->n_data_avail = sizeof data; sr->data_dir = SMCSR_DD_IN; rc = smc_scsi_xa (smc); if (rc != 0) return rc; if (data[0] != SINQ_MEDIA_CHANGER) { strcpy (smc->errmsg, "Not a media changer"); return -1; } for (i = 28-1; i >= 0; i--) { int c = data[8+i]; if (c != ' ') break; } for (; i >= 0; i--) { int c = data[8+i]; if (! (' ' <= c && c < 0x7F)) c = '*'; smc->ident[i] = c; } return 0; } int smc_test_unit_ready (struct smc_ctrl_block *smc) { struct smc_scsi_req * sr = &smc->scsi_req; int rc; bzero (sr, sizeof *sr); sr->n_cmd = 6; sr->cmd[0] = SCSI_CMD_TEST_UNIT_READY; rc = smc_scsi_xa (smc); return rc; } int smc_get_elem_aa (struct smc_ctrl_block *smc) { struct smc_scsi_req * sr = &smc->scsi_req; unsigned char data[256]; int rc; bzero (sr, sizeof *sr); bzero (data, sizeof data); bzero (&smc->elem_aa, sizeof smc->elem_aa); smc->valid_elem_aa = 0; sr->n_cmd = 6; sr->cmd[0] = SCSI_CMD_MODE_SENSE_6; sr->cmd[1] = 0x08; /* DBD */ sr->cmd[2] = 0x1D; /* current elem addrs */ sr->cmd[3] = 0; /* reserved */ sr->cmd[4] = 255; /* allocation length */ sr->cmd[5] = 0; /* reserved */ sr->data = data; sr->n_data_avail = 255; sr->data_dir = SMCSR_DD_IN; rc = smc_scsi_xa (smc); if (rc != 0) return rc; if (data[0] < 18) { strcpy (smc->errmsg, "short sense data"); return -1; } rc = smc_parse_element_address_assignment ((void*)&data[4], &smc->elem_aa); if (rc) { strcpy (smc->errmsg, "elem_addr_assignment format error"); return -1; } smc->valid_elem_aa = 1; return 0; } /* * 17.2.2 INITIALIZE ELEMENT STATUS command * * The INITIALIZE ELEMENT STATUS command (see table 329) will cause the * medium changer to check all elements for medium and any other status * relevant to that element. The intent of this command is to enable the * initiator to get a quick response from a following READ ELEMENT STATUS * command. It may be useful to issue this command after a power failure, * or if medium has been changed by an operator, or if configurations have * been changed. * * Table 329 - INITIALIZE ELEMENT STATUS command * +====-=======-========-========-========-========-========-========-======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+====================================================================| * | 0 | Operation code (07h) | * |----+--------------------------------------------------------------------| * | 1 |Logical unit number | Reserved | * |----+--------------------------------------------------------------------| * | 2 | Reserved | * |----+--------------------------------------------------------------------| * | 3 | Reserved | * |----+--------------------------------------------------------------------| * | 4 | Reserved | * |----+--------------------------------------------------------------------| * | 5 | Control | * +=========================================================================+ */ int smc_init_elem_status (struct smc_ctrl_block *smc) { struct smc_scsi_req * sr = &smc->scsi_req; int rc; bzero (sr, sizeof *sr); sr->n_cmd = 6; sr->cmd[0] = SCSI_CMD_INITIALIZE_ELEMENT_STATUS; sr->data_dir = SMCSR_DD_NONE; rc = smc_scsi_xa (smc); if (rc != 0) return rc; return 0; } /* * 17.2.5 READ ELEMENT STATUS command * * The READ ELEMENT STATUS command (see table 332) requests that the * target report the status of its internal elements to the initiator. * * Table 332 - READ ELEMENT STATUS command * +====-=======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+=====================================================================| * | 0 | Operation code (B8h) | * |----+---------------------------------------------------------------------| * | 1 |Logical unit number | VolTag | Element type code | * |----+---------------------------------------------------------------------| * | 2 |(MSB) | * |----+-- Starting element address --| * | 3 | (LSB)| * |----+---------------------------------------------------------------------| * | 4 |(MSB) | * |----+-- Number of elements --| * | 5 | (LSB)| * |----+---------------------------------------------------------------------| * | 6 | Reserved | * |----+---------------------------------------------------------------------| * | 7 |(MSB) | * |----+-- --| * | 8 | Allocation length | * |----+-- --| * | 9 | (LSB)| * |----+---------------------------------------------------------------------| * |10 | Reserved | * |----+---------------------------------------------------------------------| * |11 | Control | * +==========================================================================+ * * * A volume tag (VolTag) bit of one indicates that the target shall report * volume tag information if this feature is supported. A value of zero * indicates that volume tag information shall not be reported. If the * volume tag feature is not supported this field shall be treated as * reserved. * * The element type code field specifies the particular element type(s) * selected for reporting by this command. A value of zero specifies that * status for all element types shall be reported. The element type codes * are defined in table 333. * * Table 333 - Element type code * +=============-===================================================+ * | Code | Description | * |-------------+---------------------------------------------------| * | 0h | All element types reported, (valid in CDB only) | * | 1h | Medium transport element | * | 2h | Storage element | * | 3h | Import export element | * | 4h | Data transfer element | * | 5h - Fh | Reserved | * +=================================================================+ * * * The starting element address specifies the minimum element address to * report. Only elements with an element type code permitted by the * element type code specification, and an element address greater than or * equal to the starting element address shall be reported. Element * descriptor blocks are not generated for undefined element addresses. * * The number of elements specifies the maximum number of element * descriptors to be created by the target for this command. The value * specified by this field is not the range of element addresses to be * considered for reporting but rather the number of defined elements to * report. If the allocation length is not sufficient to transfer all the * element descriptors, the target shall transfer all those descriptors * that can be completely transferred and this shall not be considered an * error. */ int smc_read_elem_status (struct smc_ctrl_block *smc) { struct smc_scsi_req * sr = &smc->scsi_req; unsigned char data[8192]; int rc; retry: bzero (sr, sizeof *sr); bzero (data, sizeof data); bzero (&smc->elem_desc, sizeof smc->elem_desc); smc->n_elem_desc = 0; smc->valid_elem_desc = 0; sr->n_cmd = 12; sr->cmd[0] = SCSI_CMD_READ_ELEMENT_STATUS; if (!smc->dont_ask_for_voltags) { sr->cmd[1] = 0x10; /* VolTag, all types */ } else { sr->cmd[1] = 0x00; /* !VolTag, all types */ } sr->cmd[2] = 0; /* starting elem MSB */ sr->cmd[3] = 0; /* starting elem LSB */ sr->cmd[4] = 0; /* number of elem MSB */ sr->cmd[5] = SMC_MAX_ELEMENT; /* number of elem LSB */ sr->cmd[6] = 0; /* reserved */ SMC_PUT3 (&sr->cmd[7], sizeof data); sr->cmd[10] = 0; /* reserved */ sr->data = data; sr->n_data_avail = sizeof data; sr->data_dir = SMCSR_DD_IN; rc = smc_scsi_xa (smc); if (rc != 0) { if (smc->dont_ask_for_voltags) return rc; smc->dont_ask_for_voltags = 1; goto retry; } rc = smc_parse_element_status_data ((void*)data, sr->n_data_done, smc->elem_desc, SMC_MAX_ELEMENT); if (rc < 0) { strcpy (smc->errmsg, "elem_status format error"); return -1; } smc->n_elem_desc = rc; smc->valid_elem_aa = 1; return 0; } int smc_move (struct smc_ctrl_block *smc, unsigned from_addr, unsigned to_addr, int invert, unsigned chs_addr) { struct smc_scsi_req * sr = &smc->scsi_req; int rc; bzero (sr, sizeof *sr); sr->n_cmd = 12; sr->cmd[0] = SCSI_CMD_MOVE_MEDIUM; SMC_PUT2(&sr->cmd[2], chs_addr); SMC_PUT2(&sr->cmd[4], from_addr); SMC_PUT2(&sr->cmd[6], to_addr); /* TODO: invert */ sr->data_dir = SMCSR_DD_NONE; rc = smc_scsi_xa (smc); if (rc != 0) return rc; return 0; } int smc_position (struct smc_ctrl_block *smc, unsigned to_addr, int invert) { return -1; } int smc_handy_move_to_drive (struct smc_ctrl_block *smc, unsigned from_se_ix) { return -1; } int smc_handy_move_from_drive (struct smc_ctrl_block *smc, unsigned to_se_ix) { return -1; } bareos-Release-14.2.6/src/ndmp/smc_parse.c000066400000000000000000000120721263011562700203070ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "smc_priv.h" #define WITH(P,V,T) { T * V = (T *) P; #define ENDWITH } int smc_parse_volume_tag ( struct smc_raw_volume_tag *raw, struct smc_volume_tag *vtag) { int i; bzero (vtag, sizeof *vtag); for (i = 31; i >= 0 && raw->volume_id[i] == ' '; i--) continue; for (; i >= 0; i--) vtag->volume_id[i] = raw->volume_id[i]; vtag->volume_seq = SMC_GET2(raw->volume_seq); return 0; } int smc_parse_element_status_data ( char * raw, unsigned raw_len, struct smc_element_descriptor elem_desc[], unsigned max_elem_desc) { unsigned char * p = (unsigned char *)raw; unsigned char * raw_end = p + raw_len; unsigned int n_elem = 0; bzero (elem_desc, sizeof elem_desc[0] * max_elem_desc); WITH(p, esdh, struct smc_raw_element_status_data_header) unsigned byte_count = SMC_GET3(esdh->byte_count); if (raw_len > byte_count+8) { /* probably an error, but press on */ raw_len = byte_count+8; } raw_end = p + raw_len; ENDWITH p += 8; while (p+8 < raw_end) { /* +8 for sizeof *esph */ WITH(p, esph, struct smc_raw_element_status_page_header) unsigned desc_size = SMC_GET2(esph->elem_desc_len); unsigned byte_count = SMC_GET3(esph->byte_count); unsigned elem_type = esph->element_type; unsigned char * pgend = p + byte_count + 8; int PVolTag = 0; int AVolTag = 0; if (pgend > raw_end) { /* malformed, really, but punt */ pgend = raw_end; } if (esph->flag1 & SMC_RAW_ESP_F1_PVolTag) PVolTag = 1; if (esph->flag1 & SMC_RAW_ESP_F1_AVolTag) AVolTag = 1; p += 8; for (;p + desc_size <= pgend; p += desc_size) { struct smc_element_descriptor *edp; if (n_elem >= max_elem_desc) { /* bust out */ goto done; } edp = &elem_desc[n_elem++]; WITH (p, red, struct smc_raw_element_descriptor) unsigned char *p2; edp->element_type_code = elem_type; edp->element_address = SMC_GET2(red->element_address); edp->PVolTag = PVolTag; edp->AVolTag = AVolTag; #define FLAG(RAWMEM,BIT,MEM) if (red->RAWMEM & BIT) edp->MEM = 1; FLAG(flags2, SMC_RAW_ED_F2_Full, Full); FLAG(flags2, SMC_RAW_ED_F2_ImpExp, ImpExp); FLAG(flags2, SMC_RAW_ED_F2_Except, Except); FLAG(flags2, SMC_RAW_ED_F2_Access, Access); FLAG(flags2, SMC_RAW_ED_F2_ExEnab, ExEnab); FLAG(flags2, SMC_RAW_ED_F2_InEnab, InEnab); edp->asc = red->asc; edp->ascq = red->ascq; edp->scsi_lun = red->flags6 & 7; FLAG(flags6, SMC_RAW_ED_F6_LU_valid, LU_valid); FLAG(flags6, SMC_RAW_ED_F6_ID_valid, ID_valid); FLAG(flags6, SMC_RAW_ED_F6_Not_bus, Not_bus); edp->scsi_sid = red->scsi_sid; FLAG(flags9, SMC_RAW_ED_F9_Invert, Invert); FLAG(flags9, SMC_RAW_ED_F9_SValid, SValid); #undef FLAG edp->src_se_addr = SMC_GET2(red->src_se_addr); p2 = (unsigned char *) &red->data; if (edp->PVolTag) { smc_parse_volume_tag ((void*)p2, &edp->primary_vol_tag); p2 += SMC_VOL_TAG_LEN; } if (edp->AVolTag) { smc_parse_volume_tag ((void*)p2, &edp->alternate_vol_tag); p2 += SMC_VOL_TAG_LEN; } p2 += 4; /* resv84 */ /* p2 ready for vendor_specific */ ENDWITH } p = pgend; ENDWITH } done: return n_elem; } int smc_parse_element_address_assignment ( struct smc_raw_element_address_assignment_page *raw, struct smc_element_address_assignment *eaa) { eaa->mte_addr = SMC_GET2(raw->mte_addr); eaa->mte_count = SMC_GET2(raw->mte_count); eaa->se_addr = SMC_GET2(raw->se_addr); eaa->se_count = SMC_GET2(raw->se_count); eaa->iee_addr = SMC_GET2(raw->iee_addr); eaa->iee_count = SMC_GET2(raw->iee_count); eaa->dte_addr = SMC_GET2(raw->dte_addr); eaa->dte_count = SMC_GET2(raw->dte_count); return 0; } bareos-Release-14.2.6/src/ndmp/smc_pp.c000066400000000000000000000107151263011562700176160ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "smc_priv.h" static char *strend(char *s); char * smc_elem_type_code_to_str(int code) { switch (code) { case SMC_ELEM_TYPE_ALL: return "ALL"; case SMC_ELEM_TYPE_MTE: return "ARM"; case SMC_ELEM_TYPE_SE: return "SLOT"; case SMC_ELEM_TYPE_IEE: return "IEE"; case SMC_ELEM_TYPE_DTE: return "TAPE"; default: return "???"; } } int smc_pp_element_address_assignments (struct smc_element_address_assignment *eaa, int lineno, char *buf) { sprintf (buf, "slots %d@%d drive %d@%d arm %d@%d i/e %d@%d", eaa->se_count, eaa->se_addr, eaa->dte_count, eaa->dte_addr, eaa->mte_count, eaa->mte_addr, eaa->iee_count, eaa->iee_addr); return 1; } int smc_pp_element_descriptor (struct smc_element_descriptor *edp, int lineno, char *ret_buf) { int nline = 0; char buf[100]; *ret_buf = 0; *buf = 0; sprintf (buf, "@%-3d %-4s", edp->element_address, smc_elem_type_code_to_str(edp->element_type_code)); if (edp->Full) strcat (buf, " Full "); else strcat (buf, " Empty"); if (edp->element_type_code == SMC_ELEM_TYPE_MTE) { if (edp->Access) { /* unusual for MTE */ /* actually not defined */ strcat (buf, " ?access=granted?"); } } else { if (!edp->Access) { /* unusual for all non-MTE elements */ strcat (buf, " ?access=denied?"); } } if (edp->PVolTag && edp->Full) { sprintf (strend(buf), " PVolTag(%s,#%d)", edp->primary_vol_tag.volume_id, edp->primary_vol_tag.volume_seq); } if (edp->Except) { sprintf (strend(buf), " Except(asc=%02x,ascq=%02x)", edp->asc, edp->ascq); } if (*buf && nline++ == lineno) strcpy (ret_buf, buf); *buf = 0; #define INDENT_SPACES " " /* 10 spaces */ if (edp->AVolTag) { sprintf (buf, INDENT_SPACES "AVolTag(%s,#%d)", edp->alternate_vol_tag.volume_id, edp->alternate_vol_tag.volume_seq); } if (*buf && nline++ == lineno) strcpy (ret_buf, buf); *buf = 0; if (edp->SValid) { sprintf (buf, INDENT_SPACES "SValid(src=%d,%sinvert)", edp->src_se_addr, edp->Invert ? "" : "!"); } if (*buf && nline++ == lineno) strcpy (ret_buf, buf); *buf = 0; if (edp->element_type_code == SMC_ELEM_TYPE_DTE) { strcpy (buf, INDENT_SPACES); if (edp->ID_valid) { sprintf (strend(buf), "ID sid=%d", edp->scsi_sid); } else { strcat (buf, "no-sid-data"); } if (edp->LU_valid) { sprintf (strend(buf), " lun=%d", edp->scsi_lun); } else { strcat (buf, " no-lun-data"); } if (edp->ID_valid && edp->Not_bus) { strcat (buf, " not-same-bus"); } } if (*buf && nline++ == lineno) strcpy (ret_buf, buf); *buf = 0; if (edp->element_type_code == SMC_ELEM_TYPE_IEE) { strcpy (buf, INDENT_SPACES); if (edp->InEnab) strcat (buf, " can-import"); else strcat (buf, " can-not-import"); if (edp->ExEnab) strcat (buf, " can-export"); else strcat (buf, " can-not-export"); if (edp->ImpExp) strcat (buf, " by-oper"); else strcat (buf, " by-mte"); } if (*buf && nline++ == lineno) strcpy (ret_buf, buf); *buf = 0; return nline; } static char * strend (char *s) { while (*s) s++; return s; } bareos-Release-14.2.6/src/ndmp/smc_priv.h000066400000000000000000000037551263011562700201720ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" /* obtains prototypes */ #include "smc_raw.h" #include "smc.h" #ifdef __cplusplus extern "C" { #endif extern int smc_parse_volume_tag ( struct smc_raw_volume_tag *raw, struct smc_volume_tag *vtag); extern int smc_parse_element_status_data ( char * raw, unsigned raw_len, struct smc_element_descriptor elem_desc[], unsigned max_elem_desc); extern int smc_parse_element_address_assignment ( struct smc_raw_element_address_assignment_page *raw, struct smc_element_address_assignment *eaa); #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/ndmp/smc_raw.h000066400000000000000000001543361263011562700200050ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #ifdef __cplusplus extern "C" { #endif /* * 17.1 Medium-changer device model * * Medium changer devices mechanize the movement of media to and from * primary devices (such as disk or tape drives) and other locations * within the range of the medium changer. The medium changer command set * is based on a physical model of this functionality. * * This command set supports varied physical implementations of the medium * changer function. Most of these variations are hidden from the * initiator by the high level of function provided by the MOVE MEDIUM and * EXCHANGE MEDIUM commands and by the generalized nature of the element * addressing scheme. However, initiators may need to be aware of the * capabilities of the particular medium changer device. These * characteristics and capabilities are conveyed via MODE SENSE pages. * * 17.1.1 Medium-changer elements * * The medium-changer command set uses as its address space the set of * physical locations and mechanisms within the scope of a medium changer * device. The term element is used throughout this clause to refer to one * member of the medium changer address space. Each element is a discrete * physical entity that may hold zero or one physical unit of media - one * disk cartridge, one spool of tape, etc. Element addresses do not extend * across multiple physical units of media. Likewise, element addresses * are independent of any logical partitioning that the primary device may * support within a physical unit of media. * * A medium changer is viewed as a set of addressable elements, each of * which may contain a unit of media or be used to move a unit of media. * Each medium changer element has a unique 16 bit element address. Each * element is an instance of one of four classes or element types. * * a) MEDIUM TRANSPORT ELEMENT * b) STORAGE ELEMENT * c) IMPORT EXPORT ELEMENT * d) DATA TRANSFER ELEMENT * * Units of media (cartridges, cassettes, caddies, etc.) are referred to * only indirectly by this device model. Units of media can be moved to * or from any of the elements of the medium changer device. The presence * of media at the various elements in a medium changer can be sensed. In * order to ensure exclusive access to a unit of media, the element where * the unit of media is located (the element address) must be reserved. * * Elements of the medium transport, import export and (rarely) data * transport types may not provide independent storage for medium. The * capabilities of a particular medium changer in this respect can be * sensed via the device capabilities page of the mode sense data. The * following hypothetical medium changer implementation illustrates one * case of an element not providing independent storage for medium. * Consider a medium changer which has a carousel style storage for * medium. The import export function could be provided by a port which * allows operator access to one of the storage elements. In such a * device, the MOVE ELEMENT command from storage element to import export * element would rotate the carousel to align the addressed storage * element to the import export position. In this case the import export * element does not provide independent storage but rather access to one * of the storage elements. * * 17.1.1.1 Medium transport elements * * Medium transport elements address the functions of the medium changer * device that perform the movement of units of media. Where a medium * transport element can serve (even temporarily) as a storage location * for medium, the location of each unit of media must have a separate * element address. * * In larger medium changer devices, the medium movement functions may be * performed by multiple independent robotics subsystems. Each of these * may have a number of medium transport element addresses. The element * addresses within each subsystem shall be contiguous. Any of the element * addresses within a subsystem may be used interchangeably in the medium * transport element address field of MOVE MEDIUM and EXCHANGE MEDIUM * commands. An initiator may determine the capabilities of the medium * movement facilities of a medium changer device via the transport * geometry MODE SENSE page, see 17.3.3.3. * * Element address zero is reserved for use in the medium transport * element address field of MOVE MEDIUM and EXCHANGE MEDIUM commands to * direct the medium changer to use a default or medium changer selected * medium transport element. * * In some implementations, medium transport elements may be source and/or * destination addresses in MOVE MEDIUM and EXCHANGE MEDIUM commands. * They may or may not provide independent storage of a unit of media. * See the device capabilities MODE SENSE page, see 17.3.3. * * 17.1.1.2 Storage elements * * Storage elements are locations of units of media while not in some * other element type. Medium in storage elements is available for access * by medium transport elements. * * Storage elements may be source and/or destination addresses in MOVE * MEDIUM and EXCHANGE MEDIUM commands. * * 17.1.1.3 Import export elements * * Import export elements are locations of units of media which are being * inserted into or withdrawn from the medium changer device. Medium in * these elements is accessible by both medium transport elements, by the * operator, or by another independent medium changer device. * * Import export elements may be source and/or destination addresses in * MOVE MEDIUM and EXCHANGE MEDIUM commands. They may or may not provide * independent storage of a unit of media, see the device capabilities * MODE SENSE page, see 17.3.3. * * Particular import export elements may be capable of either import * actions, export actions, both or neither (if an element is not * present). * * 17.1.1.4 Data transfer element * * Data transfer elements are locations of the primary devices which are * capable of reading or writing the medium. Data transfer elements may * also be viewed as medium changer element addresses of units of media * loaded in or available for loading in or removal from primary devices * such as disk or tape drives. Note that the medium changer function * specified in this clause does not control the primary device. That is * the responsibility of the system. * * Data transfer elements may be source and/or destination addresses in * MOVE MEDIUM and EXCHANGE MEDIUM commands. They may or may not provide * independent storage of a unit of media, see the device capabilities * MODE SENSE page, see 17.3.3. */ /* * Table 333 - Element type code * +=============-===================================================+ * | Code | Description | * |-------------+---------------------------------------------------| * | 0h | All element types reported, (valid in CDB only) | * | 1h | Medium transport element | * | 2h | Storage element | * | 3h | Import export element | * | 4h | Data transfer element | * | 5h - Fh | Reserved | * +=================================================================+ */ #define SMC_ELEM_TYPE_ALL 0 #define SMC_ELEM_TYPE_MTE 1 #define SMC_ELEM_TYPE_SE 2 #define SMC_ELEM_TYPE_IEE 3 #define SMC_ELEM_TYPE_DTE 4 /* * 17.1.5 Volume tags * * The read element status descriptor format for all element types * includes two sets of fields that contain volume tag information. These * optional fields are used to report media identification information * that the medium changer has acquired either by reading an external * label (e.g. bar code labels), by a SEND VOLUME TAG command or by other * means which may be vendor unique. The same volume tag information shall * be available to all initiators whether assigned by that initiator, by * some other initiator or by the media changer itself. * * Volume tag information provides a means to confirm the identity of a * unit of media that resides in a medium changer element. This command * set does not define any direct addressing of units of media based on * these fields. However, commands are defined that provide translation * between volume tag information and the element address where that unit * of media currently resides. * * The medium changer command set definition does not impose the * requirement that volume tag information be unique over the units of * media within the scope of the changer device. * * The following commands support the optional volume tag functionality: * a) SEND VOLUME TAG - either as a translation request or to associate * a volume tag with the unit of media currently residing at an * element address. * b) REQUEST VOLUME ELEMENT ADDRESS - return the element address * currently associated with the volume tag information transferred * with the last send volume tag command. * c) READ ELEMENT STATUS - optionally reports volume tag information * for all element types. * d) MOVE MEDIUM and EXCHANGE MEDIUM commands - if volume tags are * implemented, these commands must retain the association between * volume tag information and units of media as they are moved from * element to element. * * 17.1.5.1 Volume tag format * * Volume tag information consists of a volume identifier field of 32 * bytes plus a volume sequence number field of 2 bytes. The volume * identifier shall consist of a left justified sequence of ASCII * characters. Unused positions shall be blank (20h) filled. In order for * the SEND VOLUME TAG translate with template to work the characters '*' * and'?' (2Ah and 3Fh) must not appear in volume identification data and * there must be no blanks (20h) within the significant part of the volume * identifier. If volume tag information for a particular element is * undefined, the volume identifier field shall be zero. * * The volume sequence number is a 2 byte integer field. If the volume * sequence number is not used this field shall be zero. The volume tag * contents are independent of the volume identification information * recorded on the media. * * NOTE 199 For compatibility with the volume identifier defined by volume * and file structure standards, it is recommended that the characters in the * significant non-blank portion of the volume identifier field be restricted * to the set: '0'..'9', 'A'..'Z', and '_' (30h .. 39h, 41h .. 5Ah, 5Fh). * Specific systems may have differing requirements that may take precedence * over this recommendation. * * Table 326 defines the fields within the 36 byte primary and alternate * volume tag information fields found in READ ELEMENT STATUS descriptors * and in the data format for the SEND VOLUME TAG command. * * Table 326 - Volume tag information format * +=====-=======-=======-=======-========-========-========-=======-========+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte | | | | | | | | | * |=====+===================================================================| * | 0 | | * |- - -+--- Volume identification field ---| * | 31 | | * |-----+-------------------------------------------------------------------| * | 32 | | * |- - -+--- Reserved ---| * | 33 | | * |-----+-------------------------------------------------------------------| * | 34 | (MSB) | * |-----+--- Volume sequence number ---| * | 35 | (LSB) | * +=========================================================================+ * * * 17.1.5.2 Primary and alternate volume tag information * * Element status descriptors as reported by the READ ELEMENT STATUS * command define a primary volume tag and an alternate volume tag. * Alternate volume tag information provides a means for a system to use * different volume identification information for each side of double * sided media. In such a system, the primary volume tag information * refers to the logical medium accessible via a MOVE MEDIUM command * without the invert bit set. The alternate volume tag information refers * to the other side of the media, i.e. the side that would be accessed * via a MOVE MEDIUM command with the invert bit set. */ #define SMC_VOL_TAG_LEN 36 struct smc_raw_volume_tag { unsigned char volume_id[32]; unsigned char resv32[2]; unsigned char volume_seq[2]; }; /* * 17.1.4 Element status maintenance requirements * * If the medium changer device chooses to implement the READ ELEMENT * STATUS command, the medium changer device must be capable of reporting * the various data (i.e. full, error, etc.) required by each page type. * The medium changer may maintain this information at all times or * regenerate it in response to the READ ELEMENT STATUS command. The * INITIALIZE ELEMENT STATUS command can be used to force regeneration of * this information. */ /* * 17.2.5 READ ELEMENT STATUS command * * The READ ELEMENT STATUS command (see table 332) requests that the * target report the status of its internal elements to the initiator. * * Table 332 - READ ELEMENT STATUS command * +====-=======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+=====================================================================| * | 0 | Operation code (B8h) | * |----+---------------------------------------------------------------------| * | 1 |Logical unit number | VolTag | Element type code | * |----+---------------------------------------------------------------------| * | 2 |(MSB) | * |----+-- Starting element address --| * | 3 | (LSB)| * |----+---------------------------------------------------------------------| * | 4 |(MSB) | * |----+-- Number of elements --| * | 5 | (LSB)| * |----+---------------------------------------------------------------------| * | 6 | Reserved | * |----+---------------------------------------------------------------------| * | 7 |(MSB) | * |----+-- --| * | 8 | Allocation length | * |----+-- --| * | 9 | (LSB)| * |----+---------------------------------------------------------------------| * |10 | Reserved | * |----+---------------------------------------------------------------------| * |11 | Control | * +==========================================================================+ * * * A volume tag (VolTag) bit of one indicates that the target shall report * volume tag information if this feature is supported. A value of zero * indicates that volume tag information shall not be reported. If the * volume tag feature is not supported this field shall be treated as * reserved. * * The element type code field specifies the particular element type(s) * selected for reporting by this command. A value of zero specifies that * status for all element types shall be reported. The element type codes * are defined in table 333. * * Table 333 - Element type code * (SEE ABOVE) * * The starting element address specifies the minimum element address to * report. Only elements with an element type code permitted by the * element type code specification, and an element address greater than or * equal to the starting element address shall be reported. Element * descriptor blocks are not generated for undefined element addresses. * * The number of elements specifies the maximum number of element * descriptors to be created by the target for this command. The value * specified by this field is not the range of element addresses to be * considered for reporting but rather the number of defined elements to * report. If the allocation length is not sufficient to transfer all the * element descriptors, the target shall transfer all those descriptors * that can be completely transferred and this shall not be considered an * error. * * 17.2.5.1 Element status data * * The data returned by the READ ELEMENT STATUS command is defined in * table 334 and 17.2.5.3 through 17.2.5.6. Element status data consists * of an eight-byte header, (see table 334) followed by one or more * element status pages. * * Table 334 - Element status data * +====-=======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+=====================================================================| * | 0 |(MSB) | * |----+-- First element address reported --| * | 1 | (LSB)| * |----+---------------------------------------------------------------------| * | 2 |(MSB) | * |----+-- Number of elements available --| * | 3 | (LSB)| * |----+---------------------------------------------------------------------| * | 4 | Reserved | * |----+---------------------------------------------------------------------| * | 5 |(MSB) | * |----+-- --| * | 6 | Byte count of report available | * |----+-- (all pages, n - 7 ) --| * | 7 | (LSB)| * |====+=====================================================================| * | 8 | | * |- - +-- Element status page(s) --| * | n | | * +==========================================================================+ * * * The first element address reported field indicates the element address * of the element with the smallest element address found to meet the CDB * request. * * The number of elements available field indicates the number of elements * meeting the request in the command descriptor block. The status for * these elements is returned if sufficient allocation length was * specified. * * The byte count of report available field indicates the number of bytes * of element status page data available for all elements meeting the * request in the command descriptor block. This value shall not be * adjusted to match the allocation length available. * * NOTE 202 - The READ ELEMENT STATUS command can be issued with an * allocation length of eight bytes in order to determine the allocation * length required to transfer all the element status data specified by the * command. * * Figure 28 provides an illustration of the element status data * structure. * * Figure 28 - Illustration of element status data structure * * * 17.2.5.2 Element status page * * The element status page is defined in table 335. Each element status * page includes an eight-byte header followed by one or more element * descriptor blocks. The header includes the element type code, the * length of each descriptor block and the number of bytes of element * descriptor information that follow the header for this element type. * * Table 335 - Element status page * +====-=======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+=====================================================================| * | 0 | Element type code | * |----+---------------------------------------------------------------------| * | 1 |PVolTag| AVolTag| Reserved | * |----+---------------------------------------------------------------------| * | 2 |(MSB) | * |----+-- Element descriptor length --| * | 3 | (LSB)| * |----+---------------------------------------------------------------------| * | 4 | Reserved | * |----+---------------------------------------------------------------------| * | 5 |(MSB) | * |----+-- --| * | 6 | Byte count of descriptor data available | * |----+-- (this page, n - 7) --| * | 7 | (LSB)| * |====+=====================================================================| * | 8 | | * |- - +-- Element descriptor(s) --| * | n | | * +==========================================================================+ * * * The element type code field indicates the element type reported by this * page. * * A primary volume tag (PVolTag) bit of one indicates that the primary * volume tag information field is present in each of the following * element descriptor blocks. A value of zero indicates that these bytes * are omitted from the element descriptors that follow. * * An alternate volume tag (AVolTag) bit of one indicates that the * alternate volume tag information field is present in each of the * following element descriptor blocks. A value of zero indicates that * these bytes are omitted from the element descriptors that follow. * * The element descriptor length field indicates the number of bytes in * each element descriptor. * * The byte count of descriptor data available field indicates the number * of bytes of element descriptor data available for elements of this * element type meeting the request in the CDB. This value shall not be * adjusted to match the allocation length available. * * Each element descriptor includes the element address and status flags; * it may also contain sense code information as well as other information * depending on the element type (see 17.2.5.3 through 17.2.5.6). * * 17.2.5.3 Medium transport element descriptor * * Table 336 defines the medium transport element descriptor. * * Table 336 - Medium transport element descriptor * +====-======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+====================================================================| * | 0 |(MSB) | * |----+-- Element address --| * | 1 | (LSB)| * |----+--------------------------------------------------------------------| * | 2 | Reserved | Except |Reserved| Full | * |----+--------------------------------------------------------------------| * | 3 | Reserved | * |----+--------------------------------------------------------------------| * | 4 | Additional sense code | * |----+--------------------------------------------------------------------| * | 5 | Additional sense code qualifier | * |----+--------------------------------------------------------------------| * | 6 | | * | - -+-- Reserved --| * | 8 | | * |----+--------------------------------------------------------------------| * | 9 |SValid| Invert | Reserved | * |----+--------------------------------------------------------------------| * |10 |(MSB) | * |----+-- Source storage element address --| * |11 | (LSB) | * |----+--------------------------------------------------------------------| * |12 | | * | - -+-- Primary volume tag information --| * |47 | (Field omitted if PVolTag = 0) | * |----+--------------------------------------------------------------------| * |48 | | * | - -+-- Alternate volume tag information --| * |83 | (Field omitted if AVolTag = 0) | * |----+--------------------------------------------------------------------| * |84 | | * | - -+-- Reserved --| * |87 | (Field moved up if volume tag information field(s) are omitted.) | * |----+--------------------------------------------------------------------| * |88 | | * | - -+-- Vendor-specific --| * |z-1 | (Field moved up if volume tag information field(s) are omitted.) | * +=========================================================================+ * * * The element address field gives the address of the medium changer * element whose status is reported by this element descriptor block. * * An exception (Except) bit of one indicates the element is in an * abnormal state. An exception bit of zero indicates the element is in a * normal state. If this bit is one, information on the abnormal state * may be available in the additional sense code and additional sense code * qualifier bytes. * * A full bit value of one indicates that the element contains a unit of * media. A value of zero indicates that the element does not contain a * unit of media. * * The additional sense code field may provide specific information on an * abnormal element state. The values in this field are as defined for * the additional sense code of the REQUEST SENSE data (see 8.2.14.3). * * The additional sense code qualifier field may provide more detailed * information on an abnormal element state. The values in this field are * as defined for the additional sense code qualifier of the REQUEST SENSE * data (see 8.2.14.4). * * A source valid (SValid) bit value of one indicates that the source * storage element address field and the invert bit information are valid. * A value of zero indicates that the values in these fields are not * valid. * * An invert bit value of one indicates that the unit of media now in this * element was inverted by MOVE MEDIUM or EXCHANGE MEDIUM operations since * it was last in the source storage element. A value of zero indicates * that no inversion occurred during the operation. * * The source storage element address field provides the address of the * last storage element this unit of media was moved. This field is valid * only if the SValid bit is one. * * The primary and alternate volume tag information fields provide for * identifying the unit of media residing in this element (see 17.1.5.). * Either or both of these fields may be omitted for all the element * descriptor blocks that comprise an element status page as indicated by * the PVolTag and AVolTag bits in the element status page header. * * 17.2.5.4 Storage element descriptor * * Table 337 defines the storage element descriptor. * * Table 337 - Storage element descriptor * +=====-======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+====================================================================| * | 0 |(MSB) | * |----+-- Element address --| * | 1 | (LSB)| * |----+--------------------------------------------------------------------| * | 2 | Reserved | Access | Except |Reserved| Full | * |----+--------------------------------------------------------------------| * | 3 | Reserved | * |----+--------------------------------------------------------------------| * | 4 | Additional sense code | * |----+--------------------------------------------------------------------| * | 5 | Additional sense code qualifier | * |----+--------------------------------------------------------------------| * | 6 | | * | - -+-- Reserved --| * | 8 | | * |----+--------------------------------------------------------------------| * | 9 |SValid| Invert | Reserved | * |----+--------------------------------------------------------------------| * |10 |(MSB) | * |----+-- Source element address --| * |11 | (LSB) | * |----+--------------------------------------------------------------------| * |12 | | * | - -+-- Primary volume tag information --| * |47 | (Field omitted if PVolTag = 0) | * |----+--------------------------------------------------------------------| * |48 | | * | - -+-- Alternate volume tag information --| * |83 | (Field omitted if PVolTag = 0) | * |----+--------------------------------------------------------------------| * |84 | | * | - -+-- Reserved --| * |87 | (Field moved up if volume tag information field(s) are omitted.) | * |----+--------------------------------------------------------------------| * |88 | | * | - -+-- Vendor unique --| * |z-1 | (Field moved up if volume tag information field(s) are omitted.) | * +=========================================================================+ * * * An access bit value of one indicates that access to the element by a * medium transport element is allowed. An access bit of zero indicates * that access to the element by the medium transport element is denied. * * The source storage element address field provides the address of the * last storage element this unit of media was moved from. This element * address value may or may not be the same as this element. This field is * valid only if the SValid bit is one. * * For fields not defined in this subclause, see 17.2.5.3. * * 17.2.5.5 Import export element descriptor * * Table 338 defines the import export element descriptor. * * Table 338 - Import export element descriptor * +====-======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+====================================================================| * | 0 |(MSB) | * |----+-- Element address --| * | 1 | (LSB)| * |----+--------------------------------------------------------------------| * | 2 | Reserved | InEnab | ExEnab | Access | Except | ImpExp | Full | * |----+--------------------------------------------------------------------| * | 3 | Reserved | * |----+--------------------------------------------------------------------| * | 4 | Additional sense code | * |----+--------------------------------------------------------------------| * | 5 | Additional sense code qualifier | * |----+--------------------------------------------------------------------| * | 6 | | * |----+-- Reserved --| * | 8 | | * |----+--------------------------------------------------------------------| * | 9 |SValid| Invert | Reserved | * |----+--------------------------------------------------------------------| * |10 |(MSB) | * |----+-- Source storage element address --| * |11 | (LSB) | * |----+--------------------------------------------------------------------| * |12 | | * | - -+-- Primary volume tag information --| * |47 | (Field omitted if PVolTag = 0) | * |----+--------------------------------------------------------------------| * |48 | | * | - -+-- Alternate volume tag information --| * |83 | (Field omitted if PVolTag = 0) | * |----+--------------------------------------------------------------------| * |84 | | * | - -+-- Reserved --| * |87 | (Field moved up if volume tag information field(s) are omitted.) | * |----+--------------------------------------------------------------------| * |88 | | * | - -+-- Vendor unique --| * |z-1 | (Field moved up if volume tag information field(s) are omitted.) | * +=========================================================================+ * * * An import enable (InEnab) bit of one indicates that the import export * element supports movement of media into the scope of the medium changer * device. An InEnab bit of zero indicates that this element does not * support import actions. * * An export enable (ExEnab) bit of one indicates that the import export * element supports movement of media out of the scope of the medium * changer device. An ExEnab bit of zero indicates that this element does * not support export actions. * * An access bit of one indicates that access to the import export element * by a medium transport element is allowed. An access bit of zero * indicates access to the import export element by medium transport * elements is denied. * * NOTE 203 An example of when access would be denied is when the operator * has exclusive access to the import export element. * * An import export (ImpExp) bit of one indicates the unit of media in the * import export element was placed there by an operator. An ImpExp bit * of zero indicates the unit of media in the import export element was * placed there by the medium transport element. * * For fields not defined in this clause, see 17.2.5.3. * * 17.2.5.6 Data transfer element descriptor * * Table 339 defines the data transfer element descriptor. * * Table 339 - Data transfer element descriptor * +====-=======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+=====================================================================| * | 0 |(MSB) | * |----+-- Element address --| * | 1 | (LSB)| * |----+---------------------------------------------------------------------| * | 2 | Reserved | Access | Except |Reserved| Full | * |----+---------------------------------------------------------------------| * | 3 | Reserved | * |----+---------------------------------------------------------------------| * | 4 | Additional sense code | * |----+---------------------------------------------------------------------| * | 5 | Additional sense code qualifier | * |----+---------------------------------------------------------------------| * | 6 Not bus|Reserved|ID valid|LU valid|Reserved| Logical unit number | * |----+---------------------------------------------------------------------| * | 7 | SCSI bus address | * |----+---------------------------------------------------------------------| * | 8 | Reserved | * |----+---------------------------------------------------------------------| * | 9 |SValid | Invert | Reserved | * |----+---------------------------------------------------------------------| * |10 |(MSB) | * |----+-- Source storage element address --| * |11 | (LSB) | * |----+---------------------------------------------------------------------| * |12 | | * | - -+-- Primary volume tag information --| * |47 | (Field omitted if PVolTag = 0) | * |----+---------------------------------------------------------------------| * |48 | | * | - -+-- Alternate volume tag information --| * |83 | (Field omitted if PVolTag = 0) | * |----+---------------------------------------------------------------------| * |84 | | * | - -+-- Reserved --| * |87 | (Field moved up if volume tag information field(s) are omitted.) | * |----+---------------------------------------------------------------------| * |88 | | * | - -+-- Vendor unique --| * |z-1 | (Field moved up if volume tag information field(s) are omitted.) | * +==========================================================================+ * * * An access bit value of one indicates access to the data transfer * element by the medium transport element is allowed. A value of zero * indicates access to the data transfer element by a medium transport * element is denied. * * NOTE 204 Access to the data transfer element by medium transport elements * might be denied if a data transfer operation was under way. Note that a * one value in this bit may not be sufficient to ensure a successful * operation. This bit can only reflect the best information available to the * medium changer device, which may not accurately reflect the state of the * primary (data transfer) device. * * A not this bus (not bus) bit value of one indicates that the SCSI bus * address and logical unit number values are not valid for the SCSI bus * used to select the medium changer device. A not bus bit value of zero * indicates that the SCSI address and logical unit values, if valid, are * on the same bus as the medium changer device. * * An ID Valid bit value of one indicates that the SCSI bus address field * contains valid information. An LU Valid bit value of one indicates that * the logical unit number field contains valid information. * * The SCSI bus address field, if valid, provides the SCSI address (binary * representation) of the primary device served by the medium changer at * this element address. * * The logical unit number field, if valid, provides the logical unit * number within the SCSI bus device of the primary device served by the * medium changer at this element address. * * For fields not defined in this clause, see 17.2.5.3. */ struct smc_raw_element_status_data_header { unsigned char first_elem[2]; unsigned char n_elem[2]; unsigned char resv4; unsigned char byte_count[3]; }; struct smc_raw_element_status_page_header { unsigned char element_type; unsigned char flag1; #define SMC_RAW_ESP_F1_PVolTag 0x80 #define SMC_RAW_ESP_F1_AVolTag 0x40 unsigned char elem_desc_len[2]; unsigned char resv4; unsigned char byte_count[3]; }; struct smc_raw_element_descriptor { unsigned char element_address[2]; unsigned char flags2; #define SMC_RAW_ED_F2_Full 0x01 #define SMC_RAW_ED_F2_ImpExp 0x02 #define SMC_RAW_ED_F2_Except 0x04 #define SMC_RAW_ED_F2_Access 0x08 #define SMC_RAW_ED_F2_ExEnab 0x10 #define SMC_RAW_ED_F2_InEnab 0x20 unsigned char resv3; unsigned char asc; unsigned char ascq; unsigned char flags6; #define SMC_RAW_ED_F6_LUN 0x07 #define SMC_RAW_ED_F6_LU_valid 0x10 #define SMC_RAW_ED_F6_ID_valid 0x20 #define SMC_RAW_ED_F6_Not_bus 0x80 unsigned char scsi_sid; unsigned char resv8; unsigned char flags9; #define SMC_RAW_ED_F9_Invert 0x40 #define SMC_RAW_ED_F9_SValid 0x80 unsigned char src_se_addr[2]; /* * primary_vol_tag (optional) * alternate_vol_tag (optional) * resv84 * vendor_specific */ unsigned char data[SMC_VOL_TAG_LEN + SMC_VOL_TAG_LEN + 4 + 4]; }; /* * 17.3.3.2 Element address assignment page * * The element address assignment page (see table 352) is used to assign * addresses to the elements of the medium changer (MODE SELECT) and to * report those assignments (MODE SENSE). This page also defines the * number of each type of element present. * * Table 352 - Element address assignment page * +====-=======-========-========-========-========-========-========-=======+ * | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * |Byte| | | | | | | | | * |====+=======+========+====================================================| * | 0 | PS |Reserved| Page code (1Dh) | * |----+---------------------------------------------------------------------| * | 1 | Parameter length (12h) | * |----+---------------------------------------------------------------------| * | 2 |(MSB) | * |----+-- Medium transport element address --| * | 3 | (LSB)| * |----+---------------------------------------------------------------------| * | 4 |(MSB) | * |----+-- Number of medium transport elements --| * | 5 | (LSB)| * |----+---------------------------------------------------------------------| * | 6 |(MSB) | * |----+-- First storage element address --| * | 7 | (LSB)| * |----+---------------------------------------------------------------------| * | 8 |(MSB) | * |----+-- Number of storage elements --| * | 9 | (LSB)| * |----+---------------------------------------------------------------------| * | 10 |(MSB) | * |----+-- First import export element address --| * | 11 | (LSB)| * |----+---------------------------------------------------------------------| * | 12 |(MSB) | * |----+-- Number of import export elements --| * | 13 | (LSB)| * |----+---------------------------------------------------------------------| * | 14 |(MSB) | * |----+-- First data transfer element address --| * | 15 | (LSB)| * |----+---------------------------------------------------------------------| * | 16 |(MSB) | * |----+-- Number of data transfer elements --| * | 17 | (LSB)| * |----+---------------------------------------------------------------------| * | 18 | | * |----+-- Reserved --| * | 19 | | * +==========================================================================+ * * * The parameters savable (PS) bit is only used with the MODE SENSE * command. This bit is reserved with the MODE SELECT command. A PS bit * of one indicates that the target is capable of saving the page in a * non-volatile vendor-specific location. * * The first medium transport element address field identifies the first * medium transport element contained in the medium changer (other than * the default medium transport address of zero). The number of medium * transport elements field defines the total number of medium transport * elements contained in the medium changer. If the number of medium * transport elements field in a MODE SELECT command is greater than the * default value returned in the MODE SENSE parameter data, the target * shall return CHECK CONDITION status and set the sense key to ILLEGAL * REQUEST. * * The first storage element address field identifies the first medium * storage element contained in the medium changer. The number of storage * elements field defines the total number of medium storage elements * contained in the medium changer. If the number of medium storage * elements field in a MODE SELECT command is greater than the default * value returned in the MODE SENSE parameter data, the target shall * return CHECK CONDITION status and set the sense key to ILLEGAL REQUEST. * * The first import export element address field identifies the first * medium portal that is accessible both by the medium transport devices * and also by an operator from outside the medium changer. The number of * import export elements field defines the total number of import export * elements contained in the medium changer and accessible to the medium * transport elements. If the number of import export elements field in a * MODE SELECT command is greater than the default value returned in the * MODE SENSE parameter data, the target shall return CHECK CONDITION * status and set the sense key to ILLEGAL REQUEST . * * NOTE 207 The number of import export elements may be zero. * * The first data transfer element address field identifies the first data * transfer element contained in the medium changer. The data transfer * elements may be either read/write or read-only devices. The number of * data transfer field defines the total number of data transfer elements * contained within the medium changer and accessible to the medium * transport elements. If the number of data transfer elements field in a * MODE SELECT command is greater than the default value returned in the * MODE SENSE parameter data, the target shall return CHECK CONDITION * status and set the sense key to ILLEGAL REQUEST . * * Each element in the medium changer must have a unique address. If the * address ranges defined for any of the element types overlap, the target * shall return CHECK CONDITION status and set the sense key to ILLEGAL * REQUEST. */ struct smc_raw_element_address_assignment_page { unsigned char page_code; /* 0x1D */ #define SMC_RAW_EA_PC_PS 0x80 unsigned char param_length; /* 0x12 */ unsigned char mte_addr[2]; unsigned char mte_count[2]; unsigned char se_addr[2]; unsigned char se_count[2]; unsigned char iee_addr[2]; unsigned char iee_count[2]; unsigned char dte_addr[2]; unsigned char dte_count[2]; unsigned char resv18[2]; }; #define SMC_GET2(VEC) \ (uint16_t) \ ( (((unsigned char)(VEC)[0] << 8)) \ + (((unsigned char)(VEC)[1]))) #define SMC_PUT2(VEC,VAL) \ ((VEC)[0] = (unsigned char)((VAL)>>8), \ (VEC)[1] = (unsigned char)((VAL))) #define SMC_GET3(VEC) \ (uint32_t) \ ( (((unsigned char)(VEC)[0] << 16)) \ + (((unsigned char)(VEC)[1] << 8)) \ + ((unsigned char)(VEC)[2])) #define SMC_PUT3(VEC,VAL) \ ((VEC)[0] = (unsigned char)((VAL)>>16), \ (VEC)[1] = (unsigned char)((VAL)>>8), \ (VEC)[2] = (unsigned char)((VAL))) #define SMC_GET4(VEC) \ (uint32_t) \ ( (((unsigned char)(VEC)[0] << 24)) \ + (((unsigned char)(VEC)[1] << 16)) \ + (((unsigned char)(VEC)[2] << 8)) \ + ((unsigned char)(VEC)[3])) #define SMC_PUT4(VEC,VAL) \ ((VEC)[0] = (unsigned char)((VAL)>>24), \ (VEC)[1] = (unsigned char)((VAL)>>16), \ (VEC)[2] = (unsigned char)((VAL)>>8), \ (VEC)[3] = (unsigned char)((VAL))) #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/ndmp/wraplib.c000066400000000000000000000710031263011562700177720ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #include "ndmos.h" #include "wraplib.h" int wrap_main (int ac, char *av[], struct wrap_ccb *wccb) { int rc; rc = wrap_process_args (ac, av, wccb); if (rc) return rc; rc = wrap_main_start_index_file (wccb); if (rc) return rc; rc = wrap_main_start_image_file (wccb); if (rc) return rc; return 0; } int wrap_main_start_index_file (struct wrap_ccb *wccb) { char * filename = wccb->I_index_file_name; FILE * fp; if (!filename) return 0; if (filename[0] == '#') { int fd = atoi (filename+1); if (fd < 2 || fd > 100) { /* huey! */ strcpy (wccb->errmsg, "bad -I#N"); return -1; } fp = fdopen (fd, "w"); if (!fp) { sprintf (wccb->errmsg, "failed fdopen %s", filename); return -1; } } else { fp = fopen (filename, "w"); if (!fp) { sprintf (wccb->errmsg, "failed open %s", filename); return -1; } } wccb->index_fp = fp; return 0; } int wrap_main_start_image_file (struct wrap_ccb *wccb) { char * filename = wccb->f_file_name; int fd, o_mode; switch (wccb->op) { case WRAP_CCB_OP_BACKUP: o_mode = O_CREAT | O_WRONLY; break; case WRAP_CCB_OP_RECOVER: case WRAP_CCB_OP_RECOVER_FILEHIST: o_mode = O_RDONLY; break; default: abort(); return -1; } if (!filename) filename = "-"; if (strcmp (filename, "-") == 0) { if (wccb->op == WRAP_CCB_OP_BACKUP) { fd = 1; } else { fd = 0; } } else if (filename[0] == '#') { fd = atoi (filename+1); if (fd < 2 || fd > 100) { /* huey! */ strcpy (wccb->errmsg, "bad -f#N"); return -1; } } else { fd = open (filename, o_mode, 0666); if (fd < 0) { sprintf (wccb->errmsg, "failed open %s", filename); return -1; } } wccb->data_conn_fd = fd; return 0; } void wrap_log (struct wrap_ccb *wccb, char *fmt, ...) { va_list ap; char buf[4096]; if (!wccb->index_fp && wccb->d_debug < 1) return; sprintf (buf, "%04d ", ++wccb->log_seq_num); va_start (ap, fmt); vsnprintf (buf+5, sizeof(buf)-5, fmt, ap); va_end (ap); if (wccb->index_fp) wrap_send_log_message (wccb->index_fp, buf); if (wccb->d_debug > 0) fprintf (stderr, "LOG: %s\n", buf); } int wrap_set_error (struct wrap_ccb *wccb, int error) { if (error == 0) error = -3; wccb->error = error; return wccb->error; } int wrap_set_errno (struct wrap_ccb *wccb) { return wrap_set_error (wccb, errno); } /* * wrap -c [-B TYPE] [-d N] [-I FILE] [-E NAME=VALUE ...] * wrap -x [-B TYPE] [-d N] [-I FILE] [-E NAME=VALUE ...] * ORIGINAL_NAME @pos NEW_NAME ... * wrap -t [-B TYPE] [-d N] [-I FILE] [-E NAME=VALUE ...] * ORIGINAL_NAME @pos */ int wrap_process_args (int argc, char *argv[], struct wrap_ccb *wccb) { int c; enum wrap_ccb_op op; char * p; NDMOS_MACRO_ZEROFILL (wccb); wccb->progname = argv[0]; if (argc < 2) { strcpy (wccb->errmsg, "too few arguments"); return -1; } while ((c = getopt (argc, argv, "cxtB:d:I:E:f:o:")) != EOF) { switch (c) { case 'c': op = WRAP_CCB_OP_BACKUP; goto set_op; case 't': op = WRAP_CCB_OP_RECOVER_FILEHIST; goto set_op; case 'x': op = WRAP_CCB_OP_RECOVER; goto set_op; set_op: if (wccb->op != WRAP_CCB_OP_NONE) { strcpy (wccb->errmsg, "only one of -c, -x, -t"); return -1; } wccb->op = op; break; case 'B': if (wccb->B_butype) { strcpy (wccb->errmsg, "only one -B allowed"); return -1; } wccb->B_butype = optarg; break; case 'd': wccb->d_debug = atoi(optarg); break; case 'E': if (wccb->n_env >= WRAP_MAX_ENV) { strcpy (wccb->errmsg, "-E overflow"); return -1; } p = strchr (optarg, '='); if (p) { *p++ = 0; } else { p = ""; } wccb->env[wccb->n_env].name = optarg; wccb->env[wccb->n_env].value = p; wccb->n_env++; break; case 'f': if (wccb->f_file_name) { strcpy (wccb->errmsg, "only one -f allowed"); return -1; } wccb->f_file_name = optarg; break; case 'I': if (wccb->I_index_file_name) { strcpy (wccb->errmsg, "only one -I allowed"); return -1; } wccb->I_index_file_name = optarg; break; case 'o': if (wccb->n_o_option >= WRAP_MAX_O_OPTION) { strcpy (wccb->errmsg, "-o overflow"); return -1; } wccb->o_option[wccb->n_o_option] = optarg; wccb->n_o_option++; break; default: strcpy (wccb->errmsg, "unknown option"); return -1; } } switch (wccb->op) { default: abort(); /* just can't happen */ case WRAP_CCB_OP_NONE: strcpy (wccb->errmsg, "one of -c, -x, or -t required"); return -1; case WRAP_CCB_OP_BACKUP: if (optind < argc) { strcpy (wccb->errmsg, "extra args not allowed for -c"); return -1; } break; case WRAP_CCB_OP_RECOVER: case WRAP_CCB_OP_RECOVER_FILEHIST: break; } for (c = optind; c+2 < argc; c += 3) { p = argv[c+1]; if (p[0] != '@') { sprintf (wccb->errmsg, "malformed fhinfo %s", p); return -1; } if (wccb->n_file >= WRAP_MAX_FILE) { strcpy (wccb->errmsg, "file table overflow"); return -1; } if (strcmp (p, "@-") == 0) { wccb->file[wccb->n_file].fhinfo = WRAP_INVALID_FHINFO; } else { wccb->file[wccb->n_file].fhinfo = NDMOS_API_STRTOLL (p+1, &p, 0); if (*p != 0) { sprintf(wccb->errmsg,"malformed fhinfo %s",p); return -1; } } wccb->file[wccb->n_file].original_name = argv[c]; wccb->file[wccb->n_file].save_to_name = argv[c+2]; wccb->n_file++; } if (c < argc) { strcpy (wccb->errmsg, "superfluous args at end"); return -1; } p = wrap_find_env (wccb, "HIST"); if (p) { switch (*p) { case 'y': case 'Y': p = wrap_find_env (wccb, "HIST_TYPE"); if (!p) { p = "y"; } break; } switch (*p) { case 'y': case 'Y': wccb->hist_enable = 'y'; break; case 'd': case 'D': wccb->hist_enable = 'd'; break; case 'f': case 'F': wccb->hist_enable = 'f'; break; default: /* gripe? */ break; } } p = wrap_find_env (wccb, "DIRECT"); if (p) { if (*p == 'y') { wccb->direct_enable = 1; } } p = wrap_find_env (wccb, "FILESYSTEM"); if (!p) p = wrap_find_env (wccb, "PREFIX"); if (!p) p = "/"; wccb->backup_root = p; return 0; } char * wrap_find_env (struct wrap_ccb *wccb, char *name) { int i; for (i = 0; i < wccb->n_env; i++) { if (strcmp (wccb->env[i].name, name) == 0) return wccb->env[i].value; } return 0; } int wrap_cmd_add_with_escapes (char *cmd, char *word, char *special) { char * cmd_lim = &cmd[WRAP_MAX_COMMAND-3]; char * p; int c; p = cmd; while (*p) p++; if (p != cmd) *p++ = ' '; while ((c = *word++) != 0) { if (p >= cmd_lim) return -1; /* overflow */ if (c == '\\' || strchr (special, c)) *p++ = '\\'; *p++ = c; } *p = 0; return 0; } int wrap_cmd_add_with_sh_escapes (char *cmd, char *word) { return wrap_cmd_add_with_escapes (cmd, word, " \t`'\"*?[]$"); } int wrap_cmd_add_allow_file_wildcards (char *cmd, char *word) { return wrap_cmd_add_with_escapes (cmd, word, " \t`'\"$"); } int wrap_pipe_fork_exec (char *cmd, int fdmap[3]) { int pipes[3][2]; int child_fdmap[3]; int nullfd = -1; int i; int rc = -1; for (i = 0; i < 3; i++) { pipes[i][0] = -1; pipes[i][1] = -1; child_fdmap[i] = -1; } for (i = 0; i < 3; i++) { if (fdmap[i] >= 0) { child_fdmap[i] = fdmap[i]; continue; } switch (fdmap[i]) { case WRAP_FDMAP_DEV_NULL: if (nullfd < 0) { nullfd = open ("/dev/null", 2); if (nullfd < 0) { goto bail_out; } } child_fdmap[i] = nullfd; break; case WRAP_FDMAP_INPUT_PIPE: rc = pipe (pipes[i]); if (rc != 0) { goto bail_out; } child_fdmap[i] = pipes[i][0]; break; case WRAP_FDMAP_OUTPUT_PIPE: rc = pipe (pipes[i]); if (rc != 0) { goto bail_out; } child_fdmap[i] = pipes[i][1]; break; default: goto bail_out; } } rc = fork(); if (rc < 0) { goto bail_out; } if (rc == 0) { /* child */ dup2 (child_fdmap[2], 2); dup2 (child_fdmap[1], 1); dup2 (child_fdmap[0], 0); for (rc = 3; rc < 100; rc++) close(rc); execl ("/bin/sh", "sh", "-c", cmd, NULL); fprintf (stderr, "EXEC FAILED %s\n", cmd); exit(127); } if (nullfd >= 0) close (nullfd); for (i = 0; i < 3; i++) { if (fdmap[i] >= 0) { continue; } switch (fdmap[i]) { case WRAP_FDMAP_DEV_NULL: break; case WRAP_FDMAP_INPUT_PIPE: close (pipes[i][0]); fdmap[i] = pipes[i][1]; break; case WRAP_FDMAP_OUTPUT_PIPE: close (pipes[i][1]); fdmap[i] = pipes[i][0]; break; default: abort(); } } return rc; /* PID */ bail_out: if (nullfd >= 0) close (nullfd); for (i = 0; i < 3; i++) { if (pipes[i][0] >= 0) close (pipes[i][0]); if (pipes[i][1] >= 0) close (pipes[i][1]); } return -1; } int wrap_parse_msg (char *buf, struct wrap_msg_buf *wmsg) { int c1, c2; c1 = buf[0]; c2 = buf[1]; if (buf[2] != ' ') { return -1; } if (c1 == 'L' && c2 == 'x') { /* log_message */ return wrap_parse_log_message_msg (buf, wmsg); } if (c1 == 'H' && c2 == 'F') { /* add_file */ return wrap_parse_add_file_msg (buf, wmsg); } if (c1 == 'H' && c2 == 'D') { /* add_dirent */ return wrap_parse_add_dirent_msg (buf, wmsg); } if (c1 == 'H' && c2 == 'N') { /* add_node */ return wrap_parse_add_node_msg (buf, wmsg); } if (c1 == 'D' && c2 == 'E') { /* add_env */ return wrap_parse_add_env_msg (buf, wmsg); } if (c1 == 'D' && c2 == 'R') { /* data_read */ return wrap_parse_data_read_msg (buf, wmsg); } return -1; } int wrap_parse_log_message_msg (char *buf, struct wrap_msg_buf *wmsg) { struct wrap_log_message *res = &wmsg->body.log_message; char * scan = buf+3; int rc; wmsg->msg_type = WRAP_MSGTYPE_LOG_MESSAGE; while (*scan && *scan == ' ') scan++; rc = wrap_cstr_to_str (scan, res->message, sizeof res->message); if (rc < 0) return -2; return 0; } int wrap_send_log_message (FILE *fp, char *message) { struct wrap_msg_buf wmsg; struct wrap_log_message *res = &wmsg.body.log_message; if (!fp) return -1; wrap_cstr_from_str (message, res->message, sizeof res->message); fprintf (fp, "Lx %s\n", res->message); return 0; } int wrap_parse_add_file_msg (char *buf, struct wrap_msg_buf *wmsg) { struct wrap_add_file * res = &wmsg->body.add_file; char * scan = buf+3; char * p; int rc; wmsg->msg_type = WRAP_MSGTYPE_ADD_FILE; res->fstat.valid = 0; res->fhinfo = WRAP_INVALID_FHINFO; while (*scan && *scan == ' ') scan++; if (*scan == 0) return -1; p = scan; while (*scan && *scan != ' ') scan++; if (*scan) { *scan = 0; rc = wrap_cstr_to_str (p, res->path, sizeof res->path); *scan++ = ' '; } else { rc = wrap_cstr_to_str (p, res->path, sizeof res->path); } if (rc < 0) return -2; while (*scan) { p = scan+1; switch (*scan) { case ' ': scan++; continue; case '@': res->fhinfo = NDMOS_API_STRTOLL (p, &scan, 0); break; default: rc = wrap_parse_fstat_subr(&scan, &res->fstat); if (rc < 0) return rc; break; } if (*scan != ' ' && *scan != 0) { /* bogus */ return -1; } } return 0; } int wrap_send_add_file (FILE *fp, char *path, uint64_t fhinfo, struct wrap_fstat *fstat) { struct wrap_msg_buf wmsg; struct wrap_add_file * res = &wmsg.body.add_file; if (!fp) return -1; wrap_cstr_from_str (path, res->path, sizeof res->path); fprintf (fp, "HF %s", res->path); if (fhinfo != WRAP_INVALID_FHINFO) fprintf (fp, " @%llu", fhinfo); wrap_send_fstat_subr (fp, fstat); fprintf (fp, "\n"); return 0; } int wrap_parse_add_dirent_msg (char *buf, struct wrap_msg_buf *wmsg) { struct wrap_add_dirent *res = &wmsg->body.add_dirent; char * scan = buf+3; char * p; int rc; wmsg->msg_type = WRAP_MSGTYPE_ADD_DIRENT; res->fhinfo = WRAP_INVALID_FHINFO; while (*scan && *scan == ' ') scan++; if (*scan == 0) return -1; res->dir_fileno = NDMOS_API_STRTOLL (scan, &scan, 0); if (*scan != ' ') return -1; while (*scan == ' ') scan++; if (*scan == 0) return -1; p = scan; while (*scan && *scan != ' ') scan++; if (*scan) { *scan = 0; rc = wrap_cstr_to_str (p, res->name, sizeof res->name); *scan++ = ' '; } else { rc = wrap_cstr_to_str (p, res->name, sizeof res->name); } if (rc < 0) return -2; res->fileno = NDMOS_API_STRTOLL (scan, &scan, 0); if (*scan != ' ' && *scan != 0) return -1; while (*scan == ' ') scan++; if (*scan == '@') { res->fhinfo = NDMOS_API_STRTOLL(scan+1, &scan, 0); } if (*scan != ' ' && *scan != 0) return -1; while (*scan == ' ') scan++; if (*scan) return -1; return 0; } int wrap_send_add_dirent (FILE *fp, char *name, uint64_t fhinfo, uint64_t dir_fileno, uint64_t fileno) { struct wrap_msg_buf wmsg; struct wrap_add_dirent *res = &wmsg.body.add_dirent; if (!fp) return -1; wrap_cstr_from_str (name, res->name, sizeof res->name); fprintf (fp, "HD %llu %s %llu", dir_fileno, res->name, fileno); if (fhinfo != WRAP_INVALID_FHINFO) fprintf (fp, " @%llu", fhinfo); fprintf (fp, "\n"); return 0; } int wrap_parse_add_node_msg (char *buf, struct wrap_msg_buf *wmsg) { struct wrap_add_node * res = &wmsg->body.add_node; char * scan = buf+3; char * p; int rc; wmsg->msg_type = WRAP_MSGTYPE_ADD_NODE; res->fstat.valid = 0; res->fhinfo = WRAP_INVALID_FHINFO; while (*scan && *scan == ' ') scan++; if (*scan == 0) return -1; res->fstat.fileno = NDMOS_API_STRTOLL (scan, &scan, 0); if (*scan != ' ' && *scan != 0) return -1; res->fstat.valid |= WRAP_FSTAT_VALID_FILENO; while (*scan) { p = scan+1; switch (*scan) { case ' ': scan++; continue; case '@': res->fhinfo = NDMOS_API_STRTOLL (p, &scan, 0); break; default: rc = wrap_parse_fstat_subr(&scan, &res->fstat); if (rc < 0) return rc; break; } if (*scan != ' ' && *scan != 0) { /* bogus */ return -1; } } if ( (res->fstat.valid & WRAP_FSTAT_VALID_FILENO) == 0) return -5; return 0; } int wrap_send_add_node (FILE *fp, uint64_t fhinfo, struct wrap_fstat *fstat) { uint32_t save_valid; if (!fp) return -1; if (fstat->valid & WRAP_FSTAT_VALID_FILENO) { fprintf (fp, "HN %llu", fstat->fileno); } else { fprintf (fp, "HN 0000000000"); } if (fhinfo != WRAP_INVALID_FHINFO) fprintf (fp, " @%llu", fhinfo); /* suppress iFILENO */ save_valid = fstat->valid; fstat->valid &= ~WRAP_FSTAT_VALID_FILENO; wrap_send_fstat_subr (fp, fstat); fstat->valid = save_valid; fprintf (fp, "\n"); return 0; } int wrap_parse_fstat_subr (char **scanp, struct wrap_fstat *fstat) { char * scan = *scanp; char * p = scan+1; uint32_t valid = 0; valid = 0; switch (*scan) { case 's': /* size */ valid = WRAP_FSTAT_VALID_SIZE; fstat->size = NDMOS_API_STRTOLL (p, &scan, 0); break; case 'i': /* fileno (inum) */ valid = WRAP_FSTAT_VALID_FILENO; fstat->fileno = NDMOS_API_STRTOLL (p, &scan, 0); break; case 'm': /* mode low twelve bits */ valid = WRAP_FSTAT_VALID_MODE; fstat->mode = strtol (p, &scan, 8); break; case 'l': /* link count */ valid = WRAP_FSTAT_VALID_LINKS; fstat->links = strtol (p, &scan, 0); break; case 'u': /* uid */ valid = WRAP_FSTAT_VALID_UID; fstat->uid = strtol (p, &scan, 0); break; case 'g': /* gid */ valid = WRAP_FSTAT_VALID_GID; fstat->gid = strtol (p, &scan, 0); break; case 't': /* one of the times */ p = scan+2; switch (scan[1]) { case 'm': /* mtime */ valid = WRAP_FSTAT_VALID_MTIME; fstat->mtime = strtol (p, &scan, 0); break; case 'a': /* atime */ valid = WRAP_FSTAT_VALID_ATIME; fstat->atime = strtol (p, &scan, 0); break; case 'c': /* ctime */ valid = WRAP_FSTAT_VALID_CTIME; fstat->ctime = strtol (p, &scan, 0); break; default: return -3; } break; case 'f': /* ftype (file type) */ valid = WRAP_FSTAT_VALID_FTYPE; switch (scan[1]) { case 'd': fstat->ftype = WRAP_FTYPE_DIR; break; case 'p': fstat->ftype = WRAP_FTYPE_FIFO; break; case 'c': fstat->ftype = WRAP_FTYPE_CSPEC; break; case 'b': fstat->ftype = WRAP_FTYPE_BSPEC; break; case '-': fstat->ftype = WRAP_FTYPE_REG; break; case 'l': fstat->ftype = WRAP_FTYPE_SLINK; break; case 's': fstat->ftype = WRAP_FTYPE_SOCK; break; case 'R': fstat->ftype = WRAP_FTYPE_REGISTRY; break; case 'o': fstat->ftype = WRAP_FTYPE_OTHER; break; default: fstat->ftype = WRAP_FTYPE_INVALID; return -5; } scan += 2; break; default: return -3; } if (*scan != ' ' && *scan != 0) return -1; fstat->valid |= valid; *scanp = scan; return 0; } int wrap_send_fstat_subr (FILE *fp, struct wrap_fstat *fstat) { if (!fp) return -1; if (fstat->valid & WRAP_FSTAT_VALID_FTYPE) { int c = 0; switch (fstat->ftype) { default: case WRAP_FTYPE_INVALID: c = 0; break; case WRAP_FTYPE_DIR: c = 'd'; break; case WRAP_FTYPE_FIFO: c = 'p'; break; case WRAP_FTYPE_CSPEC: c = 'c'; break; case WRAP_FTYPE_BSPEC: c = 'b'; break; case WRAP_FTYPE_REG: c = '-'; break; case WRAP_FTYPE_SLINK: c = 'l'; break; case WRAP_FTYPE_SOCK: c = 's'; break; case WRAP_FTYPE_REGISTRY: c = 'R'; break; case WRAP_FTYPE_OTHER: c = 'o'; break; } if (c) { fprintf (fp, " f%c", c); } else { return -1; } } if (fstat->valid & WRAP_FSTAT_VALID_MODE) { fprintf (fp, " m%04o", fstat->mode); } if (fstat->valid & WRAP_FSTAT_VALID_LINKS) { fprintf (fp, " l%lu", fstat->links); } if (fstat->valid & WRAP_FSTAT_VALID_SIZE) { fprintf (fp, " s%llu", fstat->size); } if (fstat->valid & WRAP_FSTAT_VALID_UID) { fprintf (fp, " u%lu", fstat->uid); } if (fstat->valid & WRAP_FSTAT_VALID_GID) { fprintf (fp, " g%lu", fstat->gid); } if (fstat->valid & WRAP_FSTAT_VALID_ATIME) { fprintf (fp, " ta%lu", fstat->atime); } if (fstat->valid & WRAP_FSTAT_VALID_MTIME) { fprintf (fp, " tm%lu", fstat->mtime); } if (fstat->valid & WRAP_FSTAT_VALID_CTIME) { fprintf (fp, " tc%lu", fstat->ctime); } if (fstat->valid & WRAP_FSTAT_VALID_FILENO) { fprintf (fp, " i%llu", fstat->fileno); } return 0; } int wrap_parse_add_env_msg (char *buf, struct wrap_msg_buf *wmsg) { struct wrap_add_env * res = &wmsg->body.add_env; char * scan = buf+3; char * p; int rc; wmsg->msg_type = WRAP_MSGTYPE_ADD_ENV; while (*scan && *scan == ' ') scan++; if (*scan == 0) return -1; p = scan; while (*scan && *scan != ' ') scan++; if (*scan) { *scan = 0; rc = wrap_cstr_to_str (p, res->name, sizeof res->name); *scan++ = ' '; } else { rc = wrap_cstr_to_str (p, res->name, sizeof res->name); } if (rc < 0) return -2; while (*scan && *scan == ' ') scan++; p = scan; while (*scan && *scan != ' ') scan++; if (*scan) { *scan = 0; rc = wrap_cstr_to_str (p, res->value, sizeof res->value); *scan++ = ' '; } else { rc = wrap_cstr_to_str (p, res->value, sizeof res->value); } if (rc < 0) return -2; return 0; } int wrap_send_add_env (FILE *fp, char *name, char *value) { struct wrap_msg_buf wmsg; struct wrap_add_env * res = &wmsg.body.add_env; if (!fp) return -1; wrap_cstr_from_str (name, res->name, sizeof res->name); wrap_cstr_from_str (value, res->value, sizeof res->value); fprintf (fp, "DE %s %s\n", res->name, res->value); return 0; } int wrap_parse_data_read_msg (char *buf, struct wrap_msg_buf *wmsg) { struct wrap_data_read * res = &wmsg->body.data_read; char * scan = buf+3; wmsg->msg_type = WRAP_MSGTYPE_DATA_READ; while (*scan && *scan == ' ') scan++; if (*scan == 0) return -1; res->offset = NDMOS_API_STRTOLL (scan, &scan, 0); if (*scan != ' ') return -1; while (*scan && *scan != ' ') scan++; if (*scan == 0) return -1; res->length = NDMOS_API_STRTOLL (scan, &scan, 0); /* tolerate trailing white */ while (*scan && *scan != ' ') scan++; if (*scan != 0) return -1; return 0; } int wrap_send_data_read (FILE *fp, uint64_t offset, uint64_t length) { if (!fp) return -1; fprintf (fp, "DR %lld %lld\n", (int64_t) offset, (int64_t)length); fflush (fp); return 0; } int wrap_parse_data_stats_msg (char *buf, struct wrap_msg_buf *wmsg) { #if 0 struct wrap_data_stats *res = &wmsg->body.data_stats; char * scan = buf+3; wmsg->msg_type = WRAP_MSGTYPE_DATA_STATS; #endif return -1; } int wrap_send_data_stats (FILE *fp) { if (!fp) return -1; fprintf (fp, "DS ...\n"); fflush (fp); return 0; } /* * Recovery helpers **************************************************************** */ int wrap_reco_align_to_wanted (struct wrap_ccb *wccb) { uint64_t distance; uint64_t unwanted_length; top: /* * If there is an error, we're toast. */ if (wccb->error) return wccb->error; /* * If we're aligned, we're done. */ if (wccb->expect_offset == wccb->want_offset) { if (wccb->expect_length < wccb->want_length && wccb->reading_length == 0) { wrap_reco_issue_read (wccb); } return wccb->error; } /* * If we have a portion we don't want, consume it now */ if (wccb->have_length > 0) { if (wccb->have_offset < wccb->want_offset) { distance = wccb->want_offset - wccb->have_offset; if (distance < wccb->have_length) { /* * We have some of what we want. * Consume (discard) unwanted part. */ unwanted_length = distance; } else { unwanted_length = wccb->have_length; } } else { unwanted_length = wccb->have_length; } wrap_reco_consume (wccb, unwanted_length); goto top; } if (wccb->expect_length > 0) { /* Incoming, but we don't have it yet. */ wrap_reco_receive (wccb); goto top; } /* * We don't have anything. We don't expect anything. * Time to issue an NDMP_DATA_NOTIFY_READ via this wrapper. */ wrap_reco_issue_read (wccb); goto top; } int wrap_reco_receive (struct wrap_ccb *wccb) { char * iobuf_end = &wccb->iobuf[wccb->n_iobuf]; char * have_end = wccb->have + wccb->have_length; unsigned n_read = iobuf_end - have_end; int rc; if (wccb->error) return wccb->error; if (wccb->have_length == 0) { wccb->have = wccb->iobuf; have_end = wccb->have + wccb->have_length; } if (n_read < 512 && wccb->have != wccb->iobuf) { /* Not much room at have_end. Front of iobuf available. */ /* Compress */ NDMOS_API_BCOPY (wccb->have, wccb->iobuf, wccb->have_length); wccb->have = wccb->iobuf; have_end = wccb->have + wccb->have_length; n_read = iobuf_end - have_end; } if (n_read > wccb->reading_length) n_read = wccb->reading_length; if (n_read == 0) { /* Hmmm. */ abort (); return -1; } rc = read (wccb->data_conn_fd, have_end, n_read); if (rc > 0) { wccb->have_length += rc; wccb->reading_offset += rc; wccb->reading_length -= rc; } else { /* EOF or error */ if (rc == 0) { strcpy (wccb->errmsg, "EOF on data connection"); wrap_set_error (wccb, -1); } else { sprintf (wccb->errmsg, "errno %d on data connection", errno); wrap_set_errno (wccb); } } return wccb->error; } int wrap_reco_consume (struct wrap_ccb *wccb, uint32_t length) { assert (wccb->have_length >= length); wccb->have_offset += length; wccb->have_length -= length; wccb->expect_offset += length; wccb->expect_length -= length; wccb->have += length; if (wccb->expect_length == 0) { assert (wccb->have_length == 0); wccb->expect_offset = -1ull; } return wccb->error; } int wrap_reco_must_have (struct wrap_ccb *wccb, uint32_t length) { if (wccb->want_length < length) wccb->want_length = length; wrap_reco_align_to_wanted (wccb); while (wccb->have_length < length && !wccb->error) { wrap_reco_align_to_wanted (wccb); /* triggers issue_read() */ wrap_reco_receive (wccb); } if (wccb->have_length >= length) return 0; return wccb->error; } int wrap_reco_seek (struct wrap_ccb *wccb, uint64_t want_offset, uint64_t want_length, uint32_t must_have_length) { if (wccb->error) return wccb->error; wccb->want_offset = want_offset; wccb->want_length = want_length; return wrap_reco_must_have (wccb, must_have_length); } int wrap_reco_pass (struct wrap_ccb *wccb, int write_fd, uint64_t length, unsigned write_bsize) { unsigned cnt; int rc; while (length > 0) { if (wccb->error) break; cnt = write_bsize; if (cnt > length) cnt = length; if (wccb->have_length < cnt) { wrap_reco_must_have (wccb, cnt); } rc = write (write_fd, wccb->have, cnt); length -= cnt; wrap_reco_consume (wccb, cnt); } return wccb->error; } int wrap_reco_issue_read (struct wrap_ccb *wccb) { uint64_t off; uint64_t len; assert (wccb->reading_length == 0); if (wccb->data_conn_mode == 0) { struct stat st; int rc; rc = fstat (wccb->data_conn_fd, &st); if (rc != 0) { sprintf (wccb->errmsg, "Can't fstat() data conn rc=%d", rc); return wrap_set_errno (wccb); } if (S_ISFIFO(st.st_mode)) { wccb->data_conn_mode = 'p'; if (!wccb->index_fp) { strcpy (wccb->errmsg, "data_conn is pipe but no -I"); return wrap_set_error (wccb, -3); } } else if (S_ISREG(st.st_mode)) { wccb->data_conn_mode = 'f'; } else { sprintf (wccb->errmsg, "Unsupported data_conn type %o", st.st_mode); return wrap_set_error (wccb, -3); } } off = wccb->want_offset; len = wccb->want_length; off += wccb->have_length; len -= wccb->have_length; if (len == 0) { abort(); } wccb->last_read_offset = off; wccb->last_read_length = len; switch (wccb->data_conn_mode) { default: abort(); return -1; case 'f': if (lseek (wccb->data_conn_fd, off, 0) < 0) { return -1; } break; case 'p': wrap_send_data_read (wccb->index_fp, off, len); break; } wccb->reading_offset = wccb->last_read_offset; wccb->reading_length = wccb->last_read_length; if (wccb->have_length == 0) { wccb->expect_offset = wccb->reading_offset; wccb->expect_length = wccb->reading_length; } else { wccb->expect_length += len; } return wccb->error; } /* * (Note: this is hoisted from ndml_cstr.c) * * Description: * Convert strings to/from a canonical strings (CSTR). * * The main reason for this is to eliminate spaces * in strings thus making multiple strings easily * delimited by white space. * * Canonical strings use the HTTP convention of * percent sign followed by two hex digits (%xx). * Characters outside the printable ASCII range, * space, and percent sign are so converted. * * Both interfaces return the length of the resulting * string, -1 if there is an overflow, or -2 * there is a conversion error. */ int wrap_cstr_from_str (char *src, char *dst, unsigned dst_max) { static char cstr_to_hex[] = "0123456789ABCDEF"; unsigned char * p = (unsigned char *)src; unsigned char * q = (unsigned char *)dst; unsigned char * q_end = q + dst_max - 1; int c; while ((c = *p++) != 0) { if (c <= ' ' || c > 0x7E || c == NDMCSTR_WARN) { if (q+3 > q_end) return -1; *q++ = NDMCSTR_WARN; *q++ = cstr_to_hex[(c>>4)&0xF]; *q++ = cstr_to_hex[c&0xF]; } else { if (q+1 > q_end) return -1; *q++ = c; } } *q = 0; return q - (unsigned char *)dst; } int wrap_cstr_to_str (char *src, char *dst, unsigned dst_max) { unsigned char * p = (unsigned char *)src; unsigned char * q = (unsigned char *)dst; unsigned char * q_end = q + dst_max - 1; int c, c1, c2; while ((c = *p++) != 0) { if (q+1 > q_end) return -1; if (c != NDMCSTR_WARN) { *q++ = c; continue; } c1 = wrap_cstr_from_hex (p[0]); c2 = wrap_cstr_from_hex (p[1]); if (c1 < 0 || c2 < 0) { /* busted conversion */ return -2; } c = (c1<<4) + c2; *q++ = c; p += 2; } *q = 0; return q - (unsigned char *)dst; } int wrap_cstr_from_hex (int c) { if ('0' <= c && c <= '9') return c - '0'; if ('a' <= c && c <= 'f') return (c - 'a') + 10; if ('A' <= c && c <= 'F') return (c - 'A') + 10; return -1; } bareos-Release-14.2.6/src/ndmp/wraplib.h000066400000000000000000000270751263011562700200110ustar00rootroot00000000000000/* * Copyright (c) 1998,1999,2000 * Traakan, Inc., Los Altos, CA * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. */ /* * Project: NDMJOB * Ident: $Id: $ * * Description: * */ #define WRAP_INVALID_FHINFO (-1ull) #define WRAP_MAX_PATH (1024+512) #define WRAP_MAX_NAME 256 #define WRAP_MAX_ENV 100 #define WRAP_MAX_FILE 100 #define WRAP_MAX_COMMAND (20*1024) #define WRAP_MAX_O_OPTION 100 #ifdef __cplusplus extern "C" { #endif /* forward */ struct wrap_ccb; /* * MAIN helpers **************************************************************** */ extern int wrap_main (int ac, char *av[], struct wrap_ccb *wccb); extern int wrap_main_start_index_file (struct wrap_ccb *wccb); extern int wrap_main_start_image_file (struct wrap_ccb *wccb); extern void wrap_log (struct wrap_ccb *wccb, char *fmt, ...); extern int wrap_set_error (struct wrap_ccb *wccb, int error); /* * Command Execution **************************************************************** * * This wrapper will spawn (fork/exec) a subprocess to do * the real work. These help form the sh(1) command line, * create the pipe fittings, and spawn the subprocess. * * The fdmap[3] corresponds to the subprocess stdin, stdout, * and stderr. A value >= 0 is assumed to be an inherited * file descriptor. A value < 0 is one of the special codes * WRAP_FDMAP_xxx. On return, the _PIPE special codes are * replaced with the file descriptor for the parent process * end of the pipe. */ #define WRAP_FDMAP_INPUT_PIPE -2 /* input to child, parent writes */ #define WRAP_FDMAP_OUTPUT_PIPE -3 /* output from child, parent reads */ #define WRAP_FDMAP_DEV_NULL -4 /* /dev/null */ extern int wrap_cmd_add_with_escapes (char *cmd, char *word, char *special); extern int wrap_cmd_add_with_sh_escapes (char *cmd, char *word); extern int wrap_cmd_add_allow_file_wildcards (char *cmd, char *word); extern int wrap_pipe_fork_exec (char *cmd, int fdmap[3]); /* * CCB -- Command Control Block **************************************************************** * * A digested form of command line arguments */ enum wrap_ccb_op { WRAP_CCB_OP_NONE = 0, WRAP_CCB_OP_BACKUP = 1, /* -c */ WRAP_CCB_OP_RECOVER = 2, /* -x */ WRAP_CCB_OP_RECOVER_FILEHIST = 3 /* -t */ }; struct wrap_env { char * name; char * value; }; struct wrap_file { uint64_t fhinfo; char * original_name; /* relative to backup root */ char * save_to_name; /* relative to file system */ }; struct wrap_ccb { int error; int log_seq_num; char errmsg[WRAP_MAX_NAME]; /* Raw arguments */ char * B_butype; /* -B TYPE */ int d_debug; /* -d N */ struct wrap_env env[WRAP_MAX_ENV]; /* -E NAME=VALUE */ int n_env; char * f_file_name; /* -f FILE */ char * I_index_file_name; /* -I FILE */ char * o_option[WRAP_MAX_O_OPTION]; /* -o OPTION */ int n_o_option; struct wrap_file file[WRAP_MAX_FILE]; /* recovery only */ int n_file; /* derived from arguments */ char * progname; enum wrap_ccb_op op; FILE * index_fp; int data_conn_fd; /* Common interprettations of the env */ int hist_enable; int direct_enable; char * backup_root; /* * Recovery variables. * * All offset/length pairs refer to a portion of the * backup image. * * have The portion currently in the buffer. * want The portion wanted by the formatter * (e.g. tar, dump). * reading The portion immediately after what we * "have" (in the buffer) still coming due * to the last NDMP_NOTIFY_DATA_READ. * last_read The portion requested by the last * NDMP_NOTIFY_DATA_READ. * expect Composite of have and reading. */ char * iobuf; uint32_t n_iobuf; char * have; uint64_t have_offset; uint32_t have_length; /* never bigger than iobuf */ uint64_t want_offset; uint64_t want_length; uint64_t reading_offset; uint64_t reading_length; uint64_t last_read_offset; uint64_t last_read_length; uint64_t expect_offset; uint64_t expect_length; int data_conn_mode; }; extern int wrap_process_args (int argc, char *argv[], struct wrap_ccb *wccb); extern char * wrap_find_env (struct wrap_ccb *wccb, char *name); extern int wrap_reco_seek (struct wrap_ccb *wccb, uint64_t want_offset, uint64_t want_length, uint32_t must_have_length); extern int wrap_reco_must_have (struct wrap_ccb *wccb, uint32_t length); extern int wrap_reco_pass (struct wrap_ccb *wccb, int write_fd, uint64_t length, unsigned write_bsize); extern int wrap_reco_align_to_wanted (struct wrap_ccb *wccb); extern int wrap_reco_receive (struct wrap_ccb *wccb); extern int wrap_reco_consume (struct wrap_ccb *wccb, uint32_t length); extern int wrap_reco_issue_read (struct wrap_ccb *wccb); /* * WRAP Messages **************************************************************** * * A message is simply one text line following a format. * These structures are used to buffer incoming messages. */ struct wrap_log_message { /* Lx */ char message[WRAP_MAX_PATH]; }; enum wrap_ftype { WRAP_FTYPE_INVALID = 0, WRAP_FTYPE_DIR = 1, /* d */ WRAP_FTYPE_FIFO = 2, /* p */ WRAP_FTYPE_CSPEC = 3, /* c */ WRAP_FTYPE_BSPEC = 4, /* b */ WRAP_FTYPE_REG = 5, /* - */ WRAP_FTYPE_SLINK = 6, /* l */ WRAP_FTYPE_SOCK = 7, /* s */ WRAP_FTYPE_REGISTRY = 8, /* R */ WRAP_FTYPE_OTHER = 9 /* o */ }; struct wrap_fstat { uint32_t valid; #define WRAP_FSTAT_VALID_FTYPE (1ul<<0u) #define WRAP_FSTAT_VALID_MODE (1ul<<1u) #define WRAP_FSTAT_VALID_LINKS (1ul<<2u) #define WRAP_FSTAT_VALID_SIZE (1ul<<3u) #define WRAP_FSTAT_VALID_UID (1ul<<4u) #define WRAP_FSTAT_VALID_GID (1ul<<5u) #define WRAP_FSTAT_VALID_ATIME (1ul<<6u) #define WRAP_FSTAT_VALID_MTIME (1ul<<7u) #define WRAP_FSTAT_VALID_CTIME (1ul<<8u) #define WRAP_FSTAT_VALID_FILENO (1ul<<9u) enum wrap_ftype ftype; /* f%s */ uint16_t mode; /* m%04o */ uint32_t links; /* l%lu */ uint64_t size; /* s%llu */ uint32_t uid; /* u%lu */ uint32_t gid; /* g%lu */ uint32_t atime; /* ta%lu */ uint32_t mtime; /* tm%lu */ uint32_t ctime; /* tc%lu */ uint64_t fileno; /* i%llu */ }; /* * HF path [@fhinfo] [stats] * * History File -- Corresponds to NDMPv?_FH_ADD_FILE */ struct wrap_add_file { uint64_t fhinfo; /* @%llu */ struct wrap_fstat fstat; char path[WRAP_MAX_PATH]; }; /* * HD dir_fileno name fileno [@fhinfo] * * History Directory entry -- Corresponds to NDMPv?_FH_ADD_DIR */ struct wrap_add_dirent { uint64_t fhinfo; /* @%llu */ uint64_t dir_fileno; /* %llu */ uint64_t fileno; /* %llu */ char name[WRAP_MAX_NAME]; }; /* * HN [@fhinfo] [stats] -- iFILENO must be present * * History Node -- Corresponds to NDMPv?_FH_ADD_NODE */ struct wrap_add_node { /* HN */ uint64_t fhinfo; /* @%llu */ struct wrap_fstat fstat; }; /* * DE name value * * Data Env -- Corresponds to NDMPv?_DATA_GET_ENV * This is used for the post backup processing env[]. */ struct wrap_add_env { char name[WRAP_MAX_NAME]; char value[WRAP_MAX_PATH]; }; /* * DR offset length * * Data Read -- Corresponds to NDMPv?_NOTIFY_DATA_READ * This is used during recovery operations to retrieve * portions of the backup image. */ struct wrap_data_read { /* DR */ uint64_t offset; /* %llu */ uint64_t length; /* %llu */ }; /* * DS s{r|d|f} [wN] [etN] [ebN] * * Data Stats -- Supplemental info for NDMPv?_DATA_GET_STATE * Sent periodically to update certain fields of the * DATA_GET_STATE reply. */ enum wrap_data_status { WRAP_DS_INVALID = 0, WRAP_DS_RUNNING = 1, /* sr */ WRAP_DS_DONE_OK = 2, /* sd */ WRAP_DS_DONE_FAILED = 3 /* sf */ }; struct wrap_data_stats { /* DS */ uint32_t valid; #define WRAP_DATASTATS_VALID_BYTES_WRITTEN (1ul<<0u) #define WRAP_DATASTATS_VALID_EST_TIME_REMAINING (1ul<<1u) #define WRAP_DATASTATS_VALID_EST_BYTES_REMAINING (1ul<<2u) enum wrap_data_status status; /* s{r|d|f} */ uint64_t bytes_written; /* w%llu */ uint64_t est_time_remaining; /* et%llu */ uint64_t est_bytes_remaining; /* eb%llu */ }; /* * RR errno path * * Recovery Result -- Corresponds to NDMPv?_LOG_FILE * Sent during recovery operations to report the * success or failure of recovery. */ struct wrap_recovery_result { /* RR */ int rr_errno; /* sys/errno.h */ char path[WRAP_MAX_PATH]; }; enum wrap_msg_type { WRAP_MSGTYPE_LOG_MESSAGE = 1, WRAP_MSGTYPE_ADD_FILE = 2, WRAP_MSGTYPE_ADD_DIRENT = 3, WRAP_MSGTYPE_ADD_NODE = 4, WRAP_MSGTYPE_ADD_ENV = 5, WRAP_MSGTYPE_DATA_READ = 6, WRAP_MSGTYPE_DATA_STATS = 7, WRAP_MSGTYPE_RECOVERY_RESULT = 8, }; struct wrap_msg_buf { enum wrap_msg_type msg_type; union { struct wrap_log_message log_message; struct wrap_add_file add_file; struct wrap_add_dirent add_dirent; struct wrap_add_node add_node; struct wrap_add_env add_env; struct wrap_data_read data_read; struct wrap_data_stats data_stats; struct wrap_recovery_result recovery_result; } body; }; extern int wrap_parse_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_parse_log_message_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_send_log_message (FILE *fp, char *message); extern int wrap_parse_add_file_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_send_add_file (FILE *fp, char *path, uint64_t fhinfo, struct wrap_fstat *fstat); extern int wrap_parse_add_dirent_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_send_add_dirent (FILE *fp, char *name, uint64_t fhinfo, uint64_t dir_fileno, uint64_t fileno); extern int wrap_parse_add_node_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_send_add_node (FILE *fp, uint64_t fhinfo, struct wrap_fstat *fstat); extern int wrap_parse_fstat_subr (char **scanp, struct wrap_fstat *fstat); extern int wrap_send_fstat_subr (FILE *fp, struct wrap_fstat *fstat); extern int wrap_parse_add_env_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_send_add_env (FILE *fp, char *name, char *value); extern int wrap_parse_data_read_msg (char *buf, struct wrap_msg_buf *wmsg); extern int wrap_send_data_read (FILE *fp, uint64_t offset, uint64_t length); /* * Canonical strings **************************************************************** * Convert strings to/from HTTP-like canonical strings (%xx). * Example "a b%c" --> "a%20b%25c" */ #define NDMCSTR_WARN '%' extern int wrap_cstr_from_str (char *src, char *dst, unsigned dst_max); extern int wrap_cstr_to_str (char *src, char *dst, unsigned dst_max); extern int wrap_cstr_from_hex (int c); #ifdef __cplusplus } #endif bareos-Release-14.2.6/src/plugins/000077500000000000000000000000001263011562700167105ustar00rootroot00000000000000bareos-Release-14.2.6/src/plugins/dird/000077500000000000000000000000001263011562700176325ustar00rootroot00000000000000bareos-Release-14.2.6/src/plugins/dird/BareosDirPluginBaseclass.py000066400000000000000000000140221263011562700250550ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Maik Aussendorf # # Baseclass for Bareos python plugins # Functions taken and adapted from bareos-dir.py from bareosdir import * from bareos_dir_consts import * import os import time class BareosDirPluginBaseclass(object): ''' Bareos DIR python plugin base class ''' def __init__(self, context, plugindef): DebugMessage( context, 100, "Constructor called in module %s\n" % (__name__)) events = [] events.append(bDirEventType['bDirEventJobStart']); events.append(bDirEventType['bDirEventJobEnd']); events.append(bDirEventType['bDirEventJobInit']); events.append(bDirEventType['bDirEventJobRun']); RegisterEvents(context, events) # get some static Bareos values self.jobName = GetValue(context, brDirVariable['bDirVarJobName']) self.jobLevel = chr(GetValue(context, brDirVariable['bDirVarLevel'])) self.jobType = GetValue(context, brDirVariable['bDirVarType']) self.jobId = int(GetValue(context, brDirVariable['bDirVarJobId'])) self.jobClient = GetValue(context, brDirVariable['bDirVarClient']) self.jobStatus = GetValue(context, brDirVariable['bDirVarJobStatus']) self.Priority = GetValue(context, brDirVariable['bDirVarPriority']) DebugMessage( context, 100, "JobName = %s - level = %s - type = %s - Id = %s - \ Client = %s - jobStatus = %s - Priority = %s - BareosDirPluginBaseclass\n" % (self.jobName,self.jobLevel,self.jobType,self.jobId,self.jobClient,self.jobStatus,self.Priority)) def __str__(self): return "<$%:jobName=%s jobId=%s client=%s>" %(self.__class__, self.jobName,self.jobId,self.Client) def parse_plugin_definition(self, context, plugindef): ''' Called with the plugin options from the bareos configfiles You should overload this method with your own and do option checking here, return bRCs['bRC_Error'], if options are not ok or better call super.parse_plugin_definition in your own class and make sanity check on self.options afterwards ''' DebugMessage( context, 100, "plugin def parser called with %s\n" % (plugindef)) # Parse plugin options into a dict self.options = dict() plugin_options = plugindef.split(":") for current_option in plugin_options: key, sep, val = current_option.partition("=") DebugMessage(context, 100, "key:val = %s:%s" % (key, val)) if val == '': continue else: self.options[key] = val return bRCs['bRC_OK'] def handle_plugin_event(self, context, event): ''' This method is called for each of the above registered events Overload this method to implement your actions for the events, You may first call this method in your derived class to get the job attributes read and then only adjust where useful. ''' if event == bDirEventType['bDirEventJobInit']: self.jobInitTime = time.time() self.jobStatus = chr(GetValue(context, brDirVariable['bDirVarJobStatus'])); DebugMessage(context, 100, "bDirEventJobInit event triggered at Unix time %s\n" %self.jobInitTime); elif event == bDirEventType['bDirEventJobStart']: self.jobStartTime = time.time() self.jobStatus = chr(GetValue(context, brDirVariable['bDirVarJobStatus'])); DebugMessage(context, 100, "bDirEventJobStart event triggered at Unix time %s\n" %self.jobStartTime); elif event == bDirEventType['bDirEventJobRun']: # Now the jobs starts running, after eventually waiting some time, e.g for other jobs to finish self.jobRunTime = time.time() DebugMessage(context, 100, "bDirEventJobRun event triggered at Unix time %s\n" %self.jobRunTime); elif event == bDirEventType['bDirEventJobEnd']: self.jobEndTime = time.time() DebugMessage(context, 100, "bDirEventJobEnd event triggered at Unix time %s\n" %self.jobEndTime); self.jobLevel = chr(GetValue(context, brDirVariable['bDirVarLevel'])); self.jobStatus = chr(GetValue(context, brDirVariable['bDirVarJobStatus'])); self.jobErrors = int(GetValue(context, brDirVariable['bDirVarJobErrors'])); self.jobBytes = int(GetValue(context, brDirVariable['bDirVarJobBytes'])); self.jobFiles = int(GetValue(context, brDirVariable['bDirVarJobFiles'])); self.jobNumVols = int(GetValue(context, brDirVariable['bDirVarNumVols'])); self.jobPool = GetValue(context, brDirVariable['bDirVarPool']); self.jobStorage = GetValue(context, brDirVariable['bDirVarStorage']); self.jobMediaType = GetValue(context, brDirVariable['bDirVarMediaType']); self.jobTotalTime = self.jobEndTime - self.jobInitTime; self.jobRunningTime = self.jobEndTime - self.jobRunTime; self.throughput = 0 if self.jobRunningTime > 0: self.throughput = self.jobBytes / self.jobRunningTime return bRCs['bRC_OK']; # vim: ts=4 tabstop=4 expandtab shiftwidth=4 softtabstop=4 bareos-Release-14.2.6/src/plugins/dird/BareosDirWrapper.py000066400000000000000000000027331263011562700234240ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Maik Aussendorf # # The BareosDirWrapper module. Here is a global object bareos_dir_plugin_object # and wrapper functions, which are directly called out of the bareos-dir. They # are intended to pass the call to a method of an object of type # BareosDirPluginBaseclass (or derived) # use this as global plugin object among your python-dir-plugin modules bareos_dir_plugin_object = None def parse_plugin_definition(context, plugindef): return bareos_dir_plugin_object.parse_plugin_definition(context, plugindef) def handle_plugin_event(context, event): return bareos_dir_plugin_object.handle_plugin_event(context, event) bareos-Release-14.2.6/src/plugins/dird/Makefile.in000066400000000000000000000044041263011562700217010ustar00rootroot00000000000000# # Simple Makefile for building test DIR plugins for Bareos # @MCOMMON@ PYTHON_CPPFLAGS += @PYTHON_INC@ srcdir = @srcdir@ VPATH = @srcdir@:../../dird .PATH: @srcdir@ basedir = ../.. # top dir topdir = ../../.. # this dir relative to top dir thisdir = src/plugins/dird INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include -I$(basedir)/dird BUILD_PLUGINS = @BUILD_DIR_PLUGINS@ .SUFFIXES: .c .lo # inference rules .c.lo: $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) -c $< all: Makefile $(BUILD_PLUGINS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status example-plugin-dir.la: Makefile \ example-plugin-dir$(DEFAULT_OBJECT_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared example-plugin-dir.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version python-dir.lo: python-dir.c python-dir.h $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) $(PYTHON_CPPFLAGS) -c $< python-dir.la: Makefile \ python-dir$(DEFAULT_OBJECT_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared python-dir.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version \ -L../../lib -lbareos @PYTHON_LIBS@ plugtest: Makefile dir_plugins.c \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) ../../dird/dir_plugins.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../../lib -L../../findlib -o $@ dir_plugins.o -lbareos $(DLIB) -lm $(LIBS) install: all $(MKDIR) $(DESTDIR)$(plugindir) $(CP) *.py *.py.template $(DESTDIR)$(plugindir) @for plugin in $(BUILD_PLUGINS); do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$plugin $(DESTDIR)$(plugindir); \ $(RMF) $(DESTDIR)$(plugindir)/$$plugin; \ done install-test-plugin: all $(MKDIR) $(DESTDIR)$(plugindir) $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) example-plugin-dir.la $(DESTDIR)$(plugindir) $(RMF) $(DESTDIR)$(plugindir)/example-plugin-dir.la libtool-clean: find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) $(RMF) *.la $(RMF) -r .libs _libs clean: @LIBTOOL_CLEAN_TARGET@ @$(RMF) plugtest *.so *.o 1 2 3 distclean: clean @$(RMF) Makefile depend: bareos-Release-14.2.6/src/plugins/dird/bareos-dir-class-plugin.py000066400000000000000000000036601263011562700246370ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Bareos-dir-local-fileset a simple example for a python Bareos Dir Plugin using # BareosDirPluginBaseclass. The plugin argument 'filename' is used to read # all files listed in that file and add it to the fileset # # Author: Maik Aussendorf # # Provided by the Bareos Dir Python plugin interface import bareos_dir_consts # This module contains the wrapper functions called by the Bareos-Dir, the # functions call the corresponding methods from your plugin class import BareosDirWrapper from BareosDirWrapper import * # This module contains the used plugin class import BareosDirPluginBaseclass def load_bareos_plugin(context, plugindef): ''' This function is called by the Bareos-Dir to load the plugin We use it to instantiate the plugin class ''' # BareosDirWrapper.bareos_dir_plugin_object is the module attribute that # holds the plugin class object BareosDirWrapper.bareos_dir_plugin_object = \ BareosDirPluginBaseclass.BareosDirPluginBaseclass( context, plugindef) return bareos_dir_consts.bRCs['bRC_OK'] # the rest is done in the Plugin module bareos-Release-14.2.6/src/plugins/dird/bareos-dir.py.template000066400000000000000000000053151263011562700240510ustar00rootroot00000000000000# BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Marco van Wieringen # from bareosdir import * from bareos_dir_consts import * def load_bareos_plugin(context, plugindef): DebugMessage(context, 100, "load_bareos_plugin called with param: " + plugindef + "\n"); events = []; events.append(bDirEventType['bDirEventJobStart']); events.append(bDirEventType['bDirEventJobEnd']); events.append(bDirEventType['bDirEventJobInit']); events.append(bDirEventType['bDirEventJobRun']); RegisterEvents(context, events); return bRCs['bRC_OK']; def parse_plugin_definition(context, plugindef): DebugMessage(context, 100, "parse_plugin_definition called with param: " + plugindef + "\n"); plugin_options = plugindef.split(":"); for current_option in plugin_options: key,sep,val = current_option.partition("="); if val == '': continue; elif key == 'instance': continue; elif key == 'module_path': continue; elif key == 'module_name': continue; else: DebugMessage(context, 100, "parse_plugin_definition unknown option " + key + " with value " + val + "\n"); return bRCs['bRC_Error']; return bRCs['bRC_OK']; def handle_plugin_event(context, event): if event == bDirEventType['bDirEventJobStart']: DebugMessage(context, 100, "bDirEventJobStart event triggered\n"); jobname = GetValue(context, brDirVariable['bDirVarJobName']); DebugMessage(context, 100, "Job " + jobname + " starting\n"); elif event == bDirEventType['bDirEventJobEnd']: DebugMessage(context, 100, "bDirEventJobEnd event triggered\n"); jobname = GetValue(context, brDirVariable['bDirVarJobName']); DebugMessage(context, 100, "Job " + jobname + " stopped\n"); elif event == bDirEventType['bDirEventJobInit']: DebugMessage(context, 100, "bDirEventJobInit event triggered\n"); elif event == bDirEventType['bDirEventJobRun']: DebugMessage(context, 100, "bDirEventJobRun event triggered\n"); return bRCs['bRC_OK']; bareos-Release-14.2.6/src/plugins/dird/bareos_dir_consts.py000066400000000000000000000047361263011562700237200ustar00rootroot00000000000000# BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Marco van Wieringen # bJobMessageType = dict( M_ABORT = 1, M_DEBUG = 2, M_FATAL = 3, M_ERROR = 4, M_WARNING = 5, M_INFO = 6, M_SAVED = 7, M_NOTSAVED = 8, M_SKIPPED = 9, M_MOUNT = 10, M_ERROR_TERM = 11, M_TERM = 12, M_RESTORED = 13, M_SECURITY = 14, M_ALERT = 15, M_VOLMGMT = 16 ) brDirVariable = dict( bDirVarJob = 1, bDirVarLevel = 2, bDirVarType = 3, bDirVarJobId = 4, bDirVarClient = 5, bDirVarNumVols = 6, bDirVarPool = 7, bDirVarStorage = 8, bDirVarWriteStorage = 9, bDirVarReadStorage = 10, bDirVarCatalog = 11, bDirVarMediaType = 12, bDirVarJobName = 13, bDirVarJobStatus = 14, bDirVarPriority = 15, bDirVarVolumeName = 16, bDirVarCatalogRes = 17, bDirVarJobErrors = 18, bDirVarJobFiles = 19, bDirVarSDJobFiles = 20, bDirVarSDErrors = 21, bDirVarFDJobStatus = 22, bDirVarSDJobStatus = 23, bDirVarPluginDir = 24, bDirVarLastRate = 25, bDirVarJobBytes = 26, bDirVarReadBytes = 27 ) bwDirVariable = dict( bwDirVarJobReport = 1, bwDirVarVolumeName = 2, bwDirVarPriority = 3, bwDirVarJobLevel = 4 ) bRCs = dict( bRC_OK = 0, bRC_Stop = 1, bRC_Error = 2, bRC_More = 3, bRC_Term = 4, bRC_Seen = 5, bRC_Core = 6, bRC_Skip = 7, bRC_Cancel = 8 ) bDirEventType = dict( bDirEventJobStart = 1, bDirEventJobEnd = 2, bDirEventJobInit = 3, bDirEventJobRun = 4, bDirEventVolumePurged = 5, bDirEventNewVolume = 6, bDirEventNeedVolume = 7, bDirEventVolumeFull = 8, bDirEventRecyle = 9, bDirEventGetScratch = 10, bDirEventNewPluginOptions = 11 ) bareos-Release-14.2.6/src/plugins/dird/example-plugin-dir.c000066400000000000000000000132621263011562700235050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Sample Plugin program * * Kern Sibbald, October 2007 * */ #include "bareos.h" #include "dir_plugins.h" #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Kern Sibbald" #define PLUGIN_DATE "January 2008" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "Test Director Daemon Plugin" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pDirVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pDirVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bDirEvent *event, void *value); /* Pointers to Bareos functions */ static bDirFuncs *bfuncs = NULL; static bDirInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), DIR_PLUGIN_INTERFACE_VERSION, DIR_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION }; static pDirFuncs pluginFuncs = { sizeof(pluginFuncs), DIR_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bDirInfo *lbinfo, bDirFuncs *lbfuncs, genpInfo **pinfo, pDirFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { printf("plugin: Unloaded\n"); return bRC_OK; } #ifdef __cplusplus } #endif static bRC newPlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bDirVarJobId, (void *)&JobId); printf("plugin: newPlugin JobId=%d\n", JobId); bfuncs->registerBareosEvents(ctx, 2, bDirEventJobStart, bDirEventJobEnd); return bRC_OK; } static bRC freePlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bDirVarJobId, (void *)&JobId); printf("plugin: freePlugin JobId=%d\n", JobId); return bRC_OK; } static bRC getPluginValue(bpContext *ctx, pDirVariable var, void *value) { printf("plugin: getPluginValue var=%d\n", var); return bRC_OK; } static bRC setPluginValue(bpContext *ctx, pDirVariable var, void *value) { printf("plugin: setPluginValue var=%d\n", var); return bRC_OK; } static bRC handlePluginEvent(bpContext *ctx, bDirEvent *event, void *value) { char *name; int val; switch (event->eventType) { case bDirEventJobStart: printf("plugin: HandleEvent JobStart\n"); break; case bDirEventJobEnd: printf("plugin: HandleEvent JobEnd\n"); bfuncs->getBareosValue(ctx, bDirVarJob, (void *)&name); printf("plugin: bDirVarJob=%s\n", name); bfuncs->getBareosValue(ctx, bDirVarJobId, (void *)&val); printf("plugin: bDirVarJobId=%d\n", val); bfuncs->getBareosValue(ctx, bDirVarType, (void *)&val); printf("plugin: bDirVarType=%c\n", val); bfuncs->getBareosValue(ctx, bDirVarLevel, (void *)&val); printf("plugin: bDirVarLevel=%c\n", val); bfuncs->getBareosValue(ctx, bDirVarClient, (void *)&name); printf("plugin: bDirVarClient=%s\n", name); bfuncs->getBareosValue(ctx, bDirVarCatalog, (void *)&name); printf("plugin: bDirVarCatalog=%s\n", name); bfuncs->getBareosValue(ctx, bDirVarPool, (void *)&name); printf("plugin: bDirVarPool=%s\n", name); bfuncs->getBareosValue(ctx, bDirVarStorage, (void *)&name); printf("plugin: bDirVarStorage=%s\n", name); bfuncs->getBareosValue(ctx, bDirVarJobErrors, (void *)&val); printf("plugin: bDirVarJobErrors=%d\n", val); bfuncs->getBareosValue(ctx, bDirVarJobFiles, (void *)&val); printf("plugin: bDirVarJobFiles=%d\n", val); bfuncs->getBareosValue(ctx, bDirVarNumVols, (void *)&val); printf("plugin: bDirVarNumVols=%d\n", val); break; } bfuncs->getBareosValue(ctx, bDirVarJobName, (void *)&name); printf("Job Name=%s\n", name); bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_INFO, 0, "JobMesssage message"); bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message"); return bRC_OK; } bareos-Release-14.2.6/src/plugins/dird/python-dir.c000066400000000000000000000641121263011562700220770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Python Director Plugin program * * Marco van Wieringen, August 2012 */ #include "bareos.h" #include "dird.h" #undef _POSIX_C_SOURCE #include #if (PY_VERSION_HEX < 0x02060000) #error "Need at least Python version 2.6 or newer" #endif static const int dbglvl = 150; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Marco van Wieringen" #define PLUGIN_DATE "October 2013" #define PLUGIN_VERSION "3" #define PLUGIN_DESCRIPTION "Python Director Daemon Plugin" #define PLUGIN_USAGE "python:instance=:module_path=:module_name=" #define Dmsg(context, level, ...) bfuncs->DebugMessage(context, __FILE__, __LINE__, level, __VA_ARGS__ ) #define Jmsg(context, type, ...) bfuncs->JobMessage(context, __FILE__, __LINE__, type, 0, __VA_ARGS__ ) /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pDirVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pDirVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bDirEvent *event, void *value); static bRC parse_plugin_definition(bpContext *ctx, void *value); static void PyErrorHandler(bpContext *ctx, int msgtype); static bRC PyLoadModule(bpContext *ctx, void *value); static bRC PyParsePluginDefinition(bpContext *ctx, void *value); static bRC PyGetPluginValue(bpContext *ctx, pDirVariable var, void *value); static bRC PySetPluginValue(bpContext *ctx, pDirVariable var, void *value); static bRC PyHandlePluginEvent(bpContext *ctx, bDirEvent *event, void *value); /* Pointers to Bareos functions */ static bDirFuncs *bfuncs = NULL; static bDirInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), DIR_PLUGIN_INTERFACE_VERSION, DIR_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; static pDirFuncs pluginFuncs = { sizeof(pluginFuncs), DIR_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* New plugin instance */ freePlugin, /* Free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; /* * Plugin private context */ struct plugin_ctx { PyThreadState *interpreter; int64_t instance; bool python_loaded; char *module_path; char *module_name; PyObject *pModule; PyObject *pDict; PyObject *bpContext; }; #include "python-dir.h" /* * We don't actually use this but we need it to tear down the * final python interpreter on unload of the plugin. Each instance of * the plugin get its own interpreter. */ static PyThreadState *mainThreadState; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bDirInfo *lbinfo, bDirFuncs *lbfuncs, genpInfo **pinfo, pDirFuncs **pfuncs) { bfuncs = lbfuncs; /* Set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* Return pointer to our info */ *pfuncs = &pluginFuncs; /* Return pointer to our functions */ /* * Setup Python */ Py_InitializeEx(0); PyEval_InitThreads(); mainThreadState = PyEval_SaveThread(); return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { /* * Terminate Python */ PyEval_RestoreThread(mainThreadState); Py_Finalize(); return bRC_OK; } #ifdef __cplusplus } #endif static bRC newPlugin(bpContext *ctx) { struct plugin_ctx *p_ctx; p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(struct plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ /* * For each plugin instance we instantiate a new Python interpreter. */ PyEval_AcquireLock(); p_ctx->interpreter = Py_NewInterpreter(); PyEval_ReleaseThread(p_ctx->interpreter); /* * Always register some events the python plugin itself can register * any other events it is interested in. */ bfuncs->registerBareosEvents(ctx, 1, bDirEventNewPluginOptions); return bRC_OK; } static bRC freePlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } /* * Stop any sub interpreter started per plugin instance. */ PyEval_AcquireThread(p_ctx->interpreter); /* * Do python cleanup calls. */ if (p_ctx->bpContext) { Py_DECREF(p_ctx->bpContext); } if (p_ctx->pModule) { Py_DECREF(p_ctx->pModule); } Py_EndInterpreter(p_ctx->interpreter); PyEval_ReleaseLock(); free(p_ctx); ctx->pContext = NULL; return bRC_OK; } static bRC getPluginValue(bpContext *ctx, pDirVariable var, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; PyEval_AcquireThread(p_ctx->interpreter); retval = PyGetPluginValue(ctx, var, value); PyEval_ReleaseThread(p_ctx->interpreter); return retval; } static bRC setPluginValue(bpContext *ctx, pDirVariable var, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; PyEval_AcquireThread(p_ctx->interpreter); retval = PySetPluginValue(ctx, var, value); PyEval_ReleaseThread(p_ctx->interpreter); return retval; } static bRC handlePluginEvent(bpContext *ctx, bDirEvent *event, void *value) { bool event_dispatched = false; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; if (!p_ctx) { goto bail_out; } /* * First handle some events internally before calling python if it * want to do some special handling on the event triggered. */ switch (event->eventType) { case bDirEventNewPluginOptions: event_dispatched = true; retval = parse_plugin_definition(ctx, value); break; default: break; } /* * See if we have been triggered in the previous switch if not we have to * always dispatch the event. If we already processed the event internally * we only do a dispatch to the python entry point when that internal processing * was successfull (e.g. retval == bRC_OK). */ if (!event_dispatched || retval == bRC_OK) { PyEval_AcquireThread(p_ctx->interpreter); /* * Now dispatch the event to Python. * First the calls that need special handling. */ switch (event->eventType) { case bDirEventNewPluginOptions: /* * See if we already loaded the Python modules. */ if (!p_ctx->python_loaded) { retval = PyLoadModule(ctx, value); } /* * Only try to call when the loading succeeded. */ if (retval == bRC_OK) { retval = PyParsePluginDefinition(ctx, value); } break; default: /* * Handle the generic events e.g. the ones which are just passed on. * We only try to call Python when we loaded the right module until * that time we pretend the call succeeded. */ if (p_ctx->python_loaded) { retval = PyHandlePluginEvent(ctx, event, value); } else { retval = bRC_OK; } break; } PyEval_ReleaseThread(p_ctx->interpreter); } bail_out: return retval; } /* * Strip any backslashes in the string. */ static inline void strip_back_slashes(char *value) { char *bp; bp = value; while (*bp) { switch (*bp) { case '\\': bstrinlinecpy(bp, bp + 1); break; default: break; } bp++; } } /* * Parse a integer value. */ static inline int64_t parse_integer(const char *argument_value) { return str_to_int64(argument_value); } /* * Parse a boolean value e.g. check if its yes or true anything else translates to false. */ static inline bool parse_boolean(const char *argument_value) { if (bstrcasecmp(argument_value, "yes") || bstrcasecmp(argument_value, "true")) { return true; } else { return false; } } /* * Always set destination to value and clean any previous one. */ static inline void set_string(char **destination, char *value) { if (*destination) { free(*destination); } *destination = bstrdup(value); strip_back_slashes(*destination); } /* * Parse the plugin definition passed in. * * The definition is in this form: * * python:module_path=:module_name=:... */ static bRC parse_plugin_definition(bpContext *ctx, void *value) { int i; char *plugin_definition, *bp, *argument, *argument_value; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!value) { return bRC_Error; } /* * Parse the plugin definition. * Make a private copy of the whole string. */ plugin_definition = bstrdup((char *)value); bp = strchr(plugin_definition, ':'); if (!bp) { Jmsg(ctx, M_FATAL, "Illegal plugin definition %s\n", plugin_definition); Dmsg(ctx, dbglvl, "Illegal plugin definition %s\n", plugin_definition); goto bail_out; } /* * Skip the first ':' */ bp++; while (bp) { if (strlen(bp) == 0) { break; } /* * Each argument is in the form: * = * * So we setup the right pointers here, argument to the beginning * of the argument, argument_value to the beginning of the argument_value. */ argument = bp; argument_value = strchr(bp, '='); if (!argument_value) { Jmsg(ctx, M_FATAL, "Illegal argument %s without value\n", argument); Dmsg(ctx, dbglvl, "Illegal argument %s without value\n", argument); goto bail_out; } *argument_value++ = '\0'; /* * See if there are more arguments and setup for the next run. */ bp = argument_value; do { bp = strchr(bp, ':'); if (bp) { if (*(bp - 1) != '\\') { *bp++ = '\0'; break; } else { bp++; } } } while (bp); for (i = 0; plugin_arguments[i].name; i++) { if (bstrcasecmp(argument, plugin_arguments[i].name)) { int64_t *int_destination = NULL; char **str_destination = NULL; bool *bool_destination = NULL; switch (plugin_arguments[i].type) { case argument_instance: int_destination = &p_ctx->instance; break; case argument_module_path: str_destination = &p_ctx->module_path; break; case argument_module_name: str_destination = &p_ctx->module_name; break; default: break; } if (int_destination) { *int_destination = parse_integer(argument_value); } if (str_destination) { set_string(str_destination, argument_value); } if (bool_destination) { *bool_destination = parse_boolean(argument_value); } /* * When we have a match break the loop. */ break; } } } free(plugin_definition); return bRC_OK; bail_out: free(plugin_definition); return bRC_Error; } /* * Work around API changes in Python versions. * These function abstract the storage and retrieval of the bpContext * which is passed to the Python methods and which the method can pass * back and which allow the callback function to understand what bpContext * its talking about. */ #if ((PY_VERSION_HEX < 0x02070000) || \ ((PY_VERSION_HEX >= 0x03000000) && \ (PY_VERSION_HEX < 0x03010000))) /* * Python version before 2.7 and 3.0. */ static PyObject *PyCreatebpContext(bpContext *ctx) { /* * Setup a new CObject which holds the bpContext structure used here internally. */ return PyCObject_FromVoidPtr((void *)ctx, NULL); } static bpContext *PyGetbpContext(PyObject *pyCtx) { return (bpContext *)PyCObject_AsVoidPtr(pyCtx); } #else /* * Python version after 2.6 and 3.1. */ static PyObject *PyCreatebpContext(bpContext *ctx) { /* * Setup a new Capsule which holds the bpContext structure used here internally. */ return PyCapsule_New((void *)ctx, "bareos.bpContext", NULL); } static bpContext *PyGetbpContext(PyObject *pyCtx) { return (bpContext *)PyCapsule_GetPointer(pyCtx, "bareos.bpContext"); } #endif /* * Convert a return value into a bRC enum value. */ static inline bRC conv_python_retval(PyObject *pRetVal) { int retval; retval = PyInt_AsLong(pRetVal); return (bRC)retval; } /* * Handle a Python error. * * Python equivalent: * * import traceback, sys * return "".join(traceback.format_exception(sys.exc_type, * sys.exc_value, sys.exc_traceback)) */ static void PyErrorHandler(bpContext *ctx, int msgtype) { PyObject *type, *value, *traceback; PyObject *tracebackModule; char *error_string; PyErr_Fetch(&type, &value, &traceback); tracebackModule = PyImport_ImportModule("traceback"); if (tracebackModule != NULL) { PyObject *tbList, *emptyString, *strRetval; tbList = PyObject_CallMethod(tracebackModule, (char *)"format_exception", (char *)"OOO", type, value == NULL ? Py_None : value, traceback == NULL ? Py_None : traceback); emptyString = PyString_FromString(""); strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList); error_string = bstrdup(PyString_AsString(strRetval)); Py_DECREF(tbList); Py_DECREF(emptyString); Py_DECREF(strRetval); Py_DECREF(tracebackModule); } else { error_string = bstrdup("Unable to import traceback module."); } Py_DECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); Dmsg(ctx, dbglvl, "%s\n", error_string); if (msgtype) { Jmsg(ctx, msgtype, "%s\n", error_string); } free(error_string); } /* * Initial load of the Python module. * * Based on the parsed plugin options we set some prerequisits like the * module path and the module to load. We also load the dictionary used * for looking up the Python methods. */ static bRC PyLoadModule(bpContext *ctx, void *value) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *sysPath, *mPath, *pName, *pFunc, *module; /* * Extend the Python search path with the given module_path. */ if (p_ctx->module_path) { sysPath = PySys_GetObject((char *)"path"); mPath = PyString_FromString(p_ctx->module_path); PyList_Append(sysPath, mPath); Py_DECREF(mPath); } /* * Make our callback methods available for Python. */ module = Py_InitModule("bareosdir", BareosDIRMethods); /* * Try to load the Python module by name. */ if (p_ctx->module_name) { Dmsg(ctx, dbglvl, "Trying to load module with name %s\n", p_ctx->module_name); pName = PyString_FromString(p_ctx->module_name); p_ctx->pModule = PyImport_Import(pName); Py_DECREF(pName); if (!p_ctx->pModule) { Dmsg(ctx, dbglvl, "Failed to load module with name %s\n", p_ctx->module_name); goto bail_out; } Dmsg(ctx, dbglvl, "Sucessfully loaded module with name %s\n", p_ctx->module_name); /* * Get the Python dictionary for lookups in the Python namespace. */ p_ctx->pDict = PyModule_GetDict(p_ctx->pModule); /* Borrowed reference */ /* * Encode the bpContext so a Python method can pass it in on calling back. */ p_ctx->bpContext = PyCreatebpContext(ctx); /* * Lookup the load_bareos_plugin() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "load_bareos_plugin"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pPluginDefinition, *pRetVal; pPluginDefinition = PyString_FromString((char *)value); if (!pPluginDefinition) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pPluginDefinition, NULL); Py_DECREF(pPluginDefinition); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named load_bareos_plugins()\n"); goto bail_out; } } /* * Keep track we successfully loaded. */ p_ctx->python_loaded = true; return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Any plugin options which are passed in are dispatched here to a Python method and it * can parse the plugin options. This function is also called after PyLoadModule() has * loaded the Python module and made sure things are operational. */ static bRC PyParsePluginDefinition(bpContext *ctx, void *value) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the parse_plugin_definition() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "parse_plugin_definition"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pPluginDefinition, *pRetVal; pPluginDefinition = PyString_FromString((char *)value); if (!pPluginDefinition) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pPluginDefinition, NULL); Py_DECREF(pPluginDefinition); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } return retval; } else { Dmsg(ctx, dbglvl, "Failed to find function named parse_plugin_definition()\n"); return bRC_Error; } bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PyGetPluginValue(bpContext *ctx, pDirVariable var, void *value) { return bRC_OK; } static bRC PySetPluginValue(bpContext *ctx, pDirVariable var, void *value) { return bRC_OK; } static bRC PyHandlePluginEvent(bpContext *ctx, bDirEvent *event, void *value) { bRC retval = bRC_Error; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the handle_plugin_event() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "handle_plugin_event"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pEventType, *pRetVal; pEventType = PyInt_FromLong(event->eventType); pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pEventType, NULL); Py_DECREF(pEventType); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named handle_plugin_event()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to get certain internal values of the current Job. */ static PyObject *PyBareosGetValue(PyObject *self, PyObject *args) { int var; bpContext *ctx = NULL; PyObject *pyCtx; PyObject *pRetVal = NULL; if (!PyArg_ParseTuple(args, "Oi:BareosGetValue", &pyCtx, &var)) { return NULL; } switch (var) { case bDirVarJobId: case bDirVarLevel: case bDirVarType: case bDirVarNumVols: case bDirVarJobStatus: case bDirVarPriority: case bDirVarFDJobStatus: case bDirVarSDJobStatus: { int value = 0; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (brDirVariable)var, &value) == bRC_OK) { pRetVal = PyInt_FromLong(value); } break; } case bDirVarJobErrors: case bDirVarSDErrors: case bDirVarJobFiles: case bDirVarSDJobFiles: case bDirVarLastRate: case bDirVarJobBytes: case bDirVarReadBytes: { uint64_t value = 0; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (brDirVariable)var, &value) == bRC_OK) { pRetVal = PyLong_FromUnsignedLong(value); } break; } case bDirVarJobName: case bDirVarJob: case bDirVarClient: case bDirVarPool: case bDirVarStorage: case bDirVarWriteStorage: case bDirVarReadStorage: case bDirVarCatalog: case bDirVarMediaType: case bDirVarVolumeName: { char *value; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (brDirVariable)var, &value) == bRC_OK) { pRetVal = PyString_FromString(value); } break; } case bDirVarPluginDir: { char *value; if (bfuncs->getBareosValue(NULL, (brDirVariable)var, &value) == bRC_OK) { pRetVal = PyString_FromString(value); } break; } default: ctx = PyGetbpContext(pyCtx); Dmsg(ctx, dbglvl, "PyBareosGetValue: Unknown variable requested %d\n", var); break; } if (!pRetVal) { Py_INCREF(Py_None); pRetVal = Py_None; } return pRetVal; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to set certain internal values of the current Job. */ static PyObject *PyBareosSetValue(PyObject *self, PyObject *args) { int var; bpContext *ctx = NULL; PyObject *pyCtx, *pyValue; if (!PyArg_ParseTuple(args, "OiO:BareosSetValue", &pyCtx, &var, &pyValue)) { return NULL; } switch (var) { case bwDirVarVolumeName: { char *value; ctx = PyGetbpContext(pyCtx); value = PyString_AsString(pyValue); if (value) { bfuncs->setBareosValue(ctx, (bwDirVariable)var, value); } break; } case bwDirVarPriority: case bwDirVarJobLevel: { int value; ctx = PyGetbpContext(pyCtx); value = PyInt_AsLong(pyValue); if (value >= 0) { bfuncs->setBareosValue(ctx, (bwDirVariable)var, &value); } break; } default: ctx = PyGetbpContext(pyCtx); Dmsg(ctx, dbglvl, "PyBareosSetValue: Unknown variable requested %d\n", var); break; } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue debug messages using the Bareos debug message facility. */ static PyObject *PyBareosDebugMessage(PyObject *self, PyObject *args) { int level; char *dbgmsg = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "Oi|z:BareosDebugMessage", &pyCtx, &level, &dbgmsg)) { return NULL; } if (dbgmsg) { ctx = PyGetbpContext(pyCtx); Dmsg(ctx, level, dbgmsg); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue Job messages using the Bareos Job message facility. */ static PyObject *PyBareosJobMessage(PyObject *self, PyObject *args) { int type; char *jobmsg = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "Oi|z:BareosJobMessage", &pyCtx, &type, &jobmsg)) { return NULL; } if (jobmsg) { ctx = PyGetbpContext(pyCtx); Jmsg(ctx, type, jobmsg); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Register Event to register additional events it wants * to receive. */ static PyObject *PyBareosRegisterEvents(PyObject *self, PyObject *args) { int len, event; bpContext *ctx; PyObject *pyCtx, *pyEvents, *pySeq, *pyEvent; if (!PyArg_ParseTuple(args, "OO:BareosRegisterEvents", &pyCtx, &pyEvents)) { return NULL; } pySeq = PySequence_Fast(pyEvents, "Expected a sequence of events"); if (!pySeq) { return NULL; } len = PySequence_Fast_GET_SIZE(pySeq); ctx = PyGetbpContext(pyCtx); for (int i = 0; i < len; i++) { pyEvent = PySequence_Fast_GET_ITEM(pySeq, i); event = PyInt_AsLong(pyEvent); if (event >= bDirEventJobStart && event <= bDirEventGetScratch) { Dmsg(ctx, dbglvl, "PyBareosRegisterEvents: registering event %d\n", event); bfuncs->registerBareosEvents(ctx, 1, event); } } Py_DECREF(pySeq); Py_INCREF(Py_None); return Py_None; } bareos-Release-14.2.6/src/plugins/dird/python-dir.h000066400000000000000000000043771263011562700221130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This defines the Python types in C++ and the callbacks from Python we support. */ #ifndef BPYTHONDIR_H #define BPYTHONDIR_H 1 /* * This defines the arguments that the plugin parser understands. */ enum plugin_argument_type { argument_none, argument_instance, argument_module_path, argument_module_name }; struct plugin_argument { const char *name; enum plugin_argument_type type; }; static plugin_argument plugin_arguments[] = { { "instance", argument_instance }, { "module_path", argument_module_path }, { "module_name", argument_module_name }, { NULL, argument_none } }; /* * Callback methods from Python. */ static PyObject *PyBareosGetValue(PyObject *self, PyObject *args); static PyObject *PyBareosSetValue(PyObject *self, PyObject *args); static PyObject *PyBareosDebugMessage(PyObject *self, PyObject *args); static PyObject *PyBareosJobMessage(PyObject *self, PyObject *args); static PyObject *PyBareosRegisterEvents(PyObject *self, PyObject *args); static PyMethodDef BareosDIRMethods[] = { { "GetValue", PyBareosGetValue, METH_VARARGS, "Get a Plugin value" }, { "SetValue", PyBareosSetValue, METH_VARARGS, "Set a Plugin value" }, { "DebugMessage", PyBareosDebugMessage, METH_VARARGS, "Print a Debug message" }, { "JobMessage", PyBareosJobMessage, METH_VARARGS, "Print a Job message" }, { "RegisterEvents", PyBareosRegisterEvents, METH_VARARGS, "Register Plugin Events" }, { NULL, NULL, 0, NULL } }; #endif /* BPYTHONDIR_H */ bareos-Release-14.2.6/src/plugins/filed/000077500000000000000000000000001263011562700177735ustar00rootroot00000000000000bareos-Release-14.2.6/src/plugins/filed/BareosFdPluginBaseclass.py000066400000000000000000000245751263011562700250470ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Maik Aussendorf # # Baseclass for Bareos python plugins # Functions taken and adapted from bareos-fd.py import bareosfd from bareos_fd_consts import bVariable, bFileType, bRCs, bCFs from bareos_fd_consts import bEventType, bIOPS import os class BareosFdPluginBaseclass(object): ''' Bareos python plugin base class ''' def __init__(self, context, plugindef): bareosfd.DebugMessage( context, 100, "Constructor called in module %s\n" % (__name__)) events = [] events.append(bEventType['bEventJobEnd']) events.append(bEventType['bEventEndBackupJob']) events.append(bEventType['bEventEndFileSet']) events.append(bEventType['bEventHandleBackupFile']) bareosfd.RegisterEvents(context, events) # get some static Bareos values self.fdname = bareosfd.GetValue(context, bVariable['bVarFDName']) self.jobId = bareosfd.GetValue(context, bVariable['bVarJobId']) self.client = bareosfd.GetValue(context, bVariable['bVarClient']) self.since = bareosfd.GetValue(context, bVariable['bVarSinceTime']) self.level = bareosfd.GetValue(context, bVariable['bVarLevel']) self.jobName = bareosfd.GetValue(context, bVariable['bVarJobName']) self.workingdir = bareosfd.GetValue( context, bVariable['bVarWorkingDir']) self.FNAME = "undef" bareosfd.DebugMessage( context, 100, "FDName = %s - BareosFdPluginBaseclass\n" % (self.fdname)) bareosfd.DebugMessage( context, 100, "WorkingDir: %s JobId: %s\n" % (self.workingdir, self.jobId)) def __str__(self): return "<%s:fdname=%s jobId=%s client=%s since=%d level=%c jobName=%s workingDir=%s>" % \ (self.__class__, self.fdname, self.jobId, self.client, self.since, self.level, self.jobName, self.workingdir) def parse_plugin_definition(self, context, plugindef): bareosfd.DebugMessage( context, 100, "plugin def parser called with %s\n" % (plugindef)) # Parse plugin options into a dict self.options = dict() plugin_options = plugindef.split(":") for current_option in plugin_options: key, sep, val = current_option.partition("=") bareosfd.DebugMessage(context, 100, "key:val = %s:%s" % (key, val)) if val == '': continue else: self.options[key] = val # you should overload this method with your own and do option checking # here, return bRCs['bRC_Error'], if options are not ok # or better call super.parse_plugin_definition in your own class and # make sanity check on self.options afterwards return bRCs['bRC_OK'] def plugin_io(self, context, IOP): bareosfd.DebugMessage( context, 100, "plugin_io called with function %s\n" % (IOP.func)) bareosfd.DebugMessage( context, 100, "FNAME is set to %s\n" % (self.FNAME)) if IOP.func == bIOPS['IO_OPEN']: self.FNAME = IOP.fname try: if IOP.flags & (os.O_CREAT | os.O_WRONLY): bareosfd.DebugMessage( context, 100, "Open file %s for writing with %s\n" % (self.FNAME, IOP)) dirname = os.path.dirname(self.FNAME) if not os.path.exists(dirname): bareosfd.DebugMessage( context, 100, "Directory %s does not exist, creating it now\n" % (dirname)) os.makedirs(dirname) self.file = open(self.FNAME, 'wb') else: bareosfd.DebugMessage( context, 100, "Open file %s for reading with %s\n" % (self.FNAME, IOP)) self.file = open(self.FNAME, 'rb') except: IOP.status = -1 return bRCs['bRC_Error'] return bRCs['bRC_OK'] elif IOP.func == bIOPS['IO_CLOSE']: bareosfd.DebugMessage(context, 100, "Closing file " + "\n") self.file.close() return bRCs['bRC_OK'] elif IOP.func == bIOPS['IO_SEEK']: return bRCs['bRC_OK'] elif IOP.func == bIOPS['IO_READ']: bareosfd.DebugMessage( context, 200, "Reading %d from file %s\n" % (IOP.count, self.FNAME)) IOP.buf = bytearray(IOP.count) IOP.status = self.file.readinto(IOP.buf) IOP.io_errno = 0 return bRCs['bRC_OK'] elif IOP.func == bIOPS['IO_WRITE']: bareosfd.DebugMessage( context, 200, "Writing buffer to file %s\n" % (self.FNAME)) self.file.write(IOP.buf) IOP.status = IOP.count IOP.io_errno = 0 return bRCs['bRC_OK'] def handle_plugin_event(self, context, event): if event == bEventType['bEventJobEnd']: bareosfd.DebugMessage( context, 100, "handle_plugin_event called with bEventJobEnd\n") elif event == bEventType['bEventEndBackupJob']: bareosfd.DebugMessage( context, 100, "handle_plugin_event called with bEventEndBackupJob\n") elif event == bEventType['bEventEndFileSet']: bareosfd.DebugMessage( context, 100, "handle_plugin_event called with bEventEndFileSet\n") else: bareosfd.DebugMessage( context, 100, "handle_plugin_event called with event %s\n" % (event)) return bRCs['bRC_OK'] def start_backup_file(self, context, savepkt): ''' Base method, we do not add anything, overload this method with your implementation to add files to backup fileset ''' bareosfd.DebugMessage(context, 100, "start_backup called\n") return bRCs['bRC_Skip'] def end_backup_file(self, context): bareosfd.DebugMessage( context, 100, "end_backup_file() entry point in Python called\n") return bRCs['bRC_OK'] def start_restore_file(self, context, cmd): bareosfd.DebugMessage( context, 100, "start_restore_file() entry point in Python called with %s\n" % (cmd)) return bRCs['bRC_OK'] def end_restore_file(self, context): bareosfd.DebugMessage( context, 100, "end_restore_file() entry point in Python called\n") return bRCs['bRC_OK'] def restore_object_data(self, context, ROP): bareosfd.DebugMessage( context, 100, "restore_object_data called with " + str(ROP) + "\n") return bRCs['bRC_OK'] def create_file(self, context, restorepkt): ''' Creates the file to be restored and directory structure, if needed. Adapt this in your derived class, if you need modifications for virtual files or similar ''' bareosfd.DebugMessage( context, 100, "create_file() entry point in Python called with %s\n" % (restorepkt)) FNAME = restorepkt.ofname dirname = os.path.dirname(FNAME) if not os.path.exists(dirname): bareosfd.DebugMessage( context, 200, "Directory %s does not exist, creating it now\n" % dirname) os.makedirs(dirname) # open creates the file, if not yet existing, we close it again right # aways it will be opened again in plugin_io. # But: only do this for regular files, prevent from # IOError: (21, 'Is a directory', '/tmp/bareos-restores/my/dir/') # if it's a directory if restorepkt.type == bFileType['FT_REG']: open(FNAME, 'wb').close() restorepkt.create_status = bCFs['CF_EXTRACT'] return bRCs['bRC_OK'] def set_file_attributes(self, context, restorepkt): bareosfd.DebugMessage( context, 100, "set_file_attributes() entry point in Python called with %s\n" % (str(restorepkt))) return bRCs['bRC_OK']; def check_file(self, context, fname): bareosfd.DebugMessage( context, 100, "check_file() entry point in Python called with %s\n" % (fname)) return bRCs['bRC_OK'] def get_acl(self, context, acl): bareosfd.DebugMessage( context, 100, "get_acl() entry point in Python called with %s\n" % (acl)) return bRCs['bRC_OK']; def set_acl(self, context, acl): bareosfd.DebugMessage( context, 100, "set_acl() entry point in Python called with %s\n" % (acl)) return bRCs['bRC_OK']; def get_xattr(self, context, xattr): bareosfd.DebugMessage( context, 100, "get_xattr() entry point in Python called with %s\n" % (xattr)) return bRCs['bRC_OK']; def set_xattr(self, context, xattr): bareosfd.DebugMessage( context, 100, "set_xattr() entry point in Python called with %s\n" % (xattr)) return bRCs['bRC_OK']; def handle_backup_file(self, context, savepkt): bareosfd.DebugMessage( context, 100, "handle_backup_file() entry point in Python called with %s\n" % (savepkt)) return bRCs['bRC_OK'] # vim: ts=4 tabstop=4 expandtab shiftwidth=4 softtabstop=4 bareos-Release-14.2.6/src/plugins/filed/BareosFdPluginLocalFileset.py000066400000000000000000000101201263011562700254720ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Maik Aussendorf # # Bareos python plugins class that adds files from a local list to # the backup fileset import bareosfd from bareos_fd_consts import bJobMessageType, bFileType, bRCs import os import BareosFdPluginBaseclass class BareosFdPluginLocalFileset(BareosFdPluginBaseclass.BareosFdPluginBaseclass): # noqa ''' Simple Bareos-FD-Plugin-Class that parses a file and backups all files listed there Filename is taken from plugin argument 'filename' ''' def parse_plugin_definition(self, context, plugindef): ''' Parses the plugin argmuents and reads files from file given by argument 'filename' ''' # BareosFdPluginBaseclass.parse_plugin_definition(self, context, plugindef); # noqa super(BareosFdPluginLocalFileset, self).parse_plugin_definition( context, plugindef) if ('filename' not in self.options): bareosfd.DebugMessage(context, 100, "Option \'filename\' not defined.\n") return bRCs['bRC_Error'] bareosfd.DebugMessage(context, 100, "Using %s to search for local files\n" % (self.options['filename'])) if os.path.exists(self.options['filename']): try: config_file = open(self.options['filename'], 'rb') except: bareosfd.DebugMessage(context, 100, "Could not open file %s\n" % (self.options['filename'])) return bRCs['bRC_Error'] else: bareosfd.DebugMessage(context, 100, "File %s does not exist\n" % (self.options['filename'])) return bRCs['bRC_Error'] self.files_to_backup = config_file.read().splitlines() return bRCs['bRC_OK'] def start_backup_file(self, context, savepkt): ''' Defines the file to backup and creates the savepkt. In this example only files (no directories) are allowed ''' bareosfd.DebugMessage(context, 100, "start_backup called\n") if not self.files_to_backup: bareosfd.DebugMessage(context, 100, "No files to backup\n") return bRCs['bRC_Skip'] file_to_backup = self.files_to_backup.pop() bareosfd.DebugMessage(context, 100, "file: " + file_to_backup + "\n") statp = bareosfd.StatPacket() savepkt.statp = statp savepkt.fname = file_to_backup savepkt.type = bFileType['FT_REG'] bareosfd.JobMessage(context, bJobMessageType['M_INFO'], "Starting backup of %s\n" % (file_to_backup)) return bRCs['bRC_OK'] def end_backup_file(self, context): ''' Here we return 'bRC_More' as long as our list files_to_backup is not empty and bRC_OK when we are done ''' bareosfd.DebugMessage( context, 100, "end_backup_file() entry point in Python called\n") if self.files_to_backup: return bRCs['bRC_More'] else: return bRCs['bRC_OK'] # vim: ts=4 tabstop=4 expandtab shiftwidth=4 softtabstop=4 bareos-Release-14.2.6/src/plugins/filed/BareosFdWrapper.py000066400000000000000000000055301263011562700233760ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Maik Aussendorf # # The BareosFdWrapper module. Here is a global object bareos_fd_plugin_object # and wrapper functions, which are directly called out of the bareos-fd. They # are intended to pass the call to a method of an object of type # BareosFdPluginBaseclass (or derived) # use this as global plugin object among your python-fd-plugin modules bareos_fd_plugin_object = None def parse_plugin_definition(context, plugindef): return bareos_fd_plugin_object.parse_plugin_definition(context, plugindef) def handle_plugin_event(context, event): return bareos_fd_plugin_object.handle_plugin_event(context, event) def start_backup_file(context, savepkt): return bareos_fd_plugin_object.start_backup_file(context, savepkt) def end_backup_file(context): return bareos_fd_plugin_object.end_backup_file(context) def start_restore_file(context, cmd): return bareos_fd_plugin_object.start_restore_file(context, cmd) def end_restore_file(context): return bareos_fd_plugin_object.end_restore_file(context) def restore_object_data(context, ROP): return bareos_fd_plugin_object.restore_object_data(context, ROP) def plugin_io(context, IOP): return bareos_fd_plugin_object.plugin_io(context, IOP) def create_file(context, restorepkt): return bareos_fd_plugin_object.create_file(context, restorepkt) def set_file_attributes(context, restorepkt): return bareos_fd_plugin_object.set_file_attributes(context, restorepkt) def check_file(context, fname): return bareos_fd_plugin_object.check_file(context, fname) def get_acl(context, acl): return bareos_fd_plugin_object.get_acl(context, acl) def set_acl(context, acl): return bareos_fd_plugin_object.set_acl(context, acl) def get_xattr(context, xattr): return bareos_fd_plugin_object.get_xattr(context, xattr) def set_xattr(context, xattr): return bareos_fd_plugin_object.set_xattr(context, xattr) def handle_backup_file(context, savepkt): return bareos_fd_plugin_object.handle_backup_file(context, savepkt) bareos-Release-14.2.6/src/plugins/filed/Makefile.in000066400000000000000000000066171263011562700220520ustar00rootroot00000000000000# # Simple Makefile for building test FD plugins for Bareos # @MCOMMON@ PYTHON_CPPFLAGS += @PYTHON_INC@ srcdir = @srcdir@ VPATH = @srcdir@:../../filed .PATH: @srcdir@ basedir = ../.. # top dir topdir = ../../.. # this dir relative to top dir thisdir = src/plugins/filed INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include -I$(basedir)/filed BUILD_PLUGINS = @BUILD_FD_PLUGINS@ .SUFFIXES: .c .lo # inference rules .c.lo: $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) -c $< all: Makefile bpipe-fd.la test-plugin-fd.la test-deltaseq-fd.la $(BUILD_PLUGINS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status example-plugin-fd.la: Makefile example-plugin-fd$(DEFAULT_OBJECT_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared example-plugin-fd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version bpipe-fd.la: Makefile bpipe-fd$(DEFAULT_OBJECT_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared bpipe-fd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version python-fd.lo: python-fd.c python-fd.h $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) $(PYTHON_CPPFLAGS) -c $< python-fd.la: Makefile \ python-fd$(DEFAULT_OBJECT_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared python-fd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version \ -L../../lib -lbareos @PYTHON_LIBS@ test-deltaseq-fd.la: Makefile test-deltaseq-fd$(DEFAULT_OBJECT_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared test-deltaseq-fd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version \ -L../../lib -lbareos test-plugin-fd.la: Makefile test-plugin-fd$(DEFAULT_OBJECT_TYPE) ../../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared test-plugin-fd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version \ -L../../lib -lbareoscfg -lbareos plugtest: Makefile fd_plugins.c fileset.c \ ../../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) ../../filed/fd_plugins.c $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) ../../filed/fileset.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../../lib -L../../findlib -o $@ fd_plugins.o fileset.o -lbareosfind -lbareos $(DLIB) -lm $(LIBS) install: all $(MKDIR) $(DESTDIR)$(plugindir) $(CP) *.py *.py.template $(DESTDIR)$(plugindir) $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bpipe-fd.la $(DESTDIR)$(plugindir) $(RMF) $(DESTDIR)$(plugindir)/bpipe-fd.la @for plugin in $(BUILD_PLUGINS); do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$plugin $(DESTDIR)$(plugindir); \ $(RMF) $(DESTDIR)$(plugindir)/$$plugin; \ done install-test-plugin: all $(MKDIR) $(DESTDIR)$(plugindir) $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) test-plugin-fd.la $(DESTDIR)$(plugindir) $(RMF) $(DESTDIR)$(plugindir)/test-plugin-fd.la $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) test-deltaseq-fd.la $(DESTDIR)$(plugindir) $(RMF) $(DESTDIR)$(plugindir)/test-deltaseq-fd.la libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) plugtest *.so *.o 1 2 3 distclean: clean @$(RMF) Makefile depend: bareos-Release-14.2.6/src/plugins/filed/bareos-fd-local-fileset.py000066400000000000000000000042351263011562700247340ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Bareos-fd-local-fileset a simple example for a python Bareos FD Plugin using # BareosFdPluginLocalFileset. The plugin argument 'filename' is used to read # all files listed in that file and add it to the fileset # # Author: Maik Aussendorf # # Provided by the Bareos FD Python plugin interface import bareos_fd_consts # This module contains the wrapper functions called by the Bareos-FD, the # functions call the corresponding methods from your plugin class import BareosFdWrapper # from BareosFdWrapper import parse_plugin_definition, handle_plugin_event, start_backup_file, end_backup_file, start_restore_file, end_restore_file, restore_object_data, plugin_io, create_file, check_file, handle_backup_file # noqa from BareosFdWrapper import * # noqa # This module contains the used plugin class import BareosFdPluginLocalFileset def load_bareos_plugin(context, plugindef): ''' This function is called by the Bareos-FD to load the plugin We use it to instantiate the plugin class ''' # BareosFdWrapper.bareos_fd_plugin_object is the module attribute that # holds the plugin class object BareosFdWrapper.bareos_fd_plugin_object = \ BareosFdPluginLocalFileset.BareosFdPluginLocalFileset( context, plugindef) return bareos_fd_consts.bRCs['bRC_OK'] # the rest is done in the Plugin module bareos-Release-14.2.6/src/plugins/filed/bareos-fd-mock-test.py000066400000000000000000000026541263011562700241220ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Maik Aussendorf # # Bareos-fd-mock-test a simple example for a python Bareos FD Plugin using the baseclass # and doing nothing # You may take this as a skeleton for your plugin from bareosfd import * from bareos_fd_consts import * from BareosFdPluginBaseclass import * from BareosFdWrapper import * def load_bareos_plugin(context, plugindef): DebugMessage(context, 100, "------ Plugin loader called with " + plugindef + "\n"); BareosFdWrapper.plugin_object = BareosFdPluginBaseclass (context, plugindef); return bRCs['bRC_OK']; # the rest is done in the Plugin module bareos-Release-14.2.6/src/plugins/filed/bareos-fd.py.template000066400000000000000000000140601263011562700240220ustar00rootroot00000000000000# BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Marco van Wieringen # from bareosfd import * from bareos_fd_consts import * from io import open from os import O_WRONLY, O_CREAT def load_bareos_plugin(context, plugindef): DebugMessage(context, 100, "load_bareos_plugin called with param: " + plugindef + "\n"); events = []; events.append(bEventType['bEventJobEnd']); events.append(bEventType['bEventEndBackupJob']); events.append(bEventType['bEventEndFileSet']); events.append(bEventType['bEventHandleBackupFile']); RegisterEvents(context, events); fdname = GetValue(context, bVariable['bVarFDName']); DebugMessage(context, 100, "FDName = " + fdname + "\n"); workingdir = GetValue(context, bVariable['bVarWorkingDir']); DebugMessage(context, 100, "WorkingDir = " + workingdir + "\n"); return bRCs['bRC_OK']; def parse_plugin_definition(context, plugindef): global file_to_backup; DebugMessage(context, 100, "parse_plugin_definition called with param: " + plugindef + "\n"); file_to_backup = "Unknown"; plugin_options = plugindef.split(":"); for current_option in plugin_options: key,sep,val = current_option.partition("="); if val == '': continue; elif key == 'module_path': continue; elif key == 'module_name': continue; elif key == 'filename': file_to_backup = val; continue; else: DebugMessage(context, 100, "parse_plugin_definition unknown option " + key + " with value " + val + "\n"); return bRCs['bRC_Error']; return bRCs['bRC_OK']; def handle_plugin_event(context, event): if event == bEventType['bEventJobEnd']: DebugMessage(context, 100, "handle_plugin_event called with bEventJobEnd\n"); elif event == bEventType['bEventEndBackupJob']: DebugMessage(context, 100, "handle_plugin_event called with bEventEndBackupJob\n"); elif event == bEventType['bEventEndFileSet']: DebugMessage(context, 100, "handle_plugin_event called with bEventEndFileSet\n"); else: DebugMessage(context, 100, "handle_plugin_event called with event " + str(event) + "\n"); return bRCs['bRC_OK']; def start_backup_file(context, savepkt): DebugMessage(context, 100, "start_backup called\n"); if file_to_backup == 'Unknown': JobMessage(context, bJobMessageType['M_FATAL'], "No filename specified in plugin definition to backup\n"); return bRCs['bRC_Error']; statp = StatPacket(); savepkt.statp = statp; savepkt.fname = file_to_backup; savepkt.type = bFileType['FT_REG']; JobMessage(context, bJobMessageType['M_INFO'], "Starting backup of " + file_to_backup + "\n"); return bRCs['bRC_OK']; def end_backup_file(context): DebugMessage(context, 100, "end_backup_file() entry point in Python called\n") return bRCs['bRC_OK']; def plugin_io(context, IOP): global file DebugMessage(context, 100, "plugin_io called with " + str(IOP) + "\n"); FNAME = IOP.fname; if IOP.func == bIOPS['IO_OPEN']: try: if IOP.flags & (O_CREAT | O_WRONLY): file = open(FNAME, 'wb'); else: file = open(FNAME, 'rb'); except: IOP.status = -1; return bRCs['bRC_Error']; return bRCs['bRC_OK']; elif IOP.func == bIOPS['IO_CLOSE']: file.close(); return bRCs['bRC_OK']; elif IOP.func == bIOPS['IO_SEEK']: return bRCs['bRC_OK']; elif IOP.func == bIOPS['IO_READ']: IOP.buf = bytearray(IOP.count); IOP.status = file.readinto(IOP.buf); IOP.io_errno = 0 return bRCs['bRC_OK']; elif IOP.func == bIOPS['IO_WRITE']: IOP.status = file.write(IOP.buf); IOP.io_errno = 0 return bRCs['bRC_OK']; def start_restore_file(context, cmd): DebugMessage(context, 100, "start_restore_file() entry point in Python called with " + str(cmd) + "\n") return bRCs['bRC_OK']; def end_restore_file(context): DebugMessage(context, 100, "end_restore_file() entry point in Python called\n") return bRCs['bRC_OK']; def create_file(context, restorepkt): DebugMessage(context, 100, "create_file() entry point in Python called with " + str(restorepkt) + "\n") restorepkt.create_status = bCFs['CF_EXTRACT']; return bRCs['bRC_OK']; def set_file_attributes(context, restorepkt): DebugMessage(context, 100, "set_file_attributes() entry point in Python called with " + str(restorepkt) + "\n") return bRCs['bRC_OK']; def check_file(context, fname): DebugMessage(context, 100, "check_file() entry point in Python called with " + str(fname) + "\n") return bRCs['bRC_OK']; def get_acl(context, acl): DebugMessage(context, 100, "get_acl() entry point in Python called with " + str(acl) + "\n") return bRCs['bRC_OK']; def set_acl(context, acl): DebugMessage(context, 100, "set_acl() entry point in Python called with " + str(acl) + "\n") return bRCs['bRC_OK']; def get_xattr(context, xattr): DebugMessage(context, 100, "get_xattr() entry point in Python called with " + str(xattr) + "\n") return bRCs['bRC_OK']; def set_xattr(context, xattr): DebugMessage(context, 100, "set_xattr() entry point in Python called with " + str(xattr) + "\n") return bRCs['bRC_OK']; def restore_object_data(context, restoreobject): DebugMessage(context, 100, "restore_object_data called with " + str(restoreobject) + "\n"); return bRCs['bRC_OK']; def handle_backup_file(context, savepkt): DebugMessage(context, 100, "handle_backup_file called with " + str(savepkt) + "\n"); return bRCs['bRC_OK']; bareos-Release-14.2.6/src/plugins/filed/bareos_fd_consts.py000066400000000000000000000065731263011562700236750ustar00rootroot00000000000000# BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Marco van Wieringen # bJobMessageType = dict( M_ABORT = 1, M_DEBUG = 2, M_FATAL = 3, M_ERROR = 4, M_WARNING = 5, M_INFO = 6, M_SAVED = 7, M_NOTSAVED = 8, M_SKIPPED = 9, M_MOUNT = 10, M_ERROR_TERM = 11, M_TERM = 12, M_RESTORED = 13, M_SECURITY = 14, M_ALERT = 15, M_VOLMGMT = 16 ) bVariable = dict( bVarJobId = 1, bVarFDName = 2, bVarLevel = 3, bVarType = 4, bVarClient = 5, bVarJobName = 6, bVarJobStatus = 7, bVarSinceTime = 8, bVarAccurate = 9, bVarFileSeen = 10, bVarVssObject = 11, bVarVssDllHandle = 12, bVarWorkingDir = 13, bVarWhere = 14, bVarRegexWhere = 15, bVarExePath = 16, bVarVersion = 17, bVarDistName = 19, bVarPrevJobName = 19, bVarPrefixLinks = 20 ) bFileType = dict( FT_LNKSAVED = 1, FT_REGE = 2, FT_REG = 3, FT_LNK = 4, FT_DIREND = 5, FT_SPEC = 6, FT_NOACCESS = 7, FT_NOFOLLOW = 8, FT_NOSTAT = 9, FT_NOCHG = 10, FT_DIRNOCHG = 11, FT_ISARCH = 12, FT_NORECURSE = 13, FT_NOFSCHG = 14, FT_NOOPEN = 15, FT_RAW = 16, FT_FIFO = 17, FT_DIRBEGIN = 18, FT_INVALIDFS = 19, FT_INVALIDDT = 20, FT_REPARSE = 21, FT_PLUGIN = 22, FT_DELETED = 23, FT_BASE = 24, FT_RESTORE_FIRST = 25, FT_JUNCTION = 26, FT_PLUGIN_CONFIG = 27, FT_PLUGIN_CONFIG_FILLED = 28 ) bRCs = dict( bRC_OK = 0, bRC_Stop = 1, bRC_Error = 2, bRC_More = 3, bRC_Term = 4, bRC_Seen = 5, bRC_Core = 6, bRC_Skip = 7, bRC_Cancel = 8 ) bCFs = dict( CF_SKIP = 1, CF_ERROR = 2, CF_EXTRACT = 3, CF_CREATED = 4, CF_CORE = 5 ) bEventType = dict( bEventJobStart = 1, bEventJobEnd = 2, bEventStartBackupJob = 3, bEventEndBackupJob = 4, bEventStartRestoreJob = 5, bEventEndRestoreJob = 6, bEventStartVerifyJob = 7, bEventEndVerifyJob = 8, bEventBackupCommand = 9, bEventRestoreCommand = 10, bEventEstimateCommand = 11, bEventLevel = 12, bEventSince = 13, bEventCancelCommand = 14, bEventVssBackupAddComponents = 15, bEventVssRestoreLoadComponentMetadata = 16, bEventVssRestoreSetComponentsSelected = 17, bEventRestoreObject = 18, bEventEndFileSet = 19, bEventPluginCommand = 20, bEventVssBeforeCloseRestore = 21, bEventVssPrepareSnapshot = 22, bEventOptionPlugin = 23, bEventHandleBackupFile = 24, bEventComponentInfo = 25, bEventNewPluginOptions = 26 ) bIOPS = dict( IO_OPEN = 1, IO_READ = 2, IO_WRITE = 3, IO_CLOSE = 4, IO_SEEK = 5 ) bareos-Release-14.2.6/src/plugins/filed/bpipe-fd.c000066400000000000000000000600411263011562700216260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2012 Free Software Foundation Europe e.V. Copyright (C) 2014-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * A simple pipe plugin for the Bareos File Daemon * * Kern Sibbald, October 2007 */ #include "bareos.h" #include "fd_plugins.h" #include "fd_common.h" static const int dbglvl = 150; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Kern Sibbald" #define PLUGIN_DATE "January 2014" #define PLUGIN_VERSION "2" #define PLUGIN_DESCRIPTION "Bareos Pipe File Daemon Plugin" #define PLUGIN_USAGE "bpipe:file=:reader=:writer=\n" \ " readprogram runs on backup and its stdout is saved\n" \ " writeprogram runs on restore and gets restored data into stdin\n" \ " the data is internally stored as filepath (e.g. mybackup/backup1)" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC endBackupFile(bpContext *ctx); static bRC pluginIO(bpContext *ctx, struct io_pkt *io); static bRC startRestoreFile(bpContext *ctx, const char *cmd); static bRC endRestoreFile(bpContext *ctx); static bRC createFile(bpContext *ctx, struct restore_pkt *rp); static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp); static bRC checkFile(bpContext *ctx, char *fname); static bRC getAcl(bpContext *ctx, acl_pkt *ap); static bRC setAcl(bpContext *ctx, acl_pkt *ap); static bRC getXattr(bpContext *ctx, xattr_pkt *xp); static bRC setXattr(bpContext *ctx, xattr_pkt *xp); static char *apply_rp_codes(struct plugin_ctx * p_ctx); static bRC parse_plugin_definition(bpContext *ctx, void *value); static bRC plugin_has_all_arguments(bpContext *ctx); /* Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; /* Plugin Information block */ static genpInfo pluginInfo = { sizeof(pluginInfo), FD_PLUGIN_INTERFACE_VERSION, FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; /* Plugin entry points for Bareos */ static pFuncs pluginFuncs = { sizeof(pluginFuncs), FD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent, startBackupFile, endBackupFile, startRestoreFile, endRestoreFile, pluginIO, createFile, setFileAttributes, checkFile, getAcl, setAcl, getXattr, setXattr }; /* * Plugin private context */ struct plugin_ctx { boffset_t offset; BPIPE *pfd; /* bpipe() descriptor */ char *plugin_options; /* Override of plugin options passed in */ char *fname; /* Filename to "backup/restore" */ char *reader; /* Reader program for backup */ char *writer; /* Writer program for backup */ char where[512]; int replace; }; /* * This defines the arguments that the plugin parser understands. */ enum plugin_argument_type { argument_none = 0, argument_file, argument_reader, argument_writer }; struct plugin_argument { const char *name; enum plugin_argument_type type; int cmp_length; }; static plugin_argument plugin_arguments[] = { { "file=", argument_file, 4 }, { "reader=", argument_reader, 6 }, { "writer=", argument_writer, 6 }, { NULL, argument_none, 0 } }; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. */ /* * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, genpInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { // printf("bpipe-fd: Unloaded\n"); return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. */ /* * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(struct plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ bfuncs->registerBareosEvents(ctx, 6, bEventNewPluginOptions, bEventPluginCommand, bEventJobStart, bEventRestoreCommand, bEventEstimateCommand, bEventBackupCommand); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } if (p_ctx->fname) { free(p_ctx->fname); } if (p_ctx->reader) { free(p_ctx->reader); } if (p_ctx->writer) { free(p_ctx->writer); } if (p_ctx->plugin_options) { free(p_ctx->plugin_options); } free(p_ctx); /* free our private context */ p_ctx = NULL; return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) { bRC retval = bRC_OK; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } switch (event->eventType) { case bEventJobStart: Dmsg(ctx, dbglvl, "bpipe-fd: JobStart=%s\n", (char *)value); break; case bEventRestoreCommand: /* * Fall-through wanted */ case bEventBackupCommand: /* * Fall-through wanted */ case bEventEstimateCommand: /* * Fall-through wanted */ case bEventPluginCommand: retval = parse_plugin_definition(ctx, value); break; case bEventNewPluginOptions: /* * Free any previous value. */ if (p_ctx->plugin_options) { free(p_ctx->plugin_options); p_ctx->plugin_options = NULL; } retval = parse_plugin_definition(ctx, value); /* * Save that we got a plugin override. */ p_ctx->plugin_options = bstrdup((char *)value); break; default: Jmsg(ctx, M_FATAL, "bpipe-fd: unknown event=%d\n", event->eventType); Dmsg(ctx, dbglvl, "bpipe-fd: unknown event=%d\n", event->eventType); retval = bRC_Error; break; } return retval; } /* * Start the backup of a specific file */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { time_t now; struct plugin_ctx *p_ctx; if (plugin_has_all_arguments(ctx) != bRC_OK) { return bRC_Error; } p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } now = time(NULL); sp->fname = p_ctx->fname; sp->type = FT_REG; sp->statp.st_mode = 0700 | S_IFREG; sp->statp.st_ctime = now; sp->statp.st_mtime = now; sp->statp.st_atime = now; sp->statp.st_size = -1; sp->statp.st_blksize = 4096; sp->statp.st_blocks = 1; return bRC_OK; } /* * Done with backup of this file */ static bRC endBackupFile(bpContext *ctx) { /* * We would return bRC_More if we wanted startBackupFile to be called again to backup another file */ return bRC_OK; } /* * Bareos is calling us to do the actual I/O */ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } io->status = 0; io->io_errno = 0; switch(io->func) { case IO_OPEN: Dmsg(ctx, dbglvl, "bpipe-fd: IO_OPEN\n"); if (io->flags & (O_CREAT | O_WRONLY)) { char *writer_codes = apply_rp_codes(p_ctx); p_ctx->pfd = open_bpipe(writer_codes, 0, "w"); Dmsg(ctx, dbglvl, "bpipe-fd: IO_OPEN fd=%p writer=%s\n", p_ctx->pfd, writer_codes); if (!p_ctx->pfd) { io->io_errno = errno; Jmsg(ctx, M_FATAL, "Open pipe writer=%s failed: ERR=%s\n", writer_codes, strerror(io->io_errno)); Dmsg(ctx, dbglvl, "Open pipe writer=%s failed: ERR=%s\n", writer_codes, strerror(io->io_errno)); if (writer_codes) { free(writer_codes); } return bRC_Error; } if (writer_codes) { free(writer_codes); } } else { p_ctx->pfd = open_bpipe(p_ctx->reader, 0, "r"); Dmsg(ctx, dbglvl, "bpipe-fd: IO_OPEN fd=%p reader=%s\n", p_ctx->pfd, p_ctx->reader); if (!p_ctx->pfd) { io->io_errno = errno; Jmsg(ctx, M_FATAL, "Open pipe reader=%s failed: ERR=%s\n", p_ctx->reader, strerror(io->io_errno)); Dmsg(ctx, dbglvl, "Open pipe reader=%s failed: ERR=%s\n", p_ctx->reader, strerror(io->io_errno)); return bRC_Error; } } sleep(1); /* let pipe connect */ break; case IO_READ: if (!p_ctx->pfd) { Jmsg(ctx, M_FATAL, "Logic error: NULL read FD\n"); Dmsg(ctx, dbglvl, "Logic error: NULL read FD\n"); return bRC_Error; } io->status = fread(io->buf, 1, io->count, p_ctx->pfd->rfd); if (io->status == 0 && ferror(p_ctx->pfd->rfd)) { io->io_errno = errno; Jmsg(ctx, M_FATAL, "Pipe read error: ERR=%s\n", strerror(io->io_errno)); Dmsg(ctx, dbglvl, "Pipe read error: ERR=%s\n", strerror(io->io_errno)); return bRC_Error; } break; case IO_WRITE: if (!p_ctx->pfd) { Jmsg(ctx, M_FATAL, "Logic error: NULL write FD\n"); Dmsg(ctx, dbglvl, "Logic error: NULL write FD\n"); return bRC_Error; } io->status = fwrite(io->buf, 1, io->count, p_ctx->pfd->wfd); if (io->status == 0 && ferror(p_ctx->pfd->wfd)) { io->io_errno = errno; Jmsg(ctx, M_FATAL, "Pipe write error: ERR=%s\n", strerror(io->io_errno)); Dmsg(ctx, dbglvl, "Pipe write error: ERR=%s\n", strerror(io->io_errno)); return bRC_Error; } break; case IO_CLOSE: if (!p_ctx->pfd) { Jmsg(ctx, M_FATAL, "Logic error: NULL FD on bpipe close\n"); Dmsg(ctx, dbglvl, "Logic error: NULL FD on bpipe close\n"); return bRC_Error; } io->status = close_bpipe(p_ctx->pfd); if (io->status) { Jmsg(ctx, M_FATAL, "bpipe plugin: Error closing stream for pseudo file %s: %d\n", p_ctx->fname, io->status); Dmsg(ctx, dbglvl, "bpipe plugin: Error closing stream for pseudo file %s: %d\n", p_ctx->fname, io->status); } break; case IO_SEEK: io->offset = p_ctx->offset; break; } return bRC_OK; } /* * Bareos is notifying us that a plugin name string was found, and * passing us the plugin command, so we can prepare for a restore. */ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { if (plugin_has_all_arguments(ctx) != bRC_OK) { return bRC_Error; } return bRC_OK; } /* * Bareos is notifying us that the plugin data has terminated, so * the restore for this particular file is done. */ static bRC endRestoreFile(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } return bRC_OK; } /* * This is called during restore to create the file (if necessary) * We must return in rp->create_status: * * CF_ERROR -- error * CF_SKIP -- skip processing this file * CF_EXTRACT -- extract the file (i.e.call i/o routines) * CF_CREATED -- created, but no content to extract (typically directories) * */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { if (strlen(rp->where) > 512) { printf("Restore target dir too long. Restricting to first 512 bytes.\n"); } bstrncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 513); ((struct plugin_ctx *)ctx->pContext)->replace = rp->replace; rp->create_status = CF_EXTRACT; return bRC_OK; } /* * We will get here if the File is a directory after everything * is written in the directory. */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { return bRC_OK; } /* * When using Incremental dump, all previous dumps are necessary */ static bRC checkFile(bpContext *ctx, char *fname) { return bRC_OK; } static bRC getAcl(bpContext *ctx, acl_pkt *ap) { return bRC_OK; } static bRC setAcl(bpContext *ctx, acl_pkt *ap) { return bRC_OK; } static bRC getXattr(bpContext *ctx, xattr_pkt *xp) { return bRC_OK; } static bRC setXattr(bpContext *ctx, xattr_pkt *xp) { return bRC_OK; } /* * Apply codes in writer command: * %w -> "where" * %r -> "replace" * * Replace: * 'always' => 'a', chr(97) * 'ifnewer' => 'w', chr(119) * 'ifolder' => 'o', chr(111) * 'never' => 'n', chr(110) * * This function will allocate the required amount of memory with malloc. * Need to be free()d manually. * Inspired by edit_job_codes in lib/util.c */ static char *apply_rp_codes(struct plugin_ctx * p_ctx) { char *p, *q; const char *str; char add[10]; int w_count = 0, r_count = 0; char *omsg; char *imsg = p_ctx->writer; if (!imsg) { return NULL; } if ((p = imsg)) { while ((q = strstr(p, "%w"))) { w_count++; p=q+1; } p = imsg; while ((q = strstr(p, "%r"))) { r_count++; p=q+1; } } /* * Required mem: * len(imsg) * + number of "where" codes * (len(where)-2) * - number of "replace" codes */ omsg = (char*)malloc(strlen(imsg) + (w_count * (strlen(p_ctx->where)-2)) - r_count + 1); if (!omsg) { fprintf(stderr, "Out of memory."); return NULL; } *omsg = 0; for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'w': str = p_ctx->where; break; case 'r': snprintf(add, 2, "%c", p_ctx->replace); str = add; break; default: add[0] = '%'; add[1] = *p; add[2] = 0; str = add; break; } } else { add[0] = *p; add[1] = 0; str = add; } strcat(omsg, str); } return omsg; } /* * Strip any backslashes in the string. */ static inline void strip_back_slashes(char *value) { char *bp; bp = value; while (*bp) { switch (*bp) { case '\\': bstrinlinecpy(bp, bp + 1); break; default: break; } bp++; } } /* * Parse a boolean value e.g. check if its yes or true anything else translates to false. */ static inline bool parse_boolean(const char *argument_value) { if (bstrcasecmp(argument_value, "yes") || bstrcasecmp(argument_value, "true")) { return true; } else { return false; } } /* * Only set destination to value when it has no previous setting. */ static inline void set_string_if_null(char **destination, char *value) { if (!*destination) { *destination = bstrdup(value); strip_back_slashes(*destination); } } /* * Always set destination to value and clean any previous one. */ static inline void set_string(char **destination, char *value) { if (*destination) { free(*destination); } *destination = bstrdup(value); strip_back_slashes(*destination); } /* * Parse the plugin definition passed in. * * The definition is in this form: * * bpipe:file=:read=:write= */ static bRC parse_plugin_definition(bpContext *ctx, void *value) { int i, cnt; char *plugin_definition, *bp, *argument, *argument_value; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; bool keep_existing; bool compatible = true; if (!p_ctx || !value) { return bRC_Error; } keep_existing = (p_ctx->plugin_options) ? true : false; /* * Parse the plugin definition. * Make a private copy of the whole string. */ plugin_definition = bstrdup((char *)value); bp = strchr(plugin_definition, ':'); if (!bp) { Jmsg(ctx, M_FATAL, "Illegal plugin definition %s\n", plugin_definition); Dmsg(ctx, dbglvl, "Illegal plugin definition %s\n", plugin_definition); goto bail_out; } /* * Skip the first ':' */ bp++; /* * See if we are parsing a new plugin definition e.g. one with keywords. */ argument = bp; while (argument) { if (strlen(argument) == 0) { break; } for (i = 0; plugin_arguments[i].name; i++) { if (bstrncasecmp(argument, plugin_arguments[i].name, strlen(plugin_arguments[i].name))) { compatible = false; break; } } if (!plugin_arguments[i].name && !compatible) { /* * Parsing something fishy ? e.g. partly with known keywords. */ Jmsg(ctx, M_FATAL, "Found mixing of old and new syntax, please fix your plugin definition\n", plugin_definition); Dmsg(ctx, dbglvl, "Found mixing of old and new syntax, please fix your plugin definition\n", plugin_definition); goto bail_out; } argument = strchr(argument, ':'); if (argument) { argument++; } } /* * Start processing the definition, if compatible is left set we are pretending that we are * parsing a plugin definition in the old syntax and hope for the best. */ cnt = 1; while (bp) { if (strlen(bp) == 0) { break; } argument = bp; if (compatible) { char **str_destination = NULL; /* * See if there are more arguments and setup for the next run. */ do { bp = strchr(bp, ':'); if (bp) { if (*(bp - 1) != '\\') { *bp++ = '\0'; break; } else { bp++; } } } while (bp); /* * See which field this is in the argument string. */ switch (cnt) { case 1: str_destination = &p_ctx->fname; break; case 2: str_destination = &p_ctx->reader; break; case 3: str_destination = &p_ctx->writer; break; default: break; } if (str_destination) { if (keep_existing) { /* * Keep the first value, ignore any next setting. */ set_string_if_null(str_destination, argument); } else { /* * Overwrite any existing value. */ set_string(str_destination, argument); } } } else { /* * Each argument is in the form: * = * * So we setup the right pointers here, argument to the beginning * of the argument, argument_value to the beginning of the argument_value. */ argument_value = strchr(bp, '='); *argument_value++ = '\0'; /* * See if there are more arguments and setup for the next run. */ bp = argument_value; do { bp = strchr(bp, ':'); if (bp) { if (*(bp - 1) != '\\') { *bp++ = '\0'; break; } else { bp++; } } } while (bp); for (i = 0; plugin_arguments[i].name; i++) { if (bstrncasecmp(argument, plugin_arguments[i].name, plugin_arguments[i].cmp_length)) { char **str_destination = NULL; switch (plugin_arguments[i].type) { case argument_file: str_destination = &p_ctx->fname; break; case argument_reader: str_destination = &p_ctx->reader; break; case argument_writer: str_destination = &p_ctx->writer; break; default: break; } if (str_destination) { if (keep_existing) { /* * Keep the first value, ignore any next setting. */ set_string_if_null(str_destination, argument_value); } else { /* * Overwrite any existing value. */ set_string(str_destination, argument_value); } } /* * When we have a match break the loop. */ break; } } /* * Got an invalid keyword ? */ if (!plugin_arguments[i].name) { Jmsg(ctx, M_FATAL, "Illegal argument %s with value %s in plugin definition\n", argument, argument_value); Dmsg(ctx, dbglvl, "Illegal argument %s with value %s in plugin definition\n", argument, argument_value); goto bail_out; } } cnt++; } free(plugin_definition); return bRC_OK; bail_out: free(plugin_definition); return bRC_Error; } static bRC plugin_has_all_arguments(bpContext *ctx) { bRC retval = bRC_OK; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { retval = bRC_Error; } if (!p_ctx->fname) { Jmsg(ctx, M_FATAL, _("Plugin File argument not specified.\n")); Dmsg(ctx, dbglvl, "Plugin File argument not specified.\n"); retval = bRC_Error; } if (!p_ctx->reader) { Jmsg(ctx, M_FATAL, _("Plugin Reader argument not specified.\n")); Dmsg(ctx, dbglvl, "Plugin Reader argument not specified.\n"); retval = bRC_Error; } if (!p_ctx->writer) { Jmsg(ctx, M_FATAL, _("Plugin Writer argument not specified.\n")); Dmsg(ctx, dbglvl, "Plugin Writer argument not specified.\n"); retval = bRC_Error; } return retval; } bareos-Release-14.2.6/src/plugins/filed/example-plugin-fd.c000066400000000000000000000213751263011562700234650ustar00rootroot00000000000000/* Copyright (C) 2007-2012 Kern Sibbald You may freely use this code to create your own plugin provided it is to write a plugin for Bareos licensed under AGPLv3 (as Bareos is), and in that case, you may also remove the above Copyright and this notice as well as modify the code in any way. */ #define BUILD_PLUGIN #define BUILDING_DLL /* required for Windows plugin */ #include "bareos.h" #include "fd_plugins.h" #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Your name" #define PLUGIN_DATE "January 2010" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "Test File Daemon Plugin" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC endBackupFile(bpContext *ctx); static bRC pluginIO(bpContext *ctx, struct io_pkt *io); static bRC startRestoreFile(bpContext *ctx, const char *cmd); static bRC endRestoreFile(bpContext *ctx); static bRC createFile(bpContext *ctx, struct restore_pkt *rp); static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp); static bRC checkFile(bpContext *ctx, char *fname); static bRC getAcl(bpContext *ctx, acl_pkt *ap); static bRC setAcl(bpContext *ctx, acl_pkt *ap); static bRC getXattr(bpContext *ctx, xattr_pkt *xp); static bRC setXattr(bpContext *ctx, xattr_pkt *xp); /* Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), FD_PLUGIN_INTERFACE_VERSION, FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION }; static pFuncs pluginFuncs = { sizeof(pluginFuncs), FD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent, startBackupFile, endBackupFile, startRestoreFile, endRestoreFile, pluginIO, createFile, setFileAttributes, checkFile, getAcl, setAcl, getXattr, setXattr }; #ifdef __cplusplus extern "C" { #endif /* * Plugin called here when it is first loaded */ bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, genpInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * Plugin called here when it is unloaded, normally when * Bareos is going to exit. */ bRC unloadPlugin() { printf("plugin: Unloaded\n"); return bRC_OK; } #ifdef __cplusplus } #endif /* * Called here to make a new instance of the plugin -- i.e. when * a new Job is started. There can be multiple instances of * each plugin that are running at the same time. Your * plugin instance must be thread safe and keep its own * local data. */ static bRC newPlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bVarJobId, (void *)&JobId); // printf("plugin: newPlugin JobId=%d\n", JobId); bfuncs->registerBareosEvents(ctx, 11, bEventJobStart, bEventJobEnd, bEventStartBackupJob, bEventEndBackupJob, bEventLevel, bEventSince, bEventStartRestoreJob, bEventEndRestoreJob, bEventRestoreCommand, bEventBackupCommand, bEventComponentInfo); return bRC_OK; } /* * Release everything concerning a particular instance of a * plugin. Normally called when the Job terminates. */ static bRC freePlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bVarJobId, (void *)&JobId); // printf("plugin: freePlugin JobId=%d\n", JobId); return bRC_OK; } /* * Called by core code to get a variable from the plugin. * Not currently used. */ static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) { // printf("plugin: getPluginValue var=%d\n", var); return bRC_OK; } /* * Called by core code to set a plugin variable. * Not currently used. */ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) { // printf("plugin: setPluginValue var=%d\n", var); return bRC_OK; } /* * Called by Bareos when there are certain events that the * plugin might want to know. The value depends on the * event. */ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) { char *name; switch (event->eventType) { case bEventJobStart: printf("plugin: JobStart=%s\n", NPRT((char *)value)); break; case bEventJobEnd: printf("plugin: JobEnd\n"); break; case bEventStartBackupJob: printf("plugin: BackupStart\n"); break; case bEventEndBackupJob: printf("plugin: BackupEnd\n"); break; case bEventLevel: printf("plugin: JobLevel=%c %d\n", (int64_t)value, (int64_t)value); break; case bEventSince: printf("plugin: since=%d\n", (int64_t)value); break; case bEventStartRestoreJob: printf("plugin: StartRestoreJob\n"); break; case bEventEndRestoreJob: printf("plugin: EndRestoreJob\n"); break; case bEventRestoreCommand: /* * Plugin command e.g. plugin = ::command */ printf("plugin: backup command=%s\n", NPRT((char *)value)); break; case bEventBackupCommand: /* * Plugin command e.g. plugin = ::command */ printf("plugin: backup command=%s\n", NPRT((char *)value)); break; case bEventComponentInfo: printf("plugin: Component=%s\n", NPRT((char *)value)); break; default: printf("plugin: unknown event=%d\n", event->eventType); } bfuncs->getBareosValue(ctx, bVarFDName, (void *)&name); return bRC_OK; } /* * Called when starting to backup a file. Here the plugin must * return the "stat" packet for the directory/file and provide * certain information so that Bareos knows what the file is. * The plugin can create "Virtual" files by giving them a * name that is not normally found on the file system. */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { return bRC_OK; } /* * Done backing up a file. */ static bRC endBackupFile(bpContext *ctx) { return bRC_OK; } /* * Do actual I/O. Bareos calls this after startBackupFile * or after startRestoreFile to do the actual file input or output. */ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) { io->status = 0; io->io_errno = 0; switch(io->func) { case IO_OPEN: printf("plugin: IO_OPEN\n"); break; case IO_READ: printf("plugin: IO_READ buf=%p len=%d\n", io->buf, io->count); break; case IO_WRITE: printf("plugin: IO_WRITE buf=%p len=%d\n", io->buf, io->count); break; case IO_CLOSE: printf("plugin: IO_CLOSE\n"); break; } return bRC_OK; } static bRC startRestoreFile(bpContext *ctx, const char *cmd) { return bRC_OK; } static bRC endRestoreFile(bpContext *ctx) { return bRC_OK; } /* * Called here to give the plugin the information needed to * re-create the file on a restore. It basically gets the * stat packet that was created during the backup phase. * This data is what is needed to create the file, but does * not contain actual file data. */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { return bRC_OK; } /* * Called after the file has been restored. This can be used to set directory permissions, ... */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { return bRC_OK; } static bRC getAcl(bpContext *ctx, acl_pkt *ap) { return bRC_OK; } static bRC setAcl(bpContext *ctx, acl_pkt *ap) { return bRC_OK; } static bRC getXattr(bpContext *ctx, xattr_pkt *xp) { return bRC_OK; } static bRC setXattr(bpContext *ctx, xattr_pkt *xp) { return bRC_OK; } /* * When using Incremental dump, all previous dumps are necessary */ static bRC checkFile(bpContext *ctx, char *fname) { return bRC_OK; } bareos-Release-14.2.6/src/plugins/filed/fd_common.h000066400000000000000000000075241263011562700221150ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2010-2011 Bacula Systems(R) SA This program is Free Software; you can modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* You can include this file to your plugin to have * access to some common tools and utilities provided by Bareos */ #ifndef PCOMMON_H #define PCOMMON_H #define JT_BACKUP 'B' /* Backup Job */ #define JT_RESTORE 'R' /* Restore Job */ #define L_FULL 'F' /* Full backup */ #define L_INCREMENTAL 'I' /* since last backup */ #define L_DIFFERENTIAL 'D' /* since last full backup */ #ifndef DLL_IMP_EXP #if defined(BUILDING_DLL) #define DLL_IMP_EXP _declspec(dllexport) #elif defined(USING_DLL) #define DLL_IMP_EXP _declspec(dllimport) #else #define DLL_IMP_EXP #endif #endif DLL_IMP_EXP void *sm_malloc(const char *fname, int lineno, unsigned int nbytes); DLL_IMP_EXP void sm_free(const char *file, int line, void *fp); DLL_IMP_EXP void *reallymalloc(const char *fname, int lineno, unsigned int nbytes); DLL_IMP_EXP void reallyfree(const char *file, int line, void *fp); #ifndef bmalloc #define bmalloc(s) sm_malloc(__FILE__, __LINE__, (s)) #define bfree(o) sm_free(__FILE__, __LINE__, (o)) #endif #define SM_CHECK sm_check(__FILE__, __LINE__, false) #ifdef malloc #undef malloc #undef free #endif #define malloc(s) sm_malloc(__FILE__, __LINE__, (s)) #define free(o) sm_free(__FILE__, __LINE__, (o)) inline void *operator new(size_t size, char const * file, int line) { void *pnew = sm_malloc(file,line, size); memset((char *)pnew, 0, size); return pnew; } inline void *operator new[](size_t size, char const * file, int line) { void *pnew = sm_malloc(file, line, size); memset((char *)pnew, 0, size); return pnew; } inline void *operator new(size_t size) { void *pnew = sm_malloc(__FILE__, __LINE__, size); memset((char *)pnew, 0, size); return pnew; } inline void *operator new[](size_t size) { void *pnew = sm_malloc(__FILE__, __LINE__, size); memset((char *)pnew, 0, size); return pnew; } #define new new(__FILE__, __LINE__) inline void operator delete(void *buf) { sm_free( __FILE__, __LINE__, buf); } inline void operator delete[] (void *buf) { sm_free(__FILE__, __LINE__, buf); } #define Dmsg(context, level, ...) bfuncs->DebugMessage(context, __FILE__, __LINE__, level, __VA_ARGS__ ) #define Jmsg(context, type, ...) bfuncs->JobMessage(context, __FILE__, __LINE__, type, 0, __VA_ARGS__ ) #ifdef USE_ADD_DRIVE /* Keep drive letters for windows vss snapshot */ static void add_drive(char *drives, int *nCount, char *fname) { if (strlen(fname) >= 2 && B_ISALPHA(fname[0]) && fname[1] == ':') { /* always add in uppercase */ char ch = toupper(fname[0]); /* if not found in string, add drive letter */ if (!strchr(drives,ch)) { drives[*nCount] = ch; drives[*nCount+1] = 0; (*nCount)++; } } } /* Copy our drive list to Bareos core list */ static void copy_drives(char *drives, char *dest) { int last = strlen(dest); /* dest is 27 bytes long */ for (char *p = drives; *p && last < 26; p++) { if (!strchr(dest, *p)) { dest[last++] = *p; dest[last] = 0; } } } #endif #endif bareos-Release-14.2.6/src/plugins/filed/python-fd.c000066400000000000000000002627501263011562700220630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Python plugin for the Bareos File Daemon * * Marco van Wieringen, August 2012 */ #define BUILD_PLUGIN #define BUILDING_DLL /* required for Windows plugin */ #include "bareos.h" #include "fd_plugins.h" #include "fd_common.h" #undef _POSIX_C_SOURCE #include #if (PY_VERSION_HEX < 0x02060000) #error "Need at least Python version 2.6 or newer" #endif static const int dbglvl = 150; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Marco van Wieringen" #define PLUGIN_DATE "May 2014" #define PLUGIN_VERSION "3" #define PLUGIN_DESCRIPTION "Python File Daemon Plugin" #define PLUGIN_USAGE "python:module_path=:module_name=" /* * Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC endBackupFile(bpContext *ctx); static bRC pluginIO(bpContext *ctx, struct io_pkt *io); static bRC startRestoreFile(bpContext *ctx, const char *cmd); static bRC endRestoreFile(bpContext *ctx); static bRC createFile(bpContext *ctx, struct restore_pkt *rp); static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp); static bRC checkFile(bpContext *ctx, char *fname); static bRC getAcl(bpContext *ctx, acl_pkt *ap); static bRC setAcl(bpContext *ctx, acl_pkt *ap); static bRC getXattr(bpContext *ctx, xattr_pkt *xp); static bRC setXattr(bpContext *ctx, xattr_pkt *xp); static bRC parse_plugin_definition(bpContext *ctx, void *value); static void PyErrorHandler(bpContext *ctx, int msgtype); static bRC PyLoadModule(bpContext *ctx, void *value); static bRC PyParsePluginDefinition(bpContext *ctx, void *value); static bRC PyGetPluginValue(bpContext *ctx, pVariable var, void *value); static bRC PySetPluginValue(bpContext *ctx, pVariable var, void *value); static bRC PyHandlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC PyStartBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC PyEndBackupFile(bpContext *ctx); static bRC PyPluginIO(bpContext *ctx, struct io_pkt *io); static bRC PyStartRestoreFile(bpContext *ctx, const char *cmd); static bRC PyEndRestoreFile(bpContext *ctx); static bRC PyCreateFile(bpContext *ctx, struct restore_pkt *rp); static bRC PySetFileAttributes(bpContext *ctx, struct restore_pkt *rp); static bRC PyCheckFile(bpContext *ctx, char *fname); static bRC PyGetAcl(bpContext *ctx, acl_pkt *ap); static bRC PySetAcl(bpContext *ctx, acl_pkt *ap); static bRC PyGetXattr(bpContext *ctx, xattr_pkt *xp); static bRC PySetXattr(bpContext *ctx, xattr_pkt *xp); static bRC PyRestoreObjectData(bpContext *ctx, struct restore_object_pkt *rop); static bRC PyHandleBackupFile(bpContext *ctx, struct save_pkt *sp); /* * Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), FD_PLUGIN_INTERFACE_VERSION, FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; static pFuncs pluginFuncs = { sizeof(pluginFuncs), FD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent, startBackupFile, endBackupFile, startRestoreFile, endRestoreFile, pluginIO, createFile, setFileAttributes, checkFile, getAcl, setAcl, getXattr, setXattr }; /* * Plugin private context */ struct plugin_ctx { int32_t backup_level; /* Backup level e.g. Full/Differential/Incremental */ utime_t since; /* Since time for Differential/Incremental */ bool python_loaded; /* Plugin is loaded ? */ char *plugin_options; /* Plugin Option string */ char *module_path; /* Plugin Module Path */ char *module_name; /* Plugin Module Name */ char *fname; /* Next filename to save */ char *link; /* Target symlink points to */ char *object_name; /* Restore Object Name */ char *object; /* Restore Object Content */ PyThreadState *interpreter; /* Python interpreter for this instance of the plugin */ PyObject *pModule; /* Python Module pointer */ PyObject *pDict; /* Python Dictionary */ PyObject *bpContext; /* Python representation of plugin context */ }; #include "python-fd.h" /* * We don't actually use this but we need it to tear down the * final python interpreter on unload of the plugin. Each instance of * the plugin get its own interpreter. */ static PyThreadState *mainThreadState; #ifdef __cplusplus extern "C" { #endif /* * Plugin called here when it is first loaded */ bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, genpInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* Set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* Return pointer to our info */ *pfuncs = &pluginFuncs; /* Return pointer to our functions */ /* * Setup Python */ Py_InitializeEx(0); PyEval_InitThreads(); mainThreadState = PyEval_SaveThread(); return bRC_OK; } /* * Plugin called here when it is unloaded, normally when Bareos is going to exit. */ bRC unloadPlugin() { /* * Terminate Python */ PyEval_RestoreThread(mainThreadState); Py_Finalize(); return bRC_OK; } #ifdef __cplusplus } #endif /* * Called here to make a new instance of the plugin -- i.e. when * a new Job is started. There can be multiple instances of * each plugin that are running at the same time. Your * plugin instance must be thread safe and keep its own * local data. */ static bRC newPlugin(bpContext *ctx) { struct plugin_ctx *p_ctx; p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(struct plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ /* * For each plugin instance we instantiate a new Python interpreter. */ PyEval_AcquireLock(); p_ctx->interpreter = Py_NewInterpreter(); PyEval_ReleaseThread(p_ctx->interpreter); /* * Always register some events the python plugin itself can register * any other events it is interested in. */ bfuncs->registerBareosEvents(ctx, 9, bEventLevel, bEventSince, bEventNewPluginOptions, bEventPluginCommand, bEventJobStart, bEventRestoreCommand, bEventEstimateCommand, bEventBackupCommand, bEventRestoreObject); return bRC_OK; } /* * Release everything concerning a particular instance of a * plugin. Normally called when the Job terminates. */ static bRC freePlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } if (p_ctx->plugin_options) { free(p_ctx->plugin_options); } if (p_ctx->module_path) { free(p_ctx->module_path); } if (p_ctx->module_name) { free(p_ctx->module_name); } if (p_ctx->fname) { free(p_ctx->fname); } if (p_ctx->link) { free(p_ctx->link); } if (p_ctx->object_name) { free(p_ctx->object_name); } if (p_ctx->object) { free(p_ctx->object); } /* * Stop any sub interpreter started per plugin instance. */ PyEval_AcquireThread(p_ctx->interpreter); /* * Do python cleanup calls. */ if (p_ctx->bpContext) { Py_DECREF(p_ctx->bpContext); } if (p_ctx->pModule) { Py_DECREF(p_ctx->pModule); } Py_EndInterpreter(p_ctx->interpreter); PyEval_ReleaseLock(); free(p_ctx); ctx->pContext = NULL; return bRC_OK; } /* * Called by core code to get a variable from the plugin. * Not currently used. */ static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyGetPluginValue(ctx, var, value); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Called by core code to set a plugin variable. * Not currently used. */ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; if (!p_ctx) { return bRC_Error; } PyEval_AcquireThread(p_ctx->interpreter); retval = PySetPluginValue(ctx, var, value); PyEval_ReleaseThread(p_ctx->interpreter); return retval; } /* * Called by Bareos when there are certain events that the * plugin might want to know. The value depends on the event. */ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) { bool event_dispatched = false; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; if (!p_ctx) { goto bail_out; } /* * First handle some events internally before calling python if it * want to do some special handling on the event triggered. */ switch (event->eventType) { case bEventLevel: p_ctx->backup_level = (int64_t)value; break; case bEventSince: p_ctx->since = (int64_t)value; break; case bEventBackupCommand: /* * Fall-through wanted */ case bEventRestoreCommand: /* * Fall-through wanted */ case bEventEstimateCommand: /* * Fall-through wanted */ case bEventPluginCommand: event_dispatched = true; retval = parse_plugin_definition(ctx, value); break; case bEventNewPluginOptions: /* * Free any previous value. */ if (p_ctx->plugin_options) { free(p_ctx->plugin_options); p_ctx->plugin_options = NULL; } event_dispatched = true; retval = parse_plugin_definition(ctx, value); /* * Save that we got a plugin override. */ p_ctx->plugin_options = bstrdup((char *)value); break; case bEventRestoreObject: { struct restore_object_pkt *rop; rop = (struct restore_object_pkt *)value; /* * Only use the plugin definition of a restore object if we * didn't get any other plugin definition from some other source before. */ if (!p_ctx->python_loaded) { if (rop && *rop->plugin_name) { event_dispatched = true; retval = parse_plugin_definition(ctx, rop->plugin_name); } } break; } default: break; } /* * See if we have been triggered in the previous switch if not we have to * always dispatch the event. If we already processed the event internally * we only do a dispatch to the python entry point when that internal processing * was successfull (e.g. retval == bRC_OK). */ if (!event_dispatched || retval == bRC_OK) { PyEval_AcquireThread(p_ctx->interpreter); /* * Now dispatch the event to Python. * First the calls that need special handling. */ switch (event->eventType) { case bEventBackupCommand: /* * Fall-through wanted */ case bEventRestoreCommand: /* * Fall-through wanted */ case bEventEstimateCommand: /* * Fall-through wanted */ case bEventPluginCommand: /* * Fall-through wanted */ case bEventNewPluginOptions: /* * See if we already loaded the Python modules. */ if (!p_ctx->python_loaded) { retval = PyLoadModule(ctx, value); } /* * Only try to call when the loading succeeded. */ if (retval == bRC_OK) { retval = PyParsePluginDefinition(ctx, value); } break; case bEventRestoreObject: { struct restore_object_pkt *rop; rop = (struct restore_object_pkt *)value; if (!rop) { /* * If rop == NULL this means we got the last restore object. * No need to call into python so just return. */ retval = bRC_OK; } else { /* * See if we already loaded the Python modules. */ if (!p_ctx->python_loaded && *rop->plugin_name) { retval = PyLoadModule(ctx, rop->plugin_name); /* * Only try to call when the loading succeeded. */ if (retval == bRC_OK) { retval = PyParsePluginDefinition(ctx, rop->plugin_name); if (retval == bRC_OK) { retval = PyRestoreObjectData(ctx, rop); } } } else { retval = PyRestoreObjectData(ctx, rop); } } break; } case bEventHandleBackupFile: retval = PyHandleBackupFile(ctx, (struct save_pkt *)value); break; default: /* * Handle the generic events e.g. the ones which are just passed on. * We only try to call Python when we loaded the right module until * that time we pretend the call succeeded. */ if (p_ctx->python_loaded) { retval = PyHandlePluginEvent(ctx, event, value); } else { retval = bRC_OK; } break; } PyEval_ReleaseThread(p_ctx->interpreter); } bail_out: return retval; } /* * Called when starting to backup a file. Here the plugin must * return the "stat" packet for the directory/file and provide * certain information so that Bareos knows what the file is. * The plugin can create "Virtual" files by giving them a * name that is not normally found on the file system. */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyStartBackupFile(ctx, sp); PyEval_ReleaseThread(p_ctx->interpreter); /* * For Incremental and Differential backups use checkChanges method to * see if we need to backup this file. */ switch (p_ctx->backup_level) { case L_INCREMENTAL: case L_DIFFERENTIAL: /* * If the plugin didn't set a save_time but we have a since time * from the bEventSince event we use that as basis for the actual * save_time to check. */ if (sp->save_time == 0 && p_ctx->since) { sp->save_time = p_ctx->since; } switch (bfuncs->checkChanges(ctx, sp)) { case bRC_Seen: switch (sp->type) { case FT_DIRBEGIN: sp->type = FT_DIRNOCHG; break; default: sp->type = FT_NOCHG; break; } break; default: break; } } bail_out: return retval; } /* * Done backing up a file. */ static bRC endBackupFile(bpContext *ctx) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyEndBackupFile(ctx); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Do actual I/O. Bareos calls this after startBackupFile * or after startRestoreFile to do the actual file * input or output. */ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } if (!p_ctx->python_loaded) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyPluginIO(ctx, io); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Start restore of a file. */ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyStartRestoreFile(ctx, cmd); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Done restoring a file. */ static bRC endRestoreFile(bpContext *ctx) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyEndRestoreFile(ctx); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Called here to give the plugin the information needed to * re-create the file on a restore. It basically gets the * stat packet that was created during the backup phase. * This data is what is needed to create the file, but does * not contain actual file data. */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyCreateFile(ctx, rp); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Called after the file has been restored. This can be used to * set directory permissions, ... */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PySetFileAttributes(ctx, rp); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * When using Incremental dump, all previous dumps are necessary */ static bRC checkFile(bpContext *ctx, char *fname) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } if (!p_ctx->python_loaded) { return bRC_OK; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyCheckFile(ctx, fname); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* */ static bRC getAcl(bpContext *ctx, acl_pkt *ap) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyGetAcl(ctx, ap); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* */ static bRC setAcl(bpContext *ctx, acl_pkt *ap) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PySetAcl(ctx, ap); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* */ static bRC getXattr(bpContext *ctx, xattr_pkt *xp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PyGetXattr(ctx, xp); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* */ static bRC setXattr(bpContext *ctx, xattr_pkt *xp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } PyEval_AcquireThread(p_ctx->interpreter); retval = PySetXattr(ctx, xp); PyEval_ReleaseThread(p_ctx->interpreter); bail_out: return retval; } /* * Strip any backslashes in the string. */ static inline void strip_back_slashes(char *value) { char *bp; bp = value; while (*bp) { switch (*bp) { case '\\': bstrinlinecpy(bp, bp + 1); break; default: break; } bp++; } } /* * Parse a boolean value e.g. check if its yes or true anything else translates to false. */ static inline bool parse_boolean(const char *argument_value) { if (bstrcasecmp(argument_value, "yes") || bstrcasecmp(argument_value, "true")) { return true; } else { return false; } } /* * Only set destination to value when it has no previous setting. */ static inline void set_string_if_null(char **destination, char *value) { if (!*destination) { *destination = bstrdup(value); strip_back_slashes(*destination); } } /* * Always set destination to value and clean any previous one. */ static inline void set_string(char **destination, char *value) { if (*destination) { free(*destination); } *destination = bstrdup(value); strip_back_slashes(*destination); } /* * Parse the plugin definition passed in. * * The definition is in this form: * * python:module_path=:module_name=:... */ static bRC parse_plugin_definition(bpContext *ctx, void *value) { int i; bool keep_existing; char *plugin_definition, *bp, *argument, *argument_value; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!value) { return bRC_Error; } keep_existing = (p_ctx->plugin_options) ? true : false; /* * Parse the plugin definition. * Make a private copy of the whole string. */ plugin_definition = bstrdup((char *)value); bp = strchr(plugin_definition, ':'); if (!bp) { Jmsg(ctx, M_FATAL, "Illegal plugin definition %s\n", plugin_definition); Dmsg(ctx, dbglvl, "Illegal plugin definition %s\n", plugin_definition); goto bail_out; } /* * Skip the first ':' */ bp++; while (bp) { if (strlen(bp) == 0) { break; } /* * Each argument is in the form: * = * * So we setup the right pointers here, argument to the beginning * of the argument, argument_value to the beginning of the argument_value. */ argument = bp; argument_value = strchr(bp, '='); if (!argument_value) { Jmsg(ctx, M_FATAL, "Illegal argument %s without value\n", argument); Dmsg(ctx, dbglvl, "Illegal argument %s without value\n", argument); goto bail_out; } *argument_value++ = '\0'; /* * See if there are more arguments and setup for the next run. */ bp = argument_value; do { bp = strchr(bp, ':'); if (bp) { if (*(bp - 1) != '\\') { *bp++ = '\0'; break; } else { bp++; } } } while (bp); for (i = 0; plugin_arguments[i].name; i++) { if (bstrcasecmp(argument, plugin_arguments[i].name)) { char **str_destination = NULL; bool *bool_destination = NULL; switch (plugin_arguments[i].type) { case argument_module_path: str_destination = &p_ctx->module_path; break; case argument_module_name: str_destination = &p_ctx->module_name; break; default: break; } /* * Keep the first value, ignore any next setting. */ if (str_destination) { if (keep_existing) { set_string_if_null(str_destination, argument_value); } else { set_string(str_destination, argument_value); } } /* * Set any boolean variable. */ if (bool_destination) { *bool_destination = parse_boolean(argument_value); } /* * When we have a match break the loop. */ break; } } } free(plugin_definition); return bRC_OK; bail_out: free(plugin_definition); return bRC_Error; } /* * Work around API changes in Python versions. * These function abstract the storage and retrieval of the bpContext * which is passed to the Python methods and which the method can pass * back and which allow the callback function to understand what bpContext * its talking about. */ #if ((PY_VERSION_HEX < 0x02070000) || \ ((PY_VERSION_HEX >= 0x03000000) && \ (PY_VERSION_HEX < 0x03010000))) /* * Python version before 2.7 and 3.0. */ static PyObject *PyCreatebpContext(bpContext *ctx) { /* * Setup a new CObject which holds the bpContext structure used here internally. */ return PyCObject_FromVoidPtr((void *)ctx, NULL); } static bpContext *PyGetbpContext(PyObject *pyCtx) { return (bpContext *)PyCObject_AsVoidPtr(pyCtx); } #else /* * Python version after 2.6 and 3.1. */ static PyObject *PyCreatebpContext(bpContext *ctx) { /* * Setup a new Capsule which holds the bpContext structure used here internally. */ return PyCapsule_New((void *)ctx, "bareos.bpContext", NULL); } static bpContext *PyGetbpContext(PyObject *pyCtx) { return (bpContext *)PyCapsule_GetPointer(pyCtx, "bareos.bpContext"); } #endif /* * Convert a return value into a bRC enum value. */ static inline bRC conv_python_retval(PyObject *pRetVal) { int retval; retval = PyInt_AsLong(pRetVal); return (bRC)retval; } /* * Handle a Python error. * * Python equivalent: * * import traceback, sys * return "".join(traceback.format_exception(sys.exc_type, * sys.exc_value, sys.exc_traceback)) */ static void PyErrorHandler(bpContext *ctx, int msgtype) { PyObject *type, *value, *traceback; PyObject *tracebackModule; char *error_string; PyErr_Fetch(&type, &value, &traceback); tracebackModule = PyImport_ImportModule("traceback"); if (tracebackModule != NULL) { PyObject *tbList, *emptyString, *strRetval; tbList = PyObject_CallMethod(tracebackModule, (char *)"format_exception", (char *)"OOO", type, value == NULL ? Py_None : value, traceback == NULL ? Py_None : traceback); emptyString = PyString_FromString(""); strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList); error_string = bstrdup(PyString_AsString(strRetval)); Py_DECREF(tbList); Py_DECREF(emptyString); Py_DECREF(strRetval); Py_DECREF(tracebackModule); } else { error_string = bstrdup("Unable to import traceback module."); } Py_DECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); Dmsg(ctx, dbglvl, "%s\n", error_string); if (msgtype) { Jmsg(ctx, msgtype, "%s\n", error_string); } free(error_string); } /* * Initial load of the Python module. * * Based on the parsed plugin options we set some prerequisits like the * module path and the module to load. We also load the dictionary used * for looking up the Python methods. */ static bRC PyLoadModule(bpContext *ctx, void *value) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *sysPath, *mPath, *pName, *pFunc, *module; /* * Extend the Python search path with the given module_path. */ if (p_ctx->module_path) { sysPath = PySys_GetObject((char *)"path"); mPath = PyString_FromString(p_ctx->module_path); PyList_Append(sysPath, mPath); Py_DECREF(mPath); } /* * Make our callback methods available for Python. */ module = Py_InitModule("bareosfd", BareosFDMethods); /* * Fill in the slots of PyRestoreObject */ PyRestoreObjectType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyRestoreObjectType) < 0) { goto bail_out; } /* * Fill in the slots of PyStatPacket */ PyStatPacketType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyStatPacketType) < 0) { goto bail_out; } /* * Fill in the slots of PySavePacket */ PySavePacketType.tp_new = PyType_GenericNew; if (PyType_Ready(&PySavePacketType) < 0) { goto bail_out; } /* * Fill in the slots of PyRestorePacket */ PyRestorePacketType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyRestorePacketType) < 0) { goto bail_out; } /* * Fill in the slots of PyIoPacketType */ PyIoPacketType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyIoPacketType) < 0) { goto bail_out; } /* * Fill in the slots of PyAclPacketType */ PyAclPacketType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyAclPacketType) < 0) { goto bail_out; } /* * Fill in the slots of PyXattrPacketType */ PyXattrPacketType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyXattrPacketType) < 0) { goto bail_out; } /* * Add the types to the module */ Py_INCREF(&PyRestoreObjectType); PyModule_AddObject(module, "RestoreObject", (PyObject *)&PyRestoreObjectType); Py_INCREF(&PyStatPacketType); PyModule_AddObject(module, "StatPacket", (PyObject *)&PyStatPacketType); Py_INCREF(&PySavePacketType); PyModule_AddObject(module, "SavePacket", (PyObject *)&PySavePacketType); Py_INCREF(&PyRestorePacketType); PyModule_AddObject(module, "RestorePacket", (PyObject *)&PyRestorePacketType); Py_INCREF(&PyIoPacketType); PyModule_AddObject(module, "IoPacket", (PyObject *)&PyIoPacketType); Py_INCREF(&PyAclPacketType); PyModule_AddObject(module, "AclPacket", (PyObject *)&PyAclPacketType); Py_INCREF(&PyXattrPacketType); PyModule_AddObject(module, "XattrPacket", (PyObject *)&PyXattrPacketType); /* * Try to load the Python module by name. */ if (p_ctx->module_name) { Dmsg(ctx, dbglvl, "Trying to load module with name %s\n", p_ctx->module_name); pName = PyString_FromString(p_ctx->module_name); p_ctx->pModule = PyImport_Import(pName); Py_DECREF(pName); if (!p_ctx->pModule) { Dmsg(ctx, dbglvl, "Failed to load module with name %s\n", p_ctx->module_name); goto bail_out; } Dmsg(ctx, dbglvl, "Sucessfully loaded module with name %s\n", p_ctx->module_name); /* * Get the Python dictionary for lookups in the Python namespace. */ p_ctx->pDict = PyModule_GetDict(p_ctx->pModule); /* Borrowed reference */ /* * Encode the bpContext so a Python method can pass it in on calling back. */ p_ctx->bpContext = PyCreatebpContext(ctx); /* * Lookup the load_bareos_plugin() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "load_bareos_plugin"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pPluginDefinition, *pRetVal; pPluginDefinition = PyString_FromString((char *)value); if (!pPluginDefinition) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pPluginDefinition, NULL); Py_DECREF(pPluginDefinition); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named load_bareos_plugins()\n"); goto bail_out; } } /* * Keep track we successfully loaded. */ p_ctx->python_loaded = true; return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Any plugin options which are passed in are dispatched here to a Python method and it * can parse the plugin options. This function is also called after PyLoadModule() has * loaded the Python module and made sure things are operational. Normally you would only get * one set of plugin options but for a restore overrides can be passed in before the actual * plugin options are restored as part of the restore stream handling. */ static bRC PyParsePluginDefinition(bpContext *ctx, void *value) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the parse_plugin_definition() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "parse_plugin_definition"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pPluginDefinition, *pRetVal; pPluginDefinition = PyString_FromString((char *)value); if (!pPluginDefinition) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pPluginDefinition, NULL); Py_DECREF(pPluginDefinition); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } return retval; } else { Dmsg(ctx, dbglvl, "Failed to find function named parse_plugin_definition()\n"); return bRC_Error; } bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PyGetPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } static bRC PySetPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } static bRC PyHandlePluginEvent(bpContext *ctx, bEvent *event, void *value) { bRC retval = bRC_Error; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the handle_plugin_event() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "handle_plugin_event"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pEventType, *pRetVal; pEventType = PyInt_FromLong(event->eventType); pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pEventType, NULL); Py_DECREF(pEventType); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named handle_plugin_event()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static inline PyStatPacket *NativeToPyStatPacket(struct stat *statp) { PyStatPacket *pStatp = PyObject_New(PyStatPacket, &PyStatPacketType); if (pStatp) { pStatp->dev = statp->st_dev; pStatp->ino = statp->st_ino; pStatp->mode = statp->st_mode; pStatp->nlink = statp->st_nlink; pStatp->uid = statp->st_uid; pStatp->gid = statp->st_gid; pStatp->rdev = statp->st_rdev; pStatp->size = statp->st_size; pStatp->atime = statp->st_atime; pStatp->mtime = statp->st_mtime; pStatp->ctime = statp->st_ctime; pStatp->blksize = statp->st_blksize; pStatp->blocks = statp->st_blocks; } return pStatp; } static inline void PyStatPacketToNative(PyStatPacket *pStatp, struct stat *statp) { statp->st_dev = pStatp->dev; statp->st_ino = pStatp->ino; statp->st_mode = pStatp->mode; statp->st_nlink = pStatp->nlink; statp->st_uid = pStatp->uid; statp->st_gid = pStatp->gid; statp->st_rdev = pStatp->rdev; statp->st_size = pStatp->size; statp->st_atime = pStatp->atime; statp->st_mtime = pStatp->mtime; statp->st_ctime = pStatp->ctime; statp->st_blksize = pStatp->blksize; statp->st_blocks = pStatp->blocks; } static inline PySavePacket *NativeToPySavePacket(struct save_pkt *sp) { PySavePacket *pSavePkt = PyObject_New(PySavePacket, &PySavePacketType); if (pSavePkt) { /* * Initialize the Python SavePkt with the data we got passed in. */ if (sp->fname) { pSavePkt->fname = PyString_FromString(sp->fname); } else { pSavePkt->fname = NULL; } if (sp->link) { pSavePkt->link = PyString_FromString(sp->link); } else { pSavePkt->link = NULL; } if (sp->statp.st_mode) { pSavePkt->statp = (PyObject *)NativeToPyStatPacket(&sp->statp); } else { pSavePkt->statp = NULL; } pSavePkt->type = sp->type; pSavePkt->flags = PyByteArray_FromStringAndSize(sp->flags, sizeof(sp->flags)); pSavePkt->no_read = sp->no_read; pSavePkt->portable = sp->portable; pSavePkt->accurate_found = sp->accurate_found; pSavePkt->cmd = sp->cmd; pSavePkt->save_time = sp->save_time; pSavePkt->delta_seq = sp->delta_seq; pSavePkt->object_name = NULL; pSavePkt->object = NULL; pSavePkt->object_len = sp->object_len; pSavePkt->object_index = sp->index; } return pSavePkt; } static inline bool PySavePacketToNative(PySavePacket *pSavePkt, struct save_pkt *sp, struct plugin_ctx *p_ctx, bool is_options_plugin) { /* * See if this is for an Options Plugin. */ if (!is_options_plugin) { /* * Only copy back the arguments that are allowed to change. */ if (pSavePkt->fname) { /* * As this has to linger as long as the backup is running we save it in our plugin context. */ if (PyString_Check(pSavePkt->fname)) { if (p_ctx->fname) { free(p_ctx->fname); } p_ctx->fname = bstrdup(PyString_AsString(pSavePkt->fname)); sp->fname = p_ctx->fname; } } else { goto bail_out; } /* * Optional field. */ if (pSavePkt->link) { /* * As this has to linger as long as the backup is running we save it in our plugin context. */ if (PyString_Check(pSavePkt->link)) { if (p_ctx->link) { free(p_ctx->link); } p_ctx->link = bstrdup(PyString_AsString(pSavePkt->link)); sp->link = p_ctx->link; } } /* * Handle the stat structure. */ if (pSavePkt->statp) { PyStatPacketToNative((PyStatPacket *)pSavePkt->statp, &sp->statp); } else { goto bail_out; } sp->type = pSavePkt->type; if (PyByteArray_Check(pSavePkt->flags)) { char *flags; if (PyByteArray_Size(pSavePkt->flags) != sizeof(sp->flags)) { goto bail_out; } if ((flags = PyByteArray_AsString(pSavePkt->flags))) { memcpy(sp->flags, flags, sizeof(sp->flags)); } else { goto bail_out; } } else { goto bail_out; } /* * Special code for handling restore objects. */ if (IS_FT_OBJECT(sp->type)) { /* * See if a proper restore object was created. */ if (pSavePkt->object_len > 0) { /* * As this has to linger as long as the backup is running we save it in our plugin context. */ if (pSavePkt->object_name && pSavePkt->object && PyString_Check(pSavePkt->object_name) && PyByteArray_Check(pSavePkt->object)) { char *buf; if (p_ctx->object_name) { free(p_ctx->object_name); } p_ctx->object_name = bstrdup(PyString_AsString(pSavePkt->object_name)); sp->object_name = p_ctx->object_name; sp->object_len = pSavePkt->object_len; sp->index = pSavePkt->object_index; if ((buf = PyByteArray_AsString(pSavePkt->object))) { if (p_ctx->object) { free(p_ctx->object); } p_ctx->object = (char *)malloc(pSavePkt->object_len); memcpy(p_ctx->object, buf, pSavePkt->object_len); sp->object = p_ctx->object; } else { goto bail_out; } } else { goto bail_out; } } else { goto bail_out; } } else { sp->no_read = pSavePkt->no_read; sp->delta_seq = pSavePkt->delta_seq; } } else { sp->no_read = pSavePkt->no_read; sp->delta_seq = pSavePkt->delta_seq; if (PyByteArray_Check(pSavePkt->flags)) { char *flags; if (PyByteArray_Size(pSavePkt->flags) != sizeof(sp->flags)) { goto bail_out; } if ((flags = PyByteArray_AsString(pSavePkt->flags))) { memcpy(sp->flags, flags, sizeof(sp->flags)); } else { goto bail_out; } } else { goto bail_out; } } return true; bail_out: return false; } /* * Called when starting to backup a file. Here the plugin must * return the "stat" packet for the directory/file and provide * certain information so that Bareos knows what the file is. * The plugin can create "Virtual" files by giving them a * name that is not normally found on the file system. */ static bRC PyStartBackupFile(bpContext *ctx, struct save_pkt *sp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the start_backup_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "start_backup_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PySavePacket *pSavePkt; PyObject *pRetVal; pSavePkt = NativeToPySavePacket(sp); if (!pSavePkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, (PyObject *)pSavePkt, NULL); if (!pRetVal) { Py_DECREF((PyObject *)pSavePkt); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); if (!PySavePacketToNative(pSavePkt, sp, p_ctx, false)) { Py_DECREF((PyObject *)pSavePkt); goto bail_out; } Py_DECREF((PyObject *)pSavePkt); } } else { Dmsg(ctx, dbglvl, "Failed to find function named start_backup_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Called at the end of backing up a file for a command plugin. * If the plugin's work is done, it should return bRC_OK. * If the plugin wishes to create another file and back it up, * then it must return bRC_More (not yet implemented). */ static bRC PyEndBackupFile(bpContext *ctx) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the end_backup_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "end_backup_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pRetVal; pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, NULL); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named end_backup_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static inline PyIoPacket *NativeToPyIoPacket(struct io_pkt *io) { PyIoPacket *pIoPkt = PyObject_New(PyIoPacket, &PyIoPacketType); if (pIoPkt) { /* * Initialize the Python IoPkt with the data we got passed in. */ pIoPkt->func = io->func; pIoPkt->count = io->count; pIoPkt->flags = io->flags; pIoPkt->mode = io->mode; pIoPkt->fname = io->fname; pIoPkt->whence = io->whence; pIoPkt->offset = io->offset; if (io->func == IO_WRITE && io->count > 0) { /* * Only initialize the buffer with read data when we are writing and there is data. */ pIoPkt->buf = PyByteArray_FromStringAndSize(io->buf, io->count); if (!pIoPkt->buf) { Py_DECREF((PyObject *)pIoPkt); return (PyIoPacket *)NULL; } } else { pIoPkt->buf = NULL; } /* * These must be set by the Python function but we initialize them to zero * to be sure they have some valid setting an not random data. */ pIoPkt->io_errno = 0; pIoPkt->lerror = 0; pIoPkt->win32 = false; pIoPkt->status = 0; } return pIoPkt; } static inline bool PyIoPacketToNative(PyIoPacket *pIoPkt, struct io_pkt *io) { /* * Only copy back the arguments that are allowed to change. */ io->io_errno = pIoPkt->io_errno; io->lerror = pIoPkt->lerror; io->win32 = pIoPkt->win32; io->status = pIoPkt->status; if (io->func == IO_READ && io->status > 0) { /* * Only copy back the data when doing a read and there is data. */ if (PyByteArray_Check(pIoPkt->buf)) { char *buf; if (PyByteArray_Size(pIoPkt->buf) > io->count || io->status > io->count) { return false; } if (!(buf = PyByteArray_AsString(pIoPkt->buf))) { return false; } memcpy(io->buf, buf, io->status); } } return true; } /* * Do actual I/O. Bareos calls this after startBackupFile * or after startRestoreFile to do the actual file * input or output. */ static bRC PyPluginIO(bpContext *ctx, struct io_pkt *io) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the plugin_io() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "plugin_io"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyIoPacket *pIoPkt; PyObject *pRetVal; pIoPkt = NativeToPyIoPacket(io); if (!pIoPkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, (PyObject *)pIoPkt, NULL); if (!pRetVal) { Py_DECREF((PyObject *)pIoPkt); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); if (!PyIoPacketToNative(pIoPkt, io)) { Py_DECREF((PyObject *)pIoPkt); goto bail_out; } } Py_DECREF((PyObject *)pIoPkt); } else { Dmsg(ctx, dbglvl, "Failed to find function named plugin_io()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } io->status = -1; return retval; } /* * Called when the first record is read from the Volume that was previously written by the command plugin. */ static bRC PyStartRestoreFile(bpContext *ctx, const char *cmd) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the start_restore_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "start_restore_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pCmd, *pRetVal; pCmd = PyString_FromString(cmd); if (!pCmd) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pCmd, NULL); Py_DECREF(pCmd); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named start_restore_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Called when a command plugin is done restoring a file. */ static bRC PyEndRestoreFile(bpContext *ctx) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the end_restore_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "end_restore_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pRetVal; pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, NULL); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named end_restore_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static inline PyRestorePacket *NativeToPyRestorePacket(struct restore_pkt *rp) { PyRestorePacket *pRestorePacket = PyObject_New(PyRestorePacket, &PyRestorePacketType); if (pRestorePacket) { pRestorePacket->stream = rp->stream; pRestorePacket->data_stream = rp->data_stream; pRestorePacket->type = rp->type; pRestorePacket->file_index = rp->file_index; pRestorePacket->LinkFI = rp->LinkFI; pRestorePacket->uid = rp->uid; pRestorePacket->statp = (PyObject *)NativeToPyStatPacket(&rp->statp); pRestorePacket->attrEx = rp->attrEx; pRestorePacket->ofname = rp->ofname; pRestorePacket->olname = rp->olname; pRestorePacket->where = rp->where; pRestorePacket->RegexWhere = rp->RegexWhere; pRestorePacket->replace = rp->replace; pRestorePacket->create_status = rp->create_status; } return pRestorePacket; } static inline void PyRestorePacketToNative(PyRestorePacket *pRestorePacket, struct restore_pkt *rp) { /* * Only copy back the fields that are allowed to be changed. */ rp->create_status = pRestorePacket->create_status; } /* * Called for a command plugin to create a file during a Restore job before restoring the data. * This entry point is called before any I/O is done on the file. After this call, * Bareos will call pluginIO() to open the file for write. * * We must return in rp->create_status: * * CF_ERROR -- error * CF_SKIP -- skip processing this file * CF_EXTRACT -- extract the file (i.e.call i/o routines) * CF_CREATED -- created, but no content to extract (typically directories) */ static bRC PyCreateFile(bpContext *ctx, struct restore_pkt *rp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!rp) { return bRC_Error; } /* * Lookup the create_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "create_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyRestorePacket *pRestorePacket; PyObject *pRetVal; pRestorePacket = NativeToPyRestorePacket(rp); if (!pRestorePacket) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pRestorePacket, NULL); if (!pRetVal) { Py_DECREF(pRestorePacket); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); PyRestorePacketToNative(pRestorePacket, rp); Py_DECREF(pRestorePacket); } } else { Dmsg(ctx, dbglvl, "Failed to find function named create_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PySetFileAttributes(bpContext *ctx, struct restore_pkt *rp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!rp) { return bRC_Error; } /* * Lookup the set_file_attributes() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "set_file_attributes"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyRestorePacket *pRestorePacket; PyObject *pRetVal; pRestorePacket = NativeToPyRestorePacket(rp); if (!pRestorePacket) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pRestorePacket, NULL); if (!pRetVal) { Py_DECREF(pRestorePacket); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); Py_DECREF(pRestorePacket); } } else { Dmsg(ctx, dbglvl, "Failed to find function named set_file_attributes()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PyCheckFile(bpContext *ctx, char *fname) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!fname) { return bRC_Error; } /* * Lookup the check_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "check_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pFname, *pRetVal; pFname = PyString_FromString(fname); pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pFname, NULL); Py_DECREF(pFname); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named check_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static inline PyAclPacket *NativeToPyAclPacket(struct acl_pkt *ap) { PyAclPacket *pAclPacket = PyObject_New(PyAclPacket, &PyAclPacketType); if (pAclPacket) { pAclPacket->fname = ap->fname; if (ap->content_length && ap->content) { pAclPacket->content = PyByteArray_FromStringAndSize(ap->content, ap->content_length); } else { pAclPacket->content = NULL; } } return pAclPacket; } static inline bool PyAclPacketToNative(PyAclPacket *pAclPacket, struct acl_pkt *ap) { if (!pAclPacket->content) { return true; } if (PyByteArray_Check(pAclPacket->content)) { char *buf; ap->content_length = PyByteArray_Size(pAclPacket->content); if (ap->content_length <= 0 || !(buf = PyByteArray_AsString(pAclPacket->content))) { return false; } if (ap->content) { free(ap->content); } ap->content = (char *)malloc(ap->content_length); memcpy(ap->content, buf, ap->content_length); } return true; } static bRC PyGetAcl(bpContext *ctx, acl_pkt *ap) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!ap) { return bRC_Error; } /* * Lookup the get_acl() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "get_acl"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyAclPacket *pAclPkt; PyObject *pRetVal; pAclPkt = NativeToPyAclPacket(ap); if (!pAclPkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pAclPkt, NULL); if (!pRetVal) { Py_DECREF((PyObject *)pAclPkt); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); if (!PyAclPacketToNative(pAclPkt, ap)) { Py_DECREF((PyObject *)pAclPkt); goto bail_out; } Py_DECREF(pAclPkt); } } else { Dmsg(ctx, dbglvl, "Failed to find function named get_acl()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PySetAcl(bpContext *ctx, acl_pkt *ap) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!ap) { return bRC_Error; } /* * Lookup the set_acl() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "set_acl"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyAclPacket *pAclPkt; PyObject *pRetVal; pAclPkt = NativeToPyAclPacket(ap); if (!pAclPkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pAclPkt, NULL); Py_DECREF(pAclPkt); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named set_acl()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static inline PyXattrPacket *NativeToPyXattrPacket(struct xattr_pkt *xp) { PyXattrPacket *pXattrPacket = PyObject_New(PyXattrPacket, &PyXattrPacketType); if (pXattrPacket) { pXattrPacket->fname = xp->fname; if (xp->name_length && xp->name) { pXattrPacket->name = PyByteArray_FromStringAndSize(xp->name, xp->name_length); } else { pXattrPacket->name = NULL; } if (xp->value_length && xp->value) { pXattrPacket->value = PyByteArray_FromStringAndSize(xp->value, xp->value_length); } else { pXattrPacket->value = NULL; } } return pXattrPacket; } static inline bool PyXattrPacketToNative(PyXattrPacket *pXattrPacket, struct xattr_pkt *xp) { if (!pXattrPacket->name) { return true; } if (PyByteArray_Check(pXattrPacket->name)) { char *buf; xp->name_length = PyByteArray_Size(pXattrPacket->name); if (xp->name_length <= 0 || !(buf = PyByteArray_AsString(pXattrPacket->name))) { return false; } if (xp->name) { free(xp->name); } xp->name = (char *)malloc(xp->name_length); memcpy(xp->name, buf, xp->name_length); } if (pXattrPacket->value && PyByteArray_Check(pXattrPacket->value)) { char *buf; xp->value_length = PyByteArray_Size(pXattrPacket->value); if (xp->name_length <= 0 || !(buf = PyByteArray_AsString(pXattrPacket->name))) { return false; } if (xp->value) { free(xp->value); } xp->value = (char *)malloc(xp->value_length); memcpy(xp->value, buf, xp->value_length); } else { if (xp->value) { free(xp->value); } xp->value = NULL; } return true; } static bRC PyGetXattr(bpContext *ctx, xattr_pkt *xp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!xp) { return bRC_Error; } /* * Lookup the get_xattr() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "get_xattr"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyXattrPacket *pXattrPkt; PyObject *pRetVal; pXattrPkt = NativeToPyXattrPacket(xp); if (!pXattrPkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pXattrPkt, NULL); if (!pRetVal) { Py_DECREF((PyObject *)pXattrPkt); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); if (!PyXattrPacketToNative(pXattrPkt, xp)) { Py_DECREF((PyObject *)pXattrPkt); goto bail_out; } Py_DECREF(pXattrPkt); } } else { Dmsg(ctx, dbglvl, "Failed to find function named get_xattr()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PySetXattr(bpContext *ctx, xattr_pkt *xp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!xp) { return bRC_Error; } /* * Lookup the set_acl() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "set_xattr"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyXattrPacket *pXattrPkt; PyObject *pRetVal; pXattrPkt = NativeToPyXattrPacket(xp); if (!pXattrPkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pXattrPkt, NULL); Py_DECREF(pXattrPkt); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named set_xattr()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static inline PyRestoreObject *NativeToPyRestoreObject(struct restore_object_pkt *rop) { PyRestoreObject *pRestoreObject = PyObject_New(PyRestoreObject, &PyRestoreObjectType); if (pRestoreObject) { pRestoreObject->object_name = PyString_FromString(rop->object_name); pRestoreObject->object = PyByteArray_FromStringAndSize(rop->object, rop->object_len); pRestoreObject->plugin_name = rop->plugin_name; pRestoreObject->object_type = rop->object_type; pRestoreObject->object_len = rop->object_len; pRestoreObject->object_full_len = rop->object_full_len; pRestoreObject->object_index = rop->object_index; pRestoreObject->object_compression = rop->object_compression; pRestoreObject->stream = rop->stream; pRestoreObject->JobId = rop->JobId; } return pRestoreObject; } static bRC PyRestoreObjectData(bpContext *ctx, struct restore_object_pkt *rop) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!rop) { return bRC_OK; } /* * Lookup the restore_object_data() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "restore_object_data"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyRestoreObject *pRestoreObject; PyObject *pRetVal; pRestoreObject = NativeToPyRestoreObject(rop); if (!pRestoreObject) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pRestoreObject, NULL); Py_DECREF(pRestoreObject); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named start_restore_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PyHandleBackupFile(bpContext *ctx, struct save_pkt *sp) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; if (!sp) { return bRC_Error; } /* * Lookup the handle_backup_file() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "handle_backup_file"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PySavePacket *pSavePkt; PyObject *pRetVal; pSavePkt = NativeToPySavePacket(sp); if (!pSavePkt) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pSavePkt, NULL); if (!pRetVal) { Py_DECREF((PyObject *)pSavePkt); goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); if (!PySavePacketToNative(pSavePkt, sp, p_ctx, true)) { Py_DECREF((PyObject *)pSavePkt); goto bail_out; } Py_DECREF(pSavePkt); } } else { Dmsg(ctx, dbglvl, "Failed to find function named handle_backup_file()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to get certain internal values of the current Job. */ static PyObject *PyBareosGetValue(PyObject *self, PyObject *args) { int var; bpContext *ctx = NULL; PyObject *pyCtx; PyObject *pRetVal = NULL; if (!PyArg_ParseTuple(args, "Oi:BareosGetValue", &pyCtx, &var)) { return NULL; } switch (var) { case bVarFDName: case bVarWorkingDir: case bVarExePath: case bVarVersion: case bVarDistName: { char *value; if (bfuncs->getBareosValue(ctx, (bVariable)var, &value) == bRC_OK) { pRetVal = PyString_FromString(value); } break; } case bVarJobId: case bVarLevel: case bVarType: case bVarJobStatus: case bVarSinceTime: case bVarAccurate: case bVarPrefixLinks: { int value; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (bVariable)var, &value) == bRC_OK) { pRetVal = PyInt_FromLong(value); } break; } case bVarClient: case bVarJobName: case bVarPrevJobName: case bVarWhere: case bVarRegexWhere: { char *value; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (bVariable)var, &value) == bRC_OK) { pRetVal = PyString_FromString(value); } break; } case bVarFileSeen: break; /* a write only variable, ignore read request */ default: ctx = PyGetbpContext(pyCtx); Dmsg(ctx, dbglvl, "PyBareosGetValue: Unknown variable requested %d\n", var); break; } if (!pRetVal) { Py_INCREF(Py_None); pRetVal = Py_None; } return pRetVal; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to get certain internal values of the current Job. */ static PyObject *PyBareosSetValue(PyObject *self, PyObject *args) { int var; bpContext *ctx = NULL; PyObject *pyCtx, *pyValue; if (!PyArg_ParseTuple(args, "OiO:BareosSetValue", &pyCtx, &var, &pyValue)) { return NULL; } switch (var) { case bVarFileSeen: { char *value; value = PyString_AsString(pyValue); if (value) { bfuncs->setBareosValue(ctx, (bVariable)var, value); } break; } default: ctx = PyGetbpContext(pyCtx); Dmsg(ctx, dbglvl, "PyBareosSetValue: Unknown variable requested %d\n", var); break; } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue debug messages using the Bareos debug message facility. */ static PyObject *PyBareosDebugMessage(PyObject *self, PyObject *args) { int level; char *dbgmsg = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "Oi|z:BareosDebugMessage", &pyCtx, &level, &dbgmsg)) { return NULL; } if (dbgmsg) { ctx = PyGetbpContext(pyCtx); Dmsg(ctx, level, "%s", dbgmsg); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue Job messages using the Bareos Job message facility. */ static PyObject *PyBareosJobMessage(PyObject *self, PyObject *args) { int type; char *jobmsg = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "Oi|z:BareosJobMessage", &pyCtx, &type, &jobmsg)) { return NULL; } if (jobmsg) { ctx = PyGetbpContext(pyCtx); Jmsg(ctx, type, "%s", jobmsg); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Register Event to register additional events it wants * to receive. */ static PyObject *PyBareosRegisterEvents(PyObject *self, PyObject *args) { int len, event; bpContext *ctx; PyObject *pyCtx, *pyEvents, *pySeq, *pyEvent; if (!PyArg_ParseTuple(args, "OO:BareosRegisterEvents", &pyCtx, &pyEvents)) { return NULL; } pySeq = PySequence_Fast(pyEvents, "Expected a sequence of events"); if (!pySeq) { return NULL; } len = PySequence_Fast_GET_SIZE(pySeq); ctx = PyGetbpContext(pyCtx); for (int i = 0; i < len; i++) { pyEvent = PySequence_Fast_GET_ITEM(pySeq, i); event = PyInt_AsLong(pyEvent); if (event >= bEventJobStart && event <= bEventComponentInfo) { Dmsg(ctx, dbglvl, "PyBareosRegisterEvents: registering event %d\n", event); bfuncs->registerBareosEvents(ctx, 1, event); } } Py_DECREF(pySeq); Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add Exclude pattern to the fileset. */ static PyObject *PyBareosAddExclude(PyObject *self, PyObject *args) { char *file = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O|z:BareosAddExclude", &pyCtx, &file)) { return NULL; } if (file) { ctx = PyGetbpContext(pyCtx); bfuncs->AddExclude(ctx, file); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add Include pattern to the fileset. */ static PyObject *PyBareosAddInclude(PyObject *self, PyObject *args) { char *file = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O|z:BareosAddInclude", &pyCtx, &file)) { return NULL; } if (file) { ctx = PyGetbpContext(pyCtx); bfuncs->AddInclude(ctx, file); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add Include Options to the fileset. */ static PyObject *PyBareosAddOptions(PyObject *self, PyObject *args) { char *opts = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O|z:BareosAddOptions", &pyCtx, &opts)) { return NULL; } if (opts) { ctx = PyGetbpContext(pyCtx); bfuncs->AddOptions(ctx, opts); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add Regex to the fileset. */ static PyObject *PyBareosAddRegex(PyObject *self, PyObject *args) { int type; char *item = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O|zi:BareosAddRegex", &pyCtx, &item, &type)) { return NULL; } if (item) { ctx = PyGetbpContext(pyCtx); bfuncs->AddRegex(ctx, item, type); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add Wildcard to the fileset. */ static PyObject *PyBareosAddWild(PyObject *self, PyObject *args) { int type; char *item = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O|zi:BareosAddWild", &pyCtx, &item, &type)) { return NULL; } if (item) { ctx = PyGetbpContext(pyCtx); bfuncs->AddWild(ctx, item, type); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add New Option block. */ static PyObject *PyBareosNewOptions(PyObject *self, PyObject *args) { bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O:BareosNewOptions", &pyCtx)) { return NULL; } ctx = PyGetbpContext(pyCtx); bfuncs->NewOptions(ctx); Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add New Include block. */ static PyObject *PyBareosNewInclude(PyObject *self, PyObject *args) { bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O:BareosNewInclude", &pyCtx)) { return NULL; } ctx = PyGetbpContext(pyCtx); bfuncs->NewInclude(ctx); Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Add New Pre Include block. */ static PyObject *PyBareosNewPreInclude(PyObject *self, PyObject *args) { bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "O:BareosNewPreInclude", &pyCtx)) { return NULL; } ctx = PyGetbpContext(pyCtx); bfuncs->NewPreInclude(ctx); Py_INCREF(Py_None); return Py_None; } /* * Some helper functions. */ static inline char *PyGetStringValue(PyObject *object) { if (!object || !PyString_Check(object)) { return (char *)""; } return PyString_AsString(object); } static inline char *PyGetByteArrayValue(PyObject *object) { if (!object || !PyByteArray_Check(object)) { return (char *)""; } return PyByteArray_AsString(object); } /* * Python specific handlers for PyRestoreObject structure mapping. */ /* * Representation. */ static PyObject *PyRestoreObject_repr(PyRestoreObject *self) { PyObject *s; POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "RestoreObject(object_name=\"%s\", object=\"%s\", plugin_name=\"%s\", " "object_type=%d, object_len=%d, object_full_len=%d, " "object_index=%d, object_compression=%d, stream=%d, jobid=%u)", PyGetStringValue(self->object_name), PyGetByteArrayValue(self->object), self->plugin_name, self->object_type, self->object_len, self->object_full_len, self->object_index, self->object_compression, self->stream, self->JobId); s = PyString_FromString(buf.c_str()); return s; } /* * Initialization. */ static int PyRestoreObject_init(PyRestoreObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { (char *)"object_name", (char *)"object", (char *)"plugin_name", (char *)"object_type", (char *)"object_len", (char *)"object_full_len", (char *)"object_index", (char *)"object_compression", (char *)"stream", (char *)"jobid", NULL }; self->object_name = NULL; self->object = NULL; self->plugin_name = NULL; self->object_type = 0; self->object_len = 0; self->object_full_len = 0; self->object_index = 0; self->object_compression = 0; self->stream = 0; self->JobId = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|oosiiiiiiI", kwlist, &self->object_name, &self->object, &self->plugin_name, &self->object_type, &self->object_len, &self->object_full_len, &self->object_index, &self->object_compression, &self->stream, &self->JobId)) { return -1; } return 0; } /* * Destructor. */ static void PyRestoreObject_dealloc(PyRestoreObject *self) { if (self->object_name) { Py_XDECREF(self->object_name); } if (self->object) { Py_XDECREF(self->object); } PyObject_Del(self); } /* * Python specific handlers for PyStatPacket structure mapping. */ /* * Representation. */ static PyObject *PyStatPacket_repr(PyStatPacket *self) { PyObject *s; POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "StatPacket(dev=%ld, ino=%lld, mode=%d, nlink=%d, " "uid=%ld, gid=%ld, rdev=%ld, size=%lld, " "atime=%ld, mtime=%ld, ctime=%ld, blksize=%ld, blocks=%lld)", self->dev, self->ino, self->mode, self->nlink, self->uid, self->gid, self->rdev, self->size, self->atime, self->mtime, self->ctime, self->blksize, self->blocks); s = PyString_FromString(buf.c_str()); return s; } /* * Initialization. */ static int PyStatPacket_init(PyStatPacket *self, PyObject *args, PyObject *kwds) { time_t now; static char *kwlist[] = { (char *)"dev", (char *)"ino", (char *)"mode", (char *)"nlink", (char *)"uid", (char *)"gid", (char *)"rdev", (char *)"size", (char *)"atime", (char *)"mtime", (char *)"ctime", (char *)"blksize", (char *)"blocks", NULL }; now = time(NULL); self->dev = 0; self->ino = 0; self->mode = 0700 | S_IFREG; self->nlink = 0; self->uid = 0; self->gid = 0; self->rdev = 0; self->size = -1; self->atime = now; self->mtime = now; self->ctime = now; self->blksize = 4096; self->blocks = 1; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|IKHHIIIKIIIIK", kwlist, &self->dev, &self->ino, &self->mode, &self->nlink, &self->uid, &self->gid, &self->rdev, &self->size, &self->atime, &self->mtime, &self->ctime, &self->blksize, &self->blocks)) { return -1; } return 0; } /* * Destructor. */ static void PyStatPacket_dealloc(PyStatPacket *self) { PyObject_Del(self); } /* * Python specific handlers for PySavePacket structure mapping. */ /* * Representation. */ static inline const char *print_flags_bitmap(PyObject *bitmap) { static char visual_bitmap[FO_MAX + 1]; if (PyByteArray_Check(bitmap)) { int cnt; char *flags; if (PyByteArray_Size(bitmap) == FOPTS_BYTES) { if ((flags = PyByteArray_AsString(bitmap))) { memset(visual_bitmap, 0, sizeof(visual_bitmap)); for (cnt = 0; cnt <= FO_MAX; cnt++) { if (bit_is_set(cnt, flags)) { visual_bitmap[cnt] = '1'; } else { visual_bitmap[cnt] = '0'; } } return visual_bitmap; } } } return "Unknown"; } static PyObject *PySavePacket_repr(PySavePacket *self) { PyObject *s; POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "SavePacket(fname=\"%s\", link=\"%s\", type=%ld, flags=%s, " "no_read=%d, portable=%d, accurate_found=%d, " "cmd=\"%s\", save_time=%ld, delta_seq=%ld, object_name=\"%s\", " "object=\"%s\", object_len=%ld, object_index=%ld)", PyGetStringValue(self->fname), PyGetStringValue(self->link), self->type, print_flags_bitmap(self->flags), self->no_read, self->portable, self->accurate_found, self->cmd, self->save_time, self->delta_seq, PyGetStringValue(self->object_name), PyGetByteArrayValue(self->object), self->object_len, self->object_index); s = PyString_FromString(buf.c_str()); return s; } /* * Initialization. */ static int PySavePacket_init(PySavePacket *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { (char *)"fname", (char *)"link", (char *)"type", (char *)"flags", (char *)"no_read", (char *)"portable", (char *)"accurate_found", (char *)"cmd", (char *)"save_time", (char *)"delta_seq", (char *)"object_name", (char *)"object", (char *)"object_len", (char *)"object_index", NULL }; self->fname = NULL; self->link = NULL; self->type = 0; self->flags = NULL; self->no_read = false; self->portable = false; self->accurate_found = false; self->cmd = NULL; self->save_time = 0; self->delta_seq = 0; self->object_name = NULL; self->object = NULL; self->object_len = 0; self->object_index = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ooiocccsiiooii", kwlist, &self->fname, &self->link, &self->type, &self->flags, &self->no_read, &self->portable, &self->accurate_found, &self->cmd, &self->save_time, &self->delta_seq, &self->object_name, &self->object, &self->object_len, &self->object_index)) { return -1; } return 0; } /* * Destructor. */ static void PySavePacket_dealloc(PySavePacket *self) { if (self->fname) { Py_XDECREF(self->fname); } if (self->link) { Py_XDECREF(self->link); } if (self->flags) { Py_XDECREF(self->flags); } if (self->object_name) { Py_XDECREF(self->object_name); } if (self->object) { Py_XDECREF(self->object); } PyObject_Del(self); } /* * Python specific handlers for PyRestorePacket structure mapping. */ /* * Representation. */ static PyObject *PyRestorePacket_repr(PyRestorePacket *self) { PyObject *stat_repr, *s; POOL_MEM buf(PM_MESSAGE); stat_repr = PyObject_Repr(self->statp); Mmsg(buf, "RestorePacket(stream=%d, data_stream=%ld, type=%ld, file_index=%ld, " "linkFI=%ld, uid=%ld, statp=\"%s\", attrEx=\"%s\", ofname=\"%s\", " "olname=\"%s\", where=\"%s\", RegexWhere=\"%s\", replace=%d, create_status=%d)", self->stream, self->data_stream, self->type, self->file_index, self->LinkFI, self->uid, PyGetStringValue(stat_repr), self->attrEx, self->ofname, self->olname, self->where, self->RegexWhere, self->replace, self->create_status); s = PyString_FromString(buf.c_str()); Py_DECREF(stat_repr); return s; } /* * Initialization. */ static int PyRestorePacket_init(PyRestorePacket *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { (char *)"stream", (char *)"data_stream", (char *)"type", (char *)"file_index", (char *)"linkFI", (char *)"uid", (char *)"statp", (char *)"attrEX", (char *)"ofname", (char *)"olname", (char *)"where", (char *)"regexwhere", (char *)"replace", (char *)"create_status", NULL }; self->stream = 0; self->data_stream = 0; self->type = 0; self->file_index = 0; self->LinkFI = 0; self->uid = 0; self->statp = NULL; self->attrEx = NULL; self->ofname = NULL; self->olname = NULL; self->where = NULL; self->RegexWhere = NULL; self->replace = 0; self->create_status = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iiiiiIosssssii", kwlist, &self->stream, &self->data_stream, &self->type, &self->file_index, &self->LinkFI, &self->uid, &self->statp, &self->attrEx, &self->ofname, &self->olname, &self->where, &self->RegexWhere, &self->replace, &self->create_status)) { return -1; } return 0; } /* * Destructor. */ static void PyRestorePacket_dealloc(PyRestorePacket *self) { PyObject_Del(self); } /* * Python specific handlers for PyIoPacket structure mapping. */ /* * Representation. */ static PyObject *PyIoPacket_repr(PyIoPacket *self) { PyObject *s; POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "IoPacket(func=%d, count=%ld, flags=%ld, mode=%ld, " "buf=\"%s\", fname=\"%s\", status=%ld, io_errno=%ld, lerror=%ld, " "whence=%ld, offset=%lld, win32=%d)", self->func, self->count, self->flags, self->mode, PyGetByteArrayValue(self->buf), self->fname, self->status, self->io_errno, self->lerror, self->whence, self->offset, self->win32); s = PyString_FromString(buf.c_str()); return s; } /* * Initialization. */ static int PyIoPacket_init(PyIoPacket *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { (char *)"func", (char *)"count", (char *)"flags", (char *)"mode", (char *)"buf", (char *)"fname", (char *)"status", (char *)"io_errno", (char *)"lerror", (char *)"whence", (char *)"offset", (char *)"win32", NULL }; self->func = 0; self->count = 0; self->flags = 0; self->mode = 0; self->buf = NULL; self->fname = NULL; self->status = 0; self->io_errno = 0; self->lerror = 0; self->whence = 0; self->offset = 0; self->win32 = false; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Hiiiosiiiilc", kwlist, &self->func, &self->count, &self->flags, &self->mode, &self->buf, &self->fname, &self->status, &self->io_errno, &self->lerror, &self->whence, &self->offset, &self->win32)) { return -1; } return 0; } /* * Destructor. */ static void PyIoPacket_dealloc(PyIoPacket *self) { if (self->buf) { Py_XDECREF(self->buf); } PyObject_Del(self); } /* * Python specific handlers for PyAclPacket structure mapping. */ /* * Representation. */ static PyObject *PyAclPacket_repr(PyAclPacket *self) { PyObject *s; POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "AclPacket(fname=\"%s\", content=\"%s\")", self->fname, PyGetByteArrayValue(self->content)); s = PyString_FromString(buf.c_str()); return s; } /* * Initialization. */ static int PyAclPacket_init(PyAclPacket *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { (char *)"fname", (char *)"content", NULL }; self->fname = NULL; self->content = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|so", kwlist, &self->fname, &self->content)) { return -1; } return 0; } /* * Destructor. */ static void PyAclPacket_dealloc(PyAclPacket *self) { if (self->content) { Py_XDECREF(self->content); } PyObject_Del(self); } /* * Python specific handlers for PyIOPacket structure mapping. */ /* * Representation. */ static PyObject *PyXattrPacket_repr(PyXattrPacket *self) { PyObject *s; POOL_MEM buf(PM_MESSAGE); Mmsg(buf, "XattrPacket(fname=\"%s\", name=\"%s\", value=\"%s\")", self->fname, PyGetByteArrayValue(self->name), PyGetByteArrayValue(self->value)); s = PyString_FromString(buf.c_str()); return s; } /* * Initialization. */ static int PyXattrPacket_init(PyXattrPacket *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { (char *)"fname", (char *)"name", (char *)"value", NULL }; self->fname = NULL; self->name = NULL; self->value = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|soo", kwlist, &self->fname, &self->name, &self->value)) { return -1; } return 0; } /* * Destructor. */ static void PyXattrPacket_dealloc(PyXattrPacket *self) { if (self->value) { Py_XDECREF(self->value); } if (self->name) { Py_XDECREF(self->name); } PyObject_Del(self); } bareos-Release-14.2.6/src/plugins/filed/python-fd.h000066400000000000000000000770341263011562700220670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This defines the Python types in C++ and the callbacks from Python we support. */ #ifndef BPYTHONFD_H #define BPYTHONFD_H 1 #include "structmember.h" /* * This defines the arguments that the plugin parser understands. */ enum plugin_argument_type { argument_none, argument_module_path, argument_module_name }; struct plugin_argument { const char *name; enum plugin_argument_type type; }; static plugin_argument plugin_arguments[] = { { "module_path", argument_module_path }, { "module_name", argument_module_name }, { NULL, argument_none } }; /* * Python structures mapping C++ ones. */ /* * This packet is used for the restore objects. * It is passed to the plugin when restoring the object. */ typedef struct { PyObject_HEAD PyObject *object_name; /* Object name */ PyObject *object; /* Restore object data to restore */ char *plugin_name; /* Plugin name */ int32_t object_type; /* FT_xx for this file */ int32_t object_len; /* restore object length */ int32_t object_full_len; /* restore object uncompressed length */ int32_t object_index; /* restore object index */ int32_t object_compression; /* set to compression type */ int32_t stream; /* attribute stream id */ uint32_t JobId; /* JobId object came from */ } PyRestoreObject; /* * Forward declarations of type specific functions. */ static void PyRestoreObject_dealloc(PyRestoreObject *self); static int PyRestoreObject_init(PyRestoreObject *self, PyObject *args, PyObject *kwds); static PyObject *PyRestoreObject_repr(PyRestoreObject *self); static PyMethodDef PyRestoreObject_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PyRestoreObject_members[] = { { (char *)"object_name", T_OBJECT, offsetof(PyRestoreObject, object_name), 0, (char *)"Object Name" }, { (char *)"object", T_OBJECT, offsetof(PyRestoreObject, object), 0, (char *)"Object Content" }, { (char *)"plugin_name", T_STRING, offsetof(PyRestoreObject, plugin_name), 0, (char *)"Plugin Name" }, { (char *)"object_type", T_INT, offsetof(PyRestoreObject, object_type), 0, (char *)"Object Type" }, { (char *)"object_len", T_INT, offsetof(PyRestoreObject, object_len), 0, (char *)"Object Length" }, { (char *)"object_full_len", T_INT, offsetof(PyRestoreObject, object_full_len), 0, (char *)"Object Full Length" }, { (char *)"object_index", T_INT, offsetof(PyRestoreObject, object_index), 0, (char *)"Object Index" }, { (char *)"object_compression", T_INT, offsetof(PyRestoreObject, object_compression), 0, (char *)"Object Compression" }, { (char *)"stream", T_INT, offsetof(PyRestoreObject, stream), 0, (char *)"Attribute Stream" }, { (char *)"jobid", T_UINT, offsetof(PyRestoreObject, JobId), 0, (char *)"Jobid" }, { NULL } }; static PyTypeObject PyRestoreObjectType = { PyVarObject_HEAD_INIT(NULL, 0) "restore_object", /* tp_name */ sizeof(PyRestoreObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyRestoreObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyRestoreObject_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "io_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyRestoreObject_methods, /* tp_methods */ PyRestoreObject_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyRestoreObject_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * The PyStatPacket type */ typedef struct { PyObject_HEAD uint32_t dev; uint64_t ino; uint16_t mode; int16_t nlink; uint32_t uid; uint32_t gid; uint32_t rdev; uint64_t size; time_t atime; time_t mtime; time_t ctime; uint32_t blksize; uint64_t blocks; } PyStatPacket; /* * Forward declarations of type specific functions. */ static void PyStatPacket_dealloc(PyStatPacket *self); static int PyStatPacket_init(PyStatPacket *self, PyObject *args, PyObject *kwds); static PyObject *PyStatPacket_repr(PyStatPacket *self); static PyMethodDef PyStatPacket_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PyStatPacket_members[] = { { (char *)"dev", T_UINT, offsetof(PyStatPacket, dev), 0, (char *)"Device" }, { (char *)"ino", T_ULONGLONG, offsetof(PyStatPacket, ino), 0, (char *)"Inode number" }, { (char *)"mode", T_USHORT, offsetof(PyStatPacket, mode), 0, (char *)"Mode" }, { (char *)"nlink", T_USHORT, offsetof(PyStatPacket, nlink), 0, (char *)"Number of hardlinks" }, { (char *)"uid", T_UINT, offsetof(PyStatPacket, uid), 0, (char *)"User Id" }, { (char *)"gid", T_UINT, offsetof(PyStatPacket, gid), 0, (char *)"Group Id" }, { (char *)"rdev", T_UINT, offsetof(PyStatPacket, rdev), 0, (char *)"Rdev" }, { (char *)"size", T_ULONGLONG, offsetof(PyStatPacket, size), 0, (char *)"Size" }, { (char *)"atime", T_UINT, offsetof(PyStatPacket, atime), 0, (char *)"Access Time" }, { (char *)"mtime", T_UINT, offsetof(PyStatPacket, mtime), 0, (char *)"Modification Time" }, { (char *)"ctime", T_UINT, offsetof(PyStatPacket, ctime), 0, (char *)"Change Time" }, { (char *)"blksize", T_UINT, offsetof(PyStatPacket, blksize), 0, (char *)"Blocksize" }, { (char *)"blocks", T_ULONGLONG, offsetof(PyStatPacket, blocks), 0, (char *)"Blocks" }, { NULL } }; static PyTypeObject PyStatPacketType = { PyVarObject_HEAD_INIT(NULL, 0) "stat_pkt", /* tp_name */ sizeof(PyStatPacket), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyStatPacket_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyStatPacket_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "io_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyStatPacket_methods, /* tp_methods */ PyStatPacket_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyStatPacket_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * The PySavePacket type */ typedef struct { PyObject_HEAD PyObject *fname; /* Full path and filename */ PyObject *link; /* Link name if any */ PyObject *statp; /* System stat() packet for file */ int32_t type; /* FT_xx for this file */ PyObject *flags; /* Bareos internal flags */ bool no_read; /* During the save, the file should not be saved */ bool portable; /* set if data format is portable */ bool accurate_found; /* Found in accurate list (valid after check_changes()) */ char *cmd; /* Command */ time_t save_time; /* Start of incremental time */ uint32_t delta_seq; /* Delta sequence number */ PyObject *object_name; /* Object name to create */ PyObject *object; /* Restore object data to save */ int32_t object_len; /* Restore object length */ int32_t object_index; /* Restore object index */ } PySavePacket; /* * Forward declarations of type specific functions. */ static void PySavePacket_dealloc(PySavePacket *self); static int PySavePacket_init(PySavePacket *self, PyObject *args, PyObject *kwds); static PyObject *PySavePacket_repr(PySavePacket *self); static PyMethodDef PySavePacket_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PySavePacket_members[] = { { (char *)"fname", T_OBJECT, offsetof(PySavePacket, fname), 0, (char *)"Filename" }, { (char *)"link", T_OBJECT, offsetof(PySavePacket, link), 0, (char *)"Linkname" }, { (char *)"statp", T_OBJECT, offsetof(PySavePacket, statp), 0, (char *)"Stat Packet" }, { (char *)"type", T_INT, offsetof(PySavePacket, type), 0, (char *)"Type" }, { (char *)"flags", T_OBJECT, offsetof(PySavePacket, flags), 0, (char *)"Flags" }, { (char *)"no_read", T_BOOL, offsetof(PySavePacket, no_read), 0, (char *)"No Read" }, { (char *)"portable", T_BOOL, offsetof(PySavePacket, portable), 0, (char *)"Portable" }, { (char *)"accurate_found", T_BOOL, offsetof(PySavePacket, accurate_found), 0, (char *)"Accurate Found" }, { (char *)"cmd", T_STRING, offsetof(PySavePacket, cmd), 0, (char *)"Command" }, { (char *)"save_time", T_UINT, offsetof(PySavePacket, save_time), 0, (char *)"Save Time" }, { (char *)"delta_seq", T_UINT, offsetof(PySavePacket, delta_seq), 0, (char *)"Delta Sequence" }, { (char *)"object_name", T_OBJECT, offsetof(PySavePacket, object_name), 0, (char *)"Restore Object Name" }, { (char *)"object", T_OBJECT, offsetof(PySavePacket, object), 0, (char *)"Restore ObjectName" }, { (char *)"object_len", T_INT, offsetof(PySavePacket, object_len), 0, (char *)"Restore ObjectLen" }, { (char *)"object_index", T_INT, offsetof(PySavePacket, object_index), 0, (char *)"Restore ObjectIndex" }, { NULL } }; static PyTypeObject PySavePacketType = { PyVarObject_HEAD_INIT(NULL, 0) "save_pkt", /* tp_name */ sizeof(PySavePacket), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PySavePacket_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PySavePacket_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "save_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PySavePacket_methods, /* tp_methods */ PySavePacket_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PySavePacket_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * The PyRestorePacket type */ typedef struct { PyObject_HEAD int32_t stream; /* Attribute stream id */ int32_t data_stream; /* Id of data stream to follow */ int32_t type; /* File type FT */ int32_t file_index; /* File index */ int32_t LinkFI; /* File index to data if hard link */ uint32_t uid; /* Userid */ PyObject *statp; /* Decoded stat packet */ const char *attrEx; /* Extended attributes if any */ const char *ofname; /* Output filename */ const char *olname; /* Output link name */ const char *where; /* Where */ const char *RegexWhere; /* Regex where */ int replace; /* Replace flag */ int create_status; /* Status from createFile() */ } PyRestorePacket; /* * Forward declarations of type specific functions. */ static void PyRestorePacket_dealloc(PyRestorePacket *self); static int PyRestorePacket_init(PyRestorePacket *self, PyObject *args, PyObject *kwds); static PyObject *PyRestorePacket_repr(PyRestorePacket *self); static PyMethodDef PyRestorePacket_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PyRestorePacket_members[] = { { (char *)"stream", T_INT, offsetof(PyRestorePacket, stream), 0, (char *)"Attribute stream id" }, { (char *)"data_stream", T_INT, offsetof(PyRestorePacket, data_stream), 0, (char *)"Id of data stream to follow" }, { (char *)"type", T_INT, offsetof(PyRestorePacket, type), 0, (char *)"File type FT" }, { (char *)"file_index", T_INT, offsetof(PyRestorePacket, file_index), 0, (char *)"File index" }, { (char *)"linkFI", T_INT, offsetof(PyRestorePacket, LinkFI), 0, (char *)"File index to data if hard link" }, { (char *)"uid", T_UINT, offsetof(PyRestorePacket, uid), 0, (char *)"User Id" }, { (char *)"statp", T_OBJECT, offsetof(PyRestorePacket, statp), 0, (char *)"Stat Packet" }, { (char *)"attrEX", T_STRING, offsetof(PyRestorePacket, attrEx), 0, (char *)"Extended attributes" }, { (char *)"ofname", T_STRING, offsetof(PyRestorePacket, ofname), 0, (char *)"Output filename" }, { (char *)"olname", T_STRING, offsetof(PyRestorePacket, olname), 0, (char *)"Output link name" }, { (char *)"where", T_STRING, offsetof(PyRestorePacket, where), 0, (char *)"Where" }, { (char *)"regexwhere", T_STRING, offsetof(PyRestorePacket, RegexWhere), 0, (char *)"Regex where" }, { (char *)"replace", T_INT, offsetof(PyRestorePacket, replace), 0, (char *)"Replace flag" }, { (char *)"create_status", T_INT, offsetof(PyRestorePacket, create_status), 0, (char *)"Status from createFile()" }, { NULL } }; static PyTypeObject PyRestorePacketType = { PyVarObject_HEAD_INIT(NULL, 0) "restore_pkt", /* tp_name */ sizeof(PyRestorePacket), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyRestorePacket_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyRestorePacket_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "restore_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyRestorePacket_methods, /* tp_methods */ PyRestorePacket_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyRestorePacket_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * The PyIOPacket type */ typedef struct { PyObject_HEAD uint16_t func; /* Function code */ int32_t count; /* Read/Write count */ int32_t flags; /* Open flags */ int32_t mode; /* Permissions for created files */ PyObject *buf; /* Read/Write buffer */ const char *fname; /* Open filename */ int32_t status; /* Return status */ int32_t io_errno; /* Errno code */ int32_t lerror; /* Win32 error code */ int32_t whence; /* Lseek argument */ int64_t offset; /* Lseek argument */ bool win32; /* Win32 GetLastError returned */ } PyIoPacket; /* * Forward declarations of type specific functions. */ static void PyIoPacket_dealloc(PyIoPacket *self); static int PyIoPacket_init(PyIoPacket *self, PyObject *args, PyObject *kwds); static PyObject *PyIoPacket_repr(PyIoPacket *self); static PyMethodDef PyIoPacket_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PyIoPacket_members[] = { { (char *)"func", T_USHORT, offsetof(PyIoPacket, func), 0, (char *)"Function code" }, { (char *)"count", T_INT, offsetof(PyIoPacket, count), 0, (char *)"Read/write count" }, { (char *)"flags", T_INT, offsetof(PyIoPacket, flags), 0, (char *)"Open flags" }, { (char *)"mode", T_INT, offsetof(PyIoPacket, mode), 0, (char *)"Permissions for created files" }, { (char *)"buf", T_OBJECT, offsetof(PyIoPacket, buf), 0, (char *)"Read/write buffer" }, { (char *)"fname", T_STRING, offsetof(PyIoPacket, fname), 0, (char *)"Open filename" }, { (char *)"status", T_INT, offsetof(PyIoPacket, status), 0, (char *)"Return status" }, { (char *)"io_errno", T_INT, offsetof(PyIoPacket, io_errno), 0, (char *)"Errno code" }, { (char *)"lerror", T_INT, offsetof(PyIoPacket, lerror), 0, (char *)"Win32 error code" }, { (char *)"whence", T_INT, offsetof(PyIoPacket, whence), 0, (char *)"Lseek argument" }, { (char *)"offset", T_LONGLONG, offsetof(PyIoPacket, offset), 0, (char *)"Lseek argument" }, { (char *)"win32", T_BOOL, offsetof(PyIoPacket, win32), 0, (char *)"Win32 GetLastError returned" }, { NULL } }; static PyTypeObject PyIoPacketType = { PyVarObject_HEAD_INIT(NULL, 0) "io_pkt", /* tp_name */ sizeof(PyIoPacket), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyIoPacket_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyIoPacket_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "io_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyIoPacket_methods, /* tp_methods */ PyIoPacket_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyIoPacket_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * The PyAclPacket type */ typedef struct { PyObject_HEAD const char *fname; /* Filename */ PyObject *content; /* ACL content */ } PyAclPacket; /* * Forward declarations of type specific functions. */ static void PyAclPacket_dealloc(PyAclPacket *self); static int PyAclPacket_init(PyAclPacket *self, PyObject *args, PyObject *kwds); static PyObject *PyAclPacket_repr(PyAclPacket *self); static PyMethodDef PyAclPacket_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PyAclPacket_members[] = { { (char *)"fname", T_STRING, offsetof(PyAclPacket, fname), 0, (char *)"Filename" }, { (char *)"content", T_OBJECT, offsetof(PyAclPacket, content), 0, (char *)"ACL content buffer" }, { NULL } }; static PyTypeObject PyAclPacketType = { PyVarObject_HEAD_INIT(NULL, 0) "acl_pkt", /* tp_name */ sizeof(PyAclPacket), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyAclPacket_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyAclPacket_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "acl_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyAclPacket_methods, /* tp_methods */ PyAclPacket_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyAclPacket_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * The PyXattrPacket type */ typedef struct { PyObject_HEAD const char *fname; /* Filename */ PyObject *name; /* XATTR name */ PyObject *value; /* XATTR value */ } PyXattrPacket; /* * Forward declarations of type specific functions. */ static void PyXattrPacket_dealloc(PyXattrPacket *self); static int PyXattrPacket_init(PyXattrPacket *self, PyObject *args, PyObject *kwds); static PyObject *PyXattrPacket_repr(PyXattrPacket *self); static PyMethodDef PyXattrPacket_methods[] = { { NULL } /* Sentinel */ }; static PyMemberDef PyXattrPacket_members[] = { { (char *)"fname", T_STRING, offsetof(PyXattrPacket, fname), 0, (char *)"Filename" }, { (char *)"name", T_OBJECT, offsetof(PyXattrPacket, name), 0, (char *)"XATTR name buffer" }, { (char *)"value", T_OBJECT, offsetof(PyXattrPacket, value), 0, (char *)"XATTR value buffer" }, { NULL } }; static PyTypeObject PyXattrPacketType = { PyVarObject_HEAD_INIT(NULL, 0) "xattr_pkt", /* tp_name */ sizeof(PyXattrPacket), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyXattrPacket_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)PyXattrPacket_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/ "xattr_pkt object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ PyXattrPacket_methods, /* tp_methods */ PyXattrPacket_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyXattrPacket_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; /* * Callback methods from Python. */ static PyObject *PyBareosGetValue(PyObject *self, PyObject *args); static PyObject *PyBareosSetValue(PyObject *self, PyObject *args); static PyObject *PyBareosDebugMessage(PyObject *self, PyObject *args); static PyObject *PyBareosJobMessage(PyObject *self, PyObject *args); static PyObject *PyBareosRegisterEvents(PyObject *self, PyObject *args); static PyObject *PyBareosAddExclude(PyObject *self, PyObject *args); static PyObject *PyBareosAddInclude(PyObject *self, PyObject *args); static PyObject *PyBareosAddOptions(PyObject *self, PyObject *args); static PyObject *PyBareosAddRegex(PyObject *self, PyObject *args); static PyObject *PyBareosAddWild(PyObject *self, PyObject *args); static PyObject *PyBareosNewOptions(PyObject *self, PyObject *args); static PyObject *PyBareosNewInclude(PyObject *self, PyObject *args); static PyObject *PyBareosNewPreInclude(PyObject *self, PyObject *args); static PyMethodDef BareosFDMethods[] = { { "GetValue", PyBareosGetValue, METH_VARARGS, "Get a Plugin value" }, { "SetValue", PyBareosSetValue, METH_VARARGS, "Set a Plugin value" }, { "DebugMessage", PyBareosDebugMessage, METH_VARARGS, "Print a Debug message" }, { "JobMessage", PyBareosJobMessage, METH_VARARGS, "Print a Job message" }, { "RegisterEvents", PyBareosRegisterEvents, METH_VARARGS, "Register Plugin Events" }, { "AddExclude", PyBareosAddExclude, METH_VARARGS, "Add Exclude pattern" }, { "AddInclude", PyBareosAddInclude, METH_VARARGS, "Add Include pattern" }, { "AddOptions", PyBareosAddOptions, METH_VARARGS, "Add Include options" }, { "AddRegex", PyBareosAddRegex, METH_VARARGS, "Add regex" }, { "AddWild", PyBareosAddWild, METH_VARARGS, "Add wildcard" }, { "NewOptions", PyBareosNewOptions, METH_VARARGS, "Add new option block" }, { "NewInclude", PyBareosNewInclude, METH_VARARGS, "Add new include block" }, { "NewPreInclude", PyBareosNewPreInclude, METH_VARARGS, "Add new pre include block" }, { NULL, NULL, 0, NULL } }; #endif /* BPYTHONFD_H */ bareos-Release-14.2.6/src/plugins/filed/test-deltaseq-fd.c000066400000000000000000000311771263011562700233160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * A simple delta plugin for the Bareos File Daemon * * */ #include "bareos.h" #include "fd_plugins.h" #include "fd_common.h" static const int dbglvl = 0; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Eric Bollengier" #define PLUGIN_DATE "November 2010" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "Bareos Delta Test Plugin" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC endBackupFile(bpContext *ctx); static bRC pluginIO(bpContext *ctx, struct io_pkt *io); static bRC startRestoreFile(bpContext *ctx, const char *cmd); static bRC endRestoreFile(bpContext *ctx); static bRC createFile(bpContext *ctx, struct restore_pkt *rp); static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp); /* Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; /* Plugin Information block */ static genpInfo pluginInfo = { sizeof(pluginInfo), FD_PLUGIN_INTERFACE_VERSION, FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION }; /* Plugin entry points for Bareos */ static pFuncs pluginFuncs = { sizeof(pluginFuncs), FD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent, startBackupFile, endBackupFile, startRestoreFile, endRestoreFile, pluginIO, createFile, setFileAttributes, NULL, /* no checkFile */ NULL, /* no getAcl */ NULL, /* no setAcl */ NULL, /* no getXattr */ NULL /* no setXattr */ }; #define get_self(x) ((delta_test*)((x)->pContext)) class delta_test { private: bpContext *ctx; public: POOLMEM *fname; /* Filename to save */ int32_t delta; FILE *fd; bool done; int level; delta_test(bpContext *bpc) { fd = NULL; ctx = bpc; done = false; level = 0; delta = 0; fname = get_pool_memory(PM_FNAME); } ~delta_test() { free_and_null_pool_memory(fname); } }; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. */ /* * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, genpInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ /* Activate this plugin only in developer mode */ #ifdef DEVELOPER return bRC_OK; #else return bRC_Error; #endif } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { // Dmsg(NULL, dbglvl, "delta-test-fd: Unloaded\n"); return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. */ /* * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { delta_test *self = new delta_test(ctx); if (!self) { return bRC_Error; } ctx->pContext = (void *)self; /* set our context pointer */ bfuncs->registerBareosEvents(ctx, 3, bEventLevel, bEventRestoreCommand, bEventBackupCommand); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { delta_test *self = get_self(ctx); if (!self) { return bRC_Error; } delete self; return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) { delta_test *self = get_self(ctx); int accurate=0; if (!self) { return bRC_Error; } // char *name; switch (event->eventType) { case bEventLevel: // Dmsg(ctx, dbglvl, "delta-test-fd: JobLevel=%c %d\n", (int)value, (int)value); self->level = (int)(intptr_t)value; break; /* Plugin command e.g. plugin = ::read command:write command */ case bEventRestoreCommand: // Dmsg(ctx, dbglvl, "delta-test-fd: EventRestoreCommand cmd=%s\n", (char *)value); /* Fall-through wanted */ case bEventBackupCommand: Dmsg(ctx, dbglvl, "delta-test-fd: pluginEvent cmd=%s\n", (char *)value); if (self->level == 'I' || self->level == 'D') { bfuncs->getBareosValue(ctx, bVarAccurate, (void *)&accurate); if (!accurate) { /* can be changed to FATAL */ Jmsg(ctx, M_FATAL, "Accurate mode should be turned on when using the " "delta-test plugin\n"); return bRC_Error; } } break; default: // Dmsg(ctx, dbglvl, "delta-test-fd: unknown event=%d\n", event->eventType); break; } return bRC_OK; } static const char *files[] = { "/etc/passwd", "/etc/group", "/etc/hosts", "/etc/services" }; static int nb_files = 4; /* * Start the backup of a specific file */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { delta_test *self = get_self(ctx); if (!self) { return bRC_Error; } time_t now = time(NULL); sp->fname = (char *)"/delta.txt"; sp->type = FT_REG; sp->statp.st_mode = 0700 | S_IFREG; sp->statp.st_ctime = now; sp->statp.st_mtime = now; sp->statp.st_atime = now; sp->statp.st_size = -1; sp->statp.st_blksize = 4096; sp->statp.st_blocks = 1; if (self->level == 'I' || self->level == 'D') { bRC state = bfuncs->checkChanges(ctx, sp); /* Should always be bRC_OK */ sp->type = (state == bRC_Seen)? FT_NOCHG : FT_REG; set_bit(FO_DELTA, sp->flags); set_bit(FO_OFFSETS, sp->flags); self->delta = sp->delta_seq + 1; } pm_strcpy(self->fname, files[self->delta % nb_files]); Dmsg(ctx, dbglvl, "delta-test-fd: delta_seq=%i delta=%i fname=%s\n", sp->delta_seq, self->delta, self->fname); // Dmsg(ctx, dbglvl, "delta-test-fd: startBackupFile\n"); return bRC_OK; } /* * Done with backup of this file */ static bRC endBackupFile(bpContext *ctx) { /* * We would return bRC_More if we wanted startBackupFile to be * called again to backup another file */ return bRC_OK; } /* * Bareos is calling us to do the actual I/O */ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) { delta_test *self = get_self(ctx); struct stat statp; if (!self) { return bRC_Error; } io->status = 0; io->io_errno = 0; switch(io->func) { case IO_OPEN: Dmsg(ctx, dbglvl, "delta-test-fd: IO_OPEN\n"); if (io->flags & (O_CREAT | O_WRONLY)) { /* TODO: if the file already exists, the result is undefined */ if (stat(io->fname, &statp) == 0) { /* file exists */ self->fd = fopen(io->fname, "r+"); } else { self->fd = fopen(io->fname, "w"); /* file doesn't exist,create it */ } if (!self->fd) { io->io_errno = errno; Jmsg(ctx, M_FATAL, "Open failed: ERR=%s\n", strerror(errno)); return bRC_Error; } } else { self->fd = fopen(self->fname, "r"); if (!self->fd) { io->io_errno = errno; Jmsg(ctx, M_FATAL, "Open failed: ERR=%s\n", strerror(errno)); return bRC_Error; } } break; case IO_READ: if (!self->fd) { Jmsg(ctx, M_FATAL, "Logic error: NULL read FD\n"); return bRC_Error; } if (self->done) { io->status = 0; } else { /* first time, read 300, then replace 50-250 by other data */ if (self->delta == 0) { io->status = fread(io->buf, 1, 400, self->fd); } else { io->offset = self->delta * 100 / 2; /* chunks are melted */ io->status = fread(io->buf, 1, 100, self->fd); } Dmsg(ctx, dbglvl, "delta-test-fd: READ offset=%lld\n", (int64_t)io->offset); self->done = true; } if (io->status == 0 && ferror(self->fd)) { Jmsg(ctx, M_FATAL, "Pipe read error: ERR=%s\n", strerror(errno)); Dmsg(ctx, dbglvl, "Pipe read error: ERR=%s\n", strerror(errno)); return bRC_Error; } Dmsg(ctx, dbglvl, "offset=%d\n", io->offset); break; case IO_WRITE: if (!self->fd) { Jmsg(ctx, M_FATAL, "Logic error: NULL write FD\n"); return bRC_Error; } Dmsg(ctx, dbglvl, "delta-test-fd: WRITE count=%lld\n", (int64_t)io->count); io->status = fwrite(io->buf, 1, io->count, self->fd); if (io->status == 0 && ferror(self->fd)) { Jmsg(ctx, M_FATAL, "Pipe write error\n"); Dmsg(ctx, dbglvl, "Pipe read error: ERR=%s\n", strerror(errno)); return bRC_Error; } break; case IO_CLOSE: if (!self->fd) { Jmsg(ctx, M_FATAL, "Logic error: NULL FD on delta close\n"); return bRC_Error; } io->status = fclose(self->fd); break; case IO_SEEK: if (!self->fd) { Jmsg(ctx, M_FATAL, "Logic error: NULL FD on delta close\n"); return bRC_Error; } Dmsg(ctx, dbglvl, "delta-test-fd: SEEK offset=%lld\n", (int64_t)io->offset); io->status = fseek(self->fd, io->offset, io->whence); Dmsg(ctx, dbglvl, "after SEEK=%lld\n", (int64_t)ftell(self->fd)); break; } return bRC_OK; } /* * Bareos is notifying us that a plugin name string was found, and * passing us the plugin command, so we can prepare for a restore. */ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { // Dmsg(ctx, dbglvl, "delta-test-fd: startRestoreFile cmd=%s\n", cmd); return bRC_OK; } /* * Bareos is notifying us that the plugin data has terminated, so * the restore for this particular file is done. */ static bRC endRestoreFile(bpContext *ctx) { // Dmsg(ctx, dbglvl, "delta-test-fd: endRestoreFile\n"); return bRC_OK; } /* * This is called during restore to create the file (if necessary) * We must return in rp->create_status: * * CF_ERROR -- error * CF_SKIP -- skip processing this file * CF_EXTRACT -- extract the file (i.e.call i/o routines) * CF_CREATED -- created, but no content to extract (typically directories) * */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { delta_test *self = get_self(ctx); pm_strcpy(self->fname, rp->ofname); rp->create_status = CF_EXTRACT; return bRC_OK; } /* * We will get here if the File is a directory after everything * is written in the directory. */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { // Dmsg(ctx, dbglvl, "delta-test-fd: setFileAttributes\n"); return bRC_OK; } bareos-Release-14.2.6/src/plugins/filed/test-plugin-fd.c000066400000000000000000000703321263011562700230060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * A simple test plugin for the Bareos File Daemon derived from * the bpipe plugin, but used for testing new features. * * Kern Sibbald, October 2007 */ #include "bareos.h" #include "fd_plugins.h" #include "fd_common.h" #include "lib/ini.h" #include static const int dbglvl = 000; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Kern Sibbald" #define PLUGIN_DATE "May 2011" #define PLUGIN_VERSION "3" #define PLUGIN_DESCRIPTION "Bareos Test File Daemon Plugin" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC endBackupFile(bpContext *ctx); static bRC pluginIO(bpContext *ctx, struct io_pkt *io); static bRC startRestoreFile(bpContext *ctx, const char *cmd); static bRC endRestoreFile(bpContext *ctx); static bRC createFile(bpContext *ctx, struct restore_pkt *rp); static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp); static bRC checkFile(bpContext *ctx, char *fname); static bRC getAcl(bpContext *ctx, acl_pkt *ap); static bRC setAcl(bpContext *ctx, acl_pkt *ap); static bRC getXattr(bpContext *ctx, xattr_pkt *xp); static bRC setXattr(bpContext *ctx, xattr_pkt *xp); /* Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; /* Plugin Information block */ static genpInfo pluginInfo = { sizeof(pluginInfo), FD_PLUGIN_INTERFACE_VERSION, FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION }; /* Plugin entry points for Bareos */ static pFuncs pluginFuncs = { sizeof(pluginFuncs), FD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent, startBackupFile, endBackupFile, startRestoreFile, endRestoreFile, pluginIO, createFile, setFileAttributes, checkFile, getAcl, setAcl, getXattr, setXattr }; static struct ini_items test_items[] = { // name type comment required { "string1", INI_CFG_TYPE_STR, "Special String", 1 }, { "string2", INI_CFG_TYPE_STR, "2nd String", 0 }, { "ok", INI_CFG_TYPE_BOOL, "boolean", 0 }, // We can also use the ITEMS_DEFAULT // { "ok", INI_CFG_TYPE_BOOL, "boolean", 0, ITEMS_DEFAULT }, { NULL, 0, NULL, 0 } }; /* * Plugin private context */ struct plugin_ctx { boffset_t offset; FILE *fd; /* pipe file descriptor */ char *cmd; /* plugin command line */ char *fname; /* filename to "backup/restore" */ char *reader; /* reader program for backup */ char *writer; /* writer program for backup */ char where[512]; int replace; int nb_obj; /* Number of objects created */ POOLMEM *buf; /* store ConfigFile */ }; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. */ /* * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, genpInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. */ /* * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(struct plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ bfuncs->registerBareosEvents(ctx, 6, bEventJobStart, bEventEndFileSet, bEventRestoreObject, bEventEstimateCommand, bEventBackupCommand, bEventComponentInfo); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } if (p_ctx->buf) { free_pool_memory(p_ctx->buf); } if (p_ctx->cmd) { free(p_ctx->cmd); /* free any allocated command string */ } free(p_ctx); /* free our private context */ ctx->pContext = NULL; return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; restore_object_pkt *rop; if (!p_ctx) { return bRC_Error; } // char *name; switch (event->eventType) { case bEventJobStart: Dmsg(ctx, dbglvl, "test-plugin-fd: JobStart=%s\n", (char *)value); break; case bEventEndFileSet: /* * End of Dir FileSet commands, now we can add excludes */ bfuncs->NewOptions(ctx); bfuncs->AddWild(ctx, "*.c", ' '); bfuncs->AddWild(ctx, "*.cpp", ' '); bfuncs->AddOptions(ctx, "ei"); /* exclude, ignore case */ bfuncs->AddExclude(ctx, "/home/user/bareos/regress/README"); break; case bEventRestoreObject: { FILE *fp; POOLMEM *q; char *working; static int _nb = 0; printf("Plugin RestoreObject\n"); if (!value) { Dmsg(ctx, dbglvl, "test-plugin-fd: End restore objects\n"); break; } rop = (restore_object_pkt *)value; Dmsg(ctx, dbglvl, "Get RestoreObject len=%d JobId=%d oname=%s type=%d data=%.127s\n", rop->object_len, rop->JobId, rop->object_name, rop->object_type, rop->object); q = get_pool_memory(PM_FNAME); bfuncs->getBareosValue(ctx, bVarWorkingDir, &working); Mmsg(q, "%s/restore.%d", working, _nb++); if ((fp = fopen(q, "w")) != NULL) { fwrite(rop->object, rop->object_len, 1, fp); fclose(fp); } free_pool_memory(q); if (!strcmp(rop->object_name, INI_RESTORE_OBJECT_NAME)) { ConfigFile ini; if (!ini.dump_string(rop->object, rop->object_len)) { break; } ini.register_items(test_items, sizeof(struct ini_items)); if (ini.parse(ini.out_fname)) { Jmsg(ctx, M_INFO, "string1 = %s\n", ini.items[0].val.strval); } else { Jmsg(ctx, M_ERROR, "Can't parse config\n"); } } break; } case bEventEstimateCommand: /* Fall-through wanted */ case bEventBackupCommand: { /* * Plugin command e.g. plugin = ::read command:write command */ char *p; Dmsg(ctx, dbglvl, "test-plugin-fd: pluginEvent cmd=%s\n", (char *)value); p_ctx->cmd = bstrdup((char *)value); p = strchr(p_ctx->cmd, ':'); if (!p) { Jmsg(ctx, M_FATAL, "Plugin terminator not found: %s\n", (char *)value); Dmsg(ctx, dbglvl, "Plugin terminator not found: %s\n", (char *)value); return bRC_Error; } *p++ = 0; /* terminate plugin */ p_ctx->fname = p; p = strchr(p, ':'); if (!p) { Jmsg(ctx, M_FATAL, "File terminator not found: %s\n", (char *)value); Dmsg(ctx, dbglvl, "File terminator not found: %s\n", (char *)value); return bRC_Error; } *p++ = 0; /* terminate file */ p_ctx->reader = p; p = strchr(p, ':'); if (!p) { Jmsg(ctx, M_FATAL, "Reader terminator not found: %s\n", (char *)value); Dmsg(ctx, dbglvl, "Reader terminator not found: %s\n", (char *)value); return bRC_Error; } *p++ = 0; /* terminate reader string */ p_ctx->writer = p; Dmsg(ctx, dbglvl, "test-plugin-fd: plugin=%s fname=%s reader=%s writer=%s\n", p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer); break; } case bEventComponentInfo: Dmsg(ctx, dbglvl, "plugin: Component=%s\n", NPRT((char *)value)); break; default: Dmsg(ctx, dbglvl, "test-plugin-fd: unknown event=%d\n", event->eventType); break; } return bRC_OK; } /* * Start the backup of a specific file */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } if (p_ctx->nb_obj == 0) { sp->fname = (char *)"takeme.h"; Dmsg(ctx, dbglvl, "AcceptFile=%s = %d\n", sp->fname, bfuncs->AcceptFile(ctx, sp)); sp->fname = (char *)"/path/to/excludeme.o"; Dmsg(ctx, dbglvl, "AcceptFile=%s = %d\n", sp->fname, bfuncs->AcceptFile(ctx, sp)); sp->fname = (char *)"/path/to/excludeme.c"; Dmsg(ctx, dbglvl, "AcceptFile=%s = %d\n", sp->fname, bfuncs->AcceptFile(ctx, sp)); } if (p_ctx->nb_obj == 0) { sp->object_name = (char *)"james.xml"; sp->object = (char *)"This is test data for the restore object. " "garbage=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" "\0secret"; sp->object_len = strlen(sp->object)+1+6+1; /* str + 0 + secret + 0 */ sp->type = FT_RESTORE_FIRST; static int _nb=0; POOLMEM *q = get_pool_memory(PM_FNAME); char *working; FILE *fp; bfuncs->getBareosValue(ctx, bVarWorkingDir, &working); Mmsg(q, "%s/torestore.%d", working, _nb++); if ((fp = fopen(q, "w")) != NULL) { fwrite(sp->object, sp->object_len, 1, fp); fclose(fp); } free_pool_memory(q); } else if (p_ctx->nb_obj == 1) { ConfigFile ini; p_ctx->buf = get_pool_memory(PM_BSOCK); ini.register_items(test_items, sizeof(struct ini_items)); sp->object_name = (char*)INI_RESTORE_OBJECT_NAME; sp->object_len = ini.serialize(&p_ctx->buf); sp->object = p_ctx->buf; sp->type = FT_PLUGIN_CONFIG; Dmsg(ctx, dbglvl, "RestoreOptions=<%s>\n", p_ctx->buf); } time_t now = time(NULL); sp->index = ++p_ctx->nb_obj; sp->statp.st_mode = 0700 | S_IFREG; sp->statp.st_ctime = now; sp->statp.st_mtime = now; sp->statp.st_atime = now; sp->statp.st_size = sp->object_len; sp->statp.st_blksize = 4096; sp->statp.st_blocks = 1; Dmsg(ctx, dbglvl, "Creating RestoreObject len=%d oname=%s data=%.127s\n", sp->object_len, sp->object_name, sp->object); Dmsg(ctx, dbglvl,"test-plugin-fd: startBackupFile\n"); return bRC_OK; } static bRC getAcl(bpContext *ctx, acl_pkt *ap) { return bRC_OK; } static bRC setAcl(bpContext *ctx, acl_pkt *ap) { return bRC_OK; } static bRC getXattr(bpContext *ctx, xattr_pkt *xp) { return bRC_OK; } static bRC setXattr(bpContext *ctx, xattr_pkt *xp) { return bRC_OK; } /* * Done with backup of this file */ static bRC endBackupFile(bpContext *ctx) { /* * We would return bRC_More if we wanted startBackupFile to be * called again to backup another file */ return bRC_OK; } /* * Bareos is calling us to do the actual I/O */ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } io->status = 0; io->io_errno = 0; return bRC_OK; } /* * Bareos is notifying us that a plugin name string was found, and * passing us the plugin command, so we can prepare for a restore. */ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { printf("test-plugin-fd: startRestoreFile cmd=%s\n", cmd); return bRC_OK; } /* * Bareos is notifying us that the plugin data has terminated, so * the restore for this particular file is done. */ static bRC endRestoreFile(bpContext *ctx) { printf("test-plugin-fd: endRestoreFile\n"); return bRC_OK; } /* * This is called during restore to create the file (if necessary) * We must return in rp->create_status: * * CF_ERROR -- error * CF_SKIP -- skip processing this file * CF_EXTRACT -- extract the file (i.e.call i/o routines) * CF_CREATED -- created, but no content to extract (typically directories) * */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { printf("test-plugin-fd: createFile\n"); if (strlen(rp->where) > 512) { printf("Restore target dir too long. Restricting to first 512 bytes.\n"); } bstrncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 513); ((struct plugin_ctx *)ctx->pContext)->replace = rp->replace; rp->create_status = CF_EXTRACT; return bRC_OK; } /* * We will get here if the File is a directory after everything * is written in the directory. */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { printf("test-plugin-fd: setFileAttributes\n"); return bRC_OK; } /* When using Incremental dump, all previous dumps are necessary */ static bRC checkFile(bpContext *ctx, char *fname) { return bRC_OK; } bareos-Release-14.2.6/src/plugins/stored/000077500000000000000000000000001263011562700202105ustar00rootroot00000000000000bareos-Release-14.2.6/src/plugins/stored/Makefile.in000066400000000000000000000064061263011562700222630ustar00rootroot00000000000000# # Simple Makefile for building test SD plugins for Bareos # @MCOMMON@ PYTHON_CPPFLAGS += @PYTHON_INC@ COMPRESS_CPPFLAGS += @ZLIB_INC@ @LZO_INC@ @FASTLZ_INC@ # No optimization for now for easy debugging srcdir = @srcdir@ VPATH = @srcdir@:../../stored .PATH: @srcdir@ basedir = ../.. # top dir topdir = ../../.. # this dir relative to top dir thisdir = src/plugins/stored INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include -I$(basedir)/stored BUILD_PLUGINS = @BUILD_SD_PLUGINS@ .SUFFIXES: .c .lo # inference rules .c.lo: $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) -c $< all: Makefile $(BUILD_PLUGINS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status autoxflate-sd.lo: autoxflate-sd.c $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) $(COMPRESS_CPPFLAGS) -c $< autoxflate-sd.la: Makefile \ autoxflate-sd$(DEFAULT_OBJECT_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared autoxflate-sd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version -L../../lib -lbareos example-plugin-sd.la: Makefile example-plugin-sd$(DEFAULT_OBJECT_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared example-plugin-sd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version python-sd.lo: python-sd.c python-sd.h $(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(INCLUDES) $(PYTHON_CPPFLAGS) -c $< python-sd.la: Makefile \ python-sd$(DEFAULT_OBJECT_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared python-sd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version \ -L../../lib -lbareos @PYTHON_LIBS@ scsicrypto-sd.la: Makefile \ scsicrypto-sd$(DEFAULT_OBJECT_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared scsicrypto-sd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version -L../../lib -lbareos scsitapealert-sd.la: Makefile \ scsitapealert-sd$(DEFAULT_OBJECT_TYPE) \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -shared scsitapealert-sd.lo -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version -L../../lib -lbareos plugtest: Makefile sd_plugins.c \ ../../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) ../../stored/sd_plugins.c $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../../lib -o $@ sd_plugins.o -lbareos $(DLIB) -lm $(LIBS) install: all $(MKDIR) $(DESTDIR)$(plugindir) $(CP) *.py *.py.template $(DESTDIR)$(plugindir) @for plugin in $(BUILD_PLUGINS); do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$plugin $(DESTDIR)$(plugindir); \ $(RMF) $(DESTDIR)$(plugindir)/$$plugin; \ done install-test-plugin: $(MKDIR) $(DESTDIR)$(plugindir) $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) example-plugin-sd$(DEFAULT_SHARED_OBJECT_TYPE) $(DESTDIR)$(plugindir) $(RMF) $(DESTDIR)$(plugindir)/example-plugin-sd.la libtool-clean: find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) $(RMF) *.la $(RMF) -r .libs _libs clean: @LIBTOOL_CLEAN_TARGET@ @$(RMF) plugtest *.so *.o 1 2 3 distclean: clean @$(RMF) Makefile depend: bareos-Release-14.2.6/src/plugins/stored/autoxflate-sd.c000066400000000000000000000601261263011562700231410ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Storage Daemon plugin that handles automatic deflation/inflation of data. * * Marco van Wieringen, June 2013 */ #include "bareos.h" #include "stored.h" #if defined(HAVE_LIBZ) #include #endif #if defined(HAVE_FASTLZ) #include #endif #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Marco van Wieringen" #define PLUGIN_DATE "June 2013" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "Auto Xflation Storage Daemon Plugin" #define PLUGIN_USAGE "(No usage yet)" #define Dmsg(context, level, ...) bfuncs->DebugMessage(context, __FILE__, __LINE__, level, __VA_ARGS__ ) #define Jmsg(context, type, ...) bfuncs->JobMessage(context, __FILE__, __LINE__, type, 0, __VA_ARGS__ ) #define SETTING_YES (char *)"yes" #define SETTING_NO (char *)"no" #define SETTING_UNSET (char *)"unknown" #define COMPRESSOR_NAME_GZIP (char *)"GZIP" #define COMPRESSOR_NAME_LZO (char *)"LZO" #define COMPRESSOR_NAME_FZLZ (char *)"FASTLZ" #define COMPRESSOR_NAME_FZ4L (char *)"LZ4" #define COMPRESSOR_NAME_FZ4H (char *)"LZ4HC" #define COMPRESSOR_NAME_UNSET (char *)"unknown" /* * Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); static bRC handleJobEnd(bpContext *ctx); static bRC setup_record_translation(bpContext *ctx, void *value); static bRC handle_read_translation(bpContext *ctx, void *value); static bRC handle_write_translation(bpContext *ctx, void *value); static bool setup_auto_deflation(bpContext *ctx, DCR *dcr); static bool setup_auto_inflation(bpContext *ctx, DCR *dcr); static bool auto_deflate_record(bpContext *ctx, DCR *dcr); static bool auto_inflate_record(bpContext *ctx, DCR *dcr); /* * Is the SD in compatible mode or not. */ static bool sd_enabled_compatible = false; /* * Pointers to Bareos functions */ static bsdFuncs *bfuncs = NULL; static bsdInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION, SD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; static psdFuncs pluginFuncs = { sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION, /* * Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; /* * Plugin private context */ struct plugin_ctx { /* * Counters for compression/decompression ratio */ uint64_t deflate_bytes_in; uint64_t deflate_bytes_out; uint64_t inflate_bytes_in; uint64_t inflate_bytes_out; }; static int const dbglvl = 200; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load the plugin */ bRC DLL_IMP_EXP loadPlugin(bsdInfo *lbinfo, bsdFuncs *lbfuncs, genpInfo **pinfo, psdFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ /* * Get the current setting of the compatible flag. */ bfuncs->getBareosValue(NULL, bsdVarCompatible, (void *)&sd_enabled_compatible); return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. * * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { int JobId = 0; struct plugin_ctx *p_ctx; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); Dmsg(ctx, dbglvl, "autoxflate-sd: newPlugin JobId=%d\n", JobId); p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(struct plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ /* * Only register plugin events we are interested in. * * bsdEventJobEnd - SD Job finished. * bsdEventSetupRecordTranslation - Setup the buffers for doing record translation. * bsdEventReadRecordTranslation - Perform read-side record translation. * bsdEventWriteRecordTranslation - Perform write-side record translantion. */ bfuncs->registerBareosEvents(ctx, 4, bsdEventJobEnd, bsdEventSetupRecordTranslation, bsdEventReadRecordTranslation, bsdEventWriteRecordTranslation); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { int JobId = 0; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); Dmsg(ctx, dbglvl, "autoxflate-sd: freePlugin JobId=%d\n", JobId); if (!p_ctx) { Dmsg(ctx, dbglvl, "autoxflate-sd: freePlugin JobId=%d\n", JobId); return bRC_Error; } if (p_ctx) { free(p_ctx); } ctx->pContext = NULL; return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value) { Dmsg(ctx, dbglvl, "autoxflate-sd: getPluginValue var=%d\n", var); return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value) { Dmsg(ctx, dbglvl, "autoxflate-sd: setPluginValue var=%d\n", var); return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { switch (event->eventType) { case bsdEventSetupRecordTranslation: return setup_record_translation(ctx, value); case bsdEventReadRecordTranslation: return handle_read_translation(ctx, value); case bsdEventWriteRecordTranslation: return handle_write_translation(ctx, value); case bsdEventJobEnd: return handleJobEnd(ctx); default: Dmsg(ctx, dbglvl, "autoxflate-sd: Unknown event %d\n", event->eventType); return bRC_Error; } return bRC_OK; } /* * At end of job report how inflate/deflate ratio was. */ static bRC handleJobEnd(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } if (p_ctx->inflate_bytes_in) { Dmsg(ctx, dbglvl, "autoxflate-sd.c: inflate ratio: %lld/%lld = %0.2f%%\n" , p_ctx->inflate_bytes_out, p_ctx->inflate_bytes_in, (p_ctx->inflate_bytes_out * 100.0 / p_ctx->inflate_bytes_in)); Jmsg(ctx, M_INFO, _("autoxflate-sd.c: inflate ratio: %0.2f%%\n"), (p_ctx->inflate_bytes_out * 100.0 / p_ctx->inflate_bytes_in)); } if (p_ctx->deflate_bytes_in) { Dmsg(ctx, dbglvl, "autoxflate-sd.c: deflate ratio: %lld/%lld = %0.2f%%\n", p_ctx->deflate_bytes_out, p_ctx->deflate_bytes_in, (p_ctx->deflate_bytes_out * 100.0 / p_ctx->deflate_bytes_in)); Jmsg(ctx, M_INFO, _("autoxflate-sd.c: deflate ratio: %0.2f%%\n"), (p_ctx->deflate_bytes_out * 100.0 / p_ctx->deflate_bytes_in)); } bail_out: return bRC_OK; } static bRC setup_record_translation(bpContext *ctx, void *value) { DCR *dcr; bool did_setup = false; const char *inflate_in = SETTING_UNSET; const char *inflate_out = SETTING_UNSET; const char *deflate_in = SETTING_UNSET; const char *deflate_out = SETTING_UNSET; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { return bRC_Error; } /* * Give jobmessage info what is configured */ switch (dcr->autodeflate) { case IO_DIRECTION_NONE: deflate_in = SETTING_NO; deflate_out = SETTING_NO; break; case IO_DIRECTION_IN: deflate_in = SETTING_YES; deflate_out = SETTING_NO; break; case IO_DIRECTION_OUT: deflate_in = SETTING_NO; deflate_out = SETTING_YES; break; case IO_DIRECTION_INOUT: deflate_in = SETTING_YES; deflate_out = SETTING_YES; break; default: Jmsg(ctx, M_ERROR, _("Unexpected autodeflate setting on %s"), dcr->dev_name); break; } switch (dcr->autoinflate) { case IO_DIRECTION_NONE: inflate_in = SETTING_NO; inflate_out = SETTING_NO; break; case IO_DIRECTION_IN: inflate_in = SETTING_YES; inflate_out = SETTING_NO; break; case IO_DIRECTION_OUT: inflate_in = SETTING_NO; inflate_out = SETTING_YES; break; case IO_DIRECTION_INOUT: inflate_in = SETTING_YES; inflate_out = SETTING_YES; break; default: Jmsg(ctx, M_ERROR, _("Unexpected autoinflate setting on %s"), dcr->dev_name); break; } /* * Setup auto deflation/inflation of streams when enabled for this device. */ switch (dcr->autodeflate) { case IO_DIRECTION_NONE: break; case IO_DIRECTION_OUT: case IO_DIRECTION_INOUT: if (!setup_auto_deflation(ctx, dcr)) { return bRC_Error; } did_setup = true; break; default: break; } switch (dcr->autoinflate) { case IO_DIRECTION_NONE: break; case IO_DIRECTION_OUT: case IO_DIRECTION_INOUT: if (!setup_auto_inflation(ctx, dcr)) { return bRC_Error; } did_setup = true; break; default: break; } if (did_setup) { Jmsg(ctx, M_INFO, _("autoxflate-sd.c: %s OUT:[SD->inflate=%s->deflate=%s->DEV] IN:[DEV->inflate=%s->deflate=%s->SD]\n"), dcr->dev_name, inflate_out, deflate_out, inflate_in, deflate_in); } return bRC_OK; } static bRC handle_read_translation(bpContext *ctx, void *value) { DCR *dcr; bool swap_record = false; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { return bRC_Error; } /* * See if we need to perform auto deflation/inflation of streams. */ switch (dcr->autoinflate) { case IO_DIRECTION_IN: case IO_DIRECTION_INOUT: swap_record = auto_inflate_record(ctx, dcr); break; default: break; } if (!swap_record) { switch (dcr->autodeflate) { case IO_DIRECTION_IN: case IO_DIRECTION_INOUT: swap_record = auto_deflate_record(ctx, dcr); break; default: break; } } return bRC_OK; } static bRC handle_write_translation(bpContext *ctx, void *value) { DCR *dcr; bool swap_record = false; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { return bRC_Error; } /* * See if we need to perform auto deflation/inflation of streams. */ switch (dcr->autoinflate) { case IO_DIRECTION_OUT: case IO_DIRECTION_INOUT: swap_record = auto_inflate_record(ctx, dcr); break; default: break; } if (!swap_record) { switch (dcr->autodeflate) { case IO_DIRECTION_OUT: case IO_DIRECTION_INOUT: swap_record = auto_deflate_record(ctx, dcr); break; default: break; } } return bRC_OK; } /* * Setup deflate for auto deflate of data streams. */ static bool setup_auto_deflation(bpContext *ctx, DCR *dcr) { JCR *jcr = dcr->jcr; bool retval = false; uint32_t compress_buf_size = 0; const char *compressorname = COMPRESSOR_NAME_UNSET; if (jcr->buf_size == 0) { jcr->buf_size = DEFAULT_NETWORK_BUFFER_SIZE; } if (!setup_compression_buffers(jcr, sd_enabled_compatible, dcr->device->autodeflate_algorithm, &compress_buf_size)) { goto bail_out; } /* * See if we need to create a new compression buffer or make sure the existing is big enough. */ if (!jcr->compress.deflate_buffer) { jcr->compress.deflate_buffer = get_memory(compress_buf_size); jcr->compress.deflate_buffer_size = compress_buf_size; } else { if (compress_buf_size > jcr->compress.deflate_buffer_size) { jcr->compress.deflate_buffer = realloc_pool_memory(jcr->compress.deflate_buffer, compress_buf_size); jcr->compress.deflate_buffer_size = compress_buf_size; } } switch (dcr->device->autodeflate_algorithm) { #if defined(HAVE_LIBZ) case COMPRESS_GZIP: { compressorname = COMPRESSOR_NAME_GZIP; int zstat; z_stream *pZlibStream; pZlibStream = (z_stream *)jcr->compress.workset.pZLIB; if ((zstat = deflateParams(pZlibStream, dcr->device->autodeflate_level, Z_DEFAULT_STRATEGY)) != Z_OK) { Jmsg(ctx, M_FATAL, _("Compression deflateParams error: %d\n"), zstat); jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } break; } #endif #if defined(HAVE_LZO) case COMPRESS_LZO1X: compressorname = COMPRESSOR_NAME_LZO; break; #endif #if defined(HAVE_FASTLZ) case COMPRESS_FZFZ: compressorname = COMPRESSOR_NAME_FZLZ; case COMPRESS_FZ4L: compressorname = COMPRESSOR_NAME_FZ4L; case COMPRESS_FZ4H: { compressorname = COMPRESSOR_NAME_FZ4H; int zstat; zfast_stream *pZfastStream; zfast_stream_compressor compressor = COMPRESSOR_FASTLZ; switch (dcr->device->autodeflate_algorithm) { case COMPRESS_FZ4L: case COMPRESS_FZ4H: compressor = COMPRESSOR_LZ4; break; } pZfastStream = (zfast_stream *)jcr->compress.workset.pZFAST; if ((zstat = fastlzlibSetCompressor(pZfastStream, compressor)) != Z_OK) { Jmsg(ctx, M_FATAL, _("Compression fastlzlibSetCompressor error: %d\n"), zstat); jcr->setJobStatus(JS_ErrorTerminated); goto bail_out; } break; } #endif default: break; } Jmsg(ctx, M_INFO, _("autodeflation: Compressor on device %s is %s\n"), dcr->dev_name, compressorname); retval = true; bail_out: return retval; } /* * Setup inflation for auto inflation of data streams. */ static bool setup_auto_inflation(bpContext *ctx, DCR *dcr) { JCR *jcr = dcr->jcr; uint32_t decompress_buf_size; if (jcr->buf_size == 0) { jcr->buf_size = DEFAULT_NETWORK_BUFFER_SIZE; } setup_decompression_buffers(jcr, &decompress_buf_size); if (decompress_buf_size > 0) { /* * See if we need to create a new compression buffer or make sure the existing is big enough. */ if (!jcr->compress.inflate_buffer) { jcr->compress.inflate_buffer = get_memory(decompress_buf_size); jcr->compress.inflate_buffer_size = decompress_buf_size; } else { if (decompress_buf_size > jcr->compress.inflate_buffer_size) { jcr->compress.inflate_buffer = realloc_pool_memory(jcr->compress.inflate_buffer, decompress_buf_size); jcr->compress.inflate_buffer_size = decompress_buf_size; } } } else { return false; } return true; } /* * Perform automatic compression of certain stream types when enabled in the config. */ static bool auto_deflate_record(bpContext *ctx, DCR *dcr) { ser_declare; bool retval = false; comp_stream_header ch; DEV_RECORD *rec, *nrec; struct plugin_ctx *p_ctx; unsigned char *data = NULL; bool intermediate_value = false; unsigned int max_compression_length = 0; p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } /* * See what our starting point is. When dcr->after_rec is set we already have * a translated record by an other SD plugin. Then we use that translated record * as the starting point otherwise we start at dcr->before_rec. When an earlier * translation already happened we can free that record when we have a success * full translation here as that record is of no use anymore. */ if (dcr->after_rec) { rec = dcr->after_rec; intermediate_value = true; } else { rec = dcr->before_rec; } /* * We only do autocompression for the following stream types: * * - STREAM_FILE_DATA * - STREAM_WIN32_DATA * - STREAM_SPARSE_DATA */ switch (rec->maskedStream) { case STREAM_FILE_DATA: case STREAM_WIN32_DATA: case STREAM_SPARSE_DATA: break; default: goto bail_out; } /* * Clone the data from the original DEV_RECORD to the converted one. * As we use the compression buffers for the data we need a new * DEV_RECORD without a new memory buffer so we call new_record here * with the with_data boolean set explicitly to false. */ nrec = bfuncs->new_record(false); bfuncs->copy_record_state(nrec, rec); /* * Setup the converted DEV_RECORD to point with its data buffer to the compression buffer. */ nrec->data = dcr->jcr->compress.deflate_buffer; switch (rec->maskedStream) { case STREAM_FILE_DATA: case STREAM_WIN32_DATA: data = (unsigned char *)nrec->data + sizeof(comp_stream_header); max_compression_length = dcr->jcr->compress.deflate_buffer_size - sizeof(comp_stream_header); break; case STREAM_SPARSE_DATA: data = (unsigned char *)nrec->data + OFFSET_FADDR_SIZE + sizeof(comp_stream_header); max_compression_length = dcr->jcr->compress.deflate_buffer_size - OFFSET_FADDR_SIZE - sizeof(comp_stream_header); break; } /* * Compress the data using the configured compression algorithm. */ if (!compress_data(dcr->jcr, dcr->device->autodeflate_algorithm, rec->data, rec->data_len, data, max_compression_length, &nrec->data_len)) { bfuncs->free_record(nrec); goto bail_out; } /* * Map the streams. */ switch (rec->maskedStream) { case STREAM_FILE_DATA: nrec->Stream = STREAM_COMPRESSED_DATA; nrec->maskedStream = STREAM_COMPRESSED_DATA; break; case STREAM_WIN32_DATA: nrec->Stream = STREAM_WIN32_COMPRESSED_DATA; nrec->maskedStream = STREAM_WIN32_COMPRESSED_DATA; break; case STREAM_SPARSE_DATA: nrec->Stream = STREAM_SPARSE_COMPRESSED_DATA; nrec->maskedStream = STREAM_SPARSE_COMPRESSED_DATA; break; default: break; } /* * Generate a compression header. */ ch.magic = dcr->device->autodeflate_algorithm; ch.level = dcr->device->autodeflate_level; ch.version = COMP_HEAD_VERSION; ch.size = nrec->data_len; switch (nrec->maskedStream) { case STREAM_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: ser_begin(nrec->data, sizeof(comp_stream_header)); ser_uint32(ch.magic); ser_uint32(ch.size); ser_uint16(ch.level); ser_uint16(ch.version); ser_end(nrec->data, sizeof(comp_stream_header)); nrec->data_len += sizeof(comp_stream_header); break; case STREAM_SPARSE_COMPRESSED_DATA: /* * Copy the sparse offset from the original. */ memcpy(nrec->data, rec->data, OFFSET_FADDR_SIZE); ser_begin(nrec->data + OFFSET_FADDR_SIZE, sizeof(comp_stream_header)); ser_uint32(ch.magic); ser_uint32(ch.size); ser_uint16(ch.level); ser_uint16(ch.version); ser_end(nrec->data + OFFSET_FADDR_SIZE, sizeof(comp_stream_header)); nrec->data_len += OFFSET_FADDR_SIZE + sizeof(comp_stream_header); break; } Dmsg(ctx, 400, "auto_deflate_record: From datastream %d to %d from original size %ld to %ld\n", rec->maskedStream, nrec->maskedStream, rec->data_len, nrec->data_len); p_ctx->deflate_bytes_in += rec->data_len; p_ctx->deflate_bytes_out += nrec->data_len; /* * If the input is just an intermediate value free it now. */ if (intermediate_value) { bfuncs->free_record(dcr->after_rec); } dcr->after_rec = nrec; retval = true; bail_out: return retval; } /* * Inflate (uncompress) the content of a read record and return the data as an alternative datastream. */ static bool auto_inflate_record(bpContext *ctx, DCR *dcr) { DEV_RECORD *rec, *nrec; bool retval = false; struct plugin_ctx *p_ctx; bool intermediate_value = false; p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { goto bail_out; } /* * See what our starting point is. When dcr->after_rec is set we already have * a translated record by an other SD plugin. Then we use that translated record * as the starting point otherwise we start at dcr->before_rec. When an earlier * translation already happened we can free that record when we have a success * full translation here as that record is of no use anymore. */ if (dcr->after_rec) { rec = dcr->after_rec; intermediate_value = true; } else { rec = dcr->before_rec; } /* * We only do auto inflation for the following stream types: * * - STREAM_COMPRESSED_DATA * - STREAM_WIN32_COMPRESSED_DATA * - STREAM_SPARSE_COMPRESSED_DATA */ switch (rec->maskedStream) { case STREAM_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: break; default: goto bail_out; } /* * Clone the data from the original DEV_RECORD to the converted one. * As we use the compression buffers for the data we need a new * DEV_RECORD without a new memory buffer so we call new_record here * with the with_data boolean set explicitly to false. */ nrec = bfuncs->new_record(false); bfuncs->copy_record_state(nrec, rec); /* * Setup the converted record to point to the original data. * The decompress_data function will decompress that data and * then update the pointers with the data in the compression buffer * and with the length of the decompressed data. */ nrec->data = rec->data; nrec->data_len = rec->data_len; if (!decompress_data(dcr->jcr, "Unknown", rec->maskedStream, &nrec->data, &nrec->data_len, true)) { bfuncs->free_record(nrec); goto bail_out; } /* * If we succeeded in decompressing the data update the stream type. */ switch (rec->maskedStream) { case STREAM_COMPRESSED_DATA: nrec->Stream = STREAM_FILE_DATA; nrec->maskedStream = STREAM_FILE_DATA; break; case STREAM_WIN32_COMPRESSED_DATA: nrec->Stream = STREAM_WIN32_DATA; nrec->maskedStream = STREAM_WIN32_DATA; break; case STREAM_SPARSE_COMPRESSED_DATA: nrec->Stream = STREAM_SPARSE_DATA; nrec->maskedStream = STREAM_SPARSE_DATA; break; default: break; } Dmsg(ctx, 400, "auto_inflate_record: From datastream %d to %d from original size %ld to %ld\n", rec->maskedStream, nrec->maskedStream, rec->data_len, nrec->data_len); p_ctx->inflate_bytes_in += rec->data_len; p_ctx->inflate_bytes_out += nrec->data_len; /* * If the input is just an intermediate value free it now. */ if (intermediate_value) { bfuncs->free_record(dcr->after_rec); } dcr->after_rec = nrec; retval = true; bail_out: return retval; } bareos-Release-14.2.6/src/plugins/stored/bareos-sd.py.template000066400000000000000000000045441263011562700242620ustar00rootroot00000000000000# BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Marco van Wieringen # from bareossd import * from bareos_sd_consts import * def load_bareos_plugin(context, plugindef): DebugMessage(context, 100, "load_bareos_plugin called with param: " + plugindef + "\n"); events = []; events.append(bsdEventType['bsdEventJobStart']); events.append(bsdEventType['bsdEventJobEnd']); RegisterEvents(context, events); return bRCs['bRC_OK']; def parse_plugin_definition(context, plugindef): DebugMessage(context, 100, "parse_plugin_definition called with param: " + plugindef + "\n"); plugin_options = plugindef.split(":"); for current_option in plugin_options: key,sep,val = current_option.partition("="); if val == '': continue; elif key == 'instance': continue; elif key == 'module_path': continue; elif key == 'module_name': continue; else: DebugMessage(context, 100, "parse_plugin_definition unknown option " + key + " with value " + val + "\n"); return bRCs['bRC_Error']; return bRCs['bRC_OK']; def handle_plugin_event(context, event): if event == bsdEventType['bsdEventJobStart']: DebugMessage(context, 100, "bsdEventJobStart event triggered\n"); jobname = GetValue(context, bsdrVariable['bsdVarJobName']); DebugMessage(context, 100, "Job " + jobname + " starting\n"); elif event == bsdEventType['bsdEventJobEnd']: DebugMessage(context, 100, "bsdEventJobEnd event triggered\n"); jobname = GetValue(context, bsdrVariable['bsdVarJobName']); DebugMessage(context, 100, "Job " + jobname + " stopped\n"); return bRCs['bRC_OK']; bareos-Release-14.2.6/src/plugins/stored/bareos_sd_consts.py000066400000000000000000000050061263011562700241150ustar00rootroot00000000000000# BAREOS - Backup Archiving REcovery Open Sourced # # Copyright (C) 2013-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation, which is # listed in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # Author: Marco van Wieringen # bJobMessageType = dict( M_ABORT = 1, M_DEBUG = 2, M_FATAL = 3, M_ERROR = 4, M_WARNING = 5, M_INFO = 6, M_SAVED = 7, M_NOTSAVED = 8, M_SKIPPED = 9, M_MOUNT = 10, M_ERROR_TERM = 11, M_TERM = 12, M_RESTORED = 13, M_SECURITY = 14, M_ALERT = 15, M_VOLMGMT = 16 ) bsdrVariable = dict( bsdVarJob = 1, bsdVarLevel = 2, bsdVarType = 3, bsdVarJobId = 4, bsdVarClient = 5, bsdVarPool = 6, bsdVarPoolType = 7, bsdVarStorage = 8, bsdVarMediaType = 9, bsdVarJobName = 10, bsdVarJobStatus = 11, bsdVarVolumeName = 12, bsdVarJobErrors = 13, bsdVarJobFiles = 14, bsdVarJobBytes = 15, bsdVarCompatible = 16, bsdVarPluginDir = 17 ) bsdwVariable = dict( bsdwVarJobReport = 1, bsdwVarVolumeName = 2, bsdwVarPriority = 3, bsdwVarJobLevel = 4 ) bRCs = dict( bRC_OK = 0, bRC_Stop = 1, bRC_Error = 2, bRC_More = 3, bRC_Term = 4, bRC_Seen = 5, bRC_Core = 6, bRC_Skip = 7, bRC_Cancel = 8 ) bsdEventType = dict( bsdEventJobStart = 1, bsdEventJobEnd = 2, bsdEventDeviceInit = 3, bsdEventDeviceMount = 4, bsdEventVolumeLoad = 5, bsdEventDeviceTryOpen = 6, bsdEventDeviceOpen = 7, bsdEventLabelRead = 8, bsdEventLabelVerified = 9, bsdEventLabelWrite = 10, bsdEventDeviceClose = 11, bsdEventVolumeUnload = 12, bsdEventDeviceUnmount = 13, bsdEventReadError = 14, bsdEventWriteError = 15, bsdEventDriveStatus = 16, bsdEventVolumeStatus = 17, bsdEventSetupRecordTranslation = 18, bsdEventReadRecordTranslation = 19, bsdEventWriteRecordTranslation = 20, bsdEventNewPluginOptions = 21 ) bareos-Release-14.2.6/src/plugins/stored/example-plugin-sd.c000066400000000000000000000120711263011562700237100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Sample Storage daemon Plugin program * * Kern Sibbald, October 2007 * */ #include "bareos.h" #include "stored.h" #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Kern Sibbald" #define PLUGIN_DATE "November 2011" #define PLUGIN_VERSION "2" #define PLUGIN_DESCRIPTION "Test Storage Daemon Plugin" /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); /* Pointers to Bareos functions */ static bsdFuncs *bfuncs = NULL; static bsdInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION, SD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION }; static psdFuncs pluginFuncs = { sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bsdInfo *lbinfo, bsdFuncs *lbfuncs, genpInfo **pinfo, psdFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; printf("example-plugin-sd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ printf("example-plugin-sd: Loaded\n"); return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { printf("example-plugin-sd: Unloaded\n"); return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. */ /* * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); printf("example-plugin-sd: newPlugin JobId=%d\n", JobId); bfuncs->registerBareosEvents(ctx, 2, bsdEventJobStart, bsdEventJobEnd); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); printf("example-plugin-sd: freePlugin JobId=%d\n", JobId); return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value) { printf("example-plugin-sd: getPluginValue var=%d\n", var); return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value) { printf("example-plugin-sd: setPluginValue var=%d\n", var); return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { char *name; switch (event->eventType) { case bsdEventJobStart: printf("example-plugin-sd: HandleEvent JobStart :%s:\n", (char *)value); break; case bsdEventJobEnd: printf("example-plugin-sd: HandleEvent JobEnd\n"); break; } bfuncs->getBareosValue(ctx, bsdVarJobName, (void *)&name); printf("Job Name=%s\n", name); bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, "JobMesssage message"); bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message"); return bRC_OK; } bareos-Release-14.2.6/src/plugins/stored/python-sd.c000066400000000000000000000650201263011562700223040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Python Storage daemon Plugin program * * Marco van Wieringen, August 2012 */ #include "bareos.h" #include "stored.h" #undef _POSIX_C_SOURCE #include #if (PY_VERSION_HEX < 0x02060000) #error "Need at least Python version 2.6 or newer" #endif static const int dbglvl = 150; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Marco van Wieringen" #define PLUGIN_DATE "October 2013" #define PLUGIN_VERSION "3" #define PLUGIN_DESCRIPTION "Python Storage Daemon Plugin" #define PLUGIN_USAGE "python:instance=:module_path=:module_name=" #define Dmsg(context, level, ...) bfuncs->DebugMessage(context, __FILE__, __LINE__, level, __VA_ARGS__ ) #define Jmsg(context, type, ...) bfuncs->JobMessage(context, __FILE__, __LINE__, type, 0, __VA_ARGS__ ) /* Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); static bRC parse_plugin_definition(bpContext *ctx, void *value); static void PyErrorHandler(bpContext *ctx, int msgtype); static bRC PyLoadModule(bpContext *ctx, void *value); static bRC PyParsePluginDefinition(bpContext *ctx, void *value); static bRC PyGetPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC PySetPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC PyHandlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); /* Pointers to Bareos functions */ static bsdFuncs *bfuncs = NULL; static bsdInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION, SD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; static psdFuncs pluginFuncs = { sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; /* * Plugin private context */ struct plugin_ctx { PyThreadState *interpreter; int64_t instance; bool python_loaded; char *module_path; char *module_name; PyObject *pModule; PyObject *pDict; PyObject *bpContext; }; #include "python-sd.h" /* * We don't actually use this but we need it to tear down the * final python interpreter on unload of the plugin. Each instance of * the plugin get its own interpreter. */ static PyThreadState *mainThreadState; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bsdInfo *lbinfo, bsdFuncs *lbfuncs, genpInfo **pinfo, psdFuncs **pfuncs) { bfuncs = lbfuncs; /* Set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* Return pointer to our info */ *pfuncs = &pluginFuncs; /* Return pointer to our functions */ /* * Setup Python */ Py_InitializeEx(0); PyEval_InitThreads(); mainThreadState = PyEval_SaveThread(); return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { /* * Terminate Python */ PyEval_RestoreThread(mainThreadState); Py_Finalize(); return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. */ /* * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { struct plugin_ctx *p_ctx; p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(struct plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ /* * For each plugin instance we instantiate a new Python interpreter. */ PyEval_AcquireLock(); p_ctx->interpreter = Py_NewInterpreter(); PyEval_ReleaseThread(p_ctx->interpreter); /* * Always register some events the python plugin itself can register * any other events it is interested in. */ bfuncs->registerBareosEvents(ctx, 1, bsdEventNewPluginOptions); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } /* * Stop any sub interpreter started per plugin instance. */ PyEval_AcquireThread(p_ctx->interpreter); /* * Do python cleanup calls. */ if (p_ctx->bpContext) { Py_DECREF(p_ctx->bpContext); } if (p_ctx->pModule) { Py_DECREF(p_ctx->pModule); } Py_EndInterpreter(p_ctx->interpreter); PyEval_ReleaseLock(); free(p_ctx); ctx->pContext = NULL; return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; PyEval_AcquireThread(p_ctx->interpreter); retval = PyGetPluginValue(ctx, var, value); PyEval_ReleaseThread(p_ctx->interpreter); return retval; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value) { struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; PyEval_AcquireThread(p_ctx->interpreter); retval = PySetPluginValue(ctx, var, value); PyEval_ReleaseThread(p_ctx->interpreter); return retval; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { bool event_dispatched = false; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; bRC retval = bRC_Error; if (!p_ctx) { goto bail_out; } /* * First handle some events internally before calling python if it * want to do some special handling on the event triggered. */ switch (event->eventType) { case bsdEventNewPluginOptions: event_dispatched = true; retval = parse_plugin_definition(ctx, value); break; default: break; } /* * See if we have been triggered in the previous switch if not we have to * always dispatch the event. If we already processed the event internally * we only do a dispatch to the python entry point when that internal processing * was successfull (e.g. retval == bRC_OK). */ if (!event_dispatched || retval == bRC_OK) { PyEval_AcquireThread(p_ctx->interpreter); /* * Now dispatch the event to Python. * First the calls that need special handling. */ switch (event->eventType) { case bsdEventNewPluginOptions: /* * See if we already loaded the Python modules. */ if (!p_ctx->python_loaded) { retval = PyLoadModule(ctx, value); } /* * Only try to call when the loading succeeded. */ if (retval == bRC_OK) { retval = PyParsePluginDefinition(ctx, value); } break; default: /* * Handle the generic events e.g. the ones which are just passed on. * We only try to call Python when we loaded the right module until * that time we pretend the call succeeded. */ if (p_ctx->python_loaded) { retval = PyHandlePluginEvent(ctx, event, value); } else { retval = bRC_OK; } break; } PyEval_ReleaseThread(p_ctx->interpreter); } bail_out: return retval; } /* * Strip any backslashes in the string. */ static inline void strip_back_slashes(char *value) { char *bp; bp = value; while (*bp) { switch (*bp) { case '\\': bstrinlinecpy(bp, bp + 1); break; default: break; } bp++; } } /* * Parse a integer value. */ static inline int64_t parse_integer(const char *argument_value) { return str_to_int64(argument_value); } /* * Parse a boolean value e.g. check if its yes or true anything else translates to false. */ static inline bool parse_boolean(const char *argument_value) { if (bstrcasecmp(argument_value, "yes") || bstrcasecmp(argument_value, "true")) { return true; } else { return false; } } /* * Always set destination to value and clean any previous one. */ static inline void set_string(char **destination, char *value) { if (*destination) { free(*destination); } *destination = bstrdup(value); strip_back_slashes(*destination); } /* * Parse the plugin definition passed in. * * The definition is in this form: * * python:module_path=:module_name=:... */ static bRC parse_plugin_definition(bpContext *ctx, void *value) { int i; char *plugin_definition, *bp, *argument, *argument_value; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!value) { return bRC_Error; } /* * Parse the plugin definition. * Make a private copy of the whole string. */ plugin_definition = bstrdup((char *)value); bp = strchr(plugin_definition, ':'); if (!bp) { Jmsg(ctx, M_FATAL, "Illegal plugin definition %s\n", plugin_definition); Dmsg(ctx, dbglvl, "Illegal plugin definition %s\n", plugin_definition); goto bail_out; } /* * Skip the first ':' */ bp++; while (bp) { if (strlen(bp) == 0) { break; } /* * Each argument is in the form: * = * * So we setup the right pointers here, argument to the beginning * of the argument, argument_value to the beginning of the argument_value. */ argument = bp; argument_value = strchr(bp, '='); if (!argument_value) { Jmsg(ctx, M_FATAL, "Illegal argument %s without value\n", argument); Dmsg(ctx, dbglvl, "Illegal argument %s without value\n", argument); goto bail_out; } *argument_value++ = '\0'; /* * See if there are more arguments and setup for the next run. */ bp = argument_value; do { bp = strchr(bp, ':'); if (bp) { if (*(bp - 1) != '\\') { *bp++ = '\0'; break; } else { bp++; } } } while (bp); for (i = 0; plugin_arguments[i].name; i++) { if (bstrcasecmp(argument, plugin_arguments[i].name)) { int64_t *int_destination = NULL; char **str_destination = NULL; bool *bool_destination = NULL; switch (plugin_arguments[i].type) { case argument_instance: int_destination = &p_ctx->instance; break; case argument_module_path: str_destination = &p_ctx->module_path; break; case argument_module_name: str_destination = &p_ctx->module_name; break; default: break; } if (int_destination) { *int_destination = parse_integer(argument_value); } if (str_destination) { set_string(str_destination, argument_value); } if (bool_destination) { *bool_destination = parse_boolean(argument_value); } /* * When we have a match break the loop. */ break; } } } free(plugin_definition); return bRC_OK; bail_out: free(plugin_definition); return bRC_Error; } /* * Work around API changes in Python versions. * These function abstract the storage and retrieval of the bpContext * which is passed to the Python methods and which the method can pass * back and which allow the callback function to understand what bpContext * its talking about. */ #if ((PY_VERSION_HEX < 0x02070000) || \ ((PY_VERSION_HEX >= 0x03000000) && \ (PY_VERSION_HEX < 0x03010000))) /* * Python version before 2.7 and 3.0. */ static PyObject *PyCreatebpContext(bpContext *ctx) { /* * Setup a new CObject which holds the bpContext structure used here internally. */ return PyCObject_FromVoidPtr((void *)ctx, NULL); } static bpContext *PyGetbpContext(PyObject *pyCtx) { return (bpContext *)PyCObject_AsVoidPtr(pyCtx); } #else /* * Python version after 2.6 and 3.1. */ static PyObject *PyCreatebpContext(bpContext *ctx) { /* * Setup a new Capsule which holds the bpContext structure used here internally. */ return PyCapsule_New((void *)ctx, "bareos.bpContext", NULL); } static bpContext *PyGetbpContext(PyObject *pyCtx) { return (bpContext *)PyCapsule_GetPointer(pyCtx, "bareos.bpContext"); } #endif /* * Convert a return value into a bRC enum value. */ static inline bRC conv_python_retval(PyObject *pRetVal) { int retval; retval = PyInt_AsLong(pRetVal); return (bRC)retval; } /* * Handle a Python error. * * Python equivalent: * * import traceback, sys * return "".join(traceback.format_exception(sys.exc_type, * sys.exc_value, sys.exc_traceback)) */ static void PyErrorHandler(bpContext *ctx, int msgtype) { PyObject *type, *value, *traceback; PyObject *tracebackModule; char *error_string; PyErr_Fetch(&type, &value, &traceback); tracebackModule = PyImport_ImportModule("traceback"); if (tracebackModule != NULL) { PyObject *tbList, *emptyString, *strRetval; tbList = PyObject_CallMethod(tracebackModule, (char *)"format_exception", (char *)"OOO", type, value == NULL ? Py_None : value, traceback == NULL ? Py_None : traceback); emptyString = PyString_FromString(""); strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList); error_string = bstrdup(PyString_AsString(strRetval)); Py_DECREF(tbList); Py_DECREF(emptyString); Py_DECREF(strRetval); Py_DECREF(tracebackModule); } else { error_string = bstrdup("Unable to import traceback module."); } Py_DECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); Dmsg(ctx, dbglvl, "%s\n", error_string); if (msgtype) { Jmsg(ctx, msgtype, "%s\n", error_string); } free(error_string); } /* * Initial load of the Python module. * * Based on the parsed plugin options we set some prerequisits like the * module path and the module to load. We also load the dictionary used * for looking up the Python methods. */ static bRC PyLoadModule(bpContext *ctx, void *value) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *sysPath, *mPath, *pName, *pFunc, *module; /* * Extend the Python search path with the given module_path. */ if (p_ctx->module_path) { sysPath = PySys_GetObject((char *)"path"); mPath = PyString_FromString(p_ctx->module_path); PyList_Append(sysPath, mPath); Py_DECREF(mPath); } /* * Make our callback methods available for Python. */ module = Py_InitModule("bareossd", BareosSDMethods); /* * Try to load the Python module by name. */ if (p_ctx->module_name) { Dmsg(ctx, dbglvl, "Trying to load module with name %s\n", p_ctx->module_name); pName = PyString_FromString(p_ctx->module_name); p_ctx->pModule = PyImport_Import(pName); Py_DECREF(pName); if (!p_ctx->pModule) { Dmsg(ctx, dbglvl, "Failed to load module with name %s\n", p_ctx->module_name); goto bail_out; } Dmsg(ctx, dbglvl, "Sucessfully loaded module with name %s\n", p_ctx->module_name); /* * Get the Python dictionary for lookups in the Python namespace. */ p_ctx->pDict = PyModule_GetDict(p_ctx->pModule); /* Borrowed reference */ /* * Encode the bpContext so a Python method can pass it in on calling back. */ p_ctx->bpContext = PyCreatebpContext(ctx); /* * Lookup the load_bareos_plugin() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "load_bareos_plugin"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pPluginDefinition, *pRetVal; pPluginDefinition = PyString_FromString((char *)value); if (!pPluginDefinition) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pPluginDefinition, NULL); Py_DECREF(pPluginDefinition); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named load_bareos_plugins()\n"); goto bail_out; } } /* * Keep track we successfully loaded. */ p_ctx->python_loaded = true; return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Any plugin options which are passed in are dispatched here to a Python method and it * can parse the plugin options. This function is also called after PyLoadModule() has * loaded the Python module and made sure things are operational. */ static bRC PyParsePluginDefinition(bpContext *ctx, void *value) { bRC retval = bRC_Error; struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the parse_plugin_definition() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "parse_plugin_definition"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pPluginDefinition, *pRetVal; pPluginDefinition = PyString_FromString((char *)value); if (!pPluginDefinition) { goto bail_out; } pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pPluginDefinition, NULL); Py_DECREF(pPluginDefinition); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } return retval; } else { Dmsg(ctx, dbglvl, "Failed to find function named parse_plugin_definition()\n"); return bRC_Error; } bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } static bRC PyGetPluginValue(bpContext *ctx, psdVariable var, void *value) { return bRC_OK; } static bRC PySetPluginValue(bpContext *ctx, psdVariable var, void *value) { return bRC_OK; } static bRC PyHandlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { bRC retval = bRC_Error; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; PyObject *pFunc; /* * Lookup the handle_plugin_event() function in the python module. */ pFunc = PyDict_GetItemString(p_ctx->pDict, "handle_plugin_event"); /* Borrowed reference */ if (pFunc && PyCallable_Check(pFunc)) { PyObject *pEventType, *pRetVal; pEventType = PyInt_FromLong(event->eventType); pRetVal = PyObject_CallFunctionObjArgs(pFunc, p_ctx->bpContext, pEventType, NULL); Py_DECREF(pEventType); if (!pRetVal) { goto bail_out; } else { retval = conv_python_retval(pRetVal); Py_DECREF(pRetVal); } } else { Dmsg(ctx, dbglvl, "Failed to find function named handle_plugin_event()\n"); } return retval; bail_out: if (PyErr_Occurred()) { PyErrorHandler(ctx, M_FATAL); } return retval; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to get certain internal values of the current Job. */ static PyObject *PyBareosGetValue(PyObject *self, PyObject *args) { int var; bpContext *ctx = NULL; PyObject *pyCtx; PyObject *pRetVal = NULL; if (!PyArg_ParseTuple(args, "Oi:BareosGetValue", &pyCtx, &var)) { return NULL; } switch (var) { case bsdVarJobId: case bsdVarLevel: case bsdVarType: case bsdVarJobStatus: { int value; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (bsdrVariable)var, &value) == bRC_OK) { pRetVal = PyInt_FromLong(value); } break; } case bsdVarJobErrors: case bsdVarJobFiles: case bsdVarJobBytes: { uint64_t value = 0; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (bsdrVariable)var, &value) == bRC_OK) { pRetVal = PyLong_FromUnsignedLong(value); } break; } case bsdVarJobName: case bsdVarJob: case bsdVarClient: case bsdVarPool: case bsdVarPoolType: case bsdVarStorage: case bsdVarMediaType: case bsdVarVolumeName: { char *value; ctx = PyGetbpContext(pyCtx); if (bfuncs->getBareosValue(ctx, (bsdrVariable)var, &value) == bRC_OK) { pRetVal = PyString_FromString(value); } break; } case bsdVarCompatible: { bool value; if (bfuncs->getBareosValue(NULL, (bsdrVariable)var, &value) == bRC_OK) { long bool_value; bool_value = (value) ? 1 : 0; pRetVal = PyBool_FromLong(bool_value); } break; } case bsdVarPluginDir: { char *value; if (bfuncs->getBareosValue(NULL, (bsdrVariable)var, &value) == bRC_OK) { pRetVal = PyString_FromString(value); } break; } default: ctx = PyGetbpContext(pyCtx); Dmsg(ctx, dbglvl, "PyBareosGetValue: Unknown variable requested %d\n", var); break; } if (!pRetVal) { Py_INCREF(Py_None); pRetVal = Py_None; } return pRetVal; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to get certain internal values of the current Job. */ static PyObject *PyBareosSetValue(PyObject *self, PyObject *args) { int var; bpContext *ctx = NULL; PyObject *pyCtx, *pyValue; if (!PyArg_ParseTuple(args, "OiO:BareosSetValue", &pyCtx, &var, &pyValue)) { return NULL; } switch (var) { case bsdwVarVolumeName: { char *value; ctx = PyGetbpContext(pyCtx); value = PyString_AsString(pyValue); if (value) { bfuncs->setBareosValue(ctx, (bsdwVariable)var, value); } break; } case bsdwVarPriority: case bsdwVarJobLevel: { int value; ctx = PyGetbpContext(pyCtx); value = PyInt_AsLong(pyValue); if (value >= 0) { bfuncs->setBareosValue(ctx, (bsdwVariable)var, &value); } break; } default: ctx = PyGetbpContext(pyCtx); Dmsg(ctx, dbglvl, "PyBareosSetValue: Unknown variable requested %d\n", var); break; } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue debug messages using the Bareos debug message facility. */ static PyObject *PyBareosDebugMessage(PyObject *self, PyObject *args) { int level; char *dbgmsg = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "Oi|z:BareosDebugMessage", &pyCtx, &level, &dbgmsg)) { return NULL; } if (dbgmsg) { ctx = PyGetbpContext(pyCtx); Dmsg(ctx, level, dbgmsg); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue Job messages using the Bareos Job message facility. */ static PyObject *PyBareosJobMessage(PyObject *self, PyObject *args) { int type; char *jobmsg = NULL; bpContext *ctx; PyObject *pyCtx; if (!PyArg_ParseTuple(args, "Oi|z:BareosJobMessage", &pyCtx, &type, &jobmsg)) { return NULL; } if (jobmsg) { ctx = PyGetbpContext(pyCtx); Jmsg(ctx, type, jobmsg); } Py_INCREF(Py_None); return Py_None; } /* * Callback function which is exposed as a part of the additional methods which allow * a Python plugin to issue a Register Event to register additional events it wants * to receive. */ static PyObject *PyBareosRegisterEvents(PyObject *self, PyObject *args) { int len, event; bpContext *ctx; PyObject *pyCtx, *pyEvents, *pySeq, *pyEvent; if (!PyArg_ParseTuple(args, "OO:BareosRegisterEvents", &pyCtx, &pyEvents)) { return NULL; } pySeq = PySequence_Fast(pyEvents, "Expected a sequence of events"); if (!pySeq) { return NULL; } len = PySequence_Fast_GET_SIZE(pySeq); ctx = PyGetbpContext(pyCtx); for (int i = 0; i < len; i++) { pyEvent = PySequence_Fast_GET_ITEM(pySeq, i); event = PyInt_AsLong(pyEvent); if (event >= bsdEventJobStart && event <= bsdEventWriteRecordTranslation) { Dmsg(ctx, dbglvl, "PyBareosRegisterEvents: registering event %d\n", event); bfuncs->registerBareosEvents(ctx, 1, event); } } Py_DECREF(pySeq); Py_INCREF(Py_None); return Py_None; } bareos-Release-14.2.6/src/plugins/stored/python-sd.h000066400000000000000000000043731263011562700223150ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This defines the Python types in C++ and the callbacks from Python we support. */ #ifndef BPYTHONSD_H #define BPYTHONSD_H 1 /* * This defines the arguments that the plugin parser understands. */ enum plugin_argument_type { argument_none, argument_instance, argument_module_path, argument_module_name }; struct plugin_argument { const char *name; enum plugin_argument_type type; }; static plugin_argument plugin_arguments[] = { { "instance", argument_instance }, { "module_path", argument_module_path }, { "module_name", argument_module_name }, { NULL, argument_none } }; /* * Callback methods from Python. */ static PyObject *PyBareosGetValue(PyObject *self, PyObject *args); static PyObject *PyBareosSetValue(PyObject *self, PyObject *args); static PyObject *PyBareosDebugMessage(PyObject *self, PyObject *args); static PyObject *PyBareosJobMessage(PyObject *self, PyObject *args); static PyObject *PyBareosRegisterEvents(PyObject *self, PyObject *args); static PyMethodDef BareosSDMethods[] = { { "GetValue", PyBareosGetValue, METH_VARARGS, "Get a Plugin value" }, { "SetValue", PyBareosSetValue, METH_VARARGS, "Set a Plugin value" }, { "DebugMessage", PyBareosDebugMessage, METH_VARARGS, "Print a Debug message" }, { "JobMessage", PyBareosJobMessage, METH_VARARGS, "Print a Job message" }, { "RegisterEvents", PyBareosRegisterEvents, METH_VARARGS, "Register Plugin Events" }, { NULL, NULL, 0, NULL } }; #endif /* BPYTHONSD_H */ bareos-Release-14.2.6/src/plugins/stored/scsicrypto-sd.c000066400000000000000000000434041263011562700231670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * SCSI Encryption Storage daemon Plugin * * LTO4 and LTO5 drives and other modern tape drives * support hardware encryption. * * There are several ways of using encryption with these drives * The following types of key management are available for * doing encryption: * * - Transmission of the keys to the tapes is typically accomplished * by using a backup application that supports Application Managed * Encryption (AME) * - Transmission of the keys to the tapes is typically accomplished * by using a tape library that supports Library Managed Encryption (LME) * - Transmission of the keys to the tapes is typically accomplished * by using a Key Management Appliance (KMA). * * This plugin implements an Application Managed Encryption scheme where * on labeling a crypto key is generated for a volume and when the volume * is mounted the crypto key is loaded and when unloaded the key is cleared * from the memory of the Tape Drive using the SCSI SPOUT command set. * * If you have implemented Library Managed Encryption (LME) or * a Key Management Appliance (KMA) there is no need to have support * from Bareos on loading and clearing the encryption keys as either * the Library knows the per volume encryption keys itself or it * will ask the KMA for the encryption key when it needs it. For * big installations you might consider using a KMA but the Application * Managed Encryption implemented in Bareos should also scale rather * well and has low overhead as the keys are only loaded and cleared * when needed. * * This plugin uses the lowlevel SCSI key loading implemented in the * libbareos shared library. * * Marco van Wieringen, March 2012 */ #include "bareos.h" #include "stored.h" #include "lib/status.h" #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Marco van Wieringen" #define PLUGIN_DATE "March 2012" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "SCSI Encryption Storage Daemon Plugin" #define PLUGIN_USAGE "(No usage yet)" /* * Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); static bRC do_set_scsi_encryption_key(void *value); static bRC do_clear_scsi_encryption_key(void *value); static bRC handle_read_error(void *value); static bRC send_device_encryption_status(void *value); static bRC send_volume_encryption_status(void *value); /* * Pointers to Bareos functions */ static bsdFuncs *bfuncs = NULL; static bsdInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION, SD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; static psdFuncs pluginFuncs = { sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION, /* * Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; static int const dbglvl = 200; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load the plugin */ bRC DLL_IMP_EXP loadPlugin(bsdInfo *lbinfo, bsdFuncs *lbfuncs, genpInfo **pinfo, psdFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; Dmsg2(dbglvl, "scsicrypto-sd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. * * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); Dmsg1(dbglvl, "scsicrypto-sd: newPlugin JobId=%d\n", JobId); /* * Only register plugin events we are interested in. * * bsdEventLabelRead - Read of volume label clear key as volume * labels are unencrypted (as we are in mixed * decryption mode we could leave the current * encryption key but most likely its the key * from an previous volume and most of the times * it will be cleared already by the * bsdEventVolumeUnload event already.) * bsdEventLabelVerified - Label of volume is verified and found * to be OK, any next data read from the * volume will be backup data and most * likely encrypted so load the volume * specific encryption key. * bsdEventLabelWrite - Write of volume label clear key as volume * labels are unencrypted. * bsdEventVolumeUnload - Unload of volume clear key * bsdEventReadError - Read error on volume see if its due to * the fact encryption is enabled and we * have either the wrong key loaded or no key * at all. * bsdEventDriveStatus - plugin callback for encryption status * of the drive. * bsdEventVolumeStatus - plugin callback for encryption status * of the volume loaded in the drive. */ bfuncs->registerBareosEvents(ctx, 7, bsdEventLabelRead, bsdEventLabelVerified, bsdEventLabelWrite, bsdEventVolumeUnload, bsdEventReadError, bsdEventDriveStatus, bsdEventVolumeStatus); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); Dmsg1(dbglvl, "scsicrypto-sd: freePlugin JobId=%d\n", JobId); return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value) { Dmsg1(dbglvl, "scsicrypto-sd: getPluginValue var=%d\n", var); return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value) { Dmsg1(dbglvl, "scsicrypto-sd: setPluginValue var=%d\n", var); return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { switch (event->eventType) { case bsdEventLabelRead: case bsdEventLabelWrite: case bsdEventVolumeUnload: return do_clear_scsi_encryption_key(value); case bsdEventLabelVerified: return do_set_scsi_encryption_key(value); case bsdEventReadError: return handle_read_error(value); case bsdEventDriveStatus: return send_device_encryption_status(value); case bsdEventVolumeStatus: return send_volume_encryption_status(value); default: Dmsg1(dbglvl, "scsicrypto-sd: Unknown event %d\n", event->eventType); return bRC_Error; } return bRC_OK; } static pthread_mutex_t crypto_operation_mutex = PTHREAD_MUTEX_INITIALIZER; static inline bool get_volume_encryption_key(DCR *dcr, char *VolEncrKey) { /* * See if we have valid VolCatInfo. */ if (dcr->haveVolCatInfo()) { bstrncpy(VolEncrKey, dcr->VolCatInfo.VolEncrKey, MAX_NAME_LENGTH); return true; } else if (dcr->jcr && dcr->jcr->dir_bsock) { /* * No valid VolCatInfo but we can get the info as we have * a connection to the director. */ if (bfuncs->UpdateVolumeInfo(dcr)) { bstrncpy(VolEncrKey, dcr->VolCatInfo.VolEncrKey, MAX_NAME_LENGTH); return true; } } else { /* * No valid VolCatInfo and we have no connection to the director. * Try to get the encryption key from the cache. The cached_key * is string dupped in the LookupCryptoKey function so we need to * free it here. */ char *cached_key; if ((cached_key = bfuncs->LookupCryptoKey(dcr->VolumeName))) { bstrncpy(VolEncrKey, cached_key, MAX_NAME_LENGTH); free(cached_key); return true; } } return false; } static bRC do_set_scsi_encryption_key(void *value) { DCR *dcr; DEVICE *dev; DEVRES *device; DIRRES *director; char StoredVolEncrKey[MAX_NAME_LENGTH]; char VolEncrKey[MAX_NAME_LENGTH]; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { Dmsg0(dbglvl, "scsicrypto-sd: Error: dcr is not set!\n"); return bRC_Error; } dev = dcr->dev; if (!dev) { Dmsg0(dbglvl, "scsicrypto-sd: Error: dev is not set!\n"); return bRC_Error; } device = dev->device; if (!device) { Dmsg0(dbglvl, "scsicrypto-sd: Error: device is not set!\n"); return bRC_Error; } /* * See if device supports hardware encryption. */ if (!device->drive_crypto_enabled) { return bRC_OK; } *StoredVolEncrKey = '\0'; if (!get_volume_encryption_key(dcr, StoredVolEncrKey)) { Dmsg0(dbglvl, "scsicrypto-sd: Could not get_volume_encryption_key!\n"); /* * Check if encryption key is needed for reading this volume. */ P(crypto_operation_mutex); if (!need_scsi_crypto_key(dev->fd(), dev->dev_name, true)) { V(crypto_operation_mutex); Dmsg0(dbglvl, "scsicrypto-sd: No encryption key needed!\n"); return bRC_OK; } V(crypto_operation_mutex); return bRC_Error; } /* * See if a volume encryption key is available. */ if (!*StoredVolEncrKey) { Dmsg0(dbglvl, "scsicrypto-sd: No encryption key to load on device\n"); return bRC_OK; } /* * The key passed from the director to the storage daemon is always base64 encoded. */ base64_to_bin(VolEncrKey, sizeof(VolEncrKey), StoredVolEncrKey, strlen(StoredVolEncrKey)); /* * See if we have an key encryption key in the config then the passed key * has been wrapped using RFC3394 key wrapping. We first copy the current * wrapped key into a temporary variable for unwrapping. */ if (dcr->jcr && dcr->jcr->director) { director = dcr->jcr->director; if (director->keyencrkey.value) { char WrappedVolEncrKey[MAX_NAME_LENGTH]; memcpy(WrappedVolEncrKey, VolEncrKey, MAX_NAME_LENGTH); memset(VolEncrKey, 0, MAX_NAME_LENGTH); if (aes_unwrap((unsigned char *)director->keyencrkey.value, DEFAULT_PASSPHRASE_LENGTH / 8, (unsigned char *)WrappedVolEncrKey, (unsigned char *)VolEncrKey) != 0) { Dmsg1(dbglvl, "scsicrypto-sd: Failed to unwrap encryption key using %s\n", director->keyencrkey.value); Emsg0(M_ERROR, 0, _("scsicrypto-sd: Failed to unwrap encryption key, probably wrong KeyEncryptionKey in config\n")); return bRC_Error; } } } Dmsg1(dbglvl, "scsicrypto-sd: Loading new crypto key %s\n", VolEncrKey); P(crypto_operation_mutex); if (set_scsi_encryption_key(dev->fd(), dev->dev_name, VolEncrKey)) { dev->set_crypto_enabled(); V(crypto_operation_mutex); return bRC_OK; } else { V(crypto_operation_mutex); return bRC_Error; } } static bRC do_clear_scsi_encryption_key(void *value) { DCR *dcr; DEVICE *dev; DEVRES *device; bool need_to_clear; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { Dmsg0(dbglvl, "scsicrypto-sd: Error: dcr is not set!\n"); return bRC_Error; } dev = dcr->dev; if (!dev) { Dmsg0(dbglvl, "scsicrypto-sd: Error: dev is not set!\n"); return bRC_Error; } device = dev->device; if (!device) { Dmsg0(dbglvl, "scsicrypto-sd: Error: device is not set!\n"); return bRC_Error; } /* * See if device supports hardware encryption. */ if (!device->drive_crypto_enabled) { return bRC_OK; } P(crypto_operation_mutex); /* * See if we need to query the drive or use the tracked encryption status of the stored. */ if (device->query_crypto_status) { need_to_clear = is_scsi_encryption_enabled(dev->fd(), dev->dev_name); } else { need_to_clear = dev->is_crypto_enabled(); } if (need_to_clear) { Dmsg0(dbglvl, "scsicrypto-sd: Clearing crypto key\n"); if (clear_scsi_encryption_key(dev->fd(), dev->dev_name)) { dev->clear_crypto_enabled(); V(crypto_operation_mutex); return bRC_OK; } else { V(crypto_operation_mutex); return bRC_Error; } } else { Dmsg0(dbglvl, "scsicrypto-sd: Not clearing crypto key because encryption is currently not enabled on drive\n"); V(crypto_operation_mutex); return bRC_OK; } } static bRC handle_read_error(void *value) { DCR *dcr; DEVICE *dev; DEVRES *device; bool decryption_needed; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { return bRC_Error; } dev = dcr->dev; if (!dev) { return bRC_Error; } device = dev->device; if (!device) { return bRC_Error; } /* * See if drive crypto is enabled. */ if (device->drive_crypto_enabled) { /* * See if the read error is an EIO which can be returned when we try to read an * encrypted block from a volume without decryption enabled or without a proper * encryption key loaded. */ switch (dev->dev_errno) { case EIO: /* * See if we need to query the drive or use the tracked encryption status of the stored. * When we can query the drive we look at the next block encryption state to see if * we need decryption of the data on the volume. */ if (device->query_crypto_status) { P(crypto_operation_mutex); if (need_scsi_crypto_key(dev->fd(), dev->dev_name, false)) { decryption_needed = true; } else { decryption_needed = false; } V(crypto_operation_mutex); } else { decryption_needed = dev->is_crypto_enabled(); } /* * Alter the error message so it known this error is most likely due to a * failed decryption of the encrypted data on the volume. */ if (decryption_needed) { berrno be; be.set_errno(dev->dev_errno); Mmsg5(dev->errmsg, _("Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n" "Probably due to reading encrypted data from volume\n"), dev->fd(), dev->file, dev->block_num, dev->print_name(), be.bstrerror()); } break; default: break; } } return bRC_OK; } static bRC send_device_encryption_status(void *value) { bsdDevStatTrig *dst; /* * Unpack the arguments passed in. */ dst = (bsdDevStatTrig *)value; if (!dst) { return bRC_Error; } /* * See if drive crypto is enabled. */ if (dst->device->drive_crypto_enabled) { P(crypto_operation_mutex); dst->status_length = get_scsi_drive_encryption_status(dst->device->dev->fd(), dst->device->dev->dev_name, dst->status, 4); V(crypto_operation_mutex); } return bRC_OK; } static bRC send_volume_encryption_status(void *value) { bsdDevStatTrig *dst; /* * Unpack the arguments passed in. */ dst = (bsdDevStatTrig *)value; if (!dst) { return bRC_Error; } /* * See if drive crypto is enabled. */ if (dst->device->drive_crypto_enabled) { P(crypto_operation_mutex); dst->status_length = get_scsi_volume_encryption_status(dst->device->dev->fd(), dst->device->dev->dev_name, dst->status, 4); V(crypto_operation_mutex); } return bRC_OK; } bareos-Release-14.2.6/src/plugins/stored/scsitapealert-sd.c000066400000000000000000000146361263011562700236350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * SCSI Tape Alert Storage daemon Plugin * * Marco van Wieringen, November 2013 */ #include "bareos.h" #include "stored.h" #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Marco van Wieringen" #define PLUGIN_DATE "November 2013" #define PLUGIN_VERSION "1" #define PLUGIN_DESCRIPTION "SCSI Tape Alert Storage Daemon Plugin" #define PLUGIN_USAGE "(No usage yet)" /* * Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value); static bRC handle_tapealert_readout(void *value); /* * Pointers to Bareos functions */ static bsdFuncs *bfuncs = NULL; static bsdInfo *binfo = NULL; static genpInfo pluginInfo = { sizeof(pluginInfo), SD_PLUGIN_INTERFACE_VERSION, SD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; static psdFuncs pluginFuncs = { sizeof(pluginFuncs), SD_PLUGIN_INTERFACE_VERSION, /* * Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent }; static int const dbglvl = 200; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are * exported, so Bareos can directly call these two entry points * they are common to all Bareos plugins. * * External entry point called by Bareos to "load the plugin */ bRC DLL_IMP_EXP loadPlugin(bsdInfo *lbinfo, bsdFuncs *lbfuncs, genpInfo **pinfo, psdFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; Dmsg2(dbglvl, "scsitapealert-sd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function * pointers we supplied to Bareos. Each plugin type (dir, fd, sd) * has its own set of entry points that the plugin must define. * * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); Dmsg1(dbglvl, "scsitapealert-sd: newPlugin JobId=%d\n", JobId); /* * Only register plugin events we are interested in. */ bfuncs->registerBareosEvents(ctx, 6, bsdEventVolumeLoad, bsdEventLabelVerified, bsdEventReadError, bsdEventWriteError, bsdEventVolumeUnload, bsdEventDeviceReleased); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { int JobId = 0; bfuncs->getBareosValue(ctx, bsdVarJobId, (void *)&JobId); Dmsg1(dbglvl, "scsitapealert-sd: freePlugin JobId=%d\n", JobId); return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, psdVariable var, void *value) { Dmsg1(dbglvl, "scsitapealert-sd: getPluginValue var=%d\n", var); return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, psdVariable var, void *value) { Dmsg1(dbglvl, "scsitapealert-sd: setPluginValue var=%d\n", var); return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bsdEvent *event, void *value) { switch (event->eventType) { case bsdEventLabelVerified: case bsdEventReadError: case bsdEventWriteError: case bsdEventVolumeUnload: return handle_tapealert_readout(value); default: Dmsg1(dbglvl, "scsitapealert-sd: Unknown event %d\n", event->eventType); return bRC_Error; } return bRC_OK; } static pthread_mutex_t tapealert_operation_mutex = PTHREAD_MUTEX_INITIALIZER; static bRC handle_tapealert_readout(void *value) { DCR *dcr; DEVICE *dev; DEVRES *device; uint64_t flags; /* * Unpack the arguments passed in. */ dcr = (DCR *)value; if (!dcr) { return bRC_Error; } dev = dcr->dev; if (!dev) { return bRC_Error; } device = dev->device; if (!device) { return bRC_Error; } /* * See if drive tapealert is enabled. */ if (!device->drive_tapealert_enabled) { Dmsg1(dbglvl, "scsitapealert-sd: tapealert is not enabled on device %s\n", dev->dev_name); return bRC_OK; } Dmsg1(dbglvl, "scsitapealert-sd: checking for tapealerts on device %s\n", dev->dev_name); P(tapealert_operation_mutex); get_tapealert_flags(dev->fd(), dev->dev_name, &flags); V(tapealert_operation_mutex); Dmsg1(dbglvl, "scsitapealert-sd: checking for tapealerts on device %s DONE\n", dev->dev_name); Dmsg1(dbglvl, "scsitapealert-sd: flags: %ld \n", flags); if (flags) { Dmsg1(dbglvl, "scsitapealert-sd: tapealerts on device %s, calling UpdateTapeAlerts\n", dev->dev_name); bfuncs->UpdateTapeAlert(dcr, flags); } return bRC_OK; } bareos-Release-14.2.6/src/qt-console/000077500000000000000000000000001263011562700173135ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/README000066400000000000000000000107241263011562700201770ustar00rootroot00000000000000 This directory contains the Bareos Admin Tool (bat). At the current time, the contents of this directory are under development. If you want to help, please contact Kern directly. If you want to build it, you need Qt4 loaded and setup as your default Qt or with the appropriate Qt Environment variables set. 6/24/07 There is now one dependency, it is qwt. It compiles just fine with either qwt-5.0.2 or qwt-5.0.1. You can either install the qwt package yourself or if your distro does not have it, we have included the source in depkgs-qt, which you can download from the Bareos Source Forge download area. Building and running bat is done much like bconsole, the gnome console, or the wxWidgets console. You add the appropriate options to your ./configure, then simply do a make. Please see the Installation chapter of the manual for more details. Win32 mingw infos for QT4 : - http://silmor.de/29 - http://doc.qtfr.org/post/2007/04/10/Cross-Compilation-Native-dapplication-Qt-depuis-Linux Development status as of 05/06/07 Items not implemented: - Nothing on the brestore page Translations: - All translatable strings should be written as tr("string") ... - To extract the strings for translation run: lupdate bat.pro - To translate the strings, do: linguist ts/bat_xx.ts where xx is the country code (e.g. fr or de) - To "compile" the translated strings do: lrelease bat.pro The necessary binary files will be in ts/bat_xx.qm As far as I can tell, these files must be on your path or in the same directory as bat for them to be used, otherwise it reverts to English. Selecting the translation is based on how your system is setup or the LANG environment variable. Design decisions: - If possible all code for a particular component will be kept in an appropriate subdirectory. - All private class variables are named "m_xxx" this makes it very clear if one is referencing a class variable or a local. - All signal/slots are connected by explicit code (most all are done in the MainWin constructor), rather than using designer. - Each page has a separate designer .ui file in a subdirectory. - All windows are created with designer and have a name such as xxxForm i.e. the main window is MainForm and kept in main.ui. Major projects: - Implement other restore interfaces such as brestore ... - Implement a database browser - Implement a resource (conf file) browser - Implement a reports page -- e.g. something similar to bweb - Implement Qt plugins to add new functionality to bat - Implement a GUI configuration file editor (something like JBareos). ... Partially Done: =========================== - Implement graphical commands that allow updating most aspects of the database (i.e. commands for label, update Volume, ...) still need to be able to edit a pool object - None of the menu items except About, Select Font, and Quit. Print and save don't do anything, does save need to?? Done: ============================ Design/implementation considerations: - Need icons in front of the Director. - The console page should be in a DockWidget so it can be removed from the main window. It is currently in a dock window, but it does not remove properly -- more research needed. - Need to figure out a good implementation of adding pages and even having plugins that load as pages. Currently the page mechanism is a bit kludged. - We need to have multiple Directors - Each Director should have its own console - The Console class needs to be a list or be attached to the currently active Director. - Will automatically connect to the first Director in the conf file. Doesn't know about multiple Directors. - The Label menu bar item, prints on the shell window what you entered. - The Run menu bar item, prints on the console window what you entered. - The Restore menu bar item, brings up dialog, then when OK is clicked, it goes on to the next dialog, which is meant to be a tree view, but for the moment does nothing ... It is a bit ugly. Canceling it should get you back to the normal command prompt. - Implement a restore page that does a directory tree restore selection much like wx-console does. Not working: - The left selection window and the right window (where the console is) are dockable windows so should be movable once they are properly clicked. Well, they sort of move, but then get stuck. I haven't figured out what is going on, so for the current time, I am implementing most stuff through dialogs. Items implemented: See RELEASEFEATURES bareos-Release-14.2.6/src/qt-console/bat.conf.in000066400000000000000000000002541263011562700213360ustar00rootroot00000000000000# # Bareos Administration Tool (bat) configuration file # Director { Name = @basename@-dir DIRport = @dir_port@ address = @hostname@ Password = "@dir_password@" } bareos-Release-14.2.6/src/qt-console/bat.desktop.in000066400000000000000000000004061263011562700220610ustar00rootroot00000000000000[Desktop Entry] Name=Bareos Administration Tool GenericName=Backup Administration Tool Icon=bat TryExec=@bindir@/bat Exec=@bindir@/bat -c @sysconfdir@/bat.conf Terminal=false Type=Application StartupNotify=true Categories=System;Utility;Archiving;X-SuSE-Backup; bareos-Release-14.2.6/src/qt-console/bat.h000066400000000000000000000025221263011562700202330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January 2007 */ #ifndef _BAT_H_ #define _BAT_H_ #if defined(HAVE_WIN32) #if !defined(_STAT_H) #define _STAT_H /* don't pull in MinGW stat.h */ #define _STAT_DEFINED /* don't pull in MinGW stat.h */ #endif #endif #include "hostconfig.h" #include #include #include "bareos.h" #include "mainwin.h" #include "bat_conf.h" #include "jcr.h" #include "console/console.h" extern MainWin *mainWin; extern QApplication *app; bool isWin32Path(QString &fullPath); #endif /* _BAT_H_ */ bareos-Release-14.2.6/src/qt-console/bat.pro.in000066400000000000000000000106251263011562700212140ustar00rootroot00000000000000###################################################################### # # !!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # Edit only bat.pro.in -- bat.pro is built by the ./configure program # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # CONFIG += qt CONFIG -= debug_and_release CONFIG( debug, debug|release ) { CONFIG -= release } else { CONFIG -= debug CONFIG += release } bins.path = /$(DESTDIR)@bindir@ bins.files = bat confs.path = /$(DESTDIR)@sysconfdir@ confs.commands = ./install_conf_file help.path = /$(DESTDIR)@htmldir@/bat help.files = help/*.html ../images/status.png ../images/mail-message-new.png icons.path = /$(DESTDIR)@datarootdir@/pixmaps/ icons.files = ../images/bat.png ../images/bat.svg desktopentries.path = /$(DESTDIR)@datarootdir@/applications/ desktopentries.files = bat.desktop TEMPLATE = app TARGET = bat DEPENDPATH += . INCLUDEPATH += .. ../include . QMAKE_LIBDIR += ../lib LIBS += -lbareoscfg -lbareos LIBTOOL_LINK = @QMAKE_LIBTOOL@ --silent --tag=CXX --mode=link LIBTOOL_INSTALL = @QMAKE_LIBTOOL@ --silent --mode=install QMAKE_LINK = $${LIBTOOL_LINK} $(CXX) QMAKE_INSTALL_PROGRAM = $${LIBTOOL_INSTALL} install -m @SBINPERM@ -p QMAKE_CLEAN += .libs/* bat macx { ICON = ../images/bat.icns } RESOURCES = main.qrc MOC_DIR = moc OBJECTS_DIR = obj UI_DIR = ui # Main window FORMS += main.ui FORMS += prefs.ui FORMS += label/label.ui FORMS += relabel/relabel.ui FORMS += mount/mount.ui FORMS += console/console.ui FORMS += restore/restore.ui restore/prerestore.ui restore/brestore.ui FORMS += restore/runrestore.ui FORMS += restore/restoretree.ui FORMS += run/run.ui run/runcmd.ui run/estimate.ui run/prune.ui FORMS += select/select.ui select/textinput.ui FORMS += medialist/medialist.ui mediaedit/mediaedit.ui joblist/joblist.ui FORMS += medialist/mediaview.ui FORMS += clients/clients.ui storage/storage.ui fileset/fileset.ui FORMS += joblog/joblog.ui jobs/jobs.ui job/job.ui FORMS += help/help.ui mediainfo/mediainfo.ui FORMS += status/dirstat.ui storage/content.ui FORMS += status/clientstat.ui FORMS += status/storstat.ui # Main directory HEADERS += mainwin.h bat.h bat_conf.h qstd.h pages.h SOURCES += main.cpp bat_conf.cpp mainwin.cpp qstd.cpp pages.cpp # bcomm HEADERS += bcomm/dircomm.h SOURCES += bcomm/dircomm.cpp # Console HEADERS += console/console.h SOURCES += console/console.cpp # Restore HEADERS += restore/restore.h SOURCES += restore/prerestore.cpp restore/restore.cpp restore/brestore.cpp # Label dialog HEADERS += label/label.h SOURCES += label/label.cpp # Relabel dialog HEADERS += relabel/relabel.h SOURCES += relabel/relabel.cpp # Mount dialog HEADERS += mount/mount.h SOURCES += mount/mount.cpp # Run dialog HEADERS += run/run.h SOURCES += run/run.cpp run/runcmd.cpp run/estimate.cpp run/prune.cpp # Select dialog HEADERS += select/select.h select/textinput.h SOURCES += select/select.cpp select/textinput.cpp ## MediaList HEADERS += medialist/medialist.h SOURCES += medialist/medialist.cpp # MediaView HEADERS += medialist/mediaview.h SOURCES += medialist/mediaview.cpp ## MediaEdit HEADERS += mediaedit/mediaedit.h SOURCES += mediaedit/mediaedit.cpp ## JobList HEADERS += joblist/joblist.h SOURCES += joblist/joblist.cpp ## Clients HEADERS += clients/clients.h SOURCES += clients/clients.cpp ## Storage HEADERS += storage/storage.h SOURCES += storage/storage.cpp ## Storage content HEADERS += storage/content.h SOURCES += storage/content.cpp ## Fileset HEADERS += fileset/fileset.h SOURCES += fileset/fileset.cpp ## Job log HEADERS += joblog/joblog.h SOURCES += joblog/joblog.cpp ## Job HEADERS += job/job.h SOURCES += job/job.cpp ## Jobs HEADERS += jobs/jobs.h SOURCES += jobs/jobs.cpp ## RestoreTree HEADERS += restore/restoretree.h SOURCES += restore/restoretree.cpp # Help dialog HEADERS += help/help.h SOURCES += help/help.cpp # Media info dialog HEADERS += mediainfo/mediainfo.h SOURCES += mediainfo/mediainfo.cpp ## Status Dir HEADERS += status/dirstat.h SOURCES += status/dirstat.cpp ## Status Client HEADERS += status/clientstat.h SOURCES += status/clientstat.cpp ## Status Client HEADERS += status/storstat.h SOURCES += status/storstat.cpp # Utility sources HEADERS += util/fmtwidgetitem.h util/comboutil.h SOURCES += util/fmtwidgetitem.cpp util/comboutil.cpp INSTALLS = bins confs help icons desktopentries QMAKE_EXTRA_TARGETS += depend TRANSLATIONS += ts/bat_fr.ts ts/bat_de.ts bareos-Release-14.2.6/src/qt-console/bat_conf.cpp000066400000000000000000000271331263011562700216000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main configuration file parser for Bareos User Agent * some parts may be split into separate files such as * the schedule configuration (sch_config.c). * * Note, the configuration file parser consists of three parts * * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and * lib/parse_config.h. These files contain the parser code, * some utility routines, and the common store routines * (name, int, string). * * 3. The daemon specific file, which contains the Resource * definitions as well as any specific store routines * for the resource records. * * Kern Sibbald, January MM, September MM */ #include "bareos.h" #include "bat_conf.h" /* * Define the first and last resource ID record * types. Note, these should be unique for each * daemon though not a requirement. */ static RES *sres_head[R_LAST - R_FIRST + 1]; static RES **res_head = sres_head; /* Forward referenced subroutines */ /* * We build the current resource here as we are * scanning the resource configuration definition, * then move it to allocated memory when the resource * scan is complete. */ #if defined(_MSC_VER) extern "C" URES res_all; /* declare as C to avoid name mangling by visual c */ #endif URES res_all; int32_t res_all_size = sizeof(res_all); /* * Definition of records permitted within each * resource with the routine to process the record * information. */ static RES_ITEM dir_items[] = { { "name", CFG_TYPE_NAME, ITEM(dir_res.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(dir_res.hdr.desc), 0, 0, NULL }, { "dirport", CFG_TYPE_PINT32, ITEM(dir_res.DIRport), 0, CFG_ITEM_DEFAULT, DIR_DEFAULT_PORT }, { "address", CFG_TYPE_STR, ITEM(dir_res.address), 0, CFG_ITEM_REQUIRED, NULL }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(dir_res.password), 0, CFG_ITEM_REQUIRED, NULL }, { "tlsauthenticate",CFG_TYPE_BOOL, ITEM(dir_res.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(dir_res.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(dir_res.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(dir_res.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(dir_res.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(dir_res.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(dir_res.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(dir_res.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(dir_res.tls_keyfile), 0, 0, NULL }, { "heartbeatinterval", CFG_TYPE_TIME, ITEM(dir_res.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { NULL, 0, { 0 }, 0, 0, NULL } }; static RES_ITEM con_items[] = { { "name", CFG_TYPE_NAME, ITEM(con_res.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(con_res.hdr.desc), 0, 0, NULL }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(con_res.password), 0, CFG_ITEM_REQUIRED, NULL }, { "tlsauthenticate",CFG_TYPE_BOOL, ITEM(con_res.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(con_res.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(con_res.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(con_res.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(con_res.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(con_res.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(con_res.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(con_res.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(con_res.tls_keyfile), 0, 0, NULL }, { "heartbeatinterval", CFG_TYPE_TIME, ITEM(con_res.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { NULL, 0, { 0 }, 0, 0, NULL } }; static RES_ITEM con_font_items[] = { { "name", CFG_TYPE_NAME, ITEM(con_font.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(con_font.hdr.desc), 0, 0, NULL }, { "font", CFG_TYPE_STR, ITEM(con_font.fontface), 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * This is the master resource definition. * It must have one item for each of the resources. */ static RES_TABLE resources[] = { { "director", dir_items, R_DIRECTOR, sizeof(DIRRES) }, { "console", con_items, R_CONSOLE, sizeof(CONRES) }, { "consolefont", con_font_items, R_CONSOLE_FONT, sizeof(CONFONTRES) }, { NULL, NULL, 0, 0 } }; /* * Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { URES *res = (URES *)reshdr; bool recurse = true; if (res == NULL) { printf(_("No record for %d %s\n"), type, res_to_str(type)); return; } if (type < 0) { /* no recursion */ type = - type; recurse = false; } switch (type) { case R_DIRECTOR: printf(_("Director: name=%s address=%s DIRport=%d\n"), reshdr->name, res->dir_res.address, res->dir_res.DIRport); break; case R_CONSOLE: printf(_("Console: name=%s\n"), reshdr->name); break; case R_CONSOLE_FONT: printf(_("ConsoleFont: name=%s font face=%s\n"), reshdr->name, NPRT(res->con_font.fontface)); break; default: printf(_("Unknown resource type %d\n"), type); } if (recurse && res->dir_res.hdr.next) { dump_resource(type, res->dir_res.hdr.next, sendit, sock, hide_sensitive_data); } } /* * Free memory of resource. * NB, we don't need to worry about freeing any references * to other resources as they will be freed when that * resource chain is traversed. Mainly we worry about freeing * allocated strings (names). */ void free_resource(RES *sres, int type) { RES *nres; URES *res = (URES *)sres; if (res == NULL) return; /* * Common stuff -- free the resource name */ nres = (RES *)res->dir_res.hdr.next; if (res->dir_res.hdr.name) { free(res->dir_res.hdr.name); } if (res->dir_res.hdr.desc) { free(res->dir_res.hdr.desc); } switch (type) { case R_DIRECTOR: if (res->dir_res.address) { free(res->dir_res.address); } if (res->dir_res.tls_ctx) { free_tls_context(res->dir_res.tls_ctx); } if (res->dir_res.tls_ca_certfile) { free(res->dir_res.tls_ca_certfile); } if (res->dir_res.tls_ca_certdir) { free(res->dir_res.tls_ca_certdir); } if (res->dir_res.tls_crlfile) { free(res->dir_res.tls_crlfile); } if (res->dir_res.tls_certfile) { free(res->dir_res.tls_certfile); } if (res->dir_res.tls_keyfile) { free(res->dir_res.tls_keyfile); } break; case R_CONSOLE: if (res->con_res.password.value) { free(res->con_res.password.value); } if (res->con_res.tls_ctx) { free_tls_context(res->con_res.tls_ctx); } if (res->con_res.tls_ca_certfile) { free(res->con_res.tls_ca_certfile); } if (res->con_res.tls_ca_certdir) { free(res->con_res.tls_ca_certdir); } if (res->con_res.tls_crlfile) { free(res->con_res.tls_crlfile); } if (res->con_res.tls_certfile) { free(res->con_res.tls_certfile); } if (res->con_res.tls_keyfile) { free(res->con_res.tls_keyfile); } break; case R_CONSOLE_FONT: if (res->con_font.fontface) { free(res->con_font.fontface); } break; default: printf(_("Unknown resource type %d\n"), type); } /* * Common stuff again -- free the resource, recurse to next one */ free(res); if (nres) { free_resource(nres, type); } } /* * Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * pointers (currently only in the Job resource). */ void save_resource(int type, RES_ITEM *items, int pass) { URES *res; int rindex = type - R_FIRST; int i; int error = 0; /* * Ensure that all required items are present */ for (i=0; items[i].name; i++) { if (items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, res_all.dir_res.hdr.item_present)) { Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"), items[i].name, resources[rindex]); } } } /* * During pass 2, we looked up pointers to all the resources * referrenced in the current resource, , now we * must copy their address from the static record to the allocated * record. */ if (pass == 2) { switch (type) { /* * Resources not containing a resource */ case R_DIRECTOR: break; case R_CONSOLE: case R_CONSOLE_FONT: break; default: Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type); error = 1; break; } /* * Note, the resoure name was already saved during pass 1, * so here, we can just release it. */ if (res_all.dir_res.hdr.name) { free(res_all.dir_res.hdr.name); res_all.dir_res.hdr.name = NULL; } if (res_all.dir_res.hdr.desc) { free(res_all.dir_res.hdr.desc); res_all.dir_res.hdr.desc = NULL; } return; } /* * Common */ if (!error) { res = (URES *)malloc(resources[rindex].size); memcpy(res, &res_all, resources[rindex].size); if (!res_head[rindex]) { res_head[rindex] = (RES *)res; /* store first entry */ } else { RES *next, *last; /* * Add new res to end of chain */ for (last=next=res_head[rindex]; next; next=next->next) { last = next; if (strcmp(next->name, res->dir_res.hdr.name) == 0) { Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), resources[rindex].name, res->dir_res.hdr.name); } } last->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), res->dir_res.hdr.name); } } } bool parse_bat_config(CONFIG *config, const char *configfile, int exit_code) { config->init(configfile, NULL, NULL, NULL, NULL, NULL, exit_code, (void *)&res_all, res_all_size, R_FIRST, R_LAST, resources, res_head); return config->parse_config(); } bareos-Release-14.2.6/src/qt-console/bat_conf.h000066400000000000000000000074341263011562700212470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos Adminstration Tool (bat) * * Kern Sibbald, March 2002 */ #ifndef _BAT_CONF_H_ #define _BAT_CONF_H_ /* * Resource codes -- they must be sequential for indexing */ enum { R_DIRECTOR = 1001, R_CONSOLE, R_CONSOLE_FONT, R_FIRST = R_DIRECTOR, R_LAST = R_CONSOLE_FONT /* Keep this updated */ }; /* * Some resource attributes */ enum { R_NAME = 1020, R_ADDRESS, R_PASSWORD, R_TYPE, R_BACKUP }; /* Definition of the contents of each Resource */ class DIRRES { public: RES hdr; uint32_t DIRport; /* UA server port */ char *address; /* UA server address */ s_password password; /* UA server password */ bool tls_authenticate; /* Authenticate with tls */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ utime_t heartbeat_interval; /* Dir heartbeat interval */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ /* Methods */ char *name() const; }; inline char *DIRRES::name() const { return hdr.name; } struct CONFONTRES { RES hdr; char *fontface; /* Console Font specification */ }; class CONRES { public: RES hdr; s_password password; /* UA server password */ bool tls_authenticate; /* Authenticate with tls */ bool tls_enable; /* Enable TLS on all connections */ bool tls_require; /* Require TLS on all connections */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ utime_t heartbeat_interval; /* Cons heartbeat interval */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ /* Methods */ char *name() const; }; inline char *CONRES::name() const { return hdr.name; } /* Define the Union of all the above * resource structure definitions. */ union u_res { DIRRES dir_res; CONRES con_res; CONFONTRES con_font; RES hdr; }; typedef union u_res URES; #define GetConsoleResWithName(x) ((CONRES *)GetResWithName(R_CONSOLE, (x))) #define GetDirResWithName(x) ((DIRRES *)GetResWithName(R_DIRECTOR, (x))) #endif /* _BAT_CONF_H_ */ bareos-Release-14.2.6/src/qt-console/bcomm/000077500000000000000000000000001263011562700204105ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/bcomm/dircomm.cpp000066400000000000000000000436471263011562700225640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * DirComm, Director communications,class * * Kern Sibbald, January MMVII */ #include "bat.h" #include "restore/restore.h" #include "select/select.h" #include "select/textinput.h" #include "run/run.h" static int tls_pem_callback(char *buf, int size, const void *userdata); DirComm::DirComm(Console *parent, int conn): m_notifier(NULL), m_api_set(false) { m_console = parent; m_sock = NULL; m_at_prompt = false; m_at_main_prompt = false; m_sent_blank = false; m_conn = conn; m_in_command = 0; m_in_select = false; m_notify = false; } DirComm::~DirComm() { } /* Terminate any open socket */ void DirComm::terminate() { if (m_sock) { if (m_notifier) { m_notifier->setEnabled(false); delete m_notifier; m_notifier = NULL; m_notify = false; } if (mainWin->m_connDebug) Pmsg2(000, "DirComm %i terminating connections %s\n", m_conn, m_console->m_dir->name()); m_sock->close(); delete m_sock; m_sock = NULL; } } /* * Connect to Director. */ bool DirComm::connect_dir() { JCR *jcr = new JCR; utime_t heart_beat; char buf[1024]; CONRES *cons; buf[0] = 0; if (m_sock) { mainWin->set_status( tr("Already connected.")); m_console->display_textf(_("Already connected\"%s\".\n"), m_console->m_dir->name()); if (mainWin->m_connDebug) { Pmsg2(000, "DirComm %i BAILING already connected %s\n", m_conn, m_console->m_dir->name()); } goto bail_out; } if (mainWin->m_connDebug)Pmsg2(000, "DirComm %i connecting %s\n", m_conn, m_console->m_dir->name()); memset(jcr, 0, sizeof(JCR)); mainWin->set_statusf(_("Connecting to Director %s:%d"), m_console->m_dir->address, m_console->m_dir->DIRport); if (m_conn == 0) { m_console->display_textf(_("Connecting to Director %s:%d\n\n"), m_console->m_dir->address, m_console->m_dir->DIRport); } /* Give GUI a chance */ app->processEvents(); LockRes(); /* If cons==NULL, default console will be used */ cons = (CONRES *)GetNextRes(R_CONSOLE, NULL); UnlockRes(); /* Initialize Console TLS context once */ if (cons && !cons->tls_ctx && (cons->tls_enable || cons->tls_require)) { /* Generate passphrase prompt */ bsnprintf(buf, sizeof(buf), "Passphrase for Console \"%s\" TLS private key: ", cons->name()); /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ cons->tls_ctx = new_tls_context(cons->tls_ca_certfile, cons->tls_ca_certdir, cons->tls_crlfile, cons->tls_certfile, cons->tls_keyfile, tls_pem_callback, &buf, NULL, cons->tls_verify_peer); if (!cons->tls_ctx) { m_console->display_textf(_("Failed to initialize TLS context for Console \"%s\".\n"), m_console->m_dir->name()); if (mainWin->m_connDebug) { Pmsg2(000, "DirComm %i BAILING Failed to initialize TLS context for Console %s\n", m_conn, m_console->m_dir->name()); } goto bail_out; } set_tls_enable(cons->tls_ctx, cons->tls_enable); set_tls_require(cons->tls_ctx, cons->tls_require); } /* Initialize Director TLS context once */ if (!m_console->m_dir->tls_ctx && (m_console->m_dir->tls_enable || m_console->m_dir->tls_require)) { /* Generate passphrase prompt */ bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ", m_console->m_dir->name()); /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ m_console->m_dir->tls_ctx = new_tls_context(m_console->m_dir->tls_ca_certfile, m_console->m_dir->tls_ca_certdir, m_console->m_dir->tls_crlfile, m_console->m_dir->tls_certfile, m_console->m_dir->tls_keyfile, tls_pem_callback, &buf, NULL, m_console->m_dir->tls_verify_peer); if (!m_console->m_dir->tls_ctx) { m_console->display_textf(_("Failed to initialize TLS context for Director \"%s\".\n"), m_console->m_dir->name()); mainWin->set_status("Connection failed"); if (mainWin->m_connDebug) { Pmsg2(000, "DirComm %i BAILING Failed to initialize TLS context for Director %s\n", m_conn, m_console->m_dir->name()); } goto bail_out; } set_tls_enable(m_console->m_dir->tls_ctx, m_console->m_dir->tls_enable); set_tls_require(m_console->m_dir->tls_ctx, m_console->m_dir->tls_require); } if (m_console->m_dir->heartbeat_interval) { heart_beat = m_console->m_dir->heartbeat_interval; } else if (cons) { heart_beat = cons->heartbeat_interval; } else { heart_beat = 0; } m_sock = New(BSOCK_TCP); if (!m_sock->connect(NULL, 5, 15, heart_beat, "Director daemon", m_console->m_dir->address, NULL, m_console->m_dir->DIRport, false)) { mainWin->set_status("Connection failed"); if (mainWin->m_connDebug) { Pmsg2(000, "DirComm %i BAILING Connection failed %s\n", m_conn, m_console->m_dir->name()); } delete m_sock; m_sock = NULL; goto bail_out; } else { /* Update page selector to green to indicate that Console is connected */ mainWin->actionConnect->setIcon(QIcon(":images/connected.png")); QBrush greenBrush(Qt::green); QTreeWidgetItem *item = mainWin->getFromHash(m_console); if (item) { item->setForeground(0, greenBrush); } } jcr->dir_bsock = m_sock; if (!authenticate_with_director(jcr, m_console->m_dir, cons, buf, sizeof(buf))) { m_console->display_text(buf); if (mainWin->m_connDebug) { Pmsg2(000, "DirComm %i BAILING Connection failed %s\n", m_conn, m_console->m_dir->name()); } goto bail_out; } if (buf[0]) { m_console->display_text(buf); } /* Give GUI a chance */ app->processEvents(); mainWin->set_status(_("Initializing ...")); /* * Set up input notifier */ m_notifier = new QSocketNotifier(m_sock->m_fd, QSocketNotifier::Read, 0); QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(notify_read_dir(int))); m_notifier->setEnabled(true); m_notify = true; write(".api 1"); m_api_set = true; m_console->displayToPrompt(m_conn); m_console->beginNewCommand(m_conn); mainWin->set_status(_("Connected")); if (mainWin->m_connDebug) { Pmsg2(000, "Returning TRUE from DirComm->connect_dir : %i %s\n", m_conn, m_console->m_dir->name()); } return true; bail_out: if (mainWin->m_connDebug) { Pmsg2(000, "Returning FALSE from DirComm->connect_dir : %i %s\n", m_conn, m_console->m_dir->name()); } delete jcr; return false; } /* * This should be moved into a bSocket class */ char *DirComm::msg() { if (m_sock) { return m_sock->msg; } return NULL; } int DirComm::write(QString msg) { return write(msg.toUtf8().data()); } int DirComm::write(const char *msg) { if (!m_sock) { return -1; } m_sock->msglen = pm_strcpy(m_sock->msg, msg); m_at_prompt = false; m_at_main_prompt = false; if (mainWin->m_commDebug) Pmsg2(000, "conn %i send: %s\n", m_conn, msg); /* * Ensure we send only one blank line. Multiple blank lines are * simply discarded, it keeps the console output looking nicer. */ if (m_sock->msglen == 0 || (m_sock->msglen == 1 && *m_sock->msg == '\n')) { if (!m_sent_blank) { m_sent_blank = true; return m_sock->send(); } else { return -1; /* discard multiple blanks */ } } m_sent_blank = false; /* clear flag */ return m_sock->send(); } int DirComm::sock_read() { int stat; #ifdef HAVE_WIN32 bool wasEnabled = notify(false); stat = m_sock->recv(); notify(wasEnabled); #else stat = m_sock->recv(); #endif return stat; } /* * Blocking read from director */ int DirComm::read() { int stat = -1; if (!m_sock) { return -1; } while (m_sock) { for (;;) { if (!m_sock) break; stat = m_sock->wait_data_intr(0, 50000); if (stat > 0) { break; } app->processEvents(); if (m_api_set && m_console->is_messagesPending() && is_notify_enabled() && m_console->hasFocus()) { if (mainWin->m_commDebug) Pmsg1(000, "conn %i process_events\n", m_conn); m_console->messagesPending(false); m_console->write_dir(m_conn, ".messages", false); } } if (!m_sock) { return -1; } m_sock->msg[0] = 0; stat = sock_read(); if (stat >= 0) { if (mainWin->m_commDebug) Pmsg2(000, "conn %i got: %s\n", m_conn, m_sock->msg); if (m_at_prompt) { m_console->display_text("\n"); m_at_prompt = false; m_at_main_prompt = false; } } switch (m_sock->msglen) { case BNET_MSGS_PENDING : if (is_notify_enabled() && m_console->hasFocus()) { m_console->messagesPending(false); if (mainWin->m_commDebug) Pmsg1(000, "conn %i MSGS PENDING\n", m_conn); m_console->write_dir(m_conn, ".messages", false); m_console->displayToPrompt(m_conn); continue; } m_console->messagesPending(true); continue; case BNET_CMD_OK: if (mainWin->m_commDebug) Pmsg1(000, "conn %i CMD OK\n", m_conn); m_at_prompt = false; m_at_main_prompt = false; if (--m_in_command < 0) { m_in_command = 0; } mainWin->set_status(_("Command completed ...")); continue; case BNET_CMD_BEGIN: if (mainWin->m_commDebug) Pmsg1(000, "conn %i CMD BEGIN\n", m_conn); m_at_prompt = false; m_at_main_prompt = false; m_in_command++; mainWin->set_status(_("Processing command ...")); continue; case BNET_MAIN_PROMPT: if (mainWin->m_commDebug) Pmsg1(000, "conn %i MAIN PROMPT\n", m_conn); if (!m_at_prompt && ! m_at_main_prompt) { m_at_prompt = true; m_at_main_prompt = true; mainWin->set_status(_("At main prompt waiting for input ...")); } break; case BNET_SUB_PROMPT: if (mainWin->m_commDebug) Pmsg2(000, "conn %i SUB_PROMPT m_in_select=%d\n", m_conn, m_in_select); m_at_prompt = true; m_at_main_prompt = false; mainWin->set_status(_("At prompt waiting for input ...")); break; case BNET_TEXT_INPUT: if (mainWin->m_commDebug) Pmsg4(000, "conn %i TEXT_INPUT at_prompt=%d m_in_select=%d notify=%d\n", m_conn, m_at_prompt, m_in_select, is_notify_enabled()); //if (!m_in_select && is_notify_enabled()) { if (!m_in_select) { mainWin->waitExit(); new textInputDialog(m_console, m_conn); } else { if (mainWin->m_commDebug) Pmsg0(000, "!m_in_select && is_notify_enabled\n"); m_at_prompt = true; m_at_main_prompt = false; mainWin->set_status(_("At prompt waiting for input ...")); } break; case BNET_CMD_FAILED: if (mainWin->m_commDebug) Pmsg1(000, "CMD FAILED\n", m_conn); if (--m_in_command < 0) { m_in_command = 0; } mainWin->set_status(_("Command failed.")); break; /* We should not get this one */ case BNET_EOD: if (mainWin->m_commDebug) Pmsg1(000, "conn %i EOD\n", m_conn); mainWin->set_status_ready(); if (!m_api_set) { break; } continue; case BNET_START_SELECT: if (mainWin->m_commDebug) Pmsg1(000, "conn %i START SELECT\n", m_conn); m_in_select = true; new selectDialog(m_console, m_conn); m_in_select = false; break; case BNET_YESNO: if (mainWin->m_commDebug) Pmsg1(000, "conn %i YESNO\n", m_conn); new yesnoPopUp(m_console, m_conn); break; case BNET_RUN_CMD: if (mainWin->m_commDebug) Pmsg1(000, "conn %i RUN CMD\n", m_conn); new runCmdPage(m_conn); break; case BNET_START_RTREE: if (mainWin->m_commDebug) Pmsg1(000, "conn %i START RTREE CMD\n", m_conn); new restorePage(m_conn); break; case BNET_END_RTREE: if (mainWin->m_commDebug) Pmsg1(000, "conn %i END RTREE CMD\n", m_conn); break; case BNET_ERROR_MSG: if (mainWin->m_commDebug) Pmsg1(000, "conn %i ERROR MSG\n", m_conn); stat = sock_read(); /* get the message */ m_console->display_text(msg()); QMessageBox::critical(m_console, "Error", msg(), QMessageBox::Ok); m_console->beginNewCommand(m_conn); mainWin->waitExit(); break; case BNET_WARNING_MSG: if (mainWin->m_commDebug) Pmsg1(000, "conn %i WARNING MSG\n", m_conn); stat = sock_read(); /* get the message */ if (!m_console->m_warningPrevent) { QMessageBox::critical(m_console, "Warning", msg(), QMessageBox::Ok); } break; case BNET_INFO_MSG: if (mainWin->m_commDebug) Pmsg1(000, "conn %i INFO MSG\n", m_conn); stat = sock_read(); /* get the message */ m_console->display_text(msg()); mainWin->set_status(msg()); break; } if (!m_sock) { stat = BNET_HARDEOF; return stat; } if (is_bnet_stop(m_sock)) { /* error or term request */ if (mainWin->m_commDebug) Pmsg1(000, "conn %i BNET STOP\n", m_conn); m_console->stopTimer(); m_sock->close(); m_sock = NULL; mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); QBrush redBrush(Qt::red); QTreeWidgetItem *item = mainWin->getFromHash(m_console); item->setForeground(0, redBrush); if (m_notifier) { m_notifier->setEnabled(false); delete m_notifier; m_notifier = NULL; m_notify = false; } mainWin->set_status(_("Director disconnected.")); stat = BNET_HARDEOF; } break; } return stat; } /* Called by signal when the Director has output for us */ void DirComm::notify_read_dir(int /* fd */) { int stat; if (!mainWin->m_notify) { return; } if (mainWin->m_commDebug) Pmsg1(000, "enter read_dir conn %i read_dir\n", m_conn); stat = m_sock->wait_data(0, 5000); if (stat > 0) { if (mainWin->m_commDebug) Pmsg2(000, "read_dir conn %i stat=%d\n", m_conn, stat); while (read() >= 0) { m_console->display_text(msg()); } } if (mainWin->m_commDebug) Pmsg2(000, "exit read_dir conn %i stat=%d\n", m_conn, stat); } /* * When the notifier is enabled, read_dir() will automatically be * called by the Qt event loop when ever there is any output * from the Director, and read_dir() will then display it on * the console. * * When we are in a bat dialog, we want to control *all* output * from the Directory, so we set notify to off. * m_console->notify(false); */ bool DirComm::notify(bool enable) { bool prev_enabled = false; /* Set global flag */ mainWin->m_notify = enable; if (m_notifier) { prev_enabled = m_notifier->isEnabled(); m_notifier->setEnabled(enable); m_notify = enable; if (mainWin->m_connDebug) Pmsg3(000, "conn=%i set_notify=%d prev=%d\n", m_conn, enable, prev_enabled); } else if (mainWin->m_connDebug) { Pmsg2(000, "m_notifier does not exist: %i %s\n", m_conn, m_console->m_dir->name()); } return prev_enabled; } bool DirComm::is_notify_enabled() const { return m_notify; } /* * Call-back for reading a passphrase for an encrypted PEM file * This function uses getpass(), * which uses a static buffer and is NOT thread-safe. */ static int tls_pem_callback(char *buf, int size, const void *userdata) { (void)size; (void)userdata; #ifdef HAVE_TLS # if defined(HAVE_WIN32) //sendit(prompt); if (win32_cgets(buf, size) == NULL) { buf[0] = 0; return 0; } else { return strlen(buf); } # else const char *prompt = (const char *)userdata; char *passwd; passwd = getpass(prompt); bstrncpy(buf, passwd, size); return strlen(buf); # endif #else buf[0] = 0; return 0; #endif } bool DirComm::authenticate_with_director(JCR *jcr, DIRRES *director, CONRES *cons, char *errmsg, int errmsg_len) { const char *name; char *password; TLS_CONTEXT *tls_ctx = NULL; BSOCK *dir = jcr->dir_bsock; errmsg[0] = 0; if (cons) { ASSERT(cons->password.encoding == p_encoding_md5); name = cons->hdr.name; password = cons->password.value; tls_ctx = cons->tls_ctx; } else { ASSERT(director->password.encoding == p_encoding_md5); name = "*UserAgent*"; password = director->password.value; tls_ctx = director->tls_ctx; } return dir->authenticate_with_director(name, password, tls_ctx, errmsg, errmsg_len); } bareos-Release-14.2.6/src/qt-console/bcomm/dircomm.h000066400000000000000000000042541263011562700222200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January 2007 */ #ifndef _DIRCOMM_H_ #define _DIRCOMM_H_ #include #include "pages.h" #include "ui_console.h" #include #ifndef MAX_NAME_LENGTH #define MAX_NAME_LENGTH 128 #endif class DIRRES; class BSOCK; class JCR; class CONRES; //class DirComm : public QObject class DirComm : public QObject { Q_OBJECT friend class Console; public: DirComm(Console *parent, int conn); ~DirComm(); Console *m_console; int sock_read(); bool authenticate_with_director(JCR *jcr, DIRRES *director, CONRES *cons, char *buf, int buflen); bool is_connected() { return m_sock != NULL; }; bool is_ready() { return is_connected() && m_at_prompt && m_at_main_prompt; }; char *msg(); bool notify(bool enable); // enables/disables socket notification - returns the previous state bool is_notify_enabled() const; bool is_in_command() const { return m_in_command > 0; }; void terminate(); bool connect_dir(); int read(void); int write(const char *msg); int write(QString msg); public slots: void notify_read_dir(int fd); private: BSOCK *m_sock; bool m_at_prompt; bool m_at_main_prompt; bool m_sent_blank; bool m_notify; int m_in_command; QSocketNotifier *m_notifier; bool m_api_set; int m_conn; bool m_in_select; }; #endif /* _DIRCOMM_H_ */ bareos-Release-14.2.6/src/qt-console/clients/000077500000000000000000000000001263011562700207545ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/clients/clients.cpp000066400000000000000000000255131263011562700231270ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Clients Class * * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "clients/clients.h" #include "run/run.h" #include "status/clientstat.h" #include "util/fmtwidgetitem.h" Clients::Clients() : Pages() { setupUi(this); m_name = tr("Clients"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/network-server.png"))); /* tableWidget, Storage Tree Tree Widget inherited from ui_client.h */ m_populated = false; m_checkcurwidget = true; m_closeable = false; m_firstpopulation = true; /* add context sensitive menu items specific to this classto the page * selector tree. m_contextActions is QList of QActions */ m_contextActions.append(actionRefreshClients); createContextMenu(); } Clients::~Clients() { } /* * The main meat of the class!! The function that queries the director and * creates the widgets with appropriate values. */ void Clients::populateTable() { m_populated = true; Freeze frz(*tableWidget); /* disable updating*/ QStringList headerlist = (QStringList() << tr("Client Name") << tr("File Retention") << tr("Job Retention") << tr("AutoPrune") << tr("ClientId") << tr("Uname") ); int sortcol = headerlist.indexOf(tr("Client Name")); Qt::SortOrder sortord = Qt::AscendingOrder; if (tableWidget->rowCount()) { sortcol = tableWidget->horizontalHeader()->sortIndicatorSection(); sortord = tableWidget->horizontalHeader()->sortIndicatorOrder(); } m_checkcurwidget = false; tableWidget->clear(); m_checkcurwidget = true; tableWidget->setColumnCount(headerlist.count()); tableWidget->setHorizontalHeaderLabels(headerlist); tableWidget->horizontalHeader()->setHighlightSections(false); tableWidget->setRowCount(m_console->client_list.count()); tableWidget->verticalHeader()->hide(); tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */ bool first = true; QString client_comsep(""); foreach (QString clientName, m_console->client_list){ if (first) { client_comsep += "'" + clientName + "'"; first = false; } else client_comsep += ",'" + clientName + "'"; } if (client_comsep != "") { QString query(""); query += "SELECT Name, FileRetention, JobRetention, AutoPrune, ClientId, Uname" " FROM Client" " WHERE ClientId IN (SELECT MAX(ClientId) FROM Client WHERE"; query += " Name IN (" + client_comsep + ")"; query += " GROUP BY Name) ORDER BY Name"; QStringList results; if (mainWin->m_sqlDebug) Pmsg1(000, "Clients query cmd : %s\n",query.toUtf8().data()); if (m_console->sql_cmd(query, results)) { int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { QStringList fieldlist = resultline.split("\t"); if (m_firstpopulation) { settingsOpenStatus(fieldlist[0]); } TableItemFormatter item(*tableWidget, row); /* Iterate through fields in the record */ QStringListIterator fld(fieldlist); int col = 0; /* name */ item.setTextFld(col++, fld.next()); /* file retention */ item.setDurationFld(col++, fld.next()); /* job retention */ item.setDurationFld(col++, fld.next()); /* autoprune */ item.setBoolFld(col++, fld.next()); /* client id */ item.setNumericFld(col++, fld.next()); /* uname */ item.setTextFld(col++, fld.next()); row++; } } } /* set default sorting */ tableWidget->sortByColumn(sortcol, sortord); tableWidget->setSortingEnabled(true); /* Resize rows and columns */ tableWidget->resizeColumnsToContents(); tableWidget->resizeRowsToContents(); /* make read only */ int rcnt = tableWidget->rowCount(); int ccnt = tableWidget->columnCount(); for(int r=0; r < rcnt; r++) { for(int c=0; c < ccnt; c++) { QTableWidgetItem* item = tableWidget->item(r, c); if (item) { item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable))); } } } m_firstpopulation = false; } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void Clients::PgSeltreeWidgetClicked() { if(!m_populated) { populateTable(); } if (!isOnceDocked()) { dockPage(); } } /* * Added to set the context menu policy based on currently active treeWidgetItem * signaled by currentItemChanged */ void Clients::tableItemChanged(QTableWidgetItem *currentwidgetitem, QTableWidgetItem *previouswidgetitem ) { /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */ if (m_checkcurwidget) { int currentRow = currentwidgetitem->row(); QTableWidgetItem *currentrowzeroitem = tableWidget->item(currentRow, 0); m_currentlyselected = currentrowzeroitem->text(); /* The Previous item */ if (previouswidgetitem) { /* avoid a segfault if first time */ tableWidget->removeAction(actionListJobsofClient); tableWidget->removeAction(actionStatusClientWindow); tableWidget->removeAction(actionPurgeJobs); tableWidget->removeAction(actionPrune); } if (m_currentlyselected.length() != 0) { /* set a hold variable to the client name in case the context sensitive * menu is used */ tableWidget->addAction(actionListJobsofClient); tableWidget->addAction(actionStatusClientWindow); tableWidget->addAction(actionPurgeJobs); tableWidget->addAction(actionPrune); } } } /* * Setup a context menu * Made separate from populate so that it would not create context menu over and * over as the tree is repopulated. */ void Clients::createContextMenu() { tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu); tableWidget->addAction(actionRefreshClients); /* for the tableItemChanged to maintain m_currentJob */ connect(tableWidget, SIGNAL( currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)), this, SLOT(tableItemChanged(QTableWidgetItem *, QTableWidgetItem *))); /* connect to the action specific to this pages class */ connect(actionRefreshClients, SIGNAL(triggered()), this, SLOT(populateTable())); connect(actionListJobsofClient, SIGNAL(triggered()), this, SLOT(showJobs())); connect(actionStatusClientWindow, SIGNAL(triggered()), this, SLOT(statusClientWindow())); connect(actionPurgeJobs, SIGNAL(triggered()), this, SLOT(consolePurgeJobs())); connect(actionPrune, SIGNAL(triggered()), this, SLOT(prune())); } /* * Function responding to actionListJobsofClient which calls mainwin function * to create a window of a list of jobs of this client. */ void Clients::showJobs() { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); mainWin->createPageJobList("", m_currentlyselected, "", "", parentItem); } /* * Function responding to actionListJobsofClient which calls mainwin function * to create a window of a list of jobs of this client. */ void Clients::consoleStatusClient() { QString cmd("status client="); cmd += m_currentlyselected; consoleCommand(cmd); } /* * Virtual function which is called when this page is visible on the stack */ void Clients::currentStackItem() { if(!m_populated) { populateTable(); /* Create the context menu for the client table */ } } /* * Function responding to actionPurgeJobs */ void Clients::consolePurgeJobs() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to purge all jobs of client \"%1\" ?\n" "The Purge command will delete associated Catalog database records from Jobs and" " Volumes without considering the retention period. Purge works only on the" " Catalog database and does not affect data written to Volumes. This command can" " be dangerous because you can delete catalog records associated with current" " backups of files, and we recommend that you do not use it unless you know what" " you are doing.\n\n" " Is there any way I can get you to click Cancel here? You really don't want to do" " this\n\n" "Press OK to proceed with the purge operation?").arg(m_currentlyselected), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString cmd("purge jobs client="); cmd += m_currentlyselected; consoleCommand(cmd); } /* * Function responding to actionPrune */ void Clients::prune() { new prunePage("", m_currentlyselected); } /* * Function responding to action to create new client status window */ void Clients::statusClientWindow() { /* if one exists, then just set it current */ bool found = false; foreach(Pages *page, mainWin->m_pagehash) { if (mainWin->currentConsole() == page->console()) { if (page->name() == tr("Client Status %1").arg(m_currentlyselected)) { found = true; page->setCurrent(); } } } if (!found) { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); new ClientStat(m_currentlyselected, parentItem); } } /* * If first time, then check to see if there were status pages open the last time closed * if so open */ void Clients::settingsOpenStatus(QString &client) { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("OpenOnExit"); QString toRead = "ClientStatus_" + client; if (settings.value(toRead) == 1) { new ClientStat(client, mainWin->getFromHash(this)); setCurrent(); mainWin->getFromHash(this)->setExpanded(true); } settings.endGroup(); } bareos-Release-14.2.6/src/qt-console/clients/clients.h000066400000000000000000000031321263011562700225650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _CLIENTS_H_ #define _CLIENTS_H_ #include #include "ui_clients.h" #include class Clients : public Pages, public Ui::ClientForm { Q_OBJECT public: Clients(); ~Clients(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void tableItemChanged(QTableWidgetItem *, QTableWidgetItem *); private slots: void populateTable(); void showJobs(); void consoleStatusClient(); void statusClientWindow(); void consolePurgeJobs(); void prune(); private: void createContextMenu(); void settingsOpenStatus(QString& client); QString m_currentlyselected; bool m_populated; bool m_firstpopulation; bool m_checkcurwidget; }; #endif /* _CLIENTS_H_ */ bareos-Release-14.2.6/src/qt-console/clients/clients.ui000066400000000000000000000046531263011562700227640ustar00rootroot00000000000000 ClientForm 0 0 492 428 Client Tree :/images/view-refresh.png:/images/view-refresh.png Refresh Client List Requery the director for the list of clients. :/images/emblem-system.png:/images/emblem-system.png List Jobs of Client Open a joblist page selecting this client. :/images/weather-severe-alert.png:/images/weather-severe-alert.png Purge Jobs Purge jobs peformed from this client. :/images/edit-cut.png:/images/edit-cut.png Prune Jobs Open the diaolog to prune for this client. :/images/status.png:/images/status.png Status Client bareos-Release-14.2.6/src/qt-console/console/000077500000000000000000000000001263011562700207555ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/console/console.cpp000066400000000000000000000566721263011562700231430ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Console Class * * Kern Sibbald, January MMVII */ #include "bat.h" #include "console.h" #include "restore/restore.h" #include "select/select.h" #include "run/run.h" Console::Console(QTabWidget *parent) : Pages() { QFont font; m_name = tr("Console"); m_messages_pending = false; m_parent = parent; m_closeable = false; m_console = this; m_warningPrevent = false; m_dircommCounter = 0; /* * Create a connection to the Director and put it in a hash table */ m_dircommHash.insert(m_dircommCounter, new DirComm(this, m_dircommCounter)); setupUi(this); m_textEdit = textEdit; /* our console screen */ m_cursor = new QTextCursor(m_textEdit->document()); mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); m_timer = NULL; m_contextActions.append(actionStatusDir); m_contextActions.append(actionConsoleHelp); m_contextActions.append(actionRequestMessages); m_contextActions.append(actionConsoleReload); connect(actionStatusDir, SIGNAL(triggered()), this, SLOT(status_dir())); connect(actionConsoleHelp, SIGNAL(triggered()), this, SLOT(consoleHelp())); connect(actionConsoleReload, SIGNAL(triggered()), this, SLOT(consoleReload())); connect(actionRequestMessages, SIGNAL(triggered()), this, SLOT(messages())); } Console::~Console() { } void Console::startTimer() { m_timer = new QTimer(this); QWidget::connect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages())); m_timer->start(mainWin->m_checkMessagesInterval*30000); } void Console::stopTimer() { if (m_timer) { QWidget::disconnect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages())); m_timer->stop(); delete m_timer; m_timer = NULL; } } /* slot connected to the timer * requires preferences of check messages and operates at interval */ void Console::poll_messages() { int conn; /* Do not poll if notifier off */ if (!mainWin->m_notify) { return; } /* * Note if we call getDirComm here, we continuously consume * file descriptors. */ if (!findDirComm(conn)) { /* find a free DirComm */ return; /* try later */ } DirComm *dircomm = m_dircommHash.value(conn); if (mainWin->m_checkMessages && dircomm->m_at_main_prompt && hasFocus() && !mainWin->getWaitState()){ dircomm->write(".messages"); displayToPrompt(conn); messagesPending(false); } } /* * Connect to Director. This does not connect to the director, dircomm does. * This creates the first and possibly 2nd dircomm instance */ void Console::connect_dir() { DirComm *dircomm = m_dircommHash.value(0); if (!m_console->m_dir) { mainWin->set_status( tr("No Director found.")); return; } m_textEdit = textEdit; /* our console screen */ if (dircomm->connect_dir()) { if (mainWin->m_connDebug) { Pmsg1(000, "DirComm 0 Seems to have Connected %s\n", m_dir->name()); } beginNewCommand(0); } mainWin->set_status(_("Connected")); startTimer(); /* start message timer */ } /* * A function created to separate out the population of the lists * from the Console::connect_dir function */ void Console::populateLists(bool /*forcenew*/) { int conn; if (!getDirComm(conn)) { if (mainWin->m_connDebug) Pmsg0(000, "call newDirComm\n"); if (!newDirComm(conn)) { Emsg1(M_ABORT, 0, _("Failed to connect to director %s for populateLists." " Check, if director's address or hostname is configured properly\n"), m_dir->name()); return; } } populateLists(conn); notify(conn, true); } void Console::populateLists(int conn) { job_list.clear(); restore_list.clear(); client_list.clear(); fileset_list.clear(); messages_list.clear(); pool_list.clear(); storage_list.clear(); type_list.clear(); level_list.clear(); volstatus_list.clear(); mediatype_list.clear(); dir_cmd(conn, ".jobs", job_list); dir_cmd(conn, ".jobs type=R", restore_list); dir_cmd(conn, ".clients", client_list); dir_cmd(conn, ".filesets", fileset_list); dir_cmd(conn, ".msgs", messages_list); dir_cmd(conn, ".pools", pool_list); dir_cmd(conn, ".storage", storage_list); dir_cmd(conn, ".types", type_list); dir_cmd(conn, ".levels", level_list); dir_cmd(conn, ".volstatus", volstatus_list); dir_cmd(conn, ".mediatypes", mediatype_list); dir_cmd(conn, ".locations", location_list); if (mainWin->m_connDebug) { QString dbgmsg = QString("jobs=%1 clients=%2 filesets=%3 msgs=%4 pools=%5 storage=%6 types=%7 levels=%8 conn=%9 %10\n") .arg(job_list.count()).arg(client_list.count()).arg(fileset_list.count()).arg(messages_list.count()) .arg(pool_list.count()).arg(storage_list.count()).arg(type_list.count()).arg(level_list.count()) .arg(conn).arg(m_dir->name()); Pmsg1(000, "%s", dbgmsg.toUtf8().data()); } job_list.sort(); client_list.sort(); fileset_list.sort(); messages_list.sort(); pool_list.sort(); storage_list.sort(); type_list.sort(); level_list.sort(); } /* * Overload function for dir_cmd with a QString * Ease of use */ bool Console::dir_cmd(QString &cmd, QStringList &results) { return dir_cmd(cmd.toUtf8().data(), results); } /* * Overload function for dir_cmd, this is if connection is not worried about */ bool Console::dir_cmd(const char *cmd, QStringList &results) { int conn; if (getDirComm(conn)) { dir_cmd(conn, cmd, results); return true; } else { Pmsg1(000, "dir_cmd failed to connect to %s\n", m_dir->name()); return false; } } /* * Send a command to the Director, and return the * results in a QStringList. */ bool Console::dir_cmd(int conn, const char *cmd, QStringList &results) { mainWin->waitEnter(); DirComm *dircomm = m_dircommHash.value(conn); int stat; bool prev_notify = is_notify_enabled(conn); if (mainWin->m_connDebug) { QString dbgmsg = QString("dir_cmd conn %1 %2 %3\n").arg(conn).arg(m_dir->name()).arg(cmd); Pmsg1(000, "%s", dbgmsg.toUtf8().data()); } if (prev_notify) { notify(conn, false); } dircomm->write(cmd); while ((stat = dircomm->read()) > 0 && dircomm->is_in_command()) { if (mainWin->m_displayAll) display_text(dircomm->msg()); strip_trailing_newline(dircomm->msg()); results << dircomm->msg(); } if (stat > 0 && mainWin->m_displayAll) display_text(dircomm->msg()); if (prev_notify) { notify(conn, true); /* turn it back on */ } discardToPrompt(conn); mainWin->waitExit(); return true; /* ***FIXME*** return any command error */ } /* * OverLoads for sql_cmd */ bool Console::sql_cmd(int &conn, QString &query, QStringList &results) { return sql_cmd(conn, query.toUtf8().data(), results, false); } bool Console::sql_cmd(QString &query, QStringList &results) { int conn; if (!getDirComm(conn)) { return false; } return sql_cmd(conn, query.toUtf8().data(), results, true); } bool Console::sql_cmd(const char *query, QStringList &results) { int conn; if (!getDirComm(conn)) { return false; } return sql_cmd(conn, query, results, true); } /* * Send a sql query to the Director, and return the * results in a QStringList. */ bool Console::sql_cmd(int &conn, const char *query, QStringList &results, bool donotify) { DirComm *dircomm = m_dircommHash.value(conn); int stat; POOL_MEM cmd(PM_MESSAGE); bool prev_notify = is_notify_enabled(conn); if (!is_connectedGui()) { return false; } if (mainWin->m_connDebug) Pmsg2(000, "sql_cmd conn %i %s\n", conn, query); if (donotify) { dircomm->notify(false); } mainWin->waitEnter(); pm_strcpy(cmd, ".sql query=\""); pm_strcat(cmd, query); pm_strcat(cmd, "\""); dircomm->write(cmd.c_str()); while ((stat = dircomm->read()) > 0) { bool first = true; if (mainWin->m_displayAll) { display_text(dircomm->msg()); display_text("\n"); } strip_trailing_newline(dircomm->msg()); bool doappend = true; if (first) { QString dum = dircomm->msg(); if ((dum.left(6) == "*None*")) doappend = false; } if (doappend) { results << dircomm->msg(); } first = false; } if (donotify && prev_notify) { dircomm->notify(true); } discardToPrompt(conn); mainWin->waitExit(); if (donotify && prev_notify) { dircomm->notify(true); } return !mainWin->isClosing(); /* return false if closing */ } /* * Overloads for * Sending a command to the Director */ int Console::write_dir(const char *msg) { int conn; if (getDirComm(conn)) { write_dir(conn, msg); } return conn; } int Console::write_dir(const char *msg, bool dowait) { int conn; if (getDirComm(conn)) { write_dir(conn, msg, dowait); } return conn; } void Console::write_dir(int conn, const char *msg) { write_dir(conn, msg, true); } /* * Send a command to the Director */ void Console::write_dir(int conn, const char *msg, bool dowait) { DirComm *dircomm = m_dircommHash.value(conn); if (dircomm->m_sock) { mainWin->set_status(_("Processing command ...")); if (dowait) mainWin->waitEnter(); dircomm->write(msg); if (dowait) mainWin->waitExit(); } else { mainWin->set_status( tr(" Director not connected. Click on connect button.")); mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); QBrush redBrush(Qt::red); QTreeWidgetItem *item = mainWin->getFromHash(this); item->setForeground(0, redBrush); dircomm->m_at_prompt = false; dircomm->m_at_main_prompt = false; } } /* * get_job_defaults overload */ bool Console::get_job_defaults(struct job_defaults &job_defs) { int conn; getDirComm(conn); return get_job_defaults(conn, job_defs, true); } bool Console::get_job_defaults(int &conn, struct job_defaults &job_defs) { return get_job_defaults(conn, job_defs, true); } /* * Send a job name to the director, and read all the resulting * defaults. */ bool Console::get_job_defaults(int &conn, struct job_defaults &job_defs, bool donotify) { QString scmd; int stat; char *def; bool prev_notify = is_notify_enabled(conn); bool rtn = false; DirComm *dircomm = m_dircommHash.value(conn); if (donotify) { dircomm->notify(false); } beginNewCommand(conn); bool prevWaitState = mainWin->getWaitState(); if (!prevWaitState) mainWin->waitEnter(); if (mainWin->m_connDebug) Pmsg2(000, "job_defaults conn %i %s\n", conn, m_dir->name()); scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name); dircomm->write(scmd); while ((stat = dircomm->read()) > 0) { if (mainWin->m_displayAll) display_text(dircomm->msg()); def = strchr(dircomm->msg(), '='); if (!def) { continue; } /* Pointer to default value */ *def++ = 0; strip_trailing_newline(def); if (strcmp(dircomm->msg(), "job") == 0) { if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) { goto bail_out; } continue; } if (strcmp(dircomm->msg(), "pool") == 0) { job_defs.pool_name = def; continue; } if (strcmp(dircomm->msg(), "messages") == 0) { job_defs.messages_name = def; continue; } if (strcmp(dircomm->msg(), "client") == 0) { job_defs.client_name = def; continue; } if (strcmp(dircomm->msg(), "storage") == 0) { job_defs.store_name = def; continue; } if (strcmp(dircomm->msg(), "where") == 0) { job_defs.where = def; continue; } if (strcmp(dircomm->msg(), "level") == 0) { job_defs.level = def; continue; } if (strcmp(dircomm->msg(), "type") == 0) { job_defs.type = def; continue; } if (strcmp(dircomm->msg(), "fileset") == 0) { job_defs.fileset_name = def; continue; } if (strcmp(dircomm->msg(), "catalog") == 0) { job_defs.catalog_name = def; continue; } if (strcmp(dircomm->msg(), "enabled") == 0) { job_defs.enabled = *def == '1' ? true : false; continue; } } rtn = true; /* Fall through wanted */ bail_out: if (donotify && prev_notify) { notify(conn, true); } if (!prevWaitState) { mainWin->waitExit(); } return rtn; } /* * Save user settings associated with this console */ void Console::writeSettings() { QFont font = get_font(); QSettings settings(m_dir->name(), "bat"); settings.beginGroup("Console"); settings.setValue("consoleFont", font.family()); settings.setValue("consolePointSize", font.pointSize()); settings.setValue("consoleFixedPitch", font.fixedPitch()); settings.endGroup(); } /* * Read and restore user settings associated with this console */ void Console::readSettings() { QFont font = get_font(); QSettings settings(m_dir->name(), "bat"); settings.beginGroup("Console"); font.setFamily(settings.value("consoleFont", "Courier").value()); font.setPointSize(settings.value("consolePointSize", 10).toInt()); font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool()); settings.endGroup(); m_textEdit->setFont(font); } /* * Set the console textEdit font */ void Console::set_font() { bool ok; QFont font = QFontDialog::getFont(&ok, QFont(m_textEdit->font()), this); if (ok) { m_textEdit->setFont(font); } } /* * Get the console text edit font */ const QFont Console::get_font() { return m_textEdit->font(); } /* * Slot for responding to status dir button on button bar */ void Console::status_dir() { QString cmd("status dir"); consoleCommand(cmd); } /* * Slot for responding to messages button on button bar * Here we want to bring the console to the front so use pages' consoleCommand */ void Console::messages() { QString cmd(".messages"); consoleCommand(cmd); messagesPending(false); } /* * Put text into the console window */ void Console::display_textf(const char *fmt, ...) { va_list arg_ptr; char buf[1000]; va_start(arg_ptr, fmt); bvsnprintf(buf, sizeof(buf), fmt, arg_ptr); va_end(arg_ptr); display_text(buf); } void Console::display_text(const QString buf) { if (buf.size() != 0) { m_cursor->insertText(buf); update_cursor(); } } void Console::display_text(const char *buf) { if (*buf != 0) { m_cursor->insertText(buf); update_cursor(); } } void Console::display_html(const QString buf) { if (buf.size() != 0) { m_cursor->insertHtml(buf); update_cursor(); } } /* Position cursor to end of screen */ void Console::update_cursor() { m_textEdit->moveCursor(QTextCursor::End); m_textEdit->ensureCursorVisible(); } void Console::beginNewCommand(int conn) { DirComm *dircomm = m_dircommHash.value(conn); for (int i=0; i < 3; i++) { dircomm->write("."); while (dircomm->read() > 0) { if (mainWin->m_commDebug) Pmsg2(000, "begin new command loop %i %s\n", i, m_dir->name()); if (mainWin->m_displayAll) display_text(dircomm->msg()); } if (dircomm->m_at_main_prompt) { break; } } display_text("\n"); } void Console::displayToPrompt(int conn) { DirComm *dircomm = m_dircommHash.value(conn); int stat = 0; QString buf; if (mainWin->m_commDebug) Pmsg1(000, "DisplaytoPrompt %s\n", m_dir->name()); while (!dircomm->m_at_prompt) { if ((stat=dircomm->read()) > 0) { buf += dircomm->msg(); if (buf.size() >= 8196 || m_messages_pending) { display_text(buf); buf.clear(); messagesPending(false); } } } display_text(buf); if (mainWin->m_commDebug) Pmsg2(000, "endDisplaytoPrompt=%d %s\n", stat, m_dir->name()); } void Console::discardToPrompt(int conn) { DirComm *dircomm = m_dircommHash.value(conn); int stat = 0; if (mainWin->m_commDebug) Pmsg1(000, "discardToPrompt %s\n", m_dir->name()); if (mainWin->m_displayAll) { displayToPrompt(conn); } else { while (!dircomm->m_at_prompt) { stat = dircomm->read(); if (stat < 0) { break; } } } if (mainWin->m_commDebug) { Pmsg2(000, "endDiscardToPrompt conn=%i %s\n", conn, m_dir->name()); } } QString Console::returnFromPrompt(int conn) { DirComm *dircomm = m_dircommHash.value(conn); QString text(""); int stat = 0; text = ""; dircomm->read(); text += dircomm->msg(); if (mainWin->m_commDebug) Pmsg1(000, "returnFromPrompt %s\n", m_dir->name()); while (!dircomm->m_at_prompt) { if ((stat=dircomm->read()) > 0) { text += dircomm->msg(); } } if (mainWin->m_commDebug) Pmsg2(000, "endreturnFromPrompt=%d %s\n", stat, m_dir->name()); return text; } /* * When the notifier is enabled, read_dir() will automatically be * called by the Qt event loop when ever there is any output * from the Director, and read_dir() will then display it on * the console. * * When we are in a bat dialog, we want to control *all* output * from the Director, so we set notify to off. * m_console->notifiy(false); */ /* dual purpose function to turn notify off and return a connection */ int Console::notifyOff() { int conn = 0; if (getDirComm(conn)) { notify(conn, false); } return conn; } /* knowing a connection, turn notify off or on */ bool Console::notify(int conn, bool enable) { DirComm *dircomm = m_dircommHash.value(conn); if (dircomm) { return dircomm->notify(enable); } else { return false; } } /* knowing a connection, return notify state */ bool Console::is_notify_enabled(int conn) const { DirComm *dircomm = m_dircommHash.value(conn); if (dircomm) { return dircomm->is_notify_enabled(); } else { return false; } } void Console::setDirectorTreeItem(QTreeWidgetItem *item) { m_directorTreeItem = item; } void Console::setDirRes(DIRRES *dir) { m_dir = dir; } /* * To have the ability to get the name of the director resource. */ void Console::getDirResName(QString &name_returned) { name_returned = m_dir->name(); } /* Slot for responding to page selectors status help command */ void Console::consoleHelp() { QString cmd("help"); consoleCommand(cmd); } /* Slot for responding to page selectors reload bareos-dir.conf */ void Console::consoleReload() { QString cmd("reload"); consoleCommand(cmd); } /* For suppressing .messages * This may be rendered not needed if the multiple connections feature gets working */ bool Console::hasFocus() { if (mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this)) return true; else return false; } /* For adding feature to have the gui's messages button change when * messages are pending */ bool Console::messagesPending(bool pend) { bool prev = m_messages_pending; m_messages_pending = pend; mainWin->setMessageIcon(); return prev; } /* terminate all existing connections */ void Console::terminate() { foreach(DirComm* dircomm, m_dircommHash) { dircomm->terminate(); } m_console->stopTimer(); } /* Maybe this should be checking the list, for the moment lets check 0 which should be connected */ bool Console::is_connectedGui() { if (is_connected(0)) { return true; } else { QString message = tr("Director is currently disconnected\nPlease reconnect!"); QMessageBox::warning(this, "Bat", message, QMessageBox::Ok ); return false; } } int Console::read(int conn) { DirComm *dircomm = m_dircommHash.value(conn); return dircomm->read(); } char *Console::msg(int conn) { DirComm *dircomm = m_dircommHash.value(conn); return dircomm->msg(); } int Console::write(int conn, const QString msg) { DirComm *dircomm = m_dircommHash.value(conn); mainWin->waitEnter(); int ret = dircomm->write(msg); mainWin->waitExit(); return ret; } int Console::write(int conn, const char *msg) { DirComm *dircomm = m_dircommHash.value(conn); mainWin->waitEnter(); int ret = dircomm->write(msg); mainWin->waitExit(); return ret; } /* This checks to see if any is connected */ bool Console::is_connected() { bool connected = false; foreach(DirComm* dircomm, m_dircommHash) { if (dircomm->is_connected()) return true; } return connected; } /* knowing the connection id, is it connected */ bool Console::is_connected(int conn) { DirComm *dircomm = m_dircommHash.value(conn); return dircomm->is_connected(); } /* * Need a connection. Check existing connections or create one */ bool Console::getDirComm(int &conn) { if (findDirComm(conn)) { return true; } if (mainWin->m_connDebug) Pmsg0(000, "call newDirComm\n"); return newDirComm(conn); } /* * Try to find a free (unused but established) connection * KES: Note, I think there is a problem here because for * some reason, the notifier is often turned off on file * descriptors that seem to me to be available. That means * that we do not use a free descriptor and thus we will create * a new connection that is maybe not necessary. Someone needs * to look into whether or not notify() is correctly turned on * when we are back at the command prompt and idle. * */ bool Console::findDirComm(int &conn) { QHash::const_iterator iter = m_dircommHash.constBegin(); while (iter != m_dircommHash.constEnd()) { DirComm *dircomm = iter.value(); if (dircomm->m_at_prompt && dircomm->m_at_main_prompt && dircomm->is_notify_enabled()) { conn = dircomm->m_conn; return true; } if (mainWin->m_connDebug) { Pmsg4(000, "currentDirComm=%d at_prompt=%d at_main=%d && notify=%d\n", dircomm->m_conn, dircomm->m_at_prompt, dircomm->m_at_main_prompt, dircomm->is_notify_enabled()); } ++iter; } return false; } /* * Create a new connection */ bool Console::newDirComm(int &conn) { m_dircommCounter++; if (mainWin->m_connDebug) { Pmsg2(000, "newDirComm=%i to: %s\n", m_dircommCounter, m_dir->name()); } DirComm *dircomm = new DirComm(this, m_dircommCounter); m_dircommHash.insert(m_dircommCounter, dircomm); bool success = dircomm->connect_dir(); if (mainWin->m_connDebug) { if (success) { Pmsg2(000, "newDirComm=%i Connected %s\n", m_dircommCounter, m_dir->name()); } else { Emsg2(M_ERROR, 0, "DirComm=%i. Unable to connect to %s\n", m_dircommCounter, m_dir->name()); } } if (!success) { m_dircommHash.remove(m_dircommCounter); delete dircomm; m_dircommCounter--; } conn = m_dircommCounter; return success; } bareos-Release-14.2.6/src/qt-console/console/console.h000066400000000000000000000112741263011562700225750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, January 2007 */ #ifndef _CONSOLE_H_ #define _CONSOLE_H_ #include #include "pages.h" #include "ui_console.h" #include "bcomm/dircomm.h" #ifndef MAX_NAME_LENGTH #define MAX_NAME_LENGTH 128 #endif /* * Structure for obtaining the defaults for a job */ struct job_defaults { QString job_name; QString pool_name; QString messages_name; QString client_name; QString store_name; QString where; QString level; QString type; QString fileset_name; QString catalog_name; bool enabled; }; //class DIRRES; //class BSOCK; //class JCR; //class CONRES; class Console : public Pages, public Ui::ConsoleForm { Q_OBJECT friend class DirComm; public: Console(QTabWidget *parent); ~Console(); int read(int conn); char *msg(int conn); void discardToPrompt(int conn); int write(int conn, const char *msg); int write(int conn, QString msg); int notifyOff(); // enables/disables socket notification - returns the previous state bool notify(int conn, bool enable); // enables/disables socket notification - returns the previous state bool is_notify_enabled(int conn) const; bool getDirComm(int &conn); bool findDirComm(int &conn); void displayToPrompt(int conn); QString returnFromPrompt(int conn); bool dir_cmd(int conn, const char *cmd, QStringList &results); bool dir_cmd(const char *cmd, QStringList &results); bool dir_cmd(QString &cmd, QStringList &results); bool sql_cmd(const char *cmd, QStringList &results); bool sql_cmd(QString &cmd, QStringList &results); bool sql_cmd(int &conn, QString &cmd, QStringList &results); bool sql_cmd(int &conn, const char *cmd, QStringList &results, bool donotify); int write_dir(const char *buf); int write_dir(const char *buf, bool dowait); void write_dir(int conn, const char *buf); void write_dir(int conn, const char *buf, bool dowait); void getDirResName(QString &); void setDirRes(DIRRES *dir); void writeSettings(); void readSettings(); void setDirectorTreeItem(QTreeWidgetItem *); void terminate(); bool is_messagesPending() { return m_messages_pending; }; bool is_connected(); bool is_connected(int conn); QTreeWidgetItem *directorTreeItem() { return m_directorTreeItem; }; void startTimer(); void display_text(const char *buf); void display_text(const QString buf); void display_textf(const char *fmt, ...); void display_html(const QString buf); bool get_job_defaults(struct job_defaults &); bool get_job_defaults(int &conn, struct job_defaults &); const QFont get_font(); void beginNewCommand(int conn); void populateLists(bool forcenew); private: bool get_job_defaults(int &conn, struct job_defaults &, bool donotify); void update_cursor(void); void stopTimer(); bool is_connectedGui(); bool newDirComm(int &conn); void populateLists(int conn); public: QStringList job_list; QStringList restore_list; QStringList client_list; QStringList fileset_list; QStringList messages_list; QStringList pool_list; QStringList storage_list; QStringList type_list; QStringList level_list; QStringList volstatus_list; QStringList mediatype_list; QStringList location_list; public slots: void connect_dir(); void status_dir(void); void messages(void); void set_font(void); void poll_messages(void); void consoleHelp(); void consoleReload(); public: DIRRES *m_dir; /* so various pages can reference it */ bool m_warningPrevent; private: QTextEdit *m_textEdit; QTextCursor *m_cursor; QTreeWidgetItem *m_directorTreeItem; bool m_messages_pending; QTimer *m_timer; bool messagesPending(bool pend); bool hasFocus(); QHash m_dircommHash; int m_dircommCounter; }; #endif /* _CONSOLE_H_ */ bareos-Release-14.2.6/src/qt-console/console/console.ui000066400000000000000000000061151263011562700227610ustar00rootroot00000000000000 ConsoleForm 0 0 432 456 Console 9 6 7 7 200 0 0 0 1 0 Qt::StrongFocus false Qt::ScrollBarAsNeeded QTextEdit::AutoNone false QTextEdit::NoWrap true :/images/status.png StatusDir :/images/utilities-terminal.png Console Help :/images/utilities-terminal.png Request Messages :/images/utilities-terminal.png Reload bareos-dir.conf bareos-Release-14.2.6/src/qt-console/fileset/000077500000000000000000000000001263011562700207465ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/fileset/fileset.cpp000066400000000000000000000207511263011562700231120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * FileSet Class * * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "fileset/fileset.h" #include "util/fmtwidgetitem.h" FileSet::FileSet() : Pages() { setupUi(this); m_name = tr("FileSets"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/system-file-manager.png"))); /* tableWidget, FileSet Tree Tree Widget inherited from ui_fileset.h */ m_populated = false; m_checkcurwidget = true; m_closeable = false; readSettings(); /* add context sensitive menu items specific to this classto the page * selector tree. m_contextActions is QList of QActions */ m_contextActions.append(actionRefreshFileSet); } FileSet::~FileSet() { writeSettings(); } /* * The main meat of the class!! The function that querries the director and * creates the widgets with appropriate values. */ void FileSet::populateTable() { Freeze frz(*tableWidget); /* disable updating*/ m_checkcurwidget = false; tableWidget->clear(); m_checkcurwidget = true; QStringList headerlist = (QStringList() << tr("FileSet Name") << tr("FileSet Id") << tr("Create Time")); tableWidget->setColumnCount(headerlist.count()); tableWidget->setHorizontalHeaderLabels(headerlist); tableWidget->horizontalHeader()->setHighlightSections(false); tableWidget->verticalHeader()->hide(); tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */ QString fileset_comsep(""); bool first = true; QStringList notFoundList = m_console->fileset_list; foreach(QString filesetName, m_console->fileset_list) { if (first) { fileset_comsep += "'" + filesetName + "'"; first = false; } else fileset_comsep += ",'" + filesetName + "'"; } int row = 0; tableWidget->setRowCount(m_console->fileset_list.count()); if (fileset_comsep != "") { /* Set up query QString and header QStringList */ QString query(""); query += "SELECT FileSet AS Name, FileSetId AS Id, CreateTime" " FROM FileSet" " WHERE FileSetId IN (SELECT MAX(FileSetId) FROM FileSet WHERE"; query += " FileSet IN (" + fileset_comsep + ")"; query += " GROUP BY FileSet) ORDER BY FileSet"; QStringList results; if (mainWin->m_sqlDebug) { Pmsg1(000, "FileSet query cmd : %s\n",query.toUtf8().data()); } if (m_console->sql_cmd(query, results)) { QStringList fieldlist; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); /* remove this fileSet from notFoundList */ int indexOf = notFoundList.indexOf(fieldlist[0]); if (indexOf != -1) { notFoundList.removeAt(indexOf); } TableItemFormatter item(*tableWidget, row); /* Iterate through fields in the record */ QStringListIterator fld(fieldlist); int col = 0; /* name */ item.setTextFld(col++, fld.next()); /* id */ item.setNumericFld(col++, fld.next()); /* creation time */ item.setTextFld(col++, fld.next()); row++; } } } foreach(QString filesetName, notFoundList) { TableItemFormatter item(*tableWidget, row); item.setTextFld(0, filesetName); row++; } /* set default sorting */ tableWidget->sortByColumn(headerlist.indexOf(tr("FileSet Name")), Qt::AscendingOrder); tableWidget->setSortingEnabled(true); /* Resize rows and columns */ tableWidget->resizeColumnsToContents(); tableWidget->resizeRowsToContents(); /* make read only */ int rcnt = tableWidget->rowCount(); int ccnt = tableWidget->columnCount(); for(int r=0; r < rcnt; r++) { for(int c=0; c < ccnt; c++) { QTableWidgetItem* item = tableWidget->item(r, c); if (item) { item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable))); } } } m_populated = true; } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void FileSet::PgSeltreeWidgetClicked() { if (!m_populated) { populateTable(); createContextMenu(); } if (!isOnceDocked()) { dockPage(); } } /* * Added to set the context menu policy based on currently active treeWidgetItem * signaled by currentItemChanged */ void FileSet::tableItemChanged(QTableWidgetItem *currentwidgetitem, QTableWidgetItem *previouswidgetitem) { /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */ if (m_checkcurwidget && currentwidgetitem) { int currentRow = currentwidgetitem->row(); QTableWidgetItem *currentrowzeroitem = tableWidget->item(currentRow, 0); m_currentlyselected = currentrowzeroitem->text(); /* The Previous item */ if (previouswidgetitem) { /* avoid a segfault if first time */ tableWidget->removeAction(actionStatusFileSetInConsole); tableWidget->removeAction(actionShowJobs); } if (m_currentlyselected.length() != 0) { /* set a hold variable to the fileset name in case the context sensitive * menu is used */ tableWidget->addAction(actionStatusFileSetInConsole); tableWidget->addAction(actionShowJobs); } } } /* * Setup a context menu * Made separate from populate so that it would not create context menu over and * over as the tree is repopulated. */ void FileSet::createContextMenu() { tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu); tableWidget->addAction(actionRefreshFileSet); connect(tableWidget, SIGNAL( currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)), this, SLOT(tableItemChanged(QTableWidgetItem *, QTableWidgetItem *))); /* connect to the action specific to this pages class */ connect(actionRefreshFileSet, SIGNAL(triggered()), this, SLOT(populateTable())); connect(actionStatusFileSetInConsole, SIGNAL(triggered()), this, SLOT(consoleShowFileSet())); connect(actionShowJobs, SIGNAL(triggered()), this, SLOT(showJobs())); } /* * Function responding to actionListJobsofFileSet which calls mainwin function * to create a window of a list of jobs of this fileset. */ void FileSet::consoleShowFileSet() { QString cmd("show fileset=\""); cmd += m_currentlyselected + "\""; consoleCommand(cmd); } /* * Virtual function which is called when this page is visible on the stack */ void FileSet::currentStackItem() { if (!m_populated) { populateTable(); /* Create the context menu for the fileset table */ createContextMenu(); } } /* * Save user settings associated with this page */ void FileSet::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("FileSet"); settings.setValue("geometry", saveGeometry()); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void FileSet::readSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("FileSet"); restoreGeometry(settings.value("geometry").toByteArray()); settings.endGroup(); } /* * Create a JobList object pre-populating a fileset */ void FileSet::showJobs() { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); mainWin->createPageJobList("", "", "", m_currentlyselected, parentItem); } bareos-Release-14.2.6/src/qt-console/fileset/fileset.h000066400000000000000000000027701263011562700225600ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _FILESET_H_ #define _FILESET_H_ #include #include "ui_fileset.h" #include "pages.h" class FileSet : public Pages, public Ui::FileSetForm { Q_OBJECT public: FileSet(); ~FileSet(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void tableItemChanged(QTableWidgetItem *, QTableWidgetItem *); private slots: void populateTable(); void consoleShowFileSet(); void showJobs(); private: void writeSettings(); void readSettings(); void createContextMenu(); QString m_currentlyselected; bool m_populated; bool m_checkcurwidget; }; #endif /* _FILESET_H_ */ bareos-Release-14.2.6/src/qt-console/fileset/fileset.ui000066400000000000000000000026151263011562700227440ustar00rootroot00000000000000 FileSetForm 0 0 341 277 FileSet Tree :/images/view-refresh.png Refresh FileSet List Requery the director for the list of storage objects. :/images/status-console.png Show FileSet In Console :/images/emblem-system.png ShowJobs bareos-Release-14.2.6/src/qt-console/help/000077500000000000000000000000001263011562700202435ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/help/clients.html000066400000000000000000000023551263011562700225770ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Clients Interface

The Clients interface shows a list of configured client resources. This list of clients is a tree structure and shows a number of attributes from the database for each client.

The user may right click on a client item to display a context sensitive menu of what actions can be performed on a client. This menu has options to allow the user to perform commands in the console. These commands include requesting the status of the client, and pruning or purging jobs and files from the catalog. There is also an option to open up a JobList interface with the control for clients already prepopulated with the selected client item.

To understand pruning and purging, please read the Bareos documentation at the following URL: http://www.bareos.org/rel-manual/Bareos_Console.html bareos-Release-14.2.6/src/qt-console/help/console.html000066400000000000000000000022601263011562700225730ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Console

The Console is the interface that displays all of the text that would normally be displayed in bconsole. Use the command window at the bottom of the interface to manually enter any command as with bconsole.

There are 2 icons in the taskbar which are designed to run console commands.

Use the status   icon in the taskbar to run the status dir command.

Use the messages   icon in the taskbar to run the messages command.

There will be no attempt to document console commands here. An alphabetic list of the commands can be found on the following web URL http://www.bareos.org/rel-manual/Bareos_Console.html bareos-Release-14.2.6/src/qt-console/help/filesets.html000066400000000000000000000016661263011562700227600ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Filesets Interface

The Filesets interface shows a list of filesets and allow the user to right click on a specific fileset to popup it's context sensitive menu. This interface is a tree structure and each item displays a number of attributes from the database for each fileset.

The context sensitive menu allows the user to perform the command status fileset in the console. The user can also open up a new JobList window with the Fileset dropdown pre-populated with the selected fileset. bareos-Release-14.2.6/src/qt-console/help/help.cpp000066400000000000000000000042061263011562700217010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Help Window class * * Kern Sibbald, May MMVII */ #include "bat.h" #include "help.h" /* * Note: HELPDIR is defined in src/host.h */ Help::Help(const QString &path, const QString &file, QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_DeleteOnClose); /* Make sure we go away */ setAttribute(Qt::WA_GroupLeader); /* allow calling from modal dialog */ setupUi(this); /* create window */ textBrowser->setSearchPaths(QStringList() << HELPDIR << path << ":/images"); textBrowser->setSource(file); //textBrowser->setCurrentFont(mainWin->m_consoleHash.values()[0]->get_font()); connect(textBrowser, SIGNAL(sourceChanged(const QUrl &)), this, SLOT(updateTitle())); connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); connect(homeButton, SIGNAL(clicked()), textBrowser, SLOT(home())); connect(backButton, SIGNAL(clicked()), textBrowser, SLOT(backward())); this->show(); } void Help::updateTitle() { setWindowTitle(tr("Help: %1").arg(textBrowser->documentTitle())); } void Help::displayFile(const QString &file) { QRegExp rx; rx.setPattern("/\\.libs"); QString path = QApplication::applicationDirPath(); int pos = rx.indexIn(path); if (pos) path = path.remove(pos, 6); path += "/help"; new Help(path, file); } bareos-Release-14.2.6/src/qt-console/help/help.h000066400000000000000000000024661263011562700213540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Help Window class * It reads an html file and displays it in a "browser" window. * * Kern Sibbald, May MMVII */ #ifndef _HELP_H_ #define _HELP_H_ #include "bat.h" #include "ui_help.h" class Help : public QWidget, public Ui::helpForm { Q_OBJECT public: Help(const QString &path, const QString &file, QWidget *parent = NULL); virtual ~Help() { }; static void displayFile(const QString &file); public slots: void updateTitle(); private: }; #endif /* _HELP_H_ */ bareos-Release-14.2.6/src/qt-console/help/help.ui000066400000000000000000000032241263011562700215330ustar00rootroot00000000000000 helpForm 0 0 762 497 Form 9 6 0 6 &Home &Back Qt::Horizontal 40 20 Close bareos-Release-14.2.6/src/qt-console/help/index.html000066400000000000000000000041511263011562700222410ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The User's guide, for the Bareos Administration Tool.

Welcome to the BAT

Contents.

The Console Interface

The Clients Interface

The FileSets Interface

The Jobs Interface

The JobList Interface

The JobPlot Interface

The Media Interface

The Storage Interface

The two Restore Interfaces

What is the BAT.

Welcome to the Bareos Administration Tool. The bat is the graphical interface to communicate with and administer the bareos director daemon. If you have been using bareos for a while, you're familiar with bconsole, the text based interface to administer bareos. With bat, the user can perform any command that can be run from bconsole, and more.

The bat is bconsole with extra communication capabilities and a set of graphical user interfaces that utilize those capabilities. A bat programmer is able to create interfaces that interact with the director in all ways that a user can, by executing commands. When a command is entered by an interface, the bat types in the command in the console. Often times the interface visible is changed to the console so that the user can read the command as well as the resulting output from the director. Bat can also perform requests of the daemon, that the user would not normally do. These requests would include the ability to retrieve lists of various resources and to instruct the director to query the sql server. The director then forwards the query results to bat. bareos-Release-14.2.6/src/qt-console/help/joblist.html000066400000000000000000000100531263011562700225760ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The JobList Interface

The JobList interface displays a table of jobid's which are instances of a job having been run. The table displays data for each job stored in the daemons sql backend. The table currently includes the job name, the client name, the job type, the job level, the number of files, the number of bytes, the status, and a flag for the jobs files that have been purged or not, and the jobs fileset.

The job type is either "B" for backup or "R" for restore.

The job level is one of "I" for incremental or "F" for full or "D" for differential.

A purged value of yes means that the files for that job have been purged from the catalog's file table. Purged jobs are not be able to have their files browsed when restoring from a job with that jobid.

This interface uses a splitter to divide the display of the table and the controls used to modify the selection criterion. There are 7 drop down boxes that can be used to filter out the records in the table and to view only the items you are interested in. There are two limiting spin boxes and related check boxes that can be used to limit the number of and the age of the records that are to be displayed. These limiting controls begin with default values that can be configured in the Settings->Preferences dialog box in the JobList tab.

Pushing the Refresh button causes the interface to re-query the database. The database does also get requerried every time it comes back to the top of the stack of interfaces in the main window. Another refresh option exists in the popup when right clicking on the Joblist item in the Page Selector.

Pushing the Graph button opens up a new JobPlot interface. All of the drop downs and limiting controls in the JobPlot window default to the current settings of the controls in the JobList interface. If the graph button is not there, bat was not compiled with qwt libraries.

There are many options in the context sensitive popup that appear when the user right clicks on an item in the job table.

Listing console commands can be run to list the jobid, list the files on that jobid, list the jobmedia for that jobid, and list the volumes used for that jobid. There is a preferences item to determine whether a long list or a short list command is run. It can be found from the menu by following settings - preferences then the miscellaneous tab.

Dangerous commands of delete and purge are preceded by an "Are You Sure?" dialog box.

An interface to view the logs that have been stored in the database for the jobid can be viewed by using the show log for job option. If the database does not have a log, an popup explaining the modification that may be made to the bareos-dir.conf file appears. The change is to add "catalog = all" to the messages stanza of the messages resource that this job uses.

Restore from job opens up the Select Jobs interface. It opens prepopulated with the correct data to open up a standard restore interface displaying the filestructure backed up when the job ran. It displays only the files from this job if you don't change the controls in the "Select jobs interface"

Restore from time populates the Select Jobs interface with the endtime of the job populated in the Before Time entry box. This causes the daemon to use the Before Time to select the appropriate job id's for the restore. This contains the most recent full backup, the most recent differential backup done since the most recent full, and all the incremental backups done since the most recent full or differential. This job set is considered the best possible to restore to what the filesystem looked like after that job ran. bareos-Release-14.2.6/src/qt-console/help/jobplot.html000066400000000000000000000016451263011562700226100ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The JobPlot Interface

The JobPlot interface has all of the same selection controls as the JobList interface. It also has controls that affects the plot's display. These settings are saved and used the next time the interface is opened. The user can change the Graph type to one of sticks, lines, steps or none. The user can also turn one or both of the plots off with the File Data and the Byte Data check boxes. The symbol type for each plot's points can be changed as well. bareos-Release-14.2.6/src/qt-console/help/jobs.html000066400000000000000000000043651263011562700220760ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Jobs Interface

The Jobs interface shows a tree of configured job resources. The data displayed for each job in this list are the defaults for the job resource as defined in the bareos-dir configuration file. When a job is run due to being scheduled, these defaults are the values that are used. They are also the values that are populated by default if the job is run manually.

The context sensitive popup menu includes a number of options. There are options to run commands and there is an option to open up a different interface.

The user can run a list files command in the console that displays a list of jobid's that have been run and some associated data. This is similar output to what can be seen in the joblist interface.

The list volumes console command can be run to output a list of volumes that have this jobs files stored on it.

The list nextvolume console command tells the user the next volume that will be asked for when the job is run. It also shows a list of past jobs.

There is a preferences item to determine whether a long list or a short list command is run. It can be found from the menu by following settings - preferences then the miscellaneous tab.

There are options to run commands to either enable or disable the job as scheduled. If disabled, the job is re-enabled when the director daemon is restarted.

The cancel job command is to cancel any running job id's with the job definition.

The open joblist option is to open a new JobList interface and pre-populate the job dropdown list with the jobs resource name.

The run job option is to open the Run a Job interface prepopulating the job dropdown box with the selected job. With the job name in the job dropdown box of the Run a Job interface, the remainder of the controls are populated with the jobs defaults. bareos-Release-14.2.6/src/qt-console/help/media.html000066400000000000000000000033721263011562700222150ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Media Interface

The Media interface displays a tree structure of pools, and under each pool branch, are items representing the volumes in the pool. The display shows data that are the values in the database for each volume. With this interface, the user can manage tape volumes and file volumes.

When the user right clicks on a volume item, a context sensitve menu appears that shows the actions that can be performed on this volume. This menu allows the user to open up other interfaces and to perform commands in the console. There are command options that modify the catalog. These commands include deleting the volume, purging the jobs/files which have been written to the volume, and pruning the jobs/files that meet the pruning criterion configured in bareos-dir.conf. There is also a command to reset the parameters on the volumes based on the parameters of the pool resource.

Other interfaces can be opened up from the context sensitive menu. The user can open up the Relabel a Volume dialog box. The user can also open up the Edit a Volume interface which allows the user to modify all user editable data items for the volume. Another interface that may be opened is the JobList. When created the media drop down control is preselected to the volume. It lists jobs which have been written to the volume. bareos-Release-14.2.6/src/qt-console/help/restore.html000066400000000000000000000201251263011562700226140ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Two Restore Interfaces

Both interfaces accomplish the same three steps. The steps are to select jobs to restore from, give the user the opportunity to select files/directories, then indicate details such as the host and path to restore to and trigger the job to run.

The Standard Restore Interface

Start the standard restore procedure by pressing the restore button in the task bar. There are also two options in the joblist context sensitive menu to start a restore. They are Restore From Time or Restore From Job.

This restore method is intended as a high performance option. It is a server side process. These interfaces assist the user in utilizing the text based restore capabilities of the standard console. It interprets the text to display the information in a way that simplifies the restore procedure.

The Opening interface allows the user to choose selection criterion to inform the server how to determine the set of backup job ids to use in the restore. This best possible set is he most recent full backup, the most recent differential backup done since the most recent full, and all the incremental backups done since the most recent full or differential. Then the server uses this set of jobs to create a file structure that is the most recent version of each file found in this job list.

The second interface allows the user to browse this file structure and choose the files and directories to restore. This is done in an explorer type interface with a directory tree on the left. In the right pane of a splitter is a table showing a list of files and directories that are the contents of the directory selected in the left pane. The user can mark and unmark either with the buttons on the top or by double clicking on the check mark icon to toggle whether an item is selected or not. Double clicking an item which is a directory on a part of the table which is not the check icon opens that directory. Clicking 'OK' completes the selection process.

The third step is the Restore Run interface. It's purpose is to allow the user to inform the bareos server details of the host and path to restore to, the replacement rules, when to restore and what priority to give the restore job.

The Version Browser Restore Interface

This restore interface is NOT intended to perform major restores of directory structures with large numbers of directories and files. It should work, however it is a chatty interface. This is due to the number of sql queries made of the server which is proportional to the number of files and directories selected plus the number of exceptions to defaults selected. It IS intended to allow the user to browse for specific files and choose between the different versions of those files that are available in the catalog to restore.

The interface contains a horizontal splitter. The bottom pane contains some controls for the interface. The top portion contains a vertical splitter with 4 panes for viewing the cataloged information. The left pane is for viewing and further sub selecting of jobs. The second pane is for viewing the directory tree. The third is for viewing a list of files in a directory that has been selected. Then lastly the fourth pane is for viewing a table of versions of a single file that has been selected from the file table.

The version browser accomplishes the three restore steps differently.

To select jobs and populate the directory tree, press the refresh button. The job table contains selected jobs. The selection criterion of the three dropdowns and the two limits are used as the filtering criterion for populating the job table the first time the refresh button is pushed. After the refresh button has been pushed, the job table has check marks that can selects and unselects jobs. Re-pressing the refresh button does one of two things. What occurs is dependent on if the controls in the bottom pane display the same data as the previous time the refresh button was pressed. If changed the jobs table is repopulated from the selection criterion. If unchanged any jobs that have been unchecked are excluded from the process of selecting directories, files and versions. The directory tree does get repopulated when the refresh button is pushed. There is a text label underneath the refresh button to inform the user as to which occurs when refresh is pressed.

The user can browse the directory tree and click on a directory folder which then populates the file table with the files that are contained in the selected directory path. Selecting or unselecting a directory does also select or unselect all files and all directories in the tree hierarchy beneath it. If there are any exceptions already selected beneath that directory, those exceptions do get deleted.

With the file table populated, the user can unselect a file in a selected directory and also select a file in an unselected directory.

With a file selected the version table populates with all the instances a file has been written to tape. The user can choose a specific version of a file for restore and override the default which is to restore the most recent version.

Pressing the restore button initiates a procedure preparing to perform the restore of the requested files. The same Restore Run interface that was the third step in the standard restore is then displayed. It allows the user to instruct the bareos server of the details of what host and what path to restore the files to. This part of the restore does take control of the connection to the server and does not allow any other communication to the server by the other interfaces.

There are two progress bars that appear when refreshing or after pressing Restore. These indicate to the user the time it may take to complete any tasks that could take a long time period.

A Version Browser Limitation

There is an important limitation of the version browser. If a fileset specifically points to a file instead of a directory that contains files, it will not be seen in the version browser. This is due to the way that the version browser searches for directories first, then for files contained in those directories. A common example is with the catalog job. It by default points directly to one file created in a databse dump.

Version Browser Performance

If you have used the version browser with a large database, you may have noticed that the performance can begin to be quite slow. A way to improve the response time of the database server is to add indexes that will assist a couple of the specific queries that are made.

For postgresql add 2 indexes with the following commands in psql:
CREATE INDEX file_filenameid_jobid ON file USING btree (filenameid, jobid);
CREATE INDEX file_pathid_idx ON file USING btree (pathid);

For mysql add 2 indexes with the following commands in mysql:
CREATE INDEX file_filenameid_jobid ON File (FilenameId, JobId);
CREATE INDEX file_pathid_idx ON File (PathId);

There is one way to make the first of those two indexes perform just a little better. It is to create a partial index. First, at least one backup must be in the database that has at least one directory. Then in psql or mysql perform the command:
SELECT FilenameId FROM Filename WHERE name='';
Use the results of this command and replace for XXX in the following command:
CREATE INDEX file_filenameid_jobid2 ON File (JobId) WHERE FilenameId=XXX;
This index will use less disk space and will perform better. Don't forget to remove the index it replaces, file_filenameid_jobid.

If you have sqlite and would be willing to test out the creation of these indexes to see if they work, please let me know the commands. bareos-Release-14.2.6/src/qt-console/help/storage.html000066400000000000000000000022101263011562700225700ustar00rootroot00000000000000 Bat User's Guide

Bat User's Guide


The Storage Interface

The Storage interface shows a list of configured storage device resources. The list is a tree structure and shows the storage id and the auto changer flag.

The interface allows the user to right click on an item to popup a context sensitive menu of the actions that can be performed with that storage device. The actions allow performing commands in the console. The commands include requesting the status of the storage, and to mount, unmount or release the media in the storage device.

If the autochanger flag is true, two additional options in the context sensitive menu are found. These are options to run the command to update slots and the command to update slots scan. bareos-Release-14.2.6/src/qt-console/install_conf_file.in000077500000000000000000000007111263011562700233170ustar00rootroot00000000000000#!/bin/sh sbindir=@sbindir@ sysconfdir=@sysconfdir@ INSTALL_CONFIG="@INSTALL@ -m 640" DESTDIR=`echo ${DESTDIR}` srcconf=bat.conf if test -f ${DESTDIR}${sysconfdir}/${srcconf}; then destconf=${srcconf}.new echo " ==> Found existing $srcconf, installing new conf file as ${destconf}" else destconf=${srcconf} fi echo "${INSTALL_CONFIG} ${srcconf} ${DESTDIR}${sysconfdir}/${destconf}" ${INSTALL_CONFIG} ${srcconf} ${DESTDIR}${sysconfdir}/${destconf} bareos-Release-14.2.6/src/qt-console/job/000077500000000000000000000000001263011562700200655ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/job/job.cpp000066400000000000000000000340241263011562700213460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bat.h" #include "job.h" #include "util/fmtwidgetitem.h" #include "mediainfo/mediainfo.h" #include "run/run.h" Job::Job(QString &jobId, QTreeWidgetItem *parentTreeWidgetItem) : Pages() { setupUi(this); pgInitialize(tr("Job"), parentTreeWidgetItem); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/joblog.png"))); m_cursor = new QTextCursor(textJobLog->document()); m_jobId = jobId; m_timer = NULL; getFont(); connect(pbRefresh, SIGNAL(clicked()), this, SLOT(populateAll())); connect(pbDelete, SIGNAL(clicked()), this, SLOT(deleteJob())); connect(pbCancel, SIGNAL(clicked()), this, SLOT(cancelJob())); connect(pbRun, SIGNAL(clicked()), this, SLOT(rerun())); connect(list_Volume, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(showInfoVolume(QListWidgetItem *))); populateAll(); dockPage(); setCurrent(); } void Job::rerun() { new runPage(label_Name->text(), label_Level->text(), label_Pool->text(), QString(""), // storage label_Client->text(), label_FileSet->text()); } void Job::showInfoVolume(QListWidgetItem *item) { QString s= item->text(); QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); MediaInfo *m = new MediaInfo(pageSelectorTreeWidgetItem, s); connect(m, SIGNAL(destroyed()), this, SLOT(populateTree())); } void Job::deleteJob() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to delete?? !!!.\n" "This delete command is used to delete a Job record and all associated catalog" " records that were created. This command operates only on the Catalog" " database and has no effect on the actual data written to a Volume. This" " command can be dangerous and we strongly recommend that you do not use" " it unless you know what you are doing. The Job and all its associated" " records (File and JobMedia) will be deleted from the catalog." "Press OK to proceed with delete operation.?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString cmd("delete job jobid="); cmd += m_jobId; consoleCommand(cmd, false); closeStackPage(); } void Job::cancelJob() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to cancel this job?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString cmd("cancel jobid="); cmd += m_jobId; consoleCommand(cmd, false); } void Job::getFont() { QFont font = textJobLog->font(); QString dirname; m_console->getDirResName(dirname); QSettings settings(dirname, "bat"); settings.beginGroup("Console"); font.setFamily(settings.value("consoleFont", "Courier").value()); font.setPointSize(settings.value("consolePointSize", 10).toInt()); font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool()); settings.endGroup(); textJobLog->setFont(font); } void Job::populateAll() { // Pmsg0(50, "populateAll()\n"); populateText(); populateForm(); populateVolumes(); } /* * Populate the text in the window * TODO: Just append new text instead of clearing the window */ void Job::populateText() { textJobLog->clear(); QString query; query = "SELECT Time, LogText FROM Log WHERE JobId='" + m_jobId + "' order by Time"; /* This could be a log item */ if (mainWin->m_sqlDebug) { Pmsg1(000, "Log query cmd : %s\n", query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { if (!results.size()) { QMessageBox::warning(this, tr("Bat"), tr("There were no results!\n" "It is possible you may need to add \"catalog = all\" " "to the Messages resource for this job.\n"), QMessageBox::Ok); return; } QString jobstr("JobId "); /* FIXME: should this be translated ? */ jobstr += m_jobId; QString htmlbuf("

");

      /* Iterate through the lines of results. */
      QString field;
      QStringList fieldlist;
      QString lastTime;
      QString lastSvc;
      foreach (QString resultline, results) {
         fieldlist = resultline.split("\t");

         if (fieldlist.size() < 2)
            continue;

         QString curTime = fieldlist[0].trimmed();

         field = fieldlist[1].trimmed();
         int colon = field.indexOf(":");
         if (colon > 0) {
            /* string is like  : ..."
             * we split at ':' then remove the jobId xxxx string (always the same) */
            QString curSvc(field.left(colon).replace(jobstr,"").trimmed());
            if (curSvc == lastSvc  && curTime == lastTime) {
               curTime.clear();
               curSvc.clear();
            } else {
               lastTime = curTime;
               lastSvc = curSvc;
            }
//          htmlbuf += "
"; htmlbuf += "\n" + curSvc + " "; /* rest of string is marked as pre-formatted (here trimming should * be avoided, to preserve original formatting) */ QString msg(field.mid(colon+2)); if (msg.startsWith( tr("Error:")) ) { /* FIXME: should really be translated ? */ /* error msg, use a specific class */ htmlbuf += "
" + msg + "
";
            } else {
               htmlbuf += msg ;
            }
         } else {
            /* non standard string, place as-is */
            if (curTime == lastTime) {
               curTime.clear();
            } else {
               lastTime = curTime;
            }
//          htmlbuf += "
"; htmlbuf += "\n" + field ; } } /* foreach resultline */ htmlbuf += ""; /* full text ready. Here a custom sheet is used to align columns */ QString logSheet(".err {color:#FF0000;}"); textJobLog->document()->setDefaultStyleSheet(logSheet); textJobLog->document()->setHtml(htmlbuf); textJobLog->moveCursor(QTextCursor::Start); } /* if results from query */ } void Job::updateRunInfo() { QString cmd; QStringList results; QStringList lst; bool parseit=false; cmd = QString(".status client=\"" + m_client + "\" running"); /* * JobId 5 Job backup.2010-12-21_09.28.17_03 is running. * VSS Full Backup Job started: 21-Dec-10 09:28 * Files=4 Bytes=610,976 Bytes/sec=87,282 Errors=0 * Files Examined=4 * Processing file: /tmp/regress/build/po/de.po * SDReadSeqNo=5 fd=5 * * Or * JobId=5 * Job=backup.2010-12-21_09.28.17_03 * VSS=1 * Files=4 * Bytes=610976 * */ QRegExp jobline("(JobId) (\\d+) Job "); QRegExp itemline("([\\w /]+)[:=]\\s*(.+)"); QRegExp oldline("Files=([\\d,]+) Bytes=([\\d,]+) Bytes/sec=([\\d,]+) Errors=([\\d,]+)"); QString com(","); QString empty(""); if (m_console->dir_cmd(cmd, results)) { foreach (QString mline, results) { foreach (QString line, mline.split("\n")) { line = line.trimmed(); if (oldline.indexIn(line) >= 0) { if (parseit) { lst = oldline.capturedTexts(); label_JobErrors->setText(lst[4]); label_Speed->setText(convertBytesSI(lst[3].replace(com, empty).toULongLong())+"/s"); label_JobFiles->setText(lst[1]); label_JobBytes->setText(convertBytesSI(lst[2].replace(com, empty).toULongLong())); } continue; } else if (jobline.indexIn(line) >= 0) { lst = jobline.capturedTexts(); lst.removeFirst(); } else if (itemline.indexIn(line) >= 0) { lst = itemline.capturedTexts(); lst.removeFirst(); } else { if (mainWin->m_miscDebug) Pmsg1(0, "bad line=%s\n", line.toUtf8().data()); continue; } if (lst.count() < 2) { if (mainWin->m_miscDebug) Pmsg2(0, "bad line=%s count=%d\n", line.toUtf8().data(), lst.count()); } if (lst[0] == "JobId") { if (lst[1] == m_jobId) { parseit = true; } else { parseit = false; } } if (!parseit) { continue; } // } else if (lst[0] == "Job") { // grpRun->setTitle(lst[1]); // // } else if (lst[0] == "VSS") { // } else if (lst[0] == "Level") { // Info->setText(lst[1]); // // } else if (lst[0] == "JobType") { // // } else if (lst[0] == "JobStarted") { // Started->setText(lst[1]); if (lst[0] == "Errors") { label_JobErrors->setText(lst[1]); } else if (lst[0] == "Bytes/sec") { label_Speed->setText(convertBytesSI(lst[1].toULongLong())+"/s"); } else if (lst[0] == "Files") { label_JobFiles->setText(lst[1]); } else if (lst[0] == "Bytes") { label_JobBytes->setText(convertBytesSI(lst[1].toULongLong())); } else if (lst[0] == "Files Examined") { label_FilesExamined->setText(lst[1]); } else if (lst[0] == "Processing file") { label_CurrentFile->setText(lst[1]); } } } } } /* * Populate the text in the window */ void Job::populateForm() { QString stat, err; char buf[256]; QString query = "SELECT JobId, Job.Name, Level, Client.Name, Pool.Name, FileSet," "SchedTime, StartTime, EndTime, EndTime-StartTime AS Duration, " "JobBytes, JobFiles, JobErrors, JobStatus, PurgedFiles " "FROM Job JOIN Client USING (ClientId) " "LEFT JOIN Pool ON (Job.PoolId = Pool.PoolId) " "LEFT JOIN FileSet ON (Job.FileSetId = FileSet.FileSetId)" "WHERE JobId=" + m_jobId; QStringList results; if (m_console->sql_cmd(query, results)) { QString resultline, duration; QStringList fieldlist; foreach (resultline, results) { // should have only one result fieldlist = resultline.split("\t"); QStringListIterator fld(fieldlist); label_JobId->setText(fld.next()); label_Name->setText(fld.next()); label_Level->setText(job_level_to_str(fld.next()[0].toAscii())); m_client = fld.next(); label_Client->setText(m_client); label_Pool->setText(fld.next()); label_FileSet->setText(fld.next()); label_SchedTime->setText(fld.next()); label_StartTime->setText(fld.next()); label_EndTime->setText(fld.next()); duration = fld.next(); /* * Note: if we have a negative duration, it is because the EndTime * is zero (i.e. the Job is still running). We should use * duration = StartTime - current_time */ if (duration.left(1) == "-") { duration = "0.0"; } label_Duration->setText(duration); label_JobBytes->setText(convertBytesSI(fld.next().toULongLong())); label_JobFiles->setText(fld.next()); err = fld.next(); label_JobErrors->setText(err); stat = fld.next(); if (stat == "T" && err.toInt() > 0) { stat = "W"; } if (stat == "R") { pbDelete->setVisible(false); pbCancel->setVisible(true); grpRun->setVisible(true); if (!m_timer) { m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(populateAll())); m_timer->start(30000); } updateRunInfo(); } else { pbDelete->setVisible(true); pbCancel->setVisible(false); grpRun->setVisible(false); if (m_timer) { m_timer->stop(); delete m_timer; m_timer = NULL; } } label_JobStatus->setPixmap(QPixmap(":/images/" + stat + ".png")); jobstatus_to_ascii_gui(stat[0].toAscii(), buf, sizeof(buf)); stat = buf; label_JobStatus->setToolTip(stat); chkbox_PurgedFiles->setCheckState(fld.next().toInt()?Qt::Checked:Qt::Unchecked); } } } void Job::populateVolumes() { QString query = "SELECT DISTINCT VolumeName, InChanger, Slot " "FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) " "WHERE JobId=" + m_jobId + " ORDER BY VolumeName "; if (mainWin->m_sqlDebug) Pmsg1(0, "Query cmd : %s\n",query.toUtf8().data()); QStringList results; if (m_console->sql_cmd(query, results)) { QString resultline; QStringList fieldlist; list_Volume->clear(); foreach (resultline, results) { // should have only one result fieldlist = resultline.split("\t"); QStringListIterator fld(fieldlist); // QListWidgetItem(QIcon(":/images/inchanger" + fld.next() + ".png"), // fld.next(), list_Volume); list_Volume->addItem(fld.next()); } } } //QListWidgetItem ( const QIcon & icon, const QString & text, QListWidget * parent = 0, int type = Type ) bareos-Release-14.2.6/src/qt-console/job/job.h000066400000000000000000000026621263011562700210160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _JOB_H_ #define _JOB_H_ #include #include "ui_job.h" #include class Job : public Pages, public Ui::JobForm { Q_OBJECT public: Job(QString &jobId, QTreeWidgetItem *parentTreeWidgetItem); public slots: void populateAll(); void deleteJob(); void cancelJob(); void showInfoVolume(QListWidgetItem *); void rerun(); private slots: private: void updateRunInfo(); void populateText(); void populateForm(); void populateVolumes(); void getFont(); QTextCursor *m_cursor; QString m_jobId; QString m_client; QTimer *m_timer; }; #endif /* _JOB_H_ */ bareos-Release-14.2.6/src/qt-console/job/job.ui000066400000000000000000000544111263011562700212030ustar00rootroot00000000000000 JobForm 0 0 975 631 Form Cancel :/images/A.png:/images/A.png true Delete :/images/purge.png:/images/purge.png true false View errors for this Job Errors :/images/zoom.png:/images/zoom.png true false Media :/images/zoom.png:/images/zoom.png true false History :/images/zoom.png:/images/zoom.png true 0 0 Run again :/images/R.png:/images/R.png true false Read doc true false FileSet :/images/zoom.png:/images/zoom.png true false Stats :/images/zoom.png:/images/zoom.png true Refresh :/images/view-refresh.png:/images/view-refresh.png true Qt::Horizontal 40 20 0 0 230 180 230 180 Basic Information JobId: 2 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Job Name: Test Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Level: VirtualFull Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Client: client-fd Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse FileSet: TheFileSet Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Pool: ThePool Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 0 0 160 180 160 180 Status Status: :/images/T.png false Errors: 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Files: 1,924 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Bytes: 109 MB Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Purged: false true 0 0 260 180 260 180 Times Sched Time: 2009-07-31 00:10:00 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Start Time: 2009-07-31 00:10:00 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse End Time: 2009-07-31 00:20:00 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Duration: 00:10:00 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 0 0 170 181 170 181 170 180 Volume Used 0 0 149 140 149 140 149 140 Vol0001 :/images/inflag1.png:/images/inflag1.png Qt::Horizontal 40 20 true 500 0 Running Information Speed: Files Examined: Current File: 250 0 /var/www/bareos/spool 100,000 100 MB/s Qt::Horizontal 40 20 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:10pt;"></p></body></html> chk_Bwlimit clicked(bool) spin_Bwlimit setEnabled(bool) 51 324 302 328 bareos-Release-14.2.6/src/qt-console/joblist/000077500000000000000000000000001263011562700207615ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/joblist/joblist.cpp000066400000000000000000000571311263011562700231420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "joblist.h" #include "restore/restore.h" #include "job/job.h" #include "joblog/joblog.h" #include "util/fmtwidgetitem.h" #include "util/comboutil.h" /* * Constructor for the class */ JobList::JobList(const QString &mediaName, const QString &clientName, const QString &jobName, const QString &filesetName, QTreeWidgetItem *parentTreeWidgetItem) : Pages() { setupUi(this); m_name = "Jobs Run"; /* treeWidgetName has a virtual override in this class */ m_mediaName = mediaName; m_clientName = clientName; m_jobName = jobName; m_filesetName = filesetName; pgInitialize("", parentTreeWidgetItem); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/emblem-system.png"))); m_resultCount = 0; m_populated = false; m_closeable = false; if ((m_mediaName != "") || (m_clientName != "") || (m_jobName != "") || (m_filesetName != "")) { m_closeable=true; } m_checkCurrentWidget = true; /* Set Defaults for check and spin for limits */ limitCheckBox->setCheckState(mainWin->m_recordLimitCheck ? Qt::Checked : Qt::Unchecked); limitSpinBox->setValue(mainWin->m_recordLimitVal); daysCheckBox->setCheckState(mainWin->m_daysLimitCheck ? Qt::Checked : Qt::Unchecked); daysSpinBox->setValue(mainWin->m_daysLimitVal); QGridLayout *gridLayout = new QGridLayout(this); gridLayout->setSpacing(6); gridLayout->setMargin(9); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); m_splitter = new QSplitter(Qt::Vertical, this); QScrollArea *area = new QScrollArea(); area->setObjectName(QString::fromUtf8("area")); area->setWidget(frame); area->setWidgetResizable(true); m_splitter->addWidget(area); m_splitter->addWidget(mp_tableWidget); gridLayout->addWidget(m_splitter, 0, 0, 1, 1); createConnections(); readSettings(); if (m_closeable) { dockPage(); } } /* * Write the m_splitter settings in the destructor */ JobList::~JobList() { writeSettings(); } /* * The Meat of the class. * This function will populate the QTableWidget, mp_tablewidget, with * QTableWidgetItems representing the results of a query for what jobs exist on * the media name passed from the constructor stored in m_mediaName. */ void JobList::populateTable() { /* Can't do this in constructor because not neccesarily conected in constructor */ prepareFilterWidgets(); m_populated = true; Freeze frz(*mp_tableWidget); /* disable updating*/ /* Set up query */ QString query; fillQueryString(query); /* Set up the Header for the table */ QStringList headerlist = (QStringList() << tr("Job Id") << tr("Job Name") << tr("Client") << tr("Job Starttime") << tr("Job Type") << tr("Job Level") << tr("Job Files") << tr("Job Bytes") << tr("Job Status") << tr("Purged") << tr("File Set") << tr("Pool Name") << tr("First Volume") << tr("VolCount")); m_jobIdIndex = headerlist.indexOf(tr("Job Id")); m_purgedIndex = headerlist.indexOf(tr("Purged")); m_typeIndex = headerlist.indexOf(tr("Job Type")); m_statusIndex = headerlist.indexOf(tr("Job Status")); m_startIndex = headerlist.indexOf(tr("Job Starttime")); m_filesIndex = headerlist.indexOf(tr("Job Files")); m_bytesIndex = headerlist.indexOf(tr("Job Bytes")); m_levelIndex = headerlist.indexOf(tr("Job Level")); m_nameIndex = headerlist.indexOf(tr("Job Name")); m_filesetIndex = headerlist.indexOf(tr("File Set")); m_clientIndex = headerlist.indexOf(tr("Client")); /* Initialize the QTableWidget */ m_checkCurrentWidget = false; mp_tableWidget->clear(); m_checkCurrentWidget = true; mp_tableWidget->setColumnCount(headerlist.size()); mp_tableWidget->setHorizontalHeaderLabels(headerlist); mp_tableWidget->horizontalHeader()->setHighlightSections(false); mp_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); mp_tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */ if (mainWin->m_sqlDebug) { Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { m_resultCount = results.count(); QStringList fieldlist; mp_tableWidget->setRowCount(results.size()); int row = 0; /* Iterate through the record returned from the query */ QString resultline; foreach (resultline, results) { fieldlist = resultline.split("\t"); if (fieldlist.size() < 13) continue; /* some fields missing, ignore row */ TableItemFormatter jobitem(*mp_tableWidget, row); /* Iterate through fields in the record */ QStringListIterator fld(fieldlist); int col = 0; /* job id */ jobitem.setNumericFld(col++, fld.next()); /* job name */ jobitem.setTextFld(col++, fld.next()); /* client */ jobitem.setTextFld(col++, fld.next()); /* job starttime */ jobitem.setTextFld(col++, fld.next(), true); /* job type */ jobitem.setJobTypeFld(col++, fld.next()); /* job level */ jobitem.setJobLevelFld(col++, fld.next()); /* job files */ jobitem.setNumericFld(col++, fld.next()); /* job bytes */ jobitem.setBytesFld(col++, fld.next()); /* job status */ jobitem.setJobStatusFld(col++, fld.next()); /* purged */ jobitem.setBoolFld(col++, fld.next()); /* fileset */ jobitem.setTextFld(col++, fld.next()); /* pool name */ jobitem.setTextFld(col++, fld.next()); /* First Media */ jobitem.setTextFld(col++, fld.next()); /* Medias count */ jobitem.setNumericFld(col++, fld.next()); row++; } } /* set default sorting */ mp_tableWidget->sortByColumn(m_jobIdIndex, Qt::DescendingOrder); mp_tableWidget->setSortingEnabled(true); /* Resize the columns */ mp_tableWidget->resizeColumnsToContents(); mp_tableWidget->resizeRowsToContents(); mp_tableWidget->verticalHeader()->hide(); if ((m_mediaName != tr("Any")) && (m_resultCount == 0)){ /* for context sensitive searches, let the user know if there were no * results */ QMessageBox::warning(this, "Bat", tr("The Jobs query returned no results.\n" "Press OK to continue?"), QMessageBox::Ok ); } /* make read only */ mp_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); } void JobList::prepareFilterWidgets() { if (!m_populated) { clientComboBox->addItem(tr("Any")); clientComboBox->addItems(m_console->client_list); comboSel(clientComboBox, m_clientName); QStringList volumeList; getVolumeList(volumeList); volumeComboBox->addItem(tr("Any")); volumeComboBox->addItems(volumeList); comboSel(volumeComboBox, m_mediaName); jobComboBox->addItem(tr("Any")); jobComboBox->addItems(m_console->job_list); comboSel(jobComboBox, m_jobName); levelComboFill(levelComboBox); boolComboFill(purgedComboBox); fileSetComboBox->addItem(tr("Any")); fileSetComboBox->addItems(m_console->fileset_list); comboSel(fileSetComboBox, m_filesetName); poolComboBox->addItem(tr("Any")); poolComboBox->addItems(m_console->pool_list); jobStatusComboFill(statusComboBox); } } void JobList::fillQueryString(QString &query) { query = ""; int volumeIndex = volumeComboBox->currentIndex(); if (volumeIndex != -1) m_mediaName = volumeComboBox->itemText(volumeIndex); QString distinct = ""; if (m_mediaName != tr("Any")) { distinct = "DISTINCT "; } query += "SELECT " + distinct + "Job.JobId AS JobId, Job.Name AS JobName, " " Client.Name AS Client," " Job.Starttime AS JobStart, Job.Type AS JobType," " Job.Level AS BackupLevel, Job.Jobfiles AS FileCount," " Job.JobBytes AS Bytes, Job.JobStatus AS Status," " Job.PurgedFiles AS Purged, FileSet.FileSet," " Pool.Name AS Pool," " (SELECT Media.VolumeName FROM JobMedia JOIN Media ON JobMedia.MediaId=Media.MediaId WHERE JobMedia.JobId=Job.JobId ORDER BY JobMediaId LIMIT 1) AS FirstVolume," " (SELECT count(DISTINCT MediaId) FROM JobMedia WHERE JobMedia.JobId=Job.JobId) AS Volumes" " FROM Job" " JOIN Client ON (Client.ClientId=Job.ClientId)" " LEFT OUTER JOIN FileSet ON (FileSet.FileSetId=Job.FileSetId) " " LEFT OUTER JOIN Pool ON Job.PoolId = Pool.PoolId "; QStringList conditions; if (m_mediaName != tr("Any")) { query += " LEFT OUTER JOIN JobMedia ON (JobMedia.JobId=Job.JobId) " " LEFT OUTER JOIN Media ON (JobMedia.MediaId=Media.MediaId) "; conditions.append("Media.VolumeName='" + m_mediaName + "'"); } comboCond(conditions, clientComboBox, "Client.Name"); comboCond(conditions, jobComboBox, "Job.Name"); levelComboCond(conditions, levelComboBox, "Job.Level"); jobStatusComboCond(conditions, statusComboBox, "Job.JobStatus"); boolComboCond(conditions, purgedComboBox, "Job.PurgedFiles"); comboCond(conditions, fileSetComboBox, "FileSet.FileSet"); comboCond(conditions, poolComboBox, "Pool.Name"); /* If Limit check box For limit by days is checked */ if (daysCheckBox->checkState() == Qt::Checked) { QDateTime stamp = QDateTime::currentDateTime().addDays(-daysSpinBox->value()); QString since = stamp.toString(Qt::ISODate); conditions.append("Job.Starttime > '" + since + "'"); } if (filterCopyCheckBox->checkState() == Qt::Checked) { conditions.append("Job.Type != 'c'" ); } if (filterMigrationCheckBox->checkState() == Qt::Checked) { conditions.append("Job.Type != 'g'" ); } bool first = true; foreach (QString condition, conditions) { if (first) { query += " WHERE " + condition; first = false; } else { query += " AND " + condition; } } /* Descending */ query += " ORDER BY Job.JobId DESC"; /* If Limit check box for limit records returned is checked */ if (limitCheckBox->checkState() == Qt::Checked) { QString limit; limit.setNum(limitSpinBox->value()); query += " LIMIT " + limit; } } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void JobList::PgSeltreeWidgetClicked() { if (!m_populated) { populateTable(); /* Lets make sure the splitter is not all the way to size index 0 == 0 */ QList sizes = m_splitter->sizes(); if (sizes[0] == 0) { int frameMax = frame->maximumHeight(); int sizeSum = 0; foreach(int size, sizes) { sizeSum += size; } int tabHeight = mainWin->tabWidget->geometry().height(); sizes[0] = frameMax; sizes[1] = tabHeight - frameMax; m_splitter->setSizes(sizes); } } if (!isOnceDocked()) { dockPage(); } } /* * Virtual function override of pages function which is called when this page * is visible on the stack */ void JobList::currentStackItem() { /* if (!m_populated) populate every time user comes back to this object */ populateTable(); } /* * Virtual Function to return the name for the medialist tree widget */ void JobList::treeWidgetName(QString &desc) { if (m_mediaName != "" ) { desc = tr("Jobs Run on Volume %1").arg(m_mediaName); } else if (m_clientName != "" ) { desc = tr("Jobs Run from Client %1").arg(m_clientName); } else if (m_jobName != "" ) { desc = tr("Jobs Run of Job %1").arg(m_jobName); } else if (m_filesetName != "" ) { desc = tr("Jobs Run with fileset %1").arg(m_filesetName); } else { desc = tr("Jobs Run"); } } /* * Function to create connections for context sensitive menu for this and * the page selector */ void JobList::createConnections() { /* connect to the action specific to this pages class that shows up in the * page selector tree */ connect(actionRefreshJobList, SIGNAL(triggered()), this, SLOT(populateTable())); connect(refreshButton, SIGNAL(pressed()), this, SLOT(populateTable())); /* for the selectionChanged to maintain m_currentJob and a delete selection */ connect(mp_tableWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); connect(mp_tableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(showInfoForJob())); /* Do what is required for the local context sensitive menu */ /* setContextMenuPolicy is required */ mp_tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu); connect(actionListFilesOnJob, SIGNAL(triggered()), this, SLOT(consoleListFilesOnJob())); connect(actionListJobMedia, SIGNAL(triggered()), this, SLOT(consoleListJobMedia())); connect(actionDeleteJob, SIGNAL(triggered()), this, SLOT(consoleDeleteJob())); connect(actionRestartJob, SIGNAL(triggered()), this, SLOT(consoleRestartJob())); connect(actionPurgeFiles, SIGNAL(triggered()), this, SLOT(consolePurgeFiles())); connect(actionRestoreFromJob, SIGNAL(triggered()), this, SLOT(preRestoreFromJob())); connect(actionRestoreFromTime, SIGNAL(triggered()), this, SLOT(preRestoreFromTime())); connect(actionShowLogForJob, SIGNAL(triggered()), this, SLOT(showLogForJob())); connect(actionShowInfoForJob, SIGNAL(triggered()), this, SLOT(showInfoForJob())); connect(actionCancelJob, SIGNAL(triggered()), this, SLOT(consoleCancelJob())); connect(actionListJobTotals, SIGNAL(triggered()), this, SLOT(consoleListJobTotals())); connect(m_splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved(int, int))); m_contextActions.append(actionRefreshJobList); m_contextActions.append(actionListJobTotals); } /* * Functions to respond to local context sensitive menu sending console commands * If I could figure out how to make these one function passing a string, Yaaaaaa */ void JobList::consoleListFilesOnJob() { QString cmd("list files jobid="); cmd += m_currentJob; if (mainWin->m_longList) { cmd.prepend("l"); } consoleCommand(cmd); } void JobList::consoleListJobMedia() { QString cmd("list jobmedia jobid="); cmd += m_currentJob; if (mainWin->m_longList) { cmd.prepend("l"); } consoleCommand(cmd); } void JobList::consoleListJobTotals() { QString cmd("list jobtotals"); if (mainWin->m_longList) { cmd.prepend("l"); } consoleCommand(cmd); } void JobList::consoleDeleteJob() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to delete?? !!!.\n" "This delete command is used to delete a Job record and all associated catalog" " records that were created. This command operates only on the Catalog" " database and has no effect on the actual data written to a Volume. This" " command can be dangerous and we strongly recommend that you do not use" " it unless you know what you are doing. The Job and all its associated" " records (File and JobMedia) will be deleted from the catalog." "Press OK to proceed with delete operation.?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString cmd("delete job jobid="); cmd += m_selectedJobs; consoleCommand(cmd, false); populateTable(); } void JobList::consoleRestartJob() { QString cmd; cmd = tr("run job=\"%1\" client=\"%2\" level=%3").arg(m_jobName).arg(m_clientName).arg(m_levelName); if (m_filesetName != "" && m_filesetName != "*None*") { cmd += tr(" fileset=\"%1\"").arg(m_filesetName); } if (mainWin->m_commandDebug) Pmsg1(000, "Run cmd : %s\n",cmd.toUtf8().data()); consoleCommand(cmd, false); populateTable(); } void JobList::consolePurgeFiles() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to purge ?? !!!.\n" "The Purge command will delete associated Catalog database records from Jobs and" " Volumes without considering the retention period. Purge works only on the" " Catalog database and does not affect data written to Volumes. This command can" " be dangerous because you can delete catalog records associated with current" " backups of files, and we recommend that you do not use it unless you know what" " you are doing.\n" "Press OK to proceed with the purge operation?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } m_console->m_warningPrevent = true; foreach(QString job, m_selectedJobsList) { QString cmd("purge files jobid="); cmd += job; consoleCommand(cmd, false); } m_console->m_warningPrevent = false; populateTable(); } /* * Subroutine to call preRestore to restore from a select job */ void JobList::preRestoreFromJob() { new prerestorePage(m_currentJob, R_JOBIDLIST); } /* * Subroutine to call preRestore to restore from a select job */ void JobList::preRestoreFromTime() { new prerestorePage(m_currentJob, R_JOBDATETIME); } /* * Subroutine to call class to show the log in the database from that job */ void JobList::showLogForJob() { QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); new JobLog(m_currentJob, pageSelectorTreeWidgetItem); } /* * Subroutine to call class to show the log in the database from that job */ void JobList::showInfoForJob(QTableWidgetItem * /*item*/) { QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); new Job(m_currentJob, pageSelectorTreeWidgetItem); } /* * Cancel a running job */ void JobList::consoleCancelJob() { QString cmd("cancel jobid="); cmd += m_currentJob; consoleCommand(cmd); } /* * Save user settings associated with this page */ void JobList::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); settings.setValue(m_splitText, m_splitter->saveState()); settings.setValue("FilterCopyCheckState", filterCopyCheckBox->checkState()); settings.setValue("FilterMigrationCheckState", filterMigrationCheckBox->checkState()); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void JobList::readSettings() { m_groupText = "JobListPage"; m_splitText = "splitterSizes_2"; QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); if (settings.contains(m_splitText)) { m_splitter->restoreState(settings.value(m_splitText).toByteArray()); } filterCopyCheckBox->setCheckState((Qt::CheckState)settings.value("FilterCopyCheckState").toInt()); filterMigrationCheckBox->setCheckState((Qt::CheckState)settings.value("FilterMigrationCheckState").toInt()); settings.endGroup(); } /* * Function to fill m_selectedJobsCount and m_selectedJobs with selected values */ void JobList::selectionChanged() { QList rowList; QList sitems = mp_tableWidget->selectedItems(); foreach (QTableWidgetItem *sitem, sitems) { int row = sitem->row(); if (!rowList.contains(row)) { rowList.append(row); } } m_selectedJobs = ""; m_selectedJobsList.clear(); bool first = true; foreach(int row, rowList) { QTableWidgetItem * sitem = mp_tableWidget->item(row, m_jobIdIndex); if (!first) m_selectedJobs.append(","); else first = false; m_selectedJobs.append(sitem->text()); m_selectedJobsList.append(sitem->text()); } m_selectedJobsCount = rowList.count(); if (m_selectedJobsCount > 1) { QString text = QString( tr("Delete list of %1 Jobs")).arg(m_selectedJobsCount); actionDeleteJob->setText(text); text = QString( tr("Purge Files from list of %1 Jobs")).arg(m_selectedJobsCount); actionPurgeFiles->setText(text); } else { actionDeleteJob->setText(tr("Delete Single Job")); actionPurgeFiles->setText(tr("Purge Files from single job")); } /* remove all actions */ foreach(QAction* mediaAction, mp_tableWidget->actions()) { mp_tableWidget->removeAction(mediaAction); } /* Add Actions */ mp_tableWidget->addAction(actionRefreshJobList); if (m_selectedJobsCount == 1) { mp_tableWidget->addAction(actionListFilesOnJob); mp_tableWidget->addAction(actionListJobMedia); mp_tableWidget->addAction(actionRestartJob); mp_tableWidget->addAction(actionRestoreFromJob); mp_tableWidget->addAction(actionRestoreFromTime); mp_tableWidget->addAction(actionShowLogForJob); mp_tableWidget->addAction(actionShowInfoForJob); } if (m_selectedJobsCount >= 1) { mp_tableWidget->addAction(actionDeleteJob); mp_tableWidget->addAction(actionPurgeFiles); } /* Make Connections */ if (m_checkCurrentWidget) { int row = mp_tableWidget->currentRow(); QTableWidgetItem* jobitem = mp_tableWidget->item(row, 0); m_currentJob = jobitem->text(); /* get JobId */ jobitem = mp_tableWidget->item(row, m_clientIndex); m_clientName = jobitem->text(); /* get Client Name */ jobitem = mp_tableWidget->item(row, m_nameIndex); m_jobName = jobitem->text(); /* get Job Name */ jobitem = mp_tableWidget->item(row, m_levelIndex); m_levelName = jobitem->text(); /* get level */ jobitem = mp_tableWidget->item(row, m_filesetIndex); if (jobitem) { m_filesetName = jobitem->text(); /* get FileSet Name */ } else { m_filesetName = ""; } /* include purged action or not */ jobitem = mp_tableWidget->item(row, m_purgedIndex); QString purged = jobitem->text(); /* mp_tableWidget->removeAction(actionPurgeFiles); if (purged == tr("No") ) { mp_tableWidget->addAction(actionPurgeFiles); }*/ /* include restore from time and job action or not */ jobitem = mp_tableWidget->item(row, m_typeIndex); QString type = jobitem->text(); if (m_selectedJobsCount == 1) { mp_tableWidget->removeAction(actionRestoreFromJob); mp_tableWidget->removeAction(actionRestoreFromTime); if (type == tr("Backup")) { mp_tableWidget->addAction(actionRestoreFromJob); mp_tableWidget->addAction(actionRestoreFromTime); } } /* include cancel action or not */ jobitem = mp_tableWidget->item(row, m_statusIndex); QString status = jobitem->text(); mp_tableWidget->removeAction(actionCancelJob); if (status == tr("Running") || status == tr("Created, not yet running")) { mp_tableWidget->addAction(actionCancelJob); } } } /* * Function to prevent the splitter from making index 0 of the size larger than it * needs to be */ void JobList::splitterMoved(int /*pos*/, int /*index*/) { int frameMax = frame->maximumHeight(); QList sizes = m_splitter->sizes(); int sizeSum = 0; foreach(int size, sizes) { sizeSum += size; } if (sizes[0] > frameMax) { sizes[0] = frameMax; sizes[1] = sizeSum - frameMax; m_splitter->setSizes(sizes); } } bareos-Release-14.2.6/src/qt-console/joblist/joblist.h000066400000000000000000000051311263011562700226000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _JOBLIST_H_ #define _JOBLIST_H_ #include #include "ui_joblist.h" #include "console/console.h" #include "pages.h" class JobList : public Pages, public Ui::JobListForm { Q_OBJECT public: JobList(const QString &medianame, const QString &clientname, const QString &jobname, const QString &filesetname, QTreeWidgetItem *); ~JobList(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); int m_resultCount; public slots: void populateTable(); virtual void treeWidgetName(QString &); void selectionChanged(); private slots: void consoleListFilesOnJob(); void consoleListJobMedia(); void consoleListJobTotals(); void consoleDeleteJob(); void consoleRestartJob(); void consolePurgeFiles(); void preRestoreFromJob(); void preRestoreFromTime(); void showLogForJob(); void showInfoForJob(QTableWidgetItem * item=NULL); void consoleCancelJob(); void splitterMoved(int pos, int index); private: void createConnections(); void writeSettings(); void readSettings(); void prepareFilterWidgets(); void fillQueryString(QString &query); QSplitter *m_splitter; QString m_groupText; QString m_splitText; QString m_mediaName; QString m_clientName; QString m_jobName; QString m_filesetName; QString m_currentJob; QString m_levelName; bool m_populated; bool m_checkCurrentWidget; int m_jobIdIndex; int m_purgedIndex; int m_typeIndex; int m_levelIndex; int m_clientIndex; int m_nameIndex; int m_filesetIndex; int m_statusIndex; int m_startIndex; int m_bytesIndex; int m_filesIndex; int m_selectedJobsCount; QString m_selectedJobs; QStringList m_selectedJobsList; }; #endif /* _JOBLIST_H_ */ bareos-Release-14.2.6/src/qt-console/joblist/joblist.ui000066400000000000000000000323301263011562700227670ustar00rootroot00000000000000 JobListForm 0 0 696 456 Form 60 10 457 131 50 190 541 171 900 172 QFrame::StyledPanel QFrame::Raised 6 3 6 3 Record Limit 1 10000 25 6 3 Days Limit 7 6 3 6 3 Clients 6 3 Volume 6 3 6 3 Job 6 3 Level 6 3 6 3 Status 6 3 Purged 3 6 3 FileSet 6 3 Pool 3 3 Refresh :/images/view-refresh.png:/images/view-refresh.png Graph :/images/applications-graphics.png:/images/applications-graphics.png Filter Copy Jobs Filter Migration Jobs :/images/view-refresh.png:/images/view-refresh.png Refresh Job List Requery the director for the list of jobs. :/images/utilities-terminal.png:/images/utilities-terminal.png List Files On Job :/images/utilities-terminal.png:/images/utilities-terminal.png List Job Volumes :/images/utilities-terminal.png:/images/utilities-terminal.png List Volumes :/images/weather-severe-alert.png:/images/weather-severe-alert.png Delete Job :/images/weather-severe-alert.png:/images/weather-severe-alert.png Purge Files :/images/weather-severe-alert.png:/images/weather-severe-alert.png Restart Job :/images/restore.png:/images/restore.png Restore From Job :/images/restore.png:/images/restore.png Restore From Time :/images/joblog.png:/images/joblog.png Show Job Log :/images/joblog.png:/images/joblog.png Show Job Info :/images/unmark.png:/images/unmark.png Cancel Currently Running Job :/images/utilities-terminal.png:/images/utilities-terminal.png List Job Totals on Console bareos-Release-14.2.6/src/qt-console/joblog/000077500000000000000000000000001263011562700205675ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/joblog/joblog.cpp000066400000000000000000000112311263011562700225450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * JobLog Class * * Dirk Bartley, March 2007 */ #include "bat.h" #include "joblog.h" JobLog::JobLog(QString &jobId, QTreeWidgetItem *parentTreeWidgetItem) : Pages() { setupUi(this); pgInitialize(tr("JobLog"), parentTreeWidgetItem); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/joblog.png"))); m_cursor = new QTextCursor(textEdit->document()); m_jobId = jobId; getFont(); populateText(); dockPage(); setCurrent(); } void JobLog::getFont() { QFont font = textEdit->font(); QString dirname; m_console->getDirResName(dirname); QSettings settings(dirname, "bat"); settings.beginGroup("Console"); font.setFamily(settings.value("consoleFont", "Courier").value()); font.setPointSize(settings.value("consolePointSize", 10).toInt()); font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool()); settings.endGroup(); textEdit->setFont(font); } /* * Populate the text in the window */ void JobLog::populateText() { QString query; query = "SELECT Time, LogText FROM Log WHERE JobId='" + m_jobId + "' order by Time"; /* This could be a log item */ if (mainWin->m_sqlDebug) { Pmsg1(000, "Log query cmd : %s\n", query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { if (!results.size()) { QMessageBox::warning(this, tr("Bat"), tr("There were no results!\n" "It is possible you may need to add \"catalog = all\" " "to the Messages resource for this job.\n"), QMessageBox::Ok); return; } QString jobstr("JobId "); /* FIXME: should this be translated ? */ jobstr += m_jobId; QString htmlbuf("" + tr("Log records for job %1").arg(m_jobId) ); htmlbuf += "
" + curTime + "" + curTime + "
"; /* Iterate through the lines of results. */ QString field; QStringList fieldlist; QString lastTime; QString lastSvc; foreach (QString resultline, results) { fieldlist = resultline.split("\t"); if (fieldlist.size() < 2) continue; htmlbuf +=""; QString curTime = fieldlist[0].trimmed(); field = fieldlist[1].trimmed(); int colon = field.indexOf(":"); if (colon > 0) { /* string is like : ..." * we split at ':' then remove the jobId xxxx string (always the same) */ QString curSvc(field.left(colon).replace(jobstr,"").trimmed()); if (curSvc == lastSvc && curTime == lastTime) { curTime.clear(); curSvc.clear(); } else { lastTime = curTime; lastSvc = curSvc; } htmlbuf += ""; htmlbuf += ""; /* rest of string is marked as pre-formatted (here trimming should * be avoided, to preserve original formatting) */ QString msg(field.mid(colon+2)); if (msg.startsWith( tr("Error:")) ) { /* FIXME: should really be translated ? */ /* error msg, use a specific class */ htmlbuf += ""; } else { htmlbuf += ""; } } else { /* non standard string, place as-is */ if (curTime == lastTime) { curTime.clear(); } else { lastTime = curTime; } htmlbuf += ""; htmlbuf += ""; } htmlbuf += ""; } /* foreach resultline */ htmlbuf += "
" + curTime + "

" + curSvc + "

" + msg + "
" + msg + "
" + curTime + "
" + field + "
"; /* full text ready. Here a custom sheet is used to align columns */ QString logSheet("p,pre,.err {margin-left: 10px} .err {color:#FF0000;}"); textEdit->document()->setDefaultStyleSheet(logSheet); textEdit->document()->setHtml(htmlbuf); textEdit->moveCursor(QTextCursor::Start); } /* if results from query */ } bareos-Release-14.2.6/src/qt-console/joblog/joblog.h000066400000000000000000000023701263011562700222160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _JOBLOG_H_ #define _JOBLOG_H_ #include #include "ui_joblog.h" #include class JobLog : public Pages, public Ui::JobLogForm { Q_OBJECT public: JobLog(QString &jobId, QTreeWidgetItem *parentTreeWidgetItem); public slots: private slots: private: void populateText(); void getFont(); QTextCursor *m_cursor; QString m_jobId; }; #endif /* _JOBLOG_H_ */ bareos-Release-14.2.6/src/qt-console/joblog/joblog.ui000066400000000000000000000041541263011562700224060ustar00rootroot00000000000000 JobLogForm 0 0 432 456 Job Log 9 6 7 7 200 0 0 0 1 0 Qt::StrongFocus false Qt::ScrollBarAsNeeded QTextEdit::AutoNone false QTextEdit::NoWrap true bareos-Release-14.2.6/src/qt-console/jobs/000077500000000000000000000000001263011562700202505ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/jobs/jobs.cpp000066400000000000000000000211671263011562700217200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Jobs Class * * Dirk Bartley, March 2007 */ #include "bat.h" #include "jobs/jobs.h" #include "run/run.h" #include "util/fmtwidgetitem.h" Jobs::Jobs() : Pages() { setupUi(this); m_name = tr("Jobs"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/run.png"))); /* tableWidget, Storage Tree Tree Widget inherited from ui_client.h */ m_populated = false; m_checkcurwidget = true; m_closeable = false; /* add context sensitive menu items specific to this classto the page * selector tree. m_contextActions is QList of QActions */ m_contextActions.append(actionRefreshJobs); createContextMenu(); connect(tableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(runJob())); } Jobs::~Jobs() { } /* * The main meat of the class!! The function that querries the director and * creates the widgets with appropriate values. */ void Jobs::populateTable() { m_populated = true; mainWin->waitEnter(); Freeze frz(*tableWidget); /* disable updating*/ QBrush blackBrush(Qt::black); m_checkcurwidget = false; tableWidget->clear(); m_checkcurwidget = true; QStringList headerlist = (QStringList() << tr("Job Name") << tr("Pool") << tr("Messages") << tr("Client") << tr("Storage") << tr("Level") << tr("Type") << tr("FileSet") << tr("Catalog") << tr("Enabled") << tr("Where")); m_typeIndex = headerlist.indexOf(tr("Type")); tableWidget->setColumnCount(headerlist.count()); tableWidget->setHorizontalHeaderLabels(headerlist); tableWidget->horizontalHeader()->setHighlightSections(false); tableWidget->setRowCount(m_console->job_list.count()); tableWidget->verticalHeader()->hide(); tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */ int row = 0; foreach (QString jobName, m_console->job_list){ job_defaults job_defs; job_defs.job_name = jobName; if (m_console->get_job_defaults(job_defs)) { int col = 0; TableItemFormatter jobsItem(*tableWidget, row); jobsItem.setTextFld(col++, jobName); jobsItem.setTextFld(col++, job_defs.pool_name); jobsItem.setTextFld(col++, job_defs.messages_name); jobsItem.setTextFld(col++, job_defs.client_name); jobsItem.setTextFld(col++, job_defs.store_name); jobsItem.setTextFld(col++, job_defs.level); jobsItem.setTextFld(col++, job_defs.type); jobsItem.setTextFld(col++, job_defs.fileset_name); jobsItem.setTextFld(col++, job_defs.catalog_name); jobsItem.setBoolFld(col++, job_defs.enabled); jobsItem.setTextFld(col++, job_defs.where); } row++; } /* set default sorting */ tableWidget->sortByColumn(headerlist.indexOf(tr("Job Name")), Qt::AscendingOrder); tableWidget->setSortingEnabled(true); /* Resize rows and columns */ tableWidget->resizeColumnsToContents(); tableWidget->resizeRowsToContents(); /* make read only */ tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); mainWin->waitExit(); dockPage(); } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void Jobs::PgSeltreeWidgetClicked() { if(!m_populated) { populateTable(); } } /* * Added to set the context menu policy based on currently active tableWidgetItem * signaled by currentItemChanged */ void Jobs::tableItemChanged(QTableWidgetItem *currentwidgetitem, QTableWidgetItem *previouswidgetitem ) { /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */ if (m_checkcurwidget && currentwidgetitem) { /* The Previous item */ if (previouswidgetitem) { /* avoid a segfault if first time */ foreach(QAction* jobAction, tableWidget->actions()) { tableWidget->removeAction(jobAction); } } int currentRow = currentwidgetitem->row(); QTableWidgetItem *currentrowzeroitem = tableWidget->item(currentRow, 0); m_currentlyselected = currentrowzeroitem->text(); QTableWidgetItem *currenttypeitem = tableWidget->item(currentRow, m_typeIndex); QString type = currenttypeitem->text(); if (m_currentlyselected.length() != 0) { /* set a hold variable to the client name in case the context sensitive * menu is used */ tableWidget->addAction(actionRefreshJobs); tableWidget->addAction(actionConsoleListFiles); tableWidget->addAction(actionConsoleListVolumes); tableWidget->addAction(actionConsoleListNextVolume); tableWidget->addAction(actionConsoleEnableJob); tableWidget->addAction(actionConsoleDisableJob); tableWidget->addAction(actionConsoleCancel); tableWidget->addAction(actionJobListQuery); tableWidget->addAction(actionRunJob); } } } /* * Setup a context menu * Made separate from populate so that it would not create context menu over and * over as the table is repopulated. */ void Jobs::createContextMenu() { tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu); tableWidget->addAction(actionRefreshJobs); connect(tableWidget, SIGNAL( currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)), this, SLOT(tableItemChanged(QTableWidgetItem *, QTableWidgetItem *))); /* connect to the action specific to this pages class */ connect(actionRefreshJobs, SIGNAL(triggered()), this, SLOT(populateTable())); connect(actionConsoleListFiles, SIGNAL(triggered()), this, SLOT(consoleListFiles())); connect(actionConsoleListVolumes, SIGNAL(triggered()), this, SLOT(consoleListVolume())); connect(actionConsoleListNextVolume, SIGNAL(triggered()), this, SLOT(consoleListNextVolume())); connect(actionConsoleEnableJob, SIGNAL(triggered()), this, SLOT(consoleEnable())); connect(actionConsoleDisableJob, SIGNAL(triggered()), this, SLOT(consoleDisable())); connect(actionConsoleCancel, SIGNAL(triggered()), this, SLOT(consoleCancel())); connect(actionJobListQuery, SIGNAL(triggered()), this, SLOT(listJobs())); connect(actionRunJob, SIGNAL(triggered()), this, SLOT(runJob())); } /* * Virtual function which is called when this page is visible on the stack */ void Jobs::currentStackItem() { if(!m_populated) { /* Create the context menu for the client table */ populateTable(); } } /* * The following functions are slots responding to users clicking on the context * sensitive menu */ void Jobs::consoleListFiles() { QString cmd = "list files job=\"" + m_currentlyselected + "\""; if (mainWin->m_longList) { cmd.prepend("l"); } consoleCommand(cmd); } void Jobs::consoleListVolume() { QString cmd = "list volumes job=\"" + m_currentlyselected + "\""; if (mainWin->m_longList) { cmd.prepend("l"); } consoleCommand(cmd); } void Jobs::consoleListNextVolume() { QString cmd = "list nextvolume job=\"" + m_currentlyselected + "\""; if (mainWin->m_longList) { cmd.prepend("l"); } consoleCommand(cmd); } void Jobs::consoleEnable() { QString cmd = "enable job=\"" + m_currentlyselected + "\""; consoleCommand(cmd); } void Jobs::consoleDisable() { QString cmd = "disable job=\"" + m_currentlyselected + "\""; consoleCommand(cmd); } void Jobs::consoleCancel() { QString cmd = "cancel job=\"" + m_currentlyselected + "\""; consoleCommand(cmd); } void Jobs::listJobs() { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); mainWin->createPageJobList("", "", m_currentlyselected, "", parentItem); } /* * Open a new job run page with the currently selected job * defaulted In */ void Jobs::runJob() { new runPage(m_currentlyselected); } bareos-Release-14.2.6/src/qt-console/jobs/jobs.h000066400000000000000000000031351263011562700213600ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _JOBS_H_ #define _JOBS_H_ #include #include "ui_jobs.h" #include class Jobs : public Pages, public Ui::jobsForm { Q_OBJECT public: Jobs(); ~Jobs(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void tableItemChanged(QTableWidgetItem *, QTableWidgetItem *); private slots: void populateTable(); void consoleListFiles(); void consoleListVolume(); void consoleListNextVolume(); void consoleEnable(); void consoleDisable(); void consoleCancel(); void listJobs(); void runJob(); private: void createContextMenu(); QString m_currentlyselected; bool m_populated; bool m_checkcurwidget; int m_typeIndex; }; #endif /* _JOBS_H_ */ bareos-Release-14.2.6/src/qt-console/jobs/jobs.ui000066400000000000000000000107601263011562700215500ustar00rootroot00000000000000 jobsForm 0 0 449 307 Client Tree :/images/view-refresh.png Refresh Jobs List Requery the director for the list of clients. :/images/utilities-terminal.png List Files Command List Files Command List Files Command List Files Command :/images/utilities-terminal.png List Volumes Command List Volumes Command List Volumes Command List Volumes Command :/images/utilities-terminal.png List Next Volume Command List Next Volume Command List Next Volume Command List Next Volume Command :/images/utilities-terminal.png Enable Job Command Enable Job Command Enable Job Command Enable Job Command :/images/utilities-terminal.png Disable Job Command Disable Job Command Disable Job Command Disable Job Command :/images/emblem-system.png Open JobList on Job Open JobList on Job Open JobList on Job Open JobList on Job :/images/utilities-terminal.png Cancel Job Command Cancel Job Command :/images/run.png RunJob bareos-Release-14.2.6/src/qt-console/label/000077500000000000000000000000001263011562700203725ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/label/label.cpp000066400000000000000000000070721263011562700221630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Label Page class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "label.h" #include labelPage::labelPage() : Pages() { QString deflt(""); m_closeable = false; showPage(deflt); } /* * An overload of the constructor to have a default storage show in the * combobox on start. Used from context sensitive in storage class. */ labelPage::labelPage(QString &defString) : Pages() { showPage(defString); } /* * moved the constructor code here for the overload. */ void labelPage::showPage(QString &defString) { m_name = "Label"; pgInitialize(); setupUi(this); m_conn = m_console->notifyOff(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/label.png"))); storageCombo->addItems(m_console->storage_list); int index = storageCombo->findText(defString, Qt::MatchExactly); if (index != -1) { storageCombo->setCurrentIndex(index); } poolCombo->addItems(m_console->pool_list); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); connect(automountOnButton, SIGNAL(pressed()), this, SLOT(automountOnButtonPushed())); connect(automountOffButton, SIGNAL(pressed()), this, SLOT(automountOffButtonPushed())); dockPage(); setCurrent(); this->show(); } void labelPage::okButtonPushed() { QString scmd; if (volumeName->text().toUtf8().data()[0] == 0) { QMessageBox::warning(this, "No Volume name", "No Volume name given", QMessageBox::Ok, QMessageBox::Ok); return; } this->hide(); scmd = QString("label volume=\"%1\" pool=\"%2\" storage=\"%3\" slot=%4") .arg(volumeName->text()) .arg(poolCombo->currentText()) .arg(storageCombo->currentText()) .arg(slotSpin->value()); if (mainWin->m_commandDebug) { Pmsg1(000, "sending command : %s\n", scmd.toUtf8().data()); } if (m_console) { m_console->write_dir(scmd.toUtf8().data()); m_console->displayToPrompt(m_conn); m_console->notify(m_conn, true); } else { Pmsg0(000, "m_console==NULL !!!!!!\n"); } closeStackPage(); mainWin->resetFocus(); } void labelPage::cancelButtonPushed() { this->hide(); if (m_console) { m_console->notify(m_conn, true); } else { Pmsg0(000, "m_console==NULL !!!!!!\n"); } closeStackPage(); mainWin->resetFocus(); } /* turn automount on */ void labelPage::automountOnButtonPushed() { QString cmd("automount on"); consoleCommand(cmd); } /* turn automount off */ void labelPage::automountOffButtonPushed() { QString cmd("automount off"); consoleCommand(cmd); } bareos-Release-14.2.6/src/qt-console/label/label.h000066400000000000000000000024661263011562700216320ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, February MMVII */ #ifndef _LABEL_H_ #define _LABEL_H_ #include #include "ui_label.h" #include "pages.h" class labelPage : public Pages, public Ui::labelForm { Q_OBJECT public: labelPage(); labelPage(QString &defString); void showPage(QString &defString); private slots: void okButtonPushed(); void cancelButtonPushed(); void automountOnButtonPushed(); void automountOffButtonPushed(); private: int m_conn; }; #endif /* _LABEL_H_ */ bareos-Release-14.2.6/src/qt-console/label/label.ui000066400000000000000000000200051263011562700220050ustar00rootroot00000000000000 labelForm 0 0 560 357 Qt::NoFocus Form 9 6 Qt::Vertical QSizePolicy::Expanding 421 48 Qt::Vertical QSizePolicy::Expanding 431 48 0 6 6 0 Qt::Horizontal 40 20 OK true Cancel Volume Name: volumeName Storage: storageCombo 200 0 Qt::StrongFocus Enter Name of Volume to create 10000 Slot: slotSpin 6 0 Execute Automount On Off Qt::Vertical 20 61 Pool: poolCombo 6 0 Qt::Horizontal 71 21 16777215 30 <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Label a Volume</span></p></body></html> Qt::Horizontal 81 20 Qt::Horizontal 40 131 Qt::Horizontal 40 121 bareos-Release-14.2.6/src/qt-console/main.cpp000066400000000000000000000157171263011562700207560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main program for bat (qt-console) * * Kern Sibbald, January MMVII */ #include "bat.h" #include #include /* * We need Qt version 4.7.4 or later to be able to comple correctly */ #if QT_VERSION < 0x040602 #error "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #error "You need Qt version 4.6.2 or later to build Bat" #error "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #endif MainWin *mainWin; QApplication *app; /* Forward referenced functions */ void terminate_console(int sig); static void usage(); static int check_resources(); extern bool parse_bat_config(CONFIG *config, const char *configfile, int exit_code); extern void message_callback(int /* type */, char *msg); CONFIG *my_config = NULL; /* Our Global config */ #define CONFIG_FILE "bat.conf" /* default configuration file */ /* Static variables */ static char *configfile = NULL; int main(int argc, char *argv[]) { int ch; bool no_signals = true; bool test_config = false; app = new QApplication(argc, argv); app->setQuitOnLastWindowClosed(true); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTranslator qtTranslator; qtTranslator.load(QString("qt_") + QLocale::system().name(),QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app->installTranslator(&qtTranslator); QTranslator batTranslator; batTranslator.load(QString("bat_") + QLocale::system().name(),QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app->installTranslator(&batTranslator); register_message_callback(message_callback); #ifdef xENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); #endif #ifdef HAVE_WIN32 set_trace(true); /* output to trace file */ #endif init_stack_dump(); my_name_is(argc, argv, "bat"); lmgr_init_thread(); init_msg(NULL, NULL); working_directory = "/tmp"; struct sigaction sigignore; sigignore.sa_flags = 0; sigignore.sa_handler = SIG_IGN; sigfillset(&sigignore.sa_mask); sigaction(SIGPIPE, &sigignore, NULL); sigaction(SIGUSR2, &sigignore, NULL); while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': debug_level = atoi(optarg); if (debug_level <= 0) debug_level = 1; break; case 's': /* turn off signals */ no_signals = true; break; case 't': test_config = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (!no_signals) { init_signals(terminate_console); } if (argc) { usage(); } OSDependentInit(); #ifdef HAVE_WIN32 WSA_Init(); /* Initialize Windows sockets */ #endif if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_bat_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Emsg0(M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n")); } if (!check_resources()) { Emsg1(M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); } if (test_config) { exit(0); } mainWin = new MainWin; mainWin->show(); return app->exec(); } void terminate_console(int /*sig*/) { // WSA_Cleanup(); /* TODO: check when we have to call it */ exit(0); } static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s) %s %s %s\n\n" "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n" " -c set configuration file to file\n" " -dnn set debug level to nn\n" " -s no signals\n" " -t test - read configuration and exit\n" " -? print this message.\n" "\n"), 2007, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER); exit(1); } /* * Make a quick check to see that we have all the * resources needed. */ static int check_resources() { bool ok = true; DIRRES *director; int numdir; bool tls_needed; LockRes(); numdir = 0; foreach_res(director, R_DIRECTOR) { numdir++; /* tls_require implies tls_enable */ if (director->tls_require) { if (have_tls) { director->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); ok = false; continue; } } tls_needed = director->tls_enable || director->tls_authenticate; if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed) { Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s." " At least one CA certificate store is required.\n"), director->hdr.name, configfile); ok = false; } } if (numdir == 0) { Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n" "Without that I don't how to speak to the Director :-(\n"), configfile); ok = false; } CONRES *cons; /* Loop over Consoles */ foreach_res(cons, R_CONSOLE) { /* tls_require implies tls_enable */ if (cons->tls_require) { if (have_tls) { cons->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); ok = false; continue; } } tls_needed = cons->tls_enable || cons->tls_authenticate; if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && tls_needed) { Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in %s.\n"), cons->hdr.name, configfile); ok = false; } } UnlockRes(); return ok; } bareos-Release-14.2.6/src/qt-console/main.qrc000066400000000000000000000062471263011562700207570ustar00rootroot00000000000000 ../images/page-prev.gif ../images/page-next.gif ../images/0p.png ../images/16p.png ../images/32p.png ../images/48p.png ../images/64p.png ../images/80p.png ../images/96p.png ../images/A.png ../images/R.png ../images/T.png ../images/W.png ../images/applications-graphics.png ../images/bat.png ../images/bat.svg ../images/browse.png ../images/cartridge-edit.png ../images/cartridge.png ../images/check.png ../images/connected.png ../images/copy.png ../images/cut.png ../images/disconnected.png ../images/edit-cut.png ../images/edit-delete.png ../images/edit.png ../images/emblem-system.png ../images/estimate-job.png ../images/extern.png ../images/f.png ../images/folder.png ../images/folderbothchecked.png ../images/folderchecked.png ../images/folderunchecked.png ../images/go-down.png ../images/go-jump.png ../images/go-up.png ../images/graph1.png ../images/help-browser.png ../images/inflag0.png ../images/inflag1.png ../images/inflag2.png ../images/intern.png ../images/joblog.png ../images/label.png ../images/mail-message-new.png ../images/mail-message-pending.png ../images/mark.png ../images/network-server.png ../images/new.png ../images/open.png ../images/package-x-generic.png ../images/paste.png ../images/print.png ../images/purge.png ../images/restore.png ../images/run.png ../images/runit.png ../images/save.png ../images/status-console.png ../images/status.png ../images/system-file-manager.png ../images/unchecked.png ../images/undo.png ../images/unmark.png ../images/up.png ../images/utilities-terminal.png ../images/view-refresh.png ../images/weather-severe-alert.png ../images/zoom.png ../images/bareos_1.png ../images/bareos_2.png bareos-Release-14.2.6/src/qt-console/main.ui000066400000000000000000000377551263011562700206170ustar00rootroot00000000000000 Kern Sibbald MainForm 0 0 785 660 bat - Bareos Admin Tool :/images/bareos_1.png:/images/bareos_1.png Bareos Administration Tool It's a Dock widget to allow page selection 9 6 -1 0 0 785 25 Settings &Help &File Current Status Current Status 51 39 Tool Bar Qt::Horizontal TopToolBarArea false 0 1 112 179 524287 524287 Qt::StrongFocus false QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt::AllDockWidgetAreas 1 1 1 0 0 16777215 16777215 0 0 Qt::StrongFocus Selects panel window Use items in this tree to select what window is in panel true 1 Command: Click here to enter command &Quit Ctrl+Q :/images/bareos_1.png:/images/bareos_1.png &About bat :/images/copy.png:/images/copy.png &Copy :/images/cut.png:/images/cut.png Cu&t :/images/new.png:/images/new.png new :/images/open.png:/images/open.png open :/images/paste.png:/images/paste.png &Paste :/images/print.png:/images/print.png &Print Print :/images/save.png:/images/save.png &Save Save (not implemented) :/images/disconnected.png:/images/disconnected.png Connect Connect/disconnect :/images/label.png:/images/label.png Label Label a Volume Label a Volume :/images/restore.png:/images/restore.png Restore Restore Files false :/images/run.png:/images/run.png Run Job Run Job Run Job Run a Job false :/images/estimate-job.png:/images/estimate-job.png Estimate Job Estimate Job Estimate Job Estimate a Job :/images/status-console.png:/images/status-console.png Status Dir Status Dir Query status of director in console Query status of director in console true &Select Font ... :/images/up.png:/images/up.png Undock Window Undock Current Window :/images/up.png:/images/up.png ToggleDock Toggle Dock Status Toggle Dock Status :/images/unmark.png:/images/unmark.png Close Page Close The Current Page :/images/mail-message-new.png:/images/mail-message-new.png Messages Display any messages queued at the director false &Preferences ... Set Preferences Set Preferences :/images/help-browser.png:/images/help-browser.png bat &Help :/images/browse.png:/images/browse.png Browse Browse Cataloged Files Browse Cataloged Files :/images/applications-graphics.png:/images/applications-graphics.png JobPlot Plot Job Files and Bytes Plot Job Files and Bytes :/images/status.png:/images/status.png Status Dir Page Director Status Page :/images/mark.png:/images/mark.png Repop Lists :/images/mark.png:/images/mark.png Reload and Repop :/images/go-jump.png:/images/go-jump.png back Previous Page Previous Page bareos-Release-14.2.6/src/qt-console/mainwin.cpp000066400000000000000000001077311263011562700214720ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main Window control for bat (qt-console) * * Kern Sibbald, January MMVII */ #include "bat.h" #include "version.h" #include "joblist/joblist.h" #include "storage/storage.h" #include "fileset/fileset.h" #include "label/label.h" #include "run/run.h" #include "pages.h" #include "restore/restore.h" #include "medialist/medialist.h" #include "joblist/joblist.h" #include "clients/clients.h" #include "restore/restoretree.h" #include "help/help.h" #include "jobs/jobs.h" #include "medialist/mediaview.h" #include "status/dirstat.h" #include "util/fmtwidgetitem.h" /* * Daemon message callback */ void message_callback(int /* type */, char *msg) { QMessageBox::warning(mainWin, "Bat", msg, QMessageBox::Ok); } MainWin::MainWin(QWidget *parent) : QMainWindow(parent) { app->setOverrideCursor(QCursor(Qt::WaitCursor)); m_isClosing = false; m_waitState = false; m_doConnect = false; m_treeStackTrap = false; m_dtformat = "yyyy-MM-dd HH:mm:ss"; mainWin = this; setupUi(this); /* Setup UI defined by main.ui (designer) */ register_message_callback(message_callback); readPreferences(); treeWidget->clear(); treeWidget->setColumnCount(1); treeWidget->setHeaderLabel( tr("Select Page") ); treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu); tabWidget->setTabsClosable(true); /* wait for QT 4.5 */ createPages(); resetFocus(); /* lineEdit->setFocus() */ this->show(); readSettings(); foreach(Console *console, m_consoleHash) { console->connect_dir(); } /* * Note, the notifier is now a global flag, although each notifier * can be individually turned on and off at a socket level. Once * the notifier is turned off, we don't accept anything from anyone * this prevents unwanted messages from getting into the input * dialogs such as restore that read from the director and "know" * what to expect. */ m_notify = true; m_currentConsole = (Console*)getFromHash(m_firstItem); QTimer::singleShot(2000, this, SLOT(popLists())); if (m_miscDebug) { QString directoryResourceName; m_currentConsole->getDirResName(directoryResourceName); Pmsg1(100, "Setting initial window to %s\n", directoryResourceName.toUtf8().data()); } app->restoreOverrideCursor(); } void MainWin::popLists() { foreach(Console *console, m_consoleHash) { console->populateLists(true); } m_doConnect = true; connectConsoleSignals(); connectSignals(); app->restoreOverrideCursor(); m_currentConsole->setCurrent(); } void MainWin::createPages() { DIRRES *dir; QTreeWidgetItem *item, *topItem; m_firstItem = NULL; LockRes(); foreach_res(dir, R_DIRECTOR) { /* Create console tree stacked widget item */ m_currentConsole = new Console(tabWidget); m_currentConsole->setDirRes(dir); m_currentConsole->readSettings(); /* The top tree item representing the director */ topItem = new QTreeWidgetItem(treeWidget); topItem->setText(0, dir->name()); topItem->setIcon(0, QIcon(":images/server.png")); /* Set background to grey for ease of identification of inactive Director */ QBrush greyBrush(Qt::lightGray); topItem->setBackground(0, greyBrush); m_currentConsole->setDirectorTreeItem(topItem); m_consoleHash.insert(topItem, m_currentConsole); /* Create Tree Widget Item */ item = new QTreeWidgetItem(topItem); item->setText(0, tr("Console")); if (!m_firstItem){ m_firstItem = item; } item->setIcon(0,QIcon(QString::fromUtf8(":images/utilities-terminal.png"))); /* insert the cosole and tree widget item into the hashes */ hashInsert(item, m_currentConsole); m_currentConsole->dockPage(); /* Set Color of treeWidgetItem for the console * It will be set to green in the console class if the connection is made. */ QBrush redBrush(Qt::red); item->setForeground(0, redBrush); /* * Create instances in alphabetic order of the rest * of the classes that will by default exist under each Director. */ new bRestore(); new Clients(); new FileSet(); new Jobs(); createPageJobList("", "", "", "", NULL); new MediaList(); new MediaView(); new Storage(); if (m_openBrowser) { new restoreTree(); } if (m_openDirStat) { new DirStat(); } treeWidget->expandItem(topItem); tabWidget->setCurrentWidget(m_currentConsole); } UnlockRes(); } /* * create an instance of the the joblist class on the stack */ void MainWin::createPageJobList(const QString &media, const QString &client, const QString &job, const QString &fileset, QTreeWidgetItem *parentTreeWidgetItem) { QTreeWidgetItem *holdItem; /* save current tree widget item in case query produces no results */ holdItem = treeWidget->currentItem(); JobList* joblist = new JobList(media, client, job, fileset, parentTreeWidgetItem); /* If this is a query of jobs on a specific media */ if ((media != "") || (client != "") || (job != "") || (fileset != "")) { joblist->setCurrent(); /* did query produce results, if not close window and set back to hold */ if (joblist->m_resultCount == 0) { joblist->closeStackPage(); treeWidget->setCurrentItem(holdItem); } } } /* * Handle up and down arrow keys for the command line * history. */ void MainWin::keyPressEvent(QKeyEvent *event) { if (m_cmd_history.size() == 0) { event->ignore(); return; } switch (event->key()) { case Qt::Key_Down: if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) { event->ignore(); return; } m_cmd_last++; break; case Qt::Key_Up: if (m_cmd_last == 0) { event->ignore(); return; } if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) { m_cmd_last = m_cmd_history.size() - 1; } else { m_cmd_last--; } break; default: event->ignore(); return; } lineEdit->setText(m_cmd_history[m_cmd_last]); } void MainWin::connectSignals() { /* Connect signals to slots */ connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line())); connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about())); connect(actionBat_Help, SIGNAL(triggered()), this, SLOT(help())); connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(treeItemClicked(QTreeWidgetItem *, int))); connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(stackItemChanged(int))); connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closePage(int))); connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows())); connect(actionLabel, SIGNAL(triggered()), this, SLOT(labelButtonClicked())); connect(actionRun, SIGNAL(triggered()), this, SLOT(runButtonClicked())); connect(actionEstimate, SIGNAL(triggered()), this, SLOT(estimateButtonClicked())); connect(actionBrowse, SIGNAL(triggered()), this, SLOT(browseButtonClicked())); connect(actionStatusDirPage, SIGNAL(triggered()), this, SLOT(statusPageButtonClicked())); connect(actionRestore, SIGNAL(triggered()), this, SLOT(restoreButtonClicked())); connect(actionUndock, SIGNAL(triggered()), this, SLOT(undockWindowButton())); connect(actionToggleDock, SIGNAL(triggered()), this, SLOT(toggleDockContextWindow())); connect(actionClosePage, SIGNAL(triggered()), this, SLOT(closeCurrentPage())); connect(actionPreferences, SIGNAL(triggered()), this, SLOT(setPreferences())); connect(actionRepopLists, SIGNAL(triggered()), this, SLOT(repopLists())); connect(actionReloadRepop, SIGNAL(triggered()), this, SLOT(reloadRepopLists())); } void MainWin::disconnectSignals() { /* Connect signals to slots */ disconnect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line())); disconnect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about())); disconnect(actionBat_Help, SIGNAL(triggered()), this, SLOT(help())); disconnect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(treeItemClicked(QTreeWidgetItem *, int))); disconnect(treeWidget, SIGNAL( currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); disconnect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(stackItemChanged(int))); disconnect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closePage(int))); disconnect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows())); disconnect(actionLabel, SIGNAL(triggered()), this, SLOT(labelButtonClicked())); disconnect(actionRun, SIGNAL(triggered()), this, SLOT(runButtonClicked())); disconnect(actionEstimate, SIGNAL(triggered()), this, SLOT(estimateButtonClicked())); disconnect(actionBrowse, SIGNAL(triggered()), this, SLOT(browseButtonClicked())); disconnect(actionStatusDirPage, SIGNAL(triggered()), this, SLOT(statusPageButtonClicked())); disconnect(actionRestore, SIGNAL(triggered()), this, SLOT(restoreButtonClicked())); disconnect(actionUndock, SIGNAL(triggered()), this, SLOT(undockWindowButton())); disconnect(actionToggleDock, SIGNAL(triggered()), this, SLOT(toggleDockContextWindow())); disconnect(actionClosePage, SIGNAL(triggered()), this, SLOT(closeCurrentPage())); disconnect(actionPreferences, SIGNAL(triggered()), this, SLOT(setPreferences())); disconnect(actionRepopLists, SIGNAL(triggered()), this, SLOT(repopLists())); disconnect(actionReloadRepop, SIGNAL(triggered()), this, SLOT(reloadRepopLists())); } /* * Enter wait state */ void MainWin::waitEnter() { if (m_waitState || m_isClosing) { return; } m_waitState = true; if (mainWin->m_connDebug) Pmsg0(000, "Entering Wait State\n"); app->setOverrideCursor(QCursor(Qt::WaitCursor)); disconnectSignals(); disconnectConsoleSignals(m_currentConsole); m_waitTreeItem = treeWidget->currentItem(); } /* * Leave wait state */ void MainWin::waitExit() { if (!m_waitState || m_isClosing) { return; } if (mainWin->m_connDebug) Pmsg0(000, "Exiting Wait State\n"); if (m_waitTreeItem && (m_waitTreeItem != treeWidget->currentItem())) { treeWidget->setCurrentItem(m_waitTreeItem); } if (m_doConnect) { connectSignals(); connectConsoleSignals(); } app->restoreOverrideCursor(); m_waitState = false; } void MainWin::connectConsoleSignals() { connect(actionConnect, SIGNAL(triggered()), m_currentConsole, SLOT(connect_dir())); connect(actionSelectFont, SIGNAL(triggered()), m_currentConsole, SLOT(set_font())); connect(actionMessages, SIGNAL(triggered()), m_currentConsole, SLOT(messages())); } void MainWin::disconnectConsoleSignals(Console *console) { disconnect(actionConnect, SIGNAL(triggered()), console, SLOT(connect_dir())); disconnect(actionMessages, SIGNAL(triggered()), console, SLOT(messages())); disconnect(actionSelectFont, SIGNAL(triggered()), console, SLOT(set_font())); } /* * Two functions to respond to menu items to repop lists and execute reload and repopulate * the lists for jobs, clients, filesets .. .. */ void MainWin::repopLists() { m_currentConsole->populateLists(false); } void MainWin::reloadRepopLists() { QString cmd = "reload"; m_currentConsole->consoleCommand(cmd); m_currentConsole->populateLists(false); } /* * Reimplementation of QWidget closeEvent virtual function */ void MainWin::closeEvent(QCloseEvent *event) { m_isClosing = true; writeSettings(); /* Remove all groups from settings for OpenOnExit so that we can start some of the status windows */ foreach(Console *console, m_consoleHash){ QSettings settings(console->m_dir->name(), "bat"); settings.beginGroup("OpenOnExit"); settings.remove(""); settings.endGroup(); } /* close all non console pages, this will call settings in destructors */ while (m_consoleHash.count() < m_pagehash.count()) { foreach(Pages *page, m_pagehash) { if (page != page->console()) { QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(page); if (pageSelectorTreeWidgetItem->childCount() == 0) { page->console()->setCurrent(); page->closeStackPage(); } } } } foreach(Console *console, m_consoleHash){ console->writeSettings(); console->terminate(); console->closeStackPage(); } event->accept(); } void MainWin::writeSettings() { QSettings settings("bareos.org", "bat"); settings.beginGroup("MainWin"); settings.setValue("winSize", size()); settings.setValue("winPos", pos()); settings.setValue("state", saveState()); settings.endGroup(); } void MainWin::readSettings() { QSettings settings("bareos.org", "bat"); settings.beginGroup("MainWin"); resize(settings.value("winSize", QSize(1041, 801)).toSize()); move(settings.value("winPos", QPoint(200, 150)).toPoint()); restoreState(settings.value("state").toByteArray()); settings.endGroup(); } /* * This subroutine is called with an item in the Page Selection window * is clicked */ void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/) { /* Is this a page that has been inserted into the hash */ Pages* page = getFromHash(item); if (page) { int stackindex = tabWidget->indexOf(page); if (stackindex >= 0) { tabWidget->setCurrentWidget(page); } page->dockPage(); /* run the virtual function in case this class overrides it */ page->PgSeltreeWidgetClicked(); } else { Dmsg0(000, "Page not in hash"); } } /* * Called with a change of the highlighed tree widget item in the page selector. */ void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem) { if (m_isClosing) return; /* if closing the application, do nothing here */ Pages *previousPage, *nextPage; Console *previousConsole = NULL; Console *nextConsole; /* remove all actions before adding actions appropriate for new page */ foreach(QAction* pageAction, treeWidget->actions()) { treeWidget->removeAction(pageAction); } /* first determine the next item */ /* knowing the treeWidgetItem, get the page from the hash */ nextPage = getFromHash(currentitem); nextConsole = m_consoleHash.value(currentitem); /* Is this a page that has been inserted into the hash */ if (nextPage) { nextConsole = nextPage->console(); /* then is it a treeWidgetItem representing a director */ } else if (nextConsole) { /* let the next page BE the console */ nextPage = nextConsole; } else { /* Should never get here */ nextPage = NULL; nextConsole = NULL; } /* The Previous item */ /* this condition prevents a segfault. The first time there is no previousitem*/ if (previousitem) { if (m_treeStackTrap == false) { /* keep track of previous items for going Back */ m_treeWidgetStack.append(previousitem); } /* knowing the treeWidgetItem, get the page from the hash */ previousPage = getFromHash(previousitem); previousConsole = m_consoleHash.value(previousitem); if (previousPage) { previousConsole = previousPage->console(); } else if (previousConsole) { previousPage = previousConsole; } if ((previousPage) || (previousConsole)) { if (nextConsole != previousConsole) { /* remove connections to the current console */ disconnectConsoleSignals(previousConsole); QTreeWidgetItem *dirItem = previousConsole->directorTreeItem(); QBrush greyBrush(Qt::lightGray); dirItem->setBackground(0, greyBrush); } } } /* process the current (next) item */ if ((nextPage) || (nextConsole)) { if (nextConsole != previousConsole) { /* make connections to the current console */ m_currentConsole = nextConsole; connectConsoleSignals(); setMessageIcon(); /* Set director's tree widget background to magenta for ease of identification */ QTreeWidgetItem *dirItem = m_currentConsole->directorTreeItem(); QBrush magentaBrush(Qt::magenta); dirItem->setBackground(0, magentaBrush); } /* set the value for the currently active console */ int stackindex = tabWidget->indexOf(nextPage); nextPage->firstUseDock(); /* Is this page currently on the stack or is it undocked */ if (stackindex >= 0) { /* put this page on the top of the stack */ tabWidget->setCurrentIndex(stackindex); } else { /* it is undocked, raise it to the front */ nextPage->raise(); } /* for the page selectors menu action to dock or undock, set the text */ nextPage->setContextMenuDockText(); treeWidget->addAction(actionToggleDock); /* if this page is closeable, and it has no childern, then add that action */ if ((nextPage->isCloseable()) && (currentitem->child(0) == NULL)) treeWidget->addAction(actionClosePage); /* Add the actions to the Page Selectors tree widget that are part of the * current items list of desired actions regardless of whether on top of stack*/ treeWidget->addActions(nextPage->m_contextActions); } } void MainWin::labelButtonClicked() { new labelPage(); } void MainWin::runButtonClicked() { new runPage(""); } void MainWin::estimateButtonClicked() { new estimatePage(); } void MainWin::browseButtonClicked() { new restoreTree(); } void MainWin::statusPageButtonClicked() { /* if one exists, then just set it current */ bool found = false; foreach(Pages *page, m_pagehash) { if (m_currentConsole == page->console()) { if (page->name() == tr("Director Status")) { found = true; page->setCurrent(); } } } if (!found) { new DirStat(); } } void MainWin::restoreButtonClicked() { new prerestorePage(); if (mainWin->m_miscDebug) Pmsg0(000, "in restoreButtonClicked after prerestorePage\n"); } /* * The user just finished typing a line in the command line edit box */ void MainWin::input_line() { int conn; QString cmdStr = lineEdit->text(); /* Get the text */ lineEdit->clear(); /* clear the lineEdit box */ if (m_currentConsole->is_connected()) { if (m_currentConsole->findDirComm(conn)) { m_currentConsole->consoleCommand(cmdStr, conn); } else { /* Use consoleCommand to allow typing anything */ m_currentConsole->consoleCommand(cmdStr); } } else { set_status(tr("Director not connected. Click on connect button.")); } m_cmd_history.append(cmdStr); m_cmd_last = -1; if (treeWidget->currentItem() != getFromHash(m_currentConsole)) m_currentConsole->setCurrent(); } void MainWin::about() { QString fmt = QString("

Bareos Administration Tool %1

" "

Original by Dirk H Bartley and Kern Sibbald

" "

For more information, see: www.bareos.com" "

Copyright © 2007-2010 Free Software Foundation Europe e.V." "

Copyright © 2011-2012 Planets Communications B.V." "

Copyright © 2013-%2 Bareos GmbH & Co. KG" "

BAREOS ® is a registered trademark of Bareos GmbH & Co. KG" "

Licensed under GNU AGPLv3.").arg(VERSION).arg(BYEAR); QMessageBox::about(this, tr("About Bareos Administration Tool"), fmt); } void MainWin::help() { Help::displayFile("index.html"); } void MainWin::set_statusf(const char *fmt, ...) { va_list arg_ptr; char buf[1000]; va_start(arg_ptr, fmt); bvsnprintf(buf, sizeof(buf), fmt, arg_ptr); va_end(arg_ptr); set_status(buf); } void MainWin::set_status_ready() { set_status(tr(" Ready")); } void MainWin::set_status(const QString &str) { statusBar()->showMessage(str); } void MainWin::set_status(const char *buf) { statusBar()->showMessage(buf); } /* * Function to respond to the button bar button to undock */ void MainWin::undockWindowButton() { Pages* page = (Pages*)tabWidget->currentWidget(); if (page) { page->togglePageDocking(); } } /* * Function to respond to action on page selector context menu to toggle the * dock status of the window associated with the page selectors current * tree widget item. */ void MainWin::toggleDockContextWindow() { QTreeWidgetItem *currentitem = treeWidget->currentItem(); /* Is this a page that has been inserted into the hash */ if (getFromHash(currentitem)) { Pages* page = getFromHash(currentitem); if (page) { page->togglePageDocking(); } } } /* * This function is called when the stack item is changed. Call * the virtual function here. Avoids a window being undocked leaving * a window at the top of the stack unpopulated. */ void MainWin::stackItemChanged(int) { if (m_isClosing) return; /* if closing the application, do nothing here */ Pages* page = (Pages*)tabWidget->currentWidget(); /* run the virtual function in case this class overrides it */ if (page) { page->currentStackItem(); } if (!m_waitState) { disconnect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(treeItemClicked(QTreeWidgetItem *, int))); disconnect(treeWidget, SIGNAL( currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); treeWidget->setCurrentItem(getFromHash(page)); connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(treeItemClicked(QTreeWidgetItem *, int))); connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); } } /* * Function to simplify insertion of QTreeWidgetItem <-> Page association * into a double direction hash. */ void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page) { m_pagehash.insert(item, page); m_widgethash.insert(page, item); } /* * Function to simplify removal of QTreeWidgetItem <-> Page association * into a double direction hash. */ void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page) { /* I had all sorts of return status checking code here. Do we have a log * level capability in bat. I would have left it in but it used printf's * and it should really be some kind of log level facility ??? * ******FIXME********/ m_pagehash.remove(item); m_widgethash.remove(page); } /* * Function to retrieve a Page* when the item in the page selector's tree is * known. */ Pages* MainWin::getFromHash(QTreeWidgetItem *item) { return m_pagehash.value(item); } /* * Function to retrieve the page selectors tree widget item when the page is * known. */ QTreeWidgetItem* MainWin::getFromHash(Pages *page) { return m_widgethash.value(page); } void MainWin::closeCurrentPage() { closePage(-1); } /* * Function to respond to action on page selector context menu to close the * current window. */ void MainWin::closePage(int item) { QTreeWidgetItem *currentitem; Pages *page = NULL; if (item >= 0) { page = (Pages *)tabWidget->widget(item); } else { currentitem = treeWidget->currentItem(); /* Is this a page that has been inserted into the hash */ if (getFromHash(currentitem)) { page = getFromHash(currentitem); } } if (page) { if (page->isCloseable()) { page->closeStackPage(); } else { page->hidePage(); } } } /* Quick function to return the current console */ Console *MainWin::currentConsole() { return m_currentConsole; } /* Quick function to return the tree item for the director */ QTreeWidgetItem *MainWin::currentTopItem() { return m_currentConsole->directorTreeItem(); } /* Preferences menu item clicked */ void MainWin::setPreferences() { prefsDialog prefs; prefs.commDebug->setCheckState(m_commDebug ? Qt::Checked : Qt::Unchecked); prefs.connDebug->setCheckState(m_connDebug ? Qt::Checked : Qt::Unchecked); prefs.displayAll->setCheckState(m_displayAll ? Qt::Checked : Qt::Unchecked); prefs.sqlDebug->setCheckState(m_sqlDebug ? Qt::Checked : Qt::Unchecked); prefs.commandDebug->setCheckState(m_commandDebug ? Qt::Checked : Qt::Unchecked); prefs.miscDebug->setCheckState(m_miscDebug ? Qt::Checked : Qt::Unchecked); prefs.recordLimit->setCheckState(m_recordLimitCheck ? Qt::Checked : Qt::Unchecked); prefs.recordSpinBox->setValue(m_recordLimitVal); prefs.daysLimit->setCheckState(m_daysLimitCheck ? Qt::Checked : Qt::Unchecked); prefs.daysSpinBox->setValue(m_daysLimitVal); prefs.checkMessages->setCheckState(m_checkMessages ? Qt::Checked : Qt::Unchecked); prefs.checkMessagesSpin->setValue(m_checkMessagesInterval); prefs.executeLongCheckBox->setCheckState(m_longList ? Qt::Checked : Qt::Unchecked); prefs.rtPopDirCheckBox->setCheckState(m_rtPopDirDebug ? Qt::Checked : Qt::Unchecked); prefs.rtDirCurICCheckBox->setCheckState(m_rtDirCurICDebug ? Qt::Checked : Qt::Unchecked); prefs.rtDirICCheckBox->setCheckState(m_rtDirICDebug ? Qt::Checked : Qt::Unchecked); prefs.rtFileTabICCheckBox->setCheckState(m_rtFileTabICDebug ? Qt::Checked : Qt::Unchecked); prefs.rtVerTabICCheckBox->setCheckState(m_rtVerTabICDebug ? Qt::Checked : Qt::Unchecked); prefs.rtUpdateFTCheckBox->setCheckState(m_rtUpdateFTDebug ? Qt::Checked : Qt::Unchecked); prefs.rtUpdateVTCheckBox->setCheckState(m_rtUpdateVTDebug ? Qt::Checked : Qt::Unchecked); prefs.rtChecksCheckBox->setCheckState(m_rtChecksDebug ? Qt::Checked : Qt::Unchecked); prefs.rtIconStateCheckBox->setCheckState(m_rtIconStateDebug ? Qt::Checked : Qt::Unchecked); prefs.rtRestore1CheckBox->setCheckState(m_rtRestore1Debug ? Qt::Checked : Qt::Unchecked); prefs.rtRestore2CheckBox->setCheckState(m_rtRestore2Debug ? Qt::Checked : Qt::Unchecked); prefs.rtRestore3CheckBox->setCheckState(m_rtRestore3Debug ? Qt::Checked : Qt::Unchecked); switch (ItemFormatterBase::getBytesConversion()) { case ItemFormatterBase::BYTES_CONVERSION_NONE: prefs.radioConvertOff->setChecked(Qt::Checked); break; case ItemFormatterBase::BYTES_CONVERSION_IEC: prefs.radioConvertIEC->setChecked(Qt::Checked); break; default: prefs.radioConvertStandard->setChecked(Qt::Checked); break; } prefs.openPlotCheckBox->setCheckState(m_openPlot ? Qt::Checked : Qt::Unchecked); prefs.openBrowserCheckBox->setCheckState(m_openBrowser ? Qt::Checked : Qt::Unchecked); prefs.openDirStatCheckBox->setCheckState(m_openDirStat ? Qt::Checked : Qt::Unchecked); prefs.exec(); } /* Preferences dialog */ prefsDialog::prefsDialog() : QDialog() { setupUi(this); } void prefsDialog::accept() { this->hide(); mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked; mainWin->m_connDebug = this->connDebug->checkState() == Qt::Checked; mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked; mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked; mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked; mainWin->m_miscDebug = this->miscDebug->checkState() == Qt::Checked; mainWin->m_recordLimitCheck = this->recordLimit->checkState() == Qt::Checked; mainWin->m_recordLimitVal = this->recordSpinBox->value(); mainWin->m_daysLimitCheck = this->daysLimit->checkState() == Qt::Checked; mainWin->m_daysLimitVal = this->daysSpinBox->value(); mainWin->m_checkMessages = this->checkMessages->checkState() == Qt::Checked; mainWin->m_checkMessagesInterval = this->checkMessagesSpin->value(); mainWin->m_longList = this->executeLongCheckBox->checkState() == Qt::Checked; mainWin->m_rtPopDirDebug = this->rtPopDirCheckBox->checkState() == Qt::Checked; mainWin->m_rtDirCurICDebug = this->rtDirCurICCheckBox->checkState() == Qt::Checked; mainWin->m_rtDirICDebug = this->rtDirICCheckBox->checkState() == Qt::Checked; mainWin->m_rtFileTabICDebug = this->rtFileTabICCheckBox->checkState() == Qt::Checked; mainWin->m_rtVerTabICDebug = this->rtVerTabICCheckBox->checkState() == Qt::Checked; mainWin->m_rtUpdateFTDebug = this->rtUpdateFTCheckBox->checkState() == Qt::Checked; mainWin->m_rtUpdateVTDebug = this->rtUpdateVTCheckBox->checkState() == Qt::Checked; mainWin->m_rtChecksDebug = this->rtChecksCheckBox->checkState() == Qt::Checked; mainWin->m_rtIconStateDebug = this->rtIconStateCheckBox->checkState() == Qt::Checked; mainWin->m_rtRestore1Debug = this->rtRestore1CheckBox->checkState() == Qt::Checked; mainWin->m_rtRestore2Debug = this->rtRestore2CheckBox->checkState() == Qt::Checked; mainWin->m_rtRestore3Debug = this->rtRestore3CheckBox->checkState() == Qt::Checked; if (this->radioConvertOff->isChecked()) { ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_NONE); } else if (this->radioConvertIEC->isChecked()){ ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_IEC); } else { ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_SI); } mainWin->m_openPlot = this->openPlotCheckBox->checkState() == Qt::Checked; mainWin->m_openBrowser = this->openBrowserCheckBox->checkState() == Qt::Checked; mainWin->m_openDirStat = this->openDirStatCheckBox->checkState() == Qt::Checked; QSettings settings("www.bareos.org", "bat"); settings.beginGroup("Debug"); settings.setValue("commDebug", mainWin->m_commDebug); settings.setValue("connDebug", mainWin->m_connDebug); settings.setValue("displayAll", mainWin->m_displayAll); settings.setValue("sqlDebug", mainWin->m_sqlDebug); settings.setValue("commandDebug", mainWin->m_commandDebug); settings.setValue("miscDebug", mainWin->m_miscDebug); settings.endGroup(); settings.beginGroup("JobList"); settings.setValue("recordLimitCheck", mainWin->m_recordLimitCheck); settings.setValue("recordLimitVal", mainWin->m_recordLimitVal); settings.setValue("daysLimitCheck", mainWin->m_daysLimitCheck); settings.setValue("daysLimitVal", mainWin->m_daysLimitVal); settings.endGroup(); settings.beginGroup("Timers"); settings.setValue("checkMessages", mainWin->m_checkMessages); settings.setValue("checkMessagesInterval", mainWin->m_checkMessagesInterval); settings.endGroup(); settings.beginGroup("Misc"); settings.setValue("longList", mainWin->m_longList); settings.setValue("byteConvert", ItemFormatterBase::getBytesConversion()); settings.setValue("openplot", mainWin->m_openPlot); settings.setValue("openbrowser", mainWin->m_openBrowser); settings.setValue("opendirstat", mainWin->m_openDirStat); settings.endGroup(); settings.beginGroup("RestoreTree"); settings.setValue("rtPopDirDebug", mainWin->m_rtPopDirDebug); settings.setValue("rtDirCurICDebug", mainWin->m_rtDirCurICDebug); settings.setValue("rtDirCurICRetDebug", mainWin->m_rtDirICDebug); settings.setValue("rtFileTabICDebug", mainWin->m_rtFileTabICDebug); settings.setValue("rtVerTabICDebug", mainWin->m_rtVerTabICDebug); settings.setValue("rtUpdateFTDebug", mainWin->m_rtUpdateFTDebug); settings.setValue("rtUpdateVTDebug", mainWin->m_rtUpdateVTDebug); settings.setValue("rtChecksDebug", mainWin->m_rtChecksDebug); settings.setValue("rtIconStateDebug", mainWin->m_rtIconStateDebug); settings.setValue("rtRestore1Debug", mainWin->m_rtRestore1Debug); settings.setValue("rtRestore2Debug", mainWin->m_rtRestore2Debug); settings.setValue("rtRestore3Debug", mainWin->m_rtRestore3Debug); settings.endGroup(); } void prefsDialog::reject() { this->hide(); mainWin->set_status(tr("Canceled")); } /* read preferences for the prefences dialog box */ void MainWin::readPreferences() { QSettings settings("www.bareos.org", "bat"); settings.beginGroup("Debug"); m_commDebug = settings.value("commDebug", false).toBool(); m_connDebug = settings.value("connDebug", false).toBool(); m_displayAll = settings.value("displayAll", false).toBool(); m_sqlDebug = settings.value("sqlDebug", false).toBool(); m_commandDebug = settings.value("commandDebug", false).toBool(); m_miscDebug = settings.value("miscDebug", false).toBool(); settings.endGroup(); settings.beginGroup("JobList"); m_recordLimitCheck = settings.value("recordLimitCheck", true).toBool(); m_recordLimitVal = settings.value("recordLimitVal", 50).toInt(); m_daysLimitCheck = settings.value("daysLimitCheck", false).toBool(); m_daysLimitVal = settings.value("daysLimitVal", 28).toInt(); settings.endGroup(); settings.beginGroup("Timers"); m_checkMessages = settings.value("checkMessages", false).toBool(); m_checkMessagesInterval = settings.value("checkMessagesInterval", 28).toInt(); settings.endGroup(); settings.beginGroup("Misc"); m_longList = settings.value("longList", false).toBool(); ItemFormatterBase::setBytesConversion( (ItemFormatterBase::BYTES_CONVERSION) settings.value("byteConvert", ItemFormatterBase::BYTES_CONVERSION_IEC).toInt()); m_openPlot = settings.value("openplot", false).toBool(); m_openBrowser = settings.value("openbrowser", false).toBool(); m_openDirStat = settings.value("opendirstat", false).toBool(); settings.endGroup(); settings.beginGroup("RestoreTree"); m_rtPopDirDebug = settings.value("rtPopDirDebug", false).toBool(); m_rtDirCurICDebug = settings.value("rtDirCurICDebug", false).toBool(); m_rtDirICDebug = settings.value("rtDirCurICRetDebug", false).toBool(); m_rtFileTabICDebug = settings.value("rtFileTabICDebug", false).toBool(); m_rtVerTabICDebug = settings.value("rtVerTabICDebug", false).toBool(); m_rtUpdateFTDebug = settings.value("rtUpdateFTDebug", false).toBool(); m_rtUpdateVTDebug = settings.value("rtUpdateVTDebug", false).toBool(); m_rtChecksDebug = settings.value("rtChecksDebug", false).toBool(); m_rtIconStateDebug = settings.value("rtIconStateDebug", false).toBool(); m_rtRestore1Debug = settings.value("rtRestore1Debug", false).toBool(); m_rtRestore2Debug = settings.value("rtRestore2Debug", false).toBool(); m_rtRestore3Debug = settings.value("rtRestore3Debug", false).toBool(); settings.endGroup(); } void MainWin::setMessageIcon() { if (m_currentConsole->is_messagesPending()) actionMessages->setIcon(QIcon(QString::fromUtf8(":/images/mail-message-pending.png"))); else actionMessages->setIcon(QIcon(QString::fromUtf8(":/images/mail-message-new.png"))); } void MainWin::goToPreviousPage() { m_treeStackTrap = true; bool done = false; while (!done) { /* If stack list is emtpty, then done */ if (m_treeWidgetStack.isEmpty()) { done = true; } else { QTreeWidgetItem* testItem = m_treeWidgetStack.takeLast(); QTreeWidgetItemIterator it(treeWidget); /* lets avoid a segfault by setting an item current that no longer exists */ while (*it) { if (*it == testItem) { if (testItem != treeWidget->currentItem()) { treeWidget->setCurrentItem(testItem); done = true; } break; } ++it; } } } m_treeStackTrap = false; } bareos-Release-14.2.6/src/qt-console/mainwin.h000066400000000000000000000112511263011562700211260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * qt-console main window class definition. * * Written by Kern Sibbald, January MMVII */ #ifndef _MAINWIN_H_ #define _MAINWIN_H_ #include #include #include "ui_main.h" class Console; class Pages; class MainWin : public QMainWindow, public Ui::MainForm { Q_OBJECT public: MainWin(QWidget *parent = 0); void set_statusf(const char *fmt, ...); void set_status_ready(); void set_status(const char *buf); void set_status(const QString &str); void writeSettings(); void readSettings(); void resetFocus() { lineEdit->setFocus(); }; void hashInsert(QTreeWidgetItem *, Pages *); void hashRemove(Pages *); void hashRemove(QTreeWidgetItem *, Pages *); void setMessageIcon(); bool getWaitState() {return m_waitState; }; bool isClosing() {return m_isClosing; }; Console *currentConsole(); QTreeWidgetItem *currentTopItem(); Pages* getFromHash(QTreeWidgetItem *); QTreeWidgetItem* getFromHash(Pages *); /* This hash is to get the page when the page selector widget is known */ QHash m_pagehash; /* This hash is to get the page selector widget when the page is known */ QHash m_widgethash; /* This is a list of consoles */ QHash m_consoleHash; void createPageJobList(const QString &, const QString &, const QString &, const QString &, QTreeWidgetItem *); QString m_dtformat; /* Begin Preferences variables */ bool m_commDebug; bool m_connDebug; bool m_displayAll; bool m_sqlDebug; bool m_commandDebug; bool m_miscDebug; bool m_recordLimitCheck; int m_recordLimitVal; bool m_daysLimitCheck; int m_daysLimitVal; bool m_checkMessages; int m_checkMessagesInterval; bool m_longList; bool m_rtPopDirDebug; bool m_rtDirCurICDebug; bool m_rtDirICDebug; bool m_rtFileTabICDebug; bool m_rtVerTabICDebug; bool m_rtUpdateFTDebug; bool m_rtUpdateVTDebug; bool m_rtChecksDebug; bool m_rtIconStateDebug; bool m_rtRestore1Debug; bool m_rtRestore2Debug; bool m_rtRestore3Debug; bool m_openBrowser; bool m_openPlot; bool m_openDirStat; /* Global */ bool m_notify; /* global flag to turn on/off all notifiers */ public slots: void input_line(); void about(); void help(); void treeItemClicked(QTreeWidgetItem *item, int column); void labelButtonClicked(); void runButtonClicked(); void estimateButtonClicked(); void browseButtonClicked(); void statusPageButtonClicked(); void restoreButtonClicked(); void undockWindowButton(); void treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); void stackItemChanged(int); void toggleDockContextWindow(); void closePage(int item); void closeCurrentPage(); void setPreferences(); void readPreferences(); void waitEnter(); void waitExit(); void repopLists(); void reloadRepopLists(); void popLists(); void goToPreviousPage(); protected: void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); private: void connectConsole(); void createPages(); void connectSignals(); void disconnectSignals(); void connectConsoleSignals(); void disconnectConsoleSignals(Console *console); private: Console *m_currentConsole; Pages *m_pagespophold; QStringList m_cmd_history; int m_cmd_last; QTreeWidgetItem *m_firstItem; QTreeWidgetItem *m_waitTreeItem; bool m_isClosing; bool m_waitState; bool m_doConnect; QList m_treeWidgetStack; bool m_treeStackTrap; }; #include "ui_prefs.h" class prefsDialog : public QDialog, public Ui::PrefsForm { Q_OBJECT public: prefsDialog(); private slots: void accept(); void reject(); }; #endif /* _MAINWIN_H_ */ bareos-Release-14.2.6/src/qt-console/mediaedit/000077500000000000000000000000001263011562700212405ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/mediaedit/mediaedit.cpp000066400000000000000000000337551263011562700237060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include #include "mediaedit.h" /* * A constructor */ MediaEdit::MediaEdit(QTreeWidgetItem *parentWidget, QString &mediaId) : Pages() { setupUi(this); pgInitialize(tr("Media Edit"), parentWidget); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge-edit.png"))); dockPage(); setCurrent(); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); connectSpins(); connect(retentionSpin, SIGNAL(valueChanged(int)), this, SLOT(retentionChanged())); connect(useDurationSpin, SIGNAL(valueChanged(int)), this, SLOT(useDurationChanged())); connect(retentionRadio, SIGNAL(pressed()), this, SLOT(retentionRadioPressed())); connect(useDurationRadio, SIGNAL(pressed()), this, SLOT(useDurationRadioPressed())); m_pool = ""; m_recyclePool = ""; m_status = ""; m_slot = 0; /* The media's pool */ poolCombo->addItems(m_console->pool_list); /* The media's Status */ QStringList statusList = (QStringList() << "Full" << "Used" << "Append" << "Error" << "Purged" << "Recycle" << "Read-Only" << "Cleaning"); statusCombo->addItems(statusList); /* Set up the query for the default values */ QStringList FieldList = (QStringList() << "Media.VolumeName" << "Pool.Name" << "Media.VolStatus" << "Media.Slot" << "Media.VolRetention" << "Media.VolUseDuration" << "Media.MaxVolJobs" << "Media.MaxVolFiles" << "Media.MaxVolBytes" << "Media.Recycle" << "Media.Enabled" << "Pol.Name"); QStringList AsList = (QStringList() << "VolumeName" << "PoolName" << "Status" << "Slot" << "Retention" << "UseDuration" << "MaxJobs" << "MaxFiles" << "MaxBytes" << "Recycle" << "Enabled" << "RecyclePool"); int i = 0; QString query("SELECT "); foreach (QString field, FieldList) { if (i != 0) { query += ", "; } query += field + " AS " + AsList[i]; i += 1; } QString where = " WHERE Media.VolumeName = '" + mediaId + "' "; if (mediaId.contains(QRegExp("^[0-9]+$"))) { where = " WHERE Media.MediaId=" + mediaId; } query += " FROM Media" " JOIN Pool ON (Media.PoolId=Pool.PoolId)" " LEFT OUTER JOIN Pool AS Pol ON (Media.RecyclePoolId=Pol.PoolId)" + where; if (mainWin->m_sqlDebug) { Pmsg1(000, "MediaList query cmd : %s\n",query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { QString field; QStringList fieldlist; /* Iterate through the lines of results, there should only be one. */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); i = 0; /* Iterate through fields in the record */ foreach (field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ bool ok; if (i == 0) { m_mediaName = field; volumeLabel->setText(QString("Volume : %1").arg(m_mediaName)); } else if (i == 1) { m_pool = field; } else if (i == 2) { m_status = field; } else if (i == 3) { m_slot = field.toInt(&ok, 10); if (!ok){ m_slot = 0; } } else if (i == 4) { m_retention = field.toInt(&ok, 10); if (!ok){ m_retention = 0; } } else if (i == 5) { m_useDuration = field.toInt(&ok, 10); if (!ok){ m_useDuration = 0; } } else if (i == 6) { m_maxVolJobs = field.toInt(&ok, 10); if (!ok){ m_maxVolJobs = 0; } } else if (i == 7) { m_maxVolFiles = field.toInt(&ok, 10); if (!ok){ m_maxVolFiles = 0; } } else if (i == 8) { m_maxVolBytes = field.toInt(&ok, 10); if (!ok){ m_maxVolBytes = 0; } } else if (i == 9) { if (field == "1") m_recycle = true; else m_recycle = false; } else if (i == 10) { if (field == "1") m_enabled = true; else m_enabled = false; } else if (i == 11) { m_recyclePool = field; } i++; } /* foreach field */ } /* foreach resultline */ } /* if results from query */ if (m_mediaName != "") { int index; /* default value for pool */ index = poolCombo->findText(m_pool, Qt::MatchExactly); if (index != -1) { poolCombo->setCurrentIndex(index); } /* default value for status */ index = statusCombo->findText(m_status, Qt::MatchExactly); if (index != -1) { statusCombo->setCurrentIndex(index); } slotSpin->setValue(m_slot); retentionSpin->setValue(m_retention); useDurationSpin->setValue(m_useDuration); setSpins(retentionSpin->value()); retentionRadio->setChecked(true); maxJobsSpin->setValue(m_maxVolJobs); maxFilesSpin->setValue(m_maxVolFiles); maxBytesSpin->setValue(m_maxVolBytes); if (m_recycle) recycleCheck->setCheckState(Qt::Checked); else recycleCheck->setCheckState(Qt::Unchecked); if (m_enabled) enabledCheck->setCheckState(Qt::Checked); else enabledCheck->setCheckState(Qt::Unchecked); /* default for recycle pool */ recyclePoolCombo->addItems(m_console->pool_list); recyclePoolCombo->insertItem(0, "*None*"); index = recyclePoolCombo->findText(m_recyclePool, Qt::MatchExactly); if (index == -1) { index = 0; } recyclePoolCombo->setCurrentIndex(index); } else { QMessageBox::warning(this, tr("No Volume name"), tr("No Volume name given"), QMessageBox::Ok, QMessageBox::Ok); return; } } /* * Function to handle updating the record then closing the page */ void MediaEdit::okButtonPushed() { QString scmd; this->hide(); bool docmd = false; scmd = QString("update volume=\"%1\"") .arg(m_mediaName); if (m_pool != poolCombo->currentText()) { scmd += " pool=\"" + poolCombo->currentText() + "\""; docmd = true; } if (m_status != statusCombo->currentText()) { scmd += " volstatus=\"" + statusCombo->currentText() + "\""; docmd = true; } if (m_slot != slotSpin->value()) { scmd += " slot=" + QString().setNum(slotSpin->value()); docmd = true; } if (m_retention != retentionSpin->value()) { scmd += " VolRetention=" + QString().setNum(retentionSpin->value()); docmd = true; } if (m_useDuration != useDurationSpin->value()) { scmd += " VolUse=" + QString().setNum(useDurationSpin->value()); docmd = true; } if (m_maxVolJobs != maxJobsSpin->value()) { scmd += " MaxVolJobs=" + QString().setNum(maxJobsSpin->value()); docmd = true; } if (m_maxVolFiles != maxFilesSpin->value()) { scmd += " MaxVolFiles=" + QString().setNum(maxFilesSpin->value()); docmd = true; } if (m_maxVolBytes != maxBytesSpin->value()) { scmd += " MaxVolBytes=" + QString().setNum(maxBytesSpin->value()); docmd = true; } if ((m_recycle) && (recycleCheck->checkState() == Qt::Unchecked)) { scmd += " Recycle=no"; docmd = true; } if ((!m_recycle) && (recycleCheck->checkState() == Qt::Checked)) { scmd += " Recycle=yes"; docmd = true; } if ((m_enabled) && (enabledCheck->checkState() == Qt::Unchecked)) { scmd += " enabled=no"; docmd = true; } if ((!m_enabled) && (enabledCheck->checkState() == Qt::Checked)) { scmd += " enabled=yes"; docmd = true; } if (m_recyclePool != recyclePoolCombo->currentText()) { scmd += " recyclepool=\""; if (recyclePoolCombo->currentText() != "*None*") { scmd += recyclePoolCombo->currentText(); } scmd += "\""; docmd = true; } if (docmd) { if (mainWin->m_commandDebug) { Pmsg1(000, "sending command : %s\n",scmd.toUtf8().data()); } consoleCommand(scmd); } closeStackPage(); } /* close if cancel */ void MediaEdit::cancelButtonPushed() { closeStackPage(); } /* * Slot for user changed retention */ void MediaEdit::retentionChanged() { retentionRadio->setChecked(true); setSpins(retentionSpin->value()); } /* * Slot for user changed the use duration */ void MediaEdit::useDurationChanged() { useDurationRadio->setChecked(true); setSpins(useDurationSpin->value()); } /* * Set the 5 duration spins from a known duration value */ void MediaEdit::setSpins(int value) { int years, months, days, hours, minutes, seconds, left; years = abs(value / 31536000); left = value - years * 31536000; months = abs(left / 2592000); left = left - months * 2592000; days = abs(left / 86400); left = left - days * 86400; hours = abs(left / 3600); left = left - hours * 3600; minutes = abs(left / 60); seconds = left - minutes * 60; disconnectSpins(); yearsSpin->setValue(years); monthsSpin->setValue(months); daysSpin->setValue(days); hoursSpin->setValue(hours); minutesSpin->setValue(minutes); secondsSpin->setValue(seconds); connectSpins(); } /* * This slot is called any time any one of the 5 duration spins a changed. */ void MediaEdit::durationChanged() { disconnectSpins(); if (secondsSpin->value() == -1) { secondsSpin->setValue(59); minutesSpin->setValue(minutesSpin->value()-1); } if (minutesSpin->value() == -1) { minutesSpin->setValue(59); hoursSpin->setValue(hoursSpin->value()-1); } if (hoursSpin->value() == -1) { hoursSpin->setValue(23); daysSpin->setValue(daysSpin->value()-1); } if (daysSpin->value() == -1) { daysSpin->setValue(29); monthsSpin->setValue(monthsSpin->value()-1); } if (monthsSpin->value() == -1) { monthsSpin->setValue(11); yearsSpin->setValue(yearsSpin->value()-1); } if (yearsSpin->value() == -1) { yearsSpin->setValue(0); } if (secondsSpin->value() == 60) { secondsSpin->setValue(0); minutesSpin->setValue(minutesSpin->value()+1); } if (minutesSpin->value() == 60) { minutesSpin->setValue(0); hoursSpin->setValue(hoursSpin->value()+1); } if (hoursSpin->value() == 24) { hoursSpin->setValue(0); daysSpin->setValue(daysSpin->value()+1); } if (daysSpin->value() == 30) { daysSpin->setValue(0); monthsSpin->setValue(monthsSpin->value()+1); } if (monthsSpin->value() == 12) { monthsSpin->setValue(0); yearsSpin->setValue(yearsSpin->value()+1); } connectSpins(); if (retentionRadio->isChecked()) { int retention; retention = secondsSpin->value() + minutesSpin->value() * 60 + hoursSpin->value() * 3600 + daysSpin->value() * 86400 + monthsSpin->value() * 2592000 + yearsSpin->value() * 31536000; disconnect(retentionSpin, SIGNAL(valueChanged(int)), this, SLOT(retentionChanged())); retentionSpin->setValue(retention); connect(retentionSpin, SIGNAL(valueChanged(int)), this, SLOT(retentionChanged())); } if (useDurationRadio->isChecked()) { int useDuration; useDuration = secondsSpin->value() + minutesSpin->value() * 60 + hoursSpin->value() * 3600 + daysSpin->value() * 86400 + monthsSpin->value() * 2592000 + yearsSpin->value() * 31536000; disconnect(useDurationSpin, SIGNAL(valueChanged(int)), this, SLOT(useDurationChanged())); useDurationSpin->setValue(useDuration); connect(useDurationSpin, SIGNAL(valueChanged(int)), this, SLOT(useDurationChanged())); } } /* Connect the spins */ void MediaEdit::connectSpins() { connect(secondsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); connect(minutesSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); connect(hoursSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); connect(daysSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); connect(monthsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); connect(yearsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); } /* disconnect spins so that we can set the value of other spin from changed duration spin */ void MediaEdit::disconnectSpins() { disconnect(secondsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); disconnect(minutesSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); disconnect(hoursSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); disconnect(daysSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); disconnect(monthsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); disconnect(yearsSpin, SIGNAL(valueChanged(int)), this, SLOT(durationChanged())); } /* slot for setting spins when retention radio checked */ void MediaEdit::retentionRadioPressed() { setSpins(retentionSpin->value()); } /* slot for setting spins when duration radio checked */ void MediaEdit::useDurationRadioPressed() { setSpins(useDurationSpin->value()); } bareos-Release-14.2.6/src/qt-console/mediaedit/mediaedit.h000066400000000000000000000032521263011562700233400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _MEDIAEDIT_H_ #define _MEDIAEDIT_H_ #include #include "ui_mediaedit.h" #include class MediaEdit : public Pages, public Ui::mediaEditForm { Q_OBJECT public: MediaEdit(QTreeWidgetItem *parentWidget, QString &mediaId); private slots: void okButtonPushed(); void cancelButtonPushed(); void retentionChanged(); void durationChanged(); void useDurationChanged(); void setSpins(int value); void retentionRadioPressed(); void useDurationRadioPressed(); private: void connectSpins(); void disconnectSpins(); QString m_mediaName; QString m_pool; QString m_status; int m_slot; int m_retention; int m_useDuration; int m_maxVolJobs; int m_maxVolFiles; int m_maxVolBytes; bool m_recycle; bool m_enabled; QString m_recyclePool; }; #endif /* _MEDIAEDIT_H_ */ bareos-Release-14.2.6/src/qt-console/mediaedit/mediaedit.ui000066400000000000000000000372771263011562700235440ustar00rootroot00000000000000 mediaEditForm 0 0 487 470 Form 9 6 0 6 Pool: poolCombo Volume Status: Max Volume Bytes: slotSpin Slot: slotSpin Max Volume Jobs: slotSpin Use Duration: slotSpin 0 6 Qt::Horizontal 40 20 OK Cancel 2147483647 Retention: slotSpin Recycle Pool: slotSpin 0 6 Qt::RightToLeft Enabled Qt::Horizontal 40 20 2147483647 Max Volume Files: slotSpin 0 6 Qt::Vertical 97 21 999 -1 Years Seconds 30 -1 Use Duration Qt::Vertical 97 31 Days 60 -1 Hours Months 60 -1 24 -1 0 Retention 12 -1 Minutes 2147483647 0 6 Qt::Horizontal 40 20 16777215 48 Volume : Qt::Horizontal 40 20 2147483647 0 6 Qt::RightToLeft Recycle Qt::Horizontal 40 20 0 6 Qt::Horizontal 71 21 16777215 30 <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Edit a Volume</span></p></body></html> Qt::Horizontal 81 20 10000 2147483647 Qt::Vertical 20 40 Qt::Horizontal 40 20 Qt::Vertical 20 40 Qt::Horizontal 40 20 bareos-Release-14.2.6/src/qt-console/mediainfo/000077500000000000000000000000001263011562700212465ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/mediainfo/mediainfo.cpp000066400000000000000000000225031263011562700237070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bat.h" #include #include #include #include "mediaedit/mediaedit.h" #include "relabel/relabel.h" #include "run/run.h" #include "mediainfo.h" #include "util/fmtwidgetitem.h" #include "job/job.h" /* * A constructor */ MediaInfo::MediaInfo(QTreeWidgetItem *parentWidget, QString &mediaName) : Pages() { setupUi(this); pgInitialize(tr("Media Info"), parentWidget); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge-edit.png"))); m_mediaName = mediaName; connect(pbPrune, SIGNAL(clicked()), this, SLOT(pruneVol())); connect(pbPurge, SIGNAL(clicked()), this, SLOT(purgeVol())); connect(pbDelete, SIGNAL(clicked()), this, SLOT(deleteVol())); connect(pbEdit, SIGNAL(clicked()), this, SLOT(editVol())); connect(pbImport, SIGNAL(clicked()), this, SLOT(importVol())); connect(pbExport, SIGNAL(clicked()), this, SLOT(exportVol())); connect(tableJob, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(showInfoForJob(QTableWidgetItem *))); dockPage(); setCurrent(); populateForm(); } /* * Subroutine to call class to show the log in the database from that job */ void MediaInfo::showInfoForJob(QTableWidgetItem * item) { QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); int row = item->row(); QString jobid = tableJob->item(row, 0)->text(); new Job(jobid, pageSelectorTreeWidgetItem); // connect(j, SIGNAL(destroyed()), this, SLOT(populateTree())); } void MediaInfo::pruneVol() { new prunePage(m_mediaName, ""); // connect(prune, SIGNAL(destroyed()), this, SLOT(populateTree())); } // TODO: use same functions as in medialist.cpp void MediaInfo::purgeVol() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to purge ?? !!!.\n" "The Purge command will delete associated Catalog database records from Jobs and" " Volumes without considering the retention period. Purge works only on the" " Catalog database and does not affect data written to Volumes. This command can" " be dangerous because you can delete catalog records associated with current" " backups of files, and we recommend that you do not use it unless you know what" " you are doing.\n" "Press OK to proceed with the purge operation?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString scmd; scmd = QString("purge volume=\"%1\"") .arg(m_mediaName); consoleCommand(scmd); } void MediaInfo::deleteVol() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to delete?? !!!.\n" "This delete command is used to delete a Volume record and all associated catalog" " records that were created. This command operates only on the Catalog" " database and has no effect on the actual data written to a Volume. This" " command can be dangerous and we strongly recommend that you do not use" " it unless you know what you are doing. All Jobs and all associated" " records (File and JobMedia) will be deleted from the catalog." "Press OK to proceed with delete operation.?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString scmd; scmd = QString("delete volume=\"%1\"") .arg(m_mediaName); consoleCommand(scmd); } void MediaInfo::editVol() { new MediaEdit(mainWin->getFromHash(this), m_mediaId); // connect(edit, SIGNAL(destroyed()), this, SLOT(populateTree())); } void MediaInfo::importVol() { QString scmd; scmd = QString("import volume=\"%1\"") .arg(m_mediaName); consoleCommand(scmd); } void MediaInfo::exportVol() { QString scmd; scmd = QString("export volume=\"%1\"") .arg(m_mediaName); consoleCommand(scmd); } /* * Populate the text in the window */ void MediaInfo::populateForm() { utime_t t; time_t ttime; QString stat, LastWritten; char buf[256]; QString query = "SELECT MediaId, VolumeName, Pool.Name, MediaType, FirstWritten," "LastWritten, VolMounts, VolBytes, Media.Enabled," "Location.Location, VolStatus, RecyclePool.Name, Media.Recycle, " "VolReadTime/1000000, VolWriteTime/1000000, Media.VolUseDuration, " "Media.MaxVolJobs, Media.MaxVolFiles, Media.MaxVolBytes, " "Media.VolRetention,InChanger,Slot " "FROM Media JOIN Pool USING (PoolId) LEFT JOIN Pool AS RecyclePool " "ON (Media.RecyclePoolId=RecyclePool.PoolId) " "LEFT JOIN Location ON (Media.LocationId=Location.LocationId) " "WHERE Media.VolumeName='" + m_mediaName + "'"; if (mainWin->m_sqlDebug) { Pmsg1(000, "MediaInfo query cmd : %s\n",query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { QString resultline; QStringList fieldlist; foreach (resultline, results) { // should have only one result fieldlist = resultline.split("\t"); QStringListIterator fld(fieldlist); m_mediaId = fld.next(); label_VolumeName->setText(fld.next()); label_Pool->setText(fld.next()); label_MediaType->setText(fld.next()); label_FirstWritten->setText(fld.next()); LastWritten = fld.next(); label_LastWritten->setText(LastWritten); // label_VolFiles->setText(fld.next()); label_VolMounts->setText(fld.next()); label_VolBytes->setText(convertBytesSI(fld.next().toULongLong())); label_Enabled->setPixmap(QPixmap(":/images/inflag" + fld.next() + ".png")); label_Location->setText(fld.next()); label_VolStatus->setText(fld.next()); label_RecyclePool->setText(fld.next()); chkbox_Recycle->setCheckState(fld.next().toInt()?Qt::Checked:Qt::Unchecked); edit_utime(fld.next().toULongLong(), buf, sizeof(buf)); label_VolReadTime->setText(QString(buf)); edit_utime(fld.next().toULongLong(), buf, sizeof(buf)); label_VolWriteTime->setText(QString(buf)); edit_utime(fld.next().toULongLong(), buf, sizeof(buf)); label_VolUseDuration->setText(QString(buf)); label_MaxVolJobs->setText(fld.next()); label_MaxVolFiles->setText(fld.next()); label_MaxVolBytes->setText(fld.next()); stat = fld.next(); edit_utime(stat.toULongLong(), buf, sizeof(buf)); label_VolRetention->setText(QString(buf)); if (LastWritten != "") { t = str_to_utime(LastWritten.toAscii().data()); t = t + stat.toULongLong(); ttime = t; bstrutime(buf, sizeof(buf), ttime); label_Expire->setText(QString(buf)); } label_Online->setPixmap(QPixmap(":/images/inflag"+fld.next()+".png")); // label_VolFiles->setText(fld.next()); // label_VolErrors->setText(fld.next()); // stat=fld.next(); // jobstatus_to_ascii_gui(stat[0].toAscii(), buf, sizeof(buf)); // stat = buf; // } } query = "SELECT DISTINCT JobId, Name, StartTime, Type, Level, JobFiles," "JobBytes,JobStatus " "FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) " "WHERE Media.VolumeName = '" + m_mediaName + "'"; if (mainWin->m_sqlDebug) { Pmsg1(000, "MediaInfo query cmd : %s\n",query.toUtf8().data()); } results.clear(); if (m_console->sql_cmd(query, results)) { QString resultline; QStringList fieldlist; int row = 0; tableJob->setRowCount(results.size()); foreach (resultline, results) { fieldlist = resultline.split("\t"); QStringListIterator fld(fieldlist); int index=0; TableItemFormatter jobitem(*tableJob, row); /* JobId */ jobitem.setNumericFld(index++, fld.next()); /* job name */ jobitem.setTextFld(index++, fld.next()); /* job starttime */ jobitem.setTextFld(index++, fld.next(), true); /* job type */ jobitem.setJobTypeFld(index++, fld.next()); /* job level */ jobitem.setJobLevelFld(index++, fld.next()); /* job files */ jobitem.setNumericFld(index++, fld.next()); /* job bytes */ jobitem.setBytesFld(index++, fld.next()); /* job status */ jobitem.setJobStatusFld(index++, fld.next()); row++; } } tableJob->resizeColumnsToContents(); tableJob->resizeRowsToContents(); tableJob->verticalHeader()->hide(); /* make read only */ tableJob->setEditTriggers(QAbstractItemView::NoEditTriggers); } bareos-Release-14.2.6/src/qt-console/mediainfo/mediainfo.h000066400000000000000000000025551263011562700233610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MEDIAINFO_H_ #define _MEDIAINFO_H_ #include #include "ui_mediainfo.h" #include class MediaInfo : public Pages, public Ui::mediaInfoForm { Q_OBJECT public: MediaInfo(QTreeWidgetItem *parentWidget, QString &mediaId); private slots: void pruneVol(); void purgeVol(); void deleteVol(); void editVol(); void importVol(); void exportVol(); void showInfoForJob(QTableWidgetItem * item); private: void populateForm(); QString m_mediaName; QString m_mediaId; }; #endif /* _MEDIAINFO_H_ */ bareos-Release-14.2.6/src/qt-console/mediainfo/mediainfo.ui000066400000000000000000000520221263011562700235410ustar00rootroot00000000000000 mediaInfoForm 0 0 828 814 Form Edit :/images/edit.png:/images/edit.png true Purge :/images/purge.png:/images/purge.png true Delete :/images/purge.png:/images/purge.png true Prune :/images/edit-cut.png:/images/edit-cut.png true Import :/images/intern.png:/images/intern.png true Export :/images/extern.png:/images/extern.png true Qt::Horizontal 40 20 QLayout::SetFixedSize 0 0 251 241 251 243 Information Name: Vol0001 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Pool: Default Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Online: :/images/inflag0.png Enabled: yes Location: Vault Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Status: Append Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Media Type: File Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Recycle Pool: Scratch Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 0 0 261 241 261 241 Statistics Vol Bytes: 19.8 MB Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Vol Mounts: 10 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Recycle count: 5 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Read time: 10 mins Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Write time: 20 mins Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Errors: 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Last Written: 2009-07-05 12:23:00 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse First Written: 2009-06-05 10:00:00 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 0 0 200 241 200 241 Limits Use duration: 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Max jobs: 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Max files: 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Max bytes: 0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Recycle: false Retention: 365 days Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Expire: 2010-08-03 23:10:03 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Qt::Horizontal 40 20 0 0 Jobs true JobId true Name true Start Time true Type true Level true Files true Bytes true Status bareos-Release-14.2.6/src/qt-console/medialist/000077500000000000000000000000001263011562700212665ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/medialist/medialist.cpp000066400000000000000000000416341263011562700237550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * MediaList Class * * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include #include "medialist.h" #include "mediaedit/mediaedit.h" #include "mediainfo/mediainfo.h" #include "joblist/joblist.h" #include "relabel/relabel.h" #include "run/run.h" #include "util/fmtwidgetitem.h" MediaList::MediaList() : Pages() { setupUi(this); m_name = tr("Pools"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge.png"))); /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */ m_populated = false; m_needs_repopulate = false; m_checkcurwidget = true; m_closeable = false; /* add context sensitive menu items specific to this classto the page * selector tree. m_contextActions is QList of QActions */ m_contextActions.append(actionRefreshMediaList); } MediaList::~MediaList() { if (m_populated) { writeExpandedSettings(); } } /* * The main meat of the class!! The function that querries the director and * creates the widgets with appropriate values. */ void MediaList::populateTree() { QTreeWidgetItem *pooltreeitem = NULL; if (m_populated) { writeExpandedSettings(); } m_populated = true; Freeze frz(*mp_treeWidget); /* disable updating*/ QStringList headerlist = (QStringList() << tr("Volume Name") << tr("Id") << tr("Status") << tr("Enabled") << tr("Bytes") << tr("Files") << tr("Jobs") << tr("Retention") << tr("Media Type") << tr("Slot") << tr("Use Duration") << tr("Max Jobs") << tr("Max Files") << tr("Max Bytes") << tr("Recycle") << tr("Last Written") << tr("First Written") << tr("Read Time") << tr("Write Time") << tr("Recycle Count") << tr("Recycle Pool")); m_checkcurwidget = false; mp_treeWidget->clear(); m_checkcurwidget = true; mp_treeWidget->setColumnCount(headerlist.count()); m_topItem = new QTreeWidgetItem(mp_treeWidget); m_topItem->setText(0, tr("Pools")); m_topItem->setData(0, Qt::UserRole, 0); m_topItem->setExpanded(true); mp_treeWidget->setHeaderLabels(headerlist); QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("MediaListTreeExpanded"); QString query; /* Comma separated list of pools first */ bool first = true; QString pool_comsep(""); foreach (QString pool_listItem, m_console->pool_list) { if (first) { pool_comsep += "'" + pool_listItem + "'"; first = false; } else pool_comsep += ",'" + pool_listItem + "'"; } /* Now use pool_comsep list to perform just one query */ if (pool_comsep != "") { query = "SELECT Pool.Name AS pul," " Media.VolumeName AS Media, " " Media.MediaId AS Id, Media.VolStatus AS VolStatus," " Media.Enabled AS Enabled, Media.VolBytes AS Bytes," " Media.VolFiles AS FileCount, Media.VolJobs AS JobCount," " Media.VolRetention AS VolumeRetention, Media.MediaType AS MediaType," " Media.InChanger AS InChanger, Media.Slot AS Slot, " " Media.VolUseDuration AS UseDuration," " Media.MaxVolJobs AS MaxJobs, Media.MaxVolFiles AS MaxFiles," " Media.MaxVolBytes AS MaxBytes, Media.Recycle AS Recycle," " Media.LastWritten AS LastWritten," " Media.FirstWritten AS FirstWritten," " (VolReadTime/1000000) AS ReadTime, (VolWriteTime/1000000) AS WriteTime," " RecycleCount AS ReCyCount," " RecPool.Name AS RecyclePool" " FROM Media" " JOIN Pool ON (Media.PoolId=Pool.PoolId)" " LEFT OUTER JOIN Pool AS RecPool ON (Media.RecyclePoolId=RecPool.PoolId)" " WHERE "; query += " Pool.Name IN (" + pool_comsep + ")"; query += " ORDER BY Pool.Name, Media"; if (mainWin->m_sqlDebug) { Pmsg1(000, "MediaList query cmd : %s\n",query.toUtf8().data()); } QStringList results; int counter = 0; if (m_console->sql_cmd(query, results)) { QStringList fieldlist; QString prev_pool(""); QString this_pool(""); /* Iterate through the lines of results. */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); this_pool = fieldlist.takeFirst(); if (prev_pool != this_pool) { prev_pool = this_pool; pooltreeitem = new QTreeWidgetItem(m_topItem); pooltreeitem->setText(0, this_pool); pooltreeitem->setData(0, Qt::UserRole, 1); } if(settings.contains(this_pool)) { pooltreeitem->setExpanded(settings.value(this_pool).toBool()); } else { pooltreeitem->setExpanded(true); } if (fieldlist.size() < 18) { Pmsg1(0, "Discarding %s\n", resultline.data()); continue; /* Some fields missing, ignore row */ } int index = 0; TreeItemFormatter mediaitem(*pooltreeitem, 2); /* Iterate through fields in the record */ QStringListIterator fld(fieldlist); /* volname */ mediaitem.setTextFld(index++, fld.next()); /* id */ mediaitem.setNumericFld(index++, fld.next()); /* status */ mediaitem.setVolStatusFld(index++, fld.next()); /* enabled */ mediaitem.setBoolFld(index++, fld.next()); /* bytes */ mediaitem.setBytesFld(index++, fld.next()); /* files */ mediaitem.setNumericFld(index++, fld.next()); /* jobs */ mediaitem.setNumericFld(index++, fld.next()); /* retention */ mediaitem.setDurationFld(index++, fld.next()); /* media type */ mediaitem.setTextFld(index++, fld.next()); /* inchanger + slot */ int inchanger = fld.next().toInt(); if (inchanger) { mediaitem.setNumericFld(index++, fld.next()); } else { /* volume not in changer, show blank slot */ mediaitem.setNumericFld(index++, ""); fld.next(); } /* use duration */ mediaitem.setDurationFld(index++, fld.next()); /* max jobs */ mediaitem.setNumericFld(index++, fld.next()); /* max files */ mediaitem.setNumericFld(index++, fld.next()); /* max bytes */ mediaitem.setBytesFld(index++, fld.next()); /* recycle */ mediaitem.setBoolFld(index++, fld.next()); /* last written */ mediaitem.setTextFld(index++, fld.next()); /* first written */ mediaitem.setTextFld(index++, fld.next()); /* read time */ mediaitem.setDurationFld(index++, fld.next()); /* write time */ mediaitem.setDurationFld(index++, fld.next()); /* Recycle Count */ mediaitem.setNumericFld(index++, fld.next()); /* recycle pool */ mediaitem.setTextFld(index++, fld.next()); } /* foreach resultline */ counter += 1; } /* if results from query */ } /* foreach pool_listItem */ settings.endGroup(); /* Resize the columns */ for(int cnter=0; cnterresizeColumnToContents(cnter); } } /* * Called from the signal of the context sensitive menu! */ void MediaList::editVolume() { MediaEdit* edit = new MediaEdit(mainWin->getFromHash(this), m_currentVolumeId); connect(edit, SIGNAL(destroyed()), this, SLOT(populateTree())); } /* * Called from the signal of the context sensitive menu! */ void MediaList::showJobs() { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); mainWin->createPageJobList(m_currentVolumeName, "", "", "", parentItem); } /* * Called from the signal of the context sensitive menu! */ void MediaList::viewVolume() { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); MediaInfo* view = new MediaInfo(parentItem, m_currentVolumeName); connect(view, SIGNAL(destroyed()), this, SLOT(populateTree())); } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void MediaList::PgSeltreeWidgetClicked() { if (!m_populated) { populateTree(); createContextMenu(); } if (!isOnceDocked()) { dockPage(); } } /* * Added to set the context menu policy based on currently active treeWidgetItem * signaled by currentItemChanged */ void MediaList::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetItem *previouswidgetitem) { /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */ if (m_checkcurwidget) { /* The Previous item */ if (previouswidgetitem) { /* avoid a segfault if first time */ foreach(QAction* mediaAction, mp_treeWidget->actions()) { mp_treeWidget->removeAction(mediaAction); } } int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt(); m_currentVolumeName=currentwidgetitem->text(0); mp_treeWidget->addAction(actionRefreshMediaList); if (treedepth == 2){ m_currentVolumeId=currentwidgetitem->text(1); mp_treeWidget->addAction(actionEditVolume); mp_treeWidget->addAction(actionListJobsOnVolume); mp_treeWidget->addAction(actionDeleteVolume); mp_treeWidget->addAction(actionPruneVolume); mp_treeWidget->addAction(actionPurgeVolume); mp_treeWidget->addAction(actionImportVolume); mp_treeWidget->addAction(actionExportVolume); mp_treeWidget->addAction(actionRelabelVolume); mp_treeWidget->addAction(actionVolumeFromPool); } else if (treedepth == 1) { mp_treeWidget->addAction(actionAllVolumesFromPool); } } } /* * Setup a context menu * Made separate from populate so that it would not create context menu over and * over as the tree is repopulated. */ void MediaList::createContextMenu() { mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu); connect(mp_treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(viewVolume())); connect(actionEditVolume, SIGNAL(triggered()), this, SLOT(editVolume())); connect(actionListJobsOnVolume, SIGNAL(triggered()), this, SLOT(showJobs())); connect(actionDeleteVolume, SIGNAL(triggered()), this, SLOT(deleteVolume())); connect(actionPurgeVolume, SIGNAL(triggered()), this, SLOT(purgeVolume())); connect(actionPruneVolume, SIGNAL(triggered()), this, SLOT(pruneVolume())); connect(actionImportVolume, SIGNAL(triggered()), this, SLOT(importVolume())); connect(actionExportVolume, SIGNAL(triggered()), this, SLOT(exportVolume())); connect(actionRelabelVolume, SIGNAL(triggered()), this, SLOT(relabelVolume())); connect(mp_treeWidget, SIGNAL( currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); /* connect to the action specific to this pages class */ connect(actionRefreshMediaList, SIGNAL(triggered()), this, SLOT(populateTree())); connect(actionAllVolumes, SIGNAL(triggered()), this, SLOT(allVolumes())); connect(actionAllVolumesFromPool, SIGNAL(triggered()), this, SLOT(allVolumesFromPool())); connect(actionVolumeFromPool, SIGNAL(triggered()), this, SLOT(volumeFromPool())); } /* * Virtual function which is called when this page is visible on the stack */ void MediaList::currentStackItem() { if (!m_populated || m_needs_repopulate) { populateTree(); } /* * Create the context menu for the medialist tree */ if (!m_populated) { createContextMenu(); } } /* * Called from the signal of the context sensitive menu to delete a volume! */ void MediaList::deleteVolume() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to delete?? !!!.\n" "This delete command is used to delete a Volume record and all associated catalog" " records that were created. This command operates only on the Catalog" " database and has no effect on the actual data written to a Volume. This" " command can be dangerous and we strongly recommend that you do not use" " it unless you know what you are doing. All Jobs and all associated" " records (File and JobMedia) will be deleted from the catalog." "Press OK to proceed with delete operation.?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString scmd; scmd = QString("delete volume=\"%1\"") .arg(m_currentVolumeName); consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } /* * Called from the signal of the context sensitive menu to purge! */ void MediaList::purgeVolume() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to purge ?? !!!.\n" "The Purge command will delete associated Catalog database records from Jobs and" " Volumes without considering the retention period. Purge works only on the" " Catalog database and does not affect data written to Volumes. This command can" " be dangerous because you can delete catalog records associated with current" " backups of files, and we recommend that you do not use it unless you know what" " you are doing.\n" "Press OK to proceed with the purge operation?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QString scmd; scmd = QString("purge volume=\"%1\"") .arg(m_currentVolumeName); consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } /* * Called from the signal of the context sensitive menu to prune! */ void MediaList::pruneVolume() { new prunePage(m_currentVolumeName, ""); } void MediaList::importVolume() { QString scmd; scmd = QString("import volume=\"%1\"") .arg(m_currentVolumeName); consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaList::exportVolume() { QString scmd; scmd = QString("export volume=\"%1\"") .arg(m_currentVolumeName); consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } /* * Called from the signal of the context sensitive menu to relabel! */ void MediaList::relabelVolume() { setConsoleCurrent(); new relabelDialog(m_console, m_currentVolumeName); } /* * Called from the signal of the context sensitive menu to purge! */ void MediaList::allVolumesFromPool() { QString cmd = "update volume AllFromPool=" + m_currentVolumeName; consoleCommand(cmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaList::allVolumes() { QString cmd = "update volume allfrompools"; consoleCommand(cmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } /* * Called from the signal of the context sensitive menu to purge! */ void MediaList::volumeFromPool() { QTreeWidgetItem *currentItem = mp_treeWidget->currentItem(); QTreeWidgetItem *parent = currentItem->parent(); QString pool = parent->text(0); QString scmd; scmd = QString("update volume=\"%1\" frompool=\"%2\"") .arg(m_currentVolumeName) .arg(pool); consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } /* * Write settings to save expanded states of the pools */ void MediaList::writeExpandedSettings() { if (m_topItem) { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("MediaListTreeExpanded"); int childcount = m_topItem->childCount(); for (int cnt=0; cntchild(cnt); settings.setValue(poolitem->text(0), poolitem->isExpanded()); } settings.endGroup(); } } bareos-Release-14.2.6/src/qt-console/medialist/medialist.h000066400000000000000000000036701263011562700234200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _MEDIALIST_H_ #define _MEDIALIST_H_ #include #include "ui_medialist.h" #include #include class MediaList : public Pages, public Ui::MediaListForm { Q_OBJECT public: MediaList(); ~MediaList(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); private slots: void populateTree(); void showJobs(); void viewVolume(); void editVolume(); void deleteVolume(); void purgeVolume(); void pruneVolume(); void importVolume(); void exportVolume(); void relabelVolume(); void allVolumesFromPool(); void allVolumes(); void volumeFromPool(); private: void createContextMenu(); void writeExpandedSettings(); QString m_currentVolumeName; QString m_currentVolumeId; bool m_populated; bool m_needs_repopulate; bool m_checkcurwidget; QTreeWidgetItem *m_topItem; }; #endif /* _MEDIALIST_H_ */ bareos-Release-14.2.6/src/qt-console/medialist/medialist.ui000066400000000000000000000103711263011562700236020ustar00rootroot00000000000000 MediaListForm 0 0 490 303 Media Tree 9 6 :/images/view-refresh.png Refresh Media List Requery the director for the list of media. :/images/cartridge-edit.png Edit Volume :/images/emblem-system.png List Jobs On Volume :/images/edit-delete.png Delete Volume :/images/edit-cut.png Prune Volume :/images/weather-severe-alert.png Purge Volume :/images/intern.png Import Volume :/images/extern.png Export Volume :/images/label.png Relabel Volume :/images/cartridge-edit.png Update all Volumes From Pool Update all Volumes From Pool Update all Volumes From Pool Update all Volumes From Pool :/images/cartridge-edit.png Update all Volumes from all Pools Update all Volumes from all Pools Update all Volumes from all Pools Update all Volumes from all Pools :/images/cartridge-edit.png Volume From Pool bareos-Release-14.2.6/src/qt-console/medialist/mediaview.cpp000066400000000000000000000354031263011562700237510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bat.h" #include #include #include #include "mediaview.h" #include "mediaedit/mediaedit.h" #include "mediainfo/mediainfo.h" #include "joblist/joblist.h" #include "relabel/relabel.h" #include "run/run.h" #include "util/fmtwidgetitem.h" MediaView::MediaView() : Pages() { setupUi(this); m_name = tr("Media"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge.png"))); connect(m_pbApply, SIGNAL(pressed()), this, SLOT(applyPushed())); connect(m_pbEdit, SIGNAL(pressed()), this, SLOT(editPushed())); connect(m_pbPurge, SIGNAL(pressed()), this, SLOT(purgePushed())); connect(m_pbDelete, SIGNAL(pressed()), this, SLOT(deletePushed())); connect(m_pbPrune, SIGNAL(pressed()), this, SLOT(prunePushed())); connect(m_pbImport, SIGNAL(pressed()), this, SLOT(importPushed())); connect(m_pbExport, SIGNAL(pressed()), this, SLOT(exportPushed())); connect(m_tableMedia, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(showInfoForMedia(QTableWidgetItem *))); /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */ m_populated = false; m_needs_repopulate = false; m_checkcurwidget = true; m_closeable = false; } void MediaView::showInfoForMedia(QTableWidgetItem * item) { QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); int row = item->row(); QString vol = m_tableMedia->item(row, 0)->text(); new MediaInfo(pageSelectorTreeWidgetItem, vol); // connect(j, SIGNAL(destroyed()), this, SLOT(populateTree())); } MediaView::~MediaView() { } bool MediaView::getSelection(QStringList &list) { int i, nb, nr_rows, row; bool *tab; QTableWidgetItem *it; QList items = m_tableMedia->selectedItems(); /* * See if anything is selected. */ nb = items.count(); if (!nb) { return false; } /* * Create a nibble map for each row so we can see if its * selected or not. */ nr_rows = m_tableMedia->rowCount(); tab = (bool *)malloc (nr_rows * sizeof(bool)); memset(tab, 0, sizeof(bool) * nr_rows); for (i = 0; i < nb; i++) { row = items[i]->row(); if (!tab[row]) { tab[row] = true; it = m_tableMedia->item(row, 0); list.append(it->text()); } } free(tab); return list.count() > 0; } void MediaView::applyPushed() { populateTable(); } void MediaView::editPushed() { QStringList sel; QString cmd; getSelection(sel); for(int i=0; igetFromHash(this), cmd); } } void MediaView::purgePushed() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to purge ?? !!!.\n" "The Purge command will delete associated Catalog database records from Jobs and" " Volumes without considering the retention period. Purge works only on the" " Catalog database and does not affect data written to Volumes. This command can" " be dangerous because you can delete catalog records associated with current" " backups of files, and we recommend that you do not use it unless you know what" " you are doing.\n" "Press OK to proceed with the purge operation?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QStringList sel; QString scmd; int i; getSelection(sel); for (i = 0; i < sel.count(); i++) { scmd = QString("purge volume=\"%1\"") .arg(sel.at(i)); consoleCommand(scmd); } /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaView::prunePushed() { QStringList sel; QString scmd; int i; getSelection(sel); for (i = 0; i < sel.count(); i++) { scmd = QString("prune volume=\"%1\"") .arg(sel.at(i)); consoleCommand(scmd); } /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaView::importPushed() { QStringList sel; QString scmd; int i; getSelection(sel); if (sel.count() == 0) { return; } scmd = "import "; for (i = 0; i < sel.count(); i++) { scmd += QString("volume=\"%1\" ") .arg(sel.at(i)); } /* * Strip the trailing space. */ if (i > 0) { scmd.chop(1); } consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaView::exportPushed() { QStringList sel; QString scmd; int i; getSelection(sel); if (sel.count() == 0) { return; } scmd = "export "; for (i = 0; i < sel.count(); i++) { scmd += QString("volume=\"%1\" ") .arg(sel.at(i)); } /* * Strip the trailing space. */ if (i > 0) { scmd.chop(1); } consoleCommand(scmd); /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaView::deletePushed() { if (QMessageBox::warning(this, "Bat", tr("Are you sure you want to delete?? !!!.\n" "This delete command is used to delete a Volume record and all associated catalog" " records that were created. This command operates only on the Catalog" " database and has no effect on the actual data written to a Volume. This" " command can be dangerous and we strongly recommend that you do not use" " it unless you know what you are doing. All Jobs and all associated" " records (File and JobMedia) will be deleted from the catalog." "Press OK to proceed with delete operation.?"), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) { return; } QStringList sel; QString scmd; int i; getSelection(sel); for (i = 0; i < sel.count(); i++) { scmd = QString("delete volume=\"%1\"") .arg(sel.at(i)); consoleCommand(scmd); } /* * Volume list needs (re)populate. */ m_needs_repopulate = true; } void MediaView::populateForm() { m_cbPool->clear(); m_cbPool->addItem(""); m_cbPool->addItems(m_console->pool_list); m_cbStatus->clear(); m_cbStatus->addItem(""); m_cbStatus->addItems(m_console->volstatus_list); m_cbMediaType->clear(); m_cbMediaType->addItem(""); m_cbMediaType->addItems(m_console->mediatype_list); m_cbLocation->clear(); m_cbLocation->addItem(""); m_cbLocation->addItems(m_console->location_list); } /* * If chkExpired button is checked, we can remove all non Expired * entries */ void MediaView::filterExipired(QStringList &list) { utime_t t, now = time(NULL); QString resultline, stat, LastWritten; QStringList fieldlist; /* We should now in advance how many rows we will have */ if (m_chkExpired->isChecked()) { for (int i=list.size() -1; i >= 0; i--) { fieldlist = list.at(i).split("\t"); ASSERT(fieldlist.size() != 9); LastWritten = fieldlist.at(7); if (LastWritten == "") { list.removeAt(i); } else { stat = fieldlist.at(8); t = str_to_utime(LastWritten.toAscii().data()); t = t + stat.toULongLong(); if (t > now) { list.removeAt(i); } } } } } /* * The main meat of the class!! The function that querries the director and * creates the widgets with appropriate values. */ void MediaView::populateTable() { utime_t t; time_t ttime; QString stat, resultline, query; QString str_usage; QHash hash_size; QStringList fieldlist, results; char buf[256]; float usage; m_populated = true; Freeze frz(*m_tableMedia); /* disable updating*/ QStringList where; QString cmd; if (m_cbPool->currentText() != "") { cmd = " Pool.Name = '" + m_cbPool->currentText() + "'"; where.append(cmd); } if (m_cbStatus->currentText() != "") { cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'"; where.append(cmd); } if (m_cbStatus->currentText() != "") { cmd = " Media.VolStatus = '" + m_cbStatus->currentText() + "'"; where.append(cmd); } if (m_cbMediaType->currentText() != "") { cmd = " Media.MediaType = '" + m_cbMediaType->currentText() + "'"; where.append(cmd); } if (m_cbLocation->currentText() != "") { cmd = " Location.Location = '" + m_cbLocation->currentText() + "'"; where.append(cmd); } if (m_textName->text() != "") { cmd = " Media.VolumeName like '%" + m_textName->text() + "%'"; where.append(cmd); } if (where.size() > 0) { cmd = " WHERE " + where.join(" AND "); } else { cmd = ""; } query = "SELECT AVG(VolBytes) AS size, COUNT(1) as nb, " "MediaType FROM Media " "WHERE VolStatus IN ('Full', 'Used') " "GROUP BY MediaType"; if (mainWin->m_sqlDebug) { Pmsg1(000, "MediaView query cmd : %s\n",query.toUtf8().data()); } if (m_console->sql_cmd(query, results)) { foreach (resultline, results) { fieldlist = resultline.split("\t"); if (fieldlist.at(1).toInt() >= 1) { // MediaType hash_size[fieldlist.at(2)] = fieldlist.at(0).toFloat(); } } } m_tableMedia->clearContents(); query = "SELECT VolumeName, InChanger, " "Slot, MediaType, VolStatus, VolBytes, Pool.Name, " "LastWritten, Media.VolRetention " "FROM Media JOIN Pool USING (PoolId) " "LEFT JOIN Location ON (Media.LocationId=Location.LocationId) " + cmd + " ORDER BY VolumeName LIMIT " + m_sbLimit->cleanText(); m_tableMedia->sortByColumn(0, Qt::AscendingOrder); m_tableMedia->setSortingEnabled(false); /* Don't sort during insert */ results.clear(); if (mainWin->m_sqlDebug) { Pmsg1(000, "MediaView query cmd : %s\n",query.toUtf8().data()); } if (m_console->sql_cmd(query, results)) { int row=0; filterExipired(results); m_tableMedia->setRowCount(results.size()); foreach (resultline, results) { // should have only one result int index = 0; QString VolBytes, MediaType, LastWritten, VolStatus; fieldlist = resultline.split("\t"); if (fieldlist.size() != 10) { Pmsg1(0, "Discarding %s\n", resultline.data()); continue; } QStringListIterator fld(fieldlist); TableItemFormatter mediaitem(*m_tableMedia, row); /* VolumeName */ mediaitem.setTextFld(index++, fld.next()); /* Online */ mediaitem.setInChanger(index++, fld.next()); /* Slot */ mediaitem.setNumericFld(index++, fld.next()); MediaType = fld.next(); VolStatus = fld.next(); /* Volume bytes */ VolBytes = fld.next(); mediaitem.setBytesFld(index++, VolBytes); /* Usage */ usage = 0; if (hash_size.contains(MediaType) && hash_size[MediaType] != 0) { usage = VolBytes.toLongLong() * 100 / hash_size[MediaType]; } mediaitem.setPercent(index++, usage); /* Volstatus */ mediaitem.setVolStatusFld(index++, VolStatus); /* Pool */ mediaitem.setTextFld(index++, fld.next()); /* MediaType */ mediaitem.setTextFld(index++, MediaType); LastWritten = fld.next(); buf[0] = 0; if (LastWritten != "") { stat = fld.next(); // VolUseDuration t = str_to_utime(LastWritten.toAscii().data()); t = t + stat.toULongLong(); ttime = t; bstrutime(buf, sizeof(buf), ttime); } /* LastWritten */ mediaitem.setTextFld(index++, LastWritten); /* When expired */ mediaitem.setTextFld(index++, buf); row++; } } m_tableMedia->resizeColumnsToContents(); m_tableMedia->resizeRowsToContents(); m_tableMedia->verticalHeader()->hide(); m_tableMedia->setSortingEnabled(true); /* make read only */ m_tableMedia->setEditTriggers(QAbstractItemView::NoEditTriggers); } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void MediaView::PgSeltreeWidgetClicked() { if (!m_populated) { populateForm(); populateTable(); } if (!isOnceDocked()) { dockPage(); } } /* * Virtual function which is called when this page is visible on the stack */ void MediaView::currentStackItem() { if (!m_populated) { populateForm(); } if (!m_populated || m_needs_repopulate) { populateTable(); } } // /* // * Called from the signal of the context sensitive menu to relabel! // */ // void MediaView::relabelVolume() // { // setConsoleCurrent(); // new relabelDialog(m_console, m_currentVolumeName); // } // // /* // * Called from the signal of the context sensitive menu to purge! // */ // void MediaView::allVolumesFromPool() // { // QString cmd = "update volume AllFromPool=" + m_currentVolumeName; // consoleCommand(cmd); // // /* // * Volume list needs (re)populate. // */ // m_needs_repopulate = true; // } // // void MediaView::allVolumes() // { // QString cmd = "update volume allfrompools"; // consoleCommand(cmd); // // /* // * Volume list needs (re)populate. // */ // m_needs_repopulate = true; // } // // /* // * Called from the signal of the context sensitive menu to purge! // */ // void MediaView::volumeFromPool() // { // QTreeWidgetItem *currentItem = mp_treeWidget->currentItem(); // QTreeWidgetItem *parent = currentItem->parent(); // QString pool = parent->text(0); // QString scmd; // // scmd = QString("update volume=\"%1\" frompool=\"%2\"") // .arg(m_currentVolumeName) // .arg(pool); // consoleCommand(scmd); // // /* // * Volume list needs (re)populate. // */ // m_needs_repopulate = true; // } // bareos-Release-14.2.6/src/qt-console/medialist/mediaview.h000066400000000000000000000033501263011562700234120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MEDIAVIEW_H_ #define _MEDIAVIEW_H_ #include #include "ui_mediaview.h" #include #include class MediaView : public Pages, public Ui::MediaViewForm { Q_OBJECT public: MediaView(); ~MediaView(); private slots: void populateTable(); void populateForm(); void PgSeltreeWidgetClicked(); void currentStackItem(); void applyPushed(); void editPushed(); void purgePushed(); void prunePushed(); void importPushed(); void exportPushed(); void deletePushed(); bool getSelection(QStringList &ret); void showInfoForMedia(QTableWidgetItem * item); void filterExipired(QStringList &list); // void relabelVolume(); // void allVolumesFromPool(); // void allVolumes(); // void volumeFromPool(); private: bool m_populated; bool m_needs_repopulate; bool m_checkcurwidget; QTreeWidgetItem *m_topItem; }; #endif /* _MEDIAVIEW_H_ */ bareos-Release-14.2.6/src/qt-console/medialist/mediaview.ui000066400000000000000000000206221263011562700236010ustar00rootroot00000000000000 MediaViewForm 0 0 949 638 Form Edit :/images/edit.png:/images/edit.png true Purge :/images/purge.png:/images/purge.png true Delete :/images/purge.png:/images/purge.png true Prune :/images/edit-cut.png:/images/edit-cut.png true Import :/images/intern.png:/images/intern.png true Export :/images/extern.png:/images/extern.png true Qt::Horizontal 40 20 Filter Media Type: Status: Limit: 1 1000 100 Name: 0 0 Qt::Horizontal 40 20 Pool: Location: Expired Qt::Horizontal 40 20 Apply :/images/view-refresh.png:/images/view-refresh.png QAbstractItemView::ExtendedSelection QAbstractItemView::SelectRows true Volume Name Online Slot Vol Bytes Vol Usage Vol Status Pool Media Type Last Written When expire? bareos-Release-14.2.6/src/qt-console/mount/000077500000000000000000000000001263011562700204555ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/mount/mount.cpp000066400000000000000000000044051263011562700223260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Label Dialog class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "mount/mount.h" #include /* * A constructor */ mountDialog::mountDialog(Console *console, QString &storageName) : QDialog() { m_console = console; m_storageName = storageName; m_conn = m_console->notifyOff(); setupUi(this); this->show(); QString labelText( tr("Storage : %1").arg(storageName) ); storageLabel->setText(labelText); } void mountDialog::accept() { QString scmd; if (m_storageName == "") { QMessageBox::warning(this, tr("No Storage name"), tr("No Storage name given"), QMessageBox::Ok, QMessageBox::Ok); return; } this->hide(); scmd = QString("mount storage=\"%1\" slot=%2") .arg(m_storageName) .arg(slotSpin->value()); if (mainWin->m_commandDebug) { Pmsg1(000, "sending command : %s\n",scmd.toUtf8().data()); } m_console->display_text( tr("Context sensitive command :\n\n")); m_console->display_text("**** "); m_console->display_text(scmd + " ****\n"); m_console->display_text(tr("Director Response :\n\n")); m_console->write_dir(scmd.toUtf8().data()); m_console->displayToPrompt(m_conn); m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } void mountDialog::reject() { this->hide(); m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } bareos-Release-14.2.6/src/qt-console/mount/mount.h000066400000000000000000000023671263011562700220000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, February MMVII */ #ifndef _MOUNT_H_ #define _MOUNT_H_ #include #include "ui_mount.h" #include class mountDialog : public QDialog, public Ui::mountForm { Q_OBJECT public: mountDialog(Console *console, QString &storage); private slots: void accept(); void reject(); private: Console *m_console; QString m_storageName; int m_conn; }; #endif /* _MOUNT_H_ */ bareos-Release-14.2.6/src/qt-console/mount/mount.ui000066400000000000000000000116711263011562700221640ustar00rootroot00000000000000 mountForm Qt::WindowModal 0 0 400 300 Label 9 6 16777215 20 TextLabel Qt::AlignCenter 0 6 Slot: slotSpin 10000 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok Qt::Vertical QSizePolicy::Maximum 21 16 0 6 Qt::Horizontal 71 21 16777215 30 <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Mount a Slot</span></p></body></html> Qt::Horizontal 81 20 Qt::Vertical QSizePolicy::Maximum 382 16 buttonBox accepted() mountForm accept() 248 254 157 274 buttonBox rejected() mountForm reject() 316 260 286 274 bareos-Release-14.2.6/src/qt-console/pages.cpp000066400000000000000000000274501263011562700211260ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #include "bat.h" #include "pages.h" /* A global function */ bool isWin32Path(QString &fullPath) { if (fullPath.size()<2) { return false; } bool toret = fullPath[1].toAscii() == ':' && fullPath[0].isLetter(); if (mainWin->m_miscDebug) { if (toret) Pmsg1(000, "returning from isWin32Path true %s\n", fullPath.toUtf8().data()); else Pmsg1(000, "returning from isWin32Path false %s\n", fullPath.toUtf8().data()); } return toret; } /* Need to initialize variables here */ Pages::Pages() : QWidget() { m_docked = false; m_onceDocked = false; m_closeable = true; m_dockOnFirstUse = true; m_console = NULL; m_parent = NULL; } /* first Use Dock */ void Pages::firstUseDock() { if (!m_onceDocked && m_dockOnFirstUse) { dockPage(); } } /* * dockPage * This function is intended to be called from within the Pages class to pull * a window from floating to in the stack widget. */ void Pages::dockPage() { if (isDocked()) { return; } /* These two lines are for making sure if it is being changed from a window * that it has the proper window flag and parent. */ setWindowFlags(Qt::Widget); /* calculate the index that the tab should be inserted into */ int tabPos = 0; QTreeWidgetItemIterator it(mainWin->treeWidget); while (*it) { Pages *somepage = mainWin->getFromHash(*it); if (this == somepage) { tabPos += 1; break; } int pageindex = mainWin->tabWidget->indexOf(somepage); if (pageindex != -1) { tabPos = pageindex; } ++it; } /* This was being done already */ m_parent->insertTab(tabPos, this, m_name); /* Set docked flag */ m_docked = true; m_onceDocked = true; mainWin->tabWidget->setCurrentWidget(this); /* lets set the page selectors action for docking or undocking */ setContextMenuDockText(); } /* * undockPage * This function is intended to be called from within the Pages class to put * a window from the stack widget to a floating window. */ void Pages::undockPage() { if (!isDocked()) { return; } /* Change from a stacked widget to a normal window */ m_parent->removeTab(m_parent->indexOf(this)); setWindowFlags(Qt::Window); show(); /* Clear docked flag */ m_docked = false; /* The window has been undocked, lets change the context menu */ setContextMenuDockText(); } /* * This function is intended to be called with the subclasses. When it is * called the specific sublclass does not have to be known to Pages. When it * is called this function will change the page from it's current state of being * docked or undocked and change it to the other. */ void Pages::togglePageDocking() { if (m_docked) { undockPage(); } else { dockPage(); } } /* * This function is because I wanted for some reason to keep it protected but still * give any subclasses the ability to find out if it is currently stacked or not. */ bool Pages::isDocked() { return m_docked; } /* * This function is because after the tabbed widget was added I could not tell * from is docked if it had been docked yet. To prevent status pages from requesting * status from the director */ bool Pages::isOnceDocked() { return m_onceDocked; } /* * To keep m_closeable protected as well */ bool Pages::isCloseable() { return m_closeable; } void Pages::hidePage() { if (!m_parent || (m_parent->indexOf(this) <= 0)) { return; } /* Remove any tab that may exist */ m_parent->removeTab(m_parent->indexOf(this)); hide(); /* Clear docked flag */ m_docked = false; /* The window has been undocked, lets change the context menu */ setContextMenuDockText(); } /* * When a window is closed, this slot is called. The idea is to put it back in the * stack here, and it works. I wanted to get it to the top of the stack so that the * user immediately sees where his window went. Also, if he undocks the window, then * closes it with the tree item highlighted, it may be confusing that the highlighted * treewidgetitem is not the stack item in the front. */ void Pages::closeEvent(QCloseEvent* event) { /* A Widget was closed, lets toggle it back into the window, and set it in front. */ dockPage(); /* this fixes my woes of getting the widget to show up on top when closed */ event->ignore(); /* Set the current tree widget item in the Page Selector window to the item * which represents "this" * Which will also bring "this" to the top of the stacked widget */ setCurrent(); } /* * The next three are virtual functions. The idea here is that each subclass will have the * built in virtual function to override if the programmer wants to populate the window * when it it is first clicked. */ void Pages::PgSeltreeWidgetClicked() { } /* * Virtual function which is called when this page is visible on the stack. * This will be overridden by classes that want to populate if they are on the * top. */ void Pages::currentStackItem() { } /* * Function to close the stacked page and remove the widget from the * Page selector window */ void Pages::closeStackPage() { /* First get the tree widget item and destroy it */ QTreeWidgetItem *item=mainWin->getFromHash(this); /* remove the QTreeWidgetItem <-> page from the hash */ if (item) { mainWin->hashRemove(item, this); /* remove the item from the page selector by destroying it */ delete item; } /* remove this */ delete this; } /* * Function to set members from the external mainwin and it's overload being * passed a specific QTreeWidgetItem to be it's parent on the tree */ void Pages::pgInitialize() { pgInitialize(QString(), NULL); } void Pages::pgInitialize(const QString &name) { pgInitialize(name, NULL); } void Pages::pgInitialize(const QString &tname, QTreeWidgetItem *parentTreeWidgetItem) { m_docked = false; m_onceDocked = false; if (tname.size()) { m_name = tname; } m_parent = mainWin->tabWidget; m_console = mainWin->currentConsole(); if (!parentTreeWidgetItem) { parentTreeWidgetItem = m_console->directorTreeItem(); } QTreeWidgetItem *item = new QTreeWidgetItem(parentTreeWidgetItem); QString name; treeWidgetName(name); item->setText(0, name); mainWin->hashInsert(item, this); setTitle(); } /* * Virtual Function to return a name * All subclasses should override this function */ void Pages::treeWidgetName(QString &name) { name = m_name; } /* * Function to simplify executing a console command and bringing the * console to the front of the stack */ void Pages::consoleCommand(QString &command) { consoleCommand(command, true); } void Pages::consoleCommand(QString &command, bool setCurrent) { int conn; bool donotify = false; if (m_console->getDirComm(conn)) { if (m_console->is_notify_enabled(conn)) { donotify = true; m_console->notify(conn, false); } consoleCommand(command, conn, setCurrent); if (donotify) { m_console->notify(conn, true); } } } void Pages::consoleCommand(QString &command, int conn) { consoleCommand(command, conn, true); } void Pages::consoleCommand(QString &command, int conn, bool setCurrent) { /* Bring this director's console to the front of the stack */ if (setCurrent) { setConsoleCurrent(); } QString displayhtml(""); displayhtml += command + "\n"; m_console->display_html(displayhtml); m_console->display_text("\n"); mainWin->waitEnter(); m_console->write_dir(conn, command.toUtf8().data(), false); m_console->displayToPrompt(conn); mainWin->waitExit(); } /* * Function for handling undocked windows becoming active. * Change the currently selected item in the page selector window to the now * active undocked window. This will also make the console for the undocked * window m_currentConsole. */ void Pages::changeEvent(QEvent *event) { if ((event->type() == QEvent::ActivationChange) && (isActiveWindow())) { setCurrent(); } } /* * Function to simplify getting the name of the class and the director into * the caption or title of the window */ void Pages::setTitle() { QString wdgname, director; treeWidgetName(wdgname); m_console->getDirResName(director); QString title = tr("%1 of Director %2").arg(wdgname).arg(director); setWindowTitle(title); } /* * Bring the current directors console window to the top of the stack. */ void Pages::setConsoleCurrent() { mainWin->treeWidget->setCurrentItem(mainWin->getFromHash(m_console)); } /* * Bring this window to the top of the stack. */ void Pages::setCurrent() { mainWin->treeWidget->setCurrentItem(mainWin->getFromHash(this)); } /* * Function to set the text of the toggle dock context menu when page and * widget item are NOT known. */ void Pages::setContextMenuDockText() { QTreeWidgetItem *item = mainWin->getFromHash(this); QString docktext; if (isDocked()) { docktext = tr("UnDock %1 Window").arg(item->text(0)); } else { docktext = tr("ReDock %1 Window").arg(item->text(0)); } mainWin->actionToggleDock->setText(docktext); setTreeWidgetItemDockColor(); } /* * Function to set the color of the tree widget item based on whether it is * docked or not. */ void Pages::setTreeWidgetItemDockColor() { QTreeWidgetItem* item = mainWin->getFromHash(this); if (item) { if (item->text(0) != tr("Console")) { if (isDocked()) { /* Set the brush to blue if undocked */ QBrush blackBrush(Qt::black); item->setForeground(0, blackBrush); } else { /* Set the brush back to black if docked */ QBrush blueBrush(Qt::blue); item->setForeground(0, blueBrush); } } } } /* Function to get a list of volumes */ void Pages::getVolumeList(QStringList &volumeList) { QString query("SELECT VolumeName AS Media FROM Media ORDER BY Media"); if (mainWin->m_sqlDebug) { Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { QString field; QStringList fieldlist; /* Iterate through the lines of results. */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); volumeList.append(fieldlist[0]); } /* foreach resultline */ } /* if results from query */ } /* Function to get a list of volumes */ void Pages::getStatusList(QStringList &statusLongList) { QString statusQuery("SELECT JobStatusLong FROM Status"); if (mainWin->m_sqlDebug) { Pmsg1(000, "Query cmd : %s\n",statusQuery.toUtf8().data()); } QStringList statusResults; if (m_console->sql_cmd(statusQuery, statusResults)) { QString field; QStringList fieldlist; /* Iterate through the lines of results. */ foreach (QString resultline, statusResults) { fieldlist = resultline.split("\t"); statusLongList.append(fieldlist[0]); } /* foreach resultline */ } /* if results from statusquery */ } bareos-Release-14.2.6/src/qt-console/pages.h000066400000000000000000000061501263011562700205650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _PAGES_H_ #define _PAGES_H_ #include #include /* * The Pages Class * * This class is inherited by all widget windows which are on the stack * It is for the purpose of having a consistent set of functions and properties * in all of the subclasses to accomplish tasks such as pulling a window out * of or into the stack. It also provides virtual functions called * from in mainwin so that subclasses can contain functions to allow them * to populate the screens at the time of first viewing, (when selected) as * opposed to the first creation of the console connection. The * console is not connected until after the page selector tree has been * populated. */ class Console; class Pages : public QWidget { public: /* methods */ Pages(); void dockPage(); void undockPage(); void hidePage(); void togglePageDocking(); bool isDocked(); bool isOnceDocked(); bool isCloseable(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); void closeStackPage(); Console *console() { return m_console; }; void setCurrent(); void setContextMenuDockText(); void setTreeWidgetItemDockColor(); void consoleCommand(QString &); void consoleCommand(QString &, int conn); void consoleCommand(QString &, bool setCurrent); void consoleCommand(QString &, int conn, bool setCurrent); QString &name() { return m_name; }; void getVolumeList(QStringList &); void getStatusList(QStringList &); void firstUseDock(); /* members */ QTabWidget *m_parent; QList m_contextActions; public slots: /* closeEvent is a virtual function inherited from QWidget */ virtual void closeEvent(QCloseEvent* event); protected: /* methods */ void pgInitialize(); void pgInitialize(const QString &); void pgInitialize(const QString &, QTreeWidgetItem *); virtual void treeWidgetName(QString &); virtual void changeEvent(QEvent *event); void setConsoleCurrent(); void setTitle(); /* members */ bool m_closeable; bool m_docked; bool m_onceDocked; bool m_dockOnFirstUse; Console *m_console; QString m_name; }; #endif /* _PAGES_H_ */ bareos-Release-14.2.6/src/qt-console/prefs.ui000066400000000000000000000530511263011562700207750ustar00rootroot00000000000000 PrefsForm 0 0 470 533 0 0 Preferences images/bareos_1.png 9 9 9 9 6 6 0 Timers 60 60 180 106 0 0 Messages Options 11 81 158 16 Message check interval in seconds 11 25 158 20 Check Messages 11 51 158 24 3600 Joblist 9 9 9 9 6 6 0 0 Joblist Limit Options 9 9 9 9 6 6 0 0 0 0 6 6 Days Limit 1 10000 7 1 10000 25 Record Limit Misc 30 220 311 111 Convert 20 20 231 22 Convert Off 20 50 231 22 Display Bytes using IEC units (1024B = 1 KiB) 20 80 231 22 Display Bytes using SI units (1000B = 1KB) 30 10 311 61 Context Sensitive List Commands 9 9 9 9 6 6 Execute Long List 30 80 311 121 Open Pages 10 30 241 20 Open Plot page on startup 10 60 241 20 Open Browser page on startup 10 90 241 20 Open Director Status page on startup Debug 9 9 9 9 6 6 0 0 Debugging Options Debug comm Debug multiple connection Display all messages in console Debug Sql queries Debug Commands Debug Miscelaneous Items RestoreTree 9 9 9 9 6 6 0 0 Debugging Options 9 9 9 9 6 6 0 0 0 0 6 6 Restore Debug 2 Directory Item Changed Restore Debug 1 Directory Current Item Changed Debug Update File Table Debug Version Table Item Changed Debug File Table Item Changed Debug Icon State Debug Update Checks Debug Restore Debug 3 Update Version Table Debug Populate Directory Debug Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok 6 0 0 0 0 Qt::Horizontal 81 20 0 0 <h2>Preferences</h2> Qt::Horizontal 101 20 buttonBox accepted() PrefsForm accept() 248 254 157 274 buttonBox rejected() PrefsForm reject() 316 260 286 274 bareos-Release-14.2.6/src/qt-console/qstd.cpp000066400000000000000000000050521263011562700207740ustar00rootroot00000000000000//start id=namespace #include "qstd.h" /* QTextStreams look a lot like iostreams, we just have to point them to the right place. */ //start id=streamdefs QTextStream qstd::cin(stdin, QIODevice::ReadOnly); QTextStream qstd::cout(stdout, QIODevice::WriteOnly); QTextStream qstd::cerr(stderr, QIODevice::WriteOnly); //end /* Namespace members are like static class members */ bool qstd::yes(QString question) { QString ans; cout << QString(" %1 [y/n]? ").arg(question); cout.flush(); ans = cin.readLine(); return (ans.toUpper().startsWith("Y", Qt::CaseInsensitive)); } //end bool qstd::more(QString s) { return yes(QString("Another %1").arg(s)); } int qstd::promptInt(int base /* =10 */) { /* Usage: int n = promptInt(); */ QString numstr; int result; bool ok; cout << ": " << flush; while (1) { numstr = cin.readLine(); result = numstr.toInt(&ok, base); if (!ok) { cout << "Invalid number. Try again: "; cout.flush(); } else return result; } } double qstd::promptDouble() { /* Usage: double d = promptDouble(); */ QString numstr; double result; bool ok; while (1) { numstr = cin.readLine(); result = numstr.toDouble(&ok); if (!ok) { cout << "Invalid number. Try again: "; cout.flush(); } else return result; } } void qstd::promptOutputFile(QFile& outfile) { QString filename; while (1) { cout << "Please enter the file name for saving this data: "; cout.flush(); filename = cin.readLine(); outfile.setFileName(filename); bool fileExists = outfile.open(QIODevice::ReadOnly); if (!fileExists) break; if (yes("File already exists ... Ok to overwrite")) break; outfile.close(); outfile.reset(); } outfile.close(); outfile.reset(); outfile.open(QIODevice::WriteOnly); cout << filename << " open for writing ...\n"; cout.flush(); } void qstd::promptInputFile(QFile& infile) { QString filename; while (1) { cout << "Name of the file to be read: "; cout.flush(); filename = cin.readLine(); infile.setFileName(filename); bool fileExists = infile.open(QIODevice::ReadOnly); if (fileExists) break; cout << "File does not exist ... Please try again. \n"; cout.flush(); infile.reset(); } cout << filename << " open for reading ...\n"; cout.flush(); } bareos-Release-14.2.6/src/qt-console/qstd.h000066400000000000000000000046121263011562700204420ustar00rootroot00000000000000#ifndef QSTD_H #define QSTD_H #include #include #include /** @short helper objects and functions which help reduce the need for char[] and the standard library. defines three @ref QTextStream instances which behave like the c++ standard iostreams, bound to the standard in/out/error. Also provided, some helper functions for writing interactive stdin/stdout applications. */ //start namespace qstd { /** @short An alias for standard input */ extern QTextStream cin; /* declared only, defined in the .cpp file */ /** @short An alias for standard output */ extern QTextStream cout; /** @short An alias for standard error */ extern QTextStream cerr; /** yes/no prompt interactive stdin UI - prompts user with a yes/no question. Repeatedly-asks until user supplies a valid answer. @param yesNoQuestion the yes/no question @return true/false depending on what the user responded. */ bool yes(QString yesNoQuestion); /** Convenience function that feeds a specific question to the yes() function. @usage do {.....} while(more ("foobar")); so that user sees the question: "Another foobar (y/n)? " @param name of the item being handled by the loop. */ bool more(QString prompt); /** A function for safely taking an int from the keyboard. Takes data into a QString and tests to make sure it can be converted to int before returning. @param base allows choice of number base. @return returns validated int. */ int promptInt(int base = 10); /** A function for safely taking a double from the keyboard. Takes data into a QString and tests to make sure it can be converted to double before returning. @return returns validated int. */ double promptDouble(); /** Complete dialog for opening a file for output. Asks user for file name, checks to see if file already exists and, if so, asks the user if it is ok to overwrite. @param Reference QFile parameter is set to point to the (eventually) opened file. */ /** @short Dialog for a output file prompt */ void promptOutputFile(QFile& outfile); /** @short Dialog for input file prompt */ void promptInputFile(QFile& infile); //end } #endif bareos-Release-14.2.6/src/qt-console/relabel/000077500000000000000000000000001263011562700207215ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/relabel/relabel.cpp000066400000000000000000000074031263011562700230370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Label Dialog class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "relabel.h" #include /* * An overload of the constructor to have a default storage show in the * combobox on start. Used from context sensitive in storage class. */ relabelDialog::relabelDialog(Console *console, QString &fromVolume) { m_console = console; m_fromVolume = fromVolume; m_conn = m_console->notifyOff(); setupUi(this); storageCombo->addItems(console->storage_list); poolCombo->addItems(console->pool_list); volumeName->setText(fromVolume); QString fromText(tr("From Volume : ")); fromText += fromVolume; fromLabel->setText(fromText); QStringList defFields; if (getDefs(defFields) >= 1) { poolCombo->setCurrentIndex(poolCombo->findText(defFields[1], Qt::MatchExactly)); storageCombo->setCurrentIndex(storageCombo->findText(defFields[0], Qt::MatchExactly)); } this->show(); } /* * Use a sql statement to get some defaults */ int relabelDialog::getDefs(QStringList &fieldlist) { QString job, client, fileset; QString query(""); query = "SELECT MediaType AS MediaType, Pool.Name AS PoolName" " FROM Media" " LEFT OUTER JOIN Pool ON Media.PoolId = Pool.PoolId" " WHERE VolumeName = \'" + m_fromVolume + "\'"; if (mainWin->m_sqlDebug) { Pmsg1(000, "query = %s\n", query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(query, results)) { QString field; /* Iterate through the lines of results, there should only be one. */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); } /* foreach resultline */ } /* if results from query */ return results.count(); } void relabelDialog::accept() { QString scmd; if (volumeName->text().toUtf8().data()[0] == 0) { QMessageBox::warning(this, tr("No Volume name"), tr("No Volume name given"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_fromVolume == volumeName->text().toUtf8()) { QMessageBox::warning(this, tr("New name must be different"), tr("New name must be different"), QMessageBox::Ok, QMessageBox::Ok); return; } this->hide(); scmd = QString("relabel storage=\"%1\" oldvolume=\"%2\" volume=\"%3\" pool=\"%4\" slot=%5") .arg(storageCombo->currentText()) .arg(m_fromVolume) .arg(volumeName->text()) .arg(poolCombo->currentText()) .arg(slotSpin->value()); if (mainWin->m_commandDebug) { Pmsg1(000, "sending command : %s\n",scmd.toUtf8().data()); } m_console->write_dir(scmd.toUtf8().data()); m_console->displayToPrompt(m_conn); m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } void relabelDialog::reject() { this->hide(); m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } bareos-Release-14.2.6/src/qt-console/relabel/relabel.h000066400000000000000000000024711263011562700225040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, February MMVII */ #ifndef _RELABEL_H_ #define _RELABEL_H_ #include #include "ui_relabel.h" #include class relabelDialog : public QDialog, public Ui::relabelForm { Q_OBJECT public: relabelDialog(Console *console, QString &fromVolume); private: int getDefs(QStringList &fieldlist); private slots: void accept(); void reject(); private: Console *m_console; QString m_fromVolume; int m_conn; }; #endif /* _RELABEL_H_ */ bareos-Release-14.2.6/src/qt-console/relabel/relabel.ui000066400000000000000000000144021263011562700226670ustar00rootroot00000000000000 relabelForm Qt::WindowModal 0 0 400 212 Label 9 6 16777215 20 From Volume : Qt::AlignCenter Qt::Vertical QSizePolicy::Maximum 382 16 Qt::Vertical QSizePolicy::Maximum 21 16 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok 0 6 10000 Pool: poolCombo Storage: storageCombo 200 0 New Volume Name: volumeName Slot: slotSpin 0 6 Qt::Horizontal 71 21 16777215 30 <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Relabel a Volume</span></p></body></html> Qt::Horizontal 81 20 buttonBox accepted() relabelForm accept() 248 254 157 274 buttonBox rejected() relabelForm reject() 316 260 286 274 bareos-Release-14.2.6/src/qt-console/restore/000077500000000000000000000000001263011562700207765ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/restore/brestore.cpp000066400000000000000000000573341263011562700233430ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * bRestore Class (Eric's brestore) * * Kern Sibbald, January MMVII */ #include "bat.h" #include "restore.h" #include "util/fmtwidgetitem.h" bRestore::bRestore() : Pages() { m_name = tr("bRestore"); m_client = ""; setupUi(this); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0, QIcon(QString::fromUtf8(":images/browse.png"))); m_populated = false; m_closeable = false; m_current = NULL; RestoreList->setAcceptDrops(true); } // Populate client table and job associated void bRestore::setClient() { // Select the same client, don't touch if (m_client == ClientList->currentText()) { return; } m_client = ClientList->currentText(); FileList->clearContents(); FileRevisions->clearContents(); JobList->clear(); JobList->setEnabled(true); LocationEntry->clear(); m_path = ""; m_pathid = 0; if (ClientList->currentIndex() < 1) { JobList->setEnabled(false); return; } JobList->addItem("Job list for " + m_client); QString jobQuery = "SELECT Job.Jobid AS JobId, Job.StartTime AS StartTime," " Job.Level AS Level," " Job.Name AS Name" " FROM Job JOIN Client USING (ClientId)" " WHERE" " Job.JobStatus IN ('T','W') AND Job.Type='B' AND" " Client.Name='" + m_client + "' ORDER BY StartTime DESC" ; QString job; QStringList results; QStringList fieldlist; if (m_console->sql_cmd(jobQuery, results)) { /* Iterate through the record returned from the query */ foreach (QString resultline, results) { // 0 1 2 3 // JobId, StartTime, Level, Name fieldlist = resultline.split("\t"); job = fieldlist[1] + " " + fieldlist[3] + "(" + fieldlist[2] + ") " + fieldlist[0]; JobList->addItem(job, QVariant(fieldlist[0])); // set also private value } } } // Compute job associated and update the job cache if needed void bRestore::setJob() { if (JobList->currentIndex() < 1) { FileList->clearContents(); FileList->setRowCount(0); FileRevisions->clearContents(); FileRevisions->setRowCount(0); return ; } QStringList results; QVariant tmp = JobList->itemData(JobList->currentIndex(), Qt::UserRole); m_jobids = tmp.toString(); QString cmd = ".bvfs_get_jobids jobid=" + m_jobids; if (MergeChk->checkState() == Qt::Checked) { cmd.append(" all"); } m_console->dir_cmd(cmd, results); if (results.size() < 1) { FileList->clearContents(); FileList->setRowCount(0); FileRevisions->clearContents(); FileRevisions->setRowCount(0); return; } // TODO: Can take some time if the job contains many dirs m_jobids = results.at(0); cmd = ".bvfs_update jobid=" + m_jobids; m_console->dir_cmd(cmd, results); Pmsg1(0, "jobids=%s\n", m_jobids.toLocal8Bit().constData()); displayFiles(m_pathid, QString("")); Pmsg0(000, "update done\n"); } extern int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI); // refresh button with a filter or limit/offset change void bRestore::refreshView() { displayFiles(m_pathid, m_path); } void bRestore::displayFiles(int64_t pathid, QString path) { QString arg; QStringList results; QStringList fieldlist; struct stat statp; int32_t LinkFI; int nb = 0; int row = 0; Freeze frz_lst(*FileList); /* disable updating*/ Freeze frz_rev(*FileRevisions); /* disable updating*/ FileList->clearContents(); FileRevisions->clearContents(); FileRevisions->setRowCount(0); bool foundFilter = false; QString FileFilter, FileName; // Disable sorting while filling the table FileList->setSortingEnabled(false); // If we provide pathid, use it (path can be altered by encoding conversion) if (pathid > 0) { arg = " pathid=" + QString().setNum(pathid); // Choose .. update current path to parent dir if (path == "..") { if (m_path == "/") { m_path = ""; } else { m_path.remove(QRegExp("[^/]+/$")); } } else if (path == "/" && m_path == "") { m_path += path; } else if (path != "/" && path != ".") { m_path += path; } } else { m_path = path; arg = " path=\"" + m_path + "\""; } // If a filter is set, add it to the current query if (FilterEntry->text() != "") { QString tmp = FilterEntry->text(); tmp.replace("\"", "."); // basic escape of " FileFilter = tmp; foundFilter = true; arg += " pattern=\"" + tmp + "\""; FilterEntry->setText(""); // The filter is only used once } LocationEntry->setText(m_path); QString offset = QString().setNum(Offset1Spin->value()); QString limit=QString().setNum(Offset2Spin->value() - Offset1Spin->value()); QString q = ".bvfs_lsdir jobid=" + m_jobids + arg + " limit=" + limit + " offset=" + offset ; if (mainWin->m_miscDebug) qDebug() << q; int minCnt=0; if (m_console->dir_cmd(q, results)) { nb = results.size(); // Lets get the DIR filelist foreach (QString resultline, results) { // PathId, FilenameId, fileid, jobid, lstat, path fieldlist = resultline.split("\t"); FileName=fieldlist.at(5); minCnt++; if (foundFilter && minCnt > 2) { if (FileName.indexOf(FileFilter, 0, Qt::CaseInsensitive) < 0) { nb--; continue; } } } FileList->setRowCount(nb); minCnt=0; foreach (QString resultline, results) { int col=0; // PathId, FilenameId, fileid, jobid, lstat, path fieldlist = resultline.split("\t"); FileName=fieldlist.at(5); minCnt++; if (foundFilter && minCnt > 2) { if (FileName.indexOf(FileFilter, 0, Qt::CaseInsensitive) < 0) { continue; } } /* * Note, the next line zaps variable "item", probably * because the input data in fieldlist is bad. */ decode_stat(fieldlist.at(4).toLocal8Bit().data(), &statp, sizeof(statp), &LinkFI); TableItemFormatter item(*FileList, row++); item.setFileType(col++, QString("folder")); // folder or file item.setTextFld(col++, fieldlist.at(5)); // path item.setBytesFld(col++, QString().setNum(statp.st_size)); item.setDateFld(col++, statp.st_mtime); // date fieldlist.replace(3, m_jobids); // use current jobids selection // keep original info on the first cel that is never empty item.widget(1)->setData(Qt::UserRole, fieldlist.join("\t")); } } results.clear(); q = ".bvfs_lsfiles jobid=" + m_jobids + arg + " limit=" + limit + " offset=" + offset ; if (m_console->dir_cmd(q, results)) { FileList->setRowCount(results.size() + nb); foreach (QString resultline, results) { int col=1; // skip icon //PathId, FilenameId, fileid, jobid, lstat, name fieldlist = resultline.split("\t"); TableItemFormatter item(*FileList, row++); item.setTextFld(col++, fieldlist.at(5)); // name decode_stat(fieldlist.at(4).toLocal8Bit().data(), &statp, sizeof(statp), &LinkFI); item.setBytesFld(col++, QString().setNum(statp.st_size)); item.setDateFld(col++, statp.st_mtime); // keep original info on the first cel that is never empty item.widget(1)->setData(Qt::UserRole, fieldlist.join("\t")); // keep info } } // Enable sorting after filling the table FileList->setSortingEnabled(true); // Default sort by the Filename column ascending FileList->sortByColumn(1, Qt::AscendingOrder); // Resize all columns to the data in them FileList->verticalHeader()->hide(); FileList->resizeColumnsToContents(); FileList->resizeRowsToContents(); FileList->setEditTriggers(QAbstractItemView::NoEditTriggers); } void bRestore::PgSeltreeWidgetClicked() { if(!m_populated) { setupPage(); } if (!isOnceDocked()) { dockPage(); } } // Display all versions of a file for this client void bRestore::displayFileVersion(QString pathid, QString fnid, QString client, QString filename) { int row=0; struct stat statp; int32_t LinkFI; Freeze frz_rev(*FileRevisions); /* disable updating*/ FileRevisions->clearContents(); QString q = ".bvfs_versions jobid=" + m_jobids + " pathid=" + pathid + " fnid=" + fnid + " client=" + client; if (VersionsChk->checkState() == Qt::Checked) { q.append(" versions"); } QStringList results; QStringList fieldlist; QString tmp; // Disable sorting while filling the table FileRevisions->setSortingEnabled(false); if (m_console->dir_cmd(q, results)) { FileRevisions->setRowCount(results.size()); foreach (QString resultline, results) { int col=0; // 0 1 2 3 4 5 6 7 //PathId, FilenameId, fileid, jobid, lstat, Md5, VolName, Inchanger fieldlist = resultline.split("\t"); TableItemFormatter item(*FileRevisions, row++); item.setInChanger(col++, fieldlist.at(7)); // inchanger item.setTextFld(col++, fieldlist.at(6)); // Volume item.setNumericFld(col++, fieldlist.at(3)); // JobId decode_stat(fieldlist.at(4).toLocal8Bit().data(), &statp, sizeof(statp), &LinkFI); item.setBytesFld(col++, QString().setNum(statp.st_size)); // size item.setDateFld(col++, statp.st_mtime); // date item.setTextFld(col++, fieldlist.at(5)); // chksum // Adjust the fieldlist for drag&drop fieldlist.removeLast(); // inchanger fieldlist.removeLast(); // volname fieldlist.removeLast(); // md5 fieldlist << m_path + filename; // keep original info on the first cel that is never empty item.widget(1)->setData(Qt::UserRole, fieldlist.join("\t")); } } // Enable sorting after filling the table FileRevisions->setSortingEnabled(true); // Default sort by the Date column ascending FileRevisions->sortByColumn(4, Qt::DescendingOrder); // Resize all columns to the data in them FileRevisions->verticalHeader()->hide(); FileRevisions->resizeColumnsToContents(); FileRevisions->resizeRowsToContents(); FileRevisions->setEditTriggers(QAbstractItemView::NoEditTriggers); } void bRestore::showInfoForFile(QTableWidgetItem *widget) { m_current = widget; QTableWidgetItem *first = FileList->item(widget->row(), 1); QStringList lst = first->data(Qt::UserRole).toString().split("\t"); if (lst.at(1) == "0") { // no filenameid, should be a path displayFiles(lst.at(0).toLongLong(), lst.at(5)); } else { displayFileVersion(lst.at(0), lst.at(1), m_client, lst.at(5)); } } void bRestore::applyLocation() { displayFiles(0, LocationEntry->text()); } void bRestore::clearVersions(QTableWidgetItem *item) { if (item != m_current) { FileRevisions->clearContents(); FileRevisions->setRowCount(0); } m_current = item ; } void bRestore::clearRestoreList() { RestoreList->clearContents(); RestoreList->setRowCount(0); } void bRestore::runRestore() { bRunRestore *r = new bRunRestore(this); r->setVisible(true); } void bRestore::setupPage() { ClientList->addItem("Client list"); ClientList->addItems(m_console->client_list); connect(ClientList, SIGNAL(currentIndexChanged(int)), this, SLOT(setClient())); connect(JobList, SIGNAL(currentIndexChanged(int)), this, SLOT(setJob())); connect(FileList, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(clearVersions(QTableWidgetItem *))); connect(FileList, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(showInfoForFile(QTableWidgetItem *))); connect(LocationBp, SIGNAL(pressed()), this, SLOT(applyLocation())); connect(MergeChk, SIGNAL(clicked()), this, SLOT(setJob())); connect(ClearBp, SIGNAL(clicked()), this, SLOT(clearRestoreList())); connect(RestoreBp, SIGNAL(clicked()), this, SLOT(runRestore())); connect(FilterBp, SIGNAL(clicked()), this, SLOT(refreshView())); m_populated = true; } bRestore::~bRestore() { } // Drag & Drop handling, not so easy... void bRestoreTable::mousePressEvent(QMouseEvent *event) { QTableWidget::mousePressEvent(event); if (event->button() == Qt::LeftButton) { dragStartPosition = event->pos(); } } // This event permits to send set custom data on drag&drop // Don't forget to call original class if we are not interested void bRestoreTable::mouseMoveEvent(QMouseEvent *event) { int lastrow=-1; // Look just for drag&drop if (!(event->buttons() & Qt::LeftButton)) { QTableWidget::mouseMoveEvent(event); return; } if ((event->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance()) { QTableWidget::mouseMoveEvent(event); return; } QList lst = selectedItems(); if (mainWin->m_miscDebug) qDebug() << this << " selectedItems: " << lst; if (lst.isEmpty()) { return; } QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; for (int i=0; i < lst.size(); i++) { if (lastrow != lst[i]->row()) { lastrow = lst[i]->row(); QTableWidgetItem *it = item(lastrow, 1); mimeData->setText(it->data(Qt::UserRole).toString()); break; // at this time, we do it one by one } } drag->setMimeData(mimeData); drag->exec(); } // This event is called when the drag item enters in the destination area void bRestoreTable::dragEnterEvent(QDragEnterEvent *event) { if (event->source() == this) { event->ignore(); return; } if (event->mimeData()->hasText()) { event->acceptProposedAction(); } else { event->ignore(); } } // It should not be essential to redefine this event, but it // doesn't work if not defined void bRestoreTable::dragMoveEvent(QDragMoveEvent *event) { if (event->mimeData()->hasText()) { event->acceptProposedAction(); } else { event->ignore(); } } // When user releases the button void bRestoreTable::dropEvent(QDropEvent *event) { int col=1; struct stat statp; int32_t LinkFI; if (event->mimeData()->hasText()) { TableItemFormatter item(*this, rowCount()); setRowCount(rowCount() + 1); QStringList fields = event->mimeData()->text().split("\t"); if (fields.size() != 6) { event->ignore(); return; } if (fields.at(1) == "0") { item.setFileType(0, "folder"); } item.setTextFld(col++, fields.at(5)); // filename decode_stat(fields.at(4).toLocal8Bit().data(), &statp, sizeof(statp), &LinkFI); item.setBytesFld(col++, QString().setNum(statp.st_size)); // size item.setDateFld(col++, statp.st_mtime); // date item.setNumericFld(col++, fields.at(3)); // jobid item.setNumericFld(col++, fields.at(2)); // fileid // keep original info on the first cel that is never empty item.widget(1)->setData(Qt::UserRole, event->mimeData()->text()); event->acceptProposedAction(); } else { event->ignore(); } } // Use File Relocation bp void bRunRestore::UFRcb() { if (UseFileRelocationChk->checkState() == Qt::Checked) { WhereEntry->setEnabled(false); UseRegexpChk->setEnabled(true); if (UseRegexpChk->checkState() == Qt::Checked) { AddSuffixEntry->setEnabled(false); AddPrefixEntry->setEnabled(false); StripPrefixEntry->setEnabled(false); WhereRegexpEntry->setEnabled(true); } else { AddSuffixEntry->setEnabled(true); AddPrefixEntry->setEnabled(true); StripPrefixEntry->setEnabled(true); WhereRegexpEntry->setEnabled(false); } } else { WhereEntry->setEnabled(true); AddSuffixEntry->setEnabled(false); AddPrefixEntry->setEnabled(false); StripPrefixEntry->setEnabled(false); UseRegexpChk->setEnabled(false); WhereRegexpEntry->setEnabled(false); } } // Expert mode for file relocation void bRunRestore::useRegexp() { if (UseRegexpChk->checkState() == Qt::Checked) { AddSuffixEntry->setEnabled(false); AddPrefixEntry->setEnabled(false); StripPrefixEntry->setEnabled(false); WhereRegexpEntry->setEnabled(true); } else { AddSuffixEntry->setEnabled(true); AddPrefixEntry->setEnabled(true); StripPrefixEntry->setEnabled(true); WhereRegexpEntry->setEnabled(false); } } // Display Form to run the restore job bRunRestore::bRunRestore(bRestore *parent) { brestore = parent; setupUi(this); ClientCb->addItems(parent->console()->client_list); int i = ClientCb->findText(parent->m_client); if (i >= 0) { ClientCb->setCurrentIndex(i); } StorageCb->addItem(QString("")); RestoreCb->addItems(parent->console()->restore_list); WhenEditor->setDateTime(QDateTime::currentDateTime()); StorageCb->addItems(parent->console()->storage_list); connect(UseFileRelocationChk, SIGNAL(clicked()), this, SLOT(UFRcb())); connect(UseRegexpChk, SIGNAL(clicked()), this, SLOT(useRegexp())); connect(ActionBp, SIGNAL(accepted()), this, SLOT(computeRestore())); // TODO: handle multiple restore job struct job_defaults jd; if (parent->console()->restore_list.size() > 0) { jd.job_name = parent->console()->restore_list[0]; brestore->console()->get_job_defaults(jd); WhereEntry->setText(jd.where); } computeVolumeList(); } void bRestore::get_info_from_selection(QStringList &fileids, QStringList &jobids, QStringList &dirids, QStringList &findexes) { struct stat statp; int32_t LinkFI; for (int i=0; i < RestoreList->rowCount(); i++) { QTableWidgetItem *item = RestoreList->item(i, 1); QString filedata = item->data(Qt::UserRole).toString(); QStringList lst = filedata.split("\t"); if (lst.at(1) != "0") { // skip path fileids << lst.at(2); jobids << lst.at(3); decode_stat(lst.at(4).toLocal8Bit().data(), &statp, sizeof(statp), &LinkFI); if (LinkFI) { findexes << lst.at(3) + "," + QString().setNum(LinkFI); } } else { dirids << lst.at(0); jobids << lst.at(3).split(","); // Can have multiple jobids } } fileids.removeDuplicates(); jobids.removeDuplicates(); dirids.removeDuplicates(); findexes.removeDuplicates(); } // To compute volume list with directories, query is much slower void bRunRestore::computeVolumeList() { brestore->get_info_from_selection(m_fileids, m_jobids, m_dirids, m_findexes); if (m_fileids.size() == 0) { return; } Freeze frz_lst(*TableMedia); /* disable updating*/ QString q = " SELECT DISTINCT VolumeName, Enabled, InChanger " " FROM File, " " ( " // -- Get all media from this job " SELECT MIN(FirstIndex) AS FirstIndex, MAX(LastIndex) AS LastIndex, " " VolumeName, Enabled, Inchanger " " FROM JobMedia JOIN Media USING (MediaId) " " WHERE JobId IN (" + m_jobids.join(",") + ") " " GROUP BY VolumeName,Enabled,InChanger " " ) AS allmedia " " WHERE File.FileId IN (" + m_fileids.join(",") + ") " " AND File.FileIndex >= allmedia.FirstIndex " " AND File.FileIndex <= allmedia.LastIndex "; int row=0; QStringList results; if (brestore->console()->sql_cmd(q, results)) { QStringList fieldlist; TableMedia->setRowCount(results.size()); /* Iterate through the record returned from the query */ foreach (QString resultline, results) { // 0 1 2 //volname, enabled, inchanger fieldlist = resultline.split("\t"); int col=0; TableItemFormatter item(*TableMedia, row++); item.setInChanger(col++, fieldlist.at(2)); // inchanger item.setTextFld(col++, fieldlist.at(0)); // Volume } } TableMedia->verticalHeader()->hide(); TableMedia->resizeColumnsToContents(); TableMedia->resizeRowsToContents(); TableMedia->setEditTriggers(QAbstractItemView::NoEditTriggers); } int64_t bRunRestore::runRestore(QString tablename) { QString q; QString tmp; tmp = ClientCb->currentText(); if (tmp == "") { return 0; } q = "restore client=" + tmp; tmp = CommentEntry->text(); if (tmp != "") { tmp.replace("\"", " "); q += " comment=\"" + tmp + "\""; } tmp = StorageCb->currentText(); if (tmp != "") { q += " storage=" + tmp; } if (UseFileRelocationChk->checkState() == Qt::Checked) { if (UseRegexpChk->checkState() == Qt::Checked) { tmp = WhereRegexpEntry->text(); if (tmp != "") { tmp.replace("\"", ""); q += " regexwhere=\"" + tmp + "\""; } } else { QStringList lst; tmp = StripPrefixEntry->text(); if (tmp != "") { tmp.replace("\"", ""); lst.append("!" + tmp + "!!i"); } tmp = AddPrefixEntry->text(); if (tmp != "") { tmp.replace("\"", ""); lst.append("!^!" + tmp + "!"); } tmp = AddSuffixEntry->text(); if (tmp != "") { tmp.replace("\"", ""); lst.append("!([^/])$!$1" + tmp + "!"); } if (lst.size() > 0) { q += " regexwhere=\"" + lst.join(",") + "\""; } } } else { tmp = WhereEntry->text(); if (tmp != "") { tmp.replace("\"", ""); q += " where=\"" + tmp + "\""; } } // q += " priority=" + tmp.setNum(PrioritySb->value()); // q += " job=\"" + RestoreCb->currentText() + "\""; q += " file=\"?" + tablename + "\""; q += " when=\"" + WhenEditor->dateTime().toString("yyyy-MM-dd hh:mm:ss") + "\""; q += " done yes"; if (mainWin->m_miscDebug) qDebug() << q; QStringList results; if (brestore->console()->dir_cmd(q, results)) { foreach (QString resultline, results) { QStringList fieldlist = resultline.split("="); if (fieldlist.size() == 2) { return fieldlist.at(1).toLongLong(); } } } return 0; } void bRunRestore::computeRestore() { QString q = ".bvfs_restore path=b2123 jobid=" + m_jobids.join(","); if (m_fileids.size() > 0) { q += " fileid=" + m_fileids.join(","); } if (m_dirids.size() > 0) { q += " dirid=" + m_dirids.join(","); } if (m_findexes.size() > 0) { q += " hardlink=" + m_findexes.join(","); } if (mainWin->m_miscDebug) qDebug() << q; QStringList results; if (brestore->console()->dir_cmd(q, results)) { if (results.size() == 1 && results[0] == "OK") { int64_t jobid = runRestore("b2123"); if (mainWin->m_miscDebug) qDebug() << "jobid=" << jobid; q = ".bvfs_cleanup path=b2123"; brestore->console()->dir_cmd(q, results); } } } bareos-Release-14.2.6/src/qt-console/restore/brestore.ui000066400000000000000000000454301263011562700231700ustar00rootroot00000000000000 bRestoreForm 0 0 994 739 brestore 0 0 QComboBox::AdjustToContents false 0 0 QComboBox::AdjustToContents Qt::Horizontal QSizePolicy::Minimum 40 20 Merge Jobs true View all Versions Qt::Vertical Qt::Horizontal 0 0 16777215 352 File list -- drag below for restore 5 5 Double Click File Name to decend true QAbstractItemView::DragOnly true QAbstractItemView::SelectRows false true false Type File Name Double Click to decend Size Date QLayout::SetMinimumSize Selection Range 0 0 25 25 :/images/page-prev.gif:/images/page-prev.gif QAbstractSpinBox::NoButtons 9000000 500 0 0 16 16 - QAbstractSpinBox::NoButtons false 10 9999999 500 500 0 0 25 25 :/images/page-next.gif:/images/page-next.gif Qt::Horizontal 40 20 File Filter 150 0 111 23 25 25 :/images/view-refresh.png:/images/view-refresh.png 0 0 File revisions -- drag below for restore 0 0 true QAbstractItemView::DragOnly true true QAbstractItemView::SingleSelection QAbstractItemView::SelectRows false InChanger Volume JobId Size Date Chksum <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Drag and drop <span style=" font-weight:600;">File list</span> and/or <span style=" font-weight:600;">File revisions</span> items here for Restore</p></body></html> Qt::Horizontal 40 20 Clear false Estimate Restore true false QAbstractItemView::DropOnly true Qt::MoveAction QAbstractItemView::MultiSelection QAbstractItemView::SelectRows false Type FileName Size Date JobId FileIndex Nb Files 150 0 150 0 0 0 Current Directory bRestoreTable QTableWidget

restore/restore.h
OffsetNextBp clicked() Offset2Spin stepUp() 275 279 232 279 OffsetNextBp clicked() Offset1Spin stepUp() 272 281 92 279 OffsetPrevBp clicked() Offset1Spin stepDown() 44 287 123 282 OffsetPrevBp clicked() Offset2Spin stepDown() 50 284 221 282 bareos-Release-14.2.6/src/qt-console/restore/prerestore.cpp000066400000000000000000000312311263011562700236740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * preRestore -> dialog put up to determine the restore type * * Kern Sibbald, February MMVII */ #include "bat.h" #include "restore.h" /* Constructor to have job id list default in */ prerestorePage::prerestorePage(QString &data, unsigned int datatype) : Pages() { m_dataIn = data; m_dataInType = datatype; buildPage(); } /* Basic Constructor */ prerestorePage::prerestorePage() { m_dataIn = ""; m_dataInType = R_NONE; buildPage(); } /* * This is really the constructor */ void prerestorePage::buildPage() { m_name = tr("Restore"); setupUi(this); pgInitialize(); m_conn = m_console->notifyOff(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png"))); jobCombo->addItems(m_console->job_list); filesetCombo->addItems(m_console->fileset_list); clientCombo->addItems(m_console->client_list); poolCombo->addItem(tr("Any")); poolCombo->addItems(m_console->pool_list); storageCombo->addItems(m_console->storage_list); /* current or before . . Start out with current checked */ recentCheckBox->setCheckState(Qt::Checked); beforeDateTime->setDisplayFormat(mainWin->m_dtformat); beforeDateTime->setDateTime(QDateTime::currentDateTime()); beforeDateTime->setEnabled(false); selectFilesRadio->setChecked(true); if (m_dataInType == R_NONE) { selectJobRadio->setChecked(true); selectJobIdsRadio->setChecked(false); jobIdEdit->setText(tr("Comma separted list of Job Ids")); jobIdEdit->setEnabled(false); } else if (m_dataInType == R_JOBIDLIST) { selectJobIdsRadio->setChecked(true); selectJobRadio->setChecked(false); jobIdEdit->setText(m_dataIn); jobRadioClicked(false); QStringList fieldlist; if (jobdefsFromJob(fieldlist, m_dataIn) == 1) { filesetCombo->setCurrentIndex(filesetCombo->findText(fieldlist[2], Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(fieldlist[1], Qt::MatchExactly)); jobCombo->setCurrentIndex(jobCombo->findText(fieldlist[0], Qt::MatchExactly)); } } else if (m_dataInType == R_JOBDATETIME) { selectJobRadio->setChecked(true); selectJobIdsRadio->setChecked(false); jobIdEdit->setText(tr("Comma separted list of Job Ids")); jobIdEdit->setEnabled(false); recentCheckBox->setCheckState(Qt::Unchecked); jobRadioClicked(true); QStringList fieldlist; if (jobdefsFromJob(fieldlist, m_dataIn) == 1) { filesetCombo->setCurrentIndex(filesetCombo->findText(fieldlist[2], Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(fieldlist[1], Qt::MatchExactly)); jobCombo->setCurrentIndex(jobCombo->findText(fieldlist[0], Qt::MatchExactly)); beforeDateTime->setDateTime(QDateTime::fromString(fieldlist[3], mainWin->m_dtformat)); } } job_name_change(0); connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(job_name_change(int))); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); connect(recentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(recentChanged(int))); connect(selectJobRadio, SIGNAL(clicked(bool)), this, SLOT(jobRadioClicked(bool))); connect(selectJobIdsRadio, SIGNAL(clicked(bool)), this, SLOT(jobidsRadioClicked(bool))); connect(jobIdEdit, SIGNAL(editingFinished()), this, SLOT(jobIdEditFinished())); dockPage(); setCurrent(); this->show(); if (mainWin->m_miscDebug) Pmsg0(000, "Leave preRestore\n"); } /* * Check to make sure all is ok then start either the select window or the restore * run window */ void prerestorePage::okButtonPushed() { if (!selectJobRadio->isChecked()) { if (!checkJobIdList()) { return; } } QString cmd; this->hide(); cmd = QString("restore"); cmd += " fileset=\"" + filesetCombo->currentText() + "\""; cmd += " client=\"" + clientCombo->currentText() + "\""; if (selectJobRadio->isChecked()) { if (poolCombo->currentText() != tr("Any") ){ cmd += " pool=\"" + poolCombo->currentText() + "\""; } cmd += " storage=\"" + storageCombo->currentText() + "\""; if (recentCheckBox->checkState() == Qt::Checked) { cmd += " current"; } else { QDateTime stamp = beforeDateTime->dateTime(); QString before = stamp.toString(mainWin->m_dtformat); cmd += " before=\"" + before + "\""; } } else { cmd += " jobid=\"" + jobIdEdit->text() + "\""; } if (selectFilesRadio->isChecked()) { if (!selectJobIdsRadio->isChecked()) cmd += " select"; } else { cmd += " all done"; } if (mainWin->m_commandDebug) { Pmsg1(000, "preRestore command \'%s\'\n", cmd.toUtf8().data()); } /* * Send off command that looks something like: * * restore fileset="Full Set" client="timmy-fd" * storage="File" current select */ m_console->write_dir(m_conn, cmd.toUtf8().data()); /* Note, do not turn notifier back on here ... */ if (selectFilesRadio->isChecked()) { setConsoleCurrent(); closeStackPage(); /* wait will be exited in the restore page constructor */ mainWin->waitEnter(); } else { closeStackPage(); mainWin->resetFocus(); } m_console->notify(m_conn, true); if (mainWin->m_miscDebug) Pmsg0(000, "preRestore OK pressed\n"); } /* * Destroy the instace of the class */ void prerestorePage::cancelButtonPushed() { mainWin->set_status(tr("Canceled")); this->hide(); m_console->notify(m_conn, true); closeStackPage(); } /* * Handle updating the other widget with job defaults when the job combo is changed. */ void prerestorePage::job_name_change(int index) { job_defaults job_defs; (void)index; job_defs.job_name = jobCombo->currentText(); if (m_console->get_job_defaults(m_conn, job_defs)) { filesetCombo->setCurrentIndex(filesetCombo->findText(job_defs.fileset_name, Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly)); poolCombo->setCurrentIndex(poolCombo->findText(tr("Any"), Qt::MatchExactly)); storageCombo->setCurrentIndex(storageCombo->findText(job_defs.store_name, Qt::MatchExactly)); } } /* * Handle the change of enabled of input widgets when the recent checkbox state * is changed. */ void prerestorePage::recentChanged(int state) { if ((state == Qt::Unchecked) && (selectJobRadio->isChecked())) { beforeDateTime->setEnabled(true); } else { beforeDateTime->setEnabled(false); } } /* * For when jobs list is to be used, return a list which is the needed items from * the job record */ int prerestorePage::jobdefsFromJob(QStringList &fieldlist, QString &jobId) { QString job, client, fileset; QString query(""); query = "SELECT DISTINCT Job.Name AS JobName, Client.Name AS Client," " FileSet.FileSet AS FileSet, Job.EndTime AS JobEnd," " Job.Type AS JobType" " From Job, Client, FileSet" " WHERE Job.FileSetId=FileSet.FileSetId AND Job.ClientId=Client.ClientId" " AND JobId=\'" + jobId + "\'"; if (mainWin->m_sqlDebug) { Pmsg1(000, "query = %s\n", query.toUtf8().data()); } QStringList results; if (m_console->sql_cmd(m_conn, query, results)) { QString field; /* Iterate through the lines of results, there should only be one. */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); } /* foreach resultline */ } /* if results from query */ /* ***FIXME*** This should not ever be getting more than one */ return results.count() >= 1; } /* * Function to handle when the jobidlist line edit input loses focus or is entered */ void prerestorePage::jobIdEditFinished() { checkJobIdList(); } bool prerestorePage::checkJobIdList() { /* Need to check and make sure the text is a comma separated list of integers */ QString line = jobIdEdit->text(); if (line.contains(" ")) { QMessageBox::warning(this, "Bat", tr("There can be no spaces in the text for the joblist.\n" "Press OK to continue?"), QMessageBox::Ok ); return false; } QStringList joblist = line.split(",", QString::SkipEmptyParts); bool allintokay = true, alljobok = true, allisjob = true; QString jobName(""), clientName(""); foreach (QString job, joblist) { bool intok; job.toInt(&intok, 10); if (intok) { /* are the integers representing a list of jobs all with the same job * and client */ QStringList fields; if (jobdefsFromJob(fields, job) == 1) { if (jobName == "") jobName = fields[0]; else if (jobName != fields[0]) alljobok = false; if (clientName == "") clientName = fields[1]; else if (clientName != fields[1]) alljobok = false; } else { allisjob = false; } } else { allintokay = false; } } if (!allintokay){ QMessageBox::warning(this, "Bat", tr("The string is not a comma separated list of integers.\n" "Press OK to continue?"), QMessageBox::Ok ); return false; } if (!allisjob){ QMessageBox::warning(this, tr("Bat"), tr("At least one of the jobs is not a valid job of type \"Backup\".\n" "Press OK to continue?"), QMessageBox::Ok ); return false; } if (!alljobok){ QMessageBox::warning(this, "Bat", tr("All jobs in the list must be of the same jobName and same client.\n" "Press OK to continue?"), QMessageBox::Ok ); return false; } return true; } /* * Handle the change of enabled of input widgets when the job radio buttons * are changed. */ void prerestorePage::jobRadioClicked(bool checked) { if (checked) { jobCombo->setEnabled(true); filesetCombo->setEnabled(true); clientCombo->setEnabled(true); poolCombo->setEnabled(true); storageCombo->setEnabled(true); recentCheckBox->setEnabled(true); if (!recentCheckBox->isChecked()) { beforeDateTime->setEnabled(true); } jobIdEdit->setEnabled(false); selectJobRadio->setChecked(true); selectJobIdsRadio->setChecked(false); } else { jobCombo->setEnabled(false); filesetCombo->setEnabled(false); clientCombo->setEnabled(false); poolCombo->setEnabled(false); storageCombo->setEnabled(false); recentCheckBox->setEnabled(false); beforeDateTime->setEnabled(false); jobIdEdit->setEnabled(true); selectJobRadio->setChecked(false); selectJobIdsRadio->setChecked(true); } if (mainWin->m_miscDebug) { Pmsg2(000, "jobRadio=%d jobidsRadio=%d\n", selectJobRadio->isChecked(), selectJobIdsRadio->isChecked()); } } void prerestorePage::jobidsRadioClicked(bool checked) { if (checked) { jobCombo->setEnabled(false); filesetCombo->setEnabled(false); clientCombo->setEnabled(false); poolCombo->setEnabled(false); storageCombo->setEnabled(false); recentCheckBox->setEnabled(false); beforeDateTime->setEnabled(false); jobIdEdit->setEnabled(true); selectJobRadio->setChecked(false); selectJobIdsRadio->setChecked(true); } else { jobCombo->setEnabled(true); filesetCombo->setEnabled(true); clientCombo->setEnabled(true); poolCombo->setEnabled(true); storageCombo->setEnabled(true); recentCheckBox->setEnabled(true); if (!recentCheckBox->isChecked()) { beforeDateTime->setEnabled(true); } jobIdEdit->setEnabled(false); selectJobRadio->setChecked(true); selectJobIdsRadio->setChecked(false); } if (mainWin->m_miscDebug) { Pmsg2(000, "jobRadio=%d jobidsRadio=%d\n", selectJobRadio->isChecked(), selectJobIdsRadio->isChecked()); } } bareos-Release-14.2.6/src/qt-console/restore/prerestore.ui000066400000000000000000000256431263011562700235410ustar00rootroot00000000000000 prerestoreForm 0 0 589 897 Form true 9 6 0 6 QFrame::NoFrame QFrame::Plain 0 6 All Files false Select Files false Qt::Horizontal 40 20 Qt::Horizontal 40 20 0 6 7 0 0 0 600 600 Job JobIds Qt::Vertical QSizePolicy::Fixed 20 21 0 6 2000 1 1 yyyy-mm-dd h:mm:ss true Qt::LeftToRight Use Most Recent File Set: filesetCombo Client: clientCombo Storage: storageCombo Before: beforeDateTime Pool: poolCombo Qt::Horizontal 262 21 0 6 Qt::Horizontal 171 20 OK Cancel Qt::Vertical 71 41 Qt::Vertical 387 161 Qt::Horizontal 41 139 Qt::Horizontal 21 139 0 6 Qt::Horizontal 71 21 16777215 30 <h3>Select Jobs</h3> Qt::Horizontal 81 20 bareos-Release-14.2.6/src/qt-console/restore/restore.cpp000066400000000000000000000374221263011562700231750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Restore Class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "restore.h" static const int dbglvl = 100; restorePage::restorePage(int conn) : Pages() { Dmsg1(dbglvl, "Construcing restorePage Instance connection %i\n", conn); m_conn = conn; QStringList titles; setupUi(this); m_name = tr("Restore Select"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png"))); m_console->notify(m_conn, false); /* this should already be off */ connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(fileDoubleClicked(QTreeWidgetItem *, int))); connect(directoryWidget, SIGNAL( currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(directoryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); connect(upButton, SIGNAL(pressed()), this, SLOT(upButtonPushed())); connect(markButton, SIGNAL(pressed()), this, SLOT(markButtonPushed())); connect(unmarkButton, SIGNAL(pressed()), this, SLOT(unmarkButtonPushed())); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); fileWidget->setContextMenuPolicy(Qt::ActionsContextMenu); fileWidget->addAction(actionMark); fileWidget->addAction(actionUnMark); connect(actionMark, SIGNAL(triggered()), this, SLOT(markButtonPushed())); connect(actionUnMark, SIGNAL(triggered()), this, SLOT(unmarkButtonPushed())); setFont(m_console->get_font()); m_console->displayToPrompt(m_conn); titles << tr("Mark") << tr("File") << tr("Mode") << tr("User") << tr("Group") << tr("Size") << tr("Date"); fileWidget->setHeaderLabels(titles); get_cwd(); readSettings(); /* wait was entered from pre-restore * will exit, but will reenter in fillDirectory */ mainWin->waitExit(); fillDirectory(); dockPage(); setCurrent(); this->show(); if (mainWin->m_miscDebug) Pmsg0(000, "Leave restorePage\n"); } restorePage::~restorePage() { writeSettings(); } /* * Fill the fileWidget box with the contents of the current directory */ void restorePage::fillDirectory() { mainWin->waitEnter(); char modes[20], user[20], group[20], size[20], date[30]; char marked[10]; int pnl, fnl; POOLMEM *file = get_pool_memory(PM_FNAME); POOLMEM *path = get_pool_memory(PM_FNAME); fileWidget->clear(); m_console->write_dir(m_conn, "dir", false); QList treeItemList; QStringList item; m_rx.setPattern("has no children\\.$"); bool first = true; while (m_console->read(m_conn) > 0) { char *p = m_console->msg(m_conn); char *l; strip_trailing_newline(p); if (*p == '$' || !*p) { continue; } if (first) { if (m_rx.indexIn(QString(p)) != -1) { continue; } first = false; } l = p; skip_nonspaces(&p); /* permissions */ *p++ = 0; bstrncpy(modes, l, sizeof(modes)); skip_spaces(&p); skip_nonspaces(&p); /* link count */ *p++ = 0; skip_spaces(&p); l = p; skip_nonspaces(&p); /* user */ *p++ = 0; skip_spaces(&p); bstrncpy(user, l, sizeof(user)); l = p; skip_nonspaces(&p); /* group */ *p++ = 0; bstrncpy(group, l, sizeof(group)); skip_spaces(&p); l = p; skip_nonspaces(&p); /* size */ *p++ = 0; bstrncpy(size, l, sizeof(size)); skip_spaces(&p); l = p; skip_nonspaces(&p); /* date/time */ skip_spaces(&p); skip_nonspaces(&p); *p++ = 0; bstrncpy(date, l, sizeof(date)); skip_spaces(&p); if (*p == '*') { bstrncpy(marked, "*", sizeof(marked)); p++; } else { bstrncpy(marked, " ", sizeof(marked)); } split_path_and_filename(p, &path, &pnl, &file, &fnl); item.clear(); item << "" << file << modes << user << group << size << date; if (item[1].endsWith("/")) { addDirectory(item[1]); } QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item); ti->setTextAlignment(5, Qt::AlignRight); /* right align size */ if (strcmp(marked, "*") == 0) { ti->setIcon(0, QIcon(QString::fromUtf8(":images/check.png"))); ti->setData(0, Qt::UserRole, true); } else { ti->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png"))); ti->setData(0, Qt::UserRole, false); } treeItemList.append(ti); } fileWidget->clear(); fileWidget->insertTopLevelItems(0, treeItemList); for (int i=0; i<7; i++) { fileWidget->resizeColumnToContents(i); } free_pool_memory(file); free_pool_memory(path); mainWin->waitExit(); } /* * Function called from fill directory when a directory is found to see if this * directory exists in the directory pane and then add it to the directory pane */ void restorePage::addDirectory(QString &newdirr) { QString newdir = newdirr; QString fullpath = m_cwd + newdirr; bool ok = true; if (mainWin->m_miscDebug) { QString msg = QString(tr("In addDirectory cwd \"%1\" newdir \"%2\" fullpath \"%3\"\n")) .arg(m_cwd) .arg(newdir) .arg(fullpath); Pmsg1(dbglvl, "%s\n", msg.toUtf8().data()); } if (isWin32Path(fullpath)) { if (mainWin->m_miscDebug) Pmsg0(dbglvl, "Windows drive\n"); if (fullpath.left(1) == "/") { fullpath.replace(0, 1, ""); /* strip leading / */ } /* If drive and not already in add it */ if (fullpath.length() == 3 && !m_dirPaths.contains(fullpath)) { QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget); item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png"))); item->setText(0, fullpath.toUtf8().data()); if (mainWin->m_miscDebug) { Pmsg1(dbglvl, "Pre Inserting %s\n",fullpath.toUtf8().data()); } m_dirPaths.insert(fullpath, item); m_dirTreeItems.insert(item, fullpath); directoryWidget->setCurrentItem(NULL); } } else { // Unix add / first if not already there if (m_dirPaths.empty()) { QTreeWidgetItem *item = new QTreeWidgetItem(directoryWidget); item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png"))); QString text("/"); item->setText(0, text.toUtf8().data()); if (mainWin->m_miscDebug) { Pmsg1(dbglvl, "Pre Inserting %s\n",text.toUtf8().data()); } m_dirPaths.insert(text, item); m_dirTreeItems.insert(item, text); } } /* Does it already exist ?? */ if (!m_dirPaths.contains(fullpath)) { QTreeWidgetItem *item = NULL; if (isWin32Path(fullpath)) { /* this is the base widget */ item = new QTreeWidgetItem(directoryWidget); item->setText(0, fullpath.toUtf8().data()); if (mainWin->m_miscDebug) Pmsg1(dbglvl, "Windows: %s\n", fullpath.toUtf8().data()); item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png"))); } else { QTreeWidgetItem *parent = m_dirPaths.value(m_cwd); if (parent) { /* new directories to add */ item = new QTreeWidgetItem(parent); item->setText(0, newdir.toUtf8().data()); item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png"))); directoryWidget->expandItem(parent); if (mainWin->m_miscDebug) { Pmsg1(dbglvl, "%s\n", newdir.toUtf8().data()); } } else { ok = false; if (mainWin->m_miscDebug) { QString msg = QString(tr("In else of if parent cwd \"%1\" newdir \"%2\"\n")) .arg(m_cwd) .arg(newdir); Pmsg1(dbglvl, "%s\n", msg.toUtf8().data()); } } } /* insert into both forward and reverse hash */ if (ok) { if (mainWin->m_miscDebug) { Pmsg1(dbglvl, "Inserting %s\n",fullpath.toUtf8().data()); } m_dirPaths.insert(fullpath, item); m_dirTreeItems.insert(item, fullpath); } } } /* * Executed when the tree item in the directory pane is changed. This will * allow us to populate the file pane and make this the cwd. */ void restorePage::directoryItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem * /*previousitem*/) { QString fullpath = m_dirTreeItems.value(currentitem); statusLine->setText(""); if (fullpath != "") { cwd(fullpath.toUtf8().data()); fillDirectory(); } } void restorePage::okButtonPushed() { this->hide(); m_console->write(m_conn, "done"); m_console->notify(m_conn, true); setConsoleCurrent(); closeStackPage(); mainWin->resetFocus(); } void restorePage::cancelButtonPushed() { this->hide(); m_console->write(m_conn, "quit"); m_console->displayToPrompt(m_conn); mainWin->set_status(tr("Canceled")); closeStackPage(); m_console->notify(m_conn, true); mainWin->resetFocus(); } void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column) { char cmd[1000]; statusLine->setText(""); if (column == 0) { /* mark/unmark */ mainWin->waitEnter(); if (item->data(0, Qt::UserRole).toBool()) { bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data()); item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png"))); item->setData(0, Qt::UserRole, false); } else { bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data()); item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png"))); item->setData(0, Qt::UserRole, true); } m_console->write_dir(m_conn, cmd, false); if (m_console->read(m_conn) > 0) { strip_trailing_newline(m_console->msg(m_conn)); statusLine->setText(m_console->msg(m_conn)); } m_console->displayToPrompt(m_conn); mainWin->waitExit(); return; } /* * Double clicking other than column 0 means to decend into * the directory -- or nothing if it is not a directory. */ if (item->text(1).endsWith("/")) { QString fullpath = m_cwd + item->text(1); QTreeWidgetItem *item = m_dirPaths.value(fullpath); if (mainWin->m_miscDebug) { Pmsg1(dbglvl, "%s\n", fullpath.toUtf8().data()); } if (item) { directoryWidget->setCurrentItem(item); } else { QString msg = QString("DoubleClick else of item column %1 fullpath %2\n") .arg(column,10) .arg(fullpath); if (mainWin->m_miscDebug) Pmsg1(dbglvl, "%s\n", msg.toUtf8().data()); } } } /* * If up button pushed, making the parent tree widget current will call fill * directory. */ void restorePage::upButtonPushed() { cwd(".."); QTreeWidgetItem *item = m_dirPaths.value(m_cwd); if (item) { directoryWidget->setCurrentItem(item); } statusLine->setText(""); } /* * Mark selected items */ void restorePage::markButtonPushed() { mainWin->waitEnter(); QList treeItemList = fileWidget->selectedItems(); QTreeWidgetItem *item; char cmd[1000]; int count = 0; statusLine->setText(""); foreach (item, treeItemList) { count++; bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data()); item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png"))); m_console->write_dir(m_conn, cmd, false); if (m_console->read(m_conn) > 0) { strip_trailing_newline(m_console->msg(m_conn)); statusLine->setText(m_console->msg(m_conn)); } Dmsg1(dbglvl, "cmd=%s\n", cmd); m_console->discardToPrompt(m_conn); } if (count == 0) { mainWin->set_status("Nothing selected, nothing done"); statusLine->setText("Nothing selected, nothing done"); } mainWin->waitExit(); } /* * Unmark selected items */ void restorePage::unmarkButtonPushed() { mainWin->waitEnter(); QList treeItemList = fileWidget->selectedItems(); QTreeWidgetItem *item; char cmd[1000]; int count = 0; statusLine->setText(""); foreach (item, treeItemList) { count++; bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data()); item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png"))); m_console->write_dir(m_conn, cmd, false); if (m_console->read(m_conn) > 0) { strip_trailing_newline(m_console->msg(m_conn)); statusLine->setText(m_console->msg(m_conn)); } Dmsg1(dbglvl, "cmd=%s\n", cmd); m_console->discardToPrompt(m_conn); } if (count == 0) { mainWin->set_status(tr("Nothing selected, nothing done")); statusLine->setText(tr("Nothing selected, nothing done")); } mainWin->waitExit(); } /* * Change current working directory */ bool restorePage::cwd(const char *dir) { int stat; POOL_MEM cd_cmd(PM_NAME); mainWin->waitEnter(); statusLine->setText(""); Mmsg(cd_cmd, "cd \"%s\"", dir); Dmsg2(dbglvl, "dir=%s cmd=%s\n", dir, cd_cmd.c_str()); m_console->write_dir(m_conn, cd_cmd.c_str(), false); lineEdit->clear(); if ((stat = m_console->read(m_conn)) > 0) { m_cwd = m_console->msg(m_conn); lineEdit->insert(m_cwd); Dmsg2(dbglvl, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg(m_conn)); } else { Dmsg1(dbglvl, "stat=%d\n", stat); QMessageBox::critical(this, "Error", tr("cd command failed"), QMessageBox::Ok); } m_console->discardToPrompt(m_conn); mainWin->waitExit(); return true; /* ***FIXME*** return real status */ } /* * Return cwd when in tree restore mode */ char *restorePage::get_cwd() { int stat; mainWin->waitEnter(); m_console->write_dir(m_conn, ".pwd", false); Dmsg0(dbglvl, "send: .pwd\n"); if ((stat = m_console->read(m_conn)) > 0) { m_cwd = m_console->msg(m_conn); Dmsg2(dbglvl, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg(m_conn)); } else { Dmsg1(dbglvl, "Something went wrong read stat=%d\n", stat); QMessageBox::critical(this, "Error", tr(".pwd command failed"), QMessageBox::Ok); } m_console->discardToPrompt(m_conn); mainWin->waitExit(); return m_cwd.toUtf8().data(); } /* * Save user settings associated with this page */ void restorePage::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("RestorePage"); settings.setValue(m_splitText, splitter->saveState()); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void restorePage::readSettings() { m_splitText = "splitterSizes_2"; QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("RestorePage"); if (settings.contains(m_splitText)) { splitter->restoreState(settings.value(m_splitText).toByteArray()); } settings.endGroup(); } bareos-Release-14.2.6/src/qt-console/restore/restore.h000066400000000000000000000106671263011562700226440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, February 2007 */ #ifndef _RESTORE_H_ #define _RESTORE_H_ #include #include #include "pages.h" #include "ui_runrestore.h" class bRestoreTable : public QTableWidget { Q_OBJECT private: QPoint dragStartPosition; public: bRestoreTable(QWidget *parent) : QTableWidget(parent) { } void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event); }; #include "ui_brestore.h" #include "ui_restore.h" #include "ui_prerestore.h" enum { R_NONE, R_JOBIDLIST, R_JOBDATETIME }; /* * The pre-restore dialog selects the Job/Client to be restored * It really could use considerable enhancement. */ class prerestorePage : public Pages, public Ui::prerestoreForm { Q_OBJECT public: prerestorePage(); prerestorePage(QString &data, unsigned int); private slots: void okButtonPushed(); void cancelButtonPushed(); void job_name_change(int index); void recentChanged(int); void jobRadioClicked(bool); void jobidsRadioClicked(bool); void jobIdEditFinished(); private: int m_conn; int jobdefsFromJob(QStringList &, QString &); void buildPage(); bool checkJobIdList(); QString m_dataIn; unsigned int m_dataInType; }; /* * The restore dialog is brought up once we are in the Bareos * restore tree routines. It handles putting up a GUI tree * representation of the files to be restored. */ class restorePage : public Pages, public Ui::restoreForm { Q_OBJECT public: restorePage(int conn); ~restorePage(); void fillDirectory(); char *get_cwd(); bool cwd(const char *); private slots: void okButtonPushed(); void cancelButtonPushed(); void fileDoubleClicked(QTreeWidgetItem *item, int column); void directoryItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); void upButtonPushed(); void unmarkButtonPushed(); void markButtonPushed(); void addDirectory(QString &); private: int m_conn; void writeSettings(); void readSettings(); QString m_cwd; QHash m_dirPaths; QHash m_dirTreeItems; QRegExp m_rx; QString m_splitText; }; class bRestore : public Pages, public Ui::bRestoreForm { Q_OBJECT public: bRestore(); ~bRestore(); void PgSeltreeWidgetClicked(); QString m_client; QString m_jobids; void get_info_from_selection(QStringList &fileids, QStringList &jobids, QStringList &dirids, QStringList &fileindexes); public slots: void setClient(); void setJob(); void showInfoForFile(QTableWidgetItem *); void applyLocation(); void clearVersions(QTableWidgetItem *); void clearRestoreList(); void runRestore(); void refreshView(); private: QString m_path; int64_t m_pathid; QTableWidgetItem *m_current; void setupPage(); bool m_populated; void displayFiles(int64_t pathid, QString path); void displayFileVersion(QString pathid, QString fnid, QString client, QString filename); }; class bRunRestore : public QDialog, public Ui::bRunRestoreForm { Q_OBJECT private: bRestore *brestore; QStringList m_fileids, m_jobids, m_dirids, m_findexes; public: bRunRestore(bRestore *parent); ~bRunRestore() {} void computeVolumeList(); int64_t runRestore(QString tablename); public slots: void useRegexp(); void UFRcb(); void computeRestore(); }; #endif /* _RESTORE_H_ */ bareos-Release-14.2.6/src/qt-console/restore/restore.ui000066400000000000000000000242321263011562700230230ustar00rootroot00000000000000 restoreForm 0 0 796 597 Form Qt::Horizontal QSizePolicy::Expanding 81 20 16777215 41 <h3>Restore Select</h3> Qt::Horizontal QSizePolicy::Expanding 51 21 0 0 35 0 Up :/images/up.png 0 0 35 0 Mark :/images/check.png 0 0 50 0 Unmark :/images/unchecked.png Qt::Horizontal QSizePolicy::Expanding 81 21 <h2>Files</h2> Qt::Horizontal 71 21 0 0 Qt::Horizontal 1 1 200 0 16777215 16777215 1 0 50 0 Select a Directory true 1 Directories 144 1 400 0 0 0 true QAbstractItemView::ExtendedSelection QAbstractItemView::ScrollPerItem true 7 1 1 2 3 4 5 6 0 0 Current Dir: lineEdit 0 0 100 0 Qt::Horizontal QSizePolicy::Fixed 30 32 OK Cancel 0 0 Status: :/images/check.png Mark :/images/unchecked.png UnMark bareos-Release-14.2.6/src/qt-console/restore/restoretree.cpp000066400000000000000000002202531263011562700240510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Restore Class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "restoretree.h" #include "pages.h" restoreTree::restoreTree() : Pages() { setupUi(this); m_name = tr("Version Browser"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0, QIcon(QString::fromUtf8(":images/browse.png"))); m_populated = false; m_debugCnt = 0; m_debugTrap = true; QGridLayout *gridLayout = new QGridLayout(this); gridLayout->setSpacing(6); gridLayout->setMargin(9); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); m_splitter = new QSplitter(Qt::Vertical, this); QScrollArea *area = new QScrollArea(); area->setObjectName(QString::fromUtf8("area")); area->setWidget(widget); area->setWidgetResizable(true); m_splitter->addWidget(area); m_splitter->addWidget(splitter); splitter->setChildrenCollapsible(false); gridLayout->addWidget(m_splitter, 0, 0, 1, 1); /* progress widgets */ prBar1->setVisible(false); prBar2->setVisible(false); prLabel1->setVisible(false); prLabel2->setVisible(false); /* Set Defaults for check and spin for limits */ limitCheckBox->setCheckState(mainWin->m_recordLimitCheck ? Qt::Checked : Qt::Unchecked); limitSpinBox->setValue(mainWin->m_recordLimitVal); daysCheckBox->setCheckState(mainWin->m_daysLimitCheck ? Qt::Checked : Qt::Unchecked); daysSpinBox->setValue(mainWin->m_daysLimitVal); readSettings(); m_nullFileNameId = -1; dockPage(); setCurrent(); } restoreTree::~restoreTree() { writeSettings(); } /* * Called from the constructor to set up the page widgets and connections. */ void restoreTree::setupPage() { connect(refreshButton, SIGNAL(pressed()), this, SLOT(refreshButtonPushed())); connect(restoreButton, SIGNAL(pressed()), this, SLOT(restoreButtonPushed())); connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(jobComboChanged(int))); connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateRefresh())); connect(clientCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateRefresh())); connect(fileSetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateRefresh())); connect(limitCheckBox, SIGNAL(stateChanged(int)), this, SLOT(updateRefresh())); connect(daysCheckBox, SIGNAL(stateChanged(int)), this, SLOT(updateRefresh())); connect(daysSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateRefresh())); connect(limitSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateRefresh())); connect(directoryTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(directoryCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); connect(directoryTree, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(directoryItemExpanded(QTreeWidgetItem *))); connect(directoryTree, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(directoryItemChanged(QTreeWidgetItem *, int))); connect(fileTable, SIGNAL(currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)), this, SLOT(fileCurrentItemChanged(QTableWidgetItem *, QTableWidgetItem *))); connect(jobTable, SIGNAL(cellClicked(int, int)), this, SLOT(jobTableCellClicked(int, int))); QStringList titles = QStringList() << tr("Directories"); directoryTree->setHeaderLabels(titles); clientCombo->addItems(m_console->client_list); fileSetCombo->addItem(tr("Any")); fileSetCombo->addItems(m_console->fileset_list); jobCombo->addItem(tr("Any")); jobCombo->addItems(m_console->job_list); directoryTree->setContextMenuPolicy(Qt::ActionsContextMenu); } void restoreTree::updateRefresh() { if (mainWin->m_rtPopDirDebug) Pmsg2(000, "testing prev=\"%s\" current=\"%s\"\n", m_prevJobCombo.toUtf8().data(), jobCombo->currentText().toUtf8().data()); m_dropdownChanged = (m_prevJobCombo != jobCombo->currentText()) || (m_prevClientCombo != clientCombo->currentText()) || (m_prevFileSetCombo != fileSetCombo->currentText() || (m_prevLimitSpinBox != limitSpinBox->value()) || (m_prevDaysSpinBox != daysSpinBox->value()) || (m_prevLimitCheckState != limitCheckBox->checkState()) || (m_prevDaysCheckState != daysCheckBox->checkState()) ); if (m_dropdownChanged) { if (mainWin->m_rtPopDirDebug) Pmsg0(000, "In restoreTree::updateRefresh Is CHANGED\n"); refreshLabel->setText(tr("Refresh From Re-Select")); } else { if (mainWin->m_rtPopDirDebug) Pmsg0(000, "In restoreTree::updateRefresh Is not Changed\n"); refreshLabel->setText(tr("Refresh From JobChecks")); } } /* * When refresh button is pushed, perform a query getting the directories and * use parseDirectory and addDirectory to populate the directory tree with items. */ void restoreTree::populateDirectoryTree() { m_debugTrap = true; m_debugCnt = 0; m_slashTrap = false; m_dirPaths.clear(); directoryTree->clear(); fileTable->clear(); fileTable->setRowCount(0); fileTable->setColumnCount(0); versionTable->clear(); versionTable->setRowCount(0); versionTable->setColumnCount(0); m_fileExceptionHash.clear(); m_fileExceptionMulti.clear(); m_versionExceptionHash.clear(); m_directoryIconStateHash.clear(); updateRefresh(); int taskcount = 3, ontask = 1; if (m_dropdownChanged) taskcount += 1; /* Set progress bars and repaint */ prBar1->setVisible(true); prBar1->setRange(0,taskcount); prBar1->setValue(0); prLabel1->setText(tr("Task %1 of %2").arg(ontask).arg(taskcount)); prLabel1->setVisible(true); prBar2->setVisible(true); prBar2->setRange(0,0); prLabel2->setText(tr("Querying Database")); prLabel2->setVisible(true); repaint(); if (m_dropdownChanged) { m_prevJobCombo = jobCombo->currentText(); m_prevClientCombo = clientCombo->currentText(); m_prevFileSetCombo = fileSetCombo->currentText(); m_prevLimitSpinBox = limitSpinBox->value(); m_prevDaysSpinBox = daysSpinBox->value(); m_prevLimitCheckState = limitCheckBox->checkState(); m_prevDaysCheckState = daysCheckBox->checkState(); updateRefresh(); prBar1->setValue(ontask++); prLabel1->setText(tr("Task %1 of %2").arg(ontask).arg(taskcount)); prBar2->setValue(0); prBar2->setRange(0,0); prLabel2->setText(tr("Querying Jobs")); repaint(); populateJobTable(); } setJobsCheckedList(); if (mainWin->m_rtPopDirDebug) Pmsg0(000, "Repopulating from checks in Job Table\n"); if (m_checkedJobs != "") { /* First get the filenameid of where the nae is null. These will be the directories * This could be done in a subquery but postgres's query analyzer won't do the right * thing like I want */ if (m_nullFileNameId == -1) { QString cmd = "SELECT FilenameId FROM Filename WHERE name=''"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); QStringList qres; if (m_console->sql_cmd(cmd, qres)) { if (qres.count()) { QStringList fieldlist = qres[0].split("\t"); QString field = fieldlist[0]; bool ok; int val = field.toInt(&ok, 10); if (ok) m_nullFileNameId = val; } } } /* now create the query to get the list of paths */ QString cmd = "SELECT DISTINCT Path.Path AS Path, File.PathId AS PathId" " FROM File" " INNER JOIN Path ON (File.PathId=Path.PathId)"; if (m_nullFileNameId != -1) cmd += " WHERE File.FilenameId=" + QString("%1").arg(m_nullFileNameId); else cmd += " WHERE File.FilenameId IN (SELECT FilenameId FROM Filename WHERE Name='')"; cmd += " AND File.Jobid IN (" + m_checkedJobs + ")"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); prBar1->setValue(ontask++); prLabel1->setText(tr("Task %1 of %2").arg(ontask).arg(taskcount)); prBar2->setValue(0); prBar2->setRange(0,0); prLabel2->setText(tr("Querying for Directories")); repaint(); QStringList results; m_directoryPathIdHash.clear(); bool querydone = false; if (m_console->sql_cmd(cmd, results)) { if (!querydone) { querydone = true; prLabel2->setText(tr("Processing Directories")); prBar2->setRange(0,results.count()); repaint(); } if (mainWin->m_miscDebug) Pmsg1(000, "Done with query %i results\n", results.count()); QStringList fieldlist; foreach(const QString &resultline, results) { /* Update progress bar periodically */ if ((++m_debugCnt && 0x3FF) == 0) { prBar2->setValue(m_debugCnt); } fieldlist = resultline.split("\t"); int fieldcnt = 0; /* Iterate through fields in the record */ foreach (const QString &field, fieldlist) { if (fieldcnt == 0 ) { parseDirectory(field); } else if (fieldcnt == 1) { bool ok; int pathid = field.toInt(&ok, 10); if (ok) m_directoryPathIdHash.insert(fieldlist[0], pathid); } fieldcnt += 1; } } } else { return; } } else { QMessageBox::warning(this, "Bat", tr("No jobs were selected in the job query !!!.\n" "Press OK to continue"), QMessageBox::Ok ); } prBar1->setVisible(false); prBar2->setVisible(false); prLabel1->setVisible(false); prLabel2->setVisible(false); } /* * Function to set m_checkedJobs from the jobs that are checked in the table * of jobs */ void restoreTree::setJobsCheckedList() { m_JobsCheckedList = ""; bool first = true; /* Update the items in the version table */ int cnt = jobTable->rowCount(); for (int row=0; rowitem(row, 0); if (jobItem->checkState() == Qt::Checked) { if (!first) m_JobsCheckedList += ","; m_JobsCheckedList += jobItem->text(); first = false; jobItem->setBackground(Qt::green); } else { if (jobItem->flags()) jobItem->setBackground(Qt::gray); else jobItem->setBackground(Qt::darkYellow); } } m_checkedJobs = m_JobsCheckedList; } /* * Function to parse a directory into all possible subdirectories, then add to * The tree. */ void restoreTree::parseDirectory(const QString &dir_in) { // bail out if already processed if (m_dirPaths.contains(dir_in)) return; // search for parent... int pos=dir_in.lastIndexOf("/",-2); if (pos != -1) { QString parent=dir_in.left(pos+1); QString subdir=dir_in.mid(pos+1); QTreeWidgetItem *item = NULL; QTreeWidgetItem *parentItem = m_dirPaths.value(parent); if (parentItem==0) { // recurse to build parent... parseDirectory(parent); parentItem = m_dirPaths.value(parent); } /* new directories to add */ item = new QTreeWidgetItem(parentItem); item->setText(0, subdir); item->setData(0, Qt::UserRole, QVariant(dir_in)); item->setCheckState(0, Qt::Unchecked); /* Store the current state of the check status in column 1, which at * this point has no text*/ item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked)); m_dirPaths.insert(dir_in,item); } else { QTreeWidgetItem *item = new QTreeWidgetItem(directoryTree); item->setText(0, dir_in); item->setData(0, Qt::UserRole, QVariant(dir_in)); item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked)); item->setIcon(0, QIcon(QString::fromUtf8(":images/folder.png"))); m_dirPaths.insert(dir_in,item); } } /* * Virtual function which is called when this page is visible on the stack */ void restoreTree::currentStackItem() { if(!m_populated) { setupPage(); m_populated = true; } } /* * Populate the tree when refresh button pushed. */ void restoreTree::refreshButtonPushed() { populateDirectoryTree(); } /* * Set the values of non-job combo boxes to the job defaults */ void restoreTree::jobComboChanged(int) { if (jobCombo->currentText() == tr("Any")) { fileSetCombo->setCurrentIndex(fileSetCombo->findText(tr("Any"), Qt::MatchExactly)); return; } job_defaults job_defs; //(void)index; job_defs.job_name = jobCombo->currentText(); if (m_console->get_job_defaults(job_defs)) { fileSetCombo->setCurrentIndex(fileSetCombo->findText(job_defs.fileset_name, Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly)); } } /* * Function to populate the file list table */ void restoreTree::directoryCurrentItemChanged(QTreeWidgetItem *item, QTreeWidgetItem *) { if (item == NULL) return; fileTable->clear(); /* Also clear the version table here */ versionTable->clear(); versionFileLabel->setText(""); versionTable->setRowCount(0); versionTable->setColumnCount(0); QStringList headerlist = (QStringList() << tr("File Name") << tr("Filename Id")); fileTable->setColumnCount(headerlist.size()); fileTable->setHorizontalHeaderLabels(headerlist); fileTable->setRowCount(0); m_fileCheckStateList.clear(); disconnect(fileTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(fileTableItemChanged(QTableWidgetItem *))); QBrush blackBrush(Qt::black); QString directory = item->data(0, Qt::UserRole).toString(); directoryLabel->setText(tr("Present Working Directory: %1").arg(directory)); int pathid = m_directoryPathIdHash.value(directory, -1); if (pathid != -1) { QString cmd = "SELECT DISTINCT Filename.Name AS FileName, Filename.FilenameId AS FilenameId" " FROM File " " INNER JOIN Filename on (Filename.FilenameId=File.FilenameId)" " WHERE File.PathId=" + QString("%1").arg(pathid) + " AND File.Jobid IN (" + m_checkedJobs + ")" " AND Filename.Name!=''" " ORDER BY FileName"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); QStringList results; if (m_console->sql_cmd(cmd, results)) { QTableWidgetItem* tableItem; QString field; QStringList fieldlist; fileTable->setRowCount(results.size()); int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { /* Iterate through fields in the record */ int column = 0; fieldlist = resultline.split("\t"); foreach (field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ tableItem = new QTableWidgetItem(field, 1); /* Possible flags are Qt::ItemFlags flag = Qt::ItemIsSelectable | Qt::ItemIsEditablex * | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable * | Qt::ItemIsEnabled | Qt::ItemIsTristate; */ tableItem->setForeground(blackBrush); /* Just in case a column ever gets added */ if (mainWin->m_sqlDebug) Pmsg1(000, "Column=%d\n", column); if (column == 0) { Qt::ItemFlags flag = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate; tableItem->setFlags(flag); tableItem->setData(Qt::UserRole, QVariant(directory)); fileTable->setItem(row, column, tableItem); m_fileCheckStateList.append(Qt::Unchecked); tableItem->setCheckState(Qt::Unchecked); } else if (column == 1) { Qt::ItemFlags flag = Qt::ItemIsEnabled; tableItem->setFlags(flag); bool ok; int filenameid = field.toInt(&ok, 10); if (!ok) filenameid = -1; tableItem->setData(Qt::UserRole, QVariant(filenameid)); fileTable->setItem(row, column, tableItem); } column++; } row++; } fileTable->setRowCount(row); } fileTable->resizeColumnsToContents(); fileTable->resizeRowsToContents(); fileTable->verticalHeader()->hide(); fileTable->hideColumn(1); if (mainWin->m_rtDirCurICDebug) Pmsg0(000, "will update file table checks\n"); updateFileTableChecks(); } else if (mainWin->m_sqlDebug) Pmsg1(000, "did not perform query, pathid=%i not found\n", pathid); connect(fileTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(fileTableItemChanged(QTableWidgetItem *))); } /* * Function to populate the version table */ void restoreTree::fileCurrentItemChanged(QTableWidgetItem *currentFileTableItem, QTableWidgetItem *) { if (currentFileTableItem == NULL) return; int currentRow = fileTable->row(currentFileTableItem); QTableWidgetItem *fileTableItem = fileTable->item(currentRow, 0); QTableWidgetItem *fileNameIdTableItem = fileTable->item(currentRow, 1); int fileNameId = fileNameIdTableItem->data(Qt::UserRole).toInt(); m_versionCheckStateList.clear(); disconnect(versionTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(versionTableItemChanged(QTableWidgetItem *))); QString file = fileTableItem->text(); versionFileLabel->setText(file); QString directory = fileTableItem->data(Qt::UserRole).toString(); QBrush blackBrush(Qt::black); QStringList headerlist = (QStringList() << tr("Job Id") << tr("Type") << tr("End Time") << tr("Hash") << tr("FileId") << tr("Job Type") << tr("First Volume")); versionTable->clear(); versionTable->setColumnCount(headerlist.size()); versionTable->setHorizontalHeaderLabels(headerlist); versionTable->setRowCount(0); int pathid = m_directoryPathIdHash.value(directory, -1); if ((pathid != -1) && (fileNameId != -1)) { QString cmd = "SELECT Job.JobId AS JobId, Job.Level AS Type," " Job.EndTime AS EndTime, File.MD5 AS MD5," " File.FileId AS FileId, Job.Type AS JobType," " (SELECT Media.VolumeName FROM JobMedia JOIN Media ON JobMedia.MediaId=Media.MediaId WHERE JobMedia.JobId=Job.JobId ORDER BY JobMediaId LIMIT 1) AS FirstVolume" " FROM File" " INNER JOIN Filename on (Filename.FilenameId=File.FilenameId)" " INNER JOIN Path ON (Path.PathId=File.PathId)" " INNER JOIN Job ON (File.JobId=Job.JobId)" " WHERE Path.PathId=" + QString("%1").arg(pathid) + //" AND Filename.Name='" + file + "'" " AND Filename.FilenameId=" + QString("%1").arg(fileNameId) + " AND Job.Jobid IN (" + m_checkedJobs + ")" " ORDER BY Job.EndTime DESC"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); QStringList results; if (m_console->sql_cmd(cmd, results)) { QTableWidgetItem* tableItem; QString field; QStringList fieldlist; versionTable->setRowCount(results.size()); int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); int column = 0; /* remove directory */ if (fieldlist[0].trimmed() != "") { /* Iterate through fields in the record */ foreach (field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ if (column == 5 ) { QByteArray jtype(field.trimmed().toAscii()); if (jtype.size()) { field = job_type_to_str(jtype[0]); } } tableItem = new QTableWidgetItem(field, 1); tableItem->setFlags(0); tableItem->setForeground(blackBrush); tableItem->setData(Qt::UserRole, QVariant(directory)); versionTable->setItem(row, column, tableItem); if (mainWin->m_sqlDebug) Pmsg1(000, "Column=%d\n", column); if (column == 0) { Qt::ItemFlags flag = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate; tableItem->setFlags(flag); m_versionCheckStateList.append(Qt::Unchecked); tableItem->setCheckState(Qt::Unchecked); } column++; } row++; } } } versionTable->resizeColumnsToContents(); versionTable->resizeRowsToContents(); versionTable->verticalHeader()->hide(); updateVersionTableChecks(); } else { if (mainWin->m_sqlDebug) Pmsg2(000, "not querying : pathid=%i fileNameId=%i\n", pathid, fileNameId); } connect(versionTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(versionTableItemChanged(QTableWidgetItem *))); } /* * Save user settings associated with this page */ void restoreTree::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); settings.setValue(m_splitText1, m_splitter->saveState()); settings.setValue(m_splitText2, splitter->saveState()); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void restoreTree::readSettings() { m_groupText = tr("RestoreTreePage"); m_splitText1 = "splitterSizes1_3"; m_splitText2 = "splitterSizes2_3"; QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); if (settings.contains(m_splitText1)) { m_splitter->restoreState(settings.value(m_splitText1).toByteArray()); } if (settings.contains(m_splitText2)) { splitter->restoreState(settings.value(m_splitText2).toByteArray()); } settings.endGroup(); } /* * This is a funcion to accomplish the one thing I struggled to figure out what * was taking so long. It add the icons, but after the tree is made. Seemed to * work fast after changing from png to png file for graphic. */ void restoreTree::directoryItemExpanded(QTreeWidgetItem *item) { int childCount = item->childCount(); for (int i=0; ichild(i); if (child->icon(0).isNull()) child->setIcon(0, QIcon(QString::fromUtf8(":images/folder.png"))); } } /* * Show what jobs meet the criteria and are being used to * populate the directory tree and file and version tables. */ void restoreTree::populateJobTable() { QBrush blackBrush(Qt::black); if (mainWin->m_rtPopDirDebug) Pmsg0(000, "Repopulating the Job Table\n"); QStringList headerlist = (QStringList() << tr("Job Id") << tr("End Time") << tr("Level") << tr("Type") << tr("Name") << tr("Purged") << tr("TU") << tr("TD")); m_toggleUpIndex = headerlist.indexOf(tr("TU")); m_toggleDownIndex = headerlist.indexOf(tr("TD")); int purgedIndex = headerlist.indexOf(tr("Purged")); int typeIndex = headerlist.indexOf(tr("Type")); jobTable->clear(); jobTable->setColumnCount(headerlist.size()); jobTable->setHorizontalHeaderLabels(headerlist); QString jobQuery = "SELECT Job.Jobid AS Id, Job.EndTime AS EndTime," " Job.Level AS Level, Job.Type AS Type," " Job.Name AS JobName, Job.purgedfiles AS Purged" " FROM Job" /* INNER JOIN FileSet eliminates all restore jobs */ " INNER JOIN Client ON (Job.ClientId=Client.ClientId)" " INNER JOIN FileSet ON (Job.FileSetId=FileSet.FileSetId)" " WHERE" " Job.JobStatus IN ('T','W') AND Job.Type='B' AND" " Client.Name='" + clientCombo->currentText() + "'"; if ((jobCombo->currentIndex() >= 0) && (jobCombo->currentText() != tr("Any"))) { jobQuery += " AND Job.name = '" + jobCombo->currentText() + "'"; } if ((fileSetCombo->currentIndex() >= 0) && (fileSetCombo->currentText() != tr("Any"))) { jobQuery += " AND FileSet.FileSet='" + fileSetCombo->currentText() + "'"; } /* If Limit check box For limit by days is checked */ if (daysCheckBox->checkState() == Qt::Checked) { QDateTime stamp = QDateTime::currentDateTime().addDays(-daysSpinBox->value()); QString since = stamp.toString(Qt::ISODate); jobQuery += " AND Job.Starttime>'" + since + "'"; } //jobQuery += " AND Job.purgedfiles=0"; jobQuery += " ORDER BY Job.EndTime DESC"; /* If Limit check box for limit records returned is checked */ if (limitCheckBox->checkState() == Qt::Checked) { QString limit; limit.setNum(limitSpinBox->value()); jobQuery += " LIMIT " + limit; } if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", jobQuery.toUtf8().data()); QStringList results; if (m_console->sql_cmd(jobQuery, results)) { QTableWidgetItem* tableItem; QString field; QStringList fieldlist; jobTable->setRowCount(results.size()); int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); int column = 0; /* remove directory */ if (fieldlist[0].trimmed() != "") { /* Iterate through fields in the record */ foreach (field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ if (field != "") { if (column == typeIndex) { QByteArray jtype(field.trimmed().toAscii()); if (jtype.size()) { field = job_type_to_str(jtype[0]); } } tableItem = new QTableWidgetItem(field, 1); tableItem->setFlags(0); tableItem->setForeground(blackBrush); jobTable->setItem(row, column, tableItem); if (mainWin->m_sqlDebug) Pmsg1(000, "Column=%d\n", column); if (column == 0) { bool ok; int purged = fieldlist[purgedIndex].toInt(&ok, 10); if (!((ok) && (purged == 1))) { Qt::ItemFlags flag = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate; tableItem->setFlags(flag); tableItem->setCheckState(Qt::Checked); tableItem->setBackground(Qt::green); } else { tableItem->setFlags(0); tableItem->setCheckState(Qt::Unchecked); } } column++; } } tableItem = new QTableWidgetItem(QIcon(QString::fromUtf8(":images/go-up.png")), "", 1); tableItem->setFlags(0); tableItem->setForeground(blackBrush); jobTable->setItem(row, column, tableItem); column++; tableItem = new QTableWidgetItem(QIcon(QString::fromUtf8(":images/go-down.png")), "", 1); tableItem->setFlags(0); tableItem->setForeground(blackBrush); jobTable->setItem(row, column, tableItem); row++; } } } jobTable->resizeColumnsToContents(); jobTable->resizeRowsToContents(); jobTable->verticalHeader()->hide(); jobTable->hideColumn(purgedIndex); } void restoreTree::jobTableCellClicked(int row, int column) { if (column == m_toggleUpIndex){ int cnt; for (cnt=0; cntitem(cnt, 0); if (item->flags()) { Qt::CheckState state = item->checkState(); if (state == Qt::Checked) item->setCheckState(Qt::Unchecked); else if (state == Qt::Unchecked) item->setCheckState(Qt::Checked); } } } if (column == m_toggleDownIndex){ int cnt, max = jobTable->rowCount(); for (cnt=row; cntitem(cnt, 0); if (item->flags()) { Qt::CheckState state = item->checkState(); if (state == Qt::Checked) item->setCheckState(Qt::Unchecked); else if (state == Qt::Unchecked) item->setCheckState(Qt::Checked); } } } } /* * When a directory item is "changed" check the state of the checkable item * to see if it is different than what it was which is stored in Qt::UserRole * of the 2nd column, column 1, of the tree widget. */ void restoreTree::directoryItemChanged(QTreeWidgetItem *item, int /*column*/) { Qt::CheckState prevState = (Qt::CheckState)item->data(1, Qt::UserRole).toInt(); Qt::CheckState curState = item->checkState(0); QTreeWidgetItem* parent = item->parent(); Qt::CheckState parState; if (parent) parState = parent->checkState(0); else parState = (Qt::CheckState)3; if (mainWin->m_rtDirICDebug) { QString msg = QString("directory item OBJECT has changed prev=%1 cur=%2 par=%3 dir=%4\n") .arg(prevState).arg(curState).arg(parState).arg(item->text(0)); Pmsg1(000, "%s", msg.toUtf8().data()); } /* I only care when the check state changes */ if (prevState == curState) { if (mainWin->m_rtDirICDebug) Pmsg0(000, "Returning Early\n"); return; } if ((prevState == Qt::Unchecked) && (curState == Qt::Checked) && (parState != Qt::Unchecked)) { if (mainWin->m_rtDirICDebug) Pmsg0(000, "Disconnected Setting to Qt::PartiallyChecked\n"); directoryTreeDisconnectedSet(item, Qt::PartiallyChecked); curState = Qt::PartiallyChecked; } if ((prevState == Qt::PartiallyChecked) && (curState == Qt::Checked)) { if (mainWin->m_rtDirICDebug) Pmsg0(000, "Disconnected Setting to Qt::Unchecked\n"); directoryTreeDisconnectedSet(item, Qt::Unchecked); curState = Qt::Unchecked; } if (mainWin->m_rtDirICDebug) { QString msg = QString("directory item CHECKSTATE has changed prev=%1 cur=%2 par=%3 dir=%4\n") .arg(prevState).arg(curState).arg(parState).arg(item->text(0)); Pmsg1(000, "%s", msg.toUtf8().data()); } item->setData(1, Qt::UserRole, QVariant(curState)); Qt::CheckState childState = curState; if (childState == Qt::Checked) childState = Qt::PartiallyChecked; setCheckofChildren(item, childState); /* Remove items from the exception lists. The multi exception list is my index * of what exceptions can be removed when the directory is known*/ QString directory = item->data(0, Qt::UserRole).toString(); QStringList fullPathList = m_fileExceptionMulti.values(directory); int fullPathListCount = fullPathList.count(); if ((mainWin->m_rtDirICDebug) && fullPathListCount) Pmsg2(000, "Will attempt to remove file exceptions for %s count %i\n", directory.toUtf8().data(), fullPathListCount); foreach (QString fullPath, fullPathList) { /* If there is no value in the hash for the key fullPath a value of 3 will be returned * which will match no Qt::xxx values */ Qt::CheckState hashState = m_fileExceptionHash.value(fullPath, (Qt::CheckState)3); if (mainWin->m_rtDirICDebug) Pmsg2(000, "hashState=%i childState=%i\n", hashState, childState); if (hashState == Qt::Unchecked) { fileExceptionRemove(fullPath, directory); m_versionExceptionHash.remove(fullPath); if (mainWin->m_rtDirICDebug) Pmsg0(000, "Attempted Removal A\n"); } if (hashState == Qt::Checked) { fileExceptionRemove(fullPath, directory); m_versionExceptionHash.remove(fullPath); if (mainWin->m_rtDirICDebug) Pmsg0(000, "Attempted Removal B\n"); } } if (item == directoryTree->currentItem()) { if (mainWin->m_rtDirICDebug) Pmsg0(000, "Will attempt to update File Table Checks\n"); updateFileTableChecks(); versionTable->clear(); versionTable->setRowCount(0); versionTable->setColumnCount(0); } if (mainWin->m_rtDirICDebug) Pmsg0(000, "Returning At End\n"); } /* * When a directory item check state is changed, this function iterates through * all subdirectories and sets all to the passed state, which is either partially * checked or unchecked. */ void restoreTree::setCheckofChildren(QTreeWidgetItem *item, Qt::CheckState state) { int childCount; childCount = item->childCount(); for (int i=0; ichild(i); child->setData(1, Qt::UserRole, QVariant(state)); child->setCheckState(0, state); setCheckofChildren(child, state); } } /* * When a File Table Item is "changed" check to see if the state of the checkable * item has changed which is stored in m_fileCheckStateList * If changed store in a hash m_fileExceptionHash that whether this file should be * restored or not. * Called as a slot, connected after populated (after directory current changed called) */ void restoreTree::fileTableItemChanged(QTableWidgetItem *item) { /* get the previous and current check states */ int row = fileTable->row(item); Qt::CheckState prevState; /* prevent a segfault */ prevState = m_fileCheckStateList[row]; Qt::CheckState curState = item->checkState(); /* deterimine the default state from the state of the directory */ QTreeWidgetItem *dirTreeItem = directoryTree->currentItem(); Qt::CheckState dirState = (Qt::CheckState)dirTreeItem->data(1, Qt::UserRole).toInt(); Qt::CheckState defState = Qt::PartiallyChecked; if (dirState == Qt::Unchecked) defState = Qt::Unchecked; /* determine if it is already in the m_fileExceptionHash */ QString directory = directoryTree->currentItem()->data(0, Qt::UserRole).toString(); QString file = item->text(); QString fullPath = directory + file; Qt::CheckState hashState = m_fileExceptionHash.value(fullPath, (Qt::CheckState)3); int verJobNum = m_versionExceptionHash.value(fullPath, 0); if (mainWin->m_rtFileTabICDebug) { QString msg = QString("filerow=%1 prev=%2 cur=%3 def=%4 hash=%5 dir=%6 verJobNum=%7\n") .arg(row).arg(prevState).arg(curState).arg(defState).arg(hashState).arg(dirState).arg(verJobNum); Pmsg1(000, "%s", msg.toUtf8().data()); } /* Remove the hash if currently checked previously unchecked and directory is checked or partial */ if ((prevState == Qt::Checked) && (curState == Qt::Unchecked) && (dirState == Qt::Unchecked)) { /* it can behave as defaulted so current of unchecked is fine */ if (mainWin->m_rtFileTabICDebug) Pmsg0(000, "Will fileExceptionRemove and m_versionExceptionHash.remove here\n"); fileExceptionRemove(fullPath, directory); m_versionExceptionHash.remove(fullPath); } else if ((prevState == Qt::PartiallyChecked) && (curState == Qt::Checked) && (dirState != Qt::Unchecked) && (verJobNum == 0)) { if (mainWin->m_rtFileTabICDebug) Pmsg0(000, "Will fileExceptionInsert here\n"); fileExceptionInsert(fullPath, directory, Qt::Unchecked); } else if ((prevState == Qt::Unchecked) && (curState == Qt::Checked) && (dirState != Qt::Unchecked) && (verJobNum == 0) && (defState == Qt::PartiallyChecked)) { /* filerow=2 prev=0 cur=2 def=1 hash=0 dir=2 verJobNum=0 */ if (mainWin->m_rtFileTabICDebug) Pmsg0(000, "Will fileExceptionRemove here\n"); fileExceptionRemove(fullPath, directory); } else if ((prevState == Qt::Checked) && (curState == Qt::Unchecked) && (defState == Qt::PartiallyChecked) && (verJobNum != 0) && (hashState == Qt::Checked)) { /* Check dir, check version, attempt uncheck in file * filerow=4 prev=2 cur=0 def=1 hash=2 dir=2 verJobNum=53 */ if (mainWin->m_rtFileTabICDebug) Pmsg0(000, "Will fileExceptionRemove and m_versionExceptionHash.remove here\n"); fileExceptionRemove(fullPath, directory); m_versionExceptionHash.remove(fullPath); } else if ((prevState == Qt::Unchecked) && (curState == Qt::Checked) && (dirState != Qt::Unchecked) && (verJobNum == 0)) { /* filerow=0 prev=0 cur=2 def=1 hash=0 dirState=2 verJobNum */ if (mainWin->m_rtFileTabICDebug) Pmsg0(000, "Will Not remove here\n"); } else if (prevState != curState) { if (mainWin->m_rtFileTabICDebug) Pmsg2(000, " THE STATE OF THE Check has changed, Setting StateList[%i] to %i\n", row, curState); /* A user did not set the check state to Partially checked, ignore if so */ if (curState != Qt::PartiallyChecked) { if ((defState == Qt::Unchecked) && (prevState == Qt::PartiallyChecked) && (curState == Qt::Unchecked)) { if (mainWin->m_rtFileTabICDebug) Pmsg0(000, " got here\n"); } else { if (mainWin->m_rtFileTabICDebug) Pmsg2(000, " Inserting into m_fileExceptionHash %s, %i\n", fullPath.toUtf8().data(), curState); fileExceptionInsert(fullPath, directory, curState); } } else { if (mainWin->m_rtFileTabICDebug) Pmsg1(000, "Removing version hash for %s\n", fullPath.toUtf8().data()); /* programattically been changed back to a default state of Qt::PartiallyChecked remove the version hash here */ m_versionExceptionHash.remove(fullPath); } } updateFileTableChecks(); updateVersionTableChecks(); } /* * function to insert keys and values to both m_fileExceptionHash and m_fileExceptionMulti */ void restoreTree::fileExceptionInsert(QString &fullPath, QString &direcotry, Qt::CheckState state) { m_fileExceptionHash.insert(fullPath, state); m_fileExceptionMulti.insert(direcotry, fullPath); directoryIconStateInsert(fullPath, state); } /* * function to remove keys from both m_fileExceptionHash and m_fileExceptionMulti */ void restoreTree::fileExceptionRemove(QString &fullPath, QString &directory) { m_fileExceptionHash.remove(fullPath); /* pull the list of values in the multi */ QStringList fullPathList = m_fileExceptionMulti.values(directory); /* get the index of the fullpath to remove */ int index = fullPathList.indexOf(fullPath); if (index != -1) { /* remove the desired item in the list */ fullPathList.removeAt(index); /* remove the entire list from the multi */ m_fileExceptionMulti.remove(directory); /* readd the remaining */ foreach (QString fp, fullPathList) { m_fileExceptionMulti.insert(directory, fp); } } directoryIconStateRemove(); } /* * Overloaded function to be called from the slot and from other places to set the state * of the check marks in the version table */ void restoreTree::versionTableItemChanged(QTableWidgetItem *item) { /* get the previous and current check states */ int row = versionTable->row(item); QTableWidgetItem *colZeroItem = versionTable->item(row, 0); Qt::CheckState prevState = m_versionCheckStateList[row]; Qt::CheckState curState = (Qt::CheckState)colZeroItem->checkState(); m_versionCheckStateList[row] = curState; /* deterimine the default state from the state of the file */ QTableWidgetItem *fileTableItem = fileTable->currentItem(); Qt::CheckState fileState = (Qt::CheckState)fileTableItem->checkState(); /* determine the default state */ Qt::CheckState defState; if (mainWin->m_sqlDebug) Pmsg1(000, "row=%d\n", row); if (row == 0) { defState = Qt::PartiallyChecked; if (fileState == Qt::Unchecked) defState = Qt::Unchecked; } else { defState = Qt::Unchecked; } /* determine if it is already in the versionExceptionHash */ QString directory = directoryTree->currentItem()->data(0, Qt::UserRole).toString(); Qt::CheckState dirState = directoryTree->currentItem()->checkState(0); QString file = fileTableItem->text(); QString fullPath = directory + file; int thisJobNum = colZeroItem->text().toInt(); int hashJobNum = m_versionExceptionHash.value(fullPath, 0); if (mainWin->m_rtVerTabICDebug) { QString msg = QString("versrow=%1 prev=%2 cur=%3 def=%4 dir=%5 hashJobNum=%6 thisJobNum=%7 filestate=%8 fec=%9 vec=%10\n") .arg(row).arg(prevState).arg(curState).arg(defState).arg(dirState).arg(hashJobNum).arg(thisJobNum).arg(fileState) .arg(m_fileExceptionHash.count()).arg(m_versionExceptionHash.count()); Pmsg1(000, "%s", msg.toUtf8().data()); } /* if changed from partially checked to checked, make it unchecked */ if ((curState == Qt::Checked) && (row == 0) && (fileState == Qt::Unchecked)) { if (mainWin->m_rtVerTabICDebug) Pmsg0(000, "Setting to Qt::Checked\n"); fileTableItem->setCheckState(Qt::Checked); } else if ((prevState == Qt::PartiallyChecked) && (curState == Qt::Checked) && (row == 0) && (fileState == Qt::Checked) && (dirState == Qt::Unchecked)) { //versrow=0 prev=1 cur=2 def=1 dir=0 hashJobNum=0 thisJobNum=64 filestate=2 fec=1 vec=0 if (mainWin->m_rtVerTabICDebug) Pmsg1(000, "fileExceptionRemove %s, %i\n", fullPath.toUtf8().data()); fileExceptionRemove(fullPath, directory); } else if ((curState == Qt::Checked) && (row == 0) && (hashJobNum != 0) && (dirState != Qt::Unchecked)) { //versrow=0 prev=0 cur=2 def=1 dir=2 hashJobNum=53 thisJobNum=64 filestate=2 fec=1 vec=1 if (mainWin->m_rtVerTabICDebug) Pmsg1(000, "m_versionExceptionHash.remove %s\n", fullPath.toUtf8().data()); m_versionExceptionHash.remove(fullPath); fileExceptionRemove(fullPath, directory); } else if ((curState == Qt::Checked) && (row == 0)) { if (mainWin->m_rtVerTabICDebug) Pmsg1(000, "m_versionExceptionHash.remove %s\n", fullPath.toUtf8().data()); m_versionExceptionHash.remove(fullPath); } else if (prevState != curState) { if (mainWin->m_rtVerTabICDebug) Pmsg2(000, " THE STATE OF THE version Check has changed, Setting StateList[%i] to %i\n", row, curState); if ((curState == Qt::Checked) || (curState == Qt::PartiallyChecked)) { if (mainWin->m_rtVerTabICDebug) Pmsg2(000, "Inserting into m_versionExceptionHash %s, %i\n", fullPath.toUtf8().data(), thisJobNum); m_versionExceptionHash.insert(fullPath, thisJobNum); if (fileState != Qt::Checked) { if (mainWin->m_rtVerTabICDebug) Pmsg2(000, "Inserting into m_fileExceptionHash %s, %i\n", fullPath.toUtf8().data(), curState); fileExceptionInsert(fullPath, directory, curState); } } else { if (mainWin->m_rtVerTabICDebug) Pmsg0(000, "got here\n"); } } else { if (mainWin->m_rtVerTabICDebug) Pmsg0(000, "no conditions met\n"); } updateFileTableChecks(); updateVersionTableChecks(); } /* * Simple function to set the check state in the file table by disconnecting the * signal/slot the setting then reconnecting the signal/slot */ void restoreTree::fileTableDisconnectedSet(QTableWidgetItem *item, Qt::CheckState state, bool color) { disconnect(fileTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(fileTableItemChanged(QTableWidgetItem *))); item->setCheckState(state); if (color) item->setBackground(Qt::yellow); else item->setBackground(Qt::white); connect(fileTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(fileTableItemChanged(QTableWidgetItem *))); } /* * Simple function to set the check state in the version table by disconnecting the * signal/slot the setting then reconnecting the signal/slot */ void restoreTree::versionTableDisconnectedSet(QTableWidgetItem *item, Qt::CheckState state) { disconnect(versionTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(versionTableItemChanged(QTableWidgetItem *))); item->setCheckState(state); connect(versionTable, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(versionTableItemChanged(QTableWidgetItem *))); } /* * Simple function to set the check state in the directory tree by disconnecting the * signal/slot the setting then reconnecting the signal/slot */ void restoreTree::directoryTreeDisconnectedSet(QTreeWidgetItem *item, Qt::CheckState state) { disconnect(directoryTree, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(directoryItemChanged(QTreeWidgetItem *, int))); item->setCheckState(0, state); connect(directoryTree, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(directoryItemChanged(QTreeWidgetItem *, int))); } /* * Simplify the updating of the check state in the File table by iterating through * each item in the file table to determine it's appropriate state. * !! Will probably want to concoct a way to do this without iterating for the possibility * of the very large directories. */ void restoreTree::updateFileTableChecks() { /* deterimine the default state from the state of the directory */ QTreeWidgetItem *dirTreeItem = directoryTree->currentItem(); Qt::CheckState dirState = dirTreeItem->checkState(0); QString dirName = dirTreeItem->data(0, Qt::UserRole).toString(); /* Update the items in the version table */ int rcnt = fileTable->rowCount(); for (int row=0; rowitem(row, 0); if (!item) { return; } Qt::CheckState curState = item->checkState(); Qt::CheckState newState = Qt::PartiallyChecked; if (dirState == Qt::Unchecked) newState = Qt::Unchecked; /* determine if it is already in the m_fileExceptionHash */ QString file = item->text(); QString fullPath = dirName + file; Qt::CheckState hashState = m_fileExceptionHash.value(fullPath, (Qt::CheckState)3); int hashJobNum = m_versionExceptionHash.value(fullPath, 0); if (hashState != 3) newState = hashState; if (mainWin->m_rtUpdateFTDebug) { QString msg = QString("file row=%1 cur=%2 hash=%3 new=%4 dirState=%5\n") .arg(row).arg(curState).arg(hashState).arg(newState).arg(dirState); Pmsg1(000, "%s", msg.toUtf8().data()); } bool docolor = false; if (hashJobNum != 0) docolor = true; bool isyellow = item->background().color() == QColor(Qt::yellow); if ((newState != curState) || (hashState == 3) || ((isyellow && !docolor) || (!isyellow && docolor))) fileTableDisconnectedSet(item, newState, docolor); m_fileCheckStateList[row] = newState; } } /* * Simplify the updating of the check state in the Version table by iterating through * each item in the file table to determine it's appropriate state. */ void restoreTree::updateVersionTableChecks() { /* deterimine the default state from the state of the directory */ QTreeWidgetItem *dirTreeItem = directoryTree->currentItem(); Qt::CheckState dirState = dirTreeItem->checkState(0); QString dirName = dirTreeItem->data(0, Qt::UserRole).toString(); /* deterimine the default state from the state of the file */ QTableWidgetItem *fileTableItem = fileTable->item(fileTable->currentRow(), 0); if (!fileTableItem) { return; } Qt::CheckState fileState = fileTableItem->checkState(); QString file = fileTableItem->text(); QString fullPath = dirName + file; int hashJobNum = m_versionExceptionHash.value(fullPath, 0); /* Update the items in the version table */ int cnt = versionTable->rowCount(); for (int row=0; rowitem(row, 0); if (!item) { break; } Qt::CheckState curState = item->checkState(); Qt::CheckState newState = Qt::Unchecked; if ((row == 0) && (fileState != Qt::Unchecked) && (hashJobNum == 0)) newState = Qt::PartiallyChecked; /* determine if it is already in the versionExceptionHash */ if (hashJobNum) { int thisJobNum = item->text().toInt(); if (thisJobNum == hashJobNum) newState = Qt::Checked; } if (mainWin->m_rtChecksDebug) { QString msg = QString("ver row=%1 cur=%2 hashJobNum=%3 new=%4 dirState=%5\n") .arg(row).arg(curState).arg(hashJobNum).arg(newState).arg(dirState); Pmsg1(000, "%s", msg.toUtf8().data()); } if (newState != curState) versionTableDisconnectedSet(item, newState); m_versionCheckStateList[row] = newState; } } /* * Quick subroutine to "return via subPaths" a list of subpaths when passed a fullPath */ void restoreTree::fullPathtoSubPaths(QStringList &subPaths, QString &fullPath_in) { int index; bool done = false; QString fullPath = fullPath_in; QString direct, path; while (((index = fullPath.lastIndexOf("/", -2)) != -1) && (!done)) { direct = path = fullPath; path.replace(index+1, fullPath.length()-index-1, ""); direct.replace(0, index+1, ""); if (false) { QString msg = QString("length = \"%1\" index = \"%2\" Considering \"%3\" \"%4\"\n") .arg(fullPath.length()).arg(index).arg(path).arg(direct); Pmsg0(000, msg.toUtf8().data()); } fullPath = path; subPaths.append(fullPath); } } /* * A Function to set the icon state and insert a record into * m_directoryIconStateHash when an exception is added by the user */ void restoreTree::directoryIconStateInsert(QString &fullPath, Qt::CheckState excpState) { QStringList paths; fullPathtoSubPaths(paths, fullPath); /* an exception that causes the item in the file table to be "Checked" has occured */ if (excpState == Qt::Checked) { bool foundAsUnChecked = false; QTreeWidgetItem *firstItem = m_dirPaths.value(paths[0]); if (firstItem) { if (firstItem->checkState(0) == Qt::Unchecked) foundAsUnChecked = true; } if (foundAsUnChecked) { /* as long as directory item is Unchecked, set icon state to "green check" */ bool done = false; QListIterator siter(paths); while (siter.hasNext() && !done) { QString path = siter.next(); QTreeWidgetItem *item = m_dirPaths.value(path); if (item) { if (item->checkState(0) != Qt::Unchecked) done = true; else { directorySetIcon(1, FolderGreenChecked, path, item); if (mainWin->m_rtIconStateDebug) Pmsg1(000, "In restoreTree::directoryIconStateInsert inserting %s\n", path.toUtf8().data()); } } } } else { /* if it is partially checked or fully checked insert green Check until a unchecked is found in the path */ if (mainWin->m_rtIconStateDebug) Pmsg1(000, "In restoreTree::directoryIconStateInsert Aqua %s\n", paths[0].toUtf8().data()); bool done = false; QListIterator siter(paths); while (siter.hasNext() && !done) { QString path = siter.next(); QTreeWidgetItem *item = m_dirPaths.value(path); if (item) { /* if the directory item is checked, set icon state to unchecked "green check" */ if (item->checkState(0) == Qt::Checked) done = true; directorySetIcon(1, FolderGreenChecked, path, item); if (mainWin->m_rtIconStateDebug) Pmsg1(000, "In restoreTree::directoryIconStateInsert boogie %s\n", path.toUtf8().data()); } } } } /* an exception that causes the item in the file table to be "Unchecked" has occured */ if (excpState == Qt::Unchecked) { bool done = false; QListIterator siter(paths); while (siter.hasNext() && !done) { QString path = siter.next(); QTreeWidgetItem *item = m_dirPaths.value(path); if (item) { /* if the directory item is checked, set icon state to unchecked "white check" */ if (item->checkState(0) == Qt::Checked) done = true; directorySetIcon(1, FolderWhiteChecked, path, item); if (mainWin->m_rtIconStateDebug) Pmsg1(000, "In restoreTree::directoryIconStateInsert boogie %s\n", path.toUtf8().data()); } } } } /* * A function to set the icon state back to "folder" and to remove a record from * m_directoryIconStateHash when an exception is removed by a user. */ void restoreTree::directoryIconStateRemove() { QHash shouldBeIconStateHash; /* First determine all paths with icons that should be checked with m_fileExceptionHash */ /* Use iterator tera to iterate through m_fileExceptionHash */ QHashIterator tera(m_fileExceptionHash); while (tera.hasNext()) { tera.next(); if (mainWin->m_rtIconStateDebug) Pmsg2(000, "Alpha Key %s value %i\n", tera.key().toUtf8().data(), tera.value()); QString keyPath = tera.key(); Qt::CheckState state = tera.value(); QStringList paths; fullPathtoSubPaths(paths, keyPath); /* if the state of the item in m_fileExceptionHash is checked * each of the subpaths should be "Checked Green" */ if (state == Qt::Checked) { bool foundAsUnChecked = false; QTreeWidgetItem *firstItem = m_dirPaths.value(paths[0]); if (firstItem) { if (firstItem->checkState(0) == Qt::Unchecked) foundAsUnChecked = true; } if (foundAsUnChecked) { /* The right most directory is Unchecked, iterate leftwards * as long as directory item is Unchecked, set icon state to "green check" */ bool done = false; QListIterator siter(paths); while (siter.hasNext() && !done) { QString path = siter.next(); QTreeWidgetItem *item = m_dirPaths.value(path); if (item) { if (item->checkState(0) != Qt::Unchecked) done = true; else { shouldBeIconStateHash.insert(path, FolderGreenChecked); if (mainWin->m_rtIconStateDebug) Pmsg1(000, "In restoreTree::directoryIconStateInsert inserting %s\n", path.toUtf8().data()); } } } } else { /* The right most directory is Unchecked, iterate leftwards * until directory item is Checked, set icon state to "green check" */ bool done = false; QListIterator siter(paths); while (siter.hasNext() && !done) { QString path = siter.next(); QTreeWidgetItem *item = m_dirPaths.value(path); if (item) { if (item->checkState(0) == Qt::Checked) done = true; shouldBeIconStateHash.insert(path, FolderGreenChecked); } } } } /* if the state of the item in m_fileExceptionHash is UNChecked * each of the subpaths should be "Checked white" until the tree item * which represents that path is Qt::Checked */ if (state == Qt::Unchecked) { bool done = false; QListIterator siter(paths); while (siter.hasNext() && !done) { QString path = siter.next(); QTreeWidgetItem *item = m_dirPaths.value(path); if (item) { if (item->checkState(0) == Qt::Checked) done = true; shouldBeIconStateHash.insert(path, FolderWhiteChecked); } } } } /* now iterate through m_directoryIconStateHash which are the items that are checked * and remove all of those that are not in shouldBeIconStateHash */ QHashIterator iter(m_directoryIconStateHash); while (iter.hasNext()) { iter.next(); if (mainWin->m_rtIconStateDebug) Pmsg2(000, "Beta Key %s value %i\n", iter.key().toUtf8().data(), iter.value()); QString keyPath = iter.key(); if (shouldBeIconStateHash.value(keyPath)) { if (mainWin->m_rtIconStateDebug) Pmsg1(000, "WAS found in shouldBeStateHash %s\n", keyPath.toUtf8().data()); //newval = m_directoryIconStateHash.value(path, FolderUnchecked) & (~change); int newval = shouldBeIconStateHash.value(keyPath); newval = ~newval; newval = newval & FolderBothChecked; QTreeWidgetItem *item = m_dirPaths.value(keyPath); if (item) directorySetIcon(0, newval, keyPath, item); } else { if (mainWin->m_rtIconStateDebug) Pmsg1(000, "NOT found in shouldBeStateHash %s\n", keyPath.toUtf8().data()); QTreeWidgetItem *item = m_dirPaths.value(keyPath); if (item) directorySetIcon(0, FolderBothChecked, keyPath, item); //item->setIcon(0,QIcon(QString::fromUtf8(":images/folder.png"))); //m_directoryIconStateHash.remove(keyPath); } } } void restoreTree::directorySetIcon(int operation, int change, QString &path, QTreeWidgetItem* item) { int newval; /* we are adding a check type white or green */ if (operation > 0) { /* get the old val and "bitwise OR" with the change */ newval = m_directoryIconStateHash.value(path, FolderUnchecked) | change; if (mainWin->m_rtIconStateDebug) Pmsg2(000, "Inserting into m_directoryIconStateHash path=%s newval=%i\n", path.toUtf8().data(), newval); m_directoryIconStateHash.insert(path, newval); } else { /* we are removing a check type white or green */ newval = m_directoryIconStateHash.value(path, FolderUnchecked) & (~change); if (newval == 0) { if (mainWin->m_rtIconStateDebug) Pmsg2(000, "Removing from m_directoryIconStateHash path=%s newval=%i\n", path.toUtf8().data(), newval); m_directoryIconStateHash.remove(path); } else { if (mainWin->m_rtIconStateDebug) Pmsg2(000, "Inserting into m_directoryIconStateHash path=%s newval=%i\n", path.toUtf8().data(), newval); m_directoryIconStateHash.insert(path, newval); } } if (newval == FolderUnchecked) item->setIcon(0, QIcon(QString::fromUtf8(":images/folder.png"))); else if (newval == FolderGreenChecked) item->setIcon(0, QIcon(QString::fromUtf8(":images/folderchecked.png"))); else if (newval == FolderWhiteChecked) item->setIcon(0, QIcon(QString::fromUtf8(":images/folderunchecked.png"))); else if (newval == FolderBothChecked) item->setIcon(0, QIcon(QString::fromUtf8(":images/folderbothchecked.png"))); } /* * Restore Button */ void restoreTree::restoreButtonPushed() { /* Set progress bars and repaint */ prLabel1->setVisible(true); prLabel1->setText(tr("Task 1 of 3")); prLabel2->setVisible(true); prLabel2->setText(tr("Processing Checked directories")); prBar1->setVisible(true); prBar1->setRange(0, 3); prBar1->setValue(0); prBar2->setVisible(true); prBar2->setRange(0, 0); repaint(); QMultiHash versionFilesMulti; int vFMCounter = 0; QHash fullPathDone; QHash fileIndexHash; if ((mainWin->m_rtRestore1Debug) || (mainWin->m_rtRestore2Debug) || (mainWin->m_rtRestore3Debug)) Pmsg0(000, "In restoreTree::restoreButtonPushed\n"); /* Use a tree widget item iterator to count directories for the progress bar */ QTreeWidgetItemIterator diterc(directoryTree, QTreeWidgetItemIterator::Checked); int ditcount = 0; while (*diterc) { ditcount += 1; ++diterc; } /* while (*diterc) */ prBar2->setRange(0, ditcount); prBar2->setValue(0); ditcount = 0; /* Use a tree widget item iterator filtering for Checked Items */ QTreeWidgetItemIterator diter(directoryTree, QTreeWidgetItemIterator::Checked); while (*diter) { QString directory = (*diter)->data(0, Qt::UserRole).toString(); int pathid = m_directoryPathIdHash.value(directory, -1); if (pathid != -1) { if (mainWin->m_rtRestore1Debug) Pmsg1(000, "Directory Checked=\"%s\"\n", directory.toUtf8().data()); /* With a checked directory, query for the files in the directory */ QString cmd = "SELECT Filename.Name AS Filename, t1.JobId AS JobId, File.FileIndex AS FileIndex" " FROM" " ( SELECT File.FilenameId AS FilenameId, MAX(Job.JobId) AS JobId" " FROM File" " INNER JOIN Job ON (Job.JobId=File.JobId)" " WHERE File.PathId=" + QString("%1").arg(pathid) + " AND Job.Jobid IN (" + m_checkedJobs + ")" " GROUP BY File.FilenameId" ") t1, File " " INNER JOIN Filename on (Filename.FilenameId=File.FilenameId)" " INNER JOIN Job ON (Job.JobId=File.JobId)" " WHERE File.PathId=" + QString("%1").arg(pathid) + " AND File.FilenameId=t1.FilenameId" " AND Job.Jobid=t1.JobId" " ORDER BY Filename"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); QStringList results; if (m_console->sql_cmd(cmd, results)) { QStringList fieldlist; int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { /* Iterate through fields in the record */ int column = 0; QString fullPath = ""; Qt::CheckState fileExcpState = (Qt::CheckState)4; fieldlist = resultline.split("\t"); int version = 0; int fileIndex = 0; foreach (QString field, fieldlist) { if (column == 0) { fullPath = directory + field; } if (column == 1) { version = field.toInt(); } if (column == 2) { fileIndex = field.toInt(); } column++; } fileExcpState = m_fileExceptionHash.value(fullPath, (Qt::CheckState)3); int excpVersion = m_versionExceptionHash.value(fullPath, 0); if (fileExcpState != Qt::Unchecked) { QString debugtext; if (excpVersion != 0) { debugtext = QString("*E* version=%1").arg(excpVersion); version = excpVersion; fileIndex = queryFileIndex(fullPath, excpVersion); } else debugtext = QString("___ version=%1").arg(version); if (mainWin->m_rtRestore1Debug) Pmsg2(000, "Restoring %s File %s\n", debugtext.toUtf8().data(), fullPath.toUtf8().data()); fullPathDone.insert(fullPath, 1); fileIndexHash.insert(fullPath, fileIndex); versionFilesMulti.insert(version, fullPath); vFMCounter += 1; } row++; } } } ditcount += 1; prBar2->setValue(ditcount); ++diter; } /* while (*diter) */ prBar1->setValue(1); prLabel1->setText( tr("Task 2 of 3")); prLabel2->setText(tr("Processing Exceptions")); prBar2->setRange(0, 0); repaint(); /* There may be some exceptions not accounted for yet with fullPathDone */ QHashIterator ftera(m_fileExceptionHash); while (ftera.hasNext()) { ftera.next(); QString fullPath = ftera.key(); Qt::CheckState state = ftera.value(); if (state != 0) { /* now we don't want the ones already done */ if (fullPathDone.value(fullPath, 0) == 0) { int version = m_versionExceptionHash.value(fullPath, 0); int fileIndex = 0; QString debugtext = ""; if (version != 0) { fileIndex = queryFileIndex(fullPath, version); debugtext = QString("E1* version=%1 fileid=%2").arg(version).arg(fileIndex); } else { version = mostRecentVersionfromFullPath(fullPath); if (version) { fileIndex = queryFileIndex(fullPath, version); debugtext = QString("E2* version=%1 fileid=%2").arg(version).arg(fileIndex); } else debugtext = QString("Error det vers").arg(version); } if (mainWin->m_rtRestore1Debug) Pmsg2(000, "Restoring %s file %s\n", debugtext.toUtf8().data(), fullPath.toUtf8().data()); versionFilesMulti.insert(version, fullPath); vFMCounter += 1; fileIndexHash.insert(fullPath, fileIndex); } /* if fullPathDone.value(fullPath, 0) == 0 */ } /* if state != 0 */ } /* while ftera.hasNext */ /* The progress bars for the next step */ prBar1->setValue(2); prLabel1->setText(tr("Task 3 of 3")); prLabel2->setText(tr("Filling Database Table")); prBar2->setRange(0, vFMCounter); vFMCounter = 0; prBar2->setValue(vFMCounter); repaint(); /* now for the final spit out of the versions and lists of files for each version */ QHash doneKeys; QHashIterator vFMiter(versionFilesMulti); QString tempTable = ""; QList jobList; while (vFMiter.hasNext()) { vFMiter.next(); int fversion = vFMiter.key(); /* did not succeed in getting an iterator to work as expected on versionFilesMulti so use doneKeys */ if (doneKeys.value(fversion, 0) == 0) { if (tempTable == "") { QSettings settings("www.bareos.org", "bat"); settings.beginGroup("Restore"); int counter = settings.value("Counter", 1).toInt(); settings.setValue("Counter", counter+1); settings.endGroup(); tempTable = "restore_" + QString("%1").arg(qrand()) + "_" + QString("%1").arg(counter); QString sqlcmd = "CREATE TEMPORARY TABLE " + tempTable + " (JobId INTEGER, FileIndex INTEGER)"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s ;\n", sqlcmd.toUtf8().data()); QStringList results; if (!m_console->sql_cmd(sqlcmd, results)) Pmsg1(000, "CREATE TABLE FAILED!!!! %s\n", sqlcmd.toUtf8().data()); } if (mainWin->m_rtRestore2Debug) Pmsg1(000, "Version->%i\n", fversion); QStringList fullPathList = versionFilesMulti.values(fversion); /* create the command to perform the restore */ foreach(QString ffullPath, fullPathList) { int fileIndex = fileIndexHash.value(ffullPath); if (mainWin->m_rtRestore2Debug) Pmsg2(000, " file->%s id %i\n", ffullPath.toUtf8().data(), fileIndex); QString sqlcmd = "INSERT INTO " + tempTable + " (JobId, FileIndex) VALUES (" + QString("%1").arg(fversion) + ", " + QString("%1").arg(fileIndex) + ")"; if (mainWin->m_rtRestore3Debug) Pmsg1(000, "Insert cmd : %s\n", sqlcmd.toUtf8().data()); QStringList results; if (!m_console->sql_cmd(sqlcmd, results)) Pmsg1(000, "INSERT INTO FAILED!!!! %s\n", sqlcmd.toUtf8().data()); prBar2->setValue(++vFMCounter); } /* foreach fullPathList */ doneKeys.insert(fversion,1); jobList.append(fversion); } /* if (doneKeys.value(fversion, 0) == 0) */ } /* while (vFMiter.hasNext()) */ if (tempTable != "") { /* a table was made, lets run the job */ QString jobOption = " jobid=\""; bool first = true; /* create a list of jobs comma separated */ foreach (int job, jobList) { if (first) first = false; else jobOption += ","; jobOption += QString("%1").arg(job); } jobOption += "\""; QString cmd = QString("restore"); cmd += jobOption + " client=\"" + m_prevClientCombo + "\"" + " file=\"?" + tempTable + "\" done"; if (mainWin->m_commandDebug) Pmsg1(000, "preRestore command \'%s\'\n", cmd.toUtf8().data()); consoleCommand(cmd); } /* turn off the progress widgets */ prBar1->setVisible(false); prBar2->setVisible(false); prLabel1->setVisible(false); prLabel2->setVisible(false); } int restoreTree::mostRecentVersionfromFullPath(QString &fullPath) { int qversion = 0; QString directory, fileName; int index = fullPath.lastIndexOf("/", -2); if (index != -1) { directory = fileName = fullPath; directory.replace(index+1, fullPath.length()-index-1, ""); fileName.replace(0, index+1, ""); if (false) { QString msg = QString("length = \"%1\" index = \"%2\" Considering \"%3\" \"%4\"\n") .arg(fullPath.length()).arg(index).arg(fileName).arg(directory); Pmsg0(000, msg.toUtf8().data()); } int pathid = m_directoryPathIdHash.value(directory, -1); if (pathid != -1) { /* so now we need the latest version from the database */ QString cmd = "SELECT MAX(Job.JobId)" " FROM File " " INNER JOIN Filename on (Filename.FilenameId=File.FilenameId)" " INNER JOIN Job ON (File.JobId=Job.JobId)" " WHERE File.PathId=" + QString("%1").arg(pathid) + " AND Job.Jobid IN (" + m_checkedJobs + ")" " AND Filename.Name='" + fileName + "'" " AND File.FilenameId!=" + QString("%1").arg(m_nullFileNameId) + " GROUP BY Filename.Name"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); QStringList results; if (m_console->sql_cmd(cmd, results)) { QStringList fieldlist; int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { /* Iterate through fields in the record */ int column = 0; fieldlist = resultline.split("\t"); foreach (QString field, fieldlist) { if (column == 0) { qversion = field.toInt(); } column++; } row++; } } } } /* if (index != -1) */ return qversion; } int restoreTree::queryFileIndex(QString &fullPath, int jobId) { int qfileIndex = 0; QString directory, fileName; int index = fullPath.lastIndexOf("/", -2); if (mainWin->m_sqlDebug) Pmsg1(000, "Index=%d\n", index); if (index != -1) { directory = fileName = fullPath; directory.replace(index+1, fullPath.length()-index-1, ""); fileName.replace(0, index+1, ""); if (false) { QString msg = QString("length = \"%1\" index = \"%2\" Considering \"%3\" \"%4\"\n") .arg(fullPath.length()).arg(index).arg(fileName).arg(directory); Pmsg0(000, msg.toUtf8().data()); } int pathid = m_directoryPathIdHash.value(directory, -1); if (pathid != -1) { /* so now we need the latest version from the database */ QString cmd = "SELECT" " File.FileIndex" " FROM File" " INNER JOIN Filename on (Filename.FilenameId=File.FilenameId)" " INNER JOIN Job ON (File.JobId=Job.JobId)" " WHERE File.PathId=" + QString("%1").arg(pathid) + " AND Filename.Name='" + fileName + "'" " AND Job.Jobid='" + QString("%1").arg(jobId) + "'" " GROUP BY File.FileIndex"; if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data()); QStringList results; if (m_console->sql_cmd(cmd, results)) { QStringList fieldlist; int row = 0; /* Iterate through the record returned from the query */ foreach (QString resultline, results) { /* Iterate through fields in the record */ int column = 0; fieldlist = resultline.split("\t"); foreach (QString field, fieldlist) { if (column == 0) { qfileIndex = field.toInt(); } column++; } row++; } } } } /* if (index != -1) */ if (mainWin->m_sqlDebug) Pmsg1(000, "qfileIndex=%d\n", qfileIndex); return qfileIndex; } void restoreTree::PgSeltreeWidgetClicked() { if (!isOnceDocked()) { dockPage(); } } bareos-Release-14.2.6/src/qt-console/restore/restoretree.h000066400000000000000000000076211263011562700235200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, February 2007 */ #ifndef _RESTORETREE_H_ #define _RESTORETREE_H_ #include #include "pages.h" #include "ui_restoretree.h" /* * A restore tree to view files in the catalog */ class restoreTree : public Pages, public Ui::restoreTreeForm { Q_OBJECT public: restoreTree(); ~restoreTree(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); enum folderCheckState { FolderUnchecked = 0, FolderGreenChecked = 1, FolderWhiteChecked = 2, FolderBothChecked = 3 }; private slots: void refreshButtonPushed(); void restoreButtonPushed(); void jobComboChanged(int); void directoryCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); void fileCurrentItemChanged(QTableWidgetItem *,QTableWidgetItem *); void directoryItemExpanded(QTreeWidgetItem *); void setCheckofChildren(QTreeWidgetItem *item, Qt::CheckState); void directoryItemChanged(QTreeWidgetItem *, int); void fileTableItemChanged(QTableWidgetItem *); void versionTableItemChanged(QTableWidgetItem *); void updateRefresh(); void jobTableCellClicked(int, int); private: void populateDirectoryTree(); void populateJobTable(); void parseDirectory(const QString &dir_in); void setupPage(); void writeSettings(); void readSettings(); void fileExceptionInsert(QString &, QString &, Qt::CheckState); void fileExceptionRemove(QString &, QString &); void directoryTreeDisconnectedSet(QTreeWidgetItem *, Qt::CheckState); void fileTableDisconnectedSet(QTableWidgetItem *, Qt::CheckState, bool color); void versionTableDisconnectedSet(QTableWidgetItem *, Qt::CheckState); void updateFileTableChecks(); void updateVersionTableChecks(); void directoryIconStateInsert(QString &, Qt::CheckState); void directoryIconStateRemove(); void directorySetIcon(int operation, int change, QString &, QTreeWidgetItem* item); void fullPathtoSubPaths(QStringList &, QString &); int mostRecentVersionfromFullPath(QString &); void setJobsCheckedList(); int queryFileIndex(QString &fullPath, int jobID); QSplitter *m_splitter; QString m_groupText; QString m_splitText1; QString m_splitText2; bool m_populated; bool m_dropdownChanged; bool m_slashTrap; QHash m_dirPaths; QString m_checkedJobs, m_prevJobCombo, m_prevClientCombo, m_prevFileSetCombo; int m_prevLimitSpinBox, m_prevDaysSpinBox; Qt::CheckState m_prevLimitCheckState, m_prevDaysCheckState; QString m_JobsCheckedList; int m_debugCnt; bool m_debugTrap; QList m_fileCheckStateList; QList m_versionCheckStateList; QHash m_fileExceptionHash; QMultiHash m_fileExceptionMulti; QHash m_versionExceptionHash; QHash m_directoryIconStateHash; QHash m_directoryPathIdHash; int m_toggleUpIndex, m_toggleDownIndex, m_nullFileNameId; }; #endif /* _RESTORETREE_H_ */ bareos-Release-14.2.6/src/qt-console/restore/restoretree.ui000066400000000000000000000265601263011562700237110ustar00rootroot00000000000000 restoreTreeForm 0 0 695 432 Form 120 190 382 221 Qt::Horizontal 6 0 Jobs Qt::AlignCenter TextLabel Qt::AlignCenter true 24 Qt::Horizontal TextLabel Qt::AlignCenter true 24 Qt::Horizontal 1 6 0 Files Qt::AlignCenter 6 0 Versions of File Qt::AlignCenter FileName Qt::AlignCenter 20 59 669 95 900 95 3 2 4 2 2 3 Refresh :/images/view-refresh.png:/images/view-refresh.png TextLabel Restore :/images/restore.png:/images/restore.png 3 2 Job 0 0 Job List Job Criterion Selector Job List Job Criterion Selector 3 2 Client 0 0 Job List Client Criterion Selector Job List Client Criterion Selector 3 2 FileSet 0 0 Job List Fileset Criterion Selector Job List Fileset Criterion Selector 3 2 Record Limit 1 10000 25 3 2 Days Limit 7 0 0 PointingHandCursor Directory Select Directory UnselectDirectory bareos-Release-14.2.6/src/qt-console/restore/runrestore.ui000066400000000000000000000253511263011562700235530ustar00rootroot00000000000000 bRunRestoreForm 0 0 385 438 Run restore 0 Standard Restore options QFormLayout::ExpandingFieldsGrow Client: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Where: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Replace: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Comment: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Media needed false Qt::NoPen InChanger Volume Compute with directories false Advanced File Relocation Use file relocation: Strip prefix: false Add prefix: false Add suffix: false Use regexp: false Where regexp: false Other options When: Priority: 10 Storage: true Job: Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok ActionBp accepted() bRunRestoreForm accept() 222 422 157 274 ActionBp rejected() bRunRestoreForm reject() 290 428 286 274 UseFileRelocationChk clicked(bool) WhereEntry setDisabled(bool) 107 72 225 102 bareos-Release-14.2.6/src/qt-console/run/000077500000000000000000000000001263011562700201175ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/run/estimate.cpp000066400000000000000000000065701263011562700224460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Run Dialog class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "run.h" /* * Setup all the combo boxes and display the dialog */ estimatePage::estimatePage() : Pages() { QDateTime dt; m_name = tr("Estimate"); pgInitialize(); setupUi(this); m_conn = m_console->notifyOff(); m_console->beginNewCommand(m_conn); jobCombo->addItems(m_console->job_list); filesetCombo->addItems(m_console->fileset_list); levelCombo->addItems(m_console->level_list); clientCombo->addItems(m_console->client_list); job_name_change(0); connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(job_name_change(int))); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/estimate-job.png"))); dockPage(); setCurrent(); this->show(); m_aButtonPushed = false; } void estimatePage::okButtonPushed() { if (m_aButtonPushed) return; m_aButtonPushed = true; this->hide(); QString cmd; QTextStream(&cmd) << "estimate" << " job=\"" << jobCombo->currentText() << "\"" << " fileset=\"" << filesetCombo->currentText() << "\"" << " level=\"" << levelCombo->currentText() << "\"" << " client=\"" << clientCombo->currentText() << "\""; if (listingCheckBox->checkState() == Qt::Checked) { cmd += " listing"; } if (mainWin->m_commandDebug) { Pmsg1(000, "command : %s\n", cmd.toUtf8().data()); } consoleCommand(cmd, m_conn); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } void estimatePage::cancelButtonPushed() { if (m_aButtonPushed) return; m_aButtonPushed = true; mainWin->set_status(" Canceled"); this->hide(); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } /* * Called here when the jobname combo box is changed. * We load the default values for the new job in the * other combo boxes. */ void estimatePage::job_name_change(int index) { job_defaults job_defs; (void)index; job_defs.job_name = jobCombo->currentText(); if (m_console->get_job_defaults(m_conn, job_defs)) { filesetCombo->setCurrentIndex(filesetCombo->findText(job_defs.fileset_name, Qt::MatchExactly)); levelCombo->setCurrentIndex(levelCombo->findText(job_defs.level, Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly)); } } bareos-Release-14.2.6/src/qt-console/run/estimate.ui000066400000000000000000000160401263011562700222720ustar00rootroot00000000000000 estimateForm 0 0 562 308 Form 9 6 0 6 0 6 Qt::RightToLeft List Files Qt::Horizontal 40 20 0 6 Level: levelCombo Client: clientCombo 65 16777215 Job: jobCombo FileSet: filesetCombo 0 6 Qt::Horizontal 71 21 16777215 30 <h3>Estimate a backup Job</h3> Qt::Horizontal 81 20 0 6 Qt::Horizontal 40 20 OK Cancel Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Expanding 351 16 Qt::Vertical QSizePolicy::Expanding 351 16 Qt::Horizontal 40 20 bareos-Release-14.2.6/src/qt-console/run/prune.cpp000066400000000000000000000077251263011562700217670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Run Dialog class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "run.h" /* * Setup all the combo boxes and display the dialog */ prunePage::prunePage(const QString &volume, const QString &client) : Pages() { QDateTime dt; m_name = tr("Prune"); pgInitialize(); setupUi(this); m_conn = m_console->notifyOff(); QString query("SELECT VolumeName AS Media FROM Media ORDER BY Media"); if (mainWin->m_sqlDebug) { Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data()); } QStringList results, volumeList; if (m_console->sql_cmd(query, results)) { QString field; QStringList fieldlist; /* Iterate through the lines of results. */ foreach (QString resultline, results) { fieldlist = resultline.split("\t"); volumeList.append(fieldlist[0]); } /* foreach resultline */ } /* if results from query */ volumeCombo->addItem(tr("Any")); volumeCombo->addItems(volumeList); clientCombo->addItem(tr("Any")); clientCombo->addItems(m_console->client_list); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); filesRadioButton->setChecked(true); if (clientCombo->findText(client, Qt::MatchExactly) != -1) clientCombo->setCurrentIndex(clientCombo->findText(client, Qt::MatchExactly)); else clientCombo->setCurrentIndex(0); if (volumeCombo->findText(volume, Qt::MatchExactly) != -1) volumeCombo->setCurrentIndex(volumeCombo->findText(volume, Qt::MatchExactly)); else volumeCombo->setCurrentIndex(0); connect(volumeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(volumeChanged())); connect(clientCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(clientChanged())); dockPage(); setCurrent(); this->show(); } void prunePage::okButtonPushed() { this->hide(); QString cmd("prune"); if (filesRadioButton->isChecked()) { cmd += " files"; } if (jobsRadioButton->isChecked()) { cmd += " jobs"; } if (filesRadioButton->isChecked()) { cmd += " volume"; } if (volumeCombo->currentText() != tr("Any")) { cmd += QString(" volume=\"%1\"") .arg(volumeCombo->currentText()); } if (clientCombo->currentText() != tr("Any")) { cmd += QString(" client=\"%1\"") .arg(clientCombo->currentText()); } cmd += " yes"; if (mainWin->m_commandDebug) { Pmsg1(000, "command : %s\n", cmd.toUtf8().data()); } consoleCommand(cmd); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } void prunePage::cancelButtonPushed() { mainWin->set_status(tr(" Canceled")); this->hide(); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } void prunePage::volumeChanged() { if ((volumeCombo->currentText() == tr("Any")) && (clientCombo->currentText() == tr("Any"))) { clientCombo->setCurrentIndex(1); } } void prunePage::clientChanged() { if ((volumeCombo->currentText() == tr("Any")) && (clientCombo->currentText() == tr("Any"))) { volumeCombo->setCurrentIndex(1); } } bareos-Release-14.2.6/src/qt-console/run/prune.ui000066400000000000000000000166441263011562700216220ustar00rootroot00000000000000 pruneForm 0 0 514 363 Form 9 6 0 6 0 6 Prune Files Qt::Horizontal 40 20 Volume: volumeCombo 0 6 Qt::Horizontal 71 21 16777215 30 <h3>Prune Files/Jobs/Volumes</h3> Qt::Horizontal 81 20 0 6 Prune Jobs Qt::Horizontal 40 20 0 6 Qt::Horizontal 40 20 OK Cancel 65 16777215 Client: clientCombo 0 6 Prune Volumes Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Expanding 351 16 Qt::Vertical QSizePolicy::Expanding 351 16 Qt::Horizontal 40 20 Qt::Horizontal 40 20 bareos-Release-14.2.6/src/qt-console/run/run.cpp000066400000000000000000000144271263011562700214370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Run Dialog class * * Kern Sibbald, February MMVII */ #include "bat.h" #include "run.h" runPage::runPage() : Pages() { init(); show(); } runPage::runPage(const QString &defJob) : Pages() { m_dockOnFirstUse = false; init(); if (defJob != "") jobCombo->setCurrentIndex(jobCombo->findText(defJob, Qt::MatchExactly)); show(); } runPage::runPage(const QString &defJob, const QString &level, const QString &pool, const QString &storage, const QString &client, const QString &fileset) : Pages() { m_dockOnFirstUse = false; init(); jobCombo->setCurrentIndex(jobCombo->findText(defJob, Qt::MatchExactly)); job_name_change(0); filesetCombo->setCurrentIndex(filesetCombo->findText(fileset, Qt::MatchExactly)); levelCombo->setCurrentIndex(levelCombo->findText(level, Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(client,Qt::MatchExactly)); poolCombo->setCurrentIndex(poolCombo->findText(pool, Qt::MatchExactly)); if (storage != "") { // TODO: enable storage storageCombo->setCurrentIndex(storageCombo->findText(storage, Qt::MatchExactly)); } show(); } /* * Setup all the combo boxes and display the dialog */ void runPage::init() { QDateTime dt; QDesktopWidget *desk = QApplication::desktop(); QRect scrn; m_name = tr("Run"); pgInitialize(); setupUi(this); /* Get screen rectangle */ scrn = desk->screenGeometry(desk->primaryScreen()); /* Position this window in the middle of the screen */ this->move((scrn.width()-this->width())/2, (scrn.height()-this->height())/2); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/run.png"))); m_conn = m_console->notifyOff(); m_console->beginNewCommand(m_conn); jobCombo->addItems(m_console->job_list); filesetCombo->addItems(m_console->fileset_list); levelCombo->addItems(m_console->level_list); clientCombo->addItems(m_console->client_list); poolCombo->addItems(m_console->pool_list); storageCombo->addItems(m_console->storage_list); dateTimeEdit->setDisplayFormat(mainWin->m_dtformat); dateTimeEdit->setDateTime(dt.currentDateTime()); /*printf("listing messages resources"); ***FIME *** foreach(QString mes, m_console->messages_list) { printf("%s\n", mes.toUtf8().data()); }*/ messagesCombo->addItems(m_console->messages_list); messagesCombo->setEnabled(false); job_name_change(0); connect(jobCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(job_name_change(int))); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); // find a way to place the new window at the cursor position // or in the middle of the page // dockPage(); setCurrent(); } void runPage::okButtonPushed() { this->hide(); QString cmd; QTextStream(&cmd) << "run" << " job=\"" << jobCombo->currentText() << "\"" << " fileset=\"" << filesetCombo->currentText() << "\"" << " level=\"" << levelCombo->currentText() << "\"" << " client=\"" << clientCombo->currentText() << "\"" << " pool=\"" << poolCombo->currentText() << "\"" << " storage=\"" << storageCombo->currentText() << "\"" << " priority=\"" << prioritySpin->value() << "\"" " when=\"" << dateTimeEdit->dateTime().toString(mainWin->m_dtformat) << "\""; #ifdef xxx " messages=\"" << messagesCombo->currentText() << "\""; /* FIXME when there is an option to modify the messages resource associated * with a job */ #endif if (bootstrap->text() != "") { cmd += " bootstrap=\"" + bootstrap->text() + "\""; } cmd += " yes"; if (mainWin->m_commandDebug) { Pmsg1(000, "command : %s\n", cmd.toUtf8().data()); } consoleCommand(cmd); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } void runPage::cancelButtonPushed() { mainWin->set_status(tr(" Canceled")); this->hide(); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } /* * Called here when the jobname combo box is changed. * We load the default values for the new job in the * other combo boxes. */ void runPage::job_name_change(int index) { job_defaults job_defs; (void)index; job_defs.job_name = jobCombo->currentText(); if (m_console->get_job_defaults(job_defs)) { QString cmd; typeLabel->setText("

"+job_defs.type+"

"); filesetCombo->setCurrentIndex(filesetCombo->findText(job_defs.fileset_name, Qt::MatchExactly)); levelCombo->setCurrentIndex(levelCombo->findText(job_defs.level, Qt::MatchExactly)); clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly)); poolCombo->setCurrentIndex(poolCombo->findText(job_defs.pool_name, Qt::MatchExactly)); storageCombo->setCurrentIndex(storageCombo->findText(job_defs.store_name, Qt::MatchExactly)); messagesCombo->setCurrentIndex(messagesCombo->findText(job_defs.messages_name, Qt::MatchExactly)); m_console->level_list.clear(); cmd = ".levels " + job_defs.type; m_console->dir_cmd(cmd, m_console->level_list); levelCombo->clear(); levelCombo->addItems(m_console->level_list); levelCombo->setCurrentIndex(levelCombo->findText(job_defs.level, 0 /*Qt::MatchExactly*/)); } } bareos-Release-14.2.6/src/qt-console/run/run.h000066400000000000000000000045071263011562700211020ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _RUN_H_ #define _RUN_H_ #include #include "ui_run.h" #include "ui_runcmd.h" #include "ui_estimate.h" #include "ui_prune.h" #include class runPage : public Pages, public Ui::runForm { Q_OBJECT public: runPage(); runPage(const QString &defJob); runPage(const QString &defJob, const QString &level, const QString &pool, const QString &storage, const QString &client, const QString &fileset); public slots: void okButtonPushed(); void cancelButtonPushed(); void job_name_change(int index); private: void init(); int m_conn; }; class runCmdPage : public Pages, public Ui::runCmdForm { Q_OBJECT public: runCmdPage(int conn); public slots: void okButtonPushed(); void cancelButtonPushed(); private: void fill(); int m_conn; }; class estimatePage : public Pages, public Ui::estimateForm { Q_OBJECT public: estimatePage(); public slots: void okButtonPushed(); void cancelButtonPushed(); void job_name_change(int index); private: int m_conn; bool m_aButtonPushed; }; class prunePage : public Pages, public Ui::pruneForm { Q_OBJECT public: prunePage(const QString &volume, const QString &client); public slots: void okButtonPushed(); void cancelButtonPushed(); void volumeChanged(); void clientChanged(); private: int m_conn; }; #endif /* _RUN_H_ */ bareos-Release-14.2.6/src/qt-console/run/run.ui000066400000000000000000000235751263011562700212760ustar00rootroot00000000000000 runForm 0 0 594 415 0 0 Run job 16777215 30 11 <h3>Run a Job</h3> 0 0 0 5 Qt::Horizontal :/images/runit.png Job properties Job: jobCombo 6 0 0 0 0 Type: <h3>Backup<h3/> Client: clientCombo Priority: prioritySpin 1 10000 10 Level: levelCombo Qt::Vertical 56 151 FileSet: filesetCombo Pool: poolCombo Storage: storageCombo Messages: messagesCombo When: dateTimeEdit 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true Bootstrap: true bootstrap true 200 0 false 0 0 0 5 Qt::Horizontal Qt::Horizontal 40 20 OK Cancel bareos-Release-14.2.6/src/qt-console/run/runadmin.ui000066400000000000000000000242231263011562700222760ustar00rootroot00000000000000 runAdminForm 0 0 704 466 Form 9 6 0 6 0 6 Priority: prioritySpin 10000 1 12 Qt::Vertical 20 171 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 0 6 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true When: dateTimeEdit Where: true where Bootstrap: bootstrap Job: jobCombo true 200 0 false Storage: storageCombo FileSet: filesetCombo true 200 0 false Replace: To client: clientCombo Catalog: catalogCombo 0 6 Qt::Horizontal 40 20 OK Cancel 0 6 Qt::Horizontal QSizePolicy::Fixed 131 25 16777215 30 <h3>Run Restore Job</h3> Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 131 25 bareos-Release-14.2.6/src/qt-console/run/runbackup.ui000066400000000000000000000242251263011562700224550ustar00rootroot00000000000000 runBackupForm 0 0 704 466 Form 9 6 0 6 0 6 Priority: prioritySpin 10000 1 12 Qt::Vertical 20 171 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 0 6 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true When: dateTimeEdit Where: true where Bootstrap: bootstrap Job: jobCombo true 200 0 false Storage: storageCombo FileSet: filesetCombo true 200 0 false Replace: To client: clientCombo Catalog: catalogCombo 0 6 Qt::Horizontal 40 20 OK Cancel 0 6 Qt::Horizontal QSizePolicy::Fixed 131 25 16777215 30 <h3>Run Restore Job</h3> Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 131 25 bareos-Release-14.2.6/src/qt-console/run/runcmd.cpp000066400000000000000000000127051263011562700221200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Run Command Dialog class * * This is called when a Run Command signal is received from the * Director. We parse the Director's output and throw up a * dialog box. This happens, for example, after the user finishes * selecting files to be restored. The Director will then submit a * run command, that causes this page to be popped up. * * Kern Sibbald, March MMVII */ #include "bat.h" #include "run.h" /* * Setup all the combo boxes and display the dialog */ runCmdPage::runCmdPage(int conn) : Pages() { m_name = tr("Restore Run"); pgInitialize(); setupUi(this); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png"))); m_conn = conn; m_console->notify(conn, false); fill(); m_console->discardToPrompt(m_conn); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); //dockPage(); setCurrent(); this->show(); } void runCmdPage::fill() { QString item, val; QStringList items; QRegExp rx("^.*:\\s*(\\S.*$)"); /* Regex to get value */ clientCombo->addItems(m_console->client_list); filesetCombo->addItems(m_console->fileset_list); replaceCombo->addItems(QStringList() << tr("never") << tr("always") << tr("ifnewer") << tr("ifolder")); replaceCombo->setCurrentIndex(replaceCombo->findText(tr("never"), Qt::MatchExactly)); storageCombo->addItems(m_console->storage_list); dateTimeEdit->setDisplayFormat(mainWin->m_dtformat); m_console->read(m_conn); item = m_console->msg(m_conn); items = item.split("\n"); foreach(item, items) { rx.indexIn(item); val = rx.cap(1); Dmsg1(100, "Item=%s\n", item.toUtf8().data()); Dmsg1(100, "Value=%s\n", val.toUtf8().data()); if (item.startsWith("Title:")) { run->setText(val); } if (item.startsWith("JobName:")) { jobCombo->addItem(val); continue; } if (item.startsWith("Bootstrap:")) { bootstrap->setText(val); continue; } if (item.startsWith("Backup Client:")) { clientCombo->setCurrentIndex(clientCombo->findText(val, Qt::MatchExactly)); continue; } if (item.startsWith("Storage:")) { storageCombo->setCurrentIndex(storageCombo->findText(val, Qt::MatchExactly)); continue; } if (item.startsWith("Where:")) { where->setText(val); continue; } if (item.startsWith("When:")) { dateTimeEdit->setDateTime(QDateTime::fromString(val,mainWin->m_dtformat)); continue; } if (item.startsWith("Catalog:")) { catalogCombo->addItem(val); continue; } if (item.startsWith("FileSet:")) { filesetCombo->setCurrentIndex(filesetCombo->findText(val, Qt::MatchExactly)); continue; } if (item.startsWith("Priority:")) { bool okay; int pri = val.toInt(&okay, 10); if (okay) prioritySpin->setValue(pri); continue; } if (item.startsWith("Replace:")) { int replaceIndex = replaceCombo->findText(val, Qt::MatchExactly); if (replaceIndex >= 0) replaceCombo->setCurrentIndex(replaceIndex); continue; } } } void runCmdPage::okButtonPushed() { QString cmd(".mod"); cmd += " restoreclient=\"" + clientCombo->currentText() + "\""; cmd += " fileset=\"" + filesetCombo->currentText() + "\""; cmd += " storage=\"" + storageCombo->currentText() + "\""; cmd += " replace=\"" + replaceCombo->currentText() + "\""; cmd += " when=\"" + dateTimeEdit->dateTime().toString(mainWin->m_dtformat) + "\""; cmd += " bootstrap=\"" + bootstrap->text() + "\""; cmd += " where=\"" + where->text() + "\""; QString pri; QTextStream(&pri) << " priority=\"" << prioritySpin->value() << "\""; cmd += pri; cmd += " yes\n"; setConsoleCurrent(); QString displayhtml(""); displayhtml += cmd + "\n"; m_console->display_html(displayhtml); m_console->display_text("\n"); m_console->write_dir(m_conn, cmd.toUtf8().data()); m_console->displayToPrompt(m_conn); // consoleCommand(cmd); ***FIXME set back to consoleCommand when connection issue is resolved m_console->notify(m_conn, true); closeStackPage(); } void runCmdPage::cancelButtonPushed() { m_console->displayToPrompt(m_conn); m_console->write_dir("."); m_console->displayToPrompt(m_conn); mainWin->set_status(tr(" Canceled")); this->hide(); m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } bareos-Release-14.2.6/src/qt-console/run/runcmd.ui000066400000000000000000000242171263011562700217540ustar00rootroot00000000000000 runCmdForm 0 0 704 466 Form 9 6 0 6 0 6 Priority: prioritySpin 10000 1 12 Qt::Vertical 20 171 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 0 6 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true When: dateTimeEdit Where: true where Bootstrap: bootstrap Job: jobCombo true 200 0 false Storage: storageCombo FileSet: filesetCombo true 200 0 false Replace: To client: clientCombo Catalog: catalogCombo 0 6 Qt::Horizontal 40 20 OK Cancel 0 6 Qt::Horizontal QSizePolicy::Fixed 131 25 16777215 30 <h3>Run Restore Job</h3> Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 131 25 bareos-Release-14.2.6/src/qt-console/run/runcopy.ui000066400000000000000000000242211263011562700221560ustar00rootroot00000000000000 runCopyForm 0 0 704 466 Form 9 6 0 6 0 6 Priority: prioritySpin 10000 1 12 Qt::Vertical 20 171 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 0 6 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true When: dateTimeEdit Where: true where Bootstrap: bootstrap Job: jobCombo true 200 0 false Storage: storageCombo FileSet: filesetCombo true 200 0 false Replace: To client: clientCombo Catalog: catalogCombo 0 6 Qt::Horizontal 40 20 OK Cancel 0 6 Qt::Horizontal QSizePolicy::Fixed 131 25 16777215 30 <h3>Run Restore Job</h3> Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 131 25 bareos-Release-14.2.6/src/qt-console/run/runmigration.ui000066400000000000000000000242331263011562700232000ustar00rootroot00000000000000 runMigrationForm 0 0 704 466 Form 9 6 0 6 0 6 Priority: prioritySpin 10000 1 12 Qt::Vertical 20 171 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 0 6 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true When: dateTimeEdit Where: true where Bootstrap: bootstrap Job: jobCombo true 200 0 false Storage: storageCombo FileSet: filesetCombo true 200 0 false Replace: To client: clientCombo Catalog: catalogCombo 0 6 Qt::Horizontal 40 20 OK Cancel 0 6 Qt::Horizontal QSizePolicy::Fixed 131 25 16777215 30 <h3>Run Restore Job</h3> Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 131 25 bareos-Release-14.2.6/src/qt-console/run/runrestore.ui000066400000000000000000000242271263011562700226750ustar00rootroot00000000000000 runRestoreForm 0 0 704 466 Form 9 6 0 6 0 6 Priority: prioritySpin 10000 1 12 Qt::Vertical 20 171 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 572 16 0 6 0 2 0 2000 1 1 yyyy-mm-dd hh:mm:ss true When: dateTimeEdit Where: true where Bootstrap: bootstrap Job: jobCombo true 200 0 false Storage: storageCombo FileSet: filesetCombo true 200 0 false Replace: To client: clientCombo Catalog: catalogCombo 0 6 Qt::Horizontal 40 20 OK Cancel 0 6 Qt::Horizontal QSizePolicy::Fixed 131 25 16777215 30 <h3>Run Restore Job</h3> Qt::AlignCenter Qt::Horizontal QSizePolicy::Fixed 131 25 bareos-Release-14.2.6/src/qt-console/select/000077500000000000000000000000001263011562700205725ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/select/select.cpp000066400000000000000000000061241263011562700225600ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Select dialog class * * Kern Sibbald, March MMVII */ #include "bat.h" #include "select.h" /* * Read the items for the selection */ selectDialog::selectDialog(Console *console, int conn) : QDialog() { m_conn = conn; QDateTime dt; int stat; QListWidgetItem *item; int row = 0; m_console = console; m_console->notify(m_conn, false); setupUi(this); connect(listBox, SIGNAL(currentRowChanged(int)), this, SLOT(index_change(int))); setAttribute(Qt::WA_DeleteOnClose); m_console->read(m_conn); /* get title */ labelWidget->setText(m_console->msg(m_conn)); while ((stat=m_console->read(m_conn)) > 0) { item = new QListWidgetItem; item->setText(m_console->msg(m_conn)); listBox->insertItem(row++, item); } m_console->displayToPrompt(m_conn); this->show(); } void selectDialog::accept() { char cmd[100]; this->hide(); bsnprintf(cmd, sizeof(cmd), "%d", m_index+1); m_console->write_dir(m_conn, cmd); m_console->displayToPrompt(m_conn); this->close(); mainWin->resetFocus(); m_console->displayToPrompt(m_conn); m_console->notify(m_conn, true); } void selectDialog::reject() { this->hide(); mainWin->set_status(tr(" Canceled")); this->close(); mainWin->resetFocus(); m_console->beginNewCommand(m_conn); m_console->notify(m_conn, true); } /* * Called here when the jobname combo box is changed. * We load the default values for the new job in the * other combo boxes. */ void selectDialog::index_change(int index) { m_index = index; } /* * Handle yesno PopUp when Bareos asks a yes/no question. */ /* * Read the items for the selection */ yesnoPopUp::yesnoPopUp(Console *console, int conn) : QDialog() { QMessageBox msgBox; setAttribute(Qt::WA_DeleteOnClose); console->read(conn); /* get yesno question */ msgBox.setWindowTitle(tr("Bat Question")); msgBox.setText(console->msg(conn)); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); console->displayToPrompt(conn); switch (msgBox.exec()) { case QMessageBox::Yes: console->write_dir(conn, "yes"); break; case QMessageBox::No: console->write_dir(conn, "no"); break; } console->displayToPrompt(conn); mainWin->resetFocus(); } bareos-Release-14.2.6/src/qt-console/select/select.h000066400000000000000000000025151263011562700222250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SELECT_H_ #define _SELECT_H_ #include #include "ui_select.h" #include class selectDialog : public QDialog, public Ui::selectForm { Q_OBJECT public: selectDialog(Console *console, int conn); public slots: void accept(); void reject(); void index_change(int index); private: Console *m_console; int m_index; int m_conn; }; class yesnoPopUp : public QDialog { Q_OBJECT public: yesnoPopUp(Console *console, int conn); }; #endif /* _SELECT_H_ */ bareos-Release-14.2.6/src/qt-console/select/select.ui000066400000000000000000000035501263011562700224130ustar00rootroot00000000000000 selectForm Qt::NonModal 0 0 377 323 Selection dialog 9 6 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok buttonBox accepted() selectForm accept() 248 254 157 274 buttonBox rejected() selectForm reject() 316 260 286 274 bareos-Release-14.2.6/src/qt-console/select/textinput.cpp000066400000000000000000000034751263011562700233530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Select dialog class * * Kern Sibbald, March MMVII */ #include "bat.h" #include "textinput.h" /* * Read input text box */ textInputDialog::textInputDialog(Console *console, int conn) { m_conn = conn; QDateTime dt; m_console = console; m_console->notify(m_conn, false); setupUi(this); setAttribute(Qt::WA_DeleteOnClose); m_console->read(m_conn); /* get title */ labelWidget->setText(m_console->msg(m_conn)); this->show(); } void textInputDialog::accept() { this->hide(); m_console->write_dir(m_conn, lineEdit->text().toUtf8().data()); /* Do not displayToPrompt because there may be another Text Input required */ this->close(); mainWin->resetFocus(); m_console->notify(m_conn, true); } void textInputDialog::reject() { this->hide(); mainWin->set_status(tr(" Canceled")); m_console->write_dir(m_conn, "."); this->close(); mainWin->resetFocus(); m_console->beginNewCommand(m_conn); m_console->notify(m_conn, true); } bareos-Release-14.2.6/src/qt-console/select/textinput.h000066400000000000000000000023101263011562700230030ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _TEXTENTRY_H_ #define _TEXTENTRY_H_ #include #include "ui_textinput.h" #include class textInputDialog : public QDialog, public Ui::textInputForm { Q_OBJECT public: textInputDialog(Console *console, int conn); public slots: void accept(); void reject(); private: Console *m_console; int m_conn; }; #endif /* _TEXTENTRY_H_ */ bareos-Release-14.2.6/src/qt-console/select/textinput.ui000066400000000000000000000070521263011562700232010ustar00rootroot00000000000000 textInputForm Qt::ApplicationModal 0 0 430 96 Qt::StrongFocus Text input dialog 0 0 50 0 100 16777215 Qt::TabFocus 0 0 Message 5 Qt::Horizontal QSizePolicy::Expanding 26 9 0 0 16777215 38 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() textInputForm accept() 248 254 157 274 buttonBox rejected() textInputForm reject() 316 260 286 274 bareos-Release-14.2.6/src/qt-console/status/000077500000000000000000000000001263011562700206365ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/status/clientstat.cpp000066400000000000000000000201151263011562700235130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "clientstat.h" /* This probably should be on a mutex */ static bool working = false; /* prevent timer recursion */ /* * Constructor for the class */ ClientStat::ClientStat(QString &client, QTreeWidgetItem *parentTreeWidgetItem) : Pages() { m_client = client; setupUi(this); pgInitialize(tr("Client Status %1").arg(m_client), parentTreeWidgetItem); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/status.png"))); m_cursor = new QTextCursor(textEditHeader->document()); readSettings(); dockPage(); m_timer = new QTimer(this); createConnections(); m_timer->start(1000); setCurrent(); } void ClientStat::getFont() { QFont font = textEditHeader->font(); QString dirname; m_console->getDirResName(dirname); QSettings settings(dirname, "bat"); settings.beginGroup("Console"); font.setFamily(settings.value("consoleFont", "Courier").value()); font.setPointSize(settings.value("consolePointSize", 10).toInt()); font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool()); settings.endGroup(); textEditHeader->setFont(font); } /* * Write the m_splitter settings in the destructor */ ClientStat::~ClientStat() { writeSettings(); } /* * Populate all tables and header widgets */ void ClientStat::populateAll() { populateTerminated(); populateCurrentTab(tabWidget->currentIndex()); } /* * Timer is triggered, see if is current and repopulate. */ void ClientStat::timerTriggered() { double value = timerDisplay->value(); value -= 1; if (value <= 0 && !working) { working = true; value = spinBox->value(); bool iscurrent = mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this); if (((isDocked() && iscurrent) || (!isDocked())) && (checkBox->checkState() == Qt::Checked)) { populateAll(); } working = false; } timerDisplay->display(value); } void ClientStat::populateCurrentTab(int index) { if (index == 0) populateRunning(); if (index == 1) populateHeader(); } /* * Populate header text widget */ void ClientStat::populateHeader() { QString command = QString(".status client=\"" + m_client + "\" header"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditHeader->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditHeader->insertPlainText(line); } } } /* * Populate teminated table */ void ClientStat::populateTerminated() { QString command = QString(".status client=\"" + m_client + "\" terminated"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; QBrush blackBrush(Qt::black); terminatedTable->clear(); QStringList headerlist = (QStringList() << tr("Job Id") << tr("Job Level") << tr("Job Files") << tr("Job Bytes") << tr("Job Status") << tr("Job Time") << tr("Job Name")); QStringList flaglist = (QStringList() << "R" << "L" << "R" << "R" << "LC" << "L" << "L"); terminatedTable->setColumnCount(headerlist.size()); terminatedTable->setHorizontalHeaderLabels(headerlist); if (m_console->dir_cmd(command, results)) { int row = 0; QTableWidgetItem* p_tableitem; terminatedTable->setRowCount(results.size()); foreach (QString line, results) { /* Iterate through the record returned from the query */ QStringList fieldlist = line.split("\t"); int column = 0; QString statusCode(""); /* Iterate through fields in the record */ foreach (QString field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ p_tableitem = new QTableWidgetItem(field, 1); p_tableitem->setForeground(blackBrush); p_tableitem->setFlags(0); if (flaglist[column].contains("R")) p_tableitem->setTextAlignment(Qt::AlignRight); if (flaglist[column].contains("C")) { if (field == "OK") p_tableitem->setBackground(Qt::green); else p_tableitem->setBackground(Qt::red); } terminatedTable->setItem(results.size() - row - 1, column, p_tableitem); column += 1; } row += 1; } } terminatedTable->resizeColumnsToContents(); terminatedTable->resizeRowsToContents(); terminatedTable->verticalHeader()->hide(); } /* * Populate running text */ void ClientStat::populateRunning() { QString command = QString(".status client=\"" + m_client + "\" running"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditRunning->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditRunning->insertPlainText(line); } } } /* * When the treeWidgetItem in the page selector tree is single clicked, Make sure * The tree has been populated. */ void ClientStat::PgSeltreeWidgetClicked() { if (!m_populated) { populateAll(); m_populated=true; } } /* * Virtual function override of pages function which is called when this page * is visible on the stack */ void ClientStat::currentStackItem() { populateAll(); timerDisplay->display(spinBox->value()); if (!m_populated) { m_populated=true; } } /* * Function to create connections for context sensitive menu for this and * the page selector */ void ClientStat::createConnections() { connect(actionRefresh, SIGNAL(triggered()), this, SLOT(populateAll())); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(populateCurrentTab(int))); connect(m_timer, SIGNAL(timeout()), this, SLOT(timerTriggered())); terminatedTable->setContextMenuPolicy(Qt::ActionsContextMenu); terminatedTable->addAction(actionRefresh); } /* * Save user settings associated with this page */ void ClientStat::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); settings.setValue(m_splitText, splitter->saveState()); settings.setValue("refreshInterval", spinBox->value()); settings.setValue("refreshCheck", checkBox->checkState()); settings.endGroup(); settings.beginGroup("OpenOnExit"); QString toWrite = "ClientStatus_" + m_client; settings.setValue(toWrite, 1); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void ClientStat::readSettings() { m_groupText = "ClientStatPage"; m_splitText = "splitterSizes_1"; QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); if (settings.contains(m_splitText)) { splitter->restoreState(settings.value(m_splitText).toByteArray()); } spinBox->setValue(settings.value("refreshInterval", 28).toInt()); checkBox->setCheckState((Qt::CheckState)settings.value("refreshCheck", Qt::Checked).toInt()); settings.endGroup(); timerDisplay->display(spinBox->value()); } bareos-Release-14.2.6/src/qt-console/status/clientstat.h000066400000000000000000000032031263011562700231570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _CLIENTSTAT_H_ #define _CLIENTSTAT_H_ #include #include "ui_clientstat.h" #include "pages.h" class ClientStat : public Pages, public Ui::ClientStatForm { Q_OBJECT public: ClientStat(QString&, QTreeWidgetItem*); ~ClientStat(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void populateHeader(); void populateTerminated(); void populateRunning(); void populateAll(); void populateCurrentTab(int); private slots: void timerTriggered(); private: void createConnections(); void writeSettings(); void readSettings(); bool m_populated; QTextCursor *m_cursor; void getFont(); QString m_groupText, m_splitText; QTimer *m_timer; QString m_client; }; #endif /* _CLIENTSTAT_H_ */ bareos-Release-14.2.6/src/qt-console/status/clientstat.ui000066400000000000000000000154201263011562700233510ustar00rootroot00000000000000 ClientStatForm 0 0 557 350 Form Qt::Vertical 0 Running Header 200 0 0 0 16777215 16777215 1 0 Qt::StrongFocus false Qt::ScrollBarAsNeeded QTextEdit::AutoNone false QTextEdit::NoWrap true 141 0 141 16777215 Refresh Timer 20 50 111 24 5 999 20 20 101 20 Do Refresh 20 80 101 31 Qt::LeftToRight <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> Qt::AlignCenter :/images/view-refresh.png Refresh :/images/utilities-terminal.png Cancel Running Job bareos-Release-14.2.6/src/qt-console/status/dirstat.cpp000066400000000000000000000272611263011562700230240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "dirstat.h" static bool working = false; /* prevent timer recursion */ /* * Constructor for the class */ DirStat::DirStat() : Pages() { setupUi(this); m_name = tr("Director Status"); pgInitialize(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/status.png"))); m_cursor = new QTextCursor(textEdit->document()); m_timer = new QTimer(this); readSettings(); m_timer->start(1000); createConnections(); setCurrent(); } void DirStat::getFont() { QFont font = textEdit->font(); QString dirname; m_console->getDirResName(dirname); QSettings settings(dirname, "bat"); settings.beginGroup("Console"); font.setFamily(settings.value("consoleFont", "Courier").value()); font.setPointSize(settings.value("consolePointSize", 10).toInt()); font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool()); settings.endGroup(); textEdit->setFont(font); } /* * Write the m_splitter settings in the destructor */ DirStat::~DirStat() { writeSettings(); } /* * Populate all tables and header widgets */ void DirStat::populateAll() { populateHeader(); populateTerminated(); populateScheduled(); populateRunning(); } /* * Timer is triggered, see if is current and repopulate. */ void DirStat::timerTriggered() { double value = timerDisplay->value(); value -= 1; if (value <= 0 && !working) { working = true; value = spinBox->value(); bool iscurrent = mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this); if (((isDocked() && iscurrent) || ((!isDocked()) && isOnceDocked())) && (checkBox->checkState() == Qt::Checked)) { populateAll(); } working = false; } timerDisplay->display(value); } /* * Populate header text widget */ void DirStat::populateHeader() { QString command = QString(".status dir header"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEdit->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEdit->insertPlainText(line); } } } /* * Populate teminated table */ void DirStat::populateTerminated() { QString command = QString(".status dir terminated"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; QBrush blackBrush(Qt::black); terminatedTable->clear(); QStringList headerlist = (QStringList() << tr("Job Id") << tr("Job Level") << tr("Job Files") << tr("Job Bytes") << tr("Job Status") << tr("Job Time") << tr("Job Name")); QStringList flaglist = (QStringList() << "R" << "L" << "R" << "R" << "LC" << "L" << "L"); terminatedTable->setColumnCount(headerlist.size()); terminatedTable->setHorizontalHeaderLabels(headerlist); if (m_console->dir_cmd(command, results)) { int row = 0; QTableWidgetItem* p_tableitem; terminatedTable->setRowCount(results.size()); foreach (QString line, results) { /* Iterate through the record returned from the query */ QStringList fieldlist = line.split("\t"); int column = 0; QString statusCode(""); /* Iterate through fields in the record */ foreach (QString field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ p_tableitem = new QTableWidgetItem(field, 1); p_tableitem->setForeground(blackBrush); p_tableitem->setFlags(0); if (flaglist[column].contains("R")) p_tableitem->setTextAlignment(Qt::AlignRight); if (flaglist[column].contains("C")) { if (field == "OK") p_tableitem->setBackground(Qt::green); else p_tableitem->setBackground(Qt::red); } terminatedTable->setItem(results.size() - row - 1, column, p_tableitem); column += 1; } row += 1; } } terminatedTable->resizeColumnsToContents(); terminatedTable->resizeRowsToContents(); terminatedTable->verticalHeader()->hide(); } /* * Populate scheduled table */ void DirStat::populateScheduled() { QString command = QString(".status dir scheduled"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; QBrush blackBrush(Qt::black); scheduledTable->clear(); QStringList headerlist = (QStringList() << tr("Job Level") << tr("Job Type") << tr("Priority") << tr("Job Time") << tr("Job Name") << tr("Volume")); QStringList flaglist = (QStringList() << "L" << "L" << "R" << "L" << "L" << "L"); scheduledTable->setColumnCount(headerlist.size()); scheduledTable->setHorizontalHeaderLabels(headerlist); scheduledTable->setSelectionBehavior(QAbstractItemView::SelectRows); scheduledTable->setSelectionMode(QAbstractItemView::SingleSelection); if (m_console->dir_cmd(command, results)) { int row = 0; QTableWidgetItem* p_tableitem; scheduledTable->setRowCount(results.size()); foreach (QString line, results) { /* Iterate through the record returned from the query */ QStringList fieldlist = line.split("\t"); int column = 0; QString statusCode(""); /* Iterate through fields in the record */ foreach (QString field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ p_tableitem = new QTableWidgetItem(field, 1); p_tableitem->setForeground(blackBrush); scheduledTable->setItem(row, column, p_tableitem); column += 1; } row += 1; } } scheduledTable->resizeColumnsToContents(); scheduledTable->resizeRowsToContents(); scheduledTable->verticalHeader()->hide(); } /* * Populate running table */ void DirStat::populateRunning() { QString command = QString(".status dir running"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; QBrush blackBrush(Qt::black); runningTable->clear(); QStringList headerlist = (QStringList() << tr("Job Id") << tr("Job Level") << tr("Job Data") << tr("Job Info")); runningTable->setColumnCount(headerlist.size()); runningTable->setHorizontalHeaderLabels(headerlist); runningTable->setSelectionBehavior(QAbstractItemView::SelectRows); if (m_console->dir_cmd(command, results)) { int row = 0; QTableWidgetItem* p_tableitem; runningTable->setRowCount(results.size()); foreach (QString line, results) { /* Iterate through the record returned from the query */ QStringList fieldlist = line.split("\t"); int column = 0; QString statusCode(""); /* Iterate through fields in the record */ foreach (QString field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ p_tableitem = new QTableWidgetItem(field, 1); p_tableitem->setForeground(blackBrush); runningTable->setItem(row, column, p_tableitem); column += 1; } row += 1; } } runningTable->resizeColumnsToContents(); runningTable->resizeRowsToContents(); runningTable->verticalHeader()->hide(); } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void DirStat::PgSeltreeWidgetClicked() { if (!m_populated) { populateAll(); m_populated=true; } if (!isOnceDocked()) { dockPage(); } } /* * Virtual function override of pages function which is called when this page * is visible on the stack */ void DirStat::currentStackItem() { populateAll(); timerDisplay->display(spinBox->value()); if (!m_populated) { m_populated=true; } } /* * Function to create connections for context sensitive menu for this and * the page selector */ void DirStat::createConnections() { connect(actionRefresh, SIGNAL(triggered()), this, SLOT(populateAll())); connect(actionCancelRunning, SIGNAL(triggered()), this, SLOT(consoleCancelJob())); connect(actionDisableScheduledJob, SIGNAL(triggered()), this, SLOT(consoleDisableJob())); connect(m_timer, SIGNAL(timeout()), this, SLOT(timerTriggered())); scheduledTable->setContextMenuPolicy(Qt::ActionsContextMenu); scheduledTable->addAction(actionRefresh); scheduledTable->addAction(actionDisableScheduledJob); terminatedTable->setContextMenuPolicy(Qt::ActionsContextMenu); terminatedTable->addAction(actionRefresh); runningTable->setContextMenuPolicy(Qt::ActionsContextMenu); runningTable->addAction(actionRefresh); runningTable->addAction(actionCancelRunning); } /* * Save user settings associated with this page */ void DirStat::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); settings.setValue(m_splitText, splitter->saveState()); settings.setValue("refreshInterval", spinBox->value()); settings.setValue("refreshCheck", checkBox->checkState()); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void DirStat::readSettings() { m_groupText = "DirStatPage"; m_splitText = "splitterSizes_0"; QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); if (settings.contains(m_splitText)) { splitter->restoreState(settings.value(m_splitText).toByteArray()); } spinBox->setValue(settings.value("refreshInterval", 28).toInt()); checkBox->setCheckState((Qt::CheckState)settings.value("refreshCheck", Qt::Checked).toInt()); settings.endGroup(); timerDisplay->display(spinBox->value()); } /* * Cancel a running job */ void DirStat::consoleCancelJob() { QList rowList; QList sitems = runningTable->selectedItems(); foreach (QTableWidgetItem *sitem, sitems) { int row = sitem->row(); if (!rowList.contains(row)) { rowList.append(row); } } QStringList selectedJobsList; foreach(int row, rowList) { QTableWidgetItem * sitem = runningTable->item(row, 0); selectedJobsList.append(sitem->text()); } foreach( QString job, selectedJobsList ) { QString cmd("cancel jobid="); cmd += job; consoleCommand(cmd); } } /* * Disable a scheduled Job */ void DirStat::consoleDisableJob() { int currentrow = scheduledTable->currentRow(); QTableWidgetItem *item = scheduledTable->item(currentrow, 4); if (item) { QString text = item->text(); QString cmd("disable job=\""); cmd += text + '"'; consoleCommand(cmd); } } bareos-Release-14.2.6/src/qt-console/status/dirstat.h000066400000000000000000000031611263011562700224620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _DIRSTAT_H_ #define _DIRSTAT_H_ #include #include "ui_dirstat.h" #include class DirStat : public Pages, public Ui::DirStatForm { Q_OBJECT public: DirStat(); ~DirStat(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void populateHeader(); void populateTerminated(); void populateScheduled(); void populateRunning(); void populateAll(); private slots: void timerTriggered(); void consoleCancelJob(); void consoleDisableJob(); private: void createConnections(); void writeSettings(); void readSettings(); bool m_populated; QTextCursor *m_cursor; void getFont(); QString m_groupText, m_splitText; QTimer *m_timer; }; #endif /* _DIRSTAT_H_ */ bareos-Release-14.2.6/src/qt-console/status/dirstat.ui000066400000000000000000000227661263011562700226640ustar00rootroot00000000000000 DirStatForm 0 0 514 425 Form Qt::Vertical 0 0 0 0 16777215 100 1 0 Qt::StrongFocus false Qt::ScrollBarAsNeeded QTextEdit::AutoNone false QTextEdit::NoWrap true 0 0 221 100 221 100 Refresh Timer 20 60 111 24 5 999 20 20 101 20 Do Refresh 110 20 101 31 6 0 0 0 0 Qt::LeftToRight <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Scheduled Jobs</span></p></body></html> Qt::AlignCenter 6 0 0 0 0 Qt::LeftToRight <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Running Jobs</span></p></body></html> Qt::AlignCenter 6 0 0 0 0 Qt::LeftToRight <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> Qt::AlignCenter :/images/view-refresh.png Refresh :/images/utilities-terminal.png Cancel Selected Running Jobs :/images/utilities-terminal.png Disable Scheduled Job bareos-Release-14.2.6/src/qt-console/status/storstat.cpp000066400000000000000000000306451263011562700232350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "storstat.h" #include "mount/mount.h" #include "label/label.h" static bool working = false; /* prevent timer recursion */ /* .status storage= where is the storage name in the Director, and is one of the following: header running terminated waitreservation devices volumes spooling */ /* * Constructor for the class */ StorStat::StorStat(QString &storage, QTreeWidgetItem *parentTreeWidgetItem) : Pages() { m_storage = storage; setupUi(this); pgInitialize(tr("Storage Status %1").arg(m_storage), parentTreeWidgetItem); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/status.png"))); m_cursor = new QTextCursor(textEditHeader->document()); m_timer = new QTimer(this); readSettings(); createConnections(); m_timer->start(1000); setCurrent(); dockPage(); } void StorStat::getFont() { QFont font = textEditHeader->font(); QString dirname; m_console->getDirResName(dirname); QSettings settings(dirname, "bat"); settings.beginGroup("Console"); font.setFamily(settings.value("consoleFont", "Courier").value()); font.setPointSize(settings.value("consolePointSize", 10).toInt()); font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool()); settings.endGroup(); textEditHeader->setFont(font); } /* * Write the m_splitter settings in the destructor */ StorStat::~StorStat() { writeSettings(); } /* * Populate all tables and header widgets */ void StorStat::populateAll() { populateTerminated(); populateCurrentTab(tabWidget->currentIndex()); } /* * Timer is triggered, see if is current and repopulate. */ void StorStat::timerTriggered() { double value = timerDisplay->value(); value -= 1; if (value <= 0 && !working) { working = true; value = spinBox->value(); bool iscurrent = mainWin->tabWidget->currentIndex() == mainWin->tabWidget->indexOf(this); if (((isDocked() && iscurrent) || (!isDocked())) && (checkBox->checkState() == Qt::Checked)) { populateAll(); } working = false; } timerDisplay->display(value); } /* * Populate header text widget */ void StorStat::populateHeader() { QString command = QString(".status storage=\"" + m_storage + "\" header"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditHeader->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditHeader->insertPlainText(line); } } } void StorStat::populateWaitReservation() { QString command = QString(".status storage=\"" + m_storage + "\" waitreservation"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditWaitReservation->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditWaitReservation->insertPlainText(line); } } } void StorStat::populateDevices() { QString command = QString(".status storage=\"" + m_storage + "\" devices"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditDevices->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditDevices->insertPlainText(line); } } } void StorStat::populateVolumes() { QString command = QString(".status storage=\"" + m_storage + "\" volumes"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditVolumes->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditVolumes->insertPlainText(line); } } } void StorStat::populateSpooling() { QString command = QString(".status storage=\"" + m_storage + "\" spooling"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditSpooling->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditSpooling->insertPlainText(line); } } } void StorStat::populateRunning() { QString command = QString(".status storage=\"" + m_storage + "\" running"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; textEditRunning->clear(); if (m_console->dir_cmd(command, results)) { foreach (QString line, results) { line += "\n"; textEditRunning->insertPlainText(line); } } } /* * Populate teminated table */ void StorStat::populateTerminated() { QString command = QString(".status storage=\"" + m_storage + "\" terminated"); if (mainWin->m_commandDebug) Pmsg1(000, "sending command : %s\n",command.toUtf8().data()); QStringList results; QBrush blackBrush(Qt::black); terminatedTable->clear(); QStringList headerlist = (QStringList() << tr("Job Id") << tr("Job Level") << tr("Job Files") << tr("Job Bytes") << tr("Job Status") << tr("Job Time") << tr("Job Name")); QStringList flaglist = (QStringList() << "R" << "L" << "R" << "R" << "LC" << "L" << "L"); terminatedTable->setColumnCount(headerlist.size()); terminatedTable->setHorizontalHeaderLabels(headerlist); if (m_console->dir_cmd(command, results)) { int row = 0; QTableWidgetItem* p_tableitem; terminatedTable->setRowCount(results.size()); foreach (QString line, results) { /* Iterate through the record returned from the query */ QStringList fieldlist = line.split("\t"); int column = 0; QString statusCode(""); /* Iterate through fields in the record */ foreach (QString field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ p_tableitem = new QTableWidgetItem(field, 1); p_tableitem->setForeground(blackBrush); p_tableitem->setFlags(0); if (flaglist[column].contains("R")) p_tableitem->setTextAlignment(Qt::AlignRight); if (flaglist[column].contains("C")) { if (field == "OK") p_tableitem->setBackground(Qt::green); else p_tableitem->setBackground(Qt::red); } terminatedTable->setItem(row, column, p_tableitem); column += 1; } row += 1; } } terminatedTable->resizeColumnsToContents(); terminatedTable->resizeRowsToContents(); terminatedTable->verticalHeader()->hide(); } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void StorStat::PgSeltreeWidgetClicked() { if (!m_populated) { populateAll(); m_populated=true; } } /* * Virtual function override of pages function which is called when this page * is visible on the stack */ void StorStat::currentStackItem() { populateAll(); timerDisplay->display(spinBox->value()); if (!m_populated) { m_populated=true; } } /* * Function to create connections for context sensitive menu for this and * the page selector */ void StorStat::createConnections() { connect(actionRefresh, SIGNAL(triggered()), this, SLOT(populateAll())); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(populateCurrentTab(int))); connect(mountButton, SIGNAL(pressed()), this, SLOT(mountButtonPushed())); connect(umountButton, SIGNAL(pressed()), this, SLOT(umountButtonPushed())); connect(labelButton, SIGNAL(pressed()), this, SLOT(labelButtonPushed())); connect(releaseButton, SIGNAL(pressed()), this, SLOT(releaseButtonPushed())); terminatedTable->setContextMenuPolicy(Qt::ActionsContextMenu); terminatedTable->addAction(actionRefresh); connect(m_timer, SIGNAL(timeout()), this, SLOT(timerTriggered())); } /* * Save user settings associated with this page */ void StorStat::writeSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); settings.setValue(m_splitText, splitter->saveState()); settings.setValue("refreshInterval", spinBox->value()); settings.setValue("refreshCheck", checkBox->checkState()); settings.endGroup(); settings.beginGroup("OpenOnExit"); QString toWrite = "StorageStatus_" + m_storage; settings.setValue(toWrite, 1); settings.endGroup(); } /* * Read and restore user settings associated with this page */ void StorStat::readSettings() { m_groupText = "StorStatPage"; m_splitText = "splitterSizes_0"; QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup(m_groupText); if (settings.contains(m_splitText)) { splitter->restoreState(settings.value(m_splitText).toByteArray()); } spinBox->setValue(settings.value("refreshInterval", 28).toInt()); checkBox->setCheckState((Qt::CheckState)settings.value("refreshCheck", Qt::Checked).toInt()); settings.endGroup(); timerDisplay->display(spinBox->value()); } /* * Populate the text edit window in the current tab */ void StorStat::populateCurrentTab(int index) { if (index == 0) populateHeader(); if (index == 1) populateWaitReservation(); if (index == 2) populateDevices(); if (index == 3) populateVolumes(); if (index == 4) populateSpooling(); if (index == 5) populateRunning(); } /* * execute mount in console */ void StorStat::mountButtonPushed() { int haschanger = 3; /* Set up query QString and header QStringList */ QString query("SELECT AutoChanger AS Changer" " FROM Storage WHERE Name='" + m_storage + "'" " ORDER BY Name" ); QStringList results; /* This could be a log item */ if (mainWin->m_sqlDebug) { Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data()); } if (m_console->sql_cmd(query, results)) { int resultCount = results.count(); if (resultCount == 1){ QString resultline; QString field; QStringList fieldlist; /* there will only be one of these */ foreach (resultline, results) { fieldlist = resultline.split("\t"); int index = 0; /* Iterate through fields in the record */ foreach (field, fieldlist) { field = field.trimmed(); /* strip leading & trailing spaces */ haschanger = field.toInt(); index++; } } } } Pmsg1(000, "haschanger is : %i\n", haschanger); if (haschanger == 0){ /* no autochanger, just execute the command in the console */ QString cmd("mount storage=" + m_storage); consoleCommand(cmd); } else if (haschanger != 3) { setConsoleCurrent(); /* if this storage is an autochanger, lets ask for the slot */ new mountDialog(m_console, m_storage); } } /* * execute umount in console */ void StorStat::umountButtonPushed() { QString cmd("umount storage=" + m_storage); consoleCommand(cmd); } /* Release a tape in the drive */ void StorStat::releaseButtonPushed() { QString cmd("release storage="); cmd += m_storage; consoleCommand(cmd); } /* Label Media populating current storage by default */ void StorStat::labelButtonPushed() { new labelPage(m_storage); } bareos-Release-14.2.6/src/qt-console/status/storstat.h000066400000000000000000000035551263011562700227020ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _STORSTAT_H_ #define _STORSTAT_H_ #include #include "ui_storstat.h" #include "pages.h" class StorStat : public Pages, public Ui::StorStatForm { Q_OBJECT public: StorStat(QString &, QTreeWidgetItem *); ~StorStat(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void populateHeader(); void populateTerminated(); void populateRunning(); void populateWaitReservation(); void populateDevices(); void populateVolumes(); void populateSpooling(); void populateAll(); private slots: void timerTriggered(); void populateCurrentTab(int); void mountButtonPushed(); void umountButtonPushed(); void releaseButtonPushed(); void labelButtonPushed(); private: void createConnections(); void writeSettings(); void readSettings(); bool m_populated; QTextCursor *m_cursor; void getFont(); QString m_groupText; QString m_splitText; QTimer *m_timer; QString m_storage; }; #endif /* _STORSTAT_H_ */ bareos-Release-14.2.6/src/qt-console/status/storstat.ui000066400000000000000000000174651263011562700230750ustar00rootroot00000000000000 StorStatForm 0 0 694 393 Form Qt::Vertical 6 Header Waitreservation Devices Volumes Spooling Running Misc 10 10 168 60 Mount UMount Label Release 141 0 141 16777215 Refresh Timer 20 50 111 24 5 999 20 20 101 20 Do Refresh 20 80 101 31 Qt::LeftToRight <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> Qt::AlignCenter :/images/view-refresh.png Refresh :/images/utilities-terminal.png Cancel Running Job :/images/utilities-terminal.png Disable Scheduled Job bareos-Release-14.2.6/src/qt-console/storage/000077500000000000000000000000001263011562700207575ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/storage/content.cpp000066400000000000000000000571041263011562700231440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bat.h" #include #include #include "content.h" #include "label/label.h" #include "mediainfo/mediainfo.h" #include "mount/mount.h" #include "util/fmtwidgetitem.h" #include "status/storstat.h" /* * Create a new content subpage. */ Content::Content(QString storage, QTreeWidgetItem *parentWidget) : Pages() { setupUi(this); pgInitialize(storage, parentWidget); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/package-x-generic.png"))); m_populated = false; m_needs_repopulate = false; m_firstpopulation = true; m_checkcurwidget = true; m_currentStorage = storage; connect(pbUpdate, SIGNAL(clicked()), this, SLOT(consoleUpdateSlots())); connect(pbLabel, SIGNAL(clicked()), this, SLOT(consoleLabelStorage())); connect(pbMount, SIGNAL(clicked()), this, SLOT(consoleMountStorage())); connect(pbUnmount, SIGNAL(clicked()), this, SLOT(consoleUnMountStorage())); connect(pbImport, SIGNAL(clicked()), this, SLOT(consoleImportStorage())); connect(pbExport, SIGNAL(clicked()), this, SLOT(consoleExportStorage())); connect(pbMoveUp, SIGNAL(clicked()), this, SLOT(consoleMoveUpStorage())); connect(pbMoveDown, SIGNAL(clicked()), this, SLOT(consoleMoveDownStorage())); connect(pbStatus, SIGNAL(clicked()), this, SLOT(statusStorageWindow())); connect(pbRelease, SIGNAL(clicked()), this, SLOT(consoleRelease())); connect(tableContent, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(showMediaInfo(QTableWidgetItem *))); dockPage(); setCurrent(); } /* * Subroutine to call class to show the log in the database from that job */ void Content::showMediaInfo(QTableWidgetItem * item) { QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this); int row = item->row(); QString vol = tableContent->item(row, 1)->text(); if (vol != "") { new MediaInfo(pageSelectorTreeWidgetItem, vol); } } static int table_get_selection(QTableWidget *table, QString &sel) { int i, size, cnt; int start_range = -1, end_range = -1; bool *sel_rows; QTableWidgetItem *item; /* * When there are now rows in this table there is also nothing selected. */ size = table->rowCount(); if (size == 0) { return 0; } /* * The QT selection returns each cell, so you * have x times the same row number... * We take only one instance */ sel_rows = (bool *)malloc(size * sizeof(bool)); memset(sel_rows, 0, size * sizeof(bool)); /* * Fill an internal array with per slot a marker if its selected or not. */ foreach (item, table->selectedItems()) { sel_rows[item->row()] = true; } /* * A selection starts with a = and then the slot selection. */ sel += "="; /* * Try to be smart if we can use ranges */ cnt = 0; for (i = 0; i < size; i++) { if (sel_rows[i]) { /* * Keep track of the number of elements selected. */ cnt++; /* * If no range is started, mark this as the start of * a new one and continue with the next item. */ if (start_range == -1) { start_range = i; end_range = i; continue; } else { /* * See if this is the next item in the range. */ if (i == end_range + 1) { end_range = i; continue; } else { /* * Not the next in a range flush the previous range if any * or when just a single slot also flush it. * * See if this is a proper range. */ if (start_range != -1 && start_range != end_range) { sel += table->item(start_range, 0)->text() + "-" + table->item(end_range, 0)->text(); sel += ","; start_range = i; end_range = i; continue; } else { /* * Only a single slot was selected not a range. */ sel += table->item(start_range, 0)->text(); sel += ","; start_range = i; end_range = i; continue; } } } } else { /* * Slot is not selected so the range (if started ends here) * * See if this is a proper range. */ if (start_range != -1 && start_range != end_range) { sel += table->item(start_range, 0)->text() + "-" + table->item(end_range, 0)->text(); sel += ","; start_range = -1; end_range = -1; } else if (start_range != -1) { /* * Only a single slot was selected not a range. */ sel += table->item(start_range, 0)->text(); sel += ","; start_range = -1; end_range = -1; } } } /* * See if there are any unflushed ranges. e.g. when we run out of slots * but the range is not flushed to the cmdline. * * See if this is a proper range. */ if (start_range != -1 && start_range != end_range) { sel += table->item(start_range, 0)->text() + "-" + table->item(end_range, 0)->text(); sel += ","; } else if (start_range != -1) { /* * Only a single slot was selected not a range. */ sel += table->item(start_range, 0)->text(); sel += ","; } /* * remove trailing , or useless = */ sel.chop(1); free(sel_rows); return cnt; } /* * Label Media populating current storage by default */ void Content::consoleLabelStorage() { int drive_cnt, sel_cnt; QString sel, drive_sel, cmd; sel_cnt = table_get_selection(tableContent, sel); if (sel_cnt == 0) { new labelPage(m_currentStorage); } else { /* * See if there is more then 1 drive in this changer. * If there is the user should select which drive to * use for the label by selecting that drive in the * drives pane. */ if (tableDrive->rowCount() > 1) { drive_cnt = table_get_selection(tableDrive, drive_sel); switch (drive_cnt) { case 0: QMessageBox::warning(this, tr("Drive Selection"), tr("Please select drive in drive pane"), QMessageBox::Ok, QMessageBox::Ok); return; case 1: cmd = QString("label barcodes slots%1 storage=\"%2\" drive%3") .arg(sel) .arg(m_currentStorage) .arg(drive_sel); break; default: QMessageBox::warning(this, tr("Drive Selection"), tr("Please select only one drive in drive pane"), QMessageBox::Ok, QMessageBox::Ok); return; } } else { cmd = QString("label barcodes slots%1 storage=\"%2\"") .arg(sel) .arg(m_currentStorage); } } consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Mount currently selected storage */ void Content::consoleMountStorage() { int drive_cnt, sel_cnt; QString sel, drive_sel, cmd; /* * See if there is more then 1 drive in this changer. * If there is the user should select which drive to * use for the mount by selecting that drive in the * drives pane. If she/he does not we fall back to * the normal behaviour of showing the mountDialog. */ if (tableDrive->rowCount() > 1) { drive_cnt = table_get_selection(tableDrive, drive_sel); switch (drive_cnt) { case 0: case 1: /* * See if One slot is selected in the content table. */ sel_cnt = table_get_selection(tableContent, sel); if (sel_cnt == 1) { switch (drive_cnt) { case 0: cmd = QString("mount storage=\"%1\" slot%2 drive=0") .arg(m_currentStorage) .arg(sel); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; return; case 1: cmd = QString("mount storage=\"%1\" slot%2 drive%3") .arg(m_currentStorage) .arg(sel) .arg(drive_sel); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; return; default: break; } } break; default: break; } } /* * Fallback to old interactive mount dialog. */ setConsoleCurrent(); /* * If this storage is an autochanger, lets ask for the slot */ new mountDialog(m_console, m_currentStorage); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Unmount Currently selected storage */ void Content::consoleUnMountStorage() { int drive_cnt; QString drive_sel, cmd; /* * See if there is more then 1 drive in this changer. * If there is the user should select which drive to * use for the unmount by selecting that drive in the * drives pane. */ if (tableDrive->rowCount() > 1) { drive_cnt = table_get_selection(tableDrive, drive_sel); switch (drive_cnt) { case 0: QMessageBox::warning(this, tr("Drive Selection"), tr("Please select drive in drive pane"), QMessageBox::Ok, QMessageBox::Ok); return; case 1: cmd = QString("umount storage=\"%1\" drive%2") .arg(m_currentStorage) .arg(drive_sel); break; default: QMessageBox::warning(this, tr("Drive Selection"), tr("Please select only one drive in drive pane"), QMessageBox::Ok, QMessageBox::Ok); return; } } else { cmd = QString("umount storage=\"%1\"") .arg(m_currentStorage); } consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Import currently selected slots */ void Content::consoleImportStorage() { int src_cnt, dst_cnt; QString srcslots, dstslots, cmd; cmd = QString("import storage=\"%1\"") .arg(m_currentStorage); src_cnt = table_get_selection(tableTray, srcslots); if (src_cnt > 0) { cmd += " srcslots" + srcslots; } dst_cnt = table_get_selection(tableContent, dstslots); if (dst_cnt > 0) { cmd += " dstslots" + dstslots; } Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data()); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Export slots currently selected slots */ void Content::consoleExportStorage() { int src_cnt, dst_cnt; QString srcslots, dstslots, cmd; cmd = QString("export storage=\"%1\"") .arg(m_currentStorage); src_cnt = table_get_selection(tableContent, srcslots); if (src_cnt > 0) { cmd += " srcslots" + srcslots; } dst_cnt = table_get_selection(tableTray, dstslots); if (dst_cnt > 0) { cmd += " dstslots" + dstslots; } Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data()); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Move currently selected slots for this we need * exactly two slot ranges. */ void Content::consoleMoveUpStorage() { int sel_cnt; QString srcslots, dstslots, selslots, cmd; cmd = QString("move storage=\"%1\"") .arg(m_currentStorage); /* * For a move operation no import/export slots may be selected. */ sel_cnt = table_get_selection(tableTray, selslots); if (sel_cnt > 0) { QMessageBox::warning(this, tr("Slot Selection"), tr("Please deselect any import/export slots which are invalid for a move operation"), QMessageBox::Ok, QMessageBox::Ok); return; } /* * See what slots are selected and try to split it into exactly two ranges. */ sel_cnt = table_get_selection(tableContent, selslots); if (sel_cnt > 0) { QStringList fieldlist; fieldlist = selslots.split(","); /* * There are not 2 ranges selected this ain't gonna work for a move operation. */ if (fieldlist.size() != 2) { QMessageBox::warning(this, tr("Slot Selection"), tr("Please select two slot ranges for the move operation"), QMessageBox::Ok, QMessageBox::Ok); return; } QStringListIterator fld(fieldlist); dstslots = fld.next(); srcslots = fld.next(); cmd += " srcslots=" + srcslots; cmd += " dstslots" + dstslots; } else { /* * Nothing selected this ain't gonna work for a move operation. */ QMessageBox::warning(this, tr("Slot Selection"), tr("Please select two slot ranges for the move operation"), QMessageBox::Ok, QMessageBox::Ok); return; } Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data()); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } void Content::consoleMoveDownStorage() { int sel_cnt; QString srcslots, dstslots, selslots, cmd; cmd = QString("move storage=\"%1\"") .arg(m_currentStorage); /* * For a move operation no import/export slots may be selected. */ sel_cnt = table_get_selection(tableTray, selslots); if (sel_cnt > 0) { QMessageBox::warning(this, tr("Slot Selection"), tr("Please deselect any import/export slots which are invalid for a move operation"), QMessageBox::Ok, QMessageBox::Ok); return; } /* * See what slots are selected and try to split it into exactly two ranges. */ sel_cnt = table_get_selection(tableContent, selslots); if (sel_cnt > 0) { QStringList fieldlist; fieldlist = selslots.split(","); /* * There are not 2 ranges selected this ain't gonna work for a move operation. */ if (fieldlist.size() != 2) { QMessageBox::warning(this, tr("Slot Selection"), tr("Please select two slot ranges for the move operation"), QMessageBox::Ok, QMessageBox::Ok); return; } QStringListIterator fld(fieldlist); srcslots = fld.next(); dstslots = fld.next(); cmd += " srcslots" + srcslots; cmd += " dstslots=" + dstslots; } else { /* * Nothing selected this ain't gonna work for a move operation. */ QMessageBox::warning(this, tr("Slot Selection"), tr("Please select two slot ranges for the move operation"), QMessageBox::Ok, QMessageBox::Ok); return; } Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data()); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Status Slots */ void Content::statusStorageWindow() { /* * If one exists, then just set it current */ bool found = false; foreach(Pages *page, mainWin->m_pagehash) { if (mainWin->currentConsole() == page->console()) { if (page->name() == tr("Storage Status %1").arg(m_currentStorage)) { found = true; page->setCurrent(); } } } if (!found) { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); new StorStat(m_currentStorage, parentItem); } } /* * Update Slots */ void Content::consoleUpdateSlots() { int sel_cnt; QString sel, cmd; sel_cnt = table_get_selection(tableContent, sel); if (sel_cnt > 0) { cmd = QString("update slots%1 storage=\"%2\"") .arg(sel) .arg(m_currentStorage); } else { cmd = QString("update slots storage=\"%1\"") .arg(m_currentStorage); } Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data()); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * Release a tape in the drive */ void Content::consoleRelease() { int drive_cnt; QString drive_sel, cmd; /* * See if there is more then 1 drive in this changer. * If there is the user should select which drive to * use for the release by selecting that drive in the * drives pane. */ if (tableDrive->rowCount() > 1) { drive_cnt = table_get_selection(tableDrive, drive_sel); switch (drive_cnt) { case 0: QMessageBox::warning(this, tr("Drive Selection"), tr("Please select drive in drive pane"), QMessageBox::Ok, QMessageBox::Ok); return; case 1: cmd = QString("release storage=\"%1\" drive%2") .arg(m_currentStorage) .arg(drive_sel); break; default: QMessageBox::warning(this, tr("Drive Selection"), tr("Please select only one drive in drive pane"), QMessageBox::Ok, QMessageBox::Ok); return; } } else { cmd = QString("release storage=\"%1\"") .arg(m_currentStorage); } consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* * The main meat of the class!! The function that querries the director and * creates the widgets with appropriate values. */ void Content::populateContent() { char buf[30]; time_t tim; QStringList results_all; QString cmd; cmd = QString("status slots storage=\"%1\"") .arg(m_currentStorage); m_console->dir_cmd(cmd, results_all); Freeze frz(*tableContent); /* disable updating */ Freeze frz2(*tableTray); Freeze frz3(*tableDrive); /* * Populate Content pane. */ tableContent->clearContents(); QStringList results = results_all.filter(QRegExp("^S\\|[0-9]+\\|")); tableContent->setRowCount(results.size()); QString resultline; QStringList fieldlist; int row = 0; foreach (resultline, results) { fieldlist = resultline.split("|"); if (fieldlist.size() < 10) { Pmsg1(0, "Discarding %s\n", resultline.data()); continue; /* some fields missing, ignore row */ } int index = 0; QStringListIterator fld(fieldlist); TableItemFormatter slotitem(*tableContent, row); /* Slot type. */ fld.next(); /* Slot */ slotitem.setNumericFld(index++, fld.next()); /* Filled Slot */ if (fld.next() != "") { /* Volume */ slotitem.setTextFld(index++, fld.next()); /* Bytes */ slotitem.setBytesFld(index++, fld.next()); /* Status */ slotitem.setVolStatusFld(index++, fld.next()); /* MediaType */ slotitem.setTextFld(index++, fld.next()); /* Pool */ slotitem.setTextFld(index++, fld.next()); tim = fld.next().toInt(); if (tim > 0) { /* LastW */ bstrutime(buf, sizeof(buf), tim); slotitem.setTextFld(index++, QString(buf)); /* Expire */ tim = fld.next().toInt(); bstrutime(buf, sizeof(buf), tim); slotitem.setTextFld(index++, QString(buf)); } } row++; } tableContent->verticalHeader()->hide(); tableContent->sortByColumn(0, Qt::AscendingOrder); tableContent->setSortingEnabled(true); tableContent->resizeColumnsToContents(); tableContent->resizeRowsToContents(); tableContent->setEditTriggers(QAbstractItemView::NoEditTriggers); /* * Populate Input/Ouput pane. */ tableTray->clearContents(); QStringList io_results = results_all.filter(QRegExp("^I\\|[0-9]+\\|")); tableTray->setRowCount(io_results.size()); int row_io = 0; foreach (resultline, io_results) { fieldlist = resultline.split("|"); if (fieldlist.size() < 10) { Pmsg1(0, "Discarding %s\n", resultline.data()); continue; /* some fields missing, ignore row */ } QStringListIterator fld(fieldlist); /* Slot type. */ fld.next(); TableItemFormatter ioitem(*tableTray, row_io++); ioitem.setNumericFld(0, fieldlist[1]); ioitem.setTextFld(1, fieldlist[3]); } tableTray->verticalHeader()->hide(); tableTray->setEditTriggers(QAbstractItemView::NoEditTriggers); /* * Populate Drive pane. */ tableDrive->verticalHeader()->hide(); tableDrive->clearContents(); QStringList drives = results_all.filter(QRegExp("^D\\|[0-9]+\\|")); tableDrive->setRowCount(drives.size()); int row_drive = 0; foreach (resultline, drives) { fieldlist = resultline.split("|"); if (fieldlist.size() < 4) continue; /* some fields missing, ignore row */ int index = 0; QStringListIterator fld(fieldlist); TableItemFormatter slotitem(*tableDrive, row_drive); /* Drive type */ fld.next(); /* Number */ slotitem.setNumericFld(index++, fld.next()); /* Slot */ fld.next(); /* Volume */ slotitem.setTextFld(index++, fld.next()); row_drive++; } tableDrive->resizeRowsToContents(); tableDrive->setEditTriggers(QAbstractItemView::NoEditTriggers); m_populated = true; } /* * Virtual function which is called when this page is visible on the stack */ void Content::currentStackItem() { if (!m_populated || m_needs_repopulate) { populateContent(); } } void Content::treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *) { } bareos-Release-14.2.6/src/qt-console/storage/content.h000066400000000000000000000034601263011562700226050ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _CONTENT_H_ #define _CONTENT_H_ #include #include "ui_content.h" #include "pages.h" class Content : public Pages, public Ui::ContentForm { Q_OBJECT public: Content(QString storage, QTreeWidgetItem *parentWidget); // virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); void consoleRelease(); void consoleUpdateSlots(); void consoleLabelStorage(); void consoleMountStorage(); void statusStorageWindow(); void consoleUnMountStorage(); void consoleImportStorage(); void consoleExportStorage(); void consoleMoveUpStorage(); void consoleMoveDownStorage(); void showMediaInfo(QTableWidgetItem * item); private slots: void populateContent(); private: bool m_currentAutoChanger; bool m_populated; bool m_needs_repopulate; bool m_firstpopulation; bool m_checkcurwidget; QString m_currentStorage; }; #endif /* _STORAGE_H_ */ bareos-Release-14.2.6/src/qt-console/storage/content.ui000066400000000000000000000225461263011562700230010ustar00rootroot00000000000000 ContentForm 0 0 949 695 Form 0 0 240 110 Actions Update slots :/images/view-refresh.png Label :/images/label.png Export :/images/extern.png Import :/images/intern.png Move Up :/images/go-up.png Move Down :/images/go-down.png Mount :/images/cartridge.png Unmount :/images/cartridge.png Status :/images/status-console.png Release :/images/cartridge.png 0 0 241 221 241 16777215 Drives 0 0 220 192 QAbstractItemView::SelectRows Drive Volume 0 0 240 16777215 Import/Export 0 0 100 0 QAbstractItemView::SelectRows false Slot Volume Content true QAbstractItemView::ExtendedSelection QAbstractItemView::SelectRows 0 Slot Volume Bytes Status Media Type Pool Last Written When expire? bareos-Release-14.2.6/src/qt-console/storage/storage.cpp000066400000000000000000000406731263011562700231410ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Storage Class * * Dirk Bartley, March 2007 */ #include "bat.h" #include #include #include "storage.h" #include "content.h" #include "label/label.h" #include "mount/mount.h" #include "status/storstat.h" #include "util/fmtwidgetitem.h" Storage::Storage() : Pages() { setupUi(this); pgInitialize(tr("Storage")); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/package-x-generic.png"))); /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_storage.h */ m_populated = false; m_needs_repopulate = false; m_firstpopulation = true; m_checkcurwidget = true; m_closeable = false; m_currentStorage = ""; /* add context sensitive menu items specific to this classto the page * selector tree. m_contextActions is QList of QActions */ m_contextActions.append(actionRefreshStorage); } Storage::~Storage() { if (m_populated) { writeExpandedSettings(); } } /* * The main meat of the class!! The function that querries the director and * creates the widgets with appropriate values. */ void Storage::populateTree() { if (m_populated) { writeExpandedSettings(); } m_populated = true; Freeze frz(*mp_treeWidget); /* disable updating */ m_checkcurwidget = false; mp_treeWidget->clear(); m_checkcurwidget = true; QStringList headerlist = (QStringList() << tr("Name") << tr("Id") << tr("Changer") << tr("Slot") << tr("Status") << tr("Enabled") << tr("Pool") << tr("Media Type") ); m_topItem = new QTreeWidgetItem(mp_treeWidget); m_topItem->setText(0, tr("Storage")); m_topItem->setData(0, Qt::UserRole, 0); m_topItem->setExpanded(true); mp_treeWidget->setColumnCount(headerlist.count()); mp_treeWidget->setHeaderLabels(headerlist); QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("StorageTreeExpanded"); bool first = true; QString storage_comsep(""); QString storageName; foreach(storageName, m_console->storage_list){ if (first) { storage_comsep += "'" + storageName + "'"; first = false; } else storage_comsep += ",'" + storageName + "'"; } if (storage_comsep != "") { /* Set up query QString and header QStringList */ QString query("SELECT" " Name AS StorageName," " StorageId AS ID, AutoChanger AS Changer" " FROM Storage " " WHERE StorageId IN (SELECT MAX(StorageId) FROM Storage WHERE"); query += " Name IN (" + storage_comsep + ")"; query += " GROUP BY Name) ORDER BY Name"; QStringList results; /* This could be a log item */ if (mainWin->m_sqlDebug) { Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data()); } if (m_console->sql_cmd(query, results)) { QStringList fieldlist; foreach (QString resultline, results) { fieldlist = resultline.split("\t"); storageName = fieldlist.takeFirst(); if (m_firstpopulation) { settingsOpenStatus(storageName); } TreeItemFormatter storageItem(*m_topItem, 1); storageItem.setTextFld(0, storageName); if(settings.contains(storageName)) storageItem.widget()->setExpanded(settings.value(storageName).toBool()); else storageItem.widget()->setExpanded(true); int index = 1; QStringListIterator fld(fieldlist); /* storage id */ storageItem.setNumericFld(index++, fld.next()); /* changer */ QString changer = fld.next(); storageItem.setBoolFld(index++, changer); if (changer == "1") { mediaList(storageItem.widget(), fieldlist.first()); } } } } /* Resize the columns */ for(int cnter=0; cnterresizeColumnToContents(cnter); } m_firstpopulation = false; } /* * For autochangers A query to show the tapes in the changer. */ void Storage::mediaList(QTreeWidgetItem *parent, const QString &storageID) { QString query("SELECT Media.VolumeName AS Media, Media.Slot AS Slot," " Media.VolStatus AS VolStatus, Media.Enabled AS Enabled," " Pool.Name AS MediaPool, Media.MediaType AS MediaType" " From Media" " JOIN Pool ON (Media.PoolId=Pool.PoolId)" " WHERE Media.StorageId='" + storageID + "'" " AND Media.InChanger<>0" " ORDER BY Media.Slot"); QStringList results; /* This could be a log item */ if (mainWin->m_sqlDebug) { Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data()); } if (m_console->sql_cmd(query, results)) { QString resultline; QString field; QStringList fieldlist; foreach (resultline, results) { fieldlist = resultline.split("\t"); if (fieldlist.size() < 6) { Pmsg1(0, "Discarding %s\n", resultline.data()); continue; } /* Iterate through fields in the record */ QStringListIterator fld(fieldlist); int index = 0; TreeItemFormatter fmt(*parent, 2); /* volname */ fmt.setTextFld(index++, fld.next()); /* skip the next two columns, unused by media */ index += 2; /* slot */ fmt.setNumericFld(index++, fld.next()); /* status */ fmt.setVolStatusFld(index++, fld.next()); /* enabled */ fmt.setBoolFld(index++, fld.next()); /* pool */ fmt.setTextFld(index++, fld.next()); /* media type */ fmt.setTextFld(index++, fld.next()); } } } /* * When the treeWidgetItem in the page selector tree is singleclicked, Make sure * The tree has been populated. */ void Storage::PgSeltreeWidgetClicked() { if(!m_populated) { populateTree(); createContextMenu(); } if (!isOnceDocked()) { dockPage(); } } /* * Added to set the context menu policy based on currently active treeWidgetItem * signaled by currentItemChanged */ void Storage::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetItem *previouswidgetitem ) { /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */ if (m_checkcurwidget) { /* The Previous item */ if (previouswidgetitem) { /* avoid a segfault if first time */ int treedepth = previouswidgetitem->data(0, Qt::UserRole).toInt(); if (treedepth == 1){ mp_treeWidget->removeAction(actionStatusStorageInConsole); mp_treeWidget->removeAction(actionStatusStorageWindow); mp_treeWidget->removeAction(actionLabelStorage); mp_treeWidget->removeAction(actionMountStorage); mp_treeWidget->removeAction(actionUnMountStorage); mp_treeWidget->removeAction(actionUpdateSlots); mp_treeWidget->removeAction(actionUpdateSlotsScan); mp_treeWidget->removeAction(actionRelease); mp_treeWidget->removeAction(actionImportStorage); } } int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt(); if (treedepth == 1){ /* set a hold variable to the storage name in case the context sensitive * menu is used */ m_currentStorage = currentwidgetitem->text(0); m_currentAutoChanger = currentwidgetitem->text(2) == tr("Yes"); mp_treeWidget->addAction(actionStatusStorageInConsole); mp_treeWidget->addAction(actionStatusStorageWindow); mp_treeWidget->addAction(actionLabelStorage); mp_treeWidget->addAction(actionMountStorage); mp_treeWidget->addAction(actionUnMountStorage); mp_treeWidget->addAction(actionRelease); QString text; text = tr("Status Storage \"%1\"").arg(m_currentStorage);; actionStatusStorageInConsole->setText(text); text = tr("Status Storage \"%1\" in Window").arg(m_currentStorage);; actionStatusStorageWindow->setText(text); text = tr("Label media in Storage \"%1\"").arg(m_currentStorage); actionLabelStorage->setText(text); text = tr("Mount media in Storage \"%1\"").arg(m_currentStorage); actionMountStorage->setText(text); text = tr("\"UN\" Mount media in Storage \"%1\"").arg(m_currentStorage); actionUnMountStorage->setText(text); text = tr("Release media in Storage \"%1\"").arg(m_currentStorage); actionRelease->setText(text); if (m_currentAutoChanger) { mp_treeWidget->addAction(actionUpdateSlots); mp_treeWidget->addAction(actionUpdateSlotsScan); mp_treeWidget->addAction(actionImportStorage); text = tr("Barcode Scan media in Storage \"%1\"").arg(m_currentStorage); actionUpdateSlots->setText(text); text = tr("Read scan media in Storage \"%1\"").arg( m_currentStorage); actionUpdateSlotsScan->setText(text); text = tr("Import volumes in Storage \"%1\"").arg(m_currentStorage); actionImportStorage->setText(text); } } } } /* * Setup a context menu * Made separate from populate so that it would not create context menu over and * over as the tree is repopulated. */ void Storage::createContextMenu() { mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu); mp_treeWidget->addAction(actionRefreshStorage); connect(mp_treeWidget, SIGNAL( currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); /* connect to the action specific to this pages class */ connect(actionRefreshStorage, SIGNAL(triggered()), this, SLOT(populateTree())); connect(actionStatusStorageInConsole, SIGNAL(triggered()), this, SLOT(consoleStatusStorage())); connect(actionLabelStorage, SIGNAL(triggered()), this, SLOT(consoleLabelStorage())); connect(actionMountStorage, SIGNAL(triggered()), this, SLOT(consoleMountStorage())); connect(actionUnMountStorage, SIGNAL(triggered()), this, SLOT(consoleUnMountStorage())); connect(actionUpdateSlots, SIGNAL(triggered()), this, SLOT(consoleUpdateSlots())); connect(actionUpdateSlotsScan, SIGNAL(triggered()), this, SLOT(consoleUpdateSlotsScan())); connect(actionImportStorage, SIGNAL(triggered()), this, SLOT(consoleImportStorage())); connect(actionRelease, SIGNAL(triggered()), this, SLOT(consoleRelease())); connect(actionStatusStorageWindow, SIGNAL(triggered()), this, SLOT(statusStorageWindow())); connect(mp_treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(contentWindow())); } void Storage::contentWindow() { if (m_currentStorage != "" && m_currentAutoChanger) { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); new Content(m_currentStorage, parentItem); } } /* * Virtual function which is called when this page is visible on the stack */ void Storage::currentStackItem() { if (!m_populated || m_needs_repopulate) { /* * If things are not populated yet we do both * the populate and create the context menu for the * storage tree. When its a (Re)populate we only do * a populateTree. */ if (!m_populated) { populateTree(); createContextMenu(); } else { populateTree(); } } } /* * Functions to respond to local context sensitive menu sending console commands * If I could figure out how to make these one function passing a string, Yaaaaaa */ void Storage::consoleStatusStorage() { QString cmd; cmd = QString("status storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); } /* Label Media populating current storage by default */ void Storage::consoleLabelStorage() { new labelPage(m_currentStorage); } /* Mount currently selected storage */ void Storage::consoleMountStorage() { if (m_currentAutoChanger == 0) { /* no autochanger, just execute the command in the console */ QString cmd; cmd = QString("mount storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); } else { setConsoleCurrent(); /* if this storage is an autochanger, lets ask for the slot */ new mountDialog(m_console, m_currentStorage); } } /* Unmount Currently selected storage */ void Storage::consoleUnMountStorage() { QString cmd; cmd = QString("umount storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); } /* Update Slots */ void Storage::consoleUpdateSlots() { QString cmd; cmd = QString("update slots storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); /* * Database is updated so (re)populate the view. */ m_needs_repopulate = true; } /* Update Slots Scan */ void Storage::consoleUpdateSlotsScan() { QString cmd; cmd = QString("update slots scan storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); /* * Database is updated so (re)populate the view. */ m_needs_repopulate = true; } /* Import volumes loaded in current import/export slots */ void Storage::consoleImportStorage() { QString cmd; cmd = QString("import storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); /* * Volumes have moved so (re)populate the view. */ m_needs_repopulate = true; } /* Release a tape in the drive */ void Storage::consoleRelease() { QString cmd; cmd = QString("release storage=\"%1\"") .arg(m_currentStorage); consoleCommand(cmd); } /* * Open a status storage window */ void Storage::statusStorageWindow() { /* if one exists, then just set it current */ bool found = false; foreach(Pages *page, mainWin->m_pagehash) { if (mainWin->currentConsole() == page->console()) { if (page->name() == tr("Storage Status %1").arg(m_currentStorage)) { found = true; page->setCurrent(); } } } if (!found) { QTreeWidgetItem *parentItem = mainWin->getFromHash(this); new StorStat(m_currentStorage, parentItem); } } /* * Write settings to save expanded states of the pools */ void Storage::writeExpandedSettings() { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("StorageTreeExpanded"); int childcount = m_topItem->childCount(); for (int cnt=0; cntchild(cnt); settings.setValue(item->text(0), item->isExpanded()); } settings.endGroup(); } /* * If first time, then check to see if there were status pages open the last time closed * if so open */ void Storage::settingsOpenStatus(QString &storage) { QSettings settings(m_console->m_dir->name(), "bat"); settings.beginGroup("OpenOnExit"); QString toRead = "StorageStatus_" + storage; if (settings.value(toRead) == 1) { if (mainWin->m_sqlDebug) { Pmsg1(000, "Do open Storage Status window for : %s\n", storage.toUtf8().data()); } new StorStat(storage, mainWin->getFromHash(this)); setCurrent(); mainWin->getFromHash(this)->setExpanded(true); } else { if (mainWin->m_sqlDebug) { Pmsg1(000, "Do NOT open Storage Status window for : %s\n", storage.toUtf8().data()); } } settings.endGroup(); } bareos-Release-14.2.6/src/qt-console/storage/storage.h000066400000000000000000000041551263011562700226010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dirk Bartley, March 2007 */ #ifndef _STORAGE_H_ #define _STORAGE_H_ #include #include "ui_storage.h" #include "pages.h" class Storage : public Pages, public Ui::StorageForm { Q_OBJECT public: Storage(); ~Storage(); virtual void PgSeltreeWidgetClicked(); virtual void currentStackItem(); public slots: void treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *); private slots: void populateTree(); void consoleStatusStorage(); void consoleLabelStorage(); void consoleMountStorage(); void consoleUnMountStorage(); void consoleUpdateSlots(); void consoleUpdateSlotsScan(); void consoleImportStorage(); void consoleRelease(); void statusStorageWindow(); void contentWindow(); private: void createContextMenu(); void mediaList(QTreeWidgetItem *parent, const QString &storageID); void settingsOpenStatus(QString& storage); QString m_currentStorage; bool m_currentAutoChanger; bool m_populated; bool m_needs_repopulate; bool m_firstpopulation; bool m_checkcurwidget; void writeExpandedSettings(); QTreeWidgetItem *m_topItem; }; void table_get_selection(QTableWidget *table, QString &sel); #endif /* _STORAGE_H_ */ bareos-Release-14.2.6/src/qt-console/storage/storage.ui000066400000000000000000000102551263011562700227650ustar00rootroot00000000000000 StorageForm 0 0 467 383 Storage Tree 9 9 9 9 6 6 1 :/images/view-refresh.png Refresh Storage List Requery the director for the list of storage objects. :/images/status-console.png Status Storage In Console Status Storage In Console :/images/label.png Label Storage Label Storage :/images/cartridge.png MountStorage MountStorage :/images/cartridge.png UnMount Storage UnMount Storage :/images/package-x-generic.png Update Slots Update Slots :/images/package-x-generic.png Update Slots Scan Update Slots Scan :/images/intern.png Import volumes Import volumes :/images/cartridge.png Release :/images/status.png Status Storage Window bareos-Release-14.2.6/src/qt-console/testprogs/000077500000000000000000000000001263011562700213455ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/testprogs/examp/000077500000000000000000000000001263011562700224575ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/testprogs/examp/dock.pro000066400000000000000000000003461263011562700241240ustar00rootroot00000000000000CONFIG += qt debug TEMPLATE = app TARGET = main DEPENDPATH += . INCLUDEPATH += .. MOC_DIR = moc OBJECTS_DIR = obj UI_DIR = ui # Main window #RESOURCES = dockwidgets.qrc HEADERS += mainwindow.h SOURCES += mainwindow.cpp main.cpp bareos-Release-14.2.6/src/qt-console/testprogs/examp/dockwidgets.qrc000066400000000000000000000003151263011562700254740ustar00rootroot00000000000000 images/new.png images/print.png images/save.png images/undo.png bareos-Release-14.2.6/src/qt-console/testprogs/examp/main.cpp000066400000000000000000000003511263011562700241060ustar00rootroot00000000000000#include #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); // Q_INIT_RESOURCE(dockwidgets); MainWindow mainWin; mainWin.show(); return app.exec(); } bareos-Release-14.2.6/src/qt-console/testprogs/examp/mainwindow.cpp000066400000000000000000000260271263011562700253460ustar00rootroot00000000000000/**************************************************************************** * ** * ** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved. * ** * ** This file is part of the example classes of the Qt Toolkit. * ** * ** This file may be used under the terms of the GNU General Public * ** License version 2.0 as published by the Free Software Foundation * ** and appearing in the file LICENSE.GPL included in the packaging of * ** this file. Please review the following information to ensure GNU * ** General Public Licensing requirements will be met: * ** http://www.trolltech.com/products/qt/opensource.html * ** * ** If you are unsure which license is appropriate for your use, please * ** review the following information: * ** http://www.trolltech.com/products/qt/licensing.html or contact the * ** sales department at sales@trolltech.com. * ** * ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * ** * ****************************************************************************/ #include #include "mainwindow.h" MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); createActions(); createMenus(); createToolBars(); createStatusBar(); createDockWindows(); setWindowTitle(tr("Dock Widgets")); newLetter(); } void MainWindow::newLetter() { textEdit->clear(); QTextCursor cursor(textEdit->textCursor()); cursor.movePosition(QTextCursor::Start); QTextFrame *topFrame = cursor.currentFrame(); QTextFrameFormat topFrameFormat = topFrame->frameFormat(); topFrameFormat.setPadding(16); topFrame->setFrameFormat(topFrameFormat); QTextCharFormat textFormat; QTextCharFormat boldFormat; boldFormat.setFontWeight(QFont::Bold); QTextCharFormat italicFormat; italicFormat.setFontItalic(true); QTextTableFormat tableFormat; tableFormat.setBorder(1); tableFormat.setCellPadding(16); tableFormat.setAlignment(Qt::AlignRight); cursor.insertTable(1, 1, tableFormat); cursor.insertText("The Firm", boldFormat); cursor.insertBlock(); cursor.insertText("321 City Street", textFormat); cursor.insertBlock(); cursor.insertText("Industry Park"); cursor.insertBlock(); cursor.insertText("Some Country"); cursor.setPosition(topFrame->lastPosition()); cursor.insertText(QDate::currentDate().toString("d MMMM yyyy"), textFormat); cursor.insertBlock(); cursor.insertBlock(); cursor.insertText("Dear ", textFormat); cursor.insertText("NAME", italicFormat); cursor.insertText(",", textFormat); for (int i = 0; i < 3; ++i) cursor.insertBlock(); cursor.insertText(tr("Yours sincerely,"), textFormat); for (int i = 0; i < 3; ++i) cursor.insertBlock(); cursor.insertText("The Boss", textFormat); cursor.insertBlock(); cursor.insertText("ADDRESS", italicFormat); } void MainWindow::print() { QTextDocument *document = textEdit->document(); QPrinter printer; QPrintDialog *dlg = new QPrintDialog(&printer, this); if (dlg->exec() != QDialog::Accepted) return; document->print(&printer); statusBar()->showMessage(tr("Ready"), 2000); } void MainWindow::save() { QString fileName = QFileDialog::getSaveFileName(this, tr("Choose a file name"), ".", tr("HTML (*.html *.htm)")); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("Dock Widgets"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } QTextStream out(&file); QApplication::setOverrideCursor(Qt::WaitCursor); out << textEdit->toHtml(); QApplication::restoreOverrideCursor(); statusBar()->showMessage(tr("Saved '%1'").arg(fileName), 2000); } void MainWindow::undo() { QTextDocument *document = textEdit->document(); document->undo(); } void MainWindow::insertCustomer(const QString &customer) { if (customer.isEmpty()) return; QStringList customerList = customer.split(", "); QTextDocument *document = textEdit->document(); QTextCursor cursor = document->find("NAME"); if (!cursor.isNull()) { cursor.beginEditBlock(); cursor.insertText(customerList.at(0)); QTextCursor oldcursor = cursor; cursor = document->find("ADDRESS"); if (!cursor.isNull()) { for (int i = 1; i < customerList.size(); ++i) { cursor.insertBlock(); cursor.insertText(customerList.at(i)); } cursor.endEditBlock(); } else oldcursor.endEditBlock(); } } void MainWindow::addParagraph(const QString ¶graph) { if (paragraph.isEmpty()) return; QTextDocument *document = textEdit->document(); QTextCursor cursor = document->find(tr("Yours sincerely,")); if (cursor.isNull()) return; cursor.beginEditBlock(); cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::MoveAnchor, 2); cursor.insertBlock(); cursor.insertText(paragraph); cursor.insertBlock(); cursor.endEditBlock(); } void MainWindow::about() { QMessageBox::about(this, tr("About Dock Widgets"), tr("The Dock Widgets example demonstrates how to " "use Qt's dock widgets. You can enter your own text, " "click a customer to add a customer name and " "address, and click standard paragraphs to add them.")); } void MainWindow::createActions() { newLetterAct = new QAction(QIcon(":/images/new.png"), tr("&New Letter"), this); newLetterAct->setShortcut(tr("Ctrl+N")); newLetterAct->setStatusTip(tr("Create a new form letter")); connect(newLetterAct, SIGNAL(triggered()), this, SLOT(newLetter())); saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save..."), this); saveAct->setShortcut(tr("Ctrl+S")); saveAct->setStatusTip(tr("Save the current form letter")); connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); printAct = new QAction(QIcon(":/images/print.png"), tr("&Print..."), this); printAct->setShortcut(tr("Ctrl+P")); printAct->setStatusTip(tr("Print the current form letter")); connect(printAct, SIGNAL(triggered()), this, SLOT(print())); undoAct = new QAction(QIcon(":/images/undo.png"), tr("&Undo"), this); undoAct->setShortcut(tr("Ctrl+Z")); undoAct->setStatusTip(tr("Undo the last editing action")); connect(undoAct, SIGNAL(triggered()), this, SLOT(undo())); quitAct = new QAction(tr("&Quit"), this); quitAct->setShortcut(tr("Ctrl+Q")); quitAct->setStatusTip(tr("Quit the application")); connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); } void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newLetterAct); fileMenu->addAction(saveAct); fileMenu->addAction(printAct); fileMenu->addSeparator(); fileMenu->addAction(quitAct); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(undoAct); viewMenu = menuBar()->addMenu(tr("&View")); menuBar()->addSeparator(); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); } void MainWindow::createToolBars() { fileToolBar = addToolBar(tr("File")); fileToolBar->addAction(newLetterAct); fileToolBar->addAction(saveAct); fileToolBar->addAction(printAct); editToolBar = addToolBar(tr("Edit")); editToolBar->addAction(undoAct); } void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); } void MainWindow::createDockWindows() { QDockWidget *dock = new QDockWidget(tr("Customers"), this); dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); customerList = new QListWidget(dock); customerList->addItems(QStringList() << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton" << "Jane Doe, Memorabilia, 23 Watersedge, Beaton" << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton" << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal" << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston" << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula"); dock->setWidget(customerList); addDockWidget(Qt::RightDockWidgetArea, dock); viewMenu->addAction(dock->toggleViewAction()); dock = new QDockWidget(tr("Paragraphs"), this); paragraphsList = new QListWidget(dock); paragraphsList->addItems(QStringList() << "Thank you for your payment which we have received today." << "Your order has been dispatched and should be with you " "within 28 days." << "We have dispatched those items that were in stock. The " "rest of your order will be dispatched once all the " "remaining items have arrived at our warehouse. No " "additional shipping charges will be made." << "You made a small overpayment (less than $5) which we " "will keep on account for you, or return at your request." << "You made a small underpayment (less than $1), but we have " "sent your order anyway. We'll add this underpayment to " "your next bill." << "Unfortunately you did not send enough money. Please remit " "an additional $. Your order will be dispatched as soon as " "the complete amount has been received." << "You made an overpayment (more than $5). Do you wish to " "buy more items, or should we return the excess to you?"); dock->setWidget(paragraphsList); addDockWidget(Qt::RightDockWidgetArea, dock); viewMenu->addAction(dock->toggleViewAction()); connect(customerList, SIGNAL(currentTextChanged(const QString &)), this, SLOT(insertCustomer(const QString &))); connect(paragraphsList, SIGNAL(currentTextChanged(const QString &)), this, SLOT(addParagraph(const QString &))); } bareos-Release-14.2.6/src/qt-console/testprogs/examp/mainwindow.h000066400000000000000000000045231263011562700250100ustar00rootroot00000000000000 /**************************************************************************** * ** * ** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved. * ** * ** This file is part of the example classes of the Qt Toolkit. * ** * ** This file may be used under the terms of the GNU General Public * ** License version 2.0 as published by the Free Software Foundation * ** and appearing in the file LICENSE.GPL included in the packaging of * ** this file. Please review the following information to ensure GNU * ** General Public Licensing requirements will be met: * ** http://www.trolltech.com/products/qt/opensource.html * ** * ** If you are unsure which license is appropriate for your use, please * ** review the following information: * ** http://www.trolltech.com/products/qt/licensing.html or contact the * ** sales department at sales@trolltech.com. * ** * ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * ** * ****************************************************************************/ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include class QAction; class QListWidget; class QMenu; class QTextEdit; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); private slots: void newLetter(); void save(); void print(); void undo(); void about(); void insertCustomer(const QString &customer); void addParagraph(const QString ¶graph); private: void createActions(); void createMenus(); void createToolBars(); void createStatusBar(); void createDockWindows(); QTextEdit *textEdit; QListWidget *customerList; QListWidget *paragraphsList; QMenu *fileMenu; QMenu *editMenu; QMenu *viewMenu; QMenu *helpMenu; QToolBar *fileToolBar; QToolBar *editToolBar; QAction *newLetterAct; QAction *saveAct; QAction *printAct; QAction *undoAct; QAction *aboutAct; QAction *aboutQtAct; QAction *quitAct; }; #endif bareos-Release-14.2.6/src/qt-console/testprogs/putz/000077500000000000000000000000001263011562700223475ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/testprogs/putz/main.cpp000066400000000000000000000003641263011562700240020ustar00rootroot00000000000000#include #include "putz.h" Putz *putz; QApplication *app; int main(int argc, char *argv[]) { app = new QApplication(argc, argv); app->setQuitOnLastWindowClosed(true); putz = new Putz; putz->show(); return app->exec(); } bareos-Release-14.2.6/src/qt-console/testprogs/putz/putz.cpp000066400000000000000000000002341263011562700240540ustar00rootroot00000000000000 #include #include #include "putz.h" Putz::Putz() { printf("got to Putz Constructor\n"); setupUi(this); } bareos-Release-14.2.6/src/qt-console/testprogs/putz/putz.h000066400000000000000000000003261263011562700235230ustar00rootroot00000000000000#ifndef _PUTZ_H_ #define _PUTZ_H_ #include #include "ui_putz.h" class Putz : public QMainWindow, public Ui::MainWindow { Q_OBJECT public: Putz(); public slots: private: }; #endif /* _PUTZ_H_ */ bareos-Release-14.2.6/src/qt-console/testprogs/putz/putz.pro000066400000000000000000000003171263011562700240740ustar00rootroot00000000000000CONFIG += qt debug TEMPLATE = app TARGET = putz DEPENDPATH += . INCLUDEPATH += .. MOC_DIR = moc OBJECTS_DIR = obj UI_DIR = ui # Main window FORMS += putz.ui HEADERS += putz.h SOURCES += putz.cpp main.cpp bareos-Release-14.2.6/src/qt-console/testprogs/putz/putz.ui000066400000000000000000000040771263011562700237200ustar00rootroot00000000000000 MainWindow 0 0 557 534 MainWindow true 0 0 557 28 7 7 12 7 Whoochie 1 9 6 coochie 2 9 6 bareos-Release-14.2.6/src/qt-console/ts/000077500000000000000000000000001263011562700177415ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/ts/bat_de.ts000066400000000000000000003254221263011562700215370ustar00rootroot00000000000000 ClientForm Client Tree Refresh Client List Requery the director for the list of clients. List Jobs of Client Open a joblist page selecting this client. Status Client In Console Execute status client in console. Purge Jobs Purge jobs peformed from this client. Prune Jobs Open the diaolog to prune for this client. Clients Clients Client Name File Retention Job Retention AutoPrune ClientId Uname Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Is there any way I can get you to click Cancel here? You really don't want to do this Press OK to proceed with the purge operation? ConsoleForm Console StatusDir Console Help Request Messages Reload bareos-dir.conf DirComm Bat DirStat Job Id Job Level Job Files Job Bytes Job Status Job Time Job Name Job Type Priority Volume Job Data Job Info Director Status DirStatForm Form <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Scheduled Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Running Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> FileSet FileSets FileSet Name FileSet Id Create Time FileSet FileSetForm FileSet Tree Refresh FileSet List Requery the director for the list of storage objects. Status FileSet In Console ShowJobs Help Help: %1 JobList Any Job Id Job Name Client Job Starttime Job Type Job Level Job Files Job Bytes Job Status Purged File Set IS NOT Backup Restore The Jobs query returned no results. Press OK to continue? Are you sure you want to delete?? !!!. This delete command is used to delete a Job record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. The Job and all its associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Press OK to proceed with the purge operation? JobListForm Form Refresh Graph FileSet Status Purged Record Limit Days Limit Clients Volume Job Level Refresh Job List Requery the director for the list of jobs. ListJobid List Files On Job ListJobMedia ListVolumes DeleteJob PurgeFiles Restore From Job Restore From Time Show Log for Job Cancel Currently Running Job List Job Totals in Console JobLog Bat There were no results ?? !!!. It is possible you may need to add "catalog = all" to the Messages stanza for this job. JobLogForm Job Log JobPlot Bat The Jobs query returned no results. Press OK to continue? JobPlotControlsForm Form File Data Byte Data Refresh Status Level Purged FileSet Volume Client Job Days Limit Record Limit Byte Symbol Type File Symbol Type Graph Type Jobs Jobs Job Name Pool Messages Client Storage Where Level Type FileSet Catalog Enabled Backup MainForm bat - Bareos Admin Tool Bareos Administration Tool It's a Dock widget to allow page selection &Edit Settings &Help &File Current Status Tool Bar Page Selector Selects panel window Use items in this tree to select what window is in panel Console Entry Enter a bareos command Console Command entry Dock Widget Console Command Line Entry Command: Click here to enter command &Quit Ctrl+Q &About bat &Copy Cu&t new open &Paste &Print Print &Save Save (not implemented) Connect Connect/disconnect Label Label a Volume Restore Restore Files Run Job Run a Job Estimate Job Estimate a Job Status Dir Query status of director Status Dir Query status of director in console &Select Font ... Undock Window Undock Current Window ToggleDock Toggle Dock Status Close Page Close The Current Page Messages Display any messages queued at the director &Preferences ... Set Preferences bat &Help Browse Browse Cataloged Files JobPlot Plot Job Files and Bytes Status Dir Page Director Status Page MainWin Director not connected. Click on connect button. About bat <br><h2>bat 1.0, by Dirk H Bartley and Kern Sibbald</h2><p>Copyright &copy; 2007- Ready MediaEdit Media Edit No Volume name No Volume name given MediaList Media Volume Name Id Status Enabled Bytes Files Jobs Retention Media Type Slot Use Duration Max Jobs Max Files Max Bytes Recycle RecyclePool Last Written Pools Are you sure you want to delete?? !!!. This delete command is used to delete a Volume record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. All Jobs and all associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Press OK to proceed with the purge operation? MediaListForm Media Tree Refresh Media List Requery the director for the list of media. Edit Volume List Jobs On Volume Delete Volume Prune Volume Purge Volume Relabel Volume Update all Volumes From Pool Update all Volumes from all Pools Volume From Pool Pages of Director UnDock ReDock Window PrefsForm Preferences Messages Messages Options Message check interval in seconds Check Messages Joblist Joblist Limit Options Days Limit Record Limit Misc Convert Convert Off Convert Bytes with IEC 1000B = KB Convert Bytes with 1024B = KB Context Sensitive List Commands Execute Long List GroupBox Open Plot page on startup Open Browser page on startup Open Director Status page on startup Debug Debugging Options Debug comm Display all messages in console Debug Commands Debug Sql queries Debug Miscelaneous Items RestoreTree Restore Debug 2 Directory Item Changed Restore Debug 1 Directory Current Item Changed Debug Update File Table Debug Version Table Item Changed Debug File Table Item Changed Debug Icon State Debug Update Checks Debug Restore Debug 3 Update Version Table Debug Populate Directory Debug <h2>Preferences</h2> Storage Storage Storage Name Storage Id Auto Changer StorageForm Storage Tree Refresh Storage List Requery the director for the list of storage objects. Status Storage In Console Label Storage MountStorage UnMount Storage Update Slots Update Slots Scan Release bRestoreForm brestore File list Type File Name Size Date File revisions InChanger Volume JobId Chksum <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Restore items list</span></p></body></html> Clear Estimate Restore FileName FileIndex Nb Files Location estimateForm Form List Files Level: Client: Job: FileSet: <h3>Estimate a backup Job</h3> OK Cancel estimatePage Estimate helpForm Form &Home &Back Close jobsForm Client Tree Refresh Jobs List Requery the director for the list of clients. List Files Command List Volumes Command List Next Volume Command Enable Job Command Disable Job Command Open JobList on Job Cancel Job Command RunJob labelForm Form OK Cancel Volume Name: Storage: Slot: Execute Automount On Off Pool: <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Label a Volume</span></p></body></html> mediaEditForm Form Pool: Volume Status: Max Volume Bytes: Slot: Max Volume Jobs: Use Duration: OK Cancel Retension: Recycle Pool: Enabled Max Volume Files: Years Seconds Use Duration Days Hours Months Retention Minutes Volume : Recycle <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Edit a Volume</span></p></body></html> mountForm Label TextLabel Slot: <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Mount a Slot</span></p></body></html> prefsDialog Canceled prerestoreForm Form All Files Select Files Job JobIds yyyy-mm-dd h:mm:ss Use Most Recent File Set: Client: Storage: Before: Pool: OK Cancel <h3>Select Jobs</h3> prerestorePage Restore Any Comma separted list of Job Ids Canceled There can be no spaces in the text for the joblist. Press OK to continue? The string is not a comma separated list of integers. Press OK to continue? Bat At least one of the jobs is not a valid job of type "Backup". Press OK to continue? All jobs in the list must be of the same jobName and same client. Press OK to continue? pruneForm Form Prune Files Volume: <h3>Prune Files/Jobs/Volumes</h3> Prune Jobs OK Cancel Client: Prune Volumes prunePage Prune Any Canceled relabelDialog From Volume : No Volume name No Volume name given New name must be different relabelForm Label From Volume : Pool: Storage: New Volume Name: Slot: <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Relabel a Volume</span></p></body></html> restoreForm Form 1 2 3 4 5 6 <h2>Directories</h2> <h3>Restore Select</h3> Up Mark Unmark <h2>Files</h2> Status: Current Dir: OK Cancel UnMark restorePage Restore Select Mark File Mode User Group Size Date In addDirectory cwd "%1" newdir "%2" In else of if parent cwd "%1" newdir "%2" Canceled restoreTree Version Browser Directories Any Refresh From Re-Select Refresh From JobChecks Task Querying Database Querying Jobs Querying for Directories Processing Directories No jobs were selected in the job query !!!. Press OK to continue? In addDirectory cwd "%1" newdir "%2" In else of if parent cwd "%1" newdir "%2" File Name Filename Id Present Working Directory : Job Id Type End Time Hash FileId RestoreTreePage Level Name Purged TU TD restoreTreeForm Form Jobs TextLabel Files Versions of File FileName Refresh Restore Job Job List Job Criterion Selector Client Job List Client Criterion Selector FileSet Job List Fileset Criterion Selector Record Limit Days Limit Directory Select Directory UnselectDirectory runCmdForm Form Priority: yyyy-mm-dd hh:mm:ss When: Where: Bootstrap: Job: Storage: FileSet: Replace: To client: Catalog: OK Cancel <h3>Run Restore Job</h3> runCmdPage Restore Run never always ifnewer ifolder Canceled runForm Form Level: Bootstrap: yyyy-mm-dd hh:mm:ss Job: Pool: Type: <h3>Backup<h3/> FileSet: Messages: <h3>Run a Job</h3> Priority: Client: OK Cancel Storage: When: runPage Run Canceled selectDialog Canceled selectForm Selection dialog yesnoPopUp Bat Question bareos-Release-14.2.6/src/qt-console/ts/bat_fr.ts000066400000000000000000006114721263011562700215610ustar00rootroot00000000000000 ClientForm Client Tree Arborescence Client Refresh Client List Rafraichir la liste des Clients Requery the director for the list of clients. Interroger le director pour la liste des clients. List Jobs of Client Lister les travaux du client Open a joblist page selecting this client. Ouvrir une liste des travaux en sélectionnant ce client. Purge Jobs Purger les travaux Purge jobs peformed from this client. Purger les travaux de ce client. Prune Jobs Élaguer les travaux Open the diaolog to prune for this client. Ouvrir un dialogue pour élaguer (prune) ce client. Status Client État du client ClientStat Client Status %1 État du client %1 Job Id Id du travail Job Level Niveau Job Files Fichiers Job Bytes Octets Job Status État Job Time Heure Job Name Nom ClientStatForm Form Form Running En cours Header Entête Refresh Timer Sablier de MàJ Do Refresh Activer <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Travaux terminés</span></p></body></html> Refresh Actualiser Cancel Running Job Annuler le travail en cours Clients Clients Clients Client Name Nom du client File Retention Durée de rétention du fichier Job Retention Rétention du travail AutoPrune Élagage auto ClientId Id du client Uname Uname Are you sure you want to purge all jobs of client "%1" ? The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Is there any way I can get you to click Cancel here? You really don't want to do this Press OK to proceed with the purge operation? Êtes-vous sûr de vouloir purger tous les travaux du client "%1" ? La commande Purge va détruire les enregistrements du catalogue pour les travaux et les volumes sans prendre en considération les durées de rétention. Purger n'affecte que le catalogue, pas les données écrites dans les Volumes. Cette commande peut être dangereuse car vous pouvez détruire les enregistrements associés aux sauvegardes de fichiers actuelles, et nous vous recommandons de ne pas l'utiliser sauf si vous savez vraiment ce que vous faîtes. Comment vous persuader de clicker Annuler ? Vous ne désirez probablement pas faire ça ! Cliquer OK pour réaliser l'opération de purge ? Client Status %1 État du client %1 Console Console Console No Director found. Aucun Director trouvé. Director not connected. Click on connect button. Director déconnecté. Cliquer sur le bouton connexion. Director is currently disconnected Please reconnect! le Director est actuellement déconnecté Veuillez vous reconnecter ! ConsoleForm Console Console StatusDir Console Help Aide de la Console Request Messages Récupérer les messages Reload bareos-dir.conf Recharger bareos-dir.conf Content Storage Status %1 Etat du dépôt %1 ContentForm Form Form Actions Actions Update slots M.à.J. slots Label Étiquette Move to tray Charger Empty tray Décharger Mount Monter Unmount Démonter Status État Release Libérer Drives Lecteurs Drive Lecteur Volume Volume Import/Export Slot Slot Content Contenu Slot Slot Volume Volume Bytes Octets Status État Media Type Type de support Pool Groupe Last Written Dernière écriture When expire? Expire le ? DirComm Bat Bat Already connected. Déjà connecté. DirStat Job Id Id du travail Job Level Niveau Job Files Fichiers Job Bytes Octets Job Status État Job Time Heure Job Name Nom Job Type Type de travail Priority Priorité Volume Volume Job Data Données Job Info Information Director Status État du director DirStatForm Form Form <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Scheduled Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Travaux prévus</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Running Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Travaux en cours</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Travaux Terminés</span></p></body></html> Refresh Timer Sablier de rafraîchissement Do Refresh Activer le sablier Refresh Actualiser Cancel Selected Running Jobs Annuler les travaux en cours sélectionnés Disable Scheduled Job Désactiver le job planifié FileSet FileSets Jeux de fichiers FileSet Name FileSet Name FileSet Id Id du jeu de fichiers Create Time Date de création FileSet FileSet FileSet Name Nom FileSetForm FileSet Tree Arbre des jeux de fichiers Refresh FileSet List Rafraichir la liste des jeux de fichier Requery the director for the list of storage objects. Réinterroger le director pour la liste des dépôts. ShowJobs Afficher les travaux Show FileSet In Console Afficher le jeu de fichiers dans la console Help Help: %1 Aide : %1 Job Job Travail Are you sure you want to delete?? !!!. This delete command is used to delete a Job record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. The Job and all its associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Êtes-vous sûr de vouloir détruire?? !!!.Cette commande est utilisée pour détruire un enregistrement "travail" et tous les enregistrements associés du catalogue. Cette commande influe uniquement sur le catalogue et n'a pas d'effet sur les données écrites sur un volume. Cette commande peut être dangereuse et nous vous recommandons fortement de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Le travail et les autres enregistrements associés (fichiers et supports) seront détruits du catalogue. Cliquer OK pour réaliser la destruction ? Are you sure you want to cancel this job? Êtes-vous sûr de vouloir annuler ce travail ? Bat Bat There were no results! It is possible you may need to add "catalog = all" to the Messages resource for this job. Aucun résultat ! Il se pourrait que vous deviez ajouter "catalog = all" à la ressource "Messages" de ce travail. Error: Erreur : JobForm Form Form Cancel Annuler Delete Supprimer View errors for this Job Voir les erreurs de ce travail Errors Erreurs Media Support History Historique Run again Ré-éxécuter Read doc FileSet Jeu de fichiers Stats Statistiques Refresh Actualiser Basic Information Informations de base JobId: Id Travail : 2 2 Job Name: Nom du Travail : Test Level: Niveau : VirtualFull Client: Client : client-fd FileSet: Jeu de fichier : TheFileSet Pool: Groupe : ThePool Status État Status: État : Errors: Erreurs : 0 0 Files: Fichiers : 1,924 1,924 Bytes: Octets : 109 MB Purged: Purgés : Times Temps Sched Time: Heure prévue : 2009-07-31 00:10:00 2009-07-31 00:10:00 Start Time: Heure début : End Time: Heure de fin : 2009-07-31 00:20:00 2009-07-31 00:20:00 Duration: Durée : 00:10:00 00:10:00 Volume Used Volume utilisé Vol0001 Running Information Informations en cours Speed: Vitesse : Files Examined: nb Fichers examinés : Current File: Fichier en cours : /var/www/bareos/spool 100,000 100,000 100 MB/s <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:10pt;"></p></body></html> JobList The Jobs query returned no results. Press OK to continue? La requête ne renvoie aucun travail. Cliquer OK pour continuer ? Are you sure you want to delete?? !!!. This delete command is used to delete a Job record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. The Job and all its associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Êtes-vous sûr de vouloir détruire?? !!!.Cette commande est utilisée pour détruire un enregistrement "travail" et tous les enregistrements associés du catalogue. Cette commande influe uniquement sur le catalogue et n'a pas d'effet sur les données écrites sur un volume. Cette commande peut être dangereuse et nous vous recommandons fortement de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Le travail et les autres enregistrements associés (fichiers et supports) seront détruits du catalogue. Cliquer OK pour réaliser la destruction ? Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Press OK to proceed with the purge operation? Êtes-vous sûr de vouloir purger ?? !!!. La commande de purge va détruire les enregistrements du catalogue associés (travaux et volumes) sans prendre en compte la durée de rétention. La purge ne concerne que le catalogue et n'affecte pas les données écrites sur les volumes. Cette commande peut être dangereuse car vous pouvez détruire des enregistrements associés aux sauveardes actuelles, et nous vous recommandons de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Cliquer OK pour réaliser la purge? Any Tous, mais peut-on le traduire ? Job Id Id du travail Job Name Nom Client Client Job Starttime Heure de début Job Type Type de travail Job Level Niveau Job Files Fichiers Job Bytes Octets Job Status État Purged Purgé File Set Jeu de fichiers Backup Sauvegarde .... mais peut-on le traduire ? Restore Restauration Pool Name Nom du Groupe First Volume Premier Volume VolCount nb de volumes Jobs Run on Volume %1 Exécutions sur le volume %1 Jobs Run from Client %1 Exécutions depuis le client %1 Jobs Run of Job %1 Exécutions du travail %1 Jobs Run with fileset %1 Exécutions avec le jeu de fichiers %1 Jobs Run Exécutions de travaux run job="%1" client="%2" level=%3 faut-il traduire les commandes envoyées à la console ? je ne crois pas. fileset="%1" faut-il traduire les commandes envoyées à la console ? je ne crois pas. Delete list of %1 Jobs Détruire %1 travaux Purge Files from list of %1 Jobs Purger les fichiers de %1 travaux Delete Single Job Détruire un travail Purge Files from single job Purger les fichiers d'un travail Running En cours ... mais faut-il le traduire ? Created, not yet running Créé, pas encore lancé ... mais faut-il le traduire ? JobListForm Form Form Refresh Actualiser Graph Graphique FileSet Jeu de fichiers Status État Purged Purgé Record Limit Limitation en nombre Days Limit Limitation en jours Clients Clients Volume Volume Job Travail Level Niveau Refresh Job List Actualiser la liste Requery the director for the list of jobs. Réinterroger le Director pour la liste des travaux. List Files On Job Lister les fichiers du travail Restore From Job Restaurer depuis ce travail Restore From Time Restaurer à cette date Cancel Currently Running Job Annuler le travail en cours Pool Groupe Filter Copy Jobs Filtrer les copies Filter Migration Jobs Filtrer les migrations List Job Volumes Lister les volumes du travail List Volumes Lister les volumes Delete Job Détruire le travail Purge Files Purger les fichiers Restart Job Relancer le travail Show Job Log Voir les traces du travail Show Job Info Voir les informations du travail List Job Totals on Console Lister les grands totaux des travaux dans la console JobLog Bat Bat JobLog Traces du travail There were no results! It is possible you may need to add "catalog = all" to the Messages resource for this job. Aucun résultat ! Il se pourrait que vous deviez ajouter "catalog = all" à la ressource "Messages" de ce travail. Log records for job %1 Enregistrements de trace du travail %1 Error: Erreur : ... mais faut-il le traduire ? JobLogForm Job Log Traces du travail JobPlot The Jobs query returned no results. Press OK to continue? La requête ne renvoie aucun travail. Cliquer OK pour continuer ? JobPlot Sticks Lines Steps None Any Tous Files and Bytes backed up <-- Bytes Kb date of backup --> Number of Files --> Files Fichiers Bytes Octets Fitted Ellipse Rect Diamond Triangle DTrianle UTriangle LTriangle RTriangle Cross XCross HLine Vline Star1 Star2 Hexagon JobPlotControlsForm Form Form File Data Byte Data Refresh Actualiser Status État Level Niveau Purged Purgé FileSet Jeu de fichiers Volume Volume Client Client Job Travail Days Limit Limitation en jour Record Limit Limitation en nombre Byte Symbol Type File Symbol Type Graph Type Type de graphique Jobs Jobs Travaux Job Name Nom du travail Pool Groupe Messages Messages Client Client Storage Dépôt Where Level Niveau Type Type FileSet Jeu de fichiers Catalog Catalogue Enabled Activé MainForm bat - Bareos Admin Tool Bareos Administration Tool Outil d'administration de Bareos It's a Dock widget to allow page selection Settings Options &Help &Aide &File &Fichier Current Status Barre d'état Tool Bar Barre d'outils Page Selector Choisir Page Selects panel window Choisir l'onglet actif Use items in this tree to select what window is in panel Cliquer sur un élément de cette liste pour choisir l'onglet actif du panneau Enter a bareos command Entrer une commande Bareos Command: Commande : Click here to enter command Cliquer ici pour entrer une commande &Quit &Quitter Ctrl+Q &About bat &À propos de bat &Copy Co&pier Cu&t &Couper new nouveau open ouvrir &Paste Co&ller &Print &Imprimer Print Imprimer &Save &Enregistrer Save (not implemented) Enregistrer (pas implémenté) Connect Connexion Connect/disconnect Connexion/Déconnexion Label Étiquette (Label) Label a Volume Étiqueter un volume Restore Restaurer Restore Files Restaurer des fichiers Run Job Lancer un travail Run a Job Lancer un nouveau travail Estimate Job Estimer un travail Estimate a Job Estimer un travail Status Dir Query status of director État du director Status Dir État du director Query status of director in console Interroger l'état du director dans la console &Select Font ... &Choisir la police ... Undock Window Déplacer vers une nouvelle fenêtre Undock Current Window Déplacer l'onglet courant vers une nouvelle fenêtre ToggleDock Toggle Dock Status Close Page Fermer l'onglet Close The Current Page Fermer l'onglet en cours Messages Messages Display any messages queued at the director Afficher tous les messages en attente dans le director &Preferences ... &Préférences ... Set Preferences Définir les préférences bat &Help &Aide de bat Browse Naviguer Browse Cataloged Files Naviguer dans les fichiers du catalogue JobPlot Plot Job Files and Bytes Status Dir Page État du director Director Status Page État du director 1 1 Repop Lists Remplir les listes Reload and Repop Recharger et remplir les listes back Previous Page MainWin Director not connected. Click on connect button. le Director n'est pas connecté. Cliquer le bouton de connexion. About bat À propos de bat <br><h2>bat 1.0, by Dirk H Bartley and Kern Sibbald</h2><p>Copyright &copy; 2007- <br><h2>bat 1.0, par Dirk H Bartley et Kern Sibbald</h2><p>Copyright &copy; 2007- Ready Prêt Select Page Sélection d'onglet Console Console Director Status Etat du director <br><h2>bat %1 (%2), by Dirk H Bartley and Kern Sibbald</h2><p>Copyright &copy; 2007-%3 Free Software Foundation Europe e.V.<p>The <b>bat</b> is an administrative console interface to the Director. <br><h2>bat %1 (%2), par Dirk H Bartley et Kern Sibbald</h2><p>Copyright &copy; 2007-%3 Free Software Foundation Europe e.V.<p><b>bat</b> est une console d'administration pour le "Director". MediaEdit Media Edit Édition du support No Volume name Pas de nom de volume No Volume name given Pas de nom de Volume donné MediaInfo Media Info Informations du support Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Press OK to proceed with the purge operation? Êtes-vous sûr de vouloir purger ?? !!!. La commande de purge va détruire les enregistrements du catalogue associés (travaux et volumes) sans prendre en compte la durée de rétention. La purge ne concerne que le catalogue et n'affecte pas les données écrites sur les volumes. Cette commande peut être dangereuse car vous pouvez détruire des enregistrements associés aux sauvegardes actuelles, et nous vous recommandons de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Cliquer OK pour réaliser la purge? Are you sure you want to delete?? !!!. This delete command is used to delete a Volume record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. All Jobs and all associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Êtes-vous sûr de vouloir détruire?? !!!. Cette commande est utilisée pour détruire un enregistrement "volume" et tous les enregistrements associés du catalogue. Cette commande influe uniquement sur le catalogue et n'a pas d'effet sur les données écritessur un volume. Cette commande peut être dangereuse et nous vous recommandons fortement de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Tous les travaux et autres enregistrements associés (fichiers et supports) seront détruits du catalogue. Cliquer OK pour réaliser la destruction ? MediaList Are you sure you want to delete?? !!!. This delete command is used to delete a Volume record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. All Jobs and all associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Êtes-vous sûr de vouloir détruire?? !!!. Cette commande est utilisée pour détruire un enregistrement "volume" et tous les enregistrements associés du catalogue. Cette commande influe uniquement sur le catalogue et n'a pas d'effet sur les données écritessur un volume. Cette commande peut être dangereuse et nous vous recommandons fortement de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Tous les travaux et autres enregistrements associés (fichiers et supports) seront détruits du catalogue. Cliquer OK pour réaliser la destruction ? Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Press OK to proceed with the purge operation? Êtes-vous sûr de vouloir purger ?? !!!. La commande de purge va détruire les enregistrements du catalogue associés (travaux et volumes) sans prendre en compte la durée de rétention. La purge ne concerne que le catalogue et n'affecte pas les données écrites sur les volumes. Cette commande peut être dangereuse car vous pouvez détruire des enregistrements associés aux sauveardes actuelles, et nous vous recommandons de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Cliquer OK pour réaliser la purge? Volume Name Nom de volume Id Status État Enabled Activé Bytes Octets Files Fichiers Jobs Travaux Retention Rétention Media Type Type de support Slot Slot Use Duration Durée d'utilisation Max Jobs nb max de travaux Max Files nb max de fichiers Max Bytes nb max d'octets Recycle Recycler Last Written Dernière écriture Pools Groupes First Written Première écriture Read Time Temps de lecture Write Time Temps d'écriture Recycle Count Compteur de recyclage Recycle Pool Groupe de recyclage MediaListForm Media Tree Arbre des supports Refresh Media List Actualiser la liste des supports Requery the director for the list of media. Interroger le director pour la liste des supports. Edit Volume Éditer le volume List Jobs On Volume Lister les travaux du volume Delete Volume Détruire le volume Prune Volume Élaguer le volume (prune) Purge Volume Purger le volume Relabel Volume Ré-étiqueter le volume Update all Volumes From Pool Mettre à jour tous les volumes du groupe Update all Volumes from all Pools Mettre à jour tous les volumes de tous les groupes Volume From Pool Volumes du groupe MediaView Media Support Are you sure you want to purge ?? !!!. The Purge command will delete associated Catalog database records from Jobs and Volumes without considering the retention period. Purge works only on the Catalog database and does not affect data written to Volumes. This command can be dangerous because you can delete catalog records associated with current backups of files, and we recommend that you do not use it unless you know what you are doing. Press OK to proceed with the purge operation? Êtes-vous sûr de vouloir purger ?? !!!. La commande de purge va détruire les enregistrements du catalogue associés (travaux et volumes) sans prendre en compte la durée de rétention. La purge ne concerne que le catalogue et n'affecte pas les données écrites sur les volumes. Cette commande peut être dangereuse car vous pouvez détruire des enregistrements associés aux sauvegardes actuelles, et nous vous recommandons de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Cliquer OK pour réaliser la purge ? Are you sure you want to delete?? !!!. This delete command is used to delete a Volume record and all associated catalog records that were created. This command operates only on the Catalog database and has no effect on the actual data written to a Volume. This command can be dangerous and we strongly recommend that you do not use it unless you know what you are doing. All Jobs and all associated records (File and JobMedia) will be deleted from the catalog.Press OK to proceed with delete operation.? Êtes-vous sûr de vouloir détruire?? !!!. Cette commande est utilisée pour détruire un enregistrement "volume" et tous les enregistrements associés du catalogue. Cette commande influe uniquement sur le catalogue et n'a pas d'effet sur les données écritessur un volume. Cette commande peut être dangereuse et nous vous recommandons fortement de ne pas l'utiliser, sauf si vous savez exactement ce que vous faites. Tous les travaux et autres enregistrements associés (fichiers et supports) seront détruits du catalogue. Cliquer OK pour réaliser la destruction ? MediaViewForm Form Form Edit Éditer Purge Purger Delete Détruire Prune Élaguer (prune) Filter Filtre Media Type: Type de support : Status: État : Limit: Limite : Name: Nom : Pool: Groupe :Pool : Location: Lieu : Expired Expiré Apply Appliquer Volume Name Nom du volume Online Disponible Slot Emplacement Vol Bytes Octets Vol Usage Utilisation Vol Status ÉTAT Pool gROUPE Media Type Type de support Last Written Dernière écriture When expire? Expire le ? Pages %1 of Director %2 %1 du Director %2 UnDock %1 Window Déplacer %1 vers une nouvelle fenêtre ReDock %1 Window Remettre %1 en onglet Console Console PrefsForm Preferences Préférences Messages Messages Messages Options Options des Messages Message check interval in seconds Intervalle de vérification Check Messages Activer la vérification auto Joblist Travaux Joblist Limit Options Options de limitation sur Travaux Days Limit Limitation en jour Record Limit Limitation sur la taille Misc Autres Convert Conversion Convert Off Désactiver la conversion Convert Bytes with IEC 1000B = KB Convertir les octets avec IEC 1000B = KB Convert Bytes with 1024B = KB Convertir les octets avec 1024B = KB Context Sensitive List Commands Liste de commandes sensible au contexte Execute Long List Open Plot page on startup Open Browser page on startup Ouvrir l'onglet de navigation au démarrage Open Director Status page on startup Ouvrir l'onglet d'état du director au démarrage Debug Déboguer Debugging Options Options de débogage Debug comm Débogage communications avec le director Display all messages in console Afficher tous les messages dans la console Debug Commands Débogage des commandes Debug Sql queries Débogage des requêtes SQL Debug Miscelaneous Items Débogage divers RestoreTree Arbre de restauration Restore Debug 2 Directory Item Changed Restore Debug 1 Directory Current Item Changed Debug Update File Table Debug Version Table Item Changed Debug File Table Item Changed Debug Icon State Debug Update Checks Debug Restore Debug 3 Update Version Table Debug Populate Directory Debug <h2>Preferences</h2> <h2>Préférences</h2> Timers Sabliers Display Bytes using IEC units (1024B = 1 KiB) Afficher les octets avec les unités IEC (1 KiO = 1000 octets) Display Bytes using SI units (1000B = 1KB) Afficher les octets avec les unités SI (1 KO = 1000 octets) Open Pages Ouverture d'onglets Debug multiple connection QObject Any Tous No Non Yes Oui Invalid job status %1 État de travail invalide : %1 StorStat Storage Status %1 Etat du dépôt %1 Job Id Id du travail Job Level Niveau du Travail Job Files Fichiers Job Bytes Octets Job Status État Job Time Heure Job Name Nom StorStatForm Form Form Header Entête Waitreservation Attente de réservation Devices Lecteurs Volumes Volumes Spooling Running En cours Misc Autres Mount Monter UMount Démonter Label Étiquette Release Libérer Refresh Timer Sablier de rafraîchissement Do Refresh Activer le sablier <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Terminated Jobs</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:13pt; font-weight:600;">Travaux Terminés</span></p></body></html> Refresh Actualiser Cancel Running Job Annuler le travail en cours Disable Scheduled Job Désactiver le job planifié Storage Storage Dépôt Name Nom Id Id Changer Changeur Slot Emplacement Status État Enabled Activé Pool Groupe Media Type Type de support Yes Oui Status Storage "%1" État du dépôt "%1" Status Storage "%1" in Window État du dépôt "%1" (dans une fenêtre) Label media in Storage "%1" Étiqueter le support dans le dépôt "%1" Mount media in Storage "%1" Monter le support dans le dépôt "%1" "UN" Mount media in Storage "%1" Démonter le support dans le dépôt "%1" Release media in Storage "%1" Libérer le support dans le dépôt "%1" Barcode Scan media in Storage "%1" Scanner le code-barre du support dans le dépôt "%1" Read scan media in Storage "%1" Storage Status %1 État du dépôt %1 StorageForm Storage Tree Arbre des dépôts Refresh Storage List Rafraichir la liste Requery the director for the list of storage objects. Réinterroger le director pour la liste des dépôts. Status Storage In Console État du dépôt (dans la console) Label Storage Étiqueter le dépôt MountStorage Monter UnMount Storage Démonter Update Slots Mettre à jour les slots Update Slots Scan Mettre à jour les slots (scan) Release Relâcher 1 1 Status Storage Window État du dépôt (dans une fenêtre) bRestore bRestore b-Restauration bRestoreForm brestore brestore Type Type File Name Nom de fichier Size Taille Date Date InChanger dans changeur Volume Volume JobId Id du travail Chksum Somme de contrôle Clear Effacer Estimate Estimer Restore Restaurer FileName Nom de fichier FileIndex Position du fichier Nb Files Nb de fichiers Merge Jobs Fusionner les travaux View all Versions Voir toutes les versions Current Directory Dossier courant File list -- drag below for restore Liste des fichiers -- glisser en-dessous pour restaurer Double Click File Name to decend Double-cliquer le dossier pour y entrer, double-cliquer le fichier pour voir ses versions Double Click to decend Double-cliquer pour entrer Selection Range Rang de sélection - - File Filter Filtre de fichiers File revisions -- drag below for restore Versions de fichier -- glisser en-dessous pour restaurer <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Drag and drop <span style=" font-weight:600;">File list</span> and/or <span style=" font-weight:600;">File revisions</span> items here for Restore</p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Glisser et déplacer ici depuis <span style=" font-weight:600;">"Liste des fichiers"</span> et/ou depuis <span style=" font-weight:600;">"Versions de fichier"</span> les éléments à restaurer.</p></body></html> Select from Client list drop down then select from Job list drop down Choisir un élément dans la liste déroulante "Client List" puis dans la liste déroulante "Job list" bRunRestoreForm Run restore Lancer la restauration Standard Standard Restore options Options de restauration Client: Client : Where: Où : Replace: Remplacer : Comment: Commentaire : Media needed Supports nécessaires InChanger dans Changeur Volume Volume Compute with directories Advanced Avancé File Relocation Déplacement de fichiers Use file relocation: Utiliser Strip prefix: préfixe à supprimer : Add prefix: préfixe à ajouter : Add suffix: suffixe à ajouter : Use regexp: utiliser une "regexp" : Where regexp: "regexp" : Other options Autres options When: Quand : Priority: Priorité : Storage: Dépôt : Job: Travail : estimateForm Form Form List Files Lister les fichiers Level: Niveau : Client: Client : Job: Travail : FileSet: Jeu de fichiers : <h3>Estimate a backup Job</h3> <h3>Estimer un travail de sauvegarde</h3> OK OK Cancel Annuler estimatePage Estimate Estimer helpForm Form Form &Home &Accueil &Back &En arrière Close Fermer jobsForm Client Tree Arborescence Client Refresh Jobs List Actualiser la liste des travaux Requery the director for the list of clients. Interroger le director pour la liste des clients. List Files Command commande "list files" : liste des fichiers List Volumes Command commande "list volumes" : liste des volumes List Next Volume Command commande "next volume" : volume suivant Enable Job Command commande "enable job" : activer le travail Disable Job Command commande "disable job" : désactiver le travail Open JobList on Job Ouvrie la liste des exécutions de ce travail Cancel Job Command commande "cancel job" : annuler le travail RunJob Èxécuter ce travail labelForm Form Form OK OK Cancel Annuler Volume Name: Nom du volume : Storage: Dépôt : Slot: Emplacement : Execute Automount Montage automatique On Activer Off Désactiver Pool: Groupe : <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Label a Volume</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Étiqueter un volume</span></p></body></html> Enter Name of Volume to create Entrer le nom du volume à créer mediaEditForm Form Form Pool: Groupe : Volume Status: État du volume : Max Volume Bytes: Nb Max d'octets : Slot: Emplacement : Max Volume Jobs: Nb Max de Travaux : Use Duration: Durée d'utilisation : OK OK Cancel Annuler Recycle Pool: Groupe de recyclage : Enabled Activé Max Volume Files: nb max de fichiers : Years Années Seconds Secondes Use Duration Durée d'utilisation Days Jours Hours Heures Months Mois Retention Rétention Minutes Minutes Volume : Volume : Recycle Recycler <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Edit a Volume</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Éditer un Volume</span></p></body></html> Retention: Rétention : mediaInfoForm Form Form Edit Éditer Purge Purger Delete Supprimer Prune Élaguer (prune) Load Charger Unload Décharger Information Informations Name: Nom : Vol0001 Pool: Groupe : Default Online: Disponible : Enabled: Activé : yes Location: Lieu : Vault Status: État : Append Media Type: Type de support : File Recycle Pool: Groupe de recyclage : Scratch Statistics Statistiques Vol Bytes: Octets : 19.8 MB Vol Mounts: Montages : 10 10 Recycle count: Recyclages : 5 5 Read time: Temps de lecture : 10 mins Write time: Temps d'écriture : 20 mins Errors: Erreurs : 0 0 Last Written: Dernière écriture : 2009-07-05 12:23:00 2009-07-05 12:23:00 First Written: Première écriture : 2009-06-05 10:00:00 2009-06-05 10:00:00 Limits Limitations Use duration: Durée d'utilisation : Max jobs: Nb max de travaux : Max files: Nb max de fichiers : Max bytes: Nb max d'octets : Recycle: Recyclage : Retention: Rétention : 365 days Expire: Expire le : 2010-08-03 23:10:03 2010-08-03 23:10:03 Jobs Travaux JobId Id du travail Name Nom Start Time début le Type Type Level Niveau Files Fichiers Bytes Octets Status État mountDialog Storage : %1 Dépôt : %1 No Storage name Pas de nom de dépôt No Storage name given Pas de nom de dépôt indiqué Context sensitive command : Commande sensible au contexte : Director Response : Réponse du Director : mountForm Label Étiquette TextLabel TextLabel Slot: Emplacement : <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Mount a Slot</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Monter un emplacement</span></p></body></html> prefsDialog Canceled Annulé prerestoreForm Form Form All Files Tous les fichiers Select Files Fichiers sélectionnés Job Travail JobIds Travaux yyyy-mm-dd h:mm:ss aaaa-mm-jj h:mm:ss Use Most Recent Utiliser le plus récent File Set: File Set : Client: Client : Storage: Dépôt : Before: Avant : Pool: Pool : OK OK Cancel Annuler <h3>Select Jobs</h3> <h3>Sélectionner les Travaux</h3> prerestorePage Bat Bat There can be no spaces in the text for the joblist. Press OK to continue? Il ne peut pas y avoir d'espace dans la liste des travaux. Appuyer sur OK pour continuer ? At least one of the jobs is not a valid job of type "Backup". Press OK to continue? Il y a au moins un travail qui n'est pas du type "Backup" (Sauvegarde). Appuyer sur OK pour continuer ? All jobs in the list must be of the same jobName and same client. Press OK to continue? Tous les travaux de la liste doivent avoir le même nom et le même Client. Appuyer sur OK pour continuer ? Restore Restaurer Any Tous Comma separted list of Job Ids Liste de "id de travail" séparés par des virgules Canceled Annulé The string is not a comma separated list of integers. Press OK to continue? La chaine n'est pas une liste de nombres séparés par des virgules. Appuyer sur OK pour continuer ? pruneForm Form Form Prune Files Élaguer (Prune) les fichiers Volume: Volume : <h3>Prune Files/Jobs/Volumes</h3> <h3>Élaguer (Prune) les Fichiers/Travaux/Volumes</h3> Prune Jobs Élaguer (prune) les travaux OK OK Cancel Annuler Client: Client : Prune Volumes Élaguer (Pruner) les Volumes prunePage Prune Élaguer (prune) Any Tous Canceled Annulé relabelDialog From Volume : Volume : No Volume name Pas de nom de volume No Volume name given Pas de nom de Volume donné New name must be different Le nouveau nom doit être différent relabelForm Label Label From Volume : Ancien Volume : Pool: Pool : Storage: Dépôt : New Volume Name: Nouveau nom de Volume : Slot: Slot : <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Relabel a Volume</span></p></body></html> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Relabéliser un Volume</span></p></body></html> restoreForm Form Form 1 1 2 2 3 3 4 4 5 5 6 6 <h2>Directories</h2> <h2>Répertoires</h2> <h3>Restore Select</h3> <h3>Restaurer la sélection</h3> Up Dossier parent Mark Sélectionner Unmark Désélectionner <h2>Files</h2> <h2>Fichiers</h2> Status: État : Current Dir: Dossier courant : OK OK Cancel Annuler UnMark Désélectionner Select a Directory Choisir un dossier Directories Dossiers restorePage Restore Select Sélection pour restauration Mark Sélectionner File Fichier Mode Mode User Propriétaire Group Groupe Size Taille Date Date In else of if parent cwd "%1" newdir "%2" Dans le "else" du "if parent" cwd "%1" newdir "%2" Canceled Annulé In addDirectory cwd "%1" newdir "%2" fullpath "%3" Dans "addDirectory" cwd "%1" newdir "%2" fullpath "%3" Nothing selected, nothing done Rien de sélectionné, rien de fait cd command failed la commande cd a échoué .pwd command failed la commande ".pwd" a échoué restoreTree Version Browser Navigateur temporel Directories Dossiers Any Tous Refresh From JobChecks Rafraichir depuis JobChecks Task Taches Querying Database Interrogation en cours Querying Jobs Interrogation des travaux Querying for Directories Interrogation des dossiers Processing Directories Analyse des dossiers File Name Nom de fichier Filename Id Id du nom de fichier Job Id Type Type End Time Heure de fin Hash FileId FileId RestoreTreePage Onglet de l'arbre de restauration Level Niveau Name Nom Purged Purgé TU TD Refresh From Re-Select Task %1 of %2 Tâche %1 sur %2 No jobs were selected in the job query !!!. Press OK to continue La requête ne renvoie aucun travail !!! Cliquer OK pour continuer Present Working Directory: %1 Dossier de travail actuel : %1 Job Type Type de travail First Volume Premier volume Task 1 of 3 Tâche 1 sur 3 Processing Checked directories Traitement des dossiers Task 2 of 3 Tâche 2 sur 3 Processing Exceptions Traitement des exceptions Task 3 of 3 Tâche 3 sur 3 Filling Database Table Remplissage de la base de données restoreTreeForm Form Form Jobs Travaux TextLabel TextLabel Files Fichiers Versions of File Versions du fichier FileName Nom de fichier Refresh Actualiser Restore Restaurer Job Travail Job List Job Criterion Selector Job List Job Criterion Selector Client Client Job List Client Criterion Selector Job List Client Criterion Selector FileSet Jeu de fichiers Job List Fileset Criterion Selector Job List Fileset Criterion Selector Record Limit Limitation en nombre Days Limit Limitation en jour Directory Dossier Select Directory Sélectionner le dossier UnselectDirectory Désélectionner le dossier runCmdForm Form Form Priority: Priorité : yyyy-mm-dd hh:mm:ss aaaa-mm-jj hh:mm:ss When: Quand : Where: Ou : Bootstrap: Bootstrap : Job: Travail : Storage: Dépôt : FileSet: Jeu de fichiers : Replace: Remplacer : To client: Vers le client : Catalog: Catalogue : OK OK Cancel Annuler <h3>Run Restore Job</h3> <h3>Lancer la restauration</h3> runCmdPage Restore Run Restauration never jamais ... mais il faudrait retraduire dans okButtonPushed. never always toujours ... mais il faudrait retraduire dans okButtonPushed. always ifnewer si nouveau ... mais il faudrait retraduire dans okButtonPushed. si nouveau ifolder si plus vieux ... mais il faudrait retraduire dans okButtonPushed. si ancien Canceled Annulé runForm Form Form Level: Niveau : Bootstrap: Bootstrap : yyyy-mm-dd hh:mm:ss aaaa-mm-jj h:mm:ss Job: Travail : Pool: Groupe : Type: Type : <h3>Backup<h3/> <h3>Sauvegarde</h3> FileSet: Jeu de fichiers : Messages: Messages : <h3>Run a Job</h3> <h3>Lancer un Travail</h3> Priority: Priorité : Client: Client : OK OK Cancel Annuler Storage: Dépôt : When: Quand : Run job Lancer le travail Job properties Propriétés du travail runPage Run Lancer Canceled Annulé selectDialog Canceled Annulé selectForm Selection dialog Dialogue de sélection textInputDialog Canceled Annulé textInputForm Selection dialog Dialogue de sélection TextLabel TextLabel yesnoPopUp Bat Question Bat Question bareos-Release-14.2.6/src/qt-console/util/000077500000000000000000000000001263011562700202705ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-console/util/comboutil.cpp000066400000000000000000000106661263011562700230020ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * ComboBox helper functions * * Riccardo Ghetta, May 2008 */ #include "bat.h" #include #include #include #include "fmtwidgetitem.h" #include "comboutil.h" static const QString QS_ANY(QObject::tr("Any")); /* selects value val on combo, if exists */ void comboSel(QComboBox *combo, const QString &val) { int index = combo->findText(val, Qt::MatchExactly); if (index != -1) { combo->setCurrentIndex(index); } } /* if the combo has selected something different from "Any" uses the selection * to build a condition on field fldname and adds it to the condition list */ void comboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname) { int index = combo->currentIndex(); if (index != -1 && combo->itemText(index) != QS_ANY) { cndlist.append( QString("%1='%2'").arg(fldname).arg(combo->itemText(index)) ); } } /* boolean combo (yes/no) */ void boolComboFill(QComboBox *combo) { combo->addItem(QS_ANY, -1); combo->addItem(QObject::tr("No"), 0); combo->addItem(QObject::tr("Yes"), 1); } void boolComboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname) { int index = combo->currentIndex(); if (index != -1 && combo->itemData(index).toInt() >= 0 ) { QString cnd = combo->itemData(index).toString(); cndlist.append( QString("%1='%2'").arg(fldname).arg(cnd) ); } } /* backup level combo */ void levelComboFill(QComboBox *combo) { combo->addItem(QS_ANY); combo->addItem(job_level_to_str(L_FULL), L_FULL); combo->addItem(job_level_to_str(L_INCREMENTAL), L_INCREMENTAL); combo->addItem(job_level_to_str(L_DIFFERENTIAL), L_DIFFERENTIAL); combo->addItem(job_level_to_str(L_SINCE), L_SINCE); combo->addItem(job_level_to_str(L_VERIFY_CATALOG), L_VERIFY_CATALOG); combo->addItem(job_level_to_str(L_VERIFY_INIT), L_VERIFY_INIT); combo->addItem(job_level_to_str(L_VERIFY_VOLUME_TO_CATALOG), L_VERIFY_VOLUME_TO_CATALOG); combo->addItem(job_level_to_str(L_VERIFY_DISK_TO_CATALOG), L_VERIFY_DISK_TO_CATALOG); combo->addItem(job_level_to_str(L_VERIFY_DATA), L_VERIFY_DATA); /* combo->addItem(job_level_to_str(L_BASE), L_BASE); base jobs ignored */ } void levelComboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname) { int index = combo->currentIndex(); if (index != -1 && combo->itemText(index) != QS_ANY ) { QString cnd = combo->itemData(index).toChar(); cndlist.append( QString("%1='%2'").arg(fldname).arg(cnd) ); } } /* job status combo */ void jobStatusComboFill(QComboBox *combo) { static const char js[] = { JS_Terminated, JS_Warnings, JS_Created, JS_Running, JS_Blocked, JS_ErrorTerminated, JS_Error, JS_FatalError, JS_Differences, JS_Canceled, JS_WaitFD, JS_WaitSD, JS_WaitMedia, JS_WaitMount, JS_WaitStoreRes, JS_WaitJobRes, JS_WaitClientRes, JS_WaitMaxJobs, JS_WaitStartTime, JS_WaitPriority, JS_AttrDespooling, JS_AttrInserting, JS_DataDespooling, JS_DataCommitting, '\0'}; int pos; combo->addItem(QS_ANY); for (pos = 0 ; js[pos] != '\0' ; ++pos) { combo->addItem(convertJobStatus( QString(js[pos]) ), js[pos]); } } void jobStatusComboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname) { int index = combo->currentIndex(); if (index != -1 && combo->itemText(index) != QS_ANY ) { QString cnd = combo->itemData(index).toChar(); cndlist.append( QString("%1='%2'").arg(fldname).arg(cnd) ); } } bareos-Release-14.2.6/src/qt-console/util/comboutil.h000066400000000000000000000041111263011562700224330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Combobox helpers - Riccardo Ghetta, May 2008 */ #ifndef _COMBOUTIL_H_ #define _COMBOUTIL_H_ class QComboBox; class QString; class QStringList; /* selects value val on combo, if exists */ void comboSel(QComboBox *combo, const QString &val); /* if the combo has selected something different from "Any" uses the selection * to build a condition on field fldname and adds it to the condition list */ void comboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname); /* these helpers are used to give an uniform content to common combos. * There are two routines per combo type: * - XXXXComboFill fills the combo with values. * - XXXXComboCond checks the combo and, if selected adds a condition * on the field fldName to the list of conditions cndList */ /* boolean combo (yes/no) */ void boolComboFill(QComboBox *combo); void boolComboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname); /* backup level combo */ void levelComboFill(QComboBox *combo); void levelComboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname); /* job status combo */ void jobStatusComboFill(QComboBox *combo); void jobStatusComboCond(QStringList &cndlist, const QComboBox *combo, const char *fldname); #endif /* _COMBOUTIL_H_ */ bareos-Release-14.2.6/src/qt-console/util/fmtwidgetitem.cpp000066400000000000000000000342421263011562700236520ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Helper functions for tree widget formatting * * Riccardo Ghetta, May 2008 */ #include "bat.h" #include #include #include #include #include #include #include #include "fmtwidgetitem.h" /*********************************************** * * common helpers * ***********************************************/ QString convertJobStatus(const QString &sts) { QString code( sts.trimmed() ); if ( code.size() != 1) { return QObject::tr("Invalid job status %1").arg(sts); } char buf[256]; jobstatus_to_ascii_gui( code[0].toAscii(), buf, sizeof(buf)); return QString(buf); } /* * disable widget updating */ Freeze::Freeze(QWidget &q): qw(&q) { qw->setUpdatesEnabled(false); } Freeze::~Freeze() { if (qw) { qw->setUpdatesEnabled(true); qw->update(); } } /*********************************************** * * ItemFormatterBase static members * ***********************************************/ ItemFormatterBase::BYTES_CONVERSION ItemFormatterBase::cnvFlag(BYTES_CONVERSION_IEC); /* String to Electronic value based on K=1024 */ QString convertBytesIEC(qint64 qfld) { static const qint64 KB = Q_INT64_C(1024); static const qint64 MB = (KB * KB); static const qint64 GB = (MB * KB); static const qint64 TB = (GB * KB); static const qint64 PB = (TB * KB); static const qint64 EB = (PB * KB); /* note: division is integer, so to have some decimals we divide for a smaller unit (e.g. GB for a TB number and so on) */ char suffix; if (qfld >= EB) { qfld /= PB; suffix = 'E'; } else if (qfld >= PB) { qfld /= TB; suffix = 'P'; } else if (qfld >= TB) { qfld /= GB; suffix = 'T'; } else if (qfld >= GB) { qfld /= MB; suffix = 'G'; } else if (qfld >= MB) { qfld /= KB; suffix = 'M'; } else if (qfld >= KB) { suffix = 'K'; } else { /* plain bytes, no need to reformat */ return QString("%1 B").arg(qfld); } /* having divided for a smaller unit, now we can safely convert to double and use the extra room for decimals */ return QString("%1 %2iB").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix); } /* String to human value based on k=1000 */ QString convertBytesSI(qint64 qfld) { static const qint64 KB = Q_INT64_C(1000); static const qint64 MB = (KB * KB); static const qint64 GB = (MB * KB); static const qint64 TB = (GB * KB); static const qint64 PB = (TB * KB); static const qint64 EB = (PB * KB); /* note: division is integer, so to have some decimals we divide for a smaller unit (e.g. GB for a TB number and so on) */ char suffix; if (qfld >= EB) { qfld /= PB; suffix = 'E'; } else if (qfld >= PB) { qfld /= TB; suffix = 'P'; } else if (qfld >= TB) { qfld /= GB; suffix = 'T'; } else if (qfld >= GB) { qfld /= MB; suffix = 'G'; } else if (qfld >= MB) { qfld /= KB; suffix = 'M'; } else if (qfld >= KB) { suffix = 'k'; /* SI uses lowercase k */ } else { /* plain bytes, no need to reformat */ return QString("%1 B").arg(qfld); } /* having divided for a smaller unit, now we can safely convert to double and use the extra room for decimals */ return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix); } /*********************************************** * * base formatting routines * ***********************************************/ ItemFormatterBase::ItemFormatterBase() { } ItemFormatterBase::~ItemFormatterBase() { } void ItemFormatterBase::setPercent(int index, float value) { char buf[100]; bsnprintf(buf, sizeof(buf), "%.2f%%", value); QString val = buf; QString pix; if (value < 8) { pix = ":images/0p.png"; } else if (value < 24) { pix = ":images/16p.png"; } else if (value < 40) { pix = ":images/32p.png"; } else if (value < 56) { pix = ":images/48p.png"; } else if (value < 72) { pix = ":images/64p.png"; } else if (value < 88) { pix = ":images/80p.png"; } else { pix = ":images/96p.png"; } setPixmap(index, QPixmap(pix), val); //setSortValue(index, (int) value); //setBackground(index, Qt::green); } /* By default, the setPixmap implementation with tooltip don't implement * the tooltip stuff */ void ItemFormatterBase::setPixmap(int index, const QPixmap &pix, const QString & /* tip */) { setPixmap(index, pix); } void ItemFormatterBase::setInChanger(int index, const QString &InChanger) { setPixmap(index, QPixmap(":images/inflag"+InChanger+".png")); //setSortValue(index, InChanger.toInt() ); } void ItemFormatterBase::setFileType(int index, const QString &type) { setPixmap(index, QPixmap(":images/"+type+".png")); //setSortValue(index, InChanger.toInt() ); } void ItemFormatterBase::setTextFld(int index, const QString &fld, bool center) { setText(index, fld.trimmed()); if (center) { setTextAlignment(index, Qt::AlignCenter); } } void ItemFormatterBase::setDateFld(int index, utime_t fld, bool center) { char buf[200]; bstrutime(buf, sizeof(buf), fld); setText(index, QString(buf).trimmed()); if (center) { setTextAlignment(index, Qt::AlignCenter); } } void ItemFormatterBase::setRightFld(int index, const QString &fld) { setText(index, fld.trimmed()); setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter); } void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center) { if (fld.trimmed().toInt()) setTextFld(index, QObject::tr("Yes"), center); else setTextFld(index, QObject::tr("No"), center); } void ItemFormatterBase::setBoolFld(int index, int fld, bool center) { if (fld) setTextFld(index, QObject::tr("Yes"), center); else setTextFld(index, QObject::tr("No"), center); } void ItemFormatterBase::setNumericFld(int index, const QString &fld) { setRightFld(index, fld.trimmed()); setSortValue(index, fld.toDouble()); } void ItemFormatterBase::setNumericFld(int index, const QString &fld, const QVariant &sortval) { setRightFld(index, fld.trimmed()); setSortValue(index, sortval); } void ItemFormatterBase::setBytesFld(int index, const QString &fld) { qint64 qfld = fld.trimmed().toLongLong(); QString msg; switch (cnvFlag) { case BYTES_CONVERSION_NONE: msg = QString::number(qfld); break; case BYTES_CONVERSION_IEC: msg = convertBytesIEC(qfld); break; case BYTES_CONVERSION_SI: msg = convertBytesSI(qfld); break; default: msg = " "; break; } setNumericFld(index, msg, QVariant(qfld)); } void ItemFormatterBase::setDurationFld(int index, const QString &fld) { static const qint64 HOUR = Q_INT64_C(3600); static const qint64 DAY = HOUR * 24; static const qint64 WEEK = DAY * 7; static const qint64 MONTH = DAY * 30; static const qint64 YEAR = DAY * 365; static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR }; static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' }; qint64 dfld = fld.trimmed().toLongLong(); char suffix = 's'; if (dfld) { for (int pos = 0 ; sufs[pos] ; ++pos) { if (dfld % divs[pos] == 0) { dfld /= divs[pos]; suffix = sufs[pos]; break; } } } QString msg; if (dfld < 100) { msg = QString("%1%2").arg(dfld).arg(suffix); } else { /* previous check returned a number too big. The original specification perhaps was mixed, like 1d 2h, so we try to match with this routine */ dfld = fld.trimmed().toLongLong(); msg = ""; for (int pos = 0 ; sufs[pos] ; ++pos) { if (dfld / divs[pos] != 0) { msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]); dfld %= divs[pos]; } } if (dfld) msg += QString(" %1s").arg(dfld); } setNumericFld(index, msg, QVariant(fld.trimmed().toLongLong())); } void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center) { QString mp(fld.trimmed()); setTextFld(index, volume_status_to_str(mp.toUtf8()), center); if (mp == "Append" ) { setBackground(index, Qt::green); } else if (mp == "Error") { setBackground(index, Qt::red); } else if (mp == "Used" || mp == "Full"){ setBackground(index, Qt::yellow); } else if (mp == "Read-only" || mp == "Disabled"){ setBackground(index, Qt::lightGray); } } void ItemFormatterBase::setJobStatusFld(int index, const QString &status, bool center) { /* C (created, not yet running) uses the default background */ static QString greenchars("TR"); static QString redchars("BEf"); static QString yellowchars("eDAFSMmsjdctp"); setTextFld(index, convertJobStatus(status), center); QString st(status.trimmed()); if (greenchars.contains(st, Qt::CaseSensitive)) { setBackground(index, Qt::green); } else if (redchars.contains(st, Qt::CaseSensitive)) { setBackground(index, Qt::red); } else if (yellowchars.contains(st, Qt::CaseSensitive)){ setBackground(index, Qt::yellow); } } void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center) { QByteArray jtype(fld.trimmed().toAscii()); if (jtype.size()) { setTextFld(index, job_type_to_str(jtype[0]), center); } else { setTextFld(index, "", center); } } void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center) { QByteArray lvl(fld.trimmed().toAscii()); if (lvl.size()) { setTextFld(index, job_level_to_str(lvl[0]), center); } else { setTextFld(index, "", center); } } /*********************************************** * * treeitem formatting routines * ***********************************************/ TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level): ItemFormatterBase(), wdg(new QTreeWidgetItem(&parent)), level(indent_level) { } void TreeItemFormatter::setText(int index, const QString &fld) { wdg->setData(index, Qt::UserRole, level); wdg->setText(index, fld); } void TreeItemFormatter::setTextAlignment(int index, int align) { wdg->setTextAlignment(index, align); } void TreeItemFormatter::setBackground(int index, const QBrush &qb) { wdg->setBackground(index, qb); } /* at this time we don't sort trees, so this method does nothing */ void TreeItemFormatter::setSortValue(int /* index */, const QVariant & /* value */) { } void TreeItemFormatter::setPixmap(int index, const QPixmap &pix) { wdg->setIcon(index, QIcon(pix)); } /*********************************************** * * Specialized table widget used for sorting * ***********************************************/ TableItemFormatter::BatSortingTableItem::BatSortingTableItem(): QTableWidgetItem(1) { } void TableItemFormatter::BatSortingTableItem::setSortData(const QVariant &d) { setData(SORTDATA_ROLE, d); } bool TableItemFormatter::BatSortingTableItem::operator< ( const QTableWidgetItem & o ) const { QVariant my = data(SORTDATA_ROLE); QVariant other = o.data(SORTDATA_ROLE); if (!my.isValid() || !other.isValid() || my.type() != other.type()) return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */ /* 64bit integers must be handled separately, others can be converted to double */ if (QVariant::ULongLong == my.type()) { return my.toULongLong() < other.toULongLong(); } else if (QVariant::LongLong == my.type()) { return my.toLongLong() < other.toLongLong(); } else if (my.canConvert(QVariant::Double)) { return my.toDouble() < other.toDouble(); } else { return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */ } } /*********************************************** * * tableitem formatting routines * ***********************************************/ TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow): ItemFormatterBase(), parent(&tparent), row(trow), last(NULL) { } void TableItemFormatter::setPixmap(int index, const QPixmap &pix) { // Centered, but not sortable ! QLabel *lbl = new QLabel(); lbl->setAlignment(Qt::AlignCenter); lbl->setPixmap(pix); parent->setCellWidget(row, index, lbl); } void TableItemFormatter::setPixmap(int index, const QPixmap &pix, const QString &tips) { // Centered, but not sortable ! QLabel *lbl = new QLabel(); lbl->setAlignment(Qt::AlignCenter); lbl->setPixmap(pix); if (!tips.isEmpty()) { lbl->setToolTip(tips); } parent->setCellWidget(row, index, lbl); // last = new BatSortingTableItem; // parent->setItem(row, index, last); // last->setIcon(pix); } void TableItemFormatter::setText(int col, const QString &fld) { last = new BatSortingTableItem; parent->setItem(row, col, last); last->setText(fld); } void TableItemFormatter::setTextAlignment(int /*index*/, int align) { last->setTextAlignment(align); } void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb) { last->setBackground(qb); } void TableItemFormatter::setSortValue(int /* index */, const QVariant &value ) { last->setSortData(value); } QTableWidgetItem *TableItemFormatter::widget(int col) { return parent->item(row, col); } const QTableWidgetItem *TableItemFormatter::widget(int col) const { return parent->item(row, col); } bareos-Release-14.2.6/src/qt-console/util/fmtwidgetitem.h000066400000000000000000000150661263011562700233220ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * TreeView formatting helpers - Riccardo Ghetta, May 2008 */ #ifndef _FMTWIDGETITEM_H_ #define _FMTWIDGETITEM_H_ class QWidget; class QTreeWidgetItem; class QTableWidget; class QTableWidgetItem; class QString; class QBrush; /* * common conversion routines * */ QString convertJobStatus(const QString &sts); /* bytes formatted as power-of-two with IEC suffixes (KiB, MiB, and so on) */ QString convertBytesIEC(qint64 fld); /* bytes formatted as power-of-ten with SI suffixes (kB, MB, and so on) */ QString convertBytesSI(qint64 fld); /* * disable widget updating */ class Freeze { private: QWidget *qw; public: Freeze(QWidget &q); ~Freeze(); }; /* * base class for formatters * */ class ItemFormatterBase { public: enum BYTES_CONVERSION { BYTES_CONVERSION_NONE, BYTES_CONVERSION_IEC, BYTES_CONVERSION_SI }; public: virtual ~ItemFormatterBase(); /* Prints Yes if fld is != 0, No otherwise. Centers field if center true*/ void setBoolFld(int index, const QString &fld, bool center = true); void setBoolFld(int index, int fld, bool center = true); /* Print nice icon to represent percent */ void setPercent(int index, float number); /* Normal text field. Centers field if center true*/ void setTextFld(int index, const QString &fld, bool center = false); /* Normal date field. Centers field if center true*/ void setDateFld(int index, utime_t fld, bool center = false); /* Right-aligned text field. */ void setRightFld(int index, const QString &fld); /* Numeric field - sorted as numeric type */ void setNumericFld(int index, const QString &fld); void setNumericFld(int index, const QString &fld, const QVariant &sortVal); /* fld value interpreted as bytes and formatted with size suffixes */ void setBytesFld(int index, const QString &fld); /* fld value interpreted as seconds and formatted with y,m,w,h suffixes */ void setDurationFld(int index, const QString &fld); /* fld value interpreted as volume status. Colored accordingly */ void setVolStatusFld(int index, const QString &fld, bool center = true); /* fld value interpreted as job status. Colored accordingly */ void setJobStatusFld(int index, const QString &status, bool center = true); /* fld value interpreted as job type. */ void setJobTypeFld(int index, const QString &fld, bool center = false); /* fld value interpreted as job level. */ void setJobLevelFld(int index, const QString &fld, bool center = false); /* fld value interpreted as Online/Offline */ void setInChanger(int index, const QString &InChanger); /* fld value interpreted as file or folder */ void setFileType(int index, const QString &type); static void setBytesConversion(BYTES_CONVERSION b) { cnvFlag = b; } static BYTES_CONVERSION getBytesConversion() { return cnvFlag; } protected: /* only derived classes can create one of these */ ItemFormatterBase(); virtual void setText(int index, const QString &fld) = 0; virtual void setTextAlignment(int index, int align) = 0; virtual void setBackground(int index, const QBrush &) = 0; virtual void setPixmap(int index, const QPixmap &pix) = 0; virtual void setPixmap(int index, const QPixmap &pix, const QString &tip); /* sets the *optional* value used for sorting */ virtual void setSortValue(int index, const QVariant &value) = 0; private: static BYTES_CONVERSION cnvFlag; }; /* * This class can be used instead of QTreeWidgetItem (it allocates one internally, * to format data fields. * All setXXXFld routines receive a column index and the unformatted string value. */ class TreeItemFormatter : public ItemFormatterBase { public: TreeItemFormatter(QTreeWidgetItem &parent, int indent_level); /* access internal widget */ QTreeWidgetItem *widget() { return wdg; } const QTreeWidgetItem *widget() const { return wdg; } protected: virtual void setText(int index, const QString &fld); virtual void setTextAlignment(int index, int align); virtual void setBackground(int index, const QBrush &); virtual void setSortValue(int index, const QVariant &value); virtual void setPixmap(int index, const QPixmap &pix); private: QTreeWidgetItem *wdg; int level; }; /* * This class can be used instead of QTableWidgetItem (it allocates one internally, * to format data fields. * All setXXXFld routines receive the column and the unformatted string value. */ class TableItemFormatter : public ItemFormatterBase { private: /* specialized widget item - allows an optional data property for sorting */ class BatSortingTableItem : public QTableWidgetItem { private: static const int SORTDATA_ROLE = Qt::UserRole + 100; public: BatSortingTableItem(); /* uses the sort data if available, reverts to default behavior othervise */ virtual bool operator< ( const QTableWidgetItem & o ) const; /* set the value used for sorting - MUST BE A NUMERIC TYPE */ void setSortData(const QVariant &d); }; public: TableItemFormatter(QTableWidget &parent, int row); /* access internal widget at column col*/ QTableWidgetItem *widget(int col); const QTableWidgetItem *widget(int col) const; protected: virtual void setText(int index, const QString &fld); virtual void setTextAlignment(int index, int align); virtual void setBackground(int index, const QBrush &); virtual void setSortValue(int index, const QVariant &value); virtual void setPixmap(int index, const QPixmap &pix); virtual void setPixmap(int index, const QPixmap &pix, const QString &tip); private: QTableWidget *parent; int row; BatSortingTableItem *last; }; #endif /* _FMTWIDGETITEM_H_ */ bareos-Release-14.2.6/src/qt-tray-monitor/000077500000000000000000000000001263011562700203155ustar00rootroot00000000000000bareos-Release-14.2.6/src/qt-tray-monitor/authenticate.cpp000066400000000000000000000160261263011562700235040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos authentication. Provides authentication with File and Storage daemons. * * Nicolas Boichat, August MMIV */ #include "monitoritem.h" #include "authenticate.h" #include "jcr.h" #include "monitoritemthread.h" /* Commands sent to Director */ static char DIRhello[] = "Hello %s calling\n"; /* Response from Director */ static char DIROKhello[] = "1000 OK:"; /* Commands sent to Storage daemon and File daemon and received * from the User Agent */ static char SDFDhello[] = "Hello Director %s calling\n"; /* Response from SD */ static char SDOKhello[] = "3000 OK Hello\n"; /* Response from FD */ static char FDOKhello[] = "2000 OK Hello"; /* Forward referenced functions */ /* * Authenticate Director */ static bool authenticate_director(JCR *jcr) { const MONITORRES *monitor = MonitorItemThread::instance()->getMonitor(); BSOCK *dir = jcr->dir_bsock; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; char bashed_name[MAX_NAME_LENGTH]; bstrncpy(bashed_name, monitor->hdr.name, sizeof(bashed_name)); bash_spaces(bashed_name); /* * Timeout Hello after 5 mins */ btimer_t *tid = start_bsock_timer(dir, 60 * 5); dir->fsend(DIRhello, bashed_name); ASSERT(monitor->password.encoding == p_encoding_md5); if (!cram_md5_respond(dir, monitor->password.value, &tls_remote_need, &compatible) || !cram_md5_challenge(dir, monitor->password.value, tls_local_need, compatible)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Director authorization problem.\n" "Most likely the passwords do not agree.\n" "Please see %s for help.\n"), MANUAL_AUTH_URL); return false; } Dmsg1(6, ">dird: %s", dir->msg); if (dir->recv() <= 0) { stop_bsock_timer(tid); Jmsg1(jcr, M_FATAL, 0, _("Bad response to Hello command: ERR=%s\n"), dir->bstrerror()); return false; } Dmsg1(10, "msg); stop_bsock_timer(tid); if (strncmp(dir->msg, DIROKhello, sizeof(DIROKhello)-1) != 0) { Jmsg0(jcr, M_FATAL, 0, _("Director rejected Hello command\n")); return false; } else { Jmsg0(jcr, M_INFO, 0, dir->msg); } return true; } /* * Authenticate Storage daemon connection */ static bool authenticate_storage_daemon(JCR *jcr, STORERES* store) { const MONITORRES *monitor = MonitorItemThread::instance()->getMonitor(); BSOCK *sd = jcr->store_bsock; char dirname[MAX_NAME_LENGTH]; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; /* * Send my name to the Storage daemon then do authentication */ bstrncpy(dirname, monitor->hdr.name, sizeof(dirname)); bash_spaces(dirname); /* * Timeout Hello after 5 mins */ btimer_t *tid = start_bsock_timer(sd, 60 * 5); if (!sd->fsend(SDFDhello, dirname)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), bnet_strerror(sd)); return false; } ASSERT(store->password.encoding == p_encoding_md5); if (!cram_md5_respond(sd, store->password.value, &tls_remote_need, &compatible) || !cram_md5_challenge(sd, store->password.value, tls_local_need, compatible)) { stop_bsock_timer(tid); Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords or names not the same.\n" "Please see " MANUAL_AUTH_URL " for help.\n")); return false; } Dmsg1(116, ">stored: %s", sd->msg); if (sd->recv() <= 0) { stop_bsock_timer(tid); Jmsg1(jcr, M_FATAL, 0, _("bdirdbstrerror()); return false; } Dmsg1(110, "msg); stop_bsock_timer(tid); if (strncmp(sd->msg, SDOKhello, sizeof(SDOKhello)) != 0) { Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n")); return false; } return true; } /* * Authenticate File daemon connection */ static bool authenticate_file_daemon(JCR *jcr, CLIENTRES* client) { const MONITORRES *monitor = MonitorItemThread::instance()->getMonitor(); BSOCK *fd = jcr->file_bsock; char dirname[MAX_NAME_LENGTH]; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; /* * Send my name to the File daemon then do authentication */ bstrncpy(dirname, monitor->hdr.name, sizeof(dirname)); bash_spaces(dirname); /* * Timeout Hello after 5 mins */ btimer_t *tid = start_bsock_timer(fd, 60 * 5); if (!fd->fsend(SDFDhello, dirname)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd)); return false; } ASSERT(client->password.encoding == p_encoding_md5); if (!cram_md5_respond(fd, client->password.value, &tls_remote_need, &compatible) || !cram_md5_challenge(fd, client->password.value, tls_local_need, compatible)) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords or names not the same.\n" "Please see %s for help.\n"), MANUAL_AUTH_URL); return false; } Dmsg1(116, ">filed: %s", fd->msg); if (fd->recv() <= 0) { stop_bsock_timer(tid); Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"), fd->bstrerror()); return false; } Dmsg1(110, "msg); stop_bsock_timer(tid); if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)-1) != 0) { Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n")); return false; } return true; } bool authenticate_daemon(MonitorItem* item, JCR *jcr) { switch (item->type()) { case R_DIRECTOR: return authenticate_director(jcr); case R_CLIENT: return authenticate_file_daemon(jcr, (CLIENTRES*)item->resource()); case R_STORAGE: return authenticate_storage_daemon(jcr, (STORERES*)item->resource()); default: printf(_("Error, currentitem is not a Client or a Storage..\n")); return false; } return false; } bareos-Release-14.2.6/src/qt-tray-monitor/authenticate.h000066400000000000000000000003141263011562700231420ustar00rootroot00000000000000#ifndef AUTHENTICATE_H_INCLUDED #define AUTHENTICATE_H_INCLUDED class MONITORRES; class MonitorItem; class JCR; bool authenticate_daemon(MonitorItem *item, JCR *jcr); #endif // AUTHENTICATE_H_INCLUDED bareos-Release-14.2.6/src/qt-tray-monitor/bareos-tray-monitor.desktop.in000066400000000000000000000004741263011562700262370ustar00rootroot00000000000000[Desktop Entry] X-SuSE-translate=true Name=Bareos Tray Monitor GenericName=Backup Tray Monitor Comment=Notification Tray Monitor Icon=bareos-tray-monitor Exec=@bindir@/bareos-tray-monitor -c @sysconfdir@/tray-monitor.conf Terminal=false Type=Application Categories=System;Utility;Archiving;X-SuSE-Backup; #TrayIcon; bareos-Release-14.2.6/src/qt-tray-monitor/bareos-tray-monitor.xpm000066400000000000000000000067541263011562700247740ustar00rootroot00000000000000/* XPM */ static char * tray_monitor_xpm[] = { "22 22 153 2", " c None", ". c #354446", "+ c #3D4F51", "@ c #648B90", "# c #536E72", "$ c #1D1D1D", "% c #1E1F1F", "& c #3A4B4D", "* c #61878C", "= c #252A2B", "- c #1D1E1E", "; c #364648", "> c #5C8185", ", c #3E4E51", "' c #344345", ") c #577C80", "! c #5F7C81", "~ c #1C1C1C", "{ c #1D1D1E", "] c #313F40", "^ c #53787C", "/ c #272B2C", "( c #141414", "_ c #181818", ": c #2D3A3C", "< c #4E7276", "[ c #46585C", "} c #0A0A0A", "| c #040404", "1 c #342F2F", "2 c #171515", "3 c #191919", "4 c #2B3738", "5 c #4B6F72", "6 c #6A898F", "7 c #4F4B4D", "8 c #B8CED9", "9 c #A3AAB1", "0 c #0A0909", "a c #0F0F0F", "b c #1C1B1B", "c c #283435", "d c #323B3C", "e c #090909", "f c #6B696D", "g c #B6C8D3", "h c #191616", "i c #282222", "j c #222222", "k c #344042", "l c #4F6368", "m c #1A1818", "n c #787E84", "o c #555255", "p c #342E2E", "q c #363636", "r c #2E2E2E", "s c #1F1F1F", "t c #1C1D1D", "u c #455152", "v c #2D3536", "w c #1C1C1D", "x c #151515", "y c #0D0B0B", "z c #433E3E", "A c #3B3A3A", "B c #1E1E1F", "C c #333C3D", "D c #546E71", "E c #3E3E3F", "F c #343638", "G c #272D2F", "H c #302C2C", "I c #888D92", "J c #B8CCD7", "K c #797C81", "L c #2A2A2A", "M c #454F50", "N c #608F95", "O c #536367", "P c #474646", "Q c #797575", "R c #3E4243", "S c #242829", "T c #2C2C2C", "U c #A4ADB4", "V c #979FA6", "W c #2B2B2B", "X c #212424", "Y c #4F5F61", "Z c #6C8B92", "` c #67696A", " . c #989292", ".. c #6C6969", "+. c #363C3D", "@. c #1F2122", "#. c #202020", "$. c #585A5D", "%. c #9DA6AD", "&. c #5D5D60", "*. c #2F2F2F", "=. c #414C4E", "-. c #5A8084", ";. c #5F777B", ">. c #717071", ",. c #999393", "'. c #615E5F", "). c #2F3738", "!. c #303030", "~. c #323232", "{. c #485253", "]. c #5B6B6E", "^. c #7F797A", "/. c #948E8E", "(. c #545455", "_. c #272E2F", ":. c #353E3F", "<. c #577476", "[. c #709BA1", "}. c #5C6567", "|. c #8D8889", "1. c #878282", "2. c #484B4B", "3. c #232828", "4. c #475152", "5. c #62878C", "6. c #636667", "7. c #9B9494", "8. c #797475", "9. c #3C4344", "0. c #1F2222", "a. c #262B2B", "b. c #516465", "c. c #597679", "d. c #6C6C6D", "e. c #9E9A9A", "f. c #6B6868", "g. c #333A3B", "h. c #424D4D", "i. c #5C8689", "j. c #55696B", "k. c #7A7777", "l. c #9D9898", "m. c #4E5050", "n. c #262F2F", "o. c #4A5556", "p. c #64979A", "q. c #566263", "r. c #535050", "s. c #383D3D", "t. c #58797B", "u. c #5B8789", "v. c #374748", " . + @ ", " # $ $ % & * ", " = $ $ $ $ - ; > ", " , $ $ $ $ $ $ $ - ' ) ", " ! ~ $ $ $ $ $ $ $ $ $ { ] ^ ", " / $ ( _ $ $ $ $ $ $ $ $ $ $ : < ", " [ $ } | 1 2 3 $ $ $ $ $ $ $ $ $ $ 4 5 ", " 6 % 3 | 7 8 9 0 a b $ $ $ $ $ $ $ $ $ $ c ", " d $ $ e f 8 g h | i j ~ $ $ $ $ $ $ $ $ k ", "l $ $ $ _ m n o | | p q r s ~ $ $ $ $ $ t u ", "v w $ $ $ $ x e | y z q q q A B $ $ $ $ C D ", "E F G $ $ $ $ $ x H q q q I J K L t $ $ M N ", "O P Q R S $ $ $ $ $ { T q U 8 V q W $ X Y ", " Z ` ...+.@.$ $ $ $ w #.$.%.&.q *.~ =.-. ", " ;.>.,.'.).{ $ $ $ $ w j !.~.- - {. ", " ].^./.(._.$ $ $ $ $ ~ ~ $ :.<. ", " [.}.|.1.2.3.$ $ $ $ $ $ 4. ", " 5.6.7.8.9.0.$ $ $ a.b. ", " c.d.e.f.g.- $ h.i. ", " j.k.l.m.n.o. ", " p.q.r.s.t. ", " u.v. "}; bareos-Release-14.2.6/src/qt-tray-monitor/main.qrc000066400000000000000000000004071263011562700217510ustar00rootroot00000000000000 ../images/f.png ../images/W.png ../images/bareos_1.png ../images/bareos_2.png ../images/bareos_3.png bareos-Release-14.2.6/src/qt-tray-monitor/mainwindow.cpp000066400000000000000000000131051263011562700231750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mainwindow.h" #include "ui_mainwindow.h" #include "systemtrayicon.h" #include #include #include #include #include #include "tray-monitor.h" #include "monitoritemthread.h" #include "monitoritem.h" #include "monitortab.h" MainWindow* MainWindow::mainWindowSingleton = NULL; bool MainWindow::already_destroyed = false; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , monitorTabMap(new QMap) , systemTrayIcon(new SystemTrayIcon(this)) { /* Init the SystemTrayIcon first to have all its signals * configured to be auto-connected via connectSlotsByName(MainWindow) * during ui->setupUi(this). */ Q_ASSERT(systemTrayIcon->objectName() == "SystemTrayIcon"); // This will setup the tab-window and auto-connect signals and slots. ui->setupUi(this); setWindowTitle(tr("Bareos Tray Monitor")); setWindowIcon(QIcon(":images/bareos_1.png")); ui->pushButton_Close->setIcon(QIcon(":images/f.png")); // Prepare the tabWidget while (ui->tabWidget->count()) { ui->tabWidget->removeTab(0); } bRefs = new bool[nTabs]; for(int i=0; ishow(); } MainWindow::~MainWindow() { delete ui; delete monitorTabMap; delete bRefs; } MainWindow* MainWindow::instance() { // improve that the MainWindow is created // and deleted only once during program execution Q_ASSERT(!already_destroyed); if (!mainWindowSingleton) { mainWindowSingleton = new MainWindow; } return mainWindowSingleton; } void MainWindow::destruct() { if (mainWindowSingleton) { delete mainWindowSingleton; mainWindowSingleton = NULL; } } void MainWindow::addTabs(QStringList tabRefs) { tabs = tabRefs; // nTabs = tabRefs.size(); for (int i = 0; i < tabRefs.count(); i++) { MonitorTab* tab = new MonitorTab(tabRefs[i], this); monitorTabMap->insert(tabRefs[i], tab); //tabRefs[i] used as reference ui->tabWidget->addTab(tab->getTabWidget(), tabRefs[i]); } } void MainWindow::on_TrayMenu_About_triggered() { QString fmt = QString("

Bareos Tray Monitor %1

" "

For more information, see: www.bareos.com" "

Copyright © 2004-2011 Free Software Foundation Europe e.V." "

Copyright © 2011-2012 Planets Communications B.V." "

Copyright © 2013-%2 Bareos GmbH & Co. KG" "

BAREOS ® is a registered trademark of Bareos GmbH & Co. KG" "

Licensed under GNU AGPLv3.").arg(VERSION).arg(BYEAR); QMessageBox::about(this, tr("About Bareos Tray Monitor"), fmt); } void MainWindow::on_TrayMenu_Quit_triggered() { QApplication::quit(); } void MainWindow::on_TrayMenu_Display_triggered() { if (isVisible()) { hide(); } else { show(); raise(); emit refreshItems(); } } void MainWindow::on_SystemTrayIcon_activated(QSystemTrayIcon::ActivationReason r) { if (r == QSystemTrayIcon::Trigger) { on_TrayMenu_Display_triggered(); } } void MainWindow::on_pushButton_Close_clicked() { hide(); } QPlainTextEdit* MainWindow::getTextEdit(const QString& tabRef) { MonitorTab* tab = monitorTabMap->value(tabRef); return (tab) ? tab->getTextEdit() : 0; } void MainWindow::onClearText(const QString& tabRef) { QPlainTextEdit *w = getTextEdit(tabRef); if (w) { w->clear(); } } void MainWindow::onAppendText(QString tabRef, QString line) { QPlainTextEdit *w = getTextEdit(tabRef); if (w) { w->appendPlainText(line); } } void MainWindow::onShowStatusbarMessage(QString message) { ui->statusbar->showMessage(message, 3000); } void MainWindow::onStatusChanged(const QString &tabRef, int state) { int n = tabs.indexOf(tabRef); MonitorTab* tab = monitorTabMap->value(tabRef); if (tab) { int idx = ui->tabWidget->indexOf(tab->getTabWidget()); if (idx < 0) { return; } switch(state) { case MonitorItem::Error: bRefs[n] = false; systemTrayIcon->setNewIcon(2); // red Icon on Error ui->tabWidget->setTabIcon(idx, QIcon(":images/W.png")); break; case MonitorItem::Running: bRefs[n] = true; if( bRefs[(n+1)%nTabs] && bRefs[(n+2)%nTabs]) // if all Tabs OK systemTrayIcon->setNewIcon(0); // shows blue Icon ui->tabWidget->setTabIcon(idx, QIcon()); break; default: break; } /* switch(state) */ } /* if (tab) */ } void MainWindow::onFdJobIsRunning(bool running) { systemTrayIcon->animateIcon(running); } bareos-Release-14.2.6/src/qt-tray-monitor/mainwindow.h000066400000000000000000000050231263011562700226420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include #include #include #include namespace Ui { class MainWindow; } class QPlainTextEdit; class MonitorTab; class MonitorItem; class SystemTrayIcon; class MainWindow : public QMainWindow { Q_OBJECT public: static MainWindow* instance(); static void destruct(); void addTabs(QStringList tabRefs); private: explicit MainWindow(QWidget *parent = 0); Q_DISABLE_COPY(MainWindow); ~MainWindow(); QPlainTextEdit* getTextEdit(const QString& tabRef); static MainWindow* mainWindowSingleton; static bool already_destroyed; Ui::MainWindow *ui; QMap* monitorTabMap; SystemTrayIcon* systemTrayIcon; QStringList tabs; int nTabs; bool *bRefs; public slots: /* auto-connected slots to the UI */ void on_pushButton_Close_clicked(); /* ********************************************* */ /* auto-connected slots to the TrayMenu Actions */ void on_TrayMenu_About_triggered(); void on_TrayMenu_Quit_triggered(); void on_TrayMenu_Display_triggered(); /* ********************************************* */ /* auto-connected slots to the SystemTrayIcon */ void on_SystemTrayIcon_activated(QSystemTrayIcon::ActivationReason); /* ********************************************* */ void onShowStatusbarMessage(QString); void onAppendText(QString, QString); void onClearText(const QString& tabRef); void onStatusChanged(const QString& tabRef, int state); void onFdJobIsRunning(bool running); signals: void refreshItems(); }; #endif // MAINWINDOW_H bareos-Release-14.2.6/src/qt-tray-monitor/mainwindow.ui000066400000000000000000000031151263011562700230300ustar00rootroot00000000000000 MainWindow 0 0 800 542 MainWindow Qt::Horizontal 40 20 Close Tab 1 Tab 2 bareos-Release-14.2.6/src/qt-tray-monitor/monitoritem.cpp000066400000000000000000000246211263011562700233740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "monitoritem.h" #include "authenticate.h" #include "monitoritemthread.h" MonitorItem::MonitorItem(QObject* parent) : QObject(parent) , d(new MonitorItemPrivate) { /* Run this class only in the context of MonitorItemThread because of the networking */ Q_ASSERT(QThread::currentThreadId() == MonitorItemThread::instance()->getThreadId()); } MonitorItem::~MonitorItem() { delete d; } char* MonitorItem::get_name() const { return static_cast(d->resource)->hdr.name; } void MonitorItem::writecmd(const char* command) { if (d->DSock) { d->DSock->msglen = pm_strcpy(&d->DSock->msg, command); bnet_send(d->DSock); } } bool MonitorItem::get_job_defaults(struct JobDefaults &job_defs) { int stat; char *def; BSOCK *dircomm; QString scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name); if (job_defs.job_name == "" || !doconnect()) { return false; } dircomm = d->DSock; dircomm->fsend("%s", scmd.toUtf8().data()); while ((stat = dircomm->recv()) > 0) { def = strchr(dircomm->msg, '='); if (def) { /* Pointer to default value */ *def++ = 0; strip_trailing_newline(def); if (strcmp(dircomm->msg, "job") == 0) { if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) return false; } else if (strcmp(dircomm->msg, "pool") == 0) { job_defs.pool_name = def; } else if (strcmp(dircomm->msg, "messages") == 0) { job_defs.messages_name = def; } else if (strcmp(dircomm->msg, "client") == 0) { job_defs.client_name = def; } else if (strcmp(dircomm->msg, "storage") == 0) { job_defs.store_name = def; } else if (strcmp(dircomm->msg, "where") == 0) { job_defs.where = def; } else if (strcmp(dircomm->msg, "level") == 0) { job_defs.level = def; } else if (strcmp(dircomm->msg, "type") == 0) { job_defs.type = def; } else if (strcmp(dircomm->msg, "fileset") == 0) { job_defs.fileset_name = def; } else if (strcmp(dircomm->msg, "catalog") == 0) { job_defs.catalog_name = def; job_defs.enabled = *def == '1' ? true : false; } } } return true; } bool MonitorItem::doconnect() { if (d->DSock) { //already connected return true; } JCR jcr; memset(&jcr, 0, sizeof(jcr)); DIRRES *dird; CLIENTRES *filed; STORERES *stored; QString message; switch (d->type) { case R_DIRECTOR: dird = static_cast(d->resource); message = QString("Connecting to Director %1:%2").arg(dird->address).arg(dird->DIRport); emit showStatusbarMessage(message); d->DSock = New(BSOCK_TCP); if (!d->DSock->connect(NULL, d->connectTimeout, 0, 0, "Director daemon", dird->address, NULL, dird->DIRport, false)) { delete d->DSock; d->DSock = NULL; } else { jcr.dir_bsock = d->DSock; } break; case R_CLIENT: filed = static_cast(d->resource); message = QString("Connecting to Client %1:%2").arg(filed->address).arg(filed->FDport); emit showStatusbarMessage(message); d->DSock = New(BSOCK_TCP); if (!d->DSock->connect(NULL, d->connectTimeout, 0, 0, "File daemon", filed->address, NULL, filed->FDport, false)) { delete d->DSock; d->DSock = NULL; } else { jcr.file_bsock = d->DSock; } break; case R_STORAGE: stored = static_cast(d->resource); message = QString("Connecting to Storage %1:%2").arg(stored->address).arg(stored->SDport); emit showStatusbarMessage(message); d->DSock = New(BSOCK_TCP); if (!d->DSock->connect(NULL, d->connectTimeout, 0, 0, "Storage daemon", stored->address, NULL, stored->SDport, false)) { delete d->DSock; d->DSock = NULL; } else { jcr.store_bsock = d->DSock; } break; default: printf("Error, currentitem is not a Client, a Storage or a Director..\n"); return false; } char *name = get_name(); if (d->DSock == NULL) { emit showStatusbarMessage("Cannot connect to daemon."); emit clearText(name); emit appendText(name, QString("Cannot connect to daemon.")); d->state = MonitorItem::Error; emit statusChanged(name, d->state); return false; } if (!authenticate_daemon(this, &jcr)) { d->state = MonitorItem::Error; emit statusChanged(name, d->state); message = QString("Authentication error : %1").arg(d->DSock->msg); emit showStatusbarMessage(message); emit clearText(name); emit appendText(name, QString("Authentication error : %1").arg(d->DSock->msg)); d->DSock->signal(BNET_TERMINATE); /* send EOF */ d->DSock->close(); delete d->DSock; d->DSock = NULL; return false; } switch (d->type) { case R_DIRECTOR: emit showStatusbarMessage("Opened connection with Director daemon."); break; case R_CLIENT: emit showStatusbarMessage("Opened connection with File daemon."); break; case R_STORAGE: emit showStatusbarMessage("Opened connection with Storage daemon."); break; default: emit showStatusbarMessage("Error, currentitem is not a Client, a Storage or a Director..\n"); d->state = Error; emit statusChanged(name, d->state); return false; } if (d->type == R_DIRECTOR) { /* Read connection messages... */ docmd(""); /* Usually invalid, but no matter */ } d->state = Running; emit statusChanged(name, d->state); return true; } void MonitorItem::disconnect() { if (d->DSock) { writecmd("quit"); d->DSock->signal(BNET_TERMINATE); /* send EOF */ d->DSock->close(); delete d->DSock; d->DSock = NULL; } } bool MonitorItem::docmd(const char* command) { if (!doconnect()) { return false; } if (command[0] != 0) { writecmd(command); } emit clearText(get_name()); bool jobRunning = false; while (1) { int stat; if ((stat = bnet_recv(d->DSock)) >= 0) { strip_trailing_newline(d->DSock->msg); QString msg = QString::fromUtf8(d->DSock->msg); emit appendText(QString::fromUtf8(get_name()), msg); if (d->type == R_CLIENT) { if (msg.contains("Job started:")) jobRunning = true; } } else if (stat == BNET_SIGNAL) { if (d->DSock->msglen == BNET_EOD) { // qDebug() << "<< EOD >>"; if (d->type == R_CLIENT) emit jobIsRunning (jobRunning); return true; } else if (d->DSock->msglen == BNET_SUB_PROMPT) { // qDebug() << "<< PROMPT >>"; return false; } else if (d->DSock->msglen == BNET_HEARTBEAT) { bnet_sig(d->DSock, BNET_HB_RESPONSE); } else { qDebug() << bnet_sig_to_ascii(d->DSock); } } else { /* BNET_HARDEOF || BNET_ERROR */ d->DSock = NULL; d->state = MonitorItem::Error; emit statusChanged(get_name(), d->state); emit showStatusbarMessage("Error : BNET_HARDEOF or BNET_ERROR"); //fprintf(stderr, "<< ERROR >>\n")); return false; } /* if ((stat = bnet_recv(d->DSock)) >= 0) */ if (is_bnet_stop(d->DSock)) { d->DSock = NULL; d->state = MonitorItem::Error; emit statusChanged(get_name(), d->state); emit showStatusbarMessage("Error : Connection closed."); //fprintf(stderr, "<< STOP >>\n"); return false; /* error or term */ } /* if (is_bnet_stop(d->DSock) */ } /* while (1) */ } void MonitorItem::get_list(const char *cmd, QStringList &lst) { doconnect(); writecmd(cmd); while (bnet_recv(d->DSock) >= 0) { strip_trailing_newline(d->DSock->msg); if (*(d->DSock->msg)) { lst << QString(d->DSock->msg); } } } void MonitorItem::get_status() { switch (d->type) { case R_DIRECTOR: docmd("status dir"); break; case R_CLIENT: if (!docmd("status")) emit jobIsRunning(false); break; case R_STORAGE: docmd("status"); break; default: break; } } void MonitorItem::connectToMainWindow(QObject* mainWindow) { connect(this, SIGNAL(showStatusbarMessage(QString)), mainWindow, SLOT(onShowStatusbarMessage(QString))); connect(this, SIGNAL(appendText(QString,QString)), mainWindow, SLOT(onAppendText(QString,QString))); connect(this, SIGNAL(clearText(QString)), mainWindow, SLOT(onClearText(QString))); connect(this, SIGNAL(statusChanged(QString,int)), mainWindow, SLOT(onStatusChanged(QString,int))); if (d->type == R_CLIENT) { connect(this, SIGNAL(jobIsRunning(bool)), mainWindow, SLOT(onFdJobIsRunning(bool))); } } Rescode MonitorItem::type() const { return d->type; } void* MonitorItem::resource() const { return d->resource; } BSOCK* MonitorItem::DSock() const { return d->DSock; } MonitorItem::StateEnum MonitorItem::state() const { return d->state; } int MonitorItem::connectTimeout() const { return d->connectTimeout; } void MonitorItem::setType(Rescode type) { d->type = type; } void MonitorItem::setResource(void* resource) { d->resource = resource; } void MonitorItem::setDSock(BSOCK* DSock) { d->DSock = DSock; } void MonitorItem::setState(MonitorItem::StateEnum state) { d->state = state; } void MonitorItem::setConnectTimeout(int timeout) { d->connectTimeout = timeout; } bareos-Release-14.2.6/src/qt-tray-monitor/monitoritem.h000066400000000000000000000063041263011562700230370ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MONITORITEM_H_INCLUDED #define MONITORITEM_H_INCLUDED #include #include #include #include "bareos.h" #include "tray_conf.h" #include "jcr.h" #include "tray-monitor.h" class MonitorItemPrivate; class MonitorItem : public QObject { Q_OBJECT public: enum StateEnum { Idle = 0, Running = 1, Warn = 2, Error = 3 }; class JobDefaults { public: QString job_name; QString pool_name; QString messages_name; QString client_name; QString store_name; QString where; QString level; QString type; QString fileset_name; QString catalog_name; bool enabled; }; class Resources { public: QStringList job_list; QStringList pool_list; QStringList client_list; QStringList storage_list; QStringList levels; QStringList fileset_list; QStringList messages_list; }; public: MonitorItem(QObject* parent = 0); ~MonitorItem(); char *get_name() const; void writecmd(const char* command); bool get_job_defaults(struct JobDefaults &job_defs); bool doconnect(); void disconnect(); bool docmd(const char* command); void connectToMainWindow(QObject* mainWindow); void get_list(const char *cmd, QStringList &lst); void get_status(); Rescode type() const; void* resource() const; BSOCK* DSock() const; StateEnum state() const; int connectTimeout() const; void setType(Rescode type); void setResource(void* resource); void setDSock(BSOCK* DSock); void setState(StateEnum state); void setConnectTimeout(int timeout); private: Q_DISABLE_COPY(MonitorItem); MonitorItemPrivate* d; public slots: signals: void showStatusbarMessage(const QString& message); void appendText(const QString& tabRef, const QString& message); void clearText(const QString& tabRef); void statusChanged(const QString&tabRef, int); void jobIsRunning(bool); }; class MonitorItemPrivate { friend class MonitorItem; MonitorItemPrivate() : type(R_UNKNOWN) , resource(NULL) , DSock(NULL) , connectTimeout(0) , state(MonitorItem::Idle) { } Rescode type; /* R_DIRECTOR, R_CLIENT or R_STORAGE */ void* resource; /* DIRRES*, CLIENTRES* or STORERES* */ BSOCK* DSock; int connectTimeout; MonitorItem::StateEnum state; }; #endif // MONITORITEM_H_INCLUDED bareos-Release-14.2.6/src/qt-tray-monitor/monitoritemthread.cpp000066400000000000000000000135411263011562700245630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "mainwindow.h" #include "monitoritemthread.h" #include "tray-monitor.h" #include "monitoritem.h" #include "tray_conf.h" MonitorItemThread* MonitorItemThread::monitorItemThreadSingleton; bool MonitorItemThread::already_destroyed = false; MonitorItemThread::MonitorItemThread(QObject* parent) : QThread(parent) , monitor(NULL) , refreshTimer(new QTimer(this)) , isRefreshing(false) { threadId = currentThreadId(); refreshTimer->setObjectName("RefreshTimer"); QMetaObject::connectSlotsByName(this); } MonitorItemThread::~MonitorItemThread() { return; } MonitorItemThread* MonitorItemThread::instance() { // improve that the MonitorItemThread is created // and deleted only once during program execution Q_ASSERT(!already_destroyed); if (!monitorItemThreadSingleton) { monitorItemThreadSingleton = new MonitorItemThread; } return monitorItemThreadSingleton; } void MonitorItemThread::destruct() { if (monitorItemThreadSingleton) { monitorItemThreadSingleton->exit(0); monitorItemThreadSingleton->wait(20000); delete monitorItemThreadSingleton; monitorItemThreadSingleton = NULL; already_destroyed = true; } } Qt::HANDLE MonitorItemThread::getThreadId() { return threadId; } void MonitorItemThread::run() { /* all this must be run in the same * context of the MonitorItemThread */ lmgr_init_thread(); if (monitor) { refreshTimer->start(monitor->RefreshInterval * 1000); } exec(); while (items.count()) { MonitorItem* item = items.first(); item->disconnect(); delete item; items.removeFirst(); } term_msg(); // this cannot be called twice, however } QStringList MonitorItemThread::createRes(const cl_opts& cl) { QStringList tabRefs; LockRes(); int monitorItems = 0; MONITORRES *monitorRes; foreach_res(monitorRes, R_MONITOR) { monitorItems++; } if (monitorItems != 1) { Emsg2(M_ERROR_TERM, 0, _("Error: %d Monitor resources defined in %s. " "You must define one and only one Monitor resource.\n"), monitorItems, cl.configfile); } monitor = reinterpret_cast(GetNextRes(R_MONITOR, (RES *)NULL)); int nitems = 0; DIRRES* dird; foreach_res(dird, R_DIRECTOR) { MonitorItem* item = new MonitorItem; item->setType(R_DIRECTOR); item->setResource(dird); item->setConnectTimeout(monitor->DIRConnectTimeout); item->connectToMainWindow(MainWindow::instance()); tabRefs.append(item->get_name()); items.append(item); nitems++; } CLIENTRES* filed; foreach_res(filed, R_CLIENT) { MonitorItem* item = new MonitorItem; item->setType(R_CLIENT); item->setResource(filed); item->setConnectTimeout(monitor->FDConnectTimeout); item->connectToMainWindow(MainWindow::instance()); tabRefs.append(item->get_name()); items.append(item); nitems++; } STORERES* stored; foreach_res(stored, R_STORAGE) { MonitorItem* item = new MonitorItem; item->setType(R_STORAGE); item->setResource(stored); item->setConnectTimeout(monitor->SDConnectTimeout); item->connectToMainWindow(MainWindow::instance()); tabRefs.append(item->get_name()); items.append(item); nitems++; } UnlockRes(); if (nitems == 0) { Emsg1(M_ERROR_TERM, 0, "No Client, Storage or Director resource defined in %s\n" "Without that I don't know how to get status from the File, " "Storage or Director Daemon :-(\n", cl.configfile); } // check the refresh intervals for reasonable values int interval = monitor->RefreshInterval; if ((interval < 1) || (interval > 600)) { Emsg2(M_ERROR_TERM, 0, "Invalid refresh interval defined in %s\n" "This value must be greater or equal to 1 second and less or " "equal to 10 minutes (read value: %d).\n", cl.configfile, interval); } return tabRefs; } void MonitorItemThread::onRefreshItems() { if (!isRefreshing) { isRefreshing = true; for (int i = 0; i < items.count(); i++) { items[i]->get_status(); } emit refreshItemsReady(); isRefreshing = false; } } void MonitorItemThread::on_RefreshTimer_timeout() { onRefreshItems(); } MONITORRES* MonitorItemThread::getMonitor() const { return monitor; } MonitorItem* MonitorItemThread::getDirector() const { // search for the first occurrence of a director int count = items.count(); for (int i = 0; i < count; i++) { if (items[i]->type() == R_DIRECTOR) { return items[i]; } } return NULL; } /************* Testing ***************/ void MonitorItemThread::dotest() { const char *cmd; int count = items.count(); for (int i = 0; i < count; i++) { switch (items[i]->type()) { case R_DIRECTOR: cmd = ".jobs type=B"; items[i]->docmd(cmd); break; default: break; } } } bareos-Release-14.2.6/src/qt-tray-monitor/monitoritemthread.h000066400000000000000000000036461263011562700242350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MONITORITEMTHREAD_H_INCLUDED #define MONITORITEMTHREAD_H_INCLUDED #include "tray-monitor.h" #include #include class MonitorItem; class MONITORRES; class QTimer; class MonitorItemThread : public QThread { Q_OBJECT public: static MonitorItemThread* instance(); static void destruct(); Qt::HANDLE getThreadId(); QStringList createRes(const cl_opts& cl); MONITORRES* getMonitor() const; MonitorItem *getDirector() const; protected: virtual void run(); void dotest(); private: MonitorItemThread(QObject* parent = 0); Q_DISABLE_COPY(MonitorItemThread); virtual ~MonitorItemThread(); static MonitorItemThread* monitorItemThreadSingleton; static bool already_destroyed; MONITORRES* monitor; Qt::HANDLE threadId; QList items; QTimer* refreshTimer; bool isRefreshing; public slots: /* auto-connected slots to the Refresh Timer */ void on_RefreshTimer_timeout(); /* ********************************************* */ void onRefreshItems(); signals: void refreshItemsReady(); }; #endif // MONITORITEMTHREAD_H_INCLUDED bareos-Release-14.2.6/src/qt-tray-monitor/monitortab.h000066400000000000000000000013771263011562700226540ustar00rootroot00000000000000#ifndef MONITORTAB_H #define MONITORTAB_H class MonitorTab : public QObject { public: MonitorTab(QString tabRefString, QObject* parent = 0) : QObject(parent) , tab(new QWidget) , textEdit(new QPlainTextEdit(tab)) { QVBoxLayout *vLayout = new QVBoxLayout(tab); textEdit->setObjectName(tabRefString); textEdit->setReadOnly(true); textEdit->setFont(QFont("courier")); vLayout->addWidget(textEdit); } ~MonitorTab() { // do not delete widgets since they // all have a parent that does the work } QWidget* getTabWidget() const { return tab; } QPlainTextEdit* getTextEdit() const { return textEdit; } private: QWidget* tab; QPlainTextEdit *textEdit; }; #endif // MONITORTAB_H bareos-Release-14.2.6/src/qt-tray-monitor/systemtrayicon.cpp000066400000000000000000000041111263011562700241130ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "systemtrayicon.h" #include "traymenu.h" #include #include #include #include SystemTrayIcon::SystemTrayIcon(QMainWindow* mainWindow) : QSystemTrayIcon(mainWindow) , iconIdx(0) , timer(new QTimer(this)) { // this object name is used for auto-connection to the MainWindow setObjectName("SystemTrayIcon"); TrayMenu* menu = new TrayMenu(mainWindow); setContextMenu(menu); icons << ":/images/bareos_1.png" << ":/images/bareos_2.png" << ":/images/W.png"; setIcon(QIcon(icons[iconIdx])); setToolTip("Bareos Tray Monitor"); timer->setInterval(700); connect(timer, SIGNAL(timeout()), this, SLOT(setIconInternal())); } SystemTrayIcon::~SystemTrayIcon() { timer->stop(); } void SystemTrayIcon::setNewIcon(int icon){ iconIdx = icon; setIcon(QIcon(icons[icon])); } void SystemTrayIcon::setIconInternal() { setIcon(QIcon(icons[iconIdx++])); iconIdx %= 2; // 0 if 1 / 1 if 0 } void SystemTrayIcon::animateIcon(bool on) { if (on) { if (!timer->isActive()) { timer->start(); } } else { //off if (timer->isActive()) { timer->stop(); } if(iconIdx != 2){ // blink if there's no error iconIdx = 0; setIconInternal(); } } } bareos-Release-14.2.6/src/qt-tray-monitor/systemtrayicon.h000066400000000000000000000025061263011562700235660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SYSTEMTRAYICON_H #define SYSTEMTRAYICON_H #include class QMainWindow; class QTimer; class SystemTrayIcon : public QSystemTrayIcon { Q_OBJECT public: SystemTrayIcon(QMainWindow* mainWindow); virtual ~SystemTrayIcon(); void animateIcon(bool on); private: Q_DISABLE_COPY(SystemTrayIcon); SystemTrayIcon(); QStringList icons; int iconIdx; QTimer* timer; protected: public slots: void setNewIcon(int icon); void setIconInternal(); }; #endif // SYSTEMTRAYICON_H bareos-Release-14.2.6/src/qt-tray-monitor/tray-monitor.conf.in000066400000000000000000000010661263011562700242400ustar00rootroot00000000000000# # Bareos Tray Monitor Configuration File # Monitor { Name = @basename@-mon Password = "@mon_dir_password@" # password for the Directors RefreshInterval = 30 seconds } Client { Name = @basename@-fd Address = @hostname@ FDPort = @fd_port@ Password = "@mon_fd_password@" # password for FileDaemon } Storage { Name = @basename@-sd Address = @hostname@ SDPort = @sd_port@ Password = "@mon_sd_password@" # password for StorageDaemon } Director { Name = @basename@-dir DIRport = @dir_port@ address = @hostname@ } bareos-Release-14.2.6/src/qt-tray-monitor/tray-monitor.cpp000066400000000000000000000140571263011562700234740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "version.h" #include "mainwindow.h" #include "tray-monitor.h" #include "authenticate.h" #include "monitoritem.h" #include "monitoritemthread.h" #define CONFIG_FILE "tray-monitor.conf" /* default configuration file */ CONFIG *my_config = NULL; /* Our Global config */ /* Imported function from tray_conf.cpp */ extern bool parse_tmon_config(CONFIG *config, const char *configfile, int exit_code); /* Static variables */ static QApplication* app = NULL; static void usage() { QString out; out = out.sprintf(_(PROG_COPYRIGHT "\nVersion: %s (%s) %s %s %s\n\n" "Usage: tray-monitor [-c config_file] [-d debug_level]\n" " -c set configuration file to file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -t test - read configuration and exit\n" " -xc print configuration and exit\n" " -xs print configuration file schema in JSON format and exit\n" " -? print this message.\n" "\n"), 2004, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER); #if HAVE_WIN32 QMessageBox::information(0, "Help", out); #else fprintf(stderr, "%s", out.toUtf8().data()); #endif } static void parse_command_line(int argc, char* argv[], cl_opts& cl) { int ch; while ((ch = getopt(argc, argv, "bc:d:th?f:s:")) != -1) { switch (ch) { case 'c': /* configuration file */ if (cl.configfile) { free(static_cast(cl.configfile)); } cl.configfile = bstrdup(optarg); break; case 'd': if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 't': cl.test_config_only = true; break; case 'h': case '?': default: usage(); exit(1); } } argc -= optind; //argv += optind; if (argc) { usage(); exit(1); } if (!cl.configfile) { cl.configfile = bstrdup(CONFIG_FILE); } } static void setupQtObjects() { MonitorItemThread* thr = MonitorItemThread::instance(); MainWindow* win = MainWindow::instance(); QObject::connect(win, SIGNAL(refreshItems()), thr, SLOT(onRefreshItems()), Qt::QueuedConnection); // move the thread exec handler // into its own context thr->moveToThread(thr); } static void cleanup() { static bool terminated = false; if (terminated) { // don't call it twice return; } terminated = true; MonitorItemThread::destruct(); //disconnects network MainWindow::destruct(); //destroys the tray-icon if(app) { delete app; app = NULL; } if (my_config) { my_config->free_resources(); free(my_config); my_config = NULL; } WSACleanup(); /* Cleanup Windows sockets */ } void intHandler(int) { exit(0); } static void init_environment(int argc, char* argv[]) { setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "tray-monitor"); init_msg(NULL, NULL); signal(SIGINT, intHandler); working_directory = "/tmp"; WSA_Init(); /* Initialize Windows sockets */ } /********************************************************************* * * Main Bareos Tray Monitor -- User Interface Program * */ int main(int argc, char *argv[]) { init_environment(argc, argv); cl_opts cl; // remember some command line options parse_command_line(argc, argv, cl); // read the config file my_config = new_config_parser(); parse_tmon_config(my_config, cl.configfile, M_ERROR_TERM); // this is the Qt core application // with its message handler app = new QApplication(argc, argv); app->setQuitOnLastWindowClosed(false); setupQtObjects(); // create the monitoritems QStringList tabRefs = MonitorItemThread::instance()->createRes(cl); MainWindow::instance()->addTabs(tabRefs); // exit() if it was only a test if (cl.test_config_only) { exit(0); } MonitorItemThread::instance()->start(); // launch the QApplication message handler int ret = app->exec(); // cleanup everything before finishing cleanup(); return ret; } /* This is a replacement for the std::exit() handler */ void exit(int status) { /* avoid to call the std::exit() cleanup handlers * via atexit() since exit() destroys objects that * are used by the QApplication class and this would * lead to a sementation fault when QApplication * in turn wants to destroy its child-objects. */ // first do the Qt cleanup cleanup(); // do the kernel cleanup _exit(status); } bareos-Release-14.2.6/src/qt-tray-monitor/tray-monitor.h000066400000000000000000000025011263011562700231300ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Includes specific to the tray monitor * * Nicolas Boichat, August MMIV */ #ifndef TRAY_MONITOR_H #define TRAY_MONITOR_H struct cl_opts { char *configfile; bool test_config_only; cl_opts () { configfile = (char*)0; test_config_only = false; } }; class MonitorItem; class MONITORRES; void refresh_item(); const MONITORRES* getMonitor(); #endif /* TRAY_MONITOR_H */ bareos-Release-14.2.6/src/qt-tray-monitor/tray-monitor.pro.in000066400000000000000000000035661263011562700241220ustar00rootroot00000000000000###################################################################### # # !!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # Edit only tray-monitor.pro.in -- tray-monitor.pro is built by the ./configure program # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # CONFIG += qt CONFIG -= debug_and_release CONFIG( debug, debug|release ) { CONFIG -= release } else { CONFIG -= debug CONFIG += release } QMAKE_LIBDIR += ../lib LIBS += -lbareoscfg -lbareos bins.path = /$(DESTDIR)@bindir@ bins.files = bareos-tray-monitor confs.path = /$(DESTDIR)@sysconfdir@ confs.files = tray-monitor.conf icons.path = /$(DESTDIR)@datarootdir@/pixmaps/ icons.files = bareos-tray-monitor.xpm desktopentries.path = /$(DESTDIR)@datarootdir@/applications/ desktopentries.files = bareos-tray-monitor.desktop autostarts.path = /$(DESTDIR)/etc/xdg/autostart/ autostarts.files = bareos-tray-monitor.desktop TEMPLATE = app TARGET = bareos-tray-monitor DEPENDPATH += . INCLUDEPATH += ../include .. . LIBTOOL_LINK = @QMAKE_LIBTOOL@ --silent --tag=CXX --mode=link LIBTOOL_INSTALL = @QMAKE_LIBTOOL@ --silent --mode=install QMAKE_LINK = $${LIBTOOL_LINK} $(CXX) QMAKE_INSTALL_PROGRAM = $${LIBTOOL_INSTALL} install -m @SBINPERM@ -p QMAKE_CLEAN += .libs/* bareos-tray-monitor release/bareos-tray-monitor RESOURCES = main.qrc MOC_DIR = moc OBJECTS_DIR = obj UI_DIR = ui # Main directory HEADERS += tray_conf.h tray-monitor.h traymenu.h systemtrayicon.h mainwindow.h authenticate.h monitoritem.h monitoritemthread.h SOURCES += authenticate.cpp tray_conf.cpp tray-monitor.cpp traymenu.cpp systemtrayicon.cpp mainwindow.cpp monitoritem.cpp monitoritemthread.cpp FORMS += mainwindow.ui INSTALLS += bins confs icons desktopentries autostarts QMAKE_EXTRA_TARGETS += depend bareos-Release-14.2.6/src/qt-tray-monitor/tray_conf.cpp000066400000000000000000000314271263011562700230140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Main configuration file parser for Bareos Tray Monitor. * Adapted from dird_conf.c * * Note, the configuration file parser consists of three parts * * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and * lib/parse_config.h. These files contain the parser code, * some utility routines, and the common store routines * (name, int, string). * * 3. The daemon specific file, which contains the Resource * definitions as well as any specific store routines * for the resource records. * * Nicolas Boichat, August MMIV */ #include "bareos.h" #include "tray_conf.h" /* * Define the first and last resource ID record * types. Note, these should be unique for each * daemon though not a requirement. */ static RES *sres_head[R_LAST - R_FIRST + 1]; static RES **res_head = sres_head; /* * We build the current resource here as we are * scanning the resource configuration definition, * then move it to allocated memory when the resource * scan is complete. */ URES res_all; int32_t res_all_size = sizeof(res_all); /* * Definition of records permitted within each * resource with the routine to process the record * information. NOTE! quoted names must be in lower case. */ /* * Monitor Resource * * name handler value code flags default_value */ static RES_ITEM mon_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_monitor.hdr.name), 0, CFG_ITEM_REQUIRED, 0 }, { "description", CFG_TYPE_STR, ITEM(res_monitor.hdr.desc), 0, 0, 0 }, { "requiressl", CFG_TYPE_BOOL, ITEM(res_monitor.require_ssl), 0, CFG_ITEM_DEFAULT, "false" }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(res_monitor.password), 0, CFG_ITEM_REQUIRED, NULL }, { "refreshinterval", CFG_TYPE_TIME, ITEM(res_monitor.RefreshInterval), 0, CFG_ITEM_DEFAULT, "60" }, { "fdconnecttimeout", CFG_TYPE_TIME, ITEM(res_monitor.FDConnectTimeout), 0, CFG_ITEM_DEFAULT, "10" }, { "sdconnecttimeout", CFG_TYPE_TIME, ITEM(res_monitor.SDConnectTimeout), 0, CFG_ITEM_DEFAULT, "10" }, { "dirconnecttimeout", CFG_TYPE_TIME, ITEM(res_monitor.DIRConnectTimeout), 0, CFG_ITEM_DEFAULT, "10" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Director's that we can contact * * name handler value code flags default_value */ static RES_ITEM dir_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_dir.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_dir.hdr.desc), 0, 0, NULL }, { "dirport", CFG_TYPE_PINT32, ITEM(res_dir.DIRport), 0, CFG_ITEM_DEFAULT, DIR_DEFAULT_PORT }, { "address", CFG_TYPE_STR, ITEM(res_dir.address), 0, CFG_ITEM_REQUIRED, NULL }, { "enablessl", CFG_TYPE_BOOL, ITEM(res_dir.enable_ssl), 0, CFG_ITEM_DEFAULT, "false" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Client or File daemon resource * * name handler value code flags default_value */ static RES_ITEM cli_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_client.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_client.hdr.desc), 0, 0, NULL }, { "address", CFG_TYPE_STR, ITEM(res_client.address), 0, CFG_ITEM_REQUIRED, NULL }, { "fdport", CFG_TYPE_PINT32, ITEM(res_client.FDport), 0, CFG_ITEM_DEFAULT, FD_DEFAULT_PORT }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(res_client.password), 0, CFG_ITEM_REQUIRED, NULL }, { "enablessl", CFG_TYPE_BOOL, ITEM(res_client.enable_ssl), 0, CFG_ITEM_DEFAULT, "false" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Storage daemon resource * * name handler value code flags default_value */ static RES_ITEM store_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_store.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_store.hdr.desc), 0, 0, NULL }, { "sdport", CFG_TYPE_PINT32, ITEM(res_store.SDport), 0, CFG_ITEM_DEFAULT, SD_DEFAULT_PORT }, { "address", CFG_TYPE_STR, ITEM(res_store.address), 0, CFG_ITEM_REQUIRED, NULL }, { "sdaddress", CFG_TYPE_STR, ITEM(res_store.address), 0, 0, NULL }, { "password", CFG_TYPE_MD5PASSWORD, ITEM(res_store.password), 0, CFG_ITEM_REQUIRED, NULL }, { "sdpassword", CFG_TYPE_MD5PASSWORD, ITEM(res_store.password), 0, 0, NULL }, { "enablessl", CFG_TYPE_BOOL, ITEM(res_store.enable_ssl), 0, CFG_ITEM_DEFAULT, "false" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Font resource * * name handler value code flags default_value */ static RES_ITEM con_font_items[] = { { "name", CFG_TYPE_NAME, ITEM(con_font.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(con_font.hdr.desc), 0, 0, NULL }, { "font", CFG_TYPE_STR, ITEM(con_font.fontface), 0, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * This is the master resource definition. * It must have one item for each of the resources. * * NOTE!!! keep it in the same order as the R_codes * or eliminate all resources[rindex].name * * name items rcode res_head */ static RES_TABLE resources[] = { { "monitor", mon_items, R_MONITOR, sizeof(MONITORRES) }, { "director", dir_items, R_DIRECTOR, sizeof(DIRRES) }, { "client", cli_items, R_CLIENT, sizeof(CLIENTRES) }, { "storage", store_items, R_STORAGE, sizeof(STORERES) }, { "consolefont", con_font_items, R_CONSOLE_FONT, sizeof(CONFONTRES) }, { NULL, NULL, 0, 0 } }; /* * Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { URES *res = (URES *)reshdr; bool recurse = true; char ed1[100], ed2[100]; if (res == NULL) { sendit(sock, _("No %s resource defined\n"), res_to_str(type)); return; } if (type < 0) { /* no recursion */ type = - type; recurse = false; } switch (type) { case R_MONITOR: sendit(sock, _("Monitor: name=%s FDtimeout=%s SDtimeout=%s\n"), reshdr->name, edit_uint64(res->res_monitor.FDConnectTimeout, ed1), edit_uint64(res->res_monitor.SDConnectTimeout, ed2)); break; case R_DIRECTOR: sendit(sock, _("Director: name=%s address=%s FDport=%d\n"), res->res_dir.hdr.name, res->res_dir.address, res->res_dir.DIRport); break; case R_CLIENT: sendit(sock, _("Client: name=%s address=%s FDport=%d\n"), res->res_client.hdr.name, res->res_client.address, res->res_client.FDport); break; case R_STORAGE: sendit(sock, _("Storage: name=%s address=%s SDport=%d\n"), res->res_store.hdr.name, res->res_store.address, res->res_store.SDport); break; case R_CONSOLE_FONT: sendit(sock, _("ConsoleFont: name=%s font face=%s\n"), reshdr->name, NPRT(res->con_font.fontface)); break; default: sendit(sock, _("Unknown resource type %d in dump_resource.\n"), type); break; } if (recurse && res->res_monitor.hdr.next) { dump_resource(type, res->res_monitor.hdr.next, sendit, sock, hide_sensitive_data); } } /* * Free memory of resource -- called when daemon terminates. * NB, we don't need to worry about freeing any references * to other resources as they will be freed when that * resource chain is traversed. Mainly we worry about freeing * allocated strings (names). */ void free_resource(RES *sres, int type) { RES *nres; /* next resource if linked */ URES *res = (URES *)sres; if (res == NULL) return; /* * Common stuff -- free the resource name and description */ nres = (RES *)res->res_monitor.hdr.next; if (res->res_monitor.hdr.name) { free(res->res_monitor.hdr.name); } if (res->res_monitor.hdr.desc) { free(res->res_monitor.hdr.desc); } switch (type) { case R_MONITOR: break; case R_DIRECTOR: if (res->res_dir.address) { free(res->res_dir.address); } break; case R_CLIENT: if (res->res_client.address) { free(res->res_client.address); } if (res->res_client.password.value) { free(res->res_client.password.value); } break; case R_STORAGE: if (res->res_store.address) { free(res->res_store.address); } if (res->res_store.password.value) { free(res->res_store.password.value); } break; case R_CONSOLE_FONT: if (res->con_font.fontface) { free(res->con_font.fontface); } break; default: printf(_("Unknown resource type %d in free_resource.\n"), type); } /* * Common stuff again -- free the resource, recurse to next one */ if (res) { free(res); } if (nres) { free_resource(nres, type); } } /* * Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * pointers because they may not have been defined until * later in pass 1. */ void save_resource(int type, RES_ITEM *items, int pass) { URES *res; int rindex = type - R_FIRST; int i; int error = 0; /* * Ensure that all required items are present */ for (i = 0; items[i].name; i++) { if (items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, res_all.res_monitor.hdr.item_present)) { Emsg2(M_ERROR_TERM, 0, _("%s item is required in %s resource, but not found.\n"), items[i].name, resources[rindex]); } } /* If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]); } } /* * During pass 2 in each "store" routine, we looked up pointers * to all the resources referrenced in the current resource, now we * must copy their addresses from the static record to the allocated * record. */ if (pass == 2) { switch (type) { /* * Resources not containing a resource */ case R_MONITOR: case R_CLIENT: case R_STORAGE: case R_DIRECTOR: case R_CONSOLE_FONT: break; default: Emsg1(M_ERROR, 0, _("Unknown resource type %d in save_resource.\n"), type); error = 1; break; } /* * Note, the resource name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_monitor.hdr.name) { free(res_all.res_monitor.hdr.name); res_all.res_monitor.hdr.name = NULL; } if (res_all.res_monitor.hdr.desc) { free(res_all.res_monitor.hdr.desc); res_all.res_monitor.hdr.desc = NULL; } return; } /* * Common */ if (!error) { res = (URES *)malloc(resources[rindex].size); memcpy(res, &res_all, resources[rindex].size); if (!res_head[rindex]) { res_head[rindex] = (RES *)res; /* store first entry */ Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(type), res->res_monitor.hdr.name, rindex); } else { RES *next, *last; /* * Add new res to end of chain */ for (last = next = res_head[rindex]; next; next=next->next) { last = next; if (strcmp(next->name, res->res_monitor.hdr.name) == 0) { Emsg2(M_ERROR_TERM, 0, _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), resources[rindex].name, res->res_monitor.hdr.name); } } last->next = (RES *)res; Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type), res->res_monitor.hdr.name, rindex, pass); } } } bool parse_tmon_config(CONFIG *config, const char *configfile, int exit_code) { config->init(configfile, NULL, NULL, NULL, NULL, NULL, exit_code, (void *)&res_all, res_all_size, R_FIRST, R_LAST, resources, res_head); return config->parse_config(); } bareos-Release-14.2.6/src/qt-tray-monitor/tray_conf.h000066400000000000000000000060101263011562700224470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Tray Monitor specific configuration and defines * * Adapted from dird_conf.c * * Nicolas Boichat, August MMIV */ /* NOTE: #includes at the end of this file */ /* * Resource codes -- they must be sequential for indexing */ #ifndef TRAY_CONF_H_INCLUDED #define TRAY_CONF_H_INCLUDED enum Rescode { R_UNKNOWN = 0, R_MONITOR = 1001, R_DIRECTOR, R_CLIENT, R_STORAGE, R_CONSOLE_FONT, R_FIRST = R_MONITOR, R_LAST = R_CONSOLE_FONT /* keep this updated */ }; /* * Some resource attributes */ enum { R_NAME = 1020, R_ADDRESS, R_PASSWORD, R_TYPE, R_BACKUP }; /* * Director Resource * */ struct DIRRES { RES hdr; uint32_t DIRport; /* UA server port */ char *address; /* UA server address */ bool enable_ssl; /* Use SSL */ }; /* * Tray Monitor Resource * */ struct MONITORRES { RES hdr; bool require_ssl; /* Require SSL for all connections */ MSGSRES *messages; /* Daemon message handler */ s_password password; /* UA server password */ utime_t RefreshInterval; /* Status refresh interval */ utime_t FDConnectTimeout; /* timeout for connect in seconds */ utime_t SDConnectTimeout; /* timeout in seconds */ utime_t DIRConnectTimeout; /* timeout in seconds */ }; /* * Client Resource * */ struct CLIENTRES { RES hdr; uint32_t FDport; /* Where File daemon listens */ char *address; s_password password; bool enable_ssl; /* Use SSL */ }; /* * Store Resource * */ struct STORERES { RES hdr; uint32_t SDport; /* port where Directors connect */ char *address; s_password password; bool enable_ssl; /* Use SSL */ }; struct CONFONTRES { RES hdr; char *fontface; /* Console Font specification */ }; /* Define the Union of all the above * resource structure definitions. */ union URES { MONITORRES res_monitor; DIRRES res_dir; CLIENTRES res_client; STORERES res_store; CONFONTRES con_font; RES hdr; }; #endif /* TRAY_CONF_H_INCLUDED */ bareos-Release-14.2.6/src/qt-tray-monitor/traymenu.cpp000066400000000000000000000037421263011562700226730ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "traymenu.h" #include #include #include #include TrayMenu::TrayMenu(QWidget* mainWindow) : QMenu(mainWindow) { setObjectName("TrayMenu"); createAction("Display", "Display", mainWindow); createAction("About", "About", mainWindow); addSeparator(); createAction("Quit", "Quit", mainWindow); } TrayMenu::~TrayMenu() { return; } void TrayMenu::createAction(QString objName, QString text, QWidget* mainWindow) { const QString& translate = QApplication::translate("TrayMonitor", text.toUtf8(), 0, QApplication::UnicodeUTF8); QAction *action = new QAction(translate, mainWindow); /* QActions are connected to the mainWindow with their * name-signals-schema i.e. "on_Display_triggered()" * using QMetaObject::connectSlotsByName(mainWindow) * during SetupUi of the mainWindow */ const QString& objNameForSignal = QString("TrayMenu_%1").arg(objName); action->setObjectName(objNameForSignal); addAction(action); } bareos-Release-14.2.6/src/qt-tray-monitor/traymenu.h000066400000000000000000000022631263011562700223350ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef TRAYMONITOR_TRAYMENU_H #define TRAYMONITOR_TRAYMENU_H #include #include class QAction; class TrayMenu : public QMenu { Q_OBJECT public: TrayMenu(QWidget* trayMonitor = 0); virtual ~TrayMenu(); private: void createAction(QString objName, QString text, QWidget* trayMonitor); public slots: signals: }; #endif // TRAYMONITOR_TRAYMENU_H bareos-Release-14.2.6/src/stored/000077500000000000000000000000001263011562700165275ustar00rootroot00000000000000bareos-Release-14.2.6/src/stored/Makefile.in000066400000000000000000000246401263011562700206020ustar00rootroot00000000000000# @MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@:backends .PATH: @srcdir@ sd_group=@sd_group@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/stored DEBUG = @DEBUG@ GETTEXT_LIBS = @LIBINTL@ DB_LIBS = @DB_LIBS@ AFS_LIBS = @AFS_LIBS_NONSHARED@ ACL_LIBS = @ACL_LIBS_NONSHARED@ XATTR_LIBS = @XATTR_LIBS_NONSHARED@ COMPRESS_LIBS = @ZLIB_LIBS_NONSHARED@ @LZO_LIBS_NONSHARED@ @FASTLZ_LIBS_NONSHARED@ OPENSSL_LIBS_NONSHARED = @OPENSSL_LIBS_NONSHARED@ GNUTLS_LIBS_NONSHARED = @GNUTLS_LIBS_NONSHARED@ first_rule: all dummy: AVAILABLE_DEVICE_API_SRCS = cephfs_device.c \ gfapi_device.c \ object_store_device.c \ rados_device.c \ generic_tape_device.c \ unix_fifo_device.c \ unix_tape_device.c NEEDED_DEVICE_API_SRCS = unix_file_device.c @NEEDED_DEVICE_API_SRCS@ CEPHFS_LIBS = @CEPHFS_LIBS@ DROPLET_LIBS = @DROPLET_LIBS@ GLUSTER_LIBS = @GLUSTER_LIBS@ RADOS_LIBS = @RADOS_LIBS@ AVAILABLE_BACKEND_LIBS = $(CEPHFS_LIBS) $(DROPLET_LIBS) $(GLUSTER_LIBS) $(RADOS_LIBS) LIBS += @NEEDED_BACKEND_LIBS@ # objects used in all daemons collected in (shared) library. LIBBAREOSSD_SRCS = acquire.c ansi_label.c askdir.c autochanger.c block.c bsr.c \ butil.c crc32.c dev.c device.c ebcdic.c label.c lock.c \ mount.c read_record.c record.c reserve.c scan.c \ sd_backends.c sd_plugins.c sd_stats.c spool.c \ stored_conf.c vol_mgr.c wait.c $(NEEDED_DEVICE_API_SRCS) LIBBAREOSSD_OBJS = $(LIBBAREOSSD_SRCS:.c=.o) LIBBAREOSSD_LOBJS = $(LIBBAREOSSD_SRCS:.c=.lo) LIBBAREOSSD_LT_RELEASE = @LIBBAREOSSD_LT_RELEASE@ # bareos-sd SDSRCS = append.c askdir.c authenticate.c dir_cmd.c fd_cmds.c job.c mac.c \ ndmp_tape.c read.c sd_cmds.c sd_stats.c status.c stored.c SDOBJS = $(SDSRCS:.c=.o) # btape TAPESRCS = btape.c TAPEOBJS = $(TAPESRCS:.c=.o) # bls BLSSRCS = bls.c BLSOBJS = $(BLSSRCS:.c=.o) # bextract BEXTSRCS = bextract.c BEXTOBJS = $(BEXTSRCS:.c=.o) # bscan SCNSRCS = bscan.c SCNOBJS = $(SCNSRCS:.c=.o) # bcopy COPYSRCS = bcopy.c COPYOBJS = $(COPYSRCS:.c=.o) SD_LIBS += @CAP_LIBS@ BEXTRACT_LIBS += @ZLIB_LIBS_NONSHARED@ BEXTRACT_LIBS += @LZO_LIBS_NONSHARED@ BEXTRACT_LIBS += @FASTLZ_LIBS_NONSHARED@ CEPHFS_INC = @CEPHFS_INC@ DROPLET_INC = @DROPLET_INC@ GLUSTER_INC = @GLUSTER_INC@ RADOS_INC = @RADOS_INC@ INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include DEBUG = @DEBUG@ GETTEXT_LIBS = @LIBINTL@ DB_LIBS = @DB_LIBS@ ACL_LIBS = @ACL_LIBS@ XATTR_LIBS = @XATTR_LIBS@ NDMP_LIBS = @NDMP_LIBS@ .SUFFIXES: .c .o .lo .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< .c.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) bareos-sd @STATIC_SD@ bls bextract bscan btape bcopy @echo "===== Make of stored is good ====" @echo " " libbareossd.a: $(LIBBAREOSSD_OBJS) @echo "Making $@ ..." $(AR) rc $@ $(LIBBAREOSSD_OBJS) $(RANLIB) $@ libbareossd.la: Makefile $(LIBBAREOSSD_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../lib -o $@ $(LIBBAREOSSD_LOBJS) -export-dynamic -rpath $(libdir) -release $(LIBBAREOSSD_LT_RELEASE) -lbareos -lbareoscfg dev.lo: dev.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CEPHFS_INC) $(GLUSTER_INC) $(DROPLET_INC) $(RADOS_INC) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< cephfs_device.lo: cephfs_device.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< gfapi_device.lo: gfapi_device.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(GLUSTER_INC) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< object_storage_device.lo: object_storage_device.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(DROPLET_INC) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< rados_device.lo: rados_device.c @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(RADOS_INC) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< bareos-sd: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(SDOBJS) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ @NDMP_DEPS@ @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(WLDFLAGS) $(LDFLAGS) -L. -L../lib -o $@ $(SDOBJS) \ $(NDMP_LIBS) -lbareossd -lbareoscfg -lbareos -lm $(DLIB) $(LIBS) $(WRAPLIBS) \ $(SD_LIBS) $(GETTEXT_LIBS) $(COMPRESS_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) static-bareos-sd: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(SDOBJS) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ @NDMP_DEPS@ @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L. -L../lib -o $@ $(SDOBJS) \ $(NDMP_LIBS) -lbareossd -lbareoscfg -lbareos -lm $(DLIB) $(LIBS) $(WRAPLIBS) \ $(SD_LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS) $(GNUTLS_LIBS) $(COMPRESS_LIBS) strip $@ ndmp_tape.o: ndmp_tape.c @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I../lib $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< btape: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(TAPEOBJS) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L. -L../lib -o $@ $(TAPEOBJS) \ -lbareossd -lbareoscfg -lbareos $(DLIB) -lm $(LIBS) $(GETTEXT_LIBS) \ $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bls: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(BLSOBJS) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L. -L../lib -L../findlib -o $@ $(BLSOBJS) $(DLIB) \ -lbareossd -lbareosfind -lbareoscfg -lbareos -lm $(LIBS) $(GETTEXT_LIBS) \ $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bextract: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(BEXTOBJS) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L. -L../lib -L../findlib -o $@ $(BEXTOBJS) $(DLIB) \ -lbareossd -lbareosfind -lbareoscfg -lbareos -lm $(LIBS) $(SD_LIBS) $(BEXTRACT_LIBS) \ $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bscan: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(SCNOBJS) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L. -L../lib -L../cats -L../findlib -o $@ $(SCNOBJS) \ -lbareossql -lbareoscats $(DB_LIBS) -lbareossd -lbareosfind -lbareoscfg -lbareos -lm $(LIBS) $(SD_LIBS) \ $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bcopy: Makefile libbareossd$(DEFAULT_ARCHIVE_TYPE) $(COPYOBJS) \ ../lib/libbareoscfg$(DEFAULT_ARCHIVE_TYPE) ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(TTOOL_LDFLAGS) $(LDFLAGS) -L. -L../lib -o $@ $(COPYOBJS) \ -lbareossd -lbareoscfg -lbareos -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-install: all $(MKDIR) $(DESTDIR)$(libdir) $(RMF) $(DESTDIR)$(libdir)/libbareossd-[0-9]*.so $(DESTDIR)$(libdir)/libbareossd.la $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) libbareossd.la $(DESTDIR)$(libdir) install: all @LIBTOOL_INSTALL_TARGET@ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bareos-sd $(DESTDIR)$(sbindir)/bareos-sd $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bls $(DESTDIR)$(sbindir)/bls $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bextract $(DESTDIR)$(sbindir)/bextract $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bcopy $(DESTDIR)$(sbindir)/bcopy $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) bscan $(DESTDIR)$(sbindir)/bscan $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) btape $(DESTDIR)$(sbindir)/btape @srcconf=bareos-sd.conf; \ $(MKDIR) ${DESTDIR}${sysconfdir}/bareos-sd.d/; \ if test -f ${DESTDIR}${sysconfdir}/$$srcconf; then \ destconf=$$srcconf.new; \ echo " ==> Found existing $$srcconf, installing new conf file as $$destconf"; \ else \ destconf=$$srcconf; \ fi; \ echo "${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf"; \ ${INSTALL_CONFIG} $$srcconf ${DESTDIR}${sysconfdir}/$$destconf -@if test "x${sd_group}" != "x"; then \ chgrp -f ${sd_group} ${DESTDIR}${sysconfdir}/$$destconf; \ fi @if test -f static-bareos-sd; then \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) static-bareos-sd $(DESTDIR)$(sbindir)/static-bareos-sd; \ fi libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) bareos-sd stored bls bextract bpool btape shmfree core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 @$(RMF) bscan bcopy static-bareos-sd realclean: clean @$(RMF) tags bareos-sd.conf distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) # Semi-automatic generation of dependencies: # Use cc -M because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(INCLUDES) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ======= Something went wrong with make depend. ======="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/stored/acquire.c000066400000000000000000000656541263011562700203440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2013 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Routines to acquire and release a device for read/write * * Kern Sibbald, August MMII */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ static int const rdbglvl = 100; /* Forward referenced functions */ static void attach_dcr_to_dev(DCR *dcr); static void detach_dcr_from_dev(DCR *dcr); static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol); /********************************************************************* * Acquire device for reading. * The drive should have previously been reserved by calling * reserve_device_for_read(). We read the Volume label from the block and * leave the block pointers just after the label. * * Returns: NULL if failed for any reason * dcr if successful */ bool acquire_device_for_read(DCR *dcr) { DEVICE *dev; JCR *jcr = dcr->jcr; bool ok = false; bool tape_previously_mounted; VOL_LIST *vol; bool try_autochanger = true; int i; int vol_label_status; int retry = 0; Enter(rdbglvl); dev = dcr->dev; dev->Lock_read_acquire(); Dmsg2(rdbglvl, "dcr=%p dev=%p\n", dcr, dcr->dev); Dmsg2(rdbglvl, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type); dev->dblock(BST_DOING_ACQUIRE); if (dev->num_writers > 0) { Jmsg2(jcr, M_FATAL, 0, _("Acquire read: num_writers=%d not zero. Job %d canceled.\n"), dev->num_writers, jcr->JobId); goto get_out; } /* Find next Volume, if any */ vol = jcr->VolList; if (!vol) { char ed1[50]; Jmsg(jcr, M_FATAL, 0, _("No volumes specified for reading. Job %s canceled.\n"), edit_int64(jcr->JobId, ed1)); goto get_out; } jcr->CurReadVolume++; for (i=1; iCurReadVolume; i++) { vol = vol->next; } if (!vol) { Jmsg(jcr, M_FATAL, 0, _("Logic error: no next volume to read. Numvol=%d Curvol=%d\n"), jcr->NumReadVolumes, jcr->CurReadVolume); goto get_out; /* should not happen */ } set_dcr_from_vol(dcr, vol); Dmsg2(rdbglvl, "Want Vol=%s Slot=%d\n", vol->VolumeName, vol->Slot); /* * If the MediaType requested for this volume is not the * same as the current drive, we attempt to find the same * device that was used to write the orginal volume. If * found, we switch to using that device. * * N.B. A lot of routines rely on the dcr pointer not changing * read_records.c even has multiple dcrs cached, so we take care * here to release all important parts of the dcr and re-acquire * them such as the block pointer (size may change), but we do * not release the dcr. */ Dmsg2(rdbglvl, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type); if (dcr->media_type[0] && !bstrcmp(dcr->media_type, dev->device->media_type)) { RCTX rctx; DIRSTORE *store; int status; Jmsg3(jcr, M_INFO, 0, _("Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n"), dcr->media_type, dev->device->media_type, dev->print_name()); Dmsg3(rdbglvl, "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n" " device=%s\n", dcr->media_type, dev->device->media_type, dev->print_name()); dev->dunblock(DEV_UNLOCKED); lock_reservations(); memset(&rctx, 0, sizeof(RCTX)); rctx.jcr = jcr; jcr->read_dcr = dcr; jcr->reserve_msgs = New(alist(10, not_owned_by_alist)); rctx.any_drive = true; rctx.device_name = vol->device; store = new DIRSTORE; memset(store, 0, sizeof(DIRSTORE)); store->name[0] = 0; /* No dir name */ bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type)); bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name)); bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type)); store->append = false; rctx.store = store; clean_device(dcr); /* clean up the dcr */ /* * Search for a new device */ status = search_res_for_device(rctx); release_reserve_messages(jcr); /* release queued messages */ unlock_reservations(); if (status == 1) { /* found new device to use */ /* * Switching devices, so acquire lock on new device, * then release the old one. */ dcr->dev->Lock_read_acquire(); /* lock new one */ dev->Unlock_read_acquire(); /* release old one */ dev = dcr->dev; /* get new device pointer */ dev->dblock(BST_DOING_ACQUIRE); dcr->VolumeName[0] = 0; Jmsg(jcr, M_INFO, 0, _("Media Type change. New read device %s chosen.\n"), dev->print_name()); Dmsg1(50, "Media Type change. New read device %s chosen.\n", dev->print_name()); bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName)); dcr->setVolCatName(vol->VolumeName); bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type)); dcr->VolCatInfo.Slot = vol->Slot; dcr->VolCatInfo.InChanger = vol->Slot > 0; bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name)); bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type)); } else { /* error */ Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"), vol->VolumeName); Dmsg1(rdbglvl, "No suitable device found to read Volume \"%s\"\n", vol->VolumeName); goto get_out; } } Dmsg2(rdbglvl, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type); dev->clear_unload(); if (dev->vol && dev->vol->is_swapping()) { dev->vol->set_slot(vol->Slot); Dmsg3(rdbglvl, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(), dev->vol->vol_name, dev->print_name()); } init_device_wait_timers(dcr); tape_previously_mounted = dev->can_read() || dev->can_append() || dev->is_labeled(); // tape_initially_mounted = tape_previously_mounted; /* Volume info is always needed because of VolParts */ Dmsg1(rdbglvl, "dir_get_volume_info vol=%s\n", dcr->VolumeName); if (!dcr->dir_get_volume_info(GET_VOL_INFO_FOR_READ)) { Dmsg2(rdbglvl, "dir_get_vol_info failed for vol=%s: %s\n", dcr->VolumeName, jcr->errmsg); Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg); } dev->set_load(); /* set to load volume */ for ( ;; ) { /* If not polling limit retries */ if (!dev->poll && retry++ > 10) { break; } dev->clear_labeled(); /* force reread of label */ if (job_canceled(jcr)) { char ed1[50]; Mmsg1(dev->errmsg, _("Job %s canceled.\n"), edit_int64(jcr->JobId, ed1)); Jmsg(jcr, M_INFO, 0, dev->errmsg); goto get_out; /* error return */ } dcr->do_unload(); dcr->do_swapping(false/*!is_writing*/); dcr->do_load(false /*!is_writing*/); set_dcr_from_vol(dcr, vol); /* refresh dcr with desired volume info */ /* * This code ensures that the device is ready for * reading. If it is a file, it opens it. * If it is a tape, it checks the volume name */ Dmsg1(rdbglvl, "stored: open vol=%s\n", dcr->VolumeName); if (!dev->open(dcr, OPEN_READ_ONLY)) { if (!dev->poll) { Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"), dev->print_name(), dcr->VolumeName, dev->bstrerror()); } goto default_path; } Dmsg1(rdbglvl, "opened dev %s OK\n", dev->print_name()); /* Read Volume Label */ Dmsg0(rdbglvl, "calling read-vol-label\n"); vol_label_status = read_dev_volume_label(dcr); switch (vol_label_status) { case VOL_OK: Dmsg0(rdbglvl, "Got correct volume.\n"); ok = true; dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */ break; /* got it */ case VOL_IO_ERROR: Dmsg0(rdbglvl, "IO Error\n"); /* * Send error message generated by read_dev_volume_label() * only we really had a tape mounted. This supresses superfluous * error messages when nothing is mounted. */ if (tape_previously_mounted) { Jmsg(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg); } goto default_path; case VOL_NAME_ERROR: Dmsg3(rdbglvl, "Vol name=%s want=%s drv=%s.\n", dev->VolHdr.VolumeName, dcr->VolumeName, dev->print_name()); if (dev->is_volume_to_unload()) { goto default_path; } dev->set_unload(); /* force unload of unwanted tape */ if (!unload_autochanger(dcr, -1)) { /* at least free the device so we can re-open with correct volume */ dev->close(dcr); free_volume(dev); } dev->set_load(); /* Fall through */ default: Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg); default_path: Dmsg0(rdbglvl, "default path\n"); tape_previously_mounted = true; /* * If the device requires mount, close it, so the device can be ejected. */ if (dev->requires_mount()) { dev->close(dcr); free_volume(dev); } /* Call autochanger only once unless ask_sysop called */ if (try_autochanger) { int status; Dmsg2(rdbglvl, "calling autoload Vol=%s Slot=%d\n", dcr->VolumeName, dcr->VolCatInfo.Slot); status = autoload_device(dcr, 0, NULL); if (status > 0) { try_autochanger = false; continue; /* try reading volume mounted */ } } /* Mount a specific volume and no other */ Dmsg0(rdbglvl, "calling dir_ask_sysop\n"); if (!dcr->dir_ask_sysop_to_mount_volume(ST_READREADY)) { goto get_out; /* error return */ } /* Volume info is always needed because of VolParts */ Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName); if (!dcr->dir_get_volume_info(GET_VOL_INFO_FOR_READ)) { Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n", dcr->VolumeName, jcr->errmsg); Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg); } dev->set_load(); /* set to load volume */ try_autochanger = true; /* permit trying the autochanger again */ continue; /* try reading again */ } /* end switch */ break; } /* end for loop */ if (!ok) { Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"), dev->print_name()); goto get_out; } dev->clear_append(); dev->set_read(); jcr->sendJobStatus(JS_Running); Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"), dcr->VolumeName, dev->print_name()); get_out: dev->Lock(); dcr->clear_reserved(); /* * Normally we are blocked, but in at least one error case above * we are not blocked because we unsuccessfully tried changing * devices. */ if (dev->is_blocked()) { dev->dunblock(DEV_LOCKED); } else { dev->Unlock(); /* dunblock() unlock the device too */ } Dmsg2(rdbglvl, "dcr=%p dev=%p\n", dcr, dcr->dev); Dmsg2(rdbglvl, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type); dev->Unlock_read_acquire(); Leave(rdbglvl); return ok; } /* * Acquire device for writing. We permit multiple writers. * If this is the first one, we read the label. * * Returns: NULL if failed for any reason * dcr if successful. * Note, normally reserve_device_for_append() is called * before this routine. */ DCR *acquire_device_for_append(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; bool ok = false; bool have_vol = false; Enter(200); init_device_wait_timers(dcr); dev->Lock_acquire(); /* only one job at a time */ dev->Lock(); Dmsg1(100, "acquire_append device is %s\n", dev->is_tape() ? "tape" : "disk"); /* * With the reservation system, this should not happen */ if (dev->can_read()) { Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name()); Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name()); goto get_out; } dev->clear_unload(); /* * have_vol defines whether or not mount_next_write_volume should * ask the Director again about what Volume to use. */ if (dev->can_append() && dcr->is_suitable_volume_mounted() && !bstrcmp(dcr->VolCatInfo.VolCatStatus, "Recycle")) { Dmsg0(190, "device already in append.\n"); /* * At this point, the correct tape is already mounted, so * we do not need to do mount_next_write_volume(), unless * we need to recycle the tape. */ if (dev->num_writers == 0) { dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */ } have_vol = dcr->is_tape_position_ok(); } if (!have_vol) { dev->rLock(true); block_device(dev, BST_DOING_ACQUIRE); dev->Unlock(); Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId); if (!dcr->mount_next_write_volume()) { if (!job_canceled(jcr)) { /* Reduce "noise" -- don't print if job canceled */ Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"), dev->print_name()); Dmsg1(200, "Could not ready device %s for append.\n", dev->print_name()); } dev->Lock(); unblock_device(dev); goto get_out; } Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num); dev->Lock(); unblock_device(dev); } dev->num_writers++; /* we are now a writer */ if (jcr->NumWriteVolumes == 0) { jcr->NumWriteVolumes = 1; } dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */ Dmsg4(100, "=== nwriters=%d nres=%d vcatjob=%d dev=%s\n", dev->num_writers, dev->num_reserved(), dev->VolCatInfo.VolCatJobs, dev->print_name()); dcr->dir_update_volume_info(false, false); /* send Volume info to Director */ ok = true; get_out: /* Don't plugin close here, we might have multiple writers */ dcr->clear_reserved(); dev->Unlock(); dev->Unlock_acquire(); Leave(200); return ok ? dcr : NULL; } /* * This job is done, so release the device. From a Unix standpoint, * the device remains open. * * Note, if we were spooling, we may enter with the device blocked. * We unblock at the end, only if it was us who blocked the * device. * */ bool release_device(DCR *dcr) { utime_t now; JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; bool ok = true; char tbuf[100]; int was_blocked = BST_NOT_BLOCKED; /* * Capture job statistics now that we are done using this device. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); dev->Lock(); if (!dev->is_blocked()) { block_device(dev, BST_RELEASING); } else { was_blocked = dev->blocked(); dev->set_blocked(BST_RELEASING); } lock_volumes(); Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape() ? "tape" : "disk"); /* * If device is reserved, job never started, so release the reserve here */ dcr->clear_reserved(); if (dev->can_read()) { VOLUME_CAT_INFO *vol = &dev->VolCatInfo; dev->clear_read(); /* clear read bit */ Dmsg2(150, "dir_update_vol_info. label=%d Vol=%s\n", dev->is_labeled(), vol->VolCatName); if (dev->is_labeled() && vol->VolCatName[0] != 0) { dcr->dir_update_volume_info(false, false); /* send Volume info to Director */ remove_read_volume(jcr, dcr->VolumeName); volume_unused(dcr); } } else if (dev->num_writers > 0) { /* * Note if WEOT is set, we are at the end of the tape and may not be positioned correctly, * so the job_media_record and update_vol_info have already been done, * which means we skip them here. */ dev->num_writers--; Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers); if (dev->is_labeled()) { Dmsg2(200, "dir_create_jobmedia. Release vol=%s dev=%s\n", dev->getVolCatName(), dev->print_name()); if (!dev->at_weot() && !dcr->dir_create_jobmedia_record(false)) { Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->getVolCatName(), jcr->Job); } /* * If no more writers, and no errors, and wrote something, write an EOF */ if (!dev->num_writers && dev->can_write() && dev->block_num > 0) { dev->weof(1); write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName); } if (!dev->at_weot()) { dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */ /* * Note! do volume update before close, which zaps VolCatInfo */ dcr->dir_update_volume_info(false, false); /* send Volume info to Director */ Dmsg2(200, "dir_update_vol_info. Release vol=%s dev=%s\n", dev->getVolCatName(), dev->print_name()); } if (dev->num_writers == 0) { /* if not being used */ volume_unused(dcr); /* we obviously are not using the volume */ } } } else { /* * If we reach here, it is most likely because the job has failed, * since the device is not in read mode and there are no writers. * It was probably reserved. */ volume_unused(dcr); } Dmsg3(100, "%d writers, %d reserve, dev=%s\n", dev->num_writers, dev->num_reserved(), dev->print_name()); /* * If no writers, close if file or !CAP_ALWAYS_OPEN */ if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) { dev->close(dcr); free_volume(dev); } unlock_volumes(); /* * Fire off Alert command and include any output */ if (!job_canceled(jcr)) { if (!dcr->device->drive_tapealert_enabled && dcr->device->alert_command) { int status = 1; POOLMEM *alert, *line; BPIPE *bpipe; alert = get_pool_memory(PM_FNAME); line = get_pool_memory(PM_FNAME); alert = edit_device_codes(dcr, alert, dcr->device->alert_command, ""); /* * Wait maximum 5 minutes */ bpipe = open_bpipe(alert, 60 * 5, "r"); if (bpipe) { while (bfgets(line, bpipe->rfd)) { Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line); } status = close_bpipe(bpipe); } else { status = errno; } if (status != 0) { berrno be; Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"), alert, be.bstrerror(status)); } Dmsg1(400, "alert status=%d\n", status); free_pool_memory(alert); free_pool_memory(line); } else { /* * If all reservations are cleared for this device raise an event that SD plugins can register to. */ if (dev->num_reserved() == 0) { generate_plugin_event(jcr, bsdEventDeviceReleased, dcr); } } } pthread_cond_broadcast(&dev->wait_next_vol); Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n", (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); release_device_cond(); /* * If we are the thread that blocked the device, then unblock it */ if (pthread_equal(dev->no_wait_id, pthread_self())) { dev->dunblock(true); } else { /* * Otherwise, reset the prior block status and unlock */ dev->set_blocked(was_blocked); dev->Unlock(); } if (dcr->keep_dcr) { detach_dcr_from_dev(dcr); } else { free_dcr(dcr); } Dmsg2(100, "Device %s released by JobId=%u\n", dev->print_name(), (uint32_t)jcr->JobId); return ok; } /* * Clean up the device for reuse without freeing the memory */ bool clean_device(DCR *dcr) { bool ok; dcr->keep_dcr = true; /* do not free the dcr */ ok = release_device(dcr); dcr->keep_dcr = false; return ok; } /* * DCR Constructor. */ DCR::DCR() { POOL_MEM errmsg(PM_MESSAGE); int errstat; tid = pthread_self(); spool_fd = -1; if ((errstat = pthread_mutex_init(&m_mutex, NULL)) != 0) { berrno be; Mmsg(errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(NULL, M_ERROR_TERM, 0, errmsg.c_str()); } if ((errstat = pthread_mutex_init(&r_mutex, NULL)) != 0) { berrno be; Mmsg(errmsg, _("Unable to init r_mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(NULL, M_ERROR_TERM, 0, errmsg.c_str()); } } /* * Setup DCR with a new device. */ void setup_new_dcr_device(JCR *jcr, DCR *dcr, DEVICE *dev, BLOCKSIZES *blocksizes) { dcr->jcr = jcr; /* point back to jcr */ /* * Set device information, possibly change device */ if (dev) { /* * Set wanted blocksizes */ if (blocksizes) { dev->min_block_size = blocksizes->min_block_size; dev->max_block_size = blocksizes->max_block_size; } if (dcr->block) { free_block(dcr->block); } dcr->block = new_block(dev); if (dcr->rec) { free_record(dcr->rec); dcr->rec = NULL; } dcr->rec = new_record(); if (dcr->attached_to_dev) { detach_dcr_from_dev(dcr); } /* * Use job spoolsize prior to device spoolsize */ if (jcr && jcr->spool_size) { dcr->max_job_spool_size = jcr->spool_size; } else { dcr->max_job_spool_size = dev->device->max_job_spool_size; } dcr->device = dev->device; dcr->set_dev(dev); attach_dcr_to_dev(dcr); /* * Initialize the auto deflation/inflation which can * be disabled per DCR when we want to. e.g. when we want to * send the data as part of a replication stream in which we * don't want to first inflate the data to then again * do deflation for sending it to the other storage daemon. */ dcr->autodeflate = dcr->device->autodeflate; dcr->autoinflate = dcr->device->autoinflate; } } /* * Search the dcrs list for the given dcr. If it is found, * as it should be, then remove it. Also zap the jcr pointer * to the dcr if it is the same one. * * Note, this code will be turned on when we can write to multiple * dcrs at the same time. */ #ifdef needed static void remove_dcr_from_dcrs(DCR *dcr) { JCR *jcr = dcr->jcr; if (jcr->dcrs) { int i = 0; DCR *ldcr; int num = jcr->dcrs->size(); for (i=0; i < num; i++) { ldcr = (DCR *)jcr->dcrs->get(i); if (ldcr == dcr) { jcr->dcrs->remove(i); if (jcr->dcr == dcr) { jcr->dcr = NULL; } } } } } #endif static void attach_dcr_to_dev(DCR *dcr) { DEVICE *dev; JCR *jcr; P(dcr->m_mutex); dev = dcr->dev; jcr = dcr->jcr; if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId); /* ***FIXME*** return error if dev not initiated */ if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->getJobType() != JT_SYSTEM) { dev->Lock(); Dmsg4(200, "Attach Jid=%d dcr=%p size=%d dev=%s\n", (uint32_t)jcr->JobId, dcr, dev->attached_dcrs->size(), dev->print_name()); dev->attached_dcrs->append(dcr); /* attach dcr to device */ dev->Unlock(); dcr->attached_to_dev = true; } V(dcr->m_mutex); } /* * DCR is locked before calling this routine */ static void locked_detach_dcr_from_dev(DCR *dcr) { DEVICE *dev = dcr->dev; Dmsg0(500, "Enter detach_dcr_from_dev\n"); /* jcr is NULL in some cases */ /* Detach this dcr only if attached */ if (dcr->attached_to_dev && dev) { dcr->unreserve_device(); dev->Lock(); Dmsg4(200, "Detach Jid=%d dcr=%p size=%d to dev=%s\n", (uint32_t)dcr->jcr->JobId, dcr, dev->attached_dcrs->size(), dev->print_name()); dcr->attached_to_dev = false; if (dev->attached_dcrs->size()) { dev->attached_dcrs->remove(dcr); /* detach dcr from device */ } // remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */ dev->Unlock(); } dcr->attached_to_dev = false; } static void detach_dcr_from_dev(DCR *dcr) { P(dcr->m_mutex); locked_detach_dcr_from_dev(dcr); V(dcr->m_mutex); } /* * Free up all aspects of the given dcr -- i.e. dechain it, * release allocated memory, zap pointers, ... */ void free_dcr(DCR *dcr) { JCR *jcr; P(dcr->m_mutex); jcr = dcr->jcr; locked_detach_dcr_from_dev(dcr); if (dcr->block) { free_block(dcr->block); } if (dcr->rec) { free_record(dcr->rec); } if (jcr && jcr->dcr == dcr) { jcr->dcr = NULL; } if (jcr && jcr->read_dcr == dcr) { jcr->read_dcr = NULL; } V(dcr->m_mutex); pthread_mutex_destroy(&dcr->m_mutex); pthread_mutex_destroy(&dcr->r_mutex); delete dcr; } static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol) { /* * Note, if we want to be able to work from a .bsr file only * for disaster recovery, we must "simulate" reading the catalog */ bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName)); dcr->setVolCatName(vol->VolumeName); bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type)); dcr->VolCatInfo.Slot = vol->Slot; dcr->VolCatInfo.InChanger = vol->Slot > 0; } bareos-Release-14.2.6/src/stored/ansi_label.c000066400000000000000000000372041263011562700207720ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * ansi_label.c routines to handle ANSI (and perhaps one day IBM) tape labels. * * Kern Sibbald, MMV */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ /* Imported functions */ void ascii_to_ebcdic(char *dst, char *src, int count); void ebcdic_to_ascii(char *dst, char *src, int count); /* Forward referenced functions */ static char *ansi_date(time_t td, char *buf); static bool same_label_names(char *bareos_name, char *ansi_name); /* * We read an ANSI label and compare the Volume name. We require * a VOL1 record of 80 characters followed by a HDR1 record containing * BAREOS.DATA in the filename field. We then read up to 3 more * header records (they are not required) and an EOF, at which * point, all is good. * * Returns: * VOL_OK Volume name OK * VOL_NO_LABEL No ANSI label on Volume * VOL_IO_ERROR I/O error on read * VOL_NAME_ERROR Wrong name in VOL1 record * VOL_LABEL_ERROR Probably an ANSI label, but something wrong */ int read_ansi_ibm_label(DCR *dcr) { DEVICE * volatile dev = dcr->dev; JCR *jcr = dcr->jcr; char label[80]; /* tape label */ int status, i; char *VolName = dcr->VolumeName; bool ok = false; /* * Read VOL1, HDR1, HDR2 labels, but ignore the data * If tape read the following EOF mark, on disk do not read. */ Dmsg0(100, "Read ansi label.\n"); if (!dev->is_tape()) { return VOL_OK; } dev->label_type = B_BAREOS_LABEL; /* assume Bareos label */ /* * Read a maximum of 5 records VOL1, HDR1, ... HDR4 */ for (i = 0; i < 6; i++) { do { status = dev->read(label, sizeof(label)); } while (status == -1 && errno == EINTR); if (status < 0) { berrno be; dev->clrerror(-1); Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror()); Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"), dev->dev_name, be.bstrerror()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dev->VolCatInfo.VolCatErrors++; return VOL_IO_ERROR; } if (status == 0) { if (dev->at_eof()) { dev->set_eot(); /* second eof, set eot bit */ Dmsg0(100, "EOM on ANSI label\n"); Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n")); return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */ } else { dev->set_ateof(); /* set eof state */ } } switch (i) { case 0: /* Want VOL1 label */ if (status == 80) { if (bstrncmp("VOL1", label, 4)) { ok = true; dev->label_type = B_ANSI_LABEL; Dmsg0(100, "Got ANSI VOL1 label\n"); } else { /* * Try EBCDIC */ ebcdic_to_ascii(label, label, sizeof(label)); if (bstrncmp("VOL1", label, 4)) { ok = true;; dev->label_type = B_IBM_LABEL; Dmsg0(100, "Found IBM label.\n"); Dmsg0(100, "Got IBM VOL1 label\n"); } } } if (!ok) { Dmsg0(100, "No VOL1 label\n"); Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n")); return VOL_NO_LABEL; /* No ANSI label */ } /* * Compare Volume Names allow special wild card */ if (VolName && *VolName && *VolName != '*') { if (!same_label_names(VolName, &label[4])) { char *p = &label[4]; char *q; free_volume(dev); /* * Store new Volume name */ q = dev->VolHdr.VolumeName; for (int i=0; *p != ' ' && i < 6; i++) { *q++ = *p++; } *q = 0; Dmsg0(100, "Call reserve_volume\n"); /* * ***FIXME*** why is this reserve_volume() needed???? KES */ reserve_volume(dcr, dev->VolHdr.VolumeName); dev = dcr->dev; /* may have changed in reserve_volume */ Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName); Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName); return VOL_NAME_ERROR; } } break; case 1: if (dev->label_type == B_IBM_LABEL) { ebcdic_to_ascii(label, label, sizeof(label)); } if (status != 80 || !bstrncmp("HDR1", label, 4)) { Dmsg0(100, "No HDR1 label\n"); Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n")); return VOL_LABEL_ERROR; } if (me->compatible) { if (!bstrncmp("BACULA.DATA", &label[4], 11) && !bstrncmp("BAREOS.DATA", &label[4], 11)) { Dmsg1(100, "HD1 not Bacula/Bareos label. Wanted BACULA.DATA/BAREOS.DATA got %11s\n", &label[4]); Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bareos.\n"), dev->VolHdr.VolumeName); return VOL_NAME_ERROR; /* Not a Bareos label */ } } else { if (!bstrncmp("BAREOS.DATA", &label[4], 11)) { Dmsg1(100, "HD1 not Bareos label. Wanted BAREOS.DATA got %11s\n", &label[4]); Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bareos.\n"), dev->VolHdr.VolumeName); return VOL_NAME_ERROR; /* Not a Bareos label */ } } Dmsg0(100, "Got HDR1 label\n"); break; case 2: if (dev->label_type == B_IBM_LABEL) { ebcdic_to_ascii(label, label, sizeof(label)); } if (status != 80 || !bstrncmp("HDR2", label, 4)) { Dmsg0(100, "No HDR2 label\n"); Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n")); return VOL_LABEL_ERROR; } Dmsg0(100, "Got ANSI HDR2 label\n"); break; default: if (status == 0) { Dmsg0(100, "ANSI label OK\n"); return VOL_OK; } if (dev->label_type == B_IBM_LABEL) { ebcdic_to_ascii(label, label, sizeof(label)); } if (status != 80 || !bstrncmp("HDR", label, 3)) { Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n"); Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n")); return VOL_LABEL_ERROR; } Dmsg0(100, "Got HDR label\n"); break; } } Dmsg0(100, "Too many records in ANSI/IBM label.\n"); Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n")); return VOL_LABEL_ERROR; } /* * ANSI/IBM VOL1 label * 80 characters blank filled * Pos count Function What Bareos puts * 0-3 4 "VOL1" VOL1 * 4-9 6 Volume name Volume name * 10-10 1 Access code * 11-36 26 Unused * * ANSI * 37-50 14 Owner * 51-78 28 reserved * 79 1 ANSI level 3 * * IBM * 37-40 4 reserved * 41-50 10 Owner * 51-79 29 reserved * * ANSI/IBM HDR1 label * 80 characters blank filled * Pos count Function What Bareos puts * 0-3 4 "HDR1" HDR1 * 4-20 17 File name BAREOS.DATA * 21-26 6 Volume name Volume name * 27-30 4 Vol seq num 0001 * 31-34 4 file num 0001 * 35-38 4 Generation 0001 * 39-40 2 Gen version 00 * 41-46 6 Create date bYYDDD yesterday * 47-52 6 Expire date bYYDDD today * 53-53 1 Access * 54-59 6 Block count 000000 * 60-72 13 Software name Bareos * 73-79 7 Reserved * * ANSI/IBM HDR2 label * 80 characters blank filled * Pos count Function What Bareos puts * 0-3 4 "HDR2" HDR2 * 4-4 1 Record format D (V if IBM) => variable * 5-9 5 Block length 32000 * 10-14 5 Rec length 32000 * 15-15 1 Density * 16-16 1 Continued * 17-33 17 Job * 34-35 2 Recording * 36-36 1 cr/lf ctl * 37-37 1 reserved * 38-38 1 Blocked flag * 39-49 11 reserved * 50-51 2 offset * 52-79 28 reserved */ static const char *labels[] = {"HDR", "EOF", "EOV"}; /* * Write an ANSI or IBM 80 character tape label * * Type determines whether we are writing HDR, EOF, or EOV labels * Assume we are positioned to write the labels * Returns: true of OK * false if error */ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; char ansi_volname[7]; /* 6 char + \0 */ char label[80]; /* tape label */ char date[20]; /* ansi date buffer */ time_t now; int len, status, label_type; /* * If the Device requires a specific label type use it, * otherwise, use the type requested by the Director */ if (dcr->device->label_type != B_BAREOS_LABEL) { label_type = dcr->device->label_type; /* force label type */ } else { label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */ } switch (label_type) { case B_BAREOS_LABEL: return true; case B_ANSI_LABEL: case B_IBM_LABEL: ser_declare; Dmsg1(100, "Write ANSI label type=%d\n", label_type); len = strlen(VolName); if (len > 6) { Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"), VolName); return false; } /* * ANSI labels have 6 characters, and are padded with spaces 'vol1\0' => 'vol1 \0' */ strcpy(ansi_volname, VolName); for(int i=len; i < 6; i++) { ansi_volname[i]=' '; } ansi_volname[6]='\0'; /* only for debug */ if (type == ANSI_VOL_LABEL) { ser_begin(label, sizeof(label)); ser_bytes("VOL1", 4); ser_bytes(ansi_volname, 6); /* * Write VOL1 label */ if (label_type == B_IBM_LABEL) { ascii_to_ebcdic(label, label, sizeof(label)); } else { label[79] = '3'; /* ANSI label flag */ } status = dev->write(label, sizeof(label)); if (status != sizeof(label)) { berrno be; Jmsg3(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n"), sizeof(label), status, be.bstrerror()); return false; } } /* * Now construct HDR1 label */ memset(label, ' ', sizeof(label)); ser_begin(label, sizeof(label)); ser_bytes(labels[type], 3); ser_bytes("1", 1); if (me->compatible) { ser_bytes("BACULA.DATA", 11); /* Filename field */ } else { ser_bytes("BAREOS.DATA", 11); /* Filename field */ } ser_begin(&label[21], sizeof(label)-21); /* fileset field */ ser_bytes(ansi_volname, 6); /* write Vol Ser No. */ ser_begin(&label[27], sizeof(label)-27); ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */ now = time(NULL); ser_bytes(ansi_date(now, date), 6); /* current date */ ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */ ser_bytes(" 000000Bareos ", 27); /* * Write HDR1 label */ if (label_type == B_IBM_LABEL) { ascii_to_ebcdic(label, label, sizeof(label)); } /* * This could come at the end of a tape, ignore EOT errors. */ status = dev->write(label, sizeof(label)); if (status != sizeof(label)) { berrno be; if (status == -1) { dev->clrerror(-1); if (dev->dev_errno == 0) { dev->dev_errno = ENOSPC; /* out of space */ } if (dev->dev_errno != ENOSPC) { Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"), be.bstrerror()); return false; } } else { Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n")); return false; } } /* * Now construct HDR2 label */ memset(label, ' ', sizeof(label)); ser_begin(label, sizeof(label)); ser_bytes(labels[type], 3); ser_bytes("2D3200032000", 12); /* * Write HDR2 label */ if (label_type == B_IBM_LABEL) { label[4] = 'V'; ascii_to_ebcdic(label, label, sizeof(label)); } status = dev->write(label, sizeof(label)); if (status != sizeof(label)) { berrno be; if (status == -1) { dev->clrerror(-1); if (dev->dev_errno == 0) { dev->dev_errno = ENOSPC; /* out of space */ } if (dev->dev_errno != ENOSPC) { Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"), be.bstrerror()); return false; } dev->weof(1); return true; } else { Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n")); return false; } } if (!dev->weof(1)) { Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg); return false; } return true; default: Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n")); return false; /* should not get here */ } } /* * Check a Bareos Volume name against an ANSI Volume name */ static bool same_label_names(char *bareos_name, char *ansi_name) { char *a = ansi_name; char *b = bareos_name; /* * Six characters max */ for (int i=0; i < 6; i++) { if (*a == *b) { a++; b++; continue; } /* * ANSI labels are blank filled, Bareos's are zero terminated */ if (*a == ' ' && *b == 0) { return true; } return false; } /* * Reached 6 characters */ b++; if (*b == 0) { return true; } return false; } /* * ANSI date * ' 'YYDDD */ static char *ansi_date(time_t td, char *buf) { struct tm *tm; if (td == 0) { td = time(NULL); } tm = gmtime(&td); bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday); return buf; } bareos-Release-14.2.6/src/stored/append.c000066400000000000000000000271071263011562700201510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Append code for Storage daemon * * Kern Sibbald, May MM */ #include "bareos.h" #include "stored.h" /* Responses sent to the daemon */ static char OK_data[] = "3000 OK data\n"; static char OK_append[] = "3000 OK append data\n"; static char OK_replicate[] = "3000 OK replicate data\n"; /* Forward referenced functions */ /* */ void possible_incomplete_job(JCR *jcr, int32_t last_file_index) { } /* * Append Data sent from File daemon */ bool do_append_data(JCR *jcr, BSOCK *bs, const char *what) { int32_t n, file_index, stream, last_file_index, job_elapsed; bool ok = true; char buf1[100]; DCR *dcr = jcr->dcr; DEVICE *dev; POOLMEM *rec_data; char ec[50]; if (!dcr) { Jmsg0(jcr, M_FATAL, 0, _("DCR is NULL!!!\n")); return false; } dev = dcr->dev; if (!dev) { Jmsg0(jcr, M_FATAL, 0, _("DEVICE is NULL!!!\n")); return false; } Dmsg1(100, "Start append data. res=%d\n", dev->num_reserved()); if (!bs->set_buffer_size(dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) { Jmsg0(jcr, M_FATAL, 0, _("Unable to set network buffer size.\n")); goto bail_out; } if (!acquire_device_for_append(dcr)) { goto bail_out; } if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { goto bail_out; } jcr->sendJobStatus(JS_Running); if (dev->VolCatInfo.VolCatName[0] == 0) { Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); } Dmsg1(50, "Begin append device=%s\n", dev->print_name()); if (!begin_data_spool(dcr) ) { goto bail_out; } if (!begin_attribute_spool(jcr)) { discard_data_spool(dcr); goto bail_out; } Dmsg0(100, "Just after acquire_device_for_append\n"); if (dev->VolCatInfo.VolCatName[0] == 0) { Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); } /* * Write Begin Session Record */ if (!write_session_label(dcr, SOS_LABEL)) { Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"), dev->bstrerror()); jcr->setJobStatus(JS_ErrorTerminated); ok = false; } if (dev->VolCatInfo.VolCatName[0] == 0) { Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); } /* * Tell daemon to send data */ if (!bs->fsend(OK_data)) { berrno be; Jmsg2(jcr, M_FATAL, 0, _("Network send error to %s. ERR=%s\n"), what, be.bstrerror(bs->b_errno)); ok = false; } /* * Get Data from daemon, write to device. To clarify what is * going on here. We expect: * - A stream header * - Multiple records of data * - EOD record * * The Stream header is just used to sychronize things, and * none of the stream header is written to tape. * The Multiple records of data, contain first the Attributes, * then after another stream header, the file data, then * after another stream header, the MD5 data if any. * * So we get the (stream header, data, EOD) three time for each * file. 1. for the Attributes, 2. for the file data if any, * and 3. for the MD5 if any. */ dcr->VolFirstIndex = dcr->VolLastIndex = 0; jcr->run_time = time(NULL); /* start counting time for rates */ for (last_file_index = 0; ok && !jcr->is_job_canceled(); ) { /* * Read Stream header from the daemon. * * The stream header consists of the following: * - file_index (sequential Bareos file index, base 1) * - stream (Bareos number to distinguish parts of data) * - info (Info for Storage daemon -- compressed, encrypted, ...) * info is not currently used, so is read, but ignored! */ if ((n = bget_msg(bs)) <= 0) { if (n == BNET_SIGNAL && bs->msglen == BNET_EOD) { break; /* end of data */ } Jmsg2(jcr, M_FATAL, 0, _("Error reading data header from %s. ERR=%s\n"), what, bs->bstrerror()); possible_incomplete_job(jcr, last_file_index); ok = false; break; } if (sscanf(bs->msg, "%ld %ld", &file_index, &stream) != 2) { Jmsg2(jcr, M_FATAL, 0, _("Malformed data header from %s: %s\n"), what, bs->msg); ok = false; possible_incomplete_job(jcr, last_file_index); break; } Dmsg2(890, "rerunning && file_index > 0 && last_file_index == 0) { goto fi_checked; } if (file_index > 0 && (file_index == last_file_index || file_index == last_file_index + 1)) { goto fi_checked; } Jmsg3(jcr, M_FATAL, 0, _("FI=%d from %s not positive or sequential=%d\n"), file_index, what, last_file_index); possible_incomplete_job(jcr, last_file_index); ok = false; break; fi_checked: if (file_index != last_file_index) { jcr->JobFiles = file_index; last_file_index = file_index; } /* * Read data stream from the daemon. The data stream is just raw bytes. * We save the original data pointer from the record so we can restore * that after the loop ends. */ rec_data = dcr->rec->data; while ((n = bget_msg(bs)) > 0 && !jcr->is_job_canceled()) { dcr->rec->VolSessionId = jcr->VolSessionId; dcr->rec->VolSessionTime = jcr->VolSessionTime; dcr->rec->FileIndex = file_index; dcr->rec->Stream = stream; dcr->rec->maskedStream = stream & STREAMMASK_TYPE; /* strip high bits */ dcr->rec->data_len = bs->msglen; dcr->rec->data = bs->msg; /* use message buffer */ Dmsg4(850, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n", dcr->rec->FileIndex, dcr->rec->VolSessionId, stream_to_ascii(buf1, dcr->rec->Stream, dcr->rec->FileIndex), dcr->rec->data_len); ok = dcr->write_record(); if (!ok) { Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n", dcr->dev->print_name(), dcr->dev->bstrerror()); break; } send_attrs_to_dir(jcr, dcr->rec); Dmsg0(650, "Enter bnet_get\n"); } Dmsg2(650, "End read loop with %s. Stat=%d\n", what, n); /* * Restore the original data pointer. */ dcr->rec->data = rec_data; if (bs->is_error()) { if (!jcr->is_job_canceled()) { Dmsg2(350, "Network read error from %s. ERR=%s\n", what, bs->bstrerror()); Jmsg2(jcr, M_FATAL, 0, _("Network error reading from %s. ERR=%s\n"), what, bs->bstrerror()); possible_incomplete_job(jcr, last_file_index); } ok = false; break; } } /* * Create Job status for end of session label */ jcr->setJobStatus(ok ? JS_Terminated : JS_ErrorTerminated); if (ok && bs == jcr->file_bsock) { /* * Terminate connection with FD */ bs->fsend(OK_append); do_fd_commands(jcr); /* finish dialog with FD */ } else if (bs == jcr->store_bsock) { bs->fsend(OK_replicate); } else { bs->fsend("3999 Failed append\n"); } Dmsg1(200, "Write EOS label JobStatus=%c\n", jcr->JobStatus); /* * Check if we can still write. This may not be the case * if we are at the end of the tape or we got a fatal I/O error. */ if (ok || dev->can_write()) { if (!write_session_label(dcr, EOS_LABEL)) { /* * Print only if ok and not cancelled to avoid spurious messages */ if (ok && !jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Error writing end session label. ERR=%s\n"), dev->bstrerror()); possible_incomplete_job(jcr, last_file_index); } jcr->setJobStatus(JS_ErrorTerminated); ok = false; } Dmsg0(90, "back from write_end_session_label()\n"); /* * Flush out final partial block of this session */ if (!dcr->write_block_to_device()) { /* * Print only if ok and not cancelled to avoid spurious messages */ if (ok && !jcr->is_job_canceled()) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n")); possible_incomplete_job(jcr, last_file_index); } jcr->setJobStatus(JS_ErrorTerminated); ok = false; } } if (!ok && !jcr->is_JobStatus(JS_Incomplete)) { discard_data_spool(dcr); } else { /* * Note: if commit is OK, the device will remain blocked */ commit_data_spool(dcr); } /* * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits, * and the subsequent Jmsg() editing will break */ job_elapsed = time(NULL) - jcr->run_time; if (job_elapsed <= 0) { job_elapsed = 1; } Jmsg(dcr->jcr, M_INFO, 0, _("Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n"), job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60, edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec)); /* * Release the device -- and send final Vol info to DIR and unlock it. */ release_device(dcr); if ((!ok || jcr->is_job_canceled()) && !jcr->is_JobStatus(JS_Incomplete)) { discard_attribute_spool(jcr); } else { commit_attribute_spool(jcr); } jcr->sendJobStatus(); /* update director */ Dmsg1(100, "return from do_append_data() ok=%d\n", ok); return ok; bail_out: jcr->setJobStatus(JS_ErrorTerminated); return false; } /* * Send attributes and digest to Director for Catalog */ bool send_attrs_to_dir(JCR *jcr, DEV_RECORD *rec) { if (rec->maskedStream == STREAM_UNIX_ATTRIBUTES || rec->maskedStream == STREAM_UNIX_ATTRIBUTES_EX || rec->maskedStream == STREAM_RESTORE_OBJECT || crypto_digest_stream_type(rec->maskedStream) != CRYPTO_DIGEST_NONE) { if (!jcr->no_attributes) { BSOCK *dir = jcr->dir_bsock; if (are_attributes_spooled(jcr)) { dir->set_spooling(); } Dmsg0(850, "Send attributes to dir.\n"); if (!jcr->dcr->dir_update_file_attributes(rec)) { Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"), dir->bstrerror()); dir->clear_spooling(); return false; } dir->clear_spooling(); } } return true; } bareos-Release-14.2.6/src/stored/askdir.c000066400000000000000000000563421263011562700201620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Subroutines to handle Catalog reqests sent to the Director * Reqests/commands from the Director are handled in dircmd.c * * Kern Sibbald, December 2000 */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ #include "lib/crypto_cache.h" static const int dbglvl = 200; static pthread_mutex_t vol_info_mutex = PTHREAD_MUTEX_INITIALIZER; /* Requests sent to the Director */ static char Find_media[] = "CatReq Job=%s FindMedia=%d pool_name=%s media_type=%s\n"; static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n"; static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s" " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u" " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%s VolStatus=%s" " Slot=%d relabel=%d InChanger=%d VolReadTime=%s VolWriteTime=%s" " VolFirstWritten=%s\n"; static char Create_job_media[] = "CatReq Job=%s CreateJobMedia" " FirstIndex=%u LastIndex=%u StartFile=%u EndFile=%u" " StartBlock=%u EndBlock=%u Copy=%d Strip=%d MediaId=%s\n"; static char FileAttributes[] = "UpdCat Job=%s FileAttributes "; /* Responses received from the Director */ static char OK_media[] = "1000 OK VolName=%127s VolJobs=%u VolFiles=%lu" " VolBlocks=%lu VolBytes=%lld VolMounts=%lu VolErrors=%lu VolWrites=%lu" " MaxVolBytes=%lld VolCapacityBytes=%lld VolStatus=%20s" " Slot=%ld MaxVolJobs=%lu MaxVolFiles=%lu InChanger=%ld" " VolReadTime=%lld VolWriteTime=%lld EndFile=%lu EndBlock=%lu" " LabelType=%ld MediaId=%lld EncryptionKey=%127s" " MinBlocksize=%lu MaxBlocksize=%lu\n"; static char OK_create[] = "1000 OK CreateJobMedia\n"; #ifdef needed static char Device_update[] = "DevUpd Job=%s device=%s " "append=%d read=%d num_writers=%d " "open=%d labeled=%d offline=%d " "reserved=%d max_writers=%d " "autoselect=%d autochanger=%d " "changer_name=%s media_type=%s volume_name=%s\n"; /* * Send update information about a device to Director */ bool SD_DCR::dir_update_device(JCR *jcr, DEVICE *dev) { BSOCK *dir = jcr->dir_bsock; POOL_MEM dev_name, VolumeName, MediaType, ChangerName; DEVRES *device = dev->device; bool ok; pm_strcpy(dev_name, device->hdr.name); bash_spaces(dev_name); if (dev->is_labeled()) { pm_strcpy(VolumeName, dev->VolHdr.VolumeName); } else { pm_strcpy(VolumeName, "*"); } bash_spaces(VolumeName); pm_strcpy(MediaType, device->media_type); bash_spaces(MediaType); if (device->changer_res) { pm_strcpy(ChangerName, device->changer_res->hdr.name); bash_spaces(ChangerName); } else { pm_strcpy(ChangerName, "*"); } ok = dir->fsend(Device_update, jcr->Job, dev_name.c_str(), dev->can_append()!=0, dev->can_read()!=0, dev->num_writers, dev->is_open()!=0, dev->is_labeled()!=0, dev->is_offline()!=0, dev->reserved_device, dev->is_tape()?100000:1, dev->autoselect, 0, ChangerName.c_str(), MediaType.c_str(), VolumeName.c_str()); Dmsg1(dbglvl, ">dird: %s", dir->msg); return ok; } bool SD_DCR::dir_update_changer(JCR *jcr, AUTOCHANGER *changer) { BSOCK *dir = jcr->dir_bsock; POOL_MEM dev_name, MediaType; DEVRES *device; bool ok; pm_strcpy(dev_name, changer->hdr.name); bash_spaces(dev_name); device = (DEVRES *)changer->device->first(); pm_strcpy(MediaType, device->media_type); bash_spaces(MediaType); /* This is mostly to indicate that we are here */ ok = dir->fsend(Device_update, jcr->Job, dev_name.c_str(), /* Changer name */ 0, 0, 0, /* append, read, num_writers */ 0, 0, 0, /* is_open, is_labeled, offline */ 0, 0, /* reserved, max_writers */ 0, /* Autoselect */ changer->device->size(), /* Number of devices */ "0", /* PoolId */ "*", /* ChangerName */ MediaType.c_str(), /* MediaType */ "*"); /* VolName */ Dmsg1(dbglvl, ">dird: %s", dir->msg); return ok; } #endif /** * Common routine for: * dir_get_volume_info() * and * dir_find_next_appendable_volume() * * NOTE!!! All calls to this routine must be protected by * locking vol_info_mutex before calling it so that * we don't have one thread modifying the parameters * and another reading them. * * Returns: true on success and vol info in dcr->VolCatInfo * false on failure */ static bool do_get_volume_info(DCR *dcr) { JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; VOLUME_CAT_INFO vol; int n; int32_t InChanger; dcr->setVolCatInfo(false); if (dir->recv() <= 0) { Dmsg0(dbglvl, "getvolname error bnet_recv\n"); Mmsg(jcr->errmsg, _("Network error on bnet_recv in req_vol_info.\n")); return false; } memset(&vol, 0, sizeof(vol)); Dmsg1(dbglvl, "msg); n = sscanf(dir->msg, OK_media, vol.VolCatName, &vol.VolCatJobs, &vol.VolCatFiles, &vol.VolCatBlocks, &vol.VolCatBytes, &vol.VolCatMounts, &vol.VolCatErrors, &vol.VolCatWrites, &vol.VolCatMaxBytes, &vol.VolCatCapacityBytes, vol.VolCatStatus, &vol.Slot, &vol.VolCatMaxJobs, &vol.VolCatMaxFiles, &InChanger, &vol.VolReadTime, &vol.VolWriteTime, &vol.EndFile, &vol.EndBlock, &vol.LabelType, &vol.VolMediaId, vol.VolEncrKey, &vol.VolMinBlocksize, &vol.VolMaxBlocksize); if (n != 24) { Dmsg3(dbglvl, "Bad response from Dir fields=%d, len=%d: %s", n, dir->msglen, dir->msg); Mmsg(jcr->errmsg, _("Error getting Volume info: %s"), dir->msg); return false; } vol.InChanger = InChanger; /* bool in structure */ vol.is_valid = true; unbash_spaces(vol.VolCatName); bstrncpy(dcr->VolumeName, vol.VolCatName, sizeof(dcr->VolumeName)); dcr->VolCatInfo = vol; /* structure assignment */ /* * If we received a new crypto key update the cache and write out the new cache on a change. */ if (*vol.VolEncrKey) { if (update_crypto_cache(vol.VolCatName, vol.VolEncrKey)) { write_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); } } Dmsg4(dbglvl, "do_get_volume_info return true slot=%d Volume=%s, " "VolminBlocksize=%u VolMaxBlocksize=%u\n", vol.Slot, vol.VolCatName, vol.VolMinBlocksize, vol.VolMaxBlocksize); Dmsg2(dbglvl, "setting dcr->VolMinBlocksize(%u) to vol.VolMinBlocksize(%u)\n", dcr->VolMinBlocksize, vol.VolMinBlocksize); Dmsg2(dbglvl, "setting dcr->VolMaxBlocksize(%u) to vol.VolMaxBlocksize(%u)\n", dcr->VolMaxBlocksize, vol.VolMaxBlocksize); /* * Assign the volcatinfo to the dcr. */ dcr->VolMinBlocksize = vol.VolMinBlocksize; dcr->VolMaxBlocksize = vol.VolMaxBlocksize; return true; } /** * Get Volume info for a specific volume from the Director's Database * * Returns: true on success (Director guarantees that Pool and MediaType * are correct and VolStatus==Append or * VolStatus==Recycle) * false on failure * * Volume information returned in dcr->VolCatInfo */ bool SD_DCR::dir_get_volume_info(enum get_vol_info_rw writing) { bool ok; BSOCK *dir = jcr->dir_bsock; P(vol_info_mutex); setVolCatName(VolumeName); bash_spaces(getVolCatName()); dir->fsend(Get_Vol_Info, jcr->Job, getVolCatName(), (writing == GET_VOL_INFO_FOR_WRITE) ? 1 : 0); Dmsg1(dbglvl, ">dird %s", dir->msg); unbash_spaces(getVolCatName()); ok = do_get_volume_info(this); V(vol_info_mutex); return ok; } /** * Get info on the next appendable volume in the Director's database * * Returns: true on success dcr->VolumeName is volume * reserve_volume() called on Volume name * false on failure dcr->VolumeName[0] == 0 * also sets dcr->found_in_use if at least one * in use volume was found. * * Volume information returned in dcr */ bool SD_DCR::dir_find_next_appendable_volume() { BSOCK *dir = jcr->dir_bsock; bool rtn; char lastVolume[MAX_NAME_LENGTH]; Dmsg2(dbglvl, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", is_reserved(), VolumeName); /* * Try the twenty oldest or most available volumes. Note, * the most available could already be mounted on another * drive, so we continue looking for a not in use Volume. */ lock_volumes(); P(vol_info_mutex); clear_found_in_use(); lastVolume[0] = 0; for (int vol_index=1; vol_index < 20; vol_index++) { bash_spaces(media_type); bash_spaces(pool_name); dir->fsend(Find_media, jcr->Job, vol_index, pool_name, media_type); unbash_spaces(media_type); unbash_spaces(pool_name); Dmsg1(dbglvl, ">dird %s", dir->msg); if (do_get_volume_info(this)) { /* * Give up if we get the same volume name twice */ if (lastVolume[0] && bstrcmp(lastVolume, VolumeName)) { Dmsg1(dbglvl, "Got same vol = %s\n", lastVolume); break; } bstrncpy(lastVolume, VolumeName, sizeof(lastVolume)); if (can_i_write_volume()) { Dmsg1(dbglvl, "Call reserve_volume for write. Vol=%s\n", VolumeName); if (reserve_volume(this, VolumeName) == NULL) { Dmsg2(dbglvl, "Could not reserve volume %s on %s\n", VolumeName, dev->print_name()); continue; } Dmsg1(dbglvl, "dir_find_next_appendable_volume return true. vol=%s\n", VolumeName); rtn = true; goto get_out; } else { Dmsg1(dbglvl, "Volume %s is in use.\n", VolumeName); /* If volume is not usable, it is in use by someone else */ set_found_in_use(); continue; } } Dmsg2(dbglvl, "No vol. index %d return false. dev=%s\n", vol_index, dev->print_name()); break; } rtn = false; VolumeName[0] = 0; get_out: V(vol_info_mutex); unlock_volumes(); return rtn; } /** * After writing a Volume, send the updated statistics * back to the director. The information comes from the * dev record. */ bool SD_DCR::dir_update_volume_info(bool label, bool update_LastWritten) { BSOCK *dir = jcr->dir_bsock; VOLUME_CAT_INFO *vol = &dev->VolCatInfo; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; int InChanger; bool ok = false; POOL_MEM volume_name; /* If system job, do not update catalog */ if (jcr->is_JobType(JT_SYSTEM)) { return true; } if (vol->VolCatName[0] == 0) { Jmsg0(jcr, M_FATAL, 0, _("NULL Volume name. This shouldn't happen!!!\n")); Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); return false; } /* Lock during Volume update */ P(vol_info_mutex); Dmsg1(dbglvl, "Update cat VolBytes=%lld\n", vol->VolCatBytes); /* Just labeled or relabeled the tape */ if (label) { bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus)); } // if (update_LastWritten) { vol->VolLastWritten = time(NULL); // } pm_strcpy(volume_name, vol->VolCatName); bash_spaces(volume_name); InChanger = vol->InChanger; dir->fsend(Update_media, jcr->Job, volume_name.c_str(), vol->VolCatJobs, vol->VolCatFiles, vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1), vol->VolCatMounts, vol->VolCatErrors, vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2), edit_uint64(vol->VolLastWritten, ed6), vol->VolCatStatus, vol->Slot, label, InChanger, /* bool in structure */ edit_int64(vol->VolReadTime, ed3), edit_int64(vol->VolWriteTime, ed4), edit_uint64(vol->VolFirstWritten, ed5)); Dmsg1(dbglvl, ">dird %s", dir->msg); /* Do not lock device here because it may be locked from label */ if (!jcr->is_canceled()) { if (!do_get_volume_info(this)) { Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg); Dmsg2(dbglvl, _("Didn't get vol info vol=%s: ERR=%s"), vol->VolCatName, jcr->errmsg); goto bail_out; } Dmsg1(420, "get_volume_info() %s", dir->msg); /* Update dev Volume info in case something changed (e.g. expired) */ dev->VolCatInfo = VolCatInfo; ok = true; } bail_out: V(vol_info_mutex); return ok; } /** * After writing a Volume, create the JobMedia record. */ bool SD_DCR::dir_create_jobmedia_record(bool zero) { BSOCK *dir = jcr->dir_bsock; char ed1[50]; /* If system job, do not update catalog */ if (jcr->is_JobType(JT_SYSTEM)) { return true; } /* Throw out records where FI is zero -- i.e. nothing done */ if (!zero && VolFirstIndex == 0 && (StartBlock != 0 || EndBlock != 0)) { Dmsg0(dbglvl, "JobMedia FI=0 StartBlock!=0 record suppressed\n"); return true; } if (!WroteVol) { return true; /* nothing written to tape */ } WroteVol = false; if (zero) { /* Send dummy place holder to avoid purging */ dir->fsend(Create_job_media, jcr->Job, 0 , 0, 0, 0, 0, 0, 0, 0, edit_uint64(VolMediaId, ed1)); } else { dir->fsend(Create_job_media, jcr->Job, VolFirstIndex, VolLastIndex, StartFile, EndFile, StartBlock, EndBlock, Copy, Stripe, edit_uint64(VolMediaId, ed1)); } Dmsg1(dbglvl, ">dird %s", dir->msg); if (dir->recv() <= 0) { Dmsg0(dbglvl, "create_jobmedia error bnet_recv\n"); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"), dir->bstrerror()); return false; } Dmsg1(dbglvl, "msg); if (!bstrcmp(dir->msg, OK_create)) { Dmsg1(dbglvl, "Bad response from Dir: %s\n", dir->msg); Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: %s\n"), dir->msg); return false; } return true; } /** * Update File Attribute data * We do the following: * 1. expand the bsock buffer to be large enough * 2. Write a "header" into the buffer with serialized data * VolSessionId * VolSeesionTime * FileIndex * Stream * data length that follows * start of raw byte data from the Device record. * Note, this is primarily for Attribute data, but can * also handle any device record. The Director must know * the raw byte data format that is defined for each Stream. * Now Restore Objects pass through here STREAM_RESTORE_OBJECT */ bool SD_DCR::dir_update_file_attributes(DEV_RECORD *record) { BSOCK *dir = jcr->dir_bsock; ser_declare; #ifdef NO_ATTRIBUTES_TEST return true; #endif dir->msg = check_pool_memory_size(dir->msg, sizeof(FileAttributes) + MAX_NAME_LENGTH + sizeof(DEV_RECORD) + record->data_len + 1); dir->msglen = bsnprintf(dir->msg, sizeof(FileAttributes) + MAX_NAME_LENGTH + 1, FileAttributes, jcr->Job); ser_begin(dir->msg + dir->msglen, 0); ser_uint32(record->VolSessionId); ser_uint32(record->VolSessionTime); ser_int32(record->FileIndex); ser_int32(record->Stream); ser_uint32(record->data_len); ser_bytes(record->data, record->data_len); dir->msglen = ser_length(dir->msg); Dmsg1(1800, ">dird %s", dir->msg); /* Attributes */ return dir->send(); } /** * Request the sysop to create an appendable volume * * Entered with device blocked. * Leaves with device blocked. * * Returns: true on success (operator issues a mount command) * false on failure * Note, must create dev->errmsg on error return. * * On success, dcr->VolumeName and dcr->VolCatInfo contain * information on suggested volume, but this may not be the * same as what is actually mounted. * * When we return with success, the correct tape may or may not * actually be mounted. The calling routine must read it and * verify the label. */ bool SD_DCR::dir_ask_sysop_to_create_appendable_volume() { int status = W_TIMEOUT; bool got_vol = false; if (job_canceled(jcr)) { return false; } Dmsg0(dbglvl, "enter dir_ask_sysop_to_create_appendable_volume\n"); ASSERT(dev->blocked()); for ( ;; ) { if (job_canceled(jcr)) { Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device \"%s\".\n"), jcr->Job, dev->print_name()); Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); return false; } got_vol = dir_find_next_appendable_volume(); /* get suggested volume */ if (got_vol) { goto get_out; } else { if (status == W_TIMEOUT || status == W_MOUNT) { Mmsg(dev->errmsg, _( "Job %s is waiting. Cannot find any appendable volumes.\n" "Please use the \"label\" command to create a new Volume for:\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n"), jcr->Job, dev->print_name(), pool_name, media_type); Jmsg(jcr, M_MOUNT, 0, "%s", dev->errmsg); Dmsg1(dbglvl, "%s", dev->errmsg); } } jcr->sendJobStatus(JS_WaitMedia); status = wait_for_sysop(this); Dmsg1(dbglvl, "Back from wait_for_sysop status=%d\n", status); if (dev->poll) { Dmsg1(dbglvl, "Poll timeout in create append vol on device %s\n", dev->print_name()); continue; } if (status == W_TIMEOUT) { if (!double_dev_wait_time(dev)) { Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"), dev->print_name(), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); Dmsg1(dbglvl, "Gave up waiting on device %s\n", dev->print_name()); return false; /* exceeded maximum waits */ } continue; } if (status == W_ERROR) { berrno be; Mmsg0(dev->errmsg, _("pthread error in mount_next_volume.\n")); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); return false; } Dmsg1(dbglvl, "Someone woke me for device %s\n", dev->print_name()); } get_out: jcr->sendJobStatus(JS_Running); Dmsg0(dbglvl, "leave dir_ask_sysop_to_mount_create_appendable_volume\n"); return true; } /** * Request to mount specific Volume * * Entered with device blocked and dcr->VolumeName is desired volume. * Leaves with device blocked. * * Returns: true on success (operator issues a mount command) * false on failure * * Note, must create dev->errmsg on error return. */ bool SD_DCR::dir_ask_sysop_to_mount_volume(int mode) { int status = W_TIMEOUT; Dmsg0(dbglvl, "enter dir_ask_sysop_to_mount_volume\n"); if (!VolumeName[0]) { Mmsg0(dev->errmsg, _("Cannot request another volume: no volume name given.\n")); return false; } ASSERT(dev->blocked()); while (1) { if (job_canceled(jcr)) { Mmsg(dev->errmsg, _("Job %s canceled while waiting for mount on Storage Device %s.\n"), jcr->Job, dev->print_name()); return false; } /* * If we are not polling, and the wait timeout or the * user explicitly did a mount, send him the message. * Otherwise skip it. */ if (!dev->poll && (status == W_TIMEOUT || status == W_MOUNT)) { const char *msg; if (mode == ST_APPENDREADY) { msg = _("Please mount append Volume \"%s\" or label a new one for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n"); } else { msg = _("Please mount read Volume \"%s\" for:\n" " Job: %s\n" " Storage: %s\n" " Pool: %s\n" " Media type: %s\n"); } Jmsg(jcr, M_MOUNT, 0, msg, VolumeName, jcr->Job, dev->print_name(), pool_name, media_type); Dmsg3(dbglvl, "Mount \"%s\" on device \"%s\" for Job %s\n", VolumeName, dev->print_name(), jcr->Job); } jcr->sendJobStatus(JS_WaitMount); status = wait_for_sysop(this); /* wait on device */ Dmsg1(dbglvl, "Back from wait_for_sysop status=%d\n", status); if (dev->poll) { Dmsg1(dbglvl, "Poll timeout in mount vol on device %s\n", dev->print_name()); Dmsg1(dbglvl, "Blocked=%s\n", dev->print_blocked()); goto get_out; } if (status == W_TIMEOUT) { if (!double_dev_wait_time(dev)) { Mmsg(dev->errmsg, _("Max time exceeded waiting to mount Storage Device %s for Job %s\n"), dev->print_name(), jcr->Job); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); Dmsg1(dbglvl, "Gave up waiting on device %s\n", dev->print_name()); return false; /* exceeded maximum waits */ } continue; } if (status == W_ERROR) { berrno be; Mmsg(dev->errmsg, _("pthread error in mount_volume\n")); Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); return false; } Dmsg1(dbglvl, "Someone woke me for device %s\n", dev->print_name()); break; } get_out: jcr->sendJobStatus(JS_Running); Dmsg0(dbglvl, "leave dir_ask_sysop_to_mount_volume\n"); return true; } DCR *SD_DCR::get_new_spooling_dcr() { DCR *dcr; dcr = New(SD_DCR); return dcr; } /* * Dummy methods for everything but SD and BTAPE. */ bool DCR::dir_ask_sysop_to_mount_volume(int /*mode*/) { fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "), VolumeName, dev->print_name()); dev->close(this); getchar(); return true; } bool DCR::dir_get_volume_info(enum get_vol_info_rw writing) { Dmsg0(100, "Fake dir_get_volume_info\n"); setVolCatName(VolumeName); Dmsg1(500, "Vol=%s\n", getVolCatName()); return 1; } DCR *DCR::get_new_spooling_dcr() { DCR *dcr; dcr = New(SD_DCR); return dcr; } bareos-Release-14.2.6/src/stored/authenticate.c000066400000000000000000000307131263011562700213550ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Authenticate caller * * Kern Sibbald, October 2000 */ #include "bareos.h" #include "stored.h" const int dbglvl = 50; static char Dir_sorry[] = "3999 No go\n"; static char OK_hello[] = "3000 OK Hello\n"; /* * See who is connecting and lookup the authentication information. * First make him prove his identity and then prove our identity to the Remote daemon. */ static inline bool two_way_authenticate(int rcode, BSOCK *bs, JCR* jcr) { POOLMEM *dirname; DIRRES *director = NULL; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; /* require md5 compatible DIR */ bool auth_success = false; alist *verify_list = NULL; if (rcode != R_DIRECTOR) { Dmsg1(dbglvl, "I only authenticate Directors, not %d\n", rcode); Jmsg1(jcr, M_FATAL, 0, _("I only authenticate Directors, not %d\n"), rcode); return 0; } /* * Sanity check. */ if (bs->msglen < 25 || bs->msglen > 500) { Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n", bs->who(), bs->msglen); Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"), bs->who(), bs->msglen); return 0; } dirname = get_pool_memory(PM_MESSAGE); dirname = check_pool_memory_size(dirname, bs->msglen); if (sscanf(bs->msg, "Hello Director %127s calling", dirname) != 1) { bs->msg[100] = 0; Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n", bs->who(), bs->msg); Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"), bs->who(), bs->msg); return 0; } director = NULL; unbash_spaces(dirname); foreach_res(director, rcode) { if (bstrcmp(director->hdr.name, dirname)) { break; } } if (!director) { Dmsg2(dbglvl, "Connection from unknown Director %s at %s rejected.\n", dirname, bs->who()); Jmsg(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n" "Please see %s for help.\n"), dirname, bs->who(), MANUAL_AUTH_URL); free_pool_memory(dirname); return 0; } /* * TLS Requirement */ if (director->tls_enable) { if (director->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } if (director->tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } if (director->tls_verify_peer) { verify_list = director->tls_allowed_cns; } ASSERT(director->password.encoding == p_encoding_md5); /* * Timeout Hello after 10 mins */ btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT); auth_success = cram_md5_challenge(bs, director->password.value, tls_local_need, compatible); if (auth_success) { auth_success = cram_md5_respond(bs, director->password.value, &tls_remote_need, &compatible); if (!auth_success) { Dmsg1(dbglvl, "cram_get_auth failed with %s\n", bs->who()); } } else { Dmsg1(dbglvl, "cram_auth failed with %s\n", bs->who()); } if (!auth_success) { Jmsg(jcr, M_FATAL, 0, _("Incorrect password given by Director.\n" "Please see %s for help.\n"), MANUAL_AUTH_URL); auth_success = false; goto auth_fatal; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" " advertize required TLS support.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg0(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) { Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with DIR at \"%s:%d\"\n"), bs->host(), bs->port()); auth_success = false; goto auth_fatal; } if (director->tls_authenticate) { /* authenticate with tls only? */ bs->free_tls(); /* yes, shut it down */ } } auth_fatal: stop_bsock_timer(tid); free_pool_memory(dirname); jcr->director = director; return auth_success; } /* * Depending on the initiate parameter perform one of the following: * * - First make him prove his identity and then prove our identity to the Remote daemon. * - First prove our identity to the Remote daemon and then make him prove his identity. */ static inline bool two_way_authenticate(BSOCK *bs, JCR *jcr, bool initiate, const char *what) { int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool compatible = true; /* require md5 compatible FD/SD */ bool auth_success = false; alist *verify_list = NULL; btimer_t *tid = NULL; /* * TLS Requirement */ if (me->tls_enable) { if (me->tls_require) { tls_local_need = BNET_TLS_REQUIRED; } else { tls_local_need = BNET_TLS_OK; } } if (me->tls_authenticate) { tls_local_need = BNET_TLS_REQUIRED; } if (me->tls_verify_peer) { verify_list = me->tls_allowed_cns; } /* * Timeout Hello after 5 mins */ tid = start_bsock_timer(bs, AUTH_TIMEOUT); /* * See if we initiate the challenge or respond to a challenge. */ if (initiate) { /* * Challenge FD/SD */ auth_success = cram_md5_challenge(bs, jcr->sd_auth_key, tls_local_need, compatible); if (auth_success) { /* * Respond to his challenge */ auth_success = cram_md5_respond(bs, jcr->sd_auth_key, &tls_remote_need, &compatible); if (!auth_success) { Dmsg1(dbglvl, "Respond cram-get-auth failed with %s\n", bs->who()); } } else { Dmsg1(dbglvl, "Challenge cram-auth failed with %s\n", bs->who()); } } else { /* * Respond to his challenge */ auth_success = cram_md5_respond(bs, jcr->sd_auth_key, &tls_remote_need, &compatible); if (auth_success) { /* * Challenge FD/SD */ auth_success = cram_md5_challenge(bs, jcr->sd_auth_key, tls_local_need, compatible); if (!auth_success) { Dmsg1(dbglvl, "Challenge cram-auth failed with %s\n", bs->who()); } } else { Dmsg1(dbglvl, "Respond cram-get-auth failed with %s\n", bs->who()); } } if (!auth_success) { Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from %s daemon at %s rejected.\n" "Please see %s for help.\n"), what, bs->who(), MANUAL_AUTH_URL); auth_success = false; goto auth_fatal; } /* * Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server did not" " advertize required TLS support.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } /* * Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { Jmsg(jcr, M_FATAL, 0, _("Authorization problem: Remote server requires TLS.\n")); Dmsg2(dbglvl, "remote_need=%d local_need=%d\n", tls_remote_need, tls_local_need); auth_success = false; goto auth_fatal; } if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { /* * Check if we need to be client or server. */ if (initiate) { if (!bnet_tls_server(me->tls_ctx, bs, verify_list)) { Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with %s daemon at \"%s:%d\"\n"), what, bs->host(), bs->port()); auth_success = false; goto auth_fatal; } } else { if (!bnet_tls_client(me->tls_ctx, bs, verify_list)) { Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with %s daemon at \"%s:%d\"\n"), what, bs->host(), bs->port()); auth_success = false; goto auth_fatal; } } if (me->tls_authenticate) { /* tls authenticate only? */ bs->free_tls(); /* yes, shut it down */ } } auth_fatal: stop_bsock_timer(tid); jcr->authenticated = auth_success; return auth_success; } /* * Initiate the message channel with the Director. * It has made a connection to our server. * * Basic tasks done here: * - Assume the Hello message is already in the input buffer. * - Authenticate * - Get device * - Get media * - Get pool information * * This is the channel across which we will send error * messages and job status information. */ bool authenticate_director(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; if (!two_way_authenticate(R_DIRECTOR, dir, jcr)) { dir->fsend("%s", Dir_sorry); Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who()); Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who()); bmicrosleep(5, 0); return false; } return dir->fsend("%s", OK_hello); } /* * Authenticate a remote storage daemon. * * This is used for SD-SD replication of data. */ bool authenticate_storagedaemon(JCR *jcr) { BSOCK *sd = jcr->store_bsock; if (!two_way_authenticate(sd, jcr, true, "Storage")) { Jmsg1(jcr, M_FATAL, 0, _("Authorization problem: Two way security handshake failed with Storage daemon at %s\n"), sd->who()); return false; } return true; } /* * Authenticate with a remote storage daemon. * * This is used for SD-SD replication of data. */ bool authenticate_with_storagedaemon(JCR *jcr) { BSOCK *sd = jcr->store_bsock; if (!two_way_authenticate(sd, jcr, false, "Storage")) { Jmsg1(jcr, M_FATAL, 0, _("Authorization problem: Two way security handshake failed with Storage daemon at %s\n"), sd->who()); return false; } return true; } /* * Authenticate a remote File daemon. * * This is used for FD backups or restores. */ bool authenticate_filedaemon(JCR *jcr) { BSOCK *fd = jcr->file_bsock; if (!two_way_authenticate(fd, jcr, true, "File")) { Jmsg1(jcr, M_FATAL, 0, _("Authorization problem: Two way security handshake failed with File daemon at %s\n"), fd->who()); return false; } return true; } /* * Authenticate with a remote file daemon. * * This is used for passive FD backups or restores. */ bool authenticate_with_filedaemon(JCR *jcr) { BSOCK *fd = jcr->file_bsock; if (!two_way_authenticate(fd, jcr, false, "File")) { Jmsg1(jcr, M_FATAL, 0, _("Authorization problem: Two way security handshake failed with File daemon at %s\n"), fd->who()); return false; } return true; } bareos-Release-14.2.6/src/stored/autochanger.c000066400000000000000000000602161263011562700212000ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Routines for handling the autochanger. * * Kern Sibbald, August MMII */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ static void lock_changer(DCR *dcr); static void unlock_changer(DCR *dcr); static bool unload_other_drive(DCR *dcr, int slot); static char *transfer_edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd, int src_slot, int dst_slot); /* Init all the autochanger resources found */ bool init_autochangers() { bool OK = true; AUTOCHANGERRES *changer; /* Ensure that the media_type for each device is the same */ foreach_res(changer, R_AUTOCHANGER) { DEVRES *device; foreach_alist(device, changer->device) { /* * If the device does not have a changer name or changer command * defined, used the one from the Autochanger resource */ if (!device->changer_name && changer->changer_name) { device->changer_name = bstrdup(changer->changer_name); } if (!device->changer_command && changer->changer_command) { device->changer_command = bstrdup(changer->changer_command); } if (!device->changer_name) { Jmsg(NULL, M_ERROR, 0, _("No Changer Name given for device %s. Cannot continue.\n"), device->hdr.name); OK = false; } if (!device->changer_command) { Jmsg(NULL, M_ERROR, 0, _("No Changer Command given for device %s. Cannot continue.\n"), device->hdr.name); OK = false; } } } return OK; } /* * Called here to do an autoload using the autochanger, if * configured, and if a Slot has been defined for this Volume. * On success this routine loads the indicated tape, but the * label is not read, so it must be verified. * * Note if dir is not NULL, it is the console requesting the * autoload for labeling, so we respond directly to the * dir bsock. * * Returns: 1 on success * 0 on failure (no changer available) * -1 on error on autochanger */ int autoload_device(DCR *dcr, int writing, BSOCK *dir) { JCR *jcr = dcr->jcr; DEVICE * volatile dev = dcr->dev; int slot; int drive = dev->drive_index; int rtn_stat = -1; /* error status */ POOLMEM *changer; if (!dev->is_autochanger()) { Dmsg1(100, "Device %s is not an autochanger\n", dev->print_name()); return 0; } /* An empty ChangerCommand => virtual disk autochanger */ if (dcr->device->changer_command && dcr->device->changer_command[0] == 0) { Dmsg0(100, "ChangerCommand=0, virtual disk changer\n"); return 1; /* nothing to load */ } slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0; Dmsg3(100, "autoload: slot=%d InChgr=%d Vol=%s\n", dcr->VolCatInfo.Slot, dcr->VolCatInfo.InChanger, dcr->getVolCatName()); /* * Handle autoloaders here. If we cannot autoload it, we * will return 0 so that the sysop will be asked to load it. */ if (writing && slot <= 0) { if (dir) { return 0; /* For user, bail out right now */ } /* ***FIXME*** this really should not be here */ if (dcr->dir_find_next_appendable_volume()) { slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0; } else { slot = 0; } } Dmsg1(400, "Want changer slot=%d\n", slot); changer = get_pool_memory(PM_FNAME); if (slot <= 0) { /* Suppress info when polling */ if (!dev->poll) { Jmsg(jcr, M_INFO, 0, _("No slot defined in catalog (slot=%d) for Volume \"%s\" on %s.\n"), slot, dcr->getVolCatName(), dev->print_name()); Jmsg(jcr, M_INFO, 0, _("Cartridge change or \"update slots\" may be required.\n")); } rtn_stat = 0; } else if (!dcr->device->changer_name) { /* Suppress info when polling */ if (!dev->poll) { Jmsg(jcr, M_INFO, 0, _("No \"Changer Device\" for %s. Manual load of Volume may be required.\n"), dev->print_name()); } rtn_stat = 0; } else if (!dcr->device->changer_command) { /* Suppress info when polling */ if (!dev->poll) { Jmsg(jcr, M_INFO, 0, _("No \"Changer Command\" for %s. Manual load of Volume may be requird.\n"), dev->print_name()); } rtn_stat = 0; } else { /* Attempt to load the Volume */ uint32_t timeout = dcr->device->max_changer_wait; int loaded, status; loaded = get_autochanger_loaded_slot(dcr); if (loaded != slot) { POOL_MEM results(PM_MESSAGE); /* Unload anything in our drive */ if (!unload_autochanger(dcr, loaded)) { goto bail_out; } /* Make sure desired slot is unloaded */ if (!unload_other_drive(dcr, slot)) { goto bail_out; } /* * Load the desired cassette */ lock_changer(dcr); Dmsg2(100, "Doing changer load slot %d %s\n", slot, dev->print_name()); Jmsg(jcr, M_INFO, 0, _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"), slot, drive); dcr->VolCatInfo.Slot = slot; /* slot to be loaded */ changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "load"); dev->close(dcr); Dmsg1(200, "Run program=%s\n", changer); status = run_program_full_output(changer, timeout, results.addr()); if (status == 0) { Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"), slot, drive); Dmsg2(100, "load slot %d, drive %d, status is OK.\n", slot, drive); dev->set_slot(slot); /* set currently loaded slot */ if (dev->vol) { /* We just swapped this Volume so it cannot be swapping any more */ dev->vol->clear_swapping(); } } else { berrno be; be.set_errno(status); Dmsg3(100, "load slot %d, drive %d, bad stats=%s.\n", slot, drive, be.bstrerror()); Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"load slot %d, drive %d\": " "ERR=%s.\nResults=%s\n"), slot, drive, be.bstrerror(), results.c_str()); rtn_stat = -1; /* hard error */ dev->set_slot(-1); /* mark unknown */ } Dmsg2(100, "load slot %d status=%d\n", slot, status); unlock_changer(dcr); } else { status = 0; /* we got what we want */ dev->set_slot(slot); /* set currently loaded slot */ } Dmsg1(100, "After changer, status=%d\n", status); if (status == 0) { /* did we succeed? */ rtn_stat = 1; /* tape loaded by changer */ } } free_pool_memory(changer); return rtn_stat; bail_out: free_pool_memory(changer); return -1; } /* * Returns: -1 if error from changer command * slot otherwise * Note, this is safe to do without releasing the drive * since it does not attempt load/unload a slot. */ int get_autochanger_loaded_slot(DCR *dcr) { JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; int status, loaded; uint32_t timeout = dcr->device->max_changer_wait; int drive = dcr->dev->drive_index; POOL_MEM results(PM_MESSAGE); POOLMEM *changer; if (!dev->is_autochanger()) { return -1; } if (!dcr->device->changer_command) { return -1; } if (dev->get_slot() > 0) { return dev->get_slot(); } /* Virtual disk autochanger */ if (dcr->device->changer_command[0] == 0) { return 1; } /* Find out what is loaded, zero means device is unloaded */ changer = get_pool_memory(PM_FNAME); lock_changer(dcr); /* Suppress info when polling */ if (!dev->poll && debug_level >= 1) { Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded? drive %d\" command.\n"), drive); } changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "loaded"); Dmsg1(100, "Run program=%s\n", changer); status = run_program_full_output(changer, timeout, results.addr()); Dmsg3(100, "run_prog: %s stat=%d result=%s", changer, status, results.c_str()); if (status == 0) { loaded = str_to_int32(results.c_str()); if (loaded > 0) { /* Suppress info when polling */ if (!dev->poll && debug_level >= 1) { Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded? drive %d\", result is Slot %d.\n"), drive, loaded); } dev->set_slot(loaded); } else { /* Suppress info when polling */ if (!dev->poll && debug_level >= 1) { Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded? drive %d\", result: nothing loaded.\n"), drive); } if (loaded == 0) { /* no slot loaded */ dev->set_slot(0); } else { /* probably some error */ dev->clear_slot(); /* unknown */ } } } else { berrno be; be.set_errno(status); Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded? drive %d\" command: " "ERR=%s.\nResults=%s\n"), drive, be.bstrerror(), results.c_str()); loaded = -1; /* force unload */ } unlock_changer(dcr); free_pool_memory(changer); return loaded; } static void lock_changer(DCR *dcr) { AUTOCHANGERRES *changer_res = dcr->device->changer_res; if (changer_res) { int errstat; Dmsg1(200, "Locking changer %s\n", changer_res->hdr.name); if ((errstat=rwl_writelock(&changer_res->changer_lock)) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR_TERM, 0, _("Lock failure on autochanger. ERR=%s\n"), be.bstrerror(errstat)); } } } static void unlock_changer(DCR *dcr) { AUTOCHANGERRES *changer_res = dcr->device->changer_res; if (changer_res) { int errstat; Dmsg1(200, "Unlocking changer %s\n", changer_res->hdr.name); if ((errstat=rwl_writeunlock(&changer_res->changer_lock)) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR_TERM, 0, _("Unlock failure on autochanger. ERR=%s\n"), be.bstrerror(errstat)); } } } /* * Unload the volume, if any, in this drive * On entry: loaded == 0 -- nothing to do * loaded < 0 -- check if anything to do * loaded > 0 -- load slot == loaded */ bool unload_autochanger(DCR *dcr, int loaded) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; int slot; uint32_t timeout = dcr->device->max_changer_wait; bool ok = true; if (loaded == 0) { return true; } if (!dev->is_autochanger() || !dcr->device->changer_name || !dcr->device->changer_command) { return false; } /* Virtual disk autochanger */ if (dcr->device->changer_command[0] == 0) { dev->clear_unload(); return true; } lock_changer(dcr); if (loaded < 0) { loaded = get_autochanger_loaded_slot(dcr); } if (loaded > 0) { POOL_MEM results(PM_MESSAGE); POOLMEM *changer = get_pool_memory(PM_FNAME); Jmsg(jcr, M_INFO, 0, _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"), loaded, dev->drive_index); slot = dcr->VolCatInfo.Slot; dcr->VolCatInfo.Slot = loaded; changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "unload"); dev->close(dcr); Dmsg1(100, "Run program=%s\n", changer); int status = run_program_full_output(changer, timeout, results.addr()); dcr->VolCatInfo.Slot = slot; if (status != 0) { berrno be; be.set_errno(status); Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": " "ERR=%s\nResults=%s\n"), loaded, dev->drive_index, be.bstrerror(), results.c_str()); ok = false; dev->clear_slot(); /* unknown */ } else { dev->set_slot(0); /* nothing loaded */ } free_pool_memory(changer); } unlock_changer(dcr); if (loaded > 0) { /* free_volume outside from changer lock */ free_volume(dev); /* Free any volume associated with this drive */ } if (ok) { dev->clear_unload(); } return ok; } /* * Unload the slot if mounted in a different drive */ static bool unload_other_drive(DCR *dcr, int slot) { DEVICE *dev = NULL; DEVICE *dev_save; bool found = false; AUTOCHANGERRES *changer = dcr->dev->device->changer_res; DEVRES *device; int retries = 0; /* wait for device retries */ if (!changer) { return false; } if (changer->device->size() == 1) { return true; } /* * We look for the slot number corresponding to the tape * we want in other drives, and if possible, unload * it. */ Dmsg0(100, "Wiffle through devices looking for slot\n"); foreach_alist(device, changer->device) { dev = device->dev; if (!dev) { continue; } dev_save = dcr->dev; dcr->set_dev(dev); if (dev->get_slot() <= 0 && get_autochanger_loaded_slot(dcr) <= 0) { dcr->set_dev(dev_save); continue; } dcr->set_dev(dev_save); if (dev->get_slot() == slot) { found = true; break; } } if (!found) { Dmsg1(100, "Slot=%d not found in another device\n", slot); return true; } else { Dmsg1(100, "Slot=%d found in another device\n", slot); } /* The Volume we want is on another device. */ if (dev->is_busy()) { Dmsg4(100, "Vol %s for dev=%s in use dev=%s slot=%d\n", dcr->VolumeName, dcr->dev->print_name(), dev->print_name(), slot); } for (int i=0; i < 3; i++) { if (dev->is_busy()) { wait_for_device(dcr->jcr, retries); continue; } break; } if (dev->is_busy()) { Jmsg(dcr->jcr, M_WARNING, 0, _("Volume \"%s\" wanted on %s is in use by device %s\n"), dcr->VolumeName, dcr->dev->print_name(), dev->print_name()); Dmsg4(100, "Vol %s for dev=%s is busy dev=%s slot=%d\n", dcr->VolumeName, dcr->dev->print_name(), dev->print_name(), dev->get_slot()); Dmsg2(100, "num_writ=%d reserv=%d\n", dev->num_writers, dev->num_reserved()); volume_unused(dcr); return false; } return unload_dev(dcr, dev); } /* * Unconditionally unload a specified drive */ bool unload_dev(DCR *dcr, DEVICE *dev) { JCR *jcr = dcr->jcr; bool ok = true; uint32_t timeout = dcr->device->max_changer_wait; AUTOCHANGERRES *changer = dcr->dev->device->changer_res; DEVICE *save_dev; int save_slot; if (!changer) { return false; } save_dev = dcr->dev; /* save dcr device */ dcr->set_dev(dev); /* temporarily point dcr at other device */ /* Update slot if not set or not always_open */ if (dev->get_slot() <= 0 || !dev->has_cap(CAP_ALWAYSOPEN)) { get_autochanger_loaded_slot(dcr); } /* Fail if we have no slot to unload */ if (dev->get_slot() <= 0) { dcr->set_dev(save_dev); return false; } save_slot = dcr->VolCatInfo.Slot; dcr->VolCatInfo.Slot = dev->get_slot(); // dev->dlock(); POOLMEM *changer_cmd = get_pool_memory(PM_FNAME); POOL_MEM results(PM_MESSAGE); lock_changer(dcr); Jmsg(jcr, M_INFO, 0, _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"), dev->get_slot(), dev->drive_index); Dmsg2(100, "Issuing autochanger \"unload slot %d, drive %d\" command.\n", dev->get_slot(), dev->drive_index); changer_cmd = edit_device_codes(dcr, changer_cmd, dcr->device->changer_command, "unload"); dev->close(dcr); Dmsg2(200, "close dev=%s reserve=%d\n", dev->print_name(), dev->num_reserved()); Dmsg1(100, "Run program=%s\n", changer_cmd); int status = run_program_full_output(changer_cmd, timeout, results.addr()); dcr->VolCatInfo.Slot = save_slot; dcr->set_dev(save_dev); if (status != 0) { berrno be; be.set_errno(status); Jmsg(jcr, M_INFO, 0, _("3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"), dev->get_slot(), dev->drive_index, be.bstrerror()); Dmsg3(100, "Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n", dev->get_slot(), dev->drive_index, be.bstrerror()); ok = false; dev->clear_slot(); /* unknown */ } else { Dmsg2(100, "Slot %d unloaded %s\n", dev->get_slot(), dev->print_name()); dev->set_slot(0); /* nothing loaded */ } if (ok) { dev->clear_unload(); } unlock_changer(dcr); // dev->dunlock(); free_volume(dev); /* Free any volume associated with this drive */ free_pool_memory(changer_cmd); return ok; } /* * List the Volumes that are in the autoloader possibly with their barcodes. * We assume that it is always the Console that is calling us. */ bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd) { DEVICE *dev = dcr->dev; uint32_t timeout = dcr->device->max_changer_wait; POOLMEM *changer; BPIPE *bpipe; int len = sizeof_pool_memory(dir->msg) - 1; int status; int retries = 1; /* Number of retries on failing slot count */ if (!dev->is_autochanger() || !dcr->device->changer_name || !dcr->device->changer_command) { if (bstrcmp(cmd, "drives")) { dir->fsend("drives=1\n"); } dir->fsend(_("3993 Device %s not an autochanger device.\n"), dev->print_name()); return false; } if (bstrcmp(cmd, "drives")) { AUTOCHANGERRES *changer_res = dcr->device->changer_res; int drives = 1; if (changer_res) { drives = changer_res->device->size(); } dir->fsend("drives=%d\n", drives); Dmsg1(100, "drives=%d\n", drives); return true; } /* * If listing, reprobe changer */ if (bstrcmp(cmd, "list") || bstrcmp(cmd, "listall")) { dcr->dev->set_slot(0); get_autochanger_loaded_slot(dcr); } changer = get_pool_memory(PM_FNAME); lock_changer(dcr); changer = edit_device_codes(dcr, changer, dcr->device->changer_command, cmd); dir->fsend(_("3306 Issuing autochanger \"%s\" command.\n"), cmd); /* * Now issue the command */ retry_changercmd: bpipe = open_bpipe(changer, timeout, "r"); if (!bpipe) { dir->fsend(_("3996 Open bpipe failed.\n")); goto bail_out; /* TODO: check if we need to return false */ } if (bstrcmp(cmd, "list") || bstrcmp(cmd, "listall")) { /* * Get output from changer */ while (fgets(dir->msg, len, bpipe->rfd)) { dir->msglen = strlen(dir->msg); Dmsg1(100, "msg); bnet_send(dir); } } else if (bstrcmp(cmd, "slots")) { int slots; char buf[100], *p; /* * For slots command, read a single line */ buf[0] = 0; fgets(buf, sizeof(buf)-1, bpipe->rfd); buf[sizeof(buf)-1] = 0; /* * Strip any leading space in front of # of slots */ for (p = buf; B_ISSPACE(*p); p++) { } /* * Validate slot count. If slots == 0 retry retries more times. */ slots = str_to_int32(p); if (slots == 0 && retries-- >= 0) { close_bpipe(bpipe); goto retry_changercmd; } dir->fsend("slots=%d", slots); Dmsg1(100, "msg); } status = close_bpipe(bpipe); if (status != 0) { berrno be; be.set_errno(status); dir->fsend(_("3998 Autochanger error: ERR=%s\n"), be.bstrerror()); } bail_out: unlock_changer(dcr); free_pool_memory(changer); return true; } /* * Transfer a volume from src_slot to dst_slot. * We assume that it is always the Console that is calling us. */ bool autochanger_transfer_cmd(DCR *dcr, BSOCK *dir, int src_slot, int dst_slot) { DEVICE *dev = dcr->dev; uint32_t timeout = dcr->device->max_changer_wait; POOLMEM *changer; BPIPE *bpipe; int len = sizeof_pool_memory(dir->msg) - 1; int status; if (!dev->is_autochanger() || !dcr->device->changer_name || !dcr->device->changer_command) { dir->fsend(_("3993 Device %s not an autochanger device.\n"), dev->print_name()); return false; } changer = get_pool_memory(PM_FNAME); lock_changer(dcr); changer = transfer_edit_device_codes(dcr, changer, dcr->device->changer_command, "transfer", src_slot, dst_slot); dir->fsend(_("3306 Issuing autochanger transfer command.\n")); /* Now issue the command */ bpipe = open_bpipe(changer, timeout, "r"); if (!bpipe) { dir->fsend(_("3996 Open bpipe failed.\n")); goto bail_out; /* TODO: check if we need to return false */ } /* Get output from changer */ while (fgets(dir->msg, len, bpipe->rfd)) { dir->msglen = strlen(dir->msg); Dmsg1(100, "msg); bnet_send(dir); } status = close_bpipe(bpipe); if (status != 0) { berrno be; be.set_errno(status); dir->fsend(_("3998 Autochanger error: ERR=%s\n"), be.bstrerror()); } else { dir->fsend(_("3308 Successfully transfered volume from slot %d to %d.\n"), src_slot, dst_slot); } bail_out: unlock_changer(dcr); free_pool_memory(changer); return true; } /* * Special version of edit_device_codes for use with transfer subcommand. * Edit codes into ChangerCommand * %% = % * %a = destination slot * %c = changer device name * %d = none * %f = none * %j = none * %o = command * %s = source slot * %S = source slot * %v = none * * omsg = edited output message * imsg = input string containing edit codes (%x) * cmd = command string (transfer) * */ static char *transfer_edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd, int src_slot, int dst_slot) { const char *p; const char *str; char ed1[50]; *omsg = 0; Dmsg1(1800, "transfer_edit_device_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'a': str = edit_int64(dst_slot, ed1); break; case 'c': str = NPRT(dcr->device->changer_name); break; case 'o': str = NPRT(cmd); break; case 's': case 'S': str = edit_int64(src_slot, ed1); break; default: continue; } } else { ed1[0] = *p; ed1[1] = 0; str = ed1; } Dmsg1(1900, "add_str %s\n", str); pm_strcat(&omsg, (char *)str); Dmsg1(1800, "omsg=%s\n", omsg); } Dmsg1(800, "omsg=%s\n", omsg); return omsg; } bareos-Release-14.2.6/src/stored/backends/000077500000000000000000000000001263011562700203015ustar00rootroot00000000000000bareos-Release-14.2.6/src/stored/backends/Makefile.in000066400000000000000000000131211263011562700223440ustar00rootroot00000000000000# @MCOMMON@ srcdir = . .PATH: . # one up basedir = ../.. # top dir topdir = ../../.. # this dir relative to top dir thisdir = src/stored/backends DEBUG=@DEBUG@ MKDIR=$(topdir)/autoconf/mkinstalldirs first_rule: all dummy: CEPHFS_INC = @CEPHFS_INC@ DROPLET_INC = @DROPLET_INC@ GLUSTER_INC = @GLUSTER_INC@ RADOS_INC = @RADOS_INC@ CEPHFS_LIBS = @CEPHFS_LIBS@ DROPLET_LIBS = @DROPLET_LIBS@ GLUSTER_LIBS = @GLUSTER_LIBS@ RADOS_LIBS = @RADOS_LIBS@ CHEPHFS_SRCS = cephfs_device.c CHEPHFS_LOBJS = $(CHEPHFS_SRCS:.c=.lo) GFAPI_SRCS = gfapi_device.c GFAPI_LOBJS = $(GFAPI_SRCS:.c=.lo) OBJECT_SRCS = object_store_device.c OBJECT_LOBJS = $(OBJECT_SRCS:.c=.lo) RADOS_SRCS = rados_device.c RADOS_LOBJS = $(RADOS_SRCS:.c=.lo) FIFO_SRCS = unix_fifo_device.c FIFO_LOBJS = $(FIFO_SRCS:.c=.lo) GEN_TAPE_SRCS = generic_tape_device.c GEN_TAPE_LOBJS = $(GEN_TAPE_SRCS:.c=.lo) TAPE_SRCS = unix_tape_device.c TAPE_LOBJS = $(TAPE_SRCS:.c=.lo) LIBBAREOSSD_LT_RELEASE = @LIBBAREOSSD_LT_RELEASE@ INCLUDES += -I$(srcdir) -I.. -I$(basedir) -I$(basedir)/include BUILD_BACKENDS = @BUILD_SD_BACKENDS@ INSTALL_CONFS = @INSTALL_SD_CONFS@ .SUFFIXES: .c .o .lo .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< .c.lo: @echo "Compiling $<" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< $(CHEPHFS_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(CEPHFS_INC) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) $(GFAPI_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(GLUSTER_INC) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) $(OBJECT_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(DROPLET_INC) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) $(RADOS_LOBJS): @echo "Compiling $(@:.lo=.c)" $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(INCLUDES) $(RADOS_INC) $(DINCLUDE) $(CXXFLAGS) $(@:.lo=.c) #------------------------------------------------------------------------- all: Makefile $(BUILD_BACKENDS) @echo "==== Make of sd-backends is good ====" @echo " " libbareossd-cephfs.la: Makefile $(CHEPHFS_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(CHEPHFS_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-cephfs-$(LIBBAREOSSD_LT_RELEASE).so $(CEPHFS_LIBS) -lbareos libbareossd-gfapi.la: Makefile $(GFAPI_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(GFAPI_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-gfapi-$(LIBBAREOSSD_LT_RELEASE).so $(GLUSTER_LIBS) -lbareos libbareossd-object.la: Makefile $(OBJECT_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(OBJECT_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-object-$(LIBBAREOSSD_LT_RELEASE).so $(DROPLET_LIBS) -lbareos libbareossd-rados.la: Makefile $(RADOS_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(RADOS_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-rados-$(LIBBAREOSSD_LT_RELEASE).so $(RADOS_LIBS) -lbareos libbareossd-fifo.la: Makefile $(FIFO_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(FIFO_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-fifo-$(LIBBAREOSSD_LT_RELEASE).so -lbareos libbareossd-gentape.la: Makefile $(GEN_TAPE_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(GEN_TAPE_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-gentape-$(LIBBAREOSSD_LT_RELEASE).so -lbareos libbareossd-tape.la: Makefile libbareossd-gentape.la $(TAPE_LOBJS) @echo "Making $@ ..." $(LIBTOOL_LINK) $(CXX) $(DEFS) $(DEBUG) $(LDFLAGS) -L../../lib -o $@ $(TAPE_LOBJS) -export-dynamic -rpath $(backenddir) -release $(LIBBAREOSSD_LT_RELEASE) \ -soname libbareossd-tape-$(LIBBAREOSSD_LT_RELEASE).so libbareossd-gentape.la -lbareos Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @find . -name '*.lo' -print | xargs $(LIBTOOL_CLEAN) $(RMF) @$(RMF) *.la @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) core a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 realclean: clean $(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) libtool-install: all $(MKDIR) $(DESTDIR)$(backenddir) @for backend in $(BUILD_BACKENDS); do \ $(LIBTOOL_INSTALL_FINISH) $(INSTALL_LIB) $$backend $(DESTDIR)$(backenddir); \ $(RM) $(DESTDIR)$(backenddir)/$$backend; \ done install-configs: $(MKDIR) ${DESTDIR}${sysconfdir}/bareos-sd.d/ @for conf in $(INSTALL_CONFS); do \ $(INSTALL_CONFIG) ../../defaultconfigs/bareos-sd.d/$$conf ${DESTDIR}${sysconfdir}/bareos-sd.d/; \ done install: @LIBTOOL_INSTALL_TARGET@ install-configs depend: bareos-Release-14.2.6/src/stored/backends/cephfs_device.c000066400000000000000000000166261263011562700232470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Gluster Filesystem API device abstraction. * * Marco van Wieringen, May 2014 */ #include "bareos.h" #ifdef HAVE_CEPHFS #include "stored.h" #include "backends/cephfs_device.h" /* * Open a volume using libcephfs. */ int cephfs_device::d_open(const char *pathname, int flags, int mode) { int status; berrno be; if (!m_cephfs_configstring) { char *bp; m_cephfs_configstring = bstrdup(dev_name); bp = strchr(m_cephfs_configstring, ':'); if (!bp) { m_cephfs_conffile = m_cephfs_configstring; } else { *bp++ = '\0'; m_cephfs_conffile = m_cephfs_configstring; m_basedir = bp; } } if (!m_cmount) { status = ceph_create(&m_cmount, NULL); if (status < 0) { Mmsg1(errmsg, _("Unable to create CEPHFS mount: ERR=%s\n"), be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } status = ceph_conf_read_file(m_cmount, m_cephfs_conffile); if (status < 0) { Mmsg2(errmsg, _("Unable to read CEPHFS config %s: ERR=%s\n"), m_cephfs_conffile, be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } status = ceph_mount(m_cmount, NULL); if (status < 0) { Mmsg1(errmsg, _("Unable to mount CEPHFS: ERR=%s\n"), be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } } /* * See if we don't have a file open already. */ if (m_fd >= 0) { ceph_close(m_cmount, m_fd); m_fd = -1; } /* * See if we store in an explicit directory. */ if (m_basedir) { struct stat st; /* * Make sure the dir exists if one is defined. */ status = ceph_stat(m_cmount, m_basedir, &st); if (status < 0) { switch (status) { case -ENOENT: status = ceph_mkdirs(m_cmount, m_basedir, 0750); if (status < 0) { Mmsg1(errmsg, _("Specified CEPHFS direcory %s cannot be created.\n"), m_basedir); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } break; default: goto bail_out; } } else { if (!S_ISDIR(st.st_mode)) { Mmsg1(errmsg, _("Specified CEPHFS direcory %s is not a directory.\n"), m_basedir); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } } Mmsg(m_virtual_filename, "%s/%s", m_basedir, getVolCatName()); } else { Mmsg(m_virtual_filename, "%s", getVolCatName()); } m_fd = ceph_open(m_cmount, m_virtual_filename, flags, mode); if (m_fd < 0) { goto bail_out; } return 0; bail_out: /* * Cleanup the CEPHFS context. */ if (m_cmount) { ceph_shutdown(m_cmount); m_cmount = NULL; } m_fd = -1; return -1; } /* * Read data from a volume using libcephfs. */ ssize_t cephfs_device::d_read(int fd, void *buffer, size_t count) { if (m_fd >= 0) { return ceph_read(m_cmount, m_fd, (char *)buffer, count, -1); } else { errno = EBADF; return -1; } } /* * Write data to a volume using libcephfs. */ ssize_t cephfs_device::d_write(int fd, const void *buffer, size_t count) { if (m_fd >= 0) { return ceph_write(m_cmount, m_fd, (char *)buffer, count, -1); } else { errno = EBADF; return -1; } } int cephfs_device::d_close(int fd) { if (m_fd >= 0) { int status; status = ceph_close(m_cmount, m_fd); m_fd = -1; return (status < 0) ? -1: 0; } else { errno = EBADF; return -1; } } int cephfs_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t cephfs_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { if (m_fd >= 0) { boffset_t status; status = ceph_lseek(m_cmount, m_fd, offset, whence); if (status >= 0) { return status; } else { errno = -status; status = -1; return status; } } else { errno = EBADF; return -1; } } bool cephfs_device::d_truncate(DCR *dcr) { int status; struct stat st; if (m_fd >= 0) { status = ceph_ftruncate(m_cmount, m_fd, 0); if (status < 0) { berrno be; Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), prt_name, be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); return false; } /* * Check for a successful ceph_ftruncate() and issue work-around when truncation doesn't work. * * 1. close file * 2. delete file * 3. open new file with same mode * 4. change ownership to original */ status = ceph_fstat(m_cmount, m_fd, &st); if (status < 0) { berrno be; Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), prt_name, be.bstrerror(-status)); return false; } if (st.st_size != 0) { /* ceph_ftruncate() didn't work */ ceph_close(m_cmount, m_fd); ceph_unlink(m_cmount, m_virtual_filename); /* * Recreate the file -- of course, empty */ oflags = O_CREAT | O_RDWR | O_BINARY; m_fd = ceph_open(m_cmount, m_virtual_filename, oflags, st.st_mode); if (m_fd < 0) { berrno be; dev_errno = -m_fd;; Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), m_virtual_filename, be.bstrerror(-m_fd)); Emsg0(M_FATAL, 0, errmsg); m_fd = -1; return false; } /* * Reset proper owner */ ceph_chown(m_cmount, m_virtual_filename, st.st_uid, st.st_gid); } } return true; } cephfs_device::~cephfs_device() { if (m_cmount && m_fd >= 0) { ceph_close(m_cmount, m_fd); m_fd = -1; } if (!m_cmount) { ceph_shutdown(m_cmount); m_cmount = NULL; } if (m_cephfs_configstring) { free(m_cephfs_configstring); m_cephfs_configstring = NULL; } free_pool_memory(m_virtual_filename); } cephfs_device::cephfs_device() { m_cephfs_configstring = NULL; m_cephfs_conffile = NULL; m_basedir = NULL; m_cmount = NULL; m_virtual_filename = get_pool_memory(PM_FNAME); } #ifdef HAVE_DYNAMIC_SD_BACKENDS extern "C" DEVICE SD_IMP_EXP *backend_instantiate(JCR *jcr, int device_type) { DEVICE *dev = NULL; switch (device_type) { case B_CEPHFS_DEV: dev = New(cephfs_device); break; default: Jmsg(jcr, M_FATAL, 0, _("Request for unknown devicetype: %d\n"), device_type); break; } return dev; } extern "C" void SD_IMP_EXP flush_backend(void) { } #endif #endif /* HAVE_CEPHFS */ bareos-Release-14.2.6/src/stored/backends/cephfs_device.h000066400000000000000000000031671263011562700232500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * CEPHFS API device abstraction. * * Marco van Wieringen, May 2014 */ #ifndef CEPHFS_DEVICE_H #define CEPHFS_DEVICE_H #include class cephfs_device: public DEVICE { private: char *m_cephfs_configstring; char *m_cephfs_conffile; char *m_basedir; struct ceph_mount_info *m_cmount; POOLMEM *m_virtual_filename; public: cephfs_device(); ~cephfs_device(); /* * Interface from DEVICE */ int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); bool d_truncate(DCR *dcr); }; #endif /* CEPHFS_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/generic_tape_device.c000066400000000000000000001103331263011562700244120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Generic Tape API device abstraction. * * Kern Sibbald, MM * * Extracted from other source files Marco van Wieringen, June 2014 */ #include "bareos.h" #include "stored.h" #include "generic_tape_device.h" /* * Open a tape device */ void generic_tape_device::open_device(DCR *dcr, int omode) { file_size = 0; int timeout = max_open_wait; #if !defined(HAVE_WIN32) struct mtop mt_com; utime_t start_time = time(NULL); #endif mount(dcr, 1); /* do mount if required */ Dmsg0(100, "Open dev: device is tape\n"); get_autochanger_loaded_slot(dcr); open_mode = omode; set_mode(omode); if (timeout < 1) { timeout = 1; } errno = 0; Dmsg2(100, "Try open %s mode=%s\n", prt_name, mode_to_str(omode)); #if defined(HAVE_WIN32) /* * Windows Code */ if ((m_fd = d_open(dev_name, oflags, 0)) < 0) { dev_errno = errno; } #else /* * UNIX Code * * If busy retry each second for max_open_wait seconds */ for ( ;; ) { /* * Try non-blocking open */ m_fd = d_open(dev_name, oflags | O_NONBLOCK, 0); if (m_fd < 0) { berrno be; dev_errno = errno; Dmsg5(100, "Open error on %s omode=%d oflags=%x errno=%d: ERR=%s\n", prt_name, omode, oflags, errno, be.bstrerror()); } else { /* * Tape open, now rewind it */ Dmsg0(100, "Rewind after open\n"); mt_com.mt_op = MTREW; mt_com.mt_count = 1; /* * Rewind only if dev is a tape */ if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { berrno be; dev_errno = errno; /* set error status from rewind */ d_close(m_fd); clear_opened(); Dmsg2(100, "Rewind error on %s close: ERR=%s\n", prt_name, be.bstrerror(dev_errno)); /* * If we get busy, device is probably rewinding, try again */ if (dev_errno != EBUSY) { break; /* error -- no medium */ } } else { /* * Got fd and rewind worked, so we must have medium in drive */ d_close(m_fd); m_fd = d_open(dev_name, oflags, 0); /* open normally */ if (m_fd < 0) { berrno be; dev_errno = errno; Dmsg5(100, "Open error on %s omode=%d oflags=%x errno=%d: ERR=%s\n", prt_name, omode, oflags, errno, be.bstrerror()); break; } dev_errno = 0; lock_door(); set_os_device_parameters(dcr); /* do system dependent stuff */ break; /* Successfully opened and rewound */ } } bmicrosleep(5, 0); /* * Exceed wait time ? */ if (time(NULL) - start_time >= max_open_wait) { break; /* yes, get out */ } } #endif if (!is_open()) { berrno be; Mmsg2(errmsg, _("Unable to open device %s: ERR=%s\n"), prt_name, be.bstrerror(dev_errno)); Dmsg1(100, "%s", errmsg); } Dmsg1(100, "open dev: tape %d opened\n", m_fd); } /* * Position device to end of medium (end of data) * * Returns: true on succes * false on error */ bool generic_tape_device::eod(DCR *dcr) { struct mtop mt_com; bool ok = true; int32_t os_file; if (m_fd < 0) { dev_errno = EBADF; Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), prt_name); return false; } #if defined (__digital__) && defined (__unix__) return fsf(VolCatInfo.VolCatFiles); #endif Dmsg0(100, "Enter eod\n"); if (at_eot()) { return true; } clear_eof(); /* remove EOF flag */ block_num = file = 0; file_size = 0; file_addr = 0; #ifdef MTEOM if (has_cap(CAP_FASTFSF) && !has_cap(CAP_EOM)) { Dmsg0(100,"Using FAST FSF for EOM\n"); /* * If unknown position, rewind */ if (get_os_tape_file() < 0) { if (!rewind(NULL)) { Dmsg0(100, "Rewind error\n"); return false; } } mt_com.mt_op = MTFSF; /* * ***FIXME*** fix code to handle case that INT16_MAX is not large enough. */ mt_com.mt_count = INT16_MAX; /* use big positive number */ if (mt_com.mt_count < 0) { mt_com.mt_count = INT16_MAX; /* brain damaged system */ } } if (has_cap(CAP_MTIOCGET) && (has_cap(CAP_FASTFSF) || has_cap(CAP_EOM))) { if (has_cap(CAP_EOM)) { Dmsg0(100,"Using EOM for EOM\n"); mt_com.mt_op = MTEOM; mt_com.mt_count = 1; } if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { berrno be; clrerror(mt_com.mt_op); Dmsg1(50, "ioctl error: %s\n", be.bstrerror()); update_pos(dcr); Mmsg2(errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg0(100, errmsg); return false; } os_file = get_os_tape_file(); if (os_file < 0) { berrno be; clrerror(-1); Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg0(100, errmsg); return false; } Dmsg1(100, "EOD file=%d\n", os_file); set_ateof(); file = os_file; } else { #endif /* * Rewind then use FSF until EOT reached */ if (!rewind(NULL)) { Dmsg0(100, "Rewind error.\n"); return false; } /* * Move file by file to the end of the tape */ int file_num; for (file_num=file; !at_eot(); file_num++) { Dmsg0(200, "eod: doing fsf 1\n"); if (!fsf(1)) { Dmsg0(100, "fsf error.\n"); return false; } /* * Avoid infinite loop by ensuring we advance. */ if (!at_eot() && file_num == (int)file) { Dmsg1(100, "fsf did not advance from file %d\n", file_num); set_ateof(); os_file = get_os_tape_file(); if (os_file >= 0) { Dmsg2(100, "Adjust file from %d to %d\n", file_num, os_file); file = os_file; } break; } } #ifdef MTEOM } #endif /* * Some drivers leave us after second EOF when doing MTEOM, so we must backup * so that appending overwrites the second EOF. */ if (has_cap(CAP_BSFATEOM)) { /* * Backup over EOF */ ok = bsf(1); /* * If BSF worked and fileno is known (not -1), set file */ os_file = get_os_tape_file(); if (os_file >= 0) { Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", file , os_file); file = os_file; } else { file++; /* wing it -- not correct on all OSes */ } } else { update_pos(dcr); /* update position */ } Dmsg1(200, "EOD dev->file=%d\n", file); return ok; } /* * Called to indicate that we have just read an EOF from the device. */ void generic_tape_device::set_ateof() { set_eof(); file++; file_addr = 0; file_size = 0; block_num = 0; } /* * Called to indicate we are now at the end of the volume, and writing is not possible. */ void generic_tape_device::set_ateot() { /* * Make volume effectively read-only */ state |= (ST_EOF | ST_EOT | ST_WEOT); clear_append(); } /* * Rewind device and put it offline * * Returns: true on success * false on failure */ bool generic_tape_device::offline() { struct mtop mt_com; state &= ~(ST_APPENDREADY | ST_READREADY | ST_EOT | ST_EOF | ST_WEOT); /* remove EOF/EOT flags */ block_num = file = 0; file_size = 0; file_addr = 0; unlock_door(); mt_com.mt_op = MTOFFL; mt_com.mt_count = 1; if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); return false; } Dmsg1(100, "Offlined device %s\n", prt_name); return true; } /* * Write an end of file on the device * * Returns: true on success * false on failure */ bool generic_tape_device::weof(int num) { struct mtop mt_com; int status; Dmsg1(129, "=== weof_dev=%s\n", prt_name); if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to weof_dev. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } file_size = 0; if (!can_append()) { Mmsg0(errmsg, _("Attempt to WEOF on non-appendable Volume\n")); Emsg0(M_FATAL, 0, errmsg); return false; } clear_eof(); clear_eot(); mt_com.mt_op = MTWEOF; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status == 0) { block_num = 0; file += num; file_addr = 0; } else { berrno be; clrerror(mt_com.mt_op); if (status == -1) { Mmsg2(errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); } } return status == 0; } /* * Foward space a file * * Returns: true on success * false on failure */ bool generic_tape_device::fsf(int num) { int32_t os_file = 0; struct mtop mt_com; int status = 0; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to fsf. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (at_eot()) { dev_errno = 0; Mmsg1(errmsg, _("Device %s at End of Tape.\n"), prt_name); return false; } if (at_eof()) { Dmsg0(200, "ST_EOF set on entry to FSF\n"); } Dmsg0(100, "fsf\n"); block_num = 0; /* * If Fast forward space file is set, then we * use MTFSF to forward space and MTIOCGET * to get the file position. We assume that * the SCSI driver will ensure that we do not * forward space past the end of the medium. */ if (has_cap(CAP_FSF) && has_cap(CAP_MTIOCGET) && has_cap(CAP_FASTFSF)) { int my_errno = 0; mt_com.mt_op = MTFSF; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { my_errno = errno; /* save errno */ } else if ((os_file=get_os_tape_file()) < 0) { my_errno = errno; /* save errno */ } if (my_errno != 0) { berrno be; set_eot(); Dmsg0(200, "Set ST_EOT\n"); clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"), prt_name, be.bstrerror(my_errno)); Dmsg1(200, "%s", errmsg); return false; } Dmsg1(200, "fsf file=%d\n", os_file); set_ateof(); file = os_file; return true; /* * Here if CAP_FSF is set, and virtually all drives * these days support it, we read a record, then forward * space one file. Using this procedure, which is slow, * is the only way we can be sure that we don't read * two consecutive EOF marks, which means End of Data. */ } else if (has_cap(CAP_FSF)) { POOLMEM *rbuf; int rbuf_len; Dmsg0(200, "FSF has cap_fsf\n"); if (max_block_size == 0) { rbuf_len = DEFAULT_BLOCK_SIZE; } else { rbuf_len = max_block_size; } rbuf = get_memory(rbuf_len); mt_com.mt_op = MTFSF; mt_com.mt_count = 1; while (num-- && !at_eot()) { Dmsg0(100, "Doing read before fsf\n"); if ((status = this->read((char *)rbuf, rbuf_len)) < 0) { if (errno == ENOMEM) { /* tape record exceeds buf len */ status = rbuf_len; /* This is OK */ /* * On IBM drives, they return ENOSPC at EOM instead of EOF status */ } else if (at_eof() && errno == ENOSPC) { status = 0; } else if (has_cap(CAP_IOERRATEOM) && at_eof() && errno == EIO) { if (has_cap(CAP_IBMLINTAPE)) { Dmsg0(100, "Got EIO on read, checking lin_tape sense data\n"); if (check_scsi_at_eod(m_fd)) { Dmsg0(100, "Sense data confirms it's EOD\n"); status = 0; } else { Dmsg0(100, "Not at EOD, might be a real error. Check sense trace from lin_taped logs.\n"); set_eot(); clrerror(-1); Mmsg1(errmsg, _("read error on %s. ERR=Input/Output error.\n"), prt_name); break; } } else { Dmsg0(100, "Got EIO on read, assuming that's due to EOD\n"); status = 0; } } else { berrno be; set_eot(); clrerror(-1); Dmsg2(100, "Set ST_EOT read errno=%d. ERR=%s\n", dev_errno, be.bstrerror()); Mmsg2(errmsg, _("read error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg1(100, "%s", errmsg); break; } } if (status == 0) { /* EOF */ Dmsg1(100, "End of File mark from read. File=%d\n", file+1); /* * Two reads of zero means end of tape */ if (at_eof()) { set_eot(); Dmsg0(100, "Set ST_EOT\n"); break; } else { set_ateof(); continue; } } else { /* Got data */ clear_eot(); clear_eof(); } Dmsg0(100, "Doing MTFSF\n"); status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { /* error => EOT */ berrno be; set_eot(); Dmsg0(100, "Set ST_EOT\n"); clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg0(100, "Got < 0 for MTFSF\n"); Dmsg1(100, "%s", errmsg); } else { set_ateof(); } } free_memory(rbuf); /* * No FSF, so use FSR to simulate it */ } else { Dmsg0(200, "Doing FSR for FSF\n"); while (num-- && !at_eot()) { fsr(INT32_MAX); /* returns -1 on EOF or EOT */ } if (at_eot()) { dev_errno = 0; Mmsg1(errmsg, _("Device %s at End of Tape.\n"), prt_name); status = -1; } else { status = 0; } } Dmsg1(200, "Return %d from FSF\n", status); if (at_eof()) { Dmsg0(200, "ST_EOF set on exit FSF\n"); } if (at_eot()) { Dmsg0(200, "ST_EOT set on exit FSF\n"); } Dmsg1(200, "Return from FSF file=%d\n", file); return status == 0; } /* * Backward space a file * * Returns: false on failure * true on success */ bool generic_tape_device::bsf(int num) { struct mtop mt_com; int status; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to bsf. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } Dmsg0(100, "bsf\n"); clear_eot(); clear_eof(); file -= num; file_addr = 0; file_size = 0; mt_com.mt_op = MTBSF; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { berrno be; clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); } return status == 0; } static inline bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat) { Dmsg0(100, "dev_get_os_pos\n"); return dev->has_cap(CAP_MTIOCGET) && dev->d_ioctl(dev->fd(), MTIOCGET, (char *)mt_stat) == 0 && mt_stat->mt_fileno >= 0; } /* * Foward space num records * * Returns: false on failure * true on success */ bool generic_tape_device::fsr(int num) { struct mtop mt_com; int status; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to fsr. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (!has_cap(CAP_FSR)) { Mmsg1(errmsg, _("ioctl MTFSR not permitted on %s.\n"), prt_name); return false; } Dmsg1(100, "fsr %d\n", num); mt_com.mt_op = MTFSR; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status == 0) { clear_eof(); block_num += num; } else { berrno be; struct mtget mt_stat; clrerror(mt_com.mt_op); Dmsg1(100, "FSF fail: ERR=%s\n", be.bstrerror()); if (dev_get_os_pos(this, &mt_stat)) { Dmsg4(100, "Adjust from %d:%d to %d:%d\n", file, block_num, mt_stat.mt_fileno, mt_stat.mt_blkno); file = mt_stat.mt_fileno; block_num = mt_stat.mt_blkno; } else { if (at_eof()) { set_eot(); } else { set_ateof(); } } Mmsg3(errmsg, _("ioctl MTFSR %d error on %s. ERR=%s.\n"), num, prt_name, be.bstrerror()); } return status == 0; } /* * Backward space a record * * Returns: false on failure * true on success */ bool generic_tape_device::bsr(int num) { struct mtop mt_com; int status; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to bsr_dev. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (!has_cap(CAP_BSR)) { Mmsg1(errmsg, _("ioctl MTBSR not permitted on %s.\n"), prt_name); return false; } Dmsg0(100, "bsr_dev\n"); block_num -= num; clear_eof(); clear_eot(); mt_com.mt_op = MTBSR; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { berrno be; clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); } return status == 0; } /* * Load medium in device * * Returns: true on success * false on failure */ bool generic_tape_device::load_dev() { #ifdef MTLOAD struct mtop mt_com; #endif if (m_fd < 0) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to load_dev. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } #ifndef MTLOAD Dmsg0(200, "stored: MTLOAD command not available\n"); berrno be; dev_errno = ENOTTY; /* function not available */ Mmsg2(errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); return false; #else block_num = file = 0; file_size = 0; file_addr = 0; mt_com.mt_op = MTLOAD; mt_com.mt_count = 1; if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); return false; } return true; #endif } void generic_tape_device::lock_door() { #ifdef MTLOCK struct mtop mt_com; mt_com.mt_op = MTLOCK; mt_com.mt_count = 1; if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { clrerror(mt_com.mt_op); } #endif } void generic_tape_device::unlock_door() { #ifdef MTUNLOCK struct mtop mt_com; mt_com.mt_op = MTUNLOCK; mt_com.mt_count = 1; if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { clrerror(mt_com.mt_op); } #endif } #if defined(MTIOCLRERR) /* * Found on Solaris */ static inline void os_clrerror(DEVICE *dev) { if (dev->d_ioctl(dev->fd(), MTIOCLRERR) < 0) { dev->clrerror(MTIOCLRERR); } Dmsg0(200, "Did MTIOCLRERR\n"); } #elif defined(MTIOCERRSTAT) /* * Typically on FreeBSD */ static inline void os_clrerror(DEVICE *dev) { berrno be; union mterrstat mt_errstat; /* * Read and clear SCSI error status */ Dmsg2(200, "Doing MTIOCERRSTAT errno=%d ERR=%s\n", dev->dev_errno, be.bstrerror(dev->dev_errno)); if (dev->d_ioctl(dev->fd(), MTIOCERRSTAT, (char *)&mt_errstat) < 0) { dev->clrerror(MTIOCERRSTAT); } } #elif defined(MTCSE) /* * Clear Subsystem Exception TRU64 */ static inline void os_clrerror(DEVICE *dev) { struct mtop mt_com; /* * Clear any error condition on the tape */ mt_com.mt_op = MTCSE; mt_com.mt_count = 1; if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } Dmsg0(200, "Did MTCSE\n"); } #else static inline void os_clrerror(DEVICE *dev) { } #endif /* * If implemented in system, clear the tape error status. */ void generic_tape_device::clrerror(int func) { const char *msg = NULL; char buf[100]; dev_errno = errno; /* save errno */ if (errno == EIO) { VolCatInfo.VolCatErrors++; } if (errno == ENOTTY || errno == ENOSYS) { /* Function not implemented */ switch (func) { case -1: break; /* ignore message printed later */ case MTWEOF: msg = "WTWEOF"; clear_cap(CAP_EOF); /* turn off feature */ break; #ifdef MTEOM case MTEOM: msg = "WTEOM"; clear_cap(CAP_EOM); /* turn off feature */ break; #endif case MTFSF: msg = "MTFSF"; clear_cap(CAP_FSF); /* turn off feature */ break; case MTBSF: msg = "MTBSF"; clear_cap(CAP_BSF); /* turn off feature */ break; case MTFSR: msg = "MTFSR"; clear_cap(CAP_FSR); /* turn off feature */ break; case MTBSR: msg = "MTBSR"; clear_cap(CAP_BSR); /* turn off feature */ break; case MTREW: msg = "MTREW"; break; #ifdef MTSETBLK case MTSETBLK: msg = "MTSETBLK"; break; #endif #ifdef MTSETDRVBUFFER case MTSETDRVBUFFER: msg = "MTSETDRVBUFFER"; break; #endif #ifdef MTRESET case MTRESET: msg = "MTRESET"; break; #endif #ifdef MTSETBSIZ case MTSETBSIZ: msg = "MTSETBSIZ"; break; #endif #ifdef MTSRSZ case MTSRSZ: msg = "MTSRSZ"; break; #endif #ifdef MTLOAD case MTLOAD: msg = "MTLOAD"; break; #endif #ifdef MTLOCK case MTLOCK: msg = "MTLOCK"; break; #endif #ifdef MTUNLOCK case MTUNLOCK: msg = "MTUNLOCK"; break; #endif case MTOFFL: msg = "MTOFFL"; break; #ifdef MTIOCLRERR case MTIOCLRERR: msg = "MTIOCLRERR"; break; #endif #ifdef MTIOCERRSTAT case MTIOCERRSTAT: msg = "MTIOCERRSTAT"; break; #endif #ifdef MTCSE case MTCSE: msg = "MTCSE"; break; #endif default: bsnprintf(buf, sizeof(buf), _("unknown func code %d"), func); msg = buf; break; } if (msg != NULL) { dev_errno = ENOSYS; Mmsg1(errmsg, _("I/O function \"%s\" not supported on this device.\n"), msg); Emsg0(M_ERROR, 0, errmsg); } } /* * Now we try different methods of clearing the error status on the drive * so that it is not locked for further operations. */ /* * On some systems such as NetBSD, this clears all errors */ get_os_tape_file(); /* * OS specific clear function. */ os_clrerror(this); } void generic_tape_device::set_os_device_parameters(DCR *dcr) { DEVICE *dev = dcr->dev; if (bstrcmp(dev->dev_name, "/dev/null")) { return; /* no use trying to set /dev/null */ } #if defined(HAVE_LINUX_OS) || defined(HAVE_WIN32) struct mtop mt_com; Dmsg0(100, "In set_os_device_parameters\n"); #if defined(MTSETBLK) if (dev->min_block_size == dev->max_block_size && dev->min_block_size == 0) { /* variable block mode */ mt_com.mt_op = MTSETBLK; mt_com.mt_count = 0; Dmsg0(100, "Set block size to zero\n"); if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } } #endif #if defined(MTSETDRVBUFFER) if (getuid() == 0) { /* Only root can do this */ mt_com.mt_op = MTSETDRVBUFFER; mt_com.mt_count = MT_ST_CLEARBOOLEANS; if (!dev->has_cap(CAP_TWOEOF)) { mt_com.mt_count |= MT_ST_TWO_FM; } if (dev->has_cap(CAP_EOM)) { mt_com.mt_count |= MT_ST_FAST_MTEOM; } Dmsg0(100, "MTSETDRVBUFFER\n"); if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } } #endif return; #endif #ifdef HAVE_NETBSD_OS struct mtop mt_com; if (dev->min_block_size == dev->max_block_size && dev->min_block_size == 0) { /* variable block mode */ mt_com.mt_op = MTSETBSIZ; mt_com.mt_count = 0; if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } /* Get notified at logical end of tape */ mt_com.mt_op = MTEWARN; mt_com.mt_count = 1; if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } } return; #endif #if HAVE_FREEBSD_OS || HAVE_OPENBSD_OS struct mtop mt_com; if (dev->min_block_size == dev->max_block_size && dev->min_block_size == 0) { /* variable block mode */ mt_com.mt_op = MTSETBSIZ; mt_com.mt_count = 0; if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } } #if defined(MTIOCSETEOTMODEL) uint32_t neof; if (dev->has_cap(CAP_TWOEOF)) { neof = 2; } else { neof = 1; } if (dev->d_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) { berrno be; dev->dev_errno = errno; /* save errno */ Mmsg2(dev->errmsg, _("Unable to set eotmodel on device %s: ERR=%s\n"), dev->print_name(), be.bstrerror(dev->dev_errno)); Jmsg(dcr->jcr, M_FATAL, 0, dev->errmsg); } #endif return; #endif #ifdef HAVE_SUN_OS struct mtop mt_com; if (dev->min_block_size == dev->max_block_size && dev->min_block_size == 0) { /* variable block mode */ mt_com.mt_op = MTSRSZ; mt_com.mt_count = 0; if (dev->d_ioctl(dev->fd(), MTIOCTOP, (char *)&mt_com) < 0) { dev->clrerror(mt_com.mt_op); } } return; #endif } /* * Returns file position on tape or -1 */ int32_t generic_tape_device::get_os_tape_file() { struct mtget mt_stat; if (has_cap(CAP_MTIOCGET) && d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) { return mt_stat.mt_fileno; } return -1; } /* * Rewind the device. * * Returns: true on success * false on failure */ bool generic_tape_device::rewind(DCR *dcr) { struct mtop mt_com; unsigned int i; bool first = true; Dmsg3(400, "rewind res=%d fd=%d %s\n", num_reserved(), m_fd, prt_name); state &= ~(ST_EOT | ST_EOF | ST_WEOT); /* Remove EOF/EOT flags */ block_num = file = 0; file_size = 0; file_addr = 0; if (m_fd < 0) { return false; } mt_com.mt_op = MTREW; mt_com.mt_count = 1; /* * If we get an I/O error on rewind, it is probably because * the drive is actually busy. We loop for (about 5 minutes) * retrying every 5 seconds. */ for (i = max_rewind_wait; ; i -= 5) { if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { berrno be; clrerror(mt_com.mt_op); if (i == max_rewind_wait) { Dmsg1(200, "Rewind error, %s. retrying ...\n", be.bstrerror()); } /* * This is a gross hack, because if the user has the * device mounted (i.e. open), then uses mtx to load * a tape, the current open file descriptor is invalid. * So, we close the drive and re-open it. */ if (first && dcr) { int oo_mode = open_mode; d_close(m_fd); clear_opened(); open(dcr, oo_mode); if (m_fd < 0) { return false; } first = false; continue; } #ifdef HAVE_SUN_OS if (dev_errno == EIO) { Mmsg1(errmsg, _("No tape loaded or drive offline on %s.\n"), prt_name); return false; } #else if (dev_errno == EIO && i > 0) { Dmsg0(200, "Sleeping 5 seconds.\n"); bmicrosleep(5, 0); continue; } #endif Mmsg2(errmsg, _("Rewind error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); return false; } break; } return true; } /* * (Un)mount the device (for tape devices) */ static bool do_mount(DCR *dcr, int mount, int dotimeout) { DEVRES *device = dcr->dev->device; POOL_MEM ocmd(PM_FNAME); POOLMEM *results; char *icmd; int status, tries; berrno be; Dsm_check(200); if (mount) { icmd = device->mount_command; } else { icmd = device->unmount_command; } dcr->dev->edit_mount_codes(ocmd, icmd); Dmsg2(100, "do_mount: cmd=%s mounted=%d\n", ocmd.c_str(), dcr->dev->is_mounted()); if (dotimeout) { /* Try at most 10 times to (un)mount the device. This should perhaps be configurable. */ tries = 10; } else { tries = 1; } results = get_memory(4000); /* If busy retry each second */ Dmsg1(100, "do_mount run_prog=%s\n", ocmd.c_str()); while ((status = run_program_full_output(ocmd.c_str(), dcr->dev->max_open_wait / 2, results)) != 0) { if (tries-- > 0) { continue; } Dmsg5(100, "Device %s cannot be %smounted. stat=%d result=%s ERR=%s\n", dcr->dev->print_name(), (mount ? "" : "un"), status, results, be.bstrerror(status)); Mmsg(dcr->dev->errmsg, _("Device %s cannot be %smounted. ERR=%s\n"), dcr->dev->print_name(), (mount ? "" : "un"), be.bstrerror(status)); free_pool_memory(results); Dmsg0(200, "============ mount=0\n"); Dsm_check(200); return false; } free_pool_memory(results); Dmsg1(200, "============ mount=%d\n", mount); return true; } uint32_t generic_tape_device::status_dev() { struct mtget mt_stat; uint32_t status = 0; if (state & (ST_EOT | ST_WEOT)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (state & ST_EOF) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } status |= BMT_TAPE; Pmsg0(-20,_(" Bareos status:")); Pmsg2(-20,_(" file=%d block=%d\n"), file, block_num); if (d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); return 0; } Pmsg0(-20, _(" Device status:")); #if defined(HAVE_LINUX_OS) if (GMT_EOF(mt_stat.mt_gstat)) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } if (GMT_BOT(mt_stat.mt_gstat)) { status |= BMT_BOT; Pmsg0(-20, " BOT"); } if (GMT_EOT(mt_stat.mt_gstat)) { status |= BMT_EOT; Pmsg0(-20, " EOT"); } if (GMT_SM(mt_stat.mt_gstat)) { status |= BMT_SM; Pmsg0(-20, " SM"); } if (GMT_EOD(mt_stat.mt_gstat)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (GMT_WR_PROT(mt_stat.mt_gstat)) { status |= BMT_WR_PROT; Pmsg0(-20, " WR_PROT"); } if (GMT_ONLINE(mt_stat.mt_gstat)) { status |= BMT_ONLINE; Pmsg0(-20, " ONLINE"); } if (GMT_DR_OPEN(mt_stat.mt_gstat)) { status |= BMT_DR_OPEN; Pmsg0(-20, " DR_OPEN"); } if (GMT_IM_REP_EN(mt_stat.mt_gstat)) { status |= BMT_IM_REP_EN; Pmsg0(-20, " IM_REP_EN"); } #elif defined(HAVE_WIN32) if (GMT_EOF(mt_stat.mt_gstat)) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } if (GMT_BOT(mt_stat.mt_gstat)) { status |= BMT_BOT; Pmsg0(-20, " BOT"); } if (GMT_EOT(mt_stat.mt_gstat)) { status |= BMT_EOT; Pmsg0(-20, " EOT"); } if (GMT_EOD(mt_stat.mt_gstat)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (GMT_WR_PROT(mt_stat.mt_gstat)) { status |= BMT_WR_PROT; Pmsg0(-20, " WR_PROT"); } if (GMT_ONLINE(mt_stat.mt_gstat)) { status |= BMT_ONLINE; Pmsg0(-20, " ONLINE"); } if (GMT_DR_OPEN(mt_stat.mt_gstat)) { status |= BMT_DR_OPEN; Pmsg0(-20, " DR_OPEN"); } if (GMT_IM_REP_EN(mt_stat.mt_gstat)) { status |= BMT_IM_REP_EN; Pmsg0(-20, " IM_REP_EN"); } #endif /* HAVE_LINUX_OS || HAVE_WIN32 */ if (has_cap(CAP_MTIOCGET)) { Pmsg2(-20, _(" file=%d block=%d\n"), mt_stat.mt_fileno, mt_stat.mt_blkno); } else { Pmsg2(-20, _(" file=%d block=%d\n"), -1, -1); } return status; } /* * Set the position of the device. * * Returns: true on succes * false on error */ bool generic_tape_device::update_pos(DCR *dcr) { return true; } /* * Reposition the device to file, block * * Returns: false on failure * true on success */ bool generic_tape_device::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) { Dmsg4(100, "reposition from %u:%u to %u:%u\n", file, block_num, rfile, rblock); if (rfile < file) { Dmsg0(100, "Rewind\n"); if (!rewind(NULL)) { return false; } } if (rfile > file) { Dmsg1(100, "fsf %d\n", rfile-file); if (!fsf(rfile-file)) { Dmsg1(100, "fsf failed! ERR=%s\n", bstrerror()); return false; } Dmsg2(100, "wanted_file=%d at_file=%d\n", rfile, file); } if (rblock < block_num) { Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); Dmsg0(100, "bsf 1\n"); bsf(1); Dmsg0(100, "fsf 1\n"); fsf(1); Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); } if (has_cap(CAP_POSITIONBLOCKS) && rblock > block_num) { /* * Ignore errors as Bareos can read to the correct block. */ Dmsg1(100, "fsr %d\n", rblock-block_num); return fsr(rblock-block_num); } else { while (rblock > block_num) { if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; dev_errno = errno; Dmsg2(30, "Failed to find requested block on %s: ERR=%s", prt_name, be.bstrerror()); return false; } Dmsg2(300, "moving forward wanted_blk=%d at_blk=%d\n", rblock, block_num); } } return true; } /* * Mount the device. * * If timeout, wait until the mount command returns 0. * If !timeout, try to mount the device only once. */ bool generic_tape_device::mount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->mount_command) { retval = do_mount(dcr, true, timeout); } return retval; } /* * Unmount the device * * If timeout, wait until the unmount command returns 0. * If !timeout, try to unmount the device only once. */ bool generic_tape_device::unmount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->unmount_command) { retval = do_mount(dcr, false, timeout); } return retval; } int generic_tape_device::d_open(const char *pathname, int flags, int mode) { return ::open(pathname, flags, mode); } ssize_t generic_tape_device::d_read(int fd, void *buffer, size_t count) { return ::read(fd, buffer, count); } ssize_t generic_tape_device::d_write(int fd, const void *buffer, size_t count) { return ::write(fd, buffer, count); } int generic_tape_device::d_close(int fd) { return ::close(fd); } int generic_tape_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t generic_tape_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { return -1; } bool generic_tape_device::d_truncate(DCR *dcr) { /* * Maybe we should rewind and write and eof ???? */ return true; /* We don't really truncate tapes */ } bareos-Release-14.2.6/src/stored/backends/generic_tape_device.h000066400000000000000000000045351263011562700244250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * GENERIC Tape API device abstraction. * * Marco van Wieringen, June 2014 */ #ifndef GENERIC_TAPE_DEVICE_H #define GENERIC_TAPE_DEVICE_H class generic_tape_device: public DEVICE { public: generic_tape_device() {}; virtual ~generic_tape_device() {}; /* * Interface from DEVICE */ virtual void open_device(DCR *dcr, int omode); virtual uint32_t status_dev(); virtual bool eod(DCR *dcr); virtual void set_ateof(); virtual void set_ateot(); virtual bool offline(); virtual bool weof(int num); virtual bool fsf(int num); virtual bool bsf(int num); virtual bool fsr(int num); virtual bool bsr(int num); virtual bool load_dev(); virtual void lock_door(); virtual void unlock_door(); virtual void clrerror(int func); virtual void set_os_device_parameters(DCR *dcr); virtual int32_t get_os_tape_file(); virtual bool rewind(DCR *dcr); virtual bool update_pos(DCR *dcr); virtual bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); virtual bool mount_backend(DCR *dcr, int timeout); virtual bool unmount_backend(DCR *dcr, int timeout); virtual int d_close(int); virtual int d_open(const char *pathname, int flags, int mode); virtual int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); virtual boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); virtual ssize_t d_read(int fd, void *buffer, size_t count); virtual ssize_t d_write(int fd, const void *buffer, size_t count); virtual bool d_truncate(DCR *dcr); }; #endif /* GENERIC_TAPE_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/gfapi_device.c000066400000000000000000000336551263011562700230660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Gluster Filesystem API device abstraction. * * Marco van Wieringen, February 2014 */ #include "bareos.h" #ifdef HAVE_GFAPI #include "stored.h" #include "backends/gfapi_device.h" /* * Parse a gluster definition into something we can use for setting * up the right connection to a gluster management server and get access * to a gluster volume. * * Syntax: * * gluster[+transport]://[server[:port]]/volname[/dir][?socket=...] * * 'gluster' is the protocol. * * 'transport' specifies the transport type used to connect to gluster * management daemon (glusterd). Valid transport types are tcp, unix * and rdma. If a transport type isn't specified, then tcp type is assumed. * * 'server' specifies the server where the volume file specification for * the given volume resides. This can be either hostname, ipv4 address * or ipv6 address. ipv6 address needs to be within square brackets [ ]. * If transport type is 'unix', then 'server' field should not be specifed. * The 'socket' field needs to be populated with the path to unix domain * socket. * * 'port' is the port number on which glusterd is listening. This is optional * and if not specified, QEMU will send 0 which will make gluster to use the * default port. If the transport type is unix, then 'port' should not be * specified. * * 'volname' is the name of the gluster volume which contains the backup images. * * 'dir' is an optional directory on the 'volname' * * Examples: * * gluster://1.2.3.4/testvol[/dir] * gluster+tcp://1.2.3.4/testvol[/dir] * gluster+tcp://1.2.3.4:24007/testvol[/dir] * gluster+tcp://[1:2:3:4:5:6:7:8]/testvol[/dir] * gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol[/dir] * gluster+tcp://server.domain.com:24007/testvol[/dir] * gluster+unix:///testvol[/dir]?socket=/tmp/glusterd.socket * gluster+rdma://1.2.3.4:24007/testvol[/dir] */ static inline bool parse_gfapi_devicename(char *devicename, char **transport, char **servername, char **volumename, char **dir, int *serverport) { char *bp; /* * Make sure its a URI that starts with gluster. */ if (!bstrncasecmp(devicename, "gluster", 7)) { return false; } /* * Parse any explicit protocol. */ bp = strchr(devicename, '+'); if (bp) { *transport = ++bp; bp = strchr(bp, ':'); if (bp) { *bp++ = '\0'; } else { goto bail_out; } } else { *transport = NULL; bp = strchr(devicename, ':'); if (!bp) { goto bail_out; } } /* * When protocol is not UNIX parse servername and portnr. */ if (!*transport || !bstrcasecmp(*transport, "unix")) { /* * Parse servername of gluster management server. */ bp = strchr(bp, '/'); /* * Validate URI. */ if (!bp || !*bp == '/') { goto bail_out; } /* * Skip the two // */ *bp++ = '\0'; bp++; *servername = bp; /* * Parse any explicit server portnr. * We search reverse in the string for a : what indicates * a port specification but in that string there may not contain a ']' * because then we searching in a IPv6 string. */ bp = strrchr(bp, ':'); if (bp && !strchr(bp, ']')) { char *port; *bp++ = '\0'; port = bp; bp = strchr(bp, '/'); if (!bp) { goto bail_out; } *bp++ = '\0'; *serverport = str_to_int64(port); *volumename = bp; /* * See if there is a dir specified. */ bp = strchr(bp, '/'); if (bp) { *bp++ = '\0'; *dir = bp; } } else { *serverport = 0; bp = *servername; /* * Parse the volume name. */ bp = strchr(bp, '/'); if (!bp) { goto bail_out; } *bp++ = '\0'; *volumename = bp; /* * See if there is a dir specified. */ bp = strchr(bp, '/'); if (bp) { *bp++ = '\0'; *dir = bp; } } } else { /* * For UNIX serverport is zero. */ *serverport = 0; /* * Validate URI. */ if (*bp != '/' || *(bp + 1) != '/') { goto bail_out; } /* * Skip the two // */ *bp++ = '\0'; bp++; /* * For UNIX URIs the server part of the URI needs to be empty. */ if (*bp++ != '/') { goto bail_out; } *volumename = bp; /* * See if there is a dir specified. */ bp = strchr(bp, '/'); if (bp) { *bp++ = '\0'; *dir = bp; } /* * Parse any socket parameters. */ bp = strchr(bp, '?'); if (bp) { if (bstrncasecmp(bp + 1, "socket=", 7)) { *bp = '\0'; *servername = bp + 8; } } } return true; bail_out: return false; } /* * Create a parent directory using the gfapi. */ static inline bool gfapi_makedir(glfs_t *glfs, const char *directory) { char *bp; struct stat st; bool retval = false; POOL_MEM new_directory(PM_FNAME); pm_strcpy(new_directory, directory); /* * See if the parent exists. */ bp = strrchr(new_directory.c_str(), '/'); if (bp) { /* * See if we reached the root. */ if (bp == new_directory.c_str()) { /* * Create the directory. */ if (glfs_mkdir(glfs, directory, 0750) == 0) { retval = true; } } else { *bp = '\0'; if (glfs_stat(glfs, new_directory.c_str(), &st) != 0) { switch (errno) { case ENOENT: /* * Make sure our parent exists. */ retval = gfapi_makedir(glfs, new_directory.c_str()); if (!retval) { return false; } /* * Create the directory. */ if (glfs_mkdir(glfs, directory, 0750) == 0) { retval = true; } break; default: break; } } else { retval = true; } } } return retval; } /* * Open a volume using gfapi. */ int gfapi_device::d_open(const char *pathname, int flags, int mode) { int status; /* * Parse the gluster URI. */ if (!m_gfapi_volume) { m_gfapi_volume = bstrdup(dev_name); if (!parse_gfapi_devicename(m_gfapi_volume, &m_transport, &m_servername, &m_volumename, &m_basedir, &m_serverport)) { Mmsg1(errmsg, _("Unable to parse device URI %s.\n"), dev_name); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } } /* * See if we need to setup a Gluster context. */ if (!m_glfs) { m_glfs = glfs_new(m_volumename); if (!m_glfs) { Mmsg1(errmsg, _("Unable to create new Gluster context for volumename %s.\n"), m_volumename); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } status = glfs_set_volfile_server(m_glfs, (m_transport) ? m_transport : "tcp", m_servername, m_serverport); if (status < 0) { Mmsg3(errmsg, _("Unable to initialize Gluster management server for transport %s, servername %s, serverport %d\n"), (m_transport) ? m_transport : "tcp", m_servername, m_serverport); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } status = glfs_init(m_glfs); if (status < 0) { Mmsg1(errmsg, _("Unable to initialize Gluster for volumename %s.\n"), m_volumename); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } } /* * See if we don't have a file open already. */ if (m_gfd) { glfs_close(m_gfd); m_gfd = NULL; } /* * See if we store in an explicit directory. */ if (m_basedir) { struct stat st; /* * Make sure the dir exists if one is defined. */ Mmsg(m_virtual_filename, "/%s", m_basedir); if (glfs_stat(m_glfs, m_virtual_filename, &st) != 0) { switch (errno) { case ENOENT: if (!gfapi_makedir(m_glfs, m_virtual_filename)) { Mmsg1(errmsg, _("Specified glusterfs direcory %s cannot be created.\n"), m_virtual_filename); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } break; default: goto bail_out; } } else { if (!S_ISDIR(st.st_mode)) { Mmsg1(errmsg, _("Specified glusterfs direcory %s is not a directory.\n"), m_virtual_filename); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } } Mmsg(m_virtual_filename, "/%s/%s", m_basedir, getVolCatName()); } else { Mmsg(m_virtual_filename, "%s", getVolCatName()); } /* * See if the O_CREAT flag is set as glfs_open doesn't support that flag and you have to call glfs_creat then. */ if (flags & O_CREAT) { m_gfd = glfs_creat(m_glfs, m_virtual_filename, flags, mode); } else { m_gfd = glfs_open(m_glfs, m_virtual_filename, flags); } if (!m_gfd) { goto bail_out; } return 0; bail_out: /* * Cleanup the Gluster context. */ if (m_glfs) { glfs_fini(m_glfs); m_glfs = NULL; } return -1; } /* * Read data from a volume using gfapi. */ ssize_t gfapi_device::d_read(int fd, void *buffer, size_t count) { if (m_gfd) { return glfs_read(m_gfd, buffer, count, 0); } else { errno = EBADF; return -1; } } /* * Write data to a volume using gfapi. */ ssize_t gfapi_device::d_write(int fd, const void *buffer, size_t count) { if (m_gfd) { return glfs_write(m_gfd, buffer, count, 0); } else { errno = EBADF; return -1; } } int gfapi_device::d_close(int fd) { if (m_gfd) { int status; status = glfs_close(m_gfd); m_gfd = NULL; return status; } else { errno = EBADF; return -1; } } int gfapi_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t gfapi_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { if (m_gfd) { return glfs_lseek(m_gfd, offset, whence); } else { errno = EBADF; return -1; } } bool gfapi_device::d_truncate(DCR *dcr) { struct stat st; if (m_gfd) { if (glfs_ftruncate(m_gfd, 0) != 0) { berrno be; Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), prt_name, be.bstrerror()); Emsg0(M_FATAL, 0, errmsg); return false; } /* * Check for a successful glfs_truncate() and issue work-around when truncation doesn't work. * * 1. close file * 2. delete file * 3. open new file with same mode * 4. change ownership to original */ if (glfs_fstat(m_gfd, &st) != 0) { berrno be; Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), prt_name, be.bstrerror()); return false; } if (st.st_size != 0) { /* glfs_truncate() didn't work */ glfs_close(m_gfd); glfs_unlink(m_glfs, m_virtual_filename); /* * Recreate the file -- of course, empty */ oflags = O_CREAT | O_RDWR | O_BINARY; m_gfd = glfs_creat(m_glfs, m_virtual_filename, oflags, st.st_mode); if (!m_gfd) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), m_virtual_filename, be.bstrerror()); Emsg0(M_FATAL, 0, errmsg); return false; } /* * Reset proper owner */ glfs_chown(m_glfs, m_virtual_filename, st.st_uid, st.st_gid); } } return true; } gfapi_device::~gfapi_device() { if (m_gfd) { glfs_close(m_gfd); m_gfd = NULL; } if (!m_glfs) { glfs_fini(m_glfs); m_glfs = NULL; } if (m_gfapi_volume) { free(m_gfapi_volume); m_gfapi_volume = NULL; } free_pool_memory(m_virtual_filename); } gfapi_device::gfapi_device() { m_gfapi_volume = NULL; m_transport = NULL; m_servername = NULL; m_volumename = NULL; m_basedir = NULL; m_serverport = 0; m_glfs = NULL; m_gfd = NULL; m_virtual_filename = get_pool_memory(PM_FNAME); } #ifdef HAVE_DYNAMIC_SD_BACKENDS extern "C" DEVICE SD_IMP_EXP *backend_instantiate(JCR *jcr, int device_type) { DEVICE *dev = NULL; switch (device_type) { case B_GFAPI_DEV: dev = New(gfapi_device); break; default: Jmsg(jcr, M_FATAL, 0, _("Request for unknown devicetype: %d\n"), device_type); break; } return dev; } extern "C" void SD_IMP_EXP flush_backend(void) { } #endif #endif /* HAVE_GFAPI */ bareos-Release-14.2.6/src/stored/backends/gfapi_device.h000066400000000000000000000032631263011562700230630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Gluster Filesystem API device abstraction. * * Marco van Wieringen, February 2014 */ #ifndef GFAPI_DEVICE_H #define GFAPI_DEVICE_H #include class gfapi_device: public DEVICE { private: char *m_gfapi_volume; char *m_transport; char *m_servername; char *m_volumename; char *m_basedir; int m_serverport; glfs_t *m_glfs; glfs_fd_t *m_gfd; POOLMEM *m_virtual_filename; public: gfapi_device(); ~gfapi_device(); /* * Interface from DEVICE */ int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); bool d_truncate(DCR *dcr); }; #endif /* GFAPI_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/object_store_device.c000066400000000000000000000301571263011562700244540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Object Storage API device abstraction. * * Marco van Wieringen, February 2014 */ #include "bareos.h" #ifdef HAVE_OBJECTSTORE #include "stored.h" #include "object_store_device.h" static int droplet_reference_count = 0; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* * Generic log function that glues libdroplet with BAREOS. */ static void object_store_logfunc(dpl_ctx_t *ctx, dpl_log_level_t level, const char *message) { switch (level) { case DPL_DEBUG: Dmsg1(100, "%s\n", message); break; case DPL_INFO: Emsg1(M_INFO, 0, "%s\n", message); break; case DPL_WARNING: Emsg1(M_WARNING, 0, "%s\n", message); break; case DPL_ERROR: Emsg1(M_ERROR, 0, "%s\n", message); break; } } /* * Map the droplet errno's to system ones. */ static inline int droplet_errno_to_system_errno(dpl_status_t status) { switch (status) { case DPL_ENOENT: errno = ENOENT; break; case DPL_EIO: errno = EIO; break; case DPL_ENAMETOOLONG: errno = ENAMETOOLONG; break; case DPL_EEXIST: errno = EEXIST; break; case DPL_EPERM: errno = EPERM; break; default: break; } return -1; } /* * Open a volume using libdroplet. */ int object_store_device::d_open(const char *pathname, int flags, int mode) { dpl_status_t status; dpl_vfile_flag_t dpl_flags; dpl_option_t dpl_options; #if 1 Mmsg1(errmsg, _("Object Storage devices are not yet supported, please disable %s\n"), dev_name); return -1; #endif /* * Initialize the droplet library when its not done previously. */ P(mutex); if (droplet_reference_count == 0) { status = dpl_init(); if (status != DPL_SUCCESS) { V(mutex); return -1; } dpl_set_log_func(object_store_logfunc); droplet_reference_count++; } V(mutex); if (!m_object_configstring) { int len; char *bp; m_object_configstring = bstrdup(dev_name); /* * See if there is a bucket defined. */ bp = strchr(m_object_configstring, ':'); if (bp) { *bp++ = '\0'; m_object_bucketname = bp; } /* * Strip any .profile prefix from the libdroplet profile name. */ len = strlen(m_object_configstring); if (len > 8 && bstrcasecmp(m_object_configstring + (len - 8), ".profile")) { m_object_configstring[len - 8] = '\0'; } } /* * See if we need to setup a new context for this device. */ if (!m_ctx) { char *bp; /* * See if this is a path. */ bp = strrchr(m_object_configstring, '/'); if (!bp) { /* * Only a profile name. */ m_ctx = dpl_ctx_new(NULL, m_object_configstring); } else { if (bp == m_object_configstring) { /* * Profile in root of filesystem */ m_ctx = dpl_ctx_new("/", bp + 1); } else { /* * Profile somewhere else. */ *bp++ = '\0'; m_ctx = dpl_ctx_new(m_object_configstring, bp); } } /* * If we failed to allocate a new context fail the open. */ if (!m_ctx) { Mmsg1(errmsg, _("Failed to create a new context using config %s\n"), dev_name); return -1; } /* * Login if that is needed for this backend. */ status = dpl_login(m_ctx); switch (status) { case DPL_SUCCESS: break; case DPL_ENOTSUPP: /* * Backend doesn't support login which is fine. */ break; default: Mmsg2(errmsg, _("Failed to login for voume %s using dpl_login(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return -1; } /* * If a bucketname was defined set it in the context. */ if (m_object_bucketname) { m_ctx->cur_bucket = m_object_bucketname; } } /* * See if we don't have a file open already. */ if (m_vfd) { dpl_close(m_vfd); m_vfd = NULL; } /* * Create some options for libdroplet. * * DPL_OPTION_NOALLOC - we provide the buffer to copy the data into * no need to let the library allocate memory we * need to free after copying the data. */ memset(&dpl_options, 0, sizeof(dpl_options)); dpl_options.mask |= DPL_OPTION_NOALLOC; if (flags & O_CREAT) { dpl_flags = DPL_VFILE_FLAG_CREAT | DPL_VFILE_FLAG_RDWR; status = dpl_open(m_ctx, /* context */ getVolCatName(), /* locator */ dpl_flags, /* flags */ &dpl_options, /* options */ NULL, /* condition */ NULL, /* metadata */ NULL, /* sysmd */ NULL, /* query_params */ &m_vfd); } else { dpl_flags = DPL_VFILE_FLAG_RDWR; status = dpl_open(m_ctx, /* context */ getVolCatName(), /* locator */ dpl_flags, /* flags */ &dpl_options, /* options */ NULL, /* condition */ NULL, /* metadata */ NULL, /* sysmd */ NULL, /* query_params */ &m_vfd); } switch (status) { case DPL_SUCCESS: m_offset = 0; return 0; default: Mmsg2(errmsg, _("Failed to open %s using dpl_open(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); m_vfd = NULL; return droplet_errno_to_system_errno(status); } } /* * Read data from a volume using libdroplet. */ ssize_t object_store_device::d_read(int fd, void *buffer, size_t count) { if (m_vfd) { int buflen; dpl_status_t status; buflen = count; status = dpl_pread(m_vfd, count, m_offset, (char **)&buffer, &buflen); switch (status) { case DPL_SUCCESS: m_offset += buflen; return buflen; default: Mmsg2(errmsg, _("Failed to read %s using dpl_read(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return droplet_errno_to_system_errno(status); } } else { errno = EBADF; return -1; } } /* * Write data to a volume using libdroplet. */ ssize_t object_store_device::d_write(int fd, const void *buffer, size_t count) { if (m_vfd) { dpl_status_t status; status = dpl_pwrite(m_vfd, (char *)buffer, count, m_offset); switch (status) { case DPL_SUCCESS: m_offset += count; return count; default: Mmsg2(errmsg, _("Failed to write %s using dpl_write(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return droplet_errno_to_system_errno(status); } } else { errno = EBADF; return -1; } } int object_store_device::d_close(int fd) { if (m_vfd) { dpl_status_t status; status = dpl_close(m_vfd); switch (status) { case DPL_SUCCESS: m_vfd = NULL; return 0; default: m_vfd = NULL; return droplet_errno_to_system_errno(status); } } else { errno = EBADF; return -1; } } int object_store_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } /* * Open a directory on the object store and find out size information for a file. */ static inline size_t object_store_get_file_size(dpl_ctx_t *ctx, const char *filename) { void *dir_hdl; dpl_status_t status; dpl_dirent_t dirent; size_t filesize = -1; status = dpl_opendir(ctx, ".", &dir_hdl); switch (status) { case DPL_SUCCESS: break; default: return -1; } while (!dpl_eof(dir_hdl)) { if (bstrcasecmp(dirent.name, filename)) { filesize = dirent.size; break; } } dpl_closedir(dir_hdl); return filesize; } boffset_t object_store_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { switch (whence) { case SEEK_SET: m_offset = offset; break; case SEEK_CUR: m_offset += offset; break; case SEEK_END: { size_t filesize; filesize = object_store_get_file_size(m_ctx, getVolCatName()); if (filesize >= 0) { m_offset = filesize + offset; } else { return -1; } break; } default: return -1; } return m_offset; } bool object_store_device::d_truncate(DCR *dcr) { /* * libdroplet doesn't have a truncate function so unlink the volume and create a new empty one. */ if (m_vfd) { dpl_status_t status; dpl_vfile_flag_t dpl_flags; dpl_option_t dpl_options; status = dpl_close(m_vfd); switch (status) { case DPL_SUCCESS: m_vfd = NULL; break; default: Mmsg2(errmsg, _("Failed to close %s using dpl_close(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return false; } status = dpl_unlink(m_ctx, getVolCatName()); switch (status) { case DPL_SUCCESS: break; default: Mmsg2(errmsg, _("Failed to unlink %s using dpl_unlink(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return false; } /* * Create some options for libdroplet. * * DPL_OPTION_NOALLOC - we provide the buffer to copy the data into * no need to let the library allocate memory we * need to free after copying the data. */ memset(&dpl_options, 0, sizeof(dpl_options)); dpl_options.mask |= DPL_OPTION_NOALLOC; dpl_flags = DPL_VFILE_FLAG_CREAT | DPL_VFILE_FLAG_RDWR; status = dpl_open(m_ctx, /* context */ getVolCatName(), /* locator */ dpl_flags, /* flags */ &dpl_options, /* options */ NULL, /* condition */ NULL, /* metadata */ NULL, /* sysmd */ NULL, /* query_params */ &m_vfd); switch (status) { case DPL_SUCCESS: break; default: Mmsg2(errmsg, _("Failed to open %s using dpl_open(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return false; } } return true; } object_store_device::~object_store_device() { if (m_ctx) { dpl_ctx_free(m_ctx); m_ctx = NULL; } if (m_object_configstring) { free(m_object_configstring); } P(mutex); droplet_reference_count--; if (droplet_reference_count == 0) { dpl_free(); } V(mutex); } object_store_device::object_store_device() { m_object_configstring = NULL; m_object_bucketname = NULL; m_ctx = NULL; } #ifdef HAVE_DYNAMIC_SD_BACKENDS extern "C" DEVICE SD_IMP_EXP *backend_instantiate(JCR *jcr, int device_type) { DEVICE *dev = NULL; switch (device_type) { case B_OBJECT_STORE_DEV: dev = New(object_store_device); break; default: Jmsg(jcr, M_FATAL, 0, _("Request for unknown devicetype: %d\n"), device_type); break; } return dev; } extern "C" void SD_IMP_EXP flush_backend(void) { } #endif #endif /* HAVE_OBJECTSTORE */ bareos-Release-14.2.6/src/stored/backends/object_store_device.h000066400000000000000000000032451263011562700244570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Object Storage API device abstraction. * * Marco van Wieringen, February 2014 */ #ifndef OBJECTSTORAGE_DEVICE_H #define OBJECTSTORAGE_DEVICE_H #include #include class object_store_device: public DEVICE { private: char *m_object_configstring; char *m_object_bucketname; dpl_ctx_t *m_ctx; dpl_vfile_t *m_vfd; boffset_t m_offset; public: object_store_device(); ~object_store_device(); /* * Interface from DEVICE */ int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); bool d_truncate(DCR *dcr); }; #endif /* OBJECTSTORE_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/rados_device.c000066400000000000000000000172561263011562700231070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * CEPH (librados) API device abstraction. * * Marco van Wieringen, February 2014 */ #include "bareos.h" #ifdef HAVE_RADOS #include "stored.h" #include "rados_device.h" /* * Open a volume using librados. */ int rados_device::d_open(const char *pathname, int flags, int mode) { int status; uint64_t object_size; time_t object_mtime; berrno be; if (!m_rados_configstring) { char *bp; m_rados_configstring = bstrdup(dev_name); bp = strchr(m_rados_configstring, ':'); if (!bp) { Mmsg1(errmsg, _("Unable to parse device %s.\n"), dev_name); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } *bp++ = '\0'; m_rados_conffile = m_rados_configstring; m_rados_poolname = bp; } if (!m_cluster_initialized) { status = rados_create(&m_cluster, NULL); if (status < 0) { Mmsg1(errmsg, _("Unable to create RADOS cluster: ERR=%s\n"), be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } status = rados_conf_read_file(m_cluster, m_rados_conffile); if (status < 0) { Mmsg2(errmsg, _("Unable to read RADOS config %s: ERR=%s\n"), m_rados_conffile, be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); rados_shutdown(m_cluster); goto bail_out; } status = rados_connect(m_cluster); if (status < 0) { Mmsg1(errmsg, _("Unable to connect to RADOS cluster: ERR=%s\n"), be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); rados_shutdown(m_cluster); goto bail_out; } m_cluster_initialized = true; } if (!m_ctx) { status = rados_ioctx_create(m_cluster, m_rados_poolname, &m_ctx); if (status < 0) { Mmsg2(errmsg, _("Unable to create RADOS IO context for pool %s: ERR=%s\n"), m_rados_poolname, be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } } /* * See if the object already exists. */ status = rados_stat(m_ctx, getVolCatName(), &object_size, &object_mtime); /* * See if the O_CREAT flag is set. */ if (flags & O_CREAT) { if (status < 0) { switch (status) { case -ENOENT: /* * Create an empty object. * e.g. write one byte and then truncate it to zero bytes. */ rados_write(m_ctx, getVolCatName(), " ", 1, 0); rados_trunc(m_ctx, getVolCatName(), 0); break; default: errno = -status; return -1; } } } else { if (status < 0) { errno = -status; return -1; } } m_offset = 0; return 0; bail_out: if (m_cluster_initialized) { rados_shutdown(&m_cluster); m_cluster_initialized = false; } return -1; } /* * Read data from a volume using librados. */ ssize_t rados_device::d_read(int fd, void *buffer, size_t count) { if (m_ctx) { int nr_read; nr_read = rados_read(m_ctx, getVolCatName(), (char *)buffer, count, m_offset); if (nr_read >= 0) { m_offset += nr_read; return nr_read; } else { errno = -nr_read; return -1; } } else { errno = EBADF; return -1; } } /* * Write data to a volume using librados. * * Seems the API changed everything earlier then 0.69 returns bytes written. */ #if LIBRADOS_VERSION_CODE <= 17408 ssize_t rados_device::d_write(int fd, const void *buffer, size_t count) { if (m_ctx) { int nr_written; nr_written = rados_write(m_ctx, getVolCatName(), (char *)buffer, count, m_offset); if (nr_written >= 0) { m_offset += nr_written; return nr_written; } else { errno = -nr_written; return -1; } } else { errno = EBADF; return -1; } } #else ssize_t rados_device::d_write(int fd, const void *buffer, size_t count) { if (m_ctx) { int status; status = rados_write(m_ctx, getVolCatName(), (char *)buffer, count, m_offset); if (status == 0) { m_offset += count; return count; } else { errno = -status; return -1; } } else { errno = EBADF; return -1; } } #endif int rados_device::d_close(int fd) { /* * Destroy the IOcontext. */ if (m_ctx) { rados_ioctx_destroy(m_ctx); m_ctx = NULL; } else { errno = EBADF; return -1; } return 0; } int rados_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t rados_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { switch (whence) { case SEEK_SET: m_offset = offset; break; case SEEK_CUR: m_offset += offset; break; case SEEK_END: { uint64_t object_size; time_t object_mtime; if (rados_stat(m_ctx, getVolCatName(), &object_size, &object_mtime) == 0) { m_offset = object_size + offset; } else { return -1; } break; } default: return -1; } return m_offset; } bool rados_device::d_truncate(DCR *dcr) { if (m_ctx) { int status; uint64_t object_size; time_t object_mtime; berrno be; status = rados_trunc(m_ctx, getVolCatName(), 0); if (status < 0) { Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), prt_name, be.bstrerror(-status)); Emsg0(M_FATAL, 0, errmsg); return false; } status = rados_stat(m_ctx, getVolCatName(), &object_size, &object_mtime); if (status < 0) { Mmsg2(errmsg, _("Unable to stat volume %s. ERR=%s\n"), getVolCatName(), be.bstrerror(-status)); return false; } if (object_size != 0) { /* rados_trunc() didn't work. */ status = rados_remove(m_ctx, getVolCatName()); if (status < 0) { Mmsg2(errmsg, _("Unable to remove volume %s. ERR=%s\n"), getVolCatName(), be.bstrerror(-status)); return false; } } m_offset = 0; } return true; } rados_device::~rados_device() { if (m_ctx) { rados_ioctx_destroy(m_ctx); m_ctx = NULL; } if (m_cluster_initialized) { rados_shutdown(&m_cluster); m_cluster_initialized = false; } if (m_rados_configstring) { free(m_rados_configstring); } } rados_device::rados_device() { m_rados_configstring = NULL; m_rados_conffile = NULL; m_rados_poolname = NULL; m_cluster_initialized = false; m_ctx = NULL; } #ifdef HAVE_DYNAMIC_SD_BACKENDS extern "C" DEVICE SD_IMP_EXP *backend_instantiate(JCR *jcr, int device_type) { DEVICE *dev = NULL; switch (device_type) { case B_RADOS_DEV: dev = New(rados_device); break; default: Jmsg(jcr, M_FATAL, 0, _("Request for unknown devicetype: %d\n"), device_type); break; } return dev; } extern "C" void SD_IMP_EXP flush_backend(void) { } #endif #endif /* HAVE_RADOS */ bareos-Release-14.2.6/src/stored/backends/rados_device.h000066400000000000000000000032411263011562700231010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * CEPH (librados) API device abstraction. * * Marco van Wieringen, February 2014 */ #ifndef RADOS_DEVICE_H #define RADOS_DEVICE_H #include class rados_device: public DEVICE { private: char *m_rados_configstring; char *m_rados_conffile; char *m_rados_poolname; bool m_cluster_initialized; rados_t m_cluster; rados_ioctx_t m_ctx; boffset_t m_offset; public: rados_device(); ~rados_device(); /* * Interface from DEVICE */ int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); bool d_truncate(DCR *dcr); }; #endif /* RADOS_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/unix_fifo_device.c000066400000000000000000000223561263011562700237620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UNIX FIFO API device abstraction. * * Kern Sibbald, MM * * Extracted from other source files Marco van Wieringen, December 2013 */ #include "bareos.h" #include "stored.h" #include "unix_fifo_device.h" /* * Open a fifo device */ void unix_fifo_device::open_device(DCR *dcr, int omode) { file_size = 0; int timeout = max_open_wait; utime_t start_time = time(NULL); mount(dcr, 1); /* do mount if required */ Dmsg0(100, "Open dev: device is fifo\n"); get_autochanger_loaded_slot(dcr); open_mode = omode; set_mode(omode); if (timeout < 1) { timeout = 1; } errno = 0; if (timeout) { /* * Set open timer */ tid = start_thread_timer(dcr->jcr, pthread_self(), timeout); } Dmsg2(100, "Try open %s mode=%s\n", prt_name, mode_to_str(omode)); /* * If busy retry each second for max_open_wait seconds */ for ( ;; ) { /* * Try non-blocking open */ m_fd = d_open(dev_name, oflags | O_NONBLOCK, 0); if (m_fd < 0) { berrno be; dev_errno = errno; Dmsg5(100, "Open error on %s omode=%d oflags=%x errno=%d: ERR=%s\n", prt_name, omode, oflags, errno, be.bstrerror()); } else { d_close(m_fd); m_fd = d_open(dev_name, oflags, 0); /* open normally */ if (m_fd < 0) { berrno be; dev_errno = errno; Dmsg5(100, "Open error on %s omode=%d oflags=%x errno=%d: ERR=%s\n", prt_name, omode, oflags, errno, be.bstrerror()); break; } dev_errno = 0; lock_door(); break; /* Successfully opened and rewound */ } bmicrosleep(5, 0); /* * Exceed wait time ? */ if (time(NULL) - start_time >= max_open_wait) { break; /* yes, get out */ } } if (!is_open()) { berrno be; Mmsg2(errmsg, _("Unable to open device %s: ERR=%s\n"), prt_name, be.bstrerror(dev_errno)); Dmsg1(100, "%s", errmsg); } /* * Stop any open() timer we started */ if (tid) { stop_thread_timer(tid); tid = 0; } Dmsg1(100, "open dev: fifo %d opened\n", m_fd); } bool unix_fifo_device::eod(DCR *dcr) { if (m_fd < 0) { dev_errno = EBADF; Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), prt_name); return false; } Dmsg0(100, "Enter eod\n"); if (at_eot()) { return true; } clear_eof(); /* remove EOF flag */ block_num = file = 0; file_size = 0; file_addr = 0; return true; } /* * (Un)mount the device (For a FILE device) */ static bool do_mount(DCR *dcr, bool mount, int dotimeout) { DEVRES *device = dcr->dev->device; POOL_MEM ocmd(PM_FNAME); POOLMEM *results; DIR* dp; char *icmd; struct dirent *entry, *result; int status, tries, name_max, count; berrno be; Dsm_check(200); if (mount) { icmd = device->mount_command; } else { icmd = device->unmount_command; } dcr->dev->edit_mount_codes(ocmd, icmd); Dmsg2(100, "do_mount: cmd=%s mounted=%d\n", ocmd.c_str(), dcr->dev->is_mounted()); if (dotimeout) { /* Try at most 10 times to (un)mount the device. This should perhaps be configurable. */ tries = 10; } else { tries = 1; } results = get_memory(4000); /* If busy retry each second */ Dmsg1(100, "do_mount run_prog=%s\n", ocmd.c_str()); while ((status = run_program_full_output(ocmd.c_str(), dcr->dev->max_open_wait / 2, results)) != 0) { /* Doesn't work with internationalization (This is not a problem) */ if (mount && fnmatch("*is already mounted on*", results, 0) == 0) { break; } if (!mount && fnmatch("* not mounted*", results, 0) == 0) { break; } if (tries-- > 0) { /* Sometimes the device cannot be mounted because it is already mounted. * Try to unmount it, then remount it */ if (mount) { Dmsg1(400, "Trying to unmount the device %s...\n", dcr->dev->print_name()); do_mount(dcr, 0, 0); } bmicrosleep(1, 0); continue; } Dmsg5(100, "Device %s cannot be %smounted. status=%d result=%s ERR=%s\n", dcr->dev->print_name(), (mount ? "" : "un"), status, results, be.bstrerror(status)); Mmsg(dcr->dev->errmsg, _("Device %s cannot be %smounted. ERR=%s\n"), dcr->dev->print_name(), (mount ? "" : "un"), be.bstrerror(status)); /* * Now, just to be sure it is not mounted, try to read the filesystem. */ name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (!(dp = opendir(device->mount_point))) { berrno be; dcr->dev->dev_errno = errno; Dmsg3(100, "do_mount: failed to open dir %s (dev=%s), ERR=%s\n", device->mount_point, dcr->dev->print_name(), be.bstrerror()); goto get_out; } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); count = 0; while (1) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { dcr->dev->dev_errno = EIO; Dmsg2(129, "do_mount: failed to find suitable file in dir %s (dev=%s)\n", device->mount_point, dcr->dev->print_name()); break; } if (!bstrcmp(result->d_name, ".") && !bstrcmp(result->d_name, "..") && !bstrcmp(result->d_name, ".keep")) { count++; /* result->d_name != ., .. or .keep (Gentoo-specific) */ break; } else { Dmsg2(129, "do_mount: ignoring %s in %s\n", result->d_name, device->mount_point); } } free(entry); closedir(dp); Dmsg1(100, "do_mount: got %d files in the mount point (not counting ., .. and .keep)\n", count); if (count > 0) { /* If we got more than ., .. and .keep */ /* there must be something mounted */ if (mount) { Dmsg1(100, "Did Mount by count=%d\n", count); break; } else { /* An unmount request. We failed to unmount - report an error */ free_pool_memory(results); Dmsg0(200, "== error mount=1 wanted unmount\n"); return false; } } get_out: free_pool_memory(results); Dmsg0(200, "============ mount=0\n"); Dsm_check(200); return false; } free_pool_memory(results); Dmsg1(200, "============ mount=%d\n", mount); return true; } /* * Mount the device. * * If timeout, wait until the mount command returns 0. * If !timeout, try to mount the device only once. */ bool unix_fifo_device::mount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->mount_command) { retval = do_mount(dcr, true, timeout); } return retval; } /* * Unmount the device * * If timeout, wait until the unmount command returns 0. * If !timeout, try to unmount the device only once. */ bool unix_fifo_device::unmount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->unmount_command) { retval = do_mount(dcr, false, timeout); } return retval; } int unix_fifo_device::d_open(const char *pathname, int flags, int mode) { return ::open(pathname, flags, mode); } ssize_t unix_fifo_device::d_read(int fd, void *buffer, size_t count) { return ::read(fd, buffer, count); } ssize_t unix_fifo_device::d_write(int fd, const void *buffer, size_t count) { return ::write(fd, buffer, count); } int unix_fifo_device::d_close(int fd) { return ::close(fd); } int unix_fifo_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t unix_fifo_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { return -1; } bool unix_fifo_device::d_truncate(DCR *dcr) { return true; } unix_fifo_device::~unix_fifo_device() { } unix_fifo_device::unix_fifo_device() { } #ifdef HAVE_DYNAMIC_SD_BACKENDS extern "C" DEVICE SD_IMP_EXP *backend_instantiate(JCR *jcr, int device_type) { DEVICE *dev = NULL; switch (device_type) { case B_FIFO_DEV: dev = New(unix_fifo_device); break; default: Jmsg(jcr, M_FATAL, 0, _("Request for unknown devicetype: %d\n"), device_type); break; } return dev; } extern "C" void SD_IMP_EXP flush_backend(void) { } #endif bareos-Release-14.2.6/src/stored/backends/unix_fifo_device.h000066400000000000000000000031561263011562700237640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UNIX File API device abstraction. * * Marco van Wieringen, June 2014 */ #ifndef UNIX_FIFO_DEVICE_H #define UNIX_FIFO_DEVICE_H class unix_fifo_device: public DEVICE { public: unix_fifo_device(); ~unix_fifo_device(); /* * Interface from DEVICE */ void open_device(DCR *dcr, int omode); bool eod(DCR *dcr); bool mount_backend(DCR *dcr, int timeout); bool unmount_backend(DCR *dcr, int timeout); int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); bool d_truncate(DCR *dcr); }; #endif /* UNIX_FIFO_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/unix_file_device.c000066400000000000000000000203331263011562700237470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UNIX FILE API device abstraction. * * Kern Sibbald, MM * * Extracted from other source files Marco van Wieringen, December 2013 */ #include "bareos.h" #include "stored.h" #include "unix_file_device.h" /* * (Un)mount the device (For a FILE device) */ static bool do_mount(DCR *dcr, bool mount, int dotimeout) { DEVRES *device = dcr->dev->device; POOL_MEM ocmd(PM_FNAME); POOLMEM *results; DIR* dp; char *icmd; struct dirent *entry, *result; int status, tries, name_max, count; berrno be; Dsm_check(200); if (mount) { icmd = device->mount_command; } else { icmd = device->unmount_command; } dcr->dev->edit_mount_codes(ocmd, icmd); Dmsg2(100, "do_mount: cmd=%s mounted=%d\n", ocmd.c_str(), dcr->dev->is_mounted()); if (dotimeout) { /* Try at most 10 times to (un)mount the device. This should perhaps be configurable. */ tries = 10; } else { tries = 1; } results = get_memory(4000); /* If busy retry each second */ Dmsg1(100, "do_mount run_prog=%s\n", ocmd.c_str()); while ((status = run_program_full_output(ocmd.c_str(), dcr->dev->max_open_wait / 2, results)) != 0) { /* Doesn't work with internationalization (This is not a problem) */ if (mount && fnmatch("*is already mounted on*", results, 0) == 0) { break; } if (!mount && fnmatch("* not mounted*", results, 0) == 0) { break; } if (tries-- > 0) { /* Sometimes the device cannot be mounted because it is already mounted. * Try to unmount it, then remount it */ if (mount) { Dmsg1(400, "Trying to unmount the device %s...\n", dcr->dev->print_name()); do_mount(dcr, 0, 0); } bmicrosleep(1, 0); continue; } Dmsg5(100, "Device %s cannot be %smounted. status=%d result=%s ERR=%s\n", dcr->dev->print_name(), (mount ? "" : "un"), status, results, be.bstrerror(status)); Mmsg(dcr->dev->errmsg, _("Device %s cannot be %smounted. ERR=%s\n"), dcr->dev->print_name(), (mount ? "" : "un"), be.bstrerror(status)); /* * Now, just to be sure it is not mounted, try to read the filesystem. */ name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (!(dp = opendir(device->mount_point))) { berrno be; dcr->dev->dev_errno = errno; Dmsg3(100, "do_mount: failed to open dir %s (dev=%s), ERR=%s\n", device->mount_point, dcr->dev->print_name(), be.bstrerror()); goto get_out; } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); count = 0; while (1) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { dcr->dev->dev_errno = EIO; Dmsg2(129, "do_mount: failed to find suitable file in dir %s (dev=%s)\n", device->mount_point, dcr->dev->print_name()); break; } if (!bstrcmp(result->d_name, ".") && !bstrcmp(result->d_name, "..") && !bstrcmp(result->d_name, ".keep")) { count++; /* result->d_name != ., .. or .keep (Gentoo-specific) */ break; } else { Dmsg2(129, "do_mount: ignoring %s in %s\n", result->d_name, device->mount_point); } } free(entry); closedir(dp); Dmsg1(100, "do_mount: got %d files in the mount point (not counting ., .. and .keep)\n", count); if (count > 0) { /* If we got more than ., .. and .keep */ /* there must be something mounted */ if (mount) { Dmsg1(100, "Did Mount by count=%d\n", count); break; } else { /* An unmount request. We failed to unmount - report an error */ free_pool_memory(results); Dmsg0(200, "== error mount=1 wanted unmount\n"); return false; } } get_out: free_pool_memory(results); Dmsg0(200, "============ mount=0\n"); Dsm_check(200); return false; } free_pool_memory(results); Dmsg1(200, "============ mount=%d\n", mount); return true; } /* * Mount the device. * * If timeout, wait until the mount command returns 0. * If !timeout, try to mount the device only once. */ bool unix_file_device::mount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->mount_command) { retval = do_mount(dcr, true, timeout); } return retval; } /* * Unmount the device * * If timeout, wait until the unmount command returns 0. * If !timeout, try to unmount the device only once. */ bool unix_file_device::unmount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->unmount_command) { retval = do_mount(dcr, false, timeout); } return retval; } int unix_file_device::d_open(const char *pathname, int flags, int mode) { return ::open(pathname, flags, mode); } ssize_t unix_file_device::d_read(int fd, void *buffer, size_t count) { return ::read(fd, buffer, count); } ssize_t unix_file_device::d_write(int fd, const void *buffer, size_t count) { return ::write(fd, buffer, count); } int unix_file_device::d_close(int fd) { return ::close(fd); } int unix_file_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t unix_file_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { return ::lseek(m_fd, offset, whence); } bool unix_file_device::d_truncate(DCR *dcr) { struct stat st; if (ftruncate(m_fd, 0) != 0) { berrno be; Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), prt_name, be.bstrerror()); return false; } /* * Check for a successful ftruncate() and issue a work-around for devices * (mostly cheap NAS) that don't support truncation. * Workaround supplied by Martin Schmid as a solution to bug #1011. * 1. close file * 2. delete file * 3. open new file with same mode * 4. change ownership to original */ if (fstat(m_fd, &st) != 0) { berrno be; Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), prt_name, be.bstrerror()); return false; } if (st.st_size != 0) { /* ftruncate() didn't work */ POOL_MEM archive_name(PM_FNAME); pm_strcpy(archive_name, dev_name); if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) { pm_strcat(archive_name, "/"); } pm_strcat(archive_name, dcr->VolumeName); Mmsg2(errmsg, _("Device %s doesn't support ftruncate(). Recreating file %s.\n"), prt_name, archive_name.c_str()); /* * Close file and blow it away */ ::close(m_fd); ::unlink(archive_name.c_str()); /* * Recreate the file -- of course, empty */ oflags = O_CREAT | O_RDWR | O_BINARY; if ((m_fd = ::open(archive_name.c_str(), oflags, st.st_mode)) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), archive_name.c_str(), be.bstrerror()); Dmsg1(100, "reopen failed: %s", errmsg); Emsg0(M_FATAL, 0, errmsg); return false; } /* * Reset proper owner */ chown(archive_name.c_str(), st.st_uid, st.st_gid); } return true; } unix_file_device::~unix_file_device() { } unix_file_device::unix_file_device() { } bareos-Release-14.2.6/src/stored/backends/unix_file_device.h000066400000000000000000000030551263011562700237560ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UNIX File API device abstraction. * * Marco van Wieringen, June 2014 */ #ifndef UNIX_FILE_DEVICE_H #define UNIX_FILE_DEVICE_H class unix_file_device: public DEVICE { public: unix_file_device(); ~unix_file_device(); /* * Interface from DEVICE */ bool mount_backend(DCR *dcr, int timeout); bool unmount_backend(DCR *dcr, int timeout); int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); bool d_truncate(DCR *dcr); }; #endif /* UNIX_FILE_DEVICE_H */ bareos-Release-14.2.6/src/stored/backends/unix_tape_device.c000066400000000000000000000032271263011562700237640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UNIX Tape API device abstraction. * * Marco van Wieringen, December 2013 */ #include "bareos.h" #include "stored.h" #include "generic_tape_device.h" #include "unix_tape_device.h" int unix_tape_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return ::ioctl(fd, request, op); } unix_tape_device::~unix_tape_device() { } unix_tape_device::unix_tape_device() { } #ifdef HAVE_DYNAMIC_SD_BACKENDS extern "C" DEVICE SD_IMP_EXP *backend_instantiate(JCR *jcr, int device_type) { DEVICE *dev = NULL; switch (device_type) { case B_TAPE_DEV: dev = New(unix_tape_device); break; default: Jmsg(jcr, M_FATAL, 0, _("Request for unknown devicetype: %d\n"), device_type); break; } return dev; } extern "C" void SD_IMP_EXP flush_backend(void) { } #endif bareos-Release-14.2.6/src/stored/backends/unix_tape_device.h000066400000000000000000000022131263011562700237630ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * UNIX API device abstraction. * * Marco van Wieringen, December 2013 */ #ifndef UNIX_TAPE_DEVICE_H #define UNIX_TAPE_DEVICE_H class unix_tape_device: public generic_tape_device { public: unix_tape_device(); ~unix_tape_device(); int d_ioctl(int fd, ioctl_req_t request, char *op); }; #endif /* UNIX_TAPE_DEVICE_H */ bareos-Release-14.2.6/src/stored/bareos-sd.conf.in000077700000000000000000000000001263011562700320542../defaultconfigs/diskonly/bareos-sd.conf.inustar00rootroot00000000000000bareos-Release-14.2.6/src/stored/bcopy.c000066400000000000000000000260341263011562700200140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to copy a Bareos from one volume to another. * * Kern E. Sibbald, October 2002 */ #include "bareos.h" #include "stored.h" #include "lib/crypto_cache.h" /* Dummy functions */ extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec); static bool record_cb(DCR *dcr, DEV_RECORD *rec); /* Global variables */ static DEVICE *in_dev = NULL; static DEVICE *out_dev = NULL; static JCR *in_jcr; /* input jcr */ static JCR *out_jcr; /* output jcr */ static BSR *bsr = NULL; static const char *wd = "/tmp"; static bool list_records = false; static uint32_t records = 0; static uint32_t jobs = 0; static DEV_BLOCK *out_block; static SESSION_LABEL sessrec; #define CONFIG_FILE "bareos-sd.conf" static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bcopy [-d debug_level] \n" " -b bootstrap specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -i specify input Volume names (separated by |)\n" " -o specify output Volume names (separated by |)\n" " -p proceed inspite of errors\n" " -v verbose\n" " -w

specify working directory (default /tmp)\n" " -? print this message\n\n"), 2002, VERSION, BDATE); exit(1); } int main (int argc, char *argv[]) { int ch; bool ok; char *iVolumeName = NULL; char *oVolumeName = NULL; char *DirectorName = NULL; DIRRES *director = NULL; bool ignore_label_errors = false; DCR *in_dcr, *out_dcr; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "bcopy"); lmgr_init_thread(); init_msg(NULL, NULL); while ((ch = getopt(argc, argv, "b:c:D:d:i:o:pvw:?")) != -1) { switch (ch) { case 'b': bsr = parse_bsr(NULL, optarg); break; case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'D': /* specify director name */ if (DirectorName != NULL) { free(DirectorName); } DirectorName = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'i': /* input Volume name */ iVolumeName = optarg; break; case 'o': /* output Volume name */ oVolumeName = optarg; break; case 'p': ignore_label_errors = true; forge_on = true; break; case 'v': verbose++; break; case 'w': wd = optarg; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 2) { Pmsg0(0, _("Wrong number of arguments: \n")); usage(); } OSDependentInit(); working_directory = wd; if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (DirectorName) { foreach_res(director, R_DIRECTOR) { if (bstrcmp(director->hdr.name, DirectorName)) { break; } } if (!director) { Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"), DirectorName, configfile); } } load_sd_plugins(me->plugin_directory, me->plugin_names); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); /* * Setup and acquire input device for reading */ Dmsg0(100, "About to setup input jcr\n"); in_dcr = New(DCR); in_jcr = setup_jcr("bcopy", argv[0], bsr, director, in_dcr, iVolumeName, true); /* read device */ if (!in_jcr) { exit(1); } in_jcr->ignore_label_errors = ignore_label_errors; in_dev = in_jcr->dcr->dev; if (!in_dev) { exit(1); } /* * Setup output device for writing */ Dmsg0(100, "About to setup output jcr\n"); out_dcr = New(DCR); out_jcr = setup_jcr("bcopy", argv[1], bsr, director, out_dcr, oVolumeName, false); /* write device */ if (!out_jcr) { exit(1); } out_dev = out_jcr->dcr->dev; if (!out_dev) { exit(1); } Dmsg0(100, "About to acquire device for writing\n"); /* * For we must now acquire the device for writing */ out_dev->rLock(false); if (!out_dev->open(out_jcr->dcr, OPEN_READ_WRITE)) { Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), out_dev->errmsg); out_dev->Unlock(); exit(1); } out_dev->Unlock(); if (!acquire_device_for_append(out_jcr->dcr)) { free_jcr(in_jcr); exit(1); } out_block = out_jcr->dcr->block; ok = read_records(in_jcr->dcr, record_cb, mount_next_read_volume); if (ok || out_dev->can_write()) { if (!out_jcr->dcr->write_block_to_device()) { Pmsg0(000, _("Write of last block failed.\n")); } } Pmsg2(000, _("%u Jobs copied. %u records copied.\n"), jobs, records); in_dev->term(); out_dev->term(); free_jcr(in_jcr); free_jcr(out_jcr); return 0; } /* * read_records() calls back here for each record it gets */ static bool record_cb(DCR *in_dcr, DEV_RECORD *rec) { if (list_records) { Pmsg5(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n"), rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, rec->Stream, rec->data_len); } /* * Check for Start or End of Session Record * */ if (rec->FileIndex < 0) { get_session_record(in_dcr->dev, rec, &sessrec); if (verbose > 1) { dump_label_record(in_dcr->dev, rec, true); } switch (rec->FileIndex) { case PRE_LABEL: Pmsg0(000, _("Volume is prelabeled. This volume cannot be copied.\n")); return false; case VOL_LABEL: Pmsg0(000, _("Volume label not copied.\n")); return true; case SOS_LABEL: if (bsr && rec->match_stat < 1) { /* Skipping record, because does not match BSR filter */ if (verbose) { Pmsg0(-1, _("Copy skipped. Record does not match BSR filter.\n")); } } else { jobs++; } break; case EOS_LABEL: if (bsr && rec->match_stat < 1) { /* Skipping record, because does not match BSR filter */ return true; } while (!write_record_to_block(out_jcr->dcr, rec)) { Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len, rec->remainder); if (!out_jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n", out_dev->print_name(), out_dev->bstrerror()); Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"), out_dev->bstrerror()); return false; } } if (!out_jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n", out_dev->print_name(), out_dev->bstrerror()); Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"), out_dev->bstrerror()); return false; } return true; case EOM_LABEL: Pmsg0(000, _("EOM label not copied.\n")); return true; case EOT_LABEL: /* end of all tapes */ Pmsg0(000, _("EOT label not copied.\n")); return true; default: return true; } } /* Write record */ if (bsr && rec->match_stat < 1) { /* Skipping record, because does not match BSR filter */ return true; } records++; while (!write_record_to_block(out_jcr->dcr, rec)) { Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec->data_len, rec->remainder); if (!out_jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s: ERR=%s\n", out_dev->print_name(), out_dev->bstrerror()); Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"), out_dev->bstrerror()); return false; } } return true; } static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec) { const char *rtype; memset(sessrec, 0, sizeof(SESSION_LABEL)); switch (rec->FileIndex) { case PRE_LABEL: rtype = _("Fresh Volume Label"); break; case VOL_LABEL: rtype = _("Volume Label"); unser_volume_label(dev, rec); break; case SOS_LABEL: rtype = _("Begin Job Session"); unser_session_label(sessrec, rec); break; case EOS_LABEL: rtype = _("End Job Session"); unser_session_label(sessrec, rec); break; case 0: case EOM_LABEL: rtype = _("End of Medium"); break; default: rtype = _("Unknown"); break; } Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n", rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); if (verbose) { Pmsg5(-1, _("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n"), rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); } } bareos-Release-14.2.6/src/stored/bextract.c000066400000000000000000000507621263011562700205210ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dumb program to extract files from a Bareos backup. * * Kern E. Sibbald, MM */ #include "bareos.h" #include "stored.h" #include "lib/crypto_cache.h" #include "findlib/find.h" extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); static void do_extract(char *devname); static bool record_cb(DCR *dcr, DEV_RECORD *rec); static DEVICE *dev = NULL; static DCR *dcr; static BFILE bfd; static JCR *jcr; static FF_PKT *ff; static BSR *bsr = NULL; static bool extract = false; static int non_support_data = 0; static long total = 0; static ATTR *attr; static char *where; static uint32_t num_files = 0; static int prog_name_msg = 0; static int win32_data_msg = 0; static char *VolumeName = NULL; static char *DirectorName = NULL; static DIRRES *director = NULL; static struct acl_data_t acl_data; static struct xattr_data_t xattr_data; static alist *delayed_streams = NULL; static char *wbuf; /* write buffer address */ static uint32_t wsize; /* write size */ static uint64_t fileAddr = 0; /* file write address */ #define CONFIG_FILE "bareos-sd.conf" static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bextract \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -p proceed inspite of I/O errors\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n\n"), 2000, VERSION, BDATE); exit(1); } int main (int argc, char *argv[]) { int ch; FILE *fd; char line[1000]; bool got_inc = false; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); lmgr_init_thread(); working_directory = "/tmp"; my_name_is(argc, argv, "bextract"); init_msg(NULL, NULL); /* setup message handler */ OSDependentInit(); ff = init_find_files(); binit(&bfd); while ((ch = getopt(argc, argv, "b:c:D:d:e:i:pvV:?")) != -1) { switch (ch) { case 'b': /* bootstrap file */ bsr = parse_bsr(NULL, optarg); // dump_bsr(bsr, true); break; case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'D': /* specify director name */ if (DirectorName != NULL) { free(DirectorName); } DirectorName = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'e': /* exclude list */ if ((fd = fopen(optarg, "rb")) == NULL) { berrno be; Pmsg2(0, _("Could not open exclude file: %s, ERR=%s\n"), optarg, be.bstrerror()); exit(1); } while (fgets(line, sizeof(line), fd) != NULL) { strip_trailing_junk(line); Dmsg1(900, "add_exclude %s\n", line); add_fname_to_exclude_list(ff, line); } fclose(fd); break; case 'i': /* include list */ if ((fd = fopen(optarg, "rb")) == NULL) { berrno be; Pmsg2(0, _("Could not open include file: %s, ERR=%s\n"), optarg, be.bstrerror()); exit(1); } while (fgets(line, sizeof(line), fd) != NULL) { strip_trailing_junk(line); Dmsg1(900, "add_include %s\n", line); add_fname_to_include_list(ff, 0, line); } fclose(fd); got_inc = true; break; case 'p': forge_on = true; break; case 'v': verbose++; break; case 'V': /* Volume name */ VolumeName = optarg; break; case '?': default: usage(); } /* end switch */ } /* end while */ argc -= optind; argv += optind; if (argc != 2) { Pmsg0(0, _("Wrong number of arguments. Make sure the last two parameters are \n")); usage(); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (DirectorName) { foreach_res(director, R_DIRECTOR) { if (bstrcmp(director->hdr.name, DirectorName)) { break; } } if (!director) { Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"), DirectorName, configfile); } } load_sd_plugins(me->plugin_directory, me->plugin_names); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); if (!got_inc) { /* If no include file, */ add_fname_to_include_list(ff, 0, "/"); /* include everything */ } where = argv[1]; do_extract(argv[0]); if (bsr) { free_bsr(bsr); } if (prog_name_msg) { Pmsg1(000, _("%d Program Name and/or Program Data Stream records ignored.\n"), prog_name_msg); } if (win32_data_msg) { Pmsg1(000, _("%d Win32 data or Win32 gzip data stream records. Ignored.\n"), win32_data_msg); } term_include_exclude_files(ff); term_find_files(ff); return 0; } /* * Cleanup of delayed restore stack with streams for later processing. */ static inline void drop_delayed_data_streams() { DELAYED_DATA_STREAM *dds; if (!delayed_streams || delayed_streams->empty()) { return; } foreach_alist(dds, delayed_streams) { free(dds->content); } delayed_streams->destroy(); } /* * Push a data stream onto the delayed restore stack for later processing. */ static inline void push_delayed_data_stream(int stream, char *content, uint32_t content_length) { DELAYED_DATA_STREAM *dds; if (!delayed_streams) { delayed_streams = New(alist(10, owned_by_alist)); } dds = (DELAYED_DATA_STREAM *)malloc(sizeof(DELAYED_DATA_STREAM)); dds->stream = stream; dds->content = (char *)malloc(content_length); memcpy(dds->content, content, content_length); dds->content_length = content_length; delayed_streams->append(dds); } /* * Restore any data streams that are restored after the file * is fully restored and has its attributes restored. Things * like acls and xattr are restored after we set the file * attributes otherwise we might clear some security flags * by setting the attributes. */ static inline void pop_delayed_data_streams() { DELAYED_DATA_STREAM *dds; /* * See if there is anything todo. */ if (!delayed_streams || delayed_streams->empty()) { return; } /* * Only process known delayed data streams here. * If you start using more delayed data streams * be sure to add them in this loop and add the * proper calls here. * * Currently we support delayed data stream * processing for the following type of streams: * - *_ACL_* * - *_XATTR_* */ foreach_alist(dds, delayed_streams) { switch (dds->stream) { case STREAM_UNIX_ACCESS_ACL: case STREAM_UNIX_DEFAULT_ACL: case STREAM_ACL_AIX_TEXT: case STREAM_ACL_DARWIN_ACCESS_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_ACL_HPUX_ACL_ENTRY: case STREAM_ACL_IRIX_DEFAULT_ACL: case STREAM_ACL_IRIX_ACCESS_ACL: case STREAM_ACL_LINUX_DEFAULT_ACL: case STREAM_ACL_LINUX_ACCESS_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: case STREAM_ACL_AFS_TEXT: case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: case STREAM_ACL_HURD_DEFAULT_ACL: case STREAM_ACL_HURD_ACCESS_ACL: parse_acl_streams(jcr, &acl_data, dds->stream, dds->content, dds->content_length); free(dds->content); break; case STREAM_XATTR_HURD: case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: case STREAM_XATTR_SOLARIS_SYS: case STREAM_XATTR_DARWIN: case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: parse_xattr_streams(jcr, &xattr_data, dds->stream, dds->content, dds->content_length); free(dds->content); break; default: Jmsg(jcr, M_WARNING, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), dds->stream); break; } } /* * We processed the stack so we can destroy it. */ delayed_streams->destroy(); /* * (Re)Initialize the stack for a new use. */ delayed_streams->init(10, owned_by_alist); return; } static void close_previous_stream(void) { pop_delayed_data_streams(); set_attributes(jcr, attr, &bfd); } static void do_extract(char *devname) { struct stat statp; uint32_t decompress_buf_size; enable_backup_privileges(NULL, 1); dcr = New(DCR); jcr = setup_jcr("bextract", devname, bsr, director, dcr, VolumeName, true); /* read device */ if (!jcr) { exit(1); } dev = jcr->read_dcr->dev; if (!dev) { exit(1); } dcr = jcr->read_dcr; /* * Make sure where directory exists and that it is a directory */ if (stat(where, &statp) < 0) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot stat %s. It must exist. ERR=%s\n"), where, be.bstrerror()); } if (!S_ISDIR(statp.st_mode)) { Emsg1(M_ERROR_TERM, 0, _("%s must be a directory.\n"), where); } free(jcr->where); jcr->where = bstrdup(where); attr = new_attr(jcr); jcr->buf_size = DEFAULT_NETWORK_BUFFER_SIZE; setup_decompression_buffers(jcr, &decompress_buf_size); if (decompress_buf_size > 0) { memset(&jcr->compress, 0, sizeof(CMPRS_CTX)); jcr->compress.inflate_buffer = get_memory(decompress_buf_size); jcr->compress.inflate_buffer_size = decompress_buf_size; } acl_data.last_fname = get_pool_memory(PM_FNAME); xattr_data.last_fname = get_pool_memory(PM_FNAME); read_records(dcr, record_cb, mount_next_read_volume); /* * If output file is still open, it was the last one in the * archive since we just hit an end of file, so close the file. */ if (is_bopen(&bfd)) { close_previous_stream(); } free_attr(attr); free_pool_memory(acl_data.last_fname); free_pool_memory(xattr_data.last_fname); if (delayed_streams) { drop_delayed_data_streams(); delete delayed_streams; } cleanup_compression(jcr); clean_device(jcr->dcr); dev->term(); free_dcr(dcr); free_jcr(jcr); printf(_("%u files restored.\n"), num_files); return; } static bool store_data(BFILE *bfd, char *data, const int32_t length) { if (is_win32_stream(attr->data_stream) && !have_win32_api()) { set_portable_backup(bfd); if (!processWin32BackupAPIBlock(bfd, data, length)) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"), attr->ofname, be.bstrerror()); return false; } } else if (bwrite(bfd, data, length) != (ssize_t)length) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"), attr->ofname, be.bstrerror()); return false; } return true; } /* * Called here for each record from read_records() */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { int status; JCR *jcr = dcr->jcr; if (rec->FileIndex < 0) { return true; /* we don't want labels */ } /* File Attributes stream */ switch (rec->maskedStream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: /* If extracting, it was from previous stream, so * close the output file. */ if (extract) { if (!is_bopen(&bfd)) { Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n")); } close_previous_stream(); extract = false; } if (!unpack_attributes_record(jcr, rec->Stream, rec->data, rec->data_len, attr)) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) { attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI); if (!is_restore_stream_supported(attr->data_stream)) { if (!non_support_data++) { Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"), stream_to_ascii(attr->data_stream)); } extract = false; return true; } build_attr_output_fnames(jcr, attr); if (attr->type == FT_DELETED) { /* TODO: choose the right fname/ofname */ Jmsg(jcr, M_INFO, 0, _("%s was deleted.\n"), attr->fname); extract = false; return true; } extract = false; status = create_file(jcr, attr, &bfd, REPLACE_ALWAYS); switch (status) { case CF_ERROR: case CF_SKIP: break; case CF_EXTRACT: extract = true; print_ls_output(jcr, attr); num_files++; fileAddr = 0; break; case CF_CREATED: close_previous_stream(); print_ls_output(jcr, attr); num_files++; fileAddr = 0; break; } } break; case STREAM_RESTORE_OBJECT: /* nothing to do */ break; /* Data stream and extracting */ case STREAM_FILE_DATA: case STREAM_SPARSE_DATA: case STREAM_WIN32_DATA: if (extract) { if (rec->maskedStream == STREAM_SPARSE_DATA) { ser_declare; uint64_t faddr; wbuf = rec->data + OFFSET_FADDR_SIZE; wsize = rec->data_len - OFFSET_FADDR_SIZE; ser_begin(rec->data, OFFSET_FADDR_SIZE); unser_uint64(faddr); if (fileAddr != faddr) { fileAddr = faddr; if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"), attr->ofname, be.bstrerror()); } } } else { wbuf = rec->data; wsize = rec->data_len; } total += wsize; Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total); store_data(&bfd, wbuf, wsize); fileAddr += wsize; } break; /* GZIP data stream and Compressed data stream */ case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_COMPRESSED_DATA: case STREAM_SPARSE_COMPRESSED_DATA: case STREAM_WIN32_COMPRESSED_DATA: if (extract) { if (rec->maskedStream == STREAM_SPARSE_GZIP_DATA || rec->maskedStream == STREAM_SPARSE_COMPRESSED_DATA) { ser_declare; uint64_t faddr; char ec1[50]; wbuf = rec->data + OFFSET_FADDR_SIZE; wsize = rec->data_len - OFFSET_FADDR_SIZE; ser_begin(rec->data, OFFSET_FADDR_SIZE); unser_uint64(faddr); ser_end(rec->data, OFFSET_FADDR_SIZE); if (fileAddr != faddr) { fileAddr = faddr; if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) { berrno be; Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), edit_uint64(fileAddr, ec1), attr->ofname, be.bstrerror()); extract = false; return true; } } } else { wbuf = rec->data; wsize = rec->data_len; } if (decompress_data(jcr, attr->ofname, rec->maskedStream, &wbuf, &wsize, false)) { Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", wsize, total); store_data(&bfd, wbuf, wsize); total += wsize; fileAddr += wsize; Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len, wsize); } else { extract = false; return false; } } break; case STREAM_MD5_DIGEST: case STREAM_SHA1_DIGEST: case STREAM_SHA256_DIGEST: case STREAM_SHA512_DIGEST: break; case STREAM_SIGNED_DIGEST: case STREAM_ENCRYPTED_SESSION_DATA: // TODO landonf: Investigate crypto support in the storage daemon break; case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: if (!prog_name_msg) { Pmsg0(000, _("Got Program Name or Data Stream. Ignored.\n")); prog_name_msg++; } break; case STREAM_UNIX_ACCESS_ACL: /* Deprecated Standard ACL attributes on UNIX */ case STREAM_UNIX_DEFAULT_ACL: /* Deprecated Default ACL attributes on UNIX */ case STREAM_ACL_AIX_TEXT: case STREAM_ACL_DARWIN_ACCESS_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_ACL_HPUX_ACL_ENTRY: case STREAM_ACL_IRIX_DEFAULT_ACL: case STREAM_ACL_IRIX_ACCESS_ACL: case STREAM_ACL_LINUX_DEFAULT_ACL: case STREAM_ACL_LINUX_ACCESS_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: case STREAM_ACL_AFS_TEXT: case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: case STREAM_ACL_HURD_DEFAULT_ACL: case STREAM_ACL_HURD_ACCESS_ACL: if (extract) { pm_strcpy(acl_data.last_fname, attr->fname); push_delayed_data_stream(rec->maskedStream, rec->data, rec->data_len); } break; case STREAM_XATTR_HURD: case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: case STREAM_XATTR_SOLARIS_SYS: case STREAM_XATTR_SOLARIS: case STREAM_XATTR_DARWIN: case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: if (extract) { pm_strcpy(xattr_data.last_fname, attr->fname); push_delayed_data_stream(rec->maskedStream, rec->data, rec->data_len); } break; case STREAM_NDMP_SEPERATOR: break; default: /* * If extracting, weird stream (not 1 or 2), close output file anyway */ if (extract) { if (!is_bopen(&bfd)) { Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n")); } close_previous_stream(); extract = false; } Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), rec->Stream); break; } /* end switch */ return true; } bareos-Release-14.2.6/src/stored/block.c000066400000000000000000001127331263011562700177740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * block.c -- tape block handling functions * * Kern Sibbald, March MMI * added BB02 format October MMII */ #include "bareos.h" #include "stored.h" #ifdef DEBUG_BLOCK_CHECKSUM static const bool debug_block_checksum = true; #else static const bool debug_block_checksum = false; #endif #ifdef NO_TAPE_WRITE_TEST static const bool no_tape_write_test = true; #else static const bool no_tape_write_test = false; #endif static bool terminate_writing_volume(DCR *dcr); static bool do_new_file_bookkeeping(DCR *dcr); static void reread_last_block(DCR *dcr); bool forge_on = false; /* proceed inspite of I/O errors */ /* * Dump the block header, then walk through * the block printing out the record headers. */ void dump_block(DEV_BLOCK *b, const char *msg) { ser_declare; char *p; char Id[BLKHDR_ID_LENGTH+1]; uint32_t CheckSum, BlockCheckSum; uint32_t block_len; uint32_t BlockNumber; uint32_t VolSessionId, VolSessionTime, data_len; int32_t FileIndex; int32_t Stream; int bhl, rhl; char buf1[100], buf2[100]; unser_begin(b->buf, BLKHDR1_LENGTH); unser_uint32(CheckSum); unser_uint32(block_len); unser_uint32(BlockNumber); unser_bytes(Id, BLKHDR_ID_LENGTH); ASSERT(unser_length(b->buf) == BLKHDR1_LENGTH); Id[BLKHDR_ID_LENGTH] = 0; if (Id[3] == '2') { unser_uint32(VolSessionId); unser_uint32(VolSessionTime); bhl = BLKHDR2_LENGTH; rhl = RECHDR2_LENGTH; } else { VolSessionId = VolSessionTime = 0; bhl = BLKHDR1_LENGTH; rhl = RECHDR1_LENGTH; } if (block_len > 4000000) { Dmsg3(20, "Dump block %s 0x%x blocksize too big %u\n", msg, b, block_len); return; } BlockCheckSum = bcrc32((uint8_t *)b->buf+BLKHDR_CS_LENGTH, block_len-BLKHDR_CS_LENGTH); Pmsg6(000, _("Dump block %s %x: size=%d BlkNum=%d\n" " Hdrcksum=%x cksum=%x\n"), msg, b, block_len, BlockNumber, CheckSum, BlockCheckSum); p = b->buf + bhl; while (p < (b->buf + block_len+WRITE_RECHDR_LENGTH)) { unser_begin(p, WRITE_RECHDR_LENGTH); if (rhl == RECHDR1_LENGTH) { unser_uint32(VolSessionId); unser_uint32(VolSessionTime); } unser_int32(FileIndex); unser_int32(Stream); unser_uint32(data_len); Pmsg6(000, _(" Rec: VId=%u VT=%u FI=%s Strm=%s len=%d p=%x\n"), VolSessionId, VolSessionTime, FI_to_ascii(buf1, FileIndex), stream_to_ascii(buf2, Stream, FileIndex), data_len, p); p += data_len + rhl; } } /* * Create a new block structure. * We pass device so that the block can inherit the * min and max block sizes. */ DEV_BLOCK *new_block(DEVICE *dev) { DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK)); memset(block, 0, sizeof(DEV_BLOCK)); if (dev->max_block_size == 0) { block->buf_len = dev->device->label_block_size; Dmsg1(100, "created new block of blocksize %d (dev->device->label_block_size) as dev->max_block_size is zero\n", block->buf_len); } else { block->buf_len = dev->max_block_size; Dmsg1(100, "created new block of blocksize %d (dev->max_block_size)\n", block->buf_len); } block->dev = dev; block->block_len = block->buf_len; /* default block size */ block->buf = get_memory(block->buf_len); empty_block(block); block->BlockVer = BLOCK_VER; /* default write version */ Dmsg1(650, "Returning new block=%x\n", block); return block; } /* * Duplicate an existing block (eblock) */ DEV_BLOCK *dup_block(DEV_BLOCK *eblock) { DEV_BLOCK *block = (DEV_BLOCK *)get_memory(sizeof(DEV_BLOCK)); int buf_len = sizeof_pool_memory(eblock->buf); memcpy(block, eblock, sizeof(DEV_BLOCK)); block->buf = get_memory(buf_len); memcpy(block->buf, eblock->buf, buf_len); return block; } /* * Only the first block checksum error was reported. * If there are more, report it now. */ void print_block_read_errors(JCR *jcr, DEV_BLOCK *block) { if (block->read_errors > 1) { Jmsg(jcr, M_ERROR, 0, _("%d block read errors not printed.\n"), block->read_errors); } } /* * Free block */ void free_block(DEV_BLOCK *block) { if (block) { Dmsg1(999, "free_block buffer %x\n", block->buf); free_memory(block->buf); Dmsg1(999, "free_block block %x\n", block); free_memory((POOLMEM *)block); } } /* * Empty the block -- for writing */ void empty_block(DEV_BLOCK *block) { block->binbuf = WRITE_BLKHDR_LENGTH; block->bufp = block->buf + block->binbuf; block->read_len = 0; block->write_failed = false; block->block_read = false; block->FirstIndex = block->LastIndex = 0; } /* * Create block header just before write. The space * in the buffer should have already been reserved by * init_block. */ static uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum) { ser_declare; uint32_t CheckSum = 0; uint32_t block_len = block->binbuf; Dmsg1(1390, "ser_block_header: block_len=%d\n", block_len); ser_begin(block->buf, BLKHDR2_LENGTH); ser_uint32(CheckSum); ser_uint32(block_len); ser_uint32(block->BlockNumber); ser_bytes(WRITE_BLKHDR_ID, BLKHDR_ID_LENGTH); if (BLOCK_VER >= 2) { ser_uint32(block->VolSessionId); ser_uint32(block->VolSessionTime); } /* * Checksum whole block except for the checksum */ if (do_checksum) { CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH, block_len-BLKHDR_CS_LENGTH); } Dmsg1(1390, "ser_bloc_header: checksum=%x\n", CheckSum); ser_begin(block->buf, BLKHDR2_LENGTH); ser_uint32(CheckSum); /* now add checksum to block header */ return CheckSum; } /* * Unserialize the block header for reading block. * This includes setting all the buffer pointers correctly. * * Returns: false on failure (not a block) * true on success */ static inline bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { ser_declare; char Id[BLKHDR_ID_LENGTH+1]; uint32_t CheckSum, BlockCheckSum; uint32_t block_len; uint32_t block_end; uint32_t BlockNumber; int bhl; unser_begin(block->buf, BLKHDR_LENGTH); unser_uint32(CheckSum); unser_uint32(block_len); unser_uint32(BlockNumber); unser_bytes(Id, BLKHDR_ID_LENGTH); ASSERT(unser_length(block->buf) == BLKHDR1_LENGTH); Id[BLKHDR_ID_LENGTH] = 0; if (Id[3] == '1') { bhl = BLKHDR1_LENGTH; block->BlockVer = 1; block->bufp = block->buf + bhl; if (!bstrncmp(Id, BLKHDR1_ID, BLKHDR_ID_LENGTH)) { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"), dev->file, dev->block_num, BLKHDR1_ID, Id); if (block->read_errors == 0 || verbose >= 2) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } block->read_errors++; return false; } } else if (Id[3] == '2') { unser_uint32(block->VolSessionId); unser_uint32(block->VolSessionTime); bhl = BLKHDR2_LENGTH; block->BlockVer = 2; block->bufp = block->buf + bhl; if (!bstrncmp(Id, BLKHDR2_ID, BLKHDR_ID_LENGTH)) { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"), dev->file, dev->block_num, BLKHDR2_ID, Id); if (block->read_errors == 0 || verbose >= 2) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } block->read_errors++; return false; } } else { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"), dev->file, dev->block_num, BLKHDR2_ID, Id); Dmsg1(50, "%s", dev->errmsg); if (block->read_errors == 0 || verbose >= 2) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } block->read_errors++; unser_uint32(block->VolSessionId); unser_uint32(block->VolSessionTime); return false; } /* * Sanity check */ if (block_len > MAX_BLOCK_LENGTH) { dev->dev_errno = EIO; Mmsg3(dev->errmsg, _("Volume data error at %u:%u! Block length %u is insane (too large), probably due to a bad archive.\n"), dev->file, dev->block_num, block_len); if (block->read_errors == 0 || verbose >= 2) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } block->read_errors++; return false; } Dmsg1(390, "unser_block_header block_len=%d\n", block_len); /* * Find end of block or end of buffer whichever is smaller */ if (block_len > block->read_len) { block_end = block->read_len; } else { block_end = block_len; } block->binbuf = block_end - bhl; block->block_len = block_len; block->BlockNumber = BlockNumber; Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf, bhl, block_len); if (block_len <= block->read_len && dev->do_checksum()) { BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH, block_len-BLKHDR_CS_LENGTH); if (BlockCheckSum != CheckSum) { dev->dev_errno = EIO; Mmsg6(dev->errmsg, _("Volume data error at %u:%u!\n" "Block checksum mismatch in block=%u len=%d: calc=%x blk=%x\n"), dev->file, dev->block_num, (unsigned)BlockNumber, block_len, BlockCheckSum, CheckSum); if (block->read_errors == 0 || verbose >= 2) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dump_block(block, "with checksum error"); } block->read_errors++; if (!forge_on) { return false; } } } return true; } /* * Write a block to the device, with locking and unlocking * * Returns: true on success * : false on failure * */ bool DCR::write_block_to_device() { bool status = true; DCR *dcr = this; if (dcr->spooling) { status = write_block_to_spool_file(dcr); return status; } if (!dcr->is_dev_locked()) { /* device already locked? */ /* * Note, do not change this to dcr->r_dlock */ dev->rLock(); /* no, lock it */ } /* * If a new volume has been mounted since our last write * Create a JobMedia record for the previous volume written, * and set new parameters to write this volume * * The same applies for if we are in a new file. */ if (dcr->NewVol || dcr->NewFile) { if (job_canceled(jcr)) { status = false; Dmsg0(100, "Canceled\n"); goto bail_out; } /* Create a jobmedia record for this job */ if (!dcr->dir_create_jobmedia_record(false)) { dev->dev_errno = EIO; Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->getVolCatName(), jcr->Job); set_new_volume_parameters(dcr); status = false; Dmsg0(100, "cannot create media record\n"); goto bail_out; } if (dcr->NewVol) { /* * Note, setting a new volume also handles any pending new file */ set_new_volume_parameters(dcr); } else { set_new_file_parameters(dcr); } } if (!dcr->write_block_to_dev()) { if (job_canceled(jcr) || jcr->is_JobType(JT_SYSTEM)) { status = false; } else { status = fixup_device_block_write_error(dcr); } } bail_out: if (!dcr->is_dev_locked()) { /* did we lock dev above? */ /* * Note, do not change this to dcr->dunlock */ dev->Unlock(); /* unlock it now */ } return status; } /* * Write a block to the device * * Returns: true on success or EOT * false on hard error */ bool DCR::write_block_to_dev() { ssize_t status = 0; uint32_t wlen; /* length to write */ int hit_max1, hit_max2; bool ok = true; DCR *dcr = this; uint32_t checksum; if (no_tape_write_test) { empty_block(block); return true; } if (job_canceled(jcr)) { return false; } ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf))); wlen = block->binbuf; if (wlen <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */ Dmsg0(100, "return write_block_to_dev no data to write\n"); return true; } /* dump_block(block, "before write"); */ if (dev->at_weot()) { Dmsg0(100, "return write_block_to_dev with ST_WEOT\n"); dev->dev_errno = ENOSPC; Jmsg1(jcr, M_FATAL, 0, _("Cannot write block. Device at EOM. dev=%s\n"), dev->print_name()); Dmsg1(100, "Attempt to write on read-only Volume. dev=%s\n", dev->print_name()); return false; } if (!dev->can_append()) { dev->dev_errno = EIO; Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on read-only Volume. dev=%s\n"), dev->print_name()); Dmsg1(100, "Attempt to write on read-only Volume. dev=%s\n", dev->print_name()); return false; } if (!dev->is_open()) { Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on closed device=%s\n"), dev->print_name()); Dmsg1(100, "Attempt to write on closed device=%s\n", dev->print_name()); return false; } /* * Clear to the end of the buffer if it is not full, * and on tape devices, apply min and fixed blocking. */ if (wlen != block->buf_len) { uint32_t blen; /* current buffer length */ Dmsg2(250, "binbuf=%d buf_len=%d\n", block->binbuf, block->buf_len); blen = wlen; /* * Adjust write size to min/max for tapes only */ if (dev->is_tape()) { /* * Check for fixed block size */ if (dev->min_block_size == dev->max_block_size) { wlen = block->buf_len; /* fixed block size already rounded */ /* * Check for min block size */ } else if (wlen < dev->min_block_size) { wlen = ((dev->min_block_size + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE; /* * Ensure size is rounded */ } else { wlen = ((wlen + TAPE_BSIZE - 1) / TAPE_BSIZE) * TAPE_BSIZE; } } Dmsg4(400, "writing block of size %d to dev=%s with max_block_size %d and min_block_size %d\n", wlen, dev->print_name(), dev->max_block_size, dev->min_block_size); if (wlen-blen > 0) { memset(block->bufp, 0, wlen-blen); /* clear garbage */ } } Dmsg4(400, "writing block of size %d to dev=%s with max_block_size %d and min_block_size %d\n", wlen, dev->print_name(), dev->max_block_size, dev->min_block_size); checksum = ser_block_header(block, dev->do_checksum()); /* * Limit maximum Volume size to value specified by user */ hit_max1 = (dev->max_volume_size > 0) && ((dev->VolCatInfo.VolCatBytes + block->binbuf)) >= dev->max_volume_size; hit_max2 = (dev->VolCatInfo.VolCatMaxBytes > 0) && ((dev->VolCatInfo.VolCatBytes + block->binbuf)) >= dev->VolCatInfo.VolCatMaxBytes; if (hit_max1 || hit_max2) { char ed1[50]; uint64_t max_cap; Dmsg0(100, "==== Output bytes Triggered medium max capacity.\n"); if (hit_max1) { max_cap = dev->max_volume_size; } else { max_cap = dev->VolCatInfo.VolCatMaxBytes; } Jmsg(jcr, M_INFO, 0, _("User defined maximum volume capacity %s exceeded on device %s.\n"), edit_uint64_with_commas(max_cap, ed1), dev->print_name()); terminate_writing_volume(dcr); reread_last_block(dcr); /* DEBUG */ dev->dev_errno = ENOSPC; return false; } /* * Limit maximum File size on volume to user specified value */ if ((dev->max_file_size > 0) && (dev->file_size+block->binbuf) >= dev->max_file_size) { dev->file_size = 0; /* reset file size */ if (!dev->weof(1)) { /* write eof */ Dmsg0(50, "WEOF error in max file size.\n"); Jmsg(jcr, M_FATAL, 0, _("Unable to write EOF. ERR=%s\n"), dev->bstrerror()); terminate_writing_volume(dcr); dev->dev_errno = ENOSPC; return false; } if (!write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName)) { return false; } if (!do_new_file_bookkeeping(dcr)) { /* * Error message already sent */ return false; } } dev->VolCatInfo.VolCatWrites++; Dmsg1(1300, "Write block of %u bytes\n", wlen); #ifdef DEBUG_BLOCK_ZEROING uint32_t *bp = (uint32_t *)block->buf; if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) { Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n")); } #endif /* * Do write here, make a somewhat feeble attempt to recover from * I/O errors, or from the OS telling us it is busy. */ int retry = 0; errno = 0; status = 0; do { if (retry > 0 && status == -1 && errno == EBUSY) { berrno be; Dmsg4(100, "===== write retry=%d status=%d errno=%d: ERR=%s\n", retry, status, errno, be.bstrerror()); bmicrosleep(5, 0); /* pause a bit if busy or lots of errors */ dev->clrerror(-1); } status = dev->write(block->buf, (size_t)wlen); } while (status == -1 && (errno == EBUSY || errno == EIO) && retry++ < 3); if (debug_block_checksum) { uint32_t achecksum = ser_block_header(block, dev->do_checksum()); if (checksum != achecksum) { Jmsg2(jcr, M_ERROR, 0, _("Block checksum changed during write: before=%ud after=%ud\n"), checksum, achecksum); dump_block(block, "with checksum error"); } } #ifdef DEBUG_BLOCK_ZEROING if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) { Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n")); } #endif if (status != (ssize_t)wlen) { /* * Some devices simply report EIO when the volume is full. * With a little more thought we may be able to check * capacity and distinguish real errors and EOT * conditions. In any case, we probably want to * simulate an End of Medium. */ if (status == -1) { berrno be; dev->clrerror(-1); if (dev->dev_errno == 0) { dev->dev_errno = ENOSPC; /* out of space */ } if (dev->dev_errno != ENOSPC) { dev->VolCatInfo.VolCatErrors++; Jmsg4(jcr, M_ERROR, 0, _("Write error at %u:%u on device %s. ERR=%s.\n"), dev->file, dev->block_num, dev->print_name(), be.bstrerror()); } } else { dev->dev_errno = ENOSPC; /* out of space */ } if (dev->dev_errno == ENOSPC) { Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"), dev->getVolCatName(), dev->file, dev->block_num, dev->print_name(), wlen, status); } else { berrno be; be.set_errno(dev->dev_errno); Mmsg5(dev->errmsg, _("Write error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n"), dev->fd(), dev->file, dev->block_num, dev->print_name(), be.bstrerror()); } generate_plugin_event(jcr, bsdEventWriteError, dcr); if (dev->dev_errno != ENOSPC) { Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } if (debug_level >= 100) { berrno be; be.set_errno(dev->dev_errno); Dmsg7(100, "=== Write error. fd=%d size=%u rtn=%d dev_blk=%d blk_blk=%d errno=%d: ERR=%s\n", dev->fd(), wlen, status, dev->block_num, block->BlockNumber, dev->dev_errno, be.bstrerror(dev->dev_errno)); } ok = terminate_writing_volume(dcr); if (!ok && !forge_on) { return false; } if (ok) { reread_last_block(dcr); } return false; } /* * We successfully wrote the block, now do housekeeping */ Dmsg2(1300, "VolCatBytes=%d newVolCatBytes=%d\n", (int)dev->VolCatInfo.VolCatBytes, (int)(dev->VolCatInfo.VolCatBytes+wlen)); dev->VolCatInfo.VolCatBytes += wlen; dev->VolCatInfo.VolCatBlocks++; dev->EndBlock = dev->block_num; dev->EndFile = dev->file; dev->LastBlock = block->BlockNumber; block->BlockNumber++; /* * Update dcr values */ if (dev->is_tape()) { dcr->EndBlock = dev->EndBlock; dcr->EndFile = dev->EndFile; dev->block_num++; } else { /* * Save address of block just written */ uint64_t addr = dev->file_addr + wlen - 1; dcr->EndBlock = (uint32_t)addr; dcr->EndFile = (uint32_t)(addr >> 32); dev->block_num = dcr->EndBlock; dev->file = dcr->EndFile; } dcr->VolMediaId = dev->VolCatInfo.VolMediaId; if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) { dcr->VolFirstIndex = block->FirstIndex; } if (block->LastIndex > 0) { dcr->VolLastIndex = block->LastIndex; } dcr->WroteVol = true; dev->file_addr += wlen; /* update file address */ dev->file_size += wlen; Dmsg2(1300, "write_block: wrote block %d bytes=%d\n", dev->block_num, wlen); empty_block(block); return true; } static void reread_last_block(DCR *dcr) { #define CHECK_LAST_BLOCK #ifdef CHECK_LAST_BLOCK bool ok = true; DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; DEV_BLOCK *block = dcr->block; /* * If the device is a tape and it supports backspace record, * we backspace over one or two eof marks depending on * how many we just wrote, then over the last record, * then re-read it and verify that the block number is * correct. */ if (dev->is_tape() && dev->has_cap(CAP_BSR)) { /* * Now back up over what we wrote and read the last block */ if (!dev->bsf(1)) { berrno be; ok = false; Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"), be.bstrerror(dev->dev_errno)); } if (ok && dev->has_cap(CAP_TWOEOF) && !dev->bsf(1)) { berrno be; ok = false; Jmsg(jcr, M_ERROR, 0, _("Backspace file at EOT failed. ERR=%s\n"), be.bstrerror(dev->dev_errno)); } /* * Backspace over record */ if (ok && !dev->bsr(1)) { berrno be; ok = false; Jmsg(jcr, M_ERROR, 0, _("Backspace record at EOT failed. ERR=%s\n"), be.bstrerror(dev->dev_errno)); /* * On FreeBSD systems, if the user got here, it is likely that his/her * tape drive is "frozen". The correct thing to do is a * rewind(), but if we do that, higher levels in cleaning up, will * most likely write the EOS record over the beginning of the * tape. The rewind *is* done later in mount.c when another * tape is requested. Note, the clrerror() call in bsr() * calls ioctl(MTCERRSTAT), which *should* fix the problem. */ } if (ok) { DEV_BLOCK *lblock = new_block(dev); /* * Note, this can destroy dev->errmsg */ dcr->block = lblock; if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { Jmsg(jcr, M_ERROR, 0, _("Re-read last block at EOT failed. ERR=%s"), dev->errmsg); } else { /* * If we wrote block and the block numbers don't agree * we have a possible problem. */ if (lblock->BlockNumber != dev->LastBlock) { if (dev->LastBlock > (lblock->BlockNumber + 1)) { Jmsg(jcr, M_FATAL, 0, _( "Re-read of last block: block numbers differ by more than one.\n" "Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"), lblock->BlockNumber, dev->LastBlock); } else { Jmsg(jcr, M_ERROR, 0, _( "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"), lblock->BlockNumber, dev->LastBlock); } } else { Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n")); } } free_block(lblock); dcr->block = block; } } #endif } /* * If this routine is called, we do our bookkeeping and * then assure that the volume will not be written any more. */ static bool terminate_writing_volume(DCR *dcr) { DEVICE *dev = dcr->dev; bool ok = true; /* Create a JobMedia record to indicated end of tape */ dev->VolCatInfo.VolCatFiles = dev->file; if (!dcr->dir_create_jobmedia_record(false)) { Dmsg0(50, "Error from create JobMedia\n"); dev->dev_errno = EIO; Mmsg2(dev->errmsg, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->getVolCatName(), dcr->jcr->Job); Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg); ok = false; } dcr->block->write_failed = true; if (!dev->weof(1)) { /* end the tape */ dev->VolCatInfo.VolCatErrors++; Jmsg(dcr->jcr, M_ERROR, 0, _("Error writing final EOF to tape. This Volume may not be readable.\n" "%s"), dev->errmsg); ok = false; Dmsg0(50, "Error writing final EOF to volume.\n"); } if (ok) { ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName); } bstrncpy(dev->VolCatInfo.VolCatStatus, "Full", sizeof(dev->VolCatInfo.VolCatStatus)); dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */ if (!dcr->dir_update_volume_info(false, true)) { Mmsg(dev->errmsg, _("Error sending Volume info to Director.\n")); ok = false; Dmsg0(50, "Error updating volume info.\n"); } Dmsg1(50, "dir_update_volume_info terminate writing -- %s\n", ok?"OK":"ERROR"); /* * Walk through all attached dcrs setting flag to call * set_new_file_parameters() when that dcr is next used. */ DCR *mdcr; foreach_dlist(mdcr, dev->attached_dcrs) { if (mdcr->jcr->JobId == 0) { continue; } mdcr->NewFile = true; /* set reminder to do set_new_file_params */ } /* * Set new file/block parameters for current dcr */ set_new_file_parameters(dcr); if (ok && dev->has_cap(CAP_TWOEOF) && !dev->weof(1)) { /* end the tape */ dev->VolCatInfo.VolCatErrors++; /* * This may not be fatal since we already wrote an EOF */ Jmsg(dcr->jcr, M_ERROR, 0, "%s", dev->errmsg); Dmsg0(50, "Writing second EOF failed.\n"); } dev->set_ateot(); /* no more writing this tape */ Dmsg1(50, "*** Leave terminate_writing_volume -- %s\n", ok?"OK":"ERROR"); return ok; } /* * Do bookkeeping when a new file is created on a Volume. This is * also done for disk files to generate the jobmedia records for * quick seeking. */ static bool do_new_file_bookkeeping(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; /* * Create a JobMedia record so restore can seek */ if (!dcr->dir_create_jobmedia_record(false)) { Dmsg0(50, "Error from create_job_media.\n"); dev->dev_errno = EIO; Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->getVolCatName(), jcr->Job); terminate_writing_volume(dcr); dev->dev_errno = EIO; return false; } dev->VolCatInfo.VolCatFiles = dev->file; if (!dcr->dir_update_volume_info(false, false)) { Dmsg0(50, "Error from update_vol_info.\n"); terminate_writing_volume(dcr); dev->dev_errno = EIO; return false; } Dmsg0(100, "dir_update_volume_info max file size -- OK\n"); /* * Walk through all attached dcrs setting flag to call * set_new_file_parameters() when that dcr is next used. */ DCR *mdcr; foreach_dlist(mdcr, dev->attached_dcrs) { if (mdcr->jcr->JobId == 0) { continue; } mdcr->NewFile = true; /* set reminder to do set_new_file_params */ } /* * Set new file/block parameters for current dcr */ set_new_file_parameters(dcr); return true; } /* * Read block with locking */ bool DCR::read_block_from_device(bool check_block_numbers) { bool ok; Dmsg0(250, "Enter read_block_from_device\n"); dev->rLock(); ok = read_block_from_dev(check_block_numbers); dev->Unlock(); Dmsg0(250, "Leave read_block_from_device\n"); return ok; } /* * Read the next block into the block structure and unserialize * the block header. For a file, the block may be partially * or completely in the current buffer. */ bool DCR::read_block_from_dev(bool check_block_numbers) { ssize_t status; int looping; int retry; DCR *dcr = this; if (job_canceled(jcr)) { Mmsg(dev->errmsg, _("Job failed or canceled.\n")); block->read_len = 0; return false; } if (dev->at_eot()) { Mmsg(dev->errmsg, _("Attempt to read past end of tape or file.\n")); block->read_len = 0; return false; } looping = 0; Dmsg1(250, "Full read in read_block_from_device() len=%d\n", block->buf_len); if (!dev->is_open()) { Mmsg4(dev->errmsg, _("Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n"), dev->fd(), dev->file, dev->block_num, dev->print_name()); Jmsg(dcr->jcr, M_WARNING, 0, "%s", dev->errmsg); block->read_len = 0; return false; } reread: if (looping > 1) { dev->dev_errno = EIO; Mmsg1(dev->errmsg, _("Block buffer size looping problem on device %s\n"), dev->print_name()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); block->read_len = 0; return false; } retry = 0; errno = 0; status = 0; do { if ((retry > 0 && status == -1 && errno == EBUSY)) { berrno be; Dmsg4(100, "===== read retry=%d status=%d errno=%d: ERR=%s\n", retry, status, errno, be.bstrerror()); bmicrosleep(10, 0); /* pause a bit if busy or lots of errors */ dev->clrerror(-1); } status = dev->read(block->buf, (size_t)block->buf_len); } while (status == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3); if (status < 0) { berrno be; dev->clrerror(-1); Dmsg1(250, "Read device got: ERR=%s\n", be.bstrerror()); block->read_len = 0; Mmsg5(dev->errmsg, _("Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n"), dev->fd(), dev->file, dev->block_num, dev->print_name(), be.bstrerror()); generate_plugin_event(jcr, bsdEventReadError, dcr); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); if (dev->at_eof()) { /* EOF just seen? */ dev->set_eot(); /* yes, error => EOT */ } return false; } Dmsg3(250, "Read device got %d bytes at %u:%u\n", status, dev->file, dev->block_num); if (status == 0) { /* Got EOF ! */ dev->block_num = 0; block->read_len = 0; Mmsg3(dev->errmsg, _("Read zero bytes at %u:%u on device %s.\n"), dev->file, dev->block_num, dev->print_name()); if (dev->at_eof()) { /* EOF already read? */ dev->set_eot(); /* yes, 2 EOFs => EOT */ return 0; } dev->set_ateof(); return false; /* return eof */ } /* * Continue here for successful read */ block->read_len = status; /* save length read */ if (block->read_len == 80 && (dcr->VolCatInfo.LabelType != B_BAREOS_LABEL || dcr->device->label_type != B_BAREOS_LABEL)) { /* ***FIXME*** should check label */ Dmsg2(100, "Ignore 80 byte ANSI label at %u:%u\n", dev->file, dev->block_num); dev->clear_eof(); goto reread; /* skip ANSI/IBM label */ } if (block->read_len < BLKHDR2_LENGTH) { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Very short block of %d bytes on device %s discarded.\n"), dev->file, dev->block_num, block->read_len, dev->print_name()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dev->set_short_block(); block->read_len = block->binbuf = 0; Dmsg2(200, "set block=%p binbuf=%d\n", block, block->binbuf); return false; /* return error */ } // BlockNumber = block->BlockNumber + 1; if (!unser_block_header(jcr, dev, block)) { if (forge_on) { dev->file_addr += block->read_len; dev->file_size += block->read_len; goto reread; } return false; } /* * If the block is bigger than the buffer, we reposition for * re-reading the block, allocate a buffer of the correct size, * and go re-read. */ if (block->block_len > block->buf_len) { dev->dev_errno = EIO; Mmsg2(dev->errmsg, _("Block length %u is greater than buffer %u. Attempting recovery.\n"), block->block_len, block->buf_len); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); Pmsg1(000, "%s", dev->errmsg); /* * Attempt to reposition to re-read the block */ if (dev->is_tape()) { Dmsg0(250, "BSR for reread; block too big for buffer.\n"); if (!dev->bsr(1)) { Mmsg(dev->errmsg, "%s", dev->bstrerror()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); block->read_len = 0; return false; } } else { Dmsg0(250, "Seek to beginning of block for reread.\n"); boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */ pos -= block->read_len; dev->lseek(dcr, pos, SEEK_SET); dev->file_addr = pos; } Mmsg1(dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len); Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); Pmsg1(000, "%s", dev->errmsg); /* * Set new block length */ dev->max_block_size = block->block_len; block->buf_len = block->block_len; free_memory(block->buf); block->buf = get_memory(block->buf_len); empty_block(block); looping++; goto reread; /* re-read block with correct block size */ } if (block->block_len > block->read_len) { dev->dev_errno = EIO; Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n"), dev->file, dev->block_num, block->read_len, dev->print_name()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); dev->set_short_block(); block->read_len = block->binbuf = 0; return false; /* return error */ } dev->clear_short_block(); dev->clear_eof(); dev->VolCatInfo.VolCatReads++; dev->VolCatInfo.VolCatRBytes += block->read_len; dev->EndBlock = dev->block_num; dev->EndFile = dev->file; dev->block_num++; /* * Update dcr values */ if (dev->is_tape()) { dcr->EndBlock = dev->EndBlock; dcr->EndFile = dev->EndFile; } else { /* * We need to take care about a short block in EndBlock/File computation */ uint32_t len = MIN(block->read_len, block->block_len); uint64_t addr = dev->file_addr + len - 1; dcr->EndBlock = (uint32_t)addr; dcr->EndFile = (uint32_t)(addr >> 32); dev->block_num = dev->EndBlock = dcr->EndBlock; dev->file = dev->EndFile = dcr->EndFile; } dcr->VolMediaId = dev->VolCatInfo.VolMediaId; dev->file_addr += block->read_len; dev->file_size += block->read_len; /* * If we read a short block on disk, * seek to beginning of next block. This saves us * from shuffling blocks around in the buffer. Take a * look at this from an efficiency stand point later, but * it should only happen once at the end of each job. * * I've been lseek()ing negative relative to SEEK_CUR for 30 * years now. However, it seems that with the new off_t definition, * it is not possible to seek negative amounts, so we use two * lseek(). One to get the position, then the second to do an * absolute positioning -- so much for efficiency. KES Sep 02. */ Dmsg0(250, "At end of read block\n"); if (block->read_len > block->block_len && !dev->is_tape()) { char ed1[50]; boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */ Dmsg1(250, "Current lseek pos=%s\n", edit_int64(pos, ed1)); pos -= (block->read_len - block->block_len); dev->lseek(dcr, pos, SEEK_SET); Dmsg3(250, "Did lseek pos=%s blk_size=%d rdlen=%d\n", edit_int64(pos, ed1), block->block_len, block->read_len); dev->file_addr = pos; dev->file_size = pos; } Dmsg2(250, "Exit read_block read_len=%d block_len=%d\n", block->read_len, block->block_len); block->block_read = true; return true; } bareos-Release-14.2.6/src/stored/block.h000066400000000000000000000104521263011562700177740ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Block definitions for Bareos media data format. * * Kern Sibbald, MM */ #ifndef __BLOCK_H #define __BLOCK_H 1 #define MAX_BLOCK_LENGTH 20000000 /* this is a sort of sanity check */ #define DEFAULT_BLOCK_SIZE (512 * 126) /* 64,512 N.B. do not use 65,536 here the POSIX standard defaults the size of a tape record to 126 blocks (63k). */ /* Block Header definitions. */ #define BLKHDR1_ID "BB01" #define BLKHDR2_ID "BB02" #define BLKHDR_ID_LENGTH 4 #define BLKHDR_CS_LENGTH 4 /* checksum length */ #define BLKHDR1_LENGTH 16 /* Total length */ #define BLKHDR2_LENGTH 24 /* Total length */ #define WRITE_BLKHDR_ID BLKHDR2_ID #define WRITE_BLKHDR_LENGTH BLKHDR2_LENGTH #define BLOCK_VER 2 /* Record header definitions */ #define RECHDR1_LENGTH 20 #define RECHDR2_LENGTH 12 #define WRITE_RECHDR_LENGTH RECHDR2_LENGTH /* Tape label and version definitions */ #define BareosId "Bareos 2.0 immortal\n" #define OldBaculaId "Bacula 1.0 immortal\n" #define OlderBaculaId "Bacula 0.9 mortal\n" #define BareosTapeVersion 20 #define OldCompatibleBareosTapeVersion1 11 #define OldCompatibleBareosTapeVersion2 10 #define OldCompatibleBareosTapeVersion3 9 /* * This is the Media structure for a block header * Note, when written, it is serialized. uint32_t CheckSum; uint32_t block_len; uint32_t BlockNumber; char Id[BLKHDR_ID_LENGTH]; * for BB02 block, we also have uint32_t VolSessionId; uint32_t VolSessionTime; */ class DEVICE; /* for forward reference */ /* * DEV_BLOCK for reading and writing blocks. * This is the basic unit that is written to the device, and * it contains a Block Header followd by Records. Note, * at times (when reading a file), this block may contain * multiple blocks. * * This is the memory structure for a device block. */ struct DEV_BLOCK { DEV_BLOCK *next; /* pointer to next one */ DEVICE *dev; /* pointer to device */ /* binbuf is the number of bytes remaining in the buffer. * For writes, it is bytes not yet written. * For reads, it is remaining bytes not yet read. */ uint32_t binbuf; /* bytes in buffer */ uint32_t block_len; /* length of current block read */ uint32_t buf_len; /* max/default block length */ uint32_t BlockNumber; /* sequential Bareos block number */ uint32_t read_len; /* bytes read into buffer, if zero, block empty */ uint32_t VolSessionId; /* */ uint32_t VolSessionTime; /* */ uint32_t read_errors; /* block errors (checksum, header, ...) */ int BlockVer; /* block version 1 or 2 */ bool write_failed; /* set if write failed */ bool block_read; /* set when block read */ int32_t FirstIndex; /* first index this block */ int32_t LastIndex; /* last index this block */ char *bufp; /* pointer into buffer */ POOLMEM *buf; /* actual data buffer */ }; #define block_is_empty(block) ((block)->read_len == 0) #endif bareos-Release-14.2.6/src/stored/bls.c000066400000000000000000000334431263011562700174620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dumb program to do an "ls" of a Bareos 2.0 mortal file. * * Kern Sibbald, MM */ #include "bareos.h" #include "stored.h" #include "lib/crypto_cache.h" #include "findlib/find.h" /* Dummy functions */ extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); static void do_blocks(char *infname); static void do_jobs(char *infname); static void do_ls(char *fname); static void do_close(JCR *jcr); static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec); static bool record_cb(DCR *dcr, DEV_RECORD *rec); static DEVICE *dev; static DCR *dcr; static bool dump_label = false; static bool list_blocks = false; static bool list_jobs = false; static DEV_RECORD *rec; static JCR *jcr; static SESSION_LABEL sessrec; static uint32_t num_files = 0; static ATTR *attr; #define CONFIG_FILE "bareos-sd.conf" static FF_PKT *ff; static BSR *bsr = NULL; static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bls [options] \n" " -b specify a bootstrap file\n" " -c specify a Storage configuration file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e exclude list\n" " -i include list\n" " -j list jobs\n" " -k list blocks\n" " (no j or k option) list saved files\n" " -L dump label\n" " -p proceed inspite of errors\n" " -v be verbose\n" " -V specify Volume names (separated by |)\n" " -? print this message\n\n"), 2000, VERSION, BDATE); exit(1); } int main (int argc, char *argv[]) { int i, ch; FILE *fd; char line[1000]; char *VolumeName = NULL; char *bsrName = NULL; char *DirectorName = NULL; bool ignore_label_errors = false; DIRRES *director = NULL; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); lmgr_init_thread(); working_directory = "/tmp"; my_name_is(argc, argv, "bls"); init_msg(NULL, NULL); /* initialize message handler */ OSDependentInit(); ff = init_find_files(); while ((ch = getopt(argc, argv, "b:c:D:d:e:i:jkLpvV:?")) != -1) { switch (ch) { case 'b': bsrName = optarg; break; case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'D': /* specify director name */ if (DirectorName != NULL) { free(DirectorName); } DirectorName = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'e': /* exclude list */ if ((fd = fopen(optarg, "rb")) == NULL) { berrno be; Pmsg2(0, _("Could not open exclude file: %s, ERR=%s\n"), optarg, be.bstrerror()); exit(1); } while (fgets(line, sizeof(line), fd) != NULL) { strip_trailing_junk(line); Dmsg1(100, "add_exclude %s\n", line); add_fname_to_exclude_list(ff, line); } fclose(fd); break; case 'i': /* include list */ if ((fd = fopen(optarg, "rb")) == NULL) { berrno be; Pmsg2(0, _("Could not open include file: %s, ERR=%s\n"), optarg, be.bstrerror()); exit(1); } while (fgets(line, sizeof(line), fd) != NULL) { strip_trailing_junk(line); Dmsg1(100, "add_include %s\n", line); add_fname_to_include_list(ff, 0, line); } fclose(fd); break; case 'j': list_jobs = true; break; case 'k': list_blocks = true; break; case 'L': dump_label = true; break; case 'p': ignore_label_errors = true; forge_on = true; break; case 'v': verbose++; break; case 'V': /* Volume name */ VolumeName = optarg; break; case '?': default: usage(); } /* end switch */ } /* end while */ argc -= optind; argv += optind; if (!argc) { Pmsg0(0, _("No archive name specified\n")); usage(); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (DirectorName) { foreach_res(director, R_DIRECTOR) { if (bstrcmp(director->hdr.name, DirectorName)) { break; } } if (!director) { Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"), DirectorName, configfile); } } load_sd_plugins(me->plugin_directory, me->plugin_names); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); if (ff->included_files_list == NULL) { add_fname_to_include_list(ff, 0, "/"); } for (i=0; i < argc; i++) { if (bsrName) { bsr = parse_bsr(NULL, bsrName); } dcr = New(DCR); jcr = setup_jcr("bls", argv[i], bsr, director, dcr, VolumeName, true); /* read device */ if (!jcr) { exit(1); } jcr->ignore_label_errors = ignore_label_errors; dev = jcr->dcr->dev; if (!dev) { exit(1); } dcr = jcr->dcr; rec = new_record(); attr = new_attr(jcr); /* * Assume that we have already read the volume label. * If on second or subsequent volume, adjust buffer pointer */ if (dev->VolHdr.PrevVolumeName[0] != 0) { /* second volume */ Pmsg1(0, _("\n" "Warning, this Volume is a continuation of Volume %s\n"), dev->VolHdr.PrevVolumeName); } if (list_blocks) { do_blocks(argv[i]); } else if (list_jobs) { do_jobs(argv[i]); } else { do_ls(argv[i]); } do_close(jcr); } if (bsr) { free_bsr(bsr); } term_include_exclude_files(ff); term_find_files(ff); return 0; } static void do_close(JCR *jcr) { free_attr(attr); free_record(rec); clean_device(jcr->dcr); dev->term(); free_dcr(jcr->dcr); free_jcr(jcr); } /* List just block information */ static void do_blocks(char *infname) { DEV_BLOCK *block = dcr->block; char buf1[100], buf2[100]; for ( ;; ) { if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror()); if (dev->at_eot()) { if (!mount_next_read_volume(dcr)) { Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"), dev->file, dev->print_name(), dcr->VolumeName); break; } /* Read and discard Volume label */ DEV_RECORD *record; record = new_record(); dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK); read_record_from_block(dcr, record); get_session_record(dev, record, &sessrec); free_record(record); Jmsg(jcr, M_INFO, 0, _("Mounted Volume \"%s\".\n"), dcr->VolumeName); } else if (dev->at_eof()) { Jmsg(jcr, M_INFO, 0, _("End of file %u on device %s, Volume \"%s\"\n"), dev->file, dev->print_name(), dcr->VolumeName); Dmsg0(20, "read_record got eof. try again\n"); continue; } else if (dev->is_short_block()) { Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); continue; } else { /* I/O error */ display_tape_error_status(jcr, dev); break; } } if (!match_bsr_block(bsr, block)) { Dmsg5(100, "reject Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n", block->BlockNumber, block->block_len, block->BlockVer, block->VolSessionId, block->VolSessionTime); continue; } Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n", block->BlockNumber, block->block_len, block->BlockVer, block->VolSessionId, block->VolSessionTime); if (verbose == 1) { read_record_from_block(dcr, rec); Pmsg9(-1, _("File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"), dev->file, dev->block_num, block->BlockNumber, block->block_len, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); rec->remainder = 0; } else if (verbose > 1) { dump_block(block, ""); } else { printf(_("Block: %d size=%d\n"), block->BlockNumber, block->block_len); } } return; } /* * We are only looking for labels or in particular Job Session records */ static bool jobs_cb(DCR *dcr, DEV_RECORD *rec) { if (rec->FileIndex < 0) { dump_label_record(dcr->dev, rec, verbose); } rec->remainder = 0; return true; } /* Do list job records */ static void do_jobs(char *infname) { read_records(dcr, jobs_cb, mount_next_read_volume); } /* Do an ls type listing of an archive */ static void do_ls(char *infname) { if (dump_label) { dump_volume_label(dev); return; } read_records(dcr, record_cb, mount_next_read_volume); printf("%u files found.\n", num_files); } /* * Called here for each record from read_records() */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { if (rec->FileIndex < 0) { get_session_record(dev, rec, &sessrec); return true; } /* * File Attributes stream */ switch (rec->maskedStream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: if (!unpack_attributes_record(jcr, rec->Stream, rec->data, rec->data_len, attr)) { if (!forge_on) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } else { Emsg0(M_ERROR, 0, _("Attrib unpack error!\n")); } num_files++; return true; } attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI); build_attr_output_fnames(jcr, attr); if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) { if (verbose) { Pmsg5(-1, _("FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n"), rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); } print_ls_output(jcr, attr); num_files++; } break; case STREAM_PLUGIN_NAME: { char data[100]; int len = MIN(rec->data_len+1, sizeof(data)); bstrncpy(data, rec->data, len); Pmsg1(000, "Plugin data: %s\n", data); break; } case STREAM_RESTORE_OBJECT: Pmsg0(000, "Restore Object record\n"); break; default: break; } return true; } static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec) { const char *rtype; memset(sessrec, 0, sizeof(SESSION_LABEL)); jcr->JobId = 0; switch (rec->FileIndex) { case PRE_LABEL: rtype = _("Fresh Volume Label"); break; case VOL_LABEL: rtype = _("Volume Label"); unser_volume_label(dev, rec); break; case SOS_LABEL: rtype = _("Begin Job Session"); unser_session_label(sessrec, rec); jcr->JobId = sessrec->JobId; break; case EOS_LABEL: rtype = _("End Job Session"); break; case 0: case EOM_LABEL: rtype = _("End of Medium"); break; case EOT_LABEL: rtype = _("End of Physical Medium"); break; case SOB_LABEL: rtype = _("Start of object"); break; case EOB_LABEL: rtype = _("End of object"); break; default: rtype = _("Unknown"); Dmsg1(10, "FI rtype=%d unknown\n", rec->FileIndex); break; } Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n", rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); if (verbose) { Pmsg5(-1, _("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n"), rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); } } bareos-Release-14.2.6/src/stored/bscan.c000066400000000000000000001243061263011562700177670ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to scan a Bareos Volume and compare it with * the catalog and optionally synchronize the catalog * with the tape. * * Kern E. Sibbald, December 2001 */ #include "bareos.h" #include "stored.h" #include "lib/crypto_cache.h" #include "findlib/find.h" #include "cats/cats.h" #include "cats/sql_glue.h" /* Dummy functions */ extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ static void do_scan(void); static bool record_cb(DCR *dcr, DEV_RECORD *rec); static int create_file_attributes_record(B_DB *db, JCR *mjcr, char *fname, char *lname, int type, char *ap, DEV_RECORD *rec); static int create_media_record(B_DB *db, MEDIA_DBR *mr, VOLUME_LABEL *vl); static bool update_media_record(B_DB *db, MEDIA_DBR *mr); static int create_pool_record(B_DB *db, POOL_DBR *pr); static JCR *create_job_record(B_DB *db, JOB_DBR *mr, SESSION_LABEL *label, DEV_RECORD *rec); static int update_job_record(B_DB *db, JOB_DBR *mr, SESSION_LABEL *elabel, DEV_RECORD *rec); static int create_client_record(B_DB *db, CLIENT_DBR *cr); static int create_fileset_record(B_DB *db, FILESET_DBR *fsr); static int create_jobmedia_record(B_DB *db, JCR *jcr); static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId); static int update_digest_record(B_DB *db, char *digest, DEV_RECORD *rec, int type); /* Local variables */ static DEVICE *dev = NULL; static B_DB *db; static JCR *bjcr; /* jcr for bscan */ static BSR *bsr = NULL; static MEDIA_DBR mr; static POOL_DBR pr; static JOB_DBR jr; static CLIENT_DBR cr; static FILESET_DBR fsr; static ATTR_DBR ar; static FILE_DBR fr; static SESSION_LABEL label; static SESSION_LABEL elabel; static ATTR *attr; static time_t lasttime = 0; static const char *backend_directory = _PATH_BAREOS_BACKENDDIR; static const char *db_driver = "NULL"; static const char *db_name = "bareos"; static const char *db_user = "bareos"; static const char *db_password = ""; static const char *db_host = NULL; static int db_port = 0; static const char *wd = NULL; static bool update_db = false; static bool update_vol_info = false; static bool list_records = false; static int ignored_msgs = 0; static uint64_t currentVolumeSize; static int last_pct = -1; static bool showProgress = false; static int num_jobs = 0; static int num_pools = 0; static int num_media = 0; static int num_files = 0; #define CONFIG_FILE "bareos-sd.conf" static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bscan [ options ] \n" " -B specify the database driver name (default NULL) \n" " -b specify a bootstrap file\n" " -c specify storage daemon configuration file (default: %s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" " -D specify a director name specified in the storage daemon\n" " configuration file for the Key Encryption Key selection\n" " -a specify the database backend directory (default %s)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" " -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" " -S show scan progress periodically\n" " -v verbose\n" " -V specify Volume names (separated by |)\n" " -w specify working directory (default from configuration file)\n" " -? print this message\n\n"), 2001, VERSION, BDATE, CONFIG_FILE, backend_directory); exit(1); } int main (int argc, char *argv[]) { int ch; struct stat stat_buf; char *VolumeName = NULL; char *DirectorName = NULL; DIRRES *director = NULL; DCR *dcr; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) alist *backend_directories = NULL; #endif setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); lmgr_init_thread(); my_name_is(argc, argv, "bscan"); init_msg(NULL, NULL); OSDependentInit(); while ((ch = getopt(argc, argv, "a:B:b:c:d:D:h:p:mn:pP:rsSt:u:vV:w:?")) != -1) { switch (ch) { case 'a': backend_directory = optarg; break; case 'B': db_driver = optarg; break; case 'b': bsr = parse_bsr(NULL, optarg); break; case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'D': /* specify director name */ if (DirectorName != NULL) { free(DirectorName); } DirectorName = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'h': db_host = optarg; break; case 't': db_port = atoi(optarg); break; case 'm': update_vol_info = true; break; case 'n': db_name = optarg; break; case 'u': db_user = optarg; break; case 'P': db_password = optarg; break; case 'p': forge_on = true; break; case 'r': list_records = true; break; case 'S' : showProgress = true; break; case 's': update_db = true; break; case 'V': /* Volume name */ VolumeName = optarg; break; case 'v': verbose++; break; case 'w': wd = optarg; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 1) { Pmsg0(0, _("Wrong number of arguments: \n")); usage(); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (DirectorName) { foreach_res(director, R_DIRECTOR) { if (bstrcmp(director->hdr.name, DirectorName)) { break; } } if (!director) { Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"), DirectorName, configfile); } } load_sd_plugins(me->plugin_directory, me->plugin_names); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); /* Check if -w option given, otherwise use resource for working directory */ if (wd) { working_directory = wd; } else if (!me->working_directory) { Emsg1(M_ERROR_TERM, 0, _("No Working Directory defined in %s. Cannot continue.\n"), configfile); } else { working_directory = me->working_directory; } /* Check that working directory is good */ if (stat(working_directory, &stat_buf) != 0) { Emsg1(M_ERROR_TERM, 0, _("Working Directory: %s not found. Cannot continue.\n"), working_directory); } if (!S_ISDIR(stat_buf.st_mode)) { Emsg1(M_ERROR_TERM, 0, _("Working Directory: %s is not a directory. Cannot continue.\n"), working_directory); } dcr = New(DCR); bjcr = setup_jcr("bscan", argv[0], bsr, director, dcr, VolumeName, true); if (!bjcr) { exit(1); } dev = bjcr->read_dcr->dev; if (showProgress) { char ed1[50]; struct stat sb; fstat(dev->fd(), &sb); currentVolumeSize = sb.st_size; Pmsg1(000, _("First Volume Size = %s\n"), edit_uint64(currentVolumeSize, ed1)); } #if defined(HAVE_DYNAMIC_CATS_BACKENDS) backend_directories = New(alist(10, owned_by_alist)); backend_directories->append((char *)backend_directory); db_set_backend_dirs(backend_directories); #endif if ((db = db_init_database(NULL, db_driver, db_name, db_user, db_password, db_host, db_port, NULL)) == NULL) { Emsg0(M_ERROR_TERM, 0, _("Could not init Bareos database\n")); } if (!db_open_database(NULL, db)) { Emsg0(M_ERROR_TERM, 0, db_strerror(db)); } Dmsg0(200, "Database opened\n"); if (verbose) { Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user); } do_scan(); if (update_db) { printf("Records added or updated in the catalog:\n%7d Media\n%7d Pool\n%7d Job\n%7d File\n", num_media, num_pools, num_jobs, num_files); } else { printf("Records would have been added or updated in the catalog:\n%7d Media\n%7d Pool\n%7d Job\n%7d File\n", num_media, num_pools, num_jobs, num_files); } db_flush_backends(); clean_device(bjcr->dcr); dev->term(); free_dcr(bjcr->dcr); free_jcr(bjcr); return 0; } /* * We are at the end of reading a tape. Now, we simulate handling * the end of writing a tape by wiffling through the attached * jcrs creating jobmedia records. */ static bool bscan_mount_next_read_volume(DCR *dcr) { bool status; DEVICE *dev = dcr->dev; DCR *mdcr; Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->getVolCatName()); foreach_dlist(mdcr, dev->attached_dcrs) { JCR *mjcr = mdcr->jcr; Dmsg1(000, "========== JobId=%u ========\n", mjcr->JobId); if (mjcr->JobId == 0) { continue; } if (verbose) { Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job); } mdcr->StartBlock = dcr->StartBlock; mdcr->StartFile = dcr->StartFile; mdcr->EndBlock = dcr->EndBlock; mdcr->EndFile = dcr->EndFile; mdcr->VolMediaId = dcr->VolMediaId; mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex; if( mjcr->insert_jobmedia_records ) { if (!create_jobmedia_record(db, mjcr)) { Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"), dev->getVolCatName(), mjcr->Job); } } } update_media_record(db, &mr); /* Now let common read routine get up next tape. Note, * we call mount_next... with bscan's jcr because that is where we * have the Volume list, but we get attached. */ status = mount_next_read_volume(dcr); if (showProgress) { char ed1[50]; struct stat sb; fstat(dev->fd(), &sb); currentVolumeSize = sb.st_size; Pmsg1(000, _("First Volume Size = %s\n"), edit_uint64(currentVolumeSize, ed1)); } return status; } static void do_scan() { attr = new_attr(bjcr); memset(&ar, 0, sizeof(ar)); memset(&pr, 0, sizeof(pr)); memset(&jr, 0, sizeof(jr)); memset(&cr, 0, sizeof(cr)); memset(&fsr, 0, sizeof(fsr)); memset(&fr, 0, sizeof(fr)); /* Detach bscan's jcr as we are not a real Job on the tape */ read_records(bjcr->read_dcr, record_cb, bscan_mount_next_read_volume); if (update_db) { db_write_batch_file_records(bjcr); /* used by bulk batch file insert */ } free_attr(attr); } /* * Returns: true if OK * false if error */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { JCR *mjcr; char ec1[30]; DEVICE *dev = dcr->dev; JCR *bjcr = dcr->jcr; DEV_BLOCK *block = dcr->block; POOL_MEM sql_buffer; db_int64_ctx jmr_count; char digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; if (rec->data_len > 0) { mr.VolBytes += rec->data_len + WRITE_RECHDR_LENGTH; /* Accumulate Volume bytes */ if (showProgress && currentVolumeSize > 0) { int pct = (mr.VolBytes * 100) / currentVolumeSize; if (pct != last_pct) { fprintf(stdout, _("done: %d%%\n"), pct); fflush(stdout); last_pct = pct; } } } if (list_records) { Pmsg5(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n"), rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, rec->Stream, rec->data_len); } /* * Check for Start or End of Session Record * */ if (rec->FileIndex < 0) { bool save_update_db = update_db; if (verbose > 1) { dump_label_record(dev, rec, true); } switch (rec->FileIndex) { case PRE_LABEL: Pmsg0(000, _("Volume is prelabeled. This tape cannot be scanned.\n")); return false; break; case VOL_LABEL: unser_volume_label(dev, rec); /* Check Pool info */ bstrncpy(pr.Name, dev->VolHdr.PoolName, sizeof(pr.Name)); bstrncpy(pr.PoolType, dev->VolHdr.PoolType, sizeof(pr.PoolType)); num_pools++; if (db_get_pool_record(bjcr, db, &pr)) { if (verbose) { Pmsg1(000, _("Pool record for %s found in DB.\n"), pr.Name); } } else { if (!update_db) { Pmsg1(000, _("VOL_LABEL: Pool record not found for Pool: %s\n"), pr.Name); } create_pool_record(db, &pr); } if (!bstrcmp(pr.PoolType, dev->VolHdr.PoolType)) { Pmsg2(000, _("VOL_LABEL: PoolType mismatch. DB=%s Vol=%s\n"), pr.PoolType, dev->VolHdr.PoolType); return true; } else if (verbose) { Pmsg1(000, _("Pool type \"%s\" is OK.\n"), pr.PoolType); } /* Check Media Info */ memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, dev->VolHdr.VolumeName, sizeof(mr.VolumeName)); mr.PoolId = pr.PoolId; num_media++; if (db_get_media_record(bjcr, db, &mr)) { if (verbose) { Pmsg1(000, _("Media record for %s found in DB.\n"), mr.VolumeName); } /* Clear out some volume statistics that will be updated */ mr.VolJobs = mr.VolFiles = mr.VolBlocks = 0; mr.VolBytes = rec->data_len + 20; } else { if (!update_db) { Pmsg1(000, _("VOL_LABEL: Media record not found for Volume: %s\n"), mr.VolumeName); } bstrncpy(mr.MediaType, dev->VolHdr.MediaType, sizeof(mr.MediaType)); create_media_record(db, &mr, &dev->VolHdr); } if (!bstrcmp(mr.MediaType, dev->VolHdr.MediaType)) { Pmsg2(000, _("VOL_LABEL: MediaType mismatch. DB=%s Vol=%s\n"), mr.MediaType, dev->VolHdr.MediaType); return true; /* ignore error */ } else if (verbose) { Pmsg1(000, _("Media type \"%s\" is OK.\n"), mr.MediaType); } /* Reset some DCR variables */ foreach_dlist(dcr, dev->attached_dcrs) { dcr->VolFirstIndex = dcr->FileIndex = 0; dcr->StartBlock = dcr->EndBlock = 0; dcr->StartFile = dcr->EndFile = 0; dcr->VolMediaId = 0; } Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName); break; case SOS_LABEL: mr.VolJobs++; num_jobs++; if (ignored_msgs > 0) { Pmsg1(000, _("%d \"errors\" ignored before first Start of Session record.\n"), ignored_msgs); ignored_msgs = 0; } unser_session_label(&label, rec); memset(&jr, 0, sizeof(jr)); bstrncpy(jr.Job, label.Job, sizeof(jr.Job)); if (db_get_job_record(bjcr, db, &jr)) { /* Job record already exists in DB */ update_db = false; /* don't change db in create_job_record */ if (verbose) { Pmsg1(000, _("SOS_LABEL: Found Job record for JobId: %d\n"), jr.JobId); } } else { /* Must create a Job record in DB */ if (!update_db) { Pmsg1(000, _("SOS_LABEL: Job record not found for JobId: %d\n"), jr.JobId); } } /* Create Client record if not already there */ bstrncpy(cr.Name, label.ClientName, sizeof(cr.Name)); create_client_record(db, &cr); jr.ClientId = cr.ClientId; /* process label, if Job record exists don't update db */ mjcr = create_job_record(db, &jr, &label, rec); dcr = mjcr->read_dcr; update_db = save_update_db; jr.PoolId = pr.PoolId; mjcr->start_time = jr.StartTime; mjcr->setJobLevel(jr.JobLevel); mjcr->client_name = get_pool_memory(PM_FNAME); pm_strcpy(mjcr->client_name, label.ClientName); mjcr->fileset_name = get_pool_memory(PM_FNAME); pm_strcpy(mjcr->fileset_name, label.FileSetName); bstrncpy(dcr->pool_type, label.PoolType, sizeof(dcr->pool_type)); bstrncpy(dcr->pool_name, label.PoolName, sizeof(dcr->pool_name)); /* Look for existing Job Media records for this job. If there are any, no new ones need be created. This may occur if File Retention has expired before Job Retention, or if the volume has already been bscan'd */ Mmsg(sql_buffer, "SELECT count(*) from JobMedia where JobId=%d", jr.JobId); db_sql_query(db, sql_buffer.c_str(), db_int64_handler, &jmr_count); if( jmr_count.value > 0 ) { //FIELD NAME TO BE DEFINED/CONFIRMED (maybe a struct?) mjcr->insert_jobmedia_records = false; } else { mjcr->insert_jobmedia_records = true; } if (rec->VolSessionId != jr.VolSessionId) { Pmsg3(000, _("SOS_LABEL: VolSessId mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.VolSessionId, rec->VolSessionId); return true; /* ignore error */ } if (rec->VolSessionTime != jr.VolSessionTime) { Pmsg3(000, _("SOS_LABEL: VolSessTime mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.VolSessionTime, rec->VolSessionTime); return true; /* ignore error */ } if (jr.PoolId != pr.PoolId) { Pmsg3(000, _("SOS_LABEL: PoolId mismatch for JobId=%u. DB=%d Vol=%d\n"), jr.JobId, jr.PoolId, pr.PoolId); return true; /* ignore error */ } break; case EOS_LABEL: unser_session_label(&elabel, rec); /* Create FileSet record */ bstrncpy(fsr.FileSet, label.FileSetName, sizeof(fsr.FileSet)); bstrncpy(fsr.MD5, label.FileSetMD5, sizeof(fsr.MD5)); create_fileset_record(db, &fsr); jr.FileSetId = fsr.FileSetId; mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { Pmsg2(000, _("Could not find SessId=%d SessTime=%d for EOS record.\n"), rec->VolSessionId, rec->VolSessionTime); break; } /* Do the final update to the Job record */ update_job_record(db, &jr, &elabel, rec); mjcr->end_time = jr.EndTime; mjcr->setJobStatus(JS_Terminated); /* Create JobMedia record */ mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex; if( mjcr->insert_jobmedia_records ) { create_jobmedia_record(db, mjcr); } free_dcr(mjcr->read_dcr); free_jcr(mjcr); break; case EOM_LABEL: break; case EOT_LABEL: /* end of all tapes */ /* * Wiffle through all jobs still open and close * them. */ if (update_db) { DCR *mdcr; foreach_dlist(mdcr, dev->attached_dcrs) { JCR *mjcr = mdcr->jcr; if (!mjcr || mjcr->JobId == 0) { continue; } jr.JobId = mjcr->JobId; /* Mark Job as Error Terimined */ jr.JobStatus = JS_ErrorTerminated; jr.JobFiles = mjcr->JobFiles; jr.JobBytes = mjcr->JobBytes; jr.VolSessionId = mjcr->VolSessionId; jr.VolSessionTime = mjcr->VolSessionTime; jr.JobTDate = (utime_t)mjcr->start_time; jr.ClientId = mjcr->ClientId; if (!db_update_job_end_record(bjcr, db, &jr)) { Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db)); } mjcr->read_dcr = NULL; free_jcr(mjcr); } } mr.VolFiles = rec->File; mr.VolBlocks = rec->Block; mr.VolBytes += mr.VolBlocks * WRITE_BLKHDR_LENGTH; /* approx. */ mr.VolMounts++; update_media_record(db, &mr); Pmsg3(0, _("End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles, mr.VolBlocks, edit_uint64_with_commas(mr.VolBytes, ec1)); break; default: break; } /* end switch */ return true; } mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { if (mr.VolJobs > 0) { Pmsg2(000, _("Could not find Job for SessId=%d SessTime=%d record.\n"), rec->VolSessionId, rec->VolSessionTime); } else { ignored_msgs++; } return true; } dcr = mjcr->read_dcr; if (dcr->VolFirstIndex == 0) { dcr->VolFirstIndex = block->FirstIndex; } /* File Attributes stream */ switch (rec->maskedStream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: if (!unpack_attributes_record(bjcr, rec->Stream, rec->data, rec->data_len, attr)) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } if (verbose > 1) { decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI); build_attr_output_fnames(bjcr, attr); print_ls_output(bjcr, attr); } fr.JobId = mjcr->JobId; fr.FileId = 0; num_files++; if (verbose && (num_files & 0x7FFF) == 0) { char ed1[30], ed2[30], ed3[30], ed4[30]; Pmsg4(000, _("%s file records. At file:blk=%s:%s bytes=%s\n"), edit_uint64_with_commas(num_files, ed1), edit_uint64_with_commas(rec->File, ed2), edit_uint64_with_commas(rec->Block, ed3), edit_uint64_with_commas(mr.VolBytes, ed4)); } create_file_attributes_record(db, mjcr, attr->fname, attr->lname, attr->type, attr->attr, rec); free_jcr(mjcr); break; case STREAM_RESTORE_OBJECT: /* ****FIXME*****/ /* Implement putting into catalog */ break; /* Data stream */ case STREAM_WIN32_DATA: case STREAM_FILE_DATA: case STREAM_SPARSE_DATA: case STREAM_MACOS_FORK_DATA: case STREAM_ENCRYPTED_FILE_DATA: case STREAM_ENCRYPTED_WIN32_DATA: case STREAM_ENCRYPTED_MACOS_FORK_DATA: /* * For encrypted stream, this is an approximation. * The data must be decrypted to know the correct length. */ mjcr->JobBytes += rec->data_len; if (rec->maskedStream == STREAM_SPARSE_DATA) { mjcr->JobBytes -= sizeof(uint64_t); } free_jcr(mjcr); /* done using JCR */ break; case STREAM_GZIP_DATA: case STREAM_COMPRESSED_DATA: case STREAM_ENCRYPTED_FILE_GZIP_DATA: case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: case STREAM_ENCRYPTED_WIN32_GZIP_DATA: case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: /* No correct, we should (decrypt and) expand it done using JCR */ mjcr->JobBytes += rec->data_len; free_jcr(mjcr); break; case STREAM_SPARSE_GZIP_DATA: case STREAM_SPARSE_COMPRESSED_DATA: mjcr->JobBytes += rec->data_len - sizeof(uint64_t); /* No correct, we should expand it */ free_jcr(mjcr); /* done using JCR */ break; /* Win32 GZIP stream */ case STREAM_WIN32_GZIP_DATA: case STREAM_WIN32_COMPRESSED_DATA: mjcr->JobBytes += rec->data_len; free_jcr(mjcr); /* done using JCR */ break; case STREAM_MD5_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_MD5_SIZE, true); if (verbose > 1) { Pmsg1(000, _("Got MD5 record: %s\n"), digest); } update_digest_record(db, digest, rec, CRYPTO_DIGEST_MD5); break; case STREAM_SHA1_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA1_SIZE, true); if (verbose > 1) { Pmsg1(000, _("Got SHA1 record: %s\n"), digest); } update_digest_record(db, digest, rec, CRYPTO_DIGEST_SHA1); break; case STREAM_SHA256_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA256_SIZE, true); if (verbose > 1) { Pmsg1(000, _("Got SHA256 record: %s\n"), digest); } update_digest_record(db, digest, rec, CRYPTO_DIGEST_SHA256); break; case STREAM_SHA512_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA512_SIZE, true); if (verbose > 1) { Pmsg1(000, _("Got SHA512 record: %s\n"), digest); } update_digest_record(db, digest, rec, CRYPTO_DIGEST_SHA512); break; case STREAM_ENCRYPTED_SESSION_DATA: // TODO landonf: Investigate crypto support in bscan if (verbose > 1) { Pmsg0(000, _("Got signed digest record\n")); } break; case STREAM_SIGNED_DIGEST: // TODO landonf: Investigate crypto support in bscan if (verbose > 1) { Pmsg0(000, _("Got signed digest record\n")); } break; case STREAM_PROGRAM_NAMES: if (verbose) { Pmsg1(000, _("Got Prog Names Stream: %s\n"), rec->data); } break; case STREAM_PROGRAM_DATA: if (verbose > 1) { Pmsg0(000, _("Got Prog Data Stream record.\n")); } break; case STREAM_HFSPLUS_ATTRIBUTES: /* Ignore OSX attributes */ break; case STREAM_PLUGIN_NAME: case STREAM_PLUGIN_DATA: /* Ignore plugin data */ break; case STREAM_UNIX_ACCESS_ACL: /* Deprecated Standard ACL attributes on UNIX */ case STREAM_UNIX_DEFAULT_ACL: /* Deprecated Default ACL attributes on UNIX */ case STREAM_ACL_AIX_TEXT: case STREAM_ACL_DARWIN_ACCESS_ACL: case STREAM_ACL_FREEBSD_DEFAULT_ACL: case STREAM_ACL_FREEBSD_ACCESS_ACL: case STREAM_ACL_HPUX_ACL_ENTRY: case STREAM_ACL_IRIX_DEFAULT_ACL: case STREAM_ACL_IRIX_ACCESS_ACL: case STREAM_ACL_LINUX_DEFAULT_ACL: case STREAM_ACL_LINUX_ACCESS_ACL: case STREAM_ACL_TRU64_DEFAULT_ACL: case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: case STREAM_ACL_TRU64_ACCESS_ACL: case STREAM_ACL_SOLARIS_ACLENT: case STREAM_ACL_SOLARIS_ACE: case STREAM_ACL_AFS_TEXT: case STREAM_ACL_AIX_AIXC: case STREAM_ACL_AIX_NFS4: case STREAM_ACL_FREEBSD_NFS4_ACL: case STREAM_ACL_HURD_DEFAULT_ACL: case STREAM_ACL_HURD_ACCESS_ACL: case STREAM_ACL_PLUGIN: /* Ignore Unix ACL attributes */ break; case STREAM_XATTR_PLUGIN: case STREAM_XATTR_HURD: case STREAM_XATTR_IRIX: case STREAM_XATTR_TRU64: case STREAM_XATTR_AIX: case STREAM_XATTR_OPENBSD: case STREAM_XATTR_SOLARIS_SYS: case STREAM_XATTR_SOLARIS: case STREAM_XATTR_DARWIN: case STREAM_XATTR_FREEBSD: case STREAM_XATTR_LINUX: case STREAM_XATTR_NETBSD: /* Ignore Unix Extended attributes */ break; case STREAM_NDMP_SEPERATOR: /* Ignore NDMP seperators */ break; default: Pmsg2(0, _("Unknown stream type!!! stream=%d len=%i\n"), rec->Stream, rec->data_len); break; } return true; } /* * Free the Job Control Record if no one is still using it. * Called from main free_jcr() routine in src/lib/jcr.c so * that we can do our Director specific cleanup of the jcr. */ static void bscan_free_jcr(JCR *jcr) { Dmsg0(200, "Start bscan free_jcr\n"); if (jcr->file_bsock) { Dmsg0(200, "Close File bsock\n"); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } if (jcr->store_bsock) { Dmsg0(200, "Close Store bsock\n"); jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; } if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); } if (jcr->dcr) { free_dcr(jcr->dcr); jcr->dcr = NULL; } if (jcr->read_dcr) { free_dcr(jcr->read_dcr); jcr->read_dcr = NULL; } Dmsg0(200, "End bscan free_jcr\n"); } /* * We got a File Attributes record on the tape. Now, lookup the Job * record, and then create the attributes record. */ static int create_file_attributes_record(B_DB *db, JCR *mjcr, char *fname, char *lname, int type, char *ap, DEV_RECORD *rec) { DCR *dcr = mjcr->read_dcr; ar.fname = fname; ar.link = lname; ar.ClientId = mjcr->ClientId; ar.JobId = mjcr->JobId; ar.Stream = rec->Stream; if (type == FT_DELETED) { ar.FileIndex = 0; } else { ar.FileIndex = rec->FileIndex; } ar.attr = ap; if (dcr->VolFirstIndex == 0) { dcr->VolFirstIndex = rec->FileIndex; } dcr->FileIndex = rec->FileIndex; mjcr->JobFiles++; if (!update_db) { return 1; } if (!db_create_file_attributes_record(bjcr, db, &ar)) { Pmsg1(0, _("Could not create File Attributes record. ERR=%s\n"), db_strerror(db)); return 0; } mjcr->FileId = ar.FileId; if (verbose > 1) { Pmsg1(000, _("Created File record: %s\n"), fname); } return 1; } /* * For each Volume we see, we create a Medium record */ static int create_media_record(B_DB *db, MEDIA_DBR *mr, VOLUME_LABEL *vl) { struct date_time dt; struct tm tm; /* We mark Vols as Archive to keep them from being re-written */ bstrncpy(mr->VolStatus, "Archive", sizeof(mr->VolStatus)); mr->VolRetention = 365 * 3600 * 24; /* 1 year */ mr->Enabled = 1; if (vl->VerNum >= 11) { mr->set_first_written = true; /* Save FirstWritten during update_media */ mr->FirstWritten = btime_to_utime(vl->write_btime); mr->LabelDate = btime_to_utime(vl->label_btime); } else { /* DEPRECATED DO NOT USE */ dt.julian_day_number = vl->write_date; dt.julian_day_fraction = vl->write_time; tm_decode(&dt, &tm); mr->FirstWritten = mktime(&tm); dt.julian_day_number = vl->label_date; dt.julian_day_fraction = vl->label_time; tm_decode(&dt, &tm); mr->LabelDate = mktime(&tm); } lasttime = mr->LabelDate; if (mr->VolJobs == 0) { mr->VolJobs = 1; } if (mr->VolMounts == 0) { mr->VolMounts = 1; } if (!update_db) { return 1; } if (!db_create_media_record(bjcr, db, mr)) { Pmsg1(0, _("Could not create media record. ERR=%s\n"), db_strerror(db)); return 0; } if (!db_update_media_record(bjcr, db, mr)) { Pmsg1(0, _("Could not update media record. ERR=%s\n"), db_strerror(db)); return 0; } if (verbose) { Pmsg1(000, _("Created Media record for Volume: %s\n"), mr->VolumeName); } return 1; } /* * Called at end of media to update it */ static bool update_media_record(B_DB *db, MEDIA_DBR *mr) { if (!update_db && !update_vol_info) { return true; } mr->LastWritten = lasttime; if (!db_update_media_record(bjcr, db, mr)) { Pmsg1(0, _("Could not update media record. ERR=%s\n"), db_strerror(db)); return false; } if (verbose) { Pmsg1(000, _("Updated Media record at end of Volume: %s\n"), mr->VolumeName); } return true; } static int create_pool_record(B_DB *db, POOL_DBR *pr) { pr->NumVols++; pr->UseCatalog = 1; pr->VolRetention = 355 * 3600 * 24; /* 1 year */ if (!update_db) { return 1; } if (!db_create_pool_record(bjcr, db, pr)) { Pmsg1(0, _("Could not create pool record. ERR=%s\n"), db_strerror(db)); return 0; } if (verbose) { Pmsg1(000, _("Created Pool record for Pool: %s\n"), pr->Name); } return 1; } /* * Called from SOS to create a client for the current Job */ static int create_client_record(B_DB *db, CLIENT_DBR *cr) { /* * Note, update_db can temporarily be set false while * updating the database, so we must ensure that ClientId is non-zero. */ if (!update_db) { cr->ClientId = 0; if (!db_get_client_record(bjcr, db, cr)) { Pmsg1(0, _("Could not get Client record. ERR=%s\n"), db_strerror(db)); return 0; } return 1; } if (!db_create_client_record(bjcr, db, cr)) { Pmsg1(0, _("Could not create Client record. ERR=%s\n"), db_strerror(db)); return 0; } if (verbose) { Pmsg1(000, _("Created Client record for Client: %s\n"), cr->Name); } return 1; } static int create_fileset_record(B_DB *db, FILESET_DBR *fsr) { if (!update_db) { return 1; } fsr->FileSetId = 0; if (fsr->MD5[0] == 0) { fsr->MD5[0] = ' '; /* Equivalent to nothing */ fsr->MD5[1] = 0; } if (db_get_fileset_record(bjcr, db, fsr)) { if (verbose) { Pmsg1(000, _("Fileset \"%s\" already exists.\n"), fsr->FileSet); } } else { if (!db_create_fileset_record(bjcr, db, fsr)) { Pmsg2(0, _("Could not create FileSet record \"%s\". ERR=%s\n"), fsr->FileSet, db_strerror(db)); return 0; } if (verbose) { Pmsg1(000, _("Created FileSet record \"%s\"\n"), fsr->FileSet); } } return 1; } /* * Simulate the two calls on the database to create * the Job record and to update it when the Job actually * begins running. */ static JCR *create_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *label, DEV_RECORD *rec) { JCR *mjcr; struct date_time dt; struct tm tm; jr->JobId = label->JobId; jr->JobType = label->JobType; jr->JobLevel = label->JobLevel; jr->JobStatus = JS_Created; bstrncpy(jr->Name, label->JobName, sizeof(jr->Name)); bstrncpy(jr->Job, label->Job, sizeof(jr->Job)); if (label->VerNum >= 11) { jr->SchedTime = btime_to_unix(label->write_btime); } else { dt.julian_day_number = label->write_date; dt.julian_day_fraction = label->write_time; tm_decode(&dt, &tm); jr->SchedTime = mktime(&tm); } jr->StartTime = jr->SchedTime; jr->JobTDate = (utime_t)jr->SchedTime; jr->VolSessionId = rec->VolSessionId; jr->VolSessionTime = rec->VolSessionTime; /* Now create a JCR as if starting the Job */ mjcr = create_jcr(jr, rec, label->JobId); if (!update_db) { return mjcr; } /* This creates the bare essentials */ if (!db_create_job_record(bjcr, db, jr)) { Pmsg1(0, _("Could not create JobId record. ERR=%s\n"), db_strerror(db)); return mjcr; } /* This adds the client, StartTime, JobTDate, ... */ if (!db_update_job_start_record(bjcr, db, jr)) { Pmsg1(0, _("Could not update job start record. ERR=%s\n"), db_strerror(db)); return mjcr; } Pmsg2(000, _("Created new JobId=%u record for original JobId=%u\n"), jr->JobId, label->JobId); mjcr->JobId = jr->JobId; /* set new JobId */ return mjcr; } /* * Simulate the database call that updates the Job * at Job termination time. */ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, DEV_RECORD *rec) { struct date_time dt; struct tm tm; JCR *mjcr; mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { Pmsg2(000, _("Could not find SessId=%d SessTime=%d for EOS record.\n"), rec->VolSessionId, rec->VolSessionTime); return 0; } if (elabel->VerNum >= 11) { jr->EndTime = btime_to_unix(elabel->write_btime); } else { dt.julian_day_number = elabel->write_date; dt.julian_day_fraction = elabel->write_time; tm_decode(&dt, &tm); jr->EndTime = mktime(&tm); } lasttime = jr->EndTime; mjcr->end_time = jr->EndTime; jr->JobId = mjcr->JobId; jr->JobStatus = elabel->JobStatus; mjcr->JobStatus = elabel->JobStatus; jr->JobFiles = elabel->JobFiles; if (jr->JobFiles > 0) { /* If we found files, force PurgedFiles */ jr->PurgedFiles = 0; } jr->JobBytes = elabel->JobBytes; jr->VolSessionId = rec->VolSessionId; jr->VolSessionTime = rec->VolSessionTime; jr->JobTDate = (utime_t)mjcr->start_time; jr->ClientId = mjcr->ClientId; if (!update_db) { free_jcr(mjcr); return 1; } if (!db_update_job_end_record(bjcr, db, jr)) { Pmsg2(0, _("Could not update JobId=%u record. ERR=%s\n"), jr->JobId, db_strerror(db)); free_jcr(mjcr); return 0; } if (verbose) { Pmsg3(000, _("Updated Job termination record for JobId=%u Level=%s TermStat=%c\n"), jr->JobId, job_level_to_str(mjcr->getJobLevel()), jr->JobStatus); } if (verbose > 1) { const char *term_msg; static char term_code[70]; char sdt[50], edt[50]; char ec1[30], ec2[30], ec3[30]; switch (mjcr->JobStatus) { case JS_Terminated: term_msg = _("Backup OK"); break; case JS_Warnings: term_msg = _("Backup OK -- with warnings"); break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Backup Error ***"); break; case JS_Canceled: term_msg = _("Backup Canceled"); break; default: term_msg = term_code; sprintf(term_code, _("Job Termination code: %d"), mjcr->JobStatus); break; } bstrftime(sdt, sizeof(sdt), mjcr->start_time); bstrftime(edt, sizeof(edt), mjcr->end_time); Pmsg14(000, _("%s\n" "JobId: %d\n" "Job: %s\n" "FileSet: %s\n" "Backup Level: %s\n" "Client: %s\n" "Start time: %s\n" "End time: %s\n" "Files Written: %s\n" "Bytes Written: %s\n" "Volume Session Id: %d\n" "Volume Session Time: %d\n" "Last Volume Bytes: %s\n" "Termination: %s\n\n"), edt, mjcr->JobId, mjcr->Job, mjcr->fileset_name, job_level_to_str(mjcr->getJobLevel()), mjcr->client_name, sdt, edt, edit_uint64_with_commas(mjcr->JobFiles, ec1), edit_uint64_with_commas(mjcr->JobBytes, ec2), mjcr->VolSessionId, mjcr->VolSessionTime, edit_uint64_with_commas(mr.VolBytes, ec3), term_msg); } free_jcr(mjcr); return 1; } static int create_jobmedia_record(B_DB *db, JCR *mjcr) { JOBMEDIA_DBR jmr; DCR *dcr = mjcr->read_dcr; dcr->EndBlock = dev->EndBlock; dcr->EndFile = dev->EndFile; dcr->VolMediaId = dev->VolCatInfo.VolMediaId; memset(&jmr, 0, sizeof(jmr)); jmr.JobId = mjcr->JobId; jmr.MediaId = mr.MediaId; jmr.FirstIndex = dcr->VolFirstIndex; jmr.LastIndex = dcr->VolLastIndex; jmr.StartFile = dcr->StartFile; jmr.EndFile = dcr->EndFile; jmr.StartBlock = dcr->StartBlock; jmr.EndBlock = dcr->EndBlock; if (!update_db) { return 1; } if (!db_create_jobmedia_record(bjcr, db, &jmr)) { Pmsg1(0, _("Could not create JobMedia record. ERR=%s\n"), db_strerror(db)); return 0; } if (verbose) { Pmsg2(000, _("Created JobMedia record JobId %d, MediaId %d\n"), jmr.JobId, jmr.MediaId); } return 1; } /* * Simulate the database call that updates the MD5/SHA1 record */ static int update_digest_record(B_DB *db, char *digest, DEV_RECORD *rec, int type) { JCR *mjcr; mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime); if (!mjcr) { if (mr.VolJobs > 0) { Pmsg2(000, _("Could not find SessId=%d SessTime=%d for MD5/SHA1 record.\n"), rec->VolSessionId, rec->VolSessionTime); } else { ignored_msgs++; } return 0; } if (!update_db || mjcr->FileId == 0) { free_jcr(mjcr); return 1; } if (!db_add_digest_to_file_record(bjcr, db, mjcr->FileId, digest, type)) { Pmsg1(0, _("Could not add MD5/SHA1 to File record. ERR=%s\n"), db_strerror(db)); free_jcr(mjcr); return 0; } if (verbose > 1) { Pmsg0(000, _("Updated MD5/SHA1 record\n")); } free_jcr(mjcr); return 1; } /* * Create a JCR as if we are really starting the job */ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId) { JCR *jobjcr; /* * Transfer as much as possible to the Job JCR. Most important is * the JobId and the ClientId. */ jobjcr = new_jcr(sizeof(JCR), bscan_free_jcr); jobjcr->setJobType(jr->JobType); jobjcr->setJobLevel(jr->JobLevel); jobjcr->JobStatus = jr->JobStatus; bstrncpy(jobjcr->Job, jr->Job, sizeof(jobjcr->Job)); jobjcr->JobId = JobId; /* this is JobId on tape */ jobjcr->sched_time = jr->SchedTime; jobjcr->start_time = jr->StartTime; jobjcr->VolSessionId = rec->VolSessionId; jobjcr->VolSessionTime = rec->VolSessionTime; jobjcr->ClientId = jr->ClientId; jobjcr->dcr = jobjcr->read_dcr = New(DCR); setup_new_dcr_device(jobjcr, jobjcr->dcr, dev, NULL); return jobjcr; } bareos-Release-14.2.6/src/stored/bsr.c000066400000000000000000000664151263011562700174750ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Match Bootstrap Records (used for restores) against * Volume Records * * Kern Sibbald, June MMII */ /* * ***FIXME*** * Also for efficiency, once a bsr is done, it really should be * delinked from the bsr chain. This will avoid the above * problem and make traversal of the bsr chain more efficient. * * To be done ... */ #include "bareos.h" #include "stored.h" const int dbglevel = 500; /* Forward references */ static int match_volume(BSR *bsr, BSR_VOLUME *volume, VOLUME_LABEL *volrec, bool done); static int match_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_RECORD *rec, bool done); static int match_sessid(BSR *bsr, BSR_SESSID *sessid, DEV_RECORD *rec); static int match_client(BSR *bsr, BSR_CLIENT *client, SESSION_LABEL *sessrec, bool done); static int match_job(BSR *bsr, BSR_JOB *job, SESSION_LABEL *sessrec, bool done); static int match_job_type(BSR *bsr, BSR_JOBTYPE *job_type, SESSION_LABEL *sessrec, bool done); static int match_job_level(BSR *bsr, BSR_JOBLEVEL *job_level, SESSION_LABEL *sessrec, bool done); static int match_jobid(BSR *bsr, BSR_JOBID *jobid, SESSION_LABEL *sessrec, bool done); static int match_findex(BSR *bsr, BSR_FINDEX *findex, DEV_RECORD *rec, bool done); static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool done); static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done); static int match_stream(BSR *bsr, BSR_STREAM *stream, DEV_RECORD *rec, bool done); static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, bool done, JCR *jcr); static int match_block_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_BLOCK *block); static int match_block_sessid(BSR *bsr, BSR_SESSID *sessid, DEV_BLOCK *block); static BSR *find_smallest_volfile(BSR *fbsr, BSR *bsr); /********************************************************************* * * If possible, position the archive device (tape) to read the * next block. */ void position_bsr_block(BSR *bsr, DEV_BLOCK *block) { /* To be implemented */ } /********************************************************************* * * Do fast block rejection based on bootstrap records. * use_fast_rejection will be set if we have VolSessionId and VolSessTime * in each record. When BlockVer is >= 2, we have those in the block header * so can do fast rejection. * * returns: 1 if block may contain valid records * 0 if block may be skipped (i.e. it contains no records of * that can match the bsr). * */ int match_bsr_block(BSR *bsr, DEV_BLOCK *block) { if (!bsr || !bsr->use_fast_rejection || (block->BlockVer < 2)) { return 1; /* cannot fast reject */ } for ( ; bsr; bsr=bsr->next) { if (!match_block_sesstime(bsr, bsr->sesstime, block)) { continue; } if (!match_block_sessid(bsr, bsr->sessid, block)) { continue; } return 1; } return 0; } static int match_block_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_BLOCK *block) { if (!sesstime) { return 1; /* no specification matches all */ } if (sesstime->sesstime == block->VolSessionTime) { return 1; } if (sesstime->next) { return match_block_sesstime(bsr, sesstime->next, block); } return 0; } static int match_block_sessid(BSR *bsr, BSR_SESSID *sessid, DEV_BLOCK *block) { if (!sessid) { return 1; /* no specification matches all */ } if (sessid->sessid <= block->VolSessionId && sessid->sessid2 >= block->VolSessionId) { return 1; } if (sessid->next) { return match_block_sessid(bsr, sessid->next, block); } return 0; } static int match_fileregex(BSR *bsr, DEV_RECORD *rec, JCR *jcr) { if (bsr->fileregex_re == NULL) return 1; if (bsr->attr == NULL) { bsr->attr = new_attr(jcr); } /* * The code breaks if the first record associated with a file is * not of this type */ if (rec->maskedStream == STREAM_UNIX_ATTRIBUTES || rec->maskedStream == STREAM_UNIX_ATTRIBUTES_EX) { bsr->skip_file = false; if (unpack_attributes_record(jcr, rec->Stream, rec->data, rec->data_len, bsr->attr)) { if (regexec(bsr->fileregex_re, bsr->attr->fname, 0, NULL, 0) == 0) { Dmsg2(dbglevel, "Matched pattern, fname=%s FI=%d\n", bsr->attr->fname, rec->FileIndex); } else { Dmsg2(dbglevel, "Didn't match, skipping fname=%s FI=%d\n", bsr->attr->fname, rec->FileIndex); bsr->skip_file = true; } } } return 1; } /********************************************************************* * * Match Bootstrap records * returns 1 on match * returns 0 no match and reposition is set if we should * reposition the tape * returns -1 no additional matches possible */ int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, JCR *jcr) { int status; /* * The bsr->reposition flag is set any time a bsr is done. * In this case, we can probably reposition the * tape to the next available bsr position. */ if (bsr) { bsr->reposition = false; status = match_all(bsr, rec, volrec, sessrec, true, jcr); /* * Note, bsr->reposition is set by match_all when * a bsr is done. We turn it off if a match was * found or if we cannot use positioning */ if (status != 0 || !bsr->use_positioning) { bsr->reposition = false; } } else { status = 1; /* no bsr => match all */ } return status; } /* * Find the next bsr that applies to the current tape. * It is the one with the smallest VolFile position. */ BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev) { BSR *bsr; BSR *found_bsr = NULL; /* Do tape/disk seeking only if CAP_POSITIONBLOCKS is on */ if (!root_bsr) { Dmsg0(dbglevel, "NULL root bsr pointer passed to find_next_bsr.\n"); return NULL; } if (!root_bsr->use_positioning || !root_bsr->reposition || !dev->has_cap(CAP_POSITIONBLOCKS)) { Dmsg2(dbglevel, "No nxt_bsr use_pos=%d repos=%d\n", root_bsr->use_positioning, root_bsr->reposition); return NULL; } Dmsg2(dbglevel, "use_pos=%d repos=%d\n", root_bsr->use_positioning, root_bsr->reposition); root_bsr->mount_next_volume = false; /* Walk through all bsrs to find the next one to use => smallest file,block */ for (bsr=root_bsr; bsr; bsr=bsr->next) { if (bsr->done || !match_volume(bsr, bsr->volume, &dev->VolHdr, 1)) { continue; } if (found_bsr == NULL) { found_bsr = bsr; } else { found_bsr = find_smallest_volfile(found_bsr, bsr); } } /* * If we get to this point and found no bsr, it means * that any additional bsr's must apply to the next * tape, so set a flag. */ if (found_bsr == NULL) { root_bsr->mount_next_volume = true; } return found_bsr; } /* * Get the smallest address from this voladdr part * Don't use "done" elements */ static bool get_smallest_voladdr(BSR_VOLADDR *va, uint64_t *ret) { bool ok=false; uint64_t min_val=0; for (; va ; va = va->next) { if (!va->done) { if (ok) { min_val = MIN(min_val, va->saddr); } else { min_val = va->saddr; ok=true; } } } *ret = min_val; return ok; } /* FIXME * This routine needs to be fixed to only look at items that * are not marked as done. Otherwise, it can find a bsr * that has already been consumed, and this will cause the * bsr to be used, thus we may seek back and re-read the * same records, causing an error. This deficiency must * be fixed. For the moment, it has been kludged in * read_record.c to avoid seeking back if find_next_bsr * returns a bsr pointing to a smaller address (file/block). * */ static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr) { BSR *return_bsr = found_bsr; BSR_VOLFILE *vf; BSR_VOLBLOCK *vb; uint32_t found_bsr_sfile, bsr_sfile; uint32_t found_bsr_sblock, bsr_sblock; uint64_t found_bsr_saddr, bsr_saddr; /* if we have VolAddr, use it, else try with File and Block */ if (get_smallest_voladdr(found_bsr->voladdr, &found_bsr_saddr)) { if (get_smallest_voladdr(bsr->voladdr, &bsr_saddr)) { if (found_bsr_saddr > bsr_saddr) { return bsr; } else { return found_bsr; } } } /* Find the smallest file in the found_bsr */ vf = found_bsr->volfile; found_bsr_sfile = vf->sfile; while ( (vf=vf->next) ) { if (vf->sfile < found_bsr_sfile) { found_bsr_sfile = vf->sfile; } } /* Find the smallest file in the bsr */ vf = bsr->volfile; bsr_sfile = vf->sfile; while ( (vf=vf->next) ) { if (vf->sfile < bsr_sfile) { bsr_sfile = vf->sfile; } } /* if the bsr file is less than the found_bsr file, return bsr */ if (found_bsr_sfile > bsr_sfile) { return_bsr = bsr; } else if (found_bsr_sfile == bsr_sfile) { /* Files are equal */ /* find smallest block in found_bsr */ vb = found_bsr->volblock; found_bsr_sblock = vb->sblock; while ( (vb=vb->next) ) { if (vb->sblock < found_bsr_sblock) { found_bsr_sblock = vb->sblock; } } /* Find smallest block in bsr */ vb = bsr->volblock; bsr_sblock = vb->sblock; while ( (vb=vb->next) ) { if (vb->sblock < bsr_sblock) { bsr_sblock = vb->sblock; } } /* Compare and return the smallest */ if (found_bsr_sblock > bsr_sblock) { return_bsr = bsr; } } return return_bsr; } /* * Called after the signature record so that * we can see if the current bsr has been * fully processed (i.e. is done). * The bsr argument is not used, but is included * for consistency with the other match calls. * * Returns: true if we should reposition * : false otherwise. */ bool is_this_bsr_done(BSR *bsr, DEV_RECORD *rec) { BSR *rbsr = rec->bsr; Dmsg1(dbglevel, "match_set %d\n", rbsr != NULL); if (!rbsr) { return false; } rec->bsr = NULL; rbsr->found++; if (rbsr->count && rbsr->found >= rbsr->count) { rbsr->done = true; rbsr->root->reposition = true; Dmsg2(dbglevel, "is_end_this_bsr set reposition=1 count=%d found=%d\n", rbsr->count, rbsr->found); return true; } Dmsg2(dbglevel, "is_end_this_bsr not done count=%d found=%d\n", rbsr->count, rbsr->found); return false; } /* * Match all the components of current record * returns 1 on match * returns 0 no match * returns -1 no additional matches possible */ static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, bool done, JCR *jcr) { Dmsg0(dbglevel, "Enter match_all\n"); if (bsr->done) { // Dmsg0(dbglevel, "bsr->done set\n"); goto no_match; } if (!match_volume(bsr, bsr->volume, volrec, 1)) { Dmsg2(dbglevel, "bsr fail bsr_vol=%s != rec read_vol=%s\n", bsr->volume->VolumeName, volrec->VolumeName); goto no_match; } Dmsg2(dbglevel, "OK bsr match bsr_vol=%s read_vol=%s\n", bsr->volume->VolumeName, volrec->VolumeName); if (!match_volfile(bsr, bsr->volfile, rec, 1)) { if (bsr->volfile) { Dmsg3(dbglevel, "Fail on file=%u. bsr=%u,%u\n", rec->File, bsr->volfile->sfile, bsr->volfile->efile); } goto no_match; } if (!match_voladdr(bsr, bsr->voladdr, rec, 1)) { if (bsr->voladdr) { Dmsg3(dbglevel, "Fail on Addr=%llu. bsr=%llu,%llu\n", get_record_address(rec), bsr->voladdr->saddr, bsr->voladdr->eaddr); } goto no_match; } if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) { Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n", bsr->sesstime->sesstime, rec->VolSessionTime); goto no_match; } /* NOTE!! This test MUST come after the sesstime test */ if (!match_sessid(bsr, bsr->sessid, rec)) { Dmsg2(dbglevel, "Fail on sessid. bsr=%u rec=%u\n", bsr->sessid->sessid, rec->VolSessionId); goto no_match; } /* NOTE!! This test MUST come after sesstime and sessid tests */ if (!match_findex(bsr, bsr->FileIndex, rec, 1)) { Dmsg3(dbglevel, "Fail on findex=%d. bsr=%d,%d\n", rec->FileIndex, bsr->FileIndex->findex, bsr->FileIndex->findex2); goto no_match; } Dmsg3(dbglevel, "match on findex=%d. bsr=%d,%d\n", rec->FileIndex, bsr->FileIndex->findex, bsr->FileIndex->findex2); if (!match_fileregex(bsr, rec, jcr)) { Dmsg1(dbglevel, "Fail on fileregex='%s'\n", bsr->fileregex); goto no_match; } /* This flag is set by match_fileregex (and perhaps other tests) */ if (bsr->skip_file) { Dmsg1(dbglevel, "Skipping findex=%d\n", rec->FileIndex); goto no_match; } /* * If a count was specified and we have a FileIndex, assume * it is a Bareos created bsr (or the equivalent). We * then save the bsr where the match occurred so that * after processing the record or records, we can update * the found count. I.e. rec->bsr points to the bsr that * satisfied the match. */ if (bsr->count && bsr->FileIndex) { rec->bsr = bsr; Dmsg0(dbglevel, "Leave match_all 1\n"); return 1; /* this is a complete match */ } /* * The selections below are not used by Bareos's * restore command, and don't work because of * the rec->bsr = bsr optimization above. */ if (!match_jobid(bsr, bsr->JobId, sessrec, 1)) { Dmsg0(dbglevel, "fail on JobId\n"); goto no_match; } if (!match_job(bsr, bsr->job, sessrec, 1)) { Dmsg0(dbglevel, "fail on Job\n"); goto no_match; } if (!match_client(bsr, bsr->client, sessrec, 1)) { Dmsg0(dbglevel, "fail on Client\n"); goto no_match; } if (!match_job_type(bsr, bsr->JobType, sessrec, 1)) { Dmsg0(dbglevel, "fail on Job type\n"); goto no_match; } if (!match_job_level(bsr, bsr->JobLevel, sessrec, 1)) { Dmsg0(dbglevel, "fail on Job level\n"); goto no_match; } if (!match_stream(bsr, bsr->stream, rec, 1)) { Dmsg0(dbglevel, "fail on stream\n"); goto no_match; } return 1; no_match: if (bsr->next) { return match_all(bsr->next, rec, volrec, sessrec, bsr->done && done, jcr); } if (bsr->done && done) { Dmsg0(dbglevel, "Leave match all -1\n"); return -1; } Dmsg0(dbglevel, "Leave match all 0\n"); return 0; } static int match_volume(BSR *bsr, BSR_VOLUME *volume, VOLUME_LABEL *volrec, bool done) { if (!volume) { return 0; /* Volume must match */ } if (bstrcmp(volume->VolumeName, volrec->VolumeName)) { Dmsg1(dbglevel, "match_volume=%s\n", volrec->VolumeName); return 1; } if (volume->next) { return match_volume(bsr, volume->next, volrec, 1); } return 0; } static int match_client(BSR *bsr, BSR_CLIENT *client, SESSION_LABEL *sessrec, bool done) { if (!client) { return 1; /* no specification matches all */ } if (bstrcmp(client->ClientName, sessrec->ClientName)) { return 1; } if (client->next) { return match_client(bsr, client->next, sessrec, 1); } return 0; } static int match_job(BSR *bsr, BSR_JOB *job, SESSION_LABEL *sessrec, bool done) { if (!job) { return 1; /* no specification matches all */ } if (bstrcmp(job->Job, sessrec->Job)) { return 1; } if (job->next) { return match_job(bsr, job->next, sessrec, 1); } return 0; } static int match_job_type(BSR *bsr, BSR_JOBTYPE *job_type, SESSION_LABEL *sessrec, bool done) { if (!job_type) { return 1; /* no specification matches all */ } if (job_type->JobType == sessrec->JobType) { return 1; } if (job_type->next) { return match_job_type(bsr, job_type->next, sessrec, 1); } return 0; } static int match_job_level(BSR *bsr, BSR_JOBLEVEL *job_level, SESSION_LABEL *sessrec, bool done) { if (!job_level) { return 1; /* no specification matches all */ } if (job_level->JobLevel == sessrec->JobLevel) { return 1; } if (job_level->next) { return match_job_level(bsr, job_level->next, sessrec, 1); } return 0; } static int match_jobid(BSR *bsr, BSR_JOBID *jobid, SESSION_LABEL *sessrec, bool done) { if (!jobid) { return 1; /* no specification matches all */ } if (jobid->JobId <= sessrec->JobId && jobid->JobId2 >= sessrec->JobId) { return 1; } if (jobid->next) { return match_jobid(bsr, jobid->next, sessrec, 1); } return 0; } static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool done) { if (!volfile) { return 1; /* no specification matches all */ } /* * The following code is turned off because this should now work * with disk files too, though since a "volfile" is 4GB, it does * not improve performance much. */ #ifdef xxx /* For the moment, these tests work only with tapes. */ if (!(rec->state & REC_ISTAPE)) { return 1; /* All File records OK for this match */ } Dmsg3(dbglevel, "match_volfile: sfile=%u efile=%u recfile=%u\n", volfile->sfile, volfile->efile, rec->File); #endif if (volfile->sfile <= rec->File && volfile->efile >= rec->File) { return 1; } /* Once we get past last efile, we are done */ if (rec->File > volfile->efile) { volfile->done = true; /* set local done */ } if (volfile->next) { return match_volfile(bsr, volfile->next, rec, volfile->done && done); } /* If we are done and all prior matches are done, this bsr is finished */ if (volfile->done && done) { bsr->done = true; bsr->root->reposition = true; Dmsg2(dbglevel, "bsr done from volfile rec=%u volefile=%u\n", rec->File, volfile->efile); } return 0; } static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done) { if (!voladdr) { return 1; /* no specification matches all */ } #ifdef xxx /* For the moment, these tests work only with disk. */ if (rec->state & REC_ISTAPE) { uint32_t sFile = (voladdr->saddr)>>32; uint32_t eFile = (voladdr->eaddr)>>32; if (sFile <= rec->File && eFile >= rec->File) { return 1; } } #endif uint64_t addr = get_record_address(rec); Dmsg6(dbglevel, "match_voladdr: saddr=%llu eaddr=%llu recaddr=%llu sfile=%u efile=%u recfile=%u\n", voladdr->saddr, voladdr->eaddr, addr, voladdr->saddr>>32, voladdr->eaddr>>32, addr>>32); if (voladdr->saddr <= addr && voladdr->eaddr >= addr) { return 1; } /* Once we get past last eblock, we are done */ if (addr > voladdr->eaddr) { voladdr->done = true; /* set local done */ } if (voladdr->next) { return match_voladdr(bsr, voladdr->next, rec, voladdr->done && done); } /* If we are done and all prior matches are done, this bsr is finished */ if (voladdr->done && done) { bsr->done = true; bsr->root->reposition = true; Dmsg2(dbglevel, "bsr done from voladdr rec=%llu voleaddr=%llu\n", addr, voladdr->eaddr); } return 0; } static int match_stream(BSR *bsr, BSR_STREAM *stream, DEV_RECORD *rec, bool done) { if (!stream) { return 1; /* no specification matches all */ } if (stream->stream == rec->Stream) { return 1; } if (stream->next) { return match_stream(bsr, stream->next, rec, 1); } return 0; } static int match_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_RECORD *rec, bool done) { if (!sesstime) { return 1; /* no specification matches all */ } if (sesstime->sesstime == rec->VolSessionTime) { return 1; } if (rec->VolSessionTime > sesstime->sesstime) { sesstime->done = true; } if (sesstime->next) { return match_sesstime(bsr, sesstime->next, rec, sesstime->done && done); } if (sesstime->done && done) { bsr->done = true; bsr->root->reposition = true; Dmsg0(dbglevel, "bsr done from sesstime\n"); } return 0; } /* * Note, we cannot mark bsr done based on session id because we may * have interleaved records, and there may be more of what we want * later. */ static int match_sessid(BSR *bsr, BSR_SESSID *sessid, DEV_RECORD *rec) { if (!sessid) { return 1; /* no specification matches all */ } if (sessid->sessid <= rec->VolSessionId && sessid->sessid2 >= rec->VolSessionId) { return 1; } if (sessid->next) { return match_sessid(bsr, sessid->next, rec); } return 0; } /* * When reading the Volume, the Volume Findex (rec->FileIndex) always * are found in sequential order. Thus we can make optimizations. * * ***FIXME*** optimizations * We could optimize by removing the recursion. */ static int match_findex(BSR *bsr, BSR_FINDEX *findex, DEV_RECORD *rec, bool done) { if (!findex) { return 1; /* no specification matches all */ } if (!findex->done) { if (findex->findex <= rec->FileIndex && findex->findex2 >= rec->FileIndex) { Dmsg3(dbglevel, "Match on findex=%d. bsrFIs=%d,%d\n", rec->FileIndex, findex->findex, findex->findex2); return 1; } if (rec->FileIndex > findex->findex2) { findex->done = true; } } if (findex->next) { return match_findex(bsr, findex->next, rec, findex->done && done); } if (findex->done && done) { bsr->done = true; bsr->root->reposition = true; Dmsg1(dbglevel, "bsr done from findex %d\n", rec->FileIndex); } return 0; } uint64_t get_bsr_start_addr(BSR *bsr, uint32_t *file, uint32_t *block) { uint64_t bsr_addr = 0; uint32_t sfile = 0, sblock = 0; if (bsr) { if (bsr->voladdr) { bsr_addr = bsr->voladdr->saddr; sfile = bsr_addr>>32; sblock = (uint32_t)bsr_addr; } else if (bsr->volfile && bsr->volblock) { bsr_addr = (((uint64_t)bsr->volfile->sfile)<<32)|bsr->volblock->sblock; sfile = bsr->volfile->sfile; sblock = bsr->volblock->sblock; } } if (file && block) { *file = sfile; *block = sblock; } return bsr_addr; } /***************************************************************** * Routines for handling volumes */ static VOL_LIST *new_restore_volume() { VOL_LIST *vol; vol = (VOL_LIST *)malloc(sizeof(VOL_LIST)); memset(vol, 0, sizeof(VOL_LIST)); return vol; } /* * Add current volume to end of list, only if the Volume * is not already in the list. * * returns: 1 if volume added * 0 if volume already in list */ static bool add_restore_volume(JCR *jcr, VOL_LIST *vol) { VOL_LIST *next = jcr->VolList; /* Add volume to volume manager's read list */ add_read_volume(jcr, vol->VolumeName); if (!next) { /* list empty ? */ jcr->VolList = vol; /* yes, add volume */ } else { /* Loop through all but last */ for ( ; next->next; next=next->next) { if (bstrcmp(vol->VolumeName, next->VolumeName)) { /* Save smallest start file */ if (vol->start_file < next->start_file) { next->start_file = vol->start_file; } return false; /* already in list */ } } /* Check last volume in list */ if (bstrcmp(vol->VolumeName, next->VolumeName)) { if (vol->start_file < next->start_file) { next->start_file = vol->start_file; } return false; /* already in list */ } next->next = vol; /* add volume */ } return true; } /* * Create a list of Volumes (and Slots and Start positions) to be * used in the current restore job. */ void create_restore_volume_list(JCR *jcr) { char *p, *n; VOL_LIST *vol; /* * Build a list of volumes to be processed */ jcr->NumReadVolumes = 0; jcr->CurReadVolume = 0; if (jcr->bsr) { BSR *bsr = jcr->bsr; if (!bsr->volume || !bsr->volume->VolumeName[0]) { return; } for ( ; bsr; bsr=bsr->next) { BSR_VOLUME *bsrvol; BSR_VOLFILE *volfile; uint32_t sfile = UINT32_MAX; /* Find minimum start file so that we can forward space to it */ for (volfile = bsr->volfile; volfile; volfile=volfile->next) { if (volfile->sfile < sfile) { sfile = volfile->sfile; } } /* Now add volumes for this bsr */ for (bsrvol = bsr->volume; bsrvol; bsrvol=bsrvol->next) { vol = new_restore_volume(); bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName)); bstrncpy(vol->MediaType, bsrvol->MediaType, sizeof(vol->MediaType)); bstrncpy(vol->device, bsrvol->device, sizeof(vol->device)); vol->Slot = bsrvol->Slot; vol->start_file = sfile; if (add_restore_volume(jcr, vol)) { jcr->NumReadVolumes++; Dmsg2(400, "Added volume=%s mediatype=%s\n", vol->VolumeName, vol->MediaType); } else { Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName); free((char *)vol); } sfile = 0; /* start at beginning of second volume */ } } } else { /* This is the old way -- deprecated */ for (p = jcr->dcr->VolumeName; p && *p; ) { n = strchr(p, '|'); /* volume name separator */ if (n) { *n++ = 0; /* Terminate name */ } vol = new_restore_volume(); bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName)); bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType)); if (add_restore_volume(jcr, vol)) { jcr->NumReadVolumes++; } else { free((char *)vol); } p = n; } } } void free_restore_volume_list(JCR *jcr) { VOL_LIST *vol = jcr->VolList; VOL_LIST *tmp; for ( ; vol; ) { tmp = vol->next; remove_read_volume(jcr, vol->VolumeName); free(vol); vol = tmp; } jcr->VolList = NULL; } bareos-Release-14.2.6/src/stored/btape.c000066400000000000000000002576221263011562700200040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos Tape manipulation program * * Has various tape manipulation commands -- mostly for * use in determining how tapes really work. * * Kern Sibbald, April MM * * Note, this program reads stored.conf, and will only * talk to devices that are configured. */ #include "bareos.h" #include "stored.h" #include "lib/crypto_cache.h" /* Dummy functions */ extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); /* Exported variables */ int quit = 0; char buf[100000]; int bsize = TAPE_BSIZE; char VolName[MAX_NAME_LENGTH]; /* * If you change the format of the state file, * increment this value */ static uint32_t btape_state_level = 2; DEVICE *dev = NULL; DCR *dcr; DEVRES *device = NULL; int exit_code = 0; #define REC_SIZE 32768 /* Forward referenced subroutines */ static void do_tape_cmds(); static void helpcmd(); static void scancmd(); static void rewindcmd(); static void clearcmd(); static void wrcmd(); static void rrcmd(); static void rbcmd(); static void eodcmd(); static void fillcmd(); static void qfillcmd(); static void statcmd(); static void unfillcmd(); static int flush_block(DEV_BLOCK *block, int dump); static bool quickie_cb(DCR *dcr, DEV_RECORD *rec); static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block); static bool my_mount_next_read_volume(DCR *dcr); static void scan_blocks(); static void set_volume_name(const char *VolName, int volnum); static void rawfill_cmd(); static bool open_the_device(); static void autochangercmd(); static bool do_unfill(); /* Static variables */ #define CONFIG_FILE "bareos-sd.conf" #define MAX_CMD_ARGS 30 static POOLMEM *cmd; static POOLMEM *args; static char *argk[MAX_CMD_ARGS]; static char *argv[MAX_CMD_ARGS]; static int argc; static int quickie_count = 0; static uint64_t write_count = 0; static BSR *bsr = NULL; static int signals = TRUE; static bool ok; static int stop = 0; static uint64_t vol_size; static uint64_t VolBytes; static time_t now; static int32_t file_index; static int end_of_tape = 0; static uint32_t LastBlock = 0; static uint32_t eot_block; static uint32_t eot_block_len; static uint32_t eot_FileIndex; static int dumped = 0; static DEV_BLOCK *last_block1 = NULL; static DEV_BLOCK *last_block2 = NULL; static DEV_BLOCK *last_block = NULL; static DEV_BLOCK *this_block = NULL; static DEV_BLOCK *first_block = NULL; static uint32_t last_file1 = 0; static uint32_t last_file2 = 0; static uint32_t last_file = 0; static uint32_t last_block_num1 = 0; static uint32_t last_block_num2 = 0; static uint32_t last_block_num = 0; static uint32_t BlockNumber = 0; static bool simple = true; static const char *volumename = NULL; static int vol_num = 0; static JCR *jcr = NULL; static void usage(); static void terminate_btape(int sig); int get_cmd(const char *prompt); /********************************************************************* * * Bareos tape testing program * */ int main(int margc, char *margv[]) { int ch, i; uint32_t x32, y32; uint64_t x64, y64; char buf[1000]; char *DirectorName = NULL; DIRRES *director = NULL; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); lmgr_init_thread(); /* Sanity checks */ if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) { Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"), TAPE_BSIZE, B_DEV_BSIZE); } if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) { Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE); } if (sizeof(boffset_t) < 8) { Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"), sizeof(boffset_t)); } x32 = 123456789; bsnprintf(buf, sizeof(buf), "%u", x32); i = bsscanf(buf, "%lu", &y32); if (i != 1 || x32 != y32) { Pmsg3(-1, _("32 bit printf/scanf problem. i=%d x32=%u y32=%u\n"), i, x32, y32); exit(1); } x64 = 123456789; x64 = x64 << 32; x64 += 123456789; bsnprintf(buf, sizeof(buf), "%" llu, x64); i = bsscanf(buf, "%llu", &y64); if (i != 1 || x64 != y64) { Pmsg3(-1, _("64 bit printf/scanf problem. i=%d x64=%" llu " y64=%" llu "\n"), i, x64, y64); exit(1); } printf(_("Tape block granularity is %d bytes.\n"), TAPE_BSIZE); working_directory = "/tmp"; my_name_is(margc, margv, "btape"); init_msg(NULL, NULL); OSDependentInit(); while ((ch = getopt(margc, margv, "b:c:D:d:psv?")) != -1) { switch (ch) { case 'b': /* bootstrap file */ bsr = parse_bsr(NULL, optarg); // dump_bsr(bsr, true); break; case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'D': /* specify director name */ if (DirectorName != NULL) { free(DirectorName); } DirectorName = bstrdup(optarg); break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'p': forge_on = true; break; case 's': signals = false; break; case 'v': verbose++; break; case '?': default: helpcmd(); exit(0); } } margc -= optind; margv += optind; cmd = get_pool_memory(PM_FNAME); args = get_pool_memory(PM_FNAME); if (signals) { init_signals(terminate_btape); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } daemon_start_time = time(NULL); my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (DirectorName) { foreach_res(director, R_DIRECTOR) { if (bstrcmp(director->hdr.name, DirectorName)) { break; } } if (!director) { Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"), DirectorName, configfile); } } load_sd_plugins(me->plugin_directory, me->plugin_names); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); /* See if we can open a device */ if (margc == 0) { Pmsg0(000, _("No archive name specified.\n")); usage(); exit(1); } else if (margc != 1) { Pmsg0(000, _("Improper number of arguments specified.\n")); usage(); exit(1); } dcr = New(BTAPE_DCR); jcr = setup_jcr("btape", margv[0], bsr, director, dcr, NULL, false); /* write device */ if (!jcr) { exit(1); } dev = jcr->dcr->dev; if (!dev) { exit(1); } if (!dev->is_tape()) { Pmsg0(000, _("btape only works with tape storage.\n")); usage(); exit(1); } if (!open_the_device()) { exit(1); } Dmsg0(200, "Do tape commands\n"); do_tape_cmds(); terminate_btape(exit_code); } static void terminate_btape(int status) { Dsm_check(200); free_jcr(jcr); jcr = NULL; if (args) { free_pool_memory(args); args = NULL; } if (cmd) { free_pool_memory(cmd); cmd = NULL; } if (bsr) { free_bsr(bsr); } free_volume_lists(); if (dev) { dev->term(); } #if defined(HAVE_DYNAMIC_SD_BACKENDS) dev_flush_backends(); #endif if (configfile) { free(configfile); } if (my_config) { my_config->free_resources(); free(my_config); my_config = NULL; } if (debug_level > 10) { print_memory_pool_stats(); } if (this_block) { free_block(this_block); this_block = NULL; } stop_watchdog(); term_msg(); term_last_jobs_list(); close_memory_pool(); /* free memory in pool */ lmgr_cleanup_main(); sm_dump(false); exit(status); } btime_t total_time=0; uint64_t total_size=0; static void init_total_speed() { total_size = 0; total_time = 0; } static void print_total_speed() { char ec1[50], ec2[50]; uint64_t rate = total_size / total_time; Pmsg2(000, _("Total Volume bytes=%sB. Total Write rate = %sB/s\n"), edit_uint64_with_suffix(total_size, ec1), edit_uint64_with_suffix(rate, ec2)); } static void init_speed() { time(&jcr->run_time); /* start counting time for rates */ jcr->JobBytes=0; } static void print_speed(uint64_t bytes) { char ec1[50], ec2[50]; uint64_t rate; now = time(NULL); now -= jcr->run_time; if (now <= 0) { now = 1; /* don't divide by zero */ } total_time += now; total_size += bytes; rate = bytes / now; Pmsg2(000, _("Volume bytes=%sB. Write rate = %sB/s\n"), edit_uint64_with_suffix(bytes, ec1), edit_uint64_with_suffix(rate, ec2)); } /* * Helper that fill a buffer with random data or not */ typedef enum { FILL_RANDOM, FILL_ZERO } fill_mode_t; static void fill_buffer(fill_mode_t mode, char *buf, uint32_t len) { int fd; switch (mode) { case FILL_RANDOM: fd = open("/dev/urandom", O_RDONLY); if (fd != -1) { read(fd, buf, len); close(fd); } else { uint32_t *p = (uint32_t *)buf; srandom(time(NULL)); for (uint32_t i=0; irLock(); Dmsg1(200, "Opening device %s\n", dcr->VolumeName); if (!dev->open(dcr, OPEN_READ_WRITE)) { Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); ok = false; goto bail_out; } Pmsg1(000, _("open device %s: OK\n"), dev->print_name()); dev->set_append(); /* put volume in append mode */ bail_out: dev->Unlock(); free_block(block); return ok; } void quitcmd() { quit = 1; } /* * Write a label to the tape */ static void labelcmd() { if (volumename) { pm_strcpy(cmd, volumename); } else { if (!get_cmd(_("Enter Volume Name: "))) { return; } } if (!dev->is_open()) { if (!first_open_device(dcr)) { Pmsg1(0, _("Device open failed. ERR=%s\n"), dev->bstrerror()); } } dev->rewind(dcr); write_new_volume_label_to_dev(dcr, cmd, "Default", false /*no relabel*/); Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd); } /* * Read the tape label */ static void readlabelcmd() { int save_debug_level = debug_level; int status; status = read_dev_volume_label(dcr); switch (status) { case VOL_NO_LABEL: Pmsg0(0, _("Volume has no label.\n")); break; case VOL_OK: Pmsg0(0, _("Volume label read correctly.\n")); break; case VOL_IO_ERROR: Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror()); break; case VOL_NAME_ERROR: Pmsg0(0, _("Volume name error\n")); break; case VOL_CREATE_ERROR: Pmsg1(0, _("Error creating label. ERR=%s"), dev->bstrerror()); break; case VOL_VERSION_ERROR: Pmsg0(0, _("Volume version error.\n")); break; case VOL_LABEL_ERROR: Pmsg0(0, _("Bad Volume label type.\n")); break; default: Pmsg0(0, _("Unknown error.\n")); break; } debug_level = 20; dump_volume_label(dev); debug_level = save_debug_level; } /* * Load the tape should have prevously been taken * off line, otherwise this command is not necessary. */ static void loadcmd() { if (!dev->load_dev()) { Pmsg1(0, _("Bad status from load. ERR=%s\n"), dev->bstrerror()); } else Pmsg1(0, _("Loaded %s\n"), dev->print_name()); } /* * Rewind the tape. */ static void rewindcmd() { if (!dev->rewind(dcr)) { Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror()); dev->clrerror(-1); } else { Pmsg1(0, _("Rewound %s\n"), dev->print_name()); } } /* * Clear any tape error */ static void clearcmd() { dev->clrerror(-1); } /* * Write and end of file on the tape */ static void weofcmd() { int num = 1; if (argc > 1) { num = atoi(argk[1]); } if (num <= 0) { num = 1; } if (!dev->weof(num)) { Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror()); return; } else { if (num==1) { Pmsg1(0, _("Wrote 1 EOF to %s\n"), dev->print_name()); } else { Pmsg2(0, _("Wrote %d EOFs to %s\n"), num, dev->print_name()); } } } /* Go to the end of the medium -- raw command * The idea was orginally that the end of the Bareos * medium would be flagged differently. This is not * currently the case. So, this is identical to the * eodcmd(). */ static void eomcmd() { if (!dev->eod(dcr)) { Pmsg1(0, "%s", dev->bstrerror()); return; } else { Pmsg0(0, _("Moved to end of medium.\n")); } } /* * Go to the end of the medium (either hardware determined * or defined by two eofs. */ static void eodcmd() { eomcmd(); } /* * Backspace file */ static void bsfcmd() { int num = 1; if (argc > 1) { num = atoi(argk[1]); } if (num <= 0) { num = 1; } if (!dev->bsf(num)) { Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), dev->bstrerror()); } else { Pmsg2(0, _("Backspaced %d file%s.\n"), num, num==1?"":"s"); } } /* * Backspace record */ static void bsrcmd() { int num = 1; if (argc > 1) { num = atoi(argk[1]); } if (num <= 0) { num = 1; } if (!dev->bsr(num)) { Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), dev->bstrerror()); } else { Pmsg2(0, _("Backspaced %d record%s.\n"), num, num==1?"":"s"); } } /* * List device capabilities as defined in the * stored.conf file. */ static void capcmd() { printf(_("Configured device capabilities:\n")); printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!"); printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!"); printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!"); printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!"); printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!"); printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!"); printf("%sBSFATEOM ", dev->capabilities & CAP_BSFATEOM ? "" : "!"); printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!"); printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!"); printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!"); printf("%sAUTOMOUNT ", dev->capabilities & CAP_AUTOMOUNT ? "" : "!"); printf("%sLABEL ", dev->capabilities & CAP_LABEL ? "" : "!"); printf("%sANONVOLS ", dev->capabilities & CAP_ANONVOLS ? "" : "!"); printf("%sALWAYSOPEN ", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!"); printf("%sMTIOCGET ", dev->capabilities & CAP_MTIOCGET ? "" : "!"); printf("\n"); printf(_("Device status:\n")); printf("%sOPENED ", dev->is_open() ? "" : "!"); printf("%sTAPE ", dev->is_tape() ? "" : "!"); printf("%sLABEL ", dev->is_labeled() ? "" : "!"); printf("%sMALLOC ", dev->state & ST_MALLOC ? "" : "!"); printf("%sAPPEND ", dev->can_append() ? "" : "!"); printf("%sREAD ", dev->can_read() ? "" : "!"); printf("%sEOT ", dev->at_eot() ? "" : "!"); printf("%sWEOT ", dev->state & ST_WEOT ? "" : "!"); printf("%sEOF ", dev->at_eof() ? "" : "!"); printf("%sNEXTVOL ", dev->state & ST_NEXTVOL ? "" : "!"); printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!"); printf("\n"); printf(_("Device parameters:\n")); printf("Device name: %s\n", dev->dev_name); printf("File=%u block=%u\n", dev->file, dev->block_num); printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size); printf(_("Status:\n")); statcmd(); } /* * Test writing larger and larger records. * This is a torture test for records. */ static void rectestcmd() { DEV_BLOCK *save_block; DEV_RECORD *rec; int i, blkno = 0; Pmsg0(0, _("Test writing larger and larger records.\n" "This is a torture test for records.\nI am going to write\n" "larger and larger records. It will stop when the record size\n" "plus the header exceeds the block size (by default about 64K)\n")); get_cmd(_("Do you want to continue? (y/n): ")); if (cmd[0] != 'y') { Pmsg0(000, _("Command aborted.\n")); return; } Dsm_check(200); save_block = dcr->block; dcr->block = new_block(dev); rec = new_record(); for (i=1; i<500000; i++) { rec->data = check_pool_memory_size(rec->data, i); memset(rec->data, i & 0xFF, i); rec->data_len = i; Dsm_check(200); if (write_record_to_block(dcr, rec)) { empty_block(dcr->block); blkno++; Pmsg2(0, _("Block %d i=%d\n"), blkno, i); } else { break; } Dsm_check(200); } free_record(rec); free_block(dcr->block); dcr->block = save_block; /* restore block to dcr */ Dsm_check(200); } /* * This test attempts to re-read a block written by Bareos * normally at the end of the tape. Bareos will then back up * over the two eof marks, backup over the record and reread * it to make sure it is valid. Bareos can skip this validation * if you set "Backward space record = no" */ static bool re_read_block_test() { DEV_BLOCK *block = dcr->block; DEV_RECORD *rec; bool rc = false; int len; if (!(dev->capabilities & CAP_BSR)) { Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n")); return true; } Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n" "I'm going to write three records and an EOF\n" "then backup over the EOF and re-read the last record.\n" "Bareos does this after writing the last block on the\n" "tape to verify that the block was written correctly.\n\n" "This is not an *essential* feature ...\n\n")); rewindcmd(); empty_block(block); rec = new_record(); rec->data = check_pool_memory_size(rec->data, block->buf_len); len = rec->data_len = block->buf_len-100; memset(rec->data, 1, rec->data_len); if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { Pmsg1(0, _("Wrote first record of %d bytes.\n"), rec->data_len); } memset(rec->data, 2, rec->data_len); if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { Pmsg1(0, _("Wrote second record of %d bytes.\n"), rec->data_len); } memset(rec->data, 3, rec->data_len); if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len); } weofcmd(); if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } if (!dev->bsf(1)) { Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror()); goto bail_out; } if (dev->has_cap(CAP_TWOEOF)) { if (!dev->bsf(1)) { Pmsg1(0, _("Backspace file failed! ERR=%s\n"), dev->bstrerror()); goto bail_out; } } Pmsg0(0, _("Backspaced over EOF OK.\n")); if (!dev->bsr(1)) { Pmsg1(0, _("Backspace record failed! ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg0(0, _("Backspace record OK.\n")); if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; } memset(rec->data, 0, rec->data_len); if (!read_record_from_block(dcr, rec)) { berrno be; Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; } for (int i=0; idata[i] != 3) { Pmsg0(0, _("Bad data in record. Test failed!\n")); goto bail_out; } } Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n")); Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n")); rc = true; bail_out: free_record(rec); if (!rc) { Pmsg0(0, _("This is not terribly serious since Bareos only uses\n" "this function to verify the last block written to the\n" "tape. Bareos will skip the last block verification\n" "if you add:\n\n" "Backward Space Record = No\n\n" "to your Storage daemon's Device resource definition.\n")); } return rc; } static bool speed_test_raw(fill_mode_t mode, uint64_t nb_gb, uint32_t nb) { DEV_BLOCK *block = dcr->block; int status; uint32_t block_num = 0; int my_errno; char ed1[200]; nb_gb *= 1024*1024*1024; /* convert size from nb to GB */ init_total_speed(); fill_buffer(mode, block->buf, block->buf_len); Pmsg3(0, _("Begin writing %i files of %sB with raw blocks of %u bytes.\n"), nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len); for (uint32_t j=0; jJobBytes < nb_gb; ) { status = dev->d_write(dev->fd(), block->buf, block->buf_len); if (status == (int)block->buf_len) { if ((block_num++ % 500) == 0) { printf("+"); fflush(stdout); } mix_buffer(mode, block->buf, block->buf_len); jcr->JobBytes += status; } else { my_errno = errno; printf("\n"); berrno be; printf(_("Write failed at block %u. status=%d ERR=%s\n"), block_num, status, be.bstrerror(my_errno)); return false; } } printf("\n"); weofcmd(); print_speed(jcr->JobBytes); } print_total_speed(); printf("\n"); return true; } static bool speed_test_bareos(fill_mode_t mode, uint64_t nb_gb, uint32_t nb) { DEV_BLOCK *block = dcr->block; char ed1[200]; DEV_RECORD *rec; uint64_t last_bytes = dev->VolCatInfo.VolCatBytes; uint64_t written=0; nb_gb *= 1024*1024*1024; /* convert size from nb to GB */ init_total_speed(); empty_block(block); rec = new_record(); rec->data = check_pool_memory_size(rec->data, block->buf_len); rec->data_len = block->buf_len-100; fill_buffer(mode, rec->data, rec->data_len); Pmsg3(0, _("Begin writing %i files of %sB with blocks of %u bytes.\n"), nb, edit_uint64_with_suffix(nb_gb, ed1), block->buf_len); for (uint32_t j=0; jwrite_block_to_dev()) { Pmsg0(0, _("\nError writing block to device.\n")); goto bail_out; } if ((block->BlockNumber % 500) == 0) { printf("+"); fflush(stdout); } written += dev->VolCatInfo.VolCatBytes - last_bytes; last_bytes = dev->VolCatInfo.VolCatBytes; mix_buffer(mode, rec->data, rec->data_len); } printf("\n"); weofcmd(); print_speed(written); } print_total_speed(); printf("\n"); free_record(rec); return true; bail_out: free_record(rec); return false; } /* TODO: use UAContext */ static int btape_find_arg(const char *keyword) { for (int i=1; i 0) { file_size = atoi(argv[i]); if (file_size > 100) { Pmsg0(0, _("The file_size is too big, stop this test with Ctrl-c.\n")); } } i = btape_find_arg("nb_file"); if (i > 0) { nb_file = atoi(argv[i]); } if (btape_find_arg("skip_zero") > 0) { do_zero = false; } if (btape_find_arg("skip_random") > 0) { do_random = false; } if (btape_find_arg("skip_raw") > 0) { do_raw = false; } if (btape_find_arg("skip_block") > 0) { do_block = false; } if (do_raw) { dev->rewind(dcr); if (do_zero) { Pmsg0(0, _("Test with zero data, should give the " "maximum throughput.\n")); if (file_size) { ok(speed_test_raw(FILL_ZERO, file_size, nb_file)); } else { ok(speed_test_raw(FILL_ZERO, 1, nb_file)); ok(speed_test_raw(FILL_ZERO, 2, nb_file)); ok(speed_test_raw(FILL_ZERO, 4, nb_file)); } } if (do_random) { Pmsg0(0, _("Test with random data, should give the minimum " "throughput.\n")); if (file_size) { ok(speed_test_raw(FILL_RANDOM, file_size, nb_file)); } else { ok(speed_test_raw(FILL_RANDOM, 1, nb_file)); ok(speed_test_raw(FILL_RANDOM, 2, nb_file)); ok(speed_test_raw(FILL_RANDOM, 4, nb_file)); } } } if (do_block) { dev->rewind(dcr); if (do_zero) { Pmsg0(0, _("Test with zero data and bareos block structure.\n")); if (file_size) { ok(speed_test_bareos(FILL_ZERO, file_size, nb_file)); } else { ok(speed_test_bareos(FILL_ZERO, 1, nb_file)); ok(speed_test_bareos(FILL_ZERO, 2, nb_file)); ok(speed_test_bareos(FILL_ZERO, 4, nb_file)); } } if (do_random) { Pmsg0(0, _("Test with random data, should give the minimum " "throughput.\n")); if (file_size) { ok(speed_test_bareos(FILL_RANDOM, file_size, nb_file)); } else { ok(speed_test_bareos(FILL_RANDOM, 1, nb_file)); ok(speed_test_bareos(FILL_RANDOM, 2, nb_file)); ok(speed_test_bareos(FILL_RANDOM, 4, nb_file)); } } } } const uint64_t num_recs = 10000LL; static bool write_two_files() { DEV_BLOCK *block; DEV_RECORD *rec; int len, j; unsigned int i; int *p; bool rc = false; /* bad return code */ DEVICE *dev = dcr->dev; /* * Set big max_file_size so that write_record_to_block * doesn't insert any additional EOF marks */ if (dev->max_block_size) { dev->max_file_size = 2LL * num_recs * (uint64_t)dev->max_block_size; } else { dev->max_file_size = 2LL * num_recs * (uint64_t)DEFAULT_BLOCK_SIZE; } Dmsg1(100, "max_file_size was set to %lld\n", dev->max_file_size); Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n" "I'm going to write %d records and an EOF\n" "then write %d records and an EOF, then rewind,\n" "and re-read the data to verify that it is correct.\n\n" "This is an *essential* feature ...\n\n"), num_recs, num_recs); block = dcr->block; empty_block(block); rec = new_record(); rec->data = check_pool_memory_size(rec->data, block->buf_len); rec->data_len = block->buf_len-100; len = rec->data_len/sizeof(i); if (!dev->rewind(dcr)) { Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror()); goto bail_out; } for (i=1; i<=num_recs; i++) { p = (int *)rec->data; for (j=0; jwrite_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } } Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len); weofcmd(); for (i=num_recs+1; i<=2*num_recs; i++) { p = (int *)rec->data; for (j=0; jwrite_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } } Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len); weofcmd(); if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } rc = true; bail_out: free_record(rec); if (!rc) { exit_code = 1; } return rc; } /* * This test writes Bareos blocks to the tape in * several files. It then rewinds the tape and attepts * to read these blocks back checking the data. */ static bool write_read_test() { DEV_BLOCK *block; DEV_RECORD *rec; bool rc = false; int len, i, j; int *p; rec = new_record(); if (!write_two_files()) { goto bail_out; } block = dcr->block; empty_block(block); if (!dev->rewind(dcr)) { Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror()); goto bail_out; } else { Pmsg0(0, _("Rewind OK.\n")); } rec->data = check_pool_memory_size(rec->data, block->buf_len); rec->data_len = block->buf_len-100; len = rec->data_len/sizeof(i); /* Now read it back */ for (i=1; i<=2*num_recs; i++) { read_again: if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; if (dev->at_eof()) { Pmsg0(-1, _("Got EOF on tape.\n")); if (i == num_recs+1) { goto read_again; } } Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno)); goto bail_out; } memset(rec->data, 0, rec->data_len); if (!read_record_from_block(dcr, rec)) { berrno be; Pmsg2(0, _("Read record failed. Block %d! ERR=%s\n"), i, be.bstrerror(dev->dev_errno)); goto bail_out; } p = (int *)rec->data; for (j=0; jblock; DEV_RECORD *rec; bool rc = false; int len, j; bool more = true; int recno = 0; int file = 0, blk = 0; int *p; bool got_eof = false; Pmsg0(0, _("Block position test\n")); block = dcr->block; empty_block(block); rec = new_record(); rec->data = check_pool_memory_size(rec->data, block->buf_len); rec->data_len = block->buf_len-100; len = rec->data_len/sizeof(j); if (!dev->rewind(dcr)) { Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror()); goto bail_out; } else { Pmsg0(0, _("Rewind OK.\n")); } while (more) { /* Set up next item to read based on where we are */ /* At each step, recno is what we print for the "block number" * and file, blk are the real positions to go to. */ switch (recno) { case 0: recno = 5; file = 0; blk = 4; break; case 5: recno = 201; file = 0; blk = 200; break; case 201: recno = num_recs; file = 0; blk = num_recs-1; break; case num_recs: recno = num_recs+1; file = 1; blk = 0; break; case num_recs+1: recno = num_recs+601; file = 1; blk = 600; break; case num_recs+601: recno = 2*num_recs; file = 1; blk = num_recs-1; break; case 2*num_recs: more = false; continue; } Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk); if (!dev->reposition(dcr, file, blk)) { Pmsg0(0, _("Reposition error.\n")); goto bail_out; } read_again: if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; if (dev->at_eof()) { Pmsg0(-1, _("Got EOF on tape.\n")); if (!got_eof) { got_eof = true; goto read_again; } } Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"), recno, file, blk, be.bstrerror(dev->dev_errno)); Pmsg0(0, _("This may be because the tape drive block size is not\n" " set to variable blocking as normally used by Bareos.\n" " Please see the Tape Testing chapter in the manual and \n" " look for using mt with defblksize and setoptions\n" "If your tape drive block size is correct, then perhaps\n" " your SCSI driver is *really* stupid and does not\n" " correctly report the file:block after a FSF. In this\n" " case try setting:\n" " Fast Forward Space File = no\n" " in your Device resource.\n")); goto bail_out; } memset(rec->data, 0, rec->data_len); if (!read_record_from_block(dcr, rec)) { berrno be; Pmsg1(0, _("Read record failed! ERR=%s\n"), be.bstrerror(dev->dev_errno)); goto bail_out; } p = (int *)rec->data; for (j=0; jhas_cap(CAP_TWOEOF)) { weofcmd(); } dev->close(dcr); /* release device */ if (!open_the_device()) { return -1; } rewindcmd(); Pmsg0(0, _("Now moving to end of medium.\n")); eodcmd(); Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"), dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!")); if (dev->file != 3) { return -1; } Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n")); wrcmd(); weofcmd(); if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } rewindcmd(); Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n")); Pmsg0(-1, _("Doing Bareos scan of blocks:\n")); scan_blocks(); Pmsg0(-1, _("End scanning the tape.\n")); Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"), dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!")); if (dev->file != 4) { return -2; } return 1; } /* * This test exercises the autochanger */ static int autochanger_test() { POOLMEM *results, *changer; int slot, status, loaded; int timeout = dcr->device->max_changer_wait; int sleep_time = 0; Dmsg1(100, "Max changer wait = %d sec\n", timeout); if (!dev->has_cap(CAP_AUTOCHANGER)) { return 1; } if (!(dcr->device && dcr->device->changer_name && dcr->device->changer_command)) { Pmsg0(-1, _("\nAutochanger enabled, but no name or no command device specified.\n")); return 1; } Pmsg0(-1, _("\nAh, I see you have an autochanger configured.\n" "To test the autochanger you must have a blank tape\n" " that I can write on in Slot 1.\n")); if (!get_cmd(_("\nDo you wish to continue with the Autochanger test? (y/n): "))) { return 0; } if (cmd[0] != 'y' && cmd[0] != 'Y') { return 0; } Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n")); results = get_pool_memory(PM_MESSAGE); changer = get_pool_memory(PM_FNAME); try_again: slot = 1; dcr->VolCatInfo.Slot = slot; /* Find out what is loaded, zero means device is unloaded */ Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n")); changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "loaded"); status = run_program(changer, timeout, results); Dmsg3(100, "run_prog: %s stat=%d result=\"%s\"\n", changer, status, results); if (status == 0) { loaded = atoi(results); } else { berrno be; Pmsg1(-1, _("3991 Bad autochanger command: %s\n"), changer); Pmsg2(-1, _("3991 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status)); goto bail_out; } if (loaded) { Pmsg1(-1, _("Slot %d loaded. I am going to unload it.\n"), loaded); } else { Pmsg0(-1, _("Nothing loaded in the drive. OK.\n")); } Dmsg1(100, "Results from loaded query=%s\n", results); if (loaded) { dcr->VolCatInfo.Slot = loaded; /* We are going to load a new tape, so close the device */ dev->close(dcr); Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"), loaded, dev->drive_index); changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "unload"); status = run_program(changer, timeout, results); Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status); if (status != 0) { berrno be; Pmsg1(-1, _("3992 Bad autochanger command: %s\n"), changer); Pmsg2(-1, _("3992 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status)); } } /* * Load the Slot 1 */ slot = 1; dcr->VolCatInfo.Slot = slot; Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"), slot, dev->drive_index); changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "load"); Dmsg1(100, "Changer=%s\n", changer); dev->close(dcr); status = run_program(changer, timeout, results); if (status == 0) { Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"), slot, dev->drive_index); } else { berrno be; Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer); Pmsg2(-1, _("3993 result=\"%s\": ERR=%s\n"), results, be.bstrerror(status)); goto bail_out; } if (!open_the_device()) { goto bail_out; } /* * Start with sleep_time 0 then increment by 30 seconds if we get * a failure. */ bmicrosleep(sleep_time, 0); if (!dev->rewind(dcr) || !dev->weof(1)) { Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror()); dev->clrerror(-1); Pmsg0(-1, _("\nThe test failed, probably because you need to put\n" "a longer sleep time in the mtx-script in the load) case.\n" "Adding a 30 second sleep and trying again ...\n")); sleep_time += 30; goto try_again; } else { Pmsg1(0, _("Rewound %s\n"), dev->print_name()); } if (!dev->weof(1)) { Pmsg1(0, _("Bad status from weof. ERR=%s\n"), dev->bstrerror()); goto bail_out; } else { Pmsg1(0, _("Wrote EOF to %s\n"), dev->print_name()); } if (sleep_time) { Pmsg1(-1, _("\nThe test worked this time. Please add:\n\n" " sleep %d\n\n" "to your mtx-changer script in the load) case.\n\n"), sleep_time); } else { Pmsg0(-1, _("\nThe test autochanger worked!!\n\n")); } free_pool_memory(changer); free_pool_memory(results); return 1; bail_out: free_pool_memory(changer); free_pool_memory(results); Pmsg0(-1, _("You must correct this error or the Autochanger will not work.\n")); return -2; } static void autochangercmd() { autochanger_test(); } /* * This test assumes that the append test has been done, * then it tests the fsf function. */ static bool fsf_test() { bool set_off = false; Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n" "This test is essential to Bareos.\n\n" "I'm going to write five files then test forward spacing\n\n")); argc = 1; rewindcmd(); wrcmd(); weofcmd(); /* end file 0 */ wrcmd(); wrcmd(); weofcmd(); /* end file 1 */ wrcmd(); wrcmd(); wrcmd(); weofcmd(); /* end file 2 */ wrcmd(); wrcmd(); weofcmd(); /* end file 3 */ wrcmd(); weofcmd(); /* end file 4 */ if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } test_again: rewindcmd(); Pmsg0(0, _("Now forward spacing 1 file.\n")); if (!dev->fsf(1)) { Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg2(-1, _("We should be in file 1. I am at file %d. %s\n"), dev->file, dev->file == 1 ? _("This is correct!") : _("This is NOT correct!!!!")); if (dev->file != 1) { goto bail_out; } Pmsg0(0, _("Now forward spacing 2 files.\n")); if (!dev->fsf(2)) { Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg2(-1, _("We should be in file 3. I am at file %d. %s\n"), dev->file, dev->file == 3 ? _("This is correct!") : _("This is NOT correct!!!!")); if (dev->file != 3) { goto bail_out; } rewindcmd(); Pmsg0(0, _("Now forward spacing 4 files.\n")); if (!dev->fsf(4)) { Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg2(-1, _("We should be in file 4. I am at file %d. %s\n"), dev->file, dev->file == 4 ? _("This is correct!") : _("This is NOT correct!!!!")); if (dev->file != 4) { goto bail_out; } if (set_off) { Pmsg0(-1, _("The test worked this time. Please add:\n\n" " Fast Forward Space File = no\n\n" "to your Device resource for this drive.\n")); } Pmsg0(-1, "\n"); Pmsg0(0, _("Now forward spacing 1 more file.\n")); if (!dev->fsf(1)) { Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror()); } Pmsg2(-1, _("We should be in file 5. I am at file %d. %s\n"), dev->file, dev->file == 5 ? _("This is correct!") : _("This is NOT correct!!!!")); if (dev->file != 5) { goto bail_out; } Pmsg0(-1, _("\n=== End Forward space files test ===\n\n")); return true; bail_out: Pmsg0(-1, _("\nThe forward space file test failed.\n")); if (dev->has_cap(CAP_FASTFSF)) { Pmsg0(-1, _("You have Fast Forward Space File enabled.\n" "I am turning it off then retrying the test.\n")); dev->clear_cap(CAP_FASTFSF); set_off = true; goto test_again; } Pmsg0(-1, _("You must correct this error or Bareos will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n")); return false; } /* * This is a general test of Bareos's functions * needed to read and write the tape. */ static void testcmd() { int status; if (!write_read_test()) { exit_code = 1; return; } if (!position_test()) { exit_code = 1; return; } status = append_test(); if (status == 1) { /* OK get out */ goto all_done; } if (status == -1) { /* first test failed */ if (dev->has_cap(CAP_EOM) || dev->has_cap(CAP_FASTFSF)) { Pmsg0(-1, _("\nAppend test failed. Attempting again.\n" "Setting \"Hardware End of Medium = no\n" " and \"Fast Forward Space File = no\n" "and retrying append test.\n\n")); dev->clear_cap(CAP_EOM); /* turn off eom */ dev->clear_cap(CAP_FASTFSF); /* turn off fast fsf */ status = append_test(); if (status == 1) { Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n" " Hardware End of Medium = No\n\n" " Fast Forward Space File = No\n" "to your Device resource in the Storage conf file.\n")); goto all_done; } if (status == -1) { Pmsg0(-1, _("\n\nThat appears *NOT* to have corrected the problem.\n")); goto failed; } /* Wrong count after append */ if (status == -2) { Pmsg0(-1, _("\n\nIt looks like the append failed. Attempting again.\n" "Setting \"BSF at EOM = yes\" and retrying append test.\n")); dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */ status = append_test(); if (status == 1) { Pmsg0(-1, _("\n\nIt looks like the test worked this time, please add:\n\n" " Hardware End of Medium = No\n" " Fast Forward Space File = No\n" " BSF at EOM = yes\n\n" "to your Device resource in the Storage conf file.\n")); goto all_done; } } } failed: Pmsg0(-1, _("\nAppend test failed.\n\n" "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "Unable to correct the problem. You MUST fix this\n" "problem before Bareos can use your tape drive correctly\n" "\nPerhaps running Bareos in fixed block mode will work.\n" "Do so by setting:\n\n" "Minimum Block Size = nnn\n" "Maximum Block Size = nnn\n\n" "in your Storage daemon's Device definition.\n" "nnn must match your tape driver's block size, which\n" "can be determined by reading your tape manufacturers\n" "information, and the information on your kernel dirver.\n" "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n")); exit_code = 1; return; } all_done: Pmsg0(-1, _("\nThe above Bareos scan should have output identical to what follows.\n" "Please double check it ...\n" "=== Sample correct output ===\n" "1 block of 64448 bytes in file 1\n" "End of File mark.\n" "2 blocks of 64448 bytes in file 2\n" "End of File mark.\n" "3 blocks of 64448 bytes in file 3\n" "End of File mark.\n" "1 block of 64448 bytes in file 4\n" "End of File mark.\n" "Total files=4, blocks=7, bytes = 451,136\n" "=== End sample correct output ===\n\n" "If the above scan output is not identical to the\n" "sample output, you MUST correct the problem\n" "or Bareos will not be able to write multiple Jobs to \n" "the tape.\n\n")); if (status == 1) { if (!re_read_block_test()) { exit_code = 1; } } if (!fsf_test()) { /* do fast forward space file test */ exit_code = 1; } autochanger_test(); /* do autochanger test */ } /* Forward space a file */ static void fsfcmd() { int num = 1; if (argc > 1) { num = atoi(argk[1]); } if (num <= 0) { num = 1; } if (!dev->fsf(num)) { Pmsg1(0, _("Bad status from fsf. ERR=%s\n"), dev->bstrerror()); return; } if (num == 1) { Pmsg0(0, _("Forward spaced 1 file.\n")); } else { Pmsg1(0, _("Forward spaced %d files.\n"), num); } } /* Forward space a record */ static void fsrcmd() { int num = 1; if (argc > 1) { num = atoi(argk[1]); } if (num <= 0) { num = 1; } if (!dev->fsr(num)) { Pmsg1(0, _("Bad status from fsr. ERR=%s\n"), dev->bstrerror()); return; } if (num == 1) { Pmsg0(0, _("Forward spaced 1 record.\n")); } else { Pmsg1(0, _("Forward spaced %d records.\n"), num); } } /* * Read a Bareos block from the tape */ static void rbcmd() { dev->open(dcr, OPEN_READ_ONLY); dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK); } /* * Write a Bareos block to the tape */ static void wrcmd() { DEV_BLOCK *block = dcr->block; DEV_RECORD *rec = dcr->rec; int i; if (!dev->is_open()) { open_the_device(); } Dsm_check(200); empty_block(block); if (verbose > 1) { dump_block(block, "test"); } i = block->buf_len - 100; ASSERT (i > 0); rec->data = check_pool_memory_size(rec->data, i); memset(rec->data, i & 0xFF, i); rec->data_len = i; Dsm_check(200); if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } else { Pmsg1(0, _("Wrote one record of %d bytes.\n"), i); } Pmsg0(0, _("Wrote block to device.\n")); bail_out: Dsm_check(200); } /* * Read a record from the tape */ static void rrcmd() { char *buf; int status, len; if (!get_cmd(_("Enter length to read: "))) { return; } len = atoi(cmd); if (len < 0 || len > 1000000) { Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n")); len = 1024; } buf = (char *)malloc(len); status = read(dev->fd(), buf, len); if (status > 0 && status <= len) { errno = 0; } berrno be; Pmsg3(0, _("Read of %d bytes gives status=%d. ERR=%s\n"), len, status, be.bstrerror()); free(buf); } /* * Scan tape by reading block by block. Report what is * on the tape. Note, this command does raw reads, and as such * will not work with fixed block size devices. */ static void scancmd() { int status; int blocks, tot_blocks, tot_files; int block_size; uint64_t bytes; char ec1[50]; blocks = block_size = tot_blocks = 0; bytes = 0; if (dev->at_eot()) { Pmsg0(0, _("End of tape\n")); return; } dev->update_pos(dcr); tot_files = dev->file; Pmsg1(0, _("Starting scan at file %u\n"), dev->file); for (;;) { if ((status = read(dev->fd(), buf, sizeof(buf))) < 0) { berrno be; dev->clrerror(-1); Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"), dev->dev_name, be.bstrerror()); Pmsg2(0, _("Bad status from read %d. ERR=%s\n"), status, dev->bstrerror()); if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); } else { printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file); } } return; } Dmsg1(200, "read status = %d\n", status); /* sleep(1); */ if (status != block_size) { dev->update_pos(dcr); if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); } else { printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file); } blocks = 0; } block_size = status; } if (status == 0) { /* EOF */ dev->update_pos(dcr); printf(_("End of File mark.\n")); /* Two reads of zero means end of tape */ if (dev->at_eof()) { dev->set_eot(); } else { dev->set_eof(); dev->file++; } if (dev->at_eot()) { printf(_("End of tape\n")); break; } } else { /* Got data */ dev->clear_eof(); blocks++; tot_blocks++; bytes += status; } } dev->update_pos(dcr); tot_files = dev->file - tot_files; printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks, edit_uint64_with_commas(bytes, ec1)); } /* * Scan tape by reading Bareos block by block. Report what is * on the tape. This function reads Bareos blocks, so if your * Device resource is correctly defined, it should work with * either variable or fixed block sizes. */ static void scan_blocks() { int blocks, tot_blocks, tot_files; uint32_t block_size; uint64_t bytes; DEV_BLOCK *block = dcr->block; char ec1[50]; char buf1[100], buf2[100]; blocks = block_size = tot_blocks = 0; bytes = 0; empty_block(block); dev->update_pos(dcr); tot_files = dev->file; for (;;) { if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror()); if (dev->at_eot()) { if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); } else { printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file); } blocks = 0; } goto bail_out; } if (dev->at_eof()) { if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); } else { printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file); } blocks = 0; } printf(_("End of File mark.\n")); continue; } if (dev->state & ST_SHORT) { if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); } else { printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file); } blocks = 0; } printf(_("Short block read.\n")); continue; } printf(_("Error reading block. ERR=%s\n"), dev->bstrerror()); goto bail_out; } if (block->block_len != block_size) { if (blocks > 0) { if (blocks==1) { printf(_("1 block of %d bytes in file %d\n"), block_size, dev->file); } else { printf(_("%d blocks of %d bytes in file %d\n"), blocks, block_size, dev->file); } blocks = 0; } block_size = block->block_len; } blocks++; tot_blocks++; bytes += block->block_len; Dmsg7(100, "Blk_blk=%u file,blk=%u,%u blen=%u bVer=%d SessId=%u SessTim=%u\n", block->BlockNumber, dev->file, dev->block_num, block->block_len, block->BlockVer, block->VolSessionId, block->VolSessionTime); if (verbose == 1) { DEV_RECORD *rec = new_record(); read_record_from_block(dcr, rec); Pmsg9(-1, _("Block=%u file,blk=%u,%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"), block->BlockNumber, dev->file, dev->block_num, block->block_len, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); rec->remainder = 0; free_record(rec); } else if (verbose > 1) { dump_block(block, ""); } } bail_out: tot_files = dev->file - tot_files; printf(_("Total files=%d, blocks=%d, bytes = %s\n"), tot_files, tot_blocks, edit_uint64_with_commas(bytes, ec1)); } static void statcmd() { int debug = debug_level; debug_level = 30; Pmsg2(0, _("Device status: %u. ERR=%s\n"), dev->status_dev(), dev->bstrerror()); #ifdef xxxx dump_volume_label(dev); #endif debug_level = debug; } /* * First we label the tape, then we fill * it with data get a new tape and write a few blocks. */ static void fillcmd() { DEV_RECORD rec; DEV_BLOCK *block = dcr->block; char ec1[50], ec2[50]; char buf1[100], buf2[100]; uint64_t write_eof; uint64_t rate; uint32_t min_block_size; int fd; ok = true; stop = 0; vol_num = 0; last_file = 0; last_block_num = 0; BlockNumber = 0; exit_code = 0; Pmsg1(-1, _("\n" "This command simulates Bareos writing to a tape.\n" "It requires either one or two blank tapes, which it\n" "will label and write.\n\n" "If you have an autochanger configured, it will use\n" "the tapes that are in slots 1 and 2, otherwise, you will\n" "be prompted to insert the tapes when necessary.\n\n" "It will print a status approximately\n" "every 322 MB, and write an EOF every %s. If you have\n" "selected the simple test option, after writing the first tape\n" "it will rewind it and re-read the last block written.\n\n" "If you have selected the multiple tape test, when the first tape\n" "fills, it will ask for a second, and after writing a few more \n" "blocks, it will stop. Then it will begin re-reading the\n" "two tapes.\n\n" "This may take a long time -- hours! ...\n\n"), edit_uint64_with_suffix(dev->max_file_size, buf1)); get_cmd(_("Do you want to run the simplified test (s) with one tape\n" "or the complete multiple tape (m) test: (s/m) ")); if (cmd[0] == 's') { Pmsg0(-1, _("Simple test (single tape) selected.\n")); simple = true; } else if (cmd[0] == 'm') { Pmsg0(-1, _("Multiple tape test selected.\n")); simple = false; } else { Pmsg0(000, _("Command aborted.\n")); exit_code = 1; return; } Dmsg1(20, "Begin append device=%s\n", dev->print_name()); Dmsg1(20, "MaxVolSize=%s\n", edit_uint64(dev->max_volume_size, ec1)); /* Use fixed block size to simplify read back */ min_block_size = dev->min_block_size; dev->min_block_size = dev->max_block_size; write_eof = dev->max_file_size / REC_SIZE; /*compute when we add EOF*/ ASSERT(write_eof > 0); set_volume_name("TestVolume1", 1); dcr->dir_ask_sysop_to_create_appendable_volume(); dev->set_append(); /* force volume to be relabeled */ /* * Acquire output device for writing. Note, after acquiring a * device, we MUST release it, which is done at the end of this * subroutine. */ Dmsg0(100, "just before acquire_device\n"); if (!acquire_device_for_append(dcr)) { jcr->setJobStatus(JS_ErrorTerminated); exit_code = 1; return; } block = jcr->dcr->block; Dmsg0(100, "Just after acquire_device_for_append\n"); /* * Write Begin Session Record */ if (!write_session_label(dcr, SOS_LABEL)) { jcr->setJobStatus(JS_ErrorTerminated); Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"), dev->bstrerror()); ok = false; } Pmsg0(-1, _("Wrote Start of Session label.\n")); memset(&rec, 0, sizeof(rec)); rec.data = get_memory(100000); /* max record size */ rec.data_len = REC_SIZE; /* * Put some random data in the record */ fill_buffer(FILL_RANDOM, rec.data, rec.data_len); /* * Generate data as if from File daemon, write to device */ jcr->dcr->VolFirstIndex = 0; time(&jcr->run_time); /* start counting time for rates */ bstrftime(buf1, sizeof(buf1), jcr->run_time, "%H:%M:%S"); if (simple) { Pmsg1(-1, _("%s Begin writing Bareos records to tape ...\n"), buf1); } else { Pmsg1(-1, _("%s Begin writing Bareos records to first tape ...\n"), buf1); } for (file_index = 0; ok && !job_canceled(jcr); ) { rec.VolSessionId = jcr->VolSessionId; rec.VolSessionTime = jcr->VolSessionTime; rec.FileIndex = ++file_index; rec.Stream = STREAM_FILE_DATA; rec.maskedStream = STREAM_FILE_DATA; /* Mix up the data just a bit */ mix_buffer(FILL_RANDOM, rec.data, rec.data_len); Dmsg4(250, "before write_rec FI=%d SessId=%d Strm=%s len=%d\n", rec.FileIndex, rec.VolSessionId, stream_to_ascii(buf1, rec.Stream, rec.FileIndex), rec.data_len); while (!write_record_to_block(dcr, &rec)) { /* * When we get here we have just filled a block */ Dmsg2(150, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len, rec.remainder); /* Write block to tape */ if (!flush_block(block, 1)) { Pmsg0(000, _("Flush block failed.\n")); exit_code = 1; break; } /* Every 5000 blocks (approx 322MB) report where we are. */ if ((block->BlockNumber % 5000) == 0) { now = time(NULL); now -= jcr->run_time; if (now <= 0) { now = 1; /* prevent divide error */ } rate = dev->VolCatInfo.VolCatBytes / now; Pmsg5(-1, _("Wrote block=%u, file,blk=%u,%u VolBytes=%s rate=%sB/s\n"), block->BlockNumber, dev->file, dev->block_num, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), edit_uint64_with_suffix(rate, ec2)); } /* Every X blocks (dev->max_file_size) write an EOF. */ if ((block->BlockNumber % write_eof) == 0) { now = time(NULL); bstrftime(buf1, sizeof(buf1), now, "%H:%M:%S"); Pmsg1(-1, _("%s Flush block, write EOF\n"), buf1); flush_block(block, 0); #ifdef needed_xxx dev->weof(1); #endif } /* Get out after writing 1000 blocks to the second tape */ if (++BlockNumber > 1000 && stop != 0) { /* get out */ Pmsg0(000, _("Wrote 1000 blocks on second tape. Done.\n")); break; } } if (!ok) { Pmsg0(000, _("Not OK\n")); exit_code = 1; break; } jcr->JobBytes += rec.data_len; /* increment bytes of this job */ Dmsg4(190, "write_record FI=%s SessId=%d Strm=%s len=%d\n", FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId, stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len); /* Get out after writing 1000 blocks to the second tape */ if (BlockNumber > 1000 && stop != 0) { /* get out */ char ed1[50]; Pmsg1(-1, "Done writing %s records ...\n", edit_uint64_with_commas(write_count, ed1)); break; } } /* end big for loop */ if (vol_num > 1) { Dmsg0(100, "Write_end_session_label()\n"); /* Create Job status for end of session label */ if (!job_canceled(jcr) && ok) { jcr->setJobStatus(JS_Terminated); } else if (!ok) { Pmsg0(000, _("Job canceled.\n")); jcr->setJobStatus(JS_ErrorTerminated); exit_code = 1; } if (!write_session_label(dcr, EOS_LABEL)) { Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror()); ok = false; exit_code = 1; } /* Write out final block of this session */ if (!dcr->write_block_to_device()) { Pmsg0(-1, _("Set ok=false after write_block_to_device.\n")); ok = false; exit_code = 1; } Pmsg0(-1, _("Wrote End of Session label.\n")); /* Save last block info for second tape */ last_block_num2 = last_block_num; last_file2 = last_file; if (last_block2) { free_block(last_block2); } last_block2 = dup_block(last_block); } sprintf(buf, "%s/btape.state", working_directory); fd = open(buf, O_CREAT|O_TRUNC|O_WRONLY, 0640); if (fd >= 0) { write(fd, &btape_state_level, sizeof(btape_state_level)); write(fd, &simple, sizeof(simple)); write(fd, &last_block_num1, sizeof(last_block_num1)); write(fd, &last_block_num2, sizeof(last_block_num2)); write(fd, &last_file1, sizeof(last_file1)); write(fd, &last_file2, sizeof(last_file2)); write(fd, last_block1->buf, last_block1->buf_len); write(fd, last_block2->buf, last_block2->buf_len); write(fd, first_block->buf, first_block->buf_len); close(fd); Pmsg2(0, _("Wrote state file last_block_num1=%d last_block_num2=%d\n"), last_block_num1, last_block_num2); } else { berrno be; Pmsg2(0, _("Could not create state file: %s ERR=%s\n"), buf, be.bstrerror()); exit_code = 1; ok = false; } now = time(NULL); bstrftime(buf1, sizeof(buf1), now, "%H:%M:%S"); if (ok) { if (simple) { Pmsg3(0, _("\n\n%s Done filling tape at %d:%d. Now beginning re-read of tape ...\n"), buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num); } else { Pmsg3(0, _("\n\n%s Done filling tapes at %d:%d. Now beginning re-read of first tape ...\n"), buf1, jcr->dcr->dev->file, jcr->dcr->dev->block_num); } jcr->dcr->block = block; if (!do_unfill()) { Pmsg0(000, _("do_unfill failed.\n")); exit_code = 1; ok = false; } } else { Pmsg1(000, _("%s: Error during test.\n"), buf1); } dev->min_block_size = min_block_size; free_memory(rec.data); } /* * Read two tapes written by the "fill" command and ensure * that the data is valid. If stop==1 we simulate full read back * of two tapes. If stop==-1 we simply read the last block and * verify that it is correct. */ static void unfillcmd() { int fd; exit_code = 0; last_block1 = new_block(dev); last_block2 = new_block(dev); first_block = new_block(dev); sprintf(buf, "%s/btape.state", working_directory); fd = open(buf, O_RDONLY); if (fd >= 0) { uint32_t state_level; read(fd, &state_level, sizeof(btape_state_level)); read(fd, &simple, sizeof(simple)); read(fd, &last_block_num1, sizeof(last_block_num1)); read(fd, &last_block_num2, sizeof(last_block_num2)); read(fd, &last_file1, sizeof(last_file1)); read(fd, &last_file2, sizeof(last_file2)); read(fd, last_block1->buf, last_block1->buf_len); read(fd, last_block2->buf, last_block2->buf_len); read(fd, first_block->buf, first_block->buf_len); close(fd); if (state_level != btape_state_level) { Pmsg0(-1, _("\nThe state file level has changed. You must redo\n" "the fill command.\n")); exit_code = 1; return; } } else { berrno be; Pmsg2(-1, _("\nCould not find the state file: %s ERR=%s\n" "You must redo the fill command.\n"), buf, be.bstrerror()); exit_code = 1; return; } if (!do_unfill()) { exit_code = 1; } this_block = NULL; } /* * This is the second part of the fill command. After the tape or * tapes are written, we are called here to reread parts, particularly * the last block. */ static bool do_unfill() { DEV_BLOCK *block = dcr->block; int autochanger; bool rc = false; dumped = 0; VolBytes = 0; LastBlock = 0; Pmsg0(000, "Enter do_unfill\n"); dev->set_cap(CAP_ANONVOLS); /* allow reading any volume */ dev->clear_cap(CAP_LABEL); /* don't label anything here */ end_of_tape = 0; time(&jcr->run_time); /* start counting time for rates */ stop = 0; file_index = 0; if (last_block) { free_block(last_block); last_block = NULL; } last_block_num = last_block_num1; last_file = last_file1; last_block = last_block1; free_restore_volume_list(jcr); jcr->bsr = NULL; bstrncpy(dcr->VolumeName, "TestVolume1|TestVolume2", sizeof(dcr->VolumeName)); create_restore_volume_list(jcr); if (jcr->VolList != NULL) { jcr->VolList->Slot = 1; if (jcr->VolList->next != NULL) { jcr->VolList->next->Slot = 2; } } set_volume_name("TestVolume1", 1); if (!simple) { /* Multiple Volume tape */ /* Close device so user can use autochanger if desired */ if (dev->has_cap(CAP_OFFLINEUNMOUNT)) { dev->offline(); } autochanger = autoload_device(dcr, 1, NULL); if (autochanger != 1) { Pmsg1(100, "Autochanger returned: %d\n", autochanger); dev->close(dcr); get_cmd(_("Mount first tape. Press enter when ready: ")); Pmsg0(000, "\n"); } } dev->close(dcr); dev->num_writers = 0; jcr->dcr->clear_will_write(); if (!acquire_device_for_read(dcr)) { Pmsg1(-1, "%s", dev->errmsg); goto bail_out; } /* * We now have the first tape mounted. * Note, re-reading last block may have caused us to * loose track of where we are (block number unknown). */ Pmsg0(-1, _("Rewinding.\n")); if (!dev->rewind(dcr)) { /* get to a known place on tape */ goto bail_out; } /* Read the first 10000 records */ Pmsg2(-1, _("Reading the first 10000 records from %u:%u.\n"), dev->file, dev->block_num); quickie_count = 0; read_records(dcr, quickie_cb, my_mount_next_read_volume); Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num, last_file, last_block_num); if (!dev->reposition(dcr, last_file, last_block_num)) { Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg1(-1, _("Reading block %u.\n"), last_block_num); if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror()); goto bail_out; } if (compare_blocks(last_block, block)) { if (simple) { Pmsg0(-1, _("\nThe last block on the tape matches. Test succeeded.\n\n")); rc = true; } else { Pmsg0(-1, _("\nThe last block of the first tape matches.\n\n")); } } if (simple) { goto bail_out; } /* restore info for last block on second Volume */ last_block_num = last_block_num2; last_file = last_file2; last_block = last_block2; /* Multiple Volume tape */ /* Close device so user can use autochanger if desired */ if (dev->has_cap(CAP_OFFLINEUNMOUNT)) { dev->offline(); } set_volume_name("TestVolume2", 2); autochanger = autoload_device(dcr, 1, NULL); if (autochanger != 1) { Pmsg1(100, "Autochanger returned: %d\n", autochanger); dev->close(dcr); get_cmd(_("Mount second tape. Press enter when ready: ")); Pmsg0(000, "\n"); } dev->clear_read(); if (!acquire_device_for_read(dcr)) { Pmsg1(-1, "%s", dev->errmsg); goto bail_out; } /* Space to "first" block which is last block not written * on the previous tape. */ Pmsg2(-1, _("Reposition from %u:%u to 0:1\n"), dev->file, dev->block_num); if (!dev->reposition(dcr, 0, 1)) { Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg1(-1, _("Reading block %d.\n"), dev->block_num); if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror()); goto bail_out; } if (compare_blocks(first_block, block)) { Pmsg0(-1, _("\nThe first block on the second tape matches.\n\n")); } /* Now find and compare the last block */ Pmsg4(-1, _("Reposition from %u:%u to %u:%u\n"), dev->file, dev->block_num, last_file, last_block_num); if (!dev->reposition(dcr, last_file, last_block_num)) { Pmsg1(-1, _("Reposition error. ERR=%s\n"), dev->bstrerror()); goto bail_out; } Pmsg1(-1, _("Reading block %d.\n"), dev->block_num); if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) { Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror()); goto bail_out; } if (compare_blocks(last_block, block)) { Pmsg0(-1, _("\nThe last block on the second tape matches. Test succeeded.\n\n")); rc = true; } bail_out: free_block(last_block1); free_block(last_block2); free_block(first_block); last_block1 = NULL; last_block2 = NULL; last_block = NULL; first_block = NULL; return rc; } /* Read 10000 records then stop */ static bool quickie_cb(DCR *dcr, DEV_RECORD *rec) { DEVICE *dev = dcr->dev; quickie_count++; if (quickie_count == 10000) { Pmsg2(-1, _("10000 records read now at %d:%d\n"), dev->file, dev->block_num); } return quickie_count < 10000; } static bool compare_blocks(DEV_BLOCK *last_block, DEV_BLOCK *block) { char *p, *q; union { uint32_t CheckSum; uint32_t block_len; }; ser_declare; p = last_block->buf; q = block->buf; unser_begin(q, BLKHDR2_LENGTH); unser_uint32(CheckSum); unser_uint32(block_len); while (q < (block->buf+block_len)) { if (*p == *q) { p++; q++; continue; } Pmsg0(-1, "\n"); dump_block(last_block, _("Last block written")); Pmsg0(-1, "\n"); dump_block(block, _("Block read back")); Pmsg1(-1, _("\n\nThe blocks differ at byte %u\n"), p - last_block->buf); Pmsg0(-1, _("\n\n!!!! The last block written and the block\n" "that was read back differ. The test FAILED !!!!\n" "This must be corrected before you use Bareos\n" "to write multi-tape Volumes.!!!!\n")); return false; } if (verbose) { dump_block(last_block, _("Last block written")); dump_block(block, _("Block read back")); } return true; } /* * Write current block to tape regardless of whether or * not it is full. If the tape fills, attempt to * acquire another tape. */ static int flush_block(DEV_BLOCK *block, int dump) { char ec1[50], ec2[50]; uint64_t rate; DEV_BLOCK *tblock; uint32_t this_file, this_block_num; dev->rLock(); if (!this_block) { this_block = new_block(dev); } if (!last_block) { last_block = new_block(dev); } /* Copy block */ this_file = dev->file; this_block_num = dev->block_num; if (!dcr->write_block_to_dev()) { Pmsg3(000, _("Last block at: %u:%u this_dev_block_num=%d\n"), last_file, last_block_num, this_block_num); if (vol_num == 1) { /* * This is 1st tape, so save first tape info separate * from second tape info */ last_block_num1 = last_block_num; last_file1 = last_file; last_block1 = dup_block(last_block); last_block2 = dup_block(last_block); first_block = dup_block(block); /* first block second tape */ } if (verbose) { Pmsg3(000, _("Block not written: FileIndex=%u blk_block=%u Size=%u\n"), (unsigned)file_index, block->BlockNumber, block->block_len); dump_block(last_block, _("Last block written")); Pmsg0(-1, "\n"); dump_block(block, _("Block not written")); } if (stop == 0) { eot_block = block->BlockNumber; eot_block_len = block->block_len; eot_FileIndex = file_index; stop = 1; } now = time(NULL); now -= jcr->run_time; if (now <= 0) { now = 1; /* don't divide by zero */ } rate = dev->VolCatInfo.VolCatBytes / now; vol_size = dev->VolCatInfo.VolCatBytes; Pmsg4(000, _("End of tape %d:%d. Volume Bytes=%s. Write rate = %sB/s\n"), dev->file, dev->block_num, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), edit_uint64_with_suffix(rate, ec2)); if (simple) { stop = -1; /* stop, but do simplified test */ } else { /* Full test in progress */ if (!fixup_device_block_write_error(jcr->dcr)) { Pmsg1(000, _("Cannot fixup device error. %s\n"), dev->bstrerror()); ok = false; dev->Unlock(); return 0; } BlockNumber = 0; /* start counting for second tape */ } dev->Unlock(); return 1; /* end of tape reached */ } /* Save contents after write so that the header is serialized */ memcpy(this_block->buf, block->buf, this_block->buf_len); /* * Note, we always read/write to block, but we toggle * copying it to one or another of two allocated blocks. * Switch blocks so that the block just successfully written is * always in last_block. */ tblock = last_block; last_block = this_block; this_block = tblock; last_file = this_file; last_block_num = this_block_num; dev->Unlock(); return 1; } /* * First we label the tape, then we fill * it with data get a new tape and write a few blocks. */ static void qfillcmd() { DEV_BLOCK *block = dcr->block; DEV_RECORD *rec = dcr->rec; int i, count; Pmsg0(0, _("Test writing blocks of 64512 bytes to tape.\n")); get_cmd(_("How many blocks do you want to write? (1000): ")); count = atoi(cmd); if (count <= 0) { count = 1000; } Dsm_check(200); i = block->buf_len - 100; ASSERT (i > 0); rec->data = check_pool_memory_size(rec->data, i); memset(rec->data, i & 0xFF, i); rec->data_len = i; rewindcmd(); init_speed(); Pmsg1(0, _("Begin writing %d Bareos blocks to tape ...\n"), count); for (i=0; i < count; i++) { if (i % 100 == 0) { printf("+"); fflush(stdout); } if (!write_record_to_block(dcr, rec)) { Pmsg0(0, _("Error writing record to block.\n")); goto bail_out; } if (!dcr->write_block_to_dev()) { Pmsg0(0, _("Error writing block to device.\n")); goto bail_out; } } printf("\n"); print_speed(dev->VolCatInfo.VolCatBytes); weofcmd(); if (dev->has_cap(CAP_TWOEOF)) { weofcmd(); } rewindcmd(); scan_blocks(); bail_out: Dsm_check(200); } /* * Fill a tape using raw write() command */ static void rawfill_cmd() { DEV_BLOCK *block = dcr->block; int status; uint32_t block_num = 0; uint32_t *p; int my_errno; fill_buffer(FILL_RANDOM, block->buf, block->buf_len); init_speed(); p = (uint32_t *)block->buf; Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len); for ( ;; ) { *p = block_num; status = dev->d_write(dev->fd(), block->buf, block->buf_len); if (status == (int)block->buf_len) { if ((block_num++ % 100) == 0) { printf("+"); fflush(stdout); } mix_buffer(FILL_RANDOM, block->buf, block->buf_len); jcr->JobBytes += status; continue; } break; } my_errno = errno; printf("\n"); berrno be; printf(_("Write failed at block %u. status=%d ERR=%s\n"), block_num, status, be.bstrerror(my_errno)); print_speed(jcr->JobBytes); weofcmd(); } struct cmdstruct { const char *key; void (*func)(); const char *help; }; static struct cmdstruct commands[] = { {NT_("autochanger"),autochangercmd, _("test autochanger")}, {NT_("bsf"), bsfcmd, _("backspace file")}, {NT_("bsr"), bsrcmd, _("backspace record")}, {NT_("cap"), capcmd, _("list device capabilities")}, {NT_("clear"), clearcmd, _("clear tape errors")}, {NT_("eod"), eodcmd, _("go to end of Bareos data for append")}, {NT_("eom"), eomcmd, _("go to the physical end of medium")}, {NT_("fill"), fillcmd, _("fill tape, write onto second volume")}, {NT_("unfill"), unfillcmd, _("read filled tape")}, {NT_("fsf"), fsfcmd, _("forward space a file")}, {NT_("fsr"), fsrcmd, _("forward space a record")}, {NT_("help"), helpcmd, _("print this command")}, {NT_("label"), labelcmd, _("write a Bareos label to the tape")}, {NT_("load"), loadcmd, _("load a tape")}, {NT_("quit"), quitcmd, _("quit btape")}, {NT_("rawfill"), rawfill_cmd, _("use write() to fill tape")}, {NT_("readlabel"), readlabelcmd, _("read and print the Bareos tape label")}, {NT_("rectest"), rectestcmd, _("test record handling functions")}, {NT_("rewind"), rewindcmd, _("rewind the tape")}, {NT_("scan"), scancmd, _("read() tape block by block to EOT and report")}, {NT_("scanblocks"),scan_blocks, _("Bareos read block by block to EOT and report")}, {NT_("speed"), speed_test, _("[file_size=n(GB)|nb_file=3|skip_zero|skip_random|skip_raw|skip_block] report drive speed")}, {NT_("status"), statcmd, _("print tape status")}, {NT_("test"), testcmd, _("General test Bareos tape functions")}, {NT_("weof"), weofcmd, _("write an EOF on the tape")}, {NT_("wr"), wrcmd, _("write a single Bareos block")}, {NT_("rr"), rrcmd, _("read a single record")}, {NT_("rb"), rbcmd, _("read a single Bareos block")}, {NT_("qfill"), qfillcmd, _("quick fill command")} }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) static void do_tape_cmds() { unsigned int i; bool found; while (!quit && get_cmd("*")) { Dsm_check(200); found = false; parse_args(cmd, &args, &argc, argk, argv, MAX_CMD_ARGS); for (i=0; i 0 && fstrsch(argk[0], commands[i].key)) { (*commands[i].func)(); /* go execute command */ found = true; break; } if (*cmd && !found) { Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd); } } } static void helpcmd() { unsigned int i; usage(); printf(_("Interactive commands:\n")); printf(_(" Command Description\n ======= ===========\n")); for (i=0; i \n" " -b specify bootstrap file\n" " -c set Storage configuration file to file\n" " -D specify a director name specified in the Storage\n" " configuration file for the Key Encryption Key selection\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -p proceed inspite of I/O errors\n" " -s turn off signals\n" " -v be verbose\n" " -? print this message.\n" "\n"), 2000, VERSION, BDATE); } /* * Get next input command from terminal. This * routine is REALLY primitive, and should be enhanced * to have correct backspacing, etc. */ int get_cmd(const char *prompt) { int i = 0; int ch; fprintf(stdout, "%s", prompt); /* We really should turn off echoing and pretty this * up a bit. */ cmd[i] = 0; while ((ch = fgetc(stdin)) != EOF) { if (ch == '\n') { strip_trailing_junk(cmd); return 1; } else if (ch == 4 || ch == 0xd3 || ch == 0x8) { if (i > 0) { cmd[--i] = 0; } continue; } cmd[i++] = ch; cmd[i] = 0; } quit = 1; return 0; } bool BTAPE_DCR::dir_create_jobmedia_record(bool zero) { WroteVol = false; return 1; } bool BTAPE_DCR::dir_find_next_appendable_volume() { Dmsg1(20, "Enter dir_find_next_appendable_volume. stop=%d\n", stop); return VolumeName[0] != 0; } bool BTAPE_DCR::dir_ask_sysop_to_mount_volume(int mode) { Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n"); if (VolumeName[0] == 0) { return dir_ask_sysop_to_create_appendable_volume(); } Pmsg1(-1, "%s", dev->errmsg); /* print reason */ if (VolumeName[0] == 0 || bstrcmp(VolumeName, "TestVolume2")) { fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "), dev->print_name()); } else { fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "), VolumeName, dev->print_name()); } dev->close(this); getchar(); return true; } bool BTAPE_DCR::dir_ask_sysop_to_create_appendable_volume() { int autochanger; Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n"); if (stop == 0) { set_volume_name("TestVolume1", 1); } else { set_volume_name("TestVolume2", 2); } /* Close device so user can use autochanger if desired */ if (dev->has_cap(CAP_OFFLINEUNMOUNT)) { dev->offline(); } autochanger = autoload_device(this, 1, NULL); if (autochanger != 1) { Pmsg1(100, "Autochanger returned: %d\n", autochanger); fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "), dev->print_name()); dev->close(this); getchar(); Pmsg0(000, "\n"); } labelcmd(); volumename = NULL; BlockNumber = 0; return true; } DCR *BTAPE_DCR::get_new_spooling_dcr() { DCR *dcr; dcr = New(BTAPE_DCR); return dcr; } static bool my_mount_next_read_volume(DCR *dcr) { char ec1[50], ec2[50]; uint64_t rate; JCR *jcr = dcr->jcr; DEV_BLOCK *block = dcr->block; Dmsg0(20, "Enter my_mount_next_read_volume\n"); Pmsg2(000, _("End of Volume \"%s\" %d records.\n"), dcr->VolumeName, quickie_count); volume_unused(dcr); /* release current volume */ if (LastBlock != block->BlockNumber) { VolBytes += block->block_len; } LastBlock = block->BlockNumber; now = time(NULL); now -= jcr->run_time; if (now <= 0) { now = 1; } rate = VolBytes / now; Pmsg3(-1, _("Read block=%u, VolBytes=%s rate=%sB/s\n"), block->BlockNumber, edit_uint64_with_commas(VolBytes, ec1), edit_uint64_with_suffix(rate, ec2)); if (bstrcmp(dcr->VolumeName, "TestVolume2")) { end_of_tape = 1; return false; } set_volume_name("TestVolume2", 2); dev->close(dcr); if (!acquire_device_for_read(dcr)) { Pmsg2(0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName); return false; } return true; /* next volume mounted */ } static void set_volume_name(const char *VolName, int volnum) { DCR *dcr = jcr->dcr; volumename = VolName; vol_num = volnum; dev->setVolCatName(VolName); dcr->setVolCatName(VolName); bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName)); dcr->VolCatInfo.Slot = volnum; dcr->VolCatInfo.InChanger = true; } bareos-Release-14.2.6/src/stored/butil.c000066400000000000000000000215621263011562700200200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Utility routines for "tool" programs such as bscan, bls, * bextract, ... Some routines also used by Bareos. * * Kern Sibbald, MM * * Normally nothing in this file is called by the Storage * daemon because we interact more directly with the user * i.e. printf, ... */ #include "bareos.h" #include "stored.h" /* Forward referenced functions */ static bool setup_to_access_device(DCR *dcr, JCR *jcr, char *dev_name, const char *VolumeName, bool readonly); static DEVRES *find_device_res(char *device_name, bool readonly); static void my_free_jcr(JCR *jcr); /* Global variables */ char SD_IMP_EXP *configfile; STORES SD_IMP_EXP *me = NULL; /* Our Global resource */ CONFIG SD_IMP_EXP *my_config = NULL; /* Our Global config */ #ifdef DEBUG char *rec_state_bits_to_str(DEV_RECORD *rec) { static char buf[200]; buf[0] = 0; if (rec->state_bits & REC_NO_HEADER) { strcat(buf, _("Nohdr,")); } if (is_partial_record(rec)) { strcat(buf, _("partial,")); } if (rec->state_bits & REC_BLOCK_EMPTY) { strcat(buf, _("empty,")); } if (rec->state_bits & REC_NO_MATCH) { strcat(buf, _("Nomatch,")); } if (rec->state_bits & REC_CONTINUATION) { strcat(buf, _("cont,")); } if (buf[0]) { buf[strlen(buf)-1] = 0; } return buf; } #endif /* * Setup a "daemon" JCR for the various standalone * tools (e.g. bls, bextract, bscan, ...) */ JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr, DIRRES *director, DCR *dcr, const char *VolumeName, bool readonly) { JCR *jcr = new_jcr(sizeof(JCR), my_free_jcr); jcr->bsr = bsr; jcr->director = director; jcr->VolSessionId = 1; jcr->VolSessionTime = (uint32_t)time(NULL); jcr->NumReadVolumes = 0; jcr->NumWriteVolumes = 0; jcr->JobId = 0; jcr->setJobType(JT_CONSOLE); jcr->setJobLevel(L_FULL); jcr->JobStatus = JS_Terminated; jcr->where = bstrdup(""); jcr->job_name = get_pool_memory(PM_FNAME); pm_strcpy(jcr->job_name, "Dummy.Job.Name"); jcr->client_name = get_pool_memory(PM_FNAME); pm_strcpy(jcr->client_name, "Dummy.Client.Name"); bstrncpy(jcr->Job, name, sizeof(jcr->Job)); jcr->fileset_name = get_pool_memory(PM_FNAME); pm_strcpy(jcr->fileset_name, "Dummy.fileset.name"); jcr->fileset_md5 = get_pool_memory(PM_FNAME); pm_strcpy(jcr->fileset_md5, "Dummy.fileset.md5"); new_plugins(jcr); /* instantiate plugins */ init_autochangers(); create_volume_lists(); if (!setup_to_access_device(dcr, jcr, dev_name, VolumeName, readonly)) { return NULL; } if (!bsr && VolumeName) { bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName)); } bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name)); bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type)); return jcr; } /* * Setup device, jcr, and prepare to access device. * If the caller wants read access, acquire the device, otherwise, * the caller will do it. */ static bool setup_to_access_device(DCR *dcr, JCR *jcr, char *dev_name, const char *VolumeName, bool readonly) { DEVICE *dev; char *p; DEVRES *device; char VolName[MAX_NAME_LENGTH]; init_reservations_lock(); /* * If no volume name already given and no bsr, and it is a file, * try getting name from Filename */ if (VolumeName) { bstrncpy(VolName, VolumeName, sizeof(VolName)); if (strlen(VolumeName) >= MAX_NAME_LENGTH) { Jmsg0(jcr, M_ERROR, 0, _("Volume name or names is too long. Please use a .bsr file.\n")); } } else { VolName[0] = 0; } if (!jcr->bsr && VolName[0] == 0) { if (!bstrncmp(dev_name, "/dev/", 5)) { /* Try stripping file part */ p = dev_name + strlen(dev_name); while (p >= dev_name && !IsPathSeparator(*p)) p--; if (IsPathSeparator(*p)) { bstrncpy(VolName, p+1, sizeof(VolName)); *p = 0; } } } if ((device = find_device_res(dev_name, readonly)) == NULL) { Jmsg2(jcr, M_FATAL, 0, _("Cannot find device \"%s\" in config file %s.\n"), dev_name, configfile); return false; } dev = init_dev(jcr, device); if (!dev) { Jmsg1(jcr, M_FATAL, 0, _("Cannot init device %s\n"), dev_name); return false; } device->dev = dev; jcr->dcr = dcr; setup_new_dcr_device(jcr, dcr, dev, NULL); if (!readonly) { dcr->set_will_write(); } if (VolName[0]) { bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName)); } bstrncpy(dcr->dev_name, device->device_name, sizeof(dcr->dev_name)); create_restore_volume_list(jcr); if (readonly) { /* read only access? */ Dmsg0(100, "Acquire device for read\n"); if (!acquire_device_for_read(dcr)) { return false; } jcr->read_dcr = dcr; } else { if (!first_open_device(dcr)) { Jmsg1(jcr, M_FATAL, 0, _("Cannot open %s\n"), dev->print_name()); return false; } } return true; } /* * Called here when freeing JCR so that we can get rid * of "daemon" specific memory allocated. */ static void my_free_jcr(JCR *jcr) { if (jcr->job_name) { free_pool_memory(jcr->job_name); jcr->job_name = NULL; } if (jcr->client_name) { free_pool_memory(jcr->client_name); jcr->client_name = NULL; } if (jcr->fileset_name) { free_pool_memory(jcr->fileset_name); jcr->fileset_name = NULL; } if (jcr->fileset_md5) { free_pool_memory(jcr->fileset_md5); jcr->fileset_md5 = NULL; } if (jcr->comment) { free_pool_memory(jcr->comment); jcr->comment = NULL; } if (jcr->VolList) { free_restore_volume_list(jcr); } if (jcr->dcr) { free_dcr(jcr->dcr); jcr->dcr = NULL; } return; } /* * Search for device resource that corresponds to * device name on command line (or default). * * Returns: NULL on failure * Device resource pointer on success */ static DEVRES *find_device_res(char *device_name, bool readonly) { bool found = false; DEVRES *device; Dmsg0(900, "Enter find_device_res\n"); LockRes(); foreach_res(device, R_DEVICE) { Dmsg2(900, "Compare %s and %s\n", device->device_name, device_name); if (bstrcmp(device->device_name, device_name)) { found = true; break; } } if (!found) { /* Search for name of Device resource rather than archive name */ if (device_name[0] == '"') { int len = strlen(device_name); bstrncpy(device_name, device_name+1, len+1); len--; if (len > 0) { device_name[len-1] = 0; /* zap trailing " */ } } foreach_res(device, R_DEVICE) { Dmsg2(900, "Compare %s and %s\n", device->hdr.name, device_name); if (bstrcmp(device->hdr.name, device_name)) { found = true; break; } } } UnlockRes(); if (!found) { Pmsg2(0, _("Could not find device \"%s\" in config file %s.\n"), device_name, configfile); return NULL; } if (readonly) { Pmsg1(0, _("Using device: \"%s\" for reading.\n"), device_name); } else { Pmsg1(0, _("Using device: \"%s\" for writing.\n"), device_name); } return device; } /* * Device got an error, attempt to analyse it */ void display_tape_error_status(JCR *jcr, DEVICE *dev) { uint32_t status; status = dev->status_dev(); Dmsg1(20, "Device status: %x\n", status); if (status & BMT_EOD) Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Data\n")); else if (status & BMT_EOT) Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Tape\n")); else if (status & BMT_EOF) Jmsg(jcr, M_ERROR, 0, _("Unexpected End of File\n")); else if (status & BMT_DR_OPEN) Jmsg(jcr, M_ERROR, 0, _("Tape Door is Open\n")); else if (!(status & BMT_ONLINE)) Jmsg(jcr, M_ERROR, 0, _("Unexpected Tape is Off-line\n")); } bareos-Release-14.2.6/src/stored/crc32.c000066400000000000000000000575001263011562700176160ustar00rootroot00000000000000/* crc32.c 32 bit CRC Copyright (C) 2010 Joakim Tjernlund This file 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 3 of the License, or (at your option) any later version. This file 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 Affero General Public License for more details. */ /* * Original 32 bit CRC. Algorithm from RFC 2083 (png format) * By Kern Sibbald, January 2001 * * Inproved, faster version * By Joakim Tjernlunc, 2010 */ #ifdef GENERATE_STATIC_CRC_TABLE /* * The following code can be used to generate the static CRC table. * * Note, the magic number 0xedb88320L below comes from the terms * of the defining polynomial x^n, * where n=0,1,2,4,5,7,8,10,11,12,16,22,23,26 */ #include main() { unsigned long crc; unsigned long buf[5]; int i, j, k; k = 0; for (i = 0; i < 256; i++) { crc = (unsigned long)i; for (j = 0; j < 8; j++) { if (crc & 1) { crc = 0xedb88320L ^ (crc >> 1); } else { crc = crc >> 1; } } buf[k++] = crc; if (k == 5) { k = 0; printf(" 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", buf[0], buf[1], buf[2], buf[3], buf[4]); } } printf(" 0x%08x\n", buf[0]); } #endif #include "bareos.h" #if defined(AC_APPLE_UNIVERSAL_BUILD) #error This code only supports compile time endianess selection not during runtime. #endif #if !defined(HAVE_LITTLE_ENDIAN) && !defined(HAVE_BIG_ENDIAN) #error Either HAVE_LITTLE_ENDIAN or HAVE_BIG_ENDIAN must be defined! #endif /* tole == To Little Endian */ #ifdef HAVE_BIG_ENDIAN #define tole(x) \ ((uint32_t)( \ (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) #else #define tole(x) x #endif /* * The magic number 0xedb88320L below comes from the terms * of the defining polynomial x^n, * where n=0,1,2,4,5,7,8,10,11,12,16,22,23,26 */ static const uint32_t tab[4][256] = {{ tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL), tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L), tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L), tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L), tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL), tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L), tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL), tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L), tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L), tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL), tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L), tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L), tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L), tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL), tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L), tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL), tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL), tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L), tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L), tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L), tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL), tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L), tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL), tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L), tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L), tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL), tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L), tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L), tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L), tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL), tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L), tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL), tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL), tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L), tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L), tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L), tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL), tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L), tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL), tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L), tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L), tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL), tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L), tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L), tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L), tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL), tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L), tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL), tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL), tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L), tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L), tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L), tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL), tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L), tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL), tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L), tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L), tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL), tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L), tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L), tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L), tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL), tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L), tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)}, { tole(0x00000000L), tole(0x191b3141L), tole(0x32366282L), tole(0x2b2d53c3L), tole(0x646cc504L), tole(0x7d77f445L), tole(0x565aa786L), tole(0x4f4196c7L), tole(0xc8d98a08L), tole(0xd1c2bb49L), tole(0xfaefe88aL), tole(0xe3f4d9cbL), tole(0xacb54f0cL), tole(0xb5ae7e4dL), tole(0x9e832d8eL), tole(0x87981ccfL), tole(0x4ac21251L), tole(0x53d92310L), tole(0x78f470d3L), tole(0x61ef4192L), tole(0x2eaed755L), tole(0x37b5e614L), tole(0x1c98b5d7L), tole(0x05838496L), tole(0x821b9859L), tole(0x9b00a918L), tole(0xb02dfadbL), tole(0xa936cb9aL), tole(0xe6775d5dL), tole(0xff6c6c1cL), tole(0xd4413fdfL), tole(0xcd5a0e9eL), tole(0x958424a2L), tole(0x8c9f15e3L), tole(0xa7b24620L), tole(0xbea97761L), tole(0xf1e8e1a6L), tole(0xe8f3d0e7L), tole(0xc3de8324L), tole(0xdac5b265L), tole(0x5d5daeaaL), tole(0x44469febL), tole(0x6f6bcc28L), tole(0x7670fd69L), tole(0x39316baeL), tole(0x202a5aefL), tole(0x0b07092cL), tole(0x121c386dL), tole(0xdf4636f3L), tole(0xc65d07b2L), tole(0xed705471L), tole(0xf46b6530L), tole(0xbb2af3f7L), tole(0xa231c2b6L), tole(0x891c9175L), tole(0x9007a034L), tole(0x179fbcfbL), tole(0x0e848dbaL), tole(0x25a9de79L), tole(0x3cb2ef38L), tole(0x73f379ffL), tole(0x6ae848beL), tole(0x41c51b7dL), tole(0x58de2a3cL), tole(0xf0794f05L), tole(0xe9627e44L), tole(0xc24f2d87L), tole(0xdb541cc6L), tole(0x94158a01L), tole(0x8d0ebb40L), tole(0xa623e883L), tole(0xbf38d9c2L), tole(0x38a0c50dL), tole(0x21bbf44cL), tole(0x0a96a78fL), tole(0x138d96ceL), tole(0x5ccc0009L), tole(0x45d73148L), tole(0x6efa628bL), tole(0x77e153caL), tole(0xbabb5d54L), tole(0xa3a06c15L), tole(0x888d3fd6L), tole(0x91960e97L), tole(0xded79850L), tole(0xc7cca911L), tole(0xece1fad2L), tole(0xf5facb93L), tole(0x7262d75cL), tole(0x6b79e61dL), tole(0x4054b5deL), tole(0x594f849fL), tole(0x160e1258L), tole(0x0f152319L), tole(0x243870daL), tole(0x3d23419bL), tole(0x65fd6ba7L), tole(0x7ce65ae6L), tole(0x57cb0925L), tole(0x4ed03864L), tole(0x0191aea3L), tole(0x188a9fe2L), tole(0x33a7cc21L), tole(0x2abcfd60L), tole(0xad24e1afL), tole(0xb43fd0eeL), tole(0x9f12832dL), tole(0x8609b26cL), tole(0xc94824abL), tole(0xd05315eaL), tole(0xfb7e4629L), tole(0xe2657768L), tole(0x2f3f79f6L), tole(0x362448b7L), tole(0x1d091b74L), tole(0x04122a35L), tole(0x4b53bcf2L), tole(0x52488db3L), tole(0x7965de70L), tole(0x607eef31L), tole(0xe7e6f3feL), tole(0xfefdc2bfL), tole(0xd5d0917cL), tole(0xcccba03dL), tole(0x838a36faL), tole(0x9a9107bbL), tole(0xb1bc5478L), tole(0xa8a76539L), tole(0x3b83984bL), tole(0x2298a90aL), tole(0x09b5fac9L), tole(0x10aecb88L), tole(0x5fef5d4fL), tole(0x46f46c0eL), tole(0x6dd93fcdL), tole(0x74c20e8cL), tole(0xf35a1243L), tole(0xea412302L), tole(0xc16c70c1L), tole(0xd8774180L), tole(0x9736d747L), tole(0x8e2de606L), tole(0xa500b5c5L), tole(0xbc1b8484L), tole(0x71418a1aL), tole(0x685abb5bL), tole(0x4377e898L), tole(0x5a6cd9d9L), tole(0x152d4f1eL), tole(0x0c367e5fL), tole(0x271b2d9cL), tole(0x3e001cddL), tole(0xb9980012L), tole(0xa0833153L), tole(0x8bae6290L), tole(0x92b553d1L), tole(0xddf4c516L), tole(0xc4eff457L), tole(0xefc2a794L), tole(0xf6d996d5L), tole(0xae07bce9L), tole(0xb71c8da8L), tole(0x9c31de6bL), tole(0x852aef2aL), tole(0xca6b79edL), tole(0xd37048acL), tole(0xf85d1b6fL), tole(0xe1462a2eL), tole(0x66de36e1L), tole(0x7fc507a0L), tole(0x54e85463L), tole(0x4df36522L), tole(0x02b2f3e5L), tole(0x1ba9c2a4L), tole(0x30849167L), tole(0x299fa026L), tole(0xe4c5aeb8L), tole(0xfdde9ff9L), tole(0xd6f3cc3aL), tole(0xcfe8fd7bL), tole(0x80a96bbcL), tole(0x99b25afdL), tole(0xb29f093eL), tole(0xab84387fL), tole(0x2c1c24b0L), tole(0x350715f1L), tole(0x1e2a4632L), tole(0x07317773L), tole(0x4870e1b4L), tole(0x516bd0f5L), tole(0x7a468336L), tole(0x635db277L), tole(0xcbfad74eL), tole(0xd2e1e60fL), tole(0xf9ccb5ccL), tole(0xe0d7848dL), tole(0xaf96124aL), tole(0xb68d230bL), tole(0x9da070c8L), tole(0x84bb4189L), tole(0x03235d46L), tole(0x1a386c07L), tole(0x31153fc4L), tole(0x280e0e85L), tole(0x674f9842L), tole(0x7e54a903L), tole(0x5579fac0L), tole(0x4c62cb81L), tole(0x8138c51fL), tole(0x9823f45eL), tole(0xb30ea79dL), tole(0xaa1596dcL), tole(0xe554001bL), tole(0xfc4f315aL), tole(0xd7626299L), tole(0xce7953d8L), tole(0x49e14f17L), tole(0x50fa7e56L), tole(0x7bd72d95L), tole(0x62cc1cd4L), tole(0x2d8d8a13L), tole(0x3496bb52L), tole(0x1fbbe891L), tole(0x06a0d9d0L), tole(0x5e7ef3ecL), tole(0x4765c2adL), tole(0x6c48916eL), tole(0x7553a02fL), tole(0x3a1236e8L), tole(0x230907a9L), tole(0x0824546aL), tole(0x113f652bL), tole(0x96a779e4L), tole(0x8fbc48a5L), tole(0xa4911b66L), tole(0xbd8a2a27L), tole(0xf2cbbce0L), tole(0xebd08da1L), tole(0xc0fdde62L), tole(0xd9e6ef23L), tole(0x14bce1bdL), tole(0x0da7d0fcL), tole(0x268a833fL), tole(0x3f91b27eL), tole(0x70d024b9L), tole(0x69cb15f8L), tole(0x42e6463bL), tole(0x5bfd777aL), tole(0xdc656bb5L), tole(0xc57e5af4L), tole(0xee530937L), tole(0xf7483876L), tole(0xb809aeb1L), tole(0xa1129ff0L), tole(0x8a3fcc33L), tole(0x9324fd72L)}, { tole(0x00000000L), tole(0x01c26a37L), tole(0x0384d46eL), tole(0x0246be59L), tole(0x0709a8dcL), tole(0x06cbc2ebL), tole(0x048d7cb2L), tole(0x054f1685L), tole(0x0e1351b8L), tole(0x0fd13b8fL), tole(0x0d9785d6L), tole(0x0c55efe1L), tole(0x091af964L), tole(0x08d89353L), tole(0x0a9e2d0aL), tole(0x0b5c473dL), tole(0x1c26a370L), tole(0x1de4c947L), tole(0x1fa2771eL), tole(0x1e601d29L), tole(0x1b2f0bacL), tole(0x1aed619bL), tole(0x18abdfc2L), tole(0x1969b5f5L), tole(0x1235f2c8L), tole(0x13f798ffL), tole(0x11b126a6L), tole(0x10734c91L), tole(0x153c5a14L), tole(0x14fe3023L), tole(0x16b88e7aL), tole(0x177ae44dL), tole(0x384d46e0L), tole(0x398f2cd7L), tole(0x3bc9928eL), tole(0x3a0bf8b9L), tole(0x3f44ee3cL), tole(0x3e86840bL), tole(0x3cc03a52L), tole(0x3d025065L), tole(0x365e1758L), tole(0x379c7d6fL), tole(0x35dac336L), tole(0x3418a901L), tole(0x3157bf84L), tole(0x3095d5b3L), tole(0x32d36beaL), tole(0x331101ddL), tole(0x246be590L), tole(0x25a98fa7L), tole(0x27ef31feL), tole(0x262d5bc9L), tole(0x23624d4cL), tole(0x22a0277bL), tole(0x20e69922L), tole(0x2124f315L), tole(0x2a78b428L), tole(0x2bbade1fL), tole(0x29fc6046L), tole(0x283e0a71L), tole(0x2d711cf4L), tole(0x2cb376c3L), tole(0x2ef5c89aL), tole(0x2f37a2adL), tole(0x709a8dc0L), tole(0x7158e7f7L), tole(0x731e59aeL), tole(0x72dc3399L), tole(0x7793251cL), tole(0x76514f2bL), tole(0x7417f172L), tole(0x75d59b45L), tole(0x7e89dc78L), tole(0x7f4bb64fL), tole(0x7d0d0816L), tole(0x7ccf6221L), tole(0x798074a4L), tole(0x78421e93L), tole(0x7a04a0caL), tole(0x7bc6cafdL), tole(0x6cbc2eb0L), tole(0x6d7e4487L), tole(0x6f38fadeL), tole(0x6efa90e9L), tole(0x6bb5866cL), tole(0x6a77ec5bL), tole(0x68315202L), tole(0x69f33835L), tole(0x62af7f08L), tole(0x636d153fL), tole(0x612bab66L), tole(0x60e9c151L), tole(0x65a6d7d4L), tole(0x6464bde3L), tole(0x662203baL), tole(0x67e0698dL), tole(0x48d7cb20L), tole(0x4915a117L), tole(0x4b531f4eL), tole(0x4a917579L), tole(0x4fde63fcL), tole(0x4e1c09cbL), tole(0x4c5ab792L), tole(0x4d98dda5L), tole(0x46c49a98L), tole(0x4706f0afL), tole(0x45404ef6L), tole(0x448224c1L), tole(0x41cd3244L), tole(0x400f5873L), tole(0x4249e62aL), tole(0x438b8c1dL), tole(0x54f16850L), tole(0x55330267L), tole(0x5775bc3eL), tole(0x56b7d609L), tole(0x53f8c08cL), tole(0x523aaabbL), tole(0x507c14e2L), tole(0x51be7ed5L), tole(0x5ae239e8L), tole(0x5b2053dfL), tole(0x5966ed86L), tole(0x58a487b1L), tole(0x5deb9134L), tole(0x5c29fb03L), tole(0x5e6f455aL), tole(0x5fad2f6dL), tole(0xe1351b80L), tole(0xe0f771b7L), tole(0xe2b1cfeeL), tole(0xe373a5d9L), tole(0xe63cb35cL), tole(0xe7fed96bL), tole(0xe5b86732L), tole(0xe47a0d05L), tole(0xef264a38L), tole(0xeee4200fL), tole(0xeca29e56L), tole(0xed60f461L), tole(0xe82fe2e4L), tole(0xe9ed88d3L), tole(0xebab368aL), tole(0xea695cbdL), tole(0xfd13b8f0L), tole(0xfcd1d2c7L), tole(0xfe976c9eL), tole(0xff5506a9L), tole(0xfa1a102cL), tole(0xfbd87a1bL), tole(0xf99ec442L), tole(0xf85cae75L), tole(0xf300e948L), tole(0xf2c2837fL), tole(0xf0843d26L), tole(0xf1465711L), tole(0xf4094194L), tole(0xf5cb2ba3L), tole(0xf78d95faL), tole(0xf64fffcdL), tole(0xd9785d60L), tole(0xd8ba3757L), tole(0xdafc890eL), tole(0xdb3ee339L), tole(0xde71f5bcL), tole(0xdfb39f8bL), tole(0xddf521d2L), tole(0xdc374be5L), tole(0xd76b0cd8L), tole(0xd6a966efL), tole(0xd4efd8b6L), tole(0xd52db281L), tole(0xd062a404L), tole(0xd1a0ce33L), tole(0xd3e6706aL), tole(0xd2241a5dL), tole(0xc55efe10L), tole(0xc49c9427L), tole(0xc6da2a7eL), tole(0xc7184049L), tole(0xc25756ccL), tole(0xc3953cfbL), tole(0xc1d382a2L), tole(0xc011e895L), tole(0xcb4dafa8L), tole(0xca8fc59fL), tole(0xc8c97bc6L), tole(0xc90b11f1L), tole(0xcc440774L), tole(0xcd866d43L), tole(0xcfc0d31aL), tole(0xce02b92dL), tole(0x91af9640L), tole(0x906dfc77L), tole(0x922b422eL), tole(0x93e92819L), tole(0x96a63e9cL), tole(0x976454abL), tole(0x9522eaf2L), tole(0x94e080c5L), tole(0x9fbcc7f8L), tole(0x9e7eadcfL), tole(0x9c381396L), tole(0x9dfa79a1L), tole(0x98b56f24L), tole(0x99770513L), tole(0x9b31bb4aL), tole(0x9af3d17dL), tole(0x8d893530L), tole(0x8c4b5f07L), tole(0x8e0de15eL), tole(0x8fcf8b69L), tole(0x8a809decL), tole(0x8b42f7dbL), tole(0x89044982L), tole(0x88c623b5L), tole(0x839a6488L), tole(0x82580ebfL), tole(0x801eb0e6L), tole(0x81dcdad1L), tole(0x8493cc54L), tole(0x8551a663L), tole(0x8717183aL), tole(0x86d5720dL), tole(0xa9e2d0a0L), tole(0xa820ba97L), tole(0xaa6604ceL), tole(0xaba46ef9L), tole(0xaeeb787cL), tole(0xaf29124bL), tole(0xad6fac12L), tole(0xacadc625L), tole(0xa7f18118L), tole(0xa633eb2fL), tole(0xa4755576L), tole(0xa5b73f41L), tole(0xa0f829c4L), tole(0xa13a43f3L), tole(0xa37cfdaaL), tole(0xa2be979dL), tole(0xb5c473d0L), tole(0xb40619e7L), tole(0xb640a7beL), tole(0xb782cd89L), tole(0xb2cddb0cL), tole(0xb30fb13bL), tole(0xb1490f62L), tole(0xb08b6555L), tole(0xbbd72268L), tole(0xba15485fL), tole(0xb853f606L), tole(0xb9919c31L), tole(0xbcde8ab4L), tole(0xbd1ce083L), tole(0xbf5a5edaL), tole(0xbe9834edL)}, { tole(0x00000000L), tole(0xb8bc6765L), tole(0xaa09c88bL), tole(0x12b5afeeL), tole(0x8f629757L), tole(0x37def032L), tole(0x256b5fdcL), tole(0x9dd738b9L), tole(0xc5b428efL), tole(0x7d084f8aL), tole(0x6fbde064L), tole(0xd7018701L), tole(0x4ad6bfb8L), tole(0xf26ad8ddL), tole(0xe0df7733L), tole(0x58631056L), tole(0x5019579fL), tole(0xe8a530faL), tole(0xfa109f14L), tole(0x42acf871L), tole(0xdf7bc0c8L), tole(0x67c7a7adL), tole(0x75720843L), tole(0xcdce6f26L), tole(0x95ad7f70L), tole(0x2d111815L), tole(0x3fa4b7fbL), tole(0x8718d09eL), tole(0x1acfe827L), tole(0xa2738f42L), tole(0xb0c620acL), tole(0x087a47c9L), tole(0xa032af3eL), tole(0x188ec85bL), tole(0x0a3b67b5L), tole(0xb28700d0L), tole(0x2f503869L), tole(0x97ec5f0cL), tole(0x8559f0e2L), tole(0x3de59787L), tole(0x658687d1L), tole(0xdd3ae0b4L), tole(0xcf8f4f5aL), tole(0x7733283fL), tole(0xeae41086L), tole(0x525877e3L), tole(0x40edd80dL), tole(0xf851bf68L), tole(0xf02bf8a1L), tole(0x48979fc4L), tole(0x5a22302aL), tole(0xe29e574fL), tole(0x7f496ff6L), tole(0xc7f50893L), tole(0xd540a77dL), tole(0x6dfcc018L), tole(0x359fd04eL), tole(0x8d23b72bL), tole(0x9f9618c5L), tole(0x272a7fa0L), tole(0xbafd4719L), tole(0x0241207cL), tole(0x10f48f92L), tole(0xa848e8f7L), tole(0x9b14583dL), tole(0x23a83f58L), tole(0x311d90b6L), tole(0x89a1f7d3L), tole(0x1476cf6aL), tole(0xaccaa80fL), tole(0xbe7f07e1L), tole(0x06c36084L), tole(0x5ea070d2L), tole(0xe61c17b7L), tole(0xf4a9b859L), tole(0x4c15df3cL), tole(0xd1c2e785L), tole(0x697e80e0L), tole(0x7bcb2f0eL), tole(0xc377486bL), tole(0xcb0d0fa2L), tole(0x73b168c7L), tole(0x6104c729L), tole(0xd9b8a04cL), tole(0x446f98f5L), tole(0xfcd3ff90L), tole(0xee66507eL), tole(0x56da371bL), tole(0x0eb9274dL), tole(0xb6054028L), tole(0xa4b0efc6L), tole(0x1c0c88a3L), tole(0x81dbb01aL), tole(0x3967d77fL), tole(0x2bd27891L), tole(0x936e1ff4L), tole(0x3b26f703L), tole(0x839a9066L), tole(0x912f3f88L), tole(0x299358edL), tole(0xb4446054L), tole(0x0cf80731L), tole(0x1e4da8dfL), tole(0xa6f1cfbaL), tole(0xfe92dfecL), tole(0x462eb889L), tole(0x549b1767L), tole(0xec277002L), tole(0x71f048bbL), tole(0xc94c2fdeL), tole(0xdbf98030L), tole(0x6345e755L), tole(0x6b3fa09cL), tole(0xd383c7f9L), tole(0xc1366817L), tole(0x798a0f72L), tole(0xe45d37cbL), tole(0x5ce150aeL), tole(0x4e54ff40L), tole(0xf6e89825L), tole(0xae8b8873L), tole(0x1637ef16L), tole(0x048240f8L), tole(0xbc3e279dL), tole(0x21e91f24L), tole(0x99557841L), tole(0x8be0d7afL), tole(0x335cb0caL), tole(0xed59b63bL), tole(0x55e5d15eL), tole(0x47507eb0L), tole(0xffec19d5L), tole(0x623b216cL), tole(0xda874609L), tole(0xc832e9e7L), tole(0x708e8e82L), tole(0x28ed9ed4L), tole(0x9051f9b1L), tole(0x82e4565fL), tole(0x3a58313aL), tole(0xa78f0983L), tole(0x1f336ee6L), tole(0x0d86c108L), tole(0xb53aa66dL), tole(0xbd40e1a4L), tole(0x05fc86c1L), tole(0x1749292fL), tole(0xaff54e4aL), tole(0x322276f3L), tole(0x8a9e1196L), tole(0x982bbe78L), tole(0x2097d91dL), tole(0x78f4c94bL), tole(0xc048ae2eL), tole(0xd2fd01c0L), tole(0x6a4166a5L), tole(0xf7965e1cL), tole(0x4f2a3979L), tole(0x5d9f9697L), tole(0xe523f1f2L), tole(0x4d6b1905L), tole(0xf5d77e60L), tole(0xe762d18eL), tole(0x5fdeb6ebL), tole(0xc2098e52L), tole(0x7ab5e937L), tole(0x680046d9L), tole(0xd0bc21bcL), tole(0x88df31eaL), tole(0x3063568fL), tole(0x22d6f961L), tole(0x9a6a9e04L), tole(0x07bda6bdL), tole(0xbf01c1d8L), tole(0xadb46e36L), tole(0x15080953L), tole(0x1d724e9aL), tole(0xa5ce29ffL), tole(0xb77b8611L), tole(0x0fc7e174L), tole(0x9210d9cdL), tole(0x2aacbea8L), tole(0x38191146L), tole(0x80a57623L), tole(0xd8c66675L), tole(0x607a0110L), tole(0x72cfaefeL), tole(0xca73c99bL), tole(0x57a4f122L), tole(0xef189647L), tole(0xfdad39a9L), tole(0x45115eccL), tole(0x764dee06L), tole(0xcef18963L), tole(0xdc44268dL), tole(0x64f841e8L), tole(0xf92f7951L), tole(0x41931e34L), tole(0x5326b1daL), tole(0xeb9ad6bfL), tole(0xb3f9c6e9L), tole(0x0b45a18cL), tole(0x19f00e62L), tole(0xa14c6907L), tole(0x3c9b51beL), tole(0x842736dbL), tole(0x96929935L), tole(0x2e2efe50L), tole(0x2654b999L), tole(0x9ee8defcL), tole(0x8c5d7112L), tole(0x34e11677L), tole(0xa9362eceL), tole(0x118a49abL), tole(0x033fe645L), tole(0xbb838120L), tole(0xe3e09176L), tole(0x5b5cf613L), tole(0x49e959fdL), tole(0xf1553e98L), tole(0x6c820621L), tole(0xd43e6144L), tole(0xc68bceaaL), tole(0x7e37a9cfL), tole(0xd67f4138L), tole(0x6ec3265dL), tole(0x7c7689b3L), tole(0xc4caeed6L), tole(0x591dd66fL), tole(0xe1a1b10aL), tole(0xf3141ee4L), tole(0x4ba87981L), tole(0x13cb69d7L), tole(0xab770eb2L), tole(0xb9c2a15cL), tole(0x017ec639L), tole(0x9ca9fe80L), tole(0x241599e5L), tole(0x36a0360bL), tole(0x8e1c516eL), tole(0x866616a7L), tole(0x3eda71c2L), tole(0x2c6fde2cL), tole(0x94d3b949L), tole(0x090481f0L), tole(0xb1b8e695L), tole(0xa30d497bL), tole(0x1bb12e1eL), tole(0x43d23e48L), tole(0xfb6e592dL), tole(0xe9dbf6c3L), tole(0x516791a6L), tole(0xccb0a91fL), tole(0x740cce7aL), tole(0x66b96194L), tole(0xde0506f1L)}, }; /* * Calculate the PNG 32 bit CRC on a buffer */ uint32_t bcrc32(unsigned char*buf, int len) { # ifdef HAVE_LITTLE_ENDIAN # define DO_CRC(x) crc = tab[0][(crc ^ (x)) & 255 ] ^ (crc >> 8) # define DO_CRC4 crc = tab[3][(crc) & 255 ] ^ \ tab[2][(crc >> 8) & 255 ] ^ \ tab[1][(crc >> 16) & 255 ] ^ \ tab[0][(crc >> 24) & 255 ] # else # define DO_CRC(x) crc = tab[0][((crc >> 24) ^ (x)) & 255] ^ (crc << 8) # define DO_CRC4 crc = tab[0][(crc) & 255 ] ^ \ tab[1][(crc >> 8) & 255 ] ^ \ tab[2][(crc >> 16) & 255 ] ^ \ tab[3][(crc >> 24) & 255 ] # endif const uint32_t *b; size_t rem_len; uint32_t crc = tole(~0); /* Align it */ if ((intptr_t)buf & 3 && len) { do { DO_CRC(*buf++); } while ((--len) && ((intptr_t)buf)&3); } rem_len = len & 3; /* load data 32 bits wide, xor data 32 bits wide. */ b = (const uint32_t *)buf; len = len >> 2; for (--b; len; --len) { crc ^= *++b; /* use pre increment for speed */ DO_CRC4; } len = rem_len; /* And the last few bytes */ if (len) { uint8_t *p = (uint8_t *)(b + 1) - 1; do { DO_CRC(*++p); /* use pre increment for speed */ } while (--len); } return tole(crc) ^ ~0; } #ifdef CRC32_SUM static void usage() { fprintf(stderr, "\n" "Usage: crc32 \n" " -? print this message.\n" "\n\n"); exit(1); } /* * Reads a single ASCII file and prints the HEX md5 sum. */ #include int main(int argc, char *argv[]) { FILE *fd; char buf[5000]; int ch; while ((ch = getopt(argc, argv, "h?")) != -1) { switch (ch) { case 'h': case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < 1) { printf("Must have filename\n"); exit(1); } fd = fopen(argv[0], "rb"); if (!fd) { printf("Could not open %s: ERR=%s\n", argv[0], strerror(errno)); exit(1); } uint32_t res; while (fgets(buf, sizeof(buf), fd)) { res = bcrc32((unsigned char *)buf, strlen(buf)); printf("%02x\n", res); } printf(" %s\n", argv[0]); fclose(fd); } #endif bareos-Release-14.2.6/src/stored/dev.c000066400000000000000000001000321263011562700174450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * dev.c -- low level operations on device (storage device) * * Kern Sibbald, MM * * NOTE!!!! None of these routines are reentrant. You must * use dev->rLock() and dev->Unlock() at a higher level, * or use the xxx_device() equivalents. By moving the * thread synchronization to a higher level, we permit * the higher level routines to "seize" the device and * to carry out operations without worrying about who * set what lock (i.e. race conditions). * * Note, this is the device dependent code, and may have * to be modified for each system, but is meant to * be as "generic" as possible. * * The purpose of this code is to develop a SIMPLE Storage * daemon. More complicated coding (double buffering, writer * thread, ...) is left for a later version. */ /* * Handling I/O errors and end of tape conditions are a bit tricky. * This is how it is currently done when writing. * On either an I/O error or end of tape, * we will stop writing on the physical device (no I/O recovery is * attempted at least in this daemon). The state flag will be sent * to include ST_EOT, which is ephemeral, and ST_WEOT, which is * persistent. Lots of routines clear ST_EOT, but ST_WEOT is * cleared only when the problem goes away. Now when ST_WEOT * is set all calls to write_block_to_device() call the fix_up * routine. In addition, all threads are blocked * from writing on the tape by calling lock_dev(), and thread other * than the first thread to hit the EOT will block on a condition * variable. The first thread to hit the EOT will continue to * be able to read and write the tape (he sort of tunnels through * the locking mechanism -- see lock_dev() for details). * * Now presumably somewhere higher in the chain of command * (device.c), someone will notice the EOT condition and * get a new tape up, get the tape label read, and mark * the label for rewriting. Then this higher level routine * will write the unwritten buffer to the new volume. * Finally, he will release * any blocked threads by doing a broadcast on the condition * variable. At that point, we should be totally back in * business with no lost data. */ #include "bareos.h" #include "stored.h" #ifndef HAVE_DYNAMIC_SD_BACKENDS #ifdef HAVE_GFAPI #include "backends/gfapi_device.h" #endif #ifdef HAVE_OBJECTSTORE #include "backends/object_store_device.h" #endif #ifdef HAVE_RADOS #include "backends/rados_device.h" #endif #ifdef HAVE_CEPHFS #include "backends/cephfs_device.h" #endif #include "backends/generic_tape_device.h" #ifdef HAVE_WIN32 #include "backends/win32_tape_device.h" #else #include "backends/unix_fifo_device.h" #include "backends/unix_tape_device.h" #endif #endif /* HAVE_DYNAMIC_SD_BACKENDS */ #ifdef HAVE_WIN32 #include "backends/win32_file_device.h" #else #include "backends/unix_file_device.h" #endif #ifndef O_NONBLOCK #define O_NONBLOCK 0 #endif /* Forward referenced functions */ static const char *modes[] = { "CREATE_READ_WRITE", "OPEN_READ_WRITE", "OPEN_READ_ONLY", "OPEN_WRITE_ONLY" }; const char *DEVICE::mode_to_str(int mode) { static char buf[100]; if (mode < 1 || mode > 4) { bsnprintf(buf, sizeof(buf), "BAD mode=%d", mode); return buf; } return modes[mode - 1]; } static inline DEVICE *m_init_dev(JCR *jcr, DEVRES *device, bool new_init) { struct stat statp; int errstat; DCR *dcr = NULL; DEVICE *dev = NULL; uint32_t max_bs; Dmsg1(400, "max_block_size in device res is %u\n", device->max_block_size); /* * If no device type specified, try to guess */ if (!device->dev_type) { /* * Check that device is available */ if (stat(device->device_name, &statp) < 0) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Unable to stat device %s: ERR=%s\n"), device->device_name, be.bstrerror()); return NULL; } if (S_ISDIR(statp.st_mode)) { device->dev_type = B_FILE_DEV; } else if (S_ISCHR(statp.st_mode)) { device->dev_type = B_TAPE_DEV; } else if (S_ISFIFO(statp.st_mode)) { device->dev_type = B_FIFO_DEV; } else if (!(device->cap_bits & CAP_REQMOUNT)) { Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory, st_mode=%x\n"), device->device_name, statp.st_mode); return NULL; } } /* * See what type of device is wanted. */ switch (device->dev_type) { /* * When using dynamic loading use the init_backend_dev() function * for any type of device not being of the type file. */ #ifndef HAVE_DYNAMIC_SD_BACKENDS #ifdef HAVE_GFAPI case B_GFAPI_DEV: dev = New(gfapi_device); break; #endif #ifdef HAVE_OBJECTSTORE case B_OBJECT_STORE_DEV: dev = New(object_store_device); break; #endif #ifdef HAVE_RADOS case B_RADOS_DEV: dev = New(rados_device); break; #endif #ifdef HAVE_CEPHFS case B_CEPHFS_DEV: dev = New(cephfs_device); break; #endif #ifdef HAVE_WIN32 case B_TAPE_DEV: dev = New(win32_tape_device); break; #else case B_TAPE_DEV: dev = New(unix_tape_device); break; case B_FIFO_DEV: dev = New(unix_fifo_device); break; #endif #endif /* HAVE_DYNAMIC_SD_BACKENDS */ #ifdef HAVE_WIN32 case B_FILE_DEV: dev = New(win32_file_device); break; #else case B_FILE_DEV: dev = New(unix_file_device); break; #endif default: #ifdef HAVE_DYNAMIC_SD_BACKENDS dev = init_backend_dev(jcr, device->dev_type); #endif break; } if (!dev) { Jmsg2(jcr, M_ERROR, 0, _("%s has an unknown device type %d\n"), device->device_name, device->dev_type); return NULL; } dev->clear_slot(); /* unknown */ /* * Copy user supplied device parameters from Resource */ dev->dev_name = get_memory(strlen(device->device_name)+1); pm_strcpy(dev->dev_name, device->device_name); dev->prt_name = get_memory(strlen(device->device_name) + strlen(device->hdr.name) + 20); /* * We edit "Resource-name" (physical-name) */ Mmsg(dev->prt_name, "\"%s\" (%s)", device->hdr.name, device->device_name); Dmsg1(400, "Allocate dev=%s\n", dev->print_name()); dev->capabilities = device->cap_bits; /* * current block sizes */ dev->min_block_size = device->min_block_size; dev->max_block_size = device->max_block_size; dev->max_volume_size = device->max_volume_size; dev->max_file_size = device->max_file_size; dev->max_concurrent_jobs = device->max_concurrent_jobs; dev->volume_capacity = device->volume_capacity; dev->max_rewind_wait = device->max_rewind_wait; dev->max_open_wait = device->max_open_wait; dev->max_open_vols = device->max_open_vols; dev->vol_poll_interval = device->vol_poll_interval; dev->max_spool_size = device->max_spool_size; dev->drive_index = device->drive_index; dev->autoselect = device->autoselect; dev->norewindonclose = device->norewindonclose; dev->dev_type = device->dev_type; dev->device = device; /* * Sanity check */ if (dev->vol_poll_interval && dev->vol_poll_interval < 60) { dev->vol_poll_interval = 60; } device->dev = dev; if (dev->is_fifo()) { dev->capabilities |= CAP_STREAM; /* set stream device */ } /* * If the device requires mount : * - Check that the mount point is available * - Check that (un)mount commands are defined */ if (dev->is_file() && dev->requires_mount()) { if (!device->mount_point || stat(device->mount_point, &statp) < 0) { berrno be; dev->dev_errno = errno; Jmsg2(jcr, M_ERROR_TERM, 0, _("Unable to stat mount point %s: ERR=%s\n"), device->mount_point, be.bstrerror()); } if (!device->mount_command || !device->unmount_command) { Jmsg0(jcr, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n")); } } /* * Sanity check */ if (dev->max_block_size == 0) { max_bs = DEFAULT_BLOCK_SIZE; } else { max_bs = dev->max_block_size; } if (dev->min_block_size > max_bs) { Jmsg(jcr, M_ERROR_TERM, 0, _("Min block size > max on device %s\n"), dev->print_name()); } if (dev->max_block_size > MAX_BLOCK_LENGTH) { Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"), dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE); dev->max_block_size = 0; } if (dev->max_block_size % TAPE_BSIZE != 0) { Jmsg3(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size=%d.\n"), dev->max_block_size, dev->print_name(), TAPE_BSIZE); } if (dev->max_volume_size != 0 && dev->max_volume_size < (dev->max_block_size << 4)) { Jmsg(jcr, M_ERROR_TERM, 0, _("Max Vol Size < 8 * Max Block Size for device %s\n"), dev->print_name()); } dev->errmsg = get_pool_memory(PM_EMSG); *dev->errmsg = 0; if ((errstat = dev->init_mutex()) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init spool mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } if ((errstat = dev->init_acquire_mutex()) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init acquire mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } if ((errstat = dev->init_read_acquire_mutex()) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init read acquire mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } dev->set_mutex_priorities(); #ifdef xxx if ((errstat = rwl_init(&dev->lock)) != 0) { berrno be; dev->dev_errno = errstat; Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat)); Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg); } #endif dev->clear_opened(); dev->attached_dcrs = New(dlist(dcr, &dcr->dev_link)); Dmsg2(100, "init_dev: tape=%d dev_name=%s\n", dev->is_tape(), dev->dev_name); dev->initiated = true; Dmsg3(100, "dev=%s dev_max_bs=%u max_bs=%u\n", dev->dev_name, dev->device->max_block_size, dev->max_block_size); return dev; } /* * Allocate and initialize the DEVICE structure * Note, if dev is non-NULL, it is already allocated, * thus we neither allocate it nor free it. This allows * the caller to put the packet in shared memory. * * Note, for a tape, the device->device_name is the device name * (e.g. /dev/nst0), and for a file, the device name * is the directory in which the file will be placed. */ DEVICE *init_dev(JCR *jcr, DEVRES *device) { DEVICE *dev; dev = m_init_dev(jcr, device, false); return dev; } /* * Set the block size of the device. * If the volume block size is zero, we set the max block size to what is * configured in the device resource i.e. dev->device->max_block_size. * * If dev->device->max_block_size is zero, do nothing and leave dev->max_block_size as it is. */ void DEVICE::set_blocksizes(DCR *dcr) { DEVICE* dev = this; JCR* jcr = dcr->jcr; uint32_t max_bs; Dmsg4(100, "Device %s has dev->device->max_block_size of %u and dev->max_block_size of %u, dcr->VolMaxBlocksize is %u\n", dev->print_name(), dev->device->max_block_size, dev->max_block_size, dcr->VolMaxBlocksize); if (dcr->VolMaxBlocksize == 0 && dev->device->max_block_size != 0) { Dmsg2(100, "setting dev->max_block_size to dev->device->max_block_size=%u " "on device %s because dcr->VolMaxBlocksize is 0\n", dev->device->max_block_size, dev->print_name()); dev->min_block_size = dev->device->min_block_size; dev->max_block_size = dev->device->max_block_size; } else if (dcr->VolMaxBlocksize != 0) { dev->min_block_size = dcr->VolMinBlocksize; dev->max_block_size = dcr->VolMaxBlocksize; } /* * Sanity check */ if (dev->max_block_size == 0) { max_bs = DEFAULT_BLOCK_SIZE; } else { max_bs = dev->max_block_size; } if (dev->min_block_size > max_bs) { Jmsg(jcr, M_ERROR_TERM, 0, _("Min block size > max on device %s\n"), dev->print_name()); } if (dev->max_block_size > MAX_BLOCK_LENGTH) { Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"), dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE); dev->max_block_size = 0; } if (dev->max_block_size % TAPE_BSIZE != 0) { Jmsg3(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size=%d.\n"), dev->max_block_size, dev->print_name(), TAPE_BSIZE); } if (dev->max_volume_size != 0 && dev->max_volume_size < (dev->max_block_size << 4)) { Jmsg(jcr, M_ERROR_TERM, 0, _("Max Vol Size < 8 * Max Block Size for device %s\n"), dev->print_name()); } Dmsg3(100, "set minblocksize to %d, maxblocksize to %d on device %s\n", dev->min_block_size, dev->max_block_size, dev->print_name()); /* * If blocklen is not dev->max_block_size create a new block with the right size. * (as header is always dev->label_block_size which is preset with DEFAULT_BLOCK_SIZE) */ if (dcr->block) { if (dcr->block->buf_len != dev->max_block_size) { Dmsg2(100, "created new block of buf_len: %u on device %s\n", dev->max_block_size, dev->print_name()); free_block(dcr->block); dcr->block = new_block(dev); Dmsg2(100, "created new block of buf_len: %u on device %s, freeing block\n", dcr->block->buf_len, dev->print_name()); } } } /* * Set the block size of the device to the label_block_size * to read labels as we want to always use that blocksize when * writing volume labels */ void DEVICE::set_label_blocksize(DCR *dcr) { DEVICE *dev = this; Dmsg3(100, "setting minblocksize to %u, " "maxblocksize to label_block_size=%u, on device %s\n", dev->device->label_block_size, dev->device->label_block_size, dev->print_name()); dev->min_block_size = dev->device->label_block_size; dev->max_block_size = dev->device->label_block_size; /* * If blocklen is not dev->max_block_size create a new block with the right size * (as header is always label_block_size) */ if (dcr->block) { if (dcr->block->buf_len != dev->max_block_size) { free_block(dcr->block); dcr->block = new_block(dev); Dmsg2(100, "created new block of buf_len: %u on device %s\n", dcr->block->buf_len, dev->print_name()); } } } /* * Open the device with the operating system and * initialize buffer pointers. * * Returns: true on success * false on error * * Note, for a tape, the VolName is the name we give to the * volume (not really used here), but for a file, the * VolName represents the name of the file to be created/opened. * In the case of a file, the full name is the device name * (archive_name) with the VolName concatenated. */ bool DEVICE::open(DCR *dcr, int omode) { int preserve = 0; if (is_open()) { if (open_mode == omode) { return true; } else { d_close(m_fd); clear_opened(); Dmsg0(100, "Close fd for mode change.\n"); preserve = state & (ST_LABEL | ST_APPENDREADY | ST_READREADY); } } if (dcr) { dcr->setVolCatName(dcr->VolumeName); VolCatInfo = dcr->VolCatInfo; /* structure assign */ } Dmsg4(100, "open dev: type=%d dev_name=%s vol=%s mode=%s\n", dev_type, print_name(), getVolCatName(), mode_to_str(omode)); state &= ~(ST_LABEL | ST_APPENDREADY | ST_READREADY | ST_EOT | ST_WEOT | ST_EOF); label_type = B_BAREOS_LABEL; Dmsg1(100, "call open_device mode=%s\n", mode_to_str(omode)); open_device(dcr, omode); state |= preserve; /* reset any important state info */ Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd); return m_fd >= 0; } void DEVICE::set_mode(int mode) { switch (mode) { case CREATE_READ_WRITE: oflags = O_CREAT | O_RDWR | O_BINARY; break; case OPEN_READ_WRITE: oflags = O_RDWR | O_BINARY; break; case OPEN_READ_ONLY: oflags = O_RDONLY | O_BINARY; break; case OPEN_WRITE_ONLY: oflags = O_WRONLY | O_BINARY; break; default: Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n")); } } /* * Open a device. */ void DEVICE::open_device(DCR *dcr, int omode) { POOL_MEM archive_name(PM_FNAME); get_autochanger_loaded_slot(dcr); /* * Handle opening of File Archive (not a tape) */ pm_strcpy(archive_name, dev_name); /* * If this is a virtual autochanger (i.e. changer_res != NULL) we simply use * the device name, assuming it has been appropriately setup by the "autochanger". */ if (!device->changer_res || device->changer_command[0] == 0) { if (VolCatInfo.VolCatName[0] == 0) { Mmsg(errmsg, _("Could not open file device %s. No Volume name given.\n"), print_name()); clear_opened(); return; } if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) { pm_strcat(archive_name, "/"); } pm_strcat(archive_name, getVolCatName()); } mount(dcr, 1); /* do mount if required */ open_mode = omode; set_mode(omode); /* * If creating file, give 0640 permissions */ Dmsg3(100, "open disk: mode=%s open(%s, 0x%x, 0640)\n", mode_to_str(omode), archive_name.c_str(), oflags); if ((m_fd = d_open(archive_name.c_str(), oflags, 0640)) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), be.bstrerror()); Dmsg1(100, "open failed: %s", errmsg); } if (m_fd >= 0) { dev_errno = 0; file = 0; file_addr = 0; } Dmsg1(100, "open dev: disk fd=%d opened\n", m_fd); } /* * Rewind the device. * * Returns: true on success * false on failure */ bool DEVICE::rewind(DCR *dcr) { Dmsg3(400, "rewind res=%d fd=%d %s\n", num_reserved(), m_fd, print_name()); state &= ~(ST_EOT | ST_EOF | ST_WEOT); /* Remove EOF/EOT flags */ block_num = file = 0; file_size = 0; file_addr = 0; if (m_fd < 0) { return false; } if (is_fifo() || is_vtl()) { return true; } if (lseek(dcr, (boffset_t)0, SEEK_SET) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); return false; } return true; } /* * Called to indicate that we have just read an EOF from the device. */ void DEVICE::set_ateof() { set_eof(); file_addr = 0; file_size = 0; block_num = 0; } /* * Called to indicate we are now at the end of the volume, and writing is not possible. */ void DEVICE::set_ateot() { /* * Make volume effectively read-only */ state |= (ST_EOF | ST_EOT | ST_WEOT); clear_append(); } /* * Position device to end of medium (end of data) * * Returns: true on succes * false on error */ bool DEVICE::eod(DCR *dcr) { boffset_t pos; if (m_fd < 0) { dev_errno = EBADF; Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), print_name()); return false; } if (is_vtl()) { return true; } Dmsg0(100, "Enter eod\n"); if (at_eot()) { return true; } clear_eof(); /* remove EOF flag */ block_num = file = 0; file_size = 0; file_addr = 0; pos = lseek(dcr, (boffset_t)0, SEEK_END); Dmsg1(200, "====== Seek to %lld\n", pos); if (pos >= 0) { update_pos(dcr); set_eot(); return true; } dev_errno = errno; berrno be; Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); Dmsg0(100, errmsg); return false; } /* * Set the position of the device. * * Returns: true on succes * false on error */ bool DEVICE::update_pos(DCR *dcr) { boffset_t pos; bool ok = true; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad device call. Device not open\n")); Emsg1(M_FATAL, 0, "%s", errmsg); return false; } if (is_fifo() || is_vtl()) { return true; } file = 0; file_addr = 0; pos = lseek(dcr, (boffset_t)0, SEEK_CUR); if (pos < 0) { berrno be; dev_errno = errno; Pmsg1(000, _("Seek error: ERR=%s\n"), be.bstrerror()); Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); ok = false; } else { file_addr = pos; block_num = (uint32_t)pos; file = (uint32_t)(pos >> 32); } return ok; } uint32_t DEVICE::status_dev() { uint32_t status = 0; if (state & (ST_EOT | ST_WEOT)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (state & ST_EOF) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } status |= BMT_ONLINE | BMT_BOT; return status; } bool DEVICE::offline_or_rewind() { if (m_fd < 0) { return false; } if (has_cap(CAP_OFFLINEUNMOUNT)) { return offline(); } else { /* * Note, this rewind probably should not be here (it wasn't * in prior versions of Bareos), but on FreeBSD, this is * needed in the case the tape was "frozen" due to an error * such as backspacing after writing and EOF. If it is not * done, all future references to the drive get and I/O error. */ clrerror(MTREW); return rewind(NULL); } } void DEVICE::set_slot(int32_t slot) { m_slot = slot; if (vol) vol->clear_slot(); } void DEVICE::clear_slot() { m_slot = -1; if (vol) vol->set_slot(-1); } /* * Reposition the device to file, block * * Returns: false on failure * true on success */ bool DEVICE::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) { if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to reposition. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (is_fifo() || is_vtl()) { return true; } boffset_t pos = (((boffset_t)rfile) << 32) | rblock; Dmsg1(100, "===== lseek to %d\n", (int)pos); if (lseek(dcr, pos, SEEK_SET) == (boffset_t)-1) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); return false; } file = rfile; block_num = rblock; file_addr = pos; return true; } /* * Set to unload the current volume in the drive. */ void DEVICE::set_unload() { if (!m_unload && VolHdr.VolumeName[0] != 0) { m_unload = true; memcpy(UnloadVolName, VolHdr.VolumeName, sizeof(UnloadVolName)); } } /* * Clear volume header. */ void DEVICE::clear_volhdr() { Dmsg1(100, "Clear volhdr vol=%s\n", VolHdr.VolumeName); memset(&VolHdr, 0, sizeof(VolHdr)); setVolCatInfo(false); } /* * Close the device. */ void DEVICE::close(DCR *dcr) { int status; Dmsg1(100, "close_dev %s\n", print_name()); if (!norewindonclose) { offline_or_rewind(); } if (!is_open()) { Dmsg2(100, "device %s already closed vol=%s\n", print_name(), VolHdr.VolumeName); return; /* already closed */ } switch (dev_type) { case B_VTL_DEV: case B_TAPE_DEV: unlock_door(); /* Fall through wanted */ default: status = d_close(m_fd); if (status < 0) { berrno be; Mmsg2(errmsg, _("Unable to close device %s. ERR=%s\n"), print_name(), be.bstrerror()); Jmsg(dcr->jcr, M_FATAL, 0, errmsg); } break; } unmount(dcr, 1); /* do unmount if required */ /* * Clean up device packet so it can be reused. */ clear_opened(); state &= ~(ST_LABEL | ST_READREADY | ST_APPENDREADY | ST_EOT | ST_WEOT | ST_EOF | ST_MOUNTED | ST_MEDIA | ST_SHORT); label_type = B_BAREOS_LABEL; file = block_num = 0; file_size = 0; file_addr = 0; EndFile = EndBlock = 0; open_mode = 0; clear_volhdr(); memset(&VolCatInfo, 0, sizeof(VolCatInfo)); if (tid) { stop_thread_timer(tid); tid = 0; } } /* * Mount the device. * If timeout, wait until the mount command returns 0. * If !timeout, try to mount the device only once. */ bool DEVICE::mount(DCR *dcr, int timeout) { bool retval = true; Dmsg0(190, "Enter mount\n"); if (is_mounted()) { return true; } retval = mount_backend(dcr, timeout); /* * When the mount command succeeded sent a * bsdEventDeviceMount plugin event so any plugin * that want to do something can do things now. */ if (retval && generate_plugin_event(dcr->jcr, bsdEventDeviceMount, dcr) != bRC_OK) { retval = false; } /* * Mark the device mounted if we succeed. */ if (retval) { set_mounted(); } return retval; } /* * Unmount the device * If timeout, wait until the unmount command returns 0. * If !timeout, try to unmount the device only once. */ bool DEVICE::unmount(DCR *dcr, int timeout) { bool retval = true; Dmsg0(100, "Enter unmount\n"); /* * See if the device is mounted. */ if (!is_mounted()) { return true; } /* * Before running the unmount program sent a * bsdEventDeviceUnmount plugin event so any plugin * that want to do something can do things now. */ if (dcr && generate_plugin_event(dcr->jcr, bsdEventDeviceUnmount, dcr) != bRC_OK) { retval = false; goto bail_out; } retval = unmount_backend(dcr, timeout); /* * Mark the device unmounted if we succeed. */ if (retval) { clear_mounted(); } bail_out: return retval; } /* * Edit codes into (Un)MountCommand * %% = % * %a = archive device name * %m = mount point * * omsg = edited output message * imsg = input string containing edit codes (%x) * */ void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg) { const char *p; const char *str; char add[20]; POOL_MEM archive_name(PM_FNAME); omsg.c_str()[0] = 0; Dmsg1(800, "edit_mount_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'a': str = dev_name; break; case 'm': str = device->mount_point; break; default: add[0] = '%'; add[1] = *p; add[2] = 0; str = add; break; } } else { add[0] = *p; add[1] = 0; str = add; } Dmsg1(1900, "add_str %s\n", str); pm_strcat(omsg, (char *)str); Dmsg1(1800, "omsg=%s\n", omsg.c_str()); } } /* * Return the last timer interval (ms) or 0 if something goes wrong */ btime_t DEVICE::get_timer_count() { btime_t temp = last_timer; last_timer = get_current_btime(); temp = last_timer - temp; /* get elapsed time */ return (temp > 0) ? temp : 0; /* take care of skewed clock */ } /* * Read from device. */ ssize_t DEVICE::read(void *buf, size_t len) { ssize_t read_len ; get_timer_count(); read_len = d_read(m_fd, buf, len); last_tick = get_timer_count(); DevReadTime += last_tick; VolCatInfo.VolReadTime += last_tick; if (read_len > 0) { /* skip error */ DevReadBytes += read_len; } return read_len; } /* * Write to device. */ ssize_t DEVICE::write(const void *buf, size_t len) { ssize_t write_len ; get_timer_count(); write_len = d_write(m_fd, buf, len); last_tick = get_timer_count(); DevWriteTime += last_tick; VolCatInfo.VolWriteTime += last_tick; if (write_len > 0) { /* skip error */ DevWriteBytes += write_len; } return write_len; } /* * Return the resource name for the device */ const char *DEVICE::name() const { return device->hdr.name; } /* * Free memory allocated for the device */ void DEVICE::term() { Dmsg1(900, "term dev: %s\n", print_name()); /* * On termination we don't have any DCRs left * so we call close with a NULL argument as * the dcr argument is only used in the unmount * method to generate a plugin_event we just check * there if the dcr is not NULL and otherwise skip * the plugin event generation. */ close(NULL); if (dev_name) { free_memory(dev_name); dev_name = NULL; } if (prt_name) { free_memory(prt_name); prt_name = NULL; } if (errmsg) { free_pool_memory(errmsg); errmsg = NULL; } pthread_mutex_destroy(&m_mutex); pthread_cond_destroy(&wait); pthread_cond_destroy(&wait_next_vol); pthread_mutex_destroy(&spool_mutex); // rwl_destroy(&lock); if (attached_dcrs) { delete attached_dcrs; attached_dcrs = NULL; } if (device) { device->dev = NULL; } delete this; } /* * This routine initializes the device wait timers */ void init_device_wait_timers(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; /* ******FIXME******* put these on config variables */ dev->min_wait = 60 * 60; dev->max_wait = 24 * 60 * 60; dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ dev->wait_sec = dev->min_wait; dev->rem_wait_sec = dev->wait_sec; dev->num_wait = 0; dev->poll = false; jcr->min_wait = 60 * 60; jcr->max_wait = 24 * 60 * 60; jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ jcr->wait_sec = jcr->min_wait; jcr->rem_wait_sec = jcr->wait_sec; jcr->num_wait = 0; } void init_jcr_device_wait_timers(JCR *jcr) { /* ******FIXME******* put these on config variables */ jcr->min_wait = 60 * 60; jcr->max_wait = 24 * 60 * 60; jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ jcr->wait_sec = jcr->min_wait; jcr->rem_wait_sec = jcr->wait_sec; jcr->num_wait = 0; } /* * The dev timers are used for waiting on a particular device * * Returns: true if time doubled * false if max time expired */ bool double_dev_wait_time(DEVICE *dev) { dev->wait_sec *= 2; /* Double wait time */ if (dev->wait_sec > dev->max_wait) { /* But not longer than maxtime */ dev->wait_sec = dev->max_wait; } dev->num_wait++; dev->rem_wait_sec = dev->wait_sec; if (dev->num_wait >= dev->max_num_wait) { return false; } return true; } DEVICE::DEVICE() { m_fd = -1; } bareos-Release-14.2.6/src/stored/dev.h000066400000000000000000000747631263011562700174770ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Definitions for using the Device functions in Bareos Tape and File storage access * * Kern Sibbald, MM */ /* * Some details of how volume and device reservations work * * class VOLRES: * set_in_use() volume being used on current drive * clear_in_use() no longer being used. Can be re-used or moved. * set_swapping() set volume being moved to another drive * is_swapping() volume is being moved to another drive * clear_swapping() volume normal * * class DEVICE: * set_load() set to load volume * needs_load() volume must be loaded (i.e. set_load done) * clear_load() load done. * set_unload() set to unload volume * needs_unload() volume must be unloaded * clear_unload() volume unloaded * * reservations are temporary until the drive is acquired * inc_reserved() increments num of reservations * dec_reserved() decrements num of reservations * num_reserved() number of reservations * * class DCR: * set_reserved() sets local reserve flag and calls dev->inc_reserved() * clear_reserved() clears local reserve flag and calls dev->dec_reserved() * is_reserved() returns local reserved flag * unreserve_device() much more complete unreservation */ #ifndef __DEV_H #define __DEV_H 1 #undef DCR /* used by Bareos */ /* * Return values from wait_for_sysop() */ enum { W_ERROR = 1, W_TIMEOUT, W_POLL, W_MOUNT, W_WAKE }; /* * Arguments to open_dev() */ enum { CREATE_READ_WRITE = 1, OPEN_READ_WRITE, OPEN_READ_ONLY, OPEN_WRITE_ONLY }; /* * Device types */ enum { B_FILE_DEV = 1, B_TAPE_DEV, B_FIFO_DEV, B_VTL_DEV, B_GFAPI_DEV, B_OBJECT_STORE_DEV, B_RADOS_DEV, B_CEPHFS_DEV }; /* * IO directions */ enum { IO_DIRECTION_NONE = 0, IO_DIRECTION_IN, IO_DIRECTION_OUT, IO_DIRECTION_INOUT }; /* * Generic status bits returned from status_dev() */ #define BMT_TAPE (1 << 0) /* is tape device */ #define BMT_EOF (1 << 1) /* just read EOF */ #define BMT_BOT (1 << 2) /* at beginning of tape */ #define BMT_EOT (1 << 3) /* end of tape reached */ #define BMT_SM (1 << 4) /* DDS setmark */ #define BMT_EOD (1 << 5) /* DDS at end of data */ #define BMT_WR_PROT (1 << 6) /* tape write protected */ #define BMT_ONLINE (1 << 7) /* tape online */ #define BMT_DR_OPEN (1 << 8) /* tape door open */ #define BMT_IM_REP_EN (1 << 9) /* immediate report enabled */ /* * Bits for device capabilities */ #define CAP_EOF (1 << 0) /* has MTWEOF */ #define CAP_BSR (1 << 1) /* has MTBSR */ #define CAP_BSF (1 << 2) /* has MTBSF */ #define CAP_FSR (1 << 3) /* has MTFSR */ #define CAP_FSF (1 << 4) /* has MTFSF */ #define CAP_EOM (1 << 5) /* has MTEOM */ #define CAP_REM (1 << 6) /* is removable media */ #define CAP_RACCESS (1 << 7) /* is random access device */ #define CAP_AUTOMOUNT (1 << 8) /* Read device at start to see what is there */ #define CAP_LABEL (1 << 9) /* Label blank tapes */ #define CAP_ANONVOLS (1 << 10) /* Mount without knowing volume name */ #define CAP_ALWAYSOPEN (1 << 11) /* always keep device open */ #define CAP_AUTOCHANGER (1 << 12) /* AutoChanger */ #define CAP_OFFLINEUNMOUNT (1 << 13) /* Offline before unmount */ #define CAP_STREAM (1 << 14) /* Stream device */ #define CAP_BSFATEOM (1 << 15) /* Backspace file at EOM */ #define CAP_FASTFSF (1 << 16) /* Fast forward space file */ #define CAP_TWOEOF (1 << 17) /* Write two eofs for EOM */ #define CAP_CLOSEONPOLL (1 << 18) /* Close device on polling */ #define CAP_POSITIONBLOCKS (1 << 19) /* Use block positioning */ #define CAP_MTIOCGET (1 << 20) /* Basic support for fileno and blkno */ #define CAP_REQMOUNT (1 << 21) /* Require mount/unmount */ #define CAP_CHECKLABELS (1 << 22) /* Check for ANSI/IBM labels */ #define CAP_BLOCKCHECKSUM (1 << 23) /* Create/test block checksum */ #define CAP_IOERRATEOM (1 << 24) /* IOError at EOM */ #define CAP_IBMLINTAPE (1 << 25) /* Using IBM lin_tape driver */ /* * Device state bits */ #define ST_XXXXXX (1 << 0) /* was ST_OPENED */ #define ST_XXXXX (1 << 1) /* was ST_TAPE */ #define ST_XXXX (1 << 2) /* was ST_FILE */ #define ST_XXX (1 << 3) /* was ST_FIFO */ #define ST_XX (1 << 4) /* was ST_DVD */ #define ST_X (1 << 5) /* was ST_PROG */ #define ST_LABEL (1 << 6) /* label found */ #define ST_MALLOC (1 << 7) /* dev packet malloc'ed in init_dev() */ #define ST_APPENDREADY (1 << 8) /* Ready for Bareos append */ #define ST_READREADY (1 << 9) /* Ready for Bareos read */ #define ST_EOT (1 << 10) /* at end of tape */ #define ST_WEOT (1 << 11) /* Got EOT on write */ #define ST_EOF (1 << 12) /* Read EOF i.e. zero bytes */ #define ST_NEXTVOL (1 << 13) /* Start writing on next volume */ #define ST_SHORT (1 << 14) /* Short block read */ #define ST_MOUNTED (1 << 15) /* the device is mounted to the mount point */ #define ST_MEDIA (1 << 16) /* Media found in mounted device */ #define ST_OFFLINE (1 << 17) /* set offline by operator */ #define ST_PART_SPOOLED (1 << 18) /* spooling part */ #define ST_CRYPTOKEY (1 << 19) /* The device has a crypto key loaded */ /* * Volume Catalog Information structure definition */ struct VOLUME_CAT_INFO { /* * Media info for the current Volume */ uint32_t VolCatJobs; /* number of jobs on this Volume */ uint32_t VolCatFiles; /* Number of files */ uint32_t VolCatBlocks; /* Number of blocks */ uint64_t VolCatBytes; /* Number of bytes written */ uint32_t VolCatMounts; /* Number of mounts this volume */ uint32_t VolCatErrors; /* Number of errors this volume */ uint32_t VolCatWrites; /* Number of writes this volume */ uint32_t VolCatReads; /* Number of reads this volume */ uint64_t VolCatRBytes; /* Number of bytes read */ uint32_t VolCatRecycles; /* Number of recycles this volume */ uint32_t EndFile; /* Last file number */ uint32_t EndBlock; /* Last block number */ int32_t LabelType; /* Bareos/ANSI/IBM */ int32_t Slot; /* >0=Slot loaded, 0=nothing, -1=unknown */ uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */ uint32_t VolCatMaxFiles; /* Maximum files to write to volume */ uint64_t VolCatMaxBytes; /* Max bytes to write to volume */ uint64_t VolCatCapacityBytes; /* capacity estimate */ btime_t VolReadTime; /* time spent reading */ btime_t VolWriteTime; /* time spent writing this Volume */ int64_t VolMediaId; /* MediaId */ utime_t VolFirstWritten; /* Time of first write */ utime_t VolLastWritten; /* Time of last write */ bool InChanger; /* Set if vol in current magazine */ bool is_valid; /* set if this data is valid */ char VolCatStatus[20]; /* Volume status */ char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */ char VolEncrKey[MAX_NAME_LENGTH]; /* Encryption Key needed to read the media */ uint32_t VolMinBlocksize; /* Volume Minimum Blocksize */ uint32_t VolMaxBlocksize; /* Volume Maximum Blocksize */ }; struct BLOCKSIZES { uint32_t max_block_size; uint32_t min_block_size; }; class DEVRES; /* Device resource defined in stored_conf.h */ class DCR; /* Forward reference */ class VOLRES; /* Forward reference */ /* * Device structure definition. * * There is one of these for each physical device. Everything here is "global" to * that device and effects all jobs using the device. */ class DEVICE: public SMARTALLOC { protected: int m_fd; /* File descriptor */ private: int m_blocked; /* Set if we must wait (i.e. change tape) */ int m_count; /* Mutex use count -- DEBUG only */ int m_num_reserved; /* Counter of device reservations */ int32_t m_slot; /* Slot loaded in drive or -1 if none */ pthread_t m_pid; /* Thread that locked -- DEBUG only */ bool m_unload; /* Set when Volume must be unloaded */ bool m_load; /* Set when Volume must be loaded */ public: DEVICE(); virtual ~DEVICE() {}; DEVICE * volatile swap_dev; /* Swap vol from this device */ dlist *attached_dcrs; /* Attached DCR list */ bthread_mutex_t m_mutex; /* Access control */ bthread_mutex_t spool_mutex; /* Mutex for updating spool_size */ bthread_mutex_t acquire_mutex; /* Mutex for acquire code */ pthread_mutex_t read_acquire_mutex; /* Mutex for acquire read code */ pthread_cond_t wait; /* Thread wait variable */ pthread_cond_t wait_next_vol; /* Wait for tape to be mounted */ pthread_t no_wait_id; /* This thread must not wait */ int dev_prev_blocked; /* Previous blocked state */ int num_waiting; /* Number of threads waiting */ int num_writers; /* Number of writing threads */ int capabilities; /* Capabilities mask */ int state; /* State mask */ int dev_errno; /* Our own errno */ int oflags; /* Read/write flags */ int open_mode; /* Parameter passed to open_dev (useful to reopen the device) */ int dev_type; /* Device type */ bool autoselect; /* Autoselect in autochanger */ bool norewindonclose; /* Don't rewind tape drive on close */ bool initiated; /* Set when init_dev() called */ int label_type; /* Bareos/ANSI/IBM label types */ uint32_t drive_index; /* Autochanger drive index (base 0) */ POOLMEM *dev_name; /* Physical device name */ POOLMEM *prt_name; /* Name used for display purposes */ char *errmsg; /* Nicely edited error message */ uint32_t block_num; /* Current block number base 0 */ uint32_t LastBlock; /* Last DEV_BLOCK number written to Volume */ uint32_t file; /* Current file number base 0 */ uint64_t file_addr; /* Current file read/write address */ uint64_t file_size; /* Current file size */ uint32_t EndBlock; /* Last block written */ uint32_t EndFile; /* Last file written */ uint32_t min_block_size; /* Min block size currently set */ uint32_t max_block_size; /* Max block size currently set */ uint32_t max_concurrent_jobs; /* Maximum simultaneous jobs this drive */ uint64_t max_volume_size; /* Max bytes to put on one volume */ uint64_t max_file_size; /* Max file size to put in one file on volume */ uint64_t volume_capacity; /* Advisory capacity */ uint64_t max_spool_size; /* Maximum spool file size */ uint64_t spool_size; /* Current spool size for this device */ uint32_t max_rewind_wait; /* Max secs to allow for rewind */ uint32_t max_open_wait; /* Max secs to allow for open */ uint32_t max_open_vols; /* Max simultaneous open volumes */ utime_t vol_poll_interval; /* Interval between polling Vol mount */ DEVRES *device; /* Pointer to Device Resource */ VOLRES *vol; /* Pointer to Volume reservation item */ btimer_t *tid; /* Timer id */ VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */ VOLUME_LABEL VolHdr; /* Actual volume label */ char pool_name[MAX_NAME_LENGTH]; /* Pool name */ char pool_type[MAX_NAME_LENGTH]; /* Pool type */ char UnloadVolName[MAX_NAME_LENGTH]; /* Last wrong Volume mounted */ bool poll; /* Set to poll Volume */ /* Device wait times ***FIXME*** look at durations */ int min_wait; int max_wait; int max_num_wait; int wait_sec; int rem_wait_sec; int num_wait; btime_t last_timer; /* Used by read/write/seek to get stats (usec) */ btime_t last_tick; /* Contains last read/write time (usec) */ btime_t DevReadTime; btime_t DevWriteTime; uint64_t DevWriteBytes; uint64_t DevReadBytes; /* Methods */ btime_t get_timer_count(); /* Return the last timer interval (ms) */ int has_cap(int cap) const { return capabilities & cap; } void clear_cap(int cap) { capabilities &= ~cap; } void set_cap(int cap) { capabilities |= cap; } bool do_checksum() const { return (capabilities & CAP_BLOCKCHECKSUM) != 0; } int is_autochanger() const { return capabilities & CAP_AUTOCHANGER; } int requires_mount() const { return capabilities & CAP_REQMOUNT; } int is_removable() const { return capabilities & CAP_REM; } int is_tape() const { return (dev_type == B_TAPE_DEV); } int is_file() const { return (dev_type == B_FILE_DEV || dev_type == B_GFAPI_DEV || dev_type == B_OBJECT_STORE_DEV || dev_type == B_RADOS_DEV || dev_type == B_CEPHFS_DEV); } int is_fifo() const { return dev_type == B_FIFO_DEV; } int is_vtl() const { return dev_type == B_VTL_DEV; } int is_open() const { return m_fd >= 0; } int is_offline() const { return state & ST_OFFLINE; } int is_labeled() const { return state & ST_LABEL; } int is_mounted() const { return state & ST_MOUNTED; } int is_unmountable() const { return ((is_file() && is_removable())); } int num_reserved() const { return m_num_reserved; }; int is_part_spooled() const { return state & ST_PART_SPOOLED; } int have_media() const { return state & ST_MEDIA; } int is_short_block() const { return state & ST_SHORT; } int is_busy() const { return (state & ST_READREADY) || num_writers || num_reserved(); } int at_eof() const { return state & ST_EOF; } int at_eot() const { return state & ST_EOT; } int at_weot() const { return state & ST_WEOT; } int can_append() const { return state & ST_APPENDREADY; } int is_crypto_enabled() const { return state & ST_CRYPTOKEY; } /* * can_write() is meant for checking at the end of a job to see * if we still have a tape (perhaps not if at end of tape * and the job is canceled). */ int can_write() const { return is_open() && can_append() && is_labeled() && !at_weot(); } int can_read() const { return state & ST_READREADY; } bool can_steal_lock() const { return m_blocked && (m_blocked == BST_UNMOUNTED || m_blocked == BST_WAITING_FOR_SYSOP || m_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); }; bool waiting_for_mount() const { return (m_blocked == BST_UNMOUNTED || m_blocked == BST_WAITING_FOR_SYSOP || m_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); }; bool must_unload() const { return m_unload; }; bool must_load() const { return m_load; }; const char *strerror() const; const char *archive_name() const; const char *name() const; const char *print_name() const; /* Name for display purposes */ void set_eot() { state |= ST_EOT; }; void set_eof() { state |= ST_EOF; }; void set_append() { state |= ST_APPENDREADY; }; void set_labeled() { state |= ST_LABEL; }; inline void set_read() { state |= ST_READREADY; }; void set_offline() { state |= ST_OFFLINE; }; void set_mounted() { state |= ST_MOUNTED; }; void set_media() { state |= ST_MEDIA; }; void set_short_block() { state |= ST_SHORT; }; void set_crypto_enabled() { state |= ST_CRYPTOKEY; }; void set_part_spooled(int val) { if (val) state |= ST_PART_SPOOLED; \ else state &= ~ST_PART_SPOOLED; }; bool is_volume_to_unload() const { \ return m_unload && strcmp(VolHdr.VolumeName, UnloadVolName) == 0; }; void set_load() { m_load = true; }; void inc_reserved() { m_num_reserved++; } void dec_reserved() { m_num_reserved--; ASSERT(m_num_reserved>=0); }; void clear_append() { state &= ~ST_APPENDREADY; }; void clear_read() { state &= ~ST_READREADY; }; void clear_labeled() { state &= ~ST_LABEL; }; void clear_offline() { state &= ~ST_OFFLINE; }; void clear_eot() { state &= ~ST_EOT; }; void clear_eof() { state &= ~ST_EOF; }; void clear_opened() { m_fd = -1; }; void clear_mounted() { state &= ~ST_MOUNTED; }; void clear_media() { state &= ~ST_MEDIA; }; void clear_short_block() { state &= ~ST_SHORT; }; void clear_crypto_enabled() { state &= ~ST_CRYPTOKEY; }; void clear_unload() { m_unload = false; UnloadVolName[0] = 0; }; void clear_load() { m_load = false; }; char *bstrerror(void) { return errmsg; }; char *print_errmsg() { return errmsg; }; int32_t get_slot() const { return m_slot; }; void setVolCatInfo(bool valid) { VolCatInfo.is_valid = valid; }; bool haveVolCatInfo() const { return VolCatInfo.is_valid; }; void setVolCatName(const char *name) { bstrncpy(VolCatInfo.VolCatName, name, sizeof(VolCatInfo.VolCatName)); setVolCatInfo(false); }; char *getVolCatName() { return VolCatInfo.VolCatName; }; const char *mode_to_str(int mode); void set_unload(); void clear_volhdr(); void close(DCR *dcr); bool open(DCR *dcr, int mode); void term(); ssize_t read(void *buf, size_t len); ssize_t write(const void *buf, size_t len); bool mount(DCR *dcr, int timeout); bool unmount(DCR *dcr, int timeout); void edit_mount_codes(POOL_MEM &omsg, const char *imsg); bool offline_or_rewind(); bool scan_dir_for_volume(DCR *dcr); void set_slot(int32_t slot); void clear_slot(); void set_blocksizes(DCR* dcr); void set_label_blocksize(DCR* dcr); uint32_t get_file() const { return file; }; uint32_t get_block_num() const { return block_num; }; int fd() const { return m_fd; }; /* * Tape specific operations. */ virtual bool offline() { return true; }; virtual bool weof(int num) { return true; }; virtual bool fsf(int num) { return true; }; virtual bool bsf(int num) { return false; }; virtual bool fsr(int num) { return false; }; virtual bool bsr(int num) { return false; }; virtual bool load_dev() { return true; }; virtual void lock_door() {}; virtual void unlock_door() {}; virtual void clrerror(int func) {}; virtual void set_os_device_parameters(DCR *dcr) {}; virtual int32_t get_os_tape_file() { return -1; }; /* * Generic operations. */ virtual void open_device(DCR *dcr, int omode); virtual uint32_t status_dev(); virtual bool eod(DCR *dcr); virtual void set_ateof(); virtual void set_ateot(); virtual bool rewind(DCR *dcr); virtual bool update_pos(DCR *dcr); virtual bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); virtual bool mount_backend(DCR *dcr, int timeout) { return true; }; virtual bool unmount_backend(DCR *dcr, int timeout) { return true; }; boffset_t lseek(DCR *dcr, boffset_t offset, int whence) { return d_lseek(dcr, offset, whence); }; bool truncate(DCR *dcr) { return d_truncate(dcr); }; /* * Low level operations */ virtual int d_ioctl(int fd, ioctl_req_t request, char *mt_com = NULL) = 0; virtual int d_open(const char *pathname, int flags, int mode) = 0; virtual int d_close(int fd) = 0; virtual ssize_t d_read(int fd, void *buffer, size_t count) = 0; virtual ssize_t d_write(int fd, const void *buffer, size_t count) = 0; virtual boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence) = 0; virtual bool d_truncate(DCR *dcr) = 0; /* * Locking and blocking calls */ #ifdef SD_DEBUG_LOCK void dbg_rLock(const char *, int, bool locked = false); void dbg_rUnlock(const char *, int); void dbg_Lock(const char *, int); void dbg_Unlock(const char *, int); void dbg_Lock_acquire(const char *, int); void dbg_Unlock_acquire(const char *, int); void dbg_Lock_read_acquire(const char *, int); void dbg_Unlock_read_acquire(const char *, int); #else void rLock(bool locked = false); void rUnlock(); void Lock(); void Unlock(); void Lock_acquire(); void Unlock_acquire(); void Lock_read_acquire(); void Unlock_read_acquire(); void Lock_VolCatInfo(); void Unlock_VolCatInfo(); #endif int init_mutex(); int init_acquire_mutex(); int init_read_acquire_mutex(); int init_volcat_mutex(); void set_mutex_priorities(); int next_vol_timedwait(const struct timespec *timeout); void dblock(int why); void dunblock(bool locked = false); bool is_device_unmounted(); void set_blocked(int block) { m_blocked = block; }; int blocked() const { return m_blocked; }; bool is_blocked() const { return m_blocked != BST_NOT_BLOCKED; }; const char *print_blocked() const; protected: void set_mode(int mode); }; inline const char *DEVICE::strerror() const { return errmsg; } inline const char *DEVICE::archive_name() const { return dev_name; } inline const char *DEVICE::print_name() const { return prt_name; } #define CHECK_BLOCK_NUMBERS true #define NO_BLOCK_NUMBER_CHECK false enum get_vol_info_rw { GET_VOL_INFO_FOR_WRITE, GET_VOL_INFO_FOR_READ }; /* * Device Context (or Control) Record. * * There is one of these records for each Job that is using * the device. Items in this record are "local" to the Job and * do not affect other Jobs. Note, a job can have multiple * DCRs open, each pointing to a different device. * * Normally, there is only one JCR thread per DCR. However, the * big and important exception to this is when a Job is being * canceled. At that time, there may be two threads using the * same DCR. Consequently, when creating/attaching/detaching * and freeing the DCR we must lock it (m_mutex). */ class SD_IMP_EXP DCR : public SMARTALLOC { private: bool m_dev_locked; /* Set if dev already locked */ int m_dev_lock; /* Non-zero if rLock already called */ bool m_reserved; /* Set if reserved device */ bool m_found_in_use; /* Set if a volume found in use */ bool m_will_write; /* Set if DCR will be used for writing */ public: dlink dev_link; /* Link to attach to dev */ JCR *jcr; /* Pointer to JCR */ bthread_mutex_t m_mutex; /* Access control */ pthread_mutex_t r_mutex; /* rLock pre-mutex */ DEVICE * volatile dev; /* Pointer to device */ DEVRES *device; /* Pointer to device resource */ DEV_BLOCK *block; /* Pointer to current block */ DEV_RECORD *rec; /* Pointer to record being processed */ DEV_RECORD *before_rec; /* Pointer to record before translation */ DEV_RECORD *after_rec; /* Pointer to record after translation */ pthread_t tid; /* Thread running this dcr */ int spool_fd; /* Fd if spooling */ bool spool_data; /* Set to spool data */ bool spooling; /* Set when actually spooling */ bool despooling; /* Set when despooling */ bool despool_wait; /* Waiting for despooling */ bool NewVol; /* Set if new Volume mounted */ bool WroteVol; /* Set if Volume written */ bool NewFile; /* Set when EOF written */ bool reserved_volume; /* Set if we reserved a volume */ bool any_volume; /* Any OK for dir_find_next... */ bool attached_to_dev; /* Set when attached to dev */ bool keep_dcr; /* Do not free dcr in release_dcr */ uint32_t autodeflate; /* Try to autodeflate streams */ uint32_t autoinflate; /* Try to autoinflate streams */ uint32_t VolFirstIndex; /* First file index this Volume */ uint32_t VolLastIndex; /* Last file index this Volume */ uint32_t FileIndex; /* Current File Index */ uint32_t EndFile; /* End file written */ uint32_t StartFile; /* Start write file */ uint32_t StartBlock; /* Start write block */ uint32_t EndBlock; /* Ending block written */ int64_t VolMediaId; /* MediaId */ int64_t job_spool_size; /* Current job spool size */ int64_t max_job_spool_size; /* Max job spool size */ uint32_t VolMinBlocksize; /* Minimum Blocksize */ uint32_t VolMaxBlocksize; /* Maximum Blocksize */ char VolumeName[MAX_NAME_LENGTH]; /* Volume name */ char pool_name[MAX_NAME_LENGTH]; /* Pool name */ char pool_type[MAX_NAME_LENGTH]; /* Pool type */ char media_type[MAX_NAME_LENGTH]; /* Media type */ char dev_name[MAX_NAME_LENGTH]; /* Dev name */ int Copy; /* Identical copy number */ int Stripe; /* RAIT stripe */ VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */ /* * Constructor/Destructor. */ DCR(); virtual ~DCR() {}; /* * Methods */ void set_dev(DEVICE *ndev) { dev = ndev; }; void set_found_in_use() { m_found_in_use = true; }; void set_will_write() { m_will_write = true; }; void setVolCatInfo(bool valid) { VolCatInfo.is_valid = valid; }; void clear_found_in_use() { m_found_in_use = false; }; void clear_will_write() { m_will_write = false; }; bool is_reserved() const { return m_reserved; }; bool is_dev_locked() { return m_dev_locked; } bool is_writing() const { return m_will_write; }; void inc_dev_lock() { m_dev_lock++; }; void dec_dev_lock() { m_dev_lock--; }; bool found_in_use() const { return m_found_in_use; }; bool haveVolCatInfo() const { return VolCatInfo.is_valid; }; void setVolCatName(const char *name) { bstrncpy(VolCatInfo.VolCatName, name, sizeof(VolCatInfo.VolCatName)); setVolCatInfo(false); }; char *getVolCatName() { return VolCatInfo.VolCatName; }; /* * Methods in askdir.c */ virtual DCR *get_new_spooling_dcr(); virtual bool dir_find_next_appendable_volume() { return true; }; virtual bool dir_update_volume_info(bool label, bool update_LastWritten) { return true; }; virtual bool dir_create_jobmedia_record(bool zero) { return true; }; virtual bool dir_update_file_attributes(DEV_RECORD *record) { return true; }; virtual bool dir_ask_sysop_to_mount_volume(int mode); virtual bool dir_ask_sysop_to_create_appendable_volume() { return true; }; virtual bool dir_get_volume_info(enum get_vol_info_rw writing); /* * Methods in lock.c */ void dblock(int why) { dev->dblock(why); } #ifdef SD_DEBUG_LOCK void dbg_mLock(const char *, int, bool locked); void dbg_mUnlock(const char *, int); #else void mLock(bool locked); void mUnlock(); #endif /* * Methods in record.c */ bool write_record(); /* * Methods in reserve.c */ void clear_reserved(); void set_reserved(); void unreserve_device(); /* * Methods in vol_mgr.c */ bool can_i_use_volume(); bool can_i_write_volume(); /* * Methods in mount.c */ bool mount_next_write_volume(); bool mount_next_read_volume(); void mark_volume_in_error(); void mark_volume_not_inchanger(); int try_autolabel(bool opened); bool find_a_volume(); bool is_suitable_volume_mounted(); bool is_eod_valid(); int check_volume_label(bool &ask, bool &autochanger); void release_volume(); void do_swapping(bool is_writing); bool do_unload(); bool do_load(bool is_writing); bool is_tape_position_ok(); /* * Methods in block.c */ bool write_block_to_device(); bool write_block_to_dev(); bool read_block_from_device(bool check_block_numbers); bool read_block_from_dev(bool check_block_numbers); /* * Methods in label.c */ bool rewrite_volume_label(bool recycle); }; class SD_IMP_EXP SD_DCR : public DCR { public: /* * Virtual Destructor. */ ~SD_DCR() {}; /* * Methods overriding default implementations. */ bool dir_find_next_appendable_volume(); bool dir_update_volume_info(bool label, bool update_LastWritten); bool dir_create_jobmedia_record(bool zero); bool dir_update_file_attributes(DEV_RECORD *record); bool dir_ask_sysop_to_mount_volume(int mode); bool dir_ask_sysop_to_create_appendable_volume(); bool dir_get_volume_info(enum get_vol_info_rw writing); DCR *get_new_spooling_dcr(); }; class BTAPE_DCR : public DCR { public: /* * Virtual Destructor. */ ~BTAPE_DCR() {}; /* * Methods overriding default implementations. */ bool dir_find_next_appendable_volume(); bool dir_create_jobmedia_record(bool zero); bool dir_ask_sysop_to_mount_volume(int mode); bool dir_ask_sysop_to_create_appendable_volume(); DCR *get_new_spooling_dcr(); }; /* * Get some definition of function to position to the end of the medium in MTEOM. System dependent. */ #ifndef MTEOM #ifdef MTSEOD #define MTEOM MTSEOD #endif #ifdef MTEOD #undef MTEOM #define MTEOM MTEOD #endif #endif #endif bareos-Release-14.2.6/src/stored/device.c000066400000000000000000000277171263011562700201500ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Higher Level Device routines. * Knows about Bareos tape labels and such * * NOTE! In general, subroutines that have the word * "device" in the name do locking. Subroutines * that have the word "dev" in the name do not * do locking. Thus if xxx_device() calls * yyy_dev(), all is OK, but if xxx_device() * calls yyy_device(), everything will hang. * Obviously, no zzz_dev() is allowed to call * a www_device() or everything falls apart. * * Concerning the routines dev->r_lock()() and block_device() * see the end of this module for details. In general, * blocking a device leaves it in a state where all threads * other than the current thread block when they attempt to * lock the device. They remain suspended (blocked) until the device * is unblocked. So, a device is blocked during an operation * that takes a long time (initialization, mounting a new * volume, ...) locking a device is done for an operation * that takes a short time such as writing data to the * device. * * Kern Sibbald, MM, MMI */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ /* * This is the dreaded moment. We either have an end of * medium condition or worse, and error condition. * Attempt to "recover" by obtaining a new Volume. * * Here are a few things to know: * dcr->VolCatInfo contains the info on the "current" tape for this job. * dev->VolCatInfo contains the info on the tape in the drive. * The tape in the drive could have changed several times since * the last time the job used it (jcr->VolCatInfo). * dcr->VolumeName is the name of the current/desired tape in the drive. * * We enter with device locked, and * exit with device locked. * * Note, we are called only from one place in block.c for the daemons. * The btape utility calls it from btape.c. * * Returns: true on success * false on failure */ bool fixup_device_block_write_error(DCR *dcr, int retries) { char PrevVolName[MAX_NAME_LENGTH]; DEV_BLOCK *block; char b1[30], b2[30]; time_t wait_time; char dt[MAX_TIME_LENGTH]; JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; int blocked = dev->blocked(); /* save any previous blocked status */ bool ok = false; wait_time = time(NULL); Dmsg0(100, "=== Enter fixup_device_block_write_error\n"); /* * If we are blocked at entry, unblock it, and set our own block status */ if (blocked != BST_NOT_BLOCKED) { unblock_device(dev); } block_device(dev, BST_DOING_ACQUIRE); /* Continue unlocked, but leave BLOCKED */ dev->Unlock(); bstrncpy(PrevVolName, dev->getVolCatName(), sizeof(PrevVolName)); bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName)); /* Save the old block and create a new temporary label block */ block = dcr->block; dcr->block = new_block(dev); /* Inform User about end of medium */ Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"), PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1), edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2), bstrftime(dt, sizeof(dt), time(NULL))); Dmsg1(050, "set_unload dev=%s\n", dev->print_name()); dev->set_unload(); if (!dcr->mount_next_write_volume()) { free_block(dcr->block); dcr->block = block; dev->Lock(); goto bail_out; } Dmsg2(050, "must_unload=%d dev=%s\n", dev->must_unload(), dev->print_name()); dev->Lock(); /* lock again */ dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */ dcr->dir_update_volume_info(false, false); /* send Volume info to Director */ Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"), dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL))); /* * If this is a new tape, the label_blk will contain the * label, so write it now. If this is a previously * used tape, mount_next_write_volume() will return an * empty label_blk, and nothing will be written. */ Dmsg0(190, "write label block to dev\n"); if (!dcr->write_block_to_dev()) { berrno be; Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"), be.bstrerror(dev->dev_errno)); free_block(dcr->block); dcr->block = block; goto bail_out; } free_block(dcr->block); dcr->block = block; /* * Walk through all attached jcrs indicating the volume has changed */ Dmsg1(100, "Notify vol change. Volume=%s\n", dev->getVolCatName()); DCR *mdcr; foreach_dlist(mdcr, dev->attached_dcrs) { JCR *mjcr = mdcr->jcr; if (mjcr->JobId == 0) { continue; /* ignore console */ } mdcr->NewVol = true; if (jcr != mjcr) { bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName)); } } /* Clear NewVol now because dir_get_volume_info() already done */ jcr->dcr->NewVol = false; set_new_volume_parameters(dcr); jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */ /* Write overflow block to device */ Dmsg0(190, "Write overflow block to dev\n"); if (!dcr->write_block_to_dev()) { berrno be; Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"), be.bstrerror(dev->dev_errno)); /* Note: recursive call */ if (retries-- <= 0 || !fixup_device_block_write_error(dcr, retries)) { Jmsg2(jcr, M_FATAL, 0, _("Catastrophic error. Cannot write overflow block to device %s. ERR=%s"), dev->print_name(), be.bstrerror(dev->dev_errno)); goto bail_out; } } ok = true; bail_out: /* * At this point, the device is locked and blocked. * Unblock the device, restore any entry blocked condition, then * return leaving the device locked (as it was on entry). */ unblock_device(dev); if (blocked != BST_NOT_BLOCKED) { block_device(dev, blocked); } return ok; /* device locked */ } void set_start_vol_position(DCR *dcr) { DEVICE *dev = dcr->dev; /* Set new start position */ if (dev->is_tape()) { dcr->StartBlock = dev->block_num; dcr->StartFile = dev->file; } else { dcr->StartBlock = (uint32_t)dev->file_addr; dcr->StartFile = (uint32_t)(dev->file_addr >> 32); } } /* * We have a new Volume mounted, so reset the Volume parameters * concerning this job. The global changes were made earlier * in the dev structure. */ void set_new_volume_parameters(DCR *dcr) { JCR *jcr = dcr->jcr; if (dcr->NewVol && !dcr->dir_get_volume_info(GET_VOL_INFO_FOR_WRITE)) { Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg); } set_new_file_parameters(dcr); jcr->NumWriteVolumes++; dcr->NewVol = false; } /* * We are now in a new Volume file, so reset the Volume parameters * concerning this job. The global changes were made earlier * in the dev structure. */ void set_new_file_parameters(DCR *dcr) { set_start_vol_position(dcr); /* Reset indicies */ dcr->VolFirstIndex = 0; dcr->VolLastIndex = 0; dcr->NewFile = false; dcr->WroteVol = false; } /* * First Open of the device. Expect dev to already be initialized. * * This routine is used only when the Storage daemon starts * and always_open is set, and in the stand-alone utility * routines such as bextract. * * Note, opening of a normal file is deferred to later so * that we can get the filename; the device_name for * a file is the directory only. * * Returns: false on failure * true on success */ bool first_open_device(DCR *dcr) { DEVICE *dev = dcr->dev; bool ok = true; Dmsg0(120, "start open_output_device()\n"); if (!dev) { return false; } dev->rLock(); /* Defer opening files */ if (!dev->is_tape()) { Dmsg0(129, "Device is file, deferring open.\n"); goto bail_out; } int mode; if (dev->has_cap(CAP_STREAM)) { mode = OPEN_WRITE_ONLY; } else { mode = OPEN_READ_ONLY; } Dmsg0(129, "Opening device.\n"); if (!dev->open(dcr, mode)) { Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); ok = false; goto bail_out; } Dmsg1(129, "open dev %s OK\n", dev->print_name()); bail_out: dev->Unlock(); return ok; } /* * Make sure device is open, if not do so */ bool open_device(DCR *dcr) { DEVICE *dev = dcr->dev; /* Open device */ int mode; if (dev->has_cap(CAP_STREAM)) { mode = OPEN_WRITE_ONLY; } else { mode = OPEN_READ_WRITE; } if (!dev->open(dcr, mode)) { /* If polling, ignore the error */ if (!dev->poll && !dev->is_removable()) { Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); } return false; } return true; } /* * Position to the first file on this volume */ BSR *position_device_to_first_file(JCR *jcr, DCR *dcr) { BSR *bsr = NULL; DEVICE *dev = dcr->dev; uint32_t file, block; /* * Now find and position to first file and block * on this tape. */ if (jcr->bsr) { jcr->bsr->reposition = true; /* force repositioning */ bsr = find_next_bsr(jcr->bsr, dev); if (get_bsr_start_addr(bsr, &file, &block) > 0) { Jmsg(jcr, M_INFO, 0, _("Forward spacing Volume \"%s\" to file:block %u:%u.\n"), dev->VolHdr.VolumeName, file, block); dev->reposition(dcr, file, block); } } return bsr; } /* * See if we can reposition. * * Returns: true if at end of volume * false otherwise */ bool try_device_repositioning(JCR *jcr, DEV_RECORD *rec, DCR *dcr) { BSR *bsr; DEVICE *dev = dcr->dev; bsr = find_next_bsr(jcr->bsr, dev); if (bsr == NULL && jcr->bsr->mount_next_volume) { Dmsg0(500, "Would mount next volume here\n"); Dmsg2(500, "Current postion (file:block) %u:%u\n", dev->file, dev->block_num); jcr->bsr->mount_next_volume = false; if (!dev->at_eot()) { /* Set EOT flag to force mount of next Volume */ jcr->mount_next_volume = true; dev->set_eot(); } rec->Block = 0; return true; } if (bsr) { /* * ***FIXME*** gross kludge to make disk seeking work. Remove * when find_next_bsr() is fixed not to return a bsr already * completed. */ uint32_t block, file; /* TODO: use dev->file_addr ? */ uint64_t dev_addr = (((uint64_t) dev->file)<<32) | dev->block_num; uint64_t bsr_addr = get_bsr_start_addr(bsr, &file, &block); if (dev_addr > bsr_addr) { return false; } Dmsg4(500, "Try_Reposition from (file:block) %u:%u to %u:%u\n", dev->file, dev->block_num, file, block); dev->reposition(dcr, file, block); rec->Block = 0; } return false; } bareos-Release-14.2.6/src/stored/dir_cmd.c000066400000000000000000001560771263011562700203140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file handles accepting Director Commands * * Most Director commands are handled here, with the * exception of the Job command command and subsequent * subcommands that are handled * in job.c. * * N.B. in this file, in general we must use P(dev->mutex) rather * than dev->r_lock() so that we can examine the blocked * state rather than blocking ourselves because a Job * thread has the device blocked. In some "safe" cases, * we can do things to a blocked device. CAREFUL!!!! * * File daemon commands are handled in fd_cmds.c * * Kern Sibbald, May MMI */ #include "bareos.h" #include "stored.h" /* Exported variables */ /* Imported variables */ extern BSOCK *filed_chan; extern struct s_last_job last_job; extern bool init_done; /* Commands received from director that need scanning */ static char setbandwidth[] = "setbandwidth=%lld Job=%127s"; static char setdebugv0cmd[] = "setdebug=%d trace=%d"; static char setdebugv1cmd[] = "setdebug=%d trace=%d timestamp=%d"; static char cancelcmd[] = "cancel Job=%127s"; static char relabelcmd[] = "relabel %127s OldName=%127s NewName=%127s PoolName=%127s " "MediaType=%127s Slot=%d drive=%d MinBlocksize=%d MaxBlocksize=%d"; static char labelcmd[] = "label %127s VolumeName=%127s PoolName=%127s " "MediaType=%127s Slot=%d drive=%d MinBlocksize=%d MaxBlocksize=%d"; static char mountslotcmd[] = "mount %127s drive=%d slot=%d"; static char mountcmd[] = "mount %127s drive=%d"; static char unmountcmd[] = "unmount %127s drive=%d"; #if 0 static char actionopcmd[] = "action_on_purge %127s vol=%127s action=%d"; #endif static char releasecmd[] = "release %127s drive=%d"; static char readlabelcmd[] = "readlabel %127s Slot=%d drive=%d"; static char replicatecmd[] = "replicate Job=%127s address=%s port=%d ssl=%d Authorization=%100s"; static char passiveclientcmd[] = "passive client address=%s port=%d ssl=%d"; static char resolvecmd[] = "resolve %s"; static char pluginoptionscmd[] = "pluginoptions %s"; /* Responses sent to Director */ static char derrmsg[] = "3900 Invalid command:"; static char OKsetdebugv0[] = "3000 OK setdebug=%d tracefile=%s\n"; static char OKsetdebugv1[] = "3000 OK setdebug=%d trace=%d timestamp=%d tracefile=%s\n"; static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n"; static char OK_bootstrap[] = "3000 OK bootstrap\n"; static char ERROR_bootstrap[] = "3904 Error bootstrap\n"; static char OK_replicate[] = "3000 OK replicate\n"; static char BADcmd[] = "3991 Bad %s command: %s\n"; static char OKBandwidth[] = "2000 OK Bandwidth\n"; static char OKpassive[] = "2000 OK passive client\n"; static char OKpluginoptions[] = "2000 OK plugin options\n"; /* Imported functions */ extern bool finish_cmd(JCR *jcr); extern bool job_cmd(JCR *jcr); extern bool nextrun_cmd(JCR *jcr); extern bool dotstatus_cmd(JCR *jcr); //extern bool query_cmd(JCR *jcr); extern bool status_cmd(JCR *sjcr); extern bool use_cmd(JCR *jcr); extern bool stats_cmd(JCR *jcr); extern bool do_job_run(JCR *jcr); extern bool do_mac_run(JCR *jcr); extern void terminate_child(); /* Forward referenced functions */ //static bool action_on_purge_cmd(JCR *jcr); static bool bootstrap_cmd(JCR *jcr); static bool cancel_cmd(JCR *cjcr); static bool changer_cmd(JCR *jcr); static bool die_cmd(JCR *jcr); static bool label_cmd(JCR *jcr); static bool listen_cmd(JCR *jcr); static bool mount_cmd(JCR *jcr); static bool passive_cmd(JCR *jcr); static bool pluginoptions_cmd(JCR *jcr); static bool readlabel_cmd(JCR *jcr); static bool resolve_cmd(JCR *jcr); static bool relabel_cmd(JCR *jcr); static bool release_cmd(JCR *jcr); static bool replicate_cmd(JCR *jcr); static bool run_cmd(JCR *jcr); static bool setbandwidth_cmd(JCR *jcr); static bool setdebug_cmd(JCR *jcr); static bool unmount_cmd(JCR *jcr); static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive, BLOCKSIZES *blocksizes); static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot); static void label_volume_if_ok(DCR *dcr, char *oldname, char *newname, char *poolname, int Slot, bool relabel); static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName); static void send_dir_busy_message(BSOCK *dir, DEVICE *dev); struct s_cmds { const char *cmd; bool (*func)(JCR *jcr); bool monitoraccess; /* set if monitors can access this cmd */ }; /* * The following are the recognized commands from the Director. * * Keywords are sorted first longest match when the keywords start with the same string. */ static struct s_cmds cmds[] = { // { "action_on_purge", action_on_purge_cmd, false }, { "autochanger", changer_cmd, false }, { "bootstrap", bootstrap_cmd, false }, { "cancel", cancel_cmd, false }, { ".die", die_cmd, false }, { "finish", finish_cmd, false }, /* End of backup */ { "JobId=", job_cmd, false }, /* Start Job */ { "label", label_cmd, false }, /* Label a tape */ { "listen", listen_cmd, false }, /* Listen for an incoming Storage Job */ { "mount", mount_cmd, false }, { "nextrun", nextrun_cmd, false }, /* Prepare for next backup/restore part of same Job */ { "passive", passive_cmd, false }, { "pluginoptions", pluginoptions_cmd, false }, // { "query", query_cmd, false }, { "readlabel", readlabel_cmd, false }, { "relabel", relabel_cmd, false }, /* Relabel a tape */ { "release", release_cmd, false }, { "resolve", resolve_cmd, false }, { "replicate", replicate_cmd, false }, /* Replicate data to an external SD */ { "run", run_cmd, false }, /* Start of Job */ { "setbandwidth=", setbandwidth_cmd, false }, { "setdebug=", setdebug_cmd, false }, /* Set debug level */ { "stats", stats_cmd, false }, { "status", status_cmd, true }, { ".status", dotstatus_cmd, true }, { "unmount", unmount_cmd, false }, { "use storage=", use_cmd, false }, { NULL, NULL, false } /* list terminator */ }; /* * Connection request from an director. * * Basic tasks done here: * - Create a JCR record * - Authenticate the Director * - We wait for a command * - We execute the command * - We continue or exit depending on the return status */ static void *handle_director_connection(BSOCK *dir, char *job_name) { JCR *jcr; int i, errstat; int bnet_stat = 0; bool found, quit; /* * This is a connection from the Director, so setup a JCR */ jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */ new_plugins(jcr); /* instantiate plugins */ jcr->dir_bsock = dir; /* save Director bsock */ jcr->dir_bsock->set_jcr(jcr); jcr->dcrs = New(alist(10, not_owned_by_alist)); /* * Initialize Start Job condition variable */ errstat = pthread_cond_init(&jcr->job_start_wait, NULL); if (errstat != 0) { berrno be; Jmsg1(jcr, M_FATAL, 0, _("Unable to init job start cond variable: ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } /* * Initialize End Job condition variable */ errstat = pthread_cond_init(&jcr->job_end_wait, NULL); if (errstat != 0) { berrno be; Jmsg1(jcr, M_FATAL, 0, _("Unable to init job end cond variable: ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } Dmsg0(1000, "stored in start_job\n"); set_jcr_in_tsd(jcr); /* * Authenticate the Director */ if (!authenticate_director(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n")); goto bail_out; } Dmsg0(90, "Message channel init completed.\n"); quit = false; while (!quit) { /* * Read command */ if ((bnet_stat = dir->recv()) <= 0) { break; /* connection terminated */ } Dmsg1(199, "msg); /* * Ensure that device initialization is complete */ while (!init_done) { bmicrosleep(1, 0); } found = false; for (i = 0; cmds[i].cmd; i++) { if (bstrncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd))) { if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) { Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd); dir->fsend(invalid_cmd); dir->signal(BNET_EOD); break; } Dmsg1(200, "Do command: %s\n", cmds[i].cmd); if (!cmds[i].func(jcr)) { /* do command */ quit = true; /* error, get out */ Dmsg1(190, "Command %s requests quit\n", cmds[i].cmd); } found = true; /* indicate command found */ break; } } if (!found) { /* command not found */ POOL_MEM err_msg; Mmsg(err_msg, "%s %s\n", derrmsg, dir->msg); dir->fsend(err_msg.c_str()); break; } } bail_out: generate_plugin_event(jcr, bsdEventJobEnd); dequeue_messages(jcr); /* send any queued messages */ dir->signal(BNET_TERMINATE); free_plugins(jcr); /* release instantiated plugins */ free_jcr(jcr); return NULL; } /* * Connection request. We accept connections either from the * Director, Storage Daemon or a Client (File daemon). * * Note, we are running as a seperate thread of the Storage daemon. * * Basic tasks done here: * - If it was a connection from the FD, call handle_filed_connection() * - If it was a connection from an other SD, call handle_stored_connection() * - Otherwise it was a connection from the DIR, call handle_director_connection() */ void *handle_connection_request(void *arg) { BSOCK *bs = (BSOCK *)arg; char name[500]; char tbuf[100]; if (bs->recv() <= 0) { Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who()); bmicrosleep(5, 0); /* make user wait 5 seconds */ bs->close(); return NULL; } /* * Do a sanity check on the message received */ if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)) { Dmsg1(000, "msg); Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen); bmicrosleep(5, 0); /* make user wait 5 seconds */ bs->close(); return NULL; } Dmsg1(110, "Conn: %s", bs->msg); /* * See if this is a File daemon connection. If so call FD handler. */ if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) { Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); return handle_filed_connection(bs, name); } /* * See if this is a Storage daemon connection. If so call SD handler. */ if (sscanf(bs->msg, "Hello Start Storage Job %127s", name) == 1) { Dmsg1(110, "Got a SD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); return handle_stored_connection(bs, name); } Dmsg1(110, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); return handle_director_connection(bs, name); } /* * Force SD to die, and hopefully dump itself. Turned on only in development version. */ static bool die_cmd(JCR *jcr) { #ifdef DEVELOPER JCR *djcr = NULL; int a; BSOCK *dir = jcr->dir_bsock; pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER; if (strstr(dir->msg, "deadlock")) { Pmsg0(000, "I have been requested to deadlock ...\n"); P(m); P(m); } Pmsg1(000, "I have been requested to die ... (%s)\n", dir->msg); a = djcr->JobId; /* ref NULL pointer */ djcr->JobId = a; #endif return false; } /** * Set bandwidth limit as requested by the Director */ static bool setbandwidth_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; int64_t bw = 0; JCR *cjcr; char Job[MAX_NAME_LENGTH]; *Job = 0; if (sscanf(dir->msg, setbandwidth, &bw, Job) != 2 || bw < 0) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("2991 Bad setbandwidth command: %s\n"), jcr->errmsg); return false; } if (*Job) { if (!(cjcr = get_jcr_by_full_name(Job))) { dir->fsend(_("2901 Job %s not found.\n"), Job); } else { cjcr->max_bandwidth = bw; if (cjcr->store_bsock) { cjcr->store_bsock->set_bwlimit(bw); if (me->allow_bw_bursting) { cjcr->store_bsock->set_bwlimit_bursting(); } } free_jcr(cjcr); } } else { /* No job requested, apply globally */ me->max_bandwidth_per_job = bw; /* Overwrite directive */ } return dir->fsend(OKBandwidth); } /* * Set debug level as requested by the Director */ static bool setdebug_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; int32_t level, trace_flag, timestamp_flag; int scan; Dmsg1(10, "setdebug_cmd: %s", dir->msg); scan = sscanf(dir->msg, setdebugv1cmd, &level, &trace_flag, ×tamp_flag); if (scan != 3) { scan = sscanf(dir->msg, setdebugv0cmd, &level, &trace_flag); } if ((scan != 3 && scan != 2) || level < 0) { dir->fsend(BADcmd, "setdebug", dir->msg); return false; } POOL_MEM tracefilename(PM_FNAME); Mmsg(tracefilename, "%s/%s.trace", TRACEFILEDIRECTORY, my_name); debug_level = level; set_trace(trace_flag); if (scan == 3) { set_timestamp(timestamp_flag); Dmsg4(50, "level=%d trace=%d timestamp=%d tracefilename=%s\n", level, get_trace(), get_timestamp(), tracefilename.c_str()); return dir->fsend(OKsetdebugv1, level, get_trace(), get_timestamp(), tracefilename.c_str()); } else { Dmsg3(50, "level=%d trace=%d\n", level, get_trace(), tracefilename.c_str()); return dir->fsend(OKsetdebugv0, level, tracefilename.c_str()); } } /* * Cancel a Job * Be careful, we switch to using the job's JCR! So, using * BSOCKs on that jcr can have two threads in the same code. */ static bool cancel_cmd(JCR *cjcr) { BSOCK *dir = cjcr->dir_bsock; int oldStatus; char Job[MAX_NAME_LENGTH]; JobId_t JobId; JCR *jcr; int status; const char *reason; if (sscanf(dir->msg, cancelcmd, Job) == 1) { status = JS_Canceled; reason = "canceled"; } else { dir->fsend(_("3903 Error scanning cancel command.\n")); goto bail_out; } /* * See if the Jobname is a number only then its a JobId. */ if (is_a_number(Job)) { JobId = str_to_int64(Job); if (!(jcr = get_jcr_by_id(JobId))) { dir->fsend(_("3904 Job %s not found.\n"), Job); goto bail_out; } } else { if (!(jcr = get_jcr_by_full_name(Job))) { dir->fsend(_("3904 Job %s not found.\n"), Job); goto bail_out; } } oldStatus = jcr->JobStatus; jcr->setJobStatus(status); Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr); if (!jcr->authenticated && (oldStatus == JS_WaitFD || oldStatus == JS_WaitSD)) { pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */ } if (jcr->file_bsock) { jcr->file_bsock->set_terminated(); jcr->file_bsock->set_timed_out(); Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr); } else { if (oldStatus != JS_WaitSD) { /* * Still waiting for FD to connect, release it */ pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */ Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr); } } /* * If thread waiting on mount, wake him */ if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) { pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId); release_device_cond(); } if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) { pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId); release_device_cond(); } /* * See if the Job has a certain protocol. * When canceling a NDMP job make sure we call the end_of_ndmp_* functions. */ switch (jcr->getJobProtocol()) { case PT_NDMP: switch (jcr->getJobType()) { case JT_BACKUP: end_of_ndmp_backup(jcr); break; case JT_RESTORE: end_of_ndmp_restore(jcr); break; default: break; } } pthread_cond_signal(&jcr->job_end_wait); /* wake waiting job */ dir->fsend(_("3000 JobId=%ld Job=\"%s\" marked to be %s.\n"), jcr->JobId, jcr->Job, reason); free_jcr(jcr); bail_out: dir->signal(BNET_EOD); return true; } /* * Resolve a hostname */ static bool resolve_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; dlist *addr_list; const char *errstr; char addresses[2048]; char hostname[2048]; sscanf(dir->msg, resolvecmd, &hostname); if ((addr_list = bnet_host2ipaddrs(hostname, 0, &errstr)) == NULL) { dir->fsend(_("%s: Failed to resolve %s\n"), my_name, hostname); goto bail_out; } dir->fsend(_("%s resolves %s to %s\n"), my_name, hostname, build_addresses_str(addr_list, addresses, sizeof(addresses), false)); free_addresses(addr_list); bail_out: dir->signal(BNET_EOD); return true; } static bool do_label(JCR *jcr, bool relabel) { int len; POOLMEM *newname, *oldname, *poolname, *mediatype; POOL_MEM dev_name; BSOCK *dir = jcr->dir_bsock; DCR *dcr; DEVICE *dev; BLOCKSIZES blocksizes; bool ok = false; int32_t slot, drive; //, max_block_size, min_block_size; /* * Determine the length of the temporary buffers. * If the total length of the incoming message is less * then MAX_NAME_LENGTH we can use that as the upper limit. * If the incomming message is bigger then MAX_NAME_LENGTH * limit the temporary buffer to MAX_NAME_LENGTH bytes as * we use a sscanf %127s for reading the temorary buffer. */ len = dir->msglen + 1; if (len > MAX_NAME_LENGTH) { len = MAX_NAME_LENGTH; } newname = get_memory(len); oldname = get_memory(len); poolname = get_memory(len); mediatype = get_memory(len); if (relabel) { if (sscanf(dir->msg, relabelcmd, dev_name.c_str(), oldname, newname, poolname, mediatype, &slot, &drive, &blocksizes.min_block_size, &blocksizes.max_block_size) == 9) { ok = true; } } else { *oldname = 0; if (sscanf(dir->msg, labelcmd, dev_name.c_str(), newname, poolname, mediatype, &slot, &drive, &blocksizes.min_block_size, &blocksizes.max_block_size) == 8) { ok = true; } } if (ok) { unbash_spaces(newname); unbash_spaces(oldname); unbash_spaces(poolname); unbash_spaces(mediatype); dcr = find_device(jcr, dev_name, drive, &blocksizes); if (dcr) { dev = dcr->dev; dev->Lock(); /* Use P to avoid indefinite block */ dcr->VolMinBlocksize = blocksizes.min_block_size; dcr->VolMaxBlocksize = blocksizes.max_block_size; dev->set_blocksizes(dcr); /* apply blocksizes from dcr to dev */ if (!dev->is_open() && !dev->is_busy()) { Dmsg1(400, "Can %slabel. Device is not open\n", relabel ? "re" : ""); label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel); dev->close(dcr); /* Under certain "safe" conditions, we can steal the lock */ } else if (dev->can_steal_lock()) { Dmsg0(400, "Can relabel. can_steal_lock\n"); label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel); } else if (dev->is_busy() || dev->is_blocked()) { send_dir_busy_message(dir, dev); } else { /* device not being used */ Dmsg0(400, "Can relabel. device not used\n"); label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel); } dev->Unlock(); free_dcr(dcr); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str()); } } else { /* NB dir->msg gets clobbered in bnet_fsend, so save command */ pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3903 Error scanning label command: %s\n"), jcr->errmsg); } free_memory(oldname); free_memory(newname); free_memory(poolname); free_memory(mediatype); dir->signal(BNET_EOD); return true; } /* * Label a Volume */ static bool label_cmd(JCR *jcr) { return do_label(jcr, false); } static bool relabel_cmd(JCR *jcr) { return do_label(jcr, true); } /* * Read the tape label and determine if we can safely * label the tape (not a Bareos volume), then label it. * * Enter with the mutex set */ static void label_volume_if_ok(DCR *dcr, char *oldname, char *newname, char *poolname, int slot, bool relabel) { BSOCK *dir = dcr->jcr->dir_bsock; bsteal_lock_t hold; DEVICE *dev = dcr->dev; int label_status; int mode; const char *volname = relabel ? oldname : newname; char ed1[50]; steal_device_lock(dev, &hold, BST_WRITING_LABEL); Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name()); Dmsg0(90, "try_autoload_device - looking for volume_info\n"); if (!try_autoload_device(dcr->jcr, dcr, slot, volname)) { goto bail_out; /* error */ } /* Ensure that the device is open -- autoload_device() closes it */ if (dev->is_tape()) { mode = OPEN_READ_WRITE; } else { mode = CREATE_READ_WRITE; } /* Set old volume name for open if relabeling */ dcr->setVolCatName(volname); if (!dev->open(dcr, mode)) { dir->fsend(_("3910 Unable to open device \"%s\": ERR=%s\n"), dev->print_name(), dev->bstrerror()); goto bail_out; } /* See what we have for a Volume */ label_status = read_dev_volume_label(dcr); /* Set new volume name */ dcr->setVolCatName(newname); switch(label_status) { case VOL_NAME_ERROR: case VOL_VERSION_ERROR: case VOL_LABEL_ERROR: case VOL_OK: if (!relabel) { dir->fsend(_("3920 Cannot label Volume because it is already labeled: \"%s\"\n"), dev->VolHdr.VolumeName); goto bail_out; } /* Relabel request. If oldname matches, continue */ if (!bstrcmp(oldname, dev->VolHdr.VolumeName)) { dir->fsend(_("3921 Wrong volume mounted.\n")); goto bail_out; } if (dev->label_type != B_BAREOS_LABEL) { dir->fsend(_("3922 Cannot relabel an ANSI/IBM labeled Volume.\n")); goto bail_out; } /* Fall through wanted! */ case VOL_IO_ERROR: case VOL_NO_LABEL: if (!write_new_volume_label_to_dev(dcr, newname, poolname, relabel)) { dir->fsend(_("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror()); goto bail_out; } bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName)); /* The following 3000 OK label. string is scanned in ua_label.c */ dir->fsend("3000 OK label. VolBytes=%s Volume=\"%s\" Device=%s\n", edit_uint64(dev->VolCatInfo.VolCatBytes, ed1), newname, dev->print_name()); break; case VOL_NO_MEDIA: dir->fsend(_("3914 Failed to label Volume (no media): ERR=%s\n"), dev->bstrerror()); break; default: dir->fsend(_("3913 Cannot label Volume. " "Unknown status %d from read_volume_label()\n"), label_status); break; } bail_out: if (dev->is_open() && !dev->has_cap(CAP_ALWAYSOPEN)) { dev->close(dcr); } if (!dev->is_open()) { dev->clear_volhdr(); } volume_unused(dcr); /* no longer using volume */ give_back_device_lock(dev, &hold); return; } /* * Read the tape label * * Enter with the mutex set */ static bool read_label(DCR *dcr) { int ok; JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; bsteal_lock_t hold; DEVICE *dev = dcr->dev; steal_device_lock(dev, &hold, BST_DOING_ACQUIRE); dcr->VolumeName[0] = 0; dev->clear_labeled(); /* force read of label */ switch (read_dev_volume_label(dcr)) { case VOL_OK: dir->fsend(_("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName); ok = true; break; default: dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"), dev->print_name(), jcr->errmsg); ok = false; break; } volume_unused(dcr); give_back_device_lock(dev, &hold); return ok; } /* * Searches for device by name, and if found, creates a dcr and returns it. */ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive, BLOCKSIZES *blocksizes) { DEVRES *device; AUTOCHANGERRES *changer; bool found = false; DCR *dcr = NULL; unbash_spaces(devname); foreach_res(device, R_DEVICE) { /* Find resource, and make sure we were able to open it */ if (bstrcmp(device->hdr.name, devname.c_str())) { if (!device->dev) { device->dev = init_dev(jcr, device); } if (!device->dev) { Jmsg(jcr, M_WARNING, 0, _("\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n"), devname.c_str()); continue; } Dmsg1(20, "Found device %s\n", device->hdr.name); found = true; break; } } if (!found) { foreach_res(changer, R_AUTOCHANGER) { /* Find resource, and make sure we were able to open it */ if (bstrcmp(devname.c_str(), changer->hdr.name)) { /* Try each device in this AutoChanger */ foreach_alist(device, changer->device) { Dmsg1(100, "Try changer device %s\n", device->hdr.name); if (!device->dev) { device->dev = init_dev(jcr, device); } if (!device->dev) { Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str()); Jmsg(jcr, M_WARNING, 0, _("\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"), device->hdr.name, devname.c_str()); continue; } if (!device->dev->autoselect) { Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str()); continue; /* device is not available */ } if (drive < 0 || drive == (int)device->dev->drive_index) { Dmsg1(20, "Found changer device %s\n", device->hdr.name); found = true; break; } Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n", devname.c_str(), drive, (int)device->dev->drive_index); } break; /* we found it but could not open a device */ } } } if (found) { Dmsg1(100, "Found device %s\n", device->hdr.name); dcr = New(SD_DCR); setup_new_dcr_device(jcr, dcr, device->dev, blocksizes); dcr->set_will_write(); dcr->device = device; } return dcr; } /* * Mount command from Director */ static bool mount_cmd(JCR *jcr) { POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; int32_t drive; int32_t slot = 0; bool ok; ok = sscanf(dir->msg, mountslotcmd, devname.c_str(), &drive, &slot) == 3; if (!ok) { ok = sscanf(dir->msg, mountcmd, devname.c_str(), &drive) == 2; } Dmsg3(100, "ok=%d drive=%d slot=%d\n", ok, drive, slot); if (ok) { dcr = find_device(jcr, devname, drive, NULL); if (dcr) { dev = dcr->dev; dev->Lock(); /* Use P to avoid indefinite block */ Dmsg2(100, "mount cmd blocked=%d must_unload=%d\n", dev->blocked(), dev->must_unload()); switch (dev->blocked()) { /* device blocked? */ case BST_WAITING_FOR_SYSOP: /* Someone is waiting, wake him */ Dmsg0(100, "Waiting for mount. Attempting to wake thread\n"); dev->set_blocked(BST_MOUNT); dir->fsend("3001 OK mount requested. %sDevice=%s\n", (slot > 0) ? _("Specified slot ignored. ") : "", dev->print_name()); pthread_cond_broadcast(&dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId); release_device_cond(); break; /* In both of these two cases, we (the user) unmounted the Volume */ case BST_UNMOUNTED_WAITING_FOR_SYSOP: case BST_UNMOUNTED: Dmsg2(100, "Unmounted changer=%d slot=%d\n", dev->is_autochanger(), slot); if (dev->is_autochanger() && slot > 0) { try_autoload_device(jcr, dcr, slot, ""); } /* We freed the device, so reopen it and wake any waiting threads */ if (!dev->open(dcr, OPEN_READ_ONLY)) { dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"), dev->print_name(), dev->bstrerror()); if (dev->blocked() == BST_UNMOUNTED) { /* We blocked the device, so unblock it */ Dmsg0(100, "Unmounted. Unblocking device\n"); unblock_device(dev); } break; } read_dev_volume_label(dcr); if (dev->blocked() == BST_UNMOUNTED) { /* We blocked the device, so unblock it */ Dmsg0(100, "Unmounted. Unblocking device\n"); read_label(dcr); /* this should not be necessary */ unblock_device(dev); } else { Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n"); dev->set_blocked(BST_MOUNT); } if (dev->is_labeled()) { dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"), dev->print_name(), dev->VolHdr.VolumeName); } else { dir->fsend(_("3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n"), dev->print_name()); } pthread_cond_broadcast(&dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId); release_device_cond(); break; case BST_DOING_ACQUIRE: dir->fsend(_("3001 Device \"%s\" is doing acquire.\n"), dev->print_name()); break; case BST_WRITING_LABEL: dir->fsend(_("3903 Device \"%s\" is being labeled.\n"), dev->print_name()); break; case BST_NOT_BLOCKED: Dmsg2(100, "Not blocked changer=%d slot=%d\n", dev->is_autochanger(), slot); if (dev->is_autochanger() && slot > 0) { try_autoload_device(jcr, dcr, slot, ""); } if (dev->is_open()) { if (dev->is_labeled()) { dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"), dev->print_name(), dev->VolHdr.VolumeName); } else { dir->fsend(_("3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n"), dev->print_name()); } } else if (dev->is_tape()) { if (!dev->open(dcr, OPEN_READ_ONLY)) { dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"), dev->print_name(), dev->bstrerror()); break; } read_label(dcr); if (dev->is_labeled()) { dir->fsend(_("3001 Device \"%s\" is already mounted with Volume \"%s\"\n"), dev->print_name(), dev->VolHdr.VolumeName); } else { dir->fsend(_("3905 Device \"%s\" open but no Bareos volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n"), dev->print_name()); } if (dev->is_open() && !dev->has_cap(CAP_ALWAYSOPEN)) { dev->close(dcr); } } else if (dev->is_unmountable()) { if (dev->mount(dcr, 1)) { dir->fsend(_("3002 Device \"%s\" is mounted.\n"), dev->print_name()); } else { dir->fsend(_("3907 %s"), dev->bstrerror()); } } else { /* must be file */ dir->fsend(_("3906 File device \"%s\" is always mounted.\n"), dev->print_name()); pthread_cond_broadcast(&dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId); release_device_cond(); } break; case BST_RELEASING: dir->fsend(_("3930 Device \"%s\" is being released.\n"), dev->print_name()); break; default: dir->fsend(_("3905 Unknown wait state %d\n"), dev->blocked()); break; } dev->Unlock(); free_dcr(dcr); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3909 Error scanning mount command: %s\n"), jcr->errmsg); } dir->signal(BNET_EOD); return true; } /* * unmount command from Director */ static bool unmount_cmd(JCR *jcr) { POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; int32_t drive; if (sscanf(dir->msg, unmountcmd, devname.c_str(), &drive) == 2) { dcr = find_device(jcr, devname, drive, NULL); if (dcr) { dev = dcr->dev; dev->Lock(); /* Use P to avoid indefinite block */ if (!dev->is_open()) { if (!dev->is_busy()) { unload_autochanger(dcr, -1); } if (dev->is_unmountable()) { if (dev->unmount(dcr, 0)) { dir->fsend(_("3002 Device \"%s\" unmounted.\n"), dev->print_name()); } else { dir->fsend(_("3907 %s"), dev->bstrerror()); } } else { Dmsg0(90, "Device already unmounted\n"); dir->fsend(_("3901 Device \"%s\" is already unmounted.\n"), dev->print_name()); } } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) { Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting, dev->blocked()); if (!unload_autochanger(dcr, -1)) { /* ***FIXME**** what is this ???? */ dev->close(dcr); free_volume(dev); } if (dev->is_unmountable() && !dev->unmount(dcr, 0)) { dir->fsend(_("3907 %s"), dev->bstrerror()); } else { dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP); dir->fsend(_("3001 Device \"%s\" unmounted.\n"), dev->print_name()); } } else if (dev->blocked() == BST_DOING_ACQUIRE) { dir->fsend(_("3902 Device \"%s\" is busy in acquire.\n"), dev->print_name()); } else if (dev->blocked() == BST_WRITING_LABEL) { dir->fsend(_("3903 Device \"%s\" is being labeled.\n"), dev->print_name()); } else if (dev->is_busy()) { send_dir_busy_message(dir, dev); } else { /* device not being used */ Dmsg0(90, "Device not in use, unmounting\n"); /* On FreeBSD, I am having ASSERT() failures in block_device() * and I can only imagine that the thread id that we are * leaving in no_wait_id is being re-used. So here, * we simply do it by hand. Gross, but a solution. */ /* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */ dev->set_blocked(BST_UNMOUNTED); clear_thread_id(dev->no_wait_id); if (!unload_autochanger(dcr, -1)) { dev->close(dcr); free_volume(dev); } if (dev->is_unmountable() && !dev->unmount(dcr, 0)) { dir->fsend(_("3907 %s"), dev->bstrerror()); } else { dir->fsend(_("3002 Device \"%s\" unmounted.\n"), dev->print_name()); } } dev->Unlock(); free_dcr(dcr); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { /* NB dir->msg gets clobbered in bnet_fsend, so save command */ pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3907 Error scanning unmount command: %s\n"), jcr->errmsg); } dir->signal(BNET_EOD); return true; } #if 0 /* * The truncate command will recycle a volume. The director can call this * after purging a volume so that disk space will not be wasted. Only useful * for File Storage, of course. * * * It is currently disabled */ static bool action_on_purge_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; char devname[MAX_NAME_LENGTH]; char volumename[MAX_NAME_LENGTH]; int32_t action; /* TODO: Need to find a free device and ask for slot to the director */ if (sscanf(dir->msg, actionopcmd, devname, volumename, &action) != 3) { dir->fsend(_("3916 Error scanning action_on_purge command\n")); goto done; } unbash_spaces(volumename); unbash_spaces(devname); /* Check if action is correct */ if (action & AOP_TRUNCTATE) { } /* ... */ done: dir->signal(BNET_EOD); return true; } #endif /* * Release command from Director. This rewinds the device and if * configured does a offline and ensures that Bareos will * re-read the label of the tape before continuing. This gives * the operator the chance to change the tape anytime before the * next job starts. */ static bool release_cmd(JCR *jcr) { POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; int32_t drive; if (sscanf(dir->msg, releasecmd, devname.c_str(), &drive) == 2) { dcr = find_device(jcr, devname, drive, NULL); if (dcr) { dev = dcr->dev; dev->Lock(); /* Use P to avoid indefinite block */ if (!dev->is_open()) { if (!dev->is_busy()) { unload_autochanger(dcr, -1); } Dmsg0(90, "Device already released\n"); dir->fsend(_("3921 Device \"%s\" already released.\n"), dev->print_name()); } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) { Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting, dev->blocked()); unload_autochanger(dcr, -1); dir->fsend(_("3922 Device \"%s\" waiting for sysop.\n"), dev->print_name()); } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) { Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting, dev->blocked()); dir->fsend(_("3922 Device \"%s\" waiting for mount.\n"), dev->print_name()); } else if (dev->blocked() == BST_DOING_ACQUIRE) { dir->fsend(_("3923 Device \"%s\" is busy in acquire.\n"), dev->print_name()); } else if (dev->blocked() == BST_WRITING_LABEL) { dir->fsend(_("3914 Device \"%s\" is being labeled.\n"), dev->print_name()); } else if (dev->is_busy()) { send_dir_busy_message(dir, dev); } else { /* device not being used */ Dmsg0(90, "Device not in use, releasing\n"); dcr->release_volume(); dir->fsend(_("3022 Device \"%s\" released.\n"), dev->print_name()); } dev->Unlock(); free_dcr(dcr); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { /* NB dir->msg gets clobbered in bnet_fsend, so save command */ pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3927 Error scanning release command: %s\n"), jcr->errmsg); } dir->signal(BNET_EOD); return true; } static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER; static uint32_t bsr_uniq = 0; static inline bool get_bootstrap_file(JCR *jcr, BSOCK *sock) { POOLMEM *fname = get_pool_memory(PM_FNAME); FILE *bs; bool ok = false; if (jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); free_pool_memory(jcr->RestoreBootstrap); } P(bsr_mutex); bsr_uniq++; Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name, jcr->Job, bsr_uniq); V(bsr_mutex); Dmsg1(400, "bootstrap=%s\n", fname); jcr->RestoreBootstrap = fname; bs = fopen(fname, "a+b"); /* create file */ if (!bs) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"), jcr->RestoreBootstrap, be.bstrerror()); goto bail_out; } Dmsg0(10, "=== Bootstrap file ===\n"); while (sock->recv() >= 0) { Dmsg1(10, "%s", sock->msg); fputs(sock->msg, bs); } fclose(bs); Dmsg0(10, "=== end bootstrap file ===\n"); jcr->bsr = parse_bsr(jcr, jcr->RestoreBootstrap); if (!jcr->bsr) { Jmsg(jcr, M_FATAL, 0, _("Error parsing bootstrap file.\n")); goto bail_out; } if (debug_level >= 10) { dump_bsr(jcr->bsr, true); } /* If we got a bootstrap, we are reading, so create read volume list */ create_restore_volume_list(jcr); ok = true; bail_out: unlink(jcr->RestoreBootstrap); free_pool_memory(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; if (!ok) { sock->fsend(ERROR_bootstrap); return false; } return sock->fsend(OK_bootstrap); } static bool bootstrap_cmd(JCR *jcr) { return get_bootstrap_file(jcr, jcr->dir_bsock); } /* * Autochanger command from Director */ static bool changer_cmd(JCR *jcr) { int src_slot, dst_slot; POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; const char *cmd = NULL; bool ok = false; bool is_transfer = false; /* * A safe_cmd may call autochanger script but does not load/unload * slots so it can be done at the same time that the drive is open. */ bool safe_cmd = false; if (sscanf(dir->msg, "autochanger listall %127s", devname.c_str()) == 1) { cmd = "listall"; safe_cmd = ok = true; } else if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) { cmd = "list"; safe_cmd = ok = true; } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) { cmd = "slots"; safe_cmd = ok = true; } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) { cmd = "drives"; safe_cmd = ok = true; } else if (sscanf(dir->msg, "autochanger transfer %127s %d %d", devname.c_str(), &src_slot, &dst_slot) == 3) { cmd = "transfer"; safe_cmd = ok = true; is_transfer = true; } if (ok) { dcr = find_device(jcr, devname, -1, NULL); if (dcr) { dev = dcr->dev; dev->Lock(); /* Use P to avoid indefinite block */ if (!dev->device->changer_res) { dir->fsend(_("3998 Device \"%s\" is not an autochanger.\n"), dev->print_name()); /* Under certain "safe" conditions, we can steal the lock */ } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) { if (is_transfer) { autochanger_transfer_cmd(dcr, dir, src_slot, dst_slot); } else { autochanger_cmd(dcr, dir, cmd); } } else if (dev->is_busy() || dev->is_blocked()) { send_dir_busy_message(dir, dev); } else { /* device not being used */ if (is_transfer) { autochanger_transfer_cmd(dcr, dir, src_slot, dst_slot); } else { autochanger_cmd(dcr, dir, cmd); } } dev->Unlock(); free_dcr(dcr); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { /* error on scanf */ pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3908 Error scanning autochanger drives/list/slots command: %s\n"), jcr->errmsg); } dir->signal(BNET_EOD); return true; } /* * Read and return the Volume label */ static bool readlabel_cmd(JCR *jcr) { POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; int32_t Slot, drive; if (sscanf(dir->msg, readlabelcmd, devname.c_str(), &Slot, &drive) == 3) { dcr = find_device(jcr, devname, drive, NULL); if (dcr) { dev = dcr->dev; dev->Lock(); /* Use P to avoid indefinite block */ if (!dev->is_open()) { read_volume_label(jcr, dcr, dev, Slot); dev->close(dcr); /* Under certain "safe" conditions, we can steal the lock */ } else if (dev->can_steal_lock()) { read_volume_label(jcr, dcr, dev, Slot); } else if (dev->is_busy() || dev->is_blocked()) { send_dir_busy_message(dir, dev); } else { /* device not being used */ read_volume_label(jcr, dcr, dev, Slot); } dev->Unlock(); free_dcr(dcr); } else { dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3909 Error scanning readlabel command: %s\n"), jcr->errmsg); } dir->signal(BNET_EOD); return true; } /* * Read the tape label * * Enter with the mutex set */ static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot) { BSOCK *dir = jcr->dir_bsock; bsteal_lock_t hold; dcr->set_dev(dev); steal_device_lock(dev, &hold, BST_WRITING_LABEL); if (!try_autoload_device(jcr, dcr, Slot, "")) { goto bail_out; /* error */ } dev->clear_labeled(); /* force read of label */ switch (read_dev_volume_label(dcr)) { case VOL_OK: /* DO NOT add quotes around the Volume name. It is scanned in the DIR */ dir->fsend(_("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot); Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName); break; default: dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"), dev->print_name(), jcr->errmsg); break; } bail_out: give_back_device_lock(dev, &hold); return; } static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName) { BSOCK *dir = jcr->dir_bsock; bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName)); dcr->VolCatInfo.Slot = slot; dcr->VolCatInfo.InChanger = slot > 0; if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */ return false; } return true; } static void send_dir_busy_message(BSOCK *dir, DEVICE *dev) { if (dev->is_blocked()) { switch (dev->blocked()) { case BST_UNMOUNTED: dir->fsend(_("3931 Device \"%s\" is BLOCKED. user unmounted.\n"), dev->print_name()); break; case BST_UNMOUNTED_WAITING_FOR_SYSOP: dir->fsend(_("3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n"), dev->print_name()); break; case BST_WAITING_FOR_SYSOP: dir->fsend(_("3933 Device \"%s\" is BLOCKED waiting for media.\n"), dev->print_name()); break; case BST_DOING_ACQUIRE: dir->fsend(_("3934 Device \"%s\" is being initialized.\n"), dev->print_name()); break; case BST_WRITING_LABEL: dir->fsend(_("3935 Device \"%s\" is blocked labeling a Volume.\n"), dev->print_name()); break; default: dir->fsend(_("3935 Device \"%s\" is blocked for unknown reason.\n"), dev->print_name()); break; } } else if (dev->can_read()) { dir->fsend(_("3936 Device \"%s\" is busy reading.\n"), dev->print_name()); } else { dir->fsend(_("3937 Device \"%s\" is busy with writers=%d reserved=%d.\n"), dev->print_name(), dev->num_writers, dev->num_reserved()); } } static inline void set_storage_auth_key(JCR *jcr, char *key) { /* * If no key don't update anything */ if (!*key) { return; } /* * Clear any sd_auth_key which can be a key when we are acting as * the endpoint for a backup session which we don't seem to be. */ if (jcr->sd_auth_key) { bfree(jcr->sd_auth_key); } jcr->sd_auth_key = bstrdup(key); Dmsg0(5, "set sd auth key\n"); } /* * Listen for incoming replication session from other SD. */ static bool listen_cmd(JCR *jcr) { Dsm_check(200); return do_listen_run(jcr); } /* * Get address of storage daemon from Director */ static bool replicate_cmd(JCR *jcr) { int stored_port; /* storage daemon port */ int enable_ssl; /* enable ssl to sd */ char JobName[MAX_NAME_LENGTH]; char stored_addr[MAX_NAME_LENGTH]; POOL_MEM sd_auth_key(PM_MESSAGE); BSOCK *dir = jcr->dir_bsock; BSOCK *sd; /* storage daemon bsock */ sd = New(BSOCK_TCP); if (me->nokeepalive) { sd->clear_keepalive(); } Dmsg1(100, "ReplicateCmd: %s", dir->msg); sd_auth_key.check_size(dir->msglen); if (sscanf(dir->msg, replicatecmd, JobName, stored_addr, &stored_port, &enable_ssl, sd_auth_key.c_str()) != 5) { dir->fsend(BADcmd, "replicate", dir->msg); goto bail_out; } set_storage_auth_key(jcr, sd_auth_key.c_str()); Dmsg3(110, "Open storage: %s:%d ssl=%d\n", stored_addr, stored_port, enable_ssl); sd->set_source_address(me->SDsrc_addr); if (!jcr->max_bandwidth) { if (jcr->director->max_bandwidth_per_job) { jcr->max_bandwidth = jcr->director->max_bandwidth_per_job; } else if (me->max_bandwidth_per_job) { jcr->max_bandwidth = me->max_bandwidth_per_job; } } sd->set_bwlimit(jcr->max_bandwidth); if (me->allow_bw_bursting) { sd->set_bwlimit_bursting(); } /* * Open command communications with Storage daemon */ if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval, _("Storage daemon"), stored_addr, NULL, stored_port, 1)) { delete sd; sd = NULL; } if (sd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"), stored_addr, stored_port); Dmsg2(100, "Failed to connect to Storage daemon: %s:%d\n", stored_addr, stored_port); goto bail_out; } Dmsg0(110, "Connection OK to SD.\n"); jcr->store_bsock = sd; sd->fsend("Hello Start Storage Job %s\n", JobName); if (!authenticate_with_storagedaemon(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Failed to authenticate Storage daemon.\n")); delete sd; goto bail_out; } Dmsg0(110, "Authenticated with SD.\n"); /* * Keep track that we are replicating to a remote SD. */ jcr->remote_replicate = true; /* * Send OK to Director */ return dir->fsend(OK_replicate); bail_out: return false; } static bool run_cmd(JCR *jcr) { Dsm_check(200); Dmsg1(200, "Run_cmd: %s\n", jcr->dir_bsock->msg); /* * If we do not need the FD, we are doing a migrate, copy, or virtual backup. */ if (jcr->no_client_used()) { return do_mac_run(jcr); } else { return do_job_run(jcr); } } static bool passive_cmd(JCR *jcr) { int filed_port; /* file daemon port */ int enable_ssl; /* enable ssl to fd */ char filed_addr[MAX_NAME_LENGTH]; BSOCK *dir = jcr->dir_bsock; BSOCK *fd; /* file daemon bsock */ Dmsg1(100, "PassiveClientCmd: %s", dir->msg); if (sscanf(dir->msg, passiveclientcmd, filed_addr, &filed_port, &enable_ssl) != 3) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad passiveclientcmd command: %s"), jcr->errmsg); goto bail_out; } Dmsg3(110, "PassiveClientCmd: %s:%d ssl=%d\n", filed_addr, filed_port, enable_ssl); jcr->passive_client = true; fd = New(BSOCK_TCP); if (me->nokeepalive) { fd->clear_keepalive(); } fd->set_source_address(me->SDsrc_addr); /* * Open command communications with passive filedaemon */ if (!fd->connect(jcr, 10, (int)me->FDConnectTimeout, me->heartbeat_interval, _("File Daemon"), filed_addr, NULL, filed_port, 1)) { delete fd; fd = NULL; } if (fd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Failed to connect to File daemon: %s:%d\n"), filed_addr, filed_port); Dmsg2(100, "Failed to connect to File daemon: %s:%d\n", filed_addr, filed_port); goto bail_out; } Dmsg0(110, "Connection OK to FD.\n"); jcr->file_bsock = fd; fd->fsend("Hello Storage calling Start Job %s\n", jcr->Job); if (!authenticate_with_filedaemon(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Failed to authenticate File daemon.\n")); delete fd; jcr->file_bsock = NULL; goto bail_out; } else { utime_t now; Dmsg0(110, "Authenticated with FD.\n"); /* * Update the initial Job Statistics. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); } /* * Send OK to Director */ return dir->fsend(OKpassive); bail_out: dir->fsend(BADcmd, "passive client"); return false; } static bool pluginoptions_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; char plugin_options[2048]; Dmsg1(100, "PluginOptionsCmd: %s", dir->msg); if (sscanf(dir->msg, pluginoptionscmd, plugin_options) != 1) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad pluginoptionscmd command: %s"), jcr->errmsg); goto bail_out; } unbash_spaces(plugin_options); if (!jcr->plugin_options) { jcr->plugin_options = New(alist(10, owned_by_alist)); } jcr->plugin_options->append(bstrdup(plugin_options)); /* * Send OK to Director */ return dir->fsend(OKpluginoptions); bail_out: dir->fsend(BADcmd, "plugin options"); return false; } bareos-Release-14.2.6/src/stored/ebcdic.c000066400000000000000000000135011263011562700201040ustar00rootroot00000000000000/* * Taken from the public domain ansitape program for * integration into Bareos. KES - Mar 2005 */ /* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Mapping of EBCDIC codes to ASCII equivalents. */ static char to_ascii_table[256] = { '\000', '\001', '\002', '\003', '\234', '\011', '\206', '\177', '\227', '\215', '\216', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\235', '\205', '\010', '\207', '\030', '\031', '\222', '\217', '\034', '\035', '\036', '\037', '\200', '\201', '\202', '\203', '\204', '\012', '\027', '\033', '\210', '\211', '\212', '\213', '\214', '\005', '\006', '\007', '\220', '\221', '\026', '\223', '\224', '\225', '\226', '\004', '\230', '\231', '\232', '\233', '\024', '\025', '\236', '\032', '\040', '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\133', '\056', '\074', '\050', '\053', '\041', '\046', '\251', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\135', '\044', '\052', '\051', '\073', '\136', '\055', '\057', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\174', '\054', '\045', '\137', '\076', '\077', '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\301', '\302', '\140', '\072', '\043', '\100', '\047', '\075', '\042', '\303', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\304', '\305', '\306', '\307', '\310', '\311', '\312', '\152', '\153', '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\313', '\314', '\315', '\316', '\317', '\320', '\321', '\176', '\163', '\164', '\165', '\166', '\167', '\170', '\171', '\172', '\322', '\323', '\324', '\325', '\326', '\327', '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\173', '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110', '\111', '\350', '\351', '\352', '\353', '\354', '\355', '\175', '\112', '\113', '\114', '\115', '\116', '\117', '\120', '\121', '\122', '\356', '\357', '\360', '\361', '\362', '\363', '\134', '\237', '\123', '\124', '\125', '\126', '\127', '\130', '\131', '\132', '\364', '\365', '\366', '\367', '\370', '\371', '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', '\070', '\071', '\372', '\373', '\374', '\375', '\376', '\377' }; /* Mapping of ASCII codes to EBCDIC equivalents. */ static char to_ebcdic_table[256] = { '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057', '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046', '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037', '\100', '\117', '\177', '\173', '\133', '\154', '\120', '\175', '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157', '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307', '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326', '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\112', '\340', '\132', '\137', '\155', '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207', '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\300', '\152', '\320', '\241', '\007', '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027', '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033', '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010', '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341', '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110', '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127', '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215', '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333', '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355', '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377' }; /* * Convert from ASCII to EBCDIC */ void ascii_to_ebcdic(char *dst, char *src, int count) { while (count--) { *dst++ = to_ebcdic_table[0377 & *src++]; } } /* * Convert from EBCDIC to ASCII */ void ebcdic_to_ascii(char *dst, char *src, int count) { while (count--) { *dst++ = to_ascii_table[0377 & *src++]; } } bareos-Release-14.2.6/src/stored/fd_cmds.c000066400000000000000000000276631263011562700203100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file handles commands from the File daemon. * * Kern Sibbald, MM * * We get here because the Director has initiated a Job with * the Storage daemon, then done the same with the File daemon, * then when the Storage daemon receives a proper connection from * the File daemon, control is passed here to handle the * subsequent File daemon commands. */ #include "bareos.h" #include "stored.h" /* Imported variables */ /* Static variables */ static char ferrmsg[] = "3900 Invalid command\n"; /* Imported functions */ /* Forward referenced FD commands */ static bool append_open_session(JCR *jcr); static bool append_close_session(JCR *jcr); static bool append_data_cmd(JCR *jcr); static bool append_end_session(JCR *jcr); static bool read_open_session(JCR *jcr); static bool read_data_cmd(JCR *jcr); static bool read_close_session(JCR *jcr); /* Exported function */ struct s_cmds { const char *cmd; bool (*func)(JCR *jcr); }; /* * The following are the recognized commands from the File daemon */ static struct s_cmds fd_cmds[] = { { "append open", append_open_session }, { "append data", append_data_cmd }, { "append end", append_end_session }, { "append close", append_close_session }, { "read open", read_open_session }, { "read data", read_data_cmd }, { "read close", read_close_session }, { NULL, NULL } /* list terminator */ }; /* Commands from the File daemon that require additional scanning */ static char read_open[] = "read open session = %127s %ld %ld %ld %ld %ld %ld\n"; /* Responses sent to the File daemon */ static char NO_open[] = "3901 Error session already open\n"; static char NOT_opened[] = "3902 Error session not opened\n"; static char OK_end[] = "3000 OK end\n"; static char OK_close[] = "3000 OK close Status = %d\n"; static char OK_open[] = "3000 OK open ticket = %d\n"; static char ERROR_append[] = "3903 Error append data\n"; /* Responses sent to the Director */ static char Job_start[] = "3010 Job %s start\n"; static char Job_end[] = "3099 Job %s end JobStatus=%d JobFiles=%d JobBytes=%s JobErrors=%u\n"; /* * After receiving a connection (in dircmd.c) if it is * from the File daemon, this routine is called. */ void *handle_filed_connection(BSOCK *fd, char *job_name) { JCR *jcr; /* * With the following bmicrosleep on, running the * SD under the debugger fails. */ // bmicrosleep(0, 50000); /* wait 50 millisecs */ if (!(jcr = get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name); Dmsg1(3, "**** Job \"%s\" not found.\n", job_name); fd->close(); return NULL; } Dmsg1(50, "Found Job %s\n", job_name); if (jcr->authenticated) { Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"), (uint32_t)jcr->JobId, jcr->Job); Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n", (uint32_t)jcr->JobId, jcr->Job); fd->close(); free_jcr(jcr); return NULL; } jcr->file_bsock = fd; jcr->file_bsock->set_jcr(jcr); /* * Authenticate the File daemon */ if (!authenticate_filedaemon(jcr)) { Dmsg1(50, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n")); jcr->setJobStatus(JS_ErrorTerminated); } else { utime_t now; jcr->authenticated = true; Dmsg2(50, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job); /* * Update the initial Job Statistics. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); } pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */ free_jcr(jcr); return NULL; } /* * Run a File daemon Job -- File daemon already authorized * Director sends us this command. * * Basic task here is: * - Read a command from the File daemon * - Execute it */ void run_job(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; char ec1[30]; dir->set_jcr(jcr); Dmsg1(120, "Start run Job=%s\n", jcr->Job); dir->fsend(Job_start, jcr->Job); jcr->start_time = time(NULL); jcr->run_time = jcr->start_time; jcr->sendJobStatus(JS_Running); do_fd_commands(jcr); jcr->end_time = time(NULL); dequeue_messages(jcr); /* send any queued messages */ jcr->setJobStatus(JS_Terminated); generate_plugin_event(jcr, bsdEventJobEnd); dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); dir->signal(BNET_EOD); /* send EOD to Director daemon */ free_plugins(jcr); /* release instantiated plugins */ } /* * Now talk to the FD and do what he says */ void do_fd_commands(JCR *jcr) { int i, status; bool found, quit; BSOCK *fd = jcr->file_bsock; fd->set_jcr(jcr); quit = false; while (!quit) { /* * Read command coming from the File daemon */ status = fd->recv(); if (is_bnet_stop(fd)) { /* hardeof or error */ break; /* connection terminated */ } if (status <= 0) { continue; /* ignore signals and zero length msgs */ } Dmsg1(110, "msg); found = false; for (i = 0; fd_cmds[i].cmd; i++) { if (bstrncmp(fd_cmds[i].cmd, fd->msg, strlen(fd_cmds[i].cmd))) { found = true; /* indicate command found */ jcr->errmsg[0] = 0; if (!fd_cmds[i].func(jcr)) { /* do command */ /* * Note fd->msg command may be destroyed by comm activity */ if (!job_canceled(jcr)) { if (jcr->errmsg[0]) { Jmsg1(jcr, M_FATAL, 0, _("Command error with FD, hanging up. %s\n"), jcr->errmsg); } else { Jmsg0(jcr, M_FATAL, 0, _("Command error with FD, hanging up.\n")); } jcr->setJobStatus(JS_ErrorTerminated); } quit = true; } break; } } if (!found) { /* command not found */ if (!job_canceled(jcr)) { Jmsg1(jcr, M_FATAL, 0, _("FD command not found: %s\n"), fd->msg); Dmsg1(110, "msg); } fd->fsend(ferrmsg); break; } } fd->signal(BNET_TERMINATE); /* signal to FD job is done */ } /* * Append Data command * Open Data Channel and receive Data for archiving * Write the Data to the archive device */ static bool append_data_cmd(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Append data: %s", fd->msg); if (jcr->session_opened) { Dmsg1(110, "msg); jcr->setJobType(JT_BACKUP); if (do_append_data(jcr, fd, "FD")) { return true; } else { pm_strcpy(jcr->errmsg, _("Append data error.\n")); bnet_suppress_error_messages(fd, 1); /* ignore errors at this point */ fd->fsend(ERROR_append); } } else { pm_strcpy(jcr->errmsg, _("Attempt to append on non-open session.\n")); fd->fsend(NOT_opened); } return false; } static bool append_end_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "storedmsg); if (!jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to close non-open session.\n")); fd->fsend(NOT_opened); return false; } return fd->fsend(OK_end); } /* * Append Open session command */ static bool append_open_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Append open session: %s", fd->msg); if (jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to open already open session.\n")); fd->fsend(NO_open); return false; } jcr->session_opened = true; /* Send "Ticket" to File Daemon */ fd->fsend(OK_open, jcr->VolSessionId); Dmsg1(110, ">filed: %s", fd->msg); return true; } /* * Append Close session command * Close the append session and send back Statistics * (need to fix statistics) */ static bool append_close_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "msg); if (!jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to close non-open session.\n")); fd->fsend(NOT_opened); return false; } /* * Send final statistics to File daemon */ fd->fsend(OK_close, jcr->JobStatus); Dmsg1(120, ">filed: %s", fd->msg); fd->signal(BNET_EOD); /* send EOD to File daemon */ jcr->session_opened = false; return true; } /* * Read Data command * Open Data Channel, read the data from * the archive device and send to File * daemon. */ static bool read_data_cmd(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Read data: %s", fd->msg); if (jcr->session_opened) { Dmsg1(120, "msg); return do_read_data(jcr); } else { pm_strcpy(jcr->errmsg, _("Attempt to read on non-open session.\n")); fd->fsend(NOT_opened); return false; } } /* * Read Open session command * We need to scan for the parameters of the job * to be restored. */ static bool read_open_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "%s\n", fd->msg); if (jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to open read on non-open session.\n")); fd->fsend(NO_open); return false; } if (sscanf(fd->msg, read_open, jcr->read_dcr->VolumeName, &jcr->read_VolSessionId, &jcr->read_VolSessionTime, &jcr->read_StartFile, &jcr->read_EndFile, &jcr->read_StartBlock, &jcr->read_EndBlock) == 7) { if (jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to open read on non-open session.\n")); fd->fsend(NOT_opened); return false; } Dmsg4(100, "read_open_session got: JobId=%d Vol=%s VolSessId=%ld VolSessT=%ld\n", jcr->JobId, jcr->read_dcr->VolumeName, jcr->read_VolSessionId, jcr->read_VolSessionTime); Dmsg4(100, " StartF=%ld EndF=%ld StartB=%ld EndB=%ld\n", jcr->read_StartFile, jcr->read_EndFile, jcr->read_StartBlock, jcr->read_EndBlock); } jcr->session_opened = true; jcr->setJobType(JT_RESTORE); /* * Send "Ticket" to File Daemon */ fd->fsend(OK_open, jcr->VolSessionId); Dmsg1(110, ">filed: %s", fd->msg); return true; } /* * Read Close session command * Close the read session */ static bool read_close_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Read close session: %s\n", fd->msg); if (!jcr->session_opened) { fd->fsend(NOT_opened); return false; } /* * Send final close msg to File daemon */ fd->fsend(OK_close, jcr->JobStatus); Dmsg1(160, ">filed: %s", fd->msg); fd->signal(BNET_EOD); /* send EOD to File daemon */ jcr->session_opened = false; return true; } bareos-Release-14.2.6/src/stored/job.c000066400000000000000000000435171263011562700174570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Job control and execution for Storage Daemon * * Kern Sibbald, MM */ #include "bareos.h" #include "stored.h" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Imported variables */ extern uint32_t VolSessionTime; /* Imported functions */ extern uint32_t newVolSessionId(); /* Requests from the Director daemon */ static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s " "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s " "SpoolData=%d PreferMountedVols=%d SpoolSize=%127s " "rerunning=%d VolSessionId=%d VolSessionTime=%d Quota=%llu " "Protocol=%d BackupFormat=%127s DumpLevel=%d\n"; /* Responses sent to Director daemon */ static char OK_job[] = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n"; static char OK_nextrun[] = "3000 OK Job Authorization=%s\n"; static char BAD_job[] = "3915 Bad Job command. stat=%d CMD: %s\n"; static char Job_end[] = "3099 Job %s end JobStatus=%d JobFiles=%d JobBytes=%s JobErrors=%u\n"; /* * Director requests us to start a job * Basic tasks done here: * - We pickup the JobId to be run from the Director. * - We pickup the device, media, and pool from the Director * - Wait for a connection from the File Daemon (FD) * - Accept commands from the FD (i.e. run the job) * - Return when the connection is terminated or * there is an error. */ bool job_cmd(JCR *jcr) { int32_t JobId; char auth_key[MAX_NAME_LENGTH]; char seed[MAX_NAME_LENGTH]; char spool_size[MAX_NAME_LENGTH]; BSOCK *dir = jcr->dir_bsock; POOL_MEM job_name, client_name, job, fileset_name, fileset_md5, backup_format; int32_t JobType, level, spool_attributes, no_attributes, spool_data; int32_t PreferMountedVols, rerunning, protocol, dumplevel; int status; uint64_t quota = 0; JCR *ojcr; /* * Get JobId and permissions from Director */ Dmsg1(100, "msg); bstrncpy(spool_size, "0", sizeof(spool_size)); status = sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(), client_name.c_str(), &JobType, &level, fileset_name.c_str(), &no_attributes, &spool_attributes, fileset_md5.c_str(), &spool_data, &PreferMountedVols, spool_size, &rerunning, &jcr->VolSessionId, &jcr->VolSessionTime, "a, &protocol, backup_format.c_str(), &dumplevel); if (status != 20) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(BAD_job, status, jcr->errmsg); Dmsg1(100, ">dird: %s", dir->msg); jcr->setJobStatus(JS_ErrorTerminated); return false; } jcr->rerunning = (rerunning) ? true : false; jcr->setJobProtocol(protocol); Dmsg4(100, "rerunning=%d VolSesId=%d VolSesTime=%d Protocol=%d\n", jcr->rerunning, jcr->VolSessionId, jcr->VolSessionTime, jcr->getJobProtocol()); /* * Since this job could be rescheduled, we * check to see if we have it already. If so * free the old jcr and use the new one. */ ojcr = get_jcr_by_full_name(job.c_str()); if (ojcr && !ojcr->authenticated) { Dmsg2(100, "Found ojcr=0x%x Job %s\n", (unsigned)(intptr_t)ojcr, job.c_str()); free_jcr(ojcr); } jcr->JobId = JobId; Dmsg2(800, "Start JobId=%d %p\n", JobId, jcr); /* * If job rescheduled because previous was incomplete, * the Resched flag is set and VolSessionId and VolSessionTime * are given to us (same as restarted job). */ if (!jcr->rerunning) { jcr->VolSessionId = newVolSessionId(); jcr->VolSessionTime = VolSessionTime; } bstrncpy(jcr->Job, job, sizeof(jcr->Job)); unbash_spaces(job_name); jcr->job_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->job_name, job_name); unbash_spaces(client_name); jcr->client_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->client_name, client_name); unbash_spaces(fileset_name); jcr->fileset_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->fileset_name, fileset_name); jcr->setJobType(JobType); jcr->setJobLevel(level); jcr->no_attributes = no_attributes; jcr->spool_attributes = spool_attributes; jcr->spool_data = spool_data; jcr->spool_size = str_to_int64(spool_size); jcr->fileset_md5 = get_pool_memory(PM_NAME); pm_strcpy(jcr->fileset_md5, fileset_md5); jcr->PreferMountedVols = PreferMountedVols; jcr->RemainingQuota = quota; unbash_spaces(backup_format); jcr->backup_format = get_pool_memory(PM_NAME); pm_strcpy(jcr->backup_format, backup_format); jcr->DumpLevel = dumplevel; jcr->authenticated = false; Dmsg1(50, "Quota set as %llu\n", quota); /* * Pass back an authorization key for the File daemon */ bsnprintf(seed, sizeof(seed), "%p%d", jcr, JobId); make_session_key(auth_key, seed, 1); dir->fsend(OK_job, jcr->VolSessionId, jcr->VolSessionTime, auth_key); Dmsg2(50, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg); jcr->sd_auth_key = bstrdup(auth_key); memset(auth_key, 0, sizeof(auth_key)); dispatch_new_plugin_options(jcr); generate_plugin_event(jcr, bsdEventJobStart, (void *)"JobStart"); return true; } bool do_job_run(JCR *jcr) { struct timeval tv; struct timezone tz; struct timespec timeout; int errstat = 0; jcr->sendJobStatus(JS_WaitFD); /* wait for FD to connect */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + me->client_wait; Dmsg3(50, "%s waiting %d sec for FD to contact SD key=%s\n", jcr->Job, (int)(timeout.tv_sec-time(NULL)), jcr->sd_auth_key); Dmsg2(800, "Wait FD for jid=%d %p\n", jcr->JobId, jcr); /* * Wait for the File daemon to contact us to start the Job, * when he does, we will be released, unless the 30 minutes * expires. */ P(mutex); while (!jcr->authenticated && !job_canceled(jcr)) { errstat = pthread_cond_timedwait(&jcr->job_start_wait, &mutex, &timeout); if (errstat == ETIMEDOUT || errstat == EINVAL || errstat == EPERM) { break; } Dmsg1(800, "=== Auth cond errstat=%d\n", errstat); } Dmsg3(50, "Auth=%d canceled=%d errstat=%d\n", jcr->authenticated, job_canceled(jcr), errstat); V(mutex); Dmsg2(800, "Auth fail or cancel for jid=%d %p\n", jcr->JobId, jcr); memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); switch (jcr->getJobProtocol()) { case PT_NDMP: if (jcr->authenticated && !job_canceled(jcr)) { Dmsg2(800, "Running jid=%d %p\n", jcr->JobId, jcr); /* * Wait for the Job to finish. As we want exclusive access to * things like the connection to the director we suspend this * thread and let the actual NDMP connection wake us after it * has performed the backup. E.g. instead of doing a busy wait * we just hang on a conditional variable. */ Dmsg2(800, "Wait for end job jid=%d %p\n", jcr->JobId, jcr); P(mutex); pthread_cond_wait(&jcr->job_end_wait, &mutex); V(mutex); } Dmsg2(800, "Done jid=%d %p\n", jcr->JobId, jcr); /* * For a NDMP backup we expect the protocol to send us either a nextrun cmd * or a finish cmd to let us know they are finished. */ return true; default: /* * Handle the file daemon session. */ if (jcr->authenticated && !job_canceled(jcr)) { Dmsg2(800, "Running jid=%d %p\n", jcr->JobId, jcr); run_job(jcr); /* Run the job */ } Dmsg2(800, "Done jid=%d %p\n", jcr->JobId, jcr); /* * After a run cmd of a native backup we are done e.g. * return false. */ return false; } } bool nextrun_cmd(JCR *jcr) { char auth_key[MAX_NAME_LENGTH]; char seed[MAX_NAME_LENGTH]; BSOCK *dir = jcr->dir_bsock; struct timeval tv; struct timezone tz; struct timespec timeout; int errstat = 0; switch (jcr->getJobProtocol()) { case PT_NDMP: /* * We expect a next NDMP backup stream so clear the authenticated flag * and start waiting for the Next backup to Start. */ jcr->authenticated = false; /* * Pass back a new authorization key for the File daemon */ bsnprintf(seed, sizeof(seed), "%p%d", jcr, jcr->JobId); make_session_key(auth_key, seed, 1); dir->fsend(OK_nextrun, auth_key); Dmsg2(50, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg); if (jcr->sd_auth_key) { free(jcr->sd_auth_key); } jcr->sd_auth_key = bstrdup(auth_key); memset(auth_key, 0, sizeof(auth_key)); jcr->sendJobStatus(JS_WaitFD); /* wait for FD to connect */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + me->client_wait; Dmsg3(50, "%s waiting %d sec for FD to contact SD key=%s\n", jcr->Job, (int)(timeout.tv_sec-time(NULL)), jcr->sd_auth_key); Dmsg2(800, "Wait FD for jid=%d %p\n", jcr->JobId, jcr); P(mutex); while (!jcr->authenticated && !job_canceled(jcr)) { errstat = pthread_cond_timedwait(&jcr->job_start_wait, &mutex, &timeout); if (errstat == ETIMEDOUT || errstat == EINVAL || errstat == EPERM) { break; } Dmsg1(800, "=== Auth cond errstat=%d\n", errstat); } Dmsg3(50, "Auth=%d canceled=%d errstat=%d\n", jcr->authenticated, job_canceled(jcr), errstat); V(mutex); Dmsg2(800, "Auth fail or cancel for jid=%d %p\n", jcr->JobId, jcr); if (jcr->authenticated && !job_canceled(jcr)) { Dmsg2(800, "Running jid=%d %p\n", jcr->JobId, jcr); /* * Wait for the Job to finish. As we want exclusive access to * things like the connection to the director we suspend this * thread and let the actual NDMP connection wake us after it * has performed the backup. E.g. instead of doing a busy wait * we just hang on a conditional variable. */ Dmsg2(800, "Wait for end job jid=%d %p\n", jcr->JobId, jcr); P(mutex); pthread_cond_wait(&jcr->job_end_wait, &mutex); V(mutex); } Dmsg2(800, "Done jid=%d %p\n", jcr->JobId, jcr); /* * For a NDMP backup we expect the protocol to send us either a nextrun cmd * or a finish cmd to let us know they are finished. */ return true; default: Dmsg1(200, "Nextrun_cmd: %s", jcr->dir_bsock->msg); Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s tries to use nextrun cmd while not part of protocol.\n"), (uint32_t)jcr->JobId, jcr->Job); return false; } } bool finish_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; char ec1[30]; /* * See if the Job has a certain protocol. Some protocols allow the * finish cmd some do not (Native backup for example does NOT) */ switch (jcr->getJobProtocol()) { case PT_NDMP: Dmsg1(200, "Finish_cmd: %s", jcr->dir_bsock->msg); jcr->end_time = time(NULL); dequeue_messages(jcr); /* send any queued messages */ jcr->setJobStatus(JS_Terminated); switch (jcr->getJobType()) { case JT_BACKUP: end_of_ndmp_backup(jcr); break; case JT_RESTORE: end_of_ndmp_restore(jcr); break; default: break; } generate_plugin_event(jcr, bsdEventJobEnd); dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); dir->signal(BNET_EOD); /* send EOD to Director daemon */ free_plugins(jcr); /* release instantiated plugins */ Dmsg2(800, "Done jid=%d %p\n", jcr->JobId, jcr); return false; /* Continue DIR session ? */ default: Dmsg1(200, "Finish_cmd: %s", jcr->dir_bsock->msg); Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n"), (uint32_t)jcr->JobId, jcr->Job); return false; /* Continue DIR session ? */ } } #ifdef needed /* * Query Device command from Director * Sends Storage Daemon's information on the device to the * caller (presumably the Director). * This command always returns "true" so that the line is * not closed on an error. * */ bool query_cmd(JCR *jcr) { POOL_MEM dev_name, VolumeName, MediaType, ChangerName; BSOCK *dir = jcr->dir_bsock; DEVRES *device; AUTOCHANGER *changer; bool ok; Dmsg1(100, "Query_cmd: %s", dir->msg); ok = sscanf(dir->msg, query_device, dev_name.c_str()) == 1; Dmsg1(100, "msg); if (ok) { unbash_spaces(dev_name); foreach_res(device, R_DEVICE) { /* Find resource, and make sure we were able to open it */ if (bstrcmp(dev_name.c_str(), device->hdr.name)) { if (!device->dev) { device->dev = init_dev(jcr, device); } if (!device->dev) { break; } ok = dir_update_device(jcr, device->dev); if (ok) { ok = dir->fsend(OK_query); } else { dir->fsend(NO_query); } return ok; } } foreach_res(changer, R_AUTOCHANGER) { /* Find resource, and make sure we were able to open it */ if (bstrcmp(dev_name.c_str(), changer->hdr.name)) { if (!changer->device || changer->device->size() == 0) { continue; /* no devices */ } ok = dir_update_changer(jcr, changer); if (ok) { ok = dir->fsend(OK_query); } else { dir->fsend(NO_query); } return ok; } } /* If we get here, the device/autochanger was not found */ unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(NO_device, dev_name.c_str()); Dmsg1(100, ">dird: %s", dir->msg); } else { unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(BAD_query, jcr->errmsg); Dmsg1(100, ">dird: %s", dir->msg); } return true; } #endif /* * Destroy the Job Control Record and associated * resources (sockets). */ void stored_free_jcr(JCR *jcr) { Dmsg0(200, "Start stored free_jcr\n"); Dmsg2(800, "End Job JobId=%u %p\n", jcr->JobId, jcr); if (jcr->dir_bsock) { Dmsg2(800, "Send terminate jid=%d %p\n", jcr->JobId, jcr); jcr->dir_bsock->signal(BNET_EOD); jcr->dir_bsock->signal(BNET_TERMINATE); } if (jcr->store_bsock) { jcr->store_bsock->close(); delete jcr->store_bsock; jcr->store_bsock = NULL; } if (jcr->file_bsock) { jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } if (jcr->job_name) { free_pool_memory(jcr->job_name); } if (jcr->client_name) { free_memory(jcr->client_name); jcr->client_name = NULL; } if (jcr->fileset_name) { free_memory(jcr->fileset_name); } if (jcr->fileset_md5) { free_memory(jcr->fileset_md5); } if (jcr->backup_format) { free_memory(jcr->backup_format); } if (jcr->bsr) { free_bsr(jcr->bsr); jcr->bsr = NULL; } if (jcr->rctx) { free_read_context(jcr->rctx); jcr->rctx = NULL; } if (jcr->compress.deflate_buffer || jcr->compress.inflate_buffer) { cleanup_compression(jcr); } /* * Free any restore volume list created */ free_restore_volume_list(jcr); if (jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); free_pool_memory(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; } if (jcr->next_dev || jcr->prev_dev) { Emsg0(M_FATAL, 0, _("In free_jcr(), but still attached to device!!!!\n")); } pthread_cond_destroy(&jcr->job_start_wait); pthread_cond_destroy(&jcr->job_end_wait); if (jcr->dcrs) { delete jcr->dcrs; jcr->dcrs = NULL; } /* * Avoid a double free */ if (jcr->dcr == jcr->read_dcr) { jcr->read_dcr = NULL; } if (jcr->dcr) { free_dcr(jcr->dcr); jcr->dcr = NULL; } if (jcr->read_dcr) { free_dcr(jcr->read_dcr); jcr->read_dcr = NULL; } if (jcr->plugin_options) { delete jcr->plugin_options; } if (jcr->read_store) { DIRSTORE *store; foreach_alist(store, jcr->read_store) { delete store->device; delete store; } delete jcr->read_store; jcr->read_store = NULL; } if (jcr->write_store) { DIRSTORE *store; foreach_alist(store, jcr->write_store) { delete store->device; delete store; } delete jcr->write_store; jcr->write_store = NULL; } free_plugins(jcr); /* release instantiated plugins */ Dsm_check(200); if (jcr->JobId != 0) { write_state_file(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); } Dmsg0(200, "End stored free_jcr\n"); return; } bareos-Release-14.2.6/src/stored/label.c000066400000000000000000001127561263011562700177660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * label.c Bareos routines to handle labels * * Kern Sibbald, MM */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ static void create_volume_label_record(DCR *dcr, DEVICE *dev, DEV_RECORD *rec); /* * Read the volume label * * If dcr->VolumeName == NULL, we accept any Bareos Volume * If dcr->VolumeName[0] == 0, we accept any Bareos Volume * otherwise dcr->VolumeName must match the Volume. * * If VolName given, ensure that it matches * * Returns VOL_ code as defined in record.h * VOL_NOT_READ * VOL_OK good label found * VOL_NO_LABEL volume not labeled * VOL_IO_ERROR I/O error reading tape * VOL_NAME_ERROR label has wrong name * VOL_CREATE_ERROR Error creating label * VOL_VERSION_ERROR label has wrong version * VOL_LABEL_ERROR bad label type * VOL_NO_MEDIA no media in drive * * The dcr block is emptied on return, and the Volume is rewound. */ int read_dev_volume_label(DCR *dcr) { JCR *jcr = dcr->jcr; DEVICE * volatile dev = dcr->dev; char *VolName = dcr->VolumeName; DEV_RECORD *record; bool ok = false; int status; bool want_ansi_label; bool have_ansi_label = false; /* * We always write the label in an 64512 byte / 63k block. * so we never have problems reading the volume label. */ dev->set_label_blocksize(dcr); Dmsg5(100, "Enter read_volume_label res=%d device=%s vol=%s dev_Vol=%s max_blocksize=%u\n", dev->num_reserved(), dev->print_name(), VolName, dev->VolHdr.VolumeName[0]?dev->VolHdr.VolumeName:"*NULL*", dev->max_block_size); if (!dev->is_open()) { if (!dev->open(dcr, OPEN_READ_ONLY)) { return VOL_IO_ERROR; } } dev->clear_labeled(); dev->clear_append(); dev->clear_read(); dev->label_type = B_BAREOS_LABEL; if (!dev->rewind(dcr)) { Mmsg(jcr->errmsg, _("Couldn't rewind device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); Dmsg1(130, "return VOL_NO_MEDIA: %s", jcr->errmsg); return VOL_NO_MEDIA; } bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id)); /* * The stored plugin handling the bsdEventLabelRead event can abort * the reading of the label by returning a non bRC_OK. */ if (generate_plugin_event(jcr, bsdEventLabelRead, dcr) != bRC_OK) { Dmsg0(200, "Error from bsdEventLabelRead plugin event.\n"); return VOL_NO_MEDIA; } /* * Read ANSI/IBM label if so requested */ want_ansi_label = dcr->VolCatInfo.LabelType != B_BAREOS_LABEL || dcr->device->label_type != B_BAREOS_LABEL; if (want_ansi_label || dev->has_cap(CAP_CHECKLABELS)) { status = read_ansi_ibm_label(dcr); /* * If we want a label and didn't find it, return error */ if (want_ansi_label && status != VOL_OK) { goto bail_out; } if (status == VOL_NAME_ERROR || status == VOL_LABEL_ERROR) { Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"), dev->print_name(), VolName, dev->VolHdr.VolumeName); if (!dev->poll && jcr->label_errors++ > 100) { Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg); } goto bail_out; } if (status != VOL_OK) { /* Not an ANSI/IBM label, so re-read */ dev->rewind(dcr); } else { have_ansi_label = true; } } /* * Read the Bareos Volume label block */ record = new_record(); empty_block(dcr->block); Dmsg0(130, "Big if statement in read_volume_label\n"); if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bareos " "labeled Volume, because: ERR=%s"), NPRT(VolName), dev->print_name(), dev->print_errmsg()); Dmsg1(130, "%s", jcr->errmsg); } else if (!read_record_from_block(dcr, record)) { Mmsg(jcr->errmsg, _("Could not read Volume label from block.\n")); Dmsg1(130, "%s", jcr->errmsg); } else if (!unser_volume_label(dev, record)) { Mmsg(jcr->errmsg, _("Could not unserialize Volume label: ERR=%s\n"), dev->print_errmsg()); Dmsg1(130, "%s", jcr->errmsg); } else if (!bstrcmp(dev->VolHdr.Id, BareosId) && !bstrcmp(dev->VolHdr.Id, OldBaculaId) && !bstrcmp(dev->VolHdr.Id, OlderBaculaId)) { Mmsg(jcr->errmsg, _("Volume Header Id bad: %s\n"), dev->VolHdr.Id); Dmsg1(130, "%s", jcr->errmsg); } else { ok = true; } free_record(record); /* finished reading Volume record */ if (!dev->is_volume_to_unload()) { dev->clear_unload(); } if (!ok) { if (forge_on || jcr->ignore_label_errors) { dev->set_labeled(); /* set has Bareos label */ Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg); goto ok_out; } Dmsg0(100, "No volume label - bailing out\n"); status = VOL_NO_LABEL; goto bail_out; } /* * At this point, we have read the first Bareos block, and * then read the Bareos Volume label. Now we need to * make sure we have the right Volume. */ if (dev->VolHdr.VerNum != BareosTapeVersion && dev->VolHdr.VerNum != OldCompatibleBareosTapeVersion1 && dev->VolHdr.VerNum != OldCompatibleBareosTapeVersion2 && dev->VolHdr.VerNum != OldCompatibleBareosTapeVersion3) { Mmsg(jcr->errmsg, _("Volume on %s has wrong Bareos version. Wanted %d got %d\n"), dev->print_name(), BareosTapeVersion, dev->VolHdr.VerNum); Dmsg1(130, "VOL_VERSION_ERROR: %s", jcr->errmsg); status = VOL_VERSION_ERROR; goto bail_out; } /* * We are looking for either an unused Bareos tape (PRE_LABEL) or * a Bareos volume label (VOL_LABEL) */ if (dev->VolHdr.LabelType != PRE_LABEL && dev->VolHdr.LabelType != VOL_LABEL) { Mmsg(jcr->errmsg, _("Volume on %s has bad Bareos label type: %x\n"), dev->print_name(), dev->VolHdr.LabelType); Dmsg1(130, "%s", jcr->errmsg); if (!dev->poll && jcr->label_errors++ > 100) { Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg); } Dmsg0(150, "return VOL_LABEL_ERROR\n"); status = VOL_LABEL_ERROR; goto bail_out; } dev->set_labeled(); /* set has Bareos label */ /* Compare Volume Names */ Dmsg2(130, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName); if (VolName && *VolName && *VolName != '*' && !bstrcmp(dev->VolHdr.VolumeName, VolName)) { Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"), dev->print_name(), VolName, dev->VolHdr.VolumeName); Dmsg1(130, "%s", jcr->errmsg); /* * Cancel Job if too many label errors * => we are in a loop */ if (!dev->poll && jcr->label_errors++ > 100) { Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg); } Dmsg0(150, "return VOL_NAME_ERROR\n"); status = VOL_NAME_ERROR; goto bail_out; } if (debug_level >= 200) { dump_volume_label(dev); } Dmsg0(130, "Leave read_volume_label() VOL_OK\n"); /* * If we are a streaming device, we only get one chance to read */ if (!dev->has_cap(CAP_STREAM)) { dev->rewind(dcr); if (have_ansi_label) { status = read_ansi_ibm_label(dcr); /* * If we want a label and didn't find it, return error */ if (status != VOL_OK) { goto bail_out; } } } Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName); if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) { Mmsg2(jcr->errmsg, _("Could not reserve volume %s on %s\n"), dev->VolHdr.VolumeName, dev->print_name()); Dmsg2(150, "Could not reserve volume %s on %s\n", dev->VolHdr.VolumeName, dev->print_name()); status = VOL_NAME_ERROR; goto bail_out; } ok_out: /* * The stored plugin handling the bsdEventLabelVerified event can override * the return value e.g. although we think the volume label is ok the plugin * has reasons to override that. So when the plugin returns something else * then bRC_OK it want to tell us the volume is not OK to use and as * such we return VOL_NAME_ERROR as error although it might not be the * best error it should be sufficient. */ if (generate_plugin_event(jcr, bsdEventLabelVerified, dcr) != bRC_OK) { Dmsg0(200, "Error from bsdEventLabelVerified plugin event.\n"); status = VOL_NAME_ERROR; goto bail_out; } empty_block(dcr->block); /* * Reset blocksizes from volinfo to device as we set blocksize to * DEFAULT_BLOCK_SIZE to read the label */ dev->set_blocksizes(dcr); return VOL_OK; bail_out: empty_block(dcr->block); dev->rewind(dcr); Dmsg1(150, "return %d\n", status); return status; } /* * Put a volume label into the block * * Returns: false on failure * true on success */ static bool write_volume_label_to_block(DCR *dcr) { DEVICE *dev = dcr->dev; DEV_BLOCK *block = dcr->block; DEV_RECORD rec; JCR *jcr = dcr->jcr; Dmsg0(130, "write Label in write_volume_label_to_block()\n"); memset(&rec, 0, sizeof(rec)); rec.data = get_memory(SER_LENGTH_Volume_Label); empty_block(block); /* Volume label always at beginning */ create_volume_label_record(dcr, dev, &rec); block->BlockNumber = 0; if (!write_record_to_block(dcr, &rec)) { free_pool_memory(rec.data); Jmsg1(jcr, M_FATAL, 0, _("Cannot write Volume label to block for device %s\n"), dev->print_name()); return false; } else { Dmsg2(130, "Wrote label of %d bytes to block. Vol=%s\n", rec.data_len, dcr->VolumeName); } free_pool_memory(rec.data); return true; } /* * Write a Volume Label * !!! Note, this is ONLY used for writing * a fresh volume label. Any data * after the label will be destroyed, * in fact, we write the label 5 times !!!! * * This routine should be used only when labeling a blank tape. */ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName, bool relabel) { DEV_RECORD *rec; JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; DEV_BLOCK *block = dcr->block; /* * Set the default blocksize to read the label */ dev->set_label_blocksize(dcr); Dmsg0(150, "write_volume_label()\n"); if (*VolName == 0) { Pmsg0(0, "=== ERROR: write_new_volume_label_to_dev called with NULL VolName\n"); goto bail_out; } if (relabel) { volume_unused(dcr); /* mark current volume unused */ /* Truncate device */ if (!dev->truncate(dcr)) { goto bail_out; } if (!dev->is_tape()) { dev->close(dcr); /* make sure file closed for rename */ } } /* Set the new filename for open, ... */ dev->setVolCatName(VolName); dcr->setVolCatName(VolName); Dmsg1(150, "New VolName=%s\n", VolName); if (!dev->open(dcr, OPEN_READ_WRITE)) { /* If device is not tape, attempt to create it */ if (dev->is_tape() || !dev->open(dcr, CREATE_READ_WRITE)) { Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"), dev->print_name(), dcr->VolumeName, dev->bstrerror()); goto bail_out; } } Dmsg1(150, "Label type=%d\n", dev->label_type); /* * Let any stored plugin know that we are about to write a new label to the volume. */ if (generate_plugin_event(jcr, bsdEventLabelWrite, dcr) != bRC_OK) { Dmsg0(200, "Error from bsdEventLabelWrite plugin event.\n"); goto bail_out; } empty_block(block); if (!dev->rewind(dcr)) { Dmsg2(130, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), dev->print_errmsg()); if (!forge_on) { goto bail_out; } } /* Temporarily mark in append state to enable writing */ dev->set_append(); /* Create PRE_LABEL */ create_volume_label(dev, VolName, PoolName); /* * If we have already detected an ANSI label, re-read it * to skip past it. Otherwise, we write a new one if * so requested. */ if (dev->label_type != B_BAREOS_LABEL) { if (read_ansi_ibm_label(dcr) != VOL_OK) { dev->rewind(dcr); goto bail_out; } } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) { goto bail_out; } rec = new_record(); create_volume_label_record(dcr, dev, rec); rec->Stream = 0; rec->maskedStream = 0; if (!write_record_to_block(dcr, rec)) { Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); free_record(rec); goto bail_out; } else { Dmsg2(130, "Wrote label of %d bytes to %s\n", rec->data_len, dev->print_name()); free_record(rec); } Dmsg0(130, "Call write_block_to_dev()\n"); if (!dcr->write_block_to_dev()) { Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg()); goto bail_out; } dev = dcr->dev; Dmsg0(130, " Wrote block to device\n"); if (dev->weof(1)) { dev->set_labeled(); write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName); } if (debug_level >= 20) { dump_volume_label(dev); } Dmsg0(100, "Call reserve_volume\n"); if (reserve_volume(dcr, VolName) == NULL) { Mmsg2(jcr->errmsg, _("Could not reserve volume %s on %s\n"), dev->VolHdr.VolumeName, dev->print_name()); Dmsg1(100, "%s", jcr->errmsg); goto bail_out; } dev = dcr->dev; /* may have changed in reserve_volume */ dev->clear_append(); /* remove append since this is PRE_LABEL */ /* * Reset blocksizes from volinfo to device as we set blocksize to DEFAULT_BLOCK_SIZE to read the label. */ dev->set_blocksizes(dcr); return true; bail_out: volume_unused(dcr); dev->clear_volhdr(); dev->clear_append(); /* remove append since this is PRE_LABEL */ return false; } /* * Write a volume label. This is ONLY called if we have a valid Bareos * label of type PRE_LABEL or we are recyling an existing Volume. * * Returns: true if OK * false if unable to write it */ bool DCR::rewrite_volume_label(bool recycle) { DCR *dcr = this; /* * Set the label blocksize to write the label */ dev->set_label_blocksize(dcr); if (!dev->open(dcr, OPEN_READ_WRITE)) { Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"), dev->print_name(), dcr->VolumeName, dev->bstrerror()); return false; } Dmsg2(190, "set append found freshly labeled volume. fd=%d dev=%x\n", dev->fd(), dev); /* * Let any stored plugin know that we are (re)writing the label. */ if (generate_plugin_event(jcr, bsdEventLabelWrite, dcr) != bRC_OK) { Dmsg0(200, "Error from bsdEventLabelWrite plugin event.\n"); return false; } dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */ dev->set_append(); if (!write_volume_label_to_block(dcr)) { Dmsg0(200, "Error from write volume label.\n"); return false; } Dmsg1(150, "wrote vol label to block. Vol=%s\n", dcr->VolumeName); dev->setVolCatInfo(false); dev->VolCatInfo.VolCatBytes = 0; /* reset byte count */ /* * If we are not dealing with a streaming device, * write the block now to ensure we have write permission. * It is better to find out now rather than later. * We do not write the block now if this is an ANSI label. This * avoids re-writing the ANSI label, which we do not want to do. */ if (!dev->has_cap(CAP_STREAM)) { if (!dev->rewind(dcr)) { Jmsg2(jcr, M_FATAL, 0, _("Rewind error on device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); return false; } if (recycle) { Dmsg1(150, "Doing recycle. Vol=%s\n", dcr->VolumeName); if (!dev->truncate(dcr)) { Jmsg2(jcr, M_FATAL, 0, _("Truncate error on device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); return false; } if (!dev->open(dcr, OPEN_READ_WRITE)) { Jmsg2(jcr, M_FATAL, 0, _("Failed to re-open after truncate on device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); return false; } } /* * If we have already detected an ANSI label, re-read it * to skip past it. Otherwise, we write a new one if * so requested. */ if (dev->label_type != B_BAREOS_LABEL) { if (read_ansi_ibm_label(dcr) != VOL_OK) { dev->rewind(dcr); return false; } } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, dev->VolHdr.VolumeName)) { return false; } /* Attempt write to check write permission */ Dmsg1(200, "Attempt to write to device fd=%d.\n", dev->fd()); if (!dcr->write_block_to_dev()) { Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s: ERR=%s\n"), dev->print_name(), dev->print_errmsg()); Dmsg0(200, "===ERROR write block to dev\n"); return false; } } dev->set_labeled(); /* Set or reset Volume statistics */ dev->VolCatInfo.VolCatJobs = 0; dev->VolCatInfo.VolCatFiles = 0; dev->VolCatInfo.VolCatErrors = 0; dev->VolCatInfo.VolCatBlocks = 0; dev->VolCatInfo.VolCatRBytes = 0; if (recycle) { dev->VolCatInfo.VolCatMounts++; dev->VolCatInfo.VolCatRecycles++; dcr->dir_create_jobmedia_record(true); } else { dev->VolCatInfo.VolCatMounts = 1; dev->VolCatInfo.VolCatRecycles = 0; dev->VolCatInfo.VolCatWrites = 1; dev->VolCatInfo.VolCatReads = 1; } Dmsg1(150, "dir_update_vol_info. Set Append vol=%s\n", dcr->VolumeName); dev->VolCatInfo.VolFirstWritten = time(NULL); bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus)); dev->setVolCatName(dcr->VolumeName); if (!dcr->dir_update_volume_info(true, true)) { /* indicate doing relabel */ return false; } if (recycle) { Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\" on device %s, all previous data lost.\n"), dcr->VolumeName, dev->print_name()); } else { Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume \"%s\" on device %s\n"), dcr->VolumeName, dev->print_name()); } /* * End writing real Volume label (from pre-labeled tape), or recycling * the volume. */ Dmsg1(150, "OK from rewrite vol label. Vol=%s\n", dcr->VolumeName); /* * reset blocksizes from volinfo to device as we set blocksize to * DEFAULT_BLOCK_SIZE to write the label */ dev->set_blocksizes(dcr); /* * Let any stored plugin know the label was rewritten and as such is verified . */ if (generate_plugin_event(jcr, bsdEventLabelVerified, dcr) != bRC_OK) { Dmsg0(200, "Error from bsdEventLabelVerified plugin event.\n"); return false; } return true; } /* * create_volume_label_record * Serialize label (from dev->VolHdr structure) into device record. * Assumes that the dev->VolHdr structure is properly * initialized. */ static void create_volume_label_record(DCR *dcr, DEVICE *dev, DEV_RECORD *rec) { ser_declare; struct date_time dt; JCR *jcr = dcr->jcr; char buf[100]; /* Serialize the label into the device record. */ rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Volume_Label); ser_begin(rec->data, SER_LENGTH_Volume_Label); ser_string(dev->VolHdr.Id); ser_uint32(dev->VolHdr.VerNum); if (dev->VolHdr.VerNum >= 11) { ser_btime(dev->VolHdr.label_btime); dev->VolHdr.write_btime = get_current_btime(); ser_btime(dev->VolHdr.write_btime); dev->VolHdr.write_date = 0; dev->VolHdr.write_time = 0; } else { /* OLD WAY DEPRECATED */ ser_float64(dev->VolHdr.label_date); ser_float64(dev->VolHdr.label_time); get_current_time(&dt); dev->VolHdr.write_date = dt.julian_day_number; dev->VolHdr.write_time = dt.julian_day_fraction; } ser_float64(dev->VolHdr.write_date); /* 0 if VerNum >= 11 */ ser_float64(dev->VolHdr.write_time); /* 0 if VerNum >= 11 */ ser_string(dev->VolHdr.VolumeName); ser_string(dev->VolHdr.PrevVolumeName); ser_string(dev->VolHdr.PoolName); ser_string(dev->VolHdr.PoolType); ser_string(dev->VolHdr.MediaType); ser_string(dev->VolHdr.HostName); ser_string(dev->VolHdr.LabelProg); ser_string(dev->VolHdr.ProgVersion); ser_string(dev->VolHdr.ProgDate); ser_end(rec->data, SER_LENGTH_Volume_Label); bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName)); rec->data_len = ser_length(rec->data); rec->FileIndex = dev->VolHdr.LabelType; rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; rec->Stream = jcr->NumWriteVolumes; rec->maskedStream = jcr->NumWriteVolumes; Dmsg2(150, "Created Vol label rec: FI=%s len=%d\n", FI_to_ascii(buf, rec->FileIndex), rec->data_len); } /* * Create a volume label in memory */ void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName) { DEVRES *device = (DEVRES *)dev->device; Dmsg0(130, "Start create_volume_label()\n"); ASSERT(dev != NULL); dev->clear_volhdr(); /* clear any old volume info */ if (me->compatible) { bstrncpy(dev->VolHdr.Id, OldBaculaId, sizeof(dev->VolHdr.Id)); dev->VolHdr.VerNum = OldCompatibleBareosTapeVersion1; } else { bstrncpy(dev->VolHdr.Id, BareosId, sizeof(dev->VolHdr.Id)); dev->VolHdr.VerNum = BareosTapeVersion; } dev->VolHdr.LabelType = PRE_LABEL; /* Mark tape as unused */ bstrncpy(dev->VolHdr.VolumeName, VolName, sizeof(dev->VolHdr.VolumeName)); bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName)); bstrncpy(dev->VolHdr.MediaType, device->media_type, sizeof(dev->VolHdr.MediaType)); bstrncpy(dev->VolHdr.PoolType, "Backup", sizeof(dev->VolHdr.PoolType)); dev->VolHdr.label_btime = get_current_btime(); dev->VolHdr.label_date = 0; dev->VolHdr.label_time = 0; if (gethostname(dev->VolHdr.HostName, sizeof(dev->VolHdr.HostName)) != 0) { dev->VolHdr.HostName[0] = 0; } bstrncpy(dev->VolHdr.LabelProg, my_name, sizeof(dev->VolHdr.LabelProg)); sprintf(dev->VolHdr.ProgVersion, "Ver. %s %s", VERSION, BDATE); sprintf(dev->VolHdr.ProgDate, "Build %s %s", __DATE__, __TIME__); dev->set_labeled(); /* set has Bareos label */ if (debug_level >= 90) { dump_volume_label(dev); } } /* * Create session label * The pool memory must be released by the calling program */ void create_session_label(DCR *dcr, DEV_RECORD *rec, int label) { JCR *jcr = dcr->jcr; ser_declare; rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; rec->Stream = jcr->JobId; rec->maskedStream = jcr->JobId; rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Session_Label); ser_begin(rec->data, SER_LENGTH_Session_Label); if (me->compatible) { ser_string(OldBaculaId); ser_uint32(OldCompatibleBareosTapeVersion1); } else { ser_string(BareosId); ser_uint32(BareosTapeVersion); } ser_uint32(jcr->JobId); /* Changed in VerNum 11 */ ser_btime(get_current_btime()); ser_float64(0); ser_string(dcr->pool_name); ser_string(dcr->pool_type); ser_string(jcr->job_name); /* base Job name */ ser_string(jcr->client_name); /* Added in VerNum 10 */ ser_string(jcr->Job); /* Unique name of this Job */ ser_string(jcr->fileset_name); ser_uint32(jcr->getJobType()); ser_uint32(jcr->getJobLevel()); /* Added in VerNum 11 */ ser_string(jcr->fileset_md5); if (label == EOS_LABEL) { ser_uint32(jcr->JobFiles); ser_uint64(jcr->JobBytes); ser_uint32(dcr->StartBlock); ser_uint32(dcr->EndBlock); ser_uint32(dcr->StartFile); ser_uint32(dcr->EndFile); ser_uint32(jcr->JobErrors); /* Added in VerNum 11 */ ser_uint32(jcr->JobStatus); } ser_end(rec->data, SER_LENGTH_Session_Label); rec->data_len = ser_length(rec->data); } /* Write session label * Returns: false on failure * true on success */ bool write_session_label(DCR *dcr, int label) { JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; DEV_RECORD *rec; DEV_BLOCK *block = dcr->block; char buf1[100], buf2[100]; rec = new_record(); Dmsg1(130, "session_label record=%x\n", rec); switch (label) { case SOS_LABEL: set_start_vol_position(dcr); break; case EOS_LABEL: if (dev->is_tape()) { dcr->EndBlock = dev->EndBlock; dcr->EndFile = dev->EndFile; } else { dcr->EndBlock = (uint32_t)dev->file_addr; dcr->EndFile = (uint32_t)(dev->file_addr >> 32); } break; default: Jmsg1(jcr, M_ABORT, 0, _("Bad Volume session label = %d\n"), label); break; } create_session_label(dcr, rec, label); rec->FileIndex = label; /* * We guarantee that the session record can totally fit * into a block. If not, write the block, and put it in * the next block. Having the sesssion record totally in * one block makes reading them much easier (no need to * read the next block). */ if (!can_write_record_to_block(block, rec)) { Dmsg0(150, "Cannot write session label to block.\n"); if (!dcr->write_block_to_device()) { Dmsg0(130, "Got session label write_block_to_dev error.\n"); free_record(rec); return false; } } if (!write_record_to_block(dcr, rec)) { free_record(rec); return false; } Dmsg6(150, "Write sesson_label record JobId=%d FI=%s SessId=%d Strm=%s len=%d " "remainder=%d\n", jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len, rec->remainder); free_record(rec); Dmsg2(150, "Leave write_session_label Block=%ud File=%ud\n", dev->get_block_num(), dev->get_file()); return true; } /* unser_volume_label * * Unserialize the Bareos Volume label into the device Volume_Label * structure. * * Assumes that the record is already read. * * Returns: false on error * true on success */ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec) { ser_declare; char buf1[100], buf2[100]; if (rec->FileIndex != VOL_LABEL && rec->FileIndex != PRE_LABEL) { Mmsg3(dev->errmsg, _("Expecting Volume Label, got FI=%s Stream=%s len=%d\n"), FI_to_ascii(buf1, rec->FileIndex), stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); if (!forge_on) { return false; } } dev->VolHdr.LabelType = rec->FileIndex; dev->VolHdr.LabelSize = rec->data_len; /* Unserialize the record into the Volume Header */ rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Volume_Label); ser_begin(rec->data, SER_LENGTH_Volume_Label); unser_string(dev->VolHdr.Id); unser_uint32(dev->VolHdr.VerNum); if (dev->VolHdr.VerNum >= 11) { unser_btime(dev->VolHdr.label_btime); unser_btime(dev->VolHdr.write_btime); } else { /* old way */ unser_float64(dev->VolHdr.label_date); unser_float64(dev->VolHdr.label_time); } unser_float64(dev->VolHdr.write_date); /* Unused with VerNum >= 11 */ unser_float64(dev->VolHdr.write_time); /* Unused with VerNum >= 11 */ unser_string(dev->VolHdr.VolumeName); unser_string(dev->VolHdr.PrevVolumeName); unser_string(dev->VolHdr.PoolName); unser_string(dev->VolHdr.PoolType); unser_string(dev->VolHdr.MediaType); unser_string(dev->VolHdr.HostName); unser_string(dev->VolHdr.LabelProg); unser_string(dev->VolHdr.ProgVersion); unser_string(dev->VolHdr.ProgDate); ser_end(rec->data, SER_LENGTH_Volume_Label); Dmsg0(190, "unser_vol_label\n"); if (debug_level >= 190) { dump_volume_label(dev); } return true; } bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec) { ser_declare; rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Session_Label); unser_begin(rec->data, SER_LENGTH_Session_Label); unser_string(label->Id); unser_uint32(label->VerNum); unser_uint32(label->JobId); if (label->VerNum >= 11) { unser_btime(label->write_btime); } else { unser_float64(label->write_date); } unser_float64(label->write_time); unser_string(label->PoolName); unser_string(label->PoolType); unser_string(label->JobName); unser_string(label->ClientName); if (label->VerNum >= 10) { unser_string(label->Job); /* Unique name of this Job */ unser_string(label->FileSetName); unser_uint32(label->JobType); unser_uint32(label->JobLevel); } if (label->VerNum >= 11) { unser_string(label->FileSetMD5); } else { label->FileSetMD5[0] = 0; } if (rec->FileIndex == EOS_LABEL) { unser_uint32(label->JobFiles); unser_uint64(label->JobBytes); unser_uint32(label->StartBlock); unser_uint32(label->EndBlock); unser_uint32(label->StartFile); unser_uint32(label->EndFile); unser_uint32(label->JobErrors); if (label->VerNum >= 11) { unser_uint32(label->JobStatus); } else { label->JobStatus = JS_Terminated; /* kludge */ } } return true; } void dump_volume_label(DEVICE *dev) { int dbl = debug_level; uint32_t File; const char *LabelType; char buf[30]; struct tm tm; struct date_time dt; debug_level = 1; File = dev->file; switch (dev->VolHdr.LabelType) { case PRE_LABEL: LabelType = "PRE_LABEL"; break; case VOL_LABEL: LabelType = "VOL_LABEL"; break; case EOM_LABEL: LabelType = "EOM_LABEL"; break; case SOS_LABEL: LabelType = "SOS_LABEL"; break; case EOS_LABEL: LabelType = "EOS_LABEL"; break; case EOT_LABEL: goto bail_out; default: LabelType = buf; sprintf(buf, _("Unknown %d"), dev->VolHdr.LabelType); break; } Pmsg11(-1, _("\nVolume Label:\n" "Id : %s" "VerNo : %d\n" "VolName : %s\n" "PrevVolName : %s\n" "VolFile : %d\n" "LabelType : %s\n" "LabelSize : %d\n" "PoolName : %s\n" "MediaType : %s\n" "PoolType : %s\n" "HostName : %s\n" ""), dev->VolHdr.Id, dev->VolHdr.VerNum, dev->VolHdr.VolumeName, dev->VolHdr.PrevVolumeName, File, LabelType, dev->VolHdr.LabelSize, dev->VolHdr.PoolName, dev->VolHdr.MediaType, dev->VolHdr.PoolType, dev->VolHdr.HostName); if (dev->VolHdr.VerNum >= 11) { char dt[50]; bstrftime(dt, sizeof(dt), btime_to_utime(dev->VolHdr.label_btime)); Pmsg1(-1, _("Date label written: %s\n"), dt); } else { dt.julian_day_number = dev->VolHdr.label_date; dt.julian_day_fraction = dev->VolHdr.label_time; tm_decode(&dt, &tm); Pmsg5(-1, _("Date label written: %04d-%02d-%02d at %02d:%02d\n"), tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min); } bail_out: debug_level = dbl; } static void dump_session_label(DEV_RECORD *rec, const char *type) { int dbl; struct date_time dt; struct tm tm; SESSION_LABEL label; char ec1[30], ec2[30], ec3[30], ec4[30], ec5[30], ec6[30], ec7[30]; unser_session_label(&label, rec); dbl = debug_level; debug_level = 1; Pmsg7(-1, _("\n%s Record:\n" "JobId : %d\n" "VerNum : %d\n" "PoolName : %s\n" "PoolType : %s\n" "JobName : %s\n" "ClientName : %s\n" ""), type, label.JobId, label.VerNum, label.PoolName, label.PoolType, label.JobName, label.ClientName); if (label.VerNum >= 10) { Pmsg4(-1, _( "Job (unique name) : %s\n" "FileSet : %s\n" "JobType : %c\n" "JobLevel : %c\n" ""), label.Job, label.FileSetName, label.JobType, label.JobLevel); } if (rec->FileIndex == EOS_LABEL) { Pmsg8(-1, _( "JobFiles : %s\n" "JobBytes : %s\n" "StartBlock : %s\n" "EndBlock : %s\n" "StartFile : %s\n" "EndFile : %s\n" "JobErrors : %s\n" "JobStatus : %c\n" ""), edit_uint64_with_commas(label.JobFiles, ec1), edit_uint64_with_commas(label.JobBytes, ec2), edit_uint64_with_commas(label.StartBlock, ec3), edit_uint64_with_commas(label.EndBlock, ec4), edit_uint64_with_commas(label.StartFile, ec5), edit_uint64_with_commas(label.EndFile, ec6), edit_uint64_with_commas(label.JobErrors, ec7), label.JobStatus); } if (label.VerNum >= 11) { char dt[50]; bstrftime(dt, sizeof(dt), btime_to_utime(label.write_btime)); Pmsg1(-1, _("Date written : %s\n"), dt); } else { dt.julian_day_number = label.write_date; dt.julian_day_fraction = label.write_time; tm_decode(&dt, &tm); Pmsg5(-1, _("Date written : %04d-%02d-%02d at %02d:%02d\n"), tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min); } debug_level = dbl; } void dump_label_record(DEVICE *dev, DEV_RECORD *rec, bool verbose) { const char *type; int dbl; if (rec->FileIndex == 0 && rec->VolSessionId == 0 && rec->VolSessionTime == 0) { return; } dbl = debug_level; debug_level = 1; switch (rec->FileIndex) { case PRE_LABEL: type = _("Fresh Volume"); break; case VOL_LABEL: type = _("Volume"); break; case SOS_LABEL: type = _("Begin Job Session"); break; case EOS_LABEL: type = _("End Job Session"); break; case EOM_LABEL: type = _("End of Media"); break; case EOT_LABEL: type = _("End of Tape"); break; default: type = _("Unknown"); break; } if (verbose) { switch (rec->FileIndex) { case PRE_LABEL: case VOL_LABEL: unser_volume_label(dev, rec); dump_volume_label(dev); break; case SOS_LABEL: dump_session_label(rec, type); break; case EOS_LABEL: dump_session_label(rec, type); break; case EOM_LABEL: Pmsg7(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n"), type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); break; case EOT_LABEL: Pmsg0(-1, _("End of physical tape.\n")); break; default: Pmsg7(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n"), type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); break; } } else { SESSION_LABEL label; char dt[50]; switch (rec->FileIndex) { case SOS_LABEL: unser_session_label(&label, rec); bstrftimes(dt, sizeof(dt), btime_to_utime(label.write_btime)); Pmsg6(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n"), type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, label.JobId); Pmsg4(-1, _(" Job=%s Date=%s Level=%c Type=%c\n"), label.Job, dt, label.JobLevel, label.JobType); break; case EOS_LABEL: char ed1[30], ed2[30]; unser_session_label(&label, rec); bstrftimes(dt, sizeof(dt), btime_to_utime(label.write_btime)); Pmsg6(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n"), type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, label.JobId); Pmsg7(-1, _(" Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n"), dt, label.JobLevel, label.JobType, edit_uint64_with_commas(label.JobFiles, ed1), edit_uint64_with_commas(label.JobBytes, ed2), label.JobErrors, (char)label.JobStatus); break; case EOM_LABEL: case PRE_LABEL: case VOL_LABEL: default: Pmsg7(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n"), type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); break; case EOT_LABEL: break; } } debug_level = dbl; } bareos-Release-14.2.6/src/stored/lock.c000066400000000000000000000340401263011562700176240ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Collection of Bacula Storage daemon locking software * * Kern Sibbald, June 2007 */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ #ifdef SD_DEBUG_LOCK const int dbglvl = 0; #else const int dbglvl = 500; #endif /* * * The Storage daemon has three locking concepts that must be * understood: * * 1. dblock blocking the device, which means that the device * is "marked" in use. When setting and removing the * block, the device is locked, but after dblock is * called the device is unlocked. * 2. Lock() simple mutex that locks the device structure. A Lock * can be acquired while a device is blocked if it is not * locked. * 3. rLock(locked) "recursive" Lock, when means that a Lock (mutex) * will be acquired on the device if it is not blocked * by some other thread. If the device was blocked by * the current thread, it will acquire the lock. * If some other thread has set a block on the device, * this call will wait until the device is unblocked. * Can be called with locked true, which means the * Lock is already set * * A lock is normally set when modifying the device structure. * A rLock is normally acquired when you want to block the device * i.e. it will wait until the device is not blocked. * A block is normally set during long operations like writing to * the device. * If you are writing the device, you will normally block and * lock it. * A lock cannot be violated. No other thread can touch the * device while a lock is set. * When a block is set, every thread accept the thread that set * the block will block if rLock is called. * A device can be blocked for multiple reasons, labeling, writing, * acquiring (opening) the device, waiting for the operator, unmounted, * ... * Under certain conditions the block that is set on a device can be * stolen and the device can be used by another thread. For example, * a device is blocked because it is waiting for the operator to * mount a tape. The operator can then unmount the device, and label * a tape, re-mount it, give back the block, and the job will continue. * * * Functions: * * DEVICE::Lock() does P(m_mutex) (in dev.h) * DEVICE::Unlock() does V(m_mutex) * * DEVICE::rLock(locked) allows locking the device when this thread * already has the device blocked. * if (!locked) * Lock() * if blocked and not same thread that locked * pthread_cond_wait * leaves device locked * * DEVICE::rUnlock() unlocks but does not unblock * same as Unlock(); * * DEVICE::dblock(why) does * rLock(); (recursive device lock) * block_device(this, why) * rUnlock() * * DEVICE::dunblock does * Lock() * unblock_device() * Unlock() * * block_device() does (must be locked and not blocked at entry) * set blocked status * set our pid * * unblock_device() does (must be blocked at entry) * (locked on entry) * (locked on exit) * set unblocked status * clear pid * if waiting threads * pthread_cond_broadcast * * steal_device_lock() does (must be locked and blocked at entry) * save status * set new blocked status * set new pid * Unlock() * * give_back_device_lock() does (must be blocked but not locked) * Lock() * reset blocked status * save previous blocked * reset pid * if waiting threads * pthread_cond_broadcast * */ void DEVICE::dblock(int why) { rLock(false); /* need recursive lock to block */ block_device(this, why); rUnlock(); } void DEVICE::dunblock(bool locked) { if (!locked) { Lock(); } unblock_device(this); Unlock(); } #ifdef SD_DEBUG_LOCK /* * Debug DCR locks N.B. * */ void DCR::dbg_mLock(const char *file, int line, bool locked) { real_P(r_mutex); if (is_dev_locked()) { real_V(r_mutex); return; } Dmsg3(sd_dbglvl, "mLock %d from %s:%d\n", locked, file, line); dev->dbg_rLock(file,line,locked); inc_dev_lock(); real_V(r_mutex); return; } void DCR::dbg_mUnlock(const char *file, int line) { Dmsg2(sd_dbglvl, "mUnlock from %s:%d\n", file, line); real_P(r_mutex); if (!is_dev_locked()) { real_P(r_mutex); ASSERT2(0, "Call on dcr mUnlock when not locked"); return; } dec_dev_lock(); /* When the count goes to zero, unlock it */ if (!is_dev_locked()) { dev->dbg_rUnlock(file,line); } real_V(r_mutex); return; } /* * Debug DEVICE locks N.B. * */ void DEVICE::dbg_Lock(const char *file, int line) { Dmsg3(sd_dbglvl, "Lock from %s:%d precnt=%d\n", file, line, m_count); /* Note, this *really* should be protected by a mutex, but * since it is only debug code we don't worry too much. */ if (m_count > 0 && pthread_equal(m_pid, pthread_self())) { Dmsg4(sd_dbglvl, "Possible DEADLOCK!! lock held by JobId=%u from %s:%d m_count=%d\n", get_jobid_from_tid(m_pid), file, line, m_count); } bthread_mutex_lock_p(&m_mutex, file, line); m_pid = pthread_self(); m_count++; } void DEVICE::dbg_Unlock(const char *file, int line) { m_count--; Dmsg3(sd_dbglvl, "Unlock from %s:%d postcnt=%d\n", file, line, m_count); bthread_mutex_unlock_p(&m_mutex, file, line); } void DEVICE::dbg_rUnlock(const char *file, int line) { Dmsg2(sd_dbglvl, "rUnlock from %s:%d\n", file, line); dbg_Unlock(file, line); } void DEVICE::dbg_Lock_acquire(const char *file, int line) { Dmsg2(sd_dbglvl, "Lock_acquire from %s:%d\n", file, line); bthread_mutex_lock_p(&acquire_mutex, file, line); } void DEVICE::dbg_Unlock_acquire(const char *file, int line) { Dmsg2(sd_dbglvl, "Unlock_acquire from %s:%d\n", file, line); bthread_mutex_unlock_p(&acquire_mutex, file, line); } void DEVICE::dbg_Lock_read_acquire(const char *file, int line) { Dmsg2(sd_dbglvl, "Lock_read_acquire from %s:%d\n", file, line); bthread_mutex_lock_p(&read_acquire_mutex, file, line); } void DEVICE::dbg_Unlock_read_acquire(const char *file, int line) { Dmsg2(sd_dbglvl, "Unlock_read_acquire from %s:%d\n", file, line); bthread_mutex_unlock_p(&read_acquire_mutex, file, line); } #else /* * DCR locks N.B. * */ /* Multiple rLock implementation */ void DCR::mLock(bool locked) { P(r_mutex); if (is_dev_locked()) { V(r_mutex); return; } dev->rLock(locked); inc_dev_lock(); V(r_mutex); return; } /* Multiple rUnlock implementation */ void DCR::mUnlock() { P(r_mutex); if (!is_dev_locked()) { V(r_mutex); ASSERT2(0, "Call on dcr mUnlock when not locked"); return; } dec_dev_lock(); /* When the count goes to zero, unlock it */ if (!is_dev_locked()) { dev->rUnlock(); } V(r_mutex); return; } /* * DEVICE locks N.B. */ void DEVICE::rUnlock() { Unlock(); } void DEVICE::Lock() { P(m_mutex); } void DEVICE::Unlock() { V(m_mutex); } void DEVICE::Lock_acquire() { P(acquire_mutex); } void DEVICE::Unlock_acquire() { V(acquire_mutex); } void DEVICE::Lock_read_acquire() { P(read_acquire_mutex); } void DEVICE::Unlock_read_acquire() { V(read_acquire_mutex); } #endif /* Main device access control */ int DEVICE::init_mutex() { return pthread_mutex_init(&m_mutex, NULL); } /* Write device acquire mutex */ int DEVICE::init_acquire_mutex() { return pthread_mutex_init(&acquire_mutex, NULL); } /* Read device acquire mutex */ int DEVICE::init_read_acquire_mutex() { return pthread_mutex_init(&read_acquire_mutex, NULL); } /* Set order in which device locks must be acquired */ void DEVICE::set_mutex_priorities() { /* Ensure that we respect this order in P/V operations */ bthread_mutex_set_priority(&m_mutex, PRIO_SD_DEV_ACCESS); bthread_mutex_set_priority(&spool_mutex, PRIO_SD_DEV_SPOOL); bthread_mutex_set_priority(&acquire_mutex, PRIO_SD_DEV_ACQUIRE); } int DEVICE::next_vol_timedwait(const struct timespec *timeout) { return pthread_cond_timedwait(&wait_next_vol, &m_mutex, timeout); } /* * This is a recursive lock that checks if the device is blocked. * * When blocked is set, all threads EXCEPT thread with id no_wait_id * must wait. The no_wait_id thread is out obtaining a new volume * and preparing the label. */ #ifdef SD_DEBUG_LOCK void DEVICE::dbg_rLock(const char *file, int line, bool locked) { Dmsg3(sd_dbglvl, "rLock blked=%s from %s:%d\n", print_blocked(), file, line); if (!locked) { /* lockmgr version of P(m_mutex) */ bthread_mutex_lock_p(&m_mutex, file, line); m_count++; } #else void DEVICE::rLock(bool locked) { if (!locked) { Lock(); m_count++; } #endif if (blocked() && !pthread_equal(no_wait_id, pthread_self())) { num_waiting++; /* indicate that I am waiting */ while (blocked()) { int status; #ifndef HAVE_WIN32 /* thread id on Win32 may be a struct */ Dmsg3(sd_dbglvl, "rLock blked=%s no_wait=%p me=%p\n", print_blocked(), no_wait_id, pthread_self()); #endif if ((status = pthread_cond_wait(&this->wait, &m_mutex)) != 0) { berrno be; this->Unlock(); Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"), be.bstrerror(status)); } } num_waiting--; /* no longer waiting */ } } /* * Block all other threads from using the device * Device must already be locked. After this call, * the device is blocked to any thread calling dev->rLock(), * but the device is not locked (i.e. no P on device). Also, * the current thread can do slip through the dev->rLock() * calls without blocking. */ void _block_device(const char *file, int line, DEVICE *dev, int state) { // ASSERT(lmgr_mutex_is_locked(&dev->m_mutex) == 1); ASSERT(dev->blocked() == BST_NOT_BLOCKED); dev->set_blocked(state); /* make other threads wait */ dev->no_wait_id = pthread_self(); /* allow us to continue */ Dmsg3(sd_dbglvl, "set blocked=%s from %s:%d\n", dev->print_blocked(), file, line); } /* * Unblock the device, and wake up anyone who went to sleep. * Enter: device locked * Exit: device locked */ void _unblock_device(const char *file, int line, DEVICE *dev) { Dmsg3(sd_dbglvl, "unblock %s from %s:%d\n", dev->print_blocked(), file, line); // ASSERT(lmgr_mutex_is_locked(&dev->m_mutex) == 1); ASSERT(dev->blocked()); dev->set_blocked(BST_NOT_BLOCKED); clear_thread_id(dev->no_wait_id); if (dev->num_waiting > 0) { pthread_cond_broadcast(&dev->wait); /* wake them up */ } } /* * Enter with device locked and blocked * Exit with device unlocked and blocked by us. */ void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state) { Dmsg3(sd_dbglvl, "steal lock. old=%s from %s:%d\n", dev->print_blocked(), file, line); hold->dev_blocked = dev->blocked(); hold->dev_prev_blocked = dev->dev_prev_blocked; hold->no_wait_id = dev->no_wait_id; dev->set_blocked(state); Dmsg1(sd_dbglvl, "steal lock. new=%s\n", dev->print_blocked()); dev->no_wait_id = pthread_self(); dev->Unlock(); } /* * Enter with device blocked by us but not locked * Exit with device locked, and blocked by previous owner */ void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold) { Dmsg3(sd_dbglvl, "return lock. old=%s from %s:%d\n", dev->print_blocked(), file, line); dev->Lock(); dev->set_blocked(hold->dev_blocked); dev->dev_prev_blocked = hold->dev_prev_blocked; dev->no_wait_id = hold->no_wait_id; Dmsg1(sd_dbglvl, "return lock. new=%s\n", dev->print_blocked()); if (dev->num_waiting > 0) { pthread_cond_broadcast(&dev->wait); /* wake them up */ } } const char *DEVICE::print_blocked() const { switch (m_blocked) { case BST_NOT_BLOCKED: return "BST_NOT_BLOCKED"; case BST_UNMOUNTED: return "BST_UNMOUNTED"; case BST_WAITING_FOR_SYSOP: return "BST_WAITING_FOR_SYSOP"; case BST_DOING_ACQUIRE: return "BST_DOING_ACQUIRE"; case BST_WRITING_LABEL: return "BST_WRITING_LABEL"; case BST_UNMOUNTED_WAITING_FOR_SYSOP: return "BST_UNMOUNTED_WAITING_FOR_SYSOP"; case BST_MOUNT: return "BST_MOUNT"; case BST_DESPOOLING: return "BST_DESPOOLING"; case BST_RELEASING: return "BST_RELEASING"; default: return _("unknown blocked code"); } } /* * Check if the device is blocked or not */ bool DEVICE::is_device_unmounted() { bool status; int blk = blocked(); status = (blk == BST_UNMOUNTED) || (blk == BST_UNMOUNTED_WAITING_FOR_SYSOP); return status; } bareos-Release-14.2.6/src/stored/lock.h000066400000000000000000000051071263011562700176330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Definitions for locking and blocking functions in the SD * * Kern Sibbald, pulled out of dev.h June 2007 */ #ifndef __LOCK_H #define __LOCK_H 1 #ifdef SD_DEBUG_LOCK #define r_dlock() _r_dlock(__FILE__, __LINE__); /* in lock.c */ #define r_dunlock() _r_dunlock(__FILE__, __LINE__); /* in lock.c */ #define dlock() _dlock(__FILE__, __LINE__); /* in lock.c */ #define dunlock() _dunlock(__FILE__, __LINE__); /* in lock.c */ #endif #define block_device(d, s) _block_device(__FILE__, __LINE__, (d), s) #define unblock_device(d) _unblock_device(__FILE__, __LINE__, (d)) #define steal_device_lock(d, p, s) _steal_device_lock(__FILE__, __LINE__, (d), (p), s) #define give_back_device_lock(d, p) _give_back_device_lock(__FILE__, __LINE__, (d), (p)) /* m_blocked states (mutually exclusive) */ enum { BST_NOT_BLOCKED = 0, /* not blocked */ BST_UNMOUNTED, /* User unmounted device */ BST_WAITING_FOR_SYSOP, /* Waiting for operator to mount tape */ BST_DOING_ACQUIRE, /* Opening/validating/moving tape */ BST_WRITING_LABEL, /* Labeling a tape */ BST_UNMOUNTED_WAITING_FOR_SYSOP, /* User unmounted during wait for op */ BST_MOUNT, /* Mount request */ BST_DESPOOLING, /* Despooling -- i.e. multiple writes */ BST_RELEASING /* Releasing the device */ }; typedef struct s_steal_lock { pthread_t no_wait_id; /* id of no wait thread */ int dev_blocked; /* state */ int dev_prev_blocked; /* previous blocked state */ } bsteal_lock_t; /* * Used in unblock() call */ enum { DEV_LOCKED = true, DEV_UNLOCKED = false }; #endif bareos-Release-14.2.6/src/stored/mac.c000066400000000000000000000467221263011562700174460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * SD -- mac.c -- responsible for doing * migration, archive, copy, and virtual backup jobs. * * Kern Sibbald, January MMVI */ #include "bareos.h" #include "stored.h" /* Import functions */ /* Forward referenced subroutines */ /* * Responses sent to the Director */ static char Job_end[] = "3099 Job %s end JobStatus=%d JobFiles=%d JobBytes=%s JobErrors=%u\n"; /* * Responses received from Storage Daemon */ static char OK_start_replicate[] = "3000 OK start replicate ticket = %d\n"; static char OK_data[] = "3000 OK data\n"; static char OK_replicate[] = "3000 OK replicate data\n"; static char OK_end_replicate[] = "3000 OK end replicate\n"; /* * Commands sent to Storage Daemon */ static char start_replicate[] = "start replicate\n"; static char replicate_data[] = "replicate data %d\n"; static char end_replicate[] = "end replicate\n"; /* * Get response from Storage daemon to a command we sent. * Check that the response is OK. * * Returns: false on failure * true on success */ static bool response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd) { if (sd->errors) { return false; } if (bget_msg(sd) > 0) { Dmsg1(110, "msg); if (bstrcmp(sd->msg, resp)) { return true; } } if (job_canceled(jcr)) { return false; /* if canceled avoid useless error messages */ } if (is_bnet_error(sd)) { Jmsg2(jcr, M_FATAL, 0, _("Comm error with SD. bad response to %s. ERR=%s\n"), cmd, bnet_strerror(sd)); } else { Jmsg3(jcr, M_FATAL, 0, _("Bad response to %s command. Wanted %s, got %s\n"), cmd, resp, sd->msg); } return false; } /* * Called here for each record from read_records() * This function is used when we do a internal clone of a Job e.g. * this SD is both the reading and writing SD. * * Returns: true if OK * false if error */ static bool clone_record_internally(DCR *dcr, DEV_RECORD *rec) { JCR *jcr = dcr->jcr; DEVICE *dev = jcr->dcr->dev; char buf1[100], buf2[100]; #ifdef xxx Dmsg5(000, "on entry JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); #endif /* * If label and not for us, discard it */ if (rec->FileIndex < 0 && rec->match_stat <= 0) { return true; } /* * We want to write SOS_LABEL and EOS_LABEL discard all others */ switch (rec->FileIndex) { case PRE_LABEL: case VOL_LABEL: case EOT_LABEL: case EOM_LABEL: return true; /* don't write vol labels */ } // if (jcr->is_JobType(JT_BACKUP)) { /* * For normal migration jobs, FileIndex values are sequential because * we are dealing with one job. However, for Vbackup (consolidation), * we will be getting records from multiple jobs and writing them back * out, so we need to ensure that the output FileIndex is sequential. * We do so by detecting a FileIndex change and incrementing the * JobFiles, which we then use as the output FileIndex. */ if (rec->FileIndex >= 0) { /* * If something changed, increment FileIndex */ if (rec->VolSessionId != rec->last_VolSessionId || rec->VolSessionTime != rec->last_VolSessionTime || rec->FileIndex != rec->last_FileIndex) { jcr->JobFiles++; rec->last_VolSessionId = rec->VolSessionId; rec->last_VolSessionTime = rec->VolSessionTime; rec->last_FileIndex = rec->FileIndex; } rec->FileIndex = jcr->JobFiles; /* set sequential output FileIndex */ } // } /* * Modify record SessionId and SessionTime to correspond to output. */ rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; Dmsg5(200, "before write JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); while (!write_record_to_block(jcr->dcr, rec)) { Dmsg4(200, "!write_record_to_block blkpos=%u:%u len=%d rem=%d\n", dev->file, dev->block_num, rec->data_len, rec->remainder); if (!jcr->dcr->write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n", dev->print_name(), dev->bstrerror()); Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); return false; } Dmsg2(200, "===== Wrote block new pos %u:%u\n", dev->file, dev->block_num); } /* * Restore packet */ rec->VolSessionId = rec->last_VolSessionId; rec->VolSessionTime = rec->last_VolSessionTime; if (rec->FileIndex < 0) { return true; /* don't send LABELs to Dir */ } jcr->JobBytes += rec->data_len; /* increment bytes of this job */ Dmsg5(500, "wrote_record JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); send_attrs_to_dir(jcr, rec); return true; } /* * Called here for each record from read_records() * This function is used when we do a external clone of a Job e.g. * this SD is the reading SD. And a remote SD is the writing SD. * * Returns: true if OK * false if error */ static bool clone_record_to_remote_sd(DCR *dcr, DEV_RECORD *rec) { POOLMEM *msgsave; JCR *jcr = dcr->jcr; char buf1[100], buf2[100]; BSOCK *sd = jcr->store_bsock; bool send_eod, send_header; #ifdef xxx Dmsg5(000, "on entry JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); #endif /* * If label discard it */ if (rec->FileIndex < 0) { return true; } /* * See if this is the first record being processed. */ if (rec->last_FileIndex == 0) { /* * Initialize the last counters so we can compare * things in the next run through here. */ rec->last_VolSessionId = rec->VolSessionId; rec->last_VolSessionTime = rec->VolSessionTime; rec->last_FileIndex = rec->FileIndex; rec->last_Stream = rec->Stream; jcr->JobFiles = 1; /* * Need to send both a new header only. */ send_eod = false; send_header = true; } else { /* * See if we are changing file or stream type. */ if (rec->VolSessionId != rec->last_VolSessionId || rec->VolSessionTime != rec->last_VolSessionTime || rec->FileIndex != rec->last_FileIndex || rec->Stream != rec->last_Stream) { /* * See if we are changing the FileIndex e.g. * start processing the next file in the backup stream. */ if (rec->FileIndex != rec->last_FileIndex) { jcr->JobFiles++; } /* * Keep track of the new state. */ rec->last_VolSessionId = rec->VolSessionId; rec->last_VolSessionTime = rec->VolSessionTime; rec->last_FileIndex = rec->FileIndex; rec->last_Stream = rec->Stream; /* * Need to send both a EOD and a new header. */ send_eod = true; send_header = true; } else { send_eod = false; send_header = false; } } /* * Send a EOD when needed. */ if (send_eod) { if (!sd->signal(BNET_EOD)) { /* indicate end of file data */ if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } return false; } } /* * Send a header when needed. */ if (send_header) { if (!sd->fsend("%ld %d 0", rec->FileIndex, rec->Stream)) { if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } return false; } } /* * Send the record data. * We don't want to copy the data from the record to the socket structure * so we save the original msg pointer and use the record data pointer for * sending and restore the original msg pointer when done. */ msgsave = sd->msg; sd->msg = rec->data; sd->msglen = rec->data_len; if (!sd->send()) { sd->msg = msgsave; sd->msglen = 0; if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } return false; } jcr->JobBytes += sd->msglen; sd->msg = msgsave; Dmsg5(500, "wrote_record JobId=%d FI=%s SessId=%d Strm=%s len=%d\n", jcr->JobId, FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); return true; } /* * Check autoinflation/autodeflation settings. */ static inline void check_auto_xflation(JCR *jcr) { /* * See if the autoxflateonreplication flag is set to true then we allow * autodeflation and autoinflation to take place. */ if (me->autoxflateonreplication) { return; } /* * Check autodeflation. */ switch (jcr->read_dcr->autodeflate) { case IO_DIRECTION_IN: case IO_DIRECTION_INOUT: Dmsg0(200, "Clearing autodeflate on read_dcr\n"); jcr->read_dcr->autodeflate = IO_DIRECTION_NONE; break; default: break; } if (jcr->dcr) { switch (jcr->dcr->autodeflate) { case IO_DIRECTION_OUT: case IO_DIRECTION_INOUT: Dmsg0(200, "Clearing autodeflate on write dcr\n"); jcr->dcr->autodeflate = IO_DIRECTION_NONE; break; default: break; } } /* * Check autoinflation. */ switch (jcr->read_dcr->autoinflate) { case IO_DIRECTION_IN: case IO_DIRECTION_INOUT: Dmsg0(200, "Clearing autoinflate on read_dcr\n"); jcr->read_dcr->autoinflate = IO_DIRECTION_NONE; break; default: break; } if (jcr->dcr) { switch (jcr->dcr->autoinflate) { case IO_DIRECTION_OUT: case IO_DIRECTION_INOUT: Dmsg0(200, "Clearing autoinflate on write dcr\n"); jcr->dcr->autoinflate = IO_DIRECTION_NONE; break; default: break; } } } /* * Read Data and commit to new job. */ bool do_mac_run(JCR *jcr) { DEVICE *dev; utime_t now; char ec1[50]; const char *Type; bool ok = true; BSOCK *dir = jcr->dir_bsock; switch(jcr->getJobType()) { case JT_MIGRATE: Type = "Migration"; break; case JT_ARCHIVE: Type = "Archive"; break; case JT_COPY: Type = "Copy"; break; case JT_BACKUP: Type = "Virtual Backup"; break; default: Type = "Unknown"; break; } Dmsg0(20, "Start read data.\n"); if (jcr->NumReadVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type); goto bail_out; } /* * Check autoinflation/autodeflation settings. */ check_auto_xflation(jcr); /* * See if we perform both read and write or read only. */ if (jcr->remote_replicate) { BSOCK *sd; if (!jcr->read_dcr) { Jmsg(jcr, M_FATAL, 0, _("Read device not properly initialized.\n")); goto bail_out; } Dmsg1(100, "read_dcr=%p\n", jcr->read_dcr); Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumReadVolumes, Type, jcr->VolList->VolumeName); /* * Ready devices for reading. */ if (!acquire_device_for_read(jcr->read_dcr)) { ok = false; goto bail_out; } Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->read_dcr->dev->file, jcr->read_dcr->dev->block_num); jcr->sendJobStatus(JS_Running); /* * Set network buffering. */ sd = jcr->store_bsock; if (!sd->set_buffer_size(me->max_network_buffer_size, BNET_SETBUF_WRITE)) { Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size SD->SD.\n")); ok = false; goto bail_out; } /* * Let the remote SD know we are about to start the replication. */ sd->fsend(start_replicate); Dmsg1(110, ">stored: %s", sd->msg); /* * Expect to receive back the Ticket number. */ if (bget_msg(sd) >= 0) { Dmsg1(110, "msg); if (sscanf(sd->msg, OK_start_replicate, &jcr->Ticket) != 1) { Jmsg(jcr, M_FATAL, 0, _("Bad response to start replicate: %s\n"), sd->msg); goto bail_out; } Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket); } else { Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to start replicate command\n")); goto bail_out; } /* * Let the remote SD know we are now really going to send the data. */ sd->fsend(replicate_data, jcr->Ticket); Dmsg1(110, ">stored: %s", sd->msg); /* * Expect to get response to the replicate data cmd from Storage daemon */ if (!response(jcr, sd, OK_data, "replicate data")) { ok = false; goto bail_out; } /* * Update the initial Job Statistics. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); /* * Read all data and send it to remote SD. */ ok = read_records(jcr->read_dcr, clone_record_to_remote_sd, mount_next_read_volume); /* * Send the last EOD to close the last data transfer and a next EOD to * signal the remote we are done. */ if (!sd->signal(BNET_EOD) || !sd->signal(BNET_EOD)) { if (!jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror()); } goto bail_out; } /* * Expect to get response that the replicate data succeeded. */ if (!response(jcr, sd, OK_replicate, "replicate data")) { ok = false; goto bail_out; } /* * End replicate session. */ sd->fsend(end_replicate); Dmsg1(110, ">stored: %s", sd->msg); /* * Expect to get response to the end replicate cmd from Storage daemon */ if (!response(jcr, sd, OK_end_replicate, "end replicate")) { ok = false; goto bail_out; } /* Inform Storage daemon that we are done */ sd->signal(BNET_TERMINATE); } else { if (!jcr->read_dcr || !jcr->dcr) { Jmsg(jcr, M_FATAL, 0, _("Read and write devices not properly initialized.\n")); goto bail_out; } Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr); Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumReadVolumes, Type, jcr->VolList->VolumeName); /* * Ready devices for reading and writing. */ if (!acquire_device_for_read(jcr->read_dcr) || !acquire_device_for_append(jcr->dcr)) { ok = false; goto bail_out; } Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num); jcr->sendJobStatus(JS_Running); /* * Update the initial Job Statistics. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); if (!begin_data_spool(jcr->dcr) ) { ok = false; goto bail_out; } if (!begin_attribute_spool(jcr)) { ok = false; goto bail_out; } jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0; jcr->run_time = time(NULL); set_start_vol_position(jcr->dcr); jcr->JobFiles = 0; /* * Read all data and make a local clone of it. */ ok = read_records(jcr->read_dcr, clone_record_internally, mount_next_read_volume); } bail_out: if (!ok) { jcr->setJobStatus(JS_ErrorTerminated); } if (!jcr->remote_replicate && jcr->dcr) { /* * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits, * and the subsequent Jmsg() editing will break */ int32_t job_elapsed; dev = jcr->dcr->dev; Dmsg1(100, "ok=%d\n", ok); if (ok || dev->can_write()) { /* * Flush out final partial block of this session */ if (!jcr->dcr->write_block_to_device()) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n")); ok = false; } Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num); } if (!ok) { discard_data_spool(jcr->dcr); } else { /* * Note: if commit is OK, the device will remain blocked */ commit_data_spool(jcr->dcr); } job_elapsed = time(NULL) - jcr->run_time; if (job_elapsed <= 0) { job_elapsed = 1; } Jmsg(jcr, M_INFO, 0, _("Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n"), job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60, edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec1)); /* * Release the device -- and send final Vol info to DIR */ release_device(jcr->dcr); if (!ok || job_canceled(jcr)) { discard_attribute_spool(jcr); } else { commit_attribute_spool(jcr); } } if (jcr->read_dcr) { if (!release_device(jcr->read_dcr)) { ok = false; } } jcr->sendJobStatus(); /* update director */ Dmsg0(30, "Done reading.\n"); jcr->end_time = time(NULL); dequeue_messages(jcr); /* send any queued messages */ if (ok) { jcr->setJobStatus(JS_Terminated); } generate_plugin_event(jcr, bsdEventJobEnd); dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); Dmsg4(100, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1); dir->signal(BNET_EOD); /* send EOD to Director daemon */ free_plugins(jcr); /* release instantiated plugins */ return false; /* Continue DIR session ? */ } bareos-Release-14.2.6/src/stored/mount.c000066400000000000000000000723231263011562700200440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Routines for handling mounting tapes for reading and for writing. * * Kern Sibbald, August MMII */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ static pthread_mutex_t mount_mutex = PTHREAD_MUTEX_INITIALIZER; enum { try_next_vol = 1, try_read_vol, try_error, try_default }; enum { check_next_vol = 1, check_ok, check_read_vol, check_error }; /* * If release is set, we rewind the current volume, * which we no longer want, and ask the user (console) * to mount the next volume. * * Continue trying until we get it, and then ensure * that we can write on it. * * This routine returns a 0 only if it is REALLY * impossible to get the requested Volume. * * This routine is entered with the device blocked, but not * locked. * */ bool DCR::mount_next_write_volume() { int retry = 0; bool ask = false, recycle, autochanger; int mode; DCR *dcr = this; Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", dev->must_unload(), dev->print_name()); init_device_wait_timers(dcr); P(mount_mutex); /* * Attempt to mount the next volume. If something non-fatal goes * wrong, we come back here to re-try (new op messages, re-read * Volume, ...) */ mount_next_vol: Dmsg1(150, "mount_next_vol retry=%d\n", retry); /* * Ignore retry if this is poll request */ if (retry++ > 4) { /* * Last ditch effort before giving up, force operator to respond */ VolCatInfo.Slot = 0; V(mount_mutex); if (!dcr->dir_ask_sysop_to_mount_volume(ST_APPENDREADY)) { Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"), dev->print_name()); goto no_lock_bail_out; } P(mount_mutex); Dmsg1(150, "Continue after dir_ask_sysop_to_mount. must_load=%d\n", dev->must_load()); } if (job_canceled(jcr)) { Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId); goto bail_out; } recycle = false; if (dev->must_unload()) { ask = true; /* ask operator to mount tape */ } do_unload(); do_swapping(true /*is_writing*/); do_load(true /*is_writing*/); if (!find_a_volume()) { goto bail_out; } if (job_canceled(jcr)) { goto bail_out; } Dmsg2(150, "After find_next_append. Vol=%s Slot=%d\n", getVolCatName(), VolCatInfo.Slot); /* * Get next volume and ready it for append * This code ensures that the device is ready for * writing. We start from the assumption that there * may not be a tape mounted. * * If the device is a file, we create the output * file. If it is a tape, we check the volume name * and move the tape to the end of data. * */ dcr->setVolCatInfo(false); /* out of date when Vols unlocked */ if (autoload_device(dcr, true/*writing*/, NULL) > 0) { autochanger = true; ask = false; } else { autochanger = false; VolCatInfo.Slot = 0; ask = retry >= 2; } Dmsg1(150, "autoload_dev returns %d\n", autochanger); /* * If we autochanged to correct Volume or (we have not just * released the Volume AND we can automount) we go ahead * and read the label. If there is no tape in the drive, * we will fail, recurse and ask the operator the next time. */ if (!dev->must_unload() && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) { Dmsg0(250, "(1)Ask=0\n"); ask = false; /* don't ask SYSOP this time */ } /* Don't ask if not removable */ if (!dev->is_removable()) { Dmsg0(250, "(2)Ask=0\n"); ask = false; } Dmsg2(250, "Ask=%d autochanger=%d\n", ask, autochanger); if (ask) { V(mount_mutex); dcr->setVolCatInfo(false); /* out of date when Vols unlocked */ if (!dcr->dir_ask_sysop_to_mount_volume(ST_APPENDREADY)) { Dmsg0(150, "Error return ask_sysop ...\n"); goto no_lock_bail_out; } P(mount_mutex); } if (job_canceled(jcr)) { goto bail_out; } Dmsg3(150, "want vol=%s devvol=%s dev=%s\n", VolumeName, dev->VolHdr.VolumeName, dev->print_name()); if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) { dev->close(dcr); free_volume(dev); } /* Ensure the device is open */ if (dev->has_cap(CAP_STREAM)) { mode = OPEN_WRITE_ONLY; } else { mode = OPEN_READ_WRITE; } /* Try autolabel if enabled */ if (!dev->open(dcr, mode)) { try_autolabel(false); /* try to create a new volume label */ } while (!dev->open(dcr, mode)) { Dmsg1(150, "open_device failed: ERR=%s\n", dev->bstrerror()); if (dev->is_file() && dev->is_removable()) { bool ok = true; Dmsg0(150, "call scan_dir_for_vol\n"); if (ok && dev->scan_dir_for_volume(dcr)) { if (dev->open(dcr, mode)) { break; /* got a valid volume */ } } } if (try_autolabel(false) == try_read_vol) { break; /* created a new volume label */ } Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"), dev->print_name(), dcr->VolumeName, dev->bstrerror()); Dmsg0(50, "set_unload\n"); dev->set_unload(); /* force ask sysop */ ask = true; Dmsg0(150, "goto mount_next_vol\n"); goto mount_next_vol; } /* * Now check the volume label to make sure we have the right tape mounted */ read_volume: switch (check_volume_label(ask, autochanger)) { case check_next_vol: Dmsg0(50, "set_unload\n"); dev->set_unload(); /* want a different Volume */ Dmsg0(150, "goto mount_next_vol\n"); goto mount_next_vol; case check_read_vol: goto read_volume; case check_error: goto bail_out; case check_ok: break; } /* * Check that volcatinfo is good */ if (!dev->haveVolCatInfo()) { Dmsg0(210, "Do not have volcatinfo\n"); if (!find_a_volume()) { goto mount_next_vol; } dev->VolCatInfo = VolCatInfo; /* structure assignment */ /* * Apply the Volume Blocksizes to device */ dcr->VolMinBlocksize = VolCatInfo.VolMinBlocksize; dcr->VolMaxBlocksize = VolCatInfo.VolMaxBlocksize; Dmsg3(200, "applying vol block sizes to device %s: dcr->VolMinBlocksize set to %u, dcr->VolMaxBlocksize set to %u\n", dev->print_name(), dcr->VolMinBlocksize, dcr->VolMaxBlocksize); /* * Set the block sizes of the dcr in the device. */ dev->set_blocksizes(dcr); } /* * See if we have a fresh tape or a tape with data. * * Note, if the LabelType is PRE_LABEL, it was labeled * but never written. If so, rewrite the label but set as * VOL_LABEL. We rewind and return the label (reconstructed) * in the block so that in the case of a new tape, data can * be appended just after the block label. If we are writing * a second volume, the calling routine will write the label * before writing the overflow block. * * If the tape is marked as Recycle, we rewrite the label. */ recycle = bstrcmp(dev->VolCatInfo.VolCatStatus, "Recycle"); if (dev->VolHdr.LabelType == PRE_LABEL || recycle) { if (!dcr->rewrite_volume_label(recycle)) { mark_volume_in_error(); goto mount_next_vol; } } else { /* * OK, at this point, we have a valid Bareos label, but * we need to position to the end of the volume, since we are * just now putting it into append mode. */ Dmsg1(100, "Device previously written, moving to end of data. Expect %lld bytes\n", dev->VolCatInfo.VolCatBytes); Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"), VolumeName); if (!dev->eod(dcr)) { Dmsg2(050, "Unable to position to end of data on device %s: ERR=%s\n", dev->print_name(), dev->bstrerror()); Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); mark_volume_in_error(); goto mount_next_vol; } if (!is_eod_valid()) { Dmsg0(100, "goto mount_next_vol\n"); goto mount_next_vol; } dev->VolCatInfo.VolCatMounts++; /* Update mounts */ Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts); if (!dcr->dir_update_volume_info(false, false)) { goto bail_out; } /* Return an empty block */ empty_block(block); /* we used it for reading so set for write */ } dev->set_append(); Dmsg1(150, "set APPEND, normal return from mount_next_write_volume. dev=%s\n", dev->print_name()); V(mount_mutex); return true; bail_out: V(mount_mutex); no_lock_bail_out: return false; } /* * This routine is meant to be called once the first pass * to ensure that we have a candidate volume to mount. * Otherwise, we ask the sysop to created one. * Note, mount_mutex is already locked on entry and thus * must remain locked on exit from this function. */ bool DCR::find_a_volume() { DCR *dcr = this; if (!is_suitable_volume_mounted()) { bool have_vol = false; /* Do we have a candidate volume? */ if (dev->vol) { bstrncpy(VolumeName, dev->vol->vol_name, sizeof(VolumeName)); have_vol = dcr->dir_get_volume_info(GET_VOL_INFO_FOR_WRITE); } /* * Get Director's idea of what tape we should have mounted. * in dcr->VolCatInfo */ if (!have_vol) { Dmsg0(200, "Before dir_find_next_appendable_volume.\n"); while (!dcr->dir_find_next_appendable_volume()) { Dmsg0(200, "not dir_find_next\n"); if (job_canceled(jcr)) { return false; } V(mount_mutex); if (!dcr->dir_ask_sysop_to_create_appendable_volume()) { P(mount_mutex); return false; } P(mount_mutex); if (job_canceled(jcr)) { return false; } Dmsg0(150, "Again dir_find_next_append...\n"); } } } if (dcr->haveVolCatInfo()) { return true; } return dcr->dir_get_volume_info(GET_VOL_INFO_FOR_WRITE); } int DCR::check_volume_label(bool &ask, bool &autochanger) { DCR *dcr = this; int vol_label_status; /* * If we are writing to a stream device, ASSUME the volume label * is correct. */ if (dev->has_cap(CAP_STREAM)) { vol_label_status = VOL_OK; create_volume_label(dev, VolumeName, "Default"); dev->VolHdr.LabelType = PRE_LABEL; } else { vol_label_status = read_dev_volume_label(dcr); } if (job_canceled(jcr)) { goto check_bail_out; } Dmsg2(150, "Want dirVol=%s dirStat=%s\n", VolumeName, VolCatInfo.VolCatStatus); /* * At this point, dev->VolCatInfo has what is in the drive, if anything, * and dcr->VolCatInfo has what the Director wants. */ switch (vol_label_status) { case VOL_OK: Dmsg1(150, "Vol OK name=%s\n", dev->VolHdr.VolumeName); dev->VolCatInfo = VolCatInfo; /* structure assignment */ break; /* got a Volume */ case VOL_NAME_ERROR: VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo; char saveVolumeName[MAX_NAME_LENGTH]; Dmsg2(150, "Vol NAME Error Have=%s, want=%s\n", dev->VolHdr.VolumeName, VolumeName); if (dev->is_volume_to_unload()) { ask = true; goto check_next_volume; } /* If not removable, Volume is broken */ if (!dev->is_removable()) { Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"), VolumeName, dev->print_name()); mark_volume_in_error(); goto check_next_volume; } /* * OK, we got a different volume mounted. First save the * requested Volume info (dcr) structure, then query if * this volume is really OK. If not, put back the desired * volume name, mark it not in changer and continue. */ dcrVolCatInfo = VolCatInfo; /* structure assignment */ devVolCatInfo = dev->VolCatInfo; /* structure assignment */ /* Check if this is a valid Volume in the pool */ bstrncpy(saveVolumeName, VolumeName, sizeof(saveVolumeName)); bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName)); if (!dcr->dir_get_volume_info(GET_VOL_INFO_FOR_WRITE)) { POOL_MEM vol_info_msg; pm_strcpy(vol_info_msg, jcr->dir_bsock->msg); /* save error message */ /* Restore desired volume name, note device info out of sync */ /* This gets the info regardless of the Pool */ bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName)); if (autochanger && !dcr->dir_get_volume_info(GET_VOL_INFO_FOR_READ)) { /* * If we get here, we know we cannot write on the Volume, * and we know that we cannot read it either, so it * is not in the autochanger. */ mark_volume_not_inchanger(); } dev->VolCatInfo = devVolCatInfo; /* structure assignment */ dev->set_unload(); /* unload this volume */ Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s"), dcrVolCatInfo.VolCatName, dev->VolHdr.VolumeName, vol_info_msg.c_str()); ask = true; /* Restore saved DCR before continuing */ bstrncpy(VolumeName, saveVolumeName, sizeof(VolumeName)); VolCatInfo = dcrVolCatInfo; /* structure assignment */ goto check_next_volume; } /* * This was not the volume we expected, but it is OK with * the Director, so use it. */ Dmsg1(150, "Got new Volume name=%s\n", VolumeName); dev->VolCatInfo = VolCatInfo; /* structure assignment */ Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName); if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) { Jmsg2(jcr, M_WARNING, 0, _("Could not reserve volume %s on %s\n"), dev->VolHdr.VolumeName, dev->print_name()); ask = true; dev->setVolCatInfo(false); setVolCatInfo(false); goto check_next_volume; } break; /* got a Volume */ /* * At this point, we assume we have a blank tape mounted. */ case VOL_IO_ERROR: /* Fall through wanted */ case VOL_NO_LABEL: switch (try_autolabel(true)) { case try_next_vol: goto check_next_volume; case try_read_vol: goto check_read_volume; case try_error: goto check_bail_out; case try_default: break; } /* NOTE! Fall-through wanted. */ case VOL_NO_MEDIA: default: Dmsg0(200, "VOL_NO_MEDIA or default.\n"); /* Send error message */ if (!dev->poll) { } else { Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg); } ask = true; /* Needed, so the medium can be changed */ if (dev->requires_mount()) { dev->close(dcr); free_volume(dev); } goto check_next_volume; } return check_ok; check_next_volume: dev->setVolCatInfo(false); setVolCatInfo(false); return check_next_vol; check_bail_out: return check_error; check_read_volume: return check_read_vol; } bool DCR::is_suitable_volume_mounted() { /* Volume mounted? */ if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->must_unload()) { return false; /* no */ } bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName)); return dir_get_volume_info(GET_VOL_INFO_FOR_WRITE); } bool DCR::do_unload() { DCR *dcr = this; if (generate_plugin_event(jcr, bsdEventVolumeUnload, dcr) != bRC_OK) { return false; } if (dev->must_unload()) { Dmsg1(100, "must_unload release %s\n", dev->print_name()); release_volume(); } return true; } bool DCR::do_load(bool is_writing) { DCR *dcr = this; bool retval = false; if (dev->must_load()) { Dmsg1(100, "Must load %s\n", dev->print_name()); if (autoload_device(dcr, is_writing, NULL) > 0) { dev->clear_load(); retval = true; } } else { retval = true; } if (generate_plugin_event(jcr, bsdEventVolumeLoad, dcr) != bRC_OK) { retval = false; } return retval; } void DCR::do_swapping(bool is_writing) { DCR *dcr = this; /* * See if we are asked to swap the Volume from another device * if so, unload the other device here, and attach the * volume to our drive. */ if (dev->swap_dev) { if (dev->swap_dev->must_unload()) { if (dev->vol) { dev->swap_dev->set_slot(dev->vol->get_slot()); } Dmsg2(100, "Swap unloading slot=%d %s\n", dev->swap_dev->get_slot(), dev->swap_dev->print_name()); unload_dev(dcr, dev->swap_dev); } if (dev->vol) { dev->vol->clear_swapping(); Dmsg1(100, "=== set in_use vol=%s\n", dev->vol->vol_name); dev->vol->set_in_use(); dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */ } else { Dmsg1(100, "No vol on dev=%s\n", dev->print_name()); } if (dev->swap_dev->vol) { Dmsg2(100, "Vol=%s on dev=%s\n", dev->swap_dev->vol->vol_name, dev->swap_dev->print_name()); } Dmsg2(100, "Set swap_dev=NULL for dev=%s swap_dev=%s\n", dev->print_name(), dev->swap_dev->print_name()); dev->swap_dev = NULL; } else { Dmsg0(100, "No swap_dev set\n"); } } /* * Check if the current position on the volume corresponds to what is in the catalog. */ bool DCR::is_eod_valid() { DCR *dcr = this; if (dev->is_tape()) { /* * Check if we are positioned on the tape at the same place * that the database says we should be. */ if (dev->VolCatInfo.VolCatFiles == dev->get_file()) { Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"), VolumeName, dev->get_file()); } else if (dev->get_file() > dev->VolCatInfo.VolCatFiles) { Jmsg(jcr, M_WARNING, 0, _("For Volume \"%s\":\n" "The number of files mismatch! Volume=%u Catalog=%u\n" "Correcting Catalog\n"), VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles); dev->VolCatInfo.VolCatFiles = dev->get_file(); dev->VolCatInfo.VolCatBlocks = dev->get_block_num(); if (!dcr->dir_update_volume_info(false, true)) { Jmsg(jcr, M_WARNING, 0, _("Error updating Catalog\n")); mark_volume_in_error(); return false; } } else { Jmsg(jcr, M_ERROR, 0, _("Bareos cannot write on tape Volume \"%s\" because:\n" "The number of files mismatch! Volume=%u Catalog=%u\n"), VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles); mark_volume_in_error(); return false; } } else if (dev->is_file()) { char ed1[50], ed2[50]; boffset_t pos; pos = dev->lseek(dcr, (boffset_t)0, SEEK_END); if (dev->VolCatInfo.VolCatBytes == (uint64_t)pos) { Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\"" " size=%s\n"), VolumeName, edit_uint64(dev->VolCatInfo.VolCatBytes, ed1)); } else if ((uint64_t)pos > dev->VolCatInfo.VolCatBytes) { Jmsg(jcr, M_WARNING, 0, _("For Volume \"%s\":\n" "The sizes do not match! Volume=%s Catalog=%s\n" "Correcting Catalog\n"), VolumeName, edit_uint64(pos, ed1), edit_uint64(dev->VolCatInfo.VolCatBytes, ed2)); dev->VolCatInfo.VolCatBytes = (uint64_t)pos; dev->VolCatInfo.VolCatFiles = (uint32_t)(pos >> 32); if (!dcr->dir_update_volume_info(false, true)) { Jmsg(jcr, M_WARNING, 0, _("Error updating Catalog\n")); mark_volume_in_error(); return false; } } else { Mmsg(jcr->errmsg, _("Bareos cannot write on disk Volume \"%s\" because: " "The sizes do not match! Volume=%s Catalog=%s\n"), VolumeName, edit_uint64(pos, ed1), edit_uint64(dev->VolCatInfo.VolCatBytes, ed2)); Jmsg(jcr, M_ERROR, 0, jcr->errmsg); Dmsg0(050, jcr->errmsg); mark_volume_in_error(); return false; } } else if (dev->is_fifo() || dev->is_vtl()) { return true; } else { Mmsg1(jcr->errmsg, _("Don't know how to check if EOD is valid for a device of type %d\n"), dev->dev_type); Jmsg(jcr, M_ERROR, 0, jcr->errmsg); Dmsg0(050, jcr->errmsg); return false; } return true; } /* * If permitted, we label the device, make sure we can do * it by checking that the VolCatBytes is zero => not labeled, * once the Volume is labeled we don't want to label another * blank tape with the same name. For disk, we go ahead and * label it anyway, because the OS insures that there is only * one Volume with that name. * As noted above, at this point dcr->VolCatInfo has what * the Director wants and dev->VolCatInfo has info on the * previous tape (or nothing). * * Return codes are: * try_next_vol label failed, look for another volume * try_read_vol labeled volume, now re-read the label * try_error hard error (catalog update) * try_default I couldn't do anything */ int DCR::try_autolabel(bool opened) { DCR *dcr = this; if (dev->poll && !dev->is_tape()) { return try_default; /* if polling, don't try to create new labels */ } /* For a tape require it to be opened and read before labeling */ if (!opened && dev->is_tape()) { return try_default; } if (dev->has_cap(CAP_LABEL) && (VolCatInfo.VolCatBytes == 0 || (!dev->is_tape() && bstrcmp(VolCatInfo.VolCatStatus, "Recycle")))) { Dmsg0(150, "Create volume label\n"); /* Create a new Volume label and write it to the device */ if (!write_new_volume_label_to_dev(dcr, VolumeName, pool_name, false /* no relabel */)) { Dmsg2(150, "write_vol_label failed. vol=%s, pool=%s\n", VolumeName, pool_name); if (opened) { mark_volume_in_error(); } return try_next_vol; } Dmsg0(150, "dir_update_vol_info. Set Append\n"); /* Copy Director's info into the device info */ dev->VolCatInfo = VolCatInfo; /* structure assignment */ if (!dcr->dir_update_volume_info(true, true)) { /* indicate tape labeled */ return try_error; } Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"), VolumeName, dev->print_name()); return try_read_vol; /* read label we just wrote */ } if (!dev->has_cap(CAP_LABEL) && VolCatInfo.VolCatBytes == 0) { Jmsg(jcr, M_WARNING, 0, _("Device %s not configured to autolabel Volumes.\n"), dev->print_name()); } /* If not removable, Volume is broken */ if (!dev->is_removable()) { Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"), VolumeName, dev->print_name()); mark_volume_in_error(); return try_next_vol; } return try_default; } /* * Mark volume in error in catalog */ void DCR::mark_volume_in_error() { DCR *dcr = this; Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"), VolumeName); dev->VolCatInfo = VolCatInfo; /* structure assignment */ bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus)); Dmsg0(150, "dir_update_vol_info. Set Error.\n"); dcr->dir_update_volume_info(false, false); volume_unused(dcr); Dmsg0(50, "set_unload\n"); dev->set_unload(); /* must get a new volume */ } /* * The Volume is not in the correct slot, so mark this * Volume as not being in the Changer. */ void DCR::mark_volume_not_inchanger() { DCR *dcr = this; Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n" " Setting InChanger to zero in catalog.\n"), getVolCatName(), VolCatInfo.Slot); dev->VolCatInfo = VolCatInfo; /* structure assignment */ VolCatInfo.InChanger = false; dev->VolCatInfo.InChanger = false; Dmsg0(400, "update vol info in mount\n"); dcr->dir_update_volume_info(true, false); /* set new status */ } /* * Either because we are going to hang a new volume, or because * of explicit user request, we release the current volume. */ void DCR::release_volume() { DCR *dcr = this; unload_autochanger(dcr, -1); generate_plugin_event(jcr, bsdEventVolumeUnload, dcr); if (WroteVol) { Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n")); Pmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n"); } /* * First erase all memory of the current volume */ free_volume(dev); dev->block_num = dev->file = 0; dev->EndBlock = dev->EndFile = 0; memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); dev->clear_volhdr(); /* * Force re-read of label */ dev->clear_labeled(); dev->clear_read(); dev->clear_append(); dev->label_type = B_BAREOS_LABEL; VolumeName[0] = 0; if (dev->is_open() && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) { dev->close(dcr); } /* * If we have not closed the device, then at least rewind the tape */ if (dev->is_open()) { dev->offline_or_rewind(); } Dmsg0(190, "release_volume\n"); } /* * Insanity check * * Check to see if the tape position as defined by the OS is * the same as our concept. If it is not, * it means the user has probably manually rewound the tape. * Note, we check only if num_writers == 0, but this code will * also work fine for any number of writers. If num_writers > 0, * we probably should cancel all jobs using this device, or * perhaps even abort the SD, or at a minimum, mark the tape * in error. Another strategy with num_writers == 0, would be * to rewind the tape and do a new eod() request. */ bool DCR::is_tape_position_ok() { if (dev->is_tape() && dev->num_writers == 0) { int32_t file = dev->get_os_tape_file(); if (file >= 0 && file != (int32_t)dev->get_file()) { Jmsg(jcr, M_ERROR, 0, _("Invalid tape position on volume \"%s\"" " on device %s. Expected %d, got %d\n"), dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file); /* * If the current file is greater than zero, it means we probably * have some bad count of EOF marks, so mark tape in error. Otherwise * the operator might have moved the tape, so we just release it * and try again. */ if (file > 0) { mark_volume_in_error(); } release_volume(); return false; } } return true; } /* * If we are reading, we come here at the end of the tape * and see if there are more volumes to be mounted. */ bool mount_next_read_volume(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->NumReadVolumes, jcr->CurReadVolume); volume_unused(dcr); /* release current volume */ /* * End Of Tape -- mount next Volume (if another specified) */ if (jcr->NumReadVolumes > 1 && jcr->CurReadVolume < jcr->NumReadVolumes) { dev->Lock(); dev->close(dcr); dev->set_read(); dcr->set_reserved(); dev->Unlock(); if (!acquire_device_for_read(dcr)) { Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(), dcr->VolumeName); return false; } return true; /* next volume mounted */ } Dmsg0(90, "End of Device reached.\n"); return false; } bareos-Release-14.2.6/src/stored/ndmp_tape.c000066400000000000000000001274741263011562700206610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * ndmp_tape.c implements the NDMP TAPE service which interfaces to * the internal Bareos infrstructure. This is implemented as a seperate * daemon protocol on a different port (10000 NDMP by default) which * interfaces to the standard Bareos storage daemon at the record level. * * E.g. normal data from a FD comes via the 9103 port and then get turned * into records for NDMP packets travel via the NDMP protocol library * which is named libbareosndmp and the data gets turned into native Bareos * tape records. * * Marco van Wieringen, May 2012 */ #include "bareos.h" #if HAVE_NDMP #include "stored.h" #include #include #include #include #ifdef HAVE_ARPA_NAMESER_H #include #endif #ifdef HAVE_LIBWRAP #include "tcpd.h" #endif #ifdef HAVE_POLL_H #include #elif HAVE_SYS_POLL_H #include #endif #include "ndmp/ndmagents.h" /* * Structure used to pass arguments to the ndmp_thread_server thread * via a void * argument. Things like the addresslist, maximum number * of clients and the client workqueue to use are passed using this * structure. */ struct ndmp_thread_server_args { dlist *addr_list; int max_clients; workq_t *client_wq; }; /* * Internal structure to keep track of private data for a NDMP session. * Referenced via (struct ndm_session)->session_handle. */ struct ndmp_session_handle { int fd; /* Socket file descriptor */ char *host; /* Host name/IP */ int port; /* Local port */ struct sockaddr client_addr; /* Client's IP address */ struct sockaddr_in peer_addr; /* Peer's IP address */ JCR *jcr; /* Internal JCR bound to this NDMP session */ }; /* * Internal structure to keep track of private data. */ struct ndmp_internal_state { uint32_t LogLevel; JCR *jcr; }; typedef struct ndmp_internal_state NIS; struct ndmp_backup_format_option { char *format; bool uses_level; }; static ndmp_backup_format_option ndmp_backup_format_options[] = { { (char *)"dump", true }, { (char *)"tar", false }, { (char *)"smtape", true }, { (char *)"zfs", true }, { (char *)"vbb", true }, { (char *)"image", true }, { NULL, false } }; static ndmp_backup_format_option *lookup_backup_format_options(const char *backup_format) { int i = 0; while (ndmp_backup_format_options[i].format) { if (bstrcasecmp(backup_format, ndmp_backup_format_options[i].format)) { break; } i++; } if (ndmp_backup_format_options[i].format) { return &ndmp_backup_format_options[i]; } return (ndmp_backup_format_option *)NULL; } /* Static globals */ static bool quit = false; static bool ndmp_initialized = false; static pthread_t ndmp_tid; static struct ndmp_thread_server_args ndmp_thread_server_args; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Forward referenced functions */ static inline int native_to_ndmp_loglevel(int debuglevel, NIS *nis) { unsigned int level; memset(nis, 0, sizeof(NIS)); /* * Lookup the initial default log_level from the default STORES. */ nis->LogLevel = me->ndmploglevel; /* * NDMP loglevels run from 0 - 9 so we take a look at the * current debug level and divide it by 100 to get a proper * value. If the debuglevel is below the wanted initial level * we set the loglevel to the wanted initial level. As the * debug logging takes care of logging messages that are * unwanted we can set the loglevel higher and still don't * get debug messages. */ level = debuglevel / 100; if (level < nis->LogLevel) { level = nis->LogLevel; } /* * Make sure the level is in the wanted range. */ if (level > 9) { level = 9; } return level; } /* * Interface function which glues the logging infra of the NDMP lib with the daemon. */ extern "C" void ndmp_loghandler(struct ndmlog *log, char *tag, int level, char *msg) { int internal_level; NIS *nis; /* * We don't want any trailing newline in log messages. */ strip_trailing_newline(msg); /* * Make sure if the logging system was setup properly. */ nis = (NIS *)log->ctx; if (!nis) { return; } /* * If the log level of this message is under our logging treshold we * log it as part of the Job. */ if (level <= (int)nis->LogLevel) { if (nis->jcr) { /* * Look at the tag field to see what is logged. */ if (bstrncmp(tag + 1, "LM", 2)) { /* * *LM* messages. E.g. log message NDMP protocol msgs. * First character of the tag is the agent sending the * message e.g. 'D' == Data Agent * 'T' == Tape Agent * 'R' == Robot Agent * 'C' == Control Agent (DMA) * * Last character is the type of message e.g. * 'n' - normal message * 'd' - debug message * 'e' - error message * 'w' - warning message * '?' - unknown message level */ switch (*(tag + 3)) { case 'n': Jmsg(nis->jcr, M_INFO, 0, "%s\n", msg); break; case 'e': Jmsg(nis->jcr, M_ERROR, 0, "%s\n", msg); break; case 'w': Jmsg(nis->jcr, M_WARNING, 0, "%s\n", msg); break; case '?': Jmsg(nis->jcr, M_INFO, 0, "%s\n", msg); break; default: break; } } else { Jmsg(nis->jcr, M_INFO, 0, "%s\n", msg); } } } /* * Print any debug message we convert the NDMP level back to an internal * level and let the normal debug logging handle if it needs to be printed * or not. */ internal_level = level * 100; Dmsg3(internal_level, "NDMP: [%s] [%d] %s\n", tag, level, msg); } /* * Clear text authentication callback. */ extern "C" int bndmp_auth_clear(struct ndm_session *sess, char *name, char *pass) { NDMPRES *auth_config; foreach_res(auth_config, R_NDMP) { /* * Only consider entries for AT_CLEAR authentication type. */ if (auth_config->AuthType != AT_CLEAR) { continue; } ASSERT(auth_config->password.encoding == p_encoding_clear); if (bstrcmp(name, auth_config->username) && bstrcmp(pass, auth_config->password.value)) { /* * See if we need to adjust the logging level. */ if (sess->param->log.ctx) { NIS *nis; nis = (NIS *)sess->param->log.ctx; if (nis->LogLevel != auth_config->LogLevel) { if (auth_config->LogLevel <= 9) { nis->LogLevel = auth_config->LogLevel; } } } return 1; } } return 0; } /* * MD5 authentication callback. */ extern "C" int bndmp_auth_md5(struct ndm_session *sess, char *name, char digest[16]) { NDMPRES *auth_config; foreach_res(auth_config, R_NDMP) { /* * Only consider entries for AT_MD5 authentication type. */ if (auth_config->AuthType != AT_MD5) { continue; } if (!bstrcmp(name, auth_config->username)) { continue; } ASSERT(auth_config->password.encoding == p_encoding_clear); if (!ndmmd5_ok_digest(sess->md5_challenge, auth_config->password.value, digest)) { return 0; } /* * See if we need to adjust the logging level. */ if (sess->param->log.ctx) { NIS *nis; nis = (NIS *)sess->param->log.ctx; if (nis->LogLevel != auth_config->LogLevel) { if (auth_config->LogLevel <= 9) { nis->LogLevel = auth_config->LogLevel; } } } return 1; } return 0; } /* * Save a record using the native routines. */ static inline bool bndmp_write_data_to_block(JCR *jcr, int stream, char *data, uint32_t data_length) { bool retval = false; DCR *dcr = jcr->dcr; POOLMEM *rec_data; /* * Keep track of the original data buffer and restore it on exit from this function. */ rec_data = dcr->rec->data; dcr->rec->VolSessionId = jcr->VolSessionId; dcr->rec->VolSessionTime = jcr->VolSessionTime; dcr->rec->FileIndex = dcr->FileIndex; dcr->rec->Stream = stream; dcr->rec->maskedStream = stream & STREAMMASK_TYPE; /* strip high bits */ dcr->rec->data = data; dcr->rec->data_len = data_length; if (!dcr->write_record()) { goto bail_out; } if (stream == STREAM_UNIX_ATTRIBUTES) { dcr->dir_update_file_attributes(dcr->rec); } retval = true; bail_out: dcr->rec->data = rec_data; return retval; } /* * Read a record using the native routines. * * data_length == 0 = EOF */ static inline bool bndmp_read_data_from_block(JCR *jcr, char *data, uint32_t wanted_data_length, uint32_t *data_length) { DCR *dcr = jcr->read_dcr; READ_CTX *rctx = jcr->rctx; bool done = false; bool ok = true; if (!rctx) { return false; } while (!done) { /* * See if there are any records left to process. */ if (!is_block_empty(rctx->rec)) { if (!read_next_record_from_block(dcr, rctx, &done)) { /* * When the done flag is set to true we are done reading all * records or end of block read next block. */ continue; } } else { /* * Read the next block into our buffers. */ if (!read_next_block_from_device(dcr, &rctx->sessrec, NULL, mount_next_read_volume, &ok)) { return false; } /* * Get a new record for each Job as defined by VolSessionId and VolSessionTime */ if (!rctx->rec || rctx->rec->VolSessionId != dcr->block->VolSessionId || rctx->rec->VolSessionTime != dcr->block->VolSessionTime) { read_context_set_record(dcr, rctx); } rctx->records_processed = 0; rctx->rec->state_bits = 0; rctx->lastFileIndex = READ_NO_FILEINDEX; if (!read_next_record_from_block(dcr, rctx, &done)) { /* * When the done flag is set to true we are done reading all * records or end of block read next block. */ continue; } } /* * See if we are processing some sort of label? */ if (rctx->rec->FileIndex < 0) { continue; } /* * Here we should have read a record from the block which contains some data. * Its either: * * - STREAM_UNIX_ATTRIBUTES * Which is the start of the dump when we encounter that we just read the next record. * - STREAM_FILE_DATA * Normal NDMP data. * - STREAM_NDMP_SEPERATOR * End of NDMP data stream. * * anything other means a corrupted stream of records and means we give an EOF. */ switch (rctx->rec->maskedStream) { case STREAM_UNIX_ATTRIBUTES: continue; case STREAM_FILE_DATA: if (wanted_data_length < rctx->rec->data_len) { Jmsg0(jcr, M_FATAL, 0, _("Data read from volume bigger then NDMP databuffer, please increase the NDMP blocksize.\n")); return false; } memcpy(data, rctx->rec->data, rctx->rec->data_len); *data_length = rctx->rec->data_len; return true; case STREAM_NDMP_SEPERATOR: *data_length = 0; return true; default: Jmsg1(jcr, M_ERROR, 0, _("Encountered an unknown stream type %d\n"), rctx->rec->maskedStream); *data_length = 0; return true; } } if (done) { *data_length = 0; } return true; } /* * Generate virtual file attributes for the whole NDMP stream. */ static inline bool bndmp_create_virtual_file(JCR *jcr, char *filename) { DCR *dcr = jcr->dcr; struct stat statp; time_t now = time(NULL); POOL_MEM attribs(PM_NAME), data(PM_NAME); int32_t size; memset(&statp, 0, sizeof(statp)); statp.st_mode = 0700 | S_IFREG; statp.st_ctime = now; statp.st_mtime = now; statp.st_atime = now; statp.st_size = -1; statp.st_blksize = 4096; statp.st_blocks = 1; /* * Encode a stat structure into an ASCII string. */ encode_stat(attribs.c_str(), &statp, sizeof(statp), dcr->FileIndex, STREAM_UNIX_ATTRIBUTES); /* * Generate a file attributes stream. * File_index * File type * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK or FT_LNKSAVED) * Encoded extended-attributes (for Win32) * Delta Sequence Number */ size = Mmsg(data, "%ld %d %s%c%s%c%s%c%s%c%d%c", dcr->FileIndex, /* File_index */ FT_REG, /* File type */ filename, /* Filename (full path) */ 0, attribs.c_str(), /* Encoded attributes */ 0, "", /* Link name (if type==FT_LNK or FT_LNKSAVED) */ 0, "", /* Encoded extended-attributes (for Win32) */ 0, 0, /* Delta Sequence Number */ 0); return bndmp_write_data_to_block(jcr, STREAM_UNIX_ATTRIBUTES, data.c_str(), size); } static int bndmp_simu_flush_weof(struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; if (ta->weof_on_close) { /* best effort */ ndmos_tape_wfm (sess); } return 0; } /* * Search the JCRs for one with the given security key. */ static inline JCR *get_jcr_by_security_key(char *security_key) { JCR *jcr; foreach_jcr(jcr) { if (bstrcmp(jcr->sd_auth_key, security_key)) { jcr->inc_use_count(); break; } } endeach_jcr(jcr); return jcr; } extern "C" ndmp9_error bndmp_tape_open(struct ndm_session *sess, char *drive_name, int will_write) { JCR *jcr; DCR *dcr; char *filesystem; struct ndmp_session_handle *handle; struct ndm_tape_agent *ta; ndmp_backup_format_option *nbf_options; /* * The drive_name should be in the form @ */ if ((filesystem = strchr(drive_name, '@')) == NULL) { return NDMP9_NO_DEVICE_ERR; } /* * Lookup the jobid the drive_name should contain a valid authentication key. */ *filesystem++ = '\0'; if (!(jcr = get_jcr_by_security_key(drive_name))) { Jmsg1(NULL, M_FATAL, 0, _("NDMP tape open failed: Security Key not found: %s\n"), drive_name); return NDMP9_NO_DEVICE_ERR; } /* * When we found a JCR with the wanted security key it also implictly * means the authentication succeeded as the connecting NDMP session * only knows the exact security key as it was inserted by the director. */ jcr->authenticated = true; /* * There is a native storage daemon session waiting for the FD to connect. * In NDMP terms this is the same as a FD connecting so wake any waiting * threads. */ pthread_cond_signal(&jcr->job_start_wait); /* * Save the JCR to ndm_session binding so everything furher * knows which JCR belongs to which NDMP session. We have * a special ndmp_session_handle which we can use to track * session specific information. */ handle = (struct ndmp_session_handle *)sess->session_handle; /* * If we already have a JCR binding for this connection we release it here * as we are about to establish a new binding (e.g. second NDMP save for * the same job) and we should end up with the same binding. */ if (handle->jcr) { free_jcr(handle->jcr); } handle->jcr = jcr; /* * Keep track of the JCR for logging purposes. */ if (sess->param->log.ctx) { NIS *nis; nis = (NIS *)sess->param->log.ctx; nis->jcr = jcr; } /* * See if we know this backup format and get it options. */ nbf_options = lookup_backup_format_options(jcr->backup_format); /* * Depending on the open mode select the right DCR. */ if (will_write) { dcr = jcr->dcr; } else { dcr = jcr->read_dcr; } if (!dcr) { Jmsg0(jcr, M_FATAL, 0, _("DCR is NULL!!!\n")); return NDMP9_NO_DEVICE_ERR; } if (!dcr->dev) { Jmsg0(jcr, M_FATAL, 0, _("DEVICE is NULL!!!\n")); return NDMP9_NO_DEVICE_ERR; } /* * See if need to setup for write or read. */ if (will_write) { POOL_MEM virtual_filename(PM_FNAME); /* * Setup internal system for writing data. */ Dmsg1(100, "Start append data. res=%d\n", dcr->dev->num_reserved()); /* * One NDMP backup Job can be one or more save sessions so we keep * track if we already acquired the storage. */ if (!jcr->acquired_storage) { /* * Actually acquire the device which we reserved. */ if (!acquire_device_for_append(dcr)) { goto bail_out; } /* * Let any SD plugin know now its time to setup the record translation infra. */ if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { goto bail_out; } /* * Keep track that we acquired the storage. */ jcr->acquired_storage = true; Dmsg1(50, "Begin append device=%s\n", dcr->dev->print_name()); /* * Change the Job to running state. */ jcr->sendJobStatus(JS_Running); /* * As we only generate very limited attributes info e.g. one * set per NDMP backup stream we only setup data spooling and not * attribute spooling. */ if (!begin_data_spool(dcr) ) { goto bail_out; } /* * Write Begin Session Record */ if (!write_session_label(dcr, SOS_LABEL)) { Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"), dcr->dev->bstrerror()); goto bail_out; } dcr->VolFirstIndex = dcr->VolLastIndex = 0; jcr->run_time = time(NULL); /* start counting time for rates */ /* * The session is saved as one file stream. */ dcr->FileIndex = 1; jcr->JobFiles = 1; } else { /* * The next session is saved as one file stream. */ dcr->FileIndex++; jcr->JobFiles++; } /* * Create a virtual file name @NDMP/% or * @NDMP/ and save the attributes to the director. */ if (nbf_options && nbf_options->uses_level) { Mmsg(virtual_filename, "/@NDMP%s%%%d", filesystem, jcr->DumpLevel); } else { Mmsg(virtual_filename, "/@NDMP%s", filesystem); } if (!bndmp_create_virtual_file(jcr, virtual_filename.c_str())) { Jmsg0(jcr, M_FATAL, 0, _("Creating virtual file attributes failed.\n")); goto bail_out; } } else { bool ok = true; READ_CTX *rctx; /* * Setup internal system for reading data (if not done before). */ if (!jcr->acquired_storage) { Dmsg0(20, "Start read data.\n"); if (jcr->NumReadVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n")); goto bail_out; } Dmsg2(200, "Found %d volumes names to restore. First=%s\n", jcr->NumReadVolumes, jcr->VolList->VolumeName); /* * Ready device for reading */ if (!acquire_device_for_read(dcr)) { goto bail_out; } /* * Let any SD plugin know now its time to setup the record translation infra. */ if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { goto bail_out; } /* * Keep track that we acquired the storage. */ jcr->acquired_storage = true; /* * Change the Job to running state. */ jcr->sendJobStatus(JS_Running); Dmsg1(50, "Begin reading device=%s\n", dcr->dev->print_name()); position_device_to_first_file(jcr, dcr); jcr->mount_next_volume = false; /* * Allocate a new read context for this Job. */ rctx = new_read_context(); jcr->rctx = rctx; /* * Read the first block and setup record processing. */ if (!read_next_block_from_device(dcr, &rctx->sessrec, NULL, mount_next_read_volume, &ok)) { Jmsg1(jcr, M_FATAL, 0, _("Read session label failed. ERR=%s\n"), dcr->dev->bstrerror()); goto bail_out; } read_context_set_record(dcr, rctx); rctx->records_processed = 0; rctx->rec->state_bits = 0; rctx->lastFileIndex = READ_NO_FILEINDEX; } } /* * Setup NDMP states. */ ta = sess->tape_acb; ta->tape_fd = 0; /* fake filedescriptor */ bzero (&ta->tape_state, sizeof ta->tape_state); ta->tape_state.error = NDMP9_NO_ERR; ta->tape_state.state = NDMP9_TAPE_STATE_OPEN; ta->tape_state.open_mode = will_write ? NDMP9_TAPE_RDWR_MODE : NDMP9_TAPE_READ_MODE; ta->tape_state.file_num.valid = NDMP9_VALIDITY_VALID; ta->tape_state.soft_errors.valid = NDMP9_VALIDITY_VALID; ta->tape_state.block_size.valid = NDMP9_VALIDITY_VALID; ta->tape_state.blockno.valid = NDMP9_VALIDITY_VALID; ta->tape_state.total_space.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.space_remain.valid = NDMP9_VALIDITY_INVALID; return NDMP9_NO_ERR; bail_out: jcr->setJobStatus(JS_ErrorTerminated); return NDMP9_NO_DEVICE_ERR; } extern "C" ndmp9_error bndmp_tape_close(struct ndm_session *sess) { JCR *jcr; ndmp9_error err; struct ndmp_session_handle *handle; struct ndm_tape_agent *ta = sess->tape_acb; char ndmp_seperator[] = { "NdMpSePeRaToR" }; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } bndmp_simu_flush_weof(sess); /* * Setup the glue between the NDMP layer and the Storage Daemon. */ handle = (struct ndmp_session_handle *)sess->session_handle; jcr = handle->jcr; if (!jcr) { Jmsg0(NULL, M_FATAL, 0, _("JCR is NULL!!!\n")); return NDMP9_DEV_NOT_OPEN_ERR; } err = NDMP9_NO_ERR; if (NDMTA_TAPE_IS_WRITABLE(ta)) { /* * Write a seperator record so on restore we can recognize the different * NDMP datastreams from each other. */ if (!bndmp_write_data_to_block(jcr, STREAM_NDMP_SEPERATOR, ndmp_seperator, 13)) { err = NDMP9_IO_ERR; } } pthread_cond_signal(&jcr->job_end_wait); /* wake any waiting thread */ ta->tape_fd = -1; ndmos_tape_initialize(sess); return err; } extern "C" ndmp9_error bndmp_tape_mtio(struct ndm_session *sess, ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid) { struct ndm_tape_agent *ta = sess->tape_acb; *resid = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } /* * audit for valid op and for tape mode */ switch (op) { case NDMP9_MTIO_FSF: return NDMP9_NO_ERR; case NDMP9_MTIO_BSF: return NDMP9_NO_ERR; case NDMP9_MTIO_FSR: return NDMP9_NO_ERR; case NDMP9_MTIO_BSR: return NDMP9_NO_ERR; case NDMP9_MTIO_REW: bndmp_simu_flush_weof(sess); *resid = 0; ta->tape_state.file_num.value = 0; ta->tape_state.blockno.value = 0; break; case NDMP9_MTIO_OFF: return NDMP9_NO_ERR; case NDMP9_MTIO_EOF: /* should be "WFM" write-file-mark */ return NDMP9_NO_ERR; default: return NDMP9_ILLEGAL_ARGS_ERR; } return NDMP9_NO_ERR; } extern "C" ndmp9_error bndmp_tape_write(struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { JCR *jcr; ndmp9_error err; struct ndmp_session_handle *handle; struct ndm_tape_agent *ta = sess->tape_acb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } /* * Setup the glue between the NDMP layer and the Storage Daemon. */ handle = (struct ndmp_session_handle *)sess->session_handle; jcr = handle->jcr; if (!jcr) { Jmsg0(NULL, M_FATAL, 0, _("JCR is NULL!!!\n")); return NDMP9_DEV_NOT_OPEN_ERR; } /* * Turn the NDMP data into a internal record and save it. */ if (bndmp_write_data_to_block(jcr, STREAM_FILE_DATA, buf, count)) { ta->tape_state.blockno.value++; *done_count = count; err = NDMP9_NO_ERR; } else { jcr->setJobStatus(JS_ErrorTerminated); err = NDMP9_IO_ERR; } ta->weof_on_close = 1; return err; } extern "C" ndmp9_error bndmp_tape_wfm(struct ndm_session *sess) { ndmp9_error err; struct ndm_tape_agent *ta = sess->tape_acb; ta->weof_on_close = 0; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } if (!NDMTA_TAPE_IS_WRITABLE(ta)) { return NDMP9_PERMISSION_ERR; } err = NDMP9_NO_ERR; return err; } extern "C" ndmp9_error bndmp_tape_read(struct ndm_session *sess, char *buf, uint32_t count, uint32_t *done_count) { JCR *jcr; ndmp9_error err; struct ndmp_session_handle *handle; struct ndm_tape_agent *ta = sess->tape_acb; if (ta->tape_fd < 0) { return NDMP9_DEV_NOT_OPEN_ERR; } /* * Setup the glue between the NDMP layer and the Storage Daemon. */ handle = (struct ndmp_session_handle *)sess->session_handle; jcr = handle->jcr; if (!jcr) { Jmsg0(NULL, M_FATAL, 0, _("JCR is NULL!!!\n")); return NDMP9_DEV_NOT_OPEN_ERR; } if (bndmp_read_data_from_block(jcr, buf, count, done_count)) { ta->tape_state.blockno.value++; if (*done_count == 0) { err = NDMP9_EOF_ERR; } else { err = NDMP9_NO_ERR; } } else { jcr->setJobStatus(JS_ErrorTerminated); err = NDMP9_IO_ERR; } return err; } static inline void register_callback_hooks(struct ndm_session *sess) { struct ndm_auth_callbacks auth_callbacks; struct ndm_tape_simulator_callbacks tape_callbacks; /* * Register the authentication callbacks. */ auth_callbacks.validate_password = bndmp_auth_clear; auth_callbacks.validate_md5 = bndmp_auth_md5; ndmos_auth_register_callbacks(sess, &auth_callbacks); /* * Register the tape simulator callbacks. */ tape_callbacks.tape_open = bndmp_tape_open; tape_callbacks.tape_close = bndmp_tape_close; tape_callbacks.tape_mtio = bndmp_tape_mtio; tape_callbacks.tape_write = bndmp_tape_write; tape_callbacks.tape_wfm = bndmp_tape_wfm; tape_callbacks.tape_read = bndmp_tape_read; ndmos_tape_register_callbacks(sess, &tape_callbacks); } static inline void unregister_callback_hooks(struct ndm_session *sess) { ndmos_tape_unregister_callbacks(sess); ndmos_auth_unregister_callbacks(sess); } void end_of_ndmp_backup(JCR *jcr) { DCR *dcr = jcr->dcr; char ec[50]; /* * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits, * and the subsequent Jmsg() editing will break */ int32_t job_elapsed = time(NULL) - jcr->run_time; if (job_elapsed <= 0) { job_elapsed = 1; } Jmsg(jcr, M_INFO, 0, _("Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n"), job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60, edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec)); if (dcr) { /* * Check if we can still write. This may not be the case * if we are at the end of the tape or we got a fatal I/O error. */ if (dcr->dev && dcr->dev->can_write()) { Dmsg1(200, "Write EOS label JobStatus=%c\n", jcr->JobStatus); if (!write_session_label(dcr, EOS_LABEL)) { /* * Print only if JobStatus JS_Terminated and not cancelled to avoid spurious messages */ if (jcr->is_JobStatus(JS_Terminated) && !jcr->is_job_canceled()) { Jmsg1(jcr, M_FATAL, 0, _("Error writing end session label. ERR=%s\n"), dcr->dev->bstrerror()); } jcr->setJobStatus(JS_ErrorTerminated); } Dmsg0(90, "back from write_end_session_label()\n"); /* * Flush out final partial block of this session */ if (!dcr->write_block_to_device()) { /* * Print only if JobStatus JS_Terminated and not cancelled to avoid spurious messages */ if (jcr->is_JobStatus(JS_Terminated) && !jcr->is_job_canceled()) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dcr->dev->print_name(), dcr->dev->bstrerror()); } jcr->setJobStatus(JS_ErrorTerminated); } } if (jcr->is_JobStatus(JS_Terminated)) { /* * Note: if commit is OK, the device will remain blocked */ commit_data_spool(dcr); } else { discard_data_spool(dcr); } /* * Release the device -- and send final Vol info to DIR and unlock it. */ if (jcr->acquired_storage) { release_device(dcr); jcr->acquired_storage = false; } else { dcr->unreserve_device(); } } jcr->sendJobStatus(); /* update director */ } void end_of_ndmp_restore(JCR *jcr) { if (jcr->rctx) { free_read_context(jcr->rctx); jcr->rctx = NULL; } if (jcr->acquired_storage) { release_device(jcr->read_dcr); jcr->acquired_storage = false; } else { jcr->read_dcr->unreserve_device(); } } extern "C" void *handle_ndmp_client_request(void *arg) { int status; struct ndmconn *conn; struct ndm_session *sess; struct ndmp_session_handle *handle; NIS *nis; handle = (struct ndmp_session_handle *)arg; if (!handle) { Emsg0(M_ABORT, 0, _("Illegal call to handle_ndmp_client_request with NULL session handle\n")); return NULL; } /* * Initialize a new NDMP session */ sess = (struct ndm_session *)malloc(sizeof(struct ndm_session)); memset(sess, 0, sizeof(struct ndm_session)); sess->param = (struct ndm_session_param *)malloc(sizeof(struct ndm_session_param)); memset(sess->param, 0, sizeof(struct ndm_session_param)); sess->param->log.deliver = ndmp_loghandler; nis = (NIS *)malloc(sizeof(NIS)); sess->param->log.ctx = nis; sess->param->log_level = native_to_ndmp_loglevel(debug_level, nis); sess->param->log_tag = bstrdup("SD-NDMP"); register_callback_hooks(sess); /* * We duplicate some of the code from the ndma server session handling available * in the NDMJOB NDMP library e.g. we do not enter via ndma_daemon_session() * and then continue to ndma_server_session() which is the normal entry point * into the library as the ndma_daemon_session() function does things like creating * a listen socket, fork and accept the connection and the ndma_server_session() * function tries to get peername and socket names before eventually establishing * the NDMP connection. We already do all of that ourself via proven code * implemented in ndmp_thread_server which is calling us. */ /* * Make the ndm_session usable for a new connection e.g. initialize and commission. */ sess->tape_agent_enabled = 1; sess->data_agent_enabled = 1; status = ndma_session_initialize(sess); if (status) { Emsg0(M_ABORT, 0, _("Cannot initialize new NDMA session\n")); goto bail_out; } status = ndma_session_commission(sess); if (status) { Emsg0(M_ABORT, 0, _("Cannot commission new NDMA session\n")); goto bail_out; } conn = ndmconn_initialize(0, (char *)"#C"); if (!conn) { Emsg0(M_ABORT, 0, _("Cannot initialize new NDMA connection\n")); goto bail_out; } /* * Tell the lower levels which socket to use and setup snooping. */ ndmos_condition_control_socket(sess, handle->fd); if (me->ndmp_snooping) { ndmconn_set_snoop(conn, &sess->param->log, sess->param->log_level); } ndmconn_accept(conn, handle->fd); /* * Initialize some members now that we have a initialized NDMP connection. */ conn->call = ndma_call; conn->context = sess; sess->plumb.control = conn; sess->session_handle = handle; /* * This does the actual work e.g. run through the NDMP state machine. */ while (!conn->chan.eof) { ndma_session_quantum(sess, 1000); } /* * Tear down the NDMP connection. */ ndmconn_destruct(conn); ndma_session_decommission(sess); bail_out: unregister_callback_hooks(sess); free(sess->param->log.ctx); free(sess->param->log_tag); free(sess->param); free(sess); close(handle->fd); if (handle->jcr) { free_jcr(handle->jcr); } free(handle); return NULL; } /* * Create a seperate thread that accepts NDMP connections. * We don't use the Bareos native bnet_thread_server_tcp which * uses the bsock class which is a bit to much overhead * for simple sockets which we need and has all kinds of * extra features likes TLS and keep-alive support etc. * which wouldn't work for NDMP anyhow. * * So this is a bnet_thread_server_tcp put on a diet which * also contains the absolute minimum code needed to * have a robust connection handler. */ extern "C" void *ndmp_thread_server(void *arg) { struct ndmp_thread_server_args *ntsa; int new_sockfd, status; socklen_t clilen; struct sockaddr cli_addr; /* client's address */ int tlog, tmax; int turnon = 1; #ifdef HAVE_LIBWRAP struct request_info request; #endif IPADDR *ipaddr, *next; struct s_sockfd { dlink link; /* this MUST be the first item */ int fd; int port; } *fd_ptr = NULL; char buf[128]; alist sockfds(10, not_owned_by_alist); #ifdef HAVE_POLL nfds_t nfds; struct pollfd *pfds; #endif ntsa = (struct ndmp_thread_server_args *)arg; if (!ntsa) { return NULL; } /* * Remove any duplicate addresses. */ for (ipaddr = (IPADDR *)ntsa->addr_list->first(); ipaddr; ipaddr = (IPADDR *)ntsa->addr_list->next(ipaddr)) { for (next = (IPADDR *)ntsa->addr_list->next(ipaddr); next; next = (IPADDR *)ntsa->addr_list->next(next)) { if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() && memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(), ipaddr->get_sockaddr_len()) == 0) { ntsa->addr_list->remove(next); } } } char allbuf[256 * 10]; Dmsg1(100, "Addresses %s\n", build_addresses_str(ntsa->addr_list, allbuf, sizeof(allbuf))); #ifdef HAVE_POLL nfds = 0; #endif foreach_dlist(ipaddr, ntsa->addr_list) { /* * Allocate on stack from -- no need to free */ fd_ptr = (s_sockfd *)alloca(sizeof(s_sockfd)); fd_ptr->port = ipaddr->get_port_net_order(); /* * Open a TCP socket */ for (tlog= 60; (fd_ptr->fd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0; tlog -= 10) { if (tlog <= 0) { berrno be; char curbuf[256]; Emsg3(M_ABORT, 0, _("Cannot open stream socket. ERR=%s. Current %s All %s\n"), be.bstrerror(), ipaddr->build_address_str(curbuf, sizeof(curbuf)), build_addresses_str(ntsa->addr_list, allbuf, sizeof(allbuf))); } bmicrosleep(10, 0); } /* * Reuse old sockets */ if (setsockopt(fd_ptr->fd, SOL_SOCKET, SO_REUSEADDR, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { berrno be; Emsg1(M_WARNING, 0, _("Cannot set SO_REUSEADDR on socket: %s\n"), be.bstrerror()); } tmax = 30 * (60 / 5); /* wait 30 minutes max */ for (tlog = 0; bind(fd_ptr->fd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0; tlog -= 5) { berrno be; if (tlog <= 0) { tlog = 2 * 60; /* Complain every 2 minutes */ Emsg2(M_WARNING, 0, _("Cannot bind port %d: ERR=%s: Retrying ...\n"), ntohs(fd_ptr->port), be.bstrerror()); } bmicrosleep(5, 0); if (--tmax <= 0) { Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port), be.bstrerror()); } } listen(fd_ptr->fd, 50); /* tell system we are ready */ sockfds.append(fd_ptr); #ifdef HAVE_POLL nfds++; #endif } /* * Start work queue thread */ if ((status = workq_init(ntsa->client_wq, ntsa->max_clients, handle_ndmp_client_request)) != 0) { berrno be; be.set_errno(status); Emsg1(M_ABORT, 0, _("Could not init ndmp client queue: ERR=%s\n"), be.bstrerror()); } #ifdef HAVE_POLL /* * Allocate on stack from -- no need to free */ pfds = (struct pollfd *)alloca(sizeof(struct pollfd) * nfds); memset(pfds, 0, sizeof(struct pollfd) * nfds); nfds = 0; foreach_alist(fd_ptr, &sockfds) { pfds[nfds].fd = fd_ptr->fd; pfds[nfds].events |= POLL_IN; nfds++; } #endif /* * Wait for a connection from the client process. */ while (!quit) { #ifndef HAVE_POLL unsigned int maxfd = 0; fd_set sockset; FD_ZERO(&sockset); foreach_alist(fd_ptr, &sockfds) { FD_SET((unsigned)fd_ptr->fd, &sockset); maxfd = maxfd > (unsigned)fd_ptr->fd ? maxfd : fd_ptr->fd; } errno = 0; if ((status = select(maxfd + 1, &sockset, NULL, NULL, NULL)) < 0) { berrno be; /* capture errno */ if (errno == EINTR) { continue; } Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.bstrerror()); break; } foreach_alist(fd_ptr, &sockfds) { if (FD_ISSET(fd_ptr->fd, &sockset)) { #else int cnt; errno = 0; if ((status = poll(pfds, nfds, -1)) < 0) { berrno be; /* capture errno */ if (errno == EINTR) { continue; } Emsg1(M_FATAL, 0, _("Error in poll: %s\n"), be.bstrerror()); break; } cnt = 0; foreach_alist(fd_ptr, &sockfds) { if (pfds[cnt++].revents & POLLIN) { #endif /* * Got a connection, now accept it. */ do { clilen = sizeof(cli_addr); new_sockfd = accept(fd_ptr->fd, &cli_addr, &clilen); } while (new_sockfd < 0 && errno == EINTR); if (new_sockfd < 0) { continue; } #ifdef HAVE_LIBWRAP P(mutex); /* hosts_access is not thread safe */ request_init(&request, RQ_DAEMON, my_name, RQ_FILE, new_sockfd, 0); fromhost(&request); if (!hosts_access(&request)) { V(mutex); Jmsg2(NULL, M_SECURITY, 0, _("Connection from %s:%d refused by hosts.access\n"), sockaddr_to_ascii(&cli_addr, buf, sizeof(buf)), sockaddr_get_port(&cli_addr)); close(new_sockfd); continue; } V(mutex); #endif /* * Receive notification when connection dies. */ if (setsockopt(new_sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { berrno be; Emsg1(M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), be.bstrerror()); } /* * See who client is. i.e. who connected to us. */ P(mutex); sockaddr_to_ascii(&cli_addr, buf, sizeof(buf)); V(mutex); struct ndmp_session_handle *new_handle; new_handle = (struct ndmp_session_handle *)malloc(sizeof(struct ndmp_session_handle)); memset(new_handle, 0, sizeof(struct ndmp_session_handle)); new_handle->fd = new_sockfd; new_handle->host = bstrdup(buf); memset(&new_handle->peer_addr, 0, sizeof(new_handle->peer_addr)); memcpy(&new_handle->client_addr, &cli_addr, sizeof(new_handle->client_addr)); /* * Queue client to be served */ if ((status = workq_add(ntsa->client_wq, (void *)new_handle, NULL, 0)) != 0) { berrno be; be.set_errno(status); Jmsg1(NULL, M_ABORT, 0, _("Could not add job to ndmp client queue: ERR=%s\n"), be.bstrerror()); } } } } /* * Cleanup open files. */ fd_ptr = (s_sockfd *)sockfds.first(); while (fd_ptr) { close(fd_ptr->fd); fd_ptr = (s_sockfd *)sockfds.next(); } /* * Stop work queue thread */ if ((status = workq_destroy(ntsa->client_wq)) != 0) { berrno be; be.set_errno(status); Emsg1(M_FATAL, 0, _("Could not destroy ndmp client queue: ERR=%s\n"), be.bstrerror()); } return NULL; } int start_ndmp_thread_server(dlist *addr_list, int max_clients, workq_t *client_wq) { int status; ndmp_thread_server_args.addr_list = addr_list; ndmp_thread_server_args.max_clients = max_clients; ndmp_thread_server_args.client_wq = client_wq; if ((status = pthread_create(&ndmp_tid, NULL, ndmp_thread_server, (void *)&ndmp_thread_server_args)) != 0) { return status; } ndmp_initialized = true; return 0; } void stop_ndmp_thread_server() { if (!ndmp_initialized) { return; } quit = true; if (!pthread_equal(ndmp_tid, pthread_self())) { pthread_join(ndmp_tid, NULL); } } #else void end_of_ndmp_backup(JCR *jcr) { } void end_of_ndmp_restore(JCR *jcr) { } #endif /* HAVE_NDMP */ bareos-Release-14.2.6/src/stored/protos.h000066400000000000000000000256071263011562700202400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Protypes for stored -- Kern Sibbald MM */ /* stored.c */ uint32_t new_VolSessionId(); /* acquire.c */ DCR *acquire_device_for_append(DCR *dcr); bool acquire_device_for_read(DCR *dcr); bool release_device(DCR *dcr); bool clean_device(DCR *dcr); void setup_new_dcr_device(JCR *jcr, DCR *dcr, DEVICE *dev, BLOCKSIZES *blocksizes); void free_dcr(DCR *dcr); /* append.c */ bool do_append_data(JCR *jcr, BSOCK *bs, const char *what); bool send_attrs_to_dir(JCR *jcr, DEV_RECORD *rec); /* authenticate.c */ bool authenticate_director(JCR *jcr); bool authenticate_storagedaemon(JCR *jcr); bool authenticate_with_storagedaemon(JCR *jcr); bool authenticate_filedaemon(JCR *jcr); bool authenticate_with_filedaemon(JCR *jcr); /* autochanger.c */ bool init_autochangers(); int autoload_device(DCR *dcr, int writing, BSOCK *dir); bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd); bool autochanger_transfer_cmd(DCR *dcr, BSOCK *dir, int src_slot, int dst_slot); bool unload_autochanger(DCR *dcr, int loaded); bool unload_dev(DCR *dcr, DEVICE *dev); int get_autochanger_loaded_slot(DCR *dcr); /* block.c */ void dump_block(DEV_BLOCK *b, const char *msg); DEV_BLOCK *new_block(DEVICE *dev); DEV_BLOCK *dup_block(DEV_BLOCK *eblock); void init_block_write(DEV_BLOCK *block); void empty_block(DEV_BLOCK *block); void free_block(DEV_BLOCK *block); void print_block_read_errors(JCR *jcr, DEV_BLOCK *block); void ser_block_header(DEV_BLOCK *block); /* butil.c -- utilities for SD tool programs */ void print_ls_output(const char *fname, const char *link, int type, struct stat *statp); JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr, DIRRES *director, DCR* dcr, const char *VolumeName, bool readonly); void display_tape_error_status(JCR *jcr, DEVICE *dev); /* crc32.c */ uint32_t bcrc32(uint8_t *buf, int len); /* dev.c */ DEVICE *init_dev(JCR *jcr, DEVRES *device); bool can_open_mounted_dev(DEVICE *dev); bool load_dev(DEVICE *dev); int write_block(DEVICE *dev); void attach_jcr_to_device(DEVICE *dev, JCR *jcr); void detach_jcr_from_device(DEVICE *dev, JCR *jcr); JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); void init_device_wait_timers(DCR *dcr); void init_jcr_device_wait_timers(JCR *jcr); bool double_dev_wait_time(DEVICE *dev); /* device.c */ bool open_device(DCR *dcr); bool first_open_device(DCR *dcr); bool fixup_device_block_write_error(DCR *dcr, int retries = 4); void set_start_vol_position(DCR *dcr); void set_new_volume_parameters(DCR *dcr); void set_new_file_parameters(DCR *dcr); BSR *position_device_to_first_file(JCR *jcr, DCR *dcr); bool try_device_repositioning(JCR *jcr, DEV_RECORD *rec, DCR *dcr); /* dircmd.c */ void *handle_connection_request(void *arg); /* fd_cmds.c */ void *handle_filed_connection(BSOCK *fd, char *job_name); void run_job(JCR *jcr); void do_fd_commands(JCR *jcr); /* job.c */ void stored_free_jcr(JCR *jcr); /* label.c */ int read_dev_volume_label(DCR *dcr); void create_session_label(DCR *dcr, DEV_RECORD *rec, int label); void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName); #define ANSI_VOL_LABEL 0 #define ANSI_EOF_LABEL 1 #define ANSI_EOV_LABEL 2 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName); int read_ansi_ibm_label(DCR *dcr); bool write_session_label(DCR *dcr, int label); void dump_volume_label(DEVICE *dev); void dump_label_record(DEVICE *dev, DEV_RECORD *rec, bool verbose); bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec); bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName, bool relabel); /* locks.c */ void _lock_device(const char *file, int line, DEVICE *dev); void _unlock_device(const char *file, int line, DEVICE *dev); void _block_device(const char *file, int line, DEVICE *dev, int state); void _unblock_device(const char *file, int line, DEVICE *dev); void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state); void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold); /* match_bsr.c */ int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sesrec, JCR *jcr); int match_bsr_block(BSR *bsr, DEV_BLOCK *block); void position_bsr_block(BSR *bsr, DEV_BLOCK *block); BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev); bool is_this_bsr_done(BSR *bsr, DEV_RECORD *rec); uint64_t get_bsr_start_addr(BSR *bsr, uint32_t *file = NULL, uint32_t *block = NULL); /* mount.c */ bool mount_next_read_volume(DCR *dcr); /* ndmp_tape.c */ void end_of_ndmp_backup(JCR *jcr); void end_of_ndmp_restore(JCR *jcr); int start_ndmp_thread_server(dlist *addr_list, int max_clients, workq_t *client_wq); void stop_ndmp_thread_server(); /* parse_bsr.c */ BSR *parse_bsr(JCR *jcr, char *lf); void dump_bsr(BSR *bsr, bool recurse); void free_bsr(BSR *bsr); void free_restore_volume_list(JCR *jcr); void create_restore_volume_list(JCR *jcr); /* status.c */ bool status_cmd(JCR *jcr); bool dotstatus_cmd(JCR *jcr); #if defined(HAVE_WIN32) char *bareos_status(char *buf, int buf_len); #endif /* read.c */ bool do_read_data(JCR *jcr); /* read_record.c */ READ_CTX *new_read_context(void); void free_read_context(READ_CTX *rctx); void read_context_set_record(DCR *dcr, READ_CTX *rctx); bool read_next_block_from_device(DCR *dcr, SESSION_LABEL *sessrec, bool record_cb(DCR *dcr, DEV_RECORD *rec), bool mount_cb(DCR *dcr), bool *status); bool read_next_record_from_block(DCR *dcr, READ_CTX *rctx, bool *done); bool read_records(DCR *dcr, bool record_cb(DCR *dcr, DEV_RECORD *rec), bool mount_cb(DCR *dcr)); /* record.c */ const char *FI_to_ascii(char *buf, int fi); const char *stream_to_ascii(char *buf, int stream, int fi); bool write_record_to_block(DCR *dcr, DEV_RECORD *rec); bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); bool read_record_from_block(DCR *dcr, DEV_RECORD *rec); DEV_RECORD *new_record(bool with_data = true); void empty_record(DEV_RECORD *rec); void copy_record_state(DEV_RECORD *dst, DEV_RECORD *src); void free_record(DEV_RECORD *rec); uint64_t get_record_address(DEV_RECORD *rec); /* reserve.c */ void init_reservations_lock(); void term_reservations_lock(); void _lock_reservations(const char *file = "**Unknown**", int line = 0); void _unlock_reservations(); void _lock_volumes(const char *file = "**Unknown**", int line = 0); void _unlock_volumes(); void unreserve_device(DCR *dcr); void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg); bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx); int search_res_for_device(RCTX &rctx); void release_reserve_messages(JCR *jcr); extern int reservations_lock_count; #ifdef SD_DEBUG_LOCK #define lock_reservations() \ do { Dmsg3(sd_dbglvl, "lock_reservations at %s:%d precnt=%d\n", \ __FILE__, __LINE__, \ reservations_lock_count); \ _lock_reservations(__FILE__, __LINE__); \ Dmsg0(sd_dbglvl, "lock_reservations: got lock\n"); \ } while (0) #define unlock_reservations() \ do { Dmsg3(sd_dbglvl, "unlock_reservations at %s:%d precnt=%d\n", \ __FILE__, __LINE__, \ reservations_lock_count); \ _unlock_reservations(); } while (0) #define lock_volumes() \ do { Dmsg3(sd_dbglvl, "lock_volumes at %s:%d precnt=%d\n", \ __FILE__, __LINE__, \ vol_list_lock_count); \ _lock_volumes(__FILE__, __LINE__); \ Dmsg0(sd_dbglvl, "lock_volumes: got lock\n"); \ } while (0) #define unlock_volumes() \ do { Dmsg3(sd_dbglvl, "unlock_volumes at %s:%d precnt=%d\n", \ __FILE__, __LINE__, \ vol_list_lock_count); \ _unlock_volumes(); } while (0) #else #define lock_reservations() _lock_reservations(__FILE__, __LINE__) #define unlock_reservations() _unlock_reservations() #define lock_volumes() _lock_volumes(__FILE__, __LINE__) #define unlock_volumes() _unlock_volumes() #endif /* sd_backends.c */ #if defined(HAVE_DYNAMIC_SD_BACKENDS) void sd_set_backend_dirs(alist *new_backend_dirs); DEVICE *init_backend_dev(JCR *jcr, int device_type); void dev_flush_backends(); #endif /* sd_cmds.c */ void *handle_stored_connection(BSOCK *sd, char *job_name); bool do_listen_run(JCR *jcr); /* sd_plugins.c */ char *edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd); /* sd_stats.c */ int start_statistics_thread(void); void stop_statistics_thread(); void update_device_tapealert(const char *devname, uint64_t flags, utime_t now); void update_job_statistics(JCR *jcr, utime_t now); /* spool.c */ bool begin_data_spool (DCR *dcr); bool discard_data_spool (DCR *dcr); bool commit_data_spool (DCR *dcr); bool are_attributes_spooled (JCR *jcr); bool begin_attribute_spool (JCR *jcr); bool discard_attribute_spool (JCR *jcr); bool commit_attribute_spool (JCR *jcr); bool write_block_to_spool_file (DCR *dcr); void list_spool_stats (void sendit(const char *msg, int len, void *sarg), void *arg); /* vol_mgr.c */ void init_vol_list_lock(); void term_vol_list_lock(); VOLRES *reserve_volume(DCR *dcr, const char *VolumeName); bool free_volume(DEVICE *dev); bool is_vol_list_empty(); dlist *dup_vol_list(JCR *jcr); void free_temp_vol_list(dlist *temp_vol_list); bool volume_unused(DCR *dcr); void create_volume_lists(); void free_volume_lists(); void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg); bool is_volume_in_use(DCR *dcr); extern int vol_list_lock_count; void add_read_volume(JCR *jcr, const char *VolumeName); void remove_read_volume(JCR *jcr, const char *VolumeName); /* wait.c */ int wait_for_sysop(DCR *dcr); bool wait_for_device(JCR *jcr, int &retries); void release_device_cond(); bareos-Release-14.2.6/src/stored/read.c000066400000000000000000000103521263011562700176070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Read code for Storage daemon * * Kern Sibbald, November MM */ #include "bareos.h" #include "stored.h" /* Forward referenced subroutines */ static bool record_cb(DCR *dcr, DEV_RECORD *rec); /* Responses sent to the File daemon */ static char OK_data[] = "3000 OK data\n"; static char FD_error[] = "3000 error\n"; static char rec_header[] = "rechdr %ld %ld %ld %ld %ld"; /* * Read Data and send to File Daemon * * Returns: false on failure * true on success */ bool do_read_data(JCR *jcr) { BSOCK *fd = jcr->file_bsock; DCR *dcr = jcr->read_dcr; bool ok = true; Dmsg0(20, "Start read data.\n"); if (!bnet_set_buffer_size(fd, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) { return false; } if (jcr->NumReadVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n")); fd->fsend(FD_error); return false; } Dmsg2(200, "Found %d volumes names to restore. First=%s\n", jcr->NumReadVolumes, jcr->VolList->VolumeName); /* * Ready device for reading */ if (!acquire_device_for_read(dcr)) { fd->fsend(FD_error); return false; } /* * Let any SD plugin know now its time to setup the record translation infra. */ if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) { jcr->setJobStatus(JS_ErrorTerminated); return false; } /* * Tell File daemon we will send data */ fd->fsend(OK_data); jcr->sendJobStatus(JS_Running); ok = read_records(dcr, record_cb, mount_next_read_volume); /* * Send end of data to FD */ fd->signal(BNET_EOD); if (!release_device(jcr->read_dcr)) { ok = false; } Dmsg0(30, "Done reading.\n"); return ok; } /* * Called here for each record from read_records() * * Returns: true if OK * false if error */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { JCR *jcr = dcr->jcr; BSOCK *fd = jcr->file_bsock; bool ok = true; POOLMEM *save_msg; char ec1[50], ec2[50]; if (rec->FileIndex < 0) { return true; } Dmsg5(400, "Send to FD: SessId=%u SessTim=%u FI=%s Strm=%s, len=%d\n", rec->VolSessionId, rec->VolSessionTime, FI_to_ascii(ec1, rec->FileIndex), stream_to_ascii(ec2, rec->Stream, rec->FileIndex), rec->data_len); /* * Send record header to File daemon */ if (!fd->fsend(rec_header, rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, rec->Stream, rec->data_len)) { Pmsg1(000, _(">filed: Error Hdr=%s"), fd->msg); Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), fd->bstrerror()); return false; } else { Dmsg1(400, ">filed: Hdr=%s", fd->msg); } /* * Send data record to File daemon */ save_msg = fd->msg; /* save fd message pointer */ fd->msg = rec->data; /* pass data directly to the FD */ fd->msglen = rec->data_len; Dmsg1(400, ">filed: send %d bytes data.\n", fd->msglen); if (!fd->send()) { Pmsg1(000, _("Error sending to FD. ERR=%s\n"), fd->bstrerror()); Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), fd->bstrerror()); ok = false; } fd->msg = save_msg; /* restore fd message pointer */ return ok; } bareos-Release-14.2.6/src/stored/read_record.c000066400000000000000000000414041263011562700211470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2002-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file provides routines that will handle all * the gory little details of reading a record from a Bareos * archive. It uses a callback to pass you each record in turn, * as well as a callback for mounting the next tape. It takes * care of reading blocks, applying the bsr, ... * * Note, this routine is really the heart of the restore routines, * and we are *really* bit pushing here so be careful about making * any modifications. * * Kern E. Sibbald, August MMII */ #include "bareos.h" #include "stored.h" /* Forward referenced functions */ static const int dbglvl = 500; static void handle_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec) { const char *rtype; char buf[100]; memset(sessrec, 0, sizeof(SESSION_LABEL)); switch (rec->FileIndex) { case PRE_LABEL: rtype = _("Fresh Volume Label"); break; case VOL_LABEL: rtype = _("Volume Label"); unser_volume_label(dev, rec); break; case SOS_LABEL: rtype = _("Begin Session"); unser_session_label(sessrec, rec); break; case EOS_LABEL: rtype = _("End Session"); break; case EOM_LABEL: rtype = _("End of Media"); break; default: bsnprintf(buf, sizeof(buf), _("Unknown code %d\n"), rec->FileIndex); rtype = buf; break; } Dmsg5(dbglvl, _("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n"), rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); } static char *rec_state_bits_to_str(DEV_RECORD *rec) { static char buf[200]; buf[0] = 0; if (rec->state_bits & REC_NO_HEADER) { bstrncat(buf, "Nohdr,", sizeof(buf)); } if (is_partial_record(rec)) { bstrncat(buf, "partial,", sizeof(buf)); } if (rec->state_bits & REC_BLOCK_EMPTY) { bstrncat(buf, "empty,", sizeof(buf)); } if (rec->state_bits & REC_NO_MATCH) { bstrncat(buf, "Nomatch,", sizeof(buf)); } if (rec->state_bits & REC_CONTINUATION) { bstrncat(buf, "cont,", sizeof(buf)); } if (buf[0]) { buf[strlen(buf)-1] = 0; } return buf; } /* * Allocate a new read context which will contains accumulated data from a read session. */ READ_CTX *new_read_context(void) { DEV_RECORD *rec = NULL; READ_CTX *rctx; rctx = (READ_CTX *)malloc(sizeof(READ_CTX)); memset(rctx, 0, sizeof(READ_CTX)); rctx->recs = New(dlist(rec, &rec->link)); return rctx; } /* * Free a read context which contains accumulated data from a read session. */ void free_read_context(READ_CTX *rctx) { DEV_RECORD *rec; /* * Walk down list and free all remaining allocated recs */ while (!rctx->recs->empty()) { rec = (DEV_RECORD *)rctx->recs->first(); rctx->recs->remove(rec); free_record(rec); } delete rctx->recs; free(rctx); } /* * Setup the record pointer in the Read Context. * Reuse an already existing record when available in the linked * list or allocate a fresh one and prepend it in the linked list. */ void read_context_set_record(DCR *dcr, READ_CTX *rctx) { DEV_RECORD *rec; bool found = false; foreach_dlist(rec, rctx->recs) { if (rec->VolSessionId == dcr->block->VolSessionId && rec->VolSessionTime == dcr->block->VolSessionTime) { found = true; break; } } if (!found) { rec = new_record(); rctx->recs->prepend(rec); Dmsg3(dbglvl, "New record for state=%s SI=%d ST=%d\n", rec_state_bits_to_str(rec), dcr->block->VolSessionId, dcr->block->VolSessionTime); } rctx->rec = rec; } /* * Read the next block from the device and handle any volume * switches etc. * * Returns: true on success * false on error * * Any fatal error sets the status bool to false. */ bool read_next_block_from_device(DCR *dcr, SESSION_LABEL *sessrec, bool record_cb(DCR *dcr, DEV_RECORD *rec), bool mount_cb(DCR *dcr), bool *status) { JCR *jcr = dcr->jcr; DEV_RECORD *trec; while (1) { if (!dcr->read_block_from_device(CHECK_BLOCK_NUMBERS)) { if (dcr->dev->at_eot()) { Jmsg(jcr, M_INFO, 0, _("End of Volume at file %u on device %s, Volume \"%s\"\n"), dcr->dev->file, dcr->dev->print_name(), dcr->VolumeName); volume_unused(dcr); /* mark volume unused */ if (!mount_cb(dcr)) { Jmsg(jcr, M_INFO, 0, _("End of all volumes.\n")); if (record_cb) { /* * Create EOT Label so that Media record may * be properly updated because this is the last * tape. */ trec = new_record(); trec->FileIndex = EOT_LABEL; trec->File = dcr->dev->file; *status = record_cb(dcr, trec); if (jcr->mount_next_volume) { jcr->mount_next_volume = false; dcr->dev->clear_eot(); } free_record(trec); } return false; } jcr->mount_next_volume = false; /* * We just have a new tape up, now read the label (first record) * and pass it off to the callback routine, then continue * most likely reading the previous record. */ dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK); trec = new_record(); read_record_from_block(dcr, trec); handle_session_record(dcr->dev, trec, sessrec); if (record_cb) { record_cb(dcr, trec); } free_record(trec); position_device_to_first_file(jcr, dcr); /* * After reading label, we must read first data block */ continue; } else if (dcr->dev->at_eof()) { Dmsg3(200, "End of file %u on device %s, Volume \"%s\"\n", dcr->dev->file, dcr->dev->print_name(), dcr->VolumeName); continue; } else if (dcr->dev->is_short_block()) { Jmsg1(jcr, M_ERROR, 0, "%s", dcr->dev->errmsg); continue; } else { /* * I/O error or strange end of tape */ display_tape_error_status(jcr, dcr->dev); if (forge_on || jcr->ignore_label_errors) { dcr->dev->fsr(1); /* try skipping bad record */ Pmsg0(000, _("Did fsr in attemp to skip bad record.\n")); continue; } *status = false; return false; } } Dmsg2(dbglvl, "Read new block at pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num); return true; } } /* * Read the next record from a block. * * Returns: true on continue processing. * false on error or when done with this block. * * When we are done processing all records the done bool is set to true. */ bool read_next_record_from_block(DCR *dcr, READ_CTX *rctx, bool *done) { JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; DEV_BLOCK *block = dcr->block; DEV_RECORD *rec = rctx->rec; while (1) { if (!read_record_from_block(dcr, rec)) { Dmsg3(400, "!read-break. state_bits=%s blk=%d rem=%d\n", rec_state_bits_to_str(rec), block->BlockNumber, rec->remainder); return false; } Dmsg5(dbglvl, "read-OK. state_bits=%s blk=%d rem=%d file:block=%u:%u\n", rec_state_bits_to_str(rec), block->BlockNumber, rec->remainder, dev->file, dev->block_num); /* * At this point, we have at least a record header. * Now decide if we want this record or not, but remember * before accessing the record, we may need to read again to * get all the data. */ rctx->records_processed++; Dmsg6(dbglvl, "recno=%d state_bits=%s blk=%d SI=%d ST=%d FI=%d\n", rctx->records_processed, rec_state_bits_to_str(rec), block->BlockNumber, rec->VolSessionId, rec->VolSessionTime, rec->FileIndex); if (rec->FileIndex == EOM_LABEL) { /* end of tape? */ Dmsg0(40, "Get EOM LABEL\n"); return false; } /* * Some sort of label? */ if (rec->FileIndex < 0) { handle_session_record(dcr->dev, rec, &rctx->sessrec); if (jcr->bsr) { /* * We just check block FI and FT not FileIndex */ rec->match_stat = match_bsr_block(jcr->bsr, dcr->block); } else { rec->match_stat = 0; } return true; } /* * Apply BSR filter */ if (jcr->bsr) { rec->match_stat = match_bsr(jcr->bsr, rec, &dev->VolHdr, &rctx->sessrec, jcr); if (rec->match_stat == -1) { /* no more possible matches */ *done = true; /* all items found, stop */ Dmsg2(dbglvl, "All done=(file:block) %u:%u\n", dev->file, dev->block_num); return false; } else if (rec->match_stat == 0) { /* no match */ Dmsg4(dbglvl, "BSR no match: clear rem=%d FI=%d before set_eof pos %u:%u\n", rec->remainder, rec->FileIndex, dev->file, dev->block_num); rec->remainder = 0; rec->state_bits &= ~REC_PARTIAL_RECORD; if (try_device_repositioning(jcr, rec, dcr)) { return false; } continue; /* we don't want record, read next one */ } } dcr->VolLastIndex = rec->FileIndex; /* let caller know where we are */ if (is_partial_record(rec)) { Dmsg6(dbglvl, "Partial, break. recno=%d state_bits=%s blk=%d SI=%d ST=%d FI=%d\n", rctx->records_processed, rec_state_bits_to_str(rec), block->BlockNumber, rec->VolSessionId, rec->VolSessionTime, rec->FileIndex); return false; /* read second part of record */ } if (rctx->lastFileIndex != READ_NO_FILEINDEX && rctx->lastFileIndex != rec->FileIndex) { if (is_this_bsr_done(jcr->bsr, rec) && try_device_repositioning(jcr, rec, dcr)) { Dmsg2(dbglvl, "This bsr done, break pos %u:%u\n", dev->file, dev->block_num); return false; } Dmsg2(dbglvl, "==== inside LastIndex=%d FileIndex=%d\n", rctx->lastFileIndex, rec->FileIndex); } Dmsg2(dbglvl, "==== LastIndex=%d FileIndex=%d\n", rctx->lastFileIndex, rec->FileIndex); rctx->lastFileIndex = rec->FileIndex; return true; } } /* * This subroutine reads all the records and passes them back to your * callback routine (also mount routine at EOM). * * You must not change any values in the DEV_RECORD packet */ bool read_records(DCR *dcr, bool record_cb(DCR *dcr, DEV_RECORD *rec), bool mount_cb(DCR *dcr)) { JCR *jcr = dcr->jcr; READ_CTX *rctx; bool ok = true; bool done = false; rctx = new_read_context(); position_device_to_first_file(jcr, dcr); jcr->mount_next_volume = false; while (ok && !done) { if (job_canceled(jcr)) { ok = false; break; } /* * Read the next block into our buffers. */ if (!read_next_block_from_device(dcr, &rctx->sessrec, record_cb, mount_cb, &ok)) { break; } #ifdef if_and_when_FAST_BLOCK_REJECTION_is_working /* * This does not stop when file/block are too big */ if (!match_bsr_block(jcr->bsr, block)) { if (try_device_repositioning(jcr, rctx->rec, dcr)) { break; /* get next volume */ } continue; /* skip this record */ } #endif /* * Get a new record for each Job as defined by VolSessionId and VolSessionTime */ if (!rctx->rec || rctx->rec->VolSessionId != dcr->block->VolSessionId || rctx->rec->VolSessionTime != dcr->block->VolSessionTime) { read_context_set_record(dcr, rctx); } Dmsg3(dbglvl, "Before read rec loop. stat=%s blk=%d rem=%d\n", rec_state_bits_to_str(rctx->rec), dcr->block->BlockNumber, rctx->rec->remainder); rctx->records_processed = 0; rctx->rec->state_bits = 0; rctx->lastFileIndex = READ_NO_FILEINDEX; Dmsg1(dbglvl, "Block %s empty\n", is_block_empty(rctx->rec) ? "is" : "NOT"); /* * Process the block and read all records in the block and send * them to the defined callback. */ rctx->rec->state_bits = 0; while (ok && !is_block_empty(rctx->rec)) { if (!read_next_record_from_block(dcr, rctx, &done)) { break; } if (rctx->rec->FileIndex < 0) { /* * Note, we pass *all* labels to the callback routine. If * he wants to know if they matched the bsr, then he must * check the match_stat in the record */ ok = record_cb(dcr, rctx->rec); } else { DEV_RECORD *rec; Dmsg6(dbglvl, "OK callback. recno=%d state_bits=%s blk=%d SI=%d ST=%d FI=%d\n", rctx->records_processed, rec_state_bits_to_str(rctx->rec), dcr->block->BlockNumber, rctx->rec->VolSessionId, rctx->rec->VolSessionTime, rctx->rec->FileIndex); /* * Perform record translations. */ dcr->before_rec = rctx->rec; dcr->after_rec = NULL; /* * We want the plugins to be called in reverse order so we give the generate_plugin_event() * the reverse argument so it knows that we want the plugins to be called in that order. */ if (generate_plugin_event(jcr, bsdEventReadRecordTranslation, dcr, true) != bRC_OK) { ok = false; continue; } /* * The record got translated when we got an after_rec pointer after calling the * bsdEventReadRecordTranslation plugin event. If no translation has taken place * we just point the rec pointer to same DEV_RECORD as in the before_rec pointer. */ rec = (dcr->after_rec) ? dcr->after_rec : dcr->before_rec; ok = record_cb(dcr, rec); #if 0 /* * If we have a digest stream, we check to see if we have * finished the current bsr, and if so, repositioning will * be turned on. */ if (crypto_digest_stream_type(rec->Stream) != CRYPTO_DIGEST_NONE) { Dmsg3(dbglvl, "=== Have digest FI=%u before bsr check pos %u:%u\n", rec->FileIndex, dev->file, dev->block_num); if (is_this_bsr_done(jcr->bsr, rec) && try_repositioning(jcr, rec, dcr)) { Dmsg1(dbglvl, "==== BSR done at FI=%d\n", rec->FileIndex); Dmsg2(dbglvl, "This bsr done, break pos %u:%u\n", dev->file, dev->block_num); break; } Dmsg2(900, "After is_bsr_done pos %u:%u\n", dev->file, dev->block_num); } #endif /* * We can just release the translated record here as the record may not be * changed by the record callback so any changes made don't need to be copied * back to the original DEV_RECORD. */ if (dcr->after_rec) { free_record(dcr->after_rec); dcr->after_rec = NULL; } } } Dmsg2(dbglvl, "After end recs in block. pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num); } // Dmsg2(dbglvl, "Position=(file:block) %u:%u\n", dcr->dev->file, dcr->dev->block_num); free_read_context(rctx); print_block_read_errors(jcr, dcr->block); return ok; } bareos-Release-14.2.6/src/stored/record.c000066400000000000000000000602021263011562700201510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * record.c -- Volume (tape/disk) record handling functions * * Kern Sibbald, April MMI * added BB02 format October MMII */ #include "bareos.h" #include "stored.h" /* * Convert a FileIndex into a printable * ASCII string. Not reentrant. * If the FileIndex is negative, it flags the * record as a Label, otherwise it is simply * the FileIndex of the current file. */ const char *FI_to_ascii(char *buf, int fi) { if (fi >= 0) { sprintf(buf, "%d", fi); return buf; } switch (fi) { case PRE_LABEL: return "PRE_LABEL"; case VOL_LABEL: return "VOL_LABEL"; case EOM_LABEL: return "EOM_LABEL"; case SOS_LABEL: return "SOS_LABEL"; case EOS_LABEL: return "EOS_LABEL"; case EOT_LABEL: return "EOT_LABEL"; break; case SOB_LABEL: return "SOB_LABEL"; break; case EOB_LABEL: return "EOB_LABEL"; break; default: sprintf(buf, _("unknown: %d"), fi); return buf; } } /* * Convert a Stream ID into a printable * ASCII string. Not reentrant. * A negative stream number represents * stream data that is continued from a * record in the previous block. * If the FileIndex is negative, we are * dealing with a Label, hence the * stream is the JobId. */ const char *stream_to_ascii(char *buf, int stream, int fi) { if (fi < 0) { sprintf(buf, "%d", stream); return buf; } if (stream < 0) { stream = -stream; stream &= STREAMMASK_TYPE; /* Stream was negative => all are continuation items */ switch (stream) { case STREAM_UNIX_ATTRIBUTES: return "contUATTR"; case STREAM_FILE_DATA: return "contDATA"; case STREAM_WIN32_DATA: return "contWIN32-DATA"; case STREAM_WIN32_GZIP_DATA: return "contWIN32-GZIP"; case STREAM_WIN32_COMPRESSED_DATA: return "contWIN32-COMPRESSED"; case STREAM_MD5_DIGEST: return "contMD5"; case STREAM_SHA1_DIGEST: return "contSHA1"; case STREAM_GZIP_DATA: return "contGZIP"; case STREAM_COMPRESSED_DATA: return "contCOMPRESSED"; case STREAM_UNIX_ATTRIBUTES_EX: return "contUNIX-ATTR-EX"; case STREAM_RESTORE_OBJECT: return "contRESTORE-OBJECT"; case STREAM_SPARSE_DATA: return "contSPARSE-DATA"; case STREAM_SPARSE_GZIP_DATA: return "contSPARSE-GZIP"; case STREAM_SPARSE_COMPRESSED_DATA: return "contSPARSE-COMPRESSED"; case STREAM_PROGRAM_NAMES: return "contPROG-NAMES"; case STREAM_PROGRAM_DATA: return "contPROG-DATA"; case STREAM_MACOS_FORK_DATA: return "contMACOS-RSRC"; case STREAM_HFSPLUS_ATTRIBUTES: return "contHFSPLUS-ATTR"; case STREAM_SHA256_DIGEST: return "contSHA256"; case STREAM_SHA512_DIGEST: return "contSHA512"; case STREAM_SIGNED_DIGEST: return "contSIGNED-DIGEST"; case STREAM_ENCRYPTED_SESSION_DATA: return "contENCRYPTED-SESSION-DATA"; case STREAM_ENCRYPTED_FILE_DATA: return "contENCRYPTED-FILE"; case STREAM_ENCRYPTED_FILE_GZIP_DATA: return "contENCRYPTED-GZIP"; case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: return "contENCRYPTED-COMPRESSED"; case STREAM_ENCRYPTED_WIN32_DATA: return "contENCRYPTED-WIN32-DATA"; case STREAM_ENCRYPTED_WIN32_GZIP_DATA: return "contENCRYPTED-WIN32-GZIP"; case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: return "contENCRYPTED-WIN32-COMPRESSED"; case STREAM_ENCRYPTED_MACOS_FORK_DATA: return "contENCRYPTED-MACOS-RSRC"; case STREAM_PLUGIN_NAME: return "contPLUGIN-NAME"; default: sprintf(buf, "%d", -stream); return buf; } } switch (stream & STREAMMASK_TYPE) { case STREAM_UNIX_ATTRIBUTES: return "UATTR"; case STREAM_FILE_DATA: return "DATA"; case STREAM_WIN32_DATA: return "WIN32-DATA"; case STREAM_WIN32_GZIP_DATA: return "WIN32-GZIP"; case STREAM_WIN32_COMPRESSED_DATA: return "WIN32-COMPRESSED"; case STREAM_MD5_DIGEST: return "MD5"; case STREAM_SHA1_DIGEST: return "SHA1"; case STREAM_GZIP_DATA: return "GZIP"; case STREAM_COMPRESSED_DATA: return "COMPRESSED"; case STREAM_UNIX_ATTRIBUTES_EX: return "UNIX-ATTR-EX"; case STREAM_RESTORE_OBJECT: return "RESTORE-OBJECT"; case STREAM_SPARSE_DATA: return "SPARSE-DATA"; case STREAM_SPARSE_GZIP_DATA: return "SPARSE-GZIP"; case STREAM_SPARSE_COMPRESSED_DATA: return "SPARSE-COMPRESSED"; case STREAM_PROGRAM_NAMES: return "PROG-NAMES"; case STREAM_PROGRAM_DATA: return "PROG-DATA"; case STREAM_PLUGIN_NAME: return "PLUGIN-NAME"; case STREAM_MACOS_FORK_DATA: return "MACOS-RSRC"; case STREAM_HFSPLUS_ATTRIBUTES: return "HFSPLUS-ATTR"; case STREAM_SHA256_DIGEST: return "SHA256"; case STREAM_SHA512_DIGEST: return "SHA512"; case STREAM_SIGNED_DIGEST: return "SIGNED-DIGEST"; case STREAM_ENCRYPTED_SESSION_DATA: return "ENCRYPTED-SESSION-DATA"; case STREAM_ENCRYPTED_FILE_DATA: return "ENCRYPTED-FILE"; case STREAM_ENCRYPTED_FILE_GZIP_DATA: return "ENCRYPTED-GZIP"; case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA: return "ENCRYPTED-COMPRESSED"; case STREAM_ENCRYPTED_WIN32_DATA: return "ENCRYPTED-WIN32-DATA"; case STREAM_ENCRYPTED_WIN32_GZIP_DATA: return "ENCRYPTED-WIN32-GZIP"; case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA: return "ENCRYPTED-WIN32-COMPRESSED"; case STREAM_ENCRYPTED_MACOS_FORK_DATA: return "ENCRYPTED-MACOS-RSRC"; default: sprintf(buf, "%d", stream); return buf; } } /* * Return a new record entity */ DEV_RECORD *new_record(bool with_data) { DEV_RECORD *rec; rec = (DEV_RECORD *)get_pool_memory(PM_RECORD); memset(rec, 0, sizeof(DEV_RECORD)); if (with_data) { rec->data = get_pool_memory(PM_MESSAGE); rec->own_mempool = true; } rec->state = st_none; return rec; } void empty_record(DEV_RECORD *rec) { rec->File = rec->Block = 0; rec->VolSessionId = rec->VolSessionTime = 0; rec->FileIndex = rec->Stream = 0; rec->data_len = rec->remainder = 0; rec->state_bits &= ~(REC_PARTIAL_RECORD | REC_BLOCK_EMPTY | REC_NO_MATCH | REC_CONTINUATION); rec->state = st_none; } void copy_record_state(DEV_RECORD *dst, DEV_RECORD *src) { bool own_mempool; int32_t Stream, maskedStream; uint32_t data_len; POOLMEM *data; /* * Preserve some important fields all other can be overwritten. */ Stream = dst->Stream; maskedStream = dst->maskedStream; data = dst->data; data_len = dst->data_len; own_mempool = dst->own_mempool; memcpy(dst, src, sizeof(DEV_RECORD)); dst->Stream = Stream; dst->maskedStream = maskedStream; dst->data = data; dst->data_len = data_len; dst->own_mempool = own_mempool; } /* * Free the record entity */ void free_record(DEV_RECORD *rec) { Dmsg0(950, "Enter free_record.\n"); if (rec->data && rec->own_mempool) { free_pool_memory(rec->data); } Dmsg0(950, "Data buf is freed.\n"); free_pool_memory((POOLMEM *)rec); Dmsg0(950, "Leave free_record.\n"); } static inline bool write_header_to_block(DEV_BLOCK *block, DEV_RECORD *rec) { ser_declare; rec->remlen = block->buf_len - block->binbuf; /* * Require enough room to write a full header */ if (rec->remlen >= WRITE_RECHDR_LENGTH) { ser_begin(block->bufp, WRITE_RECHDR_LENGTH); if (BLOCK_VER == 1) { ser_uint32(rec->VolSessionId); ser_uint32(rec->VolSessionTime); } else { block->VolSessionId = rec->VolSessionId; block->VolSessionTime = rec->VolSessionTime; } ser_int32(rec->FileIndex); ser_int32(rec->Stream); ser_uint32(rec->data_len); block->bufp += WRITE_RECHDR_LENGTH; block->binbuf += WRITE_RECHDR_LENGTH; rec->remlen -= WRITE_RECHDR_LENGTH; rec->remainder = rec->data_len; if (rec->FileIndex > 0) { /* * If data record, update what we have in this block */ if (block->FirstIndex == 0) { block->FirstIndex = rec->FileIndex; } block->LastIndex = rec->FileIndex; } } else { rec->remainder = rec->data_len + WRITE_RECHDR_LENGTH; return false; } return true; } static inline void write_continue_header_to_block(DEV_BLOCK *block, DEV_RECORD *rec) { ser_declare; rec->remlen = block->buf_len - block->binbuf; /* * We have unwritten bytes from a previous * time. Presumably we have a new buffer (possibly * containing a volume label), so the new header * should be able to fit in the block -- otherwise we have * an error. Note, we have to continue splitting the * data record if it is longer than the block. * * First, write the header. * * Every time we write a header and it is a continuation * of a previous partially written record, we store the * Stream as -Stream in the record header. */ ser_begin(block->bufp, WRITE_RECHDR_LENGTH); if (BLOCK_VER == 1) { ser_uint32(rec->VolSessionId); ser_uint32(rec->VolSessionTime); } else { block->VolSessionId = rec->VolSessionId; block->VolSessionTime = rec->VolSessionTime; } ser_int32(rec->FileIndex); if (rec->remainder > rec->data_len) { ser_int32(rec->Stream); /* normal full header */ ser_uint32(rec->data_len); rec->remainder = rec->data_len; /* must still do data record */ } else { ser_int32(-rec->Stream); /* mark this as a continuation record */ ser_uint32(rec->remainder); /* bytes to do */ } /* * Require enough room to write a full header */ ASSERT(rec->remlen >= WRITE_RECHDR_LENGTH); block->bufp += WRITE_RECHDR_LENGTH; block->binbuf += WRITE_RECHDR_LENGTH; rec->remlen -= WRITE_RECHDR_LENGTH; if (rec->FileIndex > 0) { /* * If data record, update what we have in this block */ if (block->FirstIndex == 0) { block->FirstIndex = rec->FileIndex; } block->LastIndex = rec->FileIndex; } } static inline bool write_data_to_block(DEV_BLOCK *block, DEV_RECORD *rec) { rec->remlen = block->buf_len - block->binbuf; /* * Write as much of data as possible */ if (rec->remlen >= rec->remainder) { memcpy(block->bufp, rec->data + (rec->data_len - rec->remainder), rec->remainder); block->bufp += rec->remainder; block->binbuf += rec->remainder; } else { memcpy(block->bufp, rec->data + (rec->data_len - rec->remainder), rec->remlen); #ifdef xxxxxSMCHECK if (!sm_check_rtn(__FILE__, __LINE__, False)) { /* * We damaged a buffer */ Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n" "rem=%d remainder=%d\n", FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len, rec->remlen, rec->remainder); Dmsg5(0, "Damaged block: bufp=%x binbuf=%d buf_len=%d rem=%d moved=%d\n", block->bufp, block->binbuf, block->buf_len, block->buf_len-block->binbuf, rec->remlen); Dmsg2(0, "Damaged block: buf=%x binbuffrombuf=%d \n", block->buf, block->bufp-block->buf); Emsg0(M_ABORT, 0, _("Damaged buffer\n")); } #endif block->bufp += rec->remlen; block->binbuf += rec->remlen; rec->remainder -= rec->remlen; return false; /* did partial transfer */ } return true; } /* * Write a Record to the block * * Returns: false means the block could not be written to tape/disk. * true on success (all bytes written to the block). */ bool DCR::write_record() { bool retval = false; bool translated_record = false; char buf1[100], buf2[100]; /* * Perform record translations. */ before_rec = rec; after_rec = NULL; if (generate_plugin_event(jcr, bsdEventWriteRecordTranslation, this) != bRC_OK) { goto bail_out; } /* * The record got translated when we got an after_rec pointer after calling the * bsdEventWriteRecordTranslation plugin event. If no translation has taken place * we just point the after_rec pointer to same DEV_RECORD as in the before_rec pointer. */ if (!after_rec) { after_rec = before_rec; } else { translated_record = true; } while (!write_record_to_block(this, after_rec)) { Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", after_rec->data_len, after_rec->remainder); if (!write_block_to_device()) { Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n", dev->print_name(), dev->bstrerror()); goto bail_out; } } jcr->JobBytes += after_rec->data_len; /* increment bytes this job */ if (jcr->RemainingQuota && jcr->JobBytes > jcr->RemainingQuota) { Jmsg0(jcr, M_FATAL, 0, _("Quota Exceeded. Job Terminated.\n")); goto bail_out; } Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n", FI_to_ascii(buf1, after_rec->FileIndex), after_rec->VolSessionId, stream_to_ascii(buf2, after_rec->Stream, after_rec->FileIndex), after_rec->data_len); retval = true; bail_out: if (translated_record) { copy_record_state(before_rec, after_rec); free_record(after_rec); after_rec = NULL; } return retval; } /* * Write a Record to the block * * Returns: false on failure (none or partially written) * true on success (all bytes written) * * and remainder returned in packet. * * We require enough room for the header, and we deal with * two special cases. 1. Only part of the record may have * been transferred the last time (when remainder is * non-zero), and 2. The remaining bytes to write may not * all fit into the block. */ bool write_record_to_block(DCR *dcr, DEV_RECORD *rec) { bool retval = false; char buf1[100], buf2[100]; DEV_BLOCK *block = dcr->block; /* * After this point the record is in nrec not rec e.g. its either converted * or is just a pointer to the same as the rec pointer being passed in. */ while (1) { ASSERT(block->binbuf == (uint32_t)(block->bufp - block->buf)); ASSERT(block->buf_len >= block->binbuf); Dmsg6(890, "write_record_to_block() FI=%s SessId=%d Strm=%s len=%d\n" "rem=%d remainder=%d\n", FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len, rec->remlen, rec->remainder); switch (rec->state) { case st_none: /* * Figure out what to do */ rec->state = st_header; continue; /* go to next state */ case st_header: /* * Write header * * If rec->remainder is non-zero, we have been called a * second (or subsequent) time to finish writing a record * that did not previously fit into the block. */ if (!write_header_to_block(block, rec)) { goto bail_out; /* write block then come back here */ } rec->state = st_data; /* after header, now write data */ continue; /* * Write continuation header */ case st_header_cont: write_continue_header_to_block(block, rec); rec->state = st_data; if (rec->remlen == 0) { goto bail_out; /* Partial transfer */ } continue; /* * Write normal data */ case st_data: /* * Write data * * Part of it may have already been transferred, and we * may not have enough room to transfer the whole this time. */ if (rec->remainder > 0) { if (!write_data_to_block(block, rec)) { rec->state = st_header_cont; goto bail_out; } } rec->remainder = 0; /* did whole transfer */ rec->state = st_none; retval = true; goto bail_out; default: Dmsg0(000, "Something went wrong. Default state.\n"); rec->state = st_none; retval = true; goto bail_out; } } bail_out: return retval; } /* * Test if we can write whole record to the block * * Returns: false on failure * true on success (all bytes can be written) */ bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec) { uint32_t remlen; remlen = block->buf_len - block->binbuf; if (rec->remainder == 0) { if (remlen >= WRITE_RECHDR_LENGTH) { remlen -= WRITE_RECHDR_LENGTH; rec->remainder = rec->data_len; } else { return false; } } else { return false; } if (rec->remainder > 0 && remlen < rec->remainder) { return false; } return true; } uint64_t get_record_address(DEV_RECORD *rec) { return ((uint64_t)rec->File)<<32 | rec->Block; } /* * Read a Record from the block * * Returns: false if nothing read or if the continuation record does not match. * In both of these cases, a block read must be done. * true if at least the record header was read, this * routine may have to be called again with a new * block if the entire record was not read. */ bool read_record_from_block(DCR *dcr, DEV_RECORD *rec) { ser_declare; uint32_t remlen; uint32_t VolSessionId; uint32_t VolSessionTime; int32_t FileIndex; int32_t Stream; uint32_t data_bytes; uint32_t rhl; char buf1[100], buf2[100]; remlen = dcr->block->binbuf; /* * Clear state flags */ rec->state_bits = 0; if (dcr->block->dev->is_tape()) { rec->state_bits |= REC_ISTAPE; } rec->Block = ((DEVICE *)(dcr->block->dev))->EndBlock; rec->File = ((DEVICE *)(dcr->block->dev))->EndFile; /* * Get the header. There is always a full header, otherwise we find it in the next block. */ Dmsg3(450, "Block=%d Ver=%d size=%u\n", dcr->block->BlockNumber, dcr->block->BlockVer, dcr->block->block_len); if (dcr->block->BlockVer == 1) { rhl = RECHDR1_LENGTH; } else { rhl = RECHDR2_LENGTH; } if (remlen >= rhl) { Dmsg4(450, "Enter read_record_block: remlen=%d data_len=%d rem=%d blkver=%d\n", remlen, rec->data_len, rec->remainder, dcr->block->BlockVer); unser_begin(dcr->block->bufp, WRITE_RECHDR_LENGTH); if (dcr->block->BlockVer == 1) { unser_uint32(VolSessionId); unser_uint32(VolSessionTime); } else { VolSessionId = dcr->block->VolSessionId; VolSessionTime = dcr->block->VolSessionTime; } unser_int32(FileIndex); unser_int32(Stream); unser_uint32(data_bytes); dcr->block->bufp += rhl; dcr->block->binbuf -= rhl; remlen -= rhl; /* * If we are looking for more (remainder!=0), we reject anything * where the VolSessionId and VolSessionTime don't agree */ if (rec->remainder && (rec->VolSessionId != VolSessionId || rec->VolSessionTime != VolSessionTime)) { rec->state_bits |= REC_NO_MATCH; Dmsg0(450, "remainder and VolSession doesn't match\n"); return false; /* This is from some other Session */ } /* * If Stream is negative, it means that this is a continuation * of a previous partially written record. */ if (Stream < 0) { /* continuation record? */ Dmsg1(500, "Got negative Stream => continuation. remainder=%d\n", rec->remainder); rec->state_bits |= REC_CONTINUATION; if (!rec->remainder) { /* if we didn't read previously */ rec->data_len = 0; /* return data as if no continuation */ } else if (rec->Stream != -Stream) { rec->state_bits |= REC_NO_MATCH; return false; /* This is from some other Session */ } rec->Stream = -Stream; /* set correct Stream */ rec->maskedStream = rec->Stream & STREAMMASK_TYPE; } else { /* Regular record */ rec->Stream = Stream; rec->maskedStream = rec->Stream & STREAMMASK_TYPE; rec->data_len = 0; /* transfer to beginning of data */ } rec->VolSessionId = VolSessionId; rec->VolSessionTime = VolSessionTime; rec->FileIndex = FileIndex; if (FileIndex > 0) { if (dcr->block->FirstIndex == 0) { dcr->block->FirstIndex = FileIndex; } dcr->block->LastIndex = FileIndex; } Dmsg6(450, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n" "remlen=%d data_len=%d\n", FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), data_bytes, remlen, rec->data_len); } else { /* * No more records in this block because the number * of remaining bytes are less than a record header * length, so return empty handed, but indicate that * he must read again. By returning, we allow the * higher level routine to fetch the next block and * then reread. */ Dmsg0(450, "read_record_block: nothing\n"); rec->state_bits |= (REC_NO_HEADER | REC_BLOCK_EMPTY); empty_block(dcr->block); /* mark block empty */ return false; } /* Sanity check */ if (data_bytes >= MAX_BLOCK_LENGTH) { /* * Something is wrong, force read of next block, abort * continuing with this block. */ rec->state_bits |= (REC_NO_HEADER | REC_BLOCK_EMPTY); empty_block(dcr->block); Jmsg2(dcr->jcr, M_WARNING, 0, _("Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n"), MAX_BLOCK_LENGTH, data_bytes); return false; } rec->data = check_pool_memory_size(rec->data, rec->data_len + data_bytes); /* * At this point, we have read the header, now we * must transfer as much of the data record as * possible taking into account: 1. A partial * data record may have previously been transferred, * 2. The current block may not contain the whole data * record. */ if (remlen >= data_bytes) { /* * Got whole record */ memcpy(rec->data+rec->data_len, dcr->block->bufp, data_bytes); dcr->block->bufp += data_bytes; dcr->block->binbuf -= data_bytes; rec->data_len += data_bytes; } else { /* * Partial record */ memcpy(rec->data+rec->data_len, dcr->block->bufp, remlen); dcr->block->bufp += remlen; dcr->block->binbuf -= remlen; rec->data_len += remlen; rec->remainder = 1; /* partial record transferred */ Dmsg1(450, "read_record_block: partial xfered=%d\n", rec->data_len); rec->state_bits |= (REC_PARTIAL_RECORD | REC_BLOCK_EMPTY); return true; } rec->remainder = 0; Dmsg4(450, "Rtn full rd_rec_blk FI=%s SessId=%d Strm=%s len=%d\n", FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len); return true; /* transferred full record */ } bareos-Release-14.2.6/src/stored/record.h000066400000000000000000000226701263011562700201650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Record, and label definitions for Bareos media data format. * * Kern Sibbald, MM */ #ifndef __RECORD_H #define __RECORD_H 1 /* Return codes from read_device_volume_label() */ enum { VOL_NOT_READ = 1, /* Volume label not read */ VOL_OK, /* volume name OK */ VOL_NO_LABEL, /* volume not labeled */ VOL_IO_ERROR, /* volume I/O error */ VOL_NAME_ERROR, /* Volume name mismatch */ VOL_CREATE_ERROR, /* Error creating label */ VOL_VERSION_ERROR, /* Bareos version error */ VOL_LABEL_ERROR, /* Bad label type */ VOL_NO_MEDIA /* Hard error -- no media present */ }; enum rec_state { st_none, /* No state */ st_header, /* Write header */ st_header_cont, st_data }; /* See block.h for RECHDR_LENGTH */ /* * This is the Media structure for a record header. * NB: when it is written it is serialized. uint32_t VolSessionId; uint32_t VolSessionTime; * The above 8 bytes are only written in a BB01 block, BB02 * and later blocks contain these values in the block header * rather than the record header. int32_t FileIndex; int32_t Stream; uint32_t data_len; */ /* Record state bit definitions */ #define REC_NO_HEADER (1<<0) /* No header read */ #define REC_PARTIAL_RECORD (1<<1) /* returning partial record */ #define REC_BLOCK_EMPTY (1<<2) /* not enough data in block */ #define REC_NO_MATCH (1<<3) /* No match on continuation data */ #define REC_CONTINUATION (1<<4) /* Continuation record found */ #define REC_ISTAPE (1<<5) /* Set if device is tape */ #define is_partial_record(r) ((r)->state_bits & REC_PARTIAL_RECORD) #define is_block_empty(r) ((r)->state_bits & REC_BLOCK_EMPTY) /* * DEV_RECORD for reading and writing records. * It consists of a Record Header, and the Record Data * * This is the memory structure for the record header. */ struct BSR; /* satisfy forward reference */ struct DEV_RECORD { dlink link; /* link for chaining in read_record.c */ /* * File and Block are always returned during reading and writing records. */ uint32_t File; /* File number */ uint32_t Block; /* Block number */ uint32_t VolSessionId; /* Sequential id within this session */ uint32_t VolSessionTime; /* Session start time */ int32_t FileIndex; /* Sequential file number */ int32_t Stream; /* Full Stream number with high bits */ int32_t maskedStream; /* Masked Stream without high bits */ uint32_t data_len; /* Current record length */ uint32_t remainder; /* Remaining bytes to read/write */ uint32_t remlen; /* Temp remainder bytes */ uint32_t state_bits; /* State bits */ rec_state state; /* State of write_record_to_block */ BSR *bsr; /* Pointer to bsr that matched */ uint8_t ser_buf[WRITE_RECHDR_LENGTH]; /* Serialized record header goes here */ POOLMEM *data; /* Record data. This MUST be a memory pool item */ int32_t match_stat; /* BSR match status */ uint32_t last_VolSessionId; /* Used in sequencing FI for Vbackup */ uint32_t last_VolSessionTime; int32_t last_FileIndex; int32_t last_Stream; /* Used in SD-SD replication */ bool own_mempool; /* Do we own the POOLMEM pointed to in data ? */ }; /* * Values for LabelType that are put into the FileIndex field * Note, these values are negative to distinguish them * from user records where the FileIndex is forced positive. */ #define PRE_LABEL -1 /* Vol label on unwritten tape */ #define VOL_LABEL -2 /* Volume label first file */ #define EOM_LABEL -3 /* Writen at end of tape */ #define SOS_LABEL -4 /* Start of Session */ #define EOS_LABEL -5 /* End of Session */ #define EOT_LABEL -6 /* End of physical tape (2 eofs) */ #define SOB_LABEL -7 /* Start of object -- file/directory */ #define EOB_LABEL -8 /* End of object (after all streams) */ /* * Volume Label Record. This is the in-memory definition. The * tape definition is defined in the serialization code itself * ser_volume_label() and unser_volume_label() and is slightly different. */ struct Volume_Label { /* * The first items in this structure are saved * in the DEVICE buffer, but are not actually written * to the tape. */ int32_t LabelType; /* This is written in header only */ uint32_t LabelSize; /* length of serialized label */ /* * The items below this line are stored on * the tape */ char Id[32]; /* Bareos Immortal ... */ uint32_t VerNum; /* Label version number */ /* VerNum <= 10 */ float64_t label_date; /* Date tape labeled */ float64_t label_time; /* Time tape labeled */ /* VerNum >= 11 */ btime_t label_btime; /* tdate tape labeled */ btime_t write_btime; /* tdate tape written */ /* Unused with VerNum >= 11 */ float64_t write_date; /* Date this label written */ float64_t write_time; /* Time this label written */ char VolumeName[MAX_NAME_LENGTH]; /* Volume name */ char PrevVolumeName[MAX_NAME_LENGTH]; /* Previous Volume Name */ char PoolName[MAX_NAME_LENGTH]; /* Pool name */ char PoolType[MAX_NAME_LENGTH]; /* Pool type */ char MediaType[MAX_NAME_LENGTH]; /* Type of this media */ char HostName[MAX_NAME_LENGTH]; /* Host name of writing computer */ char LabelProg[50]; /* Label program name */ char ProgVersion[50]; /* Program version */ char ProgDate[50]; /* Program build date/time */ }; #define SER_LENGTH_Volume_Label 1024 /* max serialised length of volume label */ #define SER_LENGTH_Session_Label 1024 /* max serialised length of session label */ typedef struct Volume_Label VOLUME_LABEL; /* * Session Start/End Label * This record is at the beginning and end of each session */ struct Session_Label { char Id[32]; /* Bareos Immortal ... */ uint32_t VerNum; /* Label version number */ uint32_t JobId; /* Job id */ uint32_t VolumeIndex; /* Sequence no of volume for this job */ /* VerNum >= 11 */ btime_t write_btime; /* Tdate this label written */ /* VerNum < 11 */ float64_t write_date; /* Date this label written */ /* Unused VerNum >= 11 */ float64_t write_time; /* Time this label written */ char PoolName[MAX_NAME_LENGTH]; /* Pool name */ char PoolType[MAX_NAME_LENGTH]; /* Pool type */ char JobName[MAX_NAME_LENGTH]; /* base Job name */ char ClientName[MAX_NAME_LENGTH]; char Job[MAX_NAME_LENGTH]; /* Unique name of this Job */ char FileSetName[MAX_NAME_LENGTH]; char FileSetMD5[MAX_NAME_LENGTH]; uint32_t JobType; uint32_t JobLevel; /* The remainder are part of EOS label only */ uint32_t JobFiles; uint64_t JobBytes; uint32_t StartBlock; uint32_t EndBlock; uint32_t StartFile; uint32_t EndFile; uint32_t JobErrors; uint32_t JobStatus; /* Job status */ }; typedef struct Session_Label SESSION_LABEL; #define SERIAL_BUFSIZE 1024 /* Volume serialisation buffer size */ /* * Read context used to keep track of what is processed or not. */ struct Read_Context { DEV_RECORD *rec; /* Record currently being processed */ dlist *recs; /* Linked list of record packets open */ SESSION_LABEL sessrec; /* Start Of Session record info */ uint32_t records_processed; /* Number of records processed from this block */ int32_t lastFileIndex; /* Last File Index processed */ }; typedef struct Read_Context READ_CTX; struct DELAYED_DATA_STREAM { int32_t stream; /* stream less new bits */ char *content; /* stream data */ uint32_t content_length; /* stream length */ }; #define READ_NO_FILEINDEX -999999 #endif bareos-Release-14.2.6/src/stored/reserve.c000066400000000000000000001145621263011562700203570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Drive reservation functions for Storage Daemon * * Kern Sibbald, MM * * Split from job.c and acquire.c June 2005 */ #include "bareos.h" #include "stored.h" const int dbglvl = 150; static brwlock_t reservation_lock; /* Forward referenced functions */ static int can_reserve_drive(DCR *dcr, RCTX &rctx); static int reserve_device(RCTX &rctx); static bool reserve_device_for_read(DCR *dcr); static bool reserve_device_for_append(DCR *dcr, RCTX &rctx); static bool use_device_cmd(JCR *jcr); static void queue_reserve_message(JCR *jcr); static void pop_reserve_messages(JCR *jcr); //void switch_device(DCR *dcr, DEVICE *dev); /* Requests from the Director daemon */ static char use_storage[] = "use storage=%127s media_type=%127s " "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n"; static char use_device[] = "use device=%127s\n"; /* Responses sent to Director daemon */ static char OK_device[] = "3000 OK use device device=%s\n"; static char NO_device[] = "3924 Device \"%s\" not in SD Device" " resources or no matching Media Type.\n"; static char BAD_use[] = "3913 Bad use command: %s\n"; bool use_cmd(JCR *jcr) { /* * Get the device, media, and pool information */ if (!use_device_cmd(jcr)) { jcr->setJobStatus(JS_ErrorTerminated); memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key)); return false; } return true; } /* * This allows a given thread to recursively call lock_reservations. * It must, of course, call unlock_... the same number of times. */ void init_reservations_lock() { int errstat; if ((errstat=rwl_init(&reservation_lock)) != 0) { berrno be; Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"), be.bstrerror(errstat)); } init_vol_list_lock(); } void term_reservations_lock() { rwl_destroy(&reservation_lock); term_vol_list_lock(); } int reservations_lock_count = 0; /* This applies to a drive and to Volumes */ void _lock_reservations(const char *file, int line) { int errstat; reservations_lock_count++; if ((errstat=rwl_writelock_p(&reservation_lock, file, line)) != 0) { berrno be; Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n", errstat, be.bstrerror(errstat)); } } void _unlock_reservations() { int errstat; reservations_lock_count--; if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) { berrno be; Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n", errstat, be.bstrerror(errstat)); } } void DCR::set_reserved() { m_reserved = true; Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name()); dev->inc_reserved(); } void DCR::clear_reserved() { if (m_reserved) { m_reserved = false; dev->dec_reserved(); Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name()); } } /* * Remove any reservation from a drive and tell the system * that the volume is unused at least by us. */ void DCR::unreserve_device() { dev->Lock(); if (is_reserved()) { clear_reserved(); reserved_volume = false; /* If we set read mode in reserving, remove it */ if (dev->can_read()) { dev->clear_read(); } if (dev->num_writers < 0) { Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers); dev->num_writers = 0; } if (dev->num_reserved() == 0 && dev->num_writers == 0) { generate_plugin_event(jcr, bsdEventDeviceClose, this); volume_unused(this); } } dev->Unlock(); } /* * We get the following type of information: * * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0 * use device=zzz * use device=aaa * use device=bbb * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0 * use device=bbb * */ static bool use_device_cmd(JCR *jcr) { POOL_MEM store_name, dev_name, media_type, pool_name, pool_type; BSOCK *dir = jcr->dir_bsock; int32_t append; bool ok; int32_t Copy, Stripe; DIRSTORE *store; RCTX rctx; alist *dirstore; memset(&rctx, 0, sizeof(RCTX)); rctx.jcr = jcr; /* * If there are multiple devices, the director sends us * use_device for each device that it wants to use. */ dirstore = New(alist(10, not_owned_by_alist)); jcr->reserve_msgs = New(alist(10, not_owned_by_alist)); do { Dmsg1(dbglvl, "msg); ok = sscanf(dir->msg, use_storage, store_name.c_str(), media_type.c_str(), pool_name.c_str(), pool_type.c_str(), &append, &Copy, &Stripe) == 7; if (!ok) { break; } if (append) { jcr->write_store = dirstore; } else { jcr->read_store = dirstore; } rctx.append = append; unbash_spaces(store_name); unbash_spaces(media_type); unbash_spaces(pool_name); unbash_spaces(pool_type); store = new DIRSTORE; dirstore->append(store); memset(store, 0, sizeof(DIRSTORE)); store->device = New(alist(10)); bstrncpy(store->name, store_name, sizeof(store->name)); bstrncpy(store->media_type, media_type, sizeof(store->media_type)); bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name)); bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type)); store->append = append; /* Now get all devices */ while (dir->recv() >= 0) { Dmsg1(dbglvl, "msg); ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1; if (!ok) { break; } unbash_spaces(dev_name); store->device->append(bstrdup(dev_name.c_str())); } } while (ok && dir->recv() >= 0); #ifdef xxxx /* Developer debug code */ char *device_name; if (debug_level >= dbglvl) { foreach_alist(store, dirstore) { Dmsg5(dbglvl, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n", store->name, store->media_type, store->pool_name, store->pool_type, store->append); foreach_alist(device_name, store->device) { Dmsg1(dbglvl, " Device=%s\n", device_name); } } } #endif init_jcr_device_wait_timers(jcr); jcr->dcr = New(SD_DCR); setup_new_dcr_device(jcr, jcr->dcr, NULL, NULL); if (rctx.append) { jcr->dcr->set_will_write(); } if (!jcr->dcr) { BSOCK *dir = jcr->dir_bsock; dir->fsend(_("3939 Could not get dcr\n")); Dmsg1(dbglvl, ">dird: %s", dir->msg); ok = false; } /* * At this point, we have a list of all the Director's Storage resources indicated * for this Job, which include Pool, PoolType, storage name, and Media type. * * Then for each of the Storage resources, we have a list of device names that were given. * * Wiffle through them and find one that can do the backup. */ if (ok) { int wait_for_device_retries = 0; int repeat = 0; bool fail = false; rctx.notify_dir = true; /* Put new dcr in proper location */ if (rctx.append) { rctx.jcr->dcr = jcr->dcr; } else { rctx.jcr->read_dcr = jcr->dcr; } lock_reservations(); for ( ; !fail && !job_canceled(jcr); ) { pop_reserve_messages(jcr); rctx.suitable_device = false; rctx.have_volume = false; rctx.VolumeName[0] = 0; rctx.any_drive = false; if (!jcr->PreferMountedVols) { /* * Here we try to find a drive that is not used. * This will maximize the use of available drives. * */ rctx.num_writers = 20000000; /* start with impossible number */ rctx.low_use_drive = NULL; rctx.PreferMountedVols = false; rctx.exact_match = false; rctx.autochanger_only = true; if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } /* Look through all drives possibly for low_use drive */ if (rctx.low_use_drive) { rctx.try_low_use_drive = true; if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } rctx.try_low_use_drive = false; } rctx.autochanger_only = false; if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } } /* * Now we look for a drive that may or may not be in * use. */ /* Look for an exact Volume match all drives */ rctx.PreferMountedVols = true; rctx.exact_match = true; rctx.autochanger_only = false; if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } /* Look for any mounted drive */ rctx.exact_match = false; if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } /* Try any drive */ rctx.any_drive = true; if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } /* Keep reservations locked *except* during wait_for_device() */ unlock_reservations(); /* * The idea of looping on repeat a few times it to ensure * that if there is some subtle timing problem between two * jobs, we will simply try again, and most likely succeed. * This can happen if one job reserves a drive or finishes using * a drive at the same time a second job wants it. */ if (repeat++ > 1) { /* try algorithm 3 times */ bmicrosleep(30, 0); /* wait a bit */ Dmsg0(dbglvl, "repeat reserve algorithm\n"); } else if (!rctx.suitable_device || !wait_for_device(jcr, wait_for_device_retries)) { Dmsg0(dbglvl, "Fail. !suitable_device || !wait_for_device\n"); fail = true; } lock_reservations(); dir->signal(BNET_HEARTBEAT); /* Inform Dir that we are alive */ } unlock_reservations(); if (!ok) { /* * If we get here, there are no suitable devices available, which * means nothing configured. If a device is suitable but busy * with another Volume, we will not come here. */ unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Device reservation failed for JobId=%d: %s\n"), jcr->JobId, jcr->errmsg); dir->fsend(NO_device, dev_name.c_str()); Dmsg1(dbglvl, ">dird: %s", dir->msg); } } else { unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg); dir->fsend(BAD_use, jcr->errmsg); Dmsg1(dbglvl, ">dird: %s", dir->msg); } release_reserve_messages(jcr); return ok; } /* * Walk through the autochanger resources and check if the volume is in one of them. * * Returns: true if volume is in device * false otherwise */ static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol) { AUTOCHANGERRES *changer = vol->dev->device->changer_res; if (!changer) { return false; } /* * Find resource, and make sure we were able to open it */ if (bstrcmp(rctx.device_name, changer->hdr.name)) { Dmsg1(dbglvl, "Found changer device %s\n", vol->dev->device->hdr.name); return true; } Dmsg1(dbglvl, "Incorrect changer device %s\n", changer->hdr.name); return false; } /* * Search for a device suitable for this job. * Note, this routine sets sets rctx.suitable_device if any * device exists within the SD. The device may not be actually * useable. * It also returns if it finds a useable device. */ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) { bool ok = false; DIRSTORE *store; char *device_name; alist *dirstore; DCR *dcr = jcr->dcr; if (rctx.append) { dirstore = jcr->write_store; } else { dirstore = jcr->read_store; } Dmsg5(dbglvl, "Start find_suit_dev PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n", rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device, rctx.autochanger_only, rctx.any_drive); /* * If the appropriate conditions of this if are met, namely that * we are appending and the user wants mounted drive (or we * force try a mounted drive because they are all busy), we * start by looking at all the Volumes in the volume list. */ if (!is_vol_list_empty() && rctx.append && rctx.PreferMountedVols) { dlist *temp_vol_list; VOLRES *vol = NULL; temp_vol_list = dup_vol_list(jcr); /* Look through reserved volumes for one we can use */ Dmsg0(dbglvl, "look for vol in vol list\n"); foreach_dlist(vol, temp_vol_list) { if (!vol->dev) { Dmsg1(dbglvl, "vol=%s no dev\n", vol->vol_name); continue; } /* Check with Director if this Volume is OK */ bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName)); if (!dcr->dir_get_volume_info(GET_VOL_INFO_FOR_WRITE)) { continue; } Dmsg1(dbglvl, "vol=%s OK for this job\n", vol->vol_name); foreach_alist(store, dirstore) { int status; rctx.store = store; foreach_alist(device_name, store->device) { /* Found a device, try to use it */ rctx.device_name = device_name; rctx.device = vol->dev->device; if (vol->dev->is_autochanger()) { Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name); if (!is_vol_in_autochanger(rctx, vol) || !vol->dev->autoselect) { continue; } } else if (!bstrcmp(device_name, vol->dev->device->hdr.name)) { Dmsg2(dbglvl, "device=%s not suitable want %s\n", vol->dev->device->hdr.name, device_name); continue; } bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName)); rctx.have_volume = true; /* Try reserving this device and volume */ Dmsg2(dbglvl, "try vol=%s on device=%s\n", rctx.VolumeName, device_name); status = reserve_device(rctx); if (status == 1) { /* found available device */ Dmsg1(dbglvl, "Suitable device found=%s\n", device_name); ok = true; break; } else if (status == 0) { /* device busy */ Dmsg1(dbglvl, "Suitable device=%s, busy: not use\n", device_name); } else { /* otherwise error */ Dmsg0(dbglvl, "No suitable device found.\n"); } rctx.have_volume = false; rctx.VolumeName[0] = 0; } if (ok) { break; } } if (ok) { break; } } /* end for loop over reserved volumes */ Dmsg0(dbglvl, "lock volumes\n"); free_temp_vol_list(temp_vol_list); temp_vol_list = NULL; } if (ok) { Dmsg1(dbglvl, "OK dev found. Vol=%s from in-use vols list\n", rctx.VolumeName); return true; } /* * No reserved volume we can use, so now search for an available device. * * For each storage device that the user specified, we * search and see if there is a resource for that device. */ foreach_alist(store, dirstore) { rctx.store = store; foreach_alist(device_name, store->device) { int status; rctx.device_name = device_name; status = search_res_for_device(rctx); if (status == 1) { /* found available device */ Dmsg1(dbglvl, "available device found=%s\n", device_name); ok = true; break; } else if (status == 0) { /* device busy */ Dmsg1(dbglvl, "No usable device=%s, busy: not use\n", device_name); } else { /* otherwise error */ Dmsg0(dbglvl, "No usable device found.\n"); } } if (ok) { break; } } if (ok) { Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName); } else { Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n"); } return ok; } /* * Search for a particular storage device with particular storage * characteristics (MediaType). */ int search_res_for_device(RCTX &rctx) { AUTOCHANGERRES *changer; int status; Dmsg1(dbglvl, "search res for %s\n", rctx.device_name); /* Look through Autochangers first */ foreach_res(changer, R_AUTOCHANGER) { Dmsg1(dbglvl, "Try match changer res=%s\n", changer->hdr.name); /* Find resource, and make sure we were able to open it */ if (bstrcmp(rctx.device_name, changer->hdr.name)) { /* Try each device in this AutoChanger */ foreach_alist(rctx.device, changer->device) { Dmsg1(dbglvl, "Try changer device %s\n", rctx.device->hdr.name); if (!rctx.device->autoselect) { Dmsg1(100, "Device %s not autoselect skipped.\n", rctx.device->hdr.name); continue; /* device is not available */ } status = reserve_device(rctx); if (status != 1) { /* try another device */ continue; } /* Debug code */ if (rctx.store->append == SD_APPEND) { Dmsg2(dbglvl, "Device %s reserved=%d for append.\n", rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved()); } else { Dmsg2(dbglvl, "Device %s reserved=%d for read.\n", rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved()); } return status; } } } /* Now if requested look through regular devices */ if (!rctx.autochanger_only) { foreach_res(rctx.device, R_DEVICE) { Dmsg1(dbglvl, "Try match res=%s\n", rctx.device->hdr.name); /* Find resource, and make sure we were able to open it */ if (bstrcmp(rctx.device_name, rctx.device->hdr.name)) { status = reserve_device(rctx); if (status != 1) { /* try another device */ continue; } /* Debug code */ if (rctx.store->append == SD_APPEND) { Dmsg2(dbglvl, "Device %s reserved=%d for append.\n", rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved()); } else { Dmsg2(dbglvl, "Device %s reserved=%d for read.\n", rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved()); } return status; } } } return -1; /* nothing found */ } /* * Try to reserve a specific device. * * Returns: 1 -- OK, have DCR * 0 -- must wait * -1 -- fatal error */ static int reserve_device(RCTX &rctx) { bool ok; DCR *dcr; const int name_len = MAX_NAME_LENGTH; /* Make sure MediaType is OK */ Dmsg2(dbglvl, "chk MediaType device=%s request=%s\n", rctx.device->media_type, rctx.store->media_type); if (!bstrcmp(rctx.device->media_type, rctx.store->media_type)) { return -1; } /* Make sure device exists -- i.e. we can stat() it */ if (!rctx.device->dev) { rctx.device->dev = init_dev(rctx.jcr, rctx.device); } if (!rctx.device->dev) { if (rctx.device->changer_res) { Jmsg(rctx.jcr, M_WARNING, 0, _("\n" " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"), rctx.device->hdr.name, rctx.device_name); } else { Jmsg(rctx.jcr, M_WARNING, 0, _("\n" " Device \"%s\" requested by DIR could not be opened or does not exist.\n"), rctx.device_name); } return -1; /* no use waiting */ } rctx.suitable_device = true; Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name); if (rctx.store->append) { setup_new_dcr_device(rctx.jcr, rctx.jcr->dcr, rctx.device->dev, NULL); dcr = rctx.jcr->dcr; } else { setup_new_dcr_device(rctx.jcr, rctx.jcr->read_dcr, rctx.device->dev, NULL); dcr = rctx.jcr->read_dcr; } if (!dcr) { BSOCK *dir = rctx.jcr->dir_bsock; dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name); Dmsg1(dbglvl, ">dird: %s", dir->msg); return -1; } if (rctx.store->append) { dcr->set_will_write(); } bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len); bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len); bstrncpy(dcr->media_type, rctx.store->media_type, name_len); bstrncpy(dcr->dev_name, rctx.device_name, name_len); if (rctx.store->append == SD_APPEND) { Dmsg2(dbglvl, "call reserve for append: have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName); ok = reserve_device_for_append(dcr, rctx); if (!ok) { goto bail_out; } rctx.jcr->dcr = dcr; Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n", dcr->dev->num_reserved(), dcr->dev_name, dcr->media_type, dcr->pool_name, ok); Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n", rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume); if (rctx.have_volume) { Dmsg0(dbglvl, "Call reserve_volume for append.\n"); if (reserve_volume(dcr, rctx.VolumeName)) { Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName); } else { Dmsg1(dbglvl, "Could not reserve vol=%s\n", rctx.VolumeName); goto bail_out; } } else { dcr->any_volume = true; Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n"); if (dcr->dir_find_next_appendable_volume()) { bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName)); rctx.have_volume = true; Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName); } else { Dmsg0(dbglvl, "No next volume found\n"); rctx.have_volume = false; rctx.VolumeName[0] = 0; /* * If there is at least one volume that is valid and in use, * but we get here, check if we are running with prefers * non-mounted drives. In that case, we have selected a * non-used drive and our one and only volume is mounted * elsewhere, so we bail out and retry using that drive. */ if (dcr->found_in_use() && !rctx.PreferMountedVols) { rctx.PreferMountedVols = true; if (dcr->VolumeName[0]) { dcr->unreserve_device(); } goto bail_out; } /* * Note. Under some circumstances, the Director can hand us * a Volume name that is not the same as the one on the current * drive, and in that case, the call above to find the next * volume will fail because in attempting to reserve the Volume * the code will realize that we already have a tape mounted, * and it will fail. This *should* only happen if there are * writers, thus the following test. In that case, we simply * bail out, and continue waiting, rather than plunging on * and hoping that the operator can resolve the problem. */ if (dcr->dev->num_writers != 0) { if (dcr->VolumeName[0]) { dcr->unreserve_device(); } goto bail_out; } } } } else { ok = reserve_device_for_read(dcr); if (ok) { rctx.jcr->read_dcr = dcr; Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n", dcr->dev->num_reserved(), dcr->dev_name, dcr->media_type, dcr->pool_name, ok); } } if (!ok) { goto bail_out; } if (rctx.notify_dir) { POOL_MEM dev_name; BSOCK *dir = rctx.jcr->dir_bsock; pm_strcpy(dev_name, rctx.device->hdr.name); bash_spaces(dev_name); ok = dir->fsend(OK_device, dev_name.c_str()); /* Return real device name */ Dmsg1(dbglvl, ">dird: %s", dir->msg); } else { ok = true; } return ok ? 1 : -1; bail_out: rctx.have_volume = false; rctx.VolumeName[0] = 0; Dmsg0(dbglvl, "Not OK.\n"); return 0; } /* * We "reserve" the drive by setting the ST_READREADY bit. No one else * should touch the drive until that is cleared. * This allows the DIR to "reserve" the device before actually * starting the job. */ static bool reserve_device_for_read(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; bool ok = false; ASSERT(dcr); if (job_canceled(jcr)) { return false; } dev->Lock(); if (dev->is_device_unmounted()) { Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name()); Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"), jcr->JobId, dev->print_name()); queue_reserve_message(jcr); goto bail_out; } if (dev->is_busy()) { Dmsg4(dbglvl, "Device %s is busy ST_READREADY=%d num_writers=%d reserved=%d.\n", dev->print_name(), dev->state & ST_READREADY ? 1 : 0, dev->num_writers, dev->num_reserved()); Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"), jcr->JobId, dev->print_name()); queue_reserve_message(jcr); goto bail_out; } /* Note: on failure this returns jcr->errmsg properly edited */ if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) { queue_reserve_message(jcr); goto bail_out; } dev->clear_append(); dev->set_read(); dcr->set_reserved(); ok = true; bail_out: dev->Unlock(); return ok; } /* * We reserve the device for appending by incrementing * num_reserved(). We do virtually all the same work that * is done in acquire_device_for_append(), but we do * not attempt to mount the device. This routine allows * the DIR to reserve multiple devices before *really* * starting the job. It also permits the SD to refuse * certain devices (not up, ...). * * Note, in reserving a device, if the device is for the * same pool and the same pool type, then it is acceptable. * The Media Type has already been checked. If we are * the first tor reserve the device, we put the pool * name and pool type in the device record. */ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx) { JCR *jcr = dcr->jcr; DEVICE *dev = dcr->dev; bool ok = false; ASSERT(dcr); if (job_canceled(jcr)) { return false; } dev->Lock(); /* If device is being read, we cannot write it */ if (dev->can_read()) { Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"), jcr->JobId, dev->print_name()); Dmsg1(dbglvl, "Failed: %s", jcr->errmsg); queue_reserve_message(jcr); goto bail_out; } /* If device is unmounted, we are out of luck */ if (dev->is_device_unmounted()) { Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"), jcr->JobId, dev->print_name()); Dmsg1(dbglvl, "Failed: %s", jcr->errmsg); queue_reserve_message(jcr); goto bail_out; } Dmsg1(dbglvl, "reserve_append device is %s\n", dev->print_name()); /* Now do detailed tests ... */ if (can_reserve_drive(dcr, rctx) != 1) { Dmsg0(dbglvl, "can_reserve_drive!=1\n"); goto bail_out; } /* Note: on failure this returns jcr->errmsg properly edited */ if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) { queue_reserve_message(jcr); goto bail_out; } dcr->set_reserved(); ok = true; bail_out: dev->Unlock(); return ok; } static int is_pool_ok(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; /* Now check if we want the same Pool and pool type */ if (bstrcmp(dev->pool_name, dcr->pool_name) && bstrcmp(dev->pool_type, dcr->pool_type)) { /* OK, compatible device */ Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name()); return 1; } else { /* Drive Pool not suitable for us */ Mmsg(jcr->errmsg, _( "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"), (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name, dev->num_reserved(), dev->print_name()); Dmsg1(dbglvl, "Failed: %s", jcr->errmsg); queue_reserve_message(jcr); } return 0; } static bool is_max_jobs_ok(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; Dmsg5(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Status=%s Vol=%s\n", dcr->VolCatInfo.VolCatMaxJobs, dcr->VolCatInfo.VolCatJobs, dev->num_reserved(), dcr->VolCatInfo.VolCatStatus, dcr->VolumeName); /* Limit max concurrent jobs on this drive */ if (dev->max_concurrent_jobs > 0 && dev->max_concurrent_jobs <= (uint32_t)(dev->num_writers + dev->num_reserved())) { /* Max Concurrent Jobs depassed or already reserved */ Mmsg(jcr->errmsg, _("3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n"), (uint32_t)jcr->JobId, dev->print_name()); Dmsg1(dbglvl, "Failed: %s", jcr->errmsg); queue_reserve_message(jcr); return false; } if (bstrcmp(dcr->VolCatInfo.VolCatStatus, "Recycle")) { return true; } if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <= (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) { /* Max Job Vols depassed or already reserved */ Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"), (uint32_t)jcr->JobId, dev->print_name()); Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg); queue_reserve_message(jcr); return false; /* wait */ } return true; } /* * Returns: 1 if drive can be reserved * 0 if we should wait * -1 on error or impossibility */ static int can_reserve_drive(DCR *dcr, RCTX &rctx) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n", rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device, rctx.autochanger_only, rctx.any_drive); /* Check for max jobs on this Volume */ if (!is_max_jobs_ok(dcr)) { return 0; } /* setting any_drive overrides PreferMountedVols flag */ if (!rctx.any_drive) { /* * When PreferMountedVols is set, we keep track of the * drive in use that has the least number of writers, then if * no unmounted drive is found, we try that drive. This * helps spread the load to the least used drives. */ if (rctx.try_low_use_drive && dev == rctx.low_use_drive) { Dmsg2(dbglvl, "OK dev=%s == low_drive=%s.\n", dev->print_name(), rctx.low_use_drive->print_name()); return 1; } /* If he wants a free drive, but this one is busy, no go */ if (!rctx.PreferMountedVols && dev->is_busy()) { /* Save least used drive */ if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) { rctx.num_writers = dev->num_writers + dev->num_reserved(); rctx.low_use_drive = dev; Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n", dev->print_name(), rctx.num_writers); } else { Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved()); } Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"), jcr->JobId, dev->print_name()); Dmsg1(dbglvl, "Failed: %s", jcr->errmsg); queue_reserve_message(jcr); return 0; } /* Check for prefer mounted volumes */ if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) { Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"), jcr->JobId, dev->print_name()); Dmsg1(dbglvl, "Failed: %s", jcr->errmsg); queue_reserve_message(jcr); return 0; /* No volume mounted */ } /* Check for exact Volume name match */ /* ***FIXME*** for Disk, we can accept any volume that goes with this * drive. */ if (rctx.exact_match && rctx.have_volume) { bool ok; Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n", rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device, rctx.autochanger_only, rctx.any_drive); Dmsg4(dbglvl, "have_vol=%d have=%s resvol=%s want=%s\n", rctx.have_volume, dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName); ok = bstrcmp(dev->VolHdr.VolumeName, rctx.VolumeName) || (dev->vol && bstrcmp(dev->vol->vol_name, rctx.VolumeName)); if (!ok) { Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"), jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName, dev->print_name()); queue_reserve_message(jcr); Dmsg3(dbglvl, "not OK: dev have=%s resvol=%s want=%s\n", dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName); return 0; } if (!dcr->can_i_use_volume()) { return 0; /* fail if volume on another drive */ } } } /* Check for unused autochanger drive */ if (rctx.autochanger_only && !dev->is_busy() && dev->VolHdr.VolumeName[0] == 0) { /* Device is available but not yet reserved, reserve it for us */ Dmsg1(dbglvl, "OK Res Unused autochanger %s.\n", dev->print_name()); bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name)); bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type)); return 1; /* reserve drive */ } /* * Handle the case that there are no writers */ if (dev->num_writers == 0) { /* Now check if there are any reservations on the drive */ if (dev->num_reserved()) { return is_pool_ok(dcr); } else if (dev->can_append()) { if (is_pool_ok(dcr)) { return 1; } else { /* Changing pool, unload old tape if any in drive */ Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n"); /* ***FIXME*** use set_unload() */ unload_autochanger(dcr, -1); } } /* Device is available but not yet reserved, reserve it for us */ Dmsg1(dbglvl, "OK Dev avail reserved %s\n", dev->print_name()); bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name)); bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type)); return 1; /* reserve drive */ } /* * Check if the device is in append mode with writers (i.e. available if pool is the same). */ if (dev->can_append() || dev->num_writers > 0) { return is_pool_ok(dcr); } else { Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId); Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"), jcr->JobId, dev->print_name()); queue_reserve_message(jcr); Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n")); return -1; /* error, should not get here */ } } /* * Queue a reservation error or failure message for this jcr */ static void queue_reserve_message(JCR *jcr) { int i; alist *msgs; char *msg; jcr->lock(); msgs = jcr->reserve_msgs; if (!msgs) { goto bail_out; } /* * Look for duplicate message. If found, do * not insert */ for (i=msgs->size()-1; i >= 0; i--) { msg = (char *)msgs->get(i); if (!msg) { goto bail_out; } /* Comparison based on 4 digit message number */ if (bstrncmp(msg, jcr->errmsg, 4)) { goto bail_out; } } /* Message unique, so insert it */ jcr->reserve_msgs->push(bstrdup(jcr->errmsg)); bail_out: jcr->unlock(); } /* * Send any reservation messages queued for this jcr */ void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg) { int i; alist *msgs; char *msg; jcr->lock(); msgs = jcr->reserve_msgs; if (!msgs || msgs->size() == 0) { goto bail_out; } for (i=msgs->size()-1; i >= 0; i--) { msg = (char *)msgs->get(i); if (msg) { sendit(" ", 3, arg); sendit(msg, strlen(msg), arg); } else { break; } } bail_out: jcr->unlock(); } /* * Pop and release any reservations messages */ static void pop_reserve_messages(JCR *jcr) { alist *msgs; char *msg; jcr->lock(); msgs = jcr->reserve_msgs; if (!msgs) { goto bail_out; } while ((msg = (char *)msgs->pop())) { free(msg); } bail_out: jcr->unlock(); } /* * Also called from acquire.c */ void release_reserve_messages(JCR *jcr) { pop_reserve_messages(jcr); jcr->lock(); if (!jcr->reserve_msgs) { goto bail_out; } delete jcr->reserve_msgs; jcr->reserve_msgs = NULL; bail_out: jcr->unlock(); } bareos-Release-14.2.6/src/stored/reserve.h000066400000000000000000000045431263011562700203610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Definitions for reservation system. * * Kern Sibbald, February MMVI */ /* * Use Device command from Director * The DIR tells us what Device Name to use, the Media Type, * the Pool Name, and the Pool Type. * * Ensure that the device exists and is opened, then store * the media and pool info in the JCR. This class is used * only temporarily in this file. */ class DIRSTORE { public: alist *device; bool append; char name[MAX_NAME_LENGTH]; char media_type[MAX_NAME_LENGTH]; char pool_name[MAX_NAME_LENGTH]; char pool_type[MAX_NAME_LENGTH]; }; /* Reserve context */ class RCTX { public: JCR *jcr; char *device_name; DIRSTORE *store; DEVRES *device; DEVICE *low_use_drive; /* Low use drive candidate */ int num_writers; /* for selecting low use drive */ bool try_low_use_drive; /* see if low use drive available */ bool any_drive; /* Accept any drive if set */ bool PreferMountedVols; /* Prefer volumes already mounted */ bool exact_match; /* Want exact volume */ bool have_volume; /* Have DIR suggested vol name */ bool suitable_device; /* at least one device is suitable */ bool autochanger_only; /* look at autochangers only */ bool notify_dir; /* Notify DIR about device */ bool append; /* set if append device */ char VolumeName[MAX_NAME_LENGTH]; /* Vol name suggested by DIR */ }; bareos-Release-14.2.6/src/stored/scan.c000066400000000000000000000112541263011562700176220ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * scan.c scan a directory (on a removable file) for a valid * Volume name. If found, open the file for append. * * Kern Sibbald, MMVI */ #include "bareos.h" #include "stored.h" /* Forward referenced functions */ static bool is_volume_name_legal(char *name); bool DEVICE::scan_dir_for_volume(DCR *dcr) { DIR* dp; struct dirent *entry, *result; int name_max; char *mount_point; VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo; char VolumeName[MAX_NAME_LENGTH]; struct stat statp; bool found = false; POOL_MEM fname(PM_FNAME); bool need_slash = false; int len; dcrVolCatInfo = dcr->VolCatInfo; /* structure assignment */ devVolCatInfo = VolCatInfo; /* structure assignment */ bstrncpy(VolumeName, dcr->VolumeName, sizeof(VolumeName)); name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (device->mount_point) { mount_point = device->mount_point; } else { mount_point = device->device_name; } if (!(dp = opendir(mount_point))) { berrno be; dev_errno = errno; Dmsg3(29, "scan_dir_for_vol: failed to open dir %s (dev=%s), ERR=%s\n", mount_point, print_name(), be.bstrerror()); goto get_out; } len = strlen(mount_point); if (len > 0) { need_slash = !IsPathSeparator(mount_point[len - 1]); } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); for ( ;; ) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { dev_errno = EIO; Dmsg2(129, "scan_dir_for_vol: failed to find suitable file in dir %s (dev=%s)\n", mount_point, print_name()); break; } if (bstrcmp(result->d_name, ".") || bstrcmp(result->d_name, "..")) { continue; } if (!is_volume_name_legal(result->d_name)) { continue; } pm_strcpy(fname, mount_point); if (need_slash) { pm_strcat(fname, "/"); } pm_strcat(fname, result->d_name); if (lstat(fname.c_str(), &statp) != 0 || !S_ISREG(statp.st_mode)) { continue; /* ignore directories & special files */ } /* * OK, we got a different volume mounted. First save the * requested Volume info (dcr) structure, then query if * this volume is really OK. If not, put back the desired * volume name, mark it not in changer and continue. */ /* Check if this is a valid Volume in the pool */ bstrncpy(dcr->VolumeName, result->d_name, sizeof(dcr->VolumeName)); if (!dcr->dir_get_volume_info(GET_VOL_INFO_FOR_WRITE)) { continue; } /* This was not the volume we expected, but it is OK with * the Director, so use it. */ VolCatInfo = dcr->VolCatInfo; /* structure assignment */ found = true; break; /* got a Volume */ } free(entry); closedir(dp); get_out: if (!found) { /* Restore VolumeName we really wanted */ bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName)); dcr->VolCatInfo = dcrVolCatInfo; /* structure assignment */ VolCatInfo = devVolCatInfo; /* structure assignment */ } Dsm_check(100); return found; } /* * Check if the Volume name has legal characters * If ua is non-NULL send the message */ static bool is_volume_name_legal(char *name) { int len; const char *p; const char *accept = ":.-_/"; if (name[0] == '/') { return false; } /* Restrict the characters permitted in the Volume name */ for (p=name; *p; p++) { if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) { continue; } return false; } len = strlen(name); if (len >= MAX_NAME_LENGTH) { return false; } if (len == 0) { return false; } return true; } bareos-Release-14.2.6/src/stored/sd_backends.c000066400000000000000000000143431263011562700211400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dynamic loading of SD backend plugins. * * Marco van Wieringen, June 2014 */ #include "bareos.h" #include "stored.h" #if defined(HAVE_DYNAMIC_SD_BACKENDS) #include "sd_backends.h" #include #ifndef RTLD_NOW #define RTLD_NOW 2 #endif /* * All loaded backends. */ static alist *loaded_backends = NULL; static alist *backend_dirs = NULL; void sd_set_backend_dirs(alist *new_backend_dirs) { backend_dirs = new_backend_dirs; } static inline backend_interface_mapping_t *lookup_backend_interface_mapping(int device_type) { backend_interface_mapping_t *backend_interface_mapping; for (backend_interface_mapping = backend_interface_mappings; backend_interface_mapping->interface_name != NULL; backend_interface_mapping++) { /* * See if this is a match. */ if (backend_interface_mapping->interface_type_id == device_type) { return backend_interface_mapping; } } return NULL; } DEVICE *init_backend_dev(JCR *jcr, int device_type) { struct stat st; char *backend_dir; void *dl_handle = NULL; POOL_MEM shared_library_name(PM_FNAME); backend_interface_mapping_t *backend_interface_mapping; backend_shared_library_t *backend_shared_library; t_backend_instantiate backend_instantiate; t_flush_backend flush_backend; /* * For dynamic loading storage backends there must be a list of backend dirs set. */ if (!backend_dirs) { Jmsg(jcr, M_ABORT, 0, _("Catalog Backends Dir not configured.\n")); } backend_interface_mapping = lookup_backend_interface_mapping(device_type); if (backend_interface_mapping == NULL) { return (DEVICE *)NULL; } /* * See if the backend is already loaded. */ if (loaded_backends) { foreach_alist(backend_shared_library, loaded_backends) { if (backend_shared_library->interface_type_id == backend_interface_mapping->interface_type_id) { return backend_shared_library->backend_instantiate(jcr, device_type); } } } /* * This is a new backend try to use dynamic loading to load the backend library. */ foreach_alist(backend_dir, backend_dirs) { Mmsg(shared_library_name, "%s/libbareossd-%s%s", backend_dir, backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); Dmsg3(100, "init_backend_dev: testing backend %s/libbareossd-%s%s\n", backend_dir, backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); /* * Make sure the shared library with this name exists. */ if (stat(shared_library_name.c_str(), &st) == 0) { dl_handle = dlopen(shared_library_name.c_str(), RTLD_NOW); if (!dl_handle) { Jmsg(jcr, M_ERROR, 0, _("Unable to load shared library: %s ERR=%s\n"), shared_library_name.c_str(), NPRT(dlerror())); continue; } /* * Lookup the backend_instantiate function. */ backend_instantiate = (t_backend_instantiate)dlsym(dl_handle, "backend_instantiate"); if (backend_instantiate == NULL) { Jmsg(jcr, M_ERROR, 0, _("Lookup of backend_instantiate in shared library %s failed: ERR=%s\n"), shared_library_name.c_str(), NPRT(dlerror())); dlclose(dl_handle); dl_handle = NULL; continue; } /* * Lookup the flush_backend function. */ flush_backend = (t_flush_backend)dlsym(dl_handle, "flush_backend"); if (flush_backend == NULL) { Jmsg(jcr, M_ERROR, 0, _("Lookup of flush_backend in shared library %s failed: ERR=%s\n"), shared_library_name.c_str(), NPRT(dlerror())); dlclose(dl_handle); dl_handle = NULL; continue; } /* * We found the shared library and it has the right entry points. */ break; } } if (dl_handle) { /* * Create a new loaded shared library entry and tack it onto the list of loaded backend shared libs. */ backend_shared_library = (backend_shared_library_t *)malloc(sizeof(backend_shared_library_t)); backend_shared_library->interface_type_id = backend_interface_mapping->interface_type_id; backend_shared_library->handle = dl_handle; backend_shared_library->backend_instantiate = backend_instantiate; backend_shared_library->flush_backend = flush_backend; if (loaded_backends == NULL) { loaded_backends = New(alist(10, not_owned_by_alist)); } loaded_backends->append(backend_shared_library); return backend_shared_library->backend_instantiate(jcr, device_type); } else { Jmsg(jcr, M_ABORT, 0, _("Unable to load any shared library for libbareossd-%s%s\n"), backend_interface_mapping->interface_name, DYN_LIB_EXTENSION); return (DEVICE *)NULL; } } void dev_flush_backends() { backend_shared_library_t *backend_shared_library; if (loaded_backends) { foreach_alist(backend_shared_library, loaded_backends) { /* * Call the flush entry point in the lib. */ backend_shared_library->flush_backend(); /* * Close the shared library and unload it. */ dlclose(backend_shared_library->handle); free(backend_shared_library); } delete loaded_backends; loaded_backends = NULL; } } #endif /* HAVE_DYNAMIC_SD_BACKENDS */ bareos-Release-14.2.6/src/stored/sd_backends.h000066400000000000000000000036461263011562700211510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2014-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Dynamic loading of SD backend plugins. * * Marco van Wieringen, June 2014 */ #ifndef __SD_BACKENDS_H_ #define __SD_BACKENDS_H_ 1 extern "C" { typedef DEVICE *(*t_backend_instantiate)(JCR *jcr, int device_type); typedef void (*t_flush_backend)(void); } /* * Loaded shared library with a certain backend interface type. */ struct backend_shared_library_t { int interface_type_id; void *handle; /* * Entry points into loaded shared library. */ t_backend_instantiate backend_instantiate; t_flush_backend flush_backend; }; #if defined(HAVE_WIN32) #define DYN_LIB_EXTENSION ".dll" #elif defined(HAVE_DARWIN_OS) #define DYN_LIB_EXTENSION ".dylib" #else #define DYN_LIB_EXTENSION ".so" #endif /* * Known backend to interface mappings. */ static struct backend_interface_mapping_t { int interface_type_id; const char *interface_name; } backend_interface_mappings[] = { { B_FIFO_DEV, "fifo" }, { B_TAPE_DEV, "tape" }, { B_GFAPI_DEV, "gfapi" }, { B_OBJECT_STORE_DEV, "object" }, { B_RADOS_DEV, "rados" }, { B_CEPHFS_DEV, "cephfs" }, { 0, NULL } }; #endif /* __SD_DYNAMIC_H_ */ bareos-Release-14.2.6/src/stored/sd_cmds.c000066400000000000000000000241761263011562700203210ustar00rootroot00000000000000/* BAREOS - Backup Archiving REcovery Open Sourced Copyright (C) 2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file handles commands from an other Storage daemon. * * Marco van Wieringen, November 2012 * * We get here because the Director has initiated a Job with * an other Storage daemon, then done the same with this * Storage daemon. When the Storage daemon receives a proper * connection from the other Storage daemon, control is * passed here to handle the subsequent Storage daemon commands. */ #include "bareos.h" #include "stored.h" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Imported variables */ /* Static variables */ static char serrmsg[] = "3900 Invalid command\n"; /* Imported functions */ /* Forward referenced SD commands */ static bool start_replication_session(JCR *jcr); static bool replicate_data(JCR *jcr); static bool end_replication_session(JCR *jcr); struct s_cmds { const char *cmd; bool (*func)(JCR *jcr); }; /* * The following are the recognized commands from the Remote Storage daemon */ static struct s_cmds sd_cmds[] = { { "start replicate", start_replication_session }, { "replicate data", replicate_data }, { "end replicate", end_replication_session }, { NULL, NULL } /* list terminator */ }; /* * Responses sent to the Remote Storage daemon */ static char NO_open[] = "3901 Error replicate session already open\n"; static char NOT_opened[] = "3902 Error replicate session not opened\n"; static char ERROR_replicate[] = "3903 Error replicate data\n"; static char OK_end_replicate[] = "3000 OK end replicate\n"; static char OK_start_replicate[] = "3000 OK start replicate ticket = %d\n"; /* * Responses sent to the Director */ static char Job_start[] = "3010 Job %s start\n"; static char Job_end[] = "3099 Job %s end JobStatus=%d JobFiles=%d JobBytes=%s JobErrors=%u\n"; /* * After receiving a connection (in dircmd.c) if it is * from the Storage daemon, this routine is called. */ void *handle_stored_connection(BSOCK *sd, char *job_name) { JCR *jcr; /* * With the following bmicrosleep on, running the * SD under the debugger fails. */ // bmicrosleep(0, 50000); /* wait 50 millisecs */ if (!(jcr = get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("SD connect failed: Job name not found: %s\n"), job_name); Dmsg1(3, "**** Job \"%s\" not found.\n", job_name); sd->close(); delete sd; return NULL; } Dmsg1(50, "Found Job %s\n", job_name); if (jcr->authenticated) { Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"), (uint32_t)jcr->JobId, jcr->Job); Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n", (uint32_t)jcr->JobId, jcr->Job); sd->close(); delete sd; free_jcr(jcr); return NULL; } jcr->store_bsock = sd; jcr->store_bsock->set_jcr(jcr); /* * Authenticate the Storage daemon */ if (jcr->authenticated || !authenticate_storagedaemon(jcr)) { Dmsg1(50, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Storage daemon\n")); } else { jcr->authenticated = true; Dmsg2(50, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job); } if (!jcr->authenticated) { jcr->setJobStatus(JS_ErrorTerminated); } pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */ free_jcr(jcr); return NULL; } /* * Now talk to the SD and do what he says */ static void do_sd_commands(JCR *jcr) { int i, status; bool found, quit; BSOCK *sd = jcr->store_bsock; sd->set_jcr(jcr); quit = false; while (!quit) { /* * Read command coming from the Storage daemon */ status = sd->recv(); if (is_bnet_stop(sd)) { /* hardeof or error */ break; /* connection terminated */ } if (status <= 0) { continue; /* ignore signals and zero length msgs */ } Dmsg1(110, "msg); found = false; for (i = 0; sd_cmds[i].cmd; i++) { if (bstrncmp(sd_cmds[i].cmd, sd->msg, strlen(sd_cmds[i].cmd))) { found = true; /* indicate command found */ jcr->errmsg[0] = 0; if (!sd_cmds[i].func(jcr)) { /* do command */ /* * Note sd->msg command may be destroyed by comm activity */ if (!job_canceled(jcr)) { if (jcr->errmsg[0]) { Jmsg1(jcr, M_FATAL, 0, _("Command error with SD, hanging up. %s\n"), jcr->errmsg); } else { Jmsg0(jcr, M_FATAL, 0, _("Command error with SD, hanging up.\n")); } jcr->setJobStatus(JS_ErrorTerminated); } quit = true; } break; } } if (!found) { /* command not found */ if (!job_canceled(jcr)) { Jmsg1(jcr, M_FATAL, 0, _("SD command not found: %s\n"), sd->msg); Dmsg1(110, "msg); } sd->fsend(serrmsg); break; } } sd->signal(BNET_TERMINATE); /* signal to SD job is done */ } /* * Run a Storage daemon replicate Job -- Wait for remote Storage daemon * to connect and authenticate it we then will get a wakeup sign using * the job_start_wait conditional * * Director sends us this command. * * Basic task here is: * - Read a command from the Storage daemon * - Execute it */ bool do_listen_run(JCR *jcr) { char ec1[30]; int errstat = 0; BSOCK *dir = jcr->dir_bsock; jcr->sendJobStatus(JS_WaitSD); /* wait for SD to connect */ Dmsg2(50, "%s waiting for SD to contact SD key=%s\n", jcr->Job, jcr->sd_auth_key); Dmsg2(800, "Wait SD for jid=%d %p\n", jcr->JobId, jcr); /* * Wait for the Storage daemon to contact us to start the Job, when he does, we will be released. */ P(mutex); while (!jcr->authenticated && !job_canceled(jcr)) { errstat = pthread_cond_wait(&jcr->job_start_wait, &mutex); if (errstat == EINVAL || errstat == EPERM) { break; } Dmsg1(800, "=== Auth cond errstat=%d\n", errstat); } Dmsg3(50, "Auth=%d canceled=%d errstat=%d\n", jcr->authenticated, job_canceled(jcr), errstat); V(mutex); if (!jcr->authenticated || !jcr->store_bsock) { Dmsg2(800, "Auth fail or cancel for jid=%d %p\n", jcr->JobId, jcr); dequeue_messages(jcr); /* send any queued messages */ goto cleanup; } Dmsg1(120, "Start run Job=%s\n", jcr->Job); dir->fsend(Job_start, jcr->Job); jcr->start_time = time(NULL); jcr->run_time = jcr->start_time; jcr->sendJobStatus(JS_Running); /* * See if we need to limit the inbound bandwidth. */ if (me->max_bandwidth_per_job && jcr->store_bsock) { jcr->store_bsock->set_bwlimit(me->max_bandwidth_per_job); if (me->allow_bw_bursting) { jcr->store_bsock->set_bwlimit_bursting(); } } do_sd_commands(jcr); jcr->end_time = time(NULL); dequeue_messages(jcr); /* send any queued messages */ jcr->setJobStatus(JS_Terminated); cleanup: generate_plugin_event(jcr, bsdEventJobEnd); dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors); dir->signal(BNET_EOD); /* send EOD to Director daemon */ free_plugins(jcr); /* release instantiated plugins */ /* * After a listen cmd we are done e.g. return false. */ return false; } /* * Start of replication. */ static bool start_replication_session(JCR *jcr) { BSOCK *sd = jcr->store_bsock; Dmsg1(120, "Start replication session: %s", sd->msg); if (jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to open already open session.\n")); sd->fsend(NO_open); return false; } jcr->session_opened = true; /* * Send "Ticket" to Storage Daemon */ sd->fsend(OK_start_replicate, jcr->VolSessionId); Dmsg1(110, ">stored: %s", sd->msg); return true; } /* * Replicate data. * Open Data Channel and receive Data for archiving * Write the Data to the archive device */ static bool replicate_data(JCR *jcr) { BSOCK *sd = jcr->store_bsock; Dmsg1(120, "Replicate data: %s", sd->msg); if (jcr->session_opened) { utime_t now; /* * Update the initial Job Statistics. */ now = (utime_t)time(NULL); update_job_statistics(jcr, now); Dmsg1(110, "msg); if (do_append_data(jcr, sd, "SD")) { return true; } else { pm_strcpy(jcr->errmsg, _("Replicate data error.\n")); bnet_suppress_error_messages(sd, 1); /* ignore errors at this point */ sd->fsend(ERROR_replicate); } } else { pm_strcpy(jcr->errmsg, _("Attempt to replicate on non-open session.\n")); sd->fsend(NOT_opened); } return false; } /* * End a replication session. */ static bool end_replication_session(JCR *jcr) { BSOCK *sd = jcr->store_bsock; Dmsg1(120, "storedmsg); if (!jcr->session_opened) { pm_strcpy(jcr->errmsg, _("Attempt to close non-open session.\n")); sd->fsend(NOT_opened); return false; } return sd->fsend(OK_end_replicate); } bareos-Release-14.2.6/src/stored/sd_plugins.c000066400000000000000000000575661263011562700210650ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Bareos pluginloader * * Kern Sibbald, October 2007 */ #include "bareos.h" #include "stored.h" #include "sd_plugins.h" #include "lib/crypto_cache.h" const int dbglvl = 250; const char *plugin_type = "-sd.so"; static alist *sd_plugin_list = NULL; /* Forward referenced functions */ static bRC bareosGetValue(bpContext *ctx, bsdrVariable var, void *value); static bRC bareosSetValue(bpContext *ctx, bsdwVariable var, void *value); static bRC bareosRegisterEvents(bpContext *ctx, int nr_events, ...); static bRC bareosJobMsg(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); static bRC bareosDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); static char *bareosEditDeviceCodes(DCR *dcr, char *omsg, const char *imsg, const char *cmd); static char *bareosLookupCryptoKey(const char *VolumeName); static bool bareosUpdateVolumeInfo(DCR *dcr); static void bareosUpdateTapeAlert(DCR *dcr, uint64_t flags); static DEV_RECORD *bareosNewRecord(bool with_data); static void bareosCopyRecordState(DEV_RECORD *dst, DEV_RECORD *src); static void bareosFreeRecord(DEV_RECORD *rec); static bool is_plugin_compatible(Plugin *plugin); /* Bareos info */ static bsdInfo binfo = { sizeof(bsdFuncs), SD_PLUGIN_INTERFACE_VERSION }; /* Bareos entry points */ static bsdFuncs bfuncs = { sizeof(bsdFuncs), SD_PLUGIN_INTERFACE_VERSION, bareosRegisterEvents, bareosGetValue, bareosSetValue, bareosJobMsg, bareosDebugMsg, bareosEditDeviceCodes, bareosLookupCryptoKey, bareosUpdateVolumeInfo, bareosUpdateTapeAlert, bareosNewRecord, bareosCopyRecordState, bareosFreeRecord }; /* * Bareos private context */ struct b_plugin_ctx { JCR *jcr; /* jcr for plugin */ bRC rc; /* last return code */ bool disabled; /* set if plugin disabled */ char events[nbytes_for_bits(SD_NR_EVENTS + 1)]; /* enabled events bitmask */ }; static inline bool is_event_enabled(bpContext *ctx, bsdEventType eventType) { b_plugin_ctx *b_ctx; if (!ctx) { return true; } b_ctx = (b_plugin_ctx *)ctx->bContext; if (!b_ctx) { return true; } return bit_is_set(eventType, b_ctx->events); } static inline bool is_plugin_disabled(bpContext *ctx) { b_plugin_ctx *b_ctx; if (!ctx) { return true; } b_ctx = (b_plugin_ctx *)ctx->bContext; return b_ctx->disabled; } #ifdef needed static inline bool is_plugin_disabled(JCR *jcr) { return is_plugin_disabled(jcr->plugin_ctx); } #endif /* * Edit codes into ChangerCommand * %% = % * %a = Archive device name * %c = Changer device name * %D = Diagnostic device name * %d = Changer drive index * %f = Client's name * %j = Job name * %o = Command * %s = Slot base 0 * %S = Slot base 1 * %v = Volume name * * * omsg = edited output message * imsg = input string containing edit codes (%x) * cmd = command string (load, unload, ...) * */ char *edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd) { const char *p; const char *str; char ed1[50]; *omsg = 0; Dmsg1(1800, "edit_device_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'a': str = dcr->dev->archive_name(); break; case 'c': str = NPRT(dcr->device->changer_name); break; case 'D': str = NPRT(dcr->device->diag_device_name); break; case 'd': str = edit_int64(dcr->dev->drive_index, ed1); break; case 'o': str = NPRT(cmd); break; case 's': str = edit_int64(dcr->VolCatInfo.Slot - 1, ed1); break; case 'S': str = edit_int64(dcr->VolCatInfo.Slot, ed1); break; case 'j': /* Job name */ str = dcr->jcr->Job; break; case 'v': if (dcr->VolCatInfo.VolCatName[0]) { str = dcr->VolCatInfo.VolCatName; } else if (dcr->VolumeName[0]) { str = dcr->VolumeName; } else if (dcr->dev->vol && dcr->dev->vol->vol_name) { str = dcr->dev->vol->vol_name; } else { str = dcr->dev->VolHdr.VolumeName; } break; case 'f': str = NPRT(dcr->jcr->client_name); break; default: ed1[0] = '%'; ed1[1] = *p; ed1[2] = 0; str = ed1; break; } } else { ed1[0] = *p; ed1[1] = 0; str = ed1; } Dmsg1(1900, "add_str %s\n", str); pm_strcat(&omsg, (char *)str); Dmsg1(1800, "omsg=%s\n", omsg); } Dmsg1(800, "omsg=%s\n", omsg); return omsg; } static inline bRC trigger_plugin_event(JCR *jcr, bsdEventType eventType, bsdEvent *event, bpContext *ctx, void *value) { if (!is_event_enabled(ctx, eventType)) { Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType); return bRC_OK; } if (is_plugin_disabled(ctx)) { Dmsg0(dbglvl, "Plugin disabled.\n"); return bRC_OK; } return sdplug_func(ctx->plugin)->handlePluginEvent(ctx, event, value); } /* * Create a plugin event */ int generate_plugin_event(JCR *jcr, bsdEventType eventType, void *value, bool reverse) { int i; bsdEvent event; alist *plugin_ctx_list; bRC rc = bRC_OK; if (!sd_plugin_list) { Dmsg0(dbglvl, "No bplugin_list: generate_plugin_event ignored.\n"); return bRC_OK; } if (!jcr) { Dmsg0(dbglvl, "No jcr: generate_plugin_event ignored.\n"); return bRC_OK; } if (!jcr->plugin_ctx_list) { Dmsg0(dbglvl, "No plugin_ctx_list: generate_plugin_event ignored.\n"); return bRC_OK; /* Return if no plugins loaded */ } if (jcr->is_job_canceled()) { Dmsg0(dbglvl, "Cancel return from generate_plugin_event\n"); return bRC_Cancel; } plugin_ctx_list = jcr->plugin_ctx_list; event.eventType = eventType; Dmsg2(dbglvl, "sd-plugin_ctx_list=%p JobId=%d\n", plugin_ctx_list, jcr->JobId); /* * See if we need to trigger the loaded plugins in reverse order. */ if (reverse) { bpContext *ctx; foreach_alist_rindex(i, ctx, plugin_ctx_list) { rc = trigger_plugin_event(jcr, eventType, &event, ctx, value); if (rc != bRC_OK) { break; } } } else { bpContext *ctx; foreach_alist_index(i, ctx, plugin_ctx_list) { rc = trigger_plugin_event(jcr, eventType, &event, ctx, value); if (rc != bRC_OK) { break; } } } return rc; } /* * Print to file the plugin info. */ void dump_sd_plugin(Plugin *plugin, FILE *fp) { genpInfo *info; if (!plugin) { return ; } info = (genpInfo *) plugin->pinfo; fprintf(fp, "\tversion=%d\n", info->version); fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date)); fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic)); fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author)); fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license)); fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version)); fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description)); } static void dump_sd_plugins(FILE *fp) { dump_plugins(sd_plugin_list, fp); } /** * This entry point is called internally by Bareos to ensure * that the plugin IO calls come into this code. */ void load_sd_plugins(const char *plugin_dir, alist *plugin_names) { Plugin *plugin; int i; Dmsg0(dbglvl, "Load sd plugins\n"); if (!plugin_dir) { Dmsg0(dbglvl, "No sd plugin dir!\n"); return; } sd_plugin_list = New(alist(10, not_owned_by_alist)); if (!load_plugins((void *)&binfo, (void *)&bfuncs, sd_plugin_list, plugin_dir, plugin_names, plugin_type, is_plugin_compatible)) { /* * Either none found, or some error */ if (sd_plugin_list->size() == 0) { delete sd_plugin_list; sd_plugin_list = NULL; Dmsg0(dbglvl, "No plugins loaded\n"); return; } } /* * Verify that the plugin is acceptable, and print information about it. */ foreach_alist_index(i, plugin, sd_plugin_list) { Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); } Dmsg1(dbglvl, "num plugins=%d\n", sd_plugin_list->size()); dbg_plugin_add_hook(dump_sd_plugin); dbg_print_plugin_add_hook(dump_sd_plugins); } void unload_sd_plugins(void) { unload_plugins(sd_plugin_list); delete sd_plugin_list; sd_plugin_list = NULL; } int list_sd_plugins(POOL_MEM &msg) { return list_plugins(sd_plugin_list, msg); } /** * Check if a plugin is compatible. Called by the load_plugin function * to allow us to verify the plugin. */ static bool is_plugin_compatible(Plugin *plugin) { genpInfo *info = (genpInfo *)plugin->pinfo; Dmsg0(50, "is_plugin_compatible called\n"); if (debug_level >= 50) { dump_sd_plugin(plugin, stdin); } if (!bstrcmp(info->plugin_magic, SD_PLUGIN_MAGIC)) { Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), plugin->file, SD_PLUGIN_MAGIC, info->plugin_magic); Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", plugin->file, SD_PLUGIN_MAGIC, info->plugin_magic); return false; } if (info->version != SD_PLUGIN_INTERFACE_VERSION) { Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), plugin->file, SD_PLUGIN_INTERFACE_VERSION, info->version); Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", plugin->file, SD_PLUGIN_INTERFACE_VERSION, info->version); return false; } if (!bstrcasecmp(info->plugin_license, "Bareos AGPLv3") && !bstrcasecmp(info->plugin_license, "AGPLv3")) { Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), plugin->file, info->plugin_license); Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", plugin->file, info->plugin_license); return false; } if (info->size != sizeof(genpInfo)) { Jmsg(NULL, M_ERROR, 0, _("Plugin size incorrect. Plugin=%s wanted=%d got=%d\n"), plugin->file, sizeof(genpInfo), info->size); return false; } return true; } /* * Instantiate a new plugin instance. */ static inline bpContext *instantiate_plugin(JCR *jcr, Plugin *plugin, uint32_t instance) { bpContext *ctx; b_plugin_ctx *b_ctx; b_ctx = (b_plugin_ctx *)malloc(sizeof(b_plugin_ctx)); memset(b_ctx, 0, sizeof(b_plugin_ctx)); b_ctx->jcr = jcr; Dmsg2(dbglvl, "Instantiate dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); ctx = (bpContext *)malloc(sizeof(bpContext)); ctx->instance = instance; ctx->plugin = plugin; ctx->bContext = (void *)b_ctx; ctx->pContext = NULL; jcr->plugin_ctx_list->append(ctx); if (sdplug_func(plugin)->newPlugin(ctx) != bRC_OK) { b_ctx->disabled = true; } return ctx; } /* * Send a bsdEventNewPluginOptions event to all plugins configured in jcr->plugin_options. */ void dispatch_new_plugin_options(JCR *jcr) { int i, j, len; Plugin *plugin; bpContext *ctx; uint32_t instance; bsdEvent event; bsdEventType eventType; char *bp, *plugin_name, *option; const char *plugin_options; POOL_MEM priv_plugin_options(PM_MESSAGE); if (!sd_plugin_list || sd_plugin_list->empty()) { return; } if (jcr->plugin_options && jcr->plugin_options->size()) { eventType = bsdEventNewPluginOptions; event.eventType = eventType; foreach_alist_index(i, plugin_options, jcr->plugin_options) { /* * Make a private copy of plugin options. */ pm_strcpy(priv_plugin_options, plugin_options); plugin_name = priv_plugin_options.c_str(); if (!(bp = strchr(plugin_name, ':'))) { Jmsg(NULL, M_ERROR, 0, _("Illegal SD plugin options encountered, %s skipping\n"), priv_plugin_options.c_str()); continue; } *bp++ = '\0'; /* * See if there is any instance named in the options string. */ instance = 0; option = bp; while (option) { bp = strchr(bp, ':'); if (bp) { *bp++ = '\0'; } if (bstrncasecmp(option, "instance=", 9)) { instance = str_to_int64(option + 9); break; } option = bp; } if (instance < LOWEST_PLUGIN_INSTANCE || instance > HIGHEST_PLUGIN_INSTANCE) { Jmsg(NULL, M_ERROR, 0, _("Illegal SD plugin options encountered, %s instance %d skipping\n"), plugin_options, instance); continue; } len = strlen(plugin_name); /* * See if this plugin options are for an already instantiated plugin instance. */ foreach_alist(ctx, jcr->plugin_ctx_list) { if (ctx->instance == instance && ctx->plugin->file_len == len && bstrncasecmp(ctx->plugin->file, plugin_name, len)) { break; } } /* * Found a context in the previous loop ? */ if (!ctx) { foreach_alist_index(j, plugin, sd_plugin_list) { if (plugin->file_len == len && bstrncasecmp(plugin->file, plugin_name, len)) { ctx = instantiate_plugin(jcr, plugin, instance); break; } } } if (ctx) { trigger_plugin_event(jcr, eventType, &event, ctx, (void *)plugin_options); } } } } /* * Create a new instance of each plugin for this Job */ void new_plugins(JCR *jcr) { Plugin *plugin; int i, num; Dmsg0(dbglvl, "=== enter new_plugins ===\n"); if (!sd_plugin_list) { Dmsg0(dbglvl, "No sd plugin list!\n"); return; } if (jcr->is_job_canceled()) { return; } /* * If plugins already loaded, just return */ if (jcr->plugin_ctx_list) { return; } num = sd_plugin_list->size(); Dmsg1(dbglvl, "sd-plugin-list size=%d\n", num); if (num == 0) { return; } jcr->plugin_ctx_list = New(alist(10, owned_by_alist)); foreach_alist_index(i, plugin, sd_plugin_list) { /* * Start a new instance of each plugin */ instantiate_plugin(jcr, plugin, 0); } } /* * Free the plugin instances for this Job */ void free_plugins(JCR *jcr) { bpContext *ctx; if (!sd_plugin_list || !jcr->plugin_ctx_list) { return; } Dmsg2(dbglvl, "Free instance dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId); foreach_alist(ctx, jcr->plugin_ctx_list) { /* * Free the plugin instance */ sdplug_func(ctx->plugin)->freePlugin(ctx); free(ctx->bContext); /* Free BAREOS private context */ } delete jcr->plugin_ctx_list; jcr->plugin_ctx_list = NULL; } /* ============================================================== * * Callbacks from the plugin * * ============================================================== */ static bRC bareosGetValue(bpContext *ctx, bsdrVariable var, void *value) { JCR *jcr = NULL; bRC ret = bRC_OK; if (!value) { return bRC_Error; } switch (var) { /* General variables, no need of ctx */ case bsdVarCompatible: *((bool *)value) = me->compatible; Dmsg1(dbglvl, "sd-plugin: return bsdVarCompatible=%s\n", (me->compatible) ? "true" : "false"); break; case bsdVarPluginDir: *((char **)value) = me->plugin_directory; Dmsg1(dbglvl, "sd-plugin: return bsdVarPluginDir=%s\n", me->plugin_directory); break; default: if (!ctx) { return bRC_Error; } jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; if (!jcr) { return bRC_Error; } break; } if (jcr) { switch (var) { case bsdVarJob: *((char **)value) = jcr->job_name; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobName=%s\n", NPRT(*((char **)value))); break; case bsdVarLevel: *((int *)value) = jcr->getJobLevel(); Dmsg1(dbglvl, "sd-plugin: return bsdVarLevel=%c\n", jcr->getJobLevel()); break; case bsdVarType: *((int *)value) = jcr->getJobType(); Dmsg1(dbglvl, "sd-plugin: return bsdVarType=%c\n", jcr->getJobType()); break; case bsdVarJobId: *((int *)value) = jcr->JobId; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobId=%d\n", jcr->JobId); break; case bsdVarClient: *((char **)value) = jcr->client_name; Dmsg1(dbglvl, "sd-plugin: return bsdVarClient=%s\n", NPRT(*((char **)value))); break; case bsdVarPool: if (jcr->dcr) { *((char **)value) = jcr->dcr->pool_name; Dmsg1(dbglvl, "sd-plugin: return bsdVarPool=%s\n", NPRT(*((char **)value))); } else { ret = bRC_Error; } break; case bsdVarPoolType: if (jcr->dcr) { *((char **)value) = jcr->dcr->pool_type; Dmsg1(dbglvl, "sd-plugin: return bsdVarPoolType=%s\n", NPRT(*((char **)value))); } else { ret = bRC_Error; } break; case bsdVarStorage: if (jcr->dcr && jcr->dcr->device) { *((char **)value) = jcr->dcr->device->hdr.name; Dmsg1(dbglvl, "sd-plugin: return bsdVarStorage=%s\n", NPRT(*((char **)value))); } else { ret = bRC_Error; } break; case bsdVarMediaType: if (jcr->dcr) { *((char **)value) = jcr->dcr->media_type; Dmsg1(dbglvl, "sd-plugin: return bsdVarMediaType=%s\n", NPRT(*((char **)value))); } else { ret = bRC_Error; } break; case bsdVarJobName: *((char **)value) = jcr->Job; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobName=%s\n", NPRT(*((char **)value))); break; case bsdVarJobStatus: *((int *)value) = jcr->JobStatus; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobStatus=%c\n", jcr->JobStatus); break; case bsdVarVolumeName: if (jcr->dcr) { *((char **)value) = jcr->dcr->VolumeName; Dmsg1(dbglvl, "sd-plugin: return bsdVarVolumeName=%s\n", NPRT(*((char **)value))); } else { ret = bRC_Error; } Dmsg1(dbglvl, "sd-plugin: return bsdVarVolumeName=%s\n", jcr->VolumeName); break; case bsdVarJobErrors: *((int *)value) = jcr->JobErrors; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobErrors=%d\n", jcr->JobErrors); break; case bsdVarJobFiles: *((int *)value) = jcr->JobFiles; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobFiles=%d\n", jcr->JobFiles); break; case bsdVarJobBytes: *((uint64_t *)value) = jcr->JobBytes; Dmsg1(dbglvl, "sd-plugin: return bsdVarJobBytes=%d\n", jcr->JobBytes); break; default: break; } } return ret; } static bRC bareosSetValue(bpContext *ctx, bsdwVariable var, void *value) { JCR *jcr; if (!value || !ctx) { return bRC_Error; } jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; if (!jcr) { return bRC_Error; } Dmsg1(dbglvl, "sd-plugin: bareosSetValue var=%d\n", var); switch (var) { case bsdwVarVolumeName: pm_strcpy(jcr->VolumeName, ((char *)value)); break; case bsdwVarPriority: jcr->JobPriority = *((int *)value); break; case bsdwVarJobLevel: jcr->setJobLevel(*((int *)value)); break; default: break; } return bRC_OK; } static bRC bareosRegisterEvents(bpContext *ctx, int nr_events, ...) { int i; va_list args; uint32_t event; b_plugin_ctx *b_ctx; if (!ctx) { return bRC_Error; } b_ctx = (b_plugin_ctx *)ctx->bContext; va_start(args, nr_events); for (i = 0; i < nr_events; i++) { event = va_arg(args, uint32_t); Dmsg1(dbglvl, "sd-Plugin wants event=%u\n", event); set_bit(event, b_ctx->events); } va_end(args); return bRC_OK; } static bRC bareosJobMsg(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...) { JCR *jcr; va_list arg_ptr; POOL_MEM buffer(PM_MESSAGE); if (ctx) { jcr = ((b_plugin_ctx *)ctx->bContext)->jcr; } else { jcr = NULL; } va_start(arg_ptr, fmt); buffer.bvsprintf(fmt, arg_ptr); va_end(arg_ptr); Jmsg(jcr, type, mtime, "%s", buffer.c_str()); return bRC_OK; } static bRC bareosDebugMsg(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...) { va_list arg_ptr; POOL_MEM buffer(PM_MESSAGE); va_start(arg_ptr, fmt); buffer.bvsprintf(fmt, arg_ptr); va_end(arg_ptr); d_msg(file, line, level, "%s", buffer.c_str()); return bRC_OK; } static char *bareosEditDeviceCodes(DCR *dcr, char *omsg, const char *imsg, const char *cmd) { return edit_device_codes(dcr, omsg, imsg, cmd); } static char *bareosLookupCryptoKey(const char *VolumeName) { return lookup_crypto_cache_entry(VolumeName); } static bool bareosUpdateVolumeInfo(DCR *dcr) { return dcr->dir_get_volume_info(GET_VOL_INFO_FOR_READ); } static void bareosUpdateTapeAlert(DCR *dcr, uint64_t flags) { utime_t now; now = (utime_t)time(NULL); update_device_tapealert(dcr->device->hdr.name, flags, now); } static DEV_RECORD *bareosNewRecord(bool with_data) { return new_record(with_data); } static void bareosCopyRecordState(DEV_RECORD *dst, DEV_RECORD *src) { copy_record_state(dst, src); } static void bareosFreeRecord(DEV_RECORD *rec) { free_record(rec); } #ifdef TEST_PROGRAM int main(int argc, char *argv[]) { char plugin_dir[1000]; JCR mjcr1, mjcr2; JCR *jcr1 = &mjcr1; JCR *jcr2 = &mjcr2; my_name_is(argc, argv, "plugtest"); init_msg(NULL, NULL); OSDependentInit(); if (argc != 1) { bstrncpy(plugin_dir, argv[1], sizeof(plugin_dir)); } else { getcwd(plugin_dir, sizeof(plugin_dir)-1); } load_sd_plugins(plugin_dir, NULL); jcr1->JobId = 111; new_plugins(jcr1); jcr2->JobId = 222; new_plugins(jcr2); generate_plugin_event(jcr1, bsdEventJobStart, (void *)"Start Job 1"); generate_plugin_event(jcr1, bsdEventJobEnd); generate_plugin_event(jcr2, bsdEventJobStart, (void *)"Start Job 1"); free_plugins(jcr1); generate_plugin_event(jcr2, bsdEventJobEnd); free_plugins(jcr2); unload_sd_plugins(); term_msg(); close_memory_pool(); lmgr_cleanup_main(); sm_dump(false); exit(0); } #endif /* TEST_PROGRAM */ bareos-Release-14.2.6/src/stored/sd_plugins.h000066400000000000000000000141701263011562700210520ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Interface definition for Bareos SD Plugins * * Kern Sibbald, October 2007 */ #ifndef __SD_PLUGINS_H #define __SD_PLUGINS_H #ifndef _BAREOS_H #ifdef __cplusplus /* Workaround for SGI IRIX 6.5 */ #define _LANGUAGE_C_PLUS_PLUS 1 #endif #define _REENTRANT 1 #define _THREAD_SAFE 1 #define _POSIX_PTHREAD_SEMANTICS 1 #define _FILE_OFFSET_BITS 64 #define _LARGEFILE_SOURCE 1 #define _LARGE_FILES 1 #endif #include #include "hostconfig.h" #include "bc_types.h" #include "lib/plugins.h" /**************************************************************************** * * * Bareos definitions * * * ****************************************************************************/ /* * Bareos Variable Ids (Read) */ typedef enum { bsdVarJob = 1, bsdVarLevel = 2, bsdVarType = 3, bsdVarJobId = 4, bsdVarClient = 5, bsdVarPool = 6, bsdVarPoolType = 7, bsdVarStorage = 8, bsdVarMediaType = 9, bsdVarJobName = 10, bsdVarJobStatus = 11, bsdVarVolumeName = 12, bsdVarJobErrors = 13, bsdVarJobFiles = 14, bsdVarJobBytes = 15, bsdVarCompatible = 16, bsdVarPluginDir = 17 } bsdrVariable; /* * Bareos Variable Ids (Write) */ typedef enum { bsdwVarJobReport = 1, bsdwVarVolumeName = 2, bsdwVarPriority = 3, bsdwVarJobLevel = 4 } bsdwVariable; /* * Events that are passed to plugin */ typedef enum { bsdEventJobStart = 1, bsdEventJobEnd = 2, bsdEventDeviceInit = 3, bsdEventDeviceMount = 4, bsdEventVolumeLoad = 5, bsdEventDeviceTryOpen = 6, bsdEventDeviceOpen = 7, bsdEventLabelRead = 8, bsdEventLabelVerified = 9, bsdEventLabelWrite = 10, bsdEventDeviceClose = 11, bsdEventVolumeUnload = 12, bsdEventDeviceUnmount = 13, bsdEventReadError = 14, bsdEventWriteError = 15, bsdEventDriveStatus = 16, bsdEventVolumeStatus = 17, bsdEventSetupRecordTranslation = 18, bsdEventReadRecordTranslation = 19, bsdEventWriteRecordTranslation = 20, bsdEventDeviceReleased = 21, bsdEventNewPluginOptions = 22 } bsdEventType; #define SD_NR_EVENTS bsdEventNewPluginOptions /* keep this updated ! */ typedef struct s_bsdEvent { uint32_t eventType; } bsdEvent; typedef struct s_sdbareosInfo { uint32_t size; uint32_t version; } bsdInfo; #ifdef __cplusplus extern "C" { #endif /* * Bareos interface version and function pointers */ class DCR; struct DEV_RECORD; typedef struct s_sdbareosFuncs { uint32_t size; uint32_t version; bRC (*registerBareosEvents)(bpContext *ctx, int nr_events, ...); bRC (*getBareosValue)(bpContext *ctx, bsdrVariable var, void *value); bRC (*setBareosValue)(bpContext *ctx, bsdwVariable var, void *value); bRC (*JobMessage)(bpContext *ctx, const char *file, int line, int type, utime_t mtime, const char *fmt, ...); bRC (*DebugMessage)(bpContext *ctx, const char *file, int line, int level, const char *fmt, ...); char *(*EditDeviceCodes)(DCR *dcr, char *omsg, const char *imsg, const char *cmd); char *(*LookupCryptoKey)(const char *VolumeName); bool (*UpdateVolumeInfo)(DCR *dcr); void (*UpdateTapeAlert)(DCR *dcr, uint64_t flags); DEV_RECORD *(*new_record)(bool with_data); void (*copy_record_state)(DEV_RECORD *dst, DEV_RECORD *src); void (*free_record)(DEV_RECORD *rec); } bsdFuncs; /* * Bareos Core Routines -- not used within a plugin */ #ifdef STORAGE_DAEMON void load_sd_plugins(const char *plugin_dir, alist *plugin_names); void unload_sd_plugins(void); int list_sd_plugins(POOL_MEM &msg); void dispatch_new_plugin_options(JCR *jcr); void new_plugins(JCR *jcr); void free_plugins(JCR *jcr); int generate_plugin_event(JCR *jcr, bsdEventType event, void *value = NULL, bool reverse = false); #endif /**************************************************************************** * * * Plugin definitions * * * ****************************************************************************/ typedef enum { psdVarName = 1, psdVarDescription = 2 } psdVariable; #define SD_PLUGIN_MAGIC "*SDPluginData*" #define SD_PLUGIN_INTERFACE_VERSION 3 /* * Functions that must be defined in every plugin */ typedef struct s_sdpluginFuncs { uint32_t size; uint32_t version; bRC (*newPlugin)(bpContext *ctx); bRC (*freePlugin)(bpContext *ctx); bRC (*getPluginValue)(bpContext *ctx, psdVariable var, void *value); bRC (*setPluginValue)(bpContext *ctx, psdVariable var, void *value); bRC (*handlePluginEvent)(bpContext *ctx, bsdEvent *event, void *value); } psdFuncs; #define sdplug_func(plugin) ((psdFuncs *)(plugin->pfuncs)) #define sdplug_info(plugin) ((genpInfo *)(plugin->pinfo)) class DEVRES; typedef struct s_sdbareosDevStatTrigger { DEVRES *device; POOLMEM *status; int status_length; } bsdDevStatTrig; #ifdef __cplusplus } #endif #endif /* __SD_PLUGINS_H */ bareos-Release-14.2.6/src/stored/sd_stats.c000066400000000000000000000421341263011562700205230ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Storage Daemon statistics gatherer. * * Written by Marco van Wieringen and Philipp Storz, November 2013 */ #include "bareos.h" #include "stored.h" static char OKstats[] = "2000 OK statistics\n"; static char DevStats[] = "Devicestats [%lld]: Device=%s Read=%llu, Write=%llu, SpoolSize=%llu, NumWaiting=%ld, NumWriters=%ld, " "ReadTime=%lld, WriteTime=%lld, MediaId=%ld, VolBytes=%llu, VolFiles=%llu, VolBlocks=%llu\n"; static char TapeAlerts[] = "Tapealerts [%lld]: Device=%s TapeAlert=%llu\n"; static char JobStats[] = "Jobstats [%lld]: JobId=%ld, JobFiles=%lu, JobBytes=%llu, DevName=%s\n"; /* Static globals */ static bool quit = false; static bool statistics_initialized = false; static pthread_t statistics_tid; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t wait_for_next_run = PTHREAD_COND_INITIALIZER; struct device_statistic { dlink link; bool collected; utime_t timestamp; btime_t DevReadTime; btime_t DevWriteTime; uint64_t DevWriteBytes; uint64_t DevReadBytes; uint64_t spool_size; int num_waiting; int num_writers; DBId_t MediaId; uint64_t VolCatBytes; uint64_t VolCatFiles; uint64_t VolCatBlocks; }; struct device_tapealert { dlink link; utime_t timestamp; uint64_t flags; }; struct device_statistics { dlink link; char DevName[MAX_NAME_LENGTH]; struct device_statistic *cached; dlist *statistics; dlist *tapealerts; }; struct job_statistic { dlink link; bool collected; utime_t timestamp; uint32_t JobFiles; uint64_t JobBytes; char *DevName; }; struct job_statistics { dlink link; uint32_t JobId; struct job_statistic *cached; dlist *statistics; }; static dlist *device_statistics = NULL; static dlist *job_statistics = NULL; static inline void setup_statistics() { struct device_statistics *dev_stats = NULL; struct job_statistics *job_stats = NULL; device_statistics = New(dlist(dev_stats, &dev_stats->link)); job_statistics = New(dlist(job_stats, &job_stats->link)); } void update_device_tapealert(const char *devname, uint64_t flags, utime_t now) { bool found = false; struct device_statistics *dev_stats = NULL; struct device_tapealert *tape_alert = NULL; if (!me || !me->collect_dev_stats || !device_statistics) { return; } foreach_dlist(dev_stats, device_statistics) { if (bstrcmp(dev_stats->DevName, devname)) { found = true; break; } } if (!found) { dev_stats = (struct device_statistics *)malloc(sizeof(struct device_statistics)); memset(dev_stats, 0, sizeof(struct device_statistics)); bstrncpy(dev_stats->DevName, devname, sizeof(dev_stats->DevName)); P(mutex); device_statistics->append(dev_stats); V(mutex); } /* * Add a new tapealert message. */ tape_alert = (struct device_tapealert *)malloc(sizeof(struct device_tapealert)); memset(tape_alert, 0, sizeof(struct device_tapealert)); tape_alert->timestamp = now; tape_alert->flags = flags; if (!dev_stats->tapealerts) { dev_stats->tapealerts = New(dlist(tape_alert, &tape_alert->link)); } P(mutex); dev_stats->tapealerts->append(tape_alert); V(mutex); Dmsg3(200, "New stats [%lld]: Device %s TapeAlert %llu\n", tape_alert->timestamp, dev_stats->DevName, tape_alert->flags); } static inline void update_device_statistics(const char *devname, DEVICE *dev, utime_t now) { bool found = false; struct device_statistics *dev_stats = NULL; struct device_statistic *dev_stat = NULL; if (!me || !me->collect_dev_stats || !device_statistics) { return; } /* * See if we already have statistics for this device. */ foreach_dlist(dev_stats, device_statistics) { if (bstrcmp(dev_stats->DevName, devname)) { found = true; break; } } /* * If we have statistics and the cached entry is filled it points * to the latest sampled statistics so we compare them with the current * statistics and if nothing changed we just return. */ if (found && dev_stats->cached) { dev_stat = dev_stats->cached; if (dev_stat->DevReadBytes == dev->DevReadBytes && dev_stat->DevWriteBytes == dev->DevWriteBytes && dev_stat->spool_size == dev->spool_size) { return; } } else if (!found) { dev_stats = (struct device_statistics *)malloc(sizeof(struct device_statistics)); memset(dev_stats, 0, sizeof(struct device_statistics)); bstrncpy(dev_stats->DevName, devname, sizeof(dev_stats->DevName)); P(mutex); device_statistics->append(dev_stats); V(mutex); } /* * Add a new set of statistics. */ dev_stat = (struct device_statistic *)malloc(sizeof(struct device_statistic)); memset(dev_stat, 0, sizeof(struct device_statistic)); dev_stat->timestamp = now; dev_stat->DevReadTime = dev->DevReadTime; dev_stat->DevWriteTime = dev->DevWriteTime; dev_stat->DevWriteBytes = dev->DevWriteBytes; dev_stat->DevReadBytes = dev->DevReadBytes; dev_stat->spool_size = dev->spool_size; dev_stat->num_waiting = dev->num_waiting; dev_stat->num_writers = dev->num_writers; dev_stat->MediaId = dev->VolCatInfo.VolMediaId; dev_stat->VolCatBytes = dev->VolCatInfo.VolCatBytes; dev_stat->VolCatFiles = dev->VolCatInfo.VolCatFiles; dev_stat->VolCatBlocks = dev->VolCatInfo.VolCatBlocks; if (!dev_stats->statistics) { dev_stats->statistics = New(dlist(dev_stat, &dev_stat->link)); } P(mutex); dev_stats->cached = dev_stat; dev_stats->statistics->append(dev_stat); V(mutex); Dmsg5(200, "New stats [%lld]: Device %s Read %llu, Write %llu, Spoolsize %llu,\n", dev_stat->timestamp, dev_stats->DevName, dev_stat->DevReadBytes, dev_stat->DevWriteBytes, dev_stat->spool_size); Dmsg4(200, "NumWaiting %ld, NumWriters %ld, ReadTime=%lld, WriteTime=%lld,\n", dev_stat->num_waiting, dev_stat->num_writers, dev_stat->DevReadTime, dev_stat->DevWriteTime); Dmsg4(200, "MediaId=%ld VolBytes=%llu, VolFiles=%llu, VolBlocks=%llu\n", dev_stat->MediaId, dev_stat->VolCatBytes, dev_stat->VolCatFiles, dev_stat->VolCatBlocks); } void update_job_statistics(JCR *jcr, utime_t now) { bool found = false; struct job_statistics *job_stats = NULL; struct job_statistic *job_stat = NULL; if (!me || !me->collect_job_stats || !job_statistics) { return; } /* * Skip job 0 info */ if (!jcr->JobId) { return; } /* * See if we already have statistics for this job. */ foreach_dlist(job_stats, job_statistics) { if (job_stats->JobId == jcr->JobId) { found = true; break; } } /* * If we have statistics and the cached entry is filled it points * to the latest sampled statistics so we compare them with the current * statistics and if nothing changed we just return. */ if (found && job_stats->cached) { job_stat = job_stats->cached; if (job_stat->JobFiles == jcr->JobFiles && job_stat->JobBytes == jcr->JobBytes) { return; } } else if (!found) { job_stats = (struct job_statistics *)malloc(sizeof(struct job_statistics)); memset(job_stats, 0, sizeof(struct job_statistics)); job_stats->JobId = jcr->JobId; P(mutex); job_statistics->append(job_stats); V(mutex); } /* * Add a new set of statistics. */ job_stat = (struct job_statistic *)malloc(sizeof(struct job_statistic)); memset(job_stat, 0, sizeof(struct job_statistic)); job_stat->timestamp = now; job_stat->JobFiles = jcr->JobFiles; job_stat->JobBytes = jcr->JobBytes; if (jcr->dcr) { job_stat->DevName = bstrdup(jcr->dcr->device->hdr.name); } else { job_stat->DevName = bstrdup("unknown"); } if (!job_stats->statistics) { job_stats->statistics = New(dlist(job_stat, &job_stat->link)); } P(mutex); job_stats->cached = job_stat; job_stats->statistics->append(job_stat); V(mutex); Dmsg5(200, "New stats [%lld]: JobId %ld, JobFiles %lu, JobBytes %llu, DevName %s\n", job_stat->timestamp, job_stats->JobId, job_stat->JobFiles, job_stat->JobBytes, job_stat->DevName); } static inline void cleanup_cached_statistics() { struct device_statistics *dev_stats; struct job_statistics *job_stats; P(mutex); if (device_statistics) { foreach_dlist(dev_stats, device_statistics) { dev_stats->statistics->destroy(); dev_stats->statistics = NULL; } device_statistics->destroy(); device_statistics = NULL; } if (job_statistics) { foreach_dlist(job_stats, job_statistics) { job_stats->statistics->destroy(); job_stats->statistics = NULL; } job_statistics->destroy(); job_statistics = NULL; } V(mutex); } /* * Entry point for a seperate statistics thread. */ extern "C" void *statistics_thread_runner(void *arg) { utime_t now; struct timeval tv; struct timezone tz; struct timespec timeout; DEVRES *device; JCR *jcr; setup_statistics(); /* * Do our work as long as we are not signaled to quit. */ while (!quit) { now = (utime_t)time(NULL); if (me->collect_dev_stats) { /* * Loop over all defined devices. */ foreach_res(device, R_DEVICE) { if (device->collectstats) { DEVICE *dev; dev = device->dev; if (dev && dev->initiated) { update_device_statistics(device->hdr.name, dev, now); } } } } if (me->collect_job_stats) { /* * Loop over all running Jobs in the Storage Daemon. */ foreach_jcr(jcr) { update_job_statistics(jcr, now); } endeach_jcr(jcr); } /* * Wait for a next run. Normally this waits exactly me->stats_collect_interval seconds. * It can be interrupted when signaled by the stop_statistics_thread() function. */ gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + me->stats_collect_interval; P(mutex); pthread_cond_timedwait(&wait_for_next_run, &mutex, &timeout); V(mutex); } /* * Cleanup the cached statistics. */ cleanup_cached_statistics(); return NULL; } int start_statistics_thread(void) { int status; /* * First see if device and job stats collection is enabled. */ if (!me->stats_collect_interval || (!me->collect_dev_stats && !me->collect_job_stats)) { return 0; } /* * See if only device stats collection is enabled that there is a least * one device of which stats are collected. */ if (me->collect_dev_stats && !me->collect_job_stats) { DEVRES *device; int cnt = 0; foreach_res(device, R_DEVICE) { if (device->collectstats) { cnt++; } } if (cnt == 0) { return 0; } } if ((status = pthread_create(&statistics_tid, NULL, statistics_thread_runner, NULL)) != 0) { return status; } statistics_initialized = true; return 0; } void stop_statistics_thread() { if (!statistics_initialized) { return; } quit = true; pthread_cond_broadcast(&wait_for_next_run); if (!pthread_equal(statistics_tid, pthread_self())) { pthread_join(statistics_tid, NULL); } } bool stats_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOL_MEM msg(PM_MESSAGE); POOL_MEM dev_tmp(PM_MESSAGE); if (device_statistics) { struct device_statistics *dev_stats; foreach_dlist(dev_stats, device_statistics) { if (dev_stats->statistics) { struct device_statistic *dev_stat, *next_dev_stat; dev_stat = (struct device_statistic *)dev_stats->statistics->first(); while (dev_stat) { next_dev_stat = (struct device_statistic *)dev_stats->statistics->next(dev_stat); /* * If the entry was already collected no need to do it again. */ if (!dev_stat->collected) { pm_strcpy(dev_tmp, dev_stats->DevName); bash_spaces(dev_tmp); Mmsg(msg, DevStats, dev_stat->timestamp, dev_tmp.c_str(), dev_stat->DevReadBytes, dev_stat->DevWriteBytes, dev_stat->spool_size, dev_stat->num_waiting, dev_stat->num_writers, dev_stat->DevReadTime, dev_stat->DevWriteTime, dev_stat->MediaId, dev_stat->VolCatBytes, dev_stat->VolCatFiles, dev_stat->VolCatBlocks); Dmsg1(100, ">dird: %s", msg.c_str()); dir->fsend(msg.c_str()); } P(mutex); /* * If this is the last one on the list leave it for comparison. */ if (!next_dev_stat) { dev_stat->collected = true; } else { dev_stats->statistics->remove(dev_stat); if (dev_stats->cached == dev_stat) { dev_stats->cached = NULL; } } V(mutex); dev_stat = next_dev_stat; } } if (dev_stats->tapealerts) { struct device_tapealert *tape_alert, *next_tape_alert; tape_alert = (struct device_tapealert *)dev_stats->tapealerts->first(); while (tape_alert) { pm_strcpy(dev_tmp, dev_stats->DevName); bash_spaces(dev_tmp); Mmsg(msg, TapeAlerts, tape_alert->timestamp, dev_tmp.c_str(), tape_alert->flags); Dmsg1(100, ">dird: %s", msg.c_str()); dir->fsend(msg.c_str()); next_tape_alert = (struct device_tapealert *)dev_stats->tapealerts->next(tape_alert); P(mutex); dev_stats->tapealerts->remove(tape_alert); V(mutex); tape_alert = next_tape_alert; } } } } if (job_statistics) { bool found; JCR *jcr; struct job_statistics *job_stats, *next_job_stats; job_stats = (struct job_statistics *)job_statistics->first(); while (job_stats) { if (job_stats->statistics) { struct job_statistic *job_stat, *next_job_stat; job_stat = (struct job_statistic *)job_stats->statistics->first(); while (job_stat) { next_job_stat = (struct job_statistic *)job_stats->statistics->next(job_stat); /* * If the entry was already collected no need to do it again. */ if (!job_stat->collected) { pm_strcpy(dev_tmp, job_stat->DevName); bash_spaces(dev_tmp); Mmsg(msg, JobStats, job_stat->timestamp, job_stats->JobId, job_stat->JobFiles, job_stat->JobBytes, dev_tmp.c_str()); Dmsg1(100, ">dird: %s", msg.c_str()); dir->fsend(msg.c_str()); } P(mutex); /* * If this is the last one on the list leave it for comparison. */ if (!next_job_stat) { job_stat->collected = true; } else { job_stats->statistics->remove(job_stat); if (job_stats->cached == job_stat) { job_stats->cached = NULL; } } V(mutex); job_stat = next_job_stat; } } /* * If the Job doesn't exist anymore remove it from the job_statistics. */ next_job_stats = (struct job_statistics *)job_statistics->next(job_stats); found = false; foreach_jcr(jcr) { if (jcr->JobId == job_stats->JobId) { found = true; break; } } endeach_jcr(jcr); if (!found) { P(mutex); Dmsg1(200, "Removing jobid %d from job_statistics\n", job_stats->JobId); job_statistics->remove(job_stats); V(mutex); } job_stats = next_job_stats; } } dir->fsend(OKstats); return false; } bareos-Release-14.2.6/src/stored/spool.c000066400000000000000000000616041263011562700200360ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Spooling code * * Kern Sibbald, March 2004 */ #include "bareos.h" #include "stored.h" /* Forward referenced subroutines */ static void make_unique_data_spool_filename(DCR *dcr, POOLMEM **name); static bool open_data_spool_file(DCR *dcr); static bool close_data_spool_file(DCR *dcr); static bool despool_data(DCR *dcr, bool commit); static int read_block_from_spool_file(DCR *dcr); static bool open_attr_spool_file(JCR *jcr, BSOCK *bs); static bool close_attr_spool_file(JCR *jcr, BSOCK *bs); static bool write_spool_header(DCR *dcr); static bool write_spool_data(DCR *dcr); struct spool_stats_t { uint32_t data_jobs; /* current jobs spooling data */ uint32_t attr_jobs; uint32_t total_data_jobs; /* total jobs to have spooled data */ uint32_t total_attr_jobs; int64_t max_data_size; /* max data size */ int64_t max_attr_size; int64_t data_size; /* current data size (all jobs running) */ int64_t attr_size; }; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static spool_stats_t spool_stats; /* * Header for data spool record */ struct spool_hdr { int32_t FirstIndex; /* FirstIndex for buffer */ int32_t LastIndex; /* LastIndex for buffer */ uint32_t len; /* length of next buffer */ }; enum { RB_EOT = 1, RB_ERROR, RB_OK }; void list_spool_stats(void sendit(const char *msg, int len, void *sarg), void *arg) { char ed1[30], ed2[30]; POOL_MEM msg(PM_MESSAGE); int len; len = Mmsg(msg, _("Spooling statistics:\n")); if (spool_stats.data_jobs || spool_stats.max_data_size) { len = Mmsg(msg, _("Data spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes/job.\n"), spool_stats.data_jobs, edit_uint64_with_commas(spool_stats.data_size, ed1), spool_stats.total_data_jobs, edit_uint64_with_commas(spool_stats.max_data_size, ed2)); sendit(msg.c_str(), len, arg); } if (spool_stats.attr_jobs || spool_stats.max_attr_size) { len = Mmsg(msg, _("Attr spooling: %u active jobs, %s bytes; %u total jobs, %s max bytes.\n"), spool_stats.attr_jobs, edit_uint64_with_commas(spool_stats.attr_size, ed1), spool_stats.total_attr_jobs, edit_uint64_with_commas(spool_stats.max_attr_size, ed2)); sendit(msg.c_str(), len, arg); } } bool begin_data_spool(DCR *dcr) { bool status = true; if (dcr->jcr->spool_data) { Dmsg0(100, "Turning on data spooling\n"); dcr->spool_data = true; status = open_data_spool_file(dcr); if (status) { dcr->spooling = true; Jmsg(dcr->jcr, M_INFO, 0, _("Spooling data ...\n")); P(mutex); spool_stats.data_jobs++; V(mutex); } } return status; } bool discard_data_spool(DCR *dcr) { if (dcr->spooling) { Dmsg0(100, "Data spooling discarded\n"); return close_data_spool_file(dcr); } return true; } bool commit_data_spool(DCR *dcr) { bool status; if (dcr->spooling) { Dmsg0(100, "Committing spooled data\n"); status = despool_data(dcr, true /*commit*/); if (!status) { Dmsg1(100, _("Bad return from despool WroteVol=%d\n"), dcr->WroteVol); close_data_spool_file(dcr); return false; } return close_data_spool_file(dcr); } return true; } static void make_unique_data_spool_filename(DCR *dcr, POOLMEM **name) { const char *dir; if (dcr->dev->device->spool_directory) { dir = dcr->dev->device->spool_directory; } else { dir = working_directory; } Mmsg(name, "%s/%s.data.%u.%s.%s.spool", dir, my_name, dcr->jcr->JobId, dcr->jcr->Job, dcr->device->hdr.name); } static bool open_data_spool_file(DCR *dcr) { POOLMEM *name = get_pool_memory(PM_MESSAGE); int spool_fd; make_unique_data_spool_filename(dcr, &name); if ((spool_fd = open(name, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0640)) >= 0) { dcr->spool_fd = spool_fd; dcr->jcr->spool_attributes = true; } else { berrno be; Jmsg(dcr->jcr, M_FATAL, 0, _("Open data spool file %s failed: ERR=%s\n"), name, be.bstrerror()); free_pool_memory(name); return false; } Dmsg1(100, "Created spool file: %s\n", name); free_pool_memory(name); return true; } static bool close_data_spool_file(DCR *dcr) { POOLMEM *name = get_pool_memory(PM_MESSAGE); P(mutex); spool_stats.data_jobs--; spool_stats.total_data_jobs++; if (spool_stats.data_size < dcr->job_spool_size) { spool_stats.data_size = 0; } else { spool_stats.data_size -= dcr->job_spool_size; } V(mutex); P(dcr->dev->spool_mutex); dcr->job_spool_size = 0; V(dcr->dev->spool_mutex); make_unique_data_spool_filename(dcr, &name); close(dcr->spool_fd); dcr->spool_fd = -1; dcr->spooling = false; unlink(name); Dmsg1(100, "Deleted spool file: %s\n", name); free_pool_memory(name); return true; } static const char *spool_name = "*spool*"; /* * NB! This routine locks the device, but if committing will * not unlock it. If not committing, it will be unlocked. */ static bool despool_data(DCR *dcr, bool commit) { DEVICE *rdev; DCR *rdcr; bool ok = true; DEV_BLOCK *block; JCR *jcr = dcr->jcr; int status; char ec1[50]; BSOCK *dir = jcr->dir_bsock; Dmsg0(100, "Despooling data\n"); if (jcr->dcr->job_spool_size == 0) { Jmsg(jcr, M_WARNING, 0, _("Despooling zero bytes. Your disk is probably FULL!\n")); } /* * Commit means that the job is done, so we commit, otherwise, we * are despooling because of user spool size max or some error * (e.g. filesystem full). */ if (commit) { Jmsg(jcr, M_INFO, 0, _("Committing spooled data to Volume \"%s\". Despooling %s bytes ...\n"), jcr->dcr->VolumeName, edit_uint64_with_commas(jcr->dcr->job_spool_size, ec1)); jcr->setJobStatus(JS_DataCommitting); } else { Jmsg(jcr, M_INFO, 0, _("Writing spooled data to Volume. Despooling %s bytes ...\n"), edit_uint64_with_commas(jcr->dcr->job_spool_size, ec1)); jcr->setJobStatus(JS_DataDespooling); } jcr->sendJobStatus(JS_DataDespooling); dcr->despool_wait = true; dcr->spooling = false; /* * We work with device blocked, but not locked so that other threads * e.g. reservations can lock the device structure. */ dcr->dblock(BST_DESPOOLING); dcr->despool_wait = false; dcr->despooling = true; /* * This is really quite kludgy and should be fixed some time. * We create a dev structure to read from the spool file * in rdev and rdcr. */ rdev = (DEVICE *)malloc(sizeof(DEVICE)); memset(rdev, 0, sizeof(DEVICE)); rdev->dev_name = get_memory(strlen(spool_name)+1); bstrncpy(rdev->dev_name, spool_name, sizeof_pool_memory(rdev->dev_name)); rdev->errmsg = get_pool_memory(PM_EMSG); *rdev->errmsg = 0; rdev->max_block_size = dcr->dev->max_block_size; rdev->min_block_size = dcr->dev->min_block_size; rdev->device = dcr->dev->device; rdcr = dcr->get_new_spooling_dcr(); setup_new_dcr_device(jcr, rdcr, rdev, NULL); rdcr->spool_fd = dcr->spool_fd; block = dcr->block; /* save block */ dcr->block = rdcr->block; /* make read and write block the same */ Dmsg1(800, "read/write block size = %d\n", block->buf_len); lseek(rdcr->spool_fd, 0, SEEK_SET); /* rewind */ #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) posix_fadvise(rdcr->spool_fd, 0, 0, POSIX_FADV_WILLNEED); #endif /* Add run time, to get current wait time */ int32_t despool_start = time(NULL) - jcr->run_time; set_new_file_parameters(dcr); while (ok) { if (job_canceled(jcr)) { ok = false; break; } status = read_block_from_spool_file(rdcr); if (status == RB_EOT) { break; } else if (status == RB_ERROR) { ok = false; break; } ok = dcr->write_block_to_device(); if (!ok) { Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"), dcr->dev->print_name(), dcr->dev->bstrerror()); Dmsg2(000, "Fatal append error on device %s: ERR=%s\n", dcr->dev->print_name(), dcr->dev->bstrerror()); /* Force in case Incomplete set */ jcr->forceJobStatus(JS_FatalError); } Dmsg3(800, "Write block ok=%d FI=%d LI=%d\n", ok, block->FirstIndex, block->LastIndex); } /* * If this Job is incomplete, we need to backup the FileIndex * to the last correctly saved file so that the JobMedia * LastIndex is correct. */ if (jcr->is_JobStatus(JS_Incomplete)) { dcr->VolLastIndex = dir->get_FileIndex(); Dmsg1(100, "======= Set FI=%ld\n", dir->get_FileIndex()); } if (!dcr->dir_create_jobmedia_record(false)) { Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), dcr->getVolCatName(), jcr->Job); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ } /* Set new file/block parameters for current dcr */ set_new_file_parameters(dcr); /* * Subtracting run_time give us elapsed time - wait_time since * we started despooling. Note, don't use time_t as it is 32 or 64 * bits depending on the OS and doesn't edit with %d */ int32_t despool_elapsed = time(NULL) - despool_start - jcr->run_time; if (despool_elapsed <= 0) { despool_elapsed = 1; } Jmsg(jcr, M_INFO, 0, _("Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s Bytes/second\n"), despool_elapsed / 3600, despool_elapsed % 3600 / 60, despool_elapsed % 60, edit_uint64_with_suffix(jcr->dcr->job_spool_size / despool_elapsed, ec1)); dcr->block = block; /* reset block */ lseek(rdcr->spool_fd, 0, SEEK_SET); /* rewind */ if (ftruncate(rdcr->spool_fd, 0) != 0) { berrno be; Jmsg(jcr, M_ERROR, 0, _("Ftruncate spool file failed: ERR=%s\n"), be.bstrerror()); /* Note, try continuing despite ftruncate problem */ } P(mutex); if (spool_stats.data_size < dcr->job_spool_size) { spool_stats.data_size = 0; } else { spool_stats.data_size -= dcr->job_spool_size; } V(mutex); P(dcr->dev->spool_mutex); dcr->dev->spool_size -= dcr->job_spool_size; dcr->job_spool_size = 0; /* zap size in input dcr */ V(dcr->dev->spool_mutex); free_memory(rdev->dev_name); free_pool_memory(rdev->errmsg); /* Be careful to NULL the jcr and free rdev after free_dcr() */ rdcr->jcr = NULL; rdcr->set_dev(NULL); free_dcr(rdcr); free(rdev); dcr->spooling = true; /* turn on spooling again */ dcr->despooling = false; /* * Note, if committing we leave the device blocked. It will be removed in * release_device(); */ if (!commit) { dcr->dev->dunblock(); } jcr->sendJobStatus(JS_Running); return ok; } /* * Read a block from the spool file * * Returns RB_OK on success * RB_EOT when file done * RB_ERROR on error */ static int read_block_from_spool_file(DCR *dcr) { uint32_t rlen; ssize_t status; spool_hdr hdr; DEV_BLOCK *block = dcr->block; JCR *jcr = dcr->jcr; rlen = sizeof(hdr); status = read(dcr->spool_fd, (char *)&hdr, (size_t)rlen); if (status == 0) { Dmsg0(100, "EOT on spool read.\n"); return RB_EOT; } else if (status != (ssize_t)rlen) { if (status == -1) { berrno be; Jmsg(dcr->jcr, M_FATAL, 0, _("Spool header read error. ERR=%s\n"), be.bstrerror()); } else { Pmsg2(000, _("Spool read error. Wanted %u bytes, got %d\n"), rlen, status); Jmsg2(jcr, M_FATAL, 0, _("Spool header read error. Wanted %u bytes, got %d\n"), rlen, status); } jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return RB_ERROR; } rlen = hdr.len; if (rlen > block->buf_len) { Pmsg2(000, _("Spool block too big. Max %u bytes, got %u\n"), block->buf_len, rlen); Jmsg2(jcr, M_FATAL, 0, _("Spool block too big. Max %u bytes, got %u\n"), block->buf_len, rlen); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return RB_ERROR; } status = read(dcr->spool_fd, (char *)block->buf, (size_t)rlen); if (status != (ssize_t)rlen) { Pmsg2(000, _("Spool data read error. Wanted %u bytes, got %d\n"), rlen, status); Jmsg2(dcr->jcr, M_FATAL, 0, _("Spool data read error. Wanted %u bytes, got %d\n"), rlen, status); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return RB_ERROR; } /* Setup write pointers */ block->binbuf = rlen; block->bufp = block->buf + block->binbuf; block->FirstIndex = hdr.FirstIndex; block->LastIndex = hdr.LastIndex; block->VolSessionId = dcr->jcr->VolSessionId; block->VolSessionTime = dcr->jcr->VolSessionTime; Dmsg2(800, "Read block FI=%d LI=%d\n", block->FirstIndex, block->LastIndex); return RB_OK; } /* * Write a block to the spool file * * Returns: true on success or EOT * false on hard error */ bool write_block_to_spool_file(DCR *dcr) { uint32_t wlen, hlen; /* length to write */ bool despool = false; DEV_BLOCK *block = dcr->block; if (job_canceled(dcr->jcr)) { return false; } ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf))); if (block->binbuf <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */ return true; } hlen = sizeof(spool_hdr); wlen = block->binbuf; P(dcr->dev->spool_mutex); dcr->job_spool_size += hlen + wlen; dcr->dev->spool_size += hlen + wlen; if ((dcr->max_job_spool_size > 0 && dcr->job_spool_size >= dcr->max_job_spool_size) || (dcr->dev->max_spool_size > 0 && dcr->dev->spool_size >= dcr->dev->max_spool_size)) { despool = true; } V(dcr->dev->spool_mutex); P(mutex); spool_stats.data_size += hlen + wlen; if (spool_stats.data_size > spool_stats.max_data_size) { spool_stats.max_data_size = spool_stats.data_size; } V(mutex); if (despool) { char ec1[30], ec2[30]; if (dcr->max_job_spool_size > 0) { Jmsg(dcr->jcr, M_INFO, 0, _("User specified Job spool size reached: " "JobSpoolSize=%s MaxJobSpoolSize=%s\n"), edit_uint64_with_commas(dcr->job_spool_size, ec1), edit_uint64_with_commas(dcr->max_job_spool_size, ec2)); } else { Jmsg(dcr->jcr, M_INFO, 0, _("User specified Device spool size reached: " "DevSpoolSize=%s MaxDevSpoolSize=%s\n"), edit_uint64_with_commas(dcr->dev->spool_size, ec1), edit_uint64_with_commas(dcr->dev->max_spool_size, ec2)); } if (!despool_data(dcr, false)) { Pmsg0(000, _("Bad return from despool in write_block.\n")); return false; } /* Despooling cleared these variables so reset them */ P(dcr->dev->spool_mutex); dcr->job_spool_size += hlen + wlen; dcr->dev->spool_size += hlen + wlen; V(dcr->dev->spool_mutex); Jmsg(dcr->jcr, M_INFO, 0, _("Spooling data again ...\n")); } if (!write_spool_header(dcr)) { return false; } if (!write_spool_data(dcr)) { return false; } Dmsg2(800, "Wrote block FI=%d LI=%d\n", block->FirstIndex, block->LastIndex); empty_block(block); return true; } static bool write_spool_header(DCR *dcr) { spool_hdr hdr; ssize_t status; DEV_BLOCK *block = dcr->block; JCR *jcr = dcr->jcr; hdr.FirstIndex = block->FirstIndex; hdr.LastIndex = block->LastIndex; hdr.len = block->binbuf; /* Write header */ for (int retry = 0; retry <= 1; retry++) { status = write(dcr->spool_fd, (char*)&hdr, sizeof(hdr)); if (status == -1) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Error writing header to spool file. ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ } if (status != (ssize_t)sizeof(hdr)) { Jmsg(jcr, M_ERROR, 0, _("Error writing header to spool file." " Disk probably full. Attempting recovery. Wanted to write=%d got=%d\n"), (int)status, (int)sizeof(hdr)); /* If we wrote something, truncate it, then despool */ if (status != -1) { #if defined(HAVE_WIN32) boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR); #else boffset_t pos = lseek(dcr->spool_fd, 0, SEEK_CUR); #endif if (ftruncate(dcr->spool_fd, pos - status) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR, 0, _("Ftruncate spool file failed: ERR=%s\n"), be.bstrerror()); /* Note, try continuing despite ftruncate problem */ } } if (!despool_data(dcr, false)) { Jmsg(jcr, M_FATAL, 0, _("Fatal despooling error.")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } continue; /* try again */ } return true; } Jmsg(jcr, M_FATAL, 0, _("Retrying after header spooling error failed.\n")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } static bool write_spool_data(DCR *dcr) { ssize_t status; DEV_BLOCK *block = dcr->block; JCR *jcr = dcr->jcr; /* Write data */ for (int retry = 0; retry <= 1; retry++) { status = write(dcr->spool_fd, block->buf, (size_t)block->binbuf); if (status == -1) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Error writing data to spool file. ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ } if (status != (ssize_t)block->binbuf) { /* * If we wrote something, truncate it and the header, then despool */ if (status != -1) { #if defined(HAVE_WIN32) boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR); #else boffset_t pos = lseek(dcr->spool_fd, 0, SEEK_CUR); #endif if (ftruncate(dcr->spool_fd, pos - status - sizeof(spool_hdr)) != 0) { berrno be; Jmsg(dcr->jcr, M_ERROR, 0, _("Ftruncate spool file failed: ERR=%s\n"), be.bstrerror()); /* Note, try continuing despite ftruncate problem */ } } if (!despool_data(dcr, false)) { Jmsg(jcr, M_FATAL, 0, _("Fatal despooling error.")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } if (!write_spool_header(dcr)) { return false; } continue; /* try again */ } return true; } Jmsg(jcr, M_FATAL, 0, _("Retrying after data spooling error failed.\n")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } bool are_attributes_spooled(JCR *jcr) { return jcr->spool_attributes && jcr->dir_bsock->m_spool_fd != -1; } /* * Create spool file for attributes. * This is done by "attaching" to the bsock, and when * it is called, the output is written to a file. * The actual spooling is turned on and off in * append.c only during writing of the attributes. */ bool begin_attribute_spool(JCR *jcr) { if (!jcr->no_attributes && jcr->spool_attributes) { return open_attr_spool_file(jcr, jcr->dir_bsock); } return true; } bool discard_attribute_spool(JCR *jcr) { if (are_attributes_spooled(jcr)) { return close_attr_spool_file(jcr, jcr->dir_bsock); } return true; } static void update_attr_spool_size(ssize_t size) { P(mutex); if (size > 0) { if ((spool_stats.attr_size - size) > 0) { spool_stats.attr_size -= size; } else { spool_stats.attr_size = 0; } } V(mutex); } static void make_unique_spool_filename(JCR *jcr, POOLMEM **name, int fd) { Mmsg(name, "%s/%s.attr.%s.%d.spool", working_directory, my_name, jcr->Job, fd); } /* * Tell Director where to find the attributes spool file * Note, if we are not on the same machine, the Director will * return an error, and the higher level routine will transmit * the data record by record -- using bsock->despool(). */ static bool blast_attr_spool_file(JCR *jcr, boffset_t size) { /* send full spool file name */ POOLMEM *name = get_pool_memory(PM_MESSAGE); make_unique_spool_filename(jcr, &name, jcr->dir_bsock->m_fd); bash_spaces(name); jcr->dir_bsock->fsend("BlastAttr Job=%s File=%s\n", jcr->Job, name); free_pool_memory(name); if (jcr->dir_bsock->recv() <= 0) { Jmsg(jcr, M_FATAL, 0, _("Network error on BlastAttributes.\n")); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ return false; } if (!bstrcmp(jcr->dir_bsock->msg, "1000 OK BlastAttr\n")) { return false; } return true; } bool commit_attribute_spool(JCR *jcr) { boffset_t size, data_end; char ec1[30]; char tbuf[MAX_TIME_LENGTH]; BSOCK *dir; Dmsg1(100, "Commit attributes at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); if (are_attributes_spooled(jcr)) { dir = jcr->dir_bsock; if ((size = lseek(dir->m_spool_fd, 0, SEEK_END)) == -1) { berrno be; Jmsg(jcr, M_FATAL, 0, _("lseek on attributes file failed: ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ goto bail_out; } if (jcr->is_JobStatus(JS_Incomplete)) { data_end = dir->get_data_end(); /* * Check and truncate to last valid data_end if necssary */ if (size > data_end) { if (ftruncate(dir->m_spool_fd, data_end) != 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Truncate on attributes file failed: ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ goto bail_out; } Dmsg2(100, "=== Attrib spool truncated from %lld to %lld\n", size, data_end); size = data_end; } } if (size < 0) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Fseek on attributes file failed: ERR=%s\n"), be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ goto bail_out; } P(mutex); if (spool_stats.attr_size + size > spool_stats.max_attr_size) { spool_stats.max_attr_size = spool_stats.attr_size + size; } spool_stats.attr_size += size; V(mutex); jcr->sendJobStatus(JS_AttrDespooling); Jmsg(jcr, M_INFO, 0, _("Sending spooled attrs to the Director. Despooling %s bytes ...\n"), edit_uint64_with_commas(size, ec1)); if (!blast_attr_spool_file(jcr, size)) { /* Can't read spool file from director side, * send content over network. */ dir->despool(update_attr_spool_size, size); } return close_attr_spool_file(jcr, dir); } return true; bail_out: close_attr_spool_file(jcr, dir); return false; } static bool open_attr_spool_file(JCR *jcr, BSOCK *bs) { POOLMEM *name = get_pool_memory(PM_MESSAGE); make_unique_spool_filename(jcr, &name, bs->m_fd); bs->m_spool_fd = open(name, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0640); if (bs->m_spool_fd == -1) { berrno be; Jmsg(jcr, M_FATAL, 0, _("fopen attr spool file %s failed: ERR=%s\n"), name, be.bstrerror()); jcr->forceJobStatus(JS_FatalError); /* override any Incomplete */ free_pool_memory(name); return false; } P(mutex); spool_stats.attr_jobs++; V(mutex); free_pool_memory(name); return true; } static bool close_attr_spool_file(JCR *jcr, BSOCK *bs) { POOLMEM *name; char tbuf[MAX_TIME_LENGTH]; Dmsg1(100, "Close attr spool file at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL))); if (bs->m_spool_fd == -1) { return true; } name = get_pool_memory(PM_MESSAGE); P(mutex); spool_stats.attr_jobs--; spool_stats.total_attr_jobs++; V(mutex); make_unique_spool_filename(jcr, &name, bs->m_fd); close(bs->m_spool_fd); unlink(name); free_pool_memory(name); bs->m_spool_fd = -1; bs->clear_spooling(); return true; } bareos-Release-14.2.6/src/stored/status.c000066400000000000000000000772311263011562700202300ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This file handles the status command * * Kern Sibbald, May MMIII */ #include "bareos.h" #include "stored.h" #include "lib/status.h" /* Imported functions */ extern bool GetWindowsVersionString(char *buf, int maxsiz); /* Imported variables */ extern BSOCK *filed_chan; extern void *start_heap; /* Static variables */ static char statuscmd[] = "status %s\n"; static char dotstatuscmd[] = ".status %127s\n"; static char OKdotstatus[] = "3000 OK .status\n"; static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n"; /* Forward referenced functions */ static void sendit(const char *msg, int len, STATUS_PKT *sp); static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp); static void sendit(const char *msg, int len, void *arg); static void trigger_device_status_hook(JCR *jcr, DEVRES *device, STATUS_PKT *sp, bsdEventType eventType); static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp); static void send_device_status(DEVICE *dev, STATUS_PKT *sp); static void list_terminated_jobs(STATUS_PKT *sp); static void list_running_jobs(STATUS_PKT *sp); static void list_jobs_waiting_on_reservation(STATUS_PKT *sp); static void list_status_header(STATUS_PKT *sp); static void list_devices(JCR *jcr, STATUS_PKT *sp, const char *devicenames); static const char *level_to_str(int level); /* * Status command from Director */ static void output_status(JCR *jcr, STATUS_PKT *sp, const char *devicenames) { int len; POOL_MEM msg(PM_MESSAGE); list_status_header(sp); /* * List running jobs */ list_running_jobs(sp); /* * List jobs stuck in reservation system */ list_jobs_waiting_on_reservation(sp); /* * List terminated jobs */ list_terminated_jobs(sp); /* * List devices */ list_devices(jcr, sp, devicenames); if (!sp->api) { len = Mmsg(msg, _("Used Volume status:\n")); sendit(msg, len, sp); } list_volumes(sendit, (void *)sp); if (!sp->api) { len = pm_strcpy(msg, "====\n\n"); sendit(msg, len, sp); } list_spool_stats(sendit, (void *)sp); if (!sp->api) { len = pm_strcpy(msg, "====\n\n"); sendit(msg, len, sp); } } static void list_resources(STATUS_PKT *sp) { #ifdef when_working int len; POOL_MEM msg(PM_MESSAGE); if (!sp->api) { len = Mmsg(msg, _("\nSD Resources:\n")); sendit(msg, len, sp); } dump_resource(R_DEVICE, resources[R_DEVICE - my_config->m_r_first], sp, false); if (!sp->api) { len = pm_strcpy(msg, "====\n\n"); sendit(msg, len, sp); } #endif } #ifdef xxxx static find_device(char *devname) { foreach_res(device, R_DEVICE) { if (strcasecmp(device->hdr.name, devname) == 0) { found = true; break; } } if (!found) { foreach_res(changer, R_AUTOCHANGER) { if (strcasecmp(changer->hdr.name, devname) == 0) { break; } } } } #endif static bool need_to_list_device(const char *devicenames, const char *devicename) { char *cur, *bp; POOL_MEM namelist; /* * Make a local copy that we can split on ',' */ pm_strcpy(namelist, devicenames); /* * See if devicename is in the list. */ cur = namelist.c_str(); while (cur) { bp = strchr(cur, ','); if (bp) { *bp++ = '\0'; } if (bstrcasecmp(cur, devicename)) { return true; } cur = bp; } return false; } static void list_devices(JCR *jcr, STATUS_PKT *sp, const char *devicenames) { int len; int bpb; DEVICE *dev; DEVRES *device; AUTOCHANGERRES *changer; POOL_MEM msg(PM_MESSAGE); char b1[35], b2[35], b3[35]; if (!sp->api) { len = Mmsg(msg, _("\nDevice status:\n")); sendit(msg, len, sp); } foreach_res(changer, R_AUTOCHANGER) { /* * See if we need to list this autochanger. */ if (devicenames && !need_to_list_device(devicenames, changer->hdr.name)) { continue; } len = Mmsg(msg, _("Autochanger \"%s\" with devices:\n"), changer->hdr.name); sendit(msg, len, sp); foreach_alist(device, changer->device) { if (device->dev) { len = Mmsg(msg, " %s\n", device->dev->print_name()); sendit(msg, len, sp); } else { len = Mmsg(msg, " %s\n", device->hdr.name); sendit(msg, len, sp); } } } foreach_res(device, R_DEVICE) { /* * See if we need to check for devicenames at all. */ if (devicenames) { /* * See if this device is part of an autochanger. */ if (device->changer_res) { /* * See if we need to list this particular device part of the given autochanger. */ if (!need_to_list_device(devicenames, device->changer_res->hdr.name)) { continue; } } else { /* * Try matching a non autochanger device. */ if (!need_to_list_device(devicenames, device->hdr.name)) { continue; } } } dev = device->dev; if (dev && dev->is_open()) { if (dev->is_labeled()) { const char *state; switch (dev->blocked()) { case BST_NOT_BLOCKED: case BST_DESPOOLING: case BST_RELEASING: state = _("mounted with"); break; case BST_MOUNT: state = _("waiting for"); break; case BST_WRITING_LABEL: state = _("being labeled with"); break; case BST_DOING_ACQUIRE: state = _("being acquired with"); break; case BST_UNMOUNTED: case BST_WAITING_FOR_SYSOP: case BST_UNMOUNTED_WAITING_FOR_SYSOP: state = _("waiting for sysop intervention"); break; default: state = _("unknown state"); break; } len = Mmsg(msg, _("\nDevice %s is %s:\n" " Volume: %s\n" " Pool: %s\n" " Media type: %s\n"), dev->print_name(), state, dev->VolHdr.VolumeName, dev->pool_name[0] ? dev->pool_name : "*unknown*", dev->device->media_type); sendit(msg, len, sp); } else { len = Mmsg(msg, _("\nDevice %s open but no Bareos volume is currently mounted.\n"), dev->print_name()); sendit(msg, len, sp); } trigger_device_status_hook(jcr, device, sp, bsdEventDriveStatus); send_blocked_status(dev, sp); if (dev->can_append()) { bpb = dev->VolCatInfo.VolCatBlocks; if (bpb <= 0) { bpb = 1; } bpb = dev->VolCatInfo.VolCatBytes / bpb; len = Mmsg(msg, _(" Total Bytes=%s Blocks=%s Bytes/block=%s\n"), edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1), edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2), edit_uint64_with_commas(bpb, b3)); sendit(msg, len, sp); } else { /* reading */ bpb = dev->VolCatInfo.VolCatReads; if (bpb <= 0) { bpb = 1; } if (dev->VolCatInfo.VolCatRBytes > 0) { bpb = dev->VolCatInfo.VolCatRBytes / bpb; } else { bpb = 0; } len = Mmsg(msg, _(" Total Bytes Read=%s Blocks Read=%s Bytes/block=%s\n"), edit_uint64_with_commas(dev->VolCatInfo.VolCatRBytes, b1), edit_uint64_with_commas(dev->VolCatInfo.VolCatReads, b2), edit_uint64_with_commas(bpb, b3)); sendit(msg, len, sp); } len = Mmsg(msg, _(" Positioned at File=%s Block=%s\n"), edit_uint64_with_commas(dev->file, b1), edit_uint64_with_commas(dev->block_num, b2)); sendit(msg, len, sp); trigger_device_status_hook(jcr, device, sp, bsdEventVolumeStatus); } else { if (dev) { len = Mmsg(msg, _("\nDevice %s is not open.\n"), dev->print_name()); sendit(msg, len, sp); send_blocked_status(dev, sp); } else { len = Mmsg(msg, _("\nDevice \"%s\" is not open or does not exist.\n"), device->hdr.name); sendit(msg, len, sp); } } if (!sp->api) { len = pm_strcpy(msg, "==\n"); sendit(msg, len, sp); } } if (!sp->api) { len = pm_strcpy(msg, "====\n\n"); sendit(msg, len, sp); } } static void list_status_header(STATUS_PKT *sp) { int len; POOL_MEM msg(PM_MESSAGE); char dt[MAX_TIME_LENGTH]; char b1[35], b2[35], b3[35], b4[35], b5[35]; #if defined(HAVE_WIN32) char buf[300]; #endif len = Mmsg(msg, _("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER); sendit(msg, len, sp); bstrftime_nc(dt, sizeof(dt), daemon_start_time); len = Mmsg(msg, _("Daemon started %s. Jobs: run=%d, running=%d.\n"), dt, num_jobs_run, job_count()); sendit(msg, len, sp); #if defined(HAVE_WIN32) if (GetWindowsVersionString(buf, sizeof(buf))) { len = Mmsg(msg, "%s\n", buf); sendit(msg.c_str(), len, sp); } if (debug_level > 0) { len = Mmsg(msg, "APIs=%sOPT,%sATP,%sLPV,%sCFA,%sCFW,\n", p_OpenProcessToken ? "" : "!", p_AdjustTokenPrivileges ? "" : "!", p_LookupPrivilegeValue ? "" : "!", p_CreateFileA ? "" : "!", p_CreateFileW ? "" : "!"); sendit(msg.c_str(), len, sp); len = Mmsg(msg, " %sWUL,%sWMKD,%sGFAA,%sGFAW,%sGFAEA,%sGFAEW,%sSFAA,%sSFAW,%sBR,%sBW,%sSPSP,\n", p_wunlink ? "" : "!", p_wmkdir ? "" : "!", p_GetFileAttributesA ? "" : "!", p_GetFileAttributesW ? "" : "!", p_GetFileAttributesExA ? "" : "!", p_GetFileAttributesExW ? "" : "!", p_SetFileAttributesA ? "" : "!", p_SetFileAttributesW ? "" : "!", p_BackupRead ? "" : "!", p_BackupWrite ? "" : "!", p_SetProcessShutdownParameters ? "" : "!"); sendit(msg.c_str(), len, sp); len = Mmsg(msg, " %sWC2MB,%sMB2WC,%sFFFA,%sFFFW,%sFNFA,%sFNFW,%sSCDA,%sSCDW,\n", p_WideCharToMultiByte ? "" : "!", p_MultiByteToWideChar ? "" : "!", p_FindFirstFileA ? "" : "!", p_FindFirstFileW ? "" : "!", p_FindNextFileA ? "" : "!", p_FindNextFileW ? "" : "!", p_SetCurrentDirectoryA ? "" : "!", p_SetCurrentDirectoryW ? "" : "!"); sendit(msg.c_str(), len, sp); len = Mmsg(msg, " %sGCDA,%sGCDW,%sGVPNW,%sGVNFVMPW\n", p_GetCurrentDirectoryA ? "" : "!", p_GetCurrentDirectoryW ? "" : "!", p_GetVolumePathNameW ? "" : "!", p_GetVolumeNameForVolumeMountPointW ? "" : "!"); sendit(msg.c_str(), len, sp); } #endif len = Mmsg(msg, _(" Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"), edit_uint64_with_commas((char *)sbrk(0)-(char *)start_heap, b1), edit_uint64_with_commas(sm_bytes, b2), edit_uint64_with_commas(sm_max_bytes, b3), edit_uint64_with_commas(sm_buffers, b4), edit_uint64_with_commas(sm_max_buffers, b5)); sendit(msg, len, sp); len = Mmsg(msg, " Sizes: boffset_t=%d size_t=%d int32_t=%d int64_t=%d " "mode=%d bwlimit=%skB/s\n", (int)sizeof(boffset_t), (int)sizeof(size_t), (int)sizeof(int32_t), (int)sizeof(int64_t), (int)DEVELOPER_MODE, edit_uint64_with_commas(me->max_bandwidth_per_job / 1024, b1)); sendit(msg, len, sp); len = list_sd_plugins(msg); if (len > 0) { sendit(msg.c_str(), len, sp); } } static void trigger_device_status_hook(JCR *jcr, DEVRES *device, STATUS_PKT *sp, bsdEventType eventType) { bsdDevStatTrig dst; dst.device = device; dst.status = get_pool_memory(PM_MESSAGE); dst.status_length = 0; if (generate_plugin_event(jcr, eventType, &dst) == bRC_OK) { if (dst.status_length > 0) { sendit(dst.status, dst.status_length, sp); } } free_pool_memory(dst.status); } static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp) { int len; POOL_MEM msg(PM_MESSAGE); if (!dev) { len = Mmsg(msg, _("No DEVICE structure.\n\n")); sendit(msg, len, sp); return; } switch (dev->blocked()) { case BST_UNMOUNTED: len = Mmsg(msg, _(" Device is BLOCKED. User unmounted.\n")); sendit(msg, len, sp); break; case BST_UNMOUNTED_WAITING_FOR_SYSOP: len = Mmsg(msg, _(" Device is BLOCKED. User unmounted during wait for media/mount.\n")); sendit(msg, len, sp); break; case BST_WAITING_FOR_SYSOP: { DCR *dcr; bool found_jcr = false; dev->Lock(); foreach_dlist(dcr, dev->attached_dcrs) { if (dcr->jcr->JobStatus == JS_WaitMount) { len = Mmsg(msg, _(" Device is BLOCKED waiting for mount of volume \"%s\",\n" " Pool: %s\n" " Media type: %s\n"), dcr->VolumeName, dcr->pool_name, dcr->media_type); sendit(msg, len, sp); found_jcr = true; } else if (dcr->jcr->JobStatus == JS_WaitMedia) { len = Mmsg(msg, _(" Device is BLOCKED waiting to create a volume for:\n" " Pool: %s\n" " Media type: %s\n"), dcr->pool_name, dcr->media_type); sendit(msg, len, sp); found_jcr = true; } } dev->Unlock(); if (!found_jcr) { len = Mmsg(msg, _(" Device is BLOCKED waiting for media.\n")); sendit(msg, len, sp); } } break; case BST_DOING_ACQUIRE: len = Mmsg(msg, _(" Device is being initialized.\n")); sendit(msg, len, sp); break; case BST_WRITING_LABEL: len = Mmsg(msg, _(" Device is blocked labeling a Volume.\n")); sendit(msg, len, sp); break; default: break; } /* Send autochanger slot status */ if (dev->is_autochanger()) { if (dev->get_slot() > 0) { len = Mmsg(msg, _(" Slot %d %s loaded in drive %d.\n"), dev->get_slot(), dev->is_open() ? "is" : "was last", dev->drive_index); sendit(msg, len, sp); } else if (dev->get_slot() <= 0) { len = Mmsg(msg, _(" Drive %d is not loaded.\n"), dev->drive_index); sendit(msg, len, sp); } } if (debug_level > 1) { send_device_status(dev, sp); } } static void send_device_status(DEVICE *dev, STATUS_PKT *sp) { int len; DCR *dcr = NULL; bool found = false; POOL_MEM msg(PM_MESSAGE); if (debug_level > 5) { len = Mmsg(msg, _("Configured device capabilities:\n")); sendit(msg, len, sp); len = Mmsg(msg, " %sEOF %sBSR %sBSF %sFSR %sFSF %sEOM %sREM %sRACCESS %sAUTOMOUNT %sLABEL %sANONVOLS %sALWAYSOPEN\n", dev->capabilities & CAP_EOF ? "" : "!", dev->capabilities & CAP_BSR ? "" : "!", dev->capabilities & CAP_BSF ? "" : "!", dev->capabilities & CAP_FSR ? "" : "!", dev->capabilities & CAP_FSF ? "" : "!", dev->capabilities & CAP_EOM ? "" : "!", dev->capabilities & CAP_REM ? "" : "!", dev->capabilities & CAP_RACCESS ? "" : "!", dev->capabilities & CAP_AUTOMOUNT ? "" : "!", dev->capabilities & CAP_LABEL ? "" : "!", dev->capabilities & CAP_ANONVOLS ? "" : "!", dev->capabilities & CAP_ALWAYSOPEN ? "" : "!"); sendit(msg, len, sp); } len = Mmsg(msg, _("Device state:\n")); sendit(msg, len, sp); len = Mmsg(msg, " %sOPENED %sTAPE %sLABEL %sMALLOC %sAPPEND %sREAD %sEOT %sWEOT %sEOF %sNEXTVOL %sSHORT %sMOUNTED\n", dev->is_open() ? "" : "!", dev->is_tape() ? "" : "!", dev->is_labeled() ? "" : "!", dev->state & ST_MALLOC ? "" : "!", dev->can_append() ? "" : "!", dev->can_read() ? "" : "!", dev->at_eot() ? "" : "!", dev->state & ST_WEOT ? "" : "!", dev->at_eof() ? "" : "!", dev->state & ST_NEXTVOL ? "" : "!", dev->state & ST_SHORT ? "" : "!", dev->state & ST_MOUNTED ? "" : "!"); sendit(msg, len, sp); len = Mmsg(msg, _(" num_writers=%d reserves=%d block=%d\n"), dev->num_writers, dev->num_reserved(), dev->blocked()); sendit(msg, len, sp); len = Mmsg(msg, _("Attached Jobs: ")); sendit(msg, len, sp); dev->Lock(); foreach_dlist(dcr, dev->attached_dcrs) { if (dcr->jcr) { if (found) { len = Mmsg(msg, ",%d", (int)dcr->jcr->JobId); } else { len = Mmsg(msg, "%d", (int)dcr->jcr->JobId); } sendit(msg, len, sp); found = true; } } dev->Unlock(); sendit("\n", 1, sp); len = Mmsg(msg, _("Device parameters:\n")); sendit(msg, len, sp); len = Mmsg(msg, _(" Archive name: %s Device name: %s\n"), dev->archive_name(), dev->name()); sendit(msg, len, sp); len = Mmsg(msg, _(" File=%u block=%u\n"), dev->file, dev->block_num); sendit(msg, len, sp); len = Mmsg(msg, _(" Min block=%u Max block=%u\n"), dev->min_block_size, dev->max_block_size); sendit(msg, len, sp); } static void list_running_jobs(STATUS_PKT *sp) { JCR *jcr; DCR *dcr, *rdcr; bool found = false; time_t now = time(NULL); POOL_MEM msg(PM_MESSAGE); int len, avebps, bps, sec; char JobName[MAX_NAME_LENGTH]; char b1[50], b2[50], b3[50], b4[50]; if (!sp->api) { len = Mmsg(msg, _("\nRunning Jobs:\n")); sendit(msg, len, sp); } foreach_jcr(jcr) { if (jcr->JobStatus == JS_WaitFD) { len = Mmsg(msg, _("%s Job %s waiting for Client connection.\n"), job_type_to_str(jcr->getJobType()), jcr->Job); sendit(msg, len, sp); } dcr = jcr->dcr; rdcr = jcr->read_dcr; if ((dcr && dcr->device) || (rdcr && rdcr->device)) { bstrncpy(JobName, jcr->Job, sizeof(JobName)); /* There are three periods after the Job name */ char *p; for (int i=0; i<3; i++) { if ((p=strrchr(JobName, '.')) != NULL) { *p = 0; } } if (rdcr && rdcr->device) { len = Mmsg(msg, _("Reading: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n"), job_level_to_str(jcr->getJobLevel()), job_type_to_str(jcr->getJobType()), JobName, jcr->JobId, rdcr->VolumeName, rdcr->pool_name, rdcr->dev ? rdcr->dev->print_name(): rdcr->device->device_name); sendit(msg, len, sp); } if (dcr && dcr->device) { len = Mmsg(msg, _("Writing: %s %s job %s JobId=%d Volume=\"%s\"\n" " pool=\"%s\" device=%s\n"), job_level_to_str(jcr->getJobLevel()), job_type_to_str(jcr->getJobType()), JobName, jcr->JobId, dcr->VolumeName, dcr->pool_name, dcr->dev ? dcr->dev->print_name(): dcr->device->device_name); sendit(msg, len, sp); len= Mmsg(msg, _(" spooling=%d despooling=%d despool_wait=%d\n"), dcr->spooling, dcr->despooling, dcr->despool_wait); sendit(msg, len, sp); } if (jcr->last_time == 0) { jcr->last_time = jcr->run_time; } sec = now - jcr->last_time; if (sec <= 0) { sec = 1; } bps = (jcr->JobBytes - jcr->LastJobBytes) / sec; if (jcr->LastRate == 0) { jcr->LastRate = bps; } avebps = (jcr->LastRate + bps) / 2; len = Mmsg(msg, _(" Files=%s Bytes=%s AveBytes/sec=%s LastBytes/sec=%s\n"), edit_uint64_with_commas(jcr->JobFiles, b1), edit_uint64_with_commas(jcr->JobBytes, b2), edit_uint64_with_commas(avebps, b3), edit_uint64_with_commas(bps, b4)); sendit(msg, len, sp); jcr->LastRate = avebps; jcr->LastJobBytes = jcr->JobBytes; jcr->last_time = now; found = true; #ifdef DEBUG if (jcr->file_bsock) { len = Mmsg(msg, _(" FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n"), edit_uint64_with_commas(jcr->file_bsock->read_seqno, b1), jcr->file_bsock->in_msg_no, jcr->file_bsock->out_msg_no, jcr->file_bsock->m_fd); sendit(msg, len, sp); } else { len = Mmsg(msg, _(" FDSocket closed\n")); sendit(msg, len, sp); } #endif } } endeach_jcr(jcr); if (!found) { if (!sp->api) { len = Mmsg(msg, _("No Jobs running.\n")); sendit(msg, len, sp); } } if (!sp->api) { len = pm_strcpy(msg, "====\n"); sendit(msg, len, sp); } } static void list_jobs_waiting_on_reservation(STATUS_PKT *sp) { int len; JCR *jcr; POOL_MEM msg(PM_MESSAGE); if (!sp->api) { len = Mmsg(msg, _("\nJobs waiting to reserve a drive:\n")); sendit(msg, len, sp); } foreach_jcr(jcr) { if (!jcr->reserve_msgs) { continue; } send_drive_reserve_messages(jcr, sendit, sp); } endeach_jcr(jcr); if (!sp->api) { len = pm_strcpy(msg, "====\n"); sendit(msg, len, sp); } } static void list_terminated_jobs(STATUS_PKT *sp) { int len; char level[10]; struct s_last_job *je; POOL_MEM msg(PM_MESSAGE); char dt[MAX_TIME_LENGTH], b1[30], b2[30]; if (!sp->api) { len = pm_strcpy(msg, _("\nTerminated Jobs:\n")); sendit(msg, len, sp); } if (last_jobs->size() == 0) { if (!sp->api) { len = pm_strcpy(msg, "====\n"); sendit(msg, len, sp); } return; } lock_last_jobs_list(); if (!sp->api) { len = pm_strcpy(msg, _(" JobId Level Files Bytes Status Finished Name \n")); sendit(msg, len, sp); len = pm_strcpy(msg, _("===================================================================\n")); sendit(msg, len, sp); } foreach_dlist(je, last_jobs) { char JobName[MAX_NAME_LENGTH]; const char *termstat; bstrftime_nc(dt, sizeof(dt), je->end_time); switch (je->JobType) { case JT_ADMIN: case JT_RESTORE: bstrncpy(level, " ", sizeof(level)); break; default: bstrncpy(level, level_to_str(je->JobLevel), sizeof(level)); level[4] = 0; break; } switch (je->JobStatus) { case JS_Created: termstat = _("Created"); break; case JS_FatalError: case JS_ErrorTerminated: termstat = _("Error"); break; case JS_Differences: termstat = _("Diffs"); break; case JS_Canceled: termstat = _("Cancel"); break; case JS_Terminated: termstat = _("OK"); break; case JS_Warnings: termstat = _("OK -- with warnings"); break; default: termstat = _("Other"); break; } bstrncpy(JobName, je->Job, sizeof(JobName)); /* There are three periods after the Job name */ char *p; for (int i=0; i<3; i++) { if ((p=strrchr(JobName, '.')) != NULL) { *p = 0; } } if (sp->api) { len = Mmsg(msg, _("%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"), je->JobId, level, edit_uint64_with_commas(je->JobFiles, b1), edit_uint64_with_suffix(je->JobBytes, b2), termstat, dt, JobName); } else { len = Mmsg(msg, _("%6d %-6s %8s %10s %-7s %-8s %s\n"), je->JobId, level, edit_uint64_with_commas(je->JobFiles, b1), edit_uint64_with_suffix(je->JobBytes, b2), termstat, dt, JobName); } sendit(msg, len, sp); } unlock_last_jobs_list(); if (!sp->api) { len = pm_strcpy(msg, "====\n"); sendit(msg, len, sp); } } /* * Convert Job Level into a string */ static const char *level_to_str(int level) { const char *str; switch (level) { case L_BASE: str = _("Base"); break; case L_FULL: str = _("Full"); break; case L_INCREMENTAL: str = _("Incremental"); break; case L_DIFFERENTIAL: str = _("Differential"); break; case L_SINCE: str = _("Since"); break; case L_VERIFY_CATALOG: str = _("Verify Catalog"); break; case L_VERIFY_INIT: str = _("Init Catalog"); break; case L_VERIFY_VOLUME_TO_CATALOG: str = _("Volume to Catalog"); break; case L_VERIFY_DISK_TO_CATALOG: str = _("Disk to Catalog"); break; case L_VERIFY_DATA: str = _("Data"); break; case L_NONE: str = " "; break; default: str = _("Unknown Job Level"); break; } return str; } /* * Send to Director */ static void sendit(const char *msg, int len, STATUS_PKT *sp) { BSOCK *bs = sp->bs; if (bs) { memcpy(bs->msg, msg, len+1); bs->msglen = len+1; bs->send(); } else { sp->callback(msg, len, sp->context); } } static void sendit(const char *msg, int len, void *sp) { sendit(msg, len, (STATUS_PKT *)sp); } static void sendit(POOL_MEM &msg, int len, STATUS_PKT *sp) { BSOCK *bs = sp->bs; if (bs) { memcpy(bs->msg, msg.c_str(), len+1); bs->msglen = len+1; bs->send(); } else { sp->callback(msg.c_str(), len, sp->context); } } /* * Status command from Director */ bool status_cmd(JCR *jcr) { POOL_MEM devicenames; STATUS_PKT sp; BSOCK *dir = jcr->dir_bsock; sp.bs = dir; devicenames.check_size(dir->msglen); if (sscanf(dir->msg, statuscmd, devicenames.c_str()) != 1) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3900 No arg in status command: %s\n"), jcr->errmsg); dir->signal(BNET_EOD); return false; } unbash_spaces(devicenames); dir->fsend("\n"); output_status(jcr, &sp, devicenames.c_str()); dir->signal(BNET_EOD); return true; } /* * .status command from Director */ bool dotstatus_cmd(JCR *jcr) { JCR *njcr; POOL_MEM cmd; STATUS_PKT sp; s_last_job* job; BSOCK *dir = jcr->dir_bsock; sp.bs = dir; cmd.check_size(dir->msglen); if (sscanf(dir->msg, dotstatuscmd, cmd.c_str()) != 1) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3900 No arg in .status command: %s\n"), jcr->errmsg); dir->signal(BNET_EOD); return false; } unbash_spaces(cmd); Dmsg1(200, "cmd=%s\n", cmd.c_str()); if (bstrcasecmp(cmd.c_str(), "current")) { dir->fsend(OKdotstatus, cmd.c_str()); foreach_jcr(njcr) { if (njcr->JobId != 0) { dir->fsend(DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors); } } endeach_jcr(njcr); } else if (bstrcasecmp(cmd.c_str(), "last")) { dir->fsend(OKdotstatus, cmd.c_str()); if ((last_jobs) && (last_jobs->size() > 0)) { job = (s_last_job*)last_jobs->last(); dir->fsend(DotStatusJob, job->JobId, job->JobStatus, job->Errors); } } else if (bstrcasecmp(cmd.c_str(), "header")) { sp.api = true; list_status_header(&sp); } else if (bstrcasecmp(cmd.c_str(), "running")) { sp.api = true; list_running_jobs(&sp); } else if (bstrcasecmp(cmd.c_str(), "waitreservation")) { sp.api = true; list_jobs_waiting_on_reservation(&sp); } else if (bstrcasecmp(cmd.c_str(), "devices")) { sp.api = true; list_devices(jcr, &sp, NULL); } else if (bstrcasecmp(cmd.c_str(), "volumes")) { sp.api = true; list_volumes(sendit, &sp); } else if (bstrcasecmp(cmd.c_str(), "spooling")) { sp.api = true; list_spool_stats(sendit, &sp); } else if (bstrcasecmp(cmd.c_str(), "terminated")) { sp.api = true; list_terminated_jobs(&sp); } else if (bstrcasecmp(cmd.c_str(), "resources")) { sp.api = true; list_resources(&sp); } else { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(_("3900 Unknown arg in .status command: %s\n"), jcr->errmsg); dir->signal(BNET_EOD); return false; } dir->signal(BNET_EOD); return true; } #if defined(HAVE_WIN32) int bareosstat = 0; /* * Return a one line status for the tray monitor */ char *bareos_status(char *buf, int buf_len) { JCR *njcr; const char *termstat = _("Bareos Storage: Idle"); struct s_last_job *job; int status = 0; /* Idle */ if (!last_jobs) { goto done; } Dmsg0(1000, "Begin bareos_status jcr loop.\n"); foreach_jcr(njcr) { if (njcr->JobId != 0) { status = JS_Running; termstat = _("Bareos Storage: Running"); break; } } endeach_jcr(njcr); if (status != 0) { goto done; } if (last_jobs->size() > 0) { job = (struct s_last_job *)last_jobs->last(); status = job->JobStatus; switch (job->JobStatus) { case JS_Canceled: termstat = _("Bareos Storage: Last Job Canceled"); break; case JS_ErrorTerminated: case JS_FatalError: termstat = _("Bareos Storage: Last Job Failed"); break; default: if (job->Errors) { termstat = _("Bareos Storage: Last Job had Warnings"); } break; } } Dmsg0(1000, "End bareos_status jcr loop.\n"); done: bareosstat = status; if (buf) { bstrncpy(buf, termstat, buf_len); } return buf; } #endif /* HAVE_WIN32 */ bareos-Release-14.2.6/src/stored/stored.c000066400000000000000000000562271263011562700202070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Second generation Storage daemon. * * Kern Sibbald, MM * * It accepts a number of simple commands from the File daemon * and acts on them. When a request to append data is made, * it opens a data channel and accepts data from the * File daemon. */ #include "bareos.h" #include "stored.h" #include "lib/crypto_cache.h" /* Imported functions */ extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ #if !defined(HAVE_WIN32) static #endif void terminate_stored(int sig); static int check_resources(); static void cleanup_old_files(); extern "C" void *device_initialization(void *arg); #define CONFIG_FILE "bareos-sd.conf" /* Default config file */ /* Global variables exported */ char OK_msg[] = "3000 OK\n"; char TERM_msg[] = "3999 Terminate\n"; void *start_heap; static uint32_t VolSessionId = 0; uint32_t VolSessionTime; bool init_done = false; /* Global static variables */ static bool foreground = 0; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static workq_t dird_workq; /* queue for processing connections */ #if HAVE_NDMP static workq_t ndmp_workq; /* queue for processing NDMP connections */ #endif static alist *sock_fds; static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n\n" "Usage: bareos-sd [options] [-c config_file] [config_file]\n" " -c use as configuration file\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -f run in foreground (for debugging)\n" " -g set groupid to group\n" " -m print kaboom output (for debugging)\n" " -p proceed despite I/O errors\n" " -s no signals (for debugging)\n" " -t test - read config and exit\n" " -u userid to \n" " -v verbose user messages\n" " -? print this message.\n" "\n"), 2000, VERSION, BDATE); exit(1); } /********************************************************************* * * Main Bareos Unix Storage Daemon * */ #if defined(HAVE_WIN32) #define main BareosMain #endif int main (int argc, char *argv[]) { int ch; bool no_signals = false; bool test_config = false; pthread_t thid; char *uid = NULL; char *gid = NULL; start_heap = sbrk(0); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "bareos-sd"); init_msg(NULL, NULL); daemon_start_time = time(NULL); /* Sanity checks */ if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) { Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"), TAPE_BSIZE, B_DEV_BSIZE); } if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) { Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE); } while ((ch = getopt(argc, argv, "c:d:fg:mpstu:v?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* run in foreground */ foreground = true; break; case 'g': /* set group id */ gid = optarg; break; case 'm': /* print kaboom output */ prt_kaboom = true; break; case 'p': /* proceed in spite of I/O errors */ forge_on = true; break; case 's': /* no signals */ no_signals = true; break; case 't': test_config = true; break; case 'u': /* set uid */ uid = optarg; break; case 'v': /* verbose */ verbose++; break; case '?': default: usage(); break; } } argc -= optind; argv += optind; if (argc) { if (configfile != NULL) { free(configfile); } configfile = bstrdup(*argv); argc--; argv++; } if (argc) usage(); /* * See if we want to drop privs. */ if (geteuid() == 0) { drop(uid, gid, false); } if (!no_signals) { init_signals(terminate_stored); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n")); } if (!check_resources()) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); } init_reservations_lock(); if (test_config) { terminate_stored(0); } my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */ if (!foreground) { daemon_start(); /* become daemon */ init_stack_dump(); /* pick up new pid */ } create_pid_file(me->pid_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); read_state_file(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); set_jcr_in_tsd(INVALID_JCR); /* * Make sure on Solaris we can run concurrent, watch dog + servers + misc */ set_thread_concurrency(me->max_concurrent_jobs * 2 + 4); lmgr_init_thread(); /* initialize the lockmanager stack */ load_sd_plugins(me->plugin_directory, me->plugin_names); cleanup_old_files(); /* Ensure that Volume Session Time and Id are both * set and are both non-zero. */ VolSessionTime = (uint32_t)daemon_start_time; if (VolSessionTime == 0) { /* paranoid */ Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n")); } /* * Start the device allocation thread */ create_volume_lists(); /* do before device_init */ if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) { berrno be; Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), be.bstrerror()); } start_watchdog(); /* start watchdog thread */ if (me->jcr_watchdog_time) { init_jcr_subsystem(me->jcr_watchdog_time); /* start JCR watchdogs etc. */ } start_statistics_thread(); #if HAVE_NDMP /* Seperate thread that handles NDMP connections */ if (me->ndmp_enable) { start_ndmp_thread_server(me->NDMPaddrs, me->max_concurrent_jobs * 2 + 1, &ndmp_workq); } #endif /* Single server used for Director/Storage and File daemon */ sock_fds = New(alist(10, not_owned_by_alist)); bnet_thread_server_tcp(me->SDaddrs, me->max_concurrent_jobs * 2 + 1, sock_fds, &dird_workq, me->nokeepalive, handle_connection_request); exit(1); /* to keep compiler quiet */ } /* Return a new Session Id */ uint32_t newVolSessionId() { uint32_t Id; P(mutex); VolSessionId++; Id = VolSessionId; V(mutex); return Id; } /* Check Configuration file for necessary info */ static int check_resources() { bool OK = true; bool tls_needed; if (GetNextRes(R_STORAGE, (RES *)me) != NULL) { Jmsg1(NULL, M_ERROR, 0, _("Only one Storage resource permitted in %s\n"), configfile); OK = false; } if (GetNextRes(R_DIRECTOR, NULL) == NULL) { Jmsg1(NULL, M_ERROR, 0, _("No Director resource defined in %s. Cannot continue.\n"), configfile); OK = false; } if (GetNextRes(R_DEVICE, NULL) == NULL){ Jmsg1(NULL, M_ERROR, 0, _("No Device resource defined in %s. Cannot continue.\n"), configfile); OK = false; } if (!me->messages) { me->messages = (MSGSRES *)GetNextRes(R_MSGS, NULL); if (!me->messages) { Jmsg1(NULL, M_ERROR, 0, _("No Messages resource defined in %s. Cannot continue.\n"), configfile); OK = false; } } if (!me->working_directory) { Jmsg1(NULL, M_ERROR, 0, _("No Working Directory defined in %s. Cannot continue.\n"), configfile); OK = false; } STORES *store; foreach_res(store, R_STORAGE) { /* tls_require implies tls_enable */ if (store->tls_require) { if (have_tls) { store->tls_enable = true; } else { Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bareos.\n")); OK = false; continue; } } tls_needed = store->tls_enable || store->tls_authenticate; if (!store->tls_certfile && tls_needed) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Storage \"%s\" in %s.\n"), store->hdr.name, configfile); OK = false; } if (!store->tls_keyfile && tls_needed) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Storage \"%s\" in %s.\n"), store->hdr.name, configfile); OK = false; } if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && tls_needed && store->tls_verify_peer) { Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Storage \"%s\" in %s." " At least one CA certificate store is required" " when using \"TLS Verify Peer\".\n"), store->hdr.name, configfile); OK = false; } /* If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (tls_needed || store->tls_require)) { /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ store->tls_ctx = new_tls_context(store->tls_ca_certfile, store->tls_ca_certdir, store->tls_crlfile, store->tls_certfile, store->tls_keyfile, NULL, NULL, store->tls_dhfile, store->tls_verify_peer); if (!store->tls_ctx) { Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Storage \"%s\" in %s.\n"), store->hdr.name, configfile); OK = false; } set_tls_enable(store->tls_ctx, tls_needed); set_tls_require(store->tls_ctx, store->tls_require); } } DIRRES *director; foreach_res(director, R_DIRECTOR) { /* tls_require implies tls_enable */ if (director->tls_require) { director->tls_enable = true; } tls_needed = director->tls_enable || director->tls_authenticate; if (!director->tls_certfile && tls_needed) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } if (!director->tls_keyfile && tls_needed) { Jmsg(NULL, M_FATAL, 0, _("\"TLS Key\" file not defined for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed && director->tls_verify_peer) { Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\"" " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s." " At least one CA certificate store is required" " when using \"TLS Verify Peer\".\n"), director->hdr.name, configfile); OK = false; } /* If everything is well, attempt to initialize our per-resource TLS context */ if (OK && (tls_needed || director->tls_require)) { /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ director->tls_ctx = new_tls_context(director->tls_ca_certfile, director->tls_ca_certdir, director->tls_crlfile, director->tls_certfile, director->tls_keyfile, NULL, NULL, director->tls_dhfile, director->tls_verify_peer); if (!director->tls_ctx) { Jmsg(NULL, M_FATAL, 0, _("Failed to initialize TLS context for Director \"%s\" in %s.\n"), director->hdr.name, configfile); OK = false; } set_tls_enable(director->tls_ctx, tls_needed); set_tls_require(director->tls_ctx, director->tls_require); } } DEVRES *device; foreach_res(device, R_DEVICE) { if (device->drive_crypto_enabled && device->cap_bits & CAP_LABEL) { Jmsg(NULL, M_FATAL, 0, _("LabelMedia enabled is incompatible with tape crypto on Device \"%s\" in %s.\n"), device->hdr.name, configfile); OK = false; } } if (OK) { OK = init_autochangers(); } if (OK) { close_msg(NULL); /* close temp message handler */ init_msg(NULL, me->messages); /* open daemon message handler */ set_working_directory(me->working_directory); } return OK; } /* * Remove old .spool files written by me from the working directory. */ static void cleanup_old_files() { DIR* dp; struct dirent *entry, *result; int rc, name_max; int my_name_len = strlen(my_name); int len = strlen(me->working_directory); POOLMEM *cleanup = get_pool_memory(PM_MESSAGE); POOLMEM *basename = get_pool_memory(PM_MESSAGE); regex_t preg1; char prbuf[500]; berrno be; /* Look for .spool files but don't allow spaces */ const char *pat1 = "^[^ ]+\\.spool$"; /* Setup working directory prefix */ pm_strcpy(basename, me->working_directory); if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) { pm_strcat(basename, "/"); } /* Compile regex expressions */ rc = regcomp(&preg1, pat1, REG_EXTENDED); if (rc != 0) { regerror(rc, &preg1, prbuf, sizeof(prbuf)); Pmsg2(000, _("Could not compile regex pattern \"%s\" ERR=%s\n"), pat1, prbuf); goto get_out2; } name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (!(dp = opendir(me->working_directory))) { berrno be; Pmsg2(000, "Failed to open working dir %s for cleanup: ERR=%s\n", me->working_directory, be.bstrerror()); goto get_out1; } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); while (1) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { break; } /* Exclude any name with ., .., not my_name or containing a space */ if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0 || strncmp(result->d_name, my_name, my_name_len) != 0) { Dmsg1(500, "Skipped: %s\n", result->d_name); continue; } /* Unlink files that match regex */ if (regexec(&preg1, result->d_name, 0, NULL, 0) == 0) { pm_strcpy(cleanup, basename); pm_strcat(cleanup, result->d_name); Dmsg1(500, "Unlink: %s\n", cleanup); unlink(cleanup); } } free(entry); closedir(dp); get_out1: regfree(&preg1); get_out2: free_pool_memory(cleanup); free_pool_memory(basename); } /* * Here we attempt to init and open each device. This is done once at startup in a separate thread. */ extern "C" void *device_initialization(void *arg) { DEVRES *device; DCR *dcr; JCR *jcr; DEVICE *dev; int errstat; LockRes(); pthread_detach(pthread_self()); jcr = new_jcr(sizeof(JCR), stored_free_jcr); new_plugins(jcr); /* instantiate plugins */ jcr->setJobType(JT_SYSTEM); /* * Initialize job start condition variable */ errstat = pthread_cond_init(&jcr->job_start_wait, NULL); if (errstat != 0) { berrno be; Jmsg1(jcr, M_ABORT, 0, _("Unable to init job start cond variable: ERR=%s\n"), be.bstrerror(errstat)); } /* * Initialize job end condition variable */ errstat = pthread_cond_init(&jcr->job_end_wait, NULL); if (errstat != 0) { berrno be; Jmsg1(jcr, M_ABORT, 0, _("Unable to init job endstart cond variable: ERR=%s\n"), be.bstrerror(errstat)); } foreach_res(device, R_DEVICE) { Dmsg1(90, "calling init_dev %s\n", device->device_name); dev = init_dev(NULL, device); Dmsg1(10, "SD init done %s\n", device->device_name); if (!dev) { Jmsg1(NULL, M_ERROR, 0, _("Could not initialize %s\n"), device->device_name); continue; } dcr = New(SD_DCR); jcr->dcr = dcr; setup_new_dcr_device(jcr, dcr, dev, NULL); jcr->dcr->set_will_write(); generate_plugin_event(jcr, bsdEventDeviceInit, dcr); if (dev->is_autochanger()) { /* * If autochanger set slot in dev structure */ get_autochanger_loaded_slot(dcr); } if (device->cap_bits & CAP_ALWAYSOPEN) { Dmsg1(20, "calling first_open_device %s\n", dev->print_name()); if (!first_open_device(dcr)) { Jmsg1(NULL, M_ERROR, 0, _("Could not open device %s\n"), dev->print_name()); Dmsg1(20, "Could not open device %s\n", dev->print_name()); free_dcr(dcr); jcr->dcr = NULL; continue; } } if (device->cap_bits & CAP_AUTOMOUNT && dev->is_open()) { switch (read_dev_volume_label(dcr)) { case VOL_OK: memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo)); volume_unused(dcr); /* mark volume "released" */ break; default: Jmsg1(NULL, M_WARNING, 0, _("Could not mount device %s\n"), dev->print_name()); break; } } free_dcr(dcr); jcr->dcr = NULL; } #ifdef xxx if (jcr->dcr) { Dmsg1(000, "free_dcr=%p\n", jcr->dcr); free_dcr(jcr->dcr); jcr->dcr = NULL; } #endif free_jcr(jcr); init_done = true; UnlockRes(); return NULL; } /* * Clean up and then exit */ #if !defined(HAVE_WIN32) static #endif void terminate_stored(int sig) { static bool in_here = false; DEVRES *device; JCR *jcr; if (in_here) { /* prevent loops */ bmicrosleep(2, 0); /* yield */ exit(1); } in_here = true; debug_level = 0; /* turn off any debug */ stop_statistics_thread(); #if HAVE_NDMP if (me->ndmp_enable) { stop_ndmp_thread_server(); } #endif stop_watchdog(); cleanup_bnet_thread_server_tcp(sock_fds, &dird_workq); delete sock_fds; sock_fds = NULL; if (sig == SIGTERM) { /* normal shutdown request? */ /* * This is a normal shutdown request. We wiffle through * all open jobs canceling them and trying to wake * them up so that they will report back the correct * volume status. */ foreach_jcr(jcr) { BSOCK *fd; if (jcr->JobId == 0) { free_jcr(jcr); continue; /* ignore console */ } jcr->setJobStatus(JS_Canceled); fd = jcr->file_bsock; if (fd) { fd->set_timed_out(); jcr->my_thread_send_signal(TIMEOUT_SIGNAL); Dmsg1(100, "term_stored killing JobId=%d\n", jcr->JobId); /* ***FIXME*** wiffle through all dcrs */ if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->blocked()) { pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId); release_device_cond(); } if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->blocked()) { pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol); Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId); release_device_cond(); } bmicrosleep(0, 50000); } free_jcr(jcr); } bmicrosleep(0, 500000); /* give them 1/2 sec to clean up */ } write_state_file(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); delete_pid_file(me->pid_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); Dmsg1(200, "In terminate_stored() sig=%d\n", sig); unload_sd_plugins(); flush_crypto_cache(); free_volume_lists(); foreach_res(device, R_DEVICE) { Dmsg1(10, "Term device %s\n", device->device_name); if (device->dev) { device->dev->clear_volhdr(); device->dev->term(); device->dev = NULL; } else { Dmsg1(10, "No dev structure %s\n", device->device_name); } } #if defined(HAVE_DYNAMIC_SD_BACKENDS) dev_flush_backends(); #endif if (configfile) { free(configfile); configfile = NULL; } if (my_config) { my_config->free_resources(); free(my_config); my_config = NULL; } if (debug_level > 10) { print_memory_pool_stats(); } term_msg(); cleanup_crypto(); term_reservations_lock(); close_memory_pool(); lmgr_cleanup_main(); sm_dump(false); /* dump orphaned buffers */ exit(sig); } bareos-Release-14.2.6/src/stored/stored.conf.in000066400000000000000000000027361263011562700213130ustar00rootroot00000000000000# # Bareos Storage Daemon Configuration file # # For Bareos release @VERSION@ (@DATE@) -- @DISTNAME@ @DISTVER@ # # "Global" Storage daemon configuration specifications # Storage { Name = "Storage daemon" Address = @hostname@ SDPort = @sd_port@ # Directors port WorkingDirectory = "@working_dir@" Pid Directory = "@piddir@" } # # List Directors who are permitted to contact Storage daemon # Director { Name = @hostname@-dir Password = local_storage_password } # # Devices supported by this Storage daemon # To connect, the Director must have the same Name and MediaType, # which are sent to the File daemon # # For the settings of Block and File Sizes, see: # http://www.bareos.org/en/Whitepapers/articles/Speed_Tuning_of_Tape_Drives.html Device { Name = "LTO-6" Media Type = LTO Archive Device = /dev/nst0 Minimum Block Size = 1048576 Maximum Block Size = 1048576 Maximum File Size = 50g # 20g for LTO4, 40g for LTO5 AutomaticMount = yes; # when device opened, read it AlwaysOpen = yes; RemovableMedia = yes; } #Device { # Name = "Exabyte 8mm" # Media Type = "8mm" # Archive Device = /dev/nst1 # Hardware end of medium = No; ## LabelMedia = yes; # lets Bareos label unlabeled media # AutomaticMount = yes; # when device opened, read it # AlwaysOpen = Yes; # RemovableMedia = yes; #} Messages { Name = Standard director = @hostname@-dir = all operator = @dump_email@ = mount } bareos-Release-14.2.6/src/stored/stored.h000066400000000000000000000041701263011562700202020ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2013 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Storage daemon specific defines and includes */ #ifndef __STORED_H_ #define __STORED_H_ #define STORAGE_DAEMON 1 /* Set to debug mutexes */ //#define SD_DEBUG_LOCK #ifdef SD_DEBUG_LOCK const int sd_dbglvl = 3; #else const int sd_dbglvl = 300; #endif #ifdef HAVE_MTIO_H #include #else #ifdef HAVE_SYS_MTIO_H #ifdef HAVE_AIX_OS #define _MTEXTEND_H 1 #endif #include #else #ifdef HAVE_SYS_TAPE_H #include #else /* Needed for Mac 10.6 (Snow Leopard) */ #include "lib/bmtio.h" #endif #endif #endif #include "lib/bsr.h" #include "ch.h" #include "lock.h" #include "block.h" #include "record.h" #include "dev.h" #include "stored_conf.h" #include "jcr.h" #include "vol_mgr.h" #include "reserve.h" #include "protos.h" #ifdef HAVE_FNMATCH #include #else #include "lib/fnmatch.h" #endif #ifdef HAVE_DIRENT_H #include #define NAMELEN(dirent) (strlen((dirent)->d_name)) #endif #ifndef HAVE_READDIR_R int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #endif #include "sd_plugins.h" extern char SD_IMP_EXP *configfile; extern bool SD_IMP_EXP forge_on; /* Proceed inspite of I/O errors */ extern STORES SD_IMP_EXP *me; /* "Global" daemon resource */ extern CONFIG SD_IMP_EXP *my_config; /* Our Global config */ #endif /* __STORED_H_ */ bareos-Release-14.2.6/src/stored/stored_conf.c000066400000000000000000001137501263011562700212070ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2009 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Configuration file parser for Bareos Storage daemon * * Kern Sibbald, March MM */ #include "bareos.h" #include "stored.h" /* * First and last resource ids */ static RES *sres_head[R_LAST - R_FIRST + 1]; static RES **res_head = sres_head; /* * Forward referenced subroutines */ /* * We build the current resource here statically, * then move it to dynamic memory */ static URES res_all; static int32_t res_all_size = sizeof(res_all); /* * Definition of records permitted within each * resource with the routine to process the record * information. */ /* * Globals for the Storage daemon. */ static RES_ITEM store_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_store.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_store.hdr.desc), 0, 0, NULL }, { "sdport", CFG_TYPE_ADDRESSES_PORT, ITEM(res_store.SDaddrs), 0, CFG_ITEM_DEFAULT, SD_DEFAULT_PORT }, { "sdaddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_store.SDaddrs), 0, CFG_ITEM_DEFAULT, SD_DEFAULT_PORT }, { "sdaddresses", CFG_TYPE_ADDRESSES, ITEM(res_store.SDaddrs), 0, CFG_ITEM_DEFAULT, SD_DEFAULT_PORT }, { "sdsourceaddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_store.SDsrc_addr), 0, CFG_ITEM_DEFAULT, "0" }, { "workingdirectory", CFG_TYPE_DIR, ITEM(res_store.working_directory), 0, CFG_ITEM_DEFAULT, _PATH_BAREOS_WORKINGDIR }, { "piddirectory", CFG_TYPE_DIR, ITEM(res_store.pid_directory), 0, CFG_ITEM_DEFAULT, _PATH_BAREOS_PIDDIR }, { "subsysdirectory", CFG_TYPE_DIR, ITEM(res_store.subsys_directory), CFG_ITEM_DEPRECATED, 0, NULL }, #if defined(HAVE_DYNAMIC_SD_BACKENDS) { "backenddirectory", CFG_TYPE_ALIST_DIR, ITEM(res_store.backend_directories), 0, CFG_ITEM_DEFAULT, _PATH_BAREOS_BACKENDDIR }, #endif { "plugindirectory", CFG_TYPE_DIR, ITEM(res_store.plugin_directory), 0, 0, NULL }, { "pluginnames", CFG_TYPE_PLUGIN_NAMES, ITEM(res_store.plugin_names), 0, 0, NULL }, { "scriptsdirectory", CFG_TYPE_DIR, ITEM(res_store.scripts_directory), 0, 0, NULL }, { "maximumconcurrentjobs", CFG_TYPE_PINT32, ITEM(res_store.max_concurrent_jobs), 0, CFG_ITEM_DEFAULT, "20" }, { "messages", CFG_TYPE_RES, ITEM(res_store.messages), R_MSGS, 0, NULL }, { "sdconnecttimeout", CFG_TYPE_TIME, ITEM(res_store.SDConnectTimeout), 0, CFG_ITEM_DEFAULT, "1800" /* 30 minutes */ }, { "fdconnecttimeout", CFG_TYPE_TIME, ITEM(res_store.FDConnectTimeout), 0, CFG_ITEM_DEFAULT, "1800" /* 30 minutes */ }, { "heartbeatinterval", CFG_TYPE_TIME, ITEM(res_store.heartbeat_interval), 0, CFG_ITEM_DEFAULT, "0" }, { "maximumnetworkbuffersize", CFG_TYPE_PINT32, ITEM(res_store.max_network_buffer_size), 0, 0, NULL }, { "tlsauthenticate", CFG_TYPE_BOOL, ITEM(res_store.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(res_store.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(res_store.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(res_store.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(res_store.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(res_store.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(res_store.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(res_store.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(res_store.tls_keyfile), 0, 0, NULL }, { "tlsdhfile", CFG_TYPE_DIR, ITEM(res_store.tls_dhfile), 0, 0, NULL }, { "tlsallowedcn", CFG_TYPE_ALIST_STR, ITEM(res_store.tls_allowed_cns), 0, 0, NULL }, { "clientconnectwait", CFG_TYPE_TIME, ITEM(res_store.client_wait), 0, CFG_ITEM_DEFAULT, "1800" /* 30 minutes */ }, { "verid", CFG_TYPE_STR, ITEM(res_store.verid), 0, 0, NULL }, { "compatible", CFG_TYPE_BOOL, ITEM(res_store.compatible), 0, CFG_ITEM_DEFAULT, "true" }, { "maximumbandwidthperjob", CFG_TYPE_SPEED, ITEM(res_store.max_bandwidth_per_job), 0, 0, NULL }, { "allowbandwidthbursting", CFG_TYPE_BOOL, ITEM(res_store.allow_bw_bursting), 0, CFG_ITEM_DEFAULT, "false" }, { "ndmpenable", CFG_TYPE_BOOL, ITEM(res_store.ndmp_enable), 0, CFG_ITEM_DEFAULT, "false" }, { "ndmpsnooping", CFG_TYPE_BOOL, ITEM(res_store.ndmp_snooping), 0, CFG_ITEM_DEFAULT, "false" }, { "ndmploglevel", CFG_TYPE_PINT32, ITEM(res_store.ndmploglevel), 0, CFG_ITEM_DEFAULT, "4" }, { "ndmpaddress", CFG_TYPE_ADDRESSES_ADDRESS, ITEM(res_store.NDMPaddrs), 0, CFG_ITEM_DEFAULT, "10000" }, { "ndmpaddresses", CFG_TYPE_ADDRESSES, ITEM(res_store.NDMPaddrs), 0, CFG_ITEM_DEFAULT, "10000" }, { "ndmpport", CFG_TYPE_ADDRESSES_PORT, ITEM(res_store.NDMPaddrs), 0, CFG_ITEM_DEFAULT, "10000" }, { "autoxflateonreplication", CFG_TYPE_BOOL, ITEM(res_store.autoxflateonreplication), 0, CFG_ITEM_DEFAULT, "false" }, { "absolutejobtimeout", CFG_TYPE_PINT32, ITEM(res_store.jcr_watchdog_time), 0, 0, NULL }, { "collectdevicestatistics", CFG_TYPE_BOOL, ITEM(res_store.collect_dev_stats), 0, CFG_ITEM_DEFAULT, "false" }, { "collectjobstatistics", CFG_TYPE_BOOL, ITEM(res_store.collect_job_stats), 0, CFG_ITEM_DEFAULT, "false" }, { "statisticscollectinterval", CFG_TYPE_PINT32, ITEM(res_store.stats_collect_interval), 0, CFG_ITEM_DEFAULT, "30" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Directors that can speak to the Storage daemon */ static RES_ITEM dir_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_dir.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_dir.hdr.desc), 0, 0, NULL }, { "password", CFG_TYPE_AUTOPASSWORD, ITEM(res_dir.password), 0, CFG_ITEM_REQUIRED, NULL }, { "monitor", CFG_TYPE_BOOL, ITEM(res_dir.monitor), 0, 0, NULL }, { "tlsauthenticate", CFG_TYPE_BOOL, ITEM(res_dir.tls_authenticate), 0, 0, NULL }, { "tlsenable", CFG_TYPE_BOOL, ITEM(res_dir.tls_enable), 0, 0, NULL }, { "tlsrequire", CFG_TYPE_BOOL, ITEM(res_dir.tls_require), 0, 0, NULL }, { "tlsverifypeer", CFG_TYPE_BOOL, ITEM(res_dir.tls_verify_peer), 0, CFG_ITEM_DEFAULT, "true" }, { "tlscacertificatefile", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certfile), 0, 0, NULL }, { "tlscacertificatedir", CFG_TYPE_DIR, ITEM(res_dir.tls_ca_certdir), 0, 0, NULL }, { "tlscertificaterevocationlist", CFG_TYPE_DIR, ITEM(res_dir.tls_crlfile), 0, 0, NULL }, { "tlscertificate", CFG_TYPE_DIR, ITEM(res_dir.tls_certfile), 0, 0, NULL }, { "tlskey", CFG_TYPE_DIR, ITEM(res_dir.tls_keyfile), 0, 0, NULL }, { "tlsdhfile", CFG_TYPE_DIR, ITEM(res_dir.tls_dhfile), 0, 0, NULL }, { "tlsallowedcn", CFG_TYPE_ALIST_STR, ITEM(res_dir.tls_allowed_cns), 0, 0, NULL }, { "maximumbandwidthperjob", CFG_TYPE_SPEED, ITEM(res_dir.max_bandwidth_per_job), 0, 0, NULL }, { "keyencryptionkey", CFG_TYPE_AUTOPASSWORD, ITEM(res_dir.keyencrkey), 1, 0, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * NDMP DMA's that can speak to the Storage daemon */ static RES_ITEM ndmp_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_ndmp.hdr.name), 0, CFG_ITEM_REQUIRED, 0 }, { "description", CFG_TYPE_STR, ITEM(res_ndmp.hdr.desc), 0, 0, 0 }, { "username", CFG_TYPE_STR, ITEM(res_ndmp.username), 0, CFG_ITEM_REQUIRED, 0 }, { "password", CFG_TYPE_AUTOPASSWORD, ITEM(res_ndmp.password), 0, CFG_ITEM_REQUIRED, 0 }, { "authtype", CFG_TYPE_AUTHTYPE, ITEM(res_ndmp.AuthType), 0, CFG_ITEM_DEFAULT, "None" }, { "loglevel", CFG_TYPE_PINT32, ITEM(res_ndmp.LogLevel), 0, CFG_ITEM_DEFAULT, "4" }, { NULL, 0, { 0 }, 0, 0, 0 } }; /* * Device definition */ static RES_ITEM dev_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_dev.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_dev.hdr.desc), 0, 0, NULL }, { "mediatype", CFG_TYPE_STRNAME, ITEM(res_dev.media_type), 0, CFG_ITEM_REQUIRED, NULL }, { "devicetype", CFG_TYPE_DEVTYPE, ITEM(res_dev.dev_type), 0, 0, NULL }, { "archivedevice", CFG_TYPE_STRNAME, ITEM(res_dev.device_name), 0, CFG_ITEM_REQUIRED, NULL }, { "diagnosticdevice", CFG_TYPE_STRNAME, ITEM(res_dev.diag_device_name), 0, 0, NULL }, { "hardwareendoffile", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_EOF, CFG_ITEM_DEFAULT, "on" }, { "hardwareendofmedium", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_EOM, CFG_ITEM_DEFAULT, "on" }, { "backwardspacerecord", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_BSR, CFG_ITEM_DEFAULT, "on" }, { "backwardspacefile", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_BSF, CFG_ITEM_DEFAULT, "on" }, { "bsfateom", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_BSFATEOM, CFG_ITEM_DEFAULT, "off" }, { "twoeof", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_TWOEOF, CFG_ITEM_DEFAULT, "off" }, { "forwardspacerecord", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_FSR, CFG_ITEM_DEFAULT, "on" }, { "forwardspacefile", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_FSF, CFG_ITEM_DEFAULT, "on" }, { "fastforwardspacefile", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_FASTFSF, CFG_ITEM_DEFAULT, "on" }, { "removablemedia", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_REM, CFG_ITEM_DEFAULT, "on" }, { "randomaccess", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_RACCESS, CFG_ITEM_DEFAULT, "off" }, { "automaticmount", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_AUTOMOUNT, CFG_ITEM_DEFAULT, "off" }, { "labelmedia", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_LABEL, CFG_ITEM_DEFAULT, "off" }, { "alwaysopen", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_ALWAYSOPEN, CFG_ITEM_DEFAULT, "on" }, { "autochanger", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_AUTOCHANGER, CFG_ITEM_DEFAULT, "off" }, { "closeonpoll", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_CLOSEONPOLL, CFG_ITEM_DEFAULT, "off" }, { "blockpositioning", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_POSITIONBLOCKS, CFG_ITEM_DEFAULT, "on" }, { "usemtiocget", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_MTIOCGET, CFG_ITEM_DEFAULT, "on" }, { "checklabels", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_CHECKLABELS, CFG_ITEM_DEFAULT, "off" }, { "requiresmount", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_REQMOUNT, CFG_ITEM_DEFAULT, "off" }, { "offlineonunmount", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_OFFLINEUNMOUNT, CFG_ITEM_DEFAULT, "off" }, { "blockchecksum", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_BLOCKCHECKSUM, CFG_ITEM_DEFAULT, "on" }, { "autoselect", CFG_TYPE_BOOL, ITEM(res_dev.autoselect), 0, CFG_ITEM_DEFAULT, "true" }, { "changerdevice", CFG_TYPE_STRNAME, ITEM(res_dev.changer_name), 0, 0, NULL }, { "changercommand", CFG_TYPE_STRNAME, ITEM(res_dev.changer_command), 0, 0, NULL }, { "alertcommand", CFG_TYPE_STRNAME, ITEM(res_dev.alert_command), 0, 0, NULL }, { "maximumchangerwait", CFG_TYPE_TIME, ITEM(res_dev.max_changer_wait), 0, CFG_ITEM_DEFAULT, "300" /* 5 minutes */ }, { "maximumopenwait", CFG_TYPE_TIME, ITEM(res_dev.max_open_wait), 0, CFG_ITEM_DEFAULT, "300" /* 5 minutes */ }, { "maximumopenvolumes", CFG_TYPE_PINT32, ITEM(res_dev.max_open_vols), 0, CFG_ITEM_DEFAULT, "1" }, { "maximumnetworkbuffersize", CFG_TYPE_PINT32, ITEM(res_dev.max_network_buffer_size), 0, 0, NULL }, { "volumepollinterval", CFG_TYPE_TIME, ITEM(res_dev.vol_poll_interval), 0, CFG_ITEM_DEFAULT, "300" /* 5 minutes */ }, { "maximumrewindwait", CFG_TYPE_TIME, ITEM(res_dev.max_rewind_wait), 0, CFG_ITEM_DEFAULT, "300" /* 5 minutes */ }, { "labelblocksize", CFG_TYPE_PINT32, ITEM(res_dev.label_block_size), 0, CFG_ITEM_DEFAULT, "64512"/* DEFAULT_BLOCK_SIZE */ }, { "minimumblocksize", CFG_TYPE_PINT32, ITEM(res_dev.min_block_size), 0, 0, NULL }, { "maximumblocksize", CFG_TYPE_MAXBLOCKSIZE, ITEM(res_dev.max_block_size), 0, 0, NULL }, { "maximumvolumesize", CFG_TYPE_SIZE64, ITEM(res_dev.max_volume_size), 0, CFG_ITEM_DEPRECATED, NULL }, { "maximumfilesize", CFG_TYPE_SIZE64, ITEM(res_dev.max_file_size), 0, CFG_ITEM_DEFAULT, "1000000000" }, { "volumecapacity", CFG_TYPE_SIZE64, ITEM(res_dev.volume_capacity), 0, 0, NULL }, { "maximumconcurrentjobs", CFG_TYPE_PINT32, ITEM(res_dev.max_concurrent_jobs), 0, 0, NULL }, { "spooldirectory", CFG_TYPE_DIR, ITEM(res_dev.spool_directory), 0, 0, NULL }, { "maximumspoolsize", CFG_TYPE_SIZE64, ITEM(res_dev.max_spool_size), 0, 0, NULL }, { "maximumjobspoolsize", CFG_TYPE_SIZE64, ITEM(res_dev.max_job_spool_size), 0, 0, NULL }, { "driveindex", CFG_TYPE_PINT32, ITEM(res_dev.drive_index), 0, 0, NULL }, { "maximumpartsize", CFG_TYPE_SIZE64, ITEM(res_dev.max_part_size), 0, CFG_ITEM_DEPRECATED, NULL }, { "mountpoint", CFG_TYPE_STRNAME, ITEM(res_dev.mount_point), 0, 0, NULL }, { "mountcommand", CFG_TYPE_STRNAME, ITEM(res_dev.mount_command), 0, 0, NULL }, { "unmountcommand", CFG_TYPE_STRNAME, ITEM(res_dev.unmount_command), 0, 0, NULL }, { "writepartcommand", CFG_TYPE_STRNAME, ITEM(res_dev.write_part_command), 0, CFG_ITEM_DEPRECATED, NULL }, { "freespacecommand", CFG_TYPE_STRNAME, ITEM(res_dev.free_space_command), 0, CFG_ITEM_DEPRECATED, NULL }, { "labeltype", CFG_TYPE_LABEL, ITEM(res_dev.label_type), 0, 0, NULL }, { "norewindonclose", CFG_TYPE_BOOL, ITEM(res_dev.norewindonclose), 0, CFG_ITEM_DEFAULT, "true" }, { "drivetapealertenabled", CFG_TYPE_BOOL, ITEM(res_dev.drive_tapealert_enabled), 0, 0, NULL }, { "drivecryptoenabled", CFG_TYPE_BOOL, ITEM(res_dev.drive_crypto_enabled), 0, 0, NULL }, { "querycryptostatus", CFG_TYPE_BOOL, ITEM(res_dev.query_crypto_status), 0, 0, NULL }, { "autodeflate", CFG_TYPE_IODIRECTION, ITEM(res_dev.autodeflate), 0, 0, NULL }, { "autodeflatealgorithm", CFG_TYPE_CMPRSALGO, ITEM(res_dev.autodeflate_algorithm), 0, 0, NULL }, { "autodeflatelevel", CFG_TYPE_PINT32, ITEM(res_dev.autodeflate_level), 0, CFG_ITEM_DEFAULT, "6" }, { "autoinflate", CFG_TYPE_IODIRECTION, ITEM(res_dev.autoinflate), 0, 0, NULL }, { "collectstatistics", CFG_TYPE_BOOL, ITEM(res_dev.collectstats), 0, CFG_ITEM_DEFAULT, "true" }, { NULL, 0, { 0 }, 0, 0, NULL } }; /* * Autochanger definition */ static RES_ITEM changer_items[] = { { "name", CFG_TYPE_NAME, ITEM(res_changer.hdr.name), 0, CFG_ITEM_REQUIRED, NULL }, { "description", CFG_TYPE_STR, ITEM(res_changer.hdr.desc), 0, 0, NULL }, { "device", CFG_TYPE_ALIST_RES, ITEM(res_changer.device), R_DEVICE, CFG_ITEM_REQUIRED, NULL }, { "changerdevice", CFG_TYPE_STRNAME, ITEM(res_changer.changer_name), 0, CFG_ITEM_REQUIRED, NULL }, { "changercommand", CFG_TYPE_STRNAME, ITEM(res_changer.changer_command), 0, CFG_ITEM_REQUIRED, NULL }, { NULL, 0, { 0 }, 0, 0, NULL } }; // { "mountanonymousvolumes", CFG_TYPE_BIT, ITEM(res_dev.cap_bits), CAP_ANONVOLS, CFG_ITEM_DEFAULT, "off" }, /* * Message resource */ #include "lib/msg_res.h" /* * This is the master resource definition */ static RES_TABLE resources[] = { { "director", dir_items, R_DIRECTOR, sizeof(DIRRES) }, { "ndmp", ndmp_items, R_NDMP, sizeof(NDMPRES) }, { "storage", store_items, R_STORAGE, sizeof(STORES) }, { "device", dev_items, R_DEVICE, sizeof(DEVRES) }, { "messages", msgs_items, R_MSGS, sizeof(MSGSRES) }, { "autochanger", changer_items, R_AUTOCHANGER, sizeof(AUTOCHANGERRES) }, { NULL, NULL, 0 } }; /* * Authentication methods */ static struct s_kw authmethods[] = { { "None", AT_NONE }, { "Clear", AT_CLEAR }, { "MD5", AT_MD5 }, { NULL, 0 } }; /* * Device types * * device type, device code = token */ static s_kw dev_types[] = { { "file", B_FILE_DEV }, { "tape", B_TAPE_DEV }, { "fifo", B_FIFO_DEV }, { "vtl", B_VTL_DEV }, { "gfapi", B_GFAPI_DEV }, { "object", B_OBJECT_STORE_DEV }, { "rados", B_RADOS_DEV }, { "cephfs", B_CEPHFS_DEV }, { NULL, 0 } }; /* * IO directions. */ static s_kw io_directions[] = { { "in", IO_DIRECTION_IN }, { "out", IO_DIRECTION_OUT }, { "both", IO_DIRECTION_INOUT }, { NULL, 0 } }; /* * Compression algorithms */ static s_kw compression_algorithms[] = { { "gzip", COMPRESS_GZIP }, { "lzo", COMPRESS_LZO1X }, { "lzfast", COMPRESS_FZFZ }, { "lz4", COMPRESS_FZ4L }, { "lz4hc", COMPRESS_FZ4H }, { NULL, 0 } }; /* * Store authentication type (Mostly for NDMP like clear or MD5). */ static void store_authtype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the type both pass 1 and pass 2 */ for (i = 0; authmethods[i].name; i++) { if (bstrcasecmp(lc->str, authmethods[i].name)) { *(uint32_t *)(item->value) = authmethods[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Authentication Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store password either clear if for NDMP or MD5 hashed for native. */ static void store_autopassword(LEX *lc, RES_ITEM *item, int index, int pass) { switch (res_all.hdr.rcode) { case R_DIRECTOR: /* * As we need to store both clear and MD5 hashed within the same * resource class we use the item->code as a hint default is 0 * and for clear we need a code of 1. */ switch (item->code) { case 1: store_resource(CFG_TYPE_CLEARPASSWORD, lc, item, index, pass); break; default: store_resource(CFG_TYPE_MD5PASSWORD, lc, item, index, pass); break; } break; case R_NDMP: store_resource(CFG_TYPE_CLEARPASSWORD, lc, item, index, pass); break; default: store_resource(CFG_TYPE_MD5PASSWORD, lc, item, index, pass); break; } } /* * Store Device Type (File, FIFO, Tape) */ static void store_devtype(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); /* * Store the label pass 2 so that type is defined */ for (i = 0; dev_types[i].name; i++) { if (bstrcasecmp(lc->str, dev_types[i].name)) { *(uint32_t *)(item->value) = dev_types[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Device Type keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store Maximum Block Size, and check it is not greater than MAX_BLOCK_LENGTH */ static void store_maxblocksize(LEX *lc, RES_ITEM *item, int index, int pass) { store_resource(CFG_TYPE_SIZE32, lc, item, index, pass); if (*(uint32_t *)(item->value) > MAX_BLOCK_LENGTH) { scan_err2(lc, _("Maximum Block Size configured value %u is greater than allowed maximum: %u"), *(uint32_t *)(item->value), MAX_BLOCK_LENGTH ); } } /* * Store the IO direction on a certain device. */ static void store_io_direction(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); for (i = 0; io_directions[i].name; i++) { if (bstrcasecmp(lc->str, io_directions[i].name)) { *(uint32_t *)(item->value) = io_directions[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a IO direction keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Store the compression algorithm to use on a certain device. */ static void store_compressionalgorithm(LEX *lc, RES_ITEM *item, int index, int pass) { int i; lex_get_token(lc, T_NAME); for (i = 0; compression_algorithms[i].name; i++) { if (bstrcasecmp(lc->str, compression_algorithms[i].name)) { *(uint32_t *)(item->value) = compression_algorithms[i].token; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Expected a Compression algorithm keyword, got: %s"), lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); clear_bit(index, res_all.hdr.inherit_content); } /* * Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { URES *res = (URES *)reshdr; char buf[1000]; int recurse = 1; IPADDR *addr; if (res == NULL) { sendit(sock, _("Warning: no \"%s\" resource (%d) defined.\n"), res_to_str(type), type); return; } sendit(sock, _("dump_resource type=%d\n"), type); if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_DIRECTOR: sendit(sock, "Director: name=%s\n", res->res_dir.hdr.name); break; case R_NDMP: sendit(sock, "NDMP DMA: name=%s\n", res->res_dir.hdr.name); break; case R_STORAGE: sendit(sock, "Storage: name=%s SDaddr=%s HB=%s\n", res->res_store.hdr.name, NPRT(get_first_address(res->res_store.SDaddrs, buf, sizeof(buf))), edit_utime(res->res_store.heartbeat_interval, buf, sizeof(buf))); if (res->res_store.SDaddrs) { foreach_dlist(addr, res->res_store.SDaddrs) { sendit(sock, " SDaddr=%s SDport=%d\n", addr->get_address(buf, sizeof(buf)), addr->get_port_host_order()); } } if (res->res_store.NDMPaddrs) { foreach_dlist(addr, res->res_store.NDMPaddrs) { sendit(sock, " NDMPaddr=%s NDMPport=%d\n", addr->get_address(buf, sizeof(buf)), addr->get_port_host_order()); } } break; case R_DEVICE: sendit(sock, "Device: name=%s MediaType=%s Device=%s DiagDevice=%s LabelType=%d\n", res->res_dev.hdr.name, res->res_dev.media_type, res->res_dev.device_name, NPRT(res->res_dev.diag_device_name), res->res_dev.label_type); sendit(sock, " rew_wait=%" lld " min_bs=%d max_bs=%d chgr_wait=%" lld "\n", res->res_dev.max_rewind_wait, res->res_dev.min_block_size, res->res_dev.max_block_size, res->res_dev.max_changer_wait); sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n", res->res_dev.max_volume_jobs, res->res_dev.max_volume_files, res->res_dev.max_volume_size); sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n", res->res_dev.max_file_size, res->res_dev.volume_capacity); sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory)); sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n", res->res_dev.max_spool_size, res->res_dev.max_job_spool_size); if (res->res_dev.changer_res) { sendit(sock, " changer=%p\n", res->res_dev.changer_res); } bstrncpy(buf, " ", sizeof(buf)); if (res->res_dev.cap_bits & CAP_EOF) { bstrncat(buf, "CAP_EOF ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_BSR) { bstrncat(buf, "CAP_BSR ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_BSF) { bstrncat(buf, "CAP_BSF ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_FSR) { bstrncat(buf, "CAP_FSR ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_FSF) { bstrncat(buf, "CAP_FSF ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_EOM) { bstrncat(buf, "CAP_EOM ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_REM) { bstrncat(buf, "CAP_REM ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_RACCESS) { bstrncat(buf, "CAP_RACCESS ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_AUTOMOUNT) { bstrncat(buf, "CAP_AUTOMOUNT ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_LABEL) { bstrncat(buf, "CAP_LABEL ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_ANONVOLS) { bstrncat(buf, "CAP_ANONVOLS ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_ALWAYSOPEN) { bstrncat(buf, "CAP_ALWAYSOPEN ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_CHECKLABELS) { bstrncat(buf, "CAP_CHECKLABELS ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_REQMOUNT) { bstrncat(buf, "CAP_REQMOUNT ", sizeof(buf)); } if (res->res_dev.cap_bits & CAP_OFFLINEUNMOUNT) { bstrncat(buf, "CAP_OFFLINEUNMOUNT ", sizeof(buf)); } bstrncat(buf, "\n", sizeof(buf)); sendit(sock, buf); break; case R_AUTOCHANGER: DEVRES *dev; sendit(sock, "Changer: name=%s Changer_devname=%s\n Changer_cmd=%s\n", res->res_changer.hdr.name, res->res_changer.changer_name, res->res_changer.changer_command); foreach_alist(dev, res->res_changer.device) { sendit(sock, " --->Device: name=%s\n", dev->hdr.name); } bstrncat(buf, "\n", sizeof(buf)); sendit(sock, buf); break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); if (res->res_msgs.mail_cmd) sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); if (res->res_msgs.operator_cmd) sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); break; default: sendit(sock, _("Warning: unknown resource type %d\n"), type); break; } if (recurse && res->res_dir.hdr.next) dump_resource(type, (RES *)res->res_dir.hdr.next, sendit, sock); } /* * Free memory of resource. * NB, we don't need to worry about freeing any references * to other resources as they will be freed when that * resource chain is traversed. Mainly we worry about freeing * allocated strings (names). */ void free_resource(RES *sres, int type) { RES *nres; URES *res = (URES *)sres; if (res == NULL) return; /* * Common stuff -- free the resource name */ nres = (RES *)res->res_dir.hdr.next; if (res->res_dir.hdr.name) { free(res->res_dir.hdr.name); } if (res->res_dir.hdr.desc) { free(res->res_dir.hdr.desc); } switch (type) { case R_DIRECTOR: if (res->res_dir.password.value) { free(res->res_dir.password.value); } if (res->res_dir.address) { free(res->res_dir.address); } if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } if (res->res_dir.tls_ca_certfile) { free(res->res_dir.tls_ca_certfile); } if (res->res_dir.tls_ca_certdir) { free(res->res_dir.tls_ca_certdir); } if (res->res_dir.tls_crlfile) { free(res->res_dir.tls_crlfile); } if (res->res_dir.tls_certfile) { free(res->res_dir.tls_certfile); } if (res->res_dir.tls_keyfile) { free(res->res_dir.tls_keyfile); } if (res->res_dir.tls_dhfile) { free(res->res_dir.tls_dhfile); } if (res->res_dir.tls_allowed_cns) { delete res->res_dir.tls_allowed_cns; } if (res->res_dir.keyencrkey.value) { free(res->res_dir.keyencrkey.value); } break; case R_NDMP: if (res->res_ndmp.username) { free(res->res_ndmp.username); } if (res->res_ndmp.password.value) { free(res->res_ndmp.password.value); } break; case R_AUTOCHANGER: if (res->res_changer.changer_name) { free(res->res_changer.changer_name); } if (res->res_changer.changer_command) { free(res->res_changer.changer_command); } if (res->res_changer.device) { delete res->res_changer.device; } rwl_destroy(&res->res_changer.changer_lock); break; case R_STORAGE: if (res->res_store.SDaddrs) { free_addresses(res->res_store.SDaddrs); } if (res->res_store.SDsrc_addr) { free_addresses(res->res_store.SDsrc_addr); } if (res->res_store.NDMPaddrs) { free_addresses(res->res_store.NDMPaddrs); } if (res->res_store.working_directory) { free(res->res_store.working_directory); } if (res->res_store.pid_directory) { free(res->res_store.pid_directory); } if (res->res_store.subsys_directory) { free(res->res_store.subsys_directory); } if (res->res_store.plugin_directory) { free(res->res_store.plugin_directory); } if (res->res_store.plugin_names) { delete res->res_store.plugin_names; } if (res->res_store.scripts_directory) { free(res->res_store.scripts_directory); } if (res->res_store.backend_directories) { delete res->res_store.backend_directories; } if (res->res_store.tls_ctx) { free_tls_context(res->res_store.tls_ctx); } if (res->res_store.tls_ca_certfile) { free(res->res_store.tls_ca_certfile); } if (res->res_store.tls_ca_certdir) { free(res->res_store.tls_ca_certdir); } if (res->res_store.tls_crlfile) { free(res->res_store.tls_crlfile); } if (res->res_store.tls_certfile) { free(res->res_store.tls_certfile); } if (res->res_store.tls_keyfile) { free(res->res_store.tls_keyfile); } if (res->res_store.tls_dhfile) { free(res->res_store.tls_dhfile); } if (res->res_store.tls_allowed_cns) { delete res->res_store.tls_allowed_cns; } if (res->res_store.verid) { free(res->res_store.verid); } break; case R_DEVICE: if (res->res_dev.media_type) { free(res->res_dev.media_type); } if (res->res_dev.device_name) { free(res->res_dev.device_name); } if (res->res_dev.diag_device_name) { free(res->res_dev.diag_device_name); } if (res->res_dev.changer_name) { free(res->res_dev.changer_name); } if (res->res_dev.changer_command) { free(res->res_dev.changer_command); } if (res->res_dev.alert_command) { free(res->res_dev.alert_command); } if (res->res_dev.spool_directory) { free(res->res_dev.spool_directory); } if (res->res_dev.mount_point) { free(res->res_dev.mount_point); } if (res->res_dev.mount_command) { free(res->res_dev.mount_command); } if (res->res_dev.unmount_command) { free(res->res_dev.unmount_command); } if (res->res_dev.write_part_command) { free(res->res_dev.write_part_command); } if (res->res_dev.free_space_command) { free(res->res_dev.free_space_command); } break; case R_MSGS: if (res->res_msgs.mail_cmd) { free(res->res_msgs.mail_cmd); } if (res->res_msgs.operator_cmd) { free(res->res_msgs.operator_cmd); } free_msgs_res((MSGSRES *)res); /* free message resource */ res = NULL; break; default: Dmsg1(0, _("Unknown resource type %d\n"), type); break; } /* * Common stuff again -- free the resource, recurse to next one */ if (res) { free(res); } if (nres) { free_resource(nres, type); } } /* * Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * or alist pointers. */ void save_resource(int type, RES_ITEM *items, int pass) { URES *res; int rindex = type - R_FIRST; int i; int error = 0; /* * Ensure that all required items are present */ for (i = 0; items[i].name; i++) { if (items[i].flags & CFG_ITEM_REQUIRED) { if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ERROR_TERM, 0, _("\"%s\" item is required in \"%s\" resource, but not found.\n"), items[i].name, resources[rindex]); } } /* * If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { Emsg1(M_ERROR_TERM, 0, _("Too many items in \"%s\" resource\n"), resources[rindex]); } } /* * During pass 2, we looked up pointers to all the resources * referrenced in the current resource, , now we * must copy their address from the static record to the allocated * record. */ if (pass == 2) { DEVRES *dev; int errstat; switch (type) { case R_DEVICE: case R_MSGS: case R_NDMP: /* * Resources not containing a resource */ break; case R_DIRECTOR: /* * Resources containing a resource or an alist */ if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Director resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_dir.tls_allowed_cns = res_all.res_dir.tls_allowed_cns; } break; case R_STORAGE: if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find Storage resource %s\n"), res_all.res_dir.hdr.name); } else { res->res_store.plugin_names = res_all.res_store.plugin_names; res->res_store.messages = res_all.res_store.messages; res->res_store.backend_directories = res_all.res_store.backend_directories; res->res_store.tls_allowed_cns = res_all.res_store.tls_allowed_cns; } break; case R_AUTOCHANGER: if ((res = (URES *)GetResWithName(type, res_all.res_changer.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, _("Cannot find AutoChanger resource %s\n"), res_all.res_changer.hdr.name); } else { /* * We must explicitly copy the device alist pointer */ res->res_changer.device = res_all.res_changer.device; /* * Now update each device in this resource to point back to the changer resource. */ foreach_alist(dev, res->res_changer.device) { dev->changer_res = (AUTOCHANGERRES *)&res->res_changer; } if ((errstat = rwl_init(&res->res_changer.changer_lock, PRIO_SD_ACH_ACCESS)) != 0) { berrno be; Jmsg1(NULL, M_ERROR_TERM, 0, _("Unable to init lock: ERR=%s\n"), be.bstrerror(errstat)); } } break; default: printf(_("Unknown resource type %d\n"), type); error = 1; break; } if (res_all.res_dir.hdr.name) { free(res_all.res_dir.hdr.name); res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { free(res_all.res_dir.hdr.desc); res_all.res_dir.hdr.desc = NULL; } return; } /* * Common */ if (!error) { res = (URES *)malloc(resources[rindex].size); memcpy(res, &res_all, resources[rindex].size); if (!res_head[rindex]) { res_head[rindex] = (RES *)res; /* store first entry */ } else { RES *next, *last; /* * Add new res to end of chain */ for (last = next = res_head[rindex]; next; next = next->next) { last = next; if (bstrcmp(next->name, res->res_dir.hdr.name)) { Emsg2(M_ERROR_TERM, 0, _("Attempt to define second \"%s\" resource named \"%s\" is not permitted.\n"), resources[rindex].name, res->res_dir.hdr.name); } } last->next = (RES *)res; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), res->res_dir.hdr.name); } } } /* * callback function for init_resource * See ../lib/parse_conf.c, function init_resource, for more generic handling. */ static void init_resource_cb(RES_ITEM *item, int pass) { switch (pass) { case 1: switch (item->type) { case CFG_TYPE_AUTHTYPE: for (int i = 0; authmethods[i].name; i++) { if (bstrcasecmp(item->default_value, authmethods[i].name)) { *(uint32_t *)(item->value) = authmethods[i].token; } } break; default: break; } break; default: break; } } /* * callback function for parse_config * See ../lib/parse_conf.c, function parse_config, for more generic handling. */ static void parse_config_cb(LEX *lc, RES_ITEM *item, int index, int pass) { switch (item->type) { case CFG_TYPE_AUTOPASSWORD: store_autopassword(lc, item, index, pass); break; case CFG_TYPE_AUTHTYPE: store_authtype(lc, item, index, pass); break; case CFG_TYPE_DEVTYPE: store_devtype(lc, item, index, pass); break; case CFG_TYPE_MAXBLOCKSIZE: store_maxblocksize(lc, item, index, pass); break; case CFG_TYPE_IODIRECTION: store_io_direction(lc, item, index, pass); break; case CFG_TYPE_CMPRSALGO: store_compressionalgorithm(lc, item, index, pass); break; default: break; } } bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code) { bool retval; config->init(configfile, NULL, NULL, init_resource_cb, parse_config_cb, NULL, exit_code, (void *)&res_all, res_all_size, R_FIRST, R_LAST, resources, res_head); retval = config->parse_config(); if (retval) { me = (STORES *)GetNextRes(R_STORAGE, NULL); if (!me) { Emsg1(exit_code, 0, _("No Storage resource defined in %s. Cannot continue.\n"), configfile); return retval; } #if defined(HAVE_DYNAMIC_SD_BACKENDS) sd_set_backend_dirs(me->backend_directories); #endif } return retval; } bareos-Release-14.2.6/src/stored/stored_conf.h000066400000000000000000000227171263011562700212160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Resource codes -- they must be sequential for indexing */ enum { R_DIRECTOR = 3001, R_NDMP, R_STORAGE, R_DEVICE, R_MSGS, R_AUTOCHANGER, R_FIRST = R_DIRECTOR, R_LAST = R_AUTOCHANGER /* keep this updated */ }; enum { R_NAME = 3020, R_ADDRESS, R_PASSWORD, R_TYPE, R_BACKUP }; /* Definition of the contents of each Resource */ class DIRRES { public: RES hdr; s_password password; /* Director password */ char *address; /* Director IP address or zero */ bool monitor; /* Have only access to status and .status functions */ bool tls_authenticate; /* Authenticate with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Server Certificate File */ char *tls_keyfile; /* TLS Server Key File */ char *tls_dhfile; /* TLS Diffie-Hellman Parameters */ alist *tls_allowed_cns; /* TLS Allowed Clients */ uint64_t max_bandwidth_per_job; /* Bandwidth limitation (per director) */ s_password keyencrkey; /* Key Encryption Key */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; class NDMPRES { public: RES hdr; uint32_t AuthType; /* Authentication Type to use */ uint32_t LogLevel; /* Log level to use for logging NDMP protocol msgs */ char *username; /* NDMP username */ s_password password; /* NDMP password */ }; /* Storage daemon "global" definitions */ class STORES { public: RES hdr; dlist *SDaddrs; dlist *SDsrc_addr; /* Address to source connections from */ dlist *NDMPaddrs; char *working_directory; /* Working directory for checkpoints */ char *pid_directory; char *subsys_directory; char *plugin_directory; /* Plugin directory */ alist *plugin_names; char *scripts_directory; alist *backend_directories; /* Backend Directories */ uint32_t max_concurrent_jobs; /* Maximum concurrent jobs to run */ uint32_t ndmploglevel; /* Initial NDMP log level */ uint32_t jcr_watchdog_time; /* Absolute time after which a Job gets terminated regardless of its progress */ uint32_t stats_collect_interval; /* Statistics collect interval in seconds */ MSGSRES *messages; /* Daemon message handler */ utime_t SDConnectTimeout; /* Timeout in seconds */ utime_t FDConnectTimeout; /* Timeout in seconds */ utime_t heartbeat_interval; /* Interval to send hb to FD */ utime_t client_wait; /* Time to wait for FD to connect */ uint32_t max_network_buffer_size; /* Max network buf size */ bool autoxflateonreplication; /* Perform autoxflation when replicating data */ bool compatible; /* Write compatible format */ bool allow_bw_bursting; /* Allow bursting with bandwidth limiting */ bool ndmp_enable; /* Enable NDMP protocol listener */ bool ndmp_snooping; /* Enable NDMP protocol snooping */ bool tls_authenticate; /* Authenticate with TLS */ bool tls_enable; /* Enable TLS */ bool tls_require; /* Require TLS */ bool tls_verify_peer; /* TLS Verify Peer Certificate */ bool nokeepalive; /* Don't use SO_KEEPALIVE on sockets */ bool collect_dev_stats; /* Collect Device Statistics */ bool collect_job_stats; /* Collect Job Statistics */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_crlfile; /* TLS CA Certificate Revocation List File */ char *tls_certfile; /* TLS Server Certificate File */ char *tls_keyfile; /* TLS Server Key File */ char *tls_dhfile; /* TLS Diffie-Hellman Parameters */ alist *tls_allowed_cns; /* TLS Allowed Clients */ char *verid; /* Custom Id to print in version command */ uint64_t max_bandwidth_per_job; /* Bandwidth limitation (global) */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; class AUTOCHANGERRES { public: RES hdr; alist *device; /* List of DEVRES device pointers */ char *changer_name; /* Changer device name */ char *changer_command; /* Changer command -- external program */ brwlock_t changer_lock; /* One changer operation at a time */ }; /* Device specific definitions */ class DEVRES { public: RES hdr; char *media_type; /* User assigned media type */ char *device_name; /* Archive device name */ char *diag_device_name; /* Diagnostic device name */ char *changer_name; /* Changer device name */ char *changer_command; /* Changer command -- external program */ char *alert_command; /* Alert command -- external program */ char *spool_directory; /* Spool file directory */ uint32_t dev_type; /* device type */ uint32_t label_type; /* label type */ bool autoselect; /* Automatically select from AutoChanger */ bool norewindonclose; /* Don't rewind tape drive on close */ bool drive_tapealert_enabled; /* Enable Tape Alert monitoring */ bool drive_crypto_enabled; /* Enable hardware crypto */ bool query_crypto_status; /* Query device for crypto status */ bool collectstats; /* Set if statistics should be collected */ uint32_t drive_index; /* Autochanger drive index */ uint32_t cap_bits; /* Capabilities of this device */ utime_t max_changer_wait; /* Changer timeout */ utime_t max_rewind_wait; /* Maximum secs to wait for rewind */ utime_t max_open_wait; /* Maximum secs to wait for open */ uint32_t max_open_vols; /* Maximum simultaneous open volumes */ uint32_t label_block_size; /* block size of the label block*/ uint32_t min_block_size; /* Current Minimum block size */ uint32_t max_block_size; /* Current Maximum block size */ uint32_t max_volume_jobs; /* Max jobs to put on one volume */ uint32_t max_network_buffer_size; /* Max network buf size */ uint32_t max_concurrent_jobs; /* Maximum concurrent jobs this drive */ uint32_t autodeflate_algorithm; /* Compression algorithm to use for compression */ uint32_t autodeflate_level; /* Compression level to use for compression algorithm which uses levels */ uint32_t autodeflate; /* Perform auto deflation in this IO direction */ uint32_t autoinflate; /* Perform auto inflation in this IO direction */ utime_t vol_poll_interval; /* Interval between polling volume during mount */ int64_t max_volume_files; /* Max files to put on one volume */ int64_t max_volume_size; /* Max bytes to put on one volume */ int64_t max_file_size; /* Max file size in bytes */ int64_t volume_capacity; /* Advisory capacity */ int64_t max_spool_size; /* Max spool size for all jobs */ int64_t max_job_spool_size; /* Max spool size for any single job */ int64_t max_part_size; /* Max part size */ char *mount_point; /* Mount point for require mount devices */ char *mount_command; /* Mount command */ char *unmount_command; /* Unmount command */ char *write_part_command; /* Write part command */ char *free_space_command; /* Free space command */ /* * The following are set at runtime */ DEVICE *dev; /* Pointer to phyical dev -- set at runtime */ AUTOCHANGERRES *changer_res; /* Pointer to changer res if any */ }; union URES { DIRRES res_dir; NDMPRES res_ndmp; STORES res_store; DEVRES res_dev; MSGSRES res_msgs; AUTOCHANGERRES res_changer; RES hdr; }; bareos-Release-14.2.6/src/stored/vol_mgr.c000066400000000000000000000627061263011562700203530ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2013 Free Software Foundation Europe e.V. Copyright (C) 2015-2015 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Volume management functions for Storage Daemon * * Kern Sibbald, MM * * Split from reserve.c October 2008 */ #include "bareos.h" #include "stored.h" const int dbglvl = 150; static brwlock_t vol_list_lock; static dlist *vol_list = NULL; static dlist *read_vol_list = NULL; static bthread_mutex_t read_vol_lock = BTHREAD_MUTEX_PRIORITY(PRIO_SD_READ_VOL_LIST); /* Global static variables */ int vol_list_lock_count = 0; /* Forward referenced functions */ static void free_vol_item(VOLRES *vol); static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName); static void debug_list_volumes(const char *imsg); /* * For append volumes the key is the VolumeName. */ static int compare_by_volumename(void *item1, void *item2) { VOLRES *vol1 = (VOLRES *)item1; VOLRES *vol2 = (VOLRES *)item2; ASSERT(vol1->vol_name); ASSERT(vol2->vol_name); return strcmp(vol1->vol_name, vol2->vol_name); } /* * For read volumes the key is JobId, VolumeName. */ static int read_compare(void *item1, void *item2) { VOLRES *vol1 = (VOLRES *)item1; VOLRES *vol2 = (VOLRES *)item2; ASSERT(vol1->vol_name); ASSERT(vol2->vol_name); if (vol1->get_jobid() == vol2->get_jobid()) { return strcmp(vol1->vol_name, vol2->vol_name); } if (vol1->get_jobid() < vol2->get_jobid()) { return -1; } return 1; } bool is_vol_list_empty() { return vol_list->empty(); } /* * Initialized the main volume list. Note, we are using a recursive lock. */ void init_vol_list_lock() { int errstat; if ((errstat=rwl_init(&vol_list_lock, PRIO_SD_VOL_LIST)) != 0) { berrno be; Emsg1(M_ABORT, 0, _("Unable to initialize volume list lock. ERR=%s\n"), be.bstrerror(errstat)); } } void term_vol_list_lock() { rwl_destroy(&vol_list_lock); } /* * This allows a given thread to recursively call to lock_volumes() */ void _lock_volumes(const char *file, int line) { int errstat; vol_list_lock_count++; if ((errstat=rwl_writelock_p(&vol_list_lock, file, line)) != 0) { berrno be; Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n", errstat, be.bstrerror(errstat)); } } void _unlock_volumes() { int errstat; vol_list_lock_count--; if ((errstat=rwl_writeunlock(&vol_list_lock)) != 0) { berrno be; Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n", errstat, be.bstrerror(errstat)); } } #define lock_read_volumes() lock_read_volumes_p(__FILE__, __LINE__) static void lock_read_volumes_p(const char *file, int line) { bthread_mutex_lock_p(&read_vol_lock, file, line); } static void unlock_read_volumes() { bthread_mutex_unlock(&read_vol_lock); } /* * Add a volume to the read list. * * Note, we use VOLRES because it simplifies the code * even though, the only part of VOLRES that we need is * the volume name. The same volume may be in the list * multiple times, but each one is distinguished by the * JobId. We use JobId, VolumeName as the key. * * We can get called multiple times for the same volume because * when parsing the bsr, the volume name appears multiple times. */ void add_read_volume(JCR *jcr, const char *VolumeName) { VOLRES *nvol, *vol; nvol = new_vol_item(NULL, VolumeName); nvol->set_jobid(jcr->JobId); nvol->set_reading(); lock_read_volumes(); vol = (VOLRES *)read_vol_list->binary_insert(nvol, read_compare); if (vol != nvol) { free_vol_item(nvol); Dmsg2(dbglvl, "read_vol=%s JobId=%d already in list.\n", VolumeName, jcr->JobId); } else { Dmsg2(dbglvl, "add read_vol=%s JobId=%d\n", VolumeName, jcr->JobId); } unlock_read_volumes(); } /* * Remove a given volume name from the read list. */ void remove_read_volume(JCR *jcr, const char *VolumeName) { VOLRES vol, *fvol; lock_read_volumes(); memset(&vol, 0, sizeof(vol)); vol.vol_name = bstrdup(VolumeName); vol.set_jobid(jcr->JobId); fvol = (VOLRES *)read_vol_list->binary_search(&vol, read_compare); free(vol.vol_name); if (fvol) { Dmsg3(dbglvl, "remove_read_vol=%s JobId=%d found=%d\n", VolumeName, jcr->JobId, fvol!=NULL); } if (fvol) { read_vol_list->remove(fvol); free_vol_item(fvol); } unlock_read_volumes(); // pthread_cond_broadcast(&wait_next_vol); } /* * Search for a Volume name in the read Volume list. * * Returns: VOLRES entry on success * NULL if the Volume is not in the list */ static VOLRES *find_read_volume(const char *VolumeName) { VOLRES vol, *fvol; if (read_vol_list->empty()) { Dmsg0(dbglvl, "find_read_vol: read_vol_list empty.\n"); return NULL; } /* * Do not lock reservations here */ lock_read_volumes(); memset(&vol, 0, sizeof(vol)); vol.vol_name = bstrdup(VolumeName); /* * Note, we do want a simple compare_by_volumename on volume name only here */ fvol = (VOLRES *)read_vol_list->binary_search(&vol, compare_by_volumename); free(vol.vol_name); Dmsg2(dbglvl, "find_read_vol=%s found=%d\n", VolumeName, fvol!=NULL); unlock_read_volumes(); return fvol; } /* * List Volumes -- this should be moved to status.c */ enum { debug_lock = true, debug_nolock = false }; static void debug_list_volumes(const char *imsg) { VOLRES *vol; POOL_MEM msg(PM_MESSAGE); foreach_vol(vol) { if (vol->dev) { Mmsg(msg, "List %s: %s in_use=%d swap=%d on device %s\n", imsg, vol->vol_name, vol->is_in_use(), vol->is_swapping(), vol->dev->print_name()); } else { Mmsg(msg, "List %s: %s in_use=%d swap=%d no dev\n", imsg, vol->vol_name, vol->is_in_use(), vol->is_swapping()); } Dmsg1(dbglvl, "%s", msg.c_str()); } endeach_vol(vol); } /* * List Volumes -- this should be moved to status.c */ void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg) { VOLRES *vol; POOL_MEM msg(PM_MESSAGE); int len; foreach_vol(vol) { DEVICE *dev = vol->dev; if (dev) { len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name()); sendit(msg.c_str(), len, arg); len = Mmsg(msg, " Reader=%d writers=%d reserves=%d volinuse=%d\n", dev->can_read() ? 1 : 0, dev->num_writers, dev->num_reserved(), vol->is_in_use()); sendit(msg.c_str(), len, arg); } else { len = Mmsg(msg, "Volume %s no device. volinuse= %d\n", vol->vol_name, vol->is_in_use()); sendit(msg.c_str(), len, arg); } } endeach_vol(vol); lock_read_volumes(); foreach_dlist(vol, read_vol_list) { DEVICE *dev = vol->dev; if (dev) { len = Mmsg(msg, "Read volume: %s on device %s\n", vol->vol_name, dev->print_name()); sendit(msg.c_str(), len, arg); len = Mmsg(msg, " Reader=%d writers=%d reserves=%d volinuse=%d JobId=%d\n", dev->can_read() ? 1 : 0, dev->num_writers, dev->num_reserved(), vol->is_in_use(), vol->get_jobid()); sendit(msg.c_str(), len, arg); } else { len = Mmsg(msg, "Volume: %s no device. volinuse= %d\n", vol->vol_name, vol->is_in_use()); sendit(msg.c_str(), len, arg); } } unlock_read_volumes(); } /* * Create a Volume item to put in the Volume list * Ensure that the device points to it. */ static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName) { VOLRES *vol; vol = (VOLRES *)malloc(sizeof(VOLRES)); memset(vol, 0, sizeof(VOLRES)); vol->vol_name = bstrdup(VolumeName); if (dcr) { vol->dev = dcr->dev; Dmsg3(dbglvl, "new Vol=%s at %p dev=%s\n", VolumeName, vol->vol_name, vol->dev->print_name()); } vol->init_mutex(); vol->inc_use_count(); return vol; } static void free_vol_item(VOLRES *vol) { DEVICE *dev = NULL; vol->dec_use_count(); vol->Lock(); if (vol->use_count() > 0) { vol->Unlock(); return; } vol->Unlock(); free(vol->vol_name); if (vol->dev) { dev = vol->dev; } vol->destroy_mutex(); free(vol); if (dev) { dev->vol = NULL; } } /* * Put a new Volume entry in the Volume list. This * effectively reserves the volume so that it will * not be mounted again. * * If the device has any current volume associated with it, * and it is a different Volume, and the device is not busy, * we release the old Volume item and insert the new one. * * It is assumed that the device is free and locked so that * we can change the device structure. * * Some details of the Volume list handling: * * 1. The Volume list entry is attached to the drive (rather than * attached to a job as it was previously. I.e. the drive that "owns" * the volume (in use, mounted) * must point to the volume (still to be maintained in a list). * * 2. The Volume is entered in the list when a drive is reserved. * * 3. When a drive is in use, the device code must appropriately update the * volume name as it changes. * * This code keeps the same list entry as long as the drive * has any volume associated with it but the volume name in the list * must be updated when the drive has a different volume mounted. * * 4. A job that has reserved a volume, can un-reserve the volume, and if the * volume is not mounted, and not reserved, and not in use, it will be * removed from the list. * * 5. If a job wants to reserve a drive with a different Volume from the one on * the drive, it can re-use the drive for the new Volume. * * 6. If a job wants a Volume that is in a different drive, it can either use the * other drive or take the volume, only if the other drive is not in use or * not reserved. * * One nice aspect of this is that the reserve use count and the writer use count * already exist and are correctly programmed and will need no changes -- use * counts are always very tricky. * * The old code had a concept of "reserving" a Volume, but was changed * to reserving and using a drive. A volume is must be attached to (owned by) a * drive and can move from drive to drive or be unused given certain specific * conditions of the drive. The key is that the drive must "own" the Volume. * * Return: VOLRES entry on success * NULL volume busy on another drive */ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) { VOLRES *vol, *nvol; DEVICE * volatile dev = dcr->dev; if (job_canceled(dcr->jcr)) { return NULL; } ASSERT(dev != NULL); Dmsg2(dbglvl, "enter reserve_volume=%s drive=%s\n", VolumeName, dcr->dev->print_name()); /* * We lock the reservations system here to ensure when adding a new volume that no newly * scheduled job can reserve it. */ lock_volumes(); if (debug_level >= dbglvl) { debug_list_volumes("begin reserve_volume"); } /* * First, remove any old volume attached to this device as it is no longer used. */ if (dev->vol) { vol = dev->vol; Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volinuse=%d on %s\n", vol->vol_name, VolumeName, vol->is_in_use(), dev->print_name()); /* * Make sure we don't remove the current volume we are inserting * because it was probably inserted by another job, or it * is not being used and is marked as not reserved. */ if (bstrcmp(vol->vol_name, VolumeName)) { Dmsg2(dbglvl, "=== set reserved vol=%s dev=%s\n", VolumeName, vol->dev->print_name()); goto get_out; /* Volume already on this device */ } else { /* * Don't release a volume if it was reserved by someone other than us */ if (vol->is_in_use() && !dcr->reserved_volume) { Dmsg1(dbglvl, "Cannot free vol=%s. It is reserved.\n", vol->vol_name); vol = NULL; /* vol in use */ goto get_out; } Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name); /* * If old Volume is still mounted, must unload it */ if (bstrcmp(vol->vol_name, dev->VolHdr.VolumeName)) { Dmsg0(50, "set_unload\n"); dev->set_unload(); /* have to unload current volume */ } free_volume(dev); /* Release old volume entry */ if (debug_level >= dbglvl) { debug_list_volumes("reserve_vol free"); } } } /* * Create a new Volume entry */ nvol = new_vol_item(dcr, VolumeName); /* * Now try to insert the new Volume */ vol = (VOLRES *)vol_list->binary_insert(nvol, compare_by_volumename); if (vol != nvol) { Dmsg2(dbglvl, "Found vol=%s dev-same=%d\n", vol->vol_name, dev==vol->dev); /* * At this point, a Volume with this name already is in the list, * so we simply release our new Volume entry. Note, this should * only happen if we are moving the volume from one drive to another. */ Dmsg2(dbglvl, "reserve_vol free-tmp vol=%s at %p\n", vol->vol_name, vol->vol_name); /* * Clear dev pointer so that free_vol_item() doesn't take away our volume. */ nvol->dev = NULL; /* don't zap dev entry */ free_vol_item(nvol); if (vol->dev) { Dmsg2(dbglvl, "dev=%s vol->dev=%s\n", dev->print_name(), vol->dev->print_name()); } /* * Check if we are trying to use the Volume on a different drive dev is our device * vol->dev is where the Volume we want is */ if (dev != vol->dev) { /* * Caller wants to switch Volume to another device */ if (!vol->dev->is_busy() && !vol->is_swapping()) { int32_t slot; Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); free_volume(dev); /* free any volume attached to our drive */ Dmsg1(50, "set_unload dev=%s\n", dev->print_name()); dev->set_unload(); /* Unload any volume that is on our drive */ dcr->set_dev(vol->dev); /* temp point to other dev */ slot = get_autochanger_loaded_slot(dcr); /* get slot on other drive */ dcr->set_dev(dev); /* restore dev */ vol->set_slot(slot); /* save slot */ vol->dev->set_unload(); /* unload the other drive */ vol->set_swapping(); /* swap from other drive */ dev->swap_dev = vol->dev; /* remember to get this vol */ dev->set_load(); /* then reload on our drive */ vol->dev->vol = NULL; /* remove volume from other drive */ vol->dev = dev; /* point the Volume at our drive */ dev->vol = vol; /* point our drive at the Volume */ } else { Jmsg7(dcr->jcr, M_WARNING, 0, "Need volume from other drive, but swap not possible. " "Status: read=%d num_writers=%d num_reserve=%d swap=%d " "vol=%s from dev=%s to %s\n", vol->dev->can_read(), vol->dev->num_writers, vol->dev->num_reserved(), vol->is_swapping(), VolumeName, vol->dev->print_name(), dev->print_name()); if (vol->is_swapping() && dev->swap_dev) { Dmsg3(dbglvl, "Swap failed vol=%s from=%s to dev=%s\n", vol->vol_name, dev->swap_dev->print_name(), dev->print_name()); } else { Dmsg3(dbglvl, "Swap failed vol=%s from=%p to dev=%s\n", vol->vol_name, dev->swap_dev, dev->print_name()); } if (debug_level >= dbglvl) { debug_list_volumes("failed swap"); } vol = NULL; /* device busy */ goto get_out; } } else { dev->vol = vol; } } else { dev->vol = vol; /* point to newly inserted volume */ } get_out: if (vol) { Dmsg2(dbglvl, "=== set in_use. vol=%s dev=%s\n", vol->vol_name, vol->dev->print_name()); vol->set_in_use(); dcr->reserved_volume = true; bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName)); } if (debug_level >= dbglvl) { debug_list_volumes("end new volume"); } unlock_volumes(); return vol; } /* * Start walk of vol chain * The proper way to walk the vol chain is: * * VOLRES *vol; * foreach_vol(vol) { * ... * } * endeach_vol(vol); * * It is possible to leave out the endeach_vol(vol), but in that case, * the last vol referenced must be explicitly released with: * * free_vol_item(vol); */ VOLRES *vol_walk_start() { VOLRES *vol; lock_volumes(); vol = (VOLRES *)vol_list->first(); if (vol) { vol->inc_use_count(); Dmsg2(dbglvl, "Inc walk_start use_count=%d volname=%s\n", vol->use_count(), vol->vol_name); } unlock_volumes(); return vol; } /* * Get next vol from chain, and release current one */ VOLRES *vol_walk_next(VOLRES *prev_vol) { VOLRES *vol; lock_volumes(); vol = (VOLRES *)vol_list->next(prev_vol); if (vol) { vol->inc_use_count(); Dmsg2(dbglvl, "Inc walk_next use_count=%d volname=%s\n", vol->use_count(), vol->vol_name); } if (prev_vol) { free_vol_item(prev_vol); } unlock_volumes(); return vol; } /* * Release last vol referenced */ void vol_walk_end(VOLRES *vol) { if (vol) { lock_volumes(); Dmsg2(dbglvl, "Free walk_end use_count=%d volname=%s\n", vol->use_count(), vol->vol_name); free_vol_item(vol); unlock_volumes(); } } /* * Search for a Volume name in the Volume list. * * Returns: VOLRES entry on success * NULL if the Volume is not in the list */ static VOLRES *find_volume(const char *VolumeName) { VOLRES vol, *fvol; if (vol_list->empty()) { return NULL; } /* Do not lock reservations here */ lock_volumes(); vol.vol_name = bstrdup(VolumeName); fvol = (VOLRES *)vol_list->binary_search(&vol, compare_by_volumename); free(vol.vol_name); Dmsg2(dbglvl, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL); if (debug_level >= dbglvl) { debug_list_volumes("find_volume"); } unlock_volumes(); return fvol; } /* * Free a Volume from the Volume list if it is no longer used * Note, for tape drives we want to remember where the Volume * was when last used, so rather than free the volume entry, * we simply mark it "not reserved" so when the drive is really * needed for another volume, we can reuse it. * * Returns: true if the Volume found and "removed" from the list * false if the Volume is not in the list or is in use */ bool volume_unused(DCR *dcr) { DEVICE *dev = dcr->dev; if (!dev->vol) { Dmsg1(dbglvl, "vol_unused: no vol on %s\n", dev->print_name()); if (debug_level >= dbglvl) { debug_list_volumes("null vol cannot unreserve_volume"); } return false; } Dmsg1(dbglvl, "=== clear in_use vol=%s\n", dev->vol->vol_name); dev->vol->clear_in_use(); if (dev->vol->is_swapping()) { Dmsg1(dbglvl, "vol_unused: vol being swapped on %s\n", dev->print_name()); if (debug_level >= dbglvl) { debug_list_volumes("swapping vol cannot free_volume"); } return false; } /* * If this is a tape, we do not free the volume, rather we wait * until the autoloader unloads it, or until another tape is * explicitly read in this drive. This allows the SD to remember * where the tapes are or last were. */ Dmsg4(dbglvl, "=== set not reserved vol=%s num_writers=%d dev_reserved=%d dev=%s\n", dev->vol->vol_name, dev->num_writers, dev->num_reserved(), dev->print_name()); if (dev->is_tape() || dev->is_autochanger()) { return true; } else { /* * Note, this frees the volume reservation entry, but the file descriptor remains * open with the OS. */ return free_volume(dev); } } /* * Unconditionally release the volume entry */ bool free_volume(DEVICE *dev) { VOLRES *vol; lock_volumes(); vol = dev->vol; if (vol == NULL) { Dmsg1(dbglvl, "No vol on dev %s\n", dev->print_name()); unlock_volumes(); return false; } /* * Don't free a volume while it is being swapped */ if (!vol->is_swapping()) { Dmsg1(dbglvl, "=== clear in_use vol=%s\n", vol->vol_name); dev->vol = NULL; vol_list->remove(vol); Dmsg2(dbglvl, "=== remove volume %s dev=%s\n", vol->vol_name, dev->print_name()); free_vol_item(vol); if (debug_level >= dbglvl) { debug_list_volumes("free_volume"); } } else { Dmsg1(dbglvl, "=== cannot clear swapping vol=%s\n", vol->vol_name); } unlock_volumes(); // pthread_cond_broadcast(&wait_next_vol); return true; } /* * Create the Volume list */ void create_volume_lists() { VOLRES *vol = NULL; if (vol_list == NULL) { vol_list = New(dlist(vol, &vol->link)); } if (read_vol_list == NULL) { read_vol_list = New(dlist(vol, &vol->link)); } } /* * Free normal append volumes list */ static inline void free_volume_list(const char *what, dlist *vollist) { VOLRES *vol; foreach_dlist(vol, vollist) { if (vol->dev) { Dmsg3(dbglvl, "free %s Volume=%s dev=%s\n", what, vol->vol_name, vol->dev->print_name()); } else { Dmsg2(dbglvl, "free %s Volume=%s No dev\n", what, vol->vol_name); } free(vol->vol_name); vol->vol_name = NULL; vol->destroy_mutex(); } } /* * Release all Volumes from the list */ void free_volume_lists() { if (vol_list) { lock_volumes(); free_volume_list("vol_list", vol_list); delete vol_list; vol_list = NULL; unlock_volumes(); } if (read_vol_list) { lock_read_volumes(); free_volume_list("read_vol_list", read_vol_list); delete read_vol_list; read_vol_list = NULL; unlock_read_volumes(); } } /* * Determine if caller can write on volume */ bool DCR::can_i_write_volume() { VOLRES *vol; vol = find_read_volume(VolumeName); if (vol) { Dmsg1(100, "Found in read list; cannot write vol=%s\n", VolumeName); return false; } return can_i_use_volume(); } /* * Determine if caller can read or write volume */ bool DCR::can_i_use_volume() { bool rtn = true; VOLRES *vol; if (job_canceled(jcr)) { return false; } lock_volumes(); vol = find_volume(VolumeName); if (!vol) { Dmsg1(dbglvl, "Vol=%s not in use.\n", VolumeName); goto get_out; /* vol not in list */ } ASSERT(vol->dev != NULL); if (dev == vol->dev) { /* same device OK */ Dmsg1(dbglvl, "Vol=%s on same dev.\n", VolumeName); goto get_out; } else { Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); } /* ***FIXME*** check this ... */ if (!vol->dev->is_busy()) { Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", VolumeName, vol->dev->print_name()); goto get_out; } else { Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", VolumeName, vol->dev->print_name()); } Dmsg2(dbglvl, "Vol=%s in use by %s.\n", VolumeName, vol->dev->print_name()); rtn = false; get_out: unlock_volumes(); return rtn; } /* * Create a temporary copy of the volume list. We do this, * to avoid having the volume list locked during the * call to reserve_device(), which would cause a deadlock. * * Note, we may want to add an update counter on the vol_list * so that if it is modified while we are traversing the copy * we can take note and act accordingly (probably redo the * search at least a few times). */ dlist *dup_vol_list(JCR *jcr) { dlist *temp_vol_list; VOLRES *vol = NULL; Dmsg0(dbglvl, "lock volumes\n"); Dmsg0(dbglvl, "duplicate vol list\n"); temp_vol_list = New(dlist(vol, &vol->link)); foreach_vol(vol) { VOLRES *nvol, *tvol; tvol = new_vol_item(NULL, vol->vol_name); tvol->dev = vol->dev; nvol = (VOLRES *)temp_vol_list->binary_insert(tvol, compare_by_volumename); if (tvol != nvol) { tvol->dev = NULL; /* don't zap dev entry */ free_vol_item(tvol); Pmsg0(000, "Logic error. Duplicating vol list hit duplicate.\n"); Jmsg(jcr, M_WARNING, 0, "Logic error. Duplicating vol list hit duplicate.\n"); } } endeach_vol(vol); Dmsg0(dbglvl, "unlock volumes\n"); return temp_vol_list; } /* * Free the specified temp list. */ void free_temp_vol_list(dlist *temp_vol_list) { free_volume_list("temp_vol_list", temp_vol_list); delete temp_vol_list; } bareos-Release-14.2.6/src/stored/vol_mgr.h000066400000000000000000000065471263011562700203610ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2013 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Pulled out of dev.h * * Kern Sibbald, MMXIII * */ /* * Some details of how volume reservations work * * class VOLRES: * set_in_use() volume being used on current drive * clear_in_use() no longer being used. Can be re-used or moved. * set_swapping() set volume being moved to another drive * is_swapping() volume is being moved to another drive * clear_swapping() volume normal * */ #ifndef __VOL_MGR_H #define __VOL_MGR_H 1 class VOLRES; VOLRES *vol_walk_start(); VOLRES *vol_walk_next(VOLRES *prev_vol); void vol_walk_end(VOLRES *vol); /* * Volume reservation class -- see vol_mgr.c and reserve.c */ class VOLRES { bool m_swapping; /* set when swapping to another drive */ bool m_in_use; /* set when volume reserved or in use */ bool m_reading; /* set when reading */ int32_t m_slot; /* slot of swapping volume */ uint32_t m_JobId; /* JobId for read volumes */ volatile int32_t m_use_count; /* Use count */ pthread_mutex_t m_mutex; /* Vol muntex */ public: dlink link; char *vol_name; /* Volume name */ DEVICE *dev; /* Pointer to device to which we are attached */ void init_mutex() { pthread_mutex_init(&m_mutex, NULL); }; void destroy_mutex() { pthread_mutex_destroy(&m_mutex); }; void Lock() { P(m_mutex); }; void Unlock() { V(m_mutex); }; void inc_use_count(void) {P(m_mutex); m_use_count++; V(m_mutex); }; void dec_use_count(void) {P(m_mutex); m_use_count--; V(m_mutex); }; int32_t use_count() const { return m_use_count; }; bool is_swapping() const { return m_swapping; }; bool is_reading() const { return m_reading; }; bool is_writing() const { return !m_reading; }; void set_reading() { m_reading = true; }; void clear_reading() { m_reading = false; }; void set_swapping() { m_swapping = true; }; void clear_swapping() { m_swapping = false; }; bool is_in_use() const { return m_in_use; }; void set_in_use() { m_in_use = true; }; void clear_in_use() { m_in_use = false; }; void set_slot(int32_t slot) { m_slot = slot; }; void clear_slot() { m_slot = -1; }; int32_t get_slot() const { return m_slot; }; uint32_t get_jobid() const { return m_JobId; }; void set_jobid(uint32_t JobId) { m_JobId = JobId; }; }; #define foreach_vol(vol) \ for (vol=vol_walk_start(); vol; (vol=vol_walk_next(vol)) ) #define endeach_vol(vol) vol_walk_end(vol) #endif bareos-Release-14.2.6/src/stored/wait.c000066400000000000000000000211431263011562700176400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Subroutines to handle waiting for operator intervention * or waiting for a Device to be released * * Code for wait_for_sysop() pulled from askdir.c * * Kern Sibbald, March 2005 */ #include "bareos.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ const int dbglvl = 400; static pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER; /* * Wait for SysOp to mount a tape on a specific device * * Returns: W_ERROR, W_TIMEOUT, W_POLL, W_MOUNT, or W_WAKE */ int wait_for_sysop(DCR *dcr) { struct timeval tv; struct timezone tz; struct timespec timeout; time_t last_heartbeat = 0; time_t first_start = time(NULL); int status = 0; int add_wait; bool unmounted; DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; dev->Lock(); Dmsg1(dbglvl, "Enter blocked=%s\n", dev->print_blocked()); /* * Since we want to mount a tape, make sure current one is * not marked as using this drive. */ volume_unused(dcr); unmounted = dev->is_device_unmounted(); dev->poll = false; /* * Wait requested time (dev->rem_wait_sec). However, we also wake up every * HB_TIME seconds and send a heartbeat to the FD and the Director * to keep stateful firewalls from closing them down while waiting * for the operator. */ add_wait = dev->rem_wait_sec; if (me->heartbeat_interval && add_wait > me->heartbeat_interval) { add_wait = me->heartbeat_interval; } /* If the user did not unmount the tape and we are polling, ensure * that we poll at the correct interval. */ if (!unmounted && dev->vol_poll_interval && add_wait > dev->vol_poll_interval) { add_wait = dev->vol_poll_interval; } if (!unmounted) { Dmsg1(dbglvl, "blocked=%s\n", dev->print_blocked()); dev->dev_prev_blocked = dev->blocked(); dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */ } while (!job_canceled(jcr)) { time_t now, start, total_waited; gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + add_wait; Dmsg4(dbglvl, "I'm going to sleep on device %s. HB=%d rem_wait=%d add_wait=%d\n", dev->print_name(), (int)me->heartbeat_interval, dev->rem_wait_sec, add_wait); start = time(NULL); /* Wait required time */ status = pthread_cond_timedwait(&dev->wait_next_vol, &dev->m_mutex, &timeout); Dmsg2(dbglvl, "Wokeup from sleep on device status=%d blocked=%s\n", status, dev->print_blocked()); now = time(NULL); total_waited = now - first_start; dev->rem_wait_sec -= (now - start); /* Note, this always triggers the first time. We want that. */ if (me->heartbeat_interval) { if (now - last_heartbeat >= me->heartbeat_interval) { /* send heartbeats */ if (jcr->file_bsock) { jcr->file_bsock->signal(BNET_HEARTBEAT); Dmsg0(dbglvl, "Send heartbeat to FD.\n"); } if (jcr->dir_bsock) { jcr->dir_bsock->signal(BNET_HEARTBEAT); } last_heartbeat = now; } } if (status == EINVAL) { berrno be; Jmsg1(jcr, M_FATAL, 0, _("pthread timedwait error. ERR=%s\n"), be.bstrerror(status)); status = W_ERROR; /* error */ break; } /* * Continue waiting if operator is labeling volumes */ if (dev->blocked() == BST_WRITING_LABEL) { continue; } if (dev->rem_wait_sec <= 0) { /* on exceeding wait time return */ Dmsg0(dbglvl, "Exceed wait time.\n"); status = W_TIMEOUT; break; } /* * Check if user unmounted the device while we were waiting */ unmounted = dev->is_device_unmounted(); if (!unmounted && dev->vol_poll_interval && (total_waited >= dev->vol_poll_interval)) { Dmsg1(dbglvl, "poll return in wait blocked=%s\n", dev->print_blocked()); dev->poll = true; /* returning a poll event */ status = W_POLL; break; } /* * Check if user mounted the device while we were waiting */ if (dev->blocked() == BST_MOUNT) { /* mount request ? */ Dmsg0(dbglvl, "Mounted return.\n"); status = W_MOUNT; break; } /* * If we did not timeout, then some event happened, so * return to check if state changed. */ if (status != ETIMEDOUT) { berrno be; Dmsg2(dbglvl, "Wake return. status=%d. ERR=%s\n", status, be.bstrerror(status)); status = W_WAKE; /* someone woke us */ break; } /* * At this point, we know we woke up because of a timeout, * that was due to a heartbeat, because any other reason would * have caused us to return, so update the wait counters and continue. */ add_wait = dev->rem_wait_sec; if (me->heartbeat_interval && add_wait > me->heartbeat_interval) { add_wait = me->heartbeat_interval; } /* If the user did not unmount the tape and we are polling, ensure * that we poll at the correct interval. */ if (!unmounted && dev->vol_poll_interval && add_wait > dev->vol_poll_interval - total_waited) { add_wait = dev->vol_poll_interval - total_waited; } if (add_wait < 0) { add_wait = 0; } } if (!unmounted) { dev->set_blocked(dev->dev_prev_blocked); /* restore entry state */ Dmsg1(dbglvl, "set %s\n", dev->print_blocked()); } Dmsg1(dbglvl, "Exit blocked=%s\n", dev->print_blocked()); dev->Unlock(); return status; } /* * Wait for any device to be released, then we return, so * higher level code can rescan possible devices. Since there * could be a job waiting for a drive to free up, we wait a maximum * of 1 minute then retry just in case a broadcast was lost, and * we return to rescan the devices. * * Returns: true if a device has changed state * false if the total wait time has expired. */ bool wait_for_device(JCR *jcr, int &retries) { struct timeval tv; struct timezone tz; struct timespec timeout; int status = 0; bool ok = true; const int max_wait_time = 1 * 60; /* wait 1 minute */ char ed1[50]; Dmsg0(dbglvl, "Enter wait_for_device\n"); P(device_release_mutex); if (++retries % 5 == 0) { /* Print message every 5 minutes */ Jmsg(jcr, M_MOUNT, 0, _("JobId=%s, Job %s waiting to reserve a device.\n"), edit_uint64(jcr->JobId, ed1), jcr->Job); } gettimeofday(&tv, &tz); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + max_wait_time; Dmsg0(dbglvl, "Going to wait for a device.\n"); /* Wait required time */ status = pthread_cond_timedwait(&wait_device_release, &device_release_mutex, &timeout); Dmsg1(dbglvl, "Wokeup from sleep on device status=%d\n", status); V(device_release_mutex); Dmsg1(dbglvl, "Return from wait_device ok=%d\n", ok); return ok; } /* * Signal the above wait_for_device function. */ void release_device_cond() { pthread_cond_broadcast(&wait_device_release); } #ifdef xxx /* * The jcr timers are used for waiting on any device * * Returns: true if time doubled * false if max time expired */ static bool double_jcr_wait_time(JCR *jcr) { jcr->wait_sec *= 2; /* double wait time */ if (jcr->wait_sec > jcr->max_wait) { /* but not longer than maxtime */ jcr->wait_sec = jcr->max_wait; } jcr->num_wait++; jcr->rem_wait_sec = jcr->wait_sec; if (jcr->num_wait >= jcr->max_num_wait) { return false; } return true; } #endif bareos-Release-14.2.6/src/tests/000077500000000000000000000000001263011562700163715ustar00rootroot00000000000000bareos-Release-14.2.6/src/tests/Makefile.in000066400000000000000000000113041263011562700204350ustar00rootroot00000000000000# # Bareos Tests Makefile # @MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/tests DEBUG = @DEBUG@ ZLIB_INC = @ZLIB_INC@ LZO_INC = @LZO_INC@ first_rule: all dummy: GETTEXT_LIBS = @LIBINTL@ TESTS = testls bbatch bregtest bvfs_test ing_test gigaslam grow INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .o .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile $(TESTS) gigaslam grow @echo "==== Make of tools is good ====" @echo " " bregtest: Makefile bregtest.o \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -o $@ bregtest.o -lbareos -lm $(DLIB) $(LIBS) $(GETTEXT_LIBS) testls: Makefile testls.o \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) -g $(LDFLAGS) -L. -L../lib -L../findlib -o $@ testls.o \ $(DLIB) -lbareosfind -lbareos -lm $(LIBS) $(GETTEXT_LIBS) bbatch.o: bbatch.c echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(ZLIB_INC) $(LZO_INC) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< bbatch: Makefile bbatch.o \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) -g $(LDFLAGS) -L../cats -L. -L../lib -o $@ bbatch.o \ -lbareoscats -lbareossql -lbareos -lm $(DB_LIBS) $(LIBS) $(GETTEXT_LIBS) bvfs_test: Makefile bvfs_test.o \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) -g $(LDFLAGS) -L../cats -L. -L../lib -L../findlib -o $@ bvfs_test.o \ -lbareoscats -lbareossql -lbareosfind -lbareos -lm $(DB_LIBS) $(LIBS) $(GETTEXT_LIBS) ing_test: Makefile ing_test.o \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareoscats$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) -g $(LDFLAGS) -L../cats -L. -L../lib -L../findlib -o $@ ing_test.o \ -lbareoscats -lbareossql -lbareosfind -lbareos -lm $(DB_LIBS) $(LIBS) $(GETTEXT_LIBS) cats_test: Makefile cats_test.o \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../cats/libbareossql$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) -g $(LDFLAGS) -L../cats -L. -L../lib -L../findlib -o $@ cats_test.o \ -lbareoscats -lbareossql -lbareosfind -lbareos -lm $(DB_LIBS) $(LIBS) $(GETTEXT_LIBS) gigaslam.o: gigaslam.c echo "Compiling $<" $(CXX) $(CXXFLAGS) -c $< gigaslam: gigaslam.o @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -o $@ gigaslam.o grow: Makefile grow.o ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -o $@ grow.o -lbareos -lm $(DLIB) $(LIBS) $(GETTEXT_LIBS) Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) bsmtp core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 @$(RMF) $(TESTS) realclean: clean @$(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) installall: $(TESTS) @for tst in ${TESTS} ; do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$tst $(DESTDIR)$(sbindir)/$$tst ; \ done install: # Semi-automatic generation of dependencies: # Use gcc -MM because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @$(CXX) -S -M $(CPPFLAGS) $(INCLUDES) *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/tests/bbatch.c000066400000000000000000000224171263011562700177660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to test batch mode * * Eric Bollengier, March 2007 */ /* to create datafile for i in $(seq 10000 99999) ; do j=$((($i % 1000) + 555)) echo "$i;/tmp/totabofds$j/fiddddle${j}$i;xxxLSTATxxxx;xxxxxxxMD5xxxxxx" done > dat1 or j=0 find / | while read a; do j=$(($j+1)) echo "$j;$a;xxxLSTATxxxx;xxxxxxxMD5xxxxxx" done > dat1 */ #include "bareos.h" #include "stored/stored.h" #include "findlib/find.h" #include "cats/cats.h" #include "cats/sql_glue.h" /* Forward referenced functions */ static void *do_batch(void *); /* Local variables */ static B_DB *db; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) static const char *backend_directory = _PATH_BAREOS_BACKENDDIR; #endif static const char *db_name = "bareos"; static const char *db_user = "bareos"; static const char *db_password = ""; static const char *db_host = NULL; static const char *db_driver = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n" "Example : bbatch -w /path/to/workdir -h localhost -f dat1 -f dat -f datx\n" " will start 3 thread and load dat1, dat and datx in your catalog\n" "See bbatch.c to generate datafile\n\n" "Usage: bbatch [ options ] -w working/dir -f datafile\n" " -b with batch mode\n" " -B without batch mode\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -r call restore code with given jobids\n" " -v verbose\n" " -f specify data file\n" " -? print this message\n\n"), 2001, VERSION, BDATE); exit(1); } /* number of thread started */ int nb=0; static int list_handler(void *ctx, int num_fields, char **row) { uint64_t *a = (uint64_t*) ctx; (*a)++; return 0; } int main (int argc, char *argv[]) { int ch; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) alist *backend_directories = NULL; #endif bool disable_batch = false; char *restore_list=NULL; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); lmgr_init_thread(); char **files = (char **) malloc (10 * sizeof(char *)); int i; my_name_is(argc, argv, "bbatch"); init_msg(NULL, NULL); OSDependentInit(); while ((ch = getopt(argc, argv, "bBh:c:d:D:n:P:Su:vf:w:r:?")) != -1) { switch (ch) { case 'r': restore_list=bstrdup(optarg); break; case 'B': disable_batch = true; break; case 'b': disable_batch = false; break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'D': db_driver = optarg; break; case 'h': db_host = optarg; break; case 'n': db_name = optarg; break; case 'w': working_directory = optarg; break; case 'u': db_user = optarg; break; case 'P': db_password = optarg; break; case 'v': verbose++; break; case 'f': if (nb < 10 ) { files[nb++] = optarg; } break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 0) { Pmsg0(0, _("Wrong number of arguments: \n")); usage(); } if (restore_list) { uint64_t nb_file=0; btime_t start, end; /* * To use the -r option, the catalog should already contains records */ #if defined(HAVE_DYNAMIC_CATS_BACKENDS) backend_directories = New(alist(10, owned_by_alist)); backend_directories->append((char *)backend_directory); db_set_backend_dirs(backend_directories); #endif if ((db = db_init_database(NULL, db_driver, db_name, db_user, db_password, db_host, 0, NULL, false, disable_batch)) == NULL) { Emsg0(M_ERROR_TERM, 0, _("Could not init Bareos database\n")); } if (!db_open_database(NULL, db)) { Emsg0(M_ERROR_TERM, 0, db_strerror(db)); } start = get_current_btime(); db_get_file_list(NULL, db, restore_list, false, false, list_handler, &nb_file); end = get_current_btime(); Pmsg3(0, _("Computing file list for jobid=%s files=%lld secs=%d\n"), restore_list, nb_file, (uint32_t)btime_to_unix(end-start)); free(restore_list); return 0; } if (disable_batch) { printf("Without new Batch mode\n"); } else { printf("With new Batch mode\n"); } i = nb; while (--i >= 0) { pthread_t thid; JCR *bjcr = new_jcr(sizeof(JCR), NULL); bjcr->bsr = NULL; bjcr->VolSessionId = 1; bjcr->VolSessionTime = (uint32_t)time(NULL); bjcr->NumReadVolumes = 0; bjcr->NumWriteVolumes = 0; bjcr->JobId = getpid(); bjcr->setJobType(JT_CONSOLE); bjcr->setJobLevel(L_FULL); bjcr->JobStatus = JS_Running; bjcr->where = bstrdup(files[i]); bjcr->job_name = get_pool_memory(PM_FNAME); pm_strcpy(bjcr->job_name, "Dummy.Job.Name"); bjcr->client_name = get_pool_memory(PM_FNAME); pm_strcpy(bjcr->client_name, "Dummy.Client.Name"); bstrncpy(bjcr->Job, "bbatch", sizeof(bjcr->Job)); bjcr->fileset_name = get_pool_memory(PM_FNAME); pm_strcpy(bjcr->fileset_name, "Dummy.fileset.name"); bjcr->fileset_md5 = get_pool_memory(PM_FNAME); pm_strcpy(bjcr->fileset_md5, "Dummy.fileset.md5"); if ((db = db_init_database(NULL, db_driver, db_name, db_user, db_password, db_host, 0, NULL, false, false)) == NULL) { Emsg0(M_ERROR_TERM, 0, _("Could not init Bareos database\n")); } if (!db_open_database(NULL, db)) { Emsg0(M_ERROR_TERM, 0, db_strerror(db)); } Dmsg0(200, "Database opened\n"); if (verbose) { Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user); } bjcr->db = db; pthread_create(&thid, NULL, do_batch, bjcr); } while (nb > 0) { bmicrosleep(1,0); } return 0; } static void fill_attr(ATTR_DBR *ar, char *data) { char *p; char *b; int index=0; ar->Stream = STREAM_UNIX_ATTRIBUTES; ar->JobId = getpid(); for(p = b = data; *p; p++) { if (*p == ';') { *p = '\0'; switch (index) { case 0: ar->FileIndex = str_to_int64(b); break; case 1: ar->fname = b; break; case 2: ar->attr = b; break; case 3: ar->Digest = b; break; } index++; b = ++p; } } } static void *do_batch(void *jcr) { JCR *bjcr = (JCR *)jcr; char data[1024]; int lineno = 0; struct ATTR_DBR ar; memset(&ar, 0, sizeof(ar)); btime_t begin = get_current_btime(); char *datafile = bjcr->where; FILE *fd = fopen(datafile, "r"); if (!fd) { Emsg1(M_ERROR_TERM, 0, _("Error opening datafile %s\n"), datafile); } while (fgets(data, sizeof(data)-1, fd)) { strip_trailing_newline(data); lineno++; if (verbose && ((lineno % 5000) == 1)) { printf("\r%i", lineno); } fill_attr(&ar, data); if (!db_create_attributes_record(bjcr, bjcr->db, &ar)) { Emsg0(M_ERROR_TERM, 0, _("Error while inserting file\n")); } } fclose(fd); db_write_batch_file_records(bjcr); btime_t end = get_current_btime(); P(mutex); char ed1[200], ed2[200]; printf("\rbegin = %s, end = %s\n", edit_int64(begin, ed1),edit_int64(end, ed2)); printf("Insert time = %sms\n", edit_int64((end - begin) / 10000, ed1)); printf("Create %u files at %.2f/s\n", lineno, (lineno / ((float)((end - begin) / 1000000)))); nb--; V(mutex); pthread_exit(NULL); return NULL; } bareos-Release-14.2.6/src/tests/bregtest.c000066400000000000000000000067301263011562700203620ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Test program for testing regular expressions. * * Kern Sibbald, MMVI */ /* * If you define BAREOS_REGEX, bregex will be built with the * Bareos bregex library, which is the same code that we * use on Win32, thus using Linux, you can test your Win32 * expressions. Otherwise, this program will link with the * system library routines. */ //#define BAREOS_REGEX #include "bareos.h" #include #include "lib/breg.h" static void usage() { fprintf(stderr, "\n" "Usage: bregtest [-d debug_level] [-s] -f -e /test/test2/\n" " -f specify file of data to be matched\n" " -e specify expression\n" " -s sed output\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -? print this message.\n" "\n"); exit(1); } int main(int argc, char *const *argv) { char *fname = NULL; char *expr = NULL; int ch; bool sed=false; char data[1000]; FILE *fd; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); while ((ch = getopt(argc, argv, "sd:f:e:")) != -1) { switch (ch) { case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* data */ fname = optarg; break; case 'e': expr = optarg; break; case 's': sed=true; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (!fname) { printf("A data file must be specified.\n"); usage(); } if (!expr) { printf("An expression must be specified.\n"); usage(); } OSDependentInit(); alist *list; char *p; list = get_bregexps(expr); if (!list) { printf("Can't use %s as 'sed' expression\n", expr); exit (1); } fd = fopen(fname, "r"); if (!fd) { printf(_("Could not open data file: %s\n"), fname); exit(1); } while (fgets(data, sizeof(data)-1, fd)) { strip_trailing_newline(data); apply_bregexps(data, list, &p); if (sed) { printf("%s\n", p); } else { printf("%s => %s\n", data, p); } } fclose(fd); free_bregexps(list); delete list; exit(0); } /* TODO: - ajout /g - tests * test avec /i * test avec un sed et faire un diff * test avec une boucle pour voir les fuites */ bareos-Release-14.2.6/src/tests/bvfs_test.c000066400000000000000000000203561263011562700205420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to test cache path * * Eric Bollengier, August 2009 */ #include "bareos.h" #include "cats/cats.h" #include "cats/sql_glue.h" #include "cats/bvfs.h" #include "findlib/find.h" /* Local variables */ static B_DB *db; static const char *file = "COPYRIGHT"; static DBId_t fnid=0; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) static const char *backend_directory = _PATH_BAREOS_BACKENDDIR; #endif static const char *db_name = "regress"; static const char *db_user = "regress"; static const char *db_password = ""; static const char *db_host = NULL; static const char *db_driver = NULL; static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n\n"), 2001, VERSION, BDATE); exit(1); } static int result_handler(void *ctx, int fields, char **row) { Bvfs *vfs = (Bvfs *)ctx; ATTR *attr = vfs->get_attr(); char empty[] = "A A A A A A A A A A A A A A"; memset(&attr->statp, 0, sizeof(struct stat)); decode_stat((row[BVFS_LStat] && row[BVFS_LStat][0])?row[BVFS_LStat]:empty, &attr->statp, sizeof(attr->statp), &attr->LinkFI); if (bvfs_is_dir(row) || bvfs_is_file(row)) { /* display clean stuffs */ if (bvfs_is_dir(row)) { pm_strcpy(attr->ofname, bvfs_basename_dir(row[BVFS_Name])); } else { /* if we see the requested file, note his filenameid */ if (bstrcmp(row[BVFS_Name], file)) { fnid = str_to_int64(row[BVFS_FilenameId]); } pm_strcpy(attr->ofname, row[BVFS_Name]); } print_ls_output(vfs->get_jcr(), attr); } else { Pmsg5(0, "JobId=%s FileId=%s\tMd5=%s\tVolName=%s\tVolInChanger=%s\n", row[BVFS_JobId], row[BVFS_FileId], row[BVFS_Md5], row[BVFS_VolName], row[BVFS_VolInchanger]); pm_strcpy(attr->ofname, file); print_ls_output(vfs->get_jcr(), attr); } return 0; } /* number of thread started */ int main (int argc, char *argv[]) { int ch; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) alist *backend_directories = NULL; #endif char *jobids = (char *)"1"; char *path=NULL, *client=NULL; uint64_t limit=0; bool clean=false; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); Dmsg0(0, "Starting bvfs_test tool\n"); my_name_is(argc, argv, "bvfs_test"); init_msg(NULL, NULL); OSDependentInit(); while ((ch = getopt(argc, argv, "h:c:l:d:D:n:P:Su:vf:w:?j:p:f:T")) != -1) { switch (ch) { case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'D': db_driver = optarg; break; case 'l': limit = str_to_int64(optarg); break; case 'c': client = optarg; break; case 'h': db_host = optarg; break; case 'n': db_name = optarg; break; case 'w': working_directory = optarg; break; case 'u': db_user = optarg; break; case 'P': db_password = optarg; break; case 'v': verbose++; break; case 'p': path = optarg; break; case 'f': file = optarg; break; case 'j': jobids = optarg; break; case 'T': clean = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 0) { Pmsg0(0, _("Wrong number of arguments: \n")); usage(); } JCR *bjcr = new_jcr(sizeof(JCR), NULL); bjcr->JobId = getpid(); bjcr->setJobType(JT_CONSOLE); bjcr->setJobLevel(L_FULL); bjcr->JobStatus = JS_Running; bjcr->client_name = get_pool_memory(PM_FNAME); pm_strcpy(bjcr->client_name, "Dummy.Client.Name"); bstrncpy(bjcr->Job, "bvfs_test", sizeof(bjcr->Job)); #if defined(HAVE_DYNAMIC_CATS_BACKENDS) backend_directories = New(alist(10, owned_by_alist)); backend_directories->append((char *)backend_directory); db_set_backend_dirs(backend_directories); #endif if ((db = db_init_database(NULL, NULL, db_name, db_user, db_password, db_host, 0, NULL)) == NULL) { Emsg0(M_ERROR_TERM, 0, _("Could not init Bareos database\n")); } Dmsg1(0, "db_type=%s\n", db_get_type(db)); if (!db_open_database(NULL, db)) { Emsg0(M_ERROR_TERM, 0, db_strerror(db)); } Dmsg0(200, "Database opened\n"); if (verbose) { Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user); } bjcr->db = db; if (clean) { Pmsg0(0, "Clean old table\n"); db_sql_query(db, "DELETE FROM PathHierarchy", NULL, NULL); db_sql_query(db, "UPDATE Job SET HasCache=0", NULL, NULL); db_sql_query(db, "DELETE FROM PathVisibility", NULL, NULL); bvfs_update_cache(bjcr, db); } Bvfs fs(bjcr, db); fs.set_handler(result_handler, &fs); fs.set_jobids(jobids); fs.update_cache(); if (limit) fs.set_limit(limit); if (path) { fs.ch_dir(path); fs.ls_special_dirs(); fs.ls_dirs(); while (fs.ls_files()) { fs.next_offset(); } if (fnid && client) { Pmsg0(0, "---------------------------------------------\n"); Pmsg1(0, "Getting file version for %s\n", file); fs.get_all_file_versions(fs.get_pwd(), fnid, client); } exit (0); } Pmsg0(0, "list /\n"); fs.ch_dir("/"); fs.ls_special_dirs(); fs.ls_dirs(); fs.ls_files(); Pmsg0(0, "list /tmp/\n"); fs.ch_dir("/tmp/"); fs.ls_special_dirs(); fs.ls_dirs(); fs.ls_files(); Pmsg0(0, "list /tmp/regress/\n"); fs.ch_dir("/tmp/regress/"); fs.ls_special_dirs(); fs.ls_files(); fs.ls_dirs(); Pmsg0(0, "list /tmp/regress/build/\n"); fs.ch_dir("/tmp/regress/build/"); fs.ls_special_dirs(); fs.ls_dirs(); fs.ls_files(); fs.get_all_file_versions(1, 347, "zog4-fd"); char p[200]; strcpy(p, "/tmp/toto/rep/"); bvfs_parent_dir(p); if(!bstrcmp(p, "/tmp/toto/")) { Pmsg0(000, "Error in bvfs_parent_dir\n"); } bvfs_parent_dir(p); if(!bstrcmp(p, "/tmp/")) { Pmsg0(000, "Error in bvfs_parent_dir\n"); } bvfs_parent_dir(p); if(!bstrcmp(p, "/")) { Pmsg0(000, "Error in bvfs_parent_dir\n"); } bvfs_parent_dir(p); if(!bstrcmp(p, "")) { Pmsg0(000, "Error in bvfs_parent_dir\n"); } bvfs_parent_dir(p); if(!bstrcmp(p, "")) { Pmsg0(000, "Error in bvfs_parent_dir\n"); } return 0; } bareos-Release-14.2.6/src/tests/cats_test.c000066400000000000000000000560221263011562700205330ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2011-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to test CATS DB routines */ #define _BDB_PRIV_INTERFACE_ #include "bareos.h" #include "cats/cats.h" #include "cats/bdb_priv.h" #include "cats/sql_glue.h" /* Local variables */ static B_DB *db; static const char *file = "COPYRIGHT"; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) static const char *backend_directory = _PATH_BAREOS_BACKENDDIR; #endif static const char *db_name = "bareos"; static const char *db_user = "bareos"; static const char *db_password = ""; static const char *db_host = NULL; static const char *db_address = NULL; static const char *db_driver = NULL; static int db_port = 0; static int64_t pid = 0; static JCR *jcr=NULL; #define PLINE "\n============================================================\n" static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -D specify the driver database name (default NULL)\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -q print only errors\n" " -v verbose\n" " -? print this message\n\n"), 2011, VERSION, BDATE); exit(1); } bool print_ok=true; int _err=0; int _wrn=0; int _nb=0; bool _warn(const char *file, int l, const char *op, int value, const char *label) { bool ret=false; _nb++; if (!value) { _wrn++; printf("WRN %.30s %s:%i on %s\n", label, file, l, op); } else { ret=true; printf("OK %.30s\n", label); } return ret; } #define warn(x, label) _warn(__FILE__, __LINE__, #x, (x), label) bool _ok(const char *file, int l, const char *op, int value, const char *label) { bool ret=false; _nb++; if (!value) { _err++; printf("ERR %.30s %s:%i on %s\n", label, file, l, op); } else { ret=true; if (print_ok) { printf("OK %.30s\n", label); } } return ret; } #define ok(x, label) _ok(__FILE__, __LINE__, #x, (x), label) bool _nok(const char *file, int l, const char *op, int value, const char *label) { bool ret=false; _nb++; if (value) { _err++; printf("ERR %.30s %s:%i on !%s\n", label, file, l, op); } else { ret = true; if (print_ok) { printf("OK %.30s\n", label); } } return ret; } #define nok(x, label) _nok(__FILE__, __LINE__, #x, (x), label) int report() { printf("Result %i/%i OK\n", _nb - _err, _nb); return _err>0; } static void cmp_pool(POOL_DBR &pr, POOL_DBR &pr2) { ok(pr.MaxVols == pr2.MaxVols, " Check Pool MaxVols"); ok(pr.UseOnce == pr2.UseOnce, " Check Pool UseOnce"); ok(pr.UseCatalog == pr2.UseCatalog, " Check Pool UseCatalog"); ok(pr.AcceptAnyVolume == pr2.AcceptAnyVolume," Check Pool AcceptAnyVolume"); ok(pr.AutoPrune == pr2.AutoPrune, " Check Pool AutoPrune"); ok(pr.Recycle == pr2.Recycle, " Check Pool Recycle"); ok(pr.VolRetention == pr2.VolRetention , " Check Pool VolRetention"); ok(pr.VolUseDuration == pr2.VolUseDuration, " Check Pool VolUseDuration"); ok(pr.MaxVolJobs == pr2.MaxVolJobs, " Check Pool MaxVolJobs"); ok(pr.MaxVolFiles == pr2.MaxVolFiles, " Check Pool MaxVolFiles"); ok(pr.MaxVolBytes == pr2.MaxVolBytes, " Check Pool MaxVolBytes"); ok(bstrcmp(pr.PoolType, pr2.PoolType), " Check Pool PoolType"); ok(pr.LabelType == pr2.LabelType, " Check Pool LabelType"); ok(bstrcmp(pr.LabelFormat, pr2.LabelFormat), " Check Pool LabelFormat"); ok(pr.RecyclePoolId == pr2.RecyclePoolId, " Check Pool RecyclePoolId"); ok(pr.ScratchPoolId == pr2.ScratchPoolId, " Check Pool ScratchPoolId"); ok(pr.ActionOnPurge == pr2.ActionOnPurge, " Check Pool ActionOnPurge"); } static void cmp_client(CLIENT_DBR &cr, CLIENT_DBR &cr2) { ok(bstrcmp(cr2.Name, cr.Name), " Check Client Name"); ok(bstrcmp(cr2.Uname, cr.Uname), " Check Client Uname"); ok(cr.AutoPrune == cr2.AutoPrune, " Check Client Autoprune"); ok(cr.JobRetention == cr2.JobRetention, " Check Client JobRetention"); ok(cr.FileRetention == cr2.FileRetention," Check Client FileRetention"); } static void cmp_job(JOB_DBR &jr, JOB_DBR &jr2) { ok(jr.VolSessionId == jr2.VolSessionId, " Check VolSessionId"); ok(jr.VolSessionTime == jr2.VolSessionTime, " Check VolSessionTime"); ok(jr.PoolId == jr2.PoolId, " Check PoolId"); ok(jr.StartTime == jr2.StartTime, " Check StartTime"); ok(jr.EndTime == jr2.EndTime, " Check EndTime"); ok(jr.JobFiles == jr2.JobFiles, " Check JobFiles"); ok(jr.JobBytes == jr2.JobBytes, " Check JobBytes"); ok(jr.JobTDate == jr2.JobTDate, " Check JobTDate"); ok(bstrcmp(jr.Job, jr2.Job), " Check Job"); ok(jr.JobStatus == jr2.JobStatus, " Check JobStatus"); ok(jr.JobType == jr2.JobType, " Check Type"); ok(jr.JobLevel == jr2.JobLevel, " Check Level"); ok(jr.ClientId == jr2.ClientId, " Check ClientId"); ok(bstrcmp(jr.Name, jr2.Name), " Check Name"); ok(jr.PriorJobId == jr2.PriorJobId, " Check PriorJobId"); ok(jr.RealEndTime == jr2.RealEndTime, " Check RealEndTime"); ok(jr.JobId == jr2.JobId, " Check JobId"); ok(jr.FileSetId == jr2.FileSetId, " Check FileSetId"); ok(jr.SchedTime == jr2.SchedTime, " Check SchedTime"); ok(jr.RealEndTime == jr2.RealEndTime, " Check RealEndTime"); ok(jr.ReadBytes == jr2.ReadBytes, " Check ReadBytes"); ok(jr.HasBase == jr2.HasBase, " Check HasBase"); ok(jr.PurgedFiles == jr2.PurgedFiles, " Check PurgedFiles"); } #define aPATH "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" #define aFILE "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" static int list_files(void *ctx, int nb_col, char **row) { uint32_t *k = (uint32_t*) ctx; (*k)++; ok(nb_col > 4, "Check result columns"); ok(bstrcmp(row[0], aPATH aPATH aPATH aPATH "/"), "Check path"); ok(bstrcmp(row[1], aFILE aFILE ".txt"), "Check filename"); ok(str_to_int64(row[2]) == 10, "Check FileIndex"); ok(str_to_int64(row[3]) == jcr->JobId, "Check JobId"); return 1; } static int count_col(void *ctx, int nb_col, char **row) { *((int32_t*) ctx) = nb_col; return 1; } /* number of thread started */ int main (int argc, char *argv[]) { int ch; alist* backend_directories = NULL; char *path=NULL, *client=NULL; uint64_t limit=0; bool clean=false; bool full_test=false; int dbtype; uint32_t j; char temp[20]; POOLMEM *buf = get_pool_memory(PM_FNAME); POOLMEM *buf2 = get_pool_memory(PM_FNAME); POOLMEM *buf3 = get_pool_memory(PM_FNAME); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); pid = getpid(); Pmsg0(0, "Starting cats_test tool" PLINE); my_name_is(argc, argv, ""); init_msg(NULL, NULL); OSDependentInit(); while ((ch = getopt(argc, argv, "qh:c:l:d:D:n:P:Su:vFw:?p:f:T")) != -1) { switch (ch) { case 'q': print_ok = false; break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'D': db_driver = optarg; break; case 'l': limit = str_to_int64(optarg); break; case 'c': client = optarg; break; case 'h': db_host = optarg; break; case 'n': db_name = optarg; break; case 'w': working_directory = optarg; break; case 'u': db_user = optarg; break; case 'P': db_password = optarg; break; case 'v': verbose++; break; case 'p': path = optarg; break; case 'F': full_test = true; break; case 'f': file = optarg; break; case 'T': clean = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 0) { Pmsg0(0, _("Wrong number of arguments: \n")); usage(); } /* TODO: * - Open DB * - With errors * - With good info * - With multiple thread in // * - Test cats.h * - Test all sql_cmds.c * - Test all sql.c (db_) * - Test all sql_create.c * - Test db_handler */ jcr = new_jcr(sizeof(JCR), NULL); jcr->setJobType(JT_CONSOLE); jcr->setJobLevel(L_NONE); jcr->JobStatus = JS_Running; bstrncpy(jcr->Job, "**dummy**", sizeof(jcr->Job)); jcr->JobId = pid; /* this is JobId on tape */ jcr->start_time = jcr->sched_time = time(NULL); /* Test DB connexion */ Pmsg1(0, PLINE "Test DB connection \"%s\"" PLINE, db_name); #if defined(HAVE_DYNAMIC_CATS_BACKENDS) backend_directories = New(alist(10, owned_by_alist)); backend_directories->append((char *)backend_directory); db_set_backend_dirs(backend_directories); #endif if (full_test) { db = db_init_database(jcr, db_driver, db_name, db_user, db_password, db_address, db_port + 100, NULL); ok(db != NULL, "Test bad connection"); if (!db) { report(); exit (1); } nok(db_open_database(jcr, db), "Open bad Database"); db_close_database(jcr, db); } db = db_init_database(jcr, db_driver, db_name, db_user, db_password, db_address, db_port, NULL); ok(db != NULL, "Test db connection"); if (!db) { report(); exit (1); } if (!ok(db_open_database(jcr, db), "Open Database")) { Pmsg1(000, _("Could not open database \"%s\".\n"), db_name); Jmsg(jcr, M_FATAL, 0, _("Could not open, database \"%s\".\n"), db_name); Jmsg(jcr, M_FATAL, 0, _("%s"), db_strerror(db)); Pmsg1(000, "%s", db_strerror(db)); db_close_database(jcr, db); report(); exit (1); } dbtype = db_get_type_index(db); /* Check if the SQL library is thread-safe */ //db_check_backend_thread_safe(); ok(check_tables_version(jcr, db), "Check table version"); ok(db_sql_query(db, "SELECT VersionId FROM Version", db_int_handler, &j), "SELECT VersionId"); ok(UPDATE_DB(jcr, db, (char*)"UPDATE Version SET VersionId = 1"), "Update VersionId"); nok(check_tables_version(jcr, db), "Check table version"); Mmsg(buf, "UPDATE Version SET VersionId = %d", j); ok(UPDATE_DB(jcr, db, buf), "Restore VersionId"); if (dbtype != SQL_TYPE_SQLITE3) { ok(db_check_max_connections(jcr, db, 1), "Test min Max Connexion"); nok(db_check_max_connections(jcr, db, 10000), "Test max Max Connexion"); } ok(db_open_batch_connexion(jcr, db), "Opening batch connection"); db_close_database(jcr, jcr->db_batch); jcr->db_batch = NULL; /* ---------------------------------------------------------------- */ uint32_t storageid=0; ok(db_sql_query(db, "SELECT MIN(StorageId) FROM Storage", db_int_handler, &storageid), "Get StorageId"); ok(storageid > 0, "Check StorageId"); if (!storageid) { Pmsg0(0, "Please, run REGRESS_DEBUG=1 tests/bareos-backup-test before this test"); exit (1); } /* ---------------------------------------------------------------- */ Pmsg0(0, PLINE "Doing Basic SQL tests" PLINE); ok(db_sql_query(db, "SELECT 1,2,3,4,5", count_col, &j), "Count 5 rows"); ok(j == 5, "Check number of columns"); ok(db_sql_query(db, "SELECT 1,2,3,4,5,'a','b','c','d','e'", count_col, &j), "Count 10 rows"); ok(j == 10, "Check number of columns"); bsnprintf(temp, sizeof(temp), "t%lld", pid); ok(db_sql_query(db, "SELECT 2", db_int_handler, &j), "Good SELECT query"); ok(db_sql_query(db, "SELECT 1 FROM Media WHERE VolumeName='missing'", db_int_handler, &j), "Good empty SELECT query"); db_int64_ctx i64; i64.value = 0; i64.count = 0; ok(db_sql_query(db, "SELECT 1",db_int64_handler, &i64),"db_int64_handler"); ok(i64.value == 1, "Check db_int64_handler return"); db_list_ctx lctx; ok(db_sql_query(db, "SELECT FileId FROM File ORDER By FileId LIMIT 10", db_list_handler, &lctx), "db_list_ctx"); ok(lctx.count == 10, "Check db_list_ctx count "); ok(bstrcmp(lctx.list, "1,2,3,4,5,6,7,8,9,10"), "Check db_list_ctx list"); nok(db_sql_query(db, "blabla", db_int_handler, &j), "Bad query"); Mmsg(buf, "CREATE Table %s (a int)", temp); ok(db_sql_query(db, buf, NULL, NULL), "CREATE query"); Mmsg(buf, "INSERT INTO %s (a) VALUES (1)", temp); ok(INSERT_DB(jcr, db, buf), "INSERT query"); ok(INSERT_DB(jcr, db, buf), "INSERT query"); ok(sql_affected_rows(db) == 1, "Check sql_affected_rows"); Mmsg(buf, "INSERT INTO aaa%s (a) VALUES (1)", temp); nok(INSERT_DB(jcr, db, buf), "Bad INSERT query"); ok(sql_affected_rows(db) == 0, "Check sql_affected_rows"); Mmsg(buf, "UPDATE %s SET a = 2", temp); ok(UPDATE_DB(jcr, db, buf), "UPDATE query"); ok(sql_affected_rows(db) == 2, "Check sql_affected_rows"); Mmsg(buf, "UPDATE %s SET a = 2 WHERE a = 1", temp); nok(UPDATE_DB(jcr, db, buf), "Empty UPDATE query"); Mmsg(buf, "UPDATE aaa%s SET a = 2", temp); nok(UPDATE_DB(jcr, db, buf), "Bad UPDATE query"); Mmsg(buf, "DELETE FROM %s", temp); ok(DELETE_DB(jcr, db, buf), "DELETE query"); nok(DELETE_DB(jcr, db, buf), "Empty DELETE query"); /* TODO bug ? */ Mmsg(buf, "DELETE FROM aaa%s", temp); ok(DELETE_DB(jcr, db, buf), "Bad DELETE query"); /* TODO bug ? */ Mmsg(buf, "DROP TABLE %s", temp); ok(QUERY_DB(jcr, db, buf), "DROP query"); nok(QUERY_DB(jcr, db, buf), "Empty DROP query"); /* ---------------------------------------------------------------- */ strcpy(buf, "This string should be 'escaped'"); db_escape_string(jcr, db, buf2, buf, strlen(buf)); ok((strlen(buf) + 2) == strlen(buf2),"Quoted string should be longer"); Mmsg(buf, "INSERT INTO Path (Path) VALUES ('%lld-%s')", pid, buf2); ok(db_sql_query(db, buf, NULL, NULL), "Inserting quoted string"); /* ---------------------------------------------------------------- */ Pmsg0(0, PLINE "Doing Job tests" PLINE); JOB_DBR jr, jr2; memset(&jr, 0, sizeof(jr)); memset(&jr2, 0, sizeof(jr2)); jr.JobId = 1; ok(db_get_job_record(jcr, db, &jr), "Get Job record for JobId=1"); ok(jr.JobFiles > 10, "Check number of files"); jr.JobId = (JobId_t)pid; Mmsg(buf, "%s-%lld", jr.Job, pid); strcpy(jr.Job, buf); ok(db_create_job_record(jcr, db, &jr), "Create Job record"); ok(db_update_job_start_record(jcr, db, &jr), "Update Start Record"); ok(db_update_job_end_record(jcr, db, &jr), "Update End Record"); jr2.JobId = jr.JobId; ok(db_get_job_record(jcr, db, &jr2), "Get Job record by JobId"); cmp_job(jr, jr2); memset(&jr2, 0, sizeof(jr2)); strcpy(jr2.Job, jr.Job); ok(db_get_job_record(jcr, db, &jr2), "Get Job record by Job name"); cmp_job(jr, jr2); memset(&jr2, 0, sizeof(jr2)); jr2.JobId = 99999; nok(db_get_job_record(jcr, db, &jr2), "Get non existing Job record (JobId)"); memset(&jr2, 0, sizeof(jr2)); strcpy(jr2.Job, "test"); nok(db_get_job_record(jcr, db, &jr2), "Get non existing Job record (Job)"); /* ---------------------------------------------------------------- */ ATTR_DBR ar; memset(&ar, 0, sizeof(ar)); Mmsg(buf2, aPATH aPATH aPATH aPATH "/" aFILE aFILE ".txt"); ar.fname = buf2; Mmsg(buf3, "gD ImIZ IGk B Po Po A A A JY BNNvf5 BNKzS7 BNNuwC A A C"); ar.attr = buf3; ar.FileIndex = 10; ar.Stream = STREAM_UNIX_ATTRIBUTES; ar.FileType = FT_REG; jcr->JobId = ar.JobId = jr.JobId; jcr->JobStatus = JS_Running; ok(db_create_attributes_record(jcr, db, &ar), "Inserting Filename"); ok(db_write_batch_file_records(jcr), "Commit batch session"); Mmsg(buf, "SELECT FileIndex FROM File WHERE JobId=%lld",(int64_t)jcr->JobId); ok(db_sql_query(db, buf, db_int_handler, &j), "Get Inserted record"); ok(j == ar.FileIndex, "Check FileIndex"); Mmsg(buf, "SELECT COUNT(1) FROM File WHERE JobId=%lld",(int64_t)jcr->JobId); ok(db_sql_query(db, buf, db_int_handler, &j), "List records"); ok(j == 1, "Check batch session records"); j = 0; Mmsg(buf, "%lld", (uint64_t)jcr->JobId); ok(db_get_file_list(jcr, jcr->db_batch, buf, false, false, list_files, &j), "List files with db_get_file_list()"); ok(j == 1, "Check db_get_file_list results"); /* ---------------------------------------------------------------- */ Pmsg0(0, PLINE "Doing Client tests" PLINE); CLIENT_DBR cr, cr2; memset(&cr, 0, sizeof(cr)); memset(&cr2, 0, sizeof(cr2)); cr.AutoPrune = 1; cr.FileRetention = 10; cr.JobRetention = 15; bsnprintf(cr.Name, sizeof(cr.Name), "client-%lld-fd", pid); bsnprintf(cr.Uname, sizeof(cr.Uname), "uname-%lld", pid); ok(db_create_client_record(jcr, db, &cr), "db_create_client_record()"); ok(cr.ClientId > 0, "Check ClientId"); cr2.ClientId = cr.ClientId; /* Save it */ cr.ClientId = 0; Pmsg0(0, "Search client by ClientId\n"); ok(db_create_client_record(jcr, db, &cr),"Should get the client record"); ok(cr.ClientId == cr2.ClientId, "Check if ClientId is the same"); ok(db_get_client_record(jcr, db, &cr2), "Search client by ClientId"); cmp_client(cr, cr2); Pmsg0(0, "Search client by Name\n"); memset(&cr2, 0, sizeof(cr2)); strcpy(cr2.Name, cr.Name); ok(db_get_client_record(jcr, db, &cr2),"Search client by Name"); cmp_client(cr, cr2); Pmsg0(0, "Search non existing client by Name\n"); memset(&cr2, 0, sizeof(cr2)); bsnprintf(cr2.Name, sizeof(cr2.Name), "hollow-client-%lld-fd", pid); nok(db_get_client_record(jcr, db, &cr2), "Search non existing client"); ok(cr2.ClientId == 0, "Check ClientId after failed search"); cr.AutoPrune = 0; strcpy(cr.Uname, "NewUname"); ok(db_update_client_record(jcr, db, &cr), "Update Client record"); memset(&cr2, 0, sizeof(cr2)); cr2.ClientId = cr.ClientId; ok(db_get_client_record(jcr, db, &cr2),"Search client by ClientId"); cmp_client(cr, cr2); int nb, i; uint32_t *ret_ids; ok(db_get_client_ids(jcr, db, &nb, &ret_ids), "Get Client Ids"); ok(nb > 0, "Should find at least 1 Id"); for (i = 0; i < nb; i++) { if (ret_ids[i] == cr2.ClientId) { break; } } ok(i < nb, "Check if ClientId was found"); /* ---------------------------------------------------------------- */ Pmsg0(0, PLINE "Doing Pool tests" PLINE); POOL_DBR pr, pr2; memset(&pr, 0, sizeof(pr)); memset(&pr2, 0, sizeof(pr2)); bsnprintf(pr.Name, sizeof(pr.Name), "pool-%lld", pid); pr.MaxVols = 10; pr.UseOnce = 0; pr.UseCatalog = true; pr.AcceptAnyVolume = true; pr.AutoPrune = true; pr.Recycle = true; pr.VolRetention = 1000; pr.VolUseDuration = 1000; pr.MaxVolJobs = 100; pr.MaxVolFiles = 1000; pr.MaxVolBytes = 1000000; strcpy(pr.PoolType, "Backup"); pr.LabelType = 0; pr.LabelFormat[0] = 0; pr.RecyclePoolId = 0; pr.ScratchPoolId = 0; pr.ActionOnPurge = 1; ok(db_create_pool_record(jcr, db, &pr), "db_create_pool_record()"); ok(pr.PoolId > 0, "Check PoolId"); pr2.PoolId = pr.PoolId; pr.PoolId = 0; Pmsg0(0, "Search pool by PoolId\n"); nok(db_create_pool_record(jcr, db, &pr),"Can't create pool twice"); ok(db_get_pool_record(jcr, db, &pr2), "Search pool by PoolId"); cmp_pool(pr, pr2); pr2.MaxVols++; pr2.AutoPrune = false; pr2.Recycle = false; pr2.VolRetention++; pr2.VolUseDuration++; pr2.MaxVolJobs++; pr2.MaxVolFiles++; pr2.MaxVolBytes++; strcpy(pr2.PoolType, "Restore"); strcpy(pr2.LabelFormat, "VolFormat"); pr2.RecyclePoolId = 0; pr2.ScratchPoolId = 0; pr2.ActionOnPurge = 2; ok(db_update_pool_record(jcr, db, &pr2), "Update Pool record"); memset(&pr, 0, sizeof(pr)); pr.PoolId = pr2.PoolId; ok(db_get_pool_record(jcr, db, &pr), "Search pool by PoolId"); cmp_pool(pr, pr2); ok(db_delete_pool_record(jcr, db, &pr), "Delete Pool"); nok(db_delete_pool_record(jcr, db, &pr), "Delete non existing Pool"); nok(db_update_pool_record(jcr, db, &pr), "Update non existing Pool"); ok(db_create_pool_record(jcr, db, &pr), "Recreate Pool"); /* ---------------------------------------------------------------- */ Pmsg0(0, PLINE "Doing Media tests" PLINE); MEDIA_DBR mr, mr2; memset(&mr, 0, sizeof(mr)); memset(&mr2, 0, sizeof(mr2)); bsnprintf(mr.VolumeName, sizeof(mr.VolumeName), "media-%lld", pid); bsnprintf(mr.MediaType, sizeof(mr.MediaType), "type-%lld", pid); /* from set_pool_dbr_defaults_in_media_dbr(&mr, &pr); */ mr.PoolId = pr.PoolId; bstrncpy(mr.VolStatus, NT_("Append"), sizeof(mr.VolStatus)); mr.Recycle = pr.Recycle; mr.VolRetention = pr.VolRetention; mr.VolUseDuration = pr.VolUseDuration; mr.ActionOnPurge = pr.ActionOnPurge; mr.RecyclePoolId = pr.RecyclePoolId; mr.MaxVolJobs = pr.MaxVolJobs; mr.MaxVolFiles = pr.MaxVolFiles; mr.MaxVolBytes = pr.MaxVolBytes; mr.LabelType = pr.LabelType; mr.Enabled = 1; mr.VolCapacityBytes = 1000; mr.Slot = 1; mr.VolBytes = 1000; mr.InChanger = 1; mr.VolReadTime = 10000; mr.VolWriteTime = 99999; mr.StorageId = 0; mr.DeviceId = 0; mr.LocationId = 0; mr.ScratchPoolId = 0; mr.RecyclePoolId = 0; ok(db_create_media_record(jcr, db, &mr), "Create Media"); nok(db_create_media_record(jcr, db, &mr), "Create Media twice"); /* ---------------------------------------------------------------- */ Pmsg0(0, PLINE "Doing ... tests" PLINE); db_close_database(jcr, db); report(); free_pool_memory(buf); free_pool_memory(buf2); free_pool_memory(buf3); return 0; } bareos-Release-14.2.6/src/tests/gigaslam.c000066400000000000000000000022721263011562700203240ustar00rootroot00000000000000/* By John Walker written ages ago. Create a sparse file. Beat denial of service floggers to death by persuading them to download a HOW_BIG pseudo GIF file which is actually a holey file occupying trivial space on our server. Make: make gigaslam Run: ./gigaslam Output: a file named gigaslam.gif that contains something like 16K bytes (i.e. 2-8K blocks), but appears to be 1GB in length because the second block is written at a 1GB address. Be careful what you do with this file as not all programs know how to deal with sparse files. */ #define HOW_BIG 1000000000ll #ifdef __GNUC__ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif #endif #include #include #include int main(int argc, char *const *argv) { FILE *fp = fopen("gigaslam.gif", "w"); char header[] = "\n\n
\n"; char trailer[] = "\n"; off_t howBig = HOW_BIG; fwrite(header, sizeof header, 1, fp); fseeko(fp, howBig - strlen(trailer), 0); fwrite(trailer, strlen(trailer), 1, fp); fclose(fp); return 0; } bareos-Release-14.2.6/src/tests/grow.c000066400000000000000000000025461263011562700175220ustar00rootroot00000000000000/* By John Walker written ages ago. Create a sparse file. Beat denial of service floggers to death by persuading them to download a HOW_BIG pseudo GIF file which is actually a holey file occupying trivial space on our server. Make: make gigaslam Run: ./gigaslam Output: a file named gigaslam.gif that contains something like 16K bytes (i.e. 2-8K blocks), but appears to be 1GB in length because the second block is written at a 1GB address. Be careful what you do with this file as not all programs know how to deal with sparse files. Tweaked by Kern Sibbald, July 2007 to grow a file to a specified size. */ #ifdef __GNUC__ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif #endif #include "bareos.h" int main(int argc, char *argv[]) { off_t howBig; FILE *fp; if (argc != 3) { Pmsg0(0, "Calling sequence: grow \n"); exit(1); } howBig = str_to_int64(argv[2]); fp = fopen(argv[1], "r+"); if (!fp) { berrno be; Pmsg2(0, "Could not open %s for write. ERR=%s\n", argv[1], be.bstrerror()); exit(1); } char trailer[] = "xxxxxxx\n"; fseeko(fp, howBig - strlen(trailer), SEEK_SET); fwrite(trailer, strlen(trailer), 1, fp); fclose(fp); return 0; } bareos-Release-14.2.6/src/tests/ing_test.c000066400000000000000000000206621263011562700203570ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2009-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program to test Ingres DB routines * * Stefan Reddig, February 2010 * * reusing code by * Eric Bollengier, August 2009 */ #ifdef needed #include "bareos.h" #include "cats/cats.h" #include "cats/sql_glue.h" /* Local variables */ static B_DB *db; static const char *file = "COPYRIGHT"; #if defined(HAVE_DYNAMIC_CATS_BACKENDS) static const char *backend_directory = _PATH_BAREOS_BACKENDDIR; #endif static const char *db_name = "bareos"; static const char *db_user = "bareos"; static const char *db_password = ""; static const char *db_host = NULL; static void usage() { fprintf(stderr, _( PROG_COPYRIGHT "\nVersion: %s (%s)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -n specify the database name (default bareos)\n" " -u specify database user name (default bareos)\n" " -P specify database host (default NULL)\n" " -w specify working directory\n" " -j specify jobids\n" " -p specify path\n" " -f specify file\n" " -l maximum tuple to fetch\n" " -T truncate cache table before starting\n" " -v verbose\n" " -? print this message\n\n"), 2001, VERSION, BDATE); exit(1); } /* * simple handler for debug output of CRUD example */ static int test_handler(void *ctx, int num_fields, char **row) { Pmsg2(0, " Values are %d, %s\n", str_to_int64(row[0]), row[1]); return 0; } /* * string handler for debug output of simple SELECT tests */ static int string_handler(void *ctx, int num_fields, char **row) { Pmsg1(0, " Value is >>%s<<\n", row[0]); return 0; } /* number of thread started */ int main (int argc, char *argv[]) { int ch; alist* backend_directories = NULL; char *jobids = (char *)"1"; char *path=NULL, *client=NULL; uint64_t limit=0; bool clean=false; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); Dmsg0(0, "Starting ing_test tool\n"); my_name_is(argc, argv, "ing_test"); init_msg(NULL, NULL); OSDependentInit(); while ((ch = getopt(argc, argv, "h:c:l:d:n:P:Su:vf:w:?j:p:f:T")) != -1) { switch (ch) { case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'l': limit = str_to_int64(optarg); break; case 'c': client = optarg; break; case 'h': db_host = optarg; break; case 'n': db_name = optarg; break; case 'w': working_directory = optarg; break; case 'u': db_user = optarg; break; case 'P': db_password = optarg; break; case 'v': verbose++; break; case 'p': path = optarg; break; case 'f': file = optarg; break; case 'j': jobids = optarg; break; case 'T': clean = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 0) { Pmsg0(0, _("Wrong number of arguments: \n")); usage(); } #if defined(HAVE_DYNAMIC_CATS_BACKENDS) backend_directories = New(alist(10, owned_by_alist)); backend_directories->append((char *)backend_directory); db_set_backend_dirs(backend_directories); #endif if ((db = db_init_database(NULL, "ingres", db_name, db_user, db_password, db_host, 0, NULL)) == NULL) { Emsg0(M_ERROR_TERM, 0, _("Could not init Bareos database\n")); } Dmsg1(0, "db_type=%s\n", db_get_type(db)); if (!db_open_database(NULL, db)) { Emsg0(M_ERROR_TERM, 0, db_strerror(db)); } Dmsg0(200, "Database opened\n"); if (verbose) { Pmsg2(000, _("Using Database: %s, User: %s\n"), db_name, db_user); } /* * simple CRUD test including create/drop table */ Pmsg0(0, "\nsimple CRUD test...\n\n"); const char *stmt1[8] = { "CREATE TABLE t1 ( c1 integer, c2 varchar(29))", "INSERT INTO t1 VALUES (1, 'foo')", "SELECT c1,c2 FROM t1", "UPDATE t1 SET c2='bar' WHERE c1=1", "SELECT * FROM t1", "DELETE FROM t1 WHERE c2 LIKE '\%r'", "SELECT * FROM t1", "DROP TABLE t1" }; int (*hndl1[8])(void*,int,char**) = { NULL, NULL, test_handler, NULL, test_handler, NULL, test_handler, NULL }; for (int i=0; i<8; ++i) { Pmsg1(0, "DB-Statement: %s\n",stmt1[i]); if (!db_sql_query(db, stmt1[i], hndl1[i], NULL)) { Emsg0(M_ERROR_TERM, 0, _("Stmt went wrong\n")); } } /* * simple SELECT tests without tables */ Pmsg0(0, "\nsimple SELECT tests without tables...\n\n"); const char *stmt2[8] = { "SELECT 'Test of simple SELECT!'", "SELECT 'Test of simple SELECT!' as Text", "SELECT VARCHAR(LENGTH('Test of simple SELECT!'))", "SELECT DBMSINFO('_version')", "SELECT 'This is a ''quoting'' test with single quotes'", "SELECT 'This is a \"quoting\" test with double quotes'", "SELECT null", "SELECT ''" }; int (*hndl2[8])(void*,int,char**) = { string_handler, string_handler, string_handler, string_handler, string_handler, string_handler, string_handler, string_handler }; for (int i=0; i<8; ++i) { Pmsg1(0, "DB-Statement: %s\n",stmt2[i]); if (!db_sql_query(db, stmt2[i], hndl2[i], NULL)) { Emsg0(M_ERROR_TERM, 0, _("Stmt went wrong\n")); } } /* * testing aggregates like avg, max, sum */ Pmsg0(0, "\ntesting aggregates...\n\n"); const char *stmt[11] = { "CREATE TABLE t1 (c1 integer, c2 varchar(29))", "INSERT INTO t1 VALUES (1,'foo')", "INSERT INTO t1 VALUES (2,'bar')", "INSERT INTO t1 VALUES (3,'fun')", "INSERT INTO t1 VALUES (4,'egg')", "SELECT max(c1) from t1", "SELECT sum(c1) from t1", "INSERT INTO t1 VALUES (5,NULL)", "SELECT count(*) from t1", "SELECT count(c2) from t1", "DROP TABLE t1" }; int (*hndl[11])(void*,int,char**) = { NULL, NULL, NULL, NULL, NULL, string_handler, string_handler, NULL, string_handler, string_handler, NULL }; for (int i=0; i<11; ++i) { Pmsg1(0, "DB-Statement: %s\n",stmt[i]); if (!db_sql_query(db, stmt[i], hndl[i], NULL)) { Emsg0(M_ERROR_TERM, 0, _("Stmt went wrong\n")); } } /* * datatypes test */ Pmsg0(0, "\ndatatypes test... (TODO)\n\n"); Dmsg0(200, "DB-Statement: CREATE TABLE for datatypes\n"); if (!db_sql_query(db, "CREATE TABLE t2 (" "c1 integer," "c2 varchar(255)," "c3 char(255)" /* some more datatypes... "c4 ," */ ")" , NULL, NULL)) { Emsg0(M_ERROR_TERM, 0, _("CREATE-Stmt went wrong\n")); } Dmsg0(200, "DB-Statement: DROP TABLE for datatypes\n"); if (!db_sql_query(db, "DROP TABLE t2", NULL, NULL)) { Emsg0(M_ERROR_TERM, 0, _("DROP-Stmt went wrong\n")); } db_close_database(NULL, db); db_flush_backends(); Dmsg0(200, "Database closed\n"); return 0; } #else /* needed */ int main (int argc, char *argv[]) { return 1; } #endif /* needed */ bareos-Release-14.2.6/src/tests/testls.c000066400000000000000000000166531263011562700200660ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Test program for listing files during regression testing * Links have their permissions and time bashed since they cannot * be set by Bareos. * * Kern Sibbald, MM */ #include "bareos.h" #include "findlib/find.h" #include "filed/fd_plugins.h" /* Dummy functions */ int generate_job_event(JCR *jcr, const char *event) { return 1; } void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) { } /* Global variables */ int attrs = 0; static JCR *jcr; static int num_files = 0; static int print_file(JCR *jcr, FF_PKT *ff, bool); static void print_ls_output(char *fname, char *link, int type, struct stat *statp); static int count_files(JCR *jcr, FF_PKT *ff, bool top_level); static void usage() { fprintf(stderr, _( "\n" "Usage: testls [-d debug_level] [-] [pattern1 ...]\n" " -a print extended attributes (Win32 debug)\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -e specify file of exclude patterns\n" " -i specify file of include patterns\n" " -q quiet, don't print filenames (debug)\n" " - read pattern(s) from stdin\n" " -? print this message.\n" "\n" "Patterns are file inclusion -- normally directories.\n" "Debug level >= 1 prints each file found.\n" "Debug level >= 10 prints path/file for catalog.\n" "Errors always printed.\n" "Files/paths truncated is number with len > 255.\n" "Truncation is only in catalog.\n" "\n")); exit(1); } int main(int argc, char *const *argv) { FF_PKT *ff; char name[1000]; bool quiet = false; int i, ch; char *inc = NULL; char *exc = NULL; FILE *fd; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); lmgr_init_thread(); while ((ch = getopt(argc, argv, "ad:e:i:q?")) != -1) { switch (ch) { case 'a': /* print extended attributes *debug* */ attrs = 1; break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'e': /* exclude patterns */ exc = optarg; break; case 'i': /* include patterns */ inc = optarg; break; case 'q': quiet = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; jcr = new_jcr(sizeof(JCR), NULL); ff = init_find_files(); if (argc == 0 && !inc) { add_fname_to_include_list(ff, 0, "/"); /* default to / */ } else { for (i=0; i < argc; i++) { if (bstrcmp(argv[i], "-")) { while (fgets(name, sizeof(name)-1, stdin)) { strip_trailing_junk(name); add_fname_to_include_list(ff, 0, name); } continue; } add_fname_to_include_list(ff, 0, argv[i]); } } if (inc) { fd = fopen(inc, "rb"); if (!fd) { printf(_("Could not open include file: %s\n"), inc); exit(1); } while (fgets(name, sizeof(name)-1, fd)) { strip_trailing_junk(name); add_fname_to_include_list(ff, 0, name); } fclose(fd); } if (exc) { fd = fopen(exc, "rb"); if (!fd) { printf(_("Could not open exclude file: %s\n"), exc); exit(1); } while (fgets(name, sizeof(name)-1, fd)) { strip_trailing_junk(name); add_fname_to_exclude_list(ff, name); } fclose(fd); } if (quiet) { match_files(jcr, ff, count_files); } else { match_files(jcr, ff, print_file); } printf(_("Files seen = %d\n"), num_files); term_include_exclude_files(ff); term_find_files(ff); free_jcr(jcr); term_last_jobs_list(); /* free jcr chain */ close_memory_pool(); lmgr_cleanup_main(); sm_dump(false); exit(0); } static int count_files(JCR *jcr, FF_PKT *ff, bool top_level) { num_files++; return 1; } static int print_file(JCR *jcr, FF_PKT *ff, bool top_level) { switch (ff->type) { case FT_LNKSAVED: case FT_REGE: case FT_REG: case FT_LNK: case FT_DIREND: case FT_SPEC: print_ls_output(ff->fname, ff->link, ff->type, &ff->statp); break; case FT_DIRBEGIN: break; case FT_NOACCESS: printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno)); break; case FT_NOFOLLOW: printf(_("Err: Could not follow ff->link %s: %s\n"), ff->fname, strerror(errno)); break; case FT_NOSTAT: printf(_("Err: Could not stat %s: %s\n"), ff->fname, strerror(errno)); break; case FT_NOCHG: printf(_("Skip: File not saved. No change. %s\n"), ff->fname); break; case FT_ISARCH: printf(_("Err: Attempt to backup archive. Not saved. %s\n"), ff->fname); break; case FT_NORECURSE: printf(_("Recursion turned off. Directory not entered. %s\n"), ff->fname); break; case FT_NOFSCHG: printf(_("Skip: File system change prohibited. Directory not entered. %s\n"), ff->fname); break; case FT_NOOPEN: printf(_("Err: Could not open directory %s: %s\n"), ff->fname, strerror(errno)); break; default: printf(_("Err: Unknown file ff->type %d: %s\n"), ff->type, ff->fname); break; } num_files++; return 1; } static void print_ls_output(char *fname, char *link, int type, struct stat *statp) { char buf[2000]; char ec1[30]; char *p, *f; int n; if (type == FT_LNK) { statp->st_mtime = 0; statp->st_mode |= 0777; } p = encode_mode(statp->st_mode, buf); n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink); p += n; n = sprintf(p, "%-4d %-4d", (int)statp->st_uid, (int)statp->st_gid); p += n; n = sprintf(p, "%10.10s ", edit_uint64(statp->st_size, ec1)); p += n; if (S_ISCHR(statp->st_mode) || S_ISBLK(statp->st_mode)) { n = sprintf(p, "%4x ", (int)statp->st_rdev); } else { n = sprintf(p, " "); } p += n; p = encode_time(statp->st_mtime, p); *p++ = ' '; /* Copy file name */ for (f=fname; *f && (p-buf) < (int)sizeof(buf); ) *p++ = *f++; if (type == FT_LNK) { *p++ = '-'; *p++ = '>'; *p++ = ' '; /* Copy link name */ for (f=link; *f && (p-buf) < (int)sizeof(buf); ) *p++ = *f++; } *p++ = '\n'; *p = 0; fputs(buf, stdout); } bool python_set_prog(JCR*, char const*) { return false; } bareos-Release-14.2.6/src/tools/000077500000000000000000000000001263011562700163675ustar00rootroot00000000000000bareos-Release-14.2.6/src/tools/Makefile.in000066400000000000000000000124561263011562700204440ustar00rootroot00000000000000# # Bareos Tools Makefile # @MCOMMON@ srcdir = @srcdir@ VPATH = @srcdir@ .PATH: @srcdir@ # one up basedir = .. # top dir topdir = ../.. # this dir relative to top dir thisdir = src/tools DEBUG=@DEBUG@ ZLIB_INC=@ZLIB_INC@ LZO_INC=@LZO_INC@ first_rule: all dummy: GETTEXT_LIBS = @LIBINTL@ OPENSSL_LIBS_NONSHARED = @OPENSSL_LIBS_NONSHARED@ GNUTLS_LIBS_NONSHARED = @GNUTLS_LIBS_NONSHARED@ TOOLS = bsmtp drivetype fstype bregex bwild bpluginfo bscrypto timelimit TOOLS_BIN = bsmtp bwild bregex TOOLS_SBIN = bpluginfo bscrypto INCLUDES += -I$(srcdir) -I$(basedir) -I$(basedir)/include .SUFFIXES: .c .o .PHONY: .DONTCARE: # inference rules .c.o: @echo "Compiling $<" $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) $(DINCLUDE) $(CXXFLAGS) $< #------------------------------------------------------------------------- all: Makefile $(TOOLS) @echo "==== Make of tools is good ====" @echo " " bsmtp: Makefile bsmtp.o ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -o $@ bsmtp.o -lbareos -lm $(DLIB) $(LIBS) \ $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) fstype: Makefile fstype.o \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ fstype.o -lbareosfind -lbareos -lm \ $(DLIB) $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) drivetype: Makefile drivetype.o \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ drivetype.o -lbareosfind -lbareos -lm \ $(DLIB) $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bregex: Makefile bregex.o \ ../findlib/libbareosfind$(DEFAULT_ARCHIVE_TYPE) \ ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -L../lib -o $@ bregex.o \ $(DLIB) -lbareos -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bwild: Makefile bwild.o ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -L../lib -o $@ bwild.o \ $(DLIB) -lbareos -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bscrypto: Makefile bscrypto.o ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -L../lib -o $@ bscrypto.o \ $(DLIB) -lbareos -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) bpluginfo.o: bpluginfo.c @echo "Compiling $<" $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) $(INCLUDES) -I../filed -I../dird -I../stored $(DINCLUDE) $(CFLAGS) $< bpluginfo: Makefile bpluginfo.o ../lib/libbareos$(DEFAULT_ARCHIVE_TYPE) @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L../lib -o $@ bpluginfo.o -lbareos $(LIBS) \ $(GETTEXT_LIBS) $(OPENSSL_LIBS_NONSHARED) $(GNUTLS_LIBS_NONSHARED) timelimit.o: timelimit.c @echo "Compiling $<" ${CC} ${DEFS} ${DEBUG} $(CFLAGS) -DHAVE_ERRNO_H -DHAVE_SETITIMER -DHAVE_SIGACTION -c timelimit.c timelimit: timelimit.o @echo "Linking $@ ..." $(LIBTOOL_LINK) $(CC) $(LDFLAGS) -o $@ timelimit.o Makefile: $(srcdir)/Makefile.in $(topdir)/config.status cd $(topdir) \ && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status libtool-clean: @$(RMF) -r .libs _libs clean: libtool-clean @$(RMF) bsmtp core core.* a.out *.o *.bak *~ *.intpro *.extpro 1 2 3 @$(RMF) $(TOOLS) realclean: clean @$(RMF) tags distclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) devclean: realclean if test $(srcdir) = .; then $(MAKE) realclean; fi (cd $(srcdir); $(RMF) Makefile) installall: $(TOOLS) @for tool in ${TOOLS} ; do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$tool $(DESTDIR)$(sbindir)/$$tool ; \ done chmod 755 $(DESTDIR)$(sbindir)/bsmtp installbin: $(TOOLS_BIN) $(MKDIR) $(DESTDIR)$(bindir) $(MKDIR) $(DESTDIR)$(sbindir) @for tool in ${TOOLS_BIN} ; do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$tool $(DESTDIR)$(bindir)/$$tool ; \ if ! [ -r $(DESTDIR)$(sbindir)/$$tool ]; then $(SYMLINK) $(bindir)/$$tool $(DESTDIR)$(sbindir)/$$tool; fi; \ done # Allow non-root execution of bsmtp for non-root Directors chmod 755 $(DESTDIR)$(bindir)/bsmtp installsbin: $(TOOLS_SBIN) $(MKDIR) $(DESTDIR)$(sbindir) @for tool in ${TOOLS_SBIN} ; do \ $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $$tool $(DESTDIR)$(sbindir)/$$tool ; \ done install: installbin installsbin # Semi-automatic generation of dependencies: # Use gcc -MM because X11 `makedepend' doesn't work on all systems # and it also includes system headers. # `semi'-automatic since dependencies are generated at distribution time. depend: @$(MV) Makefile Makefile.bak @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile @$(ECHOCMD) "# DO NOT DELETE: nice dependency list follows" >> Makefile @$(CXX) -S -M $(CPPFLAGS) $(INCLUDES) -I../filed -I../dird -I../stored *.c >> Makefile @if test -f Makefile ; then \ $(RMF) Makefile.bak; \ else \ $(MV) Makefile.bak Makefile; \ echo " ===== Something went wrong in make depend ====="; \ fi # ----------------------------------------------------------------------- # DO NOT DELETE: nice dependency list follows bareos-Release-14.2.6/src/tools/assert_macro.h000066400000000000000000000064501263011562700212270ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Assertion definitions */ #ifndef _ASSERT_MACRO_H #define _ASSERT_MACRO_H 1 /* Assertions definitions */ /* check valid pointer if not return */ #ifndef ASSERT_NVAL_RET #define ASSERT_NVAL_RET(value) \ if ( ! value ){ \ return; \ } #endif /* check an error if true return */ #ifndef ASSERT_VAL_RET #define ASSERT_VAL_RET(value) \ if ( value ){ \ return; \ } #endif /* check valid pointer with Null return */ #ifndef ASSERT_NVAL_RET_NULL #define ASSERT_NVAL_RET_NULL(value) \ if ( ! value ) \ { \ return NULL; \ } #endif /* if value then Null return */ #ifndef ASSERT_VAL_RET_NULL #define ASSERT_VAL_RET_NULL(value) \ if ( value ) \ { \ return NULL; \ } #endif /* check valid pointer with int/err return */ #ifndef ASSERT_NVAL_RET_ONE #define ASSERT_NVAL_RET_ONE(value) \ if ( ! value ) \ { \ return 1; \ } #endif /* check valid pointer with int/err return */ #ifndef ASSERT_NVAL_RET_NONE #define ASSERT_NVAL_RET_NONE(value) \ if ( ! value ) \ { \ return -1; \ } #endif /* check error if not exit with error */ #ifndef ASSERT_NVAL_EXIT_ONE #define ASSERT_NVAL_EXIT_ONE(value) \ if ( ! value ){ \ exit ( 1 ); \ } #endif /* check error if not exit with error */ #ifndef ASSERT_NVAL_EXIT_E #define ASSERT_NVAL_EXIT_E(value,ev) \ if ( ! value ){ \ exit ( ev ); \ } #endif /* check error if not return zero */ #ifndef ASSERT_NVAL_RET_ZERO #define ASSERT_NVAL_RET_ZERO(value) \ if ( ! value ){ \ return 0; \ } #endif /* check error if not return value */ #ifndef ASSERT_NVAL_RET_V #define ASSERT_NVAL_RET_V(value,rv) \ if ( ! value ){ \ return rv; \ } #endif /* checks error value then int/err return */ #ifndef ASSERT_VAL_RET_ONE #define ASSERT_VAL_RET_ONE(value) \ if ( value ) \ { \ return 1; \ } #endif /* checks error value then int/err return */ #ifndef ASSERT_VAL_RET_NONE #define ASSERT_VAL_RET_NONE(value) \ if ( value ) \ { \ return -1; \ } #endif /* checks error value then exit one */ #ifndef ASSERT_VAL_EXIT_ONE #define ASSERT_VAL_EXIT_ONE(value) \ if ( value ) \ { \ exit (1); \ } #endif /* check error if not return zero */ #ifndef ASSERT_VAL_RET_ZERO #define ASSERT_VAL_RET_ZERO(value) \ if ( value ){ \ return 0; \ } #endif /* check error if not return value */ #ifndef ASSERT_VAL_RET_V #define ASSERT_VAL_RET_V(value,rv) \ if ( value ){ \ return rv; \ } #endif #endif /* _ASSERT_MACRO_H */ bareos-Release-14.2.6/src/tools/bpluginfo.c000066400000000000000000000324601263011562700205250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Contributed in 2012 by Inteos sp. z o.o. * * Utility tool display various information about Bareos plugin, * including but not limited to: * - Name and Author of the plugin * - Plugin License * - Description * - API version * - Enabled functions, etc. */ #include "bareos.h" #include "fd_plugins.h" #include "dir_plugins.h" #include "sd_plugins.h" #include "assert_macro.h" #ifndef __WIN32__ #include #endif extern "C" { typedef int (*loadPlugin) (void *binfo, void *bfuncs, void **pinfo, void **pfuncs); typedef int (*unloadPlugin) (void); } #define DEFAULT_API_VERSION 1 enum plugintype { DIRPLUGIN, FDPLUGIN, SDPLUGIN, ERRORPLUGIN }; /* * pDirFuncs * pFuncs * psdFuncs */ typedef union _plugfuncs plugfuncs; union _plugfuncs { pDirFuncs pdirfuncs; pFuncs pfdfuncs; psdFuncs psdfuncs; }; /* * bDirFuncs * bFuncs * bsdFuncs */ typedef struct _bareosfuncs bareosfuncs; struct _bareosfuncs { uint32_t size; uint32_t version; int (*registerBareosEvents) (void *ctx, ...); int (*getBareosValue) (void *ctx, int var, void *value); int (*setBareosValue) (void *ctx, int var, void *value); int (*JobMessage) (void *ctx, const char *file, int line, int type, int64_t mtime, const char *fmt, ...); int (*DebugMessage) (void *ctx, const char *file, int line, int level, const char *fmt, ...); void *(*bareosMalloc) (void *ctx, const char *file, int line, size_t size); void (*bareosFree) (void *ctx, const char *file, int line, void *mem); }; /* * bDirInfo * bInfo * bsdInfo */ typedef union _bareosinfos bareosinfos; union _bareosinfos { bDirInfo bdirinfo; bInfo bfdinfo; bsdInfo bsdinfo; }; typedef struct _progdata progdata; struct _progdata { bool verbose; bool listinfo; bool listfunc; char *pluginfile; void *pluginhandle; int bapiversion; int bplugtype; gen_pluginInfo *pinfo; plugfuncs *pfuncs; }; /* memory allocation/deallocation */ #define MALLOC(size) \ (char *) bmalloc ( size ); #define ASSERT_MEMORY(m) \ if ( m == NULL ){ \ printf ( "Error: memory allocation error!\n" ); \ exit (10); \ } #define FREE(ptr) \ if ( ptr != NULL ){ \ bfree ( ptr ); \ ptr = NULL; \ } int registerBareosEvents(void *ctx, ...) { return 0; }; int getBareosValue(void *ctx, int var, void *value) { return 0; }; int setBareosValue(void *ctx, int var, void *value) { return 0; }; int DebugMessage(void *ctx, const char *file, int line, int level, const char *fmt, ...) { #ifdef DEBUGMSG printf("DG: %s:%d %s\n", file, line, fmt); #endif return 0; }; int JobMessage(void *ctx, const char *file, int line, int type, int64_t mtime, const char *fmt, ...) { #ifdef DEBUGMSG printf("JM: %s:%d <%d> %s\n", file, line, type, fmt); #endif return 0; }; void *bareosMalloc(void *ctx, const char *file, int line, size_t size) { return MALLOC(size); }; void bareosFree(void *ctx, const char *file, int line, void *mem) { FREE(mem); }; /* * displays a short help */ void print_help(int argc, char *argv[]) { printf("\n" "Usage: bpluginfo [options] \n" " -v verbose\n" " -i list plugin header information only (default)\n" " -f list plugin functions information only\n" " -a bareos api version (default %d)\n" " -h help screen\n" "\n", DEFAULT_API_VERSION); } /* allocates and resets a main program data variable */ progdata *allocpdata(void) { progdata *pdata; pdata = (progdata *) bmalloc(sizeof(progdata)); ASSERT_MEMORY(pdata); memset(pdata, 0, sizeof(progdata)); return pdata; } /* releases all allocated program data resources */ void freepdata(progdata *pdata) { if (pdata->pluginfile) { FREE(pdata->pluginfile); } FREE(pdata); } /* * parse execution arguments and fills required pdata structure fields * * input: * pdata - pointer to program data structure * argc, argv - execution envinroment variables * output: * pdata - required structure fields * * supported options: * -v verbose flag * -i list plugin header info only (default) * -f list implemented functions only * -a bareos api version (default 1) * -h help screen */ void parse_args(progdata *pdata, int argc, char *argv[]) { int ch; char *dirtmp; char *progdir; while ((ch = getopt(argc, argv, "a:fiv")) != -1) { switch (ch) { case 'a': pdata->bapiversion = atoi(optarg); break; case 'f': pdata->listfunc = true; break; case 'i': pdata->listinfo = true; break; case 'v': pdata->verbose = true; break; case '?': default: print_help(argc, argv); exit(0); } } argc -= optind; argv += optind; if (argc < 1) { print_help(argc, argv); exit(0); } if (!pdata->pluginfile) { if (argv[0][0] != '/') { dirtmp = MALLOC(PATH_MAX); ASSERT_MEMORY(dirtmp); progdir = MALLOC(PATH_MAX); ASSERT_MEMORY(progdir); dirtmp = getcwd(dirtmp, PATH_MAX); strcat(dirtmp, "/"); strcat(dirtmp, argv[0]); if (realpath(dirtmp, progdir) == NULL) { /* * Error in resolving path */ FREE(progdir); progdir = bstrdup(argv[0]); } pdata->pluginfile = bstrdup(progdir); FREE(dirtmp); FREE(progdir); } else { pdata->pluginfile = bstrdup(argv[0]); } } } /* * checks a plugin type based on a plugin magic string * * input: * pdata - program data with plugin info structure * output: * int - enum plugintype */ int getplugintype(progdata *pdata) { ASSERT_NVAL_RET_V(pdata, ERRORPLUGIN); gen_pluginInfo *pinfo = pdata->pinfo; ASSERT_NVAL_RET_V(pinfo, ERRORPLUGIN); if (pinfo->plugin_magic && bstrcmp(pinfo->plugin_magic, DIR_PLUGIN_MAGIC)) { return DIRPLUGIN; } else { if (pinfo->plugin_magic && bstrcmp(pinfo->plugin_magic, FD_PLUGIN_MAGIC)) { return FDPLUGIN; } else { if (pinfo->plugin_magic && bstrcmp(pinfo->plugin_magic, SD_PLUGIN_MAGIC)) { return SDPLUGIN; } else { return ERRORPLUGIN; } } } } /* * prints any available information about a plugin * * input: * pdata - program data with plugin info structure * output: * printed info */ void dump_pluginfo(progdata *pdata) { ASSERT_NVAL_RET(pdata); gen_pluginInfo *pinfo = pdata->pinfo; ASSERT_NVAL_RET(pinfo); plugfuncs *pfuncs = pdata->pfuncs; ASSERT_NVAL_RET(pfuncs); switch (pdata->bplugtype) { case DIRPLUGIN: printf("\nPlugin type:\t\tBareos Director plugin\n"); break; case FDPLUGIN: printf("\nPlugin type:\t\tBareos File Daemon plugin\n"); break; case SDPLUGIN: printf("\nPlugin type:\t\tBareos Storage plugin\n"); break; default: printf("\nUnknown plugin type or other Error\n\n"); return; } if (pdata->verbose) { printf("Plugin magic:\t\t%s\n", NPRT(pinfo->plugin_magic)); } printf("Plugin version:\t\t%s\n", pinfo->plugin_version); printf("Plugin release date:\t%s\n", NPRT(pinfo->plugin_date)); printf("Plugin author:\t\t%s\n", NPRT(pinfo->plugin_author)); printf("Plugin licence:\t\t%s\n", NPRT(pinfo->plugin_license)); printf("Plugin description:\t%s\n", NPRT(pinfo->plugin_description)); printf("Plugin API version:\t%d\n", pinfo->version); if (pinfo->plugin_usage) { printf("Plugin usage:\n%s\n", pinfo->plugin_usage); } } /* * prints any available information about plugin' functions * * input: * pdata - program data with plugin info structure * output: * printed info */ void dump_plugfuncs(progdata *pdata) { ASSERT_NVAL_RET(pdata); plugfuncs *pfuncs = pdata->pfuncs; ASSERT_NVAL_RET(pfuncs); printf("\nPlugin functions:\n"); switch (pdata->bplugtype) { case DIRPLUGIN: if (pdata->verbose) { if (pfuncs->pdirfuncs.newPlugin) { printf(" newPlugin()\n"); } if (pfuncs->pdirfuncs.freePlugin) { printf(" freePlugin()\n"); } } if (pfuncs->pdirfuncs.getPluginValue) { printf(" getPluginValue()\n"); } if (pfuncs->pdirfuncs.setPluginValue) { printf(" setPluginValue()\n"); } if (pfuncs->pdirfuncs.handlePluginEvent) { printf(" handlePluginEvent()\n"); } break; case FDPLUGIN: if (pdata->verbose) { if (pfuncs->pfdfuncs.newPlugin) { printf(" newPlugin()\n"); } if (pfuncs->pfdfuncs.freePlugin) { printf(" freePlugin()\n"); } } if (pfuncs->pfdfuncs.getPluginValue) { printf(" getPluginValue()\n"); } if (pfuncs->pfdfuncs.setPluginValue) { printf(" setPluginValue()\n"); } if (pfuncs->pfdfuncs.handlePluginEvent) { printf(" handlePluginEvent()\n"); } if (pfuncs->pfdfuncs.startBackupFile) { printf(" startBackupFile()\n"); } if (pfuncs->pfdfuncs.endBackupFile) { printf(" endBackupFile()\n"); } if (pfuncs->pfdfuncs.startRestoreFile) { printf(" startRestoreFile()\n"); } if (pfuncs->pfdfuncs.endRestoreFile) { printf(" endRestoreFile()\n"); } if (pfuncs->pfdfuncs.pluginIO) { printf(" pluginIO()\n"); } if (pfuncs->pfdfuncs.createFile) { printf(" createFile()\n"); } if (pfuncs->pfdfuncs.setFileAttributes) { printf(" setFileAttributes()\n"); } if (pfuncs->pfdfuncs.checkFile) { printf(" checkFile()\n"); } break; case SDPLUGIN: if (pdata->verbose) { if (pfuncs->psdfuncs.newPlugin) { printf(" newPlugin()\n"); } if (pfuncs->psdfuncs.freePlugin) { printf(" freePlugin()\n"); } } if (pfuncs->psdfuncs.getPluginValue) { printf(" getPluginValue()\n"); } if (pfuncs->psdfuncs.setPluginValue) { printf(" setPluginValue()\n"); } if (pfuncs->psdfuncs.handlePluginEvent) { printf(" handlePluginEvent()\n"); } break; default: printf("\nUnknown plugin type or other Error\n\n"); } } /* * input parameters: * argv[0] [options] * * exit codes: * 0 - success * 1 - cannot load a plugin * 2 - cannot find a loadPlugin function * 3 - cannot find an unloadPlugin function * 10 - not enough memory */ int main(int argc, char *argv[]) { progdata *pdata; loadPlugin loadplugfunc; unloadPlugin unloadplugfunc; bareosfuncs bfuncs = { sizeof(bfuncs), 1, registerBareosEvents, getBareosValue, setBareosValue, JobMessage, DebugMessage, bareosMalloc, bareosFree, }; bareosinfos binfos; pdata = allocpdata(); parse_args(pdata, argc, argv); binfos.bfdinfo.size = sizeof(binfos); binfos.bfdinfo.version = DEFAULT_API_VERSION; pdata->pluginhandle = dlopen(pdata->pluginfile, RTLD_LAZY); if (pdata->pluginhandle == NULL) { printf("\nCannot load a plugin: %s\n\n", dlerror()); freepdata(pdata); exit(1); } loadplugfunc = (loadPlugin) dlsym(pdata->pluginhandle, "loadPlugin"); if (loadplugfunc == NULL) { printf("\nCannot find loadPlugin function: %s\n", dlerror()); printf("\nWhether the file is a really Bareos plugin?\n\n"); freepdata(pdata); exit(2); } unloadplugfunc = (unloadPlugin) dlsym(pdata->pluginhandle, "unloadPlugin"); if (unloadplugfunc == NULL) { printf("\nCannot find unloadPlugin function: %s\n", dlerror()); printf("\nWhether the file is a really Bareos plugin?\n\n"); freepdata(pdata); exit(3); } if (pdata->bapiversion > 0) { binfos.bdirinfo.version = pdata->bapiversion; } loadplugfunc(&binfos, &bfuncs, (void **)&pdata->pinfo, (void **)&pdata->pfuncs); pdata->bplugtype = getplugintype(pdata); if (!pdata->listfunc) { dump_pluginfo(pdata); } if ((!pdata->listinfo && pdata->listfunc) || pdata->verbose) { dump_plugfuncs(pdata); } printf("\n"); unloadplugfunc(); dlclose(pdata->pluginhandle); freepdata(pdata); return 0; } bareos-Release-14.2.6/src/tools/bregex.c000066400000000000000000000075611263011562700200200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Test program for testing regular expressions. * * Kern Sibbald, MMVI */ #include "bareos.h" /* * If you define BAREOS_REGEX, bregex will be built with the * Bareos bregex library, which is the same code that we * use on Win32, thus using Linux, you can test your Win32 * expressions. Otherwise, this program will link with the * system library routines. */ //#define BAREOS_REGEX #ifdef BAREOS_REGEX #include "lib/bregex.h" #else #ifndef HAVE_REGEX_H #include "lib/bregex.h" #else #include #endif #endif static void usage() { fprintf(stderr, "\n" "Usage: bregex [-d debug_level] -f \n" " -f specify file of data to be matched\n" " -l suppress line numbers\n" " -n print lines that do not match\n" " -d set debug level to \n" " -dt print timestamp in debug output\n" " -? print this message.\n" "\n\n"); exit(1); } int main(int argc, char *const *argv) { regex_t preg; char prbuf[500]; char *fname = NULL; int rc, ch; char data[1000]; char pat[500]; FILE *fd; bool match_only = true; int lineno; bool no_linenos = false; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); while ((ch = getopt(argc, argv, "d:f:n?")) != -1) { switch (ch) { case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* data */ fname = optarg; break; case 'l': no_linenos = true; break; case 'n': match_only = false; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (!fname) { printf("A data file must be specified.\n"); usage(); } OSDependentInit(); for ( ;; ) { printf("Enter regex pattern: "); if (fgets(pat, sizeof(pat)-1, stdin) == NULL) { break; } strip_trailing_newline(pat); if (pat[0] == 0) { exit(0); } rc = regcomp(&preg, pat, REG_EXTENDED); if (rc != 0) { regerror(rc, &preg, prbuf, sizeof(prbuf)); printf("Regex compile error: %s\n", prbuf); continue; } fd = fopen(fname, "r"); if (!fd) { printf(_("Could not open data file: %s\n"), fname); exit(1); } lineno = 0; while (fgets(data, sizeof(data)-1, fd)) { strip_trailing_newline(data); lineno++; rc = regexec(&preg, data, 0, NULL, 0); if ((match_only && rc == 0) || (!match_only && rc != 0)) { if (no_linenos) { printf("%s\n", data); } else { printf("%5d: %s\n", lineno, data); } } } fclose(fd); regfree(&preg); } exit(0); } bareos-Release-14.2.6/src/tools/bscrypto.c000066400000000000000000000366051263011562700204120ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2012-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Load and clear an SCSI encryption key used by a tape drive * using a lowlevel SCSI interface. * * Marco van Wieringen, March 2012 */ #include "bareos.h" #include "lib/crypto_cache.h" static void usage() { fprintf(stderr, "\n" "Usage: bscrypto []\n" " -b Perform base64 encoding of keydata\n" " -c Clear encryption key\n" " -D Dump content of given cachefile\n" " -d Set debug level to \n" " -e Show drive encryption status\n" " -g Generate new encryption passphrase in keyfile\n" " -k Show content of keyfile\n" " -p Populate given cachefile with crypto keys\n" " -r Reset expiry time for entries of given cachefile\n" " -s Set encryption key loaded from keyfile\n" " -v Show volume encryption status\n" " -w Wrap/Unwrap the key using RFC3394 aes-(un)wrap\n" " using the key in keyfile as a Key Encryption Key\n" " -? print this message.\n" "\n" " A keyfile named - is either stdin or stdout depending on the option\n" "\n"); } int main(int argc, char *const *argv) { int retval = 0; int ch, kfd, length; bool base64_transform = false, clear_encryption = false, dump_cache = false, drive_encryption_status = false, generate_passphrase = false, populate_cache = false, reset_cache = false, set_encryption = false, show_keydata = false, volume_encryption_status = false, wrapped_keys = false; char *keyfile = NULL; char *cache_file = NULL; char *wrap_keyfile = NULL; char keydata[64]; char wrapdata[64]; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); while ((ch = getopt(argc, argv, "bcD:d:eg:k:p:r:s:vw:?")) != -1) { switch (ch) { case 'b': base64_transform = true; break; case 'c': clear_encryption = true; break; case 'D': dump_cache = true; cache_file = bstrdup(optarg); break; case 'd': debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } break; case 'e': drive_encryption_status = true; break; case 'g': generate_passphrase = true; if (keyfile) { usage(); goto bail_out; } keyfile = bstrdup(optarg); break; case 'k': show_keydata = true; if (keyfile) { usage(); goto bail_out; } keyfile = bstrdup(optarg); break; case 'p': populate_cache = true; cache_file = bstrdup(optarg); break; case 'r': reset_cache = true; cache_file = bstrdup(optarg); break; case 's': set_encryption = true; if (keyfile) { usage(); goto bail_out; } keyfile = bstrdup(optarg); break; case 'v': volume_encryption_status = true; break; case 'w': wrapped_keys = true; wrap_keyfile = bstrdup(optarg); break; case '?': default: usage(); goto bail_out; } } argc -= optind; argv += optind; if (!generate_passphrase && !show_keydata && !dump_cache && !populate_cache && !reset_cache && argc < 1) { fprintf(stderr, _("Missing device_name argument for this option\n")); usage(); retval = 1; goto bail_out; } if (generate_passphrase && show_keydata) { fprintf(stderr, _("Either use -g or -k not both\n")); retval = 1; goto bail_out; } if (clear_encryption && set_encryption) { fprintf(stderr, _("Either use -c or -s not both\n")); retval = 1; goto bail_out; } if ((clear_encryption || set_encryption) && (drive_encryption_status || volume_encryption_status)) { fprintf(stderr, _("Either set or clear the crypto key or ask for status not both\n")); retval = 1; goto bail_out; } if ((clear_encryption || set_encryption || drive_encryption_status || volume_encryption_status) && (generate_passphrase || show_keydata || dump_cache || populate_cache || reset_cache)) { fprintf(stderr, _("Don't mix operations which are incompatible " "e.g. generate/show vs set/clear etc.\n")); retval = 1; goto bail_out; } OSDependentInit(); init_msg(NULL, NULL); if (dump_cache) { /* * Load any keys currently in the cache. */ read_crypto_cache(cache_file); /* * Dump the content of the cache. */ dump_crypto_cache(1); flush_crypto_cache(); goto bail_out; } if (populate_cache) { char *VolumeName, *EncrKey; char new_cache_entry[256]; /* * Load any keys currently in the cache. */ read_crypto_cache(cache_file); /* * Read new entries from stdin and parse them to update * the cache. */ fprintf(stdout, _("Enter cache entrie(s) (close with ^D): ")); fflush(stdout); memset(new_cache_entry, 0, sizeof(new_cache_entry)); while (read(1, new_cache_entry, sizeof(new_cache_entry)) > 0) { strip_trailing_junk(new_cache_entry); /* * Try to parse the entry. */ VolumeName = new_cache_entry; EncrKey = strchr(new_cache_entry, '\t'); if (!EncrKey) { break; } *EncrKey++ = '\0'; update_crypto_cache(VolumeName, EncrKey); memset(new_cache_entry, 0, sizeof(new_cache_entry)); } /* * Write out the new cache entries. */ write_crypto_cache(cache_file); flush_crypto_cache(); goto bail_out; } if (reset_cache) { /* * Load any keys currently in the cache. */ read_crypto_cache(cache_file); /* * Reset all entries. */ reset_crypto_cache(); /* * Write out the new cache entries. */ write_crypto_cache(cache_file); flush_crypto_cache(); goto bail_out; } memset(keydata, 0, sizeof(keydata)); memset(wrapdata, 0, sizeof(wrapdata)); if (wrapped_keys) { /* * Read the key bits from the keyfile. * - == stdin */ if (bstrcmp(wrap_keyfile, "-")) { kfd = 0; fprintf(stdout, _("Enter Key Encryption Key: ")); fflush(stdout); } else { kfd = open(wrap_keyfile, O_RDONLY); if (kfd < 0) { fprintf(stderr, _("Cannot open keyfile %s\n"), wrap_keyfile); retval = 1; goto bail_out; } } read(kfd, wrapdata, sizeof(wrapdata)); if (kfd > 0) { close(kfd); } strip_trailing_junk(wrapdata); Dmsg1(10, "Wrapped keydata = %s\n", wrapdata); } /* * Generate a new passphrase allow it to be wrapped using the given wrapkey * and base64 if specified or when wrapped. */ if (generate_passphrase) { int cnt; char *passphrase; passphrase = generate_crypto_passphrase(DEFAULT_PASSPHRASE_LENGTH); if (!passphrase) { retval = 1; goto bail_out; } Dmsg1(10, "Generated passphrase = %s\n", passphrase); /* * See if we need to wrap the passphrase. */ if (wrapped_keys) { char *wrapped_passphrase; length = DEFAULT_PASSPHRASE_LENGTH + 8; wrapped_passphrase = (char *)malloc(length); memset(wrapped_passphrase, 0, length); aes_wrap((unsigned char *)wrapdata, DEFAULT_PASSPHRASE_LENGTH / 8, (unsigned char *)passphrase, (unsigned char *)wrapped_passphrase); free(passphrase); passphrase = wrapped_passphrase; } else { length = DEFAULT_PASSPHRASE_LENGTH; } /* * See where to write the key. * - == stdout */ if (bstrcmp(keyfile, "-")) { kfd = 1; } else { kfd = open(keyfile, O_WRONLY | O_CREAT, 0644); if (kfd < 0) { fprintf(stderr, _("Cannot open keyfile %s\n"), keyfile); free(passphrase); retval = 1; goto bail_out; } } if (base64_transform || wrapped_keys) { cnt = bin_to_base64(keydata, sizeof(keydata), passphrase, length, true); if (write(kfd, keydata, cnt) != cnt) { fprintf(stderr, _("Failed to write %d bytes to keyfile %s\n"), cnt, keyfile); } } else { cnt = DEFAULT_PASSPHRASE_LENGTH; if (write(kfd, passphrase, cnt) != cnt) { fprintf(stderr, _("Failed to write %d bytes to keyfile %s\n"), cnt, keyfile); } } Dmsg1(10, "Keydata = %s\n", keydata); if (kfd > 1) { close(kfd); } else { write(kfd, "\n", 1); } free(passphrase); goto bail_out; } if (show_keydata) { char *passphrase; /* * Read the key bits from the keyfile. * - == stdin */ if (bstrcmp(keyfile, "-")) { kfd = 0; fprintf(stdout, _("Enter Encryption Key: ")); fflush(stdout); } else { kfd = open(keyfile, O_RDONLY); if (kfd < 0) { fprintf(stderr, _("Cannot open keyfile %s\n"), keyfile); retval = 1; goto bail_out; } } read(kfd, keydata, sizeof(keydata)); if (kfd > 0) { close(kfd); } strip_trailing_junk(keydata); Dmsg1(10, "Keydata = %s\n", keydata); /* * See if we need to unwrap the passphrase. */ if (wrapped_keys) { char *wrapped_passphrase; /* * A wrapped key is base64 encoded after it was wrapped so first * convert it from base64 to bin. As we first go from base64 to bin * and the base64_to_bin has a check if the decoded string will fit * we need to alocate some more bytes for the decoded buffer to be * sure it will fit. */ length = DEFAULT_PASSPHRASE_LENGTH + 12; wrapped_passphrase = (char *)malloc(length); memset(wrapped_passphrase, 0, length); if (base64_to_bin(wrapped_passphrase, length, keydata, strlen(keydata)) == 0) { fprintf(stderr, _("Failed to base64 decode the keydata read from %s, aborting...\n"), keyfile); free(wrapped_passphrase); goto bail_out; } length = DEFAULT_PASSPHRASE_LENGTH; passphrase = (char *)malloc(length); memset(passphrase, 0, length); if (aes_unwrap((unsigned char *)wrapdata, length / 8, (unsigned char *)wrapped_passphrase, (unsigned char *)passphrase) == -1) { fprintf(stderr, _("Failed to aes unwrap the keydata read from %s using the wrap data from %s, aborting...\n"), keyfile, wrap_keyfile); free(wrapped_passphrase); goto bail_out; } free(wrapped_passphrase); } else { if (base64_transform) { /* * As we first go from base64 to bin and the base64_to_bin has a check * if the decoded string will fit we need to alocate some more bytes * for the decoded buffer to be sure it will fit. */ length = DEFAULT_PASSPHRASE_LENGTH + 4; passphrase = (char *)malloc(length); memset(passphrase, 0, length); base64_to_bin(passphrase, length, keydata, strlen(keydata)); } else { length = DEFAULT_PASSPHRASE_LENGTH; passphrase = (char *)malloc(length); memset(passphrase, 0, length); bstrncpy(passphrase, keydata, length); } } Dmsg1(10, "Unwrapped passphrase = %s\n", passphrase); fprintf(stdout, "%s\n", passphrase); free(passphrase); goto bail_out; } /* * Clear the loaded encryption key of the given drive. */ if (clear_encryption) { if (clear_scsi_encryption_key(-1, argv[0])) { goto bail_out; } else { retval = 1; goto bail_out; } } /* * Get the drive encryption status of the given drive. */ if (drive_encryption_status) { POOLMEM *encryption_status = get_pool_memory(PM_MESSAGE); if (get_scsi_drive_encryption_status(-1, argv[0], encryption_status, 0)) { fprintf(stdout, "%s", encryption_status); free_pool_memory(encryption_status); } else { retval = 1; free_pool_memory(encryption_status); goto bail_out; } } /* * Load a new encryption key onto the given drive. */ if (set_encryption) { /* * Read the key bits from the keyfile. * - == stdin */ if (bstrcmp(keyfile, "-")) { kfd = 0; fprintf(stdout, _("Enter Encryption Key (close with ^D): ")); fflush(stdout); } else { kfd = open(keyfile, O_RDONLY); if (kfd < 0) { fprintf(stderr, _("Cannot open keyfile %s\n"), keyfile); retval = 1; goto bail_out; } } read(kfd, keydata, sizeof(keydata)); if (kfd > 0) { close(kfd); } strip_trailing_junk(keydata); if (set_scsi_encryption_key(-1, argv[0], keydata)) { goto bail_out; } else { retval = 1; goto bail_out; } } /* * Get the volume encryption status of volume currently loaded in the given drive. */ if (volume_encryption_status) { POOLMEM *encryption_status = get_pool_memory(PM_MESSAGE); if (get_scsi_volume_encryption_status(-1, argv[0], encryption_status, 0)) { fprintf(stdout, "%s", encryption_status); free_pool_memory(encryption_status); } else { retval = 1; free_pool_memory(encryption_status); goto bail_out; } } bail_out: if (cache_file) { free(cache_file); } if (keyfile) { free(keyfile); } if (wrap_keyfile) { free(wrap_keyfile); } exit(retval); } bareos-Release-14.2.6/src/tools/bsmtp.c000066400000000000000000000440461263011562700176700ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2001-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Derived from a SMTPclient: ======== Original copyrights ========== SMTPclient -- simple SMTP client Copyright (c) 1997 Ralf S. Engelschall, All rights reserved. This program is free software; it may be redistributed and/or modified only under the terms of either the Artistic License or the GNU General Public License, which may be found in the SMTP source distribution. Look at the file COPYING. 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 Affero General Public License for more details. ====================================================================== smtpclient_main.c -- program source Based on smtp.c as of August 11, 1995 from W.Z. Venema, Eindhoven University of Technology, Department of Mathematics and Computer Science, Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands. ========= Kern Sibbald, July 2001 Note, the original W.Z. Venema smtp.c had no license and no copyright. See: http://archives.neohapsis.com/archives/postfix/2000-05/1520.html */ #include "bareos.h" #include "jcr.h" #define MY_NAME "bsmtp" #if defined(HAVE_WIN32) #include #endif #ifndef MAXSTRING #define MAXSTRING 254 #endif enum resolv_type { RESOLV_PROTO_ANY, RESOLV_PROTO_IPV4, RESOLV_PROTO_IPV6 }; static FILE *sfp; static FILE *rfp; static char *from_addr = NULL; static char *cc_addr = NULL; static char *subject = NULL; static char *err_addr = NULL; static const char *mailhost = NULL; static char *reply_addr = NULL; static int mailport = 25; static char my_hostname[MAXSTRING]; static bool content_utf8 = false; static resolv_type default_resolv_type = RESOLV_PROTO_IPV4; /* * Take input that may have names and other stuff and strip * it down to the mail box address ... i.e. what is enclosed * in < >. Otherwise add < >. */ static char *cleanup_addr(char *addr, char *buf, int buf_len) { char *p, *q; if ((p = strchr(addr, '<')) == NULL) { snprintf(buf, buf_len, "<%s>", addr); } else { /* Copy */ for (q=buf; *p && *p!='>'; ) { *q++ = *p++; } if (*p) { *q++ = *p; } *q = 0; } Dmsg2(100, "cleanup in=%s out=%s\n", addr, buf); return buf; } /* * examine message from server */ static void get_response(void) { char buf[1000]; Dmsg0(50, "Calling fgets on read socket rfp.\n"); buf[3] = 0; while (fgets(buf, sizeof(buf), rfp)) { int len = strlen(buf); if (len > 0) { buf[len-1] = 0; } if (debug_level >= 10) { fprintf(stderr, "%s <-- %s\n", mailhost, buf); } Dmsg2(10, "%s --> %s\n", mailhost, buf); if (!isdigit((int)buf[0]) || buf[0] > '3') { Pmsg2(0, _("Fatal malformed reply from %s: %s\n"), mailhost, buf); exit(1); } if (buf[3] != '-') { break; } } if (ferror(rfp)) { fprintf(stderr, _("Fatal fgets error: ERR=%s\n"), strerror(errno)); } return; } /* * say something to server and check the response */ static void chat(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(sfp, fmt, ap); va_end(ap); if (debug_level >= 10) { fprintf(stdout, "%s --> ", my_hostname); va_start(ap, fmt); vfprintf(stdout, fmt, ap); va_end(ap); } fflush(sfp); if (debug_level >= 10) { fflush(stdout); } get_response(); } static void usage() { fprintf(stderr, _("\n" "Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n" " -4 forces bsmtp to use IPv4 addresses only.\n" #ifdef HAVE_IPV6 " -6 forces bsmtp to use IPv6 addresses only.\n" #endif " -8 set charset to UTF-8\n" " -a use any ip protocol for address resolution\n" " -c set the Cc: field\n" " -d set debug level to \n" " -dt print a timestamp in debug output\n" " -f set the From: field\n" " -h use mailhost:port as the SMTP server\n" " -s set the Subject: field\n" " -r set the Reply-To: field\n" " -l set the maximum number of lines to send (default: unlimited)\n" " -? print this message.\n" "\n"), MY_NAME); exit(1); } /* * Return the offset west from localtime to UTC in minutes * Same as timezone.tz_minuteswest * Unix tz_offset coded by: Attila Fülöp */ static long tz_offset(time_t lnow, struct tm &tm) { #if defined(HAVE_WIN32) #if defined(HAVE_MINGW) __MINGW_IMPORT long _dstbias; #endif #if defined(MINGW64) # define _tzset tzset #endif /* Win32 code */ long offset; _tzset(); offset = _timezone; if (tm.tm_isdst) { offset += _dstbias; } return offset /= 60; #else /* Unix/Linux code */ struct tm tm_utc; time_t now = lnow; (void)gmtime_r(&now, &tm_utc); tm_utc.tm_isdst = tm.tm_isdst; return (long)difftime(mktime(&tm_utc), now) / 60; #endif } static void get_date_string(char *buf, int buf_len) { time_t now = time(NULL); struct tm tm; char tzbuf[MAXSTRING]; long my_timezone; /* Add RFC822 date */ blocaltime(&now, &tm); my_timezone = tz_offset(now, tm); strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S", &tm); snprintf(tzbuf, sizeof(tzbuf), " %+2.2ld%2.2u", -my_timezone / 60, abs(my_timezone) % 60); strcat(buf, tzbuf); /* add +0100 */ strftime(tzbuf, sizeof(tzbuf), " (%Z)", &tm); strcat(buf, tzbuf); /* add (CEST) */ } /********************************************************************* * * Program to send email */ int main (int argc, char *argv[]) { char buf[1000]; int i, ch; unsigned long maxlines, lines; #if defined(HAVE_WIN32) SOCKET s; #else int s, r; struct passwd *pwd; #endif char *cp, *p; #ifdef HAVE_GETADDRINFO int res; struct addrinfo hints; struct addrinfo *ai, *rp; char mail_port[10]; #else struct hostent *hp; struct sockaddr_in sin; #endif #ifdef HAVE_IPV6 const char *options = "468ac:d:f:h:r:s:l:?"; #else const char *options = "48ac:d:f:h:r:s:l:?"; #endif setlocale(LC_ALL, "en_US"); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); my_name_is(argc, argv, "bsmtp"); maxlines = 0; while ((ch = getopt(argc, argv, options)) != -1) { switch (ch) { case '4': default_resolv_type = RESOLV_PROTO_IPV4; break; #ifdef HAVE_IPV6 case '6': default_resolv_type = RESOLV_PROTO_IPV6; break; #endif case '8': content_utf8 = true; break; case 'a': default_resolv_type = RESOLV_PROTO_ANY; break; case 'c': Dmsg1(20, "cc=%s\n", optarg); cc_addr = optarg; break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } Dmsg1(20, "Debug level = %d\n", debug_level); break; case 'f': /* from */ from_addr = optarg; break; case 'h': /* smtp host */ Dmsg1(20, "host=%s\n", optarg); p = strchr(optarg, ':'); if (p) { *p++ = 0; mailport = atoi(p); } mailhost = optarg; break; case 's': /* subject */ Dmsg1(20, "subject=%s\n", optarg); subject = optarg; break; case 'r': /* reply address */ reply_addr = optarg; break; case 'l': Dmsg1(20, "maxlines=%s\n", optarg); maxlines = (unsigned long) atol(optarg); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < 1) { Pmsg0(0, _("Fatal error: no recipient given.\n")); usage(); exit(1); } /* * Determine SMTP server */ if (mailhost == NULL) { if ((cp = getenv("SMTPSERVER")) != NULL) { mailhost = cp; } else { mailhost = "localhost"; } } #if defined(HAVE_WIN32) WSADATA wsaData; _setmode(0, _O_BINARY); WSAStartup(MAKEWORD(2,2), &wsaData); #endif /* * Find out my own host name for HELO; * if possible, get the fully qualified domain name */ if (gethostname(my_hostname, sizeof(my_hostname) - 1) < 0) { Pmsg1(0, _("Fatal gethostname error: ERR=%s\n"), strerror(errno)); exit(1); } #ifdef HAVE_GETADDRINFO memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = 0; hints.ai_protocol = 0; hints.ai_flags = AI_CANONNAME; if ((res = getaddrinfo(my_hostname, NULL, &hints, &ai)) != 0) { Pmsg2(0, _("Fatal getaddrinfo for myself failed \"%s\": ERR=%s\n"), my_hostname, gai_strerror(res)); exit(1); } strncpy(my_hostname, ai->ai_canonname, sizeof(my_hostname) - 1); my_hostname[sizeof(my_hostname) - 1] = '\0'; freeaddrinfo(ai); #else if ((hp = gethostbyname(my_hostname)) == NULL) { Pmsg2(0, _("Fatal gethostbyname for myself failed \"%s\": ERR=%s\n"), my_hostname, strerror(errno)); exit(1); } strncpy(my_hostname, hp->h_name, sizeof(my_hostname) - 1); my_hostname[sizeof(my_hostname) - 1] = '\0'; #endif Dmsg1(20, "My hostname is: %s\n", my_hostname); /* * Determine from address. */ if (from_addr == NULL) { #if defined(HAVE_WIN32) DWORD dwSize = UNLEN + 1; LPSTR lpszBuffer = (LPSTR)alloca(dwSize); if (GetUserName(lpszBuffer, &dwSize)) { snprintf(buf, sizeof(buf), "%s@%s", lpszBuffer, my_hostname); } else { snprintf(buf, sizeof(buf), "unknown-user@%s", my_hostname); } #else if ((pwd = getpwuid(getuid())) == 0) { snprintf(buf, sizeof(buf), "userid-%d@%s", (int)getuid(), my_hostname); } else { snprintf(buf, sizeof(buf), "%s@%s", pwd->pw_name, my_hostname); } #endif from_addr = bstrdup(buf); } Dmsg1(20, "From addr=%s\n", from_addr); /* * Connect to smtp daemon on mailhost. */ lookup_host: #ifdef HAVE_GETADDRINFO memset(&hints, 0, sizeof(struct addrinfo)); switch (default_resolv_type) { case RESOLV_PROTO_ANY: hints.ai_family = AF_UNSPEC; break; case RESOLV_PROTO_IPV4: hints.ai_family = AF_INET; break; #ifdef HAVE_IPV6 case RESOLV_PROTO_IPV6: hints.ai_family = AF_INET6; break; #endif default: hints.ai_family = AF_UNSPEC; break; } hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; hints.ai_flags = 0; snprintf(mail_port, sizeof(mail_port), "%d", mailport); if ((res = getaddrinfo(mailhost, mail_port, &hints, &ai)) != 0) { Pmsg2(0, _("Error unknown mail host \"%s\": ERR=%s\n"), mailhost, gai_strerror(res)); if (!bstrcasecmp(mailhost, "localhost")) { Pmsg0(0, _("Retrying connection using \"localhost\".\n")); mailhost = "localhost"; goto lookup_host; } exit(1); } for (rp = ai; rp != NULL; rp = rp->ai_next) { #if defined(HAVE_WIN32) s = WSASocket(rp->ai_family, rp->ai_socktype, rp->ai_protocol, NULL, 0, 0); #else s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); #endif if (s < 0) { continue; } if (connect(s, rp->ai_addr, rp->ai_addrlen) != -1) { break; } close(s); } if (!rp) { Pmsg1(0, _("Failed to connect to mailhost %s\n"), mailhost); exit(1); } freeaddrinfo(ai); #else if ((hp = gethostbyname(mailhost)) == NULL) { Pmsg2(0, _("Error unknown mail host \"%s\": ERR=%s\n"), mailhost, strerror(errno)); if (!bstrcasecmp(mailhost, "localhost")) { Pmsg0(0, _("Retrying connection using \"localhost\".\n")); mailhost = "localhost"; goto lookup_host; } exit(1); } if (hp->h_addrtype != AF_INET) { Pmsg1(0, _("Fatal error: Unknown address family for smtp host: %d\n"), hp->h_addrtype); exit(1); } memset((char *)&sin, 0, sizeof(sin)); memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length); sin.sin_family = hp->h_addrtype; sin.sin_port = htons(mailport); #if defined(HAVE_WIN32) if ((s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0)) < 0) { Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno)); exit(1); } #else if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno)); exit(1); } #endif if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { Pmsg2(0, _("Fatal connect error to %s: ERR=%s\n"), mailhost, strerror(errno)); exit(1); } Dmsg0(20, "Connected\n"); #endif #if defined(HAVE_WIN32) int fdSocket = _open_osfhandle(s, _O_RDWR | _O_BINARY); if (fdSocket == -1) { Pmsg1(0, _("Fatal _open_osfhandle error: ERR=%s\n"), strerror(errno)); exit(1); } int fdSocket2 = dup(fdSocket); if ((sfp = fdopen(fdSocket, "wb")) == NULL) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } if ((rfp = fdopen(fdSocket2, "rb")) == NULL) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } #else if ((r = dup(s)) < 0) { Pmsg1(0, _("Fatal dup error: ERR=%s\n"), strerror(errno)); exit(1); } if ((sfp = fdopen(s, "w")) == 0) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } if ((rfp = fdopen(r, "r")) == 0) { Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } #endif /* * Send SMTP headers. Note, if any of the strings have a < * in them already, we do not enclose the string in < >, otherwise * we do. */ get_response(); /* banner */ chat("HELO %s\r\n", my_hostname); chat("MAIL FROM:%s\r\n", cleanup_addr(from_addr, buf, sizeof(buf))); for (i = 0; i < argc; i++) { Dmsg1(20, "rcpt to: %s\n", argv[i]); chat("RCPT TO:%s\r\n", cleanup_addr(argv[i], buf, sizeof(buf))); } if (cc_addr) { chat("RCPT TO:%s\r\n", cleanup_addr(cc_addr, buf, sizeof(buf))); } Dmsg0(20, "Data\n"); chat("DATA\r\n"); /* * Send message header */ fprintf(sfp, "From: %s\r\n", from_addr); Dmsg1(10, "From: %s\r\n", from_addr); if (subject) { fprintf(sfp, "Subject: %s\r\n", subject); Dmsg1(10, "Subject: %s\r\n", subject); } if (reply_addr) { fprintf(sfp, "Reply-To: %s\r\n", reply_addr); Dmsg1(10, "Reply-To: %s\r\n", reply_addr); } if (err_addr) { fprintf(sfp, "Errors-To: %s\r\n", err_addr); Dmsg1(10, "Errors-To: %s\r\n", err_addr); } #if defined(HAVE_WIN32) DWORD dwSize = UNLEN + 1; LPSTR lpszBuffer = (LPSTR)alloca(dwSize); if (GetUserName(lpszBuffer, &dwSize)) { fprintf(sfp, "Sender: %s@%s\r\n", lpszBuffer, my_hostname); Dmsg2(10, "Sender: %s@%s\r\n", lpszBuffer, my_hostname); } else { fprintf(sfp, "Sender: unknown-user@%s\r\n", my_hostname); Dmsg1(10, "Sender: unknown-user@%s\r\n", my_hostname); } #else if ((pwd = getpwuid(getuid())) == 0) { fprintf(sfp, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname); Dmsg2(10, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname); } else { fprintf(sfp, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname); Dmsg2(10, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname); } #endif fprintf(sfp, "To: %s", argv[0]); Dmsg1(10, "To: %s", argv[0]); for (i = 1; i < argc; i++) { fprintf(sfp, ",%s", argv[i]); Dmsg1(10, ",%s", argv[i]); } fprintf(sfp, "\r\n"); Dmsg0(10, "\r\n"); if (cc_addr) { fprintf(sfp, "Cc: %s\r\n", cc_addr); Dmsg1(10, "Cc: %s\r\n", cc_addr); } if (content_utf8) { fprintf(sfp, "Content-Type: text/plain; charset=UTF-8\r\n"); Dmsg0(10, "Content-Type: text/plain; charset=UTF-8\r\n"); } get_date_string(buf, sizeof(buf)); fprintf(sfp, "Date: %s\r\n", buf); Dmsg1(10, "Date: %s\r\n", buf); fprintf(sfp, "\r\n"); /* * Send message body */ lines = 0; while (fgets(buf, sizeof(buf), stdin)) { if (maxlines > 0 && ++lines > maxlines) { Dmsg1(20, "skip line because of maxlines limit: %lu\n", maxlines); while (fgets(buf, sizeof(buf), stdin)) { ++lines; } break; } buf[sizeof(buf)-1] = '\0'; buf[strlen(buf)-1] = '\0'; if (buf[0] == '.') { /* add extra . see RFC 2821 4.5.2 */ fputs(".", sfp); } fputs(buf, sfp); fputs("\r\n", sfp); } if (lines > maxlines) { Dmsg1(10, "hit maxlines limit: %lu\n", maxlines); fprintf(sfp, "\r\n\r\n[maximum of %lu lines exceeded, skipped %lu lines of output]\r\n", maxlines, lines-maxlines); } /* * Send SMTP quit command */ chat(".\r\n"); chat("QUIT\r\n"); /* * Go away gracefully ... */ exit(0); } bareos-Release-14.2.6/src/tools/bwild.c000066400000000000000000000062311263011562700176360ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Test program for testing wild card expressions * * Kern Sibbald, MMVI */ #include "bareos.h" #include "lib/fnmatch.h" static void usage() { fprintf(stderr, "\n" "Usage: bwild [-d debug_level] -f \n" " -f specify file of data to be matched\n" " -i use case insenitive match\n" " -l suppress line numbers\n" " -n print lines that do not match\n" " -? print this message.\n" "\n\n"); exit(1); } int main(int argc, char *const *argv) { char *fname = NULL; int rc, ch; char data[1000]; char pat[500]; FILE *fd; bool match_only = true; int lineno; bool no_linenos = false; int ic = 0; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); while ((ch = getopt(argc, argv, "d:f:in?")) != -1) { switch (ch) { case 'd': /* set debug level */ debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } break; case 'f': /* data */ fname = optarg; break; case 'i': /* ignore case */ ic = FNM_CASEFOLD; break; case 'l': no_linenos = true; break; case 'n': match_only = false; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (!fname) { printf("A data file must be specified.\n"); usage(); } OSDependentInit(); for ( ;; ) { printf("Enter a wild-card: "); if (fgets(pat, sizeof(pat)-1, stdin) == NULL) { break; } strip_trailing_newline(pat); if (pat[0] == 0) { exit(0); } fd = fopen(fname, "r"); if (!fd) { printf(_("Could not open data file: %s\n"), fname); exit(1); } lineno = 0; while (fgets(data, sizeof(data)-1, fd)) { strip_trailing_newline(data); lineno++; rc = fnmatch(pat, data, ic); if ((match_only && rc == 0) || (!match_only && rc != 0)) { if (no_linenos) { printf("%s\n", data); } else { printf("%5d: %s\n", lineno, data); } } } fclose(fd); } exit(0); } bareos-Release-14.2.6/src/tools/drivetype.c000066400000000000000000000060301263011562700205450ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program for determining drive type * * Written by Robert Nelson, June 2006 */ #include "bareos.h" #include "findlib/find.h" static void usage() { fprintf(stderr, _( "\n" "Usage: drivetype [-v] path ...\n" "\n" " Print the drive type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -l print local fixed hard drive\n" " -a display information on all drives\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n")); exit(1); } int display_drive(char *drive, bool display_local, int verbose) { char dt[100]; int status = 0; if (drivetype(drive, dt, sizeof(dt))) { if (display_local) { /* in local mode, display only harddrive */ if (bstrcmp(dt, "fixed")) { printf("%s\n", drive); } } else if (verbose) { printf("%s: %s\n", drive, dt); } else { puts(dt); } } else if (!display_local) { /* local mode is used by FileSet scripts */ fprintf(stderr, _("%s: unknown\n"), drive); status = 1; } return status; } int main (int argc, char *const *argv) { int verbose = 0; int status = 0; int ch, i; bool display_local = false; bool display_all = false; char drive='A'; char buf[16]; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); while ((ch = getopt(argc, argv, "alv?")) != -1) { switch (ch) { case 'v': verbose = 1; break; case 'l': display_local = true; break; case 'a': display_all = true; break; case '?': default: usage(); } } argc -= optind; argv += optind; OSDependentInit(); if (argc < 1 && display_all) { /* Try all letters */ for (drive = 'A'; drive <= 'Z'; drive++) { bsnprintf(buf, sizeof(buf), "%c:/", drive); display_drive(buf, display_local, verbose); } exit(status); } if (argc < 1) { usage(); } for (i = 0; i < argc; --argc, ++argv) { status += display_drive(*argv, display_local, verbose); } exit(status); } bareos-Release-14.2.6/src/tools/fstype.c000066400000000000000000000042501263011562700200460ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2006 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Program for determining file system type * * Written by Preben 'Peppe' Guldberg, December MMIV */ #include "bareos.h" #include "findlib/find.h" #include "lib/mntent_cache.h" static void usage() { fprintf(stderr, _( "\n" "Usage: fstype [-v] path ...\n" "\n" " Print the file system type a given file/directory is on.\n" " The following options are supported:\n" "\n" " -v print both path and file system type.\n" " -? print this message.\n" "\n")); exit(1); } int main (int argc, char *const *argv) { char fs[1000]; int verbose = 0; int status = 0; int ch, i; setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); while ((ch = getopt(argc, argv, "v?")) != -1) { switch (ch) { case 'v': verbose = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < 1) { usage(); } OSDependentInit(); for (i = 0; i < argc; --argc, ++argv) { if (fstype(*argv, fs, sizeof(fs))) { if (verbose) { printf("%s: %s\n", *argv, fs); } else { puts(fs); } } else { fprintf(stderr, _("%s: unknown\n"), *argv); status = 1; } } flush_mntent_cache(); exit(status); } bareos-Release-14.2.6/src/tools/smtp-orig.c000066400000000000000000000302121263011562700204520ustar00rootroot00000000000000/* Subject: Re: send mail from chrooted Apache From: Wietse Venema (wietseporcupine.org) Date: Tue Jun 06 2000 - 07:43:31 CDT Next message: Wietse Venema: "Re: -" Previous message: Brad Knowles: "Re: performance issues" In reply to: ISM Kolemanov, Ivan: "send mail from chrooted Apache" ISM Kolemanov, Ivan: > hi all, > > I've just prepared Apache Web Server in chroot env. > but now I have a problem, I can't send mails from the web server > I mean that on the web server I have some formulars, > which my clients are using to send me mail. > > I guess that there is any solution for that, but up to now I didn't find it. > If anybody knows it please respond. > > 10x in advance > Ivan Kolemanov This is a quick-and-dirty stand-alone SMTP client from long ago. Works OK for lines up to BUFSIZ characters, nothing to worry about security-wise. You could probably do the same in PERL, but I wrote this for a web server that allowed no programming languages inside the jail. Wietse */ /*++ /* NAME /* smtp 1 /* SUMMARY /* simple smtp client /* SYNOPSIS /* smtp [options] recipient(s)... /* DESCRIPTION /* \fIsmtp\fP is a minimal smtp client that takes an email /* message body and passes it on to an smtp daemon (default /* the smtp daemon on the local host). Since it is /* completely self-supporting, the smtp client is especially /* suitable for use in restricted environments. /* /* Options: /* .TP /* -c carbon-copy /* Specifies one Cc: address to send one copy of the message to. /* .TP /* -e errors-to /* Specifies the Errors-To: address. This is where delivery /* problems should be reported. /* .TP /* -f from /* Sets the From: address. Default is "daemon", which is /* probably wrong. /* .TP /* -m mailhost /* Specifies where the mail should be posted. By default, the /* mail is posted to the smtp daemon on \fIlocalhost\fR. /* .TP /* -M /* Use MIME-style translation to quoted-printable (base 16). /* .TP /* -r reply-to /* Sets the Reply-To: address. /* .TP /* -s subject /* Specifies the message subject. /* .TP /* -v /* Turn on verbose logging to stdout. /* DIAGNOSTICS /* Non-zero exit status in case of problems. Errors are reported /* to the syslogd, with facility daemon. /* AUTHOR(S) /* W.Z. Venema /* Eindhoven University of Technology /* Department of Mathematics and Computer Science /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands /* CREATION DATE /* Wed Dec 1 14:51:13 MET 1993 /* LAST UPDATE /* Fri Aug 11 12:29:23 MET DST 1995 /*--*/ /* System libraries */ #include #include #include #include #include #include #include #include #include #ifdef __STDC__ #include #define VARARGS(func,arg,type) func(type arg, ...) #define VASTART(ap,name,type) { va_start(ap, name) #define VAEND(ap) va_end(ap); } #else #include #define VARARGS(func,arg,type) func(va_alist) \ va_dcl #define VASTART(ap,name,type) { type name; \ va_start(ap); \ name = va_arg(ap, type) #define VAEND(ap) va_end(ap); } #endif /* __STDC__ */ extern int optind; extern char *optarg; /* Local stuff */ static char *cc_addr = 0; static char *err_addr = 0; static char *from_addr = "daemon"; static char *mailhost = "localhost"; static char *reply_addr = 0; static char *subject = 0; static int mime_style = 0; static int verbose = 0; static FILE *sfp; static FILE *rfp; #define dprintf if (verbose) printf #define dvprintf if (verbose) vprintf void toqp(); /* usage - explain and bail out */ void usage() { syslog(LOG_ERR, "usage: smtp [-c cc] [-e errors-to] [-f from] [-m mailhost] [-M] [-r reply-to] [-s subject] [-v] recipents..\n"); exit(1); } /* get_response - examine message from server */ void get_response() { char buf[BUFSIZ]; while (fgets(buf, sizeof(buf), rfp)) { buf[strlen(buf) - 1] = 0; dprintf(">>>> %s\n", buf); if (!isdigit(buf[0]) || buf[0] > '3') { syslog(LOG_ERR, "unexpected reply: %s", buf); exit(1); } if (buf[4] != '-') break; } } /* chat - say something to server and check the response */ void VARARGS(chat, fmt, char *) { va_list ap; /* Format the message. */ VASTART(ap, fmt, char *); vfprintf(sfp, fmt, ap); VAEND(ap); VASTART(ap, fmt, char *); dvprintf(fmt, ap); VAEND(ap); /* Send message to server and parse its response. */ fflush(sfp); get_response(); } main(argc, argv) int argc; char **argv; { char buf[BUFSIZ]; char my_name[BUFSIZ]; struct sockaddr_in sin; struct hostent *hp; struct servent *sp; int c; int s; int r; int i; struct passwd *pwd; openlog(argv[0], LOG_PID, LOG_DAEMON); /* Go away when something gets stuck. */ alarm(60); /* Parse JCL. */ while ((c = getopt(argc, argv, "c:e:f:m:Mr:s:v")) != EOF) { switch (c) { case 'c': /* carbon copy */ cc_addr = optarg; break; case 'e': /* errors-to */ err_addr = optarg; break; case 'f': /* originator */ from_addr = optarg; break; case 'm': /* mailhost */ mailhost = optarg; break; case 'M': /* MIME quoted printable */ mime_style = 1; break; case 'r': /* reply-to */ reply_addr = optarg; break; case 's': /* subject */ subject = optarg; break; case 'v': /* log protocol */ verbose = 1; break; default: usage(); /* NOTREACHED */ } } if (argc == optind) usage(); /* Find out my own host name for HELO; if possible, get the FQDN. */ if (gethostname(my_name, sizeof(my_name) - 1) < 0) { syslog(LOG_ERR, "gethostname: %m"); exit(1); } if ((hp = gethostbyname(my_name)) == 0) { syslog(LOG_ERR, "%s: unknown host\n", my_name); exit(1); } strncpy(my_name, hp->h_name, sizeof(my_name) - 1); /* Connect to smtp daemon on mailhost. */ if ((hp = gethostbyname(mailhost)) == 0) { syslog(LOG_ERR, "%s: unknown host\n", mailhost); exit(1); } if (hp->h_addrtype != AF_INET) { syslog(LOG_ERR, "unknown address family: %d", hp->h_addrtype); exit(1); } memset((char *) &sin, 0, sizeof(sin)); memcpy((char *) &sin.sin_addr, hp->h_addr, hp->h_length); sin.sin_family = hp->h_addrtype; if ((sp = getservbyname("smtp", "tcp")) != 0) { sin.sin_port = sp->s_port; } else { syslog(LOG_ERR, "smtp/tcp: unknown service"); exit(1); } if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) < 0) { syslog(LOG_ERR, "connect: %m"); exit(1); } if ((r = dup(s)) < 0) { syslog(LOG_ERR, "dup: %m"); exit(1); } if ((sfp = fdopen(s, "w")) == 0) { syslog(LOG_ERR, "fdopen: %m"); exit(1); } if ((rfp = fdopen(r, "r")) == 0) { syslog(LOG_ERR, "fdopen: %m"); exit(1); } /* Speak SMTP. */ get_response(); /* banner */ chat("HELO %s\r\n", my_name); chat("MAIL FROM: <%s>\r\n", from_addr); for (i = optind; i < argc; i++) chat("RCPT TO: <%s>\r\n", argv[i]); if (cc_addr) chat("RCPT TO: <%s>\r\n", cc_addr); chat("DATA\r\n"); /* Do message header. */ fprintf(sfp, "From: %s\r\n", from_addr); if (subject) fprintf(sfp, "Subject: %s\r\n", subject); if (err_addr) fprintf(sfp, "Errors-To: %s\r\n", err_addr); if (reply_addr) fprintf(sfp, "Reply-To: %s\r\n", reply_addr); if ((pwd = getpwuid(getuid())) == 0) { fprintf(sfp, "Sender: userid-%d%s\r\n", getuid(), my_name); } else { fprintf(sfp, "Sender: %s%s\r\n", pwd->pw_name, my_name); } fprintf(sfp, "To: %s", argv[optind]); for (i = optind + 1; i < argc; i++) fprintf(sfp, ", %s", argv[i]); fprintf(sfp, "\r\n"); if (cc_addr) fprintf(sfp, "Cc: %s\r\n", cc_addr); if (mime_style) { fprintf(sfp, "Mime-Version: 1.0\r\n"); fprintf(sfp, "Content-Type: text/plain; charset=ISO-8859-1\r\n"); fprintf(sfp, "Content-Transfer-Encoding: quoted-printable\r\n"); } fprintf(sfp, "\r\n"); /* Do message body. */ if (mime_style) { /* MIME quoted-printable */ toqp(stdin, sfp); } else { /* traditional... */ while (fgets(buf, sizeof(buf), stdin)) { buf[strlen(buf) - 1] = 0; if (strcmp(buf, ".") == 0) { /* quote lone dots */ fprintf(sfp, "..\r\n"); } else { /* pass thru mode */ fprintf(sfp, "%s\r\n", buf); } } } chat(".\r\n"); chat("QUIT\r\n"); exit(0); } /* * Following code was lifted from the metamail version 2.7 source code * (codes.c) and modified to emit \r\n at line boundaries. */ static char basis_hex[] = "0123456789ABCDEF"; /* toqp - transform to MIME-style quoted printable */ void toqp(infile, outfile) FILE *infile, *outfile; { int c, ct = 0, prevc = 255; while ((c = getc(infile)) != EOF) { if ((c < 32 && (c != '\n' && c != '\t')) || (c == '=') || (c >= 127) /* * Following line is to avoid single periods alone on lines, which * messes up some dumb smtp implementations, sigh... */ || (ct == 0 && c == '.')) { putc('=', outfile); putc(basis_hex[c >> 4], outfile); putc(basis_hex[c & 0xF], outfile); ct += 3; prevc = 'A'; /* close enough */ } else if (c == '\n') { if (prevc == ' ' || prevc == '\t') { putc('=', outfile); /* soft & hard lines */ putc(c, outfile); } putc(c, outfile); ct = 0; prevc = c; } else { if (c == 'F' && prevc == '\n') { /* * HORRIBLE but clever hack suggested by MTR for * sendmail-avoidance */ c = getc(infile); if (c == 'r') { c = getc(infile); if (c == 'o') { c = getc(infile); if (c == 'm') { c = getc(infile); if (c == ' ') { /* This is the case we are looking for */ fputs("=46rom", outfile); ct += 6; } else { fputs("From", outfile); ct += 4; } } else { fputs("Fro", outfile); ct += 3; } } else { fputs("Fr", outfile); ct += 2; } } else { putc('F', outfile); ++ct; } ungetc(c, infile); prevc = 'x'; /* close enough -- printable */ } else { /* END horrible hack */ putc(c, outfile); ++ct; prevc = c; } } if (ct > 72) { putc('=', outfile); putc('\r', outfile); /* XXX */ putc('\n', outfile); ct = 0; prevc = '\n'; } } if (ct) { putc('=', outfile); putc('\r', outfile); /* XXX */ putc('\n', outfile); } } bareos-Release-14.2.6/src/tools/timelimit.1000066400000000000000000000137231263011562700204540ustar00rootroot00000000000000.\" Copyright (c) 2001, 2007 - 2010 Peter Pentchev .\" 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 AUTHOR 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 AUTHOR 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. .\" .\" $Ringlet$ .\" .Dd September 29, 2010 .Dt TIMELIMIT 1 .Os .Sh NAME .Nm timelimit .Nd effectively limit the absolute execution time of a process .Sh SYNOPSIS .Nm .Op Fl pq .Op Fl S Ar killsig .Op Fl s Ar warnsig .Op Fl T Ar killtime .Op Fl t Ar warntime .Ar command .Op Ar arguments ... .Sh DESCRIPTION The .Nm utility executes a given .Ar command with the supplied .Ar arguments and terminates the spawned process after a given time with a given signal. If the process exits before the time limit has elapsed, .Nm will silently exit, too. .Pp Options: .Bl -tag -width indent .It Fl p If the child process is terminated by a signal, .Nm propagates this condition, i.e. sends the same signal to itself. This allows the program executing .Nm to determine whether the child process was terminated by a signal or actually exited with an exit code larger than 128. .It Fl q Quiet operation - .Nm does not output diagnostic messages about signals sent to the child process. .It Fl S Ar killsig Specify the number of the signal to be sent to the process .Ar killtime seconds after .Ar warntime has expired. Defaults to 9 (SIGKILL). .It Fl s Ar warnsig Specify the number of the signal to be sent to the process .Ar warntime seconds after it has been started. Defaults to 15 (SIGTERM). .It Fl T Ar killtime Specify the maximum execution time of the process before sending .Ar killsig after .Ar warnsig has been sent. Defaults to 120 seconds. .It Fl t Ar warntime Specify the maximum execution time of the process in seconds before sending .Ar warnsig . Defaults to 3600 seconds. .El .Pp On systems that support the .Xr setitimer 2 system call, the .Ar warntime and .Ar killtime values may be specified in fractional seconds with microsecond precision. .Sh ENVIRONMENT .Bl -tag -width indent .It Ev KILLSIG The .Ar killsig to use if the .Fl S option was not specified. .It Ev KILLTIME The .Ar killtime to use if the .Fl T option was not specified. .It Ev WARNSIG The .Ar warnsig to use if the .Fl s option was not specified. .It Ev WARNTIME The .Ar warntime to use if the .Fl t option was not specified. .El .Sh EXIT STATUS If the child process exits normally, the .Nm utility will pass its exit code on up. If the child process is terminated by a signal and the .Fl p flag was not specified, the .Nm utility's exit status is 128 plus the signal number, similar to .Xr sh 1 . If the .Fl p flag was specified, the .Nm utility will raise the signal itself so that its own parent process may in turn reliably distinguish between a signal and a larger than 128 exit code. .Pp In rare cases, the .Nm utility may encounter a system or user error; then, its exit status is one of the standard .Xr sysexits 3 values: .Bl -tag -width indent .It Dv EX_USAGE The command-line parameters and options were incorrectly specified. .It Dv EX_SOFTWARE The .Nm utility itself received an unexpected signal while waiting for the child process to terminate. .It Dv EX_OSERR The .Nm utility was unable to execute the child process, wait for it to terminate, or examine its exit status. .El .Sh EXAMPLES .Pp The following examples are shown as given to the shell: .Pp .Dl timelimit -p /usr/local/bin/rsync rsync://some.host/dir /opt/mirror .Pp Run the rsync program to mirror a WWW or FTP site and kill it if it runs longer than 1 hour (that is 3600 seconds) with SIGTERM. If the rsync process does not exit after receiving the SIGTERM, .Nm issues a SIGKILL 120 seconds after the SIGTERM. If the rsync process is terminated by a signal, .Nm will itself raise this signal. .Pp .Dl tcpserver 0 8888 timelimit -t600 -T300 /opt/services/chat/stats .Pp Start a .Xr tcpserver n process listening on tcp port 8888; each client connection shall invoke an instance of an IRC statistics tool under .Pa /opt/services/chat and kill it after 600 seconds have elapsed. If the stats process is still running after the SIGTERM, it will be killed by a SIGKILL sent 300 seconds later. .Pp .Dl env WARNTIME=4.99 WARNSIG=1 KILLTIME=1.000001 timelimit sh stats.sh .Pp Start a shell script and kill it with a SIGHUP in a little under 5 seconds. If the shell gets stuck and does not respond to the SIGHUP, kill it with the default SIGKILL just a bit over a second afterwards. .Sh SEE ALSO .Xr kill 1 , .Xr rsync 1 , .Xr signal 3 , .Xr tcpserver n .Sh STANDARDS No standards documentation was harmed in the process of creating .Nm . .Sh BUGS Please report any bugs in .Nm to the author. .Sh AUTHOR The .Nm utility was conceived and written by .An Peter Pentchev Aq roam@ringlet.net with contributions and suggestions by .An Karsten W Rohrbach Aq karsten@rohrbach.de , .An Teddy Hogeborn Aq teddy@fukt.bsnet.se , and .An Tomasz Nowak Aq nowak2000@poczta.onet.pl . bareos-Release-14.2.6/src/tools/timelimit.c000066400000000000000000000362431263011562700205400ustar00rootroot00000000000000/*- * Copyright (c) 2001, 2007 - 2010 Peter Pentchev * 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 AUTHOR 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 AUTHOR 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. */ /* we hope all OS's have those..*/ #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ERR #include #endif /* HAVE_ERR */ #ifdef HAVE_SYSEXITS_H #include #else #define EX_OK 0 /* successful termination */ #define EX__BASE 64 /* base value for error messages */ #define EX_USAGE 64 /* command line usage error */ #define EX_DATAERR 65 /* data format error */ #define EX_NOINPUT 66 /* cannot open input */ #define EX_NOUSER 67 /* addressee unknown */ #define EX_NOHOST 68 /* host name unknown */ #define EX_UNAVAILABLE 69 /* service unavailable */ #define EX_SOFTWARE 70 /* internal software error */ #define EX_OSERR 71 /* system error (e.g., can't fork) */ #define EX_OSFILE 72 /* critical OS file missing */ #define EX_CANTCREAT 73 /* can't create (user) output file */ #define EX_IOERR 74 /* input/output error */ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ #define EX_PROTOCOL 76 /* remote error in protocol */ #define EX_NOPERM 77 /* permission denied */ #define EX_CONFIG 78 /* configuration error */ #define EX__MAX 78 /* maximum listed value */ #endif /* HAVE_SYSEXITS_H */ #ifndef __unused #ifdef __GNUC__ #define __unused __attribute__((unused)) #else /* __GNUC__ */ #define __unused #endif /* __GNUC__ */ #endif /* __unused */ #ifndef __dead2 #ifdef __GNUC__ #define __dead2 __attribute__((noreturn)) #else /* __GNUC__ */ #define __dead2 #endif /* __GNUC__ */ #endif /* __dead2 */ #define PARSE_CMDLINE unsigned long warntime, warnmsec, killtime, killmsec; unsigned long warnsig, killsig; volatile int fdone, falarm, fsig, sigcaught; int propagate, quiet; static struct { const char *name, opt, issig; unsigned long *sec, *msec; } envopts[] = { {"KILLSIG", 'S', 1, &killsig, NULL}, {"KILLTIME", 'T', 0, &killtime, &killmsec}, {"WARNSIG", 's', 1, &warnsig, NULL}, {"WARNTIME", 't', 0, &warntime, &warnmsec}, {NULL, 0, 0, NULL, NULL} }; static struct { const char *name; int num; } signals[] = { /* We kind of assume that the POSIX-mandated signals are present */ {"ABRT", SIGABRT}, {"ALRM", SIGALRM}, {"BUS", SIGBUS}, {"CHLD", SIGCHLD}, {"CONT", SIGCONT}, {"FPE", SIGFPE}, {"HUP", SIGHUP}, {"ILL", SIGILL}, {"INT", SIGINT}, {"KILL", SIGKILL}, {"PIPE", SIGPIPE}, {"QUIT", SIGQUIT}, {"SEGV", SIGSEGV}, {"STOP", SIGSTOP}, {"TERM", SIGTERM}, {"TSTP", SIGTSTP}, {"TTIN", SIGTTIN}, {"TTOU", SIGTTOU}, {"USR1", SIGUSR1}, {"USR2", SIGUSR2}, {"PROF", SIGPROF}, {"SYS", SIGSYS}, {"TRAP", SIGTRAP}, {"URG", SIGURG}, {"VTALRM", SIGVTALRM}, {"XCPU", SIGXCPU}, {"XFSZ", SIGXFSZ}, /* Some more signals found on a Linux 2.6 system */ #ifdef SIGIO {"IO", SIGIO}, #endif #ifdef SIGIOT {"IOT", SIGIOT}, #endif #ifdef SIGLOST {"LOST", SIGLOST}, #endif #ifdef SIGPOLL {"POLL", SIGPOLL}, #endif #ifdef SIGPWR {"PWR", SIGPWR}, #endif #ifdef SIGSTKFLT {"STKFLT", SIGSTKFLT}, #endif #ifdef SIGWINCH {"WINCH", SIGWINCH}, #endif /* Some more signals found on a FreeBSD 8.x system */ #ifdef SIGEMT {"EMT", SIGEMT}, #endif #ifdef SIGINFO {"INFO", SIGINFO}, #endif #ifdef SIGLWP {"LWP", SIGLWP}, #endif #ifdef SIGTHR {"THR", SIGTHR}, #endif }; #define SIGNALS (sizeof(signals) / sizeof(signals[0])) #ifndef HAVE_ERR static void err(int, const char *, ...); static void errx(int, const char *, ...); #endif /* !HAVE_ERR */ static void usage(void); static void init(int, char *[]); static pid_t doit(char *[]); static void child(char *[]); static void raisesignal(int) __dead2; static void setsig_fatal(int, void (*)(int)); static void setsig_fatal_gen(int, void (*)(int), int, const char *); static void terminated(const char *); #ifndef HAVE_ERR static void err(int code, const char *fmt, ...) { va_list v; va_start(v, fmt); vfprintf(stderr, fmt, v); va_end(v); fprintf(stderr, ": %s\n", strerror(errno)); exit(code); } static void errx(int code, const char *fmt, ...) { va_list v; va_start(v, fmt); vfprintf(stderr, fmt, v); va_end(v); fprintf(stderr, "\n"); exit(code); } static void warnx(const char *fmt, ...) { va_list v; va_start(v, fmt); vfprintf(stderr, fmt, v); va_end(v); fprintf(stderr, "\n"); } #endif /* !HAVE_ERR */ static void usage(void) { errx(EX_USAGE, "usage: timelimit [-pq] [-S ksig] [-s wsig] " "[-T ktime] [-t wtime] command"); } static void atou_fatal(const char *s, unsigned long *sec, unsigned long *msec, int issig) { unsigned long v, vm, mul; const char *p; size_t i; if (s[0] < '0' || s[0] > '9') { if (s[0] == '\0' || !issig) usage(); for (i = 0; i < SIGNALS; i++) if (!strcmp(signals[i].name, s)) break; if (i == SIGNALS) usage(); *sec = (unsigned long)signals[i].num; if (msec != NULL) *msec = 0; return; } v = 0; for (p = s; (*p >= '0') && (*p <= '9'); p++) v = v * 10 + *p - '0'; if (*p == '\0') { *sec = v; if (msec != NULL) *msec = 0; return; } else if (*p != '.' || msec == NULL) { usage(); } p++; vm = 0; mul = 1000000; for (; (*p >= '0') && (*p <= '9'); p++) { vm = vm * 10 + *p - '0'; mul = mul / 10; } if (*p != '\0') usage(); else if (mul < 1) errx(EX_USAGE, "no more than microsecond precision"); #ifndef HAVE_SETITIMER if (msec != 0) errx(EX_UNAVAILABLE, "subsecond precision not supported on this platform"); #endif *sec = v; *msec = vm * mul; } static void init(int argc, char *argv[]) { #ifdef PARSE_CMDLINE int ch, listsigs; #endif int optset; unsigned i; char *s; /* defaults */ quiet = 0; warnsig = SIGTERM; killsig = SIGKILL; warntime = 900; warnmsec = 0; killtime = 5; killmsec = 0; optset = 0; /* process environment variables first */ for (i = 0; envopts[i].name != NULL; i++) if ((s = getenv(envopts[i].name)) != NULL) { atou_fatal(s, envopts[i].sec, envopts[i].msec, envopts[i].issig); optset = 1; } #ifdef PARSE_CMDLINE listsigs = 0; while ((ch = getopt(argc, argv, "+lqpS:s:T:t:")) != -1) { switch (ch) { case 'l': listsigs = 1; break; case 'p': propagate = 1; break; case 'q': quiet = 1; break; default: /* check if it's a recognized option */ for (i = 0; envopts[i].name != NULL; i++) if (ch == envopts[i].opt) { atou_fatal(optarg, envopts[i].sec, envopts[i].msec, envopts[i].issig); optset = 1; break; } if (envopts[i].name == NULL) usage(); } } if (listsigs) { for (i = 0; i < SIGNALS; i++) printf("%s%c", signals[i].name, i + 1 < SIGNALS? ' ': '\n'); exit(EX_OK); } #else optind = 1; #endif if (!optset) /* && !quiet? */ warnx("using defaults: warntime=%lu, warnsig=%lu, " "killtime=%lu, killsig=%lu", warntime, warnsig, killtime, killsig); argc -= optind; argv += optind; if (argc == 0) usage(); /* sanity checks */ if ((warntime == 0 && warnmsec == 0) || (killtime == 0 && killmsec == 0)) usage(); } static void sigchld(int sig __unused) { fdone = 1; } static void sigalrm(int sig __unused) { falarm = 1; } static void sighandler(int sig) { sigcaught = sig; fsig = 1; } static void setsig_fatal(int sig, void (*handler)(int)) { setsig_fatal_gen(sig, handler, 1, "setting"); } static void setsig_fatal_gen(int sig, void (*handler)(int), int nocld, const char *what) { #ifdef HAVE_SIGACTION struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = handler; act.sa_flags = 0; #ifdef SA_NOCLDSTOP if (nocld) act.sa_flags |= SA_NOCLDSTOP; #endif /* SA_NOCLDSTOP */ if (sigaction(sig, &act, NULL) < 0) err(EX_OSERR, "%s signal handler for %d", what, sig); #else /* HAVE_SIGACTION */ if (signal(sig, handler) == SIG_ERR) err(EX_OSERR, "%s signal handler for %d", what, sig); #endif /* HAVE_SIGACTION */ } static void settimer(const char *name, unsigned long sec, unsigned long msec) { #ifdef HAVE_SETITIMER struct itimerval tval; tval.it_interval.tv_sec = tval.it_interval.tv_usec = 0; tval.it_value.tv_sec = sec; tval.it_value.tv_usec = msec; if (setitimer(ITIMER_REAL, &tval, NULL) == -1) err(EX_OSERR, "could not set the %s timer", name); #else alarm(sec); #endif } static pid_t doit(char *argv[]) { pid_t pid; /* install signal handlers */ fdone = falarm = fsig = sigcaught = 0; setsig_fatal(SIGALRM, sigalrm); setsig_fatal(SIGCHLD, sigchld); setsig_fatal(SIGTERM, sighandler); setsig_fatal(SIGHUP, sighandler); setsig_fatal(SIGINT, sighandler); setsig_fatal(SIGQUIT, sighandler); /* fork off the child process */ if ((pid = fork()) < 0) err(EX_OSERR, "fork"); if (pid == 0) child(argv); /* sleep for the allowed time */ settimer("warning", warntime, warnmsec); while (!(fdone || falarm || fsig)) pause(); alarm(0); /* send the warning signal */ if (fdone) return (pid); if (fsig) terminated("run"); falarm = 0; if (!quiet) warnx("sending warning signal %lu", warnsig); kill(pid, (int) warnsig); #ifndef HAVE_SIGACTION /* reset our signal handlers, just in case */ setsig_fatal(SIGALRM, sigalrm); setsig_fatal(SIGCHLD, sigchld); setsig_fatal(SIGTERM, sighandler); setsig_fatal(SIGHUP, sighandler); setsig_fatal(SIGINT, sighandler); setsig_fatal(SIGQUIT, sighandler); #endif /* HAVE_SIGACTION */ /* sleep for the grace time */ settimer("kill", killtime, killmsec); while (!(fdone || falarm || fsig)) pause(); alarm(0); /* send the kill signal */ if (fdone) return (pid); if (fsig) terminated("grace"); if (!quiet) warnx("sending kill signal %lu", killsig); kill(pid, (int) killsig); setsig_fatal_gen(SIGCHLD, SIG_DFL, 0, "restoring"); return (pid); } static void terminated(const char *period) { errx(EX_SOFTWARE, "terminated by signal %d during the %s period", sigcaught, period); } static void child(char *argv[]) { execvp(argv[0], argv); err(EX_OSERR, "executing %s", argv[0]); } static __dead2 void raisesignal (int sig) { setsig_fatal_gen(sig, SIG_DFL, 0, "restoring"); raise(sig); while (1) pause(); /* NOTREACHED */ } int main(int argc, char *argv[]) { pid_t pid; int status; init(argc, argv); argc -= optind; argv += optind; pid = doit(argv); if (waitpid(pid, &status, 0) == -1) err(EX_OSERR, "could not get the exit status for process %ld", (long)pid); if (WIFEXITED(status)) return (WEXITSTATUS(status)); else if (!WIFSIGNALED(status)) return (EX_OSERR); if (propagate) raisesignal(WTERMSIG(status)); else return (WTERMSIG(status) + 128); } bareos-Release-14.2.6/src/win32/000077500000000000000000000000001263011562700161715ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/Makefile000066400000000000000000000075451263011562700176440ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # include Makefile.inc VERSION_STRING := $(shell grep 'VERSION "' ../include/version.h | cut -d ' ' -f3) all_subdirs = lib findlib lmdb filed console tools cats dird stored plugins ifeq ($(BUILD_QTGUI),yes) all_subdirs += qt-console qt-tray-monitor endif all: rc-files qt-gui @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done install: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done clean: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done distclean: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done ifeq ($(BUILD_QTGUI),) rc-files: tools/bsmtpres.rc \ console/consoleres.rc \ filed/filedres.rc \ stored/storedres.rc \ stored/bextractres.rc \ stored/blsres.rc \ stored/btaperes.rc \ dird/dirdres.rc \ dird/dbcheckres.rc qt-gui: else rc-files: tools/bsmtpres.rc \ console/consoleres.rc \ filed/filedres.rc \ stored/storedres.rc \ stored/bextractres.rc \ stored/blsres.rc \ stored/btaperes.rc \ dird/dirdres.rc \ dird/dbcheckres.rc \ qt-console/batres.rc \ qt-tray-monitor/traymon.rc qt-gui: qt-console/Makefile qt-tray-monitor/Makefile qt-console/Makefile: qt-console/bat.pro cd qt-console; $(QMAKE) $(QMAKE_ARGS) bat.pro qt-tray-monitor/Makefile: qt-tray-monitor/tray-monitor.pro cd qt-tray-monitor; $(QMAKE) $(QMAKE_ARGS) tray-monitor.pro qt-console/batres.rc: qt-console/batres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ qt-tray-monitor/traymon.rc: qt-tray-monitor/traymon.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ endif tools/bsmtpres.rc: tools/bsmtpres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ console/consoleres.rc: console/consoleres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ filed/filedres.rc: filed/filedres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ stored/storedres.rc: stored/storedres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ dird/dirdres.rc: dird/dirdres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ dird/dbcheckres.rc: dird/dbcheckres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ stored/bextractres.rc: stored/bextractres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ stored/btaperes.rc: stored/btaperes.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ stored/blsres.rc: stored/blsres.rc.in @sed -e 's/@VERSION@/$(VERSION_STRING)/' $< > $@ bareos-Release-14.2.6/src/win32/Makefile.inc000066400000000000000000000041771263011562700204120ustar00rootroot00000000000000# # If no version is forced from the outside set a default. # ifeq ($(WIN_VERSION),) WIN_VERSION = 64 endif # # If no debug if forced from the ouside set a default. # ifeq ($(WIN_DEBUG),) WIN_DEBUG = no endif # # If no vistacompat is forced from the outside set a default. # ifeq ($(WIN_VISTACOMPAT),) WIN_VISTACOMPAT = no endif ifeq ($(WIN_VISTACOMPAT),yes) WINDOWS_VERSION = 0x600 QMAKE_ARGS = "DEFINES+=_WIN32_WINNT=$(WINDOWS_VERSION)" else WINDOWS_VERSION = 0x500 QMAKE_ARGS = "DEFINES+=_WIN32_WINNT=$(WINDOWS_VERSION)" endif MINGW_32_BASE = /usr/i686-w64-mingw32 MINGW_64_BASE = /usr/x86_64-w64-mingw32 ifeq ($(WIN_VERSION),32) DEFINES = -DHAVE_WIN32 -DHAVE_MINGW -D_WIN32_WINNT=$(WINDOWS_VERSION) QMAKE = /usr/bin/i686-w64-mingw32-qmake WINDRES = /usr/bin/i686-w64-mingw32-windres CC = /usr/bin/i686-w64-mingw32-gcc CXX = /usr/bin/i686-w64-mingw32-g++ ifeq ($(WIN_DEBUG),yes) CFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -g CXXFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -fno-strict-aliasing -Wno-unknown-pragmas -g else CFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -O3 CXXFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -O3 -fno-strict-aliasing -Wno-unknown-pragmas endif MINGW_LIB = $(MINGW_32_BASE)/sys-root/mingw/lib else DEFINES = -DMINGW64 -DHAVE_WIN32 -DHAVE_MINGW -D_WIN32_WINNT=$(WINDOWS_VERSION) QMAKE = /usr/bin/x86_64-w64-mingw32-qmake WINDRES = /usr/bin/x86_64-w64-mingw32-windres CC = /usr/bin/x86_64-w64-mingw32-gcc CXX = /usr/bin/x86_64-w64-mingw32-g++ ifeq ($(WIN_DEBUG),yes) CFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -g CXXFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -fno-strict-aliasing -Wno-unknown-pragmas -g else CFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -O3 CXXFLAGS = $(DEFINES) $(INCLUDES) -Wall -m$(WIN_VERSION) -mwin32 -mthreads -O3 -fno-strict-aliasing -Wno-unknown-pragmas endif MINGW_LIB = $(MINGW_64_BASE)/sys-root/mingw/lib endif WINSOCKLIB = -lws2_32 LDFLAGS_DLL = -mdll -mwindows LDFLAGS_WINAPP = -mwindows LDFLAGS_CONS = -mconsole bareos-Release-14.2.6/src/win32/README.OBS000066400000000000000000000021251263011562700174730ustar00rootroot00000000000000The sources under this directory are build on the so called Open Build Service (OBS) of SUSE with prepackaged mingw32 and mingw64 rpms. rpms needed are: For mingw32: https://build.opensuse.org/project/show?project=windows%3Amingw%3Awin32 mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc mingw32-cross-gcc-c++ mingw32-filesystem mingw32-headers mingw32-libopenssl-devel mingw32-pcre-devel mingw32-pthreads-devel mingw32-readline-devel mingw32-runtime mingw32-zlib-devel mingw32-libqt4 mingw32-libqt4-devel mingw32-libsqlite mingw32-libsqlite-devel For mingw64: https://build.opensuse.org/project/show?project=windows%3Amingw%3Awin64 mingw64-cross-binutils mingw64-cross-cpp mingw64-cross-gcc mingw64-cross-gcc-c++ mingw64-filesystem mingw64-headers mingw64-libopenssl-devel mingw64-pcre-devel mingw64-pthreads-devel mingw64-readline-devel mingw64-runtime mingw64-zlib-devel mingw64-libqt4-devel mingw64-libsqlite mingw64-libsqlite-devel The Makefiles in this directory are setup to work with this setup. As the are seriously simple adapting to an other mingw install should be rather simple. bareos-Release-14.2.6/src/win32/cats/000077500000000000000000000000001263011562700171235ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/cats/Makefile000066400000000000000000000051071263011562700205660ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../cats include ../Makefile.inc INCLUDES = -I../.. \ -I../../include \ -I../include \ -I../../findlib \ -I../compat/include LDLIBS = ../lib/libbareos.dll LIBBAREOSCATS_SRCS = bvfs.c cats.c cats_backends.c sql.c sql_cmds.c \ sql_create.c sql_delete.c sql_find.c sql_get.c \ sql_glue.c sql_list.c sql_pooling.c sql_update.c LIBBAREOSCATS_OBJS = $(LIBBAREOSCATS_SRCS:.c=.o) DEFINES += -D_BDB_PRIV_INTERFACE_ DYNAMIC_OBJS = $(LIBBAREOSCATS_OBJS) all: libbareoscats.dll libbareoscats-postgresql.dll libbareoscats-sqlite3.dll bareos$(WIN_VERSION).def: $(DYNAMIC_OBJS) make_def ./make_def $(WIN_VERSION) $(DYNAMIC_OBJS) > $@ libbareoscats.dll: DLL_USAGE = -DBUILDING_DLL libbareoscats.dll: $(DYNAMIC_OBJS) \ bareos$(WIN_VERSION).def $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a $(DYNAMIC_OBJS) bareos$(WIN_VERSION).def $(LDLIBS) -o $@ postgresql.o: postgresql.c @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -Ipgsql/include -c -o $@ $< libbareoscats-postgresql.dll: DLL_USAGE = -DBUILDING_DLL libbareoscats-postgresql.dll: postgresql.o libbareoscats.dll $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a postgresql.o $(LDLIBS) libbareoscats.dll pgsql/lib/$(WIN_VERSION)/libpq.dll -o $@ libbareoscats-sqlite3.dll: DLL_USAGE = -DBUILDING_DLL libbareoscats-sqlite3.dll: sqlite.o libbareoscats.dll $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a sqlite.o $(LDLIBS) libbareoscats.dll -lsqlite3 -o $@ clean: rm -f *.o bareos$(WIN_VERSION).def distclean: clean rm -f libbareoscats.dll libbareoscats.dll.a \ libbareoscats-postgresql.dll libbareoscats-postgresql.dll.a \ libbareoscats-sqlite3.dll libbareoscats-sqlite3.dll.a # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/cats/make_def000077500000000000000000000016461263011562700206130ustar00rootroot00000000000000#!/bin/sh NM=nm case $1 in 32) SYMBOL_START=13 ;; 64) SYMBOL_START=20 ;; *) SYMBOL_START=13 ;; esac shift echo "LIBRARY libbareoscats.dll" echo "EXPORTS" echo " " # # Get all function symbols. # for i in $* do header=1 ${NM} $i | grep "^[0-9a-f]* T " | cut -c${SYMBOL_START}- > /tmp/sym.$$ while read symbol do if [ ${header} = 1 ]; then echo "; $i" header=0 fi echo "${symbol}" done < /tmp/sym.$$ if [ ${header} = 0 ]; then echo " " fi rm -f /tmp/sym.$$ done # # Get all data symbols. # for i in $* do header=1 ${NM} $i | grep "^[0-9a-f]* D " | cut -c${SYMBOL_START}- > /tmp/sym.$$ while read symbol do if [ ${header} = 1 ]; then echo "; $i" header=0 fi echo "${symbol}" done < /tmp/sym.$$ if [ ${header} = 0 ]; then echo " " fi rm -f /tmp/sym.$$ done bareos-Release-14.2.6/src/win32/compat/000077500000000000000000000000001263011562700174545ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/compat.c000066400000000000000000002752521263011562700211200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * -*- Mode: C++ -*- * compat.cpp -- compatibilty layer to make bareos-fd run natively under windows * * Copyright transferred from Raider Solutions, Inc to * Kern Sibbald and John Walker by express permission. * * Author : Christopher S. Hull * Created On : Sat Jan 31 15:55:00 2004 */ #include "bareos.h" #include "jcr.h" #include "dlfcn.h" #include "findlib/find.h" /* * Sanity check to make sure FILE_ATTRIBUTE_VALID_FLAGS is always smaller * than our define of FILE_ATTRIBUTE_VOLUME_MOUNT_POINT. */ #if FILE_ATTRIBUTE_VOLUME_MOUNT_POINT < FILE_ATTRIBUTE_VALID_FLAGS #error "FILE_ATTRIBUTE_VALID_FLAGS smaller than FILE_ATTRIBUTE_VALID_FLAGS" #endif /* * Note, if you want to see what Windows variables and structures * are defined, bareos.h includes , which is found in: * * cross-tools/mingw32/mingw32/include * or * cross-tools/mingw-w64/x86_64-pc-mingw32/include * * depending on whether we are building the 32 bit version or * the 64 bit version. */ static const int dbglvl = 500; #define b_errno_win32 (1<<29) #define MAX_PATHLENGTH 1024 /* * UTF-8 to UCS2 path conversion is expensive, * so we cache the conversion. During backup the * conversion is called 3 times (lstat, attribs, open), * by using the cache this is reduced to 1 time */ static POOLMEM *g_pWin32ConvUTF8Cache = NULL; static POOLMEM *g_pWin32ConvUCS2Cache = NULL; static DWORD g_dwWin32ConvUTF8strlen = 0; static pthread_mutex_t Win32Convmutex = PTHREAD_MUTEX_INITIALIZER; /* * Special flag used to enable or disable Bacula compatible win32 encoding. */ static bool win32_bacula_compatible = true; void Win32ClearCompatible() { win32_bacula_compatible = false; } void Win32SetCompatible() { win32_bacula_compatible = true; } bool Win32IsCompatible() { return win32_bacula_compatible; } static t_pVSSPathConvert g_pVSSPathConvert; static t_pVSSPathConvertW g_pVSSPathConvertW; /* * Forward referenced functions */ static const char *errorString(void); void SetVSSPathConvert(t_pVSSPathConvert pPathConvert, t_pVSSPathConvertW pPathConvertW) { g_pVSSPathConvert = pPathConvert; g_pVSSPathConvertW = pPathConvertW; } static void Win32ConvInitCache() { if (g_pWin32ConvUTF8Cache) { return; } g_pWin32ConvUTF8Cache = get_pool_memory(PM_FNAME); g_pWin32ConvUCS2Cache = get_pool_memory(PM_FNAME); } void Win32ConvCleanupCache() { P(Win32Convmutex); if (g_pWin32ConvUTF8Cache) { free_pool_memory(g_pWin32ConvUTF8Cache); g_pWin32ConvUTF8Cache = NULL; } if (g_pWin32ConvUCS2Cache) { free_pool_memory(g_pWin32ConvUCS2Cache); g_pWin32ConvUCS2Cache = NULL; } g_dwWin32ConvUTF8strlen = 0; V(Win32Convmutex); } /* * To allow the usage of the original version in this file here */ #undef fputs #define USE_WIN32_32KPATHCONVERSION 1 extern DWORD g_platform_id; extern DWORD g_MinorVersion; /* * From Microsoft SDK (KES) is the diff between Jan 1 1601 and Jan 1 1970 */ #ifdef HAVE_MINGW #define WIN32_FILETIME_ADJUST 0x19DB1DED53E8000ULL #else #define WIN32_FILETIME_ADJUST 0x19DB1DED53E8000I64 #endif #define WIN32_FILETIME_SCALE 10000000 // 100ns/second /** * Convert from UTF-8 to VSS Windows path/file * Used by compatibility layer for Unix system calls */ static void conv_unix_to_vss_win32_path(const char *name, char *win32_name, DWORD dwSize) { const char *fname = name; char *tname = win32_name; Dmsg0(dbglvl, "Enter convert_unix_to_win32_path\n"); if (IsPathSeparator(name[0]) && IsPathSeparator(name[1]) && name[2] == '.' && IsPathSeparator(name[3])) { *win32_name++ = '\\'; *win32_name++ = '\\'; *win32_name++ = '.'; *win32_name++ = '\\'; name += 4; } else if (g_platform_id != VER_PLATFORM_WIN32_WINDOWS && g_pVSSPathConvert == NULL) { /* * Allow path to be 32767 bytes */ *win32_name++ = '\\'; *win32_name++ = '\\'; *win32_name++ = '?'; *win32_name++ = '\\'; } while (*name) { /** * Check for Unix separator and convert to Win32 */ if (name[0] == '/' && name[1] == '/') { /* double slash? */ name++; /* yes, skip first one */ } if (*name == '/') { *win32_name++ = '\\'; /* convert char */ /* * If Win32 separator that is "quoted", remove quote */ } else if (*name == '\\' && name[1] == '\\') { *win32_name++ = '\\'; name++; /* skip first \ */ } else { *win32_name++ = *name; /* copy character */ } name++; } /** * Strip any trailing slash, if we stored something * but leave "c:\" with backslash (root directory case */ if (*fname != 0 && win32_name[-1] == '\\' && strlen (fname) != 3) { win32_name[-1] = 0; } else { *win32_name = 0; } /** * Here we convert to VSS specific file name which * can get longer because VSS will make something like * \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy1\\bareos\\uninstall.exe * from c:\bareos\uninstall.exe */ Dmsg1(dbglvl, "path=%s\n", tname); if (g_pVSSPathConvert != NULL) { POOLMEM *pszBuf = get_pool_memory (PM_FNAME); pszBuf = check_pool_memory_size(pszBuf, dwSize); bstrncpy(pszBuf, tname, strlen(tname)+1); g_pVSSPathConvert(pszBuf, tname, dwSize); free_pool_memory(pszBuf); } Dmsg1(dbglvl, "Leave cvt_u_to_win32_path path=%s\n", tname); } /** * Conversion of a Unix filename to a Win32 filename */ void unix_name_to_win32(POOLMEM **win32_name, const char *name) { /* * One extra byte should suffice, but we double it * add MAX_PATH bytes for VSS shadow copy name. */ DWORD dwSize = 2 * strlen(name) + MAX_PATH; *win32_name = check_pool_memory_size(*win32_name, dwSize); conv_unix_to_vss_win32_path(name, *win32_name, dwSize); } /** * This function expects an UCS-encoded standard wchar_t in pszUCSPath and * will complete the input path to an absolue path of the form \\?\c:\path\file * * With this trick, it is possible to have 32K characters long paths. * * Optionally one can use pBIsRawPath to determine id pszUCSPath contains a path * to a raw windows partition. * * Created 02/27/2006 Thorsten Engel */ static POOLMEM *make_wchar_win32_path(POOLMEM *pszUCSPath, BOOL *pBIsRawPath /*= NULL*/) { Dmsg0(dbglvl, "Enter wchar_win32_path\n"); if (pBIsRawPath) { *pBIsRawPath = FALSE; /* Initialize, set later */ } if (!p_GetCurrentDirectoryW) { Dmsg0(dbglvl, "Leave wchar_win32_path no change \n"); return pszUCSPath; } wchar_t *name = (wchar_t *)pszUCSPath; /* * If it has already the desired form, exit without changes */ if (wcslen(name) > 3 && wcsncmp(name, L"\\\\?\\", 4) == 0) { Dmsg0(dbglvl, "Leave wchar_win32_path no change \n"); return pszUCSPath; } wchar_t *pwszBuf = (wchar_t *)get_pool_memory(PM_FNAME); wchar_t *pwszCurDirBuf = (wchar_t *)get_pool_memory(PM_FNAME); DWORD dwCurDirPathSize = 0; /* * Get buffer with enough size (name+max 6. wchars+1 null terminator */ DWORD dwBufCharsNeeded = (wcslen(name)+7); pwszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszBuf, dwBufCharsNeeded * sizeof(wchar_t)); /* * Add \\?\ to support 32K long filepaths * it is important to make absolute paths, so we add drive and * current path if necessary */ BOOL bAddDrive = TRUE; BOOL bAddCurrentPath = TRUE; BOOL bAddPrefix = TRUE; /* * Does path begin with drive? if yes, it is absolute */ if (iswalpha(name[0]) && name[1] == ':' && IsPathSeparator(name[2])) { bAddDrive = FALSE; bAddCurrentPath = FALSE; } /* * Is path absolute? */ if (IsPathSeparator(name[0])) bAddCurrentPath = FALSE; /* * Is path relative to itself?, if yes, skip ./ */ if (name[0] == '.' && IsPathSeparator(name[1])) { name += 2; } /* * Is path of form '//./'? */ if (IsPathSeparator(name[0]) && IsPathSeparator(name[1]) && name[2] == '.' && IsPathSeparator(name[3])) { bAddDrive = FALSE; bAddCurrentPath = FALSE; bAddPrefix = FALSE; if (pBIsRawPath) { *pBIsRawPath = TRUE; } } int nParseOffset = 0; /* * Add 4 bytes header */ if (bAddPrefix) { nParseOffset = 4; wcscpy(pwszBuf, L"\\\\?\\"); } /* * Get current path if needed */ if (bAddDrive || bAddCurrentPath) { dwCurDirPathSize = p_GetCurrentDirectoryW(0, NULL); if (dwCurDirPathSize > 0) { /* * Get directory into own buffer as it may either return c:\... or \\?\C:\.... */ pwszCurDirBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszCurDirBuf, (dwCurDirPathSize+1) * sizeof(wchar_t)); p_GetCurrentDirectoryW(dwCurDirPathSize, pwszCurDirBuf); } else { /* * We have no info for doing so */ bAddDrive = FALSE; bAddCurrentPath = FALSE; } } /* * Add drive if needed */ if (bAddDrive && !bAddCurrentPath) { wchar_t szDrive[3]; if (IsPathSeparator(pwszCurDirBuf[0]) && IsPathSeparator(pwszCurDirBuf[1]) && pwszCurDirBuf[2] == '?' && IsPathSeparator(pwszCurDirBuf[3])) { /* * Copy drive character */ szDrive[0] = pwszCurDirBuf[4]; } else { /* * Copy drive character */ szDrive[0] = pwszCurDirBuf[0]; } szDrive[1] = ':'; szDrive[2] = 0; wcscat(pwszBuf, szDrive); nParseOffset +=2; } /* * Add path if needed */ if (bAddCurrentPath) { /* * The 1 additional character is for the eventually added backslash */ dwBufCharsNeeded += dwCurDirPathSize+1; pwszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszBuf, dwBufCharsNeeded * sizeof(wchar_t)); /* * Get directory into own buffer as it may either return c:\... or \\?\C:\.... */ if (IsPathSeparator(pwszCurDirBuf[0]) && IsPathSeparator(pwszCurDirBuf[1]) && pwszCurDirBuf[2] == '?' && IsPathSeparator(pwszCurDirBuf[3])) { /* * Copy complete string */ wcscpy(pwszBuf, pwszCurDirBuf); } else { /* * Append path */ wcscat(pwszBuf, pwszCurDirBuf); } nParseOffset = wcslen((LPCWSTR) pwszBuf); /* * Check if path ends with backslash, if not, add one */ if (!IsPathSeparator(pwszBuf[nParseOffset-1])) { wcscat(pwszBuf, L"\\"); nParseOffset++; } } wchar_t *win32_name = &pwszBuf[nParseOffset]; wchar_t *name_start = name; wchar_t previous_char = 0; wchar_t next_char = 0; while (*name) { /* * Check for Unix separator and convert to Win32, eliminating duplicate separators. */ if (IsPathSeparator(*name)) { /* * Don't add a trailing slash. */ next_char = *(name + 1); if (previous_char != ':' && next_char == '\0') { name++; continue; } previous_char = '\\'; *win32_name++ = '\\'; /* convert char */ /* * Eliminate consecutive slashes, but not at the start so that \\.\ still works. */ if (name_start != name && IsPathSeparator(name[1])) { name++; } } else { previous_char = *name; *win32_name++ = *name; /* copy character */ } name++; } /* * NULL terminate string */ *win32_name = 0; /* * Here we convert to VSS specific file name which can get longer because VSS will make something like * \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy1\\bareos\\uninstall.exe from c:\bareos\uninstall.exe */ if (g_pVSSPathConvertW != NULL) { /* * Is output buffer large enough? */ pwszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszBuf, (dwBufCharsNeeded+MAX_PATH) * sizeof(wchar_t)); /* * Create temp. buffer */ wchar_t *pszBuf = (wchar_t *)get_pool_memory(PM_FNAME); pszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pszBuf, (dwBufCharsNeeded+MAX_PATH) * sizeof(wchar_t)); if (bAddPrefix) nParseOffset = 4; else nParseOffset = 0; wcsncpy(pszBuf, &pwszBuf[nParseOffset], wcslen(pwszBuf)+1-nParseOffset); g_pVSSPathConvertW(pszBuf, pwszBuf, dwBufCharsNeeded+MAX_PATH); free_pool_memory((POOLMEM *)pszBuf); } free_pool_memory(pszUCSPath); free_pool_memory((POOLMEM *)pwszCurDirBuf); Dmsg1(dbglvl, "Leave wchar_win32_path=%s\n", pwszBuf); return (POOLMEM *)pwszBuf; } /* * Convert from WCHAR (UCS) to UTF-8 */ int wchar_2_UTF8(POOLMEM **pszUTF, const wchar_t *pszUCS) { /** * The return value is the number of bytes written to the buffer. * The number includes the byte for the null terminator. */ if (p_WideCharToMultiByte) { int nRet = p_WideCharToMultiByte(CP_UTF8,0,pszUCS,-1,NULL,0,NULL,NULL); *pszUTF = check_pool_memory_size(*pszUTF, nRet); return p_WideCharToMultiByte(CP_UTF8,0,pszUCS,-1,*pszUTF,nRet,NULL,NULL); } else { return 0; } } /* * Convert from WCHAR (UCS) to UTF-8 */ int wchar_2_UTF8(char *pszUTF, const wchar_t *pszUCS, int cchChar) { /** * The return value is the number of bytes written to the buffer. * The number includes the byte for the null terminator. */ if (p_WideCharToMultiByte) { int nRet = p_WideCharToMultiByte(CP_UTF8,0,pszUCS,-1,pszUTF,cchChar,NULL,NULL); ASSERT (nRet > 0); return nRet; } else { return 0; } } int UTF8_2_wchar(POOLMEM **ppszUCS, const char *pszUTF) { /* * The return value is the number of wide characters written to the buffer. * convert null terminated string from utf-8 to ucs2, enlarge buffer if necessary */ if (p_MultiByteToWideChar) { /* * strlen of UTF8 +1 is enough */ DWORD cchSize = (strlen(pszUTF)+1); *ppszUCS = check_pool_memory_size(*ppszUCS, cchSize * sizeof (wchar_t)); int nRet = p_MultiByteToWideChar(CP_UTF8, 0, pszUTF, -1, (LPWSTR) *ppszUCS,cchSize); ASSERT (nRet > 0); return nRet; } else { return 0; } } /* * Convert a C character string into an BSTR. */ BSTR str_2_BSTR(const char *pSrc) { DWORD cwch; BSTR wsOut(NULL); if (!pSrc) { return NULL; } if (p_MultiByteToWideChar) { if ((cwch = p_MultiByteToWideChar(CP_ACP, 0, pSrc, -1, NULL, 0))) { cwch--; wsOut = SysAllocStringLen(NULL, cwch); if (wsOut) { if (!p_MultiByteToWideChar(CP_ACP, 0, pSrc, -1, wsOut, cwch)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { return wsOut; } SysFreeString(wsOut); wsOut = NULL; } } } } return wsOut; } /* * Convert a BSTR into an C character string. */ char *BSTR_2_str(BSTR pSrc) { DWORD cb, cwch; char *szOut = NULL; if (!pSrc) { return NULL; } if (p_WideCharToMultiByte) { cwch = SysStringLen(pSrc); if ((cb = p_WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, NULL, 0, 0, 0))) { szOut = (char *)malloc(cb); szOut[cb - 1] = '\0'; if (!p_WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, szOut, cb, 0, 0)) { free(szOut); szOut = NULL; } } } return szOut; } void wchar_win32_path(const char *name, wchar_t *win32_name) { const char *fname = name; while (*name) { /* * Check for Unix separator and convert to Win32 */ if (*name == '/') { *win32_name++ = '\\'; /* convert char */ /* * If Win32 separated that is "quoted", remove quote */ } else if (*name == '\\' && name[1] == '\\') { *win32_name++ = '\\'; name++; /* skip first \ */ } else { *win32_name++ = *name; /* copy character */ } name++; } /* * Strip any trailing slash, if we stored something */ if (*fname != 0 && win32_name[-1] == '\\') { win32_name[-1] = 0; } else { *win32_name = 0; } } int make_win32_path_UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF, BOOL *pBIsRawPath /*= NULL*/) { P(Win32Convmutex); /* * If we find the utf8 string in cache, we use the cached ucs2 version. * we compare the stringlength first (quick check) and then compare the content. */ if (!g_pWin32ConvUTF8Cache) { Win32ConvInitCache(); } else if (g_dwWin32ConvUTF8strlen == strlen(pszUTF)) { if (bstrcmp(pszUTF, g_pWin32ConvUTF8Cache)) { /* Return cached value */ int32_t nBufSize = sizeof_pool_memory(g_pWin32ConvUCS2Cache); *pszUCS = check_pool_memory_size(*pszUCS, nBufSize); wcscpy((LPWSTR) *pszUCS, (LPWSTR)g_pWin32ConvUCS2Cache); V(Win32Convmutex); return nBufSize / sizeof (WCHAR); } } /* * Helper to convert from utf-8 to UCS-2 and to complete a path for 32K path syntax */ int nRet = UTF8_2_wchar(pszUCS, pszUTF); #ifdef USE_WIN32_32KPATHCONVERSION /* * Add \\?\ to support 32K long filepaths */ *pszUCS = make_wchar_win32_path(*pszUCS, pBIsRawPath); #else if (pBIsRawPath) *pBIsRawPath = FALSE; #endif /* * Populate cache */ g_pWin32ConvUCS2Cache = check_pool_memory_size(g_pWin32ConvUCS2Cache, sizeof_pool_memory(*pszUCS)); wcscpy((LPWSTR) g_pWin32ConvUCS2Cache, (LPWSTR) *pszUCS); g_dwWin32ConvUTF8strlen = strlen(pszUTF); g_pWin32ConvUTF8Cache = check_pool_memory_size(g_pWin32ConvUTF8Cache, g_dwWin32ConvUTF8strlen+2); bstrncpy(g_pWin32ConvUTF8Cache, pszUTF, g_dwWin32ConvUTF8strlen+1); V(Win32Convmutex); return nRet; } #if !defined(_MSC_VER) || (_MSC_VER < 1400) // VC8+ int umask(int) { return 0; } #endif #ifndef LOAD_WITH_ALTERED_SEARCH_PATH #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 #endif void *dlopen(const char *filename, int mode) { void *handle; DWORD dwFlags = 0; dwFlags |= LOAD_WITH_ALTERED_SEARCH_PATH; if (mode & RTLD_NOLOAD) { dwFlags |= LOAD_LIBRARY_AS_DATAFILE; } handle = LoadLibraryEx(filename, NULL, dwFlags); return handle; } void *dlsym(void *handle, const char *name) { void *symaddr; symaddr = (void *)GetProcAddress((HMODULE)handle, name); return symaddr; } int dlclose(void *handle) { if (handle && !FreeLibrary((HMODULE)handle)) { errno = b_errno_win32; return 1; /* failed */ } return 0; /* OK */ } char *dlerror(void) { static char buf[200]; const char *err = errorString(); bstrncpy(buf, (char *)err, sizeof(buf)); LocalFree((void *)err); return buf; } int fcntl(int fd, int cmd) { return 0; } int chown(const char *k, uid_t, gid_t) { return 0; } int lchown(const char *k, uid_t, gid_t) { return 0; } long int random(void) { return rand(); } void srandom(unsigned int seed) { srand(seed); } /* * Convert from Windows concept of time to Unix concept of time */ static void cvt_utime_to_ftime(const time_t &time, FILETIME &wintime) { uint64_t mstime = time; mstime *= WIN32_FILETIME_SCALE; mstime += WIN32_FILETIME_ADJUST; #if defined(_MSC_VER) wintime.dwLowDateTime = (DWORD)(mstime & 0xffffffffI64); #else wintime.dwLowDateTime = (DWORD)(mstime & 0xffffffffUL); #endif wintime.dwHighDateTime = (DWORD) ((mstime>>32)& 0xffffffffUL); } static time_t cvt_ftime_to_utime(const FILETIME &time) { uint64_t mstime; mstime = time.dwHighDateTime; mstime <<= 32; mstime |= time.dwLowDateTime; mstime -= WIN32_FILETIME_ADJUST; mstime /= WIN32_FILETIME_SCALE; /* convert to seconds. */ return (time_t) (mstime & 0xffffffff); } static time_t cvt_ftime_to_utime(const LARGE_INTEGER &time) { uint64_t mstime; mstime = time.HighPart; mstime <<= 32; mstime |= time.LowPart; mstime -= WIN32_FILETIME_ADJUST; mstime /= WIN32_FILETIME_SCALE; /* convert to seconds. */ return (time_t) (mstime & 0xffffffff); } static inline bool CreateJunction(LPCSTR szJunction, LPCSTR szPath) { DWORD dwRet; HANDLE hDir; POOLMEM *buf; bool retval = false; int buf_length, path_length, data_length; REPARSE_DATA_BUFFER *rdb; char szDestDir[MAX_PATH]; /* * Create a buffer big enough to hold all data. */ buf_length = sizeof(REPARSE_DATA_BUFFER) + MAX_PATH * sizeof(WCHAR); buf = get_pool_memory(PM_NAME); buf = check_pool_memory_size(buf, buf_length); rdb = (REPARSE_DATA_BUFFER *)buf; bstrncpy(szDestDir, "\\??\\", sizeof(szDestDir)); bstrncat(szDestDir, szPath, sizeof(szDestDir)); bstrncat(szDestDir, "\\", sizeof(szDestDir)); if (!CreateDirectory(szJunction, NULL)) { Dmsg1(dbglvl, "CreateDirectory Failed:%s\n", errorString()); goto bail_out; } hDir = CreateFile(szJunction, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hDir == INVALID_HANDLE_VALUE){ Dmsg0(dbglvl, "INVALID_FILE_HANDLE"); RemoveDirectory(szJunction); goto bail_out; } memset(buf, 0, buf_length); path_length = MultiByteToWideChar(CP_ACP, 0, szDestDir, -1, rdb->MountPointReparseBuffer.PathBuffer, MAX_PATH * sizeof(WCHAR)); rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; rdb->ReparseDataLength = (path_length + 2) * sizeof(WCHAR) + 6; rdb->MountPointReparseBuffer.SubstituteNameLength = (path_length - 1) * sizeof(WCHAR); rdb->MountPointReparseBuffer.PrintNameOffset = path_length * sizeof(WCHAR); data_length = rdb->ReparseDataLength + 8; if (!DeviceIoControl(hDir, FSCTL_SET_REPARSE_POINT, (LPVOID)buf, data_length, NULL, 0, &dwRet, 0)) { Dmsg1(dbglvl, "DeviceIoControl Failed:%s\n", errorString()); CloseHandle(hDir); RemoveDirectory(szJunction); goto bail_out; } CloseHandle(hDir); retval = true; bail_out: free_pool_memory(buf); return retval; } static const char *errorString(void) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default lang */ (LPTSTR) &lpMsgBuf, 0, NULL); /* * Strip any \r or \n */ char *rval = (char *) lpMsgBuf; char *cp = strchr(rval, '\r'); if (cp != NULL) { *cp = 0; } else { cp = strchr(rval, '\n'); if (cp != NULL) *cp = 0; } return rval; } /* * Retrieve the unique devicename of a Volume MountPoint. */ static inline bool get_volume_mount_point_data(const char *filename, POOLMEM **devicename) { HANDLE h = INVALID_HANDLE_VALUE; /* * Now to find out if the directory is a mount point or a reparse point. * Explicitly open the file to read the reparse point, then call * DeviceIoControl to find out if it points to a Volume or to a directory. */ if (p_GetFileAttributesW) { POOLMEM *pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); if (p_CreateFileW) { h = CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); } if (h == INVALID_HANDLE_VALUE) { Dmsg1(dbglvl, "Invalid handle from CreateFileW(%s)\n", pwszBuf); free_pool_memory(pwszBuf); return false; } free_pool_memory(pwszBuf); } else if (p_GetFileAttributesA) { POOLMEM *win32_fname; win32_fname = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, filename); h = CreateFileA(win32_fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (h == INVALID_HANDLE_VALUE) { Dmsg1(dbglvl, "Invalid handle from CreateFile(%s)\n", win32_fname); free_pool_memory(win32_fname); return false; } free_pool_memory(win32_fname); } if (h != INVALID_HANDLE_VALUE) { bool ok; POOLMEM *buf; int buf_length; REPARSE_DATA_BUFFER *rdb; DWORD bytes; /* * Create a buffer big enough to hold all data. */ buf_length = sizeof(REPARSE_DATA_BUFFER) + MAX_PATH * sizeof(WCHAR); buf = get_pool_memory(PM_NAME); buf = check_pool_memory_size(buf, buf_length); rdb = (REPARSE_DATA_BUFFER *)buf; memset(buf, 0, buf_length); rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; ok = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, /* in buffer, bytes */ (LPVOID)buf, (DWORD)buf_length, /* out buffer, btyes */ (LPDWORD)&bytes, (LPOVERLAPPED)0); if (ok) { wchar_2_UTF8(devicename, (wchar_t *)rdb->MountPointReparseBuffer.PathBuffer); } CloseHandle(h); free_pool_memory(buf); } else { return false; } return true; } /* * Retrieve the symlink target */ static inline ssize_t get_symlink_data(const char *filename, POOLMEM **symlinktarget) { ssize_t nrconverted = -1; HANDLE h = INVALID_HANDLE_VALUE; if (p_GetFileAttributesW) { POOLMEM *pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); if (p_CreateFileW) { h = CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); } if (h == INVALID_HANDLE_VALUE) { Dmsg1(dbglvl, "Invalid handle from CreateFileW(%s)\n", pwszBuf); free_pool_memory(pwszBuf); return -1; } free_pool_memory(pwszBuf); } else if (p_GetFileAttributesA) { POOLMEM *win32_fname; win32_fname = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, filename); h = CreateFileA(win32_fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (h == INVALID_HANDLE_VALUE) { Dmsg1(dbglvl, "Invalid handle from CreateFile(%s)\n", win32_fname); free_pool_memory(win32_fname); return -1; } free_pool_memory(win32_fname); } if (h != INVALID_HANDLE_VALUE) { bool ok; POOLMEM *buf; int buf_length; REPARSE_DATA_BUFFER *rdb; DWORD bytes; /* * Create a buffer big enough to hold all data. */ buf_length = sizeof(REPARSE_DATA_BUFFER) + MAX_PATH * sizeof(WCHAR); buf = get_pool_memory(PM_NAME); buf = check_pool_memory_size(buf, buf_length); rdb = (REPARSE_DATA_BUFFER *)buf; memset(buf, 0, buf_length); rdb->ReparseTag = IO_REPARSE_TAG_SYMLINK; ok = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, /* in buffer, bytes */ (LPVOID)buf, (DWORD)buf_length, /* out buffer, btyes */ (LPDWORD)&bytes, (LPOVERLAPPED)0); if (ok) { POOLMEM *path; int len, offset, ofs; len = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR); offset = rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR); /* * null-terminate pathbuffer */ *(wchar_t *)(rdb->SymbolicLinkReparseBuffer.PathBuffer + offset + len) = L'\0'; /* * convert to UTF-8 */ path = get_pool_memory(PM_FNAME); nrconverted = wchar_2_UTF8(&path, (wchar_t *)(rdb->SymbolicLinkReparseBuffer.PathBuffer + offset)); ofs = 0; if (bstrncasecmp(path, "\\??\\", 4)) { /* skip \\??\\ if exists */ ofs = 4; Dmsg0(dbglvl, "\\??\\ was in filename, skipping\n"); } if (bstrncasecmp(path, "?\\", 2)) { /* skip ?\\ if exists, this is a MountPoint that we opened as Symlink */ ofs = 2; Dmsg0(dbglvl, "?\\ was in filename, skipping, use of MountPointReparseDataBuffer is needed\n"); } pm_strcpy(symlinktarget, path + ofs); free_pool_memory(path); } else { Dmsg1(dbglvl, "DeviceIoControl failed:%s\n", errorString()); } CloseHandle(h); free_pool_memory(buf); } else { return -1; } return nrconverted; } /* * Encode file sttributes using the old Bacula method. */ static inline void encode_windows_flags_compatible(DWORD pdwFileAttributes, struct stat *sb) { if (pdwFileAttributes & FILE_ATTRIBUTE_READONLY) { sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH); /* Clear all read bits */ } if (pdwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { sb->st_mode &= ~S_IRWXO; /* Remove everything for other */ } if (pdwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { sb->st_mode |= S_ISVTX; /* Use sticky bit -> hidden */ } } /* * This is called for directories, and reparse points and is used to * get some special attributes like the type of reparse point etc.. */ static int get_windows_file_info(const char *filename, struct stat *sb, bool is_directory) { bool use_fallback_data = true; WIN32_FIND_DATAW info_w; // window's file info WIN32_FIND_DATAA info_a; // window's file info #if (_WIN32_WINNT >= 0x0600) FILE_BASIC_INFO binfo; // window's basic file info HANDLE h = INVALID_HANDLE_VALUE; #endif HANDLE fh = INVALID_HANDLE_VALUE; /* * Cache some common vars to make code more transparent. */ DWORD *pdwFileAttributes; DWORD *pnFileSizeHigh; DWORD *pnFileSizeLow; DWORD *pdwReserved0; FILETIME *pftLastAccessTime; FILETIME *pftLastWriteTime; FILETIME *pftCreationTime; /* * First get a findhandle and a file handle to the file. */ if (p_FindFirstFileW) { /* use unicode */ POOLMEM* pwszBuf = get_pool_memory (PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); Dmsg1(dbglvl, "FindFirstFileW=%s\n", pwszBuf); fh = p_FindFirstFileW((LPCWSTR)pwszBuf, &info_w); #if (_WIN32_WINNT >= 0x0600) if (fh != INVALID_HANDLE_VALUE) { h = p_CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, /* Required for directories */ NULL); } #endif free_pool_memory(pwszBuf); } else if (p_FindFirstFileA) { // use ASCII POOLMEM *win32_fname; win32_fname = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, filename); Dmsg1(dbglvl, "FindFirstFileA=%s\n", win32_fname); fh = p_FindFirstFileA(win32_fname, &info_a); #if (_WIN32_WINNT >= 0x0600) if (h != INVALID_HANDLE_VALUE) { h = CreateFileA(win32_fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, /* Required for directories */ NULL); } #endif free_pool_memory(win32_fname); } else { Dmsg0(dbglvl, "No findFirstFile A or W found\n"); } /* * If we got a valid handle start processing the info. */ if (fh != INVALID_HANDLE_VALUE) { if (p_FindFirstFileW) { /* use unicode */ pdwFileAttributes = &info_w.dwFileAttributes; pdwReserved0 = &info_w.dwReserved0; pnFileSizeHigh = &info_w.nFileSizeHigh; pnFileSizeLow = &info_w.nFileSizeLow; } else { pdwFileAttributes = &info_a.dwFileAttributes; pdwReserved0 = &info_a.dwReserved0; pnFileSizeHigh = &info_a.nFileSizeHigh; pnFileSizeLow = &info_a.nFileSizeLow; } #if (_WIN32_WINNT >= 0x0600) /* * As this is retrieved by handle it has no specific A or W call. */ if (h != INVALID_HANDLE_VALUE) { if (p_GetFileInformationByHandleEx) { if (p_GetFileInformationByHandleEx(h, FileBasicInfo, &binfo, sizeof(binfo))) { pftLastAccessTime = (FILETIME *)&binfo.LastAccessTime; pftLastWriteTime = (FILETIME *)&binfo.LastWriteTime; if (cvt_ftime_to_utime(binfo.CreationTime) > cvt_ftime_to_utime(binfo.ChangeTime)) { pftCreationTime = (FILETIME *)&binfo.CreationTime; } else { pftCreationTime = (FILETIME *)&binfo.ChangeTime; } use_fallback_data = false; } } CloseHandle(h); } #endif /* * See if we got anything from the GetFileInformationByHandleEx() call if not * fallback to the normal info data returned by FindFirstFileW() or FindFirstFileA() */ if (use_fallback_data) { if (p_FindFirstFileW) { /* use unicode */ pftLastAccessTime = &info_w.ftLastAccessTime; pftLastWriteTime = &info_w.ftLastWriteTime; pftCreationTime = &info_w.ftCreationTime; } else { pftLastAccessTime = &info_a.ftLastAccessTime; pftLastWriteTime = &info_a.ftLastWriteTime; pftCreationTime = &info_a.ftCreationTime; } } FindClose(fh); } else { const char *err = errorString(); /* * Note, in creating leading paths, it is normal that the file does not exist. */ Dmsg2(2099, "FindFirstFile(%s):%s\n", filename, err); LocalFree((void *)err); errno = b_errno_win32; return -1; } sb->st_mode = 0777; /* * See if we need to encode in the old Bacula compatible way. */ if (win32_bacula_compatible) { encode_windows_flags_compatible(*pdwFileAttributes, sb); } else { /* * We store the full windows file attributes into st_rdev. */ sb->st_rdev = *pdwFileAttributes; } if (is_directory) { /* * Directory */ sb->st_mode |= S_IFDIR; /* * Store reparse/mount point info in st_rdev. Note a Win32 reparse point * (junction point) is like a link though it can have many properties * (directory link, soft link, hard link, HSM, ... * The IO_REPARSE_TAG_* tag values describe what type of reparse point * it actually is. * * A mount point is a reparse point where another volume is mounted, * so it is like a Unix mount point (change of filesystem). */ if ((*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { switch (*pdwReserved0) { case IO_REPARSE_TAG_MOUNT_POINT: { /* * A mount point can be: * Volume Mount Point "\\??\\volume{..." * Junction Point "\\??\\..." */ POOLMEM *vmp = get_pool_memory(PM_NAME); if (get_volume_mount_point_data(filename, &vmp)) { if (bstrncasecmp(vmp, "\\??\\volume{", 11)) { Dmsg2(dbglvl, "Volume Mount Point %s points to: %s\n", filename, vmp); sb->st_rdev |= FILE_ATTRIBUTE_VOLUME_MOUNT_POINT; } else { Dmsg2(dbglvl, "Junction Point %s points to: %s\n", filename, vmp); sb->st_rdev |= FILE_ATTRIBUTES_JUNCTION_POINT; sb->st_mode |= S_IFLNK; sb->st_mode &= ~S_IFDIR; } } free_pool_memory(vmp); break; } case IO_REPARSE_TAG_SYMLINK: { POOLMEM *slt; Dmsg0(dbglvl, "We have a symlinked directory!\n"); sb->st_rdev |= FILE_ATTRIBUTES_SYMBOLIC_LINK; sb->st_mode |= S_IFLNK; sb->st_mode &= ~S_IFDIR; slt = get_pool_memory(PM_NAME); slt = check_pool_memory_size(slt, MAX_PATH * sizeof(WCHAR)); if (get_symlink_data(filename, &slt)) { Dmsg2(dbglvl, "Symlinked Directory %s points to: %s\n", filename, slt); } free_pool_memory(slt); break; } default: Dmsg1(dbglvl, "IO_REPARSE_TAG_MOUNT_POINT with unhandled IO_REPARSE_TAG %d\n", *pdwReserved0); break; } } } else { /* * No directory */ if ((*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { switch (*pdwReserved0) { case IO_REPARSE_TAG_SYMLINK: { POOLMEM *slt = get_pool_memory(PM_NAME); Dmsg0(dbglvl, "We have a symlinked file!\n"); sb->st_mode |= S_IFLNK; if (get_symlink_data(filename, &slt)) { Dmsg2(dbglvl, "Symlinked File %s points to: %s\n", filename, slt); } free_pool_memory(slt); break; } case IO_REPARSE_TAG_DEDUP: Dmsg0(dbglvl, "We have a deduplicated file!\n"); sb->st_rdev |= FILE_ATTRIBUTES_DEDUPED_ITEM; /* * We treat a deduped file as a normal file. */ sb->st_mode |= S_IFREG; break; default: Dmsg1(dbglvl, "IO_REPARSE_TAG_MOUNT_POINT with unhandled IO_REPARSE_TAG %d\n", *pdwReserved0); break; } } } Dmsg2(dbglvl, "st_rdev=%d filename=%s\n", sb->st_rdev, filename); sb->st_size = *pnFileSizeHigh; sb->st_size <<= 32; sb->st_size |= *pnFileSizeLow; sb->st_blksize = 4096; sb->st_blocks = (uint32_t)(sb->st_size + 4095) / 4096; sb->st_atime = cvt_ftime_to_utime(*pftLastAccessTime); sb->st_mtime = cvt_ftime_to_utime(*pftLastWriteTime); sb->st_ctime = cvt_ftime_to_utime(*pftCreationTime); return 0; } int fstat(intptr_t fd, struct stat *sb) { bool use_fallback_data = true; BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) { const char *err = errorString(); Dmsg1(2099, "GetfileInformationByHandle: %s\n", err); LocalFree((void *)err); errno = b_errno_win32; return -1; } sb->st_dev = info.dwVolumeSerialNumber; sb->st_ino = info.nFileIndexHigh; sb->st_ino <<= 32; sb->st_ino |= info.nFileIndexLow; sb->st_nlink = (short)info.nNumberOfLinks; if (sb->st_nlink > 1) { Dmsg1(dbglvl, "st_nlink=%d\n", sb->st_nlink); } sb->st_mode = 0777; sb->st_mode |= S_IFREG; /* * See if we need to encode in the old Bacula compatible way. */ if (win32_bacula_compatible) { encode_windows_flags_compatible(info.dwFileAttributes, sb); } else { /* * We store the full windows file attributes into st_rdev. */ sb->st_rdev = info.dwFileAttributes; } Dmsg3(dbglvl, "st_rdev=%d sizino=%d ino=%lld\n", sb->st_rdev, sizeof(sb->st_ino), (long long)sb->st_ino); sb->st_size = info.nFileSizeHigh; sb->st_size <<= 32; sb->st_size |= info.nFileSizeLow; sb->st_blksize = 4096; sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096; #if (_WIN32_WINNT >= 0x0600) if (p_GetFileInformationByHandleEx) { FILE_BASIC_INFO binfo; if (p_GetFileInformationByHandleEx((HANDLE)_get_osfhandle(fd), FileBasicInfo, &binfo, sizeof(binfo))) { sb->st_atime = cvt_ftime_to_utime(binfo.LastAccessTime); sb->st_mtime = cvt_ftime_to_utime(binfo.LastWriteTime); if (cvt_ftime_to_utime(binfo.CreationTime) > cvt_ftime_to_utime(binfo.ChangeTime)) { sb->st_ctime = cvt_ftime_to_utime(binfo.CreationTime); } else { sb->st_ctime = cvt_ftime_to_utime(binfo.ChangeTime); } use_fallback_data = false; } } #endif if (use_fallback_data) { sb->st_atime = cvt_ftime_to_utime(info.ftLastAccessTime); sb->st_mtime = cvt_ftime_to_utime(info.ftLastWriteTime); sb->st_ctime = cvt_ftime_to_utime(info.ftCreationTime); } return 0; } static inline bool is_drive_letter_only(const char *filename) { return ((filename[1] == ':' && filename[2] == 0) || (filename[1] == ':' && filename[2] == '/' && filename[3] == 0)); } static int stat2(const char *filename, struct stat *sb) { HANDLE h = INVALID_HANDLE_VALUE; int rval = 0; DWORD attr = (DWORD)-1; if (p_GetFileAttributesW) { POOLMEM *pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); attr = p_GetFileAttributesW((LPCWSTR) pwszBuf); if (p_CreateFileW) { h = CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); } free_pool_memory(pwszBuf); } else if (p_GetFileAttributesA) { POOLMEM *win32_fname; win32_fname = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, filename); attr = p_GetFileAttributesA(win32_fname); h = CreateFileA(win32_fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); free_pool_memory(win32_fname); } if (attr == (DWORD)-1) { const char *err = errorString(); Dmsg2(2099, "GetFileAttributes(%s): %s\n", filename, err); LocalFree((void *)err); if (h != INVALID_HANDLE_VALUE) { CloseHandle(h); } errno = b_errno_win32; rval = -1; goto bail_out; } if (h == INVALID_HANDLE_VALUE) { const char *err = errorString(); Dmsg2(2099, "Cannot open file for stat (%s):%s\n", filename, err); LocalFree((void *)err); errno = b_errno_win32; rval = -1; goto bail_out; } rval = fstat((intptr_t)h, sb); CloseHandle(h); /* * See if this is a directory or a reparse point and its not a single drive letter. * If so we call get_windows_file_info() which retrieves the lowlevel information we need. */ if (((attr & FILE_ATTRIBUTE_DIRECTORY) || (attr & FILE_ATTRIBUTE_REPARSE_POINT)) && !is_drive_letter_only(filename)) { rval = get_windows_file_info(filename, sb, (attr & FILE_ATTRIBUTE_DIRECTORY)); } bail_out: return rval; } int stat(const char *filename, struct stat *sb) { int rval = 0; POOLMEM *win32_fname = NULL; WIN32_FILE_ATTRIBUTE_DATA data; errno = 0; memset(sb, 0, sizeof(*sb)); if (p_GetFileAttributesExW) { /* * Dynamically allocate enough space for UCS2 filename */ POOLMEM *pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); BOOL b = p_GetFileAttributesExW((LPCWSTR)pwszBuf, GetFileExInfoStandard, &data); free_pool_memory(pwszBuf); if (!b) { goto bail_out; } } else if (p_GetFileAttributesExA) { win32_fname = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, filename); if (!p_GetFileAttributesExA(win32_fname, GetFileExInfoStandard, &data)) { goto bail_out; } } else { goto bail_out; } /* * See if this is a directory or a reparse point and not a single drive letter. * If so we call get_windows_file_info() which retrieves the lowlevel information we need. * As get_windows_file_info() fills the complete stat structs we only need to perform the * other part of the code when we don't call the get_windows_file_info() function. */ if (((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) && !is_drive_letter_only(filename)) { rval = get_windows_file_info(filename, sb, (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); } else { bool use_fallback_data = true; sb->st_mode = 0777; /* * See if we need to encode in the old Bacula compatible way. */ if (win32_bacula_compatible) { encode_windows_flags_compatible(data.dwFileAttributes, sb); } /* * We store the full windows file attributes into st_rdev. */ sb->st_rdev = data.dwFileAttributes; if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { sb->st_mode |= S_IFDIR; } else { sb->st_mode |= S_IFREG; } sb->st_nlink = 1; sb->st_size = data.nFileSizeHigh; sb->st_size <<= 32; sb->st_size |= data.nFileSizeLow; sb->st_blksize = 4096; sb->st_blocks = (uint32_t)(sb->st_size + 4095) / 4096; #if (_WIN32_WINNT >= 0x0600) /* * See if GetFileInformationByHandleEx API is available. */ if (p_GetFileInformationByHandleEx) { HANDLE h = INVALID_HANDLE_VALUE; /* * The GetFileInformationByHandleEx need a file handle so we have to * open the file or directory read-only. */ if (p_CreateFileW) { POOLMEM *pwszBuf; pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); h = p_CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); free_pool_memory(pwszBuf); } else { h = CreateFileA(win32_fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); } if (h != INVALID_HANDLE_VALUE) { FILE_BASIC_INFO binfo; if (p_GetFileInformationByHandleEx(h, FileBasicInfo, &binfo, sizeof(binfo))) { sb->st_atime = cvt_ftime_to_utime(binfo.LastAccessTime); sb->st_mtime = cvt_ftime_to_utime(binfo.LastWriteTime); if (cvt_ftime_to_utime(binfo.CreationTime) > cvt_ftime_to_utime(binfo.ChangeTime)) { sb->st_ctime = cvt_ftime_to_utime(binfo.CreationTime); } else { sb->st_ctime = cvt_ftime_to_utime(binfo.ChangeTime); } use_fallback_data = false; } CloseHandle(h); } } #endif if (use_fallback_data) { /* * Fall back to the GetFileAttributesEx data. */ sb->st_atime = cvt_ftime_to_utime(data.ftLastAccessTime); sb->st_mtime = cvt_ftime_to_utime(data.ftLastWriteTime); sb->st_ctime = cvt_ftime_to_utime(data.ftCreationTime); } } rval = 0; Dmsg3(dbglvl, "sizino=%d ino=%lld filename=%s\n", sizeof(sb->st_ino), (long long)sb->st_ino, filename); return rval; bail_out: if (win32_fname) { free_pool_memory(win32_fname); } return stat2(filename, sb); } /* * Get the Volume MountPoint unique devicename for the given filename. * This is a wrapper around get_volume_mount_point_data() used for retrieving * the VMP data used in the VSS snapshotting. */ bool win32_get_vmp_devicename(const char *filename, POOLMEM **devicename) { return get_volume_mount_point_data(filename, devicename); } /* * We write our own ftruncate because the one in the * Microsoft library mrcrt.dll does not truncate * files greater than 2GB. * KES - May 2007 */ int win32_ftruncate(int fd, int64_t length) { /* Set point we want to truncate file */ __int64 pos = _lseeki64(fd, (__int64)length, SEEK_SET); if (pos != (__int64)length) { errno = EACCES; /* truncation failed, get out */ return -1; } /* Truncate file */ if (SetEndOfFile((HANDLE)_get_osfhandle(fd)) == 0) { errno = b_errno_win32; return -1; } errno = 0; return 0; } int fcntl(int fd, int cmd, long arg) { int rval = 0; switch (cmd) { case F_GETFL: rval = O_NONBLOCK; break; case F_SETFL: rval = 0; break; default: errno = EINVAL; rval = -1; break; } return rval; } int lstat(const char *filename, struct stat *sb) { return stat(filename, sb); } void sleep(int sec) { Sleep(sec * 1000); } int geteuid(void) { return 0; } int execvp(const char *, char *[]) { errno = ENOSYS; return -1; } int fork(void) { errno = ENOSYS; return -1; } int pipe(int[]) { errno = ENOSYS; return -1; } int waitpid(int, int*, int) { errno = ENOSYS; return -1; } /* * Read contents of symbolic link */ ssize_t readlink(const char *path, char *buf, size_t bufsiz) { POOLMEM *slt = get_pool_memory(PM_NAME); Dmsg1(dbglvl, "readlink called for path %s\n", path); get_symlink_data(path, &slt); strncpy(buf, slt, bufsiz - 1); buf[bufsiz] = '\0'; free_pool_memory(slt); return strlen(buf); } /* * Create a directory symlink / file symlink/junction */ int win32_symlink(const char *name1, const char *name2, _dev_t st_rdev) { #if (_WIN32_WINNT >= 0x0600) int dwFlags = 0x0; if (st_rdev & FILE_ATTRIBUTES_JUNCTION_POINT){ Dmsg0(130, "We have a Junction Point \n"); if (!CreateJunction(name2, name1)) { return -1; } else { return 0; } } else if (st_rdev & FILE_ATTRIBUTE_VOLUME_MOUNT_POINT){ Dmsg0(130, "We have a Volume Mount Point \n"); return 0; } else if (st_rdev & FILE_ATTRIBUTES_SYMBOLIC_LINK) { Dmsg0(130, "We have a Directory Symbolic Link\n"); dwFlags = SYMBOLIC_LINK_FLAG_DIRECTORY; } else { Dmsg0(130, "We have a File Symbolic Link \n"); } Dmsg2(dbglvl, "symlink called name1=%s, name2=%s\n", name1, name2); if (!CreateSymbolicLink(const_cast(name2), const_cast(name1), dwFlags)) { Dmsg1(dbglvl, "CreateSymbolicLink failed:%s\n", errorString()); return -1; } else { return 0; } #else errno = ENOSYS; return -1; #endif } /* * Create a hardlink */ int link(const char *existing, const char *newfile) { errno = ENOSYS; return -1; } #ifndef HAVE_MINGW int strcasecmp(const char *s1, const char *s2) { register int ch1, ch2; if (s1 == s2) { return 0; /* strings are equal if same object. */ } else if (!s1) { return -1; } else if (!s2) { return 1; } do { ch1 = *s1; ch2 = *s2; s1++; s2++; } while (ch1 != 0 && tolower(ch1) == tolower(ch2)); return ch1 - ch2; } int strncasecmp(const char *s1, const char *s2, int len) { register int ch1 = 0, ch2 = 0; if (s1 == s2) { return 0; /* strings are equal if same object. */ } else if (!s1) { return -1; } else if (!s2) { return 1; } while (len--) { ch1 = *s1; ch2 = *s2; s1++; s2++; if (ch1 == 0 || tolower(ch1) != tolower(ch2)) { break; } } return ch1 - ch2; } int gettimeofday(struct timeval *tv, struct timezone *tz) { SYSTEMTIME now; FILETIME tmp; GetSystemTime(&now); if (tv == NULL) { errno = EINVAL; return -1; } if (!SystemTimeToFileTime(&now, &tmp)) { errno = b_errno_win32; return -1; } int64_t _100nsec = tmp.dwHighDateTime; _100nsec <<= 32; _100nsec |= tmp.dwLowDateTime; _100nsec -= WIN32_FILETIME_ADJUST; tv->tv_sec = (long)(_100nsec / 10000000); tv->tv_usec = (long)((_100nsec % 10000000)/10); return 0; } #else int gettimeofday(struct timeval *tv, struct timezone *tz) { return mingw_gettimeofday(tv, tz); } #endif //HAVE_MINGW /* * Write in Windows System log */ extern "C" void syslog(int type, const char *fmt, ...) { va_list arg_ptr; int len, maxlen; POOLMEM *msg; msg = get_pool_memory(PM_EMSG); for (;;) { maxlen = sizeof_pool_memory(msg) - 1; va_start(arg_ptr, fmt); len = bvsnprintf(msg, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { msg = realloc_pool_memory(msg, maxlen + maxlen/2); continue; } break; } LogErrorMsg((const char *)msg); free_memory(msg); } extern "C" void closelog() { } struct passwd *getpwuid(uid_t) { return NULL; } struct group *getgrgid(uid_t) { return NULL; } /* * Implement opendir/readdir/closedir on top of window's API */ typedef struct _dir { WIN32_FIND_DATAA data_a; /* window's file info (ansii version) */ WIN32_FIND_DATAW data_w; /* window's file info (wchar version) */ const char *spec; /* the directory we're traversing */ HANDLE dirh; /* the search handle */ BOOL valid_a; /* the info in data_a field is valid */ BOOL valid_w; /* the info in data_w field is valid */ UINT32 offset; /* pseudo offset for d_off */ } _dir; DIR *opendir(const char *path) { POOLMEM *win32_path; _dir *rval = NULL; if (path == NULL) { errno = ENOENT; return NULL; } Dmsg1(dbglvl, "Opendir path=%s\n", path); rval = (_dir *)malloc(sizeof(_dir)); memset (rval, 0, sizeof (_dir)); win32_path = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_path, path); Dmsg1(dbglvl, "win32 path=%s\n", win32_path); /* * Add backslash only if there is none yet (think of c:\) */ if (win32_path[strlen(win32_path) - 1] != '\\') { pm_strcat(win32_path, "\\*"); } else { pm_strcat(win32_path, "*"); } rval->spec = win32_path; /* * convert to wchar_t */ if (p_FindFirstFileW) { POOLMEM *pwcBuf; pwcBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwcBuf, rval->spec); rval->dirh = p_FindFirstFileW((LPCWSTR)pwcBuf, &rval->data_w); if (rval->dirh != INVALID_HANDLE_VALUE) { rval->valid_w = 1; } free_pool_memory(pwcBuf); } else if (p_FindFirstFileA) { rval->dirh = p_FindFirstFileA(rval->spec, &rval->data_a); if (rval->dirh != INVALID_HANDLE_VALUE) { rval->valid_a = 1; } } else { goto bail_out; } Dmsg3(dbglvl, "opendir(%s)\n\tspec=%s,\n\tFindFirstFile returns %d\n", path, rval->spec, rval->dirh); rval->offset = 0; if (rval->dirh == INVALID_HANDLE_VALUE) { goto bail_out; } if (rval->valid_w) { Dmsg1(dbglvl, "\tFirstFile=%s\n", rval->data_w.cFileName); } if (rval->valid_a) { Dmsg1(dbglvl, "\tFirstFile=%s\n", rval->data_a.cFileName); } return (DIR *)rval; bail_out: if (rval) { free(rval); } free_pool_memory(win32_path); errno = b_errno_win32; return NULL; } int closedir(DIR *dirp) { _dir *dp = (_dir *)dirp; FindClose(dp->dirh); free_pool_memory((POOLMEM *)dp->spec); free((void *)dp); return 0; } static int copyin(struct dirent &dp, const char *fname) { char *cp; dp.d_ino = 0; dp.d_reclen = 0; cp = dp.d_name; while (*fname) { *cp++ = *fname++; dp.d_reclen++; } *cp = 0; return dp.d_reclen; } int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { _dir *dp = (_dir *)dirp; if (dp->valid_w || dp->valid_a) { entry->d_off = dp->offset; // copy unicode if (dp->valid_w) { POOLMEM *szBuf; szBuf = get_pool_memory(PM_NAME); wchar_2_UTF8(&szBuf, dp->data_w.cFileName); dp->offset += copyin(*entry, szBuf); free_pool_memory(szBuf); } else if (dp->valid_a) { // copy ansi (only 1 will be valid) dp->offset += copyin(*entry, dp->data_a.cFileName); } *result = entry; /* return entry address */ Dmsg4(dbglvl, "readdir_r(%p, { d_name=\"%s\", d_reclen=%d, d_off=%d\n", dirp, entry->d_name, entry->d_reclen, entry->d_off); } else { errno = b_errno_win32; return -1; } /* * get next file, try unicode first */ if (p_FindNextFileW) { dp->valid_w = p_FindNextFileW(dp->dirh, &dp->data_w); } else if (p_FindNextFileA) { dp->valid_a = p_FindNextFileA(dp->dirh, &dp->data_a); } else { dp->valid_a = FALSE; dp->valid_w = FALSE; } return 0; } /* * Dotted IP address to network address * * Returns 1 if OK * 0 on error */ int inet_aton(const char *a, struct in_addr *inp) { const char *cp = a; uint32_t acc = 0, tmp = 0; int dotc = 0; if (!isdigit(*cp)) { /* first char must be digit */ return 0; /* error */ } do { if (isdigit(*cp)) { tmp = (tmp * 10) + (*cp -'0'); } else if (*cp == '.' || *cp == 0) { if (tmp > 255) { return 0; /* error */ } acc = (acc << 8) + tmp; dotc++; tmp = 0; } else { return 0; /* error */ } } while (*cp++ != 0); if (dotc != 4) { /* want 3 .'s plus EOS */ return 0; /* error */ } inp->s_addr = htonl(acc); /* store addr in network format */ return 1; } void init_signals(void terminate(int sig)) { } void init_stack_dump(void) { } long pathconf(const char *path, int name) { switch(name) { case _PC_PATH_MAX : if (strncmp(path, "\\\\?\\", 4) == 0) return 32767; case _PC_NAME_MAX : return 255; } errno = ENOSYS; return -1; } int WSA_Init(void) { WORD wVersionRequested = MAKEWORD( 1, 1); WSADATA wsaData; int err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("Can not start Windows Sockets\n"); errno = ENOSYS; return -1; } return 0; } static DWORD fill_attribute(DWORD attr, mode_t mode, _dev_t rdev) { bool compatible = false; Dmsg1(dbglvl, " before attr=%lld\n", (uint64_t) attr); /* * First see if there are any old encoded attributes in the mode. */ /* * If file is readable then this is not READONLY */ if (mode & (S_IRUSR|S_IRGRP|S_IROTH)) { attr &= ~FILE_ATTRIBUTE_READONLY; } else { attr |= FILE_ATTRIBUTE_READONLY; compatible = true; } /* * The sticky bit <=> HIDDEN */ if (mode & S_ISVTX) { attr |= FILE_ATTRIBUTE_HIDDEN; compatible = true; } else { attr &= ~FILE_ATTRIBUTE_HIDDEN; } /* * Other can read/write/execute ? * => Not system */ if (mode & S_IRWXO) { attr &= ~FILE_ATTRIBUTE_SYSTEM; } else { attr |= FILE_ATTRIBUTE_SYSTEM; compatible = true; } /* * See if there are any compatible mode settings in the to restore mode. * If so we don't trust the rdev setting as it is from an Bacula compatible * Filedaemon and as such doesn't encode the windows file flags in st_rdev * but uses st_rdev for marking reparse points. */ if (!compatible) { /* * Based on the setting of rdev restore any special file flags. */ if (rdev & FILE_ATTRIBUTE_READONLY) { attr |= FILE_ATTRIBUTE_READONLY; } else { attr &= ~FILE_ATTRIBUTE_READONLY; } if (rdev & FILE_ATTRIBUTE_HIDDEN) { attr |= FILE_ATTRIBUTE_HIDDEN; } else { attr &= ~FILE_ATTRIBUTE_HIDDEN; } if (rdev & FILE_ATTRIBUTE_SYSTEM) { attr |= FILE_ATTRIBUTE_SYSTEM; } else { attr &= ~FILE_ATTRIBUTE_SYSTEM; } if (rdev & FILE_ATTRIBUTE_ARCHIVE) { attr |= FILE_ATTRIBUTE_ARCHIVE; } else { attr &= ~FILE_ATTRIBUTE_ARCHIVE; } if (rdev & FILE_ATTRIBUTE_TEMPORARY) { attr |= FILE_ATTRIBUTE_TEMPORARY; } else { attr &= ~FILE_ATTRIBUTE_TEMPORARY; } if (rdev & FILE_ATTRIBUTE_OFFLINE) { attr |= FILE_ATTRIBUTE_OFFLINE; } else { attr &= ~FILE_ATTRIBUTE_OFFLINE; } if (rdev & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) { attr |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; } else { attr &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED; } } Dmsg1(dbglvl, " after attr=%lld\n", (uint64_t)attr); return attr; } int win32_chmod(const char *path, mode_t mode, _dev_t rdev) { bool ret = false; DWORD attr; Dmsg3(dbglvl, "win32_chmod(path=%s mode=%lld, rdev=%lld)\n", path, (uint64_t)mode, (uint64_t)rdev); if (p_GetFileAttributesW) { POOLMEM *pwszBuf; pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, path); attr = p_GetFileAttributesW((LPCWSTR) pwszBuf); if (attr != INVALID_FILE_ATTRIBUTES) { /* * Use Bareos mappings define in stat() above */ attr = fill_attribute(attr, mode, rdev); ret = p_SetFileAttributesW((LPCWSTR)pwszBuf, attr); } free_pool_memory(pwszBuf); Dmsg0(dbglvl, "Leave win32_chmod. AttributesW\n"); } else if (p_GetFileAttributesA) { attr = p_GetFileAttributesA(path); if (attr != INVALID_FILE_ATTRIBUTES) { attr = fill_attribute(attr, mode, rdev); ret = p_SetFileAttributesA(path, attr); } Dmsg0(dbglvl, "Leave win32_chmod did AttributesA\n"); } else { Dmsg0(dbglvl, "Leave win32_chmod did nothing\n"); } if (!ret) { const char *err = errorString(); Dmsg2(dbglvl, "Get/SetFileAttributes(%s): %s\n", path, err); LocalFree((void *)err); errno = b_errno_win32; return -1; } return 0; } int win32_chdir(const char *dir) { if (p_SetCurrentDirectoryW) { POOLMEM *pwszBuf; BOOL b; pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, dir); b = p_SetCurrentDirectoryW((LPCWSTR)pwszBuf); free_pool_memory(pwszBuf); if (!b) { errno = b_errno_win32; return -1; } } else if (p_SetCurrentDirectoryA) { if (0 == p_SetCurrentDirectoryA(dir)) { errno = b_errno_win32; return -1; } } else { return -1; } return 0; } int win32_mkdir(const char *dir) { Dmsg1(dbglvl, "enter win32_mkdir. dir=%s\n", dir); if (p_wmkdir){ int n; POOLMEM *pwszBuf; pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, dir); n = p_wmkdir((LPCWSTR)pwszBuf); free_pool_memory(pwszBuf); Dmsg0(dbglvl, "Leave win32_mkdir did wmkdir\n"); return n; } Dmsg0(dbglvl, "Leave win32_mkdir did _mkdir\n"); return _mkdir(dir); } char *win32_getcwd(char *buf, int maxlen) { int n = 0; if (p_GetCurrentDirectoryW) { POOLMEM *pwszBuf; pwszBuf = get_pool_memory(PM_FNAME); pwszBuf = check_pool_memory_size (pwszBuf, maxlen * sizeof(wchar_t)); n = p_GetCurrentDirectoryW(maxlen, (LPWSTR) pwszBuf); if (n != 0) { n = wchar_2_UTF8 (buf, (wchar_t *)pwszBuf, maxlen)-1; } free_pool_memory(pwszBuf); } else if (p_GetCurrentDirectoryA) { n = p_GetCurrentDirectoryA(maxlen, buf); } if (n <= 0 || n > maxlen) { return NULL; } if (n + 1 > maxlen) { return NULL; } if (n != 3) { buf[n] = '\\'; buf[n+1] = 0; } return buf; } int win32_fputs(const char *string, FILE *stream) { /* * We use WriteConsoleA / WriteConsoleA so we can be sure that unicode support * works on win32. with fallback if something fails */ HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE); if (hOut && (hOut != INVALID_HANDLE_VALUE) && p_WideCharToMultiByte && p_MultiByteToWideChar && (stream == stdout)) { POOLMEM *pwszBuf; POOLMEM *pszBuf; DWORD dwCharsWritten; DWORD dwChars; pwszBuf = get_pool_memory(PM_MESSAGE); dwChars = UTF8_2_wchar(&pwszBuf, string); /* * Try WriteConsoleW */ if (WriteConsoleW (hOut, pwszBuf, dwChars-1, &dwCharsWritten, NULL)) { free_pool_memory(pwszBuf); return dwCharsWritten; } /* * Convert to local codepage and try WriteConsoleA */ pszBuf = get_pool_memory(PM_MESSAGE); pszBuf = check_pool_memory_size(pszBuf, dwChars+1); dwChars = p_WideCharToMultiByte(GetConsoleOutputCP(), 0, (LPCWSTR)pwszBuf, -1, pszBuf, dwChars, NULL, NULL); free_pool_memory(pwszBuf); if (WriteConsoleA (hOut, pszBuf, dwChars-1, &dwCharsWritten, NULL)) { free_pool_memory(pszBuf); return dwCharsWritten; } free_pool_memory(pszBuf); } /* * Fall back */ return fputs(string, stream); } char *win32_cgets (char* buffer, int len) { /* * We use console ReadConsoleA / ReadConsoleW to be able to read unicode * from the win32 console and fallback if seomething fails */ HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE); if (hIn && (hIn != INVALID_HANDLE_VALUE) && p_WideCharToMultiByte && p_MultiByteToWideChar) { DWORD dwRead; wchar_t wszBuf[1024]; char szBuf[1024]; /* * NT and unicode conversion */ if (ReadConsoleW (hIn, wszBuf, 1024, &dwRead, NULL)) { /* * NULL terminate at end */ if (wszBuf[dwRead-1] == L'\n') { wszBuf[dwRead-1] = L'\0'; dwRead --; } if (wszBuf[dwRead-1] == L'\r') { wszBuf[dwRead-1] = L'\0'; dwRead --; } wchar_2_UTF8(buffer, wszBuf, len); return buffer; } /* * WIN 9x and unicode conversion */ if (ReadConsoleA (hIn, szBuf, 1024, &dwRead, NULL)) { /* * NULL terminate at end */ if (szBuf[dwRead-1] == L'\n') { szBuf[dwRead-1] = L'\0'; dwRead --; } if (szBuf[dwRead-1] == L'\r') { szBuf[dwRead-1] = L'\0'; dwRead --; } /* * Convert from ansii to wchar_t */ p_MultiByteToWideChar(GetConsoleCP(), 0, szBuf, -1, wszBuf,1024); /* * Convert from wchar_t to UTF-8 */ if (wchar_2_UTF8(buffer, wszBuf, len)) return buffer; } } /* * Fallback */ if (fgets(buffer, len, stdin)) return buffer; else return NULL; } int win32_unlink(const char *filename) { int nRetCode; if (p_wunlink) { POOLMEM *pwszBuf; pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); nRetCode = _wunlink((LPCWSTR) pwszBuf); /* * Special case if file is readonly, we retry but unset attribute before */ if (nRetCode == -1 && errno == EACCES && p_SetFileAttributesW && p_GetFileAttributesW) { DWORD dwAttr = p_GetFileAttributesW((LPCWSTR)pwszBuf); if (dwAttr != INVALID_FILE_ATTRIBUTES) { if (p_SetFileAttributesW((LPCWSTR)pwszBuf, dwAttr & ~FILE_ATTRIBUTE_READONLY)) { nRetCode = _wunlink((LPCWSTR) pwszBuf); /* reset to original if it didn't help */ if (nRetCode == -1) p_SetFileAttributesW((LPCWSTR)pwszBuf, dwAttr); } } } free_pool_memory(pwszBuf); } else { nRetCode = _unlink(filename); /* * Special case if file is readonly, we retry but unset attribute before */ if (nRetCode == -1 && errno == EACCES && p_SetFileAttributesA && p_GetFileAttributesA) { DWORD dwAttr = p_GetFileAttributesA(filename); if (dwAttr != INVALID_FILE_ATTRIBUTES) { if (p_SetFileAttributesA(filename, dwAttr & ~FILE_ATTRIBUTE_READONLY)) { nRetCode = _unlink(filename); /* * Reset to original if it didn't help */ if (nRetCode == -1) p_SetFileAttributesA(filename, dwAttr); } } } } return nRetCode; } /* * Define attributes that are legal to set with SetFileAttributes() */ #define SET_ATTRS ( \ FILE_ATTRIBUTE_ARCHIVE | \ FILE_ATTRIBUTE_HIDDEN | \ FILE_ATTRIBUTE_NORMAL | \ FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | \ FILE_ATTRIBUTE_OFFLINE | \ FILE_ATTRIBUTE_READONLY | \ FILE_ATTRIBUTE_SYSTEM | \ FILE_ATTRIBUTE_TEMPORARY) bool win32_restore_file_attributes(POOLMEM *ofname, HANDLE handle, WIN32_FILE_ATTRIBUTE_DATA *atts) { bool retval = false; Dmsg1(100, "SetFileAtts %s\n", ofname); if (!(atts->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (p_SetFileAttributesW) { BOOL b; POOLMEM *pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, ofname); b = p_SetFileAttributesW((LPCWSTR)pwszBuf, atts->dwFileAttributes & SET_ATTRS); free_pool_memory(pwszBuf); if (!b) { goto bail_out; } } else { BOOL b; POOLMEM *win32_ofile = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_ofile, ofname); b = p_SetFileAttributesA(win32_ofile, atts->dwFileAttributes & SET_ATTRS); free_pool_memory(win32_ofile); if (!b) { goto bail_out; } } } if (handle != INVALID_HANDLE_VALUE) { if (atts->dwFileAttributes & FILE_ATTRIBUTES_DEDUPED_ITEM) { Dmsg1(100, "File %s is a FILE_ATTRIBUTES_DEDUPED_ITEM\n", ofname); } /* * Restore the sparse file attribute on the restored file. */ if (atts->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { Dmsg1(100, "Restore FILE_ATTRIBUTE_SPARSE_FILE on %s\n", ofname); if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, NULL, NULL)) { goto bail_out; } } /* * Restore the compressed file attribute on the restored file. */ if (atts->dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) { USHORT format = COMPRESSION_FORMAT_DEFAULT; DWORD bytesreturned; Dmsg1(100, "Restore FILE_ATTRIBUTE_COMPRESSED on %s\n", ofname); if (!DeviceIoControl(handle, FSCTL_SET_COMPRESSION, &format, sizeof(format), NULL, 0, &bytesreturned, NULL)) { goto bail_out; } } /* * Restore file times on the restored file. */ Dmsg1(100, "SetFileTime %s\n", ofname); if (!SetFileTime(handle, &atts->ftCreationTime, &atts->ftLastAccessTime, &atts->ftLastWriteTime)) { goto bail_out; } } retval = true; bail_out: return retval; } #include "mswinver.h" char WIN_VERSION_LONG[64]; char WIN_VERSION[32]; char WIN_RAWVERSION[32]; class winver { public: winver(void); }; static winver INIT; /* Cause constructor to be called before main() */ winver::winver(void) { const char *version = ""; const char *platform = ""; OSVERSIONINFO osvinfo; osvinfo.dwOSVersionInfoSize = sizeof(osvinfo); /* * Get the current OS version */ if (!GetVersionEx(&osvinfo)) { version = "Unknown"; platform = "Unknown"; } const int ver = _mkversion(osvinfo.dwPlatformId, osvinfo.dwMajorVersion, osvinfo.dwMinorVersion); snprintf(WIN_RAWVERSION, sizeof(WIN_RAWVERSION), "Windows %#08x", ver); switch (ver) { case MS_WINDOWS_95: version = "Windows 95"; break; case MS_WINDOWS_98: version = "Windows 98"; break; case MS_WINDOWS_ME: version = "Windows ME"; break; case MS_WINDOWS_NT4: version = "Windows NT 4.0"; platform = "NT"; break; case MS_WINDOWS_2K: version = "Windows 2000"; platform = "NT"; break; case MS_WINDOWS_XP: version = "Windows XP"; platform = "NT"; break; case MS_WINDOWS_S2003: version = "Windows Server 2003"; platform = "NT"; break; default: version = WIN_RAWVERSION; break; } bstrncpy(WIN_VERSION_LONG, version, sizeof(WIN_VERSION_LONG)); snprintf(WIN_VERSION, sizeof(WIN_VERSION), "%s %lu.%lu.%lu", platform, osvinfo.dwMajorVersion, osvinfo.dwMinorVersion, osvinfo.dwBuildNumber); } BOOL CreateChildProcess(VOID); VOID WriteToPipe(VOID); VOID ReadFromPipe(VOID); VOID ErrorExit(LPCSTR); VOID ErrMsg(LPTSTR, BOOL); /** * Check for a quoted path, if an absolute path name is given and it contains * spaces it will need to be quoted. i.e. "c:/Program Files/foo/bar.exe" * CreateProcess() says the best way to ensure proper results with executables * with spaces in path or filename is to quote the string. */ const char *getArgv0(const char *cmdline) { int inquote = 0; const char *cp; for (cp = cmdline; *cp; cp++) { if (*cp == '"') { inquote = !inquote; } if (!inquote && isspace(*cp)) break; } int len = cp - cmdline; char *rval = (char *)malloc(len+1); cp = cmdline; char *rp = rval; while (len--) *rp++ = *cp++; *rp = 0; return rval; } /* * Extracts the executable or script name from the first string in cmdline. * * If the name contains blanks then it must be quoted with double quotes, * otherwise quotes are optional. If the name contains blanks then it * will be converted to a short name. * * The optional quotes will be removed. The result is copied to a malloc'ed * buffer and returned through the pexe argument. The pargs parameter is set * to the address of the character in cmdline located after the name. * * The malloc'ed buffer returned in *pexe must be freed by the caller. */ bool GetApplicationName(const char *cmdline, char **pexe, const char **pargs) { const char *pExeStart = NULL; /* Start of executable name in cmdline */ const char *pExeEnd = NULL; /* Character after executable name (separator) */ const char *pBasename = NULL; /* Character after last path separator */ const char *pExtension = NULL; /* Period at start of extension */ const char *current = cmdline; bool bQuoted = false; /* Skip initial whitespace */ while (*current == ' ' || *current == '\t') { current++; } /* Calculate start of name and determine if quoted */ if (*current == '"') { pExeStart = ++current; bQuoted = true; } else { pExeStart = current; bQuoted = false; } *pargs = NULL; *pexe = NULL; /* * Scan command line looking for path separators (/ and \\) and the * terminator, either a quote or a blank. The location of the * extension is also noted. */ for ( ; *current != '\0'; current++) { if (*current == '.') { pExtension = current; } else if (IsPathSeparator(*current) && current[1] != '\0') { pBasename = ¤t[1]; pExtension = NULL; } /* * Check for terminator, either quote or blank */ if (bQuoted) { if (*current != '"') { continue; } } else { if (*current != ' ') { continue; } } /* * Hit terminator, remember end of name (address of terminator) and start of arguments */ pExeEnd = current; if (bQuoted && *current == '"') { *pargs = ¤t[1]; } else { *pargs = current; } break; } if (pBasename == NULL) { pBasename = pExeStart; } if (pExeEnd == NULL) { pExeEnd = current; } if (*pargs == NULL) { *pargs = current; } bool bHasPathSeparators = pExeStart != pBasename; /* * We have pointers to all the useful parts of the name * Default extensions in the order cmd.exe uses to search */ static const char ExtensionList[][5] = { ".com", ".exe", ".bat", ".cmd" }; DWORD dwBasePathLength = pExeEnd - pExeStart; DWORD dwAltNameLength = 0; char *pPathname = (char *)alloca(MAX_PATHLENGTH + 1); char *pAltPathname = (char *)alloca(MAX_PATHLENGTH + 1); pPathname[MAX_PATHLENGTH] = '\0'; pAltPathname[MAX_PATHLENGTH] = '\0'; memcpy(pPathname, pExeStart, dwBasePathLength); pPathname[dwBasePathLength] = '\0'; if (pExtension == NULL) { /* * Try appending extensions */ for (int index = 0; index < (int)(sizeof(ExtensionList) / sizeof(ExtensionList[0])); index++) { if (!bHasPathSeparators) { /* * There are no path separators, search in the standard locations */ dwAltNameLength = SearchPath(NULL, pPathname, ExtensionList[index], MAX_PATHLENGTH, pAltPathname, NULL); if (dwAltNameLength > 0 && dwAltNameLength <= MAX_PATHLENGTH) { memcpy(pPathname, pAltPathname, dwAltNameLength); pPathname[dwAltNameLength] = '\0'; break; } } else { bstrncpy(&pPathname[dwBasePathLength], ExtensionList[index], MAX_PATHLENGTH - dwBasePathLength); if (GetFileAttributes(pPathname) != INVALID_FILE_ATTRIBUTES) { break; } pPathname[dwBasePathLength] = '\0'; } } } else if (!bHasPathSeparators) { /* * There are no path separators, search in the standard locations */ dwAltNameLength = SearchPath(NULL, pPathname, NULL, MAX_PATHLENGTH, pAltPathname, NULL); if (dwAltNameLength > 0 && dwAltNameLength < MAX_PATHLENGTH) { memcpy(pPathname, pAltPathname, dwAltNameLength); pPathname[dwAltNameLength] = '\0'; } } if (strchr(pPathname, ' ') != NULL) { dwAltNameLength = GetShortPathName(pPathname, pAltPathname, MAX_PATHLENGTH); if (dwAltNameLength > 0 && dwAltNameLength <= MAX_PATHLENGTH) { *pexe = (char *)malloc(dwAltNameLength + 1); if (*pexe == NULL) { return false; } memcpy(*pexe, pAltPathname, dwAltNameLength + 1); } } if (*pexe == NULL) { DWORD dwPathnameLength = strlen(pPathname); *pexe = (char *)malloc(dwPathnameLength + 1); if (*pexe == NULL) { return false; } memcpy(*pexe, pPathname, dwPathnameLength + 1); } return true; } /** * Create the process with WCHAR API */ static BOOL CreateChildProcessW(const char *comspec, const char *cmdLine, PROCESS_INFORMATION *hProcInfo, HANDLE in, HANDLE out, HANDLE err) { STARTUPINFOW siStartInfo; BOOL bFuncRetn = FALSE; POOLMEM *cmdLine_wchar, *comspec_wchar; /* * Setup members of the STARTUPINFO structure. */ ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); siStartInfo.cb = sizeof(siStartInfo); /* * Setup new process to use supplied handles for stdin,stdout,stderr */ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; siStartInfo.hStdInput = in; siStartInfo.hStdOutput = out; siStartInfo.hStdError = err; /* * Convert argument to WCHAR */ cmdLine_wchar = get_pool_memory(PM_FNAME); comspec_wchar = get_pool_memory(PM_FNAME); UTF8_2_wchar(&cmdLine_wchar, cmdLine); UTF8_2_wchar(&comspec_wchar, comspec); /* * Create the child process. */ Dmsg2(dbglvl, "Calling CreateProcess(%s, %s, ...)\n", comspec_wchar, cmdLine_wchar); /* * Try to execute program */ bFuncRetn = p_CreateProcessW((WCHAR*)comspec_wchar, (WCHAR*)cmdLine_wchar, /* Command line */ NULL, /* Process security attributes */ NULL, /* Primary thread security attributes */ TRUE, /* Handles are inherited */ 0, /* Creation flags */ NULL, /* Use parent's environment */ NULL, /* Use parent's current directory */ &siStartInfo, /* STARTUPINFO pointer */ hProcInfo); /* Receives PROCESS_INFORMATION */ free_pool_memory(cmdLine_wchar); free_pool_memory(comspec_wchar); return bFuncRetn; } /** * Create the process with ANSI API */ static BOOL CreateChildProcessA(const char *comspec, char *cmdLine, PROCESS_INFORMATION *hProcInfo, HANDLE in, HANDLE out, HANDLE err) { STARTUPINFOA siStartInfo; BOOL bFuncRetn = FALSE; /* * Set up members of the STARTUPINFO structure. */ ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); siStartInfo.cb = sizeof(siStartInfo); /* * setup new process to use supplied handles for stdin,stdout,stderr */ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; siStartInfo.hStdInput = in; siStartInfo.hStdOutput = out; siStartInfo.hStdError = err; /* * Create the child process. */ Dmsg2(dbglvl, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); /* * Try to execute program */ bFuncRetn = p_CreateProcessA(comspec, cmdLine, /* Command line */ NULL, /* Process security attributes */ NULL, /* Primary thread security attributes */ TRUE, /* Handles are inherited */ 0, /* Creation flags */ NULL, /* Use parent's environment */ NULL, /* Use parent's current directory */ &siStartInfo, /* STARTUPINFO pointer */ hProcInfo); /* Receives PROCESS_INFORMATION */ return bFuncRetn; } /** * OK, so it would seem CreateProcess only handles true executables: * .com or .exe files. So grab $COMSPEC value and pass command line to it. */ HANDLE CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err) { static const char *comspec = NULL; PROCESS_INFORMATION piProcInfo; BOOL bFuncRetn = FALSE; if (!p_CreateProcessA || !p_CreateProcessW) return INVALID_HANDLE_VALUE; if (comspec == NULL) comspec = getenv("COMSPEC"); if (comspec == NULL) // should never happen return INVALID_HANDLE_VALUE; /* * Set up members of the PROCESS_INFORMATION structure. */ ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); /* * if supplied handles are not used the send a copy of our STD_HANDLE as appropriate. */ if (in == INVALID_HANDLE_VALUE) in = GetStdHandle(STD_INPUT_HANDLE); if (out == INVALID_HANDLE_VALUE) out = GetStdHandle(STD_OUTPUT_HANDLE); if (err == INVALID_HANDLE_VALUE) err = GetStdHandle(STD_ERROR_HANDLE); char *exeFile; const char *argStart; if (!GetApplicationName(cmdline, &exeFile, &argStart)) { return INVALID_HANDLE_VALUE; } POOL_MEM cmdLine(PM_FNAME); Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart); free(exeFile); /* * New function disabled */ if (p_CreateProcessW && p_MultiByteToWideChar) { bFuncRetn = CreateChildProcessW(comspec, cmdLine.c_str(), &piProcInfo, in, out, err); } else { bFuncRetn = CreateChildProcessA(comspec, cmdLine.c_str(), &piProcInfo, in, out, err); } if (bFuncRetn == 0) { ErrorExit("CreateProcess failed\n"); const char *err = errorString(); Dmsg3(dbglvl, "CreateProcess(%s, %s, ...)=%s\n",comspec,cmdLine.c_str(),err); LocalFree((void *)err); return INVALID_HANDLE_VALUE; } /* * we don't need a handle on the process primary thread so we close this now. */ CloseHandle(piProcInfo.hThread); return piProcInfo.hProcess; } void ErrorExit (LPCSTR lpszMessage) { Dmsg1(0, "%s", lpszMessage); } static void CloseHandleIfValid(HANDLE handle) { if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); } } BPIPE *open_bpipe(char *prog, int wait, const char *mode) { int mode_read, mode_write; SECURITY_ATTRIBUTES saAttr; BOOL fSuccess; BPIPE *bpipe; HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup, hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup; hChildStdinRd = INVALID_HANDLE_VALUE; hChildStdinWr = INVALID_HANDLE_VALUE; hChildStdinWrDup = INVALID_HANDLE_VALUE; hChildStdoutRd = INVALID_HANDLE_VALUE; hChildStdoutWr = INVALID_HANDLE_VALUE; hChildStdoutRdDup = INVALID_HANDLE_VALUE; bpipe = (BPIPE *)malloc(sizeof(BPIPE)); memset((void *)bpipe, 0, sizeof(BPIPE)); mode_read = (mode[0] == 'r'); mode_write = (mode[0] == 'w' || mode[1] == 'w'); /* * Set the bInheritHandle flag so pipe handles are inherited. */ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (mode_read) { /* * Create a pipe for the child process's STDOUT. */ if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) { ErrorExit("Stdout pipe creation failed\n"); goto cleanup; } /* * Create noninheritable read handle and close the inheritable read handle. */ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup , 0, FALSE, DUPLICATE_SAME_ACCESS); if (!fSuccess) { ErrorExit("DuplicateHandle failed"); goto cleanup; } CloseHandle(hChildStdoutRd); hChildStdoutRd = INVALID_HANDLE_VALUE; } if (mode_write) { /* * Create a pipe for the child process's STDIN. */ if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) { ErrorExit("Stdin pipe creation failed\n"); goto cleanup; } /* * Duplicate the write handle to the pipe so it is not inherited. */ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, // not inherited DUPLICATE_SAME_ACCESS); if (!fSuccess) { ErrorExit("DuplicateHandle failed"); goto cleanup; } CloseHandle(hChildStdinWr); hChildStdinWr = INVALID_HANDLE_VALUE; } /* * Spawn program with redirected handles as appropriate */ bpipe->worker_pid = (pid_t) CreateChildProcess(prog, /* Commandline */ hChildStdinRd, /* stdin HANDLE */ hChildStdoutWr, /* stdout HANDLE */ hChildStdoutWr); /* stderr HANDLE */ if ((HANDLE) bpipe->worker_pid == INVALID_HANDLE_VALUE) goto cleanup; bpipe->wait = wait; bpipe->worker_stime = time(NULL); if (mode_read) { /* * Close our write side so when process terminates we can detect eof. */ CloseHandle(hChildStdoutWr); hChildStdoutWr = INVALID_HANDLE_VALUE; int rfd = _open_osfhandle((intptr_t)hChildStdoutRdDup, O_RDONLY | O_BINARY); if (rfd >= 0) { bpipe->rfd = _fdopen(rfd, "rb"); } } if (mode_write) { /* * Close our read side so to not interfere with child's copy. */ CloseHandle(hChildStdinRd); hChildStdinRd = INVALID_HANDLE_VALUE; int wfd = _open_osfhandle((intptr_t)hChildStdinWrDup, O_WRONLY | O_BINARY); if (wfd >= 0) { bpipe->wfd = _fdopen(wfd, "wb"); } } if (wait > 0) { bpipe->timer_id = start_child_timer(NULL, bpipe->worker_pid, wait); } return bpipe; cleanup: CloseHandleIfValid(hChildStdoutRd); CloseHandleIfValid(hChildStdoutWr); CloseHandleIfValid(hChildStdoutRdDup); CloseHandleIfValid(hChildStdinRd); CloseHandleIfValid(hChildStdinWr); CloseHandleIfValid(hChildStdinWrDup); free((void *)bpipe); errno = b_errno_win32; /* Do GetLastError() for error code */ return NULL; } int kill(int pid, int signal) { int rval = 0; if (!TerminateProcess((HANDLE)pid, (UINT) signal)) { rval = -1; errno = b_errno_win32; } CloseHandle((HANDLE)pid); return rval; } int close_bpipe(BPIPE *bpipe) { int rval = 0; int32_t remaining_wait = bpipe->wait; /* * Close pipes */ if (bpipe->rfd) { fclose(bpipe->rfd); bpipe->rfd = NULL; } if (bpipe->wfd) { fclose(bpipe->wfd); bpipe->wfd = NULL; } if (remaining_wait == 0) { /* Wait indefinitely */ remaining_wait = INT32_MAX; } for ( ;; ) { DWORD exitCode; if (!GetExitCodeProcess((HANDLE)bpipe->worker_pid, &exitCode)) { const char *err = errorString(); rval = b_errno_win32; Dmsg1(dbglvl, "GetExitCode error %s\n", err); LocalFree((void *)err); break; } if (exitCode == STILL_ACTIVE) { if (remaining_wait <= 0) { rval = ETIME; /* Timed out */ break; } bmicrosleep(1, 0); /* Wait one second */ remaining_wait--; } else if (exitCode != 0) { /* * Truncate exit code as it doesn't seem to be correct */ rval = (exitCode & 0xFF) | b_errno_exit; break; } else { break; /* Shouldn't get here */ } } if (bpipe->timer_id) { stop_child_timer(bpipe->timer_id); } if (bpipe->rfd) { fclose(bpipe->rfd); } if (bpipe->wfd) { fclose(bpipe->wfd); } free((void *)bpipe); return rval; } int close_wpipe(BPIPE *bpipe) { int result = 1; if (bpipe->wfd) { fflush(bpipe->wfd); if (fclose(bpipe->wfd) != 0) { result = 0; } bpipe->wfd = NULL; } return result; } #ifndef HAVE_MINGW int utime(const char *filename, struct utimbuf *times) { int rval = -1; FILETIME acc, mod; HANDLE h = INVALID_HANDLE_VALUE; cvt_utime_to_ftime(times->actime, acc); cvt_utime_to_ftime(times->modtime, mod); if (p_CreateFileW) { POOLMEM *pwszBuf; pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, filename); h = p_CreateFileW((LPCWSTR)pwszBuf, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, /* Required for directories */ NULL); free_pool_memory(pwszBuf); } else if (p_CreateFileA) { POOLMEM *win32_fname; win32_fname = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_fname, filename); h = p_CreateFileA(win32_fname, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, /* Required for directories */ NULL); free_pool_memory(win32_fname); } if (h == INVALID_HANDLE_VALUE) { const char *err = errorString(); Dmsg2(dbglvl, "Cannot open file \"%s\" for utime(): ERR=%s", filename, err); LocalFree((void *)err); errno = b_errno_win32; goto bail_out; } rval = SetFileTime(h, NULL, &acc, &mod) ? 0 : -1; CloseHandle(h); if (rval == -1) { errno = b_errno_win32; } bail_out: return rval; } #endif #ifdef HAVE_MINGW /* * Syslog function, added by Nicolas Boichat */ extern "C" void openlog(const char *ident, int option, int facility) { } #endif //HAVE_MINGW /* * Log an error message */ void LogErrorMsg(const char *message) { HANDLE eventHandler; const char *strings[2]; /* * Use the OS event logging to log the error */ strings[0] = _("\n\nBareos ERROR: "); strings[1] = message; eventHandler = RegisterEventSource(NULL, "Bareos"); if (eventHandler) { ReportEvent(eventHandler, EVENTLOG_ERROR_TYPE, 0, /* Category */ 0, /* ID */ NULL, /* SID */ 2, /* Number of strings */ 0, /* Raw data size */ (const char **)strings, /* Error strings */ NULL); /* Raw data */ DeregisterEventSource(eventHandler); } } /* * Don't allow OS to suspend while backup running * Note, the OS automatically tracks these for each thread */ void prevent_os_suspensions() { SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); } void allow_os_suspensions() { SetThreadExecutionState(ES_CONTINUOUS); } bareos-Release-14.2.6/src/win32/compat/include/000077500000000000000000000000001263011562700210775ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/alloca.h000066400000000000000000000000001263011562700224710ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/arpa/000077500000000000000000000000001263011562700220225ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/arpa/inet.h000066400000000000000000000000001263011562700231200ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/compat.h000066400000000000000000000244251263011562700225420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2004-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* -*- Mode: C -*- * compat.h -- */ // Copyright transferred from Raider Solutions, Inc to // Kern Sibbald and John Walker by express permission. // /* * Author : Christopher S. Hull * Created On : Fri Jan 30 13:00:51 2004 */ #if !defined(__COMPAT_H_) #define __COMPAT_H_ #if !defined(_STAT_H) #define _STAT_H /* don't pull in MinGW stat.h */ #endif #ifndef _STAT_DEFINED #define _STAT_DEFINED 1 /* don't pull in MinGW struct stat from wchar.h */ #endif #if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC8+ #pragma warning(disable : 4996) // Either disable all deprecation warnings, // #define _CRT_SECURE_NO_DEPRECATE // Or just turn off warnings about the newly deprecated CRT functions. #elif !defined(HAVE_MINGW) && !defined(HAVE_WXCONSOLE) #define __STDC__ 1 #endif #include #include #if defined(HAVE_MINGW) /* * MINGW uses __declspec while Microsoft Visual C uses _declspec so map all _declspec to __declspec */ #define _declspec __declspec #endif typedef struct _REPARSE_DATA_BUFFER { DWORD ReparseTag; WORD ReparseDataLength; WORD Reserved; union { struct { WORD SubstituteNameOffset; WORD SubstituteNameLength; WORD PrintNameOffset; WORD PrintNameLength; ULONG Flags; WCHAR PathBuffer[1]; } SymbolicLinkReparseBuffer; struct { WORD SubstituteNameOffset; WORD SubstituteNameLength; WORD PrintNameOffset; WORD PrintNameLength; WCHAR PathBuffer[1]; } MountPointReparseBuffer; struct { BYTE DataBuffer[1]; } GenericReparseBuffer; } DUMMYUNIONNAME; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; #include #ifdef _WIN64 #define GWL_USERDATA GWLP_USERDATA #endif #ifndef INT64 #define INT64 long long int #endif void sleep(int); typedef UINT32 key_t; #if defined(HAVE_MINGW) #if !defined(uid_t) typedef UINT32 uid_t; typedef UINT32 gid_t; #endif #else typedef UINT32 uid_t; typedef UINT32 gid_t; typedef UINT32 mode_t; typedef INT32 ssize_t; typedef UINT32 size_t; #define HAVE_SSIZE_T 1 #endif /* HAVE_MINGW */ struct dirent { uint64_t d_ino; uint32_t d_off; uint16_t d_reclen; char d_name[256]; }; typedef void DIR; #if !defined(__cplusplus) #if !defined(true) #define true 1 #endif #if !defined(false) #define false 0 #endif #endif #ifndef _TIMEZONE_DEFINED /* also in sys/time.h */ #define _TIMEZONE_DEFINED struct timezone { int foo; }; #endif #ifndef HAVE_MINGW int strcasecmp(const char*, const char *); #endif int gettimeofday(struct timeval *, struct timezone *); #if !defined(EETXTBUSY) #define EETXTBUSY 26 #endif #if !defined(ETIMEDOUT) #define ETIMEDOUT 55 #endif #if !defined(ENOMEDIUM) #define ENOMEDIUM 123 #endif #if !defined(ENODATA) #define ENODATA 61 #endif struct stat { _dev_t st_dev; uint64_t st_ino; uint16_t st_mode; int16_t st_nlink; uint32_t st_uid; uint32_t st_gid; _dev_t st_rdev; uint64_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; uint32_t st_blksize; uint64_t st_blocks; }; #undef S_IFMT #define S_IFMT 0170000 /* file type mask */ #undef S_IFDIR #define S_IFDIR 0040000 /* directory */ #define S_IFCHR 0020000 /* character special */ #define S_IFBLK 0060000 /* block special */ #define S_IFIFO 0010000 /* pipe */ #undef S_IFREG #define S_IFREG 0100000 /* regular */ #undef S_IFLNK #define S_IFLNK 0120000 /* symbolic link */ #define S_IREAD 0000400 /* read permission, owner */ #define S_IWRITE 0000200 /* write permission, owner */ #define S_IEXEC 0000100 /* execute/search permission, owner */ #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #define S_IXUSR S_IEXEC #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) #define S_ISCHR(x) 0 #define S_ISBLK(x) (((x) & S_IFMT) == S_IFBLK) #define S_ISFIFO(x) 0 #define S_IRGRP 000040 #define S_IWGRP 000020 #define S_IXGRP 000010 #define S_IROTH 00004 #define S_IWOTH 00002 #define S_IXOTH 00001 #define S_IRWXO 000007 #define S_IRWXG 000070 #define S_ISUID 004000 #define S_ISGID 002000 #define S_ISVTX 001000 #define S_ISSOCK(x) 0 #if __STDC__ #define O_RDONLY _O_RDONLY #define O_WRONLY _O_WRONLY #define O_RDWR _O_RDWR #define O_CREAT _O_CREAT #define O_TRUNC _O_TRUNC #ifndef O_NOFOLLOW #define O_NOFOLLOW 0x80000 #endif #define isascii __isascii #define toascii __toascii #define iscsymf __iscsymf #define iscsym __iscsym #endif typedef bool (*t_pVSSPathConvert)(const char *szFilePath, char *szShadowPath, int nBuflen); typedef bool (*t_pVSSPathConvertW)(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen); void SetVSSPathConvert(t_pVSSPathConvert pPathConvert, t_pVSSPathConvertW pPathConvertW); int lchown(const char *, uid_t uid, gid_t gid); int chown(const char *, uid_t uid, gid_t gid); #define O_NONBLOCK 04000 #define F_GETFL 3 #define F_SETFL 4 #ifndef MINGW64 #define open _open #endif int fcntl(int fd, int cmd, long arg); int fstat(intptr_t fd, struct stat *sb); int inet_aton(const char *cp, struct in_addr *inp); int kill(int pid, int signo); int pipe(int []); int fork(); int waitpid(int, int *, int); #if !defined(HAVE_MINGW) #define strncasecmp strnicmp //int strncasecmp(const char*, const char *, int); int utime(const char *filename, struct utimbuf *buf); #define vsnprintf _vsnprintf #define snprintf _snprintf #endif //HAVE_MINGW #define WNOHANG 0 #define WIFEXITED(x) 0 #define WEXITSTATUS(x) x #define WIFSIGNALED(x) 0 #define WTERMSIG(x) x #define SIGKILL 9 #define SIGUSR2 9999 #define HAVE_OLD_SOCKOPT struct timespec; int readdir(unsigned int fd, struct dirent *dirp, unsigned int count); int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); long int random(void); void srandom(unsigned int seed); int lstat(const char *filename, struct stat *sb); int stat(const char *file, struct stat *sb); long pathconf(const char *path, int name); ssize_t readlink(const char *path, char *buf, size_t bufsiz); int win32_symlink(const char *name1, const char *name2, _dev_t st_rdev); int link(const char *existing, const char *newfile); #define _PC_PATH_MAX 1 #define _PC_NAME_MAX 2 int geteuid(); DIR *opendir(const char *filename); int closedir(DIR *dir); struct passwd { char *foo; }; struct group { char *foo; }; struct passwd *getpwuid(uid_t); struct group *getgrgid(uid_t); struct sigaction { int sa_flags; void (*sa_handler)(int); }; #define sigfillset(x) #define sigaction(a, b, c) #define mkdir(p, m) win32_mkdir(p) #define unlink win32_unlink #define chdir win32_chdir extern "C" void syslog(int type, const char *fmt, ...); #if !defined(LOG_DAEMON) #define LOG_DAEMON 0 #endif #if !defined(HAVE_MINGW) #define R_OK 04 #define W_OK 02 int stat(const char *, struct stat *); #if defined(__cplusplus) #define access _access extern "C" _CRTIMP int __cdecl _access(const char *, int); int execvp(const char *, char *[]); extern "C" void * __cdecl _alloca(size_t); #endif #endif //HAVE_MINGW #define getpid _getpid #define getppid() 0 #define gethostid() 0 #define getuid() 0 #define getgid() 0 #define getcwd win32_getcwd #define chdir win32_chdir #define fputs win32_fputs char *win32_getcwd(char *buf, int maxlen); int win32_chdir(const char *buf); int win32_mkdir(const char *buf); int win32_fputs(const char *string, FILE *stream); int win32_unlink(const char *filename); int win32_chmod(const char *, mode_t, _dev_t); char* win32_cgets (char* buffer, int len); int WSA_Init(void); void Win32ClearCompatible(); void Win32SetCompatible(); bool Win32IsCompatible(); void Win32ConvCleanupCache(); #if defined(HAVE_MINGW) void closelog(); void openlog(const char *ident, int option, int facility); #endif //HAVE_MINGW /* Don't let OS go to sleep (usually a Laptop) while we are backing up */ void prevent_os_suspensions(); void allow_os_suspensions(); typedef DWORD EXECUTION_STATE; #ifndef ES_CONTINUOUS #define ES_CONTINUOUS 0x80000000 #endif #ifndef ES_SYSTEM_REQUIRED #define ES_SYSTEM_REQUIRED 0x00000001 #endif #ifndef ES_DISPLAY_REQUIRED #define ES_DISPLAY_REQUIRED 0x00000002 #endif #ifndef ES_USER_PRESENT #define ES_USER_PRESENT 0x00000004 #endif WINBASEAPI EXECUTION_STATE WINAPI SetThreadExecutionState(EXECUTION_STATE esFlags); extern void LogErrorMsg(const char *message); #if !defined(INVALID_FILE_ATTRIBUTES) #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif #if defined(_MSC_VER) inline unsigned long ffs(unsigned long word) { unsigned long index; if (_BitScanForward(&index, word) != 0) return index + 1; else return 0; } #else #define ffs __builtin_ffs #endif bool win32_get_vmp_devicename(const char *filename, POOLMEM **device); int win32_ftruncate(int fd, int64_t length); bool win32_restore_file_attributes(POOLMEM *ofname, HANDLE handle, WIN32_FILE_ATTRIBUTE_DATA *atts); #undef ftruncate #define ftruncate win32_ftruncate #define FILE_ATTRIBUTE_VOLUME_MOUNT_POINT 0x10000000 #define FILE_ATTRIBUTES_JUNCTION_POINT 0x20000000 #define FILE_ATTRIBUTES_DEDUPED_ITEM 0x40000000 #define FILE_ATTRIBUTES_SYMBOLIC_LINK 0x80000000 #ifndef IO_REPARSE_TAG_DEDUP #define IO_REPARSE_TAG_DEDUP (0x80000013) #endif #endif /* __COMPAT_H_ */ bareos-Release-14.2.6/src/win32/compat/include/dirent.h000066400000000000000000000000001263011562700225230ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/dlfcn.h000066400000000000000000000027411263011562700223420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2008-2008 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Written by Kern Sibbald, February 2008 */ #ifndef __DLFCN_H_ #define __DLFCN_H_ #define RTLD_LAZY 0x00001 /* Deferred function binding */ #define RTLD_NOW 0x00002 /* Immediate function binding */ #define RTLD_NOLOAD 0x00004 /* Don't load object */ #define RTLD_GLOBAL 0x00100 /* Export symbols to others */ #define RTLD_LOCAL 0x00000 /* Symbols are only available to group members */ void *dlopen(const char *file, int mode); void *dlsym(void *handle, const char *name); int dlclose(void *handle); char *dlerror(void); #endif /* __DLFCN_H_ */ bareos-Release-14.2.6/src/win32/compat/include/getopt.h000066400000000000000000000024101263011562700225470ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2007 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, September, MMVII * * Written from man page definitions */ #ifndef _GETOPT_H_ #define _GETOPT_H_ #ifdef __cplusplus extern "C" { #endif int getopt(int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt; #ifdef __cplusplus } #endif #endif /* _GETOPT_H_ */ bareos-Release-14.2.6/src/win32/compat/include/grp.h000066400000000000000000000000001263011562700220260ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/mingwconfig.h000066400000000000000000000304561263011562700235670ustar00rootroot00000000000000/* ------------------------------------------------------------------------- */ /* -- CONFIGURE SPECIFIED FEATURES -- */ /* ------------------------------------------------------------------------- */ #ifndef __MINGWCONFIG_H #define __MINGWCONFIG_H /* Define if you want SmartAlloc debug code enabled */ #define SMARTALLOC 1 /* Define if you want to use Batch Mode */ /* #define HAVE_BATCH_FILE_INSERT 1 */ /* Define if you need function prototypes */ #define PROTOTYPES 1 /* Define if you have GCC */ #define HAVE_GCC 1 /* Define to 1 if utime.h exists and declares struct utimbuf. */ #define HAVE_UTIME_H 1 /* Data types */ #define HAVE_U_INT 1 #define HAVE_INTXX_T 1 #define HAVE_U_INTXX_T 1 /* #undef HAVE_UINTXX_T */ #define HAVE_INT64_T 1 #define HAVE_U_INT64_T 1 #define HAVE_UINT64_T 1 #define HAVE_INTMAX_T 1 /* #undef HAVE_U_INTMAX_T */ #define HAVE_UINTPTR_T 1 #define HAVE_INTPTR_T 1 /* Define if you want TCP Wrappers support */ /* #undef HAVE_LIBWRAP */ /* Define if you have sys/bitypes.h */ /* #undef HAVE_SYS_BITYPES_H */ /* Define if you have zlib */ #define HAVE_LIBZ 1 /* Define if you have lzo lib */ #define HAVE_LZO 1 /* Define to 1 if you have the header file. */ #define HAVE_LZO_LZOCONF_H 1 /* Define if you have fastlz lib */ #define HAVE_FASTLZ 1 /* File daemon specif libraries */ #define FDLIBS 1 /* What kind of signals we have */ /*#define HAVE_POSIX_SIGNALS 1 */ /* #undef HAVE_BSD_SIGNALS */ /* #undef HAVE_USG_SIGHOLD */ /* Set to correct scanf value for long long int */ #define lld "lld" #define llu "llu" /* #define USE_BSNPRINTF */ #define HAVE_STRTOLL 1 /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 #ifndef HAVE_MINGW #define alloca _alloca #endif /* Define to 1 if you have the header file, and it defines `DIR'. */ #define HAVE_DIRENT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `getcwd' function. */ #define HAVE_GETCWD 1 /* Define to 1 if you have the `gethostid' function. */ #define HAVE_GETHOSTID 1 /* Define to 1 if you have the `gethostname' function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the `getmntent' function. */ /*#define HAVE_GETMNTENT 1 */ /* Define to 1 if you have the `getpid' function. */ #define HAVE_GETPID 1 #define getpid _getpid /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the header file. */ /*#define HAVE_GRP_H 1*/ /* Define to 1 if you have the `inet_pton' function. */ /* #undef HAVE_INET_PTON */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `lchown' function. */ #define HAVE_LCHOWN 1 /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define to 1 if you have the `localtime_r' function. */ #define HAVE_LOCALTIME_R 1 /* Define to 1 if you have the `lstat' function. */ #define HAVE_LSTAT 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_MTIO_H */ /* Define to 1 if you have the `nanosleep' function. */ /* #undef HAVE_NANOSLEEP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_PWD_H */ /* Define to 1 if you have the `readdir_r' function. */ /* #undef HAVE_READDIR_R */ /* Define to 1 if you have the header file. */ /* #undef HAVE_RESOLV_H */ /* Define to 1 if you have the `select' function. */ #define HAVE_SELECT 1 /* Define to 1 if you have the `setenv' function. */ /* #undef HAVE_SETENV */ /* Define to 1 if you have the `putenv' function. */ #define HAVE_PUTENV 1 /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if translation of program messages to the user's native language is requested. */ #if (defined _MSC_VER) && (_MSC_VER >= 1400) // VC8+ /* Enable NLS only if we are using the new VC++. * NLS should also work with VC++ 7.1, but the Makefiles are * not adapted to support it (include, lib...). */ #define ENABLE_NLS 1 #endif #undef LOCALEDIR #define LOCALEDIR "." #undef HAVE_NL_LANGINFO /* Define to 1 if you have the `setpgid' function. */ #define HAVE_SETPGID 1 /* Define to 1 if you have the `setpgrp' function. */ #define HAVE_SETPGRP 1 /* Define to 1 if you have the `setsid' function. */ #define HAVE_SETSID 1 /* Define to 1 if you have the `signal' function. */ /*#define HAVE_SIGNAL 1 */ /* Define to 1 if you have the `snprintf' function. */ #define HAVE_SNPRINTF 1 /* Define to 1 if you have the header file. */ #define HAVE_STDARG_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strcasecmp' function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the `strerror' function. */ #define HAVE_STRERROR 1 /* Define to 1 if you have the `strerror_r' function. */ #define HAVE_STRERROR_R 1 /* Define to 1 if you have the `strftime' function. */ #define HAVE_STRFTIME 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strncmp' function. */ #define HAVE_STRNCMP 1 /* Define to 1 if you have the `strncpy' function. */ #define HAVE_STRNCPY 1 /* Define to 1 if you have the `strtoll' function. */ #define HAVE_STRTOLL 1 /* Define to 1 if `st_blksize' is member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 /* Define to 1 if `st_blocks' is member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_BLOCKS 1 /* Define to 1 if `st_rdev' is member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_RDEV 1 /* Define to 1 if `tm_zone' is member of `struct tm'. */ /* #undef HAVE_STRUCT_TM_TM_ZONE */ /* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ #define HAVE_ST_BLKSIZE 1 /* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ #define HAVE_ST_BLOCKS 1 /* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use `HAVE_STRUCT_STAT_ST_RDEV' instead. */ #define HAVE_ST_RDEV 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_BYTEORDER_H */ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_DIR_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_MTIO_H 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_NDIR_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SOCKIO_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to 1 if you have the `tcgetattr' function. */ #define HAVE_TCGETATTR 1 /* Define to 1 if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use `HAVE_STRUCT_TM_TM_ZONE' instead. */ /* #undef HAVE_TM_ZONE */ /* Define to 1 if you don't have `tm_zone' but do have the external array `tzname'. */ #define HAVE_TZNAME 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_VARARGS_H */ /* Define to 1 if you have the `vfprintf' function. */ #define HAVE_VFPRINTF 1 /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Define to 1 if you have the `vsnprintf' function. */ #define HAVE_VSNPRINTF 1 /* Define to 1 if you have the header file. */ #define HAVE_ZLIB_H 1 /* Define to 1 if `major', `minor', and `makedev' are declared in . */ /* #undef MAJOR_IN_MKDEV */ /* Define to 1 if `major', `minor', and `makedev' are declared in . */ /* #undef MAJOR_IN_SYSMACROS */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "" /* Define to the version of this package. */ #define PACKAGE_VERSION "" /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to 1 if the `setpgrp' function takes no argument. */ #define SETPGRP_VOID 1 /* The size of a `char', as computed by sizeof. */ #define SIZEOF_CHAR 1 /* The size of a `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of a `int *', as computed by sizeof. */ #define SIZEOF_INT_P 4 /* The size of a `long int', as computed by sizeof. */ #define SIZEOF_LONG_INT 4 /* The size of a `long long int', as computed by sizeof. */ #define SIZEOF_LONG_LONG_INT 8 /* The size of a `short int', as computed by sizeof. */ #define SIZEOF_SHORT_INT 2 /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to 1 if your declares `struct tm'. */ /* #undef TM_IN_SYS_TIME */ /* Use long unsigned int for ioctl request */ #define HAVE_IOCTL_ULINT_REQUEST /* For now, we only support Little endian on Win32 */ #define HAVE_LITTLE_ENDIAN 1 /* Number of bits in a file offset, on hosts where this is settable. */ #define _FILE_OFFSET_BITS 64 /* Define to make fseeko etc. visible, on some hosts. */ #define _LARGEFILE_SOURCE 1 /* Define for large files, on AIX-style hosts. */ #define _LARGE_FILES 1 /* Define to 1 if encryption support should be enabled */ #define HAVE_CRYPTO 1 /* Define to 1 if TLS support should be enabled */ #define HAVE_TLS 1 /* Define to 1 if OpenSSL library is available */ #define HAVE_OPENSSL 1 /* Define to 1 if IPv6 support should be enabled */ #define HAVE_IPV6 1 /* Define to 1 if you have the `getaddrinfo' function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if you have the `__builtin_va_copy' function. */ #define HAVE___BUILTIN_VA_COPY 1 /* Define to 1 if readline support should be enabled */ #define HAVE_READLINE 1 /* Directory for PID files */ #define _PATH_BAREOS_PIDDIR "%TEMP%" /* Directory for daemon files */ #define _PATH_BAREOS_WORKINGDIR "%TEMP%" /* Directory for backend drivers */ #define _PATH_BAREOS_BACKENDDIR "." /* Define to 1 if dynamic loading of catalog backends is enabled */ #define HAVE_DYNAMIC_CATS_BACKENDS 1 /* Define to 1 if DB batch insert code enabled */ #define USE_BATCH_FILE_INSERT 1 /* Set if you have an SQLite3 Database */ #define HAVE_SQLITE3 1 /* Define to 1 if you have the `sqlite3_threadsafe' function. */ #define HAVE_SQLITE3_THREADSAFE 1 /* Set if you have an PostgreSQL Database */ #define HAVE_POSTGRESQL 1 /* Set if PostgreSQL DB batch insert code enabled */ #define HAVE_POSTGRESQL_BATCH_FILE_INSERT 1 /* Set if have PQisthreadsafe */ #define HAVE_PQISTHREADSAFE 1 /* Define to 1 if LMDB support should be enabled */ #define HAVE_LMDB 1 #endif /* __MINGWNCONFIG_H */ bareos-Release-14.2.6/src/win32/compat/include/ms_atl.h000066400000000000000000000012751263011562700225340ustar00rootroot00000000000000/* * Minimal replacement for class CComPtr and CComBSTR * Based on common public IUnknown interface only */ template class CComPtr { public: /* Attribute(s) ... */ T* p; /* Creation ... */ CComPtr() { p = NULL; } /* Destructor ... */ ~CComPtr() { if (p) p->Release(); } }; class CComBSTR { public: BSTR p; /* Creation ... */ CComBSTR() { p = NULL; } /* Destructor ... */ ~CComBSTR() { ::SysFreeString(p); } /* Address-of operator */ BSTR* operator&() { return &p; } }; bareos-Release-14.2.6/src/win32/compat/include/mswinver.h000066400000000000000000000024511263011562700231240ustar00rootroot00000000000000#ifndef __MSWINVER_H_ #define __MSWINVER_H_ #define MS_MAJOR_WINDOWS_3 3 #define MS_MAJOR_WINDOWS_95 4 #define MS_MAJOR_WINDOWS_98 4 #define MS_MAJOR_WINDOWS_ME 4 #define MS_MAJOR_WINDOWS_NT4 4 #define MS_MAJOR_WINDOWS_2K 5 #define MS_MAJOR_WINDOWS_XP 5 #define MS_MAJOR_WINDOWS_S2003 5 #define MS_MINOR_WINDOWS_3 51 #define MS_MINOR_WINDOWS_95 0 #define MS_MINOR_WINDOWS_98 10 #define MS_MINOR_WINDOWS_ME 90 #define MS_MINOR_WINDOWS_NT4 0 #define MS_MINOR_WINDOWS_2K 0 #define MS_MINOR_WINDOWS_XP 1 #define MS_MINOR_WINDOWS_S2003 2 #define _mkversion(p, m, r) (((p)<<24)|((m)<<8)|(r)) #define MS_WINDOWS_95 _mkversion(VER_PLATFORM_WIN32_WINDOWS, MS_MAJOR_WINDOWS_95, MS_MINOR_WINDOWS_95) #define MS_WINDOWS_98 _mkversion(VER_PLATFORM_WIN32_WINDOWS, MS_MAJOR_WINDOWS_98, MS_MINOR_WINDOWS_98) #define MS_WINDOWS_ME _mkversion(VER_PLATFORM_WIN32_WINDOWS, MS_MAJOR_WINDOWS_ME, MS_MINOR_WINDOWS_ME) #define MS_WINDOWS_NT4 _mkversion(VER_PLATFORM_WIN32_NT, MS_MAJOR_WINDOWS_NT4, MS_MINOR_WINDOWS_NT4) #define MS_WINDOWS_2K _mkversion(VER_PLATFORM_WIN32_NT, MS_MAJOR_WINDOWS_2K, MS_MINOR_WINDOWS_2K) #define MS_WINDOWS_XP _mkversion(VER_PLATFORM_WIN32_NT, MS_MAJOR_WINDOWS_XP, MS_MINOR_WINDOWS_XP) #define MS_WINDOWS_S2003 _mkversion(VER_PLATFORM_WIN32_NT, MS_MAJOR_WINDOWS_S2003, MS_MINOR_WINDOWS_S2003) #endif bareos-Release-14.2.6/src/win32/compat/include/netdb.h000066400000000000000000000000001263011562700223320ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/netinet/000077500000000000000000000000001263011562700225455ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/netinet/in.h000066400000000000000000000000001263011562700233120ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/netinet/tcp.h000066400000000000000000000000001263011562700234720ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/pwd.h000066400000000000000000000000001263011562700220300ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/stdint.h000066400000000000000000000000661263011562700225570ustar00rootroot00000000000000#if defined(__GNUC__) #include_next #endif bareos-Release-14.2.6/src/win32/compat/include/strings.h000066400000000000000000000000001263011562700227270ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/sys/000077500000000000000000000000001263011562700217155ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/sys/file.h000066400000000000000000000000251263011562700230020ustar00rootroot00000000000000 #include "compat.h" bareos-Release-14.2.6/src/win32/compat/include/sys/ioctl.h000066400000000000000000000000761263011562700232030ustar00rootroot00000000000000extern int ioctl(int __fd, unsigned long int __request, ...); bareos-Release-14.2.6/src/win32/compat/include/sys/mtio.h000066400000000000000000000257361263011562700230530ustar00rootroot00000000000000/* Structures and definitions for magnetic tape I/O control commands. Copyright (C) 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C 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. The GNU C 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 the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* Written by H. Bergman . */ #ifndef _SYS_MTIO_H #define _SYS_MTIO_H 1 /* Get necessary definitions from system and kernel headers. */ #include #include /* Structure for MTIOCTOP - magnetic tape operation command. */ struct mtop { short int mt_op; /* Operations defined below. */ int mt_count; /* How many of them. */ }; #define _IOT_mtop /* Hurd ioctl type field. */ \ _IOT (_IOTS (short), 1, _IOTS (int), 1, 0, 0) /* Magnetic Tape operations [Not all operations supported by all drivers]. */ #define MTRESET 0 /* +reset drive in case of problems. */ #define MTFSF 1 /* Forward space over FileMark, * position at first record of next file. */ #define MTBSF 2 /* Backward space FileMark (position before FM). */ #define MTFSR 3 /* Forward space record. */ #define MTBSR 4 /* Backward space record. */ #define MTWEOF 5 /* Write an end-of-file record (mark). */ #define MTREW 6 /* Rewind. */ #define MTOFFL 7 /* Rewind and put the drive offline (eject?). */ #define MTNOP 8 /* No op, set status only (read with MTIOCGET). */ #define MTRETEN 9 /* Retension tape. */ #define MTBSFM 10 /* +backward space FileMark, position at FM. */ #define MTFSFM 11 /* +forward space FileMark, position at FM. */ #define MTEOM 12 /* Goto end of recorded media (for appending files). MTEOM positions after the last FM, ready for appending another file. */ #define MTERASE 13 /* Erase tape -- be careful! */ #define MTRAS1 14 /* Run self test 1 (nondestructive). */ #define MTRAS2 15 /* Run self test 2 (destructive). */ #define MTRAS3 16 /* Reserved for self test 3. */ #define MTSETBLK 20 /* Set block length (SCSI). */ #define MTSETDENSITY 21 /* Set tape density (SCSI). */ #define MTSEEK 22 /* Seek to block (Tandberg, etc.). */ #define MTTELL 23 /* Tell block (Tandberg, etc.). */ #define MTSETDRVBUFFER 24 /* Set the drive buffering according to SCSI-2. Ordinary buffered operation with code 1. */ #define MTFSS 25 /* Space forward over setmarks. */ #define MTBSS 26 /* Space backward over setmarks. */ #define MTWSM 27 /* Write setmarks. */ #define MTLOCK 28 /* Lock the drive door. */ #define MTUNLOCK 29 /* Unlock the drive door. */ #define MTLOAD 30 /* Execute the SCSI load command. */ #define MTUNLOAD 31 /* Execute the SCSI unload command. */ #define MTCOMPRESSION 32/* Control compression with SCSI mode page 15. */ #define MTSETPART 33 /* Change the active tape partition. */ #define MTMKPART 34 /* Format the tape with one or two partitions. */ /* structure for MTIOCGET - mag tape get status command */ struct mtget { long int mt_type; /* Type of magtape device. */ long int mt_resid; /* Residual count: (not sure) number of bytes ignored, or number of files not skipped, or number of records not skipped. */ /* The following registers are device dependent. */ long int mt_dsreg; /* Status register. */ long int mt_gstat; /* Generic (device independent) status. */ long int mt_erreg; /* Error register. */ /* The next two fields are not always used. */ __daddr_t mt_fileno; /* Number of current file on tape. */ __daddr_t mt_blkno; /* Current block number. */ }; #define _IOT_mtget /* Hurd ioctl type field. */ \ _IOT (_IOTS (long), 7, 0, 0, 0, 0) /* Constants for mt_type. Not all of these are supported, and these are not all of the ones that are supported. */ #define MT_ISUNKNOWN 0x01 #define MT_ISQIC02 0x02 /* Generic QIC-02 tape streamer. */ #define MT_ISWT5150 0x03 /* Wangtek 5150EQ, QIC-150, QIC-02. */ #define MT_ISARCHIVE_5945L2 0x04 /* Archive 5945L-2, QIC-24, QIC-02?. */ #define MT_ISCMSJ500 0x05 /* CMS Jumbo 500 (QIC-02?). */ #define MT_ISTDC3610 0x06 /* Tandberg 6310, QIC-24. */ #define MT_ISARCHIVE_VP60I 0x07 /* Archive VP60i, QIC-02. */ #define MT_ISARCHIVE_2150L 0x08 /* Archive Viper 2150L. */ #define MT_ISARCHIVE_2060L 0x09 /* Archive Viper 2060L. */ #define MT_ISARCHIVESC499 0x0A /* Archive SC-499 QIC-36 controller. */ #define MT_ISQIC02_ALL_FEATURES 0x0F /* Generic QIC-02 with all features. */ #define MT_ISWT5099EEN24 0x11 /* Wangtek 5099-een24, 60MB, QIC-24. */ #define MT_ISTEAC_MT2ST 0x12 /* Teac MT-2ST 155mb drive, Teac DC-1 card (Wangtek type). */ #define MT_ISEVEREX_FT40A 0x32 /* Everex FT40A (QIC-40). */ #define MT_ISDDS1 0x51 /* DDS device without partitions. */ #define MT_ISDDS2 0x52 /* DDS device with partitions. */ #define MT_ISSCSI1 0x71 /* Generic ANSI SCSI-1 tape unit. */ #define MT_ISSCSI2 0x72 /* Generic ANSI SCSI-2 tape unit. */ /* QIC-40/80/3010/3020 ftape supported drives. 20bit vendor ID + 0x800000 (see vendors.h in ftape distribution). */ #define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */ #define MT_ISFTAPE_FLAG 0x800000 struct mt_tape_info { long int t_type; /* Device type id (mt_type). */ char *t_name; /* Descriptive name. */ }; #define MT_TAPE_INFO \ { \ {MT_ISUNKNOWN, "Unknown type of tape device"}, \ {MT_ISQIC02, "Generic QIC-02 tape streamer"}, \ {MT_ISWT5150, "Wangtek 5150, QIC-150"}, \ {MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \ {MT_ISCMSJ500, "CMS Jumbo 500"}, \ {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \ {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \ {MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, \ {MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \ {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \ {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \ {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \ {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \ {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \ {MT_ISSCSI1, "Generic SCSI-1 tape"}, \ {MT_ISSCSI2, "Generic SCSI-2 tape"}, \ {0, NULL} \ } /* Structure for MTIOCPOS - mag tape get position command. */ struct mtpos { long int mt_blkno; /* Current block number. */ }; #define _IOT_mtpos /* Hurd ioctl type field. */ \ _IOT_SIMPLE (long) /* Structure for MTIOCGETCONFIG/MTIOCSETCONFIG primarily intended as an interim solution for QIC-02 until DDI is fully implemented. */ struct mtconfiginfo { long int mt_type; /* Drive type. */ long int ifc_type; /* Interface card type. */ unsigned short int irqnr; /* IRQ number to use. */ unsigned short int dmanr; /* DMA channel to use. */ unsigned short int port; /* IO port base address. */ unsigned long int debug; /* Debugging flags. */ unsigned have_dens:1; unsigned have_bsf:1; unsigned have_fsr:1; unsigned have_bsr:1; unsigned have_eod:1; unsigned have_seek:1; unsigned have_tell:1; unsigned have_ras1:1; unsigned have_ras2:1; unsigned have_ras3:1; unsigned have_qfa:1; unsigned pad1:5; char reserved[10]; }; #define _IOT_mtconfiginfo /* Hurd ioctl type field. */ \ _IOT (_IOTS (long), 2, _IOTS (short), 3, _IOTS (long), 1) /* XXX wrong */ /* Magnetic tape I/O control commands. */ #define MTIOCTOP _IOW('m', 1, struct mtop) /* Do a mag tape op. */ #define MTIOCGET _IOR('m', 2, struct mtget) /* Get tape status. */ #define MTIOCPOS _IOR('m', 3, struct mtpos) /* Get tape position.*/ /* The next two are used by the QIC-02 driver for runtime reconfiguration. See tpqic02.h for struct mtconfiginfo. */ #define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo) /* Get tape config.*/ #define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo) /* Set tape config.*/ /* Generic Mag Tape (device independent) status macros for examining mt_gstat -- HP-UX compatible. There is room for more generic status bits here, but I don't know which of them are reserved. At least three or so should be added to make this really useful. */ #define GMT_EOF(x) ((x) & 0x80000000) #define GMT_BOT(x) ((x) & 0x40000000) #define GMT_EOT(x) ((x) & 0x20000000) #define GMT_SM(x) ((x) & 0x10000000) /* DDS setmark */ #define GMT_EOD(x) ((x) & 0x08000000) /* DDS EOD */ #define GMT_WR_PROT(x) ((x) & 0x04000000) /* #define GMT_ ? ((x) & 0x02000000) */ #define GMT_ONLINE(x) ((x) & 0x01000000) #define GMT_D_6250(x) ((x) & 0x00800000) #define GMT_D_1600(x) ((x) & 0x00400000) #define GMT_D_800(x) ((x) & 0x00200000) /* #define GMT_ ? ((x) & 0x00100000) */ /* #define GMT_ ? ((x) & 0x00080000) */ #define GMT_DR_OPEN(x) ((x) & 0x00040000) /* Door open (no tape). */ /* #define GMT_ ? ((x) & 0x00020000) */ #define GMT_IM_REP_EN(x) ((x) & 0x00010000) /* Immediate report mode.*/ /* 16 generic status bits unused. */ /* SCSI-tape specific definitions. Bitfield shifts in the status */ #define MT_ST_BLKSIZE_SHIFT 0 #define MT_ST_BLKSIZE_MASK 0xffffff #define MT_ST_DENSITY_SHIFT 24 #define MT_ST_DENSITY_MASK 0xff000000 #define MT_ST_SOFTERR_SHIFT 0 #define MT_ST_SOFTERR_MASK 0xffff /* Bitfields for the MTSETDRVBUFFER ioctl. */ #define MT_ST_OPTIONS 0xf0000000 #define MT_ST_BOOLEANS 0x10000000 #define MT_ST_SETBOOLEANS 0x30000000 #define MT_ST_CLEARBOOLEANS 0x40000000 #define MT_ST_WRITE_THRESHOLD 0x20000000 #define MT_ST_DEF_BLKSIZE 0x50000000 #define MT_ST_DEF_OPTIONS 0x60000000 #define MT_ST_BUFFER_WRITES 0x1 #define MT_ST_ASYNC_WRITES 0x2 #define MT_ST_READ_AHEAD 0x4 #define MT_ST_DEBUGGING 0x8 #define MT_ST_TWO_FM 0x10 #define MT_ST_FAST_MTEOM 0x20 #define MT_ST_AUTO_LOCK 0x40 #define MT_ST_DEF_WRITES 0x80 #define MT_ST_CAN_BSR 0x100 #define MT_ST_NO_BLKLIMS 0x200 #define MT_ST_CAN_PARTITIONS 0x400 #define MT_ST_SCSI2LOGICAL 0x800 /* The mode parameters to be controlled. Parameter chosen with bits 20-28. */ #define MT_ST_CLEAR_DEFAULT 0xfffff #define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000) #define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000) #define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000) /* The offset for the arguments for the special HP changer load command. */ #define MT_ST_HPLOADER_OFFSET 10000 /* Specify default tape device. */ #ifndef DEFTAPE # define DEFTAPE "/dev/tape" #endif #endif /* mtio.h */ bareos-Release-14.2.6/src/win32/compat/include/sys/socket.h000066400000000000000000000000001263011562700233440ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/sys/stat.h000066400000000000000000000000241263011562700230350ustar00rootroot00000000000000#include "compat.h" bareos-Release-14.2.6/src/win32/compat/include/sys/time.h000066400000000000000000000000001263011562700230120ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/sys/wait.h000066400000000000000000000000001263011562700230200ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/compat/include/syslog.h000066400000000000000000000106361263011562700225760ustar00rootroot00000000000000/* * Copyright (c) 1982, 1986, 1988, 1993 * The Regents of the University of California. 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #ifndef _SYSLOG_H #define _SYSLOG_H #ifdef __cplusplus extern "C" { #endif /* * Facility codes */ #define LOG_KERN (0<<3) /* kernel messages */ #define LOG_USER (1<<3) /* random user-level messages */ #define LOG_MAIL (2<<3) /* mail system */ #define LOG_DAEMON (3<<3) /* system daemons */ #define LOG_AUTH (4<<3) /* security/authorization messages */ #define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ #define LOG_LPR (6<<3) /* line printer subsystem */ #define LOG_NEWS (7<<3) /* netnews subsystem */ #define LOG_UUCP (8<<3) /* uucp subsystem */ #define LOG_AUDIT (13<<3) /* audit subsystem */ #define LOG_CRON (15<<3) /* cron/at subsystem */ /* other codes through 15 reserved for system use */ #define LOG_LOCAL0 (16<<3) /* reserved for local use */ #define LOG_LOCAL1 (17<<3) /* reserved for local use */ #define LOG_LOCAL2 (18<<3) /* reserved for local use */ #define LOG_LOCAL3 (19<<3) /* reserved for local use */ #define LOG_LOCAL4 (20<<3) /* reserved for local use */ #define LOG_LOCAL5 (21<<3) /* reserved for local use */ #define LOG_LOCAL6 (22<<3) /* reserved for local use */ #define LOG_LOCAL7 (23<<3) /* reserved for local use */ #define LOG_NFACILITIES 24 /* maximum number of facilities */ #define LOG_FACMASK 0x03f8 /* mask to extract facility part */ /* * Priorities (these are ordered) */ #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but signification condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ #define LOG_PRIMASK 0x0007 /* mask to extract priority part (internal) */ /* * arguments to setlogmask. */ #define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ #define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ /* * Option flags for openlog. * * LOG_ODELAY no longer does anything; LOG_NDELAY is the * inverse of what it used to be. */ #define LOG_PID 0x01 /* log the pid with each message */ #define LOG_CONS 0x02 /* log on the console if errors in sending */ #define LOG_ODELAY 0x04 /* delay open until syslog() is called */ #define LOG_NDELAY 0x08 /* don't delay open */ #define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */ void syslog(int type, const char *fmt, ...); void openlog(const char *app, int, int); void closelog(void); #ifdef __cplusplus } #endif #endif /* _SYSLOG_H */ bareos-Release-14.2.6/src/win32/compat/include/unistd.h000066400000000000000000000000651263011562700225570ustar00rootroot00000000000000#if defined(__GNUC__) #include_next #endif bareos-Release-14.2.6/src/win32/compat/include/winhost.h000066400000000000000000000030311263011562700227400ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Define Host machine */ #ifdef HAVE_MINGW extern char win_os[]; #define HOST_OS "Linux" #define DISTNAME "Cross-compile" #ifndef BAREOS #define BAREOS "Bareos" #endif #ifdef _WIN64 # define DISTVER "Win64" #else # define DISTVER "Win32" #endif #else extern DLL_IMP_EXP char WIN_VERSION_LONG[]; extern DLL_IMP_EXP char WIN_VERSION[]; #define HOST_OS WIN_VERSION_LONG #define DISTNAME "MVS" #define DISTVER WIN_VERSION #endif #define HELPDIR "c://Program Files//Bareos//help" #define FD_DEFAULT_PORT "9102" #define SD_DEFAULT_PORT "9103" #define DIR_DEFAULT_PORT "9101" #define NDMP_DEFAULT_PORT "10000" bareos-Release-14.2.6/src/win32/compat/include/winsock.h000066400000000000000000000001041263011562700227200ustar00rootroot00000000000000#include #ifdef HAVE_IPV6 #include #endif bareos-Release-14.2.6/src/win32/compat/print.c000066400000000000000000000477221263011562700207700ustar00rootroot00000000000000/************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt(dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. * * More Recently: * Brandon Long 9/15/96 for mutt 0.43 * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything * from the normal C string format, at least as far as I can tell from * the Solaris 2.5 printf(3S) man page. * * Brandon Long 10/22/97 for mutt 0.87.1 * Ok, added some minimal floating point support, which means this * probably requires libm on most operating systems. Don't yet * support the exponent(e, E) and sigfig(g, G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways * which showed it, so that's been fixed. Also, formated the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. * * Thomas Roessler 01/27/98 for mutt 0.89i * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 * The original code assumed that both snprintf() and vsnprintf() were * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * Ben Lindstrom 09/27/00 for OpenSSH * Welcome to the world of %lld and %qd support. With other * long long support. This is needed for sftp-server to work * right. * * Ben Lindstrom 02/12/01 for OpenSSH * Removed all hint of VARARGS stuff and banished it to the void, * and did a bit of KNF style work to make things a bit more * acceptable. Consider stealing from mutt or enlightenment. **************************************************************/ #include "bareos.h" typedef void (prfun)(char *, size_t *, size_t, int); int dopr(char *buffer, size_t maxlen, const char *format, va_list args, prfun); static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max, prfun); static void fmtint(char *buffer, size_t *currlen, size_t maxlen, INT64 value, int base, int min, int max, int flags, prfun); static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags, prfun); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, int c); /* * dopr(): poor man's version of doprintf */ #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LONG_LONG 4 #define char_to_int(p) (p - '0') #define abs_val(p) (p < 0 ? -p : p) static const char digitval[] = "0123456789abcdef0123456789ABCDEF"; int dopr(char *buffer, size_t maxlen, const char *format, va_list args, prfun outch) { char *strvalue; char ch; INT64 value; long double fvalue; int min = 0; int max = -1; int state = DP_S_DEFAULT; int flags = 0; int cflags = 0; size_t currlen = 0; ch = *format++; while (state != DP_S_DONE) { if ((ch == '\0') || (currlen >= maxlen)) state = DP_S_DONE; switch (state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; else outch(buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; break; case '+': flags |= DP_F_PLUS; ch = *format++; break; case ' ': flags |= DP_F_SPACE; ch = *format++; break; case '#': flags |= DP_F_NUM; ch = *format++; break; case '0': flags |= DP_F_ZERO; ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { min = 10*min + char_to_int(ch); ch = *format++; } else if (ch == '*') { min = va_arg(args, int); ch = *format++; state = DP_S_DOT; } else state = DP_S_DOT; break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; ch = *format++; } else state = DP_S_MOD; break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10*max + char_to_int(ch); ch = *format++; } else if (ch == '*') { max = va_arg(args, int); ch = *format++; state = DP_S_MOD; } else state = DP_S_MOD; break; case DP_S_MOD: switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'l': cflags = DP_C_LONG; ch = *format++; if (ch == 'l') { cflags = DP_C_LONG_LONG; ch = *format++; } break; case 'q': cflags = DP_C_LONG_LONG; ch = *format++; break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { case 'b': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg(args, unsigned int); else if (cflags == DP_C_LONG) value = va_arg(args, unsigned long int); else if (cflags == DP_C_LONG_LONG) value = va_arg(args, UINT64); else value = va_arg(args, unsigned int); fmtint(buffer, &currlen, maxlen, value, 2, min, max, flags, outch); break; case 'd': case 'i': if (cflags == DP_C_SHORT) value = va_arg(args, int); else if (cflags == DP_C_LONG) value = va_arg(args, long int); else if (cflags == DP_C_LONG_LONG) value = va_arg(args, INT64); else value = va_arg(args, int); fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags, outch); break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg(args, unsigned int); else if (cflags == DP_C_LONG) value = va_arg(args, unsigned long int); else if (cflags == DP_C_LONG_LONG) value = va_arg(args, UINT64); else value = va_arg(args, unsigned int); fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags, outch); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg(args, unsigned int); else if (cflags == DP_C_LONG) value = va_arg(args, unsigned long int); else if (cflags == DP_C_LONG_LONG) value = va_arg(args, UINT64); else value = va_arg(args, unsigned int); fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags, outch); break; case 'X': flags |= DP_F_UP; case 'x': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg(args, unsigned int); else if (cflags == DP_C_LONG) value = va_arg(args, unsigned long int); else if (cflags == DP_C_LONG_LONG) value = va_arg(args, UINT64); else value = va_arg(args, unsigned int); fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags, outch); break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg(args, long double); else fvalue = va_arg(args, double); /* um, floating point? */ fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags, outch); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg(args, long double); else fvalue = va_arg(args, double); break; case 'G': flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg(args, long double); else fvalue = va_arg(args, double); break; case 'c': outch(buffer, &currlen, maxlen, va_arg(args, int)); break; case 's': strvalue = va_arg(args, char *); if (max < 0) { max = maxlen; /* ie, no max */ } fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max, outch); break; case 'p': flags |= DP_F_UNSIGNED; if (sizeof(char *) == 4) { value = va_arg(args, uint32_t); } else if (sizeof(char *) == 8) { value = va_arg(args, uint64_t); } else { value = 0; /* we have a problem */ } fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags, outch); break; case 'n': if (cflags == DP_C_SHORT) { short int *num; num = va_arg(args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { long int *num; num = va_arg(args, long int *); *num = currlen; } else if (cflags == DP_C_LONG_LONG) { INT64 *num; num = va_arg(args, INT64 *); *num = currlen; } else { int *num; num = va_arg(args, int *); *num = currlen; } break; case '%': outch(buffer, &currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ ch = *format++; break; default: /* Unknown, skip */ break; } ch = *format++; state = DP_S_DEFAULT; flags = cflags = min = 0; max = -1; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } outch(buffer, &currlen, maxlen, -1); return currlen; } static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max, prfun outch) { int padlen, strln; /* amount to pad */ int cnt = 0; if (value == NULL) value = (char *)""; for (strln = 0; value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { outch(buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { outch(buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { outch(buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM(ie 0x and 0 alternates) */ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, INT64 value, int base, int min, int max, int flags, prfun outch) { UINT64 uvalue; char convert[20]; int signvalue = 0; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; uvalue = -value; } else if (flags & DP_F_PLUS) /* Do a sign(+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } if (flags & DP_F_UP) caps = 16; /* Should characters be upper case? */ do { convert[place++] = digitval[(uvalue%base)+caps]; uvalue = (uvalue / (unsigned)base); } while (uvalue && (place < 20)); if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ /* Spaces */ while (spadlen > 0) { outch(buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) outch(buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { outch(buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) outch(buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { outch(buffer, currlen, maxlen, ' '); ++spadlen; } } static long double pow10(int exp) { long double result = 1; while (exp) { result *= 10; exp--; } return result; } static long round(long double value) { long intpart = (long)value; value -= intpart; if (value >= 0.5) intpart++; return intpart; } static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags, prfun outch) { char iconvert[20]; char fconvert[20]; int signvalue = 0; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; long intpart; long fracpart; long double ufvalue; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val(fvalue); if (fvalue < 0) signvalue = '-'; else if (flags & DP_F_PLUS) /* Do a sign(+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; intpart = (long)ufvalue; /* * Sorry, we only support 9 digits past the decimal because of our * conversion method */ if (max > 9) max = 9; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ fracpart = round((pow10 (max)) * (ufvalue - intpart)); if (fracpart >= pow10 (max)) { intpart++; fracpart -= (long)pow10 (max); } /* Convert integer part */ do { iconvert[iplace++] = digitval[intpart % 10]; intpart = (intpart / 10); } while (intpart && (iplace < 20)); if (iplace == 20) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ do { fconvert[fplace++] = digitval[fracpart % 10]; fracpart = (fracpart / 10); } while (fracpart && (fplace < 20)); if (fplace == 20) fplace--; fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { outch(buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { outch(buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { outch(buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) outch(buffer, currlen, maxlen, signvalue); while (iplace > 0) outch(buffer, currlen, maxlen, iconvert[--iplace]); /* * Decimal point. This should probably use locale to find the correct * char to print out. */ outch(buffer, currlen, maxlen, '.'); while (fplace > 0) outch(buffer, currlen, maxlen, fconvert[--fplace]); while (zpadlen > 0) { outch(buffer, currlen, maxlen, '0'); --zpadlen; } while (padlen < 0) { outch(buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, int c) { if (c == -1) { if (*currlen < maxlen - 1) buffer[*currlen] = '\0'; else buffer[maxlen - 1] = '\0'; } else if (*currlen < maxlen) buffer[(*currlen)++] = c; } int __sprintf(char *str, const char *fmt, ...) { int rval; va_list ap; va_start(ap, fmt); rval = vsnprintf(str, 128*1024, fmt, ap); va_end(ap); return rval; } int __snprintf(char *str, size_t count, const char *fmt, ...) { int rval; va_list ap; va_start(ap, fmt); rval = vsnprintf(str, count, fmt, ap); va_end(ap); return rval; } int __vsprintf(char *s, const char *format, va_list args) { s[0] = 0; return dopr(s, 0xfffff, format, args, dopr_outch); } int __vsnprintf(char *s, size_t count, const char *format, va_list args) { s[0] = 0; return dopr(s, count, format, args, dopr_outch); } bareos-Release-14.2.6/src/win32/compat/winapi.c000066400000000000000000000223751263011562700211200ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2008 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows APIs that are different for each system. * We use pointers to the entry points so that a * single binary will run on all Windows systems. * * Kern Sibbald MMIII */ #include "bareos.h" /* * Init with win9x, but maybe set to NT in InitWinAPI */ DWORD g_platform_id = VER_PLATFORM_WIN32_WINDOWS; DWORD g_MinorVersion = 0; DWORD g_MajorVersion = 0; /* * API Pointers */ t_OpenProcessToken p_OpenProcessToken = NULL; t_AdjustTokenPrivileges p_AdjustTokenPrivileges = NULL; t_LookupPrivilegeValue p_LookupPrivilegeValue = NULL; t_SetProcessShutdownParameters p_SetProcessShutdownParameters = NULL; t_CreateFileA p_CreateFileA = NULL; t_CreateFileW p_CreateFileW = NULL; t_CreateDirectoryA p_CreateDirectoryA; t_CreateDirectoryW p_CreateDirectoryW; t_OpenEncryptedFileRawA p_OpenEncryptedFileRawA = NULL; t_OpenEncryptedFileRawW p_OpenEncryptedFileRawW = NULL; t_ReadEncryptedFileRaw p_ReadEncryptedFileRaw = NULL; t_WriteEncryptedFileRaw p_WriteEncryptedFileRaw = NULL; t_CloseEncryptedFileRaw p_CloseEncryptedFileRaw = NULL; t_wunlink p_wunlink = NULL; t_wmkdir p_wmkdir = NULL; #if (_WIN32_WINNT >= 0x0600) t_GetFileInformationByHandleEx p_GetFileInformationByHandleEx = NULL; #endif t_GetFileAttributesA p_GetFileAttributesA = NULL; t_GetFileAttributesW p_GetFileAttributesW = NULL; t_GetFileAttributesExA p_GetFileAttributesExA = NULL; t_GetFileAttributesExW p_GetFileAttributesExW = NULL; t_SetFileAttributesA p_SetFileAttributesA = NULL; t_SetFileAttributesW p_SetFileAttributesW = NULL; t_BackupRead p_BackupRead = NULL; t_BackupWrite p_BackupWrite = NULL; t_WideCharToMultiByte p_WideCharToMultiByte = NULL; t_MultiByteToWideChar p_MultiByteToWideChar = NULL; t_AttachConsole p_AttachConsole = NULL; t_FindFirstFileA p_FindFirstFileA = NULL; t_FindFirstFileW p_FindFirstFileW = NULL; t_FindNextFileA p_FindNextFileA = NULL; t_FindNextFileW p_FindNextFileW = NULL; t_SetCurrentDirectoryA p_SetCurrentDirectoryA = NULL; t_SetCurrentDirectoryW p_SetCurrentDirectoryW = NULL; t_GetCurrentDirectoryA p_GetCurrentDirectoryA = NULL; t_GetCurrentDirectoryW p_GetCurrentDirectoryW = NULL; t_GetVolumePathNameW p_GetVolumePathNameW = NULL; t_GetVolumeNameForVolumeMountPointW p_GetVolumeNameForVolumeMountPointW = NULL; t_SHGetFolderPath p_SHGetFolderPath = NULL; t_CreateProcessA p_CreateProcessA = NULL; t_CreateProcessW p_CreateProcessW = NULL; t_GetLogicalDriveStringsA p_GetLogicalDriveStringsA = NULL; t_GetLogicalDriveStringsW p_GetLogicalDriveStringsW = NULL; t_InetPton p_InetPton = NULL; void InitWinAPIWrapper() { OSVERSIONINFO osversioninfo = { sizeof(OSVERSIONINFO) }; /* * Get the current OS version */ if (!GetVersionEx(&osversioninfo)) { g_platform_id = 0; } else { g_platform_id = osversioninfo.dwPlatformId; g_MinorVersion = osversioninfo.dwMinorVersion; g_MajorVersion = osversioninfo.dwMajorVersion; } HMODULE hLib = LoadLibraryA("KERNEL32.DLL"); if (hLib) { /* * Get logical drive calls */ p_GetLogicalDriveStringsA = (t_GetLogicalDriveStringsA) GetProcAddress(hLib, "GetLogicalDriveStringsA"); p_GetLogicalDriveStringsW = (t_GetLogicalDriveStringsW) GetProcAddress(hLib, "GetLogicalDriveStringsW"); /* * Create process calls */ p_CreateProcessA = (t_CreateProcessA) GetProcAddress(hLib, "CreateProcessA"); p_CreateProcessW = (t_CreateProcessW) GetProcAddress(hLib, "CreateProcessW"); /* * Create file calls */ p_CreateFileA = (t_CreateFileA) GetProcAddress(hLib, "CreateFileA"); p_CreateDirectoryA = (t_CreateDirectoryA) GetProcAddress(hLib, "CreateDirectoryA"); #if (_WIN32_WINNT >= 0x0600) /* * File Information calls */ p_GetFileInformationByHandleEx = (t_GetFileInformationByHandleEx) GetProcAddress(hLib, "GetFileInformationByHandleEx"); #endif /* * Attribute calls */ p_GetFileAttributesA = (t_GetFileAttributesA) GetProcAddress(hLib, "GetFileAttributesA"); p_GetFileAttributesExA = (t_GetFileAttributesExA) GetProcAddress(hLib, "GetFileAttributesExA"); p_SetFileAttributesA = (t_SetFileAttributesA) GetProcAddress(hLib, "SetFileAttributesA"); /* * Process calls */ p_SetProcessShutdownParameters = (t_SetProcessShutdownParameters) GetProcAddress(hLib, "SetProcessShutdownParameters"); /* * Char conversion calls */ p_WideCharToMultiByte = (t_WideCharToMultiByte) GetProcAddress(hLib, "WideCharToMultiByte"); p_MultiByteToWideChar = (t_MultiByteToWideChar) GetProcAddress(hLib, "MultiByteToWideChar"); /* * Find files */ p_FindFirstFileA = (t_FindFirstFileA) GetProcAddress(hLib, "FindFirstFileA"); p_FindNextFileA = (t_FindNextFileA) GetProcAddress(hLib, "FindNextFileA"); /* * Get and set directory */ p_GetCurrentDirectoryA = (t_GetCurrentDirectoryA) GetProcAddress(hLib, "GetCurrentDirectoryA"); p_SetCurrentDirectoryA = (t_SetCurrentDirectoryA) GetProcAddress(hLib, "SetCurrentDirectoryA"); if (g_platform_id != VER_PLATFORM_WIN32_WINDOWS) { p_CreateFileW = (t_CreateFileW) GetProcAddress(hLib, "CreateFileW"); p_CreateDirectoryW = (t_CreateDirectoryW) GetProcAddress(hLib, "CreateDirectoryW"); /* * Backup calls */ p_BackupRead = (t_BackupRead) GetProcAddress(hLib, "BackupRead"); p_BackupWrite = (t_BackupWrite) GetProcAddress(hLib, "BackupWrite"); p_GetFileAttributesW = (t_GetFileAttributesW) GetProcAddress(hLib, "GetFileAttributesW"); p_GetFileAttributesExW = (t_GetFileAttributesExW) GetProcAddress(hLib, "GetFileAttributesExW"); p_SetFileAttributesW = (t_SetFileAttributesW) GetProcAddress(hLib, "SetFileAttributesW"); p_FindFirstFileW = (t_FindFirstFileW) GetProcAddress(hLib, "FindFirstFileW"); p_FindNextFileW = (t_FindNextFileW) GetProcAddress(hLib, "FindNextFileW"); p_GetCurrentDirectoryW = (t_GetCurrentDirectoryW) GetProcAddress(hLib, "GetCurrentDirectoryW"); p_SetCurrentDirectoryW = (t_SetCurrentDirectoryW) GetProcAddress(hLib, "SetCurrentDirectoryW"); /* * Some special stuff we need for VSS * but static linkage doesn't work on Win 9x */ p_GetVolumePathNameW = (t_GetVolumePathNameW) GetProcAddress(hLib, "GetVolumePathNameW"); p_GetVolumeNameForVolumeMountPointW = (t_GetVolumeNameForVolumeMountPointW) GetProcAddress(hLib, "GetVolumeNameForVolumeMountPointW"); p_AttachConsole = (t_AttachConsole) GetProcAddress(hLib, "AttachConsole"); } } if (g_platform_id != VER_PLATFORM_WIN32_WINDOWS) { hLib = LoadLibraryA("MSVCRT.DLL"); if (hLib) { /* unlink */ p_wunlink = (t_wunlink) GetProcAddress(hLib, "_wunlink"); /* wmkdir */ p_wmkdir = (t_wmkdir) GetProcAddress(hLib, "_wmkdir"); } hLib = LoadLibraryA("ADVAPI32.DLL"); if (hLib) { p_OpenProcessToken = (t_OpenProcessToken) GetProcAddress(hLib, "OpenProcessToken"); p_AdjustTokenPrivileges = (t_AdjustTokenPrivileges) GetProcAddress(hLib, "AdjustTokenPrivileges"); p_LookupPrivilegeValue = (t_LookupPrivilegeValue) GetProcAddress(hLib, "LookupPrivilegeValueA"); /* * EFS calls */ p_OpenEncryptedFileRawA = (t_OpenEncryptedFileRawA) GetProcAddress(hLib, "OpenEncryptedFileRawA"); p_OpenEncryptedFileRawW = (t_OpenEncryptedFileRawW) GetProcAddress(hLib, "OpenEncryptedFileRawW"); p_ReadEncryptedFileRaw = (t_ReadEncryptedFileRaw) GetProcAddress(hLib, "ReadEncryptedFileRaw"); p_WriteEncryptedFileRaw = (t_WriteEncryptedFileRaw) GetProcAddress(hLib, "WriteEncryptedFileRaw"); p_CloseEncryptedFileRaw = (t_CloseEncryptedFileRaw) GetProcAddress(hLib, "CloseEncryptedFileRaw"); } } hLib = LoadLibraryA("SHELL32.DLL"); if (hLib) { p_SHGetFolderPath = (t_SHGetFolderPath) GetProcAddress(hLib, "SHGetFolderPathA"); } else { /* * If SHELL32 isn't found try SHFOLDER for older systems */ hLib = LoadLibraryA("SHFOLDER.DLL"); if (hLib) { p_SHGetFolderPath = (t_SHGetFolderPath) GetProcAddress(hLib, "SHGetFolderPathA"); } } hLib = LoadLibraryA("WS2_32.DLL"); if (hLib) { p_InetPton = (t_InetPton) GetProcAddress(hLib, "InetPtonA"); } atexit(Win32ConvCleanupCache); } bareos-Release-14.2.6/src/win32/console/000077500000000000000000000000001263011562700176335ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/console/Makefile000066400000000000000000000032431263011562700212750ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../console include ../Makefile.inc INCLUDES = -I../.. \ -I../../include \ -I../include \ -I../compat/include \ -I../vss/include LDLIBS = ../lib/libbareos.a \ ../lib/libbareos.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(MINGW_LIB)/libz.dll.a \ $(MINGW_LIB)/libreadline.dll.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid CONSSRCS = console.c console_conf.c CONSOBJS = $(CONSSRCS:.c=.o) WINDRESSRCS = consoleres.rc WINDRESOBJS = $(WINDRESSRCS:.rc=.o) all: bconsole.exe bconsole.exe: DLL_USAGE = -DUSING_DLL bconsole.exe: $(CONSOBJS) $(WINDRESOBJS) $(CXX) $(LDFLAGS_CONS) $(CONSOBJS) $(LDLIBS) $(WINDRESOBJS) -o $@ clean: rm -f *.o distclean:: clean rm -f bconsole.exe # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< %.o : %.rc @echo "Ressource Compiling $^" $(WINDRES) $^ -o $@ bareos-Release-14.2.6/src/win32/console/consoleres.rc.in000066400000000000000000000022401263011562700227400ustar00rootroot00000000000000id ICON "../../../platforms/win32/bconsole.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos Console" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bconsole.exe" VALUE "OriginalFilename", "bconsole.exe" VALUE "ProductName", "Bareos Console" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/dird/000077500000000000000000000000001263011562700171135ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/dird/Makefile000066400000000000000000000052771263011562700205660ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../dird:../generic include ../Makefile.inc INCLUDES = -I. \ -I../.. \ -I../../include \ -I../include \ -I../compat/include LDLIBS = ../lib/libbareos.a \ ../lib/libbareos.dll \ ../findlib/libbareosfind.dll \ ../cats/libbareoscats.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid -lcomctl32 SVRSRCS = admin.c authenticate.c autoprune.c backup.c bsr.c catreq.c \ dir_plugins.c dird_conf.c dird.c expand.c fd_cmds.c getmsg.c \ inc_conf.c job.c jobq.c migrate.c mountreq.c msgchan.c \ ndmp_dma_backup.c ndmp_dma_generic.c ndmp_dma_restore.c \ ndmp_dma_storage.c ndmp_fhdb_helpers.c ndmp_fhdb_mem.c \ ndmp_fhdb_lmdb.c newvol.c next_vol.c quota.c recycle.c \ restore.c run_conf.c sd_cmds.c scheduler.c stats.c ua_acl.c \ ua_audit.c ua_cmds.c ua_configure.c ua_dotcmds.c ua_input.c \ ua_impexp.c ua_label.c ua_output.c ua_prune.c ua_purge.c \ ua_query.c ua_restore.c ua_run.c ua_select.c ua_server.c \ ua_status.c ua_tree.c ua_update.c vbackup.c verify.c \ service.c main.c SVROBJS = $(SVRSRCS:.c=.o) DBCHKSRCS = dbcheck.c dird_conf.c ua_acl.c ua_audit.c run_conf.c inc_conf.c DBCHKOBJS = $(DBCHKSRCS:.c=.o) WINDRESSRCS = dirdres.rc WINDRESOBJS = $(WINDRESSRCS:.rc=.o) DBCHKRESSRCS = dbcheckres.rc DBCHKRESOBJS = $(DBCHKRESSRCS:.rc=.o) all: bareos-dir.exe bareos-dbcheck.exe bareos-dir.exe: DLL_USAGE = -DUSING_DLL bareos-dir.exe: $(SVROBJS) $(WINDRESOBJS) $(CXX) $(LDFLAGS_WINAPP) $(SVROBJS) $(WINDRESOBJS) $(LDLIBS) -o $@ bareos-dbcheck.exe: DLL_USAGE = -DUSING_DLL bareos-dbcheck.exe: $(DBCHKOBJS) $(DBCHKRESOBJS) $(CXX) $(LDFLAGS_CONS) $(DBCHKOBJS) $(LDLIBS) $(DBCHKRESOBJS) -o $@ clean: rm -f *.o distclean:: clean rm -f bareos-dir.exe bareos-dbcheck.exe # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< %.o : %.rc @echo "Ressource Compiling $^" $(WINDRES) $^ -o $@ bareos-Release-14.2.6/src/win32/dird/dbcheckres.rc.in000066400000000000000000000022741263011562700221500ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareostools.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos Database Check" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bareos-dbcheck.exe" VALUE "OriginalFilename", "bareos-dbcheck.exe" VALUE "ProductName", "Bareos Database Check" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2014 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/dird/dirdres.rc.in000066400000000000000000000022461263011562700215060ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareosdir.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos Director" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bareos-dir.exe" VALUE "OriginalFilename", "bareos-dir.exe" VALUE "ProductName", "Bareos Director" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2014 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/dird/who.h000066400000000000000000000021461263011562700200640ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 */ #define APP_NAME "Bareos-dir" #define LC_APP_NAME "bareos-dir" #define APP_DESC "Bareos Director Service" #define SERVICE_DESC "Provides bareos director services." #define terminate_app(x) terminate_dird(x) extern void terminate_dird(int sig); bareos-Release-14.2.6/src/win32/filed/000077500000000000000000000000001263011562700172545ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/filed/Makefile000066400000000000000000000044001263011562700207120ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../filed:../generic include ../Makefile.inc DEFINES += -DWIN32_VSS ifeq ($(WIN_VERSION),64) DEFINES += -DHAVE_VSS64 endif INCLUDES = -I. \ -I../.. \ -I../../include \ -I../../lmdb \ -I../include \ -I../compat/include \ -I../vss/include LDLIBS = ../lib/libbareos.a \ ../lib/libbareos.dll \ ../findlib/libbareosfind.dll \ ../lmdb/libbareoslmdb.dll \ $(MINGW_LIB)/libz.dll.a \ $(MINGW_LIB)/liblzo2.dll.a \ $(MINGW_LIB)/libfastlz.dll.a \ $(MINGW_LIB)/libpthreadGCE2.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid -lcomctl32 SVRSRCS = accurate.c accurate_htable.c accurate_lmdb.c authenticate.c \ backup.c compression.c crypto.c dir_cmd.c estimate.c \ fd_plugins.c filed_conf.c filed.c fileset.c heartbeat.c \ restore.c sd_cmds.c status.c verify.c verify_vol.c \ vss.c vss_XP.c vss_W2K3.c vss_Vista.c service.c main.c SVROBJS = $(SVRSRCS:.c=.o) WINDRESSRCS = filedres.rc WINDRESOBJS = $(WINDRESSRCS:.rc=.o) all: bareos-fd.exe bareos-fd.exe: DLL_USAGE = -DUSING_DLL bareos-fd.exe: $(SVROBJS) $(WINDRESOBJS) $(CXX) $(LDFLAGS_WINAPP) $(SVROBJS) $(WINDRESOBJS) $(LDLIBS) -o $@ clean: rm -f *.o distclean:: clean rm -f bareos-fd.exe # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< %.o : %.rc @echo "Ressource Compiling $^" $(WINDRES) $^ -o $@ main.o: ../generic/main.c @echo "Compiling $<" $(CXX) -DFILE_DAEMON $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/filed/filedres.rc.in000066400000000000000000000022521263011562700220050ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareosfd.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos File Daemon" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bareos-fd.exe" VALUE "OriginalFilename", "bareos-fd.exe" VALUE "ProductName", "Bareos File Daemon" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/filed/vss.c000066400000000000000000000136631263011562700202440ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // vss.cpp -- Interface to Volume Shadow Copies (VSS) // // Copyright transferred from MATRIX-Computer GmbH to // Kern Sibbald by express permission. // // Author : Thorsten Engel // Created On : Fri May 06 21:44:00 2005 #ifdef WIN32_VSS #include "bareos.h" #include "ms_atl.h" #include #include "vss.h" VSSClient *g_pVSSClient; // {b5946137-7b9f-4925-af80-51abd60b20d5} static const GUID VSS_SWPRV_ProviderID = { 0xb5946137, 0x7b9f, 0x4925, { 0xaf, 0x80, 0x51, 0xab, 0xd6, 0x0b, 0x20, 0xd5 } }; void VSSCleanup() { if (g_pVSSClient) { delete (g_pVSSClient); g_pVSSClient = NULL; } } /* * May be called multiple times */ void VSSInit() { if (g_pVSSClient) { return; /* already initialized */ } /* decide which vss class to initialize */ if (g_MajorVersion == 5) { switch (g_MinorVersion) { case 1: g_pVSSClient = new VSSClientXP(); break; case 2: g_pVSSClient = new VSSClient2003(); break; } /* Vista or Longhorn or later */ } else if (g_MajorVersion >= 6) { g_pVSSClient = new VSSClientVista(); } if (g_pVSSClient) { atexit(VSSCleanup); } } bool VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen) { return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen); } bool VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen) { return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen); } // Constructor VSSClient::VSSClient() { memset(this, 0, sizeof(VSSClient)); m_pAlistWriterState = New(alist(10, not_owned_by_alist)); m_pAlistWriterInfoText = New(alist(10, owned_by_alist)); m_uidCurrentSnapshotSet = GUID_NULL; } // Destructor VSSClient::~VSSClient() { // Release the IVssBackupComponents interface // WARNING: this must be done BEFORE calling CoUninitialize() if (m_pVssObject) { // m_pVssObject->Release(); m_pVssObject = NULL; } DestroyWriterInfo(); delete m_pAlistWriterState; delete m_pAlistWriterInfoText; // Call CoUninitialize if the CoInitialize was performed successfully if (m_bCoInitializeCalled) { CoUninitialize(); } } bool VSSClient::InitializeForBackup(JCR *jcr) { //return Initialize (VSS_CTX_BACKUP); m_jcr = jcr; return Initialize(0); } bool VSSClient::InitializeForRestore(JCR *jcr) { m_metadata = NULL; m_jcr = jcr; return Initialize(0, true/*=>Restore*/); } bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen) { if (!m_bBackupIsInitialized) return false; /* check for valid pathname */ bool bIsValidName; bIsValidName = strlen(szFilePath) > 3; if (bIsValidName) bIsValidName &= isalpha (szFilePath[0]) && szFilePath[1]==':' && szFilePath[2] == '\\'; if (bIsValidName) { int nDriveIndex = toupper(szFilePath[0])-'A'; if (m_szShadowCopyName[nDriveIndex][0] != 0) { if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) { nBuflen -= (int)strlen(szShadowPath); bstrncat(szShadowPath, szFilePath+2, nBuflen); return true; } } } bstrncpy(szShadowPath, szFilePath, nBuflen); errno = EINVAL; return false; } bool VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen) { if (!m_bBackupIsInitialized) return false; /* check for valid pathname */ bool bIsValidName; bIsValidName = wcslen(szFilePath) > 3; if (bIsValidName) bIsValidName &= iswalpha (szFilePath[0]) && szFilePath[1]==':' && szFilePath[2] == '\\'; if (bIsValidName) { int nDriveIndex = towupper(szFilePath[0])-'A'; if (m_szShadowCopyName[nDriveIndex][0] != 0) { wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen); nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]); wcsncat(szShadowPath, szFilePath+2, nBuflen); return true; } } wcsncpy(szShadowPath, szFilePath, nBuflen); errno = EINVAL; return false; } const size_t VSSClient::GetWriterCount() { return m_pAlistWriterInfoText->size(); } const char* VSSClient::GetWriterInfo(int nIndex) { return (char*)m_pAlistWriterInfoText->get(nIndex); } const int VSSClient::GetWriterState(int nIndex) { void *item = m_pAlistWriterState->get(nIndex); /* Eliminate compiler warnings */ #ifdef HAVE_VSS64 return (int64_t)(char *)item; #else return (int)(char *)item; #endif } void VSSClient::AppendWriterInfo(int nState, const char* pszInfo) { m_pAlistWriterInfoText->push(bstrdup(pszInfo)); m_pAlistWriterState->push((void*)nState); } /* * Note, this is called at the end of every job, so release all * the items in the alists, but do not delete the alist. */ void VSSClient::DestroyWriterInfo() { while (!m_pAlistWriterInfoText->empty()) { free(m_pAlistWriterInfoText->pop()); } while (!m_pAlistWriterState->empty()) { m_pAlistWriterState->pop(); } } #endif bareos-Release-14.2.6/src/win32/filed/vss_Vista.c000066400000000000000000000001051263011562700213750ustar00rootroot00000000000000#ifdef WIN32_VSS #define B_VSS_VISTA #include "vss_generic.c" #endif bareos-Release-14.2.6/src/win32/filed/vss_W2K3.c000066400000000000000000000001041263011562700207740ustar00rootroot00000000000000#ifdef WIN32_VSS #define B_VSS_W2K3 #include "vss_generic.c" #endif bareos-Release-14.2.6/src/win32/filed/vss_XP.c000066400000000000000000000001021263011562700206330ustar00rootroot00000000000000#ifdef WIN32_VSS #define B_VSS_XP #include "vss_generic.c" #endif bareos-Release-14.2.6/src/win32/filed/vss_generic.c000066400000000000000000001000661263011562700217320ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2005-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * vss.c -- Interface to Volume Shadow Copies (VSS) * * Copyright transferred from MATRIX-Computer GmbH to * Kern Sibbald by express permission. * * Author : Thorsten Engel * Created On : Fri May 06 21:44:00 2005 */ #ifdef WIN32_VSS #include "bareos.h" #include "jcr.h" #undef setlocale // STL includes #include #include #include #include #include using namespace std; #include "ms_atl.h" #include /* * Kludges to get Vista code to compile. */ #define __in IN #define __out OUT #define __RPC_unique_pointer #define __RPC_string #ifndef __RPC__out_ecount_part #define __RPC__out_ecount_part(x, y) #endif #define __RPC__deref_inout_opt #define __RPC__out #if !defined(ENABLE_NLS) #define setlocale(p, d) #endif #ifdef HAVE_STRSAFE_H /* * Used for safe string manipulation */ #include #endif bool VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen); bool VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen); #ifdef HAVE_MINGW class IXMLDOMDocument; #endif /* * Reduce compiler warnings from Windows vss code */ #undef uuid #define uuid(x) #ifdef B_VSS_XP #define VSSClientGeneric VSSClientXP #include "WinXP/vss.h" #include "WinXP/vswriter.h" #include "WinXP/vsbackup.h" #endif #ifdef B_VSS_W2K3 #define VSSClientGeneric VSSClient2003 #include "Win2003/vss.h" #include "Win2003/vswriter.h" #include "Win2003/vsbackup.h" #endif #ifdef B_VSS_VISTA #define VSSClientGeneric VSSClientVista #include "Win2003/vss.h" #include "Win2003/vswriter.h" #include "Win2003/vsbackup.h" #endif #define VSS_ERROR_OBJECT_ALREADY_EXISTS 0x8004230D /* In VSSAPI.DLL */ typedef HRESULT (STDAPICALLTYPE* t_CreateVssBackupComponents)(OUT IVssBackupComponents **); typedef void (APIENTRY* t_VssFreeSnapshotProperties)(IN VSS_SNAPSHOT_PROP*); static t_CreateVssBackupComponents p_CreateVssBackupComponents = NULL; static t_VssFreeSnapshotProperties p_VssFreeSnapshotProperties = NULL; #include "vss.h" static void JmsgVssApiStatus(JCR *jcr, int msg_status, HRESULT hr, const char *apiName) { const char *errmsg; if (hr == S_OK || hr == VSS_S_ASYNC_FINISHED) { return; } switch (hr) { case E_INVALIDARG: errmsg = "One of the parameter values is not valid."; break; case E_OUTOFMEMORY: errmsg = "The caller is out of memory or other system resources."; break; case E_ACCESSDENIED: errmsg = "The caller does not have sufficient backup privileges or is not an administrator."; break; case VSS_E_INVALID_XML_DOCUMENT: errmsg = "The XML document is not valid."; break; case VSS_E_OBJECT_NOT_FOUND: errmsg = "The specified file does not exist."; break; case VSS_E_BAD_STATE: errmsg = "Object is not initialized; called during restore or not called in correct sequence."; break; case VSS_E_WRITER_INFRASTRUCTURE: errmsg = "The writer infrastructure is not operating properly. Check that the Event Service and VSS have been started, and check for errors associated with those services in the error log."; break; case VSS_S_ASYNC_CANCELLED: errmsg = "The asynchronous operation was canceled by a previous call to IVssAsync::Cancel."; break; case VSS_S_ASYNC_PENDING: errmsg = "The asynchronous operation is still running."; break; case RPC_E_CHANGED_MODE: errmsg = "Previous call to CoInitializeEx specified the multithread apartment (MTA). This call indicates single-threaded apartment has occurred."; break; case S_FALSE: errmsg = "No writer found for the current component."; break; default: errmsg = "Unexpected error. The error code is logged in the error log file."; break; } Jmsg(jcr, msg_status, 0, "VSS API failure calling \"%s\". ERR=%s\n", apiName, errmsg); } #ifndef VSS_WS_FAILED_AT_BACKUPSHUTDOWN #define VSS_WS_FAILED_AT_BACKUPSHUTDOWN (VSS_WRITER_STATE)15 #endif static void JmsgVssWriterStatus(JCR *jcr, int msg_status, VSS_WRITER_STATE eWriterStatus, char *writer_name) { const char *errmsg; /* * The following are normal states */ if (eWriterStatus == VSS_WS_STABLE || eWriterStatus == VSS_WS_WAITING_FOR_BACKUP_COMPLETE) { return; } /* * Potential errors */ switch (eWriterStatus) { default: case VSS_WS_UNKNOWN: errmsg = "The writer's state is not known. This is a writer error."; break; case VSS_WS_WAITING_FOR_FREEZE: errmsg = "The writer is waiting for the freeze state."; break; case VSS_WS_WAITING_FOR_THAW: errmsg = "The writer is waiting for the thaw state."; break; case VSS_WS_WAITING_FOR_POST_SNAPSHOT: errmsg = "The writer is waiting for the PostSnapshot state."; break; case VSS_WS_WAITING_FOR_BACKUP_COMPLETE: errmsg = "The writer is waiting for the requester to finish its backup operation."; break; case VSS_WS_FAILED_AT_IDENTIFY: errmsg = "The writer vetoed the shadow copy creation process at the writer identification state."; break; case VSS_WS_FAILED_AT_PREPARE_BACKUP: errmsg = "The writer vetoed the shadow copy creation process during the backup preparation state."; break; case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: errmsg = "The writer vetoed the shadow copy creation process during the PrepareForSnapshot state."; break; case VSS_WS_FAILED_AT_FREEZE: errmsg = "The writer vetoed the shadow copy creation process during the freeze state."; break; case VSS_WS_FAILED_AT_THAW: errmsg = "The writer vetoed the shadow copy creation process during the thaw state."; break; case VSS_WS_FAILED_AT_POST_SNAPSHOT: errmsg = "The writer vetoed the shadow copy creation process during the PostSnapshot state."; break; case VSS_WS_FAILED_AT_BACKUP_COMPLETE: errmsg = "The shadow copy has been created and the writer failed during the BackupComplete state."; break; case VSS_WS_FAILED_AT_PRE_RESTORE: errmsg = "The writer failed during the PreRestore state."; break; case VSS_WS_FAILED_AT_POST_RESTORE: errmsg = "The writer failed during the PostRestore state."; break; case VSS_WS_FAILED_AT_BACKUPSHUTDOWN: errmsg = "The writer failed during the shutdown of the backup application."; } Jmsg(jcr, msg_status, 0, "VSS Writer \"%s\" has invalid state. ERR=%s\n", writer_name, errmsg); } /* * Some helper functions */ /* * bstrdup a wchar_t string. */ static inline wchar_t *wbstrdup(const wchar_t *str) { int len; wchar_t *dup; len = wcslen(str) + 1; dup = (wchar_t *)malloc(len * sizeof(wchar_t)); memcpy(dup, str, len * sizeof(wchar_t)); return dup; } /* * Append a backslash to the current string. */ static inline wstring AppendBackslash(wstring str) { if (str.length() == 0) { return wstring(L"\\"); } if (str[str.length() - 1] == L'\\') { return str; } return str.append(L"\\"); } /* * Get the unique volume name for the given path. */ static inline wstring GetUniqueVolumeNameForPath(wstring path) { wchar_t volumeRootPath[MAX_PATH]; wchar_t volumeName[MAX_PATH]; wchar_t volumeUniqueName[MAX_PATH]; if (path.length() <= 0) { return L""; } /* * Add the backslash termination, if needed. */ path = AppendBackslash(path); /* * Get the root path of the volume. */ if (!p_GetVolumePathNameW || !p_GetVolumePathNameW((LPCWSTR)path.c_str(), volumeRootPath, MAX_PATH)) { return L""; } /* * Get the volume name alias (might be different from the unique volume name in rare cases). */ if (!p_GetVolumeNameForVolumeMountPointW || !p_GetVolumeNameForVolumeMountPointW(volumeRootPath, volumeName, MAX_PATH)) { return L""; } /* * Get the unique volume name. */ if (!p_GetVolumeNameForVolumeMountPointW(volumeName, volumeUniqueName, MAX_PATH)) { return L""; } return volumeUniqueName; } static inline POOLMEM *GetMountedVolumeForMountPointPath(POOLMEM *volumepath, POOLMEM *mountpoint) { POOLMEM *fullPath, *buf, *vol; int len; /* * GetUniqueVolumeNameForPath() should be used here */ len = strlen(volumepath) + 1; fullPath = get_pool_memory(PM_FNAME); pm_strcpy(fullPath, volumepath); pm_strcat(fullPath, mountpoint); buf = get_pool_memory(PM_FNAME); GetVolumeNameForVolumeMountPoint(fullPath, buf, len); Dmsg3(200, "%s%s mounts volume %s\n", volumepath, mountpoint, buf); vol = get_pool_memory(PM_FNAME); UTF8_2_wchar(&vol, buf); free_pool_memory(fullPath); free_pool_memory(buf); return vol; } static inline bool HandleVolumeMountPoint(VSSClientGeneric *pVssClient, IVssBackupComponents *pVssObj, POOLMEM *volumepath, POOLMEM *mountpoint) { bool retval = false; HRESULT hr; POOLMEM *vol = NULL; POOLMEM *pvol; VSS_ID pid; vol = GetMountedVolumeForMountPointPath(volumepath, mountpoint); hr = pVssObj->AddToSnapshotSet((LPWSTR)vol, GUID_NULL, &pid); pvol = get_pool_memory(PM_FNAME); wchar_2_UTF8(&pvol, (wchar_t *)vol); if (SUCCEEDED(hr)) { pVssClient->AddVolumeMountPointSnapshots(pVssObj, (wchar_t *)vol); Dmsg1(200, "%s added to snapshotset \n", pvol); retval = true; } else if((unsigned)hr == VSS_ERROR_OBJECT_ALREADY_EXISTS) { Dmsg1(200, "%s already in snapshotset, skipping.\n" ,pvol); } else { Dmsg3(200, "%s with vmp %s could not be added to snapshotset, COM ERROR: 0x%X\n", vol, mountpoint, hr); } free_pool_memory(pvol); if (vol) { free_pool_memory(vol); } return retval; } /* * Helper macro for quick treatment of case statements for error codes */ #define GEN_MERGE(A, B) A##B #define GEN_MAKE_W(A) GEN_MERGE(L, A) #define CHECK_CASE_FOR_CONSTANT(value) \ case value: return (GEN_MAKE_W(#value)); /* * Convert a writer status into a string */ static inline const wchar_t *GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus) { switch (eWriterStatus) { CHECK_CASE_FOR_CONSTANT(VSS_WS_STABLE); CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_FREEZE); CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_THAW); CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_POST_SNAPSHOT); CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_BACKUP_COMPLETE); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_IDENTIFY); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_PREPARE_BACKUP); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_PREPARE_SNAPSHOT); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_FREEZE); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_THAW); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_POST_SNAPSHOT); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_BACKUP_COMPLETE); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_PRE_RESTORE); CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_POST_RESTORE); default: return L"Error or Undefined"; } } #ifdef HAVE_VSS64 /* 64 bit entrypoint name */ #define VSSVBACK_ENTRY "?CreateVssBackupComponents@@YAJPEAPEAVIVssBackupComponents@@@Z" #else /* 32 bit entrypoint name */ #define VSSVBACK_ENTRY "?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z" #endif /* * Constructor */ VSSClientGeneric::VSSClientGeneric() { m_hLib = LoadLibraryA("VSSAPI.DLL"); if (m_hLib) { p_CreateVssBackupComponents = (t_CreateVssBackupComponents) GetProcAddress(m_hLib, VSSVBACK_ENTRY); p_VssFreeSnapshotProperties = (t_VssFreeSnapshotProperties) GetProcAddress(m_hLib, "VssFreeSnapshotProperties"); } } /* * Destructor */ VSSClientGeneric::~VSSClientGeneric() { if (m_hLib) { FreeLibrary(m_hLib); } } /* * Initialize the COM infrastructure and the internal pointers */ bool VSSClientGeneric::Initialize(DWORD dwContext, bool bDuringRestore) { VMPs = 0; VMP_snapshots = 0; HRESULT hr; CComPtr pAsync1; VSS_BACKUP_TYPE backup_type; IVssBackupComponents *pVssObj = (IVssBackupComponents *)m_pVssObject; if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) { Dmsg2(0, "VSSClientGeneric::Initialize: p_CreateVssBackupComponents=0x%08X, p_VssFreeSnapshotProperties=0x%08X\n", p_CreateVssBackupComponents, p_VssFreeSnapshotProperties); Jmsg(m_jcr, M_FATAL, 0, "Entry point CreateVssBackupComponents or VssFreeSnapshotProperties missing.\n"); return false; } /* * Initialize COM */ if (!m_bCoInitializeCalled) { hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (FAILED(hr)) { Dmsg1(0, "VSSClientGeneric::Initialize: CoInitializeEx returned 0x%08X\n", hr); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "CoInitializeEx"); errno = b_errno_win32; return false; } m_bCoInitializeCalled = true; } /* * Initialize COM security */ if (!m_bCoInitializeSecurityCalled) { hr = CoInitializeSecurity(NULL, /* Allow *all* VSS writers to communicate back! */ -1, /* Default COM authentication service */ NULL, /* Default COM authorization service */ NULL, /* reserved parameter */ RPC_C_AUTHN_LEVEL_PKT_PRIVACY, /* Strongest COM authentication level */ RPC_C_IMP_LEVEL_IDENTIFY, /* Minimal impersonation abilities */ NULL, /* Default COM authentication settings */ EOAC_NONE, /* No special options */ NULL); /* Reserved parameter */ if (FAILED(hr)) { Dmsg1(0, "VSSClientGeneric::Initialize: CoInitializeSecurity returned 0x%08X\n", hr); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "CoInitializeSecurity"); errno = b_errno_win32; return false; } m_bCoInitializeSecurityCalled = true; } /* * Release the any old IVssBackupComponents interface */ if (pVssObj) { pVssObj->Release(); m_pVssObject = NULL; } /* * Create new internal backup components object */ hr = p_CreateVssBackupComponents((IVssBackupComponents**)&m_pVssObject); if (FAILED(hr)) { berrno be; Dmsg2(0, "VSSClientGeneric::Initialize: CreateVssBackupComponents returned 0x%08X. ERR=%s\n", hr, be.bstrerror(b_errno_win32)); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "CreateVssBackupComponents"); errno = b_errno_win32; return false; } /* * Define shorthand VssObject with time */ pVssObj = (IVssBackupComponents *)m_pVssObject; if (!bDuringRestore) { #if defined(B_VSS_W2K3) || defined(B_VSS_VISTA) if (dwContext != VSS_CTX_BACKUP) { hr = pVssObj->SetContext(dwContext); if (FAILED(hr)) { Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->SetContext returned 0x%08X\n", hr); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "SetContext"); errno = b_errno_win32; return false; } } #endif /* * 1. InitializeForBackup */ hr = pVssObj->InitializeForBackup(); if (FAILED(hr)) { Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->InitializeForBackup returned 0x%08X\n", hr); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "InitializeForBackup"); errno = b_errno_win32; return false; } /* * 2. SetBackupState */ switch (m_jcr->getJobLevel()) { case L_FULL: backup_type = VSS_BT_FULL; break; case L_DIFFERENTIAL: backup_type = VSS_BT_DIFFERENTIAL; break; case L_INCREMENTAL: backup_type = VSS_BT_INCREMENTAL; break; default: Dmsg1(0, "VSSClientGeneric::Initialize: unknown backup level %d\n", m_jcr->getJobLevel()); backup_type = VSS_BT_FULL; break; } /* * FIXME: need to support partial files - make last parameter true when done */ hr = pVssObj->SetBackupState(true, true, backup_type, false); if (FAILED(hr)) { Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->SetBackupState returned 0x%08X\n", hr); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "SetBackupState"); errno = b_errno_win32; return false; } /* * 3. GatherWriterMetaData */ hr = pVssObj->GatherWriterMetadata(&pAsync1.p); if (FAILED(hr)) { Dmsg1(0, "VSSClientGeneric::Initialize: IVssBackupComponents->GatherWriterMetadata returned 0x%08X\n", hr); JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterMetadata"); errno = b_errno_win32; return false; } /* * Wait for the async operation to finish and checks the result */ if (!WaitAndCheckForAsyncOperation(pAsync1.p)) { /* * Error message already printed */ errno = b_errno_win32; return false; } } /* * We are during restore now? */ m_bDuringRestore = bDuringRestore; /* * Keep the context */ m_dwContext = dwContext; return true; } bool VSSClientGeneric::WaitAndCheckForAsyncOperation(IVssAsync* pAsync) { HRESULT hr; HRESULT hrReturned = S_OK; int timeout = 600; /* 10 minutes.... */ int queryErrors = 0; /* * Wait until the async operation finishes * unfortunately we can't use a timeout here yet. * the interface would allow it on W2k3, * but it is not implemented yet.... */ do { if (hrReturned != S_OK) { Sleep(1000); } hrReturned = S_OK; hr = pAsync->QueryStatus(&hrReturned, NULL); if (FAILED(hr)) { queryErrors++; } } while ((timeout-- > 0) && (hrReturned == VSS_S_ASYNC_PENDING)); /* * Check the result of the asynchronous operation */ if (hrReturned == VSS_S_ASYNC_FINISHED) { return true; } JmsgVssApiStatus(m_jcr, M_FATAL, hr, "Query Async Status after 10 minute wait"); return false; } /* * Add all drive letters that need to be snapshotted. */ void VSSClientGeneric::AddDriveSnapshots(IVssBackupComponents *pVssObj, char *szDriveLetters, bool onefs_disabled) { wstring volume; wchar_t szDrive[3]; VSS_ID pid; szDrive[1] = ':'; szDrive[2] = 0; /* * szDriveLetters contains all drive letters in uppercase * If a drive can not being added, it's converted to lowercase in szDriveLetters */ for (size_t i = 0; i < strlen (szDriveLetters); i++) { szDrive[0] = szDriveLetters[i]; volume = GetUniqueVolumeNameForPath(szDrive); /* * Store uniquevolumname. */ if (SUCCEEDED(pVssObj->AddToSnapshotSet((LPWSTR)volume.c_str(), GUID_NULL, &pid))) { if (debug_level >= 200) { POOLMEM *szBuf = get_pool_memory(PM_FNAME); wchar_2_UTF8(&szBuf, volume.c_str()); Dmsg2(200, "%s added to snapshotset (Drive %s:\\)\n", szBuf, szDrive); free_pool_memory(szBuf); } wcsncpy(m_wszUniqueVolumeName[szDriveLetters[i]-'A'], (LPWSTR)volume.c_str(), MAX_PATH); } else { szDriveLetters[i] = tolower(szDriveLetters[i]); } if (onefs_disabled) { AddVolumeMountPointSnapshots(pVssObj, (LPWSTR)volume.c_str()); } else { Jmsg(m_jcr, M_INFO, 0, "VolumeMountpoints are not processed as onefs = yes.\n"); } } } /* * Add all volume mountpoints that need to be snapshotted. * Volumes can be mounted multiple times, but can only be added to the snapshotset once. * So we skip adding a volume if it is already in snapshotset. * We count the total number of vmps and the number of volumes we added to the snapshotset. */ void VSSClientGeneric::AddVolumeMountPointSnapshots(IVssBackupComponents *pVssObj, LPWSTR volume) { BOOL b; int len; HANDLE hMount; POOLMEM *mp, *path; mp = get_pool_memory(PM_FNAME); path = get_pool_memory(PM_FNAME); wchar_2_UTF8(&path, volume); len = wcslen(volume) + 1; hMount = FindFirstVolumeMountPoint(path, mp, len); if (hMount != INVALID_HANDLE_VALUE) { /* * Count number of vmps. */ VMPs += 1; if (HandleVolumeMountPoint(this, pVssObj, path, mp)) { /* * Count vmps that were snapshotted */ VMP_snapshots += 1; } while ((b = FindNextVolumeMountPoint(hMount, mp, len))) { /* * Count number of vmps. */ VMPs += 1; if (HandleVolumeMountPoint(this, pVssObj, path, mp)) { /* * Count vmps that were snapshotted */ VMP_snapshots += 1; } } } FindVolumeMountPointClose(hMount); free_pool_memory(path); free_pool_memory(mp); } void VSSClientGeneric::ShowVolumeMountPointStats(JCR *jcr) { if (VMPs) { Jmsg(jcr, M_INFO, 0, _("Volume Mount Points found: %d, added to snapshotset: %d\n"), VMPs, VMP_snapshots); } } bool VSSClientGeneric::CreateSnapshots(char *szDriveLetters, bool onefs_disabled) { IVssBackupComponents *pVssObj; CComPtr pAsync1; CComPtr pAsync2; HRESULT hr; /* * See http://msdn.microsoft.com/en-us/library/windows/desktop/aa382870%28v=vs.85%29.aspx. */ if (!m_pVssObject || m_bBackupIsInitialized) { Jmsg(m_jcr, M_FATAL, 0, "No pointer to VssObject or Backup is not Initialized\n"); errno = ENOSYS; return false; } m_uidCurrentSnapshotSet = GUID_NULL; pVssObj = (IVssBackupComponents*)m_pVssObject; /* * startSnapshotSet */ hr = pVssObj->StartSnapshotSet(&m_uidCurrentSnapshotSet); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "StartSnapshotSet"); errno = ENOSYS; return false; } /* * AddToSnapshotSet */ if (szDriveLetters) { AddDriveSnapshots(pVssObj, szDriveLetters, onefs_disabled); } /* * PrepareForBackup */ hr = pVssObj->PrepareForBackup(&pAsync1.p); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "PrepareForBackup"); errno = b_errno_win32; return false; } /* * Wait for the async operation to finish and checks the result. */ if (!WaitAndCheckForAsyncOperation(pAsync1.p)) { errno = b_errno_win32; return false; } /* * Get latest info about writer status. */ if (!CheckWriterStatus()) { errno = b_errno_win32; /* Error already printed */ return false; } /* * DoSnapShotSet */ hr = pVssObj->DoSnapshotSet(&pAsync2.p); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "DoSnapshotSet"); errno = b_errno_win32; return false; } /* * Waits for the async operation to finish and checks the result. */ if (!WaitAndCheckForAsyncOperation(pAsync2.p)) { errno = b_errno_win32; return false; } /* * Get latest info about writer status. */ if (!CheckWriterStatus()) { errno = b_errno_win32; /* Error already printed */ return false; } /* * Query snapshot info. */ QuerySnapshotSet(m_uidCurrentSnapshotSet); SetVSSPathConvert(VSSPathConvert, VSSPathConvertW); m_bBackupIsInitialized = true; return true; } bool VSSClientGeneric::CloseBackup() { bool bRet = false; HRESULT hr; BSTR xml; IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject; if (!m_pVssObject) { Jmsg(m_jcr, M_FATAL, 0, "VssOject is NULL.\n"); errno = ENOSYS; return bRet; } CComPtr pAsync; SetVSSPathConvert(NULL, NULL); m_bBackupIsInitialized = false; hr = pVssObj->BackupComplete(&pAsync.p); if (SUCCEEDED(hr)) { /* * Wait for the async operation to finish and checks the result. */ WaitAndCheckForAsyncOperation(pAsync.p); bRet = true; } else { JmsgVssApiStatus(m_jcr, M_ERROR, hr, "BackupComplete"); errno = b_errno_win32; pVssObj->AbortBackup(); } /* * Get latest info about writer status. */ CheckWriterStatus(); hr = pVssObj->SaveAsXML(&xml); if (SUCCEEDED(hr)) { m_metadata = xml; } else { m_metadata = NULL; } /* * FIXME?: The docs http://msdn.microsoft.com/en-us/library/aa384582%28v=VS.85%29.aspx say this isn't required... */ if (m_uidCurrentSnapshotSet != GUID_NULL) { VSS_ID idNonDeletedSnapshotID = GUID_NULL; LONG lSnapshots; pVssObj->DeleteSnapshots(m_uidCurrentSnapshotSet, VSS_OBJECT_SNAPSHOT_SET, false, &lSnapshots, &idNonDeletedSnapshotID); m_uidCurrentSnapshotSet = GUID_NULL; } if (m_bWriterStatusCurrent) { m_bWriterStatusCurrent = false; pVssObj->FreeWriterStatus(); } pVssObj->Release(); m_pVssObject = NULL; /* * Call CoUninitialize if the CoInitializeEx was performed sucesfully */ if (m_bCoInitializeCalled) { CoUninitialize(); m_bCoInitializeCalled = false; } return bRet; } WCHAR *VSSClientGeneric::GetMetadata() { return m_metadata; } bool VSSClientGeneric::CloseRestore() { IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject; CComPtr pAsync; if (!pVssObj) { errno = ENOSYS; return false; } return true; } /* * Query all the shadow copies in the given set */ void VSSClientGeneric::QuerySnapshotSet(GUID snapshotSetID) { if (!(p_CreateVssBackupComponents && p_VssFreeSnapshotProperties)) { Jmsg(m_jcr, M_FATAL, 0, "CreateVssBackupComponents or VssFreeSnapshotProperties API is NULL.\n"); errno = ENOSYS; return; } memset(m_szShadowCopyName,0,sizeof (m_szShadowCopyName)); if (snapshotSetID == GUID_NULL || m_pVssObject == NULL) { Jmsg(m_jcr, M_FATAL, 0, "snapshotSetID == NULL or VssObject is NULL.\n"); errno = ENOSYS; return; } IVssBackupComponents* pVssObj = (IVssBackupComponents*) m_pVssObject; /* * Get list all shadow copies. */ CComPtr pIEnumSnapshots; HRESULT hr = pVssObj->Query(GUID_NULL, VSS_OBJECT_NONE, VSS_OBJECT_SNAPSHOT, (IVssEnumObject**)(&pIEnumSnapshots)); /* * If there are no shadow copies, just return */ if (FAILED(hr)) { Jmsg(m_jcr, M_FATAL, 0, "No Volume Shadow copies made.\n"); errno = b_errno_win32; return; } /* * Enumerate all shadow copies. */ VSS_OBJECT_PROP Prop; VSS_SNAPSHOT_PROP& Snap = Prop.Obj.Snap; while (true) { /* * Get the next element */ ULONG ulFetched; hr = (pIEnumSnapshots.p)->Next(1, &Prop, &ulFetched); /* * We reached the end of list */ if (ulFetched == 0) break; /* * Print the shadow copy (if not filtered out) */ if (Snap.m_SnapshotSetId == snapshotSetID) { for (int ch='A'-'A';ch<='Z'-'A';ch++) { if (wcscmp(Snap.m_pwszOriginalVolumeName, m_wszUniqueVolumeName[ch]) == 0) { wcsncpy(m_szShadowCopyName[ch],Snap.m_pwszSnapshotDeviceObject, MAX_PATH-1); break; } } } p_VssFreeSnapshotProperties(&Snap); } errno = 0; } /* * Check the status for all selected writers */ bool VSSClientGeneric::CheckWriterStatus() { /* * See http://msdn.microsoft.com/en-us/library/windows/desktop/aa382870%28v=vs.85%29.aspx */ IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject; if (!pVssObj) { Jmsg(m_jcr, M_FATAL, 0, "Cannot get IVssBackupComponents pointer.\n"); errno = ENOSYS; return false; } DestroyWriterInfo(); if (m_bWriterStatusCurrent) { m_bWriterStatusCurrent = false; pVssObj->FreeWriterStatus(); } /* * Gather writer status to detect potential errors */ CComPtr pAsync; HRESULT hr = pVssObj->GatherWriterStatus(&pAsync.p); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterStatus"); errno = b_errno_win32; return false; } /* * Waits for the async operation to finish and checks the result */ if (!WaitAndCheckForAsyncOperation(pAsync.p)) { errno = b_errno_win32; return false; } m_bWriterStatusCurrent = true; unsigned cWriters = 0; hr = pVssObj->GetWriterStatusCount(&cWriters); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterStatusCount"); errno = b_errno_win32; return false; } int nState; POOLMEM *szBuf = get_pool_memory(PM_FNAME); /* * Enumerate each writer */ for (unsigned iWriter = 0; iWriter < cWriters; iWriter++) { VSS_ID idInstance = GUID_NULL; VSS_ID idWriter= GUID_NULL; VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN; CComBSTR bstrWriterName; HRESULT hrWriterFailure = S_OK; /* * Get writer status */ hr = pVssObj->GetWriterStatus(iWriter, &idInstance, &idWriter, &bstrWriterName, &eWriterStatus, &hrWriterFailure); if (FAILED(hr)) { /* * Api failed */ JmsgVssApiStatus(m_jcr, M_WARNING, hr, "GetWriterStatus"); nState = 0; /* Unknown writer state -- API failed */ } else { switch(eWriterStatus) { case VSS_WS_FAILED_AT_IDENTIFY: case VSS_WS_FAILED_AT_PREPARE_BACKUP: case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: case VSS_WS_FAILED_AT_FREEZE: case VSS_WS_FAILED_AT_THAW: case VSS_WS_FAILED_AT_POST_SNAPSHOT: case VSS_WS_FAILED_AT_BACKUP_COMPLETE: case VSS_WS_FAILED_AT_PRE_RESTORE: case VSS_WS_FAILED_AT_POST_RESTORE: #if defined(B_VSS_W2K3) || defined(B_VSS_VISTA) case VSS_WS_FAILED_AT_BACKUPSHUTDOWN: #endif /* * Writer status problem */ wchar_2_UTF8(&szBuf, bstrWriterName.p); JmsgVssWriterStatus(m_jcr, M_WARNING, eWriterStatus, szBuf); nState = -1; /* bad writer state */ break; default: nState = 1; /* Writer state OK */ } } /* * store text info */ char str[1000]; bstrncpy(str, "\"", sizeof(str)); wchar_2_UTF8(&szBuf, bstrWriterName.p); bstrncat(str, szBuf, sizeof(str)); bstrncat(str, "\", State: 0x", sizeof(str)); itoa(eWriterStatus, szBuf, sizeof_pool_memory(szBuf)); bstrncat(str, szBuf, sizeof(str)); bstrncat(str, " (", sizeof(str)); wchar_2_UTF8(&szBuf, GetStringFromWriterStatus(eWriterStatus)); bstrncat(str, szBuf, sizeof(str)); bstrncat(str, ")", sizeof(str)); AppendWriterInfo(nState, (const char *)str); } free_pool_memory(szBuf); errno = 0; return true; } #endif /* WIN32_VSS */ bareos-Release-14.2.6/src/win32/filed/who.h000066400000000000000000000022301263011562700202170ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 */ #define APP_NAME "Bareos-fd" #define LC_APP_NAME "bareos-fd" #define APP_DESC "Bareos File Backup Service" #define SERVICE_DESC "Provides file backup and restore services (bareos client)." #define terminate_app(x) terminate_filed(x) extern void terminate_filed(int sig); extern void VSSInit(); bareos-Release-14.2.6/src/win32/findlib/000077500000000000000000000000001263011562700176005ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/findlib/Makefile000066400000000000000000000035711263011562700212460ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../findlib include ../Makefile.inc INCLUDES = -I../.. \ -I../../include \ -I../include \ -I../../findlib \ -I../compat/include LDLIBS = ../lib/libbareos.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(WINSOCKLIB) LIBBAREOSFIND_SRCS = acl.c attribs.c bfile.c create_file.c \ drivetype.c enable_priv.c find_one.c \ find.c fstype.c hardlink.c match.c mkpath.c \ shadowing.c win32.c xattr.c LIBBAREOSFIND_OBJS = $(LIBBAREOSFIND_SRCS:.c=.o) DYNAMIC_OBJS = $(LIBBAREOSFIND_OBJS) all: libbareosfind.dll bareos$(WIN_VERSION).def: $(DYNAMIC_OBJS) make_def ./make_def $(WIN_VERSION) $(DYNAMIC_OBJS) > $@ libbareosfind.dll: DLL_USAGE = -DBUILDING_DLL libbareosfind.dll: $(DYNAMIC_OBJS) \ bareos$(WIN_VERSION).def $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a $(DYNAMIC_OBJS) bareos$(WIN_VERSION).def $(LDLIBS) -o $@ clean: rm -f *.o bareos$(WIN_VERSION).def distclean: clean rm -f libbareosfind.dll libbareosfind.dll.a # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/findlib/make_def000077500000000000000000000010771263011562700212660ustar00rootroot00000000000000#!/bin/sh # # Make the stupid bareos.def file so that we don't have to do it manually # # Kern Sibbald, June 2007 # NM=nm case $1 in 32) SYMBOL_START=13 ;; 64) SYMBOL_START=20 ;; *) SYMBOL_START=13 ;; esac shift echo "LIBRARY libbareosfind.dll" echo "EXPORTS" echo " " for i in $*; do \ echo "; $i"; \ ${NM} $i | grep "^[0-9a-f]* T " | cut -c${SYMBOL_START}- ; \ echo " "; \ done DATA="\ plugin_bopen \ plugin_bclose \ plugin_bread \ plugin_bwrite \ plugin_blseek \ " for i in ${DATA}; do \ echo "$i DATA"; \ done bareos-Release-14.2.6/src/win32/findlib/win32.c000066400000000000000000000616031263011562700207140ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows specific functions. */ #include "bareos.h" #if defined(HAVE_WIN32) #include "find.h" #include "lib/cbuf.h" /* * We need to analyze if a fileset contains onefs=no as option, because only then * we need to snapshot submounted vmps */ bool win32_onefs_is_disabled(findFILESET *fileset) { findINCEXE *incexe; for (int i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); /* * Look through all files and check */ for (int j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); if (bit_is_set(FO_MULTIFS, fo->flags)) { return true; } } } return false; } /* * For VSS we need to know which windows drives are used, because we create a snapshot * of all used drives. This function returns the number of used drives and fills * szDrives with up to 26 (A..Z) drive names. */ int get_win32_driveletters(findFILESET *fileset, char *szDrives) { int i; int nCount; char *fname, ch; char drive[4], dt[16]; struct stat sb; dlistString *node; findINCEXE *incexe; /* * szDrives must be at least 27 bytes long * Can be already filled by plugin, so check that all * letters are in upper case. There should be no duplicates. */ for (nCount = 0; nCount < 27 && szDrives[nCount]; nCount++) { szDrives[nCount] = toupper(szDrives[nCount]); } /* * First check if there are any non fixed drives in the list * filled by the plugin. VSS can only snapshot fixed drives. */ for (nCount = 0; nCount < 27 && szDrives[nCount]; nCount++) { bsnprintf(drive, sizeof(drive), "%c:\\", szDrives[nCount]); if (drivetype(drive, dt, sizeof(dt))) { if (bstrcmp(dt, "fixed")) { continue; } /* * Inline copy the rest of the string over the current * drive letter. */ bstrinlinecpy(szDrives + nCount, szDrives + nCount + 1); } } if (fileset) { for (i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); /* * Look through all files and check */ foreach_dlist(node, &incexe->name_list) { fname = node->c_str(); /* * See if the entry doesn't have the FILE_ATTRIBUTE_VOLUME_MOUNT_POINT flag set. */ if (stat(fname, &sb) == 0) { if (sb.st_rdev & FILE_ATTRIBUTE_VOLUME_MOUNT_POINT) { continue; } } /* * fname should match x:/ */ if (strlen(fname) >= 2 && B_ISALPHA(fname[0]) && fname[1] == ':') { /* * VSS can only snapshot fixed drives. */ bstrncpy(drive, fname, sizeof(drive)); drive[2] = '\\'; drive[3] = '\0'; /* * Lookup the drive type. */ if (drivetype(drive, dt, sizeof(dt))) { if (bstrcmp(dt, "fixed")) { /* * Always add in uppercase */ ch = toupper(fname[0]); /* * If not found in string, add drive letter */ if (!strchr(szDrives, ch)) { szDrives[nCount] = ch; szDrives[nCount + 1] = 0; nCount++; } } } } } } } return nCount; } /* * For VSS we need to know which windows virtual mountpoints are used, because we create * a snapshot of all used drives and virtual mountpoints. This function returns the number * of used virtual mountpoints and fills szVmps with a list of all virtual mountpoints. */ int get_win32_virtualmountpoints(findFILESET *fileset, dlist **szVmps) { int i, cnt; char *fname; struct stat sb; dlistString *node; findINCEXE *incexe; POOLMEM *devicename; cnt = 0; if (fileset) { devicename = get_pool_memory(PM_FNAME); for (i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); /* * Look through all files and check */ foreach_dlist(node, &incexe->name_list) { fname = node->c_str(); /* * See if the entry has the FILE_ATTRIBUTE_VOLUME_MOUNT_POINT flag set. */ if (stat(fname, &sb) == 0) { if (!(sb.st_rdev & FILE_ATTRIBUTE_VOLUME_MOUNT_POINT)) { continue; } } else { continue; } if (win32_get_vmp_devicename(fname, &devicename)) { /* * See if we need to allocate a new dlist. */ if (!cnt) { if (!*szVmps) { *szVmps = (dlist *)malloc(sizeof(dlist)); (*szVmps)->init(); } } (*szVmps)->append(new_dlistString(devicename)); cnt++; } } } free_pool_memory(devicename); } return cnt; } static inline bool wanted_drive_type(const char *drive, findINCEXE *incexe) { int i,j; char dt[16]; findFOPTS *fo; bool done = false; bool wanted = true; /* * Lookup the drive type. */ if (!drivetype(drive, dt, sizeof(dt))) { return false; } /* * We start the loop with done set to false and wanted * to true so when there are no drivetype selections we * select any drivetype. */ for (i = 0; !done && i < incexe->opts_list.size(); i++) { fo = (findFOPTS *)incexe->opts_list.get(i); /* * If there is any drivetype selection set the default * selection to false. */ if (fo->drivetype.size()) { wanted = false; } for (j = 0; !done && j < fo->drivetype.size(); j++) { if (bstrcasecmp(dt, (char *)fo->drivetype.get(j))) { wanted = true; done = true; } } } return wanted; } bool expand_win32_fileset(findFILESET *fileset) { int i; char *bp; dlistString *node; findINCEXE *incexe; char drives[MAX_NAME_LENGTH]; for (i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); foreach_dlist(node, &incexe->name_list) { Dmsg1(100, "Checking %s\n", node->c_str()); if (bstrcmp(node->c_str(), "/")) { /* * Request for auto expansion but no support for it. */ if (!p_GetLogicalDriveStringsA) { return false; } /* * we want to add all available local drives to our fileset * if we have "/" specified in the fileset. We want to remove * the "/" pattern itself that gets expanded into all * available drives. */ incexe->name_list.remove(node); if (p_GetLogicalDriveStringsA(sizeof(drives), drives) != 0) { bp = drives; while (bp && strlen(bp) > 0) { /* * Apply any drivetype selection to the currently * processed item. */ if (wanted_drive_type(bp, incexe)) { if (*(bp + 2) == '\\') { *(bp + 2) = '/'; /* 'x:\' -> 'x:/' */ } Dmsg1(100, "adding drive %s\n", bp); incexe->name_list.append(new_dlistString(bp)); } if ((bp = strchr(bp, '\0'))) { bp++; } } } else { return false; } /* * No need to search further in the include list when we have * found what we were looking for. */ break; } } } return true; } static inline int count_include_list_file_entries(FF_PKT *ff) { int cnt = 0; findFILESET *fileset; findINCEXE *incexe; fileset = ff->fileset; if (fileset) { for (int i = 0; i < fileset->include_list.size(); i++) { incexe = (findINCEXE *)fileset->include_list.get(i); cnt += incexe->name_list.size(); } } return cnt; } /* * Automatically exclude all files and paths defined in Registry Key * "SYSTEM\\CurrentControlSet\\Control\\BackupRestore\\FilesNotToBackup" * * Files/directories with wildcard characters are added to an * options block with flags "exclude=yes" as "wild=dir/file". * This options block is created and prepended by us. * */ #define MAX_VALUE_NAME 16383 #define REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Control\\BackupRestore\\FilesNotToBackup" bool exclude_win32_not_to_backup_registry_entries(JCR *jcr, FF_PKT *ff) { bool retval = false; uint32_t wild_count = 0; DWORD retCode; HKEY hKey; /* * If we do not have "File = " directives (e.g. only plugin calls) * we do not create excludes for the NotForBackup RegKey */ if (count_include_list_file_entries(ff) == 0 ) { Qmsg(jcr, M_INFO, 1, _("Fileset has no \"File=\" directives, ignoring FilesNotToBackup Registry key\n")); return true; } /* * If autoexclude is set to no in fileset options somewhere, we do not * automatically exclude files from FilesNotToBackup Registry Key */ for (int i = 0; i < ff->fileset->include_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)ff->fileset->include_list.get(i); for (int j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); if (bit_is_set(FO_NO_AUTOEXCL, fo->flags)) { Qmsg(jcr, M_INFO, 1, _("Fileset has autoexclude disabled, ignoring FilesNotToBackup Registry key\n")); return true; } } } retCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(REGISTRY_KEY), 0, KEY_READ, &hKey); if (retCode == ERROR_SUCCESS ) { POOL_MEM achClass(PM_MESSAGE), achValue(PM_MESSAGE), dwKeyEn(PM_MESSAGE), expandedKey(PM_MESSAGE), destination(PM_MESSAGE); DWORD cchClassName; /* Size of class string */ DWORD cSubKeys = 0; /* Number of subkeys */ DWORD cbMaxSubKey; /* Longest subkey size */ DWORD cchMaxClass; /* Longest class string */ DWORD cValues; /* Number of values for key */ DWORD cchMaxValue; /* Longest value name */ DWORD cbMaxValueData; /* Longest value data */ DWORD cbSecurityDescriptor; /* Size of security descriptor */ FILETIME ftLastWriteTime; /* Last write time */ DWORD cchValue; /* Size of value string */ findINCEXE *include; /* * Make sure the variable are big enough to contain the data. */ achClass.check_size(MAX_PATH); /* * Get the class name and the value count. */ cchClassName = achClass.size(); retCode = RegQueryInfoKey(hKey, /* Key handle */ achClass.c_str(), /* Buffer for class name */ &cchClassName, /* Size of class string */ NULL, /* Reserved */ &cSubKeys, /* Number of subkeys */ &cbMaxSubKey, /* Longest subkey size */ &cchMaxClass, /* Longest class string */ &cValues, /* Number of values for this key */ &cchMaxValue, /* Longest value name */ &cbMaxValueData, /* Longest value data */ &cbSecurityDescriptor, /* Security descriptor */ &ftLastWriteTime); /* Last write time */ if (cValues) { findFOPTS *fo; /* * Prepare include block to do exclusion via wildcards in options */ new_preinclude(ff->fileset); include = (findINCEXE*)ff->fileset->include_list.get(0); if (include->opts_list.size() == 0) { /* * Create new options block in include block for the wildcard excludes */ Dmsg0(100, "prepending new options block\n"); new_options(ff, ff->fileset->incexe); } else { Dmsg0(100, "reusing existing options block\n"); } fo = (findFOPTS *)include->opts_list.get(0); set_bit(FO_EXCLUDE, fo->flags); /* exclude = yes */ set_bit(FO_IGNORECASE, fo->flags); /* ignore case = yes */ /* * Make sure the variables are big enough to contain the data. */ achValue.check_size(MAX_VALUE_NAME); dwKeyEn.check_size(MAX_PATH); expandedKey.check_size(MAX_PATH); destination.check_size(MAX_PATH); for (unsigned int i = 0; i < cValues; i++) { pm_strcpy(achValue, ""); cchValue = achValue.size(); retCode = RegEnumValue(hKey, i, achValue.c_str(), &cchValue, NULL, NULL, NULL, NULL); if (retCode == ERROR_SUCCESS ){ DWORD dwLen; Dmsg2(100 , "(%d) \"%s\" : \n", i + 1, achValue.c_str()); dwLen = dwKeyEn.size(); retCode = RegQueryValueEx(hKey, achValue.c_str(), 0, NULL, (LPBYTE)dwKeyEn.c_str(), &dwLen); if (retCode == ERROR_SUCCESS) { char *lpValue; /* * Iterate over each string, expand the %xxx% variables and * process them for addition to exclude block or wildcard options block */ for (lpValue = dwKeyEn.c_str(); lpValue && *lpValue; lpValue = strchr(lpValue, '\0') + 1) { char *s, *d; ExpandEnvironmentStrings(lpValue, expandedKey.c_str(), expandedKey.size()); Dmsg1(100, " \"%s\"\n", expandedKey.c_str()); /* * Never add single character entries. Probably known buggy DRM Entry in Windows XP / 2003 */ if (strlen(expandedKey.c_str()) <= 1) { Dmsg0(100, TEXT("Single character entry ignored. Probably reading buggy DRM entry on Windows XP/2003 SP 1 and later\n")); } else { pm_strcpy(destination, ""); /* * Do all post processing. * - Replace '\' by '/' * - Strip any trailing /s patterns. * - Check if wildcards are used. */ s = expandedKey.c_str(); d = destination.c_str(); /* * Begin with \ means all drives */ if (*s == '\\') { d += pm_strcpy(destination, "[A-Z]:"); } while (*s) { switch (*s) { case '\\': *d++ = '/'; s++; break; case ' ': if (bstrcmp(s, " /s")) { *d = '\0'; *s = '\0'; continue; } /* FALLTHROUGH */ default: *d++ = *s++; break; } } *d = '\0'; Dmsg1(100, " -> \"%s\"\n", destination.c_str() ); fo->wild.append(bstrdup(destination.c_str())); wild_count++; } } } else { Dmsg0(100, TEXT("RegGetValue failed \n")); } } } } Qmsg(jcr, M_INFO, 0, _("Created %d wildcard excludes from FilesNotToBackup Registry key\n"), wild_count); RegCloseKey(hKey); retval = true; } else { Qmsg(jcr, M_ERROR, 0, _("Failed to open FilesNotToBackup Registry Key\n")); } return retval; } /* * Windows specific code for restoring EFS data. */ struct CP_THREAD_SAVE_DATA { uint32_t data_len; /* Length of Data */ POOLMEM *data; /* Data */ }; struct CP_THREAD_CTX { BFILE *bfd; /* Filehandle */ int nr_save_elements; /* Number of save items in save_data */ CP_THREAD_SAVE_DATA *save_data; /* To save data (cached structure build during restore) */ circbuf *cb; /* Circular buffer for passing work to copy thread */ bool started; /* Copy thread consuming data */ bool flushed; /* Copy thread flushed data */ pthread_t thread_id; /* Id of copy thread */ pthread_mutex_t lock; /* Lock the structure */ pthread_cond_t start; /* Start consuming data from the Circular buffer */ pthread_cond_t flush; /* Flush data from the Circular buffer */ }; /* * Callback method for WriteEncryptedFileRaw() */ static DWORD WINAPI receive_efs_data(PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength) { CP_THREAD_SAVE_DATA *save_data; CP_THREAD_CTX *context = (CP_THREAD_CTX *)pvCallbackContext; /* * Dequeue an item from the circular buffer. */ save_data = (CP_THREAD_SAVE_DATA *)context->cb->dequeue(); if (save_data) { if (save_data->data_len > *ulLength) { Dmsg2(100, "Restore of data bigger then allowed EFS buffer %d vs %d\n", save_data->data_len, *ulLength); *ulLength = 0; } else { memcpy(pbData, save_data->data, save_data->data_len); *ulLength = save_data->data_len; } } else { *ulLength = 0; } return ERROR_SUCCESS; } /* * Copy thread cancel handler. */ static void copy_cleanup_thread(void *data) { CP_THREAD_CTX *context = (CP_THREAD_CTX *)data; pthread_mutex_unlock(&context->lock); } /* * Actual copy thread that restores EFS data. */ static void *copy_thread(void *data) { CP_THREAD_CTX *context = (CP_THREAD_CTX *)data; if (pthread_mutex_lock(&context->lock) != 0) { goto bail_out; } /* * When we get canceled make sure we run the cleanup function. */ pthread_cleanup_push(copy_cleanup_thread, data); while (1) { /* * Wait for the moment we are supposed to start. * We are signalled by the restore thread. */ pthread_cond_wait(&context->start, &context->lock); context->started = true; pthread_mutex_unlock(&context->lock); if (p_WriteEncryptedFileRaw((PFE_IMPORT_FUNC)receive_efs_data, context, context->bfd->pvContext)) { goto bail_out; } /* * Need to synchronize the main thread and this one so the main thread cannot miss the conditional signal. */ if (pthread_mutex_lock(&context->lock) != 0) { goto bail_out; } /* * Signal the main thread we flushed the data and the BFD can be closed. */ pthread_cond_signal(&context->flush); context->started = false; context->flushed = true; } pthread_cleanup_pop(1); bail_out: return NULL; } /* * Create a copy thread that restores the EFS data. */ static inline bool setup_copy_thread(JCR *jcr, BFILE *bfd) { int nr_save_elements; CP_THREAD_CTX *new_context; new_context = (CP_THREAD_CTX *)malloc(sizeof(CP_THREAD_CTX)); new_context->started = false; new_context->flushed = false; new_context->cb = New(circbuf); nr_save_elements = new_context->cb->capacity(); new_context->save_data = (CP_THREAD_SAVE_DATA *)malloc(nr_save_elements * sizeof(CP_THREAD_SAVE_DATA)); memset(new_context->save_data, 0, nr_save_elements * sizeof(CP_THREAD_SAVE_DATA)); new_context->nr_save_elements = nr_save_elements; if (pthread_mutex_init(&new_context->lock, NULL) != 0) { goto bail_out; } if (pthread_cond_init(&new_context->start, NULL) != 0) { pthread_mutex_destroy(&new_context->lock); goto bail_out; } if (pthread_create(&new_context->thread_id, NULL, copy_thread, (void *)new_context) != 0) { pthread_cond_destroy(&new_context->start); pthread_mutex_destroy(&new_context->lock); goto bail_out; } jcr->cp_thread = new_context; return true; bail_out: free(new_context->save_data); delete new_context->cb; free(new_context); return false; } /* * Send data to the copy thread that restores EFS data. */ int win32_send_to_copy_thread(JCR *jcr, BFILE *bfd, char *data, const int32_t length) { circbuf *cb; int slotnr; CP_THREAD_SAVE_DATA *save_data; if (!p_WriteEncryptedFileRaw) { Jmsg0(jcr, M_FATAL, 0, _("Encrypted file restore but no EFS support functions\n")); } /* * If no copy thread started do it now. */ if (!jcr->cp_thread) { if (!setup_copy_thread(jcr, bfd)) { Jmsg0(jcr, M_FATAL, 0, _("Failed to start encrypted data restore copy thread\n")); return -1; } } cb = jcr->cp_thread->cb; /* * See if the bfd changed. */ if (jcr->cp_thread->bfd != bfd) { jcr->cp_thread->bfd = bfd; } /* * Find out which next slot will be used on the Circular Buffer. * The method will block when the circular buffer is full until a slot is available. */ slotnr = cb->next_slot(); save_data = &jcr->cp_thread->save_data[slotnr]; /* * If this is the first time we use this slot we need to allocate some memory. */ if (!save_data->data) { save_data->data = get_pool_memory(PM_BSOCK); } save_data->data = check_pool_memory_size(save_data->data, length + 1); memcpy(save_data->data, data, length); save_data->data_len = length; cb->enqueue(save_data); /* * Signal the copy thread its time to start if it didn't start yet. */ if (!jcr->cp_thread->started) { pthread_cond_signal(&jcr->cp_thread->start); } return length; } /* * Flush the copy thread so we can close the BFD. */ void win32_flush_copy_thread(JCR *jcr) { CP_THREAD_CTX *context = jcr->cp_thread; if (pthread_mutex_lock(&context->lock) != 0) { return; } /* * In essence the flush should work in one shot but be a bit more conservative. */ while (!context->flushed) { /* * Tell the copy thread to flush out all data. */ context->cb->flush(); /* * Wait for the copy thread to say it flushed the data out. */ pthread_cond_wait(&context->flush, &context->lock); } context->flushed = false; pthread_mutex_unlock(&context->lock); } /* * Cleanup all data allocated for the copy thread. */ void win32_cleanup_copy_thread(JCR *jcr) { int slotnr; /* * Stop the copy thread. */ if (!pthread_equal(jcr->cp_thread->thread_id, pthread_self())) { pthread_cancel(jcr->cp_thread->thread_id); pthread_join(jcr->cp_thread->thread_id, NULL); } /* * Free all data allocated along the way. */ for (slotnr = 0; slotnr < jcr->cp_thread->nr_save_elements; slotnr++) { if (jcr->cp_thread->save_data[slotnr].data) { free_pool_memory(jcr->cp_thread->save_data[slotnr].data); } } free(jcr->cp_thread->save_data); delete jcr->cp_thread->cb; free(jcr->cp_thread); jcr->cp_thread = NULL; } #endif bareos-Release-14.2.6/src/win32/generic/000077500000000000000000000000001263011562700176055ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/generic/main.c000066400000000000000000000536531263011562700207110ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2011 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 * * Note, some of the original Bareos Windows startup and service handling code * was derived from VNC code that was used in apcupsd then ported to * Bareos. However, since then the code has been significantly enhanced * and largely rewritten. * * Evidently due to the nature of Windows startup code and service * handling code, certain similarities remain. Thanks to the original * VNC authors. * * This is a generic main routine, which is used by all three * of the daemons. Each one compiles it with slightly different * #defines. */ #include "bareos.h" #include "win32.h" #include "who.h" #include #include #undef _WIN32_IE #ifdef MINGW64 # define _WIN32_IE 0x0501 #else # define _WIN32_IE 0x0401 #endif // MINGW64 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #include /* Globals */ HINSTANCE appInstance; DWORD mainthreadId; bool opt_debug = false; bool have_service_api; DWORD service_thread_id = 0; char win_os[300]; bool GetWindowsVersionString(LPTSTR osbuf, int maxsiz); #define MAX_COMMAND_ARGS 100 static char *command_args[MAX_COMMAND_ARGS] = { (char *)LC_APP_NAME, NULL }; static int num_command_args = 1; static pid_t main_pid; static pthread_t main_tid; const char usage[] = APP_NAME "[/debug] [/service] [/run] [/kill] [/install] [/remove] [/help]\n"; /* * * Main Windows entry point. * * We parse the command line and either calls the main App * or starts up the service. */ int WINAPI WinMain(HINSTANCE Instance, HINSTANCE /*PrevInstance*/, PSTR CmdLine, int /*show*/) { char *cmdLine = CmdLine; char *wordPtr, *tempPtr; int i, quote; OSVERSIONINFO osversioninfo; osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo); /* Save the application instance and main thread id */ appInstance = Instance; mainthreadId = GetCurrentThreadId(); if (GetVersionEx(&osversioninfo) && osversioninfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { have_service_api = true; } GetWindowsVersionString(win_os, sizeof(win_os)); main_pid = getpid(); main_tid = pthread_self(); INITCOMMONCONTROLSEX initCC = { sizeof(INITCOMMONCONTROLSEX), ICC_STANDARD_CLASSES }; InitCommonControlsEx(&initCC); /* * Funny things happen with the command line if the * execution comes from c:/Program Files/bareos/bareos.exe * We get a command line like: Files/bareos/bareos.exe" options * I.e. someone stops scanning command line on a space, not * realizing that the filename is quoted!!!!!!!!!! * So if first character is not a double quote and * the last character before first space is a double * quote, we throw away the junk. */ wordPtr = cmdLine; while (*wordPtr && *wordPtr != ' ') wordPtr++; if (wordPtr > cmdLine) /* backup to char before space */ wordPtr--; /* if first character is not a quote and last is, junk it */ if (*cmdLine != '"' && *wordPtr == '"') { cmdLine = wordPtr + 1; } /* * Build Unix style argc *argv[] for the main "Unix" code * stripping out any Windows options */ /* Don't NULL command_args[0] !!! */ for (i=1;i #include #include #ifndef PRODUCT_UNLICENSED #define PRODUCT_UNLICENSED 0xABCDABCD #define PRODUCT_BUSINESS 0x00000006 #define PRODUCT_BUSINESS_N 0x00000010 #define PRODUCT_CLUSTER_SERVER 0x00000012 #define PRODUCT_DATACENTER_SERVER 0x00000008 #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C #define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027 #define PRODUCT_DATACENTER_SERVER_V 0x00000025 #define PRODUCT_ENTERPRISE 0x00000004 #define PRODUCT_ENTERPRISE_E 0x00000046 #define PRODUCT_ENTERPRISE_N 0x0000001B #define PRODUCT_ENTERPRISE_SERVER 0x0000000A #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E #define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029 #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F #define PRODUCT_ENTERPRISE_SERVER_V 0x00000026 #define PRODUCT_HOME_BASIC 0x00000002 #define PRODUCT_HOME_BASIC_E 0x00000043 #define PRODUCT_HOME_BASIC_N 0x00000005 #define PRODUCT_HOME_PREMIUM 0x00000003 #define PRODUCT_HOME_PREMIUM_E 0x00000044 #define PRODUCT_HOME_PREMIUM_N 0x0000001A #define PRODUCT_HYPERV 0x0000002A #define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E #define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020 #define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F #define PRODUCT_PROFESSIONAL 0x00000030 #define PRODUCT_PROFESSIONAL_E 0x00000045 #define PRODUCT_PROFESSIONAL_N 0x00000031 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 #define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023 #define PRODUCT_SERVER_FOUNDATION 0x00000021 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 #define PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038 #define PRODUCT_STANDARD_SERVER 0x00000007 #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D #define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028 #define PRODUCT_STANDARD_SERVER_V 0x00000024 #define PRODUCT_STARTER 0x0000000B #define PRODUCT_STARTER_E 0x00000042 #define PRODUCT_STARTER_N 0x0000002F #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 #define PRODUCT_UNDEFINED 0x00000000 #define PRODUCT_ULTIMATE 0x00000001 #define PRODUCT_ULTIMATE_E 0x00000047 #define PRODUCT_ULTIMATE_N 0x0000001C #define PRODUCT_WEB_SERVER 0x00000011 #define PRODUCT_WEB_SERVER_CORE 0x0000001D #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x19 #define SM_SERVERR2 89 #define VER_SERVER_NT 0x80000000 #endif #ifndef PRODUCT_PROFESSIONAL #define PRODUCT_PROFESSIONAL 0x00000030 #endif #ifndef VER_SUITE_STORAGE_SERVER #define VER_SUITE_STORAGE_SERVER 0x00002000 #endif #ifndef VER_SUITE_COMPUTE_SERVER #define VER_SUITE_COMPUTE_SERVER 0x00004000 #endif /* Unknown value */ #undef VER_SUITE_WH_SERVER #define VER_SUITE_WH_SERVER -1 typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); /* * Get Windows version display string */ bool GetWindowsVersionString(LPTSTR osbuf, int maxsiz) { OSVERSIONINFOEX osvi; SYSTEM_INFO si; PGNSI pGNSI; PGPI pGPI; BOOL bOsVersionInfoEx; DWORD dwType; memset(&si, 0, sizeof(SYSTEM_INFO)); memset(&osvi, 0, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi))) return 1; // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); if (pGNSI) { pGNSI(&si); } else { GetSystemInfo(&si); } if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion > 4) { bstrncpy(osbuf, TEXT("Microsoft "), maxsiz); /* * Test for the specific product. */ switch (osvi.dwMajorVersion) { case 6: switch (osvi.dwMinorVersion) { case 0: if (osvi.wProductType == VER_NT_WORKSTATION) { bstrncat(osbuf, TEXT("Windows Vista "), maxsiz); } else { bstrncat(osbuf, TEXT("Windows Server 2008 "), maxsiz); } break; case 1: if (osvi.wProductType == VER_NT_WORKSTATION) { bstrncat(osbuf, TEXT("Windows 7 "), maxsiz); } else { bstrncat(osbuf, TEXT("Windows Server 2008 R2 "), maxsiz); } break; case 2: if (osvi.wProductType == VER_NT_WORKSTATION) { bstrncat(osbuf, TEXT("Windows 8 "), maxsiz); } else { bstrncat(osbuf, TEXT("Windows Server 2012 "), maxsiz); } break; default: bstrncat(osbuf, TEXT("Windows Unknown Release "), maxsiz); break; } pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); if (pGPI) { pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); } else { dwType = PRODUCT_HOME_BASIC; } switch (dwType) { case PRODUCT_ULTIMATE: bstrncat(osbuf, TEXT("Ultimate Edition"), maxsiz); break; case PRODUCT_PROFESSIONAL: bstrncat(osbuf, TEXT("Professional"), maxsiz); break; case PRODUCT_HOME_PREMIUM: bstrncat(osbuf, TEXT("Home Premium Edition"), maxsiz); break; case PRODUCT_HOME_BASIC: bstrncat(osbuf, TEXT("Home Basic Edition"), maxsiz); break; case PRODUCT_ENTERPRISE: bstrncat(osbuf, TEXT("Enterprise Edition"), maxsiz); break; case PRODUCT_BUSINESS: bstrncat(osbuf, TEXT("Business Edition"), maxsiz); break; case PRODUCT_STARTER: bstrncat(osbuf, TEXT("Starter Edition"), maxsiz); break; case PRODUCT_CLUSTER_SERVER: bstrncat(osbuf, TEXT("Cluster Server Edition"), maxsiz); break; case PRODUCT_DATACENTER_SERVER: bstrncat(osbuf, TEXT("Datacenter Edition"), maxsiz); break; case PRODUCT_DATACENTER_SERVER_CORE: bstrncat(osbuf, TEXT("Datacenter Edition (core installation)"), maxsiz); break; case PRODUCT_ENTERPRISE_SERVER: bstrncat(osbuf, TEXT("Enterprise Edition"), maxsiz); break; case PRODUCT_ENTERPRISE_SERVER_CORE: bstrncat(osbuf, TEXT("Enterprise Edition (core installation)"), maxsiz); break; case PRODUCT_ENTERPRISE_SERVER_IA64: bstrncat(osbuf, TEXT("Enterprise Edition for Itanium-based Systems"), maxsiz); break; case PRODUCT_SMALLBUSINESS_SERVER: bstrncat(osbuf, TEXT("Small Business Server"), maxsiz); break; case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: bstrncat(osbuf, TEXT("Small Business Server Premium Edition"), maxsiz); break; case PRODUCT_STANDARD_SERVER: bstrncat(osbuf, TEXT("Standard Edition"), maxsiz); break; case PRODUCT_STANDARD_SERVER_CORE: bstrncat(osbuf, TEXT("Standard Edition (core installation)"), maxsiz); break; case PRODUCT_WEB_SERVER: bstrncat(osbuf, TEXT("Web Server Edition"), maxsiz); break; } break; case 5: switch (osvi.dwMinorVersion) { case 2: if (GetSystemMetrics(SM_SERVERR2)) { bstrncat(osbuf, TEXT("Windows Server 2003 R2 "), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER) { bstrncat(osbuf, TEXT("Windows Storage Server 2003"), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER) { bstrncat(osbuf, TEXT("Windows Home Server"), maxsiz); } else if (osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { bstrncat(osbuf, TEXT("Windows XP Professional x64 Edition"), maxsiz); } else { bstrncat(osbuf, TEXT("Windows Server 2003 "), maxsiz); } /* * Test for the server type. */ if (osvi.wProductType != VER_NT_WORKSTATION) { if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { bstrncat(osbuf, TEXT("Datacenter Edition for Itanium-based Systems"), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { bstrncat(osbuf, TEXT("Enterprise Edition for Itanium-based Systems"), maxsiz); } } else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { bstrncat(osbuf, TEXT("Datacenter x64 Edition"), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { bstrncat(osbuf, TEXT("Enterprise x64 Edition"), maxsiz); } else { bstrncat(osbuf, TEXT("Standard x64 Edition"), maxsiz); } } else { if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) { bstrncat(osbuf, TEXT("Compute Cluster Edition"), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { bstrncat(osbuf, TEXT("Datacenter Edition"), maxsiz); } else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { bstrncat(osbuf, TEXT("Enterprise Edition"), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_BLADE) { bstrncat(osbuf, TEXT("Web Edition"), maxsiz); } else { bstrncat(osbuf, TEXT("Standard Edition"), maxsiz); } } } break; case 1: bstrncat(osbuf, TEXT("Windows XP "), maxsiz); if (osvi.wSuiteMask & VER_SUITE_PERSONAL) { bstrncat(osbuf, TEXT("Home Edition"), maxsiz); } else { bstrncat(osbuf, TEXT("Professional"), maxsiz); } break; case 0: bstrncat(osbuf, TEXT("Windows 2000 "), maxsiz); if (osvi.wProductType == VER_NT_WORKSTATION) { bstrncat(osbuf, TEXT("Professional"), maxsiz); } else { if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { bstrncat(osbuf, TEXT("Datacenter Server"), maxsiz); } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { bstrncat(osbuf, TEXT("Advanced Server"), maxsiz); } else { bstrncat(osbuf, TEXT("Server"), maxsiz); } } break; } break; default: break; } /* * Include service pack (if any) and build number. */ if (_tcslen(osvi.szCSDVersion) > 0) { bstrncat(osbuf, TEXT(" ") , maxsiz); bstrncat(osbuf, osvi.szCSDVersion, maxsiz); } char buf[80]; snprintf(buf, 80, " (build %d)", (int)osvi.dwBuildNumber); bstrncat(osbuf, buf, maxsiz); if (osvi.dwMajorVersion >= 6) { if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) bstrncat(osbuf, TEXT(", 64-bit"), maxsiz); else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) bstrncat(osbuf, TEXT(", 32-bit"), maxsiz); } return true; } else { bstrncpy(osbuf, "Unknown Windows version.", maxsiz); return true; } } bareos-Release-14.2.6/src/win32/generic/protos.h000066400000000000000000000032231263011562700213040ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2009 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 */ #define log_error_message(msg) LogLastErrorMsg((msg), __FILE__, __LINE__) extern int BareosAppMain(); extern void LogLastErrorMsg(const char *msg, const char *fname, int lineno); extern int BareosMain(int argc, char *argv[]); extern BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); extern void d_msg(const char *, int, int, const char *, ...); extern char *bareos_status(char *buf, int buf_len); /* service.cpp */ bool postToBareos(UINT message, WPARAM wParam, LPARAM lParam); bool isAService(); int installService(const char *svc); int removeService(); int stopRunningBareos(); int bareosServiceMain(); /* Globals */ extern DWORD service_thread_id; extern DWORD service_error; extern bool opt_debug; extern bool have_service_api; extern HINSTANCE appInstance; extern int bareosstat; bareos-Release-14.2.6/src/win32/generic/res.h000066400000000000000000000025531263011562700205540ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 */ /* Icon definitions */ #define IDI_BAREOS 100 #define IDI_IDLE 101 #define IDI_RUNNING 102 #define IDI_JOB_ERROR 103 #define IDI_JOB_WARNING 104 #define IDR_TRAYMENU 105 #define IDB_BAREOSBMP 106 #define IDC_TEXTDISPLAY 1000 #define ID_ABOUT 40000 #define ID_STATUS 40001 #define ID_CLOSE 40002 /* Dialog definitions */ #define IDD_ABOUT 201 #define IDD_STATUS 202 bareos-Release-14.2.6/src/win32/generic/service.c000066400000000000000000000503011263011562700214100ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 * * This is a generic service routine, which is used by all three * of the daemons. Each one compiles it with slightly different * #defines. */ #include "bareos.h" #include "win32.h" #include "who.h" /* * Other Window component dependencies */ #define BAREOS_DEPENDENCIES __TEXT("tcpip\0afd\0") /* * Service globals */ SERVICE_STATUS_HANDLE service_handle; SERVICE_STATUS service_status; DWORD service_error = 0; static bool is_service = false; /* * Forward references */ static void set_service_description(SC_HANDLE hSCManager, SC_HANDLE hService, LPSTR lpDesc); void WINAPI serviceControlCallback(DWORD ctrlcode); BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); DWORD WINAPI bareosWorkerThread(LPVOID lpwThreadParam); /* * Post a message to a running instance of the app */ bool postToBareos(UINT message, WPARAM wParam, LPARAM lParam) { /* * Locate the Bareos menu window */ HWND hservwnd = FindWindow(APP_NAME, NULL); if (hservwnd == NULL) { return false; } /* * Post the message to Bareos */ PostMessage(hservwnd, message, wParam, lParam); return true; } /* * Running as a service? */ bool isAService() { return is_service; } /* * terminate any running Bareos */ int stopRunningBareos() { postToBareos(WM_CLOSE, 0, 0); sleep(5); return 0; } /* * New style service start callback handler for the OS. * the OS returns control here immediately after starting * the service. */ void WINAPI serviceStartCallback(DWORD argc, char **argv) { DWORD dwThreadID; /* * Register our service */ service_handle = RegisterServiceCtrlHandler(APP_NAME, serviceControlCallback); if (!service_handle) { log_error_message(_("RegisterServiceCtlHandler failed")); MessageBox(NULL, _("Failure contacting the Service Handler"), APP_DESC, MB_OK); return; } service_status.dwServiceType = SERVICE_WIN32; service_status.dwServiceSpecificExitCode = 0; /* * Report status */ if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 45000)) { ReportStatus(SERVICE_STOPPED, service_error, 0); log_error_message(_("Service start report failed")); return; } /* * Now create the Bareos worker thread */ (void)CreateThread(NULL, 0, bareosWorkerThread, NULL, 0, &dwThreadID); return; } /* * Stop our service */ static void serviceStop() { /* Post a quit message our service thread */ if (service_thread_id != 0) { PostThreadMessage(service_thread_id, WM_QUIT, 0, 0); } } /* * Service Control callback handler. The OS can call us here at any time, most often to stop the service. */ void WINAPI serviceControlCallback(DWORD ctrlcode) { switch(ctrlcode) { case SERVICE_CONTROL_STOP: service_status.dwCurrentState = SERVICE_STOP_PENDING; serviceStop(); /* our stop service routine */ break; } /* Report our status */ ReportStatus(service_status.dwCurrentState, NO_ERROR, 0); } /* * Run Bareos as a service */ int bareosServiceMain() { is_service = true; /* indicate we are running as a service */ if (have_service_api) { /* New style service API */ /* * Tell OS where to dispatch service calls to us */ SERVICE_TABLE_ENTRY dispatchTable[] = { { (char *)APP_NAME, (LPSERVICE_MAIN_FUNCTION)serviceStartCallback }, { (char * )NULL, NULL } }; /* * Start the service control dispatcher */ if (!StartServiceCtrlDispatcher(dispatchTable)) { log_error_message(_("StartServiceCtrlDispatcher failed.")); } /* * Note, this thread continues in the ServiceCallback routine */ } else { /* old style Win95/98/Me */ HINSTANCE kerneldll = LoadLibrary("KERNEL32.DLL"); if (kerneldll == NULL) { MessageBox(NULL, _("KERNEL32.DLL not found: Bareos service not started"), APP_DESC, MB_OK); return 1; } /* * Get entry point for RegisterServiceProcess function */ DWORD (WINAPI *RegisterService)(DWORD, DWORD); RegisterService = (DWORD (WINAPI *)(DWORD, DWORD)) GetProcAddress(kerneldll, "RegisterServiceProcess"); if (RegisterService == NULL) { MessageBox(NULL, _("Registry service not found: Bareos service not started"), APP_DESC, MB_OK); log_error_message(_("Registry service entry point not found")); FreeLibrary(kerneldll); /* free up kernel dll */ return 1; } RegisterService(0, 1); /* register us as a service */ BareosAppMain(); /* call the main Bareos code */ RegisterService(0, 0); /* terminate the service */ FreeLibrary(kerneldll); /* free up kernel dll */ } return 0; } /* * New style service bareos worker thread */ DWORD WINAPI bareosWorkerThread(LPVOID lpwThreadParam) { service_thread_id = GetCurrentThreadId(); if (!ReportStatus(SERVICE_RUNNING, NO_ERROR, 0)) { MessageBox(NULL, _("Report Service failure"), APP_DESC, MB_OK); log_error_message("ReportStatus RUNNING failed"); return 0; } /* * Call Bareos main code */ BareosAppMain(); /* * Mark that we're no longer running */ service_thread_id = 0; /* * Tell the service manager that we've stopped */ ReportStatus(SERVICE_STOPPED, service_error, 0); return 0; } /* * Install the Bareos service on the OS -- very complicated */ int installService(const char *cmdOpts) { const int maxlen = 2048; char path[maxlen]; char svcmd[maxlen]; bsnprintf(svcmd, sizeof(svcmd), "service: install: %s", cmdOpts, APP_DESC, MB_OK); /* * Get our filename */ if (GetModuleFileName(NULL, path, maxlen-11) == 0) { MessageBox(NULL, _("Unable to install the service"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 0; } /* * Create a valid command for starting the service */ if ((int)strlen(path) + (int)strlen(cmdOpts) + 30 < maxlen) { bsnprintf(svcmd, sizeof(svcmd), "\"%s\" /service %s", path, cmdOpts); } else { log_error_message(_("Service command length too long")); MessageBox(NULL, _("Service command length too long. Service not registered."), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 0; } if (have_service_api) { SC_HANDLE bareosService, serviceManager; /* * Open the service control manager */ serviceManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!serviceManager) { log_error_message("Open Service Manager failed"); MessageBox(NULL, _("The Service Control Manager could not be contacted - the service was not installed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 0; } /* * Now actually create the Bareos service entry */ bareosService = CreateService(serviceManager, APP_NAME, /* Our service name */ APP_DESC, /* Display name */ SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcmd, /* Command string to start the service */ NULL, NULL, BAREOS_DEPENDENCIES, /* Services to start before us */ NULL, /* Use default SYSTEM account */ NULL); if (!bareosService) { CloseServiceHandle(serviceManager); log_error_message("CreateService failed for " APP_DESC); MessageBox(NULL, _("The Bareos service: " APP_NAME " could not be installed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 0; } /* * Set a text description in the service manager's control panel */ set_service_description(serviceManager, bareosService, (char *)_(SERVICE_DESC)); CloseServiceHandle(serviceManager); CloseServiceHandle(bareosService); } else { /* * Old style service -- create appropriate registry key path */ HKEY runservices; if (RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", &runservices) != ERROR_SUCCESS) { log_error_message(_("Cannot write System Registry for " APP_DESC)); MessageBox(NULL, _("The System Registry could not be updated - the Bareos service was not installed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 0; } /* * Add the Bareos values */ if (RegSetValueEx(runservices, APP_NAME, 0, REG_SZ, (unsigned char *)svcmd, strlen(svcmd)+1) != ERROR_SUCCESS) { RegCloseKey(runservices); log_error_message(_("Cannot add Bareos key to System Registry")); MessageBox(NULL, _("The Bareos service: " APP_NAME " could not be installed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 0; } RegCloseKey(runservices); } /* * At this point the service is installed */ if (opt_debug) { MessageBox(NULL, _("The " APP_DESC "was successfully installed.\n" "The service may be started by double clicking on the\n" "Bareos \"Start\" icon and will be automatically\n" "be run the next time this machine is rebooted. "), APP_DESC, MB_ICONINFORMATION | MB_OK); } return 0; } /* * Remove a service from the OS (normally done when we are installing a new version). */ int removeService() { if (have_service_api) { /* Newer Windows platform (NT, Win2K, ...) */ SC_HANDLE serviceManager, bareosService; int stat = 0; serviceManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (serviceManager) { /* * Now get the Bareos service entry */ bareosService = OpenService(serviceManager, APP_NAME, SERVICE_ALL_ACCESS); if (bareosService) { SERVICE_STATUS status; /* * If the service is running, stop it */ if (ControlService(bareosService, SERVICE_CONTROL_STOP, &status)) { while(QueryServiceStatus(bareosService, &status)) { if (status.dwCurrentState == SERVICE_STOP_PENDING) { sleep(1); } else { break; } } if (status.dwCurrentState != SERVICE_STOPPED) { if (opt_debug) { MessageBox(NULL, _("The Bareos service: " APP_NAME " could not be stopped"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); } } } if (DeleteService(bareosService)) { if (opt_debug) { MessageBox(NULL, _("The Bareos service: " APP_NAME " has been removed"), APP_DESC, MB_ICONINFORMATION | MB_OK); } } else { MessageBox(NULL, _("The Bareos service: " APP_NAME " could not be removed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); stat = 1; /* error */ } CloseServiceHandle(bareosService); } else { if (opt_debug) { MessageBox(NULL, _("An existing Bareos service: " APP_NAME " could not be found for " "removal. This is not normally an error."), APP_DESC, MB_ICONEXCLAMATION | MB_OK); } } CloseServiceHandle(serviceManager); return stat; } else { MessageBox(NULL, _("The service Manager could not be contacted - the Bareos service was not removed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); return 1; /* error */ } } else { /* Old Win95/98/Me OS */ /* * Open the registry path key */ HKEY runservices; if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", &runservices) != ERROR_SUCCESS) { if (opt_debug) { MessageBox(NULL, _("Could not find registry entry.\nService probably not registerd - the Bareos service was not removed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); } } else { /* * Now delete the Bareos entry */ if (RegDeleteValue(runservices, APP_NAME) != ERROR_SUCCESS) { RegCloseKey(runservices); MessageBox(NULL, _("Could not delete Registry key for " APP_NAME ".\n" "The Bareos service could not be removed"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); } RegCloseKey(runservices); return 1; } /* * Stop any running Bareos */ if (!stopRunningBareos()) { if (opt_debug) { MessageBox(NULL, _("Bareos could not be contacted, probably not running"), APP_DESC, MB_ICONEXCLAMATION | MB_OK); } return 0; /* not really an error */ } /* * At this point, the service has been removed */ if (opt_debug) { MessageBox(NULL, _("The Bareos service has been removed"), APP_DESC, MB_ICONINFORMATION | MB_OK); } } return 0; } /* * This subroutine is called to report our current status to the new style service manager */ BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint) { static DWORD checkpoint = 1; BOOL result = TRUE; /* * No callbacks until we are started */ if (state == SERVICE_START_PENDING) { service_status.dwControlsAccepted = 0; } else { service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; } /* * Save global service_status state */ service_status.dwCurrentState = state; service_status.dwWin32ExitCode = exitcode; service_status.dwWaitHint = waithint; /* * Update the checkpoint variable so the service manager knows we are alive. */ if (state == SERVICE_RUNNING || state == SERVICE_STOPPED) { service_status.dwCheckPoint = 0; } else { service_status.dwCheckPoint = checkpoint++; } /* * Send our new status */ result = SetServiceStatus(service_handle, &service_status); if (!result) { log_error_message(_("SetServiceStatus failed")); } return result; } /* Log an error message for the last Windows error */ void LogLastErrorMsg(const char *message, const char *fname, int lineno) { char msgbuf[500]; HANDLE eventHandler; const char *strings[3]; LPTSTR msg; service_error = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM, NULL, service_error, 0, (LPTSTR)&msg, 0, NULL); /* * Use the OS event logging to log the error */ eventHandler = RegisterEventSource(NULL, APP_NAME); bsnprintf(msgbuf, sizeof(msgbuf), _("\n\n%s error: %ld at %s:%d"), APP_NAME, service_error, fname, lineno); strings[0] = msgbuf; strings[1] = message; strings[2] = msg; if (eventHandler) { ReportEvent(eventHandler, EVENTLOG_ERROR_TYPE, 0, /* category */ 0, /* ID */ NULL, /* SID */ 3, /* Number of strings */ 0, /* raw data size */ (const char **)strings, /* error strings */ NULL); /* raw data */ DeregisterEventSource(eventHandler); } LocalFree(msg); } typedef BOOL (WINAPI * WinAPI)(SC_HANDLE, DWORD, LPVOID); /* * This is amazingly complicated just to get a bit of English explanation in the service manager's dialog box. */ static void set_service_description(SC_HANDLE hSCManager, SC_HANDLE hService, LPSTR lpDesc) { SC_LOCK sclLock; LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf; SERVICE_DESCRIPTION sdBuf; DWORD dwBytesNeeded; WinAPI ChangeServiceDescription; HINSTANCE hLib = LoadLibrary("ADVAPI32.DLL"); if (!hLib) { return; } ChangeServiceDescription = (WinAPI)GetProcAddress(hLib, "ChangeServiceConfig2A"); FreeLibrary(hLib); if (!ChangeServiceDescription) { return; } /* * Need to acquire database lock before reconfiguring. */ sclLock = LockServiceDatabase(hSCManager); /* * If the database cannot be locked, report the details. */ if (sclLock == NULL) { /* * Exit if the database is not locked by another process. */ if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) { log_error_message("LockServiceDatabase"); return; } /* * Allocate a buffer to get details about the lock. */ lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS)LocalAlloc(LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); if (lpqslsBuf == NULL) { log_error_message("LocalAlloc"); return; } /* * Get and print the lock status information. */ if (!QueryServiceLockStatus(hSCManager, lpqslsBuf, sizeof(QUERY_SERVICE_LOCK_STATUS)+256, &dwBytesNeeded)) { log_error_message("QueryServiceLockStatus"); } if (lpqslsBuf->fIsLocked) { printf(_("Locked by: %s, duration: %ld seconds\n"), lpqslsBuf->lpLockOwner, lpqslsBuf->dwLockDuration); } else { printf(_("No longer locked\n")); } LocalFree(lpqslsBuf); log_error_message(_("Could not lock database")); return; } /* * The database is locked, so it is safe to make changes. */ sdBuf.lpDescription = lpDesc; if (!ChangeServiceDescription(hService, /* handle to service */ SERVICE_CONFIG_DESCRIPTION, /* change: description */ &sdBuf) ) { /* value: new description */ log_error_message("ChangeServiceConfig2"); } /* * Release the database lock. */ UnlockServiceDatabase(sclLock); } bareos-Release-14.2.6/src/win32/generic/win32.h000066400000000000000000000016261263011562700207250ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2007 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 */ #include "protos.h" #include "res.h" bareos-Release-14.2.6/src/win32/include/000077500000000000000000000000001263011562700176145ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/include/vss.h000066400000000000000000000145151263011562700206060ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2006-2012 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* -*- Mode: C -*- * vss.h -- */ // // Copyright transferred from MATRIX-Computer GmbH to // Kern Sibbald by express permission. /* * * Author : Thorsten Engel * Created On : Fri May 06 21:44:00 2006 */ #ifndef __VSS_H_ #define __VSS_H_ #ifndef b_errno_win32 #define b_errno_win32 (1<<29) #endif #ifdef WIN32_VSS #define VSS_INIT_RESTORE_AFTER_INIT 1 #define VSS_INIT_RESTORE_AFTER_GATHER 2 // some forward declarations struct IVssAsync; struct IVssBackupComponents; class VSSClient { public: VSSClient(); virtual ~VSSClient(); // Backup Process bool InitializeForBackup(JCR *jcr); bool InitializeForRestore(JCR *jcr); virtual void AddDriveSnapshots(IVssBackupComponents *pVssObj, char *szDriveLetters, bool onefs_disabled) = 0; virtual void AddVolumeMountPointSnapshots(IVssBackupComponents *pVssObj, LPWSTR volume) = 0; virtual void ShowVolumeMountPointStats(JCR *jcr) = 0; virtual bool CreateSnapshots(char *szDriveLetters, bool onefs_disabled) = 0; virtual bool CloseBackup() = 0; virtual bool CloseRestore() = 0; virtual WCHAR *GetMetadata() = 0; virtual const char *GetDriverName() = 0; bool GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen); bool GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen); /* nBuflen in characters */ const size_t GetWriterCount(); const char *GetWriterInfo(int nIndex); const int GetWriterState(int nIndex); void DestroyWriterInfo(); void AppendWriterInfo(int nState, const char *pszInfo); const bool IsInitialized() { return m_bBackupIsInitialized; }; HMODULE GetVssDllHandle() { return m_hLib; }; IUnknown *GetVssObject() { return m_pVssObject; }; private: virtual bool Initialize(DWORD dwContext, bool bDuringRestore = FALSE) = 0; virtual bool WaitAndCheckForAsyncOperation(IVssAsync *pAsync) = 0; virtual void QuerySnapshotSet(GUID snapshotSetID) = 0; protected: HMODULE m_hLib; JCR *m_jcr; DWORD m_dwContext; IUnknown *m_pVssObject; GUID m_uidCurrentSnapshotSet; /* ! drive A will be stored on position 0, Z on pos. 25 */ wchar_t m_wszUniqueVolumeName[26][MAX_PATH]; wchar_t m_szShadowCopyName[26][MAX_PATH]; wchar_t *m_metadata; alist *m_pAlistWriterState; alist *m_pAlistWriterInfoText; bool m_bCoInitializeCalled; bool m_bCoInitializeSecurityCalled; bool m_bDuringRestore; /* true if we are doing a restore */ bool m_bBackupIsInitialized; bool m_bWriterStatusCurrent; int VMPs; /* volume mount points */ int VMP_snapshots; /* volume mount points that are snapshotted */ }; class VSSClientXP: public VSSClient { public: VSSClientXP(); virtual ~VSSClientXP(); virtual void AddDriveSnapshots(IVssBackupComponents *pVssObj, char *szDriveLetters, bool onefs_disabled); virtual void AddVolumeMountPointSnapshots(IVssBackupComponents *pVssObj, LPWSTR volume); virtual void ShowVolumeMountPointStats(JCR *jcr); virtual bool CreateSnapshots(char *szDriveLetters, bool onefs_disabled); virtual bool CloseBackup(); virtual bool CloseRestore(); virtual WCHAR *GetMetadata(); #ifdef _WIN64 virtual const char *GetDriverName() { return "Win64 VSS"; }; #else virtual const char *GetDriverName() { return "Win32 VSS"; }; #endif private: virtual bool Initialize(DWORD dwContext, bool bDuringRestore); virtual bool WaitAndCheckForAsyncOperation(IVssAsync *pAsync); virtual void QuerySnapshotSet(GUID snapshotSetID); bool CheckWriterStatus(); }; class VSSClient2003: public VSSClient { public: VSSClient2003(); virtual ~VSSClient2003(); virtual void AddDriveSnapshots(IVssBackupComponents *pVssObj, char *szDriveLetters, bool onefs_disabled); virtual void AddVolumeMountPointSnapshots(IVssBackupComponents *pVssObj, LPWSTR volume); virtual void ShowVolumeMountPointStats(JCR *jcr); virtual bool CreateSnapshots(char *szDriveLetters, bool onefs_disabled); virtual bool CloseBackup(); virtual bool CloseRestore(); virtual WCHAR *GetMetadata(); #ifdef _WIN64 virtual const char *GetDriverName() { return "Win64 VSS"; }; #else virtual const char *GetDriverName() { return "Win32 VSS"; }; #endif private: virtual bool Initialize(DWORD dwContext, bool bDuringRestore); virtual bool WaitAndCheckForAsyncOperation(IVssAsync *pAsync); virtual void QuerySnapshotSet(GUID snapshotSetID); bool CheckWriterStatus(); }; class VSSClientVista: public VSSClient { public: VSSClientVista(); virtual ~VSSClientVista(); virtual void AddDriveSnapshots(IVssBackupComponents *pVssObj, char *szDriveLetters, bool onefs_disabled); virtual void AddVolumeMountPointSnapshots(IVssBackupComponents *pVssObj, LPWSTR volume); virtual void ShowVolumeMountPointStats(JCR *jcr); virtual bool CreateSnapshots(char *szDriveLetters, bool onefs_disabled); virtual bool CloseBackup(); virtual bool CloseRestore(); virtual WCHAR *GetMetadata(); #ifdef _WIN64 virtual const char *GetDriverName() { return "Win64 VSS"; }; #else virtual const char *GetDriverName() { return "Win32 VSS"; }; #endif private: virtual bool Initialize(DWORD dwContext, bool bDuringRestore); virtual bool WaitAndCheckForAsyncOperation(IVssAsync *pAsync); virtual void QuerySnapshotSet(GUID snapshotSetID); bool CheckWriterStatus(); }; extern VSSClient *g_pVSSClient; bool VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen); bool VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen); #endif /* WIN32_VSS */ #endif /* __VSS_H_ */ bareos-Release-14.2.6/src/win32/include/winapi.h000066400000000000000000000222171263011562700212600ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2003-2010 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows APIs that are different for each system. * We use pointers to the entry points so that a * single binary will run on all Windows systems. * * Kern Sibbald MMIII */ #ifndef __WINAPI_H #define __WINAPI_H #if defined(HAVE_WIN32) /* * Commented out native.h include statement, which is not distributed with the * free version of VC++, and which is not used in bareos. * * #if !defined(HAVE_MINGW) // native.h not present on mingw * #include * #endif */ #include #ifndef POOLMEM typedef char POOLMEM; #endif // unicode enabling of win 32 needs some defines and functions // using an average of 3 bytes per character is probably fine in // practice but I believe that Windows actually uses UTF-16 encoding // as opposed to UCS2 which means characters 0x10000-0x10ffff are // valid and result in 4 byte UTF-8 encodings. #define MAX_PATH_UTF8 MAX_PATH * 4 // strict upper bound on UTF-16 to UTF-8 conversion // from // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileattributesex.asp // In the ANSI version of this function, the name is limited to // MAX_PATH characters. To extend this limit to 32,767 wide // characters, call the Unicode version of the function and prepend // "\\?\" to the path. For more information, see Naming a File. #define MAX_PATH_W 32767 int wchar_2_UTF8(POOLMEM **pszUTF, const wchar_t *pszUCS); int wchar_2_UTF8(char *pszUTF, const WCHAR *pszUCS, int cchChar = MAX_PATH_UTF8); int UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF); BSTR str_2_BSTR(const char *pSrc); char *BSTR_2_str(BSTR pSrc); int make_win32_path_UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF, BOOL* pBIsRawPath = NULL); // init with win9x, but maybe set to NT in InitWinAPI extern DWORD DLL_IMP_EXP g_platform_id; extern DWORD DLL_IMP_EXP g_MinorVersion; extern DWORD DLL_IMP_EXP g_MajorVersion; /* In ADVAPI32.DLL */ typedef BOOL (WINAPI * t_OpenProcessToken)(HANDLE, DWORD, PHANDLE); typedef BOOL (WINAPI * t_AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); typedef BOOL (WINAPI * t_LookupPrivilegeValue)(LPCTSTR, LPCTSTR, PLUID); extern t_OpenProcessToken DLL_IMP_EXP p_OpenProcessToken; extern t_AdjustTokenPrivileges DLL_IMP_EXP p_AdjustTokenPrivileges; extern t_LookupPrivilegeValue DLL_IMP_EXP p_LookupPrivilegeValue; /* In MSVCRT.DLL */ typedef int (__cdecl * t_wunlink) (const wchar_t *); typedef int (__cdecl * t_wmkdir) (const wchar_t *); typedef int (__cdecl * t_wopen) (const wchar_t *, int, ...); extern t_wunlink DLL_IMP_EXP p_wunlink; extern t_wmkdir DLL_IMP_EXP p_wmkdir; /* In KERNEL32.DLL */ typedef BOOL (WINAPI * t_GetFileAttributesExA)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID); typedef BOOL (WINAPI * t_GetFileAttributesExW)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID); #if (_WIN32_WINNT >= 0x0600) typedef DWORD (WINAPI * t_GetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); #endif typedef DWORD (WINAPI * t_GetFileAttributesA)(LPCSTR); typedef DWORD (WINAPI * t_GetFileAttributesW)(LPCWSTR); typedef BOOL (WINAPI * t_SetFileAttributesA)(LPCSTR, DWORD); typedef BOOL (WINAPI * t_SetFileAttributesW)(LPCWSTR, DWORD); typedef HANDLE (WINAPI * t_CreateFileA) (LPCSTR, DWORD ,DWORD, LPSECURITY_ATTRIBUTES, DWORD , DWORD, HANDLE); typedef HANDLE (WINAPI * t_CreateFileW) (LPCWSTR, DWORD ,DWORD, LPSECURITY_ATTRIBUTES, DWORD , DWORD, HANDLE); typedef DWORD (WINAPI * t_OpenEncryptedFileRawA)(LPCSTR, ULONG, PVOID); typedef DWORD (WINAPI * t_OpenEncryptedFileRawW)(LPCWSTR, ULONG, PVOID); typedef DWORD (WINAPI * t_ReadEncryptedFileRaw)(PFE_EXPORT_FUNC, PVOID, PVOID); typedef DWORD (WINAPI * t_WriteEncryptedFileRaw)(PFE_IMPORT_FUNC, PVOID, PVOID); typedef void (WINAPI *t_CloseEncryptedFileRaw)(PVOID); typedef BOOL (WINAPI * t_CreateDirectoryA) (LPCSTR, LPSECURITY_ATTRIBUTES); typedef BOOL (WINAPI * t_CreateDirectoryW) (LPCWSTR, LPSECURITY_ATTRIBUTES); typedef BOOL (WINAPI * t_SetProcessShutdownParameters)(DWORD, DWORD); typedef BOOL (WINAPI * t_BackupRead)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*); typedef BOOL (WINAPI * t_BackupWrite)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*); typedef int (WINAPI * t_WideCharToMultiByte) (UINT CodePage, DWORD , LPCWSTR, int, LPSTR, int, LPCSTR, LPBOOL); typedef int (WINAPI * t_MultiByteToWideChar) (UINT, DWORD, LPCSTR, int, LPWSTR, int); typedef HANDLE (WINAPI * t_FindFirstFileA) (LPCSTR, LPWIN32_FIND_DATAA); typedef HANDLE (WINAPI * t_FindFirstFileW) (LPCWSTR, LPWIN32_FIND_DATAW); typedef BOOL (WINAPI * t_FindNextFileA) (HANDLE, LPWIN32_FIND_DATAA); typedef BOOL (WINAPI * t_FindNextFileW) (HANDLE, LPWIN32_FIND_DATAW); typedef BOOL (WINAPI * t_SetCurrentDirectoryA) (LPCSTR); typedef BOOL (WINAPI * t_SetCurrentDirectoryW) (LPCWSTR); typedef DWORD (WINAPI * t_GetCurrentDirectoryA) (DWORD, LPSTR); typedef DWORD (WINAPI * t_GetCurrentDirectoryW) (DWORD, LPWSTR); typedef BOOL (WINAPI * t_GetVolumePathNameW) (LPCWSTR, LPWSTR, DWORD); typedef BOOL (WINAPI * t_GetVolumeNameForVolumeMountPointW) (LPCWSTR, LPWSTR, DWORD); typedef DWORD (WINAPI * t_GetLogicalDriveStringsA) (DWORD, LPSTR); typedef DWORD (WINAPI * t_GetLogicalDriveStringsW) (DWORD, LPCWSTR); typedef BOOL (WINAPI * t_AttachConsole) (DWORD); typedef BOOL (WINAPI *t_CreateProcessA) (LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION); typedef BOOL (WINAPI *t_CreateProcessW) (LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); extern t_CreateProcessA DLL_IMP_EXP p_CreateProcessA; extern t_CreateProcessW DLL_IMP_EXP p_CreateProcessW; #if (_WIN32_WINNT >= 0x0600) extern t_GetFileInformationByHandleEx DLL_IMP_EXP p_GetFileInformationByHandleEx; #endif extern t_GetFileAttributesA DLL_IMP_EXP p_GetFileAttributesA; extern t_GetFileAttributesW DLL_IMP_EXP p_GetFileAttributesW; extern t_GetFileAttributesExA DLL_IMP_EXP p_GetFileAttributesExA; extern t_GetFileAttributesExW DLL_IMP_EXP p_GetFileAttributesExW; extern t_SetFileAttributesA DLL_IMP_EXP p_SetFileAttributesA; extern t_SetFileAttributesW DLL_IMP_EXP p_SetFileAttributesW; extern t_CreateFileA DLL_IMP_EXP p_CreateFileA; extern t_CreateFileW DLL_IMP_EXP p_CreateFileW; extern t_CreateDirectoryA DLL_IMP_EXP p_CreateDirectoryA; extern t_CreateDirectoryW DLL_IMP_EXP p_CreateDirectoryW; extern t_OpenEncryptedFileRawA DLL_IMP_EXP p_OpenEncryptedFileRawA; extern t_OpenEncryptedFileRawW DLL_IMP_EXP p_OpenEncryptedFileRawW; extern t_ReadEncryptedFileRaw DLL_IMP_EXP p_ReadEncryptedFileRaw; extern t_WriteEncryptedFileRaw DLL_IMP_EXP p_WriteEncryptedFileRaw; extern t_CloseEncryptedFileRaw DLL_IMP_EXP p_CloseEncryptedFileRaw; extern t_BackupRead DLL_IMP_EXP p_BackupRead; extern t_BackupWrite DLL_IMP_EXP p_BackupWrite; extern t_SetProcessShutdownParameters DLL_IMP_EXP p_SetProcessShutdownParameters; extern t_WideCharToMultiByte DLL_IMP_EXP p_WideCharToMultiByte; extern t_MultiByteToWideChar DLL_IMP_EXP p_MultiByteToWideChar; extern t_FindFirstFileA DLL_IMP_EXP p_FindFirstFileA; extern t_FindFirstFileW DLL_IMP_EXP p_FindFirstFileW; extern t_FindNextFileA DLL_IMP_EXP p_FindNextFileA; extern t_FindNextFileW DLL_IMP_EXP p_FindNextFileW; extern t_SetCurrentDirectoryA DLL_IMP_EXP p_SetCurrentDirectoryA; extern t_SetCurrentDirectoryW DLL_IMP_EXP p_SetCurrentDirectoryW; extern t_GetCurrentDirectoryA DLL_IMP_EXP p_GetCurrentDirectoryA; extern t_GetCurrentDirectoryW DLL_IMP_EXP p_GetCurrentDirectoryW; extern t_GetVolumePathNameW DLL_IMP_EXP p_GetVolumePathNameW; extern t_GetVolumeNameForVolumeMountPointW DLL_IMP_EXP p_GetVolumeNameForVolumeMountPointW; extern t_GetLogicalDriveStringsA DLL_IMP_EXP p_GetLogicalDriveStringsA; extern t_GetLogicalDriveStringsW DLL_IMP_EXP p_GetLogicalDriveStringsW; extern t_AttachConsole DLL_IMP_EXP p_AttachConsole; void InitWinAPIWrapper(); /* * In SHFOLDER.DLL on older systems, and now SHELL32.DLL */ typedef BOOL (WINAPI * t_SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR); extern t_SHGetFolderPath DLL_IMP_EXP p_SHGetFolderPath; /* * In WS2_32.DLL */ typedef INT (WSAAPI * t_InetPton)(INT Family, PCTSTR pszAddrString, PVOID pAddrBuf); extern t_InetPton DLL_IMP_EXP p_InetPton; #endif #endif /* __WINAPI_H */ bareos-Release-14.2.6/src/win32/lib/000077500000000000000000000000001263011562700167375ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/lib/Makefile000066400000000000000000000061041263011562700204000ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../lib:../compat include ../Makefile.inc INCLUDES = -I../.. \ -I../../include \ -I../include \ -I../compat/include LDLIBS = $(MINGW_LIB)/libssl.dll.a \ $(MINGW_LIB)/libcrypto.dll.a \ $(MINGW_LIB)/libpthreadGCE2.a \ $(MINGW_LIB)/libz.dll.a \ $(MINGW_LIB)/liblzo2.dll.a \ $(MINGW_LIB)/libfastlz.dll.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid LIBBAREOS_SRCS = address_conf.c alist.c attr.c attribs.c base64.c \ berrno.c bget_msg.c binflate.c bnet_server_tcp.c bnet.c \ bpipe.c breg.c bregex.c bsnprintf.c bsock.c bsock_sctp.c \ bsock_tcp.c bsock_udt.c bsys.c btime.c btimers.c \ compression.c cram-md5.c cbuf.c crypto.c crypto_cache.c \ crypto_gnutls.c crypto_none.c crypto_nss.c crypto_openssl.c \ crypto_wrap.c daemon.c devlock.c dlist.c edit.c fnmatch.c \ guid_to_name.c hmac.c htable.c jcr.c lockmgr.c md5.c \ mem_pool.c message.c mntent_cache.c passphrase.c plugins.c \ poll.c priv.c queue.c rblist.c runscript.c rwlock.c scan.c \ scsi_crypto.c scsi_lli.c sellist.c serial.c sha1.c signal.c \ smartall.c tls_gnutls.c tls_none.c tls_nss.c tls_openssl.c \ tree.c util.c var.c watchdog.c workq.c LIBBAREOS_OBJS = $(LIBBAREOS_SRCS:.c=.o) LIBBAREOSCFG_SRCS = ini.c lex.c parse_bsr.c LIBBAREOSCFG_OBJS = $(LIBBAREOSCFG_SRCS:.c=.o) COMPAT_SRCS = compat.c print.c winapi.c COMPAT_OBJS = $(COMPAT_SRCS:.c=.o) DYNAMIC_OBJS = $(LIBBAREOS_OBJS) $(LIBBAREOSCFG_OBJS) $(COMPAT_OBJS) STATIC_SRCS = parse_conf.c res.c STATIC_OBJS = $(STATIC_SRCS:.c=.o) all: libbareos.dll libbareos.a bareos$(WIN_VERSION).def: $(DYNAMIC_OBJS) make_def ./make_def $(WIN_VERSION) $(DYNAMIC_OBJS) > $@ libbareos.dll: DLL_USAGE = -DBUILDING_DLL libbareos.dll: $(DYNAMIC_OBJS) \ bareos$(WIN_VERSION).def $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a $(DYNAMIC_OBJS) bareos$(WIN_VERSION).def $(LDLIBS) -o $@ libbareos.a: DLL_USAGE = -DUSING_DLL libbareos.a: $(STATIC_OBJS) ar rsv $@ $(STATIC_OBJS) clean: rm -f *.o bareos$(WIN_VERSION).def distclean:: clean rm -f libbareos.dll libbareos.dll.a libbareos.a # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< btime.o: DEFINES += -D_POSIX_C_SOURCE=200112 btime.o: btime.c @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/lib/make_def000077500000000000000000000010401263011562700204130ustar00rootroot00000000000000#!/bin/sh # # Make the stupid bareos.def file so that we don't have to do it manually # # Kern Sibbald, June 2007 # NM=nm case $1 in 32) SYMBOL_START=13 ;; 64) SYMBOL_START=20 ;; *) SYMBOL_START=13 ;; esac shift echo "LIBRARY libbareos.dll" echo "EXPORTS" echo " " for i in $* ; do \ echo "; $i"; \ ${NM} $i | grep "^[0-9a-f]* T " | cut -c${SYMBOL_START}- ; \ echo " "; \ done DATA="\ console_command \ exepath \ version \ dist_name \ " for i in ${DATA}; do \ echo "$i DATA"; \ done bareos-Release-14.2.6/src/win32/lmdb/000077500000000000000000000000001263011562700171075ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/lmdb/Makefile000066400000000000000000000030511263011562700205460ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../lmdb include ../Makefile.inc INCLUDES = -I../../lmdb LDLIBS = $(MINGW_LIB)/libpthreadGCE2.a LIBBAREOSLMDB_SRCS = mdb.c midl.c LIBBAREOSLMDB_OBJS = $(LIBBAREOSLMDB_SRCS:.c=.o) DYNAMIC_OBJS = $(LIBBAREOSLMDB_OBJS) all: libbareoslmdb.dll bareos$(WIN_VERSION).def: $(DYNAMIC_OBJS) make_def ./make_def $(WIN_VERSION) $(DYNAMIC_OBJS) > $@ libbareoslmdb.dll: DLL_USAGE = -DBUILDING_DLL libbareoslmdb.dll: $(DYNAMIC_OBJS) \ bareos$(WIN_VERSION).def $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a $(DYNAMIC_OBJS) bareos$(WIN_VERSION).def $(LDLIBS) -o $@ clean: rm -f *.o bareos$(WIN_VERSION).def distclean: clean rm -f libbareoslmdb.dll libbareoslmdb.dll.a # inference rules .c.o: @echo "Compiling $<" $(CC) $(DLL_USAGE) $(CFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/lmdb/make_def000077500000000000000000000006651263011562700205770ustar00rootroot00000000000000#!/bin/sh # # Make the stupid bareos.def file so that we don't have to do it manually # # Kern Sibbald, June 2007 # NM=nm case $1 in 32) SYMBOL_START=13 ;; 64) SYMBOL_START=20 ;; *) SYMBOL_START=13 ;; esac shift echo "LIBRARY libbareoslmdb.dll" echo "EXPORTS" echo " " for i in $*; do \ echo "; $i"; \ ${NM} $i | grep "^[0-9a-f]* T " | cut -c${SYMBOL_START}- ; \ echo " "; \ done bareos-Release-14.2.6/src/win32/plugins/000077500000000000000000000000001263011562700176525ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/plugins/Makefile000066400000000000000000000034671263011562700213240ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # all_subdirs = filed stored all: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done install: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done clean: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done distclean: @for I in ${all_subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ $(MAKE) WIN_VERSION=$(WIN_VERSION) DESTDIR=$(DESTDIR) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ echo ""; echo ""; exit 1;)); \ done bareos-Release-14.2.6/src/win32/plugins/filed/000077500000000000000000000000001263011562700207355ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/plugins/filed/Makefile000066400000000000000000000036441263011562700224040ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../../plugins/filed include ../../Makefile.inc INCLUDES = -I../../.. \ -I../../../include \ -I../../../filed \ -I../../../plugins/filed \ -I../../include \ -I../../compat/include VDI_INCLUDES = -I../../vdi/include LDLIBS = ../../lib/libbareos.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(MINGW_LIB)/libz.dll.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid ifeq ($(WIN_DEBUG),yes) OPT_CXXFLAGS = $(CXXFLAGS) -O2 else OPT_CXXFLAGS = $(CXXFLAGS) endif all: bpipe-fd.dll mssqlvdi-fd.dll bpipe-fd.dll: DLL_USAGE = -DBUILDING_DLL bpipe-fd.dll: bpipe-fd.o $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a bpipe-fd.o $(LDLIBS) -o $@ mssqlvdi-fd.o: CXXFLAGS += -fpermissive mssqlvdi-fd.o: mssqlvdi-fd.c @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(OPT_CXXFLAGS) $(VDI_INCLUDES) -c -o $@ $< mssqlvdi-fd.dll: DLL_USAGE = -DBUILDING_DLL mssqlvdi-fd.dll: mssqlvdi-fd.o $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a mssqlvdi-fd.o $(LDLIBS) -o $@ clean: rm -f *.o distclean:: clean rm -f bpipe-fd.dll mssqlvdi-fd.dll # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/plugins/filed/mssqlvdi-fd.c000066400000000000000000001366451263011562700233510ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2010 Zilvinas Krapavickas Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * MSSQL backup restore plugin using VDI. */ #include "bareos.h" #include "fd_plugins.h" #include "fd_common.h" /* * Microsoft® Component Object Model (COM) */ #include /* * Microsoft® MSSQL Virtual Device Interface (VDI) */ #include "vdi.h" #include "vdierror.h" #include "vdiguid.h" /* * Microsoft® ActiveX® Data Objects */ #include #include #include static const int dbglvl = 150; #define PLUGIN_LICENSE "Bareos AGPLv3" #define PLUGIN_AUTHOR "Zilvinas Krapavickas" #define PLUGIN_DATE "October 2014" #define PLUGIN_VERSION "2" #define PLUGIN_DESCRIPTION "Bareos MSSQL VDI Windows File Daemon Plugin" #define PLUGIN_USAGE "\n mssqlvdi:\n"\ " serveraddress=:\n"\ " instance=:\n"\ " database=:\n"\ " username=:\n"\ " password=:\n"\ " norecovery=:\n"\ " replace=:\n"\ " recoverafterrestore=:\n"\ " stopbeforemark=:\n"\ " stopatmark=:\n"\ " stopat=\n"\ " \n"\ " examples:\n"\ " timestamp: 'Apr 15, 2020 12:00 AM'\n"\ " log sequence number: 'lsn:15000000040000037'" #define DEFAULT_SERVER_ADDRESS "localhost" #define DEFAULT_INSTANCE "default" #define DEFAULT_BLOCKSIZE 65536 #define DEFAULT_BUFFERS 10 #define VDS_NAME_LENGTH 50 #define VDI_DEFAULT_WAIT 60000 /* 60 seconds */ #define VDI_WAIT_TIMEOUT 0xFFFFFFFF /* INFINITE */ /* * Forward referenced functions */ static bRC newPlugin(bpContext *ctx); static bRC freePlugin(bpContext *ctx); static bRC getPluginValue(bpContext *ctx, pVariable var, void *value); static bRC setPluginValue(bpContext *ctx, pVariable var, void *value); static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value); static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp); static bRC endBackupFile(bpContext *ctx); static bRC pluginIO(bpContext *ctx, struct io_pkt *io); static bRC startRestoreFile(bpContext *ctx, const char *cmd); static bRC endRestoreFile(bpContext *ctx); static bRC createFile(bpContext *ctx, struct restore_pkt *rp); static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp); static bRC checkFile(bpContext *ctx, char *fname); static bRC parse_plugin_definition(bpContext *ctx, void *value); static bRC end_restore_job(bpContext *ctx, void *value); static void close_vdi_deviceset(struct plugin_ctx *p_ctx); static bool adoReportError(bpContext *ctx); /* * Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; /* * Plugin Information block */ static genpInfo pluginInfo = { sizeof(pluginInfo), FD_PLUGIN_INTERFACE_VERSION, FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_USAGE }; /* * Plugin entry points for Bareos */ static pFuncs pluginFuncs = { sizeof(pluginFuncs), FD_PLUGIN_INTERFACE_VERSION, /* Entry points into plugin */ newPlugin, /* new plugin instance */ freePlugin, /* free plugin instance */ getPluginValue, setPluginValue, handlePluginEvent, startBackupFile, endBackupFile, startRestoreFile, endRestoreFile, pluginIO, createFile, setFileAttributes, checkFile }; /* * Plugin private context */ struct plugin_ctx { int RestoreFD; bool RestoreToFile; bool DoNoRecovery; bool ForceReplace; bool RecoverAfterRestore; char *plugin_options; char *filename; char *server_address; char *instance; char *database; char *username; char *password; char *stopbeforemark; char *stopatmark; char *stopat; char *ado_connect_string; char *ado_query; char *ado_errorstr; wchar_t *vdsname; int32_t backup_level; IClientVirtualDeviceSet2 *VDIDeviceSet; IClientVirtualDevice *VDIDevice; VDConfig VDIConfig; bool AdoThreadStarted; pthread_t ADOThread; }; struct adoThreadContext { _ADOConnection *adoConnection; BSTR ado_connect_string; BSTR ado_query; }; /* * This defines the arguments that the plugin parser understands. */ enum plugin_argument_type { argument_none, argument_server_address, argument_instance, argument_database, argument_username, argument_password, argument_norecovery, argument_replace, argument_recover_after_restore, argument_stopbeforemark, argument_stopatmark, argument_stopat }; struct plugin_argument { const char *name; enum plugin_argument_type type; }; static plugin_argument plugin_arguments[] = { { "serveraddress", argument_server_address }, { "instance", argument_instance }, { "database", argument_database }, { "username", argument_username }, { "password", argument_password }, { "norecovery", argument_norecovery }, { "replace", argument_replace }, { "recoverafterrestore", argument_recover_after_restore }, { "stopbeforemark", argument_stopbeforemark }, { "stopatmark", argument_stopatmark }, { "stopat", argument_stopat }, { NULL, argument_none } }; #ifdef __cplusplus extern "C" { #endif /* * loadPlugin() and unloadPlugin() are entry points that are exported, so Bareos can * directly call these two entry points they are common to all Bareos plugins. * * External entry point called by Bareos to "load" the plugin */ bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, genpInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return bRC_OK; } /* * External entry point to unload the plugin */ bRC DLL_IMP_EXP unloadPlugin() { return bRC_OK; } #ifdef __cplusplus } #endif /* * The following entry points are accessed through the function pointers we supplied to Bareos. * Each plugin type (dir, fd, sd) has its own set of entry points that the plugin must define. * * Create a new instance of the plugin i.e. allocate our private storage */ static bRC newPlugin(bpContext *ctx) { HRESULT hr; plugin_ctx *p_ctx; /* * Initialize COM for this thread. */ hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (!SUCCEEDED (hr)) { return bRC_Error; } p_ctx = (plugin_ctx *)malloc(sizeof(plugin_ctx)); if (!p_ctx) { return bRC_Error; } memset(p_ctx, 0, sizeof(plugin_ctx)); ctx->pContext = (void *)p_ctx; /* set our context pointer */ /* * Only register the events we are really interested in. */ bfuncs->registerBareosEvents(ctx, 6, bEventLevel, bEventRestoreCommand, bEventBackupCommand, bEventPluginCommand, bEventEndRestoreJob, bEventNewPluginOptions); return bRC_OK; } /* * Free a plugin instance, i.e. release our private storage */ static bRC freePlugin(bpContext *ctx) { plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } Dmsg(ctx, dbglvl, "mssqlvdi-fd: entering freePlugin\n"); /* * Close any open VDI deviceset. */ close_vdi_deviceset(p_ctx); /* * See if there is any error to report from the ADO layer. */ adoReportError(ctx); /* * Cleanup the context. */ if (p_ctx->plugin_options) { free(p_ctx->plugin_options); } if (p_ctx->filename) { free(p_ctx->filename); } if (p_ctx->server_address) { free(p_ctx->server_address); } if (p_ctx->instance) { free(p_ctx->instance); } if (p_ctx->database) { free(p_ctx->database); } if (p_ctx->username) { free(p_ctx->username); } if (p_ctx->password) { free(p_ctx->password); } if (p_ctx->stopbeforemark) { free(p_ctx->stopbeforemark); } if (p_ctx->stopatmark) { free(p_ctx->stopatmark); } if (p_ctx->stopat) { free(p_ctx->stopat); } if (p_ctx->vdsname) { free(p_ctx->vdsname); } if (p_ctx->ado_connect_string) { free(p_ctx->ado_connect_string); } if (p_ctx->ado_query) { free(p_ctx->ado_query); } free(p_ctx); p_ctx = NULL; /* * Tear down COM for this thread. */ CoUninitialize(); Dmsg(ctx, dbglvl, "mssqlvdi-fd: leaving freePlugin\n"); return bRC_OK; } /* * Return some plugin value (none defined) */ static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Set a plugin value (none defined) */ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) { return bRC_OK; } /* * Handle an event that was generated in Bareos */ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) { bRC retval; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } switch (event->eventType) { case bEventLevel: p_ctx->backup_level = (int64_t)value; retval = bRC_OK; break; case bEventRestoreCommand: /* * Fall-through wanted */ case bEventBackupCommand: /* * Fall-through wanted */ case bEventPluginCommand: retval = parse_plugin_definition(ctx, value); break; case bEventNewPluginOptions: /* * Free any previous value. */ if (p_ctx->plugin_options) { free(p_ctx->plugin_options); p_ctx->plugin_options = NULL; } retval = parse_plugin_definition(ctx, value); /* * Save that we got a plugin override. */ p_ctx->plugin_options = bstrdup((char *)value); break; case bEventEndRestoreJob: retval = end_restore_job(ctx, value); break; default: Jmsg(ctx, M_FATAL, "mssqlvdi-fd: unknown event=%d\n", event->eventType); Dmsg(ctx, dbglvl, "mssqlvdi-fd: unknown event=%d\n", event->eventType); retval = bRC_Error; break; } return retval; } /* * Start the backup of a specific file */ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp) { time_t now; POOL_MEM fname(PM_NAME); char dt[MAX_TIME_LENGTH]; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } /* * If no explicit instance name given use the DEFAULT_INSTANCE. */ if (!p_ctx->instance) { p_ctx->instance = bstrdup(DEFAULT_INSTANCE); } /* * If no explicit server address given use the DEFAULT_SERVER_ADDRESS. */ if (!p_ctx->server_address) { p_ctx->server_address = bstrdup(DEFAULT_SERVER_ADDRESS); } now = time(NULL); bstrftime(dt, sizeof(dt), now, "%Y%m%d-%H%M%S"); switch (p_ctx->backup_level) { case L_FULL: Mmsg(fname, "/@MSSQL/%s/%s/db-%s-full.bak", p_ctx->instance, p_ctx->database, dt); break; case L_DIFFERENTIAL: Mmsg(fname, "/@MSSQL/%s/%s/db-%s-diff.bak", p_ctx->instance, p_ctx->database, dt); break; case L_INCREMENTAL: Mmsg(fname, "/@MSSQL/%s/%s/db-%s-log.trn", p_ctx->instance, p_ctx->database, dt); break; default: Jmsg(ctx, M_FATAL, "Unsuported backup level (%c).\n", p_ctx->backup_level); Dmsg(ctx, dbglvl, "Unsuported backup level (%c).\n", p_ctx->backup_level); return bRC_Error; } p_ctx->filename = bstrdup(fname.c_str()); Dmsg(ctx, dbglvl, "startBackupFile: Generated filename %s\n", p_ctx->filename); sp->fname = p_ctx->filename; sp->type = FT_REG; sp->statp.st_mode = S_IFREG | S_IREAD | S_IWRITE | S_IEXEC; sp->statp.st_ctime = now; sp->statp.st_mtime = now; sp->statp.st_atime = now; sp->statp.st_size = 0; sp->statp.st_blksize = DEFAULT_BLOCKSIZE; sp->statp.st_blocks = 1; return bRC_OK; } /* * Done with backup of this file */ static bRC endBackupFile(bpContext *ctx) { /* * We would return bRC_More if we wanted startBackupFile to be called again to backup another file */ return bRC_OK; } /* * Strip any backslashes in the string. */ static inline void strip_back_slashes(char *value) { char *bp; bp = value; while (*bp) { switch (*bp) { case '\\': bstrinlinecpy(bp, bp + 1); break; default: break; } bp++; } } /* * Parse a boolean value e.g. check if its yes or true anything else translates to false. */ static inline bool parse_boolean(const char *argument_value) { if (bstrcasecmp(argument_value, "yes") || bstrcasecmp(argument_value, "true")) { return true; } else { return false; } } /* * Only set destination to value when it has no previous setting. */ static inline void set_string_if_null(char **destination, char *value) { if (!*destination) { *destination = bstrdup(value); strip_back_slashes(*destination); } } /* * Always set destination to value and clean any previous one. */ static inline void set_string(char **destination, char *value) { if (*destination) { free(*destination); } *destination = bstrdup(value); strip_back_slashes(*destination); } /* * Parse the plugin definition passed in. * * The definition is in this form: * * mssqlvdi:instance=:database=: */ static bRC parse_plugin_definition(bpContext *ctx, void *value) { int i; bool keep_existing; char *plugin_definition, *bp, *argument, *argument_value; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx || !value) { return bRC_Error; } keep_existing = (p_ctx->plugin_options) ? true : false; /* * Parse the plugin definition. * Make a private copy of the whole string. */ plugin_definition = bstrdup((char *)value); bp = strchr(plugin_definition, ':'); if (!bp) { Jmsg(ctx, M_FATAL, "Illegal plugin definition %s\n", plugin_definition); Dmsg(ctx, dbglvl, "Illegal plugin definition %s\n", plugin_definition); goto bail_out; } /* * Skip the first ':' */ bp++; while (bp) { if (strlen(bp) == 0) { break; } /* * Each argument is in the form: * = * * So we setup the right pointers here, argument to the beginning * of the argument, argument_value to the beginning of the argument_value. */ argument = bp; argument_value = strchr(bp, '='); if (!argument_value) { Jmsg(ctx, M_FATAL, "Illegal argument %s without value\n", argument); Dmsg(ctx, dbglvl, "Illegal argument %s without value\n", argument); goto bail_out; } *argument_value++ = '\0'; /* * See if there are more arguments and setup for the next run. */ bp = argument_value; do { bp = strchr(bp, ':'); if (bp) { if (*(bp - 1) != '\\') { *bp++ = '\0'; break; } else { bp++; } } } while (bp); for (i = 0; plugin_arguments[i].name; i++) { if (bstrcasecmp(argument, plugin_arguments[i].name)) { char **str_destination = NULL; bool *bool_destination = NULL; switch (plugin_arguments[i].type) { case argument_server_address: str_destination = &p_ctx->server_address; break; case argument_instance: str_destination = &p_ctx->instance; break; case argument_database: str_destination = &p_ctx->database; break; case argument_username: str_destination = &p_ctx->username; break; case argument_password: str_destination = &p_ctx->password; break; case argument_norecovery: bool_destination = &p_ctx->DoNoRecovery; break; case argument_replace: bool_destination = &p_ctx->ForceReplace; break; case argument_recover_after_restore: bool_destination = &p_ctx->RecoverAfterRestore; break; case argument_stopbeforemark: str_destination = &p_ctx->stopbeforemark; break; case argument_stopatmark: str_destination = &p_ctx->stopatmark; break; case argument_stopat: str_destination = &p_ctx->stopat; break; default: break; } /* * Keep the first value, ignore any next setting. */ if (str_destination) { if (keep_existing) { set_string_if_null(str_destination, argument_value); } else { set_string(str_destination, argument_value); } } /* * Set any boolean variable. */ if (bool_destination) { *bool_destination = parse_boolean(argument_value); } /* * When we have a match break the loop. */ break; } } /* * Got an invalid keyword ? */ if (!plugin_arguments[i].name) { Jmsg(ctx, M_FATAL, "Illegal argument %s with value %s in plugin definition\n", argument, argument_value); Dmsg(ctx, dbglvl, "Illegal argument %s with value %s in plugin definition\n", argument, argument_value); goto bail_out; } } free(plugin_definition); return bRC_OK; bail_out: free(plugin_definition); return bRC_Error; } /* * Close the VDI deviceset if is is opened. */ static void close_vdi_deviceset(plugin_ctx *p_ctx) { /* * Close VDI Device. */ if (p_ctx->VDIDevice) { p_ctx->VDIDevice->Release(); p_ctx->VDIDevice = NULL; } /* * Close VDI DeviceSet. */ if (p_ctx->VDIDeviceSet) { p_ctx->VDIDeviceSet->Close(); p_ctx->VDIDeviceSet->Release(); p_ctx->VDIDeviceSet = NULL; } /* * Cancel the started database thread. */ if (p_ctx->AdoThreadStarted) { if (!pthread_equal(p_ctx->ADOThread, pthread_self())) { pthread_cancel(p_ctx->ADOThread); } } } /* * Generic COM error reporting function. */ static void comReportError(bpContext *ctx, HRESULT hrErr) { IErrorInfo *pErrorInfo; BSTR pSource = NULL; BSTR pDescription = NULL; HRESULT hr; char *source, *description; /* * See if there is anything to report. */ hr = GetErrorInfo(0, &pErrorInfo); if (hr == S_FALSE) { return; } /* * Get the description of the COM error. */ hr = pErrorInfo->GetDescription(&pDescription); if (!SUCCEEDED (hr)) { pErrorInfo->Release(); return; } /* * Get the source of the COM error. */ hr = pErrorInfo->GetSource(&pSource); if (!SUCCEEDED (hr)) { SysFreeString(pDescription); pErrorInfo->Release(); return; } /* * Convert windows BSTR to normal strings. */ source = BSTR_2_str(pSource); description = BSTR_2_str(pDescription); if (source && description) { Jmsg(ctx, M_FATAL, "%s(x%X): %s\n", source, hrErr, description); Dmsg(ctx, dbglvl, "%s(x%X): %s\n", source, hrErr, description); } if (source) { free(source); } if (description) { free(description); } /* * Generic cleanup (free the description and source as those are returned in * dynamically allocated memory by the COM routines.) */ SysFreeString(pSource); SysFreeString(pDescription); pErrorInfo->Release(); } /* * Retrieve errors from ADO Connection. */ static bool adoGetErrors(bpContext *ctx, _ADOConnection *adoConnection, POOL_MEM &ado_errorstr) { HRESULT hr; ADOErrors *adoErrors; long errCount; /* * Get any errors that are reported. */ hr = adoConnection->get_Errors(&adoErrors); if (!SUCCEEDED (hr)) { comReportError(ctx, hr); goto bail_out; } /* * See how many errors there are. */ hr = adoErrors->get_Count(&errCount); if (!SUCCEEDED (hr)) { comReportError(ctx, hr); adoErrors->Release(); goto bail_out; } /* * Loop over all error and append them into one big error string. */ pm_strcpy(ado_errorstr, ""); for (long i = 0; i < errCount; i++ ) { ADOError *adoError; BSTR pDescription = NULL; char *description; hr = adoErrors->get_Item(_variant_t(i), &adoError); if (!SUCCEEDED (hr)) { comReportError(ctx, hr); adoErrors->Release(); goto bail_out; } hr = adoError->get_Description(&pDescription); if (!SUCCEEDED (hr)) { comReportError(ctx, hr); adoError->Release(); adoErrors->Release(); goto bail_out; } description = BSTR_2_str(pDescription); if (description) { Dmsg(ctx, dbglvl, "adoGetErrors: ADO error %s\n", description); pm_strcat(ado_errorstr, description); pm_strcat(ado_errorstr, "\n"); free(description); } SysFreeString(pDescription); adoError->Release(); } /* * Generic cleanup. */ adoErrors->Clear(); adoErrors->Release(); return true; bail_out: return false; } /* * Print errors (when available) collected by adoThreadSetError function. */ static bool adoReportError(bpContext *ctx) { plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (p_ctx->ado_errorstr) { Jmsg(ctx, M_FATAL, "%s\n", p_ctx->ado_errorstr); Dmsg(ctx, dbglvl, "%s\n", p_ctx->ado_errorstr); free(p_ctx->ado_errorstr); p_ctx->ado_errorstr = NULL; return true; } return false; } /* * Retrieve errors from ADO Connection when running the query in a seperate thread. */ static void adoThreadSetError(bpContext *ctx, _ADOConnection *adoConnection) { int cancel_type; POOL_MEM ado_errorstr(PM_NAME); plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (p_ctx->ado_errorstr) { return; } /* * Set the threads cancellation type to defered. */ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &cancel_type); if (!adoGetErrors(ctx, adoConnection, ado_errorstr)) { goto bail_out; } /* * Keep the errors in a buffer these will be printed by the adoReportError function. */ p_ctx->ado_errorstr = bstrdup(ado_errorstr.c_str()); bail_out: /* * Restore the threads cancellation type. */ pthread_setcanceltype(cancel_type, NULL); return; } /* * Cleanup function called on thread destroy. */ static void adoCleanupThread(void *data) { adoThreadContext *ado_ctx; ado_ctx = (adoThreadContext *)data; if (!data) { return; } /* * Generic cleanup. */ if (ado_ctx->ado_connect_string) { SysFreeString(ado_ctx->ado_connect_string); } if (ado_ctx->ado_query) { SysFreeString(ado_ctx->ado_query); } if (ado_ctx->adoConnection) { LONG adoState; ado_ctx->adoConnection->get_State(&adoState); if (adoState & adStateExecuting) { ado_ctx->adoConnection->Cancel(); } if (adoState & adStateOpen) { ado_ctx->adoConnection->Close(); } ado_ctx->adoConnection->Release(); } /* * Tear down COM for this thread. */ CoUninitialize(); } /* * Run a seperate thread that connects to the database server and * controls the backup or restore. When we close the VDI device we * also tear down this database control thread. */ static void *adoThread(void *data) { HRESULT hr; adoThreadContext ado_ctx; bpContext *ctx = (bpContext *)data; plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext; memset(&ado_ctx, 0, sizeof(ado_ctx)); /* * When we get canceled make sure we run the cleanup function. */ pthread_cleanup_push(adoCleanupThread, &ado_ctx); /* * Initialize COM for this thread. */ hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (!SUCCEEDED (hr)) { return NULL; } /* * Create a COM instance for an ActiveX® Data Objects connection. */ hr = CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (void **)&ado_ctx.adoConnection); if (!SUCCEEDED (hr)) { goto bail_out; } /* * Make sure the connection doesn't timeout. * Default timeout is not long enough most of the time * for the backup or restore to finish and when it times * out it will abort the action it was performing. */ hr = ado_ctx.adoConnection->put_CommandTimeout(0); if (!SUCCEEDED (hr)) { adoThreadSetError(ctx, ado_ctx.adoConnection); goto bail_out; } /* * Open a connection to the database server with the defined connection string. */ ado_ctx.ado_connect_string = str_2_BSTR(p_ctx->ado_connect_string); hr = ado_ctx.adoConnection->Open(ado_ctx.ado_connect_string); if (!SUCCEEDED (hr)) { adoThreadSetError(ctx, ado_ctx.adoConnection); goto bail_out; } /* * Execute the backup or restore command. */ ado_ctx.ado_query = str_2_BSTR(p_ctx->ado_query); hr = ado_ctx.adoConnection->Execute(ado_ctx.ado_query, NULL, adExecuteNoRecords, NULL); if (!SUCCEEDED (hr)) { adoThreadSetError(ctx, ado_ctx.adoConnection); goto bail_out; } bail_out: /* * Run the thread cleanup. */ pthread_cleanup_pop(1); return NULL; } /* * Create a connection string for connecting to the master database. */ static void set_ado_connect_string(bpContext *ctx) { POOL_MEM ado_connect_string(PM_NAME); plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (bstrcasecmp(p_ctx->instance, DEFAULT_INSTANCE)) { Mmsg(ado_connect_string, "Provider=SQLOLEDB.1;Data Source=%s;Initial Catalog=master", p_ctx->server_address); } else { Mmsg(ado_connect_string, "Provider=SQLOLEDB.1;Data Source=%s\\%s;Initial Catalog=master", p_ctx->server_address, p_ctx->instance); } /* * See if we need to use a username/password or a trusted connection. */ if (p_ctx->username && p_ctx->password) { POOL_MEM temp(PM_NAME); Mmsg(temp, ";User Id=%s;Password=%s;", p_ctx->username, p_ctx->password); pm_strcat(ado_connect_string, temp.c_str()); } else { pm_strcat(ado_connect_string, ";Integrated Security=SSPI;"); } Dmsg(ctx, dbglvl, "set_ado_connect_string: ADO Connect String '%s'\n", ado_connect_string.c_str()); if (p_ctx->ado_connect_string) { free(p_ctx->ado_connect_string); } p_ctx->ado_connect_string = bstrdup(ado_connect_string.c_str()); } /* * Generate a valid connect string and the backup command we should execute * in the seperate database controling thread. */ static inline void perform_ado_backup(bpContext *ctx) { plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; POOL_MEM ado_connect_string(PM_NAME), ado_query(PM_NAME); POOLMEM *vdsname; /* * If no explicit instance name given usedthe DEFAULT_INSTANCE name. */ if (!p_ctx->instance) { p_ctx->instance = bstrdup(DEFAULT_INSTANCE); } set_ado_connect_string(ctx); vdsname = get_pool_memory(PM_NAME); wchar_2_UTF8(&vdsname, p_ctx->vdsname); switch (p_ctx->backup_level) { case L_INCREMENTAL: Mmsg(ado_query, "BACKUP LOG %s TO VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d", p_ctx->database, vdsname, DEFAULT_BLOCKSIZE, DEFAULT_BUFFERS, DEFAULT_BLOCKSIZE); break; case L_DIFFERENTIAL: Mmsg(ado_query, "BACKUP DATABASE [%s] TO VIRTUAL_DEVICE='%s' WITH DIFFERENTIAL, BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d", p_ctx->database, vdsname, DEFAULT_BLOCKSIZE, DEFAULT_BUFFERS, DEFAULT_BLOCKSIZE); break; default: Mmsg(ado_query, "BACKUP DATABASE [%s] TO VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d", p_ctx->database, vdsname, DEFAULT_BLOCKSIZE, DEFAULT_BUFFERS, DEFAULT_BLOCKSIZE); break; } Dmsg(ctx, dbglvl, "perform_ado_backup: ADO Query '%s'\n", ado_query.c_str()); p_ctx->ado_query = bstrdup(ado_query.c_str()); free_pool_memory(vdsname); } /* * Generate a valid connect string and the restore command we should execute * in the seperate database controling thread. */ static inline void perform_ado_restore(bpContext *ctx) { POOL_MEM ado_query(PM_NAME), temp(PM_NAME); POOLMEM *vdsname; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; /* * If no explicit instance name given use the DEFAULT_INSTANCE name. */ if (!p_ctx->instance) { p_ctx->instance = bstrdup(DEFAULT_INSTANCE); } set_ado_connect_string(ctx); vdsname = get_pool_memory(PM_NAME); wchar_2_UTF8(&vdsname, p_ctx->vdsname); switch (p_ctx->backup_level) { case L_INCREMENTAL: Mmsg(ado_query, "RESTORE LOG %s FROM VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d, %s", p_ctx->database, vdsname, DEFAULT_BLOCKSIZE, DEFAULT_BUFFERS, DEFAULT_BLOCKSIZE, p_ctx->DoNoRecovery ? "NORECOVERY" : "RECOVERY"); break; default: Mmsg(ado_query, "RESTORE DATABASE [%s] FROM VIRTUAL_DEVICE='%s' WITH BLOCKSIZE=%d, BUFFERCOUNT=%d, MAXTRANSFERSIZE=%d, %s", p_ctx->database, vdsname, DEFAULT_BLOCKSIZE, DEFAULT_BUFFERS, DEFAULT_BLOCKSIZE, p_ctx->DoNoRecovery ? "NORECOVERY" : "RECOVERY"); break; } /* * See if we need to insert any stopbeforemark arguments. */ if (p_ctx->stopbeforemark) { Mmsg(temp, ", STOPBEFOREMARK = '%s'", p_ctx->stopbeforemark); pm_strcat(ado_query, temp.c_str()); } /* * See if we need to insert any stopatmark arguments. */ if (p_ctx->stopatmark) { Mmsg(temp, ", STOPATMARK = '%s'", p_ctx->stopatmark); pm_strcat(ado_query, temp.c_str()); } /* * See if we need to insert any stopat arguments. */ if (p_ctx->stopat) { Mmsg(temp, ", STOPAT = '%s'", p_ctx->stopat); pm_strcat(ado_query, temp.c_str()); } /* * See if we need to insert the REPLACE option. */ if (p_ctx->ForceReplace) { pm_strcat(ado_query, ", REPLACE"); } Dmsg(ctx, dbglvl, "perform_ado_restore: ADO Query '%s'\n", ado_query.c_str()); p_ctx->ado_query = bstrdup(ado_query.c_str()); free_pool_memory(vdsname); } /* * Run a query not in a seperate thread. */ static inline bool run_ado_query(bpContext *ctx, const char *query) { bool retval = false; HRESULT hr; BSTR ado_connect_string = NULL; BSTR ado_query = NULL; _ADOConnection *adoConnection = NULL; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; Dmsg(ctx, dbglvl, "run_ado_query: ADO Query '%s'\n", query); /* * Create a COM instance for an ActiveX® Data Objects connection. */ hr = CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (void **)&adoConnection); if (!SUCCEEDED (hr)) { goto cleanup; } /* * Open a connection to the database server with the defined connection string. */ ado_connect_string = str_2_BSTR(p_ctx->ado_connect_string); hr = adoConnection->Open(ado_connect_string); if (!SUCCEEDED (hr)) { POOL_MEM ado_errorstr(PM_NAME); adoGetErrors(ctx, adoConnection, ado_errorstr); Jmsg(ctx, M_FATAL, "Failed to connect to database, %s\n", ado_errorstr.c_str()); Dmsg(ctx, dbglvl, "Failed to connect to database, %s\n", ado_errorstr.c_str()); goto cleanup; } /* * Perform the query. */ ado_query = str_2_BSTR(query); hr = adoConnection->Execute(ado_query, NULL, adExecuteNoRecords, NULL); if (!SUCCEEDED (hr)) { POOL_MEM ado_errorstr(PM_NAME); adoGetErrors(ctx, adoConnection, ado_errorstr); Jmsg(ctx, M_FATAL, "Failed to execute query %s on database, %s\n", query, ado_errorstr.c_str()); Dmsg(ctx, dbglvl, "Failed to execute query %s on database, %s\n", query, ado_errorstr.c_str()); goto cleanup; } retval = true; cleanup: if (ado_connect_string) { SysFreeString(ado_connect_string); } if (ado_query) { SysFreeString(ado_query); } if (adoConnection) { LONG adoState; adoConnection->get_State(&adoState); if (adoState & adStateExecuting) { adoConnection->Cancel(); } if (adoState & adStateOpen) { adoConnection->Close(); } adoConnection->Release(); } return retval; } /* * Automatically recover the database at the end of the whole restore process. */ static inline bool perform_ado_recover(bpContext *ctx) { POOL_MEM recovery_query(PM_NAME); plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; set_ado_connect_string(ctx); Mmsg(recovery_query, "RESTORE DATABASE [%s] WITH RECOVERY", p_ctx->database); return run_ado_query(ctx, recovery_query.c_str()); } /* * Setup a VDI device for performing a backup or restore operation. */ static inline bool setup_vdi_device(bpContext *ctx, struct io_pkt *io) { int status; HRESULT hr = NOERROR; GUID vdsId; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if ((p_ctx->username && !p_ctx->password) || (!p_ctx->username && p_ctx->password)) { Jmsg(ctx, M_FATAL, "Illegal plugin definition when using username or password define both\n"); return false; } CoCreateGuid(&vdsId); p_ctx->vdsname = (wchar_t *)malloc((VDS_NAME_LENGTH * sizeof(wchar_t)) + 2); StringFromGUID2(vdsId, p_ctx->vdsname, VDS_NAME_LENGTH); /* * Get a handle to the device set. */ hr = CoCreateInstance(CLSID_MSSQL_ClientVirtualDeviceSet, NULL, CLSCTX_INPROC_SERVER, IID_IClientVirtualDeviceSet2, (void **)&p_ctx->VDIDeviceSet); if (!SUCCEEDED(hr)) { comReportError(ctx, hr); return false; } /* * Setup the VDI configuration. */ memset(&p_ctx->VDIConfig, 0, sizeof(p_ctx->VDIConfig)); p_ctx->VDIConfig.deviceCount = 1; p_ctx->VDIConfig.features = VDF_LikePipe; /* * Create the VDI device set. */ hr = p_ctx->VDIDeviceSet->CreateEx(NULL, p_ctx->vdsname, &p_ctx->VDIConfig); if (!SUCCEEDED(hr)) { comReportError(ctx, hr); return false; } /* * Setup the right backup or restore cmdline and connect info. */ if (io->flags & (O_CREAT | O_WRONLY)) { perform_ado_restore(ctx); } else { perform_ado_backup(ctx); } /* * Ask the database server to start a backup or restore via an other thread. * We create a new thread that handles the connection to the database. */ status = pthread_create(&p_ctx->ADOThread, NULL, adoThread, (void *)ctx); if (status != 0) { return false; } /* * Track that we have started the thread and as such need to kill it when * we perform a close of the VDI device. */ p_ctx->AdoThreadStarted = true; /* * Wait for the database server to connect to the VDI deviceset. */ hr = p_ctx->VDIDeviceSet->GetConfiguration(VDI_DEFAULT_WAIT, &p_ctx->VDIConfig); if (!SUCCEEDED(hr)) { Jmsg(ctx, M_FATAL, "mssqlvdi-fd: IClientVirtualDeviceSet2::GetConfiguration failed\n"); Dmsg(ctx, dbglvl, "mssqlvdi-fd: IClientVirtualDeviceSet2::GetConfiguration failed\n"); goto bail_out; } hr = p_ctx->VDIDeviceSet->OpenDevice(p_ctx->vdsname, &p_ctx->VDIDevice); if (!SUCCEEDED(hr)) { char vdsname[VDS_NAME_LENGTH + 1]; sprintf_s(vdsname, sizeof(vdsname), "%S", p_ctx->vdsname); Jmsg(ctx, M_FATAL, "mssqlvdi-fd: IClientVirtualDeviceSet2::OpenDevice(%s)\n", vdsname); Dmsg(ctx, dbglvl, "mssqlvdi-fd: IClientVirtualDeviceSet2::OpenDevice(%s)\n", vdsname); goto bail_out; } io->status = 0; io->io_errno = 0; io->lerror = 0; io->win32 = false; return true; bail_out: /* * Report any COM errors. */ comReportError(ctx, hr); /* * Wait for the adoThread to exit. */ if (p_ctx->AdoThreadStarted) { if (!pthread_equal(p_ctx->ADOThread, pthread_self())) { pthread_cancel(p_ctx->ADOThread); pthread_join(p_ctx->ADOThread, NULL); p_ctx->AdoThreadStarted = false; } } return false; } /* * Perform an I/O operation to a file as part of a restore. */ static inline bool perform_file_io(bpContext *ctx, struct io_pkt *io, DWORD *completionCode) { plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; switch(io->func) { case IO_OPEN: if (p_ctx->RestoreFD == -1) { io->status = 0; p_ctx->RestoreFD = open(io->fname, io->flags, io->mode); if (p_ctx->RestoreFD < 0) { goto bail_out; } } else { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } break; case IO_READ: if (p_ctx->RestoreFD != -1) { io->status = read(p_ctx->RestoreFD, io->buf, io->count); } else { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } break; case IO_WRITE: if (p_ctx->RestoreFD != -1) { io->status = write(p_ctx->RestoreFD, io->buf, io->count); } else { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } break; case IO_CLOSE: if (p_ctx->RestoreFD != -1) { io->status = 0; close(p_ctx->RestoreFD); p_ctx->RestoreFD = -1; } else { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } break; case IO_SEEK: if (p_ctx->RestoreFD != -1) { io->status = lseek(p_ctx->RestoreFD, io->offset, io->whence); } else { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } break; default: goto bail_out; } if (io->status < 0) { goto bail_out; } io->io_errno = 0; io->lerror = 0; io->win32 = false; *completionCode = ERROR_SUCCESS; return true; bail_out: return false; } /* * Perform an I/O operation to a virtual device as part of a backup or restore. */ static inline bool perform_vdi_io(bpContext *ctx, struct io_pkt *io, DWORD *completionCode) { HRESULT hr = NOERROR; VDC_Command *cmd; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; /* * See what command is available on the VDIDevice. */ hr = p_ctx->VDIDevice->GetCommand(VDI_WAIT_TIMEOUT , &cmd); if (!SUCCEEDED(hr)) { Jmsg(ctx, M_ERROR, "mssqlvdi-fd: IClientVirtualDevice::GetCommand: x%X\n", hr); Dmsg(ctx, dbglvl, "mssqlvdi-fd: IClientVirtualDevice::GetCommand: x%X\n", hr); goto bail_out; } switch (cmd->commandCode) { case VDC_Read: /* * Make sure the write to the VDIDevice will fit e.g. not a to big IO and * that we are currently writing to the device. */ if ((DWORD)io->count > cmd->size || io->func != IO_WRITE) { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } else { memcpy(cmd->buffer, io->buf, io->count); io->status = io->count; *completionCode = ERROR_SUCCESS; } break; case VDC_Write: /* * Make sure the read from the VDIDevice will fit e.g. not a to big IO and * that we are currently reading from the device. */ if (cmd->size > (DWORD)io->count || io->func != IO_READ) { *completionCode = ERROR_BAD_ENVIRONMENT; goto bail_out; } else { memcpy(io->buf, cmd->buffer, cmd->size); io->status = cmd->size; *completionCode = ERROR_SUCCESS; } break; case VDC_Flush: io->status = 0; *completionCode = ERROR_SUCCESS; break; case VDC_ClearError: *completionCode = ERROR_SUCCESS; break; default: *completionCode = ERROR_NOT_SUPPORTED; goto bail_out; } hr = p_ctx->VDIDevice->CompleteCommand(cmd, *completionCode, io->status, 0); if (!SUCCEEDED(hr)) { Jmsg(ctx, M_ERROR, "mssqlvdi-fd: IClientVirtualDevice::CompleteCommand: x%X\n", hr); Dmsg(ctx, dbglvl, "mssqlvdi-fd: IClientVirtualDevice::CompleteCommand: x%X\n", hr); goto bail_out; } io->io_errno = 0; io->lerror = 0; io->win32 = false; return true; bail_out: /* * Report any COM errors. */ comReportError(ctx, hr); /* * Wait for the adoThread to exit. */ if (p_ctx->AdoThreadStarted) { if (!pthread_equal(p_ctx->ADOThread, pthread_self())) { pthread_cancel(p_ctx->ADOThread); pthread_join(p_ctx->ADOThread, NULL); p_ctx->AdoThreadStarted = false; } } return false; } /* * End of I/O tear down the VDI and check if everything did go to plan. */ static inline bool tear_down_vdi_device(bpContext *ctx, struct io_pkt *io) { HRESULT hr = NOERROR; VDC_Command *cmd; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; Dmsg(ctx, dbglvl, "mssqlvdi-fd: entering tear_down_vdi_device\n"); /* * Check if the VDI device is closed. */ if (p_ctx->VDIDevice) { hr = p_ctx->VDIDevice->GetCommand(VDI_WAIT_TIMEOUT , &cmd); if (hr != VD_E_CLOSE) { Jmsg(ctx, M_ERROR, "Abnormal termination, VDIDevice not closed."); Dmsg(ctx, dbglvl, "Abnormal termination, VDIDevice not closed."); goto bail_out; } } /* * Close and release the VDIDevice and VDIDeviceSet. */ close_vdi_deviceset(p_ctx); /* * See if there is any error to report from the ADO layer. */ if (p_ctx->AdoThreadStarted) { if (adoReportError(ctx)) { goto bail_out; } } io->status = 0; io->io_errno = 0; io->lerror = 0; io->win32 = false; Dmsg(ctx, dbglvl, "mssqlvdi-fd: leaving tear_down_vdi_device\n"); return true; bail_out: /* * Report any COM errors. */ comReportError(ctx, hr); Dmsg(ctx, dbglvl, "mssqlvdi-fd: leaving tear_down_vdi_device\n"); return false; } /* * Bareos is calling us to do the actual I/O */ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) { DWORD completionCode = ERROR_BAD_ENVIRONMENT; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } switch(io->func) { case IO_OPEN: if (p_ctx->RestoreToFile) { if (!perform_file_io(ctx, io, &completionCode)) { goto bail_out; } } else { if (!setup_vdi_device(ctx, io)) { goto bail_out; } } break; case IO_READ: if (!p_ctx->VDIDevice) { return bRC_Error; } if (!perform_vdi_io(ctx, io, &completionCode)) { goto bail_out; } break; case IO_WRITE: if (p_ctx->RestoreToFile) { if (!perform_file_io(ctx, io, &completionCode)) { goto bail_out; } } else { if (!p_ctx->VDIDevice) { return bRC_Error; } if (!perform_vdi_io(ctx, io, &completionCode)) { goto bail_out; } } break; case IO_CLOSE: if (p_ctx->RestoreToFile) { if (!perform_file_io(ctx, io, &completionCode)) { goto bail_out; } } else { if (!tear_down_vdi_device(ctx, io)) { goto bail_out; } } break; case IO_SEEK: if (p_ctx->RestoreToFile) { if (!perform_file_io(ctx, io, &completionCode)) { goto bail_out; } } else { Jmsg(ctx, M_ERROR, "Illegal Seek request on VDIDevice."); Dmsg(ctx, dbglvl, "Illegal Seek request on VDIDevice."); goto bail_out; } break; } return bRC_OK; bail_out: if (!p_ctx->RestoreToFile) { /* * Report any ADO errors. */ adoReportError(ctx); /* * Generic error handling. */ close_vdi_deviceset(p_ctx); } io->io_errno = completionCode; io->lerror = completionCode; io->win32 = true; io->status = -1; return bRC_Error; } /* * See if we need to do any postprocessing after the restore. */ static bRC end_restore_job(bpContext *ctx, void *value) { bRC retval = bRC_OK; plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } Dmsg(ctx, dbglvl, "mssqlvdi-fd: entering end_restore_job\n"); if (!p_ctx->RestoreToFile && p_ctx->RecoverAfterRestore) { if (!perform_ado_recover(ctx)) { retval = bRC_Error; } } Dmsg(ctx, dbglvl, "mssqlvdi-fd: leaving end_restore_job\n"); return retval; } /* * Bareos is notifying us that a plugin name string was found, * and passing us the plugin command, so we can prepare for a restore. */ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { return bRC_OK; } /* * Bareos is notifying us that the plugin data has terminated, * so the restore for this particular file is done. */ static bRC endRestoreFile(bpContext *ctx) { return bRC_OK; } /* * This is called during restore to create the file (if necessary) We must return in rp->create_status: * * CF_ERROR -- error * CF_SKIP -- skip processing this file * CF_EXTRACT -- extract the file (i.e.call i/o routines) * CF_CREATED -- created, but no content to extract (typically directories) * CF_CORE -- let bareos core create the file */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext; if (!p_ctx) { return bRC_Error; } if (strlen(rp->where) > 0) { p_ctx->RestoreToFile = true; p_ctx->RestoreFD = -1; rp->create_status = CF_CORE; } else { rp->create_status = CF_EXTRACT; } return bRC_OK; } /* * We will get here if the File is a directory after everything is written in the directory. */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { return bRC_OK; } /* * When using Incremental dump, all previous dumps are necessary */ static bRC checkFile(bpContext *ctx, char *fname) { return bRC_OK; } bareos-Release-14.2.6/src/win32/plugins/stored/000077500000000000000000000000001263011562700211525ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/plugins/stored/Makefile000066400000000000000000000033101263011562700226070ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../../plugins/stored include ../../Makefile.inc ifeq ($(WIN_VERSION),32) INCLUDES = -I../../.. \ -I../../../include \ -I../../../stored \ -I../../../plugins/stored \ -I../../include \ -I../../compat/include else INCLUDES = -I../../.. \ -I../../../include \ -I../../../stored \ -I../../../plugins/stored \ -I../../include \ -I../../compat/include endif LDLIBS = ../../lib/libbareos.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(MINGW_LIB)/libz.dll.a \ $(MINGW_LIB)/libfastlz.dll.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid all: autoxflate-sd.dll autoxflate-sd.dll: DLL_USAGE = -DBUILDING_DLL autoxflate-sd.dll: autoxflate-sd.o $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a autoxflate-sd.o $(LDLIBS) -o $@ clean: rm -f *.o distclean:: clean rm -f autoxflate-sd.dll # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< bareos-Release-14.2.6/src/win32/qt-console/000077500000000000000000000000001263011562700202555ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/qt-console/bat.pro000066400000000000000000000072221263011562700215500ustar00rootroot00000000000000CONFIG += qt cross-win32 CONFIG -= debug_and_release CONFIG( debug, debug|release ) { CONFIG -= release } else { CONFIG -= debug CONFIG += release } bins.path = ./ bins.files = ./bat confs.path = ./ confs.commands = ./install_conf_file TEMPLATE = app TARGET = bat DEPENDPATH += . INCLUDEPATH += ../.. ../../include ../include ../compat/include ../../qt-console VPATH = ../../qt-console LIBS += -mwindows ../lib/libbareos.a ../lib/libbareos.dll -lwsock32 DEFINES += HAVE_WIN32 HAVE_MINGW RESOURCES = main.qrc MOC_DIR = moc OBJECTS_DIR = obj UI_DIR = ui # Main window FORMS += main.ui FORMS += prefs.ui FORMS += label/label.ui FORMS += relabel/relabel.ui FORMS += mount/mount.ui FORMS += console/console.ui FORMS += restore/restore.ui restore/prerestore.ui restore/brestore.ui FORMS += restore/runrestore.ui restore/restoretree.ui FORMS += run/run.ui run/runcmd.ui run/estimate.ui run/prune.ui FORMS += select/select.ui select/textinput.ui FORMS += medialist/medialist.ui mediaedit/mediaedit.ui joblist/joblist.ui FORMS += medialist/mediaview.ui FORMS += clients/clients.ui storage/storage.ui fileset/fileset.ui FORMS += joblog/joblog.ui jobs/jobs.ui job/job.ui FORMS += help/help.ui mediainfo/mediainfo.ui FORMS += status/dirstat.ui storage/content.ui FORMS += status/clientstat.ui FORMS += status/storstat.ui # Main directory HEADERS += mainwin.h bat.h bat_conf.h qstd.h pages.h SOURCES += main.cpp bat_conf.cpp mainwin.cpp qstd.cpp pages.cpp # bcomm HEADERS += bcomm/dircomm.h SOURCES += bcomm/dircomm.cpp # Console HEADERS += console/console.h SOURCES += console/console.cpp # Restore HEADERS += restore/restore.h SOURCES += restore/prerestore.cpp restore/restore.cpp restore/brestore.cpp # Label dialog HEADERS += label/label.h SOURCES += label/label.cpp # Relabel dialog HEADERS += relabel/relabel.h SOURCES += relabel/relabel.cpp # Mount dialog HEADERS += mount/mount.h SOURCES += mount/mount.cpp # Run dialog HEADERS += run/run.h SOURCES += run/run.cpp run/runcmd.cpp run/estimate.cpp run/prune.cpp # Select dialog HEADERS += select/select.h select/textinput.h SOURCES += select/select.cpp select/textinput.cpp ## MediaList HEADERS += medialist/medialist.h SOURCES += medialist/medialist.cpp # MediaView HEADERS += medialist/mediaview.h SOURCES += medialist/mediaview.cpp ## MediaEdit HEADERS += mediaedit/mediaedit.h SOURCES += mediaedit/mediaedit.cpp ## JobList HEADERS += joblist/joblist.h SOURCES += joblist/joblist.cpp ## Clients HEADERS += clients/clients.h SOURCES += clients/clients.cpp ## Storage HEADERS += storage/storage.h SOURCES += storage/storage.cpp ## Storage content HEADERS += storage/content.h SOURCES += storage/content.cpp ## Fileset HEADERS += fileset/fileset.h SOURCES += fileset/fileset.cpp ## Job log HEADERS += joblog/joblog.h SOURCES += joblog/joblog.cpp ## Job HEADERS += job/job.h SOURCES += job/job.cpp ## Jobs HEADERS += jobs/jobs.h SOURCES += jobs/jobs.cpp ## RestoreTree HEADERS += restore/restoretree.h SOURCES += restore/restoretree.cpp # Help dialog HEADERS += help/help.h SOURCES += help/help.cpp # Media info dialog HEADERS += mediainfo/mediainfo.h SOURCES += mediainfo/mediainfo.cpp ## Status Dir HEADERS += status/dirstat.h SOURCES += status/dirstat.cpp ## Status Client HEADERS += status/clientstat.h SOURCES += status/clientstat.cpp ## Status Client HEADERS += status/storstat.h SOURCES += status/storstat.cpp # Utility sources HEADERS += util/fmtwidgetitem.h util/comboutil.h SOURCES += util/fmtwidgetitem.cpp util/comboutil.cpp INSTALLS += bins INSTALLS += confs QMAKE_EXTRA_TARGETS += depend TRANSLATIONS += ts/bat_fr.ts ts/bat_de.ts # Windows Icon and App Info win32:RC_FILE = batres.rc bareos-Release-14.2.6/src/win32/qt-console/batres.rc.in000066400000000000000000000022321263011562700224670ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareos.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos Admin Tool" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bat.exe" VALUE "OriginalFilename", "bat.exe" VALUE "ProductName", "Bareos Admin Tool" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/qt-tray-monitor/000077500000000000000000000000001263011562700212575ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/qt-tray-monitor/tray-monitor.pro000066400000000000000000000023001263011562700244400ustar00rootroot00000000000000CONFIG += qt cross-win32 CONFIG -= debug_and_release CONFIG( debug, debug|release ) { CONFIG -= release } else { CONFIG -= debug CONFIG += release } bins.path = /$(DESTDIR)@sbindir@ bins.files = bareos-tray-monitor confs.path = /$(DESTDIR)@sysconfdir@ confs.commands = ./install_conf_file TEMPLATE = app TARGET = bareos-tray-monitor PRE_TARGETDEPS += ../lib/libbareos.a ../lib/libbareos.dll DEPENDPATH += . INCLUDEPATH += ../.. ../../include ../include ../compat/include \ ../../qt-tray-monitor VPATH = ../../qt-tray-monitor LIBS += -mwindows ../lib/libbareos.a ../lib/libbareos.dll -lwsock32 DEFINES += HAVE_WIN32 HAVE_MINGW _STAT_DEFINED=1 RESOURCES = main.qrc MOC_DIR = moc OBJECTS_DIR = obj UI_DIR = ui # Main directory HEADERS += tray_conf.h tray-monitor.h traymenu.h \ systemtrayicon.h mainwindow.h authenticate.h monitoritem.h \ monitoritemthread.h monitortab.h SOURCES += authenticate.cpp tray_conf.cpp tray-monitor.cpp \ traymenu.cpp systemtrayicon.cpp mainwindow.cpp monitoritem.cpp \ monitoritemthread.cpp FORMS += mainwindow.ui # Application icon and info win32:RC_FILE = traymon.rc bareos-Release-14.2.6/src/win32/qt-tray-monitor/traymon.rc.in000066400000000000000000000022751263011562700237110ustar00rootroot00000000000000id ICON "../../../platforms/win32/traymon.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos Tray Monitor" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bareos-tray-monitor.exe" VALUE "OriginalFilename", "bareos-tray-monitor.exe" VALUE "ProductName", "Bareos Admin Tool" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/stored/000077500000000000000000000000001263011562700174715ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/stored/Makefile000066400000000000000000000075411263011562700211400ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../stored:../../stored/backends:../generic:backends include ../Makefile.inc INCLUDES = -I. \ -I../.. \ -I../../include \ -I../../stored \ -I../../stored/backends \ -I../include \ -I../compat/include LDLIBS = ../lib/libbareos.a \ ../lib/libbareos.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid -lcomctl32 LDLIBS_FIND = ../lib/libbareos.a \ ../lib/libbareos.dll \ ../findlib/libbareosfind.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid -lcomctl32 DEVICE_API_SRCS = generic_tape_device.c win32_tape_device.c win32_file_device.c # objects used in all daemons collected in (shared) library. LIBBAREOSSD_SRCS = acquire.c ansi_label.c askdir.c autochanger.c block.c \ bsr.c butil.c crc32.c dev.c device.c ebcdic.c label.c \ lock.c mount.c read_record.c record.c reserve.c scan.c \ sd_backends.c sd_plugins.c sd_stats.c spool.c \ stored_conf.c vol_mgr.c wait.c $(DEVICE_API_SRCS) LIBBAREOSSD_OBJS = $(LIBBAREOSSD_SRCS:.c=.o) DYNAMIC_OBJS = $(LIBBAREOSSD_OBJS) SVRSRCS = append.c askdir.c authenticate.c dir_cmd.c fd_cmds.c job.c mac.c \ ndmp_tape.c read.c sd_cmds.c sd_stats.c status.c stored.c \ service.c main.c SVROBJS = $(SVRSRCS:.c=.o) TAPESRCS = btape.c TAPEOBJS = $(TAPESRCS:.c=.o) BLSSRCS = bls.c BLSOBJS = $(BLSSRCS:.c=.o) BEXTSRCS = bextract.c BEXTOBJS = $(BEXTSRCS:.c=.o) WINDRESSRCS = storedres.rc WINDRESOBJS = $(WINDRESSRCS:.rc=.o) BLSRESSRCS = blsres.rc BLSRESOBJS = $(BLSRESSRCS:.rc=.o) BTAPERESSRCS = btaperes.rc BTAPERESOBJS = $(BTAPERESSRCS:.rc=.o) BEXTRACTRESSRCS = bextractres.rc BEXTRACTRESOBJS = $(BEXTRACTRESSRCS:.rc=.o) all: libbareossd.dll bareos-sd.exe btape.exe bls.exe bextract.exe bareos$(WIN_VERSION).def: $(DYNAMIC_OBJS) make_def ./make_def $(WIN_VERSION) $(DYNAMIC_OBJS) > $@ libbareossd.dll: DLL_USAGE = -DBUILDING_DLL libbareossd.dll: $(DYNAMIC_OBJS) \ bareos$(WIN_VERSION).def $(CXX) $(LDFLAGS_DLL) -Wl,--out-implib,$@.a $(DYNAMIC_OBJS) bareos$(WIN_VERSION).def $(LDLIBS) -o $@ bareos-sd.exe: DLL_USAGE = -DUSING_DLL bareos-sd.exe: libbareossd.dll $(SVROBJS) $(WINDRESOBJS) $(CXX) $(LDFLAGS_WINAPP) $(SVROBJS) $(WINDRESOBJS) $(LDLIBS) ./libbareossd.dll -o $@ btape.exe: DLL_USAGE = -DUSING_DLL btape.exe: libbareossd.dll $(TAPEOBJS) $(BTAPERESOBJS) $(CXX) $(LDFLAGS_CONS) $(TAPEOBJS) $(BTAPERESOBJS) $(LDLIBS) ./libbareossd.dll -o $@ bls.exe: DLL_USAGE = -DUSING_DLL bls.exe: libbareossd.dll $(BLSOBJS) $(BLSRESOBJS) $(CXX) $(LDFLAGS_CONS) $(BLSOBJS) $(BLSRESOBJS) $(LDLIBS_FIND) ./libbareossd.dll -o $@ bextract.exe: DLL_USAGE = -DUSING_DLL bextract.exe: libbareossd.dll $(BEXTOBJS) $(BEXTRACTRESOBJS) $(CXX) $(LDFLAGS_CONS) $(BEXTOBJS) $(BEXTRACTRESOBJS) $(LDLIBS_FIND) ./libbareossd.dll -o $@ clean: rm -f *.o bareos$(WIN_VERSION).def distclean:: clean rm -f libbareossd.dll libbareossd.dll.a bareos-sd.exe btape.exe bls.exe bextract.exe # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< %.o : %.rc @echo "Ressource Compiling $^" $(WINDRES) $^ -o $@ bareos-Release-14.2.6/src/win32/stored/backends/000077500000000000000000000000001263011562700212435ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/stored/backends/win32_file_device.c000066400000000000000000000204051263011562700246700ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows File API device abstraction. * * Kern Sibbald, MM * * Extracted from other source files Marco van Wieringen, December 2013 */ #include "bareos.h" #include "stored.h" #include "win32_file_device.h" /* * (Un)mount the device (For a FILE device) */ static bool do_mount(DCR *dcr, bool mount, int dotimeout) { DEVRES *device = dcr->dev->device; POOL_MEM ocmd(PM_FNAME); POOLMEM *results; DIR* dp; char *icmd; struct dirent *entry, *result; int status, tries, name_max, count; berrno be; Dsm_check(200); if (mount) { icmd = device->mount_command; } else { icmd = device->unmount_command; } dcr->dev->edit_mount_codes(ocmd, icmd); Dmsg2(100, "do_mount: cmd=%s mounted=%d\n", ocmd.c_str(), dcr->dev->is_mounted()); if (dotimeout) { /* Try at most 10 times to (un)mount the device. This should perhaps be configurable. */ tries = 10; } else { tries = 1; } results = get_memory(4000); /* If busy retry each second */ Dmsg1(100, "do_mount run_prog=%s\n", ocmd.c_str()); while ((status = run_program_full_output(ocmd.c_str(), dcr->dev->max_open_wait / 2, results)) != 0) { /* Doesn't work with internationalization (This is not a problem) */ if (mount && fnmatch("*is already mounted on*", results, 0) == 0) { break; } if (!mount && fnmatch("* not mounted*", results, 0) == 0) { break; } if (tries-- > 0) { /* Sometimes the device cannot be mounted because it is already mounted. * Try to unmount it, then remount it */ if (mount) { Dmsg1(400, "Trying to unmount the device %s...\n", dcr->dev->print_name()); do_mount(dcr, 0, 0); } bmicrosleep(1, 0); continue; } Dmsg5(100, "Device %s cannot be %smounted. status=%d result=%s ERR=%s\n", dcr->dev->print_name(), (mount ? "" : "un"), status, results, be.bstrerror(status)); Mmsg(dcr->dev->errmsg, _("Device %s cannot be %smounted. ERR=%s\n"), dcr->dev->print_name(), (mount ? "" : "un"), be.bstrerror(status)); /* * Now, just to be sure it is not mounted, try to read the filesystem. */ name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { name_max = 1024; } if (!(dp = opendir(device->mount_point))) { berrno be; dcr->dev->dev_errno = errno; Dmsg3(100, "do_mount: failed to open dir %s (dev=%s), ERR=%s\n", device->mount_point, dcr->dev->print_name(), be.bstrerror()); goto get_out; } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); count = 0; while (1) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { dcr->dev->dev_errno = EIO; Dmsg2(129, "do_mount: failed to find suitable file in dir %s (dev=%s)\n", device->mount_point, dcr->dev->print_name()); break; } if (!bstrcmp(result->d_name, ".") && !bstrcmp(result->d_name, "..") && !bstrcmp(result->d_name, ".keep")) { count++; /* result->d_name != ., .. or .keep (Gentoo-specific) */ break; } else { Dmsg2(129, "do_mount: ignoring %s in %s\n", result->d_name, device->mount_point); } } free(entry); closedir(dp); Dmsg1(100, "do_mount: got %d files in the mount point (not counting ., .. and .keep)\n", count); if (count > 0) { /* If we got more than ., .. and .keep */ /* there must be something mounted */ if (mount) { Dmsg1(100, "Did Mount by count=%d\n", count); break; } else { /* An unmount request. We failed to unmount - report an error */ free_pool_memory(results); Dmsg0(200, "== error mount=1 wanted unmount\n"); return false; } } get_out: free_pool_memory(results); Dmsg0(200, "============ mount=0\n"); Dsm_check(200); return false; } free_pool_memory(results); Dmsg1(200, "============ mount=%d\n", mount); return true; } /* * Mount the device. * * If timeout, wait until the mount command returns 0. * If !timeout, try to mount the device only once. */ bool win32_file_device::mount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->mount_command) { retval = do_mount(dcr, true, timeout); } return retval; } /* * Unmount the device * * If timeout, wait until the unmount command returns 0. * If !timeout, try to unmount the device only once. */ bool win32_file_device::unmount_backend(DCR *dcr, int timeout) { bool retval = true; if (requires_mount() && device->unmount_command) { retval = do_mount(dcr, false, timeout); } return retval; } int win32_file_device::d_open(const char *pathname, int flags, int mode) { return ::open(pathname, flags, mode); } ssize_t win32_file_device::d_read(int fd, void *buffer, size_t count) { return ::read(fd, buffer, count); } ssize_t win32_file_device::d_write(int fd, const void *buffer, size_t count) { return ::write(fd, buffer, count); } int win32_file_device::d_close(int fd) { return ::close(fd); } int win32_file_device::d_ioctl(int fd, ioctl_req_t request, char *op) { return -1; } boffset_t win32_file_device::d_lseek(DCR *dcr, boffset_t offset, int whence) { return ::_lseeki64(m_fd, (__int64)offset, whence); } bool win32_file_device::d_truncate(DCR *dcr) { struct stat st; if (ftruncate(m_fd, 0) != 0) { berrno be; Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), print_name(), be.bstrerror()); return false; } /* * Check for a successful ftruncate() and issue a work-around for devices * (mostly cheap NAS) that don't support truncation. * Workaround supplied by Martin Schmid as a solution to bug #1011. * 1. close file * 2. delete file * 3. open new file with same mode * 4. change ownership to original */ if (fstat(m_fd, &st) != 0) { berrno be; Mmsg2(errmsg, _("Unable to stat device %s. ERR=%s\n"), print_name(), be.bstrerror()); return false; } if (st.st_size != 0) { /* ftruncate() didn't work */ POOL_MEM archive_name(PM_FNAME); pm_strcpy(archive_name, dev_name); if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) { pm_strcat(archive_name, "/"); } pm_strcat(archive_name, dcr->VolumeName); Mmsg2(errmsg, _("Device %s doesn't support ftruncate(). Recreating file %s.\n"), print_name(), archive_name.c_str()); /* * Close file and blow it away */ ::close(m_fd); ::unlink(archive_name.c_str()); /* * Recreate the file -- of course, empty */ oflags = O_CREAT | O_RDWR | O_BINARY; if ((m_fd = ::open(archive_name.c_str(), oflags, st.st_mode)) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("Could not reopen: %s, ERR=%s\n"), archive_name.c_str(), be.bstrerror()); Dmsg1(100, "reopen failed: %s", errmsg); Emsg0(M_FATAL, 0, errmsg); return false; } /* * Reset proper owner */ chown(archive_name.c_str(), st.st_uid, st.st_gid); } return true; } win32_file_device::~win32_file_device() { } win32_file_device::win32_file_device() { } bareos-Release-14.2.6/src/win32/stored/backends/win32_file_device.h000066400000000000000000000030721263011562700246760ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows File API device abstraction. * * Marco van Wieringen, December 2013 */ #ifndef WIN32_FILE_DEVICE_H #define WIN32_FILE_DEVICE_H class win32_file_device: public DEVICE { public: win32_file_device(); ~win32_file_device(); /* * Interface from DEVICE */ bool mount_backend(DCR *dcr, int timeout); bool unmount_backend(DCR *dcr, int timeout); int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); boffset_t d_lseek(DCR *dcr, boffset_t offset, int whence); bool d_truncate(DCR *dcr); }; #endif /* WIN32_FILE_DEVICE_H */ bareos-Release-14.2.6/src/win32/stored/backends/win32_tape_device.c000066400000000000000000001003601263011562700247010ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2013-2013 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. 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 Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows Tape API device abstraction. * * Kern Sibbald, MM * * Emulate the Linux st (scsi tape) driver on Microsoft Windows. * Robert Nelson, May, 2006 * * Extracted from other source files Marco van Wieringen, December 2013 */ #include "bareos.h" #include "stored.h" #include "generic_tape_device.h" #include "win32_tape_device.h" #include "sys/mtio.h" #if defined(_MSC_VER) #include #else #include #endif #include /* * SCSI bus status codes. */ #define SCSISTAT_GOOD 0x00 #define SCSISTAT_CHECK_CONDITION 0x02 #define SCSISTAT_CONDITION_MET 0x04 #define SCSISTAT_BUSY 0x08 #define SCSISTAT_INTERMEDIATE 0x10 #define SCSISTAT_INTERMEDIATE_COND_MET 0x14 #define SCSISTAT_RESERVATION_CONFLICT 0x18 #define SCSISTAT_COMMAND_TERMINATED 0x22 #define SCSISTAT_QUEUE_FULL 0x28 static inline SHORT Read16BitSigned(const unsigned char *pValue) { return (SHORT)(((USHORT)pValue[0] << 8) | (USHORT)pValue[1]); } static inline USHORT Read16BitUnsigned(const unsigned char *pValue) { return (((USHORT)pValue[0] << 8) | (USHORT)pValue[1]); } static inline LONG Read24BitSigned(const unsigned char *pValue) { return ((LONG)(((ULONG)pValue[0] << 16) | ((ULONG)pValue[1] << 8) | (ULONG)pValue[2])) << 8 >> 8; } static inline ULONG Read24BitUnsigned(const unsigned char *pValue) { return ((ULONG)pValue[0] << 16) | ((ULONG)pValue[1] << 8) | (ULONG)pValue[2]; } static inline LONG Read32BitSigned(const unsigned char *pValue) { return (LONG)(((ULONG)pValue[0] << 24) | ((ULONG)pValue[1] << 16) | ((ULONG)pValue[2] << 8) | (ULONG)pValue[3]); } static inline ULONG Read32BitUnsigned(const unsigned char *pValue) { return (((ULONG)pValue[0] << 24) | ((ULONG)pValue[1] << 16) | ((ULONG)pValue[2] << 8) | (ULONG)pValue[3]); } static inline LONGLONG Read64BitSigned(const unsigned char *pValue) { return (LONGLONG)(((ULONGLONG)pValue[0] << 56) | ((ULONGLONG)pValue[1] << 48) | ((ULONGLONG)pValue[2] << 40) | ((ULONGLONG)pValue[3] << 32) | ((ULONGLONG)pValue[4] << 24) | ((ULONGLONG)pValue[5] << 16) | ((ULONGLONG)pValue[6] << 8) | (ULONGLONG)pValue[7]); } static inline ULONGLONG Read64BitUnsigned(const unsigned char *pValue) { return (LONGLONG)(((ULONGLONG)pValue[0] << 56) | ((ULONGLONG)pValue[1] << 48) | ((ULONGLONG)pValue[2] << 40) | ((ULONGLONG)pValue[3] << 32) | ((ULONGLONG)pValue[4] << 24) | ((ULONGLONG)pValue[5] << 16) | ((ULONGLONG)pValue[6] << 8) | (ULONGLONG)pValue[7]); } typedef struct _TAPE_POSITION_INFO { UCHAR AtPartitionStart:1; UCHAR AtPartitionEnd:1; UCHAR PartitionBlockValid:1; UCHAR FileSetValid:1; UCHAR :4; UCHAR Reserved1[3]; ULONG Partition; ULONGLONG BlockNumber; ULONGLONG FileNumber; ULONGLONG SetNumber; } TAPE_POSITION_INFO, *PTAPE_POSITION_INFO; typedef struct _TAPE_HANDLE_INFO { HANDLE OSHandle; bool bEOD; bool bEOF; bool bEOT; bool bBlockValid; ULONG FeaturesLow; ULONG FeaturesHigh; ULONG ulFile; ULONGLONG ullFileStart; } TAPE_HANDLE_INFO, *PTAPE_HANDLE_INFO; TAPE_HANDLE_INFO TapeHandleTable[] = { { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE }, { INVALID_HANDLE_VALUE } }; #define NUMBER_HANDLE_ENTRIES (sizeof(TapeHandleTable) / sizeof(TapeHandleTable[0])) static DWORD GetTapePositionInfo(HANDLE hDevice, PTAPE_POSITION_INFO TapePositionInfo); static DWORD GetDensityBlockSize(HANDLE hDevice, DWORD *pdwDensity, DWORD *pdwBlockSize); int win32_tape_device::d_open(const char *pathname, int flags, int mode) { HANDLE hDevice = INVALID_HANDLE_VALUE; char szDeviceName[256] = "\\\\.\\"; int idxFile; DWORD dwResult; for (idxFile = 0; idxFile < (int)NUMBER_HANDLE_ENTRIES; idxFile++) { if (TapeHandleTable[idxFile].OSHandle == INVALID_HANDLE_VALUE) { break; } } if (idxFile >= (int)NUMBER_HANDLE_ENTRIES) { return EMFILE; } memset(&TapeHandleTable[idxFile], 0, sizeof(TapeHandleTable[idxFile])); if (!IsPathSeparator(pathname[0])) { bstrncpy(&szDeviceName[4], pathname, sizeof(szDeviceName) - 4); } else { bstrncpy(&szDeviceName[0], pathname, sizeof(szDeviceName)); } hDevice = CreateFile(szDeviceName, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, NULL); if (hDevice != INVALID_HANDLE_VALUE) { PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[idxFile]; memset(pHandleInfo, 0, sizeof(*pHandleInfo)); pHandleInfo->OSHandle = hDevice; TAPE_GET_DRIVE_PARAMETERS TapeDriveParameters; DWORD dwSize = sizeof(TapeDriveParameters); dwResult = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &dwSize, &TapeDriveParameters); if (dwResult == NO_ERROR) { pHandleInfo->FeaturesLow = TapeDriveParameters.FeaturesLow; pHandleInfo->FeaturesHigh = TapeDriveParameters.FeaturesHigh; } TAPE_POSITION_INFO TapePositionInfo; dwResult = GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo); if (dwResult == NO_ERROR) { if (TapePositionInfo.AtPartitionStart || TapePositionInfo.AtPartitionEnd || (TapePositionInfo.PartitionBlockValid && TapePositionInfo.BlockNumber == 0)) { pHandleInfo->ulFile = 0; pHandleInfo->bBlockValid = true; pHandleInfo->ullFileStart = 0; } else if (TapePositionInfo.FileSetValid) { pHandleInfo->ulFile = (ULONG)TapePositionInfo.FileNumber; } } } else { DWORD dwError = GetLastError(); switch (dwError) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; case ERROR_TOO_MANY_OPEN_FILES: errno = EMFILE; break; case ERROR_ACCESS_DENIED: case ERROR_SHARING_VIOLATION: case ERROR_LOCK_VIOLATION: case ERROR_INVALID_NAME: errno = EACCES; break; case ERROR_FILE_EXISTS: errno = EEXIST; break; case ERROR_INVALID_PARAMETER: errno = EINVAL; break; default: errno = EACCES; break; } return(int) -1; } return (int)idxFile + 3; } ssize_t win32_tape_device::d_read(int fd, void *buffer, size_t count) { if (buffer == NULL) { errno = EINVAL; return -1; } if (fd < 3 || fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) || TapeHandleTable[fd - 3].OSHandle == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; } PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[fd - 3]; DWORD bytes_read; BOOL bResult; bResult = ReadFile(pHandleInfo->OSHandle, buffer, count, &bytes_read, NULL); if (bResult) { pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->bEOD = false; return bytes_read; } else { int iReturnValue = 0; DWORD last_error = GetLastError(); switch (last_error) { case ERROR_FILEMARK_DETECTED: pHandleInfo->bEOF = true; break; case ERROR_END_OF_MEDIA: pHandleInfo->bEOT = true; break; case ERROR_NO_MEDIA_IN_DRIVE: pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->bEOD = false; errno = ENOMEDIUM; iReturnValue = -1; break; case ERROR_NO_DATA_DETECTED: pHandleInfo->bEOD = true; break; case ERROR_INVALID_HANDLE: case ERROR_ACCESS_DENIED: case ERROR_LOCK_VIOLATION: errno = EBADF; iReturnValue = -1; break; default: pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->bEOD = false; errno = EIO; iReturnValue = -1; } return iReturnValue; } } ssize_t win32_tape_device::d_write(int fd, const void *buffer, size_t count) { if (buffer == NULL) { errno = EINVAL; return -1; } if (fd < 3 || fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) || TapeHandleTable[fd - 3].OSHandle == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; } PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[fd - 3]; DWORD bytes_written; BOOL bResult; bResult = WriteFile(pHandleInfo->OSHandle, buffer, count, &bytes_written, NULL); if (bResult) { pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; return bytes_written; } else { DWORD last_error = GetLastError(); switch (last_error) { case ERROR_END_OF_MEDIA: case ERROR_DISK_FULL: pHandleInfo->bEOT = true; errno = ENOSPC; break; case ERROR_NO_MEDIA_IN_DRIVE: pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->bEOD = false; errno = ENOMEDIUM; break; case ERROR_INVALID_HANDLE: case ERROR_ACCESS_DENIED: errno = EBADF; break; default: pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->bEOD = false; errno = EIO; break; } return -1; } } int win32_tape_device::d_close(int fd) { if (fd < 3 || fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) || TapeHandleTable[fd - 3].OSHandle == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; } PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[fd - 3]; if (!CloseHandle(pHandleInfo->OSHandle)) { pHandleInfo->OSHandle = INVALID_HANDLE_VALUE; errno = EBADF; return -1; } pHandleInfo->OSHandle = INVALID_HANDLE_VALUE; return 0; } int win32_tape_device::d_ioctl(int fd, ioctl_req_t request, char *op) { int result = 0; if (request == MTIOCTOP) { result = tape_op((mtop *)op); } else if (request == MTIOCGET) { result = tape_get((mtget *)op); } else if (request == MTIOCPOS) { result = tape_pos((mtpos *)op); } else { errno = ENOTTY; result = -1; } return result; } int win32_tape_device::tape_op(struct mtop *mt_com) { DWORD result = NO_ERROR; int index; if (m_fd < 3 || m_fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) || TapeHandleTable[m_fd - 3].OSHandle == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; } PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[m_fd - 3]; switch (mt_com->mt_op) { case MTRESET: case MTNOP: case MTSETDRVBUFFER: break; case MTRAS1: case MTRAS2: case MTRAS3: case MTSETDENSITY: errno = ENOTTY; result = (DWORD)-1; break; case MTFSF: for (index = 0; index < mt_com->mt_count; index++) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, 1, 0, FALSE); if (result == NO_ERROR) { pHandleInfo->ulFile++; pHandleInfo->bEOF = true; pHandleInfo->bEOT = false; } } break; case MTBSF: for (index = 0; index < mt_com->mt_count; index++) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, (DWORD)-1, ~0, FALSE); if (result == NO_ERROR) { pHandleInfo->ulFile--; pHandleInfo->bBlockValid = false; pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; } } break; case MTFSR: result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_RELATIVE_BLOCKS, 0, mt_com->mt_count, 0, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; } else if (result == ERROR_FILEMARK_DETECTED) { pHandleInfo->bEOF = true; } break; case MTBSR: result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_RELATIVE_BLOCKS, 0, -mt_com->mt_count, ~0, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; } else if (result == ERROR_FILEMARK_DETECTED) { pHandleInfo->ulFile--; pHandleInfo->bBlockValid = false; pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; } break; case MTWEOF: result = WriteTapemark(pHandleInfo->OSHandle, TAPE_FILEMARKS, mt_com->mt_count, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOF = true; pHandleInfo->bEOT = false; pHandleInfo->ulFile += mt_com->mt_count; pHandleInfo->bBlockValid = true; pHandleInfo->ullFileStart = 0; } break; case MTREW: result = SetTapePosition(pHandleInfo->OSHandle, TAPE_REWIND, 0, 0, 0, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->ulFile = 0; pHandleInfo->bBlockValid = true; pHandleInfo->ullFileStart = 0; } break; case MTOFFL: result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOAD, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->ulFile = 0; pHandleInfo->ullFileStart = 0; } break; case MTRETEN: result = PrepareTape(pHandleInfo->OSHandle, TAPE_TENSION, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->ulFile = 0; pHandleInfo->bBlockValid = true; pHandleInfo->ullFileStart = 0; } break; case MTBSFM: for (index = 0; index < mt_com->mt_count; index++) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, (DWORD)-1, ~0, FALSE); if (result == NO_ERROR) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, 1, 0, FALSE); pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; } } break; case MTFSFM: for (index = 0; index < mt_com->mt_count; index++) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, mt_com->mt_count, 0, FALSE); if (result == NO_ERROR) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, (DWORD)-1, ~0, FALSE); pHandleInfo->bEOD = false; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; } } break; case MTEOM: while (1) { result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_FILEMARKS, 0, 1, 0, FALSE); if (result != NO_ERROR) { pHandleInfo->bEOF = false; if (result == ERROR_END_OF_MEDIA) { pHandleInfo->bEOD = true; pHandleInfo->bEOT = true; return 0; } if (result == ERROR_NO_DATA_DETECTED) { pHandleInfo->bEOD = true; pHandleInfo->bEOT = false; return 0; } break; } else { pHandleInfo->bEOF = true; pHandleInfo->ulFile++; } } break; case MTERASE: result = EraseTape(pHandleInfo->OSHandle, TAPE_ERASE_LONG, FALSE); if (result == NO_ERROR) { pHandleInfo->bEOD = true; pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->ulFile = 0; pHandleInfo->bBlockValid = true; pHandleInfo->ullFileStart = 0; } break; case MTSETBLK: { TAPE_SET_MEDIA_PARAMETERS SetMediaParameters; SetMediaParameters.BlockSize = mt_com->mt_count; result = SetTapeParameters(pHandleInfo->OSHandle, SET_TAPE_MEDIA_INFORMATION, &SetMediaParameters); break; } case MTSEEK: { TAPE_POSITION_INFO TapePositionInfo; result = SetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, 0, mt_com->mt_count, 0, FALSE); memset(&TapePositionInfo, 0, sizeof(TapePositionInfo)); DWORD dwPosResult = GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo); if (dwPosResult == NO_ERROR && TapePositionInfo.FileSetValid) { pHandleInfo->ulFile = (ULONG)TapePositionInfo.FileNumber; } else { pHandleInfo->ulFile = ~0U; } break; } case MTTELL: { DWORD partition; DWORD offset; DWORD offsetHi; result = GetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, &partition, &offset, &offsetHi); if (result == NO_ERROR) { return offset; } break; } case MTFSS: result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_SETMARKS, 0, mt_com->mt_count, 0, FALSE); break; case MTBSS: result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_SETMARKS, 0, -mt_com->mt_count, ~0, FALSE); break; case MTWSM: result = WriteTapemark(pHandleInfo->OSHandle, TAPE_SETMARKS, mt_com->mt_count, FALSE); break; case MTLOCK: result = PrepareTape(pHandleInfo->OSHandle, TAPE_LOCK, FALSE); break; case MTUNLOCK: result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOCK, FALSE); break; case MTLOAD: result = PrepareTape(pHandleInfo->OSHandle, TAPE_LOAD, FALSE); break; case MTUNLOAD: result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOAD, FALSE); break; case MTCOMPRESSION: { TAPE_GET_DRIVE_PARAMETERS GetDriveParameters; TAPE_SET_DRIVE_PARAMETERS SetDriveParameters; DWORD size; size = sizeof(GetDriveParameters); result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &size, &GetDriveParameters); if (result == NO_ERROR) { SetDriveParameters.ECC = GetDriveParameters.ECC; SetDriveParameters.Compression = (BOOLEAN)mt_com->mt_count; SetDriveParameters.DataPadding = GetDriveParameters.DataPadding; SetDriveParameters.ReportSetmarks = GetDriveParameters.ReportSetmarks; SetDriveParameters.EOTWarningZoneSize = GetDriveParameters.EOTWarningZoneSize; result = SetTapeParameters(pHandleInfo->OSHandle, SET_TAPE_DRIVE_INFORMATION, &SetDriveParameters); } break; } case MTSETPART: result = SetTapePosition(pHandleInfo->OSHandle, TAPE_LOGICAL_BLOCK, mt_com->mt_count, 0, 0, FALSE); break; case MTMKPART: if (mt_com->mt_count == 0) { result = CreateTapePartition(pHandleInfo->OSHandle, TAPE_INITIATOR_PARTITIONS, 1, 0); } else { result = CreateTapePartition(pHandleInfo->OSHandle, TAPE_INITIATOR_PARTITIONS, 2, mt_com->mt_count); } break; default: errno = ENOTTY; result = (DWORD)-1; break; } if ((result == NO_ERROR && pHandleInfo->bEOF) || (result == ERROR_FILEMARK_DETECTED && mt_com->mt_op == MTFSR)) { TAPE_POSITION_INFO TapePositionInfo; if (GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo) == NO_ERROR) { pHandleInfo->bBlockValid = true; pHandleInfo->ullFileStart = TapePositionInfo.BlockNumber; } } switch (result) { case NO_ERROR: case (DWORD)-1: /* Error has already been translated into errno */ break; case ERROR_FILEMARK_DETECTED: errno = EIO; break; case ERROR_END_OF_MEDIA: pHandleInfo->bEOT = true; errno = EIO; break; case ERROR_NO_DATA_DETECTED: pHandleInfo->bEOD = true; errno = EIO; break; case ERROR_NO_MEDIA_IN_DRIVE: pHandleInfo->bEOF = false; pHandleInfo->bEOT = false; pHandleInfo->bEOD = false; errno = ENOMEDIUM; break; case ERROR_INVALID_HANDLE: case ERROR_ACCESS_DENIED: case ERROR_LOCK_VIOLATION: errno = EBADF; break; default: errno = EIO; break; } return result == NO_ERROR ? 0 : -1; } int win32_tape_device::tape_get(struct mtget *mt_get) { TAPE_POSITION_INFO pos_info; BOOL result; if (m_fd < 3 || m_fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) || TapeHandleTable[m_fd - 3].OSHandle == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; } PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[m_fd - 3]; if (GetTapePositionInfo(pHandleInfo->OSHandle, &pos_info) != NO_ERROR) { return -1; } DWORD density = 0; DWORD blocksize = 0; result = GetDensityBlockSize(pHandleInfo->OSHandle, &density, &blocksize); if (result != NO_ERROR) { TAPE_GET_DRIVE_PARAMETERS drive_params; DWORD size; size = sizeof(drive_params); result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &size, &drive_params); if (result == NO_ERROR) { blocksize = drive_params.DefaultBlockSize; } } mt_get->mt_type = MT_ISSCSI2; /* * Partition # */ mt_get->mt_resid = pos_info.PartitionBlockValid ? pos_info.Partition : (ULONG)-1; /* * Density / Block Size */ mt_get->mt_dsreg = ((density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK) | ((blocksize << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK); mt_get->mt_gstat = 0x00010000; /* Immediate report mode.*/ if (pHandleInfo->bEOF) { mt_get->mt_gstat |= 0x80000000; /* GMT_EOF */ } if (pos_info.PartitionBlockValid && pos_info.BlockNumber == 0) { mt_get->mt_gstat |= 0x40000000; /* GMT_BOT */ } if (pHandleInfo->bEOT) { mt_get->mt_gstat |= 0x20000000; /* GMT_EOT */ } if (pHandleInfo->bEOD) { mt_get->mt_gstat |= 0x08000000; /* GMT_EOD */ } TAPE_GET_MEDIA_PARAMETERS media_params; DWORD size = sizeof(media_params); result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_MEDIA_INFORMATION, &size, &media_params); if (result == NO_ERROR && media_params.WriteProtected) { mt_get->mt_gstat |= 0x04000000; /* GMT_WR_PROT */ } result = GetTapeStatus(pHandleInfo->OSHandle); if (result != NO_ERROR) { if (result == ERROR_NO_MEDIA_IN_DRIVE) { mt_get->mt_gstat |= 0x00040000; /* GMT_DR_OPEN */ } } else { mt_get->mt_gstat |= 0x01000000; /* GMT_ONLINE */ } /* * Recovered Error Count */ mt_get->mt_erreg = 0; /* * File Number */ mt_get->mt_fileno = (__daddr_t)pHandleInfo->ulFile; /* * Block Number */ mt_get->mt_blkno = (__daddr_t)(pHandleInfo->bBlockValid ? pos_info.BlockNumber - pHandleInfo->ullFileStart : (ULONGLONG)-1); return 0; } #define SERVICEACTION_SHORT_FORM_BLOCKID 0 #define SERVICEACTION_SHORT_FORM_VENDOR_SPECIFIC 1 #define SERVICEACTION_LONG_FORM 6 #define SERVICEACTION_EXTENDED_FORM 8 typedef struct _SCSI_READ_POSITION_SHORT_BUFFER { UCHAR :1; UCHAR PERR:1; UCHAR BPU:1; UCHAR :1; UCHAR BYCU:1; UCHAR BCU:1; UCHAR EOP:1; UCHAR BOP:1; UCHAR Partition; UCHAR Reserved1[2]; UCHAR FirstBlock[4]; UCHAR LastBlock[4]; UCHAR Reserved2; UCHAR NumberBufferBlocks[3]; UCHAR NumberBufferBytes[4]; } SCSI_READ_POSITION_SHORT_BUFFER, *PSCSI_READ_POSITION_SHORT_BUFFER; typedef struct _SCSI_READ_POSITION_LONG_BUFFER { UCHAR :2; UCHAR BPU:1; UCHAR MPU:1; UCHAR :2; UCHAR EOP:1; UCHAR BOP:1; UCHAR Reserved3[3]; UCHAR Partition[4]; UCHAR BlockNumber[8]; UCHAR FileNumber[8]; UCHAR SetNumber[8]; } SCSI_READ_POSITION_LONG_BUFFER, *PSCSI_READ_POSITION_LONG_BUFFER; typedef struct _SCSI_READ_POSITION_EXTENDED_BUFFER { UCHAR :1; UCHAR PERR:1; UCHAR LOPU:1; UCHAR :1; UCHAR BYCU:1; UCHAR LOCU:1; UCHAR EOP:1; UCHAR BOP:1; UCHAR Partition; UCHAR AdditionalLength[2]; UCHAR Reserved1; UCHAR NumberBufferObjects[3]; UCHAR FirstLogicalObject[8]; UCHAR LastLogicalObject[8]; UCHAR NumberBufferObjectBytes[8]; } SCSI_READ_POSITION_EXTENDED_BUFFER, *PSCSI_READ_POSITION_EXTENDED_BUFFER; typedef union _READ_POSITION_RESULT { SCSI_READ_POSITION_SHORT_BUFFER ShortBuffer; SCSI_READ_POSITION_LONG_BUFFER LongBuffer; SCSI_READ_POSITION_EXTENDED_BUFFER ExtendedBuffer; } READ_POSITION_RESULT, *PREAD_POSITION_RESULT; static DWORD GetTapePositionInfo(HANDLE hDevice, PTAPE_POSITION_INFO TapePositionInfo) { PSCSI_PASS_THROUGH ScsiPassThrough; BOOL bResult; DWORD dwBytesReturned; const DWORD dwBufferSize = sizeof(SCSI_PASS_THROUGH) + sizeof(READ_POSITION_RESULT) + 28; memset(TapePositionInfo, 0, sizeof(*TapePositionInfo)); ScsiPassThrough = (PSCSI_PASS_THROUGH)malloc(dwBufferSize); for (int pass = 0; pass < 2; pass++) { memset(ScsiPassThrough, 0, dwBufferSize); ScsiPassThrough->Length = sizeof(SCSI_PASS_THROUGH); ScsiPassThrough->CdbLength = 10; ScsiPassThrough->SenseInfoLength = 28; ScsiPassThrough->DataIn = 1; ScsiPassThrough->DataTransferLength = sizeof(SCSI_READ_POSITION_LONG_BUFFER); ScsiPassThrough->TimeOutValue = 1000; ScsiPassThrough->DataBufferOffset = sizeof(SCSI_PASS_THROUGH) + 28; ScsiPassThrough->SenseInfoOffset = sizeof(SCSI_PASS_THROUGH); ScsiPassThrough->Cdb[0] = 0x34; /* READ POSITION */ switch (pass) { case 0: ScsiPassThrough->Cdb[1] = SERVICEACTION_LONG_FORM; break; case 1: ScsiPassThrough->Cdb[1] = SERVICEACTION_SHORT_FORM_BLOCKID; break; } bResult = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH, ScsiPassThrough, sizeof(SCSI_PASS_THROUGH), ScsiPassThrough, dwBufferSize, &dwBytesReturned, NULL); if (bResult && dwBytesReturned >= (offsetof(SCSI_PASS_THROUGH, ScsiStatus) + sizeof(ScsiPassThrough->ScsiStatus))) { if (ScsiPassThrough->ScsiStatus == SCSISTAT_GOOD) { PREAD_POSITION_RESULT pPosResult = (PREAD_POSITION_RESULT)((PUCHAR)ScsiPassThrough + ScsiPassThrough->DataBufferOffset); switch (pass) { case 0: { /* SERVICEACTION_LONG_FORM */ TapePositionInfo->AtPartitionStart = pPosResult->LongBuffer.BOP; TapePositionInfo->AtPartitionEnd = pPosResult->LongBuffer.EOP; if (!TapePositionInfo->PartitionBlockValid) { TapePositionInfo->PartitionBlockValid = !pPosResult->LongBuffer.BPU; if (TapePositionInfo->PartitionBlockValid) { TapePositionInfo->Partition = Read32BitUnsigned(pPosResult->LongBuffer.Partition); TapePositionInfo->BlockNumber = Read64BitUnsigned(pPosResult->LongBuffer.BlockNumber); } } TapePositionInfo->FileSetValid = !pPosResult->LongBuffer.MPU; if (TapePositionInfo->FileSetValid) { TapePositionInfo->FileNumber = Read64BitUnsigned(pPosResult->LongBuffer.FileNumber); TapePositionInfo->SetNumber = Read64BitUnsigned(pPosResult->LongBuffer.SetNumber); } break; } case 1: { /* * SERVICEACTION_SHORT_FORM_BLOCKID */ // pPosResult->ShortBuffer.PERR; // pPosResult->ShortBuffer.BYCU; // pPosResult->ShortBuffer.BCU; TapePositionInfo->AtPartitionStart = pPosResult->ShortBuffer.BOP; TapePositionInfo->AtPartitionEnd = pPosResult->ShortBuffer.EOP; if (!TapePositionInfo->PartitionBlockValid) { TapePositionInfo->PartitionBlockValid = !pPosResult->ShortBuffer.BPU; if (TapePositionInfo->PartitionBlockValid) { TapePositionInfo->Partition = pPosResult->ShortBuffer.Partition; TapePositionInfo->BlockNumber = Read32BitUnsigned(pPosResult->ShortBuffer.FirstBlock); } } // Read32BitsUnsigned(pPosResult->ShortBuffer.LastBlock); // Read24BitsUnsigned(pPosResult->ShortBuffer.NumberBufferBlocks); // Read32BitsUnsigned(pPosResult->ShortBuffer.NumberBufferBytes); break; } default: break; } } } } free(ScsiPassThrough); return NO_ERROR; } static DWORD GetDensityBlockSize(HANDLE hDevice, DWORD *pdwDensity, DWORD *pdwBlockSize) { DWORD dwBufferSize = sizeof(GET_MEDIA_TYPES) + 5 * sizeof(DEVICE_MEDIA_INFO); GET_MEDIA_TYPES *pGetMediaTypes = (GET_MEDIA_TYPES *)malloc(dwBufferSize); BOOL bResult; DWORD dwResult; if (pGetMediaTypes == NULL) { return ERROR_OUTOFMEMORY; } do { DWORD dwBytesReturned; bResult = DeviceIoControl(hDevice, IOCTL_STORAGE_GET_MEDIA_TYPES_EX, NULL, 0, (LPVOID)pGetMediaTypes, dwBufferSize, &dwBytesReturned, NULL); if (!bResult) { dwResult = GetLastError(); if (dwResult != ERROR_INSUFFICIENT_BUFFER) { free(pGetMediaTypes); return dwResult; } dwBufferSize += 6 * sizeof(DEVICE_MEDIA_INFO); GET_MEDIA_TYPES *pNewBuffer = (GET_MEDIA_TYPES *)realloc(pGetMediaTypes, dwBufferSize); if (pNewBuffer != pGetMediaTypes) { free(pGetMediaTypes); if (pNewBuffer == NULL) { return ERROR_OUTOFMEMORY; } pGetMediaTypes = pNewBuffer; } } } while (!bResult); if (pGetMediaTypes->DeviceType != FILE_DEVICE_TAPE) { free(pGetMediaTypes); return ERROR_BAD_DEVICE; } for (DWORD idxMedia = 0; idxMedia < pGetMediaTypes->MediaInfoCount; idxMedia++) { if (pGetMediaTypes->MediaInfo[idxMedia].DeviceSpecific.TapeInfo.MediaCharacteristics & MEDIA_CURRENTLY_MOUNTED) { if (pGetMediaTypes->MediaInfo[idxMedia].DeviceSpecific.TapeInfo.BusType == BusTypeScsi) { *pdwDensity = pGetMediaTypes->MediaInfo[idxMedia].DeviceSpecific.TapeInfo.BusSpecificData.ScsiInformation.DensityCode; } else { *pdwDensity = 0; } *pdwBlockSize = pGetMediaTypes->MediaInfo[idxMedia].DeviceSpecific.TapeInfo.CurrentBlockSize; free(pGetMediaTypes); return NO_ERROR; } } free(pGetMediaTypes); return ERROR_NO_MEDIA_IN_DRIVE; } int win32_tape_device::tape_pos(struct mtpos *mt_pos) { DWORD partition; DWORD offset; DWORD offsetHi; BOOL result; if (m_fd < 3 || m_fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) || TapeHandleTable[m_fd - 3].OSHandle == INVALID_HANDLE_VALUE) { errno = EBADF; return -1; } PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[m_fd - 3]; result = GetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, &partition, &offset, &offsetHi); if (result == NO_ERROR) { mt_pos->mt_blkno = offset; return 0; } return -1; } win32_tape_device::~win32_tape_device() { } win32_tape_device::win32_tape_device() { } bareos-Release-14.2.6/src/win32/stored/backends/win32_tape_device.h000066400000000000000000000027271263011562700247160ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Windows Tape API device abstraction. * * Marco van Wieringen, December 2013 */ #ifndef WIN32_TAPE_DEVICE_H #define WIN32_TAPE_DEVICE_H class win32_tape_device: public generic_tape_device { public: win32_tape_device(); ~win32_tape_device(); int d_close(int); int d_open(const char *pathname, int flags, int mode); int d_ioctl(int fd, ioctl_req_t request, char *mt = NULL); ssize_t d_read(int fd, void *buffer, size_t count); ssize_t d_write(int fd, const void *buffer, size_t count); int tape_op(struct mtop *mt_com); int tape_get(struct mtget *mt_com); int tape_pos(struct mtpos *mt_com); }; #endif /* WIN32_TAPE_DEVICE_H */ bareos-Release-14.2.6/src/win32/stored/bextractres.rc.in000066400000000000000000000022541263011562700227550ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareostools.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "bextract utility" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bextract.exe" VALUE "OriginalFilename", "bextract.exe" VALUE "ProductName", "Bareos Storage Daemon" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/stored/blsres.rc.in000066400000000000000000000022351263011562700217200ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareostools.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "bls utility" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bls.exe" VALUE "OriginalFilename", "bls.exe" VALUE "ProductName", "Bareos Storage Daemon" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/stored/btaperes.rc.in000066400000000000000000000022431263011562700222320ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareostools.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "btape utility" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "btape.exe" VALUE "OriginalFilename", "btape.exe" VALUE "ProductName", "Bareos Storage Daemon" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/stored/make_def000077500000000000000000000010301263011562700211440ustar00rootroot00000000000000#!/bin/sh # # Make the stupid bareos.def file so that we don't have to do it manually # # Kern Sibbald, June 2007 # NM=nm case $1 in 32) SYMBOL_START=13 ;; 64) SYMBOL_START=20 ;; *) SYMBOL_START=13 ;; esac shift echo "LIBRARY libbareossd.dll" echo "EXPORTS" echo " " for i in $*; do \ echo "; $i"; \ ${NM} $i | grep "^[0-9a-f]* T " | cut -c${SYMBOL_START}- ; \ echo " "; \ done DATA="\ forge_on \ configfile \ me \ my_config \ " for i in ${DATA}; do \ echo "$i DATA"; \ done bareos-Release-14.2.6/src/win32/stored/storedres.rc.in000066400000000000000000000022601263011562700224360ustar00rootroot00000000000000id ICON "../../../platforms/win32/bareossd.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos Storage Daemon" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bareos-sd.exe" VALUE "OriginalFilename", "bareos-sd.exe" VALUE "ProductName", "Bareos Storage Daemon" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2013 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/src/win32/stored/who.h000066400000000000000000000021461263011562700204420ustar00rootroot00000000000000/* BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2007-2010 Free Software Foundation Europe e.V. This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation, which is listed in the file LICENSE. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Kern Sibbald, August 2007 */ #define APP_NAME "Bareos-sd" #define LC_APP_NAME "bareos-sd" #define APP_DESC "Bareos Storage Service" #define SERVICE_DESC "Provides bareos storage services." #define terminate_app(x) terminate_stored(x) extern void terminate_stored(int sig); bareos-Release-14.2.6/src/win32/tools/000077500000000000000000000000001263011562700173315ustar00rootroot00000000000000bareos-Release-14.2.6/src/win32/tools/Makefile000066400000000000000000000031341263011562700207720ustar00rootroot00000000000000# # BAREOS® - Backup Archiving REcovery Open Sourced # # Copyright (C) 2014-2014 Bareos GmbH & Co. KG # # This program is Free Software; you can redistribute it and/or # modify it under the terms of version three of the GNU Affero General Public # License as published by the Free Software Foundation and included # in the file LICENSE. # # 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 # Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # VPATH = .:../../tools include ../Makefile.inc INCLUDES = -I../.. \ -I../../include \ -I../include \ -I../compat/include \ -I../vss/include LDLIBS = ../lib/libbareos.a \ ../lib/libbareos.dll \ $(MINGW_LIB)/libpthreadGCE2.a \ $(MINGW_LIB)/libz.dll.a \ $(WINSOCKLIB) -lole32 -loleaut32 -luuid BSMTPSRCS = bsmtp.c BSMTPOBJS = $(BSMTPSRCS:.c=.o) WINDRESSRCS = bsmtpres.rc WINDRESOBJS = $(WINDRESSRCS:.rc=.o) all: bsmtp.exe bsmtp.exe: DLL_USAGE = -DUSING_DLL bsmtp.exe: $(BSMTPOBJS) $(WINDRESOBJS) $(CXX) $(LDFLAGS_CONS) $(BSMTPOBJS) $(LDLIBS) $(WINDRESOBJS) -o $@ clean: rm -f *.o distclean:: clean rm -f bsmtp.exe # inference rules .c.o: @echo "Compiling $<" $(CXX) $(DLL_USAGE) $(CXXFLAGS) -c -o $@ $< %.o : %.rc @echo "Ressource Compiling $^" $(WINDRES) $^ -o $@ bareos-Release-14.2.6/src/win32/tools/bsmtpres.rc.in000066400000000000000000000022351263011562700221250ustar00rootroot00000000000000id ICON "../../../platforms/win32/bsmtp.ico" 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "Bareos GmbH & Co. KG" VALUE "FileDescription", "Bareos SMTP Client" VALUE "FileVersion", @VERSION@ VALUE "InternalName", "bsmtp.exe" VALUE "OriginalFilename", "bsmtp.exe" VALUE "ProductName", "Bareos SMTP Agent" VALUE "ProductVersion", @VERSION@ VALUE "LegalCopyright", "Copyright 2000-2012 Free Software Foundation Europe e.V. " "Copyright 2013-2014 Bareos GmbH & Co. KG " VALUE "LegalTrademarks", "Licensed under GNU AGPLv3." "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 Affero General Public License for more details. " END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END bareos-Release-14.2.6/test/000077500000000000000000000000001263011562700154175ustar00rootroot00000000000000bareos-Release-14.2.6/test/all000077500000000000000000000020631263011562700161160ustar00rootroot00000000000000#!/bin/bash # stop on first error set -e echo "start testing ... " echo "TRAVIS_BRANCH: $TRAVIS_BRANCH" echo "USER: $USER" echo "DB: $DB" echo "--------- starting services ----------- " service bareos-dir start service bareos-sd start service bareos-fd start sleep 10 echo "--------- checking services ----------- " service bareos-dir status service bareos-sd status service bareos-fd status # enable bash debug set -v BACKUP_TEST_FILE=/usr/sbin/bareos.test echo -e "status dir" | bconsole echo echo "---- label a volume ----" echo -e "label volume=testvol pool=Full" | bconsole echo echo "----- create some file to test backup / restore ----" echo "bareos restore test" > ${BACKUP_TEST_FILE} echo echo "------ trigger backup job -----" echo -e "run job=BackupClient1 yes\rwait" | bconsole | grep "Job queued. JobId=" echo "status dir" | bconsole echo echo "------ trigger restore job -----" echo -e "restore select current\r2\rls\rmark usr\rdone\ryes\rwait" | bconsole echo "status dir" | bconsole grep "bareos restore test" /tmp/bareos-restores/${BACKUP_TEST_FILE}